浏览代码

Use throws in place of nil for ciphers

Marcin Krzyżanowski 10 年之前
父节点
当前提交
9504f1df6a

+ 16 - 14
CryptoSwift/AES.swift

@@ -10,6 +10,10 @@ import Foundation
 
 final public class AES {
     
+    enum Error: ErrorType {
+        case BlockSizeExceeded
+    }
+    
     public enum AESVariant:Int {
         case aes128 = 1, aes192, aes256
         
@@ -140,18 +144,17 @@ final public class AES {
     - returns: Encrypted data
     */
 
-    public func encrypt(bytes:[UInt8], padding:Padding? = PKCS7()) -> [UInt8]? {
+    public func encrypt(bytes:[UInt8], padding:Padding? = PKCS7()) throws -> [UInt8] {
         var finalBytes = bytes;
 
         if let padding = padding {
             finalBytes = padding.add(bytes, blockSize: AES.blockSize)
-        } else if (bytes.count % AES.blockSize != 0) {
-            assert(false, "AES block size exceeded!");
-            return nil
+        } else if bytes.count % AES.blockSize != 0 {
+            throw Error.BlockSizeExceeded
         }
 
         let blocks = finalBytes.chunks(AES.blockSize) // 0.34
-        return blockMode.encryptBlocks(blocks, iv: self.iv, cipherOperation: encryptBlock)
+        return try blockMode.encryptBlocks(blocks, iv: self.iv, cipherOperation: encryptBlock)
     }
     
     private func encryptBlock(block:[UInt8]) -> [UInt8]? {
@@ -189,27 +192,26 @@ final public class AES {
         return out
     }
     
-    public func decrypt(bytes:[UInt8], padding:Padding? = PKCS7()) -> [UInt8]? {
-        if (bytes.count % AES.blockSize != 0) {
-            assert(false,"AES block size exceeded!")
-            return nil
+    public func decrypt(bytes:[UInt8], padding:Padding? = PKCS7()) throws -> [UInt8] {
+        if bytes.count % AES.blockSize != 0 {
+            throw Error.BlockSizeExceeded
         }
         
         let blocks = bytes.chunks(AES.blockSize)
-        let out:[UInt8]?
+        let out:[UInt8]
         switch (blockMode) {
         case .CFB, .CTR:
             // CFB, CTR uses encryptBlock to decrypt
-            out = blockMode.decryptBlocks(blocks, iv: self.iv, cipherOperation: encryptBlock)
+            out = try blockMode.decryptBlocks(blocks, iv: self.iv, cipherOperation: encryptBlock)
         default:
-            out = blockMode.decryptBlocks(blocks, iv: self.iv, cipherOperation: decryptBlock)
+            out = try blockMode.decryptBlocks(blocks, iv: self.iv, cipherOperation: decryptBlock)
         }
         
-        if let out = out, let padding = padding {
+        if let padding = padding {
             return padding.remove(out, blockSize: nil)
         }
         
-        return out;
+        return out
     }
     
     private func decryptBlock(block:[UInt8]) -> [UInt8]? {

+ 37 - 32
CryptoSwift/ChaCha20.swift

@@ -10,6 +10,10 @@ import Foundation
 
 final public class ChaCha20 {
     
+    enum Error: ErrorType {
+        case MissingContext
+    }
+    
     static let blockSize = 64 // 512 / 8
     private let stateSize = 16
     private var context:Context?
@@ -40,16 +44,16 @@ final public class ChaCha20 {
     }
 
     
-    public func encrypt(bytes:[UInt8]) -> [UInt8]? {
-        if (context == nil) {
-            return nil
+    public func encrypt(bytes:[UInt8]) throws -> [UInt8] {
+        guard context != nil else {
+            throw Error.MissingContext
         }
         
-        return encryptBytes(bytes)
+        return try encryptBytes(bytes)
     }
     
-    public func decrypt(bytes:[UInt8]) -> [UInt8]? {
-        return encrypt(bytes)
+    public func decrypt(bytes:[UInt8]) throws -> [UInt8] {
+        return try encrypt(bytes)
     }
     
     private final func wordToByte(input:[UInt32] /* 64 */) -> [UInt8]? /* 16 */ {
@@ -135,38 +139,39 @@ final public class ChaCha20 {
         return ctx
     }
     
-    private final func encryptBytes(message:[UInt8]) -> [UInt8]? {
+    private final func encryptBytes(message:[UInt8]) throws -> [UInt8] {
         
-        if let ctx = context {
-            var c:[UInt8] = [UInt8](count: message.count, repeatedValue: 0)
-            
-            var cPos:Int = 0
-            var mPos:Int = 0
-            var bytes = message.count
-            
-            while (true) {
-                if let output = wordToByte(ctx.input) {
-                    ctx.input[12] = ctx.input[12] &+ 1
-                    if (ctx.input[12] == 0) {
-                        ctx.input[13] = ctx.input[13] &+ 1
-                        /* stopping at 2^70 bytes per nonce is user's responsibility */
-                    }
-                    if (bytes <= ChaCha20.blockSize) {
-                        for (var i = 0; i < bytes; i++) {
-                            c[i + cPos] = message[i + mPos] ^ output[i]
-                        }
-                        return c
-                    }
-                    for (var i = 0; i < ChaCha20.blockSize; i++) {
+        guard let ctx = context else {
+            throw Error.MissingContext
+        }
+        
+        var c:[UInt8] = [UInt8](count: message.count, repeatedValue: 0)
+        
+        var cPos:Int = 0
+        var mPos:Int = 0
+        var bytes = message.count
+        
+        while (true) {
+            if let output = wordToByte(ctx.input) {
+                ctx.input[12] = ctx.input[12] &+ 1
+                if (ctx.input[12] == 0) {
+                    ctx.input[13] = ctx.input[13] &+ 1
+                    /* stopping at 2^70 bytes per nonce is user's responsibility */
+                }
+                if (bytes <= ChaCha20.blockSize) {
+                    for (var i = 0; i < bytes; i++) {
                         c[i + cPos] = message[i + mPos] ^ output[i]
                     }
-                    bytes -= ChaCha20.blockSize
-                    cPos += ChaCha20.blockSize
-                    mPos += ChaCha20.blockSize
+                    return c
+                }
+                for (var i = 0; i < ChaCha20.blockSize; i++) {
+                    c[i + cPos] = message[i + mPos] ^ output[i]
                 }
+                bytes -= ChaCha20.blockSize
+                cPos += ChaCha20.blockSize
+                mPos += ChaCha20.blockSize
             }
         }
-        return nil;
     }
     
     private final func quarterround(inout a:UInt32, inout _ b:UInt32, inout _ c:UInt32, inout _ d:UInt32) {

+ 24 - 10
CryptoSwift/Cipher.swift

@@ -9,6 +9,12 @@
 import Foundation
 
 public enum Cipher {
+    
+    public enum Error: ErrorType {
+        case EncryptError
+        case DecryptError
+    }
+    
     /**
     ChaCha20
     
@@ -36,14 +42,18 @@ public enum Cipher {
     
     - returns: encrypted message
     */
-    public func encrypt(bytes: [UInt8]) -> [UInt8]? {
+    public func encrypt(bytes: [UInt8]) throws -> [UInt8] {
         switch (self) {
             case .ChaCha20(let key, let iv):
-                let chacha = CryptoSwift.ChaCha20(key: key, iv: iv)
-                return chacha?.encrypt(bytes)
+                guard let chacha = CryptoSwift.ChaCha20(key: key, iv: iv) else {
+                    throw Error.EncryptError
+                }
+                return try chacha.encrypt(bytes)
             case .AES(let key, let iv, let blockMode):
-                let aes = CryptoSwift.AES(key: key, iv: iv, blockMode: blockMode)
-                return aes?.encrypt(bytes)
+                guard let aes = CryptoSwift.AES(key: key, iv: iv, blockMode: blockMode) else {
+                    throw Error.EncryptError
+                }
+                return try aes.encrypt(bytes)
         }
     }
     
@@ -54,14 +64,18 @@ public enum Cipher {
     
     - returns: Plaintext message
     */
-    public func decrypt(bytes: [UInt8]) -> [UInt8]? {
+    public func decrypt(bytes: [UInt8]) throws -> [UInt8] {
         switch (self) {
             case .ChaCha20(let key, let iv):
-                let chacha = CryptoSwift.ChaCha20(key: key, iv: iv);
-                return chacha?.decrypt(bytes)
+                guard let chacha = CryptoSwift.ChaCha20(key: key, iv: iv) else {
+                    throw Error.DecryptError
+                }
+                return try chacha.decrypt(bytes)
             case .AES(let key, let iv, let blockMode):
-                let aes = CryptoSwift.AES(key: key, iv: iv, blockMode: blockMode);
-                return aes?.decrypt(bytes)
+                guard let aes = CryptoSwift.AES(key: key, iv: iv, blockMode: blockMode) else {
+                    throw Error.DecryptError
+                }
+                return try aes.decrypt(bytes)
         }
     }
 

+ 41 - 30
CryptoSwift/CipherBlockMode.swift

@@ -11,10 +11,14 @@ import Foundation
 // I have no better name for that
 typealias CipherOperationOnBlock = (block: [UInt8]) -> [UInt8]?
 
+enum BlockError: ErrorType {
+    case MissingInitializationVector
+}
+
 private protocol BlockMode {
     var needIV:Bool { get }
-    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8]?
-    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8]?
+    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8]
+    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8]
 }
 
 public enum CipherBlockMode {
@@ -46,7 +50,7 @@ public enum CipherBlockMode {
     
     - returns: encrypted bytes
     */
-    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8]? {
+    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
         
         // if IV is not available, fallback to plain
         var finalBlockMode:CipherBlockMode = self
@@ -54,17 +58,17 @@ public enum CipherBlockMode {
             finalBlockMode = .ECB
         }
         
-        return finalBlockMode.mode.encryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
+        return try finalBlockMode.mode.encryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
     }
     
-    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8]? {
+    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
         // if IV is not available, fallback to plain
         var finalBlockMode:CipherBlockMode = self
         if (iv == nil) {
             finalBlockMode = .ECB
         }
 
-        return finalBlockMode.mode.decryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
+        return try finalBlockMode.mode.decryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
     }
 }
 
@@ -74,35 +78,33 @@ Cipher-block chaining (CBC)
 private struct CBCMode: BlockMode {
     let needIV = true
     
-    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8]? {
+    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
         precondition(blocks.count > 0)
-        assert(iv != nil, "CFB require IV")
-        if (iv == nil) {
-            return nil
+        guard let iv = iv else {
+            throw BlockError.MissingInitializationVector
         }
         
         var out:[UInt8] = [UInt8]()
         out.reserveCapacity(blocks.count * blocks[0].count)
-        var prevCiphertext = iv! // for the first time prevCiphertext = iv
+        var prevCiphertext = iv // for the first time prevCiphertext = iv
         for plaintext in blocks {
             if let encrypted = cipherOperation(block: xor(prevCiphertext, b: plaintext)) {
                 out.extend(encrypted)
                 prevCiphertext = encrypted
             }
         }
-        return out;
+        return out
     }
     
-    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8]? {
+    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
         precondition(blocks.count > 0)
-        assert(iv != nil, "CFB require IV")
-        if (iv == nil) {
-            return nil
+        guard let iv = iv else {
+            throw BlockError.MissingInitializationVector
         }
 
         var out:[UInt8] = [UInt8]()
         out.reserveCapacity(blocks.count * blocks[0].count)
-        var prevCiphertext = iv! // for the first time prevCiphertext = iv
+        var prevCiphertext = iv // for the first time prevCiphertext = iv
         for ciphertext in blocks {
             if let decrypted = cipherOperation(block: ciphertext) { // decrypt
                 out.extend(xor(prevCiphertext, b: decrypted)) //FIXME: b:
@@ -120,27 +122,26 @@ Cipher feedback (CFB)
 private struct CFBMode: BlockMode {
     let needIV = true
     
-    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8]? {
-        assert(iv != nil, "CFB require IV")
-        if (iv == nil) {
-            return nil
+    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
+        guard let iv = iv else {
+            throw BlockError.MissingInitializationVector
         }
         
         var out:[UInt8] = [UInt8]()
         out.reserveCapacity(blocks.count * blocks[0].count)
 
-        var lastCiphertext = iv!
+        var lastCiphertext = iv
         for plaintext in blocks {
             if let encrypted = cipherOperation(block: lastCiphertext) {
                 lastCiphertext = xor(plaintext,b: encrypted)
                 out.extend(lastCiphertext)
             }
         }
-        return out;
+        return out
     }
     
-    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8]? {
-        return encryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
+    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
+        return try encryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
     }
 }
 
@@ -150,7 +151,8 @@ Electronic codebook (ECB)
 */
 private struct ECBMode: BlockMode {
     let needIV = false
-    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8]? {
+    
+    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8] {
         var out:[UInt8] = [UInt8]()
         out.reserveCapacity(blocks.count * blocks[0].count)
         for plaintext in blocks {
@@ -161,7 +163,7 @@ private struct ECBMode: BlockMode {
         return out
     }
     
-    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8]? {
+    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8] {
         return encryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
     }
 }
@@ -182,13 +184,18 @@ private struct CTRMode: BlockMode {
         return nonce
     }
     
-    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8]? {
+    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
         //var counter:UInt = 17940646550795321087
+        
+        guard let iv = iv else {
+            throw BlockError.MissingInitializationVector
+        }
+
         var counter:UInt = 0
         var out:[UInt8] = [UInt8]()
         out.reserveCapacity(blocks.count * blocks[0].count)
         for plaintext in blocks {
-            let nonce = buildNonce(iv!, counter: counter++)
+            let nonce = buildNonce(iv, counter: counter++)
             if let encrypted = cipherOperation(block: nonce) {
                 out.extend(xor(plaintext, b: encrypted))
             }
@@ -196,7 +203,11 @@ private struct CTRMode: BlockMode {
         return out
     }
     
-    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8]? {
+    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
+        guard iv != nil else {
+            throw BlockError.MissingInitializationVector
+        }
+        
         var counter:UInt = 0
         var out:[UInt8] = [UInt8]()
         out.reserveCapacity(blocks.count * blocks[0].count)

+ 6 - 10
CryptoSwift/NSDataExtension.swift

@@ -60,18 +60,14 @@ extension NSData {
         return Hash.crc32(self).calculate()
     }
 
-    public func encrypt(cipher: Cipher) -> NSData? {
-        if let encrypted = cipher.encrypt(self.arrayOfBytes()) {
-            return NSData.withBytes(encrypted)
-        }
-        return nil
+    public func encrypt(cipher: Cipher) throws -> NSData? {
+        let encrypted = try cipher.encrypt(self.arrayOfBytes())
+        return NSData.withBytes(encrypted)
     }
 
-    public func decrypt(cipher: Cipher) -> NSData? {
-        if let decrypted = cipher.decrypt(self.arrayOfBytes()) {
-            return NSData.withBytes(decrypted)
-        }
-        return nil;
+    public func decrypt(cipher: Cipher) throws -> NSData? {
+        let decrypted = try cipher.decrypt(self.arrayOfBytes())
+        return NSData.withBytes(decrypted)
     }
     
     public func authenticate(authenticator: Authenticator) -> NSData? {

+ 4 - 4
CryptoSwift/StringExtension.swift

@@ -40,12 +40,12 @@ extension String {
         return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.crc32()?.toHexString()
     }
 
-    public func encrypt(cipher: Cipher) -> String? {
-        return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.encrypt(cipher)?.toHexString()
+    public func encrypt(cipher: Cipher) throws -> String? {
+        return try self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.encrypt(cipher)?.toHexString()
     }
 
-    public func decrypt(cipher: Cipher) -> String? {
-        return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.decrypt(cipher)?.toHexString()
+    public func decrypt(cipher: Cipher) throws -> String? {
+        return try self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.decrypt(cipher)?.toHexString()
     }
     
     public func authenticate(authenticator: Authenticator) -> String? {

+ 21 - 21
CryptoSwiftTests/AESTests.swift

@@ -22,10 +22,10 @@ final class AESTests: XCTestCase {
         let expected:[UInt8] = [0xae,0x8c,0x59,0x95,0xb2,0x6f,0x8e,0x3d,0xb0,0x6f,0x0a,0xa5,0xfe,0xc4,0xf0,0xc2];
         
         if let aes = AES(key: key, iv: iv, blockMode: .CBC) {
-            let encrypted = aes.encrypt(input, padding: nil)
-            XCTAssertEqual(encrypted!, expected, "encryption failed")
-            let decrypted = aes.decrypt(encrypted!, padding: nil)
-            XCTAssertEqual(decrypted!, input, "decryption failed")
+            let encrypted = try! aes.encrypt(input, padding: nil)
+            XCTAssertEqual(encrypted, expected, "encryption failed")
+            let decrypted = try! aes.decrypt(encrypted, padding: nil)
+            XCTAssertEqual(decrypted, input, "decryption failed")
         } else {
             XCTAssert(false, "failed")
         }
@@ -43,10 +43,10 @@ final class AESTests: XCTestCase {
             0x70, 0xb4, 0xc5, 0x5a];
         
         if let aes = AES(key: aesKey, blockMode: .ECB) {
-            let encrypted = aes.encrypt(input, padding: nil)
-            XCTAssertEqual(encrypted!, expected, "encryption failed")
-            let decrypted = aes.decrypt(encrypted!, padding: nil)
-            XCTAssertEqual(decrypted!, input, "decryption failed")
+            let encrypted = try! aes.encrypt(input, padding: nil)
+            XCTAssertEqual(encrypted, expected, "encryption failed")
+            let decrypted = try! aes.decrypt(encrypted, padding: nil)
+            XCTAssertEqual(decrypted, input, "decryption failed")
         } else {
             XCTAssert(false, "failed")
         }
@@ -60,10 +60,10 @@ final class AESTests: XCTestCase {
         
         if let aes = AES(key: key, iv:iv, blockMode: .CBC) {
             XCTAssertTrue(aes.blockMode == .CBC, "Invalid block mode")
-            let encrypted = aes.encrypt(plaintext, padding: nil)
-            XCTAssertEqual(encrypted!, expected, "encryption failed")
-            let decrypted = aes.decrypt(encrypted!, padding: nil)
-            XCTAssertEqual(decrypted!, plaintext, "decryption failed")
+            let encrypted = try! aes.encrypt(plaintext, padding: nil)
+            XCTAssertEqual(encrypted, expected, "encryption failed")
+            let decrypted = try! aes.decrypt(encrypted, padding: nil)
+            XCTAssertEqual(decrypted, plaintext, "decryption failed")
         } else {
             XCTAssert(false, "failed")
         }
@@ -77,10 +77,10 @@ final class AESTests: XCTestCase {
         
         if let aes = AES(key: key, iv:iv, blockMode: .CFB) {
             XCTAssertTrue(aes.blockMode == .CFB, "Invalid block mode")
-            let encrypted = aes.encrypt(plaintext, padding: nil)
-            XCTAssertEqual(encrypted!, expected, "encryption failed")
-            let decrypted = aes.decrypt(encrypted!, padding: nil)
-            XCTAssertEqual(decrypted!, plaintext, "decryption failed")
+            let encrypted = try! aes.encrypt(plaintext, padding: nil)
+            XCTAssertEqual(encrypted, expected, "encryption failed")
+            let decrypted = try! aes.decrypt(encrypted, padding: nil)
+            XCTAssertEqual(decrypted, plaintext, "decryption failed")
         } else {
             XCTAssert(false, "failed")
         }
@@ -94,10 +94,10 @@ final class AESTests: XCTestCase {
         
         if let aes = AES(key: key, iv:iv, blockMode: .CTR) {
             XCTAssertTrue(aes.blockMode == .CTR, "Invalid block mode")
-            let encrypted = aes.encrypt(plaintext, padding: nil)
-            XCTAssertEqual(encrypted!, expected, "encryption failed")
-            let decrypted = aes.decrypt(encrypted!, padding: nil)
-            XCTAssertEqual(decrypted!, plaintext, "decryption failed")
+            let encrypted = try! aes.encrypt(plaintext, padding: nil)
+            XCTAssertEqual(encrypted, expected, "encryption failed")
+            let decrypted = try! aes.decrypt(encrypted, padding: nil)
+            XCTAssertEqual(decrypted, plaintext, "decryption failed")
         } else {
             XCTAssert(false, "failed")
         }
@@ -197,7 +197,7 @@ final class AESTests: XCTestCase {
         let iv:[UInt8] = [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F]
         let message = [UInt8](count: 1024 * 1024, repeatedValue: 7)
         measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: true, forBlock: { () -> Void in
-            AES(key: key, iv: iv, blockMode: .CBC)?.encrypt(message, padding: PKCS7())
+            try! AES(key: key, iv: iv, blockMode: .CBC)?.encrypt(message, padding: PKCS7())
         })
     }
     

+ 12 - 10
CryptoSwiftTests/ChaCha20Tests.swift

@@ -51,22 +51,24 @@ final class ChaCha20Tests: XCTestCase {
             let message = [UInt8](count: (expectedHex.characters.count / 2), repeatedValue: 0)
             
             let setup = (key: keys[idx], iv: ivs[idx])
-            let encrypted = Cipher.ChaCha20(setup).encrypt(message)
-            XCTAssert(encrypted != nil, "missing")
-            if let encrypted = encrypted {
-                let decrypted = Cipher.ChaCha20(setup).decrypt(encrypted)
-                XCTAssert(decrypted != nil, "missing")
-                if let decrypted = decrypted {
-                    XCTAssertEqual(message, decrypted, "ChaCha20 decryption failed");
-                }
+            do {
+                let encrypted = try Cipher.ChaCha20(setup).encrypt(message)
+                let decrypted = try Cipher.ChaCha20(setup).decrypt(encrypted)
+                XCTAssertEqual(message, decrypted, "ChaCha20 decryption failed");
                 
                 // check extension
                 let messageData = NSData(bytes: message, length: message.count);
-                let encrypted2 = messageData.encrypt(Cipher.ChaCha20(setup))
+                let encrypted2 = try! messageData.encrypt(Cipher.ChaCha20(setup))
                 XCTAssertNotNil(encrypted2, "")
                 if let encrypted2 = encrypted2 {
                     XCTAssertEqual(NSData.withBytes(encrypted), encrypted2, "ChaCha20 extension failed")
                 }
+            } catch Cipher.Error.EncryptError {
+                XCTAssert(false, "Encryption failed")
+            } catch Cipher.Error.DecryptError {
+                XCTAssert(false, "Decryption failed")
+            } catch {
+                XCTAssert(false, "Failed")
             }
         }
     }
@@ -76,7 +78,7 @@ final class ChaCha20Tests: XCTestCase {
         let iv:[UInt8] = [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F]
         let message = [UInt8](count: (1024 * 1024) * 1, repeatedValue: 7)
         measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: true, forBlock: { () -> Void in
-            let encrypted = ChaCha20(key: key, iv: iv)?.encrypt(message)
+            let encrypted = try! ChaCha20(key: key, iv: iv)?.encrypt(message)
             self.stopMeasuring()
             XCTAssert(encrypted != nil, "not encrypted")
         })