Number of leaves. Must be larger than 0.
The leaves of the tree. Exactly l.
One bitmask for each layer of the tree.
L-tree hash sanity test.
t { import dcrypt.pqc.sphincs.sphincs256: hash_2n_n; enum l = 3; enum hash_bytes = 32; alias ubyte[hash_bytes] hash256; alias TreeUtil!(hash_2n_n, ubyte[hash_bytes], ubyte[2*hash_bytes]) Tree; hash256[l] leaves; for(uint i = 0; i < l; ++i) { leaves[i][] = cast(ubyte) (i+1); } // Make leaves distinct. ubyte[64][2] masks; masks[0][] = 1; masks[1][] = 2; hash256 root = Tree.hash_tree!l(leaves, masks); leaves[0][] ^= masks[0][0..hash_bytes]; leaves[1][] ^= masks[0][hash_bytes..$]; hash256 root2 = hash_2n_n(leaves[0], leaves[1]); root2[] ^= masks[1][0..hash_bytes]; leaves[2][] ^= masks[1][hash_bytes..$]; root2 = hash_2n_n(root2, leaves[2]); assert(root == root2)
Test hash_ltree against result of reference implementation (l_tree()).
t { import dcrypt.pqc.sphincs.sphincs256: hash_2n_n, hash256; enum l = 67; enum hash_bytes = 32; alias TreeUtil!(hash_2n_n, ubyte[hash_bytes], ubyte[2*hash_bytes]) Tree; hash256[l] leaves; for(uint i = 0; i < leaves.length; ++i) { leaves[i] = cast(ubyte) i; } ubyte[2*hash_bytes][7] masks; for(uint i = 0; i < masks.length; ++i) { masks[i][0..hash_bytes] = cast(ubyte) (1+2*i); masks[i][hash_bytes..$] = cast(ubyte) (2+2*i); } hash256 root = Tree.hash_tree!l(leaves, masks); assert(root == x"59641ed4970735d4e1d84ec00e4780d1ab211ebd9339b9962de2a15ead43e1e4", "hash_ltree() failed.")
Calculate root hash of a L-tree or a binary tree. The number of leaves is not required to be a power of 2.