Botan 3.6.1
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 <span>
22#include <tuple>
23
24namespace Botan {
25
26/**
27 * Adapter class that uses polymorphy to distinguish
28 * Kyber "modern" from Kyber "90s" modes.
29 */
31 public:
32 virtual ~Kyber_Symmetric_Primitives() = default;
33
34 // TODO: remove this once Kyber-R3 is removed
36
37 // TODO: remove this once Kyber-R3 is removed
41
45
46 std::pair<KyberSeedRho, KyberSeedSigma> G(StrongSpan<const KyberSeedRandomness> seed,
47 const KyberConstants& mode) const {
48 if(auto domsep = seed_expansion_domain_separator(mode)) {
49 return G_split<KyberSeedRho, KyberSeedSigma>(seed, *domsep);
50 } else {
51 return G_split<KyberSeedRho, KyberSeedSigma>(seed);
52 }
53 }
54
55 std::pair<KyberSharedSecret, KyberEncryptionRandomness> G(
57 return G_split<KyberSharedSecret, KyberEncryptionRandomness>(msg, pubkey_hash);
58 }
59
62 auto& j = get_J();
63 j.update(rejection_value);
64 j.update(ciphertext);
65 return j.final<KyberSharedSecret>();
66 }
67
68 // TODO: remove this once Kyber-R3 is removed
71 StrongSpan<const KyberHashedCiphertext> hashed_ciphertext) const {
72 auto& kdf = get_KDF();
73 kdf.update(shared_secret);
74 kdf.update(hashed_ciphertext);
75 kdf.final(out);
76 }
77
79 const uint8_t nonce,
80 const size_t outlen) const {
81 auto bare_seed_span = std::visit([&](const auto s) { return s.get(); }, seed);
82 return get_PRF(bare_seed_span, nonce).output<KyberSamplingRandomness>(outlen);
83 }
84
85 Botan::XOF& XOF(StrongSpan<const KyberSeedRho> seed, std::tuple<uint8_t, uint8_t> matrix_position) const {
86 return get_XOF(seed, matrix_position);
87 }
88
89 private:
92 ranges::contiguous_range... InputTs>
93 std::pair<T1, T2> G_split(InputTs&&... inputs) const {
94 auto& g = get_G();
95 (g.update(inputs), ...);
96 auto s = g.final();
97
98 BufferSlicer bs(s);
99 std::pair<T1, T2> result;
100 result.first = bs.copy<T1>(KyberConstants::SEED_BYTES);
101 result.second = bs.copy<T2>(KyberConstants::SEED_BYTES);
102 BOTAN_ASSERT_NOMSG(bs.empty());
103 return result;
104 }
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
#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 SEED_BYTES
virtual Botan::XOF & get_XOF(std::span< const uint8_t > seed, std::tuple< uint8_t, uint8_t > matrix_position) const =0
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
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
Botan::XOF & XOF(StrongSpan< const KyberSeedRho > seed, std::tuple< uint8_t, uint8_t > matrix_position) const
virtual HashFunction & get_J() const =0
std::pair< KyberSharedSecret, KyberEncryptionRandomness > G(StrongSpan< const KyberMessage > msg, StrongSpan< const KyberHashedPublicKey > pubkey_hash) const
KyberSharedSecret J(StrongSpan< const KyberImplicitRejectionValue > rejection_value, StrongSpan< const KyberCompressedCiphertext > ciphertext) const
virtual HashFunction & get_H() const =0
std::pair< KyberSeedRho, KyberSeedSigma > G(StrongSpan< const KyberSeedRandomness > seed, const KyberConstants &mode) const
virtual HashFunction & get_KDF() const =0
KyberHashedPublicKey H(StrongSpan< const KyberSerializedPublicKey > pk) const
virtual std::optional< std::array< uint8_t, 1 > > seed_expansion_domain_separator(const KyberConstants &mode) const =0
T output(size_t bytes)
Definition xof.h:155
std::variant< StrongSpan< const KyberSeedSigma >, StrongSpan< const KyberEncryptionRandomness > > KyberSigmaOrEncryptionRandomness
Variant value of either a KyberSeedSigma or a KyberEncryptionRandomness.
Definition kyber_types.h:70