Coverage Report

Created: 2024-11-29 06:10

/src/botan/build/include/internal/botan/internal/kyber_symmetric_primitives.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Symmetric primitives for Kyber (modern)
3
 * (C) 2022 Jack Lloyd
4
 * (C) 2022 Hannes Rantzsch, René Meusel, neXenio GmbH
5
 * (C) 2024 René Meusel, Rohde & Schwarz Cybersecurity
6
 *
7
 * Botan is released under the Simplified BSD License (see license.txt)
8
 */
9
10
#ifndef BOTAN_KYBER_SYMMETRIC_PRIMITIVES_H_
11
#define BOTAN_KYBER_SYMMETRIC_PRIMITIVES_H_
12
13
#include <botan/hash.h>
14
#include <botan/secmem.h>
15
#include <botan/xof.h>
16
17
#include <botan/internal/kyber_constants.h>
18
#include <botan/internal/kyber_types.h>
19
#include <botan/internal/stl_util.h>
20
21
#include <span>
22
#include <tuple>
23
24
namespace Botan {
25
26
/**
27
 * Adapter class that uses polymorphy to distinguish
28
 * Kyber "modern" from Kyber "90s" modes.
29
 */
30
class Kyber_Symmetric_Primitives {
31
   public:
32
3
      virtual ~Kyber_Symmetric_Primitives() = default;
33
34
      // TODO: remove this once Kyber-R3 is removed
35
0
      KyberMessage H(StrongSpan<const KyberMessage> m) const { return get_H().process<KyberMessage>(m); }
36
37
      // TODO: remove this once Kyber-R3 is removed
38
0
      KyberHashedCiphertext H(StrongSpan<const KyberCompressedCiphertext> r) const {
39
0
         return get_H().process<KyberHashedCiphertext>(r);
40
0
      }
41
42
0
      KyberHashedPublicKey H(StrongSpan<const KyberSerializedPublicKey> pk) const {
43
0
         return get_H().process<KyberHashedPublicKey>(pk);
44
0
      }
45
46
      std::pair<KyberSeedRho, KyberSeedSigma> G(StrongSpan<const KyberSeedRandomness> seed,
47
0
                                                const KyberConstants& mode) const {
48
0
         if(auto domsep = seed_expansion_domain_separator(mode)) {
49
0
            return G_split<KyberSeedRho, KyberSeedSigma>(seed, *domsep);
50
0
         } else {
51
0
            return G_split<KyberSeedRho, KyberSeedSigma>(seed);
52
0
         }
53
0
      }
54
55
      std::pair<KyberSharedSecret, KyberEncryptionRandomness> G(
56
0
         StrongSpan<const KyberMessage> msg, StrongSpan<const KyberHashedPublicKey> pubkey_hash) const {
57
0
         return G_split<KyberSharedSecret, KyberEncryptionRandomness>(msg, pubkey_hash);
58
0
      }
59
60
      KyberSharedSecret J(StrongSpan<const KyberImplicitRejectionValue> rejection_value,
61
0
                          StrongSpan<const KyberCompressedCiphertext> ciphertext) const {
62
0
         auto& j = get_J();
63
0
         j.update(rejection_value);
64
0
         j.update(ciphertext);
65
0
         return j.final<KyberSharedSecret>();
66
0
      }
67
68
      // TODO: remove this once Kyber-R3 is removed
69
      void KDF(StrongSpan<KyberSharedSecret> out,
70
               StrongSpan<const KyberSharedSecret> shared_secret,
71
0
               StrongSpan<const KyberHashedCiphertext> hashed_ciphertext) const {
72
0
         auto& kdf = get_KDF();
73
0
         kdf.update(shared_secret);
74
0
         kdf.update(hashed_ciphertext);
75
0
         kdf.final(out);
76
0
      }
77
78
      KyberSamplingRandomness PRF(KyberSigmaOrEncryptionRandomness seed,
79
                                  const uint8_t nonce,
80
0
                                  const size_t outlen) const {
81
0
         auto bare_seed_span = std::visit([&](const auto s) { return s.get(); }, seed);
Unexecuted instantiation: auto Botan::Kyber_Symmetric_Primitives::PRF(std::__1::variant<Botan::StrongSpan<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberSeedSigma_> const>, Botan::StrongSpan<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberEncryptionRandomness_> const> >, unsigned char, unsigned long) const::{lambda(auto:1)#1}::operator()<Botan::StrongSpan<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberSeedSigma_> const> >(Botan::StrongSpan<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberSeedSigma_> const>) const
Unexecuted instantiation: auto Botan::Kyber_Symmetric_Primitives::PRF(std::__1::variant<Botan::StrongSpan<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberSeedSigma_> const>, Botan::StrongSpan<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberEncryptionRandomness_> const> >, unsigned char, unsigned long) const::{lambda(auto:1)#1}::operator()<Botan::StrongSpan<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberEncryptionRandomness_> const> >(Botan::StrongSpan<Botan::Strong<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::KyberEncryptionRandomness_> const>) const
82
0
         return get_PRF(bare_seed_span, nonce).output<KyberSamplingRandomness>(outlen);
83
0
      }
84
85
0
      Botan::XOF& XOF(StrongSpan<const KyberSeedRho> seed, std::tuple<uint8_t, uint8_t> matrix_position) const {
86
0
         return get_XOF(seed, matrix_position);
87
0
      }
88
89
   private:
90
      template <concepts::contiguous_strong_type T1,
91
                concepts::contiguous_strong_type T2,
92
                ranges::contiguous_range... InputTs>
93
0
      std::pair<T1, T2> G_split(InputTs&&... inputs) const {
94
0
         auto& g = get_G();
95
0
         (g.update(inputs), ...);
96
0
         auto s = g.final();
97
98
0
         BufferSlicer bs(s);
99
0
         std::pair<T1, T2> result;
100
0
         result.first = bs.copy<T1>(KyberConstants::SEED_BYTES);
101
0
         result.second = bs.copy<T2>(KyberConstants::SEED_BYTES);
102
0
         BOTAN_ASSERT_NOMSG(bs.empty());
103
0
         return result;
104
0
      }
Unexecuted instantiation: _ZNK5Botan26Kyber_Symmetric_Primitives7G_splitITkNS_8concepts22contiguous_strong_typeENS_6StrongINSt3__16vectorIhNS4_9allocatorIhEEEENS_13KyberSeedRho_EJEEETkNS2_22contiguous_strong_typeENS3_INS5_IhNS_16secure_allocatorIhEEEENS_15KyberSeedSigma_EJEEETpTkNS_6ranges16contiguous_rangeEJRNS_10StrongSpanIKNS3_ISD_NS_20KyberSeedRandomness_EJEEEEERNS4_5arrayIhLm1EEEEEENS4_4pairIT_T0_EEDpOT1_
Unexecuted instantiation: _ZNK5Botan26Kyber_Symmetric_Primitives7G_splitITkNS_8concepts22contiguous_strong_typeENS_6StrongINSt3__16vectorIhNS4_9allocatorIhEEEENS_13KyberSeedRho_EJEEETkNS2_22contiguous_strong_typeENS3_INS5_IhNS_16secure_allocatorIhEEEENS_15KyberSeedSigma_EJEEETpTkNS_6ranges16contiguous_rangeEJRNS_10StrongSpanIKNS3_ISD_NS_20KyberSeedRandomness_EJEEEEEEEENS4_4pairIT_T0_EEDpOT1_
Unexecuted instantiation: _ZNK5Botan26Kyber_Symmetric_Primitives7G_splitITkNS_8concepts22contiguous_strong_typeENS_6StrongINSt3__16vectorIhNS_16secure_allocatorIhEEEENS_18KyberSharedSecret_EJEEETkNS2_22contiguous_strong_typeENS3_IS8_NS_26KyberEncryptionRandomness_EJEEETpTkNS_6ranges16contiguous_rangeEJRNS_10StrongSpanIKNS3_IS8_NS_13KyberMessage_EJEEEEERNSE_IKNS3_INS5_IhNS4_9allocatorIhEEEENS_21KyberHashedPublicKey_EJEEEEEEEENS4_4pairIT_T0_EEDpOT1_
105
106
   protected:
107
      virtual std::optional<std::array<uint8_t, 1>> seed_expansion_domain_separator(
108
         const KyberConstants& mode) const = 0;
109
110
      virtual HashFunction& get_G() const = 0;
111
      virtual HashFunction& get_H() const = 0;
112
      virtual HashFunction& get_J() const = 0;
113
      virtual HashFunction& get_KDF() const = 0;
114
      virtual Botan::XOF& get_PRF(std::span<const uint8_t> seed, uint8_t nonce) const = 0;
115
      virtual Botan::XOF& get_XOF(std::span<const uint8_t> seed,
116
                                  std::tuple<uint8_t, uint8_t> matrix_position) const = 0;
117
};
118
119
}  // namespace Botan
120
121
#endif