소스 검색

Update Cryptor protocol interface.

Marcin Krzyżanowski 9 년 전
부모
커밋
82961eb882

+ 20 - 10
CryptoSwift.xcodeproj/project.pbxproj

@@ -84,10 +84,10 @@
 		757BC9551C1CA5790093AAA9 /* ChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9201C1CA5790093AAA9 /* ChaCha20.swift */; };
 		757BC9561C1CA5790093AAA9 /* ChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9201C1CA5790093AAA9 /* ChaCha20.swift */; };
 		757BC9571C1CA5790093AAA9 /* ChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9201C1CA5790093AAA9 /* ChaCha20.swift */; };
-		757BC9581C1CA5790093AAA9 /* CipherProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9211C1CA5790093AAA9 /* CipherProtocol.swift */; };
-		757BC9591C1CA5790093AAA9 /* CipherProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9211C1CA5790093AAA9 /* CipherProtocol.swift */; };
-		757BC95A1C1CA5790093AAA9 /* CipherProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9211C1CA5790093AAA9 /* CipherProtocol.swift */; };
-		757BC95B1C1CA5790093AAA9 /* CipherProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9211C1CA5790093AAA9 /* CipherProtocol.swift */; };
+		757BC9581C1CA5790093AAA9 /* UpdatableCryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9211C1CA5790093AAA9 /* UpdatableCryptor.swift */; };
+		757BC9591C1CA5790093AAA9 /* UpdatableCryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9211C1CA5790093AAA9 /* UpdatableCryptor.swift */; };
+		757BC95A1C1CA5790093AAA9 /* UpdatableCryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9211C1CA5790093AAA9 /* UpdatableCryptor.swift */; };
+		757BC95B1C1CA5790093AAA9 /* UpdatableCryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9211C1CA5790093AAA9 /* UpdatableCryptor.swift */; };
 		757BC9601C1CA5790093AAA9 /* CRC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9231C1CA5790093AAA9 /* CRC.swift */; };
 		757BC9611C1CA5790093AAA9 /* CRC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9231C1CA5790093AAA9 /* CRC.swift */; };
 		757BC9621C1CA5790093AAA9 /* CRC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9231C1CA5790093AAA9 /* CRC.swift */; };
@@ -223,6 +223,10 @@
 		75CB934F1C8F609D0087740D /* BlockModeOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB934D1C8F609D0087740D /* BlockModeOptions.swift */; };
 		75CB93501C8F609D0087740D /* BlockModeOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB934D1C8F609D0087740D /* BlockModeOptions.swift */; };
 		75CB93511C8F609D0087740D /* BlockModeOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB934D1C8F609D0087740D /* BlockModeOptions.swift */; };
+		75D0E05C1CFB9B9400FCEA0E /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */; };
+		75D0E05D1CFB9B9400FCEA0E /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */; };
+		75D0E05E1CFB9B9400FCEA0E /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */; };
+		75D0E05F1CFB9B9400FCEA0E /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */; };
 		75DB81A31CDBFDC700ED181A /* BlockModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75DB81A21CDBFDC700ED181A /* BlockModeWorker.swift */; };
 		75DB81A41CDBFDC700ED181A /* BlockModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75DB81A21CDBFDC700ED181A /* BlockModeWorker.swift */; };
 		75DB81A51CDBFDC700ED181A /* BlockModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75DB81A21CDBFDC700ED181A /* BlockModeWorker.swift */; };
