20 #if (defined(__aarch32__) || defined(__aarch64__)) && defined(CRYPTOPP_SLOW_ARMV8_SHIFT) 21 # undef CRYPTOPP_ARM_NEON_AVAILABLE 24 ANONYMOUS_NAMESPACE_BEGIN
27 using CryptoPP::word32;
28 using CryptoPP::word64;
31 template <
class W,
bool T_64bit>
34 CRYPTOPP_ALIGN_DATA(16)
39 const word32 BLAKE2_IV<word32, false>::iv[8] = {
40 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
41 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
45 const word64 BLAKE2_IV<word64, true>::iv[8] = {
46 W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
47 W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
48 W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f),
49 W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)
52 CRYPTOPP_ALIGN_DATA(16)
53 const byte BLAKE2S_SIGMA[10][16] = {
54 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
55 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
56 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
57 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
58 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
59 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
60 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
61 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
62 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
63 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
66 CRYPTOPP_ALIGN_DATA(16)
67 const byte BLAKE2B_SIGMA[12][16] = {
68 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
69 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
70 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
71 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
72 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
73 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
74 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
75 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
76 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
77 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
78 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
79 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
82 template <
unsigned int R,
unsigned int N>
83 inline void BLAKE2B_G(
const word64 m[16], word64& a, word64& b, word64& c, word64& d)
85 a = a + b + m[BLAKE2B_SIGMA[R][2*N+0]];
86 d = rotrConstant<32>(d ^ a);
88 b = rotrConstant<24>(b ^ c);
89 a = a + b + m[BLAKE2B_SIGMA[R][2*N+1]];
90 d = rotrConstant<16>(d ^ a);
92 b = rotrConstant<63>(b ^ c);
95 template <
unsigned int R>
96 inline void BLAKE2B_ROUND(
const word64 m[16], word64 v[16])
98 BLAKE2B_G<R,0>(m,v[ 0],v[ 4],v[ 8],v[12]);
99 BLAKE2B_G<R,1>(m,v[ 1],v[ 5],v[ 9],v[13]);
100 BLAKE2B_G<R,2>(m,v[ 2],v[ 6],v[10],v[14]);
101 BLAKE2B_G<R,3>(m,v[ 3],v[ 7],v[11],v[15]);
102 BLAKE2B_G<R,4>(m,v[ 0],v[ 5],v[10],v[15]);
103 BLAKE2B_G<R,5>(m,v[ 1],v[ 6],v[11],v[12]);
104 BLAKE2B_G<R,6>(m,v[ 2],v[ 7],v[ 8],v[13]);
105 BLAKE2B_G<R,7>(m,v[ 3],v[ 4],v[ 9],v[14]);
108 template <
unsigned int R,
unsigned int N>
109 inline void BLAKE2S_G(
const word32 m[16], word32& a, word32& b, word32& c, word32& d)
111 a = a + b + m[BLAKE2S_SIGMA[R][2*N+0]];
112 d = rotrConstant<16>(d ^ a);
114 b = rotrConstant<12>(b ^ c);
115 a = a + b + m[BLAKE2S_SIGMA[R][2*N+1]];
116 d = rotrConstant<8>(d ^ a);
118 b = rotrConstant<7>(b ^ c);
121 template <
unsigned int R>
122 inline void BLAKE2S_ROUND(
const word32 m[16], word32 v[])
124 BLAKE2S_G<R,0>(m,v[ 0],v[ 4],v[ 8],v[12]);
125 BLAKE2S_G<R,1>(m,v[ 1],v[ 5],v[ 9],v[13]);
126 BLAKE2S_G<R,2>(m,v[ 2],v[ 6],v[10],v[14]);
127 BLAKE2S_G<R,3>(m,v[ 3],v[ 7],v[11],v[15]);
128 BLAKE2S_G<R,4>(m,v[ 0],v[ 5],v[10],v[15]);
129 BLAKE2S_G<R,5>(m,v[ 1],v[ 6],v[11],v[12]);
130 BLAKE2S_G<R,6>(m,v[ 2],v[ 7],v[ 8],v[13]);
131 BLAKE2S_G<R,7>(m,v[ 3],v[ 4],v[ 9],v[14]);
134 ANONYMOUS_NAMESPACE_END
141 #if CRYPTOPP_SSE41_AVAILABLE 146 #if CRYPTOPP_ARM_NEON_AVAILABLE 152 const byte* saltStr,
size_t saltLen,
153 const byte* personalizationStr,
size_t personalizationLen)
156 digestLength = (byte)digestLen;
157 keyLength = (byte)keyLen;
159 nodeDepth = innerLength = 0;
161 memset(leafLength, 0x00,
COUNTOF(leafLength));
162 memset(nodeOffset, 0x00,
COUNTOF(nodeOffset));
164 if (saltStr && saltLen)
167 const size_t rem =
COUNTOF(salt) - saltLen;
168 const size_t off =
COUNTOF(salt) - rem;
170 memset(salt+off, 0x00, rem);
174 memset(salt, 0x00,
COUNTOF(salt));
177 if (personalizationStr && personalizationLen)
179 memcpy_s(personalization,
COUNTOF(personalization), personalizationStr, personalizationLen);
180 const size_t rem =
COUNTOF(personalization) - personalizationLen;
181 const size_t off =
COUNTOF(personalization) - rem;
183 memset(personalization+off, 0x00, rem);
187 memset(personalization, 0x00,
COUNTOF(personalization));
192 const byte* saltStr,
size_t saltLen,
193 const byte* personalizationStr,
size_t personalizationLen)
196 digestLength = (byte)digestLen;
197 keyLength = (byte)keyLen;
199 nodeDepth = innerLength = 0;
201 memset(rfu, 0x00,
COUNTOF(rfu));
202 memset(leafLength, 0x00,
COUNTOF(leafLength));
203 memset(nodeOffset, 0x00,
COUNTOF(nodeOffset));
205 if (saltStr && saltLen)
208 const size_t rem =
COUNTOF(salt) - saltLen;
209 const size_t off =
COUNTOF(salt) - rem;
211 memset(salt+off, 0x00, rem);
215 memset(salt, 0x00,
COUNTOF(salt));
218 if (personalizationStr && personalizationLen)
220 memcpy_s(personalization,
COUNTOF(personalization), personalizationStr, personalizationLen);
221 const size_t rem =
COUNTOF(personalization) - personalizationLen;
222 const size_t off =
COUNTOF(personalization) - rem;
224 memset(personalization+off, 0x00, rem);
228 memset(personalization, 0x00,
COUNTOF(personalization));
232 template <
class W,
bool T_64bit>
238 memcpy_s(temp, BLOCKSIZE, key, length);
240 const size_t rem = BLOCKSIZE - length;
242 memset(temp+length, 0x00, rem);
252 ParameterBlock& block = *m_block.data();
253 memset(m_block.data(), 0x00,
sizeof(ParameterBlock));
255 block.keyLength = (byte)length;
256 block.digestLength = (byte)params.GetIntValueWithDefault(
Name::DigestSize(), DIGESTSIZE);
257 block.fanout = block.depth = 1;
264 const size_t off =
COUNTOF(block.salt) - rem;
266 memset(block.salt+off, 0x00, rem);
270 memset(block.salt, 0x00,
COUNTOF(block.salt));
276 const size_t rem =
COUNTOF(block.personalization) - t.
size();
277 const size_t off =
COUNTOF(block.personalization) - rem;
279 memset(block.personalization+off, 0x00, rem);
283 memset(block.personalization, 0x00,
COUNTOF(block.personalization));
287 template <
class W,
bool T_64bit>
294 template <
class W,
bool T_64bit>
303 template <
class W,
bool T_64bit>
305 const byte* personalization,
size_t personalizationLength,
bool treeMode,
unsigned int digestSize)
306 : m_state(1), m_block(1), m_digestSize(digestSize), m_treeMode(treeMode)
318 template <
class W,
bool T_64bit>
321 static const W zero[2] = {0,0};
322 Restart(*m_block.data(), zero);
325 template <
class W,
bool T_64bit>
330 if (&block != m_block.data())
333 m_block.data()->digestLength = (byte)m_digestSize;
334 m_block.data()->keyLength = (byte)m_key.size();
337 State& state = *m_state.data();
338 state.t[0] = state.t[1] = 0, state.f[0] = state.f[1] = 0, state.length = 0;
340 if (counter != NULLPTR)
342 state.t[0] = counter[0];
343 state.t[1] = counter[1];
346 const W* iv = BLAKE2_IV<W, T_64bit>::iv;
348 put(iv[0])(iv[1])(iv[2])(iv[3])(iv[4])(iv[5])(iv[6])(iv[7]);
353 Update(m_key, m_key.size());
356 template <
class W,
bool T_64bit>
359 State& state = *m_state.data();
360 if (state.length + length > BLOCKSIZE)
363 const size_t fill = BLOCKSIZE - state.length;
364 memcpy_s(&state.buffer[state.length], fill, input, fill);
367 Compress(state.buffer);
370 length -= fill, input += fill;
373 while (length > BLOCKSIZE)
377 length -= BLOCKSIZE, input += BLOCKSIZE;
385 memcpy_s(&state.buffer[state.length], length, input, length);
386 state.length +=
static_cast<unsigned int>(length);
390 template <
class W,
bool T_64bit>
393 this->ThrowIfInvalidTruncatedSize(size);
396 State& state = *m_state.data();
397 state.f[0] =
static_cast<W
>(-1);
401 state.f[1] =
static_cast<W
>(-1);
404 IncrementCounter(state.length);
406 memset(state.buffer + state.length, 0x00, BLOCKSIZE - state.length);
407 Compress(state.buffer);
410 memcpy_s(hash, size, &state.h[0], size);
415 template <
class W,
bool T_64bit>
418 State& state = *m_state.data();
419 state.t[0] +=
static_cast<W
>(count);
420 state.t[1] += !!(state.t[0] < count);
426 #if CRYPTOPP_SSE41_AVAILABLE 429 return BLAKE2_Compress64_SSE4(input, *m_state.
data());
432 #if CRYPTOPP_ARM_NEON_AVAILABLE 435 return BLAKE2_Compress64_NEON(input, *m_state.
data());
438 return BLAKE2_Compress64_CXX(input, *m_state.
data());
444 #if CRYPTOPP_SSE41_AVAILABLE 447 return BLAKE2_Compress32_SSE4(input, *m_state.
data());
450 #if CRYPTOPP_ARM_NEON_AVAILABLE 453 return BLAKE2_Compress32_NEON(input, *m_state.
data());
456 return BLAKE2_Compress32_CXX(input, *m_state.
data());
464 get1(m[0])(m[1])(m[2])(m[3])(m[4])(m[5])(m[6])(m[7])(m[8])(m[9])(m[10])(m[11])(m[12])(m[13])(m[14])(m[15]);
467 get2(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7]);
469 const word64* iv = BLAKE2_IV<word64, true>::iv;
474 v[12] = state.t[0] ^ iv[4];
475 v[13] = state.t[1] ^ iv[5];
476 v[14] = state.f[0] ^ iv[6];
477 v[15] = state.f[1] ^ iv[7];
479 BLAKE2B_ROUND<0>(m, v);
480 BLAKE2B_ROUND<1>(m, v);
481 BLAKE2B_ROUND<2>(m, v);
482 BLAKE2B_ROUND<3>(m, v);
483 BLAKE2B_ROUND<4>(m, v);
484 BLAKE2B_ROUND<5>(m, v);
485 BLAKE2B_ROUND<6>(m, v);
486 BLAKE2B_ROUND<7>(m, v);
487 BLAKE2B_ROUND<8>(m, v);
488 BLAKE2B_ROUND<9>(m, v);
489 BLAKE2B_ROUND<10>(m, v);
490 BLAKE2B_ROUND<11>(m, v);
492 for(
unsigned int i = 0; i < 8; ++i)
501 get1(m[0])(m[1])(m[2])(m[3])(m[4])(m[5])(m[6])(m[7])(m[8])(m[9])(m[10])(m[11])(m[12])(m[13])(m[14])(m[15]);
504 get2(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7]);
506 const word32* iv = BLAKE2_IV<word32, false>::iv;
511 v[12] = state.t[0] ^ iv[4];
512 v[13] = state.t[1] ^ iv[5];
513 v[14] = state.f[0] ^ iv[6];
514 v[15] = state.f[1] ^ iv[7];
516 BLAKE2S_ROUND<0>(m, v);
517 BLAKE2S_ROUND<1>(m, v);
518 BLAKE2S_ROUND<2>(m, v);
519 BLAKE2S_ROUND<3>(m, v);
520 BLAKE2S_ROUND<4>(m, v);
521 BLAKE2S_ROUND<5>(m, v);
522 BLAKE2S_ROUND<6>(m, v);
523 BLAKE2S_ROUND<7>(m, v);
524 BLAKE2S_ROUND<8>(m, v);
525 BLAKE2S_ROUND<9>(m, v);
527 for(
unsigned int i = 0; i < 8; ++i)
Used to pass byte array input as part of a NameValuePairs object.
void Restart()
Restart the hash.
Standard names for retrieving values by name when working with NameValuePairs.
const char * DigestSize()
int, in bytes
const char * TreeMode()
byte
Classes for working with NameValuePairs.
BLAKE2 hash implementation.
size_t size() const
Length of the memory block.
void TruncatedFinal(byte *hash, size_t size)
Computes the hash of the current message.
Abstract base classes that provide a uniform interface to this library.
void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
Bounds checking replacement for memcpy()
Library configuration file.
const byte * begin() const
Pointer to the first byte in the memory block.
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
A::pointer data()
Provides a pointer to the first element in the memory block.
const char * Salt()
ConstByteArrayParameter.
#define COUNTOF(arr)
Counts elements in an array.
SecBlock using AllocatorWithCleanup<byte, true> typedef.
Classes for BLAKE2b and BLAKE2s message digests and keyed message digests.
const char * Personalization()
ConstByteArrayParameter.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Functions for CPU features and intrinsics.
BLAKE2 state information.
const NameValuePairs g_nullNameValuePairs
An empty set of name-value pairs.
T rotrConstant(T x)
Performs a right rotate.
Access a block of memory.
bool HasSSE41()
Determines SSE4.1 availability.
Access a block of memory.
Crypto++ library namespace.
bool HasNEON()
Determine if an ARM processor has Advanced SIMD available.
void Update(const byte *input, size_t length)
Updates a hash with additional input.