LibCrypto: Implement key generation for ML-KEM algorithms

This commit is contained in:
Tete17
2025-11-28 20:07:09 +01:00
committed by Shannon Booth
parent cabcf3ed66
commit 92fdc97d98
3 changed files with 127 additions and 0 deletions

View File

@@ -22,6 +22,7 @@ set(SOURCES
Hash/SHA3.cpp
PK/EC.cpp
PK/MLDSA.cpp
PK/MLKEM.cpp
PK/RSA.cpp
SecureRandom.cpp
)

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2025, Miguel Sacristán Izcue <miguel_tete17@hotmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibCrypto/PK/MLKEM.h>
#include <LibCrypto/OpenSSL.h>
#include <openssl/core_names.h>
#include <openssl/evp.h>
namespace Crypto::PK {
static char const* mlkem_size_to_openssl_name(MLKEMSize size)
{
switch (size) {
case MLKEMSize::MLKEM512:
return "ML-KEM-512";
case MLKEMSize::MLKEM768:
return "ML-KEM-768";
case MLKEMSize::MLKEM1024:
return "ML-KEM-1024";
default:
VERIFY_NOT_REACHED();
}
}
ErrorOr<MLKEM::KeyPairType> MLKEM::generate_key_pair(MLKEMSize size, ByteBuffer seed)
{
auto ctx = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_name(nullptr, mlkem_size_to_openssl_name(size), nullptr)));
OPENSSL_TRY(EVP_PKEY_keygen_init(ctx.ptr()));
OSSL_PARAM params[2] = {
OSSL_PARAM_END,
OSSL_PARAM_END
};
if (!seed.is_empty()) {
params[0] = OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ML_KEM_SEED, seed.data(), seed.size());
}
OPENSSL_TRY(EVP_PKEY_CTX_set_params(ctx.ptr(), params));
auto key = TRY(OpenSSL_PKEY::create());
auto* key_ptr = key.ptr();
OPENSSL_TRY(EVP_PKEY_generate(ctx.ptr(), &key_ptr));
auto pub = TRY(get_byte_buffer_param_from_key(key, OSSL_PKEY_PARAM_PUB_KEY));
auto priv = TRY(get_byte_buffer_param_from_key(key, OSSL_PKEY_PARAM_PRIV_KEY));
seed = TRY(get_byte_buffer_param_from_key(key, OSSL_PKEY_PARAM_ML_KEM_SEED));
return KeyPairType {
MLKEMPublicKey { pub },
{ seed, pub, priv }
};
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 2025, Miguel Sacristán Izcue <miguel_tete17@hotmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/ByteBuffer.h>
#include <AK/Error.h>
namespace Crypto::PK {
enum class MLKEMSize {
MLKEM512,
MLKEM768,
MLKEM1024,
};
class MLKEMPublicKey {
public:
explicit MLKEMPublicKey(ByteBuffer m_public_key)
: m_public_key(move(m_public_key))
{
}
MLKEMPublicKey() = default;
private:
ByteBuffer m_public_key;
};
class MLKEMPrivateKey {
public:
MLKEMPrivateKey(ByteBuffer seed, ByteBuffer public_key, ByteBuffer private_key)
: m_seed(move(seed))
, m_public_key(move(public_key))
, m_private_key(move(private_key))
{
}
MLKEMPrivateKey() = default;
private:
ByteBuffer m_seed;
ByteBuffer m_public_key;
ByteBuffer m_private_key;
};
template<typename PubKey, typename PrivKey>
struct MLKEMKeyPair {
PubKey public_key;
PrivKey private_key;
};
class MLKEM {
using PublicKeyType = MLKEMPublicKey;
using PrivateKeyType = MLKEMPrivateKey;
public:
using KeyPairType = MLKEMKeyPair<PublicKeyType, PrivateKeyType>;
static ErrorOr<KeyPairType> generate_key_pair(MLKEMSize size, ByteBuffer seed = {});
};
};