Add SecretStream to the OSX target, fix examples
This commit is contained in:
parent
e31629b8d3
commit
b8a23a25a3
|
@ -16,7 +16,7 @@ extension Data {
|
|||
func toString() -> String? {
|
||||
return String(data: self, encoding: .utf8)
|
||||
}
|
||||
|
||||
|
||||
func toDictionary() -> [String: AnyObject]? {
|
||||
return NSKeyedUnarchiver.unarchiveObject(with: self) as? [String: AnyObject]
|
||||
}
|
||||
|
|
|
@ -3,42 +3,36 @@ import Sodium
|
|||
|
||||
@NSApplicationMain
|
||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
|
||||
@IBOutlet weak var window: NSWindow!
|
||||
|
||||
|
||||
|
||||
func applicationDidFinishLaunching(aNotification: NSNotification) {
|
||||
// Insert code here to initialize your application
|
||||
|
||||
let sodium = Sodium()
|
||||
let aliceKeyPair = sodium.box.keyPair()!
|
||||
let bobKeyPair = sodium.box.keyPair()!
|
||||
let message = "My Test Message".toData()!
|
||||
|
||||
|
||||
print("Original Message:\(String(describing: message.toString()))")
|
||||
|
||||
|
||||
let encryptedMessageFromAliceToBob: Data =
|
||||
sodium.box.seal(
|
||||
message: message,
|
||||
recipientPublicKey: bobKeyPair.publicKey,
|
||||
senderSecretKey: aliceKeyPair.secretKey)!
|
||||
|
||||
|
||||
print("Encrypted Message:\(encryptedMessageFromAliceToBob)")
|
||||
|
||||
|
||||
let messageVerifiedAndDecryptedByBob =
|
||||
sodium.box.open(
|
||||
nonceAndAuthenticatedCipherText: encryptedMessageFromAliceToBob,
|
||||
senderPublicKey: bobKeyPair.publicKey,
|
||||
recipientSecretKey: aliceKeyPair.secretKey)
|
||||
|
||||
|
||||
print("Decrypted Message:\(String(describing: messageVerifiedAndDecryptedByBob!.toString()))")
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
func applicationWillTerminate(aNotification: NSNotification) {
|
||||
// Insert code here to tear down your application
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2015 Frank Denis. All rights reserved.</string>
|
||||
<string>Copyright © 2015-2017 Frank Denis. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
|
|
@ -1,46 +1,34 @@
|
|||
//
|
||||
// AppDelegate.swift
|
||||
// Example iOS
|
||||
//
|
||||
// Created by RamaKrishna Mallireddy on 19/04/15.
|
||||
// Copyright (c) 2015 Frank Denis. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
|
||||
|
||||
private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
func applicationWillResignActive(_ application: UIApplication) {
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
|
||||
}
|
||||
|
||||
|
||||
func applicationDidEnterBackground(_ application: UIApplication) {
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
}
|
||||
|
||||
|
||||
func applicationWillEnterForeground(_ application: UIApplication) {
|
||||
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
|
||||
}
|
||||
|
||||
|
||||
func applicationDidBecomeActive(_ application: UIApplication) {
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
}
|
||||
|
||||
|
||||
func applicationWillTerminate(_ application: UIApplication) {
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2,41 +2,36 @@ import UIKit
|
|||
import Sodium
|
||||
|
||||
class ViewController: UIViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
// Do any additional setup after loading the view, typically from a nib.
|
||||
|
||||
|
||||
let sodium = Sodium()
|
||||
let aliceKeyPair = sodium.box.keyPair()!
|
||||
let bobKeyPair = sodium.box.keyPair()!
|
||||
let message = "My Test Message".toData()!
|
||||
|
||||
|
||||
print("Original Message:\(String(describing: message.toString()))")
|
||||
|
||||
|
||||
let encryptedMessageFromAliceToBob: Data =
|
||||
sodium.box.seal(
|
||||
message: message,
|
||||
recipientPublicKey: bobKeyPair.publicKey,
|
||||
senderSecretKey: aliceKeyPair.secretKey)!
|
||||
|
||||
|
||||
print("Encrypted Message:\(encryptedMessageFromAliceToBob)")
|
||||
|
||||
|
||||
let messageVerifiedAndDecryptedByBob =
|
||||
sodium.box.open(
|
||||
nonceAndAuthenticatedCipherText: encryptedMessageFromAliceToBob,
|
||||
senderPublicKey: bobKeyPair.publicKey,
|
||||
recipientSecretKey: aliceKeyPair.secretKey)
|
||||
|
||||
|
||||
print("Decrypted Message:\(String(describing: messageVerifiedAndDecryptedByBob!.toString()))")
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
095D805B1A4F35CA000B83F9 /* RandomBytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 095D805A1A4F35CA000B83F9 /* RandomBytes.swift */; };
|
||||
095D805D1A4F4F72000B83F9 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 095D805C1A4F4F72000B83F9 /* Utils.swift */; };
|
||||
097F20DA1AF127480088C2FE /* PWHash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097F20D91AF127480088C2FE /* PWHash.swift */; };
|
||||
098DAF041F76E35C00DFB1C3 /* SecretStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09A5AC111F74466700D3200B /* SecretStream.swift */; };
|
||||
09A5AC121F74466700D3200B /* SecretStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09A5AC111F74466700D3200B /* SecretStream.swift */; };
|
||||
09A943D31A4EB5F500C8A04F /* Sodium.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09A943C71A4EB5F500C8A04F /* Sodium.framework */; };
|
||||
09A943DA1A4EB5F500C8A04F /* SodiumTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09A943D91A4EB5F500C8A04F /* SodiumTests.swift */; };
|
||||
|
@ -689,6 +690,7 @@
|
|||
60C211E71EB73D3900882AD0 /* Auth.swift in Sources */,
|
||||
094298311EDDAA3B001236B1 /* Stream.swift in Sources */,
|
||||
6096E7321F194FA800E6599F /* KeyDerivation.swift in Sources */,
|
||||
098DAF041F76E35C00DFB1C3 /* SecretStream.swift in Sources */,
|
||||
90C75EEA1AE3583E00F1E749 /* ShortHash.swift in Sources */,
|
||||
90C75EEB1AE3583E00F1E749 /* Sign.swift in Sources */,
|
||||
90C75EEC1AE3583E00F1E749 /* Sodium.swift in Sources */,
|
||||
|
@ -994,7 +996,7 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = "com.vucontacts.swiftodium.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
|
@ -1015,7 +1017,7 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = "com.vucontacts.swiftodium.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Release;
|
||||
|
@ -1051,7 +1053,7 @@
|
|||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_INCLUDE_PATHS = "$(PROJECT_DIR)/Sodium $(PROJECT_DIR)/Sodium/libsodium";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
|
@ -1084,7 +1086,7 @@
|
|||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_INCLUDE_PATHS = "$(PROJECT_DIR)/Sodium $(PROJECT_DIR)/Sodium/libsodium";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Release;
|
||||
|
|
|
@ -7,36 +7,36 @@ class ReadmeTests : XCTestCase {
|
|||
let aliceKeyPair = sodium.box.keyPair()!
|
||||
let bobKeyPair = sodium.box.keyPair()!
|
||||
let message = "My Test Message".data(using:.utf8)!
|
||||
|
||||
|
||||
let encryptedMessageFromAliceToBob: Data =
|
||||
sodium.box.seal(message: message,
|
||||
recipientPublicKey: bobKeyPair.publicKey,
|
||||
senderSecretKey: aliceKeyPair.secretKey)!
|
||||
|
||||
|
||||
let messageVerifiedAndDecryptedByBob =
|
||||
sodium.box.open(nonceAndAuthenticatedCipherText: encryptedMessageFromAliceToBob,
|
||||
senderPublicKey: aliceKeyPair.publicKey,
|
||||
recipientSecretKey: bobKeyPair.secretKey)
|
||||
|
||||
|
||||
XCTAssertNotNil(messageVerifiedAndDecryptedByBob)
|
||||
}
|
||||
|
||||
|
||||
func testAnonymousEncryptionSealedBoxes() {
|
||||
let sodium = Sodium()
|
||||
let bobKeyPair = sodium.box.keyPair()!
|
||||
let message = "My Test Message".data(using:.utf8)!
|
||||
|
||||
|
||||
let encryptedMessageToBob =
|
||||
sodium.box.seal(message: message, recipientPublicKey: bobKeyPair.publicKey)!
|
||||
|
||||
|
||||
let messageDecryptedByBob =
|
||||
sodium.box.open(anonymousCipherText: encryptedMessageToBob,
|
||||
recipientPublicKey: bobKeyPair.publicKey,
|
||||
recipientSecretKey: bobKeyPair.secretKey)
|
||||
|
||||
|
||||
XCTAssertNotNil(messageDecryptedByBob)
|
||||
}
|
||||
|
||||
|
||||
func testDetachedSignatures() {
|
||||
let sodium = Sodium()
|
||||
let message = "My Test Message".data(using:.utf8)!
|
||||
|
@ -48,7 +48,7 @@ class ReadmeTests : XCTestCase {
|
|||
// signature is valid
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testAttachedSignatures() {
|
||||
let sodium = Sodium()
|
||||
let message = "My Test Message".data(using:.utf8)!
|
||||
|
@ -58,7 +58,7 @@ class ReadmeTests : XCTestCase {
|
|||
// signature is valid
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testSecretKeyAuthenticatedEncryption() {
|
||||
let sodium = Sodium()
|
||||
let message = "My Test Message".data(using:.utf8)!
|
||||
|
@ -68,24 +68,24 @@ class ReadmeTests : XCTestCase {
|
|||
// authenticator is valid, decrypted contains the original message
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testDeterministicHashing() {
|
||||
let sodium = Sodium()
|
||||
let message = "My Test Message".data(using:.utf8)!
|
||||
let h = sodium.genericHash.hash(message: message)
|
||||
|
||||
|
||||
XCTAssertNotNil(h)
|
||||
}
|
||||
|
||||
|
||||
func testKeyedHashing() {
|
||||
let sodium = Sodium()
|
||||
let message = "My Test Message".data(using:.utf8)!
|
||||
let key = "Secret key".data(using:.utf8)!
|
||||
let h = sodium.genericHash.hash(message: message, key: key)
|
||||
|
||||
|
||||
XCTAssertNotNil(h)
|
||||
}
|
||||
|
||||
|
||||
func testStreaming() {
|
||||
let sodium = Sodium()
|
||||
let message1 = "My Test ".data(using:.utf8)!
|
||||
|
@ -95,33 +95,33 @@ class ReadmeTests : XCTestCase {
|
|||
let _ = stream.update(input: message1)
|
||||
let _ = stream.update(input: message2)
|
||||
let h = stream.final()
|
||||
|
||||
|
||||
XCTAssertNotNil(h)
|
||||
}
|
||||
|
||||
|
||||
func testShortOutputHashing() {
|
||||
let sodium = Sodium()
|
||||
let message = "My Test Message".data(using:.utf8)!
|
||||
let key = sodium.randomBytes.buf(length: sodium.shortHash.KeyBytes)!
|
||||
let h = sodium.shortHash.hash(message: message, key: key)
|
||||
|
||||
|
||||
XCTAssertNotNil(h)
|
||||
}
|
||||
|
||||
|
||||
func testRandomNumberGeneration() {
|
||||
let sodium = Sodium()
|
||||
let randomData = sodium.randomBytes.buf(length: 1000)
|
||||
|
||||
|
||||
XCTAssertNotNil(randomData)
|
||||
}
|
||||
|
||||
|
||||
func testPasswordHashing() {
|
||||
let sodium = Sodium()
|
||||
let password = "Correct Horse Battery Staple".data(using:.utf8)!
|
||||
let hashedStr = sodium.pwHash.str(passwd: password,
|
||||
opsLimit: sodium.pwHash.OpsLimitInteractive,
|
||||
memLimit: sodium.pwHash.MemLimitInteractive)!
|
||||
|
||||
|
||||
if sodium.pwHash.strVerify(hash: hashedStr, passwd: password) {
|
||||
// Password matches the given hash string
|
||||
} else {
|
||||
|
@ -135,63 +135,63 @@ class ReadmeTests : XCTestCase {
|
|||
// hashed doesn't match the current algorithm and the given parameters.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testZeroingMemory() {
|
||||
let sodium = Sodium()
|
||||
var dataToZero = "Message".data(using:.utf8)!
|
||||
sodium.utils.zero(&dataToZero)
|
||||
}
|
||||
|
||||
|
||||
func testConstantTimeComparison() {
|
||||
let sodium = Sodium()
|
||||
let secret1 = "Secret key".data(using:.utf8)!
|
||||
let secret2 = "Secret key".data(using:.utf8)!
|
||||
let equality = sodium.utils.equals(secret1, secret2)
|
||||
|
||||
|
||||
XCTAssertTrue(equality)
|
||||
}
|
||||
|
||||
|
||||
func testConstantTimeHexdecimalEncoding() {
|
||||
let sodium = Sodium()
|
||||
let data = "Secret key".data(using:.utf8)!
|
||||
let hex = sodium.utils.bin2hex(data)
|
||||
|
||||
|
||||
XCTAssertNotNil(hex)
|
||||
}
|
||||
|
||||
|
||||
func testHexDecimalDecoding() {
|
||||
let sodium = Sodium()
|
||||
let data1 = sodium.utils.hex2bin("deadbeef")
|
||||
let data2 = sodium.utils.hex2bin("de:ad be:ef", ignore: " :")
|
||||
|
||||
|
||||
XCTAssertNotNil(data1)
|
||||
XCTAssertNotNil(data2)
|
||||
}
|
||||
|
||||
|
||||
func testStream() {
|
||||
let sodium = Sodium()
|
||||
let input = "test".data(using:.utf8)!
|
||||
let key = sodium.stream.key()!
|
||||
let (output, nonce) = sodium.stream.xor(input: input, secretKey: key)!
|
||||
let twice = sodium.stream.xor(input: output, nonce: nonce, secretKey: key)!
|
||||
|
||||
|
||||
XCTAssertEqual(input, twice)
|
||||
}
|
||||
|
||||
|
||||
func testAuth() {
|
||||
let sodium = Sodium()
|
||||
let input = "test".data(using:.utf8)!
|
||||
let key = sodium.auth.key()!
|
||||
let tag = sodium.auth.tag(message: input, secretKey: key)!
|
||||
let tagIsValid = sodium.auth.verify(message: input, secretKey: key, tag: tag)
|
||||
|
||||
|
||||
XCTAssertTrue(tagIsValid)
|
||||
}
|
||||
|
||||
|
||||
func testKeyDerivation() {
|
||||
let sodium = Sodium()
|
||||
let secretKey = sodium.keyDerivation.key()!
|
||||
|
||||
|
||||
let subKey1 = sodium.keyDerivation.derive(secretKey: secretKey,
|
||||
index: 0, length: 32,
|
||||
context: "Context!")!
|
||||
|
@ -200,30 +200,30 @@ class ReadmeTests : XCTestCase {
|
|||
context: "Context!")!
|
||||
XCTAssertNotEqual(subKey1, subKey2)
|
||||
}
|
||||
|
||||
|
||||
func testSecretStream() {
|
||||
let sodium = Sodium()
|
||||
let message1 = "Message 1".data(using:.utf8)!
|
||||
let message2 = "Message 2".data(using:.utf8)!
|
||||
let message3 = "Message 3".data(using:.utf8)!
|
||||
|
||||
|
||||
let secretkey = sodium.secretStream.xchacha20poly1305.key()!
|
||||
|
||||
|
||||
/* stream encryption */
|
||||
|
||||
|
||||
let stream_enc = sodium.secretStream.xchacha20poly1305.initPush(secretKey: secretkey)!
|
||||
let header = stream_enc.header()
|
||||
let encrypted1 = stream_enc.push(message: message1)!
|
||||
let encrypted2 = stream_enc.push(message: message2)!
|
||||
let encrypted3 = stream_enc.push(message: message3, tag: .FINAL)!
|
||||
|
||||
|
||||
/* stream decryption */
|
||||
|
||||
|
||||
let stream_dec = sodium.secretStream.xchacha20poly1305.initPull(secretKey: secretkey, header: header)!
|
||||
let (message1_dec, tag1) = stream_dec.pull(cipherText: encrypted1)!
|
||||
let (message2_dec, tag2) = stream_dec.pull(cipherText: encrypted2)!
|
||||
let (message3_dec, tag3) = stream_dec.pull(cipherText: encrypted3)!
|
||||
|
||||
|
||||
XCTAssertEqual(message1, message1_dec)
|
||||
XCTAssertEqual(message2, message2_dec)
|
||||
XCTAssertEqual(message3, message3_dec)
|
||||
|
@ -231,7 +231,7 @@ class ReadmeTests : XCTestCase {
|
|||
XCTAssertEqual(tag2, .MESSAGE)
|
||||
XCTAssertEqual(tag3, .FINAL)
|
||||
}
|
||||
|
||||
|
||||
func testBase64() {
|
||||
let sodium = Sodium()
|
||||
let b64 = sodium.utils.bin2base64("data".toData()!)!
|
||||
|
@ -240,19 +240,19 @@ class ReadmeTests : XCTestCase {
|
|||
let data1 = sodium.utils.base642bin(b64)
|
||||
let data2 = sodium.utils.base642bin(b64, ignore: " \n")
|
||||
let data3 = sodium.utils.base642bin(b64_2, variant: .URLSAFE_NO_PADDING, ignore: " \n")
|
||||
|
||||
|
||||
XCTAssertEqual(data1, "data".toData())
|
||||
XCTAssertEqual(data2, "data".toData())
|
||||
XCTAssertEqual(data3, "data".toData())
|
||||
}
|
||||
|
||||
|
||||
func testPadding() {
|
||||
let sodium = Sodium()
|
||||
var data = "test".toData()!
|
||||
|
||||
|
||||
// make data.count a multiple of 16
|
||||
sodium.utils.pad(data: &data, blockSize: 16)!
|
||||
|
||||
|
||||
// restore original size
|
||||
sodium.utils.unpad(data: &data, blockSize: 16)!
|
||||
}
|
||||
|
|
|
@ -15,116 +15,116 @@ extension Data {
|
|||
|
||||
class SodiumTests: XCTestCase {
|
||||
let sodium = Sodium()
|
||||
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
}
|
||||
|
||||
|
||||
override func tearDown() {
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
|
||||
func testBox() {
|
||||
let message = "My Test Message".toData()!
|
||||
let aliceKeyPair = sodium.box.keyPair()!
|
||||
let bobKeyPair = sodium.box.keyPair()!
|
||||
|
||||
|
||||
let encryptedMessageFromAliceToBob: Data = sodium.box.seal(message: message, recipientPublicKey: bobKeyPair.publicKey, senderSecretKey: aliceKeyPair.secretKey)!
|
||||
let decrypted = sodium.box.open(nonceAndAuthenticatedCipherText: encryptedMessageFromAliceToBob, senderPublicKey: bobKeyPair.publicKey, recipientSecretKey: aliceKeyPair.secretKey)
|
||||
XCTAssertEqual(decrypted, message)
|
||||
|
||||
|
||||
let (encryptedMessageFromAliceToBob2, nonce): (Data, Box.Nonce) = sodium.box.seal(message: message, recipientPublicKey: bobKeyPair.publicKey, senderSecretKey: aliceKeyPair.secretKey)!
|
||||
let decrypted2 = sodium.box.open(authenticatedCipherText: encryptedMessageFromAliceToBob2, senderPublicKey: aliceKeyPair.publicKey, recipientSecretKey: bobKeyPair.secretKey, nonce: nonce)
|
||||
XCTAssertEqual(decrypted2, message)
|
||||
|
||||
|
||||
let (encryptedMessageFromAliceToBob3, nonce2, mac): (Data, Box.Nonce, Box.MAC) = sodium.box.seal(message: message, recipientPublicKey: bobKeyPair.publicKey, senderSecretKey: aliceKeyPair.secretKey)!
|
||||
let decrypted3 = sodium.box.open(authenticatedCipherText: encryptedMessageFromAliceToBob3, senderPublicKey: aliceKeyPair.publicKey, recipientSecretKey: bobKeyPair.secretKey, nonce: nonce2, mac: mac)
|
||||
XCTAssertEqual(decrypted3, message)
|
||||
|
||||
|
||||
let userNonce = sodium.randomBytes.buf(length: sodium.box.NonceBytes)!
|
||||
let encryptedMessageFromAliceToBob4: Data = sodium.box.seal(message: message, recipientPublicKey: bobKeyPair.publicKey, senderSecretKey: aliceKeyPair.secretKey, nonce: userNonce)!
|
||||
let decrypted4 = sodium.box.open(authenticatedCipherText: encryptedMessageFromAliceToBob4, senderPublicKey: bobKeyPair.publicKey, recipientSecretKey: aliceKeyPair.secretKey, nonce: userNonce)
|
||||
XCTAssertEqual(message, decrypted4)
|
||||
|
||||
|
||||
let encryptedMessageToBob: Data = sodium.box.seal(message: message, recipientPublicKey: bobKeyPair.publicKey)!
|
||||
let decrypted5 = sodium.box.open(anonymousCipherText: encryptedMessageToBob, recipientPublicKey: bobKeyPair.publicKey,
|
||||
recipientSecretKey: bobKeyPair.secretKey)
|
||||
XCTAssertEqual(decrypted5, message)
|
||||
|
||||
|
||||
// beforenm tests
|
||||
// The two beforenm keys calculated by Alice and Bob separately should be identical
|
||||
let aliceBeforenm = sodium.box.beforenm(recipientPublicKey: bobKeyPair.publicKey, senderSecretKey: aliceKeyPair.secretKey)!
|
||||
let bobBeforenm = sodium.box.beforenm(recipientPublicKey: aliceKeyPair.publicKey, senderSecretKey: bobKeyPair.secretKey)!
|
||||
XCTAssertEqual(aliceBeforenm, bobBeforenm)
|
||||
|
||||
|
||||
// Make sure the encryption using beforenm works
|
||||
let encryptedMessageBeforenm: Data = sodium.box.seal(message: message, beforenm: aliceBeforenm)!
|
||||
let decryptedBeforenm = sodium.box.open(nonceAndAuthenticatedCipherText: encryptedMessageBeforenm, beforenm: aliceBeforenm)
|
||||
XCTAssertEqual(decryptedBeforenm, message)
|
||||
|
||||
|
||||
let (encryptedMessageBeforenm2, nonceBeforenm): (Data, Box.Nonce) = sodium.box.seal(message: message, beforenm: aliceBeforenm)!
|
||||
let decryptedBeforenm2 = sodium.box.open(authenticatedCipherText: encryptedMessageBeforenm2, beforenm: aliceBeforenm, nonce: nonceBeforenm)
|
||||
XCTAssertEqual(decryptedBeforenm2, message)
|
||||
}
|
||||
|
||||
|
||||
func testSecretBox() {
|
||||
let message = "My Test Message".toData()!
|
||||
let secretKey = sodium.secretBox.key()!
|
||||
|
||||
|
||||
// test simple nonce + mac + message box
|
||||
let encrypted: Data = sodium.secretBox.seal(message: message, secretKey: secretKey)!
|
||||
let decrypted = sodium.secretBox.open(nonceAndAuthenticatedCipherText: encrypted, secretKey: secretKey)!
|
||||
XCTAssertEqual(decrypted, message)
|
||||
|
||||
|
||||
XCTAssertNotEqual(sodium.secretBox.seal(message: message, secretKey: secretKey), encrypted, "Ciphertext of two encryption operations on the same plaintext shouldn't be equal. Make sure the nonce was used only once!")
|
||||
|
||||
|
||||
XCTAssertNil(sodium.secretBox.open(nonceAndAuthenticatedCipherText: encrypted, secretKey: sodium.secretBox.key()!), "Shouldn't be able to decrypt with a bad key")
|
||||
|
||||
|
||||
// test (mac + message, nonce) box
|
||||
let (encrypted2, nonce2) = sodium.secretBox.seal(message: message, secretKey: secretKey)!
|
||||
let decrypted2 = sodium.secretBox.open(authenticatedCipherText: encrypted2, secretKey: secretKey, nonce: nonce2)
|
||||
XCTAssertEqual(decrypted2, message)
|
||||
|
||||
|
||||
XCTAssertNil(sodium.secretBox.open(authenticatedCipherText: encrypted2, secretKey: secretKey, nonce: sodium.secretBox.nonce()), "Shouldn't be able to decrypt with an invalid nonce")
|
||||
|
||||
|
||||
// test (message, nonce, mac) box
|
||||
let (encrypted3, nonce3, mac3) = sodium.secretBox.seal(message: message, secretKey: secretKey)!
|
||||
let decrypted3 = sodium.secretBox.open(cipherText: encrypted3, secretKey: secretKey, nonce: nonce3, mac: mac3)
|
||||
XCTAssertEqual(decrypted3, message)
|
||||
|
||||
|
||||
let (encrypted4, nonce4, mac4) = sodium.secretBox.seal(message: message, secretKey: secretKey)!
|
||||
XCTAssertNil(sodium.secretBox.open(cipherText: encrypted4, secretKey: secretKey, nonce: nonce3, mac: mac4), "Shouldn't be able to decrypt with an invalid MAC")
|
||||
XCTAssertNil(sodium.secretBox.open(cipherText: encrypted4, secretKey: secretKey, nonce: nonce4, mac: mac3), "Shouldn't be able to decrypt with an invalid nonce")
|
||||
}
|
||||
|
||||
|
||||
func testGenericHash() {
|
||||
let message = "My Test Message".toData()!
|
||||
let h1 = sodium.utils.bin2hex(sodium.genericHash.hash(message: message)!)!
|
||||
XCTAssertEqual(h1, "64a9026fca646c31df54426ad15a341e2444d8a1863d57eb27abecf239609f75")
|
||||
|
||||
|
||||
let key = sodium.utils.hex2bin("64 a9 02 6f ca 64 6c 31 df 54", ignore: " ")
|
||||
let h2 = sodium.utils.bin2hex(sodium.genericHash.hash(message: message, key: key)!)!
|
||||
XCTAssertEqual(h2, "1773f324cba2e7b0017e32d7e44f7afd1036c5d4ef9a80ae0e52e95a629844cd")
|
||||
|
||||
|
||||
let h3 = sodium.utils.bin2hex(sodium.genericHash.hash(message: message, key: key, outputLength: sodium.genericHash.BytesMax)!)!
|
||||
XCTAssertEqual(h3, "cba85e39f2d03923b2f66aba99b204333edc34a8443ab1700f7920c7abcc6639963a953f35162a520b21072ab906457d21f1645e6e3985858ee95a84d0771f07")
|
||||
|
||||
|
||||
let s1 = sodium.genericHash.initStream()!
|
||||
XCTAssertTrue(s1.update(input: message))
|
||||
let h4 = sodium.utils.bin2hex(s1.final()!)!
|
||||
XCTAssertEqual(h4, h1)
|
||||
|
||||
|
||||
let s2 = sodium.genericHash.initStream(key: key, outputLength: sodium.genericHash.Bytes)!
|
||||
XCTAssertTrue(s2.update(input: message))
|
||||
let h5 = sodium.utils.bin2hex(s2.final()!)!
|
||||
XCTAssertEqual(h5, h2)
|
||||
|
||||
|
||||
let s3 = sodium.genericHash.initStream(key: key, outputLength: sodium.genericHash.BytesMax)!
|
||||
XCTAssertTrue(s3.update(input: message))
|
||||
let h6 = sodium.utils.bin2hex(s3.final()!)!
|
||||
XCTAssertEqual(h6, h3)
|
||||
}
|
||||
|
||||
|
||||
func testRandomBytes() {
|
||||
let randomLen = 100 + Int(sodium.randomBytes.uniform(upperBound: 100))
|
||||
let random1 = sodium.randomBytes.buf(length: randomLen)!
|
||||
|
@ -132,7 +132,7 @@ class SodiumTests: XCTestCase {
|
|||
XCTAssertEqual(random1.count, randomLen)
|
||||
XCTAssertEqual(random2.count, randomLen)
|
||||
XCTAssertNotEqual(random1, random2)
|
||||
|
||||
|
||||
var c1 = 0
|
||||
let ref1 = self.sodium.randomBytes.random()
|
||||
for _ in (0..<100) {
|
||||
|
@ -141,7 +141,7 @@ class SodiumTests: XCTestCase {
|
|||
}
|
||||
}
|
||||
XCTAssert(c1 < 10)
|
||||
|
||||
|
||||
var c2 = 0
|
||||
let ref2 = self.sodium.randomBytes.uniform(upperBound: 100_000)
|
||||
for _ in (0..<100) {
|
||||
|
@ -150,65 +150,65 @@ class SodiumTests: XCTestCase {
|
|||
}
|
||||
}
|
||||
XCTAssert(c2 < 10)
|
||||
|
||||
|
||||
let seed = sodium.utils.hex2bin("00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff", ignore: " ")!
|
||||
let randomd = sodium.utils.bin2hex(sodium.randomBytes.deterministic(length: 10, seed: seed)!)!
|
||||
XCTAssertEqual(randomd, "444dc0602207c270b93f")
|
||||
}
|
||||
|
||||
|
||||
func testShortHash() {
|
||||
let message = "My Test Message".toData()!
|
||||
let key = sodium.utils.hex2bin("00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff", ignore: " ")!
|
||||
let h = sodium.utils.bin2hex(sodium.shortHash.hash(message: message, key: key)!)!
|
||||
XCTAssertEqual(h, "bb9be85c918015ea")
|
||||
}
|
||||
|
||||
|
||||
func testSignature() {
|
||||
let message = "My Test Message".toData()!
|
||||
let keyPair = sodium.sign.keyPair(seed: sodium.utils.hex2bin("00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff", ignore: " ")!)!
|
||||
let signedMessage = sodium.sign.sign(message: message, secretKey: keyPair.secretKey)!
|
||||
XCTAssertEqual(sodium.utils.bin2hex(signedMessage)!, "ce8437d58a27c4d91426d35b24cfaf1e49f95b213c15eddb198f4a8d24c0fdd0df3e7f7a894f60ec15cff25b5f6f27399ce01db0e2649fc54c91cafb8dd48a094d792054657374204d657373616765")
|
||||
|
||||
|
||||
let signature = sodium.sign.signature(message: message, secretKey: keyPair.secretKey)!
|
||||
XCTAssertEqual(sodium.utils.bin2hex(signature)!, "ce8437d58a27c4d91426d35b24cfaf1e49f95b213c15eddb198f4a8d24c0fdd0df3e7f7a894f60ec15cff25b5f6f27399ce01db0e2649fc54c91cafb8dd48a09")
|
||||
|
||||
|
||||
XCTAssertTrue(sodium.sign.verify(signedMessage: signedMessage, publicKey: keyPair.publicKey))
|
||||
XCTAssertTrue(sodium.sign.verify(message: message, publicKey: keyPair.publicKey, signature: signature))
|
||||
|
||||
|
||||
let unsignedMessage = sodium.sign.open(signedMessage: signedMessage, publicKey: keyPair.publicKey)!
|
||||
XCTAssertEqual(unsignedMessage, message)
|
||||
}
|
||||
|
||||
|
||||
func testUtils() {
|
||||
var dataToZero = Data(bytes: [1, 2, 3, 4] as [UInt8])
|
||||
sodium.utils.zero(&dataToZero)
|
||||
XCTAssert(dataToZero == Data(bytes: [0, 0, 0, 0] as [UInt8]))
|
||||
|
||||
|
||||
var dataToZero2 = Data(bytes: [1, 2, 3, 4] as [UInt8])
|
||||
sodium.utils.zero(&dataToZero2)
|
||||
XCTAssert(dataToZero2 == Data(bytes: [0, 0, 0, 0,] as [UInt8]))
|
||||
|
||||
|
||||
let eq1 = Data(bytes: [1, 2, 3, 4] as [UInt8])
|
||||
let eq2 = Data(bytes: [1, 2, 3, 4] as [UInt8])
|
||||
let eq3 = Data(bytes: [1, 2, 3, 5] as [UInt8])
|
||||
let eq4 = Data(bytes: [1, 2, 3] as [UInt8])
|
||||
|
||||
|
||||
XCTAssertTrue(sodium.utils.equals(eq1, eq2))
|
||||
XCTAssertFalse(sodium.utils.equals(eq1, eq3))
|
||||
XCTAssertFalse(sodium.utils.equals(eq1, eq4))
|
||||
|
||||
|
||||
XCTAssertEqual(sodium.utils.compare(eq1, eq2)!, 0)
|
||||
XCTAssertEqual(sodium.utils.compare(eq1, eq3)!, -1)
|
||||
XCTAssertEqual(sodium.utils.compare(eq3, eq2)!, 1)
|
||||
XCTAssertNil(sodium.utils.compare(eq1, eq4))
|
||||
|
||||
|
||||
let bin = sodium.utils.hex2bin("deadbeef")!
|
||||
let hex = sodium.utils.bin2hex(bin)
|
||||
XCTAssertEqual(hex, "deadbeef")
|
||||
let bin2 = sodium.utils.hex2bin("de-ad be:ef", ignore: ":- ")!
|
||||
XCTAssertEqual(bin2, bin)
|
||||
}
|
||||
|
||||
|
||||
func testPwHash() {
|
||||
let passwordLen = 4 + Int(sodium.randomBytes.uniform(upperBound: 64))
|
||||
let password = sodium.randomBytes.buf(length: passwordLen)!
|
||||
|
@ -219,37 +219,37 @@ class SodiumTests: XCTestCase {
|
|||
let password2 = sodium.randomBytes.buf(length: passwordLen)!
|
||||
let verify2 = sodium.pwHash.strVerify(hash: hash!, passwd: password2)
|
||||
XCTAssertFalse(verify2)
|
||||
|
||||
|
||||
let password3 = "My Test Message".toData()!
|
||||
let salt = Data(bytes: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] as [UInt8])
|
||||
let hash2 = sodium.pwHash.hash(outputLength: 64, passwd: password3, salt: salt, opsLimit: sodium.pwHash.OpsLimitInteractive, memLimit: sodium.pwHash.MemLimitInteractive)
|
||||
XCTAssertEqual(sodium.utils.bin2hex(hash2!)!, "51d659ee6f8790042688274c5bc8a6296390cdc786d2341c3553b01a5c3f7ff1190e04b86a878538b17ef10e74baa19295479f3e3ee587ce571f366fc66e2fdc")
|
||||
|
||||
|
||||
XCTAssertFalse(sodium.pwHash.strNeedsRehash(hash: hash!, opsLimit: sodium.pwHash.OpsLimitInteractive, memLimit: sodium.pwHash.MemLimitInteractive))
|
||||
XCTAssertTrue(sodium.pwHash.strNeedsRehash(hash: hash!, opsLimit: sodium.pwHash.OpsLimitSensitive, memLimit: sodium.pwHash.MemLimitSensitive))
|
||||
}
|
||||
|
||||
|
||||
func testKeyExchange() {
|
||||
let aliceKeyPair = sodium.keyExchange.keyPair()!
|
||||
let bobKeyPair = sodium.keyExchange.keyPair()!
|
||||
|
||||
|
||||
let sessionKeyPairForAlice = sodium.keyExchange.sessionKeyPair(publicKey: aliceKeyPair.publicKey, secretKey: aliceKeyPair.secretKey, otherPublicKey: bobKeyPair.publicKey, side: .CLIENT)!
|
||||
let sessionKeyPairForBob = sodium.keyExchange.sessionKeyPair(publicKey: bobKeyPair.publicKey, secretKey: bobKeyPair.secretKey, otherPublicKey: aliceKeyPair.publicKey, side: .SERVER)!
|
||||
|
||||
|
||||
XCTAssertEqual(sessionKeyPairForAlice.rx, sessionKeyPairForBob.tx)
|
||||
XCTAssertEqual(sessionKeyPairForAlice.tx, sessionKeyPairForBob.rx)
|
||||
}
|
||||
|
||||
|
||||
func testStream() {
|
||||
let key = sodium.stream.key()!
|
||||
let inputLen = Int(sodium.randomBytes.uniform(upperBound: 1024))
|
||||
let input = sodium.randomBytes.buf(length: inputLen)!
|
||||
let (output, nonce) = sodium.stream.xor(input: input, secretKey: key)!
|
||||
let twice = sodium.stream.xor(input: output, nonce: nonce, secretKey: key)!
|
||||
|
||||
|
||||
XCTAssertEqual(input, twice)
|
||||
}
|
||||
|
||||
|
||||
func testAuth() {
|
||||
let key = sodium.utils.hex2bin("eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880")!
|
||||
let message = sodium.utils.hex2bin("8e993b9f48681273c29650ba32fc76ce48332ea7164d96a4476fb8c531a1186ac0dfc17c98dce87b4da7f011ec48c97271d2c20f9b928fe2270d6fb863d51738b48eeee314a7cc8ab932164548e526ae90224368517acfeabd6bb3732bc0e9da99832b61ca01b6de56244a9e88d5f9b37973f622a43d14a6599b1f654cb45a74e355a5")!
|
||||
|
@ -261,33 +261,33 @@ class SodiumTests: XCTestCase {
|
|||
let verify2 = sodium.auth.verify(message: message, secretKey: key2, tag: tag)
|
||||
XCTAssertFalse(verify2)
|
||||
}
|
||||
|
||||
|
||||
func testKeyDerivationInputKeyTooShort() {
|
||||
let secretKey = sodium.randomBytes.buf(length: sodium.keyDerivation.KeyBytes - 1)!
|
||||
|
||||
|
||||
XCTAssertNil(sodium.keyDerivation.derive(secretKey: secretKey, index: 0, length: sodium.keyDerivation.BytesMin, context: "TEST"))
|
||||
}
|
||||
|
||||
|
||||
func testKeyDerivationInputKeyTooLong() {
|
||||
let secretKey = sodium.randomBytes.buf(length: sodium.keyDerivation.BytesMax + 1)!
|
||||
XCTAssertNil(sodium.keyDerivation.derive(secretKey: secretKey, index: 0, length: sodium.keyDerivation.BytesMin, context: "TEST"))
|
||||
}
|
||||
|
||||
|
||||
func testKeyDerivationSubKeyTooShort() {
|
||||
let secretKey = sodium.keyDerivation.key()!
|
||||
XCTAssertNil(sodium.keyDerivation.derive(secretKey: secretKey, index: 0, length: sodium.keyDerivation.BytesMin - 1, context: "TEST"))
|
||||
}
|
||||
|
||||
|
||||
func testKeyDerivationSubKeyTooLong() {
|
||||
let secretKey = sodium.keyDerivation.key()!
|
||||
XCTAssertNil(sodium.keyDerivation.derive(secretKey: secretKey, index: 0, length: sodium.keyDerivation.BytesMax + 1, context: "TEST"))
|
||||
}
|
||||
|
||||
|
||||
func testKeyDerivationContextTooLong() {
|
||||
let secretKey = sodium.keyDerivation.key()!
|
||||
XCTAssertNil(sodium.keyDerivation.derive(secretKey: secretKey, index: 0, length: sodium.keyDerivation.BytesMin, context: "TEST_SODIUM"))
|
||||
}
|
||||
|
||||
|
||||
func testKeyDerivation() {
|
||||
let secretKey = sodium.keyDerivation.key()!
|
||||
let subKey1 = sodium.keyDerivation.derive(secretKey: secretKey, index: 0, length: sodium.keyDerivation.BytesMin, context: "TEST")!
|
||||
|
@ -295,33 +295,33 @@ class SodiumTests: XCTestCase {
|
|||
let subKey3 = sodium.keyDerivation.derive(secretKey: secretKey, index: 0, length: sodium.keyDerivation.BytesMin, context: "TEST\0")!
|
||||
let subKey4 = sodium.keyDerivation.derive(secretKey: secretKey, index: 1, length: sodium.keyDerivation.BytesMin, context: "TEST")!
|
||||
let subKey5 = sodium.keyDerivation.derive(secretKey: secretKey, index: 0, length: sodium.keyDerivation.BytesMin, context: "test")!
|
||||
|
||||
|
||||
XCTAssertEqual(subKey1, subKey2, "Equally derived keys must be equal!")
|
||||
XCTAssertEqual(subKey1, subKey3, "Manual padding should result in same key.")
|
||||
|
||||
|
||||
XCTAssertNotEqual(subKey1, subKey4, "Subkeys with different indices must be different!")
|
||||
XCTAssertNotEqual(subKey1, subKey5, "Subkeys with different contexts must be different!")
|
||||
}
|
||||
|
||||
|
||||
func testKeyDerivationRegression() {
|
||||
let secretKey = sodium.utils.hex2bin("a9029ec4ec56dd6f3ce5a5fa27a17a005ce73a5b8e77529887f24f73ffa10d67")!
|
||||
let subKey1 = sodium.keyDerivation.derive(secretKey: secretKey, index: 0, length: sodium.keyDerivation.BytesMin, context: "TEST")!
|
||||
let subKey2 = sodium.keyDerivation.derive(secretKey: secretKey, index: 1, length: sodium.keyDerivation.BytesMin, context: "TEST")!
|
||||
|
||||
|
||||
XCTAssertEqual(sodium.utils.bin2hex(subKey1)!, "40d69c5e6e8b46e399433c9b5c3a7713")
|
||||
XCTAssertEqual(sodium.utils.bin2hex(subKey2)!, "8ba83c1cd5a3be912a80ef2abe1457c5")
|
||||
}
|
||||
|
||||
|
||||
func testSecretStream() {
|
||||
let secretKey = sodium.secretStream.xchacha20poly1305.key()!
|
||||
XCTAssertEqual(secretKey.count, 32)
|
||||
|
||||
|
||||
let stream = sodium.secretStream.xchacha20poly1305.initPush(secretKey: secretKey)!
|
||||
let header = stream.header()
|
||||
let encrypted1 = stream.push(message: "message 1".toData()!)!
|
||||
let encrypted2 = stream.push(message: "message 2".toData()!)!
|
||||
let encrypted3 = stream.push(message: "message 3".toData()!, tag: .FINAL)!
|
||||
|
||||
|
||||
let stream2 = sodium.secretStream.xchacha20poly1305.initPull(secretKey: secretKey, header: header)!
|
||||
let (message1, tag1) = stream2.pull(cipherText: encrypted1)!
|
||||
let (message2, tag2) = stream2.pull(cipherText: encrypted2)!
|
||||
|
@ -334,20 +334,20 @@ class SodiumTests: XCTestCase {
|
|||
XCTAssertEqual(message3, "message 3".toData()!)
|
||||
XCTAssertNil(stream2.pull(cipherText: encrypted3))
|
||||
}
|
||||
|
||||
|
||||
func testBase64() {
|
||||
let bin = "test".toData()!
|
||||
let b64 = sodium.utils.bin2base64(bin)!
|
||||
let bin2 = sodium.utils.base642bin(b64)!
|
||||
XCTAssertEqual(b64, "dGVzdA==")
|
||||
XCTAssertEqual(bin2, bin)
|
||||
|
||||
|
||||
let b64_nopad = sodium.utils.bin2base64(bin, variant: .URLSAFE_NO_PADDING)!
|
||||
let bin2_nopad = sodium.utils.base642bin(b64_nopad, variant: .URLSAFE_NO_PADDING)!
|
||||
XCTAssertEqual(b64_nopad, "dGVzdA")
|
||||
XCTAssertEqual(bin2_nopad, bin)
|
||||
}
|
||||
|
||||
|
||||
func testPad() {
|
||||
var data = "test".toData()!
|
||||
sodium.utils.pad(data: &data, blockSize: 16)!
|
||||
|
|
Loading…
Reference in New Issue