Browse Source

Decouple BlockMode into separate files

Marcin Krzyżanowski 9 years ago
parent
commit
62e4ef8834

+ 98 - 10
CryptoSwift.xcodeproj/project.pbxproj

@@ -79,10 +79,6 @@
 		757BC9591C1CA5790093AAA9 /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9211C1CA5790093AAA9 /* Cipher.swift */; };
 		757BC95A1C1CA5790093AAA9 /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9211C1CA5790093AAA9 /* Cipher.swift */; };
 		757BC95B1C1CA5790093AAA9 /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9211C1CA5790093AAA9 /* Cipher.swift */; };
-		757BC95C1C1CA5790093AAA9 /* CipherBlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9221C1CA5790093AAA9 /* CipherBlockMode.swift */; };
-		757BC95D1C1CA5790093AAA9 /* CipherBlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9221C1CA5790093AAA9 /* CipherBlockMode.swift */; };
-		757BC95E1C1CA5790093AAA9 /* CipherBlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9221C1CA5790093AAA9 /* CipherBlockMode.swift */; };
-		757BC95F1C1CA5790093AAA9 /* CipherBlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9221C1CA5790093AAA9 /* CipherBlockMode.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 */; };
@@ -182,6 +178,42 @@
 		758A94281A65C59200E46135 /* HMACTests.swift in Resources */ = {isa = PBXBuildFile; fileRef = 758A94271A65C59200E46135 /* HMACTests.swift */; };
 		758A94291A65C67400E46135 /* HMACTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758A94271A65C59200E46135 /* HMACTests.swift */; };
 		75B601EB197D6A6C0009B53D /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 754BE45519693E190098E6F3 /* CryptoSwift.framework */; };
+		75CB93251C8F5EC10087740D /* CBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93241C8F5EC10087740D /* CBC.swift */; };
+		75CB93261C8F5EC10087740D /* CBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93241C8F5EC10087740D /* CBC.swift */; };
+		75CB93271C8F5EC10087740D /* CBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93241C8F5EC10087740D /* CBC.swift */; };
+		75CB93281C8F5EC10087740D /* CBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93241C8F5EC10087740D /* CBC.swift */; };
+		75CB932B1C8F5EE90087740D /* BlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB932A1C8F5EE90087740D /* BlockMode.swift */; };
+		75CB932C1C8F5EE90087740D /* BlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB932A1C8F5EE90087740D /* BlockMode.swift */; };
+		75CB932D1C8F5EE90087740D /* BlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB932A1C8F5EE90087740D /* BlockMode.swift */; };
+		75CB932E1C8F5EE90087740D /* BlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB932A1C8F5EE90087740D /* BlockMode.swift */; };
+		75CB93301C8F5F580087740D /* CipherBlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB932F1C8F5F580087740D /* CipherBlockMode.swift */; };
+		75CB93311C8F5F580087740D /* CipherBlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB932F1C8F5F580087740D /* CipherBlockMode.swift */; };
+		75CB93321C8F5F580087740D /* CipherBlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB932F1C8F5F580087740D /* CipherBlockMode.swift */; };
+		75CB93331C8F5F580087740D /* CipherBlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB932F1C8F5F580087740D /* CipherBlockMode.swift */; };
+		75CB93351C8F5FCE0087740D /* PCBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93341C8F5FCE0087740D /* PCBC.swift */; };
+		75CB93361C8F5FCE0087740D /* PCBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93341C8F5FCE0087740D /* PCBC.swift */; };
+		75CB93371C8F5FCE0087740D /* PCBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93341C8F5FCE0087740D /* PCBC.swift */; };
+		75CB93381C8F5FCE0087740D /* PCBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93341C8F5FCE0087740D /* PCBC.swift */; };
+		75CB933A1C8F5FFD0087740D /* CFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93391C8F5FFD0087740D /* CFB.swift */; };
+		75CB933B1C8F5FFD0087740D /* CFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93391C8F5FFD0087740D /* CFB.swift */; };
+		75CB933C1C8F5FFD0087740D /* CFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93391C8F5FFD0087740D /* CFB.swift */; };
+		75CB933D1C8F5FFD0087740D /* CFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93391C8F5FFD0087740D /* CFB.swift */; };
+		75CB933F1C8F60070087740D /* OFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB933E1C8F60070087740D /* OFB.swift */; };
+		75CB93401C8F60070087740D /* OFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB933E1C8F60070087740D /* OFB.swift */; };
+		75CB93411C8F60070087740D /* OFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB933E1C8F60070087740D /* OFB.swift */; };
+		75CB93421C8F60070087740D /* OFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB933E1C8F60070087740D /* OFB.swift */; };
+		75CB93441C8F603C0087740D /* CTR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93431C8F603C0087740D /* CTR.swift */; };
+		75CB93451C8F603C0087740D /* CTR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93431C8F603C0087740D /* CTR.swift */; };
+		75CB93461C8F603C0087740D /* CTR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93431C8F603C0087740D /* CTR.swift */; };
+		75CB93471C8F603C0087740D /* CTR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93431C8F603C0087740D /* CTR.swift */; };
+		75CB93491C8F60700087740D /* ECB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93481C8F60700087740D /* ECB.swift */; };
+		75CB934A1C8F60700087740D /* ECB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93481C8F60700087740D /* ECB.swift */; };
+		75CB934B1C8F60700087740D /* ECB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93481C8F60700087740D /* ECB.swift */; };
+		75CB934C1C8F60700087740D /* ECB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB93481C8F60700087740D /* ECB.swift */; };
+		75CB934E1C8F609D0087740D /* BlockModeOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CB934D1C8F609D0087740D /* BlockModeOptions.swift */; };
+		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 */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -293,7 +325,6 @@
 		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 /* Cipher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Cipher.swift; path = Sources/CryptoSwift/Cipher.swift; sourceTree = SOURCE_ROOT; };
-		757BC9221C1CA5790093AAA9 /* CipherBlockMode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CipherBlockMode.swift; path = Sources/CryptoSwift/CipherBlockMode.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; };
@@ -323,6 +354,15 @@
 		757DA2561A4ED47B002BA3EF /* Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = "<group>"; };
 		757DA2581A4ED4D7002BA3EF /* ChaCha20Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChaCha20Tests.swift; sourceTree = "<group>"; };
 		758A94271A65C59200E46135 /* HMACTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HMACTests.swift; sourceTree = "<group>"; };
+		75CB93241C8F5EC10087740D /* CBC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CBC.swift; path = Sources/CryptoSwift/BlockMode/CBC.swift; sourceTree = SOURCE_ROOT; };
+		75CB932A1C8F5EE90087740D /* BlockMode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BlockMode.swift; path = Sources/CryptoSwift/BlockMode/BlockMode.swift; sourceTree = SOURCE_ROOT; };
+		75CB932F1C8F5F580087740D /* CipherBlockMode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CipherBlockMode.swift; path = Sources/CryptoSwift/BlockMode/CipherBlockMode.swift; sourceTree = SOURCE_ROOT; };
+		75CB93341C8F5FCE0087740D /* PCBC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PCBC.swift; path = Sources/CryptoSwift/BlockMode/PCBC.swift; sourceTree = SOURCE_ROOT; };
+		75CB93391C8F5FFD0087740D /* CFB.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CFB.swift; path = Sources/CryptoSwift/BlockMode/CFB.swift; sourceTree = SOURCE_ROOT; };
+		75CB933E1C8F60070087740D /* OFB.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OFB.swift; path = Sources/CryptoSwift/OFB.swift; sourceTree = SOURCE_ROOT; };
+		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; };
 		75D614BF1BD844F2001358B2 /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		75DF77721BC8EB59006E9520 /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 /* End PBXFileReference section */
