You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-ios/SessionUtilitiesKit/Crypto/Crypto+SessionUtilitiesKit....

221 lines
7.8 KiB
Swift

// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import SessionUtil
// MARK: - Randomness
public extension Crypto.Generator {
static func uuid() -> Crypto.Generator<UUID> {
return Crypto.Generator(id: "uuid") { UUID() }
}
static func randomBytes(_ count: Int) -> Crypto.Generator<Data> {
return Crypto.Generator(id: "randomBytes_Data", args: [count]) { () -> Data in
Data(bytes: session_random(count), count: count)
}
}
static func randomBytes(_ count: Int) -> Crypto.Generator<[UInt8]> {
return Crypto.Generator(id: "randomBytes_[UInt8]", args: [count]) { () -> [UInt8] in
Array(Data(bytes: session_random(count), count: count))
}
}
}
// MARK: - Hash
public extension Crypto.Generator {
static func hash(message: [UInt8], key: [UInt8]? = nil, length: Int = 32) -> Crypto.Generator<[UInt8]> {
return Crypto.Generator(id: "hash", args: [message, key]) {
var cMessage: [UInt8] = message
var cHash: [UInt8] = [UInt8](repeating: 0, count: length)
switch key {
case .some(let finalKey):
var cKey: [UInt8] = finalKey
guard session_hash(length, &cMessage, cMessage.count, &cKey, cKey.count, &cHash) else {
throw CryptoError.failedToGenerateOutput
}
case .none:
guard session_hash(length, &cMessage, cMessage.count, nil, 0, &cHash) else {
throw CryptoError.failedToGenerateOutput
}
}
return cHash
}
}
}
// MARK: - curve25519
public extension Crypto.Generator {
static func x25519KeyPair() -> Crypto.Generator<KeyPair> {
return Crypto.Generator<KeyPair>(id: "x25519KeyPair") { () -> KeyPair in
var pubkey: [UInt8] = [UInt8](repeating: 0, count: 32)
var seckey: [UInt8] = [UInt8](repeating: 0, count: 32)
guard session_curve25519_key_pair(&pubkey, &seckey) else { throw CryptoError.keyGenerationFailed }
return KeyPair(publicKey: pubkey, secretKey: seckey)
}
}
static func x25519(
ed25519Pubkey: [UInt8]
) -> Crypto.Generator<[UInt8]> {
return Crypto.Generator(
id: "ed25519Pubkey_to_x25519Pubkey",
args: [ed25519Pubkey]
) {
var cEd25519Pubkey: [UInt8] = ed25519Pubkey
var pubkey: [UInt8] = [UInt8](repeating: 0, count: 32)
guard
cEd25519Pubkey.count == 32,
session_to_curve25519_pubkey(&cEd25519Pubkey, &pubkey)
else { throw CryptoError.keyGenerationFailed }
return pubkey
}
}
static func x25519(
ed25519Seckey: [UInt8]
) -> Crypto.Generator<[UInt8]> {
return Crypto.Generator(
id: "ed25519Seckey_to_x25519Seckey",
args: [ed25519Seckey]
) {
var cEd25519SecretKey: [UInt8] = ed25519Seckey
var seckey: [UInt8] = [UInt8](repeating: 0, count: 32)
guard
cEd25519SecretKey.count == 64,
session_to_curve25519_seckey(&cEd25519SecretKey, &seckey)
else { throw CryptoError.keyGenerationFailed }
return seckey
}
}
}
// MARK: - Ed25519
public extension Crypto.Generator {
static func ed25519KeyPair() -> Crypto.Generator<KeyPair> {
return Crypto.Generator(id: "ed25519KeyPair") {
var pubkey: [UInt8] = [UInt8](repeating: 0, count: 32)
var seckey: [UInt8] = [UInt8](repeating: 0, count: 64)
guard session_ed25519_key_pair(&pubkey, &seckey) else { throw CryptoError.keyGenerationFailed }
return KeyPair(publicKey: pubkey, secretKey: seckey)
}
}
static func ed25519KeyPair(seed: [UInt8]) -> Crypto.Generator<KeyPair> {
return Crypto.Generator(id: "ed25519KeyPair_Seed", args: [seed]) {
var cSeed: [UInt8] = seed
var pubkey: [UInt8] = [UInt8](repeating: 0, count: 32)
var seckey: [UInt8] = [UInt8](repeating: 0, count: 64)
guard
cSeed.count == 32,
session_ed25519_key_pair_seed(&cSeed, &pubkey, &seckey)
else { throw CryptoError.invalidSeed }
return KeyPair(publicKey: pubkey, secretKey: seckey)
}
}
static func ed25519Seed(ed25519SecretKey: [UInt8]) -> Crypto.Generator<Data> {
return Crypto.Generator(id: "ed25519Seed", args: [ed25519SecretKey]) {
var cEd25519SecretKey: [UInt8] = ed25519SecretKey
var seed: [UInt8] = [UInt8](repeating: 0, count: 32)
guard
cEd25519SecretKey.count == 64,
session_seed_for_ed_privkey(&cEd25519SecretKey, &seed)
else { throw CryptoError.invalidSeed }
return Data(seed)
}
}
static func signature(message: [UInt8], ed25519SecretKey: [UInt8]) -> Crypto.Generator<[UInt8]> {
return Crypto.Generator(id: "signature", args: [message, ed25519SecretKey]) {
var cEd25519SecretKey: [UInt8] = ed25519SecretKey
var cMessage: [UInt8] = message
var cSignature: [UInt8] = [UInt8](repeating: 0, count: 64)
guard
cEd25519SecretKey.count == 64,
session_ed25519_sign(&cEd25519SecretKey, &cMessage, cMessage.count, &cSignature)
else { throw CryptoError.signatureGenerationFailed }
return cSignature
}
}
}
public extension Crypto.Verification {
static func signature(message: [UInt8], publicKey: [UInt8], signature: [UInt8]) -> Crypto.Verification {
return Crypto.Verification(id: "signature", args: [message, publicKey, signature]) {
var cSignature: [UInt8] = signature
var cPublicKey: [UInt8] = publicKey
var cMessage: [UInt8] = message
return session_ed25519_verify(
&cSignature,
&cPublicKey,
&cMessage,
cMessage.count
)
}
}
}
// MARK: - Xed25519
public extension Crypto.Generator {
static func signatureXed25519(data: [UInt8], curve25519PrivateKey: [UInt8]) -> Crypto.Generator<[UInt8]> {
return Crypto.Generator(id: "signatureXed25519", args: [data, curve25519PrivateKey]) {
var cSignature: [UInt8] = [UInt8](repeating: 0, count: 64)
var cCurve25519PrivateKey: [UInt8] = curve25519PrivateKey
var cData: [UInt8] = data
guard
cCurve25519PrivateKey.count == 32,
session_xed25519_sign(
&cSignature,
&cCurve25519PrivateKey,
&cData,
cData.count
)
else { throw CryptoError.signatureGenerationFailed }
return cSignature
}
}
}
public extension Crypto.Verification {
static func signatureXed25519(_ signature: Data, curve25519PublicKey: [UInt8], data: Data) -> Crypto.Verification {
return Crypto.Verification(id: "signatureXed25519", args: [signature, curve25519PublicKey, data]) {
var cSignature: [UInt8] = Array(signature)
var cCurve25519PublicKey: [UInt8] = curve25519PublicKey
var cData: [UInt8] = Array(data)
return session_xed25519_verify(
&cSignature,
&cCurve25519PublicKey,
&cData,
cData.count
)
}
}
}