]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Define slh-dsa-128s and dsa-slh-128f parameters, independent of shake.
authorNiels Möller <nisse@lysator.liu.se>
Thu, 3 Jul 2025 07:51:15 +0000 (09:51 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Wed, 10 Sep 2025 06:51:59 +0000 (08:51 +0200)
slh-dsa-internal.h
slh-dsa-shake-128f.c
slh-dsa-shake-128s.c
slh-dsa.c
slh-sha256.c
slh-shake.c

index d5b2b2370422e760b2c99143cd0b687eab053928..8612a488ed2820f2312f18f5efa9167f3558344a 100644 (file)
 #include "sha3.h"
 
 /* Name mangling */
-#define _slh_shake_randomizer _nettle_slh_shake_randomizer
-#define _slh_shake_msg_digest _nettle_slh_shake_msg_digest
-#define _slh_sha256_randomizer _nettle_slh_sha256_randomizer
-#define _slh_sha256_msg_digest _nettle_slh_sha256_msg_digest
 #define _wots_gen _nettle_wots_gen
 #define _wots_sign _nettle_wots_sign
 #define _wots_verify _nettle_wots_verify
@@ -55,6 +51,8 @@
 #define _xmss_gen _nettle_xmss_gen
 #define _xmss_sign _nettle_xmss_sign
 #define _xmss_verify _nettle_xmss_verify
+#define _slh_dsa_pure_digest _nettle_slh_dsa_pure_digest
+#define _slh_dsa_pure_rdigest _nettle_slh_dsa_pure_rdigest
 #define _slh_dsa_sign _nettle_slh_dsa_sign
 #define _slh_dsa_verify _nettle_slh_dsa_verify
 
@@ -95,6 +93,16 @@ union slh_hash_ctx
   struct sha3_ctx sha3;
 };
 
+typedef void slh_hash_randomizer_func (const uint8_t *public_seed, const uint8_t *secret_prf,
+                                      size_t prefix_length, const uint8_t *prefix,
+                                      size_t msg_length, const uint8_t *msg,
+                                      uint8_t *randomizer);
+
+typedef void slh_hash_msg_digest_func (const uint8_t *randomizer, const uint8_t *pub,
+                                      size_t prefix_length, const uint8_t *prefix,
+                                      size_t msg_length, const uint8_t *msg,
+                                      size_t digest_size, uint8_t *digest);
+
 typedef void slh_hash_init_tree_func (union slh_hash_ctx *tree_ctx, const uint8_t *public_seed,
                                      uint32_t layer, uint64_t tree_idx);
 typedef void slh_hash_init_hash_func (const union slh_hash_ctx *tree_ctx, union slh_hash_ctx *ctx,
@@ -115,6 +123,8 @@ struct slh_hash
   nettle_hash_digest_func *digest;
   slh_hash_secret_func *secret;
   slh_hash_node_func *node;
+  slh_hash_randomizer_func *randomizer;
+  slh_hash_msg_digest_func *msg_digest;
 };
 
 extern const struct slh_hash _slh_hash_shake;
@@ -134,6 +144,8 @@ struct slh_merkle_ctx_secret
   const uint8_t *secret_seed;
 };
 