@@ -407,7 +447,7 @@
 				757BC91F1C1CA5790093AAA9 /* BytesSequence.swift */,
 				757BC9201C1CA5790093AAA9 /* ChaCha20.swift */,
 				757BC9211C1CA5790093AAA9 /* Cipher.swift */,
-				757BC9221C1CA5790093AAA9 /* CipherBlockMode.swift */,
+				75CB93291C8F5EC60087740D /* BlockMode */,
 				757BC9231C1CA5790093AAA9 /* CRC.swift */,
 				757BC9251C1CA5790093AAA9 /* CSArrayType+Extensions.swift */,
 				757BC9261C1CA5790093AAA9 /* Generics.swift */,
@@ -488,6 +528,22 @@
 			path = Sources/CryptoSwift/Foundation;
 			sourceTree = SOURCE_ROOT;
 		};
+		75CB93291C8F5EC60087740D /* BlockMode */ = {
+			isa = PBXGroup;
+			children = (
+				75CB932A1C8F5EE90087740D /* BlockMode.swift */,
+				75CB934D1C8F609D0087740D /* BlockModeOptions.swift */,
+				75CB932F1C8F5F580087740D /* CipherBlockMode.swift */,
+				75CB93241C8F5EC10087740D /* CBC.swift */,
+				75CB93341C8F5FCE0087740D /* PCBC.swift */,
+				75CB93391C8F5FFD0087740D /* CFB.swift */,
+				75CB933E1C8F60070087740D /* OFB.swift */,
+				75CB93431C8F603C0087740D /* CTR.swift */,
+				75CB93481C8F60700087740D /* ECB.swift */,
+			);
+			name = BlockMode;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
@@ -719,12 +775,17 @@
 				757BC94D1C1CA5790093AAA9 /* BitExtension.swift in Sources */,
 				757BC9491C1CA5790093AAA9 /* Authenticator.swift in Sources */,
 				757BC9C11C1CA5790093AAA9 /* Utils.swift in Sources */,
+				75CB934A1C8F60700087740D /* ECB.swift in Sources */,
 				757BC9751C1CA5790093AAA9 /* HashProtocol.swift in Sources */,
 				757BC9071C1CA56A0093AAA9 /* ChaCha20+Foundation.swift in Sources */,
 				757BC9851C1CA5790093AAA9 /* IntExtension.swift in Sources */,
 				757BC9B11C1CA5790093AAA9 /* String+Extension.swift in Sources */,
 				757BC96D1C1CA5790093AAA9 /* Generics.swift in Sources */,
+				75CB93261C8F5EC10087740D /* CBC.swift in Sources */,
 				757BC9711C1CA5790093AAA9 /* Hash.swift in Sources */,
+				75CB932C1C8F5EE90087740D /* BlockMode.swift in Sources */,
+				75CB93361C8F5FCE0087740D /* PCBC.swift in Sources */,
+				75CB93311C8F5F580087740D /* CipherBlockMode.swift in Sources */,
 				757BC9171C1CA56A0093AAA9 /* Utils+Foundation.swift in Sources */,
 				757BC9B51C1CA5790093AAA9 /* UInt8Extension.swift in Sources */,
 				757BC9411C1CA5790093AAA9 /* Array+Extension.swift in Sources */,
@@ -732,19 +793,22 @@
 				757BC9691C1CA5790093AAA9 /* CSArrayType+Extensions.swift in Sources */,
 				757BC9611C1CA5790093AAA9 /* CRC.swift in Sources */,
 				757BC9A11C1CA5790093AAA9 /* Poly1305.swift in Sources */,
+				75CB93451C8F603C0087740D /* CTR.swift in Sources */,
 				757BC9451C1CA5790093AAA9 /* ArraySliceUInt8+Bytes.swift in Sources */,
 				757BC9BD1C1CA5790093AAA9 /* UInt64Extension.swift in Sources */,
 				757BC9991C1CA5790093AAA9 /* PKCS5.swift in Sources */,
+				75CB934F1C8F609D0087740D /* BlockModeOptions.swift in Sources */,
 				757BC9811C1CA5790093AAA9 /* IntegerConvertible.swift in Sources */,
 				757BC9511C1CA5790093AAA9 /* BytesSequence.swift in Sources */,
 				757BC9891C1CA5790093AAA9 /* MD5.swift in Sources */,
 				757BC9A91C1CA5790093AAA9 /* SHA1.swift in Sources */,
 				757BC9911C1CA5790093AAA9 /* Operators.swift in Sources */,
+				75CB933B1C8F5FFD0087740D /* CFB.swift in Sources */,
+				75CB93401C8F60070087740D /* OFB.swift in Sources */,
 				757BC9B91C1CA5790093AAA9 /* UInt32Extension.swift in Sources */,
 				757BC9131C1CA56A0093AAA9 /* String+FoundationExtension.swift in Sources */,
 				757BC98D1C1CA5790093AAA9 /* Multiplatform.swift in Sources */,
 				757BC93D1C1CA5790093AAA9 /* AES.swift in Sources */,
-				757BC95D1C1CA5790093AAA9 /* CipherBlockMode.swift in Sources */,
 				757BC9551C1CA5790093AAA9 /* ChaCha20.swift in Sources */,
 				757BC9951C1CA5790093AAA9 /* Padding.swift in Sources */,
 				757BC9A51C1CA5790093AAA9 /* Rabbit.swift in Sources */,
@@ -766,12 +830,17 @@
 				757BC94C1C1CA5790093AAA9 /* BitExtension.swift in Sources */,
 				757BC9481C1CA5790093AAA9 /* Authenticator.swift in Sources */,
 				757BC9C01C1CA5790093AAA9 /* Utils.swift in Sources */,
+				75CB93491C8F60700087740D /* ECB.swift in Sources */,
 				757BC9741C1CA5790093AAA9 /* HashProtocol.swift in Sources */,
 				757BC90E1C1CA56A0093AAA9 /* Rabbit+Foundation.swift in Sources */,
 				757BC9841C1CA5790093AAA9 /* IntExtension.swift in Sources */,
 				757BC9B01C1CA5790093AAA9 /* String+Extension.swift in Sources */,
 				757BC96C1C1CA5790093AAA9 /* Generics.swift in Sources */,
+				75CB93251C8F5EC10087740D /* CBC.swift in Sources */,
 				757BC9701C1CA5790093AAA9 /* Hash.swift in Sources */,
+				75CB932B1C8F5EE90087740D /* BlockMode.swift in Sources */,
+				75CB93351C8F5FCE0087740D /* PCBC.swift in Sources */,
+				75CB93301C8F5F580087740D /* CipherBlockMode.swift in Sources */,
 				757BC9121C1CA56A0093AAA9 /* String+FoundationExtension.swift in Sources */,
 				757BC9B41C1CA5790093AAA9 /* UInt8Extension.swift in Sources */,
 				757BC9401C1CA5790093AAA9 /* Array+Extension.swift in Sources */,
@@ -779,19 +848,22 @@
 				757BC9681C1CA5790093AAA9 /* CSArrayType+Extensions.swift in Sources */,
 				757BC9601C1CA5790093AAA9 /* CRC.swift in Sources */,
 				757BC9A01C1CA5790093AAA9 /* Poly1305.swift in Sources */,
+				75CB93441C8F603C0087740D /* CTR.swift in Sources */,
 				757BC9441C1CA5790093AAA9 /* ArraySliceUInt8+Bytes.swift in Sources */,
 				757BC9BC1C1CA5790093AAA9 /* UInt64Extension.swift in Sources */,
 				757BC9981C1CA5790093AAA9 /* PKCS5.swift in Sources */,
+				75CB934E1C8F609D0087740D /* BlockModeOptions.swift in Sources */,
 				757BC9801C1CA5790093AAA9 /* IntegerConvertible.swift in Sources */,
 				757BC9501C1CA5790093AAA9 /* BytesSequence.swift in Sources */,
 				757BC9881C1CA5790093AAA9 /* MD5.swift in Sources */,
 				757BC9A81C1CA5790093AAA9 /* SHA1.swift in Sources */,
 				757BC9901C1CA5790093AAA9 /* Operators.swift in Sources */,
+				75CB933A1C8F5FFD0087740D /* CFB.swift in Sources */,
+				75CB933F1C8F60070087740D /* OFB.swift in Sources */,
 				757BC9B81C1CA5790093AAA9 /* UInt32Extension.swift in Sources */,
 				757BC8FE1C1CA56A0093AAA9 /* AES+Foundation.swift in Sources */,
 				757BC98C1C1CA5790093AAA9 /* Multiplatform.swift in Sources */,
 				757BC93C1C1CA5790093AAA9 /* AES.swift in Sources */,
-				757BC95C1C1CA5790093AAA9 /* CipherBlockMode.swift in Sources */,
 				757BC9541C1CA5790093AAA9 /* ChaCha20.swift in Sources */,
 				757BC9941C1CA5790093AAA9 /* Padding.swift in Sources */,
 				757BC9A41C1CA5790093AAA9 /* Rabbit.swift in Sources */,
@@ -829,12 +901,17 @@
 				757BC94E1C1CA5790093AAA9 /* BitExtension.swift in Sources */,
 				757BC94A1C1CA5790093AAA9 /* Authenticator.swift in Sources */,
 				757BC9C21C1CA5790093AAA9 /* Utils.swift in Sources */,
+				75CB934B1C8F60700087740D /* ECB.swift in Sources */,
 				757BC9761C1CA5790093AAA9 /* HashProtocol.swift in Sources */,
 				757BC9101C1CA56A0093AAA9 /* Rabbit+Foundation.swift in Sources */,
 				757BC9861C1CA5790093AAA9 /* IntExtension.swift in Sources */,
 				757BC9B21C1CA5790093AAA9 /* String+Extension.swift in Sources */,
 				757BC96E1C1CA5790093AAA9 /* Generics.swift in Sources */,
+				75CB93271C8F5EC10087740D /* CBC.swift in Sources */,
 				757BC9721C1CA5790093AAA9 /* Hash.swift in Sources */,
+				75CB932D1C8F5EE90087740D /* BlockMode.swift in Sources */,
+				75CB93371C8F5FCE0087740D /* PCBC.swift in Sources */,
+				75CB93321C8F5F580087740D /* CipherBlockMode.swift in Sources */,
 				757BC9141C1CA56A0093AAA9 /* String+FoundationExtension.swift in Sources */,
 				757BC9B61C1CA5790093AAA9 /* UInt8Extension.swift in Sources */,
 				757BC9421C1CA5790093AAA9 /* Array+Extension.swift in Sources */,
@@ -842,19 +919,22 @@
 				757BC96A1C1CA5790093AAA9 /* CSArrayType+Extensions.swift in Sources */,
 				757BC9621C1CA5790093AAA9 /* CRC.swift in Sources */,
 				757BC9A21C1CA5790093AAA9 /* Poly1305.swift in Sources */,
+				75CB93461C8F603C0087740D /* CTR.swift in Sources */,
 				757BC9461C1CA5790093AAA9 /* ArraySliceUInt8+Bytes.swift in Sources */,
 				757BC9BE1C1CA5790093AAA9 /* UInt64Extension.swift in Sources */,
 				757BC99A1C1CA5790093AAA9 /* PKCS5.swift in Sources */,
+				75CB93501C8F609D0087740D /* BlockModeOptions.swift in Sources */,
 				757BC9821C1CA5790093AAA9 /* IntegerConvertible.swift in Sources */,
 				757BC9521C1CA5790093AAA9 /* BytesSequence.swift in Sources */,
 				757BC98A1C1CA5790093AAA9 /* MD5.swift in Sources */,
 				757BC9AA1C1CA5790093AAA9 /* SHA1.swift in Sources */,
 				757BC9921C1CA5790093AAA9 /* Operators.swift in Sources */,
+				75CB933C1C8F5FFD0087740D /* CFB.swift in Sources */,
+				75CB93411C8F60070087740D /* OFB.swift in Sources */,
 				757BC9BA1C1CA5790093AAA9 /* UInt32Extension.swift in Sources */,
 				757BC9001C1CA56A0093AAA9 /* AES+Foundation.swift in Sources */,
 				757BC98E1C1CA5790093AAA9 /* Multiplatform.swift in Sources */,
 				757BC93E1C1CA5790093AAA9 /* AES.swift in Sources */,
-				757BC95E1C1CA5790093AAA9 /* CipherBlockMode.swift in Sources */,
 				757BC9561C1CA5790093AAA9 /* ChaCha20.swift in Sources */,
 				757BC9961C1CA5790093AAA9 /* Padding.swift in Sources */,
 				757BC9A61C1CA5790093AAA9 /* Rabbit.swift in Sources */,
@@ -876,12 +956,17 @@
 				757BC94F1C1CA5790093AAA9 /* BitExtension.swift in Sources */,
 				757BC94B1C1CA5790093AAA9 /* Authenticator.swift in Sources */,
 				757BC9C31C1CA5790093AAA9 /* Utils.swift in Sources */,
+				75CB934C1C8F60700087740D /* ECB.swift in Sources */,
 				757BC9771C1CA5790093AAA9 /* HashProtocol.swift in Sources */,
 				757BC9091C1CA56A0093AAA9 /* ChaCha20+Foundation.swift in Sources */,
 				757BC9871C1CA5790093AAA9 /* IntExtension.swift in Sources */,
 				757BC9B31C1CA5790093AAA9 /* String+Extension.swift in Sources */,
 				757BC96F1C1CA5790093AAA9 /* Generics.swift in Sources */,
+				75CB93281C8F5EC10087740D /* CBC.swift in Sources */,
 				757BC9731C1CA5790093AAA9 /* Hash.swift in Sources */,
+				75CB932E1C8F5EE90087740D /* BlockMode.swift in Sources */,
+				75CB93381C8F5FCE0087740D /* PCBC.swift in Sources */,
+				75CB93331C8F5F580087740D /* CipherBlockMode.swift in Sources */,
 				757BC9191C1CA56A0093AAA9 /* Utils+Foundation.swift in Sources */,
 				757BC9B71C1CA5790093AAA9 /* UInt8Extension.swift in Sources */,
 				757BC9431C1CA5790093AAA9 /* Array+Extension.swift in Sources */,
@@ -889,19 +974,22 @@
 				757BC96B1C1CA5790093AAA9 /* CSArrayType+Extensions.swift in Sources */,
 				757BC9631C1CA5790093AAA9 /* CRC.swift in Sources */,
 				757BC9A31C1CA5790093AAA9 /* Poly1305.swift in Sources */,
+				75CB93471C8F603C0087740D /* CTR.swift in Sources */,
 				757BC9471C1CA5790093AAA9 /* ArraySliceUInt8+Bytes.swift in Sources */,
 				757BC9BF1C1CA5790093AAA9 /* UInt64Extension.swift in Sources */,
 				757BC99B1C1CA5790093AAA9 /* PKCS5.swift in Sources */,
+				75CB93511C8F609D0087740D /* BlockModeOptions.swift in Sources */,
 				757BC9831C1CA5790093AAA9 /* IntegerConvertible.swift in Sources */,
 				757BC9531C1CA5790093AAA9 /* BytesSequence.swift in Sources */,
 				757BC98B1C1CA5790093AAA9 /* MD5.swift in Sources */,
 				757BC9AB1C1CA5790093AAA9 /* SHA1.swift in Sources */,
 				757BC9931C1CA5790093AAA9 /* Operators.swift in Sources */,
+				75CB933D1C8F5FFD0087740D /* CFB.swift in Sources */,
+				75CB93421C8F60070087740D /* OFB.swift in Sources */,
 				757BC9BB1C1CA5790093AAA9 /* UInt32Extension.swift in Sources */,
 				757BC9151C1CA56A0093AAA9 /* String+FoundationExtension.swift in Sources */,
 				757BC98F1C1CA5790093AAA9 /* Multiplatform.swift in Sources */,
 				757BC93F1C1CA5790093AAA9 /* AES.swift in Sources */,
-				757BC95F1C1CA5790093AAA9 /* CipherBlockMode.swift in Sources */,
 				757BC9571C1CA5790093AAA9 /* ChaCha20.swift in Sources */,
 				757BC9971C1CA5790093AAA9 /* Padding.swift in Sources */,
 				757BC9A71C1CA5790093AAA9 /* Rabbit.swift in Sources */,

+ 22 - 0
Sources/CryptoSwift/BlockMode/BlockMode.swift

@@ -0,0 +1,22 @@
+//
+//  BlockMode.swift
+//  CryptoSwift
+//
+//  Created by Marcin Krzyzanowski on 08/03/16.
+//  Copyright © 2016 Marcin Krzyzanowski. All rights reserved.
+//
+
+import Foundation
+
+// I have no better name for that
+typealias CipherOperationOnBlock = (block: [UInt8]) -> [UInt8]?
+
+enum BlockError: ErrorType {
+    case MissingInitializationVector
+}
+
+protocol BlockMode {
+    var options: BlockModeOptions { get }
+    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8]
+    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8]
+}

