gestumblinde

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

ht.c (1941B)


      1 #include "ht.h"
      2 
      3 static inline void set_tree_address(uint32_t adrs[ADRS_LEN], idx_tree_t idx) {
      4   idx_tree_t tmp;
      5   tmp.valhb = htobe32(idx.valhb);
      6   tmp.vallb = htobe64(idx.vallb);
      7 
      8   memcpy(&adrs[ADRS_TREE_ADDRESS_IDX], &tmp, sizeof(tmp));
      9 }
     10 
     11 /*
     12  * Generate a hypertree signature.
     13  */
     14 int ht_sign(uint8_t *out, const uint8_t msg[ENN], const uint8_t sk_seed[ENN],
     15             const uint8_t pk_seed[ENN], idx_tree_t idx_tree,
     16             uint64_t idx_leaf) {
     17   uint32_t adrs[ADRS_LEN] = {0};
     18   set_tree_address(adrs, idx_tree);
     19 
     20   uint8_t *csig = out;
     21   xmss_sign(csig, msg, sk_seed, idx_leaf, pk_seed, adrs);
     22 
     23   uint8_t root[ENN];
     24   xmss_pk_from_sig(root, idx_leaf, csig, msg, pk_seed, adrs);
     25 
     26   csig += (WOTSP_LEN + HP) * ENN;
     27   size_t j;
     28   for (j = 1; j < D; j++) {
     29     idx_leaf = idx_tree_mod_2hp(idx_tree);
     30     idx_tree_shift(&idx_tree, HP);
     31 
     32     adrs[ADRS_LAYER_ADDRESS_IDX] = htobe32(j);
     33     set_tree_address(adrs, idx_tree);
     34 
     35     xmss_sign(csig, root, sk_seed, idx_leaf, pk_seed, adrs);
     36 
     37     if (j < D - 1) {
     38       xmss_pk_from_sig(root, idx_leaf, csig, root, pk_seed, adrs);
     39     }
     40 
     41     csig += (WOTSP_LEN + HP) * ENN;
     42   }
     43 
     44   return 0;
     45 }
     46 
     47 int ht_verify(const uint8_t msg[ENN], const uint8_t *sig_ht,
     48               const uint8_t pk_seed[ENN], idx_tree_t idx_tree,
     49               uint64_t idx_leaf, const uint8_t pk_root[ENN]) {
     50   uint32_t adrs[ADRS_LEN] = {0};
     51   set_tree_address(adrs, idx_tree);
     52 
     53   const uint8_t *csig = sig_ht;
     54   uint8_t node[ENN];
     55   xmss_pk_from_sig(node, idx_leaf, csig, msg, pk_seed, adrs);
     56   csig += (WOTSP_LEN + HP) * ENN;
     57 
     58   size_t j;
     59   for (j = 1; j < D; j++) {
     60     idx_leaf = idx_tree_mod_2hp(idx_tree);
     61     idx_tree_shift(&idx_tree, HP);
     62 
     63     adrs[ADRS_LAYER_ADDRESS_IDX] = htobe32(j);
     64     set_tree_address(adrs, idx_tree);
     65 
     66     xmss_pk_from_sig(node, idx_leaf, csig, node, pk_seed, adrs);
     67     csig += (WOTSP_LEN + HP) * ENN;
     68   }
     69 
     70   if (memcmp(node, pk_root, ENN) == 0)
     71     return 1;
     72   else
     73     return 0;
     74 }