+typedef void slh_parse_digest_func (const uint8_t *digest, uint64_t *tree_idx, unsigned *leaf_idx);
+
 struct slh_xmss_params
 {
   unsigned short d; /* Levels of xmss trees. */
@@ -261,6 +273,18 @@ void
 _xmss_verify (const struct slh_merkle_ctx_public *ctx, unsigned h,
              unsigned idx, const uint8_t *msg, const uint8_t *signature, uint8_t *pub);
 
+void
+_slh_dsa_pure_digest (const struct slh_hash *hash,
+                     const uint8_t *pub,
+                     size_t length, const uint8_t *msg,
+                     const uint8_t *randomizer, size_t digest_size, uint8_t *digest);
+
+void
+_slh_dsa_pure_rdigest (const struct slh_hash *hash,
+                      const uint8_t *pub, const uint8_t *prf,
+                      size_t length, const uint8_t *msg,
+                      uint8_t *randomizer, size_t digest_size, uint8_t *digest);
+
 void
 _slh_dsa_sign (const struct slh_dsa_params *params,
               const struct slh_hash *hash,
index 207be26c21be99daa8d144fcb86d0c73f436cc55..37b84795c3dd68750da8c2f623ca0b0466abcf02 100644 (file)
@@ -67,11 +67,11 @@ slh_dsa_shake_128f_sign (const uint8_t *pub, const uint8_t *priv,
                         uint8_t *signature)
 {
   uint8_t digest[SLH_DSA_M];
-  _slh_shake_randomizer (pub, priv + _SLH_DSA_128_SIZE, length, msg, signature);
-  _slh_shake_msg_digest (signature, pub, length, msg, SLH_DSA_M, digest);
+  _slh_dsa_pure_rdigest (&_slh_hash_shake,
+                        pub, priv + _SLH_DSA_128_SIZE, length, msg,
+                        signature, sizeof (digest), digest);
   _slh_dsa_sign (&_slh_dsa_128f_params, &_slh_hash_shake,
-                pub, priv, digest,
-                signature + _SLH_DSA_128_SIZE);
+                pub, priv, digest, signature + _SLH_DSA_128_SIZE);
 }
 
 int
@@ -80,8 +80,8 @@ slh_dsa_shake_128f_verify (const uint8_t *pub,
                           const uint8_t *signature)
 {
   uint8_t digest[SLH_DSA_M];
-  _slh_shake_msg_digest (signature, pub, length, msg, SLH_DSA_M,digest);
+  _slh_dsa_pure_digest (&_slh_hash_shake,
+                       pub, length, msg, signature, sizeof (digest), digest);
   return _slh_dsa_verify (&_slh_dsa_128f_params, &_slh_hash_shake,
-                         pub, digest,
-                         signature + _SLH_DSA_128_SIZE);
+                         pub, digest, signature + _SLH_DSA_128_SIZE);
 }
index 841ec67689eabf756c984cd4ef3a0480492bbf4a..ed400727be5447e50e2a57027ea273c784c18b7e 100644 (file)
@@ -67,11 +67,11 @@ slh_dsa_shake_128s_sign (const uint8_t *pub, const uint8_t *priv,
                         uint8_t *signature)
 {
   uint8_t digest[SLH_DSA_M];
-  _slh_shake_randomizer (pub, priv + _SLH_DSA_128_SIZE, length, msg, signature);
-  _slh_shake_msg_digest (signature, pub, length, msg, SLH_DSA_M, digest);
+  _slh_dsa_pure_rdigest (&_slh_hash_shake,
+                        pub, priv + _SLH_DSA_128_SIZE, length, msg,
+                        signature, sizeof (digest), digest);
   _slh_dsa_sign (&_slh_dsa_128s_params, &_slh_hash_shake,
-                pub, priv, digest,
-                signature + _SLH_DSA_128_SIZE);
+                pub, priv, digest, signature + _SLH_DSA_128_SIZE);
 }
 
 int
@@ -80,8 +80,8 @@ slh_dsa_shake_128s_verify (const uint8_t *pub,
                           const uint8_t *signature)
 {
   uint8_t digest[SLH_DSA_M];
-  _slh_shake_msg_digest (signature, pub, length, msg, SLH_DSA_M,digest);
+  _slh_dsa_pure_digest (&_slh_hash_shake,
+                       pub, length, msg, signature, sizeof (digest), digest);
   return _slh_dsa_verify (&_slh_dsa_128s_params, &_slh_hash_shake,
-                         pub, digest,
-                         signature + _SLH_DSA_128_SIZE);
+                         pub, digest, signature + _SLH_DSA_128_SIZE);
 }
index 1561f5fe9a34b4e4f713eb83f5d110e04264dde8..5414991bda41825d9a354eed5686a612713a1155 100644 (file)
--- a/slh-dsa.c
+++ b/slh-dsa.c
 #include "slh-dsa.h"
 #include "slh-dsa-internal.h"
 
