Coverage Report

Created: 2025-04-11 06:34

/src/botan/build/include/internal/botan/internal/kyber_algos.h
Line
Count
Source (jump to first uncovered line)
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
24
namespace Botan::Kyber_Algos {
25
26
void encode_polynomial_vector(std::span<uint8_t> out, const KyberPolyVecNTT& p);
27
28
KyberPolyVecNTT decode_polynomial_vector(std::span<const uint8_t> a, const KyberConstants& mode);
29
30
KyberPoly polynomial_from_message(StrongSpan<const KyberMessage> msg);
31
32
KyberMessage polynomial_to_message(const KyberPoly& p);
33
34
KyberInternalKeypair expand_keypair(KyberPrivateKeySeed seed, KyberConstants mode);
35
36
void compress_ciphertext(StrongSpan<KyberCompressedCiphertext> out,
37
                         const KyberPolyVec& u,
38
                         const KyberPoly& v,
39
                         const KyberConstants& m_mode);
40
41
std::pair<KyberPolyVec, KyberPoly> decompress_ciphertext(StrongSpan<const KyberCompressedCiphertext> ct,
42
                                                         const KyberConstants& mode);
43
44
KyberPolyMat sample_matrix(StrongSpan<const KyberSeedRho> seed, bool transposed, const KyberConstants& mode);
45
46
void sample_polynomial_from_cbd(KyberPoly& poly,
47
                                KyberConstants::KyberEta eta,
48
                                const KyberSamplingRandomness& randomness);
49
50
template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
51
0
T encode_polynomial_vector(const KyberPolyVecNTT& vec, const KyberConstants& mode) {
52
0
   T r(mode.polynomial_vector_bytes());
53
0
   encode_polynomial_vector(r, vec);
54
0
   return r;
55
0
}
Unexecuted instantiation: _ZN5Botan11Kyber_Algos24encode_polynomial_vectorITkNS_8concepts21resizable_byte_bufferENSt3__16vectorIhNS_16secure_allocatorIhEEEEEET_RKNS_8CRYSTALS16PolynomialVectorINS_15KyberPolyTraitsELNS9_6DomainE1EEERKNS_14KyberConstantsE
Unexecuted instantiation: _ZN5Botan11Kyber_Algos24encode_polynomial_vectorITkNS_8concepts21resizable_byte_bufferENSt3__16vectorIhNS3_9allocatorIhEEEEEET_RKNS_8CRYSTALS16PolynomialVectorINS_15KyberPolyTraitsELNS9_6DomainE1EEERKNS_14KyberConstantsE
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
 */
63
template <typename SeedT>
64
   requires std::same_as<KyberSeedSigma, SeedT> || std::same_as<KyberEncryptionRandomness, SeedT>
65
class PolynomialSampler {
66
   public:
67
      PolynomialSampler(StrongSpan<const SeedT> seed, const KyberConstants& mode) :
68
0
            m_seed(seed), m_mode(mode), m_nonce(0) {}
Unexecuted instantiation: Botan::Kyber_Algos::PolynomialSampler<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberSeedSigma_> >::PolynomialSampler(Botan::StrongSpan<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberSeedSigma_> const>, Botan::KyberConstants const&)
Unexecuted instantiation: Botan::Kyber_Algos::PolynomialSampler<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberEncryptionRandomness_> >::PolynomialSampler(Botan::StrongSpan<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberEncryptionRandomness_> const>, Botan::KyberConstants const&)
69
70
0
      KyberPolyVec sample_polynomial_vector_cbd_eta1() {
71
0
         KyberPolyVec vec(m_mode.k());
72
0
         for(auto& poly : vec) {
73
0
            sample_poly_cbd(poly, m_mode.eta1());
74
0
         }
75
0
         return vec;
76
0
      }
Unexecuted instantiation: Botan::Kyber_Algos::PolynomialSampler<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberSeedSigma_> >::sample_polynomial_vector_cbd_eta1()
Unexecuted instantiation: Botan::Kyber_Algos::PolynomialSampler<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberEncryptionRandomness_> >::sample_polynomial_vector_cbd_eta1()
77
78
      KyberPoly sample_polynomial_cbd_eta2()
79
         requires std::same_as<KyberEncryptionRandomness, SeedT>
80
0
      {
81
0
         KyberPoly poly;
82
0
         sample_poly_cbd(poly, m_mode.eta2());
83
0
         return poly;
84
0
      }
85
86
      KyberPolyVec sample_polynomial_vector_cbd_eta2()
87
         requires std::same_as<KyberEncryptionRandomness, SeedT>
88
0
      {
89
0
         KyberPolyVec vec(m_mode.k());
90
0
         for(auto& poly : vec) {
91
0
            sample_poly_cbd(poly, m_mode.eta2());
92
0
         }
93
0
         return vec;
94
0
      }
95
96
   private:
97
0
      KyberSamplingRandomness prf(size_t bytes) { return m_mode.symmetric_primitives().PRF(m_seed, m_nonce++, bytes); }
Unexecuted instantiation: Botan::Kyber_Algos::PolynomialSampler<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberSeedSigma_> >::prf(unsigned long)
Unexecuted instantiation: Botan::Kyber_Algos::PolynomialSampler<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberEncryptionRandomness_> >::prf(unsigned long)
98
99
0
      void sample_poly_cbd(KyberPoly& poly, KyberConstants::KyberEta eta) {
100
0
         const auto randomness = [&] {
101
0
            switch(eta) {
102
0
               case KyberConstants::KyberEta::_2:
103
0
                  return prf(2 * poly.size() / 4);
104
0
               case KyberConstants::KyberEta::_3:
105
0
                  return prf(3 * poly.size() / 4);
106
0
            }
107
108
0
            BOTAN_ASSERT_UNREACHABLE();
109
0
         }();
Unexecuted instantiation: Botan::Kyber_Algos::PolynomialSampler<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberSeedSigma_> >::sample_poly_cbd(Botan::CRYSTALS::Polynomial<Botan::KyberPolyTraits, (Botan::CRYSTALS::Domain)0>&, Botan::KyberConstants::KyberEta)::{lambda()#1}::operator()() const
Unexecuted instantiation: Botan::Kyber_Algos::PolynomialSampler<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberEncryptionRandomness_> >::sample_poly_cbd(Botan::CRYSTALS::Polynomial<Botan::KyberPolyTraits, (Botan::CRYSTALS::Domain)0>&, Botan::KyberConstants::KyberEta)::{lambda()#1}::operator()() const
110
111
0
         sample_polynomial_from_cbd(poly, eta, randomness);
112
0
      }
Unexecuted instantiation: Botan::Kyber_Algos::PolynomialSampler<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberSeedSigma_> >::sample_poly_cbd(Botan::CRYSTALS::Polynomial<Botan::KyberPolyTraits, (Botan::CRYSTALS::Domain)0>&, Botan::KyberConstants::KyberEta)
Unexecuted instantiation: Botan::Kyber_Algos::PolynomialSampler<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberEncryptionRandomness_> >::sample_poly_cbd(Botan::CRYSTALS::Polynomial<Botan::KyberPolyTraits, (Botan::CRYSTALS::Domain)0>&, Botan::KyberConstants::KyberEta)
113
114
   private:
115
      StrongSpan<const SeedT> m_seed;
116
      const KyberConstants& m_mode;
117
      uint8_t m_nonce;
118
};
119
120
template <typename T>
121
PolynomialSampler(T, const KyberConstants&) -> PolynomialSampler<T>;
122
123
}  // namespace Botan::Kyber_Algos
124
125
#endif