#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
#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
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,
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;
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. */
_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,
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
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);
}
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
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);
}
#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, ¶ms->fors, digest, signature, root);
signature += params->fors.signature_size;
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, ¶ms->fors, digest, signature, root);
signature += params->fors.signature_size;
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)
{
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];
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);
(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
};
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);
}
(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
};