Skip to content

Commit

Permalink
Merge pull request #4382 from Rohde-Schwarz/pqc_sig_compat
Browse files Browse the repository at this point in the history
ML-DSA, SLH-DSA: Provide Type Aliases (+ Small Test Fixes)
  • Loading branch information
FAlbertDev authored Oct 17, 2024
2 parents b33eaef + b290aa9 commit e70e1bf
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 30 deletions.
20 changes: 10 additions & 10 deletions src/lib/ffi/ffi_pkey_algs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@
#endif

#if defined(BOTAN_HAS_ML_DSA)
#include <botan/dilithium.h>
#include <botan/ml_dsa.h>
#endif

#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
#include <botan/sphincsplus.h>
#include <botan/slh_dsa.h>
#endif

namespace {
Expand Down Expand Up @@ -1108,12 +1108,12 @@ int botan_privkey_load_ml_dsa(botan_privkey_t* key, const uint8_t privkey[], siz
*key = nullptr;

return ffi_guard_thunk(__func__, [=]() -> int {
auto mode = Botan::DilithiumMode(mldsa_mode);
auto mode = Botan::ML_DSA_Mode(mldsa_mode);
if(!mode.is_ml_dsa()) {
return BOTAN_FFI_ERROR_BAD_PARAMETER;
}

auto mldsa_key = std::make_unique<Botan::Dilithium_PrivateKey>(std::span{privkey, key_len}, mode);
auto mldsa_key = std::make_unique<Botan::ML_DSA_PrivateKey>(std::span{privkey, key_len}, mode);
*key = new botan_privkey_struct(std::move(mldsa_key));
return BOTAN_FFI_SUCCESS;
});
Expand All @@ -1132,12 +1132,12 @@ int botan_pubkey_load_ml_dsa(botan_pubkey_t* key, const uint8_t pubkey[], size_t
*key = nullptr;

return ffi_guard_thunk(__func__, [=]() -> int {
auto mode = Botan::DilithiumMode(mldsa_mode);
auto mode = Botan::ML_DSA_Mode(mldsa_mode);
if(!mode.is_ml_dsa()) {
return BOTAN_FFI_ERROR_BAD_PARAMETER;
}

auto mldsa_key = std::make_unique<Botan::Dilithium_PublicKey>(std::span{pubkey, key_len}, mode);
auto mldsa_key = std::make_unique<Botan::ML_DSA_PublicKey>(std::span{pubkey, key_len}, mode);
*key = new botan_pubkey_struct(std::move(mldsa_key));
return BOTAN_FFI_SUCCESS;
});
Expand All @@ -1160,12 +1160,12 @@ int botan_privkey_load_slh_dsa(botan_privkey_t* key, const uint8_t privkey[], si
*key = nullptr;

return ffi_guard_thunk(__func__, [=]() -> int {
auto mode = Botan::Sphincs_Parameters::create(slhdsa_mode);
auto mode = Botan::SLH_DSA_Parameters::create(slhdsa_mode);
if(!mode.is_slh_dsa()) {
return BOTAN_FFI_ERROR_BAD_PARAMETER;
}

auto slhdsa_key = std::make_unique<Botan::SphincsPlus_PrivateKey>(std::span{privkey, key_len}, mode);
auto slhdsa_key = std::make_unique<Botan::SLH_DSA_PrivateKey>(std::span{privkey, key_len}, mode);
*key = new botan_privkey_struct(std::move(slhdsa_key));
return BOTAN_FFI_SUCCESS;
});
Expand All @@ -1184,12 +1184,12 @@ int botan_pubkey_load_slh_dsa(botan_pubkey_t* key, const uint8_t pubkey[], size_
*key = nullptr;

return ffi_guard_thunk(__func__, [=]() -> int {
auto mode = Botan::Sphincs_Parameters::create(slhdsa_mode);
auto mode = Botan::SLH_DSA_Parameters::create(slhdsa_mode);
if(!mode.is_slh_dsa()) {
return BOTAN_FFI_ERROR_BAD_PARAMETER;
}

auto mldsa_key = std::make_unique<Botan::SphincsPlus_PublicKey>(std::span{pubkey, key_len}, mode);
auto mldsa_key = std::make_unique<Botan::SLH_DSA_PublicKey>(std::span{pubkey, key_len}, mode);
*key = new botan_pubkey_struct(std::move(mldsa_key));
return BOTAN_FFI_SUCCESS;
});
Expand Down
4 changes: 4 additions & 0 deletions src/lib/pubkey/dilithium/ml_dsa/info.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ dilithium_shake
<header:internal>
ml_dsa_impl.h
</header:internal>

<header:public>
ml_dsa.h
</header:public>
27 changes: 27 additions & 0 deletions src/lib/pubkey/dilithium/ml_dsa/ml_dsa.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Module-Lattice-Based Digital Signature Standard (ML-DSA)
*
* (C) 2024 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#ifndef BOTAN_ML_DSA_H_
#define BOTAN_ML_DSA_H_

// This is a bridge into a future where we don't support Dilithium anymore to
// keep the API stable for users of the ML-DSA algorithm. We recommend new
// users to use the type-aliases declared in this header as the Dilithium API
// might be deprecated and eventually removed in future releases.

#include <botan/dilithium.h>

namespace Botan {

using ML_DSA_Mode = DilithiumMode;
using ML_DSA_PublicKey = Dilithium_PublicKey;
using ML_DSA_PrivateKey = Dilithium_PrivateKey;

} // namespace Botan

#endif
74 changes: 56 additions & 18 deletions src/lib/pubkey/pk_algs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,22 @@
#include <botan/sm2.h>
#endif

#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES) || defined(BOTAN_HAS_ML_DSA)
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
#include <botan/dilithium.h>
#endif

#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON)
#if defined(BOTAN_HAS_ML_DSA)
#include <botan/ml_dsa.h>
#endif

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

#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
#include <botan/slh_dsa.h>
#endif

namespace Botan {

std::unique_ptr<Public_Key> load_public_key(const AlgorithmIdentifier& alg_id,
Expand Down Expand Up @@ -228,25 +236,36 @@ std::unique_ptr<Public_Key> load_public_key(const AlgorithmIdentifier& alg_id,
}
#endif

#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES) || defined(BOTAN_HAS_ML_DSA)
if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-") || alg_name.starts_with("ML-DSA-")) {
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
}
#endif

#if defined(BOTAN_HAS_ML_DSA)
if(alg_name.starts_with("ML-DSA-")) {
return std::make_unique<ML_DSA_PublicKey>(alg_id, key_bits);
}
#endif

#if defined(BOTAN_HAS_HSS_LMS)
if(alg_name == "HSS-LMS") {
return std::make_unique<HSS_LMS_PublicKey>(key_bits);
}
#endif

#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON)
if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-") || alg_name.starts_with("SLH-DSA-") ||
alg_name.starts_with("Hash-SLH-DSA-")) {
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
}
#endif

#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
return std::make_unique<SLH_DSA_PublicKey>(alg_id, key_bits);
}
#endif

throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
}

Expand Down Expand Up @@ -370,25 +389,36 @@ std::unique_ptr<Private_Key> load_private_key(const AlgorithmIdentifier& alg_id,
}
#endif

#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES) || defined(BOTAN_HAS_ML_DSA)
if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-") || alg_name.starts_with("ML-DSA-")) {
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
}
#endif

#if defined(BOTAN_HAS_ML_DSA)
if(alg_name.starts_with("ML-DSA-")) {
return std::make_unique<ML_DSA_PrivateKey>(alg_id, key_bits);
}
#endif

#if defined(BOTAN_HAS_HSS_LMS)
if(alg_name == "HSS-LMS-Private-Key") {
return std::make_unique<HSS_LMS_PrivateKey>(key_bits);
}
#endif

#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON)
if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-") || alg_name.starts_with("SLH-DSA-") ||
alg_name.starts_with("Hash-SLH-DSA-")) {
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
}
#endif

#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
return std::make_unique<SLH_DSA_PrivateKey>(alg_id, key_bits);
}
#endif

throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
}

Expand Down Expand Up @@ -534,14 +564,14 @@ std::unique_ptr<Private_Key> create_private_key(std::string_view alg_name,

#if defined(BOTAN_HAS_ML_DSA)
if(alg_name == "ML-DSA") {
const auto mode = [&]() -> DilithiumMode {
const auto mode = [&]() -> ML_DSA_Mode {
if(params.empty()) {
return DilithiumMode::ML_DSA_6x5;
return ML_DSA_Mode::ML_DSA_6x5;
}
return DilithiumMode(params);
return ML_DSA_Mode(params);
}();

return std::make_unique<Dilithium_PrivateKey>(rng, mode);
return std::make_unique<ML_DSA_PrivateKey>(rng, mode);
}
#endif

Expand All @@ -551,14 +581,22 @@ std::unique_ptr<Private_Key> create_private_key(std::string_view alg_name,
}
#endif

#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON)
if(alg_name == "SPHINCS+" || alg_name == "SphincsPlus" || alg_name == "SLH-DSA") {
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
if(alg_name == "SPHINCS+" || alg_name == "SphincsPlus") {
auto sphincs_params = Sphincs_Parameters::create(params);

return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
}
#endif

#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
if(alg_name == "SLH-DSA") {
auto slh_dsa_params = SLH_DSA_Parameters::create(params);

return std::make_unique<SLH_DSA_PrivateKey>(rng, slh_dsa_params);
}
#endif

#if defined(BOTAN_HAS_XMSS_RFC8391)
if(alg_name == "XMSS") {
const auto xmss_oid = [&]() -> XMSS_Parameters::xmss_algorithm_t {
Expand Down
1 change: 1 addition & 0 deletions src/lib/pubkey/sphincsplus/sphincsplus_common/info.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type -> "Internal"
</module_info>

<header:public>
slh_dsa.h
sphincsplus.h
sp_parameters.h
</header:public>
Expand Down
34 changes: 34 additions & 0 deletions src/lib/pubkey/sphincsplus/sphincsplus_common/slh_dsa.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Stateless Hash-Based Digital Signature Standard
*
* (C) 2024 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#ifndef BOTAN_SLH_DSA_H_
#define BOTAN_SLH_DSA_H_

// This is a bridge into a future where we don't support SPHINCS+ anymore to
// keep the API stable for users of the SHPINCS+ algorithm. We recommend new
// users to use the type-aliases declared in this header as the SPHINCS+ API
// might be deprecated and eventually removed in future releases.

#include <botan/sphincsplus.h>

namespace Botan {

#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)

using SLH_DSA_Parameter_Set = Sphincs_Parameter_Set;
using SLH_DSA_Hash_Type = Sphincs_Hash_Type;
using SLH_DSA_Parameters = Sphincs_Parameters;

using SLH_DSA_PublicKey = SphincsPlus_PublicKey;
using SLH_DSA_PrivateKey = SphincsPlus_PrivateKey;

#endif

} // namespace Botan

#endif
2 changes: 1 addition & 1 deletion src/tests/test_dilithium.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

namespace Botan_Tests {

#if defined(BOTAN_HAS_DILITHIUM_COMMON) && defined(BOTAN_HAS_AES)
#if defined(BOTAN_HAS_DILITHIUM_COMMON) && defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_SHA3)

template <typename DerivedT>
class Dilithium_KAT_Tests : public Text_Based_Test {
Expand Down
2 changes: 1 addition & 1 deletion src/tests/test_sphincsplus_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#include "tests.h"

#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON)
#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON) && defined(BOTAN_HAS_SHA2_32)

#include <botan/hex.h>
#include <botan/internal/sp_address.h>
Expand Down

0 comments on commit e70e1bf

Please sign in to comment.