session-ios/SessionUtilitiesKit/Crypto/Crypto+SessionUtilitiesKit....

85 lines
3.0 KiB
Swift

// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import Sodium
import Clibsodium
import Curve25519Kit
// MARK: - Box
public extension Crypto.Size {
static let publicKey: Crypto.Size = Crypto.Size(id: "publicKey") { $0.sign.PublicKeyBytes }
static let secretKey: Crypto.Size = Crypto.Size(id: "secretKey") { $0.sign.SecretKeyBytes }
}
// MARK: - Sign
public extension Crypto.Action {
static func toX25519(ed25519PublicKey: Bytes) -> Crypto.Action {
return Crypto.Action(id: "toX25519", args: [ed25519PublicKey]) { sodium in
sodium.sign.toX25519(ed25519PublicKey: ed25519PublicKey)
}
}
static func toX25519(ed25519SecretKey: Bytes) -> Crypto.Action {
return Crypto.Action(id: "toX25519", args: [ed25519SecretKey]) { sodium in
sodium.sign.toX25519(ed25519SecretKey: ed25519SecretKey)
}
}
}
// MARK: - Ed25519
public extension Crypto.KeyPairType {
static func x25519KeyPair() -> Crypto.KeyPairType {
return Crypto.KeyPairType(id: "x25519KeyPair") {
let keyPair: ECKeyPair = Curve25519.generateKeyPair()
return KeyPair(publicKey: Array(keyPair.publicKey), secretKey: Array(keyPair.privateKey))
}
}
static func ed25519KeyPair(
seed: Data? = nil,
using dependencies: Dependencies = Dependencies()
) -> Crypto.KeyPairType {
return Crypto.KeyPairType(id: "ed25519KeyPair") {
let pkSize: Int = dependencies[singleton: .crypto].size(.publicKey)
let skSize: Int = dependencies[singleton: .crypto].size(.secretKey)
var edPK: [UInt8] = [UInt8](repeating: 0, count: pkSize)
var edSK: [UInt8] = [UInt8](repeating: 0, count: skSize)
var targetSeed: [UInt8] = ((seed ?? (try? Randomness.generateRandomBytes(numberBytes: skSize)))
.map { Array($0) })
.defaulting(to: [])
// Generate the key
guard Sodium.lib_crypto_sign_ed25519_seed_keypair(&edPK, &edSK, &targetSeed) == 0 else {
return nil
}
return KeyPair(publicKey: edPK, secretKey: edSK)
}
}
}
public extension Crypto.Action {
static func signEd25519(data: Bytes, keyPair: KeyPair) -> Crypto.Action {
return Crypto.Action(id: "signEd25519", args: [data, keyPair]) {
let ecKeyPair: ECKeyPair = try ECKeyPair(
publicKeyData: Data(keyPair.publicKey),
privateKeyData: Data(keyPair.secretKey)
)
return try Ed25519.sign(Data(data), with: ecKeyPair).bytes
}
}
}
public extension Crypto.Verification {
static func signatureEd25519(_ signature: Data, publicKey: Data, data: Data) -> Crypto.Verification {
return Crypto.Verification(id: "signatureEd25519", args: [signature, publicKey, data]) {
return ((try? Ed25519.verifySignature(signature, publicKey: publicKey, data: data)) == true)
}
}
}