Botan 3.0.0
Crypto and TLS for C&
dilithium_symmetric_primitives.h
Go to the documentation of this file.
1/*
2* Asymmetric primitives for dilithium
3* (C) 2022-2023 Jack Lloyd
4* (C) 2022-2023 Michael Boric, René Meusel - Rohde & Schwarz Cybersecurity
5* (C) 2022 Manuel Glaser - Rohde & Schwarz Cybersecurity
6*
7* Botan is released under the Simplified BSD License (see license.txt)
8*/
9
10#ifndef BOTAN_DILITHIUM_ASYM_PRIMITIVES_H_
11#define BOTAN_DILITHIUM_ASYM_PRIMITIVES_H_
12
13#include <botan/dilithium.h>
14#include <botan/stream_cipher.h>
15
16#include <botan/internal/shake.h>
17
18#include <memory>
19#include <vector>
20#include <span>
21
22namespace Botan {
23
24/**
25* Adapter class that uses polymorphy to distinguish
26* Dilithium "common" from Dilithium "AES" modes.
27*/
29 {
30 public:
31 enum class XofType
32 {
33 k128,
34 k256
35 };
36
37 public:
38 static std::unique_ptr<Dilithium_Symmetric_Primitives> create(DilithiumMode mode);
39
41
42 // H is same for all modes
43 secure_vector<uint8_t> H(std::span<const uint8_t> seed, size_t out_len) const
44 {
45 return SHAKE_256(out_len * 8).process(seed.data(), seed.size());
46 }
47
48 // CRH is same for all modes
49 secure_vector<uint8_t> CRH(std::span<const uint8_t> in, size_t out_len) const
50 {
51 return SHAKE_256(out_len * 8).process(in.data(), in.size());
52 }
53
54 // ExpandMatrix always uses the 256 version of the XOF
55 secure_vector<uint8_t> ExpandMask(std::span<const uint8_t> seed,
56 uint16_t nonce, size_t out_len) const
57 {
58 return XOF(XofType::k256, seed, nonce)->keystream_bytes(out_len);
59 }
60
61 // Mode dependent function
62 virtual std::unique_ptr<StreamCipher> XOF(const XofType type, std::span<const uint8_t> seed,
63 uint16_t matrix_position) const = 0;
64 };
65
66enum DilithiumEta : uint32_t
67 {
68 Eta2 = 2,
69 Eta4 = 4
70 };
71
72// Constants and mode dependent values
74 {
75 public:
76
77 static constexpr int32_t SEEDBYTES = 32;
78 static constexpr int32_t CRHBYTES = 64;
79 static constexpr int32_t N = 256;
80 static constexpr int32_t Q = 8380417;
81 static constexpr int32_t D = 13;
82 static constexpr int32_t ROOT_OF_UNITY = 1753;
83 static constexpr int32_t POLYT1_PACKEDBYTES = 320;
84 static constexpr int32_t POLYT0_PACKEDBYTES = 416;
85 static constexpr int32_t SHAKE128_RATE = 168;
86 static constexpr int32_t SHAKE256_RATE = 136;
87 static constexpr int32_t SHA3_256_RATE = 136;
88 static constexpr int32_t SHA3_512_RATE = 72;
89 static constexpr int32_t AES256CTR_BLOCKBYTES = 64;
90 static constexpr int32_t QINV = 58728449;
91 static constexpr int32_t ZETAS[DilithiumModeConstants::N] =
92 {
93 0, 25847, -2608894, -518909, 237124, -777960, -876248, 466468,
94 1826347, 2353451, -359251, -2091905, 3119733, -2884855, 3111497, 2680103,
95 2725464, 1024112, -1079900, 3585928, -549488, -1119584, 2619752, -2108549,
96 -2118186, -3859737, -1399561, -3277672, 1757237, -19422, 4010497, 280005,
97 2706023, 95776, 3077325, 3530437, -1661693, -3592148, -2537516, 3915439,
98 -3861115, -3043716, 3574422, -2867647, 3539968, -300467, 2348700, -539299,
99 -1699267, -1643818, 3505694, -3821735, 3507263, -2140649, -1600420, 3699596,
100 811944, 531354, 954230, 3881043, 3900724, -2556880, 2071892, -2797779,
101 -3930395, -1528703, -3677745, -3041255, -1452451, 3475950, 2176455, -1585221,
102 -1257611, 1939314, -4083598, -1000202, -3190144, -3157330, -3632928, 126922,
103 3412210, -983419, 2147896, 2715295, -2967645, -3693493, -411027, -2477047,
104 -671102, -1228525, -22981, -1308169, -381987, 1349076, 1852771, -1430430,
105 -3343383, 264944, 508951, 3097992, 44288, -1100098, 904516, 3958618,
106 -3724342, -8578, 1653064, -3249728, 2389356, -210977, 759969, -1316856,
107 189548, -3553272, 3159746, -1851402, -2409325, -177440, 1315589, 1341330,
108 1285669, -1584928, -812732, -1439742, -3019102, -3881060, -3628969, 3839961,
109 2091667, 3407706, 2316500, 3817976, -3342478, 2244091, -2446433, -3562462,
110 266997, 2434439, -1235728, 3513181, -3520352, -3759364, -1197226, -3193378,
111 900702, 1859098, 909542, 819034, 495491, -1613174, -43260, -522500,
112 -655327, -3122442, 2031748, 3207046, -3556995, -525098, -768622, -3595838,
113 342297, 286988, -2437823, 4108315, 3437287, -3342277, 1735879, 203044,
114 2842341, 2691481, -2590150, 1265009, 4055324, 1247620, 2486353, 1595974,
115 -3767016, 1250494, 2635921, -3548272, -2994039, 1869119, 1903435, -1050970,
116 -1333058, 1237275, -3318210, -1430225, -451100, 1312455, 3306115, -1962642,
117 -1279661, 1917081, -2546312, -1374803, 1500165, 777191, 2235880, 3406031,
118 -542412, -2831860, -1671176, -1846953, -2584293, -3724270, 594136, -3776993,
119 -2013608, 2432395, 2454455, -164721, 1957272, 3369112, 185531, -1207385,
120 -3183426, 162844, 1616392, 3014001, 810149, 1652634, -3694233, -1799107,
121 -3038916, 3523897, 3866901, 269760, 2213111, -975884, 1717735, 472078,
122 -426683, 1723600, -1803090, 1910376, -1667432, -1104333, -260646, -3833893,
123 -2939036, -2235985, -420899, -2286327, 183443, -976891, 1612842, -3545687,
124 -554416, 3919660, -48306, -1362209, 3937738, 1400424, -846154, 1976782
125 };
127
129
131 : DilithiumModeConstants(other.m_mode) {}
132
136
137 // Getter
138 uint8_t k() const
139 {
140 return m_k;
141 }
142 uint8_t l() const
143 {
144 return m_l;
145 }
147 {
148 return m_eta;
149 }
150 size_t tau() const
151 {
152 return m_tau;
153 }
155 {
156 return m_poly_uniform_gamma1_nblocks;
157 }
158 size_t stream256_blockbytes() const
159 {
160 return m_stream256_blockbytes;
161 }
162 size_t stream128_blockbytes() const
163 {
164 return m_stream128_blockbytes;
165 }
166 size_t polyw1_packedbytes() const
167 {
168 return m_polyw1_packedbytes;
169 }
170 size_t omega() const
171 {
172 return m_omega;
173 }
174 size_t polyz_packedbytes() const
175 {
176 return m_polyz_packedbytes;
177 }
178 size_t gamma2() const
179 {
180 return m_gamma2;
181 }
182 size_t gamma1() const
183 {
184 return m_gamma1;
185 }
186 size_t beta() const
187 {
188 return m_beta;
189 }
191 {
192 return m_poly_uniform_eta_nblocks;
193 }
194 size_t poly_uniform_nblocks() const
195 {
196 return m_poly_uniform_nblocks;
197 }
198 size_t polyeta_packedbytes() const
199 {
200 return m_polyeta_packedbytes;
201 }
202 size_t public_key_bytes() const
203 {
204 return m_public_key_bytes;
205 }
206 size_t crypto_bytes() const
207 {
208 return m_crypto_bytes;
209 }
210 OID oid() const
211 {
212 return m_mode.object_identifier();
213 }
214 size_t private_key_bytes() const
215 {
216 return m_private_key_bytes;
217 }
218
220 {
221 return m_nist_security_strength;
222 }
223
224 // Wrapper
225 decltype(auto) H(std::span<const uint8_t> seed, size_t out_len) const
226 {
227 return m_symmetric_primitives->H(seed, out_len);
228 }
229
230 secure_vector<uint8_t> CRH(const std::span<const uint8_t> in) const
231 {
232 return m_symmetric_primitives->CRH(in, DilithiumModeConstants::CRHBYTES);
233 }
234
235 std::unique_ptr<StreamCipher> XOF_128(std::span<const uint8_t> seed,
236 uint16_t nonce) const
237 {
238 return this->m_symmetric_primitives->XOF(Dilithium_Symmetric_Primitives::XofType::k128, seed, nonce);
239 }
240 std::unique_ptr<StreamCipher> XOF_256(std::span<const uint8_t> seed,
241 uint16_t nonce) const
242 {
243 return this->m_symmetric_primitives->XOF(Dilithium_Symmetric_Primitives::XofType::k256, seed, nonce);
244 }
245
247 {
248 return this->m_symmetric_primitives->ExpandMask(seed, nonce,
250 }
251
252 private:
253 DilithiumMode m_mode;
254
255 uint16_t m_nist_security_strength;
256
257 // generated matrix dimension is m_k x m_l
258 uint8_t m_k;
259 uint8_t m_l;
260 DilithiumEta m_eta;
261 int32_t m_tau;
262 int32_t m_beta;
263 int32_t m_gamma1;
264 int32_t m_gamma2;
265 int32_t m_omega;
266 int32_t m_stream128_blockbytes;
267 int32_t m_stream256_blockbytes;
268 int32_t m_poly_uniform_nblocks;
269 int32_t m_poly_uniform_eta_nblocks;
270 int32_t m_poly_uniform_gamma1_nblocks;
271 int32_t m_polyvech_packedbytes;
272 int32_t m_polyz_packedbytes;
273 int32_t m_polyw1_packedbytes;
274 int32_t m_polyeta_packedbytes;
275 int32_t m_private_key_bytes;
276 int32_t m_public_key_bytes;
277 int32_t m_crypto_bytes;
278
279 // Mode dependent primitives
280 std::unique_ptr<Dilithium_Symmetric_Primitives> m_symmetric_primitives;
281 };
282} // namespace Botan
283
284#endif
T process(const uint8_t in[], size_t length)
Definition: buf_comp.h:117
DilithiumModeConstants & operator=(const DilithiumModeConstants &other)=delete
static constexpr int32_t kSerializedPolynomialByteLength
secure_vector< uint8_t > CRH(const std::span< const uint8_t > in) const
std::unique_ptr< StreamCipher > XOF_128(std::span< const uint8_t > seed, uint16_t nonce) const
DilithiumModeConstants & operator=(DilithiumModeConstants &&other)=default
DilithiumModeConstants(const DilithiumModeConstants &other)
secure_vector< uint8_t > ExpandMask(const secure_vector< uint8_t > &seed, uint16_t nonce) const
static constexpr int32_t ZETAS[DilithiumModeConstants::N]
decltype(auto) H(std::span< const uint8_t > seed, size_t out_len) const
std::unique_ptr< StreamCipher > XOF_256(std::span< const uint8_t > seed, uint16_t nonce) const
DilithiumModeConstants(DilithiumModeConstants &&other)=default
OID object_identifier() const
Definition: dilithium.cpp:90
secure_vector< uint8_t > CRH(std::span< const uint8_t > in, size_t out_len) const
secure_vector< uint8_t > ExpandMask(std::span< const uint8_t > seed, uint16_t nonce, size_t out_len) const
secure_vector< uint8_t > H(std::span< const uint8_t > seed, size_t out_len) const
virtual std::unique_ptr< StreamCipher > XOF(const XofType type, std::span< const uint8_t > seed, uint16_t matrix_position) const =0
static std::unique_ptr< Dilithium_Symmetric_Primitives > create(DilithiumMode mode)
virtual ~Dilithium_Symmetric_Primitives()=default
Definition: alg_id.cpp:12
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:64