Defer to Swift's own handling for most pointers

Reference: https://developer.apple.com/swift/blog/?id=6
This commit is contained in:
Aidan Woods 2018-04-27 12:56:21 +01:00
parent af892c0f75
commit 48b08e47f0
No known key found for this signature in database
GPG Key ID: 9A6A8EFAA512BBB9
22 changed files with 587 additions and 828 deletions

View File

@ -69,6 +69,8 @@
DD35BB5720924D3A006BF351 /* KeyPairProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD35BB5520924D3A006BF351 /* KeyPairProtocol.swift */; };
DD35BB5A20925566006BF351 /* SecretKeyGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD35BB5920925566006BF351 /* SecretKeyGenerator.swift */; };
DD35BB5B20925566006BF351 /* SecretKeyGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD35BB5920925566006BF351 /* SecretKeyGenerator.swift */; };
DD35BB6320932A83006BF351 /* Bytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD35BB6220932A83006BF351 /* Bytes.swift */; };
DD35BB6420932A83006BF351 /* Bytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD35BB6220932A83006BF351 /* Bytes.swift */; };
F87EEC402063C655006C830D /* Aead.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EEC3F2063C655006C830D /* Aead.swift */; };
/* End PBXBuildFile section */
@ -210,6 +212,7 @@
DD35BB5220924B6F006BF351 /* KeyPairGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPairGenerator.swift; sourceTree = "<group>"; };
DD35BB5520924D3A006BF351 /* KeyPairProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPairProtocol.swift; sourceTree = "<group>"; };
DD35BB5920925566006BF351 /* SecretKeyGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretKeyGenerator.swift; sourceTree = "<group>"; };
DD35BB6220932A83006BF351 /* Bytes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bytes.swift; sourceTree = "<group>"; };
F87EEC3F2063C655006C830D /* Aead.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Aead.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -289,6 +292,7 @@
09A943E91A4EB70900C8A04F /* libsodium */,
09A943CC1A4EB5F500C8A04F /* Sodium.h */,
094F21E91A5017CA001C3141 /* Box.swift */,
DD35BB6220932A83006BF351 /* Bytes.swift */,
DD35BB58209252BF006BF351 /* Generators */,
DD1E4D0E20922C9E00BE7A3F /* ExitCode.swift */,
DD1E4D05208E744100BE7A3F /* StateStream.swift */,
@ -708,6 +712,7 @@
DD1E4D06208E744100BE7A3F /* StateStream.swift in Sources */,
094298301EDDAA3B001236B1 /* Stream.swift in Sources */,
D2A274061F13AD9300958702 /* KeyDerivation.swift in Sources */,
DD35BB6320932A83006BF351 /* Bytes.swift in Sources */,
09A5AC121F74466700D3200B /* SecretStream.swift in Sources */,
DD35BB5020924A35006BF351 /* NonceGenerator.swift in Sources */,
091C7CDA1A507E95002E5351 /* ShortHash.swift in Sources */,
@ -764,6 +769,7 @@
094298311EDDAA3B001236B1 /* Stream.swift in Sources */,
DD1E4D07208E744100BE7A3F /* StateStream.swift in Sources */,
DD1E4D1020922C9E00BE7A3F /* ExitCode.swift in Sources */,
DD35BB6420932A83006BF351 /* Bytes.swift in Sources */,
6096E7321F194FA800E6599F /* KeyDerivation.swift in Sources */,
098DAF041F76E35C00DFB1C3 /* SecretStream.swift in Sources */,
90C75EEA1AE3583E00F1E749 /* ShortHash.swift in Sources */,

View File