+ 15 - 0
Sources/CryptoSwift/BlockMode/BlockModeOptions.swift

@@ -0,0 +1,15 @@
+//
+//  BlockModeOptions.swift
+//  CryptoSwift
+//
+//  Created by Marcin Krzyzanowski on 08/03/16.
+//  Copyright © 2016 Marcin Krzyzanowski. All rights reserved.
+//
+
+struct BlockModeOptions: OptionSetType {
+    let rawValue: Int
+
+    static let None = BlockModeOptions(rawValue: 0)
+    static let InitializationVectorRequired = BlockModeOptions(rawValue: 1)
+    static let PaddingRequired = BlockModeOptions(rawValue: 2)
+}

+ 50 - 0
Sources/CryptoSwift/BlockMode/CBC.swift

@@ -0,0 +1,50 @@
+//
+//  CBC.swift
+//  CryptoSwift
+//
+//  Created by Marcin Krzyzanowski on 08/03/16.
+//  Copyright © 2016 Marcin Krzyzanowski. All rights reserved.
+//
+//  Cipher-block chaining (CBC)
+//
+
+struct CBCMode: BlockMode {
+    let options: BlockModeOptions = [.InitializationVectorRequired, .PaddingRequired]
+
+    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
+        precondition(blocks.count > 0)
+        guard let iv = iv else {
+            throw BlockError.MissingInitializationVector
+        }
+
+        var out:[UInt8] = [UInt8]()
+        out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
+        var prevCiphertext = iv // for the first time prevCiphertext = iv
+        for plaintext in blocks {
+            if let encrypted = cipherOperation(block: xor(prevCiphertext, plaintext)) {
+                out.appendContentsOf(encrypted)
+                prevCiphertext = encrypted
+            }
+        }
+        return out
+    }
+
+    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
+        precondition(blocks.count > 0)
+        guard let iv = iv else {
+            throw BlockError.MissingInitializationVector
+        }
+
+        var out:[UInt8] = [UInt8]()
+        out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
+        var prevCiphertext = iv // for the first time prevCiphertext = iv
+        for ciphertext in blocks {
+            if let decrypted = cipherOperation(block: ciphertext) { // decrypt
+                out.appendContentsOf(xor(prevCiphertext, decrypted))
+            }
+            prevCiphertext = ciphertext
+        }
+
+        return out
+    }
+}

