Merge branch 'CoreData' of https://github.com/siegesmund/SwiftDDP into CoreData

This commit is contained in:
Peter 2015-11-18 09:38:49 -05:00
commit ec9fee215f
88 changed files with 2270 additions and 2211 deletions

View File

@ -1,9 +1,7 @@
github "krzyzanowskim/CryptoSwift" "0.0.16"
github "tidwall/SwiftWebSocket" "v2.1.1"
github "DaveWoodCom/XCGLogger" "Version_3.0"
github "Quick/Quick" "v0.6.0"
github "Quick/Nimble" "v2.0.0-rc.3"
github "krzyzanowskim/CryptoSwift"
github "tidwall/SwiftWebSocket"
github "DaveWoodCom/XCGLogger"
github "Quick/Quick"
github "Quick/Nimble"

View File

@ -1,5 +1,5 @@
github "krzyzanowskim/CryptoSwift" "0.0.16"
github "Quick/Nimble" "v2.0.0-rc.3"
github "Quick/Quick" "v0.6.0"
github "tidwall/SwiftWebSocket" "v2.1.1"
github "DaveWoodCom/XCGLogger" "Version_3.0"
github "krzyzanowskim/CryptoSwift" "0.1.1"
github "Quick/Nimble" "v3.0.0"
github "Quick/Quick" "v0.8.0"
github "tidwall/SwiftWebSocket" "v2.3.0"
github "DaveWoodCom/XCGLogger" "Version_3.1"

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "CryptoSwift"
s.version = "0.0.16"
s.version = "0.1.1"
s.summary = "Cryptography in Swift. SHA, MD5, CRC, Poly1305, HMAC, ChaCha20, AES."
s.description = "Cryptography functions and helpers for Swift implemented in Swift. SHA, MD5, CRC, Poly1305, HMAC, ChaCha20, AES."
s.homepage = "https://github.com/krzyzanowskim/CryptoSwift"
@ -12,6 +12,8 @@ Pod::Spec.new do |s|
s.ios.deployment_target = "8.0"
s.osx.platform = :osx, '10.9'
s.osx.deployment_target = "10.9"
s.source_files = "CryptoSwift/*.swift"
s.watchos.platform = :watchos, '2.0'
s.watchos.deployment_target = "2.0"
s.source_files = "CryptoSwift/**/*.swift"
s.requires_arc = true
end

View File

