Bläddra i källkod

add README, use SecureBytes, allow long test in Release mode

Alex Vlasov 6 år sedan
förälder
incheckning
4b9dc2c821
3 ändrade filer med 34 tillägg och 22 borttagningar
  1. 11 1
      README.md
  2. 6 6
      Sources/CryptoSwift/Scrypt.swift
  3. 17 15
      Tests/Tests/ScryptTests.swift

+ 11 - 1
README.md

@@ -79,6 +79,7 @@ Good mood
 - [PBKDF1](http://tools.ietf.org/html/rfc2898#section-5.1) (Password-Based Key Derivation Function 1)
 - [PBKDF2](http://tools.ietf.org/html/rfc2898#section-5.2) (Password-Based Key Derivation Function 2)
 - [HKDF](https://tools.ietf.org/html/rfc5869) (HMAC-based Extract-and-Expand Key Derivation Function)
+- [Scrypt](https://tools.ietf.org/html/rfc7914) (The scrypt Password-Based Key Derivation Function)
 
 #### Data padding
   PKCS#5
@@ -314,6 +315,14 @@ let salt: Array<UInt8> = Array("nacllcan".utf8)
 let key = try PKCS5.PBKDF2(password: password, salt: salt, iterations: 4096, variant: .sha256).calculate()
 ```
 
+```swift
+let password: Array<UInt8> = Array("s33krit".utf8)
+let salt: Array<UInt8> = Array("nacllcan".utf8)
+// Scrypt implementation does not implement work parallelization, so `p` parameter will
+// increase the work time even in multicore systems
+let key = try Scrypt(password: password, salt: salt, dkLen: 64, N: 16384, r: 8, p: 1).calculate()
+```
+
 ##### HMAC-based Key Derivation Function
 
 ```swift
@@ -323,6 +332,7 @@ let salt: Array<UInt8> = Array("nacllcan".utf8)
 let key = try HKDF(password: password, salt: salt, variant: .sha256).calculate()
 ```
 
+
 ##### Data Padding
     
 Some content-encryption algorithms assume the input length is a multiple of `k` octets, where `k` is greater than one. For such algorithms, the input shall be padded.
@@ -466,7 +476,7 @@ do {
 
 The result of Counter with Cipher Block Chaining-Message Authentication Code encryption is ciphertext and **authentication tag**, that is later used to decryption.
 
-```
+```swift
 do {
     // The authentication tag is appended to the encrypted message.
 	let tagLength = 8

+ 6 - 6
Sources/CryptoSwift/Scrypt.swift

@@ -27,8 +27,8 @@ public final class Scrypt {
     }
 
     /// Configuration parameters.
-    private let salt: Array<UInt8>
-    private let password: Array<UInt8>
+    private let salt: SecureBytes
+    private let password: SecureBytes
     fileprivate let blocksize: Int // 128 * r
     fileprivate let salsaBlock = UnsafeMutableRawPointer.allocate(byteCount: 64, alignment: 64)
     private let dkLen: Int
@@ -62,8 +62,8 @@ public final class Scrypt {
         self.N = N
         self.r = r
         self.p = p
-        self.password = password
-        self.salt = salt
+        self.password = SecureBytes.init(bytes: password)
+        self.salt = SecureBytes.init(bytes: salt)
         self.dkLen = dkLen
     }
 
@@ -83,7 +83,7 @@ public final class Scrypt {
 
         /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
         // Expand the initial key
-        let barray = try PKCS5.PBKDF2(password: password, salt: salt, iterations: 1, keyLength: p * 128 * r, variant: .sha256).calculate()
+        let barray = try PKCS5.PBKDF2(password: Array(password), salt: Array(salt), iterations: 1, keyLength: p * 128 * r, variant: .sha256).calculate()
         barray.withUnsafeBytes { p in
             B.copyMemory(from: p.baseAddress!, byteCount: barray.count)
         }
@@ -99,7 +99,7 @@ public final class Scrypt {
         let pointer = B.assumingMemoryBound(to: UInt8.self)
         let bufferPointer = UnsafeBufferPointer(start: pointer, count: p * 128 * r)
         let block = [UInt8](bufferPointer)
-        return try PKCS5.PBKDF2(password: password, salt: block, iterations: 1, keyLength: dkLen, variant: .sha256).calculate()
+        return try PKCS5.PBKDF2(password: Array(password), salt: block, iterations: 1, keyLength: dkLen, variant: .sha256).calculate()
     }
 }
 

+ 17 - 15
Tests/Tests/ScryptTests.swift

@@ -46,24 +46,26 @@ class Scrypt: XCTestCase {
         XCTAssertEqual(derived, expected)
     }
     
-    //      Takes too long to run in debug mode!
-    //    func testScrypt_2() {
-    //        let password = Array("pleaseletmein".data(using: .ascii)!)
-    //        let salt = Array("SodiumChloride".data(using: .ascii)!)
-    //        let deriver = try! CryptoSwift.Scrypt(password: password, salt: salt, dkLen: 64, N: 1048576, r: 8, p: 16)
-    //        let derived = try! deriver.calculate()
-    //        let expected: [UInt8] = Array<UInt8>.init(hex: """
-    //                21 01 cb 9b 6a 51 1a ae ad db be 09 cf 70 f8 81
-    //                ec 56 8d 57 4a 2f fd 4d ab e5 ee 98 20 ad aa 47
-    //                8e 56 fd 8f 4b a5 d0 9f fa 1c 6d 92 7c 40 f4 c3
-    //                37 30 40 49 e8 a9 52 fb cb f4 5c 6f a7 7a 41 a4
-    //""".replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "\n", with: "").replacingOccurrences(of: "\t", with: ""))
-    //        XCTAssertEqual(derived, expected)
-    //    }
+//          Takes too long to run in debug mode!
+        func testScrypt_2() {
+            #if !DEBUG
+            let password = Array("pleaseletmein".data(using: .ascii)!)
+            let salt = Array("SodiumChloride".data(using: .ascii)!)
+            let deriver = try! CryptoSwift.Scrypt(password: password, salt: salt, dkLen: 64, N: 1048576, r: 8, p: 16)
+            let derived = try! deriver.calculate()
+            let expected: [UInt8] = Array<UInt8>.init(hex: """
+                    21 01 cb 9b 6a 51 1a ae ad db be 09 cf 70 f8 81
+                    ec 56 8d 57 4a 2f fd 4d ab e5 ee 98 20 ad aa 47
+                    8e 56 fd 8f 4b a5 d0 9f fa 1c 6d 92 7c 40 f4 c3
+                    37 30 40 49 e8 a9 52 fb cb f4 5c 6f a7 7a 41 a4
+    """.replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "\n", with: "").replacingOccurrences(of: "\t", with: ""))
+            XCTAssertEqual(derived, expected)
+            #endif
+        }
     
     static let allTests = [
         ("testScrypt_0", testScrypt_0),
         ("testScrypt_1", testScrypt_1),
-        //        ("testScrypt_2", testScrypt_2)
+        ("testScrypt_2", testScrypt_2)
     ]
 }