@ -6,7 +6,7 @@ public struct Aead {
public class XChaCha20Poly1305Ietf {
public let ABytes = Int(crypto_aead_xchacha20poly1305_ietf_abytes())
public typealias MAC = Data
public typealias MAC = Bytes
/**
Encrypts a message with a shared secret key.
@ -15,10 +15,10 @@ public struct Aead {
- Parameter secretKey: The shared secret key.
- Parameter additionalData: A typical use for these data is to authenticate version numbers, timestamps or monotonically increasing counters
- Returns: A `Data` object containing the nonce and authenticated ciphertext.
- Returns: A `Bytes` object containing the nonce and authenticated ciphertext.
*/
public func encrypt(message: Data, secretKey: Key, additionalData: Data? = nil) -> Data? {
guard let (authenticatedCipherText, nonce): (Data, Nonce) = encrypt(
public func encrypt(message: Bytes, secretKey: Key, additionalData: Bytes = Bytes()) -> Bytes? {
guard let (authenticatedCipherText, nonce): (Bytes, Nonce) = encrypt(
message: message,
secretKey: secretKey,
additionalData: additionalData
@ -36,82 +36,37 @@ public struct Aead {
- Returns: The authenticated ciphertext and encryption nonce.
*/
public func encrypt(message: Data, secretKey: Key, additionalData: Data? = nil) -> (authenticatedCipherText: Data, nonce: Nonce)? {
public func encrypt(message: Bytes, secretKey: Key, additionalData: Bytes = Bytes()) -> (authenticatedCipherText: Bytes, nonce: Nonce)? {
guard secretKey.count == KeyBytes else { return nil }
var authenticatedCipherText = Data(count: message.count + ABytes)
var authenticatedCipherTextLen = Data()
var authenticatedCipherText = Bytes(count: message.count + ABytes)
var authenticatedCipherTextLen: UInt64 = 0
let nonce = self.nonce()
let result: ExitCode
if let additionalData = additionalData {
result = authenticatedCipherText.withUnsafeMutableBytes { authenticatedCipherTextPtr in
authenticatedCipherTextLen.withUnsafeMutableBytes { authenticatedCipherTextLenPtr in
message.withUnsafeBytes { messagePtr in
additionalData.withUnsafeBytes { additionalDataPtr in
nonce.withUnsafeBytes { noncePtr in
secretKey.withUnsafeBytes { secretKeyPtr in
crypto_aead_xchacha20poly1305_ietf_encrypt(
authenticatedCipherTextPtr,
authenticatedCipherTextLenPtr,
messagePtr,
UInt64(message.count),
additionalDataPtr,
UInt64(additionalData.count),
nil, noncePtr, secretKeyPtr
).exitCode
}
}
}
}
}
}
} else {
result = authenticatedCipherText.withUnsafeMutableBytes { authenticatedCipherTextPtr in
authenticatedCipherTextLen.withUnsafeMutableBytes { authenticatedCipherTextLenPtr in
message.withUnsafeBytes { messagePtr in
nonce.withUnsafeBytes { noncePtr in
secretKey.withUnsafeBytes { secretKeyPtr in
crypto_aead_xchacha20poly1305_ietf_encrypt(
authenticatedCipherTextPtr,
authenticatedCipherTextLenPtr,
messagePtr,
UInt64(message.count),
nil,
0,
nil, noncePtr, secretKeyPtr
).exitCode
}
}
}
}
}
}
guard result == .SUCCESS else { return nil }
guard .SUCCESS == crypto_aead_xchacha20poly1305_ietf_encrypt (
&authenticatedCipherText, &authenticatedCipherTextLen,
message, UInt64(message.count),
additionalData, UInt64(additionalData.count),
nil, nonce, secretKey
).exitCode else { return nil }
return (authenticatedCipherText: authenticatedCipherText, nonce: nonce)
}
/**
Decrypts a message with a shared secret key.
- Parameter nonceAndAuthenticatedCipherText: A `Data` object containing the nonce and authenticated ciphertext.
- Parameter nonceAndAuthenticatedCipherText: A `Bytes` object containing the nonce and authenticated ciphertext.
- Parameter secretKey: The shared secret key.
- Parameter additionalData: Must be used same `Data` that was used to encrypt, if `Data` deferred will return nil
- Parameter additionalData: Must be used same `Bytes` that was used to encrypt, if `Bytes` deferred will return nil
- Returns: The decrypted message.
*/
public func decrypt(nonceAndAuthenticatedCipherText: Data, secretKey: Key, additionalData: Data? = nil) -> Data? {
public func decrypt(nonceAndAuthenticatedCipherText: Bytes, secretKey: Key, additionalData: Bytes = Bytes()) -> Bytes? {
guard nonceAndAuthenticatedCipherText.count >= ABytes + NonceBytes else { return nil }
let nonce = nonceAndAuthenticatedCipherText[..<NonceBytes] as Nonce
let authenticatedCipherText = nonceAndAuthenticatedCipherText[NonceBytes...]
let nonce = nonceAndAuthenticatedCipherText[..<NonceBytes].bytes as Nonce
let authenticatedCipherText = nonceAndAuthenticatedCipherText[NonceBytes...].bytes
return decrypt(authenticatedCipherText: authenticatedCipherText, secretKey: secretKey, nonce: nonce, additionalData: additionalData)
}
@ -119,73 +74,25 @@ public struct Aead {
/**
Decrypts a message with a shared secret key.
- Parameter authenticatedCipherText: A `Data` object containing authenticated ciphertext.
- Parameter authenticatedCipherText: A `Bytes` object containing authenticated ciphertext.
- Parameter secretKey: The shared secret key.
- Parameter additionalData: Must be used same `Data` that was used to encrypt, if `Data` deferred will return nil
- Parameter additionalData: Must be used same `Bytes` that was used to encrypt, if `Bytes` deferred will return nil
- Returns: The decrypted message.
*/
public func decrypt(authenticatedCipherText: Data, secretKey: Key, nonce: Nonce, additionalData: Data? = nil) -> Data? {
public func decrypt(authenticatedCipherText: Bytes, secretKey: Key, nonce: Nonce, additionalData: Bytes = Bytes()) -> Bytes? {
guard authenticatedCipherText.count >= ABytes else { return nil }
var message = Data(count: authenticatedCipherText.count - ABytes)
var messageLen = Data()
let result: ExitCode
if let additionalData = additionalData {
result = message.withUnsafeMutableBytes { messagePtr in
messageLen.withUnsafeMutableBytes { messageLen in
authenticatedCipherText.withUnsafeBytes { cipherTextPtr in
additionalData.withUnsafeBytes { additionalDataPtr in
nonce.withUnsafeBytes { noncePtr in
secretKey.withUnsafeBytes { secretKeyPtr in
crypto_aead_xchacha20poly1305_ietf_decrypt(
messagePtr,
messageLen,
nil,
cipherTextPtr,
UInt64(authenticatedCipherText.count),
additionalDataPtr,
UInt64(additionalData.count),
noncePtr, secretKeyPtr
).exitCode
}
}
}
}
}
}
} else {
result = message.withUnsafeMutableBytes { messagePtr in
messageLen.withUnsafeMutableBytes { messageLen in
authenticatedCipherText.withUnsafeBytes { cipherTextPtr in
nonce.withUnsafeBytes { noncePtr in
secretKey.withUnsafeBytes { secretKeyPtr in
crypto_aead_xchacha20poly1305_ietf_decrypt(
messagePtr,
messageLen,
nil,
cipherTextPtr,
UInt64(authenticatedCipherText.count),
nil,
0,
noncePtr, secretKeyPtr
).exitCode
}
}
}
}
}
}
guard result == .SUCCESS else { return nil }
var message = Bytes(count: authenticatedCipherText.count - ABytes)
var messageLen: UInt64 = 0
guard .SUCCESS == crypto_aead_xchacha20poly1305_ietf_decrypt (
&message, &messageLen,
nil,
authenticatedCipherText, UInt64(authenticatedCipherText.count),
additionalData, UInt64(additionalData.count),
nonce, secretKey
).exitCode else { return nil }
return message
}
@ -193,13 +100,13 @@ public struct Aead {
}
extension Aead.XChaCha20Poly1305Ietf: NonceGenerator {
public typealias Nonce = Data
public typealias Nonce = Bytes
public var NonceBytes: Int { return Int(crypto_aead_xchacha20poly1305_ietf_npubbytes()) }
}
extension Aead.XChaCha20Poly1305Ietf: SecretKeyGenerator {
public var KeyBytes: Int { return Int(crypto_aead_xchacha20poly1305_ietf_keybytes()) }
public typealias Key = Data
public typealias Key = Bytes
static var keygen: (UnsafeMutablePointer<UInt8>) -> Void = crypto_aead_xchacha20poly1305_ietf_keygen
}

View File

@ -13,19 +13,15 @@ public class Auth {
- Returns: The computed authentication tag.
*/
public func tag(message: Data, secretKey: SecretKey) -> Data? {
public func tag(message: Bytes, secretKey: SecretKey) -> Bytes? {
guard secretKey.count == KeyBytes else { return nil }
var tag = Data(count: Bytes)
guard .SUCCESS == tag.withUnsafeMutableBytes({ tagPtr in
message.withUnsafeBytes { messagePtr in
secretKey.withUnsafeBytes { secretKeyPtr in
crypto_auth( tagPtr,
messagePtr, CUnsignedLongLong(message.count),
secretKeyPtr).exitCode
}
}
}) else { return nil }
var tag = Array<UInt8>(count: Bytes)
guard .SUCCESS == crypto_auth (
&tag,
message, UInt64(message.count),
secretKey
).exitCode else { return nil }
return tag
}
@ -39,25 +35,21 @@ public class Auth {
- Returns: `true` if the verification is successful.
*/
public func verify(message: Data, secretKey: SecretKey, tag: Data) -> Bool {
public func verify(message: Bytes, secretKey: SecretKey, tag: Bytes) -> Bool {
guard secretKey.count == KeyBytes else {
return false
}
return .SUCCESS == tag.withUnsafeBytes { tagPtr in
message.withUnsafeBytes { messagePtr in
secretKey.withUnsafeBytes { secretKeyPtr in
crypto_auth_verify(
tagPtr,
messagePtr, CUnsignedLongLong(message.count), secretKeyPtr).exitCode
}
}
}
return .SUCCESS == crypto_auth_verify (
tag,
message, UInt64(message.count),
secretKey
).exitCode
}
}
extension Auth: SecretKeyGenerator {
public var KeyBytes: Int { return Int(crypto_auth_keybytes()) }
public typealias Key = Data
public typealias Key = Bytes
static let keygen: (_ k: UnsafeMutablePointer<UInt8>) -> Void = crypto_auth_keygen
}

View File

@ -7,8 +7,8 @@ public class Box {
public let BeforenmBytes = Int(crypto_box_beforenmbytes())
public let SealBytes = Int(crypto_box_sealbytes())
public typealias MAC = Data
public typealias Beforenm = Data
public typealias MAC = Bytes
public typealias Beforenm = Bytes
/**
Encrypts a message with a recipient's public key and a sender's secret key.
@ -17,10 +17,10 @@ public class Box {
- Parameter recipientPublicKey: The recipient's public key.
- Parameter senderSecretKey: The sender's secret key.
- Returns: A `Data` object containing the nonce and authenticated ciphertext.
- Returns: A `Bytes` object containing the nonce and authenticated ciphertext.
*/
public func seal(message: Data, recipientPublicKey: PublicKey, senderSecretKey: SecretKey) -> Data? {
guard let (authenticatedCipherText, nonce): (Data, Nonce) = seal(message: message, recipientPublicKey: recipientPublicKey, senderSecretKey: senderSecretKey) else {
public func seal(message: Bytes, recipientPublicKey: PublicKey, senderSecretKey: SecretKey) -> Bytes? {
guard let (authenticatedCipherText, nonce): (Bytes, Nonce) = seal(message: message, recipientPublicKey: recipientPublicKey, senderSecretKey: senderSecretKey) else {
return nil
}
return nonce + authenticatedCipherText
@ -36,29 +36,22 @@ public class Box {
- Returns: The authenticated ciphertext.
*/
public func seal(message: Data, recipientPublicKey: PublicKey, senderSecretKey: SecretKey, nonce: Nonce) -> Data? {
public func seal(message: Bytes, recipientPublicKey: PublicKey, senderSecretKey: SecretKey, nonce: Nonce) -> Bytes? {
guard recipientPublicKey.count == PublicKeyBytes,
senderSecretKey.count == SecretKeyBytes,
nonce.count == NonceBytes
else { return nil }
var authenticatedCipherText = Data(count: message.count + MacBytes)
var authenticatedCipherText = Bytes(count: message.count + MacBytes)
guard .SUCCESS == authenticatedCipherText.withUnsafeMutableBytes({ authenticatedCipherTextPtr in
message.withUnsafeBytes { messagePtr in
nonce.withUnsafeBytes { noncePtr in
recipientPublicKey.withUnsafeBytes { recipientPublicKeyPtr in
senderSecretKey.withUnsafeBytes { senderSecretKeyPtr in
crypto_box_easy(
authenticatedCipherTextPtr,
messagePtr, CUnsignedLongLong(message.count),
noncePtr,
recipientPublicKeyPtr, senderSecretKeyPtr).exitCode
}
}
}
}
}) else { return nil }
guard .SUCCESS == crypto_box_easy(
&authenticatedCipherText,
message,
CUnsignedLongLong(message.count),
nonce,
recipientPublicKey,
senderSecretKey
).exitCode else { return nil }
return authenticatedCipherText
}
@ -72,29 +65,22 @@ public class Box {
- Returns: The authenticated ciphertext and encryption nonce.
*/
public func seal(message: Data, recipientPublicKey: PublicKey, senderSecretKey: SecretKey) -> (authenticatedCipherText: Data, nonce: Nonce)? {
public func seal(message: Bytes, recipientPublicKey: PublicKey, senderSecretKey: SecretKey) -> (authenticatedCipherText: Bytes, nonce: Nonce)? {
guard recipientPublicKey.count == PublicKeyBytes,
senderSecretKey.count == SecretKeyBytes
else { return nil }
var authenticatedCipherText = Data(count: message.count + MacBytes)
var authenticatedCipherText = Bytes(count: message.count + MacBytes)
let nonce = self.nonce()
guard .SUCCESS == authenticatedCipherText.withUnsafeMutableBytes({ authenticatedCipherTextPtr in
message.withUnsafeBytes { messagePtr in
nonce.withUnsafeBytes { noncePtr in
recipientPublicKey.withUnsafeBytes { recipientPublicKeyPtr in
senderSecretKey.withUnsafeBytes { senderSecretKeyPtr in
crypto_box_easy(
authenticatedCipherTextPtr,
messagePtr, CUnsignedLongLong(message.count),
noncePtr,
recipientPublicKeyPtr, senderSecretKeyPtr).exitCode
}
}
}
}
}) else { return nil }
guard .SUCCESS == crypto_box_easy(
&authenticatedCipherText,
message,
CUnsignedLongLong(message.count),
nonce,
recipientPublicKey,
senderSecretKey
).exitCode else { return nil }
return (authenticatedCipherText: authenticatedCipherText, nonce: nonce)
}
@ -108,31 +94,23 @@ public class Box {
- Returns: The authenticated ciphertext, encryption nonce, and authentication tag.
*/
public func seal(message: Data, recipientPublicKey: PublicKey, senderSecretKey: SecretKey) -> (authenticatedCipherText: Data, nonce: Nonce, mac: MAC)? {
public func seal(message: Bytes, recipientPublicKey: PublicKey, senderSecretKey: SecretKey) -> (authenticatedCipherText: Bytes, nonce: Nonce, mac: MAC)? {
guard recipientPublicKey.count == PublicKeyBytes,
senderSecretKey.count == SecretKeyBytes
else { return nil }
var authenticatedCipherText = Data(count: message.count)
var mac = Data(count: MacBytes)
var authenticatedCipherText = Bytes(count: message.count)
var mac = Bytes(count: MacBytes)
let nonce = self.nonce()
guard .SUCCESS == authenticatedCipherText.withUnsafeMutableBytes({ authenticatedCipherTextPtr in
mac.withUnsafeMutableBytes { macPtr in
message.withUnsafeBytes { messagePtr in
nonce.withUnsafeBytes { noncePtr in
recipientPublicKey.withUnsafeBytes { recipientPublicKeyPtr in
senderSecretKey.withUnsafeBytes { senderSecretKeyPtr in
crypto_box_detached(
authenticatedCipherTextPtr, macPtr,
messagePtr, CUnsignedLongLong(message.count),
noncePtr,
recipientPublicKeyPtr, senderSecretKeyPtr).exitCode
}
}
}
}
}
}) else { return nil }
guard .SUCCESS == crypto_box_detached (
&authenticatedCipherText,
&mac,
message, CUnsignedLongLong(message.count),
nonce,
recipientPublicKey,
senderSecretKey
).exitCode else { return nil }
return (authenticatedCipherText: authenticatedCipherText, nonce: nonce as Nonce, mac: mac as MAC)
}
@ -140,16 +118,16 @@ public class Box {
/**
Decrypts a message with a sender's public key and the recipient's secret key.
- Parameter nonceAndAuthenticatedCipherText: A `Data` object containing the nonce and authenticated ciphertext.
- Parameter nonceAndAuthenticatedCipherText: A `Bytes` object containing the nonce and authenticated ciphertext.
- Parameter senderPublicKey: The sender's public key.
- Parameter recipientSecretKey: The recipient's secret key.
- Returns: The decrypted message.
*/
public func open(nonceAndAuthenticatedCipherText: Data, senderPublicKey: PublicKey, recipientSecretKey: SecretKey) -> Data? {
public func open(nonceAndAuthenticatedCipherText: Bytes, senderPublicKey: PublicKey, recipientSecretKey: SecretKey) -> Bytes? {
guard nonceAndAuthenticatedCipherText.count >= NonceBytes + MacBytes else { return nil }
let nonce = nonceAndAuthenticatedCipherText[..<NonceBytes] as Nonce
let authenticatedCipherText = nonceAndAuthenticatedCipherText[NonceBytes...]
let nonce = nonceAndAuthenticatedCipherText[..<NonceBytes].bytes as Nonce
let authenticatedCipherText = nonceAndAuthenticatedCipherText[NonceBytes...].bytes
return open(authenticatedCipherText: authenticatedCipherText, senderPublicKey: senderPublicKey, recipientSecretKey: recipientSecretKey, nonce: nonce)
}
@ -164,29 +142,22 @@ public class Box {
- Returns: The decrypted message.
*/
public func open(authenticatedCipherText: Data, senderPublicKey: PublicKey, recipientSecretKey: SecretKey, nonce: Nonce) -> Data? {
public func open(authenticatedCipherText: Bytes, senderPublicKey: PublicKey, recipientSecretKey: SecretKey, nonce: Nonce) -> Bytes? {
guard nonce.count == NonceBytes,
authenticatedCipherText.count >= MacBytes,
senderPublicKey.count == PublicKeyBytes,
recipientSecretKey.count == SecretKeyBytes
else { return nil }
var message = Data(count: authenticatedCipherText.count - MacBytes)
guard .SUCCESS == message.withUnsafeMutableBytes({ messagePtr in
authenticatedCipherText.withUnsafeBytes { authenticatedCipherTextPtr in
nonce.withUnsafeBytes { noncePtr in
senderPublicKey.withUnsafeBytes { senderPublicKeyPtr in
recipientSecretKey.withUnsafeBytes { recipientSecretKeyPtr in
crypto_box_open_easy(
messagePtr, authenticatedCipherTextPtr,
CUnsignedLongLong(authenticatedCipherText.count),
noncePtr,
senderPublicKeyPtr, recipientSecretKeyPtr).exitCode
}
}
}
}
}) else { return nil }
var message = Bytes(count: authenticatedCipherText.count - MacBytes)
guard .SUCCESS == crypto_box_open_easy(
&message,
authenticatedCipherText, UInt64(authenticatedCipherText.count),
nonce,
senderPublicKey,
recipientSecretKey
).exitCode else { return nil }
return message
}
@ -202,32 +173,24 @@ public class Box {
- Returns: The decrypted message.
*/
public func open(authenticatedCipherText: Data, senderPublicKey: PublicKey, recipientSecretKey: SecretKey, nonce: Nonce, mac: MAC) -> Data? {
public func open(authenticatedCipherText: Bytes, senderPublicKey: PublicKey, recipientSecretKey: SecretKey, nonce: Nonce, mac: MAC) -> Bytes? {
guard nonce.count == NonceBytes,
mac.count == MacBytes,
senderPublicKey.count == PublicKeyBytes,
recipientSecretKey.count == SecretKeyBytes
else { return nil }
var message = Data(count: authenticatedCipherText.count)
var message = Bytes(count: authenticatedCipherText.count)
guard .SUCCESS == message.withUnsafeMutableBytes({ messagePtr in
authenticatedCipherText.withUnsafeBytes { authenticatedCipherTextPtr in
mac.withUnsafeBytes { macPtr in
nonce.withUnsafeBytes { noncePtr in
senderPublicKey.withUnsafeBytes { senderPublicKeyPtr in
recipientSecretKey.withUnsafeBytes { recipientSecretKeyPtr in
crypto_box_open_detached(
messagePtr, authenticatedCipherTextPtr, macPtr,
CUnsignedLongLong(authenticatedCipherText.count),
noncePtr,
senderPublicKeyPtr, recipientSecretKeyPtr).exitCode
}
}
}
}
}
}) else { return nil }
guard .SUCCESS == crypto_box_open_detached(
&message,
authenticatedCipherText,
mac,
UInt64(authenticatedCipherText.count),
nonce,
senderPublicKey,
recipientSecretKey
).exitCode else { return nil }
return message
}
@ -242,15 +205,13 @@ public class Box {
- Returns: The computed shared secret key.
*/
public func beforenm(recipientPublicKey: PublicKey, senderSecretKey: SecretKey) -> Data? {
var key = Data(count: BeforenmBytes)
guard .SUCCESS == key.withUnsafeMutableBytes({ keyPtr in
recipientPublicKey.withUnsafeBytes { recipientPublicKeyPtr in
senderSecretKey.withUnsafeBytes { senderSecretKeyPtr in
crypto_box_beforenm(keyPtr, recipientPublicKeyPtr, senderSecretKeyPtr).exitCode
}
}
}) else { return nil }
public func beforenm(recipientPublicKey: PublicKey, senderSecretKey: SecretKey) -> Bytes? {
var key = Bytes(count: BeforenmBytes)
guard .SUCCESS == crypto_box_beforenm (
&key,
recipientPublicKey,
senderSecretKey
).exitCode else { return nil }
return key
}
@ -263,25 +224,17 @@ public class Box {
- Returns: The authenticated ciphertext and encryption nonce.
*/
public func seal(message: Data, beforenm: Beforenm) -> (authenticatedCipherText: Data, nonce: Nonce)? {
public func seal(message: Bytes, beforenm: Beforenm) -> (authenticatedCipherText: Bytes, nonce: Nonce)? {
guard beforenm.count == BeforenmBytes else { return nil }
var authenticatedCipherText = Data(count: message.count + MacBytes)
var authenticatedCipherText = Bytes(count: message.count + MacBytes)
let nonce = self.nonce()
guard .SUCCESS == authenticatedCipherText.withUnsafeMutableBytes({ authenticatedCipherTextPtr in
message.withUnsafeBytes { messagePtr in
nonce.withUnsafeBytes { noncePtr in
beforenm.withUnsafeBytes { beforenmPtr in
crypto_box_easy_afternm(
authenticatedCipherTextPtr,
messagePtr,
CUnsignedLongLong(message.count),
noncePtr,
beforenmPtr).exitCode
}
}
}
}) else { return nil }
guard .SUCCESS == crypto_box_easy_afternm (
&authenticatedCipherText,
message, UInt64(message.count),
nonce,
beforenm
).exitCode else { return nil }
return (authenticatedCipherText: authenticatedCipherText, nonce: nonce)
}
@ -289,16 +242,16 @@ public class Box {
/**
Decrypts a message with the shared secret key generated from a recipient's public key and a sender's secret key using `beforenm()`.
- Parameter nonceAndAuthenticatedCipherText: A `Data` object containing the nonce and authenticated ciphertext.
- Parameter nonceAndAuthenticatedCipherText: A `Bytes` object containing the nonce and authenticated ciphertext.
- Parameter beforenm: The shared secret key.
- Returns: The decrypted message.
*/
public func open(nonceAndAuthenticatedCipherText: Data, beforenm: Beforenm) -> Data? {
public func open(nonceAndAuthenticatedCipherText: Bytes, beforenm: Beforenm) -> Bytes? {
guard nonceAndAuthenticatedCipherText.count >= NonceBytes + MacBytes else { return nil }
let nonce = nonceAndAuthenticatedCipherText[..<NonceBytes] as Nonce
let authenticatedCipherText = nonceAndAuthenticatedCipherText[NonceBytes...]
let nonce = nonceAndAuthenticatedCipherText[..<NonceBytes].bytes as Nonce
let authenticatedCipherText = nonceAndAuthenticatedCipherText[NonceBytes...].bytes
return open(authenticatedCipherText: authenticatedCipherText, beforenm: beforenm, nonce: nonce)
}
@ -312,25 +265,20 @@ public class Box {
- Returns: The decrypted message.
*/
public func open(authenticatedCipherText: Data, beforenm: Beforenm, nonce: Nonce) -> Data? {
public func open(authenticatedCipherText: Bytes, beforenm: Beforenm, nonce: Nonce) -> Bytes? {
guard nonce.count == NonceBytes,
authenticatedCipherText.count >= MacBytes,
beforenm.count == BeforenmBytes
else { return nil }
var message = Data(count: authenticatedCipherText.count - MacBytes)
guard .SUCCESS == message.withUnsafeMutableBytes({ messagePtr in
authenticatedCipherText.withUnsafeBytes { authenticatedCipherTextPtr in
nonce.withUnsafeBytes { noncePtr in
beforenm.withUnsafeBytes { beforenmPtr in
crypto_box_open_easy_afternm(
messagePtr,
authenticatedCipherTextPtr, CUnsignedLongLong(authenticatedCipherText.count),
noncePtr, beforenmPtr).exitCode
}
}
}
}) else { return nil }
var message = Bytes(count: authenticatedCipherText.count - MacBytes)
guard .SUCCESS == crypto_box_open_easy_afternm (
&message,
authenticatedCipherText, UInt64(authenticatedCipherText.count),
nonce,
beforenm
).exitCode else { return nil }
return message
}
@ -341,10 +289,10 @@ public class Box {
- Parameter message: The message to encrypt.
- Parameter beforenm: The shared secret key.
- Returns: A `Data` object containing the encryption nonce and authenticated ciphertext.
- Returns: A `Bytes` object containing the encryption nonce and authenticated ciphertext.
*/
public func seal(message: Data, beforenm: Beforenm) -> Data? {
guard let (authenticatedCipherText, nonce): (Data, Nonce) = seal(
public func seal(message: Bytes, beforenm: Beforenm) -> Bytes? {
guard let (authenticatedCipherText, nonce): (Bytes, Nonce) = seal(
message: message,
beforenm: beforenm
) else { return nil }
@ -360,20 +308,15 @@ public class Box {
- Returns: The anonymous ciphertext.
*/
public func seal(message: Data, recipientPublicKey: Box.PublicKey) -> Data? {
public func seal(message: Bytes, recipientPublicKey: Box.PublicKey) -> Bytes? {
guard recipientPublicKey.count == PublicKeyBytes else { return nil }
var anonymousCipherText = Data(count: SealBytes + message.count)
var anonymousCipherText = Bytes(count: SealBytes + message.count)
guard .SUCCESS == anonymousCipherText.withUnsafeMutableBytes({ anonymousCipherTextPtr in
message.withUnsafeBytes { messagePtr in
recipientPublicKey.withUnsafeBytes { recipientPublicKeyPtr in
crypto_box_seal(
anonymousCipherTextPtr,
messagePtr, CUnsignedLongLong(message.count),
recipientPublicKeyPtr).exitCode
}
}
}) else { return nil }
guard .SUCCESS == crypto_box_seal (
&anonymousCipherText,
message, UInt64(message.count),
recipientPublicKey
).exitCode else { return nil }
return anonymousCipherText
}
@ -381,40 +324,34 @@ public class Box {
/**
Decrypts a message with the recipient's public key and secret key.
- Parameter anonymousCipherText: A `Data` object containing the anonymous ciphertext.
- Parameter anonymousCipherText: A `Bytes` object containing the anonymous ciphertext.
- Parameter senderPublicKey: The recipient's public key.
- Parameter recipientSecretKey: The recipient's secret key.
- Returns: The decrypted message.
*/
public func open(anonymousCipherText: Data, recipientPublicKey: PublicKey, recipientSecretKey: SecretKey) -> Data? {
public func open(anonymousCipherText: Bytes, recipientPublicKey: PublicKey, recipientSecretKey: SecretKey) -> Bytes? {
guard recipientPublicKey.count == PublicKeyBytes,
recipientSecretKey.count == SecretKeyBytes,
anonymousCipherText.count >= SealBytes
else { return nil }
var message = Data(count: anonymousCipherText.count - SealBytes)
var message = Bytes(count: anonymousCipherText.count - SealBytes)
guard .SUCCESS == message.withUnsafeMutableBytes({ messagePtr in
anonymousCipherText.withUnsafeBytes { anonymousCipherTextPtr in
recipientPublicKey.withUnsafeBytes { recipientPublicKeyPtr in
recipientSecretKey.withUnsafeBytes { recipientSecretKeyPtr in
crypto_box_seal_open(
messagePtr,
anonymousCipherTextPtr, CUnsignedLongLong(anonymousCipherText.count),
recipientPublicKeyPtr, recipientSecretKeyPtr).exitCode
}
}
}
}) else { return nil }
guard .SUCCESS == crypto_box_seal_open (
&message,
anonymousCipherText, UInt64(anonymousCipherText.count),
recipientPublicKey,
recipientSecretKey
).exitCode else { return nil }
return message
}
}
extension Box: KeyPairGenerator {
public typealias PublicKey = Data
public typealias SecretKey = Data
public typealias PublicKey = Bytes
public typealias SecretKey = Bytes
public var SeedBytes: Int { return Int(crypto_box_seedbytes()) }
public var PublicKeyBytes: Int { return Int(crypto_box_publickeybytes()) }
@ -440,7 +377,7 @@ extension Box: KeyPairGenerator {
}
extension Box: NonceGenerator {
public typealias Nonce = Data
public typealias Nonce = Bytes
public var NonceBytes: Int { return Int(crypto_box_noncebytes()) }
}

17
Sodium/Bytes.swift Normal file
View File

@ -0,0 +1,17 @@
import Foundation
public typealias Bytes = Array<UInt8>
extension Array where Element == UInt8 {
init (count bytes: Int) {
self.init(repeating: 0, count: bytes)
}
}
extension ArraySlice where Element == UInt8 {
var bytes: Bytes { return Bytes(self) }
}
public extension String {
var bytes: Bytes { return Bytes(self.utf8) }
}

View File

@ -4,10 +4,10 @@ protocol KeyPairGenerator {
associatedtype KeyPair: KeyPairProtocol
var PublicKeyBytes: Int { get }
associatedtype PublicKey where PublicKey == Data
associatedtype PublicKey where PublicKey == Bytes
var SecretKeyBytes: Int { get }
associatedtype SecretKey where SecretKey == Data
associatedtype SecretKey where SecretKey == Bytes
var SeedBytes: Int { get }
@ -30,14 +30,10 @@ extension KeyPairGenerator {
- Returns: A key pair containing the secret key and public key.
*/
public func keyPair() -> KeyPair? {
var pk = Data(count: PublicKeyBytes)
var sk = Data(count: SecretKeyBytes)
var pk = Bytes(count: PublicKeyBytes)
var sk = Bytes(count: SecretKeyBytes)
guard .SUCCESS == pk.withUnsafeMutableBytes({ pkPtr in
sk.withUnsafeMutableBytes { skPtr in
Self.newKeypair(pkPtr, skPtr).exitCode
}
}) else { return nil }
guard .SUCCESS == Self.newKeypair(&pk, &sk).exitCode else { return nil }
return KeyPair(publicKey: pk, secretKey: sk)
}
@ -49,18 +45,14 @@ extension KeyPairGenerator {
- Returns: A key pair containing the secret key and public key.
*/
public func keyPair(seed: Data) -> KeyPair? {
public func keyPair(seed: Bytes) -> KeyPair? {
guard seed.count == SeedBytes else { return nil }
var pk = Data(count: PublicKeyBytes)
var sk = Data(count: SecretKeyBytes)
var pk = Bytes(count: PublicKeyBytes)
var sk = Bytes(count: SecretKeyBytes)
guard .SUCCESS == pk.withUnsafeMutableBytes({ pkPtr in
sk.withUnsafeMutableBytes { skPtr in
seed.withUnsafeBytes { seedPtr in
Self.keypairFromSeed(pkPtr, skPtr, seedPtr).exitCode
}
}
}) else { return nil }
guard .SUCCESS == Self.keypairFromSeed(&pk, &sk, seed).exitCode else {
return nil
}
return KeyPair(publicKey: pk, secretKey: sk)
}

View File

@ -1,8 +1,8 @@
import Foundation
protocol KeyPairProtocol {
associatedtype PublicKey where PublicKey == Data
associatedtype SecretKey where SecretKey == Data
associatedtype PublicKey where PublicKey == Bytes
associatedtype SecretKey where SecretKey == Bytes
var publicKey: PublicKey { get }
var secretKey: SecretKey { get }

View File

@ -3,7 +3,7 @@ import Clibsodium
protocol NonceGenerator {
var NonceBytes: Int { get }
associatedtype Nonce where Nonce == Data
associatedtype Nonce where Nonce == Bytes
}
extension NonceGenerator {
@ -13,10 +13,8 @@ extension NonceGenerator {
- Returns: A nonce.
*/
public func nonce() -> Nonce {
var nonce = Data(count: NonceBytes)
nonce.withUnsafeMutableBytes {
noncePtr in randombytes_buf(noncePtr, NonceBytes)
}
var nonce = Bytes(count: NonceBytes)
randombytes_buf(&nonce, NonceBytes)
return nonce
}
}

View File

@ -2,7 +2,7 @@ import Foundation
protocol SecretKeyGenerator {
var KeyBytes: Int { get }
associatedtype Key where Key == Data
associatedtype Key where Key == Bytes
static var keygen: (_ k: UnsafeMutablePointer<UInt8>) -> Void { get }
}
@ -14,8 +14,8 @@ extension SecretKeyGenerator {
- Returns: The generated key.
*/
public func key() -> Key {
var k = Data(count: KeyBytes)
k.withUnsafeMutableBytes { kPtr in Self.keygen(kPtr) }
var k = Bytes(count: KeyBytes)
Self.keygen(&k)
return k
}
}

View File

@ -18,7 +18,7 @@ public class GenericHash {
- Returns: The computed fingerprint.
*/
public func hash(message: Data, key: Data? = nil) -> Data? {
public func hash(message: Bytes, key: Bytes? = nil) -> Bytes? {
return hash(message: message, key: key, outputLength: Bytes)
}
@ -31,32 +31,14 @@ public class GenericHash {
- Returns: The computed fingerprint.
*/
public func hash(message: Data, key: Data?, outputLength: Int) -> Data? {
var output = Data(count: outputLength)
let result: ExitCode
public func hash(message: Bytes, key: Bytes?, outputLength: Int) -> Bytes? {
var output = Array<UInt8>(count: outputLength)
if let key = key {
result = output.withUnsafeMutableBytes { outputPtr in
message.withUnsafeBytes { messagePtr in
key.withUnsafeBytes { keyPtr in
crypto_generichash(
outputPtr, outputLength,
messagePtr, CUnsignedLongLong(message.count),
keyPtr, key.count).exitCode
}
}
}
} else {
result = output.withUnsafeMutableBytes { outputPtr in
message.withUnsafeBytes { messagePtr in
crypto_generichash(
outputPtr, outputLength,
messagePtr, CUnsignedLongLong(message.count),
nil, 0).exitCode
}
}
}
guard result == .SUCCESS else { return nil }
guard .SUCCESS == crypto_generichash(
&output, outputLength,
message, UInt64(message.count),
key, key?.count ?? 0
).exitCode else { return nil }
return output
}
@ -69,7 +51,7 @@ public class GenericHash {
- Returns: The computed fingerprint.
*/
public func hash(message: Data, outputLength: Int) -> Data? {
public func hash(message: Bytes, outputLength: Int) -> Bytes? {
return hash(message: message, key: nil, outputLength: outputLength)
}
@ -80,7 +62,7 @@ public class GenericHash {
- Returns: The initialized `Stream`.
*/
public func initStream(key: Data? = nil) -> Stream? {
public func initStream(key: Bytes? = nil) -> Stream? {
return Stream(key: key, outputLength: Bytes)
}
@ -92,7 +74,7 @@ public class GenericHash {
- Returns: The initialized `Stream`.
*/
public func initStream(key: Data?, outputLength: Int) -> Stream? {
public func initStream(key: Bytes?, outputLength: Int) -> Stream? {
return Stream(key: key, outputLength: outputLength)
}
@ -114,20 +96,18 @@ public class GenericHash {
public var outputLength: Int = 0
init?(key: Data?, outputLength: Int) {
init?(key: Bytes?, outputLength: Int) {
state = Stream.generate()
let result: ExitCode
if let key = key {
result = key.withUnsafeBytes { keyPtr in
crypto_generichash_init(state, keyPtr, key.count, outputLength).exitCode
}
} else {
result = crypto_generichash_init(state, nil, 0, outputLength).exitCode
}
guard result == .SUCCESS else {
guard .SUCCESS == crypto_generichash_init(
state,
key, key?.count ?? 0,
outputLength
).exitCode else {
free()
return nil
}
self.outputLength = outputLength
}
@ -146,10 +126,11 @@ public class GenericHash {
- Returns: `true` if the data was consumed successfully.
*/
public func update(input: Data) -> Bool {
return .SUCCESS == input.withUnsafeBytes { inputPtr in
crypto_generichash_update(state, inputPtr, CUnsignedLongLong(input.count)).exitCode
}
public func update(input: Bytes) -> Bool {
return .SUCCESS == crypto_generichash_update(
state,
input, UInt64(input.count)
).exitCode
}
/**
@ -157,12 +138,13 @@ public class GenericHash {
- Returns: The computed fingerprint.
*/
public func final() -> Data? {
public func final() -> Bytes? {
let outputLen = outputLength
var output = Data(count: outputLen)
guard .SUCCESS == output.withUnsafeMutableBytes({ outputPtr in
crypto_generichash_final(state, outputPtr, outputLen).exitCode
}) else { return nil }
var output = Array<UInt8>(count: outputLen)
guard .SUCCESS == crypto_generichash_final(
state,
&output, outputLen
).exitCode else { return nil }
return output
}
@ -171,7 +153,7 @@ public class GenericHash {
extension GenericHash: SecretKeyGenerator {
public var KeyBytes: Int { return Int(crypto_generichash_keybytes()) }
public typealias Key = Data
public typealias Key = Bytes
static var keygen: (UnsafeMutablePointer<UInt8>) -> Void = crypto_generichash_keygen

View File

@ -6,7 +6,7 @@ public class KeyDerivation {
public let BytesMax = Int(crypto_kdf_bytes_max())
public let ContextBytes = Int(crypto_kdf_contextbytes())
public typealias SubKey = Data
public typealias SubKey = Bytes
/**
Derives a subkey from the specified input key. Each index (from 0 to (2^64) - 1) yields a unique deterministic subkey.
@ -21,10 +21,10 @@ public class KeyDerivation {
- Note: Output keys must have a length between BytesMin and BytesMax bytes (inclusive), otherwise an error is returned. Context must be at most 8 characters long. If the specified context is shorter than 8 characters, it will be padded to 8 characters. The master key is KeyBytes long.
*/
public func derive(secretKey: Data, index: UInt64, length: Int, context: String) -> Data? {
public func derive(secretKey: Bytes, index: UInt64, length: Int, context: String) -> Bytes? {
var contextBin = Bytes(context.utf8).map(Int8.init)
guard (BytesMin...BytesMax).contains(length),
secretKey.count == KeyBytes,
var contextBin = context.data(using: .utf8),
contextBin.count <= ContextBytes
else { return nil }
@ -32,15 +32,14 @@ public class KeyDerivation {
contextBin += [0]
}
var output = Data(count: length)
var output = Bytes(count: length)
guard .SUCCESS == output.withUnsafeMutableBytes({ outputPtr in
secretKey.withUnsafeBytes { secretKeyPtr in
contextBin.withUnsafeBytes { contextBinPtr in
crypto_kdf_derive_from_key(outputPtr, length, index, contextBinPtr, secretKeyPtr).exitCode
}
}
}) else { return nil }
guard .SUCCESS == crypto_kdf_derive_from_key(
&output, length,
index,
contextBin,
secretKey
).exitCode else { return nil }
return output
}
@ -48,7 +47,7 @@ public class KeyDerivation {
extension KeyDerivation: SecretKeyGenerator {
public var KeyBytes: Int { return Int(crypto_kdf_keybytes()) }
public typealias Key = Data
public typealias Key = Bytes
static var keygen: (UnsafeMutablePointer<UInt8>) -> Void = crypto_kdf_keygen
}

View File

@ -5,10 +5,10 @@ public class KeyExchange {
public let SessionKeyBytes = Int(crypto_kx_sessionkeybytes())
public struct SessionKeyPair {
public let rx: Data
public let tx: Data
public let rx: Bytes
public let tx: Bytes
public init(rx: Data, tx: Data) {
public init(rx: Bytes, tx: Bytes) {
self.rx = rx
self.tx = tx
}
@ -51,28 +51,24 @@ public class KeyExchange {
otherPublicKey.count == PublicKeyBytes
else { return nil }
var rx = Data(count: SessionKeyBytes)
var tx = Data(count: SessionKeyBytes)
var rx = Bytes(count: SessionKeyBytes)
var tx = Bytes(count: SessionKeyBytes)
guard .SUCCESS == rx.withUnsafeMutableBytes({ rxPtr in
tx.withUnsafeMutableBytes { txPtr in
secretKey.withUnsafeBytes { secretKeyPtr in
publicKey.withUnsafeBytes { publicKeyPtr in
otherPublicKey.withUnsafeBytes { otherPublicKeyPtr in
side.sessionKeys(rxPtr, txPtr, publicKeyPtr, secretKeyPtr, otherPublicKeyPtr).exitCode
}
}
}
}
}) else { return nil }
guard .SUCCESS == side.sessionKeys (
&rx,
&tx,
publicKey,
secretKey,
otherPublicKey
).exitCode else { return nil }
return SessionKeyPair(rx: rx, tx: tx)
}
}
extension KeyExchange: KeyPairGenerator {
public typealias PublicKey = Data
public typealias SecretKey = Data
public typealias PublicKey = Bytes
public typealias SecretKey = Bytes
public var SeedBytes: Int { return Int(crypto_kx_seedbytes()) }
public var PublicKeyBytes: Int { return Int(crypto_kx_publickeybytes()) }

View File

@ -41,37 +41,36 @@ public class PWHash {
- Returns: The generated string.
*/
public func str(passwd: Data, opsLimit: Int, memLimit: Int) -> String? {
var output = Data(count: StrBytes)
guard .SUCCESS == output.withUnsafeMutableBytes({ outputPtr in
passwd.withUnsafeBytes { passwdPtr in
crypto_pwhash_str(outputPtr,
passwdPtr, CUnsignedLongLong(passwd.count),
CUnsignedLongLong(opsLimit), size_t(memLimit)).exitCode
}
}) else { return nil }
public func str(passwd: Bytes, opsLimit: Int, memLimit: Int) -> String? {
var output = Bytes(count: StrBytes).map(Int8.init)
let passwd = passwd.map(Int8.init)
return String(data: output, encoding: .utf8)
guard .SUCCESS == crypto_pwhash_str(
&output,
passwd, UInt64(passwd.count),
UInt64(opsLimit),
size_t(memLimit)
).exitCode else { return nil }
return String(cString: output)
}
/**
Verifies that the password str is a valid password verification string (as generated by `str(passwd: Data, opslimit: Int, memLimit: Int)` for `passwd`.
Verifies that the password str is a valid password verification string (as generated by `str(passwd: Bytes, opslimit: Int, memLimit: Int)` for `passwd`.
- Parameter hash: The password hash string to verify.
- Parameter passwd: The password data to verify.
- Returns: `true` if the verification succeeds.
*/
public func strVerify(hash: String, passwd: Data) -> Bool {
guard let hashData = (hash + "\0").data(using: .utf8, allowLossyConversion: false) else {
return false
}
return .SUCCESS == hashData.withUnsafeBytes { hashPtr in
passwd.withUnsafeBytes { passwdPtr in
crypto_pwhash_str_verify(
hashPtr, passwdPtr, CUnsignedLongLong(passwd.count)).exitCode
}
}
public func strVerify(hash: String, passwd: Bytes) -> Bool {
let hashBytes = Bytes((hash + "\0").utf8).map(Int8.init)
let passwd = passwd.map(Int8.init)
return .SUCCESS == crypto_pwhash_str_verify(
hashBytes,
passwd, UInt64(passwd.count)
).exitCode
}
/**
@ -84,13 +83,12 @@ public class PWHash {
- Returns: `true` if the password hash should be updated.
*/
public func strNeedsRehash(hash: String, opsLimit: Int, memLimit: Int) -> Bool {
guard let hashData = (hash + "\0").data(using: .utf8, allowLossyConversion: false) else {
return true
}
return hashData.withUnsafeBytes { hashPtr in
crypto_pwhash_str_needs_rehash(
hashPtr, CUnsignedLongLong(opsLimit), size_t(memLimit)) != 0
}
let hashBytes = Bytes((hash + "\0").utf8).map(Int8.init)
return .SUCCESS != crypto_pwhash_str_needs_rehash(
hashBytes,
UInt64(opsLimit),
size_t(memLimit)
).exitCode
}
/**
@ -107,20 +105,19 @@ public class PWHash {
- Returns: The derived key data.
*/
public func hash(outputLength: Int, passwd: Data, salt: Data, opsLimit: Int, memLimit: Int, alg: Alg = .Default) -> Data? {
public func hash(outputLength: Int, passwd: Bytes, salt: Bytes, opsLimit: Int, memLimit: Int, alg: Alg = .Default) -> Bytes? {
guard salt.count == SaltBytes else { return nil }
var output = Data(count: outputLength)
guard .SUCCESS == passwd.withUnsafeBytes({ passwdPtr in
salt.withUnsafeBytes { saltPtr in
output.withUnsafeMutableBytes { outputPtr in
crypto_pwhash(
outputPtr, CUnsignedLongLong(outputLength),
passwdPtr, CUnsignedLongLong(passwd.count),
saltPtr, CUnsignedLongLong(opsLimit),
size_t(memLimit), alg.id).exitCode
}
}
}) else { return nil }
var output = Bytes(count: outputLength)
let passwd = passwd.map(Int8.init)
guard .SUCCESS == crypto_pwhash(
&output, UInt64(outputLength),
passwd, UInt64(passwd.count),
salt,
UInt64(opsLimit),
size_t(memLimit),
alg.id
).exitCode else { return nil }
return output
}

View File

@ -5,18 +5,16 @@ public class RandomBytes {
public let SeedBytes = Int(randombytes_seedbytes())
/**
Returns a `Data object of length `length` containing an unpredictable sequence of bytes.
Returns a `Bytes object of length `length` containing an unpredictable sequence of bytes.
- Parameter length: The number of bytes to generate.
- Returns: The generated data.
*/
public func buf(length: Int) -> Data? {
public func buf(length: Int) -> Bytes? {
guard length >= 0 else { return nil }
var output = Data(count: length)
output.withUnsafeMutableBytes { outputPtr in
randombytes_buf(outputPtr, length)
}
var output = Bytes(count: length)
randombytes_buf(&output, length)
return output
}
@ -46,18 +44,14 @@ public class RandomBytes {
- Returns: The generated data.
*/
public func deterministic(length: Int, seed: Data) -> Data? {
public func deterministic(length: Int, seed: Bytes) -> Bytes? {
guard length >= 0,
seed.count == SeedBytes,
Int64(length) <= 0x4000000000 as Int64
else { return nil }
var output = Data(count: length)
output.withUnsafeMutableBytes { outputPtr in
seed.withUnsafeBytes { seedPtr in
randombytes_buf_deterministic(outputPtr, length, seedPtr)
}
}
var output = Bytes(count: length)
randombytes_buf_deterministic(&output, length, seed)
return output
}
}

View File

@ -3,7 +3,7 @@ import Clibsodium
public class SecretBox {
public let MacBytes = Int(crypto_secretbox_macbytes())
public typealias MAC = Data
public typealias MAC = Bytes
/**
Encrypts a message with a shared secret key.
@ -11,10 +11,10 @@ public class SecretBox {
- Parameter message: The message to encrypt.
- Parameter secretKey: The shared secret key.
- Returns: A `Data` object containing the nonce and authenticated ciphertext.
- Returns: A `Bytes` object containing the nonce and authenticated ciphertext.
*/
public func seal(message: Data, secretKey: Key) -> Data? {
guard let (authenticatedCipherText, nonce): (Data, Nonce) = seal(
public func seal(message: Bytes, secretKey: Key) -> Bytes? {
guard let (authenticatedCipherText, nonce): (Bytes, Nonce) = seal(
message: message,
secretKey: secretKey
) else { return nil }
@ -29,23 +29,17 @@ public class SecretBox {
- Returns: The authenticated ciphertext and encryption nonce.
*/
public func seal(message: Data, secretKey: Key) -> (authenticatedCipherText: Data, nonce: Nonce)? {
public func seal(message: Bytes, secretKey: Key) -> (authenticatedCipherText: Bytes, nonce: Nonce)? {
guard secretKey.count == KeyBytes else { return nil }
var authenticatedCipherText = Data(count: message.count + MacBytes)
var authenticatedCipherText = Bytes(count: message.count + MacBytes)
let nonce = self.nonce()
guard .SUCCESS == authenticatedCipherText.withUnsafeMutableBytes({ authenticatedCipherTextPtr in
message.withUnsafeBytes { messagePtr in
nonce.withUnsafeBytes { noncePtr in
secretKey.withUnsafeBytes { secretKeyPtr in
crypto_secretbox_easy(
authenticatedCipherTextPtr,
messagePtr, UInt64(message.count),
noncePtr, secretKeyPtr).exitCode
}
}
}
}) else { return nil }
guard .SUCCESS == crypto_secretbox_easy (
&authenticatedCipherText,
message, UInt64(message.count),
nonce,
secretKey
).exitCode else { return nil }
return (authenticatedCipherText: authenticatedCipherText, nonce: nonce)
}
@ -58,27 +52,20 @@ public class SecretBox {
- Returns: The encrypted ciphertext, encryption nonce, and authentication tag.
*/
public func seal(message: Data, secretKey: Key) -> (cipherText: Data, nonce: Nonce, mac: MAC)? {
public func seal(message: Bytes, secretKey: Key) -> (cipherText: Bytes, nonce: Nonce, mac: MAC)? {
guard secretKey.count == KeyBytes else { return nil }
var cipherText = Data(count: message.count)
var mac = Data(count: MacBytes)
var cipherText = Bytes(count: message.count)
var mac = Bytes(count: MacBytes)
let nonce = self.nonce()
guard .SUCCESS == cipherText.withUnsafeMutableBytes({ cipherTextPtr in
mac.withUnsafeMutableBytes { macPtr in
message.withUnsafeBytes { messagePtr in
nonce.withUnsafeBytes { noncePtr in
secretKey.withUnsafeBytes { secretKeyPtr in
crypto_secretbox_detached(
cipherTextPtr, macPtr,
messagePtr, UInt64(message.count),
noncePtr, secretKeyPtr).exitCode
}
}
}
}
}) else { return nil }
guard .SUCCESS == crypto_secretbox_detached (
&cipherText,
&mac,
message, UInt64(message.count),
nonce,
secretKey
).exitCode else { return nil }
return (cipherText: cipherText, nonce: nonce, mac: mac)
}
@ -86,15 +73,15 @@ public class SecretBox {
/**
Decrypts a message with a shared secret key.
- Parameter nonceAndAuthenticatedCipherText: A `Data` object containing the nonce and authenticated ciphertext.
- Parameter nonceAndAuthenticatedCipherText: A `Bytes` object containing the nonce and authenticated ciphertext.
- Parameter secretKey: The shared secret key.
- Returns: The decrypted message.
*/
public func open(nonceAndAuthenticatedCipherText: Data, secretKey: Key) -> Data? {
public func open(nonceAndAuthenticatedCipherText: Bytes, secretKey: Key) -> Bytes? {
guard nonceAndAuthenticatedCipherText.count >= MacBytes + NonceBytes else { return nil }
let nonce = nonceAndAuthenticatedCipherText[..<NonceBytes] as Nonce
let authenticatedCipherText = nonceAndAuthenticatedCipherText[NonceBytes...]
let nonce = nonceAndAuthenticatedCipherText[..<NonceBytes].bytes as Nonce
let authenticatedCipherText = nonceAndAuthenticatedCipherText[NonceBytes...].bytes
return open(authenticatedCipherText: authenticatedCipherText, secretKey: secretKey, nonce: nonce)
}
@ -108,22 +95,16 @@ public class SecretBox {
- Returns: The decrypted message.
*/
public func open(authenticatedCipherText: Data, secretKey: Key, nonce: Nonce) -> Data? {
public func open(authenticatedCipherText: Bytes, secretKey: Key, nonce: Nonce) -> Bytes? {
guard authenticatedCipherText.count >= MacBytes else { return nil }
var message = Data(count: authenticatedCipherText.count - MacBytes)
var message = Bytes(count: authenticatedCipherText.count - MacBytes)
guard .SUCCESS == message.withUnsafeMutableBytes({ messagePtr in
authenticatedCipherText.withUnsafeBytes { authenticatedCipherTextPtr in
nonce.withUnsafeBytes { noncePtr in
secretKey.withUnsafeBytes { secretKeyPtr in
crypto_secretbox_open_easy(
messagePtr,
authenticatedCipherTextPtr, UInt64(authenticatedCipherText.count),
noncePtr, secretKeyPtr).exitCode
}
}
}
}) else { return nil }
guard .SUCCESS == crypto_secretbox_open_easy (
&message,
authenticatedCipherText, UInt64(authenticatedCipherText.count),
nonce,
secretKey
).exitCode else { return nil }
return message
}
@ -137,28 +118,22 @@ public class SecretBox {
- Returns: The decrypted message.
*/
public func open(cipherText: Data, secretKey: Key, nonce: Nonce, mac: MAC) -> Data? {
public func open(cipherText: Bytes, secretKey: Key, nonce: Nonce, mac: MAC) -> Bytes? {
guard nonce.count == NonceBytes,
mac.count == MacBytes,
secretKey.count == KeyBytes
else { return nil }
var message = Data(count: cipherText.count)
var message = Bytes(count: cipherText.count)
guard .SUCCESS == message.withUnsafeMutableBytes({ messagePtr in
cipherText.withUnsafeBytes { cipherTextPtr in
mac.withUnsafeBytes { macPtr in
nonce.withUnsafeBytes { noncePtr in
secretKey.withUnsafeBytes { secretKeyPtr in
crypto_secretbox_open_detached(
messagePtr,
cipherTextPtr, macPtr, UInt64(cipherText.count),
noncePtr, secretKeyPtr).exitCode
}
}
}
}
}) else { return nil }
guard .SUCCESS == crypto_secretbox_open_detached (
&message,
cipherText,
mac,
UInt64(cipherText.count),
nonce,
secretKey
).exitCode else { return nil }
return message
}
@ -166,10 +141,10 @@ public class SecretBox {
extension SecretBox: NonceGenerator {
public var NonceBytes: Int { return Int(crypto_secretbox_noncebytes()) }
public typealias Nonce = Data
public typealias Nonce = Bytes
}
extension SecretBox: SecretKeyGenerator {
public typealias Key = Data
public typealias Key = Bytes
public var KeyBytes: Int { return Int(crypto_secretbox_keybytes()) }
static let keygen: (_ k: UnsafeMutablePointer<UInt8>) -> Void = crypto_secretbox_keygen

View File

@ -14,7 +14,7 @@ public class SecretStream {
case REKEY = 0x02
case FINAL = 0x03
}
public typealias Header = Data
public typealias Header = Bytes
/**
Creates a new stream using the secret key `secretKey`
@ -52,12 +52,12 @@ public class SecretStream {
guard secretKey.count == KeyBytes else { return nil }
state = PushStream.generate()
_header = Data(count: HeaderBytes)
guard .SUCCESS == secretKey.withUnsafeBytes({ secretKeyPtr in
_header.withUnsafeMutableBytes { headerPtr in
crypto_secretstream_xchacha20poly1305_init_push(state, headerPtr, secretKeyPtr).exitCode
}
}) else {
_header = Bytes(count: HeaderBytes)
guard .SUCCESS == crypto_secretstream_xchacha20poly1305_init_push(
state,
&_header,
secretKey
).exitCode else {
free()
return nil
}
@ -82,16 +82,17 @@ public class SecretStream {
- Returns: The ciphertext.
*/
public func push(message: Data, tag: Tag = .MESSAGE, ad: Data? = nil) -> Data? {
let _ad = ad ?? Data(count: 0)
var cipherText = Data(count: message.count + ABytes)
guard .SUCCESS == cipherText.withUnsafeMutableBytes({ cipherTextPtr in
_ad.withUnsafeBytes { adPtr in
message.withUnsafeBytes { messagePtr in
crypto_secretstream_xchacha20poly1305_push(state, cipherTextPtr, nil, messagePtr, CUnsignedLongLong(message.count), adPtr, CUnsignedLongLong(_ad.count), tag.rawValue).exitCode
}
}
}) else { return nil }
public func push(message: Bytes, tag: Tag = .MESSAGE, ad: Bytes? = nil) -> Bytes? {
let _ad = ad ?? Bytes(count: 0)
var cipherText = Bytes(count: message.count + ABytes)
guard .SUCCESS == crypto_secretstream_xchacha20poly1305_push(
state,
&cipherText,
nil,
message, UInt64(message.count),
_ad, UInt64(_ad.count),
tag.rawValue
).exitCode else { return nil }
return cipherText
}
@ -123,11 +124,11 @@ public class SecretStream {
return nil
}
state = PushStream.generate()
guard .SUCCESS == secretKey.withUnsafeBytes({ secretKeyPtr in
header.withUnsafeBytes { headerPtr in
crypto_secretstream_xchacha20poly1305_init_pull(state, headerPtr, secretKeyPtr).exitCode
}
}) else {
guard .SUCCESS == crypto_secretstream_xchacha20poly1305_init_pull(
state,
header,
secretKey
).exitCode else {
free()
return nil
}
@ -141,18 +142,20 @@ public class SecretStream {
- Returns: The decrypted message, as well as the tag attached to it.
*/
public func pull(cipherText: Data, ad: Data? = nil) -> (Data, Tag)? {
public func pull(cipherText: Bytes, ad: Bytes? = nil) -> (Bytes, Tag)? {
guard cipherText.count >= ABytes else { return nil }
var message = Data(count: cipherText.count - ABytes)
let _ad = ad ?? Data(count: 0)
var message = Bytes(count: cipherText.count - ABytes)
let _ad = ad ?? Bytes(count: 0)
var _tag: UInt8 = 0
let result = cipherText.withUnsafeBytes { cipherTextPtr in
_ad.withUnsafeBytes { adPtr in
message.withUnsafeMutableBytes { messagePtr in
crypto_secretstream_xchacha20poly1305_pull(state, messagePtr, nil, &_tag, cipherTextPtr, CUnsignedLongLong(cipherText.count), adPtr, CUnsignedLongLong(_ad.count)).exitCode
}
}
}
let result = crypto_secretstream_xchacha20poly1305_pull(
state,
&message,
nil,
&_tag,
cipherText, UInt64(cipherText.count),
_ad, UInt64(_ad.count)
).exitCode
guard result == .SUCCESS, let tag = Tag(rawValue: _tag) else {
return nil
}
@ -179,7 +182,7 @@ public class SecretStream {
extension SecretStream.XChaCha20Poly1305: SecretKeyGenerator {
var KeyBytes: Int { return SecretStream.XChaCha20Poly1305.KeyBytes }
public typealias Key = Data
public typealias Key = Bytes
static var keygen: (UnsafeMutablePointer<UInt8>) -> Void = crypto_secretstream_xchacha20poly1305_keygen

View File

@ -12,17 +12,15 @@ public class ShortHash {
- Returns: The computed fingerprint.
*/
public func hash(message: Data, key: Data) -> Data? {
public func hash(message: Bytes, key: Bytes) -> Bytes? {
guard key.count == KeyBytes else { return nil }
var output = Data(count: Bytes)
var output = Array<UInt8>(count: Bytes)
guard .SUCCESS == output.withUnsafeMutableBytes({ outputPtr in
message.withUnsafeBytes { messagePtr in
key.withUnsafeBytes { keyPtr in
crypto_shorthash(outputPtr, messagePtr, CUnsignedLongLong(message.count), keyPtr).exitCode
}
}
}) else { return nil }
guard .SUCCESS == crypto_shorthash (
&output,
message, UInt64(message.count),
key
).exitCode else { return nil }
return output
}
@ -30,7 +28,7 @@ public class ShortHash {
extension ShortHash: SecretKeyGenerator {
public var KeyBytes: Int { return Int(crypto_shorthash_keybytes()) }
public typealias Key = Data
public typealias Key = Bytes
static var keygen: (UnsafeMutablePointer<UInt8>) -> Void = crypto_shorthash_keygen
}

View File

@ -13,20 +13,16 @@ public class Sign {
- Returns: The signed message.
*/
public func sign(message: Data, secretKey: SecretKey) -> Data? {
public func sign(message: Bytes, secretKey: SecretKey) -> Bytes? {
guard secretKey.count == SecretKeyBytes else { return nil }
var signedMessage = Data(count: message.count + Bytes)
var signedMessage = Array<UInt8>(count: message.count + Bytes)
guard .SUCCESS == signedMessage.withUnsafeMutableBytes({ signedMessagePtr in
message.withUnsafeBytes { messagePtr in
secretKey.withUnsafeBytes { secretKeyPtr in
crypto_sign(
signedMessagePtr, nil,
messagePtr, CUnsignedLongLong(message.count),
secretKeyPtr).exitCode
}
}
}) else { return nil }
guard .SUCCESS == crypto_sign (
&signedMessage,
nil,
message, UInt64(message.count),
secretKey
).exitCode else { return nil }
return signedMessage
}
@ -39,20 +35,16 @@ public class Sign {
- Returns: The computed signature.
*/
public func signature(message: Data, secretKey: SecretKey) -> Data? {
public func signature(message: Bytes, secretKey: SecretKey) -> Bytes? {
guard secretKey.count == SecretKeyBytes else { return nil }
var signature = Data(count: Bytes)
var signature = Array<UInt8>(count: Bytes)
guard .SUCCESS == signature.withUnsafeMutableBytes({ signaturePtr in
message.withUnsafeBytes { messagePtr in
secretKey.withUnsafeBytes { secretKeyPtr in
crypto_sign_detached(
signaturePtr, nil,
messagePtr, CUnsignedLongLong(message.count),
secretKeyPtr).exitCode
}
}
}) else { return nil }
guard .SUCCESS == crypto_sign_detached (
&signature,
nil,
message, UInt64(message.count),
secretKey
).exitCode else { return nil }
return signature
}
@ -65,9 +57,9 @@ public class Sign {
- Returns: `true` if verification is successful.
*/
public func verify(signedMessage: Data, publicKey: PublicKey) -> Bool {
let signature = signedMessage[..<Bytes]
let message = signedMessage[Bytes...]
public func verify(signedMessage: Bytes, publicKey: PublicKey) -> Bool {
let signature = signedMessage[..<Bytes].bytes
let message = signedMessage[Bytes...].bytes
return verify(message: message, publicKey: publicKey, signature: signature)
}
@ -81,20 +73,16 @@ public class Sign {
- Returns: `true` if verification is successful.
*/
public func verify(message: Data, publicKey: PublicKey, signature: Data) -> Bool {
public func verify(message: Bytes, publicKey: PublicKey, signature: Bytes) -> Bool {
guard publicKey.count == PublicKeyBytes else {
return false
}
return .SUCCESS == signature.withUnsafeBytes { signaturePtr in
message.withUnsafeBytes { messagePtr in
publicKey.withUnsafeBytes { publicKeyPtr in
crypto_sign_verify_detached(
signaturePtr,
messagePtr, CUnsignedLongLong(message.count), publicKeyPtr).exitCode
}
}
}
return .SUCCESS == crypto_sign_verify_detached (
signature,
message, UInt64(message.count),
publicKey
).exitCode
}
/**
@ -105,32 +93,27 @@ public class Sign {
- Returns: The message data if verification is successful.
*/
public func open(signedMessage: Data, publicKey: PublicKey) -> Data? {
public func open(signedMessage: Bytes, publicKey: PublicKey) -> Bytes? {
guard publicKey.count == PublicKeyBytes, signedMessage.count >= Bytes else {
return nil
}
var message = Data(count: signedMessage.count - Bytes)
var mlen: CUnsignedLongLong = 0
var message = Array<UInt8>(count: signedMessage.count - Bytes)
var mlen: UInt64 = 0
guard .SUCCESS == message.withUnsafeMutableBytes({ messagePtr in
signedMessage.withUnsafeBytes { signedMessagePtr in
publicKey.withUnsafeBytes { publicKeyPtr in
crypto_sign_open(
messagePtr, &mlen,
signedMessagePtr, CUnsignedLongLong(signedMessage.count),
publicKeyPtr).exitCode
}
}
}) else { return nil }
guard .SUCCESS == crypto_sign_open (
&message, &mlen,
signedMessage, UInt64(signedMessage.count),
publicKey
).exitCode else { return nil }
return message
}
}
extension Sign: KeyPairGenerator {
public typealias PublicKey = Data
public typealias SecretKey = Data
public typealias PublicKey = Bytes
public typealias SecretKey = Bytes
public var SeedBytes: Int { return Int(crypto_sign_seedbytes()) }
public var PublicKeyBytes: Int { return Int(crypto_sign_publickeybytes()) }

View File

@ -17,19 +17,16 @@ public class Stream {
- Returns: input XOR keystream(secretKey, nonce)
*/
public func xor(input: Data, nonce: Nonce, secretKey: Key) -> Data? {
public func xor(input: Bytes, nonce: Nonce, secretKey: Key) -> Bytes? {
guard secretKey.count == KeyBytes, nonce.count == NonceBytes else { return nil }
var output = Data(count: input.count)
guard .SUCCESS == output.withUnsafeMutableBytes({ outputPtr in
input.withUnsafeBytes { inputPtr in
nonce.withUnsafeBytes { noncePtr in
secretKey.withUnsafeBytes { secretKeyPtr in
crypto_stream_xor(outputPtr, inputPtr, UInt64(input.count), noncePtr, secretKeyPtr).exitCode
}
}
}
}) else { return nil }
var output = Bytes(count: input.count)
guard .SUCCESS == crypto_stream_xor (
&output,
input, UInt64(input.count),
nonce,
secretKey
).exitCode else { return nil }
return output
}
@ -47,10 +44,10 @@ public class Stream {
- Returns: (input XOR keystream(secretKey, nonce), nonce)
*/
public func xor(input: Data, secretKey: Key) -> (output:Data, nonce: Nonce)? {
public func xor(input: Bytes, secretKey: Key) -> (output:Bytes, nonce: Nonce)? {
let nonce = self.nonce()
guard let output: Data = xor(
guard let output: Bytes = xor(
input: input,
nonce: nonce,
secretKey: secretKey
@ -61,12 +58,12 @@ public class Stream {
}
extension Stream: NonceGenerator {
public typealias Nonce = Data
public typealias Nonce = Bytes
public var NonceBytes: Int { return Int(crypto_secretbox_noncebytes()) }
}
extension Stream: SecretKeyGenerator {
public typealias Key = Data
public typealias Key = Bytes
public var KeyBytes: Int { return Int(crypto_secretbox_keybytes()) }
static let keygen: (_ k: UnsafeMutablePointer<UInt8>) -> Void = crypto_stream_keygen

View File

@ -5,18 +5,15 @@ public class Utils {
/**
Tries to effectively zero bytes in `data`, even if optimizations are being applied to the code.
- Parameter data: The `Data` object to zero.
- Parameter data: The `Bytes` object to zero.
*/
public func zero(_ data: inout Data) {
public func zero(_ data: inout Bytes) {
let count = data.count
data.withUnsafeMutableBytes { (dataPtr: UnsafeMutablePointer<UInt8>) in
let rawPtr = UnsafeMutableRawPointer(dataPtr)
sodium_memzero(rawPtr, count)
}
sodium_memzero(&data, count)
}
/**
Checks that two `Data` objects have the same content, without leaking information
Checks that two `Bytes` objects have the same content, without leaking information
about the actual content of these objects.
- Parameter b1: first object
@ -24,33 +21,23 @@ public class Utils {
- Returns: `true` if the bytes in `b1` match the bytes in `b2`. Otherwise, it returns false.
*/
public func equals(_ b1: Data, _ b2: Data) -> Bool {
public func equals(_ b1: Bytes, _ b2: Bytes) -> Bool {
guard b1.count == b2.count else {
return false
}
return .SUCCESS == b1.withUnsafeBytes { b1Ptr in
b2.withUnsafeBytes { b2Ptr in
sodium_memcmp(
UnsafeRawPointer(b1Ptr), UnsafeRawPointer(b2Ptr), b1.count).exitCode
}
}
return .SUCCESS == sodium_memcmp(b1, b2, b1.count).exitCode
}
/**
Compares two `Data` objects without leaking information about the content of these objects.
Compares two `Bytes` objects without leaking information about the content of these objects.
- Returns: `0` if the bytes in `b1` match the bytes in `b2`.
`-1` if `b2` is less than `b1` (considered as little-endian values) and
`1` if `b1` is less than `b2` (considered as little-endian values)
*/
public func compare(_ b1: Data, _ b2: Data) -> Int? {
public func compare(_ b1: Bytes, _ b2: Bytes) -> Int? {
guard b1.count == b2.count else { return nil }
return b1.withUnsafeBytes { b1Ptr in
b2.withUnsafeBytes { b2Ptr in
Int(sodium_compare(
b1Ptr, b2Ptr, b1.count))
}
}
return Int(sodium_compare(b1, b2, b1.count))
}
/**
@ -60,18 +47,15 @@ public class Utils {
- Returns: The encoded hexdecimal string.
*/
public func bin2hex(_ bin: Data) -> String? {
let hexDataLen = bin.count * 2 + 1
var hexData = Data(count: hexDataLen)
public func bin2hex(_ bin: Bytes) -> String? {
let hexBytesLen = bin.count * 2 + 1
var hexBytes = Bytes(count: hexBytesLen).map(Int8.init)
return hexData.withUnsafeMutableBytes { (hexPtr: UnsafeMutablePointer<Int8>) -> String? in
bin.withUnsafeBytes { (binPtr: UnsafePointer<UInt8>) -> String? in
guard sodium_bin2hex(hexPtr, hexDataLen, binPtr, bin.count) != nil else {
return nil
}
return String(validatingUTF8: hexPtr)
}
guard sodium_bin2hex(&hexBytes, hexBytesLen, bin, bin.count) != nil else {
return nil
}
return String(validatingUTF8: hexBytes)
}
/**
@ -82,28 +66,24 @@ public class Utils {
- Returns: The decoded data.
*/
public func hex2bin(_ hex: String, ignore: String? = nil) -> Data? {
guard let hexData = hex.data(using: .utf8, allowLossyConversion: false) else {
return nil
}
let hexDataLen = hexData.count
let binDataCapacity = hexDataLen / 2
var binData = Data(count: binDataCapacity)
var binDataLen: size_t = 0
public func hex2bin(_ hex: String, ignore: String? = nil) -> Bytes? {
let hexBytes = Bytes(hex.utf8)
let hexBytesLen = hexBytes.count
let binBytesCapacity = hexBytesLen / 2
var binBytes = Bytes(count: binBytesCapacity)
var binBytesLen: size_t = 0
let ignore_nsstr = ignore.flatMap({ NSString(string: $0) })
let ignore_cstr = ignore_nsstr?.cString(using: String.Encoding.isoLatin1.rawValue)
guard .SUCCESS == binData.withUnsafeMutableBytes({ binPtr in
hexData.withUnsafeBytes { hexPtr in
sodium_hex2bin(binPtr, binDataCapacity,
hexPtr, hexDataLen,
ignore_cstr, &binDataLen, nil).exitCode
}
}) else { return nil }
guard .SUCCESS == sodium_hex2bin(
&binBytes, binBytesCapacity,
hex, hexBytesLen,
ignore_cstr, &binBytesLen, nil
).exitCode else { return nil }
binData.count = Int(binDataLen)
binBytes = binBytes[..<binBytesLen].bytes
return binData
return binBytes
}
public enum Base64Variant: CInt {
@ -121,18 +101,14 @@ public class Utils {
- Returns: The encoded base64 string.
*/
public func bin2base64(_ bin: Data, variant: Base64Variant = .URLSAFE) -> String? {
let b64DataLen = sodium_base64_encoded_len(bin.count, variant.rawValue)
var b64Data = Data(count: b64DataLen)
public func bin2base64(_ bin: Bytes, variant: Base64Variant = .URLSAFE) -> String? {
let b64BytesLen = sodium_base64_encoded_len(bin.count, variant.rawValue)
var b64Bytes = Bytes(count: b64BytesLen).map(Int8.init)
return b64Data.withUnsafeMutableBytes { (b64Ptr: UnsafeMutablePointer<Int8>) -> String? in
bin.withUnsafeBytes { (binPtr: UnsafePointer<UInt8>) -> String? in
guard sodium_bin2base64(b64Ptr, b64DataLen, binPtr, bin.count, variant.rawValue) != nil else {
return nil
}
return String(validatingUTF8: b64Ptr)
}
guard sodium_bin2base64(&b64Bytes, b64BytesLen, bin, bin.count, variant.rawValue) != nil else {
return nil
}
return String(validatingUTF8: b64Bytes)
}
/*
@ -143,28 +119,26 @@ public class Utils {
- Returns: The decoded data.
*/
public func base642bin(_ b64: String, variant: Base64Variant = .URLSAFE, ignore: String? = nil) -> Data? {
guard let b64Data = b64.data(using: .utf8, allowLossyConversion: false) else {
return nil
}
let b64DataLen = b64Data.count
let binDataCapacity = b64DataLen * 3 / 4
var binData = Data(count: binDataCapacity)
var binDataLen: size_t = 0
public func base642bin(_ b64: String, variant: Base64Variant = .URLSAFE, ignore: String? = nil) -> Bytes? {
let b64Bytes = Bytes(b64.utf8).map(Int8.init)
let b64BytesLen = b64Bytes.count
let binBytesCapacity = b64BytesLen * 3 / 4
var binBytes = Bytes(count: binBytesCapacity)
var binBytesLen: size_t = 0
let ignore_nsstr = ignore.flatMap({ NSString(string: $0) })
let ignore_cstr = ignore_nsstr?.cString(using: String.Encoding.isoLatin1.rawValue)
guard .SUCCESS == binData.withUnsafeMutableBytes({ binPtr in
b64Data.withUnsafeBytes { b64Ptr in
sodium_base642bin(binPtr, binDataCapacity,
b64Ptr, b64DataLen,
ignore_cstr, &binDataLen, nil, variant.rawValue).exitCode
}
}) else { return nil }
guard .SUCCESS == sodium_base642bin(
&binBytes, binBytesCapacity,
b64Bytes, b64BytesLen,
ignore_cstr, &binBytesLen,
nil,
variant.rawValue
).exitCode else { return nil }
binData.count = Int(binDataLen)
binBytes = binBytes[..<binBytesLen].bytes
return binData
return binBytes
}
/*
@ -173,17 +147,27 @@ public class Utils {
- Parameter data: input/output buffer, will be modified in-place
- Parameter blocksize: the block size
*/
public func pad(data: inout Data, blockSize: Int) -> ()? {
public func pad(data bytes: inout Bytes, blockSize: Int) -> ()? {
// we must use Data and not Bytes because we need to increase the
// count size before passing to `sodium_pad` without initilising bytes
var data = Data(bytes)
let dataCount = data.count
data.reserveCapacity(dataCount + blockSize)
data.count = dataCount + blockSize
var paddedLen: size_t = 0
guard .SUCCESS == data.withUnsafeMutableBytes({ dataPtr in
sodium_pad(&paddedLen, dataPtr, dataCount, blockSize, dataCount + blockSize).exitCode
guard .SUCCESS == data.withUnsafeMutableBytes({
dataPtr in sodium_pad(
&paddedLen,
dataPtr, dataCount,
blockSize,
dataCount + blockSize
).exitCode
}) else { return nil }
data.count = Int(paddedLen)
data.count = paddedLen
// return the new bytes by argument
bytes = Bytes(data)
return ()
}
@ -193,14 +177,16 @@ public class Utils {
- Parameter data: input/output buffer, will be modified in-place
- Parameter blocksize: the block size
*/
public func unpad(data: inout Data, blockSize: Int) -> ()? {
public func unpad(data: inout Bytes, blockSize: Int) -> ()? {
var unpaddedLen: size_t = 0
let dataLen = data.count
guard .SUCCESS == data.withUnsafeMutableBytes({ dataPtr in
sodium_unpad(&unpaddedLen, dataPtr, dataLen, blockSize).exitCode
}) else { return nil }
guard .SUCCESS == sodium_unpad(
&unpaddedLen,
data, dataLen,
blockSize
).exitCode else { return nil }
data.count = Int(unpaddedLen)
data = data[..<unpaddedLen].bytes
return ()
}

View File

@ -31,9 +31,9 @@ class ReadmeTests : XCTestCase {
let sodium = Sodium()
let aliceKeyPair = sodium.box.keyPair()!
let bobKeyPair = sodium.box.keyPair()!
let message = "My Test Message".data(using:.utf8)!
let message = "My Test Message".bytes
let encryptedMessageFromAliceToBob: Data =
let encryptedMessageFromAliceToBob: Bytes =
sodium.box.seal(message: message,
recipientPublicKey: bobKeyPair.publicKey,
senderSecretKey: aliceKeyPair.secretKey)!
@ -49,7 +49,7 @@ class ReadmeTests : XCTestCase {
func testAnonymousEncryptionSealedBoxes() {
let sodium = Sodium()
let bobKeyPair = sodium.box.keyPair()!
let message = "My Test Message".data(using:.utf8)!
let message = "My Test Message".bytes
let encryptedMessageToBob =
sodium.box.seal(message: message, recipientPublicKey: bobKeyPair.publicKey)!
@ -81,7 +81,7 @@ class ReadmeTests : XCTestCase {
func testDetachedSignatures() {
let sodium = Sodium()
let message = "My Test Message".data(using:.utf8)!
let message = "My Test Message".bytes
let keyPair = sodium.sign.keyPair()!
let signature = sodium.sign.signature(message: message, secretKey: keyPair.secretKey)!
if sodium.sign.verify(message: message,
@ -93,7 +93,7 @@ class ReadmeTests : XCTestCase {
func testAttachedSignatures() {
let sodium = Sodium()
let message = "My Test Message".data(using:.utf8)!
let message = "My Test Message".bytes
let keyPair = sodium.sign.keyPair()!
let signedMessage = sodium.sign.sign(message: message, secretKey: keyPair.secretKey)!
if sodium.sign.open(signedMessage: signedMessage, publicKey: keyPair.publicKey) != nil {
@ -103,9 +103,9 @@ class ReadmeTests : XCTestCase {
func testSecretKeyAuthenticatedEncryption() {
let sodium = Sodium()
let message = "My Test Message".data(using:.utf8)!
let message = "My Test Message".bytes
let secretKey = sodium.secretBox.key()
let encrypted: Data = sodium.secretBox.seal(message: message, secretKey: secretKey)!
let encrypted: Bytes = sodium.secretBox.seal(message: message, secretKey: secretKey)!
if sodium.secretBox.open(nonceAndAuthenticatedCipherText: encrypted, secretKey: secretKey) != nil {
// authenticator is valid, decrypted contains the original message
}
@ -113,7 +113,7 @@ class ReadmeTests : XCTestCase {
func testDeterministicHashing() {
let sodium = Sodium()
let message = "My Test Message".data(using:.utf8)!
let message = "My Test Message".bytes
let h = sodium.genericHash.hash(message: message)
XCTAssertNotNil(h)
@ -121,8 +121,8 @@ class ReadmeTests : XCTestCase {
func testKeyedHashing() {
let sodium = Sodium()
let message = "My Test Message".data(using:.utf8)!
let key = "Secret key".data(using:.utf8)!
let message = "My Test Message".bytes
let key = "Secret key".bytes
let h = sodium.genericHash.hash(message: message, key: key)
XCTAssertNotNil(h)
@ -130,9 +130,9 @@ class ReadmeTests : XCTestCase {
func testStreaming() {
let sodium = Sodium()
let message1 = "My Test ".data(using:.utf8)!
let message2 = "Message".data(using:.utf8)!
let key = "Secret key".data(using:.utf8)!
let message1 = "My Test ".bytes
let message2 = "Message".bytes
let key = "Secret key".bytes
let stream = sodium.genericHash.initStream(key: key)!
let _ = stream.update(input: message1)
let _ = stream.update(input: message2)
@ -143,7 +143,7 @@ class ReadmeTests : XCTestCase {
func testShortOutputHashing() {
let sodium = Sodium()
let message = "My Test Message".data(using:.utf8)!
let message = "My Test Message".bytes
let key = sodium.randomBytes.buf(length: sodium.shortHash.KeyBytes)!
let h = sodium.shortHash.hash(message: message, key: key)
@ -159,7 +159,7 @@ class ReadmeTests : XCTestCase {
func testPasswordHashing() {
let sodium = Sodium()
let password = "Correct Horse Battery Staple".data(using:.utf8)!
let password = "Correct Horse Battery Staple".bytes
let hashedStr = sodium.pwHash.str(passwd: password,
opsLimit: sodium.pwHash.OpsLimitInteractive,
memLimit: sodium.pwHash.MemLimitInteractive)!
@ -180,14 +180,14 @@ class ReadmeTests : XCTestCase {
func testZeroingMemory() {
let sodium = Sodium()
var dataToZero = "Message".data(using:.utf8)!
var dataToZero = "Message".bytes
sodium.utils.zero(&dataToZero)
}
func testConstantTimeComparison() {
let sodium = Sodium()
let secret1 = "Secret key".data(using:.utf8)!
let secret2 = "Secret key".data(using:.utf8)!
let secret1 = "Secret key".bytes
let secret2 = "Secret key".bytes
let equality = sodium.utils.equals(secret1, secret2)
XCTAssertTrue(equality)
@ -195,7 +195,7 @@ class ReadmeTests : XCTestCase {
func testConstantTimeHexdecimalEncoding() {
let sodium = Sodium()
let data = "Secret key".data(using:.utf8)!
let data = "Secret key".bytes
let hex = sodium.utils.bin2hex(data)
XCTAssertNotNil(hex)
@ -212,7 +212,7 @@ class ReadmeTests : XCTestCase {
func testStream() {
let sodium = Sodium()
let input = "test".data(using:.utf8)!
let input = "test".bytes
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)!
@ -222,7 +222,7 @@ class ReadmeTests : XCTestCase {
func testAuth() {
let sodium = Sodium()
let input = "test".data(using:.utf8)!
let input = "test".bytes
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)
@ -245,9 +245,9 @@ class ReadmeTests : XCTestCase {
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 message1 = "Message 1".bytes
let message2 = "Message 2".bytes
let message3 = "Message 3".bytes
let secretkey = sodium.secretStream.xchacha20poly1305.key()
@ -276,21 +276,21 @@ class ReadmeTests : XCTestCase {
func testBase64() {
let sodium = Sodium()
let b64 = sodium.utils.bin2base64("data".toData()!)!
let b64_2 = sodium.utils.bin2base64("data".toData()!, variant: .URLSAFE_NO_PADDING)!
let b64 = sodium.utils.bin2base64("data".bytes)!
let b64_2 = sodium.utils.bin2base64("data".bytes, variant: .URLSAFE_NO_PADDING)!
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())
XCTAssertEqual(data1, "data".bytes)
XCTAssertEqual(data2, "data".bytes)
XCTAssertEqual(data3, "data".bytes)
}
func testPadding() {
let sodium = Sodium()
var data = "test".toData()!
var data = "test".bytes
// make data.count a multiple of 16
sodium.utils.pad(data: &data, blockSize: 16)!

View File

@ -49,28 +49,28 @@ class SodiumTests: XCTestCase {
}
func testBox() {
let message = "My Test Message".toData()!
let message = "My Test Message".bytes
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 encryptedMessageFromAliceToBob: Bytes = 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 (encryptedMessageFromAliceToBob2, nonce): (Bytes, 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 (encryptedMessageFromAliceToBob3, nonce2, mac): (Bytes, 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 encryptedMessageFromAliceToBob4: Bytes = 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 encryptedMessageToBob: Bytes = sodium.box.seal(message: message, recipientPublicKey: bobKeyPair.publicKey)!
let decrypted5 = sodium.box.open(anonymousCipherText: encryptedMessageToBob, recipientPublicKey: bobKeyPair.publicKey,
recipientSecretKey: bobKeyPair.secretKey)
XCTAssertEqual(decrypted5, message)
@ -82,21 +82,21 @@ class SodiumTests: XCTestCase {
XCTAssertEqual(aliceBeforenm, bobBeforenm)
// Make sure the encryption using beforenm works
let encryptedMessageBeforenm: Data = sodium.box.seal(message: message, beforenm: aliceBeforenm)!
let encryptedMessageBeforenm: Bytes = 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 (encryptedMessageBeforenm2, nonceBeforenm): (Bytes, 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 message = "My Test Message".bytes
let secretKey = sodium.secretBox.key()
// test simple nonce + mac + message box
let encrypted: Data = sodium.secretBox.seal(message: message, secretKey: secretKey)!
let encrypted: Bytes = sodium.secretBox.seal(message: message, secretKey: secretKey)!
let decrypted = sodium.secretBox.open(nonceAndAuthenticatedCipherText: encrypted, secretKey: secretKey)!
XCTAssertEqual(decrypted, message)
@ -122,7 +122,7 @@ class SodiumTests: XCTestCase {
}
func testGenericHash() {
let message = "My Test Message".toData()!
let message = "My Test Message".bytes
let h1 = sodium.utils.bin2hex(sodium.genericHash.hash(message: message)!)!
XCTAssertEqual(h1, "64a9026fca646c31df54426ad15a341e2444d8a1863d57eb27abecf239609f75")
@ -181,14 +181,14 @@ class SodiumTests: XCTestCase {
}
func testShortHash() {
let message = "My Test Message".toData()!
let message = "My Test Message".bytes
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 message = "My Test Message".bytes
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")
@ -204,18 +204,18 @@ class SodiumTests: XCTestCase {
}
func testUtils() {
var dataToZero = Data(bytes: [1, 2, 3, 4] as [UInt8])
var dataToZero = [1, 2, 3, 4] as [UInt8]
sodium.utils.zero(&dataToZero)
XCTAssert(dataToZero == Data(bytes: [0, 0, 0, 0] as [UInt8]))
XCTAssert(dataToZero == [0, 0, 0, 0] as [UInt8])
var dataToZero2 = Data(bytes: [1, 2, 3, 4] as [UInt8])
var dataToZero2 = [1, 2, 3, 4] as [UInt8]
sodium.utils.zero(&dataToZero2)
XCTAssert(dataToZero2 == Data(bytes: [0, 0, 0, 0,] as [UInt8]))
XCTAssert(dataToZero2 == [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])
let eq1 = [1, 2, 3, 4] as [UInt8]
let eq2 = [1, 2, 3, 4] as [UInt8]
let eq3 = [1, 2, 3, 5] as [UInt8]
let eq4 = [1, 2, 3] as [UInt8]
XCTAssertTrue(sodium.utils.equals(eq1, eq2))
XCTAssertFalse(sodium.utils.equals(eq1, eq3))
@ -244,8 +244,8 @@ class SodiumTests: XCTestCase {
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 password3 = "My Test Message".bytes
let salt = [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!)!, "cc80dee6a19da46ed6ea11507dd709ce52519ddd1fd2d823ce85b9e9b4fd96d06583de2ca8bcc5998f3483a8a424c4e93ddb500968b0dbefb667d56d421d5a6c")
@ -342,9 +342,9 @@ class SodiumTests: XCTestCase {
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 encrypted1 = stream.push(message: "message 1".bytes)!
let encrypted2 = stream.push(message: "message 2".bytes)!
let encrypted3 = stream.push(message: "message 3".bytes, tag: .FINAL)!
let stream2 = sodium.secretStream.xchacha20poly1305.initPull(secretKey: secretKey, header: header)!
let (message1, tag1) = stream2.pull(cipherText: encrypted1)!
@ -353,14 +353,14 @@ class SodiumTests: XCTestCase {
XCTAssertEqual(tag1, .MESSAGE)
XCTAssertEqual(tag2, .MESSAGE)
XCTAssertEqual(tag3, .FINAL)
XCTAssertEqual(message1, "message 1".toData()!)
XCTAssertEqual(message2, "message 2".toData()!)
XCTAssertEqual(message3, "message 3".toData()!)
XCTAssertEqual(message1, "message 1".bytes)
XCTAssertEqual(message2, "message 2".bytes)
XCTAssertEqual(message3, "message 3".bytes)
XCTAssertNil(stream2.pull(cipherText: encrypted3))
}
func testBase64() {
let bin = "test".toData()!
let bin = "test".bytes
let b64 = sodium.utils.bin2base64(bin)!
let bin2 = sodium.utils.base642bin(b64)!
XCTAssertEqual(b64, "dGVzdA==")
@ -373,7 +373,7 @@ class SodiumTests: XCTestCase {
}
func testPad() {
var data = "test".toData()!
var data = "test".bytes
sodium.utils.pad(data: &data, blockSize: 16)!
XCTAssertTrue(data.count % 16 == 0)
sodium.utils.unpad(data: &data, blockSize: 16)!
@ -381,8 +381,8 @@ class SodiumTests: XCTestCase {
}
func testAead() {
let message = " I am message".toData()!
let additionalData = "I am additionalData".toData()!
let message = " I am message".bytes
let additionalData = "I am additionalData".bytes
let secretKey = sodium.aead.xchacha20poly1305ietf.key()
XCTAssertEqual(secretKey.count, 32)
@ -391,12 +391,12 @@ class SodiumTests: XCTestCase {
XCTAssertEqual(nonce.count, 24) // check nonce is 192 bit
let decrypted: Data = sodium.aead.xchacha20poly1305ietf.decrypt(authenticatedCipherText: authenticatedCipherText, secretKey: secretKey, nonce: nonce)!
let decrypted: Bytes = sodium.aead.xchacha20poly1305ietf.decrypt(authenticatedCipherText: authenticatedCipherText, secretKey: secretKey, nonce: nonce)!
XCTAssertTrue(decrypted == message)
let (authenticatedCipherTextWithAdditionalData, nonceWithAdditionlData) = sodium.aead.xchacha20poly1305ietf.encrypt(message: message, secretKey: secretKey, additionalData: additionalData)!
let decrypted2: Data = sodium.aead.xchacha20poly1305ietf.decrypt(authenticatedCipherText: authenticatedCipherTextWithAdditionalData, secretKey: secretKey, nonce: nonceWithAdditionlData, additionalData: additionalData)!
let decrypted2: Bytes = sodium.aead.xchacha20poly1305ietf.decrypt(authenticatedCipherText: authenticatedCipherTextWithAdditionalData, secretKey: secretKey, nonce: nonceWithAdditionlData, additionalData: additionalData)!
XCTAssertTrue(decrypted2 == message)
@ -405,26 +405,26 @@ class SodiumTests: XCTestCase {
XCTAssertNil(sodium.aead.xchacha20poly1305ietf.decrypt(authenticatedCipherText: authenticatedCipherText, secretKey: sodium.aead.xchacha20poly1305ietf.key(), nonce: nonce), "Decrypt with different key")
XCTAssertNil(sodium.aead.xchacha20poly1305ietf.decrypt(authenticatedCipherText: authenticatedCipherTextWithAdditionalData, secretKey: secretKey, nonce: nonceWithAdditionlData, additionalData: "wrong".toData()!), "Decrypt with wrong additional data")
XCTAssertNil(sodium.aead.xchacha20poly1305ietf.decrypt(authenticatedCipherText: "wrong".toData()!, secretKey: secretKey, nonce: nonce))
XCTAssertNil(sodium.aead.xchacha20poly1305ietf.decrypt(authenticatedCipherText: authenticatedCipherTextWithAdditionalData, secretKey: secretKey, nonce: nonceWithAdditionlData, additionalData: "wrong".bytes), "Decrypt with wrong additional data")
XCTAssertNil(sodium.aead.xchacha20poly1305ietf.decrypt(authenticatedCipherText: "wrong".bytes, secretKey: secretKey, nonce: nonce))
XCTAssertNil(sodium.aead.xchacha20poly1305ietf.decrypt(authenticatedCipherText: authenticatedCipherText, secretKey: secretKey, nonce: "invalid".toData()!))
XCTAssertNil(sodium.aead.xchacha20poly1305ietf.decrypt(authenticatedCipherText: authenticatedCipherText, secretKey: "invalid".toData()!, nonce: nonce))
XCTAssertNil(sodium.aead.xchacha20poly1305ietf.decrypt(authenticatedCipherText: authenticatedCipherText, secretKey: secretKey, nonce: "invalid".bytes))
XCTAssertNil(sodium.aead.xchacha20poly1305ietf.decrypt(authenticatedCipherText: authenticatedCipherText, secretKey: "invalid".bytes, nonce: nonce))
let nonceAndAuthenticatedCipherText: Data = sodium.aead.xchacha20poly1305ietf.encrypt(message: message, secretKey: secretKey)!
let decrypted3: Data = sodium.aead.xchacha20poly1305ietf.decrypt(nonceAndAuthenticatedCipherText: nonceAndAuthenticatedCipherText, secretKey: secretKey)!
let nonceAndAuthenticatedCipherText: Bytes = sodium.aead.xchacha20poly1305ietf.encrypt(message: message, secretKey: secretKey)!
let decrypted3: Bytes = sodium.aead.xchacha20poly1305ietf.decrypt(nonceAndAuthenticatedCipherText: nonceAndAuthenticatedCipherText, secretKey: secretKey)!
XCTAssertTrue(decrypted3 == message)
let nonceAndAuthenticatedCipherTextWithAddData: Data = sodium.aead.xchacha20poly1305ietf.encrypt(message: message, secretKey: secretKey, additionalData: additionalData)!
let decrypted4: Data = sodium.aead.xchacha20poly1305ietf.decrypt(nonceAndAuthenticatedCipherText: nonceAndAuthenticatedCipherTextWithAddData, secretKey: secretKey, additionalData: additionalData)!
let nonceAndAuthenticatedCipherTextWithAddData: Bytes = sodium.aead.xchacha20poly1305ietf.encrypt(message: message, secretKey: secretKey, additionalData: additionalData)!
let decrypted4: Bytes = sodium.aead.xchacha20poly1305ietf.decrypt(nonceAndAuthenticatedCipherText: nonceAndAuthenticatedCipherTextWithAddData, secretKey: secretKey, additionalData: additionalData)!
XCTAssertTrue(decrypted4 == message)
// encrypt -> decrypt empty message
let emptyMessage = "".toData()!
let encryptedEmpty: Data = sodium.aead.xchacha20poly1305ietf.encrypt(message: emptyMessage, secretKey: secretKey, additionalData: additionalData)!
let decryptedEmpty: Data = sodium.aead.xchacha20poly1305ietf.decrypt(nonceAndAuthenticatedCipherText: encryptedEmpty, secretKey: secretKey, additionalData: additionalData)!
let emptyMessage = "".bytes
let encryptedEmpty: Bytes = sodium.aead.xchacha20poly1305ietf.encrypt(message: emptyMessage, secretKey: secretKey, additionalData: additionalData)!
let decryptedEmpty: Bytes = sodium.aead.xchacha20poly1305ietf.decrypt(nonceAndAuthenticatedCipherText: encryptedEmpty, secretKey: secretKey, additionalData: additionalData)!
XCTAssertTrue(decryptedEmpty == emptyMessage)
}