static void compute_authpath_wots(HashFunctions hs, byte[] root, byte[] authpath, int authOff, Tree.leafaddr a, byte[] sk, byte[] masks, int height) { int i, j; uint idx; Tree.leafaddr ta = new Tree.leafaddr(a); byte[] tree = new byte[2 * (1 << SPHINCS256Config.SUBTREE_HEIGHT) * SPHINCS256Config.HASH_BYTES]; byte[] seed = new byte[(1 << SPHINCS256Config.SUBTREE_HEIGHT) * SPHINCS256Config.SEED_BYTES]; byte[] pk = new byte[(1 << SPHINCS256Config.SUBTREE_HEIGHT) * Wots.WOTS_L * SPHINCS256Config.HASH_BYTES]; // level 0 for (ta.subleaf = 0; ta.subleaf < (1UL << SPHINCS256Config.SUBTREE_HEIGHT); ta.subleaf++) { Seed.get_seed(hs, seed, (int)(ta.subleaf * (ulong)SPHINCS256Config.SEED_BYTES), sk, ta); } Wots w = new Wots(); for (ta.subleaf = 0; ta.subleaf < (1UL << SPHINCS256Config.SUBTREE_HEIGHT); ta.subleaf++) { w.wots_pkgen(hs, pk, (int)(ta.subleaf * (ulong)Wots.WOTS_L * (ulong)SPHINCS256Config.HASH_BYTES), seed, (int)(ta.subleaf * (ulong)SPHINCS256Config.SEED_BYTES), masks, 0); } for (ta.subleaf = 0; ta.subleaf < (1UL << SPHINCS256Config.SUBTREE_HEIGHT); ta.subleaf++) { Tree.l_tree(hs, tree, (int)((1UL << SPHINCS256Config.SUBTREE_HEIGHT) * (ulong)SPHINCS256Config.HASH_BYTES + ta.subleaf * (ulong)SPHINCS256Config.HASH_BYTES), pk, (int)(ta.subleaf * (ulong)Wots.WOTS_L * (ulong)SPHINCS256Config.HASH_BYTES), masks, 0); } int level = 0; // tree for (i = (1 << SPHINCS256Config.SUBTREE_HEIGHT); i > 0; i >>= 1) { for (j = 0; j < i; j += 2) { hs.hash_2n_n_mask(tree, (i >> 1) * SPHINCS256Config.HASH_BYTES + (j >> 1) * SPHINCS256Config.HASH_BYTES, tree, i * SPHINCS256Config.HASH_BYTES + j * SPHINCS256Config.HASH_BYTES, masks, 2 * (Wots.WOTS_LOG_L + level) * SPHINCS256Config.HASH_BYTES); } level++; } idx = (uint)a.subleaf; // copy authpath for (i = 0; i < height; i++) { Array.Copy(tree, ((1 << SPHINCS256Config.SUBTREE_HEIGHT) >> i) * SPHINCS256Config.HASH_BYTES + ((idx >> i) ^ 1) * SPHINCS256Config.HASH_BYTES, authpath, authOff + i * SPHINCS256Config.HASH_BYTES, SPHINCS256Config.HASH_BYTES); } // copy root Array.Copy(tree, SPHINCS256Config.HASH_BYTES, root, 0, SPHINCS256Config.HASH_BYTES); }
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); }