+ 50 - 0
Sources/CryptoSwift/BlockMode/CFB.swift

@@ -0,0 +1,50 @@
+//
+//  CFB.swift
+//  CryptoSwift
+//
+//  Created by Marcin Krzyzanowski on 08/03/16.
+//  Copyright © 2016 Marcin Krzyzanowski. All rights reserved.
+//
+//  Cipher feedback (CFB)
+//
+
+struct CFBMode: BlockMode {
+    let options: BlockModeOptions = [.InitializationVectorRequired]
+
+    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[blocks.startIndex].count)
+
+        var lastCiphertext = iv
+        for plaintext in blocks {
+            if let ciphertext = cipherOperation(block: lastCiphertext) {
+                lastCiphertext = xor(plaintext, ciphertext)
+                out.appendContentsOf(lastCiphertext)
+            }
+        }
+        return out
+    }
+
+    func decryptBlocks(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[blocks.startIndex].count)
+
+        var lastCiphertext = iv
+        for ciphertext in blocks {
+            if let decrypted = cipherOperation(block: lastCiphertext) {
+                out.appendContentsOf(xor(decrypted, ciphertext))
+            }
+            lastCiphertext = ciphertext
+        }
+
+        return out
+    }
+}

+ 59 - 0
Sources/CryptoSwift/BlockMode/CTR.swift

