79 lines
2.5 KiB
Swift
79 lines
2.5 KiB
Swift
/**
|
|
* Author: Hugo Pointcheval
|
|
* Email: git@pcl.ovh
|
|
* -----
|
|
* File: KEM.swift
|
|
* Created Date: 25/12/2021 18:31:48
|
|
* Last Modified: 25/12/2021 18:40:00
|
|
* -----
|
|
* Copyright (c) 2021
|
|
*/
|
|
|
|
import Foundation
|
|
import CryptoKit
|
|
|
|
class KeyPair {
|
|
/// Generate a keypair.
|
|
@available(iOS 13.0, *)
|
|
static func fromCurve() -> Data {
|
|
let sk = P256.KeyAgreement.PrivateKey()
|
|
var kp = sk.rawRepresentation
|
|
kp.append(contentsOf: sk.publicKey.rawRepresentation)
|
|
return kp;
|
|
}
|
|
|
|
/// Import private key from Data
|
|
@available(iOS 13.0, *)
|
|
static func importPrivateKey(privateKey: Data) throws -> P256.KeyAgreement.PrivateKey {
|
|
let sk = try P256.KeyAgreement.PrivateKey(rawRepresentation: privateKey)
|
|
|
|
return sk;
|
|
}
|
|
|
|
/// Import public key from Data
|
|
@available(iOS 13.0, *)
|
|
static func importPublicKey(publicKey: Data) throws -> P256.KeyAgreement.PublicKey {
|
|
let pk = try P256.KeyAgreement.PublicKey(rawRepresentation: publicKey)
|
|
|
|
return pk;
|
|
}
|
|
}
|
|
|
|
class ECDH {
|
|
/// Generate a shared secret with your private key and other party public key.
|
|
@available(iOS 13.0, *)
|
|
static func generateSharedSecretKey(salt: Data, hash: HashAlgorithm, keyBytesCount: Int ,privateKey: Data, publicKey: Data) -> Data? {
|
|
let sk = try? KeyPair.importPrivateKey(privateKey: privateKey)
|
|
if (sk == nil) {return nil}
|
|
|
|
let pk = try? KeyPair.importPublicKey(publicKey: publicKey)
|
|
if (pk == nil) {return nil}
|
|
|
|
let secret = try? sk!.sharedSecretFromKeyAgreement(with: pk!)
|
|
|
|
switch hash {
|
|
case .HashSHA256:
|
|
let key = secret?.hkdfDerivedSymmetricKey(using: SHA256.self, salt: salt, sharedInfo: Data(), outputByteCount: keyBytesCount)
|
|
if (key == nil) {
|
|
return nil
|
|
} else {
|
|
return Key.toBytes(key: key!)
|
|
}
|
|
case .HashSHA384:
|
|
let key = secret?.hkdfDerivedSymmetricKey(using: SHA384.self, salt: salt, sharedInfo: Data(), outputByteCount: keyBytesCount)
|
|
if (key == nil) {
|
|
return nil
|
|
} else {
|
|
return Key.toBytes(key: key!)
|
|
}
|
|
case .HashSHA512:
|
|
let key = secret?.hkdfDerivedSymmetricKey(using: SHA512.self, salt: salt, sharedInfo: Data(), outputByteCount: keyBytesCount)
|
|
if (key == nil) {
|
|
return nil
|
|
} else {
|
|
return Key.toBytes(key: key!)
|
|
}
|
|
}
|
|
}
|
|
}
|