/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 |