keccak-fast.c

Minimal SIMD keccak implementation
git clone git://git.finwo.net/lib/keccak-fast.c
Log | Files | Refs | README | LICENSE

scalar-impl.h (4499B)


      1 #ifndef FINWO_SCALAR_IMPL_H
      2 #define FINWO_SCALAR_IMPL_H
      3 
      4 #include <stddef.h>
      5 #include <stdint.h>
      6 #include <string.h>
      7 
      8 #define KF_CAT2(a, b) a##b
      9 #define KF_CAT(a, b) KF_CAT2(a, b)
     10 #define KF_FN(name) KF_CAT(KF_PREFIX, name)
     11 
     12 #if !defined(__STDC_LIB_EXT1__)
     13 static inline int memset_s(void *dest, size_t destsz, int ch, size_t count) {
     14   (void)destsz;
     15   memset(dest, ch, count);
     16   return 0;
     17 }
     18 #endif
     19 
     20 static const uint64_t RC[24] = {
     21   1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,
     22   0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,
     23   0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL,
     24   0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,
     25   0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL,
     26   0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL};
     27 
     28 #define rol(x, s) (((x) << s) | ((x) >> (64 - s)))
     29 
     30 #include "scalar-perm.h"
     31 
     32 #define _(S) do { S } while (0)
     33 #define FOR(i, ST, L, S) \
     34   _(for (size_t i = 0; i < L; i += ST) { S; })
     35 #define mkapply_ds(NAME, S) \
     36   static inline void NAME(uint8_t *dst, const uint8_t *src, size_t len) { \
     37     FOR(i, 1, len, S);                                                    \
     38   }
     39 #define mkapply_sd(NAME, S) \
     40   static inline void NAME(const uint8_t *src, uint8_t *dst, size_t len) { \
     41     FOR(i, 1, len, S);                                                    \
     42   }
     43 
     44 mkapply_ds(xorin, dst[i] ^= src[i])
     45 mkapply_sd(setout, dst[i] = src[i])
     46 
     47 #define Plen 200
     48 
     49 #define foldP(I, L, F, PERM) \
     50   while (L >= rate) {      \
     51     F(a, I, rate);         \
     52     PERM(a);               \
     53     I += rate;             \
     54     L -= rate;             \
     55   }
     56 
     57 #define KF_HASH_BODY(PERM)                                                     \
     58   uint8_t a[Plen] = {0};                                                       \
     59   foldP(in, inlen, xorin, PERM);                                               \
     60   a[inlen] ^= delim;                                                           \
     61   a[rate - 1] ^= 0x80;                                                         \
     62   xorin(a, in, inlen);                                                         \
     63   PERM(a);                                                                     \
     64   foldP(out, outlen, setout, PERM);                                            \
     65   setout(a, out, outlen);                                                      \
     66   memset_s(a, 200, 0, 200);                                                    \
     67   return 0
     68 
     69 static inline int kf_hash24(uint8_t *out, size_t outlen, const uint8_t *in,
     70                             size_t inlen, size_t rate, uint8_t delim) {
     71   if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
     72     return -1;
     73   }
     74   KF_HASH_BODY(keccakf);
     75 }
     76 
     77 static inline int kf_hash12(uint8_t *out, size_t outlen, const uint8_t *in,
     78                             size_t inlen, size_t rate, uint8_t delim) {
     79   if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
     80     return -1;
     81   }
     82   KF_HASH_BODY(keccak12);
     83 }
     84 
     85 #define defshake(bits)                                                         \
     86   KF_LINKAGE int KF_FN(shake##bits)(uint8_t *out, size_t outlen,               \
     87                                     const uint8_t *in, size_t inlen) {         \
     88     return kf_hash24(out, outlen, in, inlen, 200 - (bits / 4), 0x1f);          \
     89   }
     90 #define defsha3(bits)                                                          \
     91   KF_LINKAGE int KF_FN(sha3_##bits)(uint8_t *out, size_t outlen,               \
     92                                    const uint8_t *in, size_t inlen) {          \
     93     if (outlen > (bits / 8)) {                                                 \
     94       return -1;                                                               \
     95     }                                                                          \
     96     return kf_hash24(out, outlen, in, inlen, 200 - (bits / 4), 0x06);          \
     97   }
     98 #define defturboshake(bits)                                                    \
     99   KF_LINKAGE int KF_FN(turboshake##bits)(uint8_t *out, size_t outlen,          \
    100                                          const uint8_t *in, size_t inlen) {    \
    101     return kf_hash12(out, outlen, in, inlen, 200 - (bits / 4), 0x1f);          \
    102   }
    103 
    104 defshake(128)
    105 defshake(256)
    106 defsha3(224)
    107 defsha3(256)
    108 defsha3(384)
    109 defsha3(512)
    110 defturboshake(128)
    111 defturboshake(256)
    112 
    113 #undef defshake
    114 #undef defsha3
    115 #undef defturboshake
    116 
    117 #endif /* FINWO_SCALAR_IMPL_H */