Skip to content

Commit

Permalink
SLH-DSA integration into SPHINCS+
Browse files Browse the repository at this point in the history
Preparation for the final SLH-DSA standard using the SLH-DSA IPD
instances.
  • Loading branch information
FAlbertDev committed Aug 7, 2024
1 parent f3e5744 commit 00a177b
Show file tree
Hide file tree
Showing 23 changed files with 397 additions and 136 deletions.
15 changes: 15 additions & 0 deletions src/build-data/oids.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
53 changes: 26 additions & 27 deletions src/cli/speed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
#include <botan/hss_lms.h>
#endif

#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON)
#include <botan/sphincsplus.h>
#endif

Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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<std::string> 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<Botan::Private_Key> key(
keygen_timer->run([&] { return Botan::create_private_key("SPHINCS+", rng(), params); }));
std::vector<std::string> 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<Botan::Private_Key> 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
Expand Down
26 changes: 25 additions & 1 deletion src/lib/asn1/oid_maps.cpp
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -235,6 +235,18 @@ std::unordered_map<std::string, std::string> 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"},
Expand Down Expand Up @@ -488,6 +500,18 @@ std::unordered_map<std::string, OID> 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})},
Expand Down
14 changes: 7 additions & 7 deletions src/lib/pubkey/pk_algs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
#include <botan/dilithium.h>
#endif

#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON)
#include <botan/sphincsplus.h>
#endif

Expand Down Expand Up @@ -230,8 +230,8 @@ std::unique_ptr<Public_Key> 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<SphincsPlus_PublicKey>(alg_id, key_bits);
}
#endif
Expand Down Expand Up @@ -365,8 +365,8 @@ std::unique_ptr<Private_Key> 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<SphincsPlus_PrivateKey>(alg_id, key_bits);
}
#endif
Expand Down Expand Up @@ -507,8 +507,8 @@ std::unique_ptr<Private_Key> 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<SphincsPlus_PrivateKey>(rng, sphincs_params);
Expand Down
9 changes: 5 additions & 4 deletions src/lib/pubkey/sphincsplus/sphincsplus_common/sp_fors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
#include <botan/internal/sp_types.h>
#include <botan/internal/stl_util.h>

#include <functional>
#include <utility>

namespace Botan {

namespace {
Expand All @@ -34,7 +31,11 @@ std::vector<TreeNodeIndex> fors_message_to_indices(std::span<const uint8_t> 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);
}
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/lib/pubkey/sphincsplus/sphincsplus_common/sp_hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
#include <botan/hash.h>
#include <botan/sp_parameters.h>

#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
#if defined(BOTAN_HAS_SPHINCS_PLUS_SHAKE_BASED)
#include <botan/internal/sp_hash_shake.h>
#endif

#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2)
#if defined(BOTAN_HAS_SPHINCS_PLUS_SHA2_BASED)
#include <botan/internal/sp_hash_sha2.h>
#endif

Expand All @@ -35,14 +35,14 @@ std::unique_ptr<Sphincs_Hash_Functions> 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_Hash_Functions_Sha2>(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_Hash_Functions_Shake>(sphincs_params, pub_seed);
#else
throw Not_Implemented("SPHINCS+ with SHAKE is not available in this build");
Expand Down
Loading

0 comments on commit 00a177b

Please sign in to comment.