Make XMSS sign/open functions instances of XMSSMT
This removes a lot of code duplication.
This commit is contained in:
parent
7c6354f762
commit
94a92ed2b1
@ -190,56 +190,11 @@ int xmss_core_sign_open(const xmss_params *params,
|
|||||||
const unsigned char *sm, unsigned long long smlen,
|
const unsigned char *sm, unsigned long long smlen,
|
||||||
const unsigned char *pk)
|
const unsigned char *pk)
|
||||||
{
|
{
|
||||||
const unsigned char *pub_seed = pk + params->n;
|
/* XMSS signatures are fundamentally an instance of XMSSMT signatures.
|
||||||
unsigned char wots_pk[params->wots_sig_bytes];
|
For d=1, as is the case with XMSS, some of the calls in the XMSSMT
|
||||||
unsigned char leaf[params->n];
|
routine become vacuous (i.e. the loop only iterates once, and address
|
||||||
unsigned char root[params->n];
|
management can be simplified a bit).*/
|
||||||
unsigned char mhash[params->n];
|
return xmssmt_core_sign_open(params, m, mlen, sm, smlen, pk);
|
||||||
unsigned long idx;
|
|
||||||
|
|
||||||
uint32_t ots_addr[8] = {0};
|
|
||||||
uint32_t ltree_addr[8] = {0};
|
|
||||||
uint32_t node_addr[8] = {0};
|
|
||||||
|
|
||||||
set_type(ots_addr, XMSS_ADDR_TYPE_OTS);
|
|
||||||
set_type(ltree_addr, XMSS_ADDR_TYPE_LTREE);
|
|
||||||
set_type(node_addr, XMSS_ADDR_TYPE_HASHTREE);
|
|
||||||
|
|
||||||
*mlen = smlen - params->sig_bytes;
|
|
||||||
|
|
||||||
/* Convert the index bytes from the signature to an integer. */
|
|
||||||
idx = (unsigned long)bytes_to_ull(sm, params->index_bytes);
|
|
||||||
|
|
||||||
/* Compute the message hash. */
|
|
||||||
hash_message(params, mhash, sm + params->index_bytes, pk, idx,
|
|
||||||
sm + params->sig_bytes, *mlen);
|
|
||||||
sm += params->index_bytes + params->n;
|
|
||||||
|
|
||||||
/* The WOTS public key is only correct if the signature was correct. */
|
|
||||||
set_ots_addr(ots_addr, idx);
|
|
||||||
wots_pk_from_sig(params, wots_pk, sm, mhash, pub_seed, ots_addr);
|
|
||||||
sm += params->wots_sig_bytes;
|
|
||||||
|
|
||||||
/* Compute the leaf node using the WOTS public key. */
|
|
||||||
set_ltree_addr(ltree_addr, idx);
|
|
||||||
l_tree(params, leaf, wots_pk, pub_seed, ltree_addr);
|
|
||||||
|
|
||||||
/* Compute the root node. */
|
|
||||||
compute_root(params, root, leaf, idx, sm, pub_seed, node_addr);
|
|
||||||
sm += params->tree_height*params->n;
|
|
||||||
|
|
||||||
/* Check if the root node equals the root node in the public key. */
|
|
||||||
if (memcmp(root, pk, params->n)) {
|
|
||||||
/* If not, zero the message */
|
|
||||||
memset(m, 0, *mlen);
|
|
||||||
*mlen = -1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If verification was successful, copy the message from the signature. */
|
|
||||||
memcpy(m, sm, *mlen);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
55
xmss_core.c
55
xmss_core.c
@ -107,56 +107,11 @@ int xmss_core_sign(const xmss_params *params,
|
|||||||
unsigned char *sm, unsigned long long *smlen,
|
unsigned char *sm, unsigned long long *smlen,
|
||||||
const unsigned char *m, unsigned long long mlen)
|
const unsigned char *m, unsigned long long mlen)
|
||||||
{
|
{
|
||||||
const unsigned char *sk_seed = sk + params->index_bytes;
|
/* XMSS signatures are fundamentally an instance of XMSSMT signatures.
|
||||||
const unsigned char *sk_prf = sk + params->index_bytes + params->n;
|
For d=1, as is the case with XMSS, some of the calls in the XMSSMT
|
||||||
const unsigned char *pub_seed = sk + params->index_bytes + 2*params->n;
|
routine become vacuous (i.e. the loop only iterates once, and address
|
||||||
const unsigned char *pub_root = sk + params->index_bytes + 3*params->n;
|
management can be simplified a bit).*/
|
||||||
|
return xmssmt_core_sign(params, sk, sm, smlen, m, mlen);
|
||||||
unsigned char root[params->n];
|
|
||||||
unsigned char mhash[params->n];
|
|
||||||
unsigned char ots_seed[params->n];
|
|
||||||
unsigned long idx;
|
|
||||||
unsigned char idx_bytes_32[32];
|
|
||||||
|
|
||||||
uint32_t ots_addr[8] = {0};
|
|
||||||
set_type(ots_addr, XMSS_ADDR_TYPE_OTS);
|
|
||||||
|
|
||||||
/* Read and use the current index from the secret key. */
|
|
||||||
idx = (unsigned long)bytes_to_ull(sk, params->index_bytes);
|
|
||||||
memcpy(sm, sk, params->index_bytes);
|
|
||||||
sm += params->index_bytes;
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
* THIS IS WHERE PRODUCTION IMPLEMENTATIONS WOULD UPDATE THE SECRET KEY. *
|
|
||||||
*************************************************************************/
|
|
||||||
/* Increment the index in the secret key. */
|
|
||||||
ull_to_bytes(sk, params->index_bytes, idx + 1);
|
|
||||||
|
|
||||||
/* Compute the digest randomization value. */
|
|
||||||
ull_to_bytes(idx_bytes_32, 32, idx);
|
|
||||||
prf(params, sm, idx_bytes_32, sk_prf, params->n);
|
|
||||||
|
|
||||||
/* Compute the message hash. */
|
|
||||||
hash_message(params, mhash, sm, pub_root, idx, m, mlen);
|
|
||||||
sm += params->n;
|
|
||||||
|
|
||||||
set_ots_addr(ots_addr, idx);
|
|
||||||
|
|
||||||
/* Get a seed for the WOTS keypair. */
|
|
||||||
get_seed(params, ots_seed, sk_seed, ots_addr);
|
|
||||||
|
|
||||||
/* Compute a WOTS signature on the message hash. */
|
|
||||||
wots_sign(params, sm, mhash, ots_seed, pub_seed, ots_addr);
|
|
||||||
sm += params->wots_sig_bytes;
|
|
||||||
|
|
||||||
/* Compute the authentication path for the used WOTS leaf. */
|
|
||||||
treehash(params, root, sm, sk_seed, pub_seed, idx, ots_addr);
|
|
||||||
sm += params->tree_height*params->n;
|
|
||||||
|
|
||||||
memcpy(sm, m, mlen);
|
|
||||||
*smlen = params->sig_bytes + mlen;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user