@@ -0,0 +1,59 @@
+//
+//  CTR.swift
+//  CryptoSwift
+//
+//  Created by Marcin Krzyzanowski on 08/03/16.
+//  Copyright © 2016 Marcin Krzyzanowski. All rights reserved.
+//
+//  Counter (CTR)
+//
+
+struct CTRMode: BlockMode {
+    let options = BlockModeOptions.InitializationVectorRequired
+
+    private func buildNonce(iv: [UInt8], counter: UInt64) -> [UInt8] {
+        let noncePartLen = AES.blockSize / 2
+        let noncePrefix = Array(iv[0..<noncePartLen])
+        let nonceSuffix = Array(iv[noncePartLen..<iv.count])
+        let c = UInt64.withBytes(nonceSuffix) + counter
+        return noncePrefix + arrayOfBytes(c)
+    }
+
+    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[blocks.startIndex].count)
+        for plaintext in blocks {
+            let nonce = buildNonce(iv, counter: UInt64(counter))
+            counter += 1
+            if let encrypted = cipherOperation(block: nonce) {
+                out.appendContentsOf(xor(plaintext, encrypted))
+            }
+        }
+        return out
+    }
+
+    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
+        guard let iv = iv else {
+            throw BlockError.MissingInitializationVector
+        }
+
+        var counter:UInt = 0
+        var out = [UInt8]()
+        out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
+        for ciphertext in blocks {
+            let nonce = buildNonce(iv, counter: UInt64(counter))
+            counter += 1
+            if let decrypted = cipherOperation(block: nonce) {
+                out.appendContentsOf(xor(decrypted, ciphertext))
+            }
+        }
+        return out
+    }
+}

