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 }