Browse Source

Merge branch 'develop'

Marcin Krzyżanowski 7 years ago
parent
commit
d6c36ba67c
70 changed files with 649 additions and 301 deletions
  1. 7 14
      .github/ISSUE_TEMPLATE.md
  2. 1 1
      .swift-version
  3. 5 0
      CHANGELOG
  4. 42 8
      CryptoSwift.xcodeproj/project.pbxproj
  5. 3 5
      CryptoSwift.xcodeproj/xcshareddata/xcschemes/CryptoSwift.xcscheme
  6. 8 0
      CryptoSwift.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  7. 1 1
      Package.swift
  8. 15 3
      README.md
  9. 40 0
      Sources/CryptoSwift/AEAD/AEAD.swift
  10. 59 0
      Sources/CryptoSwift/AEAD/AEADChaCha20Poly1305.swift
  11. 3 1
      Sources/CryptoSwift/AES.Cryptors.swift
  12. 14 14
      Sources/CryptoSwift/AES.swift
  13. 80 20
      Sources/CryptoSwift/Array+Extension.swift
  14. 0 82
      Sources/CryptoSwift/Array+Extensions.swift
  15. 3 3
      Sources/CryptoSwift/BatchedCollection.swift
  16. 0 1
      Sources/CryptoSwift/Bit.swift
  17. 7 8
      Sources/CryptoSwift/Blowfish.swift
  18. 99 0
      Sources/CryptoSwift/CMAC.swift
  19. 7 6
      Sources/CryptoSwift/ChaCha20.swift
  20. 1 1
      Sources/CryptoSwift/Checksum.swift
  21. 2 0
      Sources/CryptoSwift/Cipher.swift
  22. 0 1
      Sources/CryptoSwift/Collection+Extension.swift
  23. 23 0
      Sources/CryptoSwift/CompactMap.swift
  24. 0 1
      Sources/CryptoSwift/Cryptors.swift
  25. 0 1
      Sources/CryptoSwift/Digest.swift
  26. 0 1
      Sources/CryptoSwift/Foundation/AES+Foundation.swift
  27. 0 1
      Sources/CryptoSwift/Foundation/Array+Foundation.swift
  28. 0 1
      Sources/CryptoSwift/Foundation/Blowfish+Foundation.swift
  29. 0 1
      Sources/CryptoSwift/Foundation/ChaCha20+Foundation.swift
  30. 0 2
      Sources/CryptoSwift/Foundation/Data+Extension.swift
  31. 0 1
      Sources/CryptoSwift/Foundation/HMAC+Foundation.swift
  32. 0 1
      Sources/CryptoSwift/Foundation/Rabbit+Foundation.swift
  33. 0 1
      Sources/CryptoSwift/Foundation/String+FoundationExtension.swift
  34. 2 2
      Sources/CryptoSwift/Generics.swift
  35. 13 15
      Sources/CryptoSwift/HKDF.swift
  36. 0 1
      Sources/CryptoSwift/HMAC.swift
  37. 0 1
      Sources/CryptoSwift/MD5.swift
  38. 0 1
      Sources/CryptoSwift/NoPadding.swift
  39. 0 2
      Sources/CryptoSwift/PKCS/PBKDF1.swift
  40. 0 3
      Sources/CryptoSwift/PKCS/PBKDF2.swift
  41. 0 1
      Sources/CryptoSwift/PKCS/PKCS7Padding.swift
  42. 0 1
      Sources/CryptoSwift/Poly1305.swift
  43. 7 2
      Sources/CryptoSwift/Rabbit.swift
  44. 2 3
      Sources/CryptoSwift/SHA1.swift
  45. 4 5
      Sources/CryptoSwift/SHA2.swift
  46. 4 5
      Sources/CryptoSwift/SHA3.swift
  47. 0 1
      Sources/CryptoSwift/String+Extension.swift
  48. 0 1
      Sources/CryptoSwift/UInt16+Extension.swift
  49. 0 1
      Sources/CryptoSwift/UInt32+Extension.swift
  50. 0 1
      Sources/CryptoSwift/UInt64+Extension.swift
  51. 0 2
      Sources/CryptoSwift/UInt8+Extension.swift
  52. 0 2
      Sources/CryptoSwift/Updatable.swift
  53. 5 5
      Sources/CryptoSwift/Utils.swift
  54. 0 1
      Sources/CryptoSwift/ZeroPadding.swift
  55. 2 4
      Tests/CryptoSwiftTests/AESTests.swift
  56. 2 2
      Tests/CryptoSwiftTests/Access.swift
  57. 1 3
      Tests/CryptoSwiftTests/BlowfishTests.swift
  58. 64 0
      Tests/CryptoSwiftTests/CMACTests.swift
  59. 84 0
      Tests/CryptoSwiftTests/ChaCha20Poly1305Tests.swift
  60. 2 5
      Tests/CryptoSwiftTests/ChaCha20Tests.swift
  61. 12 15
      Tests/CryptoSwiftTests/DigestTests.swift
  62. 2 5
      Tests/CryptoSwiftTests/ExtensionsTest.swift
  63. 14 15
      Tests/CryptoSwiftTests/HKDFTests.swift
  64. 1 2
      Tests/CryptoSwiftTests/HMACTests.swift
  65. 1 2
      Tests/CryptoSwiftTests/PBKDF.swift
  66. 1 2
      Tests/CryptoSwiftTests/PaddingTests.swift
  67. 2 3
      Tests/CryptoSwiftTests/Poly1305Tests.swift
  68. 1 4
      Tests/CryptoSwiftTests/RabbitTests.swift
  69. 1 2
      Tests/CryptoSwiftTests/RandomBytesSequenceTests.swift
  70. 2 1
      Tests/LinuxMain.swift

+ 7 - 14
.github/ISSUE_TEMPLATE.md

@@ -1,28 +1,21 @@
-# Details
-
 - CryptoSwift version: 
 - Swift version: 