+ 62 - 0
Sources/CryptoSwift/BlockMode/CipherBlockMode.swift

@@ -0,0 +1,62 @@
+//
+//  CipherBlockMode.swift
+//  CryptoSwift
+//
+//  Created by Marcin Krzyzanowski on 08/03/16.
+//  Copyright © 2016 Marcin Krzyzanowski. All rights reserved.
+//
+
+import Foundation
+
+public enum CipherBlockMode {
+    case ECB, CBC, PCBC, CFB, OFB, CTR
+
+    private var mode:BlockMode {
+        switch (self) {
+        case CBC:
+            return CBCMode()
+        case PCBC:
+            return PCBCMode()
+        case CFB:
+            return CFBMode()
+        case OFB:
+            return OFBMode()
+        case ECB:
+            return ECBMode()
+        case CTR:
+            return CTRMode()
+        }
+    }
+
+    var options: BlockModeOptions { return mode.options }
+
+    /**
+     Process input blocks with given block cipher mode. With fallback to plain mode.
+
+     - parameter blocks: cipher block size blocks
+     - parameter iv:     IV
+     - parameter cipher: single block encryption closure
+
+     - returns: encrypted bytes
+     */
+    func encryptBlocks(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 try finalBlockMode.mode.encryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
+    }
+
+    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 try finalBlockMode.mode.decryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
+    }
+}

+ 28 - 0
Sources/CryptoSwift/BlockMode/ECB.swift

@@ -0,0 +1,28 @@
+//
+//  CipherBlockMode.swift
+//  CryptoSwift
+//
+//  Created by Marcin Krzyzanowski on 27/12/14.
+//  Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
+//
+//  Electronic codebook (ECB)
+//
+
+struct ECBMode: BlockMode {
+    let options: BlockModeOptions = [.PaddingRequired]
+
+    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8] {
+        var out:[UInt8] = [UInt8]()
+        out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
+        for plaintext in blocks {
+            if let encrypted = cipherOperation(block: plaintext) {
+                out.appendContentsOf(encrypted)
+            }
+        }
+        return out
+    }
+    
+    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8] {
+        return encryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
+    }
+}

+ 59 - 0
Sources/CryptoSwift/BlockMode/PCBC.swift

