in xmss_fast.c [383:439]
static char bds_state_update(bds_state *state, const unsigned char *sk_seed, const xmss_params *params, unsigned char *pub_seed, const uint32_t addr[8]) {
uint32_t ltree_addr[8];
uint32_t node_addr[8];
uint32_t ots_addr[8];
int n = params->n;
int h = params->h;
int k = params->k;
int nodeh;
int idx = state->next_leaf;
if (idx == 1 << h) {
return 1;
}
// 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);
setOTSADRS(ots_addr, idx);
setLtreeADRS(ltree_addr, idx);
gen_leaf_wots(state->stack+state->stackoffset*n, sk_seed, params, pub_seed, ltree_addr, ots_addr);
state->stacklevels[state->stackoffset] = 0;
state->stackoffset++;
if (h - k > 0 && idx == 3) {
memcpy(state->treehash[0].node, state->stack+state->stackoffset*n, n);
}
while (state->stackoffset>1 && state->stacklevels[state->stackoffset-1] == state->stacklevels[state->stackoffset-2]) {
nodeh = state->stacklevels[state->stackoffset-1];
if (idx >> nodeh == 1) {
memcpy(state->auth + nodeh*n, state->stack+(state->stackoffset-1)*n, n);
}
else {
if (nodeh < h - k && idx >> nodeh == 3) {
memcpy(state->treehash[nodeh].node, state->stack+(state->stackoffset-1)*n, n);
}
else if (nodeh >= h - k) {
memcpy(state->retain + ((1 << (h - 1 - nodeh)) + nodeh - h + (((idx >> nodeh) - 3) >> 1)) * n, state->stack+(state->stackoffset-1)*n, n);
}
}
setTreeHeight(node_addr, state->stacklevels[state->stackoffset-1]);
setTreeIndex(node_addr, (idx >> (state->stacklevels[state->stackoffset-1]+1)));
hash_h(state->stack+(state->stackoffset-2)*n, state->stack+(state->stackoffset-2)*n, pub_seed, node_addr, n);
state->stacklevels[state->stackoffset-2]++;
state->stackoffset--;
}
state->next_leaf++;
return 0;
}