diff --git a/src/build-data/oids.txt b/src/build-data/oids.txt index 37513b91410..c2e3a5ba3b1 100644 --- a/src/build-data/oids.txt +++ b/src/build-data/oids.txt @@ -75,6 +75,21 @@ 1.3.6.1.4.1.25258.1.12.3.5 = SphincsPlus-haraka-256s-r3.1 1.3.6.1.4.1.25258.1.12.3.6 = SphincsPlus-haraka-256f-r3.1 +# SLH-DSA Initial Public Draft - TODO: Change for final draft +# (taken from the IETF hackathon: https://github.com/IETF-Hackathon/pqc-certificates/blob/f9ecf761c3b4f3a84520536b7ce3175e8c7726fd/docs/oid_mapping.md#nist-draft-standard-algorithm-oids) +1.3.9999.6.4.16 = SLH-DSA-SHA2-128s +1.3.9999.6.7.16 = SLH-DSA-SHAKE-128s +1.3.9999.6.4.13 = SLH-DSA-SHA2-128f +1.3.9999.6.7.13 = SLH-DSA-SHAKE-128f +1.3.9999.6.5.12 = SLH-DSA-SHA2-192s +1.3.9999.6.8.12 = SLH-DSA-SHAKE-192s +1.3.9999.6.5.10 = SLH-DSA-SHA2-192f +1.3.9999.6.8.10 = SLH-DSA-SHAKE-192f +1.3.9999.6.6.12 = SLH-DSA-SHA2-256s +1.3.9999.6.9.12 = SLH-DSA-SHAKE-256s +1.3.9999.6.6.10 = SLH-DSA-SHA2-256f +1.3.9999.6.9.10 = SLH-DSA-SHAKE-256f + # XMSS 1.3.6.1.4.1.25258.1.5 = XMSS-draft6 1.3.6.1.4.1.25258.1.8 = XMSS-draft12 diff --git a/src/cli/speed.cpp b/src/cli/speed.cpp index 50880109849..a4b8e3217e2 100644 --- a/src/cli/speed.cpp +++ b/src/cli/speed.cpp @@ -141,7 +141,7 @@ #include #endif -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) +#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON) #include #endif @@ -660,7 +660,7 @@ class Speed final : public Command { bench_hss_lms(provider, msec); } #endif -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) +#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON) else if(algo == "SPHINCS+") { bench_sphincs_plus(provider, msec); } @@ -2235,36 +2235,35 @@ class Speed final : public Command { } #endif -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) +#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON) void bench_sphincs_plus(const std::string& provider, std::chrono::milliseconds msec) { // Sphincs_Parameter_Set set, Sphincs_Hash_Type hash - std::vector sphincs_params{"SphincsPlus-sha2-128s-r3.1", - "SphincsPlus-sha2-128f-r3.1", - "SphincsPlus-sha2-192s-r3.1", - "SphincsPlus-sha2-192f-r3.1", - "SphincsPlus-sha2-256s-r3.1", - "SphincsPlus-sha2-256f-r3.1", - "SphincsPlus-shake-128s-r3.1", - "SphincsPlus-shake-128f-r3.1", - "SphincsPlus-shake-192s-r3.1", - "SphincsPlus-shake-192f-r3.1", - "SphincsPlus-shake-256s-r3.1", - "SphincsPlus-shake-256f-r3.1"}; - - for(auto params : sphincs_params) { - try { - auto keygen_timer = make_timer(params, provider, "keygen"); - - std::unique_ptr key( - keygen_timer->run([&] { return Botan::create_private_key("SPHINCS+", rng(), params); })); + std::vector sphincs_params{ + "SphincsPlus-sha2-128s-r3.1", "SphincsPlus-sha2-128f-r3.1", "SphincsPlus-sha2-192s-r3.1", + "SphincsPlus-sha2-192f-r3.1", "SphincsPlus-sha2-256s-r3.1", "SphincsPlus-sha2-256f-r3.1", + "SphincsPlus-shake-128s-r3.1", "SphincsPlus-shake-128f-r3.1", "SphincsPlus-shake-192s-r3.1", + "SphincsPlus-shake-192f-r3.1", "SphincsPlus-shake-256s-r3.1", "SphincsPlus-shake-256f-r3.1", + + "SLH-DSA-SHA2-128s", "SLH-DSA-SHA2-128f", "SLH-DSA-SHA2-192s", + "SLH-DSA-SHA2-192f", "SLH-DSA-SHA2-256s", "SLH-DSA-SHA2-256f", + "SLH-DSA-SHAKE-128s", "SLH-DSA-SHAKE-128f", "SLH-DSA-SHAKE-192s", + "SLH-DSA-SHAKE-192f", "SLH-DSA-SHAKE-256s", "SLH-DSA-SHAKE-256f", + }; - record_result(keygen_timer); - if(bench_pk_sig(*key, params, provider, "", msec) == 1) { - break; - } - } catch(Botan::Not_Implemented&) { + for(auto params_str : sphincs_params) { + auto sp_params = Botan::Sphincs_Parameters::create(params_str); + if(!sp_params.is_available()) { continue; } + auto keygen_timer = make_timer(params_str, provider, "keygen"); + + std::unique_ptr key( + keygen_timer->run([&] { return Botan::create_private_key("SPHINCS+", rng(), params_str); })); + + record_result(keygen_timer); + if(bench_pk_sig(*key, params_str, provider, "", msec) == 1) { + break; + } } } #endif diff --git a/src/lib/asn1/oid_maps.cpp b/src/lib/asn1/oid_maps.cpp index 95fa332ce9c..364542b58ac 100644 --- a/src/lib/asn1/oid_maps.cpp +++ b/src/lib/asn1/oid_maps.cpp @@ -1,7 +1,7 @@ /* * OID maps * -* This file was automatically generated by ./src/scripts/dev_tools/gen_oids.py on 2024-07-23 +* This file was automatically generated by ./src/scripts/dev_tools/gen_oids.py on 2024-08-06 * * All manual edits to this file will be lost. Edit the script * then regenerate this source file. @@ -235,6 +235,18 @@ std::unordered_map OID_Map::load_oid2str_map() { {"1.3.6.1.5.5.7.48.1.5", "PKIX.OCSP.NoCheck"}, {"1.3.6.1.5.5.7.48.2", "PKIX.CertificateAuthorityIssuers"}, {"1.3.6.1.5.5.7.8.5", "PKIX.XMPPAddr"}, + {"1.3.9999.6.4.13", "SLH-DSA-SHA2-128f"}, + {"1.3.9999.6.4.16", "SLH-DSA-SHA2-128s"}, + {"1.3.9999.6.5.10", "SLH-DSA-SHA2-192f"}, + {"1.3.9999.6.5.12", "SLH-DSA-SHA2-192s"}, + {"1.3.9999.6.6.10", "SLH-DSA-SHA2-256f"}, + {"1.3.9999.6.6.12", "SLH-DSA-SHA2-256s"}, + {"1.3.9999.6.7.13", "SLH-DSA-SHAKE-128f"}, + {"1.3.9999.6.7.16", "SLH-DSA-SHAKE-128s"}, + {"1.3.9999.6.8.10", "SLH-DSA-SHAKE-192f"}, + {"1.3.9999.6.8.12", "SLH-DSA-SHAKE-192s"}, + {"1.3.9999.6.9.10", "SLH-DSA-SHAKE-256f"}, + {"1.3.9999.6.9.12", "SLH-DSA-SHAKE-256s"}, {"2.16.840.1.101.3.4.1.2", "AES-128/CBC"}, {"2.16.840.1.101.3.4.1.22", "AES-192/CBC"}, {"2.16.840.1.101.3.4.1.25", "KeyWrap.AES-192"}, @@ -488,6 +500,18 @@ std::unordered_map OID_Map::load_str2oid_map() { {"SHA-512-256", OID({2, 16, 840, 1, 101, 3, 4, 2, 6})}, {"SHAKE-128", OID({2, 16, 840, 1, 101, 3, 4, 2, 11})}, {"SHAKE-256", OID({2, 16, 840, 1, 101, 3, 4, 2, 12})}, + {"SLH-DSA-SHA2-128f", OID({1, 3, 9999, 6, 4, 13})}, + {"SLH-DSA-SHA2-128s", OID({1, 3, 9999, 6, 4, 16})}, + {"SLH-DSA-SHA2-192f", OID({1, 3, 9999, 6, 5, 10})}, + {"SLH-DSA-SHA2-192s", OID({1, 3, 9999, 6, 5, 12})}, + {"SLH-DSA-SHA2-256f", OID({1, 3, 9999, 6, 6, 10})}, + {"SLH-DSA-SHA2-256s", OID({1, 3, 9999, 6, 6, 12})}, + {"SLH-DSA-SHAKE-128f", OID({1, 3, 9999, 6, 7, 13})}, + {"SLH-DSA-SHAKE-128s", OID({1, 3, 9999, 6, 7, 16})}, + {"SLH-DSA-SHAKE-192f", OID({1, 3, 9999, 6, 8, 10})}, + {"SLH-DSA-SHAKE-192s", OID({1, 3, 9999, 6, 8, 12})}, + {"SLH-DSA-SHAKE-256f", OID({1, 3, 9999, 6, 9, 10})}, + {"SLH-DSA-SHAKE-256s", OID({1, 3, 9999, 6, 9, 12})}, {"SM2", OID({1, 2, 156, 10197, 1, 301, 1})}, {"SM2_Enc", OID({1, 2, 156, 10197, 1, 301, 3})}, {"SM2_Kex", OID({1, 2, 156, 10197, 1, 301, 2})}, diff --git a/src/lib/pubkey/pk_algs.cpp b/src/lib/pubkey/pk_algs.cpp index 40f43f56bd0..79d953a0f3d 100644 --- a/src/lib/pubkey/pk_algs.cpp +++ b/src/lib/pubkey/pk_algs.cpp @@ -98,7 +98,7 @@ #include #endif -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) +#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON) #include #endif @@ -230,8 +230,8 @@ std::unique_ptr load_public_key(const AlgorithmIdentifier& alg_id, } #endif -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) - if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) { +#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON) + if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-") || alg_name.starts_with("SLH-DSA-")) { return std::make_unique(alg_id, key_bits); } #endif @@ -365,8 +365,8 @@ std::unique_ptr load_private_key(const AlgorithmIdentifier& alg_id, } #endif -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) - if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) { +#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON) + if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-") || alg_name.starts_with("SLH-DSA-")) { return std::make_unique(alg_id, key_bits); } #endif @@ -507,8 +507,8 @@ std::unique_ptr create_private_key(std::string_view alg_name, } #endif -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) - if(alg_name == "SPHINCS+" || alg_name == "SphincsPlus-") { +#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON) + if(alg_name == "SPHINCS+" || alg_name == "SphincsPlus-" || alg_name.starts_with("SLH-DSA-")) { auto sphincs_params = Sphincs_Parameters::create(params); return std::make_unique(rng, sphincs_params); diff --git a/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_fors.cpp b/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_fors.cpp index 5b596572993..bef2c7f7e86 100644 --- a/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_fors.cpp +++ b/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_fors.cpp @@ -18,9 +18,6 @@ #include #include -#include -#include - namespace Botan { namespace { @@ -34,7 +31,11 @@ std::vector fors_message_to_indices(std::span mess for(auto& idx : indices) { for(uint32_t i = 0; i < params.a(); ++i, ++offset) { - idx ^= (((message[offset >> 3] >> (offset & 0x7)) & 0x1) << i); + if(params.is_slh_dsa()) { + idx ^= (((message[offset >> 3] >> (~offset & 0x7)) & 0x1) << (params.a() - 1 - i)); + } else { + idx ^= (((message[offset >> 3] >> (offset & 0x7)) & 0x1) << i); + } } } diff --git a/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_hash.cpp b/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_hash.cpp index 4517d3a7ccd..8de91d7f430 100644 --- a/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_hash.cpp +++ b/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_hash.cpp @@ -15,11 +15,11 @@ #include #include -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) +#if defined(BOTAN_HAS_SPHINCS_PLUS_SHAKE_BASED) #include #endif -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) +#if defined(BOTAN_HAS_SPHINCS_PLUS_SHA2_BASED) #include #endif @@ -35,14 +35,14 @@ std::unique_ptr Sphincs_Hash_Functions::create(const Sph const SphincsPublicSeed& pub_seed) { switch(sphincs_params.hash_type()) { case Sphincs_Hash_Type::Sha256: -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) +#if defined(BOTAN_HAS_SPHINCS_PLUS_SHA2_BASED) return std::make_unique(sphincs_params, pub_seed); #else throw Not_Implemented("SPHINCS+ with SHA-256 is not available in this build"); #endif case Sphincs_Hash_Type::Shake256: -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) +#if defined(BOTAN_HAS_SPHINCS_PLUS_SHAKE_BASED) return std::make_unique(sphincs_params, pub_seed); #else throw Not_Implemented("SPHINCS+ with SHAKE is not available in this build"); diff --git a/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_parameters.cpp b/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_parameters.cpp index 75954f7916a..7e537b883f0 100644 --- a/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_parameters.cpp +++ b/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_parameters.cpp @@ -46,6 +46,24 @@ Sphincs_Parameter_Set set_from_name(std::string_view name) { name == "SphincsPlus-haraka-256f-r3.1") { return Sphincs_Parameter_Set::Sphincs256Fast; } + if(name == "SLH-DSA-SHA2-128s" || name == "SLH-DSA-SHAKE-128s") { + return Sphincs_Parameter_Set::SLHDSA128Small; + } + if(name == "SLH-DSA-SHA2-128f" || name == "SLH-DSA-SHAKE-128f") { + return Sphincs_Parameter_Set::SLHDSA128Fast; + } + if(name == "SLH-DSA-SHA2-192s" || name == "SLH-DSA-SHAKE-192s") { + return Sphincs_Parameter_Set::SLHDSA192Small; + } + if(name == "SLH-DSA-SHA2-192f" || name == "SLH-DSA-SHAKE-192f") { + return Sphincs_Parameter_Set::SLHDSA192Fast; + } + if(name == "SLH-DSA-SHA2-256s" || name == "SLH-DSA-SHAKE-256s") { + return Sphincs_Parameter_Set::SLHDSA256Small; + } + if(name == "SLH-DSA-SHA2-256f" || name == "SLH-DSA-SHAKE-256f") { + return Sphincs_Parameter_Set::SLHDSA256Fast; + } throw Lookup_Error(fmt("No SphincsPlus parameter set found for: {}", name)); } @@ -53,12 +71,16 @@ Sphincs_Parameter_Set set_from_name(std::string_view name) { Sphincs_Hash_Type hash_from_name(std::string_view name) { if(name == "SphincsPlus-sha2-128s-r3.1" || name == "SphincsPlus-sha2-128f-r3.1" || name == "SphincsPlus-sha2-192s-r3.1" || name == "SphincsPlus-sha2-192f-r3.1" || - name == "SphincsPlus-sha2-256s-r3.1" || name == "SphincsPlus-sha2-256f-r3.1") { + name == "SphincsPlus-sha2-256s-r3.1" || name == "SphincsPlus-sha2-256f-r3.1" || name == "SLH-DSA-SHA2-128s" || + name == "SLH-DSA-SHA2-128f" || name == "SLH-DSA-SHA2-192s" || name == "SLH-DSA-SHA2-192f" || + name == "SLH-DSA-SHA2-256s" || name == "SLH-DSA-SHA2-256f") { return Sphincs_Hash_Type::Sha256; } if(name == "SphincsPlus-shake-128s-r3.1" || name == "SphincsPlus-shake-128f-r3.1" || name == "SphincsPlus-shake-192s-r3.1" || name == "SphincsPlus-shake-192f-r3.1" || - name == "SphincsPlus-shake-256s-r3.1" || name == "SphincsPlus-shake-256f-r3.1") { + name == "SphincsPlus-shake-256s-r3.1" || name == "SphincsPlus-shake-256f-r3.1" || name == "SLH-DSA-SHAKE-128s" || + name == "SLH-DSA-SHAKE-128f" || name == "SLH-DSA-SHAKE-192s" || name == "SLH-DSA-SHAKE-192f" || + name == "SLH-DSA-SHAKE-256s" || name == "SLH-DSA-SHAKE-256f") { return Sphincs_Hash_Type::Shake256; } if(name == "SphincsPlus-haraka-128s-r3.1" || name == "SphincsPlus-haraka-128f-r3.1" || @@ -85,17 +107,43 @@ const char* as_string(Sphincs_Hash_Type type) { const char* as_string(Sphincs_Parameter_Set set) { switch(set) { case Sphincs_Parameter_Set::Sphincs128Small: - return "128s-r3.1"; + case Sphincs_Parameter_Set::SLHDSA128Small: + return "128s"; + case Sphincs_Parameter_Set::Sphincs128Fast: + case Sphincs_Parameter_Set::SLHDSA128Fast: + return "128f"; + case Sphincs_Parameter_Set::Sphincs192Small: + case Sphincs_Parameter_Set::SLHDSA192Small: + return "192s"; + case Sphincs_Parameter_Set::Sphincs192Fast: + case Sphincs_Parameter_Set::SLHDSA192Fast: + return "192f"; + case Sphincs_Parameter_Set::Sphincs256Small: + case Sphincs_Parameter_Set::SLHDSA256Small: + return "256s"; + case Sphincs_Parameter_Set::Sphincs256Fast: + case Sphincs_Parameter_Set::SLHDSA256Fast: + return "256f"; + } + BOTAN_ASSERT_UNREACHABLE(); +} + +constexpr bool is_slh_dsa_set(Sphincs_Parameter_Set set) { + switch(set) { + case Sphincs_Parameter_Set::SLHDSA128Small: + case Sphincs_Parameter_Set::SLHDSA128Fast: + case Sphincs_Parameter_Set::SLHDSA192Small: + case Sphincs_Parameter_Set::SLHDSA192Fast: + case Sphincs_Parameter_Set::SLHDSA256Small: + case Sphincs_Parameter_Set::SLHDSA256Fast: + return true; + case Sphincs_Parameter_Set::Sphincs128Small: case Sphincs_Parameter_Set::Sphincs128Fast: - return "128f-r3.1"; case Sphincs_Parameter_Set::Sphincs192Small: - return "192s-r3.1"; case Sphincs_Parameter_Set::Sphincs192Fast: - return "192f-r3.1"; case Sphincs_Parameter_Set::Sphincs256Small: - return "256s-r3.1"; case Sphincs_Parameter_Set::Sphincs256Fast: - return "256f-r3.1"; + return false; } BOTAN_ASSERT_UNREACHABLE(); } @@ -152,22 +200,53 @@ Sphincs_Parameters::Sphincs_Parameters(Sphincs_Parameter_Set set, m_h_msg_digest_bytes = m_fors_message_bytes + m_tree_digest_bytes + m_leaf_digest_bytes; } +bool Sphincs_Parameters::is_available() const { + [[maybe_unused]] bool is_slh_dsa = is_slh_dsa_set(m_set); +#ifdef BOTAN_HAS_SLH_DSA_WITH_SHA2 + if(is_slh_dsa && m_hash_type == Sphincs_Hash_Type::Sha256) { + return true; + } +#endif +#ifdef BOTAN_HAS_SLH_DSA_WITH_SHAKE + if(is_slh_dsa && m_hash_type == Sphincs_Hash_Type::Shake256) { + return true; + } +#endif +#ifdef BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2 + if(!is_slh_dsa && m_hash_type == Sphincs_Hash_Type::Sha256) { + return true; + } +#endif +#ifdef BOTAN_HAS_SPHINCS_PLUS_SHAKE_BASED + if(!is_slh_dsa && m_hash_type == Sphincs_Hash_Type::Shake256) { + return true; + } +#endif + return false; +} + Sphincs_Parameters Sphincs_Parameters::create(Sphincs_Parameter_Set set, Sphincs_Hash_Type hash) { // See "Table 3" in SPHINCS+ specification (NIST R3.1 submission, page 39) switch(set) { case Sphincs_Parameter_Set::Sphincs128Small: + case Sphincs_Parameter_Set::SLHDSA128Small: return Sphincs_Parameters(set, hash, 16, 63, 7, 12, 14, 16, 133); case Sphincs_Parameter_Set::Sphincs128Fast: + case Sphincs_Parameter_Set::SLHDSA128Fast: return Sphincs_Parameters(set, hash, 16, 66, 22, 6, 33, 16, 128); case Sphincs_Parameter_Set::Sphincs192Small: + case Sphincs_Parameter_Set::SLHDSA192Small: return Sphincs_Parameters(set, hash, 24, 63, 7, 14, 17, 16, 193); case Sphincs_Parameter_Set::Sphincs192Fast: + case Sphincs_Parameter_Set::SLHDSA192Fast: return Sphincs_Parameters(set, hash, 24, 66, 22, 8, 33, 16, 194); case Sphincs_Parameter_Set::Sphincs256Small: + case Sphincs_Parameter_Set::SLHDSA256Small: return Sphincs_Parameters(set, hash, 32, 64, 8, 14, 22, 16, 255); case Sphincs_Parameter_Set::Sphincs256Fast: + case Sphincs_Parameter_Set::SLHDSA256Fast: return Sphincs_Parameters(set, hash, 32, 68, 17, 9, 35, 16, 255); } BOTAN_ASSERT_UNREACHABLE(); @@ -177,6 +256,10 @@ Sphincs_Parameters Sphincs_Parameters::create(std::string_view name) { return Sphincs_Parameters::create(set_from_name(name), hash_from_name(name)); } +bool Sphincs_Parameters::is_slh_dsa() const { + return is_slh_dsa_set(m_set); +} + std::string Sphincs_Parameters::hash_name() const { switch(m_hash_type) { case Sphincs_Hash_Type::Sha256: @@ -190,7 +273,14 @@ std::string Sphincs_Parameters::hash_name() const { } std::string Sphincs_Parameters::to_string() const { - return fmt("SphincsPlus-{}-{}", as_string(m_hash_type), as_string(m_set)); + if(is_slh_dsa()) { + std::string hash_name = as_string(m_hash_type); + // Hash names are uppercase for ML-DSA instances + std::transform( + hash_name.begin(), hash_name.end(), hash_name.begin(), [](unsigned char c) { return std::toupper(c); }); + return fmt("SLH-DSA-{}-{}", hash_name, as_string(m_set)); + } + return fmt("SphincsPlus-{}-{}-r3.1", as_string(m_hash_type), as_string(m_set)); } Sphincs_Parameters Sphincs_Parameters::create(const OID& oid) { diff --git a/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_parameters.h b/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_parameters.h index e48461da2e2..5aa9971e647 100644 --- a/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_parameters.h +++ b/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_parameters.h @@ -28,6 +28,13 @@ enum class Sphincs_Parameter_Set { Sphincs192Fast, Sphincs256Small, Sphincs256Fast, + + SLHDSA128Small, + SLHDSA128Fast, + SLHDSA192Small, + SLHDSA192Fast, + SLHDSA256Small, + SLHDSA256Fast, }; /** @@ -41,6 +48,13 @@ class BOTAN_PUBLIC_API(3, 1) Sphincs_Parameters final { static Sphincs_Parameters create(std::string_view name); static Sphincs_Parameters create(const OID& oid); + /** + * @returns true iff the given parameter set and hash combination is available + * in this build. Note that parameter sets can only be used if this function + * evaluates to true. + */ + bool is_available() const; + /** * @returns the OID of the algorithm specified by those parameters */ @@ -61,6 +75,11 @@ class BOTAN_PUBLIC_API(3, 1) Sphincs_Parameters final { */ Sphincs_Parameter_Set parameter_set() const { return m_set; } + /** + * @returns true for SLH-DSA parameter sets. False for SPHINCS+ Round 3.1 parameter sets. + */ + bool is_slh_dsa() const; + /** * @returns a string representation of this parameter set */ diff --git a/src/lib/pubkey/sphincsplus/sphincsplus_common/sphincsplus.cpp b/src/lib/pubkey/sphincsplus/sphincsplus_common/sphincsplus.cpp index fe8dc57d065..26746b27fb4 100644 --- a/src/lib/pubkey/sphincsplus/sphincsplus_common/sphincsplus.cpp +++ b/src/lib/pubkey/sphincsplus/sphincsplus_common/sphincsplus.cpp @@ -19,10 +19,11 @@ #include #include -#if !defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) and !defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) +#if !defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) and !defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) and \ + !defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) and !defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE) static_assert( false, - "botan module 'sphincsplus_common' is useful only when enabling at least 'sphincsplus_sha2' or 'sphincsplus_shake'"); + "botan module 'sphincsplus_common' is useful only when enabling at least 'sphincsplus_sha2', 'sphincsplus_shake', 'slh_dsa_sha2', or 'slh_dsa_shake'"); #endif namespace Botan { @@ -91,13 +92,16 @@ class SphincsPlus_PrivateKeyInternal final { SphincsPlus_PublicKey::SphincsPlus_PublicKey(std::span pub_key, Sphincs_Parameter_Set type, Sphincs_Hash_Type hash) : - m_public(std::make_shared(Sphincs_Parameters::create(type, hash), pub_key)) {} + SphincsPlus_PublicKey(pub_key, Sphincs_Parameters::create(type, hash)) {} SphincsPlus_PublicKey::SphincsPlus_PublicKey(std::span pub_key, Sphincs_Parameters params) : - m_public(std::make_shared(params, pub_key)) {} + m_public(std::make_shared(params, pub_key)) { + BOTAN_ARG_CHECK(params.is_available(), + "The selected parameter-set-hash combination is not activated in this build."); +} SphincsPlus_PublicKey::SphincsPlus_PublicKey(const AlgorithmIdentifier& alg_id, std::span key_bits) : - m_public(std::make_shared(Sphincs_Parameters::create(alg_id.oid()), key_bits)) {} + SphincsPlus_PublicKey(key_bits, Sphincs_Parameters::create(alg_id.oid())) {} SphincsPlus_PublicKey::~SphincsPlus_PublicKey() = default; @@ -238,6 +242,8 @@ SphincsPlus_PrivateKey::SphincsPlus_PrivateKey(const AlgorithmIdentifier& alg_id SphincsPlus_PrivateKey::SphincsPlus_PrivateKey(std::span private_key, Sphincs_Parameters params) : SphincsPlus_PublicKey(slice_off_public_key(params.object_identifier(), private_key), params) { + BOTAN_ARG_CHECK(params.is_available(), + "The selected parameter-set-hash combination is not activated in this build."); const auto private_portion_bytes = params.private_key_bytes() - params.public_key_bytes(); BOTAN_ASSERT_NOMSG(private_key.size() >= private_portion_bytes); @@ -250,6 +256,8 @@ SphincsPlus_PrivateKey::SphincsPlus_PrivateKey(RandomNumberGenerator& rng, SphincsPlus_PrivateKey(rng, Sphincs_Parameters::create(type, hash)) {} SphincsPlus_PrivateKey::SphincsPlus_PrivateKey(RandomNumberGenerator& rng, Sphincs_Parameters params) { + BOTAN_ARG_CHECK(params.is_available(), + "The selected parameter-set-hash combination is not activated in this build."); auto sk_seed = rng.random_vec(params.n()); auto sk_prf = rng.random_vec(params.n()); diff --git a/src/lib/pubkey/sphincsplus/sphincsplus_sha2/info.txt b/src/lib/pubkey/sphincsplus/sphincsplus_sha2_based/info.txt similarity index 55% rename from src/lib/pubkey/sphincsplus/sphincsplus_sha2/info.txt rename to src/lib/pubkey/sphincsplus/sphincsplus_sha2_based/info.txt index 9252a17f1a8..193e4b7c073 100644 --- a/src/lib/pubkey/sphincsplus/sphincsplus_sha2/info.txt +++ b/src/lib/pubkey/sphincsplus/sphincsplus_sha2_based/info.txt @@ -1,9 +1,11 @@ -SPHINCS_PLUS_WITH_SHA2 -> 20230531 +SPHINCS_PLUS_SHA2_BASED -> 20240807 -name -> "SPHINCS+ (SHA-256)" +name -> "SPHINCS+ (SHA-256) Base" +brief -> "Base module for SLH-DSA and SPHINCS+ with SHA-2" +type -> "Internal" diff --git a/src/lib/pubkey/sphincsplus/sphincsplus_sha2_based/slh_dsa_sha2/info.txt b/src/lib/pubkey/sphincsplus/sphincsplus_sha2_based/slh_dsa_sha2/info.txt new file mode 100644 index 00000000000..3e6def1c6e5 --- /dev/null +++ b/src/lib/pubkey/sphincsplus/sphincsplus_sha2_based/slh_dsa_sha2/info.txt @@ -0,0 +1,7 @@ + +SLH_DSA_WITH_SHA2 -> 20240806 + + + +name -> "SLH-DSA (SHA-256)" + diff --git a/src/lib/pubkey/sphincsplus/sphincsplus_sha2/sp_hash_sha2.h b/src/lib/pubkey/sphincsplus/sphincsplus_sha2_based/sp_hash_sha2.h similarity index 100% rename from src/lib/pubkey/sphincsplus/sphincsplus_sha2/sp_hash_sha2.h rename to src/lib/pubkey/sphincsplus/sphincsplus_sha2_based/sp_hash_sha2.h diff --git a/src/lib/pubkey/sphincsplus/sphincsplus_sha2_based/sphincsplus_sha2/info.txt b/src/lib/pubkey/sphincsplus/sphincsplus_sha2_based/sphincsplus_sha2/info.txt new file mode 100644 index 00000000000..aa59dd99970 --- /dev/null +++ b/src/lib/pubkey/sphincsplus/sphincsplus_sha2_based/sphincsplus_sha2/info.txt @@ -0,0 +1,7 @@ + +SPHINCS_PLUS_WITH_SHA2 -> 20230531 + + + +name -> "SPHINCS+ (SHA-256)" + diff --git a/src/lib/pubkey/sphincsplus/sphincsplus_shake_based/info.txt b/src/lib/pubkey/sphincsplus/sphincsplus_shake_based/info.txt new file mode 100644 index 00000000000..641c96fee80 --- /dev/null +++ b/src/lib/pubkey/sphincsplus/sphincsplus_shake_based/info.txt @@ -0,0 +1,18 @@ + +SPHINCS_PLUS_SHAKE_BASED -> 20240809 + + + +name -> "SPHINCS+ (SHAKE) Base" +brief -> "Base module for SLH-DSA and SPHINCS+ with SHAKE" +type -> "Internal" + + + +sphincsplus_common +shake + + + +sp_hash_shake.h + diff --git a/src/lib/pubkey/sphincsplus/sphincsplus_shake_based/slh_dsa_shake/info.txt b/src/lib/pubkey/sphincsplus/sphincsplus_shake_based/slh_dsa_shake/info.txt new file mode 100644 index 00000000000..764228cc356 --- /dev/null +++ b/src/lib/pubkey/sphincsplus/sphincsplus_shake_based/slh_dsa_shake/info.txt @@ -0,0 +1,7 @@ + +SLH_DSA_WITH_SHAKE -> 20240808 + + + +name -> "SLH-DSA (SHAKE)" + diff --git a/src/lib/pubkey/sphincsplus/sphincsplus_shake/sp_hash_shake.h b/src/lib/pubkey/sphincsplus/sphincsplus_shake_based/sp_hash_shake.h similarity index 100% rename from src/lib/pubkey/sphincsplus/sphincsplus_shake/sp_hash_shake.h rename to src/lib/pubkey/sphincsplus/sphincsplus_shake_based/sp_hash_shake.h diff --git a/src/lib/pubkey/sphincsplus/sphincsplus_shake/info.txt b/src/lib/pubkey/sphincsplus/sphincsplus_shake_based/sphincsplus_shake/info.txt similarity index 53% rename from src/lib/pubkey/sphincsplus/sphincsplus_shake/info.txt rename to src/lib/pubkey/sphincsplus/sphincsplus_shake_based/sphincsplus_shake/info.txt index 7276bb2f36f..a07157c43d8 100644 --- a/src/lib/pubkey/sphincsplus/sphincsplus_shake/info.txt +++ b/src/lib/pubkey/sphincsplus/sphincsplus_shake_based/sphincsplus_shake/info.txt @@ -5,12 +5,3 @@ SPHINCS_PLUS_WITH_SHAKE -> 20230531 name -> "SPHINCS+ (SHAKE-256)" - - -sphincsplus_common -shake - - - -sp_hash_shake.h - diff --git a/src/scripts/dev_tools/gen_sphincsplus_kat.py b/src/scripts/dev_tools/gen_sphincsplus_kat.py index 6616664accd..5a415fe1f20 100755 --- a/src/scripts/dev_tools/gen_sphincsplus_kat.py +++ b/src/scripts/dev_tools/gen_sphincsplus_kat.py @@ -83,7 +83,7 @@ def main(args = None): reader = KatReader(open(katfile, encoding="utf-8")) - hash_fn = sha256 if "sha2" in param else sha3_256 + hash_fn = sha256 if "sha2" in param.lower() else sha3_256 l = 0 for kat in reader.read_kats(): diff --git a/src/tests/data/pubkey/slh_dsa.vec b/src/tests/data/pubkey/slh_dsa.vec new file mode 100644 index 00000000000..2afdaea2fc7 --- /dev/null +++ b/src/tests/data/pubkey/slh_dsa.vec @@ -0,0 +1,93 @@ +# TODO: Fill in test vectors for final SLH-DSA standard +# This test data is taken from the KAT files generated by the +# reference implementation of ML-DSA IPD (https://github.com/sphincs/sphincsplus/, branch "consistent-basew") +# +# To save space the signature is hashed with the hash function used in SPHINCS+ +# (i.e. either SHA-3 or SHA-256). +# +# Use `src/scripts/dev_tools/gen_sphincsplus_kat.py` if you need to regenerate it. +# + +SphincsParameterSet = SLH-DSA-SHA2-128s +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 +pk = B505D7CFAD1B497499323C8686325E476D2E5993D919B7F288CC823133046CF9 +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E476D2E5993D919B7F288CC823133046CF9 +HashSig = D0AE5B5734CD15A0512747896E674401A88CFD2C61A3FEC9DD32562FF7F88B16 + +SphincsParameterSet = SLH-DSA-SHAKE-128s +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 +pk = B505D7CFAD1B497499323C8686325E47AC524902FC81F5032BC27B17D9261EBD +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E47AC524902FC81F5032BC27B17D9261EBD +HashSig = 18D5FCDDDD23C5964D50CA73CD5E0AC782F95CC723695A1F84466126E1ACE25B + +SphincsParameterSet = SLH-DSA-SHA2-128f +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 +pk = B505D7CFAD1B497499323C8686325E47FDF7400AB7A5D8C7ABA7350AC4092ADD +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E47FDF7400AB7A5D8C7ABA7350AC4092ADD +HashSig = 41B7EF1B824615C3B4B699154C8FE94F9F2AFF9597695917D2CF9BD7C921F033 + +SphincsParameterSet = SLH-DSA-SHAKE-128f +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 +pk = B505D7CFAD1B497499323C8686325E47AFBC007BA1E2B4A138F03AA9A6195AC8 +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E47AFBC007BA1E2B4A138F03AA9A6195AC8 +HashSig = B7CEB514E5962585A842016D4F039B7A2EEE3EFA5889FBD6F0B94E3F9CFC3FEB + +SphincsParameterSet = SLH-DSA-SHA2-192s +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 +pk = 92F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFDEE27692EF30BAD87B55C4E2A25E7F47875C1F53723CE31C6 +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4792F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFDEE27692EF30BAD87B55C4E2A25E7F47875C1F53723CE31C6 +HashSig = F15D2B7D4F9A3FCCB22D823696D500EB30A80E03140F4F6E04C721DB59F6947F + +SphincsParameterSet = SLH-DSA-SHAKE-192s +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 +pk = 92F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFD0BDE2780ED4CCDAF544D88F22D41610D4EF994825CFB4D45 +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4792F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFD0BDE2780ED4CCDAF544D88F22D41610D4EF994825CFB4D45 +HashSig = C01A1216D10D77CBFCBC926E89D902570187BF40B83768B51C8F38F8614A2C3B + +SphincsParameterSet = SLH-DSA-SHA2-192f +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 +pk = 92F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFDAD7EF867981E22877AA4C2A8829F657E931C55409B897D2E +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4792F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFDAD7EF867981E22877AA4C2A8829F657E931C55409B897D2E +HashSig = 535FD6592D279F7A1AA16ABD49D5FA257272C026629794DA3F6FC92B41E59146 + +SphincsParameterSet = SLH-DSA-SHAKE-192f +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 +pk = 92F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFD9B836B00B9F458C1A193F062A9A3CDAFE7869F47546CB346 +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4792F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFD9B836B00B9F458C1A193F062A9A3CDAFE7869F47546CB346 +HashSig = 37BFD608EF6890087D3CD8DEAA61D884CFA4C2B0D46D0E9661C58B3A592056E2 + +SphincsParameterSet = SLH-DSA-SHA2-256s +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 +pk = 3E784CCB7EBCDCFD45542B7F6AF778742E0F4479175084AA488B3B74340678AA026F566CDCD2987EB7AB1EC71E86B617F97B98EF63902E283FB5249119C6CEB0 +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4792F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFD45542B7F6AF778742E0F4479175084AA488B3B74340678AA026F566CDCD2987EB7AB1EC71E86B617F97B98EF63902E283FB5249119C6CEB0 +HashSig = A002FEEE9119C3ECC835D4E76117A7DE5D326A137DBD2F9503F9A1F0D8B81463 + +SphincsParameterSet = SLH-DSA-SHAKE-256s +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 +pk = 3E784CCB7EBCDCFD45542B7F6AF778742E0F4479175084AA488B3B74340678AA3623940D5D834494148A661F9AC6A96BDC54AD4D0B8B0913484A9233C56212A4 +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4792F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFD45542B7F6AF778742E0F4479175084AA488B3B74340678AA3623940D5D834494148A661F9AC6A96BDC54AD4D0B8B0913484A9233C56212A4 +HashSig = 6EEAA28E6CB4188F28D43EC8315C1D1509D32AD581B5D93CEC8FB1F030528B2E + +SphincsParameterSet = SLH-DSA-SHA2-256f +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 +pk = 3E784CCB7EBCDCFD45542B7F6AF778742E0F4479175084AA488B3B74340678AAD9D73F07F69A7D12C49B9A367DE0668544E8471660678A4EF7CEE8BE9638CA53 +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4792F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFD45542B7F6AF778742E0F4479175084AA488B3B74340678AAD9D73F07F69A7D12C49B9A367DE0668544E8471660678A4EF7CEE8BE9638CA53 +HashSig = 9D5CAAEE879DD946DC158872EF25FD7DA631F54BD61ED1745717B3BDA6886DFD + +SphincsParameterSet = SLH-DSA-SHAKE-256f +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 +pk = 3E784CCB7EBCDCFD45542B7F6AF778742E0F4479175084AA488B3B74340678AA514264D1B7EF27574AE6933E374225CF87683DE3BFEE657200F3667C8D800722 +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4792F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFD45542B7F6AF778742E0F4479175084AA488B3B74340678AA514264D1B7EF27574AE6933E374225CF87683DE3BFEE657200F3667C8D800722 +HashSig = 6DFC48C3DBF6C8485287AFFB3AEE52E67B5CF9D7AA00CE105D74ED698BE64A08 \ No newline at end of file diff --git a/src/tests/test_sphincsplus.cpp b/src/tests/test_sphincsplus.cpp index d02482a0d01..6f63b38eb40 100644 --- a/src/tests/test_sphincsplus.cpp +++ b/src/tests/test_sphincsplus.cpp @@ -8,7 +8,7 @@ #include "test_rng.h" #include "tests.h" -#if(defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)) && defined(BOTAN_HAS_AES) +#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON) && defined(BOTAN_HAS_AES) #include #include @@ -29,34 +29,33 @@ namespace Botan_Tests { * generated by the reference implementation (Round 3.1 * (https://github.com/sphincs/sphincsplus/)) */ -class SPHINCS_Plus_Test final : public Text_Based_Test { +class SPHINCS_Plus_Test_Base : public Text_Based_Test { public: - SPHINCS_Plus_Test() : Text_Based_Test("pubkey/sphincsplus.vec", "SphincsParameterSet,seed,pk,sk,msg,HashSig") {} + SPHINCS_Plus_Test_Base(std::string_view kat_path) : + Text_Based_Test(std::string(kat_path), "SphincsParameterSet,seed,pk,sk,msg,HashSig") {} bool skip_this_test(const std::string&, const VarMap& vars) override { auto params = Botan::Sphincs_Parameters::create(vars.get_req_str("SphincsParameterSet")); - #if not defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) - if(params.hash_type() == Botan::Sphincs_Hash_Type::Shake256) { + if(!params.is_available()) { return true; } - #endif - - #if not defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) - if(params.hash_type() == Botan::Sphincs_Hash_Type::Sha256) { - return true; - } - #endif // Execute the small (slow) instances only with --run-long-tests switch(params.parameter_set()) { case Botan::Sphincs_Parameter_Set::Sphincs128Fast: case Botan::Sphincs_Parameter_Set::Sphincs192Fast: case Botan::Sphincs_Parameter_Set::Sphincs256Fast: + case Botan::Sphincs_Parameter_Set::SLHDSA128Fast: + case Botan::Sphincs_Parameter_Set::SLHDSA192Fast: + case Botan::Sphincs_Parameter_Set::SLHDSA256Fast: return false; case Botan::Sphincs_Parameter_Set::Sphincs128Small: case Botan::Sphincs_Parameter_Set::Sphincs192Small: case Botan::Sphincs_Parameter_Set::Sphincs256Small: + case Botan::Sphincs_Parameter_Set::SLHDSA128Small: + case Botan::Sphincs_Parameter_Set::SLHDSA192Small: + case Botan::Sphincs_Parameter_Set::SLHDSA256Small: return !Test::run_long_tests(); } BOTAN_ASSERT_UNREACHABLE(); @@ -83,7 +82,7 @@ class SPHINCS_Plus_Test final : public Text_Based_Test { return "SHA-256"; } }(); - auto hash = Botan::HashFunction::create(hash_algo_spec); + auto hash = Botan::HashFunction::create_or_throw(hash_algo_spec); /* * To get sk_seed || sk_prf || pk_seed and opt_rand from the given seed @@ -156,29 +155,35 @@ class SPHINCS_Plus_Test final : public Text_Based_Test { } }; +class SPHINCS_Plus_Test final : public SPHINCS_Plus_Test_Base { + public: + SPHINCS_Plus_Test() : SPHINCS_Plus_Test_Base("pubkey/sphincsplus.vec") {} +}; + +class SLH_DSA_Test final : public SPHINCS_Plus_Test_Base { + public: + SLH_DSA_Test() : SPHINCS_Plus_Test_Base("pubkey/slh_dsa.vec") {} +}; + class SPHINCS_Plus_Keygen_Tests final : public PK_Key_Generation_Test { public: std::vector keygen_params() const override { - // clang-format off - return { - #if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) - "SphincsPlus-shake-128s-r3.1", - "SphincsPlus-shake-128f-r3.1", - "SphincsPlus-shake-192s-r3.1", - "SphincsPlus-shake-192f-r3.1", - "SphincsPlus-shake-256s-r3.1", - "SphincsPlus-shake-256f-r3.1", - #endif - #if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) - "SphincsPlus-sha2-128s-r3.1", - "SphincsPlus-sha2-128f-r3.1", - "SphincsPlus-sha2-192s-r3.1", - "SphincsPlus-sha2-192f-r3.1", - "SphincsPlus-sha2-256s-r3.1", - "SphincsPlus-sha2-256f-r3.1", - #endif + const std::vector all_params = { + "SphincsPlus-shake-128s-r3.1", "SphincsPlus-shake-128f-r3.1", "SphincsPlus-shake-192s-r3.1", + "SphincsPlus-shake-192f-r3.1", "SphincsPlus-shake-256s-r3.1", "SphincsPlus-shake-256f-r3.1", + "SLH-DSA-SHAKE-128s", "SLH-DSA-SHAKE-128f", "SLH-DSA-SHAKE-192s", + "SLH-DSA-SHAKE-192f", "SLH-DSA-SHAKE-256s", "SLH-DSA-SHAKE-256f", + "SphincsPlus-sha2-128s-r3.1", "SphincsPlus-sha2-128f-r3.1", "SphincsPlus-sha2-192s-r3.1", + "SphincsPlus-sha2-192f-r3.1", "SphincsPlus-sha2-256s-r3.1", "SphincsPlus-sha2-256f-r3.1", + "SLH-DSA-SHA2-128s", "SLH-DSA-SHA2-128f", "SLH-DSA-SHA2-192s", + "SLH-DSA-SHA2-192f", "SLH-DSA-SHA2-256s", "SLH-DSA-SHA2-256f", }; - // clang-format on + std::vector available_params; + std::copy_if( + all_params.begin(), all_params.end(), std::back_inserter(available_params), [](const std::string& param) { + return Botan::Sphincs_Parameters::create(param).is_available(); + }); + return available_params; } std::string algo_name() const override { return "SPHINCS+"; } @@ -192,6 +197,7 @@ class SPHINCS_Plus_Keygen_Tests final : public PK_Key_Generation_Test { }; BOTAN_REGISTER_TEST("pubkey", "sphincsplus", SPHINCS_Plus_Test); +BOTAN_REGISTER_TEST("pubkey", "slh_dsa", SLH_DSA_Test); BOTAN_REGISTER_TEST("pubkey", "sphincsplus_keygen", SPHINCS_Plus_Keygen_Tests); } // namespace Botan_Tests diff --git a/src/tests/test_sphincsplus_fors.cpp b/src/tests/test_sphincsplus_fors.cpp index 18fa396b00e..b55d2e00c2b 100644 --- a/src/tests/test_sphincsplus_fors.cpp +++ b/src/tests/test_sphincsplus_fors.cpp @@ -7,7 +7,7 @@ #include "tests.h" -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) +#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON) #include #include @@ -40,21 +40,8 @@ class SPHINCS_Plus_FORS_Test final : public Text_Based_Test { "SphincsParameterSet,Address,SecretSeed,PublicSeed,PublicKey,Msg,HashSig") {} bool skip_this_test(const std::string&, const VarMap& vars) override { - [[maybe_unused]] auto params = Botan::Sphincs_Parameters::create(vars.get_req_str("SphincsParameterSet")); - - #if not defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) - if(params.hash_type() == Botan::Sphincs_Hash_Type::Shake256) { - return true; - } - #endif - - #if not defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) - if(params.hash_type() == Botan::Sphincs_Hash_Type::Sha256) { - return true; - } - #endif - - return false; + auto params = Botan::Sphincs_Parameters::create(vars.get_req_str("SphincsParameterSet")); + return !params.is_available(); } Test::Result run_one_test(const std::string&, const VarMap& vars) final { @@ -103,4 +90,4 @@ BOTAN_REGISTER_TEST("pubkey", "sphincsplus_fors", SPHINCS_Plus_FORS_Test); } // namespace Botan_Tests -#endif // BOTAN_HAS_SPHINCS_PLUS +#endif // BOTAN_HAS_SPHINCS_PLUS_COMMON diff --git a/src/tests/test_sphincsplus_utils.cpp b/src/tests/test_sphincsplus_utils.cpp index a3496a9ce5e..48736c1b895 100644 --- a/src/tests/test_sphincsplus_utils.cpp +++ b/src/tests/test_sphincsplus_utils.cpp @@ -7,7 +7,7 @@ #include "tests.h" -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) +#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON) #include #include @@ -109,4 +109,4 @@ BOTAN_REGISTER_TEST_FN("pubkey", "sphincsplus_address", test_sphincsplus_address } // namespace Botan_Tests -#endif // BOTAN_HAS_SPHINCS_PLUS +#endif // BOTAN_HAS_SPHINCS_PLUS_COMMON diff --git a/src/tests/test_sphincsplus_wots.cpp b/src/tests/test_sphincsplus_wots.cpp index 3635e3b3283..02bf03a6c71 100644 --- a/src/tests/test_sphincsplus_wots.cpp +++ b/src/tests/test_sphincsplus_wots.cpp @@ -7,7 +7,7 @@ #include "tests.h" -#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) +#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON) #include #include @@ -42,20 +42,7 @@ class SPHINCS_Plus_WOTS_Test final : public Text_Based_Test { bool skip_this_test(const std::string&, const VarMap& vars) override { [[maybe_unused]] auto params = Botan::Sphincs_Parameters::create(vars.get_req_str("SphincsParameterSet")); - - #if not defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE) - if(params.hash_type() == Botan::Sphincs_Hash_Type::Shake256) { - return true; - } - #endif - - #if not defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) - if(params.hash_type() == Botan::Sphincs_Hash_Type::Sha256) { - return true; - } - #endif - - return false; + return !params.is_available(); } Test::Result run_one_test(const std::string&, const VarMap& vars) final { @@ -131,4 +118,4 @@ BOTAN_REGISTER_TEST("pubkey", "sphincsplus_wots", SPHINCS_Plus_WOTS_Test); } // namespace Botan_Tests -#endif // BOTAN_HAS_SPHINCS_PLUS +#endif // BOTAN_HAS_SPHINCS_PLUS_COMMON