Fabcoin Core  0.16.2
P2P Digital Currency
blake2bx.cpp
Go to the documentation of this file.
1 /*
2  BLAKE2 reference source code package - optimized C implementations
3 
4  Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
5 
6  To the extent possible under law, the author(s) have dedicated all copyright
7  and related and neighboring rights to this software to the public domain
8  worldwide. This software is distributed without any warranty.
9 
10  You should have received a copy of the CC0 Public Domain Dedication along with
11  this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
12 */
13 
14 #include <stdint.h>
15 #include <string.h>
16 #include <stdio.h>
17 
18 
19 #include "blake2.h"
20 #include "blake2-impl.h"
21 
22 #include "blake2-config.h"
23 
24 #ifdef WIN32
25 #include <intrin.h>
26 #endif
27 
28 #include <emmintrin.h>
29 #if defined(HAVE_SSSE3)
30 #include <tmmintrin.h>
31 #endif
32 #if defined(HAVE_SSE41)
33 #include <smmintrin.h>
34 #endif
35 #if defined(HAVE_AVX)
36 #include <immintrin.h>
37 #endif
38 #if defined(HAVE_XOP)
39 #include <x86intrin.h>
40 #endif
41 
42 #include "blake2b-round.h"
43 
44 ALIGN(64) static const uint64_t blake2b_IV[8] = {
45  0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
46  0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
47  0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
48  0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
49 };
50 
51 /* init xors IV with input parameter block */
53 {
54  //blake2b_init0( S );
55  const uint8_t * v = (const uint8_t *)(blake2b_IV);
56  const uint8_t * p = (const uint8_t *)(P);
57  uint8_t * h = (uint8_t *)(S->h);
58  /* IV XOR ParamBlock */
59  memset(S, 0, sizeof(blake2b_state));
60 
61  for (int i = 0; i < BLAKE2B_OUTBYTES; ++i) h[i] = v[i] ^ p[i];
62 
63  return 0;
64 }
65 
66 /* Some sort of default parameter block initialization, for sequential blake2b */
67 int eq_blake2b_init(blake2b_state *S, const uint8_t outlen)
68 {
69  if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) return -1;
70 
71  const blake2b_param P =
72  {
73  outlen,
74  0,
75  1,
76  1,
77  0,
78  0,
79  0,
80  0,
81  { 0 },
82  { 0 },
83  { 0 }
84  };
85  return eq_blake2b_init_param(S, &P);
86 }
87 
88 int eq_blake2b_init_key(blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen)
89 {
90  if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) return -1;
91 
92  if ((!keylen) || keylen > BLAKE2B_KEYBYTES) return -1;
93 
94  const blake2b_param P =
95  {
96  outlen,
97  keylen,
98  1,
99  1,
100  0,
101  0,
102  0,
103  0,
104  { 0 },
105  { 0 },
106  { 0 }
107  };
108 
109  if (eq_blake2b_init_param(S, &P) < 0)
110  return 0;
111 
112  {
113  uint8_t block[BLAKE2B_BLOCKBYTES];
114  memset(block, 0, BLAKE2B_BLOCKBYTES);
115  memcpy(block, key, keylen);
117  secure_zero_memory(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */
118  }
119  return 0;
120 }
121 
122 static inline int blake2b_compress(blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES])
123 {
124  __m128i row1l, row1h;
125  __m128i row2l, row2h;
126  __m128i row3l, row3h;
127  __m128i row4l, row4h;
128  __m128i b0, b1;
129  __m128i t0, t1;
130 #if defined(HAVE_SSSE3) && !defined(HAVE_XOP)
131  const __m128i r16 = _mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9);
132  const __m128i r24 = _mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10);
133 #endif
134 #if defined(HAVE_SSE41)
135  const __m128i m0 = LOADU(block + 00);
136  const __m128i m1 = LOADU(block + 16);
137  const __m128i m2 = LOADU(block + 32);
138  const __m128i m3 = LOADU(block + 48);
139  const __m128i m4 = LOADU(block + 64);
140  const __m128i m5 = LOADU(block + 80);
141  const __m128i m6 = LOADU(block + 96);
142  const __m128i m7 = LOADU(block + 112);
143 #else
144  const uint64_t m0 = ( ( uint64_t * )block )[ 0];
145  const uint64_t m1 = ( ( uint64_t * )block )[ 1];
146  const uint64_t m2 = ( ( uint64_t * )block )[ 2];
147  const uint64_t m3 = ( ( uint64_t * )block )[ 3];
148  const uint64_t m4 = ( ( uint64_t * )block )[ 4];
149  const uint64_t m5 = ( ( uint64_t * )block )[ 5];
150  const uint64_t m6 = ( ( uint64_t * )block )[ 6];
151  const uint64_t m7 = ( ( uint64_t * )block )[ 7];
152  const uint64_t m8 = ( ( uint64_t * )block )[ 8];
153  const uint64_t m9 = ( ( uint64_t * )block )[ 9];
154  const uint64_t m10 = ( ( uint64_t * )block )[10];
155  const uint64_t m11 = ( ( uint64_t * )block )[11];
156  const uint64_t m12 = ( ( uint64_t * )block )[12];
157  const uint64_t m13 = ( ( uint64_t * )block )[13];
158  const uint64_t m14 = ( ( uint64_t * )block )[14];
159  const uint64_t m15 = ( ( uint64_t * )block )[15];
160 #endif
161  row1l = LOADU(&S->h[0]);
162  row1h = LOADU(&S->h[2]);
163  row2l = LOADU(&S->h[4]);
164  row2h = LOADU(&S->h[6]);
165  row3l = LOADU(&blake2b_IV[0]);
166  row3h = LOADU(&blake2b_IV[2]);
167  row4l = _mm_xor_si128(LOADU(&blake2b_IV[4]), _mm_set_epi32(0, 0, 0, S->counter));
168  row4h = _mm_xor_si128(LOADU(&blake2b_IV[6]), _mm_set_epi32(0, 0, 0L - S->lastblock, 0L - S->lastblock));
169  ROUND(0);
170  ROUND(1);
171  ROUND(2);
172  ROUND(3);
173  ROUND(4);
174  ROUND(5);
175  ROUND(6);
176  ROUND(7);
177  ROUND(8);
178  ROUND(9);
179  ROUND(10);
180  ROUND(11);
181  row1l = _mm_xor_si128(row3l, row1l);
182  row1h = _mm_xor_si128(row3h, row1h);
183  STOREU(&S->h[0], _mm_xor_si128(LOADU(&S->h[0]), row1l));
184  STOREU(&S->h[2], _mm_xor_si128(LOADU(&S->h[2]), row1h));
185  row2l = _mm_xor_si128(row4l, row2l);
186  row2h = _mm_xor_si128(row4h, row2h);
187  STOREU(&S->h[4], _mm_xor_si128(LOADU(&S->h[4]), row2l));
188  STOREU(&S->h[6], _mm_xor_si128(LOADU(&S->h[6]), row2h));
189  return 0;
190 }
191 
192 int eq_blake2b_update(blake2b_state *S, const uint8_t *in, uint64_t inlen)
193 {
194  while (inlen > 0)
195  {
196  size_t left = S->buflen;
197  size_t fill = BLAKE2B_BLOCKBYTES - left;
198 
199  if (inlen > fill)
200  {
201  memcpy(S->buf + left, in, fill); // Fill buffer
202  in += fill;
203  inlen -= fill;
204  S->counter += BLAKE2B_BLOCKBYTES;
205  blake2b_compress(S, S->buf); // Compress
206  S->buflen = 0;
207  }
208  else // inlen <= fill
209  {
210  memcpy(S->buf + left, in, inlen);
211  S->buflen += (uint8_t) inlen; // not enough to compress
212  in += inlen;
213  inlen = 0;
214  }
215  }
216 
217  return 0;
218 }
219 
220 int eq_blake2b_final(blake2b_state *S, uint8_t *out, uint8_t outlen)
221 {
222  if (outlen > BLAKE2B_OUTBYTES)
223  return -1;
224 
225  if (S->buflen > BLAKE2B_BLOCKBYTES)
226  {
227  S->counter += BLAKE2B_BLOCKBYTES;
228  blake2b_compress(S, S->buf);
229  S->buflen -= BLAKE2B_BLOCKBYTES;
230  memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen);
231  }
232 
233  S->counter += S->buflen;
234  S->lastblock = 1;
235  memset(S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
236  blake2b_compress(S, S->buf);
237  memcpy(out, &S->h[0], outlen);
238  S->lastblock = 0;
239  return 0;
240 }
241 
242 int eq_blake2b(uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen)
243 {
244  blake2b_state S[1];
245 
246  /* Verify parameters */
247  if (!in || !out) return -1;
248  if (NULL == key) keylen = 0;
249 
250  if (keylen)
251  {
252  if (eq_blake2b_init_key(S, outlen, key, keylen) < 0) return -1;
253  }
254  else
255  {
256  if (eq_blake2b_init(S, outlen) < 0) return -1;
257  }
258 
259  eq_blake2b_update(S, (const uint8_t *)in, inlen);
260  eq_blake2b_final(S, out, outlen);
261  return 0;
262 }
int eq_blake2b_update(blake2b_state *S, const uint8_t *in, uint64_t inlen)
Definition: blake2bx.cpp:192
int eq_blake2b_final(blake2b_state *S, uint8_t *out, uint8_t outlen)
Definition: blake2bx.cpp:220
int eq_blake2b_init_key(blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen)
Definition: blake2bx.cpp:88
#define h(i)
Definition: sha.cpp:736
#define ROUND(lh, ll, rh, rl, kh, kl)
Definition: camellia.cpp:49
#define LOADU(p)
Definition: blake2b-round.h:20
int eq_blake2b(uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen)
Definition: blake2bx.cpp:242
blake2b_state
Definition: blake2.h:62
int eq_blake2b_init_param(blake2b_state *S, const blake2b_param *P)
Definition: blake2bx.cpp:52
#define t1
ALIGN(64) static const uint64_t blake2b_IV[8]
void * memcpy(void *a, const void *b, size_t c)
#define P
#define STOREU(p, r)
Definition: blake2b-round.h:21
#define S(a)
Definition: mars.cpp:50
int eq_blake2b_init(blake2b_state *S, const uint8_t outlen)
Definition: blake2bx.cpp:67