/src/botan/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_parameters.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * SLH-DSA Parameters |
3 | | * (C) 2023 Jack Lloyd |
4 | | * 2023 Fabian Albert, René Meusel, Amos Treiber - Rohde & Schwarz Cybersecurity |
5 | | * |
6 | | * Botan is released under the Simplified BSD License (see license.txt) |
7 | | */ |
8 | | |
9 | | #include <botan/sp_parameters.h> |
10 | | |
11 | | #include <botan/assert.h> |
12 | | #include <botan/concepts.h> |
13 | | #include <botan/exceptn.h> |
14 | | #include <botan/internal/bit_ops.h> |
15 | | #include <botan/internal/fmt.h> |
16 | | |
17 | | #include <cmath> |
18 | | |
19 | | namespace Botan { |
20 | | |
21 | | namespace { |
22 | | /// @returns pair: (parameter set, hash type) |
23 | 68 | std::pair<Sphincs_Parameter_Set, Sphincs_Hash_Type> set_and_hash_from_name(std::string_view name) { |
24 | | // SPHINCS+ Round 3.1 instances |
25 | 68 | if(name == "SphincsPlus-sha2-128s-r3.1") { |
26 | 0 | return {Sphincs_Parameter_Set::Sphincs128Small, Sphincs_Hash_Type::Sha256}; |
27 | 0 | } |
28 | 68 | if(name == "SphincsPlus-sha2-128f-r3.1") { |
29 | 0 | return {Sphincs_Parameter_Set::Sphincs128Fast, Sphincs_Hash_Type::Sha256}; |
30 | 0 | } |
31 | 68 | if(name == "SphincsPlus-sha2-192s-r3.1") { |
32 | 0 | return {Sphincs_Parameter_Set::Sphincs192Small, Sphincs_Hash_Type::Sha256}; |
33 | 0 | } |
34 | 68 | if(name == "SphincsPlus-sha2-192f-r3.1") { |
35 | 0 | return {Sphincs_Parameter_Set::Sphincs192Fast, Sphincs_Hash_Type::Sha256}; |
36 | 0 | } |
37 | 68 | if(name == "SphincsPlus-sha2-256s-r3.1") { |
38 | 0 | return {Sphincs_Parameter_Set::Sphincs256Small, Sphincs_Hash_Type::Sha256}; |
39 | 0 | } |
40 | 68 | if(name == "SphincsPlus-sha2-256f-r3.1") { |
41 | 0 | return {Sphincs_Parameter_Set::Sphincs256Fast, Sphincs_Hash_Type::Sha256}; |
42 | 0 | } |
43 | | |
44 | 68 | if(name == "SphincsPlus-shake-128s-r3.1") { |
45 | 0 | return {Sphincs_Parameter_Set::Sphincs128Small, Sphincs_Hash_Type::Shake256}; |
46 | 0 | } |
47 | 68 | if(name == "SphincsPlus-shake-128f-r3.1") { |
48 | 0 | return {Sphincs_Parameter_Set::Sphincs128Fast, Sphincs_Hash_Type::Shake256}; |
49 | 0 | } |
50 | 68 | if(name == "SphincsPlus-shake-192s-r3.1") { |
51 | 0 | return {Sphincs_Parameter_Set::Sphincs192Small, Sphincs_Hash_Type::Shake256}; |
52 | 0 | } |
53 | 68 | if(name == "SphincsPlus-shake-192f-r3.1") { |
54 | 0 | return {Sphincs_Parameter_Set::Sphincs192Fast, Sphincs_Hash_Type::Shake256}; |
55 | 0 | } |
56 | 68 | if(name == "SphincsPlus-shake-256s-r3.1") { |
57 | 0 | return {Sphincs_Parameter_Set::Sphincs256Small, Sphincs_Hash_Type::Shake256}; |
58 | 0 | } |
59 | 68 | if(name == "SphincsPlus-shake-256f-r3.1") { |
60 | 0 | return {Sphincs_Parameter_Set::Sphincs256Fast, Sphincs_Hash_Type::Shake256}; |
61 | 0 | } |
62 | | |
63 | 68 | if(name == "SphincsPlus-haraka-128s-r3.1") { |
64 | 0 | return {Sphincs_Parameter_Set::Sphincs128Small, Sphincs_Hash_Type::Haraka}; |
65 | 0 | } |
66 | 68 | if(name == "SphincsPlus-haraka-128f-r3.1") { |
67 | 0 | return {Sphincs_Parameter_Set::Sphincs128Fast, Sphincs_Hash_Type::Haraka}; |
68 | 0 | } |
69 | 68 | if(name == "SphincsPlus-haraka-192s-r3.1") { |
70 | 0 | return {Sphincs_Parameter_Set::Sphincs192Small, Sphincs_Hash_Type::Haraka}; |
71 | 0 | } |
72 | 68 | if(name == "SphincsPlus-haraka-192f-r3.1") { |
73 | 0 | return {Sphincs_Parameter_Set::Sphincs192Fast, Sphincs_Hash_Type::Haraka}; |
74 | 0 | } |
75 | 68 | if(name == "SphincsPlus-haraka-256s-r3.1") { |
76 | 0 | return {Sphincs_Parameter_Set::Sphincs256Small, Sphincs_Hash_Type::Haraka}; |
77 | 0 | } |
78 | 68 | if(name == "SphincsPlus-haraka-256f-r3.1") { |
79 | 0 | return {Sphincs_Parameter_Set::Sphincs256Fast, Sphincs_Hash_Type::Haraka}; |
80 | 0 | } |
81 | | |
82 | | // SLH-DSA instances WITHOUT prehash mode |
83 | 68 | if(name == "SLH-DSA-SHA2-128s") { |
84 | 7 | return {Sphincs_Parameter_Set::SLHDSA128Small, Sphincs_Hash_Type::Sha256}; |
85 | 7 | } |
86 | 61 | if(name == "SLH-DSA-SHA2-128f") { |
87 | 7 | return {Sphincs_Parameter_Set::SLHDSA128Fast, Sphincs_Hash_Type::Sha256}; |
88 | 7 | } |
89 | 54 | if(name == "SLH-DSA-SHA2-192s") { |
90 | 5 | return {Sphincs_Parameter_Set::SLHDSA192Small, Sphincs_Hash_Type::Sha256}; |
91 | 5 | } |
92 | 49 | if(name == "SLH-DSA-SHA2-192f") { |
93 | 5 | return {Sphincs_Parameter_Set::SLHDSA192Fast, Sphincs_Hash_Type::Sha256}; |
94 | 5 | } |
95 | 44 | if(name == "SLH-DSA-SHA2-256s") { |
96 | 5 | return {Sphincs_Parameter_Set::SLHDSA256Small, Sphincs_Hash_Type::Sha256}; |
97 | 5 | } |
98 | 39 | if(name == "SLH-DSA-SHA2-256f") { |
99 | 5 | return {Sphincs_Parameter_Set::SLHDSA256Fast, Sphincs_Hash_Type::Sha256}; |
100 | 5 | } |
101 | | |
102 | 34 | if(name == "SLH-DSA-SHAKE-128s") { |
103 | 7 | return {Sphincs_Parameter_Set::SLHDSA128Small, Sphincs_Hash_Type::Shake256}; |
104 | 7 | } |
105 | 27 | if(name == "SLH-DSA-SHAKE-128f") { |
106 | 5 | return {Sphincs_Parameter_Set::SLHDSA128Fast, Sphincs_Hash_Type::Shake256}; |
107 | 5 | } |
108 | 22 | if(name == "SLH-DSA-SHAKE-192s") { |
109 | 7 | return {Sphincs_Parameter_Set::SLHDSA192Small, Sphincs_Hash_Type::Shake256}; |
110 | 7 | } |
111 | 15 | if(name == "SLH-DSA-SHAKE-192f") { |
112 | 5 | return {Sphincs_Parameter_Set::SLHDSA192Fast, Sphincs_Hash_Type::Shake256}; |
113 | 5 | } |
114 | 10 | if(name == "SLH-DSA-SHAKE-256s") { |
115 | 5 | return {Sphincs_Parameter_Set::SLHDSA256Small, Sphincs_Hash_Type::Shake256}; |
116 | 5 | } |
117 | 5 | if(name == "SLH-DSA-SHAKE-256f") { |
118 | 5 | return {Sphincs_Parameter_Set::SLHDSA256Fast, Sphincs_Hash_Type::Shake256}; |
119 | 5 | } |
120 | | |
121 | | // SLH-DSA instances WITH prehash mode |
122 | 0 | if(name == "Hash-SLH-DSA-SHA2-128s-with-SHA256") { |
123 | 0 | return {Sphincs_Parameter_Set::SLHDSA128Small, Sphincs_Hash_Type::Sha256}; |
124 | 0 | } |
125 | 0 | if(name == "Hash-SLH-DSA-SHA2-128f-with-SHA256") { |
126 | 0 | return {Sphincs_Parameter_Set::SLHDSA128Fast, Sphincs_Hash_Type::Sha256}; |
127 | 0 | } |
128 | 0 | if(name == "Hash-SLH-DSA-SHA2-192s-with-SHA512") { |
129 | 0 | return {Sphincs_Parameter_Set::SLHDSA192Small, Sphincs_Hash_Type::Sha256}; |
130 | 0 | } |
131 | 0 | if(name == "Hash-SLH-DSA-SHA2-192f-with-SHA512") { |
132 | 0 | return {Sphincs_Parameter_Set::SLHDSA192Fast, Sphincs_Hash_Type::Sha256}; |
133 | 0 | } |
134 | 0 | if(name == "Hash-SLH-DSA-SHA2-256s-with-SHA512") { |
135 | 0 | return {Sphincs_Parameter_Set::SLHDSA256Small, Sphincs_Hash_Type::Sha256}; |
136 | 0 | } |
137 | 0 | if(name == "Hash-SLH-DSA-SHA2-256f-with-SHA512") { |
138 | 0 | return {Sphincs_Parameter_Set::SLHDSA256Fast, Sphincs_Hash_Type::Sha256}; |
139 | 0 | } |
140 | | |
141 | 0 | if(name == "Hash-SLH-DSA-SHAKE-128s-with-SHAKE128") { |
142 | 0 | return {Sphincs_Parameter_Set::SLHDSA128Small, Sphincs_Hash_Type::Shake256}; |
143 | 0 | } |
144 | 0 | if(name == "Hash-SLH-DSA-SHAKE-128f-with-SHAKE128") { |
145 | 0 | return {Sphincs_Parameter_Set::SLHDSA128Fast, Sphincs_Hash_Type::Shake256}; |
146 | 0 | } |
147 | 0 | if(name == "Hash-SLH-DSA-SHAKE-192s-with-SHAKE256") { |
148 | 0 | return {Sphincs_Parameter_Set::SLHDSA192Small, Sphincs_Hash_Type::Shake256}; |
149 | 0 | } |
150 | 0 | if(name == "Hash-SLH-DSA-SHAKE-192f-with-SHAKE256") { |
151 | 0 | return {Sphincs_Parameter_Set::SLHDSA192Fast, Sphincs_Hash_Type::Shake256}; |
152 | 0 | } |
153 | 0 | if(name == "Hash-SLH-DSA-SHAKE-256s-with-SHAKE256") { |
154 | 0 | return {Sphincs_Parameter_Set::SLHDSA256Small, Sphincs_Hash_Type::Shake256}; |
155 | 0 | } |
156 | 0 | if(name == "Hash-SLH-DSA-SHAKE-256f-with-SHAKE256") { |
157 | 0 | return {Sphincs_Parameter_Set::SLHDSA256Fast, Sphincs_Hash_Type::Shake256}; |
158 | 0 | } |
159 | | |
160 | 0 | throw Lookup_Error(fmt("No SLH-DSA (or SPHINCS+) parameter supported for: {}", name)); |
161 | 0 | } |
162 | | |
163 | 0 | std::string name_from_set_and_hash(Sphincs_Parameter_Set set, Sphincs_Hash_Type hash) { |
164 | 0 | if(hash == Sphincs_Hash_Type::Sha256) { |
165 | 0 | switch(set) { |
166 | 0 | case Sphincs_Parameter_Set::Sphincs128Small: |
167 | 0 | return "SphincsPlus-sha2-128s-r3.1"; |
168 | 0 | case Sphincs_Parameter_Set::Sphincs128Fast: |
169 | 0 | return "SphincsPlus-sha2-128f-r3.1"; |
170 | 0 | case Sphincs_Parameter_Set::Sphincs192Small: |
171 | 0 | return "SphincsPlus-sha2-192s-r3.1"; |
172 | 0 | case Sphincs_Parameter_Set::Sphincs192Fast: |
173 | 0 | return "SphincsPlus-sha2-192f-r3.1"; |
174 | 0 | case Sphincs_Parameter_Set::Sphincs256Small: |
175 | 0 | return "SphincsPlus-sha2-256s-r3.1"; |
176 | 0 | case Sphincs_Parameter_Set::Sphincs256Fast: |
177 | 0 | return "SphincsPlus-sha2-256f-r3.1"; |
178 | | |
179 | 0 | case Sphincs_Parameter_Set::SLHDSA128Small: |
180 | 0 | return "SLH-DSA-SHA2-128s"; |
181 | 0 | case Sphincs_Parameter_Set::SLHDSA128Fast: |
182 | 0 | return "SLH-DSA-SHA2-128f"; |
183 | 0 | case Sphincs_Parameter_Set::SLHDSA192Small: |
184 | 0 | return "SLH-DSA-SHA2-192s"; |
185 | 0 | case Sphincs_Parameter_Set::SLHDSA192Fast: |
186 | 0 | return "SLH-DSA-SHA2-192f"; |
187 | 0 | case Sphincs_Parameter_Set::SLHDSA256Small: |
188 | 0 | return "SLH-DSA-SHA2-256s"; |
189 | 0 | case Sphincs_Parameter_Set::SLHDSA256Fast: |
190 | 0 | return "SLH-DSA-SHA2-256f"; |
191 | 0 | } |
192 | 0 | } |
193 | | |
194 | 0 | if(hash == Sphincs_Hash_Type::Shake256) { |
195 | 0 | switch(set) { |
196 | 0 | case Sphincs_Parameter_Set::Sphincs128Small: |
197 | 0 | return "SphincsPlus-shake-128s-r3.1"; |
198 | 0 | case Sphincs_Parameter_Set::Sphincs128Fast: |
199 | 0 | return "SphincsPlus-shake-128f-r3.1"; |
200 | 0 | case Sphincs_Parameter_Set::Sphincs192Small: |
201 | 0 | return "SphincsPlus-shake-192s-r3.1"; |
202 | 0 | case Sphincs_Parameter_Set::Sphincs192Fast: |
203 | 0 | return "SphincsPlus-shake-192f-r3.1"; |
204 | 0 | case Sphincs_Parameter_Set::Sphincs256Small: |
205 | 0 | return "SphincsPlus-shake-256s-r3.1"; |
206 | 0 | case Sphincs_Parameter_Set::Sphincs256Fast: |
207 | 0 | return "SphincsPlus-shake-256f-r3.1"; |
208 | | |
209 | 0 | case Sphincs_Parameter_Set::SLHDSA128Small: |
210 | 0 | return "SLH-DSA-SHAKE-128s"; |
211 | 0 | case Sphincs_Parameter_Set::SLHDSA128Fast: |
212 | 0 | return "SLH-DSA-SHAKE-128f"; |
213 | 0 | case Sphincs_Parameter_Set::SLHDSA192Small: |
214 | 0 | return "SLH-DSA-SHAKE-192s"; |
215 | 0 | case Sphincs_Parameter_Set::SLHDSA192Fast: |
216 | 0 | return "SLH-DSA-SHAKE-192f"; |
217 | 0 | case Sphincs_Parameter_Set::SLHDSA256Small: |
218 | 0 | return "SLH-DSA-SHAKE-256s"; |
219 | 0 | case Sphincs_Parameter_Set::SLHDSA256Fast: |
220 | 0 | return "SLH-DSA-SHAKE-256f"; |
221 | 0 | } |
222 | 0 | } |
223 | | |
224 | 0 | if(hash == Sphincs_Hash_Type::Haraka) { |
225 | 0 | switch(set) { |
226 | 0 | case Sphincs_Parameter_Set::Sphincs128Small: |
227 | 0 | return "SphincsPlus-haraka-128s-r3.1"; |
228 | 0 | case Sphincs_Parameter_Set::Sphincs128Fast: |
229 | 0 | return "SphincsPlus-haraka-128f-r3.1"; |
230 | 0 | case Sphincs_Parameter_Set::Sphincs192Small: |
231 | 0 | return "SphincsPlus-haraka-192s-r3.1"; |
232 | 0 | case Sphincs_Parameter_Set::Sphincs192Fast: |
233 | 0 | return "SphincsPlus-haraka-192f-r3.1"; |
234 | 0 | case Sphincs_Parameter_Set::Sphincs256Small: |
235 | 0 | return "SphincsPlus-haraka-256s-r3.1"; |
236 | 0 | case Sphincs_Parameter_Set::Sphincs256Fast: |
237 | 0 | return "SphincsPlus-haraka-256f-r3.1"; |
238 | | |
239 | 0 | case Sphincs_Parameter_Set::SLHDSA128Small: |
240 | 0 | case Sphincs_Parameter_Set::SLHDSA128Fast: |
241 | 0 | case Sphincs_Parameter_Set::SLHDSA192Small: |
242 | 0 | case Sphincs_Parameter_Set::SLHDSA192Fast: |
243 | 0 | case Sphincs_Parameter_Set::SLHDSA256Small: |
244 | 0 | case Sphincs_Parameter_Set::SLHDSA256Fast: |
245 | 0 | throw Invalid_Argument("SLH-DSA does not support Haraka"); |
246 | 0 | } |
247 | 0 | } |
248 | 0 | throw Invalid_Argument("Cannot serialize invalid parameter combination"); |
249 | 0 | } |
250 | | |
251 | 0 | constexpr bool is_slh_dsa_set(Sphincs_Parameter_Set set) { |
252 | 0 | switch(set) { |
253 | 0 | case Sphincs_Parameter_Set::SLHDSA128Small: |
254 | 0 | case Sphincs_Parameter_Set::SLHDSA128Fast: |
255 | 0 | case Sphincs_Parameter_Set::SLHDSA192Small: |
256 | 0 | case Sphincs_Parameter_Set::SLHDSA192Fast: |
257 | 0 | case Sphincs_Parameter_Set::SLHDSA256Small: |
258 | 0 | case Sphincs_Parameter_Set::SLHDSA256Fast: |
259 | 0 | return true; |
260 | 0 | case Sphincs_Parameter_Set::Sphincs128Small: |
261 | 0 | case Sphincs_Parameter_Set::Sphincs128Fast: |
262 | 0 | case Sphincs_Parameter_Set::Sphincs192Small: |
263 | 0 | case Sphincs_Parameter_Set::Sphincs192Fast: |
264 | 0 | case Sphincs_Parameter_Set::Sphincs256Small: |
265 | 0 | case Sphincs_Parameter_Set::Sphincs256Fast: |
266 | 0 | return false; |
267 | 0 | } |
268 | 0 | BOTAN_ASSERT_UNREACHABLE(); |
269 | 0 | } |
270 | | |
271 | | } // namespace |
272 | | |
273 | | Sphincs_Parameters::Sphincs_Parameters(Sphincs_Parameter_Set set, |
274 | | Sphincs_Hash_Type hash_type, |
275 | | uint32_t n, |
276 | | uint32_t h, |
277 | | uint32_t d, |
278 | | uint32_t a, |
279 | | uint32_t k, |
280 | | uint32_t w, |
281 | | uint32_t bitsec) : |
282 | 68 | m_set(set), m_hash_type(hash_type), m_n(n), m_h(h), m_d(d), m_a(a), m_k(k), m_w(w), m_bitsec(bitsec) { |
283 | 68 | BOTAN_ARG_CHECK(!(hash_type == Sphincs_Hash_Type::Haraka && is_slh_dsa_set(set)), |
284 | 68 | "Haraka is not available for SLH-DSA"); |
285 | 68 | BOTAN_ARG_CHECK(w == 4 || w == 16 || w == 256, "Winternitz parameter must be one of 4, 16, 256"); |
286 | 68 | BOTAN_ARG_CHECK(n == 16 || n == 24 || n == 32, "n must be one of 16, 24, 32"); |
287 | 68 | BOTAN_ARG_CHECK(m_d > 0, "d must be greater than zero"); |
288 | | |
289 | 68 | m_xmss_tree_height = m_h / m_d; |
290 | 68 | m_lg_w = ceil_log2(m_w); |
291 | | |
292 | | // base_2^b algorithm (Fips 205, Algorithm 4) only works |
293 | | // when m_log_w is a divisor of 8. |
294 | 68 | BOTAN_ASSERT_NOMSG(m_lg_w <= 8 && 8 % m_lg_w == 0); |
295 | | |
296 | | // # Winternitz blocks of the message (len_1 of FIPS 205, Algorithm 1) |
297 | 68 | m_wots_len1 = (m_n * 8) / m_lg_w; |
298 | | |
299 | | // # Winternitz blocks of the checksum (output of FIPS 205 Algorithm 1) |
300 | 68 | m_wots_len2 = ceil_log2(m_wots_len1 * (m_w - 1)) / m_lg_w + 1; |
301 | | |
302 | | // # Winternitz blocks in the signature (len of FIPS 205, Equation 5.4) |
303 | 68 | m_wots_len = m_wots_len1 + m_wots_len2; |
304 | | |
305 | | // byte length of WOTS+ signature as well as public key |
306 | 68 | m_wots_bytes = m_wots_len * m_n; |
307 | | |
308 | | // # of bytes the WOTS+ checksum consists of |
309 | 68 | m_wots_checksum_bytes = ceil_tobytes(m_wots_len2 * m_lg_w); |
310 | | |
311 | 68 | m_fors_sig_bytes = (m_a + 1) * m_k * m_n; |
312 | | |
313 | | // byte length of the FORS input message |
314 | 68 | m_fors_message_bytes = ceil_tobytes(m_k * m_a); |
315 | | |
316 | 68 | m_xmss_sig_bytes = m_wots_bytes + m_xmss_tree_height * m_n; |
317 | 68 | m_ht_sig_bytes = m_d * m_xmss_sig_bytes; |
318 | 68 | m_sp_sig_bytes = m_n /* random */ + m_fors_sig_bytes + m_ht_sig_bytes; |
319 | | |
320 | 68 | m_tree_digest_bytes = ceil_tobytes(m_h - m_xmss_tree_height); |
321 | 68 | m_leaf_digest_bytes = ceil_tobytes(m_xmss_tree_height); |
322 | 68 | m_h_msg_digest_bytes = m_fors_message_bytes + m_tree_digest_bytes + m_leaf_digest_bytes; |
323 | 68 | } |
324 | | |
325 | 0 | bool Sphincs_Parameters::is_available() const { |
326 | 0 | [[maybe_unused]] const bool is_slh_dsa = is_slh_dsa_set(m_set); |
327 | 0 | #ifdef BOTAN_HAS_SLH_DSA_WITH_SHA2 |
328 | 0 | if(is_slh_dsa && m_hash_type == Sphincs_Hash_Type::Sha256) { |
329 | 0 | return true; |
330 | 0 | } |
331 | 0 | #endif |
332 | 0 | #ifdef BOTAN_HAS_SLH_DSA_WITH_SHAKE |
333 | 0 | if(is_slh_dsa && m_hash_type == Sphincs_Hash_Type::Shake256) { |
334 | 0 | return true; |
335 | 0 | } |
336 | 0 | #endif |
337 | 0 | #ifdef BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2 |
338 | 0 | if(!is_slh_dsa && m_hash_type == Sphincs_Hash_Type::Sha256) { |
339 | 0 | return true; |
340 | 0 | } |
341 | 0 | #endif |
342 | 0 | #ifdef BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE |
343 | 0 | if(!is_slh_dsa && m_hash_type == Sphincs_Hash_Type::Shake256) { |
344 | 0 | return true; |
345 | 0 | } |
346 | 0 | #endif |
347 | 0 | return false; |
348 | 0 | } |
349 | | |
350 | | Sphincs_Parameters Sphincs_Parameters::create( |
351 | 68 | Sphincs_Parameter_Set set, Sphincs_Hash_Type hash /*, SlhDsaInputMode input_mode [TODO: prehash mode]*/) { |
352 | | // See FIPS 205, Table 2 |
353 | 68 | switch(set) { |
354 | 0 | case Sphincs_Parameter_Set::Sphincs128Small: |
355 | 14 | case Sphincs_Parameter_Set::SLHDSA128Small: |
356 | 14 | return Sphincs_Parameters(set, hash, 16, 63, 7, 12, 14, 16, 133); |
357 | 0 | case Sphincs_Parameter_Set::Sphincs128Fast: |
358 | 12 | case Sphincs_Parameter_Set::SLHDSA128Fast: |
359 | 12 | return Sphincs_Parameters(set, hash, 16, 66, 22, 6, 33, 16, 128); |
360 | | |
361 | 0 | case Sphincs_Parameter_Set::Sphincs192Small: |
362 | 12 | case Sphincs_Parameter_Set::SLHDSA192Small: |
363 | 12 | return Sphincs_Parameters(set, hash, 24, 63, 7, 14, 17, 16, 193); |
364 | 0 | case Sphincs_Parameter_Set::Sphincs192Fast: |
365 | 10 | case Sphincs_Parameter_Set::SLHDSA192Fast: |
366 | 10 | return Sphincs_Parameters(set, hash, 24, 66, 22, 8, 33, 16, 194); |
367 | | |
368 | 0 | case Sphincs_Parameter_Set::Sphincs256Small: |
369 | 10 | case Sphincs_Parameter_Set::SLHDSA256Small: |
370 | 10 | return Sphincs_Parameters(set, hash, 32, 64, 8, 14, 22, 16, 255); |
371 | 0 | case Sphincs_Parameter_Set::Sphincs256Fast: |
372 | 10 | case Sphincs_Parameter_Set::SLHDSA256Fast: |
373 | 10 | return Sphincs_Parameters(set, hash, 32, 68, 17, 9, 35, 16, 255); |
374 | 68 | } |
375 | 0 | BOTAN_ASSERT_UNREACHABLE(); |
376 | 0 | } |
377 | | |
378 | 68 | Sphincs_Parameters Sphincs_Parameters::create(std::string_view name) { |
379 | 68 | auto [param_set, hash_type] = set_and_hash_from_name(name); |
380 | 68 | return Sphincs_Parameters::create(param_set, hash_type); |
381 | 68 | } |
382 | | |
383 | 0 | bool Sphincs_Parameters::is_slh_dsa() const { |
384 | 0 | return is_slh_dsa_set(m_set); |
385 | 0 | } |
386 | | |
387 | 0 | std::string Sphincs_Parameters::hash_name() const { |
388 | 0 | switch(m_hash_type) { |
389 | 0 | case Sphincs_Hash_Type::Sha256: |
390 | 0 | return "SHA-256"; |
391 | 0 | case Sphincs_Hash_Type::Shake256: |
392 | 0 | return fmt("SHAKE-256({})", 8 * n()); |
393 | 0 | case Sphincs_Hash_Type::Haraka: |
394 | 0 | return "Haraka"; |
395 | 0 | } |
396 | 0 | BOTAN_ASSERT_UNREACHABLE(); |
397 | 0 | } |
398 | | |
399 | 0 | std::string Sphincs_Parameters::to_string() const { |
400 | 0 | return name_from_set_and_hash(parameter_set(), hash_type()); |
401 | 0 | } |
402 | | |
403 | 68 | Sphincs_Parameters Sphincs_Parameters::create(const OID& oid) { |
404 | 68 | return Sphincs_Parameters::create(oid.to_formatted_string()); |
405 | 68 | } |
406 | | |
407 | 0 | OID Sphincs_Parameters::object_identifier() const { |
408 | 0 | return OID::from_string(to_string()); |
409 | 0 | } |
410 | | |
411 | 0 | AlgorithmIdentifier Sphincs_Parameters::algorithm_identifier() const { |
412 | 0 | return AlgorithmIdentifier(object_identifier(), AlgorithmIdentifier::USE_EMPTY_PARAM); |
413 | 0 | } |
414 | | |
415 | | } // namespace Botan |