Explorar o código

Merge pull request #499 from zweigraf/master

Add support for Keccak SHA3
Marcin Krzyzanowski %!s(int64=8) %!d(string=hai) anos
pai
achega
e8d6b79bc4
Modificáronse 2 ficheiros con 45 adicións e 34 borrados
  1. 25 34
      Sources/CryptoSwift/SHA3.swift
  2. 20 0
      Tests/CryptoSwiftTests/DigestTests.swift

+ 25 - 34
Sources/CryptoSwift/SHA3.swift

@@ -36,59 +36,50 @@ public final class SHA3: DigestType {
 
     public let blockSize: Int
     public let digestLength: Int
-
+    public let markByte: UInt8
+    
     fileprivate var accumulated = Array<UInt8>()
     fileprivate var processedBytesTotalCount: Int = 0
     fileprivate var accumulatedHash: Array<UInt64>
-
-    public enum Variant: RawRepresentable {
-        case sha224, sha256, sha384, sha512
-
+    
+    public enum Variant {
+        case sha224, sha256, sha384, sha512, keccak224, keccak256, keccak384, keccak512
+        
         var digestLength: Int {
             return 100 - (blockSize / 2)
         }
 
         var blockSize: Int {
-            return (1600 - rawValue * 2) / 8
+            return (1600 - outputLength * 2) / 8
         }
-
-        public typealias RawValue = Int
-        public var rawValue: RawValue {
+        
+        var markByte: UInt8 {
+            switch self {
+            case .sha224, .sha256, .sha384, .sha512:
+                return 0x06 // 0x1F for SHAKE
+            case .keccak224, .keccak256, .keccak384, .keccak512:
+                return 0x01
+            }
+        }
+        
+        public var outputLength: Int {
             switch self {
-            case .sha224:
+            case .sha224, .keccak224:
                 return 224
-            case .sha256:
+            case .sha256, .keccak256:
                 return 256
-            case .sha384:
+            case .sha384, .keccak384:
                 return 384
-            case .sha512:
+            case .sha512, .keccak512:
                 return 512
             }
         }
-
-        public init?(rawValue: RawValue) {
-            switch rawValue {
-            case 224:
-                self = .sha224
-                break
-            case 256:
-                self = .sha256
-                break
-            case 384:
-                self = .sha384
-                break
-            case 512:
-                self = .sha512
-                break
-            default:
-                return nil
-            }
-        }
     }
 
     public init(variant: SHA3.Variant) {
         blockSize = variant.blockSize
         digestLength = variant.digestLength
+        markByte = variant.markByte
         accumulatedHash = Array<UInt64>(repeating: 0, count: digestLength)
     }
 
@@ -272,8 +263,7 @@ extension SHA3: Updatable {
                 let q = (r / 8) - (accumulated.count % (r / 8))
                 accumulated += Array<UInt8>(repeating: 0, count: q)
             }
-
-            accumulated[markByteIndex] |= 0x06 // 0x1F for SHAKE
+            accumulated[markByteIndex] |= markByte
             accumulated[self.accumulated.count - 1] |= 0x80
         }
 
@@ -300,3 +290,4 @@ extension SHA3: Updatable {
         return Array(result[0..<self.digestLength])
     }
 }
+

+ 20 - 0
Tests/CryptoSwiftTests/DigestTests.swift

@@ -73,26 +73,46 @@ final class DigestTests: XCTestCase {
         XCTAssertEqual(SHA3(variant: .sha256).calculate(for: Array<UInt8>(hex: "616263")).toHexString(), "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532")
         XCTAssertEqual(SHA3(variant: .sha384).calculate(for: Array<UInt8>(hex: "616263")).toHexString(), "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25")
         XCTAssertEqual(SHA3(variant: .sha512).calculate(for: Array<UInt8>(hex: "616263")).toHexString(), "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0")
+        XCTAssertEqual(SHA3(variant: .keccak224).calculate(for: Array<UInt8>(hex: "616263")).toHexString(), "c30411768506ebe1c2871b1ee2e87d38df342317300a9b97a95ec6a8")
+        XCTAssertEqual(SHA3(variant: .keccak256).calculate(for: Array<UInt8>(hex: "616263")).toHexString(), "4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
+        XCTAssertEqual(SHA3(variant: .keccak384).calculate(for: Array<UInt8>(hex: "616263")).toHexString(), "f7df1165f033337be098e7d288ad6a2f74409d7a60b49c36642218de161b1f99f8c681e4afaf31a34db29fb763e3c28e")
+        XCTAssertEqual(SHA3(variant: .keccak512).calculate(for: Array<UInt8>(hex: "616263")).toHexString(), "18587dc2ea106b9a1563e32b3312421ca164c7f1f07bc922a9c83d77cea3a1e5d0c69910739025372dc14ac9642629379540c17e2a65b19d77aa511a9d00bb96")
 
         XCTAssertEqual(SHA3(variant: .sha224).calculate(for: Array<UInt8>(hex: "")).toHexString(), "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7")
         XCTAssertEqual(SHA3(variant: .sha256).calculate(for: Array<UInt8>(hex: "")).toHexString(), "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a")
         XCTAssertEqual(SHA3(variant: .sha384).calculate(for: Array<UInt8>(hex: "")).toHexString(), "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004")
         XCTAssertEqual(SHA3(variant: .sha512).calculate(for: Array<UInt8>(hex: "")).toHexString(), "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26")
+        XCTAssertEqual(SHA3(variant: .keccak224).calculate(for: Array<UInt8>(hex: "")).toHexString(), "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd")
+        XCTAssertEqual(SHA3(variant: .keccak256).calculate(for: Array<UInt8>(hex: "")).toHexString(), "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
+        XCTAssertEqual(SHA3(variant: .keccak384).calculate(for: Array<UInt8>(hex: "")).toHexString(), "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff")
+        XCTAssertEqual(SHA3(variant: .keccak512).calculate(for: Array<UInt8>(hex: "")).toHexString(), "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e")
 
         XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.sha224), "8a24108b154ada21c9fd5574494479ba5c7e7ab76ef264ead0fcce33")
         XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.sha256), "41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376")
         XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.sha384), "991c665755eb3a4b6bbdfb75c78a492e8c56a22c5c4d7e429bfdbc32b9d4ad5aa04a1f076e62fea19eef51acd0657c22")
         XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.sha512), "04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e")