+static const uint8_t slh_pure_prefix[2] = {0, 0};
+
+void
+_slh_dsa_pure_digest (const struct slh_hash *hash,
+                     const uint8_t *pub,
+                     size_t length, const uint8_t *msg,
+                     const uint8_t *randomizer, size_t digest_size, uint8_t *digest)
+{
+  hash->msg_digest (randomizer, pub, sizeof (slh_pure_prefix), slh_pure_prefix,
+                   length, msg, digest_size, digest);
+}
+
+void
+_slh_dsa_pure_rdigest (const struct slh_hash *hash,
+                      const uint8_t *pub, const uint8_t *prf,
+                      size_t length, const uint8_t *msg,
+                      uint8_t *randomizer, size_t digest_size, uint8_t *digest)
+{
+  hash->randomizer (pub, prf,
+                   sizeof (slh_pure_prefix), slh_pure_prefix, length, msg, randomizer);
+  _slh_dsa_pure_digest (hash, pub, length, msg, randomizer, digest_size, digest);
+}
+
+static void
+merkle_ctx_secret_init (struct slh_merkle_ctx_secret *ctx,
+                       const struct slh_hash *hash, unsigned keypair,
+                       const uint8_t *secret_seed)
+{
+  ctx->pub.hash = hash;
+  ctx->pub.keypair = keypair;
+  ctx->secret_seed = secret_seed;
+}
+
 void
 _slh_dsa_sign (const struct slh_dsa_params *params,
               const struct slh_hash *hash,
               const uint8_t *pub, const uint8_t *priv,
               const uint8_t *digest, uint8_t *signature)
 {
+  struct slh_merkle_ctx_secret merkle_ctx;
+  uint8_t root[_SLH_DSA_128_SIZE];
   uint64_t tree_idx;
   unsigned leaf_idx;
 
   params->parse_digest (digest + params->fors.msg_size, &tree_idx, &leaf_idx);
+  merkle_ctx_secret_init (&merkle_ctx, hash, leaf_idx, priv);
 
-  struct slh_merkle_ctx_secret merkle_ctx =
-    {
-      { hash, {}, leaf_idx },
-      priv,
-    };
   hash->init_tree (&merkle_ctx.pub.tree_ctx, pub, 0, tree_idx);
 
-  uint8_t root[_SLH_DSA_128_SIZE];
-
   _fors_sign (&merkle_ctx, &params->fors, digest, signature, root);
   signature += params->fors.signature_size;
 
@@ -81,24 +110,31 @@ _slh_dsa_sign (const struct slh_dsa_params *params,
   assert (memeql_sec (root, pub + _SLH_DSA_128_SIZE, sizeof (root)));
 }
 
+
+static void
+merkle_ctx_public_init (struct slh_merkle_ctx_public *ctx,
+                       const struct slh_hash *hash, unsigned keypair)
+{
+  ctx->hash = hash;
+  ctx->keypair = keypair;
+}
+
 int
 _slh_dsa_verify (const struct slh_dsa_params *params,
                 const struct slh_hash *hash,
                 const uint8_t *pub,
                 const uint8_t *digest, const uint8_t *signature)
 {
+  struct slh_merkle_ctx_public merkle_ctx;
+  uint8_t root[_SLH_DSA_128_SIZE];
   uint64_t tree_idx;
   unsigned leaf_idx;
 
   params->parse_digest (digest + params->fors.msg_size, &tree_idx, &leaf_idx);
-
-  struct slh_merkle_ctx_public merkle_ctx =
-    { hash, {}, leaf_idx };
+  merkle_ctx_public_init (&merkle_ctx, hash, leaf_idx);
 
   hash->init_tree (&merkle_ctx.tree_ctx, pub, 0, tree_idx);
 
-  uint8_t root[_SLH_DSA_128_SIZE];
-
   _fors_verify (&merkle_ctx, &params->fors, digest, signature, root);
   signature += params->fors.signature_size;
 
index 45901a76d94549a6a4cb9e6a20fab9471fac74b9..516c1765f03666ad1b8140e2718fb877cfa510a3 100644 (file)
@@ -110,10 +110,9 @@ slh_sha256_node (const struct sha256_ctx *tree_ctx,
   slh_sha256_digest (&ctx, out);
 }
 
-static const uint8_t slh_pure_prefix[2] = {0, 0};
-
-void
-_slh_sha256_randomizer (const uint8_t *public_seed, const uint8_t *secret_prf,
+static void
+slh_sha256_randomizer (const uint8_t *public_seed, const uint8_t *secret_prf,
+                      size_t prefix_length, const uint8_t *prefix,
                       size_t msg_length, const uint8_t *msg,
                       uint8_t *randomizer)
 {
@@ -121,16 +120,17 @@ _slh_sha256_randomizer (const uint8_t *public_seed, const uint8_t *secret_prf,
   uint8_t digest[SHA256_DIGEST_SIZE];
   hmac_sha256_set_key (&ctx, _SLH_DSA_128_SIZE, secret_prf);
   hmac_sha256_update (&ctx, _SLH_DSA_128_SIZE, public_seed);
-  hmac_sha256_update (&ctx, sizeof (slh_pure_prefix), slh_pure_prefix);
+  hmac_sha256_update (&ctx, prefix_length, prefix);
   hmac_sha256_update (&ctx, msg_length, msg);
   hmac_sha256_digest (&ctx, digest);
   memcpy (randomizer, digest, _SLH_DSA_128_SIZE);
 }
 
-void
-_slh_sha256_msg_digest (const uint8_t *randomizer, const uint8_t *pub,
-                       size_t length, const uint8_t *msg,
-                       size_t digest_size, uint8_t *digest)
+static void
+slh_sha256_msg_digest (const uint8_t *randomizer, const uint8_t *pub,
+                      size_t prefix_length, const uint8_t *prefix,
+                      size_t length, const uint8_t *msg,
+                      size_t digest_size, uint8_t *digest)
 {
   struct sha256_ctx ctx;
   uint8_t inner[SHA256_DIGEST_SIZE];
@@ -138,7 +138,7 @@ _slh_sha256_msg_digest (const uint8_t *randomizer, const uint8_t *pub,
   sha256_init (&ctx);
   sha256_update (&ctx, _SLH_DSA_128_SIZE, randomizer);
   sha256_update (&ctx, 2*_SLH_DSA_128_SIZE, pub);
-  sha256_update (&ctx, sizeof (slh_pure_prefix), slh_pure_prefix);
+  sha256_update (&ctx, prefix_length, prefix);
   sha256_update (&ctx, length, msg);
   sha256_digest (&ctx, inner);
 
@@ -169,4 +169,6 @@ _slh_hash_sha256 =
     (nettle_hash_digest_func *) slh_sha256_digest,
     (slh_hash_secret_func *) slh_sha256_secret,
     (slh_hash_node_func *) slh_sha256_node,
+    (slh_hash_randomizer_func *) slh_sha256_randomizer,
+    (slh_hash_msg_digest_func *) slh_sha256_msg_digest
   };
index 3bffe078b19b6d488ffac3bae443920c5dd53d9e..3d10d73505a1bdc0c6f8d11f1c21aa84b05b6cce 100644 (file)
@@ -92,35 +92,35 @@ slh_shake_digest (struct sha3_ctx *ctx, uint8_t *out)
   sha3_256_shake (ctx, _SLH_DSA_128_SIZE, out);
 }
 
-static const uint8_t slh_pure_prefix[2] = {0, 0};
-
-void
-_slh_shake_randomizer (const uint8_t *public_seed, const uint8_t *secret_prf,
-                      size_t msg_length, const uint8_t *msg,
-                      uint8_t *randomizer)
+static void
+slh_shake_randomizer (const uint8_t *public_seed, const uint8_t *secret_prf,
+                     size_t prefix_length, const uint8_t *prefix,
+                     size_t msg_length, const uint8_t *msg,
+                     uint8_t *randomizer)
 {
   struct sha3_ctx ctx;
 
   sha3_init (&ctx);
   sha3_256_update (&ctx, _SLH_DSA_128_SIZE, secret_prf);
   sha3_256_update (&ctx, _SLH_DSA_128_SIZE, public_seed);
-  sha3_256_update (&ctx, sizeof (slh_pure_prefix), slh_pure_prefix);
+  sha3_256_update (&ctx, prefix_length, prefix);
   sha3_256_update (&ctx, msg_length, msg);
   sha3_256_shake (&ctx, _SLH_DSA_128_SIZE, randomizer);
 }
 
-void
-_slh_shake_msg_digest (const uint8_t *randomizer, const uint8_t *pub,
-                      size_t length, const uint8_t *msg,
-                      size_t digest_size, uint8_t *digest)
+static void
+slh_shake_msg_digest (const uint8_t *randomizer, const uint8_t *pub,
+                     size_t prefix_length, const uint8_t *prefix,
+                     size_t msg_length, const uint8_t *msg,
+                     size_t digest_size, uint8_t *digest)
 {
   struct sha3_ctx ctx;
 
   sha3_init (&ctx);
   sha3_256_update (&ctx, _SLH_DSA_128_SIZE, randomizer);
   sha3_256_update (&ctx, 2*_SLH_DSA_128_SIZE, pub);
-  sha3_256_update (&ctx, sizeof (slh_pure_prefix), slh_pure_prefix);
-  sha3_256_update (&ctx, length, msg);
+  sha3_256_update (&ctx, prefix_length, prefix);
+  sha3_256_update (&ctx, msg_length, msg);
   sha3_256_shake (&ctx, digest_size, digest);
 }
 
@@ -133,4 +133,6 @@ _slh_hash_shake =
     (nettle_hash_digest_func *) slh_shake_digest,
     (slh_hash_secret_func *) slh_shake_secret,
     (slh_hash_node_func *) slh_shake_node,
+    (slh_hash_randomizer_func *) slh_shake_randomizer,
+    (slh_hash_msg_digest_func *) slh_shake_msg_digest
   };