Browse Source

Speed up MD5. Get the right value without time consuming conversion to UInt32. Fixes #401

Marcin Krzyżanowski 8 years ago
parent
commit
9c313a7836
2 changed files with 9 additions and 7 deletions
  1. 2 2
      Sources/CryptoSwift/Collection+Extension.swift
  2. 7 5
      Sources/CryptoSwift/MD5.swift

+ 2 - 2
Sources/CryptoSwift/Collection+Extension.swift

@@ -12,7 +12,7 @@ extension Collection where Self.Iterator.Element == UInt8, Self.Index == Int {
         let count = self.count
         var result = Array<UInt32>()
         result.reserveCapacity(16)
-        for idx in stride(from: self.startIndex, to: self.endIndex, by: MemoryLayout<UInt32>.size) {
+        for idx in stride(from: self.startIndex, to: self.endIndex, by: 4) {
             var val: UInt32 = 0
             val |= count > 3 ? UInt32(self[idx.advanced(by: 3)]) << 24 : 0
             val |= count > 2 ? UInt32(self[idx.advanced(by: 2)]) << 16 : 0
@@ -28,7 +28,7 @@ extension Collection where Self.Iterator.Element == UInt8, Self.Index == Int {
         let count = self.count
         var result = Array<UInt64>()
         result.reserveCapacity(32)
-        for idx in stride(from: self.startIndex, to: self.endIndex, by: MemoryLayout<UInt64>.size) {
+        for idx in stride(from: self.startIndex, to: self.endIndex, by: 8) {
             var val: UInt64 = 0
             val |= count > 7 ? UInt64(self[idx.advanced(by: 7)]) << 56 : 0
             val |= count > 6 ? UInt64(self[idx.advanced(by: 6)]) << 48 : 0

+ 7 - 5
Sources/CryptoSwift/MD5.swift

@@ -52,10 +52,7 @@ public final class MD5: DigestType {
 
     // mutating currentHash in place is way faster than returning new result
     fileprivate func process(block chunk: ArraySlice<UInt8>, currentHash: inout Array<UInt32>) {
-
-        // break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15
-        var M = chunk.toUInt32Array()
-        assert(M.count == 16, "Invalid array")
+        assert(chunk.count == 16 * 4)
 
         // Initialize hash value for this chunk:
         var A: UInt32 = currentHash[0]
@@ -93,7 +90,12 @@ public final class MD5: DigestType {
             dTemp = D
             D = C
             C = B
-            B = B &+ rotateLeft(A &+ F &+ k[j] &+ M[g], by: s[j])
+
+            // break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15 and get M[g] value
+            let gAdvanced = g << 2
+            let Mg = UInt32(chunk[chunk.startIndex + gAdvanced]) | UInt32(chunk[chunk.startIndex + gAdvanced &+ 1]) << 8 | UInt32(chunk[chunk.startIndex + gAdvanced &+ 2]) << 16 | UInt32(chunk[chunk.startIndex + gAdvanced &+ 3]) << 24
+
+            B = B &+ rotateLeft(A &+ F &+ k[j] &+ Mg, by: s[j])
             A = dTemp
         }