+        XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.keccak224), "e51faa2b4655150b931ee8d700dc202f763ca5f962c529eae55012b6")
+        XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.keccak256), "45d3b367a6904e6e8d502ee04999a7c27647f91fa845d456525fd352ae3d7371")
+        XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.keccak384), "b41e8896428f1bcbb51e17abd6acc98052a3502e0d5bf7fa1af949b4d3c855e7c4dc2c390326b3f3e74c7b1e2b9a3657")
+        XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.keccak512), "6aa6d3669597df6d5a007b00d09c20795b5c4218234e1698a944757a488ecdc09965435d97ca32c3cfed7201ff30e070cd947f1fc12b9d9214c467d342bcba5d")
 
         XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.sha224), "543e6868e1666c1a643630df77367ae5a62a85070a51c14cbf665cbc")
         XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.sha256), "916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18")
         XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.sha384), "79407d3b5916b59c3e30b09822974791c313fb9ecc849e406f23592d04f625dc8c709b98b43b3852b337216179aa7fc7")
         XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.sha512), "afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185")
+        XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.keccak224), "344298994b1b06873eae2ce739c425c47291a2e24189e01b524f88dc")
+        XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.keccak256), "f519747ed599024f3882238e5ab43960132572b7345fbeb9a90769dafd21ad67")
+        XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.keccak384), "cc063f34685135368b34f7449108f6d10fa727b09d696ec5331771da46a923b6c34dbd1d4f77e595689c1f3800681c28")
+        XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.keccak512), "ac2fb35251825d3aa48468a9948c0a91b8256f6d97d8fa4160faff2dd9dfcc24f3f1db7a983dad13d53439ccac0b37e24037e7b95f80f59f37a2f683c4ba4682")
 
         XCTAssertEqual(Array<UInt8>(repeating: 0x61, count: 1_000_000).sha3(.sha224), Array<UInt8>(hex: "d69335b93325192e516a912e6d19a15cb51c6ed5c15243e7a7fd653c"), "One million (1,000,000) repetitions of the character 'a' (0x61)")
         XCTAssertEqual(Array<UInt8>(repeating: 0x61, count: 1_000_000).sha3(.sha256), Array<UInt8>(hex: "5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1"), "One million (1,000,000) repetitions of the character 'a' (0x61)")
         XCTAssertEqual(Array<UInt8>(repeating: 0x61, count: 1_000_000).sha3(.sha384), Array<UInt8>(hex: "eee9e24d78c1855337983451df97c8ad9eedf256c6334f8e948d252d5e0e76847aa0774ddb90a842190d2c558b4b8340"), "One million (1,000,000) repetitions of the character 'a' (0x61)")
         XCTAssertEqual(Array<UInt8>(repeating: 0x61, count: 1_000_000).sha3(.sha512), Array<UInt8>(hex: "3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87"), "One million (1,000,000) repetitions of the character 'a' (0x61)")
+        XCTAssertEqual(Array<UInt8>(repeating: 0x61, count: 1_000_000).sha3(.keccak224), Array<UInt8>(hex: "19f9167be2a04c43abd0ed554788101b9c339031acc8e1468531303f"), "One million (1,000,000) repetitions of the character 'a' (0x61)")
+        XCTAssertEqual(Array<UInt8>(repeating: 0x61, count: 1_000_000).sha3(.keccak256), Array<UInt8>(hex: "fadae6b49f129bbb812be8407b7b2894f34aecf6dbd1f9b0f0c7e9853098fc96"), "One million (1,000,000) repetitions of the character 'a' (0x61)")
+        XCTAssertEqual(Array<UInt8>(repeating: 0x61, count: 1_000_000).sha3(.keccak384), Array<UInt8>(hex: "0c8324e1ebc182822c5e2a086cac07c2fe00e3bce61d01ba8ad6b71780e2dec5fb89e5ae90cb593e57bc6258fdd94e17"), "One million (1,000,000) repetitions of the character 'a' (0x61)")
+        XCTAssertEqual(Array<UInt8>(repeating: 0x61, count: 1_000_000).sha3(.keccak512), Array<UInt8>(hex: "5cf53f2e556be5a624425ede23d0e8b2c7814b4ba0e4e09cbbf3c2fac7056f61e048fc341262875ebc58a5183fea651447124370c1ebf4d6c89bc9a7731063bb"), "One million (1,000,000) repetitions of the character 'a' (0x61)")
     }
 
     func testMD5Data() {