Botan 3.5.0
Crypto and TLS for C&
kyber_symmetric_primitives.h
Go to the documentation of this file.
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 <memory>
22#include <span>
23#include <tuple>
24#include <vector>
25
26namespace Botan {
27
28/**
29 * Adapter class that uses polymorphy to distinguish
30 * Kyber "modern" from Kyber "90s" modes.
31 */
33 public:
34 virtual ~Kyber_Symmetric_Primitives() = default;
35
36 // TODO: remove this once Kyber-R3 is removed
38
39 // TODO: remove this once Kyber-R3 is removed
43
47
48 std::pair<KyberSeedRho, KyberSeedSigma> G(StrongSpan<const KyberSeedRandomness> seed) const {
49 return G_split<KyberSeedRho, KyberSeedSigma>(seed);
50 }
51
52 std::pair<KyberSharedSecret, KyberEncryptionRandomness> G(
54 return G_split<KyberSharedSecret, KyberEncryptionRandomness>(msg, pubkey_hash);
55 }
56
57 // TODO: remove this once Kyber-R3 is removed
60 StrongSpan<const KyberHashedCiphertext> hashed_ciphertext) const {
61 auto& kdf = get_KDF();
62 kdf.update(shared_secret);
63 kdf.update(hashed_ciphertext);
64 kdf.final(out);
65 }
66
68 const uint8_t nonce,
69 const size_t outlen) const {
70 auto bare_seed_span = std::visit([&](const auto s) { return s.get(); }, seed);
71 return get_PRF(bare_seed_span, nonce).output<KyberSamplingRandomness>(outlen);
72 }
73
74 std::unique_ptr<Botan::XOF> XOF(StrongSpan<const KyberSeedRho> seed,
75 std::tuple<uint8_t, uint8_t> matrix_position) const {
76 // TODO: once we remove Kyber 90s, we should make `get_XOF()` return a
77 // reference instead of a unique pointer (for consistency), and
78 // call `get_XOF().copy_state()` here. The AES-CTR XOF doesn't
79 // support this.
80 return get_XOF(seed, matrix_position);
81 }
82
83 private:
86 ranges::contiguous_range... InputTs>
87 std::pair<T1, T2> G_split(InputTs&&... inputs) const {
88 auto& g = get_G();
89 (g.update(inputs), ...);
90 auto s = g.final();
91
92 BufferSlicer bs(s);
93 std::pair<T1, T2> result;
94 result.first = bs.copy<T1>(KyberConstants::kSeedLength);
95 result.second = bs.copy<T2>(KyberConstants::kSeedLength);
96 BOTAN_ASSERT_NOMSG(bs.empty());
97 return result;
98 }
99
100 protected:
101 virtual HashFunction& get_G() const = 0;
102 virtual HashFunction& get_H() const = 0;
103 virtual HashFunction& get_KDF() const = 0;
104 virtual Botan::XOF& get_PRF(std::span<const uint8_t> seed, uint8_t nonce) const = 0;
105 virtual std::unique_ptr<Botan::XOF> get_XOF(std::span<const uint8_t> seed,
106 std::tuple<uint8_t, uint8_t> matrix_position) const = 0;
107};
108
109} // namespace Botan
110
111#endif
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
T process(const uint8_t in[], size_t length)
Definition buf_comp.h:105
static constexpr size_t kSeedLength
virtual ~Kyber_Symmetric_Primitives()=default
KyberMessage H(StrongSpan< const KyberMessage > m) const
virtual Botan::XOF & get_PRF(std::span< const uint8_t > seed, uint8_t nonce) const =0
KyberHashedCiphertext H(StrongSpan< const KyberCompressedCiphertext > r) const
std::unique_ptr< Botan::XOF > XOF(StrongSpan< const KyberSeedRho > seed, std::tuple< uint8_t, uint8_t > matrix_position) const
virtual HashFunction & get_G() const =0
void KDF(StrongSpan< KyberSharedSecret > out, StrongSpan< const KyberSharedSecret > shared_secret, StrongSpan< const KyberHashedCiphertext > hashed_ciphertext) const
KyberSamplingRandomness PRF(KyberSigmaOrEncryptionRandomness seed, const uint8_t nonce, const size_t outlen) const
std::pair< KyberSeedRho, KyberSeedSigma > G(StrongSpan< const KyberSeedRandomness > seed) const
std::pair< KyberSharedSecret, KyberEncryptionRandomness > G(StrongSpan< const KyberMessage > msg, StrongSpan< const KyberHashedPublicKey > pubkey_hash) const
virtual HashFunction & get_H() const =0
virtual std::unique_ptr< Botan::XOF > get_XOF(std::span< const uint8_t > seed, std::tuple< uint8_t, uint8_t > matrix_position) const =0
virtual HashFunction & get_KDF() const =0
KyberHashedPublicKey H(StrongSpan< const KyberSerializedPublicKey > pk) const
T output(size_t bytes)
Definition xof.h:155
std::variant< StrongSpan< const KyberSeedSigma >, StrongSpan< const KyberEncryptionRandomness > > KyberSigmaOrEncryptionRandomness
Definition kyber_types.h:61