Make XMSS sign/open functions instances of XMSSMT

This removes a lot of code duplication.
This commit is contained in:
Joost Rijneveld 2017-10-26 12:07:29 +02:00
parent 7c6354f762
commit 94a92ed2b1
No known key found for this signature in database
GPG Key ID: A4FE39CF49CBC553
2 changed files with 10 additions and 100 deletions

View File

@ -190,56 +190,11 @@ int xmss_core_sign_open(const xmss_params *params,
const unsigned char *sm, unsigned long long smlen,
const unsigned char *pk)
{
const unsigned char *pub_seed = pk + params->n;
unsigned char wots_pk[params->wots_sig_bytes];
unsigned char leaf[params->n];
unsigned char root[params->n];
unsigned char mhash[params->n];
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;
/* XMSS signatures are fundamentally an instance of XMSSMT signatures.
For d=1, as is the case with XMSS, some of the calls in the XMSSMT
routine become vacuous (i.e. the loop only iterates once, and address
management can be simplified a bit).*/
return xmssmt_core_sign_open(params, m, mlen, sm, smlen, pk);
}
/**

View File

@ -107,56 +107,11 @@ int xmss_core_sign(const xmss_params *params,
unsigned char *sm, unsigned long long *smlen,
const unsigned char *m, unsigned long long mlen)
{
const unsigned char *sk_seed = sk + params->index_bytes;
const unsigned char *sk_prf = sk + params->index_bytes + params->n;
const unsigned char *pub_seed = sk + params->index_bytes + 2*params->n;
const unsigned char *pub_root = sk + params->index_bytes + 3*params->n;
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;
/* XMSS signatures are fundamentally an instance of XMSSMT signatures.
For d=1, as is the case with XMSS, some of the calls in the XMSSMT
routine become vacuous (i.e. the loop only iterates once, and address
management can be simplified a bit).*/
return xmssmt_core_sign(params, sk, sm, smlen, m, mlen);
}
/*