Botan 3.6.1
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/xof.h>
19#include <botan/internal/fmt.h>
20#include <botan/internal/kyber_symmetric_primitives.h>
21#include <botan/internal/kyber_types.h>
22#include <botan/internal/loadstor.h>
23
24namespace Botan::Kyber_Algos {
25
26void encode_polynomial_vector(std::span<uint8_t> out, const KyberPolyVecNTT& p);
27
28KyberPolyVecNTT decode_polynomial_vector(std::span<const uint8_t> a, const KyberConstants& mode);
29
30KyberPoly polynomial_from_message(StrongSpan<const KyberMessage> msg);
31
33
34KyberInternalKeypair expand_keypair(KyberPrivateKeySeed seed, KyberConstants mode);
35
36void compress_ciphertext(StrongSpan<KyberCompressedCiphertext> out,
37 const KyberPolyVec& u,
38 const KyberPoly& v,
39 const KyberConstants& m_mode);
40
41std::pair<KyberPolyVec, KyberPoly> decompress_ciphertext(StrongSpan<const KyberCompressedCiphertext> ct,
42 const KyberConstants& mode);
43
44KyberPolyMat sample_matrix(StrongSpan<const KyberSeedRho> seed, bool transposed, const KyberConstants& mode);
45
48 const KyberSamplingRandomness& randomness);
49
50template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
52 T r(mode.polynomial_vector_bytes());
54 return r;
55}
56
57/**
58 * Allows sampling multiple polynomials from a single seed via a XOF.
59 *
60 * Used in Algorithms 13 (K-PKE.KeyGen) and 14 (K-PKE.Encrypt), and takes care
61 * of the continuous nonce value internally.
62 */
63template <typename SeedT>
64 requires std::same_as<KyberSeedSigma, SeedT> || std::same_as<KyberEncryptionRandomness, SeedT>
66 public:
68 m_seed(seed), m_mode(mode), m_nonce(0) {}
69
71 KyberPolyVec vec(m_mode.k());
72 for(auto& poly : vec) {
73 sample_poly_cbd(poly, m_mode.eta1());
74 }
75 return vec;
76 }
77
79 requires std::same_as<KyberEncryptionRandomness, SeedT>
80 {
81 KyberPoly poly;
82 sample_poly_cbd(poly, m_mode.eta2());
83 return poly;
84 }
85
87 requires std::same_as<KyberEncryptionRandomness, SeedT>
88 {
89 KyberPolyVec vec(m_mode.k());
90 for(auto& poly : vec) {
91 sample_poly_cbd(poly, m_mode.eta2());
92 }
93 return vec;
94 }
95
96 private:
97 KyberSamplingRandomness prf(size_t bytes) { return m_mode.symmetric_primitives().PRF(m_seed, m_nonce++, bytes); }
98
99 void sample_poly_cbd(KyberPoly& poly, KyberConstants::KyberEta eta) {
100 const auto randomness = [&] {
101 switch(eta) {
103 return prf(2 * poly.size() / 4);
105 return prf(3 * poly.size() / 4);
106 }
107
109 }();
110
111 sample_polynomial_from_cbd(poly, eta, randomness);
112 }
113
114 private:
115 StrongSpan<const SeedT> m_seed;
116 const KyberConstants& m_mode;
117 uint8_t m_nonce;
118};
119
120template <typename T>
122
123} // namespace Botan::Kyber_Algos
124
125#endif
#define BOTAN_ASSERT_UNREACHABLE()
Definition assert.h:137
constexpr size_t size() const
Definition pqcrystals.h:274
constexpr KyberEta eta2() const
size_t polynomial_vector_bytes() const
byte length of an encoded polynomial vector
KyberEta eta1() const
Kyber_Symmetric_Primitives & symmetric_primitives() const
PolynomialSampler(StrongSpan< const SeedT > seed, const KyberConstants &mode)
Definition kyber_algos.h:67
KyberPolyVec sample_polynomial_vector_cbd_eta1()
Definition kyber_algos.h:70
KyberPolyVec sample_polynomial_vector_cbd_eta2()
Definition kyber_algos.h:86
KyberSamplingRandomness PRF(KyberSigmaOrEncryptionRandomness seed, const uint8_t nonce, const size_t outlen) const
FE_25519 T
Definition ge.cpp:34
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 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