Browse Source

ChaCha20 initials

Marcin Krzyżanowski 11 years ago
parent
commit
a710bf111c

+ 4 - 0
CryptoSwift.xcodeproj/project.pbxproj

@@ -24,6 +24,7 @@
 		758F3F781992F6CE0014BBDA /* ByteExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758F3F771992F6CE0014BBDA /* ByteExtension.swift */; };
 		7599C9C6199EA28700A3988B /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7599C9C5199EA28700A3988B /* StringExtension.swift */; };
 		75B601EB197D6A6C0009B53D /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 754BE45519693E190098E6F3 /* CryptoSwift.framework */; };
+		75EB380119ABDD710002375A /* ChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EB380019ABDD710002375A /* ChaCha20.swift */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -111,6 +112,7 @@
 		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>"; };
 		7599C9C5199EA28700A3988B /* StringExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = "<group>"; };
+		75EB380019ABDD710002375A /* ChaCha20.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChaCha20.swift; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -171,6 +173,7 @@
 				750A545F1992D2680017DA75 /* MD5.swift */,
 				752E087A199FF27C005B0EA0 /* SHA1.swift */,
 				75153D4119AA3C7900750381 /* SHA2.swift */,
+				75EB380019ABDD710002375A /* ChaCha20.swift */,
 				758F3F771992F6CE0014BBDA /* ByteExtension.swift */,
 				7547195019931802002FA5F1 /* IntExtension.swift */,
 				752DEF7619693EA000E17557 /* NSDataExtension.swift */,
@@ -326,6 +329,7 @@
 				7552614E1993051E000D2B20 /* CryptoHash.swift in Sources */,
 				7599C9C6199EA28700A3988B /* StringExtension.swift in Sources */,
 				752E087B199FF27C005B0EA0 /* SHA1.swift in Sources */,
+				75EB380119ABDD710002375A /* ChaCha20.swift in Sources */,
 				750A54601992D2680017DA75 /* MD5.swift in Sources */,
 				752DEF7719693EA000E17557 /* NSDataExtension.swift in Sources */,
 				754C8FED19979F94005AD904 /* ArrayExtension.swift in Sources */,

+ 93 - 0
CryptoSwift/ChaCha20.swift

@@ -0,0 +1,93 @@
+//
+//  ChaCha20.swift
+//  CryptoSwift
+//
+//  Created by Marcin Krzyzanowski on 25/08/14.
+//  Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
+//
+
+import Foundation
+
+public class ChaCha20 {
+    let keySize = 32
+    let nonceSize = 8
+    let stateSize = 16
+    let blockSize = 16 * 4
+    
+    public init() {
+    }
+    
+    public func wordToByte(input:[UInt32] /* 64 */) -> [Byte]? /* 16 */ {
+        if (input.count != stateSize) {
+            return nil;
+        }
+        
+        var x:[UInt32] = [UInt32]()
+        for val in input[0...15] {
+            x.append(val)
+        }
+        
+        for (var i = 8; i > 0; i -= 2) {
+            quarterround(&x[0], &x[4], &x[8], &x[12])
+            quarterround(&x[1], &x[5], &x[9],  &x[13])
+            quarterround(&x[2], &x[6], &x[10], &x[14])
+            quarterround(&x[3], &x[7], &x[11], &x[15])
+            quarterround(&x[0], &x[5], &x[10], &x[15])
+            quarterround(&x[1], &x[6], &x[11], &x[12])
+            quarterround(&x[2], &x[7], &x[8],  &x[13])
+            quarterround(&x[3], &x[4], &x[9],  &x[14])
+        }
+        
+        for (idx,val) in enumerate(input[0...15]) {
+            x[idx] = plus(x[idx],val)
+        }
+
+        var output:[Byte] = [Byte](count: 64, repeatedValue: 0)
+        for (i,xval) in enumerate(x[0...15]) {
+            let bytes = x[i].bytes()
+            let start = (i * 4)
+            for o in start..<(start + 4) {
+                output[o] = bytes[o - start]
+            }
+        }
+        
+        return output;
+    }
+    
+    private func UInt32To8Little(p:UInt32, _ v:UInt32) -> UInt8 {
+        var tmp1 = (v >> 0)  & 0xff | (v >> 8)  & 0xff
+        var tmp2 = (v >> 16) & 0xff | (v >> 24) & 0xff
+        return UInt8(tmp1 | tmp2)
+    }
+    
+    // rotate left
+    private func rotate(v:UInt32, _ c:UInt32) -> UInt32 {
+        return ((v << c) & 0xFFFFFFFF) | (v >> (32 - c))
+    }
+    
+    private func u32v(x:UInt32) -> UInt32 {
+        return x & 0xFFFFFFFF
+    }
+    
+    private func plusone(v:UInt32) -> UInt32 {
+        return plus(v, 1)
+    }
+    
+    private func plus(v:UInt32, _ w:UInt32) -> UInt32 {
+        return v &+ w
+    }
+
+    private func quarterround(inout a:UInt32, inout _ b:UInt32, inout _ c:UInt32, inout _ d:UInt32) {
+        a = plus(a,b);
+        d = rotate((d ^ a), 16)
+        
+        c = plus(c,d);
+        b = rotate((b ^ c), 12);
+        
+        a = plus(a,b);
+        d = rotate((d ^ a), 8);
+
+        c = plus(c,d);
+        b = rotate((b ^ c), 7);
+    }
+}

+ 1 - 1
CryptoSwift/CryptoHashBase.swift

@@ -31,7 +31,7 @@ class CryptoHashBase {
         return tmpMessage
     }
     
-    @availability(*,deprecated=0.1,message="Use bigInteger")
+    @availability(*,deprecated=0.1)
     func reverseByte(value: UInt32) -> UInt32 {
         // rdar://18060945 - not working since Xcode6-Beta6, need to split in two variables
         // return = ((value & 0x000000FF) << 24) | ((value & 0x0000FF00) << 8) | ((value & 0x00FF0000) >> 8)  | ((value & 0xFF000000) >> 24);

+ 1 - 0
CryptoSwift/IntExtension.swift

@@ -142,6 +142,7 @@ extension UInt32 {
         self = shiftedValue
         return self
     }
+
 }
 
 /** Bit operations */

+ 5 - 7
CryptoSwiftTests/HashTests.swift

@@ -114,11 +114,9 @@ class CryptoSwiftTests: XCTestCase {
         XCTAssertEqual(crc.hexString, "884863D2", "CRC32 calculation failed");
     }
 
-//    func testHashEnum() {
-//        var data:NSData = NSData(bytes: [49, 50, 51] as [Byte], length: 3)
-//        let md5 = CryptoHash.md5.hash(data);
-//        var md5String:String = md5.toHexString();
-//        XCTAssertEqualObjects(md5String, "202CB962AC59075B964B07152D234B70", "MD5 calculation failed");
-//    }
-    
+    func testChaCha20() {
+        var ch = ChaCha20()
+        let bytes = ch.wordToByte([49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64])
+        println(bytes)
+    }
 }