Botan 3.6.0
Crypto and TLS for C&
ml_kem_impl.cpp
Go to the documentation of this file.
1/*
2 * Module-Lattice Key Encapsulation Mechanism (ML-KEM), Initial Public Draft
3 *
4 * (C) 2024 Jack Lloyd
5 * (C) 2024 René Meusel, Rohde & Schwarz Cybersecurity
6 *
7 * Botan is released under the Simplified BSD License (see license.txt)
8 */
9
10#include <botan/internal/ml_kem_impl.h>
11
12#include <botan/internal/ct_utils.h>
13#include <botan/internal/kyber_algos.h>
14#include <botan/internal/kyber_constants.h>
15#include <botan/internal/kyber_types.h>
16
17namespace Botan {
18
19/**
20 * NIST FIPS 203, Algorithm 17 (ML-KEM.Encaps_internal), and 20 (ML-KEM.Encaps)
21 *
22 * Generation of the random value is inlined with its usage. The public matrix
23 * A^T as well as H(pk) are precomputed and readily available.
24 */
26 StrongSpan<KyberSharedSecret> out_shared_key,
28 const auto& sym = m_public_key->mode().symmetric_primitives();
29
31 auto scope = CT::scoped_poison(m);
32
33 const auto [K, r] = sym.G(m, m_public_key->H_public_key_bits_raw());
34 m_public_key->indcpa_encrypt(out_encapsulated_key, m, r, precomputed_matrix_At());
35
36 // TODO: avoid this copy by letting sym.G() directly write to the span.
37 copy_mem(out_shared_key, K);
38 CT::unpoison_all(out_shared_key, out_encapsulated_key);
39}
40
41/**
42 * NIST FIPS 203, Algorithm 18 (ML-KEM.Decaps_internal) and 21 (ML-KEM.Decaps)
43 *
44 * The public and private keys are readily available as member variables and
45 * don't need to be decoded. The checks stated in FIPS 203, Section 7.3 are
46 * performed before decoding the keys and the ciphertext.
47 */
50 auto scope = CT::scoped_poison(*m_private_key);
51
52 const auto& sym = m_public_key->mode().symmetric_primitives();
53
54 const auto& h = m_public_key->H_public_key_bits_raw();
55 const auto& z = m_private_key->z();
56
57 const auto m_prime = m_private_key->indcpa_decrypt(c);
58 const auto [K_prime, r_prime] = sym.G(m_prime, h);
59
60 const auto K_bar = sym.J(z, c);
61 const auto c_prime = m_public_key->indcpa_encrypt(m_prime, r_prime, precomputed_matrix_At());
62
63 BOTAN_ASSERT_NOMSG(c.size() == c_prime.size());
64 BOTAN_ASSERT_NOMSG(K_prime.size() == K_bar.size() && out_shared_key.size() == K_bar.size());
65 const auto reencrypt_success = CT::is_equal(c.data(), c_prime.data(), c.size());
66 CT::conditional_copy_mem(reencrypt_success, out_shared_key.data(), K_prime.data(), K_bar.data(), K_prime.size());
67
68 CT::unpoison(out_shared_key);
69}
70
72 KyberConstants mode) const {
73 BufferSlicer s(private_key);
74 auto seed = KyberPrivateKeySeed{
77 };
79 return Kyber_Algos::expand_keypair(std::move(seed), std::move(mode));
80}
81
83 BOTAN_ASSERT_NONNULL(keypair.second);
84 const auto& seed = keypair.second->seed();
85 BOTAN_ARG_CHECK(seed.d.has_value(), "Cannot encode keypair without the full private seed");
86 return concat<secure_vector<uint8_t>>(seed.d.value(), seed.z);
87};
88
89} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:86
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29
auto copy(const size_t count)
Definition stl_util.h:89
bool empty() const
Definition stl_util.h:129
static constexpr size_t SEED_BYTES
const KyberPolyMat & precomputed_matrix_At() const
void decapsulate(StrongSpan< KyberSharedSecret > out_shared_key, StrongSpan< const KyberCompressedCiphertext > encapsulated_key) override
void encapsulate(StrongSpan< KyberCompressedCiphertext > out_encapsulated_key, StrongSpan< KyberSharedSecret > out_shared_key, RandomNumberGenerator &rng) override
KyberInternalKeypair decode_keypair(std::span< const uint8_t > buffer, KyberConstants mode) const override
secure_vector< uint8_t > encode_keypair(KyberInternalKeypair keypair) const override
void random_vec(std::span< uint8_t > v)
Definition rng.h:180
decltype(auto) data() noexcept(noexcept(this->m_span.data()))
decltype(auto) size() const noexcept(noexcept(this->m_span.size()))
constexpr void unpoison_all(Ts &&... ts)
Definition ct_utils.h:201
constexpr auto scoped_poison(const Ts &... xs)
Definition ct_utils.h:216
constexpr Mask< T > conditional_copy_mem(Mask< T > mask, T *to, const T *from0, const T *from1, size_t elems)
Definition ct_utils.h:699
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
Definition ct_utils.h:759
constexpr void unpoison(const T *p, size_t n)
Definition ct_utils.h:64
KyberInternalKeypair expand_keypair(KyberPrivateKeySeed seed, KyberConstants mode)
constexpr auto concat(Rs &&... ranges)
Definition stl_util.h:263
std::pair< std::shared_ptr< Kyber_PublicKeyInternal >, std::shared_ptr< Kyber_PrivateKeyInternal > > KyberInternalKeypair
Definition kyber_types.h:73
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:146