Fabcoin Core  0.16.2
P2P Digital Currency
Utils.cpp
Go to the documentation of this file.
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 
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 
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 }
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
#define REPEAT24(e)
Definition: Utils.cpp:64
void keccak(uint8_t const *_data, uint64_t _size, uint8_t *o_hash)
Definition: Utils.cpp:178
#define foldP(I, L, F)
#define defkeccak(bits)
#define a(i)
#define x(i)
#define FOR5(v, s, e)
Definition: Utils.cpp:66
#define b(i, j)
#define Plen
#define rho(a0, a1, a2)
Definition: 3way.cpp:62
#define mkapply_sd(NAME, S)
Definition: Utils.cpp:118
#define P
#define mkapply_ds(NAME, S)
Definition: Utils.cpp:112
#define rol(x, s)
Definition: Utils.cpp:62
std::ostream & getLogStream(char const *_channel)
Definition: Utils.cpp:16