gestumblinde

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

fors.c (3441B)


      1 #include "fors.h"
      2 #include "address.h"
      3 #include "utils.h"
      4 
      5 void fors_skgen(uint8_t *out, const uint8_t sk_seed[ENN],
      6                 const uint8_t pk_seed[ENN], uint32_t adrs[ADRS_LEN],
      7                 const uint64_t idx) {
      8   uint32_t skadrs[ADRS_LEN];
      9   memcpy(skadrs, adrs, ADRS_TYPE_IDX * sizeof(*skadrs));
     10   skadrs[ADRS_TYPE_IDX] = FORS_PRF;
     11   skadrs[ADRS_KEYPAIR_IDX] = adrs[ADRS_KEYPAIR_IDX];
     12   skadrs[ADRS_TREE_HEIGHT_IDX] = 0;
     13   skadrs[ADRS_TREE_INDEX_IDX] = htobe32(idx);
     14 
     15   hash_prf(out, pk_seed, sk_seed, skadrs);
     16 }
     17 
     18 void fors_node(uint8_t *out, const uint8_t sk_seed[ENN], const uint64_t i,
     19                const uint64_t z, const uint8_t pk_seed[ENN],
     20                uint32_t adrs[ADRS_LEN]) {
     21   assert(z <= A);
     22   assert(i < K * (1ull << (A - z)));
     23 
     24   uint8_t sk[ENN];
     25   if (z == 0) {
     26     fors_skgen(sk, sk_seed, pk_seed, adrs, i);
     27     adrs[ADRS_TREE_HEIGHT_IDX] = 0;
     28     adrs[ADRS_TREE_INDEX_IDX] = htobe32(i);
     29     hash_f(out, pk_seed, adrs, sk);
     30   } else {
     31     uint8_t buffer[2 * ENN];
     32     uint8_t *lnode = buffer;
     33     uint8_t *rnode = buffer + ENN;
     34 
     35     fors_node(lnode, sk_seed, 2 * i, z - 1, pk_seed, adrs);
     36     fors_node(rnode, sk_seed, 2 * i + 1, z - 1, pk_seed, adrs);
     37 
     38     adrs[ADRS_TREE_HEIGHT_IDX] = htobe32(z);
     39     adrs[ADRS_TREE_INDEX_IDX] = htobe32(i);
     40 
     41     hash_h(out, pk_seed, adrs, buffer);
     42   }
     43 }
     44 
     45 void fors_sign(uint8_t *out, const uint8_t md[FORS_MD_LEN],
     46                const uint8_t sk_seed[ENN], const uint8_t pk_seed[ENN],
     47                uint32_t adrs[ADRS_LEN]) {
     48   uint64_t indices[K];
     49   base_2b(indices, md, FORS_MD_LEN, A, K);
     50 
     51   uint8_t *cout = out;
     52 
     53   size_t i, j;
     54   for (i = 0; i < K; i++) {
     55     fors_skgen(cout, sk_seed, pk_seed, adrs, i * (1ull << A) + indices[i]);
     56     cout += ENN;
     57 
     58     for (j = 0; j < A; j++) {
     59       uint64_t s = (indices[i] >> j) ^ 0x01;
     60       fors_node(cout, sk_seed, i * (1ull << (A - j)) + s, j, pk_seed, adrs);
     61       cout += ENN;
     62     }
     63   }
     64 }
     65 
     66 void fors_pk_from_sig(uint8_t *out, const uint8_t sig_fors[FORS_SIG_LEN],
     67                       const uint8_t md[FORS_MD_LEN], const uint8_t pk_seed[ENN],
     68                       uint32_t adrs[ADRS_LEN]) {
     69   uint64_t indices[K];
     70   base_2b(indices, md, FORS_MD_LEN, A, K);
     71 
     72   const uint8_t *csig = sig_fors;
     73   uint8_t buffer[3 * ENN];
     74   uint8_t root[K * ENN];
     75   uint8_t *croot = root;
     76 
     77   size_t i, j;
     78   for (i = 0; i < K; i++) {
     79     adrs[ADRS_TREE_HEIGHT_IDX] = 0;
     80     adrs[ADRS_TREE_INDEX_IDX] = htobe32(i * (1ull << A) + indices[i]);
     81     hash_f(buffer + ENN, pk_seed, adrs, csig);
     82     csig += ENN;
     83 
     84     for (j = 0; j < A; j++) {
     85       adrs[ADRS_TREE_HEIGHT_IDX] = htobe32(j + 1);
     86       if (((indices[i] >> j) & 0x01) == 0) {
     87         adrs[ADRS_TREE_INDEX_IDX] =
     88             htobe32(betoh32(adrs[ADRS_TREE_INDEX_IDX]) >> 1);
     89         memcpy(buffer + 2 * ENN, csig, ENN);
     90         hash_h(buffer + ENN, pk_seed, adrs, buffer + ENN);
     91       } else {
     92         adrs[ADRS_TREE_INDEX_IDX] =
     93             htobe32((betoh32(adrs[ADRS_TREE_INDEX_IDX]) - 1) >> 1);
     94         memcpy(buffer, csig, ENN);
     95         hash_h(buffer + ENN, pk_seed, adrs, buffer);
     96       }
     97       csig += ENN;
     98     }
     99     memcpy(croot, buffer + ENN, ENN);
    100     croot += ENN;
    101   }
    102 
    103   uint32_t forspkadrs[ADRS_LEN];
    104   memcpy(forspkadrs, adrs, ADRS_TYPE_IDX * sizeof(*adrs));
    105   forspkadrs[ADRS_TYPE_IDX] = FORS_ROOTS;
    106   forspkadrs[ADRS_KEYPAIR_IDX] = adrs[ADRS_KEYPAIR_IDX];
    107   bzero(&forspkadrs[ADRS_KEYPAIR_IDX + 1], 2 * sizeof(*adrs));
    108 
    109   hash_t(out, K, pk_seed, forspkadrs, root);
    110 }