gestumblinde

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

hash.c (10338B)


      1 #include "hash.h"
      2 
      3 #if defined(SLH_DSA_SHAKE_128S) || defined(SLH_DSA_SHAKE_128F) ||              \
      4     defined(SLH_DSA_SHAKE_192S) || defined(SLH_DSA_SHAKE_192F) ||              \
      5     defined(SLH_DSA_SHAKE_256S) || defined(SLH_DSA_SHAKE_256F)
      6 
      7 void hash_t(uint8_t *out, const size_t len, const uint8_t pk_seed[ENN],
      8             const uint32_t adrs[ADRS_LEN], const uint8_t *m_ell) {
      9   sha3_ctx_t h;
     10   shake256_init(&h);
     11   shake_update(&h, pk_seed, ENN);
     12   shake_update(&h, adrs, ADRS_LEN * sizeof(*adrs));
     13   shake_update(&h, m_ell, ENN * len);
     14   shake_xof(&h);
     15   shake_out(&h, out, ENN);
     16 }
     17 
     18 void hash_h_msg(uint8_t *out, const size_t out_len, const uint8_t *r,
     19                 const uint8_t *pk_seed, const uint8_t *pk_root,
     20                 const uint8_t *m, const size_t mlen) {
     21   sha3_ctx_t h;
     22   shake256_init(&h);
     23   shake_update(&h, r, ENN);
     24   shake_update(&h, pk_seed, ENN);
     25   shake_update(&h, pk_root, ENN);
     26   shake_update(&h, m, mlen);
     27   shake_xof(&h);
     28   shake_out(&h, out, out_len);
     29 }
     30 
     31 void hash_prf_msg(uint8_t *out, const uint8_t *sk_prf, const uint8_t *opt_rand,
     32                   const uint8_t *m, const size_t mlen) {
     33   sha3_ctx_t h;
     34   shake256_init(&h);
     35   shake_update(&h, sk_prf, ENN);
     36   shake_update(&h, opt_rand, ENN);
     37   shake_update(&h, m, mlen);
     38   shake_xof(&h);
     39   shake_out(&h, out, ENN);
     40 }
     41 
     42 #elif defined(SLH_DSA_SHA2_128S) || defined(SLH_DSA_SHA2_128F)
     43 
     44 static inline int adrs_update(SHA256_CTX *c, const uint32_t adrs[ADRS_LEN]) {
     45   const uint8_t *adrsb = (const uint8_t *)adrs;
     46   int res = 1;
     47   res &= SHA256_Update(c, &adrsb[3], 1);
     48   res &= SHA256_Update(c, &adrsb[8], 8);
     49   res &= SHA256_Update(c, &adrsb[19], 1);
     50   res &= SHA256_Update(c, &adrsb[20], 12);
     51   return res;
     52 }
     53 
     54 static inline void mgf1_sha256(uint8_t *out, const uint8_t *seed,
     55                                const size_t seedlen, const size_t mlen) {
     56   uint32_t c;
     57 
     58   uint8_t buffer[seedlen + 4];
     59   memcpy(buffer, seed, seedlen);
     60 
     61   size_t steps = (mlen + SHA256_DIGEST_LENGTH - 1) / SHA256_DIGEST_LENGTH;
     62   uint8_t tmp[mlen + SHA256_DIGEST_LENGTH]; // always enough space
     63   uint8_t *ctmp = tmp;
     64 
     65   for (c = 0; c < steps; c++) {
     66     uint32_t cbe = htobe32(c);
     67     memcpy(buffer + seedlen, &cbe, sizeof(cbe));
     68     SHA256(buffer, seedlen + 4, ctmp);
     69     ctmp += SHA256_DIGEST_LENGTH;
     70   }
     71 
     72   memcpy(out, tmp, mlen);
     73 }
     74 
     75 void hash_t(uint8_t *out, const size_t len, const uint8_t pk_seed[ENN],
     76             const uint32_t adrs[ADRS_LEN], const uint8_t *m_ell) {
     77   SHA256_CTX c;
     78 
     79   if (!SHA256_Init(&c)) {
     80     fprintf(stderr, "Failed to init SHA256.");
     81     exit(1);
     82   }
     83 
     84   if (!SHA256_Update(&c, pk_seed, ENN)) {
     85     fprintf(stderr, "Failed to update SHA256 with R.");
     86     exit(1);
     87   }
     88 
     89   uint8_t zero_bytes[64] = {0};
     90 
     91   if (!SHA256_Update(&c, zero_bytes, 64 - ENN)) {
     92     fprintf(stderr, "Failed to update SHA256 with zero_bytes.");
     93     exit(1);
     94   }
     95 
     96   if (!adrs_update(&c, adrs)) {
     97     fprintf(stderr, "Failed to update SHA256 with address.");
     98     exit(1);
     99   }
    100 
    101   if (!SHA256_Update(&c, m_ell, ENN * len)) {
    102     fprintf(stderr, "Could not update SHA256 with M_ell.");
    103     exit(1);
    104   }
    105 
    106   uint8_t tmp[SHA256_DIGEST_LENGTH];
    107   if (!SHA256_Final(tmp, &c)) {
    108     fprintf(stderr, "Could not compute SHA256 digest.");
    109     exit(1);
    110   }
    111 
    112   memcpy(out, tmp, ENN);
    113 }
    114 
    115 void hash_h_msg(uint8_t *out, const size_t out_len, const uint8_t *r,
    116                 const uint8_t *pk_seed, const uint8_t *pk_root,
    117                 const uint8_t *m, const size_t mlen) {
    118   SHA256_CTX c;
    119 
    120   if (!SHA256_Init(&c)) {
    121     fprintf(stderr, "Failed to init SHA256.");
    122     exit(1);
    123   }
    124 
    125   if (!SHA256_Update(&c, r, ENN)) {
    126     fprintf(stderr, "Failed to update SHA256 with R.");
    127     exit(1);
    128   }
    129 
    130   if (!SHA256_Update(&c, pk_seed, ENN)) {
    131     fprintf(stderr, "Failed to update SHA256 with pk_seed.");
    132     exit(1);
    133   }
    134 
    135   if (!SHA256_Update(&c, pk_root, ENN)) {
    136     fprintf(stderr, "Failed to update SHA256 with pk_root.");
    137     exit(1);
    138   }
    139 
    140   if (!SHA256_Update(&c, m, mlen)) {
    141     fprintf(stderr, "Failed to update SHA256 with m.");
    142     exit(1);
    143   }
    144 
    145   uint8_t hash_buffer[2 * ENN + SHA256_DIGEST_LENGTH];
    146   if (!SHA256_Final(hash_buffer + 2 * ENN, &c)) {
    147     fprintf(stderr, "Failed to compute digest.");
    148     exit(1);
    149   }
    150 
    151   memcpy(hash_buffer, r, ENN);
    152   memcpy(hash_buffer + ENN, pk_seed, ENN);
    153 
    154   mgf1_sha256(out, hash_buffer, 2 * ENN + SHA256_DIGEST_LENGTH, out_len);
    155 }
    156 
    157 void hash_prf_msg(uint8_t *out, const uint8_t *sk_prf, const uint8_t *opt_rand,
    158                   const uint8_t *m, const size_t mlen) {
    159   HMAC_CTX *hmac = HMAC_CTX_new();
    160 
    161   if (!HMAC_Init(hmac, sk_prf, ENN, EVP_sha256())) {
    162     fprintf(stderr, "Failed to init HMAC-SHA256.");
    163     exit(1);
    164   }
    165 
    166   if (!HMAC_Update(hmac, opt_rand, ENN)) {
    167     fprintf(stderr, "Failed to update HMAC-SHA256 with opt_rand.");
    168     exit(1);
    169   }
    170 
    171   if (!HMAC_Update(hmac, m, mlen)) {
    172     fprintf(stderr, "Could not update HMAC-SHA256 with message.");
    173     exit(1);
    174   }
    175 
    176   uint8_t tmp[SHA256_DIGEST_LENGTH];
    177   if (!HMAC_Final(hmac, tmp, NULL)) {
    178     fprintf(stderr, "Could not compute HMAC-SHA256 digest.");
    179     exit(1);
    180   }
    181 
    182   HMAC_CTX_free(hmac);
    183 
    184   memcpy(out, tmp, ENN);
    185 }
    186 
    187 #elif defined(SLH_DSA_SHA2_192S) || defined(SLH_DSA_SHA2_192F) ||              \
    188     defined(SLH_DSA_SHA2_256S) || defined(SLH_DSA_SHA2_256F)
    189 
    190 static inline int adrs_update_sha256(SHA256_CTX *c,
    191                                      const uint32_t adrs[ADRS_LEN]) {
    192   const uint8_t *adrsb = (const uint8_t *)adrs;
    193   int res = 1;
    194   res &= SHA256_Update(c, &adrsb[3], 1);
    195   res &= SHA256_Update(c, &adrsb[8], 8);
    196   res &= SHA256_Update(c, &adrsb[19], 1);
    197   res &= SHA256_Update(c, &adrsb[20], 12);
    198   return res;
    199 }
    200 
    201 static inline int adrs_update_sha512(SHA512_CTX *c,
    202                                      const uint32_t adrs[ADRS_LEN]) {
    203   const uint8_t *adrsb = (const uint8_t *)adrs;
    204   int res = 1;
    205   res &= SHA512_Update(c, &adrsb[3], 1);
    206   res &= SHA512_Update(c, &adrsb[8], 8);
    207   res &= SHA512_Update(c, &adrsb[19], 1);
    208   res &= SHA512_Update(c, &adrsb[20], 12);
    209   return res;
    210 }
    211 
    212 static inline void mgf1_sha512(uint8_t *out, const uint8_t *seed,
    213                                const size_t seedlen, const size_t mlen) {
    214   uint32_t c;
    215 
    216   uint8_t buffer[seedlen + 4];
    217   memcpy(buffer, seed, seedlen);
    218 
    219   size_t steps = (mlen + SHA512_DIGEST_LENGTH - 1) / SHA512_DIGEST_LENGTH;
    220   uint8_t tmp[mlen + SHA512_DIGEST_LENGTH]; // always enough space
    221   uint8_t *ctmp = tmp;
    222 
    223   for (c = 0; c < steps; c++) {
    224     uint32_t cbe = htobe32(c);
    225     memcpy(buffer + seedlen, &cbe, sizeof(cbe));
    226     SHA512(buffer, seedlen + 4, ctmp);
    227     ctmp += SHA512_DIGEST_LENGTH;
    228   }
    229 
    230   memcpy(out, tmp, mlen);
    231 }
    232 
    233 void hash_t(uint8_t *out, const size_t len, const uint8_t pk_seed[ENN],
    234             const uint32_t adrs[ADRS_LEN], const uint8_t *m_ell) {
    235   SHA512_CTX c;
    236 
    237   if (!SHA512_Init(&c)) {
    238     fprintf(stderr, "Failed to init SHA512.");
    239     exit(1);
    240   }
    241 
    242   if (!SHA512_Update(&c, pk_seed, ENN)) {
    243     fprintf(stderr, "Failed to update SHA512 with R.");
    244     exit(1);
    245   }
    246 
    247   uint8_t zero_bytes[128] = {0};
    248 
    249   if (!SHA512_Update(&c, zero_bytes, 128 - ENN)) {
    250     fprintf(stderr, "Failed to update SHA512 with zero_bytes.");
    251     exit(1);
    252   }
    253 
    254   if (!adrs_update_sha512(&c, adrs)) {
    255     fprintf(stderr, "Failed to update SHA512 with address.");
    256     exit(1);
    257   }
    258 
    259   if (!SHA512_Update(&c, m_ell, ENN * len)) {
    260     fprintf(stderr, "Could not update SHA512 with M_ell.");
    261     exit(1);
    262   }
    263 
    264   uint8_t tmp[SHA512_DIGEST_LENGTH];
    265   if (!SHA512_Final(tmp, &c)) {
    266     fprintf(stderr, "Could not compute SHA512 digest.");
    267     exit(1);
    268   }
    269 
    270   memcpy(out, tmp, ENN);
    271 }
    272 
    273 void hash_h_msg(uint8_t *out, const size_t out_len, const uint8_t *r,
    274                 const uint8_t *pk_seed, const uint8_t *pk_root,
    275                 const uint8_t *m, const size_t mlen) {
    276   SHA512_CTX c;
    277 
    278   if (!SHA512_Init(&c)) {
    279     fprintf(stderr, "Failed to init SHA512.");
    280     exit(1);
    281   }
    282 
    283   if (!SHA512_Update(&c, r, ENN)) {
    284     fprintf(stderr, "Failed to update SHA512 with R.");
    285     exit(1);
    286   }
    287 
    288   if (!SHA512_Update(&c, pk_seed, ENN)) {
    289     fprintf(stderr, "Failed to update SHA512 with pk_seed.");
    290     exit(1);
    291   }
    292 
    293   if (!SHA512_Update(&c, pk_root, ENN)) {
    294     fprintf(stderr, "Failed to update SHA512 with pk_root.");
    295     exit(1);
    296   }
    297 
    298   if (!SHA512_Update(&c, m, mlen)) {
    299     fprintf(stderr, "Failed to update SHA512 with m.");
    300     exit(1);
    301   }
    302 
    303   uint8_t hash_buffer[2 * ENN + SHA512_DIGEST_LENGTH];
    304   if (!SHA512_Final(hash_buffer + 2 * ENN, &c)) {
    305     fprintf(stderr, "Failed to compute digest.");
    306     exit(1);
    307   }
    308 
    309   memcpy(hash_buffer, r, ENN);
    310   memcpy(hash_buffer + ENN, pk_seed, ENN);
    311 
    312   mgf1_sha512(out, hash_buffer, 2 * ENN + SHA512_DIGEST_LENGTH, out_len);
    313 }
    314 
    315 void hash_prf_msg(uint8_t *out, const uint8_t *sk_prf, const uint8_t *opt_rand,
    316                   const uint8_t *m, const size_t mlen) {
    317   HMAC_CTX *hmac = HMAC_CTX_new();
    318 
    319   if (!HMAC_Init(hmac, sk_prf, ENN, EVP_sha512())) {
    320     fprintf(stderr, "Failed to init HMAC-SHA512.");
    321     exit(1);
    322   }
    323 
    324   if (!HMAC_Update(hmac, opt_rand, ENN)) {
    325     fprintf(stderr, "Failed to update HMAC-SHA512 with opt_rand.");
    326     exit(1);
    327   }
    328 
    329   if (!HMAC_Update(hmac, m, mlen)) {
    330     fprintf(stderr, "Could not update HMAC-SHA512 with message.");
    331     exit(1);
    332   }
    333 
    334   uint8_t tmp[SHA512_DIGEST_LENGTH];
    335   if (!HMAC_Final(hmac, tmp, NULL)) {
    336     fprintf(stderr, "Could not compute HMAC-SHA512 digest.");
    337     exit(1);
    338   }
    339 
    340   HMAC_CTX_free(hmac);
    341 
    342   memcpy(out, tmp, ENN);
    343 }
    344 
    345 void hash_f(uint8_t *out, const uint8_t pk_seed[ENN],
    346             const uint32_t adrs[ADRS_LEN], const uint8_t *m1) {
    347   SHA256_CTX c;
    348 
    349   if (!SHA256_Init(&c)) {
    350     fprintf(stderr, "Failed to init SHA256.");
    351     exit(1);
    352   }
    353 
    354   if (!SHA256_Update(&c, pk_seed, ENN)) {
    355     fprintf(stderr, "Failed to update SHA256 with R.");
    356     exit(1);
    357   }
    358 
    359   uint8_t zero_bytes[64] = {0};
    360 
    361   if (!SHA256_Update(&c, zero_bytes, 64 - ENN)) {
    362     fprintf(stderr, "Failed to update SHA256 with zero_bytes.");
    363     exit(1);
    364   }
    365 
    366   if (!adrs_update_sha256(&c, adrs)) {
    367     fprintf(stderr, "Failed to update SHA256 with address.");
    368     exit(1);
    369   }
    370 
    371   if (!SHA256_Update(&c, m1, ENN)) {
    372     fprintf(stderr, "Could not update SHA256 with M1.");
    373     exit(1);
    374   }
    375 
    376   uint8_t tmp[SHA256_DIGEST_LENGTH];
    377   if (!SHA256_Final(tmp, &c)) {
    378     fprintf(stderr, "Could not compute SHA256 digest.");
    379     exit(1);
    380   }
    381 
    382   memcpy(out, tmp, ENN);
    383 }
    384 
    385 #else
    386 
    387 #error "Could not recognize parameter set definition."
    388 
    389 #endif