9#include <botan/sp_parameters.h>
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>
23std::pair<Sphincs_Parameter_Set, Sphincs_Hash_Type> set_and_hash_from_name(std::string_view name) {
25 if(name ==
"SphincsPlus-sha2-128s-r3.1") {
28 if(name ==
"SphincsPlus-sha2-128f-r3.1") {
31 if(name ==
"SphincsPlus-sha2-192s-r3.1") {
34 if(name ==
"SphincsPlus-sha2-192f-r3.1") {
37 if(name ==
"SphincsPlus-sha2-256s-r3.1") {
40 if(name ==
"SphincsPlus-sha2-256f-r3.1") {
44 if(name ==
"SphincsPlus-shake-128s-r3.1") {
47 if(name ==
"SphincsPlus-shake-128f-r3.1") {
50 if(name ==
"SphincsPlus-shake-192s-r3.1") {
53 if(name ==
"SphincsPlus-shake-192f-r3.1") {
56 if(name ==
"SphincsPlus-shake-256s-r3.1") {
59 if(name ==
"SphincsPlus-shake-256f-r3.1") {
63 if(name ==
"SphincsPlus-haraka-128s-r3.1") {
66 if(name ==
"SphincsPlus-haraka-128f-r3.1") {
69 if(name ==
"SphincsPlus-haraka-192s-r3.1") {
72 if(name ==
"SphincsPlus-haraka-192f-r3.1") {
75 if(name ==
"SphincsPlus-haraka-256s-r3.1") {
78 if(name ==
"SphincsPlus-haraka-256f-r3.1") {
83 if(name ==
"SLH-DSA-SHA2-128s") {
86 if(name ==
"SLH-DSA-SHA2-128f") {
89 if(name ==
"SLH-DSA-SHA2-192s") {
92 if(name ==
"SLH-DSA-SHA2-192f") {
95 if(name ==
"SLH-DSA-SHA2-256s") {
98 if(name ==
"SLH-DSA-SHA2-256f") {
102 if(name ==
"SLH-DSA-SHAKE-128s") {
105 if(name ==
"SLH-DSA-SHAKE-128f") {
108 if(name ==
"SLH-DSA-SHAKE-192s") {
111 if(name ==
"SLH-DSA-SHAKE-192f") {
114 if(name ==
"SLH-DSA-SHAKE-256s") {
117 if(name ==
"SLH-DSA-SHAKE-256f") {
122 if(name ==
"Hash-SLH-DSA-SHA2-128s-with-SHA256") {
125 if(name ==
"Hash-SLH-DSA-SHA2-128f-with-SHA256") {
128 if(name ==
"Hash-SLH-DSA-SHA2-192s-with-SHA512") {
131 if(name ==
"Hash-SLH-DSA-SHA2-192f-with-SHA512") {
134 if(name ==
"Hash-SLH-DSA-SHA2-256s-with-SHA512") {
137 if(name ==
"Hash-SLH-DSA-SHA2-256f-with-SHA512") {
141 if(name ==
"Hash-SLH-DSA-SHAKE-128s-with-SHAKE128") {
144 if(name ==
"Hash-SLH-DSA-SHAKE-128f-with-SHAKE128") {
147 if(name ==
"Hash-SLH-DSA-SHAKE-192s-with-SHAKE256") {
150 if(name ==
"Hash-SLH-DSA-SHAKE-192f-with-SHAKE256") {
153 if(name ==
"Hash-SLH-DSA-SHAKE-256s-with-SHAKE256") {
156 if(name ==
"Hash-SLH-DSA-SHAKE-256f-with-SHAKE256") {
160 throw Lookup_Error(
fmt(
"No SLH-DSA (or SPHINCS+) parameter supported for: {}", name));
167 return "SphincsPlus-sha2-128s-r3.1";
169 return "SphincsPlus-sha2-128f-r3.1";
171 return "SphincsPlus-sha2-192s-r3.1";
173 return "SphincsPlus-sha2-192f-r3.1";
175 return "SphincsPlus-sha2-256s-r3.1";
177 return "SphincsPlus-sha2-256f-r3.1";
180 return "SLH-DSA-SHA2-128s";
182 return "SLH-DSA-SHA2-128f";
184 return "SLH-DSA-SHA2-192s";
186 return "SLH-DSA-SHA2-192f";
188 return "SLH-DSA-SHA2-256s";
190 return "SLH-DSA-SHA2-256f";
197 return "SphincsPlus-shake-128s-r3.1";
199 return "SphincsPlus-shake-128f-r3.1";
201 return "SphincsPlus-shake-192s-r3.1";
203 return "SphincsPlus-shake-192f-r3.1";
205 return "SphincsPlus-shake-256s-r3.1";
207 return "SphincsPlus-shake-256f-r3.1";
210 return "SLH-DSA-SHAKE-128s";
212 return "SLH-DSA-SHAKE-128f";
214 return "SLH-DSA-SHAKE-192s";
216 return "SLH-DSA-SHAKE-192f";
218 return "SLH-DSA-SHAKE-256s";
220 return "SLH-DSA-SHAKE-256f";
227 return "SphincsPlus-haraka-128s-r3.1";
229 return "SphincsPlus-haraka-128f-r3.1";
231 return "SphincsPlus-haraka-192s-r3.1";
233 return "SphincsPlus-haraka-192f-r3.1";
235 return "SphincsPlus-haraka-256s-r3.1";
237 return "SphincsPlus-haraka-256f-r3.1";
282 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 BOTAN_ARG_CHECK(!(hash_type == Sphincs_Hash_Type::Haraka && is_slh_dsa_set(set)),
284 "Haraka is not available for SLH-DSA");
285 BOTAN_ARG_CHECK(w == 4 || w == 16 || w == 256,
"Winternitz parameter must be one of 4, 16, 256");
286 BOTAN_ARG_CHECK(n == 16 || n == 24 || n == 32,
"n must be one of 16, 24, 32");
289 m_xmss_tree_height = m_h / m_d;
297 m_wots_len1 = (m_n * 8) / m_lg_w;
300 m_wots_len2 =
ceil_log2(m_wots_len1 * (m_w - 1)) / m_lg_w + 1;
303 m_wots_len = m_wots_len1 + m_wots_len2;
306 m_wots_bytes = m_wots_len * m_n;
309 m_wots_checksum_bytes =
ceil_tobytes(m_wots_len2 * m_lg_w);
311 m_fors_sig_bytes = (m_a + 1) * m_k * m_n;
316 m_xmss_sig_bytes = m_wots_bytes + m_xmss_tree_height * m_n;
317 m_ht_sig_bytes = m_d * m_xmss_sig_bytes;
318 m_sp_sig_bytes = m_n + m_fors_sig_bytes + m_ht_sig_bytes;
320 m_tree_digest_bytes =
ceil_tobytes(m_h - m_xmss_tree_height);
322 m_h_msg_digest_bytes = m_fors_message_bytes + m_tree_digest_bytes + m_leaf_digest_bytes;
326 [[maybe_unused]]
const bool is_slh_dsa = is_slh_dsa_set(m_set);
327#ifdef BOTAN_HAS_SLH_DSA_WITH_SHA2
332#ifdef BOTAN_HAS_SLH_DSA_WITH_SHAKE
337#ifdef BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2
342#ifdef BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE
356 return Sphincs_Parameters(set, hash, 16, 63, 7, 12, 14, 16, 133);
359 return Sphincs_Parameters(set, hash, 16, 66, 22, 6, 33, 16, 128);
363 return Sphincs_Parameters(set, hash, 24, 63, 7, 14, 17, 16, 193);
366 return Sphincs_Parameters(set, hash, 24, 66, 22, 8, 33, 16, 194);
370 return Sphincs_Parameters(set, hash, 32, 64, 8, 14, 22, 16, 255);
373 return Sphincs_Parameters(set, hash, 32, 68, 17, 9, 35, 16, 255);
379 auto [param_set,
hash_type] = set_and_hash_from_name(name);
384 return is_slh_dsa_set(m_set);
388 switch(m_hash_type) {
392 return fmt(
"SHAKE-256({})", 8 *
n());
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_ARG_CHECK(expr, msg)
#define BOTAN_ASSERT_UNREACHABLE()
std::string to_formatted_string() const
static OID from_string(std::string_view str)
Sphincs_Parameter_Set parameter_set() const
std::string to_string() const
AlgorithmIdentifier algorithm_identifier() const
std::string hash_name() const
bool is_available() const
OID object_identifier() const
Sphincs_Hash_Type hash_type() const
static Sphincs_Parameters create(Sphincs_Parameter_Set set, Sphincs_Hash_Type hash)
std::string fmt(std::string_view format, const T &... args)
@ Haraka
Haraka is currently not supported.
constexpr uint8_t ceil_log2(T x)
BOTAN_FORCE_INLINE constexpr T ceil_tobytes(T bits)