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 "krzyzanowskim/CryptoSwift"
github "tidwall/SwiftWebSocket" "v2.1.1" github "tidwall/SwiftWebSocket"
github "DaveWoodCom/XCGLogger"
github "DaveWoodCom/XCGLogger" "Version_3.0" github "Quick/Quick"
github "Quick/Nimble"
github "Quick/Quick" "v0.6.0"
github "Quick/Nimble" "v2.0.0-rc.3"

View File

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

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = "CryptoSwift" 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.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.description = "Cryptography functions and helpers for Swift implemented in Swift. SHA, MD5, CRC, Poly1305, HMAC, ChaCha20, AES."
s.homepage = "https://github.com/krzyzanowskim/CryptoSwift" s.homepage = "https://github.com/krzyzanowskim/CryptoSwift"
@ -12,6 +12,8 @@ Pod::Spec.new do |s|
s.ios.deployment_target = "8.0" s.ios.deployment_target = "8.0"
s.osx.platform = :osx, '10.9' s.osx.platform = :osx, '10.9'
s.osx.deployment_target = "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 s.requires_arc = true
end end

View File

@ -6,36 +6,55 @@
objectVersion = 46; objectVersion = 46;
objects = { 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 */ /* 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 */; }; 75100F8F19B0BC890005C5F5 /* Poly1305Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75100F8E19B0BC890005C5F5 /* Poly1305Tests.swift */; };
75164E4919AD30AC00737F30 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75164E4819AD30AC00737F30 /* Utils.swift */; }; 75164E4919AD30AC00737F30 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75164E4819AD30AC00737F30 /* Utils.swift */; };
751C5C3D19B26B000094C75D /* Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 751C5C3C19B26B000094C75D /* Poly1305.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 */; }; 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 */; }; 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 */; }; 7539E32D1B3B4E950037F4E1 /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752E087A199FF27C005B0EA0 /* SHA1.swift */; };
7539E32E1B3B4E970037F4E1 /* SHA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75153D4119AA3C7900750381 /* SHA2.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 */; }; 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 */; }; 754BE46819693E190098E6F3 /* HashTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754BE46719693E190098E6F3 /* HashTests.swift */; };
754C30B71AA13BC000E6FFA4 /* PKCS7.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754C30B61AA13BC000E6FFA4 /* PKCS7.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 */; }; 754DD76E19A149AF00E52288 /* HashProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754DD76D19A149AF00E52288 /* HashProtocol.swift */; };
755111E819B7B7DF00C2AD86 /* Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755111E719B7B7DF00C2AD86 /* Authenticator.swift */; }; 755111E819B7B7DF00C2AD86 /* Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755111E719B7B7DF00C2AD86 /* Authenticator.swift */; };
7552614E1993051E000D2B20 /* Hash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7552614D1993051E000D2B20 /* Hash.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 */; }; 758A94281A65C59200E46135 /* HMACTests.swift in Resources */ = {isa = PBXBuildFile; fileRef = 758A94271A65C59200E46135 /* HMACTests.swift */; };
758A94291A65C67400E46135 /* HMACTests.swift in Sources */ = {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 */; }; 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 */; }; 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 */; }; 759D481119B517BC005FF7FC /* BitExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759D481019B517BC005FF7FC /* BitExtension.swift */; };
75A663A61AA0CAD00052110B /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A663A51AA0CAD00052110B /* Padding.swift */; }; 75A663A61AA0CAD00052110B /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A663A51AA0CAD00052110B /* Padding.swift */; };
75A74B271A1FF6B2004419F1 /* AES.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A74B261A1FF6B2004419F1 /* AES.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 */; }; 75B601EB197D6A6C0009B53D /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 754BE45519693E190098E6F3 /* CryptoSwift.framework */; };
75BC3AE31A4E412000ADF343 /* CipherBlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BC3AE21A4E412000ADF343 /* CipherBlockMode.swift */; }; 75BC3AE31A4E412000ADF343 /* CipherBlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BC3AE21A4E412000ADF343 /* CipherBlockMode.swift */; };
75BE4EB11B1E4A9F007A2B57 /* IntegerConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BE4EB01B1E4A9F007A2B57 /* IntegerConvertible.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 */; }; 75D94E2419B60C08007CB2A4 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D94E2319B60C08007CB2A4 /* Operators.swift */; };
75D94E2619B60C4F007CB2A4 /* UInt32Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D94E2519B60C4F007CB2A4 /* UInt32Extension.swift */; }; 75D94E2619B60C4F007CB2A4 /* UInt32Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D94E2519B60C4F007CB2A4 /* UInt32Extension.swift */; };
75D94E2819B60DDE007CB2A4 /* UInt64Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D94E2719B60DDE007CB2A4 /* UInt64Extension.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 */; }; 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 */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -127,26 +187,35 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
75DF776E1BC8EB59006E9520 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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; }; 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>"; }; 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; }; 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>"; }; 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; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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 */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
5596BDB71BC8F220007E38D5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
754BE45119693E190098E6F3 /* Frameworks */ = { 754BE45119693E190098E6F3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
75445821196AA2A5002FF20E /* Security.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -194,6 +276,13 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
75DF776B1BC8EB59006E9520 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
@ -220,6 +309,8 @@
children = ( children = (
754BE45519693E190098E6F3 /* CryptoSwift.framework */, 754BE45519693E190098E6F3 /* CryptoSwift.framework */,
754BE46019693E190098E6F3 /* CryptoSwiftTests.xctest */, 754BE46019693E190098E6F3 /* CryptoSwiftTests.xctest */,
75DF77721BC8EB59006E9520 /* CryptoSwift.framework */,
5596BDBB1BC8F220007E38D5 /* CryptoSwift.framework */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
@ -227,7 +318,7 @@
754BE45719693E190098E6F3 /* CryptoSwift */ = { 754BE45719693E190098E6F3 /* CryptoSwift */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
754BE45A19693E190098E6F3 /* CryptoSwift.h */, 75FB9C941BB8A4BD009CAFC5 /* Foundation */,
7552614D1993051E000D2B20 /* Hash.swift */, 7552614D1993051E000D2B20 /* Hash.swift */,
7563B2E719B14D4300B152CD /* Cipher.swift */, 7563B2E719B14D4300B152CD /* Cipher.swift */,
75BC3AE21A4E412000ADF343 /* CipherBlockMode.swift */, 75BC3AE21A4E412000ADF343 /* CipherBlockMode.swift */,
@ -245,19 +336,19 @@
758A94251A65AEB100E46135 /* HMAC.swift */, 758A94251A65AEB100E46135 /* HMAC.swift */,
75A74B261A1FF6B2004419F1 /* AES.swift */, 75A74B261A1FF6B2004419F1 /* AES.swift */,
759D481019B517BC005FF7FC /* BitExtension.swift */, 759D481019B517BC005FF7FC /* BitExtension.swift */,
758F3F771992F6CE0014BBDA /* UInt8Extension.swift */,
7547195019931802002FA5F1 /* IntExtension.swift */, 7547195019931802002FA5F1 /* IntExtension.swift */,
758C764219B61DE900653BC6 /* UInt16Extension.swift */, 758F3F771992F6CE0014BBDA /* UInt8Extension.swift */,
75D94E2519B60C4F007CB2A4 /* UInt32Extension.swift */, 75D94E2519B60C4F007CB2A4 /* UInt32Extension.swift */,
75D94E2719B60DDE007CB2A4 /* UInt64Extension.swift */, 75D94E2719B60DDE007CB2A4 /* UInt64Extension.swift */,
752DEF7619693EA000E17557 /* NSDataExtension.swift */, 754C8FEC19979F94005AD904 /* Array+Extension.swift */,
754C8FEC19979F94005AD904 /* ArrayExtension.swift */, 75D63F761BB840050041579B /* ArraySlice<UInt8>+Bytes.swift */,
7599C9C5199EA28700A3988B /* StringExtension.swift */, 75232CCD1BC6E6AC007F68B1 /* CSArrayType+Extensions.swift */,
7599C9C5199EA28700A3988B /* String+Extension.swift */,
75D94E2319B60C08007CB2A4 /* Operators.swift */, 75D94E2319B60C08007CB2A4 /* Operators.swift */,
75164E4819AD30AC00737F30 /* Utils.swift */, 75164E4819AD30AC00737F30 /* Utils.swift */,
758C764019B61AE500653BC6 /* Generics.swift */, 758C764019B61AE500653BC6 /* Generics.swift */,
75BE4EB01B1E4A9F007A2B57 /* IntegerConvertible.swift */, 75BE4EB01B1E4A9F007A2B57 /* IntegerConvertible.swift */,
75D2D19F1B5689EB000A2615 /* NSDataSequence.swift */, 75D63F741BB711270041579B /* BytesSequence.swift */,
754BE45819693E190098E6F3 /* Supporting Files */, 754BE45819693E190098E6F3 /* Supporting Files */,
); );
path = CryptoSwift; path = CryptoSwift;
@ -296,23 +387,67 @@
name = "Supporting Files"; name = "Supporting Files";
sourceTree = "<group>"; 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 */ /* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */ /* Begin PBXHeadersBuildPhase section */
5596BDB81BC8F220007E38D5 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
754BE45219693E190098E6F3 /* Headers */ = { 754BE45219693E190098E6F3 /* Headers */ = {
isa = PBXHeadersBuildPhase; isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
754BE45B19693E190098E6F3 /* CryptoSwift.h in Headers */, );
runOnlyForDeploymentPostprocessing = 0;
};
75DF776C1BC8EB59006E9520 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXHeadersBuildPhase section */ /* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
754BE45419693E190098E6F3 /* CryptoSwift */ = { 5596BDBA1BC8F220007E38D5 /* CryptoSwift watchOS */ = {
isa = PBXNativeTarget; 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 = ( buildPhases = (
754BE45019693E190098E6F3 /* Sources */, 754BE45019693E190098E6F3 /* Sources */,
754BE45119693E190098E6F3 /* Frameworks */, 754BE45119693E190098E6F3 /* Frameworks */,
@ -324,7 +459,7 @@
); );
dependencies = ( dependencies = (
); );
name = CryptoSwift; name = "CryptoSwift iOS";
productName = CryptoSwift; productName = CryptoSwift;
productReference = 754BE45519693E190098E6F3 /* CryptoSwift.framework */; productReference = 754BE45519693E190098E6F3 /* CryptoSwift.framework */;
productType = "com.apple.product-type.framework"; productType = "com.apple.product-type.framework";
@ -353,6 +488,25 @@
productReference = 754BE46019693E190098E6F3 /* CryptoSwiftTests.xctest */; productReference = 754BE46019693E190098E6F3 /* CryptoSwiftTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test"; 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 */ /* End PBXNativeTarget section */
/* Begin PBXProject section */ /* Begin PBXProject section */
@ -363,8 +517,8 @@
LastUpgradeCheck = 0700; LastUpgradeCheck = 0700;
ORGANIZATIONNAME = "Marcin Krzyzanowski"; ORGANIZATIONNAME = "Marcin Krzyzanowski";
TargetAttributes = { TargetAttributes = {
3F8849E11B0647D6006AB604 = { 5596BDBA1BC8F220007E38D5 = {
CreatedOnToolsVersion = 6.3.1; CreatedOnToolsVersion = 7.0.1;
}; };
754BE45419693E190098E6F3 = { 754BE45419693E190098E6F3 = {
CreatedOnToolsVersion = 6.0; CreatedOnToolsVersion = 6.0;
@ -387,14 +541,22 @@
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
targets = ( targets = (
754BE45419693E190098E6F3 /* CryptoSwift */, 754BE45419693E190098E6F3 /* CryptoSwift iOS */,
5596BDBA1BC8F220007E38D5 /* CryptoSwift watchOS */,
75DF77461BC8EB59006E9520 /* CryptoSwift OSX */,
754BE45F19693E190098E6F3 /* CryptoSwiftTests */, 754BE45F19693E190098E6F3 /* CryptoSwiftTests */,
3F8849E11B0647D6006AB604 /* CryptoSwift-Universal */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
5596BDB91BC8F220007E38D5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
754BE45319693E190098E6F3 /* Resources */ = { 754BE45319693E190098E6F3 /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -410,54 +572,93 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXResourcesBuildPhase section */ 75DF776D1BC8EB59006E9520 /* Resources */ = {
isa = PBXResourcesBuildPhase;
/* Begin PBXShellScriptBuildPhase section */
3F8849E51B0647DD006AB604 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0; 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 */ /* 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 */ = { 754BE45019693E190098E6F3 /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
75D2D1A01B5689EB000A2615 /* NSDataSequence.swift in Sources */,
75D94E2819B60DDE007CB2A4 /* UInt64Extension.swift in Sources */, 75D94E2819B60DDE007CB2A4 /* UInt64Extension.swift in Sources */,
751C5C3D19B26B000094C75D /* Poly1305.swift in Sources */, 751C5C3D19B26B000094C75D /* Poly1305.swift in Sources */,
7552614E1993051E000D2B20 /* Hash.swift in Sources */, 7552614E1993051E000D2B20 /* Hash.swift in Sources */,
75BC3AE31A4E412000ADF343 /* CipherBlockMode.swift in Sources */, 75BC3AE31A4E412000ADF343 /* CipherBlockMode.swift in Sources */,
75BE4EB11B1E4A9F007A2B57 /* IntegerConvertible.swift in Sources */, 75BE4EB11B1E4A9F007A2B57 /* IntegerConvertible.swift in Sources */,
7539E32E1B3B4E970037F4E1 /* SHA2.swift in Sources */, 7539E32E1B3B4E970037F4E1 /* SHA2.swift in Sources */,
7539E32C1B3B4C750037F4E1 /* StringExtension.swift in Sources */, 7539E32C1B3B4C750037F4E1 /* String+Extension.swift in Sources */,
7563B2E819B14D4300B152CD /* Cipher.swift in Sources */, 7563B2E819B14D4300B152CD /* Cipher.swift in Sources */,
7539E32B1B3B4C6B0037F4E1 /* HMAC.swift in Sources */, 7539E32B1B3B4C6B0037F4E1 /* HMAC.swift in Sources */,
7539E32A1B3B4C480037F4E1 /* NSDataExtension.swift in Sources */,
75EB380119ABDD710002375A /* ChaCha20.swift in Sources */, 75EB380119ABDD710002375A /* ChaCha20.swift in Sources */,
75FB9C9A1BB8A4BD009CAFC5 /* AES+Foundation.swift in Sources */,
75A663A61AA0CAD00052110B /* Padding.swift in Sources */, 75A663A61AA0CAD00052110B /* Padding.swift in Sources */,
75164E4919AD30AC00737F30 /* Utils.swift in Sources */, 75164E4919AD30AC00737F30 /* Utils.swift in Sources */,
75D63F751BB711270041579B /* BytesSequence.swift in Sources */,
75FB9C9C1BB8A4BD009CAFC5 /* ChaCha20+Foundation.swift in Sources */,
759D481119B517BC005FF7FC /* BitExtension.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 */, 7539E3291B3B4A530037F4E1 /* MD5.swift in Sources */,
75FB9C9B1BB8A4BD009CAFC5 /* Array<UInt8>+Foundation.swift in Sources */,
7547195119931802002FA5F1 /* IntExtension.swift in Sources */, 7547195119931802002FA5F1 /* IntExtension.swift in Sources */,
758C764319B61DE900653BC6 /* UInt16Extension.swift in Sources */,
75D94E2419B60C08007CB2A4 /* Operators.swift in Sources */, 75D94E2419B60C08007CB2A4 /* Operators.swift in Sources */,
75FB9C9D1BB8A4BD009CAFC5 /* NSData+Extension.swift in Sources */,
7539E32D1B3B4E950037F4E1 /* SHA1.swift in Sources */, 7539E32D1B3B4E950037F4E1 /* SHA1.swift in Sources */,
75FB9C9E1BB8A4BD009CAFC5 /* Utils+Foundation.swift in Sources */,
75B0A5701AB1A1BB000BD8D2 /* PKCS5.swift in Sources */, 75B0A5701AB1A1BB000BD8D2 /* PKCS5.swift in Sources */,
757EF7F519AAA82400586276 /* CRC.swift in Sources */, 757EF7F519AAA82400586276 /* CRC.swift in Sources */,
75D94E2619B60C4F007CB2A4 /* UInt32Extension.swift in Sources */, 75D94E2619B60C4F007CB2A4 /* UInt32Extension.swift in Sources */,
759B0A9C1BCDAB1200AF902E /* String+FoundationExtension.swift in Sources */,
75A74B271A1FF6B2004419F1 /* AES.swift in Sources */, 75A74B271A1FF6B2004419F1 /* AES.swift in Sources */,
75D63F771BB840050041579B /* ArraySlice<UInt8>+Bytes.swift in Sources */,
754C30B71AA13BC000E6FFA4 /* PKCS7.swift in Sources */, 754C30B71AA13BC000E6FFA4 /* PKCS7.swift in Sources */,
755111E819B7B7DF00C2AD86 /* Authenticator.swift in Sources */, 755111E819B7B7DF00C2AD86 /* Authenticator.swift in Sources */,
754DD76E19A149AF00E52288 /* HashProtocol.swift in Sources */, 754DD76E19A149AF00E52288 /* HashProtocol.swift in Sources */,
@ -481,58 +682,131 @@
); );
runOnlyForDeploymentPostprocessing = 0; 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 */ /* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */ /* Begin PBXTargetDependency section */
75B601E4197D69EB0009B53D /* PBXTargetDependency */ = { 75B601E4197D69EB0009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */; target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B601E3197D69EB0009B53D /* PBXContainerItemProxy */; targetProxy = 75B601E3197D69EB0009B53D /* PBXContainerItemProxy */;
}; };
75B601E6197D6A270009B53D /* PBXTargetDependency */ = { 75B601E6197D6A270009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */; target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B601E5197D6A270009B53D /* PBXContainerItemProxy */; targetProxy = 75B601E5197D6A270009B53D /* PBXContainerItemProxy */;
}; };
75B601E8197D6A3A0009B53D /* PBXTargetDependency */ = { 75B601E8197D6A3A0009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */; target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B601E7197D6A3A0009B53D /* PBXContainerItemProxy */; targetProxy = 75B601E7197D6A3A0009B53D /* PBXContainerItemProxy */;
}; };
75B601EA197D6A5C0009B53D /* PBXTargetDependency */ = { 75B601EA197D6A5C0009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */; target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B601E9197D6A5C0009B53D /* PBXContainerItemProxy */; targetProxy = 75B601E9197D6A5C0009B53D /* PBXContainerItemProxy */;
}; };
75B601ED197D6B3D0009B53D /* PBXTargetDependency */ = { 75B601ED197D6B3D0009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */; target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B601EC197D6B3D0009B53D /* PBXContainerItemProxy */; targetProxy = 75B601EC197D6B3D0009B53D /* PBXContainerItemProxy */;
}; };
75B6021D197D6CF10009B53D /* PBXTargetDependency */ = { 75B6021D197D6CF10009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */; target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B6021C197D6CF10009B53D /* PBXContainerItemProxy */; targetProxy = 75B6021C197D6CF10009B53D /* PBXContainerItemProxy */;
}; };
75B6021F197D6D070009B53D /* PBXTargetDependency */ = { 75B6021F197D6D070009B53D /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
target = 754BE45419693E190098E6F3 /* CryptoSwift */; target = 754BE45419693E190098E6F3 /* CryptoSwift iOS */;
targetProxy = 75B6021E197D6D070009B53D /* PBXContainerItemProxy */; targetProxy = 75B6021E197D6D070009B53D /* PBXContainerItemProxy */;
}; };
/* End PBXTargetDependency section */ /* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
3F8849E31B0647D6006AB604 /* Debug */ = { 5596BDC11BC8F220007E38D5 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { 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; name = Debug;
}; };
3F8849E41B0647D6006AB604 /* Release */ = { 5596BDC21BC8F220007E38D5 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { 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; name = Release;
}; };
@ -553,7 +827,6 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
@ -573,9 +846,12 @@
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.9;
METAL_ENABLE_DEBUG_INFO = YES; METAL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = CryptoSwift;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_INSTALL_OBJC_HEADER = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
@ -600,7 +876,6 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = YES; COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
@ -613,8 +888,11 @@
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.9;
METAL_ENABLE_DEBUG_INFO = NO; METAL_ENABLE_DEBUG_INFO = NO;
PRODUCT_NAME = CryptoSwift;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_INSTALL_OBJC_HEADER = NO;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
@ -626,22 +904,19 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES; APPLICATION_EXTENSION_API_ONLY = YES;
BITCODE_GENERATION_MODE = marker;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
DEFINES_MODULE = YES; CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer";
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1; DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath"; 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; INFOPLIST_FILE = CryptoSwift/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.hakore.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_BUNDLE_IDENTIFIER = "com.hakore.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = CryptoSwift;
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
}; };
@ -651,25 +926,22 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES; APPLICATION_EXTENSION_API_ONLY = YES;
BITCODE_GENERATION_MODE = bitcode;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
DEFINES_MODULE = YES; CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer";
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1; DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath"; DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_TESTABILITY = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_UNROLL_LOOPS = YES; 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; INFOPLIST_FILE = CryptoSwift/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LLVM_LTO = YES; LLVM_LTO = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.hakore.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_BUNDLE_IDENTIFIER = "com.hakore.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = CryptoSwift;
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_DISABLE_SAFETY_CHECKS = YES; SWIFT_DISABLE_SAFETY_CHECKS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_OPTIMIZATION_LEVEL = "-O";
@ -720,14 +992,64 @@
}; };
name = Release; 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 */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */ /* Begin XCConfigurationList section */
3F8849E21B0647D6006AB604 /* Build configuration list for PBXAggregateTarget "CryptoSwift-Universal" */ = { 5596BDC01BC8F220007E38D5 /* Build configuration list for PBXNativeTarget "CryptoSwift watchOS" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
3F8849E31B0647D6006AB604 /* Debug */, 5596BDC11BC8F220007E38D5 /* Debug */,
3F8849E41B0647D6006AB604 /* Release */, 5596BDC21BC8F220007E38D5 /* Release */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
@ -741,7 +1063,7 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
754BE46B19693E190098E6F3 /* Build configuration list for PBXNativeTarget "CryptoSwift" */ = { 754BE46B19693E190098E6F3 /* Build configuration list for PBXNativeTarget "CryptoSwift iOS" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
754BE46C19693E190098E6F3 /* Debug */, 754BE46C19693E190098E6F3 /* Debug */,
@ -759,6 +1081,15 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
75DF776F1BC8EB59006E9520 /* Build configuration list for PBXNativeTarget "CryptoSwift OSX" */ = {
isa = XCConfigurationList;
buildConfigurations = (
75DF77701BC8EB59006E9520 /* Debug */,
75DF77711BC8EB59006E9520 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */ /* End XCConfigurationList section */
}; };
rootObject = 754BE44C19693E190098E6F3 /* Project object */; rootObject = 754BE44C19693E190098E6F3 /* Project object */;

View File

@ -4,6 +4,37 @@
<dict> <dict>
<key>runDestinationsByUUID</key> <key>runDestinationsByUUID</key>
<dict> <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> <key>9396A4FE-F8F7-4542-8F75-DE77E1FEBEB9</key>
<dict> <dict>
<key>localComputer</key> <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. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
final public class AES { final public class AES {
enum Error: ErrorType { enum Error: ErrorType {
case BlockSizeExceeded case BlockSizeExceeded
case InvalidKeyOrInitializationVector
case InvalidInitializationVector
} }
public enum AESVariant:Int { public enum AESVariant:Int {
@ -47,54 +47,15 @@ final public class AES {
} }
private let key:[UInt8] private let key:[UInt8]
private let iv:[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] = [ private lazy var sBoxes:(sBox:[UInt32], invSBox:[UInt32]) = self.calculateSBox()
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, private lazy var sBox:[UInt32] = self.sBoxes.sBox
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, private lazy var sBoxInv:[UInt32] = self.sBoxes.invSBox
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]
// Parameters for Linear Congruence Generators // 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, 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, 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, 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, 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] 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.key = key
self.iv = iv self.iv = iv
self.blockMode = blockMode self.blockMode = blockMode
if (blockMode.needIV && iv.count != AES.blockSize) { if (blockMode.needIV && iv.count != AES.blockSize) {
assert(false, "Block size and Initialization Vector must be the same length!") 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... // default IV is all 0x00...
let defaultIV = [UInt8](count: AES.blockSize, repeatedValue: 0) 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. 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 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) return try blockMode.encryptBlocks(blocks, iv: self.iv, cipherOperation: encryptBlock)
} }
private func encryptBlock(block:[UInt8]) -> [UInt8]? { 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 for r in 0..<rounds - 1 {
var state:[[UInt8]] = [[UInt8]](count: variant.Nb, repeatedValue: [UInt8](count: variant.Nb, repeatedValue: 0)) t[0] = b[0] ^ rk[r][0]
for (i, row) in state.enumerate() { t[1] = b[1] ^ rk[r][1]
for (j, _) in row.enumerate() { t[2] = b[2] ^ rk[r][2]
state[j][i] = block[i * row.count + j] t[3] = b[3] ^ rk[r][3]
}
}
state = addRoundKey(state,expandedKey, 0) 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)]
for roundCount in 1..<variant.Nr { b[2] = T0[Int(t[2] & 0xFF)] ^ T1[Int((t[3] >> 8) & 0xFF)] ^ T2[Int((t[0] >> 16) & 0xFF)] ^ T3[Int(t[1] >> 24)]
subBytes(&state) b[3] = T0[Int(t[3] & 0xFF)] ^ T1[Int((t[0] >> 8) & 0xFF)] ^ T2[Int((t[1] >> 16) & 0xFF)] ^ T3[Int(t[2] >> 24)]
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]
}
}
} }
// 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 return out
} }
@ -217,37 +192,87 @@ final public class AES {
} }
private func decryptBlock(block:[UInt8]) -> [UInt8]? { private func decryptBlock(block:[UInt8]) -> [UInt8]? {
var state:[[UInt8]] = [[UInt8]](count: variant.Nb, repeatedValue: [UInt8](count: variant.Nb, repeatedValue: 0)) let rounds = self.variant.Nr
for (i, row) in state.enumerate() { let rk = expandedKeyInv
for (j, _) in row.enumerate() { var b = toUInt32Array(block[block.startIndex..<block.endIndex])
state[j][i] = block[i * row.count + j]
} 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() { // rounds
state = invShiftRows(state) 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]
state = invSubBytes(state) 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]
state = addRoundKey(state, expandedKey, roundCount) 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]
state = invMixColumns(state) 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) var out = [UInt8]()
state = invSubBytes(state) out.reserveCapacity(b.count * 4)
state = addRoundKey(state, expandedKey, 0) for num in b {
out.append(UInt8(num & 0xFF))
var out:[UInt8] = [UInt8]() out.append(UInt8((num >> 8) & 0xFF))
for i in 0..<state.count { out.append(UInt8((num >> 16) & 0xFF))
for j in 0..<state[0].count { out.append(UInt8((num >> 24) & 0xFF))
out.append(state[j][i])
}
} }
return out 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 * 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] { func subWord(word:[UInt8]) -> [UInt8] {
var result = word var result = word
for i in 0..<4 { for i in 0..<4 {
result[i] = self.sBox[Int(word[i])] result[i] = UInt8(sBox[Int(word[i])])
} }
return result return result
} }
@ -277,9 +302,8 @@ final public class AES {
tmp[wordIdx] = w[4*(i-1)+wordIdx] tmp[wordIdx] = w[4*(i-1)+wordIdx]
} }
if ((i % variant.Nk) == 0) { if ((i % variant.Nk) == 0) {
let rotWord = rotateLeft(UInt32.withBytes(tmp), n: 8).bytes(sizeof(UInt32)) // RotWord tmp = subWord(rotateLeft(UInt32.withBytes(tmp), 8).bytes(sizeof(UInt32)))
tmp = subWord(rotWord) tmp[0] = tmp.first! ^ Rcon[i/variant.Nk]
tmp[0] = tmp[0] ^ Rcon[i/variant.Nk]
} else if (variant.Nk > 6 && (i % variant.Nk) == 4) { } else if (variant.Nk > 6 && (i % variant.Nk) == 4) {
tmp = subWord(tmp) tmp = subWord(tmp)
} }
@ -289,145 +313,69 @@ final public class AES {
w[4*i+wordIdx] = w[4*(i-variant.Nk)+wordIdx]^tmp[wordIdx]; w[4*i+wordIdx] = w[4*(i-variant.Nk)+wordIdx]^tmp[wordIdx];
} }
} }
return w; return convertExpandedKey(w)
} }
} }
extension AES { extension AES {
// byte substitution with table (S-box) private func B0(x: UInt32) -> UInt32 {
public func subBytes(inout state:[[UInt8]]) { return x & 0xFF
for (i,row) in state.enumerate() {
for (j,value) in row.enumerate() {
state[i][j] = AES.sBox[Int(value)]
}
}
} }
public func invSubBytes(state:[[UInt8]]) -> [[UInt8]] { private func B1(x: UInt32) -> UInt32 {
var result = state return (x >> 8) & 0xFF
for (i,row) in state.enumerate() { }
for (j,value) in row.enumerate() {
result[i][j] = AES.invSBox[Int(value)] 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 return result
} }
// Applies a cyclic shift to the last 3 rows of a state matrix. private func calculateSBox() -> (sBox:[UInt32], invSBox:[UInt32]) {
public func shiftRows(state:[[UInt8]]) -> [[UInt8]] { var sbox = [UInt32](count: 256, repeatedValue: 0)
var result = state var invsbox = sbox
for r in 1..<4 { sbox[0] = 0x63
for c in 0..<variant.Nb {
result[r][c] = state[r][(c + r) % variant.Nb] var p:UInt8 = 1, q:UInt8 = 1
}
} repeat {
return result 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]] { public func cipherDecrypt(bytes: [UInt8]) throws -> [UInt8] {
var result = state return try self.decrypt(bytes)
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
} }
} }

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. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
/** /**
* Message Authentication * Message Authentication
*/ */
public enum Authenticator { public enum Authenticator {
public enum Error: ErrorType {
case AuthenticateError
}
/** /**
Poly1305 Poly1305
@ -25,12 +28,18 @@ public enum Authenticator {
- returns: 16-byte message authentication code - returns: 16-byte message authentication code
*/ */
public func authenticate(message: [UInt8]) -> [UInt8]? { public func authenticate(message: [UInt8]) throws -> [UInt8] {
switch (self) { switch (self) {
case .Poly1305(let key): 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): 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. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
extension Bit { extension Bit {
func inverted() -> Bit { func inverted() -> Bit {
if (self == Bit.Zero) { if (self == Bit.Zero) {
return Bit.One return Bit.One
@ -17,8 +14,4 @@ extension Bit {
return Bit.Zero return Bit.Zero
} }
mutating func invert() {
self = self.inverted()
}
} }

View File

@ -6,11 +6,9 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
final class CRC { 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, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
@ -43,22 +41,58 @@ final class CRC {
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d] 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 var crc:UInt32 = 0xffffffff
for chunk in NSDataSequence(chunkSize: 256, data: message) { for chunk in BytesSequence(chunkSize: 256, data: message) {
for b in chunk.arrayOfBytes() { for b in chunk {
let idx = Int((crc ^ UInt32(b)) & 0xff) let idx = Int((crc ^ UInt32(b)) & 0xff)
crc = (crc >> 8) ^ table[idx] crc = (crc >> 8) ^ CRC.table32[idx]
} }
} }
return crc ^ 0xffffffff
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
} }
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. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
final public class ChaCha20 { final public class ChaCha20 {
enum Error: ErrorType { 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] { public func encrypt(bytes:[UInt8]) throws -> [UInt8] {
guard context != nil else { guard context != nil else {
throw Error.MissingContext 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) { private final func quarterround(inout a:UInt32, inout _ b:UInt32, inout _ c:UInt32, inout _ d:UInt32) {
a = a &+ b a = a &+ b
d = rotateLeft((d ^ a), n: 16) //FIXME: WAT? n: d = rotateLeft((d ^ a), 16) //FIXME: WAT? n:
c = c &+ d c = c &+ d
b = rotateLeft((b ^ c), n: 12); b = rotateLeft((b ^ c), 12);
a = a &+ b a = a &+ b
d = rotateLeft((d ^ a), n: 8); d = rotateLeft((d ^ a), 8);
c = c &+ d 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. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation import Darwin
public enum Cipher { public enum CipherError: ErrorType {
case Encrypt
public enum Error: ErrorType { case Decrypt
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 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] { static public func randomIV(blockSize:Int) -> [UInt8] {
var randomIV:[UInt8] = [UInt8](); var randomIV:[UInt8] = [UInt8]();
for (var i = 0; i < blockSize; i++) { for (var i = 0; i < blockSize; i++) {

View File

@ -6,8 +6,6 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
// I have no better name for that // I have no better name for that
typealias CipherOperationOnBlock = (block: [UInt8]) -> [UInt8]? typealias CipherOperationOnBlock = (block: [UInt8]) -> [UInt8]?
@ -85,7 +83,7 @@ private struct CBCMode: BlockMode {
} }
var out:[UInt8] = [UInt8]() 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 var prevCiphertext = iv // for the first time prevCiphertext = iv
for plaintext in blocks { for plaintext in blocks {
if let encrypted = cipherOperation(block: xor(prevCiphertext, b: plaintext)) { if let encrypted = cipherOperation(block: xor(prevCiphertext, b: plaintext)) {
@ -103,7 +101,7 @@ private struct CBCMode: BlockMode {
} }
var out:[UInt8] = [UInt8]() 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 var prevCiphertext = iv // for the first time prevCiphertext = iv
for ciphertext in blocks { for ciphertext in blocks {
if let decrypted = cipherOperation(block: ciphertext) { // decrypt if let decrypted = cipherOperation(block: ciphertext) { // decrypt
@ -128,12 +126,12 @@ private struct CFBMode: BlockMode {
} }
var out:[UInt8] = [UInt8]() var out:[UInt8] = [UInt8]()
out.reserveCapacity(blocks.count * blocks[0].count) out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
var lastCiphertext = iv var lastCiphertext = iv
for plaintext in blocks { for plaintext in blocks {
if let encrypted = cipherOperation(block: lastCiphertext) { if let ciphertext = cipherOperation(block: lastCiphertext) {
lastCiphertext = xor(plaintext,b: encrypted) lastCiphertext = xor(plaintext,b: ciphertext)
out.appendContentsOf(lastCiphertext) out.appendContentsOf(lastCiphertext)
} }
} }
@ -141,7 +139,22 @@ private struct CFBMode: BlockMode {
} }
func decryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) throws -> [UInt8] { 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] { func encryptBlocks(blocks:[[UInt8]], iv:[UInt8]?, cipherOperation:CipherOperationOnBlock) -> [UInt8] {
var out:[UInt8] = [UInt8]() var out:[UInt8] = [UInt8]()
out.reserveCapacity(blocks.count * blocks[0].count) out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
for plaintext in blocks { for plaintext in blocks {
if let encrypted = cipherOperation(block: plaintext) { if let encrypted = cipherOperation(block: plaintext) {
out.appendContentsOf(encrypted) out.appendContentsOf(encrypted)
@ -193,7 +206,7 @@ private struct CTRMode: BlockMode {
var counter:UInt = 0 var counter:UInt = 0
var out:[UInt8] = [UInt8]() var out:[UInt8] = [UInt8]()
out.reserveCapacity(blocks.count * blocks[0].count) out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
for plaintext in blocks { for plaintext in blocks {
let nonce = buildNonce(iv, counter: counter++) let nonce = buildNonce(iv, counter: counter++)
if let encrypted = cipherOperation(block: nonce) { if let encrypted = cipherOperation(block: nonce) {
@ -210,7 +223,7 @@ private struct CTRMode: BlockMode {
var counter:UInt = 0 var counter:UInt = 0
var out:[UInt8] = [UInt8]() var out:[UInt8] = [UInt8]()
out.reserveCapacity(blocks.count * blocks[0].count) out.reserveCapacity(blocks.count * blocks[blocks.startIndex].count)
for plaintext in blocks { for plaintext in blocks {
let nonce = buildNonce(iv, counter: counter++) let nonce = buildNonce(iv, counter: counter++)
if let encrypted = cipherOperation(block: nonce) { 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. // 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 and extensions for integerFromBitsArray. Bit hakish for me, but I can't do it in any other way */
protocol Initiable { protocol Initiable {
init(_ v: Int) init(_ v: Int)
@ -46,11 +44,11 @@ func integerWithBytes<T: IntegerType where T:ByteConvertible, T: BitshiftOperati
} }
if sizeof(T) == 1 { if sizeof(T) == 1 {
return T(truncatingBitPattern: UInt64(bytes[0])) return T(truncatingBitPattern: UInt64(bytes.first!))
} }
var result: T = 0 var result: T = 0
for byte in Array(bytes.reverse()) { //FIXME: Array?? for byte in bytes.reverse() {
result = result << 8 | T(byte) result = result << 8 | T(byte)
} }
return result return result

View File

@ -6,8 +6,6 @@
// Copyright (c) 2015 Marcin Krzyzanowski. All rights reserved. // Copyright (c) 2015 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
final public class HMAC { final public class HMAC {
public enum Variant { public enum Variant {
@ -16,7 +14,7 @@ final public class HMAC {
var size:Int { var size:Int {
switch (self) { switch (self) {
case .sha1: case .sha1:
return SHA1(NSData()).size return SHA1.size
case .sha256: case .sha256:
return SHA2.Variant.sha256.size return SHA2.Variant.sha256.size
case .sha384: case .sha384:
@ -24,22 +22,22 @@ final public class HMAC {
case .sha512: case .sha512:
return SHA2.Variant.sha512.size return SHA2.Variant.sha512.size
case .md5: case .md5:
return MD5(NSData()).size return MD5.size
} }
} }
func calculateHash(bytes bytes:[UInt8]) -> [UInt8]? { func calculateHash(bytes bytes:[UInt8]) -> [UInt8]? {
switch (self) { switch (self) {
case .sha1: case .sha1:
return NSData.withBytes(bytes).sha1()?.arrayOfBytes() return Hash.sha1(bytes).calculate()
case .sha256: case .sha256:
return NSData.withBytes(bytes).sha256()?.arrayOfBytes() return Hash.sha256(bytes).calculate()
case .sha384: case .sha384:
return NSData.withBytes(bytes).sha384()?.arrayOfBytes() return Hash.sha384(bytes).calculate()
case .sha512: case .sha512:
return NSData.withBytes(bytes).sha512()?.arrayOfBytes() return Hash.sha512(bytes).calculate()
case .md5: 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. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
public enum Hash { public enum Hash {
case md5(NSData) case md5(Array<UInt8>)
case sha1(NSData) case sha1(Array<UInt8>)
case sha224(NSData), sha256(NSData), sha384(NSData), sha512(NSData) case sha224(Array<UInt8>), sha256(Array<UInt8>), sha384(Array<UInt8>), sha512(Array<UInt8>)
case crc32(NSData) case crc32(Array<UInt8>)
case crc16(Array<UInt8>)
public func calculate() -> NSData? { public func calculate() -> [UInt8] {
switch self { switch self {
case md5(let data): case md5(let bytes):
return MD5(data).calculate() return MD5(bytes).calculate()
case sha1(let data): case sha1(let bytes):
return SHA1(data).calculate() return SHA1(bytes).calculate()
case sha224(let data): case sha224(let bytes):
return SHA2(data, variant: .sha224).calculate32() return SHA2(bytes, variant: .sha224).calculate32()
case sha256(let data): case sha256(let bytes):
return SHA2(data, variant: .sha256).calculate32() return SHA2(bytes, variant: .sha256).calculate32()
case sha384(let data): case sha384(let bytes):
return SHA2(data, variant: .sha384).calculate64() return SHA2(bytes, variant: .sha384).calculate64()
case sha512(let data): case sha512(let bytes):
return SHA2(data, variant: .sha512).calculate64() return SHA2(bytes, variant: .sha512).calculate64()
case crc32(let data): case crc32(let bytes):
return CRC().crc32(data); 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. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
internal protocol HashProtocol { internal protocol HashProtocol {
var message: NSData { get } var message: Array<UInt8> { get }
/** Common part for hash calculation. Prepare header data. */ /** Common part for hash calculation. Prepare header data. */
func prepare(len:Int) -> NSMutableData func prepare(len:Int) -> Array<UInt8>
} }
extension HashProtocol { extension HashProtocol {
func prepare(len:Int) -> NSMutableData { func prepare(len:Int) -> Array<UInt8> {
let tmpMessage: NSMutableData = NSMutableData(data: self.message) var tmpMessage = message
// Step 1. Append Padding Bits // 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) // append "0" bit until message length in bits 448 (mod 512)
var msgLength = tmpMessage.length var msgLength = tmpMessage.count
var counter = 0 var counter = 0
while msgLength % len != (len - 8) { while msgLength % len != (len - 8) {
counter++ counter++
msgLength++ msgLength++
} }
let bufZeros = UnsafeMutablePointer<UInt8>(calloc(counter, sizeof(UInt8))) tmpMessage += Array<UInt8>(count: counter, repeatedValue: 0)
tmpMessage.appendBytes(bufZeros, length: counter)
bufZeros.destroy()
bufZeros.dealloc(1)
return tmpMessage return tmpMessage
} }
} }

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.0.16</string> <string>0.1.1</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <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. // - 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. // - This notice may not be removed or altered from any source or binary distribution.
import Foundation import Darwin
/* array of bits */ /* array of bits */
extension Int { extension Int {

View File

@ -6,8 +6,6 @@
// Copyright (c) 2015 Marcin Krzyzanowski. All rights reserved. // Copyright (c) 2015 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
protocol BitshiftOperationsType { protocol BitshiftOperationsType {
func <<(lhs: Self, rhs: Self) -> Self func <<(lhs: Self, rhs: Self) -> Self
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. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
final class MD5 : HashProtocol { final class MD5 : HashProtocol {
var size:Int = 16 // 128 / 8 static let size:Int = 16 // 128 / 8
let message: NSData let message: Array<UInt8>
init (_ message: NSData) { init (_ message: Array<UInt8>) {
self.message = message self.message = message
} }
@ -42,24 +40,24 @@ final class MD5 : HashProtocol {
private let h:[UInt32] = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476] private let h:[UInt32] = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]
func calculate() -> NSData { func calculate() -> [UInt8] {
let tmpMessage = prepare(64) var tmpMessage = prepare(64)
tmpMessage.reserveCapacity(tmpMessage.count + 4)
// hash values // initialize hh with hash values
var hh = h var hh = h
// Step 2. Append Length a 64-bit representation of lengthInBits // 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) let lengthBytes = lengthInBits.bytes(64 / 8)
tmpMessage.appendBytes(Array(lengthBytes.reverse())); //FIXME: Array? tmpMessage += lengthBytes.reverse()
// Process the message in successive 512-bit chunks: // Process the message in successive 512-bit chunks:
let chunkSizeBytes = 512 / 8 // 64 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 // break chunk into sixteen 32-bit words M[j], 0 j 15
var M = [UInt32](count: 16, repeatedValue: 0) var M = toUInt32Array(chunk)
let range = NSRange(location:0, length: M.count * sizeof(UInt32)) assert(M.count == 16, "Invalid array")
chunk.getBytes(UnsafeMutablePointer<Void>(M), range: range)
// Initialize hash value for this chunk: // Initialize hash value for this chunk:
var A:UInt32 = hh[0] var A:UInt32 = hh[0]
@ -97,7 +95,7 @@ final class MD5 : HashProtocol {
dTemp = D dTemp = D
D = C D = C
C = B 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 A = dTemp
} }
@ -107,13 +105,14 @@ final class MD5 : HashProtocol {
hh[3] = hh[3] &+ D hh[3] = hh[3] &+ D
} }
let buf: NSMutableData = NSMutableData(); var result = [UInt8]()
hh.forEach({ (item) -> () in result.reserveCapacity(hh.count / 4)
var i:UInt32 = item.littleEndian
buf.appendBytes(&i, length: sizeofValue(i))
})
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 @see: https://medium.com/@krzyzanowskim/swiftly-shift-bits-and-protect-yourself-be33016ce071
*/ */
import Foundation
infix operator &<<= { infix operator &<<= {
associativity none associativity none
precedence 160 precedence 160

View File

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

View File

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

View File

@ -6,8 +6,6 @@
// Copyright (c) 2015 Marcin Krzyzanowski. All rights reserved. // Copyright (c) 2015 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
public protocol Padding { public protocol Padding {
func add(data: [UInt8], blockSize:Int) -> [UInt8] func add(data: [UInt8], blockSize:Int) -> [UInt8]
func remove(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 // 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. // message such that an attacker has a negligible chance of producing a valid tag for an inauthentic message.
import Foundation
final public class Poly1305 { final public class Poly1305 {
let blockSize = 16 let blockSize = 16
private var ctx:Context? private var ctx:Context?

View File

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

View File

@ -6,16 +6,15 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation import simd
final class SHA2 : HashProtocol { final class SHA2 : HashProtocol {
var size:Int { return variant.rawValue } var size:Int { return variant.rawValue }
let variant:SHA2.Variant 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.variant = variant
self.message = message self.message = message
} }
@ -102,25 +101,22 @@ final class SHA2 : HashProtocol {
} }
} }
private func resultingArray<T>(hh:[T]) -> [T] { private func resultingArray<T>(hh:[T]) -> ArraySlice<T> {
var finalHH:[T] = hh;
switch (self) { switch (self) {
case .sha224: case .sha224:
finalHH = Array(hh[0..<7]) return hh[0..<7]
break;
case .sha384: case .sha384:
finalHH = Array(hh[0..<6]) return hh[0..<6]
break;
default: default:
break; 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. //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 { func calculate32() -> [UInt8] {
let tmpMessage = self.prepare(64) var tmpMessage = self.prepare(64)
// hash values // hash values
var hh = [UInt32]() 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. // 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: // Process the message in successive 512-bit chunks:
let chunkSizeBytes = 512 / 8 // 64 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 // 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: // Extend the sixteen 32-bit words into sixty-four 32-bit words:
var M:[UInt32] = [UInt32](count: variant.k.count, repeatedValue: 0) var M:[UInt32] = [UInt32](count: variant.k.count, repeatedValue: 0)
for x in 0..<M.count { for x in 0..<M.count {
switch (x) { switch (x) {
case 0...15: case 0...15:
var le:UInt32 = 0 let start = chunk.startIndex + (x * sizeofValue(M[x]))
chunk.getBytes(&le, range:NSRange(location:x * sizeofValue(le), length: sizeofValue(le))); let end = start + sizeofValue(M[x])
let le = toUInt32Array(chunk[start..<end])[0]
M[x] = le.bigEndian M[x] = le.bigEndian
break break
default: default:
@ -191,17 +188,17 @@ final class SHA2 : HashProtocol {
} }
// Produce the final hash value (big-endian) as a 160 bit number: // Produce the final hash value (big-endian) as a 160 bit number:
let buf: NSMutableData = NSMutableData(); var result = [UInt8]()
variant.resultingArray(hh).forEach{ (item) -> () in result.reserveCapacity(hh.count / 4)
var i:UInt32 = UInt32(item.bigEndian) variant.resultingArray(hh).forEach {
buf.appendBytes(&i, length: sizeofValue(i)) let item = $0.bigEndian
result += [UInt8(item & 0xff), UInt8((item >> 8) & 0xff), UInt8((item >> 16) & 0xff), UInt8((item >> 24) & 0xff)]
} }
return result
return buf.copy() as! NSData;
} }
func calculate64() -> NSData { func calculate64() -> [UInt8] {
let tmpMessage = self.prepare(128) var tmpMessage = self.prepare(128)
// hash values // hash values
var hh = [UInt64]() 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. // 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: // Process the message in successive 1024-bit chunks:
let chunkSizeBytes = 1024 / 8 // 128 let chunkSizeBytes = 1024 / 8 // 128
var leftMessageBytes = tmpMessage.length for chunk in BytesSequence(chunkSize: chunkSizeBytes, data: tmpMessage) {
for var i = 0; i < tmpMessage.length; i = i + chunkSizeBytes, leftMessageBytes -= chunkSizeBytes {
let chunk = tmpMessage.subdataWithRange(NSRange(location: i, length: min(chunkSizeBytes,leftMessageBytes)))
// break chunk into sixteen 64-bit words M[j], 0 j 15, big-endian // 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: // Extend the sixteen 64-bit words into eighty 64-bit words:
var M = [UInt64](count: variant.k.count, repeatedValue: 0) var M = [UInt64](count: variant.k.count, repeatedValue: 0)
for x in 0..<M.count { for x in 0..<M.count {
switch (x) { switch (x) {
case 0...15: case 0...15:
var le:UInt64 = 0 let start = chunk.startIndex + (x * sizeofValue(M[x]))
chunk.getBytes(&le, range:NSRange(location:x * sizeofValue(le), length: sizeofValue(le))); let end = start + sizeofValue(M[x])
let le = toUInt64Array(chunk[start..<end])[0]
M[x] = le.bigEndian M[x] = le.bigEndian
break break
default: default:
@ -275,13 +271,13 @@ final class SHA2 : HashProtocol {
} }
// Produce the final hash value (big-endian) // Produce the final hash value (big-endian)
let buf: NSMutableData = NSMutableData(); var result = [UInt8]()
result.reserveCapacity(hh.count / 4)
variant.resultingArray(hh).forEach({ (item) -> () in variant.resultingArray(hh).forEach {
var i = item.bigEndian let item = $0.bigEndian
buf.appendBytes(&i, length: sizeofValue(i)) 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 buf.copy() as! NSData; 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. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation import Darwin
protocol _UInt32Type { }
extension UInt32: _UInt32Type {}
/** array of bytes */ /** array of bytes */
extension UInt32 { extension UInt32 {

View File

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

View File

@ -6,7 +6,17 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved. // 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 */ /** casting */
extension UInt8 { extension UInt8 {

View File

@ -6,21 +6,19 @@
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved. // 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)) 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)) 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)) 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)) 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); 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] { func xor(a: [UInt8], b:[UInt8]) -> [UInt8] {
var xored = [UInt8](count: a.count, repeatedValue: 0) var xored = [UInt8](count: a.count, repeatedValue: 0)
for i in 0..<xored.count { for i in 0..<xored.count {
xored[i] = a[i] ^ b[i] xored[i] = a[i] ^ b[i]
} }
return xored 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. // Created by Marcin Krzyzanowski on 27/12/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
import XCTest import XCTest
@testable import CryptoSwift @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]; 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 aes = try! AES(key: key, iv: iv, blockMode: .CBC)
let encrypted = try! aes.encrypt(input, padding: nil) let encrypted = try! aes.encrypt(input, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed") XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil) let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, input, "decryption failed") XCTAssertEqual(decrypted, input, "decryption failed")
} else {
XCTAssert(false, "failed")
}
} }
func testAES_encrypt3() { 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]; 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 aes = try! AES(key: key, iv: iv, blockMode: .CBC)
let encrypted = try! aes.encrypt(input, padding: nil) let encrypted = try! aes.encrypt(input, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed") XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil) let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, input, "decryption failed") XCTAssertEqual(decrypted, input, "decryption failed")
} else {
XCTAssert(false, "failed")
}
} }
func testAES_encrypt() { func testAES_encrypt() {
@ -59,14 +51,11 @@ final class AESTests: XCTestCase {
0xd8, 0xcd, 0xb7, 0x80, 0xd8, 0xcd, 0xb7, 0x80,
0x70, 0xb4, 0xc5, 0x5a]; 0x70, 0xb4, 0xc5, 0x5a];
if let aes = AES(key: aesKey, blockMode: .ECB) { let aes = try! AES(key: aesKey, blockMode: .ECB)
let encrypted = try! aes.encrypt(input, padding: nil) let encrypted = try! aes.encrypt(input, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed") XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil) let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, input, "decryption failed") XCTAssertEqual(decrypted, input, "decryption failed")
} else {
XCTAssert(false, "failed")
}
} }
func testAES_encrypt_cbc() { 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 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]; 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) { let aes = try! AES(key: key, iv:iv, blockMode: .CBC)
XCTAssertTrue(aes.blockMode == .CBC, "Invalid block mode") XCTAssertTrue(aes.blockMode == .CBC, "Invalid block mode")
let encrypted = try! aes.encrypt(plaintext, padding: nil) let encrypted = try! aes.encrypt(plaintext, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed") XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil) let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, plaintext, "decryption failed") XCTAssertEqual(decrypted, plaintext, "decryption failed")
} else {
XCTAssert(false, "failed")
}
} }
func testAES_encrypt_cfb() { 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 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]; 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) { let aes = try! AES(key: key, iv:iv, blockMode: .CFB)
XCTAssertTrue(aes.blockMode == .CFB, "Invalid block mode") XCTAssertTrue(aes.blockMode == .CFB, "Invalid block mode")
let encrypted = try! aes.encrypt(plaintext, padding: nil) let encrypted = try! aes.encrypt(plaintext, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed") XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil) let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, plaintext, "decryption failed") XCTAssertEqual(decrypted, plaintext, "decryption failed")
} else { }
XCTAssert(false, "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() { 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 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] 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) { let aes = try! AES(key: key, iv:iv, blockMode: .CTR)
XCTAssertTrue(aes.blockMode == .CTR, "Invalid block mode") XCTAssertTrue(aes.blockMode == .CTR, "Invalid block mode")
let encrypted = try! aes.encrypt(plaintext, padding: nil) let encrypted = try! aes.encrypt(plaintext, padding: nil)
XCTAssertEqual(encrypted, expected, "encryption failed") XCTAssertEqual(encrypted, expected, "encryption failed")
let decrypted = try! aes.decrypt(encrypted, padding: nil) let decrypted = try! aes.decrypt(encrypted, padding: nil)
XCTAssertEqual(decrypted, plaintext, "decryption failed") XCTAssertEqual(decrypted, plaintext, "decryption failed")
} else {
XCTAssert(false, "failed")
}
} }
func testAES_SubBytes() { func testAES_encrypt_performance() {
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() {
let key:[UInt8] = [0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c]; 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 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 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 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() { func testAESPerformanceCommonCrypto() {
let key:[UInt8] = [0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c]; 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 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. // Created by Marcin Krzyzanowski on 27/12/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
import XCTest import XCTest
@testable import CryptoSwift @testable import CryptoSwift
@ -52,20 +50,18 @@ final class ChaCha20Tests: XCTestCase {
let setup = (key: keys[idx], iv: ivs[idx]) let setup = (key: keys[idx], iv: ivs[idx])
do { do {
let encrypted = try Cipher.ChaCha20(setup).encrypt(message) let encrypted = try ChaCha20(setup)!.encrypt(message)
let decrypted = try Cipher.ChaCha20(setup).decrypt(encrypted) let decrypted = try ChaCha20(setup)!.decrypt(encrypted)
XCTAssertEqual(message, decrypted, "ChaCha20 decryption failed"); XCTAssertEqual(message, decrypted, "ChaCha20 decryption failed");
// check extension // check extension
let messageData = NSData(bytes: message, length: message.count); 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, "") XCTAssertNotNil(encrypted2, "")
if let encrypted2 = encrypted2 { XCTAssertEqual(NSData.withBytes(encrypted), encrypted2, "ChaCha20 extension failed")
XCTAssertEqual(NSData.withBytes(encrypted), encrypted2, "ChaCha20 extension failed") } catch CipherError.Encrypt {
}
} catch Cipher.Error.EncryptError {
XCTAssert(false, "Encryption failed") XCTAssert(false, "Encryption failed")
} catch Cipher.Error.DecryptError { } catch CipherError.Decrypt {
XCTAssert(false, "Decryption failed") XCTAssert(false, "Decryption failed")
} catch { } catch {
XCTAssert(false, "Failed") XCTAssert(false, "Failed")

View File

@ -5,8 +5,6 @@
// Created by Marcin Krzyzanowski on 15/08/14. // Created by Marcin Krzyzanowski on 15/08/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
import XCTest import XCTest
@testable import CryptoSwift @testable import CryptoSwift
@ -76,6 +74,24 @@ final class ExtensionsTest: XCTestCase {
XCTAssert(iii &<< 1 == iii << 1, "shift left failed") XCTAssert(iii &<< 1 == iii << 1, "shift left failed")
XCTAssert(iii &<< 8 == iii << 8, "shift left failed") XCTAssert(iii &<< 8 == iii << 8, "shift left failed")
XCTAssert((iii &<< 32) == 0, "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. // Created by Marcin Krzyzanowski on 29/08/14.
// Copyright (c) 2015 Marcin Krzyzanowski. All rights reserved. // Copyright (c) 2015 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
import XCTest import XCTest
@testable import CryptoSwift @testable import CryptoSwift
@ -26,8 +24,8 @@ final class HMACTests: XCTestCase {
let msg:[UInt8] = [] let msg:[UInt8] = []
let expectedMac:[UInt8] = [0x74,0xe6,0xf7,0x29,0x8a,0x9c,0x2d,0x16,0x89,0x35,0xf5,0x8c,0x00,0x1b,0xad,0x88] 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) let hmac = try! Authenticator.HMAC(key: key, variant: .md5).authenticate(msg)
XCTAssertEqual(hmac!, expectedMac, "Invalid authentication result") XCTAssertEqual(hmac, expectedMac, "Invalid authentication result")
} }
func testSHA1() { func testSHA1() {
@ -35,8 +33,8 @@ final class HMACTests: XCTestCase {
let msg:[UInt8] = [] 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 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) let hmac = try! Authenticator.HMAC(key: key, variant: .sha1).authenticate(msg)
XCTAssertEqual(hmac!, expectedMac, "Invalid authentication result") XCTAssertEqual(hmac, expectedMac, "Invalid authentication result")
} }
func testSHA256() { func testSHA256() {
@ -44,8 +42,8 @@ final class HMACTests: XCTestCase {
let msg:[UInt8] = [] 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 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) let hmac = try! Authenticator.HMAC(key: key, variant: .sha256).authenticate(msg)
XCTAssertEqual(hmac!, expectedMac, "Invalid authentication result") XCTAssertEqual(hmac, expectedMac, "Invalid authentication result")
} }
func testSHA384() { func testSHA384() {
@ -53,8 +51,8 @@ final class HMACTests: XCTestCase {
let msg:[UInt8] = [] 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 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) let hmac = try! Authenticator.HMAC(key: key, variant: .sha384).authenticate(msg)
XCTAssertEqual(hmac!, expectedMac, "Invalid authentication result") XCTAssertEqual(hmac, expectedMac, "Invalid authentication result")
} }
func testSHA512() { func testSHA512() {
@ -62,7 +60,7 @@ final class HMACTests: XCTestCase {
let msg:[UInt8] = [] 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 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) let hmac = try! Authenticator.HMAC(key: key, variant: .sha512).authenticate(msg)
XCTAssertEqual(hmac!, expectedMac, "Invalid authentication result") XCTAssertEqual(hmac, expectedMac, "Invalid authentication result")
} }
} }

View File

@ -19,85 +19,52 @@ final class CryptoSwiftTests: XCTestCase {
super.tearDown() super.tearDown()
} }
func testMD5() { func testMD5_data() {
let data1:NSData = NSData(bytes: [0x31, 0x32, 0x33] as [UInt8], length: 3) // "1", "2", "3" let data = [0x31, 0x32, 0x33] as [UInt8] // "1", "2", "3"
if let hash = Hash.md5(data1).calculate() { XCTAssertEqual(Hash.md5(data).calculate(), [0x20,0x2c,0xb9,0x62,0xac,0x59,0x07,0x5b,0x96,0x4b,0x07,0x15,0x2d,0x23,0x4b,0x70], "MD5 calculation failed");
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")
}
if let hash = "abcdefghijklmnopqrstuvwxyz".md5() { func testMD5_emptyString() {
XCTAssertEqual(hash, "c3fcd3d76192e4007dfb496cca67e13b", "MD5 calculation failed") 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() { func testMD5_string() {
XCTAssertEqual(hash, "d174ab98d277d9f5a5611c2c9f419d9f", "MD5 calculation failed") XCTAssertEqual("123".md5(), "202cb962ac59075b964b07152d234b70", "MD5 calculation failed");
} XCTAssertEqual("".md5(), "d41d8cd98f00b204e9800998ecf8427e", "MD5 calculation failed")
XCTAssertEqual("a".md5(), "0cc175b9c0f1b6a831c399e269772661", "MD5 calculation failed")
if let hash = "12345678901234567890123456789012345678901234567890123456789012345678901234567890".md5() { XCTAssertEqual("abc".md5(), "900150983cd24fb0d6963f7d28e17f72", "MD5 calculation failed")
XCTAssertEqual(hash, "57edf4a22be3c955ac49da2e2107b67a", "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() { func testMD5PerformanceSwift() {
self.measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: false, forBlock: { () -> Void in self.measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: false, forBlock: { () -> Void in
let buf = UnsafeMutablePointer<UInt8>(calloc(2048, sizeof(UInt8))) let buf = UnsafeMutablePointer<UInt8>(calloc(1024 * 1024, sizeof(UInt8)))
let data = NSData(bytes: buf, length: 2048) let data = NSData(bytes: buf, length: 1024 * 1024)
let arr = data.arrayOfBytes()
self.startMeasuring() self.startMeasuring()
Hash.md5(data).calculate() Hash.md5(arr).calculate()
self.stopMeasuring() self.stopMeasuring()
buf.dealloc(1024) buf.dealloc(1024 * 1024)
buf.destroy() buf.destroy()
}) })
} }
func testMD5PerformanceCommonCrypto() { func testMD5PerformanceCommonCrypto() {
self.measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: false, forBlock: { () -> Void in self.measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: false, forBlock: { () -> Void in
let buf = UnsafeMutablePointer<UInt8>(calloc(2048, sizeof(UInt8))) let buf = UnsafeMutablePointer<UInt8>(calloc(1024 * 1024, sizeof(UInt8)))
let data = NSData(bytes: buf, length: 2048) let data = NSData(bytes: buf, length: 1024 * 1024)
self.startMeasuring()
let outbuf = UnsafeMutablePointer<UInt8>.alloc(Int(CC_MD5_DIGEST_LENGTH)) 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)); //let output = NSData(bytes: outbuf, length: Int(CC_MD5_DIGEST_LENGTH));
self.stopMeasuring()
outbuf.dealloc(Int(CC_MD5_DIGEST_LENGTH)) outbuf.dealloc(Int(CC_MD5_DIGEST_LENGTH))
outbuf.destroy() outbuf.destroy()
self.stopMeasuring() buf.dealloc(1024 * 1024)
buf.dealloc(1024)
buf.destroy() buf.destroy()
}) })
} }
@ -108,20 +75,9 @@ final class CryptoSwiftTests: XCTestCase {
XCTAssertEqual(hash.toHexString(), "40bd001563085fc35165329ea1ff5c5ecbdbbeef", "SHA1 calculation failed"); XCTAssertEqual(hash.toHexString(), "40bd001563085fc35165329ea1ff5c5ecbdbbeef", "SHA1 calculation failed");
} }
if let hash = "abc".sha1() { XCTAssertEqual("abc".sha1(), "a9993e364706816aba3e25717850c26c9cd0d89d", "SHA1 calculation failed")
XCTAssertEqual(hash, "a9993e364706816aba3e25717850c26c9cd0d89d", "SHA1 calculation failed") XCTAssertEqual("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".sha1(), "84983e441c3bd26ebaae4aa1f95129e5e54670f1", "SHA1 calculation failed")
} XCTAssertEqual("".sha1(), "da39a3ee5e6b4b0d3255bfef95601890afd80709", "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")
}
} }
func testSHA224() { func testSHA224() {
@ -137,16 +93,8 @@ final class CryptoSwiftTests: XCTestCase {
XCTAssertEqual(hash.toHexString(), "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3", "SHA256 calculation failed"); XCTAssertEqual(hash.toHexString(), "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3", "SHA256 calculation failed");
} }
if let hash = "Rosetta code".sha256() { XCTAssertEqual("Rosetta code".sha256(), "764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf", "SHA256 calculation failed")
XCTAssertEqual(hash, "764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf", "SHA256 calculation failed") XCTAssertEqual("".sha256(), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "SHA256 calculation failed")
}
if let hash = "".sha256() {
XCTAssertEqual(hash, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "SHA256 calculation failed")
} else {
XCTAssert(false, "SHA256 calculation failed")
}
} }
func testSHA384() { func testSHA384() {
@ -155,15 +103,8 @@ final class CryptoSwiftTests: XCTestCase {
XCTAssertEqual(hash.toHexString(), "9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f", "SHA384 calculation failed"); XCTAssertEqual(hash.toHexString(), "9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f", "SHA384 calculation failed");
} }
if let hash = "The quick brown fox jumps over the lazy dog.".sha384() { XCTAssertEqual("The quick brown fox jumps over the lazy dog.".sha384(), "ed892481d8272ca6df370bf706e4d7bc1b5739fa2177aae6c50e946678718fc67a7af2819a021c2fc34e91bdb63409d7", "SHA384 calculation failed");
XCTAssertEqual(hash, "ed892481d8272ca6df370bf706e4d7bc1b5739fa2177aae6c50e946678718fc67a7af2819a021c2fc34e91bdb63409d7", "SHA384 calculation failed"); XCTAssertEqual("".sha384(), "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", "SHA384 calculation failed")
}
if let hash = "".sha384() {
XCTAssertEqual(hash, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", "SHA384 calculation failed")
} else {
XCTAssert(false, "SHA384 calculation failed")
}
} }
func testSHA512() { func testSHA512() {
@ -172,15 +113,8 @@ final class CryptoSwiftTests: XCTestCase {
XCTAssertEqual(hash.toHexString(), "3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2", "SHA512 calculation failed"); XCTAssertEqual(hash.toHexString(), "3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2", "SHA512 calculation failed");
} }
if let hash = "The quick brown fox jumps over the lazy dog.".sha512() { XCTAssertEqual("The quick brown fox jumps over the lazy dog.".sha512(), "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed", "SHA512 calculation failed");
XCTAssertEqual(hash, "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed", "SHA512 calculation failed"); XCTAssertEqual("".sha512(), "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", "SHA512 calculation failed")
}
if let hash = "".sha512() {
XCTAssertEqual(hash, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", "SHA512 calculation failed")
} else {
XCTAssert(false, "SHA512 calculation failed")
}
} }
func testCRC32() { func testCRC32() {
@ -189,22 +123,17 @@ final class CryptoSwiftTests: XCTestCase {
XCTAssertEqual(crc.toHexString(), "884863d2", "CRC32 calculation failed"); XCTAssertEqual(crc.toHexString(), "884863d2", "CRC32 calculation failed");
} }
if let crc = "".crc32() { XCTAssertEqual("".crc32(), "00000000", "CRC32 calculation failed");
XCTAssertEqual(crc, "00000000", "CRC32 calculation failed");
} else {
XCTAssert(false, "CRC32 calculation failed")
}
} }
func testCRC32Async() { func testCRC16() {
let expect = expectationWithDescription("CRC32") let result = CRC().crc16([49,50,51,52,53,54,55,56,57] as [UInt8])
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { () -> Void in XCTAssert(result == 0xBB3D, "CRC16 failed")
self.testCRC32()
expect.fulfill()
})
waitForExpectationsWithTimeout(10, handler: { (error) -> Void in
XCTAssertNil(error, "CRC32 async 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. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
func compareMatrix(a:[[UInt8]], b:[[UInt8]]) -> Bool { func compareMatrix(a:[[UInt8]], b:[[UInt8]]) -> Bool {
for (i,arr) in a.enumerate() { for (i,arr) in a.enumerate() {
for (j,val) in arr.enumerate() { for (j,val) in arr.enumerate() {

View File

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

View File

@ -5,8 +5,6 @@
// Created by Marcin Krzyzanowski on 29/08/14. // Created by Marcin Krzyzanowski on 29/08/14.
// Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
// //
import Foundation
import XCTest import XCTest
@testable import CryptoSwift @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 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] 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) { let mac = try! Authenticator.Poly1305(key: key).authenticate(msg)
XCTAssertEqual(mac, expectedMac, "Invalid authentication result") XCTAssertEqual(mac, expectedMac, "Invalid authentication result")
} else {
XCTFail("Missing MAC")
}
// extensions // extensions
let msgData = NSData.withBytes(msg) let msgData = NSData.withBytes(msg)
if let mac2 = msgData.authenticate(Authenticator.Poly1305(key: key)) { let mac2 = try! msgData.authenticate(Authenticator.Poly1305(key: key))
XCTAssertEqual(mac2, NSData.withBytes(expectedMac), "Invalid authentication result") XCTAssertEqual(mac2, NSData.withBytes(expectedMac), "Invalid authentication result")
} else {
XCTFail("Missing MAC")
}
} }
} }

View File

@ -19,7 +19,7 @@ Good mood
##Features ##Features
- Easy to use - Easy to use
- Convenience extensions - Convenient extensions for String and NSData
##What implemented? ##What implemented?
@ -31,6 +31,7 @@ Good mood
- [SHA384](http://tools.ietf.org/html/rfc6234) - [SHA384](http://tools.ietf.org/html/rfc6234)
- [SHA512](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) - [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 #####Cipher
- [AES-128, AES-192, AES-256](http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf) - [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. 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 ##Installation
To install CryptoSwift, add it as a submodule to your project (on the top level project directory): 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 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. 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*
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)
#####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. 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 ####CocoaPods
You can use [CocoaPods](http://cocoapods.org/?q=cryptoSwift). You can use [CocoaPods](http://cocoapods.org/?q=cryptoSwift).
```ruby ```ruby
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'CryptoSwift' pod 'CryptoSwift'
``` ```
@ -94,7 +112,7 @@ Specify in Cartfile:
github "krzyzanowskim/CryptoSwift" 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 ##Usage
@ -102,20 +120,23 @@ Then follow [build instructions](https://github.com/Carthage/Carthage#getting-st
import CryptoSwift 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 ```swift
/* Hash enum usage */ /* Hash enum usage */
var data:NSData = NSData(bytes: [49, 50, 51] as [UInt8], length: 3) let input:[UInt8] = [49, 50, 51]
if let data = CryptoSwift.Hash.md5(data).calculate() {
println(data.toHexString()) let output = input.md5()
} // alternatively: let output = CryptoSwift.Hash.md5(input).calculate()
print(output.toHexString())
``` ```
Hashing a data
```swift ```swift
let data = NSData()
let hash = data.md5() let hash = data.md5()
let hash = data.sha1() let hash = data.sha1()
let hash = data.sha224() let hash = data.sha224()
@ -123,17 +144,16 @@ let hash = data.sha256()
let hash = data.sha384() let hash = data.sha384()
let hash = data.sha512() 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 Hashing a String and printing result
```swift ```swift
if let hash = "123".md5() { let hash = "123".md5()
println(hash)
}
``` ```
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. 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 ChaCha20
```swift ```swift
let encrypted = Cipher.ChaCha20(key: key, iv: iv).encrypt(message) let encrypted: [UInt8] = ChaCha20(key: key, iv: iv).encrypt(message)
let decrypted = Cipher.ChaCha20(key: key, iv: iv).decrypt(encrypted) let decrypted: [UInt8] = ChaCha20(key: key, iv: iv).decrypt(encrypted)
``` ```
AES 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__.* 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 ```swift
let input = NSData()
let encrypted = try! input.encrypt(AES(key: "secret0key000000", iv:"0123456789012345"))
// 1. set key and random IV let input: [UInt8] = [0,1,2,3,4,5,6,7,8,9]
let key = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00] as [UInt8] input.encrypt(AES(key: "secret0key000000", iv:"0123456789012345", blockMode: .CBC))
let iv = Cipher.randomIV(AES.blockSize) ```
// 2. encrypt Encrypt String to Base64 string result:
let encrypted = AES(key: key, iv: iv, blockMode: .CBC)?.encrypt(message, padding: PKCS7())
```swift
// 3. decrypt with the same key and IV // Encrypt string and get Base64 representation of result
let decrypted = AES(key: key, iv: iv, blockMode: .CBC)?.decrypt(encryptedData, padding: PKCS7()) 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 AES without data padding
```swift ```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 Using extensions
```swift ```swift
let encrypted = dataToEncrypt.encrypt(Cipher.ChaCha20(key: key, iv: iv)) let plain = NSData()
let decrypted = encrypted.decrypt(Cipher.ChaCha20(key: key, iv: iv)) 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 Message authenticators
```swift ```swift
// Calculate Message Authentication Code (MAC) for message // 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] #####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: For you convenience CryptoSwift provide two function to easily convert array of bytes to NSData and other way around:
```swift ```swift
let data = NSData.withBytes([0x01,0x02,0x03]) let data: NSData = NSData(bytes: [0x01, 0x02, 0x03])
let bytes:[UInt8] = data.arrayOfBytes() let bytes:[UInt8] = data.arrayOfBytes()
``` ```
##Author ##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 ##License
@ -218,18 +269,4 @@ Permission is granted to anyone to use this software for any purpose, including
##Changelog ##Changelog
0.0.16 see CHANGELOG file
- 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

View File

@ -1,37 +1,34 @@
# OS X Finder
.DS_Store .DS_Store
# Xcode per-user config # Xcode
*.mode1 #
*.mode1v3 # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
*.mode2v3
*.perspective
*.perspectivev3
*.pbxuser
xcuserdata
*.xccheckout
# Build products ## Build generated
build/ build/
*.o DerivedData
*.LinkFileList
## 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 *.hmap
*.ipa
# Automatic backup files docsb/
*~.nib/
*.swp
*~
*.dat
*.dep
# Cocoapods
Pods
# Carthage
Carthage/Build
test/fuzzingserver.json
test/reports/

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://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://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. 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. 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 ## Features
- Swift 2.0. No need for Objective-C Bridging. - High performance.
- Reads compressed messages (`permessage-deflate`). [IETF Draft](https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-21) - TLS / WSS support. Self-signed certificate option.
- Strict UTF-8 processing.
- The API is modeled after the [Javascript API](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket). - 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. - `binaryType` property to choose between `[UInt8]` or `NSData` messages.
- Zero asserts. All networking, stream, and protocol errors are routed through the `error` event. - 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 ```swift
func echoTest(){ func echoTest(){
var messageNum = 0 var messageNum = 0
let ws = WebSocket("wss://echo.websocket.org") unowned let ws = WebSocket("wss://echo.websocket.org")
let send : ()->() = { let send : ()->() = {
let msg = "\(++messageNum): \(NSDate().description)" let msg = "\(++messageNum): \(NSDate().description)"
print("send: \(msg)") 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) ##Installation (iOS and OS X)
### [Carthage] ### [Carthage]

View File

@ -1,8 +1,8 @@
/* /*
* SwiftWebSocket (websocket.swift) * SwiftWebSocket (websocket.swift)
* *
* Copyright (C) 2015 ONcast, LLC. All Rights Reserved. * Copyright (C) Josh Baker. All Rights Reserved.
* Created by Josh Baker (joshbaker77@gmail.com) * Contact: @tidwall, joshbaker77@gmail.com
* *
* This software may be modified and distributed under the terms * This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details. * 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 atEndDetails = "streamStatus.atEnd"
private let timeoutDetails = "The operation couldnt be completed. Operation timed out"
private let timeoutDuration : CFTimeInterval = 30
public enum WebSocketError : ErrorType, CustomStringConvertible { public enum WebSocketError : ErrorType, CustomStringConvertible {
case Memory case Memory
@ -490,97 +492,92 @@ private class Deflater {
} }
/// WebSocket objects are bidirectional network streams that communicate over HTTP. RFC 6455. /// WebSocket objects are bidirectional network streams that communicate over HTTP. RFC 6455.
public class WebSocket: Hashable { private class InnerWebSocket: Hashable {
private var id : Int var id : Int
private var mutex = pthread_mutex_t() var mutex = pthread_mutex_t()
private var cond = pthread_cond_t() let request : NSURLRequest!
private let request : NSURLRequest! let subProtocols : [String]!
private let subProtocols : [String]! var frames : [Frame] = []
private var frames : [Frame] = [] var delegate : Delegate
private var delegate : Delegate var inflater : Inflater!
private var inflater : Inflater! var deflater : Deflater!
private var deflater : Deflater! var outputBytes : UnsafeMutablePointer<UInt8>
private var outputBytes : UnsafeMutablePointer<UInt8> var outputBytesSize : Int = 0
private var outputBytesSize : Int = 0 var outputBytesStart : Int = 0
private var outputBytesStart : Int = 0 var outputBytesLength : Int = 0
private var outputBytesLength : Int = 0 var inputBytes : UnsafeMutablePointer<UInt8>
private var inputBytes : UnsafeMutablePointer<UInt8> var inputBytesSize : Int = 0
private var inputBytesSize : Int = 0 var inputBytesStart : Int = 0
private var inputBytesStart : Int = 0 var inputBytesLength : Int = 0
private var inputBytesLength : Int = 0 var createdAt = CFAbsoluteTimeGetCurrent()
private var _eventQueue : dispatch_queue_t? = dispatch_get_main_queue() var connectionTimeout = false
private var _subProtocol = "" var _eventQueue : dispatch_queue_t? = dispatch_get_main_queue()
private var _compression = WebSocketCompression() var _subProtocol = ""
private var _services = WebSocketService.None var _compression = WebSocketCompression()
private var _event = WebSocketEvents() var _allowSelfSignedSSL = false
private var _binaryType = WebSocketBinaryType.UInt8Array var _services = WebSocketService.None
private var _readyState = WebSocketReadyState.Connecting var _event = WebSocketEvents()
private var _networkTimeout = NSTimeInterval(-1) 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. var url : String {
public var url : String {
return request.URL!.description 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. var subProtocol : String {
public var subProtocol : String {
get { return privateSubProtocol } get { return privateSubProtocol }
} }
private var privateSubProtocol : String { var privateSubProtocol : String {
get { lock(); defer { unlock() }; return _subProtocol } get { lock(); defer { unlock() }; return _subProtocol }
set { lock(); defer { unlock() }; _subProtocol = newValue } set { lock(); defer { unlock() }; _subProtocol = newValue }
} }
/// The compression options of the WebSocket. var compression : WebSocketCompression {
public var compression : WebSocketCompression {
get { lock(); defer { unlock() }; return _compression } get { lock(); defer { unlock() }; return _compression }
set { lock(); defer { unlock() }; _compression = newValue } set { lock(); defer { unlock() }; _compression = newValue }
} }
/// The services of the WebSocket. var allowSelfSignedSSL : Bool {
public var services : WebSocketService { get { lock(); defer { unlock() }; return _allowSelfSignedSSL }
set { lock(); defer { unlock() }; _allowSelfSignedSSL = newValue }
}
var services : WebSocketService {
get { lock(); defer { unlock() }; return _services } get { lock(); defer { unlock() }; return _services }
set { lock(); defer { unlock() }; _services = newValue } set { lock(); defer { unlock() }; _services = newValue }
} }
/// The events of the WebSocket. var event : WebSocketEvents {
public var event : WebSocketEvents {
get { lock(); defer { unlock() }; return _event } get { lock(); defer { unlock() }; return _event }
set { lock(); defer { unlock() }; _event = newValue } set { lock(); defer { unlock() }; _event = newValue }
} }
/// The queue for firing off events. default is main_queue var eventQueue : dispatch_queue_t? {
public var eventQueue : dispatch_queue_t? {
get { lock(); defer { unlock() }; return _eventQueue; } get { lock(); defer { unlock() }; return _eventQueue; }
set { lock(); defer { unlock() }; _eventQueue = newValue } set { lock(); defer { unlock() }; _eventQueue = newValue }
} }
/// A WebSocketBinaryType value indicating the type of binary data being transmitted by the connection. Default is .UInt8Array. var binaryType : WebSocketBinaryType {
public var binaryType : WebSocketBinaryType {
get { lock(); defer { unlock() }; return _binaryType } get { lock(); defer { unlock() }; return _binaryType }
set { lock(); defer { unlock() }; _binaryType = newValue } set { lock(); defer { unlock() }; _binaryType = newValue }
} }
/// The current state of the connection; this is one of the WebSocketReadyState constants. Read only. var readyState : WebSocketReadyState {
public var readyState : WebSocketReadyState {
get { return privateReadyState } get { return privateReadyState }
} }
private var privateReadyState : WebSocketReadyState { var privateReadyState : WebSocketReadyState {
get { lock(); defer { unlock() }; return _readyState } get { lock(); defer { unlock() }; return _readyState }
set { lock(); defer { unlock() }; _readyState = newValue } 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. init(request: NSURLRequest, subProtocols : [String] = [], stub : Bool = false){
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] = []){
pthread_mutex_init(&mutex, nil) pthread_mutex_init(&mutex, nil)
pthread_cond_init(&cond, nil)
self.id = manager.nextId() self.id = manager.nextId()
self.request = request self.request = request
self.subProtocols = subProtocols self.subProtocols = subProtocols
@ -589,8 +586,14 @@ public class WebSocket: Hashable {
self.inputBytes = UnsafeMutablePointer<UInt8>.alloc(windowBufferSize) self.inputBytes = UnsafeMutablePointer<UInt8>.alloc(windowBufferSize)
self.inputBytesSize = windowBufferSize self.inputBytesSize = windowBufferSize
self.delegate = Delegate() self.delegate = Delegate()
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue()){ if stub{
manager.add(self) 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{ deinit{
@ -600,7 +603,6 @@ public class WebSocket: Hashable {
if inputBytes != nil { if inputBytes != nil {
free(inputBytes) free(inputBytes)
} }
pthread_cond_init(&cond, nil)
pthread_mutex_init(&mutex, nil) pthread_mutex_init(&mutex, nil)
} }
@inline(__always) private func lock(){ @inline(__always) private func lock(){
@ -616,38 +618,47 @@ public class WebSocket: Hashable {
if exit { if exit {
return false return false
} }
if connectionTimeout {
return true
}
if stage != .ReadResponse && stage != .HandleFrames { if stage != .ReadResponse && stage != .HandleFrames {
return true return true
} }
if rd.streamStatus == .Opening && wr.streamStatus == .Opening {
return false;
}
if rd.streamStatus != .Open || wr.streamStatus != .Open { if rd.streamStatus != .Open || wr.streamStatus != .Open {
return true return true
} }
if rd.streamError != nil || wr.streamError != nil { if rd.streamError != nil || wr.streamError != nil {
return true 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 true
} }
return false return false
} }
private enum Stage : Int { enum Stage : Int {
case OpenConn case OpenConn
case ReadResponse case ReadResponse
case HandleFrames case HandleFrames
case CloseConn case CloseConn
case End case End
} }
private var stage = Stage.OpenConn var stage = Stage.OpenConn
private var rd : NSInputStream! var rd : NSInputStream!
private var wr : NSOutputStream! var wr : NSOutputStream!
private var atEnd = false var atEnd = false
private var closeCode = UInt16(0) var closeCode = UInt16(0)
private var closeReason = "" var closeReason = ""
private var closeClean = false var closeClean = false
private var closeFinal = false var closeFinal = false
private var finalError : ErrorType? var finalError : ErrorType?
private var exit = false var exit = false
private func step(){ func step(){
if exit { if exit {
return return
} }
@ -668,7 +679,7 @@ public class WebSocket: Hashable {
case .HandleFrames: case .HandleFrames:
try stepOutputFrames() try stepOutputFrames()
if closeFinal { if closeFinal {
privateReadyState == .Closing privateReadyState = .Closing
stage = .CloseConn stage = .CloseConn
return return
} }
@ -711,7 +722,7 @@ public class WebSocket: Hashable {
if let error = finalError { if let error = finalError {
self.event.error(error: error) self.event.error(error: error)
} }
privateReadyState == .Closed privateReadyState = .Closed
if rd != nil { if rd != nil {
closeConn() closeConn()
fire { fire {
@ -776,7 +787,7 @@ public class WebSocket: Hashable {
} }
} }
} }
private func stepBuffers() throws { func stepBuffers() throws {
if rd != nil { if rd != nil {
if rd.streamStatus == NSStreamStatus.AtEnd { if rd.streamStatus == NSStreamStatus.AtEnd {
if atEnd { if atEnd {
@ -815,8 +826,11 @@ public class WebSocket: Hashable {
} }
} }
} }
private func stepStreamErrors() throws { func stepStreamErrors() throws {
if finalError == nil { if finalError == nil {
if connectionTimeout {
throw WebSocketError.Network(timeoutDetails)
}
if let error = rd?.streamError { if let error = rd?.streamError {
throw WebSocketError.Network(error.localizedDescription) throw WebSocketError.Network(error.localizedDescription)
} }
@ -825,7 +839,7 @@ public class WebSocket: Hashable {
} }
} }
} }
private func stepOutputFrames() throws { func stepOutputFrames() throws {
lock() lock()
defer { defer {
frames = [] frames = []
@ -843,7 +857,7 @@ public class WebSocket: Hashable {
} }
} }
} }
@inline(__always) private func fire(block: ()->()){ @inline(__always) func fire(block: ()->()){
if let queue = eventQueue { if let queue = eventQueue {
dispatch_sync(queue) { dispatch_sync(queue) {
block() block()
@ -853,11 +867,11 @@ public class WebSocket: Hashable {
} }
} }
private var readStateSaved = false var readStateSaved = false
private var readStateFrame : Frame? var readStateFrame : Frame?
private var readStateFinished = false var readStateFinished = false
private var leaderFrame : Frame? var leaderFrame : Frame?
private func readFrame() throws -> Frame { func readFrame() throws -> Frame {
var frame : Frame var frame : Frame
var finished : Bool var finished : Bool
if !readStateSaved { if !readStateSaved {
@ -908,7 +922,7 @@ public class WebSocket: Hashable {
return frame return frame
} }
private func closeConn() { func closeConn() {
rd.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode) rd.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
wr.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode) wr.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
rd.delegate = nil rd.delegate = nil
@ -917,7 +931,7 @@ public class WebSocket: Hashable {
wr.close() wr.close()
} }
private func openConn() throws { func openConn() throws {
let req = request.mutableCopy() as! NSMutableURLRequest let req = request.mutableCopy() as! NSMutableURLRequest
req.setValue("websocket", forHTTPHeaderField: "Upgrade") req.setValue("websocket", forHTTPHeaderField: "Upgrade")
req.setValue("Upgrade", forHTTPHeaderField: "Connection") req.setValue("Upgrade", forHTTPHeaderField: "Connection")
@ -992,7 +1006,11 @@ public class WebSocket: Hashable {
throw WebSocketError.InvalidAddress throw WebSocketError.InvalidAddress
} }
var (rdo, wro) : (NSInputStream?, NSOutputStream?) 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!) (rd, wr) = (rdo!, wro!)
let securityLevel : String let securityLevel : String
switch security { switch security {
@ -1019,6 +1037,11 @@ public class WebSocket: Hashable {
rd.setProperty(NSStreamNetworkServiceTypeVoice, forKey: NSStreamNetworkServiceType) rd.setProperty(NSStreamNetworkServiceTypeVoice, forKey: NSStreamNetworkServiceType)
wr.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 rd.delegate = delegate
wr.delegate = delegate wr.delegate = delegate
rd.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode) rd.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
@ -1028,7 +1051,7 @@ public class WebSocket: Hashable {
try write(header, length: header.count) 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 { if outputBytesStart+outputBytesLength+length > outputBytesSize {
var size = outputBytesSize var size = outputBytesSize
while outputBytesStart+outputBytesLength+length > size { while outputBytesStart+outputBytesLength+length > size {
@ -1045,7 +1068,7 @@ public class WebSocket: Hashable {
outputBytesLength += length outputBytesLength += length
} }
private func readResponse() throws { func readResponse() throws {
let end : [UInt8] = [ 0x0D, 0x0A, 0x0D, 0x0A ] let end : [UInt8] = [ 0x0D, 0x0A, 0x0D, 0x0A ]
let ptr = UnsafeMutablePointer<UInt8>(memmem(inputBytes+inputBytesStart, inputBytesLength, end, 4)) let ptr = UnsafeMutablePointer<UInt8>(memmem(inputBytes+inputBytesStart, inputBytesLength, end, 4))
if ptr == nil { if ptr == nil {
@ -1126,7 +1149,7 @@ public class WebSocket: Hashable {
} }
} }
private class ByteReader { class ByteReader {
var start : UnsafePointer<UInt8> var start : UnsafePointer<UInt8>
var end : UnsafePointer<UInt8> var end : UnsafePointer<UInt8>
var bytes : UnsafePointer<UInt8> var bytes : UnsafePointer<UInt8>
@ -1156,20 +1179,20 @@ public class WebSocket: Hashable {
} }
} }
private var fragStateSaved = false var fragStateSaved = false
private var fragStatePosition = 0 var fragStatePosition = 0
private var fragStateInflate = false var fragStateInflate = false
private var fragStateLen = 0 var fragStateLen = 0
private var fragStateFin = false var fragStateFin = false
private var fragStateCode = OpCode.Continue var fragStateCode = OpCode.Continue
private var fragStateLeaderCode = OpCode.Continue var fragStateLeaderCode = OpCode.Continue
private var fragStateUTF8 = UTF8() var fragStateUTF8 = UTF8()
private var fragStatePayload = Payload() var fragStatePayload = Payload()
private var fragStateStatusCode = UInt16(0) var fragStateStatusCode = UInt16(0)
private var fragStateHeaderLen = 0 var fragStateHeaderLen = 0
private var buffer = [UInt8](count: windowBufferSize, repeatedValue: 0) var buffer = [UInt8](count: windowBufferSize, repeatedValue: 0)
private var reusedPayload = Payload() var reusedPayload = Payload()
private func readFrameFragment(var leader : Frame?) throws -> Frame { func readFrameFragment(var leader : Frame?) throws -> Frame {
var inflate : Bool var inflate : Bool
var len : Int var len : Int
var fin = false var fin = false
@ -1337,8 +1360,8 @@ public class WebSocket: Hashable {
return f return f
} }
private var head = [UInt8](count: 0xFF, repeatedValue: 0) var head = [UInt8](count: 0xFF, repeatedValue: 0)
private func writeFrame(f : Frame) throws { func writeFrame(f : Frame) throws {
if !f.finished{ if !f.finished{
throw WebSocketError.LibraryError("cannot send unfinished frames") throw WebSocketError.LibraryError("cannot send unfinished frames")
} }
@ -1406,32 +1429,20 @@ public class WebSocket: Hashable {
try write(head, length: hlen) try write(head, length: hlen)
try write(payloadBytes, length: payloadBytes.count) try write(payloadBytes, length: payloadBytes.count)
} }
func close(code : Int = 1000, reason : String = "Normal Closure") {
/**
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") {
let f = Frame() let f = Frame()
f.code = .Close f.code = .Close
f.statusCode = UInt16(truncatingBitPattern: code) f.statusCode = UInt16(truncatingBitPattern: code)
f.utf8.text = reason f.utf8.text = reason
sendFrame(f) sendFrame(f)
} }
private func sendFrame(f : Frame) { func sendFrame(f : Frame) {
lock() lock()
frames += [f] frames += [f]
unlock() unlock()
manager.signal() manager.signal()
} }
/** func send(message : Any) {
Transmits message to the server over the WebSocket connection.
:param: message The data to be sent to the server.
*/
public func send(message : Any) {
let f = Frame() let f = Frame()
if let message = message as? String { if let message = message as? String {
f.code = .Text f.code = .Text
@ -1451,20 +1462,12 @@ public class WebSocket: Hashable {
} }
sendFrame(f) sendFrame(f)
} }
/** func ping() {
Transmits a ping to the server over the WebSocket connection.
*/
public func ping() {
let f = Frame() let f = Frame()
f.code = .Ping f.code = .Ping
sendFrame(f) sendFrame(f)
} }
/** func ping(message : Any){
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){
let f = Frame() let f = Frame()
f.code = .Ping f.code = .Ping
if let message = message as? String { if let message = message as? String {
@ -1481,7 +1484,7 @@ public class WebSocket: Hashable {
sendFrame(f) sendFrame(f)
} }
} }
public func ==(lhs: WebSocket, rhs: WebSocket) -> Bool { private func ==(lhs: InnerWebSocket, rhs: InnerWebSocket) -> Bool {
return lhs.id == rhs.id return lhs.id == rhs.id
} }
@ -1497,13 +1500,13 @@ private class Manager {
var once = dispatch_once_t() var once = dispatch_once_t()
var mutex = pthread_mutex_t() var mutex = pthread_mutex_t()
var cond = pthread_cond_t() var cond = pthread_cond_t()
var websockets = Set<WebSocket>() var websockets = Set<InnerWebSocket>()
var _nextId = 0 var _nextId = 0
init(){ init(){
pthread_mutex_init(&mutex, nil) pthread_mutex_init(&mutex, nil)
pthread_cond_init(&cond, nil) pthread_cond_init(&cond, nil)
dispatch_async(dispatch_queue_create("SwiftWebSocket", nil)) { dispatch_async(dispatch_queue_create("SwiftWebSocket", nil)) {
var wss : [WebSocket] = [] var wss : [InnerWebSocket] = []
for ;; { for ;; {
var wait = true var wait = true
wss.removeAll() wss.removeAll()
@ -1512,6 +1515,7 @@ private class Manager {
wss.append(ws) wss.append(ws)
} }
for ws in wss { for ws in wss {
self.checkForConnectionTimeout(ws)
if ws.dirty { if ws.dirty {
pthread_mutex_unlock(&self.mutex) pthread_mutex_unlock(&self.mutex)
ws.step() ws.step()
@ -1520,24 +1524,44 @@ private class Manager {
} }
} }
if wait { if wait {
pthread_cond_wait(&self.cond, &self.mutex) self.wait(250)
} }
pthread_mutex_unlock(&self.mutex) 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(){ func signal(){
pthread_mutex_lock(&mutex) pthread_mutex_lock(&mutex)
pthread_cond_signal(&cond) pthread_cond_signal(&cond)
pthread_mutex_unlock(&mutex) pthread_mutex_unlock(&mutex)
} }
func add(websocket: WebSocket) { func add(websocket: InnerWebSocket) {
pthread_mutex_lock(&mutex) pthread_mutex_lock(&mutex)
websockets.insert(websocket) websockets.insert(websocket)
pthread_cond_signal(&cond) pthread_cond_signal(&cond)
pthread_mutex_unlock(&mutex) pthread_mutex_unlock(&mutex)
} }
func remove(websocket: WebSocket) { func remove(websocket: InnerWebSocket) {
pthread_mutex_lock(&mutex) pthread_mutex_lock(&mutex)
websockets.remove(websocket) websockets.remove(websocket)
pthread_cond_signal(&cond) pthread_cond_signal(&cond)
@ -1551,3 +1575,144 @@ private class Manager {
} }
private let manager = 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| Pod::Spec.new do |s|
s.name = "SwiftWebSocket" s.name = "SwiftWebSocket"
s.version = "2.1.0" s.version = "2.2.0"
s.summary = "A high performance WebSocket client library for Swift." s.summary = "A high performance WebSocket client library for Swift."
s.homepage = "https://github.com/tidwall/SwiftWebSocket" s.homepage = "https://github.com/tidwall/SwiftWebSocket"
s.license = { :type => "Attribution License", :file => "LICENSE" } s.license = { :type => "Attribution License", :file => "LICENSE" }

View File

@ -10,16 +10,41 @@
031967101B4D96C40033860E /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03285D2A1B4A9F1A0078A1AA /* WebSocket.swift */; }; 031967101B4D96C40033860E /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03285D2A1B4A9F1A0078A1AA /* WebSocket.swift */; };
03285D2B1B4A9F1A0078A1AA /* 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 */; }; 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, ); }; }; 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 */; }; 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, ); }; }; D719491B1B35E7510015C529 /* SwiftWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = D71948F11B35E5670015C529 /* SwiftWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */ /* 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 */ /* Begin PBXFileReference section */
0319670F1B4D96B80033860E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 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>"; }; 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; }; 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; }; 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>"; }; 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; }; 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; }; D71949011B35E6130015C529 /* SwiftWebSocket.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftWebSocket.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@ -34,6 +59,22 @@
); );
runOnlyForDeploymentPostprocessing = 0; 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 */ = { D71948FD1B35E6130015C529 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -51,6 +92,7 @@
D71948FA1B35E59D0015C529 /* libz.dylib */, D71948FA1B35E59D0015C529 /* libz.dylib */,
03D1E7211B208A5C00AC49AC /* libz.dylib */, 03D1E7211B208A5C00AC49AC /* libz.dylib */,
D71948F01B35E5670015C529 /* Source */, D71948F01B35E5670015C529 /* Source */,
03D70CE71BDAC70100D245C3 /* Test */,
03D1E7041B20897100AC49AC /* Products */, 03D1E7041B20897100AC49AC /* Products */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
@ -60,10 +102,21 @@
children = ( children = (
03D1E7031B20897100AC49AC /* SwiftWebSocket.framework */, 03D1E7031B20897100AC49AC /* SwiftWebSocket.framework */,
D71949011B35E6130015C529 /* SwiftWebSocket.framework */, D71949011B35E6130015C529 /* SwiftWebSocket.framework */,
03D70CCC1BDAC5EC00D245C3 /* Test-OSX.xctest */,
03D70CDB1BDAC63600D245C3 /* Test-iOS.xctest */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
03D70CE71BDAC70100D245C3 /* Test */ = {
isa = PBXGroup;
children = (
03D70CE81BDAC70100D245C3 /* Info.plist */,
03D70CE91BDAC70100D245C3 /* Test.swift */,
);
path = Test;
sourceTree = "<group>";
};
D71948F01B35E5670015C529 /* Source */ = { D71948F01B35E5670015C529 /* Source */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -114,6 +167,42 @@
productReference = 03D1E7031B20897100AC49AC /* SwiftWebSocket.framework */; productReference = 03D1E7031B20897100AC49AC /* SwiftWebSocket.framework */;
productType = "com.apple.product-type.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 */ = { D71949001B35E6130015C529 /* SwiftWebSocket-OSX */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = D71949141B35E6160015C529 /* Build configuration list for PBXNativeTarget "SwiftWebSocket-OSX" */; buildConfigurationList = D71949141B35E6160015C529 /* Build configuration list for PBXNativeTarget "SwiftWebSocket-OSX" */;
@ -138,13 +227,19 @@
03D1E6FA1B20897100AC49AC /* Project object */ = { 03D1E6FA1B20897100AC49AC /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastSwiftUpdateCheck = 0700; LastSwiftUpdateCheck = 0710;
LastUpgradeCheck = 0700; LastUpgradeCheck = 0700;
ORGANIZATIONNAME = "ONcast, LLC"; ORGANIZATIONNAME = "ONcast, LLC";
TargetAttributes = { TargetAttributes = {
03D1E7021B20897100AC49AC = { 03D1E7021B20897100AC49AC = {
CreatedOnToolsVersion = 6.3.2; CreatedOnToolsVersion = 6.3.2;
}; };
03D70CCB1BDAC5EC00D245C3 = {
CreatedOnToolsVersion = 7.1;
};
03D70CDA1BDAC63600D245C3 = {
CreatedOnToolsVersion = 7.1;
};
D71949001B35E6130015C529 = { D71949001B35E6130015C529 = {
CreatedOnToolsVersion = 6.3.2; CreatedOnToolsVersion = 6.3.2;
}; };
@ -164,6 +259,8 @@
targets = ( targets = (
03D1E7021B20897100AC49AC /* SwiftWebSocket-iOS */, 03D1E7021B20897100AC49AC /* SwiftWebSocket-iOS */,
D71949001B35E6130015C529 /* SwiftWebSocket-OSX */, D71949001B35E6130015C529 /* SwiftWebSocket-OSX */,
03D70CCB1BDAC5EC00D245C3 /* Test-OSX */,
03D70CDA1BDAC63600D245C3 /* Test-iOS */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
@ -176,6 +273,20 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
03D70CCA1BDAC5EC00D245C3 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
03D70CD91BDAC63600D245C3 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D71948FF1B35E6130015C529 /* Resources */ = { D71948FF1B35E6130015C529 /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -194,6 +305,22 @@
); );
runOnlyForDeploymentPostprocessing = 0; 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 */ = { D71948FC1B35E6130015C529 /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -204,6 +331,19 @@
}; };
/* End PBXSourcesBuildPhase section */ /* 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 */ /* Begin XCBuildConfiguration section */
03D1E7171B20897100AC49AC /* Debug */ = { 03D1E7171B20897100AC49AC /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
@ -331,6 +471,58 @@
}; };
name = Release; 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 */ = { D71949151B35E6160015C529 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
@ -401,6 +593,22 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; 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" */ = { D71949141B35E6160015C529 /* Build configuration list for PBXNativeTarget "SwiftWebSocket-OSX" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( 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 Slender: http://martiancraft.com/products/slender
Briefs: http://giveabrief.com/ 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 ###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 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 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 * **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| Pod::Spec.new do |s|
s.name = "XCGLogger" s.name = "XCGLogger"
s.version = "3.0" s.version = "3.1b1"
s.summary = "A debug log module for use in Swift projects." s.summary = "A debug log module for use in Swift projects."
s.description = <<-DESC s.description = <<-DESC
@ -12,14 +12,15 @@ Pod::Spec.new do |s|
s.license = { :type => "MIT", :file => "LICENSE.txt" } s.license = { :type => "MIT", :file => "LICENSE.txt" }
s.author = { "Dave Wood" => "cocoapods@cerebralgardens.com" } s.author = { "Dave Wood" => "cocoapods@cerebralgardens.com" }
s.social_media_url = "http://twitter.com/DaveWoodX" 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.source_files = "XCGLogger/Library/XCGLogger/XCGLogger.swift"
s.ios.deployment_target = '8.0' s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.9' s.osx.deployment_target = '10.9'
s.watchos.deployment_target = '2.0' s.watchos.deployment_target = '2.0'
s.tvos.deployment_target = '9.0'
s.framework = "Foundation" s.framework = "Foundation"
s.requires_arc = true s.requires_arc = true

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,9 +7,11 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* 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 */; }; 554DF41019D76FA9005708BE /* XCGLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 554DF40F19D76FA9005708BE /* XCGLogger.swift */; };
554DF41119D76FA9005708BE /* 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 */; }; 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 */; }; 55BB1EF91B79DC7500709779 /* XCGLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 554DF40F19D76FA9005708BE /* XCGLogger.swift */; };
55BB1EFA1B79DC7500709779 /* XCGLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E3EE5719D76F280068C3A7 /* XCGLoggerTests.swift */; }; 55BB1EFA1B79DC7500709779 /* XCGLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E3EE5719D76F280068C3A7 /* XCGLoggerTests.swift */; };
55BB1EFC1B79DC7500709779 /* XCGLogger.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55E3EE4519D76F280068C3A7 /* XCGLogger.framework */; }; 55BB1EFC1B79DC7500709779 /* XCGLogger.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55E3EE4519D76F280068C3A7 /* XCGLogger.framework */; };
@ -39,6 +41,9 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference 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>"; }; 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; }; 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; }; 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 */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
5515A3DB1BA119FA0047BA31 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
554DF41319D76FE7005708BE /* Frameworks */ = { 554DF41319D76FE7005708BE /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -93,6 +105,15 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
5515A3E01BA119FA0047BA31 /* XCGLogger (tvOS) */ = {
isa = PBXGroup;
children = (
5515A3E11BA119FA0047BA31 /* XCGLogger (tvOS).h */,
5515A3E31BA119FA0047BA31 /* Info.plist */,
);
path = "XCGLogger (tvOS)";
sourceTree = "<group>";
};
55DA396419D7737B0032F026 /* iOS */ = { 55DA396419D7737B0032F026 /* iOS */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -114,6 +135,7 @@
children = ( children = (
55E3EE4719D76F280068C3A7 /* XCGLogger */, 55E3EE4719D76F280068C3A7 /* XCGLogger */,
55E3EE5419D76F280068C3A7 /* XCGLoggerTests */, 55E3EE5419D76F280068C3A7 /* XCGLoggerTests */,
5515A3E01BA119FA0047BA31 /* XCGLogger (tvOS) */,
55E3EE4619D76F280068C3A7 /* Products */, 55E3EE4619D76F280068C3A7 /* Products */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
@ -126,6 +148,7 @@
554DF41719D76FE7005708BE /* XCGLogger.framework */, 554DF41719D76FE7005708BE /* XCGLogger.framework */,
55BB1F011B79DC7500709779 /* XCGLoggerTests (OS X).xctest */, 55BB1F011B79DC7500709779 /* XCGLoggerTests (OS X).xctest */,
70CB94201B99E728007802FF /* XCGLogger.framework */, 70CB94201B99E728007802FF /* XCGLogger.framework */,
5515A3DF1BA119FA0047BA31 /* XCGLogger.framework */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
@ -169,6 +192,14 @@
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */ /* Begin PBXHeadersBuildPhase section */
5515A3DC1BA119FA0047BA31 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
5515A3E71BA11B170047BA31 /* XCGLogger.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
554DF41419D76FE7005708BE /* Headers */ = { 554DF41419D76FE7005708BE /* Headers */ = {
isa = PBXHeadersBuildPhase; isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -196,6 +227,24 @@
/* End PBXHeadersBuildPhase section */ /* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget 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) */ = { 554DF41619D76FE7005708BE /* XCGLogger (OS X) */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 554DF42A19D76FE7005708BE /* Build configuration list for PBXNativeTarget "XCGLogger (OS X)" */; buildConfigurationList = 554DF42A19D76FE7005708BE /* Build configuration list for PBXNativeTarget "XCGLogger (OS X)" */;
@ -297,6 +346,9 @@
LastUpgradeCheck = 0700; LastUpgradeCheck = 0700;
ORGANIZATIONNAME = "Cerebral Gardens"; ORGANIZATIONNAME = "Cerebral Gardens";
TargetAttributes = { TargetAttributes = {
5515A3DE1BA119FA0047BA31 = {
CreatedOnToolsVersion = 7.1;
};
554DF41619D76FE7005708BE = { 554DF41619D76FE7005708BE = {
CreatedOnToolsVersion = 6.1; CreatedOnToolsVersion = 6.1;
}; };
@ -323,6 +375,7 @@
55E3EE4419D76F280068C3A7 /* XCGLogger (iOS) */, 55E3EE4419D76F280068C3A7 /* XCGLogger (iOS) */,
554DF41619D76FE7005708BE /* XCGLogger (OS X) */, 554DF41619D76FE7005708BE /* XCGLogger (OS X) */,
70CB94161B99E728007802FF /* XCGLogger (watchOS) */, 70CB94161B99E728007802FF /* XCGLogger (watchOS) */,
5515A3DE1BA119FA0047BA31 /* XCGLogger (tvOS) */,
55E3EE4F19D76F280068C3A7 /* XCGLoggerTests (iOS) */, 55E3EE4F19D76F280068C3A7 /* XCGLoggerTests (iOS) */,
55BB1EF51B79DC7500709779 /* XCGLoggerTests (OS X) */, 55BB1EF51B79DC7500709779 /* XCGLoggerTests (OS X) */,
); );
@ -330,6 +383,13 @@
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
5515A3DD1BA119FA0047BA31 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
554DF41519D76FE7005708BE /* Resources */ = { 554DF41519D76FE7005708BE /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -368,6 +428,14 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
5515A3DA1BA119FA0047BA31 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
557C47E41BA125F800C9A174 /* XCGLogger.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
554DF41219D76FE7005708BE /* Sources */ = { 554DF41219D76FE7005708BE /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -426,6 +494,51 @@
/* End PBXTargetDependency section */ /* End PBXTargetDependency section */
/* Begin XCBuildConfiguration 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 */ = { 554DF42B19D76FE7005708BE /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
@ -522,7 +635,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 3.0; CURRENT_PROJECT_VERSION = 3.1;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES; ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = gnu99;
@ -542,6 +655,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
PRODUCT_MODULE_NAME = XCGLogger;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
@ -569,7 +683,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES; COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 3.0; CURRENT_PROJECT_VERSION = 3.1;
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = gnu99;
@ -581,6 +695,7 @@
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_MODULE_NAME = XCGLogger;
SDKROOT = iphoneos; SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
@ -710,6 +825,15 @@
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList 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)" */ = { 554DF42A19D76FE7005708BE /* Build configuration list for PBXNativeTarget "XCGLogger (OS X)" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,6 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* 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 = (); }; }; 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 = (); }; }; 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 = (); }; }; 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 = (); }; }; 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 */; }; D02A725E1BBF07F700940C17 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D02A72351BBF033600940C17 /* Nimble.framework */; };
D02A725F1BBF07F700940C17 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D02A72361BBF033600940C17 /* Quick.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 = (); }; }; 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 = (); }; }; 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 = (); }; }; 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 = (); }; }; 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 = (); }; }; 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 = (); }; }; 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 */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -63,7 +62,6 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
D009DCA31BC1A53B0041378B /* RealmSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RealmSwift.framework; path = Carthage/Build/iOS/RealmSwift.framework; sourceTree = "<group>"; }; 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>"; }; 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; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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 */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -152,7 +150,6 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
D0CF8A131BE2AC4C00EC9F12 /* DDP */, D0CF8A131BE2AC4C00EC9F12 /* DDP */,
D0CF8A121BE2AC4400EC9F12 /* Meteor */,
D05879481BE6812E003E019E /* MeteorCoreData */, D05879481BE6812E003E019E /* MeteorCoreData */,
D02A71E11BBEFBCA00940C17 /* Info.plist */, D02A71E11BBEFBCA00940C17 /* Info.plist */,
); );
@ -201,23 +198,15 @@
name = MeteorCoreData; name = MeteorCoreData;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
D0CF8A121BE2AC4400EC9F12 /* Meteor */ = {
isa = PBXGroup;
children = (
D0C71B551BC172F40089B6CE /* Meteor.swift */,
D016D0061BC6DF2F009652C3 /* MeteorErrors.swift */,
);
name = Meteor;
sourceTree = "<group>";
};
D0CF8A131BE2AC4C00EC9F12 /* DDP */ = { D0CF8A131BE2AC4C00EC9F12 /* DDP */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
D02A720B1BBEFCD200940C17 /* DDPClient.swift */, D02A720B1BBEFCD200940C17 /* DDPClient.swift */,
D02A720C1BBEFCD300940C17 /* DDPMessage.swift */, D02A720C1BBEFCD300940C17 /* DDPMessage.swift */,
D02A720D1BBEFCD300940C17 /* DDPExtensions.swift */, D02A720D1BBEFCD300940C17 /* DDPExtensions.swift */,
D02B30821BDA8E2200E1DB72 /* DDPMethodResult.swift */, D0CF95F61BF0D51800AA151A /* DDPResult.swift */,
D02A720E1BBEFCD300940C17 /* DDPEvents.swift */, D02A720E1BBEFCD300940C17 /* DDPEvents.swift */,
D0C71B551BC172F40089B6CE /* Meteor.swift */,
); );
name = DDP; name = DDP;
sourceTree = "<group>"; sourceTree = "<group>";
@ -371,10 +360,9 @@
D05879461BE6810F003E019E /* MeteorCollectionChange.swift in Sources */, D05879461BE6810F003E019E /* MeteorCollectionChange.swift in Sources */,
D02A72101BBEFCD300940C17 /* DDPClient.swift in Sources */, D02A72101BBEFCD300940C17 /* DDPClient.swift in Sources */,
D05879441BE6810F003E019E /* MeteorCoreDataCollection.swift in Sources */, D05879441BE6810F003E019E /* MeteorCoreDataCollection.swift in Sources */,
D02B30831BDA8E2200E1DB72 /* DDPMethodResult.swift in Sources */, D0CF95F71BF0D51800AA151A /* DDPResult.swift in Sources */,
D02A72111BBEFCD300940C17 /* DDPMessage.swift in Sources */, D02A72111BBEFCD300940C17 /* DDPMessage.swift in Sources */,
D05879431BE6810F003E019E /* MeteorCoreDataStack.swift in Sources */, D05879431BE6810F003E019E /* MeteorCoreDataStack.swift in Sources */,
D016D0071BC6DF2F009652C3 /* MeteorErrors.swift in Sources */,
D02A72121BBEFCD300940C17 /* DDPExtensions.swift in Sources */, D02A72121BBEFCD300940C17 /* DDPExtensions.swift in Sources */,
D0C71B561BC172F40089B6CE /* Meteor.swift in Sources */, D0C71B561BC172F40089B6CE /* Meteor.swift in Sources */,
D05879471BE6810F003E019E /* CoreDataExtensions.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 DDPMethodCallback = (result:AnyObject?, error:DDPError?) -> ()
public typealias DDPCallback = () -> () 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 DDPClient is the base class for communicating with a server using the DDP protocol
*/ */
public class DDPClient: NSObject { public class DDPClient: NSObject {
// included for storing login id and token // included for storing login id and token
internal let userData = NSUserDefaults.standardUserDefaults() internal let userData = NSUserDefaults.standardUserDefaults()
internal let incomingData:NSOperationQueue = { let background: NSOperationQueue = {
let queue = 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.maxConcurrentOperationCount = 1
queue.qualityOfService = .Background
return queue return queue
}() }()
// Calling methods on the server + their callbacks // Callbacks execute in the order they're received
internal let outgoingData:NSOperationQueue = { internal let callbackQueue: NSOperationQueue = {
let queue = NSOperationQueue() let queue = NSOperationQueue()
queue.name = "DDP Outgoing Data Queue" queue.name = "DDP Callback Queue"
// queue.maxConcurrentOperationCount = 1
return queue
}()
internal let operation:NSOperationQueue = {
let queue = NSOperationQueue()
queue.name = "DDP Operation Queue"
queue.maxConcurrentOperationCount = 1 queue.maxConcurrentOperationCount = 1
queue.qualityOfService = .UserInitiated
return queue 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() let queue = NSOperationQueue()
queue.name = "DDP Heartbeat Queue" queue.name = "DDP Heartbeat Queue"
queue.qualityOfService = .Utility
return queue 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 socket:WebSocket!
private var server:(ping:NSDate?, pong:NSDate?) = (nil, nil) private var server:(ping:NSDate?, pong:NSDate?) = (nil, nil)
@ -87,6 +122,7 @@ public class DDPClient: NSObject {
internal var events = DDPEvents() internal var events = DDPEvents()
internal var connection:(ddp:Bool, session:String?) = (false, nil) internal var connection:(ddp:Bool, session:String?) = (false, nil)
public var delegate:SwiftDDPDelegate?
public var logLevel = XCGLogger.LogLevel.Debug public var logLevel = XCGLogger.LogLevel.Debug
internal override init() { internal override init() {
@ -141,14 +177,13 @@ public class DDPClient: NSObject {
} }
socket.event.message = { message in socket.event.message = { message in
self.operation.addOperationWithBlock() { self.background.addOperationWithBlock() {
if let text = message as? String { if let text = message as? String {
do { try self.ddpMessageHandler(DDPMessage(message: text)) } do { try self.ddpMessageHandler(DDPMessage(message: text)) }
catch { log.debug("Message handling error. Raw message: \(text)")} catch { log.debug("Message handling error. Raw message: \(text)")}
} }
} }
} }
} }
/** /**
@ -171,7 +206,6 @@ public class DDPClient: NSObject {
private func pong(ping: DDPMessage) { private func pong(ping: DDPMessage) {
heartbeat.addOperationWithBlock() { heartbeat.addOperationWithBlock() {
self.server.ping = NSDate() self.server.ping = NSDate()
// log.debug("Ping")
var response = ["msg":"pong"] var response = ["msg":"pong"]
if let id = ping.id { response["id"] = id } if let id = ping.id { response["id"] = id }
self.sendMessage(response) self.sendMessage(response)
@ -189,7 +223,7 @@ public class DDPClient: NSObject {
self.connection = (true, message.session!) self.connection = (true, message.session!)
self.events.onConnected(session:message.session!) self.events.onConnected(session:message.session!)
case .Result: incomingData.addOperationWithBlock() { case .Result: callbackQueue.addOperationWithBlock() {
if let id = message.id, // Message has id if let id = message.id, // Message has id
let callback = self.resultCallbacks[id], // There is a callback registered for the message let callback = self.resultCallbacks[id], // There is a callback registered for the message
let result = message.result { let result = message.result {
@ -204,57 +238,56 @@ public class DDPClient: NSObject {
// Principal callbacks for managing data // Principal callbacks for managing data
// Document was added // Document was added
case .Added: incomingData.addOperationWithBlock() { case .Added: documentQueue.addOperationWithBlock() {
if let collection = message.collection, if let collection = message.collection,
let id = message.id { let id = message.id {
self.documentWasAdded(collection, id: id, fields: message.fields) self.documentWasAdded(collection, id: id, fields: message.fields)
} }
} }
// Document was changed // Document was changed
case .Changed: incomingData.addOperationWithBlock() { case .Changed: documentQueue.addOperationWithBlock() {
if let collection = message.collection, if let collection = message.collection,
let id = message.id { let id = message.id {
self.documentWasChanged(collection, id: id, fields: message.fields, cleared: message.cleared) self.documentWasChanged(collection, id: id, fields: message.fields, cleared: message.cleared)
} }
} }
// Document was removed // Document was removed
case .Removed: incomingData.addOperationWithBlock() { case .Removed: documentQueue.addOperationWithBlock() {
if let collection = message.collection, if let collection = message.collection,
let id = message.id { let id = message.id {
self.documentWasRemoved(collection, id: id) self.documentWasRemoved(collection, id: id)
} }
} }
// Notifies you when the result of a method changes // Notifies you when the result of a method changes
case .Updated: incomingData.addOperationWithBlock() { case .Updated: documentQueue.addOperationWithBlock() {
if let methods = message.methods { if let methods = message.methods {
self.methodWasUpdated(methods) self.methodWasUpdated(methods)
} }
} }
// Callbacks for managing subscriptions // Callbacks for managing subscriptions
case .Ready: incomingData.addOperationWithBlock() { case .Ready: background.addOperationWithBlock() {
if let subs = message.subs { if let subs = message.subs {
self.ready(subs) self.ready(subs)
} }
} }
// Callback that fires when subscription has been completely removed // Callback that fires when subscription has been completely removed
// //
case .Nosub: incomingData.addOperationWithBlock() { case .Nosub: background.addOperationWithBlock() {
if let id = message.id { if let id = message.id {
self.nosub(id, error: message.error) self.nosub(id, error: message.error)
} }
} }
case .Ping: heartbeat.addOperationWithBlock() { self.pong(message) } case .Ping: heartbeat.addOperationWithBlock() { self.pong(message) }
case .Pong: heartbeat.addOperationWithBlock() { self.server.pong = NSDate() } case .Pong: heartbeat.addOperationWithBlock() { self.server.pong = NSDate() }
case .Error: incomingData.addOperationWithBlock() { case .Error: background.addOperationWithBlock() {
self.didReceiveErrorMessage(DDPError(json: message.json)) self.didReceiveErrorMessage(DDPError(json: message.json))
} }
@ -282,10 +315,12 @@ public class DDPClient: NSObject {
public func method(name: String, params: AnyObject?, callback: DDPMethodCallback?) -> String { public func method(name: String, params: AnyObject?, callback: DDPMethodCallback?) -> String {
let id = getId() let id = getId()
let message = ["msg":"method", "method":name, "id":id] as NSMutableDictionary let message = ["msg":"method", "method":name, "id":id] as NSMutableDictionary
if let p = params { message["params"] = p } if let p = params { message["params"] = p }
if let c = callback { resultCallbacks[id] = c } if let c = callback { self.resultCallbacks[id] = c }
outgoingData.addOperationWithBlock() { self.sendMessage(message) } userBackground.addOperationWithBlock() {
self.sendMessage(message)
}
return id return id
} }
@ -295,11 +330,13 @@ public class DDPClient: NSObject {
internal func sub(id: String, name: String, params: [AnyObject]?, callback: DDPCallback?) -> String { internal func sub(id: String, name: String, params: [AnyObject]?, callback: DDPCallback?) -> String {
if let c = callback { subCallbacks[id] = c } if let c = callback { self.subCallbacks[id] = c }
subscriptions[id] = (id, name, false) self.subscriptions[id] = (id, name, false)
let message = ["msg":"sub", "name":name, "id":id] as NSMutableDictionary let message = ["msg":"sub", "name":name, "id":id] as NSMutableDictionary
if let p = params { message["params"] = p } if let p = params { message["params"] = p }
outgoingData.addOperationWithBlock() { self.sendMessage(message) } userBackground.addOperationWithBlock() {
self.sendMessage(message)
}
return id return id
} }
@ -326,8 +363,12 @@ public class DDPClient: NSObject {
*/ */
public func sub(name:String, params: [AnyObject]?, callback: DDPCallback?) -> String { public func sub(name:String, params: [AnyObject]?, callback: DDPCallback?) -> String {
let id = getId() let id = String(name.hashValue)
return sub(id, name: name, params: params, callback: callback) 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 // 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? { public func unsub(name: String, callback: DDPCallback?) -> String? {
if let sub = findSubscription(name) { if let sub = findSubscription(name) {
unsub(withId: sub.id, callback: callback) 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 sub.id
} }
return nil return nil
@ -374,7 +415,7 @@ public class DDPClient: NSObject {
internal func unsub(withId id: String, callback: DDPCallback?) { internal func unsub(withId id: String, callback: DDPCallback?) {
if let c = callback { unsubCallbacks[id] = c } 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) { public func didReceiveErrorMessage(message: DDPError) {
if let error = events.onError { error(message: message) } 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_TOKEN_EXPIRES = "DDP_TOKEN_EXPIRES"
private let DDP_LOGGED_IN = "DDP_LOGGED_IN" 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 let SWIFT_DDP_CALLBACK_DISPATCH_TIME = DISPATCH_TIME_FOREVER
private let syncWarning = {(name:String) -> Void in private let syncWarning = {(name:String) -> Void in
@ -36,8 +39,6 @@ private let syncWarning = {(name:String) -> Void in
} }
} }
extension String { extension String {
func dictionaryValue() -> NSDictionary? { func dictionaryValue() -> NSDictionary? {
if let data = self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) { if let data = self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
@ -237,7 +238,10 @@ extension DDPClient {
return serverResponse return serverResponse
} }
// Callback runs on main thread
internal func login(params: NSDictionary, callback: ((result: AnyObject?, error: DDPError?) -> ())?) { 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 method("login", params: NSArray(arrayLiteral: params)) { result, error in
guard let e = error where (e.isValid == true) else { 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(token, forKey: DDP_TOKEN)
self.userData.setObject(expiration, forKey: DDP_TOKEN_EXPIRES) 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 return
} }
@ -276,7 +292,7 @@ extension DDPClient {
*/ */
public func loginWithPassword(email: String, password: String, callback: DDPMethodCallback?) { public func loginWithPassword(email: String, password: String, callback: DDPMethodCallback?) {
if !(loginWithToken(callback)) { 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) login(params, callback: callback)
} }
} }
@ -289,6 +305,7 @@ extension DDPClient {
public func loginWithToken(callback: DDPMethodCallback?) -> Bool { public func loginWithToken(callback: DDPMethodCallback?) -> Bool {
if let token = userData.stringForKey(DDP_TOKEN), if let token = userData.stringForKey(DDP_TOKEN),
let tokenDate = userData.objectForKey(DDP_TOKEN_EXPIRES) { let tokenDate = userData.objectForKey(DDP_TOKEN_EXPIRES) {
print("Found token & token expires \(token), \(tokenDate)")
if (tokenDate.compare(NSDate()) == NSComparisonResult.OrderedDescending) { if (tokenDate.compare(NSDate()) == NSComparisonResult.OrderedDescending) {
let params = ["resume":token] as NSDictionary let params = ["resume":token] as NSDictionary
login(params, callback:callback) login(params, callback:callback)
@ -317,6 +334,7 @@ extension DDPClient {
self.userData.setObject(id, forKey: DDP_ID) self.userData.setObject(id, forKey: DDP_ID)
self.userData.setObject(token, forKey: DDP_TOKEN) self.userData.setObject(token, forKey: DDP_TOKEN)
self.userData.setObject(expiration, forKey: DDP_TOKEN_EXPIRES) self.userData.setObject(expiration, forKey: DDP_TOKEN_EXPIRES)
self.userData.synchronize()
} }
if let c = callback { c(result:result, error:error) } if let c = callback { c(result:result, error:error) }
self.userData.setObject(true, forKey: DDP_LOGGED_IN) self.userData.setObject(true, forKey: DDP_LOGGED_IN)
@ -327,14 +345,20 @@ extension DDPClient {
if let c = callback { c(result: result, error: error) } 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?) -> ())?) { 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) 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?) -> ())?) { 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) signup(params, callback: callback)
} }
@ -357,30 +381,49 @@ extension DDPClient {
return nil 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 Logs a user out and removes their account data from NSUserDefaults
*/ */
public func logout() { public func logout() {
method("logout", params: nil) { result, error in logout(nil)
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)
}
}
} }
/** /**
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 - parameter callback: A closure with result and error parameters describing the outcome of the operation
*/ */
public func logout(callback:DDPMethodCallback?) { 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 Automatically attempts to resume a prior session, if one exists

View File

@ -20,6 +20,46 @@
import Foundation 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 Enum value representing the types of DDP messages that the server can send
*/ */
@ -94,7 +134,9 @@ public struct DDPMessage {
json = message as NSDictionary 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? { public static func toString(json:AnyObject) -> String? {
if let data = try? NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions(rawValue: 0)) { if let data = try? NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions(rawValue: 0)) {
let message = NSString(data: data, encoding: NSASCIIStringEncoding) as String? 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 An error object describing the server-side error, or nil if the method completed successfully
*/ */
public var error:DDPError? public var error:DDPError?
} }

View File

@ -20,6 +20,18 @@
import Foundation 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 { protocol MeteorCollectionType {
func documentWasAdded(collection:String, id:String, fields:NSDictionary?) func documentWasAdded(collection:String, id:String, fields:NSDictionary?)
func documentWasChanged(collection:String, id:String, fields:NSDictionary?, cleared:[String]?) 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. - 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 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 email: A string email address associated with a Meteor account
- parameter password: A string password - 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 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?) { public override func documentWasAdded(collection:String, id:String, fields:NSDictionary?) {
if let meteorCollection = Meteor.collections[collection] as? MeteorCollectionType { 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]?) { public override func documentWasChanged(collection:String, id:String, fields:NSDictionary?, cleared:[String]?) {
if let meteorCollection = Meteor.collections[collection] as? MeteorCollectionType { 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) { public override func documentWasRemoved(collection:String, id:String) {
if let meteorCollection = Meteor.collections[collection] as? MeteorCollectionType { 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 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 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) } 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]?) { public func documentWasChanged(collection:String, id:String, fields:NSDictionary?, cleared:[String]?) {
if let changed = onChanged { changed(collection:collection, id:id, fields:fields, cleared:cleared) } 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) { public func documentWasRemoved(collection:String, id:String) {
if let removed = onRemoved { removed(collection:collection, id:id) } if let removed = onRemoved { removed(collection:collection, id:id) }
} }

View File

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