internal static void treehash(HashFunctions hs, byte[] node, int nodeOff, int height, byte[] sk, leafaddr leaf, byte[] masks, int masksOff) { leafaddr a = new leafaddr(leaf); ulong lastnode; int i; byte[] stack = new byte[(height + 1) * SPHINCS256Config.HASH_BYTES]; int[] stacklevels = new int[height + 1]; int stackoffset = 0; lastnode = a.subleaf + (1UL << height); for (; a.subleaf < lastnode; a.subleaf++) { gen_leaf_wots(hs, stack, stackoffset * SPHINCS256Config.HASH_BYTES, masks, masksOff, sk, a); stacklevels[stackoffset] = 0; stackoffset++; while (stackoffset > 1 && stacklevels[stackoffset - 1] == stacklevels[stackoffset - 2]) { //MASKS int maskoffset = 2 * (stacklevels[stackoffset - 1] + Wots.WOTS_LOG_L) * SPHINCS256Config.HASH_BYTES; hs.hash_2n_n_mask(stack, (stackoffset - 2) * SPHINCS256Config.HASH_BYTES, stack, (stackoffset - 2) * SPHINCS256Config.HASH_BYTES, masks, masksOff + maskoffset); stacklevels[stackoffset - 2]++; stackoffset--; } } for (i = 0; i < SPHINCS256Config.HASH_BYTES; i++) { node[nodeOff + i] = stack[i]; } }
static void gen_leaf_wots(HashFunctions hs, byte[] leaf, int leafOff, byte[] masks, int masksOff, byte[] sk, leafaddr a) { byte[] seed = new byte[SPHINCS256Config.SEED_BYTES]; byte[] pk = new byte[Wots.WOTS_L * SPHINCS256Config.HASH_BYTES]; Wots w = new Wots(); Seed.get_seed(hs, seed, 0, sk, a); w.wots_pkgen(hs, pk, 0, seed, 0, masks, masksOff); l_tree(hs, leaf, leafOff, pk, 0, masks, masksOff); }
public leafaddr(leafaddr leafaddr) { this.level = leafaddr.level; this.subtree = leafaddr.subtree; this.subleaf = leafaddr.subleaf; }