瀏覽代碼

SHA256 -> SHA2 with variants (224, 256)

Marcin Krzyżanowski 11 年之前
父節點
當前提交
7a62fbc939

+ 4 - 4
CryptoSwift.xcodeproj/project.pbxproj

@@ -8,6 +8,7 @@
 
 /* Begin PBXBuildFile section */
 		750A54601992D2680017DA75 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750A545F1992D2680017DA75 /* MD5.swift */; };
+		75153D4219AA3C7900750381 /* SHA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75153D4119AA3C7900750381 /* SHA2.swift */; };
 		752DEF7719693EA000E17557 /* NSDataExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752DEF7619693EA000E17557 /* NSDataExtension.swift */; };
 		752E087B199FF27C005B0EA0 /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752E087A199FF27C005B0EA0 /* SHA1.swift */; };
 		75445821196AA2A5002FF20E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75445820196AA2A5002FF20E /* Security.framework */; settings = {ATTRIBUTES = (Required, ); }; };
@@ -17,7 +18,6 @@
 		754C8FED19979F94005AD904 /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754C8FEC19979F94005AD904 /* ArrayExtension.swift */; };
 		754DD76E19A149AF00E52288 /* CryptoHashBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754DD76D19A149AF00E52288 /* CryptoHashBase.swift */; };
 		7552614E1993051E000D2B20 /* CryptoHash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7552614D1993051E000D2B20 /* CryptoHash.swift */; };
-		755409B819A535FA004E7CD9 /* SHA256.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755409B719A535FA004E7CD9 /* SHA256.swift */; };
 		755FB1DA199E347D00475437 /* ExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755FB1D9199E347D00475437 /* ExtensionsTest.swift */; };
 		758F3F761992E57D0014BBDA /* Playground in Resources */ = {isa = PBXBuildFile; fileRef = 758F3F751992E57D0014BBDA /* Playground */; };
 		758F3F781992F6CE0014BBDA /* ByteExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758F3F771992F6CE0014BBDA /* ByteExtension.swift */; };
@@ -91,6 +91,7 @@
 
 /* Begin PBXFileReference section */
 		750A545F1992D2680017DA75 /* MD5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MD5.swift; sourceTree = "<group>"; };
+		75153D4119AA3C7900750381 /* SHA2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SHA2.swift; sourceTree = "<group>"; };
 		752DEF7619693EA000E17557 /* NSDataExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSDataExtension.swift; sourceTree = "<group>"; };
 		752E087A199FF27C005B0EA0 /* SHA1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SHA1.swift; sourceTree = "<group>"; };
 		75445820196AA2A5002FF20E /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
@@ -104,7 +105,6 @@
 		754C8FEC19979F94005AD904 /* ArrayExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtension.swift; sourceTree = "<group>"; };
 		754DD76D19A149AF00E52288 /* CryptoHashBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CryptoHashBase.swift; sourceTree = "<group>"; };
 		7552614D1993051E000D2B20 /* CryptoHash.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CryptoHash.swift; sourceTree = "<group>"; };
-		755409B719A535FA004E7CD9 /* SHA256.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SHA256.swift; sourceTree = "<group>"; };
 		755FB1D9199E347D00475437 /* ExtensionsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtensionsTest.swift; sourceTree = "<group>"; };
 		758F3F751992E57D0014BBDA /* Playground */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Playground; path = CryptoSwift/Playground; sourceTree = "<group>"; };
 		758F3F771992F6CE0014BBDA /* ByteExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ByteExtension.swift; sourceTree = "<group>"; };
@@ -167,7 +167,7 @@
 				754DD76D19A149AF00E52288 /* CryptoHashBase.swift */,
 				750A545F1992D2680017DA75 /* MD5.swift */,
 				752E087A199FF27C005B0EA0 /* SHA1.swift */,
-				755409B719A535FA004E7CD9 /* SHA256.swift */,
+				75153D4119AA3C7900750381 /* SHA2.swift */,
 				758F3F771992F6CE0014BBDA /* ByteExtension.swift */,
 				7547195019931802002FA5F1 /* IntExtension.swift */,
 				752DEF7619693EA000E17557 /* NSDataExtension.swift */,
@@ -326,10 +326,10 @@
 				750A54601992D2680017DA75 /* MD5.swift in Sources */,
 				752DEF7719693EA000E17557 /* NSDataExtension.swift in Sources */,
 				754C8FED19979F94005AD904 /* ArrayExtension.swift in Sources */,
