in xmss_fast.c [178:247]
static void treehash_setup(unsigned char *node, int height, int index, bds_state *state, const unsigned char *sk_seed, const xmss_params *params, const unsigned char *pub_seed, const uint32_t addr[8])
{
unsigned int idx = index;
unsigned int n = params->n;
unsigned int h = params->h;
unsigned int k = params->k;
// use three different addresses because at this point we use all three formats in parallel
uint32_t ots_addr[8];
uint32_t ltree_addr[8];
uint32_t node_addr[8];
// only copy layer and tree address parts
memcpy(ots_addr, addr, 12);
// type = ots
setType(ots_addr, 0);
memcpy(ltree_addr, addr, 12);
setType(ltree_addr, 1);
memcpy(node_addr, addr, 12);
setType(node_addr, 2);
uint32_t lastnode, i;
unsigned char stack[(height+1)*n];
unsigned int stacklevels[height+1];
unsigned int stackoffset=0;
unsigned int nodeh;
lastnode = idx+(1<<height);
for (i = 0; i < h-k; i++) {
state->treehash[i].h = i;
state->treehash[i].completed = 1;
state->treehash[i].stackusage = 0;
}
i = 0;
for (; idx < lastnode; idx++) {
setLtreeADRS(ltree_addr, idx);
setOTSADRS(ots_addr, idx);
gen_leaf_wots(stack+stackoffset*n, sk_seed, params, pub_seed, ltree_addr, ots_addr);
stacklevels[stackoffset] = 0;
stackoffset++;
if (h - k > 0 && i == 3) {
memcpy(state->treehash[0].node, stack+stackoffset*n, n);
}
while (stackoffset>1 && stacklevels[stackoffset-1] == stacklevels[stackoffset-2])
{
nodeh = stacklevels[stackoffset-1];
if (i >> nodeh == 1) {
memcpy(state->auth + nodeh*n, stack+(stackoffset-1)*n, n);
}
else {
if (nodeh < h - k && i >> nodeh == 3) {
memcpy(state->treehash[nodeh].node, stack+(stackoffset-1)*n, n);
}
else if (nodeh >= h - k) {
memcpy(state->retain + ((1 << (h - 1 - nodeh)) + nodeh - h + (((i >> nodeh) - 3) >> 1)) * n, stack+(stackoffset-1)*n, n);
}
}
setTreeHeight(node_addr, stacklevels[stackoffset-1]);
setTreeIndex(node_addr, (idx >> (stacklevels[stackoffset-1]+1)));
hash_h(stack+(stackoffset-2)*n, stack+(stackoffset-2)*n, pub_seed,
node_addr, n);
stacklevels[stackoffset-2]++;
stackoffset--;
}
i++;
}
for (i = 0; i < n; i++)
node[i] = stack[i];
}