void
_fors_sign (const struct slh_merkle_ctx_secret *ctx,
const struct slh_fors_params *fors,
- const uint8_t *msg, uint8_t *signature, uint8_t *pub);
+ const uint8_t *msg, uint8_t *signature, uint8_t *pub,
+ /* Allocated by caller, initialized and clobbered by callee. */
+ void *pub_ctx);
/* Computes candidate public key from signature. */
void
_fors_verify (const struct slh_merkle_ctx_public *ctx,
const struct slh_fors_params *fors,
- const uint8_t *msg, const uint8_t *signature, uint8_t *pub);
+ const uint8_t *msg, const uint8_t *signature, uint8_t *pub,
+ /* Allocated by caller, initialized and clobbered by callee. */
+ void *pub_ctx);
/* Just the auth path, excluding the wots signature, 144 bytes. */
#define XMSS_AUTH_SIZE(h) ((h) * _SLH_DSA_128_SIZE)
uint8_t root[_SLH_DSA_128_SIZE];
- _fors_sign (&merkle_ctx, ¶ms->fors, digest, signature, root);
+ union slh_hash_ctx scratch_ctx;
+ _fors_sign (&merkle_ctx, ¶ms->fors, digest, signature, root, &scratch_ctx);
signature += params->fors.signature_size;
_xmss_sign (&merkle_ctx, params->xmss.h, leaf_idx, root, signature, root);
uint8_t root[_SLH_DSA_128_SIZE];
- _fors_verify (&merkle_ctx, ¶ms->fors, digest, signature, root);
+ union slh_hash_ctx scratch_ctx;
+ _fors_verify (&merkle_ctx, ¶ms->fors, digest, signature, root, &scratch_ctx);
signature += params->fors.signature_size;
_xmss_verify (&merkle_ctx, params->xmss.h, leaf_idx, root, signature, root);
static void
fors_sign_one (const struct slh_merkle_ctx_secret *ctx, unsigned a,
- unsigned idx, uint8_t *signature, void *pub)
+ unsigned idx, uint8_t *signature, void *pub_ctx)
{
uint8_t hash[_SLH_DSA_128_SIZE];
_merkle_sign (ctx, fors_leaf, fors_node, a, idx, signature);
_merkle_verify (&ctx->pub, fors_node, a, idx, signature, hash);
- ctx->pub.hash->update (pub, _SLH_DSA_128_SIZE, hash);
+ ctx->pub.hash->update (pub_ctx, _SLH_DSA_128_SIZE, hash);
}
void
_fors_sign (const struct slh_merkle_ctx_secret *ctx,
const struct slh_fors_params *fors,
- const uint8_t *msg, uint8_t *signature, uint8_t *pub)
+ const uint8_t *msg, uint8_t *signature, uint8_t *pub,
+ void *pub_ctx)
{
struct slh_address_hash ah =
{
bswap32_if_le (ctx->pub.keypair),
0, 0,
};
- union slh_hash_ctx pub_ctx;
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)
{
w = (w << 8) | *msg++;
bits -= fors->a;
- fors_sign_one (ctx, fors->a, (i << fors->a) + ((w >> bits) & mask), signature, &pub_ctx);
+ fors_sign_one (ctx, fors->a, (i << fors->a) + ((w >> bits) & mask), signature, pub_ctx);
}
- ctx->pub.hash->digest (&pub_ctx, pub);
+ ctx->pub.hash->digest (pub_ctx, pub);
}
static void
void
_fors_verify (const struct slh_merkle_ctx_public *ctx,
const struct slh_fors_params *fors,
- const uint8_t *msg, const uint8_t *signature, uint8_t *pub)
+ const uint8_t *msg, const uint8_t *signature, uint8_t *pub,
+ void *pub_ctx)
{
struct slh_address_hash ah =
{
bswap32_if_le (ctx->keypair),
0, 0,
};
- union slh_hash_ctx pub_ctx;
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)
{
w = (w << 8) | *msg++;
bits -= fors->a;
- fors_verify_one (ctx, fors->a, (i << fors->a) + ((w >> bits) & mask), signature, &pub_ctx);
+ fors_verify_one (ctx, fors->a, (i << fors->a) + ((w >> bits) & mask), signature, pub_ctx);
}
- ctx->hash->digest (&pub_ctx, pub);
+ ctx->hash->digest (pub_ctx, pub);
}
unsigned layer, uint64_t tree_idx, unsigned keypair, const struct tstring *msg,
const struct tstring *exp_pub, const struct tstring *exp_sig)
{
- union slh_hash_ctx tree_ctx;
+ struct sha3_ctx tree_ctx, scratch_ctx;
const struct slh_merkle_ctx_secret ctx =
{
{ &_slh_hash_shake, &tree_ctx, keypair },
_slh_hash_shake.init_tree (&tree_ctx, public_seed->data, layer, tree_idx);
- _fors_sign (&ctx, fors, msg->data, sig, pub);
+ _fors_sign (&ctx, fors, msg->data, sig, pub, &scratch_ctx);
mark_bytes_defined (exp_sig->length, sig);
mark_bytes_defined (sizeof (pub), pub);
ASSERT (MEMEQ (exp_sig->length, sig, exp_sig->data));
ASSERT (MEMEQ (sizeof (pub), pub, exp_pub->data));
memset (pub, 0, sizeof (pub));
- _fors_verify (&ctx.pub, fors, msg->data, sig, pub);
+ _fors_verify (&ctx.pub, fors, msg->data, sig, pub, &scratch_ctx);
ASSERT (MEMEQ (sizeof (pub), pub, exp_pub->data));
free (sig);
}