15#include <botan/kyber.h>
17#include <botan/assert.h>
18#include <botan/pubkey.h>
20#include <botan/secmem.h>
21#include <botan/internal/fmt.h>
22#include <botan/internal/kyber_algos.h>
23#include <botan/internal/kyber_constants.h>
24#include <botan/internal/kyber_keys.h>
25#include <botan/internal/kyber_types.h>
27#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
28 #include <botan/internal/kyber_round3_impl.h>
31#if defined(BOTAN_HAS_ML_KEM)
32 #include <botan/internal/ml_kem_impl.h>
43 if(str ==
"Kyber-512-90s-r3") {
46 if(str ==
"Kyber-768-90s-r3") {
49 if(str ==
"Kyber-1024-90s-r3") {
52 if(str ==
"Kyber-512-r3") {
55 if(str ==
"Kyber-768-r3") {
58 if(str ==
"Kyber-1024-r3") {
61 if(str ==
"ML-KEM-512") {
64 if(str ==
"ML-KEM-768") {
67 if(str ==
"ML-KEM-1024") {
75 if(
const auto name = oid.registered_name()) {
76 return kyber_mode_from_string(*name);
97 return "Kyber-512-90s-r3";
99 return "Kyber-768-90s-r3";
101 return "Kyber-1024-90s-r3";
103 return "Kyber-512-r3";
105 return "Kyber-768-r3";
107 return "Kyber-1024-r3";
113 return "ML-KEM-1024";
137#if defined(BOTAN_HAS_KYBER)
143#if defined(BOTAN_HAS_KYBER_90S)
149#if defined(BOTAN_HAS_ML_KEM)
179 return m_public->mode().estimated_strength();
186 throw Decoding_Error(
"Unexpected parameters for ML-KEM/Kyber public key");
199 return m_public->public_key_bits_raw().get();
209 return m_public->mode().canonical_parameter_set_identifier();
218 std::vector<uint8_t> test(
m_public->mode().polynomial_vector_bytes());
221 const auto& serialized_pubkey =
m_public->public_key_bits_raw();
222 return test.size() < serialized_pubkey.size() && std::equal(test.begin(), test.end(), serialized_pubkey.begin());
226 return std::make_unique<Kyber_PrivateKey>(rng,
mode());
243 throw Decoding_Error(
"Unexpected parameters for ML-KEM/Kyber private key");
250 if(
mode.mode().is_ml_kem() && sk.size() ==
mode.seed_private_key_bytes()) {
252 }
else if(sk.size() ==
mode.expanded_private_key_bytes()) {
254 }
else if(!
mode.mode().is_ml_kem() && sk.size() ==
mode.seed_private_key_bytes()) {
255 throw Invalid_Argument(
"Kyber round 3 private keys do not support the seed format");
262 return std::make_unique<Kyber_PublicKey>(*
this);
289 const auto K_prime = dec.
decrypt(c);
295 std::string_view provider)
const {
296 if(provider.empty() || provider ==
"base") {
297#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
298 if(
mode().is_kyber_round3()) {
299 return std::make_unique<Kyber_KEM_Encryptor>(
m_public, params);
303#if defined(BOTAN_HAS_ML_KEM)
304 if(
mode().is_ml_kem()) {
305 return std::make_unique<ML_KEM_Encryptor>(
m_public, params);
315 std::string_view params,
316 std::string_view provider)
const {
318 if(provider.empty() || provider ==
"base") {
319#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
320 if(
mode().is_kyber_round3()) {
321 return std::make_unique<Kyber_KEM_Decryptor>(m_private,
m_public, params);
325#if defined(BOTAN_HAS_ML_KEM)
326 if(
mode().is_ml_kem()) {
327 return std::make_unique<ML_KEM_Decryptor>(m_private,
m_public, params);
337 if(
mode().is_ml_kem() && m_private->seed().d.has_value()) {
345 throw Encoding_Error(
"Expanded private keys do not support the seed format");
347 const auto codec = [&]() -> std::unique_ptr<Kyber_Keypair_Codec> {
350 return std::make_unique<Seed_Expanding_Keypair_Codec>();
352 return std::make_unique<Expanded_Keypair_Codec>();
356 return codec->encode_keypair({
m_public, m_private});
#define BOTAN_ASSERT_UNREACHABLE()
bool parameters_are_empty() const
Codec for expanded private keys (as specified in FIPS 203).
KyberInternalKeypair decode_keypair(std::span< const uint8_t > buffer, KyberConstants mode) const override
static std::pair< std::vector< uint8_t >, secure_vector< uint8_t > > destructure(KEM_Encapsulation &&kem)
static constexpr size_t SEED_BYTES
bool is_available() const
bool is_kyber_round3() const
std::string to_string() const
OID object_identifier() const
MlPrivateKeyFormat private_key_format() const
secure_vector< uint8_t > private_key_bits_with_format(MlPrivateKeyFormat format) const
std::unique_ptr< PK_Ops::KEM_Decryption > create_kem_decryption_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const override
std::unique_ptr< Public_Key > public_key() const override
bool check_key(RandomNumberGenerator &rng, bool strong) const override
Kyber_PrivateKey(RandomNumberGenerator &rng, KyberMode mode)
secure_vector< uint8_t > raw_private_key_bits() const override
secure_vector< uint8_t > private_key_bits() const override
std::vector< uint8_t > public_key_bits() const override
std::vector< uint8_t > raw_public_key_bits() const override
bool check_key(RandomNumberGenerator &rng, bool strong) const override
std::string algo_name() const override
size_t key_length() const override
AlgorithmIdentifier algorithm_identifier() const override
Kyber_PublicKey()=default
std::unique_ptr< PK_Ops::KEM_Encryption > create_kem_encryption_op(std::string_view params, std::string_view provider) const override
std::shared_ptr< const Kyber_PublicKeyInternal > m_public
OID object_identifier() const override
std::unique_ptr< Private_Key > generate_another(RandomNumberGenerator &rng) const final
Kyber_PublicKey(std::span< const uint8_t > pub_key, KyberMode mode)
size_t estimated_strength() const override
static OID from_string(std::string_view str)
void decrypt(std::span< uint8_t > out_shared_key, std::span< const uint8_t > encap_key, size_t desired_shared_key_len=32, std::span< const uint8_t > salt={})
KEM_Encapsulation encrypt(RandomNumberGenerator &rng, size_t desired_shared_key_len=32, std::span< const uint8_t > salt={})
void random_vec(std::span< uint8_t > v)
Codec for private keys as 64-byte seeds: d || z.
KyberInternalKeypair decode_keypair(std::span< const uint8_t > buffer, KyberConstants mode) const override
void encode_polynomial_vector(std::span< uint8_t > out, const KyberPolyVecNTT &vec)
KyberInternalKeypair expand_keypair(KyberPrivateKeySeed seed, KyberConstants mode)
Strong< secure_vector< uint8_t >, struct KyberImplicitRejectionValue_ > KyberImplicitRejectionValue
Secret random value (called Z in the spec), used for implicit rejection in the decapsulation.
std::string fmt(std::string_view format, const T &... args)
MlPrivateKeyFormat
Byte encoding format of ML-KEM and ML-DSA the private key.
@ Expanded
The expanded format, i.e., the format specified in FIPS-203/204.
BOTAN_FORCE_INLINE constexpr T rho(T x)
Strong< secure_vector< uint8_t >, struct KyberSeedRandomness_ > KyberSeedRandomness
Principal seed used to generate Kyber key pairs.
std::vector< T, secure_allocator< T > > secure_vector
Strong< std::vector< uint8_t >, struct KyberSerializedPublicKey_ > KyberSerializedPublicKey
Public key in serialized form (t || rho).