@@ -348,7 +352,7 @@
 		757BC91D1C1CA5790093AAA9 /* Authenticator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Authenticator.swift; path = Sources/CryptoSwift/Authenticator.swift; sourceTree = SOURCE_ROOT; };
 		757BC91F1C1CA5790093AAA9 /* BytesSequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BytesSequence.swift; path = Sources/CryptoSwift/BytesSequence.swift; sourceTree = SOURCE_ROOT; };
 		757BC9201C1CA5790093AAA9 /* ChaCha20.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ChaCha20.swift; path = Sources/CryptoSwift/ChaCha20.swift; sourceTree = SOURCE_ROOT; };
-		757BC9211C1CA5790093AAA9 /* CipherProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CipherProtocol.swift; path = Sources/CryptoSwift/CipherProtocol.swift; sourceTree = SOURCE_ROOT; };
+		757BC9211C1CA5790093AAA9 /* UpdatableCryptor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UpdatableCryptor.swift; path = Sources/CryptoSwift/UpdatableCryptor.swift; sourceTree = SOURCE_ROOT; };
 		757BC9231C1CA5790093AAA9 /* CRC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CRC.swift; path = Sources/CryptoSwift/CRC.swift; sourceTree = SOURCE_ROOT; };
 		757BC9251C1CA5790093AAA9 /* CSArrayType+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "CSArrayType+Extensions.swift"; path = "Sources/CryptoSwift/CSArrayType+Extensions.swift"; sourceTree = SOURCE_ROOT; };
 		757BC9261C1CA5790093AAA9 /* Generics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Generics.swift; path = Sources/CryptoSwift/Generics.swift; sourceTree = SOURCE_ROOT; };
@@ -387,6 +391,7 @@
 		75CB93431C8F603C0087740D /* CTR.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CTR.swift; path = Sources/CryptoSwift/BlockMode/CTR.swift; sourceTree = SOURCE_ROOT; };
 		75CB93481C8F60700087740D /* ECB.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ECB.swift; path = Sources/CryptoSwift/BlockMode/ECB.swift; sourceTree = SOURCE_ROOT; };
 		75CB934D1C8F609D0087740D /* BlockModeOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BlockModeOptions.swift; path = Sources/CryptoSwift/BlockMode/BlockModeOptions.swift; sourceTree = SOURCE_ROOT; };
+		75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Cipher.swift; path = Sources/CryptoSwift/Cipher.swift; sourceTree = SOURCE_ROOT; };
 		75D614BF1BD844F2001358B2 /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		75DB81A21CDBFDC700ED181A /* BlockModeWorker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BlockModeWorker.swift; path = Sources/CryptoSwift/BlockMode/BlockModeWorker.swift; sourceTree = SOURCE_ROOT; };
 		75DB81A71CDC06B100ED181A /* Cryptor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Cryptor.swift; path = Sources/CryptoSwift/Cryptor.swift; sourceTree = SOURCE_ROOT; };
@@ -585,7 +590,8 @@
 			isa = PBXGroup;
 			children = (
 				757F44081CC172B6002B1F85 /* BlockCipher.swift */,
-				757BC9211C1CA5790093AAA9 /* CipherProtocol.swift */,
+				757BC9211C1CA5790093AAA9 /* UpdatableCryptor.swift */,
+				75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */,
 				757BC91A1C1CA5790093AAA9 /* AES.swift */,
 				757BC9201C1CA5790093AAA9 /* ChaCha20.swift */,
 				757BC9341C1CA5790093AAA9 /* Rabbit.swift */,
@@ -829,6 +835,7 @@
 				757F440F1CC1822B002B1F85 /* SecureBytes.swift in Sources */,
 				757BC9751C1CA5790093AAA9 /* HashProtocol.swift in Sources */,
 				757BC9071C1CA56A0093AAA9 /* ChaCha20+Foundation.swift in Sources */,
+				75D0E05D1CFB9B9400FCEA0E /* Cipher.swift in Sources */,
 				757BC9851C1CA5790093AAA9 /* IntExtension.swift in Sources */,
 				757BC9B11C1CA5790093AAA9 /* String+Extension.swift in Sources */,
 				757BC96D1C1CA5790093AAA9 /* Generics.swift in Sources */,
@@ -865,7 +872,7 @@
 				757BC9951C1CA5790093AAA9 /* Padding.swift in Sources */,
 				80545D141CA9FECD00474A99 /* Bit.swift in Sources */,
 				757BC9A51C1CA5790093AAA9 /* Rabbit.swift in Sources */,
-				757BC9591C1CA5790093AAA9 /* CipherProtocol.swift in Sources */,
+				757BC9591C1CA5790093AAA9 /* UpdatableCryptor.swift in Sources */,
 				757BC90B1C1CA56A0093AAA9 /* NSData+Extension.swift in Sources */,
 				757BC9791C1CA5790093AAA9 /* HMAC.swift in Sources */,
 				75482EAD1CB329DF001F66A5 /* PKCS5.swift in Sources */,
@@ -889,6 +896,7 @@
 				757F440E1CC1822B002B1F85 /* SecureBytes.swift in Sources */,
 				757BC9741C1CA5790093AAA9 /* HashProtocol.swift in Sources */,
 				757BC90E1C1CA56A0093AAA9 /* Rabbit+Foundation.swift in Sources */,
