From ccd3d4e073b6bfecdc63f718a9d7aa41f22b3208 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Niels=20M=C3=B6ller?= Date: Thu, 3 Jul 2025 08:51:07 +0200 Subject: [PATCH] Implement slh_dsa_sha2_128s. --- Makefile.in | 2 +- slh-dsa-sha2-128s.c | 87 +++++++++++++++++++++++++++++++++++++++++++++ slh-dsa.h | 18 ++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 slh-dsa-sha2-128s.c diff --git a/Makefile.in b/Makefile.in index 4eaf762b..dfe76172 100644 --- a/Makefile.in +++ b/Makefile.in @@ -178,7 +178,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt-table.c \ drbg-ctr-aes256.c \ slh-fors.c slh-merkle.c slh-shake.c slh-sha256.c slh-wots.c slh-xmss.c \ slh-dsa.c slh-dsa-128s.c slh-dsa-128f.c \ - slh-dsa-shake-128s.c slh-dsa-shake-128f.c + slh-dsa-shake-128s.c slh-dsa-shake-128f.c slh-dsa-sha2-128s.c hogweed_SOURCES = sexp.c sexp-format.c \ sexp-transport.c sexp-transport-format.c \ diff --git a/slh-dsa-sha2-128s.c b/slh-dsa-sha2-128s.c new file mode 100644 index 00000000..25db823c --- /dev/null +++ b/slh-dsa-sha2-128s.c @@ -0,0 +1,87 @@ +/* slh-dsa-sha2-128s.c + + SLH-DSA (FIPS 205) signatures. + + Copyright (C) 2025 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "slh-dsa.h" +#include "slh-dsa-internal.h" + +#define SLH_DSA_M 30 + +#define XMSS_H 9 + +void +slh_dsa_sha2_128s_root (const uint8_t *public_seed, const uint8_t *private_seed, + uint8_t *root) +{ + uint8_t scratch[(XMSS_H + 1)*_SLH_DSA_128_SIZE]; + _xmss_gen (&_slh_hash_shake, public_seed, private_seed, + &_slh_dsa_128s_params.xmss, scratch, root); +} + +void +slh_dsa_sha2_128s_generate_keypair (uint8_t *pub, uint8_t *priv, + void *random_ctx, nettle_random_func *random) +{ + random (random_ctx, SLH_DSA_128_SEED_SIZE, pub); + random (random_ctx, 2*SLH_DSA_128_SEED_SIZE, priv); + slh_dsa_sha2_128s_root (pub, priv, pub + SLH_DSA_128_SEED_SIZE); +} + +/* Only the "pure" and deterministic variant. */ +void +slh_dsa_sha2_128s_sign (const uint8_t *pub, const uint8_t *priv, + size_t length, const uint8_t *msg, + uint8_t *signature) +{ + uint8_t digest[SLH_DSA_M]; + _slh_dsa_pure_rdigest (&_slh_hash_sha256, + pub, priv + _SLH_DSA_128_SIZE, length, msg, + signature, sizeof (digest), digest); + _slh_dsa_sign (&_slh_dsa_128s_params, &_slh_hash_sha256, + pub, priv, digest, signature); +} + +int +slh_dsa_sha2_128s_verify (const uint8_t *pub, + size_t length, const uint8_t *msg, + const uint8_t *signature) +{ + uint8_t digest[SLH_DSA_M]; + _slh_dsa_pure_digest (&_slh_hash_sha256, + pub, length, msg, signature, sizeof (digest), digest); + return _slh_dsa_verify (&_slh_dsa_128s_params, &_slh_hash_sha256, + pub, digest, signature); +} diff --git a/slh-dsa.h b/slh-dsa.h index 43d4fbd0..0ba3fc65 100644 --- a/slh-dsa.h +++ b/slh-dsa.h @@ -43,12 +43,16 @@ extern "C" { /* Name mangling */ #define slh_dsa_shake_128s_root nettle_slh_dsa_shake_128s_root #define slh_dsa_shake_128f_root nettle_slh_dsa_shake_128f_root +#define slh_dsa_sha2_128s_root nettle_slh_dsa_sha2_128s_root #define slh_dsa_shake_128s_generate_keypair nettle_slh_dsa_shake_128s_generate_keypair #define slh_dsa_shake_128f_generate_keypair nettle_slh_dsa_shake_128f_generate_keypair +#define slh_dsa_sha2_128s_generate_keypair nettle_slh_dsa_sha2_128s_generate_keypair #define slh_dsa_shake_128s_sign nettle_slh_dsa_shake_128s_sign #define slh_dsa_shake_128f_sign nettle_slh_dsa_shake_128f_sign +#define slh_dsa_sha2_128s_sign nettle_slh_dsa_sha2_128s_sign #define slh_dsa_shake_128s_verify nettle_slh_dsa_shake_128s_verify #define slh_dsa_shake_128f_verify nettle_slh_dsa_shake_128f_verify +#define slh_dsa_sha2_128s_verify nettle_slh_dsa_sha2_128s_verify /* Key layout: private: @@ -71,6 +75,9 @@ slh_dsa_shake_128s_root (const uint8_t *public_seed, const uint8_t *private_seed void slh_dsa_shake_128f_root (const uint8_t *public_seed, const uint8_t *private_seed, uint8_t *root); +void +slh_dsa_sha2_128s_root (const uint8_t *public_seed, const uint8_t *private_seed, + uint8_t *root); void slh_dsa_shake_128s_generate_keypair (uint8_t *pub, uint8_t *key, @@ -78,6 +85,9 @@ slh_dsa_shake_128s_generate_keypair (uint8_t *pub, uint8_t *key, void slh_dsa_shake_128f_generate_keypair (uint8_t *pub, uint8_t *key, void *random_ctx, nettle_random_func *random); +void +slh_dsa_sha2_128s_generate_keypair (uint8_t *pub, uint8_t *key, + void *random_ctx, nettle_random_func *random); /* Only the "pure" and deterministic variant. */ void @@ -88,6 +98,10 @@ void slh_dsa_shake_128f_sign (const uint8_t *pub, const uint8_t *priv, size_t length, const uint8_t *msg, uint8_t *signature); +void +slh_dsa_sha2_128s_sign (const uint8_t *pub, const uint8_t *priv, + size_t length, const uint8_t *msg, + uint8_t *signature); int slh_dsa_shake_128s_verify (const uint8_t *pub, @@ -97,6 +111,10 @@ int slh_dsa_shake_128f_verify (const uint8_t *pub, size_t length, const uint8_t *msg, const uint8_t *signature); +int +slh_dsa_sha2_128s_verify (const uint8_t *pub, + size_t length, const uint8_t *msg, + const uint8_t *signature); #ifdef __cplusplus } -- 2.47.2