Botan 3.6.1
Crypto and TLS for C&
kyber_round3_impl.cpp
Go to the documentation of this file.
1/*
2 * Crystals Kyber key encapsulation mechanism and key codec
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/kyber_round3_impl.h>
11
12#include <botan/internal/ct_utils.h>
13#include <botan/internal/kyber_constants.h>
14#include <botan/internal/kyber_symmetric_primitives.h>
15#include <botan/internal/kyber_types.h>
16
17namespace Botan {
18
19/**
20 * Crystals Kyber (Version 3.01), Algorithm 8 (Kyber.CCAKEM.Enc())
21 */
23 StrongSpan<KyberSharedSecret> out_shared_key,
25 const auto& sym = m_public_key->mode().symmetric_primitives();
26
27 const auto seed_m = rng.random_vec<KyberMessage>(KyberConstants::SEED_BYTES);
28 CT::poison(seed_m);
29
30 const auto m = sym.H(seed_m);
31 const auto [K_bar, r] = sym.G(m, m_public_key->H_public_key_bits_raw());
32 m_public_key->indcpa_encrypt(out_encapsulated_key, m, r, precomputed_matrix_At());
33
34 sym.KDF(out_shared_key, K_bar, sym.H(out_encapsulated_key));
35 CT::unpoison_all(out_shared_key, out_encapsulated_key);
36}
37
38/**
39 * Crystals Kyber (Version 3.01), Algorithm 9 (Kyber.CCAKEM.Dec())
40 */
43 auto scope = CT::scoped_poison(*m_private_key);
44
45 const auto& sym = m_public_key->mode().symmetric_primitives();
46
47 const auto& h = m_public_key->H_public_key_bits_raw();
48 const auto& z = m_private_key->z();
49
50 const auto m_prime = m_private_key->indcpa_decrypt(encapsulated_key);
51 const auto [K_bar_prime, r_prime] = sym.G(m_prime, h);
52
53 const auto c_prime = m_public_key->indcpa_encrypt(m_prime, r_prime, precomputed_matrix_At());
54
56 BOTAN_ASSERT_NOMSG(encapsulated_key.size() == c_prime.size());
57 BOTAN_ASSERT_NOMSG(K_bar_prime.size() == K.size());
58 const auto reencrypt_success = CT::is_equal(encapsulated_key.data(), c_prime.data(), encapsulated_key.size());
59 CT::conditional_copy_mem(reencrypt_success, K.data(), K_bar_prime.data(), z.data(), K_bar_prime.size());
60
61 sym.KDF(out_shared_key, K, sym.H(encapsulated_key));
62 CT::unpoison(out_shared_key);
63}
64
65/**
66 * Key decoding as specified in Crystals Kyber (Version 3.01),
67 * Algorithms 4 (CPAPKE.KeyGen()), and 7 (CCAKEM.KeyGen())
68 *
69 * Public Key: pk := (encode(t) || rho)
70 * Secret Key: sk' := encode(s)
71 *
72 * Expanded Secret Key: sk := (sk' || pk || H(pk) || z)
73 */
75 KyberConstants mode) const {
76 auto scope = CT::scoped_poison(sk);
77 BufferSlicer s(sk);
78
80 auto pub_key = s.copy<KyberSerializedPublicKey>(mode.public_key_bytes());
83
85
86 CT::unpoison_all(pub_key, puk_key_hash, skpv, z);
87
89 std::make_shared<Kyber_PublicKeyInternal>(mode, std::move(pub_key)),
90 std::make_shared<Kyber_PrivateKeyInternal>(
91 std::move(mode),
92 std::move(skpv),
93 KyberPrivateKeySeed{std::nullopt, // Reading from an expanded and encoded
94 // private key cannot reconstruct the
95 // original seed from key generation.
96 std::move(z)}),
97 };
98
99 BOTAN_ASSERT(keypair.first && keypair.second, "reading private key encoding");
100 BOTAN_ARG_CHECK(keypair.first->H_public_key_bits_raw().size() == puk_key_hash.size() &&
101 std::equal(keypair.first->H_public_key_bits_raw().begin(),
102 keypair.first->H_public_key_bits_raw().end(),
103 puk_key_hash.begin()),
104 "public key's hash does not match the stored hash");
105
106 return keypair;
107}
108
110 BOTAN_ASSERT_NONNULL(keypair.first);
111 BOTAN_ASSERT_NONNULL(keypair.second);
112 const auto& mode = keypair.first->mode();
113 auto scope = CT::scoped_poison(*keypair.second);
114 auto result = concat(Kyber_Algos::encode_polynomial_vector(keypair.second->s().reduce(), mode),
115 keypair.first->public_key_bits_raw(),
116 keypair.first->H_public_key_bits_raw(),
117 keypair.second->z());
118 CT::unpoison(result);
119 return result;
120}
121
122} // 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
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:50
auto copy(const size_t count)
Definition stl_util.h:89
bool empty() const
Definition stl_util.h:129
std::span< const uint8_t > take(const size_t count)
Definition stl_util.h:98
static constexpr size_t SEED_BYTES
size_t public_key_bytes() const
byte length of an encoded public key
size_t polynomial_vector_bytes() const
byte length of an encoded polynomial vector
static constexpr size_t PUBLIC_KEY_HASH_BYTES
KyberInternalKeypair decode_keypair(std::span< const uint8_t > buffer, KyberConstants mode) const override
secure_vector< uint8_t > encode_keypair(KyberInternalKeypair private_key) const override
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
const KyberPolyMat & precomputed_matrix_At() const
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
constexpr void poison(const T *p, size_t n)
Definition ct_utils.h:53
void encode_polynomial_vector(std::span< uint8_t > out, const KyberPolyVecNTT &vec)
KyberPolyVecNTT decode_polynomial_vector(std::span< const uint8_t > a, const 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