├── assets ├── TheBigFatNinja.png └── cryptography.png ├── scripts └── pushTrunk.sh ├── Cryptography.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── matan.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── xcshareddata │ ├── xcbaselines │ │ └── 906740801D2AE326009A988D.xcbaseline │ │ │ ├── 9319B1D1-308B-4DE0-8AFC-F425E365C72F.plist │ │ │ └── Info.plist │ └── xcschemes │ │ └── Cryptography.xcscheme ├── xcuserdata │ └── matan.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── project.pbxproj ├── Cryptography ├── Algorithms │ ├── Hash │ │ ├── HashProtocol.swift │ │ ├── SHA1.swift │ │ ├── MD5.swift │ │ └── SHA2.swift │ └── MAC │ │ ├── MACProtocol.swift │ │ └── HMAC.swift ├── Cryptography.h ├── Extensions │ ├── ArraySlicer.swift │ ├── Accessors.swift │ ├── Arithmetics.swift │ └── Representations.swift ├── Info.plist └── Cryptography.swift ├── .travis.yml ├── CryptographyTests ├── Info.plist ├── Extensions │ ├── ArraySlicerTests.swift │ ├── RepresentationsTests.swift │ ├── AccessorsTests.swift │ └── ArithmeticsTests.swift ├── Algorithms │ ├── Hash │ │ ├── MD5Tests.swift │ │ ├── SHA1Tests.swift │ │ └── SHA2Tests.swift │ └── MAC │ │ └── HMACTests.swift └── CryptographyTests.swift ├── CHANGELOG.md ├── Cryptography.podspec ├── LICENSE ├── .gitignore └── README.md /assets/TheBigFatNinja.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlachmish/Cryptography/HEAD/assets/TheBigFatNinja.png -------------------------------------------------------------------------------- /assets/cryptography.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlachmish/Cryptography/HEAD/assets/cryptography.png -------------------------------------------------------------------------------- /scripts/pushTrunk.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source ~/.rvm/scripts/rvm 4 | rvm use default 5 | pod trunk push -------------------------------------------------------------------------------- /Cryptography.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Cryptography.xcodeproj/project.xcworkspace/xcuserdata/matan.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlachmish/Cryptography/HEAD/Cryptography.xcodeproj/project.xcworkspace/xcuserdata/matan.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Cryptography/Algorithms/Hash/HashProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashProtocol.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 10/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol HashProtocol { 12 | 13 | static func hash(message: [UInt8]) -> [UInt8] 14 | 15 | //Convinence method for working with strings 16 | static func hash(message: String) -> String 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Cryptography/Algorithms/MAC/MACProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MACProtocol.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 10/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol MACProtocol { 12 | 13 | static func authenticate(message: [UInt8], key: [UInt8], hashMethod: HashMethod) -> [UInt8] 14 | 15 | //Convinence method for working with strings 16 | static func authenticate(message: String, key: String, hashMethod: HashMethod) -> String 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Cryptography/Cryptography.h: -------------------------------------------------------------------------------- 1 | // 2 | // Cryptography.h 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 04/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Cryptography. 12 | FOUNDATION_EXPORT double CryptographyVersionNumber; 13 | 14 | //! Project version string for Cryptography. 15 | FOUNDATION_EXPORT const unsigned char CryptographyVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode7.3 3 | xcode_scheme: Cryptography 4 | before_install: 5 | - gem install cocoapods -v '= 1.0.0' 6 | - gem install xcpretty --no-document 7 | script: 8 | - set -o pipefail # required to let xcpretty use the same exit code like xcodebuild 9 | - xcodebuild -project Cryptography.xcodeproj -scheme "Cryptography" -destination name="iPhone 6" -destination name="iPhone 6" test | xcpretty -c 10 | - pod lib lint --quick # lint podspec 11 | after_success: 12 | - bash <(curl -s https://codecov.io/bash) -J 'Cryptography' # Code coverage 13 | deploy: 14 | provider: script 15 | script: pod trunk push 16 | on: 17 | tags: true -------------------------------------------------------------------------------- /Cryptography/Extensions/ArraySlicer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ArraySlicer.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 05/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Array { 12 | 13 | public func splitToChuncks(chunkSize: Int) -> AnyGenerator> { 14 | var offset: Int = 0 15 | return AnyGenerator { 16 | let end = min(chunkSize, self.count - offset) 17 | let result = self[offset.. 2 | 3 | 4 | 5 | classNames 6 | 7 | MD5Tests 8 | 9 | testPerformanceExample() 10 | 11 | com.apple.XCTPerformanceMetric_WallClockTime 12 | 13 | baselineAverage 14 | 0.00034733 15 | baselineIntegrationDisplayName 16 | Local Baseline 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Cryptography.xcodeproj/xcuserdata/matan.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Cryptography.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 906740761D2AE326009A988D 16 | 17 | primary 18 | 19 | 20 | 906740801D2AE326009A988D 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /CryptographyTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | #Change Log 2 | All notable changes to this project will be documented in this file. 3 | `Cryptography` adheres to [Semantic Versioning](http://semver.org/). 4 | 5 | --- 6 | 7 | ## [0.1.2](https://github.com/mlachmish/Cryptography/releases/tag/0.1.2) (07/30/2016) 8 | Released on Saturday, July 30, 2016. 9 | 10 | #### Fixed 11 | * Fixed Cryptography interface 12 | 13 | ## [0.1.1](https://github.com/mlachmish/Cryptography/releases/tag/0.1.1) (07/30/2016) 14 | Released on Saturday, July 30, 2016. 15 | 16 | #### Updated 17 | * Updated documentation 18 | 19 | ## [0.1.0](https://github.com/mlachmish/Cryptography/releases/tag/0.1.0) (07/29/2016) 20 | Released on Friday, July 29, 2016. 21 | 22 | #### Added 23 | * Implementation of SHA-1 24 | * Implementation of SHA-2 (with variants: SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256) 25 | * Implementation of MD5 26 | * Implementation of HMAC -------------------------------------------------------------------------------- /Cryptography/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Cryptography.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'Cryptography' 3 | s.version = '0.1.2' 4 | s.summary = 'A modern cryptography library in Swift.' 5 | 6 | s.description = <<-DESC 7 | A modern cryptography library in Swift. 8 | Features: 9 | Hash Functions - MD5, SHA-1, SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256), SHA-3. 10 | Message Authentication Codes - HMAC 11 | DESC 12 | 13 | s.homepage = 'https://github.com/mlachmish/Cryptography' 14 | s.license = { :type => 'MIT', :file => 'LICENSE' } 15 | s.author = { 'Matan Lachmish' => 'mlachmish@gmail.com' } 16 | s.source = { :git => 'https://github.com/mlachmish/Cryptography.git', :tag => s.version.to_s } 17 | s.social_media_url = 'https://twitter.com/mlachmish' 18 | 19 | s.ios.deployment_target = '8.0' 20 | 21 | s.source_files = 'Cryptography/**/*' 22 | s.requires_arc = true 23 | 24 | end 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Matan Lachmish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CryptographyTests/Extensions/ArraySlicerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ArraySlicerTests.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 27/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Cryptography 11 | 12 | class ArraySlicerTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | } 17 | 18 | override func tearDown() { 19 | super.tearDown() 20 | } 21 | 22 | func testSplitToChuncksWithChunkSize1() { 23 | let array: Array = [UInt8(0x01), UInt8(0x01), UInt8(0x01), UInt8(0x01)] 24 | let slices = array.splitToChuncks(1) 25 | for slice in slices { 26 | XCTAssertEqual(slice, [UInt8(0x01)], "splitToChuncks test failed") 27 | } 28 | } 29 | 30 | func testSplitToChuncksWithChunkSize2() { 31 | let array: Array = [UInt8(0x01), UInt8(0x01), UInt8(0x01), UInt8(0x01)] 32 | let slices = array.splitToChuncks(2) 33 | for slice in slices { 34 | XCTAssertEqual(slice, [UInt8(0x01), UInt8(0x01)], "splitToChuncks test failed") 35 | } 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Cryptography.xcodeproj/xcshareddata/xcbaselines/906740801D2AE326009A988D.xcbaseline/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | runDestinationsByUUID 6 | 7 | 9319B1D1-308B-4DE0-8AFC-F425E365C72F 8 | 9 | localComputer 10 | 11 | busSpeedInMHz 12 | 100 13 | cpuCount 14 | 1 15 | cpuKind 16 | Intel Core i7 17 | cpuSpeedInMHz 18 | 2500 19 | logicalCPUCoresPerPackage 20 | 8 21 | modelCode 22 | MacBookPro11,5 23 | physicalCPUCoresPerPackage 24 | 4 25 | platformIdentifier 26 | com.apple.platform.macosx 27 | 28 | targetArchitecture 29 | x86_64 30 | targetDevice 31 | 32 | modelCode 33 | iPhone8,2 34 | platformIdentifier 35 | com.apple.platform.iphonesimulator 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /CryptographyTests/Algorithms/Hash/MD5Tests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MD5Tests.swift 3 | // MD5Tests 4 | // 5 | // Created by Matan Lachmish on 04/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Cryptography 11 | 12 | class MD5Tests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | } 17 | 18 | override func tearDown() { 19 | super.tearDown() 20 | } 21 | 22 | func testPositive1() { 23 | XCTAssertEqual(MD5.hash(""), 24 | "d41d8cd98f00b204e9800998ecf8427e", 25 | "MD5 test failed") 26 | } 27 | 28 | func testPositive2() { 29 | XCTAssertEqual(MD5.hash("The quick brown fox jumps over the lazy dog"), 30 | "9e107d9d372bb6826bd81d3542a419d6", 31 | "MD5 test failed") 32 | } 33 | 34 | func testPositive3() { 35 | XCTAssertEqual(MD5.hash("The quick brown fox jumps over the lazy dog."), 36 | "e4d909c290d0fb1ca068ffaddf22cbd0", 37 | "MD5 test failed") 38 | } 39 | 40 | // Mark: Performance tests 41 | func testPerformanceExample() { 42 | self.measureBlock { 43 | MD5.hash("The quick brown fox jumps over the lazy dog") 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /CryptographyTests/Algorithms/Hash/SHA1Tests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SHA1Tests.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 07/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SHA1Tests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | } 16 | 17 | override func tearDown() { 18 | super.tearDown() 19 | } 20 | 21 | func testPositive1() { 22 | XCTAssertEqual(SHA1.hash(""), 23 | "da39a3ee5e6b4b0d3255bfef95601890afd80709", 24 | "SHA1 test failed") 25 | } 26 | 27 | func testPositive2() { 28 | XCTAssertEqual(SHA1.hash("The quick brown fox jumps over the lazy dog"), 29 | "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", 30 | "SHA1 test failed") 31 | } 32 | 33 | func testPositive3() { 34 | XCTAssertEqual(SHA1.hash("The quick brown fox jumps over the lazy dog."), 35 | "408d94384216f890ff7a0c3528e8bed1e0b01621", 36 | "SHA1 test failed") 37 | } 38 | 39 | // Mark: Performance tests 40 | func testPerformanceExample() { 41 | self.measureBlock { 42 | SHA1.hash("The quick brown fox jumps over the lazy dog") 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Cryptography/Extensions/Accessors.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Accessors.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 06/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | internal extension UInt32 { 12 | 13 | var firstByte: UInt8 { 14 | return UInt8(self & 0xff) 15 | } 16 | 17 | var secondByte: UInt8 { 18 | return UInt8((self >> 8) & 0xff) 19 | } 20 | 21 | var thirdByte: UInt8 { 22 | return UInt8((self >> 16) & 0xff) 23 | } 24 | 25 | var fourthByte: UInt8 { 26 | return UInt8((self >> 24) & 0xff) 27 | } 28 | 29 | } 30 | 31 | internal extension UInt64 { 32 | 33 | var firstByte: UInt8 { 34 | return UInt8(self & 0xff) 35 | } 36 | 37 | var secondByte: UInt8 { 38 | return UInt8((self >> 8) & 0xff) 39 | } 40 | 41 | var thirdByte: UInt8 { 42 | return UInt8((self >> 16) & 0xff) 43 | } 44 | 45 | var fourthByte: UInt8 { 46 | return UInt8((self >> 24) & 0xff) 47 | } 48 | 49 | var fifthByte: UInt8 { 50 | return UInt8((self >> 32) & 0xff) 51 | } 52 | 53 | var sixthByte: UInt8 { 54 | return UInt8((self >> 40) & 0xff) 55 | } 56 | 57 | var seventhByte: UInt8 { 58 | return UInt8((self >> 48) & 0xff) 59 | } 60 | 61 | var eighthByte: UInt8 { 62 | return UInt8((self >> 56) & 0xff) 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /Cryptography/Extensions/Arithmetics.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Arithmetics.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 05/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | internal extension UInt32 { 12 | 13 | func rotateLeft(times: UInt32) -> UInt32 { 14 | return (self << times) | (self >> (32 - times)) 15 | } 16 | 17 | func rotateRight(times: UInt32) -> UInt32 { 18 | return (self >> times) | (self << (32 - times)) 19 | } 20 | 21 | func reverseBytes() -> UInt32 { 22 | let tmp1 = ((self & 0x000000FF) << 24) | ((self & 0x0000FF00) << 8) 23 | let tmp2 = ((self & 0x00FF0000) >> 8) | ((self & 0xFF000000) >> 24) 24 | return tmp1 | tmp2 25 | } 26 | 27 | } 28 | 29 | internal extension UInt64 { 30 | 31 | func rotateLeft(times: UInt64) -> UInt64 { 32 | return (self << times) | (self >> (64 - times)) 33 | } 34 | 35 | func rotateRight(times: UInt64) -> UInt64 { 36 | return ((self >> times) | (self << (64 - times))) 37 | } 38 | 39 | func reverseBytes() -> UInt64 { 40 | let tmp1 = ((self & 0x00000000000000FF) << 56) | 41 | ((self & 0x000000000000FF00) << 40) | 42 | ((self & 0x0000000000FF0000) << 24) | 43 | ((self & 0x00000000FF000000) << 8) 44 | 45 | let tmp2 = ((self & 0x000000FF00000000) >> 8) | 46 | ((self & 0x0000FF0000000000) >> 24) | 47 | ((self & 0x00FF000000000000) >> 40) | 48 | ((self & 0xFF00000000000000) >> 56) 49 | 50 | return tmp1 | tmp2 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /CryptographyTests/Extensions/RepresentationsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RepresentationsTests.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 27/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Cryptography 11 | 12 | class RepresentationsTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | } 17 | 18 | override func tearDown() { 19 | super.tearDown() 20 | } 21 | 22 | func testToUInt8Array() { 23 | let expectedValue = [UInt8(0x00), UInt8(0x00), UInt8(0x00), UInt8(0x00), 24 | UInt8(0x00), UInt8(0x00), UInt8(0x00), UInt8(0x40)] 25 | XCTAssertEqual(Representations.toUInt8Array(64), expectedValue) 26 | } 27 | 28 | func testMergeToUInt32Array() { 29 | XCTAssertEqual(Representations.mergeToUInt32Array( 30 | [UInt8(0x01), UInt8(0x01), UInt8(0x01), UInt8(0x01), 31 | UInt8(0x01), UInt8(0x01), UInt8(0x01), UInt8(0x01)]), 32 | [UInt32(0x01010101), UInt32(0x01010101)]) 33 | } 34 | 35 | func testMergeToUInt64Array() { 36 | XCTAssertEqual(Representations.mergeToUInt64Array( 37 | [UInt8(0x01), UInt8(0x01), UInt8(0x01), UInt8(0x01), 38 | UInt8(0x01), UInt8(0x01), UInt8(0x01), UInt8(0x01), 39 | UInt8(0x01), UInt8(0x01), UInt8(0x01), UInt8(0x01), 40 | UInt8(0x01), UInt8(0x01), UInt8(0x01), UInt8(0x01)]), 41 | [UInt64(0x0101010101010101), UInt64(0x0101010101010101)]) 42 | } 43 | 44 | func testToHexadecimalString() { 45 | XCTAssertEqual(Representations.toHexadecimalString( 46 | [UInt8(0x01), UInt8(0x01), UInt8(0x01), UInt8(0x01)]), 47 | "01010101") 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/osx,appcode,xcode 3 | 4 | ### OSX ### 5 | *.DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | 9 | # Icon must end with two \r 10 | Icon 11 | 12 | 13 | # Thumbnails 14 | ._* 15 | 16 | # Files that might appear in the root of a volume 17 | .DocumentRevisions-V100 18 | .fseventsd 19 | .Spotlight-V100 20 | .TemporaryItems 21 | .Trashes 22 | .VolumeIcon.icns 23 | .com.apple.timemachine.donotpresent 24 | 25 | # Directories potentially created on remote AFP share 26 | .AppleDB 27 | .AppleDesktop 28 | Network Trash Folder 29 | Temporary Items 30 | .apdisk 31 | 32 | 33 | ### AppCode ### 34 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 35 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 36 | .idea 37 | 38 | # User-specific stuff: 39 | .idea/workspace.xml 40 | .idea/tasks.xml 41 | .idea/dictionaries 42 | .idea/vcs.xml 43 | .idea/jsLibraryMappings.xml 44 | 45 | # Sensitive or high-churn files: 46 | .idea/dataSources.ids 47 | .idea/dataSources.xml 48 | .idea/dataSources.local.xml 49 | .idea/sqlDataSources.xml 50 | .idea/dynamic.xml 51 | .idea/uiDesigner.xml 52 | 53 | # Gradle: 54 | .idea/gradle.xml 55 | .idea/libraries 56 | 57 | # Mongo Explorer plugin: 58 | .idea/mongoSettings.xml 59 | 60 | ## File-based project format: 61 | *.iws 62 | 63 | ## Plugin-specific files: 64 | 65 | # IntelliJ 66 | /out/ 67 | 68 | # mpeltonen/sbt-idea plugin 69 | .idea_modules/ 70 | 71 | # JIRA plugin 72 | atlassian-ide-plugin.xml 73 | 74 | # Crashlytics plugin (for Android Studio and IntelliJ) 75 | com_crashlytics_export_strings.xml 76 | crashlytics.properties 77 | crashlytics-build.properties 78 | fabric.properties 79 | 80 | ### AppCode Patch ### 81 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 82 | 83 | # *.iml 84 | # modules.xml 85 | 86 | 87 | ### Xcode ### 88 | # Xcode 89 | # 90 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 91 | 92 | ## Build generated 93 | build/ 94 | DerivedData/ 95 | 96 | ## Various settings 97 | *.pbxuser 98 | !default.pbxuser 99 | *.mode1v3 100 | !default.mode1v3 101 | *.mode2v3 102 | !default.mode2v3 103 | *.perspectivev3 104 | !default.perspectivev3 105 | xcuserdata/ 106 | 107 | ## Other 108 | *.moved-aside 109 | *.xccheckout 110 | *.xcscmblueprint -------------------------------------------------------------------------------- /CryptographyTests/Extensions/AccessorsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Matan Lachmish on 06/07/2016. 3 | // Copyright (c) 2016 The Big Fat Ninja. All rights reserved. 4 | // 5 | 6 | import XCTest 7 | @testable import Cryptography 8 | 9 | class AccessorsTests: XCTestCase { 10 | 11 | override func setUp() { 12 | super.setUp() 13 | } 14 | 15 | override func tearDown() { 16 | super.tearDown() 17 | } 18 | 19 | // MARK: UInt32 accessors 20 | func testUInt32FirstByte() { 21 | let val1 = 0xA5C964F2 as UInt32 22 | XCTAssertEqual(val1.firstByte, 0xF2, "Accessors test failed") 23 | } 24 | 25 | func testUInt32SecondByte() { 26 | let val1 = 0xA5C964F2 as UInt32 27 | XCTAssertEqual(val1.secondByte, 0x64, "Accessors test failed") 28 | } 29 | 30 | func testUInt32ThirdByte() { 31 | let val1 = 0xA5C964F2 as UInt32 32 | XCTAssertEqual(val1.thirdByte, 0xC9, "Accessors test failed") 33 | } 34 | 35 | func testUInt32FourthByte() { 36 | let val1 = 0xA5C964F2 as UInt32 37 | XCTAssertEqual(val1.fourthByte, 0xA5, "Accessors test failed") 38 | } 39 | 40 | // MARK: UInt64 accessors 41 | func testUInt64FirstByte() { 42 | let val1 = 0xA5C964F25A810FE9 as UInt64 43 | XCTAssertEqual(val1.firstByte, 0xE9, "Accessors test failed") 44 | } 45 | 46 | func testUInt64SecondByte() { 47 | let val1 = 0xA5C964F25A810FE9 as UInt64 48 | XCTAssertEqual(val1.secondByte, 0x0F, "Accessors test failed") 49 | } 50 | 51 | func testUInt64ThirdByte() { 52 | let val1 = 0xA5C964F25A810FE9 as UInt64 53 | XCTAssertEqual(val1.thirdByte, 0x81, "Accessors test failed") 54 | } 55 | 56 | func testUInt64FourthByte() { 57 | let val1 = 0xA5C964F25A810FE9 as UInt64 58 | XCTAssertEqual(val1.fourthByte, 0x5A, "Accessors test failed") 59 | } 60 | 61 | func testUInt64FifthByte() { 62 | let val1 = 0xA5C964F25A810FE9 as UInt64 63 | XCTAssertEqual(val1.fifthByte, 0xF2, "Accessors test failed") 64 | } 65 | 66 | func testUInt64SixthByte() { 67 | let val1 = 0xA5C964F25A810FE9 as UInt64 68 | XCTAssertEqual(val1.sixthByte, 0x64, "Accessors test failed") 69 | } 70 | 71 | func testUInt64SeventhByte() { 72 | let val1 = 0xA5C964F25A810FE9 as UInt64 73 | XCTAssertEqual(val1.seventhByte, 0xC9, "Accessors test failed") 74 | } 75 | 76 | func testUInt64EightthByte() { 77 | let val1 = 0xA5C964F25A810FE9 as UInt64 78 | XCTAssertEqual(val1.eighthByte, 0xA5, "Accessors test failed") 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /Cryptography/Algorithms/MAC/HMAC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HMAC.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 10/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | internal struct HMAC: MACProtocol { 13 | 14 | static private func blockSize(hashMethod: HashMethod) -> Int { 15 | 16 | switch hashMethod { 17 | case .MD5: 18 | return MD5.blockSize 19 | case .SHA1: 20 | return SHA1.blockSize 21 | case .SHA2(let sha2Variant): 22 | switch sha2Variant { 23 | case .SHA224, .SHA256: 24 | return sha2Variant.blockSize 25 | case .SHA384, .SHA512, .SHA512SLASH224, .SHA512SLASH256: 26 | return sha2Variant.blockSize 27 | } 28 | } 29 | 30 | } 31 | 32 | static private func preprocessKey(key: Array, 33 | blockSize: Int, 34 | hashMethod: HashMethod) -> Array { 35 | 36 | if key.count > blockSize { // keys longer than blocksize are shortened 37 | let keyAsString = Representations.toHexadecimalString(key) 38 | let hashedKey = Cryptography.hash(keyAsString, method: hashMethod) 39 | return Representations.toUInt8Array(hashedKey) 40 | } 41 | 42 | if key.count < blockSize { // keys shorter than blocksize are zero-padded 43 | return key + Array(count: blockSize - key.count, repeatedValue: 0) 44 | } 45 | 46 | return key 47 | } 48 | 49 | static func authenticate(message: [UInt8], key: [UInt8], hashMethod: HashMethod) -> [UInt8] { 50 | let preprocessedKey = HMAC.preprocessKey(key, 51 | blockSize: self.blockSize(hashMethod), 52 | hashMethod: hashMethod) 53 | 54 | var opad = Array(count: self.blockSize(hashMethod), repeatedValue: 0x5c) 55 | for (idx, _) in preprocessedKey.enumerate() { 56 | opad[idx] = preprocessedKey[idx] ^ opad[idx] 57 | } 58 | var ipad = Array(count: self.blockSize(hashMethod), repeatedValue: 0x36) 59 | for (idx, _) in preprocessedKey.enumerate() { 60 | ipad[idx] = preprocessedKey[idx] ^ ipad[idx] 61 | } 62 | 63 | let ipadAndMessageHash = Cryptography.hash(ipad + message, method: hashMethod) 64 | return Cryptography.hash(opad + ipadAndMessageHash, method: hashMethod) 65 | } 66 | 67 | static func authenticate(message: String, key: String, hashMethod: HashMethod) -> String { 68 | return Representations.toHexadecimalString( 69 | self.authenticate(Array(message.utf8), key: Array(key.utf8), hashMethod: hashMethod) 70 | ) 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /Cryptography/Extensions/Representations.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Representations.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 05/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | internal class Representations { 12 | 13 | // Array of bytes with optional padding (little-endian) 14 | static func toUInt8Array(value: T, length: Int? = nil) -> Array { 15 | let totalBytes = length ?? sizeof(T) 16 | var copyOfValue = value 17 | 18 | return withUnsafePointer(©OfValue) { 19 | Array(UnsafeBufferPointer(start: UnsafePointer($0), count: totalBytes)).reverse() 20 | } 21 | } 22 | 23 | // Merge Array of UInt8 to array of UInt32 24 | static func mergeToUInt32Array(slice: ArraySlice) -> Array { 25 | var result = Array() 26 | result.reserveCapacity(16) 27 | 28 | for idx in slice.startIndex.stride(to: slice.endIndex, by: sizeof(UInt32)) { 29 | let val1: UInt32 = UInt32(slice[idx.advancedBy(3)]) << 24 30 | let val2: UInt32 = UInt32(slice[idx.advancedBy(2)]) << 16 31 | let val3: UInt32 = UInt32(slice[idx.advancedBy(1)]) << 8 32 | let val4: UInt32 = UInt32(slice[idx]) 33 | let val: UInt32 = val1 | val2 | val3 | val4 34 | result.append(val) 35 | } 36 | 37 | return result 38 | } 39 | 40 | // Merge Array of UInt8 to array of UInt64 41 | static func mergeToUInt64Array(slice: ArraySlice) -> Array { 42 | var result = Array() 43 | result.reserveCapacity(32) 44 | 45 | for idx in slice.startIndex.stride(to: slice.endIndex, by: sizeof(UInt64)) { 46 | let val1: UInt64 = UInt64(slice[idx.advancedBy(7)]) << 56 47 | let val2: UInt64 = UInt64(slice[idx.advancedBy(6)]) << 48 48 | let val3: UInt64 = UInt64(slice[idx.advancedBy(5)]) << 40 49 | let val4: UInt64 = UInt64(slice[idx.advancedBy(4)]) << 32 50 | let val5: UInt64 = UInt64(slice[idx.advancedBy(3)]) << 24 51 | let val6: UInt64 = UInt64(slice[idx.advancedBy(2)]) << 16 52 | let val7: UInt64 = UInt64(slice[idx.advancedBy(1)]) << 8 53 | let val8: UInt64 = UInt64(slice[idx]) 54 | let val: UInt64 = val1 | val2 | val3 | val4 | val5 | val6 | val7 | val8 55 | result.append(val) 56 | } 57 | 58 | return result 59 | } 60 | 61 | // Return hexadecimal string representation of Array 62 | static func toHexadecimalString(bytes: Array) -> String { 63 | var hexString = String() 64 | for byte in bytes { 65 | hexString = hexString.stringByAppendingFormat("%02x", byte) 66 | } 67 | 68 | return hexString 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /CryptographyTests/Algorithms/Hash/SHA2Tests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SHA2Tests.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 25/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Cryptography 11 | 12 | class SHA2Tests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | } 17 | 18 | override func tearDown() { 19 | super.tearDown() 20 | } 21 | 22 | func testSHA224Positive1() { 23 | XCTAssertEqual(SHA2Variant.SHA224.hash(""), 24 | "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", 25 | "SHA2-224 test failed") 26 | } 27 | 28 | func testSHA256Positive1() { 29 | XCTAssertEqual(SHA2Variant.SHA256.hash(""), 30 | "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 31 | "SHA2-256 test failed") 32 | } 33 | 34 | func testSHA384Positive1() { 35 | XCTAssertEqual(SHA2Variant.SHA384.hash(""), 36 | "38b060a751ac96384cd9327eb1b1e36a21fdb71114be0743" + 37 | "4c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", 38 | "SHA2-384 test failed") 39 | } 40 | 41 | func testSHA512Positive1() { 42 | XCTAssertEqual(SHA2Variant.SHA512.hash(""), 43 | "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9" + 44 | "ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", 45 | "SHA2-512 test failed") 46 | } 47 | 48 | func testSHA512SLASH224Positive1() { 49 | XCTAssertEqual(SHA2Variant.SHA512SLASH224.hash(""), 50 | "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4", 51 | "SHA2-512/224 test failed") 52 | } 53 | 54 | func testSHA512SLASH256Positive1() { 55 | XCTAssertEqual(SHA2Variant.SHA512SLASH256.hash(""), 56 | "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a", 57 | "SHA2-512/256 test failed") 58 | } 59 | 60 | // Mark: Performance tests 61 | func testPerformanceSHA224() { 62 | self.measureBlock { 63 | SHA2Variant.SHA224.hash("") 64 | } 65 | } 66 | 67 | func testPerformanceSHA256() { 68 | self.measureBlock { 69 | SHA2Variant.SHA256.hash("") 70 | } 71 | } 72 | 73 | func testPerformanceSHA384() { 74 | self.measureBlock { 75 | SHA2Variant.SHA384.hash("") 76 | } 77 | } 78 | 79 | func testPerformanceSHA512() { 80 | self.measureBlock { 81 | SHA2Variant.SHA512.hash("") 82 | } 83 | } 84 | 85 | func testPerformanceSHA512SLASH224() { 86 | self.measureBlock { 87 | SHA2Variant.SHA512SLASH224.hash("") 88 | } 89 | } 90 | 91 | func testPerformanceSHA512SLASH256() { 92 | self.measureBlock { 93 | SHA2Variant.SHA512SLASH256.hash("") 94 | } 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /CryptographyTests/Extensions/ArithmeticsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Matan Lachmish on 06/07/2016. 3 | // Copyright (c) 2016 The Big Fat Ninja. All rights reserved. 4 | // 5 | 6 | import XCTest 7 | @testable import Cryptography 8 | 9 | class ArithmeticsTests: XCTestCase { 10 | 11 | override func setUp() { 12 | super.setUp() 13 | } 14 | 15 | override func tearDown() { 16 | super.tearDown() 17 | } 18 | 19 | // Mark: UInt32 20 | func testUInt32RotateLeft() { 21 | let val1 = 0x00000001 as UInt32 22 | XCTAssertEqual(val1.rotateLeft(0x00000001), 0x00000002, "Rotation test failed") 23 | XCTAssertEqual(val1.rotateLeft(0x00000002), 0x00000004, "Rotation test failed") 24 | 25 | let val2 = 0x00000005 as UInt32 26 | XCTAssertEqual(val2.rotateLeft(0x00000001), 0x0000000a, "Rotation test failed") 27 | XCTAssertEqual(val2.rotateLeft(0x00000002), 0x00000014, "Rotation test failed") 28 | } 29 | 30 | func testUInt32RotateRight() { 31 | let val1 = 0x00000001 as UInt32 32 | XCTAssertEqual(val1.rotateRight(0x00000001), 0x80000000, "Rotation test failed") 33 | XCTAssertEqual(val1.rotateRight(0x00000002), 0x40000000, "Rotation test failed") 34 | 35 | let val2 = 0x00000005 as UInt32 36 | XCTAssertEqual(val2.rotateRight(0x00000001), 0x80000002, "Rotation test failed") 37 | XCTAssertEqual(val2.rotateRight(0x00000002), 0x40000001, "Rotation test failed") 38 | } 39 | 40 | func testUInt32ReverseBytes() { 41 | let val1 = 0x00000001 as UInt32 42 | XCTAssertEqual(val1.reverseBytes(), 0x01000000, "Reverse test failed") 43 | 44 | let val2 = 0x01000001 as UInt32 45 | XCTAssertEqual(val2.reverseBytes(), val2, "Reverse test failed") 46 | } 47 | 48 | // Mark: UInt64 49 | func testUInt64RotateLeft() { 50 | let val1 = 0x0000000000000001 as UInt64 51 | XCTAssertEqual(val1.rotateLeft(0x0000000000000001), 0x0000000000000002, 52 | "Rotation test failed") 53 | XCTAssertEqual(val1.rotateLeft(0x0000000000000002), 0x0000000000000004, 54 | "Rotation test failed") 55 | 56 | let val2 = 0x0000000000000005 as UInt64 57 | XCTAssertEqual(val2.rotateLeft(0x0000000000000001), 0x000000000000000a, 58 | "Rotation test failed") 59 | XCTAssertEqual(val2.rotateLeft(0x0000000000000002), 0x0000000000000014, 60 | "Rotation test failed") 61 | } 62 | 63 | func testUInt64RotateRight() { 64 | let val1 = 0x0000000000000001 as UInt64 65 | XCTAssertEqual(val1.rotateRight(0x0000000000000001), 0x8000000000000000, 66 | "Rotation test failed") 67 | XCTAssertEqual(val1.rotateRight(0x0000000000000002), 0x4000000000000000, 68 | "Rotation test failed") 69 | 70 | let val2 = 0x0000000000000005 as UInt64 71 | XCTAssertEqual(val2.rotateRight(0x0000000000000001), 0x8000000000000002, 72 | "Rotation test failed") 73 | XCTAssertEqual(val2.rotateRight(0x0000000000000002), 0x4000000000000001, 74 | "Rotation test failed") 75 | } 76 | 77 | func testUInt64ReverseBytes() { 78 | let val1 = 0x0000000000000001 as UInt64 79 | XCTAssertEqual(val1.reverseBytes(), 0x0100000000000000, "Reverse test failed") 80 | 81 | let val2 = 0x0100000000000001 as UInt64 82 | XCTAssertEqual(val2.reverseBytes(), val2, "Reverse test failed") 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /Cryptography.xcodeproj/xcshareddata/xcschemes/Cryptography.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Cryptography/Cryptography.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Cryptography.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 06/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // MARK: hash functions 12 | private typealias MD5Impl = MD5 13 | private typealias SHA1Impl = SHA1 14 | private typealias SHA2Impl = SHA2 15 | 16 | /** 17 | Hash Methods. 18 | */ 19 | public enum HashMethod { 20 | /** 21 | The MD5 Message-Digest Algorithm. 22 | https://tools.ietf.org/html/rfc1321 23 | */ 24 | case MD5 25 | 26 | /** 27 | US Secure Hash Algorithm 1 (SHA1). 28 | https://tools.ietf.org/html/rfc3174 29 | */ 30 | case SHA1 31 | 32 | /** 33 | US Secure Hash Algorithm 2 (SHA2). 34 | https://tools.ietf.org/html/rfc6234 35 | 36 | - Parameter sha2Variant: SHA-2 variants: 224, 256, 284, 512, 512/224, 512/256. 37 | */ 38 | case SHA2(sha2Variant: SHA2Variant) 39 | 40 | private func hash(message: [UInt8]) -> [UInt8] { 41 | switch self { 42 | case .MD5: 43 | return MD5Impl.hash(message) 44 | case .SHA1: 45 | return SHA1Impl.hash(message) 46 | case .SHA2(let sha2Variant): 47 | return sha2Variant.hash(message) 48 | } 49 | } 50 | 51 | private func hash(message: String) -> String { 52 | switch self { 53 | case .MD5: 54 | return MD5Impl.hash(message) 55 | case .SHA1: 56 | return SHA1Impl.hash(message) 57 | case .SHA2(let sha2Variant): 58 | return sha2Variant.hash(message) 59 | } 60 | } 61 | } 62 | 63 | // MARK: message authentication codes 64 | private typealias HMACImpl = HMAC 65 | 66 | /** 67 | Message Authentication Codes (MAC). 68 | */ 69 | public enum MACMethod { 70 | /** 71 | HMAC: Keyed-Hashing for Message Authentication. 72 | https://www.ietf.org/rfc/rfc2104 73 | 74 | - Parameter hashMethod: The hash method that sould be used 75 | in the HMAC algorithm (see @HashMethod). 76 | */ 77 | case HMAC(hashMethod: HashMethod) 78 | 79 | private func authenticate(message: [UInt8], key: [UInt8]) -> [UInt8] { 80 | switch self { 81 | case .HMAC(let hashMethod): 82 | return HMACImpl.authenticate(message, key: key, hashMethod: hashMethod) 83 | } 84 | } 85 | 86 | private func authenticate(message: String, key: String) -> String { 87 | switch self { 88 | case .HMAC(let hashMethod): 89 | return HMACImpl.authenticate(message, key: key, hashMethod: hashMethod) 90 | } 91 | } 92 | } 93 | 94 | /** 95 | Public facade, 96 | This is the single entry point to the entire framework. 97 | */ 98 | public struct Cryptography { 99 | 100 | /** 101 | Calculate hash function. 102 | 103 | - Parameter message: The message that should be hashed, formatted as **Byte Array**. 104 | - parameter method: The Hash Method. 105 | 106 | - Returns: The calculated hash value. 107 | */ 108 | public static func hash(message: [UInt8], method: HashMethod) -> [UInt8] { 109 | return method.hash(message) 110 | } 111 | 112 | /** 113 | Calculate hash function. 114 | 115 | - parameter message: The message that should be hashed, formatted as **String**. 116 | - parameter method: The Hash Method. 117 | 118 | - returns: The calculated hash value. 119 | */ 120 | public static func hash(message: String, method: HashMethod) -> String { 121 | return method.hash(message) 122 | } 123 | 124 | /** 125 | Calculate message authentication code (MAC). 126 | 127 | - parameter message: The message that should be authenticated, formatted as **Byte Array**. 128 | - parameter key: The key which should be used, formatted as **Byte Array**. 129 | - parameter method: The Hash Method. 130 | 131 | - returns: The calculated code value. 132 | */ 133 | public static func authenticate(message: [UInt8], key: [UInt8], method: MACMethod) -> [UInt8] { 134 | return method.authenticate(message, key: key) 135 | } 136 | 137 | /** 138 | Calculate message authentication code (MAC). 139 | 140 | - parameter message: The message that should be authenticated, formatted as **String**. 141 | - parameter key: The key which should be used, formatted as **String**. 142 | - parameter method: The Hash Method. 143 | 144 | - returns: The calculated code value. 145 | */ 146 | public static func authenticate(message: String, key: String, method: MACMethod) -> String { 147 | return method.authenticate(message, key: key) 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /CryptographyTests/CryptographyTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CryptographyTests.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 25/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Cryptography 11 | 12 | class CryptographyTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | } 17 | 18 | override func tearDown() { 19 | super.tearDown() 20 | } 21 | 22 | // Test Hash 23 | func testMD5() { 24 | XCTAssertEqual(Cryptography.hash("", method: HashMethod.MD5), 25 | "d41d8cd98f00b204e9800998ecf8427e", 26 | "MD5 sanity failed") 27 | } 28 | 29 | func testSHA1() { 30 | XCTAssertEqual(Cryptography.hash("", method: HashMethod.SHA1), 31 | "da39a3ee5e6b4b0d3255bfef95601890afd80709", 32 | "SHA1 sanity failed") 33 | } 34 | 35 | func testSHA224() { 36 | XCTAssertEqual(Cryptography.hash("", 37 | method: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA224)), 38 | "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", 39 | "SHA2-224 sanity failed") 40 | } 41 | 42 | func testSHA256() { 43 | XCTAssertEqual(Cryptography.hash("", 44 | method: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA256)), 45 | "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 46 | "SHA2-256 sanity failed") 47 | } 48 | 49 | func testSHA384() { 50 | XCTAssertEqual(Cryptography.hash("", 51 | method: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA384)), 52 | "38b060a751ac96384cd9327eb1b1e36a21fdb71114be0743" + 53 | "4c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", 54 | "SHA2-384 sanity failed") 55 | } 56 | 57 | func testSHA512() { 58 | XCTAssertEqual(Cryptography.hash("", 59 | method: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA512)), 60 | "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9" + 61 | "ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", 62 | "SHA2-512 sanity failed") 63 | } 64 | 65 | func testSHA512SLASH224() { 66 | XCTAssertEqual(Cryptography.hash("", 67 | method: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA512SLASH224)), 68 | "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4", 69 | "SHA2-512/224 sanity failed") 70 | } 71 | 72 | func testSHA512SLASH256() { 73 | XCTAssertEqual(Cryptography.hash("", 74 | method: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA512SLASH256)), 75 | "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a", 76 | "SHA2-512/256 sanity failed") 77 | } 78 | 79 | // Test MAC 80 | func testHMACwMD5Positive1() { 81 | XCTAssertEqual(Cryptography.authenticate("", key: "", 82 | method: MACMethod.HMAC(hashMethod: HashMethod.MD5)), 83 | "74e6f7298a9c2d168935f58c001bad88") 84 | } 85 | 86 | func testHMACwSHA1Positive1() { 87 | XCTAssertEqual(Cryptography.authenticate("", key: "", 88 | method: MACMethod.HMAC(hashMethod: HashMethod.SHA1)), 89 | "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d") 90 | } 91 | 92 | func testHMACwSHA256Positive1() { 93 | XCTAssertEqual(Cryptography.authenticate("", key: "", 94 | method: MACMethod.HMAC(hashMethod: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA256))), 95 | "b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad") 96 | } 97 | 98 | func testHMACwSHA384Positive1() { 99 | XCTAssertEqual( 100 | Cryptography.authenticate("", 101 | key: "", 102 | method: MACMethod.HMAC(hashMethod:HashMethod.SHA2(sha2Variant:SHA2Variant.SHA384))), 103 | // swiftlint:disable line_length 104 | "6c1f2ee938fad2e24bd91298474382ca218c75db3d83e114b3d4367776d14d3551289e75e8209cd4b792302840234adc") 105 | // swiftlint:enable line_length 106 | } 107 | 108 | func testHMACwSHA512Positive1() { 109 | XCTAssertEqual( 110 | Cryptography.authenticate("", 111 | key: "", 112 | method: MACMethod.HMAC(hashMethod:HashMethod.SHA2(sha2Variant:SHA2Variant.SHA512))), 113 | // swiftlint:disable line_length 114 | "b936cee86c9f87aa5d3c6f2e84cb5a4239a5fe50480a6ec66b70ab5b1f4ac6730c6c515421b327ec1d69402e53dfb49ad7381eb067b338fd7b0cb22247225d47") 115 | // swiftlint:enable line_length 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /Cryptography/Algorithms/Hash/SHA1.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SHA1.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 07/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | internal struct SHA1: HashProtocol { 12 | 13 | static let blockSize = 64 14 | 15 | private static func preprocessMessage(message: Array) -> Array { 16 | var preprocessedMessage = message 17 | // Pre-processing: adding a single 1 bit 18 | // Notice: the input bytes are considered as bits strings, 19 | // where the first bit is the most significant bit of the byte. 20 | preprocessedMessage.append(0x80) 21 | 22 | // Pre-processing: padding with zeros 23 | // append "0" bit until message length in bits ≡ 448 (mod 512) 24 | let desiredMessageLengthModulo = blockSize - 8 25 | var messageLength = preprocessedMessage.count 26 | var paddingCounter = 0 27 | while messageLength % blockSize != desiredMessageLengthModulo { 28 | paddingCounter += 1 29 | messageLength += 1 30 | } 31 | preprocessedMessage += Array(count: paddingCounter, repeatedValue: 0) 32 | // append original length in bits mod (2 pow 64) to message 33 | preprocessedMessage.reserveCapacity(preprocessedMessage.count + 4) 34 | let lengthInBits = message.count * 8 35 | let lengthBytes = Representations.toUInt8Array(lengthInBits, length: 64/8) 36 | preprocessedMessage += lengthBytes 37 | return preprocessedMessage 38 | } 39 | 40 | // swiftlint:disable function_body_length 41 | static func hash(message: [UInt8]) -> [UInt8] { 42 | // Initialize variables: 43 | var a0: UInt32 = 0x67452301 // A 44 | var b0: UInt32 = 0xefcdab89 // B 45 | var c0: UInt32 = 0x98badcfe // C 46 | var d0: UInt32 = 0x10325476 // D 47 | var e0: UInt32 = 0xC3D2E1F0 // E 48 | 49 | // Pre-processing 50 | let preprocessedMessage = preprocessMessage(message) 51 | 52 | // Process the message in successive 512-bit chunks: 53 | let chunkSizeBytes = 512 / 8 54 | for chunk in preprocessedMessage.splitToChuncks(chunkSizeBytes) { 55 | // Break chunk into sixteen 32-bit big-endian words w[i], 0 ≤ i ≤ 15 56 | // Extend the sixteen 32-bit words into eighty 32-bit words: 57 | var M: Array = Array(count: 80, repeatedValue: 0) 58 | 59 | for x in 0..() 124 | result.reserveCapacity(160/8) 125 | 126 | [a0, b0, c0, d0, e0].forEach { 127 | result += Representations.toUInt8Array($0.bigEndian.reverseBytes()) 128 | } 129 | 130 | return result 131 | } 132 | // swiftlint:enable function_body_length 133 | 134 | static func hash(message: String) -> String { 135 | return Representations.toHexadecimalString(self.hash(Array(message.utf8))) 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /CryptographyTests/Algorithms/MAC/HMACTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HMACTests.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 27/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class HMACTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | } 16 | 17 | override func tearDown() { 18 | super.tearDown() 19 | } 20 | 21 | func testHMACwMD5Positive1() { 22 | XCTAssertEqual( 23 | HMAC.authenticate("", key: "", hashMethod: HashMethod.MD5), 24 | "74e6f7298a9c2d168935f58c001bad88") 25 | } 26 | 27 | func testHMACwMD5Positive2() { 28 | XCTAssertEqual( 29 | HMAC.authenticate("The quick brown fox jumps over the lazy dog", 30 | key: "key", 31 | hashMethod: HashMethod.MD5), 32 | "80070713463e7749b90c2dc24911e275") 33 | } 34 | 35 | func testHMACwSHA1Positive1() { 36 | XCTAssertEqual( 37 | HMAC.authenticate("", key: "", hashMethod: HashMethod.SHA1), 38 | "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d") 39 | } 40 | 41 | func testHMACwSHA1Positive2() { 42 | XCTAssertEqual( 43 | HMAC.authenticate("The quick brown fox jumps over the lazy dog", 44 | key: "key", 45 | hashMethod: HashMethod.SHA1), 46 | "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9") 47 | } 48 | 49 | func testHMACwSHA224Positive1() { 50 | XCTAssertEqual( 51 | HMAC.authenticate("", 52 | key: "", 53 | hashMethod: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA224)), 54 | "5ce14f72894662213e2748d2a6ba234b74263910cedde2f5a9271524") 55 | } 56 | 57 | func testHMACwSHA224Positive2() { 58 | XCTAssertEqual( 59 | HMAC.authenticate("The quick brown fox jumps over the lazy dog", 60 | key: "key", 61 | hashMethod: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA224)), 62 | "88ff8b54675d39b8f72322e65ff945c52d96379988ada25639747e69") 63 | } 64 | 65 | func testHMACwSHA256Positive1() { 66 | XCTAssertEqual( 67 | HMAC.authenticate("", 68 | key: "", 69 | hashMethod: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA256)), 70 | "b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad") 71 | } 72 | 73 | func testHMACwSHA256Positive2() { 74 | XCTAssertEqual( 75 | HMAC.authenticate("The quick brown fox jumps over the lazy dog", 76 | key: "key", 77 | hashMethod: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA256)), 78 | "f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8") 79 | } 80 | 81 | func testHMACwSHA384Positive1() { 82 | XCTAssertEqual( 83 | HMAC.authenticate("", 84 | key: "", 85 | hashMethod: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA384)), 86 | // swiftlint:disable line_length 87 | "6c1f2ee938fad2e24bd91298474382ca218c75db3d83e114b3d4367776d14d3551289e75e8209cd4b792302840234adc") 88 | // swiftlint:enable line_length 89 | } 90 | 91 | func testHMACwSHA384Positive2() { 92 | XCTAssertEqual( 93 | HMAC.authenticate("The quick brown fox jumps over the lazy dog", 94 | key: "key", 95 | hashMethod: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA384)), 96 | // swiftlint:disable line_length 97 | "d7f4727e2c0b39ae0f1e40cc96f60242d5b7801841cea6fc592c5d3e1ae50700582a96cf35e1e554995fe4e03381c237") 98 | // swiftlint:enable line_length 99 | } 100 | 101 | func testHMACwSHA512Positive1() { 102 | XCTAssertEqual( 103 | HMAC.authenticate("", 104 | key: "", 105 | hashMethod: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA512)), 106 | // swiftlint:disable line_length 107 | "b936cee86c9f87aa5d3c6f2e84cb5a4239a5fe50480a6ec66b70ab5b1f4ac6730c6c515421b327ec1d69402e53dfb49ad7381eb067b338fd7b0cb22247225d47") 108 | // swiftlint:enable line_length 109 | } 110 | 111 | func testHMACwSHA512Positive2() { 112 | XCTAssertEqual( 113 | HMAC.authenticate("The quick brown fox jumps over the lazy dog", 114 | key: "key", 115 | hashMethod: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA512)), 116 | // swiftlint:disable line_length 117 | "b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a") 118 | // swiftlint:enable line_length 119 | } 120 | 121 | // Mark: Performance tests 122 | func testHMACwMD5Performance() { 123 | self.measureBlock { 124 | HMAC.authenticate("", key: "", 125 | hashMethod: HashMethod.MD5) 126 | } 127 | } 128 | 129 | func testHMACwSHA1Performance() { 130 | self.measureBlock { 131 | HMAC.authenticate("", key: "", 132 | hashMethod: HashMethod.SHA1) 133 | } 134 | } 135 | 136 | func testHMACwSHA256Performance() { 137 | self.measureBlock { 138 | HMAC.authenticate("", key: "", 139 | hashMethod: HashMethod.SHA2(sha2Variant: SHA2Variant.SHA256)) 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /Cryptography/Algorithms/Hash/MD5.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Matan Lachmish on 04/07/2016. 3 | // Copyright (c) 2016 The Big Fat Ninja. All rights reserved. 4 | // 5 | 6 | import Foundation 7 | 8 | // Fowllowing the pseudo code from https://en.wikipedia.org/wiki/MD5 9 | 10 | internal struct MD5: HashProtocol { 11 | 12 | internal static let blockSize = 64 13 | 14 | // swiftlint:disable variable_name 15 | // swiftlint:disable line_length 16 | // swiftlint:disable comma 17 | 18 | // Specifies the per-round shift amounts 19 | private static let s: Array = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 20 | 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 21 | 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 22 | 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21] 23 | 24 | // Use binary integer part of the sines of integers (Radians) as constants 25 | private static let k: Array = [0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 26 | 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 27 | 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 28 | 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 29 | 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 30 | 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 31 | 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 32 | 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 33 | 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 34 | 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 35 | 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, 36 | 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 37 | 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 38 | 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 39 | 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 40 | 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391] 41 | // swiftlint:enable variable_name 42 | // swiftlint:enable line_length 43 | // swiftlint:enable comma 44 | 45 | private static func preprocessMessage(message: Array) -> Array { 46 | var preprocessedMessage = message // Copy message 47 | 48 | // Pre-processing: adding a single 1 bit 49 | // Notice: the input bytes are considered as bits strings, 50 | // where the first bit is the most significant bit of the byte. 51 | preprocessedMessage.append(0x80) 52 | 53 | // Pre-processing: padding with zeros 54 | // append "0" bit until message length in bits ≡ 448 (mod 512) 55 | let desiredMessageLengthModulo = blockSize - 8 56 | var messageLength = preprocessedMessage.count 57 | var paddingCounter = 0 58 | while messageLength % blockSize != desiredMessageLengthModulo { 59 | paddingCounter += 1 60 | messageLength += 1 61 | } 62 | preprocessedMessage += Array(count: paddingCounter, repeatedValue: 0) 63 | 64 | // append original length in bits mod (2 pow 64) to message 65 | preprocessedMessage.reserveCapacity(preprocessedMessage.count + 4) 66 | let lengthInBits = message.count * 8 67 | let lengthBytes = Representations.toUInt8Array(lengthInBits, length: 64/8) 68 | preprocessedMessage += lengthBytes.reverse() 69 | return preprocessedMessage 70 | } 71 | 72 | // swiftlint:disable function_body_length 73 | static func hash(message: [UInt8]) -> [UInt8] { 74 | // Initialize variables: 75 | var a0: UInt32 = 0x67452301 // A 76 | var b0: UInt32 = 0xefcdab89 // B 77 | var c0: UInt32 = 0x98badcfe // C 78 | var d0: UInt32 = 0x10325476 // D 79 | 80 | // Pre-processing 81 | let preprocessedMessage = preprocessMessage(message) 82 | 83 | // Process the message in successive 512-bit chunks: 84 | let chunkSizeBytes = 512 / 8 85 | 86 | for chunk in preprocessedMessage.splitToChuncks(chunkSizeBytes) { 87 | // break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15 88 | let M = Representations.mergeToUInt32Array(chunk) 89 | 90 | // Initialize hash value for this chunk: 91 | var A: UInt32 = a0 92 | var B: UInt32 = b0 93 | var C: UInt32 = c0 94 | var D: UInt32 = d0 95 | 96 | // Main loop: 97 | for i in 0..() 136 | 137 | result.reserveCapacity(128/8) 138 | [a0, b0, c0, d0].forEach { 139 | result += Representations.toUInt8Array($0.littleEndian.reverseBytes()) 140 | } 141 | 142 | return result 143 | } 144 | // swiftlint:enable function_body_length 145 | 146 | static func hash(message: String) -> String { 147 | return Representations.toHexadecimalString(self.hash(Array(message.utf8))) 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Cryptography 3 |

4 | 5 |

6 | 7 | Language 8 | 9 | 10 | Platform 11 | 12 | 13 | MIT licensed 14 | 15 |
16 | 17 | Build Status 18 | 19 | 20 | Code Quality 21 | 22 | 23 | Code Coverage 24 | 25 | 26 | Doc Coverage 27 | 28 |
29 | 30 | CocoaPods 32 | 33 | 34 | Carthage 36 | 37 |

38 | 39 |
40 |

A modern cryptography library in Swift.

41 |

42 | Features 43 | • Usage 44 | • Installation 45 | • Documentation 46 | • Author 47 | • License 48 |

49 | 50 | ## Features 51 | 52 | - [x] Hash Functions 53 | - MD5 54 | - SHA-1 55 | - SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256) 56 | - SHA-3 57 | - [x] Message Authentication Codes 58 | - HMAC (via: SHA-3/SHA-2/SHA-1/MD5) 59 | 60 | ### Soon to come 61 | - [ ] High Speed Stream Ciphers 62 | - ChaCha 63 | - Panama 64 | - Sosemanuk 65 | - Salsa20 66 | - [ ] block ciphers 67 | - AES (Rijndael) 68 | - Triple-DES (DES-EDE2 and DES-EDE3) 69 | - Blowfish 70 | - RC5 71 | - [ ] Message Authentication Codes 72 | - VMAC 73 | - CMAC 74 | - GMAC 75 | - [ ] Hash Functions 76 | - BLAKE2s 77 | - BLAKE2b 78 | - RIPEMD 79 | - [ ] Public-Key Cryptography 80 | - RSA 81 | - DSA 82 | - ElGamal 83 | - Nyberg-Rueppel (NR) 84 | - Rabin-Williams (RW) 85 | - [ ] Key Agreement Schemes 86 | - Diffie-Hellman (DH) 87 | - Unified Diffie-Hellman (DH2) 88 | - [ ] Elliptic Curve Cryptography 89 | - ECDSA 90 | - ECNR 91 | - ECIES 92 | 93 | ## Usage 94 | 95 | * [Hash Functions](#hash-functions) 96 | * [Message Authentication Codes](#message-authentication-codes) 97 | 98 | First import Cryptography module. 99 | ```swift 100 | import Cryptography 101 | ``` 102 | Everything you need is available via the ``` Cryptography ``` facade. 103 | 104 | ### Hash Functions 105 | In order to calculate a hash value you simply call ``` Cryptography.hash(message: String, method: HashMethod) -> String ``` with the desired ``` HashMethod ``` 106 | ```swift 107 | let hashValue = Cryptography.hash("The quick brown fox jumps over the lazy dog", method: HashMethod.SHA1) // "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12" 108 | ``` 109 | 110 | ### Message Authentication Codes 111 | In order to calculate a MAC value you simply call ``` authenticate(message: String, key: String, method: MACMethod) -> String ``` with the desired ``` MACMethod ``` 112 | ```swift 113 | let macValue = Cryptography.authenticate("The quick brown fox jumps over the lazy dog", key: "key", method: MACMethod.HMAC(hashMethod: HashMethod.SHA1)) // "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9" 114 | ``` 115 | 116 | ## Installation 117 | 118 | ### Compatibility 119 | 120 | - OS X 10.9+ / iOS 8.0+ / watchOS 2.0 / tvOS 9.0 121 | 122 | - Xcode 7.1+, Swift 2.1+ 123 | 124 | ### Install Using CocoaPods 125 | [CocoaPods](https://cocoapods.org/) is a centralized dependency manager for 126 | Objective-C and Swift. Go [here](https://guides.cocoapods.org/using/index.html) 127 | to learn more. 128 | 129 | 1. Add the project to your [Podfile](https://guides.cocoapods.org/using/the-podfile.html). 130 | 131 | ```ruby 132 | use_frameworks! 133 | 134 | pod 'Cryptography' 135 | ``` 136 | 137 | 2. Run `pod install` and open the `.xcworkspace` file to launch Xcode. 138 | 139 | ### Install Using Carthage 140 | [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency 141 | manager for Objective-C and Swift. 142 | 143 | 1. Add the project to your [Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile). 144 | 145 | ``` 146 | github "mlachmish/Cryptography" 147 | ``` 148 | 149 | 2. Run `carthage update` and follow [the additional steps](https://github.com/Carthage/Carthage#getting-started) 150 | in order to add Cryptography to your project. 151 | 152 | ###Swift Package Manager 153 | You can use [Swift Package Manager](https://swift.org/package-manager/) and specify dependency in `Package.swift` by adding this: 154 | ``` 155 | .Package(url: "https://github.com/mlachmish/Cryptography.git", majorVersion: 0) 156 | ``` 157 | 158 | ### Manually 159 | Download and drop ```/Cryptography``` folder in your project. 160 | 161 | ## Author 162 | 163 | Matan Lachmish a.k.a The Big Fat Ninja The Big Fat Ninja
164 | https://thebigfatninja.xyz 165 | 166 | ### Audit & Security Disclosure 167 | 168 | If you believe you have identified a security vulnerability with Cryptography,
169 | please report it as soon as possible via email to security@thebigfatninja.xyz
170 | Do not post it to the public issue tracker. 171 | 172 | ### attribution 173 | 174 | Icon made by Freepik from www.flaticon.com 175 | 176 | ## License 177 | 178 | Cryptography is available under the MIT license. See the LICENSE file for more info. 179 | -------------------------------------------------------------------------------- /Cryptography/Algorithms/Hash/SHA2.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SHA2.swift 3 | // Cryptography 4 | // 5 | // Created by Matan Lachmish on 25/07/2016. 6 | // Copyright © 2016 The Big Fat Ninja. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // swiftlint:disable variable_name 12 | // swiftlint:disable line_length 13 | // swiftlint:disable comma 14 | 15 | public enum SHA2Variant { 16 | case SHA224 17 | case SHA256 18 | case SHA384 19 | case SHA512 20 | case SHA512SLASH224 21 | case SHA512SLASH256 22 | 23 | public func hash(message: [UInt8]) -> [UInt8] { 24 | switch self { 25 | case .SHA224, .SHA256: 26 | return SHA2.hash32Bit(message, sha2Variant: self) 27 | case .SHA384, .SHA512, .SHA512SLASH224, .SHA512SLASH256: 28 | return SHA2.hash64Bit(message, sha2Variant: self) 29 | } 30 | } 31 | 32 | public func hash(message: String) -> String { 33 | switch self { 34 | case .SHA224, .SHA256: 35 | return SHA2.hash32Bit(message, sha2Variant: self) 36 | case .SHA384, .SHA512, .SHA512SLASH224, .SHA512SLASH256: 37 | return SHA2.hash64Bit(message, sha2Variant: self) 38 | } 39 | } 40 | 41 | internal var blockSize: Int { 42 | switch self { 43 | case .SHA224, .SHA256: 44 | return SHA2Constants.blockSizeSHA256 45 | case .SHA384, .SHA512, .SHA512SLASH224, .SHA512SLASH256: 46 | return SHA2Constants.blockSizeSHA512 47 | } 48 | } 49 | 50 | private var h: [UInt64] { 51 | switch self { 52 | case .SHA224: 53 | return SHA2Constants.hSHA224 54 | case .SHA256: 55 | return SHA2Constants.hSHA256 56 | case .SHA384: 57 | return SHA2Constants.hSHA384 58 | case .SHA512: 59 | return SHA2Constants.hSHA512 60 | case .SHA512SLASH224: 61 | return SHA2Constants.hSHA512SLASH224 62 | case .SHA512SLASH256: 63 | return SHA2Constants.hSHA512SLASH256 64 | } 65 | } 66 | 67 | private var k: [UInt64] { 68 | switch self { 69 | case .SHA224, .SHA256: 70 | return SHA2Constants.kSHA256 71 | case .SHA384, .SHA512, .SHA512SLASH224, .SHA512SLASH256: 72 | return SHA2Constants.kSHA512 73 | } 74 | } 75 | 76 | private func truncateResult(h: [T]) -> ArraySlice { 77 | switch self { 78 | case .SHA224: 79 | return h[0..<7] 80 | case .SHA384: 81 | return h[0..<6] 82 | case .SHA512SLASH224: 83 | return h[0..<4] 84 | case .SHA512SLASH256: 85 | return h[0..<4] 86 | default: 87 | break 88 | } 89 | return ArraySlice(h) 90 | } 91 | 92 | } 93 | 94 | private struct SHA2Constants { 95 | 96 | static let blockSizeSHA256 = 64 97 | static let blockSizeSHA512 = 128 98 | 99 | static let hSHA224: Array = 100 | [0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4] 101 | 102 | static let hSHA256: Array = 103 | [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19] 104 | 105 | static let hSHA384: Array = 106 | [0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939, 107 | 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4] 108 | 109 | static let hSHA512: Array = 110 | [0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, 111 | 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179] 112 | 113 | static let kSHA256: Array = 114 | [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 115 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 116 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 117 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 118 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 119 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 120 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 121 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2] 122 | 123 | static let kSHA512: Array = 124 | [0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 125 | 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe, 126 | 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 127 | 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 128 | 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab, 129 | 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 130 | 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 131 | 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, 132 | 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, 133 | 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 134 | 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 135 | 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, 136 | 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c, 137 | 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 138 | 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 139 | 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817] 140 | 141 | static let hSHA512SLASH224: Array = 142 | [0x8C3D37C819544DA2, 0x73E1996689DCD4D6, 0x1DFAB7AE32FF9C82, 0x679DD514582F9FCF, 143 | 0x0F6D2B697BD44DA8, 0x77E36F7304C48942, 0x3F9D85A86A1D36C8, 0x1112E6AD91D692A1] 144 | 145 | static let hSHA512SLASH256: Array = 146 | [0x22312194FC2BF72C, 0x9F555FA3C84C64C2, 0x2393B86B6F53B151, 0x963877195940EABD, 147 | 0x96283EE2A88EFFE3, 0xBE5E1E2553863992, 0x2B0199FC2C85B8AA, 0x0EB72DDC81C52CA2] 148 | } 149 | 150 | // swiftlint:enable variable_name 151 | // swiftlint:enable line_length 152 | // swiftlint:enable comma 153 | 154 | internal struct SHA2 { 155 | 156 | private static func preprocessMessage(message: Array, 157 | messageLengthBits: Int) -> Array { 158 | 159 | var preprocessedMessage = message 160 | // Pre-processing: adding a single 1 bit 161 | // Notice: the input bytes are considered as bits strings, 162 | // where the first bit is the most significant bit of the byte. 163 | preprocessedMessage.append(0x80) 164 | 165 | // Pre-processing: padding with zeros 166 | // append "0" bit until message length in bits ≡ 448 (mod 512) 167 | let desiredMessageLengthModulo = messageLengthBits - 8 168 | var messageLength = preprocessedMessage.count 169 | var paddingCounter = 0 170 | while messageLength % messageLengthBits != desiredMessageLengthModulo { 171 | paddingCounter += 1 172 | messageLength += 1 173 | } 174 | preprocessedMessage += Array(count: paddingCounter, repeatedValue: 0) 175 | // append original length in bits mod (2 pow 64) to message 176 | preprocessedMessage.reserveCapacity(preprocessedMessage.count + 4) 177 | let lengthInBits = message.count * 8 178 | let lengthBytes = Representations.toUInt8Array(lengthInBits, length: 64/8) 179 | preprocessedMessage += lengthBytes 180 | return preprocessedMessage 181 | } 182 | 183 | // swiftlint:disable function_body_length 184 | // MARK: 32 bit version 185 | static func hash32Bit(message: [UInt8], sha2Variant: SHA2Variant) -> [UInt8] { 186 | // Initialize variables: 187 | var a0 = UInt32(sha2Variant.h[0]) // A 188 | var b0 = UInt32(sha2Variant.h[1]) // B 189 | var c0 = UInt32(sha2Variant.h[2]) // C 190 | var d0 = UInt32(sha2Variant.h[3]) // D 191 | var e0 = UInt32(sha2Variant.h[4]) // E 192 | var f0 = UInt32(sha2Variant.h[5]) // F 193 | var g0 = UInt32(sha2Variant.h[6]) // G 194 | var h0 = UInt32(sha2Variant.h[7]) // H 195 | 196 | // Pre-processing 197 | let preprocessedMessage = preprocessMessage(message, 198 | messageLengthBits:sha2Variant.blockSize) 199 | 200 | // Process the message in successive 512-bit chunks: 201 | let chunkSizeBytes = 512 / 8 202 | for chunk in preprocessedMessage.splitToChuncks(chunkSizeBytes) { 203 | // Break chunk into sixteen 32-bit big-endian words w[i], 0 ≤ i ≤ 15 204 | // Extend the sixteen 32-bit words into eighty 32-bit words: 205 | var M: Array = Array(count: sha2Variant.k.count, repeatedValue: 0) 206 | 207 | for x in 0..> 3 217 | let s1 = M[x-2].rotateRight(17) ^ M[x-2].rotateRight(19) ^ M[x-2] >> 10 218 | M[x] = M[x-16] &+ s0 &+ M[x-7] &+ s1 219 | break 220 | } 221 | } 222 | 223 | // Initialize hash value for this chunk: 224 | var A = a0 225 | var B = b0 226 | var C = c0 227 | var D = d0 228 | var E = e0 229 | var F = f0 230 | var G = g0 231 | var H = h0 232 | 233 | // Main loop: 234 | for i in 0..() 265 | result.reserveCapacity(160/8) 266 | 267 | sha2Variant.truncateResult([a0, b0, c0, d0, e0, f0, g0, h0]).forEach { 268 | result += Representations.toUInt8Array($0.bigEndian.reverseBytes()) 269 | } 270 | 271 | return result 272 | } 273 | 274 | static func hash32Bit(message: String, sha2Variant: SHA2Variant) -> String { 275 | return Representations.toHexadecimalString( 276 | self.hash32Bit(Array(message.utf8), sha2Variant: sha2Variant) 277 | ) 278 | } 279 | 280 | // MARK: 64 bit version 281 | static func hash64Bit(message: [UInt8], sha2Variant: SHA2Variant) -> [UInt8] { 282 | // Initialize variables: 283 | var a0 = sha2Variant.h[0] // A 284 | var b0 = sha2Variant.h[1] // B 285 | var c0 = sha2Variant.h[2] // C 286 | var d0 = sha2Variant.h[3] // D 287 | var e0 = sha2Variant.h[4] // E 288 | var f0 = sha2Variant.h[5] // F 289 | var g0 = sha2Variant.h[6] // G 290 | var h0 = sha2Variant.h[7] // H 291 | 292 | // Pre-processing 293 | let preprocessedMessage = preprocessMessage(message, 294 | messageLengthBits:sha2Variant.blockSize) 295 | 296 | // Process the message in successive 512-bit chunks: 297 | let chunkSizeBytes = 1024 / 8 298 | for chunk in preprocessedMessage.splitToChuncks(chunkSizeBytes) { 299 | // Break chunk into sixteen 32-bit big-endian words w[i], 0 ≤ i ≤ 15 300 | // Extend the sixteen 32-bit words into eighty 32-bit words: 301 | var M: Array = Array(count: sha2Variant.k.count, repeatedValue: 0) 302 | 303 | for x in 0..> 7 313 | let s1 = M[x-2].rotateRight(19) ^ M[x-2].rotateRight(61) ^ M[x-2] >> 6 314 | M[x] = M[x-16] &+ s0 &+ M[x-7] &+ s1 315 | break 316 | } 317 | } 318 | 319 | // Initialize hash value for this chunk: 320 | var A = a0 321 | var B = b0 322 | var C = c0 323 | var D = d0 324 | var E = e0 325 | var F = f0 326 | var G = g0 327 | var H = h0 328 | 329 | // Main loop: 330 | for i in 0..() 361 | result.reserveCapacity(160/8) 362 | 363 | sha2Variant.truncateResult([a0, b0, c0, d0, e0, f0, g0, h0]).forEach { 364 | result += Representations.toUInt8Array($0.bigEndian.reverseBytes()) 365 | } 366 | 367 | if sha2Variant == .SHA512SLASH224 { 368 | result = Array(result[0.. String { 376 | return Representations.toHexadecimalString( 377 | self.hash64Bit(Array(message.utf8), sha2Variant: sha2Variant) 378 | ) 379 | } 380 | 381 | } 382 | -------------------------------------------------------------------------------- /Cryptography.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 62DD90BA51F0E184A6069B9E /* MD5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62DD98224021F3B47DF17382 /* MD5Tests.swift */; }; 11 | 62DD91F13CFE534069A2FB3F /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62DD977C58657B9E58C13CF1 /* MD5.swift */; }; 12 | 62DD92E2382F081090BF9605 /* SHA1Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62DD9EC51EFF6EC437B15ACC /* SHA1Tests.swift */; }; 13 | 62DD93F45EBBA71C328C5F70 /* Arithmetics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62DD9150F5C21F9CB03660E1 /* Arithmetics.swift */; }; 14 | 62DD944C94BC45A50831BF7D /* ArithmeticsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62DD9AF00DCA5B8A1E6E3909 /* ArithmeticsTests.swift */; }; 15 | 62DD951E7D9C015E800B19C5 /* SHA2Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62DD910961EFEF71A473594F /* SHA2Tests.swift */; }; 16 | 62DD956BC9642840D422925E /* AccessorsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62DD9C0DB68FE09A15BCAB37 /* AccessorsTests.swift */; }; 17 | 62DD9675F9C985C3DB2EBD14 /* ArraySlicer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62DD93ACD6944601CF6556CB /* ArraySlicer.swift */; }; 18 | 62DD9E7E4E9E6837D7CC6504 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62DD977C58657B9E58C13CF1 /* MD5.swift */; }; 19 | 62DD9FE8E6A2B7399D32CB81 /* Representations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62DD919F73CA2BC4D7F5613D /* Representations.swift */; }; 20 | 9037129A1D460FF4006413CB /* CryptographyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 903712991D460FF4006413CB /* CryptographyTests.swift */; }; 21 | 9037129C1D462948006413CB /* SHA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9037129B1D462948006413CB /* SHA2.swift */; }; 22 | 9037129F1D47FB9F006413CB /* SHA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9037129B1D462948006413CB /* SHA2.swift */; }; 23 | 903712CD1D48A182006413CB /* RepresentationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 903712CC1D48A182006413CB /* RepresentationsTests.swift */; }; 24 | 903712CE1D48AE14006413CB /* Cryptography.swift in Sources */ = {isa = PBXBuildFile; fileRef = 906295791D2DA88000CC7E64 /* Cryptography.swift */; }; 25 | 903712CF1D48AE32006413CB /* HMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9090381B1D32762800A62BEB /* HMAC.swift */; }; 26 | 903712D01D48AE3F006413CB /* MACProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9090381D1D32763A00A62BEB /* MACProtocol.swift */; }; 27 | 903712D21D48B2EB006413CB /* ArraySlicerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 903712D11D48B2EB006413CB /* ArraySlicerTests.swift */; }; 28 | 9062957A1D2DA88000CC7E64 /* Cryptography.swift in Sources */ = {isa = PBXBuildFile; fileRef = 906295791D2DA88000CC7E64 /* Cryptography.swift */; }; 29 | 9062957C1D2DAB9A00CC7E64 /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9062957B1D2DAB9A00CC7E64 /* SHA1.swift */; }; 30 | 9062957F1D2DAE4C00CC7E64 /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9062957B1D2DAB9A00CC7E64 /* SHA1.swift */; }; 31 | 9067407B1D2AE326009A988D /* Cryptography.h in Headers */ = {isa = PBXBuildFile; fileRef = 9067407A1D2AE326009A988D /* Cryptography.h */; settings = {ATTRIBUTES = (Public, ); }; }; 32 | 906740821D2AE326009A988D /* Cryptography.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 906740771D2AE326009A988D /* Cryptography.framework */; }; 33 | 90712B611D2D43C3000485ED /* Representations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62DD919F73CA2BC4D7F5613D /* Representations.swift */; }; 34 | 90712B631D2D5058000485ED /* Accessors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90712B621D2D5058000485ED /* Accessors.swift */; }; 35 | 90712B661D2D528A000485ED /* Accessors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90712B621D2D5058000485ED /* Accessors.swift */; }; 36 | 90712B671D2D54D9000485ED /* Arithmetics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62DD9150F5C21F9CB03660E1 /* Arithmetics.swift */; }; 37 | 909038191D326D7500A62BEB /* HashProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 909038181D326D7500A62BEB /* HashProtocol.swift */; }; 38 | 9090381A1D32720C00A62BEB /* HashProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 909038181D326D7500A62BEB /* HashProtocol.swift */; }; 39 | 9090381C1D32762800A62BEB /* HMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9090381B1D32762800A62BEB /* HMAC.swift */; }; 40 | 9090381E1D32763A00A62BEB /* MACProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9090381D1D32763A00A62BEB /* MACProtocol.swift */; }; 41 | 90EA9B6C1D49104300700040 /* HMACTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90EA9B6B1D49104300700040 /* HMACTests.swift */; }; 42 | /* End PBXBuildFile section */ 43 | 44 | /* Begin PBXContainerItemProxy section */ 45 | 906740831D2AE326009A988D /* PBXContainerItemProxy */ = { 46 | isa = PBXContainerItemProxy; 47 | containerPortal = 9067406E1D2AE326009A988D /* Project object */; 48 | proxyType = 1; 49 | remoteGlobalIDString = 906740761D2AE326009A988D; 50 | remoteInfo = Cryptography; 51 | }; 52 | /* End PBXContainerItemProxy section */ 53 | 54 | /* Begin PBXFileReference section */ 55 | 62DD910961EFEF71A473594F /* SHA2Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SHA2Tests.swift; sourceTree = ""; }; 56 | 62DD9150F5C21F9CB03660E1 /* Arithmetics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Arithmetics.swift; sourceTree = ""; }; 57 | 62DD919F73CA2BC4D7F5613D /* Representations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Representations.swift; sourceTree = ""; }; 58 | 62DD93ACD6944601CF6556CB /* ArraySlicer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArraySlicer.swift; sourceTree = ""; }; 59 | 62DD977C58657B9E58C13CF1 /* MD5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MD5.swift; sourceTree = ""; }; 60 | 62DD98224021F3B47DF17382 /* MD5Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MD5Tests.swift; sourceTree = ""; }; 61 | 62DD9AF00DCA5B8A1E6E3909 /* ArithmeticsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArithmeticsTests.swift; sourceTree = ""; }; 62 | 62DD9C0DB68FE09A15BCAB37 /* AccessorsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccessorsTests.swift; sourceTree = ""; }; 63 | 62DD9EC51EFF6EC437B15ACC /* SHA1Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SHA1Tests.swift; sourceTree = ""; }; 64 | 903712991D460FF4006413CB /* CryptographyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CryptographyTests.swift; sourceTree = ""; }; 65 | 9037129B1D462948006413CB /* SHA2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SHA2.swift; sourceTree = ""; }; 66 | 903712CC1D48A182006413CB /* RepresentationsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepresentationsTests.swift; sourceTree = ""; }; 67 | 903712D11D48B2EB006413CB /* ArraySlicerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArraySlicerTests.swift; sourceTree = ""; }; 68 | 906295791D2DA88000CC7E64 /* Cryptography.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cryptography.swift; sourceTree = ""; }; 69 | 9062957B1D2DAB9A00CC7E64 /* SHA1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SHA1.swift; sourceTree = ""; }; 70 | 906740771D2AE326009A988D /* Cryptography.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Cryptography.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 71 | 9067407A1D2AE326009A988D /* Cryptography.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Cryptography.h; sourceTree = ""; }; 72 | 9067407C1D2AE326009A988D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 73 | 906740811D2AE326009A988D /* CryptographyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CryptographyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 74 | 906740881D2AE326009A988D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 75 | 90712B621D2D5058000485ED /* Accessors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Accessors.swift; sourceTree = ""; }; 76 | 909038181D326D7500A62BEB /* HashProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HashProtocol.swift; sourceTree = ""; }; 77 | 9090381B1D32762800A62BEB /* HMAC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HMAC.swift; sourceTree = ""; }; 78 | 9090381D1D32763A00A62BEB /* MACProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MACProtocol.swift; sourceTree = ""; }; 79 | 90EA9B6B1D49104300700040 /* HMACTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HMACTests.swift; sourceTree = ""; }; 80 | /* End PBXFileReference section */ 81 | 82 | /* Begin PBXFrameworksBuildPhase section */ 83 | 906740731D2AE326009A988D /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | ); 88 | runOnlyForDeploymentPostprocessing = 0; 89 | }; 90 | 9067407E1D2AE326009A988D /* Frameworks */ = { 91 | isa = PBXFrameworksBuildPhase; 92 | buildActionMask = 2147483647; 93 | files = ( 94 | 906740821D2AE326009A988D /* Cryptography.framework in Frameworks */, 95 | ); 96 | runOnlyForDeploymentPostprocessing = 0; 97 | }; 98 | /* End PBXFrameworksBuildPhase section */ 99 | 100 | /* Begin PBXGroup section */ 101 | 62DD90B80DEBA070835382A4 /* Hash */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | 62DD98224021F3B47DF17382 /* MD5Tests.swift */, 105 | 62DD9EC51EFF6EC437B15ACC /* SHA1Tests.swift */, 106 | 62DD910961EFEF71A473594F /* SHA2Tests.swift */, 107 | ); 108 | path = Hash; 109 | sourceTree = ""; 110 | }; 111 | 62DD90F093139CD6CE405173 /* MAC */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 9090381D1D32763A00A62BEB /* MACProtocol.swift */, 115 | 9090381B1D32762800A62BEB /* HMAC.swift */, 116 | ); 117 | path = MAC; 118 | sourceTree = ""; 119 | }; 120 | 62DD927DDC1FE24A3C7AAE68 /* Algorithms */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 62DD9EA9B28507B44DABF3E7 /* Hash */, 124 | 62DD90F093139CD6CE405173 /* MAC */, 125 | ); 126 | path = Algorithms; 127 | sourceTree = ""; 128 | }; 129 | 62DD931FC4A062A2C1486B0B /* Algorithms */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 62DD90B80DEBA070835382A4 /* Hash */, 133 | 62DD9F793F1B402D2CBE027B /* MAC */, 134 | ); 135 | path = Algorithms; 136 | sourceTree = ""; 137 | }; 138 | 62DD960D37800D903125C37B /* scripts */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | ); 142 | path = scripts; 143 | sourceTree = ""; 144 | }; 145 | 62DD962AE1326CC645DF4E4C /* Extensions */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 90712B621D2D5058000485ED /* Accessors.swift */, 149 | 62DD9150F5C21F9CB03660E1 /* Arithmetics.swift */, 150 | 62DD93ACD6944601CF6556CB /* ArraySlicer.swift */, 151 | 62DD919F73CA2BC4D7F5613D /* Representations.swift */, 152 | ); 153 | path = Extensions; 154 | sourceTree = ""; 155 | }; 156 | 62DD9EA9B28507B44DABF3E7 /* Hash */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 909038181D326D7500A62BEB /* HashProtocol.swift */, 160 | 62DD977C58657B9E58C13CF1 /* MD5.swift */, 161 | 9062957B1D2DAB9A00CC7E64 /* SHA1.swift */, 162 | 9037129B1D462948006413CB /* SHA2.swift */, 163 | ); 164 | path = Hash; 165 | sourceTree = ""; 166 | }; 167 | 62DD9F65B1DCBFC83DABE454 /* Extensions */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 62DD9C0DB68FE09A15BCAB37 /* AccessorsTests.swift */, 171 | 62DD9AF00DCA5B8A1E6E3909 /* ArithmeticsTests.swift */, 172 | 903712D11D48B2EB006413CB /* ArraySlicerTests.swift */, 173 | 903712CC1D48A182006413CB /* RepresentationsTests.swift */, 174 | ); 175 | path = Extensions; 176 | sourceTree = ""; 177 | }; 178 | 62DD9F793F1B402D2CBE027B /* MAC */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | 90EA9B6B1D49104300700040 /* HMACTests.swift */, 182 | ); 183 | path = MAC; 184 | sourceTree = ""; 185 | }; 186 | 7DD4D59DD5D3245841BC6B9C /* Frameworks */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | ); 190 | name = Frameworks; 191 | sourceTree = ""; 192 | }; 193 | 9067406D1D2AE326009A988D = { 194 | isa = PBXGroup; 195 | children = ( 196 | 906740791D2AE326009A988D /* Cryptography */, 197 | 906740851D2AE326009A988D /* CryptographyTests */, 198 | 906740781D2AE326009A988D /* Products */, 199 | 7DD4D59DD5D3245841BC6B9C /* Frameworks */, 200 | 62DD960D37800D903125C37B /* scripts */, 201 | ); 202 | sourceTree = ""; 203 | }; 204 | 906740781D2AE326009A988D /* Products */ = { 205 | isa = PBXGroup; 206 | children = ( 207 | 906740771D2AE326009A988D /* Cryptography.framework */, 208 | 906740811D2AE326009A988D /* CryptographyTests.xctest */, 209 | ); 210 | name = Products; 211 | sourceTree = ""; 212 | }; 213 | 906740791D2AE326009A988D /* Cryptography */ = { 214 | isa = PBXGroup; 215 | children = ( 216 | 9067407A1D2AE326009A988D /* Cryptography.h */, 217 | 9067407C1D2AE326009A988D /* Info.plist */, 218 | 62DD962AE1326CC645DF4E4C /* Extensions */, 219 | 62DD927DDC1FE24A3C7AAE68 /* Algorithms */, 220 | 906295791D2DA88000CC7E64 /* Cryptography.swift */, 221 | ); 222 | path = Cryptography; 223 | sourceTree = ""; 224 | }; 225 | 906740851D2AE326009A988D /* CryptographyTests */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | 906740881D2AE326009A988D /* Info.plist */, 229 | 62DD9F65B1DCBFC83DABE454 /* Extensions */, 230 | 62DD931FC4A062A2C1486B0B /* Algorithms */, 231 | 903712991D460FF4006413CB /* CryptographyTests.swift */, 232 | ); 233 | path = CryptographyTests; 234 | sourceTree = ""; 235 | }; 236 | /* End PBXGroup section */ 237 | 238 | /* Begin PBXHeadersBuildPhase section */ 239 | 906740741D2AE326009A988D /* Headers */ = { 240 | isa = PBXHeadersBuildPhase; 241 | buildActionMask = 2147483647; 242 | files = ( 243 | 9067407B1D2AE326009A988D /* Cryptography.h in Headers */, 244 | ); 245 | runOnlyForDeploymentPostprocessing = 0; 246 | }; 247 | /* End PBXHeadersBuildPhase section */ 248 | 249 | /* Begin PBXNativeTarget section */ 250 | 906740761D2AE326009A988D /* Cryptography */ = { 251 | isa = PBXNativeTarget; 252 | buildConfigurationList = 9067408B1D2AE326009A988D /* Build configuration list for PBXNativeTarget "Cryptography" */; 253 | buildPhases = ( 254 | 906740721D2AE326009A988D /* Sources */, 255 | 906740731D2AE326009A988D /* Frameworks */, 256 | 906740741D2AE326009A988D /* Headers */, 257 | 906740751D2AE326009A988D /* Resources */, 258 | 90712B681D2D57D3000485ED /* SwiftLint */, 259 | ); 260 | buildRules = ( 261 | ); 262 | dependencies = ( 263 | ); 264 | name = Cryptography; 265 | productName = Cryptography; 266 | productReference = 906740771D2AE326009A988D /* Cryptography.framework */; 267 | productType = "com.apple.product-type.framework"; 268 | }; 269 | 906740801D2AE326009A988D /* CryptographyTests */ = { 270 | isa = PBXNativeTarget; 271 | buildConfigurationList = 9067408E1D2AE326009A988D /* Build configuration list for PBXNativeTarget "CryptographyTests" */; 272 | buildPhases = ( 273 | 9067407D1D2AE326009A988D /* Sources */, 274 | 9067407E1D2AE326009A988D /* Frameworks */, 275 | 9067407F1D2AE326009A988D /* Resources */, 276 | ); 277 | buildRules = ( 278 | ); 279 | dependencies = ( 280 | 906740841D2AE326009A988D /* PBXTargetDependency */, 281 | ); 282 | name = CryptographyTests; 283 | productName = CryptographyTests; 284 | productReference = 906740811D2AE326009A988D /* CryptographyTests.xctest */; 285 | productType = "com.apple.product-type.bundle.unit-test"; 286 | }; 287 | /* End PBXNativeTarget section */ 288 | 289 | /* Begin PBXProject section */ 290 | 9067406E1D2AE326009A988D /* Project object */ = { 291 | isa = PBXProject; 292 | attributes = { 293 | LastSwiftUpdateCheck = 0730; 294 | LastUpgradeCheck = 0730; 295 | ORGANIZATIONNAME = "The Big Fat Ninja"; 296 | TargetAttributes = { 297 | 906740761D2AE326009A988D = { 298 | CreatedOnToolsVersion = 7.3.1; 299 | }; 300 | 906740801D2AE326009A988D = { 301 | CreatedOnToolsVersion = 7.3.1; 302 | }; 303 | }; 304 | }; 305 | buildConfigurationList = 906740711D2AE326009A988D /* Build configuration list for PBXProject "Cryptography" */; 306 | compatibilityVersion = "Xcode 3.2"; 307 | developmentRegion = English; 308 | hasScannedForEncodings = 0; 309 | knownRegions = ( 310 | en, 311 | ); 312 | mainGroup = 9067406D1D2AE326009A988D; 313 | productRefGroup = 906740781D2AE326009A988D /* Products */; 314 | projectDirPath = ""; 315 | projectRoot = ""; 316 | targets = ( 317 | 906740761D2AE326009A988D /* Cryptography */, 318 | 906740801D2AE326009A988D /* CryptographyTests */, 319 | ); 320 | }; 321 | /* End PBXProject section */ 322 | 323 | /* Begin PBXResourcesBuildPhase section */ 324 | 906740751D2AE326009A988D /* Resources */ = { 325 | isa = PBXResourcesBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | ); 329 | runOnlyForDeploymentPostprocessing = 0; 330 | }; 331 | 9067407F1D2AE326009A988D /* Resources */ = { 332 | isa = PBXResourcesBuildPhase; 333 | buildActionMask = 2147483647; 334 | files = ( 335 | ); 336 | runOnlyForDeploymentPostprocessing = 0; 337 | }; 338 | /* End PBXResourcesBuildPhase section */ 339 | 340 | /* Begin PBXShellScriptBuildPhase section */ 341 | 90712B681D2D57D3000485ED /* SwiftLint */ = { 342 | isa = PBXShellScriptBuildPhase; 343 | buildActionMask = 2147483647; 344 | files = ( 345 | ); 346 | inputPaths = ( 347 | ); 348 | name = SwiftLint; 349 | outputPaths = ( 350 | ); 351 | runOnlyForDeploymentPostprocessing = 0; 352 | shellPath = /bin/sh; 353 | shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; 354 | }; 355 | /* End PBXShellScriptBuildPhase section */ 356 | 357 | /* Begin PBXSourcesBuildPhase section */ 358 | 906740721D2AE326009A988D /* Sources */ = { 359 | isa = PBXSourcesBuildPhase; 360 | buildActionMask = 2147483647; 361 | files = ( 362 | 62DD93F45EBBA71C328C5F70 /* Arithmetics.swift in Sources */, 363 | 62DD9675F9C985C3DB2EBD14 /* ArraySlicer.swift in Sources */, 364 | 9090381C1D32762800A62BEB /* HMAC.swift in Sources */, 365 | 9090381E1D32763A00A62BEB /* MACProtocol.swift in Sources */, 366 | 62DD9FE8E6A2B7399D32CB81 /* Representations.swift in Sources */, 367 | 909038191D326D7500A62BEB /* HashProtocol.swift in Sources */, 368 | 9062957A1D2DA88000CC7E64 /* Cryptography.swift in Sources */, 369 | 9062957C1D2DAB9A00CC7E64 /* SHA1.swift in Sources */, 370 | 62DD91F13CFE534069A2FB3F /* MD5.swift in Sources */, 371 | 90712B631D2D5058000485ED /* Accessors.swift in Sources */, 372 | 9037129C1D462948006413CB /* SHA2.swift in Sources */, 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | }; 376 | 9067407D1D2AE326009A988D /* Sources */ = { 377 | isa = PBXSourcesBuildPhase; 378 | buildActionMask = 2147483647; 379 | files = ( 380 | 903712D01D48AE3F006413CB /* MACProtocol.swift in Sources */, 381 | 9037129F1D47FB9F006413CB /* SHA2.swift in Sources */, 382 | 90712B661D2D528A000485ED /* Accessors.swift in Sources */, 383 | 90712B611D2D43C3000485ED /* Representations.swift in Sources */, 384 | 9037129A1D460FF4006413CB /* CryptographyTests.swift in Sources */, 385 | 90712B671D2D54D9000485ED /* Arithmetics.swift in Sources */, 386 | 903712CD1D48A182006413CB /* RepresentationsTests.swift in Sources */, 387 | 62DD9E7E4E9E6837D7CC6504 /* MD5.swift in Sources */, 388 | 9062957F1D2DAE4C00CC7E64 /* SHA1.swift in Sources */, 389 | 903712CE1D48AE14006413CB /* Cryptography.swift in Sources */, 390 | 62DD956BC9642840D422925E /* AccessorsTests.swift in Sources */, 391 | 9090381A1D32720C00A62BEB /* HashProtocol.swift in Sources */, 392 | 62DD944C94BC45A50831BF7D /* ArithmeticsTests.swift in Sources */, 393 | 903712D21D48B2EB006413CB /* ArraySlicerTests.swift in Sources */, 394 | 903712CF1D48AE32006413CB /* HMAC.swift in Sources */, 395 | 62DD92E2382F081090BF9605 /* SHA1Tests.swift in Sources */, 396 | 62DD90BA51F0E184A6069B9E /* MD5Tests.swift in Sources */, 397 | 62DD951E7D9C015E800B19C5 /* SHA2Tests.swift in Sources */, 398 | 90EA9B6C1D49104300700040 /* HMACTests.swift in Sources */, 399 | ); 400 | runOnlyForDeploymentPostprocessing = 0; 401 | }; 402 | /* End PBXSourcesBuildPhase section */ 403 | 404 | /* Begin PBXTargetDependency section */ 405 | 906740841D2AE326009A988D /* PBXTargetDependency */ = { 406 | isa = PBXTargetDependency; 407 | target = 906740761D2AE326009A988D /* Cryptography */; 408 | targetProxy = 906740831D2AE326009A988D /* PBXContainerItemProxy */; 409 | }; 410 | /* End PBXTargetDependency section */ 411 | 412 | /* Begin XCBuildConfiguration section */ 413 | 906740891D2AE326009A988D /* Debug */ = { 414 | isa = XCBuildConfiguration; 415 | buildSettings = { 416 | ALWAYS_SEARCH_USER_PATHS = NO; 417 | CLANG_ANALYZER_NONNULL = YES; 418 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 419 | CLANG_CXX_LIBRARY = "libc++"; 420 | CLANG_ENABLE_MODULES = YES; 421 | CLANG_ENABLE_OBJC_ARC = YES; 422 | CLANG_WARN_BOOL_CONVERSION = YES; 423 | CLANG_WARN_CONSTANT_CONVERSION = YES; 424 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 425 | CLANG_WARN_EMPTY_BODY = YES; 426 | CLANG_WARN_ENUM_CONVERSION = YES; 427 | CLANG_WARN_INT_CONVERSION = YES; 428 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 429 | CLANG_WARN_UNREACHABLE_CODE = YES; 430 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 431 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 432 | COPY_PHASE_STRIP = NO; 433 | CURRENT_PROJECT_VERSION = 1; 434 | DEBUG_INFORMATION_FORMAT = dwarf; 435 | ENABLE_STRICT_OBJC_MSGSEND = YES; 436 | ENABLE_TESTABILITY = YES; 437 | GCC_C_LANGUAGE_STANDARD = gnu99; 438 | GCC_DYNAMIC_NO_PIC = NO; 439 | GCC_NO_COMMON_BLOCKS = YES; 440 | GCC_OPTIMIZATION_LEVEL = 0; 441 | GCC_PREPROCESSOR_DEFINITIONS = ( 442 | "DEBUG=1", 443 | "$(inherited)", 444 | ); 445 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 446 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 447 | GCC_WARN_UNDECLARED_SELECTOR = YES; 448 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 449 | GCC_WARN_UNUSED_FUNCTION = YES; 450 | GCC_WARN_UNUSED_VARIABLE = YES; 451 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 452 | MTL_ENABLE_DEBUG_INFO = YES; 453 | ONLY_ACTIVE_ARCH = YES; 454 | SDKROOT = iphoneos; 455 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 456 | TARGETED_DEVICE_FAMILY = "1,2"; 457 | VERSIONING_SYSTEM = "apple-generic"; 458 | VERSION_INFO_PREFIX = ""; 459 | }; 460 | name = Debug; 461 | }; 462 | 9067408A1D2AE326009A988D /* Release */ = { 463 | isa = XCBuildConfiguration; 464 | buildSettings = { 465 | ALWAYS_SEARCH_USER_PATHS = NO; 466 | CLANG_ANALYZER_NONNULL = YES; 467 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 468 | CLANG_CXX_LIBRARY = "libc++"; 469 | CLANG_ENABLE_MODULES = YES; 470 | CLANG_ENABLE_OBJC_ARC = YES; 471 | CLANG_WARN_BOOL_CONVERSION = YES; 472 | CLANG_WARN_CONSTANT_CONVERSION = YES; 473 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 474 | CLANG_WARN_EMPTY_BODY = YES; 475 | CLANG_WARN_ENUM_CONVERSION = YES; 476 | CLANG_WARN_INT_CONVERSION = YES; 477 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 478 | CLANG_WARN_UNREACHABLE_CODE = YES; 479 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 480 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 481 | COPY_PHASE_STRIP = NO; 482 | CURRENT_PROJECT_VERSION = 1; 483 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 484 | ENABLE_NS_ASSERTIONS = NO; 485 | ENABLE_STRICT_OBJC_MSGSEND = YES; 486 | GCC_C_LANGUAGE_STANDARD = gnu99; 487 | GCC_NO_COMMON_BLOCKS = YES; 488 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 489 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 490 | GCC_WARN_UNDECLARED_SELECTOR = YES; 491 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 492 | GCC_WARN_UNUSED_FUNCTION = YES; 493 | GCC_WARN_UNUSED_VARIABLE = YES; 494 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 495 | MTL_ENABLE_DEBUG_INFO = NO; 496 | SDKROOT = iphoneos; 497 | TARGETED_DEVICE_FAMILY = "1,2"; 498 | VALIDATE_PRODUCT = YES; 499 | VERSIONING_SYSTEM = "apple-generic"; 500 | VERSION_INFO_PREFIX = ""; 501 | }; 502 | name = Release; 503 | }; 504 | 9067408C1D2AE326009A988D /* Debug */ = { 505 | isa = XCBuildConfiguration; 506 | buildSettings = { 507 | DEFINES_MODULE = YES; 508 | DYLIB_COMPATIBILITY_VERSION = 1; 509 | DYLIB_CURRENT_VERSION = 1; 510 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 511 | INFOPLIST_FILE = Cryptography/Info.plist; 512 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 513 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 514 | PRODUCT_BUNDLE_IDENTIFIER = ninja.thebigfat.Cryptography; 515 | PRODUCT_NAME = "$(TARGET_NAME)"; 516 | SKIP_INSTALL = YES; 517 | }; 518 | name = Debug; 519 | }; 520 | 9067408D1D2AE326009A988D /* Release */ = { 521 | isa = XCBuildConfiguration; 522 | buildSettings = { 523 | DEFINES_MODULE = YES; 524 | DYLIB_COMPATIBILITY_VERSION = 1; 525 | DYLIB_CURRENT_VERSION = 1; 526 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 527 | INFOPLIST_FILE = Cryptography/Info.plist; 528 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 529 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 530 | PRODUCT_BUNDLE_IDENTIFIER = ninja.thebigfat.Cryptography; 531 | PRODUCT_NAME = "$(TARGET_NAME)"; 532 | SKIP_INSTALL = YES; 533 | }; 534 | name = Release; 535 | }; 536 | 9067408F1D2AE326009A988D /* Debug */ = { 537 | isa = XCBuildConfiguration; 538 | buildSettings = { 539 | INFOPLIST_FILE = CryptographyTests/Info.plist; 540 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 541 | PRODUCT_BUNDLE_IDENTIFIER = ninja.thebigfat.CryptographyTests; 542 | PRODUCT_NAME = "$(TARGET_NAME)"; 543 | }; 544 | name = Debug; 545 | }; 546 | 906740901D2AE326009A988D /* Release */ = { 547 | isa = XCBuildConfiguration; 548 | buildSettings = { 549 | INFOPLIST_FILE = CryptographyTests/Info.plist; 550 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 551 | PRODUCT_BUNDLE_IDENTIFIER = ninja.thebigfat.CryptographyTests; 552 | PRODUCT_NAME = "$(TARGET_NAME)"; 553 | }; 554 | name = Release; 555 | }; 556 | /* End XCBuildConfiguration section */ 557 | 558 | /* Begin XCConfigurationList section */ 559 | 906740711D2AE326009A988D /* Build configuration list for PBXProject "Cryptography" */ = { 560 | isa = XCConfigurationList; 561 | buildConfigurations = ( 562 | 906740891D2AE326009A988D /* Debug */, 563 | 9067408A1D2AE326009A988D /* Release */, 564 | ); 565 | defaultConfigurationIsVisible = 0; 566 | defaultConfigurationName = Release; 567 | }; 568 | 9067408B1D2AE326009A988D /* Build configuration list for PBXNativeTarget "Cryptography" */ = { 569 | isa = XCConfigurationList; 570 | buildConfigurations = ( 571 | 9067408C1D2AE326009A988D /* Debug */, 572 | 9067408D1D2AE326009A988D /* Release */, 573 | ); 574 | defaultConfigurationIsVisible = 0; 575 | defaultConfigurationName = Release; 576 | }; 577 | 9067408E1D2AE326009A988D /* Build configuration list for PBXNativeTarget "CryptographyTests" */ = { 578 | isa = XCConfigurationList; 579 | buildConfigurations = ( 580 | 9067408F1D2AE326009A988D /* Debug */, 581 | 906740901D2AE326009A988D /* Release */, 582 | ); 583 | defaultConfigurationIsVisible = 0; 584 | defaultConfigurationName = Release; 585 | }; 586 | /* End XCConfigurationList section */ 587 | }; 588 | rootObject = 9067406E1D2AE326009A988D /* Project object */; 589 | } 590 | --------------------------------------------------------------------------------