+				75D0E05C1CFB9B9400FCEA0E /* Cipher.swift in Sources */,
 				757BC9841C1CA5790093AAA9 /* IntExtension.swift in Sources */,
 				757BC9B01C1CA5790093AAA9 /* String+Extension.swift in Sources */,
 				757BC96C1C1CA5790093AAA9 /* Generics.swift in Sources */,
@@ -925,7 +933,7 @@
 				757BC9941C1CA5790093AAA9 /* Padding.swift in Sources */,
 				80545D131CA9FECD00474A99 /* Bit.swift in Sources */,
 				757BC9A41C1CA5790093AAA9 /* Rabbit.swift in Sources */,
-				757BC9581C1CA5790093AAA9 /* CipherProtocol.swift in Sources */,
+				757BC9581C1CA5790093AAA9 /* UpdatableCryptor.swift in Sources */,
 				757BC9021C1CA56A0093AAA9 /* ArrayUInt8+Foundation.swift in Sources */,
 				757BC9781C1CA5790093AAA9 /* HMAC.swift in Sources */,
 				75482EAC1CB329DF001F66A5 /* PKCS5.swift in Sources */,
@@ -966,6 +974,7 @@
 				757F44111CC1822B002B1F85 /* SecureBytes.swift in Sources */,
 				757BC9761C1CA5790093AAA9 /* HashProtocol.swift in Sources */,
 				757BC9101C1CA56A0093AAA9 /* Rabbit+Foundation.swift in Sources */,
+				75D0E05F1CFB9B9400FCEA0E /* Cipher.swift in Sources */,
 				757BC9861C1CA5790093AAA9 /* IntExtension.swift in Sources */,
 				757BC9B21C1CA5790093AAA9 /* String+Extension.swift in Sources */,
 				757BC96E1C1CA5790093AAA9 /* Generics.swift in Sources */,
@@ -1002,7 +1011,7 @@
 				757BC9961C1CA5790093AAA9 /* Padding.swift in Sources */,
 				80545D161CA9FECD00474A99 /* Bit.swift in Sources */,
 				757BC9A61C1CA5790093AAA9 /* Rabbit.swift in Sources */,
-				757BC95A1C1CA5790093AAA9 /* CipherProtocol.swift in Sources */,
+				757BC95A1C1CA5790093AAA9 /* UpdatableCryptor.swift in Sources */,
 				757BC9041C1CA56A0093AAA9 /* ArrayUInt8+Foundation.swift in Sources */,
 				757BC97A1C1CA5790093AAA9 /* HMAC.swift in Sources */,
 				75482EAF1CB329DF001F66A5 /* PKCS5.swift in Sources */,
@@ -1026,6 +1035,7 @@
 				757F44101CC1822B002B1F85 /* SecureBytes.swift in Sources */,
 				757BC9771C1CA5790093AAA9 /* HashProtocol.swift in Sources */,
 				757BC9091C1CA56A0093AAA9 /* ChaCha20+Foundation.swift in Sources */,
+				75D0E05E1CFB9B9400FCEA0E /* Cipher.swift in Sources */,
 				757BC9871C1CA5790093AAA9 /* IntExtension.swift in Sources */,
 				757BC9B31C1CA5790093AAA9 /* String+Extension.swift in Sources */,
 				757BC96F1C1CA5790093AAA9 /* Generics.swift in Sources */,
@@ -1062,7 +1072,7 @@
 				757BC9971C1CA5790093AAA9 /* Padding.swift in Sources */,
 				80545D151CA9FECD00474A99 /* Bit.swift in Sources */,
 				757BC9A71C1CA5790093AAA9 /* Rabbit.swift in Sources */,
-				757BC95B1C1CA5790093AAA9 /* CipherProtocol.swift in Sources */,
+				757BC95B1C1CA5790093AAA9 /* UpdatableCryptor.swift in Sources */,
 				757BC90D1C1CA56A0093AAA9 /* NSData+Extension.swift in Sources */,
 				757BC97B1C1CA5790093AAA9 /* HMAC.swift in Sources */,
 				75482EAE1CB329DF001F66A5 /* PKCS5.swift in Sources */,

+ 4 - 3
CryptoSwiftTests/AESTests.swift

