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