-- Platform version: 
-	- [ ] iOS/tvOS/watchOS
-	- [ ] macOS
-	- [ ] Linux
-- Installation: 
-	- [ ] CocoaPods
-	- [ ] Carthage
-	- [ ] Swift Package Manager
-	- [ ] Manual
-- [ ] [I'm a supporter](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=92Z6U3LBHF9J4).
+- Platform (iOS/macOS/Linux/...): 
+- Installation method (CocoaPods/Carthage/SPM/...): 
+- Project name:
 
 # Description
 
+> To whom may be concerned: I offer professional support to all my open source projects.
 
 # Steps to reproduce
 
 
-Sample code:
+Sample code to reproduce the issue:
 
 ```swift
 import CryptoSwift
 
+// Code goes here
 
-```
+```

+ 1 - 1
.swift-version

@@ -1 +1 @@
-4.0.3
+4.1

+ 5 - 0
CHANGELOG

@@ -1,3 +1,8 @@
+0.8.4
+- Added CMAC message authenticator https://tools.ietf.org/html/rfc4493
+- Added AEADChaCha20Poly1305 (AEAD_CHACHA20_POLY1305) https://tools.ietf.org/html/rfc7539#section-2.8.1
+- Swift 4.1 Update
+
 0.8.3
 - Fix SHA3 padding.
 - Fix Carthage builds.

+ 42 - 8
CryptoSwift.xcodeproj/project.pbxproj

@@ -7,12 +7,18 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		0EE73E71204D598100110E11 /* CMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE73E70204D598100110E11 /* CMAC.swift */; };
+		0EE73E74204D59C200110E11 /* CMACTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE73E72204D599C00110E11 /* CMACTests.swift */; };
+		14156CE52011422400DDCFBC /* ChaCha20Poly1305Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14156CE42011422400DDCFBC /* ChaCha20Poly1305Tests.swift */; };
+		1467460F2017BB3600DF04ED /* AEAD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1467460E2017BB3600DF04ED /* AEAD.swift */; };
 		674A736F1BF5D85B00866C5B /* RabbitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 674A736E1BF5D85B00866C5B /* RabbitTests.swift */; };
 		750509991F6BEF2A00394A1B /* PKCS7.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750509981F6BEF2A00394A1B /* PKCS7.swift */; };
 		750CC3EB1DC0CACE0096BE6E /* BlowfishTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750CC3EA1DC0CACE0096BE6E /* BlowfishTests.swift */; };
 		75100F8F19B0BC890005C5F5 /* Poly1305Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75100F8E19B0BC890005C5F5 /* Poly1305Tests.swift */; };
 		751EE9781F93996100161FFC /* AES.Cryptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 751EE9771F93996100161FFC /* AES.Cryptors.swift */; };
+		7529366A20683DFC00195874 /* AEADChaCha20Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7529366920683DFC00195874 /* AEADChaCha20Poly1305.swift */; };
 		753B33011DAB84D600D06422 /* RandomBytesSequenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753B33001DAB84D600D06422 /* RandomBytesSequenceTests.swift */; };
+		754310442050111A003FB1DF /* CompactMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754310432050111A003FB1DF /* CompactMap.swift */; };
 		75482EA41CB310B7001F66A5 /* PBKDF.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75482EA31CB310B7001F66A5 /* PBKDF.swift */; };
 		754BE46819693E190098E6F3 /* DigestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754BE46719693E190098E6F3 /* DigestTests.swift */; };
 		755FB1DA199E347D00475437 /* ExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755FB1D9199E347D00475437 /* ExtensionsTest.swift */; };
@@ -46,7 +52,6 @@
 		75EC528F1EE8B81A0048EB3B /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC524C1EE8B6CA0048EB3B /* Cipher.swift */; };
 		75EC52901EE8B81A0048EB3B /* Collection+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC524D1EE8B6CA0048EB3B /* Collection+Extension.swift */; };
 		75EC52911EE8B81A0048EB3B /* Cryptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC524E1EE8B6CA0048EB3B /* Cryptors.swift */; };
-		75EC52921EE8B81A0048EB3B /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC524F1EE8B6CA0048EB3B /* Array+Extensions.swift */; };
 		75EC52931EE8B81A0048EB3B /* Digest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52501EE8B6CA0048EB3B /* Digest.swift */; };
 		75EC52941EE8B81A0048EB3B /* DigestType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52511EE8B6CA0048EB3B /* DigestType.swift */; };
 		75EC52951EE8B8200048EB3B /* AES+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52531EE8B6CA0048EB3B /* AES+Foundation.swift */; };
@@ -155,12 +160,18 @@
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
+		0EE73E70204D598100110E11 /* CMAC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CMAC.swift; sourceTree = "<group>"; };
+		0EE73E72204D599C00110E11 /* CMACTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CMACTests.swift; sourceTree = "<group>"; };
+		14156CE42011422400DDCFBC /* ChaCha20Poly1305Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChaCha20Poly1305Tests.swift; sourceTree = "<group>"; };
+		1467460E2017BB3600DF04ED /* AEAD.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AEAD.swift; sourceTree = "<group>"; };
 		674A736E1BF5D85B00866C5B /* RabbitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RabbitTests.swift; sourceTree = "<group>"; };
 		750509981F6BEF2A00394A1B /* PKCS7.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PKCS7.swift; sourceTree = "<group>"; };
 		750CC3EA1DC0CACE0096BE6E /* BlowfishTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlowfishTests.swift; sourceTree = "<group>"; };
 		75100F8E19B0BC890005C5F5 /* Poly1305Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Poly1305Tests.swift; sourceTree = "<group>"; };
 		751EE9771F93996100161FFC /* AES.Cryptors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AES.Cryptors.swift; sourceTree = "<group>"; };
+		7529366920683DFC00195874 /* AEADChaCha20Poly1305.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AEADChaCha20Poly1305.swift; sourceTree = "<group>"; };
 		753B33001DAB84D600D06422 /* RandomBytesSequenceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RandomBytesSequenceTests.swift; sourceTree = "<group>"; };
+		754310432050111A003FB1DF /* CompactMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompactMap.swift; sourceTree = "<group>"; };
 		75482EA31CB310B7001F66A5 /* PBKDF.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PBKDF.swift; sourceTree = "<group>"; };
 		754BE45519693E190098E6F3 /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		754BE46019693E190098E6F3 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -196,7 +207,6 @@
 		75EC524C1EE8B6CA0048EB3B /* Cipher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cipher.swift; sourceTree = "<group>"; };
 		75EC524D1EE8B6CA0048EB3B /* Collection+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+Extension.swift"; sourceTree = "<group>"; };
 		75EC524E1EE8B6CA0048EB3B /* Cryptors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cryptors.swift; sourceTree = "<group>"; };
-		75EC524F1EE8B6CA0048EB3B /* Array+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+Extensions.swift"; sourceTree = "<group>"; };
 		75EC52501EE8B6CA0048EB3B /* Digest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Digest.swift; sourceTree = "<group>"; };
 		75EC52511EE8B6CA0048EB3B /* DigestType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigestType.swift; sourceTree = "<group>"; };
 		75EC52531EE8B6CA0048EB3B /* AES+Foundation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AES+Foundation.swift"; sourceTree = "<group>"; };
@@ -268,6 +278,15 @@
 			name = Frameworks;
 			sourceTree = "<group>";
 		};
+		7529366820683DFC00195874 /* AEAD */ = {
+			isa = PBXGroup;
+			children = (
+				1467460E2017BB3600DF04ED /* AEAD.swift */,
+				7529366920683DFC00195874 /* AEADChaCha20Poly1305.swift */,
+			);
+			path = AEAD;
+			sourceTree = "<group>";
+		};
 		754BE44B19693E190098E6F3 = {
 			isa = PBXGroup;
 			children = (
@@ -291,10 +310,12 @@
 		754BE46419693E190098E6F3 /* Tests */ = {
 			isa = PBXGroup;
 			children = (
+				14156CE42011422400DDCFBC /* ChaCha20Poly1305Tests.swift */,
 				E3FD2D511D6B813C00A9F35F /* Error+Extension.swift */,
 				754BE46719693E190098E6F3 /* DigestTests.swift */,
 				75100F8E19B0BC890005C5F5 /* Poly1305Tests.swift */,
 				758A94271A65C59200E46135 /* HMACTests.swift */,
+				0EE73E72204D599C00110E11 /* CMACTests.swift */,
 				E6200E151FB9B67C00258382 /* HKDFTests.swift */,
 				757DA2541A4ED408002BA3EF /* AESTests.swift */,
 				750CC3EA1DC0CACE0096BE6E /* BlowfishTests.swift */,
@@ -333,6 +354,7 @@
 		75EC52371EE8B6CA0048EB3B /* CryptoSwift */ = {
 			isa = PBXGroup;
 			children = (
+				7529366820683DFC00195874 /* AEAD */,
 				75EC52381EE8B6CA0048EB3B /* AES.swift */,
 				751EE9771F93996100161FFC /* AES.Cryptors.swift */,
 				75EC52391EE8B6CA0048EB3B /* Array+Extension.swift */,
@@ -345,9 +367,9 @@
 				75EC524A1EE8B6CA0048EB3B /* ChaCha20.swift */,
 				75EC524B1EE8B6CA0048EB3B /* Checksum.swift */,
 				75EC524C1EE8B6CA0048EB3B /* Cipher.swift */,
+				0EE73E70204D598100110E11 /* CMAC.swift */,
 				75EC524D1EE8B6CA0048EB3B /* Collection+Extension.swift */,
 				75EC524E1EE8B6CA0048EB3B /* Cryptors.swift */,
-				75EC524F1EE8B6CA0048EB3B /* Array+Extensions.swift */,
 				75EC52501EE8B6CA0048EB3B /* Digest.swift */,
 				75EC52511EE8B6CA0048EB3B /* DigestType.swift */,
 				75EC52521EE8B6CA0048EB3B /* Foundation */,
@@ -376,6 +398,7 @@
 				75EC52771EE8B6CA0048EB3B /* Updatable.swift */,
 				75EC52781EE8B6CA0048EB3B /* Utils.swift */,
 				75EC52791EE8B6CA0048EB3B /* ZeroPadding.swift */,
+				754310432050111A003FB1DF /* CompactMap.swift */,
 			);
 			path = CryptoSwift;
 			sourceTree = "<group>";
@@ -489,7 +512,7 @@
 			isa = PBXProject;
 			attributes = {
 				LastSwiftUpdateCheck = 0700;
-				LastUpgradeCheck = 0900;
+				LastUpgradeCheck = 0930;
 				ORGANIZATIONNAME = "Marcin Krzyzanowski";
 				TargetAttributes = {
 					754BE45419693E190098E6F3 = {
@@ -546,9 +569,11 @@
 			files = (
 				75EC52861EE8B8170048EB3B /* CFB.swift in Sources */,
 				75EC52901EE8B81A0048EB3B /* Collection+Extension.swift in Sources */,
+				0EE73E71204D598100110E11 /* CMAC.swift in Sources */,
 				E6200E141FB9A7AE00258382 /* HKDF.swift in Sources */,
 				75EC529F1EE8B8230048EB3B /* HMAC.swift in Sources */,
 				75EC52B91EE8B83D0048EB3B /* ZeroPadding.swift in Sources */,
+				7529366A20683DFC00195874 /* AEADChaCha20Poly1305.swift in Sources */,
 				75EC529E1EE8B8230048EB3B /* Generics.swift in Sources */,
 				75EC52AA1EE8B83D0048EB3B /* Poly1305.swift in Sources */,
 				75EC52AC1EE8B83D0048EB3B /* RandomAccessCryptor.swift in Sources */,
@@ -560,6 +585,7 @@
 				75EC52B01EE8B83D0048EB3B /* SHA2.swift in Sources */,
 				75EC52B71EE8B83D0048EB3B /* Updatable.swift in Sources */,
 				75EC528E1EE8B81A0048EB3B /* Checksum.swift in Sources */,
+				754310442050111A003FB1DF /* CompactMap.swift in Sources */,
 				75EC52811EE8B8130048EB3B /* BlockCipher.swift in Sources */,
 				75EC52941EE8B81A0048EB3B /* DigestType.swift in Sources */,
 				75EC529B1EE8B8200048EB3B /* Rabbit+Foundation.swift in Sources */,
@@ -582,7 +608,6 @@
 				75EC52A91EE8B83D0048EB3B /* PKCS7Padding.swift in Sources */,
 				75EC52A51EE8B8290048EB3B /* Padding.swift in Sources */,
 				75EC527F1EE8B8130048EB3B /* BatchedCollection.swift in Sources */,
-				75EC52921EE8B81A0048EB3B /* Array+Extensions.swift in Sources */,
 				75EC52991EE8B8200048EB3B /* Data+Extension.swift in Sources */,
 				75EC52B61EE8B83D0048EB3B /* UInt8+Extension.swift in Sources */,
 				75EC52891EE8B8170048EB3B /* OFB.swift in Sources */,
@@ -593,6 +618,7 @@
 				75EC527D1EE8B8130048EB3B /* Array+Extension.swift in Sources */,
 				75EC52B31EE8B83D0048EB3B /* UInt16+Extension.swift in Sources */,
 				75EC52A81EE8B8390048EB3B /* PKCS5.swift in Sources */,
+				1467460F2017BB3600DF04ED /* AEAD.swift in Sources */,
 				75EC528A1EE8B8170048EB3B /* PCBC.swift in Sources */,
 				75EC528D1EE8B81A0048EB3B /* ChaCha20.swift in Sources */,
 				75EC52851EE8B8170048EB3B /* CBC.swift in Sources */,
@@ -626,8 +652,10 @@
 				757DA2591A4ED4D7002BA3EF /* ChaCha20Tests.swift in Sources */,
 				755FB1DA199E347D00475437 /* ExtensionsTest.swift in Sources */,
 				674A736F1BF5D85B00866C5B /* RabbitTests.swift in Sources */,
+				0EE73E74204D59C200110E11 /* CMACTests.swift in Sources */,
 				750CC3EB1DC0CACE0096BE6E /* BlowfishTests.swift in Sources */,
 				757DA2531A4ED0A4002BA3EF /* PaddingTests.swift in Sources */,
+				14156CE52011422400DDCFBC /* ChaCha20Poly1305Tests.swift in Sources */,
 				757DA2551A4ED408002BA3EF /* AESTests.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -685,12 +713,14 @@
 				CLANG_WARN_BOOL_CONVERSION = YES;
 				CLANG_WARN_COMMA = YES;
 				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_ENUM_CONVERSION = YES;
 				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -748,12 +778,14 @@
 				CLANG_WARN_BOOL_CONVERSION = YES;
 				CLANG_WARN_COMMA = YES;
 				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_ENUM_CONVERSION = YES;
 				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -797,6 +829,7 @@
 		754BE46C19693E190098E6F3 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				APPLICATION_EXTENSION_API_ONLY = YES;
 				CLANG_ENABLE_MODULES = YES;
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
@@ -810,7 +843,6 @@
 				PRODUCT_BUNDLE_IDENTIFIER = com.krzyzanowskim.CryptoSwift;
 				PRODUCT_NAME = CryptoSwift;
 				SKIP_INSTALL = YES;
-				SWIFT_COMPILATION_MODE = wholemodule;
 				SWIFT_ENFORCE_EXCLUSIVE_ACCESS = none;
 				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
 				SWIFT_VERSION = 4.0;
@@ -822,6 +854,7 @@
 		754BE46D19693E190098E6F3 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				APPLICATION_EXTENSION_API_ONLY = YES;
 				BITCODE_GENERATION_MODE = bitcode;
 				CLANG_ENABLE_MODULES = YES;
 				CLANG_USE_OPTIMIZATION_PROFILE = NO;
@@ -839,7 +872,6 @@
 				PRODUCT_BUNDLE_IDENTIFIER = com.krzyzanowskim.CryptoSwift;
 				PRODUCT_NAME = CryptoSwift;
 				SKIP_INSTALL = YES;
-				SWIFT_COMPILATION_MODE = wholemodule;
 				SWIFT_DISABLE_SAFETY_CHECKS = YES;
 				SWIFT_ENFORCE_EXCLUSIVE_ACCESS = "compile-time";
 				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
@@ -901,12 +933,14 @@
 				CLANG_WARN_BOOL_CONVERSION = YES;
 				CLANG_WARN_COMMA = YES;
 				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_ENUM_CONVERSION = YES;
 				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -953,6 +987,7 @@
 		756B66AB1F6AAFDB00DEC41C /* Test */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				APPLICATION_EXTENSION_API_ONLY = YES;
 				BITCODE_GENERATION_MODE = bitcode;
 				CLANG_ENABLE_MODULES = YES;
 				DYLIB_COMPATIBILITY_VERSION = 1;
@@ -969,7 +1004,6 @@
 				PRODUCT_BUNDLE_IDENTIFIER = com.krzyzanowskim.CryptoSwift;
 				PRODUCT_NAME = CryptoSwift;
 				SKIP_INSTALL = YES;
-				SWIFT_COMPILATION_MODE = wholemodule;
 				SWIFT_DISABLE_SAFETY_CHECKS = YES;
 				SWIFT_ENFORCE_EXCLUSIVE_ACCESS = "compile-time";
 				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";

+ 3 - 5
CryptoSwift.xcodeproj/xcshareddata/xcschemes/CryptoSwift.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "0900"
+   LastUpgradeVersion = "0930"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "NO"
@@ -41,10 +41,9 @@
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       disableMainThreadChecker = "YES"
-      language = ""
       systemAttachmentLifetime = "keepNever"
-      shouldUseLaunchSchemeArgsEnv = "YES"
-      codeCoverageEnabled = "YES">
+      codeCoverageEnabled = "YES"
+      shouldUseLaunchSchemeArgsEnv = "YES">
       <Testables>
          <TestableReference
             skipped = "NO">
@@ -73,7 +72,6 @@
       buildConfiguration = "Test"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
-      language = ""
       launchStyle = "0"
       useCustomWorkingDirectory = "NO"
       ignoresPersistentStateOnLaunch = "NO"

+ 8 - 0
CryptoSwift.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>

+ 1 - 1
Package.swift

@@ -2,7 +2,7 @@
 
 import PackageDescription
 
-_ = Package(name: "CryptoSwift", 
+_ = Package(name: "CryptoSwift",
             products: [.library(name: "CryptoSwift", targets: ["CryptoSwift"])],
             targets: [
                 .target(name: "CryptoSwift"),

+ 15 - 3
README.md

@@ -55,6 +55,7 @@ Good mood
 #### Message authenticators
 - [Poly1305](http://cr.yp.to/mac/poly1305-20050329.pdf)
 - [HMAC](https://www.ietf.org/rfc/rfc2104.txt) MD5, SHA1, SHA256
+- [CMAC](https://tools.ietf.org/html/rfc4493)
 
 #### Cipher block mode
 - Electronic codebook ([ECB](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_.28ECB.29))
@@ -75,6 +76,9 @@ Good mood
 - [Zero padding](https://en.wikipedia.org/wiki/Padding_(cryptography)#Zero_padding)
 - No padding
 
+#### Authenticated Encryption with Associated Data (AEAD)
+- [AEAD_CHACHA20_POLY1305](https://tools.ietf.org/html/rfc7539#section-2.8)
+
 ## Why
 [Why?](https://github.com/krzyzanowskim/CryptoSwift/issues/5) [Because I can](https://github.com/krzyzanowskim/CryptoSwift/issues/5#issuecomment-53379391).
 
@@ -173,7 +177,7 @@ See: [Package.swift - manual](http://blog.krzyzanowskim.com/2016/08/09/package-s
 
 * [Basics (data types, conversion, ...)](#basics)
 * [Digest (MD5, SHA...)](#calculate-digest)
-* [Message authenticators (HMAC...)](#message-authenticators-1)
+* [Message authenticators (HMAC, CMAC...)](#message-authenticators-1)
 * [Password-Based Key Derivation Function (PBKDF2, ...)](#password-based-key-derivation-functions)
 * [HMAC-based Key Derivation Function (HKDF)](#hmac-based-key-derivation-function)
 * [Data Padding](#data-padding)
@@ -181,7 +185,7 @@ See: [Package.swift - manual](http://blog.krzyzanowskim.com/2016/08/09/package-s
 * [Rabbit](#rabbit)
 * [Blowfish](#blowfish)
 * [Advanced Encryption Standard (AES)](#aes)
-
+* [Authenticated Encryption with Associated Data (AEAD)](#aead)
 
 also check [Playground](/CryptoSwift.playground/Contents.swift)
 
@@ -281,6 +285,7 @@ let key:Array<UInt8> = [1,2,3,4,5,6,7,8,9,10,...]
 
 try Poly1305(key: key).authenticate(bytes)
 try HMAC(key: key, variant: .sha256).authenticate(bytes)
+try CMAC(key: key).authenticate(bytes)
 ```
 
 ##### Password-Based Key Derivation Functions
@@ -344,7 +349,7 @@ AES-256 example
 ```swift
 try AES(key: [1,2,3,...,32], blockMode: .CBC(iv: [1,2,3,...,16]), padding: .pkcs7)
 ```
- 
+
 ###### All at once
 ```swift
 do {
@@ -407,6 +412,13 @@ let encrypted = try! plain.encrypt(ChaCha20(key: key, iv: iv))
 let decrypted = try! encrypted.decrypt(ChaCha20(key: key, iv: iv))
 ```
 
+##### AEAD
+
+```swift
+let encrypt = try AEADChaCha20Poly1305.encrypt(plaintext, key: key, iv: nonce, authenticationHeader: header)
+let decrypt = try AEADChaCha20Poly1305.decrypt(ciphertext, key: key, iv: nonce, authenticationHeader: header, authenticationTag: tagArr: tag)
+```
+
 ## Author
 
 CryptoSwift is owned and maintained by [Marcin Krzyżanowski](http://www.krzyzanowskim.com)

+ 40 - 0
Sources/CryptoSwift/AEAD/AEAD.swift

@@ -0,0 +1,40 @@
+//
+//  AEAD.swift
+//  CryptoSwift
+//
+//  Copyright (C) 2014-2017 Marcin Krzyżanowski <marcin@krzyzanowskim.com>
+//  This software is provided 'as-is', without any express or implied warranty.
+//
+//  In no event will the authors be held liable for any damages arising from the use of this software.
+//
+//  Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
+//
+//  - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required.
+//  - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+//  - This notice may not be removed or altered from any source or binary distribution.
+//
+//
+
+// https://www.iana.org/assignments/aead-parameters/aead-parameters.xhtml
+
+/// Authenticated Encryption with Associated Data (AEAD)
+public protocol AEAD {
+    static var kLen: Int { get } // key length
+    static var ivRange: Range<Int> { get } // nonce length
+}
+
+extension AEAD {
+    static func calculateAuthenticationTag(authenticator: Authenticator, cipherText: Array<UInt8>, authenticationHeader: Array<UInt8>) throws -> Array<UInt8> {
+        let headerPadding = ((16 - (authenticationHeader.count & 0xf)) & 0xf)
+        let cipherPadding = ((16 - (cipherText.count & 0xf)) & 0xf)
+
+        var mac = authenticationHeader
+        mac += Array<UInt8>(repeating: 0, count: headerPadding)
+        mac += cipherText
+        mac += Array<UInt8>(repeating: 0, count: cipherPadding)
+        mac += UInt64(bigEndian: UInt64(authenticationHeader.count)).bytes()
+        mac += UInt64(bigEndian: UInt64(cipherText.count)).bytes()
+
+        return try authenticator.authenticate(mac)
+    }
+}

+ 59 - 0
Sources/CryptoSwift/AEAD/AEADChaCha20Poly1305.swift

@@ -0,0 +1,59 @@
+//
+//  ChaCha20Poly1305.swift
+//  CryptoSwift
+//
+//  Copyright (C) 2014-2017 Marcin Krzyżanowski <marcin@krzyzanowskim.com>
+//  This software is provided 'as-is', without any express or implied warranty.
+//
+//  In no event will the authors be held liable for any damages arising from the use of this software.
+//
+//  Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
+//
+//  - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required.
+//  - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+//  - This notice may not be removed or altered from any source or binary distribution.
+//
+//
+//  https://tools.ietf.org/html/rfc7539#section-2.8.1
+
+/// AEAD_CHACHA20_POLY1305
+public final class AEADChaCha20Poly1305: AEAD {
+    public static let kLen = 32 // key length
+    public static var ivRange = Range<Int>(12...12)
+
+    /// Authenticated encryption
+    public static func encrypt(_ plainText: Array<UInt8>, key: Array<UInt8>, iv: Array<UInt8>, authenticationHeader: Array<UInt8>) throws -> (cipherText: Array<UInt8>, authenticationTag: Array<UInt8>) {
+        let cipher = try ChaCha20(key: key, iv: iv)
+
+        var polykey = Array<UInt8>(repeating: 0, count: kLen)
+        var toEncrypt = polykey
+        polykey = try cipher.encrypt(polykey)
+        toEncrypt += polykey
+        toEncrypt += plainText
+
+        let fullCipherText = try cipher.encrypt(toEncrypt)
+        let cipherText = Array(fullCipherText.dropFirst(64))
+
+        let tag = try calculateAuthenticationTag(authenticator: Poly1305(key: polykey), cipherText: cipherText, authenticationHeader: authenticationHeader)
+        return (cipherText, tag)
+    }
+
+    /// Authenticated decryption
+    public static func decrypt(_ cipherText: Array<UInt8>, key: Array<UInt8>, iv: Array<UInt8>, authenticationHeader: Array<UInt8>, authenticationTag: Array<UInt8>) throws -> (plainText: Array<UInt8>, success: Bool) {
+        let chacha = try ChaCha20(key: key, iv: iv)
+
+        let polykey = try chacha.encrypt(Array<UInt8>(repeating: 0, count: kLen))
+        let mac = try calculateAuthenticationTag(authenticator: Poly1305(key: polykey), cipherText: cipherText, authenticationHeader: authenticationHeader)
+        guard mac == authenticationTag else {
+            return (cipherText, false)
+        }
+
+        var toDecrypt = Array<UInt8>(reserveCapacity: cipherText.count + 64)
+        toDecrypt += polykey
+        toDecrypt += polykey
+        toDecrypt += cipherText
+        let fullPlainText = try chacha.decrypt(toDecrypt)
+        let plainText = Array(fullPlainText.dropFirst(64))
+        return (plainText, true)
+    }
+}

+ 3 - 1
Sources/CryptoSwift/AES.Cryptors.swift

@@ -14,6 +14,7 @@
 //
 
 // MARK: Cryptors
+
 extension AES: Cryptors {
     public func makeEncryptor() throws -> AES.Encryptor {
         return try AES.Encryptor(aes: self)
@@ -25,6 +26,7 @@ extension AES: Cryptors {
 }
 
 // MARK: Encryptor
+
 extension AES {
     public struct Encryptor: Updatable {
         private var worker: BlockModeWorker
@@ -62,8 +64,8 @@ extension AES {
 }
 
 // MARK: Decryptor
-extension AES {
 
+extension AES {
     public struct Decryptor: RandomAccessCryptor {
         private var worker: BlockModeWorker
         private let padding: Padding

+ 14 - 14
Sources/CryptoSwift/AES.swift

@@ -18,7 +18,6 @@
 
 /// The Advanced Encryption Standard (AES)
 public final class AES: BlockCipher {
-
     public enum Error: Swift.Error {
         /// Data padding is required
         case dataPaddingRequired
@@ -47,9 +46,10 @@ public final class AES: BlockCipher {
     private lazy var variantNk: Int = self.variant.Nk
 
     public static let blockSize: Int = 16 // 128 /8
+    public let keySize: Int
 
     public var variant: Variant {
-        switch key.count * 8 {
+        switch keySize * 8 {
         case 128:
             return .aes128
         case 192:
@@ -124,6 +124,7 @@ public final class AES: BlockCipher {
         self.key = Key(bytes: key)
         self.blockMode = blockMode
         self.padding = padding
+        keySize = self.key.count
     }
 
     internal func encrypt(block: ArraySlice<UInt8>) -> Array<UInt8>? {
@@ -160,10 +161,10 @@ public final class AES: BlockCipher {
 
         let tLength = 4
         let t = UnsafeMutablePointer<UInt32>.allocate(capacity: tLength)
-        t.initialize(to: 0, count: tLength)
+        t.initialize(repeating: 0, count: tLength)
         defer {
             t.deinitialize(count: tLength)
-            t.deallocate(capacity: tLength)
+            t.deallocate()
         }
 
         for r in 0..<rounds - 1 {
@@ -255,10 +256,10 @@ public final class AES: BlockCipher {
 
         let tLength = 4
         let t = UnsafeMutablePointer<UInt32>.allocate(capacity: tLength)
-        t.initialize(to: 0, count: tLength)
+        t.initialize(repeating: 0, count: tLength)
         defer {
             t.deinitialize(count: tLength)
-            t.deallocate(capacity: tLength)
+            t.deallocate()
         }
 
         for r in (2...rounds).reversed() {
@@ -354,7 +355,6 @@ private extension AES {
     }
 
     private func expandKey(_ key: Key, variant _: Variant) -> Array<Array<UInt32>> {
-
         func convertExpandedKey(_ expanded: Array<UInt8>) -> Array<Array<UInt32>> {
             return expanded.batched(by: 4).map({ UInt32(bytes: $0.reversed()) }).batched(by: 4).map({ Array($0) })
         }
@@ -385,10 +385,10 @@ private extension AES {
 
         let wLength = variantNb * (variantNr + 1) * 4
         let w = UnsafeMutablePointer<UInt8>.allocate(capacity: wLength)
-        w.initialize(to: 0, count: wLength)
+        w.initialize(repeating: 0, count: wLength)
         defer {
             w.deinitialize(count: wLength)
-            w.deallocate(capacity: wLength)
+            w.deallocate()
         }
 
         for i in 0..<variantNk {
@@ -454,13 +454,13 @@ private extension AES {
         let sboxLength = 256
         let sbox = UnsafeMutablePointer<UInt32>.allocate(capacity: sboxLength)
         let invsbox = UnsafeMutablePointer<UInt32>.allocate(capacity: sboxLength)
-        sbox.initialize(to: 0, count: sboxLength)
-        invsbox.initialize(to: 0, count: sboxLength)
+        sbox.initialize(repeating: 0, count: sboxLength)
+        invsbox.initialize(repeating: 0, count: sboxLength)
         defer {
             sbox.deinitialize(count: sboxLength)
-            sbox.deallocate(capacity: sboxLength)
+            sbox.deallocate()
             invsbox.deinitialize(count: sboxLength)
-            invsbox.deallocate(capacity: sboxLength)
+            invsbox.deallocate()
         }
 
         sbox[0] = 0x63
@@ -485,8 +485,8 @@ private extension AES {
 }
 
 // MARK: Cipher
-extension AES: Cipher {
 
+extension AES: Cipher {
     public func encrypt(_ bytes: ArraySlice<UInt8>) throws -> Array<UInt8> {
         let chunks = bytes.batched(by: AES.blockSize)
 

+ 80 - 20
Sources/CryptoSwift/Array+Extension.swift

@@ -14,7 +14,7 @@
 //
 
 extension Array {
-    init(reserveCapacity: Int) {
+    public init(reserveCapacity: Int) {
         self = Array<Element>()
         self.reserveCapacity(reserveCapacity)
     }
@@ -24,26 +24,7 @@ extension Array {
     }
 }
 
-extension Array {
-
-    /// split in chunks with given chunk size
-    @available(*, deprecated: 0.8.0, message: "")
-    public func chunks(size chunksize: Int) -> Array<Array<Element>> {
-        var words = Array<Array<Element>>()
-        words.reserveCapacity(count / chunksize)
-        for idx in stride(from: chunksize, through: count, by: chunksize) {
-            words.append(Array(self[idx - chunksize..<idx])) // slow for large table
-        }
-        let remainder = suffix(count % chunksize)
-        if !remainder.isEmpty {
-            words.append(Array(remainder))
-        }
-        return words
-    }
-}
-
 extension Array where Element == UInt8 {
-
     public init(hex: String) {
         self.init(reserveCapacity: hex.unicodeScalars.lazy.underestimatedCount)
         var buffer: UInt8?
@@ -81,4 +62,83 @@ extension Array where Element == UInt8 {
             append(b)
         }
     }
+
+    public func toHexString() -> String {
+        return `lazy`.reduce("") {
+            var s = String($1, radix: 16)
+            if s.count == 1 {
+                s = "0" + s
+            }
+            return $0 + s
+        }
+    }
+}
+
+extension Array where Element == UInt8 {
+    /// split in chunks with given chunk size
+    @available(*, deprecated: 0.8.0, message: "")
+    public func chunks(size chunksize: Int) -> Array<Array<Element>> {
+        var words = Array<Array<Element>>()
+        words.reserveCapacity(count / chunksize)
+        for idx in stride(from: chunksize, through: count, by: chunksize) {
+            words.append(Array(self[idx - chunksize..<idx])) // slow for large table
+        }
+        let remainder = suffix(count % chunksize)
+        if !remainder.isEmpty {
+            words.append(Array(remainder))
+        }
+        return words
+    }
+
+    public func md5() -> [Element] {
+        return Digest.md5(self)
+    }
+
+    public func sha1() -> [Element] {
+        return Digest.sha1(self)
+    }
+
+    public func sha224() -> [Element] {
+        return Digest.sha224(self)
+    }
+
+    public func sha256() -> [Element] {
+        return Digest.sha256(self)
+    }
+
+    public func sha384() -> [Element] {
+        return Digest.sha384(self)
+    }
+
+    public func sha512() -> [Element] {
+        return Digest.sha512(self)
+    }
+
+    public func sha2(_ variant: SHA2.Variant) -> [Element] {
+        return Digest.sha2(self, variant: variant)
+    }
+
+    public func sha3(_ variant: SHA3.Variant) -> [Element] {
+        return Digest.sha3(self, variant: variant)
+    }
+
+    public func crc32(seed: UInt32? = nil, reflect: Bool = true) -> UInt32 {
+        return Checksum.crc32(self, seed: seed, reflect: reflect)
+    }
+
+    public func crc16(seed: UInt16? = nil) -> UInt16 {
+        return Checksum.crc16(self, seed: seed)
+    }
+
+    public func encrypt(cipher: Cipher) throws -> [Element] {
+        return try cipher.encrypt(slice)
+    }
+
+    public func decrypt(cipher: Cipher) throws -> [Element] {
+        return try cipher.decrypt(slice)
+    }
+
+    public func authenticate<A: Authenticator>(with authenticator: A) throws -> [Element] {
+        return try authenticator.authenticate(self)
+    }
 }

+ 0 - 82
Sources/CryptoSwift/Array+Extensions.swift

@@ -1,82 +0,0 @@
-//
-//  CryptoSwift
-//
-//  Copyright (C) 2014-2017 Marcin Krzyżanowski <marcin@krzyzanowskim.com>
-//  This software is provided 'as-is', without any express or implied warranty.
-//
-//  In no event will the authors be held liable for any damages arising from the use of this software.
-//
-//  Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
-//
-//  - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required.
-//  - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
-//  - This notice may not be removed or altered from any source or binary distribution.
-//
-
-public extension Array where Element == UInt8 {
-
-    public func toHexString() -> String {
-        return `lazy`.reduce("") {
-            var s = String($1, radix: 16)
-            if s.count == 1 {
-                s = "0" + s
-            }
-            return $0 + s
-        }
-    }
-}
-
-public extension Array where Element == UInt8 {
-
-    public func md5() -> [Element] {
-        return Digest.md5(self)
-    }
-
-    public func sha1() -> [Element] {
-        return Digest.sha1(self)
-    }
-
-    public func sha224() -> [Element] {
-        return Digest.sha224(self)
-    }
-
-    public func sha256() -> [Element] {
-        return Digest.sha256(self)
-    }
-
-    public func sha384() -> [Element] {
-        return Digest.sha384(self)
-    }
-
-    public func sha512() -> [Element] {
-        return Digest.sha512(self)
-    }
-
-    public func sha2(_ variant: SHA2.Variant) -> [Element] {
-        return Digest.sha2(self, variant: variant)
-    }
-
-    public func sha3(_ variant: SHA3.Variant) -> [Element] {
-        return Digest.sha3(self, variant: variant)
-    }
-
-    public func crc32(seed: UInt32? = nil, reflect: Bool = true) -> UInt32 {
-        return Checksum.crc32(self, seed: seed, reflect: reflect)
-    }
-
-    public func crc16(seed: UInt16? = nil) -> UInt16 {
-        return Checksum.crc16(self, seed: seed)
-    }
-
-    public func encrypt(cipher: Cipher) throws -> [Element] {
-        return try cipher.encrypt(slice)
-    }
-
-    public func decrypt(cipher: Cipher) throws -> [Element] {
-        return try cipher.decrypt(slice)
-    }
-
-    public func authenticate<A: Authenticator>(with authenticator: A) throws -> [Element] {
-        return try authenticator.authenticate(self)
-    }
-}

+ 3 - 3
Sources/CryptoSwift/BatchedCollection.swift

@@ -18,7 +18,7 @@ struct BatchedCollectionIndex<Base: Collection> {
 }
 
 extension BatchedCollectionIndex: Comparable {
-    static func ==<Base>(lhs: BatchedCollectionIndex<Base>, rhs: BatchedCollectionIndex<Base>) -> Bool {
+    static func == <Base>(lhs: BatchedCollectionIndex<Base>, rhs: BatchedCollectionIndex<Base>) -> Bool {
         return lhs.range.lowerBound == rhs.range.lowerBound
     }
 
@@ -33,7 +33,7 @@ protocol BatchedCollectionType: Collection {
 
 struct BatchedCollection<Base: Collection>: Collection {
     let base: Base
-    let size: Base.IndexDistance
+    let size: Int
     typealias Index = BatchedCollectionIndex<Base>
     private func nextBreak(after idx: Base.Index) -> Base.Index {
         return base.index(idx, offsetBy: size, limitedBy: base.endIndex)
@@ -58,7 +58,7 @@ struct BatchedCollection<Base: Collection>: Collection {
 }
 
 extension Collection {
-    func batched(by size: IndexDistance) -> BatchedCollection<Self> {
+    func batched(by size: Int) -> BatchedCollection<Self> {
         return BatchedCollection(base: self, size: size)
     }
 }

+ 0 - 1
Sources/CryptoSwift/Bit.swift

@@ -19,7 +19,6 @@ public enum Bit: Int {
 }
 
 extension Bit {
-
     func inverted() -> Bit {
         return self == .zero ? .one : .zero
     }

+ 7 - 8
Sources/CryptoSwift/Blowfish.swift

@@ -18,7 +18,6 @@
 //
 
 public final class Blowfish {
-
     public enum Error: Swift.Error {
         /// Data padding is required
         case dataPaddingRequired
@@ -29,8 +28,10 @@ public final class Blowfish {
     }
 
     public static let blockSize: Int = 8 // 64 bit
-    fileprivate let blockMode: BlockMode
-    fileprivate let padding: Padding
+    public let keySize: Int
+
+    private let blockMode: BlockMode
+    private let padding: Padding
     private var decryptWorker: BlockModeWorker!
     private var encryptWorker: BlockModeWorker!
 
@@ -316,6 +317,7 @@ public final class Blowfish {
 
         self.blockMode = blockMode
         self.padding = padding
+        keySize = key.count
 
         S = origS
         P = origP
@@ -490,13 +492,11 @@ public final class Blowfish {
 }
 
 extension Blowfish: Cipher {
-
     /// Encrypt the 8-byte padded buffer, block by block. Note that for amounts of data larger than a block, it is not safe to just call encrypt() on successive blocks.
     ///
     /// - Parameter bytes: Plaintext data
     /// - Returns: Encrypted data
-    public func encrypt<C: Collection>(_ bytes: C) throws -> Array<UInt8> where C.Element == UInt8, C.IndexDistance == Int, C.Index == Int {
-
+    public func encrypt<C: Collection>(_ bytes: C) throws -> Array<UInt8> where C.Element == UInt8, C.Index == Int {
         let bytes = padding.add(to: Array(bytes), blockSize: Blowfish.blockSize) // FIXME: Array(bytes) copies
 
         var out = Array<UInt8>()
@@ -517,8 +517,7 @@ extension Blowfish: Cipher {
     ///
     /// - Parameter bytes: Ciphertext data
     /// - Returns: Plaintext data
-    public func decrypt<C: Collection>(_ bytes: C) throws -> Array<UInt8> where C.Element == UInt8, C.IndexDistance == Int, C.Index == Int {
-
+    public func decrypt<C: Collection>(_ bytes: C) throws -> Array<UInt8> where C.Element == UInt8, C.Index == Int {
         if blockMode.options.contains(.paddingRequired) && (bytes.count % Blowfish.blockSize != 0) {
             throw Error.dataPaddingRequired
         }

+ 99 - 0
Sources/CryptoSwift/CMAC.swift

@@ -0,0 +1,99 @@
+//
+//  CryptoSwift
+//
+//  Copyright (C) 2014-2017 Marcin Krzyżanowski <marcin@krzyzanowskim.com>
+//  This software is provided 'as-is', without any express or implied warranty.
+//
+//  In no event will the authors be held liable for any damages arising from the use of this software.
+//
+//  Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
+//
+//  - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required.
+//  - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+//  - This notice may not be removed or altered from any source or binary distribution.
+//
+
+public final class CMAC: Authenticator {
+    public enum Error: Swift.Error {
+        case wrongKeyLength
+    }
+
+    private let key: SecureBytes
+
+    private static let BlockSize: Int = 16
+    private static let Zero: Array<UInt8> = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
+    private static let Rb: Array<UInt8> = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87]
+
+    public init(key: Array<UInt8>) throws {
+        if key.count != 16 {
+            throw Error.wrongKeyLength
+        }
+        self.key = SecureBytes(bytes: key)
+    }
+
+    // MARK: Authenticator
+
+    public func authenticate(_ bytes: Array<UInt8>) throws -> Array<UInt8> {
+        let aes = try AES(key: Array(key), blockMode: .CBC(iv: CMAC.Zero), padding: .noPadding)
+
+        let l = try aes.encrypt(CMAC.Zero)
+        var subKey1 = leftShiftOneBit(l)
+        if (l[0] & 0x80) != 0 {
+            subKey1 = xor(CMAC.Rb, subKey1)
+        }
+        var subKey2 = leftShiftOneBit(subKey1)
+        if (subKey1[0] & 0x80) != 0 {
+            subKey2 = xor(CMAC.Rb, subKey2)
+        }
+
+        let lastBlockComplete: Bool
+        let blockCount = (bytes.count + CMAC.BlockSize - 1) / CMAC.BlockSize
+        if blockCount == 0 {
+            lastBlockComplete = false
+        } else {
+            lastBlockComplete = bytes.count % CMAC.BlockSize == 0
+        }
+        var paddedBytes = bytes
+        if !lastBlockComplete {
+            bitPadding(to: &paddedBytes, blockSize: CMAC.BlockSize)
+        }
+
+        var blocks = Array(paddedBytes.batched(by: CMAC.BlockSize))
+        var lastBlock = blocks.popLast()!
+        if lastBlockComplete {
+            lastBlock = xor(lastBlock, subKey1)
+        } else {
+            lastBlock = xor(lastBlock, subKey2)
+        }
+
+        var x = Array<UInt8>(repeating: 0x00, count: CMAC.BlockSize)
+        var y = Array<UInt8>(repeating: 0x00, count: CMAC.BlockSize)
+        for block in blocks {
+            y = xor(block, x)
+            x = try aes.encrypt(y)
+        }
+        y = xor(lastBlock, x)
+        return try aes.encrypt(y)
+    }
+
+    // MARK: Helper methods
+
+    /**
+     Performs left shift by one bit to the bit string aquired after concatenating al bytes in the byte array
+     - parameters:
+     - bytes: byte array
+     - returns: bit shifted bit string split again in array of bytes
+     */
+    private func leftShiftOneBit(_ bytes: Array<UInt8>) -> Array<UInt8> {
+        var shifted = Array<UInt8>(repeating: 0x00, count: bytes.count)
+        let last = bytes.count - 1
+        for index in 0..<last {
+            shifted[index] = bytes[index] << 1
+            if (bytes[index + 1] & 0x80) != 0 {
+                shifted[index] += 0x01
+            }
+        }
+        shifted[last] = bytes[last] << 1
+        return shifted
+    }
+}

+ 7 - 6
Sources/CryptoSwift/ChaCha20.swift

@@ -17,12 +17,12 @@
 //
 
 public final class ChaCha20: BlockCipher {
-
     public enum Error: Swift.Error {
         case invalidKeyOrInitializationVector
     }
 
     public static let blockSize = 64 // 512 / 8
+    public let keySize: Int
 
     fileprivate let key: Key
     fileprivate var counter: Array<UInt8>
@@ -35,6 +35,7 @@ public final class ChaCha20: BlockCipher {
         }
 
         self.key = Key(bytes: key)
+        keySize = self.key.count
 
         if nonce.count == 8 {
             counter = [0, 0, 0, 0, 0, 0, 0, 0] + nonce
@@ -222,7 +223,7 @@ public final class ChaCha20: BlockCipher {
             var u: UInt32 = 1
             for i in 0..<4 {
                 u += UInt32(counter[i])
-                counter[i] = UInt8(u & 0xFF)
+                counter[i] = UInt8(u & 0xff)
                 u >>= 8
             }
             bytesSlice = bytesSlice[bytesSlice.startIndex + ChaCha20.blockSize..<bytesSlice.endIndex]
@@ -239,8 +240,8 @@ public final class ChaCha20: BlockCipher {
 }
 
 // MARK: Cipher
-extension ChaCha20: Cipher {
 
+extension ChaCha20: Cipher {
     public func encrypt(_ bytes: ArraySlice<UInt8>) throws -> Array<UInt8> {
         return process(bytes: bytes, counter: &counter, key: Array(key))
     }
@@ -251,8 +252,8 @@ extension ChaCha20: Cipher {
 }
 
 // MARK: Encryptor
-extension ChaCha20 {
 
+extension ChaCha20 {
     public struct Encryptor: Updatable {
         private var accumulated = Array<UInt8>()
         private let chacha: ChaCha20
@@ -278,8 +279,8 @@ extension ChaCha20 {
 }
 
 // MARK: Decryptor
-extension ChaCha20 {
 
+extension ChaCha20 {
     public struct Decryptor: Updatable {
         private var accumulated = Array<UInt8>()
 
@@ -323,8 +324,8 @@ extension ChaCha20 {
 }
 
 // MARK: Cryptors
-extension ChaCha20: Cryptors {
 
+extension ChaCha20: Cryptors {
     public func makeEncryptor() -> ChaCha20.Encryptor {
         return Encryptor(chacha: self)
     }

+ 1 - 1
Sources/CryptoSwift/Checksum.swift

@@ -108,8 +108,8 @@ public final class Checksum {
 }
 
 // MARK: Public interface
-public extension Checksum {
 
+public extension Checksum {
     /// Calculate CRC32
     ///
     /// - parameter message: Message

+ 2 - 0
Sources/CryptoSwift/Cipher.swift

@@ -19,6 +19,8 @@ public enum CipherError: Error {
 }
 
 public protocol Cipher: class {
+    var keySize: Int { get }
+
     /// Encrypt given bytes at once
     ///
     /// - parameter bytes: Plaintext data

+ 0 - 1
Sources/CryptoSwift/Collection+Extension.swift

@@ -13,7 +13,6 @@
 //  - This notice may not be removed or altered from any source or binary distribution.
 //
 extension Collection where Self.Element == UInt8, Self.Index == Int {
-
     // Big endian order
     func toUInt32Array() -> Array<UInt32> {
         if isEmpty {

+ 23 - 0
Sources/CryptoSwift/CompactMap.swift

@@ -0,0 +1,23 @@
+////  CryptoSwift
+//
+//  Copyright (C) 2014-__YEAR__ Marcin Krzyżanowski <marcin@krzyzanowskim.com>
+//  This software is provided 'as-is', without any express or implied warranty.
+//
+//  In no event will the authors be held liable for any damages arising from the use of this software.
+//
+//  Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
+//
+//  - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required.
+//  - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+//  - This notice may not be removed or altered from any source or binary distribution.
+//
+
+#if swift(>=4.1)
+    // TODO: remove this file when Xcode 9.2 is no longer used
+#else
+    extension Sequence {
+        public func compactMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] {
+            return try flatMap(transform)
+        }
+    }
+#endif

+ 0 - 1
Sources/CryptoSwift/Cryptors.swift

@@ -35,7 +35,6 @@ public protocol Cryptors: class {
 }
 
 extension Cryptors {
-
     public static func randomIV(_ blockSize: Int) -> Array<UInt8> {
         var randomIV: Array<UInt8> = Array<UInt8>()
         randomIV.reserveCapacity(blockSize)

+ 0 - 1
Sources/CryptoSwift/Digest.swift

@@ -18,7 +18,6 @@ public typealias Hash = Digest
 
 /// Hash functions to calculate Digest.
 public struct Digest {
-
     /// Calculate MD5 Digest
     /// - parameter bytes: input message
     /// - returns: Digest bytes

+ 0 - 1
Sources/CryptoSwift/Foundation/AES+Foundation.swift

@@ -16,7 +16,6 @@
 import Foundation
 
 extension AES {
-
     /// Initialize with CBC block mode.
     public convenience init(key: String, iv: String, padding: Padding = .pkcs7) throws {
         try self.init(key: key.bytes, blockMode: .CBC(iv: iv.bytes), padding: padding)

+ 0 - 1
Sources/CryptoSwift/Foundation/Array+Foundation.swift

@@ -16,7 +16,6 @@
 import Foundation
 
 public extension Array where Element == UInt8 {
-
     public func toBase64() -> String? {
         return Data(bytes: self).base64EncodedString()
     }

+ 0 - 1
Sources/CryptoSwift/Foundation/Blowfish+Foundation.swift

@@ -16,7 +16,6 @@
 import Foundation
 
 extension Blowfish {
-
     /// Initialize with CBC block mode.
     public convenience init(key: String, iv: String, padding: Padding = .pkcs7) throws {
         try self.init(key: key.bytes, blockMode: .CBC(iv: iv.bytes), padding: padding)

+ 0 - 1
Sources/CryptoSwift/Foundation/ChaCha20+Foundation.swift

@@ -16,7 +16,6 @@
 import Foundation
 
 extension ChaCha20 {
-
     public convenience init(key: String, iv: String) throws {
         try self.init(key: key.bytes, iv: iv.bytes)
     }

+ 0 - 2
Sources/CryptoSwift/Foundation/Data+Extension.swift

@@ -16,7 +16,6 @@
 import Foundation
 
 extension Data {
-
     /// Two octet checksum as defined in RFC-4880. Sum of all octets, mod 65536
     public func checksum() -> UInt16 {
         var s: UInt32 = 0
@@ -78,7 +77,6 @@ extension Data {
 }
 
 extension Data {
-
     public init(hex: String) {
         self.init(bytes: Array<UInt8>(hex: hex))
     }

+ 0 - 1
Sources/CryptoSwift/Foundation/HMAC+Foundation.swift

@@ -16,7 +16,6 @@
 import Foundation
 
 extension HMAC {
-
     public convenience init(key: String, variant: HMAC.Variant = .md5) throws {
         self.init(key: key.bytes, variant: variant)
     }

+ 0 - 1
Sources/CryptoSwift/Foundation/Rabbit+Foundation.swift

@@ -16,7 +16,6 @@
 import Foundation
 
 extension Rabbit {
-
     public convenience init(key: String) throws {
         try self.init(key: key.bytes)
     }

+ 0 - 1
Sources/CryptoSwift/Foundation/String+FoundationExtension.swift

@@ -16,7 +16,6 @@
 import Foundation
 
 extension String {
-
     /// Return Base64 back to String
     public func decryptBase64ToString(cipher: Cipher) throws -> String {
         guard let decodedData = Data(base64Encoded: self, options: []) else {

+ 2 - 2
Sources/CryptoSwift/Generics.swift

@@ -48,8 +48,8 @@ func arrayOfBytes<T: FixedWidthInteger>(value: T, length totalBytes: Int = Memor
         bytes[totalBytes - 1 - j] = (bytesPointer + j).pointee
     }
 
-    valuePointer.deinitialize()
-    valuePointer.deallocate(capacity: 1)
+    valuePointer.deinitialize(count: 1)
+    valuePointer.deallocate()
 
     return bytes
 }

+ 13 - 15
Sources/CryptoSwift/HKDF.swift

@@ -21,23 +21,22 @@
 #else
     import Darwin
 #endif
-    
+
 /// A key derivation function.
 ///
 /// HKDF   - HMAC-based Extract-and-Expand Key Derivation Function.
 public struct HKDF {
-    
     public enum Error: Swift.Error {
         case invalidInput
         case derivedKeyTooLong
     }
-    
+
     private let numBlocks: Int // l
     private let dkLen: Int
     private let info: Array<UInt8>
     fileprivate let prk: Array<UInt8>
     fileprivate let variant: HMAC.Variant
-    
+
     /// - parameters:
     ///   - variant: hash variant
     ///   - salt: optional salt (if not provided, it is set to a sequence of variant.digestLength zeros)
@@ -47,7 +46,7 @@ public struct HKDF {
         guard !password.isEmpty else {
             throw Error.invalidInput
         }
-        
+
         let dkLen = keyLength ?? variant.digestLength
         let keyLengthFinal = Double(dkLen)
         let hLen = Double(variant.digestLength)
@@ -55,32 +54,31 @@ public struct HKDF {
         guard numBlocks <= 255 else {
             throw Error.derivedKeyTooLong
         }
-        
+
         /// HKDF-Extract(salt, password) -> PRK
         ///  - PRK - a pseudo-random key; it is used by calculate()
-        self.prk = try HMAC(key: salt ?? [], variant: variant).authenticate(password)
+        prk = try HMAC(key: salt ?? [], variant: variant).authenticate(password)
         self.info = info ?? []
         self.variant = variant
         self.dkLen = dkLen
         self.numBlocks = numBlocks
     }
-    
+
     public func calculate() throws -> Array<UInt8> {
-        let hmac = HMAC(key: self.prk, variant: self.variant)
+        let hmac = HMAC(key: prk, variant: variant)
         var ret = Array<UInt8>()
-        ret.reserveCapacity(self.numBlocks * self.variant.digestLength)
+        ret.reserveCapacity(numBlocks * variant.digestLength)
         var value = Array<UInt8>()
-        for i in 1...self.numBlocks {
-            value.append(contentsOf: self.info)
+        for i in 1...numBlocks {
+            value.append(contentsOf: info)
             value.append(UInt8(i))
-            
+
             let bytes = try hmac.authenticate(value)
             ret.append(contentsOf: bytes)
-            
+
             /// update value to use it as input for next iteration
             value = bytes
         }
         return Array(ret.prefix(dkLen))
     }
 }
-

+ 0 - 1
Sources/CryptoSwift/HMAC.swift

@@ -14,7 +14,6 @@
 //
 
 public final class HMAC: Authenticator {
-
     public enum Error: Swift.Error {
         case authenticateError
         case invalidInput

+ 0 - 1
Sources/CryptoSwift/MD5.swift

@@ -122,7 +122,6 @@ public final class MD5: DigestType {
 }
 
 extension MD5: Updatable {
-
     public func update(withBytes bytes: ArraySlice<UInt8>, isLast: Bool = false) throws -> Array<UInt8> {
         accumulated += bytes
 

+ 0 - 1
Sources/CryptoSwift/NoPadding.swift

@@ -14,7 +14,6 @@
 //
 
 struct NoPadding: PaddingProtocol {
-
     init() {
     }
 

+ 0 - 2
Sources/CryptoSwift/PKCS/PBKDF1.swift

@@ -14,14 +14,12 @@
 //
 
 public extension PKCS5 {
-
     /// A key derivation function.
     ///
     /// PBKDF1 is recommended only for compatibility with existing
     /// applications since the keys it produces may not be large enough for
     /// some applications.
     public struct PBKDF1 {
-
         public enum Error: Swift.Error {
             case invalidInput
             case derivedKeyTooLong

+ 0 - 3
Sources/CryptoSwift/PKCS/PBKDF2.swift

@@ -23,13 +23,11 @@
 #endif
 
 public extension PKCS5 {
-
     /// A key derivation function.
     ///
     /// PBKDF2 - Password-Based Key Derivation Function 2. Key stretching technique.
     ///          DK = PBKDF2(PRF, Password, Salt, c, dkLen)
     public struct PBKDF2 {
-
         public enum Error: Swift.Error {
             case invalidInput
             case derivedKeyTooLong
@@ -84,7 +82,6 @@ public extension PKCS5 {
 }
 
 fileprivate extension PKCS5.PBKDF2 {
-
     func ARR(_ i: Int) -> Array<UInt8> {
         var inti = Array<UInt8>(repeating: 0, count: 4)
         inti[0] = UInt8((i >> 24) & 0xff)

+ 0 - 1
Sources/CryptoSwift/PKCS/PKCS7Padding.swift

@@ -18,7 +18,6 @@
 //
 
 struct PKCS7Padding: PaddingProtocol {
-
     enum Error: Swift.Error {
         case invalidPaddingValue
     }

+ 0 - 1
Sources/CryptoSwift/Poly1305.swift

@@ -20,7 +20,6 @@
 ///  message such that an attacker has a negligible chance of producing a valid tag for an inauthentic message.
 
 public final class Poly1305: Authenticator {
-
     public enum Error: Swift.Error {
         case authenticateError
     }

+ 7 - 2
Sources/CryptoSwift/Rabbit.swift

@@ -14,7 +14,6 @@
 //
 
 public final class Rabbit: BlockCipher {
-
     public enum Error: Swift.Error {
         case invalidKeyOrInitializationVector
     }
@@ -28,6 +27,10 @@ public final class Rabbit: BlockCipher {
     /// Size of block in bytes
     public static let blockSize = 128 / 8
 
+    public var keySize: Int {
+        return key.count
+    }
+
     /// Key
     private let key: Key
 
@@ -56,6 +59,7 @@ public final class Rabbit: BlockCipher {
     ]
 
     // MARK: - Initializers
+
     public convenience init(key: Array<UInt8>) throws {
         try self.init(key: key, iv: nil)
     }
@@ -70,6 +74,7 @@ public final class Rabbit: BlockCipher {
     }
 
     // MARK: -
+
     fileprivate func setup() {
         p7 = 0
 
@@ -183,8 +188,8 @@ public final class Rabbit: BlockCipher {
 }
 
 // MARK: Cipher
-extension Rabbit: Cipher {
 
+extension Rabbit: Cipher {
     public func encrypt(_ bytes: ArraySlice<UInt8>) throws -> Array<UInt8> {
         setup()
 

+ 2 - 3
Sources/CryptoSwift/SHA1.swift

@@ -37,10 +37,10 @@ public final class SHA1: DigestType {
         // break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15, big-endian
         // Extend the sixteen 32-bit words into eighty 32-bit words:
         let M = UnsafeMutablePointer<UInt32>.allocate(capacity: 80)
-        M.initialize(to: 0, count: 80)
+        M.initialize(repeating: 0, count: 80)
         defer {
             M.deinitialize(count: 80)
-            M.deallocate(capacity: 80)
+            M.deallocate()
         }
 
         for x in 0..<80 {
@@ -104,7 +104,6 @@ public final class SHA1: DigestType {
 }
 
 extension SHA1: Updatable {
-
     @discardableResult
     public func update(withBytes bytes: ArraySlice<UInt8>, isLast: Bool = false) throws -> Array<UInt8> {
         accumulated += bytes

+ 4 - 5
Sources/CryptoSwift/SHA2.swift

@@ -158,10 +158,10 @@ public final class SHA2: DigestType {
         // break chunk into sixteen 64-bit words M[j], 0 ≤ j ≤ 15, big-endian
         // Extend the sixteen 64-bit words into eighty 64-bit words:
         let M = UnsafeMutablePointer<UInt64>.allocate(capacity: k.count)
-        M.initialize(to: 0, count: k.count)
+        M.initialize(repeating: 0, count: k.count)
         defer {
             M.deinitialize(count: self.k.count)
-            M.deallocate(capacity: self.k.count)
+            M.deallocate()
         }
         for x in 0..<k.count {
             switch x {
@@ -220,10 +220,10 @@ public final class SHA2: DigestType {
         // break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15, big-endian
         // Extend the sixteen 32-bit words into sixty-four 32-bit words:
         let M = UnsafeMutablePointer<UInt32>.allocate(capacity: k.count)
-        M.initialize(to: 0, count: k.count)
+        M.initialize(repeating: 0, count: k.count)
         defer {
             M.deinitialize(count: self.k.count)
-            M.deallocate(capacity: self.k.count)
+            M.deallocate()
         }
 
         for x in 0..<k.count {
@@ -280,7 +280,6 @@ public final class SHA2: DigestType {
 }
 
 extension SHA2: Updatable {
-
     public func update(withBytes bytes: ArraySlice<UInt8>, isLast: Bool = false) throws -> Array<UInt8> {
         accumulated += bytes
 

+ 4 - 5
Sources/CryptoSwift/SHA3.swift

@@ -97,16 +97,16 @@ public final class SHA3: DigestType {
     ///     A′[x, y,z] = A[x, y,z] ⊕ D[x,z].
     private func θ(_ a: inout Array<UInt64>) {
         let c = UnsafeMutablePointer<UInt64>.allocate(capacity: 5)
-        c.initialize(to: 0, count: 5)
+        c.initialize(repeating: 0, count: 5)
         defer {
             c.deinitialize(count: 5)
-            c.deallocate(capacity: 5)
+            c.deallocate()
         }
         let d = UnsafeMutablePointer<UInt64>.allocate(capacity: 5)
-        d.initialize(to: 0, count: 5)
+        d.initialize(repeating: 0, count: 5)
         defer {
             d.deinitialize(count: 5)
-            d.deallocate(capacity: 5)
+            d.deallocate()
         }
 
         for i in 0..<5 {
@@ -249,7 +249,6 @@ public final class SHA3: DigestType {
 }
 
 extension SHA3: Updatable {
-
     public func update(withBytes bytes: ArraySlice<UInt8>, isLast: Bool = false) throws -> Array<UInt8> {
         accumulated += bytes
 

+ 0 - 1
Sources/CryptoSwift/String+Extension.swift

@@ -15,7 +15,6 @@
 
 /** String extension */
 extension String {
-
     public var bytes: Array<UInt8> {
         return data(using: String.Encoding.utf8, allowLossyConversion: true)?.bytes ?? Array(utf8)
     }

+ 0 - 1
Sources/CryptoSwift/UInt16+Extension.swift

@@ -15,7 +15,6 @@
 
 /** array of bytes */
 extension UInt16 {
-
     @_specialize(exported: true, where T == ArraySlice<UInt8>)
     init<T: Collection>(bytes: T) where T.Element == UInt8, T.Index == Int {
         self = UInt16(bytes: bytes, fromIndex: bytes.startIndex)

+ 0 - 1
Sources/CryptoSwift/UInt32+Extension.swift

@@ -24,7 +24,6 @@ extension UInt32: _UInt32Type {}
 
 /** array of bytes */
 extension UInt32 {
-
     @_specialize(exported: true, where T == ArraySlice<UInt8>)
     init<T: Collection>(bytes: T) where T.Element == UInt8, T.Index == Int {
         self = UInt32(bytes: bytes, fromIndex: bytes.startIndex)

+ 0 - 1
Sources/CryptoSwift/UInt64+Extension.swift

@@ -15,7 +15,6 @@
 
 /** array of bytes */
 extension UInt64 {
-
     @_specialize(exported: true, where T == ArraySlice<UInt8>)
     init<T: Collection>(bytes: T) where T.Element == UInt8, T.Index == Int {
         self = UInt64(bytes: bytes, fromIndex: bytes.startIndex)

+ 0 - 2
Sources/CryptoSwift/UInt8+Extension.swift

@@ -24,7 +24,6 @@ extension UInt8: _UInt8Type {}
 
 /** casting */
 extension UInt8 {
-
     /** cast because UInt8(<UInt32>) because std initializer crash if value is > byte */
     static func with(value: UInt64) -> UInt8 {
         let tmp = value & 0xff
@@ -44,7 +43,6 @@ extension UInt8 {
 
 /** Bits */
 extension UInt8 {
-
     init(bits: [Bit]) {
         self.init(integerFrom(bits) as UInt8)
     }

+ 0 - 2
Sources/CryptoSwift/Updatable.swift

@@ -45,7 +45,6 @@ public protocol Updatable {
 }
 
 extension Updatable {
-
     public mutating func update(withBytes bytes: ArraySlice<UInt8>, isLast: Bool = false, output: (_ bytes: Array<UInt8>) -> Void) throws {
         let processed = try update(withBytes: bytes, isLast: isLast)
         if !processed.isEmpty {
@@ -76,7 +75,6 @@ extension Updatable {
 }
 
 extension Updatable {
-
     @discardableResult
     public mutating func update(withBytes bytes: Array<UInt8>, isLast: Bool = false) throws -> Array<UInt8> {
         return try update(withBytes: bytes.slice, isLast: isLast)

+ 5 - 5
Sources/CryptoSwift/Utils.swift

@@ -68,18 +68,18 @@ func reversed(_ uint32: UInt32) -> UInt32 {
     return v
 }
 
-func xor<T, V>(_ left: T, _ right: V) -> ArraySlice<UInt8> where T: RandomAccessCollection, V: RandomAccessCollection, T.Element == UInt8, T.Index == Int, T.IndexDistance == Int, V.Element == UInt8, V.IndexDistance == Int, V.Index == Int {
+func xor<T, V>(_ left: T, _ right: V) -> ArraySlice<UInt8> where T: RandomAccessCollection, V: RandomAccessCollection, T.Element == UInt8, T.Index == Int, V.Element == UInt8, V.Index == Int {
     return xor(left, right).slice
 }
 
-func xor<T, V>(_ left: T, _ right: V) -> Array<UInt8> where T: RandomAccessCollection, V: RandomAccessCollection, T.Element == UInt8, T.Index == Int, T.IndexDistance == Int, V.Element == UInt8, V.IndexDistance == Int, V.Index == Int {
+func xor<T, V>(_ left: T, _ right: V) -> Array<UInt8> where T: RandomAccessCollection, V: RandomAccessCollection, T.Element == UInt8, T.Index == Int, V.Element == UInt8, V.Index == Int {
     let length = Swift.min(left.count, right.count)
 
     let buf = UnsafeMutablePointer<UInt8>.allocate(capacity: length)
-    buf.initialize(to: 0, count: length)
+    buf.initialize(repeating: 0, count: length)
     defer {
-        buf.deinitialize()
-        buf.deallocate(capacity: length)
+        buf.deinitialize(count: length)
+        buf.deallocate()
     }
 
     // xor

+ 0 - 1
Sources/CryptoSwift/ZeroPadding.swift

@@ -16,7 +16,6 @@
 /// All the bytes that are required to be padded are padded with zero.
 /// Zero padding may not be reversible if the original file ends with one or more zero bytes.
 struct ZeroPadding: PaddingProtocol {
-
     init() {
     }
 

+ 2 - 4
Tests/CryptoSwiftTests/AESTests.swift

@@ -13,9 +13,9 @@
 //  - This notice may not be removed or altered from any source or binary distribution.
 //
 
-import XCTest
-import Foundation
 @testable import CryptoSwift
+import Foundation
+import XCTest
 
 final class AESTests: XCTestCase {
     // 128 bit key
@@ -366,7 +366,6 @@ final class AESTests: XCTestCase {
 #if !CI
 
     extension AESTests {
-
         func testAESEncryptPerformance() {
             let key: Array<UInt8> = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c]
             let iv: Array<UInt8> = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f]
@@ -390,7 +389,6 @@ final class AESTests: XCTestCase {
 #endif
 
 extension AESTests {
-
     static func allTests() -> [(String, (AESTests) -> () -> Void)] {
         var tests = [
             ("testAESEncrypt", testAESEncrypt),

+ 2 - 2
Tests/CryptoSwiftTests/Access.swift

@@ -13,10 +13,10 @@
 //  - This notice may not be removed or altered from any source or binary distribution.
 //
 
-import XCTest
-import Foundation
 // import without @testable to test public API
 import CryptoSwift
+import Foundation
+import XCTest
 
 class Access: XCTestCase {
     let cipher = try! AES(key: "secret0key000000", iv: "0123456789012345")

+ 1 - 3
Tests/CryptoSwiftTests/BlowfishTests.swift

@@ -15,11 +15,10 @@
 
 // Test vector from http://www.schneier.com/code/vectors.txt
 
-import XCTest
 @testable import CryptoSwift
+import XCTest
 
 class BlowfishTests: XCTestCase {
-
     struct TestData {
         let key: Array<UInt8>
         let input: Array<UInt8>
@@ -211,7 +210,6 @@ class BlowfishTests: XCTestCase {
 }
 
 extension BlowfishTests {
-
     static func allTests() -> [(String, (BlowfishTests) -> () -> Void)] {
         let tests = [
             ("testEncrypt", testEncrypt),

+ 64 - 0
Tests/CryptoSwiftTests/CMACTests.swift

@@ -0,0 +1,64 @@
+//
+//  CryptoSwift
+//
+//  Copyright (C) 2014-2017 Marcin Krzyżanowski <marcin@krzyzanowskim.com>
+//  This software is provided 'as-is', without any express or implied warranty.
+//
+//  In no event will the authors be held liable for any damages arising from the use of this software.
+//
+//  Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
+//
+//  - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required.
+//  - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+//  - This notice may not be removed or altered from any source or binary distribution.
+//
+
+// Test vectors from https://tools.ietf.org/html/rfc4493
+
+@testable import CryptoSwift
+import XCTest
+
+final class CMACTests: XCTestCase {
+    func testMessageLength0() {
+        let key: Array<UInt8> = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c]
+        let msg: Array<UInt8> = []
+        let expectedMac: Array<UInt8> = [0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46]
+
+        let cmac = try! CMAC(key: key).authenticate(msg)
+        XCTAssertEqual(cmac, expectedMac, "Invalid authentication result")
+    }
+
+    func testMessageLength16() {
+        let key: Array<UInt8> = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c]
+        let msg: Array<UInt8> = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a]
+        let expectedMac: Array<UInt8> = [0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c]
+
+        let cmac = try! CMAC(key: key).authenticate(msg)
+        XCTAssertEqual(cmac, expectedMac, "Invalid authentication result")
+    }
+
+    func testMessageLength40() {
+        let key: Array<UInt8> = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c]
+        let msg: Array<UInt8> = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11]
+        let expectedMac: Array<UInt8> = [0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27]
+
+        let cmac = try! CMAC(key: key).authenticate(msg)
+        XCTAssertEqual(cmac, expectedMac, "Invalid authentication result")
+    }
+
+    func testMessageLength64() {
+        let key: Array<UInt8> = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c]
+        let msg: Array<UInt8> = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10]
+        let expectedMac: Array<UInt8> = [0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe]
+
+        let cmac = try! CMAC(key: key).authenticate(msg)
+        XCTAssertEqual(cmac, expectedMac, "Invalid authentication result")
+    }
+
+    static let allTests = [
+        ("testMessageLength0", testMessageLength0),
+        ("testMessageLength16", testMessageLength16),
+        ("testMessageLength40", testMessageLength40),
+        ("testMessageLength64", testMessageLength64),
+    ]
+}

+ 84 - 0
Tests/CryptoSwiftTests/ChaCha20Poly1305Tests.swift

@@ -0,0 +1,84 @@
+//
+//  ChaCha20Poly1305Tests.swift
+//  CryptoSwiftTests
+//
+//  Copyright (C) 2014-2017 Marcin Krzyżanowski <marcin@krzyzanowskim.com>
+//  This software is provided 'as-is', without any express or implied warranty.
+//
+//  In no event will the authors be held liable for any damages arising from the use of this software.
+//
+//  Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
+//
+//  - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required.
+//  - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+//  - This notice may not be removed or altered from any source or binary distribution.
+//
+//
+//  https://tools.ietf.org/html/rfc7539#section-2.8.1
+
+@testable import CryptoSwift
+import XCTest
+
+class ChaCha20Poly1305Tests: XCTestCase {
+    static let allTests = [
+        ("testCCPoly1", test1),
+        ("testCCPoly2", test2),
+        ("testCCPoly3", test3),
+    ]
+
+    func test1() {
+        executeTestCase("6b65792e6b65792e6b65792e6b65792e6b65792e6b65792e6b65792e6b65792e",
+                        "6e6f6e63652e6e6f6e63652e",
+                        "",
+                        "6d657373616765",
+                        "5d9c0a9fe7d5e5",
+                        "c93aa61fc3cc66a819ac96f6ce365aee")
+    }
+
+    func test2() {
+        /* Test vector from section 2.8.2. */
+        executeTestCase("808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+                        "070000004041424344454647",
+                        "50515253c0c1c2c3c4c5c6c7",
+                        "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e",
+                        "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116",
+                        "1ae10b594f09e26a7e902ecbd0600691")
+    }
+
+    func test3() {
+        /* Test vector from A.5. */
+        executeTestCase("1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0",
+                        "000000000102030405060708",
+                        "f33388860000000000004e91",
+                        "496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d",
+                        "64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b",
+                        "eead9d67890cbb22392336fea1851f38")
+    }
+
+    func executeTestCase(_ key: String, _ nonce: String, _ header: String, _ message: String, _ cipher: String, _ tag: String) {
+        let keyArr = Array<UInt8>(hex: key)
+        let nonceArr = Array<UInt8>(hex: nonce)
+        let headerArr = Array<UInt8>(hex: header)
+        let messageArr = Array<UInt8>(hex: message)
+        let cipherArr = Array<UInt8>(hex: cipher)
+        let tagArr = Array<UInt8>(hex: tag)
+
+        do {
+            let encryptResult = try AEADChaCha20Poly1305.encrypt(messageArr, key: keyArr, iv: nonceArr, authenticationHeader: headerArr)
+
+            XCTAssertEqual(encryptResult.cipherText, cipherArr, "cipher not equal")
+            XCTAssertEqual(encryptResult.authenticationTag, tagArr, "tag not equal")
+        } catch {
+            XCTAssert(false, "Encryption Failed with error: \(error.localizedDescription)")
+        }
+
+        do {
+            let decryptResult = try AEADChaCha20Poly1305.decrypt(cipherArr, key: keyArr, iv: nonceArr, authenticationHeader: headerArr, authenticationTag: tagArr)
+
+            XCTAssertEqual(decryptResult.success, true, "decrypt mac check failed")
+            XCTAssertEqual(decryptResult.plainText, messageArr, "message not equal")
+        } catch {
+            XCTAssert(false, "Encryption Failed with error: \(error.localizedDescription)")
+        }
+    }
+}

+ 2 - 5
Tests/CryptoSwiftTests/ChaCha20Tests.swift

@@ -13,12 +13,11 @@
 //  - This notice may not be removed or altered from any source or binary distribution.
 //
 
-import XCTest
-import Foundation
 @testable import CryptoSwift
+import Foundation
+import XCTest
 
 final class ChaCha20Tests: XCTestCase {
-
     func testChaCha20() {
         let keys: [Array<UInt8>] = [
             [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
@@ -112,7 +111,6 @@ final class ChaCha20Tests: XCTestCase {
 #if !CI
 
     extension ChaCha20Tests {
-
         func testChaCha20Performance() {
             let key: Array<UInt8> = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f]
             let iv: Array<UInt8> = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]
@@ -130,7 +128,6 @@ final class ChaCha20Tests: XCTestCase {
 #endif
 
 extension ChaCha20Tests {
-
     static func allTests() -> [(String, (ChaCha20Tests) -> () -> Void)] {
         var tests = [
             ("testChaCha20", testChaCha20),

+ 12 - 15
Tests/CryptoSwiftTests/DigestTests.swift

@@ -16,12 +16,11 @@
 // http://www.di-mgt.com.au/sha_testvectors.html (http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf)
 //
 
-import XCTest
-import Foundation
 @testable import CryptoSwift
+import Foundation
+import XCTest
 
 final class DigestTests: XCTestCase {
-
     func testMD5() {
         XCTAssertEqual("123".md5(), "202cb962ac59075b964b07152d234b70", "MD5 calculation failed")
         XCTAssertEqual("".md5(), "d41d8cd98f00b204e9800998ecf8427e", "MD5 calculation failed")
@@ -260,7 +259,6 @@ final class DigestTests: XCTestCase {
 #if !CI
 
     extension DigestTests {
-
         func testMD5Performance() {
             measureMetrics([XCTPerformanceMetric.wallClockTime], automaticallyStartMeasuring: false) {
                 let arr = Array<UInt8>(repeating: 200, count: 1024 * 1024)
@@ -281,22 +279,21 @@ final class DigestTests: XCTestCase {
 
         // Keep it to compare
         /*
-        func testSHA1PerformanceCC() {
-            measureMetrics([XCTPerformanceMetric.wallClockTime], automaticallyStartMeasuring: false) {
-                let arr = Array<UInt8>(repeating: 200, count: 1024 * 1024)
-                self.startMeasuring()
-                var digest = Array<UInt8>(repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
-                CC_SHA1(arr, CC_LONG(arr.count), &digest)
-                self.stopMeasuring()
-            }
-        }
+         func testSHA1PerformanceCC() {
+         measureMetrics([XCTPerformanceMetric.wallClockTime], automaticallyStartMeasuring: false) {
+         let arr = Array<UInt8>(repeating: 200, count: 1024 * 1024)
+         self.startMeasuring()
+         var digest = Array<UInt8>(repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
+         CC_SHA1(arr, CC_LONG(arr.count), &digest)
+         self.stopMeasuring()
+         }
+         }
          */
     }
 
 #endif
 
 extension DigestTests {
-
     static func allTests() -> [(String, (DigestTests) -> () -> Void)] {
         var tests = [
             ("testMD5", testMD5),
@@ -311,7 +308,7 @@ extension DigestTests {
             ("testCRC32NotReflected", testCRC32NotReflected),
             ("testCRC16", testCRC16),
             ("testChecksum", testChecksum),
-            ("testSHAPartialUpdates", testSHAPartialUpdates)
+            ("testSHAPartialUpdates", testSHAPartialUpdates),
         ]
 
         #if !CI

+ 2 - 5
Tests/CryptoSwiftTests/ExtensionsTest.swift

@@ -13,12 +13,11 @@
 //  - This notice may not be removed or altered from any source or binary distribution.
 //
 
-import XCTest
-import Foundation
 @testable import CryptoSwift
+import Foundation
+import XCTest
 
 final class ExtensionsTest: XCTestCase {
-
     func testBytes() {
         let size = MemoryLayout<UInt32>.size // 32 or 64  bit
 
@@ -88,7 +87,6 @@ final class ExtensionsTest: XCTestCase {
 #if !CI
 
     extension ExtensionsTest {
-
         func testArrayInitHexPerformance() {
             var str = "b1b2b3b3b3b3b3b3b1b2b3b3b3b3b3b3"
             for _ in 0...12 {
@@ -102,7 +100,6 @@ final class ExtensionsTest: XCTestCase {
 #endif
 
 extension ExtensionsTest {
-
     static func allTests() -> [(String, (ExtensionsTest) -> () -> Void)] {
         var tests = [
             ("testBytes", testBytes),

+ 14 - 15
Tests/CryptoSwiftTests/HKDFTests.swift

@@ -13,14 +13,13 @@
 //  - This notice may not be removed or altered from any source or binary distribution.
 //
 
-import XCTest
 @testable import CryptoSwift
+import XCTest
 
 class HKDFTests: XCTestCase {
-    
     /// All test cases are implemented with regard to RFC 5869
     /// https://www.ietf.org/rfc/rfc5869.txt
-    
+
     func testHKDF1() {
         let password = Array<UInt8>(hex: "0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b")
         let salt = Array<UInt8>(hex: "0x000102030405060708090a0b0c")
@@ -28,10 +27,10 @@ class HKDFTests: XCTestCase {
         let keyLength = 42
         let variant = HMAC.Variant.sha256
         let reference = Array<UInt8>(hex: "0x3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865")
-        
+
         XCTAssertEqual(reference, try HKDF(password: password, salt: salt, info: info, keyLength: keyLength, variant: variant).calculate())
     }
-    
+
     func testHKDF2() {
         let password = Array<UInt8>(hex: "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f")
         let salt = Array<UInt8>(hex: "0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf")
@@ -39,19 +38,19 @@ class HKDFTests: XCTestCase {
         let keyLength = 82
         let variant = HMAC.Variant.sha256
         let reference = Array<UInt8>(hex: "0xb11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87")
-        
+
         XCTAssertEqual(reference, try HKDF(password: password, salt: salt, info: info, keyLength: keyLength, variant: variant).calculate())
     }
-    
+
     func testHKDF3() {
         let password = Array<UInt8>(hex: "0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b")
         let keyLength = 42
         let variant = HMAC.Variant.sha256
         let reference = Array<UInt8>(hex: "0x8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8")
-        
+
         XCTAssertEqual(reference, try HKDF(password: password, keyLength: keyLength, variant: variant).calculate())
     }
-    
+
     func testHKDF4() {
         let password = Array<UInt8>(hex: "0x0b0b0b0b0b0b0b0b0b0b0b")
         let salt = Array<UInt8>(hex: "0x000102030405060708090a0b0c")
@@ -59,10 +58,10 @@ class HKDFTests: XCTestCase {
         let keyLength = 42
         let variant = HMAC.Variant.sha1
         let reference = Array<UInt8>(hex: "0x085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896")
-        
+
         XCTAssertEqual(reference, try HKDF(password: password, salt: salt, info: info, keyLength: keyLength, variant: variant).calculate())
     }
-    
+
     func testHKDF5() {
         let password = Array<UInt8>(hex: "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f")
         let salt = Array<UInt8>(hex: "0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf")
@@ -70,16 +69,16 @@ class HKDFTests: XCTestCase {
         let keyLength = 82
         let variant = HMAC.Variant.sha1
         let reference = Array<UInt8>(hex: "0x0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4")
-        
+
         XCTAssertEqual(reference, try HKDF(password: password, salt: salt, info: info, keyLength: keyLength, variant: variant).calculate())
     }
-    
+
     func testHKDF6() {
         let password = Array<UInt8>(hex: "0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b")
         let keyLength = 42
         let variant = HMAC.Variant.sha1
         let reference = Array<UInt8>(hex: "0x0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918")
-        
+
         XCTAssertEqual(reference, try HKDF(password: password, keyLength: keyLength, variant: variant).calculate())
     }
 
@@ -90,7 +89,7 @@ class HKDFTests: XCTestCase {
             ("Test with SHA-256 and zero-length salt/info", testHKDF3),
             ("Basic test case with SHA-1", testHKDF4),
             ("Test with SHA-1 and longer inputs/outputs", testHKDF5),
-            ("Test with SHA-1 and zero-length salt/info", testHKDF6)
+            ("Test with SHA-1 and zero-length salt/info", testHKDF6),
         ]
 
         return tests

+ 1 - 2
Tests/CryptoSwiftTests/HMACTests.swift

@@ -13,11 +13,10 @@
 //  - This notice may not be removed or altered from any source or binary distribution.
 //
 
-import XCTest
 @testable import CryptoSwift
+import XCTest
 
 final class HMACTests: XCTestCase {
-
     func testMD5() {
         let key: Array<UInt8> = []
         let msg: Array<UInt8> = []

+ 1 - 2
Tests/CryptoSwiftTests/PBKDF.swift

@@ -13,11 +13,10 @@
 //  - This notice may not be removed or altered from any source or binary distribution.
 //
 
-import XCTest
 @testable import CryptoSwift
+import XCTest
 
 class PBKDF: XCTestCase {
-
     func testPBKDF1() {
         let password: Array<UInt8> = [0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64]
         let salt: Array<UInt8> = [0x78, 0x57, 0x8e, 0x5a, 0x5d, 0x63, 0xcb, 0x06]

+ 1 - 2
Tests/CryptoSwiftTests/PaddingTests.swift

@@ -13,11 +13,10 @@
 //  - This notice may not be removed or altered from any source or binary distribution.
 //
 
-import XCTest
 @testable import CryptoSwift
+import XCTest
 
 final class PaddingTests: XCTestCase {
-
     func testPKCS7_0() {
         let input: Array<UInt8> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6]
         let expected: Array<UInt8> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]

+ 2 - 3
Tests/CryptoSwiftTests/Poly1305Tests.swift

@@ -13,12 +13,11 @@
 //  - This notice may not be removed or altered from any source or binary distribution.
 //
 
-import XCTest
-import Foundation
 @testable import CryptoSwift
+import Foundation
+import XCTest
 
 final class Poly1305Tests: XCTestCase {
-
     func testPoly1305() {
         let key: Array<UInt8> = [0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc]
         let msg: Array<UInt8> = [0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1]

+ 1 - 4
Tests/CryptoSwiftTests/RabbitTests.swift

@@ -13,11 +13,10 @@
 //  - This notice may not be removed or altered from any source or binary distribution.
 //
 
-import XCTest
 @testable import CryptoSwift
+import XCTest
 
 class RabbitTests: XCTestCase {
-
     func testInitialization() {
         var key = Array<UInt8>(repeating: 0, count: Rabbit.keySize - 1)
         var iv: Array<UInt8>?
@@ -119,7 +118,6 @@ class RabbitTests: XCTestCase {
 #if !CI
 
     extension RabbitTests {
-
         func testRabbitPerformance() {
             let key: Array<UInt8> = Array<UInt8>(repeating: 0, count: Rabbit.keySize)
             let iv: Array<UInt8> = Array<UInt8>(repeating: 0, count: Rabbit.ivSize)
@@ -132,7 +130,6 @@ class RabbitTests: XCTestCase {
 #endif
 
 extension RabbitTests {
-
     static func allTests() -> [(String, (RabbitTests) -> () -> Void)] {
         var tests = [
             ("testInitialization", testInitialization),

+ 1 - 2
Tests/CryptoSwiftTests/RandomBytesSequenceTests.swift

@@ -13,11 +13,10 @@
 //  - This notice may not be removed or altered from any source or binary distribution.
 //
 
-import XCTest
 @testable import CryptoSwift
+import XCTest
 
 class RandomBytesSequenceTests: XCTestCase {
-
     func testSequence() {
         XCTAssertNil(RandomBytesSequence(size: 0).makeIterator().next())
 

+ 2 - 1
Tests/LinuxMain.swift

@@ -1,10 +1,11 @@
-import XCTest
 @testable import CryptoSwiftTests
+import XCTest
 
 XCTMain([
     testCase(DigestTests.allTests()),
     testCase(Poly1305Tests.allTests),
     testCase(HMACTests.allTests),
+    testCase(CMACTests.allTests),
     testCase(AESTests.allTests()),
     testCase(BlowfishTests.allTests()),
     testCase(ChaCha20Tests.allTests()),