@@ -0,0 +1,59 @@
+//
+//  PCBM.swift
+//  CryptoSwift
+//
+//  Created by Marcin Krzyzanowski on 08/03/16.
+//  Copyright © 2016 Marcin Krzyzanowski. All rights reserved.
+//
+//  Propagating Cipher Block Chaining (PCBC)
+//
+
+struct PCBCMode: BlockMode {
+    let options: BlockModeOptions = [.InitializationVectorRequired, .PaddingRequired]
+
+    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
+        precondition(blocks.count > 0)
+        guard let iv = iv else {
+            throw BlockError.MissingInitializationVector
+        }
+
+        var out:[UInt8] = [UInt8]()
+        out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
+        var prevCiphertext = iv // for the first time prevCiphertext = iv
+        for plaintext in blocks {
+            guard let encrypted = cipherOperation(block: xor(prevCiphertext, plaintext)) else {
+                out.appendContentsOf(plaintext)
+                continue
+            }
+
+            let ciphertext = encrypted
+            out.appendContentsOf(ciphertext)
+
+            prevCiphertext = xor(plaintext, ciphertext)
+        }
+        return out
+    }
+
+    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
+        precondition(blocks.count > 0)
+        guard let iv = iv else {
+            throw BlockError.MissingInitializationVector
+        }
+
+        var out:[UInt8] = [UInt8]()
+        out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
+        var prevCiphertext = iv // for the first time prevCiphertext = iv
+        for ciphertext in blocks {
+            guard let decrypted = cipherOperation(block: ciphertext) else {
+                out.appendContentsOf(ciphertext)
+                continue
+            }
+
+            let plaintext = xor(prevCiphertext, decrypted)
+            out.appendContentsOf(plaintext)
+            prevCiphertext = xor(plaintext, ciphertext)
+        }
+        
+        return out
+    }
+}

+ 0 - 350
Sources/CryptoSwift/CipherBlockMode.swift

@@ -1,350 +0,0 @@
-//
-//  CipherBlockMode.swift
-//  CryptoSwift
-//
-//  Created by Marcin Krzyzanowski on 27/12/14.
-//  Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
-//
-
-// I have no better name for that
-typealias CipherOperationOnBlock = (block: [UInt8]) -> [UInt8]?
-
-enum BlockError: ErrorType {
-    case MissingInitializationVector
-}
-
-struct BlockModeOptions: OptionSetType {
-    let rawValue: Int
-
-    static let None = BlockModeOptions(rawValue: 0)
-    static let InitializationVectorRequired = BlockModeOptions(rawValue: 1)
-    static let PaddingRequired = BlockModeOptions(rawValue: 2)
-}
-
-private protocol BlockMode {
-    var options: BlockModeOptions { get }
-    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8]
-    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8]
-}
-
-public enum CipherBlockMode {
-    case ECB, CBC, PCBC, CFB, OFB, CTR
-    
-    private var mode:BlockMode {
-        switch (self) {
-        case CBC:
-            return CBCMode()
-        case PCBC:
-            return PCBCMode()
-        case CFB:
-            return CFBMode()
-        case OFB:
-            return OFBMode()
-        case ECB:
-            return ECBMode()
-        case CTR:
-            return CTRMode()
-        }
-    }
-
-    var options: BlockModeOptions { return mode.options }
-    
-    /**
-    Process input blocks with given block cipher mode. With fallback to plain mode.
-    
-    - parameter blocks: cipher block size blocks
-    - parameter iv:     IV
-    - parameter cipher: single block encryption closure
-    
-    - returns: encrypted bytes
-    */
-    func encryptBlocks(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 try finalBlockMode.mode.encryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
-    }
-    
-    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 try finalBlockMode.mode.decryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
-    }
-}
-
-/**
-Cipher-block chaining (CBC)
-*/
-private struct CBCMode: BlockMode {
-    let options: BlockModeOptions = [.InitializationVectorRequired, .PaddingRequired]
-    
-    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
-        precondition(blocks.count > 0)
-        guard let iv = iv else {
-            throw BlockError.MissingInitializationVector
-        }
-        
-        var out:[UInt8] = [UInt8]()
-        out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
-        var prevCiphertext = iv // for the first time prevCiphertext = iv
-        for plaintext in blocks {
-            if let encrypted = cipherOperation(block: xor(prevCiphertext, plaintext)) {
-                out.appendContentsOf(encrypted)
-                prevCiphertext = encrypted
-            }
-        }
-        return out
-    }
-    
-    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
-        precondition(blocks.count > 0)
-        guard let iv = iv else {
-            throw BlockError.MissingInitializationVector
-        }
-
-        var out:[UInt8] = [UInt8]()
-        out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
-        var prevCiphertext = iv // for the first time prevCiphertext = iv
-        for ciphertext in blocks {
-            if let decrypted = cipherOperation(block: ciphertext) { // decrypt
-                out.appendContentsOf(xor(prevCiphertext, decrypted))
-            }
-            prevCiphertext = ciphertext
-        }
-        
-        return out
-    }
-}
-
-/**
- Propagating Cipher Block Chaining (PCBC)
- */
-private struct PCBCMode: BlockMode {
-    let options: BlockModeOptions = [.InitializationVectorRequired, .PaddingRequired]
-
-    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
-        precondition(blocks.count > 0)
-        guard let iv = iv else {
-            throw BlockError.MissingInitializationVector
-        }
-
-        var out:[UInt8] = [UInt8]()
-        out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
-        var prevCiphertext = iv // for the first time prevCiphertext = iv
-        for plaintext in blocks {
-            guard let encrypted = cipherOperation(block: xor(prevCiphertext, plaintext)) else {
-                out.appendContentsOf(plaintext)
-                continue
-            }
-
-            let ciphertext = encrypted
-            out.appendContentsOf(ciphertext)
-
-            prevCiphertext = xor(plaintext, ciphertext)
-        }
-        return out
-    }
-
-    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
-        precondition(blocks.count > 0)
-        guard let iv = iv else {
-            throw BlockError.MissingInitializationVector
-        }
-
-        var out:[UInt8] = [UInt8]()
-        out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
-        var prevCiphertext = iv // for the first time prevCiphertext = iv
-        for ciphertext in blocks {
-            guard let decrypted = cipherOperation(block: ciphertext) else {
-                out.appendContentsOf(ciphertext)
-                continue
-            }
-
-            let plaintext = xor(prevCiphertext, decrypted)
-            out.appendContentsOf(plaintext)
-            prevCiphertext = xor(plaintext, ciphertext)
-        }
-
-        return out
-    }
-}
-
-/**
-Cipher feedback (CFB)
-*/
-private struct CFBMode: BlockMode {
-    let options: BlockModeOptions = [.InitializationVectorRequired]
-
-    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[blocks.startIndex].count)
-
-        var lastCiphertext = iv
-        for plaintext in blocks {
-            if let ciphertext = cipherOperation(block: lastCiphertext) {
-                lastCiphertext = xor(plaintext, ciphertext)
-                out.appendContentsOf(lastCiphertext)
-            }
-        }
-        return out
-    }
-    
-    func decryptBlocks(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[blocks.startIndex].count)
-
-        var lastCiphertext = iv
-        for ciphertext in blocks {
-            if let decrypted = cipherOperation(block: lastCiphertext) {
-                out.appendContentsOf(xor(decrypted, ciphertext))
-            }
-            lastCiphertext = ciphertext
-        }
-        
-        return out
-    }
-}
-
-/**
- Output Feedback (OFB)
- */
-private struct OFBMode: BlockMode {
-    let options: BlockModeOptions = [.InitializationVectorRequired]
-
-    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[blocks.startIndex].count)
-
-        var lastEncryptedBlock = iv
-        for plaintext in blocks {
-            guard let ciphertext = cipherOperation(block: lastEncryptedBlock) else {
-                out.appendContentsOf(plaintext)
-                continue
-            }
-
-            lastEncryptedBlock = ciphertext
-            out.appendContentsOf(xor(plaintext, ciphertext))
-        }
-        return out
-    }
-
-    func decryptBlocks(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[blocks.startIndex].count)
-
-        var lastDecryptedBlock = iv
-        for ciphertext in blocks {
-            guard let decrypted = cipherOperation(block: lastDecryptedBlock) else {
-                out.appendContentsOf(ciphertext)
-                continue
-            }
-
-            lastDecryptedBlock = decrypted
-
-            let plaintext = xor(decrypted, ciphertext)
-            out.appendContentsOf(plaintext)
-        }
-
-        return out
-    }
-}
-
-/**
-Electronic codebook (ECB)
-*/
-private struct ECBMode: BlockMode {
-    let options: BlockModeOptions = [.PaddingRequired]
-
-    func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8] {
-        var out:[UInt8] = [UInt8]()
-        out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
-        for plaintext in blocks {
-            if let encrypted = cipherOperation(block: plaintext) {
-                out.appendContentsOf(encrypted)
-            }
-        }
-        return out
-    }
-    
-    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8] {
-        return encryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
-    }
-}
-
-/**
-Counter (CTR)
-*/
-private struct CTRMode: BlockMode {
-    let options = BlockModeOptions.InitializationVectorRequired
-
-    private func buildNonce(iv: [UInt8], counter: UInt64) -> [UInt8] {
-        let noncePartLen = AES.blockSize / 2
-        let noncePrefix = Array(iv[0..<noncePartLen])
-        let nonceSuffix = Array(iv[noncePartLen..<iv.count])
-        let c = UInt64.withBytes(nonceSuffix) + counter
-        return noncePrefix + arrayOfBytes(c)
-    }
-    
-    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[blocks.startIndex].count)
-        for plaintext in blocks {
-            let nonce = buildNonce(iv, counter: UInt64(counter))
-            counter += 1
-            if let encrypted = cipherOperation(block: nonce) {
-                out.appendContentsOf(xor(plaintext, encrypted))
-            }
-        }
-        return out
-    }
-    
-    func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
-        guard let iv = iv else {
-            throw BlockError.MissingInitializationVector
-        }
-        
-        var counter:UInt = 0
-        var out = [UInt8]()
-        out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
-        for ciphertext in blocks {
-            let nonce = buildNonce(iv, counter: UInt64(counter))
-            counter += 1
-            if let decrypted = cipherOperation(block: nonce) {
-                out.appendContentsOf(xor(decrypted, ciphertext))
-            }
-        }
-        return out
-    }
-
-}