@@ -85,9 +85,10 @@ final class AESTests: XCTestCase {
         let encrypted = try! aes.encrypt(plaintext)
 
         var partialEncrypted = [UInt8]()
-        var encryptor = aes.encryptor()
-        partialEncrypted.appendContentsOf(try! encryptor.update(Array(plaintext[0..<16]), isLast: false))
-        partialEncrypted.appendContentsOf(try! encryptor.update(Array(plaintext[16..<32]), isLast: true))
+        var encryptor = aes.makeEncryptor()
+        partialEncrypted.appendContentsOf(try! encryptor.updateWith(bytes: Array(plaintext[0..<16]), isLast: false))
+        //partialEncrypted.appendContentsOf(try! encryptor.finish(bytes: Array(plaintext[16..<32])))
+        partialEncrypted.appendContentsOf(try! encryptor.updateWith(bytes: Array(plaintext[16..<32]), isLast: true))
         XCTAssertEqual(encrypted, partialEncrypted, "encryption failed")
     }
 

+ 18 - 8
Sources/CryptoSwift/AES.swift

@@ -400,7 +400,7 @@ extension AES {
             self.worker = aes.blockMode.worker(aes.iv, cipherOperation: aes.encryptBlock)
         }
 
-        mutating public func update(bytes:[UInt8], isLast: Bool) throws -> [UInt8] {
+        mutating public func updateWith(bytes bytes:[UInt8], isLast: Bool = false) throws -> [UInt8] {
             if isLast {
                 let paddedBytes = padding.add(bytes, blockSize: AES.blockSize)
                 var result = [UInt8]()
@@ -408,6 +408,8 @@ extension AES {
                     result.appendContentsOf(worker.encrypt(chunk))
                 }
                 return result
+            } else if bytes.count == 0 {
+                return bytes;
             }
 
             return worker.encrypt(bytes)
@@ -433,7 +435,11 @@ extension AES {
             }
         }
 
-        mutating public func update(bytes:[UInt8], isLast: Bool) throws -> [UInt8] {
+        mutating public func updateWith(bytes bytes:[UInt8], isLast: Bool = false) throws -> [UInt8] {
+            if bytes.count == 0 {
+                return bytes;
+            }
+
             let plaintext = worker.decrypt(bytes)
             if isLast {
                 return padding.remove(plaintext, blockSize: AES.blockSize)
@@ -443,16 +449,20 @@ extension AES {
     }
 }
 
-// MARK: CipherProtocol
-extension AES: CipherProtocol {
-    public func encryptor() -> Cryptor {
+// MARK: UpdatableCryptor
+extension AES: UpdatableCryptor {
+    
+    public func makeEncryptor() -> AES.Encryptor {
         return Encryptor(aes: self)
     }
 
-    public func decryptor() -> Cryptor {
+    public func makeDecryptor() -> AES.Decryptor {
         return Decryptor(aes: self)
     }
+}
 
+// MARK: Cipher
+extension AES: Cipher {
     public func encrypt(bytes:[UInt8]) throws -> [UInt8] {
         let chunks = bytes.chunks(AES.blockSize)
 
@@ -460,7 +470,7 @@ extension AES: CipherProtocol {
         var out = [UInt8]()
         out.reserveCapacity(bytes.count)
         for (idx, block) in chunks.enumerate() {
-            out.appendContentsOf(try oneTimeCryptor.update(block, isLast: idx == max(0,chunks.count - 1)))
+            out.appendContentsOf(try oneTimeCryptor.updateWith(bytes: block, isLast: idx == max(0,chunks.count - 1)))
         }
 
         if blockMode.options.contains(.PaddingRequired) && (out.count % AES.blockSize != 0) {
@@ -480,7 +490,7 @@ extension AES: CipherProtocol {
         var out = [UInt8]()
         out.reserveCapacity(bytes.count)
         for (idx,chunk) in chunks.enumerate() {
-            out.appendContentsOf(try oneTimeCryptor.update(chunk, isLast: idx == max(0,chunks.count - 1)))
+            out.appendContentsOf(try oneTimeCryptor.updateWith(bytes: chunk, isLast: idx == max(0,chunks.count - 1)))
         }
         return out
     }

+ 2 - 2
Sources/CryptoSwift/CSArrayType+Extensions.swift

@@ -55,11 +55,11 @@ public extension CSArrayType where Generator.Element == UInt8 {
         return Hash.crc16(cs_arrayValue(), seed: seed).calculate()
     }
     
-    public func encrypt(cipher: CipherProtocol) throws -> [Generator.Element] {
+    public func encrypt(cipher: Cipher) throws -> [Generator.Element] {
         return try cipher.encrypt(cs_arrayValue())
     }
 
-    public func decrypt(cipher: CipherProtocol) throws -> [Generator.Element] {
+    public func decrypt(cipher: Cipher) throws -> [Generator.Element] {
         return try cipher.decrypt(cs_arrayValue())
     }
     

+ 8 - 5
Sources/CryptoSwift/ChaCha20.swift

@@ -170,7 +170,7 @@ extension ChaCha20 {
             self.chacha20 = chacha20
         }
 
-        public func update(bytes: [UInt8], isLast: Bool) throws -> [UInt8] {
+        public func updateWith(bytes bytes: [UInt8], isLast: Bool = false) throws -> [UInt8] {
             return try chacha20.encrypt(bytes)
         }
     }
@@ -184,7 +184,7 @@ extension ChaCha20 {
             self.chacha20 = chacha20
         }
 
-        public func update(bytes: [UInt8], isLast: Bool) throws -> [UInt8] {
+        public func updateWith(bytes bytes: [UInt8], isLast: Bool = false) throws -> [UInt8] {
             return try chacha20.decrypt(bytes)
         }
     }
@@ -192,16 +192,19 @@ extension ChaCha20 {
 
 // MARK: - Cipher
 
-extension ChaCha20: CipherProtocol {
+extension ChaCha20: UpdatableCryptor {
 
-    public func encryptor() -> Cryptor {
+    public func makeEncryptor() -> ChaCha20.Encryptor {
         return Encryptor(chacha20: self)
     }
 
-    public func decryptor() -> Cryptor {
+    public func makeDecryptor() -> ChaCha20.Decryptor {
         return Decryptor(chacha20: self)
     }
+}
 
+// MARK: Cipher
+extension ChaCha20: Cipher {
     public func encrypt(bytes:[UInt8]) throws -> [UInt8] {
         guard context != nil else {
             throw Error.MissingContext

+ 26 - 0
Sources/CryptoSwift/Cipher.swift

@@ -0,0 +1,26 @@
+//
+//  Cipher.swift
+//  CryptoSwift
+//
+//  Created by Marcin Krzyzanowski on 29/05/16.
+//  Copyright © 2016 Marcin Krzyzanowski. All rights reserved.
+//
+
+public enum CipherError: ErrorType {
+    case Encrypt
+    case Decrypt
+}
+
+public protocol Cipher {
+    /// Encrypt given bytes at once
+    ///
+    /// - parameter bytes: Plaintext data
+    /// - returns: Encrypted data
+    func encrypt(bytes: [UInt8]) throws -> [UInt8]
+
+    /// Decrypt given bytes at once
+    ///
+    /// - parameter bytes: Ciphertext data
+    /// - returns: Plaintext data
+    func decrypt(bytes: [UInt8]) throws -> [UInt8]
+}

+ 8 - 1
Sources/CryptoSwift/Cryptor.swift

@@ -12,5 +12,12 @@ public protocol Cryptor {
     /// - parameter bytes: Ciphertext data
     /// - parameter isLast: Given chunk is the last one. No more updates after this call.
     /// - returns: Plaintext data
-    mutating func update(bytes:[UInt8], isLast: Bool) throws -> [UInt8]
+    mutating func updateWith(bytes bytes:[UInt8], isLast: Bool) throws -> [UInt8]
+    mutating func finish(bytes bytes:[UInt8]) throws  -> [UInt8]
+}
+
+extension Cryptor {
+    mutating public func finish(bytes bytes:[UInt8] = []) throws  -> [UInt8] {
+        return try self.updateWith(bytes: bytes, isLast: true)
+    }
 }

+ 2 - 2
Sources/CryptoSwift/Foundation/NSData+Extension.swift

@@ -70,12 +70,12 @@ extension NSData {
         return NSData.withBytes(result)
     }
 
-    public func encrypt(cipher: CipherProtocol) throws -> NSData {
+    public func encrypt(cipher: Cipher) throws -> NSData {
         let encrypted = try cipher.encrypt(self.arrayOfBytes())
         return NSData.withBytes(encrypted)
     }
 
-    public func decrypt(cipher: CipherProtocol) throws -> NSData {
+    public func decrypt(cipher: Cipher) throws -> NSData {
         let decrypted = try cipher.decrypt(self.arrayOfBytes())
         return NSData.withBytes(decrypted)
     }

+ 2 - 2
Sources/CryptoSwift/Foundation/String+FoundationExtension.swift

@@ -11,7 +11,7 @@ import Foundation
 extension String {
 
     /// Return Base64 back to String
-    public func decryptBase64ToString(cipher: CipherProtocol) throws -> String {
+    public func decryptBase64ToString(cipher: Cipher) throws -> String {
         guard let decodedData = NSData(base64EncodedString: self, options: []) else {
             throw CipherError.Decrypt
         }
@@ -25,7 +25,7 @@ extension String {
         throw CipherError.Decrypt
     }
 
-    public func decryptBase64(cipher: CipherProtocol) throws -> [UInt8] {
+    public func decryptBase64(cipher: Cipher) throws -> [UInt8] {
         guard let decodedData = NSData(base64EncodedString: self, options: []) else {
             throw CipherError.Decrypt
         }

+ 9 - 6
Sources/CryptoSwift/Rabbit.swift

@@ -181,7 +181,7 @@ extension Rabbit {
             self.rabbit = rabbit
         }
 
-        public func update(bytes: [UInt8], isLast: Bool) throws -> [UInt8] {
+        public func updateWith(bytes bytes: [UInt8], isLast: Bool = false) throws -> [UInt8] {
             return rabbit.encrypt(bytes)
         }
     }
@@ -195,24 +195,27 @@ extension Rabbit {
             self.rabbit = rabbit
         }
 
-        public func update(bytes: [UInt8], isLast: Bool) throws -> [UInt8] {
+        public func updateWith(bytes bytes: [UInt8], isLast: Bool = false) throws -> [UInt8] {
             return rabbit.decrypt(bytes)
         }
     }
 }
 
 
-// MARK: CipherType
-extension Rabbit: CipherProtocol {
+// MARK: UpdatableCryptor
+extension Rabbit: UpdatableCryptor {
 
-    public func encryptor() -> Cryptor {
+    public func makeEncryptor() -> Rabbit.Encryptor {
         return Encryptor(rabbit: self)
     }
 
-    public func decryptor() -> Cryptor {
+    public func makeDecryptor() -> Rabbit.Decryptor {
         return Decryptor(rabbit: self)
     }
+}
 
+// MARK: Cipher
+extension Rabbit: Cipher {
     public func encrypt(bytes: [UInt8]) -> [UInt8] {
         setup()
 

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

@@ -41,11 +41,11 @@ extension String {
         return self.utf8.lazy.map({ $0 as UInt8 }).crc16(seed).toHexString()
     }
 
-    public func encrypt(cipher: CipherProtocol) throws -> [UInt8] {
+    public func encrypt(cipher: Cipher) throws -> [UInt8] {
         return try self.utf8.lazy.map({ $0 as UInt8 }).encrypt(cipher)
     }
 
-    public func decrypt(cipher: CipherProtocol) throws -> [UInt8] {
+    public func decrypt(cipher: Cipher) throws -> [UInt8] {
         return try self.utf8.lazy.map({ $0 as UInt8 }).decrypt(cipher)
     }
     

+ 7 - 21
Sources/CryptoSwift/CipherProtocol.swift → Sources/CryptoSwift/UpdatableCryptor.swift

@@ -1,5 +1,5 @@
 //
-//  CipherProtocol.swift
+//  UpdatableCryptor.swift
 //  CryptoSwift
 //
 //  Created by Marcin Krzyzanowski on 30/08/14.
@@ -12,35 +12,21 @@
     import Darwin
 #endif
 
-public enum CipherError: ErrorType {
-    case Encrypt
-    case Decrypt
-}
 
-public protocol CipherProtocol {
+public protocol UpdatableCryptor {
+    associatedtype EncryptorType: Cryptor
+    associatedtype DecryptorType: Cryptor
 
     /// Cryptor suitable for encryption
-    func encryptor() -> Cryptor;
+    func makeEncryptor() -> EncryptorType
 
     /// Cryptor suitable for decryption
-    func decryptor() -> Cryptor;
-
-    /// Encrypt given bytes at once
-    ///
-    /// - parameter bytes: Plaintext data
-    /// - returns: Encrypted data
-    func encrypt(bytes: [UInt8]) throws -> [UInt8]
+    func makeDecryptor() -> DecryptorType
 
-    /// Decrypt given bytes at once
-    ///
-    /// - parameter bytes: Ciphertext data
-    /// - returns: Plaintext data
-    func decrypt(bytes: [UInt8]) throws -> [UInt8]
-    
     static func randomIV(blockSize:Int) -> [UInt8]
 }
 
-extension CipherProtocol {
+extension UpdatableCryptor {
     static public func randomIV(blockSize:Int) -> [UInt8] {
         var randomIV:[UInt8] = [UInt8]();
         for _ in 0..<blockSize {