Coverage Report

Created: 2023-02-13 06:21

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