+ 58 - 0
Sources/CryptoSwift/OFB.swift

@@ -0,0 +1,58 @@
+//
+//  OFB.swift
+//  CryptoSwift
+//
+//  Created by Marcin Krzyzanowski on 08/03/16.
+//  Copyright © 2016 Marcin Krzyzanowski. All rights reserved.
+//
+// Output Feedback (OFB)
+//
+
+struct OFBMode: BlockMode {
+    let options: BlockModeOptions = [.InitializationVectorRequired]
+
+    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[blocks.startIndex].count)
+
+        var lastEncryptedBlock = iv
+        for plaintext in blocks {
+            guard let ciphertext = cipherOperation(block: lastEncryptedBlock) else {
+                out.appendContentsOf(plaintext)
+                continue
+            }
+
+            lastEncryptedBlock = ciphertext
+            out.appendContentsOf(xor(plaintext, ciphertext))
+        }
+        return out
+    }
+
+    func decryptBlocks(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[blocks.startIndex].count)
+
+        var lastDecryptedBlock = iv
+        for ciphertext in blocks {
+            guard let decrypted = cipherOperation(block: lastDecryptedBlock) else {
+                out.appendContentsOf(ciphertext)
+                continue
+            }
+
+            lastDecryptedBlock = decrypted
+
+            let plaintext = xor(decrypted, ciphertext)
+            out.appendContentsOf(plaintext)
+        }
+        
+        return out
+    }
+}