@ -6,36 +6,55 @@
objectVersion = 46;
objects = {
/* Begin PBXAggregateTarget section */
3F8849E11B0647D6006AB604 /* CryptoSwift-Universal */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 3F8849E21B0647D6006AB604 /* Build configuration list for PBXAggregateTarget "CryptoSwift-Universal" */;
buildPhases = (
3F8849E51B0647DD006AB604 /* ShellScript */,
);
dependencies = (
);
name = "CryptoSwift-Universal";
productName = "CryptoSwift-Universal";
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
5596BDC31BC8F384007E38D5 /* AES+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C951BB8A4BD009CAFC5 /* AES+Foundation.swift */; settings = {ASSET_TAGS = (); }; };
5596BDC41BC8F384007E38D5 /* Array<UInt8>+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C961BB8A4BD009CAFC5 /* Array<UInt8>+Foundation.swift */; settings = {ASSET_TAGS = (); }; };
5596BDC51BC8F384007E38D5 /* ChaCha20+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C971BB8A4BD009CAFC5 /* ChaCha20+Foundation.swift */; settings = {ASSET_TAGS = (); }; };
5596BDC61BC8F384007E38D5 /* NSData+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C981BB8A4BD009CAFC5 /* NSData+Extension.swift */; settings = {ASSET_TAGS = (); }; };
5596BDC71BC8F384007E38D5 /* Utils+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C991BB8A4BD009CAFC5 /* Utils+Foundation.swift */; settings = {ASSET_TAGS = (); }; };
5596BDC81BC8F384007E38D5 /* Hash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7552614D1993051E000D2B20 /* Hash.swift */; settings = {ASSET_TAGS = (); }; };
5596BDC91BC8F384007E38D5 /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7563B2E719B14D4300B152CD /* Cipher.swift */; settings = {ASSET_TAGS = (); }; };
5596BDCA1BC8F384007E38D5 /* CipherBlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BC3AE21A4E412000ADF343 /* CipherBlockMode.swift */; settings = {ASSET_TAGS = (); }; };
5596BDCB1BC8F384007E38D5 /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A663A51AA0CAD00052110B /* Padding.swift */; settings = {ASSET_TAGS = (); }; };
5596BDCC1BC8F384007E38D5 /* PKCS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75B0A56F1AB1A1BB000BD8D2 /* PKCS5.swift */; settings = {ASSET_TAGS = (); }; };
5596BDCD1BC8F384007E38D5 /* PKCS7.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754C30B61AA13BC000E6FFA4 /* PKCS7.swift */; settings = {ASSET_TAGS = (); }; };
5596BDCE1BC8F384007E38D5 /* Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755111E719B7B7DF00C2AD86 /* Authenticator.swift */; settings = {ASSET_TAGS = (); }; };
5596BDCF1BC8F384007E38D5 /* HashProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754DD76D19A149AF00E52288 /* HashProtocol.swift */; settings = {ASSET_TAGS = (); }; };
5596BDD01BC8F384007E38D5 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750A545F1992D2680017DA75 /* MD5.swift */; settings = {ASSET_TAGS = (); }; };
5596BDD11BC8F384007E38D5 /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752E087A199FF27C005B0EA0 /* SHA1.swift */; settings = {ASSET_TAGS = (); }; };
5596BDD21BC8F384007E38D5 /* SHA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75153D4119AA3C7900750381 /* SHA2.swift */; settings = {ASSET_TAGS = (); }; };
5596BDD31BC8F384007E38D5 /* CRC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757EF7F419AAA82400586276 /* CRC.swift */; settings = {ASSET_TAGS = (); }; };
5596BDD41BC8F384007E38D5 /* ChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EB380019ABDD710002375A /* ChaCha20.swift */; settings = {ASSET_TAGS = (); }; };
5596BDD51BC8F384007E38D5 /* Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 751C5C3C19B26B000094C75D /* Poly1305.swift */; settings = {ASSET_TAGS = (); }; };
5596BDD61BC8F384007E38D5 /* HMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758A94251A65AEB100E46135 /* HMAC.swift */; settings = {ASSET_TAGS = (); }; };
5596BDD71BC8F384007E38D5 /* AES.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A74B261A1FF6B2004419F1 /* AES.swift */; settings = {ASSET_TAGS = (); }; };
5596BDD81BC8F384007E38D5 /* BitExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759D481019B517BC005FF7FC /* BitExtension.swift */; settings = {ASSET_TAGS = (); }; };
5596BDD91BC8F384007E38D5 /* IntExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7547195019931802002FA5F1 /* IntExtension.swift */; settings = {ASSET_TAGS = (); }; };
5596BDDA1BC8F384007E38D5 /* UInt8Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758F3F771992F6CE0014BBDA /* UInt8Extension.swift */; settings = {ASSET_TAGS = (); }; };
5596BDDB1BC8F384007E38D5 /* UInt32Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D94E2519B60C4F007CB2A4 /* UInt32Extension.swift */; settings = {ASSET_TAGS = (); }; };
5596BDDC1BC8F384007E38D5 /* UInt64Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D94E2719B60DDE007CB2A4 /* UInt64Extension.swift */; settings = {ASSET_TAGS = (); }; };
5596BDDD1BC8F384007E38D5 /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754C8FEC19979F94005AD904 /* Array+Extension.swift */; settings = {ASSET_TAGS = (); }; };
5596BDDE1BC8F384007E38D5 /* ArraySlice<UInt8>+Bytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D63F761BB840050041579B /* ArraySlice<UInt8>+Bytes.swift */; settings = {ASSET_TAGS = (); }; };
5596BDDF1BC8F384007E38D5 /* CSArrayType+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75232CCD1BC6E6AC007F68B1 /* CSArrayType+Extensions.swift */; settings = {ASSET_TAGS = (); }; };
5596BDE01BC8F384007E38D5 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7599C9C5199EA28700A3988B /* String+Extension.swift */; settings = {ASSET_TAGS = (); }; };
5596BDE11BC8F384007E38D5 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D94E2319B60C08007CB2A4 /* Operators.swift */; settings = {ASSET_TAGS = (); }; };
5596BDE21BC8F384007E38D5 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75164E4819AD30AC00737F30 /* Utils.swift */; settings = {ASSET_TAGS = (); }; };
5596BDE31BC8F384007E38D5 /* Generics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758C764019B61AE500653BC6 /* Generics.swift */; settings = {ASSET_TAGS = (); }; };
5596BDE41BC8F384007E38D5 /* IntegerConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BE4EB01B1E4A9F007A2B57 /* IntegerConvertible.swift */; settings = {ASSET_TAGS = (); }; };
5596BDE51BC8F384007E38D5 /* BytesSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D63F741BB711270041579B /* BytesSequence.swift */; settings = {ASSET_TAGS = (); }; };
75100F8F19B0BC890005C5F5 /* Poly1305Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75100F8E19B0BC890005C5F5 /* Poly1305Tests.swift */; };
75164E4919AD30AC00737F30 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75164E4819AD30AC00737F30 /* Utils.swift */; };
751C5C3D19B26B000094C75D /* Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 751C5C3C19B26B000094C75D /* Poly1305.swift */; };
75232CCE1BC6E6AC007F68B1 /* CSArrayType+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75232CCD1BC6E6AC007F68B1 /* CSArrayType+Extensions.swift */; };
7539E3291B3B4A530037F4E1 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750A545F1992D2680017DA75 /* MD5.swift */; };
7539E32A1B3B4C480037F4E1 /* NSDataExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752DEF7619693EA000E17557 /* NSDataExtension.swift */; };
7539E32B1B3B4C6B0037F4E1 /* HMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758A94251A65AEB100E46135 /* HMAC.swift */; };
7539E32C1B3B4C750037F4E1 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7599C9C5199EA28700A3988B /* StringExtension.swift */; };
7539E32C1B3B4C750037F4E1 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7599C9C5199EA28700A3988B /* String+Extension.swift */; };
7539E32D1B3B4E950037F4E1 /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752E087A199FF27C005B0EA0 /* SHA1.swift */; };
7539E32E1B3B4E970037F4E1 /* SHA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75153D4119AA3C7900750381 /* SHA2.swift */; };
75445821196AA2A5002FF20E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75445820196AA2A5002FF20E /* Security.framework */; settings = {ATTRIBUTES = (Required, ); }; };
7547195119931802002FA5F1 /* IntExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7547195019931802002FA5F1 /* IntExtension.swift */; };
754BE45B19693E190098E6F3 /* CryptoSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 754BE45A19693E190098E6F3 /* CryptoSwift.h */; settings = {ATTRIBUTES = (Public, ); }; };
754BE46819693E190098E6F3 /* HashTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754BE46719693E190098E6F3 /* HashTests.swift */; };
754C30B71AA13BC000E6FFA4 /* PKCS7.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754C30B61AA13BC000E6FFA4 /* PKCS7.swift */; };
754C8FED19979F94005AD904 /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754C8FEC19979F94005AD904 /* ArrayExtension.swift */; };
754C8FED19979F94005AD904 /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754C8FEC19979F94005AD904 /* Array+Extension.swift */; };
754DD76E19A149AF00E52288 /* HashProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754DD76D19A149AF00E52288 /* HashProtocol.swift */; };
755111E819B7B7DF00C2AD86 /* Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755111E719B7B7DF00C2AD86 /* Authenticator.swift */; };
7552614E1993051E000D2B20 /* Hash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7552614D1993051E000D2B20 /* Hash.swift */; };
@ -49,8 +68,8 @@
758A94281A65C59200E46135 /* HMACTests.swift in Resources */ = {isa = PBXBuildFile; fileRef = 758A94271A65C59200E46135 /* HMACTests.swift */; };
758A94291A65C67400E46135 /* HMACTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758A94271A65C59200E46135 /* HMACTests.swift */; };
758C764119B61AE500653BC6 /* Generics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758C764019B61AE500653BC6 /* Generics.swift */; };
758C764319B61DE900653BC6 /* UInt16Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758C764219B61DE900653BC6 /* UInt16Extension.swift */; };
758F3F781992F6CE0014BBDA /* UInt8Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758F3F771992F6CE0014BBDA /* UInt8Extension.swift */; };
759B0A9C1BCDAB1200AF902E /* String+FoundationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759B0A9B1BCDAB1200AF902E /* String+FoundationExtension.swift */; settings = {ASSET_TAGS = (); }; };
759D481119B517BC005FF7FC /* BitExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759D481019B517BC005FF7FC /* BitExtension.swift */; };
75A663A61AA0CAD00052110B /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A663A51AA0CAD00052110B /* Padding.swift */; };
75A74B271A1FF6B2004419F1 /* AES.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A74B261A1FF6B2004419F1 /* AES.swift */; };
@ -58,11 +77,52 @@
75B601EB197D6A6C0009B53D /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 754BE45519693E190098E6F3 /* CryptoSwift.framework */; };
75BC3AE31A4E412000ADF343 /* CipherBlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BC3AE21A4E412000ADF343 /* CipherBlockMode.swift */; };
75BE4EB11B1E4A9F007A2B57 /* IntegerConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BE4EB01B1E4A9F007A2B57 /* IntegerConvertible.swift */; };
75D2D1A01B5689EB000A2615 /* NSDataSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D2D19F1B5689EB000A2615 /* NSDataSequence.swift */; };
75D63F751BB711270041579B /* BytesSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D63F741BB711270041579B /* BytesSequence.swift */; };
75D63F771BB840050041579B /* ArraySlice<UInt8>+Bytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D63F761BB840050041579B /* ArraySlice<UInt8>+Bytes.swift */; };
75D94E2419B60C08007CB2A4 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D94E2319B60C08007CB2A4 /* Operators.swift */; };
75D94E2619B60C4F007CB2A4 /* UInt32Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D94E2519B60C4F007CB2A4 /* UInt32Extension.swift */; };
75D94E2819B60DDE007CB2A4 /* UInt64Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D94E2719B60DDE007CB2A4 /* UInt64Extension.swift */; };
75DF77481BC8EB59006E9520 /* UInt64Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D94E2719B60DDE007CB2A4 /* UInt64Extension.swift */; };
75DF77491BC8EB59006E9520 /* Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 751C5C3C19B26B000094C75D /* Poly1305.swift */; };
75DF774A1BC8EB59006E9520 /* Hash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7552614D1993051E000D2B20 /* Hash.swift */; };
75DF774B1BC8EB59006E9520 /* CipherBlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BC3AE21A4E412000ADF343 /* CipherBlockMode.swift */; };
75DF774C1BC8EB59006E9520 /* IntegerConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BE4EB01B1E4A9F007A2B57 /* IntegerConvertible.swift */; };
75DF774D1BC8EB59006E9520 /* SHA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75153D4119AA3C7900750381 /* SHA2.swift */; };
75DF774E1BC8EB59006E9520 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7599C9C5199EA28700A3988B /* String+Extension.swift */; };
75DF774F1BC8EB59006E9520 /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7563B2E719B14D4300B152CD /* Cipher.swift */; };
75DF77501BC8EB59006E9520 /* HMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758A94251A65AEB100E46135 /* HMAC.swift */; };
75DF77511BC8EB59006E9520 /* ChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EB380019ABDD710002375A /* ChaCha20.swift */; };
75DF77521BC8EB59006E9520 /* AES+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C951BB8A4BD009CAFC5 /* AES+Foundation.swift */; };
75DF77531BC8EB59006E9520 /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A663A51AA0CAD00052110B /* Padding.swift */; };
75DF77541BC8EB59006E9520 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75164E4819AD30AC00737F30 /* Utils.swift */; };
75DF77551BC8EB59006E9520 /* BytesSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D63F741BB711270041579B /* BytesSequence.swift */; };
75DF77561BC8EB59006E9520 /* ChaCha20+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C971BB8A4BD009CAFC5 /* ChaCha20+Foundation.swift */; };
75DF77571BC8EB59006E9520 /* BitExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759D481019B517BC005FF7FC /* BitExtension.swift */; };
75DF77581BC8EB59006E9520 /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754C8FEC19979F94005AD904 /* Array+Extension.swift */; };
75DF77591BC8EB59006E9520 /* CSArrayType+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75232CCD1BC6E6AC007F68B1 /* CSArrayType+Extensions.swift */; };
75DF775A1BC8EB59006E9520 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750A545F1992D2680017DA75 /* MD5.swift */; };
75DF775B1BC8EB59006E9520 /* Array<UInt8>+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C961BB8A4BD009CAFC5 /* Array<UInt8>+Foundation.swift */; };
75DF775C1BC8EB59006E9520 /* IntExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7547195019931802002FA5F1 /* IntExtension.swift */; };
75DF775D1BC8EB59006E9520 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D94E2319B60C08007CB2A4 /* Operators.swift */; };
75DF775E1BC8EB59006E9520 /* NSData+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C981BB8A4BD009CAFC5 /* NSData+Extension.swift */; };
75DF775F1BC8EB59006E9520 /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752E087A199FF27C005B0EA0 /* SHA1.swift */; };
75DF77601BC8EB59006E9520 /* Utils+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C991BB8A4BD009CAFC5 /* Utils+Foundation.swift */; };
75DF77611BC8EB59006E9520 /* PKCS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75B0A56F1AB1A1BB000BD8D2 /* PKCS5.swift */; };
75DF77621BC8EB59006E9520 /* CRC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757EF7F419AAA82400586276 /* CRC.swift */; };
75DF77631BC8EB59006E9520 /* UInt32Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D94E2519B60C4F007CB2A4 /* UInt32Extension.swift */; };
75DF77641BC8EB59006E9520 /* AES.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A74B261A1FF6B2004419F1 /* AES.swift */; };
75DF77651BC8EB59006E9520 /* ArraySlice<UInt8>+Bytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D63F761BB840050041579B /* ArraySlice<UInt8>+Bytes.swift */; };
75DF77661BC8EB59006E9520 /* PKCS7.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754C30B61AA13BC000E6FFA4 /* PKCS7.swift */; };
75DF77671BC8EB59006E9520 /* Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755111E719B7B7DF00C2AD86 /* Authenticator.swift */; };
75DF77681BC8EB59006E9520 /* HashProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754DD76D19A149AF00E52288 /* HashProtocol.swift */; };
75DF77691BC8EB59006E9520 /* Generics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758C764019B61AE500653BC6 /* Generics.swift */; };
75DF776A1BC8EB59006E9520 /* UInt8Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758F3F771992F6CE0014BBDA /* UInt8Extension.swift */; };
75EB380119ABDD710002375A /* ChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EB380019ABDD710002375A /* ChaCha20.swift */; };
75FB9C9A1BB8A4BD009CAFC5 /* AES+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C951BB8A4BD009CAFC5 /* AES+Foundation.swift */; };
75FB9C9B1BB8A4BD009CAFC5 /* Array<UInt8>+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C961BB8A4BD009CAFC5 /* Array<UInt8>+Foundation.swift */; };
75FB9C9C1BB8A4BD009CAFC5 /* ChaCha20+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C971BB8A4BD009CAFC5 /* ChaCha20+Foundation.swift */; };
75FB9C9D1BB8A4BD009CAFC5 /* NSData+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C981BB8A4BD009CAFC5 /* NSData+Extension.swift */; };
75FB9C9E1BB8A4BD009CAFC5 /* Utils+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FB9C991BB8A4BD009CAFC5 /* Utils+Foundation.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -127,26 +187,35 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
75DF776E1BC8EB59006E9520 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
5596BDBB1BC8F220007E38D5 /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
750A545F1992D2680017DA75 /* MD5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MD5.swift; sourceTree = "<group>"; };
75100F8E19B0BC890005C5F5 /* Poly1305Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Poly1305Tests.swift; sourceTree = "<group>"; };
75153D4119AA3C7900750381 /* SHA2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SHA2.swift; sourceTree = "<group>"; };
75164E4819AD30AC00737F30 /* Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; };
751C5C3C19B26B000094C75D /* Poly1305.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Poly1305.swift; sourceTree = "<group>"; };
752DEF7619693EA000E17557 /* NSDataExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSDataExtension.swift; sourceTree = "<group>"; };
75232CCD1BC6E6AC007F68B1 /* CSArrayType+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSArrayType+Extensions.swift"; sourceTree = "<group>"; };
752E087A199FF27C005B0EA0 /* SHA1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SHA1.swift; sourceTree = "<group>"; };
75445820196AA2A5002FF20E /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
7547195019931802002FA5F1 /* IntExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntExtension.swift; sourceTree = "<group>"; };
754BE45519693E190098E6F3 /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
754BE45919693E190098E6F3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
754BE45A19693E190098E6F3 /* CryptoSwift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CryptoSwift.h; sourceTree = "<group>"; };
754BE46019693E190098E6F3 /* CryptoSwiftTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CryptoSwiftTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
754BE46619693E190098E6F3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
754BE46719693E190098E6F3 /* HashTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashTests.swift; sourceTree = "<group>"; };
754C30B61AA13BC000E6FFA4 /* PKCS7.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PKCS7.swift; sourceTree = "<group>"; };
754C8FEC19979F94005AD904 /* ArrayExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtension.swift; sourceTree = "<group>"; };
754C8FEC19979F94005AD904 /* Array+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array+Extension.swift"; sourceTree = "<group>"; };
754DD76D19A149AF00E52288 /* HashProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HashProtocol.swift; sourceTree = "<group>"; };
755111E719B7B7DF00C2AD86 /* Authenticator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Authenticator.swift; sourceTree = "<group>"; };
7552614D1993051E000D2B20 /* Hash.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hash.swift; sourceTree = "<group>"; };
@ -161,28 +230,41 @@
758A94251A65AEB100E46135 /* HMAC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HMAC.swift; sourceTree = "<group>"; };
758A94271A65C59200E46135 /* HMACTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HMACTests.swift; sourceTree = "<group>"; };
758C764019B61AE500653BC6 /* Generics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Generics.swift; sourceTree = "<group>"; };
758C764219B61DE900653BC6 /* UInt16Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UInt16Extension.swift; sourceTree = "<group>"; };
758F3F771992F6CE0014BBDA /* UInt8Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UInt8Extension.swift; sourceTree = "<group>"; };
7599C9C5199EA28700A3988B /* StringExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = "<group>"; };
7599C9C5199EA28700A3988B /* String+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Extension.swift"; sourceTree = "<group>"; };
759B0A9B1BCDAB1200AF902E /* String+FoundationExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+FoundationExtension.swift"; sourceTree = "<group>"; };
759D481019B517BC005FF7FC /* BitExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BitExtension.swift; sourceTree = "<group>"; };
75A663A51AA0CAD00052110B /* Padding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Padding.swift; sourceTree = "<group>"; };
75A74B261A1FF6B2004419F1 /* AES.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AES.swift; sourceTree = "<group>"; };
75B0A56F1AB1A1BB000BD8D2 /* PKCS5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PKCS5.swift; sourceTree = "<group>"; };
75BC3AE21A4E412000ADF343 /* CipherBlockMode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CipherBlockMode.swift; sourceTree = "<group>"; };
75BE4EB01B1E4A9F007A2B57 /* IntegerConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntegerConvertible.swift; sourceTree = "<group>"; };
75D2D19F1B5689EB000A2615 /* NSDataSequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSDataSequence.swift; sourceTree = "<group>"; };
75D63F741BB711270041579B /* BytesSequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BytesSequence.swift; sourceTree = "<group>"; };
75D63F761BB840050041579B /* ArraySlice<UInt8>+Bytes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ArraySlice<UInt8>+Bytes.swift"; sourceTree = "<group>"; };
75D94E2319B60C08007CB2A4 /* Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = "<group>"; };
75D94E2519B60C4F007CB2A4 /* UInt32Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UInt32Extension.swift; sourceTree = "<group>"; };
75D94E2719B60DDE007CB2A4 /* UInt64Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UInt64Extension.swift; sourceTree = "<group>"; };
75DF77721BC8EB59006E9520 /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
75EB380019ABDD710002375A /* ChaCha20.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChaCha20.swift; sourceTree = "<group>"; };
75FB9C951BB8A4BD009CAFC5 /* AES+Foundation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AES+Foundation.swift"; sourceTree = "<group>"; };
75FB9C961BB8A4BD009CAFC5 /* Array<UInt8>+Foundation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array<UInt8>+Foundation.swift"; sourceTree = "<group>"; };
75FB9C971BB8A4BD009CAFC5 /* ChaCha20+Foundation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChaCha20+Foundation.swift"; sourceTree = "<group>"; };
75FB9C981BB8A4BD009CAFC5 /* NSData+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSData+Extension.swift"; sourceTree = "<group>"; };
75FB9C991BB8A4BD009CAFC5 /* Utils+Foundation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Utils+Foundation.swift"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
5596BDB71BC8F220007E38D5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
754BE45119693E190098E6F3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
75445821196AA2A5002FF20E /* Security.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -194,6 +276,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
75DF776B1BC8EB59006E9520 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@ -220,6 +309,8 @@
children = (
754BE45519693E190098E6F3 /* CryptoSwift.framework */,
754BE46019693E190098E6F3 /* CryptoSwiftTests.xctest */,
75DF77721BC8EB59006E9520 /* CryptoSwift.framework */,
5596BDBB1BC8F220007E38D5 /* CryptoSwift.framework */,
);
name = Products;
sourceTree = "<group>";
@ -227,7 +318,7 @@
754BE45719693E190098E6F3 /* CryptoSwift */ = {
isa = PBXGroup;
children = (
754BE45A19693E190098E6F3 /* CryptoSwift.h */,
75FB9C941BB8A4BD009CAFC5 /* Foundation */,
7552614D1993051E000D2B20 /* Hash.swift */,
7563B2E719B14D4300B152CD /* Cipher.swift */,
75BC3AE21A4E412000ADF343 /* CipherBlockMode.swift */,
@ -245,19 +336,19 @@
758A94251A65AEB100E46135 /* HMAC.swift */,
75A74B261A1FF6B2004419F1 /* AES.swift */,
759D481019B517BC005FF7FC /* BitExtension.swift */,
758F3F771992F6CE0014BBDA /* UInt8Extension.swift */,
7547195019931802002FA5F1 /* IntExtension.swift */,
758C764219B61DE900653BC6 /* UInt16Extension.swift */,
758F3F771992F6CE0014BBDA /* UInt8Extension.swift */,
75D94E2519B60C4F007CB2A4 /* UInt32Extension.swift */,
75D94E2719B60DDE007CB2A4 /* UInt64Extension.swift */,
752DEF7619693EA000E17557 /* NSDataExtension.swift */,
754C8FEC19979F94005AD904 /* ArrayExtension.swift */,
7599C9C5199EA28700A3988B /* StringExtension.swift */,
754C8FEC19979F94005AD904 /* Array+Extension.swift */,
75D63F761BB840050041579B /* ArraySlice<UInt8>+Bytes.swift */,
75232CCD1BC6E6AC007F68B1 /* CSArrayType+Extensions.swift */,
7599C9C5199EA28700A3988B /* String+Extension.swift */,
75D94E2319B60C08007CB2A4 /* Operators.swift */,
75164E4819AD30AC00737F30 /* Utils.swift */,
758C764019B61AE500653BC6 /* Generics.swift */,
75BE4EB01B1E4A9F007A2B57 /* IntegerConvertible.swift */,
75D2D19F1B5689EB000A2615 /* NSDataSequence.swift */,
75D63F741BB711270041579B /* BytesSequence.swift */,
754BE45819693E190098E6F3 /* Supporting Files */,
);
path = CryptoSwift;
@ -296,23 +387,67 @@
name = "Supporting Files";
sourceTree = "<group>";
};
75FB9C941BB8A4BD009CAFC5 /* Foundation */ = {
isa = PBXGroup;
children = (
75FB9C951BB8A4BD009CAFC5 /* AES+Foundation.swift */,
75FB9C961BB8A4BD009CAFC5 /* Array<UInt8>+Foundation.swift */,
75FB9C971BB8A4BD009CAFC5 /* ChaCha20+Foundation.swift */,
75FB9C981BB8A4BD009CAFC5 /* NSData+Extension.swift */,
75FB9C991BB8A4BD009CAFC5 /* Utils+Foundation.swift */,
759B0A9B1BCDAB1200AF902E /* String+FoundationExtension.swift */,
);
path = Foundation;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
5596BDB81BC8F220007E38D5 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
754BE45219693E190098E6F3 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
754BE45B19693E190098E6F3 /* CryptoSwift.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
75DF776C1BC8EB59006E9520 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
754BE45419693E190098E6F3 /* CryptoSwift */ = {
5596BDBA1BC8F220007E38D5 /* CryptoSwift watchOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 754BE46B19693E190098E6F3 /* Build configuration list for PBXNativeTarget "CryptoSwift" */;
buildConfigurationList = 5596BDC01BC8F220007E38D5 /* Build configuration list for PBXNativeTarget "CryptoSwift watchOS" */;
buildPhases = (
5596BDB61BC8F220007E38D5 /* Sources */,
5596BDB71BC8F220007E38D5 /* Frameworks */,
5596BDB81BC8F220007E38D5 /* Headers */,
5596BDB91BC8F220007E38D5 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "CryptoSwift watchOS";
productName = "CryptoSwift watchOS";
productReference = 5596BDBB1BC8F220007E38D5 /* CryptoSwift.framework */;
productType = "com.apple.product-type.framework";
};
754BE45419693E190098E6F3 /* CryptoSwift iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 754BE46B19693E190098E6F3 /* Build configuration list for PBXNativeTarget "CryptoSwift iOS" */;
buildPhases = (
754BE45019693E190098E6F3 /* Sources */,
754BE45119693E190098E6F3 /* Frameworks */,
@ -324,7 +459,7 @@
);
dependencies = (
);
name = CryptoSwift;
name = "CryptoSwift iOS";
productName = CryptoSwift;
productReference = 754BE45519693E190098E6F3 /* CryptoSwift.framework */;
productType = "com.apple.product-type.framework";
@ -353,6 +488,25 @@
productReference = 754BE46019693E190098E6F3 /* CryptoSwiftTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
75DF77461BC8EB59006E9520 /* CryptoSwift OSX */ = {
isa = PBXNativeTarget;
buildConfigurationList = 75DF776F1BC8EB59006E9520 /* Build configuration list for PBXNativeTarget "CryptoSwift OSX" */;
buildPhases = (
75DF77471BC8EB59006E9520 /* Sources */,
75DF776B1BC8EB59006E9520 /* Frameworks */,
75DF776C1BC8EB59006E9520 /* Headers */,
75DF776D1BC8EB59006E9520 /* Resources */,
75DF776E1BC8EB59006E9520 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = "CryptoSwift OSX";
productName = CryptoSwift;
productReference = 75DF77721BC8EB59006E9520 /* CryptoSwift.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@ -363,8 +517,8 @@
LastUpgradeCheck = 0700;
ORGANIZATIONNAME = "Marcin Krzyzanowski";
TargetAttributes = {
3F8849E11B0647D6006AB604 = {
CreatedOnToolsVersion = 6.3.1;
5596BDBA1BC8F220007E38D5 = {
CreatedOnToolsVersion = 7.0.1;
};
754BE45419693E190098E6F3 = {
CreatedOnToolsVersion = 6.0;
@ -387,14 +541,22 @@
projectDirPath = "";
projectRoot = "";
targets = (
754BE45419693E190098E6F3 /* CryptoSwift */,
754BE45419693E190098E6F3 /* CryptoSwift iOS */,
5596BDBA1BC8F220007E38D5 /* CryptoSwift watchOS */,
75DF77461BC8EB59006E9520 /* CryptoSwift OSX */,
754BE45F19693E190098E6F3 /* CryptoSwiftTests */,
3F8849E11B0647D6006AB604 /* CryptoSwift-Universal */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
5596BDB91BC8F220007E38D5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
754BE45319693E190098E6F3 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -410,54 +572,93 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3F8849E51B0647DD006AB604 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
75DF776D1BC8EB59006E9520 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "TARGET_NAME=\"CryptoSwift\"\nFRAMEWORK_NAME=\"CryptoSwift\"\nINSTALL_DIR=\"Framework\"\nFRAMEWORK=\"${INSTALL_DIR}/${FRAMEWORK_NAME}.framework\"\n\nif [ -d \"${INSTALL_DIR}\" ]\nthen\nrm -rf \"${INSTALL_DIR}\"\nfi\n\nmkdir \"${INSTALL_DIR}\"\n\nWRK_DIR=\"build\"\nDEVICE_DIR=\"${WRK_DIR}/Release-iphoneos/${FRAMEWORK_NAME}.framework\"\nSIMULATOR_DIR=\"${WRK_DIR}/Release-iphonesimulator/${FRAMEWORK_NAME}.framework\"\n\nxcodebuild -configuration \"Release\" -target \"${TARGET_NAME}\" -sdk iphoneos SYMROOT=$(PWD)/${WRK_DIR}\nxcodebuild -configuration \"Release\" -target \"${TARGET_NAME}\" -sdk iphonesimulator SYMROOT=$(PWD)/${WRK_DIR}\n\nlipo -create \"${DEVICE_DIR}/${FRAMEWORK_NAME}\" \"${SIMULATOR_DIR}/${FRAMEWORK_NAME}\" -output \"${DEVICE_DIR}/${FRAMEWORK_NAME}\"\n\ncp -R \"${DEVICE_DIR}\" \"${INSTALL_DIR}/\"\n\nif [ -d \"${SIMULATOR_DIR}/Modules/${FRAMEWORK_NAME}.swiftmodule/\" ]; then\ncp -f -R \"${SIMULATOR_DIR}/Modules/${FRAMEWORK_NAME}.swiftmodule/\" \"${FRAMEWORK}/Modules/${FRAMEWORK_NAME}.swiftmodule/\" | echo\nfi\n\nrm -r \"${WRK_DIR}\"";
};
/* End PBXShellScriptBuildPhase section */
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
5596BDB61BC8F220007E38D5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
5596BDD01BC8F384007E38D5 /* MD5.swift in Sources */,
5596BDD91BC8F384007E38D5 /* IntExtension.swift in Sources */,
5596BDC61BC8F384007E38D5 /* NSData+Extension.swift in Sources */,
5596BDC81BC8F384007E38D5 /* Hash.swift in Sources */,
5596BDD21BC8F384007E38D5 /* SHA2.swift in Sources */,
5596BDDC1BC8F384007E38D5 /* UInt64Extension.swift in Sources */,
5596BDE11BC8F384007E38D5 /* Operators.swift in Sources */,
5596BDDB1BC8F384007E38D5 /* UInt32Extension.swift in Sources */,
5596BDDE1BC8F384007E38D5 /* ArraySlice<UInt8>+Bytes.swift in Sources */,
5596BDCB1BC8F384007E38D5 /* Padding.swift in Sources */,
5596BDC91BC8F384007E38D5 /* Cipher.swift in Sources */,
5596BDD61BC8F384007E38D5 /* HMAC.swift in Sources */,
5596BDD11BC8F384007E38D5 /* SHA1.swift in Sources */,
5596BDD31BC8F384007E38D5 /* CRC.swift in Sources */,
5596BDE41BC8F384007E38D5 /* IntegerConvertible.swift in Sources */,
5596BDD51BC8F384007E38D5 /* Poly1305.swift in Sources */,
5596BDCA1BC8F384007E38D5 /* CipherBlockMode.swift in Sources */,
5596BDDA1BC8F384007E38D5 /* UInt8Extension.swift in Sources */,
5596BDCE1BC8F384007E38D5 /* Authenticator.swift in Sources */,
5596BDC31BC8F384007E38D5 /* AES+Foundation.swift in Sources */,
5596BDD81BC8F384007E38D5 /* BitExtension.swift in Sources */,
5596BDCD1BC8F384007E38D5 /* PKCS7.swift in Sources */,
5596BDC41BC8F384007E38D5 /* Array<UInt8>+Foundation.swift in Sources */,
5596BDC51BC8F384007E38D5 /* ChaCha20+Foundation.swift in Sources */,
5596BDE51BC8F384007E38D5 /* BytesSequence.swift in Sources */,
5596BDE21BC8F384007E38D5 /* Utils.swift in Sources */,
5596BDDD1BC8F384007E38D5 /* Array+Extension.swift in Sources */,
5596BDCC1BC8F384007E38D5 /* PKCS5.swift in Sources */,
5596BDD41BC8F384007E38D5 /* ChaCha20.swift in Sources */,
5596BDCF1BC8F384007E38D5 /* HashProtocol.swift in Sources */,
5596BDD71BC8F384007E38D5 /* AES.swift in Sources */,
5596BDDF1BC8F384007E38D5 /* CSArrayType+Extensions.swift in Sources */,
5596BDE31BC8F384007E38D5 /* Generics.swift in Sources */,
5596BDE01BC8F384007E38D5 /* String+Extension.swift in Sources */,
5596BDC71BC8F384007E38D5 /* Utils+Foundation.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
754BE45019693E190098E6F3 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
75D2D1A01B5689EB000A2615 /* NSDataSequence.swift in Sources */,
75D94E2819B60DDE007CB2A4 /* UInt64Extension.swift in Sources */,
751C5C3D19B26B000094C75D /* Poly1305.swift in Sources */,
7552614E1993051E000D2B20 /* Hash.swift in Sources */,
75BC3AE31A4E412000ADF343 /* CipherBlockMode.swift in Sources */,
75BE4EB11B1E4A9F007A2B57 /* IntegerConvertible.swift in Sources */,
7539E32E1B3B4E970037F4E1 /* SHA2.swift in Sources */,
7539E32C1B3B4C750037F4E1 /* StringExtension.swift in Sources */,
7539E32C1B3B4C750037F4E1 /* String+Extension.swift in Sources */,
7563B2E819B14D4300B152CD /* Cipher.swift in Sources */,
7539E32B1B3B4C6B0037F4E1 /* HMAC.swift in Sources */,
7539E32A1B3B4C480037F4E1 /* NSDataExtension.swift in Sources */,
75EB380119ABDD710002375A /* ChaCha20.swift in Sources */,
75FB9C9A1BB8A4BD009CAFC5 /* AES+Foundation.swift in Sources */,
75A663A61AA0CAD00052110B /* Padding.swift in Sources */,
75164E4919AD30AC00737F30 /* Utils.swift in Sources */,
75D63F751BB711270041579B /* BytesSequence.swift in Sources */,
75FB9C9C1BB8A4BD009CAFC5 /* ChaCha20+Foundation.swift in Sources */,
759D481119B517BC005FF7FC /* BitExtension.swift in Sources */,
754C8FED19979F94005AD904 /* ArrayExtension.swift in Sources */,
754C8FED19979F94005AD904 /* Array+Extension.swift in Sources */,
75232CCE1BC6E6AC007F68B1 /* CSArrayType+Extensions.swift in Sources */,
7539E3291B3B4A530037F4E1 /* MD5.swift in Sources */,
75FB9C9B1BB8A4BD009CAFC5 /* Array<UInt8>+Foundation.swift in Sources */,
7547195119931802002FA5F1 /* IntExtension.swift in Sources */,
758C764319B61DE900653BC6 /* UInt16Extension.swift in Sources */,
75D94E2419B60C08007CB2A4 /* Operators.swift in Sources */,
75FB9C9D1BB8A4BD009CAFC5 /* NSData+Extension.swift in Sources */,
7539E32D1B3B4E950037F4E1 /* SHA1.swift in Sources */,
75FB9C9E1BB8A4BD009CAFC5 /* Utils+Foundation.swift in Sources */,
75B0A5701AB1A1BB000BD8D2 /* PKCS5.swift in Sources */,
757EF7F519AAA82400586276 /* CRC.swift in Sources */,
75D94E2619B60C4F007CB2A4 /* UInt32Extension.swift in Sources */,
759B0A9C1BCDAB1200AF902E /* String+FoundationExtension.swift in Sources */,
75A74B271A1FF6B2004419F1 /* AES.swift in Sources */,
75D63F771BB840050041579B /* ArraySlice<UInt8>+Bytes.swift in Sources */,
754C30B71AA13BC000E6FFA4 /* PKCS7.swift in Sources */,
755111E819B7B7DF00C2AD86 /* Authenticator.swift in Sources */,
754DD76E19A149AF00E52288 /* HashProtocol.swift in Sources */,
@ -481,58 +682,131 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
75DF77471BC8EB59006E9520 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
75DF77481BC8EB59006E9520 /* UInt64Extension.swift in Sources */,
75DF77491BC8EB59006E9520 /* Poly1305.swift in Sources */,
75DF774A1BC8EB59006E9520 /* Hash.swift in Sources */,
75DF774B1BC8EB59006E9520 /* CipherBlockMode.swift in Sources */,
75DF774C1BC8EB59006E9520 /* IntegerConvertible.swift in Sources */,
75DF774D1BC8EB59006E9520 /* SHA2.swift in Sources */,
75DF774E1BC8EB59006E9520 /* String+Extension.swift in Sources */,
75DF774F1BC8EB59006E9520 /* Cipher.swift in Sources */,
75DF77501BC8EB59006E9520 /* HMAC.swift in Sources */,
75DF77511BC8EB59006E9520 /* ChaCha20.swift in Sources */,
75DF77521BC8EB59006E9520 /* AES+Foundation.swift in Sources */,
75DF77531BC8EB59006E9520 /* Padding.swift in Sources */,
75DF77541BC8EB59006E9520 /* Utils.swift in Sources */,
75DF77551BC8EB59006E9520 /* BytesSequence.swift in Sources */,
75DF77561BC8EB59006E9520 /* ChaCha20+Foundation.swift in Sources */,
75DF77571BC8EB59006E9520 /* BitExtension.swift in Sources */,
75DF77581BC8EB59006E9520 /* Array+Extension.swift in Sources */,
75DF77591BC8EB59006E9520 /* CSArrayType+Extensions.swift in Sources */,
75DF775A1BC8EB59006E9520 /* MD5.swift in Sources */,
75DF775B1BC8EB59006E9520 /* Array<UInt8>+Foundation.swift in Sources */,
75DF775C1BC8EB59006E9520 /* IntExtension.swift in Sources */,
75DF775D1BC8EB59006E9520 /* Operators.swift in Sources */,
75DF775E1BC8EB59006E9520 /* NSData+Extension.swift in Sources */,
75DF775F1BC8EB59006E9520 /* SHA1.swift in Sources */,
75DF77601BC8EB59006E9520 /* Utils+Foundation.swift in Sources */,
75DF77611BC8EB59006E9520 /* PKCS5.swift in Sources */,
75DF77621BC8EB59006E9520 /* CRC.swift in Sources */,
75DF77631BC8EB59006E9520 /* UInt32Extension.swift in Sources */,
75DF77641BC8EB59006E9520 /* AES.swift in Sources */,
75DF77651BC8EB59006E9520 /* ArraySlice<UInt8>+Bytes.swift in Sources */,
75DF77661BC8EB59006E9520 /* PKCS7.swift in Sources */,
75DF77671BC8EB59006E9520 /* Authenticator.swift in Sources */,
75DF77681BC8EB59006E9520 /* HashProtocol.swift in Sources */,
75DF77691BC8EB59006E9520 /* Generics.swift in Sources */,
75DF776A1BC8EB59006E9520 /* UInt8Extension.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
75B601E4197D69EB0009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */;
target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B601E3197D69EB0009B53D /* PBXContainerItemProxy */;
};
75B601E6197D6A270009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */;
target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B601E5197D6A270009B53D /* PBXContainerItemProxy */;
};
75B601E8197D6A3A0009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */;
target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B601E7197D6A3A0009B53D /* PBXContainerItemProxy */;
};
75B601EA197D6A5C0009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */;
target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B601E9197D6A5C0009B53D /* PBXContainerItemProxy */;
};
75B601ED197D6B3D0009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */;
target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B601EC197D6B3D0009B53D /* PBXContainerItemProxy */;
};
75B6021D197D6CF10009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */;
target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B6021C197D6CF10009B53D /* PBXContainerItemProxy */;
};
75B6021F197D6D070009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */;
target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B6021E197D6D070009B53D /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
3F8849E31B0647D6006AB604 /* Debug */ = {
5596BDC11BC8F220007E38D5 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = CryptoSwift/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.hakore.CryptoSwift;
PRODUCT_NAME = CryptoSwift;
SDKROOT = watchos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
name = Debug;
};
3F8849E41B0647D6006AB604 /* Release */ = {
5596BDC21BC8F220007E38D5 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = CryptoSwift/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = com.hakore.CryptoSwift;
PRODUCT_NAME = CryptoSwift;
SDKROOT = watchos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
name = Release;
};
@ -553,7 +827,6 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@ -573,9 +846,12 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.9;
METAL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = CryptoSwift;
SDKROOT = iphoneos;
SWIFT_INSTALL_OBJC_HEADER = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
@ -600,7 +876,6 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 1;
ENABLE_NS_ASSERTIONS = NO;
@ -613,8 +888,11 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.9;
METAL_ENABLE_DEBUG_INFO = NO;
PRODUCT_NAME = CryptoSwift;
SDKROOT = iphoneos;
SWIFT_INSTALL_OBJC_HEADER = NO;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
@ -626,22 +904,19 @@
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
BITCODE_GENERATION_MODE = marker;
CLANG_ENABLE_MODULES = YES;
DEFINES_MODULE = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_TESTABILITY = YES;
HEADER_SEARCH_PATHS = (
"$(inherited)",
"/Applications/Xcode6-Beta3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
"includes/**",
);
INFOPLIST_FILE = CryptoSwift/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.hakore.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
PRODUCT_NAME = CryptoSwift;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
@ -651,25 +926,22 @@
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
BITCODE_GENERATION_MODE = bitcode;
CLANG_ENABLE_MODULES = YES;
DEFINES_MODULE = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_TESTABILITY = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_UNROLL_LOOPS = YES;
HEADER_SEARCH_PATHS = (
"$(inherited)",
"/Applications/Xcode6-Beta3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
"includes/**",
);
INFOPLIST_FILE = CryptoSwift/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LLVM_LTO = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.hakore.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
PRODUCT_NAME = CryptoSwift;
SKIP_INSTALL = YES;
SWIFT_DISABLE_SAFETY_CHECKS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
@ -720,14 +992,64 @@
};
name = Release;
};
75DF77701BC8EB59006E9520 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
BITCODE_GENERATION_MODE = marker;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = CryptoSwift/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.hakore.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = CryptoSwift;
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
75DF77711BC8EB59006E9520 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
BITCODE_GENERATION_MODE = bitcode;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_UNROLL_LOOPS = YES;
INFOPLIST_FILE = CryptoSwift/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LLVM_LTO = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.hakore.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = CryptoSwift;
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_DISABLE_SAFETY_CHECKS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
3F8849E21B0647D6006AB604 /* Build configuration list for PBXAggregateTarget "CryptoSwift-Universal" */ = {
5596BDC01BC8F220007E38D5 /* Build configuration list for PBXNativeTarget "CryptoSwift watchOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3F8849E31B0647D6006AB604 /* Debug */,
3F8849E41B0647D6006AB604 /* Release */,
5596BDC11BC8F220007E38D5 /* Debug */,
5596BDC21BC8F220007E38D5 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
@ -741,7 +1063,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
754BE46B19693E190098E6F3 /* Build configuration list for PBXNativeTarget "CryptoSwift" */ = {
754BE46B19693E190098E6F3 /* Build configuration list for PBXNativeTarget "CryptoSwift iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
754BE46C19693E190098E6F3 /* Debug */,
@ -759,6 +1081,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
75DF776F1BC8EB59006E9520 /* Build configuration list for PBXNativeTarget "CryptoSwift OSX" */ = {
isa = XCConfigurationList;
buildConfigurations = (
75DF77701BC8EB59006E9520 /* Debug */,
75DF77711BC8EB59006E9520 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 754BE44C19693E190098E6F3 /* Project object */;

View File

@ -4,6 +4,37 @@
<dict>
<key>runDestinationsByUUID</key>
<dict>
<key>85434D17-7706-4DE9-AFA7-B1DD0BD9FA39</key>
<dict>
<key>localComputer</key>
<dict>
<key>busSpeedInMHz</key>
<integer>100</integer>
<key>cpuCount</key>
<integer>1</integer>
<key>cpuKind</key>
<string>Intel Core i7</string>
<key>cpuSpeedInMHz</key>
<integer>2200</integer>
<key>logicalCPUCoresPerPackage</key>
<integer>4</integer>
<key>modelCode</key>
<string>MacBookAir7,2</string>
<key>physicalCPUCoresPerPackage</key>
<integer>2</integer>
<key>platformIdentifier</key>
<string>com.apple.platform.macosx</string>
</dict>
<key>targetArchitecture</key>
<string>x86_64</string>
<key>targetDevice</key>
<dict>
<key>modelCode</key>
<string>iPhone8,1</string>
<key>platformIdentifier</key>
<string>com.apple.platform.iphonesimulator</string>
</dict>
</dict>
<key>9396A4FE-F8F7-4542-8F75-DE77E1FEBEB9</key>
<dict>
<key>localComputer</key>

View File

@ -1,127 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
version = "1.3">
<BuildAction
parallelizeBuildables = "NO"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "754BE45419693E190098E6F3"
BuildableName = "CryptoSwift.framework"
BlueprintName = "CryptoSwift"
ReferencedContainer = "container:CryptoSwift.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "754BE45F19693E190098E6F3"
BuildableName = "CryptoSwiftTests.xctest"
BlueprintName = "CryptoSwiftTests"
ReferencedContainer = "container:CryptoSwift.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "754BE45F19693E190098E6F3"
BuildableName = "CryptoSwiftTests.xctest"
BlueprintName = "CryptoSwiftTests"
ReferencedContainer = "container:CryptoSwift.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "AESTests/testAESPerformance()">
</Test>
<Test
Identifier = "AESTests/testAESPerformanceCommonCrypto()">
</Test>
<Test
Identifier = "ChaCha20Tests/testChaCha20Performance()">
</Test>
<Test
Identifier = "RaufelderTests">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "754BE45419693E190098E6F3"
BuildableName = "CryptoSwift.framework"
BlueprintName = "CryptoSwift"
ReferencedContainer = "container:CryptoSwift.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "754BE45419693E190098E6F3"
BuildableName = "CryptoSwift.framework"
BlueprintName = "CryptoSwift"
ReferencedContainer = "container:CryptoSwift.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "754BE45419693E190098E6F3"
BuildableName = "CryptoSwift.framework"
BlueprintName = "CryptoSwift"
ReferencedContainer = "container:CryptoSwift.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -6,12 +6,12 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
final public class AES {
enum Error: ErrorType {
case BlockSizeExceeded
case InvalidKeyOrInitializationVector
case InvalidInitializationVector
}
public enum AESVariant:Int {
@ -47,54 +47,15 @@ final public class AES {
}
private let key:[UInt8]
private let iv:[UInt8]?
public lazy var expandedKey:[UInt8] = { AES.expandKey(self.key, variant: self.variant) }()
private lazy var expandedKey:[[UInt32]] = self.expandKey(self.key, variant: self.variant)
private lazy var expandedKeyInv:[[UInt32]] = self.expandKeyInv(self.key, variant: self.variant)
static private let sBox:[UInt8] = [
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]
static private let invSBox:[UInt8] = [
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3,
0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f,
0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54,
0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b,
0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24,
0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8,
0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d,
0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab,
0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3,
0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1,
0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41,
0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6,
0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9,
0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d,
0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0,
0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07,
0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60,
0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f,
0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5,
0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b,
0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55,
0x21, 0x0c, 0x7d]
private lazy var sBoxes:(sBox:[UInt32], invSBox:[UInt32]) = self.calculateSBox()
private lazy var sBox:[UInt32] = self.sBoxes.sBox
private lazy var sBoxInv:[UInt32] = self.sBoxes.invSBox
// Parameters for Linear Congruence Generators
static private let Rcon:[UInt8] = [
private let Rcon:[UInt8] = [
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
@ -112,32 +73,36 @@ final public class AES {
0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d]
public init?(key:[UInt8], iv:[UInt8], blockMode:CipherBlockMode = .CBC) {
private let T0:[UInt32] = [0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0xdf2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x3010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0xbf0f0fb, 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x2f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x8f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, 0xc040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0xf05050a, 0xb59a9a2f, 0x907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x0, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, 0x10f9f9e9, 0x6020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x4f5f5f1, 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0xef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0xa06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac, 0x7f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x5030306, 0x1f6f6f7, 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c]
private let T0_INV:[UInt32] = [0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 0x2752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, 0x728ebb2, 0x3c2b52f, 0x9a7bc586, 0xa50837d3, 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x69f715e, 0x51106ebd, 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, 0x55dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x0, 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0xfe75793, 0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, 0xaba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0xb0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0xd927850, 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x97826cd, 0xf418596e, 0x1b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x8cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, 0xf7daec41, 0xe50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, 0x4ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0xc25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0]
private let T1:[UInt32] = [0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x1010203, 0x6767cea9, 0x2b2b567d, 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, 0x404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, 0x5050a0f, 0x9a9a2fb5, 0x7070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 0x909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, 0x5353a6f5, 0xd1d1b968, 0x0, 0xededc12c, 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, 0x45458acf, 0xf9f9e910, 0x2020406, 0x7f7ffe81, 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, 0xcdcd814c, 0xc0c1814, 0x13132635, 0xececc32f, 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, 0xdedea779, 0x5e5ebce2, 0xb0b161d, 0xdbdbad76, 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0xa0a141e, 0x494992db, 0x6060c0a, 0x2424486c, 0x5c5cb8e4, 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x8081018, 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x3030605, 0xf6f6f701, 0xe0e1c12, 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, 0x8c8c038f, 0xa1a159f8, 0x89890980, 0xd0d1a17, 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, 0x414182c3, 0x999929b0, 0x2d2d5a77, 0xf0f1e11, 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a]
private let T1_INV:[UInt32] = [0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, 0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x3e34b93, 0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f, 0x5ab1de49, 0x1bba2567, 0xeea4598, 0xc0fe5de1, 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, 0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, 0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44, 0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd, 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994, 0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, 0xd373ab23, 0x24b72e2, 0x8f1fe357, 0xab55662a, 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x837d3a5, 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, 0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, 0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a, 0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, 0x8a213ef9, 0x6dd963d, 0x53eddae, 0xbde64d46, 0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff, 0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db, 0xa7ca147, 0xf427ce9, 0x1e84f8c9, 0x0, 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, 0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627, 0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, 0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e, 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, 0xd090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, 0x19f15785, 0x775af4c, 0xdd99eebb, 0x607fa3fd, 0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, 0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, 0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0, 0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0xbd49836, 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, 0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, 0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5, 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, 0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8, 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6, 0x9be7bad9, 0x366f4ace, 0x99fead4, 0x7cb029d6, 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, 0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, 0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x496e4df, 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f, 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, 0x61d79a8c, 0xca1377a, 0x14f8598e, 0x3c13eb89, 0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c, 0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, 0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41, 0x1a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490, 0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042]
private let T2:[UInt32] = [0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, 0x30605030, 0x1020301, 0x67cea967, 0x2b567d2b, 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, 0x4080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, 0x50a0f05, 0x9a2fb59a, 0x70e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 0x9121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, 0x53a6f553, 0xd1b968d1, 0x0, 0xedc12ced, 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, 0x458acf45, 0xf9e910f9, 0x2040602, 0x7ffe817f, 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, 0xcd814ccd, 0xc18140c, 0x13263513, 0xecc32fec, 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, 0xdea779de, 0x5ebce25e, 0xb161d0b, 0xdbad76db, 0xe0db3be0, 0x32645632, 0x3a744e3a, 0xa141e0a, 0x4992db49, 0x60c0a06, 0x24486c24, 0x5cb8e45c, 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x8101808, 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x3060503, 0xf6f701f6, 0xe1c120e, 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, 0x8c038f8c, 0xa159f8a1, 0x89098089, 0xd1a170d, 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, 0x4182c341, 0x9929b099, 0x2d5a772d, 0xf1e110f, 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16]
private let T2_INV:[UInt32] = [0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, 0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303, 0x302055fa, 0x76adf66d, 0xcc889176, 0x2f5254c, 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3, 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, 0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, 0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8, 0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71, 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x8f9942b, 0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, 0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab, 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, 0x2830f287, 0xbf23b2a5, 0x302ba6a, 0x16ed5c82, 0xcf8a2b1c, 0x79a792b4, 0x7f3f0f2, 0x694ea1e2, 0xda65cdf4, 0x506d5be, 0x34d11f62, 0xa6c48afe, 0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, 0x5491b58d, 0xc471055d, 0x6046fd4, 0x5060ff15, 0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee, 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x0, 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, 0xefdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739, 0xf0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, 0xa0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91, 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, 0x90e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, 0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60, 0x1f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, 0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, 0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3, 0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf, 0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, 0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af, 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, 0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a, 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8, 0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, 0x4f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, 0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51, 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0xbfb2e41, 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, 0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, 0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, 0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0xdff4195, 0xa8397101, 0xc08deb3, 0xb4d89ce4, 0x566490c1, 0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257]
private let T3:[UInt32] = [0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x2030101, 0xcea96767, 0x567d2b2b, 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, 0x80c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, 0xa0f0505, 0x2fb59a9a, 0xe090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, 0xa6f55353, 0xb968d1d1, 0x0, 0xc12ceded, 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, 0x8acf4545, 0xe910f9f9, 0x4060202, 0xfe817f7f, 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x58a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a, 0x3bab9090, 0xb838888, 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 0x92db4949, 0xc0a0606, 0x486c2424, 0xb8e45c5c, 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, 0x18c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, 0x96dd4b4b, 0x61dcbdbd, 0xd868b8b, 0xf858a8a, 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x6050303, 0xf701f6f6, 0x1c120e0e, 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, 0xd2bb6969, 0xa970d9d9, 0x7898e8e, 0x33a79494, 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, 0x38f8c8c, 0x59f8a1a1, 0x9808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616]
private let T3_INV:[UInt32] = [0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3, 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, 0x3e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, 0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9, 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9, 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, 0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, 0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55, 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, 0x30f28728, 0x23b2a5bf, 0x2ba6a03, 0xed5c8216, 0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, 0x65cdf4da, 0x6d5be05, 0xd11f6234, 0xc48afea6, 0x349d532e, 0xa2a055f3, 0x532e18a, 0xa475ebf6, 0xb39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, 0x91b58d54, 0x71055dc4, 0x46fd406, 0x60ff1550, 0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, 0xb0bd42e8, 0x7888b89, 0xe7385b19, 0x79dbeec8, 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x0, 0x9838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, 0xfdfbff0e, 0xf563885, 0x3d1ed5ae, 0x3627392d, 0xa64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, 0xcb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b, 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, 0xe0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f, 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, 0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, 0x1d4b2f9e, 0xdcf330b2, 0xdec5286, 0x77d0e3c1, 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad, 0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3, 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, 0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f, 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815, 0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, 0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165, 0x9d04ea5e, 0x15d358c, 0xfa737487, 0xfb2e410b, 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, 0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, 0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d, 0x397101a8, 0x8deb30c, 0xd89ce4b4, 0x6490c156, 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8]
private var U1:[UInt32] = [0x0, 0xb0d090e, 0x161a121c, 0x1d171b12, 0x2c342438, 0x27392d36, 0x3a2e3624, 0x31233f2a, 0x58684870, 0x5365417e, 0x4e725a6c, 0x457f5362, 0x745c6c48, 0x7f516546, 0x62467e54, 0x694b775a, 0xb0d090e0, 0xbbdd99ee, 0xa6ca82fc, 0xadc78bf2, 0x9ce4b4d8, 0x97e9bdd6, 0x8afea6c4, 0x81f3afca, 0xe8b8d890, 0xe3b5d19e, 0xfea2ca8c, 0xf5afc382, 0xc48cfca8, 0xcf81f5a6, 0xd296eeb4, 0xd99be7ba, 0x7bbb3bdb, 0x70b632d5, 0x6da129c7, 0x66ac20c9, 0x578f1fe3, 0x5c8216ed, 0x41950dff, 0x4a9804f1, 0x23d373ab, 0x28de7aa5, 0x35c961b7, 0x3ec468b9, 0xfe75793, 0x4ea5e9d, 0x19fd458f, 0x12f04c81, 0xcb6bab3b, 0xc066a235, 0xdd71b927, 0xd67cb029, 0xe75f8f03, 0xec52860d, 0xf1459d1f, 0xfa489411, 0x9303e34b, 0x980eea45, 0x8519f157, 0x8e14f859, 0xbf37c773, 0xb43ace7d, 0xa92dd56f, 0xa220dc61, 0xf66d76ad, 0xfd607fa3, 0xe07764b1, 0xeb7a6dbf, 0xda595295, 0xd1545b9b, 0xcc434089, 0xc74e4987, 0xae053edd, 0xa50837d3, 0xb81f2cc1, 0xb31225cf, 0x82311ae5, 0x893c13eb, 0x942b08f9, 0x9f2601f7, 0x46bde64d, 0x4db0ef43, 0x50a7f451, 0x5baafd5f, 0x6a89c275, 0x6184cb7b, 0x7c93d069, 0x779ed967, 0x1ed5ae3d, 0x15d8a733, 0x8cfbc21, 0x3c2b52f, 0x32e18a05, 0x39ec830b, 0x24fb9819, 0x2ff69117, 0x8dd64d76, 0x86db4478, 0x9bcc5f6a, 0x90c15664, 0xa1e2694e, 0xaaef6040, 0xb7f87b52, 0xbcf5725c, 0xd5be0506, 0xdeb30c08, 0xc3a4171a, 0xc8a91e14, 0xf98a213e, 0xf2872830, 0xef903322, 0xe49d3a2c, 0x3d06dd96, 0x360bd498, 0x2b1ccf8a, 0x2011c684, 0x1132f9ae, 0x1a3ff0a0, 0x728ebb2, 0xc25e2bc, 0x656e95e6, 0x6e639ce8, 0x737487fa, 0x78798ef4, 0x495ab1de, 0x4257b8d0, 0x5f40a3c2, 0x544daacc, 0xf7daec41, 0xfcd7e54f, 0xe1c0fe5d, 0xeacdf753, 0xdbeec879, 0xd0e3c177, 0xcdf4da65, 0xc6f9d36b, 0xafb2a431, 0xa4bfad3f, 0xb9a8b62d, 0xb2a5bf23, 0x83868009, 0x888b8907, 0x959c9215, 0x9e919b1b, 0x470a7ca1, 0x4c0775af, 0x51106ebd, 0x5a1d67b3, 0x6b3e5899, 0x60335197, 0x7d244a85, 0x7629438b, 0x1f6234d1, 0x146f3ddf, 0x97826cd, 0x2752fc3, 0x335610e9, 0x385b19e7, 0x254c02f5, 0x2e410bfb, 0x8c61d79a, 0x876cde94, 0x9a7bc586, 0x9176cc88, 0xa055f3a2, 0xab58faac, 0xb64fe1be, 0xbd42e8b0, 0xd4099fea, 0xdf0496e4, 0xc2138df6, 0xc91e84f8, 0xf83dbbd2, 0xf330b2dc, 0xee27a9ce, 0xe52aa0c0, 0x3cb1477a, 0x37bc4e74, 0x2aab5566, 0x21a65c68, 0x10856342, 0x1b886a4c, 0x69f715e, 0xd927850, 0x64d90f0a, 0x6fd40604, 0x72c31d16, 0x79ce1418, 0x48ed2b32, 0x43e0223c, 0x5ef7392e, 0x55fa3020, 0x1b79aec, 0xaba93e2, 0x17ad88f0, 0x1ca081fe, 0x2d83bed4, 0x268eb7da, 0x3b99acc8, 0x3094a5c6, 0x59dfd29c, 0x52d2db92, 0x4fc5c080, 0x44c8c98e, 0x75ebf6a4, 0x7ee6ffaa, 0x63f1e4b8, 0x68fcedb6, 0xb1670a0c, 0xba6a0302, 0xa77d1810, 0xac70111e, 0x9d532e34, 0x965e273a, 0x8b493c28, 0x80443526, 0xe90f427c, 0xe2024b72, 0xff155060, 0xf418596e, 0xc53b6644, 0xce366f4a, 0xd3217458, 0xd82c7d56, 0x7a0ca137, 0x7101a839, 0x6c16b32b, 0x671bba25, 0x5638850f, 0x5d358c01, 0x40229713, 0x4b2f9e1d, 0x2264e947, 0x2969e049, 0x347efb5b, 0x3f73f255, 0xe50cd7f, 0x55dc471, 0x184adf63, 0x1347d66d, 0xcadc31d7, 0xc1d138d9, 0xdcc623cb, 0xd7cb2ac5, 0xe6e815ef, 0xede51ce1, 0xf0f207f3, 0xfbff0efd, 0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5, 0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d]
private var U2:[UInt32] = [0x0, 0xd090e0b, 0x1a121c16, 0x171b121d, 0x3424382c, 0x392d3627, 0x2e36243a, 0x233f2a31, 0x68487058, 0x65417e53, 0x725a6c4e, 0x7f536245, 0x5c6c4874, 0x5165467f, 0x467e5462, 0x4b775a69, 0xd090e0b0, 0xdd99eebb, 0xca82fca6, 0xc78bf2ad, 0xe4b4d89c, 0xe9bdd697, 0xfea6c48a, 0xf3afca81, 0xb8d890e8, 0xb5d19ee3, 0xa2ca8cfe, 0xafc382f5, 0x8cfca8c4, 0x81f5a6cf, 0x96eeb4d2, 0x9be7bad9, 0xbb3bdb7b, 0xb632d570, 0xa129c76d, 0xac20c966, 0x8f1fe357, 0x8216ed5c, 0x950dff41, 0x9804f14a, 0xd373ab23, 0xde7aa528, 0xc961b735, 0xc468b93e, 0xe757930f, 0xea5e9d04, 0xfd458f19, 0xf04c8112, 0x6bab3bcb, 0x66a235c0, 0x71b927dd, 0x7cb029d6, 0x5f8f03e7, 0x52860dec, 0x459d1ff1, 0x489411fa, 0x3e34b93, 0xeea4598, 0x19f15785, 0x14f8598e, 0x37c773bf, 0x3ace7db4, 0x2dd56fa9, 0x20dc61a2, 0x6d76adf6, 0x607fa3fd, 0x7764b1e0, 0x7a6dbfeb, 0x595295da, 0x545b9bd1, 0x434089cc, 0x4e4987c7, 0x53eddae, 0x837d3a5, 0x1f2cc1b8, 0x1225cfb3, 0x311ae582, 0x3c13eb89, 0x2b08f994, 0x2601f79f, 0xbde64d46, 0xb0ef434d, 0xa7f45150, 0xaafd5f5b, 0x89c2756a, 0x84cb7b61, 0x93d0697c, 0x9ed96777, 0xd5ae3d1e, 0xd8a73315, 0xcfbc2108, 0xc2b52f03, 0xe18a0532, 0xec830b39, 0xfb981924, 0xf691172f, 0xd64d768d, 0xdb447886, 0xcc5f6a9b, 0xc1566490, 0xe2694ea1, 0xef6040aa, 0xf87b52b7, 0xf5725cbc, 0xbe0506d5, 0xb30c08de, 0xa4171ac3, 0xa91e14c8, 0x8a213ef9, 0x872830f2, 0x903322ef, 0x9d3a2ce4, 0x6dd963d, 0xbd49836, 0x1ccf8a2b, 0x11c68420, 0x32f9ae11, 0x3ff0a01a, 0x28ebb207, 0x25e2bc0c, 0x6e95e665, 0x639ce86e, 0x7487fa73, 0x798ef478, 0x5ab1de49, 0x57b8d042, 0x40a3c25f, 0x4daacc54, 0xdaec41f7, 0xd7e54ffc, 0xc0fe5de1, 0xcdf753ea, 0xeec879db, 0xe3c177d0, 0xf4da65cd, 0xf9d36bc6, 0xb2a431af, 0xbfad3fa4, 0xa8b62db9, 0xa5bf23b2, 0x86800983, 0x8b890788, 0x9c921595, 0x919b1b9e, 0xa7ca147, 0x775af4c, 0x106ebd51, 0x1d67b35a, 0x3e58996b, 0x33519760, 0x244a857d, 0x29438b76, 0x6234d11f, 0x6f3ddf14, 0x7826cd09, 0x752fc302, 0x5610e933, 0x5b19e738, 0x4c02f525, 0x410bfb2e, 0x61d79a8c, 0x6cde9487, 0x7bc5869a, 0x76cc8891, 0x55f3a2a0, 0x58faacab, 0x4fe1beb6, 0x42e8b0bd, 0x99fead4, 0x496e4df, 0x138df6c2, 0x1e84f8c9, 0x3dbbd2f8, 0x30b2dcf3, 0x27a9ceee, 0x2aa0c0e5, 0xb1477a3c, 0xbc4e7437, 0xab55662a, 0xa65c6821, 0x85634210, 0x886a4c1b, 0x9f715e06, 0x9278500d, 0xd90f0a64, 0xd406046f, 0xc31d1672, 0xce141879, 0xed2b3248, 0xe0223c43, 0xf7392e5e, 0xfa302055, 0xb79aec01, 0xba93e20a, 0xad88f017, 0xa081fe1c, 0x83bed42d, 0x8eb7da26, 0x99acc83b, 0x94a5c630, 0xdfd29c59, 0xd2db9252, 0xc5c0804f, 0xc8c98e44, 0xebf6a475, 0xe6ffaa7e, 0xf1e4b863, 0xfcedb668, 0x670a0cb1, 0x6a0302ba, 0x7d1810a7, 0x70111eac, 0x532e349d, 0x5e273a96, 0x493c288b, 0x44352680, 0xf427ce9, 0x24b72e2, 0x155060ff, 0x18596ef4, 0x3b6644c5, 0x366f4ace, 0x217458d3, 0x2c7d56d8, 0xca1377a, 0x1a83971, 0x16b32b6c, 0x1bba2567, 0x38850f56, 0x358c015d, 0x22971340, 0x2f9e1d4b, 0x64e94722, 0x69e04929, 0x7efb5b34, 0x73f2553f, 0x50cd7f0e, 0x5dc47105, 0x4adf6318, 0x47d66d13, 0xdc31d7ca, 0xd138d9c1, 0xc623cbdc, 0xcb2ac5d7, 0xe815efe6, 0xe51ce1ed, 0xf207f3f0, 0xff0efdfb, 0xb479a792, 0xb970a999, 0xae6bbb84, 0xa362b58f, 0x805d9fbe, 0x8d5491b5, 0x9a4f83a8, 0x97468da3]
private var U3:[UInt32] = [0x0, 0x90e0b0d, 0x121c161a, 0x1b121d17, 0x24382c34, 0x2d362739, 0x36243a2e, 0x3f2a3123, 0x48705868, 0x417e5365, 0x5a6c4e72, 0x5362457f, 0x6c48745c, 0x65467f51, 0x7e546246, 0x775a694b, 0x90e0b0d0, 0x99eebbdd, 0x82fca6ca, 0x8bf2adc7, 0xb4d89ce4, 0xbdd697e9, 0xa6c48afe, 0xafca81f3, 0xd890e8b8, 0xd19ee3b5, 0xca8cfea2, 0xc382f5af, 0xfca8c48c, 0xf5a6cf81, 0xeeb4d296, 0xe7bad99b, 0x3bdb7bbb, 0x32d570b6, 0x29c76da1, 0x20c966ac, 0x1fe3578f, 0x16ed5c82, 0xdff4195, 0x4f14a98, 0x73ab23d3, 0x7aa528de, 0x61b735c9, 0x68b93ec4, 0x57930fe7, 0x5e9d04ea, 0x458f19fd, 0x4c8112f0, 0xab3bcb6b, 0xa235c066, 0xb927dd71, 0xb029d67c, 0x8f03e75f, 0x860dec52, 0x9d1ff145, 0x9411fa48, 0xe34b9303, 0xea45980e, 0xf1578519, 0xf8598e14, 0xc773bf37, 0xce7db43a, 0xd56fa92d, 0xdc61a220, 0x76adf66d, 0x7fa3fd60, 0x64b1e077, 0x6dbfeb7a, 0x5295da59, 0x5b9bd154, 0x4089cc43, 0x4987c74e, 0x3eddae05, 0x37d3a508, 0x2cc1b81f, 0x25cfb312, 0x1ae58231, 0x13eb893c, 0x8f9942b, 0x1f79f26, 0xe64d46bd, 0xef434db0, 0xf45150a7, 0xfd5f5baa, 0xc2756a89, 0xcb7b6184, 0xd0697c93, 0xd967779e, 0xae3d1ed5, 0xa73315d8, 0xbc2108cf, 0xb52f03c2, 0x8a0532e1, 0x830b39ec, 0x981924fb, 0x91172ff6, 0x4d768dd6, 0x447886db, 0x5f6a9bcc, 0x566490c1, 0x694ea1e2, 0x6040aaef, 0x7b52b7f8, 0x725cbcf5, 0x506d5be, 0xc08deb3, 0x171ac3a4, 0x1e14c8a9, 0x213ef98a, 0x2830f287, 0x3322ef90, 0x3a2ce49d, 0xdd963d06, 0xd498360b, 0xcf8a2b1c, 0xc6842011, 0xf9ae1132, 0xf0a01a3f, 0xebb20728, 0xe2bc0c25, 0x95e6656e, 0x9ce86e63, 0x87fa7374, 0x8ef47879, 0xb1de495a, 0xb8d04257, 0xa3c25f40, 0xaacc544d, 0xec41f7da, 0xe54ffcd7, 0xfe5de1c0, 0xf753eacd, 0xc879dbee, 0xc177d0e3, 0xda65cdf4, 0xd36bc6f9, 0xa431afb2, 0xad3fa4bf, 0xb62db9a8, 0xbf23b2a5, 0x80098386, 0x8907888b, 0x9215959c, 0x9b1b9e91, 0x7ca1470a, 0x75af4c07, 0x6ebd5110, 0x67b35a1d, 0x58996b3e, 0x51976033, 0x4a857d24, 0x438b7629, 0x34d11f62, 0x3ddf146f, 0x26cd0978, 0x2fc30275, 0x10e93356, 0x19e7385b, 0x2f5254c, 0xbfb2e41, 0xd79a8c61, 0xde94876c, 0xc5869a7b, 0xcc889176, 0xf3a2a055, 0xfaacab58, 0xe1beb64f, 0xe8b0bd42, 0x9fead409, 0x96e4df04, 0x8df6c213, 0x84f8c91e, 0xbbd2f83d, 0xb2dcf330, 0xa9ceee27, 0xa0c0e52a, 0x477a3cb1, 0x4e7437bc, 0x55662aab, 0x5c6821a6, 0x63421085, 0x6a4c1b88, 0x715e069f, 0x78500d92, 0xf0a64d9, 0x6046fd4, 0x1d1672c3, 0x141879ce, 0x2b3248ed, 0x223c43e0, 0x392e5ef7, 0x302055fa, 0x9aec01b7, 0x93e20aba, 0x88f017ad, 0x81fe1ca0, 0xbed42d83, 0xb7da268e, 0xacc83b99, 0xa5c63094, 0xd29c59df, 0xdb9252d2, 0xc0804fc5, 0xc98e44c8, 0xf6a475eb, 0xffaa7ee6, 0xe4b863f1, 0xedb668fc, 0xa0cb167, 0x302ba6a, 0x1810a77d, 0x111eac70, 0x2e349d53, 0x273a965e, 0x3c288b49, 0x35268044, 0x427ce90f, 0x4b72e202, 0x5060ff15, 0x596ef418, 0x6644c53b, 0x6f4ace36, 0x7458d321, 0x7d56d82c, 0xa1377a0c, 0xa8397101, 0xb32b6c16, 0xba25671b, 0x850f5638, 0x8c015d35, 0x97134022, 0x9e1d4b2f, 0xe9472264, 0xe0492969, 0xfb5b347e, 0xf2553f73, 0xcd7f0e50, 0xc471055d, 0xdf63184a, 0xd66d1347, 0x31d7cadc, 0x38d9c1d1, 0x23cbdcc6, 0x2ac5d7cb, 0x15efe6e8, 0x1ce1ede5, 0x7f3f0f2, 0xefdfbff, 0x79a792b4, 0x70a999b9, 0x6bbb84ae, 0x62b58fa3, 0x5d9fbe80, 0x5491b58d, 0x4f83a89a, 0x468da397]
private var U4:[UInt32] = [0x0, 0xe0b0d09, 0x1c161a12, 0x121d171b, 0x382c3424, 0x3627392d, 0x243a2e36, 0x2a31233f, 0x70586848, 0x7e536541, 0x6c4e725a, 0x62457f53, 0x48745c6c, 0x467f5165, 0x5462467e, 0x5a694b77, 0xe0b0d090, 0xeebbdd99, 0xfca6ca82, 0xf2adc78b, 0xd89ce4b4, 0xd697e9bd, 0xc48afea6, 0xca81f3af, 0x90e8b8d8, 0x9ee3b5d1, 0x8cfea2ca, 0x82f5afc3, 0xa8c48cfc, 0xa6cf81f5, 0xb4d296ee, 0xbad99be7, 0xdb7bbb3b, 0xd570b632, 0xc76da129, 0xc966ac20, 0xe3578f1f, 0xed5c8216, 0xff41950d, 0xf14a9804, 0xab23d373, 0xa528de7a, 0xb735c961, 0xb93ec468, 0x930fe757, 0x9d04ea5e, 0x8f19fd45, 0x8112f04c, 0x3bcb6bab, 0x35c066a2, 0x27dd71b9, 0x29d67cb0, 0x3e75f8f, 0xdec5286, 0x1ff1459d, 0x11fa4894, 0x4b9303e3, 0x45980eea, 0x578519f1, 0x598e14f8, 0x73bf37c7, 0x7db43ace, 0x6fa92dd5, 0x61a220dc, 0xadf66d76, 0xa3fd607f, 0xb1e07764, 0xbfeb7a6d, 0x95da5952, 0x9bd1545b, 0x89cc4340, 0x87c74e49, 0xddae053e, 0xd3a50837, 0xc1b81f2c, 0xcfb31225, 0xe582311a, 0xeb893c13, 0xf9942b08, 0xf79f2601, 0x4d46bde6, 0x434db0ef, 0x5150a7f4, 0x5f5baafd, 0x756a89c2, 0x7b6184cb, 0x697c93d0, 0x67779ed9, 0x3d1ed5ae, 0x3315d8a7, 0x2108cfbc, 0x2f03c2b5, 0x532e18a, 0xb39ec83, 0x1924fb98, 0x172ff691, 0x768dd64d, 0x7886db44, 0x6a9bcc5f, 0x6490c156, 0x4ea1e269, 0x40aaef60, 0x52b7f87b, 0x5cbcf572, 0x6d5be05, 0x8deb30c, 0x1ac3a417, 0x14c8a91e, 0x3ef98a21, 0x30f28728, 0x22ef9033, 0x2ce49d3a, 0x963d06dd, 0x98360bd4, 0x8a2b1ccf, 0x842011c6, 0xae1132f9, 0xa01a3ff0, 0xb20728eb, 0xbc0c25e2, 0xe6656e95, 0xe86e639c, 0xfa737487, 0xf478798e, 0xde495ab1, 0xd04257b8, 0xc25f40a3, 0xcc544daa, 0x41f7daec, 0x4ffcd7e5, 0x5de1c0fe, 0x53eacdf7, 0x79dbeec8, 0x77d0e3c1, 0x65cdf4da, 0x6bc6f9d3, 0x31afb2a4, 0x3fa4bfad, 0x2db9a8b6, 0x23b2a5bf, 0x9838680, 0x7888b89, 0x15959c92, 0x1b9e919b, 0xa1470a7c, 0xaf4c0775, 0xbd51106e, 0xb35a1d67, 0x996b3e58, 0x97603351, 0x857d244a, 0x8b762943, 0xd11f6234, 0xdf146f3d, 0xcd097826, 0xc302752f, 0xe9335610, 0xe7385b19, 0xf5254c02, 0xfb2e410b, 0x9a8c61d7, 0x94876cde, 0x869a7bc5, 0x889176cc, 0xa2a055f3, 0xacab58fa, 0xbeb64fe1, 0xb0bd42e8, 0xead4099f, 0xe4df0496, 0xf6c2138d, 0xf8c91e84, 0xd2f83dbb, 0xdcf330b2, 0xceee27a9, 0xc0e52aa0, 0x7a3cb147, 0x7437bc4e, 0x662aab55, 0x6821a65c, 0x42108563, 0x4c1b886a, 0x5e069f71, 0x500d9278, 0xa64d90f, 0x46fd406, 0x1672c31d, 0x1879ce14, 0x3248ed2b, 0x3c43e022, 0x2e5ef739, 0x2055fa30, 0xec01b79a, 0xe20aba93, 0xf017ad88, 0xfe1ca081, 0xd42d83be, 0xda268eb7, 0xc83b99ac, 0xc63094a5, 0x9c59dfd2, 0x9252d2db, 0x804fc5c0, 0x8e44c8c9, 0xa475ebf6, 0xaa7ee6ff, 0xb863f1e4, 0xb668fced, 0xcb1670a, 0x2ba6a03, 0x10a77d18, 0x1eac7011, 0x349d532e, 0x3a965e27, 0x288b493c, 0x26804435, 0x7ce90f42, 0x72e2024b, 0x60ff1550, 0x6ef41859, 0x44c53b66, 0x4ace366f, 0x58d32174, 0x56d82c7d, 0x377a0ca1, 0x397101a8, 0x2b6c16b3, 0x25671bba, 0xf563885, 0x15d358c, 0x13402297, 0x1d4b2f9e, 0x472264e9, 0x492969e0, 0x5b347efb, 0x553f73f2, 0x7f0e50cd, 0x71055dc4, 0x63184adf, 0x6d1347d6, 0xd7cadc31, 0xd9c1d138, 0xcbdcc623, 0xc5d7cb2a, 0xefe6e815, 0xe1ede51c, 0xf3f0f207, 0xfdfbff0e, 0xa792b479, 0xa999b970, 0xbb84ae6b, 0xb58fa362, 0x9fbe805d, 0x91b58d54, 0x83a89a4f, 0x8da39746]
public init(key:[UInt8], iv:[UInt8], blockMode:CipherBlockMode = .CBC) throws {
self.key = key
self.iv = iv
self.blockMode = blockMode
if (blockMode.needIV && iv.count != AES.blockSize) {
assert(false, "Block size and Initialization Vector must be the same length!")
return nil
throw Error.InvalidInitializationVector
}
}
convenience public init?(key:[UInt8], blockMode:CipherBlockMode = .CBC) {
convenience public init(key:[UInt8], blockMode:CipherBlockMode = .CBC) throws {
// default IV is all 0x00...
let defaultIV = [UInt8](count: AES.blockSize, repeatedValue: 0)
self.init(key: key, iv: defaultIV, blockMode: blockMode)
try self.init(key: key, iv: defaultIV, blockMode: blockMode)
}
convenience public init?(key:String, iv:String, blockMode:CipherBlockMode = .CBC) {
if let kkey = key.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.arrayOfBytes(), let iiv = iv.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.arrayOfBytes() {
self.init(key: kkey, iv: iiv, blockMode: blockMode)
}
else {
return nil
}
}
/**
Encrypt message. If padding is necessary, then PKCS7 padding is added and needs to be removed after decryption.
@ -155,42 +120,52 @@ final public class AES {
throw Error.BlockSizeExceeded
}
let blocks = finalBytes.chunks(AES.blockSize) // 0.34
let blocks = finalBytes.chunks(AES.blockSize)
return try blockMode.encryptBlocks(blocks, iv: self.iv, cipherOperation: encryptBlock)
}
private func encryptBlock(block:[UInt8]) -> [UInt8]? {
var out:[UInt8] = [UInt8]()
let rounds = self.variant.Nr
let rk = self.expandedKey
var b = toUInt32Array(block[block.startIndex..<block.endIndex])
var t = [UInt32](count: 4, repeatedValue: 0)
autoreleasepool { () -> () in
var state:[[UInt8]] = [[UInt8]](count: variant.Nb, repeatedValue: [UInt8](count: variant.Nb, repeatedValue: 0))
for (i, row) in state.enumerate() {
for (j, _) in row.enumerate() {
state[j][i] = block[i * row.count + j]
}
}
for r in 0..<rounds - 1 {
t[0] = b[0] ^ rk[r][0]
t[1] = b[1] ^ rk[r][1]
t[2] = b[2] ^ rk[r][2]
t[3] = b[3] ^ rk[r][3]
state = addRoundKey(state,expandedKey, 0)
for roundCount in 1..<variant.Nr {
subBytes(&state)
state = shiftRows(state)
state = mixColumns(state)
state = addRoundKey(state, expandedKey, roundCount)
}
subBytes(&state)
state = shiftRows(state)
state = addRoundKey(state, expandedKey, variant.Nr)
out = [UInt8](count: state.count * state.first!.count, repeatedValue: 0)
for i in 0..<state.count {
for j in 0..<state[i].count {
out[(i * 4) + j] = state[j][i]
}
}
b[0] = T0[Int(t[0] & 0xFF)] ^ T1[Int((t[1] >> 8) & 0xFF)] ^ T2[Int((t[2] >> 16) & 0xFF)] ^ T3[Int(t[3] >> 24)]
b[1] = T0[Int(t[1] & 0xFF)] ^ T1[Int((t[2] >> 8) & 0xFF)] ^ T2[Int((t[3] >> 16) & 0xFF)] ^ T3[Int(t[0] >> 24)]
b[2] = T0[Int(t[2] & 0xFF)] ^ T1[Int((t[3] >> 8) & 0xFF)] ^ T2[Int((t[0] >> 16) & 0xFF)] ^ T3[Int(t[1] >> 24)]
b[3] = T0[Int(t[3] & 0xFF)] ^ T1[Int((t[0] >> 8) & 0xFF)] ^ T2[Int((t[1] >> 16) & 0xFF)] ^ T3[Int(t[2] >> 24)]
}
// last round
let r = rounds - 1
t[0] = b[0] ^ rk[r][0]
t[1] = b[1] ^ rk[r][1]
t[2] = b[2] ^ rk[r][2]
t[3] = b[3] ^ rk[r][3]
// rounds
b[0] = F1(t[0], t[1], t[2], t[3]) ^ rk[rounds][0]
b[1] = F1(t[1], t[2], t[3], t[0]) ^ rk[rounds][1]
b[2] = F1(t[2], t[3], t[0], t[1]) ^ rk[rounds][2]
b[3] = F1(t[3], t[0], t[1], t[2]) ^ rk[rounds][3]
var out = [UInt8]()
out.reserveCapacity(b.count * 4)
for num in b {
out.append(UInt8(num & 0xFF))
out.append(UInt8((num >> 8) & 0xFF))
out.append(UInt8((num >> 16) & 0xFF))
out.append(UInt8((num >> 24) & 0xFF))
}
return out
}
@ -217,37 +192,87 @@ final public class AES {
}
private func decryptBlock(block:[UInt8]) -> [UInt8]? {
var state:[[UInt8]] = [[UInt8]](count: variant.Nb, repeatedValue: [UInt8](count: variant.Nb, repeatedValue: 0))
for (i, row) in state.enumerate() {
for (j, _) in row.enumerate() {
state[j][i] = block[i * row.count + j]
}
let rounds = self.variant.Nr
let rk = expandedKeyInv
var b = toUInt32Array(block[block.startIndex..<block.endIndex])
var t = [UInt32](count: 4, repeatedValue: 0)
for r in (2...rounds).reverse() {
t[0] = b[0] ^ rk[r][0]
t[1] = b[1] ^ rk[r][1]
t[2] = b[2] ^ rk[r][2]
t[3] = b[3] ^ rk[r][3]
b[0] = T0_INV[Int(t[0] & 0xFF)] ^ T1_INV[Int((t[3] >> 8) & 0xFF)] ^ T2_INV[Int((t[2] >> 16) & 0xFF)] ^ T3_INV[Int(t[1] >> 24)]
b[1] = T0_INV[Int(t[1] & 0xFF)] ^ T1_INV[Int((t[0] >> 8) & 0xFF)] ^ T2_INV[Int((t[3] >> 16) & 0xFF)] ^ T3_INV[Int(t[2] >> 24)]
b[2] = T0_INV[Int(t[2] & 0xFF)] ^ T1_INV[Int((t[1] >> 8) & 0xFF)] ^ T2_INV[Int((t[0] >> 16) & 0xFF)] ^ T3_INV[Int(t[3] >> 24)]
b[3] = T0_INV[Int(t[3] & 0xFF)] ^ T1_INV[Int((t[2] >> 8) & 0xFF)] ^ T2_INV[Int((t[1] >> 16) & 0xFF)] ^ T3_INV[Int(t[0] >> 24)]
}
state = addRoundKey(state,expandedKey, variant.Nr)
// last round
t[0] = b[0] ^ rk[1][0]
t[1] = b[1] ^ rk[1][1]
t[2] = b[2] ^ rk[1][2]
t[3] = b[3] ^ rk[1][3]
for roundCount in (1..<variant.Nr).reverse() {
state = invShiftRows(state)
state = invSubBytes(state)
state = addRoundKey(state, expandedKey, roundCount)
state = invMixColumns(state)
}
// rounds
b[0] = sBoxInv[Int(B0(t[0]))] | (sBoxInv[Int(B1(t[3]))] << 8) | (sBoxInv[Int(B2(t[2]))] << 16) | (sBoxInv[Int(B3(t[1]))] << 24) ^ rk[0][0]
b[1] = sBoxInv[Int(B0(t[1]))] | (sBoxInv[Int(B1(t[0]))] << 8) | (sBoxInv[Int(B2(t[3]))] << 16) | (sBoxInv[Int(B3(t[2]))] << 24) ^ rk[0][1]
b[2] = sBoxInv[Int(B0(t[2]))] | (sBoxInv[Int(B1(t[1]))] << 8) | (sBoxInv[Int(B2(t[0]))] << 16) | (sBoxInv[Int(B3(t[3]))] << 24) ^ rk[0][2]
b[3] = sBoxInv[Int(B0(t[3]))] | (sBoxInv[Int(B1(t[2]))] << 8) | (sBoxInv[Int(B2(t[1]))] << 16) | (sBoxInv[Int(B3(t[0]))] << 24) ^ rk[0][3]
state = invShiftRows(state)
state = invSubBytes(state)
state = addRoundKey(state, expandedKey, 0)
var out:[UInt8] = [UInt8]()
for i in 0..<state.count {
for j in 0..<state[0].count {
out.append(state[j][i])
}
var out = [UInt8]()
out.reserveCapacity(b.count * 4)
for num in b {
out.append(UInt8(num & 0xFF))
out.append(UInt8((num >> 8) & 0xFF))
out.append(UInt8((num >> 16) & 0xFF))
out.append(UInt8((num >> 24) & 0xFF))
}
return out
}
static private func expandKey(key:[UInt8], variant:AESVariant) -> [UInt8] {
private func expandKeyInv(key:[UInt8], variant:AESVariant) -> [[UInt32]] {
let rounds = variant.Nr
var rk2:[[UInt32]] = expandKey(key, variant: variant)
for r in 1..<rounds {
var w:UInt32
w = rk2[r][0];
rk2[r][0] = U1[Int(B0(w))] ^ U2[Int(B1(w))] ^ U3[Int(B2(w))] ^ U4[Int(B3(w))]
w = rk2[r][1];
rk2[r][1] = U1[Int(B0(w))] ^ U2[Int(B1(w))] ^ U3[Int(B2(w))] ^ U4[Int(B3(w))]
w = rk2[r][2];
rk2[r][2] = U1[Int(B0(w))] ^ U2[Int(B1(w))] ^ U3[Int(B2(w))] ^ U4[Int(B3(w))]
w = rk2[r][3];
rk2[r][3] = U1[Int(B0(w))] ^ U2[Int(B1(w))] ^ U3[Int(B2(w))] ^ U4[Int(B3(w))]
}
return rk2
}
private func expandKey(key:[UInt8], variant:AESVariant) -> [[UInt32]] {
func convertExpandedKey(expanded:[UInt8]) -> [[UInt32]] {
var arr = [UInt32]()
for idx in expanded.startIndex.stride(to: expanded.endIndex, by: 4) {
let four = Array(expanded[idx..<idx.advancedBy(4)].reverse())
let num = UInt32.withBytes(four)
arr.append(num)
}
var allarr = [[UInt32]]()
for idx in arr.startIndex.stride(to: arr.endIndex, by: 4) {
allarr.append(Array(arr[idx..<idx.advancedBy(4)]))
}
return allarr
}
/*
* Function used in the Key Expansion routine that takes a four-byte
@ -257,7 +282,7 @@ final public class AES {
func subWord(word:[UInt8]) -> [UInt8] {
var result = word
for i in 0..<4 {
result[i] = self.sBox[Int(word[i])]
result[i] = UInt8(sBox[Int(word[i])])
}
return result
}
@ -277,9 +302,8 @@ final public class AES {
tmp[wordIdx] = w[4*(i-1)+wordIdx]
}
if ((i % variant.Nk) == 0) {
let rotWord = rotateLeft(UInt32.withBytes(tmp), n: 8).bytes(sizeof(UInt32)) // RotWord
tmp = subWord(rotWord)
tmp[0] = tmp[0] ^ Rcon[i/variant.Nk]
tmp = subWord(rotateLeft(UInt32.withBytes(tmp), 8).bytes(sizeof(UInt32)))
tmp[0] = tmp.first! ^ Rcon[i/variant.Nk]
} else if (variant.Nk > 6 && (i % variant.Nk) == 4) {
tmp = subWord(tmp)
}
@ -289,145 +313,69 @@ final public class AES {
w[4*i+wordIdx] = w[4*(i-variant.Nk)+wordIdx]^tmp[wordIdx];
}
}
return w;
return convertExpandedKey(w)
}
}
extension AES {
// byte substitution with table (S-box)
public func subBytes(inout state:[[UInt8]]) {
for (i,row) in state.enumerate() {
for (j,value) in row.enumerate() {
state[i][j] = AES.sBox[Int(value)]
}
}
private func B0(x: UInt32) -> UInt32 {
return x & 0xFF
}
public func invSubBytes(state:[[UInt8]]) -> [[UInt8]] {
var result = state
for (i,row) in state.enumerate() {
for (j,value) in row.enumerate() {
result[i][j] = AES.invSBox[Int(value)]
}
}
private func B1(x: UInt32) -> UInt32 {
return (x >> 8) & 0xFF
}
private func B2(x: UInt32) -> UInt32 {
return (x >> 16) & 0xFF
}
private func B3(x: UInt32) -> UInt32 {
return (x >> 24) & 0xFF
}
private func F1(x0: UInt32, _ x1: UInt32, _ x2: UInt32, _ x3: UInt32) -> UInt32 {
var result:UInt32 = 0
result |= UInt32(B1(T0[Int(x0 & 255)]))
result |= UInt32(B1(T0[Int((x1 >> 8) & 255)])) << 8
result |= UInt32(B1(T0[Int((x2 >> 16) & 255)])) << 16
result |= UInt32(B1(T0[Int(x3 >> 24)])) << 24
return result
}
// Applies a cyclic shift to the last 3 rows of a state matrix.
public func shiftRows(state:[[UInt8]]) -> [[UInt8]] {
var result = state
for r in 1..<4 {
for c in 0..<variant.Nb {
result[r][c] = state[r][(c + r) % variant.Nb]
}
}
return result
private func calculateSBox() -> (sBox:[UInt32], invSBox:[UInt32]) {
var sbox = [UInt32](count: 256, repeatedValue: 0)
var invsbox = sbox
sbox[0] = 0x63
var p:UInt8 = 1, q:UInt8 = 1
repeat {
p = p ^ (UInt8(truncatingBitPattern: Int(p) << 1) ^ ((p & 0x80) == 0x80 ? 0x1B : 0))
q ^= q << 1
q ^= q << 2
q ^= q << 4
q ^= (q & 0x80) == 0x80 ? 0x09 : 0
let s = 0x63 ^ q ^ rotateLeft(q, 1) ^ rotateLeft(q, 2) ^ rotateLeft(q, 3) ^ rotateLeft(q, 4)
sbox[Int(p)] = UInt32(s)
invsbox[Int(s)] = UInt32(p)
} while (p != 1)
return (sBox: sbox, invSBox: invsbox)
}
}
extension AES: Cipher {
// MARK: - Cipher
public func cipherEncrypt(bytes:[UInt8]) throws -> [UInt8] {
return try self.encrypt(bytes)
}
public func invShiftRows(state:[[UInt8]]) -> [[UInt8]] {
var result = state
for r in 1..<4 {
for c in 0..<variant.Nb {
result[r][(c + r) % variant.Nb] = state[r][c]
}
}
return result
}
// Multiplies two polynomials
public func multiplyPolys(a:UInt8, _ b:UInt8) -> UInt8 {
var a = a, b = b
var p:UInt8 = 0, hbs:UInt8 = 0
for _ in 0..<8 {
if (b & 1 == 1) {
p ^= a
}
hbs = a & 0x80
a <<= 1
if (hbs > 0) {
a ^= 0x1B
}
b >>= 1
}
return p
}
public func matrixMultiplyPolys(matrix:[[UInt8]], _ array:[UInt8]) -> [UInt8] {
var returnArray:[UInt8] = [UInt8](count: array.count, repeatedValue: 0)
for (i, row) in matrix.enumerate() {
for (j, boxVal) in row.enumerate() {
returnArray[i] = multiplyPolys(boxVal, array[j]) ^ returnArray[i]
}
}
return returnArray
}
public func addRoundKey(state:[[UInt8]], _ expandedKeyW:[UInt8], _ round:Int) -> [[UInt8]] {
var newState = [[UInt8]](count: state.count, repeatedValue: [UInt8](count: variant.Nb, repeatedValue: 0))
let idxRow = 4*variant.Nb*round
for c in 0..<variant.Nb {
let idxCol = variant.Nb*c
newState[0][c] = state[0][c] ^ expandedKeyW[idxRow+idxCol+0]
newState[1][c] = state[1][c] ^ expandedKeyW[idxRow+idxCol+1]
newState[2][c] = state[2][c] ^ expandedKeyW[idxRow+idxCol+2]
newState[3][c] = state[3][c] ^ expandedKeyW[idxRow+idxCol+3]
}
return newState
}
// mixes data (independently of one another)
public func mixColumns(state:[[UInt8]]) -> [[UInt8]] {
var state = state
let colBox:[[UInt8]] = [[2,3,1,1],[1,2,3,1],[1,1,2,3],[3,1,1,2]]
var rowMajorState = [[UInt8]](count: state.count, repeatedValue: [UInt8](count: state.first!.count, repeatedValue: 0)) //state.map({ val -> [UInt8] in return val.map { _ in return 0 } }) // zeroing
var newRowMajorState = rowMajorState
for i in 0..<state.count {
for j in 0..<state[0].count {
rowMajorState[j][i] = state[i][j]
}
}
for (i, row) in rowMajorState.enumerate() {
newRowMajorState[i] = matrixMultiplyPolys(colBox, row)
}
for i in 0..<state.count {
for j in 0..<state[0].count {
state[i][j] = newRowMajorState[j][i]
}
}
return state
}
public func invMixColumns(state:[[UInt8]]) -> [[UInt8]] {
var state = state
let invColBox:[[UInt8]] = [[14,11,13,9],[9,14,11,13],[13,9,14,11],[11,13,9,14]]
var colOrderState = state.map({ val -> [UInt8] in return val.map { _ in return 0 } }) // zeroing
for i in 0..<state.count {
for j in 0..<state[0].count {
colOrderState[j][i] = state[i][j]
}
}
var newState = state.map({ val -> [UInt8] in return val.map { _ in return 0 } })
for (i, row) in colOrderState.enumerate() {
newState[i] = matrixMultiplyPolys(invColBox, row)
}
for i in 0..<state.count {
for j in 0..<state[0].count {
state[i][j] = newState[j][i]
}
}
return state
public func cipherDecrypt(bytes: [UInt8]) throws -> [UInt8] {
return try self.decrypt(bytes)
}
}

View File

@ -1,27 +0,0 @@
//
// ArrayExtension.swift
// CryptoSwift
//
// Created by Marcin Krzyzanowski on 10/08/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
extension Array {
/** split in chunks with given chunk size */
func chunks(chunksize:Int) -> [Array<Element>] {
var words = [[Element]]()
words.reserveCapacity(self.count / chunksize)
for var idx = chunksize; idx <= self.count; idx = idx + chunksize {
let word = Array(self[idx - chunksize..<idx]) // this is slow for large table
words.append(word)
}
let reminder = Array(self.suffix(self.count % chunksize))
if (reminder.count > 0) {
words.append(reminder)
}
return words
}
}

View File

@ -6,12 +6,15 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
/**
* Message Authentication
*/
public enum Authenticator {
public enum Error: ErrorType {
case AuthenticateError
}
/**
Poly1305
@ -25,12 +28,18 @@ public enum Authenticator {
- returns: 16-byte message authentication code
*/
public func authenticate(message: [UInt8]) -> [UInt8]? {
public func authenticate(message: [UInt8]) throws -> [UInt8] {
switch (self) {
case .Poly1305(let key):
return CryptoSwift.Poly1305.authenticate(key: key, message: message)
guard let auth = CryptoSwift.Poly1305.authenticate(key: key, message: message) else {
throw Error.AuthenticateError
}
return auth
case .HMAC(let key, let variant):
return CryptoSwift.HMAC.authenticate(key: key, message: message, variant: variant)
guard let auth = CryptoSwift.HMAC.authenticate(key: key, message: message, variant: variant) else {
throw Error.AuthenticateError
}
return auth
}
}
}

View File

@ -6,10 +6,7 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
extension Bit {
func inverted() -> Bit {
if (self == Bit.Zero) {
return Bit.One
@ -17,8 +14,4 @@ extension Bit {
return Bit.Zero
}
mutating func invert() {
self = self.inverted()
}
}

View File

@ -6,11 +6,9 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
final class CRC {
private let table:[UInt32] = [0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
private static let table32:[UInt32] = [0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
@ -43,22 +41,58 @@ final class CRC {
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d]
func crc32(message:NSData) -> NSData {
private static let table16:[UInt16] = [0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040]
func crc32(message:[UInt8]) -> UInt32 {
var crc:UInt32 = 0xffffffff
for chunk in NSDataSequence(chunkSize: 256, data: message) {
for b in chunk.arrayOfBytes() {
for chunk in BytesSequence(chunkSize: 256, data: message) {
for b in chunk {
let idx = Int((crc ^ UInt32(b)) & 0xff)
crc = (crc >> 8) ^ table[idx]
crc = (crc >> 8) ^ CRC.table32[idx]
}
}
crc = crc ^ 0xffffffff
// reverse bytes
let bytes = Array(NSMutableData(bytes: &crc, length: 4).arrayOfBytes().reverse()) //FIXME: Array ??
let data = NSData(bytes: bytes, length: bytes.count)
return data
return crc ^ 0xffffffff
}
func crc16(message:[UInt8]) -> UInt16 {
var crc:UInt16 = 0x0000
for chunk in BytesSequence(chunkSize: 256, data: message) {
for b in chunk {
crc = (crc >> 8) ^ CRC.table16[Int((crc ^ UInt16(b)) & 0xFF)]
}
}
return crc
}
}

View File

@ -6,8 +6,6 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
final public class ChaCha20 {
enum Error: ErrorType {
@ -36,14 +34,6 @@ final public class ChaCha20 {
}
}
convenience public init?(key:String, iv:String) {
if let kkey = key.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.arrayOfBytes(), let iiv = iv.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.arrayOfBytes() {
self.init(key: kkey, iv: iiv)
}
return nil
}
public func encrypt(bytes:[UInt8]) throws -> [UInt8] {
guard context != nil else {
throw Error.MissingContext
@ -176,16 +166,28 @@ final public class ChaCha20 {
private final func quarterround(inout a:UInt32, inout _ b:UInt32, inout _ c:UInt32, inout _ d:UInt32) {
a = a &+ b
d = rotateLeft((d ^ a), n: 16) //FIXME: WAT? n:
d = rotateLeft((d ^ a), 16) //FIXME: WAT? n:
c = c &+ d
b = rotateLeft((b ^ c), n: 12);
b = rotateLeft((b ^ c), 12);
a = a &+ b
d = rotateLeft((d ^ a), n: 8);
d = rotateLeft((d ^ a), 8);
c = c &+ d
b = rotateLeft((b ^ c), n: 7);
b = rotateLeft((b ^ c), 7);
}
}
// MARK: - Cipher
extension ChaCha20: Cipher {
public func cipherEncrypt(bytes:[UInt8]) throws -> [UInt8] {
return try self.encrypt(bytes)
}
public func cipherDecrypt(bytes: [UInt8]) throws -> [UInt8] {
return try self.decrypt(bytes)
}
}

View File

@ -6,79 +6,21 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
import Darwin
public enum Cipher {
public enum Error: ErrorType {
case EncryptError
case DecryptError
}
/**
ChaCha20
- parameter key: Encryption key
- parameter iv: Initialization Vector
- returns: Value of Cipher
*/
case ChaCha20(key: [UInt8], iv: [UInt8])
/**
AES
- parameter key: Encryption key
- parameter iv: Initialization Vector
- parameter blockMode: Block mode (CBC by default)
- returns: Value of Cipher
*/
case AES(key: [UInt8], iv: [UInt8], blockMode: CipherBlockMode)
/**
Encrypt message
- parameter message: Plaintext message
- returns: encrypted message
*/
public func encrypt(bytes: [UInt8]) throws -> [UInt8] {
switch (self) {
case .ChaCha20(let key, let iv):
guard let chacha = CryptoSwift.ChaCha20(key: key, iv: iv) else {
throw Error.EncryptError
}
return try chacha.encrypt(bytes)
case .AES(let key, let iv, let blockMode):
guard let aes = CryptoSwift.AES(key: key, iv: iv, blockMode: blockMode) else {
throw Error.EncryptError
}
return try aes.encrypt(bytes)
}
}
/**
Decrypt message
- parameter message: Message data
- returns: Plaintext message
*/
public func decrypt(bytes: [UInt8]) throws -> [UInt8] {
switch (self) {
case .ChaCha20(let key, let iv):
guard let chacha = CryptoSwift.ChaCha20(key: key, iv: iv) else {
throw Error.DecryptError
}
return try chacha.decrypt(bytes)
case .AES(let key, let iv, let blockMode):
guard let aes = CryptoSwift.AES(key: key, iv: iv, blockMode: blockMode) else {
throw Error.DecryptError
}
return try aes.decrypt(bytes)
}
}
public enum CipherError: ErrorType {
case Encrypt
case Decrypt
}
public protocol Cipher {
func cipherEncrypt(bytes: [UInt8]) throws -> [UInt8]
func cipherDecrypt(bytes: [UInt8]) throws -> [UInt8]
static func randomIV(blockSize:Int) -> [UInt8]
}
extension Cipher {
static public func randomIV(blockSize:Int) -> [UInt8] {
var randomIV:[UInt8] = [UInt8]();
for (var i = 0; i < blockSize; i++) {

View File

@ -6,8 +6,6 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
// I have no better name for that
typealias CipherOperationOnBlock = (block: [UInt8]) -> [UInt8]?
@ -85,7 +83,7 @@ private struct CBCMode: BlockMode {
}
var out:[UInt8] = [UInt8]()
out.reserveCapacity(blocks.count * blocks[0].count)
out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
var prevCiphertext = iv // for the first time prevCiphertext = iv
for plaintext in blocks {
if let encrypted = cipherOperation(block: xor(prevCiphertext, b: plaintext)) {
@ -103,7 +101,7 @@ private struct CBCMode: BlockMode {
}
var out:[UInt8] = [UInt8]()
out.reserveCapacity(blocks.count * blocks[0].count)
out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
var prevCiphertext = iv // for the first time prevCiphertext = iv
for ciphertext in blocks {
if let decrypted = cipherOperation(block: ciphertext) { // decrypt
@ -128,12 +126,12 @@ private struct CFBMode: BlockMode {
}
var out:[UInt8] = [UInt8]()
out.reserveCapacity(blocks.count * blocks[0].count)
out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
var lastCiphertext = iv
for plaintext in blocks {
if let encrypted = cipherOperation(block: lastCiphertext) {
lastCiphertext = xor(plaintext,b: encrypted)
if let ciphertext = cipherOperation(block: lastCiphertext) {
lastCiphertext = xor(plaintext,b: ciphertext)
out.appendContentsOf(lastCiphertext)
}
}
@ -141,7 +139,22 @@ private struct CFBMode: BlockMode {
}
func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] {
return try encryptBlocks(blocks, iv: iv, cipherOperation: cipherOperation)
guard let iv = iv else {
throw BlockError.MissingInitializationVector
}
var out:[UInt8] = [UInt8]()
out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
var lastCiphertext = iv
for ciphertext in blocks {
if let decrypted = cipherOperation(block: lastCiphertext) {
out.appendContentsOf(xor(decrypted, b: ciphertext))
}
lastCiphertext = ciphertext
}
return out
}
}
@ -154,7 +167,7 @@ private struct ECBMode: BlockMode {
func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8] {
var out:[UInt8] = [UInt8]()
out.reserveCapacity(blocks.count * blocks[0].count)
out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
for plaintext in blocks {
if let encrypted = cipherOperation(block: plaintext) {
out.appendContentsOf(encrypted)
@ -193,7 +206,7 @@ private struct CTRMode: BlockMode {
var counter:UInt = 0
var out:[UInt8] = [UInt8]()
out.reserveCapacity(blocks.count * blocks[0].count)
out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
for plaintext in blocks {
let nonce = buildNonce(iv, counter: counter++)
if let encrypted = cipherOperation(block: nonce) {
@ -210,7 +223,7 @@ private struct CTRMode: BlockMode {
var counter:UInt = 0
var out:[UInt8] = [UInt8]()
out.reserveCapacity(blocks.count * blocks[0].count)
out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
for plaintext in blocks {
let nonce = buildNonce(iv, counter: counter++)
if let encrypted = cipherOperation(block: nonce) {

View File

@ -1,19 +0,0 @@
//
// CryptoSwift.h
// CryptoSwift
//
// Created by Marcin Krzyzanowski on 06/07/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
#import <Foundation/Foundation.h>
//! Project version number for CryptoSwift.
FOUNDATION_EXPORT double CryptoSwiftVersionNumber;
//! Project version string for CryptoSwift.
FOUNDATION_EXPORT const unsigned char CryptoSwiftVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <CryptoSwift/PublicHeader.h>

View File

@ -6,8 +6,6 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
/** Protocol and extensions for integerFromBitsArray. Bit hakish for me, but I can't do it in any other way */
protocol Initiable {
init(_ v: Int)
@ -46,11 +44,11 @@ func integerWithBytes<T: IntegerType where T:ByteConvertible, T: BitshiftOperati
}
if sizeof(T) == 1 {
return T(truncatingBitPattern: UInt64(bytes[0]))
return T(truncatingBitPattern: UInt64(bytes.first!))
}
var result: T = 0
for byte in Array(bytes.reverse()) { //FIXME: Array??
for byte in bytes.reverse() {
result = result << 8 | T(byte)
}
return result

View File

@ -6,8 +6,6 @@
// Copyright (c) 2015 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
final public class HMAC {
public enum Variant {
@ -16,7 +14,7 @@ final public class HMAC {
var size:Int {
switch (self) {
case .sha1:
return SHA1(NSData()).size
return SHA1.size
case .sha256:
return SHA2.Variant.sha256.size
case .sha384:
@ -24,22 +22,22 @@ final public class HMAC {
case .sha512:
return SHA2.Variant.sha512.size
case .md5:
return MD5(NSData()).size
return MD5.size
}
}
func calculateHash(bytes bytes:[UInt8]) -> [UInt8]? {
func calculateHash(bytes bytes:[UInt8]) -> [UInt8]? {
switch (self) {
case .sha1:
return NSData.withBytes(bytes).sha1()?.arrayOfBytes()
return Hash.sha1(bytes).calculate()
case .sha256:
return NSData.withBytes(bytes).sha256()?.arrayOfBytes()
return Hash.sha256(bytes).calculate()
case .sha384:
return NSData.withBytes(bytes).sha384()?.arrayOfBytes()
return Hash.sha384(bytes).calculate()
case .sha512:
return NSData.withBytes(bytes).sha512()?.arrayOfBytes()
return Hash.sha512(bytes).calculate()
case .md5:
return NSData.withBytes(bytes).md5()?.arrayOfBytes();
return Hash.md5(bytes).calculate()
}
}

View File

@ -6,30 +6,31 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
public enum Hash {
case md5(NSData)
case sha1(NSData)
case sha224(NSData), sha256(NSData), sha384(NSData), sha512(NSData)
case crc32(NSData)
case md5(Array<UInt8>)
case sha1(Array<UInt8>)
case sha224(Array<UInt8>), sha256(Array<UInt8>), sha384(Array<UInt8>), sha512(Array<UInt8>)
case crc32(Array<UInt8>)
case crc16(Array<UInt8>)
public func calculate() -> NSData? {
public func calculate() -> [UInt8] {
switch self {
case md5(let data):
return MD5(data).calculate()
case sha1(let data):
return SHA1(data).calculate()
case sha224(let data):
return SHA2(data, variant: .sha224).calculate32()
case sha256(let data):
return SHA2(data, variant: .sha256).calculate32()
case sha384(let data):
return SHA2(data, variant: .sha384).calculate64()
case sha512(let data):
return SHA2(data, variant: .sha512).calculate64()
case crc32(let data):
return CRC().crc32(data);
case md5(let bytes):
return MD5(bytes).calculate()
case sha1(let bytes):
return SHA1(bytes).calculate()
case sha224(let bytes):
return SHA2(bytes, variant: .sha224).calculate32()
case sha256(let bytes):
return SHA2(bytes, variant: .sha256).calculate32()
case sha384(let bytes):
return SHA2(bytes, variant: .sha384).calculate64()
case sha512(let bytes):
return SHA2(bytes, variant: .sha512).calculate64()
case crc32(let bytes):
return CRC().crc32(bytes).bytes()
case crc16(let bytes):
return UInt32(CRC().crc16(bytes)).bytes(2)
}
}
}

View File

@ -6,39 +6,31 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
internal protocol HashProtocol {
var message: NSData { get }
var message: Array<UInt8> { get }
/** Common part for hash calculation. Prepare header data. */
func prepare(len:Int) -> NSMutableData
func prepare(len:Int) -> Array<UInt8>
}
extension HashProtocol {
func prepare(len:Int) -> NSMutableData {
let tmpMessage: NSMutableData = NSMutableData(data: self.message)
func prepare(len:Int) -> Array<UInt8> {
var tmpMessage = message
// Step 1. Append Padding Bits
tmpMessage.appendBytes([0x80]) // append one bit (UInt8 with one bit) to message
tmpMessage.append(0x80) // append one bit (UInt8 with one bit) to message
// append "0" bit until message length in bits 448 (mod 512)
var msgLength = tmpMessage.length
var msgLength = tmpMessage.count
var counter = 0
while msgLength % len != (len - 8) {
counter++
msgLength++
}
let bufZeros = UnsafeMutablePointer<UInt8>(calloc(counter, sizeof(UInt8)))
tmpMessage.appendBytes(bufZeros, length: counter)
bufZeros.destroy()
bufZeros.dealloc(1)
tmpMessage += Array<UInt8>(count: counter, repeatedValue: 0)
return tmpMessage
}
}

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.0.16</string>
<string>0.1.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@ -14,7 +14,7 @@
// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
// - This notice may not be removed or altered from any source or binary distribution.
import Foundation
import Darwin
/* array of bits */
extension Int {

View File

@ -6,8 +6,6 @@
// Copyright (c) 2015 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
protocol BitshiftOperationsType {
func <<(lhs: Self, rhs: Self) -> Self
func >>(lhs: Self, rhs: Self) -> Self

View File

@ -6,13 +6,11 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
final class MD5 : HashProtocol {
var size:Int = 16 // 128 / 8
let message: NSData
static let size:Int = 16 // 128 / 8
let message: Array<UInt8>
init (_ message: NSData) {
init (_ message: Array<UInt8>) {
self.message = message
}
@ -42,24 +40,24 @@ final class MD5 : HashProtocol {
private let h:[UInt32] = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]
func calculate() -> NSData {
let tmpMessage = prepare(64)
func calculate() -> [UInt8] {
var tmpMessage = prepare(64)
tmpMessage.reserveCapacity(tmpMessage.count + 4)
// hash values
// initialize hh with hash values
var hh = h
// Step 2. Append Length a 64-bit representation of lengthInBits
let lengthInBits = (message.length * 8)
let lengthInBits = (message.count * 8)
let lengthBytes = lengthInBits.bytes(64 / 8)
tmpMessage.appendBytes(Array(lengthBytes.reverse())); //FIXME: Array?
tmpMessage += lengthBytes.reverse()
// Process the message in successive 512-bit chunks:
let chunkSizeBytes = 512 / 8 // 64
for chunk in NSDataSequence(chunkSize: chunkSizeBytes, data: tmpMessage) {
for chunk in BytesSequence(chunkSize: chunkSizeBytes, data: tmpMessage) {
// break chunk into sixteen 32-bit words M[j], 0 j 15
var M = [UInt32](count: 16, repeatedValue: 0)
let range = NSRange(location:0, length: M.count * sizeof(UInt32))
chunk.getBytes(UnsafeMutablePointer<Void>(M), range: range)
var M = toUInt32Array(chunk)
assert(M.count == 16, "Invalid array")
// Initialize hash value for this chunk:
var A:UInt32 = hh[0]
@ -97,7 +95,7 @@ final class MD5 : HashProtocol {
dTemp = D
D = C
C = B
B = B &+ rotateLeft((A &+ F &+ k[j] &+ M[g]), n: s[j])
B = B &+ rotateLeft((A &+ F &+ k[j] &+ M[g]), s[j])
A = dTemp
}
@ -107,13 +105,14 @@ final class MD5 : HashProtocol {
hh[3] = hh[3] &+ D
}
let buf: NSMutableData = NSMutableData();
hh.forEach({ (item) -> () in
var i:UInt32 = item.littleEndian
buf.appendBytes(&i, length: sizeofValue(i))
})
var result = [UInt8]()
result.reserveCapacity(hh.count / 4)
return buf.copy() as! NSData
hh.forEach {
let itemLE = $0.littleEndian
result += [UInt8(itemLE & 0xff), UInt8((itemLE >> 8) & 0xff), UInt8((itemLE >> 16) & 0xff), UInt8((itemLE >> 24) & 0xff)]
}
return result
}
}

View File

@ -1,106 +0,0 @@
//
// PGPDataExtension.swift
// SwiftPGP
//
// Created by Marcin Krzyzanowski on 05/07/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
extension NSMutableData {
/** Convenient way to append bytes */
internal func appendBytes(arrayOfBytes: [UInt8]) {
self.appendBytes(arrayOfBytes, length: arrayOfBytes.count)
}
}
extension NSData {
public func checksum() -> UInt16 {
var s:UInt32 = 0;
var bytesArray = self.arrayOfBytes()
for (var i = 0; i < bytesArray.count; i++) {
_ = bytesArray[i]
s = s + UInt32(bytesArray[i])
}
s = s % 65536;
return UInt16(s);
}
@nonobjc public func md5() -> NSData? {
return Hash.md5(self).calculate()
}
public func sha1() -> NSData? {
return Hash.sha1(self).calculate()
}
public func sha224() -> NSData? {
return Hash.sha224(self).calculate()
}
public func sha256() -> NSData? {
return Hash.sha256(self).calculate()
}
public func sha384() -> NSData? {
return Hash.sha384(self).calculate()
}
public func sha512() -> NSData? {
return Hash.sha512(self).calculate()
}
public func crc32() -> NSData? {
return Hash.crc32(self).calculate()
}
public func encrypt(cipher: Cipher) throws -> NSData? {
let encrypted = try cipher.encrypt(self.arrayOfBytes())
return NSData.withBytes(encrypted)
}
public func decrypt(cipher: Cipher) throws -> NSData? {
let decrypted = try cipher.decrypt(self.arrayOfBytes())
return NSData.withBytes(decrypted)
}
public func authenticate(authenticator: Authenticator) -> NSData? {
if let result = authenticator.authenticate(self.arrayOfBytes()) {
return NSData.withBytes(result)
}
return nil
}
}
extension NSData {
public func toHexString() -> String {
let count = self.length / sizeof(UInt8)
var bytesArray = [UInt8](count: count, repeatedValue: 0)
self.getBytes(&bytesArray, length:count * sizeof(UInt8))
var s:String = "";
for byte in bytesArray {
s = s + String(format:"%02x", byte)
}
return s
}
public func arrayOfBytes() -> [UInt8] {
let count = self.length / sizeof(UInt8)
var bytesArray = [UInt8](count: count, repeatedValue: 0)
self.getBytes(&bytesArray, length:count * sizeof(UInt8))
return bytesArray
}
class public func withBytes(bytes: [UInt8]) -> NSData {
return NSData(bytes: bytes, length: bytes.count)
}
}

View File

@ -1,26 +0,0 @@
//
// NSDataSequence.swift
// CryptoSwift
//
// Created by Marcin Krzyzanowski on 15/07/15.
// Copyright © 2015 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
struct NSDataSequence: SequenceType {
let chunkSize: Int
let data: NSData
func generate() -> AnyGenerator<NSData> {
var offset:Int = 0
return anyGenerator {
let result = self.data.subdataWithRange(NSRange(location: offset, length: min(self.chunkSize, self.data.length - offset)))
offset += result.length
return result.length > 0 ? result : nil
}
}
}

View File

@ -22,8 +22,6 @@ j &<<= 2 //shift left and assign
@see: https://medium.com/@krzyzanowskim/swiftly-shift-bits-and-protect-yourself-be33016ce071
*/
import Foundation
infix operator &<<= {
associativity none
precedence 160

View File

@ -10,8 +10,6 @@
//
// PKCS#5 http://tools.ietf.org/html/rfc2898
import Foundation
//public struct PKCS5 {
//}
//

View File

@ -9,8 +9,6 @@
// and published by RSA Security Inc, starting in the early 1990s.
//
import Foundation
public struct PKCS7: Padding {
public init() {

View File

@ -6,8 +6,6 @@
// Copyright (c) 2015 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
public protocol Padding {
func add(data: [UInt8], blockSize:Int) -> [UInt8]
func remove(data: [UInt8], blockSize:Int?) -> [UInt8]

View File

@ -10,8 +10,6 @@
// Poly1305 takes a 32-byte, one-time key and a message and produces a 16-byte tag that authenticates the
// message such that an attacker has a negligible chance of producing a valid tag for an inauthentic message.
import Foundation
final public class Poly1305 {
let blockSize = 16
private var ctx:Context?

View File

@ -6,42 +6,41 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
final class SHA1 : HashProtocol {
var size:Int = 20 // 160 / 8
let message: NSData
static let size:Int = 20 // 160 / 8
let message: [UInt8]
init(_ message: NSData) {
init(_ message: [UInt8]) {
self.message = message
}
private let h:[UInt32] = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]
func calculate() -> NSData {
let tmpMessage = self.prepare(64)
func calculate() -> [UInt8] {
var tmpMessage = self.prepare(64)
// hash values
var hh = h
// append message length, in a 64-bit big-endian integer. So now the message length is a multiple of 512 bits.
tmpMessage.appendBytes((self.message.length * 8).bytes(64 / 8));
tmpMessage += (self.message.count * 8).bytes(64 / 8)
// Process the message in successive 512-bit chunks:
let chunkSizeBytes = 512 / 8 // 64
for chunk in NSDataSequence(chunkSize: chunkSizeBytes, data: tmpMessage) {
for chunk in BytesSequence(chunkSize: chunkSizeBytes, data: tmpMessage) {
// break chunk into sixteen 32-bit words M[j], 0 j 15, big-endian
// Extend the sixteen 32-bit words into eighty 32-bit words:
var M:[UInt32] = [UInt32](count: 80, repeatedValue: 0)
for x in 0..<M.count {
switch (x) {
case 0...15:
var le:UInt32 = 0
chunk.getBytes(&le, range:NSRange(location:x * sizeofValue(M[x]), length: sizeofValue(M[x])));
let start = chunk.startIndex + (x * sizeofValue(M[x]))
let end = start + sizeofValue(M[x])
let le = toUInt32Array(chunk[start..<end])[0]
M[x] = le.bigEndian
break
default:
M[x] = rotateLeft(M[x-3] ^ M[x-8] ^ M[x-14] ^ M[x-16], n: 1) //FIXME: n:
M[x] = rotateLeft(M[x-3] ^ M[x-8] ^ M[x-14] ^ M[x-16], 1) //FIXME: n:
break
}
}
@ -78,10 +77,10 @@ final class SHA1 : HashProtocol {
break
}
let temp = (rotateLeft(A,n: 5) &+ f &+ E &+ M[j] &+ k) & 0xffffffff
let temp = (rotateLeft(A,5) &+ f &+ E &+ M[j] &+ k) & 0xffffffff
E = D
D = C
C = rotateLeft(B, n: 30)
C = rotateLeft(B, 30)
B = A
A = temp
}
@ -94,12 +93,12 @@ final class SHA1 : HashProtocol {
}
// Produce the final hash value (big-endian) as a 160 bit number:
let buf: NSMutableData = NSMutableData();
for item in hh {
var i:UInt32 = item.bigEndian
buf.appendBytes(&i, length: sizeofValue(i))
var result = [UInt8]()
result.reserveCapacity(hh.count / 4)
hh.forEach {
let item = $0.bigEndian
result += [UInt8(item & 0xff), UInt8((item >> 8) & 0xff), UInt8((item >> 16) & 0xff), UInt8((item >> 24) & 0xff)]
}
return buf.copy() as! NSData;
}
return result
}
}

View File

@ -6,16 +6,15 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
import simd
final class SHA2 : HashProtocol {
var size:Int { return variant.rawValue }
let variant:SHA2.Variant
let message: NSData
let message: [UInt8]
init(_ message:NSData, variant: SHA2.Variant) {
init(_ message:[UInt8], variant: SHA2.Variant) {
self.variant = variant
self.message = message
}
@ -102,25 +101,22 @@ final class SHA2 : HashProtocol {
}
}
private func resultingArray<T>(hh:[T]) -> [T] {
var finalHH:[T] = hh;
private func resultingArray<T>(hh:[T]) -> ArraySlice<T> {
switch (self) {
case .sha224:
finalHH = Array(hh[0..<7])
break;
return hh[0..<7]
case .sha384:
finalHH = Array(hh[0..<6])
break;
return hh[0..<6]
default:
break;
}
return finalHH
return ArraySlice(hh)
}
}
//FIXME: I can't do Generic func out of calculate32 and calculate64 (UInt32 vs UInt64), but if you can - please do pull request.
func calculate32() -> NSData {
let tmpMessage = self.prepare(64)
func calculate32() -> [UInt8] {
var tmpMessage = self.prepare(64)
// hash values
var hh = [UInt32]()
@ -129,19 +125,20 @@ final class SHA2 : HashProtocol {
}
// append message length, in a 64-bit big-endian integer. So now the message length is a multiple of 512 bits.
tmpMessage.appendBytes((message.length * 8).bytes(64 / 8));
tmpMessage += (message.count * 8).bytes(64 / 8)
// Process the message in successive 512-bit chunks:
let chunkSizeBytes = 512 / 8 // 64
for chunk in NSDataSequence(chunkSize: chunkSizeBytes, data: tmpMessage) {
for chunk in BytesSequence(chunkSize: chunkSizeBytes, data: tmpMessage) {
// break chunk into sixteen 32-bit words M[j], 0 j 15, big-endian
// Extend the sixteen 32-bit words into sixty-four 32-bit words:
var M:[UInt32] = [UInt32](count: variant.k.count, repeatedValue: 0)
for x in 0..<M.count {
switch (x) {
case 0...15:
var le:UInt32 = 0
chunk.getBytes(&le, range:NSRange(location:x * sizeofValue(le), length: sizeofValue(le)));
let start = chunk.startIndex + (x * sizeofValue(M[x]))
let end = start + sizeofValue(M[x])
let le = toUInt32Array(chunk[start..<end])[0]
M[x] = le.bigEndian
break
default:
@ -191,17 +188,17 @@ final class SHA2 : HashProtocol {
}
// Produce the final hash value (big-endian) as a 160 bit number:
let buf: NSMutableData = NSMutableData();
variant.resultingArray(hh).forEach{ (item) -> () in
var i:UInt32 = UInt32(item.bigEndian)
buf.appendBytes(&i, length: sizeofValue(i))
var result = [UInt8]()
result.reserveCapacity(hh.count / 4)
variant.resultingArray(hh).forEach {
let item = $0.bigEndian
result += [UInt8(item & 0xff), UInt8((item >> 8) & 0xff), UInt8((item >> 16) & 0xff), UInt8((item >> 24) & 0xff)]
}
return buf.copy() as! NSData;
return result
}
func calculate64() -> NSData {
let tmpMessage = self.prepare(128)
func calculate64() -> [UInt8] {
var tmpMessage = self.prepare(128)
// hash values
var hh = [UInt64]()
@ -211,21 +208,20 @@ final class SHA2 : HashProtocol {
// append message length, in a 64-bit big-endian integer. So now the message length is a multiple of 512 bits.
tmpMessage.appendBytes((message.length * 8).bytes(64 / 8));
tmpMessage += (message.count * 8).bytes(64 / 8)
// Process the message in successive 1024-bit chunks:
let chunkSizeBytes = 1024 / 8 // 128
var leftMessageBytes = tmpMessage.length
for var i = 0; i < tmpMessage.length; i = i + chunkSizeBytes, leftMessageBytes -= chunkSizeBytes {
let chunk = tmpMessage.subdataWithRange(NSRange(location: i, length: min(chunkSizeBytes,leftMessageBytes)))
for chunk in BytesSequence(chunkSize: chunkSizeBytes, data: tmpMessage) {
// break chunk into sixteen 64-bit words M[j], 0 j 15, big-endian
// Extend the sixteen 64-bit words into eighty 64-bit words:
var M = [UInt64](count: variant.k.count, repeatedValue: 0)
for x in 0..<M.count {
switch (x) {
case 0...15:
var le:UInt64 = 0
chunk.getBytes(&le, range:NSRange(location:x * sizeofValue(le), length: sizeofValue(le)));
let start = chunk.startIndex + (x * sizeofValue(M[x]))
let end = start + sizeofValue(M[x])
let le = toUInt64Array(chunk[start..<end])[0]
M[x] = le.bigEndian
break
default:
@ -275,13 +271,13 @@ final class SHA2 : HashProtocol {
}
// Produce the final hash value (big-endian)
let buf: NSMutableData = NSMutableData();
variant.resultingArray(hh).forEach({ (item) -> () in
var i = item.bigEndian
buf.appendBytes(&i, length: sizeofValue(i))
})
return buf.copy() as! NSData;
var result = [UInt8]()
result.reserveCapacity(hh.count / 4)
variant.resultingArray(hh).forEach {
let item = $0.bigEndian
result += [UInt8(item & 0xff), UInt8((item >> 8) & 0xff), UInt8((item >> 16) & 0xff), UInt8((item >> 24) & 0xff),
UInt8((item >> 32) & 0xff),UInt8((item >> 40) & 0xff), UInt8((item >> 48) & 0xff), UInt8((item >> 56) & 0xff)]
}
return result
}
}

View File

@ -1,55 +0,0 @@
//
// StringExtension.swift
// CryptoSwift
//
// Created by Marcin Krzyzanowski on 15/08/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
/** String extension */
extension String {
/** Calculate MD5 hash */
public func md5() -> String? {
return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.md5()?.toHexString()
}
public func sha1() -> String? {
return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.sha1()?.toHexString()
}
public func sha224() -> String? {
return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.sha224()?.toHexString()
}
public func sha256() -> String? {
return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.sha256()?.toHexString()
}
public func sha384() -> String? {
return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.sha384()?.toHexString()
}
public func sha512() -> String? {
return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.sha512()?.toHexString()
}
public func crc32() -> String? {
return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.crc32()?.toHexString()
}
public func encrypt(cipher: Cipher) throws -> String? {
return try self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.encrypt(cipher)?.toHexString()
}
public func decrypt(cipher: Cipher) throws -> String? {
return try self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.decrypt(cipher)?.toHexString()
}
public func authenticate(authenticator: Authenticator) -> String? {
return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.authenticate(authenticator)?.toHexString()
}
}

View File

@ -1,45 +0,0 @@
//
// UInt16Extension.swift
// CryptoSwift
//
// Created by Marcin Krzyzanowski on 02/09/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
/** Shift bits */
extension UInt16 {
/** Shift bits to the right. All bits are shifted (including sign bit) */
mutating func shiftRight(count: UInt16) -> UInt16 {
if (self == 0) {
return self;
}
let bitsCount = UInt16(sizeofValue(self) * 8)
if (count >= bitsCount) {
return 0
}
let maxBitsForValue = UInt16(floor(log2(Double(self) + 1)))
let shiftCount = Swift.min(count, maxBitsForValue - 1)
var shiftedValue:UInt16 = 0;
for bitIdx in 0..<bitsCount {
let byte = 1 << bitIdx
if ((self & byte) == byte) {
shiftedValue = shiftedValue | (byte >> shiftCount)
}
}
self = shiftedValue
return self
}
}
/** shift right and assign with bits truncation */
func &>> (lhs: UInt16, rhs: UInt16) -> UInt16 {
var l = lhs;
l.shiftRight(rhs)
return l
}

View File

@ -6,7 +6,10 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
import Darwin
protocol _UInt32Type { }
extension UInt32: _UInt32Type {}
/** array of bytes */
extension UInt32 {

View File

@ -6,8 +6,6 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
/** array of bytes */
extension UInt64 {
public func bytes(totalBytes: Int = sizeof(UInt64)) -> [UInt8] {

View File

@ -6,7 +6,17 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
import Darwin
public protocol _UInt8Type { }
extension UInt8: _UInt8Type {}
extension _UInt8Type {
static func Zero() -> Self {
return 0 as! Self
}
}
/** casting */
extension UInt8 {

View File

@ -6,21 +6,19 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
func rotateLeft(v:UInt8, n:UInt8) -> UInt8 {
func rotateLeft(v:UInt8, _ n:UInt8) -> UInt8 {
return ((v << n) & 0xFF) | (v >> (8 - n))
}
func rotateLeft(v:UInt16, n:UInt16) -> UInt16 {
func rotateLeft(v:UInt16, _ n:UInt16) -> UInt16 {
return ((v << n) & 0xFFFF) | (v >> (16 - n))
}
func rotateLeft(v:UInt32, n:UInt32) -> UInt32 {
func rotateLeft(v:UInt32, _ n:UInt32) -> UInt32 {
return ((v << n) & 0xFFFFFFFF) | (v >> (32 - n))
}
func rotateLeft(x:UInt64, n:UInt64) -> UInt64 {
func rotateLeft(x:UInt64, _ n:UInt64) -> UInt64 {
return (x << n) | (x >> (64 - n))
}
@ -40,21 +38,39 @@ func reverseBytes(value: UInt32) -> UInt32 {
return ((value & 0x000000FF) << 24) | ((value & 0x0000FF00) << 8) | ((value & 0x00FF0000) >> 8) | ((value & 0xFF000000) >> 24);
}
func toUInt32Array(slice: ArraySlice<UInt8>) -> Array<UInt32> {
var result = Array<UInt32>()
result.reserveCapacity(16)
for idx in slice.startIndex.stride(to: slice.endIndex, by: sizeof(UInt32)) {
let val:UInt32 = (UInt32(slice[idx.advancedBy(3)]) << 24) | (UInt32(slice[idx.advancedBy(2)]) << 16) | (UInt32(slice[idx.advancedBy(1)]) << 8) | UInt32(slice[idx])
result.append(val)
}
return result
}
func toUInt64Array(slice: ArraySlice<UInt8>) -> Array<UInt64> {
var result = Array<UInt64>()
result.reserveCapacity(32)
for idx in slice.startIndex.stride(to: slice.endIndex, by: sizeof(UInt64)) {
var val:UInt64 = 0
val |= UInt64(slice[idx.advancedBy(7)]) << 56
val |= UInt64(slice[idx.advancedBy(6)]) << 48
val |= UInt64(slice[idx.advancedBy(5)]) << 40
val |= UInt64(slice[idx.advancedBy(4)]) << 32
val |= UInt64(slice[idx.advancedBy(3)]) << 24
val |= UInt64(slice[idx.advancedBy(2)]) << 16
val |= UInt64(slice[idx.advancedBy(1)]) << 8
val |= UInt64(slice[idx.advancedBy(0)]) << 0
result.append(val)
}
return result
}
func xor(a: [UInt8], b:[UInt8]) -> [UInt8] {
var xored = [UInt8](count: a.count, repeatedValue: 0)
for i in 0..<xored.count {
xored[i] = a[i] ^ b[i]
}
return xored
}
func perf(text: String, closure: () -> ()) {
let measurementStart = NSDate();
closure()
let measurementStop = NSDate();
let executionTime = measurementStop.timeIntervalSinceDate(measurementStart)
print("\(text) \(executionTime)");
}

View File

@ -5,8 +5,6 @@
// Created by Marcin Krzyzanowski on 27/12/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
import XCTest
@testable import CryptoSwift
@ -21,14 +19,11 @@ final class AESTests: XCTestCase {
let expected:[UInt8] = [0xae,0x8c,0x59,0x95,0xb2,0x6f,0x8e,0x3d,0xb0,0x6f,0x0a,0xa5,0xfe,0xc4,0xf0,0xc2];
if let aes = AES(key: key, iv: iv, blockMode: .CBC) {
let encrypted = try! aes.encrypt(input, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, input, "decryption failed")
} else {
XCTAssert(false, "failed")
}
let aes = try! AES(key: key, iv: iv, blockMode: .CBC)
let encrypted = try! aes.encrypt(input, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, input, "decryption failed")
}
func testAES_encrypt3() {
@ -38,14 +33,11 @@ final class AESTests: XCTestCase {
let expected:[UInt8] = [0xae,0x8c,0x59,0x95,0xb2,0x6f,0x8e,0x3d,0xb0,0x6f,0x0a,0xa5,0xfe,0xc4,0xf0,0xc2];
if let aes = AES(key: key, iv: iv, blockMode: .CBC) {
let encrypted = try! aes.encrypt(input, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, input, "decryption failed")
} else {
XCTAssert(false, "failed")
}
let aes = try! AES(key: key, iv: iv, blockMode: .CBC)
let encrypted = try! aes.encrypt(input, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, input, "decryption failed")
}
func testAES_encrypt() {
@ -59,14 +51,11 @@ final class AESTests: XCTestCase {
0xd8, 0xcd, 0xb7, 0x80,
0x70, 0xb4, 0xc5, 0x5a];
if let aes = AES(key: aesKey, blockMode: .ECB) {
let encrypted = try! aes.encrypt(input, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, input, "decryption failed")
} else {
XCTAssert(false, "failed")
}
let aes = try! AES(key: aesKey, blockMode: .ECB)
let encrypted = try! aes.encrypt(input, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, input, "decryption failed")
}
func testAES_encrypt_cbc() {
@ -75,15 +64,12 @@ final class AESTests: XCTestCase {
let plaintext:[UInt8] = [0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a]
let expected:[UInt8] = [0x76,0x49,0xab,0xac,0x81,0x19,0xb2,0x46,0xce,0xe9,0x8e,0x9b,0x12,0xe9,0x19,0x7d];
if let aes = AES(key: key, iv:iv, blockMode: .CBC) {
XCTAssertTrue(aes.blockMode == .CBC, "Invalid block mode")
let encrypted = try! aes.encrypt(plaintext, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, plaintext, "decryption failed")
} else {
XCTAssert(false, "failed")
}
let aes = try! AES(key: key, iv:iv, blockMode: .CBC)
XCTAssertTrue(aes.blockMode == .CBC, "Invalid block mode")
let encrypted = try! aes.encrypt(plaintext, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, plaintext, "decryption failed")
}
func testAES_encrypt_cfb() {
@ -92,15 +78,22 @@ final class AESTests: XCTestCase {
let plaintext:[UInt8] = [0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a]
let expected:[UInt8] = [0x3b,0x3f,0xd9,0x2e,0xb7,0x2d,0xad,0x20,0x33,0x34,0x49,0xf8,0xe8,0x3c,0xfb,0x4a];
if let aes = AES(key: key, iv:iv, blockMode: .CFB) {
XCTAssertTrue(aes.blockMode == .CFB, "Invalid block mode")
let encrypted = try! aes.encrypt(plaintext, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, plaintext, "decryption failed")
} else {
XCTAssert(false, "failed")
}
let aes = try! AES(key: key, iv:iv, blockMode: .CFB)
XCTAssertTrue(aes.blockMode == .CFB, "Invalid block mode")
let encrypted = try! aes.encrypt(plaintext, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, plaintext, "decryption failed")
}
// https://github.com/krzyzanowskim/CryptoSwift/issues/142
func testAES_encrypt_cfb2() {
let key: [UInt8] = [56, 118, 37, 51, 125, 78, 103, 107, 119, 40, 74, 88, 117, 112, 123, 75, 122, 89, 72, 36, 46, 91, 106, 60, 54, 110, 34, 126, 69, 126, 61, 87]
let iv: [UInt8] = [69, 122, 99, 87, 83, 112, 110, 65, 54, 109, 107, 89, 73, 122, 74, 49]
let plaintext: [UInt8] = [123, 10, 32, 32, 34, 67, 111, 110, 102, 105, 114, 109, 34, 32, 58, 32, 34, 116, 101, 115, 116, 105, 110, 103, 34, 44, 10, 32, 32, 34, 70, 105, 114, 115, 116, 78, 97, 109, 101, 34, 32, 58, 32, 34, 84, 101, 115, 116, 34, 44, 10, 32, 32, 34, 69, 109, 97, 105, 108, 34, 32, 58, 32, 34, 116, 101, 115, 116, 64, 116, 101, 115, 116, 46, 99, 111, 109, 34, 44, 10, 32, 32, 34, 76, 97, 115, 116, 78, 97, 109, 101, 34, 32, 58, 32, 34, 84, 101, 115, 116, 101, 114, 34, 44, 10, 32, 32, 34, 80, 97, 115, 115, 119, 111, 114, 100, 34, 32, 58, 32, 34, 116, 101, 115, 116, 105, 110, 103, 34, 44, 10, 32, 32, 34, 85, 115, 101, 114, 110, 97, 109, 101, 34, 32, 58, 32, 34, 84, 101, 115, 116, 34, 10, 125]
let encrypted: [UInt8] = try! AES(key: key, iv: iv, blockMode: .CFB).encrypt(plaintext)
let decrypted: [UInt8] = try! AES(key: key, iv: iv, blockMode: .CFB).decrypt(encrypted)
XCTAssert(decrypted == plaintext, "decryption failed")
}
func testAES_encrypt_ctr() {
@ -109,115 +102,34 @@ final class AESTests: XCTestCase {
let plaintext:[UInt8] = [0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a]
let expected:[UInt8] = [103, 238, 5, 84, 116, 153, 248, 188, 240, 195, 131, 36, 232, 96, 92, 40]
if let aes = AES(key: key, iv:iv, blockMode: .CTR) {
XCTAssertTrue(aes.blockMode == .CTR, "Invalid block mode")
let encrypted = try! aes.encrypt(plaintext, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, plaintext, "decryption failed")
} else {
XCTAssert(false, "failed")
}
let aes = try! AES(key: key, iv:iv, blockMode: .CTR)
XCTAssertTrue(aes.blockMode == .CTR, "Invalid block mode")
let encrypted = try! aes.encrypt(plaintext, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, plaintext, "decryption failed")
}
func testAES_SubBytes() {
let input:[[UInt8]] = [[0x00, 0x10, 0x20, 0x30],
[0x40, 0x50, 0x60, 0x70],
[0x80, 0x90, 0xa0, 0xb0],
[0xc0, 0xd0, 0xe0, 0xf0]]
let expected:[[UInt8]] = [[0x63, 0xca, 0xb7, 0x04],
[0x09, 0x53, 0xd0, 0x51],
[0xcd, 0x60, 0xe0, 0xe7],
[0xba, 0x70, 0xe1, 0x8c]]
var substituted = input
AES(key: aesKey, blockMode: .CBC)!.subBytes(&substituted)
XCTAssertTrue(compareMatrix(expected, b: substituted), "subBytes failed")
let inverted = AES(key: aesKey, blockMode: .CBC)!.invSubBytes(substituted)
XCTAssertTrue(compareMatrix(input, b: inverted), "invSubBytes failed")
}
func testAES_shiftRows() {
let input:[[UInt8]] = [[0x63, 0x09, 0xcd, 0xba],
[0xca, 0x53, 0x60, 0x70],
[0xb7, 0xd0, 0xe0, 0xe1],
[0x04, 0x51, 0xe7, 0x8c]]
let expected:[[UInt8]] = [[0x63, 0x9, 0xcd, 0xba],
[0x53, 0x60, 0x70, 0xca],
[0xe0, 0xe1, 0xb7, 0xd0],
[0x8c, 0x4, 0x51, 0xe7]]
let shifted = AES(key: aesKey, blockMode: .CBC)!.shiftRows(input)
XCTAssertTrue(compareMatrix(expected, b: shifted), "shiftRows failed")
let inverted = AES(key: aesKey, blockMode: .CBC)!.invShiftRows(shifted)
XCTAssertTrue(compareMatrix(input, b: inverted), "invShiftRows failed")
}
func testAES_multiply() {
XCTAssertTrue(AES(key: aesKey, blockMode: .CBC)?.multiplyPolys(0x0e, 0x5f) == 0x17, "Multiplication failed")
}
func testAES_expandKey() {
let expected:[UInt8] = [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xd6, 0xaa, 0x74, 0xfd, 0xd2, 0xaf, 0x72, 0xfa, 0xda, 0xa6, 0x78, 0xf1, 0xd6, 0xab, 0x76, 0xfe, 0xb6, 0x92, 0xcf, 0xb, 0x64, 0x3d, 0xbd, 0xf1, 0xbe, 0x9b, 0xc5, 0x0, 0x68, 0x30, 0xb3, 0xfe, 0xb6, 0xff, 0x74, 0x4e, 0xd2, 0xc2, 0xc9, 0xbf, 0x6c, 0x59, 0xc, 0xbf, 0x4, 0x69, 0xbf, 0x41, 0x47, 0xf7, 0xf7, 0xbc, 0x95, 0x35, 0x3e, 0x3, 0xf9, 0x6c, 0x32, 0xbc, 0xfd, 0x5, 0x8d, 0xfd, 0x3c, 0xaa, 0xa3, 0xe8, 0xa9, 0x9f, 0x9d, 0xeb, 0x50, 0xf3, 0xaf, 0x57, 0xad, 0xf6, 0x22, 0xaa, 0x5e, 0x39, 0xf, 0x7d, 0xf7, 0xa6, 0x92, 0x96, 0xa7, 0x55, 0x3d, 0xc1, 0xa, 0xa3, 0x1f, 0x6b, 0x14, 0xf9, 0x70, 0x1a, 0xe3, 0x5f, 0xe2, 0x8c, 0x44, 0xa, 0xdf, 0x4d, 0x4e, 0xa9, 0xc0, 0x26, 0x47, 0x43, 0x87, 0x35, 0xa4, 0x1c, 0x65, 0xb9, 0xe0, 0x16, 0xba, 0xf4, 0xae, 0xbf, 0x7a, 0xd2, 0x54, 0x99, 0x32, 0xd1, 0xf0, 0x85, 0x57, 0x68, 0x10, 0x93, 0xed, 0x9c, 0xbe, 0x2c, 0x97, 0x4e, 0x13, 0x11, 0x1d, 0x7f, 0xe3, 0x94, 0x4a, 0x17, 0xf3, 0x7, 0xa7, 0x8b, 0x4d, 0x2b, 0x30, 0xc5]
if let aes = AES(key: aesKey, blockMode: .CBC) {
XCTAssertEqual(expected, aes.expandedKey, "expandKey failed")
} else {
XCTAssert(false, "")
}
}
func testAES_addRoundKey() {
let input:[[UInt8]] = [[0x00, 0x44, 0x88, 0xcc],
[0x11, 0x55, 0x99, 0xdd],
[0x22, 0x66, 0xaa, 0xee],
[0x33, 0x77, 0xbb, 0xff]]
let expected:[[UInt8]] = [[0, 64, 128, 192],
[16, 80, 144, 208],
[32, 96, 160, 224],
[48, 112, 176, 240]]
if let aes = AES(key: aesKey, blockMode: .CBC) {
let result = aes.addRoundKey(input, aes.expandedKey, 0)
XCTAssertTrue(compareMatrix(expected, b: result), "addRoundKey failed")
} else {
XCTAssert(false, "")
}
}
func testAES_mixColumns() {
let input:[[UInt8]] = [[0x63, 0x9, 0xcd, 0xba],
[0x53, 0x60, 0x70, 0xca],
[0xe0, 0xe1, 0xb7, 0xd0],
[0x8c, 0x4, 0x51, 0xe7]]
let expected:[[UInt8]] = [[0x5f, 0x57, 0xf7, 0x1d],
[0x72, 0xf5, 0xbe, 0xb9],
[0x64, 0xbc, 0x3b, 0xf9],
[0x15, 0x92, 0x29, 0x1a]]
if let aes = AES(key: aesKey, blockMode: .CBC) {
let mixed = aes.mixColumns(input)
XCTAssertTrue(compareMatrix(expected, b: mixed), "mixColumns failed")
let inverted = aes.invMixColumns(mixed)
XCTAssertTrue(compareMatrix(input, b: inverted), "invMixColumns failed")
} else {
XCTAssert(false, "")
}
}
func testAESPerformance() {
func testAES_encrypt_performance() {
let key:[UInt8] = [0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c];
let iv:[UInt8] = [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F]
let message = [UInt8](count: 1024 * 1024, repeatedValue: 7)
let aes = try! AES(key: key, iv: iv, blockMode: .CBC)
measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: true, forBlock: { () -> Void in
try! AES(key: key, iv: iv, blockMode: .CBC)?.encrypt(message, padding: PKCS7())
try! aes.encrypt(message, padding: PKCS7())
})
}
func testAES_decrypt_performance() {
let key:[UInt8] = [0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c];
let iv:[UInt8] = [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F]
let message = [UInt8](count: 1024 * 1024, repeatedValue: 7)
let aes = try! AES(key: key, iv: iv, blockMode: .CBC)
measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: true, forBlock: { () -> Void in
try! aes.decrypt(message, padding: PKCS7())
})
}
func testAESPerformanceCommonCrypto() {
let key:[UInt8] = [0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c];
let iv:[UInt8] = [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F]

View File

@ -5,8 +5,6 @@
// Created by Marcin Krzyzanowski on 27/12/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
import XCTest
@testable import CryptoSwift
@ -52,20 +50,18 @@ final class ChaCha20Tests: XCTestCase {
let setup = (key: keys[idx], iv: ivs[idx])
do {
let encrypted = try Cipher.ChaCha20(setup).encrypt(message)
let decrypted = try Cipher.ChaCha20(setup).decrypt(encrypted)
let encrypted = try ChaCha20(setup)!.encrypt(message)
let decrypted = try ChaCha20(setup)!.decrypt(encrypted)
XCTAssertEqual(message, decrypted, "ChaCha20 decryption failed");
// check extension
let messageData = NSData(bytes: message, length: message.count);
let encrypted2 = try! messageData.encrypt(Cipher.ChaCha20(setup))
let encrypted2 = try! messageData.encrypt(ChaCha20(setup)!)
XCTAssertNotNil(encrypted2, "")
if let encrypted2 = encrypted2 {
XCTAssertEqual(NSData.withBytes(encrypted), encrypted2, "ChaCha20 extension failed")
}
} catch Cipher.Error.EncryptError {
XCTAssertEqual(NSData.withBytes(encrypted), encrypted2, "ChaCha20 extension failed")
} catch CipherError.Encrypt {
XCTAssert(false, "Encryption failed")
} catch Cipher.Error.DecryptError {
} catch CipherError.Decrypt {
XCTAssert(false, "Decryption failed")
} catch {
XCTAssert(false, "Failed")

View File

@ -5,8 +5,6 @@
// Created by Marcin Krzyzanowski on 15/08/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
import XCTest
@testable import CryptoSwift
@ -76,6 +74,24 @@ final class ExtensionsTest: XCTestCase {
XCTAssert(iii &<< 1 == iii << 1, "shift left failed")
XCTAssert(iii &<< 8 == iii << 8, "shift left failed")
XCTAssert((iii &<< 32) == 0, "shift left failed")
}
func testtoUInt32Array() {
let chunk:ArraySlice<UInt8> = [1,1,1,7,2,3,4,5]
let result = toUInt32Array(chunk)
XCTAssert(result.count == 2, "Invalid conversion")
XCTAssert(result[0] == 117506305, "Invalid conversion")
XCTAssert(result[1] == 84148994, "Invalid conversion")
}
func test_NSData_init() {
let data = NSData(bytes: [0x01, 0x02, 0x03])
XCTAssert(data.length == 3, "Invalid data")
}
func test_String_encrypt_base64() {
let encrypted: String = try! "my secret string".encrypt(AES(key: "secret0key000000", iv: "0123456789012345"))
XCTAssertEqual(encrypted, "aPf/i9th9iX+vf49eR7PYk2q7S5xmm3jkRLejgzHNJs=")
}
}

View File

@ -5,8 +5,6 @@
// Created by Marcin Krzyzanowski on 29/08/14.
// Copyright (c) 2015 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
import XCTest
@testable import CryptoSwift
@ -26,8 +24,8 @@ final class HMACTests: XCTestCase {
let msg:[UInt8] = []
let expectedMac:[UInt8] = [0x74,0xe6,0xf7,0x29,0x8a,0x9c,0x2d,0x16,0x89,0x35,0xf5,0x8c,0x00,0x1b,0xad,0x88]
let hmac = Authenticator.HMAC(key: key, variant: .md5).authenticate(msg)
XCTAssertEqual(hmac!, expectedMac, "Invalid authentication result")
let hmac = try! Authenticator.HMAC(key: key, variant: .md5).authenticate(msg)
XCTAssertEqual(hmac, expectedMac, "Invalid authentication result")
}
func testSHA1() {
@ -35,8 +33,8 @@ final class HMACTests: XCTestCase {
let msg:[UInt8] = []
let expectedMac:[UInt8] = [0xfb,0xdb,0x1d,0x1b,0x18,0xaa,0x6c,0x08,0x32,0x4b,0x7d,0x64,0xb7,0x1f,0xb7,0x63,0x70,0x69,0x0e,0x1d]
let hmac = Authenticator.HMAC(key: key, variant: .sha1).authenticate(msg)
XCTAssertEqual(hmac!, expectedMac, "Invalid authentication result")
let hmac = try! Authenticator.HMAC(key: key, variant: .sha1).authenticate(msg)
XCTAssertEqual(hmac, expectedMac, "Invalid authentication result")
}
func testSHA256() {
@ -44,8 +42,8 @@ final class HMACTests: XCTestCase {
let msg:[UInt8] = []
let expectedMac:[UInt8] = [0xb6,0x13,0x67,0x9a,0x08,0x14,0xd9,0xec,0x77,0x2f,0x95,0xd7,0x78,0xc3,0x5f,0xc5,0xff,0x16,0x97,0xc4,0x93,0x71,0x56,0x53,0xc6,0xc7,0x12,0x14,0x42,0x92,0xc5,0xad]
let hmac = Authenticator.HMAC(key: key, variant: .sha256).authenticate(msg)
XCTAssertEqual(hmac!, expectedMac, "Invalid authentication result")
let hmac = try! Authenticator.HMAC(key: key, variant: .sha256).authenticate(msg)
XCTAssertEqual(hmac, expectedMac, "Invalid authentication result")
}
func testSHA384() {
@ -53,8 +51,8 @@ final class HMACTests: XCTestCase {
let msg:[UInt8] = []
let expectedMac:[UInt8] = [0x6c, 0x1f, 0x2e, 0xe9, 0x38, 0xfa, 0xd2, 0xe2, 0x4b, 0xd9, 0x12, 0x98, 0x47, 0x43, 0x82, 0xca, 0x21, 0x8c, 0x75, 0xdb, 0x3d, 0x83, 0xe1, 0x14, 0xb3, 0xd4, 0x36, 0x77, 0x76, 0xd1, 0x4d, 0x35, 0x51, 0x28, 0x9e, 0x75, 0xe8, 0x20, 0x9c, 0xd4, 0xb7, 0x92, 0x30, 0x28, 0x40, 0x23, 0x4a, 0xdc]
let hmac = Authenticator.HMAC(key: key, variant: .sha384).authenticate(msg)
XCTAssertEqual(hmac!, expectedMac, "Invalid authentication result")
let hmac = try! Authenticator.HMAC(key: key, variant: .sha384).authenticate(msg)
XCTAssertEqual(hmac, expectedMac, "Invalid authentication result")
}
func testSHA512() {
@ -62,7 +60,7 @@ final class HMACTests: XCTestCase {
let msg:[UInt8] = []
let expectedMac:[UInt8] = [0xb9, 0x36, 0xce, 0xe8, 0x6c, 0x9f, 0x87, 0xaa, 0x5d, 0x3c, 0x6f, 0x2e, 0x84, 0xcb, 0x5a, 0x42, 0x39, 0xa5, 0xfe, 0x50, 0x48, 0x0a, 0x6e, 0xc6, 0x6b, 0x70, 0xab, 0x5b, 0x1f, 0x4a, 0xc6, 0x73, 0x0c, 0x6c, 0x51, 0x54, 0x21, 0xb3, 0x27, 0xec, 0x1d, 0x69, 0x40, 0x2e, 0x53, 0xdf, 0xb4, 0x9a, 0xd7, 0x38, 0x1e, 0xb0, 0x67, 0xb3, 0x38, 0xfd, 0x7b, 0x0c, 0xb2, 0x22, 0x47, 0x22, 0x5d, 0x47]
let hmac = Authenticator.HMAC(key: key, variant: .sha512).authenticate(msg)
XCTAssertEqual(hmac!, expectedMac, "Invalid authentication result")
let hmac = try! Authenticator.HMAC(key: key, variant: .sha512).authenticate(msg)
XCTAssertEqual(hmac, expectedMac, "Invalid authentication result")
}
}

View File

@ -19,85 +19,52 @@ final class CryptoSwiftTests: XCTestCase {
super.tearDown()
}
func testMD5() {
let data1:NSData = NSData(bytes: [0x31, 0x32, 0x33] as [UInt8], length: 3) // "1", "2", "3"
if let hash = Hash.md5(data1).calculate() {
XCTAssertEqual(hash.toHexString(), "202cb962ac59075b964b07152d234b70", "MD5 calculation failed");
} else {
XCTAssert(false, "Missing result")
}
let string:NSString = ""
let data:NSData = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
if let hashData = Hash.md5(data).calculate() {
XCTAssertEqual(hashData.toHexString(), "d41d8cd98f00b204e9800998ecf8427e", "MD5 calculation failed")
} else {
XCTAssert(false, "Missing result")
}
if let hash = data1.md5() {
XCTAssertEqual(hash.toHexString(), "202cb962ac59075b964b07152d234b70", "MD5 calculation failed");
}
if let hash = "123".md5() {
XCTAssertEqual(hash, "202cb962ac59075b964b07152d234b70", "MD5 calculation failed");
}
if let hash = "".md5() {
XCTAssertEqual(hash, "d41d8cd98f00b204e9800998ecf8427e", "MD5 calculation failed")
} else {
XCTAssert(false, "Hash for empty string is missing")
}
if let hash = "a".md5() {
XCTAssertEqual(hash, "0cc175b9c0f1b6a831c399e269772661", "MD5 calculation failed")
}
if let hash = "abc".md5() {
XCTAssertEqual(hash, "900150983cd24fb0d6963f7d28e17f72", "MD5 calculation failed")
}
if let hash = "message digest".md5() {
XCTAssertEqual(hash, "f96b697d7cb7938d525a2f31aaf161d0", "MD5 calculation failed")
}
func testMD5_data() {
let data = [0x31, 0x32, 0x33] as [UInt8] // "1", "2", "3"
XCTAssertEqual(Hash.md5(data).calculate(), [0x20,0x2c,0xb9,0x62,0xac,0x59,0x07,0x5b,0x96,0x4b,0x07,0x15,0x2d,0x23,0x4b,0x70], "MD5 calculation failed");
}
if let hash = "abcdefghijklmnopqrstuvwxyz".md5() {
XCTAssertEqual(hash, "c3fcd3d76192e4007dfb496cca67e13b", "MD5 calculation failed")
}
func testMD5_emptyString() {
let data:NSData = "".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
XCTAssertEqual(Hash.md5(data.arrayOfBytes()).calculate(), [0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e], "MD5 calculation failed")
}
if let hash = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".md5() {
XCTAssertEqual(hash, "d174ab98d277d9f5a5611c2c9f419d9f", "MD5 calculation failed")
}
if let hash = "12345678901234567890123456789012345678901234567890123456789012345678901234567890".md5() {
XCTAssertEqual(hash, "57edf4a22be3c955ac49da2e2107b67a", "MD5 calculation failed")
}
func testMD5_string() {
XCTAssertEqual("123".md5(), "202cb962ac59075b964b07152d234b70", "MD5 calculation failed");
XCTAssertEqual("".md5(), "d41d8cd98f00b204e9800998ecf8427e", "MD5 calculation failed")
XCTAssertEqual("a".md5(), "0cc175b9c0f1b6a831c399e269772661", "MD5 calculation failed")
XCTAssertEqual("abc".md5(), "900150983cd24fb0d6963f7d28e17f72", "MD5 calculation failed")
XCTAssertEqual("message digest".md5(), "f96b697d7cb7938d525a2f31aaf161d0", "MD5 calculation failed")
XCTAssertEqual("abcdefghijklmnopqrstuvwxyz".md5(), "c3fcd3d76192e4007dfb496cca67e13b", "MD5 calculation failed")
XCTAssertEqual("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".md5(), "d174ab98d277d9f5a5611c2c9f419d9f", "MD5 calculation failed")
XCTAssertEqual("12345678901234567890123456789012345678901234567890123456789012345678901234567890".md5(), "57edf4a22be3c955ac49da2e2107b67a", "MD5 calculation failed")
}
func testMD5PerformanceSwift() {
self.measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: false, forBlock: { () -> Void in
let buf = UnsafeMutablePointer<UInt8>(calloc(2048, sizeof(UInt8)))
let data = NSData(bytes: buf, length: 2048)
let buf = UnsafeMutablePointer<UInt8>(calloc(1024 * 1024, sizeof(UInt8)))
let data = NSData(bytes: buf, length: 1024 * 1024)
let arr = data.arrayOfBytes()
self.startMeasuring()
Hash.md5(data).calculate()
Hash.md5(arr).calculate()
self.stopMeasuring()
buf.dealloc(1024)
buf.dealloc(1024 * 1024)
buf.destroy()
})
}
func testMD5PerformanceCommonCrypto() {
self.measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: false, forBlock: { () -> Void in
let buf = UnsafeMutablePointer<UInt8>(calloc(2048, sizeof(UInt8)))
let data = NSData(bytes: buf, length: 2048)
self.startMeasuring()
let buf = UnsafeMutablePointer<UInt8>(calloc(1024 * 1024, sizeof(UInt8)))
let data = NSData(bytes: buf, length: 1024 * 1024)
let outbuf = UnsafeMutablePointer<UInt8>.alloc(Int(CC_MD5_DIGEST_LENGTH))
CC_MD5(data.bytes, CC_LONG(data.length), outbuf)
self.startMeasuring()
CC_MD5(data.bytes, CC_LONG(data.length), outbuf)
//let output = NSData(bytes: outbuf, length: Int(CC_MD5_DIGEST_LENGTH));
self.stopMeasuring()
outbuf.dealloc(Int(CC_MD5_DIGEST_LENGTH))
outbuf.destroy()
self.stopMeasuring()
buf.dealloc(1024)
buf.dealloc(1024 * 1024)
buf.destroy()
})
}
@ -108,20 +75,9 @@ final class CryptoSwiftTests: XCTestCase {
XCTAssertEqual(hash.toHexString(), "40bd001563085fc35165329ea1ff5c5ecbdbbeef", "SHA1 calculation failed");
}
if let hash = "abc".sha1() {
XCTAssertEqual(hash, "a9993e364706816aba3e25717850c26c9cd0d89d", "SHA1 calculation failed")
}
if let hash = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha1() {
XCTAssertEqual(hash, "84983e441c3bd26ebaae4aa1f95129e5e54670f1", "SHA1 calculation failed")
}
if let hash = "".sha1() {
XCTAssertEqual(hash, "da39a3ee5e6b4b0d3255bfef95601890afd80709", "SHA1 calculation failed")
} else {
XCTAssert(false, "SHA1 calculation failed")
}
XCTAssertEqual("abc".sha1(), "a9993e364706816aba3e25717850c26c9cd0d89d", "SHA1 calculation failed")
XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha1(), "84983e441c3bd26ebaae4aa1f95129e5e54670f1", "SHA1 calculation failed")
XCTAssertEqual("".sha1(), "da39a3ee5e6b4b0d3255bfef95601890afd80709", "SHA1 calculation failed")
}
func testSHA224() {
@ -137,16 +93,8 @@ final class CryptoSwiftTests: XCTestCase {
XCTAssertEqual(hash.toHexString(), "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3", "SHA256 calculation failed");
}
if let hash = "Rosetta code".sha256() {
XCTAssertEqual(hash, "764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf", "SHA256 calculation failed")
}
if let hash = "".sha256() {
XCTAssertEqual(hash, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "SHA256 calculation failed")
} else {
XCTAssert(false, "SHA256 calculation failed")
}
XCTAssertEqual("Rosetta code".sha256(), "764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf", "SHA256 calculation failed")
XCTAssertEqual("".sha256(), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "SHA256 calculation failed")
}
func testSHA384() {
@ -155,15 +103,8 @@ final class CryptoSwiftTests: XCTestCase {
XCTAssertEqual(hash.toHexString(), "9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f", "SHA384 calculation failed");
}
if let hash = "The quick brown fox jumps over the lazy dog.".sha384() {
XCTAssertEqual(hash, "ed892481d8272ca6df370bf706e4d7bc1b5739fa2177aae6c50e946678718fc67a7af2819a021c2fc34e91bdb63409d7", "SHA384 calculation failed");
}
if let hash = "".sha384() {
XCTAssertEqual(hash, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", "SHA384 calculation failed")
} else {
XCTAssert(false, "SHA384 calculation failed")
}
XCTAssertEqual("The quick brown fox jumps over the lazy dog.".sha384(), "ed892481d8272ca6df370bf706e4d7bc1b5739fa2177aae6c50e946678718fc67a7af2819a021c2fc34e91bdb63409d7", "SHA384 calculation failed");
XCTAssertEqual("".sha384(), "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", "SHA384 calculation failed")
}
func testSHA512() {
@ -172,15 +113,8 @@ final class CryptoSwiftTests: XCTestCase {
XCTAssertEqual(hash.toHexString(), "3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2", "SHA512 calculation failed");
}
if let hash = "The quick brown fox jumps over the lazy dog.".sha512() {
XCTAssertEqual(hash, "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed", "SHA512 calculation failed");
}
if let hash = "".sha512() {
XCTAssertEqual(hash, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", "SHA512 calculation failed")
} else {
XCTAssert(false, "SHA512 calculation failed")
}
XCTAssertEqual("The quick brown fox jumps over the lazy dog.".sha512(), "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed", "SHA512 calculation failed");
XCTAssertEqual("".sha512(), "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", "SHA512 calculation failed")
}
func testCRC32() {
@ -189,22 +123,17 @@ final class CryptoSwiftTests: XCTestCase {
XCTAssertEqual(crc.toHexString(), "884863d2", "CRC32 calculation failed");
}
if let crc = "".crc32() {
XCTAssertEqual(crc, "00000000", "CRC32 calculation failed");
} else {
XCTAssert(false, "CRC32 calculation failed")
}
XCTAssertEqual("".crc32(), "00000000", "CRC32 calculation failed");
}
func testCRC32Async() {
let expect = expectationWithDescription("CRC32")
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { () -> Void in
self.testCRC32()
expect.fulfill()
})
waitForExpectationsWithTimeout(10, handler: { (error) -> Void in
XCTAssertNil(error, "CRC32 async failed")
})
func testCRC16() {
let result = CRC().crc16([49,50,51,52,53,54,55,56,57] as [UInt8])
XCTAssert(result == 0xBB3D, "CRC16 failed")
}
func testChecksum() {
let data:NSData = NSData(bytes: [49, 50, 51] as [UInt8], length: 3)
XCTAssert(data.checksum() == 0x96, "Invalid checksum")
}
}

View File

@ -6,8 +6,6 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
func compareMatrix(a:[[UInt8]], b:[[UInt8]]) -> Bool {
for (i,arr) in a.enumerate() {
for (j,val) in arr.enumerate() {

View File

@ -5,8 +5,6 @@
// Created by Marcin Krzyzanowski on 27/12/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
import XCTest
@testable import CryptoSwift

View File

@ -5,8 +5,6 @@
// Created by Marcin Krzyzanowski on 29/08/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
//
import Foundation
import XCTest
@testable import CryptoSwift
@ -26,18 +24,12 @@ final class Poly1305Tests: XCTestCase {
let msg:[UInt8] = [0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1]
let expectedMac:[UInt8] = [0xdd,0xb9,0xda,0x7d,0xdd,0x5e,0x52,0x79,0x27,0x30,0xed,0x5c,0xda,0x5f,0x90,0xa4]
if let mac = Authenticator.Poly1305(key: key).authenticate(msg) {
XCTAssertEqual(mac, expectedMac, "Invalid authentication result")
} else {
XCTFail("Missing MAC")
}
let mac = try! Authenticator.Poly1305(key: key).authenticate(msg)
XCTAssertEqual(mac, expectedMac, "Invalid authentication result")
// extensions
let msgData = NSData.withBytes(msg)
if let mac2 = msgData.authenticate(Authenticator.Poly1305(key: key)) {
XCTAssertEqual(mac2, NSData.withBytes(expectedMac), "Invalid authentication result")
} else {
XCTFail("Missing MAC")
}
let mac2 = try! msgData.authenticate(Authenticator.Poly1305(key: key))
XCTAssertEqual(mac2, NSData.withBytes(expectedMac), "Invalid authentication result")
}
}

View File

@ -19,7 +19,7 @@ Good mood
##Features
- Easy to use
- Convenience extensions
- Convenient extensions for String and NSData
##What implemented?
@ -31,6 +31,7 @@ Good mood
- [SHA384](http://tools.ietf.org/html/rfc6234)
- [SHA512](http://tools.ietf.org/html/rfc6234)
- [CRC32](http://en.wikipedia.org/wiki/Cyclic_redundancy_check) (well, kind of hash)
- [CRC16](http://en.wikipedia.org/wiki/Cyclic_redundancy_check) (well, kind of hash)
#####Cipher
- [AES-128, AES-192, AES-256](http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf)
@ -56,27 +57,44 @@ Good mood
For latest version, please check **develop** branch. This is latest development version that will be merged into **master** branch at some point.
- If you want to contribute, submit a [pull request](https://github.com/krzyzanowskim/CryptoSwift/pulls).
- If you found a bug, [open an issue](https://github.com/krzyzanowskim/CryptoSwift/issues).
- If you have a feature request, [open an issue](https://github.com/krzyzanowskim/CryptoSwift/issues).
##Installation
To install CryptoSwift, add it as a submodule to your project (on the top level project directory):
git submodule add https://github.com/krzyzanowskim/CryptoSwift.git
Then, drag the CryptoSwift.xcodeproj file into your Xcode project, and add CryptoSwift.framework as a dependency to your target. Now select your App and choose the General tab for the app target. Drag CryptoSwift.framework to "Embedded Binaries"
####Embedded Framework
Alternatively, you can build the Universal Framework and link it in your Xcode project.
Aggregate target `CryptoSwift-Universal` runs a script to build a universal framework. The script currently copies the framework to the `Framework` directory. (The path to CryptoSwift directory cannot contain any space)
Embedded frameworks require a minimum deployment target of iOS 8 or OS X Mavericks (10.9). Drag the `CryptoSwift.xcodeproj` file into your Xcode project, and add appropriate framework as a dependency to your target. Now select your App and choose the General tab for the app target. Drag framework to *Embedded Binaries*
#####iOS, OSX, watchOS
In the project, you'll find three targets, configured for each supported SDK:
- CryptoSwift iOS
- CryptoSwift OSX
- CryptoSwift watchOS
You may need to choose the one you need to build `CryptoSwift.framework` for your application.
####CryptoSwift.framework
Alternatively, you can build the Universal Framework and link it in your Xcode project. To do that please run `build.sh` script and find resulting frameworks in `Framework` directory.
Looking for version for Swift 1.2? check branch **swift12**, it's there.
#####iOS and OSX
By default project is setup for iOS. You need to switch to OS X SDK manually [see #8](https://github.com/krzyzanowskim/CryptoSwift/issues/8)
####CocoaPods
You can use [CocoaPods](http://cocoapods.org/?q=cryptoSwift).
```ruby
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'CryptoSwift'
```
@ -94,7 +112,7 @@ Specify in Cartfile:
github "krzyzanowskim/CryptoSwift"
```
Then follow [build instructions](https://github.com/Carthage/Carthage#getting-started)
Run carthage to build the framework and drag the built CryptoSwift.framework into your Xcode project. Follow [build instructions](https://github.com/Carthage/Carthage#getting-started)
##Usage
@ -102,20 +120,23 @@ Then follow [build instructions](https://github.com/Carthage/Carthage#getting-st
import CryptoSwift
```
Generally you should use `CryptoSwift.Hash`, `CryptoSwift.Cipher` enums or convenience extensions
For your convenience you should use extensions methods like encrypt(), decrypt(), md5(), sha1() and so on.
Hash enum usage
Hashing a data or array of bytes (aka `Array<UInt8>`)
```swift
/* Hash enum usage */
var data:NSData = NSData(bytes: [49, 50, 51] as [UInt8], length: 3)
if let data = CryptoSwift.Hash.md5(data).calculate() {
println(data.toHexString())
}
let input:[UInt8] = [49, 50, 51]
let output = input.md5()
// alternatively: let output = CryptoSwift.Hash.md5(input).calculate()
print(output.toHexString())
```
Hashing a data
```swift
let data = NSData()
let hash = data.md5()
let hash = data.sha1()
let hash = data.sha224()
@ -123,17 +144,16 @@ let hash = data.sha256()
let hash = data.sha384()
let hash = data.sha512()
let crc = data.crc32()
let crc32 = data.crc32()
let crc16 = data.crc16()
println(hash.toHexString())
print(hash.toHexString())
```
Hashing a String and printing result
```swift
if let hash = "123".md5() {
println(hash)
}
let hash = "123".md5()
```
Some content-encryption algorithms assume the input length is a multiple of k octets, where k is greater than one. For such algorithms, the input shall be padded.
@ -147,46 +167,76 @@ Working with Ciphers
ChaCha20
```swift
let encrypted = Cipher.ChaCha20(key: key, iv: iv).encrypt(message)
let decrypted = Cipher.ChaCha20(key: key, iv: iv).decrypt(encrypted)
let encrypted: [UInt8] = ChaCha20(key: key, iv: iv).encrypt(message)
let decrypted: [UInt8] = ChaCha20(key: key, iv: iv).decrypt(encrypted)
```
AES
Notice regarding padding: *Manual padding of data is optional and CryptoSwift by default always will add PKCS7 padding before encryption, and remove after decryption when __Cipher__ enum is used. If you need manually disable/enable padding, you can do this by setting parameter for encrypt()/decrypt() on class __AES__.*
Basic:
```swift
let input = NSData()
let encrypted = try! input.encrypt(AES(key: "secret0key000000", iv:"0123456789012345"))
// 1. set key and random IV
let key = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00] as [UInt8]
let iv = Cipher.randomIV(AES.blockSize)
let input: [UInt8] = [0,1,2,3,4,5,6,7,8,9]
input.encrypt(AES(key: "secret0key000000", iv:"0123456789012345", blockMode: .CBC))
```
// 2. encrypt
let encrypted = AES(key: key, iv: iv, blockMode: .CBC)?.encrypt(message, padding: PKCS7())
// 3. decrypt with the same key and IV
let decrypted = AES(key: key, iv: iv, blockMode: .CBC)?.decrypt(encryptedData, padding: PKCS7())
Encrypt String to Base64 string result:
```swift
// Encrypt string and get Base64 representation of result
let base64: String = try! "my secret string".encrypt(AES(key: "secret0key000000", iv: "0123456789012345"))
```
...under the hood, this is [UInt8] converted to NSData converted to Base64 string representation:
```swift
let encryptedBytes: [UInt8] = try "my secret string".encrypt(AES(key: "secret0key000000", iv: "0123456789012345")
let base64 = NSData(bytes: encryptedBytes).base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
```
Advanced:
```swift
let input: [UInt8] = [0,1,2,3,4,5,6,7,8,9]
let key: [UInt8] = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
let iv: [UInt8] = AES.randomIV(AES.blockSize)
do {
let encrypted: [UInt8] = try AES(key: key, iv: iv, blockMode: .CBC).encrypt(input, padding: PKCS7())
let decrypted: [UInt8] = try AES(key: key, iv: iv, blockMode: .CBC).decrypt(input, padding: PKCS7())
} catch AES.Error.BlockSizeExceeded {
// block size exceeded
} catch {
// some error
}
```
AES without data padding
```swift
let encrypted = Cipher.AES(key: key, iv: iv, blockMode: .CBC).encrypt(plaintext)
let input: [UInt8] = [0,1,2,3,4,5,6,7,8,9]
let encrypted: [UInt8] = try! AES(key: "secret0key000000", iv:"0123456789012345", blockMode: .CBC).encrypt(input)
```
Using extensions
```swift
let encrypted = dataToEncrypt.encrypt(Cipher.ChaCha20(key: key, iv: iv))
let decrypted = encrypted.decrypt(Cipher.ChaCha20(key: key, iv: iv))
let plain = NSData()
let encrypted: NSData = try! plain.encrypt(ChaCha20(key: key, iv: iv))
let decrypted: NSData = try! encrypted.decrypt(ChaCha20(key: key, iv: iv))
// plain == decrypted
```
Message authenticators
```swift
// Calculate Message Authentication Code (MAC) for message
let mac = Authenticator.Poly1305(key: key).authenticate(message)
let mac: [UInt8] = try! Authenticator.Poly1305(key: key).authenticate(input)
```
#####Conversion between NSData and [UInt8]
@ -194,14 +244,15 @@ let mac = Authenticator.Poly1305(key: key).authenticate(message)
For you convenience CryptoSwift provide two function to easily convert array of bytes to NSData and other way around:
```swift
let data = NSData.withBytes([0x01,0x02,0x03])
let data: NSData = NSData(bytes: [0x01, 0x02, 0x03])
let bytes:[UInt8] = data.arrayOfBytes()
```
##Author
[Marcin Krzyżanowski](http://www.krzyzanowskim.com)
T: [@krzyzanowskim](http://twitter.com/krzyzanowskim)
Cryptoswift is owned and maintained by Marcin Krzyżanowski. You can follow me on Twitter at [@krzyzanowskim](http://twitter.com/krzyzanowskim) for project updates and releases.
[Marcin Krzyżanowski](http://www.krzyzanowskim.com)
##License
@ -218,18 +269,4 @@ Permission is granted to anyone to use this software for any purpose, including
##Changelog
0.0.16
- Critical fix for private "md5" selector issue (#135)
0.0.15
- Fix 32-bit CTR block mode
- Carthage support update
- Mark as App-Extension-Safe API
0.0.14
- hexString -> toHextString() #105
- CTR (Counter mode)
- Hex string is lowercase now
- Carthage support
- Tests update
- Swift 2.0 support - overall update
see CHANGELOG file

View File

@ -1,37 +1,34 @@
# OS X Finder
.DS_Store
# Xcode per-user config
*.mode1
*.mode1v3
*.mode2v3
*.perspective
*.perspectivev3
*.pbxuser
xcuserdata
*.xccheckout
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
# Build products
## Build generated
build/
*.o
*.LinkFileList
DerivedData
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
## Other
*.xccheckout
*.moved-aside
*.xcuserstate
*.xcscmblueprint
## Obj-C/Swift specific
*.hmap
*.ipa
# Automatic backup files
*~.nib/
*.swp
*~
*.dat
*.dep
# Cocoapods
Pods
# Carthage
Carthage/Build
test/fuzzingserver.json
test/reports/
docsb/

View File

@ -2,7 +2,7 @@
<a href="https://tidwall.github.io/SwiftWebSocket/results/"><img src="https://tidwall.github.io/SwiftWebSocket/build.png" alt="" width="93" height="20" border="0" /></a>
<a href="https://developer.apple.com/swift/"><img src="https://tidwall.github.io/SwiftWebSocket/swift2.png" alt="" width="65" height="20" border="0" /></a>
<a href="https://tidwall.github.io/SwiftWebSocket/docs/"><img src="https://tidwall.github.io/SwiftWebSocket/docs.png" alt="" width="65" height="20" border="0" /></a>
Conforming WebSocket ([RFC 6455](https://tools.ietf.org/html/rfc6455)) client library implemented in pure Swift.
@ -10,26 +10,23 @@ Conforming WebSocket ([RFC 6455](https://tools.ietf.org/html/rfc6455)) client li
SwiftWebSocket currently passes all 521 of the Autobahn's fuzzing tests, including strict UTF-8, and message compression.
**Built for Swift 2.0** - For Swift 1.2 support use the 'swift/1.2' branch.
## Features
- Swift 2.0. No need for Objective-C Bridging.
- Reads compressed messages (`permessage-deflate`). [IETF Draft](https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-21)
- Strict UTF-8 processing.
- High performance.
- TLS / WSS support. Self-signed certificate option.
- The API is modeled after the [Javascript API](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket).
- TLS / WSS support.
- Reads compressed messages (`permessage-deflate`). [IETF Draft](https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-21)
- Send pings and receive pong events.
- Strict UTF-8 processing.
- `binaryType` property to choose between `[UInt8]` or `NSData` messages.
- Zero asserts. All networking, stream, and protocol errors are routed through the `error` event.
- Send pings and receive pong events.
- High performance.
##Example
## Example
```swift
func echoTest(){
var messageNum = 0
let ws = WebSocket("wss://echo.websocket.org")
unowned let ws = WebSocket("wss://echo.websocket.org")
let send : ()->() = {
let msg = "\(++messageNum): \(NSDate().description)"
print("send: \(msg)")
@ -58,6 +55,30 @@ func echoTest(){
}
```
## Reuse and Delaying WebSocket Connections
v2.3.0+ makes available an optional `open` method. This will allow for a `WebSocket` object to be instantiated without an immediate connection to the server. It can also be used to reconnect to a server following the `close` event.
For example,
```swift
let ws = WebSocket()
ws.event.close = { _ in
ws.open() // reopen the socket to the previous url
ws.open("ws://otherurl") // or, reopen the socket to a new url
}
ws.open("ws://url") // call with url
}
```
## Compression
The `compression` flag may be used to request compressed messages from the server. If the server does not support or accept the request, then connection will continue as normal, but with uncompressed messages.
```swift
let ws = WebSocket("ws://url")
ws.compression.on = true
```
##Installation (iOS and OS X)
### [Carthage]

View File

@ -1,8 +1,8 @@
/*
* SwiftWebSocket (websocket.swift)
*
* Copyright (C) 2015 ONcast, LLC. All Rights Reserved.
* Created by Josh Baker (joshbaker77@gmail.com)
* Copyright (C) Josh Baker. All Rights Reserved.
* Contact: @tidwall, joshbaker77@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
@ -193,6 +193,8 @@ public struct WebSocketService : OptionSetType {
}
private let atEndDetails = "streamStatus.atEnd"
private let timeoutDetails = "The operation couldnt be completed. Operation timed out"
private let timeoutDuration : CFTimeInterval = 30
public enum WebSocketError : ErrorType, CustomStringConvertible {
case Memory
@ -490,97 +492,92 @@ private class Deflater {
}
/// WebSocket objects are bidirectional network streams that communicate over HTTP. RFC 6455.
public class WebSocket: Hashable {
private var id : Int
private var mutex = pthread_mutex_t()
private var cond = pthread_cond_t()
private let request : NSURLRequest!
private let subProtocols : [String]!
private var frames : [Frame] = []
private var delegate : Delegate
private var inflater : Inflater!
private var deflater : Deflater!
private var outputBytes : UnsafeMutablePointer<UInt8>
private var outputBytesSize : Int = 0
private var outputBytesStart : Int = 0
private var outputBytesLength : Int = 0
private var inputBytes : UnsafeMutablePointer<UInt8>
private var inputBytesSize : Int = 0
private var inputBytesStart : Int = 0
private var inputBytesLength : Int = 0
private var _eventQueue : dispatch_queue_t? = dispatch_get_main_queue()
private var _subProtocol = ""
private var _compression = WebSocketCompression()
private var _services = WebSocketService.None
private var _event = WebSocketEvents()
private var _binaryType = WebSocketBinaryType.UInt8Array
private var _readyState = WebSocketReadyState.Connecting
private var _networkTimeout = NSTimeInterval(-1)
private class InnerWebSocket: Hashable {
var id : Int
var mutex = pthread_mutex_t()
let request : NSURLRequest!
let subProtocols : [String]!
var frames : [Frame] = []
var delegate : Delegate
var inflater : Inflater!
var deflater : Deflater!
var outputBytes : UnsafeMutablePointer<UInt8>
var outputBytesSize : Int = 0
var outputBytesStart : Int = 0
var outputBytesLength : Int = 0
var inputBytes : UnsafeMutablePointer<UInt8>
var inputBytesSize : Int = 0
var inputBytesStart : Int = 0
var inputBytesLength : Int = 0
var createdAt = CFAbsoluteTimeGetCurrent()
var connectionTimeout = false
var _eventQueue : dispatch_queue_t? = dispatch_get_main_queue()
var _subProtocol = ""
var _compression = WebSocketCompression()
var _allowSelfSignedSSL = false
var _services = WebSocketService.None
var _event = WebSocketEvents()
var _binaryType = WebSocketBinaryType.UInt8Array
var _readyState = WebSocketReadyState.Connecting
var _networkTimeout = NSTimeInterval(-1)
/// The URL as resolved by the constructor. This is always an absolute URL. Read only.
public var url : String {
var url : String {
return request.URL!.description
}
/// A string indicating the name of the sub-protocol the server selected; this will be one of the strings specified in the protocols parameter when creating the WebSocket object.
public var subProtocol : String {
var subProtocol : String {
get { return privateSubProtocol }
}
private var privateSubProtocol : String {
var privateSubProtocol : String {
get { lock(); defer { unlock() }; return _subProtocol }
set { lock(); defer { unlock() }; _subProtocol = newValue }
}
/// The compression options of the WebSocket.
public var compression : WebSocketCompression {
var compression : WebSocketCompression {
get { lock(); defer { unlock() }; return _compression }
set { lock(); defer { unlock() }; _compression = newValue }
}
/// The services of the WebSocket.
public var services : WebSocketService {
var allowSelfSignedSSL : Bool {
get { lock(); defer { unlock() }; return _allowSelfSignedSSL }
set { lock(); defer { unlock() }; _allowSelfSignedSSL = newValue }
}
var services : WebSocketService {
get { lock(); defer { unlock() }; return _services }
set { lock(); defer { unlock() }; _services = newValue }
}
/// The events of the WebSocket.
public var event : WebSocketEvents {
var event : WebSocketEvents {
get { lock(); defer { unlock() }; return _event }
set { lock(); defer { unlock() }; _event = newValue }
}
/// The queue for firing off events. default is main_queue
public var eventQueue : dispatch_queue_t? {
var eventQueue : dispatch_queue_t? {
get { lock(); defer { unlock() }; return _eventQueue; }
set { lock(); defer { unlock() }; _eventQueue = newValue }
}
/// A WebSocketBinaryType value indicating the type of binary data being transmitted by the connection. Default is .UInt8Array.
public var binaryType : WebSocketBinaryType {
var binaryType : WebSocketBinaryType {
get { lock(); defer { unlock() }; return _binaryType }
set { lock(); defer { unlock() }; _binaryType = newValue }
}
/// The current state of the connection; this is one of the WebSocketReadyState constants. Read only.
public var readyState : WebSocketReadyState {
var readyState : WebSocketReadyState {
get { return privateReadyState }
}
private var privateReadyState : WebSocketReadyState {
var privateReadyState : WebSocketReadyState {
get { lock(); defer { unlock() }; return _readyState }
set { lock(); defer { unlock() }; _readyState = newValue }
}
public var hashValue: Int { return id }
func copyOpen(request: NSURLRequest, subProtocols : [String] = []) -> InnerWebSocket{
let ws = InnerWebSocket(request: request, subProtocols: subProtocols, stub: false)
ws.compression = compression
ws.allowSelfSignedSSL = allowSelfSignedSSL
ws.services = services
ws.event = event
ws.eventQueue = eventQueue
ws.binaryType = binaryType
return ws
}
var hashValue: Int { return id }
/// Create a WebSocket connection to a URL; this should be the URL to which the WebSocket server will respond.
public convenience init(_ url: String){
self.init(request: NSURLRequest(URL: NSURL(string: url)!), subProtocols: [])
}
/// Create a WebSocket connection to a URL; this should be the URL to which the WebSocket server will respond. Also include a list of protocols.
public convenience init(_ url: String, subProtocols : [String]){
self.init(request: NSURLRequest(URL: NSURL(string: url)!), subProtocols: subProtocols)
}
/// Create a WebSocket connection to a URL; this should be the URL to which the WebSocket server will respond. Also include a protocol.
public convenience init(_ url: String, subProtocol : String){
self.init(request: NSURLRequest(URL: NSURL(string: url)!), subProtocols: [subProtocol])
}
/// Create a WebSocket connection from an NSURLRequest; Also include a list of protocols.
public init(request: NSURLRequest, subProtocols : [String] = []){
init(request: NSURLRequest, subProtocols : [String] = [], stub : Bool = false){
pthread_mutex_init(&mutex, nil)
pthread_cond_init(&cond, nil)
self.id = manager.nextId()
self.request = request
self.subProtocols = subProtocols
@ -589,8 +586,14 @@ public class WebSocket: Hashable {
self.inputBytes = UnsafeMutablePointer<UInt8>.alloc(windowBufferSize)
self.inputBytesSize = windowBufferSize
self.delegate = Delegate()
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue()){
manager.add(self)
if stub{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue()){
self
}
} else {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue()){
manager.add(self)
}
}
}
deinit{
@ -600,7 +603,6 @@ public class WebSocket: Hashable {
if inputBytes != nil {
free(inputBytes)
}
pthread_cond_init(&cond, nil)
pthread_mutex_init(&mutex, nil)
}
@inline(__always) private func lock(){
@ -616,38 +618,47 @@ public class WebSocket: Hashable {
if exit {
return false
}
if connectionTimeout {
return true
}
if stage != .ReadResponse && stage != .HandleFrames {
return true
}
if rd.streamStatus == .Opening && wr.streamStatus == .Opening {
return false;
}
if rd.streamStatus != .Open || wr.streamStatus != .Open {
return true
}
if rd.streamError != nil || wr.streamError != nil {
return true
}
if rd.hasBytesAvailable || frames.count > 0 || inputBytesLength > 0 || outputBytesLength > 0 {
if rd.hasBytesAvailable || frames.count > 0 || inputBytesLength > 0 {
return true
}
if outputBytesLength > 0 && wr.hasSpaceAvailable{
return true
}
return false
}
private enum Stage : Int {
enum Stage : Int {
case OpenConn
case ReadResponse
case HandleFrames
case CloseConn
case End
}
private var stage = Stage.OpenConn
private var rd : NSInputStream!
private var wr : NSOutputStream!
private var atEnd = false
private var closeCode = UInt16(0)
private var closeReason = ""
private var closeClean = false
private var closeFinal = false
private var finalError : ErrorType?
private var exit = false
private func step(){
var stage = Stage.OpenConn
var rd : NSInputStream!
var wr : NSOutputStream!
var atEnd = false
var closeCode = UInt16(0)
var closeReason = ""
var closeClean = false
var closeFinal = false
var finalError : ErrorType?
var exit = false
func step(){
if exit {
return
}
@ -668,7 +679,7 @@ public class WebSocket: Hashable {
case .HandleFrames:
try stepOutputFrames()
if closeFinal {
privateReadyState == .Closing
privateReadyState = .Closing
stage = .CloseConn
return
}
@ -711,7 +722,7 @@ public class WebSocket: Hashable {
if let error = finalError {
self.event.error(error: error)
}
privateReadyState == .Closed
privateReadyState = .Closed
if rd != nil {
closeConn()
fire {
@ -776,7 +787,7 @@ public class WebSocket: Hashable {
}
}
}
private func stepBuffers() throws {
func stepBuffers() throws {
if rd != nil {
if rd.streamStatus == NSStreamStatus.AtEnd {
if atEnd {
@ -815,8 +826,11 @@ public class WebSocket: Hashable {
}
}
}
private func stepStreamErrors() throws {
func stepStreamErrors() throws {
if finalError == nil {
if connectionTimeout {
throw WebSocketError.Network(timeoutDetails)
}
if let error = rd?.streamError {
throw WebSocketError.Network(error.localizedDescription)
}
@ -825,7 +839,7 @@ public class WebSocket: Hashable {
}
}
}
private func stepOutputFrames() throws {
func stepOutputFrames() throws {
lock()
defer {
frames = []
@ -843,7 +857,7 @@ public class WebSocket: Hashable {
}
}
}
@inline(__always) private func fire(block: ()->()){
@inline(__always) func fire(block: ()->()){
if let queue = eventQueue {
dispatch_sync(queue) {
block()
@ -853,11 +867,11 @@ public class WebSocket: Hashable {
}
}
private var readStateSaved = false
private var readStateFrame : Frame?
private var readStateFinished = false
private var leaderFrame : Frame?
private func readFrame() throws -> Frame {
var readStateSaved = false
var readStateFrame : Frame?
var readStateFinished = false
var leaderFrame : Frame?
func readFrame() throws -> Frame {
var frame : Frame
var finished : Bool
if !readStateSaved {
@ -908,7 +922,7 @@ public class WebSocket: Hashable {
return frame
}
private func closeConn() {
func closeConn() {
rd.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
wr.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
rd.delegate = nil
@ -917,7 +931,7 @@ public class WebSocket: Hashable {
wr.close()
}
private func openConn() throws {
func openConn() throws {
let req = request.mutableCopy() as! NSMutableURLRequest
req.setValue("websocket", forHTTPHeaderField: "Upgrade")
req.setValue("Upgrade", forHTTPHeaderField: "Connection")
@ -992,7 +1006,11 @@ public class WebSocket: Hashable {
throw WebSocketError.InvalidAddress
}
var (rdo, wro) : (NSInputStream?, NSOutputStream?)
NSStream.getStreamsToHostWithName(addr[0], port: Int(addr[1])!, inputStream: &rdo, outputStream: &wro)
var readStream: Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?
CFStreamCreatePairWithSocketToHost(nil, addr[0], UInt32(Int(addr[1])!), &readStream, &writeStream);
rdo = readStream!.takeRetainedValue()
wro = writeStream!.takeRetainedValue()
(rd, wr) = (rdo!, wro!)
let securityLevel : String
switch security {
@ -1019,6 +1037,11 @@ public class WebSocket: Hashable {
rd.setProperty(NSStreamNetworkServiceTypeVoice, forKey: NSStreamNetworkServiceType)
wr.setProperty(NSStreamNetworkServiceTypeVoice, forKey: NSStreamNetworkServiceType)
}
if allowSelfSignedSSL {
let prop: Dictionary<NSObject,NSObject> = [kCFStreamSSLPeerName: kCFNull, kCFStreamSSLValidatesCertificateChain: NSNumber(bool: false)]
rd.setProperty(prop, forKey: kCFStreamPropertySSLSettings as String)
wr.setProperty(prop, forKey: kCFStreamPropertySSLSettings as String)
}
rd.delegate = delegate
wr.delegate = delegate
rd.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
@ -1028,7 +1051,7 @@ public class WebSocket: Hashable {
try write(header, length: header.count)
}
private func write(bytes: UnsafePointer<UInt8>, length: Int) throws {
func write(bytes: UnsafePointer<UInt8>, length: Int) throws {
if outputBytesStart+outputBytesLength+length > outputBytesSize {
var size = outputBytesSize
while outputBytesStart+outputBytesLength+length > size {
@ -1045,7 +1068,7 @@ public class WebSocket: Hashable {
outputBytesLength += length
}
private func readResponse() throws {
func readResponse() throws {
let end : [UInt8] = [ 0x0D, 0x0A, 0x0D, 0x0A ]
let ptr = UnsafeMutablePointer<UInt8>(memmem(inputBytes+inputBytesStart, inputBytesLength, end, 4))
if ptr == nil {
@ -1126,7 +1149,7 @@ public class WebSocket: Hashable {
}
}
private class ByteReader {
class ByteReader {
var start : UnsafePointer<UInt8>
var end : UnsafePointer<UInt8>
var bytes : UnsafePointer<UInt8>
@ -1156,20 +1179,20 @@ public class WebSocket: Hashable {
}
}
private var fragStateSaved = false
private var fragStatePosition = 0
private var fragStateInflate = false
private var fragStateLen = 0
private var fragStateFin = false
private var fragStateCode = OpCode.Continue
private var fragStateLeaderCode = OpCode.Continue
private var fragStateUTF8 = UTF8()
private var fragStatePayload = Payload()
private var fragStateStatusCode = UInt16(0)
private var fragStateHeaderLen = 0
private var buffer = [UInt8](count: windowBufferSize, repeatedValue: 0)
private var reusedPayload = Payload()
private func readFrameFragment(var leader : Frame?) throws -> Frame {
var fragStateSaved = false
var fragStatePosition = 0
var fragStateInflate = false
var fragStateLen = 0
var fragStateFin = false
var fragStateCode = OpCode.Continue
var fragStateLeaderCode = OpCode.Continue
var fragStateUTF8 = UTF8()
var fragStatePayload = Payload()
var fragStateStatusCode = UInt16(0)
var fragStateHeaderLen = 0
var buffer = [UInt8](count: windowBufferSize, repeatedValue: 0)
var reusedPayload = Payload()
func readFrameFragment(var leader : Frame?) throws -> Frame {
var inflate : Bool
var len : Int
var fin = false
@ -1337,8 +1360,8 @@ public class WebSocket: Hashable {
return f
}
private var head = [UInt8](count: 0xFF, repeatedValue: 0)
private func writeFrame(f : Frame) throws {
var head = [UInt8](count: 0xFF, repeatedValue: 0)
func writeFrame(f : Frame) throws {
if !f.finished{
throw WebSocketError.LibraryError("cannot send unfinished frames")
}
@ -1406,32 +1429,20 @@ public class WebSocket: Hashable {
try write(head, length: hlen)
try write(payloadBytes, length: payloadBytes.count)
}
/**
Closes the WebSocket connection or connection attempt, if any. If the connection is already closed or in the state of closing, this method does nothing.
:param: code An integer indicating the status code explaining why the connection is being closed. If this parameter is not specified, a default value of 1000 (indicating a normal closure) is assumed.
:param: reason A human-readable string explaining why the connection is closing. This string must be no longer than 123 bytes of UTF-8 text (not characters).
*/
public func close(code : Int = 1000, reason : String = "Normal Closure") {
func close(code : Int = 1000, reason : String = "Normal Closure") {
let f = Frame()
f.code = .Close
f.statusCode = UInt16(truncatingBitPattern: code)
f.utf8.text = reason
sendFrame(f)
}
private func sendFrame(f : Frame) {
func sendFrame(f : Frame) {
lock()
frames += [f]
unlock()
manager.signal()
}
/**
Transmits message to the server over the WebSocket connection.
:param: message The data to be sent to the server.
*/
public func send(message : Any) {
func send(message : Any) {
let f = Frame()
if let message = message as? String {
f.code = .Text
@ -1451,20 +1462,12 @@ public class WebSocket: Hashable {
}
sendFrame(f)
}
/**
Transmits a ping to the server over the WebSocket connection.
*/
public func ping() {
func ping() {
let f = Frame()
f.code = .Ping
sendFrame(f)
}
/**
Transmits a ping to the server over the WebSocket connection.
:param: optional message The data to be sent to the server.
*/
public func ping(message : Any){
func ping(message : Any){
let f = Frame()
f.code = .Ping
if let message = message as? String {
@ -1481,7 +1484,7 @@ public class WebSocket: Hashable {
sendFrame(f)
}
}
public func ==(lhs: WebSocket, rhs: WebSocket) -> Bool {
private func ==(lhs: InnerWebSocket, rhs: InnerWebSocket) -> Bool {
return lhs.id == rhs.id
}
@ -1497,13 +1500,13 @@ private class Manager {
var once = dispatch_once_t()
var mutex = pthread_mutex_t()
var cond = pthread_cond_t()
var websockets = Set<WebSocket>()
var websockets = Set<InnerWebSocket>()
var _nextId = 0
init(){
pthread_mutex_init(&mutex, nil)
pthread_cond_init(&cond, nil)
dispatch_async(dispatch_queue_create("SwiftWebSocket", nil)) {
var wss : [WebSocket] = []
var wss : [InnerWebSocket] = []
for ;; {
var wait = true
wss.removeAll()
@ -1512,6 +1515,7 @@ private class Manager {
wss.append(ws)
}
for ws in wss {
self.checkForConnectionTimeout(ws)
if ws.dirty {
pthread_mutex_unlock(&self.mutex)
ws.step()
@ -1520,24 +1524,44 @@ private class Manager {
}
}
if wait {
pthread_cond_wait(&self.cond, &self.mutex)
self.wait(250)
}
pthread_mutex_unlock(&self.mutex)
}
}
}
func checkForConnectionTimeout(ws : InnerWebSocket) {
if ws.rd != nil && ws.wr != nil && (ws.rd.streamStatus == .Opening || ws.wr.streamStatus == .Opening) {
let age = CFAbsoluteTimeGetCurrent() - ws.createdAt
if age >= timeoutDuration {
ws.connectionTimeout = true
}
}
}
func wait(timeInMs : Int) -> Int32 {
var ts = timespec()
var tv = timeval()
gettimeofday(&tv, nil)
ts.tv_sec = time(nil) + timeInMs / 1000;
let v1 = Int(tv.tv_usec * 1000)
let v2 = Int(1000 * 1000 * Int(timeInMs % 1000))
ts.tv_nsec = v1 + v2;
ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000);
ts.tv_nsec %= (1000 * 1000 * 1000);
return pthread_cond_timedwait(&self.cond, &self.mutex, &ts)
}
func signal(){
pthread_mutex_lock(&mutex)
pthread_cond_signal(&cond)
pthread_mutex_unlock(&mutex)
}
func add(websocket: WebSocket) {
func add(websocket: InnerWebSocket) {
pthread_mutex_lock(&mutex)
websockets.insert(websocket)
pthread_cond_signal(&cond)
pthread_mutex_unlock(&mutex)
}
func remove(websocket: WebSocket) {
func remove(websocket: InnerWebSocket) {
pthread_mutex_lock(&mutex)
websockets.remove(websocket)
pthread_cond_signal(&cond)
@ -1551,3 +1575,144 @@ private class Manager {
}
private let manager = Manager()
/// WebSocket objects are bidirectional network streams that communicate over HTTP. RFC 6455.
public class WebSocket: Hashable {
private var ws : InnerWebSocket
private var id = manager.nextId()
private var opened : Bool
public var hashValue: Int { return id }
/// Create a WebSocket connection to a URL; this should be the URL to which the WebSocket server will respond.
public convenience init(_ url: String){
self.init(request: NSURLRequest(URL: NSURL(string: url)!), subProtocols: [])
}
/// Create a WebSocket connection to a URL; this should be the URL to which the WebSocket server will respond. Also include a list of protocols.
public convenience init(_ url: String, subProtocols : [String]){
self.init(request: NSURLRequest(URL: NSURL(string: url)!), subProtocols: subProtocols)
}
/// Create a WebSocket connection to a URL; this should be the URL to which the WebSocket server will respond. Also include a protocol.
public convenience init(_ url: String, subProtocol : String){
self.init(request: NSURLRequest(URL: NSURL(string: url)!), subProtocols: [subProtocol])
}
/// Create a WebSocket connection from an NSURLRequest; Also include a list of protocols.
public init(request: NSURLRequest, subProtocols : [String] = []){
opened = true
ws = InnerWebSocket(request: request, subProtocols: subProtocols, stub: false)
}
/// Create a WebSocket object with a deferred connection; the connection is not opened until the .open() method is called.
public init(){
opened = false
ws = InnerWebSocket(request: NSURLRequest(), subProtocols: [], stub: true)
}
/// The URL as resolved by the constructor. This is always an absolute URL. Read only.
public var url : String{ return ws.url }
/// A string indicating the name of the sub-protocol the server selected; this will be one of the strings specified in the protocols parameter when creating the WebSocket object.
public var subProtocol : String{ return ws.subProtocol }
/// The compression options of the WebSocket.
public var compression : WebSocketCompression{
get { return ws.compression }
set { ws.compression = newValue }
}
/// Allow for Self-Signed SSL Certificates. Default is false.
public var allowSelfSignedSSL : Bool{
get { return ws.allowSelfSignedSSL }
set { ws.allowSelfSignedSSL = newValue }
}
/// The services of the WebSocket.
public var services : WebSocketService{
get { return ws.services }
set { ws.services = newValue }
}
/// The events of the WebSocket.
public var event : WebSocketEvents{
get { return ws.event }
set { ws.event = newValue }
}
/// The queue for firing off events. default is main_queue
public var eventQueue : dispatch_queue_t?{
get { return ws.eventQueue }
set { ws.eventQueue = newValue }
}
/// A WebSocketBinaryType value indicating the type of binary data being transmitted by the connection. Default is .UInt8Array.
public var binaryType : WebSocketBinaryType{
get { return ws.binaryType }
set { ws.binaryType = newValue }
}
/// The current state of the connection; this is one of the WebSocketReadyState constants. Read only.
public var readyState : WebSocketReadyState{
return ws.readyState
}
/// Opens a deferred or closed WebSocket connection to a URL; this should be the URL to which the WebSocket server will respond.
public func open(url: String){
open(NSURLRequest(URL: NSURL(string: url)!), subProtocols: [])
}
/// Opens a deferred or closed WebSocket connection to a URL; this should be the URL to which the WebSocket server will respond. Also include a list of protocols.
public func open(url: String, subProtocols : [String]){
open(NSURLRequest(URL: NSURL(string: url)!), subProtocols: subProtocols)
}
/// Opens a deferred or closed WebSocket connection to a URL; this should be the URL to which the WebSocket server will respond. Also include a protocol.
public func open(url: String, subProtocol : String){
open(NSURLRequest(URL: NSURL(string: url)!), subProtocols: [subProtocol])
}
/// Opens a deferred or closed WebSocket connection from an NSURLRequest; Also include a list of protocols.
public func open(request: NSURLRequest, subProtocols : [String] = []){
if opened{
return
}
opened = true
ws = ws.copyOpen(request, subProtocols: subProtocols)
}
/// Opens a closed WebSocket connection from an NSURLRequest; Uses the same request and protocols as previously closed WebSocket
public func open(){
open(ws.request, subProtocols: ws.subProtocols)
}
/**
Closes the WebSocket connection or connection attempt, if any. If the connection is already closed or in the state of closing, this method does nothing.
:param: code An integer indicating the status code explaining why the connection is being closed. If this parameter is not specified, a default value of 1000 (indicating a normal closure) is assumed.
:param: reason A human-readable string explaining why the connection is closing. This string must be no longer than 123 bytes of UTF-8 text (not characters).
*/
public func close(code : Int = 1000, reason : String = "Normal Closure"){
if !opened{
return
}
opened = false
ws.close(code, reason: reason)
}
/**
Transmits message to the server over the WebSocket connection.
:param: message The data to be sent to the server.
*/
public func send(message : Any){
if !opened{
return
}
ws.send(message)
}
/**
Transmits a ping to the server over the WebSocket connection.
:param: optional message The data to be sent to the server.
*/
public func ping(message : Any){
if !opened{
return
}
ws.ping(message)
}
/**
Transmits a ping to the server over the WebSocket connection.
*/
public func ping(){
if !opened{
return
}
ws.ping()
}
}
public func ==(lhs: WebSocket, rhs: WebSocket) -> Bool {
return lhs.id == rhs.id
}

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "SwiftWebSocket"
s.version = "2.1.0"
s.version = "2.2.0"
s.summary = "A high performance WebSocket client library for Swift."
s.homepage = "https://github.com/tidwall/SwiftWebSocket"
s.license = { :type => "Attribution License", :file => "LICENSE" }

View File

@ -10,16 +10,41 @@
031967101B4D96C40033860E /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03285D2A1B4A9F1A0078A1AA /* WebSocket.swift */; };
03285D2B1B4A9F1A0078A1AA /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03285D2A1B4A9F1A0078A1AA /* WebSocket.swift */; };
03D1E7221B208A5C00AC49AC /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 03D1E7211B208A5C00AC49AC /* libz.dylib */; };
03D70CD11BDAC5EC00D245C3 /* SwiftWebSocket.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D71949011B35E6130015C529 /* SwiftWebSocket.framework */; };
03D70CE01BDAC63600D245C3 /* SwiftWebSocket.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03D1E7031B20897100AC49AC /* SwiftWebSocket.framework */; };
03D70CEC1BDAC70B00D245C3 /* Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D70CE91BDAC70100D245C3 /* Test.swift */; };
03D70CED1BDAC70C00D245C3 /* Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D70CE91BDAC70100D245C3 /* Test.swift */; };
D71948F51B35E5670015C529 /* SwiftWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = D71948F11B35E5670015C529 /* SwiftWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };
D719491A1B35E6640015C529 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D71948FA1B35E59D0015C529 /* libz.dylib */; };
D719491B1B35E7510015C529 /* SwiftWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = D71948F11B35E5670015C529 /* SwiftWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
03D70CD21BDAC5EC00D245C3 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 03D1E6FA1B20897100AC49AC /* Project object */;
proxyType = 1;
remoteGlobalIDString = D71949001B35E6130015C529;
remoteInfo = "SwiftWebSocket-OSX";
};
03D70CE11BDAC63600D245C3 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 03D1E6FA1B20897100AC49AC /* Project object */;
proxyType = 1;
remoteGlobalIDString = 03D1E7021B20897100AC49AC;
remoteInfo = "SwiftWebSocket-iOS";
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
0319670F1B4D96B80033860E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
03285D2A1B4A9F1A0078A1AA /* WebSocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebSocket.swift; sourceTree = "<group>"; };
03D1E7031B20897100AC49AC /* SwiftWebSocket.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftWebSocket.framework; sourceTree = BUILT_PRODUCTS_DIR; };
03D1E7211B208A5C00AC49AC /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
03D70CCC1BDAC5EC00D245C3 /* Test-OSX.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Test-OSX.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
03D70CDB1BDAC63600D245C3 /* Test-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Test-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
03D70CE81BDAC70100D245C3 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
03D70CE91BDAC70100D245C3 /* Test.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Test.swift; sourceTree = "<group>"; };
D71948F11B35E5670015C529 /* SwiftWebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SwiftWebSocket.h; sourceTree = "<group>"; };
D71948FA1B35E59D0015C529 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
D71949011B35E6130015C529 /* SwiftWebSocket.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftWebSocket.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@ -34,6 +59,22 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
03D70CC91BDAC5EC00D245C3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
03D70CD11BDAC5EC00D245C3 /* SwiftWebSocket.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
03D70CD81BDAC63600D245C3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
03D70CE01BDAC63600D245C3 /* SwiftWebSocket.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D71948FD1B35E6130015C529 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -51,6 +92,7 @@
D71948FA1B35E59D0015C529 /* libz.dylib */,
03D1E7211B208A5C00AC49AC /* libz.dylib */,
D71948F01B35E5670015C529 /* Source */,
03D70CE71BDAC70100D245C3 /* Test */,
03D1E7041B20897100AC49AC /* Products */,
);
sourceTree = "<group>";
@ -60,10 +102,21 @@
children = (
03D1E7031B20897100AC49AC /* SwiftWebSocket.framework */,
D71949011B35E6130015C529 /* SwiftWebSocket.framework */,
03D70CCC1BDAC5EC00D245C3 /* Test-OSX.xctest */,
03D70CDB1BDAC63600D245C3 /* Test-iOS.xctest */,
);
name = Products;
sourceTree = "<group>";
};
03D70CE71BDAC70100D245C3 /* Test */ = {
isa = PBXGroup;
children = (
03D70CE81BDAC70100D245C3 /* Info.plist */,
03D70CE91BDAC70100D245C3 /* Test.swift */,
);
path = Test;
sourceTree = "<group>";
};
D71948F01B35E5670015C529 /* Source */ = {
isa = PBXGroup;
children = (
@ -114,6 +167,42 @@
productReference = 03D1E7031B20897100AC49AC /* SwiftWebSocket.framework */;
productType = "com.apple.product-type.framework";
};
03D70CCB1BDAC5EC00D245C3 /* Test-OSX */ = {
isa = PBXNativeTarget;
buildConfigurationList = 03D70CD61BDAC5EC00D245C3 /* Build configuration list for PBXNativeTarget "Test-OSX" */;
buildPhases = (
03D70CC81BDAC5EC00D245C3 /* Sources */,
03D70CC91BDAC5EC00D245C3 /* Frameworks */,
03D70CCA1BDAC5EC00D245C3 /* Resources */,
);
buildRules = (
);
dependencies = (
03D70CD31BDAC5EC00D245C3 /* PBXTargetDependency */,
);
name = "Test-OSX";
productName = "Test-OSX";
productReference = 03D70CCC1BDAC5EC00D245C3 /* Test-OSX.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
03D70CDA1BDAC63600D245C3 /* Test-iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 03D70CE31BDAC63600D245C3 /* Build configuration list for PBXNativeTarget "Test-iOS" */;
buildPhases = (
03D70CD71BDAC63600D245C3 /* Sources */,
03D70CD81BDAC63600D245C3 /* Frameworks */,
03D70CD91BDAC63600D245C3 /* Resources */,
);
buildRules = (
);
dependencies = (
03D70CE21BDAC63600D245C3 /* PBXTargetDependency */,
);
name = "Test-iOS";
productName = "Test-iOS";
productReference = 03D70CDB1BDAC63600D245C3 /* Test-iOS.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
D71949001B35E6130015C529 /* SwiftWebSocket-OSX */ = {
isa = PBXNativeTarget;
buildConfigurationList = D71949141B35E6160015C529 /* Build configuration list for PBXNativeTarget "SwiftWebSocket-OSX" */;
@ -138,13 +227,19 @@
03D1E6FA1B20897100AC49AC /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastSwiftUpdateCheck = 0710;
LastUpgradeCheck = 0700;
ORGANIZATIONNAME = "ONcast, LLC";
TargetAttributes = {
03D1E7021B20897100AC49AC = {
CreatedOnToolsVersion = 6.3.2;
};
03D70CCB1BDAC5EC00D245C3 = {
CreatedOnToolsVersion = 7.1;
};
03D70CDA1BDAC63600D245C3 = {
CreatedOnToolsVersion = 7.1;
};
D71949001B35E6130015C529 = {
CreatedOnToolsVersion = 6.3.2;
};
@ -164,6 +259,8 @@
targets = (
03D1E7021B20897100AC49AC /* SwiftWebSocket-iOS */,
D71949001B35E6130015C529 /* SwiftWebSocket-OSX */,
03D70CCB1BDAC5EC00D245C3 /* Test-OSX */,
03D70CDA1BDAC63600D245C3 /* Test-iOS */,
);
};
/* End PBXProject section */
@ -176,6 +273,20 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
03D70CCA1BDAC5EC00D245C3 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
03D70CD91BDAC63600D245C3 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D71948FF1B35E6130015C529 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -194,6 +305,22 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
03D70CC81BDAC5EC00D245C3 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
03D70CEC1BDAC70B00D245C3 /* Test.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
03D70CD71BDAC63600D245C3 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
03D70CED1BDAC70C00D245C3 /* Test.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D71948FC1B35E6130015C529 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -204,6 +331,19 @@
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
03D70CD31BDAC5EC00D245C3 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D71949001B35E6130015C529 /* SwiftWebSocket-OSX */;
targetProxy = 03D70CD21BDAC5EC00D245C3 /* PBXContainerItemProxy */;
};
03D70CE21BDAC63600D245C3 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 03D1E7021B20897100AC49AC /* SwiftWebSocket-iOS */;
targetProxy = 03D70CE11BDAC63600D245C3 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
03D1E7171B20897100AC49AC /* Debug */ = {
isa = XCBuildConfiguration;
@ -331,6 +471,58 @@
};
name = Release;
};
03D70CD41BDAC5EC00D245C3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
INFOPLIST_FILE = Test/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_BUNDLE_IDENTIFIER = com.oncast.SwiftWebSocketTest;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
};
name = Debug;
};
03D70CD51BDAC5EC00D245C3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Test/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_BUNDLE_IDENTIFIER = com.oncast.SwiftWebSocketTest;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
};
name = Release;
};
03D70CE41BDAC63600D245C3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
DEBUG_INFORMATION_FORMAT = dwarf;
INFOPLIST_FILE = Test/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.oncast.SwiftWebSocketTest;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
03D70CE51BDAC63600D245C3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
INFOPLIST_FILE = Test/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.oncast.SwiftWebSocketTest;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
D71949151B35E6160015C529 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -401,6 +593,22 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
03D70CD61BDAC5EC00D245C3 /* Build configuration list for PBXNativeTarget "Test-OSX" */ = {
isa = XCConfigurationList;
buildConfigurations = (
03D70CD41BDAC5EC00D245C3 /* Debug */,
03D70CD51BDAC5EC00D245C3 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
03D70CE31BDAC63600D245C3 /* Build configuration list for PBXNativeTarget "Test-iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
03D70CE41BDAC63600D245C3 /* Debug */,
03D70CE51BDAC63600D245C3 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
D71949141B35E6160015C529 /* Build configuration list for PBXNativeTarget "SwiftWebSocket-OSX" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@ -1,286 +0,0 @@
import Foundation
let baseURL = "ws://localhost:9001"
let agent = "SwiftWebSocket"
let debug = false
let keepStatsUpdated = false
let stopOnFailure = false
let stopOnInfo = false
let stopAfterOne = false
let showDuration = false
let startCase = 1
let stopAtCase = 999
private enum ErrCode : Int, CustomStringConvertible {
case Protocol = 1002, Payload = 1007, Undefined = -100, Codepoint = -101, Library = -102, Socket = -103
var description : String {
switch self {
case Protocol: return "Protocol error"
case Payload: return "Invalid payload data"
case Codepoint: return "Invalid codepoint"
case Library: return "Library error"
case Undefined: return "Undefined error"
case Socket: return "Broken socket"
}
}
}
private func makeError(error : String, _ code: ErrCode) -> ErrorType {
return NSError(domain: "com.github.tidwall.WebSocketConn", code: code.rawValue, userInfo: [NSLocalizedDescriptionKey:"\(error)"])
}
private func makeError(error : ErrorType, _ code: ErrCode) -> ErrorType {
let err = error as NSError
return NSError(domain: err.domain, code: code.rawValue, userInfo: [NSLocalizedDescriptionKey:"\(err.localizedDescription)"])
}
private func makeError(error : String) -> ErrorType {
return makeError(error, ErrCode.Library)
}
private func jsonObject(text : String) throws -> [String: AnyObject] {
if let data = text.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false),
let json = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as? [String : AnyObject] {
return json
}
throw makeError("not json")
}
// autobahn api
func getCaseCount(block:(count : Int, error : ErrorType?)->()){
let ws = WebSocket(baseURL + "/getCaseCount")
ws.event.message = { (msg) in
if let text = msg as? String {
ws.close()
if let i = Int(text) {
block(count: i, error: nil)
} else {
block(count: 0, error: makeError("invalid response"))
}
}
}
ws.event.error = { error in
block(count: 0, error: error)
}
}
func getCaseInfo(caseIdx : Int, block :(id : String, description : String, error : ErrorType?)->()){
let ws = WebSocket(baseURL + "/getCaseInfo?case=\(caseIdx+1)")
ws.event.message = { (msg) in
if let text = msg as? String {
ws.close()
do {
let json = try jsonObject(text)
if json["id"] == nil || json["description"] == nil {
block(id: "", description: "", error: makeError("invalid response"))
}
block(id: json["id"] as! String, description: json["description"] as! String, error: nil)
} catch {
block(id: "", description: "", error: error)
}
}
}
ws.event.error = { error in
block(id: "", description: "", error: error)
}
}
func getCaseStatus(caseIdx : Int, block : (error : ErrorType?)->()){
var responseText = ""
let ws = WebSocket(baseURL + "/getCaseStatus?case=\(caseIdx+1)&agent=\(agent)")
ws.event.error = { error in
block(error: error)
}
ws.event.message = { (msg) in
if let text = msg as? String {
responseText = text
ws.close()
}
}
ws.event.close = { (code, reason, clean) in
do {
let json = try jsonObject(responseText)
if let behavior = json["behavior"] as? String {
if behavior == "OK" {
block(error: nil)
} else if behavior == "FAILED"{
block(error: makeError(""))
} else {
block(error: makeError(behavior))
}
return
}
} catch {
block(error: error)
}
}
}
func updateReports(echo: Bool = false, block : ()->()){
var success = false
let ws = WebSocket(baseURL + "/updateReports?agent=\(agent)")
ws.event.close = { (code, reason, clean) in
if echo {
if !success{
print("[ERR] reports failed to update")
exit(1)
}
}
block()
}
ws.event.open = {
ws.close()
success = true
}
}
func runCase(caseIdx : Int, caseCount : Int, block : (error : ErrorType?)->()) {
// var start = NSDate().timeIntervalSince1970
// var evstart = NSTimeInterval(0)
getCaseInfo(caseIdx, block: { (id, description, error) in
if error != nil{
print("[ERR] getCaseInfo failed: \(error!)\n")
exit(1)
}
var next = { ()->() in }
print("[CASE] #\(caseIdx+1)/\(caseCount): \(id): \(description)")
let failed : (message : String)->() = { (message) in
let error = makeError(message)
printFailure(error)
if stopOnFailure {
block(error: error)
} else {
next()
}
}
let warn : (message : String)->() = { (message) in
printFailure(makeError(message))
}
next = { ()->() in
// if showDuration {
// let now = NSDate().timeIntervalSince1970
// let recv = evstart == 0 ? 0 : (evstart - start) * 1000
// let total = (now - start) * 1000
// let send = total - recv
// println("[DONE] %.0f ms (recv: %.0f ms, send: %.0f ms)", total, recv, send)
// }
getCaseStatus(caseIdx){ error in
let f : ()->() = {
if let error = error as? NSError {
if error.localizedDescription == "INFORMATIONAL" {
if stopOnInfo {
failed(message : error.localizedDescription)
return
}
} else if stopOnFailure {
failed(message : error.localizedDescription)
return
}
warn(message : error.localizedDescription)
}
if caseIdx+1 == caseCount || stopAfterOne || (caseIdx+1 == stopAtCase){
block(error: nil)
} else {
runCase(caseIdx+1, caseCount: caseCount, block: block)
}
}
if keepStatsUpdated || caseIdx % 10 == 0 {
updateReports(false, block: f)
} else {
f()
}
}
}
var responseError : ErrorType?
//print(baseURL + "/runCase?case=\(caseIdx+1)&agent=\(agent)")
let ws = WebSocket(baseURL + "/runCase?case=\(caseIdx+1)&agent=\(agent)")
ws.eventQueue = nil
ws.binaryType = .UInt8UnsafeBufferPointer
if id.hasPrefix("13.") || id.hasPrefix("12.") {
ws.compression.on = true
if id.hasPrefix("13.1"){
ws.compression.noContextTakeover = false
ws.compression.maxWindowBits = 0
}
if id.hasPrefix("13.2"){
ws.compression.noContextTakeover = true
ws.compression.maxWindowBits = 0
}
if id.hasPrefix("13.3"){
ws.compression.noContextTakeover = false
ws.compression.maxWindowBits = 8
}
if id.hasPrefix("13.4"){
ws.compression.noContextTakeover = false
ws.compression.maxWindowBits = 15
}
if id.hasPrefix("13.5"){
ws.compression.noContextTakeover = true
ws.compression.maxWindowBits = 8
}
if id.hasPrefix("13.6"){
ws.compression.noContextTakeover = true
ws.compression.maxWindowBits = 15
}
if id.hasPrefix("13.7"){
ws.compression.noContextTakeover = true
ws.compression.maxWindowBits = 8
}
}
ws.event.end = { (code, reason, clean, error) in
responseError = error
if responseError == nil {
next()
} else {
var message = ""
if let error = responseError as? NSError {
message += error.localizedDescription
}
if code != 0 {
message += " with code '\(code)' and reason '\(reason)'"
}
failed(message: message)
}
}
ws.event.message = { (msg) in
// evstart = NSDate().timeIntervalSince1970
ws.send(msg)
}
})
}
func printFailure(error : ErrorType?){
let error = error as? NSError
if error == nil || error!.localizedDescription == "" {
print("[ERR] FAILED")
exit(1)
} else {
if error!.localizedDescription == "INFORMATIONAL" {
//printinfo("INFORMATIONAL")
} else {
print("[ERR] FAILED: \(error!.localizedDescription)")
}
}
}
getCaseCount { (count, error) in
if error != nil{
print("[ERR] getCaseCount failed: \(error!)")
exit(1)
}
runCase(startCase-1, caseCount: count){ (error) in
if error == nil{
updateReports(true){
exit(0)
}
} else {
updateReports(true){
exit(1)
}
}
}
}
NSRunLoop.mainRunLoop().run()

View File

@ -1,22 +0,0 @@
#!/bin/bash
set -e
cd $(dirname "${BASH_SOURCE[0]}")
git checkout gh-pages
cleanup() {
git checkout master
}
trap cleanup EXIT
if [ -f "reports/build.png" ]; then
cp -rf reports/build.png ../build.png
git add ../build.png
fi
if [ -d "reports/clients/" ]; then
cp -rf reports/clients/ ../results/
git add ../results/
fi
git commit -m 'updated result'
git push

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -1,46 +0,0 @@
#!/bin/bash
cd $(dirname "${BASH_SOURCE[0]}")
WSTEST=$(ls $HOME/Library/Python/2.*/bin/wstest 2>/dev/null)
set -e
if [ ! -f "$WSTEST" ] || [ "$UPGRADE" == "1" ]; then
pip install --user --upgrade unittest2
pip install --user --upgrade autobahntestsuite
WSTEST=$(ls $HOME/Library/Python/2.*/bin/wstest)
fi
if [ "$SERVER" == "1" ]; then
$WSTEST -m fuzzingserver
exit
fi
if [ "$CLIENT" != "1" ]; then
$WSTEST -m fuzzingserver &
WSTEST_PID=$!
cleanup() {
kill $WSTEST_PID
if [ "$SUCCESS" == "1" ]; then
cp -f res/passing.png reports/build.png
printf "\033[0;32m[SUCCESS]\033[0m\n"
else
if [ -d "reports/clients/" ]; then
cp -f res/failing.png reports/build.png
printf "\033[0;31m[FAILURE]\033[0m\n"
else
printf "\033[0;31m[FAILURE]\033[0m Cancelled Early\n"
exit
fi
fi
printf "\033[0;33mDon't forget to run 'test/gh-pages.sh' to process the results.\033[0m\n"
}
trap cleanup EXIT
sleep 1
fi
printf "\033[0;33m[BUILDING]\033[0m\n"
rm -fr reports
mkdir -p reports
mkdir -p /tmp/SwiftWebSocket/tests
cat ../Source/WebSocket.swift > /tmp/SwiftWebSocket/tests/main.swift
echo "" >> /tmp/SwiftWebSocket/tests/main.swift
cat autobahn.swift >> /tmp/SwiftWebSocket/tests/main.swift
swift -Ounchecked /tmp/SwiftWebSocket/tests/main.swift
SUCCESS=1

View File

@ -1,3 +0,0 @@
pkg/
bin/
src/

View File

@ -1,7 +0,0 @@
#!/bin/bash
export GOPATH=$(cd $(dirname "${BASH_SOURCE[0]}"); pwd)
cd $GOPATH
go get "github.com/gorilla/websocket"
go run server.go

View File

@ -1,76 +0,0 @@
package main
import (
"github.com/gorilla/websocket"
"log"
"net/http"
)
func main() {
http.HandleFunc("/client", client)
http.HandleFunc("/echo", socket)
log.Print("Running server on port 6789")
log.Print("ws://localhost:6789/client (javascript test client)")
log.Print("ws://localhost:6789/echo (echo socket)")
http.ListenAndServe(":6789", nil)
}
func socket(w http.ResponseWriter, r *http.Request) {
log.Print("connection established")
ws, err := websocket.Upgrade(w, r, nil, 1024, 1024)
if err != nil {
log.Print(err)
return
}
defer func() {
ws.Close()
log.Print("connection closed")
}()
for {
msgt, msg, err := ws.ReadMessage()
if err != nil {
log.Print(err)
return
}
log.Print("rcvd: '" + string(msg) + "'")
ws.WriteMessage(msgt, msg)
}
}
func client(w http.ResponseWriter, r *http.Request) {
log.Print("client request")
w.Header().Set("Content-Type", "text/html")
w.Write([]byte(`
Open the Javascript Console
<script>
var messageNum = 0;
var ws = new WebSocket("ws://localhost:6789/echo")
function send(){
messageNum++;
var msg = messageNum + ": " + new Date()
console.log("send: " + msg)
ws.send(msg)
}
ws.onopen = function(){
console.log("opened")
send()
}
ws.onclose = function(){
console.log("close")
}
ws.onerror = function(ev){
console.log("error " + ev)
}
ws.onmessage = function(msg){
console.log("recv: " + msg.data)
if (messageNum == 10) {
ws.close()
} else {
send()
}
}
</script>
`))
}

View File

@ -183,10 +183,13 @@ Watchdog: http://watchdogforxcode.com/
Slender: http://martiancraft.com/products/slender
Briefs: http://giveabrief.com/
Also, please check out my book **Swift for the Really Impatient** http://swiftforthereallyimpatient.com/
Also, please check out my latest game Rudoku:
https://itunes.apple.com/app/apple-store/id965105321?pt=17255&ct=github&mt=8&at=11lMGu
###Change Log
* **Version 3.1**: *(2015/10/23)* - Initial support for tvOS
* **Version 3.1b1**: *(2015/09/09)* - Initial support for tvOS
* **Version 3.0**: *(2015/09/09)* - Bug fix, and WatchOS 2 suppport (thanks @ymyzk)
* **Version 2.4**: *(2015/09/09)* - Minor bug fix, likely the last release for Swift 1.x
* **Version 3.0b3**: *(2015/08/24)* - Added option to include the log identifier in log messages #79

View File

@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "XCGLogger"
s.version = "3.0"
s.version = "3.1b1"
s.summary = "A debug log module for use in Swift projects."
s.description = <<-DESC
@ -12,14 +12,15 @@ Pod::Spec.new do |s|
s.license = { :type => "MIT", :file => "LICENSE.txt" }
s.author = { "Dave Wood" => "cocoapods@cerebralgardens.com" }
s.social_media_url = "http://twitter.com/DaveWoodX"
s.platforms = { :ios => "7.0", :watchos => "2.0" }
s.platforms = { :ios => "7.0", :watchos => "2.0", :tvos => "9.0" }
s.source = { :git => "https://github.com/DaveWoodCom/XCGLogger.git", :tag => "Version_3.0" }
s.source = { :git => "https://github.com/DaveWoodCom/XCGLogger.git", :tag => "Version_3.1b1" }
s.source_files = "XCGLogger/Library/XCGLogger/XCGLogger.swift"
s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.9'
s.watchos.deployment_target = '2.0'
s.tvos.deployment_target = '9.0'
s.framework = "Foundation"
s.requires_arc = true

View File

@ -65,6 +65,13 @@
remoteGlobalIDString = 55BB1F011B79DC7500709779;
remoteInfo = "XCGLoggerTests (OS X)";
};
55CB2FB41BA12ADE0031F329 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 555FFCCE19D77B3400F62246 /* XCGLogger.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 5515A3DF1BA119FA0047BA31;
remoteInfo = "XCGLogger (tvOS)";
};
55D5C34819D77C6000A47D22 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 555FFCCE19D77B3400F62246 /* XCGLogger.xcodeproj */;
@ -188,6 +195,7 @@
555FFCD519D77B3400F62246 /* XCGLogger.framework */,
555FFCD719D77B3400F62246 /* XCGLogger.framework */,
555CA5E51BA1120A00A5AA95 /* XCGLogger.framework */,
55CB2FB51BA12ADE0031F329 /* XCGLogger.framework */,
555FFCD919D77B3400F62246 /* XCGLoggerTests (iOS).xctest */,
5562CA971B7B25DD00F36DD8 /* XCGLoggerTests (OS X).xctest */,
);
@ -315,6 +323,13 @@
remoteRef = 5562CA961B7B25DD00F36DD8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
55CB2FB51BA12ADE0031F329 /* XCGLogger.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = XCGLogger.framework;
remoteRef = 55CB2FB41BA12ADE0031F329 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
@ -404,7 +419,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 3.0;
CURRENT_PROJECT_VERSION = 3.1;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
@ -448,7 +463,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 3.0;
CURRENT_PROJECT_VERSION = 3.1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;

View File

@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>3.0</string>
<string>3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@ -100,6 +100,13 @@
remoteGlobalIDString = 70CB94161B99E728007802FF;
remoteInfo = "XCGLogger (watchOS)";
};
55CB2FBB1BA12B4E0031F329 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 558C64A819D777B100D6D507 /* XCGLogger.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 5515A3DF1BA119FA0047BA31;
remoteInfo = "XCGLogger (tvOS)";
};
55D4395A1B7AAC16001370EC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 558C64A819D777B100D6D507 /* XCGLogger.xcodeproj */;
@ -285,6 +292,7 @@
558C64AF19D777B100D6D507 /* XCGLogger.framework */,
558C64B119D777B100D6D507 /* XCGLogger.framework */,
558EA9561BA0FCEC00848990 /* XCGLogger.framework */,
55CB2FBC1BA12B4E0031F329 /* XCGLogger.framework */,
558C64B319D777B100D6D507 /* XCGLoggerTests (iOS).xctest */,
55D4395B1B7AAC16001370EC /* XCGLoggerTests (OS X).xctest */,
);
@ -484,6 +492,13 @@
remoteRef = 558EA9551BA0FCEC00848990 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
55CB2FBC1BA12B4E0031F329 /* XCGLogger.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = XCGLogger.framework;
remoteRef = 55CB2FBB1BA12B4E0031F329 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
55D4395B1B7AAC16001370EC /* XCGLoggerTests (OS X).xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
@ -641,7 +656,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 3.0;
CURRENT_PROJECT_VERSION = 3.1;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
@ -686,7 +701,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 3.0;
CURRENT_PROJECT_VERSION = 3.1;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>3.0</string>
<string>3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>3.0</string>
<string>3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>3.0</string>
<string>3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>3.0</string>
<string>3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@ -7,9 +7,11 @@
objects = {
/* Begin PBXBuildFile section */
5515A3E71BA11B170047BA31 /* XCGLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 55DA396519D7737B0032F026 /* XCGLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };
554DF41019D76FA9005708BE /* XCGLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 554DF40F19D76FA9005708BE /* XCGLogger.swift */; };
554DF41119D76FA9005708BE /* XCGLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 554DF40F19D76FA9005708BE /* XCGLogger.swift */; };
554DF43319D77155005708BE /* XCGLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 554DF40F19D76FA9005708BE /* XCGLogger.swift */; };
557C47E41BA125F800C9A174 /* XCGLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 554DF40F19D76FA9005708BE /* XCGLogger.swift */; };
55BB1EF91B79DC7500709779 /* XCGLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 554DF40F19D76FA9005708BE /* XCGLogger.swift */; };
55BB1EFA1B79DC7500709779 /* XCGLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E3EE5719D76F280068C3A7 /* XCGLoggerTests.swift */; };
55BB1EFC1B79DC7500709779 /* XCGLogger.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55E3EE4519D76F280068C3A7 /* XCGLogger.framework */; };
@ -39,6 +41,9 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
5515A3DF1BA119FA0047BA31 /* XCGLogger.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = XCGLogger.framework; sourceTree = BUILT_PRODUCTS_DIR; };
5515A3E11BA119FA0047BA31 /* XCGLogger (tvOS).h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XCGLogger (tvOS).h"; sourceTree = "<group>"; };
5515A3E31BA119FA0047BA31 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
554DF40F19D76FA9005708BE /* XCGLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCGLogger.swift; sourceTree = "<group>"; };
554DF41719D76FE7005708BE /* XCGLogger.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = XCGLogger.framework; sourceTree = BUILT_PRODUCTS_DIR; };
55BB1F011B79DC7500709779 /* XCGLoggerTests (OS X).xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "XCGLoggerTests (OS X).xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
@ -53,6 +58,13 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
5515A3DB1BA119FA0047BA31 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
554DF41319D76FE7005708BE /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -93,6 +105,15 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
5515A3E01BA119FA0047BA31 /* XCGLogger (tvOS) */ = {
isa = PBXGroup;
children = (
5515A3E11BA119FA0047BA31 /* XCGLogger (tvOS).h */,
5515A3E31BA119FA0047BA31 /* Info.plist */,
);
path = "XCGLogger (tvOS)";
sourceTree = "<group>";
};
55DA396419D7737B0032F026 /* iOS */ = {
isa = PBXGroup;
children = (
@ -114,6 +135,7 @@
children = (
55E3EE4719D76F280068C3A7 /* XCGLogger */,
55E3EE5419D76F280068C3A7 /* XCGLoggerTests */,
5515A3E01BA119FA0047BA31 /* XCGLogger (tvOS) */,
55E3EE4619D76F280068C3A7 /* Products */,
);
sourceTree = "<group>";
@ -126,6 +148,7 @@
554DF41719D76FE7005708BE /* XCGLogger.framework */,
55BB1F011B79DC7500709779 /* XCGLoggerTests (OS X).xctest */,
70CB94201B99E728007802FF /* XCGLogger.framework */,
5515A3DF1BA119FA0047BA31 /* XCGLogger.framework */,
);
name = Products;
sourceTree = "<group>";
@ -169,6 +192,14 @@
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
5515A3DC1BA119FA0047BA31 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
5515A3E71BA11B170047BA31 /* XCGLogger.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
554DF41419D76FE7005708BE /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
@ -196,6 +227,24 @@
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
5515A3DE1BA119FA0047BA31 /* XCGLogger (tvOS) */ = {
isa = PBXNativeTarget;
buildConfigurationList = 5515A3E61BA119FA0047BA31 /* Build configuration list for PBXNativeTarget "XCGLogger (tvOS)" */;
buildPhases = (
5515A3DA1BA119FA0047BA31 /* Sources */,
5515A3DB1BA119FA0047BA31 /* Frameworks */,
5515A3DC1BA119FA0047BA31 /* Headers */,
5515A3DD1BA119FA0047BA31 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "XCGLogger (tvOS)";
productName = "XCGLogger (tvOS)";
productReference = 5515A3DF1BA119FA0047BA31 /* XCGLogger.framework */;
productType = "com.apple.product-type.framework";
};
554DF41619D76FE7005708BE /* XCGLogger (OS X) */ = {
isa = PBXNativeTarget;
buildConfigurationList = 554DF42A19D76FE7005708BE /* Build configuration list for PBXNativeTarget "XCGLogger (OS X)" */;
@ -297,6 +346,9 @@
LastUpgradeCheck = 0700;
ORGANIZATIONNAME = "Cerebral Gardens";
TargetAttributes = {
5515A3DE1BA119FA0047BA31 = {
CreatedOnToolsVersion = 7.1;
};
554DF41619D76FE7005708BE = {
CreatedOnToolsVersion = 6.1;
};
@ -323,6 +375,7 @@
55E3EE4419D76F280068C3A7 /* XCGLogger (iOS) */,
554DF41619D76FE7005708BE /* XCGLogger (OS X) */,
70CB94161B99E728007802FF /* XCGLogger (watchOS) */,
5515A3DE1BA119FA0047BA31 /* XCGLogger (tvOS) */,
55E3EE4F19D76F280068C3A7 /* XCGLoggerTests (iOS) */,
55BB1EF51B79DC7500709779 /* XCGLoggerTests (OS X) */,
);
@ -330,6 +383,13 @@
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
5515A3DD1BA119FA0047BA31 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
554DF41519D76FE7005708BE /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -368,6 +428,14 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
5515A3DA1BA119FA0047BA31 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
557C47E41BA125F800C9A174 /* XCGLogger.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
554DF41219D76FE7005708BE /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -426,6 +494,51 @@
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
5515A3E41BA119FA0047BA31 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "XCGLogger (tvOS)/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.cerebralgardens.xcglogger;
PRODUCT_NAME = XCGLogger;
SDKROOT = appletvos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 9.0;
};
name = Debug;
};
5515A3E51BA119FA0047BA31 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "XCGLogger (tvOS)/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.cerebralgardens.xcglogger;
PRODUCT_NAME = XCGLogger;
SDKROOT = appletvos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 9.0;
};
name = Release;
};
554DF42B19D76FE7005708BE /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -522,7 +635,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 3.0;
CURRENT_PROJECT_VERSION = 3.1;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
@ -542,6 +655,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_MODULE_NAME = XCGLogger;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2";
@ -569,7 +683,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 3.0;
CURRENT_PROJECT_VERSION = 3.1;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
@ -581,6 +695,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_MODULE_NAME = XCGLogger;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
@ -710,6 +825,15 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
5515A3E61BA119FA0047BA31 /* Build configuration list for PBXNativeTarget "XCGLogger (tvOS)" */ = {
isa = XCConfigurationList;
buildConfigurations = (
5515A3E41BA119FA0047BA31 /* Debug */,
5515A3E51BA119FA0047BA31 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
554DF42A19D76FE7005708BE /* Build configuration list for PBXNativeTarget "XCGLogger (OS X)" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -51,6 +51,15 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "70CB94161B99E728007802FF"
BuildableName = "XCGLogger.framework"
BlueprintName = "XCGLogger (watchOS)"
ReferencedContainer = "container:XCGLogger.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>3.0</string>
<string>3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@ -8,10 +8,10 @@
//
import Foundation
#if os(iOS) || os(watchOS)
import UIKit
#else
#if os(OSX)
import AppKit
#else
import UIKit
#endif
// MARK: - XCGLogDetails
@ -62,7 +62,7 @@ public class XCGBaseLogDestination: XCGLogDestinationProtocol, CustomDebugString
public var showLogLevel: Bool = true
public var showDate: Bool = true
// MARK: - DebugPrintable
// MARK: - CustomDebugStringConvertible
public var debugDescription: String {
get {
return "\(extractClassName(self)): \(identifier) - LogLevel: \(outputLogLevel) showLogIdentifier: \(showLogIdentifier) showFunctionName: \(showFunctionName) showThreadName: \(showThreadName) showLogLevel: \(showLogLevel) showFileName: \(showFileName) showLineNumber: \(showLineNumber) showDate: \(showDate)"
@ -291,7 +291,7 @@ public class XCGLogger: CustomDebugStringConvertible {
public static let nslogDestinationIdentifier = "com.cerebralgardens.xcglogger.logdestination.console.nslog"
public static let baseFileLogDestinationIdentifier = "com.cerebralgardens.xcglogger.logdestination.file"
public static let nsdataFormatterCacheIdentifier = "com.cerebralgardens.xcglogger.nsdataFormatterCache"
public static let versionString = "3.0"
public static let versionString = "3.1"
}
// MARK: - Enums
@ -363,24 +363,7 @@ public class XCGLogger: CustomDebugStringConvertible {
self.bg = bg
}
#if os(iOS) || os(watchOS)
public init(fg: UIColor, bg: UIColor? = nil) {
var redComponent: CGFloat = 0
var greenComponent: CGFloat = 0
var blueComponent: CGFloat = 0
var alphaComponent: CGFloat = 0
fg.getRed(&redComponent, green: &greenComponent, blue: &blueComponent, alpha:&alphaComponent)
self.fg = (Int(redComponent * 255), Int(greenComponent * 255), Int(blueComponent * 255))
if let bg = bg {
bg.getRed(&redComponent, green: &greenComponent, blue: &blueComponent, alpha:&alphaComponent)
self.bg = (Int(redComponent * 255), Int(greenComponent * 255), Int(blueComponent * 255))
}
else {
self.bg = nil
}
}
#else
#if os(OSX)
public init(fg: NSColor, bg: NSColor? = nil) {
if let fgColorSpaceCorrected = fg.colorUsingColorSpaceName(NSCalibratedRGBColorSpace) {
self.fg = (Int(fgColorSpaceCorrected.redComponent * 255), Int(fgColorSpaceCorrected.greenComponent * 255), Int(fgColorSpaceCorrected.blueComponent * 255))
@ -398,6 +381,23 @@ public class XCGLogger: CustomDebugStringConvertible {
self.bg = nil
}
}
#else
public init(fg: UIColor, bg: UIColor? = nil) {
var redComponent: CGFloat = 0
var greenComponent: CGFloat = 0
var blueComponent: CGFloat = 0
var alphaComponent: CGFloat = 0
fg.getRed(&redComponent, green: &greenComponent, blue: &blueComponent, alpha:&alphaComponent)
self.fg = (Int(redComponent * 255), Int(greenComponent * 255), Int(blueComponent * 255))
if let bg = bg {
bg.getRed(&redComponent, green: &greenComponent, blue: &blueComponent, alpha:&alphaComponent)
self.bg = (Int(redComponent * 255), Int(greenComponent * 255), Int(blueComponent * 255))
}
else {
self.bg = nil
}
}
#endif
public static let red: XcodeColor = {
@ -557,14 +557,12 @@ public class XCGLogger: CustomDebugStringConvertible {
}
public func logln(logLevel: LogLevel = .Debug, functionName: String = __FUNCTION__, fileName: String = __FILE__, lineNumber: Int = __LINE__, @noescape closure: () -> String?) {
let date = NSDate()
var logDetails: XCGLogDetails? = nil
for logDestination in self.logDestinations {
if (logDestination.isEnabledForLogLevel(logLevel)) {
if logDetails == nil {
if let logMessage = closure() {
logDetails = XCGLogDetails(logLevel: logLevel, date: date, logMessage: logMessage, functionName: functionName, fileName: fileName, lineNumber: lineNumber)
logDetails = XCGLogDetails(logLevel: logLevel, date: NSDate(), logMessage: logMessage, functionName: functionName, fileName: fileName, lineNumber: lineNumber)
}
else {
break
@ -811,13 +809,12 @@ public class XCGLogger: CustomDebugStringConvertible {
// MARK: - Private methods
private func _logln(logMessage: String, logLevel: LogLevel = .Debug) {
let date = NSDate()
var logDetails: XCGLogDetails? = nil
for logDestination in self.logDestinations {
if (logDestination.isEnabledForLogLevel(logLevel)) {
if logDetails == nil {
logDetails = XCGLogDetails(logLevel: logLevel, date: date, logMessage: logMessage, functionName: "", fileName: "", lineNumber: 0)
logDetails = XCGLogDetails(logLevel: logLevel, date: NSDate(), logMessage: logMessage, functionName: "", fileName: "", lineNumber: 0)
}
logDestination.processInternalLogDetails(logDetails!)

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@ -7,7 +7,6 @@
objects = {
/* Begin PBXBuildFile section */
D016D0071BC6DF2F009652C3 /* MeteorErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D016D0061BC6DF2F009652C3 /* MeteorErrors.swift */; settings = {ASSET_TAGS = (); }; };
D02A72101BBEFCD300940C17 /* DDPClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = D02A720B1BBEFCD200940C17 /* DDPClient.swift */; settings = {ASSET_TAGS = (); }; };
D02A72111BBEFCD300940C17 /* DDPMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D02A720C1BBEFCD300940C17 /* DDPMessage.swift */; settings = {ASSET_TAGS = (); }; };
D02A72121BBEFCD300940C17 /* DDPExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D02A720D1BBEFCD300940C17 /* DDPExtensions.swift */; settings = {ASSET_TAGS = (); }; };
@ -22,7 +21,6 @@
D02A72581BBF07AF00940C17 /* SwiftDDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D02A71DC1BBEFBCA00940C17 /* SwiftDDP.framework */; settings = {ASSET_TAGS = (); }; };
D02A725E1BBF07F700940C17 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D02A72351BBF033600940C17 /* Nimble.framework */; };
D02A725F1BBF07F700940C17 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D02A72361BBF033600940C17 /* Quick.framework */; };
D02B30831BDA8E2200E1DB72 /* DDPMethodResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = D02B30821BDA8E2200E1DB72 /* DDPMethodResult.swift */; settings = {ASSET_TAGS = (); }; };
D05879421BE6810F003E019E /* MeteorCoreDataTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D058793C1BE6810F003E019E /* MeteorCoreDataTableViewController.swift */; settings = {ASSET_TAGS = (); }; };
D05879431BE6810F003E019E /* MeteorCoreDataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = D058793D1BE6810F003E019E /* MeteorCoreDataStack.swift */; settings = {ASSET_TAGS = (); }; };
D05879441BE6810F003E019E /* MeteorCoreDataCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D058793E1BE6810F003E019E /* MeteorCoreDataCollection.swift */; settings = {ASSET_TAGS = (); }; };
@ -33,6 +31,7 @@
D0C71B561BC172F40089B6CE /* Meteor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C71B551BC172F40089B6CE /* Meteor.swift */; settings = {ASSET_TAGS = (); }; };
D0C71B581BC173030089B6CE /* SwiftMeteor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C71B571BC173030089B6CE /* SwiftMeteor.swift */; settings = {ASSET_TAGS = (); }; };
D0C71B5B1BC174280089B6CE /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C71B5A1BC174280089B6CE /* Data.swift */; settings = {ASSET_TAGS = (); }; };
D0CF95F71BF0D51800AA151A /* DDPResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CF95F61BF0D51800AA151A /* DDPResult.swift */; settings = {ASSET_TAGS = (); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -63,7 +62,6 @@
/* Begin PBXFileReference section */
D009DCA31BC1A53B0041378B /* RealmSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RealmSwift.framework; path = Carthage/Build/iOS/RealmSwift.framework; sourceTree = "<group>"; };
D009DCA51BC1A5440041378B /* Realm.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Realm.framework; path = Carthage/Build/iOS/Realm.framework; sourceTree = "<group>"; };
D016D0061BC6DF2F009652C3 /* MeteorErrors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeteorErrors.swift; sourceTree = "<group>"; };
D02A71DC1BBEFBCA00940C17 /* SwiftDDP.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftDDP.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D02A71E11BBEFBCA00940C17 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D02A720B1BBEFCD200940C17 /* DDPClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DDPClient.swift; sourceTree = "<group>"; };
@ -86,7 +84,6 @@
D02A72AF1BBF383700940C17 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
D02A72B01BBF383700940C17 /* Cartfile.resolved */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Cartfile.resolved; sourceTree = "<group>"; };
D02A72B11BBF383700940C17 /* Cartfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Cartfile; sourceTree = "<group>"; };
D02B30821BDA8E2200E1DB72 /* DDPMethodResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DDPMethodResult.swift; sourceTree = "<group>"; };
D058793C1BE6810F003E019E /* MeteorCoreDataTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeteorCoreDataTableViewController.swift; sourceTree = "<group>"; };
D058793D1BE6810F003E019E /* MeteorCoreDataStack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeteorCoreDataStack.swift; sourceTree = "<group>"; };
D058793E1BE6810F003E019E /* MeteorCoreDataCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeteorCoreDataCollection.swift; sourceTree = "<group>"; };
@ -97,6 +94,7 @@
D0C71B551BC172F40089B6CE /* Meteor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Meteor.swift; sourceTree = "<group>"; };
D0C71B571BC173030089B6CE /* SwiftMeteor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftMeteor.swift; sourceTree = "<group>"; };
D0C71B5A1BC174280089B6CE /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = "<group>"; };
D0CF95F61BF0D51800AA151A /* DDPResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DDPResult.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -152,7 +150,6 @@
isa = PBXGroup;
children = (
D0CF8A131BE2AC4C00EC9F12 /* DDP */,
D0CF8A121BE2AC4400EC9F12 /* Meteor */,
D05879481BE6812E003E019E /* MeteorCoreData */,
D02A71E11BBEFBCA00940C17 /* Info.plist */,
);
@ -201,23 +198,15 @@
name = MeteorCoreData;
sourceTree = "<group>";
};
D0CF8A121BE2AC4400EC9F12 /* Meteor */ = {
isa = PBXGroup;
children = (
D0C71B551BC172F40089B6CE /* Meteor.swift */,
D016D0061BC6DF2F009652C3 /* MeteorErrors.swift */,
);
name = Meteor;
sourceTree = "<group>";
};
D0CF8A131BE2AC4C00EC9F12 /* DDP */ = {
isa = PBXGroup;
children = (
D02A720B1BBEFCD200940C17 /* DDPClient.swift */,
D02A720C1BBEFCD300940C17 /* DDPMessage.swift */,
D02A720D1BBEFCD300940C17 /* DDPExtensions.swift */,
D02B30821BDA8E2200E1DB72 /* DDPMethodResult.swift */,
D0CF95F61BF0D51800AA151A /* DDPResult.swift */,
D02A720E1BBEFCD300940C17 /* DDPEvents.swift */,
D0C71B551BC172F40089B6CE /* Meteor.swift */,
);
name = DDP;
sourceTree = "<group>";
@ -371,10 +360,9 @@
D05879461BE6810F003E019E /* MeteorCollectionChange.swift in Sources */,
D02A72101BBEFCD300940C17 /* DDPClient.swift in Sources */,
D05879441BE6810F003E019E /* MeteorCoreDataCollection.swift in Sources */,
D02B30831BDA8E2200E1DB72 /* DDPMethodResult.swift in Sources */,
D0CF95F71BF0D51800AA151A /* DDPResult.swift in Sources */,
D02A72111BBEFCD300940C17 /* DDPMessage.swift in Sources */,
D05879431BE6810F003E019E /* MeteorCoreDataStack.swift in Sources */,
D016D0071BC6DF2F009652C3 /* MeteorErrors.swift in Sources */,
D02A72121BBEFCD300940C17 /* DDPExtensions.swift in Sources */,
D0C71B561BC172F40089B6CE /* Meteor.swift in Sources */,
D05879471BE6810F003E019E /* CoreDataExtensions.swift in Sources */,

View File

@ -35,44 +35,79 @@ let log = XCGLogger(identifier: "DDP")
public typealias DDPMethodCallback = (result:AnyObject?, error:DDPError?) -> ()
public typealias DDPCallback = () -> ()
/**
DDPDelegate provides an interface to react to user events
*/
public protocol SwiftDDPDelegate {
func ddpUserDidLogin(user:String)
func ddpUserDidLogout(user:String)
}
/**
DDPClient is the base class for communicating with a server using the DDP protocol
*/
public class DDPClient: NSObject {
// included for storing login id and token
internal let userData = NSUserDefaults.standardUserDefaults()
internal let incomingData:NSOperationQueue = {
let background: NSOperationQueue = {
let queue = NSOperationQueue()
queue.name = "DDP Incoming Data Queue"
queue.name = "DDP Background Data Queue"
queue.qualityOfService = .Background
return queue
}()
// Not currently used
let backgroundSerial: NSOperationQueue = {
let queue = NSOperationQueue()
queue.name = "DDP Background Serial Data Queue"
queue.maxConcurrentOperationCount = 1
queue.qualityOfService = .Background
return queue
}()
// Calling methods on the server + their callbacks
internal let outgoingData:NSOperationQueue = {
// Callbacks execute in the order they're received
internal let callbackQueue: NSOperationQueue = {
let queue = NSOperationQueue()
queue.name = "DDP Outgoing Data Queue"
// queue.maxConcurrentOperationCount = 1
return queue
}()
internal let operation:NSOperationQueue = {
let queue = NSOperationQueue()
queue.name = "DDP Operation Queue"
queue.name = "DDP Callback Queue"
queue.maxConcurrentOperationCount = 1
queue.qualityOfService = .UserInitiated
return queue
}()
internal let heartbeat:NSOperationQueue = {
// Document messages are processed in the order that they are received,
// separately from callbacks
internal let documentQueue: NSOperationQueue = {
let queue = NSOperationQueue()
queue.name = "DDP Background Queue"
queue.maxConcurrentOperationCount = 1
queue.qualityOfService = .Background
return queue
}()
// Hearbeats get a special queue so that they're not blocked by
// other operations, causing the connection to close
internal let heartbeat: NSOperationQueue = {
let queue = NSOperationQueue()
queue.name = "DDP Heartbeat Queue"
queue.qualityOfService = .Utility
return queue
}()
internal let mainQueue = NSOperationQueue.mainQueue()
let userBackground: NSOperationQueue = {
let queue = NSOperationQueue()
queue.name = "DDP High Priority Background Queue"
queue.qualityOfService = .UserInitiated
return queue
}()
let userMainQueue: NSOperationQueue = {
let queue = NSOperationQueue.mainQueue()
queue.name = "DDP High Priorty Main Queue"
queue.qualityOfService = .UserInitiated
return queue
}()
private var socket:WebSocket!
private var server:(ping:NSDate?, pong:NSDate?) = (nil, nil)
@ -87,6 +122,7 @@ public class DDPClient: NSObject {
internal var events = DDPEvents()
internal var connection:(ddp:Bool, session:String?) = (false, nil)
public var delegate:SwiftDDPDelegate?
public var logLevel = XCGLogger.LogLevel.Debug
internal override init() {
@ -141,14 +177,13 @@ public class DDPClient: NSObject {
}
socket.event.message = { message in
self.operation.addOperationWithBlock() {
self.background.addOperationWithBlock() {
if let text = message as? String {
do { try self.ddpMessageHandler(DDPMessage(message: text)) }
catch { log.debug("Message handling error. Raw message: \(text)")}
}
}
}
}
/**
@ -171,7 +206,6 @@ public class DDPClient: NSObject {
private func pong(ping: DDPMessage) {
heartbeat.addOperationWithBlock() {
self.server.ping = NSDate()
// log.debug("Ping")
var response = ["msg":"pong"]
if let id = ping.id { response["id"] = id }
self.sendMessage(response)
@ -189,7 +223,7 @@ public class DDPClient: NSObject {
self.connection = (true, message.session!)
self.events.onConnected(session:message.session!)
case .Result: incomingData.addOperationWithBlock() {
case .Result: callbackQueue.addOperationWithBlock() {
if let id = message.id, // Message has id
let callback = self.resultCallbacks[id], // There is a callback registered for the message
let result = message.result {
@ -204,57 +238,56 @@ public class DDPClient: NSObject {
// Principal callbacks for managing data
// Document was added
case .Added: incomingData.addOperationWithBlock() {
if let collection = message.collection,
let id = message.id {
self.documentWasAdded(collection, id: id, fields: message.fields)
}
case .Added: documentQueue.addOperationWithBlock() {
if let collection = message.collection,
let id = message.id {
self.documentWasAdded(collection, id: id, fields: message.fields)
}
}
// Document was changed
case .Changed: incomingData.addOperationWithBlock() {
if let collection = message.collection,
let id = message.id {
self.documentWasChanged(collection, id: id, fields: message.fields, cleared: message.cleared)
}
case .Changed: documentQueue.addOperationWithBlock() {
if let collection = message.collection,
let id = message.id {
self.documentWasChanged(collection, id: id, fields: message.fields, cleared: message.cleared)
}
}
// Document was removed
case .Removed: incomingData.addOperationWithBlock() {
if let collection = message.collection,
let id = message.id {
self.documentWasRemoved(collection, id: id)
}
case .Removed: documentQueue.addOperationWithBlock() {
if let collection = message.collection,
let id = message.id {
self.documentWasRemoved(collection, id: id)
}
}
// Notifies you when the result of a method changes
case .Updated: incomingData.addOperationWithBlock() {
if let methods = message.methods {
self.methodWasUpdated(methods)
}
case .Updated: documentQueue.addOperationWithBlock() {
if let methods = message.methods {
self.methodWasUpdated(methods)
}
}
// Callbacks for managing subscriptions
case .Ready: incomingData.addOperationWithBlock() {
if let subs = message.subs {
self.ready(subs)
}
case .Ready: background.addOperationWithBlock() {
if let subs = message.subs {
self.ready(subs)
}
}
// Callback that fires when subscription has been completely removed
//
case .Nosub: incomingData.addOperationWithBlock() {
case .Nosub: background.addOperationWithBlock() {
if let id = message.id {
self.nosub(id, error: message.error)
}
}
}
case .Ping: heartbeat.addOperationWithBlock() { self.pong(message) }
case .Pong: heartbeat.addOperationWithBlock() { self.server.pong = NSDate() }
case .Error: incomingData.addOperationWithBlock() {
case .Error: background.addOperationWithBlock() {
self.didReceiveErrorMessage(DDPError(json: message.json))
}
@ -282,10 +315,12 @@ public class DDPClient: NSObject {
public func method(name: String, params: AnyObject?, callback: DDPMethodCallback?) -> String {
let id = getId()
let message = ["msg":"method", "method":name, "id":id] as NSMutableDictionary
if let p = params { message["params"] = p }
if let c = callback { resultCallbacks[id] = c }
outgoingData.addOperationWithBlock() { self.sendMessage(message) }
let message = ["msg":"method", "method":name, "id":id] as NSMutableDictionary
if let p = params { message["params"] = p }
if let c = callback { self.resultCallbacks[id] = c }
userBackground.addOperationWithBlock() {
self.sendMessage(message)
}
return id
}
@ -295,11 +330,13 @@ public class DDPClient: NSObject {
internal func sub(id: String, name: String, params: [AnyObject]?, callback: DDPCallback?) -> String {
if let c = callback { subCallbacks[id] = c }
subscriptions[id] = (id, name, false)
if let c = callback { self.subCallbacks[id] = c }
self.subscriptions[id] = (id, name, false)
let message = ["msg":"sub", "name":name, "id":id] as NSMutableDictionary
if let p = params { message["params"] = p }
outgoingData.addOperationWithBlock() { self.sendMessage(message) }
userBackground.addOperationWithBlock() {
self.sendMessage(message)
}
return id
}
@ -326,8 +363,12 @@ public class DDPClient: NSObject {
*/
public func sub(name:String, params: [AnyObject]?, callback: DDPCallback?) -> String {
let id = getId()
return sub(id, name: name, params: params, callback: callback)
let id = String(name.hashValue)
if let subData = findSubscription(name) {
log.info("You are already subscribed to \(name)")
return subData.id
}
return sub(id, name: name, params: params, callback: callback)
}
// Iterates over the Dictionary of subscriptions to find a subscription by name
@ -366,7 +407,7 @@ public class DDPClient: NSObject {
public func unsub(name: String, callback: DDPCallback?) -> String? {
if let sub = findSubscription(name) {
unsub(withId: sub.id, callback: callback)
outgoingData.addOperationWithBlock() { self.sendMessage(["msg":"unsub", "id":sub.id]) }
background.addOperationWithBlock() { self.sendMessage(["msg":"unsub", "id":sub.id]) }
return sub.id
}
return nil
@ -374,7 +415,7 @@ public class DDPClient: NSObject {
internal func unsub(withId id: String, callback: DDPCallback?) {
if let c = callback { unsubCallbacks[id] = c }
outgoingData.addOperationWithBlock() { self.sendMessage(["msg":"unsub", "id":id]) }
background.addOperationWithBlock() { self.sendMessage(["msg":"unsub", "id":id]) }
}
//
@ -492,6 +533,4 @@ public class DDPClient: NSObject {
public func didReceiveErrorMessage(message: DDPError) {
if let error = events.onError { error(message: message) }
}
}
}

View File

@ -28,6 +28,9 @@ private let DDP_TOKEN = "DDP_TOKEN"
private let DDP_TOKEN_EXPIRES = "DDP_TOKEN_EXPIRES"
private let DDP_LOGGED_IN = "DDP_LOGGED_IN"
public let DDP_USER_DID_LOGIN = "DDP_USER_DID_LOGIN"
public let DDP_USER_DID_LOGOUT = "DDP_USER_DID_LOGOUT"
let SWIFT_DDP_CALLBACK_DISPATCH_TIME = DISPATCH_TIME_FOREVER
private let syncWarning = {(name:String) -> Void in
@ -36,8 +39,6 @@ private let syncWarning = {(name:String) -> Void in
}
}
extension String {
func dictionaryValue() -> NSDictionary? {
if let data = self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
@ -237,7 +238,10 @@ extension DDPClient {
return serverResponse
}
// Callback runs on main thread
internal func login(params: NSDictionary, callback: ((result: AnyObject?, error: DDPError?) -> ())?) {
// method is run on the userBackground queue
method("login", params: NSArray(arrayLiteral: params)) { result, error in
guard let e = error where (e.isValid == true) else {
@ -257,8 +261,20 @@ extension DDPClient {
self.userData.setObject(token, forKey: DDP_TOKEN)
self.userData.setObject(expiration, forKey: DDP_TOKEN_EXPIRES)
}
if let c = callback { c(result:result, error:error) }
self.userData.setObject(true, forKey: DDP_LOGGED_IN)
self.userMainQueue.addOperationWithBlock() {
if let c = callback { c(result:result, error:error) }
self.userData.setObject(true, forKey: DDP_LOGGED_IN)
NSNotificationCenter.defaultCenter().postNotificationName(DDP_USER_DID_LOGIN, object: nil)
if let _ = self.delegate {
self.delegate!.ddpUserDidLogin(self.user()!)
}
}
return
}
@ -276,7 +292,7 @@ extension DDPClient {
*/
public func loginWithPassword(email: String, password: String, callback: DDPMethodCallback?) {
if !(loginWithToken(callback)) {
let params = ["user": ["email": email], "password":["digest": password.sha256()!, "algorithm":"sha-256"]] as NSDictionary
let params = ["user": ["email": email], "password":["digest": password.sha256(), "algorithm":"sha-256"]] as NSDictionary
login(params, callback: callback)
}
}
@ -289,6 +305,7 @@ extension DDPClient {
public func loginWithToken(callback: DDPMethodCallback?) -> Bool {
if let token = userData.stringForKey(DDP_TOKEN),
let tokenDate = userData.objectForKey(DDP_TOKEN_EXPIRES) {
print("Found token & token expires \(token), \(tokenDate)")
if (tokenDate.compare(NSDate()) == NSComparisonResult.OrderedDescending) {
let params = ["resume":token] as NSDictionary
login(params, callback:callback)
@ -317,6 +334,7 @@ extension DDPClient {
self.userData.setObject(id, forKey: DDP_ID)
self.userData.setObject(token, forKey: DDP_TOKEN)
self.userData.setObject(expiration, forKey: DDP_TOKEN_EXPIRES)
self.userData.synchronize()
}
if let c = callback { c(result:result, error:error) }
self.userData.setObject(true, forKey: DDP_LOGGED_IN)
@ -327,14 +345,20 @@ extension DDPClient {
if let c = callback { c(result: result, error: error) }
}
}
/**
Invokes a Meteor method to create a user account with a given email and password on the server
*/
public func signupWithEmail(email: String, password: String, callback: ((result:AnyObject?, error:DDPError?) -> ())?) {
let params = ["email":email, "password":["digest":password.sha256()!, "algorithm":"sha-256"]]
let params = ["email":email, "password":["digest":password.sha256(), "algorithm":"sha-256"]]
signup(params, callback: callback)
}
/**
Invokes a Meteor method to create a user account with a given email and password, and a NSDictionary containing a user profile
*/
public func signupWithEmail(email: String, password: String, profile: NSDictionary, callback: ((result:AnyObject?, error:DDPError?) -> ())?) {
let params = ["email":email, "password":["digest":password.sha256()!, "algorithm":"sha-256"], "profile":profile]
let params = ["email":email, "password":["digest":password.sha256(), "algorithm":"sha-256"], "profile":profile]
signup(params, callback: callback)
}
@ -357,30 +381,49 @@ extension DDPClient {
return nil
}
internal func resetUserData() {
self.userData.setObject(false, forKey: DDP_LOGGED_IN)
self.userData.removeObjectForKey(DDP_ID)
self.userData.removeObjectForKey(DDP_EMAIL)
self.userData.removeObjectForKey(DDP_USERNAME)
self.userData.removeObjectForKey(DDP_TOKEN)
self.userData.removeObjectForKey(DDP_TOKEN_EXPIRES)
self.userData.synchronize()
}
/**
Logs a user out and removes their account data from NSUserDefaults
*/
public func logout() {
method("logout", params: nil) { result, error in
if (error == nil) {
self.userData.setObject(false, forKey: DDP_LOGGED_IN)
self.userData.removeObjectForKey(DDP_ID)
self.userData.removeObjectForKey(DDP_EMAIL)
self.userData.removeObjectForKey(DDP_USERNAME)
self.userData.removeObjectForKey(DDP_TOKEN)
self.userData.removeObjectForKey(DDP_TOKEN_EXPIRES)
}
}
logout(nil)
}
/**
Logs a user out and removes their account data from NSUserDefaults
Logs a user out and removes their account data from NSUserDefaults.
When it completes, it posts a notification: DDP_USER_DID_LOGOUT on the main queue
- parameter callback: A closure with result and error parameters describing the outcome of the operation
*/
public func logout(callback:DDPMethodCallback?) {
method("logout", params: nil, callback: callback)
}
method("logout", params: nil) { result, error in
if (error == nil) {
self.userMainQueue.addOperationWithBlock() {
let user = self.user()!
NSNotificationCenter.defaultCenter().postNotificationName(DDP_USER_DID_LOGOUT, object: nil)
if let _ = self.delegate {
self.delegate!.ddpUserDidLogout(user)
}
self.resetUserData()
}
} else {
log.error("\(error)")
}
if let c = callback { c(result: result, error: error) }
}
}
/**
Automatically attempts to resume a prior session, if one exists

View File

@ -20,6 +20,46 @@
import Foundation
class DDPOperation: NSOperation {
typealias Action = () -> Void
var message: DDPMessage
var action: Action
init(message: DDPMessage, action: Action) {
self.message = message
self.action = action
super.init()
}
override func main() {
action()
}
}
class DDPPingOperation: DDPOperation {
override init(message: DDPMessage, action: Action) {
super.init(message: message, action: action)
self.queuePriority = .High
self.qualityOfService = .Utility
}
}
class DDPMessageOperation: DDPOperation {
init(message: DDPMessage, action: Action, completion: Action?) {
super.init(message: message, action: action)
self.queuePriority = .Low
self.qualityOfService = .Background
self.completionBlock = completion
}
}
/**
Enum value representing the types of DDP messages that the server can send
*/
@ -94,7 +134,9 @@ public struct DDPMessage {
json = message as NSDictionary
}
// Converts an NSDictionary to a JSON String
/**
Converts an NSDictionary to a JSON string
*/
public static func toString(json:AnyObject) -> String? {
if let data = try? NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions(rawValue: 0)) {
let message = NSString(data: data, encoding: NSASCIIStringEncoding) as String?

View File

@ -34,4 +34,4 @@ public struct Result {
An error object describing the server-side error, or nil if the method completed successfully
*/
public var error:DDPError?
}
}

View File

@ -20,6 +20,18 @@
import Foundation
/*
enum Error: String {
case BadRequest = "400" // The server cannot or will not process the request due to something that is perceived to be a client error
case Unauthorized = "401" // Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.
case NotFound = "404" // ex. Method not found, Subscription not found
case Forbidden = "403" // Not authorized to access resource
case RequestConflict = "409" // ex. MongoError: E11000 duplicate key error
case PayloadTooLarge = "413" // The request is larger than the server is willing or able to process.
case InternalServerError = "500"
}
*/
protocol MeteorCollectionType {
func documentWasAdded(collection:String, id:String, fields:NSDictionary?)
func documentWasChanged(collection:String, id:String, fields:NSDictionary?, cleared:[String]?)
@ -79,14 +91,39 @@ public class Meteor {
- parameter callback: The closure to be executed when the server sends a 'ready' message.
*/
public static func subscribe(name:String, callback: DDPCallback?) -> String { return client.sub(name, params:nil, callback:callback) }
public static func subscribe(name:String, callback: DDPCallback?) -> String { return client.sub(name, params: nil, callback: callback) }
//public static func unsubscribe(
/**
Sends an unsubscribe request to the server.
*/
public static func unsubscribe(name:String) -> String? { return client.unsub(name) }
/**
Sends an unsubscribe request to the server. If a callback is passed, the callback asynchronously
runs when the unsubscribe transaction is complete.
*/
public static func unsubscribe(name:String, callback:DDPCallback?) -> String? { return client.unsub(name, callback: callback) }
/**
Calls a method on the server. If a callback is passed, the callback is asynchronously
executed when the method has completed. The callback takes two arguments: result and error. It
the method call is successful, result contains the return value of the method, if any. If the method fails,
error contains information about the error.
- parameter name: The name of the method
- parameter params: An array containing method arguments, if any
- parameter callback: The closure to be executed when the method has been executed
*/
public static func call(name:String, params:[AnyObject]?, callback:DDPMethodCallback?) -> String? {
return client.method(name, params: params, callback: callback)
}
/**
Call a single function to establish a DDP connection, and login with email and password
- parameter url: The url to connect to
- parameter url: The url of a Meteor server
- parameter email: A string email address associated with a Meteor account
- parameter password: A string password
*/
@ -103,6 +140,26 @@ public class Meteor {
}
}
/**
Connect to a Meteor server and resume a prior session, if the user was logged in
- parameter url: The url of a Meteor server
*/
public static func connect(url:String) {
client.resume(url, callback: nil)
}
/**
Connect to a Meteor server and resume a prior session, if the user was logged in
- parameter url: The url of a Meteor server
- parameter callback: An optional closure to be executed after the connection is established
*/
public static func connect(url:String, callback:DDPCallback?) {
client.resume(url, callback: callback)
}
/**
Meteor.Client is a subclass of DDPClient that facilitates interaction with the MeteorCollection class
*/
@ -126,9 +183,7 @@ public class Meteor {
public override func documentWasAdded(collection:String, id:String, fields:NSDictionary?) {
if let meteorCollection = Meteor.collections[collection] as? MeteorCollectionType {
NSOperationQueue.mainQueue().addOperationWithBlock() {
meteorCollection.documentWasAdded(collection, id: id, fields: fields)
}
meteorCollection.documentWasAdded(collection, id: id, fields: fields)
}
}
@ -144,9 +199,7 @@ public class Meteor {
public override func documentWasChanged(collection:String, id:String, fields:NSDictionary?, cleared:[String]?) {
if let meteorCollection = Meteor.collections[collection] as? MeteorCollectionType {
NSOperationQueue.mainQueue().addOperationWithBlock() {
meteorCollection.documentWasChanged(collection, id: id, fields: fields, cleared: cleared)
}
meteorCollection.documentWasChanged(collection, id: id, fields: fields, cleared: cleared)
}
}
@ -160,9 +213,7 @@ public class Meteor {
public override func documentWasRemoved(collection:String, id:String) {
if let meteorCollection = Meteor.collections[collection] as? MeteorCollectionType {
NSOperationQueue.mainQueue().addOperationWithBlock() {
meteorCollection.documentWasRemoved(collection, id: id)
}
meteorCollection.documentWasRemoved(collection, id: id)
}
}
}
@ -200,7 +251,7 @@ public class MeteorCollection: NSObject, MeteorCollectionType {
}
/**
Called when a document has been sent from the server. Always executes on the main queue
Invoked when a document has been sent from the server.
- parameter collection: the string name of the collection to which the document belongs
- parameter id: the string unique id that identifies the document on the server
@ -211,10 +262,26 @@ public class MeteorCollection: NSObject, MeteorCollectionType {
if let added = onAdded { added(collection: collection, id: id, fields:fields) }
}
/**
Invoked when a document has been changed on the server.
- parameter collection: the string name of the collection to which the document belongs
- parameter id: the string unique id that identifies the document on the server
- parameter fields: an optional NSDictionary with the documents properties
- parameter cleared: Optional array of strings (field names to delete)
*/
public func documentWasChanged(collection:String, id:String, fields:NSDictionary?, cleared:[String]?) {
if let changed = onChanged { changed(collection:collection, id:id, fields:fields, cleared:cleared) }
}
/**
Invoked when a document has been removed on the server.
- parameter collection: the string name of the collection to which the document belongs
- parameter id: the string unique id that identifies the document on the server
*/
public func documentWasRemoved(collection:String, id:String) {
if let removed = onRemoved { removed(collection:collection, id:id) }
}

View File

@ -72,6 +72,7 @@ public class MeteorCoreDataCollection:MeteorCollection {
return []
}
// Retrieves a single result by name
public func findOne(id:String) -> NSManagedObject? {
let fetchRequest = NSFetchRequest(entityName: self.entityName)
@ -84,20 +85,26 @@ public class MeteorCoreDataCollection:MeteorCollection {
}
public func exists(id:String) -> Bool {
let error = NSErrorPointer()
let fetchRequest = NSFetchRequest(entityName: self.entityName)
fetchRequest.predicate = NSPredicate(format: "id == '\(id)'")
let count = managedObjectContext.countForFetchRequest(fetchRequest, error: nil)
if count > 0 {
let count = managedObjectContext.countForFetchRequest(fetchRequest, error: error)
if error == nil && count > 0 {
return true
}
return false
}
public func exists(collection:String, id:String) -> Bool {
let error = NSErrorPointer()
let fetchRequest = NSFetchRequest(entityName: self.entityName)
fetchRequest.predicate = NSPredicate(format: "id == '\(id)' AND collection == '\(collection)'")
let count = managedObjectContext.countForFetchRequest(fetchRequest, error: nil)
if count > 0 {
print("Managed object context \(managedObjectContext)")
let count = managedObjectContext.countForFetchRequest(fetchRequest, error: error)
if error == nil && count > 0 {
return true
}
return false

View File

@ -1,14 +0,0 @@
/*
extension DDP {
enum Error: String {
case BadRequest = "400" // The server cannot or will not process the request due to something that is perceived to be a client error
case Unauthorized = "401" // Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.
case NotFound = "404" // ex. Method not found, Subscription not found
case Forbidden = "403" // Not authorized to access resource
case RequestConflict = "409" // ex. MongoError: E11000 duplicate key error
case PayloadTooLarge = "413" // The request is larger than the server is willing or able to process.
case InternalServerError = "500"
}
}
*/