Defer to Swift's own handling for most pointers
Reference: https://developer.apple.com/swift/blog/?id=6
This commit is contained in:
parent
af892c0f75
commit
48b08e47f0
|
@ -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 */,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
287
Sodium/Box.swift
287
Sodium/Box.swift
|
@ -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()) }
|
||||
}
|
||||
|
|
|
@ -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) }
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()) }
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()) }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ()
|
||||
}
|
||||
|
|
|
@ -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)!
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue