diff --git a/.gitmodules b/.gitmodules index f347004f26..1830ef76cd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "Carthage/Checkouts/SQLite.swift"] path = Carthage/Checkouts/SQLite.swift url = https://github.com/stephencelis/SQLite.swift.git +[submodule "Carthage/Checkouts/CryptoSwift"] + path = Carthage/Checkouts/CryptoSwift + url = https://github.com/krzyzanowskim/CryptoSwift.git diff --git a/Apollo.podspec b/Apollo.podspec index 492cf81e1c..a7859b17cc 100644 --- a/Apollo.podspec +++ b/Apollo.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.requires_arc = true - s.swift_version = '4.2' + s.swift_version = '5.0' s.default_subspecs = 'Core' @@ -23,6 +23,7 @@ Pod::Spec.new do |s| s.subspec 'Core' do |ss| ss.source_files = 'Sources/Apollo/*.swift' ss.preserve_paths = ['scripts/check-and-run-apollo-cli.sh', 'scripts/check-and-run-apollo-codegen.sh'] + ss.dependency 'CryptoSwift' end # Apollo provides exactly one persistent cache out-of-the-box, as a reasonable default choice for @@ -30,7 +31,7 @@ Pod::Spec.new do |s| s.subspec 'SQLite' do |ss| ss.source_files = 'Sources/ApolloSQLite/*.swift' ss.dependency 'Apollo/Core' - ss.dependency 'SQLite.swift', '~> 0.11.4' + ss.dependency 'SQLite.swift', '~> 0.12.0' end # Websocket and subscription support based on Starscream diff --git a/Apollo.xcodeproj/project.pbxproj b/Apollo.xcodeproj/project.pbxproj index 1bff7a999a..5d8f19e08b 100644 --- a/Apollo.xcodeproj/project.pbxproj +++ b/Apollo.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 1D91186A2208DD5600F23EFD /* GraphQLFragmentWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D9118692208DD5600F23EFD /* GraphQLFragmentWatcher.swift */; }; + 1DAAEBC922C667CF00068B8F /* APQNetworkTransport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DAAEBC822C667CF00068B8F /* APQNetworkTransport.swift */; }; + 1DAAEBEF22C6763700068B8F /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DAAEBD922C6721E00068B8F /* CryptoSwift.framework */; }; 54DDB0921EA045870009DD99 /* InMemoryNormalizedCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54DDB0911EA045870009DD99 /* InMemoryNormalizedCache.swift */; }; 5AC6CA4322AAF7B200B7C94D /* FetchHTTPMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AC6CA4222AAF7B200B7C94D /* FetchHTTPMethod.swift */; }; 9F0CA4451EE7F9E90032DD39 /* ApolloTestSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F8A95781EC0FC1200304A2D /* ApolloTestSupport.framework */; }; @@ -99,6 +102,41 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 1DAAEBD822C6721E00068B8F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1DAAEBD022C6721E00068B8F /* CryptoSwift.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 754BE45519693E190098E6F3; + remoteInfo = CryptoSwift; + }; + 1DAAEBDA22C6721E00068B8F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1DAAEBD022C6721E00068B8F /* CryptoSwift.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 75211F92207249D8004E41F8; + remoteInfo = "CryptoSwift-TestHostApp"; + }; + 1DAAEBDC22C6721E00068B8F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1DAAEBD022C6721E00068B8F /* CryptoSwift.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 754BE46019693E190098E6F3; + remoteInfo = Tests; + }; + 1DAAEBDE22C6721E00068B8F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1DAAEBD022C6721E00068B8F /* CryptoSwift.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 7595C14A2072E48C00EA1A5F; + remoteInfo = "TestsPerformance-Mac"; + }; + 1DAAEBE022C6721E00068B8F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1DAAEBD022C6721E00068B8F /* CryptoSwift.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 7564F0602072EAEB00CA5A96; + remoteInfo = "TestsPerformance-iOS"; + }; 9F0CA4471EE7F9E90032DD39 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 9FC7503B1D2A532C00458D91 /* Project object */; @@ -230,6 +268,9 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 1D9118692208DD5600F23EFD /* GraphQLFragmentWatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphQLFragmentWatcher.swift; sourceTree = ""; }; + 1DAAEBC822C667CF00068B8F /* APQNetworkTransport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APQNetworkTransport.swift; sourceTree = ""; }; + 1DAAEBD022C6721E00068B8F /* CryptoSwift.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CryptoSwift.xcodeproj; path = Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj; sourceTree = ""; }; 54DDB0911EA045870009DD99 /* InMemoryNormalizedCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InMemoryNormalizedCache.swift; sourceTree = ""; }; 5AC6CA4222AAF7B200B7C94D /* FetchHTTPMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchHTTPMethod.swift; sourceTree = ""; }; 90690D05224333DA00FC2E54 /* Apollo-Project-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Apollo-Project-Debug.xcconfig"; sourceTree = ""; }; @@ -348,6 +389,14 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 1DAAEBE922C6763000068B8F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1DAAEBEF22C6763700068B8F /* CryptoSwift.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 9F8A95741EC0FC1200304A2D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -415,6 +464,26 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 1DAAEBCD22C66FD300068B8F /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DAAEBD022C6721E00068B8F /* CryptoSwift.xcodeproj */, + ); + name = Frameworks; + sourceTree = ""; + }; + 1DAAEBD122C6721E00068B8F /* Products */ = { + isa = PBXGroup; + children = ( + 1DAAEBD922C6721E00068B8F /* CryptoSwift.framework */, + 1DAAEBDB22C6721E00068B8F /* CryptoSwift-TestHostApp.app */, + 1DAAEBDD22C6721E00068B8F /* Tests.xctest */, + 1DAAEBDF22C6721E00068B8F /* TestsPerformance-Mac.xctest */, + 1DAAEBE122C6721E00068B8F /* TestsPerformance-iOS.xctest */, + ); + name = Products; + sourceTree = ""; + }; 90690D04224333DA00FC2E54 /* Configuration */ = { isa = PBXGroup; children = ( @@ -515,6 +584,7 @@ 9FCE2CF41E6C20E000E34457 /* Tests */, 90690D04224333DA00FC2E54 /* Configuration */, 9FC750451D2A532C00458D91 /* Products */, + 1DAAEBCD22C66FD300068B8F /* Frameworks */, ); sourceTree = ""; }; @@ -541,6 +611,7 @@ 9FC750601D2A59C300458D91 /* GraphQLOperation.swift */, 9FC9A9BE1E2C27FB0023C4D5 /* GraphQLResult.swift */, 9FC9A9D21E2FD48B0023C4D5 /* GraphQLError.swift */, + 1D9118692208DD5600F23EFD /* GraphQLFragmentWatcher.swift */, 9FCDFD281E33D0CE007519DC /* GraphQLQueryWatcher.swift */, 9FC9A9CE1E2FD0CC0023C4D5 /* Network */, 9FC9A9CA1E2FD05C0023C4D5 /* Store */, @@ -593,6 +664,7 @@ 9F69FFA81D42855900E000B1 /* NetworkTransport.swift */, 9F4DAF2D1E48B84B00EBFF0B /* HTTPNetworkTransport.swift */, 9FF90A5B1DDDEB100034C3B6 /* GraphQLResponse.swift */, + 1DAAEBC822C667CF00068B8F /* APQNetworkTransport.swift */, ); name = Network; sourceTree = ""; @@ -796,6 +868,7 @@ 9FC7503F1D2A532C00458D91 /* Sources */, 9FC750411D2A532C00458D91 /* Headers */, 9FC750421D2A532C00458D91 /* Resources */, + 1DAAEBE922C6763000068B8F /* Frameworks */, ); buildRules = ( ); @@ -927,6 +1000,12 @@ mainGroup = 9FC7503A1D2A532C00458D91; productRefGroup = 9FC750451D2A532C00458D91 /* Products */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 1DAAEBD122C6721E00068B8F /* Products */; + ProjectRef = 1DAAEBD022C6721E00068B8F /* CryptoSwift.xcodeproj */; + }, + ); projectRoot = ""; targets = ( 9FC750431D2A532C00458D91 /* Apollo */, @@ -941,6 +1020,44 @@ }; /* End PBXProject section */ +/* Begin PBXReferenceProxy section */ + 1DAAEBD922C6721E00068B8F /* CryptoSwift.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = CryptoSwift.framework; + remoteRef = 1DAAEBD822C6721E00068B8F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 1DAAEBDB22C6721E00068B8F /* CryptoSwift-TestHostApp.app */ = { + isa = PBXReferenceProxy; + fileType = wrapper.application; + path = "CryptoSwift-TestHostApp.app"; + remoteRef = 1DAAEBDA22C6721E00068B8F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 1DAAEBDD22C6721E00068B8F /* Tests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = Tests.xctest; + remoteRef = 1DAAEBDC22C6721E00068B8F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 1DAAEBDF22C6721E00068B8F /* TestsPerformance-Mac.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "TestsPerformance-Mac.xctest"; + remoteRef = 1DAAEBDE22C6721E00068B8F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 1DAAEBE122C6721E00068B8F /* TestsPerformance-iOS.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "TestsPerformance-iOS.xctest"; + remoteRef = 1DAAEBE022C6721E00068B8F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + /* Begin PBXResourcesBuildPhase section */ 9FC750421D2A532C00458D91 /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -1066,6 +1183,7 @@ 9F55347B1DE1DB2100E54264 /* ApolloStore.swift in Sources */, 9F69FFA91D42855900E000B1 /* NetworkTransport.swift in Sources */, 9FCDFD291E33D0CE007519DC /* GraphQLQueryWatcher.swift in Sources */, + 1D91186A2208DD5600F23EFD /* GraphQLFragmentWatcher.swift in Sources */, 9FC2333D1E66BBF7001E4541 /* GraphQLDependencyTracker.swift in Sources */, 9F19D8441EED568200C57247 /* ResultOrPromise.swift in Sources */, 9FC9A9BF1E2C27FB0023C4D5 /* GraphQLResult.swift in Sources */, @@ -1088,6 +1206,7 @@ 9FC750611D2A59C300458D91 /* GraphQLOperation.swift in Sources */, 5AC6CA4322AAF7B200B7C94D /* FetchHTTPMethod.swift in Sources */, 9FE941D01E62C771007CDD89 /* Promise.swift in Sources */, + 1DAAEBC922C667CF00068B8F /* APQNetworkTransport.swift in Sources */, 9FC750631D2A59F600458D91 /* ApolloClient.swift in Sources */, 9F86B6901E65533D00B885FF /* GraphQLResponseGenerator.swift in Sources */, 9FC9A9C21E2D3CAF0023C4D5 /* GraphQLInputValue.swift in Sources */, diff --git a/Cartfile b/Cartfile index 397ca8b95f..1f30be4520 100644 --- a/Cartfile +++ b/Cartfile @@ -1,2 +1,3 @@ github "stephencelis/SQLite.swift" ~> 0.12.0 github "daltoniam/Starscream" ~> 3.1.0 +github "krzyzanowskim/CryptoSwift" diff --git a/Cartfile.resolved b/Cartfile.resolved index 514ee666bb..47d72a0575 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,2 +1,3 @@ github "daltoniam/Starscream" "3.1.0" -github "stephencelis/SQLite.swift" "0.12.0" +github "krzyzanowskim/CryptoSwift" "1.0.0" +github "stephencelis/SQLite.swift" "0.12.2" diff --git a/Carthage/Checkouts/CryptoSwift/.github/CODEOWNERS b/Carthage/Checkouts/CryptoSwift/.github/CODEOWNERS new file mode 100644 index 0000000000..f0b3586b3a --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/.github/CODEOWNERS @@ -0,0 +1 @@ +* @krzyzanowskim \ No newline at end of file diff --git a/Carthage/Checkouts/CryptoSwift/.github/ISSUE_TEMPLATE.md b/Carthage/Checkouts/CryptoSwift/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..d4f8a83ea3 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,21 @@ +- CryptoSwift version: +- Swift version: +- 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 to reproduce the issue: + +```swift +import CryptoSwift + +// Code goes here + +``` diff --git a/Carthage/Checkouts/CryptoSwift/.github/ISSUE_TEMPLATE/bug_report.md b/Carthage/Checkouts/CryptoSwift/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..574425a57e --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,31 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. + +**Sample code** + +```swift + + + +``` + +**Expected behavior** + + +**Environment (please complete the following information):** +- Swift version: +- Platform (iOS/macOS/Linux/...): +- Installation method (CocoaPods/Carthage/SPM/...): +- Project name: + +**Additional context** diff --git a/Carthage/Checkouts/CryptoSwift/.github/ISSUE_TEMPLATE/feature_request.md b/Carthage/Checkouts/CryptoSwift/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..066b2d920a --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/Carthage/Checkouts/CryptoSwift/.github/PULL_REQUEST_TEMPLATE.md b/Carthage/Checkouts/CryptoSwift/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..e3b0b5f430 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,9 @@ +Fixes # + +Checklist: +- [ ] Correct file headers (see CONTRIBUTING.md). +- [ ] Formatted with [SwiftFormat](https://github.com/nicklockwood/SwiftFormat). +- [ ] Tests added. + +Changes proposed in this pull request: +- diff --git a/Carthage/Checkouts/CryptoSwift/.gitignore b/Carthage/Checkouts/CryptoSwift/.gitignore new file mode 100644 index 0000000000..9ac3bb6d8f --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/.gitignore @@ -0,0 +1,24 @@ +### Xcode ### +.build/ +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.xcuserstate +timeline.xctimeline + +/Framework +.DS_Store +Carthage/Build + +.idea +.vscode diff --git a/Carthage/Checkouts/CryptoSwift/.swift-version b/Carthage/Checkouts/CryptoSwift/.swift-version new file mode 100644 index 0000000000..6e63660516 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/.swift-version @@ -0,0 +1 @@ +5.0 \ No newline at end of file diff --git a/Carthage/Checkouts/CryptoSwift/.travis.yml b/Carthage/Checkouts/CryptoSwift/.travis.yml new file mode 100644 index 0000000000..f667595384 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/.travis.yml @@ -0,0 +1,11 @@ +os: + - linux + - osx +language: generic +sudo: required +dist: trusty +osx_image: xcode10 +install: + - eval "$(curl -sL https://swiftenv.fuller.li/install.sh)" +script: + - swift test -c release -Xswiftc -enable-testing -Xswiftc -DCI -Xswiftc -Xfrontend -Xswiftc -solver-memory-threshold -Xswiftc -Xfrontend -Xswiftc 999999999 diff --git a/Carthage/Checkouts/CryptoSwift/CHANGELOG b/Carthage/Checkouts/CryptoSwift/CHANGELOG new file mode 100644 index 0000000000..fcf4e03f2b --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CHANGELOG @@ -0,0 +1,257 @@ +1.0.0 +- Swift 5 +- Let's +- Celebrate +- This +- Event +- With +- 1.0.0 release +- After +- 4 years +- Thank you + +0.15.0 +- Adds The scrypt Password-Based Key Derivation Function (https://tools.ietf.org/html/rfc7914) +- Minor improvements + +0.14.0 +- Fixed decryption of AES-GCM ciphertexts with custom tag length + +0.13.1 +- Adds AES-GCM tag length configuration. +- Fixes count check for initializing UInt64 from Data. + +0.13.0 +- Adds CBC-MAC authenticator. +- Adds AES-CCM operation mode. + +0.12.0 +- Swift 4.2 maintenance update. + +0.11.0 +- API: Cryptor.seek() is throwable +- Adds proper stream support for CTR encryption with Updaptable interface. +- Refactor internals for the stream cipher modes. +- Set minimum deployment target to 8.0 (again). + +0.10.0 +- API: BlockMode is no longer an enum. Please migrate to eg. CBC() etc... +- Adds AES-GCM support. #97 - Feature sponsored by GesundheitsCloud (http://www.gesundheitscloud.de/) +- Adds CRC32c support. +- Improves AES variant validation. +- Fixes empty password in PBKDF2. + +0.9.0 +- Swift 4.1 compatibility +- 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 + +0.8.3 +- Fixes SHA3 padding. +- Fixes Carthage builds. + +0.8.2 +- Fixes SHA3 partial updates calculations. +- Makes ChaCha20 processing faster again. + +0.8.1 +- Adds Data(hex:) helper. +- Adds HKDF (HMAC-based Extract-and-Expand Key Derivation Function) +- Prevent ChaCha overflow error + +0.8.0 +- Adds SHA3 Keccak variants +- Adds String.bytes helper to convert String to array of bytes +- Improves AES performance +- Speeds up compilation times with Swift 4 +- Fixes: Blowfish minimum key size is 5 +- Removes Ciphers "iv" parameter (value moved to BlockMode) +- BlockMode uses associated value for IV value where apply e.g. .CBC(iv: ivbytes) +- Refactors internal hacks no longer needed with Swift 4 + +0.7.2 +- Adds Padding enum (.pkcs5, .pkcs7, .noPadding, .zeroPadding) +- Removes Generics from the public API. +- Slightly improves SHA1, SHA2, SHA3 performance. +- Update SPM configuration for Swift 4 + +0.7.1 +- Swift 4.0 compatibility release + +0.7.0 +- Swift 3.2 compatibility release + +0.6.9 +- Fixed padding issue where padding was not properly added in CTR mode. +- Fixed thrown error on decrypting empty string, +- Fixed CI build script. +- Added String.encryptToBase64() + +0.6.8 +- Speed up MD5() +- Faster Array(hex:) +- Improve AES performance +- Fix tvOS bitcode +- Fix Blowfish CFB, OFB, CTR block modes. +- Fix Blowfish for 32-bit arch. +- Fix ChaCha20 preconditions + +0.6.7 +- Release for Xcode 8.2 +- Fix playground example + +0.6.6 +- Rework ChaCha20 +- Fix Poly1305 + +0.6.5 +- Significant performance improvement when processing lange amount of data. +- Degeneric functions and change Sequence -> Collection in generic constraints. + +0.6.4 +- More performance improvements +- Add convenient Digest.sha2(bytes:variant) +- New: Blowfish cipher + +0.6.3 +- Hotfix release +- Fixes bitPadding() that breaks Digests calculations, introduced in 0.6.2 + +0.6.2 +- SHA performance improvements by using less Swift in Swift +- Fix public access to all digests classes + +0.6.1 +- Update tests. +- New: RandomBytesSequence urandom values on Linux. +- Throw appropriate error for AES with invalid input where padding is needed. +- Improve performance, especially to SHA-1, SHA-2, PBKDF and related. +- Set deployment targets for all platform. Fixes Carthage builds. +- New: SHA-3 implementation (request #291) +- SHA-1 conforms to Updatable protocol and may be calculated incrementally. +- SHA-2 conforms to Updatable protocol and may be calculated incrementally. + +0.6.0 +- Remove bridge() workaround for Linux (not needed) +- make MD5() public +- Update README +- Convenience HMAC initializer for String input + +0.6.0-beta2 +- SHA-2 fix #319 +- HashProtocol -> Digest and refactor +- MD5 conforms to Updatable protocol and may be calculated incrementally +- Cipher protocol accepts Collection input now + +0.6.0-beta1 +- Swift 3 compatibility +- Multiplatform, Single-scheme Xcode Project +- Swift Package Manager fully supported (build and tests) +- Improved Linux support +- Travis configuration added +- Public interface tests added +- enum Authenticator -> protocol Authenticator +- CRC -> Checksum +- String.encrypt() returns hex string instead of Array +- removed String.decrypt() +- enum Hash -> struct Hash +- Convenience initializer of Array of bytes with Hex string. Array(hex: "0xb1b1b2b2") +- Fix reusability of ChaCha20 instance +- Replace optional initializers with throwable initializers +- Allow to set initial counter explicitly (AES block modes). RandomAccessCryptor.seek() + +0.5.2 +- Fix AES-CTR incremental updates. #287 +- Fixed PBKDF2 tests. #295 +- Fixed assertion check in PKCS7. #288 +- Updatable protocol accept SequenceType in place of Array + +0.5.1 +- Fixed PBKDF2 not taking key length parameter into account +- Switch to Array<> in code + +0.5 +- Added PBKDF1 https://tools.ietf.org/html/rfc2898#section-5.1 +- Added PBKDF2 https://tools.ietf.org/html/rfc2898#section-5.2 +- UpdatableCryptor protocol allows incremental encryption stream of data +- CryptoSwift.playground +- Docs update +- Added reflection control to CRC-32 (Luís Silva) +- Fix AES.init() (Pascal Pfiffner) + +0.4.1 +- fix NoPadding() + +0.4 +- Padding setup is now part of cipher constructor +- Added PBKDF2 http://tools.ietf.org/html/rfc2898#section-5.2 +- Add BlockCipher protocol +- Rename Cipher -> CipherProtocol +- Remove build-frameworks.sh script +- Keep sensitive data in memory with SecureBytes +- Allows direct use of HMAC and Poly1305 +- README update +- Fix missing Foundation import on Linux + +0.3.1 +- replace deprecated Bit with new enum. + +0.3 +- Swift 2.2 support +- use generators for cipher block modes should reduce memory overload. +- add OFB block mode +- add PCBC block mode +- String.decryptBase64ToString to decrypt Base64 encoded strings +- broke up complicated expressions which were taking ages to compile + +0.2.3 +- enable bitcode setting for Debug on an Apple TV +- faster compilation times +- improve padding functions + +0.2.2 +- Fix ChaCha20 cipher +- Replace for(;;) with for-in +- Workaround for "NSString are not yet implicitly convertible to String" on Linux + +0.2.1 +- Fix linux build +- re-add umbrella header + +0.2 +- Rabbit cipher (RFC4503) +- Linux Swift support +- Swift Package Manager support +- tvOS support +- Add optional seed to CRC +- Add umbrella header (CryptoSwift.h) +- Fix AES in CTR mode +- Fix no padding support for CTR and CFB block modes +- Fix access to AES.Error and ChaCha20.Error + +0.1.1 +- Fix Cococapods package (missing Foundation integration) + +0.1.0 +- Major performance improvements. +- Transition from Optionals to throw error. +- Replace enum Cipher with protocol for ciphers. +- Added CRC16 +- Fixed AES CFB decryption +- Drop internal "Foundation" dependency, nonetheless it is supported as usual. + +0.0.16 +- Critical fix for private "md5" selector issue (#135) + +0.0.15 +- Fix 32-bit CTR block mode +- Carthage support update +- Mark as App-Extension-Safe API + +0.0.14 +- hexString -> toHextString() #105 +- CTR (Counter mode) +- Hex string is lowercase now +- Carthage support +- Tests update +- Swift 2.0 support - overall update diff --git a/Carthage/Checkouts/CryptoSwift/CODE_OF_CONDUCT.md b/Carthage/Checkouts/CryptoSwift/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..ea968f5a99 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at marcin@krzyzanowskim.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/Carthage/Checkouts/CryptoSwift/CONTRIBUTING.md b/Carthage/Checkouts/CryptoSwift/CONTRIBUTING.md new file mode 100644 index 0000000000..5ac9234513 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CONTRIBUTING.md @@ -0,0 +1,27 @@ +By submitting a pull request, you represent that you have the right to license +your contribution to Marcin Krzyżanowski and the community, and agree by submitting the patch that your contributions are licensed under the CryptoSwift project license. + +--- + +Before submitting the pull request, please make sure you have tested your changes. + +--- + +For new files, please use the correct file header: + +``` +// +// CryptoSwift +// +// Copyright (C) Marcin Krzyżanowski +// 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. +// +``` diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift-TestHostApp/AppDelegate.swift b/Carthage/Checkouts/CryptoSwift/CryptoSwift-TestHostApp/AppDelegate.swift new file mode 100644 index 0000000000..104a9cc250 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift-TestHostApp/AppDelegate.swift @@ -0,0 +1,52 @@ +//// CryptoSwift +// +// Copyright (C) 2014-2018 Marcin Krzyżanowski +// 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. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift-TestHostApp/Info.plist b/Carthage/Checkouts/CryptoSwift/CryptoSwift-TestHostApp/Info.plist new file mode 100644 index 0000000000..76398107b0 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift-TestHostApp/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIRequiredDeviceCapabilities + + armv7 + + UIRequiresFullScreen + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.playground/Contents.swift b/Carthage/Checkouts/CryptoSwift/CryptoSwift.playground/Contents.swift new file mode 100644 index 0000000000..14573ba746 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.playground/Contents.swift @@ -0,0 +1,171 @@ +/*: + To whom may be concerned: I offer professional support to all my open source projects. + + Contact: [marcin@krzyzanowskim.com](http://krzyzanowskim.com) + */ +import CryptoSwift +import Foundation +/*: + # Data types conversinn + */ +let data = Data([0x01, 0x02, 0x03]) +let bytes = data.bytes +let bytesHex = Array(hex: "0x010203") +let hexString = bytesHex.toHexString() + +/*: + # Digest + */ +data.md5() +data.sha1() +data.sha224() +data.sha256() +data.sha384() +data.sha512() + +bytes.sha1() +"123".sha1() +Digest.sha1(bytes) + +//: Digest calculated incrementally +do { + var digest = MD5() + _ = try digest.update(withBytes: [0x31, 0x32]) + _ = try digest.update(withBytes: [0x33]) + let result = try digest.finish() + result.toBase64() +} catch {} + +/*: + # CRC + */ +bytes.crc16() +bytes.crc32() +bytes.crc32c() + +/*: + # HMAC + */ + +do { + let key: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 25, 26, 27, 28, 29, 30, 31, 32] + try Poly1305(key: key).authenticate(bytes) + try HMAC(key: key, variant: .sha256).authenticate(bytes) +} catch {} + +/*: + # PBKDF1, PBKDF2 + */ + +do { + let password: Array = Array("s33krit".utf8) + let salt: Array = Array("nacllcan".utf8) + + try PKCS5.PBKDF1(password: password, salt: salt, variant: .sha1, iterations: 4096).calculate() + + let value = try PKCS5.PBKDF2(password: password, salt: salt, iterations: 4096, variant: .sha256).calculate() + print(value) +} catch {} + +/*: + # Padding + */ +Padding.pkcs7.add(to: bytes, blockSize: AES.blockSize) + +/*: + # ChaCha20 + */ + +do { + let key: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32] + let iv: Array = [1, 2, 3, 4, 5, 6, 7, 8] + let message = Array(repeating: 7, count: 10) + + let encrypted = try ChaCha20(key: key, iv: iv).encrypt(message) + let decrypted = try ChaCha20(key: key, iv: iv).decrypt(encrypted) + print(decrypted) +} catch { + print(error) +} + +/*: + # AES + ### One-time shot. + Encrypt all data at once. + */ +do { + let aes = try AES(key: "passwordpassword", iv: "drowssapdrowssap") // aes128 + let ciphertext = try aes.encrypt(Array("Nullam quis risus eget urna mollis ornare vel eu leo.".utf8)) + print(ciphertext.toHexString()) +} catch { + print(error) +} + +/*: + ### Incremental encryption + + Instantiate Encryptor for AES encryption (or decryptor for decryption) and process input data partially. + */ +do { + var encryptor = try AES(key: "passwordpassword", iv: "drowssapdrowssap").makeEncryptor() + + var ciphertext = Array() + // aggregate partial results + ciphertext += try encryptor.update(withBytes: Array("Nullam quis risus ".utf8)) + ciphertext += try encryptor.update(withBytes: Array("eget urna mollis ".utf8)) + ciphertext += try encryptor.update(withBytes: Array("ornare vel eu leo.".utf8)) + // finish at the end + ciphertext += try encryptor.finish() + + print(ciphertext.toHexString()) +} catch { + print(error) +} + +/*: + ### Encrypt stream + */ +do { + // write until all is written + func writeTo(stream: OutputStream, bytes: Array) { + var writtenCount = 0 + while stream.hasSpaceAvailable && writtenCount < bytes.count { + writtenCount += stream.write(bytes, maxLength: bytes.count) + } + } + + let aes = try AES(key: "passwordpassword", iv: "drowssapdrowssap") + var encryptor = try! aes.makeEncryptor() + + // prepare streams + let data = Data( (0 ..< 100).map { $0 }) + let inputStream = InputStream(data: data) + let outputStream = OutputStream(toMemory: ()) + inputStream.open() + outputStream.open() + + var buffer = Array(repeating: 0, count: 2) + + // encrypt input stream data and write encrypted result to output stream + while inputStream.hasBytesAvailable { + let readCount = inputStream.read(&buffer, maxLength: buffer.count) + if readCount > 0 { + try encryptor.update(withBytes: buffer[0 ..< readCount]) { bytes in + writeTo(stream: outputStream, bytes: bytes) + } + } + } + + // finalize encryption + try encryptor.finish { bytes in + writeTo(stream: outputStream, bytes: bytes) + } + + // print result + if let ciphertext = outputStream.property(forKey: Stream.PropertyKey(rawValue: Stream.PropertyKey.dataWrittenToMemoryStreamKey.rawValue)) as? Data { + print("Encrypted stream data: \(ciphertext.toHexString())") + } + +} catch { + print(error) +} diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.playground/contents.xcplayground b/Carthage/Checkouts/CryptoSwift/CryptoSwift.playground/contents.xcplayground new file mode 100644 index 0000000000..3a493ef23d --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.podspec b/Carthage/Checkouts/CryptoSwift/CryptoSwift.podspec new file mode 100644 index 0000000000..6e7516b9be --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.podspec @@ -0,0 +1,20 @@ +Pod::Spec.new do |s| + s.name = "CryptoSwift" + s.version = "1.0.0" + s.source = { :git => "https://github.com/krzyzanowskim/CryptoSwift.git", :tag => "#{s.version}" } + s.summary = "Cryptography in Swift. SHA, MD5, CRC, PBKDF, Poly1305, HMAC, CMAC, HDKF, Scrypt, ChaCha20, Rabbit, Blowfish, AES." + s.description = "Cryptography functions and helpers for Swift implemented in Swift. SHA-1, SHA-2, SHA-3, MD5, PBKDF1, PBKDF2, Scrypt, CRC, Poly1305, HMAC, ChaCha20, Rabbit, Blowfish, AES" + s.homepage = "https://github.com/krzyzanowskim/CryptoSwift" + s.license = {:type => "Attribution", :file => "LICENSE"} + s.authors = {'Marcin Krzyżanowski' => 'marcin@krzyzanowskim.com'} + s.social_media_url = "https://twitter.com/krzyzanowskim" + s.cocoapods_version = '>= 1.4.0' + s.swift_version = "5.0" + s.ios.deployment_target = "8.0" + s.osx.deployment_target = "10.10" + s.watchos.deployment_target = "2.0" + s.tvos.deployment_target = "9.0" + s.source_files = "Sources/CryptoSwift/**/*.swift" + s.requires_arc = true + s.pod_target_xcconfig = { 'SWIFT_OPTIMIZATION_LEVEL' => '-O', 'SWIFT_COMPILATION_MODE' => 'wholemodule', 'SWIFT_DISABLE_SAFETY_CHECKS' => 'YES', 'SWIFT_ENFORCE_EXCLUSIVE_ACCESS' => 'debug-only', 'GCC_UNROLL_LOOPS' => 'YES'} +end diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/project.pbxproj b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..e4d4d6d9c8 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/project.pbxproj @@ -0,0 +1,1312 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + 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 */; }; + 75211F95207249D8004E41F8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75211F94207249D8004E41F8 /* AppDelegate.swift */; }; + 7523742D2083C61D0016D662 /* GCM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7523742C2083C61C0016D662 /* GCM.swift */; }; + 7529366A20683DFC00195874 /* AEADChaCha20Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7529366920683DFC00195874 /* AEADChaCha20Poly1305.swift */; }; + 752BED9D208C120D00FC4743 /* Blowfish+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52541EE8B6CA0048EB3B /* Blowfish+Foundation.swift */; }; + 752BED9E208C121000FC4743 /* Blowfish.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52491EE8B6CA0048EB3B /* Blowfish.swift */; }; + 752BED9F208C135700FC4743 /* AES+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52531EE8B6CA0048EB3B /* AES+Foundation.swift */; }; + 753674072175D012003E32A6 /* StreamDecryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753674062175D012003E32A6 /* StreamDecryptor.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 */; }; + 7564F0522072EAEB00CA5A96 /* PBKDFPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7576F6F6207290F8006688F8 /* PBKDFPerf.swift */; }; + 7564F0532072EAEB00CA5A96 /* ChaCha20TestsPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7576F6F020728EAB006688F8 /* ChaCha20TestsPerf.swift */; }; + 7564F0542072EAEB00CA5A96 /* RabbitTestsPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7576F6F220728F00006688F8 /* RabbitTestsPerf.swift */; }; + 7564F0552072EAEB00CA5A96 /* ExtensionsTestPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7576F6F420729069006688F8 /* ExtensionsTestPerf.swift */; }; + 7564F0562072EAEB00CA5A96 /* DigestTestsPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7576F6EB20726319006688F8 /* DigestTestsPerf.swift */; }; + 7564F0572072EAEB00CA5A96 /* TestsPerformance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7595C14C2072E48C00EA1A5F /* TestsPerformance.swift */; }; + 7564F0582072EAEB00CA5A96 /* AESTestsPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7576F6EE20726422006688F8 /* AESTestsPerf.swift */; }; + 7564F05A2072EAEB00CA5A96 /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 754BE45519693E190098E6F3 /* CryptoSwift.framework */; }; + 7564F0642072ED7000CA5A96 /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 754BE45519693E190098E6F3 /* CryptoSwift.framework */; }; + 7564F0652072ED7000CA5A96 /* CryptoSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 754BE45519693E190098E6F3 /* CryptoSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 756A64C62111083B00BE8805 /* StreamEncryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756A64C52111083B00BE8805 /* StreamEncryptor.swift */; }; + 7576F64D20725BD6006688F8 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7576F64C20725BD5006688F8 /* Default-568h@2x.png */; }; + 757DA2531A4ED0A4002BA3EF /* PaddingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757DA2521A4ED0A4002BA3EF /* PaddingTests.swift */; }; + 757DA2551A4ED408002BA3EF /* AESTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757DA2541A4ED408002BA3EF /* AESTests.swift */; }; + 757DA2591A4ED4D7002BA3EF /* ChaCha20Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757DA2581A4ED4D7002BA3EF /* ChaCha20Tests.swift */; }; + 758A94291A65C67400E46135 /* HMACTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758A94271A65C59200E46135 /* HMACTests.swift */; }; + 758F95AB2072E8E20080D664 /* Bridging.h in Headers */ = {isa = PBXBuildFile; fileRef = 758F95AA2072E8E10080D664 /* Bridging.h */; }; + 7594CCBC217A76DC0055C95D /* AESCCMTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755E0303217A756F00065FC6 /* AESCCMTests.swift */; }; + 7595C14D2072E48C00EA1A5F /* TestsPerformance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7595C14C2072E48C00EA1A5F /* TestsPerformance.swift */; }; + 7595C1582072E5B900EA1A5F /* DigestTestsPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7576F6EB20726319006688F8 /* DigestTestsPerf.swift */; }; + 7595C1592072E5B900EA1A5F /* AESTestsPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7576F6EE20726422006688F8 /* AESTestsPerf.swift */; }; + 7595C15A2072E5B900EA1A5F /* ChaCha20TestsPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7576F6F020728EAB006688F8 /* ChaCha20TestsPerf.swift */; }; + 7595C15B2072E5B900EA1A5F /* RabbitTestsPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7576F6F220728F00006688F8 /* RabbitTestsPerf.swift */; }; + 7595C15C2072E5B900EA1A5F /* ExtensionsTestPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7576F6F420729069006688F8 /* ExtensionsTestPerf.swift */; }; + 7595C15D2072E5B900EA1A5F /* PBKDFPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7576F6F6207290F8006688F8 /* PBKDFPerf.swift */; }; + 7595C1602072E64900EA1A5F /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 754BE45519693E190098E6F3 /* CryptoSwift.framework */; }; + 75B3ED77210F9DF7005D4ADA /* BlockDecryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75B3ED76210F9DF7005D4ADA /* BlockDecryptor.swift */; }; + 75B3ED79210FA016005D4ADA /* BlockEncryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75B3ED78210FA016005D4ADA /* BlockEncryptor.swift */; }; + 75B601EB197D6A6C0009B53D /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 754BE45519693E190098E6F3 /* CryptoSwift.framework */; }; + 75C2E76D1D55F097003D2BCA /* Access.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C2E76C1D55F097003D2BCA /* Access.swift */; }; + 75D7AF38208BFB1600D22BEB /* UInt128.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D7AF37208BFB1600D22BEB /* UInt128.swift */; }; + 75EC527B1EE8B73A0048EB3B /* CryptoSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 75EC527A1EE8B6CA0048EB3B /* CryptoSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 75EC527C1EE8B8130048EB3B /* AES.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52381EE8B6CA0048EB3B /* AES.swift */; }; + 75EC527D1EE8B8130048EB3B /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52391EE8B6CA0048EB3B /* Array+Extension.swift */; }; + 75EC527E1EE8B8130048EB3B /* Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC523A1EE8B6CA0048EB3B /* Authenticator.swift */; }; + 75EC527F1EE8B8130048EB3B /* BatchedCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC523B1EE8B6CA0048EB3B /* BatchedCollection.swift */; }; + 75EC52801EE8B8130048EB3B /* Bit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC523C1EE8B6CA0048EB3B /* Bit.swift */; }; + 75EC52811EE8B8130048EB3B /* BlockCipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC523D1EE8B6CA0048EB3B /* BlockCipher.swift */; }; + 75EC52821EE8B8170048EB3B /* BlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC523F1EE8B6CA0048EB3B /* BlockMode.swift */; }; + 75EC52831EE8B8170048EB3B /* BlockModeOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52401EE8B6CA0048EB3B /* BlockModeOptions.swift */; }; + 75EC52841EE8B8170048EB3B /* CipherModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52411EE8B6CA0048EB3B /* CipherModeWorker.swift */; }; + 75EC52851EE8B8170048EB3B /* CBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52421EE8B6CA0048EB3B /* CBC.swift */; }; + 75EC52861EE8B8170048EB3B /* CFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52431EE8B6CA0048EB3B /* CFB.swift */; }; + 75EC52871EE8B8170048EB3B /* CTR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52441EE8B6CA0048EB3B /* CTR.swift */; }; + 75EC52881EE8B8170048EB3B /* ECB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52451EE8B6CA0048EB3B /* ECB.swift */; }; + 75EC52891EE8B8170048EB3B /* OFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52461EE8B6CA0048EB3B /* OFB.swift */; }; + 75EC528A1EE8B8170048EB3B /* PCBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52471EE8B6CA0048EB3B /* PCBC.swift */; }; + 75EC528D1EE8B81A0048EB3B /* ChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC524A1EE8B6CA0048EB3B /* ChaCha20.swift */; }; + 75EC528E1EE8B81A0048EB3B /* Checksum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC524B1EE8B6CA0048EB3B /* Checksum.swift */; }; + 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 */; }; + 75EC52931EE8B81A0048EB3B /* Digest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52501EE8B6CA0048EB3B /* Digest.swift */; }; + 75EC52941EE8B81A0048EB3B /* DigestType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52511EE8B6CA0048EB3B /* DigestType.swift */; }; + 75EC52971EE8B8200048EB3B /* ChaCha20+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52551EE8B6CA0048EB3B /* ChaCha20+Foundation.swift */; }; + 75EC52981EE8B8200048EB3B /* Array+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52561EE8B6CA0048EB3B /* Array+Foundation.swift */; }; + 75EC52991EE8B8200048EB3B /* Data+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52571EE8B6CA0048EB3B /* Data+Extension.swift */; }; + 75EC529A1EE8B8200048EB3B /* HMAC+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52581EE8B6CA0048EB3B /* HMAC+Foundation.swift */; }; + 75EC529B1EE8B8200048EB3B /* Rabbit+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52591EE8B6CA0048EB3B /* Rabbit+Foundation.swift */; }; + 75EC529C1EE8B8200048EB3B /* String+FoundationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC525A1EE8B6CA0048EB3B /* String+FoundationExtension.swift */; }; + 75EC529D1EE8B8200048EB3B /* Utils+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC525B1EE8B6CA0048EB3B /* Utils+Foundation.swift */; }; + 75EC529E1EE8B8230048EB3B /* Generics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC525C1EE8B6CA0048EB3B /* Generics.swift */; }; + 75EC529F1EE8B8230048EB3B /* HMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC525D1EE8B6CA0048EB3B /* HMAC.swift */; }; + 75EC52A01EE8B8290048EB3B /* Int+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC525F1EE8B6CA0048EB3B /* Int+Extension.swift */; }; + 75EC52A21EE8B8290048EB3B /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52611EE8B6CA0048EB3B /* MD5.swift */; }; + 75EC52A31EE8B8290048EB3B /* NoPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52621EE8B6CA0048EB3B /* NoPadding.swift */; }; + 75EC52A41EE8B8290048EB3B /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52631EE8B6CA0048EB3B /* Operators.swift */; }; + 75EC52A51EE8B8290048EB3B /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52641EE8B6CA0048EB3B /* Padding.swift */; }; + 75EC52A61EE8B8390048EB3B /* PBKDF1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52661EE8B6CA0048EB3B /* PBKDF1.swift */; }; + 75EC52A71EE8B8390048EB3B /* PBKDF2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52671EE8B6CA0048EB3B /* PBKDF2.swift */; }; + 75EC52A81EE8B8390048EB3B /* PKCS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52681EE8B6CA0048EB3B /* PKCS5.swift */; }; + 75EC52A91EE8B83D0048EB3B /* PKCS7Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52691EE8B6CA0048EB3B /* PKCS7Padding.swift */; }; + 75EC52AA1EE8B83D0048EB3B /* Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC526A1EE8B6CA0048EB3B /* Poly1305.swift */; }; + 75EC52AB1EE8B83D0048EB3B /* Rabbit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC526B1EE8B6CA0048EB3B /* Rabbit.swift */; }; + 75EC52AC1EE8B83D0048EB3B /* Cryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC526C1EE8B6CA0048EB3B /* Cryptor.swift */; }; + 75EC52AD1EE8B83D0048EB3B /* RandomBytesSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC526D1EE8B6CA0048EB3B /* RandomBytesSequence.swift */; }; + 75EC52AE1EE8B83D0048EB3B /* SecureBytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC526E1EE8B6CA0048EB3B /* SecureBytes.swift */; }; + 75EC52AF1EE8B83D0048EB3B /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC526F1EE8B6CA0048EB3B /* SHA1.swift */; }; + 75EC52B01EE8B83D0048EB3B /* SHA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52701EE8B6CA0048EB3B /* SHA2.swift */; }; + 75EC52B11EE8B83D0048EB3B /* SHA3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52711EE8B6CA0048EB3B /* SHA3.swift */; }; + 75EC52B21EE8B83D0048EB3B /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52721EE8B6CA0048EB3B /* String+Extension.swift */; }; + 75EC52B31EE8B83D0048EB3B /* UInt16+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52731EE8B6CA0048EB3B /* UInt16+Extension.swift */; }; + 75EC52B41EE8B83D0048EB3B /* UInt32+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52741EE8B6CA0048EB3B /* UInt32+Extension.swift */; }; + 75EC52B51EE8B83D0048EB3B /* UInt64+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52751EE8B6CA0048EB3B /* UInt64+Extension.swift */; }; + 75EC52B61EE8B83D0048EB3B /* UInt8+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52761EE8B6CA0048EB3B /* UInt8+Extension.swift */; }; + 75EC52B71EE8B83D0048EB3B /* Updatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52771EE8B6CA0048EB3B /* Updatable.swift */; }; + 75EC52B81EE8B83D0048EB3B /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52781EE8B6CA0048EB3B /* Utils.swift */; }; + 75EC52B91EE8B83D0048EB3B /* ZeroPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC52791EE8B6CA0048EB3B /* ZeroPadding.swift */; }; + 75F4E434216C93EF00F09710 /* CCM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75F4E433216C93EF00F09710 /* CCM.swift */; }; + 75F4E436216C98DE00F09710 /* CBCMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75F4E435216C98DE00F09710 /* CBCMAC.swift */; }; + 81F279DD2181F58300449EDA /* Scrypt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81F279DC2181F58300449EDA /* Scrypt.swift */; }; + 81F279DF2181F5A000449EDA /* ScryptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81F279DE2181F5A000449EDA /* ScryptTests.swift */; }; + 81F279E12181F5C500449EDA /* ScryptTestsPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81F279E02181F5C500449EDA /* ScryptTestsPerf.swift */; }; + 81F279E22181F5C500449EDA /* ScryptTestsPerf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81F279E02181F5C500449EDA /* ScryptTestsPerf.swift */; }; + E3FD2D531D6B81CE00A9F35F /* Error+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3FD2D511D6B813C00A9F35F /* Error+Extension.swift */; }; + E6200E141FB9A7AE00258382 /* HKDF.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6200E131FB9A7AE00258382 /* HKDF.swift */; }; + E6200E171FB9B68C00258382 /* HKDFTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6200E151FB9B67C00258382 /* HKDFTests.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 7564F0502072EAEB00CA5A96 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 754BE44C19693E190098E6F3 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 754BE45419693E190098E6F3; + remoteInfo = CryptoSwift; + }; + 7564F0612072EB5D00CA5A96 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 754BE44C19693E190098E6F3 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 75211F91207249D8004E41F8; + remoteInfo = "CryptoSwift-TestHostApp"; + }; + 7564F0662072ED7000CA5A96 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 754BE44C19693E190098E6F3 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 754BE45419693E190098E6F3; + remoteInfo = CryptoSwift; + }; + 7595C15E2072E64000EA1A5F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 754BE44C19693E190098E6F3 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 754BE45419693E190098E6F3; + remoteInfo = CryptoSwift; + }; + 75B601E3197D69EB0009B53D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 754BE44C19693E190098E6F3 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 754BE45419693E190098E6F3; + remoteInfo = CryptoSwift; + }; + 75B601E5197D6A270009B53D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 754BE44C19693E190098E6F3 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 754BE45419693E190098E6F3; + remoteInfo = CryptoSwift; + }; + 75B601E7197D6A3A0009B53D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 754BE44C19693E190098E6F3 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 754BE45419693E190098E6F3; + remoteInfo = CryptoSwift; + }; + 75B601E9197D6A5C0009B53D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 754BE44C19693E190098E6F3 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 754BE45419693E190098E6F3; + remoteInfo = CryptoSwift; + }; + 75B601EC197D6B3D0009B53D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 754BE44C19693E190098E6F3 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 754BE45419693E190098E6F3; + remoteInfo = CryptoSwift; + }; + 75B6021C197D6CF10009B53D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 754BE44C19693E190098E6F3 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 754BE45419693E190098E6F3; + remoteInfo = CryptoSwift; + }; + 75B6021E197D6D070009B53D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 754BE44C19693E190098E6F3 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 754BE45419693E190098E6F3; + remoteInfo = CryptoSwift; + }; + 75F9482120BDDF9900956311 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 754BE44C19693E190098E6F3 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 75211F91207249D8004E41F8; + remoteInfo = "CryptoSwift-TestHostApp"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 7564F0682072ED7000CA5A96 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 7564F0652072ED7000CA5A96 /* CryptoSwift.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + 75B601E0197D69770009B53D /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 0EE73E70204D598100110E11 /* CMAC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CMAC.swift; sourceTree = ""; }; + 0EE73E72204D599C00110E11 /* CMACTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CMACTests.swift; sourceTree = ""; }; + 14156CE42011422400DDCFBC /* ChaCha20Poly1305Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChaCha20Poly1305Tests.swift; sourceTree = ""; }; + 1467460E2017BB3600DF04ED /* AEAD.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AEAD.swift; sourceTree = ""; }; + 674A736E1BF5D85B00866C5B /* RabbitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RabbitTests.swift; sourceTree = ""; }; + 750509981F6BEF2A00394A1B /* PKCS7.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PKCS7.swift; sourceTree = ""; }; + 750CC3EA1DC0CACE0096BE6E /* BlowfishTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlowfishTests.swift; sourceTree = ""; }; + 75100F8E19B0BC890005C5F5 /* Poly1305Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Poly1305Tests.swift; sourceTree = ""; }; + 751EE9771F93996100161FFC /* AES.Cryptors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AES.Cryptors.swift; sourceTree = ""; }; + 75211F92207249D8004E41F8 /* CryptoSwift-TestHostApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "CryptoSwift-TestHostApp.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 75211F94207249D8004E41F8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 75211FA0207249D8004E41F8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 75211FA520724A0F004E41F8 /* CryptoSwift-TestHostApp-Test.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "CryptoSwift-TestHostApp-Test.xcconfig"; sourceTree = ""; }; + 75211FA620724A0F004E41F8 /* Project-Test.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Project-Test.xcconfig"; sourceTree = ""; }; + 75211FA720724A0F004E41F8 /* Tests-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tests-Debug.xcconfig"; sourceTree = ""; }; + 75211FA820724A0F004E41F8 /* CryptoSwift-Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "CryptoSwift-Shared.xcconfig"; sourceTree = ""; }; + 75211FA920724A0F004E41F8 /* CryptoSwift-TestHostApp-Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "CryptoSwift-TestHostApp-Shared.xcconfig"; sourceTree = ""; }; + 75211FAA20724A0F004E41F8 /* Project-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Project-Release.xcconfig"; sourceTree = ""; }; + 75211FAB20724A0F004E41F8 /* CryptoSwift-TestHostApp-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "CryptoSwift-TestHostApp-Debug.xcconfig"; sourceTree = ""; }; + 75211FAC20724A0F004E41F8 /* CryptoSwift-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "CryptoSwift-Release.xcconfig"; sourceTree = ""; }; + 75211FAD20724A0F004E41F8 /* Tests-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tests-Release.xcconfig"; sourceTree = ""; }; + 75211FAE20724A10004E41F8 /* Tests-Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tests-Shared.xcconfig"; sourceTree = ""; }; + 75211FAF20724A10004E41F8 /* CryptoSwift-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "CryptoSwift-Debug.xcconfig"; sourceTree = ""; }; + 75211FB020724A10004E41F8 /* Project-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Project-Debug.xcconfig"; sourceTree = ""; }; + 75211FB120724A10004E41F8 /* Tests-Test.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tests-Test.xcconfig"; sourceTree = ""; }; + 75211FB220724A10004E41F8 /* Project-Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Project-Shared.xcconfig"; sourceTree = ""; }; + 75211FB320724A10004E41F8 /* CryptoSwift-TestHostApp-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "CryptoSwift-TestHostApp-Release.xcconfig"; sourceTree = ""; }; + 75211FB420724A10004E41F8 /* CryptoSwift-Test.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "CryptoSwift-Test.xcconfig"; sourceTree = ""; }; + 7523742C2083C61C0016D662 /* GCM.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GCM.swift; sourceTree = ""; }; + 7529366920683DFC00195874 /* AEADChaCha20Poly1305.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AEADChaCha20Poly1305.swift; sourceTree = ""; }; + 753674062175D012003E32A6 /* StreamDecryptor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StreamDecryptor.swift; sourceTree = ""; }; + 7536A93E207254A000F39140 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; + 753B33001DAB84D600D06422 /* RandomBytesSequenceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RandomBytesSequenceTests.swift; sourceTree = ""; }; + 754310432050111A003FB1DF /* CompactMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompactMap.swift; sourceTree = ""; }; + 75482EA31CB310B7001F66A5 /* PBKDF.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PBKDF.swift; sourceTree = ""; }; + 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; }; + 754BE46619693E190098E6F3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 754BE46719693E190098E6F3 /* DigestTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DigestTests.swift; sourceTree = ""; }; + 755D27BC1D06DE6400C41692 /* CryptoSwift.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = CryptoSwift.playground; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 755E0303217A756F00065FC6 /* AESCCMTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AESCCMTests.swift; sourceTree = ""; }; + 755FB1D9199E347D00475437 /* ExtensionsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtensionsTest.swift; sourceTree = ""; }; + 7564F0602072EAEB00CA5A96 /* TestsPerformance-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "TestsPerformance-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 756A64C52111083B00BE8805 /* StreamEncryptor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StreamEncryptor.swift; sourceTree = ""; }; + 756BFDCA1A82B87300B9D9A4 /* Bridging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bridging.h; sourceTree = ""; }; + 7576F64C20725BD5006688F8 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; + 7576F6EB20726319006688F8 /* DigestTestsPerf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DigestTestsPerf.swift; sourceTree = ""; }; + 7576F6EE20726422006688F8 /* AESTestsPerf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AESTestsPerf.swift; sourceTree = ""; }; + 7576F6F020728EAB006688F8 /* ChaCha20TestsPerf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChaCha20TestsPerf.swift; sourceTree = ""; }; + 7576F6F220728F00006688F8 /* RabbitTestsPerf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RabbitTestsPerf.swift; sourceTree = ""; }; + 7576F6F420729069006688F8 /* ExtensionsTestPerf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtensionsTestPerf.swift; sourceTree = ""; }; + 7576F6F6207290F8006688F8 /* PBKDFPerf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PBKDFPerf.swift; sourceTree = ""; }; + 757DA2521A4ED0A4002BA3EF /* PaddingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaddingTests.swift; sourceTree = ""; }; + 757DA2541A4ED408002BA3EF /* AESTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AESTests.swift; sourceTree = ""; }; + 757DA2581A4ED4D7002BA3EF /* ChaCha20Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChaCha20Tests.swift; sourceTree = ""; }; + 758A94271A65C59200E46135 /* HMACTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HMACTests.swift; sourceTree = ""; }; + 758F95AA2072E8E10080D664 /* Bridging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bridging.h; sourceTree = ""; }; + 7595C14A2072E48C00EA1A5F /* TestsPerformance-Mac.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "TestsPerformance-Mac.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 7595C14C2072E48C00EA1A5F /* TestsPerformance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestsPerformance.swift; sourceTree = ""; }; + 7595C14E2072E48C00EA1A5F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 75B3ED76210F9DF7005D4ADA /* BlockDecryptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockDecryptor.swift; sourceTree = ""; }; + 75B3ED78210FA016005D4ADA /* BlockEncryptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockEncryptor.swift; sourceTree = ""; }; + 75C2E76C1D55F097003D2BCA /* Access.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Access.swift; sourceTree = ""; }; + 75D7AF37208BFB1600D22BEB /* UInt128.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UInt128.swift; sourceTree = ""; }; + 75EC52381EE8B6CA0048EB3B /* AES.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AES.swift; sourceTree = ""; }; + 75EC52391EE8B6CA0048EB3B /* Array+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+Extension.swift"; sourceTree = ""; }; + 75EC523A1EE8B6CA0048EB3B /* Authenticator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Authenticator.swift; sourceTree = ""; }; + 75EC523B1EE8B6CA0048EB3B /* BatchedCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatchedCollection.swift; sourceTree = ""; }; + 75EC523C1EE8B6CA0048EB3B /* Bit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bit.swift; sourceTree = ""; }; + 75EC523D1EE8B6CA0048EB3B /* BlockCipher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockCipher.swift; sourceTree = ""; }; + 75EC523F1EE8B6CA0048EB3B /* BlockMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockMode.swift; sourceTree = ""; }; + 75EC52401EE8B6CA0048EB3B /* BlockModeOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockModeOptions.swift; sourceTree = ""; }; + 75EC52411EE8B6CA0048EB3B /* CipherModeWorker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CipherModeWorker.swift; sourceTree = ""; }; + 75EC52421EE8B6CA0048EB3B /* CBC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBC.swift; sourceTree = ""; }; + 75EC52431EE8B6CA0048EB3B /* CFB.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CFB.swift; sourceTree = ""; }; + 75EC52441EE8B6CA0048EB3B /* CTR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTR.swift; sourceTree = ""; }; + 75EC52451EE8B6CA0048EB3B /* ECB.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ECB.swift; sourceTree = ""; }; + 75EC52461EE8B6CA0048EB3B /* OFB.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OFB.swift; sourceTree = ""; }; + 75EC52471EE8B6CA0048EB3B /* PCBC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PCBC.swift; sourceTree = ""; }; + 75EC52491EE8B6CA0048EB3B /* Blowfish.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Blowfish.swift; sourceTree = ""; }; + 75EC524A1EE8B6CA0048EB3B /* ChaCha20.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChaCha20.swift; sourceTree = ""; }; + 75EC524B1EE8B6CA0048EB3B /* Checksum.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checksum.swift; sourceTree = ""; }; + 75EC524C1EE8B6CA0048EB3B /* Cipher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cipher.swift; sourceTree = ""; }; + 75EC524D1EE8B6CA0048EB3B /* Collection+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+Extension.swift"; sourceTree = ""; }; + 75EC524E1EE8B6CA0048EB3B /* Cryptors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cryptors.swift; sourceTree = ""; }; + 75EC52501EE8B6CA0048EB3B /* Digest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Digest.swift; sourceTree = ""; }; + 75EC52511EE8B6CA0048EB3B /* DigestType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigestType.swift; sourceTree = ""; }; + 75EC52531EE8B6CA0048EB3B /* AES+Foundation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AES+Foundation.swift"; sourceTree = ""; }; + 75EC52541EE8B6CA0048EB3B /* Blowfish+Foundation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Blowfish+Foundation.swift"; sourceTree = ""; }; + 75EC52551EE8B6CA0048EB3B /* ChaCha20+Foundation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ChaCha20+Foundation.swift"; sourceTree = ""; }; + 75EC52561EE8B6CA0048EB3B /* Array+Foundation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+Foundation.swift"; sourceTree = ""; }; + 75EC52571EE8B6CA0048EB3B /* Data+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+Extension.swift"; sourceTree = ""; }; + 75EC52581EE8B6CA0048EB3B /* HMAC+Foundation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HMAC+Foundation.swift"; sourceTree = ""; }; + 75EC52591EE8B6CA0048EB3B /* Rabbit+Foundation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Rabbit+Foundation.swift"; sourceTree = ""; }; + 75EC525A1EE8B6CA0048EB3B /* String+FoundationExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+FoundationExtension.swift"; sourceTree = ""; }; + 75EC525B1EE8B6CA0048EB3B /* Utils+Foundation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Utils+Foundation.swift"; sourceTree = ""; }; + 75EC525C1EE8B6CA0048EB3B /* Generics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Generics.swift; sourceTree = ""; }; + 75EC525D1EE8B6CA0048EB3B /* HMAC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMAC.swift; sourceTree = ""; }; + 75EC525F1EE8B6CA0048EB3B /* Int+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Int+Extension.swift"; sourceTree = ""; }; + 75EC52611EE8B6CA0048EB3B /* MD5.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MD5.swift; sourceTree = ""; }; + 75EC52621EE8B6CA0048EB3B /* NoPadding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoPadding.swift; sourceTree = ""; }; + 75EC52631EE8B6CA0048EB3B /* Operators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = ""; }; + 75EC52641EE8B6CA0048EB3B /* Padding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Padding.swift; sourceTree = ""; }; + 75EC52661EE8B6CA0048EB3B /* PBKDF1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PBKDF1.swift; sourceTree = ""; }; + 75EC52671EE8B6CA0048EB3B /* PBKDF2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PBKDF2.swift; sourceTree = ""; }; + 75EC52681EE8B6CA0048EB3B /* PKCS5.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PKCS5.swift; sourceTree = ""; }; + 75EC52691EE8B6CA0048EB3B /* PKCS7Padding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PKCS7Padding.swift; sourceTree = ""; }; + 75EC526A1EE8B6CA0048EB3B /* Poly1305.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Poly1305.swift; sourceTree = ""; }; + 75EC526B1EE8B6CA0048EB3B /* Rabbit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Rabbit.swift; sourceTree = ""; }; + 75EC526C1EE8B6CA0048EB3B /* Cryptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cryptor.swift; sourceTree = ""; }; + 75EC526D1EE8B6CA0048EB3B /* RandomBytesSequence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RandomBytesSequence.swift; sourceTree = ""; }; + 75EC526E1EE8B6CA0048EB3B /* SecureBytes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBytes.swift; sourceTree = ""; }; + 75EC526F1EE8B6CA0048EB3B /* SHA1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SHA1.swift; sourceTree = ""; }; + 75EC52701EE8B6CA0048EB3B /* SHA2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SHA2.swift; sourceTree = ""; }; + 75EC52711EE8B6CA0048EB3B /* SHA3.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SHA3.swift; sourceTree = ""; }; + 75EC52721EE8B6CA0048EB3B /* String+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extension.swift"; sourceTree = ""; }; + 75EC52731EE8B6CA0048EB3B /* UInt16+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt16+Extension.swift"; sourceTree = ""; }; + 75EC52741EE8B6CA0048EB3B /* UInt32+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt32+Extension.swift"; sourceTree = ""; }; + 75EC52751EE8B6CA0048EB3B /* UInt64+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt64+Extension.swift"; sourceTree = ""; }; + 75EC52761EE8B6CA0048EB3B /* UInt8+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt8+Extension.swift"; sourceTree = ""; }; + 75EC52771EE8B6CA0048EB3B /* Updatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Updatable.swift; sourceTree = ""; }; + 75EC52781EE8B6CA0048EB3B /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; + 75EC52791EE8B6CA0048EB3B /* ZeroPadding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZeroPadding.swift; sourceTree = ""; }; + 75EC527A1EE8B6CA0048EB3B /* CryptoSwift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CryptoSwift.h; sourceTree = ""; }; + 75EDCB811DAC4CA400D270E0 /* LinuxMain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LinuxMain.swift; path = Tests/LinuxMain.swift; sourceTree = SOURCE_ROOT; }; + 75F4E433216C93EF00F09710 /* CCM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CCM.swift; sourceTree = ""; }; + 75F4E435216C98DE00F09710 /* CBCMAC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBCMAC.swift; sourceTree = ""; }; + 75F4E437216C9B5D00F09710 /* CHANGELOG */ = {isa = PBXFileReference; lastKnownFileType = text; path = CHANGELOG; sourceTree = SOURCE_ROOT; }; + 75F4E438216C9B6900F09710 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = SOURCE_ROOT; }; + 81F279DC2181F58300449EDA /* Scrypt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Scrypt.swift; sourceTree = ""; }; + 81F279DE2181F5A000449EDA /* ScryptTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScryptTests.swift; sourceTree = ""; }; + 81F279E02181F5C500449EDA /* ScryptTestsPerf.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScryptTestsPerf.swift; sourceTree = ""; }; + E3FD2D511D6B813C00A9F35F /* Error+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Error+Extension.swift"; sourceTree = ""; }; + E6200E131FB9A7AE00258382 /* HKDF.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HKDF.swift; sourceTree = ""; }; + E6200E151FB9B67C00258382 /* HKDFTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HKDFTests.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 75211F8F207249D8004E41F8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7564F0642072ED7000CA5A96 /* CryptoSwift.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 754BE45119693E190098E6F3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 754BE45D19693E190098E6F3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 75B601EB197D6A6C0009B53D /* CryptoSwift.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7564F0592072EAEB00CA5A96 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7564F05A2072EAEB00CA5A96 /* CryptoSwift.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7595C1472072E48C00EA1A5F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7595C1602072E64900EA1A5F /* CryptoSwift.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 24B0BBA29D734E62809E53BC /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7536A93E207254A000F39140 /* UIKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 75211F93207249D8004E41F8 /* CryptoSwift-TestHostApp */ = { + isa = PBXGroup; + children = ( + 75211F94207249D8004E41F8 /* AppDelegate.swift */, + 75211FA0207249D8004E41F8 /* Info.plist */, + ); + path = "CryptoSwift-TestHostApp"; + sourceTree = ""; + }; + 7529366820683DFC00195874 /* AEAD */ = { + isa = PBXGroup; + children = ( + 1467460E2017BB3600DF04ED /* AEAD.swift */, + 7529366920683DFC00195874 /* AEADChaCha20Poly1305.swift */, + ); + path = AEAD; + sourceTree = ""; + }; + 754BE44B19693E190098E6F3 = { + isa = PBXGroup; + children = ( + 75843E9A2072457A0050583A /* config */, + 755D27BC1D06DE6400C41692 /* CryptoSwift.playground */, + 75EC52361EE8B6CA0048EB3B /* Sources */, + 754BE46419693E190098E6F3 /* Tests */, + 7595C14B2072E48C00EA1A5F /* TestsPerformance */, + 75211F93207249D8004E41F8 /* CryptoSwift-TestHostApp */, + 754BE45619693E190098E6F3 /* Products */, + 24B0BBA29D734E62809E53BC /* Frameworks */, + ); + sourceTree = ""; + }; + 754BE45619693E190098E6F3 /* Products */ = { + isa = PBXGroup; + children = ( + 754BE45519693E190098E6F3 /* CryptoSwift.framework */, + 754BE46019693E190098E6F3 /* Tests.xctest */, + 75211F92207249D8004E41F8 /* CryptoSwift-TestHostApp.app */, + 7595C14A2072E48C00EA1A5F /* TestsPerformance-Mac.xctest */, + 7564F0602072EAEB00CA5A96 /* TestsPerformance-iOS.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 754BE46419693E190098E6F3 /* Tests */ = { + isa = PBXGroup; + children = ( + 81F279DE2181F5A000449EDA /* ScryptTests.swift */, + 81F279E02181F5C500449EDA /* ScryptTestsPerf.swift */, + 14156CE42011422400DDCFBC /* ChaCha20Poly1305Tests.swift */, + E3FD2D511D6B813C00A9F35F /* Error+Extension.swift */, + 754BE46719693E190098E6F3 /* DigestTests.swift */, + 7576F6EB20726319006688F8 /* DigestTestsPerf.swift */, + 75100F8E19B0BC890005C5F5 /* Poly1305Tests.swift */, + 758A94271A65C59200E46135 /* HMACTests.swift */, + 0EE73E72204D599C00110E11 /* CMACTests.swift */, + E6200E151FB9B67C00258382 /* HKDFTests.swift */, + 757DA2541A4ED408002BA3EF /* AESTests.swift */, + 755E0303217A756F00065FC6 /* AESCCMTests.swift */, + 7576F6EE20726422006688F8 /* AESTestsPerf.swift */, + 750CC3EA1DC0CACE0096BE6E /* BlowfishTests.swift */, + 757DA2581A4ED4D7002BA3EF /* ChaCha20Tests.swift */, + 7576F6F020728EAB006688F8 /* ChaCha20TestsPerf.swift */, + 674A736E1BF5D85B00866C5B /* RabbitTests.swift */, + 7576F6F220728F00006688F8 /* RabbitTestsPerf.swift */, + 755FB1D9199E347D00475437 /* ExtensionsTest.swift */, + 7576F6F420729069006688F8 /* ExtensionsTestPerf.swift */, + 757DA2521A4ED0A4002BA3EF /* PaddingTests.swift */, + 75482EA31CB310B7001F66A5 /* PBKDF.swift */, + 7576F6F6207290F8006688F8 /* PBKDFPerf.swift */, + 753B33001DAB84D600D06422 /* RandomBytesSequenceTests.swift */, + 75C2E76C1D55F097003D2BCA /* Access.swift */, + 756BFDCA1A82B87300B9D9A4 /* Bridging.h */, + 754BE46519693E190098E6F3 /* Supporting Files */, + ); + name = Tests; + path = Tests/Tests; + sourceTree = ""; + }; + 754BE46519693E190098E6F3 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 75F4E438216C9B6900F09710 /* README.md */, + 75F4E437216C9B5D00F09710 /* CHANGELOG */, + 75EDCB811DAC4CA400D270E0 /* LinuxMain.swift */, + 7576F64C20725BD5006688F8 /* Default-568h@2x.png */, + 754BE46619693E190098E6F3 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 75843E9A2072457A0050583A /* config */ = { + isa = PBXGroup; + children = ( + 75211FAF20724A10004E41F8 /* CryptoSwift-Debug.xcconfig */, + 75211FAC20724A0F004E41F8 /* CryptoSwift-Release.xcconfig */, + 75211FA820724A0F004E41F8 /* CryptoSwift-Shared.xcconfig */, + 75211FB420724A10004E41F8 /* CryptoSwift-Test.xcconfig */, + 75211FAB20724A0F004E41F8 /* CryptoSwift-TestHostApp-Debug.xcconfig */, + 75211FB320724A10004E41F8 /* CryptoSwift-TestHostApp-Release.xcconfig */, + 75211FA520724A0F004E41F8 /* CryptoSwift-TestHostApp-Test.xcconfig */, + 75211FA920724A0F004E41F8 /* CryptoSwift-TestHostApp-Shared.xcconfig */, + 75211FB020724A10004E41F8 /* Project-Debug.xcconfig */, + 75211FAA20724A0F004E41F8 /* Project-Release.xcconfig */, + 75211FB220724A10004E41F8 /* Project-Shared.xcconfig */, + 75211FA620724A0F004E41F8 /* Project-Test.xcconfig */, + 75211FA720724A0F004E41F8 /* Tests-Debug.xcconfig */, + 75211FAD20724A0F004E41F8 /* Tests-Release.xcconfig */, + 75211FAE20724A10004E41F8 /* Tests-Shared.xcconfig */, + 75211FB120724A10004E41F8 /* Tests-Test.xcconfig */, + ); + path = config; + sourceTree = ""; + }; + 7595C14B2072E48C00EA1A5F /* TestsPerformance */ = { + isa = PBXGroup; + children = ( + 758F95AA2072E8E10080D664 /* Bridging.h */, + 7595C14C2072E48C00EA1A5F /* TestsPerformance.swift */, + 7595C14E2072E48C00EA1A5F /* Info.plist */, + ); + name = TestsPerformance; + path = Tests/TestsPerformance; + sourceTree = ""; + }; + 75EC52361EE8B6CA0048EB3B /* Sources */ = { + isa = PBXGroup; + children = ( + 75EC52371EE8B6CA0048EB3B /* CryptoSwift */, + 75EC527A1EE8B6CA0048EB3B /* CryptoSwift.h */, + ); + path = Sources; + sourceTree = ""; + }; + 75EC52371EE8B6CA0048EB3B /* CryptoSwift */ = { + isa = PBXGroup; + children = ( + 7529366820683DFC00195874 /* AEAD */, + 75EC52381EE8B6CA0048EB3B /* AES.swift */, + 751EE9771F93996100161FFC /* AES.Cryptors.swift */, + 75EC52391EE8B6CA0048EB3B /* Array+Extension.swift */, + 75EC523A1EE8B6CA0048EB3B /* Authenticator.swift */, + 75EC523B1EE8B6CA0048EB3B /* BatchedCollection.swift */, + 75EC523C1EE8B6CA0048EB3B /* Bit.swift */, + 75EC523D1EE8B6CA0048EB3B /* BlockCipher.swift */, + 75EC523E1EE8B6CA0048EB3B /* BlockMode */, + 75EC52491EE8B6CA0048EB3B /* Blowfish.swift */, + 75EC524A1EE8B6CA0048EB3B /* ChaCha20.swift */, + 75EC524B1EE8B6CA0048EB3B /* Checksum.swift */, + 75EC524C1EE8B6CA0048EB3B /* Cipher.swift */, + 0EE73E70204D598100110E11 /* CMAC.swift */, + 75F4E435216C98DE00F09710 /* CBCMAC.swift */, + 75EC524D1EE8B6CA0048EB3B /* Collection+Extension.swift */, + 75EC524E1EE8B6CA0048EB3B /* Cryptors.swift */, + 75EC52501EE8B6CA0048EB3B /* Digest.swift */, + 75EC52511EE8B6CA0048EB3B /* DigestType.swift */, + 75EC52521EE8B6CA0048EB3B /* Foundation */, + 75EC525C1EE8B6CA0048EB3B /* Generics.swift */, + E6200E131FB9A7AE00258382 /* HKDF.swift */, + 75EC525D1EE8B6CA0048EB3B /* HMAC.swift */, + 75EC52611EE8B6CA0048EB3B /* MD5.swift */, + 75EC52621EE8B6CA0048EB3B /* NoPadding.swift */, + 75EC52631EE8B6CA0048EB3B /* Operators.swift */, + 75EC52641EE8B6CA0048EB3B /* Padding.swift */, + 75EC52651EE8B6CA0048EB3B /* PKCS */, + 75EC526A1EE8B6CA0048EB3B /* Poly1305.swift */, + 75EC526B1EE8B6CA0048EB3B /* Rabbit.swift */, + 75EC526C1EE8B6CA0048EB3B /* Cryptor.swift */, + 75EC526D1EE8B6CA0048EB3B /* RandomBytesSequence.swift */, + 75EC526E1EE8B6CA0048EB3B /* SecureBytes.swift */, + 81F279DC2181F58300449EDA /* Scrypt.swift */, + 75EC526F1EE8B6CA0048EB3B /* SHA1.swift */, + 75EC52701EE8B6CA0048EB3B /* SHA2.swift */, + 75EC52711EE8B6CA0048EB3B /* SHA3.swift */, + 75EC52721EE8B6CA0048EB3B /* String+Extension.swift */, + 75EC525F1EE8B6CA0048EB3B /* Int+Extension.swift */, + 75EC52761EE8B6CA0048EB3B /* UInt8+Extension.swift */, + 75EC52731EE8B6CA0048EB3B /* UInt16+Extension.swift */, + 75EC52741EE8B6CA0048EB3B /* UInt32+Extension.swift */, + 75EC52751EE8B6CA0048EB3B /* UInt64+Extension.swift */, + 75D7AF37208BFB1600D22BEB /* UInt128.swift */, + 75EC52771EE8B6CA0048EB3B /* Updatable.swift */, + 75EC52781EE8B6CA0048EB3B /* Utils.swift */, + 75EC52791EE8B6CA0048EB3B /* ZeroPadding.swift */, + 754310432050111A003FB1DF /* CompactMap.swift */, + 75B3ED76210F9DF7005D4ADA /* BlockDecryptor.swift */, + 75B3ED78210FA016005D4ADA /* BlockEncryptor.swift */, + 753674062175D012003E32A6 /* StreamDecryptor.swift */, + 756A64C52111083B00BE8805 /* StreamEncryptor.swift */, + ); + path = CryptoSwift; + sourceTree = ""; + }; + 75EC523E1EE8B6CA0048EB3B /* BlockMode */ = { + isa = PBXGroup; + children = ( + 75EC523F1EE8B6CA0048EB3B /* BlockMode.swift */, + 75EC52401EE8B6CA0048EB3B /* BlockModeOptions.swift */, + 75EC52411EE8B6CA0048EB3B /* CipherModeWorker.swift */, + 75EC52421EE8B6CA0048EB3B /* CBC.swift */, + 75EC52431EE8B6CA0048EB3B /* CFB.swift */, + 75EC52441EE8B6CA0048EB3B /* CTR.swift */, + 7523742C2083C61C0016D662 /* GCM.swift */, + 75F4E433216C93EF00F09710 /* CCM.swift */, + 75EC52451EE8B6CA0048EB3B /* ECB.swift */, + 75EC52461EE8B6CA0048EB3B /* OFB.swift */, + 75EC52471EE8B6CA0048EB3B /* PCBC.swift */, + ); + path = BlockMode; + sourceTree = ""; + }; + 75EC52521EE8B6CA0048EB3B /* Foundation */ = { + isa = PBXGroup; + children = ( + 75EC52531EE8B6CA0048EB3B /* AES+Foundation.swift */, + 75EC52541EE8B6CA0048EB3B /* Blowfish+Foundation.swift */, + 75EC52551EE8B6CA0048EB3B /* ChaCha20+Foundation.swift */, + 75EC52561EE8B6CA0048EB3B /* Array+Foundation.swift */, + 75EC52571EE8B6CA0048EB3B /* Data+Extension.swift */, + 75EC52581EE8B6CA0048EB3B /* HMAC+Foundation.swift */, + 75EC52591EE8B6CA0048EB3B /* Rabbit+Foundation.swift */, + 75EC525A1EE8B6CA0048EB3B /* String+FoundationExtension.swift */, + 75EC525B1EE8B6CA0048EB3B /* Utils+Foundation.swift */, + ); + path = Foundation; + sourceTree = ""; + }; + 75EC52651EE8B6CA0048EB3B /* PKCS */ = { + isa = PBXGroup; + children = ( + 75EC52691EE8B6CA0048EB3B /* PKCS7Padding.swift */, + 75EC52661EE8B6CA0048EB3B /* PBKDF1.swift */, + 75EC52671EE8B6CA0048EB3B /* PBKDF2.swift */, + 75EC52681EE8B6CA0048EB3B /* PKCS5.swift */, + 750509981F6BEF2A00394A1B /* PKCS7.swift */, + ); + path = PKCS; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 754BE45219693E190098E6F3 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 758F95AB2072E8E20080D664 /* Bridging.h in Headers */, + 75EC527B1EE8B73A0048EB3B /* CryptoSwift.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 75211F91207249D8004E41F8 /* CryptoSwift-TestHostApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 75211FA4207249D8004E41F8 /* Build configuration list for PBXNativeTarget "CryptoSwift-TestHostApp" */; + buildPhases = ( + 75211F8E207249D8004E41F8 /* Sources */, + 75211F8F207249D8004E41F8 /* Frameworks */, + 75211F90207249D8004E41F8 /* Resources */, + 7564F0682072ED7000CA5A96 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 7564F0672072ED7000CA5A96 /* PBXTargetDependency */, + ); + name = "CryptoSwift-TestHostApp"; + productName = "CryptoSwift-TestHostApp"; + productReference = 75211F92207249D8004E41F8 /* CryptoSwift-TestHostApp.app */; + productType = "com.apple.product-type.application"; + }; + 754BE45419693E190098E6F3 /* CryptoSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = 754BE46B19693E190098E6F3 /* Build configuration list for PBXNativeTarget "CryptoSwift" */; + buildPhases = ( + 754BE45019693E190098E6F3 /* Sources */, + 754BE45119693E190098E6F3 /* Frameworks */, + 754BE45219693E190098E6F3 /* Headers */, + 754BE45319693E190098E6F3 /* Resources */, + 75B601E0197D69770009B53D /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CryptoSwift; + productName = CryptoSwift; + productReference = 754BE45519693E190098E6F3 /* CryptoSwift.framework */; + productType = "com.apple.product-type.framework"; + }; + 754BE45F19693E190098E6F3 /* Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 754BE46E19693E190098E6F3 /* Build configuration list for PBXNativeTarget "Tests" */; + buildPhases = ( + 754BE45C19693E190098E6F3 /* Sources */, + 754BE45D19693E190098E6F3 /* Frameworks */, + 754BE45E19693E190098E6F3 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 75B601E4197D69EB0009B53D /* PBXTargetDependency */, + 75B601E6197D6A270009B53D /* PBXTargetDependency */, + 75B601E8197D6A3A0009B53D /* PBXTargetDependency */, + 75B601EA197D6A5C0009B53D /* PBXTargetDependency */, + 75B601ED197D6B3D0009B53D /* PBXTargetDependency */, + 75B6021D197D6CF10009B53D /* PBXTargetDependency */, + 75B6021F197D6D070009B53D /* PBXTargetDependency */, + 75F9482220BDDF9900956311 /* PBXTargetDependency */, + ); + name = Tests; + productName = Tests; + productReference = 754BE46019693E190098E6F3 /* Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 7564F04E2072EAEB00CA5A96 /* TestsPerformance-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7564F05C2072EAEB00CA5A96 /* Build configuration list for PBXNativeTarget "TestsPerformance-iOS" */; + buildPhases = ( + 7564F0512072EAEB00CA5A96 /* Sources */, + 7564F0592072EAEB00CA5A96 /* Frameworks */, + 7564F05B2072EAEB00CA5A96 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 7564F04F2072EAEB00CA5A96 /* PBXTargetDependency */, + 7564F0622072EB5D00CA5A96 /* PBXTargetDependency */, + ); + name = "TestsPerformance-iOS"; + productName = TestsPerformance; + productReference = 7564F0602072EAEB00CA5A96 /* TestsPerformance-iOS.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 7595C1492072E48C00EA1A5F /* TestsPerformance-Mac */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7595C1522072E48C00EA1A5F /* Build configuration list for PBXNativeTarget "TestsPerformance-Mac" */; + buildPhases = ( + 7595C1462072E48C00EA1A5F /* Sources */, + 7595C1472072E48C00EA1A5F /* Frameworks */, + 7595C1482072E48C00EA1A5F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 7595C15F2072E64000EA1A5F /* PBXTargetDependency */, + ); + name = "TestsPerformance-Mac"; + productName = TestsPerformance; + productReference = 7595C14A2072E48C00EA1A5F /* TestsPerformance-Mac.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 754BE44C19693E190098E6F3 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0930; + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "Marcin Krzyzanowski"; + TargetAttributes = { + 75211F91207249D8004E41F8 = { + CreatedOnToolsVersion = 9.3; + LastSwiftMigration = 1020; + ProvisioningStyle = Automatic; + }; + 754BE45419693E190098E6F3 = { + CreatedOnToolsVersion = 6.0; + LastSwiftMigration = 1020; + ProvisioningStyle = Manual; + }; + 754BE45F19693E190098E6F3 = { + CreatedOnToolsVersion = 6.0; + LastSwiftMigration = 1020; + ProvisioningStyle = Manual; + }; + 7564F04E2072EAEB00CA5A96 = { + LastSwiftMigration = 1020; + ProvisioningStyle = Manual; + TestTargetID = 75211F91207249D8004E41F8; + }; + 7595C1492072E48C00EA1A5F = { + CreatedOnToolsVersion = 9.3; + LastSwiftMigration = 1020; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 754BE44F19693E190098E6F3 /* Build configuration list for PBXProject "CryptoSwift" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 754BE44B19693E190098E6F3; + productRefGroup = 754BE45619693E190098E6F3 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 754BE45419693E190098E6F3 /* CryptoSwift */, + 75211F91207249D8004E41F8 /* CryptoSwift-TestHostApp */, + 754BE45F19693E190098E6F3 /* Tests */, + 7595C1492072E48C00EA1A5F /* TestsPerformance-Mac */, + 7564F04E2072EAEB00CA5A96 /* TestsPerformance-iOS */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 75211F90207249D8004E41F8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7576F64D20725BD6006688F8 /* Default-568h@2x.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 754BE45319693E190098E6F3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 754BE45E19693E190098E6F3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7564F05B2072EAEB00CA5A96 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7595C1482072E48C00EA1A5F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 75211F8E207249D8004E41F8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 75211F95207249D8004E41F8 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 754BE45019693E190098E6F3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 75EC52861EE8B8170048EB3B /* CFB.swift in Sources */, + 75EC52901EE8B81A0048EB3B /* Collection+Extension.swift in Sources */, + 0EE73E71204D598100110E11 /* CMAC.swift in Sources */, + 7523742D2083C61D0016D662 /* GCM.swift in Sources */, + 75F4E436216C98DE00F09710 /* CBCMAC.swift in Sources */, + 752BED9F208C135700FC4743 /* AES+Foundation.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 /* Cryptor.swift in Sources */, + 75EC52821EE8B8170048EB3B /* BlockMode.swift in Sources */, + 75EC52AE1EE8B83D0048EB3B /* SecureBytes.swift in Sources */, + 75EC528F1EE8B81A0048EB3B /* Cipher.swift in Sources */, + 75B3ED79210FA016005D4ADA /* BlockEncryptor.swift in Sources */, + 75EC52A01EE8B8290048EB3B /* Int+Extension.swift in Sources */, + 75EC52B01EE8B83D0048EB3B /* SHA2.swift in Sources */, + 752BED9D208C120D00FC4743 /* Blowfish+Foundation.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 */, + 756A64C62111083B00BE8805 /* StreamEncryptor.swift in Sources */, + 75EC52A61EE8B8390048EB3B /* PBKDF1.swift in Sources */, + 75EC52B41EE8B83D0048EB3B /* UInt32+Extension.swift in Sources */, + 75EC52911EE8B81A0048EB3B /* Cryptors.swift in Sources */, + 75EC52881EE8B8170048EB3B /* ECB.swift in Sources */, + 75EC52841EE8B8170048EB3B /* CipherModeWorker.swift in Sources */, + 75EC52A41EE8B8290048EB3B /* Operators.swift in Sources */, + 75EC529A1EE8B8200048EB3B /* HMAC+Foundation.swift in Sources */, + 75EC52B21EE8B83D0048EB3B /* String+Extension.swift in Sources */, + 750509991F6BEF2A00394A1B /* PKCS7.swift in Sources */, + 75EC52B51EE8B83D0048EB3B /* UInt64+Extension.swift in Sources */, + 75EC52AF1EE8B83D0048EB3B /* SHA1.swift in Sources */, + 75EC52801EE8B8130048EB3B /* Bit.swift in Sources */, + 75EC52971EE8B8200048EB3B /* ChaCha20+Foundation.swift in Sources */, + 75F4E434216C93EF00F09710 /* CCM.swift in Sources */, + 75EC52871EE8B8170048EB3B /* CTR.swift in Sources */, + 75EC52A21EE8B8290048EB3B /* MD5.swift in Sources */, + 75EC527C1EE8B8130048EB3B /* AES.swift in Sources */, + 752BED9E208C121000FC4743 /* Blowfish.swift in Sources */, + 75EC52A91EE8B83D0048EB3B /* PKCS7Padding.swift in Sources */, + 75EC52A51EE8B8290048EB3B /* Padding.swift in Sources */, + 75EC527F1EE8B8130048EB3B /* BatchedCollection.swift in Sources */, + 75EC52991EE8B8200048EB3B /* Data+Extension.swift in Sources */, + 75EC52B61EE8B83D0048EB3B /* UInt8+Extension.swift in Sources */, + 75EC52891EE8B8170048EB3B /* OFB.swift in Sources */, + 75EC52831EE8B8170048EB3B /* BlockModeOptions.swift in Sources */, + 753674072175D012003E32A6 /* StreamDecryptor.swift in Sources */, + 751EE9781F93996100161FFC /* AES.Cryptors.swift in Sources */, + 75EC527D1EE8B8130048EB3B /* Array+Extension.swift in Sources */, + 75D7AF38208BFB1600D22BEB /* UInt128.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 */, + 75EC52A71EE8B8390048EB3B /* PBKDF2.swift in Sources */, + 75EC529D1EE8B8200048EB3B /* Utils+Foundation.swift in Sources */, + 75EC527E1EE8B8130048EB3B /* Authenticator.swift in Sources */, + 75EC52AB1EE8B83D0048EB3B /* Rabbit.swift in Sources */, + 75B3ED77210F9DF7005D4ADA /* BlockDecryptor.swift in Sources */, + 75EC529C1EE8B8200048EB3B /* String+FoundationExtension.swift in Sources */, + 75EC52B81EE8B83D0048EB3B /* Utils.swift in Sources */, + 75EC52981EE8B8200048EB3B /* Array+Foundation.swift in Sources */, + 75EC52B11EE8B83D0048EB3B /* SHA3.swift in Sources */, + 75EC52A31EE8B8290048EB3B /* NoPadding.swift in Sources */, + 81F279DD2181F58300449EDA /* Scrypt.swift in Sources */, + 75EC52931EE8B81A0048EB3B /* Digest.swift in Sources */, + 75EC52AD1EE8B83D0048EB3B /* RandomBytesSequence.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 754BE45C19693E190098E6F3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 75C2E76D1D55F097003D2BCA /* Access.swift in Sources */, + 75482EA41CB310B7001F66A5 /* PBKDF.swift in Sources */, + 758A94291A65C67400E46135 /* HMACTests.swift in Sources */, + 75100F8F19B0BC890005C5F5 /* Poly1305Tests.swift in Sources */, + E6200E171FB9B68C00258382 /* HKDFTests.swift in Sources */, + 753B33011DAB84D600D06422 /* RandomBytesSequenceTests.swift in Sources */, + 754BE46819693E190098E6F3 /* DigestTests.swift in Sources */, + E3FD2D531D6B81CE00A9F35F /* Error+Extension.swift in Sources */, + 757DA2591A4ED4D7002BA3EF /* ChaCha20Tests.swift in Sources */, + 755FB1DA199E347D00475437 /* ExtensionsTest.swift in Sources */, + 81F279DF2181F5A000449EDA /* ScryptTests.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 */, + 7594CCBC217A76DC0055C95D /* AESCCMTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7564F0512072EAEB00CA5A96 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7564F0522072EAEB00CA5A96 /* PBKDFPerf.swift in Sources */, + 7564F0532072EAEB00CA5A96 /* ChaCha20TestsPerf.swift in Sources */, + 7564F0542072EAEB00CA5A96 /* RabbitTestsPerf.swift in Sources */, + 7564F0552072EAEB00CA5A96 /* ExtensionsTestPerf.swift in Sources */, + 7564F0562072EAEB00CA5A96 /* DigestTestsPerf.swift in Sources */, + 81F279E22181F5C500449EDA /* ScryptTestsPerf.swift in Sources */, + 7564F0572072EAEB00CA5A96 /* TestsPerformance.swift in Sources */, + 7564F0582072EAEB00CA5A96 /* AESTestsPerf.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7595C1462072E48C00EA1A5F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7595C15D2072E5B900EA1A5F /* PBKDFPerf.swift in Sources */, + 7595C15A2072E5B900EA1A5F /* ChaCha20TestsPerf.swift in Sources */, + 7595C15B2072E5B900EA1A5F /* RabbitTestsPerf.swift in Sources */, + 7595C15C2072E5B900EA1A5F /* ExtensionsTestPerf.swift in Sources */, + 7595C1582072E5B900EA1A5F /* DigestTestsPerf.swift in Sources */, + 81F279E12181F5C500449EDA /* ScryptTestsPerf.swift in Sources */, + 7595C14D2072E48C00EA1A5F /* TestsPerformance.swift in Sources */, + 7595C1592072E5B900EA1A5F /* AESTestsPerf.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 7564F04F2072EAEB00CA5A96 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 754BE45419693E190098E6F3 /* CryptoSwift */; + targetProxy = 7564F0502072EAEB00CA5A96 /* PBXContainerItemProxy */; + }; + 7564F0622072EB5D00CA5A96 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 75211F91207249D8004E41F8 /* CryptoSwift-TestHostApp */; + targetProxy = 7564F0612072EB5D00CA5A96 /* PBXContainerItemProxy */; + }; + 7564F0672072ED7000CA5A96 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 754BE45419693E190098E6F3 /* CryptoSwift */; + targetProxy = 7564F0662072ED7000CA5A96 /* PBXContainerItemProxy */; + }; + 7595C15F2072E64000EA1A5F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 754BE45419693E190098E6F3 /* CryptoSwift */; + targetProxy = 7595C15E2072E64000EA1A5F /* PBXContainerItemProxy */; + }; + 75B601E4197D69EB0009B53D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 754BE45419693E190098E6F3 /* CryptoSwift */; + targetProxy = 75B601E3197D69EB0009B53D /* PBXContainerItemProxy */; + }; + 75B601E6197D6A270009B53D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 754BE45419693E190098E6F3 /* CryptoSwift */; + targetProxy = 75B601E5197D6A270009B53D /* PBXContainerItemProxy */; + }; + 75B601E8197D6A3A0009B53D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 754BE45419693E190098E6F3 /* CryptoSwift */; + targetProxy = 75B601E7197D6A3A0009B53D /* PBXContainerItemProxy */; + }; + 75B601EA197D6A5C0009B53D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 754BE45419693E190098E6F3 /* CryptoSwift */; + targetProxy = 75B601E9197D6A5C0009B53D /* PBXContainerItemProxy */; + }; + 75B601ED197D6B3D0009B53D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 754BE45419693E190098E6F3 /* CryptoSwift */; + targetProxy = 75B601EC197D6B3D0009B53D /* PBXContainerItemProxy */; + }; + 75B6021D197D6CF10009B53D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 754BE45419693E190098E6F3 /* CryptoSwift */; + targetProxy = 75B6021C197D6CF10009B53D /* PBXContainerItemProxy */; + }; + 75B6021F197D6D070009B53D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 754BE45419693E190098E6F3 /* CryptoSwift */; + targetProxy = 75B6021E197D6D070009B53D /* PBXContainerItemProxy */; + }; + 75F9482220BDDF9900956311 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 75211F91207249D8004E41F8 /* CryptoSwift-TestHostApp */; + targetProxy = 75F9482120BDDF9900956311 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 75211FA1207249D8004E41F8 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FAB20724A0F004E41F8 /* CryptoSwift-TestHostApp-Debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + }; + name = Debug; + }; + 75211FA2207249D8004E41F8 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FB320724A10004E41F8 /* CryptoSwift-TestHostApp-Release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + }; + name = Release; + }; + 75211FA3207249D8004E41F8 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FA520724A0F004E41F8 /* CryptoSwift-TestHostApp-Test.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + }; + name = Test; + }; + 754BE46919693E190098E6F3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FB020724A10004E41F8 /* Project-Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + 754BE46A19693E190098E6F3 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FAA20724A0F004E41F8 /* Project-Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + 754BE46C19693E190098E6F3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FAF20724A10004E41F8 /* CryptoSwift-Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + 754BE46D19693E190098E6F3 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FAC20724A0F004E41F8 /* CryptoSwift-Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + 754BE46F19693E190098E6F3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FA720724A0F004E41F8 /* Tests-Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + 754BE47019693E190098E6F3 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FAD20724A0F004E41F8 /* Tests-Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + 7564F05D2072EAEB00CA5A96 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FA720724A0F004E41F8 /* Tests-Debug.xcconfig */; + buildSettings = { + INFOPLIST_FILE = Tests/TestsPerformance/Info.plist; + SDKROOT = iphoneos; + SWIFT_OBJC_BRIDGING_HEADER = Tests/TestsPerformance/Bridging.h; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CryptoSwift-TestHostApp.app/CryptoSwift-TestHostApp"; + }; + name = Debug; + }; + 7564F05E2072EAEB00CA5A96 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FAD20724A0F004E41F8 /* Tests-Release.xcconfig */; + buildSettings = { + INFOPLIST_FILE = Tests/TestsPerformance/Info.plist; + SDKROOT = iphoneos; + SWIFT_OBJC_BRIDGING_HEADER = Tests/TestsPerformance/Bridging.h; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CryptoSwift-TestHostApp.app/CryptoSwift-TestHostApp"; + }; + name = Release; + }; + 7564F05F2072EAEB00CA5A96 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FB120724A10004E41F8 /* Tests-Test.xcconfig */; + buildSettings = { + INFOPLIST_FILE = Tests/TestsPerformance/Info.plist; + SDKROOT = iphoneos; + SWIFT_OBJC_BRIDGING_HEADER = Tests/TestsPerformance/Bridging.h; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CryptoSwift-TestHostApp.app/CryptoSwift-TestHostApp"; + }; + name = Test; + }; + 756B66AA1F6AAFDB00DEC41C /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FA620724A0F004E41F8 /* Project-Test.xcconfig */; + buildSettings = { + }; + name = Test; + }; + 756B66AB1F6AAFDB00DEC41C /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FB420724A10004E41F8 /* CryptoSwift-Test.xcconfig */; + buildSettings = { + }; + name = Test; + }; + 756B66AC1F6AAFDB00DEC41C /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FB120724A10004E41F8 /* Tests-Test.xcconfig */; + buildSettings = { + }; + name = Test; + }; + 7595C14F2072E48C00EA1A5F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FA720724A0F004E41F8 /* Tests-Debug.xcconfig */; + buildSettings = { + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = Tests/TestsPerformance/Info.plist; + SWIFT_OBJC_BRIDGING_HEADER = Tests/TestsPerformance/Bridging.h; + }; + name = Debug; + }; + 7595C1502072E48C00EA1A5F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FAD20724A0F004E41F8 /* Tests-Release.xcconfig */; + buildSettings = { + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = Tests/TestsPerformance/Info.plist; + SWIFT_OBJC_BRIDGING_HEADER = Tests/TestsPerformance/Bridging.h; + }; + name = Release; + }; + 7595C1512072E48C00EA1A5F /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75211FB120724A10004E41F8 /* Tests-Test.xcconfig */; + buildSettings = { + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = Tests/TestsPerformance/Info.plist; + SWIFT_OBJC_BRIDGING_HEADER = Tests/TestsPerformance/Bridging.h; + }; + name = Test; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 75211FA4207249D8004E41F8 /* Build configuration list for PBXNativeTarget "CryptoSwift-TestHostApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 75211FA1207249D8004E41F8 /* Debug */, + 75211FA2207249D8004E41F8 /* Release */, + 75211FA3207249D8004E41F8 /* Test */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 754BE44F19693E190098E6F3 /* Build configuration list for PBXProject "CryptoSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 754BE46919693E190098E6F3 /* Debug */, + 754BE46A19693E190098E6F3 /* Release */, + 756B66AA1F6AAFDB00DEC41C /* Test */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 754BE46B19693E190098E6F3 /* Build configuration list for PBXNativeTarget "CryptoSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 754BE46C19693E190098E6F3 /* Debug */, + 754BE46D19693E190098E6F3 /* Release */, + 756B66AB1F6AAFDB00DEC41C /* Test */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 754BE46E19693E190098E6F3 /* Build configuration list for PBXNativeTarget "Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 754BE46F19693E190098E6F3 /* Debug */, + 754BE47019693E190098E6F3 /* Release */, + 756B66AC1F6AAFDB00DEC41C /* Test */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7564F05C2072EAEB00CA5A96 /* Build configuration list for PBXNativeTarget "TestsPerformance-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7564F05D2072EAEB00CA5A96 /* Debug */, + 7564F05E2072EAEB00CA5A96 /* Release */, + 7564F05F2072EAEB00CA5A96 /* Test */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7595C1522072E48C00EA1A5F /* Build configuration list for PBXNativeTarget "TestsPerformance-Mac" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7595C14F2072E48C00EA1A5F /* Debug */, + 7595C1502072E48C00EA1A5F /* Release */, + 7595C1512072E48C00EA1A5F /* Test */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 754BE44C19693E190098E6F3 /* Project object */; +} diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..1c8e39a2fb --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000000..08de0be8d3 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/IDETemplateMacros.plist b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/IDETemplateMacros.plist new file mode 120000 index 0000000000..64dc763b4a --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/IDETemplateMacros.plist @@ -0,0 +1 @@ +../../IDETemplateMacros.plist \ No newline at end of file diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/2774350F-3E36-4FB9-835D-90E1E9EF7CE0.plist b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/2774350F-3E36-4FB9-835D-90E1E9EF7CE0.plist new file mode 100644 index 0000000000..12ae072952 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/2774350F-3E36-4FB9-835D-90E1E9EF7CE0.plist @@ -0,0 +1,22 @@ + + + + + classNames + + AESTests + + testAESEncryptPerformance() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 2.5786 + baselineIntegrationDisplayName + Local Baseline + + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/7797B693-C86A-4026-B2CE-05813EFA26F4.plist b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/7797B693-C86A-4026-B2CE-05813EFA26F4.plist new file mode 100644 index 0000000000..898829c71a --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/7797B693-C86A-4026-B2CE-05813EFA26F4.plist @@ -0,0 +1,22 @@ + + + + + classNames + + AESTests + + testAESEncryptPerformance() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 3.093 + baselineIntegrationDisplayName + Local Baseline + + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/85434D17-7706-4DE9-AFA7-B1DD0BD9FA39.plist b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/85434D17-7706-4DE9-AFA7-B1DD0BD9FA39.plist new file mode 100644 index 0000000000..6e35bbd2c1 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/85434D17-7706-4DE9-AFA7-B1DD0BD9FA39.plist @@ -0,0 +1,68 @@ + + + + + classNames + + AESTests + + testAESPerformance() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.62 + baselineIntegrationDisplayName + Local Baseline + + + testAES_decrypt_performance() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.571 + baselineIntegrationDisplayName + Local Baseline + + + testAES_encrypt_performance() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.535 + baselineIntegrationDisplayName + Local Baseline + + + + ChaCha20Tests + + testChaCha20Performance() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.176 + baselineIntegrationDisplayName + Local Baseline + + + + CryptoSwiftTests + + testMD5PerformanceSwift() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.087 + baselineIntegrationDisplayName + Local Baseline + + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/9396A4FE-F8F7-4542-8F75-DE77E1FEBEB9.plist b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/9396A4FE-F8F7-4542-8F75-DE77E1FEBEB9.plist new file mode 100644 index 0000000000..e7ed34f90f --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/9396A4FE-F8F7-4542-8F75-DE77E1FEBEB9.plist @@ -0,0 +1,22 @@ + + + + + classNames + + ChaCha20Tests + + testChaCha20Performance() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.15 + baselineIntegrationDisplayName + Local Baseline + + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/BD46E9D4-C65B-4C11-9BB5-B8B05CCE976F.plist b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/BD46E9D4-C65B-4C11-9BB5-B8B05CCE976F.plist new file mode 100644 index 0000000000..56b58c308c --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/BD46E9D4-C65B-4C11-9BB5-B8B05CCE976F.plist @@ -0,0 +1,22 @@ + + + + + classNames + + AESTests + + testAESEncryptPerformance() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.23441 + baselineIntegrationDisplayName + Local Baseline + + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/C6E1ABC4-5FB9-4A9E-8171-64B34C8D865C.plist b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/C6E1ABC4-5FB9-4A9E-8171-64B34C8D865C.plist new file mode 100644 index 0000000000..7884170c38 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/C6E1ABC4-5FB9-4A9E-8171-64B34C8D865C.plist @@ -0,0 +1,22 @@ + + + + + classNames + + AESTests + + testAESPerformance() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 14.71 + baselineIntegrationDisplayName + Local Baseline + + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/Info.plist b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/Info.plist new file mode 100644 index 0000000000..9f04e8632e --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/Info.plist @@ -0,0 +1,71 @@ + + + + + runDestinationsByUUID + + 85434D17-7706-4DE9-AFA7-B1DD0BD9FA39 + + localComputer + + busSpeedInMHz + 100 + cpuCount + 1 + cpuKind + Intel Core i7 + cpuSpeedInMHz + 2200 + logicalCPUCoresPerPackage + 4 + modelCode + MacBookAir7,2 + physicalCPUCoresPerPackage + 2 + platformIdentifier + com.apple.platform.macosx + + targetArchitecture + x86_64 + targetDevice + + modelCode + iPhone8,1 + platformIdentifier + com.apple.platform.iphonesimulator + + + 9396A4FE-F8F7-4542-8F75-DE77E1FEBEB9 + + localComputer + + busSpeedInMHz + 100 + cpuCount + 1 + cpuKind + Intel Core i7 + cpuSpeedInMHz + 1700 + logicalCPUCoresPerPackage + 4 + modelCode + MacBookAir6,2 + physicalCPUCoresPerPackage + 2 + platformIdentifier + com.apple.platform.macosx + + targetArchitecture + x86_64 + targetDevice + + modelCode + iPhone7,2 + platformIdentifier + com.apple.platform.iphonesimulator + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/CryptoSwift-TestHostApp.xcscheme b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/CryptoSwift-TestHostApp.xcscheme new file mode 100644 index 0000000000..8c98498764 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/CryptoSwift-TestHostApp.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/CryptoSwift.xcscheme b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/CryptoSwift.xcscheme new file mode 100644 index 0000000000..f469b3cb2a --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/CryptoSwift.xcscheme @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme new file mode 100644 index 0000000000..b254148446 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/TestsPerformance-Mac.xcscheme b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/TestsPerformance-Mac.xcscheme new file mode 100644 index 0000000000..928e8ff58f --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/TestsPerformance-Mac.xcscheme @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/TestsPerformance-iOS.xcscheme b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/TestsPerformance-iOS.xcscheme new file mode 100644 index 0000000000..b3fa9179a5 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcodeproj/xcshareddata/xcschemes/TestsPerformance-iOS.xcscheme @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..c55e7e59f9 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcworkspace/xcshareddata/IDETemplateMacros.plist b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcworkspace/xcshareddata/IDETemplateMacros.plist new file mode 120000 index 0000000000..64dc763b4a --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcworkspace/xcshareddata/IDETemplateMacros.plist @@ -0,0 +1 @@ +../../IDETemplateMacros.plist \ No newline at end of file diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000000..08de0be8d3 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/CryptoSwift.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded + + + diff --git a/Carthage/Checkouts/CryptoSwift/IDETemplateMacros.plist b/Carthage/Checkouts/CryptoSwift/IDETemplateMacros.plist new file mode 100644 index 0000000000..e42562a486 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/IDETemplateMacros.plist @@ -0,0 +1,20 @@ + + + + + FILEHEADER + // 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. +// + + diff --git a/Carthage/Checkouts/CryptoSwift/LICENSE b/Carthage/Checkouts/CryptoSwift/LICENSE new file mode 100644 index 0000000000..b70d6de9a7 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/LICENSE @@ -0,0 +1,11 @@ +Copyright (C) 2014-2017 Marcin Krzyżanowski +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. +- Redistributions of any form whatsoever must retain the following acknowledgment: 'This product includes software developed by the "Marcin Krzyzanowski" (http://krzyzanowskim.com/).' \ No newline at end of file diff --git a/Carthage/Checkouts/CryptoSwift/Package.swift b/Carthage/Checkouts/CryptoSwift/Package.swift new file mode 100644 index 0000000000..c94bfec0e3 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Package.swift @@ -0,0 +1,16 @@ +// swift-tools-version:4.2 + +import PackageDescription + +let package = Package( + name: "CryptoSwift", + products: [ + .library( + name: "CryptoSwift", + targets: ["CryptoSwift"]) + ], + targets: [ + .target(name: "CryptoSwift"), + .testTarget(name: "Tests", dependencies: ["CryptoSwift"]), + .testTarget(name: "TestsPerformance", dependencies: ["CryptoSwift"]), + ]) diff --git a/Carthage/Checkouts/CryptoSwift/README.md b/Carthage/Checkouts/CryptoSwift/README.md new file mode 100644 index 0000000000..a239407d7a --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/README.md @@ -0,0 +1,527 @@ +[![Platform](https://img.shields.io/badge/Platforms-iOS%20%7C%20Android%20%7CmacOS%20%7C%20watchOS%20%7C%20tvOS%20%7C%20Linux-4E4E4E.svg?colorA=28a745)](#installation) + +[![Swift support](https://img.shields.io/badge/Swift-3.1%20%7C%203.2%20%7C%204.0%20%7C%204.1%20%7C%204.2%20%7C%205.0-lightgrey.svg?colorA=28a745&colorB=4E4E4E)](#swift-versions-support) +[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/CryptoSwift.svg?style=flat&label=CocoaPods&colorA=28a745&&colorB=4E4E4E)](https://cocoapods.org/pods/CryptoSwift) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-brightgreen.svg?style=flat&colorA=28a745&&colorB=4E4E4E)](https://github.com/Carthage/Carthage) +[![Swift Package Manager compatible](https://img.shields.io/badge/SPM-compatible-brightgreen.svg?style=flat&colorA=28a745&&colorB=4E4E4E)](https://github.com/apple/swift-package-manager) + +[![Twitter](https://img.shields.io/badge/Twitter-@krzyzanowskim-blue.svg?style=flat)](http://twitter.com/krzyzanowskim) + +# CryptoSwift + +Crypto related functions and helpers for [Swift](https://swift.org) implemented in Swift. ([#PureSwift](https://twitter.com/hashtag/pureswift)) + +**Note**: The `master` branch follows the latest currently released **version of Swift**. If you need an earlier version for an older version of Swift, you can specify its version in your Podfile or use the code on the branch for that version. Older branches are unsupported. Check [versions](#swift-versions-support) for details. + +--- + +If you find the project useful, please [support authors](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=92Z6U3LBHF9J4) to keep it alive. + +--- + +[Requirements](#requirements) +| [Features](#features) +| [Contribution](#contribution) +| [Installation](#installation) +| [Swift versions](#swift-versions-support) +| [How-to](#how-to) +| [Author](#author) +| [License](#license) +| [Changelog](#changelog) + +## Requirements +Good mood + +## Features + +- Easy to use +- Convenient extensions for String and Data +- Support for incremental updates (stream, ...) +- iOS, Android, macOS, AppleTV, watchOS, Linux support + +#### Hash (Digest) + [MD5](http://tools.ietf.org/html/rfc1321) +| [SHA1](http://tools.ietf.org/html/rfc3174) +| [SHA224](http://tools.ietf.org/html/rfc6234) +| [SHA256](http://tools.ietf.org/html/rfc6234) +| [SHA384](http://tools.ietf.org/html/rfc6234) +| [SHA512](http://tools.ietf.org/html/rfc6234) +| [SHA3](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) + +#### Cyclic Redundancy Check (CRC) + [CRC32](http://en.wikipedia.org/wiki/Cyclic_redundancy_check) +| [CRC32C](http://en.wikipedia.org/wiki/Cyclic_redundancy_check) +| [CRC16](http://en.wikipedia.org/wiki/Cyclic_redundancy_check) + +#### Cipher + [AES-128, AES-192, AES-256](http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf) +| [ChaCha20](http://cr.yp.to/chacha/chacha-20080128.pdf) +| [Rabbit](https://tools.ietf.org/html/rfc4503) +| [Blowfish](https://www.schneier.com/academic/blowfish/) + +#### Message authenticators + [Poly1305](http://cr.yp.to/mac/poly1305-20050329.pdf) +| [HMAC (MD5, SHA1, SHA256)](https://www.ietf.org/rfc/rfc2104.txt) +| [CMAC](https://tools.ietf.org/html/rfc4493) +| [CBC-MAC](https://en.wikipedia.org/wiki/CBC-MAC) + +#### Cipher mode of operation +- Electronic codebook ([ECB](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_.28ECB.29)) +- Cipher-block chaining ([CBC](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29)) +- Propagating Cipher Block Chaining ([PCBC](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Propagating_Cipher_Block_Chaining_.28PCBC.29)) +- Cipher feedback ([CFB](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_feedback_.28CFB.29)) +- Output Feedback ([OFB](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Output_Feedback_.28OFB.29)) +- Counter Mode ([CTR](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29)) +- Galois/Counter Mode ([GCM](https://csrc.nist.gov/publications/detail/sp/800-38d/final)) +- Counter with Cipher Block Chaining-Message Authentication Code ([CCM](https://csrc.nist.gov/publications/detail/sp/800-38c/final)) + +#### Password-Based Key Derivation Function +- [PBKDF1](http://tools.ietf.org/html/rfc2898#section-5.1) (Password-Based Key Derivation Function 1) +- [PBKDF2](http://tools.ietf.org/html/rfc2898#section-5.2) (Password-Based Key Derivation Function 2) +- [HKDF](https://tools.ietf.org/html/rfc5869) (HMAC-based Extract-and-Expand Key Derivation Function) +- [Scrypt](https://tools.ietf.org/html/rfc7914) (The scrypt Password-Based Key Derivation Function) + +#### Data padding + PKCS#5 +| [PKCS#7](http://tools.ietf.org/html/rfc5652#section-6.3) +| [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). + +## How do I get involved? + +You want to help, great! Go ahead and fork our repo, make your changes and send us a pull request. + +## Contribution + +Check out [CONTRIBUTING.md](CONTRIBUTING.md) for more information on how to help with CryptoSwift. + +- If you found a bug, [open an issue](https://github.com/krzyzanowskim/CryptoSwift/issues). +- If you have a feature request, [open an issue](https://github.com/krzyzanowskim/CryptoSwift/issues). + +## Installation + +To install CryptoSwift, add it as a submodule to your project (on the top level project directory): + + git submodule add https://github.com/krzyzanowskim/CryptoSwift.git + +It is recommended to enable [Whole-Module Optimization](https://swift.org/blog/whole-module-optimizations/) to gain better performance. Non-optimized build results in significantly worse performance. + +#### Embedded Framework + +Embedded frameworks require a minimum deployment target of iOS 8 or OS X Mavericks (10.9). Drag the `CryptoSwift.xcodeproj` file into your Xcode project, and add appropriate framework as a dependency to your target. Now select your App and choose the General tab for the app target. Find *Embedded Binaries* and press "+", then select `CryptoSwift.framework` (iOS, OS X, watchOS or tvOS) + +![](https://cloud.githubusercontent.com/assets/758033/10834511/25a26852-7e9a-11e5-8c01-6cc8f1838459.png) + +Sometimes "embedded framework" option is not available. In that case, you have to add new build phase for the target + +![](https://cloud.githubusercontent.com/assets/758033/18415615/d5edabb0-77f8-11e6-8c94-f41d9fc2b8cb.png) + +##### iOS, macOS, watchOS, tvOS + +In the project, you'll find [single scheme](http://promisekit.org/news/2016/08/Multiplatform-Single-Scheme-Xcode-Projects/) for all platforms: +- CryptoSwift + +#### Swift versions support + +- Swift 1.2: branch [swift12](https://github.com/krzyzanowskim/CryptoSwift/tree/swift12) version <= 0.0.13 +- Swift 2.1: branch [swift21](https://github.com/krzyzanowskim/CryptoSwift/tree/swift21) version <= 0.2.3 +- Swift 2.2, 2.3: branch [swift2](https://github.com/krzyzanowskim/CryptoSwift/tree/swift2) version <= 0.5.2 +- Swift 3.1, branch [swift3](https://github.com/krzyzanowskim/CryptoSwift/tree/swift3) version <= 0.6.9 +- Swift 3.2, branch [swift32](https://github.com/krzyzanowskim/CryptoSwift/tree/swift32) version = 0.7.0 +- Swift 4.0, branch [swift4](https://github.com/krzyzanowskim/CryptoSwift/tree/swift4) version <= 0.12.0 +- Swift 4.2, branch [swift42](https://github.com/krzyzanowskim/CryptoSwift/tree/swift42) version <= 0.15.0 +- Swift 5.0, branch [master](https://github.com/krzyzanowskim/CryptoSwift/tree/master) + +#### CocoaPods + +You can use [CocoaPods](http://cocoapods.org/?q=cryptoSwift). + +```ruby +platform :ios, '10.0' +use_frameworks! + +target 'MyApp' do + pod 'CryptoSwift' +end +``` + +or for newest version from specified branch of code: + +```ruby +pod 'CryptoSwift', :git => "https://github.com/krzyzanowskim/CryptoSwift", :branch => "master" +``` + +Bear in mind that CocoaPods will build CryptoSwift without [Whole-Module Optimization](https://swift.org/blog/whole-module-optimizations/) that may impact performance. You can change it manually after installation, or use [cocoapods-wholemodule](https://github.com/jedlewison/cocoapods-wholemodule) plugin. + +#### Carthage +You can use [Carthage](https://github.com/Carthage/Carthage). +Specify in Cartfile: + +```ruby +github "krzyzanowskim/CryptoSwift" +``` + +Run `carthage` to build the framework and drag the built CryptoSwift.framework into your Xcode project. Follow [build instructions](https://github.com/Carthage/Carthage#getting-started). [Common issues](https://github.com/krzyzanowskim/CryptoSwift/issues/492#issuecomment-330822874). + +#### Swift Package Manager + +You can use [Swift Package Manager](https://swift.org/package-manager/) and specify dependency in `Package.swift` by adding this: + +```swift +dependencies: [ + .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .upToNextMinor(from: "1.0.0")) +] +``` + +or more strict + +```swift +dependencies: [ + .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .exact("1.0.0")) +] +``` + +See: [Package.swift - manual](http://blog.krzyzanowskim.com/2016/08/09/package-swift-manual/) + +--- + +## How-to + +* [Basics (data types, conversion, ...)](#basics) +* [Digest (MD5, SHA...)](#calculate-digest) +* [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) +* [ChaCha20](#chacha20) +* [Rabbit](#rabbit) +* [Blowfish](#blowfish) +* [AES - Advanced Encryption Standard](#aes) +* [AES-GCM](#aes-gcm) +* [Authenticated Encryption with Associated Data (AEAD)](#aead) + +also check [Playground](/CryptoSwift.playground/Contents.swift) + +##### Basics + +```swift +import CryptoSwift +``` + +CryptoSwift uses array of bytes aka `Array` as a base type for all operations. Every data may be converted to a stream of bytes. You will find convenience functions that accept `String` or `Data`, and it will be internally converted to the array of bytes. + +##### Data types conversion + +For your convenience, **CryptoSwift** provides two functions to easily convert an array of bytes to `Data` or `Data` to an array of bytes: + +Data from bytes: + +```swift +let data = Data( [0x01, 0x02, 0x03]) +``` + +`Data` to `Array` + +```swift +let bytes = data.bytes // [1,2,3] +``` + +[Hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) encoding: + +```swift +let bytes = Array(hex: "0x010203") // [1,2,3] +let hex = bytes.toHexString() // "010203" +``` + +Build bytes out of `String` +```swift +let bytes: Array = "cipherkey".bytes // Array("cipherkey".utf8) +``` + +Also... check out helpers that work with **Base64** encoded data: +```swift +"aPf/i9th9iX+vf49eR7PYk2q7S5xmm3jkRLejgzHNJs=".decryptBase64ToString(cipher) +"aPf/i9th9iX+vf49eR7PYk2q7S5xmm3jkRLejgzHNJs=".decryptBase64(cipher) +bytes.toBase64() +``` + +##### Calculate Digest + +Hashing a data or array of bytes (aka `Array`) +```swift +/* Hash struct usage */ +let bytes:Array = [0x01, 0x02, 0x03] +let digest = input.md5() +let digest = Digest.md5(bytes) +``` + +```swift +let data = Data( [0x01, 0x02, 0x03]) + +let hash = data.md5() +let hash = data.sha1() +let hash = data.sha224() +let hash = data.sha256() +let hash = data.sha384() +let hash = data.sha512() +``` +```swift +do { + var digest = MD5() + let partial1 = try digest.update(withBytes: [0x31, 0x32]) + let partial2 = try digest.update(withBytes: [0x33]) + let result = try digest.finish() +} catch { } +``` + +Hashing a String and printing result + +```swift +let hash = "123".md5() // "123".bytes.md5() +``` + +##### Calculate CRC + +```swift +bytes.crc16() +data.crc16() + +bytes.crc32() +data.crc32() +``` + +##### Message authenticators + +```swift +// Calculate Message Authentication Code (MAC) for message +let key:Array = [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 + +```swift +let password: Array = Array("s33krit".utf8) +let salt: Array = Array("nacllcan".utf8) + +let key = try PKCS5.PBKDF2(password: password, salt: salt, iterations: 4096, variant: .sha256).calculate() +``` + +```swift +let password: Array = Array("s33krit".utf8) +let salt: Array = Array("nacllcan".utf8) +// Scrypt implementation does not implement work parallelization, so `p` parameter will +// increase the work time even in multicore systems +let key = try Scrypt(password: password, salt: salt, dkLen: 64, N: 16384, r: 8, p: 1).calculate() +``` + +##### HMAC-based Key Derivation Function + +```swift +let password: Array = Array("s33krit".utf8) +let salt: Array = Array("nacllcan".utf8) + +let key = try HKDF(password: password, salt: salt, variant: .sha256).calculate() +``` + + +##### Data Padding + +Some content-encryption algorithms assume the input length is a multiple of `k` octets, where `k` is greater than one. For such algorithms, the input shall be padded. + +```swift +Padding.pkcs7.add(to: bytes, blockSize: AES.blockSize) +``` + +#### Working with Ciphers +##### ChaCha20 + +```swift +let encrypted = try ChaCha20(key: key, iv: iv).encrypt(message) +let decrypted = try ChaCha20(key: key, iv: iv).decrypt(encrypted) +``` + +##### Rabbit + +```swift +let encrypted = try Rabbit(key: key, iv: iv).encrypt(message) +let decrypted = try Rabbit(key: key, iv: iv).decrypt(encrypted) +``` +##### Blowfish + +```swift +let encrypted = try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).encrypt(message) +let decrypted = try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).decrypt(encrypted) +``` + +##### AES + +Notice regarding padding: *Manual padding of data is optional, and CryptoSwift is using PKCS7 padding by default. If you need to manually disable/enable padding, you can do this by setting parameter for __AES__ class* + +Variant of AES encryption (AES-128, AES-192, AES-256) depends on given key length: + +- AES-128 = 16 bytes +- AES-192 = 24 bytes +- AES-256 = 32 bytes + +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 { + let aes = try AES(key: "keykeykeykeykeyk", iv: "drowssapdrowssap") // aes128 + let ciphertext = try aes.encrypt(Array("Nullam quis risus eget urna mollis ornare vel eu leo.".utf8)) +} catch { } +``` + +###### Incremental updates + +Incremental operations use instance of Cryptor and encrypt/decrypt one part at a time, this way you can save on memory for large files. + +```swift +do { + var encryptor = try AES(key: "keykeykeykeykeyk", iv: "drowssapdrowssap").makeEncryptor() + + var ciphertext = Array() + // aggregate partial results + ciphertext += try encryptor.update(withBytes: Array("Nullam quis risus ".utf8)) + ciphertext += try encryptor.update(withBytes: Array("eget urna mollis ".utf8)) + ciphertext += try encryptor.update(withBytes: Array("ornare vel eu leo.".utf8)) + // finish at the end + ciphertext += try encryptor.finish() + + print(ciphertext.toHexString()) +} catch { + print(error) +} +``` + +See [Playground](/CryptoSwift.playground/Contents.swift) for sample code that work with stream. + +###### AES Advanced usage +```swift +let input: Array = [0,1,2,3,4,5,6,7,8,9] + +let key: Array = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00] +let iv: Array = AES.randomIV(AES.blockSize) + +do { + let encrypted = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).encrypt(input) + let decrypted = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).decrypt(encrypted) +} catch { + print(error) +} +``` + +AES without data padding + +```swift +let input: Array = [0,1,2,3,4,5,6,7,8,9] +let encrypted: Array = try! AES(key: Array("secret0key000000".utf8), blockMode: CBC(iv: Array("0123456789012345".utf8)), padding: .noPadding).encrypt(input) +``` + +Using convenience extensions + +```swift +let plain = Data( [0x01, 0x02, 0x03]) +let encrypted = try! plain.encrypt(ChaCha20(key: key, iv: iv)) +let decrypted = try! encrypted.decrypt(ChaCha20(key: key, iv: iv)) +``` + +##### AES-GCM + +The result of Galois/Counter Mode (GCM) encryption is ciphertext and **authentication tag**, that is later used to decryption. + +encryption + +```swift +do { + // In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want. + let gcm = GCM(iv: iv, mode: .combined) + let aes = try AES(key: key, blockMode: gcm, padding: .noPadding) + let encrypted = try aes.encrypt(plaintext) + let tag = gcm.authenticationTag +catch { + // failed +} +``` + +decryption + +```swift +do { + // In combined mode, the authentication tag is appended to the encrypted message. This is usually what you want. + let gcm = GCM(iv: iv, mode: .combined) + let aes = try AES(key: key, blockMode: gcm, padding: .noPadding) + return try aes.decrypt(encrypted) +} catch { + // failed +} +``` + +**Note**: GCM instance is not intended to be reused. So you can't use the same `GCM` instance from encoding to also perform decoding. + +##### AES-CCM + +The result of Counter with Cipher Block Chaining-Message Authentication Code encryption is ciphertext and **authentication tag**, that is later used to decryption. + +```swift +do { + // The authentication tag is appended to the encrypted message. + let tagLength = 8 + let ccm = CCM(iv: iv, tagLength: tagLength, messageLength: ciphertext.count - tagLength, additionalAuthenticatedData: data) + let aes = try AES(key: key, blockMode: ccm, padding: .noPadding) + return try aes.decrypt(encrypted) +} catch { + // failed +} +``` + +Check documentation or CCM specification for valid parameters for CCM. + +##### 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) + +You can follow me on Twitter at [@krzyzanowskim](http://twitter.com/krzyzanowskim) for project updates and releases. + +# Cryptography Notice + +This distribution includes cryptographic software. The country in which you currently reside may have restrictions on the import, possession, use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check your country's laws, regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. See http://www.wassenaar.org/ for more information. + +## License + +Copyright (C) 2014-2017 Marcin Krzyżanowski +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. +- Redistributions of any form whatsoever must retain the following acknowledgment: 'This product includes software developed by the "Marcin Krzyzanowski" (http://krzyzanowskim.com/).' + +## Changelog + +See [CHANGELOG](./CHANGELOG) file. diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift.h b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift.h new file mode 100644 index 0000000000..85fe675437 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift.h @@ -0,0 +1,15 @@ +// +// CryptoSwift.h +// CryptoSwift +// +// Created by Sam Soffes on 11/29/15. +// Copyright © 2015 Marcin Krzyzanowski. All rights reserved. +// + +@import Foundation; + +//! Project version number for CryptoSwift. +FOUNDATION_EXPORT double CryptoSwiftVersionNumber; + +//! Project version string for CryptoSwift. +FOUNDATION_EXPORT const unsigned char CryptoSwiftVersionString[]; diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/AEAD/AEAD.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/AEAD/AEAD.swift new file mode 100644 index 0000000000..67179c597f --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/AEAD/AEAD.swift @@ -0,0 +1,40 @@ +// +// AEAD.swift +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 { get } // nonce length +} + +extension AEAD { + static func calculateAuthenticationTag(authenticator: Authenticator, cipherText: Array, authenticationHeader: Array) throws -> Array { + let headerPadding = ((16 - (authenticationHeader.count & 0xf)) & 0xf) + let cipherPadding = ((16 - (cipherText.count & 0xf)) & 0xf) + + var mac = authenticationHeader + mac += Array(repeating: 0, count: headerPadding) + mac += cipherText + mac += Array(repeating: 0, count: cipherPadding) + mac += UInt64(bigEndian: UInt64(authenticationHeader.count)).bytes() + mac += UInt64(bigEndian: UInt64(cipherText.count)).bytes() + + return try authenticator.authenticate(mac) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/AEAD/AEADChaCha20Poly1305.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/AEAD/AEADChaCha20Poly1305.swift new file mode 100644 index 0000000000..791f9a4420 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/AEAD/AEADChaCha20Poly1305.swift @@ -0,0 +1,59 @@ +// +// ChaCha20Poly1305.swift +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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(12...12) + + /// Authenticated encryption + public static func encrypt(_ plainText: Array, key: Array, iv: Array, authenticationHeader: Array) throws -> (cipherText: Array, authenticationTag: Array) { + let cipher = try ChaCha20(key: key, iv: iv) + + var polykey = Array(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, key: Array, iv: Array, authenticationHeader: Array, authenticationTag: Array) throws -> (plainText: Array, success: Bool) { + let chacha = try ChaCha20(key: key, iv: iv) + + let polykey = try chacha.encrypt(Array(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(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) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/AES.Cryptors.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/AES.Cryptors.swift new file mode 100644 index 0000000000..a461cd616d --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/AES.Cryptors.swift @@ -0,0 +1,35 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// MARK: Cryptors + +extension AES: Cryptors { + public func makeEncryptor() throws -> Cryptor & Updatable { + let worker = try blockMode.worker(blockSize: AES.blockSize, cipherOperation: encrypt) + if worker is StreamModeWorker { + return try StreamEncryptor(blockSize: AES.blockSize, padding: padding, worker) + } + return try BlockEncryptor(blockSize: AES.blockSize, padding: padding, worker) + } + + public func makeDecryptor() throws -> Cryptor & Updatable { + let cipherOperation: CipherOperationOnBlock = blockMode.options.contains(.useEncryptToDecrypt) == true ? encrypt : decrypt + let worker = try blockMode.worker(blockSize: AES.blockSize, cipherOperation: cipherOperation) + if worker is StreamModeWorker { + return try StreamDecryptor(blockSize: AES.blockSize, padding: padding, worker) + } + return try BlockDecryptor(blockSize: AES.blockSize, padding: padding, worker) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/AES.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/AES.swift new file mode 100644 index 0000000000..631b7d518f --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/AES.swift @@ -0,0 +1,539 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// Implementation of Gladman algorithm http://www.gladman.me.uk/AES +// + +/// The Advanced Encryption Standard (AES) +public final class AES: BlockCipher { + public enum Error: Swift.Error { + /// Invalid key + case invalidKeySize + /// Data padding is required + case dataPaddingRequired + /// Invalid Data + case invalidData + } + + public enum Variant: Int { + case aes128 = 1, aes192, aes256 + + var Nk: Int { // Nk words + return [4, 6, 8][self.rawValue - 1] + } + + var Nb: Int { // Nb words + return 4 + } + + var Nr: Int { // Nr + return Nk + 6 + } + } + + private let variantNr: Int + private let variantNb: Int + private let variantNk: Int + + public static let blockSize: Int = 16 // 128 /8 + public let keySize: Int + + /// AES Variant + public let variant: Variant + + // Parameters + let key: Key + let blockMode: BlockMode + let padding: Padding + + // + private lazy var expandedKey: Array> = self.expandKey(self.key, variant: self.variant) + private lazy var expandedKeyInv: Array> = self.expandKeyInv(self.key, variant: self.variant) + + private lazy var sBoxes: (sBox: Array, invSBox: Array) = self.calculateSBox() + private lazy var sBox: Array = self.sBoxes.sBox + private lazy var sBoxInv: Array = self.sBoxes.invSBox + + // Parameters for Linear Congruence Generators + private static let Rcon: Array = [ + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, + 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, + 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, + 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, + 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, + 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, + 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, + 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, + 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, + 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, + 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, + 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, + 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, + 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, + 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, + ] + + private static let T0: Array = [0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0xdf2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x3010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0xbf0f0fb, 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x2f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x8f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, 0xc040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0xf05050a, 0xb59a9a2f, 0x907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x0, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, 0x10f9f9e9, 0x6020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x4f5f5f1, 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0xef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0xa06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac, 0x7f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x5030306, 0x1f6f6f7, 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c] + private static let T0_INV: Array = [0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 0x2752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, 0x728ebb2, 0x3c2b52f, 0x9a7bc586, 0xa50837d3, 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x69f715e, 0x51106ebd, 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, 0x55dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x0, 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0xfe75793, 0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, 0xaba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0xb0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0xd927850, 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x97826cd, 0xf418596e, 0x1b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x8cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, 0xf7daec41, 0xe50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, 0x4ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0xc25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0] + private static let T1: Array = [0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x1010203, 0x6767cea9, 0x2b2b567d, 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, 0x404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, 0x5050a0f, 0x9a9a2fb5, 0x7070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 0x909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, 0x5353a6f5, 0xd1d1b968, 0x0, 0xededc12c, 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, 0x45458acf, 0xf9f9e910, 0x2020406, 0x7f7ffe81, 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, 0xcdcd814c, 0xc0c1814, 0x13132635, 0xececc32f, 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, 0xdedea779, 0x5e5ebce2, 0xb0b161d, 0xdbdbad76, 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0xa0a141e, 0x494992db, 0x6060c0a, 0x2424486c, 0x5c5cb8e4, 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x8081018, 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x3030605, 0xf6f6f701, 0xe0e1c12, 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, 0x8c8c038f, 0xa1a159f8, 0x89890980, 0xd0d1a17, 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, 0x414182c3, 0x999929b0, 0x2d2d5a77, 0xf0f1e11, 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a] + private static let T1_INV: Array = [0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, 0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x3e34b93, 0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f, 0x5ab1de49, 0x1bba2567, 0xeea4598, 0xc0fe5de1, 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, 0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, 0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44, 0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd, 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994, 0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, 0xd373ab23, 0x24b72e2, 0x8f1fe357, 0xab55662a, 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x837d3a5, 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, 0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, 0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a, 0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, 0x8a213ef9, 0x6dd963d, 0x53eddae, 0xbde64d46, 0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff, 0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db, 0xa7ca147, 0xf427ce9, 0x1e84f8c9, 0x0, 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, 0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627, 0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, 0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e, 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, 0xd090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, 0x19f15785, 0x775af4c, 0xdd99eebb, 0x607fa3fd, 0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, 0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, 0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0, 0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0xbd49836, 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, 0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, 0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5, 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, 0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8, 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6, 0x9be7bad9, 0x366f4ace, 0x99fead4, 0x7cb029d6, 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, 0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, 0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x496e4df, 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f, 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, 0x61d79a8c, 0xca1377a, 0x14f8598e, 0x3c13eb89, 0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c, 0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, 0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41, 0x1a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490, 0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042] + private static let T2: Array = [0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, 0x30605030, 0x1020301, 0x67cea967, 0x2b567d2b, 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, 0x4080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, 0x50a0f05, 0x9a2fb59a, 0x70e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 0x9121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, 0x53a6f553, 0xd1b968d1, 0x0, 0xedc12ced, 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, 0x458acf45, 0xf9e910f9, 0x2040602, 0x7ffe817f, 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, 0xcd814ccd, 0xc18140c, 0x13263513, 0xecc32fec, 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, 0xdea779de, 0x5ebce25e, 0xb161d0b, 0xdbad76db, 0xe0db3be0, 0x32645632, 0x3a744e3a, 0xa141e0a, 0x4992db49, 0x60c0a06, 0x24486c24, 0x5cb8e45c, 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x8101808, 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x3060503, 0xf6f701f6, 0xe1c120e, 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, 0x8c038f8c, 0xa159f8a1, 0x89098089, 0xd1a170d, 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, 0x4182c341, 0x9929b099, 0x2d5a772d, 0xf1e110f, 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16] + private static let T2_INV: Array = [0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, 0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303, 0x302055fa, 0x76adf66d, 0xcc889176, 0x2f5254c, 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3, 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, 0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, 0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8, 0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71, 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x8f9942b, 0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, 0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab, 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, 0x2830f287, 0xbf23b2a5, 0x302ba6a, 0x16ed5c82, 0xcf8a2b1c, 0x79a792b4, 0x7f3f0f2, 0x694ea1e2, 0xda65cdf4, 0x506d5be, 0x34d11f62, 0xa6c48afe, 0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, 0x5491b58d, 0xc471055d, 0x6046fd4, 0x5060ff15, 0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee, 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x0, 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, 0xefdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739, 0xf0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, 0xa0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91, 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, 0x90e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, 0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60, 0x1f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, 0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, 0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3, 0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf, 0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, 0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af, 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, 0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a, 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8, 0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, 0x4f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, 0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51, 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0xbfb2e41, 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, 0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, 0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, 0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0xdff4195, 0xa8397101, 0xc08deb3, 0xb4d89ce4, 0x566490c1, 0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257] + private static let T3: Array = [0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x2030101, 0xcea96767, 0x567d2b2b, 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, 0x80c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, 0xa0f0505, 0x2fb59a9a, 0xe090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, 0xa6f55353, 0xb968d1d1, 0x0, 0xc12ceded, 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, 0x8acf4545, 0xe910f9f9, 0x4060202, 0xfe817f7f, 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x58a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a, 0x3bab9090, 0xb838888, 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 0x92db4949, 0xc0a0606, 0x486c2424, 0xb8e45c5c, 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, 0x18c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, 0x96dd4b4b, 0x61dcbdbd, 0xd868b8b, 0xf858a8a, 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x6050303, 0xf701f6f6, 0x1c120e0e, 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, 0xd2bb6969, 0xa970d9d9, 0x7898e8e, 0x33a79494, 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, 0x38f8c8c, 0x59f8a1a1, 0x9808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616] + private static let T3_INV: Array = [0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3, 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, 0x3e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, 0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9, 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9, 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, 0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, 0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55, 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, 0x30f28728, 0x23b2a5bf, 0x2ba6a03, 0xed5c8216, 0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, 0x65cdf4da, 0x6d5be05, 0xd11f6234, 0xc48afea6, 0x349d532e, 0xa2a055f3, 0x532e18a, 0xa475ebf6, 0xb39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, 0x91b58d54, 0x71055dc4, 0x46fd406, 0x60ff1550, 0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, 0xb0bd42e8, 0x7888b89, 0xe7385b19, 0x79dbeec8, 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x0, 0x9838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, 0xfdfbff0e, 0xf563885, 0x3d1ed5ae, 0x3627392d, 0xa64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, 0xcb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b, 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, 0xe0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f, 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, 0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, 0x1d4b2f9e, 0xdcf330b2, 0xdec5286, 0x77d0e3c1, 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad, 0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3, 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, 0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f, 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815, 0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, 0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165, 0x9d04ea5e, 0x15d358c, 0xfa737487, 0xfb2e410b, 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, 0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, 0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d, 0x397101a8, 0x8deb30c, 0xd89ce4b4, 0x6490c156, 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8] + private static let U1: Array = [0x0, 0xb0d090e, 0x161a121c, 0x1d171b12, 0x2c342438, 0x27392d36, 0x3a2e3624, 0x31233f2a, 0x58684870, 0x5365417e, 0x4e725a6c, 0x457f5362, 0x745c6c48, 0x7f516546, 0x62467e54, 0x694b775a, 0xb0d090e0, 0xbbdd99ee, 0xa6ca82fc, 0xadc78bf2, 0x9ce4b4d8, 0x97e9bdd6, 0x8afea6c4, 0x81f3afca, 0xe8b8d890, 0xe3b5d19e, 0xfea2ca8c, 0xf5afc382, 0xc48cfca8, 0xcf81f5a6, 0xd296eeb4, 0xd99be7ba, 0x7bbb3bdb, 0x70b632d5, 0x6da129c7, 0x66ac20c9, 0x578f1fe3, 0x5c8216ed, 0x41950dff, 0x4a9804f1, 0x23d373ab, 0x28de7aa5, 0x35c961b7, 0x3ec468b9, 0xfe75793, 0x4ea5e9d, 0x19fd458f, 0x12f04c81, 0xcb6bab3b, 0xc066a235, 0xdd71b927, 0xd67cb029, 0xe75f8f03, 0xec52860d, 0xf1459d1f, 0xfa489411, 0x9303e34b, 0x980eea45, 0x8519f157, 0x8e14f859, 0xbf37c773, 0xb43ace7d, 0xa92dd56f, 0xa220dc61, 0xf66d76ad, 0xfd607fa3, 0xe07764b1, 0xeb7a6dbf, 0xda595295, 0xd1545b9b, 0xcc434089, 0xc74e4987, 0xae053edd, 0xa50837d3, 0xb81f2cc1, 0xb31225cf, 0x82311ae5, 0x893c13eb, 0x942b08f9, 0x9f2601f7, 0x46bde64d, 0x4db0ef43, 0x50a7f451, 0x5baafd5f, 0x6a89c275, 0x6184cb7b, 0x7c93d069, 0x779ed967, 0x1ed5ae3d, 0x15d8a733, 0x8cfbc21, 0x3c2b52f, 0x32e18a05, 0x39ec830b, 0x24fb9819, 0x2ff69117, 0x8dd64d76, 0x86db4478, 0x9bcc5f6a, 0x90c15664, 0xa1e2694e, 0xaaef6040, 0xb7f87b52, 0xbcf5725c, 0xd5be0506, 0xdeb30c08, 0xc3a4171a, 0xc8a91e14, 0xf98a213e, 0xf2872830, 0xef903322, 0xe49d3a2c, 0x3d06dd96, 0x360bd498, 0x2b1ccf8a, 0x2011c684, 0x1132f9ae, 0x1a3ff0a0, 0x728ebb2, 0xc25e2bc, 0x656e95e6, 0x6e639ce8, 0x737487fa, 0x78798ef4, 0x495ab1de, 0x4257b8d0, 0x5f40a3c2, 0x544daacc, 0xf7daec41, 0xfcd7e54f, 0xe1c0fe5d, 0xeacdf753, 0xdbeec879, 0xd0e3c177, 0xcdf4da65, 0xc6f9d36b, 0xafb2a431, 0xa4bfad3f, 0xb9a8b62d, 0xb2a5bf23, 0x83868009, 0x888b8907, 0x959c9215, 0x9e919b1b, 0x470a7ca1, 0x4c0775af, 0x51106ebd, 0x5a1d67b3, 0x6b3e5899, 0x60335197, 0x7d244a85, 0x7629438b, 0x1f6234d1, 0x146f3ddf, 0x97826cd, 0x2752fc3, 0x335610e9, 0x385b19e7, 0x254c02f5, 0x2e410bfb, 0x8c61d79a, 0x876cde94, 0x9a7bc586, 0x9176cc88, 0xa055f3a2, 0xab58faac, 0xb64fe1be, 0xbd42e8b0, 0xd4099fea, 0xdf0496e4, 0xc2138df6, 0xc91e84f8, 0xf83dbbd2, 0xf330b2dc, 0xee27a9ce, 0xe52aa0c0, 0x3cb1477a, 0x37bc4e74, 0x2aab5566, 0x21a65c68, 0x10856342, 0x1b886a4c, 0x69f715e, 0xd927850, 0x64d90f0a, 0x6fd40604, 0x72c31d16, 0x79ce1418, 0x48ed2b32, 0x43e0223c, 0x5ef7392e, 0x55fa3020, 0x1b79aec, 0xaba93e2, 0x17ad88f0, 0x1ca081fe, 0x2d83bed4, 0x268eb7da, 0x3b99acc8, 0x3094a5c6, 0x59dfd29c, 0x52d2db92, 0x4fc5c080, 0x44c8c98e, 0x75ebf6a4, 0x7ee6ffaa, 0x63f1e4b8, 0x68fcedb6, 0xb1670a0c, 0xba6a0302, 0xa77d1810, 0xac70111e, 0x9d532e34, 0x965e273a, 0x8b493c28, 0x80443526, 0xe90f427c, 0xe2024b72, 0xff155060, 0xf418596e, 0xc53b6644, 0xce366f4a, 0xd3217458, 0xd82c7d56, 0x7a0ca137, 0x7101a839, 0x6c16b32b, 0x671bba25, 0x5638850f, 0x5d358c01, 0x40229713, 0x4b2f9e1d, 0x2264e947, 0x2969e049, 0x347efb5b, 0x3f73f255, 0xe50cd7f, 0x55dc471, 0x184adf63, 0x1347d66d, 0xcadc31d7, 0xc1d138d9, 0xdcc623cb, 0xd7cb2ac5, 0xe6e815ef, 0xede51ce1, 0xf0f207f3, 0xfbff0efd, 0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5, 0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d] + private static let U2: Array = [0x0, 0xd090e0b, 0x1a121c16, 0x171b121d, 0x3424382c, 0x392d3627, 0x2e36243a, 0x233f2a31, 0x68487058, 0x65417e53, 0x725a6c4e, 0x7f536245, 0x5c6c4874, 0x5165467f, 0x467e5462, 0x4b775a69, 0xd090e0b0, 0xdd99eebb, 0xca82fca6, 0xc78bf2ad, 0xe4b4d89c, 0xe9bdd697, 0xfea6c48a, 0xf3afca81, 0xb8d890e8, 0xb5d19ee3, 0xa2ca8cfe, 0xafc382f5, 0x8cfca8c4, 0x81f5a6cf, 0x96eeb4d2, 0x9be7bad9, 0xbb3bdb7b, 0xb632d570, 0xa129c76d, 0xac20c966, 0x8f1fe357, 0x8216ed5c, 0x950dff41, 0x9804f14a, 0xd373ab23, 0xde7aa528, 0xc961b735, 0xc468b93e, 0xe757930f, 0xea5e9d04, 0xfd458f19, 0xf04c8112, 0x6bab3bcb, 0x66a235c0, 0x71b927dd, 0x7cb029d6, 0x5f8f03e7, 0x52860dec, 0x459d1ff1, 0x489411fa, 0x3e34b93, 0xeea4598, 0x19f15785, 0x14f8598e, 0x37c773bf, 0x3ace7db4, 0x2dd56fa9, 0x20dc61a2, 0x6d76adf6, 0x607fa3fd, 0x7764b1e0, 0x7a6dbfeb, 0x595295da, 0x545b9bd1, 0x434089cc, 0x4e4987c7, 0x53eddae, 0x837d3a5, 0x1f2cc1b8, 0x1225cfb3, 0x311ae582, 0x3c13eb89, 0x2b08f994, 0x2601f79f, 0xbde64d46, 0xb0ef434d, 0xa7f45150, 0xaafd5f5b, 0x89c2756a, 0x84cb7b61, 0x93d0697c, 0x9ed96777, 0xd5ae3d1e, 0xd8a73315, 0xcfbc2108, 0xc2b52f03, 0xe18a0532, 0xec830b39, 0xfb981924, 0xf691172f, 0xd64d768d, 0xdb447886, 0xcc5f6a9b, 0xc1566490, 0xe2694ea1, 0xef6040aa, 0xf87b52b7, 0xf5725cbc, 0xbe0506d5, 0xb30c08de, 0xa4171ac3, 0xa91e14c8, 0x8a213ef9, 0x872830f2, 0x903322ef, 0x9d3a2ce4, 0x6dd963d, 0xbd49836, 0x1ccf8a2b, 0x11c68420, 0x32f9ae11, 0x3ff0a01a, 0x28ebb207, 0x25e2bc0c, 0x6e95e665, 0x639ce86e, 0x7487fa73, 0x798ef478, 0x5ab1de49, 0x57b8d042, 0x40a3c25f, 0x4daacc54, 0xdaec41f7, 0xd7e54ffc, 0xc0fe5de1, 0xcdf753ea, 0xeec879db, 0xe3c177d0, 0xf4da65cd, 0xf9d36bc6, 0xb2a431af, 0xbfad3fa4, 0xa8b62db9, 0xa5bf23b2, 0x86800983, 0x8b890788, 0x9c921595, 0x919b1b9e, 0xa7ca147, 0x775af4c, 0x106ebd51, 0x1d67b35a, 0x3e58996b, 0x33519760, 0x244a857d, 0x29438b76, 0x6234d11f, 0x6f3ddf14, 0x7826cd09, 0x752fc302, 0x5610e933, 0x5b19e738, 0x4c02f525, 0x410bfb2e, 0x61d79a8c, 0x6cde9487, 0x7bc5869a, 0x76cc8891, 0x55f3a2a0, 0x58faacab, 0x4fe1beb6, 0x42e8b0bd, 0x99fead4, 0x496e4df, 0x138df6c2, 0x1e84f8c9, 0x3dbbd2f8, 0x30b2dcf3, 0x27a9ceee, 0x2aa0c0e5, 0xb1477a3c, 0xbc4e7437, 0xab55662a, 0xa65c6821, 0x85634210, 0x886a4c1b, 0x9f715e06, 0x9278500d, 0xd90f0a64, 0xd406046f, 0xc31d1672, 0xce141879, 0xed2b3248, 0xe0223c43, 0xf7392e5e, 0xfa302055, 0xb79aec01, 0xba93e20a, 0xad88f017, 0xa081fe1c, 0x83bed42d, 0x8eb7da26, 0x99acc83b, 0x94a5c630, 0xdfd29c59, 0xd2db9252, 0xc5c0804f, 0xc8c98e44, 0xebf6a475, 0xe6ffaa7e, 0xf1e4b863, 0xfcedb668, 0x670a0cb1, 0x6a0302ba, 0x7d1810a7, 0x70111eac, 0x532e349d, 0x5e273a96, 0x493c288b, 0x44352680, 0xf427ce9, 0x24b72e2, 0x155060ff, 0x18596ef4, 0x3b6644c5, 0x366f4ace, 0x217458d3, 0x2c7d56d8, 0xca1377a, 0x1a83971, 0x16b32b6c, 0x1bba2567, 0x38850f56, 0x358c015d, 0x22971340, 0x2f9e1d4b, 0x64e94722, 0x69e04929, 0x7efb5b34, 0x73f2553f, 0x50cd7f0e, 0x5dc47105, 0x4adf6318, 0x47d66d13, 0xdc31d7ca, 0xd138d9c1, 0xc623cbdc, 0xcb2ac5d7, 0xe815efe6, 0xe51ce1ed, 0xf207f3f0, 0xff0efdfb, 0xb479a792, 0xb970a999, 0xae6bbb84, 0xa362b58f, 0x805d9fbe, 0x8d5491b5, 0x9a4f83a8, 0x97468da3] + private static let U3: Array = [0x0, 0x90e0b0d, 0x121c161a, 0x1b121d17, 0x24382c34, 0x2d362739, 0x36243a2e, 0x3f2a3123, 0x48705868, 0x417e5365, 0x5a6c4e72, 0x5362457f, 0x6c48745c, 0x65467f51, 0x7e546246, 0x775a694b, 0x90e0b0d0, 0x99eebbdd, 0x82fca6ca, 0x8bf2adc7, 0xb4d89ce4, 0xbdd697e9, 0xa6c48afe, 0xafca81f3, 0xd890e8b8, 0xd19ee3b5, 0xca8cfea2, 0xc382f5af, 0xfca8c48c, 0xf5a6cf81, 0xeeb4d296, 0xe7bad99b, 0x3bdb7bbb, 0x32d570b6, 0x29c76da1, 0x20c966ac, 0x1fe3578f, 0x16ed5c82, 0xdff4195, 0x4f14a98, 0x73ab23d3, 0x7aa528de, 0x61b735c9, 0x68b93ec4, 0x57930fe7, 0x5e9d04ea, 0x458f19fd, 0x4c8112f0, 0xab3bcb6b, 0xa235c066, 0xb927dd71, 0xb029d67c, 0x8f03e75f, 0x860dec52, 0x9d1ff145, 0x9411fa48, 0xe34b9303, 0xea45980e, 0xf1578519, 0xf8598e14, 0xc773bf37, 0xce7db43a, 0xd56fa92d, 0xdc61a220, 0x76adf66d, 0x7fa3fd60, 0x64b1e077, 0x6dbfeb7a, 0x5295da59, 0x5b9bd154, 0x4089cc43, 0x4987c74e, 0x3eddae05, 0x37d3a508, 0x2cc1b81f, 0x25cfb312, 0x1ae58231, 0x13eb893c, 0x8f9942b, 0x1f79f26, 0xe64d46bd, 0xef434db0, 0xf45150a7, 0xfd5f5baa, 0xc2756a89, 0xcb7b6184, 0xd0697c93, 0xd967779e, 0xae3d1ed5, 0xa73315d8, 0xbc2108cf, 0xb52f03c2, 0x8a0532e1, 0x830b39ec, 0x981924fb, 0x91172ff6, 0x4d768dd6, 0x447886db, 0x5f6a9bcc, 0x566490c1, 0x694ea1e2, 0x6040aaef, 0x7b52b7f8, 0x725cbcf5, 0x506d5be, 0xc08deb3, 0x171ac3a4, 0x1e14c8a9, 0x213ef98a, 0x2830f287, 0x3322ef90, 0x3a2ce49d, 0xdd963d06, 0xd498360b, 0xcf8a2b1c, 0xc6842011, 0xf9ae1132, 0xf0a01a3f, 0xebb20728, 0xe2bc0c25, 0x95e6656e, 0x9ce86e63, 0x87fa7374, 0x8ef47879, 0xb1de495a, 0xb8d04257, 0xa3c25f40, 0xaacc544d, 0xec41f7da, 0xe54ffcd7, 0xfe5de1c0, 0xf753eacd, 0xc879dbee, 0xc177d0e3, 0xda65cdf4, 0xd36bc6f9, 0xa431afb2, 0xad3fa4bf, 0xb62db9a8, 0xbf23b2a5, 0x80098386, 0x8907888b, 0x9215959c, 0x9b1b9e91, 0x7ca1470a, 0x75af4c07, 0x6ebd5110, 0x67b35a1d, 0x58996b3e, 0x51976033, 0x4a857d24, 0x438b7629, 0x34d11f62, 0x3ddf146f, 0x26cd0978, 0x2fc30275, 0x10e93356, 0x19e7385b, 0x2f5254c, 0xbfb2e41, 0xd79a8c61, 0xde94876c, 0xc5869a7b, 0xcc889176, 0xf3a2a055, 0xfaacab58, 0xe1beb64f, 0xe8b0bd42, 0x9fead409, 0x96e4df04, 0x8df6c213, 0x84f8c91e, 0xbbd2f83d, 0xb2dcf330, 0xa9ceee27, 0xa0c0e52a, 0x477a3cb1, 0x4e7437bc, 0x55662aab, 0x5c6821a6, 0x63421085, 0x6a4c1b88, 0x715e069f, 0x78500d92, 0xf0a64d9, 0x6046fd4, 0x1d1672c3, 0x141879ce, 0x2b3248ed, 0x223c43e0, 0x392e5ef7, 0x302055fa, 0x9aec01b7, 0x93e20aba, 0x88f017ad, 0x81fe1ca0, 0xbed42d83, 0xb7da268e, 0xacc83b99, 0xa5c63094, 0xd29c59df, 0xdb9252d2, 0xc0804fc5, 0xc98e44c8, 0xf6a475eb, 0xffaa7ee6, 0xe4b863f1, 0xedb668fc, 0xa0cb167, 0x302ba6a, 0x1810a77d, 0x111eac70, 0x2e349d53, 0x273a965e, 0x3c288b49, 0x35268044, 0x427ce90f, 0x4b72e202, 0x5060ff15, 0x596ef418, 0x6644c53b, 0x6f4ace36, 0x7458d321, 0x7d56d82c, 0xa1377a0c, 0xa8397101, 0xb32b6c16, 0xba25671b, 0x850f5638, 0x8c015d35, 0x97134022, 0x9e1d4b2f, 0xe9472264, 0xe0492969, 0xfb5b347e, 0xf2553f73, 0xcd7f0e50, 0xc471055d, 0xdf63184a, 0xd66d1347, 0x31d7cadc, 0x38d9c1d1, 0x23cbdcc6, 0x2ac5d7cb, 0x15efe6e8, 0x1ce1ede5, 0x7f3f0f2, 0xefdfbff, 0x79a792b4, 0x70a999b9, 0x6bbb84ae, 0x62b58fa3, 0x5d9fbe80, 0x5491b58d, 0x4f83a89a, 0x468da397] + private static let U4: Array = [0x0, 0xe0b0d09, 0x1c161a12, 0x121d171b, 0x382c3424, 0x3627392d, 0x243a2e36, 0x2a31233f, 0x70586848, 0x7e536541, 0x6c4e725a, 0x62457f53, 0x48745c6c, 0x467f5165, 0x5462467e, 0x5a694b77, 0xe0b0d090, 0xeebbdd99, 0xfca6ca82, 0xf2adc78b, 0xd89ce4b4, 0xd697e9bd, 0xc48afea6, 0xca81f3af, 0x90e8b8d8, 0x9ee3b5d1, 0x8cfea2ca, 0x82f5afc3, 0xa8c48cfc, 0xa6cf81f5, 0xb4d296ee, 0xbad99be7, 0xdb7bbb3b, 0xd570b632, 0xc76da129, 0xc966ac20, 0xe3578f1f, 0xed5c8216, 0xff41950d, 0xf14a9804, 0xab23d373, 0xa528de7a, 0xb735c961, 0xb93ec468, 0x930fe757, 0x9d04ea5e, 0x8f19fd45, 0x8112f04c, 0x3bcb6bab, 0x35c066a2, 0x27dd71b9, 0x29d67cb0, 0x3e75f8f, 0xdec5286, 0x1ff1459d, 0x11fa4894, 0x4b9303e3, 0x45980eea, 0x578519f1, 0x598e14f8, 0x73bf37c7, 0x7db43ace, 0x6fa92dd5, 0x61a220dc, 0xadf66d76, 0xa3fd607f, 0xb1e07764, 0xbfeb7a6d, 0x95da5952, 0x9bd1545b, 0x89cc4340, 0x87c74e49, 0xddae053e, 0xd3a50837, 0xc1b81f2c, 0xcfb31225, 0xe582311a, 0xeb893c13, 0xf9942b08, 0xf79f2601, 0x4d46bde6, 0x434db0ef, 0x5150a7f4, 0x5f5baafd, 0x756a89c2, 0x7b6184cb, 0x697c93d0, 0x67779ed9, 0x3d1ed5ae, 0x3315d8a7, 0x2108cfbc, 0x2f03c2b5, 0x532e18a, 0xb39ec83, 0x1924fb98, 0x172ff691, 0x768dd64d, 0x7886db44, 0x6a9bcc5f, 0x6490c156, 0x4ea1e269, 0x40aaef60, 0x52b7f87b, 0x5cbcf572, 0x6d5be05, 0x8deb30c, 0x1ac3a417, 0x14c8a91e, 0x3ef98a21, 0x30f28728, 0x22ef9033, 0x2ce49d3a, 0x963d06dd, 0x98360bd4, 0x8a2b1ccf, 0x842011c6, 0xae1132f9, 0xa01a3ff0, 0xb20728eb, 0xbc0c25e2, 0xe6656e95, 0xe86e639c, 0xfa737487, 0xf478798e, 0xde495ab1, 0xd04257b8, 0xc25f40a3, 0xcc544daa, 0x41f7daec, 0x4ffcd7e5, 0x5de1c0fe, 0x53eacdf7, 0x79dbeec8, 0x77d0e3c1, 0x65cdf4da, 0x6bc6f9d3, 0x31afb2a4, 0x3fa4bfad, 0x2db9a8b6, 0x23b2a5bf, 0x9838680, 0x7888b89, 0x15959c92, 0x1b9e919b, 0xa1470a7c, 0xaf4c0775, 0xbd51106e, 0xb35a1d67, 0x996b3e58, 0x97603351, 0x857d244a, 0x8b762943, 0xd11f6234, 0xdf146f3d, 0xcd097826, 0xc302752f, 0xe9335610, 0xe7385b19, 0xf5254c02, 0xfb2e410b, 0x9a8c61d7, 0x94876cde, 0x869a7bc5, 0x889176cc, 0xa2a055f3, 0xacab58fa, 0xbeb64fe1, 0xb0bd42e8, 0xead4099f, 0xe4df0496, 0xf6c2138d, 0xf8c91e84, 0xd2f83dbb, 0xdcf330b2, 0xceee27a9, 0xc0e52aa0, 0x7a3cb147, 0x7437bc4e, 0x662aab55, 0x6821a65c, 0x42108563, 0x4c1b886a, 0x5e069f71, 0x500d9278, 0xa64d90f, 0x46fd406, 0x1672c31d, 0x1879ce14, 0x3248ed2b, 0x3c43e022, 0x2e5ef739, 0x2055fa30, 0xec01b79a, 0xe20aba93, 0xf017ad88, 0xfe1ca081, 0xd42d83be, 0xda268eb7, 0xc83b99ac, 0xc63094a5, 0x9c59dfd2, 0x9252d2db, 0x804fc5c0, 0x8e44c8c9, 0xa475ebf6, 0xaa7ee6ff, 0xb863f1e4, 0xb668fced, 0xcb1670a, 0x2ba6a03, 0x10a77d18, 0x1eac7011, 0x349d532e, 0x3a965e27, 0x288b493c, 0x26804435, 0x7ce90f42, 0x72e2024b, 0x60ff1550, 0x6ef41859, 0x44c53b66, 0x4ace366f, 0x58d32174, 0x56d82c7d, 0x377a0ca1, 0x397101a8, 0x2b6c16b3, 0x25671bba, 0xf563885, 0x15d358c, 0x13402297, 0x1d4b2f9e, 0x472264e9, 0x492969e0, 0x5b347efb, 0x553f73f2, 0x7f0e50cd, 0x71055dc4, 0x63184adf, 0x6d1347d6, 0xd7cadc31, 0xd9c1d138, 0xcbdcc623, 0xc5d7cb2a, 0xefe6e815, 0xe1ede51c, 0xf3f0f207, 0xfdfbff0e, 0xa792b479, 0xa999b970, 0xbb84ae6b, 0xb58fa362, 0x9fbe805d, 0x91b58d54, 0x83a89a4f, 0x8da39746] + + /// Initialize AES with variant calculated out of key length: + /// - 16 bytes (AES-128) + /// - 24 bytes (AES-192) + /// - 32 bytes (AES-256) + /// + /// - parameter key: Key. Length of the key decides on AES variant. + /// - parameter iv: Initialization Vector (Optional for some blockMode values) + /// - parameter blockMode: Cipher mode of operation + /// - parameter padding: Padding method. .pkcs7, .noPadding, .zeroPadding, ... + /// + /// - throws: AES.Error + /// + /// - returns: Instance + public init(key: Array, blockMode: BlockMode, padding: Padding = .pkcs7) throws { + self.key = Key(bytes: key) + self.blockMode = blockMode + self.padding = padding + self.keySize = self.key.count + + // Validate key size + switch keySize * 8 { + case 128: + variant = .aes128 + case 192: + variant = .aes192 + case 256: + variant = .aes256 + default: + throw Error.invalidKeySize + } + + variantNb = variant.Nb + variantNk = variant.Nk + variantNr = variant.Nr + } + + internal func encrypt(block: ArraySlice) -> Array? { + if blockMode.options.contains(.paddingRequired) && block.count != AES.blockSize { + return Array(block) + } + + let rounds = variantNr + let rk = expandedKey + + let b00 = UInt32(block[block.startIndex.advanced(by: 0)]) + let b01 = UInt32(block[block.startIndex.advanced(by: 1)]) << 8 + let b02 = UInt32(block[block.startIndex.advanced(by: 2)]) << 16 + let b03 = UInt32(block[block.startIndex.advanced(by: 3)]) << 24 + var b0 = b00 | b01 | b02 | b03 + + let b10 = UInt32(block[block.startIndex.advanced(by: 4)]) + let b11 = UInt32(block[block.startIndex.advanced(by: 5)]) << 8 + let b12 = UInt32(block[block.startIndex.advanced(by: 6)]) << 16 + let b13 = UInt32(block[block.startIndex.advanced(by: 7)]) << 24 + var b1 = b10 | b11 | b12 | b13 + + let b20 = UInt32(block[block.startIndex.advanced(by: 8)]) + let b21 = UInt32(block[block.startIndex.advanced(by: 9)]) << 8 + let b22 = UInt32(block[block.startIndex.advanced(by: 10)]) << 16 + let b23 = UInt32(block[block.startIndex.advanced(by: 11)]) << 24 + var b2 = b20 | b21 | b22 | b23 + + let b30 = UInt32(block[block.startIndex.advanced(by: 12)]) + let b31 = UInt32(block[block.startIndex.advanced(by: 13)]) << 8 + let b32 = UInt32(block[block.startIndex.advanced(by: 14)]) << 16 + let b33 = UInt32(block[block.startIndex.advanced(by: 15)]) << 24 + var b3 = b30 | b31 | b32 | b33 + + let tLength = 4 + let t = UnsafeMutablePointer.allocate(capacity: tLength) + t.initialize(repeating: 0, count: tLength) + defer { + t.deinitialize(count: tLength) + t.deallocate() + } + + for r in 0..> 8) & 0xff)] + let lb02 = AES.T2[Int((t[2] >> 16) & 0xff)] + let lb03 = AES.T3[Int(t[3] >> 24)] + b0 = lb00 ^ lb01 ^ lb02 ^ lb03 + + let lb10 = AES.T0[Int(t[1] & 0xff)] + let lb11 = AES.T1[Int((t[2] >> 8) & 0xff)] + let lb12 = AES.T2[Int((t[3] >> 16) & 0xff)] + let lb13 = AES.T3[Int(t[0] >> 24)] + b1 = lb10 ^ lb11 ^ lb12 ^ lb13 + + let lb20 = AES.T0[Int(t[2] & 0xff)] + let lb21 = AES.T1[Int((t[3] >> 8) & 0xff)] + let lb22 = AES.T2[Int((t[0] >> 16) & 0xff)] + let lb23 = AES.T3[Int(t[1] >> 24)] + b2 = lb20 ^ lb21 ^ lb22 ^ lb23 + + let lb30 = AES.T0[Int(t[3] & 0xff)] + let lb31 = AES.T1[Int((t[0] >> 8) & 0xff)] + let lb32 = AES.T2[Int((t[1] >> 16) & 0xff)] + let lb33 = AES.T3[Int(t[2] >> 24)] + b3 = lb30 ^ lb31 ^ lb32 ^ lb33 + } + + // last round + let r = rounds - 1 + + t[0] = b0 ^ rk[r][0] + t[1] = b1 ^ rk[r][1] + t[2] = b2 ^ rk[r][2] + t[3] = b3 ^ rk[r][3] + + // rounds + b0 = F1(t[0], t[1], t[2], t[3]) ^ rk[rounds][0] + b1 = F1(t[1], t[2], t[3], t[0]) ^ rk[rounds][1] + b2 = F1(t[2], t[3], t[0], t[1]) ^ rk[rounds][2] + b3 = F1(t[3], t[0], t[1], t[2]) ^ rk[rounds][3] + + let encrypted: Array = [ + UInt8(b0 & 0xff), UInt8((b0 >> 8) & 0xff), UInt8((b0 >> 16) & 0xff), UInt8((b0 >> 24) & 0xff), + UInt8(b1 & 0xff), UInt8((b1 >> 8) & 0xff), UInt8((b1 >> 16) & 0xff), UInt8((b1 >> 24) & 0xff), + UInt8(b2 & 0xff), UInt8((b2 >> 8) & 0xff), UInt8((b2 >> 16) & 0xff), UInt8((b2 >> 24) & 0xff), + UInt8(b3 & 0xff), UInt8((b3 >> 8) & 0xff), UInt8((b3 >> 16) & 0xff), UInt8((b3 >> 24) & 0xff), + ] + return encrypted + } + + internal func decrypt(block: ArraySlice) -> Array? { + if blockMode.options.contains(.paddingRequired) && block.count != AES.blockSize { + return Array(block) + } + + let rounds = variantNr + let rk = expandedKeyInv + + // Save miliseconds by not using `block.toUInt32Array()` + let b00 = UInt32(block[block.startIndex.advanced(by: 0)]) + let b01 = UInt32(block[block.startIndex.advanced(by: 1)]) << 8 + let b02 = UInt32(block[block.startIndex.advanced(by: 2)]) << 16 + let b03 = UInt32(block[block.startIndex.advanced(by: 3)]) << 24 + var b0 = b00 | b01 | b02 | b03 + + let b10 = UInt32(block[block.startIndex.advanced(by: 4)]) + let b11 = UInt32(block[block.startIndex.advanced(by: 5)]) << 8 + let b12 = UInt32(block[block.startIndex.advanced(by: 6)]) << 16 + let b13 = UInt32(block[block.startIndex.advanced(by: 7)]) << 24 + var b1 = b10 | b11 | b12 | b13 + + let b20 = UInt32(block[block.startIndex.advanced(by: 8)]) + let b21 = UInt32(block[block.startIndex.advanced(by: 9)]) << 8 + let b22 = UInt32(block[block.startIndex.advanced(by: 10)]) << 16 + let b23 = UInt32(block[block.startIndex.advanced(by: 11)]) << 24 + var b2 = b20 | b21 | b22 | b23 + + let b30 = UInt32(block[block.startIndex.advanced(by: 12)]) + let b31 = UInt32(block[block.startIndex.advanced(by: 13)]) << 8 + let b32 = UInt32(block[block.startIndex.advanced(by: 14)]) << 16 + let b33 = UInt32(block[block.startIndex.advanced(by: 15)]) << 24 + var b3 = b30 | b31 | b32 | b33 + + let tLength = 4 + let t = UnsafeMutablePointer.allocate(capacity: tLength) + t.initialize(repeating: 0, count: tLength) + defer { + t.deinitialize(count: tLength) + t.deallocate() + } + + for r in (2...rounds).reversed() { + t[0] = b0 ^ rk[r][0] + t[1] = b1 ^ rk[r][1] + t[2] = b2 ^ rk[r][2] + t[3] = b3 ^ rk[r][3] + + let b00 = AES.T0_INV[Int(t[0] & 0xff)] + let b01 = AES.T1_INV[Int((t[3] >> 8) & 0xff)] + let b02 = AES.T2_INV[Int((t[2] >> 16) & 0xff)] + let b03 = AES.T3_INV[Int(t[1] >> 24)] + b0 = b00 ^ b01 ^ b02 ^ b03 + + let b10 = AES.T0_INV[Int(t[1] & 0xff)] + let b11 = AES.T1_INV[Int((t[0] >> 8) & 0xff)] + let b12 = AES.T2_INV[Int((t[3] >> 16) & 0xff)] + let b13 = AES.T3_INV[Int(t[2] >> 24)] + b1 = b10 ^ b11 ^ b12 ^ b13 + + let b20 = AES.T0_INV[Int(t[2] & 0xff)] + let b21 = AES.T1_INV[Int((t[1] >> 8) & 0xff)] + let b22 = AES.T2_INV[Int((t[0] >> 16) & 0xff)] + let b23 = AES.T3_INV[Int(t[3] >> 24)] + b2 = b20 ^ b21 ^ b22 ^ b23 + + let b30 = AES.T0_INV[Int(t[3] & 0xff)] + let b31 = AES.T1_INV[Int((t[2] >> 8) & 0xff)] + let b32 = AES.T2_INV[Int((t[1] >> 16) & 0xff)] + let b33 = AES.T3_INV[Int(t[0] >> 24)] + b3 = b30 ^ b31 ^ b32 ^ b33 + } + + // last round + t[0] = b0 ^ rk[1][0] + t[1] = b1 ^ rk[1][1] + t[2] = b2 ^ rk[1][2] + t[3] = b3 ^ rk[1][3] + + // rounds + + let lb00 = sBoxInv[Int(B0(t[0]))] + let lb01 = (sBoxInv[Int(B1(t[3]))] << 8) + let lb02 = (sBoxInv[Int(B2(t[2]))] << 16) + let lb03 = (sBoxInv[Int(B3(t[1]))] << 24) + b0 = lb00 | lb01 | lb02 | lb03 ^ rk[0][0] + + let lb10 = sBoxInv[Int(B0(t[1]))] + let lb11 = (sBoxInv[Int(B1(t[0]))] << 8) + let lb12 = (sBoxInv[Int(B2(t[3]))] << 16) + let lb13 = (sBoxInv[Int(B3(t[2]))] << 24) + b1 = lb10 | lb11 | lb12 | lb13 ^ rk[0][1] + + let lb20 = sBoxInv[Int(B0(t[2]))] + let lb21 = (sBoxInv[Int(B1(t[1]))] << 8) + let lb22 = (sBoxInv[Int(B2(t[0]))] << 16) + let lb23 = (sBoxInv[Int(B3(t[3]))] << 24) + b2 = lb20 | lb21 | lb22 | lb23 ^ rk[0][2] + + let lb30 = sBoxInv[Int(B0(t[3]))] + let lb31 = (sBoxInv[Int(B1(t[2]))] << 8) + let lb32 = (sBoxInv[Int(B2(t[1]))] << 16) + let lb33 = (sBoxInv[Int(B3(t[0]))] << 24) + b3 = lb30 | lb31 | lb32 | lb33 ^ rk[0][3] + + let result: Array = [ + UInt8(b0 & 0xff), UInt8((b0 >> 8) & 0xff), UInt8((b0 >> 16) & 0xff), UInt8((b0 >> 24) & 0xff), + UInt8(b1 & 0xff), UInt8((b1 >> 8) & 0xff), UInt8((b1 >> 16) & 0xff), UInt8((b1 >> 24) & 0xff), + UInt8(b2 & 0xff), UInt8((b2 >> 8) & 0xff), UInt8((b2 >> 16) & 0xff), UInt8((b2 >> 24) & 0xff), + UInt8(b3 & 0xff), UInt8((b3 >> 8) & 0xff), UInt8((b3 >> 16) & 0xff), UInt8((b3 >> 24) & 0xff), + ] + return result + } +} + +private extension AES { + private func expandKeyInv(_ key: Key, variant: Variant) -> Array> { + let rounds = variantNr + var rk2: Array> = expandKey(key, variant: variant) + + for r in 1.. Array> { + func convertExpandedKey(_ expanded: Array) -> Array> { + return expanded.batched(by: 4).map({ UInt32(bytes: $0.reversed()) }).batched(by: 4).map { Array($0) } + } + + /* + * Function used in the Key Expansion routine that takes a four-byte + * input word and applies an S-box to each of the four bytes to + * produce an output word. + */ + func subWord(_ word: Array) -> Array { + precondition(word.count == 4) + + var result = word + for i in 0..<4 { + result[i] = UInt8(sBox[Int(word[i])]) + } + return result + } + + @inline(__always) + func subWordInPlace(_ word: inout Array) { + precondition(word.count == 4) + word[0] = UInt8(sBox[Int(word[0])]) + word[1] = UInt8(sBox[Int(word[1])]) + word[2] = UInt8(sBox[Int(word[2])]) + word[3] = UInt8(sBox[Int(word[3])]) + } + + let wLength = variantNb * (variantNr + 1) * 4 + let w = UnsafeMutablePointer.allocate(capacity: wLength) + w.initialize(repeating: 0, count: wLength) + defer { + w.deinitialize(count: wLength) + w.deallocate() + } + + for i in 0.. + + for i in variantNk..(repeating: 0, count: 4) + + for wordIdx in 0..<4 { + tmp[wordIdx] = w[4 * (i - 1) + wordIdx] + } + if (i % variantNk) == 0 { + tmp = subWord(rotateLeft(UInt32(bytes: tmp), by: 8).bytes(totalBytes: 4)) + tmp[0] = tmp.first! ^ AES.Rcon[i / variantNk] + } else if variantNk > 6 && (i % variantNk) == 4 { + subWordInPlace(&tmp) + } + + // xor array of bytes + for wordIdx in 0..<4 { + w[4 * i + wordIdx] = w[4 * (i - variantNk) + wordIdx] ^ tmp[wordIdx] + } + } + return convertExpandedKey(Array(UnsafeBufferPointer(start: w, count: wLength))) + } + + @inline(__always) + private func B0(_ x: UInt32) -> UInt32 { + return x & 0xff + } + + @inline(__always) + private func B1(_ x: UInt32) -> UInt32 { + return (x >> 8) & 0xff + } + + @inline(__always) + private func B2(_ x: UInt32) -> UInt32 { + return (x >> 16) & 0xff + } + + @inline(__always) + private func B3(_ x: UInt32) -> UInt32 { + return (x >> 24) & 0xff + } + + @inline(__always) + private func F1(_ x0: UInt32, _ x1: UInt32, _ x2: UInt32, _ x3: UInt32) -> UInt32 { + var result: UInt32 = 0 + result |= UInt32(B1(AES.T0[Int(x0 & 255)])) + result |= UInt32(B1(AES.T0[Int((x1 >> 8) & 255)])) << 8 + result |= UInt32(B1(AES.T0[Int((x2 >> 16) & 255)])) << 16 + result |= UInt32(B1(AES.T0[Int(x3 >> 24)])) << 24 + return result + } + + private func calculateSBox() -> (sBox: Array, invSBox: Array) { + let sboxLength = 256 + let sbox = UnsafeMutablePointer.allocate(capacity: sboxLength) + let invsbox = UnsafeMutablePointer.allocate(capacity: sboxLength) + sbox.initialize(repeating: 0, count: sboxLength) + invsbox.initialize(repeating: 0, count: sboxLength) + defer { + sbox.deinitialize(count: sboxLength) + sbox.deallocate() + invsbox.deinitialize(count: sboxLength) + invsbox.deallocate() + } + + sbox[0] = 0x63 + + var p: UInt8 = 1, q: UInt8 = 1 + + repeat { + p = p ^ (UInt8(truncatingIfNeeded: Int(p) << 1) ^ ((p & 0x80) == 0x80 ? 0x1b : 0)) + q ^= q << 1 + q ^= q << 2 + q ^= q << 4 + q ^= (q & 0x80) == 0x80 ? 0x09 : 0 + + let s = 0x63 ^ q ^ rotateLeft(q, by: 1) ^ rotateLeft(q, by: 2) ^ rotateLeft(q, by: 3) ^ rotateLeft(q, by: 4) + + sbox[Int(p)] = UInt32(s) + invsbox[Int(s)] = UInt32(p) + } while (p != 1) + + return (sBox: Array(UnsafeBufferPointer(start: sbox, count: sboxLength)), invSBox: Array(UnsafeBufferPointer(start: invsbox, count: sboxLength))) + } +} + +// MARK: Cipher + +extension AES: Cipher { + public func encrypt(_ bytes: ArraySlice) throws -> Array { + let chunks = bytes.batched(by: AES.blockSize) + + var oneTimeCryptor = try makeEncryptor() + var out = Array(reserveCapacity: bytes.count) + for chunk in chunks { + out += try oneTimeCryptor.update(withBytes: chunk, isLast: false) + } + // Padding may be added at the very end + out += try oneTimeCryptor.finish() + + if blockMode.options.contains(.paddingRequired) && (out.count % AES.blockSize != 0) { + throw Error.dataPaddingRequired + } + + return out + } + + public func decrypt(_ bytes: ArraySlice) throws -> Array { + if blockMode.options.contains(.paddingRequired) && (bytes.count % AES.blockSize != 0) { + throw Error.dataPaddingRequired + } + + var oneTimeCryptor = try makeDecryptor() + let chunks = bytes.batched(by: AES.blockSize) + if chunks.isEmpty { + throw Error.invalidData + } + + var out = Array(reserveCapacity: bytes.count) + + var lastIdx = chunks.startIndex + chunks.indices.formIndex(&lastIdx, offsetBy: chunks.count - 1) + + // To properly remove padding, `isLast` has to be known when called with the last chunk of ciphertext + // Last chunk of ciphertext may contains padded data so next call to update(..) won't be able to remove it + for idx in chunks.indices { + out += try oneTimeCryptor.update(withBytes: chunks[idx], isLast: idx == lastIdx) + } + return out + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Array+Extension.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Array+Extension.swift new file mode 100644 index 0000000000..752dcb8295 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Array+Extension.swift @@ -0,0 +1,148 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +extension Array { + public init(reserveCapacity: Int) { + self = Array() + self.reserveCapacity(reserveCapacity) + } + + var slice: ArraySlice { + return self[self.startIndex ..< self.endIndex] + } +} + +extension Array where Element == UInt8 { + public init(hex: String) { + self.init(reserveCapacity: hex.unicodeScalars.lazy.underestimatedCount) + var buffer: UInt8? + var skip = hex.hasPrefix("0x") ? 2 : 0 + for char in hex.unicodeScalars.lazy { + guard skip == 0 else { + skip -= 1 + continue + } + guard char.value >= 48 && char.value <= 102 else { + removeAll() + return + } + let v: UInt8 + let c: UInt8 = UInt8(char.value) + switch c { + case let c where c <= 57: + v = c - 48 + case let c where c >= 65 && c <= 70: + v = c - 55 + case let c where c >= 97: + v = c - 87 + default: + removeAll() + return + } + if let b = buffer { + append(b << 4 | v) + buffer = nil + } else { + buffer = v + } + } + if let b = buffer { + 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) + public func chunks(size chunksize: Int) -> Array> { + var words = Array>() + 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 crc32c(seed: UInt32? = nil, reflect: Bool = true) -> UInt32 { + return Checksum.crc32c(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(with authenticator: A) throws -> [Element] { + return try authenticator.authenticate(self) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Authenticator.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Authenticator.swift new file mode 100644 index 0000000000..03215a6467 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Authenticator.swift @@ -0,0 +1,20 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +/// Message authentication code. +public protocol Authenticator { + /// Calculate Message Authentication Code (MAC) for message. + func authenticate(_ bytes: Array) throws -> Array +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BatchedCollection.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BatchedCollection.swift new file mode 100644 index 0000000000..575bc1fc06 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BatchedCollection.swift @@ -0,0 +1,63 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +struct BatchedCollectionIndex { + let range: Range +} + +extension BatchedCollectionIndex: Comparable { + static func == (lhs: BatchedCollectionIndex, rhs: BatchedCollectionIndex) -> Bool { + return lhs.range.lowerBound == rhs.range.lowerBound + } + + static func < (lhs: BatchedCollectionIndex, rhs: BatchedCollectionIndex) -> Bool { + return lhs.range.lowerBound < rhs.range.lowerBound + } +} + +protocol BatchedCollectionType: Collection { + associatedtype Base: Collection +} + +struct BatchedCollection: Collection { + let base: Base + let size: Int + typealias Index = BatchedCollectionIndex + private func nextBreak(after idx: Base.Index) -> Base.Index { + return base.index(idx, offsetBy: size, limitedBy: base.endIndex) ?? base.endIndex + } + + var startIndex: Index { + return Index(range: base.startIndex.. Index { + return Index(range: idx.range.upperBound.. Base.SubSequence { + return base[idx.range] + } +} + +extension Collection { + func batched(by size: Int) -> BatchedCollection { + return BatchedCollection(base: self, size: size) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Bit.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Bit.swift new file mode 100644 index 0000000000..2e9552ed30 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Bit.swift @@ -0,0 +1,25 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 enum Bit: Int { + case zero + case one +} + +extension Bit { + func inverted() -> Bit { + return self == .zero ? .one : .zero + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockCipher.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockCipher.swift new file mode 100644 index 0000000000..b3c1ffa90b --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockCipher.swift @@ -0,0 +1,18 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +protocol BlockCipher: Cipher { + static var blockSize: Int { get } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockDecryptor.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockDecryptor.swift new file mode 100644 index 0000000000..7990a402bf --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockDecryptor.swift @@ -0,0 +1,85 @@ +// CryptoSwift +// +// Copyright (C) 2014-2018 Marcin Krzyżanowski +// 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 class BlockDecryptor: Cryptor, Updatable { + private let blockSize: Int + private let padding: Padding + private var worker: CipherModeWorker + private var accumulated = Array() + + init(blockSize: Int, padding: Padding, _ worker: CipherModeWorker) throws { + self.blockSize = blockSize + self.padding = padding + self.worker = worker + } + + public func update(withBytes bytes: ArraySlice, isLast: Bool = false) throws -> Array { + accumulated += bytes + + // If a worker (eg GCM) can combine ciphertext + tag + // we need to remove tag from the ciphertext. + if !isLast && accumulated.count < blockSize + worker.additionalBufferSize { + return [] + } + + let accumulatedWithoutSuffix: Array + if worker.additionalBufferSize > 0 { + // FIXME: how slow is that? + accumulatedWithoutSuffix = Array(accumulated.prefix(accumulated.count - worker.additionalBufferSize)) + } else { + accumulatedWithoutSuffix = accumulated + } + + var processedBytesCount = 0 + var plaintext = Array(reserveCapacity: accumulatedWithoutSuffix.count) + // Processing in a block-size manner. It's good for block modes, but bad for stream modes. + for var chunk in accumulatedWithoutSuffix.batched(by: blockSize) { + if isLast || (accumulatedWithoutSuffix.count - processedBytesCount) >= blockSize { + let isLastChunk = processedBytesCount + chunk.count == accumulatedWithoutSuffix.count + + if isLast, isLastChunk, var finalizingWorker = worker as? FinalizingDecryptModeWorker { + chunk = try finalizingWorker.willDecryptLast(bytes: chunk + accumulated.suffix(worker.additionalBufferSize)) // tag size + } + + if !chunk.isEmpty { + plaintext += worker.decrypt(block: chunk) + } + + if isLast, isLastChunk, var finalizingWorker = worker as? FinalizingDecryptModeWorker { + plaintext = Array(try finalizingWorker.didDecryptLast(bytes: plaintext.slice)) + } + + processedBytesCount += chunk.count + } + } + accumulated.removeFirst(processedBytesCount) // super-slow + + if isLast { + plaintext = padding.remove(from: plaintext, blockSize: blockSize) + } + + return plaintext + } + + public func seek(to position: Int) throws { + guard var worker = self.worker as? SeekableModeWorker else { + fatalError("Not supported") + } + + try worker.seek(to: position) + self.worker = worker + + accumulated = [] + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockEncryptor.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockEncryptor.swift new file mode 100644 index 0000000000..ba3fe28104 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockEncryptor.swift @@ -0,0 +1,57 @@ +// CryptoSwift +// +// Copyright (C) 2014-2018 Marcin Krzyżanowski +// 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. +// +final class BlockEncryptor: Cryptor, Updatable { + private let blockSize: Int + private var worker: CipherModeWorker + private let padding: Padding + // Accumulated bytes. Not all processed bytes. + private var accumulated = Array(reserveCapacity: 16) + + private var lastBlockRemainder = 0 + + init(blockSize: Int, padding: Padding, _ worker: CipherModeWorker) throws { + self.blockSize = blockSize + self.padding = padding + self.worker = worker + } + + // MARK: Updatable + public func update(withBytes bytes: ArraySlice, isLast: Bool) throws -> Array { + accumulated += bytes + + if isLast { + accumulated = padding.add(to: accumulated, blockSize: blockSize) + } + + var encrypted = Array(reserveCapacity: accumulated.count) + for chunk in accumulated.batched(by: blockSize) { + if isLast || chunk.count == blockSize { + encrypted += worker.encrypt(block: chunk) + } + } + + // Stream encrypts all, so it removes all elements + accumulated.removeFirst(encrypted.count) + + if var finalizingWorker = worker as? FinalizingEncryptModeWorker, isLast == true { + encrypted = Array(try finalizingWorker.finalize(encrypt: encrypted.slice)) + } + + return encrypted + } + + func seek(to: Int) throws { + fatalError("Not supported") + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/BlockMode.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/BlockMode.swift new file mode 100644 index 0000000000..b78e27468a --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/BlockMode.swift @@ -0,0 +1,24 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 typealias CipherOperationOnBlock = (_ block: ArraySlice) -> Array? + +public protocol BlockMode { + var options: BlockModeOption { get } + //TODO: doesn't have to be public + func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker +} + +typealias StreamMode = BlockMode diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/BlockModeOptions.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/BlockModeOptions.swift new file mode 100644 index 0000000000..646184941f --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/BlockModeOptions.swift @@ -0,0 +1,27 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 struct BlockModeOption: OptionSet { + public let rawValue: Int + + public init(rawValue: Int) { + self.rawValue = rawValue + } + + static let none = BlockModeOption(rawValue: 1 << 0) + static let initializationVectorRequired = BlockModeOption(rawValue: 1 << 1) + static let paddingRequired = BlockModeOption(rawValue: 1 << 2) + static let useEncryptToDecrypt = BlockModeOption(rawValue: 1 << 3) +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/CBC.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/CBC.swift new file mode 100644 index 0000000000..f98d9bf6e9 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/CBC.swift @@ -0,0 +1,70 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// Cipher-block chaining (CBC) +// + +public struct CBC: BlockMode { + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + } + + public let options: BlockModeOption = [.initializationVectorRequired, .paddingRequired] + private let iv: Array + + public init(iv: Array) { + self.iv = iv + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if iv.count != blockSize { + throw Error.invalidInitializationVector + } + + return CBCModeWorker(blockSize: blockSize, iv: iv.slice, cipherOperation: cipherOperation) + } +} + +struct CBCModeWorker: BlockModeWorker { + let cipherOperation: CipherOperationOnBlock + var blockSize: Int + let additionalBufferSize: Int = 0 + private let iv: ArraySlice + private var prev: ArraySlice? + + init(blockSize: Int, iv: ArraySlice, cipherOperation: @escaping CipherOperationOnBlock) { + self.blockSize = blockSize + self.iv = iv + self.cipherOperation = cipherOperation + } + + mutating func encrypt(block plaintext: ArraySlice) -> Array { + guard let ciphertext = cipherOperation(xor(prev ?? iv, plaintext)) else { + return Array(plaintext) + } + prev = ciphertext.slice + return ciphertext + } + + mutating func decrypt(block ciphertext: ArraySlice) -> Array { + guard let plaintext = cipherOperation(ciphertext) else { + return Array(ciphertext) + } + let result: Array = xor(prev ?? iv, plaintext) + prev = ciphertext + return result + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/CCM.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/CCM.swift new file mode 100644 index 0000000000..fb59ebe949 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/CCM.swift @@ -0,0 +1,359 @@ +//// CryptoSwift +// +// Copyright (C) 2014-2018 Marcin Krzyżanowski +// 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. +// + +// CCM mode combines the well known CBC-MAC with the well known counter mode of encryption. +// https://tools.ietf.org/html/rfc3610 +// https://csrc.nist.gov/publications/detail/sp/800-38c/final + +#if canImport(Darwin) +import Darwin +#else +import Glibc +#endif + + +/// Counter with Cipher Block Chaining-Message Authentication Code +public struct CCM: StreamMode { + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + case invalidParameter + case fail + } + + public let options: BlockModeOption = [.initializationVectorRequired, .useEncryptToDecrypt] + private let nonce: Array + private let additionalAuthenticatedData: Array? + private let tagLength: Int + private let messageLength: Int // total message length. need to know in advance + + // `authenticationTag` nil for encryption, known tag for decryption + /// For encryption, the value is set at the end of the encryption. + /// For decryption, this is a known Tag to validate against. + public var authenticationTag: Array? + + /// Initialize CCM + /// + /// - Parameters: + /// - iv: Initialization vector. Nonce. Valid length between 7 and 13 bytes. + /// - tagLength: Authentication tag length, in bytes. Value of {4, 6, 8, 10, 12, 14, 16}. + /// - messageLength: Plaintext message length (excluding tag if attached). Length have to be provided in advance. + /// - additionalAuthenticatedData: Additional authenticated data. + public init(iv: Array, tagLength: Int, messageLength: Int, additionalAuthenticatedData: Array? = nil) { + self.nonce = iv + self.tagLength = tagLength + self.additionalAuthenticatedData = additionalAuthenticatedData + self.messageLength = messageLength // - tagLength + } + + /// Initialize CCM + /// + /// - Parameters: + /// - iv: Initialization vector. Nonce. Valid length between 7 and 13 bytes. + /// - tagLength: Authentication tag length, in bytes. Value of {4, 6, 8, 10, 12, 14, 16}. + /// - messageLength: Plaintext message length (excluding tag if attached). Length have to be provided in advance. + /// - authenticationTag: Authentication Tag value if not concatenated to ciphertext. + /// - additionalAuthenticatedData: Additional authenticated data. + public init(iv: Array, tagLength: Int, messageLength: Int, authenticationTag: Array, additionalAuthenticatedData: Array? = nil) { + self.init(iv: iv, tagLength: tagLength, messageLength: messageLength, additionalAuthenticatedData: additionalAuthenticatedData) + self.authenticationTag = authenticationTag + } + + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if nonce.isEmpty { + throw Error.invalidInitializationVector + } + + return CCMModeWorker(blockSize: blockSize, nonce: nonce.slice, messageLength: messageLength, additionalAuthenticatedData: additionalAuthenticatedData, tagLength: tagLength, cipherOperation: cipherOperation) + } +} + +class CCMModeWorker: StreamModeWorker, SeekableModeWorker, CounterModeWorker, FinalizingEncryptModeWorker, FinalizingDecryptModeWorker { + typealias Counter = Int + var counter = 0 + + let cipherOperation: CipherOperationOnBlock + let blockSize: Int + private let tagLength: Int + private let messageLength: Int // total message length. need to know in advance + private let q: UInt8 + + let additionalBufferSize: Int + private var keystreamPosIdx = 0 + private let nonce: Array + private var last_y: ArraySlice = [] + private var keystream: Array = [] + // Known Tag used to validate during decryption + private var expectedTag: Array? + + public enum Error: Swift.Error { + case invalidParameter + } + + init(blockSize: Int, nonce: ArraySlice, messageLength: Int, additionalAuthenticatedData: [UInt8]?, expectedTag: Array? = nil, tagLength: Int, cipherOperation: @escaping CipherOperationOnBlock) { + self.blockSize = 16 // CCM is defined for 128 block size + self.tagLength = tagLength + self.additionalBufferSize = tagLength + self.messageLength = messageLength + self.expectedTag = expectedTag + self.cipherOperation = cipherOperation + self.nonce = Array(nonce) + self.q = UInt8(15 - nonce.count) // n = 15-q + + let hasAssociatedData = additionalAuthenticatedData != nil && !additionalAuthenticatedData!.isEmpty + processControlInformation(nonce: self.nonce, tagLength: tagLength, hasAssociatedData: hasAssociatedData) + + if let aad = additionalAuthenticatedData, hasAssociatedData { + process(aad: aad) + } + } + + // For the very first time setup new IV (aka y0) from the block0 + private func processControlInformation(nonce: [UInt8], tagLength: Int, hasAssociatedData: Bool) { + let block0 = try! format(nonce: nonce, Q: UInt32(messageLength), q: q, t: UInt8(tagLength), hasAssociatedData: hasAssociatedData).slice + let y0 = cipherOperation(block0)!.slice + last_y = y0 + } + + private func process(aad: [UInt8]) { + let encodedAAD = format(aad: aad) + + for block_i in encodedAAD.batched(by: 16) { + let y_i = cipherOperation(xor(block_i, last_y))!.slice + last_y = y_i + } + } + + private func S(i: Int) throws -> [UInt8] { + let ctr = try format(counter: i, nonce: nonce, q: q) + return cipherOperation(ctr.slice)! + } + + func seek(to position: Int) throws { + self.counter = position + keystream = try S(i: position) + let offset = position % blockSize + keystreamPosIdx = offset + } + + func encrypt(block plaintext: ArraySlice) -> Array { + var result = Array(reserveCapacity: plaintext.count) + + var processed = 0 + while processed < plaintext.count { + // Need a full block here to update keystream and do CBC + if keystream.isEmpty || keystreamPosIdx == blockSize { + // y[i], where i is the counter. Can encrypt 1 block at a time + counter += 1 + guard let S = try? S(i: counter) else { return Array(plaintext) } + let plaintextP = addPadding(Array(plaintext), blockSize: blockSize) + guard let y = cipherOperation(xor(last_y, plaintextP)) else { return Array(plaintext) } + last_y = y.slice + + keystream = S + keystreamPosIdx = 0 + } + + let xored: Array = xor(plaintext[plaintext.startIndex.advanced(by: processed)...], keystream[keystreamPosIdx...]) + keystreamPosIdx += xored.count + processed += xored.count + result += xored + } + return result + } + + func finalize(encrypt ciphertext: ArraySlice) throws -> ArraySlice { + // concatenate T at the end + guard let S0 = try? S(i: 0) else { return ciphertext } + + let computedTag = xor(last_y.prefix(tagLength), S0) as ArraySlice + return ciphertext + computedTag + } + + // Decryption is stream + // CBC is block + private var accumulatedPlaintext: [UInt8] = [] + + func decrypt(block ciphertext: ArraySlice) -> Array { + var output = Array(reserveCapacity: ciphertext.count) + + do { + var currentCounter = counter + var processed = 0 + while processed < ciphertext.count { + // Need a full block here to update keystream and do CBC + // New keystream for a new block + if keystream.isEmpty || keystreamPosIdx == blockSize { + currentCounter += 1 + guard let S = try? S(i: currentCounter) else { return Array(ciphertext) } + keystream = S + keystreamPosIdx = 0 + } + + let xored: Array = xor(ciphertext[ciphertext.startIndex.advanced(by: processed)...], keystream[keystreamPosIdx...]) // plaintext + keystreamPosIdx += xored.count + processed += xored.count + output += xored + counter = currentCounter + } + } + + // Accumulate plaintext for the MAC calculations at the end. + // It would be good to process it together though, here. + accumulatedPlaintext += output + + // Shouldn't return plaintext until validate tag. + // With incremental update, can't validate tag until all block are processed. + return output + } + + func finalize(decrypt plaintext: ArraySlice) throws -> ArraySlice { + // concatenate T at the end + let computedTag = Array(last_y.prefix(tagLength)) + guard let expectedTag = self.expectedTag, expectedTag == computedTag else { + throw CCM.Error.fail + } + + return plaintext + } + + @discardableResult + func willDecryptLast(bytes ciphertext: ArraySlice) throws -> ArraySlice { + // get tag of additionalBufferSize size + // `ciphertext` contains at least additionalBufferSize bytes + // overwrite expectedTag property used later for verification + guard let S0 = try? S(i: 0) else { return ciphertext } + self.expectedTag = xor(ciphertext.suffix(tagLength), S0) as [UInt8] + return ciphertext[ciphertext.startIndex..) throws -> ArraySlice { + + // Calculate Tag, from the last CBC block, for accumulated plaintext. + var processed = 0 + for block in accumulatedPlaintext.batched(by: blockSize) { + let blockP = addPadding(Array(block), blockSize: blockSize) + guard let y = cipherOperation(xor(last_y, blockP)) else { return plaintext } + last_y = y.slice + processed += block.count + } + accumulatedPlaintext.removeFirst(processed) + return plaintext + } +} + +// Q - octet length of P +// q - octet length of Q. Maximum length (in octets) of payload. An element of {2,3,4,5,6,7,8} +// t - octet length of T (MAC length). An element of {4,6,8,10,12,14,16} +private func format(nonce N: [UInt8], Q: UInt32, q: UInt8, t: UInt8, hasAssociatedData: Bool) throws -> [UInt8] { + var flags0: UInt8 = 0 + + if hasAssociatedData { + // 7 bit + flags0 |= (1 << 6) + } + + // 6,5,4 bit is t in 3 bits + flags0 |= (((t-2)/2) & 0x07) << 3 + + // 3,2,1 bit is q in 3 bits + flags0 |= ((q-1) & 0x07) << 0 + + var block0: [UInt8] = Array(repeating: 0, count: 16) + block0[0] = flags0 + + // N in 1...(15-q) octets, n = 15-q + // n is an element of {7,8,9,10,11,12,13} + let n = 15-Int(q) + guard (n + Int(q)) == 15 else { + // n+q == 15 + throw CCMModeWorker.Error.invalidParameter + } + block0[1...n] = N[0...(n-1)] + + // Q in (16-q)...15 octets + block0[(16-Int(q))...15] = Q.bytes(totalBytes: Int(q)).slice + + return block0 +} + +/// Formatting of the Counter Blocks. Ctr[i] +/// The counter generation function. +/// Q - octet length of P +/// q - octet length of Q. Maximum length (in octets) of payload. An element of {2,3,4,5,6,7,8} +private func format(counter i: Int, nonce N: [UInt8], q: UInt8) throws -> [UInt8] { + var flags0: UInt8 = 0 + + // bit 8,7 is Reserved + // bit 4,5,6 shall be set to 0 + // 3,2,1 bit is q in 3 bits + flags0 |= ((q-1) & 0x07) << 0 + + var block = Array(repeating: 0, count: 16) // block[0] + block[0] = flags0 + + // N in 1...(15-q) octets, n = 15-q + // n is an element of {7,8,9,10,11,12,13} + let n = 15-Int(q) + guard (n + Int(q)) == 15 else { + // n+q == 15 + throw CCMModeWorker.Error.invalidParameter + } + block[1...n] = N[0...(n-1)] + + // [i]8q in (16-q)...15 octets + block[(16-Int(q))...15] = i.bytes(totalBytes: Int(q)).slice + + return block +} + +/// Resulting can be partitioned into 16-octet blocks +private func format(aad: [UInt8]) -> [UInt8] { + let a = aad.count + + switch Double(a) { + case 0..<65280: // 2^16-2^8 + // [a]16 + return addPadding(a.bytes(totalBytes: 2) + aad, blockSize: 16) + case 65280..<4_294_967_296: // 2^32 + // [a]32 + return addPadding([0xFF, 0xFE] + a.bytes(totalBytes: 4) + aad, blockSize: 16) + case 4_294_967_296.., blockSize: Int) -> Array { + if bytes.isEmpty { + return Array(repeating: 0, count: blockSize) + } + + let remainder = bytes.count % blockSize + if remainder == 0 { + return bytes + } + + let paddingCount = blockSize - remainder + if paddingCount > 0 { + return bytes + Array(repeating: 0, count: paddingCount) + } + return bytes +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/CFB.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/CFB.swift new file mode 100644 index 0000000000..316283cba3 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/CFB.swift @@ -0,0 +1,70 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// Cipher feedback (CFB) +// + +public struct CFB: BlockMode { + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + } + + public let options: BlockModeOption = [.initializationVectorRequired, .useEncryptToDecrypt] + private let iv: Array + + public init(iv: Array) { + self.iv = iv + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if iv.count != blockSize { + throw Error.invalidInitializationVector + } + + return CFBModeWorker(blockSize: blockSize, iv: iv.slice, cipherOperation: cipherOperation) + } +} + +struct CFBModeWorker: BlockModeWorker { + let cipherOperation: CipherOperationOnBlock + let blockSize: Int + let additionalBufferSize: Int = 0 + private let iv: ArraySlice + private var prev: ArraySlice? + + init(blockSize: Int, iv: ArraySlice, cipherOperation: @escaping CipherOperationOnBlock) { + self.blockSize = blockSize + self.iv = iv + self.cipherOperation = cipherOperation + } + + mutating func encrypt(block plaintext: ArraySlice) -> Array { + guard let ciphertext = cipherOperation(prev ?? iv) else { + return Array(plaintext) + } + prev = xor(plaintext, ciphertext.slice) + return Array(prev ?? []) + } + + mutating func decrypt(block ciphertext: ArraySlice) -> Array { + guard let plaintext = cipherOperation(prev ?? iv) else { + return Array(ciphertext) + } + let result: Array = xor(plaintext, ciphertext) + prev = ciphertext + return result + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/CTR.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/CTR.swift new file mode 100644 index 0000000000..2dc6a9ecb3 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/CTR.swift @@ -0,0 +1,134 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// Counter (CTR) + +public struct CTR: StreamMode { + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + } + + public let options: BlockModeOption = [.initializationVectorRequired, .useEncryptToDecrypt] + private let iv: Array + private let counter: Int + + public init(iv: Array, counter: Int = 0) { + self.iv = iv + self.counter = counter + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if iv.count != blockSize { + throw Error.invalidInitializationVector + } + + return CTRModeWorker(blockSize: blockSize, iv: iv.slice, counter: counter, cipherOperation: cipherOperation) + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +struct CTRModeWorker: StreamModeWorker, SeekableModeWorker, CounterModeWorker { + typealias Counter = CTRCounter + + final class CTRCounter { + private let constPrefix: Array + private var value: UInt64 + //TODO: make it an updatable value, computing is too slow + var bytes: Array { + return constPrefix + value.bytes() + } + + init(_ initialValue: Array) { + let halfIndex = initialValue.startIndex.advanced(by: initialValue.count / 2) + constPrefix = Array(initialValue[initialValue.startIndex.., startAt index: Int) { + self.init(buildCounterValue(nonce, counter: UInt64(index))) + } + + static func +=(lhs: CTRCounter, rhs: Int) { + lhs.value += UInt64(rhs) + } + } + + let cipherOperation: CipherOperationOnBlock + let additionalBufferSize: Int = 0 + let iv: Array + var counter: CTRCounter + + private let blockSize: Int + + // The same keystream is used for the block length plaintext + // As new data is added, keystream suffix is used to xor operation. + private var keystream: Array + private var keystreamPosIdx = 0 + + init(blockSize: Int, iv: ArraySlice, counter: Int, cipherOperation: @escaping CipherOperationOnBlock) { + self.cipherOperation = cipherOperation + self.blockSize = blockSize + self.iv = Array(iv) + + // the first keystream is calculated from the nonce = initial value of counter + self.counter = CTRCounter(nonce: Array(iv), startAt: counter) + self.keystream = Array(cipherOperation(self.counter.bytes.slice)!) + } + + mutating func seek(to position: Int) throws { + let offset = position % blockSize + counter = CTRCounter(nonce: iv, startAt: position / blockSize) + keystream = Array(cipherOperation(counter.bytes.slice)!) + keystreamPosIdx = offset + } + + // plaintext is at most blockSize long + mutating func encrypt(block plaintext: ArraySlice) -> Array { + var result = Array(reserveCapacity: plaintext.count) + + var processed = 0 + while processed < plaintext.count { + // Update keystream + if keystreamPosIdx == blockSize { + counter += 1 + keystream = Array(cipherOperation(counter.bytes.slice)!) + keystreamPosIdx = 0 + } + + let xored: Array = xor(plaintext[plaintext.startIndex.advanced(by: processed)...], keystream[keystreamPosIdx...]) + keystreamPosIdx += xored.count + processed += xored.count + result += xored + } + + return result + } + + mutating func decrypt(block ciphertext: ArraySlice) -> Array { + return encrypt(block: ciphertext) + } +} + +private func buildCounterValue(_ iv: Array, counter: UInt64) -> Array { + let noncePartLen = iv.count / 2 + let noncePrefix = iv[iv.startIndex.. +// 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 protocol CipherModeWorker { + var cipherOperation: CipherOperationOnBlock { get } + + // Additional space needed when incrementally process data + // eg. for GCM combined mode + var additionalBufferSize: Int { get } + + mutating func encrypt(block plaintext: ArraySlice) -> Array + mutating func decrypt(block ciphertext: ArraySlice) -> Array +} + +/// Block workers use `BlockEncryptor` +public protocol BlockModeWorker: CipherModeWorker { + var blockSize: Int { get } +} + +public protocol CounterModeWorker: CipherModeWorker { + associatedtype Counter + var counter: Counter { get set } +} + +public protocol SeekableModeWorker: CipherModeWorker { + mutating func seek(to position: Int) throws +} + +/// Stream workers use `StreamEncryptor` +public protocol StreamModeWorker: CipherModeWorker { +} + +public protocol FinalizingEncryptModeWorker: CipherModeWorker { + // Any final calculations, eg. calculate tag + // Called after the last block is encrypted + mutating func finalize(encrypt ciphertext: ArraySlice) throws -> ArraySlice +} + +public protocol FinalizingDecryptModeWorker: CipherModeWorker { + // Called before decryption, hence input is ciphertext. + // ciphertext is either a last block, or a tag (for stream workers) + @discardableResult + mutating func willDecryptLast(bytes ciphertext: ArraySlice) throws -> ArraySlice + // Called after decryption, hence input is ciphertext + mutating func didDecryptLast(bytes plaintext: ArraySlice) throws -> ArraySlice + // Any final calculations, eg. calculate tag + // Called after the last block is encrypted + mutating func finalize(decrypt plaintext: ArraySlice) throws -> ArraySlice +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/ECB.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/ECB.swift new file mode 100644 index 0000000000..ce410b3074 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/ECB.swift @@ -0,0 +1,51 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// Electronic codebook (ECB) +// + +public struct ECB: BlockMode { + public let options: BlockModeOption = .paddingRequired + + public init() { + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + return ECBModeWorker(blockSize: blockSize, cipherOperation: cipherOperation) + } +} + +struct ECBModeWorker: BlockModeWorker { + typealias Element = Array + let cipherOperation: CipherOperationOnBlock + let blockSize: Int + let additionalBufferSize: Int = 0 + + init(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock) { + self.blockSize = blockSize + self.cipherOperation = cipherOperation + } + + mutating func encrypt(block plaintext: ArraySlice) -> Array { + guard let ciphertext = cipherOperation(plaintext) else { + return Array(plaintext) + } + return ciphertext + } + + mutating func decrypt(block ciphertext: ArraySlice) -> Array { + return encrypt(block: ciphertext) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/GCM.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/GCM.swift new file mode 100644 index 0000000000..d9bf5d94d9 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/GCM.swift @@ -0,0 +1,370 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// Galois/Counter Mode (GCM) +// https://csrc.nist.gov/publications/detail/sp/800-38d/final +// ref: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.694.695&rep=rep1&type=pdf +// + +public final class GCM: BlockMode { + public enum Mode { + /// In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want. + case combined + /// Some applications may need to store the authentication tag and the encrypted message at different locations. + case detached + } + + public let options: BlockModeOption = [.initializationVectorRequired, .useEncryptToDecrypt] + + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + /// Special symbol FAIL that indicates that the inputs are not authentic. + case fail + } + + private let iv: Array + private let additionalAuthenticatedData: Array? + private let mode: Mode + + /// Length of authentication tag, in bytes. + /// For encryption, the value is given as init parameter. + /// For decryption, the lenght of given authentication tag is used. + private let tagLength: Int + + // `authenticationTag` nil for encryption, known tag for decryption + /// For encryption, the value is set at the end of the encryption. + /// For decryption, this is a known Tag to validate against. + public var authenticationTag: Array? + + // encrypt + /// Possible tag lengths: 4,8,12,13,14,15,16 + public init(iv: Array, additionalAuthenticatedData: Array? = nil, tagLength: Int = 16, mode: Mode = .detached) { + self.iv = iv + self.additionalAuthenticatedData = additionalAuthenticatedData + self.mode = mode + self.tagLength = tagLength + } + + // decrypt + public convenience init(iv: Array, authenticationTag: Array, additionalAuthenticatedData: Array? = nil, mode: Mode = .detached) { + self.init(iv: iv, additionalAuthenticatedData: additionalAuthenticatedData, tagLength: authenticationTag.count, mode: mode) + self.authenticationTag = authenticationTag + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if iv.isEmpty { + throw Error.invalidInitializationVector + } + + let worker = GCMModeWorker(iv: iv.slice, aad: additionalAuthenticatedData?.slice, expectedTag: authenticationTag, tagLength: tagLength, mode: mode, cipherOperation: cipherOperation) + worker.didCalculateTag = { [weak self] tag in + self?.authenticationTag = tag + } + return worker + } +} + +// MARK: - Worker + +final class GCMModeWorker: BlockModeWorker, FinalizingEncryptModeWorker, FinalizingDecryptModeWorker { + let cipherOperation: CipherOperationOnBlock + + // Callback called when authenticationTag is ready + var didCalculateTag: ((Array) -> Void)? + + private let tagLength: Int + // GCM nonce is 96-bits by default. It's the most effective length for the IV + private static let nonceSize = 12 + + // GCM is designed for 128-bit ciphers like AES (but not really for Blowfish). 64-bit mode is not implemented. + let blockSize = 16 // 128 bit + let additionalBufferSize: Int + private let iv: ArraySlice + private let mode: GCM.Mode + private var counter: UInt128 + private let eky0: UInt128 // move to GF? + private let h: UInt128 + + // Additional authenticated data + private let aad: ArraySlice? + // Known Tag used to validate during decryption + private var expectedTag: Array? + + // Note: need new worker to reset instance + // Use empty aad if not specified. AAD is optional. + private lazy var gf: GF = { + if let aad = aad { + return GF(aad: Array(aad), h: h, blockSize: blockSize) + } + return GF(aad: [UInt8](), h: h, blockSize: blockSize) + }() + + init(iv: ArraySlice, aad: ArraySlice? = nil, expectedTag: Array? = nil, tagLength: Int, mode: GCM.Mode, cipherOperation: @escaping CipherOperationOnBlock) { + self.cipherOperation = cipherOperation + self.iv = iv + self.mode = mode + self.aad = aad + self.expectedTag = expectedTag + self.tagLength = tagLength + h = UInt128(cipherOperation(Array(repeating: 0, count: blockSize).slice)!) // empty block + + if mode == .combined { + self.additionalBufferSize = tagLength + } else { + self.additionalBufferSize = 0 + } + + // Assume nonce is 12 bytes long, otherwise initial counter would be calulated from GHASH + // counter = GF.ghash(aad: [UInt8](), ciphertext: nonce) + if iv.count == GCMModeWorker.nonceSize { + counter = makeCounter(nonce: Array(self.iv)) + } else { + counter = GF.ghash(h: h, aad: [UInt8](), ciphertext: Array(iv), blockSize: blockSize) + } + + // Set constants + eky0 = UInt128(cipherOperation(counter.bytes.slice)!) + } + + func encrypt(block plaintext: ArraySlice) -> Array { + counter = incrementCounter(counter) + + guard let ekyN = cipherOperation(counter.bytes.slice) else { + return Array(plaintext) + } + + // plaintext block ^ ek1 + let ciphertext = xor(plaintext, ekyN) as Array + + // update ghash incrementally + gf.ghashUpdate(block: ciphertext) + + return Array(ciphertext) + } + + func finalize(encrypt ciphertext: ArraySlice) throws -> ArraySlice { + // Calculate MAC tag. + let ghash = gf.ghashFinish() + let tag = Array((ghash ^ eky0).bytes.prefix(tagLength)) + + // Notify handler + didCalculateTag?(tag) + + switch mode { + case .combined: + return (ciphertext + tag).slice + case .detached: + return ciphertext + } + } + + func decrypt(block ciphertext: ArraySlice) -> Array { + counter = incrementCounter(counter) + + // update ghash incrementally + gf.ghashUpdate(block: Array(ciphertext)) + + guard let ekN = cipherOperation(counter.bytes.slice) else { + return Array(ciphertext) + } + + // ciphertext block ^ ek1 + let plaintext = xor(ciphertext, ekN) as Array + return plaintext + } + + // The authenticated decryption operation has five inputs: K, IV , C, A, and T. It has only a single + // output, either the plaintext value P or a special symbol FAIL that indicates that the inputs are not + // authentic. + @discardableResult + func willDecryptLast(bytes ciphertext: ArraySlice) throws -> ArraySlice { + // Validate tag + switch mode { + case .combined: + // overwrite expectedTag property used later for verification + self.expectedTag = Array(ciphertext.suffix(tagLength)) + return ciphertext[ciphertext.startIndex..) throws -> ArraySlice { + // Calculate MAC tag. + let ghash = gf.ghashFinish() + let computedTag = Array((ghash ^ eky0).bytes.prefix(tagLength)) + + // Validate tag + guard let expectedTag = self.expectedTag, computedTag == expectedTag else { + throw GCM.Error.fail + } + + return plaintext + } + + func finalize(decrypt plaintext: ArraySlice) throws -> ArraySlice { + // do nothing + return plaintext + } +} + +// MARK: - Local utils + +private func makeCounter(nonce: Array) -> UInt128 { + return UInt128(nonce + [0, 0, 0, 1]) +} + +// Successive counter values are generated using the function incr(), which treats the rightmost 32 +// bits of its argument as a nonnegative integer with the least significant bit on the right +private func incrementCounter(_ counter: UInt128) -> UInt128 { + let b = counter.i.b + 1 + let a = (b == 0 ? counter.i.a + 1 : counter.i.a) + return UInt128((a, b)) +} + +// If data is not a multiple of block size bytes long then the remainder is zero padded +// Note: It's similar to ZeroPadding, but it's not the same. +private func addPadding(_ bytes: Array, blockSize: Int) -> Array { + if bytes.isEmpty { + return Array(repeating: 0, count: blockSize) + } + + let remainder = bytes.count % blockSize + if remainder == 0 { + return bytes + } + + let paddingCount = blockSize - remainder + if paddingCount > 0 { + return bytes + Array(repeating: 0, count: paddingCount) + } + return bytes +} + +// MARK: - GF + +/// The Field GF(2^128) +private final class GF { + static let r = UInt128(a: 0xE100000000000000, b: 0) + + let blockSize: Int + let h: UInt128 + + // AAD won't change + let aadLength: Int + + // Updated for every consumed block + var ciphertextLength: Int + + // Start with 0 + var x: UInt128 + + init(aad: [UInt8], h: UInt128, blockSize: Int) { + self.blockSize = blockSize + aadLength = aad.count + ciphertextLength = 0 + self.h = h + x = 0 + + // Calculate for AAD at the begining + x = GF.calculateX(aad: aad, x: x, h: h, blockSize: blockSize) + } + + @discardableResult + func ghashUpdate(block ciphertextBlock: Array) -> UInt128 { + ciphertextLength += ciphertextBlock.count + x = GF.calculateX(block: addPadding(ciphertextBlock, blockSize: blockSize), x: x, h: h, blockSize: blockSize) + return x + } + + func ghashFinish() -> UInt128 { + // len(A) || len(C) + let len = UInt128(a: UInt64(aadLength * 8), b: UInt64(ciphertextLength * 8)) + x = GF.multiply((x ^ len), h) + return x + } + + // GHASH. One-time calculation + static func ghash(x startx: UInt128 = 0, h: UInt128, aad: Array, ciphertext: Array, blockSize: Int) -> UInt128 { + var x = calculateX(aad: aad, x: startx, h: h, blockSize: blockSize) + x = calculateX(ciphertext: ciphertext, x: x, h: h, blockSize: blockSize) + + // len(aad) || len(ciphertext) + let len = UInt128(a: UInt64(aad.count * 8), b: UInt64(ciphertext.count * 8)) + x = multiply((x ^ len), h) + + return x + } + + // Calculate Ciphertext part, for all blocks + // Not used with incremental calculation. + private static func calculateX(ciphertext: [UInt8], x startx: UInt128, h: UInt128, blockSize: Int) -> UInt128 { + let pciphertext = addPadding(ciphertext, blockSize: blockSize) + let blocksCount = pciphertext.count / blockSize + + var x = startx + for i in 0.., x: UInt128, h: UInt128, blockSize: Int) -> UInt128 { + let k = x ^ UInt128(ciphertextBlock) + return multiply(k, h) + } + + // Calculate AAD part, for all blocks + private static func calculateX(aad: [UInt8], x startx: UInt128, h: UInt128, blockSize: Int) -> UInt128 { + let paad = addPadding(aad, blockSize: blockSize) + let blocksCount = paad.count / blockSize + + var x = startx + for i in 0.. UInt128 { + var z: UInt128 = 0 + var v = x + var k = UInt128(a: 1 << 63, b: 0) + + for _ in 0..<128 { + if y & k == k { + z = z ^ v + } + + if v & 1 != 1 { + v = v >> 1 + } else { + v = (v >> 1) ^ r + } + + k = k >> 1 + } + + return z + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/OFB.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/OFB.swift new file mode 100644 index 0000000000..0f5c66a48f --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/OFB.swift @@ -0,0 +1,70 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// Output Feedback (OFB) +// + +public struct OFB: BlockMode { + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + } + + public let options: BlockModeOption = [.initializationVectorRequired, .useEncryptToDecrypt] + private let iv: Array + + public init(iv: Array) { + self.iv = iv + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if iv.count != blockSize { + throw Error.invalidInitializationVector + } + + return OFBModeWorker(blockSize: blockSize, iv: iv.slice, cipherOperation: cipherOperation) + } +} + +struct OFBModeWorker: BlockModeWorker { + let cipherOperation: CipherOperationOnBlock + let blockSize: Int + let additionalBufferSize: Int = 0 + private let iv: ArraySlice + private var prev: ArraySlice? + + init(blockSize: Int, iv: ArraySlice, cipherOperation: @escaping CipherOperationOnBlock) { + self.blockSize = blockSize + self.iv = iv + self.cipherOperation = cipherOperation + } + + mutating func encrypt(block plaintext: ArraySlice) -> Array { + guard let ciphertext = cipherOperation(prev ?? iv) else { + return Array(plaintext) + } + prev = ciphertext.slice + return xor(plaintext, ciphertext) + } + + mutating func decrypt(block ciphertext: ArraySlice) -> Array { + guard let decrypted = cipherOperation(prev ?? iv) else { + return Array(ciphertext) + } + let plaintext: Array = xor(decrypted, ciphertext) + prev = decrypted.slice + return plaintext + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/PCBC.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/PCBC.swift new file mode 100644 index 0000000000..846015d6aa --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/BlockMode/PCBC.swift @@ -0,0 +1,70 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// Propagating Cipher Block Chaining (PCBC) +// + +public struct PCBC: BlockMode { + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + } + + public let options: BlockModeOption = [.initializationVectorRequired, .paddingRequired] + private let iv: Array + + public init(iv: Array) { + self.iv = iv + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if iv.count != blockSize { + throw Error.invalidInitializationVector + } + + return PCBCModeWorker(blockSize: blockSize, iv: iv.slice, cipherOperation: cipherOperation) + } +} + +struct PCBCModeWorker: BlockModeWorker { + let cipherOperation: CipherOperationOnBlock + var blockSize: Int + let additionalBufferSize: Int = 0 + private let iv: ArraySlice + private var prev: ArraySlice? + + init(blockSize: Int, iv: ArraySlice, cipherOperation: @escaping CipherOperationOnBlock) { + self.blockSize = blockSize + self.iv = iv + self.cipherOperation = cipherOperation + } + + mutating func encrypt(block plaintext: ArraySlice) -> Array { + guard let ciphertext = cipherOperation(xor(prev ?? iv, plaintext)) else { + return Array(plaintext) + } + prev = xor(plaintext, ciphertext.slice) + return ciphertext + } + + mutating func decrypt(block ciphertext: ArraySlice) -> Array { + guard let plaintext = cipherOperation(ciphertext) else { + return Array(ciphertext) + } + let result: Array = xor(prev ?? iv, plaintext) + prev = xor(plaintext.slice, ciphertext) + return result + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Blowfish.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Blowfish.swift new file mode 100644 index 0000000000..34c771c27e --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Blowfish.swift @@ -0,0 +1,537 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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://en.wikipedia.org/wiki/Blowfish_(cipher) +// Based on Paul Kocher implementation +// + +public final class Blowfish { + public enum Error: Swift.Error { + /// Data padding is required + case dataPaddingRequired + /// Invalid key or IV + case invalidKeyOrInitializationVector + /// Invalid IV + case invalidInitializationVector + /// Invalid block mode + case invalidBlockMode + } + + public static let blockSize: Int = 8 // 64 bit + public let keySize: Int + + private let blockMode: BlockMode + private let padding: Padding + private var decryptWorker: CipherModeWorker! + private var encryptWorker: CipherModeWorker! + + private let N = 16 // rounds + private var P: Array + private var S: Array> + private let origP: Array = [ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, + 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, + 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, + 0xb5470917, 0x9216d5d9, 0x8979fb1b, + ] + + private let origS: Array> = [ + [ + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, + ], + [ + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, + ], + [ + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, + ], + [ + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6, + ], + ] + + public init(key: Array, blockMode: BlockMode = CBC(iv: Array(repeating: 0, count: Blowfish.blockSize)), padding: Padding) throws { + precondition(key.count >= 5 && key.count <= 56) + + self.blockMode = blockMode + self.padding = padding + keySize = key.count + + S = origS + P = origP + + expandKey(key: key) + try setupBlockModeWorkers() + } + + private func setupBlockModeWorkers() throws { + encryptWorker = try blockMode.worker(blockSize: Blowfish.blockSize, cipherOperation: encrypt) + + if blockMode.options.contains(.useEncryptToDecrypt) { + decryptWorker = try blockMode.worker(blockSize: Blowfish.blockSize, cipherOperation: encrypt) + } else { + decryptWorker = try blockMode.worker(blockSize: Blowfish.blockSize, cipherOperation: decrypt) + } + } + + private func reset() { + S = origS + P = origP + // todo expand key + } + + private func expandKey(key: Array) { + var j = 0 + for i in 0..<(N + 2) { + var data: UInt32 = 0x0 + for _ in 0..<4 { + data = (data << 8) | UInt32(key[j]) + j += 1 + if j >= key.count { + j = 0 + } + } + P[i] ^= data + } + + var datal: UInt32 = 0 + var datar: UInt32 = 0 + + for i in stride(from: 0, to: N + 2, by: 2) { + encryptBlowfishBlock(l: &datal, r: &datar) + P[i] = datal + P[i + 1] = datar + } + + for i in 0..<4 { + for j in stride(from: 0, to: 256, by: 2) { + encryptBlowfishBlock(l: &datal, r: &datar) + S[i][j] = datal + S[i][j + 1] = datar + } + } + } + + fileprivate func encrypt(block: ArraySlice) -> Array? { + var result = Array() + + var l = UInt32(bytes: block[block.startIndex..> 24) & 0xff), + UInt8((l >> 16) & 0xff), + ] + result += [ + UInt8((l >> 8) & 0xff), + UInt8((l >> 0) & 0xff), + ] + result += [ + UInt8((r >> 24) & 0xff), + UInt8((r >> 16) & 0xff), + ] + result += [ + UInt8((r >> 8) & 0xff), + UInt8((r >> 0) & 0xff), + ] + + return result + } + + fileprivate func decrypt(block: ArraySlice) -> Array? { + var result = Array() + + var l = UInt32(bytes: block[block.startIndex..> 24) & 0xff), + UInt8((l >> 16) & 0xff), + ] + result += [ + UInt8((l >> 8) & 0xff), + UInt8((l >> 0) & 0xff), + ] + result += [ + UInt8((r >> 24) & 0xff), + UInt8((r >> 16) & 0xff), + ] + result += [ + UInt8((r >> 8) & 0xff), + UInt8((r >> 0) & 0xff), + ] + return result + } + + /// Encrypts the 8-byte padded buffer + /// + /// - Parameters: + /// - l: left half + /// - r: right half + fileprivate func encryptBlowfishBlock(l: inout UInt32, r: inout UInt32) { + var Xl = l + var Xr = r + + for i in 0.. UInt32 { + let f1 = S[0][Int(x >> 24) & 0xff] + let f2 = S[1][Int(x >> 16) & 0xff] + let f3 = S[2][Int(x >> 8) & 0xff] + let f4 = S[3][Int(x & 0xff)] + return ((f1 &+ f2) ^ f3) &+ f4 + } +} + +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(_ bytes: C) throws -> Array where C.Element == UInt8, C.Index == Int { + let bytes = padding.add(to: Array(bytes), blockSize: Blowfish.blockSize) // FIXME: Array(bytes) copies + + var out = Array() + out.reserveCapacity(bytes.count) + + for chunk in bytes.batched(by: Blowfish.blockSize) { + out += encryptWorker.encrypt(block: chunk) + } + + if blockMode.options.contains(.paddingRequired) && (out.count % Blowfish.blockSize != 0) { + throw Error.dataPaddingRequired + } + + return out + } + + /// Decrypt the 8-byte padded buffer + /// + /// - Parameter bytes: Ciphertext data + /// - Returns: Plaintext data + public func decrypt(_ bytes: C) throws -> Array where C.Element == UInt8, C.Index == Int { + if blockMode.options.contains(.paddingRequired) && (bytes.count % Blowfish.blockSize != 0) { + throw Error.dataPaddingRequired + } + + var out = Array() + out.reserveCapacity(bytes.count) + + for chunk in Array(bytes).batched(by: Blowfish.blockSize) { + out += decryptWorker.decrypt(block: chunk) // FIXME: copying here is innefective + } + + out = padding.remove(from: out, blockSize: Blowfish.blockSize) + + return out + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/CBCMAC.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/CBCMAC.swift new file mode 100644 index 0000000000..e14f2bd520 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/CBCMAC.swift @@ -0,0 +1,104 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 class CBCMAC: Authenticator { + public enum Error: Swift.Error { + case wrongKeyLength + } + + private let key: SecureBytes + + private static let BlockSize: Int = 16 + private static let Zero: Array = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + private static let Rb: Array = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87] + + public init(key: Array) throws { + if key.count != 16 { + throw Error.wrongKeyLength + } + self.key = SecureBytes(bytes: key) + } + + // MARK: Authenticator + + public func authenticate(_ bytes: Array) throws -> Array { + let aes = try AES(key: Array(key), blockMode: CBC(iv: CBCMAC.Zero), padding: .noPadding) + + let l = try aes.encrypt(CBCMAC.Zero) + var subKey1 = leftShiftOneBit(l) + if (l[0] & 0x80) != 0 { + subKey1 = xor(CBCMAC.Rb, subKey1) + } + var subKey2 = leftShiftOneBit(subKey1) + if (subKey1[0] & 0x80) != 0 { + subKey2 = xor(CBCMAC.Rb, subKey2) + } + + let lastBlockComplete: Bool + let blockCount = (bytes.count + CBCMAC.BlockSize - 1) / CBCMAC.BlockSize + if blockCount == 0 { + lastBlockComplete = false + } else { + lastBlockComplete = bytes.count % CBCMAC.BlockSize == 0 + } + var paddedBytes = bytes + if !lastBlockComplete { + bitPadding(to: &paddedBytes, blockSize: CBCMAC.BlockSize) + } + + var blocks = Array(paddedBytes.batched(by: CBCMAC.BlockSize)) + var lastBlock = blocks.popLast()! + if lastBlockComplete { + lastBlock = xor(lastBlock, subKey1) + } else { + lastBlock = xor(lastBlock, subKey2) + } + + var x = Array(repeating: 0x00, count: CBCMAC.BlockSize) + var y = Array(repeating: 0x00, count: CBCMAC.BlockSize) + for block in blocks { + y = xor(block, x) + x = try aes.encrypt(y) + } + // the difference between CMAC and CBC-MAC is that CMAC xors the final block with a secret value + y = process(lastBlock: lastBlock, with: x) + return try aes.encrypt(y) + } + + func process(lastBlock: ArraySlice, with x: [UInt8]) -> [UInt8] { + return Array(lastBlock) + } + + // 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) -> Array { + var shifted = Array(repeating: 0x00, count: bytes.count) + let last = bytes.count - 1 + for index in 0.. +// 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: CBCMAC { + override func process(lastBlock: ArraySlice, with x: [UInt8]) -> [UInt8] { + return xor(lastBlock, x) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/ChaCha20.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/ChaCha20.swift new file mode 100644 index 0000000000..250ee9d011 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/ChaCha20.swift @@ -0,0 +1,347 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 +// + +public final class ChaCha20: BlockCipher { + public enum Error: Swift.Error { + case invalidKeyOrInitializationVector + case notSupported + } + + public static let blockSize = 64 // 512 / 8 + public let keySize: Int + + fileprivate let key: Key + fileprivate var counter: Array + + public init(key: Array, iv nonce: Array) throws { + precondition(nonce.count == 12 || nonce.count == 8) + + if key.count != 32 { + throw Error.invalidKeyOrInitializationVector + } + + self.key = Key(bytes: key) + keySize = self.key.count + + if nonce.count == 8 { + counter = [0, 0, 0, 0, 0, 0, 0, 0] + nonce + } else { + counter = [0, 0, 0, 0] + nonce + } + + assert(counter.count == 16) + } + + /// https://tools.ietf.org/html/rfc7539#section-2.3. + fileprivate func core(block: inout Array, counter: Array, key: Array) { + precondition(block.count == ChaCha20.blockSize) + precondition(counter.count == 16) + precondition(key.count == 32) + + let j0: UInt32 = 0x61707865 + let j1: UInt32 = 0x3320646e // 0x3620646e sigma/tau + let j2: UInt32 = 0x79622d32 + let j3: UInt32 = 0x6b206574 + let j4: UInt32 = UInt32(bytes: key[0..<4]).bigEndian + let j5: UInt32 = UInt32(bytes: key[4..<8]).bigEndian + let j6: UInt32 = UInt32(bytes: key[8..<12]).bigEndian + let j7: UInt32 = UInt32(bytes: key[12..<16]).bigEndian + let j8: UInt32 = UInt32(bytes: key[16..<20]).bigEndian + let j9: UInt32 = UInt32(bytes: key[20..<24]).bigEndian + let j10: UInt32 = UInt32(bytes: key[24..<28]).bigEndian + let j11: UInt32 = UInt32(bytes: key[28..<32]).bigEndian + let j12: UInt32 = UInt32(bytes: counter[0..<4]).bigEndian + let j13: UInt32 = UInt32(bytes: counter[4..<8]).bigEndian + let j14: UInt32 = UInt32(bytes: counter[8..<12]).bigEndian + let j15: UInt32 = UInt32(bytes: counter[12..<16]).bigEndian + + var (x0, x1, x2, x3, x4, x5, x6, x7) = (j0, j1, j2, j3, j4, j5, j6, j7) + var (x8, x9, x10, x11, x12, x13, x14, x15) = (j8, j9, j10, j11, j12, j13, j14, j15) + + for _ in 0..<10 { // 20 rounds + x0 = x0 &+ x4 + x12 ^= x0 + x12 = (x12 << 16) | (x12 >> 16) + x8 = x8 &+ x12 + x4 ^= x8 + x4 = (x4 << 12) | (x4 >> 20) + x0 = x0 &+ x4 + x12 ^= x0 + x12 = (x12 << 8) | (x12 >> 24) + x8 = x8 &+ x12 + x4 ^= x8 + x4 = (x4 << 7) | (x4 >> 25) + x1 = x1 &+ x5 + x13 ^= x1 + x13 = (x13 << 16) | (x13 >> 16) + x9 = x9 &+ x13 + x5 ^= x9 + x5 = (x5 << 12) | (x5 >> 20) + x1 = x1 &+ x5 + x13 ^= x1 + x13 = (x13 << 8) | (x13 >> 24) + x9 = x9 &+ x13 + x5 ^= x9 + x5 = (x5 << 7) | (x5 >> 25) + x2 = x2 &+ x6 + x14 ^= x2 + x14 = (x14 << 16) | (x14 >> 16) + x10 = x10 &+ x14 + x6 ^= x10 + x6 = (x6 << 12) | (x6 >> 20) + x2 = x2 &+ x6 + x14 ^= x2 + x14 = (x14 << 8) | (x14 >> 24) + x10 = x10 &+ x14 + x6 ^= x10 + x6 = (x6 << 7) | (x6 >> 25) + x3 = x3 &+ x7 + x15 ^= x3 + x15 = (x15 << 16) | (x15 >> 16) + x11 = x11 &+ x15 + x7 ^= x11 + x7 = (x7 << 12) | (x7 >> 20) + x3 = x3 &+ x7 + x15 ^= x3 + x15 = (x15 << 8) | (x15 >> 24) + x11 = x11 &+ x15 + x7 ^= x11 + x7 = (x7 << 7) | (x7 >> 25) + x0 = x0 &+ x5 + x15 ^= x0 + x15 = (x15 << 16) | (x15 >> 16) + x10 = x10 &+ x15 + x5 ^= x10 + x5 = (x5 << 12) | (x5 >> 20) + x0 = x0 &+ x5 + x15 ^= x0 + x15 = (x15 << 8) | (x15 >> 24) + x10 = x10 &+ x15 + x5 ^= x10 + x5 = (x5 << 7) | (x5 >> 25) + x1 = x1 &+ x6 + x12 ^= x1 + x12 = (x12 << 16) | (x12 >> 16) + x11 = x11 &+ x12 + x6 ^= x11 + x6 = (x6 << 12) | (x6 >> 20) + x1 = x1 &+ x6 + x12 ^= x1 + x12 = (x12 << 8) | (x12 >> 24) + x11 = x11 &+ x12 + x6 ^= x11 + x6 = (x6 << 7) | (x6 >> 25) + x2 = x2 &+ x7 + x13 ^= x2 + x13 = (x13 << 16) | (x13 >> 16) + x8 = x8 &+ x13 + x7 ^= x8 + x7 = (x7 << 12) | (x7 >> 20) + x2 = x2 &+ x7 + x13 ^= x2 + x13 = (x13 << 8) | (x13 >> 24) + x8 = x8 &+ x13 + x7 ^= x8 + x7 = (x7 << 7) | (x7 >> 25) + x3 = x3 &+ x4 + x14 ^= x3 + x14 = (x14 << 16) | (x14 >> 16) + x9 = x9 &+ x14 + x4 ^= x9 + x4 = (x4 << 12) | (x4 >> 20) + x3 = x3 &+ x4 + x14 ^= x3 + x14 = (x14 << 8) | (x14 >> 24) + x9 = x9 &+ x14 + x4 ^= x9 + x4 = (x4 << 7) | (x4 >> 25) + } + + x0 = x0 &+ j0 + x1 = x1 &+ j1 + x2 = x2 &+ j2 + x3 = x3 &+ j3 + x4 = x4 &+ j4 + x5 = x5 &+ j5 + x6 = x6 &+ j6 + x7 = x7 &+ j7 + x8 = x8 &+ j8 + x9 = x9 &+ j9 + x10 = x10 &+ j10 + x11 = x11 &+ j11 + x12 = x12 &+ j12 + x13 = x13 &+ j13 + x14 = x14 &+ j14 + x15 = x15 &+ j15 + + block.replaceSubrange(0..<4, with: x0.bigEndian.bytes()) + block.replaceSubrange(4..<8, with: x1.bigEndian.bytes()) + block.replaceSubrange(8..<12, with: x2.bigEndian.bytes()) + block.replaceSubrange(12..<16, with: x3.bigEndian.bytes()) + block.replaceSubrange(16..<20, with: x4.bigEndian.bytes()) + block.replaceSubrange(20..<24, with: x5.bigEndian.bytes()) + block.replaceSubrange(24..<28, with: x6.bigEndian.bytes()) + block.replaceSubrange(28..<32, with: x7.bigEndian.bytes()) + block.replaceSubrange(32..<36, with: x8.bigEndian.bytes()) + block.replaceSubrange(36..<40, with: x9.bigEndian.bytes()) + block.replaceSubrange(40..<44, with: x10.bigEndian.bytes()) + block.replaceSubrange(44..<48, with: x11.bigEndian.bytes()) + block.replaceSubrange(48..<52, with: x12.bigEndian.bytes()) + block.replaceSubrange(52..<56, with: x13.bigEndian.bytes()) + block.replaceSubrange(56..<60, with: x14.bigEndian.bytes()) + block.replaceSubrange(60..<64, with: x15.bigEndian.bytes()) + } + + // XORKeyStream + func process(bytes: ArraySlice, counter: inout Array, key: Array) -> Array { + precondition(counter.count == 16) + precondition(key.count == 32) + + var block = Array(repeating: 0, count: ChaCha20.blockSize) + var bytesSlice = bytes + var out = Array(reserveCapacity: bytesSlice.count) + + while bytesSlice.count >= ChaCha20.blockSize { + core(block: &block, counter: counter, key: key) + for (i, x) in block.enumerated() { + out.append(bytesSlice[bytesSlice.startIndex + i] ^ x) + } + var u: UInt32 = 1 + for i in 0..<4 { + u += UInt32(counter[i]) + counter[i] = UInt8(u & 0xff) + u >>= 8 + } + bytesSlice = bytesSlice[bytesSlice.startIndex + ChaCha20.blockSize.. 0 { + core(block: &block, counter: counter, key: key) + for (i, v) in bytesSlice.enumerated() { + out.append(v ^ block[i]) + } + } + return out + } +} + +// MARK: Cipher + +extension ChaCha20: Cipher { + public func encrypt(_ bytes: ArraySlice) throws -> Array { + return process(bytes: bytes, counter: &counter, key: Array(key)) + } + + public func decrypt(_ bytes: ArraySlice) throws -> Array { + return try encrypt(bytes) + } +} + +// MARK: Encryptor + +extension ChaCha20 { + public struct ChaChaEncryptor: Cryptor, Updatable { + private var accumulated = Array() + private let chacha: ChaCha20 + + init(chacha: ChaCha20) { + self.chacha = chacha + } + + public mutating func update(withBytes bytes: ArraySlice, isLast: Bool = false) throws -> Array { + accumulated += bytes + + var encrypted = Array() + encrypted.reserveCapacity(accumulated.count) + for chunk in accumulated.batched(by: ChaCha20.blockSize) { + if isLast || accumulated.count >= ChaCha20.blockSize { + encrypted += try chacha.encrypt(chunk) + accumulated.removeFirst(chunk.count) // TODO: improve performance + } + } + return encrypted + } + + public func seek(to: Int) throws { + throw Error.notSupported + } + } +} + +// MARK: Decryptor + +extension ChaCha20 { + public struct ChaChaDecryptor: Cryptor, Updatable { + private var accumulated = Array() + + private var offset: Int = 0 + private var offsetToRemove: Int = 0 + private let chacha: ChaCha20 + + init(chacha: ChaCha20) { + self.chacha = chacha + } + + public mutating func update(withBytes bytes: ArraySlice, isLast: Bool = true) throws -> Array { + // prepend "offset" number of bytes at the beginning + if offset > 0 { + accumulated += Array(repeating: 0, count: offset) + bytes + offsetToRemove = offset + offset = 0 + } else { + accumulated += bytes + } + + var plaintext = Array() + plaintext.reserveCapacity(accumulated.count) + for chunk in accumulated.batched(by: ChaCha20.blockSize) { + if isLast || accumulated.count >= ChaCha20.blockSize { + plaintext += try chacha.decrypt(chunk) + + // remove "offset" from the beginning of first chunk + if offsetToRemove > 0 { + plaintext.removeFirst(offsetToRemove) // TODO: improve performance + offsetToRemove = 0 + } + + accumulated.removeFirst(chunk.count) + } + } + + return plaintext + } + + public func seek(to: Int) throws { + throw Error.notSupported + } + } +} + +// MARK: Cryptors + +extension ChaCha20: Cryptors { + //TODO: Use BlockEncryptor/BlockDecryptor + + public func makeEncryptor() -> Cryptor & Updatable { + return ChaCha20.ChaChaEncryptor(chacha: self) + } + + public func makeDecryptor() -> Cryptor & Updatable { + return ChaCha20.ChaChaDecryptor(chacha: self) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Checksum.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Checksum.swift new file mode 100644 index 0000000000..1c4fd48c3d --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Checksum.swift @@ -0,0 +1,193 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +/// CRC - cyclic redundancy check code. +public final class Checksum { + private static let table32: Array = [ + 0x0000_0000, 0x7707_3096, 0xEE0E_612C, 0x9909_51BA, 0x076D_C419, 0x706A_F48F, 0xE963_A535, 0x9E64_95A3, + 0x0EDB_8832, 0x79DC_B8A4, 0xE0D5_E91E, 0x97D2_D988, 0x09B6_4C2B, 0x7EB1_7CBD, 0xE7B8_2D07, 0x90BF_1D91, + 0x1DB7_1064, 0x6AB0_20F2, 0xF3B9_7148, 0x84BE_41DE, 0x1ADA_D47D, 0x6DDD_E4EB, 0xF4D4_B551, 0x83D3_85C7, + 0x136C_9856, 0x646B_A8C0, 0xFD62_F97A, 0x8A65_C9EC, 0x1401_5C4F, 0x6306_6CD9, 0xFA0F_3D63, 0x8D08_0DF5, + 0x3B6E_20C8, 0x4C69_105E, 0xD560_41E4, 0xA267_7172, 0x3C03_E4D1, 0x4B04_D447, 0xD20D_85FD, 0xA50A_B56B, + 0x35B5_A8FA, 0x42B2_986C, 0xDBBB_C9D6, 0xACBC_F940, 0x32D8_6CE3, 0x45DF_5C75, 0xDCD6_0DCF, 0xABD1_3D59, + 0x26D9_30AC, 0x51DE_003A, 0xC8D7_5180, 0xBFD0_6116, 0x21B4_F4B5, 0x56B3_C423, 0xCFBA_9599, 0xB8BD_A50F, + 0x2802_B89E, 0x5F05_8808, 0xC60C_D9B2, 0xB10B_E924, 0x2F6F_7C87, 0x5868_4C11, 0xC161_1DAB, 0xB666_2D3D, + 0x76DC_4190, 0x01DB_7106, 0x98D2_20BC, 0xEFD5_102A, 0x71B1_8589, 0x06B6_B51F, 0x9FBF_E4A5, 0xE8B8_D433, + 0x7807_C9A2, 0x0F00_F934, 0x9609_A88E, 0xE10E_9818, 0x7F6A_0DBB, 0x086D_3D2D, 0x9164_6C97, 0xE663_5C01, + 0x6B6B_51F4, 0x1C6C_6162, 0x8565_30D8, 0xF262_004E, 0x6C06_95ED, 0x1B01_A57B, 0x8208_F4C1, 0xF50F_C457, + 0x65B0_D9C6, 0x12B7_E950, 0x8BBE_B8EA, 0xFCB9_887C, 0x62DD_1DDF, 0x15DA_2D49, 0x8CD3_7CF3, 0xFBD4_4C65, + 0x4DB2_6158, 0x3AB5_51CE, 0xA3BC_0074, 0xD4BB_30E2, 0x4ADF_A541, 0x3DD8_95D7, 0xA4D1_C46D, 0xD3D6_F4FB, + 0x4369_E96A, 0x346E_D9FC, 0xAD67_8846, 0xDA60_B8D0, 0x4404_2D73, 0x3303_1DE5, 0xAA0A_4C5F, 0xDD0D_7CC9, + 0x5005_713C, 0x2702_41AA, 0xBE0B_1010, 0xC90C_2086, 0x5768_B525, 0x206F_85B3, 0xB966_D409, 0xCE61_E49F, + 0x5EDE_F90E, 0x29D9_C998, 0xB0D0_9822, 0xC7D7_A8B4, 0x59B3_3D17, 0x2EB4_0D81, 0xB7BD_5C3B, 0xC0BA_6CAD, + 0xEDB8_8320, 0x9ABF_B3B6, 0x03B6_E20C, 0x74B1_D29A, 0xEAD5_4739, 0x9DD2_77AF, 0x04DB_2615, 0x73DC_1683, + 0xE363_0B12, 0x9464_3B84, 0x0D6D_6A3E, 0x7A6A_5AA8, 0xE40E_CF0B, 0x9309_FF9D, 0x0A00_AE27, 0x7D07_9EB1, + 0xF00F_9344, 0x8708_A3D2, 0x1E01_F268, 0x6906_C2FE, 0xF762_575D, 0x8065_67CB, 0x196C_3671, 0x6E6B_06E7, + 0xFED4_1B76, 0x89D3_2BE0, 0x10DA_7A5A, 0x67DD_4ACC, 0xF9B9_DF6F, 0x8EBE_EFF9, 0x17B7_BE43, 0x60B0_8ED5, + 0xD6D6_A3E8, 0xA1D1_937E, 0x38D8_C2C4, 0x4FDF_F252, 0xD1BB_67F1, 0xA6BC_5767, 0x3FB5_06DD, 0x48B2_364B, + 0xD80D_2BDA, 0xAF0A_1B4C, 0x3603_4AF6, 0x4104_7A60, 0xDF60_EFC3, 0xA867_DF55, 0x316E_8EEF, 0x4669_BE79, + 0xCB61_B38C, 0xBC66_831A, 0x256F_D2A0, 0x5268_E236, 0xCC0C_7795, 0xBB0B_4703, 0x2202_16B9, 0x5505_262F, + 0xC5BA_3BBE, 0xB2BD_0B28, 0x2BB4_5A92, 0x5CB3_6A04, 0xC2D7_FFA7, 0xB5D0_CF31, 0x2CD9_9E8B, 0x5BDE_AE1D, + 0x9B64_C2B0, 0xEC63_F226, 0x756A_A39C, 0x026D_930A, 0x9C09_06A9, 0xEB0E_363F, 0x7207_6785, 0x0500_5713, + 0x95BF_4A82, 0xE2B8_7A14, 0x7BB1_2BAE, 0x0CB6_1B38, 0x92D2_8E9B, 0xE5D5_BE0D, 0x7CDC_EFB7, 0x0BDB_DF21, + 0x86D3_D2D4, 0xF1D4_E242, 0x68DD_B3F8, 0x1FDA_836E, 0x81BE_16CD, 0xF6B9_265B, 0x6FB0_77E1, 0x18B7_4777, + 0x8808_5AE6, 0xFF0F_6A70, 0x6606_3BCA, 0x1101_0B5C, 0x8F65_9EFF, 0xF862_AE69, 0x616B_FFD3, 0x166C_CF45, + 0xA00A_E278, 0xD70D_D2EE, 0x4E04_8354, 0x3903_B3C2, 0xA767_2661, 0xD060_16F7, 0x4969_474D, 0x3E6E_77DB, + 0xAED1_6A4A, 0xD9D6_5ADC, 0x40DF_0B66, 0x37D8_3BF0, 0xA9BC_AE53, 0xDEBB_9EC5, 0x47B2_CF7F, 0x30B5_FFE9, + 0xBDBD_F21C, 0xCABA_C28A, 0x53B3_9330, 0x24B4_A3A6, 0xBAD0_3605, 0xCDD7_0693, 0x54DE_5729, 0x23D9_67BF, + 0xB366_7A2E, 0xC461_4AB8, 0x5D68_1B02, 0x2A6F_2B94, 0xB40B_BE37, 0xC30C_8EA1, 0x5A05_DF1B, 0x2D02_EF8D, + ] + + private static let table32c: Array = [ + 0x0000_0000, 0xF26B_8303, 0xE13B_70F7, 0x1350_F3F4, 0xC79A_971F, 0x35F1_141C, 0x26A1_E7E8, 0xD4CA_64EB, + 0x8AD9_58CF, 0x78B2_DBCC, 0x6BE2_2838, 0x9989_AB3B, 0x4D43_CFD0, 0xBF28_4CD3, 0xAC78_BF27, 0x5E13_3C24, + 0x105E_C76F, 0xE235_446C, 0xF165_B798, 0x030E_349B, 0xD7C4_5070, 0x25AF_D373, 0x36FF_2087, 0xC494_A384, + 0x9A87_9FA0, 0x68EC_1CA3, 0x7BBC_EF57, 0x89D7_6C54, 0x5D1D_08BF, 0xAF76_8BBC, 0xBC26_7848, 0x4E4D_FB4B, + 0x20BD_8EDE, 0xD2D6_0DDD, 0xC186_FE29, 0x33ED_7D2A, 0xE727_19C1, 0x154C_9AC2, 0x061C_6936, 0xF477_EA35, + 0xAA64_D611, 0x580F_5512, 0x4B5F_A6E6, 0xB934_25E5, 0x6DFE_410E, 0x9F95_C20D, 0x8CC5_31F9, 0x7EAE_B2FA, + 0x30E3_49B1, 0xC288_CAB2, 0xD1D8_3946, 0x23B3_BA45, 0xF779_DEAE, 0x0512_5DAD, 0x1642_AE59, 0xE429_2D5A, + 0xBA3A_117E, 0x4851_927D, 0x5B01_6189, 0xA96A_E28A, 0x7DA0_8661, 0x8FCB_0562, 0x9C9B_F696, 0x6EF0_7595, + 0x417B_1DBC, 0xB310_9EBF, 0xA040_6D4B, 0x522B_EE48, 0x86E1_8AA3, 0x748A_09A0, 0x67DA_FA54, 0x95B1_7957, + 0xCBA2_4573, 0x39C9_C670, 0x2A99_3584, 0xD8F2_B687, 0x0C38_D26C, 0xFE53_516F, 0xED03_A29B, 0x1F68_2198, + 0x5125_DAD3, 0xA34E_59D0, 0xB01E_AA24, 0x4275_2927, 0x96BF_4DCC, 0x64D4_CECF, 0x7784_3D3B, 0x85EF_BE38, + 0xDBFC_821C, 0x2997_011F, 0x3AC7_F2EB, 0xC8AC_71E8, 0x1C66_1503, 0xEE0D_9600, 0xFD5D_65F4, 0x0F36_E6F7, + 0x61C6_9362, 0x93AD_1061, 0x80FD_E395, 0x7296_6096, 0xA65C_047D, 0x5437_877E, 0x4767_748A, 0xB50C_F789, + 0xEB1F_CBAD, 0x1974_48AE, 0x0A24_BB5A, 0xF84F_3859, 0x2C85_5CB2, 0xDEEE_DFB1, 0xCDBE_2C45, 0x3FD5_AF46, + 0x7198_540D, 0x83F3_D70E, 0x90A3_24FA, 0x62C8_A7F9, 0xB602_C312, 0x4469_4011, 0x5739_B3E5, 0xA552_30E6, + 0xFB41_0CC2, 0x092A_8FC1, 0x1A7A_7C35, 0xE811_FF36, 0x3CDB_9BDD, 0xCEB0_18DE, 0xDDE0_EB2A, 0x2F8B_6829, + 0x82F6_3B78, 0x709D_B87B, 0x63CD_4B8F, 0x91A6_C88C, 0x456C_AC67, 0xB707_2F64, 0xA457_DC90, 0x563C_5F93, + 0x082F_63B7, 0xFA44_E0B4, 0xE914_1340, 0x1B7F_9043, 0xCFB5_F4A8, 0x3DDE_77AB, 0x2E8E_845F, 0xDCE5_075C, + 0x92A8_FC17, 0x60C3_7F14, 0x7393_8CE0, 0x81F8_0FE3, 0x5532_6B08, 0xA759_E80B, 0xB409_1BFF, 0x4662_98FC, + 0x1871_A4D8, 0xEA1A_27DB, 0xF94A_D42F, 0x0B21_572C, 0xDFEB_33C7, 0x2D80_B0C4, 0x3ED0_4330, 0xCCBB_C033, + 0xA24B_B5A6, 0x5020_36A5, 0x4370_C551, 0xB11B_4652, 0x65D1_22B9, 0x97BA_A1BA, 0x84EA_524E, 0x7681_D14D, + 0x2892_ED69, 0xDAF9_6E6A, 0xC9A9_9D9E, 0x3BC2_1E9D, 0xEF08_7A76, 0x1D63_F975, 0x0E33_0A81, 0xFC58_8982, + 0xB215_72C9, 0x407E_F1CA, 0x532E_023E, 0xA145_813D, 0x758F_E5D6, 0x87E4_66D5, 0x94B4_9521, 0x66DF_1622, + 0x38CC_2A06, 0xCAA7_A905, 0xD9F7_5AF1, 0x2B9C_D9F2, 0xFF56_BD19, 0x0D3D_3E1A, 0x1E6D_CDEE, 0xEC06_4EED, + 0xC38D_26C4, 0x31E6_A5C7, 0x22B6_5633, 0xD0DD_D530, 0x0417_B1DB, 0xF67C_32D8, 0xE52C_C12C, 0x1747_422F, + 0x4954_7E0B, 0xBB3F_FD08, 0xA86F_0EFC, 0x5A04_8DFF, 0x8ECE_E914, 0x7CA5_6A17, 0x6FF5_99E3, 0x9D9E_1AE0, + 0xD3D3_E1AB, 0x21B8_62A8, 0x32E8_915C, 0xC083_125F, 0x1449_76B4, 0xE622_F5B7, 0xF572_0643, 0x0719_8540, + 0x590A_B964, 0xAB61_3A67, 0xB831_C993, 0x4A5A_4A90, 0x9E90_2E7B, 0x6CFB_AD78, 0x7FAB_5E8C, 0x8DC0_DD8F, + 0xE330_A81A, 0x115B_2B19, 0x020B_D8ED, 0xF060_5BEE, 0x24AA_3F05, 0xD6C1_BC06, 0xC591_4FF2, 0x37FA_CCF1, + 0x69E9_F0D5, 0x9B82_73D6, 0x88D2_8022, 0x7AB9_0321, 0xAE73_67CA, 0x5C18_E4C9, 0x4F48_173D, 0xBD23_943E, + 0xF36E_6F75, 0x0105_EC76, 0x1255_1F82, 0xE03E_9C81, 0x34F4_F86A, 0xC69F_7B69, 0xD5CF_889D, 0x27A4_0B9E, + 0x79B7_37BA, 0x8BDC_B4B9, 0x988C_474D, 0x6AE7_C44E, 0xBE2D_A0A5, 0x4C46_23A6, 0x5F16_D052, 0xAD7D_5351, + ] + + private static let table16: Array = [ + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040, + ] + + /// Polynomial: 0xEDB88320 (Reversed) - IEEE + func crc32(_ message: Array, seed: UInt32? = nil, reflect: Bool = true) -> UInt32 { + var crc: UInt32 = seed != nil ? seed! : 0xFFFF_FFFF + for chunk in message.batched(by: 256) { + for b in chunk { + let idx = Int((crc ^ UInt32(reflect ? b : reversed(b))) & 0xFF) + crc = (crc >> 8) ^ Checksum.table32[idx] + } + } + return (reflect ? crc : reversed(crc)) ^ 0xFFFF_FFFF + } + + /// Polynomial: 0x82F63B78 (Reversed) - Castagnoli + func crc32c(_ message: Array, seed: UInt32? = nil, reflect: Bool = true) -> UInt32 { + var crc: UInt32 = seed != nil ? seed! : 0xFFFF_FFFF + for chunk in message.batched(by: 256) { + for b in chunk { + let idx = Int((crc ^ UInt32(reflect ? b : reversed(b))) & 0xFF) + crc = (crc >> 8) ^ Checksum.table32c[idx] + } + } + return (reflect ? crc : reversed(crc)) ^ 0xFFFF_FFFF + } + + /// Polynomial: 0xA001 (Reversed) - IBM + func crc16(_ message: Array, seed: UInt16? = nil) -> UInt16 { + var crc: UInt16 = seed != nil ? seed! : 0x0000 + for chunk in message.batched(by: 256) { + for b in chunk { + crc = (crc >> 8) ^ Checksum.table16[Int((crc ^ UInt16(b)) & 0xFF)] + } + } + return crc + } +} + +// MARK: Public interface + +public extension Checksum { + /// Calculate CRC32. + /// + /// - parameter message: Message + /// - parameter seed: Seed value (Optional) + /// - parameter reflect: is reflect (default true) + /// + /// - returns: Calculated code + static func crc32(_ message: Array, seed: UInt32? = nil, reflect: Bool = true) -> UInt32 { + return Checksum().crc32(message, seed: seed, reflect: reflect) + } + + /// Calculate CRC32C + /// + /// - parameter message: Message + /// - parameter seed: Seed value (Optional) + /// - parameter reflect: is reflect (default true) + /// + /// - returns: Calculated code + static func crc32c(_ message: Array, seed: UInt32? = nil, reflect: Bool = true) -> UInt32 { + return Checksum().crc32c(message, seed: seed, reflect: reflect) + } + + /// Calculate CRC16 + /// + /// - parameter message: Message + /// - parameter seed: Seed value (Optional) + /// + /// - returns: Calculated code + static func crc16(_ message: Array, seed: UInt16? = nil) -> UInt16 { + return Checksum().crc16(message, seed: seed) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Cipher.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Cipher.swift new file mode 100644 index 0000000000..6e2b636224 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Cipher.swift @@ -0,0 +1,47 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 enum CipherError: Error { + case encrypt + case decrypt +} + +public protocol Cipher: class { + var keySize: Int { get } + + /// Encrypt given bytes at once + /// + /// - parameter bytes: Plaintext data + /// - returns: Encrypted data + func encrypt(_ bytes: ArraySlice) throws -> Array + func encrypt(_ bytes: Array) throws -> Array + + /// Decrypt given bytes at once + /// + /// - parameter bytes: Ciphertext data + /// - returns: Plaintext data + func decrypt(_ bytes: ArraySlice) throws -> Array + func decrypt(_ bytes: Array) throws -> Array +} + +extension Cipher { + public func encrypt(_ bytes: Array) throws -> Array { + return try encrypt(bytes.slice) + } + + public func decrypt(_ bytes: Array) throws -> Array { + return try decrypt(bytes.slice) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Collection+Extension.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Collection+Extension.swift new file mode 100644 index 0000000000..1b79faad01 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Collection+Extension.swift @@ -0,0 +1,45 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// +extension Collection where Self.Element == UInt8, Self.Index == Int { + // Big endian order + func toUInt32Array() -> Array { + if isEmpty { + return [] + } + + var result = Array(reserveCapacity: 16) + for idx in stride(from: startIndex, to: endIndex, by: 4) { + let val = UInt32(bytes: self, fromIndex: idx).bigEndian + result.append(val) + } + + return result + } + + // Big endian order + func toUInt64Array() -> Array { + if isEmpty { + return [] + } + + var result = Array(reserveCapacity: 32) + for idx in stride(from: startIndex, to: endIndex, by: 8) { + let val = UInt64(bytes: self, fromIndex: idx).bigEndian + result.append(val) + } + + return result + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/CompactMap.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/CompactMap.swift new file mode 100644 index 0000000000..74cf92a9c8 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/CompactMap.swift @@ -0,0 +1,23 @@ +//// CryptoSwift +// +// Copyright (C) 2014-2018 Marcin Krzyżanowski +// 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(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] { + return try flatMap(transform) + } + } +#endif diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Cryptor.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Cryptor.swift new file mode 100644 index 0000000000..f79f4b3593 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Cryptor.swift @@ -0,0 +1,22 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +/// Cryptor (Encryptor or Decryptor) +public protocol Cryptor { + /// Seek to position in file, if block mode allows random access. + /// + /// - parameter to: new value of counter + mutating func seek(to: Int) throws +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Cryptors.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Cryptors.swift new file mode 100644 index 0000000000..4baa53bdea --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Cryptors.swift @@ -0,0 +1,44 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 canImport(Darwin) +import Darwin +#else +import Glibc +#endif + +/// Worker cryptor/decryptor of `Updatable` types +public protocol Cryptors: class { + + /// Cryptor suitable for encryption + func makeEncryptor() throws -> Cryptor & Updatable + + /// Cryptor suitable for decryption + func makeDecryptor() throws -> Cryptor & Updatable + + /// Generate array of random bytes. Helper function. + static func randomIV(_ blockSize: Int) -> Array +} + +extension Cryptors { + public static func randomIV(_ blockSize: Int) -> Array { + var randomIV: Array = Array() + randomIV.reserveCapacity(blockSize) + for randomByte in RandomBytesSequence(size: blockSize) { + randomIV.append(randomByte) + } + return randomIV + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Digest.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Digest.swift new file mode 100644 index 0000000000..c3976eadad --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Digest.swift @@ -0,0 +1,78 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@available(*, renamed: "Digest") +public typealias Hash = Digest + +/// Hash functions to calculate Digest. +public struct Digest { + /// Calculate MD5 Digest + /// - parameter bytes: input message + /// - returns: Digest bytes + public static func md5(_ bytes: Array) -> Array { + return MD5().calculate(for: bytes) + } + + /// Calculate SHA1 Digest + /// - parameter bytes: input message + /// - returns: Digest bytes + public static func sha1(_ bytes: Array) -> Array { + return SHA1().calculate(for: bytes) + } + + /// Calculate SHA2-224 Digest + /// - parameter bytes: input message + /// - returns: Digest bytes + public static func sha224(_ bytes: Array) -> Array { + return sha2(bytes, variant: .sha224) + } + + /// Calculate SHA2-256 Digest + /// - parameter bytes: input message + /// - returns: Digest bytes + public static func sha256(_ bytes: Array) -> Array { + return sha2(bytes, variant: .sha256) + } + + /// Calculate SHA2-384 Digest + /// - parameter bytes: input message + /// - returns: Digest bytes + public static func sha384(_ bytes: Array) -> Array { + return sha2(bytes, variant: .sha384) + } + + /// Calculate SHA2-512 Digest + /// - parameter bytes: input message + /// - returns: Digest bytes + public static func sha512(_ bytes: Array) -> Array { + return sha2(bytes, variant: .sha512) + } + + /// Calculate SHA2 Digest + /// - parameter bytes: input message + /// - parameter variant: SHA-2 variant + /// - returns: Digest bytes + public static func sha2(_ bytes: Array, variant: SHA2.Variant) -> Array { + return SHA2(variant: variant).calculate(for: bytes) + } + + /// Calculate SHA3 Digest + /// - parameter bytes: input message + /// - parameter variant: SHA-3 variant + /// - returns: Digest bytes + public static func sha3(_ bytes: Array, variant: SHA3.Variant) -> Array { + return SHA3(variant: variant).calculate(for: bytes) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/DigestType.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/DigestType.swift new file mode 100644 index 0000000000..48c40d680a --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/DigestType.swift @@ -0,0 +1,18 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +internal protocol DigestType { + func calculate(for bytes: Array) -> Array +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/AES+Foundation.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/AES+Foundation.swift new file mode 100644 index 0000000000..ba797337f0 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/AES+Foundation.swift @@ -0,0 +1,23 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +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) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Array+Foundation.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Array+Foundation.swift new file mode 100644 index 0000000000..ffab35d4c7 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Array+Foundation.swift @@ -0,0 +1,32 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +import Foundation + +public extension Array where Element == UInt8 { + func toBase64() -> String? { + return Data( self).base64EncodedString() + } + + init(base64: String) { + self.init() + + guard let decodedData = Data(base64Encoded: base64) else { + return + } + + append(contentsOf: decodedData.bytes) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Blowfish+Foundation.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Blowfish+Foundation.swift new file mode 100644 index 0000000000..be065b92ff --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Blowfish+Foundation.swift @@ -0,0 +1,23 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +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) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/ChaCha20+Foundation.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/ChaCha20+Foundation.swift new file mode 100644 index 0000000000..c1f3676831 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/ChaCha20+Foundation.swift @@ -0,0 +1,22 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +import Foundation + +extension ChaCha20 { + public convenience init(key: String, iv: String) throws { + try self.init(key: key.bytes, iv: iv.bytes) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Data+Extension.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Data+Extension.swift new file mode 100644 index 0000000000..5da7329ad2 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Data+Extension.swift @@ -0,0 +1,95 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +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 + var bytesArray = bytes + for i in 0 ..< bytesArray.count { + s = s + UInt32(bytesArray[i]) + } + s = s % 65536 + return UInt16(s) + } + + public func md5() -> Data { + return Data( Digest.md5(bytes)) + } + + public func sha1() -> Data { + return Data( Digest.sha1(bytes)) + } + + public func sha224() -> Data { + return Data( Digest.sha224(bytes)) + } + + public func sha256() -> Data { + return Data( Digest.sha256(bytes)) + } + + public func sha384() -> Data { + return Data( Digest.sha384(bytes)) + } + + public func sha512() -> Data { + return Data( Digest.sha512(bytes)) + } + + public func sha3(_ variant: SHA3.Variant) -> Data { + return Data( Digest.sha3(bytes, variant: variant)) + } + + public func crc32(seed: UInt32? = nil, reflect: Bool = true) -> Data { + return Data( Checksum.crc32(bytes, seed: seed, reflect: reflect).bytes()) + } + + public func crc32c(seed: UInt32? = nil, reflect: Bool = true) -> Data { + return Data( Checksum.crc32c(bytes, seed: seed, reflect: reflect).bytes()) + } + + public func crc16(seed: UInt16? = nil) -> Data { + return Data( Checksum.crc16(bytes, seed: seed).bytes()) + } + + public func encrypt(cipher: Cipher) throws -> Data { + return Data( try cipher.encrypt(bytes.slice)) + } + + public func decrypt(cipher: Cipher) throws -> Data { + return Data( try cipher.decrypt(bytes.slice)) + } + + public func authenticate(with authenticator: Authenticator) throws -> Data { + return Data( try authenticator.authenticate(bytes)) + } +} + +extension Data { + public init(hex: String) { + self.init(Array(hex: hex)) + } + + public var bytes: Array { + return Array(self) + } + + public func toHexString() -> String { + return bytes.toHexString() + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/HMAC+Foundation.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/HMAC+Foundation.swift new file mode 100644 index 0000000000..fd4d77cda0 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/HMAC+Foundation.swift @@ -0,0 +1,22 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +import Foundation + +extension HMAC { + public convenience init(key: String, variant: HMAC.Variant = .md5) throws { + self.init(key: key.bytes, variant: variant) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Rabbit+Foundation.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Rabbit+Foundation.swift new file mode 100644 index 0000000000..2a497e6603 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Rabbit+Foundation.swift @@ -0,0 +1,26 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +import Foundation + +extension Rabbit { + public convenience init(key: String) throws { + try self.init(key: key.bytes) + } + + public convenience init(key: String, iv: String) throws { + try self.init(key: key.bytes, iv: iv.bytes) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/String+FoundationExtension.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/String+FoundationExtension.swift new file mode 100644 index 0000000000..5cd7e9dcef --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/String+FoundationExtension.swift @@ -0,0 +1,41 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +import Foundation + +extension String { + /// Return Base64 back to String + public func decryptBase64ToString(cipher: Cipher) throws -> String { + guard let decodedData = Data(base64Encoded: self, options: []) else { + throw CipherError.decrypt + } + + let decrypted = try decodedData.decrypt(cipher: cipher) + + if let decryptedString = String(data: decrypted, encoding: String.Encoding.utf8) { + return decryptedString + } + + throw CipherError.decrypt + } + + public func decryptBase64(cipher: Cipher) throws -> Array { + guard let decodedData = Data(base64Encoded: self, options: []) else { + throw CipherError.decrypt + } + + return try decodedData.decrypt(cipher: cipher).bytes + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Utils+Foundation.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Utils+Foundation.swift new file mode 100644 index 0000000000..f945365089 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Foundation/Utils+Foundation.swift @@ -0,0 +1,27 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +import Foundation + +func perf(_ text: String, closure: () -> Void) { + let measurementStart = Date() + + closure() + + let measurementStop = Date() + let executionTime = measurementStop.timeIntervalSince(measurementStart) + + print("\(text) \(executionTime)") +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Generics.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Generics.swift new file mode 100644 index 0000000000..51797ce431 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Generics.swift @@ -0,0 +1,55 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +/** build bit pattern from array of bits */ +@_specialize(exported: true, where T == UInt8) +func integerFrom(_ bits: Array) -> T { + var bitPattern: T = 0 + for idx in bits.indices { + if bits[idx] == Bit.one { + let bit = T(UInt64(1) << UInt64(idx)) + bitPattern = bitPattern | bit + } + } + return bitPattern +} + +/// Array of bytes. Caution: don't use directly because generic is slow. +/// +/// - parameter value: integer value +/// - parameter length: length of output array. By default size of value type +/// +/// - returns: Array of bytes +@_specialize(exported: true, where T == Int) +@_specialize(exported: true, where T == UInt) +@_specialize(exported: true, where T == UInt8) +@_specialize(exported: true, where T == UInt16) +@_specialize(exported: true, where T == UInt32) +@_specialize(exported: true, where T == UInt64) +func arrayOfBytes(value: T, length totalBytes: Int = MemoryLayout.size) -> Array { + let valuePointer = UnsafeMutablePointer.allocate(capacity: 1) + valuePointer.pointee = value + + let bytesPointer = UnsafeMutablePointer(OpaquePointer(valuePointer)) + var bytes = Array(repeating: 0, count: totalBytes) + for j in 0...size, totalBytes) { + bytes[totalBytes - 1 - j] = (bytesPointer + j).pointee + } + + valuePointer.deinitialize(count: 1) + valuePointer.deallocate() + + return bytes +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/HKDF.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/HKDF.swift new file mode 100644 index 0000000000..daa8bbff8c --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/HKDF.swift @@ -0,0 +1,84 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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.ietf.org/rfc/rfc5869.txt +// + +#if canImport(Darwin) +import Darwin +#else +import Glibc +#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 + fileprivate let prk: Array + 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) + /// - info: optional context and application specific information + /// - keyLength: intended length of derived key + public init(password: Array, salt: Array? = nil, info: Array? = nil, keyLength: Int? = nil /* dkLen */, variant: HMAC.Variant = .sha256) throws { + guard !password.isEmpty else { + throw Error.invalidInput + } + + let dkLen = keyLength ?? variant.digestLength + let keyLengthFinal = Double(dkLen) + let hLen = Double(variant.digestLength) + let numBlocks = Int(ceil(keyLengthFinal / hLen)) // l = ceil(keyLength / hLen) + guard numBlocks <= 255 else { + throw Error.derivedKeyTooLong + } + + /// HKDF-Extract(salt, password) -> PRK + /// - PRK - a pseudo-random key; it is used by calculate() + 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 { + let hmac = HMAC(key: prk, variant: variant) + var ret = Array() + ret.reserveCapacity(numBlocks * variant.digestLength) + var value = Array() + 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)) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/HMAC.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/HMAC.swift new file mode 100644 index 0000000000..c5bfe3d3ce --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/HMAC.swift @@ -0,0 +1,102 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 HMAC: Authenticator { + public enum Error: Swift.Error { + case authenticateError + case invalidInput + } + + public enum Variant { + case sha1, sha256, sha384, sha512, md5 + + var digestLength: Int { + switch self { + case .sha1: + return SHA1.digestLength + case .sha256: + return SHA2.Variant.sha256.digestLength + case .sha384: + return SHA2.Variant.sha384.digestLength + case .sha512: + return SHA2.Variant.sha512.digestLength + case .md5: + return MD5.digestLength + } + } + + func calculateHash(_ bytes: Array) -> Array { + switch self { + case .sha1: + return Digest.sha1(bytes) + case .sha256: + return Digest.sha256(bytes) + case .sha384: + return Digest.sha384(bytes) + case .sha512: + return Digest.sha512(bytes) + case .md5: + return Digest.md5(bytes) + } + } + + func blockSize() -> Int { + switch self { + case .md5: + return MD5.blockSize + case .sha1, .sha256: + return 64 + case .sha384, .sha512: + return 128 + } + } + } + + var key: Array + let variant: Variant + + public init(key: Array, variant: HMAC.Variant = .md5) { + self.variant = variant + self.key = key + + if key.count > variant.blockSize() { + let hash = variant.calculateHash(key) + self.key = hash + } + + if key.count < variant.blockSize() { + self.key = ZeroPadding().add(to: key, blockSize: variant.blockSize()) + } + } + + // MARK: Authenticator + + public func authenticate(_ bytes: Array) throws -> Array { + var opad = Array(repeating: 0x5c, count: variant.blockSize()) + for idx in key.indices { + opad[idx] = key[idx] ^ opad[idx] + } + var ipad = Array(repeating: 0x36, count: variant.blockSize()) + for idx in key.indices { + ipad[idx] = key[idx] ^ ipad[idx] + } + + let ipadAndMessageHash = variant.calculateHash(ipad + bytes) + let result = variant.calculateHash(opad + ipadAndMessageHash) + + // return Array(result[0..<10]) // 80 bits + return result + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Info.plist b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Info.plist new file mode 100644 index 0000000000..2b7f70e649 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Int+Extension.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Int+Extension.swift new file mode 100644 index 0000000000..98b14762f2 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Int+Extension.swift @@ -0,0 +1,38 @@ +// +// CryptoSwift +// +// Created by Marcin Krzyzanowski on 12/08/14. +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 canImport(Darwin) +import Darwin +#else +import Glibc +#endif + +/* array of bits */ +extension Int { + init(bits: [Bit]) { + self.init(bitPattern: integerFrom(bits) as UInt) + } +} + +extension FixedWidthInteger { + @_transparent + func bytes(totalBytes: Int = MemoryLayout.size) -> Array { + return arrayOfBytes(value: self.littleEndian, length: totalBytes) + // TODO: adjust bytes order + // var value = self.littleEndian + // return withUnsafeBytes(of: &value, Array.init).reversed() + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/MD5.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/MD5.swift new file mode 100644 index 0000000000..7f44b4a286 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/MD5.swift @@ -0,0 +1,165 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 MD5: DigestType { + static let blockSize: Int = 64 + static let digestLength: Int = 16 // 128 / 8 + fileprivate static let hashInitialValue: Array = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476] + + fileprivate var accumulated = Array() + fileprivate var processedBytesTotalCount: Int = 0 + fileprivate var accumulatedHash: Array = MD5.hashInitialValue + + /** specifies the per-round shift amounts */ + private let s: Array = [ + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, + ] + + /** binary integer part of the sines of integers (Radians) */ + private let k: Array = [ + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, + ] + + public init() { + } + + public func calculate(for bytes: Array) -> Array { + do { + return try update(withBytes: bytes.slice, isLast: true) + } catch { + fatalError() + } + } + + // mutating currentHash in place is way faster than returning new result + fileprivate func process(block chunk: ArraySlice, currentHash: inout Array) { + assert(chunk.count == 16 * 4) + + // Initialize hash value for this chunk: + var A: UInt32 = currentHash[0] + var B: UInt32 = currentHash[1] + var C: UInt32 = currentHash[2] + var D: UInt32 = currentHash[3] + + var dTemp: UInt32 = 0 + + // Main loop + for j in 0.., isLast: Bool = false) throws -> Array { + accumulated += bytes + + if isLast { + let lengthInBits = (processedBytesTotalCount + accumulated.count) * 8 + let lengthBytes = lengthInBits.bytes(totalBytes: 64 / 8) // A 64-bit representation of b + + // Step 1. Append padding + bitPadding(to: &accumulated, blockSize: MD5.blockSize, allowance: 64 / 8) + + // Step 2. Append Length a 64-bit representation of lengthInBits + accumulated += lengthBytes.reversed() + } + + var processedBytes = 0 + for chunk in accumulated.batched(by: MD5.blockSize) { + if isLast || (accumulated.count - processedBytes) >= MD5.blockSize { + process(block: chunk, currentHash: &accumulatedHash) + processedBytes += chunk.count + } + } + accumulated.removeFirst(processedBytes) + processedBytesTotalCount += processedBytes + + // output current hash + var result = Array() + result.reserveCapacity(MD5.digestLength) + + for hElement in accumulatedHash { + let hLE = hElement.littleEndian + result += Array(arrayLiteral: UInt8(hLE & 0xff), UInt8((hLE >> 8) & 0xff), UInt8((hLE >> 16) & 0xff), UInt8((hLE >> 24) & 0xff)) + } + + // reset hash value for instance + if isLast { + accumulatedHash = MD5.hashInitialValue + } + + return result + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/NoPadding.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/NoPadding.swift new file mode 100644 index 0000000000..57670ad360 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/NoPadding.swift @@ -0,0 +1,27 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +struct NoPadding: PaddingProtocol { + init() { + } + + func add(to data: Array, blockSize _: Int) -> Array { + return data + } + + func remove(from data: Array, blockSize _: Int?) -> Array { + return data + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Operators.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Operators.swift new file mode 100644 index 0000000000..a15fe3c950 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Operators.swift @@ -0,0 +1,32 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +/* + Bit shifting with overflow protection using overflow operator "&". + Approach is consistent with standard overflow operators &+, &-, &*, &/ + and introduce new overflow operators for shifting: &<<, &>> + + Note: Works with unsigned integers values only + + Usage + + var i = 1 // init + var j = i &<< 2 //shift left + j &<<= 2 //shift left and assign + + @see: https://medium.com/@krzyzanowskim/swiftly-shift-bits-and-protect-yourself-be33016ce071 + + This fuctonality is now implemented as part of Swift 3, SE-0104 https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md + */ diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/PKCS/PBKDF1.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/PKCS/PBKDF1.swift new file mode 100644 index 0000000000..953b36ebd6 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/PKCS/PBKDF1.swift @@ -0,0 +1,87 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 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. + struct PBKDF1 { + public enum Error: Swift.Error { + case invalidInput + case derivedKeyTooLong + } + + public enum Variant { + case md5, sha1 + + var size: Int { + switch self { + case .md5: + return MD5.digestLength + case .sha1: + return SHA1.digestLength + } + } + + fileprivate func calculateHash(_ bytes: Array) -> Array { + switch self { + case .sha1: + return Digest.sha1(bytes) + case .md5: + return Digest.md5(bytes) + } + } + } + + private let iterations: Int // c + private let variant: Variant + private let keyLength: Int + private let t1: Array + + /// - parameters: + /// - salt: salt, an eight-bytes + /// - variant: hash variant + /// - iterations: iteration count, a positive integer + /// - keyLength: intended length of derived key + public init(password: Array, salt: Array, variant: Variant = .sha1, iterations: Int = 4096 /* c */, keyLength: Int? = nil /* dkLen */ ) throws { + precondition(iterations > 0) + precondition(salt.count == 8) + + let keyLength = keyLength ?? variant.size + + if keyLength > variant.size { + throw Error.derivedKeyTooLong + } + + let t1 = variant.calculateHash(password + salt) + + self.iterations = iterations + self.variant = variant + self.keyLength = keyLength + self.t1 = t1 + } + + /// Apply the underlying hash function Hash for c iterations + public func calculate() -> Array { + var t = t1 + for _ in 2...iterations { + t = variant.calculateHash(t) + } + return Array(t[0.. +// 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.ietf.org/rfc/rfc2898.txt +// + +#if canImport(Darwin) +import Darwin +#else +import Glibc +#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) + struct PBKDF2 { + public enum Error: Swift.Error { + case invalidInput + case derivedKeyTooLong + } + + private let salt: Array // S + fileprivate let iterations: Int // c + private let numBlocks: Int // l + private let dkLen: Int + fileprivate let prf: HMAC + + /// - parameters: + /// - salt: salt + /// - variant: hash variant + /// - iterations: iteration count, a positive integer + /// - keyLength: intended length of derived key + /// - variant: MAC variant. Defaults to SHA256 + public init(password: Array, salt: Array, iterations: Int = 4096 /* c */, keyLength: Int? = nil /* dkLen */, variant: HMAC.Variant = .sha256) throws { + precondition(iterations > 0) + + let prf = HMAC(key: password, variant: variant) + + guard iterations > 0 && !salt.isEmpty else { + throw Error.invalidInput + } + + dkLen = keyLength ?? variant.digestLength + let keyLengthFinal = Double(dkLen) + let hLen = Double(prf.variant.digestLength) + if keyLengthFinal > (pow(2, 32) - 1) * hLen { + throw Error.derivedKeyTooLong + } + + self.salt = salt + self.iterations = iterations + self.prf = prf + + numBlocks = Int(ceil(Double(keyLengthFinal) / hLen)) // l = ceil(keyLength / hLen) + } + + public func calculate() throws -> Array { + var ret = Array() + ret.reserveCapacity(numBlocks * prf.variant.digestLength) + for i in 1...numBlocks { + // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter + if let value = try calculateBlock(self.salt, blockNum: i) { + ret.append(contentsOf: value) + } + } + return Array(ret.prefix(dkLen)) + } + } +} + +fileprivate extension PKCS5.PBKDF2 { + func ARR(_ i: Int) -> Array { + var inti = Array(repeating: 0, count: 4) + inti[0] = UInt8((i >> 24) & 0xff) + inti[1] = UInt8((i >> 16) & 0xff) + inti[2] = UInt8((i >> 8) & 0xff) + inti[3] = UInt8(i & 0xff) + return inti + } + + // F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c + // U_1 = PRF (P, S || INT (i)) + func calculateBlock(_ salt: Array, blockNum: Int) throws -> Array? { + guard let u1 = try? prf.authenticate(salt + ARR(blockNum)) else { // blockNum.bytes() is slower + return nil + } + + var u = u1 + var ret = u + if iterations > 1 { + // U_2 = PRF (P, U_1) , + // U_c = PRF (P, U_{c-1}) . + for _ in 2...iterations { + u = try prf.authenticate(u) + for x in 0.. +// 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. +// + +// PKCS is a group of public-key cryptography standards devised +// and published by RSA Security Inc, starting in the early 1990s. +// + +public enum PKCS5 { + typealias Padding = PKCS7Padding +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/PKCS/PKCS7.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/PKCS/PKCS7.swift new file mode 100644 index 0000000000..9c01284944 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/PKCS/PKCS7.swift @@ -0,0 +1,18 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 enum PKCS7 { + typealias Padding = PKCS7Padding +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/PKCS/PKCS7Padding.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/PKCS/PKCS7Padding.swift new file mode 100644 index 0000000000..37cd165e48 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/PKCS/PKCS7Padding.swift @@ -0,0 +1,64 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// PKCS is a group of public-key cryptography standards devised +// and published by RSA Security Inc, starting in the early 1990s. +// + +struct PKCS7Padding: PaddingProtocol { + enum Error: Swift.Error { + case invalidPaddingValue + } + + init() { + } + + func add(to bytes: Array, blockSize: Int) -> Array { + let padding = UInt8(blockSize - (bytes.count % blockSize)) + var withPadding = bytes + if padding == 0 { + // If the original data is a multiple of N bytes, then an extra block of bytes with value N is added. + for _ in 0..(arrayLiteral: UInt8(blockSize)) + } + } else { + // The value of each added byte is the number of bytes that are added + for _ in 0..(arrayLiteral: UInt8(padding)) + } + } + return withPadding + } + + func remove(from bytes: Array, blockSize _: Int?) -> Array { + guard !bytes.isEmpty, let lastByte = bytes.last else { + return bytes + } + + assert(!bytes.isEmpty, "Need bytes to remove padding") + + let padding = Int(lastByte) // last byte + let finalLength = bytes.count - padding + + if finalLength < 0 { + return bytes + } + + if padding >= 1 { + return Array(bytes[0.. +// 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 protocol PaddingProtocol { + func add(to: Array, blockSize: Int) -> Array + func remove(from: Array, blockSize: Int?) -> Array +} + +public enum Padding: PaddingProtocol { + case noPadding, zeroPadding, pkcs7, pkcs5 + + public func add(to: Array, blockSize: Int) -> Array { + switch self { + case .noPadding: + return to // NoPadding().add(to: to, blockSize: blockSize) + case .zeroPadding: + return ZeroPadding().add(to: to, blockSize: blockSize) + case .pkcs7: + return PKCS7.Padding().add(to: to, blockSize: blockSize) + case .pkcs5: + return PKCS5.Padding().add(to: to, blockSize: blockSize) + } + } + + public func remove(from: Array, blockSize: Int?) -> Array { + switch self { + case .noPadding: + return from //NoPadding().remove(from: from, blockSize: blockSize) + case .zeroPadding: + return ZeroPadding().remove(from: from, blockSize: blockSize) + case .pkcs7: + return PKCS7.Padding().remove(from: from, blockSize: blockSize) + case .pkcs5: + return PKCS5.Padding().remove(from: from, blockSize: blockSize) + } + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Poly1305.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Poly1305.swift new file mode 100644 index 0000000000..c97f940449 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Poly1305.swift @@ -0,0 +1,165 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-4 +// nacl/crypto_onetimeauth/poly1305/ref/auth.c +// +/// Poly1305 takes a 32-byte, one-time key and a message and produces a 16-byte tag that authenticates the +/// 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 + } + + public static let blockSize: Int = 16 + + private let key: SecureBytes + + /// - parameter key: 32-byte key + public init(key: Array) { + self.key = SecureBytes(bytes: key) + } + + private func squeeze(h: inout Array) { + assert(h.count == 17) + var u: UInt32 = 0 + for j in 0..<16 { + u = u &+ h[j] + h[j] = u & 255 + u = u >> 8 + } + + u = u &+ h[16] + h[16] = u & 3 + u = 5 * (u >> 2) + + for j in 0..<16 { + u = u &+ h[j] + h[j] = u & 255 + u = u >> 8 + } + + u = u &+ h[16] + h[16] = u + } + + private func add(h: inout Array, c: Array) { + assert(h.count == 17 && c.count == 17) + + var u: UInt32 = 0 + for j in 0..<17 { + u = u &+ (h[j] &+ c[j]) + h[j] = u & 255 + u = u >> 8 + } + } + + private func mulmod(h: inout Array, r: Array) { + var hr = Array(repeating: 0, count: 17) + var u: UInt32 = 0 + for i in 0..<17 { + u = 0 + for j in 0...i { + u = u &+ (h[j] * r[i &- j]) + } + for j in (i + 1)..<17 { + u = u &+ (320 * h[j] * r[i &+ 17 &- j]) + } + hr[i] = u + } + h = hr + squeeze(h: &h) + } + + private func freeze(h: inout Array) { + let horig = h + add(h: &h, c: [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252]) + let negative = UInt32(bitPattern: -Int32(h[16] >> 7)) + for j in 0..<17 { + h[j] ^= negative & (horig[j] ^ h[j]) + } + } + + /// the key is partitioned into two parts, called "r" and "s" + fileprivate func onetimeauth(message input: Array, key k: Array) -> Array { + // clamp + var r = Array(repeating: 0, count: 17) + var h = Array(repeating: 0, count: 17) + var c = Array(repeating: 0, count: 17) + + r[0] = UInt32(k[0]) + r[1] = UInt32(k[1]) + r[2] = UInt32(k[2]) + r[3] = UInt32(k[3] & 15) + r[4] = UInt32(k[4] & 252) + r[5] = UInt32(k[5]) + r[6] = UInt32(k[6]) + r[7] = UInt32(k[7] & 15) + r[8] = UInt32(k[8] & 252) + r[9] = UInt32(k[9]) + r[10] = UInt32(k[10]) + r[11] = UInt32(k[11] & 15) + r[12] = UInt32(k[12] & 252) + r[13] = UInt32(k[13]) + r[14] = UInt32(k[14]) + r[15] = UInt32(k[15] & 15) + r[16] = 0 + + var inlen = input.count + var inpos = 0 + while inlen > 0 { + for j in 0..) throws -> Array { + return onetimeauth(message: bytes, key: Array(key)) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Rabbit.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Rabbit.swift new file mode 100644 index 0000000000..974ae90ceb --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Rabbit.swift @@ -0,0 +1,217 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 Rabbit: BlockCipher { + public enum Error: Swift.Error { + case invalidKeyOrInitializationVector + } + + /// Size of IV in bytes + public static let ivSize = 64 / 8 + + /// Size of key in bytes + public static let keySize = 128 / 8 + + /// Size of block in bytes + public static let blockSize = 128 / 8 + + public var keySize: Int { + return key.count + } + + /// Key + private let key: Key + + /// IV (optional) + private let iv: Array? + + /// State variables + private var x = Array(repeating: 0, count: 8) + + /// Counter variables + private var c = Array(repeating: 0, count: 8) + + /// Counter carry + private var p7: UInt32 = 0 + + /// 'a' constants + private var a: Array = [ + 0x4d34d34d, + 0xd34d34d3, + 0x34d34d34, + 0x4d34d34d, + 0xd34d34d3, + 0x34d34d34, + 0x4d34d34d, + 0xd34d34d3, + ] + + // MARK: - Initializers + + public convenience init(key: Array) throws { + try self.init(key: key, iv: nil) + } + + public init(key: Array, iv: Array?) throws { + self.key = Key(bytes: key) + self.iv = iv + + guard key.count == Rabbit.keySize && (iv == nil || iv!.count == Rabbit.ivSize) else { + throw Error.invalidKeyOrInitializationVector + } + } + + // MARK: - + + fileprivate func setup() { + p7 = 0 + + // Key divided into 8 subkeys + var k = Array(repeating: 0, count: 8) + for j in 0..<8 { + k[j] = UInt32(key[Rabbit.blockSize - (2 * j + 1)]) | (UInt32(key[Rabbit.blockSize - (2 * j + 2)]) << 8) + } + + // Initialize state and counter variables from subkeys + for j in 0..<8 { + if j % 2 == 0 { + x[j] = (k[(j + 1) % 8] << 16) | k[j] + c[j] = (k[(j + 4) % 8] << 16) | k[(j + 5) % 8] + } else { + x[j] = (k[(j + 5) % 8] << 16) | k[(j + 4) % 8] + c[j] = (k[j] << 16) | k[(j + 1) % 8] + } + } + + // Iterate system four times + nextState() + nextState() + nextState() + nextState() + + // Reinitialize counter variables + for j in 0..<8 { + c[j] = c[j] ^ x[(j + 4) % 8] + } + + if let iv = iv { + setupIV(iv) + } + } + + private func setupIV(_ iv: Array) { + // 63...56 55...48 47...40 39...32 31...24 23...16 15...8 7...0 IV bits + // 0 1 2 3 4 5 6 7 IV bytes in array + let iv0 = UInt32(bytes: [iv[4], iv[5], iv[6], iv[7]]) + let iv1 = UInt32(bytes: [iv[0], iv[1], iv[4], iv[5]]) + let iv2 = UInt32(bytes: [iv[0], iv[1], iv[2], iv[3]]) + let iv3 = UInt32(bytes: [iv[2], iv[3], iv[6], iv[7]]) + + // Modify the counter state as function of the IV + c[0] = c[0] ^ iv0 + c[1] = c[1] ^ iv1 + c[2] = c[2] ^ iv2 + c[3] = c[3] ^ iv3 + c[4] = c[4] ^ iv0 + c[5] = c[5] ^ iv1 + c[6] = c[6] ^ iv2 + c[7] = c[7] ^ iv3 + + // Iterate system four times + nextState() + nextState() + nextState() + nextState() + } + + private func nextState() { + // Before an iteration the counters are incremented + var carry = p7 + for j in 0..<8 { + let prev = c[j] + c[j] = prev &+ a[j] &+ carry + carry = prev > c[j] ? 1 : 0 // detect overflow + } + p7 = carry // save last carry bit + + // Iteration of the system + var newX = Array(repeating: 0, count: 8) + newX[0] = g(0) &+ rotateLeft(g(7), by: 16) &+ rotateLeft(g(6), by: 16) + newX[1] = g(1) &+ rotateLeft(g(0), by: 8) &+ g(7) + newX[2] = g(2) &+ rotateLeft(g(1), by: 16) &+ rotateLeft(g(0), by: 16) + newX[3] = g(3) &+ rotateLeft(g(2), by: 8) &+ g(1) + newX[4] = g(4) &+ rotateLeft(g(3), by: 16) &+ rotateLeft(g(2), by: 16) + newX[5] = g(5) &+ rotateLeft(g(4), by: 8) &+ g(3) + newX[6] = g(6) &+ rotateLeft(g(5), by: 16) &+ rotateLeft(g(4), by: 16) + newX[7] = g(7) &+ rotateLeft(g(6), by: 8) &+ g(5) + x = newX + } + + private func g(_ j: Int) -> UInt32 { + let sum = x[j] &+ c[j] + let square = UInt64(sum) * UInt64(sum) + return UInt32(truncatingIfNeeded: square ^ (square >> 32)) + } + + fileprivate func nextOutput() -> Array { + nextState() + + var output16 = Array(repeating: 0, count: Rabbit.blockSize / 2) + output16[7] = UInt16(truncatingIfNeeded: x[0]) ^ UInt16(truncatingIfNeeded: x[5] >> 16) + output16[6] = UInt16(truncatingIfNeeded: x[0] >> 16) ^ UInt16(truncatingIfNeeded: x[3]) + output16[5] = UInt16(truncatingIfNeeded: x[2]) ^ UInt16(truncatingIfNeeded: x[7] >> 16) + output16[4] = UInt16(truncatingIfNeeded: x[2] >> 16) ^ UInt16(truncatingIfNeeded: x[5]) + output16[3] = UInt16(truncatingIfNeeded: x[4]) ^ UInt16(truncatingIfNeeded: x[1] >> 16) + output16[2] = UInt16(truncatingIfNeeded: x[4] >> 16) ^ UInt16(truncatingIfNeeded: x[7]) + output16[1] = UInt16(truncatingIfNeeded: x[6]) ^ UInt16(truncatingIfNeeded: x[3] >> 16) + output16[0] = UInt16(truncatingIfNeeded: x[6] >> 16) ^ UInt16(truncatingIfNeeded: x[1]) + + var output8 = Array(repeating: 0, count: Rabbit.blockSize) + for j in 0..> 8) + output8[j * 2 + 1] = UInt8(truncatingIfNeeded: output16[j]) + } + return output8 + } +} + +// MARK: Cipher + +extension Rabbit: Cipher { + public func encrypt(_ bytes: ArraySlice) throws -> Array { + setup() + + var result = Array(repeating: 0, count: bytes.count) + var output = nextOutput() + var byteIdx = 0 + var outputIdx = 0 + while byteIdx < bytes.count { + if outputIdx == Rabbit.blockSize { + output = nextOutput() + outputIdx = 0 + } + + result[byteIdx] = bytes[byteIdx] ^ output[outputIdx] + + byteIdx += 1 + outputIdx += 1 + } + return result + } + + public func decrypt(_ bytes: ArraySlice) throws -> Array { + return try encrypt(bytes) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/RandomBytesSequence.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/RandomBytesSequence.swift new file mode 100644 index 0000000000..be7bdcb747 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/RandomBytesSequence.swift @@ -0,0 +1,50 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 canImport(Darwin) + import Darwin +#else + import Glibc +#endif + +struct RandomBytesSequence: Sequence { + let size: Int + + func makeIterator() -> AnyIterator { + var count = 0 + return AnyIterator.init { () -> UInt8? in + guard count < self.size else { + return nil + } + count = count + 1 + + #if os(Linux) || os(Android) || os(FreeBSD) + let fd = open("/dev/urandom", O_RDONLY) + if fd <= 0 { + return nil + } + + var value: UInt8 = 0 + let result = read(fd, &value, MemoryLayout.size) + precondition(result == 1) + + close(fd) + return value + #else + return UInt8(arc4random_uniform(UInt32(UInt8.max) + 1)) + #endif + } + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/SHA1.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/SHA1.swift new file mode 100644 index 0000000000..61f6bce3f9 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/SHA1.swift @@ -0,0 +1,151 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 SHA1: DigestType { + static let digestLength: Int = 20 // 160 / 8 + static let blockSize: Int = 64 + fileprivate static let hashInitialValue: ContiguousArray = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0] + + fileprivate var accumulated = Array() + fileprivate var processedBytesTotalCount: Int = 0 + fileprivate var accumulatedHash: ContiguousArray = SHA1.hashInitialValue + + public init() { + } + + public func calculate(for bytes: Array) -> Array { + do { + return try update(withBytes: bytes.slice, isLast: true) + } catch { + return [] + } + } + + fileprivate func process(block chunk: ArraySlice, currentHash hh: inout ContiguousArray) { + // 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.allocate(capacity: 80) + M.initialize(repeating: 0, count: 80) + defer { + M.deinitialize(count: 80) + M.deallocate() + } + + for x in 0..<80 { + switch x { + case 0...15: + let start = chunk.startIndex.advanced(by: x * 4) // * MemoryLayout.size + M[x] = UInt32(bytes: chunk, fromIndex: start) + break + default: + M[x] = rotateLeft(M[x - 3] ^ M[x - 8] ^ M[x - 14] ^ M[x - 16], by: 1) + break + } + } + + var A = hh[0] + var B = hh[1] + var C = hh[2] + var D = hh[3] + var E = hh[4] + + // Main loop + for j in 0...79 { + var f: UInt32 = 0 + var k: UInt32 = 0 + + switch j { + case 0...19: + f = (B & C) | ((~B) & D) + k = 0x5a827999 + break + case 20...39: + f = B ^ C ^ D + k = 0x6ed9eba1 + break + case 40...59: + f = (B & C) | (B & D) | (C & D) + k = 0x8f1bbcdc + break + case 60...79: + f = B ^ C ^ D + k = 0xca62c1d6 + break + default: + break + } + + let temp = rotateLeft(A, by: 5) &+ f &+ E &+ M[j] &+ k + E = D + D = C + C = rotateLeft(B, by: 30) + B = A + A = temp + } + + hh[0] = hh[0] &+ A + hh[1] = hh[1] &+ B + hh[2] = hh[2] &+ C + hh[3] = hh[3] &+ D + hh[4] = hh[4] &+ E + } +} + +extension SHA1: Updatable { + @discardableResult + public func update(withBytes bytes: ArraySlice, isLast: Bool = false) throws -> Array { + accumulated += bytes + + if isLast { + let lengthInBits = (processedBytesTotalCount + accumulated.count) * 8 + let lengthBytes = lengthInBits.bytes(totalBytes: 64 / 8) // A 64-bit representation of b + + // Step 1. Append padding + bitPadding(to: &accumulated, blockSize: SHA1.blockSize, allowance: 64 / 8) + + // Step 2. Append Length a 64-bit representation of lengthInBits + accumulated += lengthBytes + } + + var processedBytes = 0 + for chunk in accumulated.batched(by: SHA1.blockSize) { + if isLast || (accumulated.count - processedBytes) >= SHA1.blockSize { + process(block: chunk, currentHash: &accumulatedHash) + processedBytes += chunk.count + } + } + accumulated.removeFirst(processedBytes) + processedBytesTotalCount += processedBytes + + // output current hash + var result = Array(repeating: 0, count: SHA1.digestLength) + var pos = 0 + for idx in 0..> 24) & 0xff) + result[pos + 1] = UInt8((h >> 16) & 0xff) + result[pos + 2] = UInt8((h >> 8) & 0xff) + result[pos + 3] = UInt8(h & 0xff) + pos += 4 + } + + // reset hash value for instance + if isLast { + accumulatedHash = SHA1.hashInitialValue + } + + return result + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/SHA2.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/SHA2.swift new file mode 100644 index 0000000000..2e9940d390 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/SHA2.swift @@ -0,0 +1,353 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// TODO: generic for process32/64 (UInt32/UInt64) +// + +public final class SHA2: DigestType { + let variant: Variant + let size: Int + let blockSize: Int + let digestLength: Int + private let k: Array + + fileprivate var accumulated = Array() + fileprivate var processedBytesTotalCount: Int = 0 + fileprivate var accumulatedHash32 = Array() + fileprivate var accumulatedHash64 = Array() + + public enum Variant: RawRepresentable { + case sha224, sha256, sha384, sha512 + + public var digestLength: Int { + return rawValue / 8 + } + + public var blockSize: Int { + switch self { + case .sha224, .sha256: + return 64 + case .sha384, .sha512: + return 128 + } + } + + public typealias RawValue = Int + public var rawValue: RawValue { + switch self { + case .sha224: + return 224 + case .sha256: + return 256 + case .sha384: + return 384 + case .sha512: + return 512 + } + } + + public init?(rawValue: RawValue) { + switch rawValue { + case 224: + self = .sha224 + break + case 256: + self = .sha256 + break + case 384: + self = .sha384 + break + case 512: + self = .sha512 + break + default: + return nil + } + } + + fileprivate var h: Array { + switch self { + case .sha224: + return [0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4] + case .sha256: + return [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19] + case .sha384: + return [0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939, 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4] + case .sha512: + return [0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179] + } + } + + fileprivate var finalLength: Int { + switch self { + case .sha224: + return 7 + case .sha384: + return 6 + default: + return Int.max + } + } + } + + public init(variant: SHA2.Variant) { + self.variant = variant + switch self.variant { + case .sha224, .sha256: + accumulatedHash32 = variant.h.map { UInt32($0) } // FIXME: UInt64 for process64 + blockSize = variant.blockSize + size = variant.rawValue + digestLength = variant.digestLength + k = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, + ] + case .sha384, .sha512: + accumulatedHash64 = variant.h + blockSize = variant.blockSize + size = variant.rawValue + digestLength = variant.digestLength + k = [ + 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538, + 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe, + 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, + 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, + 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab, + 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, + 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, + 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, + 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, + 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, + 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, + 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, + 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c, + 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6, + 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, + 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817, + ] + } + } + + public func calculate(for bytes: Array) -> Array { + do { + return try update(withBytes: bytes.slice, isLast: true) + } catch { + return [] + } + } + + fileprivate func process64(block chunk: ArraySlice, currentHash hh: inout Array) { + // 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.allocate(capacity: k.count) + M.initialize(repeating: 0, count: k.count) + defer { + M.deinitialize(count: self.k.count) + M.deallocate() + } + for x in 0...size + M[x] = UInt64(bytes: chunk, fromIndex: start) + break + default: + let s0 = rotateRight(M[x - 15], by: 1) ^ rotateRight(M[x - 15], by: 8) ^ (M[x - 15] >> 7) + let s1 = rotateRight(M[x - 2], by: 19) ^ rotateRight(M[x - 2], by: 61) ^ (M[x - 2] >> 6) + M[x] = M[x - 16] &+ s0 &+ M[x - 7] &+ s1 + break + } + } + + var A = hh[0] + var B = hh[1] + var C = hh[2] + var D = hh[3] + var E = hh[4] + var F = hh[5] + var G = hh[6] + var H = hh[7] + + // Main loop + for j in 0.., currentHash hh: inout Array) { + // 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.allocate(capacity: k.count) + M.initialize(repeating: 0, count: k.count) + defer { + M.deinitialize(count: self.k.count) + M.deallocate() + } + + for x in 0...size + M[x] = UInt32(bytes: chunk, fromIndex: start) + break + default: + let s0 = rotateRight(M[x - 15], by: 7) ^ rotateRight(M[x - 15], by: 18) ^ (M[x - 15] >> 3) + let s1 = rotateRight(M[x - 2], by: 17) ^ rotateRight(M[x - 2], by: 19) ^ (M[x - 2] >> 10) + M[x] = M[x - 16] &+ s0 &+ M[x - 7] &+ s1 + break + } + } + + var A = hh[0] + var B = hh[1] + var C = hh[2] + var D = hh[3] + var E = hh[4] + var F = hh[5] + var G = hh[6] + var H = hh[7] + + // Main loop + for j in 0.., isLast: Bool = false) throws -> Array { + accumulated += bytes + + if isLast { + let lengthInBits = (processedBytesTotalCount + accumulated.count) * 8 + let lengthBytes = lengthInBits.bytes(totalBytes: blockSize / 8) // A 64-bit/128-bit representation of b. blockSize fit by accident. + + // Step 1. Append padding + bitPadding(to: &accumulated, blockSize: blockSize, allowance: blockSize / 8) + + // Step 2. Append Length a 64-bit representation of lengthInBits + accumulated += lengthBytes + } + + var processedBytes = 0 + for chunk in accumulated.batched(by: blockSize) { + if isLast || (accumulated.count - processedBytes) >= blockSize { + switch variant { + case .sha224, .sha256: + process32(block: chunk, currentHash: &accumulatedHash32) + case .sha384, .sha512: + process64(block: chunk, currentHash: &accumulatedHash64) + } + processedBytes += chunk.count + } + } + accumulated.removeFirst(processedBytes) + processedBytesTotalCount += processedBytes + + // output current hash + var result = Array(repeating: 0, count: variant.digestLength) + switch variant { + case .sha224, .sha256: + var pos = 0 + for idx in 0..> 24) & 0xff) + result[pos + 1] = UInt8((h >> 16) & 0xff) + result[pos + 2] = UInt8((h >> 8) & 0xff) + result[pos + 3] = UInt8(h & 0xff) + pos += 4 + } + case .sha384, .sha512: + var pos = 0 + for idx in 0..> 56) & 0xff) + result[pos + 1] = UInt8((h >> 48) & 0xff) + result[pos + 2] = UInt8((h >> 40) & 0xff) + result[pos + 3] = UInt8((h >> 32) & 0xff) + result[pos + 4] = UInt8((h >> 24) & 0xff) + result[pos + 5] = UInt8((h >> 16) & 0xff) + result[pos + 6] = UInt8((h >> 8) & 0xff) + result[pos + 7] = UInt8(h & 0xff) + pos += 8 + } + } + + // reset hash value for instance + if isLast { + switch variant { + case .sha224, .sha256: + accumulatedHash32 = variant.h.lazy.map { UInt32($0) } // FIXME: UInt64 for process64 + case .sha384, .sha512: + accumulatedHash64 = variant.h + } + } + + return result + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/SHA3.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/SHA3.swift new file mode 100644 index 0000000000..b22fb5a199 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/SHA3.swift @@ -0,0 +1,289 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf +// http://keccak.noekeon.org/specs_summary.html +// + +#if canImport(Darwin) +import Darwin +#else +import Glibc +#endif + +public final class SHA3: DigestType { + let round_constants: Array = [ + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000, + 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009, + 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003, + 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a, + 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008, + ] + + public let blockSize: Int + public let digestLength: Int + public let markByte: UInt8 + + fileprivate var accumulated = Array() + fileprivate var accumulatedHash: Array + + public enum Variant { + case sha224, sha256, sha384, sha512, keccak224, keccak256, keccak384, keccak512 + + var digestLength: Int { + return 100 - (blockSize / 2) + } + + var blockSize: Int { + return (1600 - outputLength * 2) / 8 + } + + var markByte: UInt8 { + switch self { + case .sha224, .sha256, .sha384, .sha512: + return 0x06 // 0x1F for SHAKE + case .keccak224, .keccak256, .keccak384, .keccak512: + return 0x01 + } + } + + public var outputLength: Int { + switch self { + case .sha224, .keccak224: + return 224 + case .sha256, .keccak256: + return 256 + case .sha384, .keccak384: + return 384 + case .sha512, .keccak512: + return 512 + } + } + } + + public init(variant: SHA3.Variant) { + blockSize = variant.blockSize + digestLength = variant.digestLength + markByte = variant.markByte + accumulatedHash = Array(repeating: 0, count: digestLength) + } + + public func calculate(for bytes: Array) -> Array { + do { + return try update(withBytes: bytes.slice, isLast: true) + } catch { + return [] + } + } + + /// 1. For all pairs (x,z) such that 0≤x<5 and 0≤z) { + let c = UnsafeMutablePointer.allocate(capacity: 5) + c.initialize(repeating: 0, count: 5) + defer { + c.deinitialize(count: 5) + c.deallocate() + } + let d = UnsafeMutablePointer.allocate(capacity: 5) + d.initialize(repeating: 0, count: 5) + defer { + d.deinitialize(count: 5) + d.deallocate() + } + + for i in 0..<5 { + c[i] = a[i] ^ a[i &+ 5] ^ a[i &+ 10] ^ a[i &+ 15] ^ a[i &+ 20] + } + + d[0] = rotateLeft(c[1], by: 1) ^ c[4] + d[1] = rotateLeft(c[2], by: 1) ^ c[0] + d[2] = rotateLeft(c[3], by: 1) ^ c[1] + d[3] = rotateLeft(c[4], by: 1) ^ c[2] + d[4] = rotateLeft(c[0], by: 1) ^ c[3] + + for i in 0..<5 { + a[i] ^= d[i] + a[i &+ 5] ^= d[i] + a[i &+ 10] ^= d[i] + a[i &+ 15] ^= d[i] + a[i &+ 20] ^= d[i] + } + } + + /// A′[x, y, z]=A[(x &+ 3y) mod 5, x, z] + private func π(_ a: inout Array) { + let a1 = a[1] + a[1] = a[6] + a[6] = a[9] + a[9] = a[22] + a[22] = a[14] + a[14] = a[20] + a[20] = a[2] + a[2] = a[12] + a[12] = a[13] + a[13] = a[19] + a[19] = a[23] + a[23] = a[15] + a[15] = a[4] + a[4] = a[24] + a[24] = a[21] + a[21] = a[8] + a[8] = a[16] + a[16] = a[5] + a[5] = a[3] + a[3] = a[18] + a[18] = a[17] + a[17] = a[11] + a[11] = a[7] + a[7] = a[10] + a[10] = a1 + } + + /// For all triples (x, y, z) such that 0≤x<5, 0≤y<5, and 0≤z) { + for i in stride(from: 0, to: 25, by: 5) { + let a0 = a[0 &+ i] + let a1 = a[1 &+ i] + a[0 &+ i] ^= ~a1 & a[2 &+ i] + a[1 &+ i] ^= ~a[2 &+ i] & a[3 &+ i] + a[2 &+ i] ^= ~a[3 &+ i] & a[4 &+ i] + a[3 &+ i] ^= ~a[4 &+ i] & a0 + a[4 &+ i] ^= ~a0 & a1 + } + } + + private func ι(_ a: inout Array, round: Int) { + a[0] ^= round_constants[round] + } + + fileprivate func process(block chunk: ArraySlice, currentHash hh: inout Array) { + // expand + hh[0] ^= chunk[0].littleEndian + hh[1] ^= chunk[1].littleEndian + hh[2] ^= chunk[2].littleEndian + hh[3] ^= chunk[3].littleEndian + hh[4] ^= chunk[4].littleEndian + hh[5] ^= chunk[5].littleEndian + hh[6] ^= chunk[6].littleEndian + hh[7] ^= chunk[7].littleEndian + hh[8] ^= chunk[8].littleEndian + if blockSize > 72 { // 72 / 8, sha-512 + hh[9] ^= chunk[9].littleEndian + hh[10] ^= chunk[10].littleEndian + hh[11] ^= chunk[11].littleEndian + hh[12] ^= chunk[12].littleEndian + if blockSize > 104 { // 104 / 8, sha-384 + hh[13] ^= chunk[13].littleEndian + hh[14] ^= chunk[14].littleEndian + hh[15] ^= chunk[15].littleEndian + hh[16] ^= chunk[16].littleEndian + if blockSize > 136 { // 136 / 8, sha-256 + hh[17] ^= chunk[17].littleEndian + // FULL_SHA3_FAMILY_SUPPORT + if blockSize > 144 { // 144 / 8, sha-224 + hh[18] ^= chunk[18].littleEndian + hh[19] ^= chunk[19].littleEndian + hh[20] ^= chunk[20].littleEndian + hh[21] ^= chunk[21].littleEndian + hh[22] ^= chunk[22].littleEndian + hh[23] ^= chunk[23].littleEndian + hh[24] ^= chunk[24].littleEndian + } + } + } + } + + // Keccak-f + for round in 0..<24 { + θ(&hh) + + hh[1] = rotateLeft(hh[1], by: 1) + hh[2] = rotateLeft(hh[2], by: 62) + hh[3] = rotateLeft(hh[3], by: 28) + hh[4] = rotateLeft(hh[4], by: 27) + hh[5] = rotateLeft(hh[5], by: 36) + hh[6] = rotateLeft(hh[6], by: 44) + hh[7] = rotateLeft(hh[7], by: 6) + hh[8] = rotateLeft(hh[8], by: 55) + hh[9] = rotateLeft(hh[9], by: 20) + hh[10] = rotateLeft(hh[10], by: 3) + hh[11] = rotateLeft(hh[11], by: 10) + hh[12] = rotateLeft(hh[12], by: 43) + hh[13] = rotateLeft(hh[13], by: 25) + hh[14] = rotateLeft(hh[14], by: 39) + hh[15] = rotateLeft(hh[15], by: 41) + hh[16] = rotateLeft(hh[16], by: 45) + hh[17] = rotateLeft(hh[17], by: 15) + hh[18] = rotateLeft(hh[18], by: 21) + hh[19] = rotateLeft(hh[19], by: 8) + hh[20] = rotateLeft(hh[20], by: 18) + hh[21] = rotateLeft(hh[21], by: 2) + hh[22] = rotateLeft(hh[22], by: 61) + hh[23] = rotateLeft(hh[23], by: 56) + hh[24] = rotateLeft(hh[24], by: 14) + + π(&hh) + χ(&hh) + ι(&hh, round: round) + } + } +} + +extension SHA3: Updatable { + public func update(withBytes bytes: ArraySlice, isLast: Bool = false) throws -> Array { + accumulated += bytes + + if isLast { + // Add padding + let markByteIndex = accumulated.count + + // We need to always pad the input. Even if the input is a multiple of blockSize. + let r = blockSize * 8 + let q = (r / 8) - (accumulated.count % (r / 8)) + accumulated += Array(repeating: 0, count: q) + + accumulated[markByteIndex] |= markByte + accumulated[self.accumulated.count - 1] |= 0x80 + } + + var processedBytes = 0 + for chunk in accumulated.batched(by: blockSize) { + if isLast || (accumulated.count - processedBytes) >= blockSize { + process(block: chunk.toUInt64Array().slice, currentHash: &accumulatedHash) + processedBytes += chunk.count + } + } + accumulated.removeFirst(processedBytes) + + // TODO: verify performance, reduce vs for..in + let result = accumulatedHash.reduce(Array()) { (result, value) -> Array in + return result + value.bigEndian.bytes() + } + + // reset hash value for instance + if isLast { + accumulatedHash = Array(repeating: 0, count: digestLength) + } + + return Array(result[0.. +// 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/rfc7914 +// + +/// Implementation of the scrypt key derivation function. +public final class Scrypt { + enum Error: Swift.Error { + case nIsTooLarge + case rIsTooLarge + case nMustBeAPowerOf2GreaterThan1 + case invalidInput + } + + /// Configuration parameters. + private let salt: SecureBytes + private let password: SecureBytes + fileprivate let blocksize: Int // 128 * r + fileprivate let salsaBlock = UnsafeMutableRawPointer.allocate(byteCount: 64, alignment: 64) + private let dkLen: Int + private let N: Int + private let r: Int + private let p: Int + + /// - parameters: + /// - password: password + /// - salt: salt + /// - dkLen: output length + /// - N: determines extra memory used + /// - r: determines a block size + /// - p: determines parallelicity degree + public init(password: Array, salt: Array, dkLen: Int, N: Int, r: Int, p: Int) throws { + precondition(dkLen > 0) + precondition(N > 0) + precondition(r > 0) + precondition(p > 0) + + guard !(N < 2 || (N & (N - 1)) != 0) else { throw Error.nMustBeAPowerOf2GreaterThan1 } + + guard N <= .max / 128 / r else { throw Error.nIsTooLarge } + guard r <= .max / 128 / p else { throw Error.rIsTooLarge } + + guard !salt.isEmpty else { + throw Error.invalidInput + } + + blocksize = 128 * r + self.N = N + self.r = r + self.p = p + self.password = SecureBytes.init(bytes: password) + self.salt = SecureBytes.init(bytes: salt) + self.dkLen = dkLen + } + + /// Runs the key derivation function with a specific password. + public func calculate() throws -> [UInt8] { + // Allocate memory (as bytes for now) for further use in mixing steps + let B = UnsafeMutableRawPointer.allocate(byteCount: 128 * r * p, alignment: 64) + let XY = UnsafeMutableRawPointer.allocate(byteCount: 256 * r + 64, alignment: 64) + let V = UnsafeMutableRawPointer.allocate(byteCount: 128 * r * N, alignment: 64) + + // Deallocate memory when done + defer { + B.deallocate() + XY.deallocate() + V.deallocate() + } + + /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ + // Expand the initial key + let barray = try PKCS5.PBKDF2(password: Array(password), salt: Array(salt), iterations: 1, keyLength: p * 128 * r, variant: .sha256).calculate() + barray.withUnsafeBytes { p in + B.copyMemory(from: p.baseAddress!, byteCount: barray.count) + } + + /* 2: for i = 0 to p - 1 do */ + // do the mixing + for i in 0 ..< p { + /* 3: B_i <-- MF(B_i, N) */ + smix(B + i * 128 * r, V.assumingMemoryBound(to: UInt32.self), XY.assumingMemoryBound(to: UInt32.self)) + } + + /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ + let pointer = B.assumingMemoryBound(to: UInt8.self) + let bufferPointer = UnsafeBufferPointer(start: pointer, count: p * 128 * r) + let block = [UInt8](bufferPointer) + return try PKCS5.PBKDF2(password: Array(password), salt: block, iterations: 1, keyLength: dkLen, variant: .sha256).calculate() + } +} + +private extension Scrypt { + /// Computes `B = SMix_r(B, N)`. + /// + /// The input `block` must be `128*r` bytes in length; the temporary storage `v` must be `128*r*n` bytes in length; + /// the temporary storage `xy` must be `256*r + 64` bytes in length. The arrays `block`, `v`, and `xy` must be + /// aligned to a multiple of 64 bytes. + @inline(__always) func smix(_ block: UnsafeMutableRawPointer, _ v: UnsafeMutablePointer, _ xy: UnsafeMutablePointer) { + let X = xy + let Y = xy + 32 * r + let Z = xy + 64 * r + + /* 1: X <-- B */ + let typedBlock = block.assumingMemoryBound(to: UInt32.self) + X.assign(from: typedBlock, count: 32 * r) + + /* 2: for i = 0 to N - 1 do */ + for i in stride(from: 0, to: N, by: 2) { + /* 3: V_i <-- X */ + UnsafeMutableRawPointer(v + i * (32 * r)).copyMemory(from: X, byteCount: 128 * r) + + /* 4: X <-- H(X) */ + blockMixSalsa8(X, Y, Z) + + /* 3: V_i <-- X */ + UnsafeMutableRawPointer(v + (i + 1) * (32 * r)).copyMemory(from: Y, byteCount: 128 * r) + + /* 4: X <-- H(X) */ + blockMixSalsa8(Y, X, Z) + } + + /* 6: for i = 0 to N - 1 do */ + for _ in stride(from: 0, to: N, by: 2) { + /* + 7: j <-- Integerify (X) mod N + where Integerify (B[0] ... B[2 * r - 1]) is defined + as the result of interpreting B[2 * r - 1] as a little-endian integer. + */ + var j = Int(integerify(X) & UInt64(N - 1)) + + /* 8: X <-- H(X \xor V_j) */ + blockXor(X, v + j * 32 * r, 128 * r) + blockMixSalsa8(X, Y, Z) + + /* 7: j <-- Integerify(X) mod N */ + j = Int(integerify(Y) & UInt64(N - 1)) + + /* 8: X <-- H(X \xor V_j) */ + blockXor(Y, v + j * 32 * r, 128 * r) + blockMixSalsa8(Y, X, Z) + } + + /* 10: B' <-- X */ + for k in 0 ..< 32 * r { + UnsafeMutableRawPointer(block + 4 * k).storeBytes(of: X[k], as: UInt32.self) + } + } + + /// Returns the result of parsing `B_{2r-1}` as a little-endian integer. + @inline(__always) func integerify(_ block: UnsafeRawPointer) -> UInt64 { + let bi = block + (2 * r - 1) * 64 + return bi.load(as: UInt64.self).littleEndian + } + + /// Compute `bout = BlockMix_{salsa20/8, r}(bin)`. + /// + /// The input `bin` must be `128*r` bytes in length; the output `bout` must also be the same size. The temporary + /// space `x` must be 64 bytes. + @inline(__always) func blockMixSalsa8(_ bin: UnsafePointer, _ bout: UnsafeMutablePointer, _ x: UnsafeMutablePointer) { + /* 1: X <-- B_{2r - 1} */ + UnsafeMutableRawPointer(x).copyMemory(from: bin + (2 * r - 1) * 16, byteCount: 64) + + /* 2: for i = 0 to 2r - 1 do */ + for i in stride(from: 0, to: 2 * r, by: 2) { + /* 3: X <-- H(X \xor B_i) */ + blockXor(x, bin + i * 16, 64) + salsa20_8_typed(x) + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + UnsafeMutableRawPointer(bout + i * 8).copyMemory(from: x, byteCount: 64) + + /* 3: X <-- H(X \xor B_i) */ + blockXor(x, bin + i * 16 + 16, 64) + salsa20_8_typed(x) + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + UnsafeMutableRawPointer(bout + i * 8 + r * 16).copyMemory(from: x, byteCount: 64) + } + } + + @inline(__always) func salsa20_8_typed(_ block: UnsafeMutablePointer) { + salsaBlock.copyMemory(from: UnsafeRawPointer(block), byteCount: 64) + let salsaBlockTyped = salsaBlock.assumingMemoryBound(to: UInt32.self) + + for _ in stride(from: 0, to: 8, by: 2) { + salsaBlockTyped[4] ^= rotateLeft(salsaBlockTyped[0] &+ salsaBlockTyped[12], by: 7) + salsaBlockTyped[8] ^= rotateLeft(salsaBlockTyped[4] &+ salsaBlockTyped[0], by: 9) + salsaBlockTyped[12] ^= rotateLeft(salsaBlockTyped[8] &+ salsaBlockTyped[4], by: 13) + salsaBlockTyped[0] ^= rotateLeft(salsaBlockTyped[12] &+ salsaBlockTyped[8], by: 18) + + salsaBlockTyped[9] ^= rotateLeft(salsaBlockTyped[5] &+ salsaBlockTyped[1], by: 7) + salsaBlockTyped[13] ^= rotateLeft(salsaBlockTyped[9] &+ salsaBlockTyped[5], by: 9) + salsaBlockTyped[1] ^= rotateLeft(salsaBlockTyped[13] &+ salsaBlockTyped[9], by: 13) + salsaBlockTyped[5] ^= rotateLeft(salsaBlockTyped[1] &+ salsaBlockTyped[13], by: 18) + + salsaBlockTyped[14] ^= rotateLeft(salsaBlockTyped[10] &+ salsaBlockTyped[6], by: 7) + salsaBlockTyped[2] ^= rotateLeft(salsaBlockTyped[14] &+ salsaBlockTyped[10], by: 9) + salsaBlockTyped[6] ^= rotateLeft(salsaBlockTyped[2] &+ salsaBlockTyped[14], by: 13) + salsaBlockTyped[10] ^= rotateLeft(salsaBlockTyped[6] &+ salsaBlockTyped[2], by: 18) + + salsaBlockTyped[3] ^= rotateLeft(salsaBlockTyped[15] &+ salsaBlockTyped[11], by: 7) + salsaBlockTyped[7] ^= rotateLeft(salsaBlockTyped[3] &+ salsaBlockTyped[15], by: 9) + salsaBlockTyped[11] ^= rotateLeft(salsaBlockTyped[7] &+ salsaBlockTyped[3], by: 13) + salsaBlockTyped[15] ^= rotateLeft(salsaBlockTyped[11] &+ salsaBlockTyped[7], by: 18) + + salsaBlockTyped[1] ^= rotateLeft(salsaBlockTyped[0] &+ salsaBlockTyped[3], by: 7) + salsaBlockTyped[2] ^= rotateLeft(salsaBlockTyped[1] &+ salsaBlockTyped[0], by: 9) + salsaBlockTyped[3] ^= rotateLeft(salsaBlockTyped[2] &+ salsaBlockTyped[1], by: 13) + salsaBlockTyped[0] ^= rotateLeft(salsaBlockTyped[3] &+ salsaBlockTyped[2], by: 18) + + salsaBlockTyped[6] ^= rotateLeft(salsaBlockTyped[5] &+ salsaBlockTyped[4], by: 7) + salsaBlockTyped[7] ^= rotateLeft(salsaBlockTyped[6] &+ salsaBlockTyped[5], by: 9) + salsaBlockTyped[4] ^= rotateLeft(salsaBlockTyped[7] &+ salsaBlockTyped[6], by: 13) + salsaBlockTyped[5] ^= rotateLeft(salsaBlockTyped[4] &+ salsaBlockTyped[7], by: 18) + + salsaBlockTyped[11] ^= rotateLeft(salsaBlockTyped[10] &+ salsaBlockTyped[9], by: 7) + salsaBlockTyped[8] ^= rotateLeft(salsaBlockTyped[11] &+ salsaBlockTyped[10], by: 9) + salsaBlockTyped[9] ^= rotateLeft(salsaBlockTyped[8] &+ salsaBlockTyped[11], by: 13) + salsaBlockTyped[10] ^= rotateLeft(salsaBlockTyped[9] &+ salsaBlockTyped[8], by: 18) + + salsaBlockTyped[12] ^= rotateLeft(salsaBlockTyped[15] &+ salsaBlockTyped[14], by: 7) + salsaBlockTyped[13] ^= rotateLeft(salsaBlockTyped[12] &+ salsaBlockTyped[15], by: 9) + salsaBlockTyped[14] ^= rotateLeft(salsaBlockTyped[13] &+ salsaBlockTyped[12], by: 13) + salsaBlockTyped[15] ^= rotateLeft(salsaBlockTyped[14] &+ salsaBlockTyped[13], by: 18) + } + for i in 0 ..< 16 { + block[i] = block[i] &+ salsaBlockTyped[i] + } + } + + @inline(__always) func blockXor(_ dest: UnsafeMutableRawPointer, _ src: UnsafeRawPointer, _ len: Int) { + let D = dest.assumingMemoryBound(to: UInt64.self) + let S = src.assumingMemoryBound(to: UInt64.self) + let L = len / MemoryLayout.size + + for i in 0 ..< L { + D[i] ^= S[i] + } + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/SecureBytes.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/SecureBytes.swift new file mode 100644 index 0000000000..61e7f693d7 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/SecureBytes.swift @@ -0,0 +1,77 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 canImport(Darwin) +import Darwin +#else +import Glibc +#endif + +typealias Key = SecureBytes + +/// Keeps bytes in memory. Because this is class, bytes are not copied +/// and memory area is locked as long as referenced, then unlocked on deinit +final class SecureBytes { + fileprivate let bytes: Array + let count: Int + + init(bytes: Array) { + self.bytes = bytes + count = bytes.count + self.bytes.withUnsafeBufferPointer { (pointer) -> Void in + mlock(pointer.baseAddress, pointer.count) + } + } + + deinit { + self.bytes.withUnsafeBufferPointer { (pointer) -> Void in + munlock(pointer.baseAddress, pointer.count) + } + } +} + +extension SecureBytes: Collection { + typealias Index = Int + + var endIndex: Int { + return bytes.endIndex + } + + var startIndex: Int { + return bytes.startIndex + } + + subscript(position: Index) -> UInt8 { + return bytes[position] + } + + subscript(bounds: Range) -> ArraySlice { + return bytes[bounds] + } + + func formIndex(after i: inout Int) { + bytes.formIndex(after: &i) + } + + func index(after i: Int) -> Int { + return bytes.index(after: i) + } +} + +extension SecureBytes: ExpressibleByArrayLiteral { + public convenience init(arrayLiteral elements: UInt8...) { + self.init(bytes: elements) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/StreamDecryptor.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/StreamDecryptor.swift new file mode 100644 index 0000000000..81ab2705e5 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/StreamDecryptor.swift @@ -0,0 +1,78 @@ +// CryptoSwift +// +// Copyright (C) 2014-2018 Marcin Krzyżanowski +// 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. +// + +final class StreamDecryptor: Cryptor, Updatable { + private let blockSize: Int + private var worker: CipherModeWorker + private let padding: Padding + private var accumulated = Array() + + private var lastBlockRemainder = 0 + + init(blockSize: Int, padding: Padding, _ worker: CipherModeWorker) throws { + self.blockSize = blockSize + self.padding = padding + self.worker = worker + } + + // MARK: Updatable + public func update(withBytes bytes: ArraySlice, isLast: Bool) throws -> Array { + accumulated += bytes + + let toProcess = accumulated.prefix(max(accumulated.count - worker.additionalBufferSize, 0)) + + if var finalizingWorker = worker as? FinalizingDecryptModeWorker, isLast == true { + // will truncate suffix if needed + try finalizingWorker.willDecryptLast(bytes: accumulated.slice) + } + + var processedBytesCount = 0 + var plaintext = Array(reserveCapacity: bytes.count + worker.additionalBufferSize) + for chunk in toProcess.batched(by: blockSize) { + plaintext += worker.decrypt(block: chunk) + processedBytesCount += chunk.count + } + + if var finalizingWorker = worker as? FinalizingDecryptModeWorker, isLast == true { + plaintext = Array(try finalizingWorker.didDecryptLast(bytes: plaintext.slice)) + } + + // omit unecessary calculation if not needed + if padding != .noPadding { + lastBlockRemainder = plaintext.count.quotientAndRemainder(dividingBy: blockSize).remainder + } + + if isLast { + // CTR doesn't need padding. Really. Add padding to the last block if really want. but... don't. + plaintext = padding.remove(from: plaintext, blockSize: blockSize - lastBlockRemainder) + } + + accumulated.removeFirst(processedBytesCount) // super-slow + + if var finalizingWorker = worker as? FinalizingDecryptModeWorker, isLast == true { + plaintext = Array(try finalizingWorker.finalize(decrypt: plaintext.slice)) + } + + return plaintext + } + + public func seek(to position: Int) throws { + guard var worker = self.worker as? SeekableModeWorker else { + fatalError("Not supported") + } + + try worker.seek(to: position) + self.worker = worker + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/StreamEncryptor.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/StreamEncryptor.swift new file mode 100644 index 0000000000..7cd54e3fb6 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/StreamEncryptor.swift @@ -0,0 +1,56 @@ +// CryptoSwift +// +// Copyright (C) 2014-2018 Marcin Krzyżanowski +// 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. +// + +final class StreamEncryptor: Cryptor, Updatable { + private let blockSize: Int + private var worker: CipherModeWorker + private let padding: Padding + + private var lastBlockRemainder = 0 + + init(blockSize: Int, padding: Padding, _ worker: CipherModeWorker) throws { + self.blockSize = blockSize + self.padding = padding + self.worker = worker + } + + // MARK: Updatable + public func update(withBytes bytes: ArraySlice, isLast: Bool) throws -> Array { + var accumulated = Array(bytes) + if isLast { + // CTR doesn't need padding. Really. Add padding to the last block if really want. but... don't. + accumulated = padding.add(to: accumulated, blockSize: blockSize - lastBlockRemainder) + } + + var encrypted = Array(reserveCapacity: bytes.count) + for chunk in accumulated.batched(by: blockSize) { + encrypted += worker.encrypt(block: chunk) + } + + // omit unecessary calculation if not needed + if padding != .noPadding { + lastBlockRemainder = encrypted.count.quotientAndRemainder(dividingBy: blockSize).remainder + } + + if var finalizingWorker = worker as? FinalizingEncryptModeWorker, isLast == true { + encrypted = Array(try finalizingWorker.finalize(encrypt: encrypted.slice)) + } + + return encrypted + } + + func seek(to: Int) throws { + fatalError("Not supported") + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/String+Extension.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/String+Extension.swift new file mode 100644 index 0000000000..b186e34142 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/String+Extension.swift @@ -0,0 +1,81 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +/** String extension */ +extension String { + public var bytes: Array { + return data(using: String.Encoding.utf8, allowLossyConversion: true)?.bytes ?? Array(utf8) + } + + public func md5() -> String { + return bytes.md5().toHexString() + } + + public func sha1() -> String { + return bytes.sha1().toHexString() + } + + public func sha224() -> String { + return bytes.sha224().toHexString() + } + + public func sha256() -> String { + return bytes.sha256().toHexString() + } + + public func sha384() -> String { + return bytes.sha384().toHexString() + } + + public func sha512() -> String { + return bytes.sha512().toHexString() + } + + public func sha3(_ variant: SHA3.Variant) -> String { + return bytes.sha3(variant).toHexString() + } + + public func crc32(seed: UInt32? = nil, reflect: Bool = true) -> String { + return bytes.crc32(seed: seed, reflect: reflect).bytes().toHexString() + } + + public func crc32c(seed: UInt32? = nil, reflect: Bool = true) -> String { + return bytes.crc32(seed: seed, reflect: reflect).bytes().toHexString() + } + + public func crc16(seed: UInt16? = nil) -> String { + return bytes.crc16(seed: seed).bytes().toHexString() + } + + /// - parameter cipher: Instance of `Cipher` + /// - returns: hex string of bytes + public func encrypt(cipher: Cipher) throws -> String { + return try bytes.encrypt(cipher: cipher).toHexString() + } + + /// - parameter cipher: Instance of `Cipher` + /// - returns: base64 encoded string of encrypted bytes + public func encryptToBase64(cipher: Cipher) throws -> String? { + return try bytes.encrypt(cipher: cipher).toBase64() + } + + // decrypt() does not make sense for String + + /// - parameter authenticator: Instance of `Authenticator` + /// - returns: hex string of string + public func authenticate(with authenticator: A) throws -> String { + return try bytes.authenticate(with: authenticator).toHexString() + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt128.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt128.swift new file mode 100644 index 0000000000..2015790279 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt128.swift @@ -0,0 +1,90 @@ +// +// UInt128.swift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +import Foundation + +struct UInt128: Equatable, ExpressibleByIntegerLiteral { + let i: (a: UInt64, b: UInt64) + + typealias IntegerLiteralType = UInt64 + + init(integerLiteral value: IntegerLiteralType) { + self = UInt128(value) + } + + init(_ raw: Array) { + self = raw.prefix(MemoryLayout.stride).withUnsafeBytes({ (rawBufferPointer) -> UInt128 in + let arr = rawBufferPointer.bindMemory(to: UInt64.self) + return UInt128((arr[0].bigEndian, arr[1].bigEndian)) + }) + } + + init(_ raw: ArraySlice) { + self.init(Array(raw)) + } + + init(_ i: (a: UInt64, b: UInt64)) { + self.i = i + } + + init(a: UInt64, b: UInt64) { + self.init((a, b)) + } + + init(_ b: UInt64) { + self.init((0, b)) + } + + // Bytes + var bytes: Array { + var at = i.a.bigEndian + var bt = i.b.bigEndian + + let ar = Data(bytes: &at, count: MemoryLayout.size(ofValue: at)) + let br = Data(bytes: &bt, count: MemoryLayout.size(ofValue: bt)) + + var result = Data() + result.append(ar) + result.append(br) + return result.bytes + } + + static func ^(n1: UInt128, n2: UInt128) -> UInt128 { + return UInt128((n1.i.a ^ n2.i.a, n1.i.b ^ n2.i.b)) + } + + static func &(n1: UInt128, n2: UInt128) -> UInt128 { + return UInt128((n1.i.a & n2.i.a, n1.i.b & n2.i.b)) + } + + static func >>(value: UInt128, by: Int) -> UInt128 { + var result = value + for _ in 0..> 1 + let b = result.i.b >> 1 + ((result.i.a & 1) << 63) + result = UInt128((a, b)) + } + return result + } + + // Equatable. + static func ==(lhs: UInt128, rhs: UInt128) -> Bool { + return lhs.i == rhs.i + } + + static func !=(lhs: UInt128, rhs: UInt128) -> Bool { + return !(lhs == rhs) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt16+Extension.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt16+Extension.swift new file mode 100644 index 0000000000..65f6289891 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt16+Extension.swift @@ -0,0 +1,37 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +/** array of bytes */ +extension UInt16 { + @_specialize(exported: true, where T == ArraySlice) + init(bytes: T) where T.Element == UInt8, T.Index == Int { + self = UInt16(bytes: bytes, fromIndex: bytes.startIndex) + } + + @_specialize(exported: true, where T == ArraySlice) + init(bytes: T, fromIndex index: T.Index) where T.Element == UInt8, T.Index == Int { + if bytes.isEmpty { + self = 0 + return + } + + let count = bytes.count + + let val0 = count > 0 ? UInt16(bytes[index.advanced(by: 0)]) << 8 : 0 + let val1 = count > 1 ? UInt16(bytes[index.advanced(by: 1)]) : 0 + + self = val0 | val1 + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt32+Extension.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt32+Extension.swift new file mode 100644 index 0000000000..0901148eb4 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt32+Extension.swift @@ -0,0 +1,48 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 canImport(Darwin) +import Darwin +#else +import Glibc +#endif + +protocol _UInt32Type {} +extension UInt32: _UInt32Type {} + +/** array of bytes */ +extension UInt32 { + @_specialize(exported: true, where T == ArraySlice) + init(bytes: T) where T.Element == UInt8, T.Index == Int { + self = UInt32(bytes: bytes, fromIndex: bytes.startIndex) + } + + @_specialize(exported: true, where T == ArraySlice) + init(bytes: T, fromIndex index: T.Index) where T.Element == UInt8, T.Index == Int { + if bytes.isEmpty { + self = 0 + return + } + + let count = bytes.count + + let val0 = count > 0 ? UInt32(bytes[index.advanced(by: 0)]) << 24 : 0 + let val1 = count > 1 ? UInt32(bytes[index.advanced(by: 1)]) << 16 : 0 + let val2 = count > 2 ? UInt32(bytes[index.advanced(by: 2)]) << 8 : 0 + let val3 = count > 3 ? UInt32(bytes[index.advanced(by: 3)]) : 0 + + self = val0 | val1 | val2 | val3 + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt64+Extension.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt64+Extension.swift new file mode 100644 index 0000000000..44a77d93ec --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt64+Extension.swift @@ -0,0 +1,43 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +/** array of bytes */ +extension UInt64 { + @_specialize(exported: true, where T == ArraySlice) + init(bytes: T) where T.Element == UInt8, T.Index == Int { + self = UInt64(bytes: bytes, fromIndex: bytes.startIndex) + } + + @_specialize(exported: true, where T == ArraySlice) + init(bytes: T, fromIndex index: T.Index) where T.Element == UInt8, T.Index == Int { + if bytes.isEmpty { + self = 0 + return + } + + let count = bytes.count + + let val0 = count > 0 ? UInt64(bytes[index.advanced(by: 0)]) << 56 : 0 + let val1 = count > 1 ? UInt64(bytes[index.advanced(by: 1)]) << 48 : 0 + let val2 = count > 2 ? UInt64(bytes[index.advanced(by: 2)]) << 40 : 0 + let val3 = count > 3 ? UInt64(bytes[index.advanced(by: 3)]) << 32 : 0 + let val4 = count > 4 ? UInt64(bytes[index.advanced(by: 4)]) << 24 : 0 + let val5 = count > 5 ? UInt64(bytes[index.advanced(by: 5)]) << 16 : 0 + let val6 = count > 6 ? UInt64(bytes[index.advanced(by: 6)]) << 8 : 0 + let val7 = count > 7 ? UInt64(bytes[index.advanced(by: 7)]) : 0 + + self = val0 | val1 | val2 | val3 | val4 | val5 | val6 | val7 + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt8+Extension.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt8+Extension.swift new file mode 100644 index 0000000000..481d57fdbb --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/UInt8+Extension.swift @@ -0,0 +1,76 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 canImport(Darwin) +import Darwin +#else +import Glibc +#endif + +public protocol _UInt8Type {} +extension UInt8: _UInt8Type {} + +/** casting */ +extension UInt8 { + /** cast because UInt8() because std initializer crash if value is > byte */ + static func with(value: UInt64) -> UInt8 { + let tmp = value & 0xff + return UInt8(tmp) + } + + static func with(value: UInt32) -> UInt8 { + let tmp = value & 0xff + return UInt8(tmp) + } + + static func with(value: UInt16) -> UInt8 { + let tmp = value & 0xff + return UInt8(tmp) + } +} + +/** Bits */ +extension UInt8 { + init(bits: [Bit]) { + self.init(integerFrom(bits) as UInt8) + } + + /** array of bits */ + public func bits() -> [Bit] { + let totalBitsCount = MemoryLayout.size * 8 + + var bitsArray = [Bit](repeating: Bit.zero, count: totalBitsCount) + + for j in 0.. String { + var s = String() + let arr: [Bit] = bits() + for idx in arr.indices { + s += (arr[idx] == Bit.one ? "1" : "0") + if idx.advanced(by: 1) % 8 == 0 { s += " " } + } + return s + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Updatable.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Updatable.swift new file mode 100644 index 0000000000..23f1654507 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Updatable.swift @@ -0,0 +1,98 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +/// A type that supports incremental updates. For example Digest or Cipher may be updatable +/// and calculate result incerementally. +public protocol Updatable { + /// Update given bytes in chunks. + /// + /// - parameter bytes: Bytes to process. + /// - parameter isLast: Indicate if given chunk is the last one. No more updates after this call. + /// - returns: Processed partial result data or empty array. + mutating func update(withBytes bytes: ArraySlice, isLast: Bool) throws -> Array + + /// Update given bytes in chunks. + /// + /// - Parameters: + /// - bytes: Bytes to process. + /// - isLast: Indicate if given chunk is the last one. No more updates after this call. + /// - output: Resulting bytes callback. + /// - Returns: Processed partial result data or empty array. + mutating func update(withBytes bytes: ArraySlice, isLast: Bool, output: (_ bytes: Array) -> Void) throws +} + +extension Updatable { + public mutating func update(withBytes bytes: ArraySlice, isLast: Bool = false, output: (_ bytes: Array) -> Void) throws { + let processed = try update(withBytes: bytes, isLast: isLast) + if !processed.isEmpty { + output(processed) + } + } + + public mutating func update(withBytes bytes: ArraySlice, isLast: Bool = false) throws -> Array { + return try update(withBytes: bytes, isLast: isLast) + } + + public mutating func update(withBytes bytes: Array, isLast: Bool = false) throws -> Array { + return try update(withBytes: bytes.slice, isLast: isLast) + } + + public mutating func update(withBytes bytes: Array, isLast: Bool = false, output: (_ bytes: Array) -> Void) throws { + return try update(withBytes: bytes.slice, isLast: isLast, output: output) + } + + /// Finish updates. This may apply padding. + /// - parameter bytes: Bytes to process + /// - returns: Processed data. + public mutating func finish(withBytes bytes: ArraySlice) throws -> Array { + return try update(withBytes: bytes, isLast: true) + } + + public mutating func finish(withBytes bytes: Array) throws -> Array { + return try finish(withBytes: bytes.slice) + } + + + /// Finish updates. May add padding. + /// + /// - Returns: Processed data + /// - Throws: Error + public mutating func finish() throws -> Array { + return try update(withBytes: [], isLast: true) + } + + /// Finish updates. This may apply padding. + /// - parameter bytes: Bytes to process + /// - parameter output: Resulting data + /// - returns: Processed data. + public mutating func finish(withBytes bytes: ArraySlice, output: (_ bytes: Array) -> Void) throws { + let processed = try update(withBytes: bytes, isLast: true) + if !processed.isEmpty { + output(processed) + } + } + + public mutating func finish(withBytes bytes: Array, output: (_ bytes: Array) -> Void) throws { + return try finish(withBytes: bytes.slice, output: output) + } + + /// Finish updates. May add padding. + /// + /// - Parameter output: Processed data + /// - Throws: Error + public mutating func finish(output: (Array) -> Void) throws { + try finish(withBytes: [], output: output) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Utils.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Utils.swift new file mode 100644 index 0000000000..17b368af0c --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/Utils.swift @@ -0,0 +1,115 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@_transparent +func rotateLeft(_ value: UInt8, by: UInt8) -> UInt8 { + return ((value << by) & 0xff) | (value >> (8 - by)) +} + +@_transparent +func rotateLeft(_ value: UInt16, by: UInt16) -> UInt16 { + return ((value << by) & 0xffff) | (value >> (16 - by)) +} + +@_transparent +func rotateLeft(_ value: UInt32, by: UInt32) -> UInt32 { + return ((value << by) & 0xffffffff) | (value >> (32 - by)) +} + +@_transparent +func rotateLeft(_ value: UInt64, by: UInt64) -> UInt64 { + return (value << by) | (value >> (64 - by)) +} + +@_transparent +func rotateRight(_ value: UInt16, by: UInt16) -> UInt16 { + return (value >> by) | (value << (16 - by)) +} + +@_transparent +func rotateRight(_ value: UInt32, by: UInt32) -> UInt32 { + return (value >> by) | (value << (32 - by)) +} + +@_transparent +func rotateRight(_ value: UInt64, by: UInt64) -> UInt64 { + return ((value >> by) | (value << (64 - by))) +} + +@_transparent +func reversed(_ uint8: UInt8) -> UInt8 { + var v = uint8 + v = (v & 0xf0) >> 4 | (v & 0x0f) << 4 + v = (v & 0xcc) >> 2 | (v & 0x33) << 2 + v = (v & 0xaa) >> 1 | (v & 0x55) << 1 + return v +} + +@_transparent +func reversed(_ uint32: UInt32) -> UInt32 { + var v = uint32 + v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1) + v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2) + v = ((v >> 4) & 0x0f0f0f0f) | ((v & 0x0f0f0f0f) << 4) + v = ((v >> 8) & 0x00ff00ff) | ((v & 0x00ff00ff) << 8) + v = ((v >> 16) & 0xffff) | ((v & 0xffff) << 16) + return v +} + +func xor(_ left: T, _ right: V) -> ArraySlice where T: RandomAccessCollection, V: RandomAccessCollection, T.Element == UInt8, T.Index == Int, V.Element == UInt8, V.Index == Int { + return xor(left, right).slice +} + +func xor(_ left: T, _ right: V) -> Array 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.allocate(capacity: length) + buf.initialize(repeating: 0, count: length) + defer { + buf.deinitialize(count: length) + buf.deallocate() + } + + // xor + for i in 0.., blockSize: Int, allowance: Int = 0) { + let msgLength = data.count + // Step 1. Append Padding Bits + // append one bit (UInt8 with one bit) to message + data.append(0x80) + + // Step 2. append "0" bit until message length in bits ≡ 448 (mod 512) + let max = blockSize - allowance // 448, 986 + if msgLength % blockSize < max { // 448 + data += Array(repeating: 0, count: max - 1 - (msgLength % blockSize)) + } else { + data += Array(repeating: 0, count: blockSize + max - 1 - (msgLength % blockSize)) + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/ZeroPadding.swift b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/ZeroPadding.swift new file mode 100644 index 0000000000..7d1d8276c6 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Sources/CryptoSwift/ZeroPadding.swift @@ -0,0 +1,38 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +/// 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() { + } + + func add(to bytes: Array, blockSize: Int) -> Array { + let paddingCount = blockSize - (bytes.count % blockSize) + if paddingCount > 0 { + return bytes + Array(repeating: 0, count: paddingCount) + } + return bytes + } + + func remove(from bytes: Array, blockSize _: Int?) -> Array { + for (idx, value) in bytes.reversed().enumerated() { + if value != 0 { + return Array(bytes[0.. +// 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. +// + +@testable import CryptoSwift +import Foundation +import XCTest + +final class AESCCMTests: XCTestCase { + + struct TestFixture { + let tagLength: Int + let key: Array + let nonce: Array + let aad: Array + let plaintext: Array + let expected: Array + + init(_ tagLength: Int, _ key: String, _ nonce: String, _ plaintext: String, _ expected: String, _ aad: String) { + self.tagLength = tagLength + self.key = Array(hex: key) + self.nonce = Array(hex: nonce) + self.aad = Array(hex: aad) + self.plaintext = Array(hex: plaintext) + self.expected = Array(hex: expected) + } + } + + func testAESCCMTestDVPT256() { + let fixtures = [ + //NIST Test vectors for AES-CCM with 256bit Key, from DVPT256.txt + //(Integer macLength, String key, String nonce, String plain, String ciphered, String aData) { + TestFixture(4, "eda32f751456e33195f1f499cf2dc7c97ea127b6d488f211ccc5126fbb24afa6", "a544218dadd3c1", "", "469c90bb", ""), + TestFixture(4, "eda32f751456e33195f1f499cf2dc7c97ea127b6d488f211ccc5126fbb24afa6", "dbb3923156cfd6", "", "1302d515", ""), + TestFixture(4, "eda32f751456e33195f1f499cf2dc7c97ea127b6d488f211ccc5126fbb24afa6", "a259c114eaac89", "", "4fe06e92", ""), + TestFixture(4, "eda32f751456e33195f1f499cf2dc7c97ea127b6d488f211ccc5126fbb24afa6", "e1be89af98ffd7", "", "e5417f6b", ""), + TestFixture(4, "eda32f751456e33195f1f499cf2dc7c97ea127b6d488f211ccc5126fbb24afa6", "1aa758eb2f9a28", "", "f8fa8e71", ""), + TestFixture(16, "e1b8a927a95efe94656677b692662000278b441c79e879dd5c0ddc758bdc9ee8", "a544218dadd3c1", "", "8207eb14d33855a52acceed17dbcbf6e", ""), + TestFixture(16, "e1b8a927a95efe94656677b692662000278b441c79e879dd5c0ddc758bdc9ee8", "dbb3923156cfd6", "", "e4dc5e03aacea691262ee69cee8ffbbe", ""), + TestFixture(16, "e1b8a927a95efe94656677b692662000278b441c79e879dd5c0ddc758bdc9ee8", "a259c114eaac89", "", "f79c53fd5e69835b7e70496ea999718b", ""), + TestFixture(16, "e1b8a927a95efe94656677b692662000278b441c79e879dd5c0ddc758bdc9ee8", "e1be89af98ffd7", "", "10d3f6fe08280d45e67e58fe41a7f036", ""), + TestFixture(16, "e1b8a927a95efe94656677b692662000278b441c79e879dd5c0ddc758bdc9ee8", "1aa758eb2f9a28", "", "2590df2453cb94c304ba0a2bff3f3c71", ""), + TestFixture(4, "e1b8a927a95efe94656677b692662000278b441c79e879dd5c0ddc758bdc9ee8", "a544218dadd3c10583db49cf39", "", "8a19a133", ""), + TestFixture(4, "e1b8a927a95efe94656677b692662000278b441c79e879dd5c0ddc758bdc9ee8", "79ac204a26b9fee1132370c20f", "", "154024b2", ""), + TestFixture(4, "e1b8a927a95efe94656677b692662000278b441c79e879dd5c0ddc758bdc9ee8", "0545fd9ecbc73ccdbbbd4244fd", "", "5c349fb2", ""), + TestFixture(4, "e1b8a927a95efe94656677b692662000278b441c79e879dd5c0ddc758bdc9ee8", "0a37f2e7c66490e97285f1b09e", "", "c59bf14c", ""), + TestFixture(4, "e1b8a927a95efe94656677b692662000278b441c79e879dd5c0ddc758bdc9ee8", "c1ad812bf2bbb2cdaee4636ee7", "", "5b96f41d", ""), + TestFixture(16, "af063639e66c284083c5cf72b70d8bc277f5978e80d9322d99f2fdc718cda569", "a544218dadd3c10583db49cf39", "","97e1a8dd4259ccd2e431e057b0397fcf", ""), + TestFixture(16, "af063639e66c284083c5cf72b70d8bc277f5978e80d9322d99f2fdc718cda569", "79ac204a26b9fee1132370c20f", "", "5c8c9a5b97be8c7bc01ca8d693b809f9", ""), + TestFixture(16, "af063639e66c284083c5cf72b70d8bc277f5978e80d9322d99f2fdc718cda569", "0545fd9ecbc73ccdbbbd4244fd", "", "84201662b213c7a1ff0c1b3c25e4ec45", ""), + TestFixture(16, "af063639e66c284083c5cf72b70d8bc277f5978e80d9322d99f2fdc718cda569", "0a37f2e7c66490e97285f1b09e", "", "586e728193ce6db9a926b03b2d77dd6e", ""), + TestFixture(16, "af063639e66c284083c5cf72b70d8bc277f5978e80d9322d99f2fdc718cda569", "c1ad812bf2bbb2cdaee4636ee7", "", "64864d21b6ee3fca13f07fc0486e232d", ""), + TestFixture(4, "af063639e66c284083c5cf72b70d8bc277f5978e80d9322d99f2fdc718cda569", "a544218dadd3c1", "d3d5424e20fbec43ae495353ed830271515ab104f8860c98", "64a1341679972dc5869fcf69b19d5c5ea50aa0b5e985f5b722aa8d59", ""), + TestFixture(4, "af063639e66c284083c5cf72b70d8bc277f5978e80d9322d99f2fdc718cda569", "9d773a31fe2ec7", "839d8cfa2c921c3cceb7d1f46bd2eaad706e53f64523d8c0", "5acfbe5e488976d8b9b77e69a736e8c919053f9415551209dce2d25e", ""), + TestFixture(4, "af063639e66c284083c5cf72b70d8bc277f5978e80d9322d99f2fdc718cda569", "24b7a65391f88b", "3bed52236182c19418867d468dbf47c8aac46c02445f99bb", "f00628e10e8e0115b4a4532a1212a23aade4090832c1972d750125f3", ""), + TestFixture(4, "af063639e66c284083c5cf72b70d8bc277f5978e80d9322d99f2fdc718cda569", "b672c91376f533", "4f7a561e61b7861719e4445057ac9b74a9be953b772b09ec", "758aa03dc72c362c43b5f85bfaa3db4a74860887a8c29e47d5642830", ""), + TestFixture(4, "af063639e66c284083c5cf72b70d8bc277f5978e80d9322d99f2fdc718cda569", "a6d01fb88ca547", "a36155de477364236591e453008114075b4872120ef17264", "615cbeabbe163ba8bc9c073df9ad40833fcf3f424644ccc37aa999d7", ""), + TestFixture(16, "f7079dfa3b5c7b056347d7e437bcded683abd6e2c9e069d333284082cbb5d453", "a544218dadd3c1", "d3d5424e20fbec43ae495353ed830271515ab104f8860c98", "bc51c3925a960e7732533e4ef3a4f69ee6826de952bcb0fd374f3bb6db8377ebfc79674858c4f305", ""), + TestFixture(16, "f7079dfa3b5c7b056347d7e437bcded683abd6e2c9e069d333284082cbb5d453", "9d773a31fe2ec7", "839d8cfa2c921c3cceb7d1f46bd2eaad706e53f64523d8c0", "4539bb13382b034ddb16a3329148f9243a4eee998fe444aff2870ce198af11f4fb698a67af6c89ad", ""), + TestFixture(16, "f7079dfa3b5c7b056347d7e437bcded683abd6e2c9e069d333284082cbb5d453", "24b7a65391f88b", "3bed52236182c19418867d468dbf47c8aac46c02445f99bb", "6d0f928352a17d63aca1899cbd305e1f831f1638d27c1e24432704eff9b6830476db3d30d4c103e4", ""), + TestFixture(16, "f7079dfa3b5c7b056347d7e437bcded683abd6e2c9e069d333284082cbb5d453", "b672c91376f533", "4f7a561e61b7861719e4445057ac9b74a9be953b772b09ec", "f23ac1426cb1130c9a0913b347d8efafb6ed125913aa678a9dc42d22a5436bc12eff5505edb25e19", ""), + TestFixture(16, "f7079dfa3b5c7b056347d7e437bcded683abd6e2c9e069d333284082cbb5d453", "a6d01fb88ca547", "a36155de477364236591e453008114075b4872120ef17264", "773b8eea2e9830297ac11d3c1f6ea4008c96040e83d76d55789d2043179fdd8fdcbd52313b7b15cb", ""), + TestFixture(4, "f7079dfa3b5c7b056347d7e437bcded683abd6e2c9e069d333284082cbb5d453", "a544218dadd3c10583db49cf39", "3c0e2815d37d844f7ac240ba9d6e3a0b2a86f706e885959e", "63e00d30e4b08fd2a1cc8d70fab327b2368e77a93be4f4123d14fb3f", ""), + TestFixture(4, "f7079dfa3b5c7b056347d7e437bcded683abd6e2c9e069d333284082cbb5d453", "1501a243bf60b2cb40d5aa20ca", "f5730a05fec31a11662e2e14e362ccc75c7c30cdfccbf994", "377b2f1e7bd9e3d1077038e084f61950761361095f7eeebbf1a72afc", ""), + TestFixture(4, "f7079dfa3b5c7b056347d7e437bcded683abd6e2c9e069d333284082cbb5d453", "d65e0e53f765f9d5e6795c0c5e", "20e394c7cc90bdfa6186fc1ba6fff158dfc690e24ba4c9fb", "6cab3060bf3b33b163b933c2ed0ba51406810b54d0edcf5c9d0ef4f7", ""), + TestFixture(4, "f7079dfa3b5c7b056347d7e437bcded683abd6e2c9e069d333284082cbb5d453", "a6b2371acf8321864c08ddb4d8", "1a43ca628026219c5a430c54021a5a3152ae517167399635", "c5aa500d1f7c09a590e9d15d6860c4433684e04dd6bc5c8f94f223f0", ""), + TestFixture(4, "f7079dfa3b5c7b056347d7e437bcded683abd6e2c9e069d333284082cbb5d453", "c2b60f14c894ec6178fe79919f", "3e707d98f19972a63d913e6ea7533af2f41ff98aee2b2a36", "852cca903d7fdf899807bd14642057534c8a0ccacb8c7b8fb4d35d44", ""), + TestFixture(16, "1b0e8df63c57f05d9ac457575ea764524b8610ae5164e6215f426f5a7ae6ede4", "a544218dadd3c10583db49cf39", "3c0e2815d37d844f7ac240ba9d6e3a0b2a86f706e885959e", "f0050ad16392021a3f40207bed3521fb1e9f808f49830c423a578d179902f912f9ea1afbce1120b3", ""), + TestFixture(16, "1b0e8df63c57f05d9ac457575ea764524b8610ae5164e6215f426f5a7ae6ede4", "1501a243bf60b2cb40d5aa20ca", "f5730a05fec31a11662e2e14e362ccc75c7c30cdfccbf994", "254b847d4175bbb44a82b4e805514fa444c224710933f3ec8aaa3f0133234c0cd91609982adc034b", ""), + TestFixture(16, "1b0e8df63c57f05d9ac457575ea764524b8610ae5164e6215f426f5a7ae6ede4", "d65e0e53f765f9d5e6795c0c5e", "20e394c7cc90bdfa6186fc1ba6fff158dfc690e24ba4c9fb", "c3618c991b15de641d291419ff6957e8b9ae5046dd8c6f08fafb76adf12f36740347e3edae62bca4", ""), + TestFixture(16, "1b0e8df63c57f05d9ac457575ea764524b8610ae5164e6215f426f5a7ae6ede4", "a6b2371acf8321864c08ddb4d8", "1a43ca628026219c5a430c54021a5a3152ae517167399635", "bd37326da18e5ac79a1a9512f724bb539530868576b79c67acb5a51d10a58d6584fbe73f1063c31b", ""), + TestFixture(16, "1b0e8df63c57f05d9ac457575ea764524b8610ae5164e6215f426f5a7ae6ede4", "c2b60f14c894ec6178fe79919f", "3e707d98f19972a63d913e6ea7533af2f41ff98aee2b2a36", "ecd337640022635ce1ed273756d02b7feeb2515614c1fadc95c66d3f411b478853886afd177d88c3", ""), + TestFixture(4, "1b0e8df63c57f05d9ac457575ea764524b8610ae5164e6215f426f5a7ae6ede4", "a544218dadd3c1", "", "92d00fbe", "d3d5424e20fbec43ae495353ed830271515ab104f8860c988d15b6d36c038eab"), + TestFixture(4, "1b0e8df63c57f05d9ac457575ea764524b8610ae5164e6215f426f5a7ae6ede4", "3fcb328bc96404", "", "11250056", "10b2ffed4f95af0f98ed4f77c677b5786ad01b31c095bbc6e1c99cf13977abba"), + TestFixture(4, "1b0e8df63c57f05d9ac457575ea764524b8610ae5164e6215f426f5a7ae6ede4", "c42ac63de6f12a", "", "4eed80fd", "7ff8d06c5abcc50d3820de34b03089e6c5b202bcbaabca892825553d4d30020a"), + TestFixture(4, "1b0e8df63c57f05d9ac457575ea764524b8610ae5164e6215f426f5a7ae6ede4", "3a1701b185d33a", "", "9a5382c3", "e5d54df8ed9f89b98c5ebb1bc5d5279c2e182784ff4cd9c869ae152e29d7a2b2"), + TestFixture(4, "1b0e8df63c57f05d9ac457575ea764524b8610ae5164e6215f426f5a7ae6ede4", "4f490ce07e0150", "", "e1842c46", "3e12d09632c644c540077c6f90726d4167423a679322b2000a3f19cfcea02b33"), + TestFixture(16, "a4bc10b1a62c96d459fbaf3a5aa3face7313bb9e1253e696f96a7a8e36801088", "a544218dadd3c1", "", "93af11a08379eb37a16aa2837f09d69d", "d3d5424e20fbec43ae495353ed830271515ab104f8860c988d15b6d36c038eab"), + TestFixture(16, "a4bc10b1a62c96d459fbaf3a5aa3face7313bb9e1253e696f96a7a8e36801088", "3fcb328bc96404", "", "b3884b69d117146cfa5529901753ddc0", "10b2ffed4f95af0f98ed4f77c677b5786ad01b31c095bbc6e1c99cf13977abba"), + TestFixture(16, "a4bc10b1a62c96d459fbaf3a5aa3face7313bb9e1253e696f96a7a8e36801088", "c42ac63de6f12a", "", "b53d93cbfd3d5cf3720cef5080bc7224", "7ff8d06c5abcc50d3820de34b03089e6c5b202bcbaabca892825553d4d30020a"), + TestFixture(16, "a4bc10b1a62c96d459fbaf3a5aa3face7313bb9e1253e696f96a7a8e36801088", "3a1701b185d33a", "", "0a5d1bc02c5fe096a8b9d94d1267c49a", "e5d54df8ed9f89b98c5ebb1bc5d5279c2e182784ff4cd9c869ae152e29d7a2b2"), + TestFixture(16, "a4bc10b1a62c96d459fbaf3a5aa3face7313bb9e1253e696f96a7a8e36801088", "4f490ce07e0150", "", "1eda43bf07f2bf003107f3a0ba3a4c18", "3e12d09632c644c540077c6f90726d4167423a679322b2000a3f19cfcea02b33"), + TestFixture(4, "a4bc10b1a62c96d459fbaf3a5aa3face7313bb9e1253e696f96a7a8e36801088", "a544218dadd3c10583db49cf39", "", "866d4227", "3c0e2815d37d844f7ac240ba9d6e3a0b2a86f706e885959e09a1005e024f6907"), + TestFixture(4, "a4bc10b1a62c96d459fbaf3a5aa3face7313bb9e1253e696f96a7a8e36801088", "dfdcbdff329f7af70731d8e276", "", "c4ac0952", "2ae56ddde2876d70b3b34eda8c2b1d096c836d5225d53ec460b724b6e16aa5a3"), + TestFixture(4, "a4bc10b1a62c96d459fbaf3a5aa3face7313bb9e1253e696f96a7a8e36801088", "60f2490ba0c658848859fcbea8", "", "27c3953d", "3ad743283064929bf4fe4e0807f710f5e6a273e22614c728c3280a27b6c614a0"), + TestFixture(4, "a4bc10b1a62c96d459fbaf3a5aa3face7313bb9e1253e696f96a7a8e36801088", "db113f38f0504615c5c9347c3d", "", "c38fbdff", "3b71bc84e48c6dadf6ead14621d22468a3d4c9c103ac96970269730bcfce239b"), + TestFixture(4, "a4bc10b1a62c96d459fbaf3a5aa3face7313bb9e1253e696f96a7a8e36801088", "d35f531f714694b5e49303a980", "", "d34e90bb", "55b791ee495299916ff3c2327b4990952bebd0a2da9acfc553c6c996e354a4b5"), + TestFixture(16, "8c5cf3457ff22228c39c051c4e05ed4093657eb303f859a9d4b0f8be0127d88a", "a544218dadd3c10583db49cf39", "", "867b0d87cf6e0f718200a97b4f6d5ad5", "3c0e2815d37d844f7ac240ba9d6e3a0b2a86f706e885959e09a1005e024f6907"), + TestFixture(16, "8c5cf3457ff22228c39c051c4e05ed4093657eb303f859a9d4b0f8be0127d88a", "dfdcbdff329f7af70731d8e276", "", "ad879c64425e6c1ec4841bbb0f99aa8b", "2ae56ddde2876d70b3b34eda8c2b1d096c836d5225d53ec460b724b6e16aa5a3"), + TestFixture(16, "8c5cf3457ff22228c39c051c4e05ed4093657eb303f859a9d4b0f8be0127d88a", "60f2490ba0c658848859fcbea8", "", "e2751f153fc76c0dec5e0cf2d30c1a28", "3ad743283064929bf4fe4e0807f710f5e6a273e22614c728c3280a27b6c614a0"), + TestFixture(16, "8c5cf3457ff22228c39c051c4e05ed4093657eb303f859a9d4b0f8be0127d88a", "db113f38f0504615c5c9347c3d", "", "fc85464a81fe372c12c9e4f0f3bf9c37", "3b71bc84e48c6dadf6ead14621d22468a3d4c9c103ac96970269730bcfce239b"), + TestFixture(16, "8c5cf3457ff22228c39c051c4e05ed4093657eb303f859a9d4b0f8be0127d88a", "d35f531f714694b5e49303a980", "", "b1c09b093788da19e33c5a6e82ed9627", "55b791ee495299916ff3c2327b4990952bebd0a2da9acfc553c6c996e354a4b5"), + TestFixture(4, "8c5cf3457ff22228c39c051c4e05ed4093657eb303f859a9d4b0f8be0127d88a", "a544218dadd3c1", "78c46e3249ca28e1ef0531d80fd37c124d9aecb7be6668e3", "c2fe12658139f5d0dd22cadf2e901695b579302a72fc56083ebc7720", "d3d5424e20fbec43ae495353ed830271515ab104f8860c988d15b6d36c038eab"), + TestFixture(4, "8c5cf3457ff22228c39c051c4e05ed4093657eb303f859a9d4b0f8be0127d88a", "57b940550a383b", "6fb5ce32a851676753ba3523edc5ca82af1843ffc08f1ef0", "e1b4ec4279bb62902c12521e6b874171695c5da46c647cc03b91ff03", "33c2c3a57bf8393b126982c96d87daeacd5eadad1519073ad8c84cb9b760296f"), + TestFixture(4, "8c5cf3457ff22228c39c051c4e05ed4093657eb303f859a9d4b0f8be0127d88a", "f32222e9eec4bd", "2c29d4e2bb9294e90cb04ec697e663a1f7385a39f90c8ccf", "224db21beb8cd0069007660e783c3f85706b014128368aab2a4e56a7", "684595e36eda1db5f586941c9f34c9f8d477970d5ccc14632d1f0cec8190ae68"), + TestFixture(4, "8c5cf3457ff22228c39c051c4e05ed4093657eb303f859a9d4b0f8be0127d88a", "14c9bd561c47c1", "c22524a1ea444be3412b0d773d4ea2ff0af4c1ad2383cba8", "61b46c9024eed3989064a52df90349c18e14e4b552779d3f8f9d6814", "141ae365f8e65ab9196c4e8cd4e62189b304d67de38f2117e84ec0ec8f260ebd"), + TestFixture(4, "8c5cf3457ff22228c39c051c4e05ed4093657eb303f859a9d4b0f8be0127d88a", "1ccec9923aa6e8", "518a7fb11c463bf23798982118f3cfe4d7ddde9184f37d4f", "52f8205534447d722be2b9377f7395938cc88af081a11ccb0d83fa19", "88a6d037009a1c1756f72bb4589d6d940bd514ed55386baefacc6ac3ca6f8795"), + TestFixture(16, "705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe", "a544218dadd3c1", "78c46e3249ca28e1ef0531d80fd37c124d9aecb7be6668e3", "3341168eb8c48468c414347fb08f71d2086f7c2d1bd581ce1ac68bd42f5ec7fa7e068cc0ecd79c2a", "d3d5424e20fbec43ae495353ed830271515ab104f8860c988d15b6d36c038eab"), + TestFixture(16, "705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe", "57b940550a383b", "6fb5ce32a851676753ba3523edc5ca82af1843ffc08f1ef0", "fbfed2c94f50ca10466da9903ef85833ad48ca00556e66d14d8b30df941f3536ffb42083ef0e1c30", "33c2c3a57bf8393b126982c96d87daeacd5eadad1519073ad8c84cb9b760296f"), + TestFixture(16, "705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe", "f32222e9eec4bd", "2c29d4e2bb9294e90cb04ec697e663a1f7385a39f90c8ccf", "dae13e6967c8b1ee0dd2d5ba1dd1de69f22c95da39528f9ef78e9e5e9faa058112af57f4ac78db2c", "684595e36eda1db5f586941c9f34c9f8d477970d5ccc14632d1f0cec8190ae68"), + TestFixture(16, "705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe", "14c9bd561c47c1", "c22524a1ea444be3412b0d773d4ea2ff0af4c1ad2383cba8", "a654238fb8b05e293dba07f9d68d75a7f0fbf40fe20edaeba1586bf922412e73ce338e372615c3bc", "141ae365f8e65ab9196c4e8cd4e62189b304d67de38f2117e84ec0ec8f260ebd"), + TestFixture(16, "705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe", "1ccec9923aa6e8", "518a7fb11c463bf23798982118f3cfe4d7ddde9184f37d4f", "765067ef768908d91ee4c3923943e0c7be70e2e06db99a4b3e3f51ee37fdcc5d81dd85d9e9d4f44e", "88a6d037009a1c1756f72bb4589d6d940bd514ed55386baefacc6ac3ca6f8795"), + TestFixture(4, "705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe", "a544218dadd3c10583db49cf39", "e8de970f6ee8e80ede933581b5bcf4d837e2b72baa8b00c3", "c0ea400b599561e7905b99262b4565d5c3dc49fad84d7c69ef891339", "3c0e2815d37d844f7ac240ba9d6e3a0b2a86f706e885959e09a1005e024f6907"), + TestFixture(4, "705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe", "0dd613c0fe28e913c0edbb8404", "9522fb1f1aa58493cba682d788186d902cfc93e80fd6b998", "fabe11c9629e598228f5209f3dbcc641fe4b1a22cadb0821d2898c3b", "2ad306575b577c2f61da7212ab63e3db3941f1f751f2356c7443531a90b9d141"), + TestFixture(4, "705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe", "3e0fe3427eeda80f02dda4fed5", "38333ce78110bf53a2c2abc7db99e133ad218ca43ff7a7bc", "d88f8fcd772125212ce09c2a6e5b5693dd35073f992004f0d18fc889", "ae0d1c9c834d60ff0ecfb3c0d78c72ddb789e58adfc166c81d5fc6395b31ec33"), + TestFixture(4, "705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe", "60122cbd219e5cf17415e8bc09", "794e734966e6d0001699aec3f8ab8f194de7653d3091b1b9", "76bdd9a7b34bf14ae121a87fdfa144f71b848744af6a2f0b1c0d067c", "895a45ddbe0c80793eccbf820de13a233b6aa7045cfd5313388e7184c392b216"), + TestFixture(4, "705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe", "3542fbe0f59a6d5f3abf619b7d", "c5b3d71312ea14f2f8fae5bd1a453192b6604a45db75c5ed", "617d8036e2039d516709062379e0550cbd71ebb90fea967c79018ad5", "dd4531f158a2fa3bc8a339f770595048f4a42bc1b03f2e824efc6ba4985119d8"), + TestFixture(16, "314a202f836f9f257e22d8c11757832ae5131d357a72df88f3eff0ffcee0da4e", "a544218dadd3c10583db49cf39", "e8de970f6ee8e80ede933581b5bcf4d837e2b72baa8b00c3", "8d34cdca37ce77be68f65baf3382e31efa693e63f914a781367f30f2eaad8c063ca50795acd90203", "3c0e2815d37d844f7ac240ba9d6e3a0b2a86f706e885959e09a1005e024f6907"), + TestFixture(16, "314a202f836f9f257e22d8c11757832ae5131d357a72df88f3eff0ffcee0da4e", "0dd613c0fe28e913c0edbb8404", "9522fb1f1aa58493cba682d788186d902cfc93e80fd6b998", "6df09613ea986c2d91a57a45a0942cbf20e0dfca12fbda8c945ee6db24aea5f5098952f1203339ce", "2ad306575b577c2f61da7212ab63e3db3941f1f751f2356c7443531a90b9d141"), + TestFixture(16, "314a202f836f9f257e22d8c11757832ae5131d357a72df88f3eff0ffcee0da4e", "3e0fe3427eeda80f02dda4fed5", "38333ce78110bf53a2c2abc7db99e133ad218ca43ff7a7bc", "2bfe51f1f43b982d47f76ea8206ddbf585d6f30cec0d4ef16b1556631d3b52bf24154afec1448ef6", "ae0d1c9c834d60ff0ecfb3c0d78c72ddb789e58adfc166c81d5fc6395b31ec33"), + TestFixture(16, "314a202f836f9f257e22d8c11757832ae5131d357a72df88f3eff0ffcee0da4e", "60122cbd219e5cf17415e8bc09", "794e734966e6d0001699aec3f8ab8f194de7653d3091b1b9", "bf0d219bb50fcc1d51f654bb0fd8b44efa25aef39e2f11afe47d00f2eebb544e6ba7559ac2f34edb", "895a45ddbe0c80793eccbf820de13a233b6aa7045cfd5313388e7184c392b216"), + TestFixture(16, "314a202f836f9f257e22d8c11757832ae5131d357a72df88f3eff0ffcee0da4e", "3542fbe0f59a6d5f3abf619b7d", "c5b3d71312ea14f2f8fae5bd1a453192b6604a45db75c5ed", "39c2e8f6edfe663b90963b98eb79e2d4f7f28a5053ae8881567a6b4426f1667136bed4a5e32a2bc1", "dd4531f158a2fa3bc8a339f770595048f4a42bc1b03f2e824efc6ba4985119d8"), + TestFixture(16, "c6c14c655e52c8a4c7e8d54e974d698e1f21ee3ba717a0adfa6136d02668c476", "291e91b19de518cd7806de44f6", "", "ca482c674b599046cc7d7ee0d00eec1e", "b4f8326944a45d95f91887c2a6ac36b60eea5edef84c1c358146a666b6878335"), + TestFixture(16, "c6c14c655e52c8a4c7e8d54e974d698e1f21ee3ba717a0adfa6136d02668c476", "291e91b19de518cd7806de44f6", "", "67747defe5da5fecc00b9bf3b249f434", "36c17fd901169e5b144fdb2c4bea8cd65ad8acf7b4d3dd39acf2ad83da7b1971"), + TestFixture(16, "c6c14c655e52c8a4c7e8d54e974d698e1f21ee3ba717a0adfa6136d02668c476", "291e91b19de518cd7806de44f6", "", "c57ef5d0faf49149c311707493a4cfd4", "9a37c654ab8e5a0c6bdfff9793457197d206ed207d768cbc8318cfb39f077b89"), + TestFixture(16, "c6c14c655e52c8a4c7e8d54e974d698e1f21ee3ba717a0adfa6136d02668c476", "291e91b19de518cd7806de44f6", "", "bc2fb5571a7563bb90689a229d2f63a7", "5ab80169184541393a6975f442ee583cd432d71a6d1568fa51159df7c5b8f959"), + TestFixture(16, "c6c14c655e52c8a4c7e8d54e974d698e1f21ee3ba717a0adfa6136d02668c476", "291e91b19de518cd7806de44f6", "", "428888c6420c56806f465b415a66e65a", "c78a22a667aafab0c94047e03837d51b11490693d5c57ea27b901ff80b6a38f9"), + TestFixture(16, "c6c14c655e52c8a4c7e8d54e974d698e1f21ee3ba717a0adfa6136d02668c476", "291e91b19de518cd7806de44f6", "", "9f1b7520025e1075731adc946b80121d", "e11e30cbf63623816379f578788b0c8e6b59ee3c9c50aa6e1dcd749172d48fed"), + TestFixture(16, "c6c14c655e52c8a4c7e8d54e974d698e1f21ee3ba717a0adfa6136d02668c476", "291e91b19de518cd7806de44f6", "", "bd36b053b6a90f19e3b6622cba93105d", "05716168829276ff7ab23b7dd373db361e6d9e1f11d0028d374a0d3fe62be19f"), + TestFixture(16, "c6c14c655e52c8a4c7e8d54e974d698e1f21ee3ba717a0adfa6136d02668c476", "291e91b19de518cd7806de44f6", "", "458595a3413b965b189de46703760aa0", "3e915389639435629fcc01e1b7022d3574e2848e9151261ad801d03387425dd7"), + TestFixture(16, "c6c14c655e52c8a4c7e8d54e974d698e1f21ee3ba717a0adfa6136d02668c476", "291e91b19de518cd7806de44f6", "", "8b259b84a6ee5669e175affca8ba3b1a", "2f496be73a9a5d9db5927e622e166c6ec946150687b21c51c8ca7e680f9775ac"), + TestFixture(16, "c6c14c655e52c8a4c7e8d54e974d698e1f21ee3ba717a0adfa6136d02668c476", "291e91b19de518cd7806de44f6", "", "c5f35fdf2b63e77a18d154f0ddcfedbf", "0a8725bd8c8eab9ed52ca47835837b9f00a6c8d834ab17105b01eb4eb30402e7"), + TestFixture(16, "cc49d4a397887cb57bc92c8a8c26a7aac205c653ef4011c1f48390ad35f5df14", "6df8c5c28d1728975a0b766cd7", "1a", "a5f24e87a11a95374d4c190945bf08ef2f", "080f82469505118842e5fa70df5323de175a37609904ee5e76288f94ca84b3c5"), + TestFixture(16, "cc49d4a397887cb57bc92c8a8c26a7aac205c653ef4011c1f48390ad35f5df14", "6df8c5c28d1728975a0b766cd7", "40", "ffd43c5f39be92778fdce3c832d2d3a019", "f6cfb81373f1cbb0574dda514747d0099635b48cb809c6f1fa30cbb671baa505"), + TestFixture(16, "cc49d4a397887cb57bc92c8a8c26a7aac205c653ef4011c1f48390ad35f5df14", "6df8c5c28d1728975a0b766cd7", "41", "fe753b7b661f1aad57c24c889b1c4fe513", "5a88b14bada16b513d4aa349b11ce4a77d4cda6f6322ff4939ad77d8ecb63748"), + TestFixture(16, "cc49d4a397887cb57bc92c8a8c26a7aac205c653ef4011c1f48390ad35f5df14", "6df8c5c28d1728975a0b766cd7", "06", "b91c5ac66e89bf2769ef5f38a3f1738b24", "a92b95b997cf9efded9ff5e1bff2e49d32e65f6283552ded4b05485b011f853f"), + TestFixture(16, "cc49d4a397887cb57bc92c8a8c26a7aac205c653ef4011c1f48390ad35f5df14", "6df8c5c28d1728975a0b766cd7", "c8", "773fe64379cea1a8ae3627418dd3e489a2", "a206a1eb70a9d24bb5e72f314e7d91de074f59055653bdd24aab5f2bbe112436"), + TestFixture(16, "cc49d4a397887cb57bc92c8a8c26a7aac205c653ef4011c1f48390ad35f5df14", "6df8c5c28d1728975a0b766cd7", "e2", "5dabc529442ff93005551b7689bcb748f7", "d3029f384fd7859c287e38c61a9475d5ddbfd64af93746b1dc86b8842a8c194c"), + TestFixture(16, "cc49d4a397887cb57bc92c8a8c26a7aac205c653ef4011c1f48390ad35f5df14", "6df8c5c28d1728975a0b766cd7", "1a", "a5ee68e416617ac974b3d1af7320cd51f6", "51ca3d3b70b5e354451a5177d7acfd8e7b44eae55e29d88b5e8eb8fc1e5c62fc"), + TestFixture(16, "cc49d4a397887cb57bc92c8a8c26a7aac205c653ef4011c1f48390ad35f5df14", "6df8c5c28d1728975a0b766cd7", "dd", "6243883d93d7066991e0fac453400b4fbf", "8c6c6791f1ac957b18bf008e260a0af4a5b7bfdb1e0008d6eaaa227f45cf4f62"), + TestFixture(16, "cc49d4a397887cb57bc92c8a8c26a7aac205c653ef4011c1f48390ad35f5df14", "6df8c5c28d1728975a0b766cd7", "4c", "f3b940d416f3435812f9d1b18f441b7721", "b0a1af969a95025385b251afd1e89f353426ed6e5d71019cd73366aa31d5b464"), + TestFixture(16, "cc49d4a397887cb57bc92c8a8c26a7aac205c653ef4011c1f48390ad35f5df14", "6df8c5c28d1728975a0b766cd7", "88", "371d27e9a32feea28a6a7e7da2d27e1cc4", "7e72b2ca698a18cb0bf625f5daddb0d40643009db938340a9e4fe164a052fee1"), + TestFixture(16, "36b0175379e7ae19c277fe656a2252a82796309be0f0d4e1c07fdde88aca4510", "021bd8b551947be4c18cf1a455", "be80", "ecacc3152e43d9efea26e16c1d1793e2a8c4", "b5c6e8313b9c68e6bb84bffd65fa4108d243f580eab99bb80563ed1050c8266b"), + TestFixture(16, "36b0175379e7ae19c277fe656a2252a82796309be0f0d4e1c07fdde88aca4510", "021bd8b551947be4c18cf1a455", "82c9", "d0e5d06bf4b50ccce0b2acfd16ce90a8854d", "38e5032c5949c2668191ef1af5bb17eddc28abdb4e5bb41eaffec2523b2525d6"), + TestFixture(16, "36b0175379e7ae19c277fe656a2252a82796309be0f0d4e1c07fdde88aca4510", "021bd8b551947be4c18cf1a455", "8239", "d0158d784f486c1dc4a2bafd5b02ca1e1c05", "0b50f5173249fb7118f80d25874d6745d88e4ce265fa0dd141ad67ae26c31122"), + TestFixture(16, "36b0175379e7ae19c277fe656a2252a82796309be0f0d4e1c07fdde88aca4510", "021bd8b551947be4c18cf1a455", "16c1", "44eda3377002a48f9fe306d157358e6df37d", "0296743a3125b103a2b2a78a109e825ea10834bd684215ab2e85cc4172e37348"), + TestFixture(16, "36b0175379e7ae19c277fe656a2252a82796309be0f0d4e1c07fdde88aca4510", "021bd8b551947be4c18cf1a455", "2801", "7a2df6c09bf1dcb1c82bd98c6e2c13a8d7a5", "a94e64becb803e211785ba51db7f3db042fbf44a7a821509156a6828b0f207e9"), + TestFixture(16, "36b0175379e7ae19c277fe656a2252a82796309be0f0d4e1c07fdde88aca4510", "021bd8b551947be4c18cf1a455", "65e7", "37cb2ea363c0d8864363056467570959ba03", "105358cc17b12107e023a23d57b44c66a2c58d8db05100311575e1ea152fc350"), + TestFixture(16, "36b0175379e7ae19c277fe656a2252a82796309be0f0d4e1c07fdde88aca4510", "021bd8b551947be4c18cf1a455", "819d", "d3b16519377e6d0252b5f80cdf3d0253eccf", "669f9a63cf638a202dca1965c4116273249813ce0b39703887d89bdf5b3b12d6"), + TestFixture(16, "36b0175379e7ae19c277fe656a2252a82796309be0f0d4e1c07fdde88aca4510", "021bd8b551947be4c18cf1a455", "761e", "24329a4dee6ca2cde473f08f76f779856c3c", "e288590a3eba28ac6847a50b0294ab6bd0a548716ff5102c44a5b656b2d9ddd6"), + TestFixture(16, "36b0175379e7ae19c277fe656a2252a82796309be0f0d4e1c07fdde88aca4510", "021bd8b551947be4c18cf1a455", "56de", "04f29e65c0f01e644e74092253b470cd5511", "5b222aae3c7786c3b9021ba672f9136190ec931cf055f84c85706127f74c6d5b"), + TestFixture(16, "36b0175379e7ae19c277fe656a2252a82796309be0f0d4e1c07fdde88aca4510", "021bd8b551947be4c18cf1a455", "b275", "e059809fa107f379957b52ac29fe0bc8a1e2", "2082f96c7e36b204ad076d8b2f796cccf5cbc80b8384b53a504e07706b07f596"), + TestFixture(16, "ddb739acda6c56ec9aefc4f4cbc258587f443da4e76ddfa85dbe0813a8784944", "0bddf342121b82f906368b0d7b", "db457c", "54473c3f65d6be431e79700378049ac06f2599", "887486fff7922768186363ef17eb78e5cf2fab8f47a4eb327de8b16d63b02acb"), + TestFixture(16, "ddb739acda6c56ec9aefc4f4cbc258587f443da4e76ddfa85dbe0813a8784944", "0bddf342121b82f906368b0d7b", "62a6c5", "eda4853b186edc15c22ba24e470eb5a072da9f", "0683c20e82d3c66787cb047f0b1eb1c58cdde9fb99ee4e4494bbf27eb62777d1"), + TestFixture(16, "ddb739acda6c56ec9aefc4f4cbc258587f443da4e76ddfa85dbe0813a8784944", "0bddf342121b82f906368b0d7b", "cc67bc", "4365fc52a1fb5a58bd51931230c1a7dfb1a8c1", "413074619b598f8bed34cab51ddf59941861ba0169ebe7570a5ed01d790c08e5"), + TestFixture(16, "ddb739acda6c56ec9aefc4f4cbc258587f443da4e76ddfa85dbe0813a8784944", "0bddf342121b82f906368b0d7b", "33800b", "bc824b7d3810f59176cb108c7e969da51d4d79", "2d65a5175c29a095dc082dab9cfcf4b895efbfa715c57614589d4db159543ce9"), + TestFixture(16, "ddb739acda6c56ec9aefc4f4cbc258587f443da4e76ddfa85dbe0813a8784944", "0bddf342121b82f906368b0d7b", "b2c826", "3dca6646ffea832595c9c86e6517215541ddbd", "6a831b6059456be98e6fce608d8c71cb8efb04a96b45c2dfbdaeabf5420a1482"), + TestFixture(16, "ddb739acda6c56ec9aefc4f4cbc258587f443da4e76ddfa85dbe0813a8784944", "0bddf342121b82f906368b0d7b", "d7e620", "58e460e89a6725f0fc35622d89d2f3e34be90a", "3a04a01160402bf36f33337c340883597207972728c5014213980cd7744e9e41"), + TestFixture(16, "ddb739acda6c56ec9aefc4f4cbc258587f443da4e76ddfa85dbe0813a8784944", "0bddf342121b82f906368b0d7b", "795af4", "f658b4b1bd7ad5d81686aeb44caa6025d488bd", "64d8bd3c646f76dc6ce89defd40777fe17316729e22ba90f6a2443ee03f6390b"), + TestFixture(16, "ddb739acda6c56ec9aefc4f4cbc258587f443da4e76ddfa85dbe0813a8784944", "0bddf342121b82f906368b0d7b", "66efcd", "e9ed8d0553c801f37c2b6f82861a3cd68a75e3", "7bef8d35616108922aab78936967204980b8a4945b31602f5ef2feec9b144841"), + TestFixture(16, "ddb739acda6c56ec9aefc4f4cbc258587f443da4e76ddfa85dbe0813a8784944", "0bddf342121b82f906368b0d7b", "78b00d", "f7b24de3eeb8ea6c08b466baf246b3667feb3f", "92f7dc22dcbbe6420aca303bd586e5a24f4c3ed923a6ebe01ec1b66eee216341"), + TestFixture(16, "ddb739acda6c56ec9aefc4f4cbc258587f443da4e76ddfa85dbe0813a8784944", "0bddf342121b82f906368b0d7b", "9dd5e1", "12d7a11db811640c533794bfec6eeb977233ec", "71bf573cf63b0022d8143780fc2d9c7dbd0505ac31e9dce0ad68c2428b0878a0"), + TestFixture(16, "62b82637e567ad27c3066d533ed76e314522ac5c53851a8c958ce6c64b82ffd0", "5bc2896d8b81999546f88232ab", "87294078", "2bc22735ab21dfdcfe95bd83592fb6b4168d9a23", "fffb40b0d18cb23018aac109bf62d849adca42629d8a9ad1299b83fe274f9a63"), + TestFixture(16, "62b82637e567ad27c3066d533ed76e314522ac5c53851a8c958ce6c64b82ffd0", "5bc2896d8b81999546f88232ab", "0f28ee1c", "a3c38951b5de3331078aa13bd3742b59df4f661a", "75c3b3059e59032067e9cd94d872e66f168e503bcf46bc78d82a4d4a15a29f6e"), + TestFixture(16, "62b82637e567ad27c3066d533ed76e314522ac5c53851a8c958ce6c64b82ffd0", "5bc2896d8b81999546f88232ab", "d41c9c87", "78f7fbcae52afe7326a12a9aaf22255a38d4bd0d", "8fb9569f18a256aff71601d8412d22863e5a6e6f639214d180b095fa3b18d60e"), + TestFixture(16, "62b82637e567ad27c3066d533ed76e314522ac5c53851a8c958ce6c64b82ffd0", "5bc2896d8b81999546f88232ab", "046bc0d8", "a880a7957543692a72f0d599de48b5e5f5a9413f", "8b62d9adf6819c46c870df8a1486f0a329672f7d137bb7d8659f419c361a466c"), + TestFixture(16, "62b82637e567ad27c3066d533ed76e314522ac5c53851a8c958ce6c64b82ffd0", "5bc2896d8b81999546f88232ab", "39bd4db8", "95562af530fc357f5482b9004d466bf858586acb", "fd98f8f39dfa46ea5926e0ffacbabbe8c34205aade08aa0df82e1d4eaaf95515"), + TestFixture(16, "62b82637e567ad27c3066d533ed76e314522ac5c53851a8c958ce6c64b82ffd0", "5bc2896d8b81999546f88232ab", "b43cdd3a", "18d7ba77a9e8db046fdd548b52d40375c1e9a448", "09bf4f77a9883733590a3cc7ee97f3c9b70f4db255620e88cd5080badc73684c"), + TestFixture(16, "62b82637e567ad27c3066d533ed76e314522ac5c53851a8c958ce6c64b82ffd0", "5bc2896d8b81999546f88232ab", "e0052e9b", "4cee49d64efbdd4ad8d3e863172d9372fca07c20", "40326d765e0f6cf4b4deccb128bebf65a7b3c3e5bcf1d58f6158e1e9153b7e85"), + TestFixture(16, "62b82637e567ad27c3066d533ed76e314522ac5c53851a8c958ce6c64b82ffd0", "5bc2896d8b81999546f88232ab", "696825f6", "c58342bb95bd661b32bc18025808f8b4035acad6", "aa5ae6dcdc21b5446489bdabf5c6747bdf3bbfdb3de2c03170efefe5ccb06d69"), + TestFixture(16, "62b82637e567ad27c3066d533ed76e314522ac5c53851a8c958ce6c64b82ffd0", "5bc2896d8b81999546f88232ab", "7eb07739", "d25b1074ac05b072264e31a4b2801a6d790512d7", "d3d34f140a856e55b29471fde4c0e5f7306b76d03faab26db79c10f95ffb3122"), + TestFixture(16, "62b82637e567ad27c3066d533ed76e314522ac5c53851a8c958ce6c64b82ffd0", "5bc2896d8b81999546f88232ab", "9cad70b1", "304617fcc00514d260e1d211de361c254369e93a", "648a84813ca97aef4ab7e143ee29acb946388660f18eb671194646e0b0136432"), + TestFixture(16, "bc29a16e19cfbe32bf4948e8e4484159bc819b7eec504e4441a1a98ca210e576", "4f18bcc8ee0bbb80de30a9e086", "3e8c6d1b12", "45f3795fcf9c66e1a43103d9a18f5fba5fab83f994", "574931ae4b24bdf7e9217eca6ce2a07287999e529f6e106e3721c42dacf00f5d"), + TestFixture(16, "bc29a16e19cfbe32bf4948e8e4484159bc819b7eec504e4441a1a98ca210e576", "4f18bcc8ee0bbb80de30a9e086", "76fc98ec66", "0d838ca8bb6f3cd579294f706213ed0f0bf32f00c5", "99cd9d15630a55e166114f04093bd1bb6dbb94ecaad126fe5c408dee5f012d9f"), + TestFixture(16, "bc29a16e19cfbe32bf4948e8e4484159bc819b7eec504e4441a1a98ca210e576", "4f18bcc8ee0bbb80de30a9e086", "6564c247cc", "1e1bd603117d38e026f706c9273dbcb6dc982751d0", "1516fdf7a7a99f3c9acc7fff686203dec794c3e52272985449ddf5a268a47bc3"), + TestFixture(16, "bc29a16e19cfbe32bf4948e8e4484159bc819b7eec504e4441a1a98ca210e576", "4f18bcc8ee0bbb80de30a9e086", "c11b9c9d76", "ba6488d9abc3e46166767c6ad2aeffb347168b1b55", "0c9c35be98591bf6737fc8d5624dcdba1a3523c6029013363b9153f0de77725b"), + TestFixture(16, "bc29a16e19cfbe32bf4948e8e4484159bc819b7eec504e4441a1a98ca210e576", "4f18bcc8ee0bbb80de30a9e086", "45a4e0d7dd", "3edbf4930033a7dca78bcbf4d75d651ee5fadff31b", "e74afe3ba960e6409dba78ecb9457e2a4ce2e09792b1d2e3858f4c79f7ddba62"), + TestFixture(16, "bc29a16e19cfbe32bf4948e8e4484159bc819b7eec504e4441a1a98ca210e576", "4f18bcc8ee0bbb80de30a9e086", "e5861b2327", "9ef90f67fa11585167c83105ee16828a574c84ac86", "96cbe9cd193513599c81f5a520fabaff51ee8cbdb81063c8311b1a57a0b8c8fd"), + TestFixture(16, "bc29a16e19cfbe32bf4948e8e4484159bc819b7eec504e4441a1a98ca210e576", "4f18bcc8ee0bbb80de30a9e086", "f5b5bcc38e", "8ecaa88753ffaba456f78e431f4baa5665f14e1845", "2e7ea84da4bc4d7cfb463e3f2c8647057afff3fbececa1d20024dac29e41e2cf"), + TestFixture(16, "bc29a16e19cfbe32bf4948e8e4484159bc819b7eec504e4441a1a98ca210e576", "4f18bcc8ee0bbb80de30a9e086", "b6cc89c75d", "cdb39d838034714731f9503993df357954ecb19cd3", "be125386f5be9532e36786d2e4011f1149abd227b9841150d1c00f7d0efbca4a"), + TestFixture(16, "bc29a16e19cfbe32bf4948e8e4484159bc819b7eec504e4441a1a98ca210e576", "4f18bcc8ee0bbb80de30a9e086", "3802f2aa9e", "437de6ee436c1b008b7572752f04362b2bfdc296bb", "3fa8628594b2645bc35530203dca640838037daeaf9cf8acaa0fb76abf27a733"), + TestFixture(16, "bc29a16e19cfbe32bf4948e8e4484159bc819b7eec504e4441a1a98ca210e576", "4f18bcc8ee0bbb80de30a9e086", "e082b8741c", "9bfdac30c1a3f7c3c29dc312c1f51a675400500e32", "642ae3466661ce1f51783deece86c38e986b8c0adea9e410e976f8a2fe0fe10f"), + TestFixture(16, "5f4b4f97b6aa48adb3336c451aac377fde4adf47897fd9ccdf139f33be76b18c", "7a76eac44486afdb112fc4aab9", "1b62ad19dcac", "4ad1fcf57c12b14e0e659a6305b4aeffae82f8a66c94", "a66c980f6621e03ff93b55d5a148615c4ad36d6cbdd0b22b173b4b1479fb8ff7"), + TestFixture(16, "5f4b4f97b6aa48adb3336c451aac377fde4adf47897fd9ccdf139f33be76b18c", "7a76eac44486afdb112fc4aab9", "3ef0faaa9b79", "6f43ab463bc779fa7932d365e2da9b05c00a7318384a", "c13f65bd491cb172a0f7bbc4a056c579484b62695e90383358d605307d5be0a5"), + TestFixture(16, "5f4b4f97b6aa48adb3336c451aac377fde4adf47897fd9ccdf139f33be76b18c", "7a76eac44486afdb112fc4aab9", "1a98ddbf35f1", "4b2b8c53954f813229912137b7a4945dc07cea24a974", "59dcca8fc50740831f8f259eb55d4db11f763a83187d93758d78d166f4d73cd5"), + TestFixture(16, "5f4b4f97b6aa48adb3336c451aac377fde4adf47897fd9ccdf139f33be76b18c", "7a76eac44486afdb112fc4aab9", "f46a7b1c28ea", "a5d92af088546e045f19f737a24c8addf832ed3f7a42", "578509ca4f57aadb78056794bf18b0714090970db786e2e838105e672165761c"), + TestFixture(16, "5f4b4f97b6aa48adb3336c451aac377fde4adf47897fd9ccdf139f33be76b18c", "7a76eac44486afdb112fc4aab9", "e98f5e5a20d0", "b83c0fb6806edaae8a7dcd3b0fbb59438f88743ec6e8", "696c0c6427273cf06be79f2206c43af9cbda0b884efaf04deba0c4bf0a25cb26"), + TestFixture(16, "5f4b4f97b6aa48adb3336c451aac377fde4adf47897fd9ccdf139f33be76b18c", "7a76eac44486afdb112fc4aab9", "06319c0480e2", "5782cde8205cd9cb636ca6543c4e35964f47341f2814", "95a66b60249ed086eecaeb9bc449afcee9de212619e87516ca947351b25120df"), + TestFixture(16, "5f4b4f97b6aa48adb3336c451aac377fde4adf47897fd9ccdf139f33be76b18c", "7a76eac44486afdb112fc4aab9", "f4c723433b7c", "a57472af9bc2ec82eadf4eb1f055da1a92a82052ab8b", "2b411bea57b51d10a4d2fb17ef0f204aa53cf112e1130c21d411cdf16a84176d"), + TestFixture(16, "5f4b4f97b6aa48adb3336c451aac377fde4adf47897fd9ccdf139f33be76b18c", "7a76eac44486afdb112fc4aab9", "02f809b01ce3", "534b585cbc5d01b10a7ae24a4ca2bfb07ea2a3b31a97", "ff3bff3a26fc5a91252d795f7e1b06f352314eb676bff50dc9fbe881c446941e"), + TestFixture(16, "5f4b4f97b6aa48adb3336c451aac377fde4adf47897fd9ccdf139f33be76b18c", "7a76eac44486afdb112fc4aab9", "2b6004823a29", "7ad3556e9a97231323a4b88af5d7d0b07c0e73ddce1d", "f6be4aad63d33a96c0b5e9c4be62323c9e2308b29961fff980ba0dbda0549274"), + TestFixture(16, "5f4b4f97b6aa48adb3336c451aac377fde4adf47897fd9ccdf139f33be76b18c", "7a76eac44486afdb112fc4aab9", "236c60cba4fa", "72df31270444db30eb33d2ede33abbe22f37704fe68b", "c3706a28d7420b41e072dcecc06b6b13116cca110bde8faea8e51f5107352d71"), + TestFixture(16, "f7aaeff3a1dc0cc5ecf220c67ad9f6dda060b4f1be3cc609cb4f18b2342a88a2", "d0d6871b9adc8623ac63faf00f", "d48daa2919348d", "eb32ab153a8e092fa325bafc176a07c31e6cc0a852d288", "e97175c23c5b47da8ce67811c6d60a7499b3b7e1347ad860519285b67201fe38"), + TestFixture(16, "f7aaeff3a1dc0cc5ecf220c67ad9f6dda060b4f1be3cc609cb4f18b2342a88a2", "d0d6871b9adc8623ac63faf00f", "f95b716bfe3475", "c6e47057dd8ef1a24840f4f40a7963becde3a85968b29c", "ba45e1859efae362a44a0116a14e488ba369da6c76c3913b6df8e69e5e1111fa"), + TestFixture(16, "f7aaeff3a1dc0cc5ecf220c67ad9f6dda060b4f1be3cc609cb4f18b2342a88a2", "d0d6871b9adc8623ac63faf00f", "4862e3677083f0", "77dde25b5339748f2a4a5c276727e0a210fc2efb5aeabe", "efcaa6f6cda3036b0b52ff9f36bc38ca74049c32c6b7cdfb8a46ca4144bacd64"), + TestFixture(16, "f7aaeff3a1dc0cc5ecf220c67ad9f6dda060b4f1be3cc609cb4f18b2342a88a2", "d0d6871b9adc8623ac63faf00f", "7f1ca0728f6d65", "40a3a14eacd7e1051734fc31232ab2ab63474020ab4dc9", "360bcb407603fe92f856bf677625b9882521e6dae8f35fdfc3dc737f9398f609"), + TestFixture(16, "f7aaeff3a1dc0cc5ecf220c67ad9f6dda060b4f1be3cc609cb4f18b2342a88a2", "d0d6871b9adc8623ac63faf00f", "67478ef73290fa", "58f88fcb112a7ec715244f307609ffa253e4e3659b0ece", "f12ee9d37946cfd88516cbe4a046f08c9bbba76a3973ff1e2cb14493405bd384"), + TestFixture(16, "f7aaeff3a1dc0cc5ecf220c67ad9f6dda060b4f1be3cc609cb4f18b2342a88a2", "d0d6871b9adc8623ac63faf00f", "36bb9e511276c5", "09049f6d31cc41f11047da612d2987fa2e50ada5ae7f9d", "5833dde0c577b2be4eb4b3d01d7b0042fa8441ad7043ea462bbbbd56a59790ea"), + TestFixture(16, "f7aaeff3a1dc0cc5ecf220c67ad9f6dda060b4f1be3cc609cb4f18b2342a88a2", "d0d6871b9adc8623ac63faf00f", "d68d6556c5a5b1", "e932646ae61f35382f7648718127ebae7eb7443ebd2c2c", "1e103c63d8ead36b985f921044cd32b8f9f04a2ba9fa154a09e676ffaa093970"), + TestFixture(16, "f7aaeff3a1dc0cc5ecf220c67ad9f6dda060b4f1be3cc609cb4f18b2342a88a2", "d0d6871b9adc8623ac63faf00f", "0568cca4ff79dc", "3ad7cd98dcc358cc40a5e7fffb1fb9a5dd9d6ba91bede1", "a1cfb61d45a140bdea6329ba0fe80429ff9aa4624a1d31bc752f7c97f1d390a0"), + TestFixture(16, "f7aaeff3a1dc0cc5ecf220c67ad9f6dda060b4f1be3cc609cb4f18b2342a88a2", "d0d6871b9adc8623ac63faf00f", "bd93d08eea4263", "822cd1b2c9f8e7468d2b70c311732f11ed72b57d83e500", "116b5b015e44ceef0061b2d2e73fa0b386d5c1e187782beebdfc6efb5a1c6935"), + TestFixture(16, "f7aaeff3a1dc0cc5ecf220c67ad9f6dda060b4f1be3cc609cb4f18b2342a88a2", "d0d6871b9adc8623ac63faf00f", "4fb62753024e92", "7009266f21f416b41a70f548e359add30c0e5746fbeb2b", "3d55882e6f3f89309b6940a3b408e573458eedd10fc3d0e1f3170eb313367475"), + TestFixture(16, "493e14623cd250058a7fc66a3fee0c24b6e363b966c2314aff53b276b6c2ea7b", "fe2d8ae8da94a6df563f89ce00", "e5653e512d8b0b70", "75d31f8d47bee5c4e2ba537355ae8ab25cc9ed3511ff5053", "579a637e37a0974cd2fc3b735d9ed088e8e488ffe210f043e0f9d2079a015ad6"), + TestFixture(16, "493e14623cd250058a7fc66a3fee0c24b6e363b966c2314aff53b276b6c2ea7b", "fe2d8ae8da94a6df563f89ce00", "2c4ba9ce52e01645", "bcfd881238d5f8f1781a9e359804831f31a1efb1ae1cb71d", "1583138aa307401dddc40804ac0f414d338fc3ffb2946f09aaaa7079426fc1ee"), + TestFixture(16, "493e14623cd250058a7fc66a3fee0c24b6e363b966c2314aff53b276b6c2ea7b", "fe2d8ae8da94a6df563f89ce00", "5eb2d054a0e58c62", "ce04f188cad062d62dcc77c4e1fe2bafd477598977835f0c", "78d3dda40e433bba7a330ca3e5bd5170f0895f2e3e438402344ced79fcb0c719"), + TestFixture(16, "493e14623cd250058a7fc66a3fee0c24b6e363b966c2314aff53b276b6c2ea7b", "fe2d8ae8da94a6df563f89ce00", "bbbf7830d04ab907", "2b0959ecba7f57b308946723baf0dbf613359b6e040f9bd5", "dfc762466fa84c27326e0ee4320aa71103d1e9c8a5cf7d9fab5f27d79df94bd6"), + TestFixture(16, "493e14623cd250058a7fc66a3fee0c24b6e363b966c2314aff53b276b6c2ea7b", "fe2d8ae8da94a6df563f89ce00", "10c654c78a9e3c06", "8070751be0abd2b2003bd62ca51f74088bbbd33e54ac9dd4", "7e8ea82d1137c1e233522da12626e90a5f66a988e70664cb014c12790d2ab520"), + TestFixture(16, "493e14623cd250058a7fc66a3fee0c24b6e363b966c2314aff53b276b6c2ea7b", "fe2d8ae8da94a6df563f89ce00", "668d32e322e1da3e", "f63b133f48d4348a67e65e7f2cdedf6ef8cc0ee7a6dcfb02", "873da112557935b3929f713d80744ed08b4b276b86331dbc386fba361726d565"), + TestFixture(16, "493e14623cd250058a7fc66a3fee0c24b6e363b966c2314aff53b276b6c2ea7b", "fe2d8ae8da94a6df563f89ce00", "e39f6225e8eab6cc", "732943f982df58780532f8c6639e5d6c7b755fcf516724e3", "cfba97919f703d864efc11eac5f260a5d920d780c52899e5d76f8fe66936ff82"), + TestFixture(16, "493e14623cd250058a7fc66a3fee0c24b6e363b966c2314aff53b276b6c2ea7b", "fe2d8ae8da94a6df563f89ce00", "6021a00f6d0610a4", "f09781d30733fe107fd7a33828413ebc252dd9d015773524", "01abcfee196f9d74fcaa7b69ae24a275485c25af93cc2306d56e41e1eb7f5702"), + TestFixture(16, "493e14623cd250058a7fc66a3fee0c24b6e363b966c2314aff53b276b6c2ea7b", "fe2d8ae8da94a6df563f89ce00", "bbaf0ac4e77ee78d", "2b192b188d4b0939d3d51368799325ad1c8233fa071bade0", "ce1c31e7121c071d89afab5a9676c9e96cac3d89dcae83136bbb6f5ca8f81e5d"), + TestFixture(16, "493e14623cd250058a7fc66a3fee0c24b6e363b966c2314aff53b276b6c2ea7b", "fe2d8ae8da94a6df563f89ce00", "98a2336549a23a76", "081412b92397d4c25d1ea568637f773174a7f920a51b1fe1", "bb210ca5bc07e3c5b06f1d0084a5a72125f177d3e56c151221115ae020177739"), + TestFixture(16, "b23255372455c69244a0210e6a9e13b155a5ec9d6d0900e54a8f4d9f7a255e3a", "274846196d78f0af2df5860231", "615d724ae94a5daf8d", "f019ae51063239287d896e7127f17d13f98013b420219eb877", "69adcae8a1e9a3f2fe9e62591f7b4c5b19d3b50e769521f67e7ea8d7b58d9fc8"), + TestFixture(16, "b23255372455c69244a0210e6a9e13b155a5ec9d6d0900e54a8f4d9f7a255e3a", "274846196d78f0af2df5860231", "0d9168eeab3b27ba69", "9cd5b4f54443433d997cc2cd61da9358b4045fef32f8192cbf", "162d0033c9ea8d8334d485b29eef727302135a07a934eea5fee6041e9f1f47c1"), + TestFixture(16, "b23255372455c69244a0210e6a9e13b155a5ec9d6d0900e54a8f4d9f7a255e3a", "274846196d78f0af2df5860231", "6287dcffdd5fb97885", "f3c300e43227ddff75d280f0ffdd560fb8915978e3bd6205bb", "3f4ab57efa32f51a4c00790280e77c0e55b85bbda4f854e242368e9a289b5a81"), + TestFixture(16, "b23255372455c69244a0210e6a9e13b155a5ec9d6d0900e54a8f4d9f7a255e3a", "274846196d78f0af2df5860231", "6e5e01b3fd71d16b9c", "ff1adda81209b5ec6c7dbf90420a1ff2e24bd6303b80cfc199", "945d18134c148f164b39fd7c4aef0335045553f6ea690a3b1726418d86f0de00"), + TestFixture(16, "b23255372455c69244a0210e6a9e13b155a5ec9d6d0900e54a8f4d9f7a255e3a", "274846196d78f0af2df5860231", "b51521e689b5247362", "2451fdfd66cd40f492d741f4329ae7cc77d42bf7e5f2ec5ab6", "23af12893431b07c2922ab623aed901c0eaaeb9a24efc55273e96aea4dab7038"), + TestFixture(16, "b23255372455c69244a0210e6a9e13b155a5ec9d6d0900e54a8f4d9f7a255e3a", "274846196d78f0af2df5860231", "7f973617e710fb76fe", "eed3ea0c08689ff10ec9ffdcc2f36edac14613b1d85baf25a9", "b15a118b3132c20c31e6c9d09acdee0e15fcc59d6f18306442682512d22eb10f"), + TestFixture(16, "b23255372455c69244a0210e6a9e13b155a5ec9d6d0900e54a8f4d9f7a255e3a", "274846196d78f0af2df5860231", "7e909b6727ac3fd02f", "efd4477cc8d45b57df5a61a28bb10265b26043d7a8dd357713", "dcfbeb6490f5fa7eaf917462473a6cec98bebf8f17493fe9b994119a6d5a5457"), + TestFixture(16, "b23255372455c69244a0210e6a9e13b155a5ec9d6d0900e54a8f4d9f7a255e3a", "274846196d78f0af2df5860231", "a5075638932b5632f8", "34438a237c5332b508d321c371ae1fd01bdf3b6c75a597da6e", "77e9317294f046f315a0d79e3423f29f7d9ebcd36d6eaa2a3fb2f4500309478c"), + TestFixture(16, "b23255372455c69244a0210e6a9e13b155a5ec9d6d0900e54a8f4d9f7a255e3a", "274846196d78f0af2df5860231", "c10f15a0de78db8aa3", "504bc9bb3100bf0d539393d1635bc40ac62405a39155406c47", "3aa8f204eb127b547e13873ed0238018394e13686c8734e49e3e629deb352c77"), + TestFixture(16, "b23255372455c69244a0210e6a9e13b155a5ec9d6d0900e54a8f4d9f7a255e3a", "274846196d78f0af2df5860231", "8294f830cfca42cfbe", "13d0242b20b226484eff89641e1bd5ad6cc827441b17c45ecf", "7f67e6f97c6c258f014d721a4edaaa0ddb3f9f09993276ab7b714ea9356c231d"), + TestFixture(16, "dbf06366f766e2811ecd5d4384d6d08336adc37e0824d620cf0d9e7fd1e7afa9", "b3503ed4e277ed9769b20c10c0", "2e3cf0af8c96c7b22719", "e317df43ab46eb31be7e76f2730d771d56099a0c8d2703d7a24e", "9ae5a04baa9d02c8854e609899c6240851cbc83f81f752bc04c71affa4eed385"), + TestFixture(16, "dbf06366f766e2811ecd5d4384d6d08336adc37e0824d620cf0d9e7fd1e7afa9", "b3503ed4e277ed9769b20c10c0", "e081c43a07450ce0dfa2", "2daaebd62095206346c5bcc7a8260ef361dc39fdb776d041f0d4", "da77c6d5627a2aa34911bd1f7cc5f8aa68a2c6546adc96a186b9af8e5baac4cf"), + TestFixture(16, "dbf06366f766e2811ecd5d4384d6d08336adc37e0824d620cf0d9e7fd1e7afa9", "b3503ed4e277ed9769b20c10c0", "c381d2ae5e72fc82324a", "0eaafd4279a2d001ab2d19f0cbb0899f221aac9762f2650f8058", "134d2d9726400d09dd3521326f96fbef993ddc0c4088770057b0f8d70356456f"), + TestFixture(16, "dbf06366f766e2811ecd5d4384d6d08336adc37e0824d620cf0d9e7fd1e7afa9", "b3503ed4e277ed9769b20c10c0", "737f4d00c54ddca80eec", "be5462ece29df02b978b3dc92a9bd26b9653e5917359c331fcff", "0d065dfde1de1f21784c7869eb566c977f807cfbd53578f4616995b51d7dc045"), + TestFixture(16, "dbf06366f766e2811ecd5d4384d6d08336adc37e0824d620cf0d9e7fd1e7afa9", "b3503ed4e277ed9769b20c10c0", "4e9e251ebbbbe5dbc8ff", "83b50af29c6bc958519891dda72c27d272561e00f7041845d998", "95c54d187f2415535451cbb9cb35869749b171f7043216ce6886dd77baeecf60"), + TestFixture(16, "dbf06366f766e2811ecd5d4384d6d08336adc37e0824d620cf0d9e7fd1e7afa9", "b3503ed4e277ed9769b20c10c0", "0db72b281ab4046d15a6", "c09c04c43d6428ee8cc1928ac628758ad58fc1b5a768d4722848", "0f98039e6a9fe360373b48c7850ce113a0ff7b2ae5ce773dd4c67ca967cd691b"), + TestFixture(16, "dbf06366f766e2811ecd5d4384d6d08336adc37e0824d620cf0d9e7fd1e7afa9", "b3503ed4e277ed9769b20c10c0", "4f7b4f38ff1ba4df5a59", "825060d4d8cb885cc33ed11dad4dc8b265a53cf0bdd85c5f15f4", "ad840bc55654762e5eba0e4a9e7998992d990a06d70da1b1ca922ef193dab19a"), + TestFixture(16, "dbf06366f766e2811ecd5d4384d6d08336adc37e0824d620cf0d9e7fd1e7afa9", "b3503ed4e277ed9769b20c10c0", "58ce55379ef24b72d6d6", "95e57adbb92267f14fb18eb659a5a7084be48d099467da4395df", "911e9876ea98e1bcf710d8fd05b5bf000ea317d926b41b6015998ee1462ab615"), + TestFixture(16, "dbf06366f766e2811ecd5d4384d6d08336adc37e0824d620cf0d9e7fd1e7afa9", "b3503ed4e277ed9769b20c10c0", "a219028a953ce1544835", "6f322d66b2eccdd7d1523b2b2583fd117cec47b1c84d3863159e", "3f68a4fb4043bcf9b6d277c97e11365d949c705bd6679c6f0aaf52e62330ad79"), + TestFixture(16, "dbf06366f766e2811ecd5d4384d6d08336adc37e0824d620cf0d9e7fd1e7afa9", "b3503ed4e277ed9769b20c10c0", "83b0ee9a52252c456105", "4e9bc17675f500c6f8625456eb2b6a2d35c649a84051f843153c", "02f32242cba6204319075ea8ce806a57845355ae73e6b875955df510096ebff9"), + TestFixture(16, "4dd555bd3a5253a90b68b5d4d46bd050340ee07ddad3a72048c657b5d76bb207", "bdb1b82ba864893c2ee8f7426c", "8015c0f07a7acd4b1cbdd2", "8e9f80c726980b3d42e43a6512a0481255b729a10f9edb5f07c60c", "9bcc5848e928ba0068f7a867e79e83a6f93593354a8bfcfc306aeeb9821c1da1"), + TestFixture(16, "4dd555bd3a5253a90b68b5d4d46bd050340ee07ddad3a72048c657b5d76bb207", "bdb1b82ba864893c2ee8f7426c", "c97b62a719720b44b7779c", "c7f122904590cd32e92e748c514444f00ffdb80a4bb7e9eb651946", "c2e75952ab49216f305e3776865791ce877cef8c0229ca97561787093fddf1d8"), + TestFixture(16, "4dd555bd3a5253a90b68b5d4d46bd050340ee07ddad3a72048c657b5d76bb207", "bdb1b82ba864893c2ee8f7426c", "cb7c17ef62464ecc8008f6", "c5f657d83ea488bade511edb609dfc1929ac1ba5753fc83bf945b7", "c76a3ff4e6d1f742dd845be2d74c1a9b08e418909b15077deb20373ef55caf91"), + TestFixture(16, "4dd555bd3a5253a90b68b5d4d46bd050340ee07ddad3a72048c657b5d76bb207", "bdb1b82ba864893c2ee8f7426c", "893a690cc5221de597d0e8", "87b0293b99c0db93c9890053b74283296d0fca83b262915289163c", "bdb69f99f9a144b9ad88c6cfd8ffb8304c201de9b2818552ce6379e6042c1951"), + TestFixture(16, "4dd555bd3a5253a90b68b5d4d46bd050340ee07ddad3a72048c657b5d76bb207", "bdb1b82ba864893c2ee8f7426c", "80f3e4245c3eab16ef8bf0", "8e79a41300dc6d60b1d21888a34955893059d66549795b3ac2105c", "01815f599d6ba0d1c09f6f673bb6cca4c2a7a74f4e985be4c0f37842c7bbc5a4"), + TestFixture(16, "4dd555bd3a5253a90b68b5d4d46bd050340ee07ddad3a72048c657b5d76bb207", "bdb1b82ba864893c2ee8f7426c", "641c6914920a79943dca39", "6a962923cee8bfe26393d1377c4e2f20aaa872a9a0b1d1d7f56df0", "a9db62e9ab53c4a805c43838ce36b587d29b75b43fb34c17a22d3981120f3bc5"), + TestFixture(16, "4dd555bd3a5253a90b68b5d4d46bd050340ee07ddad3a72048c657b5d76bb207", "bdb1b82ba864893c2ee8f7426c", "2286a1eddd80737a724ca9", "2c0ce1da8162b50c2c15415545aa0c1dd11551891ae553d3a91908", "f0c2cc5a1b4c4cbe839338fa0d7a343514801302aef2403530605cf4f44d2811"), + TestFixture(16, "4dd555bd3a5253a90b68b5d4d46bd050340ee07ddad3a72048c657b5d76bb207", "bdb1b82ba864893c2ee8f7426c", "d8c63e7d7d332198249c0c", "d64c7e4a21d1e7ee7ac5e4d9e07ec5806360843676ef27d811b246", "9842922499ad4d487488b3731f48765efe0b4eb59e7b491ba5f6636f09ed564d"), + TestFixture(16, "4dd555bd3a5253a90b68b5d4d46bd050340ee07ddad3a72048c657b5d76bb207", "bdb1b82ba864893c2ee8f7426c", "4b81804d777a59b6a107cf", "450bc07a2b989fc0ff5e27483b8727c5753ede25e1fab0d86963be", "399b71ecb41f4590abda79045cdf6495f27daaa559c1b34f513b5c4ac105ec10"), + TestFixture(16, "4dd555bd3a5253a90b68b5d4d46bd050340ee07ddad3a72048c657b5d76bb207", "bdb1b82ba864893c2ee8f7426c", "dfc762466fa84c27326e0e", "d14d2271334a8a516c37e64b5c3c1dc577ee8fcf6ef3ebc0783430", "2c186c5c3463a4a8bad771feb71e2973c4f6dede2529827707bf4fa40672660f"), + TestFixture(16, "d3ad8cda9a0d91a205c4c05665728bb255d50a83403c9ab9243fcbbe95ae7906", "0b5f69697eb1af24e8e6fcb605", "a203aeb635e195bc33fd42fa", "62666297a809c982b50722bd56bc555899345e0404b2938edf33168e", "ea26ea68facdac3c75ba0cdf7b1ad703c9474af83b3fbfc58e548d776b2529b9"), + TestFixture(16, "d3ad8cda9a0d91a205c4c05665728bb255d50a83403c9ab9243fcbbe95ae7906", "0b5f69697eb1af24e8e6fcb605", "aac414fbad945a49ae178103", "6aa1d8da307c067728ede1449b15447c904b671824c2ca24c4fc7ad4", "0b32069fc7e676f229f1037d3026c93eef199913e426efd786b524ce1dbde543"), + TestFixture(16, "d3ad8cda9a0d91a205c4c05665728bb255d50a83403c9ab9243fcbbe95ae7906", "0b5f69697eb1af24e8e6fcb605", "7ee0ce371329192618e3cda0", "be8502168ec145189e19ade7ea13850e99ef9300c65f5abc9419d13a", "7a8658302e5181552292aa56e8209de63b5d86934167549b0d936202681757e1"), + TestFixture(16, "d3ad8cda9a0d91a205c4c05665728bb255d50a83403c9ab9243fcbbe95ae7906", "0b5f69697eb1af24e8e6fcb605", "b0a1af969a95025385b251af", "70c463b7077d5e6d034831e8486c93c31bbedc9e5ffa2f4154bceea9", "4f05600950664d5190a2ebc29c9edb89c20079a4d3e6bc3b27d75e34e2fa3d02"), + TestFixture(16, "d3ad8cda9a0d91a205c4c05665728bb255d50a83403c9ab9243fcbbe95ae7906", "0b5f69697eb1af24e8e6fcb605", "9f6c6d60110fd3782bdf49b0", "5f09a1418ce78f46ad2529f7f18b556e7da59fd2549dc57a17bf64f8", "4530e4dc6a4c3733b8ab7e77e384223cc1a8c179fb66818c08aca47e5c705d89"), + TestFixture(16, "d3ad8cda9a0d91a205c4c05665728bb255d50a83403c9ab9243fcbbe95ae7906", "0b5f69697eb1af24e8e6fcb605", "90958d7f458d98c48cbb464c", "50f0415ed865c4fa0a41260b30aad3a838680cbd313004685a5510c5", "f179353aef342f0f691caf1fcb811e3f6504e14d6d9381c5439b098ff978b01b"), + TestFixture(16, "d3ad8cda9a0d91a205c4c05665728bb255d50a83403c9ab9243fcbbe95ae7906", "0b5f69697eb1af24e8e6fcb605", "9f7ae892e5662803408d4d06", "5f1f24b3788e743dc6772d411d57b89ed0c91251aed37a6ca68a50c7", "f6df267e5cbc9d2a67b1c0fd762f891ee3b7c435884cb87d8228091b34aeddae"), + TestFixture(16, "d3ad8cda9a0d91a205c4c05665728bb255d50a83403c9ab9243fcbbe95ae7906", "0b5f69697eb1af24e8e6fcb605", "817074e351455f23cb67883d", "4115b8c2ccad031d4d9de87ad79a3b0feea16ff5fbca16211ea6fdd9", "4372e152b1afd99c7f87c8a51dbc3a5c14c49d04ea1c482a45dfbcda54972912"), + TestFixture(16, "d3ad8cda9a0d91a205c4c05665728bb255d50a83403c9ab9243fcbbe95ae7906", "0b5f69697eb1af24e8e6fcb605", "1b7da3835e074fdf62f1eb3c", "db186fa2c3ef13e1e40b8b7b49f22737c4b2f9fa0a7e3dd4b067fbaa", "82b6cd1c6618c42ba74e746075dc28700333578131ca6fde6971d2f0c6e31e6a"), + TestFixture(16, "d3ad8cda9a0d91a205c4c05665728bb255d50a83403c9ab9243fcbbe95ae7906", "0b5f69697eb1af24e8e6fcb605", "57473e7a105c806867379194", "9722f25b8db4dc56e1cdf1d3ef43a48dbea8c1547455ad0197af88a2", "a5422e53975e43168726677930f6d3e13281bdbd13c67c168340ed67e45d15b0"), + TestFixture(16, "e300fc7a5b96806382c35af5b2c2e8e26382751b59010d4b1cfc90a4a9cb06df", "55b59eb434dd1ba3723ee0dc72", "8714eb9ecf8bdb13e919de40f9", "ba6063824d314aa3cbab14b8c54c6520dac0f073856d9b9010b7857736", "9b1d85384cb6f47c0b13514a303d4e1d95af4c6442691f314a401135f07829ec"), + TestFixture(16, "e300fc7a5b96806382c35af5b2c2e8e26382751b59010d4b1cfc90a4a9cb06df", "55b59eb434dd1ba3723ee0dc72", "a0837676e091213890dc6e0a34", "9df7fe6a622bb088b26ea4f20820a423dd30796b6016baff106aaef206", "fa17c693d0997140fbc521d39e042d8e08388106874207ca81c85f45c035d6e6"), + TestFixture(16, "e300fc7a5b96806382c35af5b2c2e8e26382751b59010d4b1cfc90a4a9cb06df", "55b59eb434dd1ba3723ee0dc72", "b8a2ce7e051b8d094ec43f2a7f", "85d6466287a11cb96c76f5d2436032bc79c4aef1f74da25e92b0aa7f8a", "27663597b389b78e96c785ca2f5510c8963a5561d2b0b24c4dcdf8e58562c12c"), + TestFixture(16, "e300fc7a5b96806382c35af5b2c2e8e26382751b59010d4b1cfc90a4a9cb06df", "55b59eb434dd1ba3723ee0dc72", "9e4103ab1dfb77ae3494507332", "a3358bb79f41e61e16269a8b0e658123d2e5bb324c7ead8897f8e32b0a", "d8f1a83371487d611ce704e0a6731f97a933c43569690022fce33cb5aecdc0a7"), + TestFixture(16, "e300fc7a5b96806382c35af5b2c2e8e26382751b59010d4b1cfc90a4a9cb06df", "55b59eb434dd1ba3723ee0dc72", "fb3e3d1b6394d2daebf121f8ac", "c64ab507e12e436ac943eb0090270758ab09f93fa3ba7d7a2aa8eac789", "05c57aab99f94b315cf8bdd2d6b54440c097fe33c62a96b98b1568cdee4ce62c"), + TestFixture(16, "e300fc7a5b96806382c35af5b2c2e8e26382751b59010d4b1cfc90a4a9cb06df", "55b59eb434dd1ba3723ee0dc72", "549ba26a299391538b56ce4bd7", "69ef2a76ab2900e3a9e404b3eb2293813f1bcb96564f772e9308e42b2d", "1c1b0933c508c6a8a20846ebd0d0377e24f4abc0c900d3a92bc409ba14ef1434"), + TestFixture(16, "e300fc7a5b96806382c35af5b2c2e8e26382751b59010d4b1cfc90a4a9cb06df", "55b59eb434dd1ba3723ee0dc72", "287f31e69880823df7798c7970", "150bb9fa1a3a138dd5cb46814c81877380d5cf097c2fb5177750f8b53a", "9f5cf9149f556124d6bb4e3e243cca1502c02682709392cc2ec7eb262fd4d479"), + TestFixture(16, "e300fc7a5b96806382c35af5b2c2e8e26382751b59010d4b1cfc90a4a9cb06df", "55b59eb434dd1ba3723ee0dc72", "040d18b128ae4a1935f9509266", "397990adaa14dba9174b9a6a5acf42c75787edc62a180568c6ef56545d", "1a49aaea6fc6fae01a57d2fc207ef9f623dfd0bc2cf736c4a70aaaa0af5dafd3"), + TestFixture(16, "e300fc7a5b96806382c35af5b2c2e8e26382751b59010d4b1cfc90a4a9cb06df", "55b59eb434dd1ba3723ee0dc72", "92441cbe8d70820870bb01ad63", "af3094a20fca13b85209cb555f56d47a0631f2038103e3904b556ba7a5", "f29a0b2c602ff2cacb587292db301182e6c76c5110b97ca8b706198f0e1dbc26"), + TestFixture(16, "e300fc7a5b96806382c35af5b2c2e8e26382751b59010d4b1cfc90a4a9cb06df", "55b59eb434dd1ba3723ee0dc72", "f11d814df217de96333dee1cbf", "cc69095170ad4f26118f24e4835be15b7ae24edccd0b0934e3af513ed3", "01fcf5fef50e36175b0510874ea50a4d2005ad5e40e5889b61417700d827251e"), + TestFixture(16, "3ae5be5904bae62609ac525e2d1cad90133447573d7b608975a6a2b16cb2efc0", "61bf06b9fa5a450d094f3ddcb5", "959403e0771c21a416bd03f38983", "37a346bc4909965c5497838251826385a52c68914e9d1f63fd297ee6e7ed", "0245484bcd987787fe97fda6c8ffb6e7058d7b8f7064f27514afaac4048767fd"), + TestFixture(16, "3ae5be5904bae62609ac525e2d1cad90133447573d7b608975a6a2b16cb2efc0", "61bf06b9fa5a450d094f3ddcb5", "23fe445efa5bcb318cc85e2ad1ac", "81c90102c44e7cc9cee2de5b09ad364b603de6afbc2d96d00510894ccbe7", "52f6a10a022e5ee57eda3fcf53dcf0d922e9a3785b39fad9498327744f2852e4"), + TestFixture(16, "3ae5be5904bae62609ac525e2d1cad90133447573d7b608975a6a2b16cb2efc0", "61bf06b9fa5a450d094f3ddcb5", "762fdc3e0c30c7ecf2ec8808bb79", "d418996232257014b0c6087963781a4321c2ddbc35ce4864457d611219e9", "d236e3841b9556b32dbd02886724d053a9b8488c5ad1b466b06482a62b79ebb6"), + TestFixture(16, "3ae5be5904bae62609ac525e2d1cad90133447573d7b608975a6a2b16cb2efc0", "61bf06b9fa5a450d094f3ddcb5", "b6813d5fe8afa68d646c197337a2", "14b67803d6ba117526469902efa3296e55efebb17fe145cdca9b31ea7bcc", "0d2739cfdac782b61f484fa1a423c478c414397ec420327963d79112b2d70a7e"), + TestFixture(16, "3ae5be5904bae62609ac525e2d1cad90133447573d7b608975a6a2b16cb2efc0", "61bf06b9fa5a450d094f3ddcb5", "4ce8b6578537215224eb9398c011", "eedff30bbb2296aa66c113e9181059270a0510e7cc1b599705853af2144d", "7f291aa463c4babc76b4a6faf2e27e9401586b1ac83e4b06a4090e94b3ef5fd4"), + TestFixture(16, "3ae5be5904bae62609ac525e2d1cad90133447573d7b608975a6a2b16cb2efc0", "61bf06b9fa5a450d094f3ddcb5", "9ebf93643854ea5c97a4f38f50bd", "3c88d63806415da4d58e73fe88bcb55847573bf21e946ce9bdc5f569e3ff", "06bca7ef6f91355d19f90bf25590a44a24e5a782f92bc693c031e6de1e948008"), + TestFixture(16, "3ae5be5904bae62609ac525e2d1cad90133447573d7b608975a6a2b16cb2efc0", "61bf06b9fa5a450d094f3ddcb5", "da989cc7d375ed5fac4d7f938d74", "78afd99bed605aa7ee67ffe25575b8a61c5687ea02f0276824b8316b76f1", "5a44ff94f817c7c028a8f3db35a4d01364d2598432469f09ded86e5127d42d35"), + TestFixture(16, "3ae5be5904bae62609ac525e2d1cad90133447573d7b608975a6a2b16cb2efc0", "61bf06b9fa5a450d094f3ddcb5", "6fbab5a0f98e21e4d15904af5948", "cd8df0fcc79b961c937384de8149a07ee02791011129fcacffcfb1bf4145", "2a755e362373ef27a911c4d93ca07bc97135645442ad7ad6a8ef98146c71e9d7"), + TestFixture(16, "3ae5be5904bae62609ac525e2d1cad90133447573d7b608975a6a2b16cb2efc0", "61bf06b9fa5a450d094f3ddcb5", "b610349e8b370a7c195598573637", "142771c2b522bd845b7f1826ee36d34204b1ce23f5f58a8eb7cf1fa8cfa7", "f7988873f45a5de314e5381d3f14d8f8c48c9b649bf3e745ed5dc882d507da58"), + TestFixture(16, "3ae5be5904bae62609ac525e2d1cad90133447573d7b608975a6a2b16cb2efc0", "61bf06b9fa5a450d094f3ddcb5", "1d969fd81dab5ced3e6ee70be3bf", "bfa1da8423beeb157c44677a3bbe9c618bb88bbcefb008a5ea6bed4ff949", "95d2c8502e28ab3ee2cac52e975c3e7bccb1a93acc33d9c32786f66d6268d198"), + TestFixture(16, "fab62b3e5deda7a9c1128663cc81c44b74ab1bfe70bc1c9dec7c7fd08173b80a", "a5c1b146c82c34b2e6ebeceb58", "54be71705e453177b53c92bbf2ab13", "788db949697b8cd9abbc74ed9aa40cd6852dc829469368491149d6bb140071", "5e60b02b26e2d5f752eb55ea5f50bb354a6f01b800cea5c815ff0030b8c7d475"), + TestFixture(16, "fab62b3e5deda7a9c1128663cc81c44b74ab1bfe70bc1c9dec7c7fd08173b80a", "a5c1b146c82c34b2e6ebeceb58", "22197f9ad14591e7a6d5f8b18c969a", "0e2ab7a3e67b2c49b8551ee7e4998556940dc5a7e44bf10234806d00a012b5", "210c04632341fbfc185bfe3cbf6fe272bbe971104173bcb11419b35ab3aaf200"), + TestFixture(16, "fab62b3e5deda7a9c1128663cc81c44b74ab1bfe70bc1c9dec7c7fd08173b80a", "a5c1b146c82c34b2e6ebeceb58", "096b2f530933c1273304a6ad423726", "2558e76a3e0d7c892d8440fb2a38390898f7dbde25b0b70d335df71a06987b", "d3a205dd017e79a67400a937a20ef049f4c40d73311731f03ab857a3f93bd458"), + TestFixture(16, "fab62b3e5deda7a9c1128663cc81c44b74ab1bfe70bc1c9dec7c7fd08173b80a", "a5c1b146c82c34b2e6ebeceb58", "d44fdfd9da3a63c1083afe574e91bf", "f87c17e0ed04de6f16ba1801269ea02fd10d1f21b6b963c05aeda8eb09e272", "0c9b3ba4faf5fc2f310ad1bab06c4ca13474b714feeffb6ad615c1b850bbd6a3"), + TestFixture(16, "fab62b3e5deda7a9c1128663cc81c44b74ab1bfe70bc1c9dec7c7fd08173b80a", "a5c1b146c82c34b2e6ebeceb58", "8d836acc13ed83c2b2c706415c9679", "a1b0a2f524d33e6cac47e0173499664491d23d90ff55abca17e9d943b98c7f", "d9bb71ad90152d5c1af358c8501fa89ebd4b17bf4ff43841528cccb79fd791b3"), + TestFixture(16, "fab62b3e5deda7a9c1128663cc81c44b74ab1bfe70bc1c9dec7c7fd08173b80a", "a5c1b146c82c34b2e6ebeceb58", "2a68e3fe746f593c1b97cb637079c3", "065b2bc74351e49205172d351876dc9616886c6b2adc97db5a673846b6662c", "69dc21eb6f295b12ba493ee8fe6c40d78af946067ce772db316a3cbf00d3c521"), + TestFixture(16, "fab62b3e5deda7a9c1128663cc81c44b74ab1bfe70bc1c9dec7c7fd08173b80a", "a5c1b146c82c34b2e6ebeceb58", "39799b001ed2c334c269acb0f2328c", "154a533929ec7e9adce94ae69a3d932441dcae1760db90379bd354fa99164e", "095eb52135dc6d9c1f56a2571c1389852482e7aa3edc245a3904a0449db24a70"), + TestFixture(16, "fab62b3e5deda7a9c1128663cc81c44b74ab1bfe70bc1c9dec7c7fd08173b80a", "a5c1b146c82c34b2e6ebeceb58", "42143a2b9e1d0b354df3264d08f7b6", "6e27f212a923b69b5373c01b60f8a9c7c7deb28bdcf84886ef843216b94449", "efd7270e0396392fde8b0ddaab00544cbbd504f4d97d4e90d749d1946de90dcb"), + TestFixture(16, "fab62b3e5deda7a9c1128663cc81c44b74ab1bfe70bc1c9dec7c7fd08173b80a", "a5c1b146c82c34b2e6ebeceb58", "a3dcf26327059a4245b79a38bb8db6", "8fef3a5a103b27ec5b377c6ed382a935061ae3cd892ba63c44b809d6d29421", "8bc181ce2e66294e803a8dc3834958b5f173bc2123c0726e31f3fca25b622ed6"), + TestFixture(16, "fab62b3e5deda7a9c1128663cc81c44b74ab1bfe70bc1c9dec7c7fd08173b80a", "a5c1b146c82c34b2e6ebeceb58", "3d54883449ecca8f153436c25a0a01", "1167400d7ed277210bb4d09432051e3c9ae69a4c59ff8e251c2fe022d065a9", "c39ec70c2c71633ae0dccc41477ac32e47638c885cf59f34ebd4a096d32f91f9"), + TestFixture(16, "ee8ce187169779d13e443d6428e38b38b55dfb90f0228a8a4e62f8f535806e62", "121642c4218b391c98e6269c8a", "d15f98f2c6d670f55c78a06648332bc9", "cc17bf8794c843457d899391898ed22a6f9d28fcb64234e1cd793c4144f1da50", "718d13e47522ac4cdf3f828063980b6d452fcdcd6e1a1904bf87f548a5fd5a05"), + TestFixture(16, "ee8ce187169779d13e443d6428e38b38b55dfb90f0228a8a4e62f8f535806e62", "121642c4218b391c98e6269c8a", "60d55a8d5ab591a51e87fdf6aaa2ad25", "7d9d7df808aba2153f76ce016b1f54c68b55bbe42d8c97504b97c34a5f16e6a6", "a371ca29b92ed676bab5dfc4d78631bb6d9bb23a29f822907084a1f0fe17721f"), + TestFixture(16, "ee8ce187169779d13e443d6428e38b38b55dfb90f0228a8a4e62f8f535806e62", "121642c4218b391c98e6269c8a", "cbf112e4fb85276c4e09649f3de225b2", "d6b93591a99b14dc6ff85768fc5fdc51017d8706acd676ae99e93d5312a4113c", "01ec87920b42639d4ba22adb1fbe5138d2849db670a2960fd94a399c1532ed75"), + TestFixture(16, "ee8ce187169779d13e443d6428e38b38b55dfb90f0228a8a4e62f8f535806e62", "121642c4218b391c98e6269c8a", "865b89aa38ee1b5a3ce56620307e8937", "9b13aedf6af028ea1d1455d7f1c370d45982f0fe5d951a8c62c87894657301e4", "eebd2bbf1e9f6d817cd8062a6a9680e7f10464eefeb50b07cb46b14b9b3fcb2c"), + TestFixture(16, "ee8ce187169779d13e443d6428e38b38b55dfb90f0228a8a4e62f8f535806e62", "121642c4218b391c98e6269c8a", "a8efc37d1b8b51f2a47b21dd14da383d", "b5a7e40849956242858a122ad567c1de5addfddbb59f4985947fb3a9ab56333e", "72863362612f146699f6b2f6ec3688f2ca6cb1505af7a309c91c1933e34d516a"), + TestFixture(16, "ee8ce187169779d13e443d6428e38b38b55dfb90f0228a8a4e62f8f535806e62", "121642c4218b391c98e6269c8a", "d9b0eaaff786165f882f41a98dbc0c35", "c4f8cddaa59825efa9de725e4c01f5d6b651053516673402a57538db1a9ce7e9", "9c9efc6593f96207678db813608f2b8bc33ed1bef974ed77ed7b6e74b621b819"), + TestFixture(16, "ee8ce187169779d13e443d6428e38b38b55dfb90f0228a8a4e62f8f535806e62", "121642c4218b391c98e6269c8a", "df49d972b6ebbbb18ee975ac635d847e", "c201fe07e4f58801af18465ba2e07d9d86d772b1a1991b7be6589bbccad36171", "dc482a051b58d8a3904d3af37c37b51983f634a504451bbba6f77d71337f8e78"), + TestFixture(16, "ee8ce187169779d13e443d6428e38b38b55dfb90f0228a8a4e62f8f535806e62", "121642c4218b391c98e6269c8a", "78318aa5cd16699b77bdcea2fc9d1d20", "6579add09f085a2b564cfd553d20e4c3569387a1a6bcc826e94012670820576e", "51ef065a43caa23faf750b02a41ad6ba701aeb8058f6d8738d6f6b005bec7f60"), + TestFixture(16, "ee8ce187169779d13e443d6428e38b38b55dfb90f0228a8a4e62f8f535806e62", "121642c4218b391c98e6269c8a", "8e20d65d02dd9a64379f75b6d8328f2d", "9368f12850c3a9d4166e4641198f76cee9c788b4aae9b2c6caf0c44aa9bd2ed0", "88e2a74d2920c89c6a101f5f06d0624a6d5eabd9bdb51395ee3983934c55c73d"), + TestFixture(16, "ee8ce187169779d13e443d6428e38b38b55dfb90f0228a8a4e62f8f535806e62", "121642c4218b391c98e6269c8a", "97e8d8513af41b97801de98cc4269096", "8aa0ff2468ea2827a1ecda7b059b6975f1df0f01944641a1b04d753e6ab8d3cc", "ada3ed7db2dabbfbc441ef68a5656e628d6d5bd6c1574369688497179a77601a"), + TestFixture(16, "7da6ef35ad594a09cb74daf27e50a6b30d6b4160cf0de41ee32bbf2a208b911d", "98a32d7fe606583e2906420297", "b0053d1f490809794250d856062d0aaa92", "a6341ee3d60eb34a8a8bc2806d50dd57a3f628ee49a8c2005c7d07d354bf80994d", "217d130408a738e6a833931e69f8696960c817407301560bbe5fbd92361488b4"), + TestFixture(16, "7da6ef35ad594a09cb74daf27e50a6b30d6b4160cf0de41ee32bbf2a208b911d", "98a32d7fe606583e2906420297", "51eb190c6a9f46e8ec1628b090795470c0", "47da3af0f599fcdb24cd3266fb04838df13c1c5755a5a240c33b2b890a486aac8b", "4ae414bc888a42141d3060c71c2dbbffd425b6a952806982271a8e756b3c9e24"), + TestFixture(16, "7da6ef35ad594a09cb74daf27e50a6b30d6b4160cf0de41ee32bbf2a208b911d", "98a32d7fe606583e2906420297", "25144e807e389bb0e45b6dc25558caf61a", "33256d7ce13e21832c8077143e251d0b2b4cfca1c19abf447d7bc0898d61885144", "7b7f78ae1a5ee96fdc49dacd71be1a6ac09a6a162d44dea0172886eca5674e46"), + TestFixture(16, "7da6ef35ad594a09cb74daf27e50a6b30d6b4160cf0de41ee32bbf2a208b911d", "98a32d7fe606583e2906420297", "dbe1ee14abfe2ecf4edf6db206cf9886ce", "cdd0cde834f894fc860477646db24f7bff229cc7a390867a245dcb7c434f1db347", "03f31c6143b77f6ad44749e2256306b8bf82242f2821fad4075b09b388ba81ca"), + TestFixture(16, "7da6ef35ad594a09cb74daf27e50a6b30d6b4160cf0de41ee32bbf2a208b911d", "98a32d7fe606583e2906420297", "db6df31f12bf552f81deff5fa2a373fc22", "cd5cd0e38db9ef1c4905e589c9dea401135361b539f9fe0fb7842907c2326aef63", "030390adb572f2bd2a6a4454fd68236cd1d465574328aa001d553375cc63f8a2"), + TestFixture(16, "7da6ef35ad594a09cb74daf27e50a6b30d6b4160cf0de41ee32bbf2a208b911d", "98a32d7fe606583e2906420297", "ff2a97b49fcc6a50d4549c979d53ccc51f", "e91bb44800cad0631c8f8641f62e1b382e8ed10943929e7d7bf798b2ae8371aae5", "7294ae94358669f2ada4b64c125b248df7fe86c6715e3b6a7b9bb2bd99392c8a"), + TestFixture(16, "7da6ef35ad594a09cb74daf27e50a6b30d6b4160cf0de41ee32bbf2a208b911d", "98a32d7fe606583e2906420297", "73ddfa0185200a890b7690a7e3986d8818", "65ecd9fd1a26b0bac3ad8a7188e5ba7529f92b9e49ab83f113f8949dc9e4a36e0d", "4d1513478fc1fb0a18eb6d2a9324fefbd975ecd1b409025de826bc397462acc1"), + TestFixture(16, "7da6ef35ad594a09cb74daf27e50a6b30d6b4160cf0de41ee32bbf2a208b911d", "98a32d7fe606583e2906420297", "5c7604f9ac8fdf30ee5820e5aeb75b65d7", "4a4727053389650326833a33c5ca8c98e6d0e53223adff22a08e3dddf66fff23e3", "b26a7ff61bfe94864249af7cc9b4a723627dd4463f5a22f0ca6063769522eab7"), + TestFixture(16, "7da6ef35ad594a09cb74daf27e50a6b30d6b4160cf0de41ee32bbf2a208b911d", "98a32d7fe606583e2906420297", "d44fdfd9da3a63c1083afe574e91bf01c9", "c27efc25453cd9f2c0e1e48125ec68fcf833f49a42521a7a2367f91bfcc2180b7c", "960f9a85cfbfb6eab223a4139c72ce926a680ea8e8ecc3088cf123de659ad310"), + TestFixture(16, "7da6ef35ad594a09cb74daf27e50a6b30d6b4160cf0de41ee32bbf2a208b911d", "98a32d7fe606583e2906420297", "bb515dc227abb9acad8fefaa14771bb77b", "ad607e3eb8ad039f6554f57c7f0acc4a4ac08bd395c6807223311070659f550934", "3718467effb5d5dc009aaefce84d8cb4fe8f80eb608f4c678f5d0de02ea11e59"), + TestFixture(16, "0786706f680c27b792d054faa63f499a8e6b5ddb90502946235bf74c022d772c", "f61ef1c8c10a863efeb4a1de86", "6a26677836d65bd0d35a027d278b2534e7df", "d1c1f3c60603359c7d6a707f05ecb2296f8e52f2210b7a798ad5c778ee7cfd7fe6e0", "67874c808600a27fcab34d6f69cc5c730831ad4589075dd82479823cb9b41dc3"), + TestFixture(16, "0786706f680c27b792d054faa63f499a8e6b5ddb90502946235bf74c022d772c", "f61ef1c8c10a863efeb4a1de86", "4021ff104ff1dbd91e46db249fd82198b0a1", "fbc66bae7f24b595b076a926bdbfb68538f00923bb5a347af13df12f234fca5f03ef", "e0c27cddf919d3092d9a34766c89a5ae6dcf39fe954d1e6f1a70ddf96805def4"), + TestFixture(16, "0786706f680c27b792d054faa63f499a8e6b5ddb90502946235bf74c022d772c", "f61ef1c8c10a863efeb4a1de86", "6a681f164efce199a787bccff223b8ae1a98", "d18f8ba87e298fd509b7cecdd0442fb392c9d03ed7bffac83e890caceb6903d9cab5", "7ae9eca03f616ab39ebb3be26b848842b4aa584e5c8e5695065ad5af34951175"), + TestFixture(16, "0786706f680c27b792d054faa63f499a8e6b5ddb90502946235bf74c022d772c", "f61ef1c8c10a863efeb4a1de86", "7861dac338ba3f8274dca04c8c6f92b6d44c", "c3864e7d086f51cedaecd24eae0805ab5c1d4dd8f30870025b2bd1e2a2511574d3e7", "b47c9bc4eb01c74f5db2e6a293bef80db18c58cf06feef7ee0f8a7a9a51c22bb"), + TestFixture(16, "0786706f680c27b792d054faa63f499a8e6b5ddb90502946235bf74c022d772c", "f61ef1c8c10a863efeb4a1de86", "a3f0473c620d2739d5ba4f7156f88d0fb669", "1817d38252d849757b8a3d73749f1a123e386046d17f337f3cb49884d94995edbdc9", "f6afd661f218c7426b92ee53e65d14898cd0c78a7e594fcc6ac0e3fb5cab1c9c"), + TestFixture(16, "0786706f680c27b792d054faa63f499a8e6b5ddb90502946235bf74c022d772c", "f61ef1c8c10a863efeb4a1de86", "07c535d9456a6ff1e41321150d16dae3f7a3", "bc22a16775bf01bd4a2353172f714dfe7ff25fdc77b43bca254d6459263cdfed8fbb", "d3802911e341577046cfc61d9043b4af059fb4bef3c6a2ff46ccdcb05670af37"), + TestFixture(16, "0786706f680c27b792d054faa63f499a8e6b5ddb90502946235bf74c022d772c", "f61ef1c8c10a863efeb4a1de86", "5ee220720a896249efdab2ce418318bb5ebf", "e505b4cc3a5c0c0541eac0cc63e48fa6d6eedd1a1d36c8164c55d55dbf0ff1e9517a", "db60720db67a60ca286fe744d46173c231fbcc7deb4c9b0d87d52a2247e06b74"), + TestFixture(16, "0786706f680c27b792d054faa63f499a8e6b5ddb90502946235bf74c022d772c", "f61ef1c8c10a863efeb4a1de86", "98e4eb0361c8bf40bcbe0539b0850e4c35ff", "23037fbd511dd10c128e773b92e29951bdaeb476e2ca48fd52bec0539b00744a8a07", "57f70ba5493265b30491decc726354e2065e7971a2efd56db9cf0f79b1d76859"), + TestFixture(16, "0786706f680c27b792d054faa63f499a8e6b5ddb90502946235bf74c022d772c", "f61ef1c8c10a863efeb4a1de86", "7f0745bea62479c0080ecec52e37c1e32d72", "c4e0d10096f1178ca63ebcc70c5056fea523fad68c62b81d62f2d490ae74f5bb1465", "4a29b9ad548964942f87f28ba267ec0d0e8f72c73b3823ee57693dd63c2605c1"), + TestFixture(16, "0786706f680c27b792d054faa63f499a8e6b5ddb90502946235bf74c022d772c", "f61ef1c8c10a863efeb4a1de86", "e99ed2ac6c38e033061b5d85f3e77dd72518", "527946125ced8e7fa82b2f87d180eacaad4913b15d8000266c61ba5aec898eb35b52", "acbd2e9911b3218a230d9db5086d91dccac3fc93fc64b0f4a15d56954906b2b7"), + TestFixture(16, "bac55f9847d93325bf5071c220c0a3dfeb38f214292d47b4acb7b0a597fe056f", "05b50c458adbba16c55fcc454d", "c1a994dc198f5676ea85801cd27cc8f47267ec", "7c9b138177590edaafec4728c4663e77458ffbe3243faec177de4a2e4a293952073e43", "89ad6ae1e550975eaa916a62615e6b6a66366a17a7e06380a95ea5cdcc1d3302"), + TestFixture(16, "bac55f9847d93325bf5071c220c0a3dfeb38f214292d47b4acb7b0a597fe056f", "05b50c458adbba16c55fcc454d", "791e232bfb42fb18197adc1967da1a83f70168", "c42ca4769594a3b45c131b2d71c0ec00c0e97f8422f736fc435687634d42254b22fd99", "dfddb719d00398bf48a6cefd27736389e654a93b8595cd5ac446af1996e0f161"), + TestFixture(16, "bac55f9847d93325bf5071c220c0a3dfeb38f214292d47b4acb7b0a597fe056f", "05b50c458adbba16c55fcc454d", "3d4127942459bb8682e662dfc862467582fa68", "8073a0c94a8fe32ac78fa5ebde78b0f6b5127f38a96e68ef7dbaef1b460cc0980eacd4", "58ef310997dcaf067dd217274921504da6dbf0428a2b48a65fe8a02c616ac306"), + TestFixture(16, "bac55f9847d93325bf5071c220c0a3dfeb38f214292d47b4acb7b0a597fe056f", "05b50c458adbba16c55fcc454d", "0e71863c2962244c7d1a28fc755f0c73e5cbd6", "b343016147b47ce03873efc86345faf0d223c15c5c702a82d468929227502e4e35796f", "511e5d5e100b595f6b20e791830bca37e23f7b785e482a58405bffe7a632a5b8"), + TestFixture(16, "bac55f9847d93325bf5071c220c0a3dfeb38f214292d47b4acb7b0a597fe056f", "05b50c458adbba16c55fcc454d", "e0f1cd013e6aea4fa484fc3fa35d348b1a2399", "5dc34a5c50bcb2e3e1ed3b0bb547c2082dcb8e89188c0940182dd99a902d158c5b0810", "e48dfaa53b6807ea6f01d8dca67960b9f321f7851f324459a9bf61fe0be73abb"), + TestFixture(16, "bac55f9847d93325bf5071c220c0a3dfeb38f214292d47b4acb7b0a597fe056f", "05b50c458adbba16c55fcc454d", "b1cc1946b4fc1dbd033254cdf536f61e9f9cd7", "0cfe9e1bda2a4511465b93f9e32c009da874c015849acbb7af1892790300bb84fb0558", "c12c0423fe36e4c88775dd00b4af267b85b7dd2a37a742a3156923c8917c97a3"), + TestFixture(16, "bac55f9847d93325bf5071c220c0a3dfeb38f214292d47b4acb7b0a597fe056f", "05b50c458adbba16c55fcc454d", "87284658928208e3bddca83e3ceb13708d88d4", "3a1ac105fc54504ff8b56f0a2af1e5f3ba60c3e75aaf3077ac6dfb5454851ec3910de6", "4255f8af18df7237e0abe98421aec9634443561752d893aaffe76380e829ef32"), + TestFixture(16, "bac55f9847d93325bf5071c220c0a3dfeb38f214292d47b4acb7b0a597fe056f", "05b50c458adbba16c55fcc454d", "bdb79f931ef3035a33bdd1b032fd9de8f6b2ba", "008518ce70255bf676d4168424e76b6bc15aade70f42e3e1f2b5bb58433bd11f5dea1f", "ab83567833d2f3461b5fbecc0e366694bb5ea00933b2b3e792ec3aefe20325df"), + TestFixture(16, "bac55f9847d93325bf5071c220c0a3dfeb38f214292d47b4acb7b0a597fe056f", "05b50c458adbba16c55fcc454d", "1f9c3a8eb8bc59f3869e10f73883aa8f8990cb", "a2aebdd3d66a015fc3f7d7c32e995c0cbe78dc564f6248cefe5fc7cfb547c90a558925", "bd1446ba3185d1c16551730947c22142142caa8cc1c540e89ab734ec297401bc"), + TestFixture(16, "bac55f9847d93325bf5071c220c0a3dfeb38f214292d47b4acb7b0a597fe056f", "05b50c458adbba16c55fcc454d", "5f28809181f9a889894da8d6fe1fde6cce354a", "e21a07ccef2ff025cc246fe2e80528eff9dd5db52249d812f7f235afa0732e984e91b2", "b87577755d2d9489194f6f7cfabf267dc3433a9c91954e81beb72c5e06870922"), + TestFixture(16, "8beedeb85d42c2a7fa6f7237b05acb197dd8e1672471ac878064fe5319eab876", "8479bdfad28ebe781e9c01a3f6", "7b125c3b9612a8b554913d0384f4795c90cd387c", "6cc611d816b18c6847b348e46a4119465104254a04e2dfeeeac9c3255f6227704848d5b2", "7aebdfd955d6e8a19a701d387447a4bdd59a9382156ab0c0dcd37b89419d6eff"), + TestFixture(16, "8beedeb85d42c2a7fa6f7237b05acb197dd8e1672471ac878064fe5319eab876", "8479bdfad28ebe781e9c01a3f6", "8b013f5782d5d1af8dbd451a4202866095dac975", "9cd572b40276f5729e9f30fdacb7e67a5413d44338d48329997c5981d678b5e24a6f01b0", "d119f300fbd74e754a200ea2c3f9fabc1466d02078c84245db693eef3f5672a6"), + TestFixture(16, "8beedeb85d42c2a7fa6f7237b05acb197dd8e1672471ac878064fe5319eab876", "8479bdfad28ebe781e9c01a3f6", "b2b1d82a5523b72ea366a680922ed3a4624536c4", "a56595c9d58093f3b044d3677c9bb3bea38c2bf2a77e3ab68e0a73519591a33ed098b758", "d6204303b86acf62d5ab860ca70161288ede56e3cf017c08dca56fd2d6f8f6fe"), + TestFixture(16, "8beedeb85d42c2a7fa6f7237b05acb197dd8e1672471ac878064fe5319eab876", "8479bdfad28ebe781e9c01a3f6", "f8c4eb4285d3d7744da52775bb44ca436a3154f7", "ef10a6a10570f3a95e87529255f1aa59abf849c1cff6c24251c2fb7b8604dfa10c60ef4a", "8557e22eb4529b43f16b1f8ae47c714ac8a2c827c1408a47704778b4c5b52601"), + TestFixture(16, "8beedeb85d42c2a7fa6f7237b05acb197dd8e1672471ac878064fe5319eab876", "8479bdfad28ebe781e9c01a3f6", "6e7fe35fa39c937a0e6b3a8c072e218650f42b8d", "79abaebc233fb7a71d494f6be99b419c913d36bb6c3c39f915d081d34559179869b32d81", "8c1a4187efbb3d38332f608f2c8bbe64247d9afa2281ced56c586ecb4ab7a85e"), + TestFixture(16, "8beedeb85d42c2a7fa6f7237b05acb197dd8e1672471ac878064fe5319eab876", "8479bdfad28ebe781e9c01a3f6", "917b467d841850fc6e648f1bc298a7f9f1ee38ca", "86af0b9e04bb74217d46fafc2c2dc7e3302725fc9389a6a6a74c6eb0e1f87562469f2082", "a41bb1f256228302cd0548ae2148ff42774d18c2d6d3e38b36bc4938da13bac3"), + TestFixture(16, "8beedeb85d42c2a7fa6f7237b05acb197dd8e1672471ac878064fe5319eab876", "8479bdfad28ebe781e9c01a3f6", "2b4314fe1a6bfa786b7cfc13fbee861b348efbf6", "3c97591d9ac8dea5785e89f4155be601f547e6c03bed3a2f5dfdbfcc0d7ac26c88d1962c", "b0b024e20c4f75a6dad54c21a9edbce846792e957878b1c8ed2d916c757e2b3c"), + TestFixture(16, "8beedeb85d42c2a7fa6f7237b05acb197dd8e1672471ac878064fe5319eab876", "8479bdfad28ebe781e9c01a3f6", "e19fa7f83c79920cbff45c41a9dee8fc99e97396", "f64bea1bbcdab6d1acd629a6476b88e658206ea035ea1d99be344fa1467ee91c73bbca67", "42153925c46fc9d5d328312d62f59bb99fdc4ac479a3386d5f88fefd4b32f577"), + TestFixture(16, "8beedeb85d42c2a7fa6f7237b05acb197dd8e1672471ac878064fe5319eab876", "8479bdfad28ebe781e9c01a3f6", "53e0475cf492b3d39dad600f5c58eb0bd0021554", "44340abf7431970e8e8f15e8b2ed8b1111cb08627936ec10a81b36768b606e9a38b2f4c5", "37ab2a0b7b69942278e21032fc83eba6cdc34f5285a8b711a08da6acd42299fe"), + TestFixture(16, "8beedeb85d42c2a7fa6f7237b05acb197dd8e1672471ac878064fe5319eab876", "8479bdfad28ebe781e9c01a3f6", "c119a383d9a3d4bff4270a1d22076b346db5f61c", "d6cdee605900f062e7057ffaccb20b2eac7ceb2a11575ae03ea8a57bbe4a67c060367b74", "4a17522da707b4b2587a0ae367a2cd2831bb593a18ef442a7977eda6de045878"), + TestFixture(16, "c3a0c126cad581012151c25cf85a44472c23f83b6095b6004f4f32cd60ec2db2", "94ab51ce75db8b046d6ab92830", "73b09d18554471309141aa33b687f9248b50fe3154", "b7e8264ca70fd2a4fb76f20a8ad5da3c37f5893fb12abeeaef1187f815ca481ed8ddd3dd37", "2a243246bfe5b5ab05f51bf5f401af52d5bbaa2549cf57a18e197597fe15dd8c"), + TestFixture(16, "c3a0c126cad581012151c25cf85a44472c23f83b6095b6004f4f32cd60ec2db2", "94ab51ce75db8b046d6ab92830", "b64d00f3a4df754fa4ee6376922fb67ccce0c6209f", "7215bba75694d6dbced93b4fae7d95647045b12e7accc2b55011dbe92ce7619e0ad48b4ccf", "0595306eb7441622a49800edee0134492d82320707fceba902af2e0c95fe634a"), + TestFixture(16, "c3a0c126cad581012151c25cf85a44472c23f83b6095b6004f4f32cd60ec2db2", "94ab51ce75db8b046d6ab92830", "2b11d1ac74ffe701ec733d32085b1054132726e622", "ef496af886b444958644650b3409334caf8251e8c71e8b1f4d70d8f4c7df4f22847d36b394", "bd439dbefec589e120fb4f9825b315bf86523b85c61791cd4da4c8d474ba2714"), + TestFixture(16, "c3a0c126cad581012151c25cf85a44472c23f83b6095b6004f4f32cd60ec2db2", "94ab51ce75db8b046d6ab92830", "a88f22424643a523aa3d7d88f4364f1290f49dd0a2", "6cd79916b40806b7c00a25b1c8646c0a2c51eade47a85e76a9d07b7b361ca56d53c34cda50", "cfebe1cf82267394065bcecfada6709c6c35a3ac835644f560d4c9a8c1848364"), + TestFixture(16, "c3a0c126cad581012151c25cf85a44472c23f83b6095b6004f4f32cd60ec2db2", "94ab51ce75db8b046d6ab92830", "c81427bc84c6a3cfefd4c4cb210fe82212977e1947", "0c4c9ce8768d005b85e39cf21d5dcb3aae320917a2fddb010e7508ad03ad287068ecee6020", "7a37255b682766a0bfecf78e5162528885a339174c2a49325739d2bd8877e64f"), + TestFixture(16, "c3a0c126cad581012151c25cf85a44472c23f83b6095b6004f4f32cd60ec2db2", "94ab51ce75db8b046d6ab92830", "28c4d6de3e2ce51b849b135d9cfd3084f0e3155447", "ec9c6d8acc67468feeac4b64a0af139c4c46625aa2ddea785e6c470c52c4fdf432fd78b66e", "619f2ae80070e278615466a3fd6c9acb7b510c5679bed7038889c77e78d8bd32"), + TestFixture(16, "c3a0c126cad581012151c25cf85a44472c23f83b6095b6004f4f32cd60ec2db2", "94ab51ce75db8b046d6ab92830", "4c88151cafef75832bacef43a06e862349d56b67ee", "88d0ae485da4d617419bb77a9c3ca53bf5701c690b91232cfbd7ffff252498b35274fb2995", "b2571e56f66a857daffbdc99370ceddd4a7bed3867d600cc797000a3b7b57a9d"), + TestFixture(16, "c3a0c126cad581012151c25cf85a44472c23f83b6095b6004f4f32cd60ec2db2", "94ab51ce75db8b046d6ab92830", "572855e22ce89bc2bcf09cb15a1765d99973449d61", "9370eeb6dea33856d6c7c488664546c125d633938472b2c50e5e391ad104f9ee33b94f2872", "db409636e3e3bcd606a91aeb7592009896f9ad2c4cc6b7f578e6ad59c0f8fa22"), + TestFixture(16, "c3a0c126cad581012151c25cf85a44472c23f83b6095b6004f4f32cd60ec2db2", "94ab51ce75db8b046d6ab92830", "89ce46b3de3afaf2518d419b1a2ac24cabca269a96", "4d96fde72c7159663bba19a22678e154176f5194732d69c5d6db1b130102af3dae0690673b", "62c89a835721207a182968c516dc8be45774ec846e8dcab9ab8611888f2a76a8"), + TestFixture(16, "c3a0c126cad581012151c25cf85a44472c23f83b6095b6004f4f32cd60ec2db2", "94ab51ce75db8b046d6ab92830", "edf1682a626e9fbf3d57bb260e0876c6f92ba5b114", "29a9d37e90253c2b5760e31f325a55de458ed2bff1489903365970c2673c9fd457e1077aad", "33f30ddd83002eea50fd4a8fae39d0980a04160a22ac88b755ac050f1d1f8639"), + TestFixture(16, "9cdebaeee8690b68751070691f49593668a6de12d3a948b38ddbd3f75218b2d4", "af1a97d43151f5ea9c48ad36a3", "3cbb08f133270e4454bcaaa0f20f6d63c38b6572e766", "3966930a2ae8fdd8f40e7007f3fde0bd6eb48a46e6d26eef83da9f6384b1a2bda10790dadb3f", "f5353fb6bfc8f09d556158132d6cbb97d9045eacdc71f782bcef62d258b1950a"), + TestFixture(16, "9cdebaeee8690b68751070691f49593668a6de12d3a948b38ddbd3f75218b2d4", "af1a97d43151f5ea9c48ad36a3", "946e86795c332031e2d1ee09d3d4a101fb6800d00911", "91b31d8245fcd3ad426334aed2262cdf5657efe408a5587bdd120a7d08cd3841cb117af444fb", "e3a1555ffe5f34bb43c4a2dae9019b19f1e44a45fb577d495d2a57097612448d"), + TestFixture(16, "9cdebaeee8690b68751070691f49593668a6de12d3a948b38ddbd3f75218b2d4", "af1a97d43151f5ea9c48ad36a3", "b76ce2ab0065ba1c0a754494991c8c452cb416f18ab1", "b2b1795019aa4980aac79e3398ee019b818bf9c58b0545b32f81dcf03e2bcc2aaf62ad366e97", "9c5d43c1a1269cde199509a1eff67cc83a1759b71c9e7a6ee99f76b98c6e23a6"), + TestFixture(16, "9cdebaeee8690b68751070691f49593668a6de12d3a948b38ddbd3f75218b2d4", "af1a97d43151f5ea9c48ad36a3", "a3e0d8d0784155bfc45769c52711d4fa68e8bc390c20", "a63d432b618ea62364e5b36226e35924c5d7530d0d94fea17d78533bc9e022dbfb460afdf499", "b07452a7900a289b91b2771dfdd5108852536659aa259def7b41e38f80bd03ab"), + TestFixture(16, "9cdebaeee8690b68751070691f49593668a6de12d3a948b38ddbd3f75218b2d4", "af1a97d43151f5ea9c48ad36a3", "6e6a88abbb52a709b47365ad6aa8016fa9a03a9bd834", "6bb71350a29d549514c1bf0a6b5a8cb1049fd5afd98056defc6dcaeec80b1c639350ab6f1fde", "6b30f55c3101540523a92380390f3f84632f42962061b2724cde78ac39809397"), + TestFixture(16, "9cdebaeee8690b68751070691f49593668a6de12d3a948b38ddbd3f75218b2d4", "af1a97d43151f5ea9c48ad36a3", "eba1810d537041821121aeff8e0914ac26a550072c8c", "ee7c1af64abfb21eb19374588ffb99728b9abf332d389d37b7251fb8c0ef2b37c36d51219d0f", "9fc62d14f8b7a6026509275cff80312ff1ade2b5d9c274cb72a506a571439fc1"), + TestFixture(16, "9cdebaeee8690b68751070691f49593668a6de12d3a948b38ddbd3f75218b2d4", "af1a97d43151f5ea9c48ad36a3", "dfc6692cd2442e5ff1f918c8812a27f81d107d16a12f", "da1bf2d7cb8bddc3514bc26f80d8aa26b02f9222a09bd279d9da4437c8a2a252436508134c56", "6b9389cc42113d639fd2b40cbc732ae0dc7c14513b88b36b45a6ea5a06fe4d2b"), + TestFixture(16, "9cdebaeee8690b68751070691f49593668a6de12d3a948b38ddbd3f75218b2d4", "af1a97d43151f5ea9c48ad36a3", "9ad338cbfd1b52e6ae4178f05e00062274f8b0b25eae", "9f0ea330e4d4a17a0ef3a2575ff28bfcd9c75f865f1a63943543bc1c5f5991ecc5964a288f79", "db72d98d63fc10acff7dceec0e2691a80ecee50a0e957ad166c77952a50318bd"), + TestFixture(16, "9cdebaeee8690b68751070691f49593668a6de12d3a948b38ddbd3f75218b2d4", "af1a97d43151f5ea9c48ad36a3", "9f5a05db89e0e336da066ce81b79ad9be1d0ec4fb7b8", "9a879e20902f10aa7ab4b64f1a8b20454cef037bb60c0a49ee2b7ceddcbd28abb24b77d5edee", "e98b710c47a4d12a73cd8aa2613fc2910c16f4195ea7f15650132493521d19be"), + TestFixture(16, "9cdebaeee8690b68751070691f49593668a6de12d3a948b38ddbd3f75218b2d4", "af1a97d43151f5ea9c48ad36a3", "58f31e5770070a5d4031fb795dc2d298561d3559960d", "5d2e85ac69c8f9c1e08321de5c305f46fb22da6d97b9b099a68cfa3572d974e03232e09f37fb", "527817316fc48b105f8ab178dd2db1fefa09c50461aa9d8bdf3c03482343bbf9"), + TestFixture(16, "d34264a12c35cdd67ac105e2826b071e46f8131d1e325f8e0ae80a6447375135", "3891e308b9f44c5b5a8b59004a", "79ac1a6a9eca5e07ce635bfd666ef72b16f3f2e140d56c", "1abcc9b1649deaa0bfa7dcd23508282d9c50ca7fee72486950608d7bcb39dcf03a2cab01587f61", "0cda000ed754456a844c9ed61843deea9dadf5e723ea1448057712996d660f8c"), + TestFixture(16, "d34264a12c35cdd67ac105e2826b071e46f8131d1e325f8e0ae80a6447375135", "3891e308b9f44c5b5a8b59004a", "76d12e3c4c5d990bf563c60aa4999e52998d887f97477f", "15c1fde7b60a2dac84a74125f7ff4154132eb0e139e05b1c4fb40e5c8bc37152a173d4bbb18c3e", "3fb6ddb76809b8e6d703347664ef00a365955124c603900d5c8d4ff476138252"), + TestFixture(16, "d34264a12c35cdd67ac105e2826b071e46f8131d1e325f8e0ae80a6447375135", "3891e308b9f44c5b5a8b59004a", "a027c28fbe22111fd4c8a226cfe8531c16d7790d561eca", "c33711544475a5b8a50c25099c8e8c1a9c744193f8b9ee019c359008adae3070b5a543ead0effb", "d9fc295082e8f48569eb073ac1b9566246728fc62ccaab4a5667c472c98b2626"), + TestFixture(16, "d34264a12c35cdd67ac105e2826b071e46f8131d1e325f8e0ae80a6447375135", "3891e308b9f44c5b5a8b59004a", "fa597e37c26c38694abdcf450f9edc529160fa0d651979", "9949adec383b8cce3b79486a5cf803541bc3c293cbbe5dbd099ab134756b90746762a92a4a9f7f", "7a459aadb48f1a528edae71fcf698b84ed64dc0e18cc23f27ab47eeabeaf833f"), + TestFixture(16, "d34264a12c35cdd67ac105e2826b071e46f8131d1e325f8e0ae80a6447375135", "3891e308b9f44c5b5a8b59004a", "9e4c8aa9b58a8eabc5586892f5541000b43f17d9a051a0", "fd5c59724fdd3a0cb49cefbda632cf063e9c2f470ef684fa4f6adfec85d055310107ba89198afa", "484207909dec4c35929ebe82fcacf20d2af6d850bd69364ebac9557adeadfbd4"), + TestFixture(16, "d34264a12c35cdd67ac105e2826b071e46f8131d1e325f8e0ae80a6447375135", "3891e308b9f44c5b5a8b59004a", "7d9582cf9e3bb9ee34dce965f56b08e716589486b0641c", "1e855114646c0d4945186e4aa60dd7e19cfbac181ec338915d23eb2e952afcc89fbddb567d9d75", "88b5448372548e6aab1b262630a28a471d285514703f1bdb10c695850e18fe6d"), + TestFixture(16, "d34264a12c35cdd67ac105e2826b071e46f8131d1e325f8e0ae80a6447375135", "3891e308b9f44c5b5a8b59004a", "5a387e7cc22491fc556fe6a0c060b4911d01f0c11f801e", "3928ada73873255b24ab618f93066b9797a2c85fb1273aaad6c31828314e24198f005955ca8f5e", "0e71863c2962244c7d1a28fc755f0c73e5cbd630a8dbdeb38842d7795d830d2e"), + TestFixture(16, "d34264a12c35cdd67ac105e2826b071e46f8131d1e325f8e0ae80a6447375135", "3891e308b9f44c5b5a8b59004a", "87946e910059cbaf48df63b220f397049c65ca10cd1920", "e484bd4afa0e7f08391be49d7395480216c6f28e63be04e531ebbadccfe47182b41904bbfebcfe", "2aa7a28da38c42fda2e578d9d6340cd8e80b9b32047c3db296d0640d517b0872"), + TestFixture(16, "d34264a12c35cdd67ac105e2826b071e46f8131d1e325f8e0ae80a6447375135", "3891e308b9f44c5b5a8b59004a", "c62f67d208f1c8ffd5d57df9de15ef54f97fbc07d1630a", "a53fb409f2a67c58a411fad68d73305273dc84997fc42e7c582414154236c09ee704cf4a5de411", "3382051c268891da04e6ca73adcead4029f6a1593be4acfe3968e7351a6a2fb5"), + TestFixture(16, "d34264a12c35cdd67ac105e2826b071e46f8131d1e325f8e0ae80a6447375135", "3891e308b9f44c5b5a8b59004a", "697e73eaaf562d31bdbf7ce9e78c7426fe1c87e421def9", "0a6ea03155019996cc7bfbc6b4eaab2074bfbf7a8f79dd57c9990029c89d1b37988745fa5737a3", "c352828b1920e53bbb60f2ea6a5f15639659e6f3243405c26f6e48628d5519a9"), + TestFixture(16, "4ad98dbef0fb2a188b6c49a859c920967214b998435a00b93d931b5acecaf976", "00d772b07788536b688ff2b84a", "9cea3b061e5c402d48497ea4948d75b8af7746d4e570c848", "f28ec535c2d834963c85814ec4173c0b8983dff8dc4a2d4e0f73bfb28ad42aa8f75f549a93594dd4", "5f8b1400920891e8057639618183c9c847821c1aae79f2a90d75f114db21e975"), + TestFixture(16, "4ad98dbef0fb2a188b6c49a859c920967214b998435a00b93d931b5acecaf976", "00d772b07788536b688ff2b84a", "2b223932fb2fd8433e4b1af9e8234a824569a141f6c96a69", "4546c70127abacf84a87e513b8b90331639d386dcff38f6f4de907a59c5e4d3f21e1348d7cdf92b6", "1ae8108f216defea65d9426da8f8746a3ae408e563d62203063d49bf7e0d6bdf"), + TestFixture(16, "4ad98dbef0fb2a188b6c49a859c920967214b998435a00b93d931b5acecaf976", "00d772b07788536b688ff2b84a", "4d57cbe4a7e780d4ed17267d5ebc91750c2f0209e0444bd2", "233335d77b63f46f99dbd9970e26d8c62adb9b25d97eaed4ff4239544e2f354d6c6837cd9c23b884", "460f08114b1015fe8b7a9b5dd1b9e6a3d28367c4bd15f29b13c02a8cb9a53968"), + TestFixture(16, "4ad98dbef0fb2a188b6c49a859c920967214b998435a00b93d931b5acecaf976", "00d772b07788536b688ff2b84a", "fda8665f87c618646a89c7abdca275fd10c31453ad4b9c99", "93cc986c5b426cdf1e4538418c383c4e36378d7f9471799f3f6c6f7cc494201069344e2d6d41bd9b", "860f4428259d9c5b17698cc95363db6cfee603258582e3a3e8feb886599d4ac4"), + TestFixture(16, "4ad98dbef0fb2a188b6c49a859c920967214b998435a00b93d931b5acecaf976", "00d772b07788536b688ff2b84a", "98104fd3f3413ad1f57ef4912cb50097dca379a58c47b0d2", "f674b1e02fc54e6a81b20b7b7c2f4924fa57e089b57d55d43787a15352cfceb028202c8730beaa7a", "1b43c482f83780c21583f88e5afcf6938edd20f21b74d895161b60c27a6a42f0"), + TestFixture(16, "4ad98dbef0fb2a188b6c49a859c920967214b998435a00b93d931b5acecaf976", "00d772b07788536b688ff2b84a", "b46b343e64d2d70e0bd909dbb3f6bedf7e4adc74321be526", "da0fca0db856a3b57f15f631e36cf76c58be45580b210020f3a0ca3da647eb31893e867956097983", "b082ccd964617c27a5607b7324faad237ee53acfc18c35502dbf7c1937a9dfcb"), + TestFixture(16, "4ad98dbef0fb2a188b6c49a859c920967214b998435a00b93d931b5acecaf976", "00d772b07788536b688ff2b84a", "8e12620bb575e6b167b085255b2b5631ff28e04cbef8826d", "e0769c3869f1920a137c7acf0bb11f82d9dc796087c2676be663fbbebbc251b9f1760afa49e89e71", "b8539ba93ef17254ec1d8d62e8f4eae4d41ee1e75345bf90c9cbb26c63bce501"), + TestFixture(16, "4ad98dbef0fb2a188b6c49a859c920967214b998435a00b93d931b5acecaf976", "00d772b07788536b688ff2b84a", "792aaa23b923d1b53173fe19853b9aa402a301d48529873e", "174e541065a7a50e45bf01f3d5a1d317245798f8bc136238da90cd87e9d9ca5d85430a150e682752", "b6b09463b5ef5ead1f17f4021693a0d8452e98dcbb8e7590f9fde6394970a6f8"), + TestFixture(16, "4ad98dbef0fb2a188b6c49a859c920967214b998435a00b93d931b5acecaf976", "00d772b07788536b688ff2b84a", "ddc5b4e48970ebd72869be6998e9103c014475e8ae6ea29c", "b3a14ad755f49f6c5ca54183c873598f27b0ecc49754479afc0cc4601afb61efa7059cfe49ec9dde", "390f6de14d5e1f2f78dbe757c00b89209d0cf8bc48cbbea035779f93de357905"), + TestFixture(16, "4ad98dbef0fb2a188b6c49a859c920967214b998435a00b93d931b5acecaf976", "00d772b07788536b688ff2b84a", "d2b66096c475a77648c27235e6972ba8f18761330d3c6adf", "bcd29ea518f1d3cd3c0e8ddfb60d621bd773f81f34068fd9cf7474962c3602dcfcb50039f43e3d6f", "1d75c9e7acb09932db332498d30f82e4009025cb1827047c59a8f97812b568a4") + ] + + func testEncrypt(fixture: TestFixture) -> Bool { + let aes = try! AES(key: fixture.key, blockMode: CCM(iv: fixture.nonce, tagLength: fixture.tagLength, messageLength: fixture.plaintext.count, additionalAuthenticatedData: fixture.aad), padding: .noPadding) + let encrypted = try! aes.encrypt(fixture.plaintext) + if encrypted != fixture.expected { + return false + } + return true + } + + func testDecrypt(fixture: TestFixture) -> Bool { + let aes = try! AES(key: fixture.key, blockMode: CCM(iv: fixture.nonce, tagLength: fixture.tagLength, messageLength: fixture.plaintext.count /*- fixture.tagLength*/, additionalAuthenticatedData: fixture.aad), padding: .noPadding) + let plaintext = try! aes.decrypt(fixture.expected) + if plaintext != fixture.plaintext { + return false + } + return true + } + + for (i,fixture) in fixtures.enumerated() { + XCTAssertTrue(testEncrypt(fixture: fixture), "Encryption failed") + XCTAssertTrue(testDecrypt(fixture: fixture), "(\(i) - Decryption failed.") + } + } + + + func testAESCCMTestCase1() { + let key: Array = [0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f]; + let nonce: Array = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16] + let aad: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07] + let plaintext: Array = [0x20, 0x21, 0x22, 0x23] + let expected: Array = [0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d] + + let aes = try! AES(key: key, blockMode: CCM(iv: nonce, tagLength: 4, messageLength: plaintext.count, additionalAuthenticatedData: aad), padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + XCTAssertEqual(encrypted, expected, "encryption failed") + } + + func testAESCCMTestCase1Decrypt() { + let key: Array = [0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f]; + let nonce: Array = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16] + let aad: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07] + let ciphertext: Array = [0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d] + let expected: Array = [0x20, 0x21, 0x22, 0x23] + + let aes = try! AES(key: key, blockMode: CCM(iv: nonce, tagLength: 4, messageLength: ciphertext.count - 4, additionalAuthenticatedData: aad), padding: .noPadding) + let decrypted = try! aes.decrypt(ciphertext) + XCTAssertEqual(decrypted, expected, "decryption failed") + } + + func testAESCCMTestCase2() { + let key: Array = [0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f]; + let nonce: Array = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17] + let aad: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + let plaintext: Array = [0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f] + let expected: Array = [0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd] + + let aes = try! AES(key: key, blockMode: CCM(iv: nonce, tagLength: 6, messageLength: plaintext.count, additionalAuthenticatedData: aad), padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + XCTAssertEqual(encrypted, expected, "encryption failed") + } + + func testAESCCMTestCase2Decrypt() { + let key: Array = [0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f]; + let nonce: Array = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17] + let aad: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + let ciphertext: Array = [0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd] + let expected: Array = [0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f] + + let aes = try! AES(key: key, blockMode: CCM(iv: nonce, tagLength: 6, messageLength: ciphertext.count - 6, additionalAuthenticatedData: aad), padding: .noPadding) + let plaintext = try! aes.decrypt(ciphertext) + XCTAssertEqual(plaintext, expected, "encryption failed") + } + + func testAESCCMTestCase3() { + let key: Array = [0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f]; + let nonce: Array = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b] + let aad: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13] + let plaintext: Array = [0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37] + let expected: Array = [0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51] + + let aes = try! AES(key: key, blockMode: CCM(iv: nonce, tagLength: 8, messageLength: plaintext.count, additionalAuthenticatedData: aad), padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + XCTAssertEqual(encrypted, expected, "encryption failed") + } + + func testAESCCMTestCase3Decrypt() { + let key: Array = [0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f]; + let nonce: Array = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b] + let aad: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13] + let ciphertext: Array = [0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51] + let expected: Array = [0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37] + + let aes = try! AES(key: key, blockMode: CCM(iv: nonce, tagLength: 8, messageLength: ciphertext.count - 8, additionalAuthenticatedData: aad), padding: .noPadding) + let plaintext = try! aes.decrypt(ciphertext) + XCTAssertEqual(plaintext, expected, "encryption failed") + } + + func testAESCCMTestCase3DecryptPartial() { + let key: Array = [0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f]; + let nonce: Array = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b] + let aad: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13] + let ciphertext: Array = [0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51] + let expected: Array = [0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37] + + let aes = try! AES(key: key, blockMode: CCM(iv: nonce, tagLength: 8, messageLength: ciphertext.count - 8, additionalAuthenticatedData: aad), padding: .noPadding) + var decryptor = try! aes.makeDecryptor() + + var plaintext = [UInt8]() + plaintext += try! decryptor.update(withBytes: Array(ciphertext[0..<2])) + plaintext += try! decryptor.update(withBytes: Array(ciphertext[2..<6])) + plaintext += try! decryptor.update(withBytes: Array(ciphertext[6..<32]), isLast: true) + XCTAssertEqual(plaintext, expected, "encryption failed") + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/AESTests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/AESTests.swift new file mode 100644 index 0000000000..c88c9a2cbf --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/AESTests.swift @@ -0,0 +1,685 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import Foundation +import XCTest + +final class AESTests: XCTestCase { + // 128 bit key + let aesKey: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + + func testAESEncrypt() { + let input: Array = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff] + let expected: Array = [0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x4, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a] + + let aes = try! AES(key: aesKey, blockMode: ECB(), padding: .noPadding) + let encrypted = try! aes.encrypt(input) + XCTAssertEqual(encrypted, expected, "encryption failed") + let decrypted = try! aes.decrypt(encrypted) + XCTAssertEqual(decrypted, input, "decryption failed") + } + + func testAESEncrypt2() { + let key: Array = [0x36, 0x37, 0x39, 0x66, 0x62, 0x31, 0x64, 0x64, 0x66, 0x37, 0x64, 0x38, 0x31, 0x62, 0x65, 0x65] + let iv: Array = [0x6b, 0x64, 0x66, 0x36, 0x37, 0x33, 0x39, 0x38, 0x44, 0x46, 0x37, 0x33, 0x38, 0x33, 0x66, 0x64] + let input: Array = [0x62, 0x72, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + + let expected: Array = [0xae, 0x8c, 0x59, 0x95, 0xb2, 0x6f, 0x8e, 0x3d, 0xb0, 0x6f, 0x0a, 0xa5, 0xfe, 0xc4, 0xf0, 0xc2] + + let aes = try! AES(key: key, blockMode: CBC(iv: iv), padding: .noPadding) + do { + let encrypted = try aes.encrypt(input) + XCTAssertEqual(encrypted, expected, "encryption failed") + let decrypted = try aes.decrypt(encrypted) + XCTAssertEqual(decrypted, input, "decryption failed") + } catch { + XCTFail("\(error)") + } + } + + func testAESEncrypt3() { + let key = "679fb1ddf7d81bee" + let iv = "kdf67398DF7383fd" + let input: Array = [0x62, 0x72, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + let expected: Array = [0xae, 0x8c, 0x59, 0x95, 0xb2, 0x6f, 0x8e, 0x3d, 0xb0, 0x6f, 0x0a, 0xa5, 0xfe, 0xc4, 0xf0, 0xc2] + + do { + let aes = try AES(key: key, iv: iv, padding: .noPadding) + let encrypted = try aes.encrypt(input) + XCTAssertEqual(encrypted, expected, "encryption failed") + let decrypted = try aes.decrypt(encrypted) + XCTAssertEqual(decrypted, input, "decryption failed") + } catch { + XCTFail("\(error)") + } + } + + func testAESEncryptCBCNoPadding() { + let key: Array = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let iv: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + let plaintext: Array = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a] + let expected: Array = [0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d] + + let aes = try! AES(key: key, blockMode: CBC(iv: iv), padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + XCTAssertEqual(encrypted, expected, "encryption failed") + let decrypted = try! aes.decrypt(encrypted) + XCTAssertEqual(decrypted, plaintext, "decryption failed") + } + + func testAESEncryptCBCWithPadding() { + let key: Array = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let iv: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + let plaintext: Array = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a] + let expected: Array = [0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, 0x89, 0x64, 0xe0, 0xb1, 0x49, 0xc1, 0x0b, 0x7b, 0x68, 0x2e, 0x6e, 0x39, 0xaa, 0xeb, 0x73, 0x1c] + + let aes = try! AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) + let encrypted = try! aes.encrypt(plaintext) + XCTAssertEqual(encrypted, expected, "encryption failed") + let decrypted = try! aes.decrypt(encrypted) + XCTAssertEqual(decrypted, plaintext, "decryption failed") + } + + func testAESEncryptCBCWithPaddingPartial() { + let key: Array = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let iv: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + let plaintext: Array = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a] + + let aes = try! AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) + + var ciphertext = Array() + var encryptor = try! aes.makeEncryptor() + ciphertext += try! encryptor.update(withBytes: plaintext[0..<8]) + ciphertext += try! encryptor.update(withBytes: plaintext[8..<16]) + ciphertext += try! encryptor.update(withBytes: plaintext[16..<32]) + ciphertext += try! encryptor.finish() + XCTAssertEqual(try! aes.encrypt(plaintext), ciphertext, "encryption failed") + } + + func testAESEncryptIncremental() { + do { + var ciphertext = Array() + let plaintext = "Today Apple launched the open source Swift community, as well as amazing new tools and resources." + let aes = try AES(key: "passwordpassword".bytes, blockMode: CBC(iv: "drowssapdrowssap".bytes)) + var encryptor = try! aes.makeEncryptor() + + ciphertext += try encryptor.update(withBytes: plaintext.bytes) + ciphertext += try encryptor.finish() + XCTAssertEqual(try aes.encrypt(plaintext.bytes), ciphertext, "encryption failed") + } catch { + XCTFail("\(error)") + } + } + + func testAESDecryptCBCWithPaddingPartial() { + let key: Array = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let iv: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + let ciphertext: Array = [118, 73, 171, 172, 129, 25, 178, 70, 206, 233, 142, 155, 18, 233, 25, 125, 76, 187, 200, 88, 117, 107, 53, 129, 37, 82, 158, 150, 152, 163, 143, 68, 169, 105, 137, 234, 93, 98, 239, 215, 41, 45, 51, 254, 138, 92, 251, 17] + + let aes = try! AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) + var plaintext = Array() + var decryptor = try! aes.makeDecryptor() + plaintext += try! decryptor.update(withBytes: ciphertext[0..<8]) + plaintext += try! decryptor.update(withBytes: ciphertext[8..<16]) + plaintext += try! decryptor.update(withBytes: ciphertext[16..<32]) + plaintext += try! decryptor.finish() + XCTAssertEqual(try! aes.decrypt(ciphertext), plaintext, "encryption failed") + } + + func testAESEncryptCFB() { + let key: Array = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let iv: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + let plaintext: Array = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a] + let expected: Array = [0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a] + + let aes = try! AES(key: key, blockMode: CFB(iv: iv), padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + XCTAssertEqual(encrypted, expected, "encryption failed") + let decrypted = try! aes.decrypt(encrypted) + XCTAssertEqual(decrypted, plaintext, "decryption failed") + } + + // https://github.com/krzyzanowskim/CryptoSwift/issues/142 + func testAESEncryptCFBLong() { + let key: Array = [56, 118, 37, 51, 125, 78, 103, 107, 119, 40, 74, 88, 117, 112, 123, 75, 122, 89, 72, 36, 46, 91, 106, 60, 54, 110, 34, 126, 69, 126, 61, 87] + let iv: Array = [69, 122, 99, 87, 83, 112, 110, 65, 54, 109, 107, 89, 73, 122, 74, 49] + let plaintext: Array = [123, 10, 32, 32, 34, 67, 111, 110, 102, 105, 114, 109, 34, 32, 58, 32, 34, 116, 101, 115, 116, 105, 110, 103, 34, 44, 10, 32, 32, 34, 70, 105, 114, 115, 116, 78, 97, 109, 101, 34, 32, 58, 32, 34, 84, 101, 115, 116, 34, 44, 10, 32, 32, 34, 69, 109, 97, 105, 108, 34, 32, 58, 32, 34, 116, 101, 115, 116, 64, 116, 101, 115, 116, 46, 99, 111, 109, 34, 44, 10, 32, 32, 34, 76, 97, 115, 116, 78, 97, 109, 101, 34, 32, 58, 32, 34, 84, 101, 115, 116, 101, 114, 34, 44, 10, 32, 32, 34, 80, 97, 115, 115, 119, 111, 114, 100, 34, 32, 58, 32, 34, 116, 101, 115, 116, 105, 110, 103, 34, 44, 10, 32, 32, 34, 85, 115, 101, 114, 110, 97, 109, 101, 34, 32, 58, 32, 34, 84, 101, 115, 116, 34, 10, 125] + let encrypted: Array = try! AES(key: key, blockMode: CFB(iv: iv)).encrypt(plaintext) + let decrypted: Array = try! AES(key: key, blockMode: CFB(iv: iv)).decrypt(encrypted) + XCTAssert(decrypted == plaintext, "decryption failed") + } + + func testAESEncryptOFB128() { + let key: Array = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let iv: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + let plaintext: Array = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a] + let expected: Array = [0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a] + + let aes = try! AES(key: key, blockMode: OFB(iv: iv), padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + XCTAssertEqual(encrypted, expected, "encryption failed") + let decrypted = try! aes.decrypt(encrypted) + XCTAssertEqual(decrypted, plaintext, "decryption failed") + } + + func testAESEncryptOFB256() { + let key: Array = [0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4] + let iv: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + let plaintext: Array = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a] + let expected: Array = [0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b, 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60] + + let aes = try! AES(key: key, blockMode: OFB(iv: iv), padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + XCTAssertEqual(encrypted, expected, "encryption failed") + let decrypted = try! aes.decrypt(encrypted) + XCTAssertEqual(decrypted, plaintext, "decryption failed") + } + + func testAESEncryptPCBC256() { + let key: Array = [0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4] + let iv: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + let plaintext: Array = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a] + let expected: Array = [0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6] + + let aes = try! AES(key: key, blockMode: PCBC(iv: iv), padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + print(encrypted.toHexString()) + XCTAssertEqual(encrypted, expected, "encryption failed") + let decrypted = try! aes.decrypt(encrypted) + XCTAssertEqual(decrypted, plaintext, "decryption failed") + } + + func testAESEncryptCTR() { + let key: Array = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let iv: Array = [0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff] + let plaintext: Array = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a] + let expected: Array = [0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce] + + let aes = try! AES(key: key, blockMode: CTR(iv: iv), padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + XCTAssertEqual(encrypted.count, plaintext.count) + XCTAssertEqual(encrypted, expected, "encryption failed") + let decrypted = try! aes.decrypt(encrypted) + XCTAssertEqual(decrypted.count, plaintext.count) + XCTAssertEqual(decrypted, plaintext, "decryption failed") + } + + // https://github.com/krzyzanowskim/CryptoSwift/issues/424 + func testAESEncryptCTRZeroPadding() { + let key: Array = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let iv: Array = [0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff] + let plaintext: Array = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0x01] + let expected: Array = [0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce, 0x37, 0x2b, 0x7c, 0x3c, 0x67, 0x73, 0x51, 0x63, 0x18, 0xa0, 0x77, 0xd7, 0xfc, 0x50, 0x73, 0xae] + + let aes = try! AES(key: key, blockMode: CTR(iv: iv), padding: .zeroPadding) + let encrypted = try! aes.encrypt(plaintext) + + XCTAssertEqual(plaintext.count, 17) + XCTAssertEqual(encrypted.count, 32, "padding failed") + XCTAssertEqual(encrypted, expected, "encryption failed") + } + + func testAESEncryptCTRIrregularLength() { + let key: Array = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let iv: Array = [0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff] + let plaintext: Array = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0x01] + let expected: Array = [0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce, 0x37] + + let aes = try! AES(key: key, blockMode: CTR(iv: iv), padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + XCTAssertEqual(encrypted, expected, "encryption failed") + let decrypted = try! aes.decrypt(encrypted) + XCTAssertEqual(decrypted, plaintext, "decryption failed") + } + + // https://github.com/krzyzanowskim/CryptoSwift/pull/290 + func testAESDecryptCTRSeek() { + let key: Array = [0x52, 0x72, 0xb5, 0x9c, 0xab, 0x07, 0xc5, 0x01, 0x11, 0x7a, 0x39, 0xb6, 0x10, 0x35, 0x87, 0x02] + let iv: Array = [0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01] + var plaintext: Array = Array(repeating: 0, count: 6000) + + for i in 0.. = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let iv: Array = [0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff] + let plaintext: Array = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0x01, 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0x01] + let expected: Array = [0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, 0x1b, 0xef, 0x68, 0x64, 0x99, 0xd, 0xb6, 0xce, 0x37, 0x40, 0xbd, 0x82, 0x85, 0x5d, 0x11, 0xfc, 0x8e, 0x49, 0x4a, 0xa9, 0xed, 0x23, 0xe0, 0xb9, 0x40, 0x2d] + + let aes = try! AES(key: key, blockMode: CTR(iv: iv), padding: .noPadding) + var encryptor = try! aes.makeEncryptor() + var encrypted = Array() + encrypted += try! encryptor.update(withBytes: plaintext[0..<5]) + encrypted += try! encryptor.update(withBytes: plaintext[5..<15]) + encrypted += try! encryptor.update(withBytes: plaintext[15...]) + encrypted += try! encryptor.finish() + XCTAssertEqual(encrypted, expected, "encryption failed") + + var decryptor = try! aes.makeDecryptor() + var decrypted = Array() + decrypted += try! decryptor.update(withBytes: expected[0..<5]) + decrypted += try! decryptor.update(withBytes: expected[5..<15]) + decrypted += try! decryptor.update(withBytes: expected[15...]) + decrypted += try! decryptor.finish() + XCTAssertEqual(decrypted, plaintext, "decryption failed") + } + + + func testAESEncryptCTRStream() { + let key = Array(hex: "0xbe3e9020816eb838782e2d9f4a2f40d4") + let iv = Array(hex: "0x0000000000000000a9bbd681ded0c0c8") + + do { + let aes = try AES(key: key, blockMode: CTR(iv: iv), padding: .noPadding) + var encryptor = try aes.makeEncryptor() + + let encrypted1 = try encryptor.update(withBytes: [0x00, 0x01, 0x02, 0x03] as [UInt8]) + XCTAssertEqual(encrypted1, Array(hex: "d79d0344")) + let encrypted2 = try encryptor.update(withBytes: [0x04, 0x05, 0x06, 0x07] as [UInt8]) + XCTAssertEqual(encrypted2, Array(hex: "b2a08879")) + let encrypted3 = try encryptor.update(withBytes: [0x08] as [UInt8]) + XCTAssertEqual(encrypted3, Array(hex: "db")) + } catch { + XCTFail(error.localizedDescription) + } + } + + func testAESWithWrongKey() { + let key: Array = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let key2: Array = [0x22, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x33] + let iv: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + let plaintext: Array = [49, 46, 50, 50, 50, 51, 51, 51, 51] + + let aes = try! AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) + let aes2 = try! AES(key: key2, blockMode: CBC(iv: iv), padding: .pkcs7) + let encrypted = try! aes.encrypt(plaintext) + let decrypted = try? aes2.decrypt(encrypted) + XCTAssertTrue(decrypted! != plaintext, "failed") + } + + // https://github.com/krzyzanowskim/CryptoSwift/issues/298 + func testIssue298() { + let encryptedValue = "47595cfa90f7b0b0e0d9d7240a2e035f7f4acde27d7ca778a7d8b05add32a0a92d945c0a59f7f0e029d7f2fbb258b2f0" + let expected: Array = [55, 52, 98, 54, 53, 51, 101, 51, 54, 52, 51, 48, 100, 55, 97, 57, 99, 100, 57, 49, 97, 50, 52, 100, 57, 57, 52, 52, 98, 48, 51, 50, 79, 114, 70, 101, 99, 107, 114, 87, 111, 0, 0, 0, 0, 0, 0, 0] + let key = "0123456789abcdef" + let iv = "fedcba9876543210" + + do { + let aes = try AES(key: key, iv: iv, padding: .noPadding) + let ciphertext = try aes.decrypt(Array(hex: encryptedValue)) + XCTAssertEqual(ciphertext, expected) + } catch { + XCTFail("failed") + } + } + + // https://github.com/krzyzanowskim/CryptoSwift/issues/394 + func testIssue394() { + let plaintext = "Nullam quis risus eget urna mollis ornare vel eu leo.".bytes + let key = "passwordpassword".bytes.md5() // -md md5 + let iv = "drowssapdrowssap".bytes // -iv 64726f777373617064726f7773736170 + let aes = try! AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) // -aes-128-cbc + let ciphertext = try! aes.encrypt(plaintext) // enc + + // $ echo -n "Nullam quis risus eget urna mollis ornare vel eu leo." | openssl enc -aes-128-cbc -md md5 -nosalt -iv 64726f777373617064726f7773736170 -pass pass:passwordpassword -base64 + // cij+965z2Xqoj9tIHgtA72ZPfv5sxnt76vwkIt1CodYY313oa7mr0pSc5o++g0CX + // YczxK2fGIa84xtwDtRMwBQ== + XCTAssertEqual(ciphertext.toBase64(), "cij+965z2Xqoj9tIHgtA72ZPfv5sxnt76vwkIt1CodYY313oa7mr0pSc5o++g0CXYczxK2fGIa84xtwDtRMwBQ==") + } + + // https://github.com/krzyzanowskim/CryptoSwift/issues/411 + func testIssue411() { + let ciphertext: Array = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f] // test + let key = "passwordpassword".bytes.md5() // -md md5 + let iv = "drowssapdrowssap".bytes // -iv 64726f777373617064726f7773736170 + let aes = try! AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) // -aes-128-cbc + let plaintext = try! ciphertext.decrypt(cipher: aes) + XCTAssertEqual("74657374", plaintext.toHexString()) + } +} + +// MARK: - GCM +extension AESTests { + func testAESGCMTestCase1() { + // Test Case 1 + let key = Array(hex: "0x00000000000000000000000000000000") + let iv = Array(hex: "0x000000000000000000000000") + + let gcm = GCM(iv: iv, mode: .detached) + let aes = try! AES(key: key, blockMode: gcm, padding: .noPadding) + let encrypted = try! aes.encrypt([UInt8]()) + XCTAssertEqual(Array(encrypted), [UInt8](hex: "")) // C + XCTAssertEqual(gcm.authenticationTag, [UInt8](hex: "58e2fccefa7e3061367f1d57a4e7455a")) // T (128-bit) + } + + func testAESGCMTestCase2() { + // Test Case 2 + let key = Array(hex: "0x00000000000000000000000000000000") + let plaintext = Array(hex: "0x00000000000000000000000000000000") + let iv = Array(hex: "0x000000000000000000000000") + + let gcm = GCM(iv: iv, mode: .detached) + let aes = try! AES(key: key, blockMode: gcm, padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + XCTAssertEqual(Array(encrypted), [UInt8](hex: "0388dace60b6a392f328c2b971b2fe78")) // C + XCTAssertEqual(gcm.authenticationTag, [UInt8](hex: "ab6e47d42cec13bdf53a67b21257bddf")) // T (128-bit) + } + + func testAESGCMTestCase3() { + // Test Case 3 + let key = Array(hex: "0xfeffe9928665731c6d6a8f9467308308") + let plaintext = Array(hex: "0xd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255") + let iv = Array(hex: "0xcafebabefacedbaddecaf888") + + let encGCM = GCM(iv: iv, mode: .detached) + let aes = try! AES(key: key, blockMode: encGCM, padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + + XCTAssertNotNil(encGCM.authenticationTag) + XCTAssertEqual(Array(encrypted), [UInt8](hex: "0x42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985")) // C + XCTAssertEqual(encGCM.authenticationTag, [UInt8](hex: "0x4d5c2af327cd64a62cf35abd2ba6fab4")) // T (128-bit) + + // decrypt + func decrypt(_ encrypted: Array, tag: Array) -> Array { + let decGCM = GCM(iv: iv, authenticationTag: tag, mode: .detached) + let aes = try! AES(key: key, blockMode: decGCM, padding: .noPadding) + return try! aes.decrypt(encrypted) + } + + let decrypted = decrypt(encrypted, tag: encGCM.authenticationTag!) + XCTAssertEqual(decrypted, plaintext) + } + + func testAESGCMTestCase3Combined() { + // Test Case 3 + let key = Array(hex: "0xfeffe9928665731c6d6a8f9467308308") + let plaintext = Array(hex: "0xd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255") + let iv = Array(hex: "0xcafebabefacedbaddecaf888") + + let encGCM = GCM(iv: iv, mode: .combined) + let aes = try! AES(key: key, blockMode: encGCM, padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + + XCTAssertNotNil(encGCM.authenticationTag) + XCTAssertEqual(Array(encrypted), [UInt8](hex: "0x42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62cf35abd2ba6fab4")) // C + XCTAssertEqual(encGCM.authenticationTag, [UInt8](hex: "0x4d5c2af327cd64a62cf35abd2ba6fab4")) // T (128-bit) + + // decrypt + func decrypt(_ encrypted: Array) -> Array { + let decGCM = GCM(iv: iv, mode: .combined) + let aes = try! AES(key: key, blockMode: decGCM, padding: .noPadding) + return try! aes.decrypt(encrypted) + } + + let decrypted = decrypt(encrypted) + XCTAssertEqual(decrypted, plaintext) + } + + func testAESGCMTestCase4() { + // Test Case 4 + let key = Array(hex: "0xfeffe9928665731c6d6a8f9467308308") + let plaintext = Array(hex: "0xd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39") + let iv = Array(hex: "0xcafebabefacedbaddecaf888") + let auth = Array(hex: "0xfeedfacedeadbeeffeedfacedeadbeefabaddad2") + + let gcm = GCM(iv: iv, additionalAuthenticatedData: auth, mode: .detached) + let aes = try! AES(key: key, blockMode: gcm, padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + + XCTAssertEqual(Array(encrypted), [UInt8](hex: "0x42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091")) // C + XCTAssertEqual(gcm.authenticationTag, [UInt8](hex: "0x5bc94fbc3221a5db94fae95ae7121a47")) // T (128-bit) + } + + func testAESGCMTestCase5() { + // Test Case 5 + let key = Array(hex: "0xfeffe9928665731c6d6a8f9467308308") + let plaintext = Array(hex: "0xd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39") + let iv = Array(hex: "0xcafebabefacedbad") + let auth = Array(hex: "0xfeedfacedeadbeeffeedfacedeadbeefabaddad2") + + let gcm = GCM(iv: iv, additionalAuthenticatedData: auth, mode: .detached) + let aes = try! AES(key: key, blockMode: gcm, padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + + XCTAssertEqual(Array(encrypted), [UInt8](hex: "0x61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598")) // C + XCTAssertEqual(gcm.authenticationTag, [UInt8](hex: "0x3612d2e79e3b0785561be14aaca2fccb")) // T (128-bit) + } + + func testAESGCMTestCase6() { + // Test Case 6 + let key = Array(hex: "0xfeffe9928665731c6d6a8f9467308308") + let plaintext = Array(hex: "0xd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39") + let iv = Array(hex: "0x9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b") + let auth = Array(hex: "0xfeedfacedeadbeeffeedfacedeadbeefabaddad2") + + let gcm = GCM(iv: iv, additionalAuthenticatedData: auth, mode: .detached) + let aes = try! AES(key: key, blockMode: gcm, padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + + XCTAssertEqual(Array(encrypted), [UInt8](hex: "0x8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5")) // C + XCTAssertEqual(gcm.authenticationTag, [UInt8](hex: "0x619cc5aefffe0bfa462af43c1699d050")) // T (128-bit) + } + + func testAESGCMTestCase7() { + // Test Case 7 + let key = Array(hex: "0x000000000000000000000000000000000000000000000000") + let plaintext = Array(hex: "") + let iv = Array(hex: "0x000000000000000000000000") + + let gcm = GCM(iv: iv, mode: .detached) + let aes = try! AES(key: key, blockMode: gcm, padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + + XCTAssertEqual(Array(encrypted), [UInt8](hex: "")) // C + XCTAssertEqual(gcm.authenticationTag, [UInt8](hex: "0xcd33b28ac773f74ba00ed1f312572435")) // T (128-bit) + } + + func testAESGCMTagLengthDetached() { + // Test Case 2 + let key = Array(hex: "0x00000000000000000000000000000000") + let plaintext = Array(hex: "0x00000000000000000000000000000000") + let iv = Array(hex: "0x000000000000000000000000") + + let gcm = GCM(iv: iv, tagLength: 12, mode: .detached) + let aes = try! AES(key: key, blockMode: gcm, padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + XCTAssertEqual(Array(encrypted), [UInt8](hex: "0388dace60b6a392f328c2b971b2fe78")) // C + XCTAssertEqual(gcm.authenticationTag, [UInt8](hex: "ab6e47d42cec13bdf53a67b2")) // T (96-bit) + + // decrypt + func decrypt(_ encrypted: Array) -> Array { + let decGCM = GCM(iv: iv, authenticationTag: gcm.authenticationTag!, mode: .detached) + let aes = try! AES(key: key, blockMode: decGCM, padding: .noPadding) + return try! aes.decrypt(encrypted) + } + + let decrypted = decrypt(encrypted) + XCTAssertEqual(decrypted, plaintext) + } + + func testAESGCMTagLengthCombined() { + // Test Case 2 + let key = Array(hex: "0x00000000000000000000000000000000") + let plaintext = Array(hex: "0x00000000000000000000000000000000") + let iv = Array(hex: "0x000000000000000000000000") + + let gcm = GCM(iv: iv, tagLength: 12, mode: .combined) + let aes = try! AES(key: key, blockMode: gcm, padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + XCTAssertEqual(Array(encrypted), [UInt8](hex: "0388dace60b6a392f328c2b971b2fe78ab6e47d42cec13bdf53a67b2")) // C + XCTAssertEqual(gcm.authenticationTag, [UInt8](hex: "ab6e47d42cec13bdf53a67b2")) // T (96-bit) + + // decrypt + func decrypt(_ encrypted: Array) -> Array { + let decGCM = GCM(iv: iv, authenticationTag: gcm.authenticationTag!, mode: .combined) + let aes = try! AES(key: key, blockMode: decGCM, padding: .noPadding) + return try! aes.decrypt(encrypted) + } + + let decrypted = decrypt(encrypted) + XCTAssertEqual(decrypted, plaintext) + } + + func testAESGCMTagLengthCombined2() { + let key = Array(hex: "0x00000000000000000000000000000000") + let plaintext = Array(hex: "0x0000000000000000000000000000000000000000") + let iv = Array(hex: "0x000000000000") + + let gcm = GCM(iv: iv, tagLength: 12, mode: .combined) + let aes = try! AES(key: key, blockMode: gcm, padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + + // decrypt + func decrypt(_ encrypted: Array) -> Array { + let decGCM = GCM(iv: iv, authenticationTag: gcm.authenticationTag!, mode: .combined) + let aes = try! AES(key: key, blockMode: decGCM, padding: .noPadding) + return try! aes.decrypt(encrypted) + } + + let decrypted = decrypt(encrypted) + XCTAssertEqual(decrypted, plaintext) + } + + func testAESGCMTestCaseIrregularCombined1() { + // echo -n "0123456789010123456789012345" | openssl enc -aes-128-gcm -K feffe9928665731c6d6a8f9467308308 -iv cafebabefacedbaddecaf888 -nopad -nosalt + // openssl note: The enc program does not support authenticated encryption modes like CCM and GCM. The utility does not store or retrieve the authentication tag + let key = Array(hex: "0xfeffe9928665731c6d6a8f9467308308") + let plaintext = "0123456789010123456789012345".bytes + let iv = Array(hex: "0xcafebabefacedbaddecaf888") + + let encGCM = GCM(iv: iv, mode: .combined) + let aes = try! AES(key: key, blockMode: encGCM, padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + + XCTAssertNotNil(encGCM.authenticationTag) + XCTAssertEqual(Array(encrypted), [UInt8](hex: "0xab831ed4edc644f6d61218431b14c0355138be4b010f630b29be7a2b9793b9fbecc7b44cc86dfd697a50c1c6")) // C + XCTAssertEqual(encGCM.authenticationTag, [UInt8](hex: "0x9793b9fbecc7b44cc86dfd697a50c1c6")) // T (128-bit) + + // decrypt + func decrypt(_ encrypted: Array) -> Array { + let decGCM = GCM(iv: iv, mode: .combined) + let aes = try! AES(key: key, blockMode: decGCM, padding: .noPadding) + return try! aes.decrypt(encrypted) + } + + let decrypted = decrypt(encrypted) + XCTAssertEqual(decrypted, plaintext) + } + + func testAESGCMTestCaseIrregularCombined2() { + // echo -n "0123456789010123456789012345012345678901012345678901234567" | openssl enc -aes-128-gcm -K feffe9928665731c6d6a8f9467308308 -iv cafebabefacedbaddecaf888 -nopad -nosalt + // openssl note: The enc program does not support authenticated encryption modes like CCM and GCM. The utility does not store or retrieve the authentication tag + let key = Array(hex: "0xfeffe9928665731c6d6a8f9467308308") + let plaintext = "0123456789010123456789012345012345678901012345678901234567".bytes + let iv = Array(hex: "0xcafebabefacedbaddecaf888") + + let encGCM = GCM(iv: iv, mode: .combined) + let aes = try! AES(key: key, blockMode: encGCM, padding: .noPadding) + let encrypted = try! aes.encrypt(plaintext) + + XCTAssertNotNil(encGCM.authenticationTag) + XCTAssertEqual(Array(encrypted), [UInt8](hex: "0xab831ed4edc644f6d61218431b14c0355138be4b010f630b29be7a2b93ac196f09dc2e10f937aa7e6271564dd117291792f0d6fdf2347ef5b10c86a7f414f0c91a8e59fd2405b850527e")) // C + XCTAssertEqual(encGCM.authenticationTag, [UInt8](hex: "0x86a7f414f0c91a8e59fd2405b850527e")) // T (128-bit) + + // decrypt + func decrypt(_ encrypted: Array) -> Array { + let decGCM = GCM(iv: iv, mode: .combined) + let aes = try! AES(key: key, blockMode: decGCM, padding: .noPadding) + return try! aes.decrypt(encrypted) + } + + let decrypted = decrypt(encrypted) + XCTAssertEqual(decrypted, plaintext) + } +} + +extension AESTests { + static func allTests() -> [(String, (AESTests) -> () -> Void)] { + let tests = [ + ("testAESEncrypt", testAESEncrypt), + ("testAESEncrypt2", testAESEncrypt2), + ("testAESEncrypt3", testAESEncrypt3), + ("testAESEncryptCBCNoPadding", testAESEncryptCBCNoPadding), + ("testAESEncryptCBCWithPadding", testAESEncryptCBCWithPadding), + ("testAESEncryptCBCWithPaddingPartial", testAESEncryptCBCWithPaddingPartial), + ("testAESEncryptIncremental", testAESEncryptIncremental), + ("testAESDecryptCBCWithPaddingPartial", testAESDecryptCBCWithPaddingPartial), + ("testAESEncryptCFB", testAESEncryptCFB), + ("testAESEncryptCFBLong", testAESEncryptCFBLong), + ("testAESEncryptOFB128", testAESEncryptOFB128), + ("testAESEncryptOFB256", testAESEncryptOFB256), + ("testAESEncryptPCBC256", testAESEncryptPCBC256), + ("testAESEncryptCTR", testAESEncryptCTR), + ("testAESEncryptCTRZeroPadding", testAESEncryptCTRZeroPadding), + ("testAESEncryptCTRIrregularLength", testAESEncryptCTRIrregularLength), + ("testAESDecryptCTRSeek", testAESDecryptCTRSeek), + ("testAESEncryptCTRIrregularLengthIncrementalUpdate", testAESEncryptCTRIrregularLengthIncrementalUpdate), + ("testAESEncryptCTRStream", testAESEncryptCTRStream), + ("testIssue298", testIssue298), + ("testIssue394", testIssue394), + ("testIssue411", testIssue411), + ("testAESWithWrongKey", testAESWithWrongKey), + ("testAESGCMTestCase1", testAESGCMTestCase1), + ("testAESGCMTestCase2", testAESGCMTestCase2), + ("testAESGCMTestCase3", testAESGCMTestCase3), + ("testAESGCMTestCase3Combined", testAESGCMTestCase3Combined), + ("testAESGCMTestCase4", testAESGCMTestCase4), + ("testAESGCMTestCase5", testAESGCMTestCase5), + ("testAESGCMTestCase6", testAESGCMTestCase6), + ("testAESGCMTestCase7", testAESGCMTestCase7), + ("testAESGCMTestTagLengthDetached", testAESGCMTagLengthDetached), + ("testAESGCMTestTagLengthCombined", testAESGCMTagLengthCombined), + ("testAESGCMTestCaseIrregularCombined1", testAESGCMTestCaseIrregularCombined1), + ("testAESGCMTestCaseIrregularCombined2", testAESGCMTestCaseIrregularCombined2) + ] + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/AESTestsPerf.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/AESTestsPerf.swift new file mode 100644 index 0000000000..9917efcc82 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/AESTestsPerf.swift @@ -0,0 +1,50 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import Foundation +import XCTest + +final class AESTestsPerf: XCTestCase { + func testAESEncryptPerformance() { + let key: Array = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let iv: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + let message = Array(repeating: 7, count: 1024 * 1024) + let aes = try! AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) + measure { + _ = try! aes.encrypt(message) + } + } + + func testAESDecryptPerformance() { + let key: Array = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let iv: Array = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] + let message = Array(repeating: 7, count: 1024 * 1024) + let aes = try! AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) + measure { + _ = try! aes.decrypt(message) + } + } +} + +extension AESTestsPerf { + static func allTests() -> [(String, (AESTestsPerf) -> () -> Void)] { + let tests = [ + ("testAESEncryptPerformance", testAESEncryptPerformance), + ("testAESDecryptPerformance", testAESDecryptPerformance), + ] + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/Access.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/Access.swift new file mode 100644 index 0000000000..8739e28d6f --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/Access.swift @@ -0,0 +1,294 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// import without @testable to test public API +import CryptoSwift +import Foundation +import XCTest + +class Access: XCTestCase { + let cipher = try! AES(key: "secret0key000000", iv: "0123456789012345") + let authenticator = HMAC(key: Array(hex: "b1b2b3b3b3b3b3b3b1b2b3b3b3b3b3b3"), variant: .sha1) + + func testChecksum() { + _ = Checksum.crc32([1, 2, 3]) + _ = Checksum.crc32c([1, 2, 3]) + _ = Checksum.crc16([1, 2, 3]) + } + + func testRandomIV() { + _ = AES.randomIV(AES.blockSize) + _ = ChaCha20.randomIV(ChaCha20.blockSize) + } + + func testDigest() { + _ = Digest.md5([1, 2, 3]) + _ = Digest.sha1([1, 2, 3]) + _ = Digest.sha224([1, 2, 3]) + _ = Digest.sha256([1, 2, 3]) + _ = Digest.sha384([1, 2, 3]) + _ = Digest.sha512([1, 2, 3]) + _ = Digest.sha3([1, 2, 3], variant: .sha224) + + _ = SHA1().calculate(for: [0]) + _ = SHA2(variant: .sha224).calculate(for: [0]) + _ = SHA3(variant: .sha256).calculate(for: [0]) + + _ = MD5().calculate(for: [0]) + } + + func testArrayExtension() { + let array = Array(hex: "b1b2b3b3b3b3b3b3b1b2b3b3b3b3b3b3") + _ = array.toHexString() + + _ = array.md5() + _ = array.sha1() + _ = array.sha256() + _ = array.sha384() + _ = array.sha512() + _ = array.sha2(.sha224) + _ = array.sha3(.sha224) + _ = array.crc32() + _ = array.crc32c() + _ = array.crc16() + + do { + _ = try array.encrypt(cipher: cipher) + _ = try array.decrypt(cipher: cipher) + _ = try array.authenticate(with: authenticator) + } catch { + XCTFail(error.localizedDescription) + } + } + + func testCollectionExtension() { + // nothing public + } + + func testStringExtension() { + let string = "foofoobarbar" + _ = string.md5() + _ = string.sha1() + _ = string.sha224() + _ = string.sha256() + _ = string.sha384() + _ = string.sha512() + _ = string.sha3(.sha224) + _ = string.crc16() + _ = string.crc32() + _ = string.crc32c() + + do { + _ = try string.encrypt(cipher: cipher) + _ = try string.authenticate(with: authenticator) + } catch { + XCTFail(error.localizedDescription) + } + } + + func testStringFoundationExtension() { + let string = "aPf/i9th9iX+vf49eR7PYk2q7S5xmm3jkRLejgzHNJs=" + do { + _ = try string.decryptBase64ToString(cipher: cipher) + _ = try string.decryptBase64(cipher: cipher) + } catch { + XCTFail(error.localizedDescription) + } + } + + func testIntExtension() { + // nothing public + } + + func testUInt16Extension() { + // nothing public + } + + func testUInt32Extension() { + // nothing public + } + + func testUInt64Extension() { + // nothing public + } + + func testUInt8Extension() { + // nothing public + } + + func testDataExtension() { + let data = Data( [1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8]) + _ = data.checksum() + _ = data.md5() + _ = data.sha1() + _ = data.sha224() + _ = data.sha256() + _ = data.sha384() + _ = data.sha512() + _ = data.sha3(.sha224) + _ = data.crc16() + _ = data.crc32() + _ = data.crc32c() + + _ = data.bytes + _ = data.toHexString() + + do { + _ = try data.encrypt(cipher: cipher) + _ = try data.decrypt(cipher: cipher) + _ = try data.authenticate(with: authenticator) + } catch { + XCTFail(error.localizedDescription) + } + } + + func testPadding() { + // PKCS7 + _ = Padding.pkcs7.add(to: [1, 2, 3], blockSize: 16) + _ = Padding.pkcs7.remove(from: [1, 2, 3], blockSize: 16) + + // PKCS5 + _ = Padding.pkcs5.add(to: [1, 2, 3], blockSize: 16) + _ = Padding.pkcs5.remove(from: [1, 2, 3], blockSize: 16) + + // NoPadding + _ = Padding.noPadding.add(to: [1, 2, 3], blockSize: 16) + _ = Padding.noPadding.remove(from: [1, 2, 3], blockSize: 16) + + // ZeroPadding + _ = Padding.zeroPadding.add(to: [1, 2, 3], blockSize: 16) + _ = Padding.zeroPadding.remove(from: [1, 2, 3], blockSize: 16) + } + + func testPBKDF() { + do { + _ = PKCS5.PBKDF1.Variant.md5 + _ = try PKCS5.PBKDF1(password: [1, 2, 3, 4, 5, 6, 7], salt: [1, 2, 3, 4, 5, 6, 7, 8]).calculate() + _ = try PKCS5.PBKDF2(password: [1, 2, 3, 4, 5, 6, 7], salt: [1, 2, 3, 4]).calculate() + } catch { + XCTFail(error.localizedDescription) + } + } + + func testAuthenticators() { + do { + _ = try HMAC(key: Array(hex: "b1b2b3b3b3b3b3b3b1b2b3b3b3b3b3b3"), variant: .sha1).authenticate([1, 2, 3]) + _ = try Poly1305(key: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2]).authenticate([1, 2, 3]) + } catch { + XCTFail(error.localizedDescription) + } + } + + func testAES() { + do { + let cipher = try AES(key: "secret0key000000", iv: "0123456789012345") + var encryptor = try cipher.makeEncryptor() + _ = try encryptor.update(withBytes: [1, 2, 3]) + _ = try encryptor.finish() + + var decryptor = try cipher.makeDecryptor() + _ = try decryptor.update(withBytes: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) + _ = try decryptor.finish() + + let enc = try cipher.encrypt([1, 2, 3]) + _ = try cipher.decrypt(enc) + + _ = try AES(key: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6], blockMode: CBC(iv: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6]), padding: .noPadding) + + _ = AES.Variant.aes128 + _ = AES.blockSize + } catch { + XCTFail("\(error)") + } + } + + func testBlowfish() { + do { + let cipher = try Blowfish(key: "secret0key000000", iv: "01234567") + let enc = try cipher.encrypt([1, 2, 3]) + _ = try cipher.decrypt(enc) + + _ = try Blowfish(key: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6], padding: .noPadding) + + _ = Blowfish.blockSize + } catch { + XCTFail(error.localizedDescription) + } + } + + func testRabbit() { + do { + let rabbit = try Rabbit(key: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) + let enc = try rabbit.encrypt([1, 2, 3]) + _ = try rabbit.decrypt(enc) + + XCTAssertThrowsError(try Rabbit(key: "123")) + + _ = Rabbit.blockSize + _ = Rabbit.keySize + _ = Rabbit.ivSize + } catch { + XCTFail(error.localizedDescription) + } + } + + func testChaCha20() { + let key: Array = [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] + let iv: Array = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + + do { + _ = ChaCha20.blockSize + let chacha20 = try ChaCha20(key: key, iv: iv) + let enc = try chacha20.encrypt([1, 3, 4]) + _ = try chacha20.decrypt(enc) + + XCTAssertThrowsError(try ChaCha20(key: "123", iv: "12345678")) + + _ = chacha20.makeEncryptor() + _ = chacha20.makeDecryptor() + + } catch { + XCTFail(error.localizedDescription) + } + } + + func testUpdatable() { + // TODO: + } + + static let allTests = [ + ("testChecksum", testChecksum), + ("testDigest", testDigest), + ("testArrayExtension", testArrayExtension), + ("testCollectionExtension", testCollectionExtension), + ("testStringExtension", testStringExtension), + ("testStringFoundationExtension", testStringFoundationExtension), + ("testIntExtension", testIntExtension), + ("testUInt16Extension", testUInt16Extension), + ("testUInt32Extension", testUInt32Extension), + ("testUInt64Extension", testUInt64Extension), + ("testUInt8Extension", testUInt8Extension), + ("testDataExtension", testDataExtension), + ("testPadding", testPadding), + ("testPBKDF", testPBKDF), + ("testAuthenticators", testAuthenticators), + ("testAES", testAES), + ("testBlowfish", testBlowfish), + ("testRabbit", testRabbit), + ("testChaCha20", testChaCha20), + ("testUpdatable", testUpdatable), + ("testRandomIV", testRandomIV), + ] +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/BlowfishTests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/BlowfishTests.swift new file mode 100644 index 0000000000..88b39575c7 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/BlowfishTests.swift @@ -0,0 +1,223 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 vector from http://www.schneier.com/code/vectors.txt + +@testable import CryptoSwift +import XCTest + +class BlowfishTests: XCTestCase { + struct TestData { + let key: Array + let input: Array + let output: Array + } + + let tests = [ + TestData(key: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + input: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + output: [0x4e, 0xf9, 0x97, 0x45, 0x61, 0x98, 0xdd, 0x78]), + TestData(key: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], + input: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], + output: [0x51, 0x86, 0x6f, 0xd5, 0xb8, 0x5e, 0xcb, 0x8a]), + TestData(key: [0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + input: [0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01], + output: [0x7d, 0x85, 0x6f, 0x9a, 0x61, 0x30, 0x63, 0xf2]), + TestData(key: [0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11], + input: [0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11], + output: [0x24, 0x66, 0xdd, 0x87, 0x8b, 0x96, 0x3c, 0x9d]), + + TestData(key: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], + input: [0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11], + output: [0x61, 0xf9, 0xc3, 0x80, 0x22, 0x81, 0xb0, 0x96]), + + TestData(key: [0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11], + input: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], + output: [0x7d, 0x0c, 0xc6, 0x30, 0xaf, 0xda, 0x1e, 0xc7]), + + TestData(key: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + input: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + output: [0x4e, 0xf9, 0x97, 0x45, 0x61, 0x98, 0xdd, 0x78]), + + TestData(key: [0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10], + input: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], + output: [0x0a, 0xce, 0xab, 0x0f, 0xc6, 0xa0, 0xa2, 0x8d]), + + TestData(key: [0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57], + input: [0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42], + output: [0x59, 0xc6, 0x82, 0x45, 0xeb, 0x05, 0x28, 0x2b]), + + TestData(key: [0x01, 0x31, 0xd9, 0x61, 0x9d, 0xc1, 0x37, 0x6e], + input: [0x5c, 0xd5, 0x4c, 0xa8, 0x3d, 0xef, 0x57, 0xda], + output: [0xb1, 0xb8, 0xcc, 0x0b, 0x25, 0x0f, 0x09, 0xa0]), + + TestData(key: [0x07, 0xa1, 0x13, 0x3e, 0x4a, 0x0b, 0x26, 0x86], + input: [0x02, 0x48, 0xd4, 0x38, 0x06, 0xf6, 0x71, 0x72], + output: [0x17, 0x30, 0xe5, 0x77, 0x8b, 0xea, 0x1d, 0xa4]), + + TestData(key: [0x38, 0x49, 0x67, 0x4c, 0x26, 0x02, 0x31, 0x9e], + input: [0x51, 0x45, 0x4b, 0x58, 0x2d, 0xdf, 0x44, 0x0a], + output: [0xa2, 0x5e, 0x78, 0x56, 0xcf, 0x26, 0x51, 0xeb]), + + TestData(key: [0x04, 0xb9, 0x15, 0xba, 0x43, 0xfe, 0xb5, 0xb6], + input: [0x42, 0xfd, 0x44, 0x30, 0x59, 0x57, 0x7f, 0xa2], + output: [0x35, 0x38, 0x82, 0xb1, 0x09, 0xce, 0x8f, 0x1a]), + + TestData(key: [0x01, 0x13, 0xb9, 0x70, 0xfd, 0x34, 0xf2, 0xce], + input: [0x05, 0x9b, 0x5e, 0x08, 0x51, 0xcf, 0x14, 0x3a], + output: [0x48, 0xf4, 0xd0, 0x88, 0x4c, 0x37, 0x99, 0x18]), + + TestData(key: [0x01, 0x70, 0xf1, 0x75, 0x46, 0x8f, 0xb5, 0xe6], + input: [0x07, 0x56, 0xd8, 0xe0, 0x77, 0x47, 0x61, 0xd2], + output: [0x43, 0x21, 0x93, 0xb7, 0x89, 0x51, 0xfc, 0x98]), + + TestData(key: [0x43, 0x29, 0x7f, 0xad, 0x38, 0xe3, 0x73, 0xfe], + input: [0x76, 0x25, 0x14, 0xb8, 0x29, 0xbf, 0x48, 0x6a], + output: [0x13, 0xf0, 0x41, 0x54, 0xd6, 0x9d, 0x1a, 0xe5]), + + TestData(key: [0x07, 0xa7, 0x13, 0x70, 0x45, 0xda, 0x2a, 0x16], + input: [0x3b, 0xdd, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02], + output: [0x2e, 0xed, 0xda, 0x93, 0xff, 0xd3, 0x9c, 0x79]), + + TestData(key: [0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f], + input: [0x26, 0x95, 0x5f, 0x68, 0x35, 0xaf, 0x60, 0x9a], + output: [0xd8, 0x87, 0xe0, 0x39, 0x3c, 0x2d, 0xa6, 0xe3]), + + TestData(key: [0x37, 0xd0, 0x6b, 0xb5, 0x16, 0xcb, 0x75, 0x46], + input: [0x16, 0x4d, 0x5e, 0x40, 0x4f, 0x27, 0x52, 0x32], + output: [0x5f, 0x99, 0xd0, 0x4f, 0x5b, 0x16, 0x39, 0x69]), + + TestData(key: [0x1f, 0x08, 0x26, 0x0d, 0x1a, 0xc2, 0x46, 0x5e], + input: [0x6b, 0x05, 0x6e, 0x18, 0x75, 0x9f, 0x5c, 0xca], + output: [0x4a, 0x05, 0x7a, 0x3b, 0x24, 0xd3, 0x97, 0x7b]), + + TestData(key: [0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76], + input: [0x00, 0x4b, 0xd6, 0xef, 0x09, 0x17, 0x60, 0x62], + output: [0x45, 0x20, 0x31, 0xc1, 0xe4, 0xfa, 0xda, 0x8e]), + + TestData(key: [0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xb0, 0x07], + input: [0x48, 0x0d, 0x39, 0x00, 0x6e, 0xe7, 0x62, 0xf2], + output: [0x75, 0x55, 0xae, 0x39, 0xf5, 0x9b, 0x87, 0xbd]), + + TestData(key: [0x49, 0x79, 0x3e, 0xbc, 0x79, 0xb3, 0x25, 0x8f], + input: [0x43, 0x75, 0x40, 0xc8, 0x69, 0x8f, 0x3c, 0xfa], + output: [0x53, 0xc5, 0x5f, 0x9c, 0xb4, 0x9f, 0xc0, 0x19]), + + TestData(key: [0x4f, 0xb0, 0x5e, 0x15, 0x15, 0xab, 0x73, 0xa7], + input: [0x07, 0x2d, 0x43, 0xa0, 0x77, 0x07, 0x52, 0x92], + output: [0x7a, 0x8e, 0x7b, 0xfa, 0x93, 0x7e, 0x89, 0xa3]), + + TestData(key: [0x49, 0xe9, 0x5d, 0x6d, 0x4c, 0xa2, 0x29, 0xbf], + input: [0x02, 0xfe, 0x55, 0x77, 0x81, 0x17, 0xf1, 0x2a], + output: [0xcf, 0x9c, 0x5d, 0x7a, 0x49, 0x86, 0xad, 0xb5]), + + TestData(key: [0x01, 0x83, 0x10, 0xdc, 0x40, 0x9b, 0x26, 0xd6], + input: [0x1d, 0x9d, 0x5c, 0x50, 0x18, 0xf7, 0x28, 0xc2], + output: [0xd1, 0xab, 0xb2, 0x90, 0x65, 0x8b, 0xc7, 0x78]), + + TestData(key: [0x1c, 0x58, 0x7f, 0x1c, 0x13, 0x92, 0x4f, 0xef], + input: [0x30, 0x55, 0x32, 0x28, 0x6d, 0x6f, 0x29, 0x5a], + output: [0x55, 0xcb, 0x37, 0x74, 0xd1, 0x3e, 0xf2, 0x01]), + + TestData(key: [0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01], + input: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], + output: [0xfa, 0x34, 0xec, 0x48, 0x47, 0xb2, 0x68, 0xb2]), + + TestData(key: [0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e], + input: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], + output: [0xa7, 0x90, 0x79, 0x51, 0x08, 0xea, 0x3c, 0xae]), + + TestData(key: [0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe], + input: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], + output: [0xc3, 0x9e, 0x07, 0x2d, 0x9f, 0xac, 0x63, 0x1d]), + + TestData(key: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + input: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], + output: [0x01, 0x49, 0x33, 0xe0, 0xcd, 0xaf, 0xf6, 0xe4]), + + TestData(key: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], + input: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + output: [0xf2, 0x1e, 0x9a, 0x77, 0xb7, 0x1c, 0x49, 0xbc]), + + TestData(key: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], + input: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + output: [0x24, 0x59, 0x46, 0x88, 0x57, 0x54, 0x36, 0x9a]), + + TestData(key: [0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10], + input: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], + output: [0x6b, 0x5c, 0x5a, 0x9c, 0x5d, 0x9e, 0x0a, 0x5a]), + ] + + func testEncrypt() { + for test in tests { + XCTAssertEqual(try Blowfish(key: test.key, blockMode: ECB(), padding: .noPadding).encrypt(test.input), test.output) + } + } + + func testDecrypt() { + for test in tests { + XCTAssertEqual(try Blowfish(key: test.key, blockMode: ECB(), padding: .noPadding).decrypt(test.output), test.input) + } + } + + func testCBCZeroPadding() { + let key = Array(hex: "0123456789ABCDEFF0E1D2C3B4A59687") + let iv = Array(hex: "FEDCBA9876543210") + let input = Array(hex: "37363534333231204E6F77206973207468652074696D6520666F722000") + XCTAssertEqual(try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .zeroPadding).encrypt(input), Array(hex: "6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC")) + } + + func testEncryptDecrypt() { + let key = Array.init(hex: "0123456789ABCDEFF0E1D2C3B4A59687") + let iv = Array.init(hex: "FEDCBA9876543210") + let input = Array.init(hex: "37363534333231204E6F77206973207468652074696D6520666F722000") + + do { + let cipher = try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) + let ciphertext = try cipher.encrypt(input) + let plaintext = try cipher.decrypt(ciphertext) + XCTAssertEqual(plaintext, input) + } catch { + XCTFail(error.localizedDescription) + } + } + + // https://github.com/krzyzanowskim/CryptoSwift/issues/415 + func testDecryptCFB415() { + do { + let plaintext = "secret12".bytes + let key = "passwordpassword".bytes + let iv = "12345678".bytes + let encrypted = try Blowfish(key: key, blockMode: CFB(iv: iv), padding: .noPadding).encrypt(plaintext) + let decrypted = try Blowfish(key: key, blockMode: CFB(iv: iv), padding: .noPadding).decrypt(encrypted) + XCTAssertEqual(plaintext, decrypted) + } catch { + XCTFail(error.localizedDescription) + } + } +} + +extension BlowfishTests { + static func allTests() -> [(String, (BlowfishTests) -> () -> Void)] { + let tests = [ + ("testEncrypt", testEncrypt), + ("testDecrypt", testDecrypt), + ("testCBCZeroPadding", testCBCZeroPadding), + ("testEncryptDecrypt", testEncryptDecrypt), + ("testDecryptCFB415", testDecryptCFB415), + ] + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/Bridging.h b/Carthage/Checkouts/CryptoSwift/Tests/Tests/Bridging.h new file mode 100644 index 0000000000..9ec068ec90 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/Bridging.h @@ -0,0 +1,21 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +#ifndef CryptoSwift_Bridging_h +#define CryptoSwift_Bridging_h + +#import + +#endif diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/CMACTests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/CMACTests.swift new file mode 100644 index 0000000000..667975ccdc --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/CMACTests.swift @@ -0,0 +1,64 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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 = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let msg: Array = [] + let expectedMac: Array = [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 = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let msg: Array = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a] + let expectedMac: Array = [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 = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let msg: Array = [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 = [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 = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] + let msg: Array = [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 = [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), + ] +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/ChaCha20Poly1305Tests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ChaCha20Poly1305Tests.swift new file mode 100644 index 0000000000..afb9849ba5 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ChaCha20Poly1305Tests.swift @@ -0,0 +1,84 @@ +// +// ChaCha20Poly1305Tests.swift +// CryptoSwiftTests +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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(hex: key) + let nonceArr = Array(hex: nonce) + let headerArr = Array(hex: header) + let messageArr = Array(hex: message) + let cipherArr = Array(hex: cipher) + let tagArr = Array(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)") + } + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/ChaCha20Tests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ChaCha20Tests.swift new file mode 100644 index 0000000000..c8d3b221f5 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ChaCha20Tests.swift @@ -0,0 +1,122 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import Foundation +import XCTest + +final class ChaCha20Tests: XCTestCase { + func testChaCha20() { + let keys: [Array] = [ + [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], + [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, 0x01], + [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], + [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], + [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 ivs: [Array] = [ + [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01], + [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], + ] + + let expectedHexes = [ + "76B8E0ADA0F13D90405D6AE55386BD28BDD219B8A08DED1AA836EFCC8B770DC7DA41597C5157488D7724E03FB8D84A376A43B8F41518A11CC387B669B2EE6586", + "4540F05A9F1FB296D7736E7B208E3C96EB4FE1834688D2604F450952ED432D41BBE2A0B6EA7566D2A5D1E7E20D42AF2C53D792B1C43FEA817E9AD275AE546963", + "DE9CBA7BF3D69EF5E786DC63973F653A0B49E015ADBFF7134FCB7DF137821031E85A050278A7084527214F73EFC7FA5B5277062EB7A0433E445F41E3", + "EF3FDFD6C61578FBF5CF35BD3DD33B8009631634D21E42AC33960BD138E50D32111E4CAF237EE53CA8AD6426194A88545DDC497A0B466E7D6BBDB0041B2F586B", + "F798A189F195E66982105FFB640BB7757F579DA31602FC93EC01AC56F85AC3C134A4547B733B46413042C9440049176905D3BE59EA1C53F15916155C2BE8241A38008B9A26BC35941E2444177C8ADE6689DE95264986D95889FB60E84629C9BD9A5ACB1CC118BE563EB9B3A4A472F82E09A7E778492B562EF7130E88DFE031C79DB9D4F7C7A899151B9A475032B63FC385245FE054E3DD5A97A5F576FE064025D3CE042C566AB2C507B138DB853E3D6959660996546CC9C4A6EAFDC777C040D70EAF46F76DAD3979E5C5360C3317166A1C894C94A371876A94DF7628FE4EAAF2CCB27D5AAAE0AD7AD0F9D4B6AD3B54098746D4524D38407A6DEB3AB78FAB78C9", + ] + + for idx in 0..(repeating: 0, count: (expectedHex.count / 2)) + + do { + let encrypted = try message.encrypt(cipher: ChaCha20(key: keys[idx], iv: ivs[idx])) + let decrypted = try encrypted.decrypt(cipher: ChaCha20(key: keys[idx], iv: ivs[idx])) + XCTAssertEqual(message, decrypted, "ChaCha20 decryption failed") + XCTAssertEqual(encrypted, Array(hex: expectedHex)) + } catch CipherError.encrypt { + XCTAssert(false, "Encryption failed") + } catch CipherError.decrypt { + XCTAssert(false, "Decryption failed") + } catch { + XCTAssert(false, "Failed") + } + } + } + + func testCore() { + let key: Array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] + var counter: Array = [1, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 74, 0, 0, 0, 0] + let input = Array.init(repeating: 0, count: 129) + let chacha = try! ChaCha20(key: key, iv: Array(key[4..<16])) + let result = chacha.process(bytes: input.slice, counter: &counter, key: key) + XCTAssertEqual(result.toHexString(), "10f1e7e4d13b5915500fdd1fa32071c4c7d1f4c733c068030422aa9ac3d46c4ed2826446079faa0914c2d705d98b02a2b5129cd1de164eb9cbd083e8a2503c4e0a88837739d7bf4ef8ccacb0ea2bb9d69d56c394aa351dfda5bf459f0a2e9fe8e721f89255f9c486bf21679c683d4f9c5cf2fa27865526005b06ca374c86af3bdc") + } + + func testVector1Py() { + let key: Array = [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] + let iv: Array = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + let expected: Array = [0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90, 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28, 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a, 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7, 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d, 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37, 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c, 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86] + let message = Array(repeating: 0, count: expected.count) + + do { + let encrypted = try ChaCha20(key: key, iv: iv).encrypt(message) + XCTAssertEqual(encrypted, expected, "Ciphertext failed") + } catch { + XCTFail() + } + } + + func testChaCha20EncryptPartial() { + let key: Array = [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 = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07] + let expectedHex = "F798A189F195E66982105FFB640BB7757F579DA31602FC93EC01AC56F85AC3C134A4547B733B46413042C9440049176905D3BE59EA1C53F15916155C2BE8241A38008B9A26BC35941E2444177C8ADE6689DE95264986D95889FB60E84629C9BD9A5ACB1CC118BE563EB9B3A4A472F82E09A7E778492B562EF7130E88DFE031C79DB9D4F7C7A899151B9A475032B63FC385245FE054E3DD5A97A5F576FE064025D3CE042C566AB2C507B138DB853E3D6959660996546CC9C4A6EAFDC777C040D70EAF46F76DAD3979E5C5360C3317166A1C894C94A371876A94DF7628FE4EAAF2CCB27D5AAAE0AD7AD0F9D4B6AD3B54098746D4524D38407A6DEB3AB78FAB78C9" + let plaintext: Array = Array(repeating: 0, count: (expectedHex.count / 2)) + + do { + let cipher = try ChaCha20(key: key, iv: iv) + + var ciphertext = Array() + var encryptor = cipher.makeEncryptor() + ciphertext += try encryptor.update(withBytes: Array(plaintext[0..<8])) + ciphertext += try encryptor.update(withBytes: Array(plaintext[8..<16])) + ciphertext += try encryptor.update(withBytes: Array(plaintext[16..<80])) + ciphertext += try encryptor.update(withBytes: Array(plaintext[80..<256])) + ciphertext += try encryptor.finish() + XCTAssertEqual(Array(hex: expectedHex), ciphertext) + } catch { + XCTFail() + } + } +} + +extension ChaCha20Tests { + static func allTests() -> [(String, (ChaCha20Tests) -> () -> Void)] { + let tests = [ + ("testChaCha20", testChaCha20), + ("testCore", testCore), + ("testVector1Py", testVector1Py), + ("testChaCha20EncryptPartial", testChaCha20EncryptPartial), + ] + + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/ChaCha20TestsPerf.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ChaCha20TestsPerf.swift new file mode 100644 index 0000000000..3e253fd6a3 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ChaCha20TestsPerf.swift @@ -0,0 +1,41 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import Foundation +import XCTest + +final class ChaCha20TestsPerf: XCTestCase { + func testChaCha20Performance() { + let key: Array = [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 = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07] + let message = Array(repeating: 7, count: 1024 * 1024) + measureMetrics([XCTPerformanceMetric.wallClockTime], automaticallyStartMeasuring: true) { () -> Void in + do { + _ = try ChaCha20(key: key, iv: iv).encrypt(message) + } catch { + XCTFail() + } + self.stopMeasuring() + } + } +} + +extension ChaCha20TestsPerf { + static func allTests() -> [(String, (ChaCha20TestsPerf) -> () -> Void)] { + let tests = [("testChaCha20Performance", testChaCha20Performance)] + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/Default-568h@2x.png b/Carthage/Checkouts/CryptoSwift/Tests/Tests/Default-568h@2x.png new file mode 100644 index 0000000000..0891b7aabf Binary files /dev/null and b/Carthage/Checkouts/CryptoSwift/Tests/Tests/Default-568h@2x.png differ diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/DigestTests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/DigestTests.swift new file mode 100644 index 0000000000..315b7c9c13 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/DigestTests.swift @@ -0,0 +1,285 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// http://www.di-mgt.com.au/sha_testvectors.html (http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf) +// + +@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") + XCTAssertEqual("a".md5(), "0cc175b9c0f1b6a831c399e269772661", "MD5 calculation failed") + XCTAssertEqual("abc".md5(), "900150983cd24fb0d6963f7d28e17f72", "MD5 calculation failed") + XCTAssertEqual("message digest".md5(), "f96b697d7cb7938d525a2f31aaf161d0", "MD5 calculation failed") + XCTAssertEqual("abcdefghijklmnopqrstuvwxyz".md5(), "c3fcd3d76192e4007dfb496cca67e13b", "MD5 calculation failed") + XCTAssertEqual("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".md5(), "d174ab98d277d9f5a5611c2c9f419d9f", "MD5 calculation failed") + XCTAssertEqual("12345678901234567890123456789012345678901234567890123456789012345678901234567890".md5(), "57edf4a22be3c955ac49da2e2107b67a", "MD5 calculation failed") + } + + func testSHA1() { + XCTAssertEqual(SHA1().calculate(for: Array(hex: "616263")).toHexString(), "a9993e364706816aba3e25717850c26c9cd0d89d") + XCTAssertEqual(SHA1().calculate(for: Array(hex: "")).toHexString(), "da39a3ee5e6b4b0d3255bfef95601890afd80709") + XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha1(), "84983e441c3bd26ebaae4aa1f95129e5e54670f1") + XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha1(), "a49b2446a02c645bf419f995b67091253a04a259") + XCTAssertEqual(Array(repeating: 0x61, count: 1_000_000).sha1(), Array(hex: "34aa973cd4c4daa4f61eeb2bdbad27316534016f"), "One million (1,000,000) repetitions of the character 'a' (0x61)") + + // https://github.com/krzyzanowskim/CryptoSwift/issues/363 + XCTAssertEqual("1477304791&1XpnGSRhOlZz2etXMeOdfNaHILTjW16U&8mpBBbzwsgs".sha1(), "0809bbf8489c594131c2030a84be364a0851a635", "Failed") + XCTAssertEqual("1477304791&1XpnGSRhOlZz2etXMeOdfNaHILTjW16U&8mpBBbzwsgsa".sha1(), "d345b525ebada7becc8107c54e07fa88644471f5", "Failed") + XCTAssertEqual("1477304791&1XpnGSRhOlZz2etXMeOdfNaHILTjW16U&8mpBBbzwsg".sha1(), "c106aa0a98606294ee35fd2d937e928ebb5339e0", "Failed") + } + + func testSHA2() { + XCTAssertEqual(SHA2(variant: .sha224).calculate(for: Array(hex: "616263")).toHexString(), "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7") + XCTAssertEqual(SHA2(variant: .sha256).calculate(for: Array(hex: "616263")).toHexString(), "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad") + XCTAssertEqual(SHA2(variant: .sha384).calculate(for: Array(hex: "616263")).toHexString(), "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7") + XCTAssertEqual(SHA2(variant: .sha512).calculate(for: Array(hex: "616263")).toHexString(), "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f") + + XCTAssertEqual(SHA2(variant: .sha224).calculate(for: Array(hex: "")).toHexString(), "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f") + XCTAssertEqual(SHA2(variant: .sha256).calculate(for: Array(hex: "")).toHexString(), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") + XCTAssertEqual(SHA2(variant: .sha384).calculate(for: Array(hex: "")).toHexString(), "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b") + XCTAssertEqual(SHA2(variant: .sha512).calculate(for: Array(hex: "")).toHexString(), "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e") + + XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha224(), "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525") + XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha256(), "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1") + XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha384(), "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b") + XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha512(), "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445") + + XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha224(), "c97ca9a559850ce97a04a96def6d99a9e0e0e2ab14e6b8df265fc0b3") + XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha256(), "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1") + XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha384(), "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039") + XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha512(), "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909") + + XCTAssertEqual(Array(repeating: 0x61, count: 1_000_000).sha224(), Array(hex: "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"), "One million (1,000,000) repetitions of the character 'a' (0x61)") + XCTAssertEqual(Array(repeating: 0x61, count: 1_000_000).sha256(), Array(hex: "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"), "One million (1,000,000) repetitions of the character 'a' (0x61)") + XCTAssertEqual(Array(repeating: 0x61, count: 1_000_000).sha384(), Array(hex: "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985"), "One million (1,000,000) repetitions of the character 'a' (0x61)") + XCTAssertEqual(Array(repeating: 0x61, count: 1_000_000).sha512(), Array(hex: "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"), "One million (1,000,000) repetitions of the character 'a' (0x61)") + + XCTAssertEqual("Rosetta code".sha256(), "764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf", "SHA256 calculation failed") + XCTAssertEqual("The quick brown fox jumps over the lazy dog.".sha384(), "ed892481d8272ca6df370bf706e4d7bc1b5739fa2177aae6c50e946678718fc67a7af2819a021c2fc34e91bdb63409d7", "SHA384 calculation failed") + } + + func testSHA3() { + XCTAssertEqual(SHA3(variant: .sha224).calculate(for: Array(hex: "616263")).toHexString(), "e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf") + XCTAssertEqual(SHA3(variant: .sha256).calculate(for: Array(hex: "616263")).toHexString(), "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532") + XCTAssertEqual(SHA3(variant: .sha384).calculate(for: Array(hex: "616263")).toHexString(), "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25") + XCTAssertEqual(SHA3(variant: .sha512).calculate(for: Array(hex: "616263")).toHexString(), "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0") + XCTAssertEqual(SHA3(variant: .keccak224).calculate(for: Array(hex: "616263")).toHexString(), "c30411768506ebe1c2871b1ee2e87d38df342317300a9b97a95ec6a8") + XCTAssertEqual(SHA3(variant: .keccak256).calculate(for: Array(hex: "616263")).toHexString(), "4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45") + XCTAssertEqual(SHA3(variant: .keccak384).calculate(for: Array(hex: "616263")).toHexString(), "f7df1165f033337be098e7d288ad6a2f74409d7a60b49c36642218de161b1f99f8c681e4afaf31a34db29fb763e3c28e") + XCTAssertEqual(SHA3(variant: .keccak512).calculate(for: Array(hex: "616263")).toHexString(), "18587dc2ea106b9a1563e32b3312421ca164c7f1f07bc922a9c83d77cea3a1e5d0c69910739025372dc14ac9642629379540c17e2a65b19d77aa511a9d00bb96") + + XCTAssertEqual(SHA3(variant: .sha224).calculate(for: Array(hex: "")).toHexString(), "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7") + XCTAssertEqual(SHA3(variant: .sha256).calculate(for: Array(hex: "")).toHexString(), "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a") + XCTAssertEqual(SHA3(variant: .sha384).calculate(for: Array(hex: "")).toHexString(), "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004") + XCTAssertEqual(SHA3(variant: .sha512).calculate(for: Array(hex: "")).toHexString(), "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26") + XCTAssertEqual(SHA3(variant: .keccak224).calculate(for: Array(hex: "")).toHexString(), "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd") + XCTAssertEqual(SHA3(variant: .keccak256).calculate(for: Array(hex: "")).toHexString(), "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470") + XCTAssertEqual(SHA3(variant: .keccak384).calculate(for: Array(hex: "")).toHexString(), "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff") + XCTAssertEqual(SHA3(variant: .keccak512).calculate(for: Array(hex: "")).toHexString(), "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e") + + XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.sha224), "8a24108b154ada21c9fd5574494479ba5c7e7ab76ef264ead0fcce33") + XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.sha256), "41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376") + XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.sha384), "991c665755eb3a4b6bbdfb75c78a492e8c56a22c5c4d7e429bfdbc32b9d4ad5aa04a1f076e62fea19eef51acd0657c22") + XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.sha512), "04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e") + XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.keccak224), "e51faa2b4655150b931ee8d700dc202f763ca5f962c529eae55012b6") + XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.keccak256), "45d3b367a6904e6e8d502ee04999a7c27647f91fa845d456525fd352ae3d7371") + XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.keccak384), "b41e8896428f1bcbb51e17abd6acc98052a3502e0d5bf7fa1af949b4d3c855e7c4dc2c390326b3f3e74c7b1e2b9a3657") + XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha3(.keccak512), "6aa6d3669597df6d5a007b00d09c20795b5c4218234e1698a944757a488ecdc09965435d97ca32c3cfed7201ff30e070cd947f1fc12b9d9214c467d342bcba5d") + + XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.sha224), "543e6868e1666c1a643630df77367ae5a62a85070a51c14cbf665cbc") + XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.sha256), "916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18") + XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.sha384), "79407d3b5916b59c3e30b09822974791c313fb9ecc849e406f23592d04f625dc8c709b98b43b3852b337216179aa7fc7") + XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.sha512), "afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185") + XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.keccak224), "344298994b1b06873eae2ce739c425c47291a2e24189e01b524f88dc") + XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.keccak256), "f519747ed599024f3882238e5ab43960132572b7345fbeb9a90769dafd21ad67") + XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.keccak384), "cc063f34685135368b34f7449108f6d10fa727b09d696ec5331771da46a923b6c34dbd1d4f77e595689c1f3800681c28") + XCTAssertEqual("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".sha3(.keccak512), "ac2fb35251825d3aa48468a9948c0a91b8256f6d97d8fa4160faff2dd9dfcc24f3f1db7a983dad13d53439ccac0b37e24037e7b95f80f59f37a2f683c4ba4682") + + XCTAssertEqual(Array(repeating: 0x61, count: 1_000_000).sha3(.sha224), Array(hex: "d69335b93325192e516a912e6d19a15cb51c6ed5c15243e7a7fd653c"), "One million (1,000,000) repetitions of the character 'a' (0x61)") + XCTAssertEqual(Array(repeating: 0x61, count: 1_000_000).sha3(.sha256), Array(hex: "5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1"), "One million (1,000,000) repetitions of the character 'a' (0x61)") + XCTAssertEqual(Array(repeating: 0x61, count: 1_000_000).sha3(.sha384), Array(hex: "eee9e24d78c1855337983451df97c8ad9eedf256c6334f8e948d252d5e0e76847aa0774ddb90a842190d2c558b4b8340"), "One million (1,000,000) repetitions of the character 'a' (0x61)") + XCTAssertEqual(Array(repeating: 0x61, count: 1_000_000).sha3(.sha512), Array(hex: "3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87"), "One million (1,000,000) repetitions of the character 'a' (0x61)") + XCTAssertEqual(Array(repeating: 0x61, count: 1_000_000).sha3(.keccak224), Array(hex: "19f9167be2a04c43abd0ed554788101b9c339031acc8e1468531303f"), "One million (1,000,000) repetitions of the character 'a' (0x61)") + XCTAssertEqual(Array(repeating: 0x61, count: 1_000_000).sha3(.keccak256), Array(hex: "fadae6b49f129bbb812be8407b7b2894f34aecf6dbd1f9b0f0c7e9853098fc96"), "One million (1,000,000) repetitions of the character 'a' (0x61)") + XCTAssertEqual(Array(repeating: 0x61, count: 1_000_000).sha3(.keccak384), Array(hex: "0c8324e1ebc182822c5e2a086cac07c2fe00e3bce61d01ba8ad6b71780e2dec5fb89e5ae90cb593e57bc6258fdd94e17"), "One million (1,000,000) repetitions of the character 'a' (0x61)") + XCTAssertEqual(Array(repeating: 0x61, count: 1_000_000).sha3(.keccak512), Array(hex: "5cf53f2e556be5a624425ede23d0e8b2c7814b4ba0e4e09cbbf3c2fac7056f61e048fc341262875ebc58a5183fea651447124370c1ebf4d6c89bc9a7731063bb"), "One million (1,000,000) repetitions of the character 'a' (0x61)") + + // *** Multiple of block size *** + + // keccak block size bytes + XCTAssertEqual(Array(repeating: 0x00, count: 144).sha3(.keccak224), Array(hex: "a50976d8ed54c961a052bfd01a64cd79b11928a9d5b75146a0828888"), "Block size bytes for keccak224") + XCTAssertEqual(Array(repeating: 0x00, count: 136).sha3(.keccak256), Array(hex: "3a5912a7c5faa06ee4fe906253e339467a9ce87d533c65be3c15cb231cdb25f9"), "Block size bytes for keccak256") + XCTAssertEqual(Array(repeating: 0x00, count: 104).sha3(.keccak384), Array(hex: "768e10c2eb9903fba6bf290669bf98bd03ce42e7492da9abb88cbbe2212ed153c857e4e883fb1b03a498391935ec6112"), "Block size bytes for keccak384") + XCTAssertEqual(Array(repeating: 0x00, count: 72).sha3(.keccak512), Array(hex: "bcf38e5b375422155b4d8eb150682a14778b0695d709cec479d013a772497bc8d7050ef2a23d69609d609b15e5001f275c4619270ffbd6e8c06a7a5bf72334b3"), "Block size bytes for keccak512") + + // keccak two times block size bytes + XCTAssertEqual(Array(repeating: 0x00, count: 288).sha3(.keccak224), Array(hex: "846f930bf21e7ec2175a635379adbdbce9ed9de6a34396c4a11aaf3c"), "Two times block size bytes for keccak224") + XCTAssertEqual(Array(repeating: 0x00, count: 272).sha3(.keccak256), Array(hex: "a8005c7a3125b6c3629b4181eca54d18721e41fef639718d205beb00b366ed7d"), "Two times block size bytes for keccak256") + XCTAssertEqual(Array(repeating: 0x00, count: 208).sha3(.keccak384), Array(hex: "db6451e6fb59ca16c9ba896de2967b07ca331e9558e21257cb6b26f126ed480c841d37788907f77ef71f8258218b0203"), "Two times block size bytes for keccak384") + XCTAssertEqual(Array(repeating: 0x00, count: 144).sha3(.keccak512), Array(hex: "04ddaacd88ce54a4acb468b792d5177ace573e9871dc10b33d02be637b674373601ba5f433b67cc6ba8dc3a1707052f1f6bffc55ef1580aca021ead8bc8e1f22"), "Two times block size bytes for keccak512") + + // nist sha3 block size bytes + XCTAssertEqual(Array(repeating: 0x00, count: 144).sha3(.sha224), Array(hex: "f2b8486fceee2c6a11a604ce4efe217da854829c2c2dcc9a23758b4d"), "Block size bytes for sha3 sha224") + XCTAssertEqual(Array(repeating: 0x00, count: 136).sha3(.sha256), Array(hex: "e772c9cf9eb9c991cdfcf125001b454fdbc0a95f188d1b4c844aa032ad6e075e"), "Block size bytes for sha3 sha256") + XCTAssertEqual(Array(repeating: 0x00, count: 104).sha3(.sha384), Array(hex: "aaed6beb61b1f9a9b469d38a27a35edde7f676f4603e67f5424c7588043b869ebbfcfc3ecee2ae6f5ecfaf7f706c49e3"), "Block size bytes for sha3 sha384") + XCTAssertEqual(Array(repeating: 0x00, count: 72).sha3(.sha512), Array(hex: "f8d76fdd8a082a67eaab47b5518ac486cb9a90dcb9f3c9efcfd86d5c8b3f1831601d3c8435f84b9e56da91283d5b98040e6e7b2c8dd9aa5bd4ebdf1823a7cf29"), "Block size bytes for sha3 sha512") + + // nist sha3 two times block size bytes + XCTAssertEqual(Array(repeating: 0x00, count: 288).sha3(.sha224), Array(hex: "920370d3fec17c0ecbc2b5b7cd64f551860fb93384e0dc4fcaf2e1ba"), "Two times block size bytes for sha3 sha224") + XCTAssertEqual(Array(repeating: 0x00, count: 272).sha3(.sha256), Array(hex: "5d86a8cc4aa8f0d98146a747281865a625a19f9580eef32e38905920bc532c5c"), "Two times block size bytes for sha3 sha256") + XCTAssertEqual(Array(repeating: 0x00, count: 208).sha3(.sha384), Array(hex: "e741867850b8753bf7fa714b11c1ca9904d0494adaf5e2db43cca42f39637bd67685279d9dfcc45d56e8c288273904af"), "Two times block size bytes for sha3 sha384") + XCTAssertEqual(Array(repeating: 0x00, count: 144).sha3(.sha512), Array(hex: "07625da1770011d59b0a71a8dec551f0ddf1917e4117fc860bd7e0a0e42f3e012284f86d509e2f22a8682aea5930197fc1f3c353d0141665c9ac2643278c3821"), "Two times block size bytes for sha3 sha512") + // *** End Multiple of block size *** + } + + func testMD5Data() { + let data = [0x31, 0x32, 0x33] as Array // "1", "2", "3" + XCTAssertEqual(Digest.md5(data), [0x20, 0x2C, 0xB9, 0x62, 0xAC, 0x59, 0x07, 0x5B, 0x96, 0x4B, 0x07, 0x15, 0x2D, 0x23, 0x4B, 0x70], "MD5 calculation failed") + } + + func testMD5Updates() { + do { + var hash = MD5() + _ = try hash.update(withBytes: [0x31, 0x32]) + _ = try hash.update(withBytes: [0x33]) + let result = try hash.finish() + XCTAssertEqual(result, [0x20, 0x2C, 0xB9, 0x62, 0xAC, 0x59, 0x07, 0x5B, 0x96, 0x4B, 0x07, 0x15, 0x2D, 0x23, 0x4B, 0x70]) + } catch { + XCTFail() + } + } + + func testSHA1Updatable1() { + do { + var hash = SHA1() + _ = try hash.update(withBytes: [0x31, 0x32]) + _ = try hash.update(withBytes: [0x33]) + XCTAssertEqual(try hash.finish().toHexString(), "40bd001563085fc35165329ea1ff5c5ecbdbbeef", "Failed") + } catch { + XCTFail() + } + } + + func testSHA1Updatable2() { + do { + var hash = SHA1() + _ = try hash.update(withBytes: [0x31, 0x32]) + _ = try hash.update(withBytes: [0x33]) + _ = try hash.update(withBytes: Array(repeating: 0x33, count: 64)) + XCTAssertEqual(try hash.finish().toHexString(), "0e659367eff83a6b868a35b96ac305b270025e86", "Failed") + } catch { + XCTFail() + } + } + + func testCRC32() { + let data: Data = Data(bytes: UnsafePointer([49, 50, 51] as Array), count: 3) + XCTAssertEqual(data.crc32(seed: nil).toHexString(), "884863d2", "CRC32 calculation failed") + + XCTAssertEqual("".crc32(seed: nil), "00000000", "CRC32 calculation failed") + } + + func testCRC32C() { + let data: Data = Data(bytes: UnsafePointer([0x32, 0, 0, 0] as Array), count: 4) + XCTAssertEqual(data.crc32c(seed: nil).toHexString(), "c941cdf0", "CRC32C calculation failed") + XCTAssertEqual("".crc32c(seed: nil), "00000000", "CRC32 calculation failed") + } + + func testCRC32NotReflected() { + let bytes: Array = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39] + let data: Data = Data(bytes: UnsafePointer(bytes), count: bytes.count) + XCTAssertEqual(data.crc32(seed: nil, reflect: false).toHexString(), "fc891918", "CRC32 (with reflection) calculation failed") + + XCTAssertEqual("".crc32(seed: nil, reflect: false), "00000000", "CRC32 (with reflection) calculation failed") + } + + func testCRC16() { + let result = Checksum.crc16([49, 50, 51, 52, 53, 54, 55, 56, 57] as Array) + XCTAssert(result == 0xBB3D, "CRC16 failed") + } + + func testChecksum() { + let data: Data = Data(bytes: UnsafePointer([49, 50, 51] as Array), count: 3) + XCTAssert(data.checksum() == 0x96, "Invalid checksum") + } + + func testSHAPartialUpdates() { + do { + let testSize = 1024 * 1024 * 5 + let buf = malloc(testSize)! + defer { free(buf) } + let input = Data(bytes: buf, count: testSize) + + // SHA1 + let sha1Once = SHA1().calculate(for: input.bytes) + + var sha1Partial = SHA1() + for batch in input.batched(by: 17) { + _ = try sha1Partial.update(withBytes: batch.bytes) + } + let sha1Result = try sha1Partial.finish() + XCTAssertEqual(sha1Once, sha1Result) + + // SHA2 + let sha2Once = SHA2(variant: .sha224).calculate(for: input.bytes) + + var sha2Partial = SHA2(variant: .sha224) + for batch in input.batched(by: 17) { + _ = try sha2Partial.update(withBytes: batch.bytes) + } + let sha2Result = try sha2Partial.finish() + XCTAssertEqual(sha2Once, sha2Result) + + // SHA3 + let sha3Once = SHA3(variant: .sha224).calculate(for: input.bytes) + + var sha3Partial = SHA3(variant: .sha224) + for batch in input.batched(by: 17) { + _ = try sha3Partial.update(withBytes: batch.bytes) + } + let sha3Result = try sha3Partial.finish() + XCTAssertEqual(sha3Once, sha3Result) + } catch { + XCTFail(error.localizedDescription) + } + } +} + +extension DigestTests { + static func allTests() -> [(String, (DigestTests) -> () -> Void)] { + let tests = [ + ("testMD5", testMD5), + ("testSHA1", testSHA1), + ("testSHA2", testSHA2), + ("testSHA3", testSHA3), + ("testMD5Data", testMD5Data), + ("testMD5Updates", testMD5Updates), + ("testSHA1Updatable1", testSHA1Updatable1), + ("testSHA1Updatable2", testSHA1Updatable2), + ("testCRC32", testCRC32), + ("testCRC32NotReflected", testCRC32NotReflected), + ("testCRC16", testCRC16), + ("testChecksum", testChecksum), + ("testSHAPartialUpdates", testSHAPartialUpdates), + ] + + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/DigestTestsPerf.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/DigestTestsPerf.swift new file mode 100644 index 0000000000..6480a8da13 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/DigestTestsPerf.swift @@ -0,0 +1,63 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +// http://www.di-mgt.com.au/sha_testvectors.html (http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf) +// + +@testable import CryptoSwift +import Foundation +import XCTest + +final class DigestTestsPerf: XCTestCase { + func testMD5Performance() { + measureMetrics([XCTPerformanceMetric.wallClockTime], automaticallyStartMeasuring: false) { + let arr = Array(repeating: 200, count: 1024 * 1024) + self.startMeasuring() + _ = Digest.md5(arr) + self.stopMeasuring() + } + } + + func testSHA1Performance() { + measureMetrics([XCTPerformanceMetric.wallClockTime], automaticallyStartMeasuring: false) { + let arr = Array(repeating: 200, count: 1024 * 1024) + self.startMeasuring() + _ = Digest.sha1(arr) + self.stopMeasuring() + } + } + + // Keep it to compare + /* + func testSHA1PerformanceCC() { + measureMetrics([XCTPerformanceMetric.wallClockTime], automaticallyStartMeasuring: false) { + let arr = Array(repeating: 200, count: 1024 * 1024) + self.startMeasuring() + var digest = Array(repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH)) + CC_SHA1(arr, CC_LONG(arr.count), &digest) + self.stopMeasuring() + } + } + */ +} + +extension DigestTestsPerf { + static func allTests() -> [(String, (DigestTestsPerf) -> () -> Void)] { + return [ + ("testMD5Performance", testMD5Performance), + ("testSHA1Performance", testSHA1Performance) + ] + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/Error+Extension.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/Error+Extension.swift new file mode 100644 index 0000000000..686350f581 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/Error+Extension.swift @@ -0,0 +1,25 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +import Foundation + +#if !_runtime(_ObjC) + + extension Error { + var localizedDescription: String { + return "\(self)" + } + } +#endif diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/ExtensionsTest.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ExtensionsTest.swift new file mode 100644 index 0000000000..1a37d4dc7e --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ExtensionsTest.swift @@ -0,0 +1,101 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import Foundation +import XCTest + +final class ExtensionsTest: XCTestCase { + func testBytes() { + let size = MemoryLayout.size // 32 or 64 bit + + let i: UInt32 = 1024 + var bytes = i.bytes() + XCTAssertTrue(bytes.count == size, "Invalid bytes length = \(bytes.count)") + + // test padding + bytes = i.bytes(totalBytes: 16) + XCTAssertTrue(bytes.count == 16, "Invalid return type \(bytes.count)") + XCTAssertTrue(bytes[14] == 4, "Invalid return type \(bytes.count)") + } + + func testToUInt32Array() { + let chunk: ArraySlice = [0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1] + let result = chunk.toUInt32Array() + + XCTAssert(result.count == 2, "Invalid conversion") + XCTAssertEqual(result[0], 0x5060708) + XCTAssertEqual(result[1], 0x1020304) + } + + func testDataInit() { + let data = Data( [0x01, 0x02, 0x03]) + XCTAssert(data.count == 3, "Invalid data") + } + + func testStringEncrypt() { + do { + let encryptedHex = try "my secret string".encrypt(cipher: AES(key: "secret0key000000", iv: "0123456789012345")) + XCTAssertEqual(encryptedHex, "68f7ff8bdb61f625febdfe3d791ecf624daaed2e719a6de39112de8e0cc7349b") + } catch { + XCTFail(error.localizedDescription) + } + } + + func testEmptyStringEncrypt() { + do { + let cipher = try AES(key: "secret0key000000".bytes.md5(), blockMode: ECB()) + let encrypted = try "".encryptToBase64(cipher: cipher) + let decrypted = try encrypted?.decryptBase64ToString(cipher: cipher) + XCTAssertEqual("", decrypted) + + XCTAssertThrowsError(try "".decryptBase64(cipher: cipher)) + } catch { + XCTFail(error.localizedDescription) + } + } + + func testStringDecryptBase64() { + let encryptedBase64 = "aPf/i9th9iX+vf49eR7PYk2q7S5xmm3jkRLejgzHNJs=" + let decrypted = try! encryptedBase64.decryptBase64ToString(cipher: AES(key: "secret0key000000", iv: "0123456789012345")) + XCTAssertEqual(decrypted, "my secret string") + } + + func testArrayInitHex() { + let bytes = Array(hex: "0xb1b1b2b2") + XCTAssertEqual(bytes, [177, 177, 178, 178]) + + let str = "b1b2b3b3b3b3b3b3b1b2b3b3b3b3b3b3" + let array = Array(hex: str) + let hex = array.toHexString() + XCTAssertEqual(str, hex) + } +} + +extension ExtensionsTest { + static func allTests() -> [(String, (ExtensionsTest) -> () -> Void)] { + let tests = [ + ("testBytes", testBytes), + ("testToUInt32Array", testToUInt32Array), + ("testDataInit", testDataInit), + ("testStringEncrypt", testStringEncrypt), + ("testStringDecryptBase64", testStringDecryptBase64), + ("testEmptyStringEncrypt", testEmptyStringEncrypt), + ("testArrayInitHex", testArrayInitHex), + ] + + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/ExtensionsTestPerf.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ExtensionsTestPerf.swift new file mode 100644 index 0000000000..b7e31e7b07 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ExtensionsTestPerf.swift @@ -0,0 +1,39 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import Foundation +import XCTest + +final class ExtensionsTestPerf: XCTestCase { + func testArrayInitHexPerformance() { + var str = "b1b2b3b3b3b3b3b3b1b2b3b3b3b3b3b3" + for _ in 0...12 { + str += str + } + measure { + _ = Array(hex: str) + } + } +} + +extension ExtensionsTestPerf { + static func allTests() -> [(String, (ExtensionsTestPerf) -> () -> Void)] { + let tests = [ + ("testArrayInitHexPerformance", testArrayInitHexPerformance), + ] + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/HKDFTests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/HKDFTests.swift new file mode 100644 index 0000000000..a072fdd5e5 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/HKDFTests.swift @@ -0,0 +1,97 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@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(hex: "0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b") + let salt = Array(hex: "0x000102030405060708090a0b0c") + let info = Array(hex: "0xf0f1f2f3f4f5f6f7f8f9") + let keyLength = 42 + let variant = HMAC.Variant.sha256 + let reference = Array(hex: "0x3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865") + + XCTAssertEqual(reference, try HKDF(password: password, salt: salt, info: info, keyLength: keyLength, variant: variant).calculate()) + } + + func testHKDF2() { + let password = Array(hex: "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f") + let salt = Array(hex: "0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf") + let info = Array(hex: "0xb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") + let keyLength = 82 + let variant = HMAC.Variant.sha256 + let reference = Array(hex: "0xb11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87") + + XCTAssertEqual(reference, try HKDF(password: password, salt: salt, info: info, keyLength: keyLength, variant: variant).calculate()) + } + + func testHKDF3() { + let password = Array(hex: "0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b") + let keyLength = 42 + let variant = HMAC.Variant.sha256 + let reference = Array(hex: "0x8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8") + + XCTAssertEqual(reference, try HKDF(password: password, keyLength: keyLength, variant: variant).calculate()) + } + + func testHKDF4() { + let password = Array(hex: "0x0b0b0b0b0b0b0b0b0b0b0b") + let salt = Array(hex: "0x000102030405060708090a0b0c") + let info = Array(hex: "0xf0f1f2f3f4f5f6f7f8f9") + let keyLength = 42 + let variant = HMAC.Variant.sha1 + let reference = Array(hex: "0x085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896") + + XCTAssertEqual(reference, try HKDF(password: password, salt: salt, info: info, keyLength: keyLength, variant: variant).calculate()) + } + + func testHKDF5() { + let password = Array(hex: "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f") + let salt = Array(hex: "0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf") + let info = Array(hex: "0xb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") + let keyLength = 82 + let variant = HMAC.Variant.sha1 + let reference = Array(hex: "0x0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4") + + XCTAssertEqual(reference, try HKDF(password: password, salt: salt, info: info, keyLength: keyLength, variant: variant).calculate()) + } + + func testHKDF6() { + let password = Array(hex: "0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b") + let keyLength = 42 + let variant = HMAC.Variant.sha1 + let reference = Array(hex: "0x0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918") + + XCTAssertEqual(reference, try HKDF(password: password, keyLength: keyLength, variant: variant).calculate()) + } + + static func allTests() -> [(String, (HKDFTests) -> () -> Void)] { + let tests = [ + ("Basic test case with SHA-256", testHKDF1), + ("Test with SHA-256 and longer inputs/outputs", testHKDF2), + ("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), + ] + + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/HMACTests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/HMACTests.swift new file mode 100644 index 0000000000..941a8643a6 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/HMACTests.swift @@ -0,0 +1,71 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import XCTest + +final class HMACTests: XCTestCase { + func testMD5() { + let key: Array = [] + let msg: Array = [] + let expectedMac: Array = [0x74, 0xe6, 0xf7, 0x29, 0x8a, 0x9c, 0x2d, 0x16, 0x89, 0x35, 0xf5, 0x8c, 0x00, 0x1b, 0xad, 0x88] + + let hmac = try! HMAC(key: key, variant: .md5).authenticate(msg) + XCTAssertEqual(hmac, expectedMac, "Invalid authentication result") + } + + func testSHA1() { + XCTAssertEqual(try HMAC(key: [], variant: .sha1).authenticate([]), Array(hex: "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d")) + // echo -n "test" | openssl sha1 -hmac 'test' + XCTAssertEqual(try HMAC(key: Array(hex: "74657374"), variant: .sha1).authenticate(Array(hex: "74657374")), Array(hex: "0c94515c15e5095b8a87a50ba0df3bf38ed05fe6")) + // echo -n "test" | openssl sha1 -hmac '0123456789012345678901234567890123456789012345678901234567890123' + XCTAssertEqual(try HMAC(key: Array(hex: "30313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233"), variant: .sha1).authenticate(Array(hex: "74657374")), Array(hex: "23cea58b0c484ed005434938ee70a938d7524e91")) + } + + func testSHA256() { + let key: Array = [] + let msg: Array = [] + let expectedMac: Array = [0xb6, 0x13, 0x67, 0x9a, 0x08, 0x14, 0xd9, 0xec, 0x77, 0x2f, 0x95, 0xd7, 0x78, 0xc3, 0x5f, 0xc5, 0xff, 0x16, 0x97, 0xc4, 0x93, 0x71, 0x56, 0x53, 0xc6, 0xc7, 0x12, 0x14, 0x42, 0x92, 0xc5, 0xad] + + let hmac = try! HMAC(key: key, variant: .sha256).authenticate(msg) + XCTAssertEqual(hmac, expectedMac, "Invalid authentication result") + } + + func testSHA384() { + let key: Array = [] + let msg: Array = [] + let expectedMac: Array = [0x6c, 0x1f, 0x2e, 0xe9, 0x38, 0xfa, 0xd2, 0xe2, 0x4b, 0xd9, 0x12, 0x98, 0x47, 0x43, 0x82, 0xca, 0x21, 0x8c, 0x75, 0xdb, 0x3d, 0x83, 0xe1, 0x14, 0xb3, 0xd4, 0x36, 0x77, 0x76, 0xd1, 0x4d, 0x35, 0x51, 0x28, 0x9e, 0x75, 0xe8, 0x20, 0x9c, 0xd4, 0xb7, 0x92, 0x30, 0x28, 0x40, 0x23, 0x4a, 0xdc] + + let hmac = try! HMAC(key: key, variant: .sha384).authenticate(msg) + XCTAssertEqual(hmac, expectedMac, "Invalid authentication result") + } + + func testSHA512() { + let key: Array = [] + let msg: Array = [] + let expectedMac: Array = [0xb9, 0x36, 0xce, 0xe8, 0x6c, 0x9f, 0x87, 0xaa, 0x5d, 0x3c, 0x6f, 0x2e, 0x84, 0xcb, 0x5a, 0x42, 0x39, 0xa5, 0xfe, 0x50, 0x48, 0x0a, 0x6e, 0xc6, 0x6b, 0x70, 0xab, 0x5b, 0x1f, 0x4a, 0xc6, 0x73, 0x0c, 0x6c, 0x51, 0x54, 0x21, 0xb3, 0x27, 0xec, 0x1d, 0x69, 0x40, 0x2e, 0x53, 0xdf, 0xb4, 0x9a, 0xd7, 0x38, 0x1e, 0xb0, 0x67, 0xb3, 0x38, 0xfd, 0x7b, 0x0c, 0xb2, 0x22, 0x47, 0x22, 0x5d, 0x47] + + let hmac = try! HMAC(key: key, variant: .sha512).authenticate(msg) + XCTAssertEqual(hmac, expectedMac, "Invalid authentication result") + } + + static let allTests = [ + ("testMD5", testMD5), + ("testSHA1", testSHA1), + ("testSHA256", testSHA256), + ("testSHA384", testSHA384), + ("testSHA512", testSHA512), + ] +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/Info.plist b/Carthage/Checkouts/CryptoSwift/Tests/Tests/Info.plist new file mode 100644 index 0000000000..e24601b6ea --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.krzyzanowskim.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/PBKDF.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/PBKDF.swift new file mode 100644 index 0000000000..3624c7bac3 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/PBKDF.swift @@ -0,0 +1,74 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import XCTest + +class PBKDF: XCTestCase { + func testPBKDF1() { + let password: Array = [0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64] + let salt: Array = [0x78, 0x57, 0x8e, 0x5a, 0x5d, 0x63, 0xcb, 0x06] + let value = try! PKCS5.PBKDF1(password: password, salt: salt, iterations: 1000, keyLength: 16).calculate() + XCTAssertEqual(value.toHexString(), "dc19847e05c64d2faf10ebfb4a3d2a20") + } + + func testPBKDF2() { + // P = "password", S = "salt", c = 1, dkLen = 20 + XCTAssertEqual([0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, 0x2f, 0xe0, 0x37, 0xa6], + try PKCS5.PBKDF2(password: [0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64], salt: [0x73, 0x61, 0x6c, 0x74], iterations: 1, keyLength: 20, variant: .sha1).calculate()) + + // P = "password", S = "salt", c = 2, dkLen = 20 + XCTAssertEqual([0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0, 0xd8, 0xde, 0x89, 0x57], + try PKCS5.PBKDF2(password: [0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64], salt: [0x73, 0x61, 0x6c, 0x74], iterations: 2, keyLength: 20, variant: .sha1).calculate()) + + // P = "password", S = "salt", c = 4096, dkLen = 20 + XCTAssertEqual([0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a, 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0, 0x65, 0xa4, 0x29, 0xc1], + try PKCS5.PBKDF2(password: [0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64], salt: [0x73, 0x61, 0x6c, 0x74], iterations: 4096, keyLength: 20, variant: .sha1).calculate()) + + // P = "password", S = "salt", c = 16777216, dkLen = 20 + // Commented because it takes a lot of time with Debug build to finish. + // XCTAssertEqual([0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4, 0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c, 0x26, 0x34, 0xe9, 0x84], + // try PKCS5.PBKDF2(password: [0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64], salt: [0x73, 0x61, 0x6C, 0x74], iterations: 16777216, keyLength: 20, variant: .sha1).calculate()) + + // P = "passwordPASSWORDpassword", S = "saltSALTsaltSALTsaltSALTsaltSALTsalt", c = 4096, dkLen = 25 + XCTAssertEqual([0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a, 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, 0x38], + try PKCS5.PBKDF2(password: [0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x50, 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, 0x44, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64], salt: [0x73, 0x61, 0x6c, 0x74, 0x53, 0x41, 0x4c, 0x54, 0x73, 0x61, 0x6c, 0x74, 0x53, 0x41, 0x4c, 0x54, 0x73, 0x61, 0x6c, 0x74, 0x53, 0x41, 0x4c, 0x54, 0x73, 0x61, 0x6c, 0x74, 0x53, 0x41, 0x4c, 0x54, 0x73, 0x61, 0x6c, 0x74], iterations: 4096, keyLength: 25, variant: .sha1).calculate()) + + // P = "pass\0word", S = "sa\0lt", c = 4096, dkLen = 16 + XCTAssertEqual([0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d, 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3], + try PKCS5.PBKDF2(password: [0x70, 0x61, 0x73, 0x73, 0x00, 0x77, 0x6f, 0x72, 0x64], salt: [0x73, 0x61, 0x00, 0x6c, 0x74], iterations: 4096, keyLength: 16, variant: .sha1).calculate()) + + // P = "", S = "salt", c = 1, dkLen = 20 + XCTAssertEqual([0xa3, 0x3d, 0xdd, 0xc3, 0x04, 0x78, 0x18, 0x55, 0x15, 0x31, 0x1f, 0x87, 0x52, 0x89, 0x5d, 0x36, 0xea, 0x43, 0x63, 0xa2], + try PKCS5.PBKDF2(password: [], salt: [0x73, 0x61, 0x6c, 0x74], iterations: 1, keyLength: 20, variant: .sha1).calculate()) + } + + func testPBKDF2Length() { + let password: Array = "s33krit".bytes + let salt: Array = "nacl".bytes + let value = try! PKCS5.PBKDF2(password: password, salt: salt, iterations: 2, keyLength: 8, variant: .sha1).calculate() + XCTAssertEqual(value.toHexString(), "a53cf3df485e5cd9") + } + + static func allTests() -> [(String, (PBKDF) -> () -> Void)] { + let tests = [ + ("testPBKDF1", testPBKDF1), + ("testPBKDF2", testPBKDF2), + ("testPBKDF2Length", testPBKDF2Length), + ] + + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/PBKDFPerf.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/PBKDFPerf.swift new file mode 100644 index 0000000000..df57b3b0b8 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/PBKDFPerf.swift @@ -0,0 +1,32 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import XCTest + +class PBKDFPerf: XCTestCase { + func testPerformance() { + let password: Array = "s33krit".bytes + let salt: Array = "nacl".bytes + measure { + _ = try! PKCS5.PBKDF2(password: password, salt: salt, iterations: 65536, keyLength: 32, variant: .sha1).calculate() + } + } + + static func allTests() -> [(String, (PBKDFPerf) -> () -> Void)] { + let tests = [("testPerformance", testPerformance)] + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/PaddingTests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/PaddingTests.swift new file mode 100644 index 0000000000..3dcecc8d52 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/PaddingTests.swift @@ -0,0 +1,70 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import XCTest + +final class PaddingTests: XCTestCase { + func testPKCS7_0() { + let input: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6] + let expected: Array = [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] + let padded = PKCS7.Padding().add(to: input, blockSize: 16) + XCTAssertEqual(padded, expected, "PKCS7 failed") + let clean = PKCS7.Padding().remove(from: padded, blockSize: nil) + XCTAssertEqual(clean, input, "PKCS7 failed") + } + + func testPKCS7_1() { + let input: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5] + let expected: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 1] + let padded = PKCS7.Padding().add(to: input, blockSize: 16) + XCTAssertEqual(padded, expected, "PKCS7 failed") + let clean = PKCS7.Padding().remove(from: padded, blockSize: nil) + XCTAssertEqual(clean, input, "PKCS7 failed") + } + + func testPKCS7_2() { + let input: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4] + let expected: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 2, 2] + let padded = PKCS7.Padding().add(to: input, blockSize: 16) + XCTAssertEqual(padded, expected, "PKCS7 failed") + let clean = PKCS7.Padding().remove(from: padded, blockSize: nil) + XCTAssertEqual(clean, input, "PKCS7 failed") + } + + func testZeroPadding1() { + let input: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9] + let expected: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0] + let padding = ZeroPadding() + XCTAssertEqual(padding.add(to: input, blockSize: 16), expected, "ZeroPadding failed") + XCTAssertEqual(padding.remove(from: padding.add(to: input, blockSize: 16), blockSize: 16), input, "ZeroPadding failed") + } + + func testZeroPadding2() { + let input: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6] + let expected: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + let padding = ZeroPadding() + XCTAssertEqual(padding.add(to: input, blockSize: 16), expected, "ZeroPadding failed") + XCTAssertEqual(padding.remove(from: padding.add(to: input, blockSize: 16), blockSize: 16), input, "ZeroPadding failed") + } + + static let allTests = [ + ("testPKCS7_0", testPKCS7_0), + ("testPKCS7_1", testPKCS7_1), + ("testPKCS7_2", testPKCS7_2), + ("testZeroPadding1", testZeroPadding1), + ("testZeroPadding2", testZeroPadding2), + ] +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/Poly1305Tests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/Poly1305Tests.swift new file mode 100644 index 0000000000..a68c13accc --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/Poly1305Tests.swift @@ -0,0 +1,45 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import Foundation +import XCTest + +final class Poly1305Tests: XCTestCase { + func testPoly1305() { + let key: Array = [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 = [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] + let expectedMac: Array = [0xdd, 0xb9, 0xda, 0x7d, 0xdd, 0x5e, 0x52, 0x79, 0x27, 0x30, 0xed, 0x5c, 0xda, 0x5f, 0x90, 0xa4] + + XCTAssertEqual(try Poly1305(key: key).authenticate(msg), expectedMac) + + // extensions + let msgData = Data( msg) + XCTAssertEqual(try msgData.authenticate(with: Poly1305(key: key)), Data( expectedMac), "Invalid authentication result") + } + + // https://github.com/krzyzanowskim/CryptoSwift/issues/183 + func testIssue183() { + let key: Array = [111, 53, 197, 181, 1, 92, 67, 199, 37, 92, 76, 167, 12, 35, 75, 226, 198, 34, 107, 84, 79, 6, 231, 10, 25, 221, 14, 155, 81, 244, 15, 203] + let message: Array = [208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 210, 40, 78, 3, 161, 87, 187, 96, 253, 104, 187, 87, 87, 249, 56, 5, 156, 122, 121, 196, 192, 254, 58, 98, 22, 47, 151, 205, 201, 108, 143, 197, 99, 182, 109, 59, 63, 172, 111, 120, 185, 175, 129, 59, 126, 68, 140, 237, 126, 175, 49, 224, 249, 245, 37, 75, 252, 69, 215, 171, 27, 163, 16, 185, 239, 184, 144, 37, 131, 242, 12, 90, 134, 24, 237, 209, 127, 71, 86, 122, 173, 238, 73, 186, 58, 102, 112, 90, 217, 243, 251, 110, 85, 106, 18, 172, 167, 179, 173, 73, 125, 9, 129, 132, 80, 70, 4, 254, 178, 211, 200, 207, 231, 232, 17, 176, 127, 153, 120, 71, 164, 139, 56, 106, 71, 96, 79, 11, 213, 243, 66, 53, 167, 108, 233, 250, 136, 69, 190, 191, 12, 136, 24, 157, 202, 49, 158, 152, 150, 34, 88, 132, 112, 74, 168, 153, 116, 31, 7, 61, 60, 22, 199, 108, 187, 209, 114, 234, 185, 247, 41, 68, 184, 95, 169, 60, 126, 73, 59, 54, 126, 162, 90, 18, 32, 230, 123, 2, 40, 74, 177, 127, 219, 93, 186, 22, 75, 251, 101, 95, 160, 68, 235, 77, 2, 10, 202, 2, 0, 0, 0, 0, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0] + let expectedMac: Array = [68, 216, 92, 163, 164, 144, 55, 43, 185, 18, 83, 92, 41, 133, 72, 168] + XCTAssertEqual(try message.authenticate(with: Poly1305(key: key)), expectedMac) + } + + static let allTests = [ + ("testPoly1305", testPoly1305), + ("testIssue183", testIssue183), + ] +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/RabbitTests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/RabbitTests.swift new file mode 100644 index 0000000000..695bee27e1 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/RabbitTests.swift @@ -0,0 +1,128 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import XCTest + +class RabbitTests: XCTestCase { + func testInitialization() { + var key = Array(repeating: 0, count: Rabbit.keySize - 1) + var iv: Array? + XCTAssertThrowsError(try Rabbit(key: key, iv: iv)) + + key = Array(repeating: 0, count: Rabbit.keySize + 1) + XCTAssertThrowsError(try Rabbit(key: key, iv: iv)) + + key = Array(repeating: 0, count: Rabbit.keySize) + XCTAssertNotNil(try Rabbit(key: key, iv: iv)) + + iv = Array(repeating: 0, count: Rabbit.ivSize - 1) + XCTAssertThrowsError(try Rabbit(key: key, iv: iv)) + + iv = Array(repeating: 0, count: Rabbit.ivSize) + XCTAssertNotNil(try Rabbit(key: key, iv: iv)) + } + + func testRabbitWithoutIV() { + // Examples from Appendix A: Test Vectors in http://tools.ietf.org/rfc/rfc4503.txt + let cases: [(Array, Array)] = [ // First case + ( + [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + [ + 0xb1, 0x57, 0x54, 0xf0, 0x36, 0xa5, 0xd6, 0xec, 0xf5, 0x6b, 0x45, 0x26, 0x1c, 0x4a, 0xf7, 0x02, + 0x88, 0xe8, 0xd8, 0x15, 0xc5, 0x9c, 0x0c, 0x39, 0x7b, 0x69, 0x6c, 0x47, 0x89, 0xc6, 0x8a, 0xa7, + 0xf4, 0x16, 0xa1, 0xc3, 0x70, 0x0c, 0xd4, 0x51, 0xda, 0x68, 0xd1, 0x88, 0x16, 0x73, 0xd6, 0x96, + ] + ), + // Second case + ( + [0x91, 0x28, 0x13, 0x29, 0x2e, 0x3d, 0x36, 0xfe, 0x3b, 0xfc, 0x62, 0xf1, 0xdc, 0x51, 0xc3, 0xac], + [ + 0x3d, 0x2d, 0xf3, 0xc8, 0x3e, 0xf6, 0x27, 0xa1, 0xe9, 0x7f, 0xc3, 0x84, 0x87, 0xe2, 0x51, 0x9c, + 0xf5, 0x76, 0xcd, 0x61, 0xf4, 0x40, 0x5b, 0x88, 0x96, 0xbf, 0x53, 0xaa, 0x85, 0x54, 0xfc, 0x19, + 0xe5, 0x54, 0x74, 0x73, 0xfb, 0xdb, 0x43, 0x50, 0x8a, 0xe5, 0x3b, 0x20, 0x20, 0x4d, 0x4c, 0x5e, + ] + ), + // Third case + ( + [0x83, 0x95, 0x74, 0x15, 0x87, 0xe0, 0xc7, 0x33, 0xe9, 0xe9, 0xab, 0x01, 0xc0, 0x9b, 0x00, 0x43], + [ + 0x0c, 0xb1, 0x0d, 0xcd, 0xa0, 0x41, 0xcd, 0xac, 0x32, 0xeb, 0x5c, 0xfd, 0x02, 0xd0, 0x60, 0x9b, + 0x95, 0xfc, 0x9f, 0xca, 0x0f, 0x17, 0x01, 0x5a, 0x7b, 0x70, 0x92, 0x11, 0x4c, 0xff, 0x3e, 0xad, + 0x96, 0x49, 0xe5, 0xde, 0x8b, 0xfc, 0x7f, 0x3f, 0x92, 0x41, 0x47, 0xad, 0x3a, 0x94, 0x74, 0x28, + ] + ), + ] + + let plainText = Array(repeating: 0, count: 48) + for (key, expectedCipher) in cases { + let rabbit = try! Rabbit(key: key) + let cipherText = try! rabbit.encrypt(plainText) + XCTAssertEqual(cipherText, expectedCipher) + XCTAssertEqual(try! rabbit.decrypt(cipherText), plainText) + } + } + + func testRabbitWithIV() { + // Examples from Appendix A: Test Vectors in http://tools.ietf.org/rfc/rfc4503.txt + let key = Array(repeating: 0, count: Rabbit.keySize) + let cases: [(Array, Array)] = [ + ( + [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + [ + 0xc6, 0xa7, 0x27, 0x5e, 0xf8, 0x54, 0x95, 0xd8, 0x7c, 0xcd, 0x5d, 0x37, 0x67, 0x05, 0xb7, 0xed, + 0x5f, 0x29, 0xa6, 0xac, 0x04, 0xf5, 0xef, 0xd4, 0x7b, 0x8f, 0x29, 0x32, 0x70, 0xdc, 0x4a, 0x8d, + 0x2a, 0xde, 0x82, 0x2b, 0x29, 0xde, 0x6c, 0x1e, 0xe5, 0x2b, 0xdb, 0x8a, 0x47, 0xbf, 0x8f, 0x66, + ] + ), + ( + [0xc3, 0x73, 0xf5, 0x75, 0xc1, 0x26, 0x7e, 0x59], + [ + 0x1f, 0xcd, 0x4e, 0xb9, 0x58, 0x00, 0x12, 0xe2, 0xe0, 0xdc, 0xcc, 0x92, 0x22, 0x01, 0x7d, 0x6d, + 0xa7, 0x5f, 0x4e, 0x10, 0xd1, 0x21, 0x25, 0x01, 0x7b, 0x24, 0x99, 0xff, 0xed, 0x93, 0x6f, 0x2e, + 0xeb, 0xc1, 0x12, 0xc3, 0x93, 0xe7, 0x38, 0x39, 0x23, 0x56, 0xbd, 0xd0, 0x12, 0x02, 0x9b, 0xa7, + ] + ), + ( + [0xa6, 0xeb, 0x56, 0x1a, 0xd2, 0xf4, 0x17, 0x27], + [ + 0x44, 0x5a, 0xd8, 0xc8, 0x05, 0x85, 0x8d, 0xbf, 0x70, 0xb6, 0xaf, 0x23, 0xa1, 0x51, 0x10, 0x4d, + 0x96, 0xc8, 0xf2, 0x79, 0x47, 0xf4, 0x2c, 0x5b, 0xae, 0xae, 0x67, 0xc6, 0xac, 0xc3, 0x5b, 0x03, + 0x9f, 0xcb, 0xfc, 0x89, 0x5f, 0xa7, 0x1c, 0x17, 0x31, 0x3d, 0xf0, 0x34, 0xf0, 0x15, 0x51, 0xcb, + ] + ), + ] + + let plainText = Array(repeating: 0, count: 48) + for (iv, expectedCipher) in cases { + let rabbit = try! Rabbit(key: key, iv: iv) + let cipherText = try! rabbit.encrypt(plainText) + XCTAssertEqual(cipherText, expectedCipher) + XCTAssertEqual(try! rabbit.decrypt(cipherText), plainText) + } + } +} + +extension RabbitTests { + static func allTests() -> [(String, (RabbitTests) -> () -> Void)] { + let tests = [ + ("testInitialization", testInitialization), + ("testRabbitWithoutIV", testRabbitWithoutIV), + ("testRabbitWithIV", testRabbitWithIV), + ] + + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/RabbitTestsPerf.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/RabbitTestsPerf.swift new file mode 100644 index 0000000000..2b4cd09f3f --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/RabbitTestsPerf.swift @@ -0,0 +1,37 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import XCTest + +class RabbitTestsPerf: XCTestCase { + func testRabbitPerformance() { + let key: Array = Array(repeating: 0, count: Rabbit.keySize) + let iv: Array = Array(repeating: 0, count: Rabbit.ivSize) + let message = Array(repeating: 7, count: (1024 * 1024) * 1) + measure { + _ = try! Rabbit(key: key, iv: iv).encrypt(message) + } + } +} + +extension RabbitTestsPerf { + static func allTests() -> [(String, (RabbitTestsPerf) -> () -> Void)] { + let tests = [ + ("testRabbitPerformance", testRabbitPerformance), + ] + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/RandomBytesSequenceTests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/RandomBytesSequenceTests.swift new file mode 100644 index 0000000000..bcc521b685 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/RandomBytesSequenceTests.swift @@ -0,0 +1,29 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import XCTest + +class RandomBytesSequenceTests: XCTestCase { + func testSequence() { + XCTAssertNil(RandomBytesSequence(size: 0).makeIterator().next()) + + for value in RandomBytesSequence(size: 100) { + XCTAssertTrue(value <= UInt8.max) + } + } + + static let allTests = [("testSequence", testSequence)] +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/ScryptTests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ScryptTests.swift new file mode 100644 index 0000000000..7a495cef62 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ScryptTests.swift @@ -0,0 +1,71 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +@testable import CryptoSwift +import XCTest + +class Scrypt: XCTestCase { + + func testScrypt_0() { + let password = Array("password".data(using: .ascii)!) + let salt = Array("NaCl".data(using: .ascii)!) + let deriver = try! CryptoSwift.Scrypt(password: password, salt: salt, dkLen: 64, N: 1024, r: 8, p: 16) + let derived = try! deriver.calculate() + let expected: [UInt8] = Array.init(hex: """ + fd ba be 1c 9d 34 72 00 78 56 e7 19 0d 01 e9 fe + 7c 6a d7 cb c8 23 78 30 e7 73 76 63 4b 37 31 62 + 2e af 30 d9 2e 22 a3 88 6f f1 09 27 9d 98 30 da + c7 27 af b9 4a 83 ee 6d 83 60 cb df a2 cc 06 40 +""".replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "\n", with: "").replacingOccurrences(of: "\t", with: "")) + XCTAssertEqual(derived, expected) + } + + func testScrypt_1() { + let password = Array("pleaseletmein".data(using: .ascii)!) + let salt = Array("SodiumChloride".data(using: .ascii)!) + let deriver = try! CryptoSwift.Scrypt(password: password, salt: salt, dkLen: 64, N: 16384, r: 8, p: 1) + let derived = try! deriver.calculate() + let expected: [UInt8] = Array.init(hex: """ + 70 23 bd cb 3a fd 73 48 46 1c 06 cd 81 fd 38 eb + fd a8 fb ba 90 4f 8e 3e a9 b5 43 f6 54 5d a1 f2 + d5 43 29 55 61 3f 0f cf 62 d4 97 05 24 2a 9a f9 + e6 1e 85 dc 0d 65 1e 40 df cf 01 7b 45 57 58 87 +""".replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "\n", with: "").replacingOccurrences(of: "\t", with: "")) + XCTAssertEqual(derived, expected) + } + +// Takes too long to run in debug mode! + func testScrypt_2() { + #if !DEBUG + let password = Array("pleaseletmein".data(using: .ascii)!) + let salt = Array("SodiumChloride".data(using: .ascii)!) + let deriver = try! CryptoSwift.Scrypt(password: password, salt: salt, dkLen: 64, N: 1048576, r: 8, p: 1) + let derived = try! deriver.calculate() + let expected: [UInt8] = Array.init(hex: """ + 21 01 cb 9b 6a 51 1a ae ad db be 09 cf 70 f8 81 + ec 56 8d 57 4a 2f fd 4d ab e5 ee 98 20 ad aa 47 + 8e 56 fd 8f 4b a5 d0 9f fa 1c 6d 92 7c 40 f4 c3 + 37 30 40 49 e8 a9 52 fb cb f4 5c 6f a7 7a 41 a4 +""".replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "\n", with: "").replacingOccurrences(of: "\t", with: "")) + XCTAssertEqual(derived, expected) + #endif + } + + static let allTests = [ + ("testScrypt_0", testScrypt_0), + ("testScrypt_1", testScrypt_1), + ("testScrypt_2", testScrypt_2) + ] +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/ScryptTestsPerf.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ScryptTestsPerf.swift new file mode 100644 index 0000000000..4016e13a92 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/ScryptTestsPerf.swift @@ -0,0 +1,39 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + + +@testable import CryptoSwift +import XCTest + +class ScryptTestsPeft: XCTestCase { + func testScryptPerformance() { + let N = 16384 + let password: Array = Array(repeating: 0, count: 32) + let salt: Array = Array(repeating: 0, count: 32) + measure { + _ = try! CryptoSwift.Scrypt(password: password, salt: salt, dkLen: 64, N: N, r: 8, p: 1).calculate() + } + } + +} + +extension ScryptTestsPeft { + static func allTests() -> [(String, (ScryptTestsPeft) -> () -> Void)] { + let tests = [ + ("testScryptPerformance", testScryptPerformance), + ] + return tests + } +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/Tests/XCTestManifests.swift b/Carthage/Checkouts/CryptoSwift/Tests/Tests/XCTestManifests.swift new file mode 100644 index 0000000000..3ea457e0fb --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/Tests/XCTestManifests.swift @@ -0,0 +1,363 @@ +#if !canImport(ObjectiveC) +import XCTest + +extension AESCCMTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__AESCCMTests = [ + ("testAESCCMTestCase1", testAESCCMTestCase1), + ("testAESCCMTestCase1Decrypt", testAESCCMTestCase1Decrypt), + ("testAESCCMTestCase2", testAESCCMTestCase2), + ("testAESCCMTestCase2Decrypt", testAESCCMTestCase2Decrypt), + ("testAESCCMTestCase3", testAESCCMTestCase3), + ("testAESCCMTestCase3Decrypt", testAESCCMTestCase3Decrypt), + ("testAESCCMTestCase3DecryptPartial", testAESCCMTestCase3DecryptPartial), + ("testAESCCMTestDVPT256", testAESCCMTestDVPT256), + ] +} + +extension AESTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__AESTests = [ + ("testAESDecryptCBCWithPaddingPartial", testAESDecryptCBCWithPaddingPartial), + ("testAESDecryptCTRSeek", testAESDecryptCTRSeek), + ("testAESEncrypt", testAESEncrypt), + ("testAESEncrypt2", testAESEncrypt2), + ("testAESEncrypt3", testAESEncrypt3), + ("testAESEncryptCBCNoPadding", testAESEncryptCBCNoPadding), + ("testAESEncryptCBCWithPadding", testAESEncryptCBCWithPadding), + ("testAESEncryptCBCWithPaddingPartial", testAESEncryptCBCWithPaddingPartial), + ("testAESEncryptCFB", testAESEncryptCFB), + ("testAESEncryptCFBLong", testAESEncryptCFBLong), + ("testAESEncryptCTR", testAESEncryptCTR), + ("testAESEncryptCTRIrregularLength", testAESEncryptCTRIrregularLength), + ("testAESEncryptCTRIrregularLengthIncrementalUpdate", testAESEncryptCTRIrregularLengthIncrementalUpdate), + ("testAESEncryptCTRStream", testAESEncryptCTRStream), + ("testAESEncryptCTRZeroPadding", testAESEncryptCTRZeroPadding), + ("testAESEncryptIncremental", testAESEncryptIncremental), + ("testAESEncryptOFB128", testAESEncryptOFB128), + ("testAESEncryptOFB256", testAESEncryptOFB256), + ("testAESEncryptPCBC256", testAESEncryptPCBC256), + ("testAESGCMTagLengthCombined", testAESGCMTagLengthCombined), + ("testAESGCMTagLengthCombined2", testAESGCMTagLengthCombined2), + ("testAESGCMTagLengthDetached", testAESGCMTagLengthDetached), + ("testAESGCMTestCase1", testAESGCMTestCase1), + ("testAESGCMTestCase2", testAESGCMTestCase2), + ("testAESGCMTestCase3", testAESGCMTestCase3), + ("testAESGCMTestCase3Combined", testAESGCMTestCase3Combined), + ("testAESGCMTestCase4", testAESGCMTestCase4), + ("testAESGCMTestCase5", testAESGCMTestCase5), + ("testAESGCMTestCase6", testAESGCMTestCase6), + ("testAESGCMTestCase7", testAESGCMTestCase7), + ("testAESGCMTestCaseIrregularCombined1", testAESGCMTestCaseIrregularCombined1), + ("testAESGCMTestCaseIrregularCombined2", testAESGCMTestCaseIrregularCombined2), + ("testAESWithWrongKey", testAESWithWrongKey), + ("testIssue298", testIssue298), + ("testIssue394", testIssue394), + ("testIssue411", testIssue411), + ] +} + +extension AESTestsPerf { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__AESTestsPerf = [ + ("testAESDecryptPerformance", testAESDecryptPerformance), + ("testAESEncryptPerformance", testAESEncryptPerformance), + ] +} + +extension Access { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__Access = [ + ("testAES", testAES), + ("testArrayExtension", testArrayExtension), + ("testAuthenticators", testAuthenticators), + ("testBlowfish", testBlowfish), + ("testChaCha20", testChaCha20), + ("testChecksum", testChecksum), + ("testCollectionExtension", testCollectionExtension), + ("testDataExtension", testDataExtension), + ("testDigest", testDigest), + ("testIntExtension", testIntExtension), + ("testPadding", testPadding), + ("testPBKDF", testPBKDF), + ("testRabbit", testRabbit), + ("testRandomIV", testRandomIV), + ("testStringExtension", testStringExtension), + ("testStringFoundationExtension", testStringFoundationExtension), + ("testUInt16Extension", testUInt16Extension), + ("testUInt32Extension", testUInt32Extension), + ("testUInt64Extension", testUInt64Extension), + ("testUInt8Extension", testUInt8Extension), + ("testUpdatable", testUpdatable), + ] +} + +extension BlowfishTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__BlowfishTests = [ + ("testCBCZeroPadding", testCBCZeroPadding), + ("testDecrypt", testDecrypt), + ("testDecryptCFB415", testDecryptCFB415), + ("testEncrypt", testEncrypt), + ("testEncryptDecrypt", testEncryptDecrypt), + ] +} + +extension CMACTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__CMACTests = [ + ("testMessageLength0", testMessageLength0), + ("testMessageLength16", testMessageLength16), + ("testMessageLength40", testMessageLength40), + ("testMessageLength64", testMessageLength64), + ] +} + +extension ChaCha20Poly1305Tests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__ChaCha20Poly1305Tests = [ + ("test1", test1), + ("test2", test2), + ("test3", test3), + ] +} + +extension ChaCha20Tests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__ChaCha20Tests = [ + ("testChaCha20", testChaCha20), + ("testChaCha20EncryptPartial", testChaCha20EncryptPartial), + ("testCore", testCore), + ("testVector1Py", testVector1Py), + ] +} + +extension ChaCha20TestsPerf { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__ChaCha20TestsPerf = [ + ("testChaCha20Performance", testChaCha20Performance), + ] +} + +extension DigestTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__DigestTests = [ + ("testChecksum", testChecksum), + ("testCRC16", testCRC16), + ("testCRC32", testCRC32), + ("testCRC32C", testCRC32C), + ("testCRC32NotReflected", testCRC32NotReflected), + ("testMD5", testMD5), + ("testMD5Data", testMD5Data), + ("testMD5Updates", testMD5Updates), + ("testSHA1", testSHA1), + ("testSHA1Updatable1", testSHA1Updatable1), + ("testSHA1Updatable2", testSHA1Updatable2), + ("testSHA2", testSHA2), + ("testSHA3", testSHA3), + ("testSHAPartialUpdates", testSHAPartialUpdates), + ] +} + +extension DigestTestsPerf { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__DigestTestsPerf = [ + ("testMD5Performance", testMD5Performance), + ("testSHA1Performance", testSHA1Performance), + ] +} + +extension ExtensionsTest { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__ExtensionsTest = [ + ("testArrayInitHex", testArrayInitHex), + ("testBytes", testBytes), + ("testDataInit", testDataInit), + ("testEmptyStringEncrypt", testEmptyStringEncrypt), + ("testStringDecryptBase64", testStringDecryptBase64), + ("testStringEncrypt", testStringEncrypt), + ("testToUInt32Array", testToUInt32Array), + ] +} + +extension ExtensionsTestPerf { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__ExtensionsTestPerf = [ + ("testArrayInitHexPerformance", testArrayInitHexPerformance), + ] +} + +extension HKDFTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__HKDFTests = [ + ("testHKDF1", testHKDF1), + ("testHKDF2", testHKDF2), + ("testHKDF3", testHKDF3), + ("testHKDF4", testHKDF4), + ("testHKDF5", testHKDF5), + ("testHKDF6", testHKDF6), + ] +} + +extension HMACTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__HMACTests = [ + ("testMD5", testMD5), + ("testSHA1", testSHA1), + ("testSHA256", testSHA256), + ("testSHA384", testSHA384), + ("testSHA512", testSHA512), + ] +} + +extension PBKDF { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__PBKDF = [ + ("testPBKDF1", testPBKDF1), + ("testPBKDF2", testPBKDF2), + ("testPBKDF2Length", testPBKDF2Length), + ] +} + +extension PBKDFPerf { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__PBKDFPerf = [ + ("testPerformance", testPerformance), + ] +} + +extension PaddingTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__PaddingTests = [ + ("testPKCS7_0", testPKCS7_0), + ("testPKCS7_1", testPKCS7_1), + ("testPKCS7_2", testPKCS7_2), + ("testZeroPadding1", testZeroPadding1), + ("testZeroPadding2", testZeroPadding2), + ] +} + +extension Poly1305Tests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__Poly1305Tests = [ + ("testIssue183", testIssue183), + ("testPoly1305", testPoly1305), + ] +} + +extension RabbitTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__RabbitTests = [ + ("testInitialization", testInitialization), + ("testRabbitWithIV", testRabbitWithIV), + ("testRabbitWithoutIV", testRabbitWithoutIV), + ] +} + +extension RabbitTestsPerf { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__RabbitTestsPerf = [ + ("testRabbitPerformance", testRabbitPerformance), + ] +} + +extension RandomBytesSequenceTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__RandomBytesSequenceTests = [ + ("testSequence", testSequence), + ] +} + +extension Scrypt { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__Scrypt = [ + ("testScrypt_0", testScrypt_0), + ("testScrypt_1", testScrypt_1), + ("testScrypt_2", testScrypt_2), + ] +} + +extension ScryptTestsPeft { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__ScryptTestsPeft = [ + ("testScryptPerformance", testScryptPerformance), + ] +} + +public func __allTests() -> [XCTestCaseEntry] { + return [ + testCase(AESCCMTests.__allTests__AESCCMTests), + testCase(AESTests.__allTests__AESTests), + testCase(AESTestsPerf.__allTests__AESTestsPerf), + testCase(Access.__allTests__Access), + testCase(BlowfishTests.__allTests__BlowfishTests), + testCase(CMACTests.__allTests__CMACTests), + testCase(ChaCha20Poly1305Tests.__allTests__ChaCha20Poly1305Tests), + testCase(ChaCha20Tests.__allTests__ChaCha20Tests), + testCase(ChaCha20TestsPerf.__allTests__ChaCha20TestsPerf), + testCase(DigestTests.__allTests__DigestTests), + testCase(DigestTestsPerf.__allTests__DigestTestsPerf), + testCase(ExtensionsTest.__allTests__ExtensionsTest), + testCase(ExtensionsTestPerf.__allTests__ExtensionsTestPerf), + testCase(HKDFTests.__allTests__HKDFTests), + testCase(HMACTests.__allTests__HMACTests), + testCase(PBKDF.__allTests__PBKDF), + testCase(PBKDFPerf.__allTests__PBKDFPerf), + testCase(PaddingTests.__allTests__PaddingTests), + testCase(Poly1305Tests.__allTests__Poly1305Tests), + testCase(RabbitTests.__allTests__RabbitTests), + testCase(RabbitTestsPerf.__allTests__RabbitTestsPerf), + testCase(RandomBytesSequenceTests.__allTests__RandomBytesSequenceTests), + testCase(Scrypt.__allTests__Scrypt), + testCase(ScryptTestsPeft.__allTests__ScryptTestsPeft), + ] +} +#endif diff --git a/Carthage/Checkouts/CryptoSwift/Tests/TestsPerformance/Bridging.h b/Carthage/Checkouts/CryptoSwift/Tests/TestsPerformance/Bridging.h new file mode 100644 index 0000000000..9ec068ec90 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/TestsPerformance/Bridging.h @@ -0,0 +1,21 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2017 Marcin Krzyżanowski +// 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. +// + +#ifndef CryptoSwift_Bridging_h +#define CryptoSwift_Bridging_h + +#import + +#endif diff --git a/Carthage/Checkouts/CryptoSwift/Tests/TestsPerformance/Info.plist b/Carthage/Checkouts/CryptoSwift/Tests/TestsPerformance/Info.plist new file mode 100644 index 0000000000..6c40a6cd0c --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/TestsPerformance/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/CryptoSwift/Tests/TestsPerformance/TestsPerformance.swift b/Carthage/Checkouts/CryptoSwift/Tests/TestsPerformance/TestsPerformance.swift new file mode 100644 index 0000000000..90e50553c2 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/TestsPerformance/TestsPerformance.swift @@ -0,0 +1,35 @@ +// +// TestsPerformance.swift +// TestsPerformance +// +// Created by Marcin Krzyzanowski on 03/04/2018. +// Copyright © 2018 Marcin Krzyzanowski. All rights reserved. +// + +import XCTest + +class TestsPerformance: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Carthage/Checkouts/CryptoSwift/Tests/TestsPerformance/XCTestManifests.swift b/Carthage/Checkouts/CryptoSwift/Tests/TestsPerformance/XCTestManifests.swift new file mode 100644 index 0000000000..bd30b2f16a --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/Tests/TestsPerformance/XCTestManifests.swift @@ -0,0 +1,19 @@ +#if !canImport(ObjectiveC) +import XCTest + +extension TestsPerformance { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__TestsPerformance = [ + ("testExample", testExample), + ("testPerformanceExample", testPerformanceExample), + ] +} + +public func __allTests() -> [XCTestCaseEntry] { + return [ + testCase(TestsPerformance.__allTests__TestsPerformance), + ] +} +#endif diff --git a/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-Debug.xcconfig b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-Debug.xcconfig new file mode 100644 index 0000000000..d54da94d06 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-Debug.xcconfig @@ -0,0 +1,36 @@ +// +// CryptoSwift-Debug.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +#include "CryptoSwift-Shared.xcconfig" + + +// Other Swift Flags +// +// A list of additional flags to pass to the Swift compiler. + +OTHER_SWIFT_FLAGS = $(inherited) -Xfrontend -debug-time-function-bodies + + + +SWIFT_COMPILATION_MODE = incremental + +// Swift Optimization Level +// +// * *None:* Compile without any optimization. [-Onone] +// * *Optimize for Speed:* [-O] +// * *Optimize for Size:* [-Osize] +// * *Whole Module Optimization:* [-O -whole-module-optimization] + +SWIFT_OPTIMIZATION_LEVEL = -Onone + + + +// Exclusive Access to Memory +// +// Enforce exclusive access to memory + +SWIFT_ENFORCE_EXCLUSIVE_ACCESS = none diff --git a/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-Release.xcconfig b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-Release.xcconfig new file mode 100644 index 0000000000..891a8953b6 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-Release.xcconfig @@ -0,0 +1,82 @@ +// +// CryptoSwift-Release.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +#include "CryptoSwift-Shared.xcconfig" + + +BITCODE_GENERATION_MODE = bitcode + + + +// Use Optimization Profile +// +// When this setting is enabled, `clang` will use the optimization profile collected for +// a target when building it. + +CLANG_USE_OPTIMIZATION_PROFILE = NO + + + +// Generate Debug Symbols +// +// Enables or disables generation of debug symbols. When debug symbols are enabled, the +// level of detail can be controlled by the `DEBUG_INFORMATION_FORMAT` setting. + +GCC_GENERATE_DEBUGGING_SYMBOLS = NO + + + +// Unroll Loops +// +// Unrolls loops. Unrolling makes the code larger, but may make it faster by reducing the +// number of branches executed. + +GCC_UNROLL_LOOPS = YES + + + +// Link-Time Optimization +// +// Enabling this setting allows optimization across file boundaries during linking. +// +// * *No:* Disabled. Do not use link-time optimization. +// * *Monolithic Link-Time Optimization:* This mode performs monolithic link-time +// optimization of binaries, combining all executable code into a single unit and running +// aggressive compiler optimizations. +// * *Incremental Link-Time Optimization:* This mode performs partitioned link-time +// optimization of binaries, inlining between compilation units and running aggressive +// compiler optimizations on each unit in parallel. This enables fast incremental builds +// and uses less memory than Monolithic LTO. + +LLVM_LTO = YES + + + +// Disable Safety Checks +// +// Disable runtime safety checks when optimizing. + +SWIFT_DISABLE_SAFETY_CHECKS = YES + + + +// Exclusive Access to Memory +// +// Enforce exclusive access to memory + +SWIFT_ENFORCE_EXCLUSIVE_ACCESS = compile-time + + + +// Swift Optimization Level +// +// * *None:* Compile without any optimization. [-Onone] +// * *Optimize for Speed:* [-O] +// * *Optimize for Size:* [-Osize] +// * *Whole Module Optimization:* [-O -whole-module-optimization] + +SWIFT_OPTIMIZATION_LEVEL = -O diff --git a/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-Shared.xcconfig b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-Shared.xcconfig new file mode 100644 index 0000000000..6dd3c3a4f4 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-Shared.xcconfig @@ -0,0 +1,151 @@ +// +// CryptoSwift-Shared.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES + +// Require Only App-Extension-Safe API +// +// When enabled, this causes the compiler and linker to disallow use of APIs that are not +// available to app extensions and to disallow linking to frameworks that have not been +// built with this setting enabled. + +APPLICATION_EXTENSION_API_ONLY = YES + + + +// Compatibility Version +// +// Determines the compatibility version of the resulting library, bundle, or framework +// binary. See [Dynamic Library Design +// Guidelines](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html#//apple_ref/doc/uid/TP40002013-SW19) +// in [Dynamic Library Programming +// Topics](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/000-Introduction/Introduction.html) +// for details on assigning version numbers of dynamic libraries. + +DYLIB_COMPATIBILITY_VERSION = 1 + + + +// Current Library Version +// +// This setting defines the current version of any framework built by the project. As +// with `CURRENT_PROJECT_VERSION`, the value must be an integer or floating point number, +// such as `57` or `365.8`. By default, it is set to `$(CURRENT_PROJECT_VERSION)`. See +// [Dynamic Library Design +// Guidelines](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html#//apple_ref/doc/uid/TP40002013-SW19) +// in [Dynamic Library Programming +// Topics](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/000-Introduction/Introduction.html) +// for details on assigning version numbers of dynamic libraries. + +DYLIB_CURRENT_VERSION = 1 + + + +// Dynamic Library Install Name Base +// +// Sets the base value for the internal `install path` (`LC_ID_DYLIB`) in a dynamic +// library. This will be combined with the `EXECUTABLE_PATH` to form the full install +// path. Setting `LD_DYLIB_INSTALL_NAME` directly will override this setting. This +// setting defaults to the target's `INSTALL_PATH`. It is ignored when building any +// product other than a dynamic library. + +DYLIB_INSTALL_NAME_BASE = @rpath + + + +// Enable Bitcode +// +// Activating this setting indicates that the target or project should generate bitcode +// during compilation for platforms and architectures that support it. For Archive +// builds, bitcode will be generated in the linked binary for submission to the App +// Store. For other builds, the compiler and linker will check whether the code complies +// with the requirements for bitcode generation, but will not generate actual bitcode. + +ENABLE_BITCODE = YES + + + +// Enable Bitcode +// +// Activating this setting indicates that the target or project should generate bitcode +// during compilation for platforms and architectures that support it. For Archive +// builds, bitcode will be generated in the linked binary for submission to the App +// Store. For other builds, the compiler and linker will check whether the code complies +// with the requirements for bitcode generation, but will not generate actual bitcode. + +ENABLE_BITCODE[sdk=macosx*] = NO + + + +// Installation Directory +// +// The directory in which to install the build products. This path is prepended by the +// `DSTROOT`. + +INSTALL_PATH = $(LOCAL_LIBRARY_DIR)/Frameworks + + +// Runpath Search Paths +// +// This is a list of paths to be added to the `runpath` search path list for the image +// being created. At runtime, `dyld` uses the `runpath` when searching for dylibs whose +// load path begins with `@rpath/`. See [Dynamic Library Programming +// Topics](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/000-Introduction/Introduction.html). + +LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks @loader_path/Frameworks + +// Info.plist File +// +// The project-relative path to the property list file that contains the `Info.plist` +// information used by bundles. For details on information property list files, see +// [Information Property List +// Files](https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigFiles.html#//apple_ref/doc/uid/20002091-CJBJIEDH) +// in [Runtime Configuration +// Guidelines](https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPRuntimeConfig/000-Introduction/introduction.html). + +INFOPLIST_FILE = Sources/CryptoSwift/Info.plist + +// Product Bundle Identifier +// +// A string that uniquely identifies the bundle. The string should be in reverse DNS +// format using only alphanumeric characters (`A-Z`, `a-z`, `0-9`), the dot (`.`), and +// the hyphen (`-`). This value is used as the `CFBundleIdentifier` in the `Info.plist` +// of the built bundle. + +PRODUCT_BUNDLE_IDENTIFIER = com.krzyzanowskim.${PRODUCT_NAME:rfc1034identifier} + + + +// Product Name +// +// This is the basename of the product generated by the target. + +PRODUCT_NAME = $(TARGET_NAME) + + + +// Skip Install +// +// If enabled, don't install built products even if deployment locations are active. + +SKIP_INSTALL = YES + + + +// Swift Language Version +// +// + +SWIFT_VERSION = 5.0 + + + +TVOS_DEPLOYMENT_TARGET = 9.0 + + + +WATCHOS_DEPLOYMENT_TARGET = 2.0 diff --git a/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-Test.xcconfig b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-Test.xcconfig new file mode 100644 index 0000000000..a5fd16b54c --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-Test.xcconfig @@ -0,0 +1,72 @@ +// +// CryptoSwift-Test.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +#include "CryptoSwift-Shared.xcconfig" + + +BITCODE_GENERATION_MODE = bitcode + + + +// Unroll Loops +// +// Unrolls loops. Unrolling makes the code larger, but may make it faster by reducing the +// number of branches executed. + +GCC_UNROLL_LOOPS = YES + + + +// Link-Time Optimization +// +// Enabling this setting allows optimization across file boundaries during linking. +// +// * *No:* Disabled. Do not use link-time optimization. +// * *Monolithic Link-Time Optimization:* This mode performs monolithic link-time +// optimization of binaries, combining all executable code into a single unit and running +// aggressive compiler optimizations. +// * *Incremental Link-Time Optimization:* This mode performs partitioned link-time +// optimization of binaries, inlining between compilation units and running aggressive +// compiler optimizations on each unit in parallel. This enables fast incremental builds +// and uses less memory than Monolithic LTO. + +LLVM_LTO = YES + + + +// Other Swift Flags +// +// A list of additional flags to pass to the Swift compiler. + +OTHER_SWIFT_FLAGS = $(inherited) -Xfrontend -debug-time-function-bodies + + + +// Disable Safety Checks +// +// Disable runtime safety checks when optimizing. + +SWIFT_DISABLE_SAFETY_CHECKS = YES + + + +// Exclusive Access to Memory +// +// Enforce exclusive access to memory + +SWIFT_ENFORCE_EXCLUSIVE_ACCESS = compile-time + + + +// Swift Optimization Level +// +// * *None:* Compile without any optimization. [-Onone] +// * *Optimize for Speed:* [-O] +// * *Optimize for Size:* [-Osize] +// * *Whole Module Optimization:* [-O -whole-module-optimization] + +SWIFT_OPTIMIZATION_LEVEL = -O diff --git a/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-TestHostApp-Debug.xcconfig b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-TestHostApp-Debug.xcconfig new file mode 100644 index 0000000000..04f3bb2183 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-TestHostApp-Debug.xcconfig @@ -0,0 +1,112 @@ +// +// CryptoSwift-TestHostApp-Debug.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +#include "CryptoSwift-TestHostApp-Shared.xcconfig" + + +// Debug Information Format +// +// The type of debug information to produce. +// +// * *DWARF:* Object files and linked products will use DWARF as the debug information +// format. [dwarf] +// * *DWARF with dSYM File:* Object files and linked products will use DWARF as the debug +// information format, and Xcode will also produce a dSYM file containing the debug +// information from the individual object files (except that a dSYM file is not needed +// and will not be created for static library or object file products). [dwarf-with-dsym] + +DEBUG_INFORMATION_FORMAT = dwarf + + + +// Enable Testability +// +// When this setting is activated, the product will be built with options appropriate for +// running automated tests, such as making private interfaces accessible to the tests. +// This may result in tests running slower than they would without testability enabled. + +ENABLE_TESTABILITY = YES + + + +// Generate Position-Dependent Code +// +// Faster function calls for applications. Not appropriate for shared libraries, which +// need to be position-independent. + +GCC_DYNAMIC_NO_PIC = NO + + + +// Optimization Level +// +// Specifies the degree to which the generated code is optimized for speed and binary +// size. +// +// * *None:* Do not optimize. [-O0] +// With this setting, the compiler's goal is to reduce the cost of compilation and to +// make debugging produce the expected results. Statements are independent—if you stop +// the program with a breakpoint between statements, you can then assign a new value to +// any variable or change the program counter to any other statement in the function and +// get exactly the results you would expect from the source code. +// * *Fast:* Optimizing compilation takes somewhat more time, and a lot more memory for a +// large function. [-O1] +// With this setting, the compiler tries to reduce code size and execution time, +// without performing any optimizations that take a great deal of compilation time. In +// Apple's compiler, strict aliasing, block reordering, and inter-block scheduling are +// disabled by default when optimizing. +// * *Faster:* The compiler performs nearly all supported optimizations that do not +// involve a space-speed tradeoff. [-O2] +// With this setting, the compiler does not perform loop unrolling or function +// inlining, or register renaming. As compared to the `Fast` setting, this setting +// increases both compilation time and the performance of the generated code. +// * *Fastest:* Turns on all optimizations specified by the `Faster` setting and also +// turns on function inlining and register renaming options. This setting may result in a +// larger binary. [-O3] +// * *Fastest, Smallest:* Optimize for size. This setting enables all `Faster` +// optimizations that do not typically increase code size. It also performs further +// optimizations designed to reduce code size. [-Os] +// * *Fastest, Aggressive Optimizations:* This setting enables `Fastest` but also enables +// aggressive optimizations that may break strict standards compliance but should work +// well on well-behaved code. [-Ofast] + +GCC_OPTIMIZATION_LEVEL = 0 + + + +// Preprocessor Macros +// +// Space-separated list of preprocessor macros of the form `foo` or `foo=bar`. + +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG=1 + + + +// Produce debugging information +// +// Produce debugging information. This information is required for shader profiling. + +MTL_ENABLE_DEBUG_INFO = YES + + + +// Build Active Architecture Only +// +// If enabled, only the active architecture is built. + +ONLY_ACTIVE_ARCH = YES + + + +// Swift Optimization Level +// +// * *None:* Compile without any optimization. [-Onone] +// * *Optimize for Speed:* [-O] +// * *Optimize for Size:* [-Osize] +// * *Whole Module Optimization:* [-O -whole-module-optimization] + +SWIFT_OPTIMIZATION_LEVEL = -Onone diff --git a/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-TestHostApp-Release.xcconfig b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-TestHostApp-Release.xcconfig new file mode 100644 index 0000000000..3f9e299478 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-TestHostApp-Release.xcconfig @@ -0,0 +1,59 @@ +// +// CryptoSwift-TestHostApp-Release.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +#include "CryptoSwift-TestHostApp-Shared.xcconfig" + + +// Debug Information Format +// +// The type of debug information to produce. +// +// * *DWARF:* Object files and linked products will use DWARF as the debug information +// format. [dwarf] +// * *DWARF with dSYM File:* Object files and linked products will use DWARF as the debug +// information format, and Xcode will also produce a dSYM file containing the debug +// information from the individual object files (except that a dSYM file is not needed +// and will not be created for static library or object file products). [dwarf-with-dsym] + +DEBUG_INFORMATION_FORMAT = dwarf-with-dsym + + + +// Enable Foundation Assertions +// +// Controls whether assertion logic provided by `NSAssert` is included in the +// preprocessed source code or is elided during preprocessing. Disabling assertions can +// improve code performance. + +ENABLE_NS_ASSERTIONS = NO + + + +// Produce debugging information +// +// Produce debugging information. This information is required for shader profiling. + +MTL_ENABLE_DEBUG_INFO = NO + + + +// Swift Optimization Level +// +// * *None:* Compile without any optimization. [-Onone] +// * *Optimize for Speed:* [-O] +// * *Optimize for Size:* [-Osize] +// * *Whole Module Optimization:* [-O -whole-module-optimization] + +SWIFT_OPTIMIZATION_LEVEL = -O + + + +// Validate Built Product +// +// If enabled, perform validation checks on the product as part of the build process. + +VALIDATE_PRODUCT = YES diff --git a/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-TestHostApp-Shared.xcconfig b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-TestHostApp-Shared.xcconfig new file mode 100644 index 0000000000..a1ab57d764 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-TestHostApp-Shared.xcconfig @@ -0,0 +1,64 @@ +// +// CryptoSwift-TestHostApp-Shared.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +CODE_SIGN_STYLE = Automatic +CODE_SIGN_IDENTITY = iPhone Developer +DEVELOPMENT_TEAM = HA4H7JURM8 +PROVISIONING_PROFILE_SPECIFIER = +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES + +// Asset Catalog App Icon Set Name +// +// Name of an asset catalog app icon set whose contents will be merged into the +// `Info.plist`. + +ASSETCATALOG_COMPILER_APPICON_NAME = + + +// Info.plist File +// +// The project-relative path to the property list file that contains the `Info.plist` +// information used by bundles. For details on information property list files, see +// [Information Property List +// Files](https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigFiles.html#//apple_ref/doc/uid/20002091-CJBJIEDH) +// in [Runtime Configuration +// Guidelines](https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPRuntimeConfig/000-Introduction/introduction.html). + +INFOPLIST_FILE = CryptoSwift-TestHostApp/Info.plist + + + +// Runpath Search Paths +// +// This is a list of paths to be added to the `runpath` search path list for the image +// being created. At runtime, `dyld` uses the `runpath` when searching for dylibs whose +// load path begins with `@rpath/`. See [Dynamic Library Programming +// Topics](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/000-Introduction/Introduction.html). + +LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks + + + +// Product Bundle Identifier +// +// A string that uniquely identifies the bundle. The string should be in reverse DNS +// format using only alphanumeric characters (`A-Z`, `a-z`, `0-9`), the dot (`.`), and +// the hyphen (`-`). This value is used as the `CFBundleIdentifier` in the `Info.plist` +// of the built bundle. + +PRODUCT_BUNDLE_IDENTIFIER = CryptoSwiftTestHostApp + + +// Base SDK +// +// The name or path of the base SDK being used during the build. The product will be +// built against the headers and libraries located inside the indicated SDK. This path +// will be prepended to all search paths, and will be passed through the environment to +// the compiler and linker. Additional SDKs can be specified in the `ADDITIONAL_SDKS` +// setting. + +SDKROOT = iphoneos diff --git a/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-TestHostApp-Test.xcconfig b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-TestHostApp-Test.xcconfig new file mode 100644 index 0000000000..ebb165ae2b --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/CryptoSwift-TestHostApp-Test.xcconfig @@ -0,0 +1,59 @@ +// +// CryptoSwift-TestHostApp-Test.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +#include "CryptoSwift-TestHostApp-Shared.xcconfig" + + +// Debug Information Format +// +// The type of debug information to produce. +// +// * *DWARF:* Object files and linked products will use DWARF as the debug information +// format. [dwarf] +// * *DWARF with dSYM File:* Object files and linked products will use DWARF as the debug +// information format, and Xcode will also produce a dSYM file containing the debug +// information from the individual object files (except that a dSYM file is not needed +// and will not be created for static library or object file products). [dwarf-with-dsym] + +DEBUG_INFORMATION_FORMAT = dwarf-with-dsym + + + +// Enable Foundation Assertions +// +// Controls whether assertion logic provided by `NSAssert` is included in the +// preprocessed source code or is elided during preprocessing. Disabling assertions can +// improve code performance. + +ENABLE_NS_ASSERTIONS = NO + + + +// Produce debugging information +// +// Produce debugging information. This information is required for shader profiling. + +MTL_ENABLE_DEBUG_INFO = NO + + + +// Swift Optimization Level +// +// * *None:* Compile without any optimization. [-Onone] +// * *Optimize for Speed:* [-O] +// * *Optimize for Size:* [-Osize] +// * *Whole Module Optimization:* [-O -whole-module-optimization] + +SWIFT_OPTIMIZATION_LEVEL = -O + + + +// Validate Built Product +// +// If enabled, perform validation checks on the product as part of the build process. + +VALIDATE_PRODUCT = YES diff --git a/Carthage/Checkouts/CryptoSwift/config/Project-Debug.xcconfig b/Carthage/Checkouts/CryptoSwift/config/Project-Debug.xcconfig new file mode 100644 index 0000000000..3c81a2e4c0 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/Project-Debug.xcconfig @@ -0,0 +1,61 @@ +// +// Project-Debug.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +#include "Project-Shared.xcconfig" + + +// Strip Debug Symbols During Copy +// +// Specifies whether binary files that are copied during the build, such as in a Copy +// Bundle Resources or Copy Files build phase, should be stripped of debugging symbols. +// It does not cause the linked product of a target to be stripped—use +// `STRIP_INSTALLED_PRODUCT` for that. + +COPY_PHASE_STRIP = NO + + + +// Enable Testability +// +// When this setting is activated, the product will be built with options appropriate for +// running automated tests, such as making private interfaces accessible to the tests. +// This may result in tests running slower than they would without testability enabled. + +ENABLE_TESTABILITY = YES + + + +// Generate Position-Dependent Code +// +// Faster function calls for applications. Not appropriate for shared libraries, which +// need to be position-independent. + +GCC_DYNAMIC_NO_PIC = NO + + + +// Preprocessor Macros +// +// Space-separated list of preprocessor macros of the form `foo` or `foo=bar`. + +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG=1 + +// Active Compilation Conditions +// +// A list of compilation conditions to enable for conditional compilation expressions. + +SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG + +METAL_ENABLE_DEBUG_INFO = YES + + + +// Build Active Architecture Only +// +// If enabled, only the active architecture is built. + +ONLY_ACTIVE_ARCH = YES diff --git a/Carthage/Checkouts/CryptoSwift/config/Project-Release.xcconfig b/Carthage/Checkouts/CryptoSwift/config/Project-Release.xcconfig new file mode 100644 index 0000000000..57162a547e --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/Project-Release.xcconfig @@ -0,0 +1,85 @@ +// +// Project-Release.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +#include "Project-Shared.xcconfig" + + +// Use Optimization Profile +// +// When this setting is enabled, `clang` will use the optimization profile collected for +// a target when building it. + +CLANG_USE_OPTIMIZATION_PROFILE = YES + + + +// Strip Debug Symbols During Copy +// +// Specifies whether binary files that are copied during the build, such as in a Copy +// Bundle Resources or Copy Files build phase, should be stripped of debugging symbols. +// It does not cause the linked product of a target to be stripped—use +// `STRIP_INSTALLED_PRODUCT` for that. + +COPY_PHASE_STRIP = YES + + + +// Enable Foundation Assertions +// +// Controls whether assertion logic provided by `NSAssert` is included in the +// preprocessed source code or is elided during preprocessing. Disabling assertions can +// improve code performance. + +ENABLE_NS_ASSERTIONS = NO + + + +// Optimization Level +// +// Specifies the degree to which the generated code is optimized for speed and binary +// size. +// +// * *None:* Do not optimize. [-O0] +// With this setting, the compiler's goal is to reduce the cost of compilation and to +// make debugging produce the expected results. Statements are independent—if you stop +// the program with a breakpoint between statements, you can then assign a new value to +// any variable or change the program counter to any other statement in the function and +// get exactly the results you would expect from the source code. +// * *Fast:* Optimizing compilation takes somewhat more time, and a lot more memory for a +// large function. [-O1] +// With this setting, the compiler tries to reduce code size and execution time, +// without performing any optimizations that take a great deal of compilation time. In +// Apple's compiler, strict aliasing, block reordering, and inter-block scheduling are +// disabled by default when optimizing. +// * *Faster:* The compiler performs nearly all supported optimizations that do not +// involve a space-speed tradeoff. [-O2] +// With this setting, the compiler does not perform loop unrolling or function +// inlining, or register renaming. As compared to the `Fast` setting, this setting +// increases both compilation time and the performance of the generated code. +// * *Fastest:* Turns on all optimizations specified by the `Faster` setting and also +// turns on function inlining and register renaming options. This setting may result in a +// larger binary. [-O3] +// * *Fastest, Smallest:* Optimize for size. This setting enables all `Faster` +// optimizations that do not typically increase code size. It also performs further +// optimizations designed to reduce code size. [-Os] +// * *Fastest, Aggressive Optimizations:* This setting enables `Fastest` but also enables +// aggressive optimizations that may break strict standards compliance but should work +// well on well-behaved code. [-Ofast] + +GCC_OPTIMIZATION_LEVEL = fast + + + +METAL_ENABLE_DEBUG_INFO = NO + + + +// Validate Built Product +// +// If enabled, perform validation checks on the product as part of the build process. + +VALIDATE_PRODUCT = YES \ No newline at end of file diff --git a/Carthage/Checkouts/CryptoSwift/config/Project-Shared.xcconfig b/Carthage/Checkouts/CryptoSwift/config/Project-Shared.xcconfig new file mode 100644 index 0000000000..b6b205026c --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/Project-Shared.xcconfig @@ -0,0 +1,522 @@ +// +// Project-Shared.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +PRODUCT_NAME = ${TARGET_NAME} + +DEVELOPMENT_TEAM = +PROVISIONING_PROFILE = +PROVISIONING_PROFILE_SPECIFIER = +CODE_SIGN_IDENTITY = +CODE_SIGN_STYLE = Manual + +// Misuse of 'nonnull' +// +// Check for misuses of `nonnull` parameter and return types. + +CLANG_ANALYZER_NONNULL = YES + +// Suspicious Conversions of NSNumber and CFNumberRef +// +// Warn when a number object, such as an instance of `NSNumber`, `CFNumberRef`, +// `OSNumber`, or `OSBoolean` is compared or converted to a primitive value instead of +// another object. + +CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE + +// Always Search User Paths (Deprecated) +// +// This setting is deprecated as of Xcode 8.3 and may not be supported in future +// versions. It is recommended that you disable the setting. +// +// If enabled, both `#include `-style and `#include "header.h"`-style +// directives search the paths in `USER_HEADER_SEARCH_PATHS` before +// `HEADER_SEARCH_PATHS`. As a consequence, user headers, such as your own `String.h` +// header, have precedence over system headers when using `#include `. This is +// done using the `-iquote` flag for the paths provided in `USER_HEADER_SEARCH_PATHS`. If +// disabled and your compiler fully supports separate user paths, user headers are only +// accessible with `#include "header.h"`-style preprocessor directives. +// +// For backwards compatibility reasons, this setting is enabled by default. Disabling it +// is strongly recommended. + +ALWAYS_SEARCH_USER_PATHS = NO + + + +// C++ Language Dialect +// +// Choose a standard or non-standard C++ language dialect. Options include: +// +// * *C++98:* Accept ISO C++ 1998 with amendments, but not GNU extensions. [-std=c++98] +// * *GNU++98:* Accept ISO C++ 1998 with amendments and GNU extensions. [-std=gnu++98] +// * *C++11:* Accept the ISO C++ 2011 standard with amendments, but not GNU extensions. +// [-std=c++11] +// * *GNU++11:* Accept the ISO C++ 2011 standard with amendments and GNU extensions. +// [-std=gnu++11] +// * *C++14:* Accept the ISO C++ 2014 standard with amendments, but not GNU extensions. +// [-std=c++14] +// * *GNU++14:* Accept the ISO C++ 2014 standard with amendments and GNU extensions. +// [-std=gnu++14] +// * *C++17:* Accept the ISO C++ 2017 standard with amendments, but not GNU extensions. +// [-std=c++17] +// * *GNU++17:* Accept the ISO C++ 2017 standard with amendments and GNU extensions. +// [-std=gnu++17] +// * *Compiler Default:* Tells the compiler to use its default C++ language dialect. This +// is normally the best choice unless you have specific needs. (Currently equivalent to +// GNU++98.) + +CLANG_CXX_LANGUAGE_STANDARD = gnu++0x + + + +// C++ Standard Library +// +// Choose a version of the C++ standard library to use. +// +// * *libstdc++:* A traditional C++ standard library that works with GCC and the LLVM +// Compiler (default). +// * *libc++:* A highly optimized C++ standard library that works only with the LLVM +// Compiler, and is designed to support new C++11 features. + +CLANG_CXX_LIBRARY = libc++ + + + +// Enable Modules (C and Objective-C) +// +// Enables the use of modules for system APIs. System headers are imported as semantic +// modules instead of raw headers. This can result in faster builds and project indexing. + +CLANG_ENABLE_MODULES = YES + + + +// Objective-C Automatic Reference Counting +// +// Compiles reference-counted Objective-C code (when garbage collection is not enabled) +// to use Automatic Reference Counting. Code compiled using automated reference counting +// is compatible with other code (such as frameworks) compiled using either manual +// reference counting (for example, traditional `retain` and `release` messages) or +// automated reference counting. Using this mode is currently incompatible with compiling +// code to use Objective-C Garbage Collection. + +CLANG_ENABLE_OBJC_ARC = YES + + +// Weak References in Manual Retain Release +// +// Compiles Objective-C code to enable weak references for code compiled with manual +// retain release (MRR) semantics. + +CLANG_ENABLE_OBJC_WEAK = YES + + +// Duplicate Method Definitions +// +// Warn about declaring the same method more than once within the same `@interface`. + +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES + + + +// Block Capture of Autoreleasing +// +// Warn about block captures of implicitly autoreleasing parameters. + +CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES + + + +// Implicit Boolean Conversions +// +// Warn about implicit conversions to boolean values that are suspicious. For example, +// writing `if (foo)` where `foo` is the name a function will trigger a warning. + +CLANG_WARN_BOOL_CONVERSION = YES + + + +// Suspicious Commas +// +// Warn about suspicious uses of the comma operator. + +CLANG_WARN_COMMA = YES + + + +// Implicit Constant Conversions +// +// Warn about implicit conversions of constant values that cause the constant value to +// change, either through a loss of precision, or entirely in its meaning. + +CLANG_WARN_CONSTANT_CONVERSION = YES + + + +// Overriding Deprecated Objective-C Methods +// +// Warn if an Objective-C class either subclasses a deprecated class or overrides a +// method that has been marked deprecated or unavailable. + +CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES + + + +// Direct usage of 'isa' +// +// Warn about direct accesses to the Objective-C `isa` pointer instead of using a runtime +// API. + +CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR + + + +// Empty Loop Bodies +// +// Warn about loop bodies that are suspiciously empty. + +CLANG_WARN_EMPTY_BODY = YES + + + +// Implicit Enum Conversions +// +// Warn about implicit conversions between different kinds of enum values. For example, +// this can catch issues when using the wrong enum flag as an argument to a function or +// method. + +CLANG_WARN_ENUM_CONVERSION = YES + + + +// Infinite Recursion +// +// Warn if all paths through a function call itself. + +CLANG_WARN_INFINITE_RECURSION = YES + + + +// Implicit Integer to Pointer Conversions +// +// Warn about implicit conversions between pointers and integers. For example, this can +// catch issues when one incorrectly intermixes using `NSNumber*`'s and raw integers. + +CLANG_WARN_INT_CONVERSION = YES + + + +// Implicit Non-Literal Null Conversions +// +// Warn about non-literal expressions that evaluate to zero being treated as a null +// pointer. + +CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES + + + +// Implicit retain of 'self' within blocks +// +// Warn about implicit retains of `self` within blocks, which can create a retain-cycle. + +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES + + + +// Implicit Objective-C Literal Conversions +// +// Warn about implicit conversions from Objective-C literals to values of incompatible +// type. + +CLANG_WARN_OBJC_LITERAL_CONVERSION = YES + + + +// Unintentional Root Class +// +// Warn about classes that unintentionally do not subclass a root class, such as +// `NSObject`. + +CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR + + + +// Range-based For Loops +// +// Warn about ranged-based for loops. + +CLANG_WARN_RANGE_LOOP_ANALYSIS = YES + + + +// Strict Prototypes +// +// Warn about non-prototype declarations. + +CLANG_WARN_STRICT_PROTOTYPES = YES + + + +// Suspicious Moves +// +// Warn about suspicious uses of `std::move`. + +CLANG_WARN_SUSPICIOUS_MOVE = YES + + + +// Unreachable Code +// +// Warns about potentially unreachable code. + +CLANG_WARN_UNREACHABLE_CODE = YES + + +// Documentation Comments +// +// Warns about issues in documentation comments (`doxygen`-style) such as missing or +// incorrect documentation tags. + +CLANG_WARN_DOCUMENTATION_COMMENTS = YES + + +// Unguarded availability +// +// Warn if an API that is newer than the deployment target is used without "if +// (@available(...))" guards. + +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE + + + +CODE_SIGNING_REQUIRED = NO + + + +// Current Project Version +// +// This setting defines the current version of the project. The value must be a integer +// or floating point number, such as `57` or `365.8`. + +CURRENT_PROJECT_VERSION = 1 + + + +// Debug Information Format +// +// The type of debug information to produce. +// +// * *DWARF:* Object files and linked products will use DWARF as the debug information +// format. [dwarf] +// * *DWARF with dSYM File:* Object files and linked products will use DWARF as the debug +// information format, and Xcode will also produce a dSYM file containing the debug +// information from the individual object files (except that a dSYM file is not needed +// and will not be created for static library or object file products). [dwarf-with-dsym] + +DEBUG_INFORMATION_FORMAT = dwarf + + + +// Defines Module +// +// If enabled, the product will be treated as defining its own module. This enables +// automatic production of LLVM module map files when appropriate, and allows the product +// to be imported as a module. + +DEFINES_MODULE = YES + + + +// Enable Strict Checking of objc_msgSend Calls +// +// Controls whether `objc_msgSend` calls must be cast to the appropriate function pointer +// type before being called. + +ENABLE_STRICT_OBJC_MSGSEND = YES + + + +// C Language Dialect +// +// Choose a standard or non-standard C language dialect. +// +// * *ANSI C:* Accept ISO C90 and ISO C++, turning off GNU extensions that are +// incompatible. [-ansi] +// Incompatible GNU extensions include the `asm`, `inline`, and `typeof` keywords (but +// not the equivalent `\_\_asm\_\_`, `\_\_inline\_\_`, and `\_\_typeof\_\_` forms), and +// the `//` syntax for comments. +// This setting also enables trigraphs. +// * *C89:* Accept ISO C90 (1990), but not GNU extensions. [-std=c89] +// * *GNU89:* Accept ISO C90 and GNU extensions. [-std=gnu89] +// * *C99:* Accept ISO C99 (1999), but not GNU extensions. [-std=c99] +// * *GNU99:* Accept ISO C99 and GNU extensions. [-std=gnu99] +// * *C11:* Accept ISO C11 (2011), but not GNU extensions. [-std=c11] +// * *GNU11:* Accept ISO C11 and GNU extensions. [-std=gnu11] +// * *Compiler Default:* Tells the compiler to use its default C language dialect. This +// is normally the best choice unless you have specific needs. (Currently equivalent to +// GNU99.) + +GCC_C_LANGUAGE_STANDARD = gnu99 + + + +// No Common Blocks +// +// In C, allocate even uninitialized global variables in the data section of the object +// file, rather than generating them as common blocks. This has the effect that if the +// same variable is declared (without `extern`) in two different compilations, you will +// get an error when you link them. + +GCC_NO_COMMON_BLOCKS = YES + + + +// Implicit Conversion to 32 Bit Type +// +// Warn if a value is implicitly converted from a 64-bit type to a 32-bit type. This is a +// subset of the warnings provided by -Wconversion. + +GCC_WARN_64_TO_32_BIT_CONVERSION = YES + + + +// Mismatched Return Type +// +// Causes warnings to be emitted when a function with a defined return type (not `void`) +// contains a return statement without a return-value. Also emits a warning when a +// function is defined without specifying a return type. + +GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR + + + +// Undeclared Selector +// +// Warn if a `@selector(...)` expression referring to an undeclared selector is found. A +// selector is considered undeclared if no method with that name has been declared before +// the `@selector(...)` expression, either explicitly in an `@interface` or `@protocol` +// declaration, or implicitly in an `@implementation` section. This option always +// performs its checks as soon as a `@selector(...)` expression is found, while +// `-Wselector` only performs its checks in the final stage of compilation. This also +// enforces the coding style convention that methods and selectors must be declared +// before being used. + +GCC_WARN_UNDECLARED_SELECTOR = YES + + + +// Uninitialized Variables +// +// Warn if a variable might be clobbered by a `setjmp` call or if an automatic variable +// is used without prior initialization. +// +// The compiler may not detect all cases where an automatic variable is initialized or +// all usage patterns that may lead to use prior to initialization. You can toggle +// between the normal uninitialized value checking or the more aggressive (conservative) +// checking, which finds more issues but the checking is much stricter. + +GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE + + + +// Unused Functions +// +// Warn whenever a static function is declared but not defined or a noninline static +// function is unused. + +GCC_WARN_UNUSED_FUNCTION = YES + + + +// Unused Labels +// +// Warn whenever a label is declared but not used. + +GCC_WARN_UNUSED_LABEL = YES + + + +// Unused Variables +// +// Warn whenever a local variable or nonconstant static variable is unused aside from its +// declaration. + +GCC_WARN_UNUSED_VARIABLE = YES + + +IPHONEOS_DEPLOYMENT_TARGET = 8.0 + + + +// macOS Deployment Target +// +// Code will load on this and later versions of macOS. Framework APIs that are +// unavailable in earlier versions will be weak-linked; your code should check for `null` +// function pointers or specific system versions before calling newer APIs. + +MACOSX_DEPLOYMENT_TARGET = 10.10 + + + +// Supported Platforms +// +// The list of supported platforms from which a base SDK can be used. This setting is +// used if the product can be built for multiple platforms using different SDKs. + +SUPPORTED_PLATFORMS = iphonesimulator iphoneos macosx appletvos watchos appletvsimulator watchsimulator + + + +SWIFT_COMPILATION_MODE = wholemodule + + + +// Swift Language Version +// +// + +SWIFT_VERSION = 5.0 + + + +// Targeted Device Family +// +// The build system uses the selected device to set the correct value for the +// `UIDeviceFamily` key it adds to the target's `Info.plist` file. This also drives the +// --target-device flag to actool, which determines the idioms selected during catalog +// compilation for iOS platforms. + +TARGETED_DEVICE_FAMILY = 1,2,3,4 + + + +TVOS_DEPLOYMENT_TARGET = 9.0 + + + +// Versioning Name Prefix +// +// Used as a prefix for the name of the version info symbol in the generated versioning +// source file. If you prefix your exported symbols you will probably want to set this to +// the same prefix. + +VERSION_INFO_PREFIX = + + + +// Versioning System +// +// Selects the process used for version-stamping generated files. +// +// * *None:* Use no versioning system. +// * *Apple Generic:* Use the current project version setting. [apple-generic] + +VERSIONING_SYSTEM = apple-generic + + + +WATCHOS_DEPLOYMENT_TARGET = 2.0 diff --git a/Carthage/Checkouts/CryptoSwift/config/Project-Test.xcconfig b/Carthage/Checkouts/CryptoSwift/config/Project-Test.xcconfig new file mode 100644 index 0000000000..1504bc428f --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/Project-Test.xcconfig @@ -0,0 +1,108 @@ +// +// Project-Test.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +#include "Project-Shared.xcconfig" + + +// Strip Debug Symbols During Copy +// +// Specifies whether binary files that are copied during the build, such as in a Copy +// Bundle Resources or Copy Files build phase, should be stripped of debugging symbols. +// It does not cause the linked product of a target to be stripped—use +// `STRIP_INSTALLED_PRODUCT` for that. + +COPY_PHASE_STRIP = NO + + + +// Enable Foundation Assertions +// +// Controls whether assertion logic provided by `NSAssert` is included in the +// preprocessed source code or is elided during preprocessing. Disabling assertions can +// improve code performance. + +ENABLE_NS_ASSERTIONS = NO + + + +// Enable Testability +// +// When this setting is activated, the product will be built with options appropriate for +// running automated tests, such as making private interfaces accessible to the tests. +// This may result in tests running slower than they would without testability enabled. + +ENABLE_TESTABILITY = YES + + + +// Optimization Level +// +// Specifies the degree to which the generated code is optimized for speed and binary +// size. +// +// * *None:* Do not optimize. [-O0] +// With this setting, the compiler's goal is to reduce the cost of compilation and to +// make debugging produce the expected results. Statements are independent—if you stop +// the program with a breakpoint between statements, you can then assign a new value to +// any variable or change the program counter to any other statement in the function and +// get exactly the results you would expect from the source code. +// * *Fast:* Optimizing compilation takes somewhat more time, and a lot more memory for a +// large function. [-O1] +// With this setting, the compiler tries to reduce code size and execution time, +// without performing any optimizations that take a great deal of compilation time. In +// Apple's compiler, strict aliasing, block reordering, and inter-block scheduling are +// disabled by default when optimizing. +// * *Faster:* The compiler performs nearly all supported optimizations that do not +// involve a space-speed tradeoff. [-O2] +// With this setting, the compiler does not perform loop unrolling or function +// inlining, or register renaming. As compared to the `Fast` setting, this setting +// increases both compilation time and the performance of the generated code. +// * *Fastest:* Turns on all optimizations specified by the `Faster` setting and also +// turns on function inlining and register renaming options. This setting may result in a +// larger binary. [-O3] +// * *Fastest, Smallest:* Optimize for size. This setting enables all `Faster` +// optimizations that do not typically increase code size. It also performs further +// optimizations designed to reduce code size. [-Os] +// * *Fastest, Aggressive Optimizations:* This setting enables `Fastest` but also enables +// aggressive optimizations that may break strict standards compliance but should work +// well on well-behaved code. [-Ofast] + +GCC_OPTIMIZATION_LEVEL = fast + + + +// Preprocessor Macros +// +// Space-separated list of preprocessor macros of the form `foo` or `foo=bar`. + +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG=1 CI=1 + +// Active Compilation Conditions +// +// A list of compilation conditions to enable for conditional compilation expressions. + +SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG + + + +METAL_ENABLE_DEBUG_INFO = NO + + + +// Build Active Architecture Only +// +// If enabled, only the active architecture is built. + +ONLY_ACTIVE_ARCH = YES + + + +// Validate Built Product +// +// If enabled, perform validation checks on the product as part of the build process. + +VALIDATE_PRODUCT = YES diff --git a/Carthage/Checkouts/CryptoSwift/config/Tests-Debug.xcconfig b/Carthage/Checkouts/CryptoSwift/config/Tests-Debug.xcconfig new file mode 100644 index 0000000000..a3f4b524d2 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/Tests-Debug.xcconfig @@ -0,0 +1,37 @@ +// +// Tests-Debug.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +#include "Tests-Shared.xcconfig" + + +// Link-Time Optimization +// +// Enabling this setting allows optimization across file boundaries during linking. +// +// * *No:* Disabled. Do not use link-time optimization. +// * *Monolithic Link-Time Optimization:* This mode performs monolithic link-time +// optimization of binaries, combining all executable code into a single unit and running +// aggressive compiler optimizations. +// * *Incremental Link-Time Optimization:* This mode performs partitioned link-time +// optimization of binaries, inlining between compilation units and running aggressive +// compiler optimizations on each unit in parallel. This enables fast incremental builds +// and uses less memory than Monolithic LTO. + +LLVM_LTO = NO + + + +METAL_ENABLE_DEBUG_INFO = YES + +// Swift Optimization Level +// +// * *None:* Compile without any optimization. [-Onone] +// * *Optimize for Speed:* [-O] +// * *Optimize for Size:* [-Osize] +// * *Whole Module Optimization:* [-O -whole-module-optimization] + +SWIFT_OPTIMIZATION_LEVEL = -Onone diff --git a/Carthage/Checkouts/CryptoSwift/config/Tests-Release.xcconfig b/Carthage/Checkouts/CryptoSwift/config/Tests-Release.xcconfig new file mode 100644 index 0000000000..ecc4547418 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/Tests-Release.xcconfig @@ -0,0 +1,92 @@ +// +// Tests-Release.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +#include "Tests-Shared.xcconfig" + + +// Optimization Level +// +// Specifies the degree to which the generated code is optimized for speed and binary +// size. +// +// * *None:* Do not optimize. [-O0] +// With this setting, the compiler's goal is to reduce the cost of compilation and to +// make debugging produce the expected results. Statements are independent—if you stop +// the program with a breakpoint between statements, you can then assign a new value to +// any variable or change the program counter to any other statement in the function and +// get exactly the results you would expect from the source code. +// * *Fast:* Optimizing compilation takes somewhat more time, and a lot more memory for a +// large function. [-O1] +// With this setting, the compiler tries to reduce code size and execution time, +// without performing any optimizations that take a great deal of compilation time. In +// Apple's compiler, strict aliasing, block reordering, and inter-block scheduling are +// disabled by default when optimizing. +// * *Faster:* The compiler performs nearly all supported optimizations that do not +// involve a space-speed tradeoff. [-O2] +// With this setting, the compiler does not perform loop unrolling or function +// inlining, or register renaming. As compared to the `Fast` setting, this setting +// increases both compilation time and the performance of the generated code. +// * *Fastest:* Turns on all optimizations specified by the `Faster` setting and also +// turns on function inlining and register renaming options. This setting may result in a +// larger binary. [-O3] +// * *Fastest, Smallest:* Optimize for size. This setting enables all `Faster` +// optimizations that do not typically increase code size. It also performs further +// optimizations designed to reduce code size. [-Os] +// * *Fastest, Aggressive Optimizations:* This setting enables `Fastest` but also enables +// aggressive optimizations that may break strict standards compliance but should work +// well on well-behaved code. [-Ofast] + +GCC_OPTIMIZATION_LEVEL = fast + + + +// Unroll Loops +// +// Unrolls loops. Unrolling makes the code larger, but may make it faster by reducing the +// number of branches executed. + +GCC_UNROLL_LOOPS = YES + + + +// Link-Time Optimization +// +// Enabling this setting allows optimization across file boundaries during linking. +// +// * *No:* Disabled. Do not use link-time optimization. +// * *Monolithic Link-Time Optimization:* This mode performs monolithic link-time +// optimization of binaries, combining all executable code into a single unit and running +// aggressive compiler optimizations. +// * *Incremental Link-Time Optimization:* This mode performs partitioned link-time +// optimization of binaries, inlining between compilation units and running aggressive +// compiler optimizations on each unit in parallel. This enables fast incremental builds +// and uses less memory than Monolithic LTO. + +LLVM_LTO = YES + + + +METAL_ENABLE_DEBUG_INFO = NO + + + +// Disable Safety Checks +// +// Disable runtime safety checks when optimizing. + +SWIFT_DISABLE_SAFETY_CHECKS = YES + + + +// Swift Optimization Level +// +// * *None:* Compile without any optimization. [-Onone] +// * *Optimize for Speed:* [-O] +// * *Optimize for Size:* [-Osize] +// * *Whole Module Optimization:* [-O -whole-module-optimization] + +SWIFT_OPTIMIZATION_LEVEL = -O diff --git a/Carthage/Checkouts/CryptoSwift/config/Tests-Shared.xcconfig b/Carthage/Checkouts/CryptoSwift/config/Tests-Shared.xcconfig new file mode 100644 index 0000000000..304e28b4a7 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/Tests-Shared.xcconfig @@ -0,0 +1,71 @@ +// +// Tests-Shared.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + + +// Always Embed Swift Standard Libraries +// +// Always embed the Swift standard libraries in the target's products, even if the target +// does not contain any Swift code. For example, this should be enabled if the target is +// embedding other products which contain Swift, or if it is a test target which does not +// contain Swift but which is testing a product which does. This setting only applies to +// wrapped products, not to standalone binary products. + +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES + + + +// Header Search Paths +// +// This is a list of paths to folders to be searched by the compiler for included or +// imported header files when compiling C, Objective-C, C++, or Objective-C++. Paths are +// delimited by whitespace, so any paths with spaces in them need to be properly quoted. + +HEADER_SEARCH_PATHS = $(inherited) includes/** + + + +// Info.plist File +// +// The project-relative path to the property list file that contains the `Info.plist` +// information used by bundles. For details on information property list files, see +// [Information Property List +// Files](https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigFiles.html#//apple_ref/doc/uid/20002091-CJBJIEDH) +// in [Runtime Configuration +// Guidelines](https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPRuntimeConfig/000-Introduction/introduction.html). + +INFOPLIST_FILE = Tests/${TARGET_NAME}/Info.plist + + + +// Runpath Search Paths +// +// This is a list of paths to be added to the `runpath` search path list for the image +// being created. At runtime, `dyld` uses the `runpath` when searching for dylibs whose +// load path begins with `@rpath/`. See [Dynamic Library Programming +// Topics](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/000-Introduction/Introduction.html). + +LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks @loader_path/Frameworks @loader_path/../Frameworks @executable_path/../Frameworks + + + +// Product Bundle Identifier +// +// A string that uniquely identifies the bundle. The string should be in reverse DNS +// format using only alphanumeric characters (`A-Z`, `a-z`, `0-9`), the dot (`.`), and +// the hyphen (`-`). This value is used as the `CFBundleIdentifier` in the `Info.plist` +// of the built bundle. + +PRODUCT_BUNDLE_IDENTIFIER = com.krzyzanowskim.${PRODUCT_NAME:rfc1034identifier} + + + +// Objective-C Bridging Header +// +// Path to the header defining the Objective-C interfaces to be exposed in Swift. + +SWIFT_OBJC_BRIDGING_HEADER = Tests/${TARGET_NAME}/Bridging.h + diff --git a/Carthage/Checkouts/CryptoSwift/config/Tests-Test.xcconfig b/Carthage/Checkouts/CryptoSwift/config/Tests-Test.xcconfig new file mode 100644 index 0000000000..eb65b72df3 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/config/Tests-Test.xcconfig @@ -0,0 +1,92 @@ +// +// Tests-Test.xcconfig +// +// Generated by BuildSettingExtractor on 02/04/2018 +// https://github.com/dempseyatgithub/BuildSettingExtractor +// + +#include "Tests-Shared.xcconfig" + + +// Optimization Level +// +// Specifies the degree to which the generated code is optimized for speed and binary +// size. +// +// * *None:* Do not optimize. [-O0] +// With this setting, the compiler's goal is to reduce the cost of compilation and to +// make debugging produce the expected results. Statements are independent—if you stop +// the program with a breakpoint between statements, you can then assign a new value to +// any variable or change the program counter to any other statement in the function and +// get exactly the results you would expect from the source code. +// * *Fast:* Optimizing compilation takes somewhat more time, and a lot more memory for a +// large function. [-O1] +// With this setting, the compiler tries to reduce code size and execution time, +// without performing any optimizations that take a great deal of compilation time. In +// Apple's compiler, strict aliasing, block reordering, and inter-block scheduling are +// disabled by default when optimizing. +// * *Faster:* The compiler performs nearly all supported optimizations that do not +// involve a space-speed tradeoff. [-O2] +// With this setting, the compiler does not perform loop unrolling or function +// inlining, or register renaming. As compared to the `Fast` setting, this setting +// increases both compilation time and the performance of the generated code. +// * *Fastest:* Turns on all optimizations specified by the `Faster` setting and also +// turns on function inlining and register renaming options. This setting may result in a +// larger binary. [-O3] +// * *Fastest, Smallest:* Optimize for size. This setting enables all `Faster` +// optimizations that do not typically increase code size. It also performs further +// optimizations designed to reduce code size. [-Os] +// * *Fastest, Aggressive Optimizations:* This setting enables `Fastest` but also enables +// aggressive optimizations that may break strict standards compliance but should work +// well on well-behaved code. [-Ofast] + +GCC_OPTIMIZATION_LEVEL = fast + + + +// Unroll Loops +// +// Unrolls loops. Unrolling makes the code larger, but may make it faster by reducing the +// number of branches executed. + +GCC_UNROLL_LOOPS = YES + + + +// Link-Time Optimization +// +// Enabling this setting allows optimization across file boundaries during linking. +// +// * *No:* Disabled. Do not use link-time optimization. +// * *Monolithic Link-Time Optimization:* This mode performs monolithic link-time +// optimization of binaries, combining all executable code into a single unit and running +// aggressive compiler optimizations. +// * *Incremental Link-Time Optimization:* This mode performs partitioned link-time +// optimization of binaries, inlining between compilation units and running aggressive +// compiler optimizations on each unit in parallel. This enables fast incremental builds +// and uses less memory than Monolithic LTO. + +LLVM_LTO = YES + + + +METAL_ENABLE_DEBUG_INFO = NO + + + +// Disable Safety Checks +// +// Disable runtime safety checks when optimizing. + +SWIFT_DISABLE_SAFETY_CHECKS = YES + + + +// Swift Optimization Level +// +// * *None:* Compile without any optimization. [-Onone] +// * *Optimize for Speed:* [-O] +// * *Optimize for Size:* [-Osize] +// * *Whole Module Optimization:* [-O -whole-module-optimization] + +SWIFT_OPTIMIZATION_LEVEL = -O diff --git a/Carthage/Checkouts/CryptoSwift/scripts/build-framework.sh b/Carthage/Checkouts/CryptoSwift/scripts/build-framework.sh new file mode 100755 index 0000000000..57f8fc3b68 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/scripts/build-framework.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -ex + +echo "Build frameworks in directory $(pwd)" + +carthage build --no-skip-current --configuration "Release" --platform all \ No newline at end of file diff --git a/Carthage/Checkouts/CryptoSwift/scripts/swiftformat.sh b/Carthage/Checkouts/CryptoSwift/scripts/swiftformat.sh new file mode 100755 index 0000000000..452e251b91 --- /dev/null +++ b/Carthage/Checkouts/CryptoSwift/scripts/swiftformat.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +swiftformat --hexliteralcase lowercase --hexgrouping none --ranges nospace --wrapelements beforefirst --self remove $1 \ No newline at end of file diff --git a/Carthage/Checkouts/SQLite.swift b/Carthage/Checkouts/SQLite.swift index 691fc89e75..0a9893ec03 160000 --- a/Carthage/Checkouts/SQLite.swift +++ b/Carthage/Checkouts/SQLite.swift @@ -1 +1 @@ -Subproject commit 691fc89e75873d417d700920e79a63cf210d1d71 +Subproject commit 0a9893ec030501a3956bee572d6b4fdd3ae158a1 diff --git a/Sources/Apollo/APQNetworkTransport.swift b/Sources/Apollo/APQNetworkTransport.swift new file mode 100644 index 0000000000..312dbb8104 --- /dev/null +++ b/Sources/Apollo/APQNetworkTransport.swift @@ -0,0 +1,77 @@ +import Foundation +import CryptoSwift + +/// Wraps a NetworkTransport to perform automated persisted queries. +public final class APQNetworkTransport: NetworkTransport { + fileprivate static let version = 1 + + var isEnabled: Bool = true + let networkTransport: NetworkTransport + let useGETForPersistedQuery: Bool + + public init(networkTransport: NetworkTransport, useGETForPersistedQuery: Bool = false) { + self.networkTransport = networkTransport + self.useGETForPersistedQuery = useGETForPersistedQuery + } + + public func send( + operation: Operation, + fetchHTTPMethod: FetchHTTPMethod, + includeQuery: Bool, + extensions: GraphQLMap?, + completionHandler: @escaping (GraphQLResponse?, Error?) -> Void + ) -> Cancellable where Operation : GraphQLOperation { + var newExtensions = extensions + if isEnabled { + newExtensions = (newExtensions ?? [:]).merging( + [ + "persistedQuery": [ + "version": type(of: self).version, + "sha256Hash": operation.queryDocument.sha256() + ] + ], + uniquingKeysWith: { $1 } + ) + } + + return networkTransport.send( + operation: operation, + fetchHTTPMethod: isEnabled && useGETForPersistedQuery && operation.operationType == .query ? .GET : fetchHTTPMethod, + includeQuery: !isEnabled, + extensions: newExtensions + ) { [weak self] result, error in + guard let `self` = self, let response = result, let errorsEntry = response.body["errors"] as? [JSONObject] else { + completionHandler(result, error) + return + } + + let errors = errorsEntry.map(GraphQLError.init) + self.isEnabled = !self.hasErrorCode(errors: errors, needleErrorCode: "PERSISTED_QUERY_NOT_SUPPORTED") + + if self.hasErrorCode(errors: errors, needleErrorCode: "PERSISTED_QUERY_NOT_FOUND") || !self.isEnabled { + _ = self.networkTransport.send( + operation: operation, + fetchHTTPMethod: fetchHTTPMethod, + includeQuery: true, + extensions: newExtensions, + completionHandler: completionHandler + ) + } + } + } + + fileprivate func hasErrorCode(errors: [GraphQLError], needleErrorCode: String) -> Bool { + let foundError = errors.first { error in + guard let extensions = error.extensions, + let errorCode = extensions["code"] as? String else { + return false + } + + return errorCode == needleErrorCode + } + + return foundError != nil + } +} + + diff --git a/Sources/Apollo/ApolloClient.swift b/Sources/Apollo/ApolloClient.swift index e4daea53d6..43d9e33947 100644 --- a/Sources/Apollo/ApolloClient.swift +++ b/Sources/Apollo/ApolloClient.swift @@ -81,17 +81,17 @@ public class ApolloClient { /// - queue: A dispatch queue on which the result handler will be called. Defaults to the main queue. /// - resultHandler: An optional closure that is called when query results are available or when an error occurs. /// - Returns: An object that can be used to cancel an in progress fetch. - @discardableResult public func fetch(query: Query, fetchHTTPMethod: FetchHTTPMethod = .POST, cachePolicy: CachePolicy = .returnCacheDataElseFetch, queue: DispatchQueue = DispatchQueue.main, resultHandler: OperationResultHandler? = nil) -> Cancellable { - return _fetch(query: query, fetchHTTPMethod: fetchHTTPMethod, cachePolicy: cachePolicy, queue: queue, resultHandler: resultHandler) + @discardableResult public func fetch(query: Query, fetchHTTPMethod: FetchHTTPMethod = .POST, includeQuery: Bool = true, extensions: GraphQLMap? = nil, cachePolicy: CachePolicy = .returnCacheDataElseFetch, queue: DispatchQueue = DispatchQueue.main, resultHandler: OperationResultHandler? = nil) -> Cancellable { + return _fetch(query: query, fetchHTTPMethod: fetchHTTPMethod, includeQuery: includeQuery, extensions: extensions, cachePolicy: cachePolicy, queue: queue, resultHandler: resultHandler) } - func _fetch(query: Query, fetchHTTPMethod: FetchHTTPMethod, cachePolicy: CachePolicy, context: UnsafeMutableRawPointer? = nil, queue: DispatchQueue, resultHandler: OperationResultHandler?) -> Cancellable { + func _fetch(query: Query, fetchHTTPMethod: FetchHTTPMethod, includeQuery: Bool, extensions: GraphQLMap?, cachePolicy: CachePolicy, context: UnsafeMutableRawPointer? = nil, queue: DispatchQueue, resultHandler: OperationResultHandler?) -> Cancellable { // If we don't have to go through the cache, there is no need to create an operation // and we can return a network task directly if cachePolicy == .fetchIgnoringCacheData { - return send(operation: query, fetchHTTPMethod: fetchHTTPMethod, context: context, handlerQueue: queue, resultHandler: resultHandler) + return send(operation: query, fetchHTTPMethod: fetchHTTPMethod, includeQuery: includeQuery, extensions: extensions, context: context, handlerQueue: queue, resultHandler: resultHandler) } else { - let operation = FetchQueryOperation(client: self, query: query, fetchHTTPMethod: fetchHTTPMethod, cachePolicy: cachePolicy, context: context, handlerQueue: queue, resultHandler: resultHandler) + let operation = FetchQueryOperation(client: self, query: query, fetchHTTPMethod: fetchHTTPMethod, includeQuery: includeQuery, extensions: extensions, cachePolicy: cachePolicy, context: context, handlerQueue: queue, resultHandler: resultHandler) operationQueue.addOperation(operation) return operation } @@ -106,12 +106,29 @@ public class ApolloClient { /// - queue: A dispatch queue on which the result handler will be called. Defaults to the main queue. /// - resultHandler: An optional closure that is called when query results are available or when an error occurs. /// - Returns: A query watcher object that can be used to control the watching behavior. - public func watch(query: Query, fetchHTTPMethod: FetchHTTPMethod = .POST, cachePolicy: CachePolicy = .returnCacheDataElseFetch, queue: DispatchQueue = DispatchQueue.main, resultHandler: @escaping OperationResultHandler) -> GraphQLQueryWatcher { - let watcher = GraphQLQueryWatcher(client: self, query: query, fetchHTTPMethod: fetchHTTPMethod, handlerQueue: queue, resultHandler: resultHandler) + public func watch(query: Query, fetchHTTPMethod: FetchHTTPMethod = .POST, includeQuery: Bool = true, extensions: GraphQLMap? = nil, cachePolicy: CachePolicy = .returnCacheDataElseFetch, queue: DispatchQueue = DispatchQueue.main, resultHandler: @escaping OperationResultHandler) -> GraphQLQueryWatcher { + let watcher = GraphQLQueryWatcher(client: self, query: query, fetchHTTPMethod: fetchHTTPMethod, includeQuery: includeQuery, extensions: extensions, handlerQueue: queue, resultHandler: resultHandler) watcher.fetch(cachePolicy: cachePolicy) return watcher } + public func watch( + forType: Fragment.Type, + cacheKey: CacheKey, + queue: DispatchQueue = DispatchQueue.main, + resultHandler: @escaping GraphQLFragmentWatcher.FragmentResultHandler + ) -> GraphQLFragmentWatcher { + let watcher = GraphQLFragmentWatcher( + client: self, + forType: forType, + cacheKey: cacheKey, + handlerQueue: queue, + resultHandler: resultHandler + ) + watcher.fetch() + return watcher + } + /// Performs a mutation by sending it to the server. /// /// - Parameters: @@ -120,12 +137,12 @@ public class ApolloClient { /// - queue: A dispatch queue on which the result handler will be called. Defaults to the main queue. /// - resultHandler: An optional closure that is called when mutation results are available or when an error occurs. /// - Returns: An object that can be used to cancel an in progress mutation. - @discardableResult public func perform(mutation: Mutation, fetchHTTPMethod: FetchHTTPMethod = .POST, queue: DispatchQueue = DispatchQueue.main, resultHandler: OperationResultHandler? = nil) -> Cancellable { - return _perform(mutation: mutation, fetchHTTPMethod: fetchHTTPMethod, queue: queue, resultHandler: resultHandler) + @discardableResult public func perform(mutation: Mutation, fetchHTTPMethod: FetchHTTPMethod = .POST, includeQuery: Bool = true, extensions: GraphQLMap? = nil, queue: DispatchQueue = DispatchQueue.main, resultHandler: OperationResultHandler? = nil) -> Cancellable { + return _perform(mutation: mutation, fetchHTTPMethod: fetchHTTPMethod, includeQuery: includeQuery, extensions: extensions, queue: queue, resultHandler: resultHandler) } - func _perform(mutation: Mutation, fetchHTTPMethod: FetchHTTPMethod, context: UnsafeMutableRawPointer? = nil, queue: DispatchQueue, resultHandler: OperationResultHandler?) -> Cancellable { - return send(operation: mutation, fetchHTTPMethod: fetchHTTPMethod, context: context, handlerQueue: queue, resultHandler: resultHandler) + func _perform(mutation: Mutation, fetchHTTPMethod: FetchHTTPMethod, includeQuery: Bool, extensions: GraphQLMap?, context: UnsafeMutableRawPointer? = nil, queue: DispatchQueue, resultHandler: OperationResultHandler?) -> Cancellable { + return send(operation: mutation, fetchHTTPMethod: fetchHTTPMethod, includeQuery: includeQuery, extensions: extensions, context: context, handlerQueue: queue, resultHandler: resultHandler) } /// Subscribe to a subscription @@ -136,12 +153,12 @@ public class ApolloClient { /// - queue: A dispatch queue on which the result handler will be called. Defaults to the main queue. /// - resultHandler: An optional closure that is called when mutation results are available or when an error occurs. /// - Returns: An object that can be used to cancel an in progress subscription. - @discardableResult public func subscribe(subscription: Subscription, fetchHTTPMethod: FetchHTTPMethod = .POST, queue: DispatchQueue = DispatchQueue.main, resultHandler: @escaping OperationResultHandler) -> Cancellable { - return send(operation: subscription, fetchHTTPMethod: fetchHTTPMethod, context: nil, handlerQueue: queue, resultHandler: resultHandler) + @discardableResult public func subscribe(subscription: Subscription, fetchHTTPMethod: FetchHTTPMethod = .POST, includeQuery: Bool = true, extensions: GraphQLMap? = nil, queue: DispatchQueue = DispatchQueue.main, resultHandler: @escaping OperationResultHandler) -> Cancellable { + return send(operation: subscription, fetchHTTPMethod: fetchHTTPMethod, includeQuery: includeQuery, extensions: extensions, context: nil, handlerQueue: queue, resultHandler: resultHandler) } - fileprivate func send(operation: Operation, fetchHTTPMethod: FetchHTTPMethod, context: UnsafeMutableRawPointer?, handlerQueue: DispatchQueue, resultHandler: OperationResultHandler?) -> Cancellable { + fileprivate func send(operation: Operation, fetchHTTPMethod: FetchHTTPMethod, includeQuery: Bool, extensions: GraphQLMap?, context: UnsafeMutableRawPointer?, handlerQueue: DispatchQueue, resultHandler: OperationResultHandler?) -> Cancellable { func notifyResultHandler(result: GraphQLResult?, error: Error?) { guard let resultHandler = resultHandler else { return } @@ -150,7 +167,7 @@ public class ApolloClient { } } - return networkTransport.send(operation: operation, fetchHTTPMethod: fetchHTTPMethod) { (response, error) in + return networkTransport.send(operation: operation, fetchHTTPMethod: fetchHTTPMethod, includeQuery: includeQuery, extensions: extensions) { (response, error) in guard let response = response else { notifyResultHandler(result: nil, error: error) return @@ -180,6 +197,8 @@ private final class FetchQueryOperation: AsynchronousOperat let client: ApolloClient let query: Query let fetchHTTPMethod: FetchHTTPMethod + let includeQuery: Bool + let extensions: GraphQLMap? let cachePolicy: CachePolicy let context: UnsafeMutableRawPointer? let handlerQueue: DispatchQueue @@ -187,10 +206,12 @@ private final class FetchQueryOperation: AsynchronousOperat private var networkTask: Cancellable? - init(client: ApolloClient, query: Query, fetchHTTPMethod: FetchHTTPMethod, cachePolicy: CachePolicy, context: UnsafeMutableRawPointer?, handlerQueue: DispatchQueue, resultHandler: OperationResultHandler?) { + init(client: ApolloClient, query: Query, fetchHTTPMethod: FetchHTTPMethod, includeQuery: Bool, extensions: GraphQLMap?, cachePolicy: CachePolicy, context: UnsafeMutableRawPointer?, handlerQueue: DispatchQueue, resultHandler: OperationResultHandler?) { self.client = client self.query = query self.fetchHTTPMethod = fetchHTTPMethod + self.includeQuery = includeQuery + self.extensions = extensions self.cachePolicy = cachePolicy self.context = context self.handlerQueue = handlerQueue @@ -236,7 +257,7 @@ private final class FetchQueryOperation: AsynchronousOperat } func fetchFromNetwork() { - networkTask = client.send(operation: query, fetchHTTPMethod: fetchHTTPMethod, context: context, handlerQueue: handlerQueue) { (result, error) in + networkTask = client.send(operation: query, fetchHTTPMethod: fetchHTTPMethod, includeQuery: includeQuery, extensions: extensions, context: context, handlerQueue: handlerQueue) { (result, error) in self.notifyResultHandler(result: result, error: error) self.state = .finished return diff --git a/Sources/Apollo/GraphQLFragmentWatcher.swift b/Sources/Apollo/GraphQLFragmentWatcher.swift new file mode 100644 index 0000000000..4d387df011 --- /dev/null +++ b/Sources/Apollo/GraphQLFragmentWatcher.swift @@ -0,0 +1,61 @@ + +public final class GraphQLFragmentWatcher: ApolloStoreSubscriber { + public typealias FragmentResultHandler = (_ result: GraphQLResult?, _ error: Error?) -> Void + + weak var client: ApolloClient? + let cacheKey: CacheKey + let handlerQueue: DispatchQueue + let resultHandler: FragmentResultHandler + + private var context = 0 + private weak var fetching: Cancellable? + private var dependentKeys: Set? + + init( + client: ApolloClient, + forType ofFragment: Fragment.Type, + cacheKey: CacheKey, + handlerQueue: DispatchQueue, + resultHandler: @escaping FragmentResultHandler + ) { + self.client = client + self.cacheKey = cacheKey + self.handlerQueue = handlerQueue + self.resultHandler = resultHandler + + client.store.subscribe(self) + } + + func fetch() { + client?.store.withinReadTransaction { transaction in + let mapper = GraphQLSelectionSetMapper() + let dependencyTracker = GraphQLDependencyTracker() + + return try transaction.execute( + selections: Fragment.selections, + onObjectWithKey: self.cacheKey, + variables: [:], + accumulator: zip(mapper, dependencyTracker) + ) + }.andThen { [weak self] (data: Fragment, dependentKeys: Set) in + guard let `self` = self else { return } + self.dependentKeys = dependentKeys + self.resultHandler(GraphQLResult(data: data, errors: nil, source: .cache, dependentKeys: dependentKeys), nil) + } + } + + func store(_ store: ApolloStore, didChangeKeys changedKeys: Set, context: UnsafeMutableRawPointer?) { + if context == &self.context { return } + + guard let dependentKeys = dependentKeys else { return } + if !dependentKeys.isDisjoint(with: changedKeys) { + fetch() + } + } + + /// Cancel any in progress fetching operations and unsubscribe from the store. + public func cancel() { + fetching?.cancel() + client?.store.unsubscribe(self) + } +} diff --git a/Sources/Apollo/GraphQLQueryWatcher.swift b/Sources/Apollo/GraphQLQueryWatcher.swift index 9c88452d52..9193b45a88 100644 --- a/Sources/Apollo/GraphQLQueryWatcher.swift +++ b/Sources/Apollo/GraphQLQueryWatcher.swift @@ -5,6 +5,8 @@ public final class GraphQLQueryWatcher: Cancellable, Apollo weak var client: ApolloClient? let query: Query let fetchHTTPMethod: FetchHTTPMethod + let includeQuery: Bool + let extensions: GraphQLMap? let handlerQueue: DispatchQueue let resultHandler: OperationResultHandler @@ -14,10 +16,12 @@ public final class GraphQLQueryWatcher: Cancellable, Apollo private var dependentKeys: Set? - init(client: ApolloClient, query: Query, fetchHTTPMethod: FetchHTTPMethod, handlerQueue: DispatchQueue, resultHandler: @escaping OperationResultHandler) { + init(client: ApolloClient, query: Query, fetchHTTPMethod: FetchHTTPMethod, includeQuery: Bool, extensions: GraphQLMap?, handlerQueue: DispatchQueue, resultHandler: @escaping OperationResultHandler) { self.client = client self.query = query self.fetchHTTPMethod = fetchHTTPMethod + self.includeQuery = includeQuery + self.extensions = extensions self.handlerQueue = handlerQueue self.resultHandler = resultHandler @@ -30,7 +34,7 @@ public final class GraphQLQueryWatcher: Cancellable, Apollo } func fetch(cachePolicy: CachePolicy) { - fetching = client?._fetch(query: query, fetchHTTPMethod: fetchHTTPMethod, cachePolicy: cachePolicy, context: &context, queue: handlerQueue) { [weak self] (result, error) in + fetching = client?._fetch(query: query, fetchHTTPMethod: fetchHTTPMethod, includeQuery: includeQuery, extensions: extensions, cachePolicy: cachePolicy, context: &context, queue: handlerQueue) { [weak self] (result, error) in guard let `self` = self else { return } self.dependentKeys = result?.dependentKeys diff --git a/Sources/Apollo/HTTPNetworkTransport.swift b/Sources/Apollo/HTTPNetworkTransport.swift index 121b66e378..5c1a9effa6 100644 --- a/Sources/Apollo/HTTPNetworkTransport.swift +++ b/Sources/Apollo/HTTPNetworkTransport.swift @@ -85,7 +85,11 @@ public class HTTPNetworkTransport: NetworkTransport { /// - url: The URL of a GraphQL server to connect to. /// - configuration: A session configuration used to configure the session. Defaults to `URLSessionConfiguration.default`. /// - sendOperationIdentifiers: Whether to send operation identifiers rather than full operation text, for use with servers that support query persistence. Defaults to false. - public init(url: URL, configuration: URLSessionConfiguration = URLSessionConfiguration.default, sendOperationIdentifiers: Bool = false) { + public init( + url: URL, + configuration: URLSessionConfiguration = URLSessionConfiguration.default, + sendOperationIdentifiers: Bool = false + ) { self.url = url self.session = URLSession(configuration: configuration) self.sendOperationIdentifiers = sendOperationIdentifiers @@ -100,8 +104,14 @@ public class HTTPNetworkTransport: NetworkTransport { /// - response: The response received from the server, or `nil` if an error occurred. /// - error: An error that indicates why a request failed, or `nil` if the request was succesful. /// - Returns: An object that can be used to cancel an in progress request. - public func send(operation: Operation, fetchHTTPMethod: FetchHTTPMethod, completionHandler: @escaping (_ response: GraphQLResponse?, _ error: Error?) -> Void) -> Cancellable { - let body = requestBody(for: operation) + public func send( + operation: Operation, + fetchHTTPMethod: FetchHTTPMethod, + includeQuery: Bool = true, + extensions: GraphQLMap? = nil, + completionHandler: @escaping (_ response: GraphQLResponse?, _ error: Error?) -> Void + ) -> Cancellable { + let body = requestBody(for: operation, includeQuery: includeQuery, extensions: extensions) var request = URLRequest(url: url) switch fetchHTTPMethod { @@ -160,45 +170,69 @@ public class HTTPNetworkTransport: NetworkTransport { private let sendOperationIdentifiers: Bool - private func requestBody(for operation: Operation) -> GraphQLMap { + private func requestBody( + for operation: Operation, + includeQuery: Bool, + extensions: GraphQLMap? + ) -> GraphQLMap { + var body: GraphQLMap = [ + "variables": operation.variables, + ] + if sendOperationIdentifiers { guard let operationIdentifier = operation.operationIdentifier else { preconditionFailure("To send operation identifiers, Apollo types must be generated with operationIdentifiers") } - return ["id": operationIdentifier, "variables": operation.variables] + return body.merging(["id": operationIdentifier], uniquingKeysWith: { $1 }) + } + + if let extensions = extensions { + body["extensions"] = extensions + } + + if includeQuery { + body["query"] = operation.queryDocument } - return ["query": operation.queryDocument, "variables": operation.variables] + + return body } private func mountUrlWithQueryParamsIfNeeded(body: GraphQLMap) -> URL? { - guard let query = body.jsonObject["query"], var queryParam = queryString(withItems: [URLQueryItem(name: "query", value: "\(query)")]) else { - return self.url + var queryStringItems = [URLQueryItem]() + if let query = optionalValue(for: body, key: "query") { + queryStringItems.append(URLQueryItem(name: "query", value: "\(query.jsonValue)")) } - if areThereVariables(in: body) { - guard let serializedVariables = try? serializationFormat.serialize(value: body.jsonObject["variables"]) else { - return URL(string: "\(self.url.absoluteString)?\(queryParam)") - } - queryParam += getVariablesEncodedString(of: serializedVariables) + + if let variables = optionalValue(for: body, key: "variables"), + let serializedVariables = try? serializationFormat.serialize(value: variables) { + queryStringItems.append(URLQueryItem(name: "variables", value: getEncodedString(of: serializedVariables))) } - guard let urlForGet = URL(string: "\(self.url.absoluteString)?\(queryParam)") else { - return URL(string: "\(self.url.absoluteString)?\(queryParam)") + + if let extensions = optionalValue(for: body, key: "extensions"), + let serializedExtensions = try? serializationFormat.serialize(value: extensions) { + queryStringItems.append(URLQueryItem(name: "extensions", value: getEncodedString(of: serializedExtensions))) + } + + guard !queryStringItems.isEmpty, + let queryString = queryString(withItems: queryStringItems) else { + return self.url } - return urlForGet + + return URL(string: "\(self.url.absoluteString)?\(queryString)") } - - private func areThereVariables(in map: GraphQLMap) -> Bool { - if let variables = map.jsonObject["variables"], "\(variables)" != "" { - return true + + private func optionalValue(for body: GraphQLMap, key: String) -> JSONEncodable? { + if let value = body[key] { + return value } - return false + return nil } - private func getVariablesEncodedString(of data: Data) -> String { + private func getEncodedString(of data: Data) -> String { var dataString = String(data: data, encoding: String.Encoding.utf8) ?? "" dataString = dataString.replacingOccurrences(of: ";", with: ",") dataString = dataString.replacingOccurrences(of: "=", with: ":") - guard let variablesEncoded = queryString(withItems: [URLQueryItem(name: "variables", value: "\(dataString)")]) else { return "" } - return "&\(variablesEncoded)" + return dataString } private func queryString(withItems items: [URLQueryItem], percentEncoded: Bool = true) -> String? { diff --git a/Sources/Apollo/NetworkTransport.swift b/Sources/Apollo/NetworkTransport.swift index aeb8611faa..33a506bbf0 100644 --- a/Sources/Apollo/NetworkTransport.swift +++ b/Sources/Apollo/NetworkTransport.swift @@ -9,6 +9,12 @@ public protocol NetworkTransport { /// - response: The response received from the server, or `nil` if an error occurred. /// - error: An error that indicates why a request failed, or `nil` if the request was succesful. /// - Returns: An object that can be used to cancel an in progress request. - func send(operation: Operation, fetchHTTPMethod: FetchHTTPMethod, completionHandler: @escaping (_ response: GraphQLResponse?, _ error: Error?) -> Void) -> Cancellable + func send( + operation: Operation, + fetchHTTPMethod: FetchHTTPMethod, + includeQuery: Bool, + extensions: GraphQLMap?, + completionHandler: @escaping (_ response: GraphQLResponse?, _ error: Error?) -> Void + ) -> Cancellable } diff --git a/Sources/ApolloWebSocket/SplitNetworkTransport.swift b/Sources/ApolloWebSocket/SplitNetworkTransport.swift index e235c2ed94..00f71e4d35 100644 --- a/Sources/ApolloWebSocket/SplitNetworkTransport.swift +++ b/Sources/ApolloWebSocket/SplitNetworkTransport.swift @@ -9,11 +9,29 @@ public class SplitNetworkTransport: NetworkTransport { self.webSocketNetworkTransport = webSocketNetworkTransport } - public func send(operation: Operation, fetchHTTPMethod: FetchHTTPMethod, completionHandler: @escaping (GraphQLResponse?, Error?) -> Void) -> Cancellable { + public func send( + operation: Operation, + fetchHTTPMethod: FetchHTTPMethod, + includeQuery: Bool, + extensions: GraphQLMap?, + completionHandler: @escaping (GraphQLResponse?, Error?) -> Void + ) -> Cancellable { if operation.operationType == .subscription { - return webSocketNetworkTransport.send(operation: operation, fetchHTTPMethod: fetchHTTPMethod, completionHandler: completionHandler) + return webSocketNetworkTransport.send( + operation: operation, + fetchHTTPMethod: fetchHTTPMethod, + includeQuery: includeQuery, + extensions: extensions, + completionHandler: completionHandler + ) } else { - return httpNetworkTransport.send(operation: operation, fetchHTTPMethod: fetchHTTPMethod, completionHandler: completionHandler) + return httpNetworkTransport.send( + operation: operation, + fetchHTTPMethod: fetchHTTPMethod, + includeQuery: includeQuery, + extensions: extensions, + completionHandler: completionHandler + ) } } } diff --git a/Sources/ApolloWebSocket/WebSocketTransport.swift b/Sources/ApolloWebSocket/WebSocketTransport.swift index c199326d86..83feaf2ef9 100644 --- a/Sources/ApolloWebSocket/WebSocketTransport.swift +++ b/Sources/ApolloWebSocket/WebSocketTransport.swift @@ -59,12 +59,18 @@ public class WebSocketTransport: NetworkTransport, WebSocketDelegate { self.websocket.connect() } - public func send(operation: Operation, fetchHTTPMethod: FetchHTTPMethod, completionHandler: @escaping (_ response: GraphQLResponse?, _ error: Error?) -> Void) -> Cancellable { + public func send( + operation: Operation, + fetchHTTPMethod: FetchHTTPMethod, + includeQuery: Bool = true, + extensions: GraphQLMap? = nil, + completionHandler: @escaping (_ response: GraphQLResponse?, _ error: Error?) -> Void + ) -> Cancellable { if let error = self.error { completionHandler(nil,error) } - return WebSocketTask(self,operation) { (body, error) in + return WebSocketTask(self, operation, includeQuery, extensions) { (body, error) in if let body = body { let response = GraphQLResponse(operation: operation, body: body) completionHandler(response,error) @@ -234,8 +240,13 @@ public class WebSocketTransport: NetworkTransport, WebSocketDelegate { return sequenceNumber } - fileprivate func sendHelper(operation: Operation, resultHandler: @escaping (_ response: JSONObject?, _ error: Error?) -> Void) -> String? { - let body = requestBody(for: operation) + fileprivate func sendHelper( + operation: Operation, + includeQuery: Bool, + extensions: GraphQLMap?, + resultHandler: @escaping (_ response: JSONObject?, _ error: Error?) -> Void + ) -> String? { + let body = requestBody(for: operation, includeQuery: includeQuery, extensions: extensions) let sequenceNumber = "\(nextSequenceNumber())" guard let message = OperationMessage(payload: body, id: sequenceNumber).rawMessage else { @@ -252,14 +263,27 @@ public class WebSocketTransport: NetworkTransport, WebSocketDelegate { return sequenceNumber } - private func requestBody(for operation: Operation) -> GraphQLMap { + private func requestBody( + for operation: Operation, + includeQuery: Bool, + extensions: GraphQLMap? + ) -> GraphQLMap { + let commonBody: GraphQLMap = [ + "variables": operation.queryDocument, + ] + if sendOperationIdentifiers { guard let operationIdentifier = operation.operationIdentifier else { preconditionFailure("To send operation identifiers, Apollo types must be generated with operationIdentifiers") } - return ["id": operationIdentifier, "variables": operation.variables] + return commonBody.merging(["id": operationIdentifier], uniquingKeysWith: { $1 }) } - return ["query": operation.queryDocument, "variables": operation.variables] + + return commonBody + .merging( + ["query": includeQuery ? operation.queryDocument : nil, "extensions": extensions], + uniquingKeysWith: { $1 } + ) } public func unsubscribe(_ subscriptionId: String) { @@ -274,8 +298,19 @@ public class WebSocketTransport: NetworkTransport, WebSocketDelegate { let sequenceNumber : String? let transport: WebSocketTransport - init(_ ws: WebSocketTransport, _ operation: Operation, _ completionHandler: @escaping (_ response: JSONObject?, _ error: Error?) -> Void) { - sequenceNumber = ws.sendHelper(operation: operation, resultHandler: completionHandler) + init( + _ ws: WebSocketTransport, + _ operation: Operation, + _ includeQuery: Bool, + _ extensions: GraphQLMap?, + _ completionHandler: @escaping (_ response: JSONObject?, _ error: Error?) -> Void + ) { + sequenceNumber = ws.sendHelper( + operation: operation, + includeQuery: includeQuery, + extensions: extensions, + resultHandler: completionHandler + ) transport = ws } diff --git a/Tests/ApolloTestSupport/MockNetworkTransport.swift b/Tests/ApolloTestSupport/MockNetworkTransport.swift index c1d73c1620..71178b9ad1 100644 --- a/Tests/ApolloTestSupport/MockNetworkTransport.swift +++ b/Tests/ApolloTestSupport/MockNetworkTransport.swift @@ -8,7 +8,13 @@ public final class MockNetworkTransport: NetworkTransport { self.body = body } - public func send(operation: Operation, fetchHTTPMethod: FetchHTTPMethod, completionHandler: @escaping (_ response: GraphQLResponse?, _ error: Error?) -> Void) -> Cancellable { + public func send( + operation: Operation, + fetchHTTPMethod: FetchHTTPMethod, + includeQuery: Bool, + extensions: GraphQLMap?, + completionHandler: @escaping (_ response: GraphQLResponse?, _ error: Error?) -> Void + ) -> Cancellable { DispatchQueue.global(qos: .default).async { completionHandler(GraphQLResponse(operation: operation, body: self.body), nil) }