gestumblinde

Gestumblinde - reference implementation of SLH-DSA
git clone git://www.tkruger.se/gestumblinde.git
Log | Files | Refs | README

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