Utils.cpp
1 #include "Utils.h" 2 3 #include <cstring> 4 5 #include <llvm/Support/Debug.h> 6 7 #include "BuildInfo.gen.h" 8 9 namespace dev 10 { 11 namespace evmjit 12 { 13 14 #if !defined(NDEBUG) // Debug 15 16 std::ostream& getLogStream(char const* _channel) 17 { 18 static std::ostream nullStream{nullptr}; 19 #if LLVM_DEBUG 20 return (llvm::DebugFlag && llvm::isCurrentDebugType(_channel)) ? std::cerr : nullStream; 21 #else 22 return (void)_channel, nullStream; 23 #endif 24 } 25 26 #endif 27 28 namespace 29 { 30 31 /** libkeccak-tiny 32 * 33 * A single-file implementation of SHA-3 and SHAKE. 34 * 35 * Implementor: David Leon Gil 36 * License: CC0, attribution kindly requested. Blame taken too, 37 * but not liability. 38 */ 39 40 /******** The Keccak-f[1600] permutation ********/ 41 42 /*** Constants. ***/ 43 static const uint8_t rho[24] = \ 44 { 1, 3, 6, 10, 15, 21, 45 28, 36, 45, 55, 2, 14, 46 27, 41, 56, 8, 25, 43, 47 62, 18, 39, 61, 20, 44}; 48 static const uint8_t pi[24] = \ 49 {10, 7, 11, 17, 18, 3, 50 5, 16, 8, 21, 24, 4, 51 15, 23, 19, 13, 12, 2, 52 20, 14, 22, 9, 6, 1}; 53 static const uint64_t RC[24] = \ 54 {1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, 55 0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, 56 0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL, 57 0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL, 58 0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL, 59 0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL}; 60 61 /*** Helper macros to unroll the permutation. ***/ 62 #define rol(x, s) (((x) << s) | ((x) >> (64 - s))) 63 #define REPEAT6(e) e e e e e e 64 #define REPEAT24(e) REPEAT6(e e e e) 65 #define REPEAT5(e) e e e e e 66 #define FOR5(v, s, e) \ 67 v = 0; \ 68 REPEAT5(e; v = decltype(v)(v + s);) 69 70 /*** Keccak-f[1600] ***/ 71 static inline void keccakf(void* state) { 72 uint64_t* a = (uint64_t*)state; 73 uint64_t b[5] = {0}; 74 uint64_t t = 0; 75 uint8_t x, y; 76 77 for (int i = 0; i < 24; i++) { 78 // Theta 79 FOR5(x, 1, 80 b[x] = 0; 81 FOR5(y, 5, 82 b[x] ^= a[x + y]; )) 83 FOR5(x, 1, 84 FOR5(y, 5, 85 a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); )) 86 // Rho and pi 87 t = a[1]; 88 x = 0; 89 REPEAT24(b[0] = a[pi[x]]; 90 a[pi[x]] = rol(t, rho[x]); 91 t = b[0]; 92 x++; ) 93 // Chi 94 FOR5(y, 95 5, 96 FOR5(x, 1, 97 b[x] = a[y + x];) 98 FOR5(x, 1, 99 a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); )) 100 // Iota 101 a[0] ^= RC[i]; 102 } 103 } 104 105 /******** The FIPS202-defined functions. ********/ 106 107 /*** Some helper macros. ***/ 108 109 #define _(S) do { S } while (0) 110 #define FOR(i, ST, L, S) \ 111 _(for (size_t i = 0; i < L; i += ST) { S; }) 112 #define mkapply_ds(NAME, S) \ 113 static inline void NAME(uint8_t* dst, \ 114 const uint8_t* src, \ 115 size_t len) { \ 116 FOR(i, 1, len, S); \ 117 } 118 #define mkapply_sd(NAME, S) \ 119 static inline void NAME(const uint8_t* src, \ 120 uint8_t* dst, \ 121 size_t len) { \ 122 FOR(i, 1, len, S); \ 123 } 124 125 mkapply_ds(xorin, dst[i] ^= src[i]) // xorin 126 mkapply_sd(setout, dst[i] = src[i]) // setout 127 128 #define P keccakf 129 #define Plen 200 130 131 // Fold P*F over the full blocks of an input. 132 #define foldP(I, L, F) \ 133 while (L >= rate) { \ 134 F(a, I, rate); \ 135 P(a); \ 136 I += rate; \ 137 L -= rate; \ 138 } 139 140 /** The sponge-based hash construction. **/ 141 static inline int hash(uint8_t* out, size_t outlen, 142 const uint8_t* in, size_t inlen, 143 size_t rate, uint8_t delim) { 144 if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) { 145 return -1; 146 } 147 uint8_t a[Plen] = {0}; 148 // Absorb input. 149 foldP(in, inlen, xorin); 150 // Xor in the DS and pad frame. 151 a[inlen] ^= delim; 152 a[rate - 1] ^= 0x80; 153 // Xor in the last block. 154 xorin(a, in, inlen); 155 // Apply P 156 P(a); 157 // Squeeze output. 158 foldP(out, outlen, setout); 159 setout(a, out, outlen); 160 memset(a, 0, 200); 161 return 0; 162 } 163 164 /*** Helper macros to define SHA3 and SHAKE instances. ***/ 165 #define defkeccak(bits) \ 166 static int keccak_##bits(uint8_t* out, size_t outlen, \ 167 const uint8_t* in, size_t inlen) { \ 168 if (outlen > (bits/8)) { \ 169 return -1; \ 170 } \ 171 return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \ 172 } 173 174 defkeccak(256) 175 176 } 177 178 void keccak(uint8_t const* _data, uint64_t _size, uint8_t* o_hash) 179 { 180 keccak_256(o_hash, 32, _data, _size); 181 } 182 183 } 184 }