|  |  |  | // Copyright © 2023 Rangeproof Pty Ltd. All rights reserved. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // stringlint:disable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import Foundation | 
					
						
							|  |  |  | import Sodium | 
					
						
							|  |  |  | import Clibsodium | 
					
						
							|  |  |  | import Curve25519Kit | 
					
						
							|  |  |  | import SessionUtilitiesKit | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // MARK: - Generic Hash | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public extension Crypto.Action { | 
					
						
							|  |  |  |     static func hash(message: Bytes, key: Bytes?) -> Crypto.Action { | 
					
						
							|  |  |  |         return Crypto.Action(id: "hash", args: [message, key]) { | 
					
						
							|  |  |  |             Sodium().genericHash.hash(message: message, key: key) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     static func hash(message: Bytes, outputLength: Int) -> Crypto.Action { | 
					
						
							|  |  |  |         return Crypto.Action(id: "hashOutputLength", args: [message, outputLength]) { | 
					
						
							|  |  |  |             Sodium().genericHash.hash(message: message, outputLength: outputLength) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     static func hashSaltPersonal( | 
					
						
							|  |  |  |         message: Bytes, | 
					
						
							|  |  |  |         outputLength: Int, | 
					
						
							|  |  |  |         key: Bytes? = nil, | 
					
						
							|  |  |  |         salt: Bytes, | 
					
						
							|  |  |  |         personal: Bytes | 
					
						
							|  |  |  |     ) -> Crypto.Action { | 
					
						
							|  |  |  |         return Crypto.Action( | 
					
						
							|  |  |  |             id: "hashSaltPersonal", | 
					
						
							|  |  |  |             args: [message, outputLength, key, salt, personal] | 
					
						
							|  |  |  |         ) { | 
					
						
							|  |  |  |             var output: [UInt8] = [UInt8](repeating: 0, count: outputLength) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             let result = crypto_generichash_blake2b_salt_personal( | 
					
						
							|  |  |  |                 &output, | 
					
						
							|  |  |  |                 outputLength, | 
					
						
							|  |  |  |                 message, | 
					
						
							|  |  |  |                 UInt64(message.count), | 
					
						
							|  |  |  |                 key, | 
					
						
							|  |  |  |                 (key?.count ?? 0), | 
					
						
							|  |  |  |                 salt, | 
					
						
							|  |  |  |                 personal | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             guard result == 0 else { return nil } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return output | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // MARK: - Sign | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public extension Crypto.Action { | 
					
						
							|  |  |  |     static func toX25519(ed25519PublicKey: Bytes) -> Crypto.Action { | 
					
						
							|  |  |  |         return Crypto.Action(id: "toX25519", args: [ed25519PublicKey]) { | 
					
						
							|  |  |  |             Sodium().sign.toX25519(ed25519PublicKey: ed25519PublicKey) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     static func toX25519(ed25519SecretKey: Bytes) -> Crypto.Action { | 
					
						
							|  |  |  |         return Crypto.Action(id: "toX25519", args: [ed25519SecretKey]) { | 
					
						
							|  |  |  |             Sodium().sign.toX25519(ed25519SecretKey: ed25519SecretKey) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     static func signature(message: Bytes, secretKey: Bytes) -> Crypto.Action { | 
					
						
							|  |  |  |         return Crypto.Action(id: "signature", args: [message, secretKey]) { | 
					
						
							|  |  |  |             Sodium().sign.signature(message: message, secretKey: secretKey) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public extension Crypto.Verification { | 
					
						
							|  |  |  |     static func signature(message: Bytes, publicKey: Bytes, signature: Bytes) -> Crypto.Verification { | 
					
						
							|  |  |  |         return Crypto.Verification(id: "signature", args: [message, publicKey, signature]) { | 
					
						
							|  |  |  |             Sodium().sign.verify(message: message, publicKey: publicKey, signature: signature) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // MARK: - Box | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public extension Crypto.Size { | 
					
						
							|  |  |  |     static let signature: Crypto.Size = Crypto.Size(id: "signature") { Sodium().sign.Bytes } | 
					
						
							|  |  |  |     static let publicKey: Crypto.Size = Crypto.Size(id: "publicKey") { Sodium().sign.PublicKeyBytes } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public extension Crypto.Action { | 
					
						
							|  |  |  |     static func seal(message: Bytes, recipientPublicKey: Bytes) -> Crypto.Action { | 
					
						
							|  |  |  |         return Crypto.Action(id: "seal", args: [message, recipientPublicKey]) { | 
					
						
							|  |  |  |             Sodium().box.seal(message: message, recipientPublicKey: recipientPublicKey) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     static func open(anonymousCipherText: Bytes, recipientPublicKey: Bytes, recipientSecretKey: Bytes) -> Crypto.Action { | 
					
						
							|  |  |  |         return Crypto.Action( | 
					
						
							|  |  |  |             id: "open", | 
					
						
							|  |  |  |             args: [anonymousCipherText, recipientPublicKey, recipientSecretKey] | 
					
						
							|  |  |  |         ) { | 
					
						
							|  |  |  |             Sodium().box.open( | 
					
						
							|  |  |  |                 anonymousCipherText: anonymousCipherText, | 
					
						
							|  |  |  |                 recipientPublicKey: recipientPublicKey, | 
					
						
							|  |  |  |                 recipientSecretKey: recipientSecretKey | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // MARK: - AeadXChaCha20Poly1305Ietf | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public extension Crypto.Size { | 
					
						
							|  |  |  |     static let aeadXChaCha20NonceBytes: Crypto.Size = Crypto.Size(id: "aeadXChaCha20NonceBytes") { | 
					
						
							|  |  |  |         Sodium().aead.xchacha20poly1305ietf.NonceBytes | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // MARK: - Ed25519 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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)) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |