ht.py (1983B)
1 """ 2 From Section 7. 3 Hypertree section. 4 """ 5 6 from address import Address 7 from slh_dsa import SLHDSA 8 from xmss import xmss_sign, xmss_pk_from_sig 9 from utils import toByte 10 11 def ht_sign(M: bytes, sk_seed: bytes, pk_seed: bytes, idx_tree: int, idx_leaf: int, ctx: SLHDSA) -> bytes: 12 """Generate a hypertree signature""" 13 assert idx_leaf >= 0 14 assert idx_tree >= 0 15 16 adrs = Address(toByte(0,32)) # adrs <- toByte(0, 32) 17 18 adrs.set_tree_address(idx_tree) 19 sig_tmp = xmss_sign(M, sk_seed, idx_leaf, pk_seed, adrs, ctx) 20 sig_ht = bytes(sig_tmp) 21 root = xmss_pk_from_sig(idx_leaf, sig_tmp, M, pk_seed, adrs, ctx) 22 for j in range(1, ctx.d): 23 idx_leaf = idx_tree % (2**ctx.hp) 24 idx_tree = idx_tree >> ctx.hp 25 adrs.set_layer_address(j) 26 adrs.set_tree_address(idx_tree) 27 sig_tmp = xmss_sign(root, sk_seed, idx_leaf, pk_seed, adrs, ctx) 28 sig_ht += sig_tmp 29 if j < ctx.d - 1: 30 root = xmss_pk_from_sig(idx_leaf, sig_tmp, root, pk_seed, adrs, ctx) 31 return sig_ht 32 33 def ht_verify(M: bytes, sig_ht: bytes, pk_seed: bytes, idx_tree: int, idx_leaf: int, pk_root: bytes, ctx: SLHDSA) -> bool: 34 """Verify a hypertree signature""" 35 assert idx_leaf >= 0 36 assert idx_tree >= 0 37 38 adrs = Address(toByte(0,32)) # adrs <- toByte(0, 32) 39 40 adrs.set_tree_address(idx_tree) 41 sig_tmp = sig_ht[:(ctx.hp+ctx.wotsp_len)*ctx.n] # sig_tmp <- sig_ht.getXMSSSignature(0) 42 node = xmss_pk_from_sig(idx_leaf, sig_tmp, M, pk_seed, adrs, ctx) 43 for j in range(1, ctx.d): 44 idx_leaf = idx_tree % (2**ctx.hp) 45 idx_tree = idx_tree >> ctx.hp 46 adrs.set_layer_address(j) 47 adrs.set_tree_address(idx_tree) 48 # sig_tmp <- sig_ht.getXMSSSignature(j) 49 sig_tmp = sig_ht[j*(ctx.hp+ctx.wotsp_len)*ctx.n : (j+1)*(ctx.hp+ctx.wotsp_len)*ctx.n] 50 node = xmss_pk_from_sig(idx_leaf, sig_tmp, node, pk_seed, adrs, ctx) 51 if node == pk_root: 52 return True 53 else: 54 return False