Botan 3.11.0
Crypto and TLS for C&
kyber_algos.h
Go to the documentation of this file.
1/*
2 * Crystals Kyber Internal Algorithms
3 * Based on the public domain reference implementation by the
4 * designers (https://github.com/pq-crystals/kyber)
5 *
6 * Further changes
7 * (C) 2021-2024 Jack Lloyd
8 * (C) 2021-2022 Manuel Glaser and Michael Boric, Rohde & Schwarz Cybersecurity
9 * (C) 2021-2022 René Meusel and Hannes Rantzsch, neXenio GmbH
10 * (C) 2024 René Meusel, Rohde & Schwarz Cybersecurity
11 *
12 * Botan is released under the Simplified BSD License (see license.txt)
13 */
14
15#ifndef BOTAN_KYBER_ALGOS_H_
16#define BOTAN_KYBER_ALGOS_H_
17
18#include <botan/internal/kyber_symmetric_primitives.h>
19#include <botan/internal/kyber_types.h>
20
21namespace Botan::Kyber_Algos {
22
23void encode_polynomial_vector(std::span<uint8_t> out, const KyberPolyVecNTT& p);
24
25KyberPolyVecNTT decode_polynomial_vector(std::span<const uint8_t> a, const KyberConstants& mode);
26
27KyberPoly polynomial_from_message(StrongSpan<const KyberMessage> msg);
28
30
31KyberInternalKeypair expand_keypair(KyberPrivateKeySeed seed, KyberConstants mode);
32
33void compress_ciphertext(StrongSpan<KyberCompressedCiphertext> out,
34 const KyberPolyVec& u,
35 const KyberPoly& v,
36 const KyberConstants& m_mode);
37
38std::pair<KyberPolyVec, KyberPoly> decompress_ciphertext(StrongSpan<const KyberCompressedCiphertext> ct,
39 const KyberConstants& mode);
40
41KyberPolyMat sample_matrix(StrongSpan<const KyberSeedRho> seed, bool transposed, const KyberConstants& mode);
42
45 const KyberSamplingRandomness& randomness);
46
47template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
49 T r(mode.polynomial_vector_bytes());
51 return r;
52}
53
54/**
55 * Allows sampling multiple polynomials from a single seed via a XOF.
56 *
57 * Used in Algorithms 13 (K-PKE.KeyGen) and 14 (K-PKE.Encrypt), and takes care
58 * of the continuous nonce value internally.
59 */
60template <typename SeedT>
61 requires std::same_as<KyberSeedSigma, SeedT> || std::same_as<KyberEncryptionRandomness, SeedT>
63 public:
65 m_seed(seed), m_mode(mode), m_nonce(0) {}
66
68 KyberPolyVec vec(m_mode.k());
69 for(auto& poly : vec) {
70 sample_poly_cbd(poly, m_mode.eta1());
71 }
72 return vec;
73 }
74
76 requires std::same_as<KyberEncryptionRandomness, SeedT>
77 {
78 KyberPoly poly;
79 sample_poly_cbd(poly, m_mode.eta2());
80 return poly;
81 }
82
84 requires std::same_as<KyberEncryptionRandomness, SeedT>
85 {
86 KyberPolyVec vec(m_mode.k());
87 for(auto& poly : vec) {
88 sample_poly_cbd(poly, m_mode.eta2());
89 }
90 return vec;
91 }
92
93 private:
94 KyberSamplingRandomness prf(size_t bytes) {
95 const auto& sym = m_mode.symmetric_primitives();
96 auto seed_span = m_seed.get();
97 sym.setup_PRF(m_prf_xof, seed_span, m_nonce++);
98 return m_prf_xof->output<KyberSamplingRandomness>(bytes);
99 }
100
101 void sample_poly_cbd(KyberPoly& poly, KyberConstants::KyberEta eta) {
102 const auto randomness = [&] {
103 switch(eta) {
105 return prf(2 * poly.size() / 4);
107 return prf(3 * poly.size() / 4);
108 }
109
111 }();
112
113 sample_polynomial_from_cbd(poly, eta, randomness);
114 }
115
116 private:
117 StrongSpan<const SeedT> m_seed;
118 const KyberConstants& m_mode;
119 uint8_t m_nonce;
120 std::unique_ptr<Botan::XOF> m_prf_xof;
121};
122
123template <typename T>
125
126} // namespace Botan::Kyber_Algos
127
128#endif
#define BOTAN_ASSERT_UNREACHABLE()
Definition assert.h:163
constexpr size_t size() const
Definition pqcrystals.h:276
size_t polynomial_vector_bytes() const
byte length of an encoded polynomial vector
Kyber_Symmetric_Primitives & symmetric_primitives() const
PolynomialSampler(StrongSpan< const SeedT > seed, const KyberConstants &mode)
Definition kyber_algos.h:64
KyberPolyVec sample_polynomial_vector_cbd_eta1()
Definition kyber_algos.h:67
KyberPolyVec sample_polynomial_vector_cbd_eta2()
Definition kyber_algos.h:83
underlying_span get() const
PolynomialSampler(T, const KyberConstants &) -> PolynomialSampler< T >
void encode_polynomial_vector(std::span< uint8_t > out, const KyberPolyVecNTT &vec)
KyberMessage polynomial_to_message(const KyberPoly &p)
KyberPolyMat sample_matrix(StrongSpan< const KyberSeedRho > seed, bool transposed, const KyberConstants &mode)
void compress_ciphertext(StrongSpan< KyberCompressedCiphertext > out, const KyberPolyVec &u, const KyberPoly &v, const KyberConstants &m_mode)
KyberInternalKeypair expand_keypair(KyberPrivateKeySeed seed, KyberConstants mode)
KyberPoly polynomial_from_message(StrongSpan< const KyberMessage > msg)
void sample_polynomial_from_cbd(KyberPoly &poly, KyberConstants::KyberEta eta, const KyberSamplingRandomness &randomness)
std::pair< KyberPolyVec, KyberPoly > decompress_ciphertext(StrongSpan< const KyberCompressedCiphertext > ct, const KyberConstants &mode)
KyberPolyVecNTT decode_polynomial_vector(std::span< const uint8_t > a, const KyberConstants &mode)
Strong< secure_vector< uint8_t >, struct KyberEncryptionRandomness_ > KyberEncryptionRandomness
Random value used to generate the Kyber ciphertext.
Definition kyber_types.h:48
Strong< secure_vector< uint8_t >, struct KyberMessage_ > KyberMessage
Random message value to be encrypted by the CPA-secure Kyber encryption scheme.
Definition kyber_types.h:45
Botan::CRYSTALS::Polynomial< KyberPolyTraits, Botan::CRYSTALS::Domain::Normal > KyberPoly
Definition kyber_types.h:29
Botan::CRYSTALS::PolynomialVector< KyberPolyTraits, Botan::CRYSTALS::Domain::NTT > KyberPolyVecNTT
Definition kyber_types.h:26
Strong< secure_vector< uint8_t >, struct KyberSamplingRandomness_ > KyberSamplingRandomness
PRF value used for sampling of error polynomials.
Definition kyber_types.h:51
std::pair< std::shared_ptr< Kyber_PublicKeyInternal >, std::shared_ptr< Kyber_PrivateKeyInternal > > KyberInternalKeypair
Definition kyber_types.h:73
Botan::CRYSTALS::PolynomialMatrix< KyberPolyTraits > KyberPolyMat
Definition kyber_types.h:27
Botan::CRYSTALS::PolynomialVector< KyberPolyTraits, Botan::CRYSTALS::Domain::Normal > KyberPolyVec
Definition kyber_types.h:30