in xmss_fast.c [663:743]
int xmss_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigned char *sig_msg, unsigned long long sig_msg_len, const unsigned char *pk, const xmss_params *params)
{
unsigned int n = params->n;
unsigned long long i, m_len;
unsigned long idx=0;
unsigned char wots_pk[params->wots_par.keysize];
unsigned char pkhash[n];
unsigned char root[n];
unsigned char msg_h[n];
unsigned char hash_key[3*n];
unsigned char pub_seed[n];
memcpy(pub_seed, pk+n, n);
// Init addresses
uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint32_t ltree_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint32_t node_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
setType(ots_addr, 0);
setType(ltree_addr, 1);
setType(node_addr, 2);
// Extract index
idx = ((unsigned long)sig_msg[0] << 24) | ((unsigned long)sig_msg[1] << 16) | ((unsigned long)sig_msg[2] << 8) | sig_msg[3];
printf("verify:: idx = %lu\n", idx);
// Generate hash key (R || root || idx)
memcpy(hash_key, sig_msg+4,n);
memcpy(hash_key+n, pk, n);
to_byte(hash_key+2*n, idx, n);
sig_msg += (n+4);
sig_msg_len -= (n+4);
// hash message
unsigned long long tmp_sig_len = params->wots_par.keysize+params->h*n;
m_len = sig_msg_len - tmp_sig_len;
h_msg(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 3*n, n);
//-----------------------
// Verify signature
//-----------------------
// Prepare Address
setOTSADRS(ots_addr, idx);
// Check WOTS signature
wots_pkFromSig(wots_pk, sig_msg, msg_h, &(params->wots_par), pub_seed, ots_addr);
sig_msg += params->wots_par.keysize;
sig_msg_len -= params->wots_par.keysize;
// Compute Ltree
setLtreeADRS(ltree_addr, idx);
l_tree(pkhash, wots_pk, params, pub_seed, ltree_addr);
// Compute root
validate_authpath(root, pkhash, idx, sig_msg, params, pub_seed, node_addr);
sig_msg += params->h*n;
sig_msg_len -= params->h*n;
for (i = 0; i < n; i++)
if (root[i] != pk[i])
goto fail;
*msglen = sig_msg_len;
for (i = 0; i < *msglen; i++)
msg[i] = sig_msg[i];
return 0;
fail:
*msglen = sig_msg_len;
for (i = 0; i < *msglen; i++)
msg[i] = 0;
*msglen = -1;
return -1;
}