struct slh_merkle_ctx_public
{
const struct slh_hash *hash;
- /* Initialized using hash->init_tree. */
- union slh_hash_ctx tree_ctx;
+ /* Initialized based on public seed and slh_address_tree. */
+ const void *tree_ctx;
unsigned keypair; /* Used only by fors_leaf and fors_node. */
};
_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);
- hash->init_tree (&merkle_ctx.pub.tree_ctx, pub, 0, tree_idx);
+ union slh_hash_ctx tree_ctx;
+ const struct slh_merkle_ctx_secret merkle_ctx =
+ {
+ { hash, &tree_ctx, leaf_idx },
+ priv,
+ };
+ hash->init_tree (&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;
leaf_idx = tree_idx & ((1 << params->xmss.h) - 1);
tree_idx >>= params->xmss.h;
- hash->init_tree (&merkle_ctx.pub.tree_ctx, pub, i, tree_idx);
+ hash->init_tree (&tree_ctx, pub, i, tree_idx);
_xmss_sign (&merkle_ctx, params->xmss.h, leaf_idx, root, signature, root);
}
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);
- merkle_ctx_public_init (&merkle_ctx, hash, leaf_idx);
- hash->init_tree (&merkle_ctx.tree_ctx, pub, 0, tree_idx);
+ union slh_hash_ctx tree_ctx;
+ const struct slh_merkle_ctx_public merkle_ctx =
+ { hash, &tree_ctx, leaf_idx };
+
+ hash->init_tree (&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;
leaf_idx = tree_idx & ((1 << params->xmss.h) - 1);
tree_idx >>= params->xmss.h;
- hash->init_tree (&merkle_ctx.tree_ctx, pub, i, tree_idx);
+ hash->init_tree (&tree_ctx, pub, i, tree_idx);
_xmss_verify (&merkle_ctx, params->xmss.h, leaf_idx, root, signature, root);
}
bswap32_if_le (idx),
};
- ctx->pub.hash->secret (&ctx->pub.tree_ctx, &ah, ctx->secret_seed, sk);
+ ctx->pub.hash->secret (ctx->pub.tree_ctx, &ah, ctx->secret_seed, sk);
ah.type = bswap32_if_le (SLH_FORS_TREE);
- ctx->pub.hash->secret (&ctx->pub.tree_ctx, &ah, sk, leaf);
+ ctx->pub.hash->secret (ctx->pub.tree_ctx, &ah, sk, leaf);
}
static void
bswap32_if_le (height),
bswap32_if_le (index),
};
- ctx->hash->node (&ctx->tree_ctx, &ah, left, right, out);
+ ctx->hash->node (ctx->tree_ctx, &ah, left, right, out);
}
static void
unsigned i, w, bits;
unsigned mask = (1 << fors->a) - 1;
- ctx->pub.hash->init_hash (&ctx->pub.tree_ctx, &pub_ctx, &ah);
+ ctx->pub.hash->init_hash (ctx->pub.tree_ctx, &pub_ctx, &ah);
for (i = w = bits = 0; i < fors->k; i++, signature += (fors->a + 1) * _SLH_DSA_128_SIZE)
{
bswap32_if_le (idx),
};
- ctx->hash->secret (&ctx->tree_ctx, &ah, signature, root);
+ ctx->hash->secret (ctx->tree_ctx, &ah, signature, root);
_merkle_verify (ctx, fors_node, a, idx, signature + _SLH_DSA_128_SIZE, root);
ctx->hash->update (pub, _SLH_DSA_128_SIZE, root);
unsigned i, w, bits;
unsigned mask = (1 << fors->a) - 1;
- ctx->hash->init_hash (&ctx->tree_ctx, &pub_ctx, &ah);
+ ctx->hash->init_hash (ctx->tree_ctx, &pub_ctx, &ah);
for (i = w = bits = 0; i < fors->k; i++, signature += (fors->a + 1) * _SLH_DSA_128_SIZE)
{
static void
xmss_leaf (const struct slh_merkle_ctx_secret *ctx, unsigned idx, uint8_t *leaf)
{
- _wots_gen (ctx->pub.hash, &ctx->pub.tree_ctx, ctx->secret_seed, idx, leaf);
+ _wots_gen (ctx->pub.hash, ctx->pub.tree_ctx, ctx->secret_seed, idx, leaf);
}
static void
bswap32_if_le (height),
bswap32_if_le (index),
};
- ctx->hash->node (&ctx->tree_ctx, &ah, left, right, out);
+ ctx->hash->node (ctx->tree_ctx, &ah, left, right, out);
}
void
const struct slh_xmss_params *xmss,
uint8_t *scratch, uint8_t *root)
{
- struct slh_merkle_ctx_secret ctx =
+ union slh_hash_ctx tree_ctx;
+ const struct slh_merkle_ctx_secret ctx =
{
- { hash, {}, 0 },
+ { hash, &tree_ctx, 0 },
secret_seed
};
- hash->init_tree (&ctx.pub.tree_ctx, public_seed, xmss->d - 1, 0);
+ hash->init_tree (&tree_ctx, public_seed, xmss->d - 1, 0);
_merkle_root (&ctx, xmss_leaf, xmss_node, xmss->h, 0, root, scratch);
}
_xmss_sign (const struct slh_merkle_ctx_secret *ctx, unsigned h,
unsigned idx, const uint8_t *msg, uint8_t *signature, uint8_t *pub)
{
- _wots_sign (ctx->pub.hash, &ctx->pub.tree_ctx, ctx->secret_seed, idx, msg, signature, pub);
+ _wots_sign (ctx->pub.hash, ctx->pub.tree_ctx, ctx->secret_seed, idx, msg, signature, pub);
signature += WOTS_SIGNATURE_SIZE;
_merkle_sign (ctx, xmss_leaf, xmss_node, h, idx, signature);
_xmss_verify (const struct slh_merkle_ctx_public *ctx, unsigned h,
unsigned idx, const uint8_t *msg, const uint8_t *signature, uint8_t *pub)
{
- _wots_verify (ctx->hash, &ctx->tree_ctx, idx, msg, signature, pub);
+ _wots_verify (ctx->hash, ctx->tree_ctx, idx, msg, signature, pub);
signature += WOTS_SIGNATURE_SIZE;
_merkle_verify (ctx, xmss_node, h, idx, signature, pub);
static void
xmss_leaf (const struct slh_merkle_ctx_secret *ctx, unsigned idx, uint8_t *leaf)
{
- _wots_gen (ctx->pub.hash, &ctx->pub.tree_ctx, ctx->secret_seed, idx, leaf);
+ _wots_gen (ctx->pub.hash, ctx->pub.tree_ctx, ctx->secret_seed, idx, leaf);
mark_bytes_defined (SLH_DSA_128_SEED_SIZE, leaf);
}
bswap32_if_le (index),
};
- ctx->hash->node (&ctx->tree_ctx, &ah, left, right, out);
+ ctx->hash->node (ctx->tree_ctx, &ah, left, right, out);
}
static void
unsigned layer, uint64_t tree_idx, uint32_t idx, const struct tstring *msg,
const struct tstring *exp_pub, const struct tstring *exp_sig)
{
- struct slh_merkle_ctx_secret ctx =
+ union slh_hash_ctx tree_ctx;
+ const struct slh_merkle_ctx_secret ctx =
{
- { &_slh_hash_shake, {}, 0 },
+ { &_slh_hash_shake, &tree_ctx, 0 },
secret_seed->data,
};
ASSERT (exp_pub->length == _SLH_DSA_128_SIZE);
ASSERT (exp_sig->length == XMSS_AUTH_SIZE (h));
- _slh_hash_shake.init_tree (&ctx.pub.tree_ctx, public_seed->data, layer, tree_idx);
+ _slh_hash_shake.init_tree (&tree_ctx, public_seed->data, layer, tree_idx);
_merkle_sign (&ctx, xmss_leaf, xmss_node, h, idx, sig);
ASSERT (MEMEQ (exp_sig->length, sig, exp_sig->data));
unsigned layer, uint64_t tree_idx, unsigned keypair, unsigned idx,
const struct tstring *exp_sk, const struct tstring *exp_leaf)
{
- struct slh_merkle_ctx_secret ctx =
+ union slh_hash_ctx tree_ctx;
+ const struct slh_merkle_ctx_secret ctx =
{
- { &_slh_hash_shake, {}, keypair },
+ { &_slh_hash_shake, &tree_ctx, keypair },
secret_seed->data,
};
uint8_t sk[_SLH_DSA_128_SIZE];
ASSERT (exp_sk->length == _SLH_DSA_128_SIZE);
ASSERT (exp_leaf->length == _SLH_DSA_128_SIZE);
- _slh_hash_shake.init_tree (&ctx.pub.tree_ctx, public_seed->data, layer, tree_idx);
+ _slh_hash_shake.init_tree (&tree_ctx, public_seed->data, layer, tree_idx);
_fors_gen (&ctx, idx, sk, leaf);
mark_bytes_defined (sizeof (sk), sk);
unsigned layer, uint64_t tree_idx, unsigned keypair, const struct tstring *msg,
const struct tstring *exp_pub, const struct tstring *exp_sig)
{
- struct slh_merkle_ctx_secret ctx =
+ union slh_hash_ctx tree_ctx;
+ const struct slh_merkle_ctx_secret ctx =
{
- { &_slh_hash_shake, {}, keypair },
+ { &_slh_hash_shake, &tree_ctx, keypair },
secret_seed->data,
};
uint8_t pub[_SLH_DSA_128_SIZE];
ASSERT (exp_pub->length == _SLH_DSA_128_SIZE);
ASSERT (exp_sig->length == fors->signature_size);
- _slh_hash_shake.init_tree (&ctx.pub.tree_ctx, public_seed->data, layer, tree_idx);
+ _slh_hash_shake.init_tree (&tree_ctx, public_seed->data, layer, tree_idx);
_fors_sign (&ctx, fors, msg->data, sig, pub);
mark_bytes_defined (exp_sig->length, sig);
unsigned layer, uint64_t tree_idx, uint32_t idx, const struct tstring *msg,
const struct tstring *exp_pub, const struct tstring *exp_sig)
{
- struct slh_merkle_ctx_secret ctx =
+ union slh_hash_ctx tree_ctx;
+ const struct slh_merkle_ctx_secret ctx =
{
- { &_slh_hash_shake, {}, 0 },
+ { &_slh_hash_shake, &tree_ctx, 0 },
secret_seed->data,
};
ASSERT (exp_pub->length == _SLH_DSA_128_SIZE);
ASSERT (exp_sig->length == XMSS_SIGNATURE_SIZE (xmss_h));
- _slh_hash_shake.init_tree (&ctx.pub.tree_ctx, public_seed->data, layer, tree_idx);
+ _slh_hash_shake.init_tree (&tree_ctx, public_seed->data, layer, tree_idx);
_xmss_sign (&ctx, xmss_h, idx, msg->data, sig, pub);
mark_bytes_defined (sizeof (pub), pub);