-				755409B819A535FA004E7CD9 /* SHA256.swift in Sources */,
 				7547195119931802002FA5F1 /* IntExtension.swift in Sources */,
 				754DD76E19A149AF00E52288 /* CryptoHashBase.swift in Sources */,
 				758F3F781992F6CE0014BBDA /* ByteExtension.swift in Sources */,
+				75153D4219AA3C7900750381 /* SHA2.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 3 - 5
CryptoSwift/CryptoHashBase.swift

@@ -8,18 +8,16 @@
 
 import Foundation
 
-public class CryptoHashBase {
+class CryptoHashBase {
     
     internal var message: NSData
     
-    //MARK: Public
-    
-    public init(_ message: NSData) {
+    init(_ message: NSData) {
         self.message = message
     }
     
     /** Common part for hash calculation. Prepare header data. */
-    internal func prepare() -> NSMutableData {
+    func prepare() -> NSMutableData {
         var tmpMessage: NSMutableData = NSMutableData(data: self.message)
         
         // Step 1. Append Padding Bits

+ 2 - 3
CryptoSwift/MD5.swift

@@ -8,7 +8,7 @@
 
 import Foundation
 
-public class MD5 : CryptoHashBase {
+class MD5 : CryptoHashBase {
 
     /** specifies the per-round shift amounts */
     private let s: [UInt32] = [7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,
@@ -36,8 +36,7 @@ public class MD5 : CryptoHashBase {
     
     private let h:[UInt32] = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]
     
-    //MARK: Public
-    public func calculate() -> NSData {
+    func calculate() -> NSData {
         var tmpMessage = prepare()
         let wordSize = sizeof(UInt32)
 

+ 5 - 1
CryptoSwift/NSDataExtension.swift

@@ -44,8 +44,12 @@ extension NSData {
         return SHA1(self).calculate()
     }
 
+    public func sha224() -> NSData {
+        return SHA2(self).calculate(.sha224)
+    }
+
     public func sha256() -> NSData {
-        return SHA256(self).calculate()
+        return SHA2(self).calculate(.sha256)
     }
 
     internal func toHexString() -> String {

+ 13 - 8
CryptoSwift/Playground/MyPlayground.playground/section-1.swift

@@ -2,14 +2,19 @@
 
 import UIKit
 
-var i:UInt32 = 402653184
-i.bigEndian
-i.littleEndian
-
+// test inside class
+class Test {
+    func test(a:Int, b:Int) -> Int {
+        return a + b
+    }
+}
 
-var M:[UInt32] = [UInt32](count: 80, repeatedValue: 0)
-for x in 0..<M.count {
-    M[x] = 1
+// test with no class
+func test(a:Int, b:Int) -> Int
+{
+    return a + b
 }
 
-M
+Test().test(3, b: 3) // parameter name "b" WITH specified name is required
+// BUT
+test(3,4) // no parameter name "b"

+ 2 - 2
CryptoSwift/SHA1.swift

@@ -8,11 +8,11 @@
 
 import Foundation
 
-public class SHA1 : CryptoHashBase {
+class SHA1 : CryptoHashBase {
     
     private let h:[UInt32] = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]
         
-    public func calculate() -> NSData {
+    func calculate() -> NSData {
         var tmpMessage = self.prepare()
         let wordSize = sizeof(UInt32)
         

+ 51 - 16
CryptoSwift/SHA256.swift → CryptoSwift/SHA2.swift

@@ -1,30 +1,64 @@
 //
-//  SHA256.swift
+//  SHA2.swift
 //  CryptoSwift
 //
-//  Created by Marcin Krzyzanowski on 20/08/14.
+//  Created by Marcin Krzyzanowski on 24/08/14.
 //  Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
 //
 
 import Foundation
 
-public class SHA256 : CryptoHashBase {
-    private let h:[UInt32] = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]
-    private let k:[UInt32] = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
-                            0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
-                            0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-                            0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
-                            0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
-                            0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
-                            0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
-                            0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2]
+class SHA2 : CryptoHashBase {
     
-    public func calculate() -> NSData {
+    enum variant {
+        case sha224, sha256, sha384, sha512
+        
+        func h() -> [UInt32] {
+            switch (self) {
+            case .sha224:
+                return [0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4]
+            case .sha256:
+                return [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]
+            default:
+                return []
+            }
+        }
+        
+        func k() -> [UInt32] {
+            switch (self) {
+            case .sha224, .sha256:
+                return [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+                    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+                    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+                    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+                    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+                    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+                    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+                    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2]
+            default:
+                return []
+            }
+        }
+        
+        func resultingArray<T>(hh:[T]) -> [T] {
+            var finalHH:[T] = hh;
+            switch (self) {
+            case .sha224:
+                finalHH = Array(hh[0..<7])
+                break;
+            default:
+                break;
+            }
+            return finalHH
+        }
+    }
+    
+    func calculate(variant: SHA2.variant) -> NSData {
         var tmpMessage = self.prepare()
         let wordSize = sizeof(UInt32)
         
         // hash values
-        var hh = h
+        var hh = variant.h()
         
         // append message length, in a 64-bit big-endian integer. So now the message length is a multiple of 512 bits.
         tmpMessage.appendBytes((message.length * 8).bytes(64 / 8));
@@ -68,7 +102,7 @@ public class SHA256 : CryptoHashBase {
                 let t2 = s0 &+ maj
                 let s1 = rotateRight(E,6) ^ rotateRight(E,11) ^ rotateRight(E,25)
                 let ch = (E & F) ^ ((~E) & G)
-                let t1 = H &+ s1 &+ ch &+ k[j] &+ M[j]
+                let t1 = H &+ s1 &+ ch &+ variant.k()[j] &+ M[j]
                 
                 H = G
                 G = F
@@ -92,7 +126,8 @@ public class SHA256 : CryptoHashBase {
         
         // Produce the final hash value (big-endian) as a 160 bit number:
         var buf: NSMutableData = NSMutableData();
-        hh.map({ (item) -> () in
+        
+        variant.resultingArray(hh).map({ (item) -> () in
             var i:UInt32 = item.bigEndian
             buf.appendBytes(&i, length: sizeof(UInt32))
         })

+ 4 - 0
CryptoSwift/StringExtension.swift

@@ -20,6 +20,10 @@ extension String {
         return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.sha1().toHexString()
     }
 
+    public func sha224() -> String? {
+        return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.sha224().toHexString()
+    }
+
     public func sha256() -> String? {
         return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.sha256().toHexString()
     }

+ 8 - 6
CryptoSwiftTests/HashTests.swift

@@ -21,7 +21,7 @@ class CryptoSwiftTests: XCTestCase {
     
     func testMD5() {
         let data1:NSData = NSData(bytes: [0x31, 0x32, 0x33] as [Byte], length: 3) // "1", "2", "3"
-        var hash:NSData = MD5(data1).calculate()
+        var hash:NSData = data1.md5()
         XCTAssertEqual(hash.hexString, "202CB962AC59075B964B07152D234B70", "MD5 calculation failed");
         
         if let hash = "123".md5() {
@@ -71,6 +71,12 @@ class CryptoSwiftTests: XCTestCase {
         }
     }
     
+    func testSHA224() {
+        var data:NSData = NSData(bytes: [0x31, 0x32, 0x33] as [Byte], length: 3)
+        var hash:NSData = data.sha224();
+        XCTAssertEqual(hash.hexString, "78D8045D684ABD2EECE923758F3CD781489DF3A48E1278982466017F", "SHA256 calculation failed");
+    }
+
     func testSHA256() {
         var data:NSData = NSData(bytes: [0x31, 0x32, 0x33] as [Byte], length: 3)
         var hash:NSData = data.sha256()
@@ -79,12 +85,8 @@ class CryptoSwiftTests: XCTestCase {
         if let hash = "Rosetta code".sha256() {
             XCTAssertEqual(hash, "764FAF5C61AC315F1497F9DFA542713965B785E5CC2F707D6468D7D1124CDFCF", "SHA1 calculation failed")
         }
-//
-//        if let hash = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha1() {
-//            XCTAssertEqual(hash, "84983E441C3BD26EBAAE4AA1F95129E5E54670F1", "SHA1 calculation failed")
-//        }
     }
-//
+    
 //    func testSHA512() {
 //        var data:NSData = NSData(bytes: [49, 50, 51] as [Byte], length: 3)
 //        var sha512:NSData = data.sha512()

+ 4 - 3
README.md

@@ -12,6 +12,7 @@ Good mood
 #####what implemented?
 - MD5
 - SHA1
+- SHA224
 - SHA256
 
 ##Usage
@@ -28,16 +29,16 @@ CryptoHash enum usage
         println(data.hexString)
     }
     
-Direct methods
+Hashing a data
 	
-	let hash = MD5(data).calculate()
 	let hash = data.md5()
 	let hash = data.sha1()
+    let hash = data.sha224()
 	let hash = data.sha256()
 	
 	println(hash.hexString)
 	
-Hashing A String And Printing Result
+Hashing a String and printing result
 
     if let hash = "123".md5() {
         println(hash)