33 #if (defined(__aarch32__) || defined(__aarch64__)) && defined(CRYPTOPP_SLOW_ARMV8_SHIFT) 34 # undef CRYPTOPP_ARM_NEON_AVAILABLE 39 #if defined(__xlC__) && (__xlC__ < 0x0d01) 40 # define CRYPTOPP_DISABLE_ALTIVEC 1 41 # define CRYPTOPP_POWER7_ALTIVEC 1 42 # undef CRYPTOPP_POWER7_AVAILABLE 43 # undef CRYPTOPP_ALTIVEC_AVAILABLE 49 extern const word32 BLAKE2S_IV[8];
50 extern const word64 BLAKE2B_IV[8];
52 CRYPTOPP_ALIGN_DATA(16)
53 const word32 BLAKE2S_IV[8] = {
54 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
55 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
58 CRYPTOPP_ALIGN_DATA(16)
59 const word64 BLAKE2B_IV[8] = {
60 W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
61 W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
62 W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f),
63 W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)
68 ANONYMOUS_NAMESPACE_BEGIN
71 using CryptoPP::word32;
72 using CryptoPP::word64;
75 CRYPTOPP_ALIGN_DATA(16)
76 const byte BLAKE2S_SIGMA[10][16] = {
77 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
78 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
79 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
80 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
81 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
82 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
83 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
84 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
85 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
86 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
89 CRYPTOPP_ALIGN_DATA(16)
90 const byte BLAKE2B_SIGMA[12][16] = {
91 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
92 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
93 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
94 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
95 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
96 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
97 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
98 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
99 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
100 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
101 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
102 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
105 template <
unsigned int R,
unsigned int N>
106 inline void BLAKE2B_G(
const word64 m[16], word64& a, word64& b, word64& c, word64& d)
108 a = a + b + m[BLAKE2B_SIGMA[R][2*N+0]];
109 d = rotrConstant<32>(d ^ a);
111 b = rotrConstant<24>(b ^ c);
112 a = a + b + m[BLAKE2B_SIGMA[R][2*N+1]];
113 d = rotrConstant<16>(d ^ a);
115 b = rotrConstant<63>(b ^ c);
118 template <
unsigned int R>
119 inline void BLAKE2B_ROUND(
const word64 m[16], word64 v[16])
121 BLAKE2B_G<R,0>(m,v[ 0],v[ 4],v[ 8],v[12]);
122 BLAKE2B_G<R,1>(m,v[ 1],v[ 5],v[ 9],v[13]);
123 BLAKE2B_G<R,2>(m,v[ 2],v[ 6],v[10],v[14]);
124 BLAKE2B_G<R,3>(m,v[ 3],v[ 7],v[11],v[15]);
125 BLAKE2B_G<R,4>(m,v[ 0],v[ 5],v[10],v[15]);
126 BLAKE2B_G<R,5>(m,v[ 1],v[ 6],v[11],v[12]);
127 BLAKE2B_G<R,6>(m,v[ 2],v[ 7],v[ 8],v[13]);
128 BLAKE2B_G<R,7>(m,v[ 3],v[ 4],v[ 9],v[14]);
131 template <
unsigned int R,
unsigned int N>
132 inline void BLAKE2S_G(
const word32 m[16], word32& a, word32& b, word32& c, word32& d)
134 a = a + b + m[BLAKE2S_SIGMA[R][2*N+0]];
135 d = rotrConstant<16>(d ^ a);
137 b = rotrConstant<12>(b ^ c);
138 a = a + b + m[BLAKE2S_SIGMA[R][2*N+1]];
139 d = rotrConstant<8>(d ^ a);
141 b = rotrConstant<7>(b ^ c);
144 template <
unsigned int R>
145 inline void BLAKE2S_ROUND(
const word32 m[16], word32 v[])
147 BLAKE2S_G<R,0>(m,v[ 0],v[ 4],v[ 8],v[12]);
148 BLAKE2S_G<R,1>(m,v[ 1],v[ 5],v[ 9],v[13]);
149 BLAKE2S_G<R,2>(m,v[ 2],v[ 6],v[10],v[14]);
150 BLAKE2S_G<R,3>(m,v[ 3],v[ 7],v[11],v[15]);
151 BLAKE2S_G<R,4>(m,v[ 0],v[ 5],v[10],v[15]);
152 BLAKE2S_G<R,5>(m,v[ 1],v[ 6],v[11],v[12]);
153 BLAKE2S_G<R,6>(m,v[ 2],v[ 7],v[ 8],v[13]);
154 BLAKE2S_G<R,7>(m,v[ 3],v[ 4],v[ 9],v[14]);
157 ANONYMOUS_NAMESPACE_END
161 void BLAKE2_Compress32_CXX(
const byte* input,
BLAKE2s_State& state);
162 void BLAKE2_Compress64_CXX(
const byte* input,
BLAKE2b_State& state);
164 #if CRYPTOPP_SSE41_AVAILABLE 165 extern void BLAKE2_Compress32_SSE4(
const byte* input,
BLAKE2s_State& state);
166 extern void BLAKE2_Compress64_SSE4(
const byte* input,
BLAKE2b_State& state);
169 #if CRYPTOPP_ARM_NEON_AVAILABLE 170 extern void BLAKE2_Compress32_NEON(
const byte* input,
BLAKE2s_State& state);
171 extern void BLAKE2_Compress64_NEON(
const byte* input,
BLAKE2b_State& state);
174 #if CRYPTOPP_POWER7_AVAILABLE 175 extern void BLAKE2_Compress32_POWER7(
const byte* input,
BLAKE2s_State& state);
176 #elif CRYPTOPP_ALTIVEC_AVAILABLE 177 extern void BLAKE2_Compress32_ALTIVEC(
const byte* input,
BLAKE2s_State& state);
180 #if CRYPTOPP_POWER8_AVAILABLE 181 extern void BLAKE2_Compress64_POWER8(
const byte* input,
BLAKE2b_State& state);
186 #if defined(CRYPTOPP_SSE41_AVAILABLE) 191 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 196 #if (CRYPTOPP_POWER8_AVAILABLE) 201 return GetAlignmentOf<word64>();
206 #if defined(CRYPTOPP_SSE41_AVAILABLE) 211 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 216 #if (CRYPTOPP_POWER8_AVAILABLE) 226 #if defined(CRYPTOPP_SSE41_AVAILABLE) 231 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 236 #if (CRYPTOPP_POWER7_AVAILABLE) 240 #elif (CRYPTOPP_ALTIVEC_AVAILABLE) 245 return GetAlignmentOf<word32>();
250 #if defined(CRYPTOPP_SSE41_AVAILABLE) 255 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 260 #if (CRYPTOPP_POWER7_AVAILABLE) 264 #elif (CRYPTOPP_ALTIVEC_AVAILABLE) 272 void BLAKE2s_State::Reset()
274 std::memset(m_hft, 0x00, m_hft.SizeInBytes());
278 void BLAKE2b_State::Reset()
280 std::memset(m_hft, 0x00, m_hft.SizeInBytes());
284 BLAKE2s_ParameterBlock::BLAKE2s_ParameterBlock(
size_t digestLen,
size_t keyLen,
285 const byte* saltStr,
size_t saltLen,
286 const byte* personalizationStr,
size_t personalizationLen)
288 Reset(digestLen, keyLen);
290 if (saltStr && saltLen)
291 memcpy_s(salt(), SALTSIZE, saltStr, saltLen);
293 if (personalizationStr && personalizationLen)
294 memcpy_s(personalization(), PERSONALIZATIONSIZE, personalizationStr, personalizationLen);
297 BLAKE2b_ParameterBlock::BLAKE2b_ParameterBlock(
size_t digestLen,
size_t keyLen,
298 const byte* saltStr,
size_t saltLen,
299 const byte* personalizationStr,
size_t personalizationLen)
301 Reset(digestLen, keyLen);
303 if (saltStr && saltLen)
304 memcpy_s(salt(), SALTSIZE, saltStr, saltLen);
306 if (personalizationStr && personalizationLen)
307 memcpy_s(personalization(), PERSONALIZATIONSIZE, personalizationStr, personalizationLen);
310 void BLAKE2s_ParameterBlock::Reset(
size_t digestLen,
size_t keyLen)
312 std::memset(m_data, 0x00, m_data.size());
313 m_data[DigestOff] =
static_cast<byte
>(digestLen);
314 m_data[KeyOff] =
static_cast<byte
>(keyLen);
315 m_data[FanoutOff] = m_data[DepthOff] = 1;
318 void BLAKE2b_ParameterBlock::Reset(
size_t digestLen,
size_t keyLen)
320 std::memset(m_data, 0x00, m_data.size());
321 m_data[DigestOff] =
static_cast<byte
>(digestLen);
322 m_data[KeyOff] =
static_cast<byte
>(keyLen);
323 m_data[FanoutOff] = m_data[DepthOff] = 1;
327 : m_digestSize(digestSize), m_keyLength(0), m_treeMode(treeMode)
337 : m_digestSize(digestSize), m_keyLength(0), m_treeMode(treeMode)
347 const byte* personalization,
size_t personalizationLength,
bool treeMode,
unsigned int digestSize)
348 : m_digestSize(digestSize), m_keyLength(static_cast<unsigned int>(keyLength)), m_treeMode(treeMode)
355 UncheckedSetKey(key, static_cast<unsigned int>(keyLength),
MakeParameters 363 const byte* personalization,
size_t personalizationLength,
bool treeMode,
unsigned int digestSize)
364 : m_digestSize(digestSize), m_keyLength(static_cast<unsigned int>(keyLength)), m_treeMode(treeMode)
371 UncheckedSetKey(key, static_cast<unsigned int>(keyLength),
MakeParameters 378 void BLAKE2s::UncheckedSetKey(
const byte *key,
unsigned int length,
const CryptoPP::NameValuePairs& params)
382 m_key.
New(BLOCKSIZE);
383 std::memcpy(m_key, key, length);
384 std::memset(m_key + length, 0x00, BLOCKSIZE - length);
385 m_keyLength = length;
393 m_digestSize =
static_cast<unsigned int>(params.GetIntValueWithDefault(
397 m_block.Reset(m_digestSize, m_keyLength);
410 void BLAKE2b::UncheckedSetKey(
const byte *key,
unsigned int length,
const CryptoPP::NameValuePairs& params)
414 m_key.
New(BLOCKSIZE);
415 std::memcpy(m_key, key, length);
416 std::memset(m_key + length, 0x00, BLOCKSIZE - length);
417 m_keyLength = length;
425 m_digestSize =
static_cast<unsigned int>(params.GetIntValueWithDefault(
429 m_block.Reset(m_digestSize, m_keyLength);
444 static const word32 zero[2] = {0,0};
450 static const word64 zero[2] = {0,0};
458 if (counter != NULLPTR)
460 word32* t = m_state.t();
467 if (block.data() == m_block.data())
468 m_block.Reset(m_digestSize, m_keyLength);
471 std::memcpy(m_block.data(), block.data(), m_block.size());
472 m_block.m_data[BLAKE2s_ParameterBlock::DigestOff] = (byte)m_digestSize;
473 m_block.m_data[BLAKE2s_ParameterBlock::KeyOff] = (byte)m_keyLength;
476 const word32* iv = BLAKE2S_IV;
478 put(iv[0])(iv[1])(iv[2])(iv[3])(iv[4])(iv[5])(iv[6])(iv[7]);
491 if (counter != NULLPTR)
493 word64* t = m_state.t();
500 if (block.data() == m_block.data())
501 m_block.Reset(m_digestSize, m_keyLength);
504 std::memcpy(m_block.data(), block.data(), m_block.size());
505 m_block.m_data[BLAKE2b_ParameterBlock::DigestOff] = (byte)m_digestSize;
506 m_block.m_data[BLAKE2b_ParameterBlock::KeyOff] = (byte)m_keyLength;
509 const word64* iv = BLAKE2B_IV;
511 put(iv[0])(iv[1])(iv[2])(iv[3])(iv[4])(iv[5])(iv[6])(iv[7]);
524 if (length > BLOCKSIZE - m_state.m_len)
526 if (m_state.m_len != 0)
529 const size_t fill = BLOCKSIZE - m_state.m_len;
530 std::memcpy(m_state.m_buf+m_state.m_len, input, fill);
532 IncrementCounter(BLOCKSIZE);
533 Compress(m_state.m_buf);
536 length -= fill, input += fill;
540 while (length > BLOCKSIZE)
542 IncrementCounter(BLOCKSIZE);
544 length -= BLOCKSIZE, input += BLOCKSIZE;
552 std::memcpy(m_state.m_buf+m_state.m_len, input, length);
553 m_state.m_len +=
static_cast<unsigned int>(length);
561 if (length > BLOCKSIZE - m_state.m_len)
563 if (m_state.m_len != 0)
566 const size_t fill = BLOCKSIZE - m_state.m_len;
567 std::memcpy(m_state.m_buf+m_state.m_len, input, fill);
569 IncrementCounter(BLOCKSIZE);
570 Compress(m_state.m_buf);
573 length -= fill, input += fill;
577 while (length > BLOCKSIZE)
580 IncrementCounter(BLOCKSIZE);
582 length -= BLOCKSIZE, input += BLOCKSIZE;
590 std::memcpy(m_state.m_buf + m_state.m_len, input, length);
591 m_state.m_len +=
static_cast<unsigned int>(length);
598 this->ThrowIfInvalidTruncatedSize(size);
599 word32* f = m_state.f();
602 f[0] = ~static_cast<word32>(0);
606 f[1] = ~static_cast<word32>(0);
609 IncrementCounter(m_state.m_len);
611 std::memset(m_state.m_buf + m_state.m_len, 0x00, BLOCKSIZE - m_state.m_len);
612 Compress(m_state.m_buf);
615 std::memcpy(hash, m_state.h(), size);
623 this->ThrowIfInvalidTruncatedSize(size);
624 word64* f = m_state.f();
627 f[0] = ~static_cast<word64>(0);
631 f[1] = ~static_cast<word64>(0);
634 IncrementCounter(m_state.m_len);
636 std::memset(m_state.m_buf + m_state.m_len, 0x00, BLOCKSIZE - m_state.m_len);
637 Compress(m_state.m_buf);
640 std::memcpy(hash, m_state.h(), size);
645 void BLAKE2s::IncrementCounter(
size_t count)
647 word32* t = m_state.t();
648 t[0] +=
static_cast<word32
>(count);
649 t[1] += !!(t[0] < count);
652 void BLAKE2b::IncrementCounter(
size_t count)
654 word64* t = m_state.t();
655 t[0] +=
static_cast<word64
>(count);
656 t[1] += !!(t[0] < count);
659 void BLAKE2s::Compress(
const byte *input)
661 #if CRYPTOPP_SSE41_AVAILABLE 664 return BLAKE2_Compress32_SSE4(input, m_state);
667 #if CRYPTOPP_ARM_NEON_AVAILABLE 670 return BLAKE2_Compress32_NEON(input, m_state);
673 #if CRYPTOPP_POWER7_AVAILABLE 676 return BLAKE2_Compress32_POWER7(input, m_state);
678 #elif CRYPTOPP_ALTIVEC_AVAILABLE 681 return BLAKE2_Compress32_ALTIVEC(input, m_state);
684 return BLAKE2_Compress32_CXX(input, m_state);
687 void BLAKE2b::Compress(
const byte *input)
689 #if CRYPTOPP_SSE41_AVAILABLE 692 return BLAKE2_Compress64_SSE4(input, m_state);
695 #if CRYPTOPP_ARM_NEON_AVAILABLE 698 return BLAKE2_Compress64_NEON(input, m_state);
701 #if CRYPTOPP_POWER8_AVAILABLE 704 return BLAKE2_Compress64_POWER8(input, m_state);
707 return BLAKE2_Compress64_CXX(input, m_state);
710 void BLAKE2_Compress64_CXX(
const byte* input,
BLAKE2b_State& state)
715 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]);
718 get2(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7]);
720 const word64* iv = BLAKE2B_IV;
721 const word64* tf = state.t();
726 v[12] = tf[0] ^ iv[4];
727 v[13] = tf[1] ^ iv[5];
728 v[14] = tf[2] ^ iv[6];
729 v[15] = tf[3] ^ iv[7];
731 BLAKE2B_ROUND<0>(m, v);
732 BLAKE2B_ROUND<1>(m, v);
733 BLAKE2B_ROUND<2>(m, v);
734 BLAKE2B_ROUND<3>(m, v);
735 BLAKE2B_ROUND<4>(m, v);
736 BLAKE2B_ROUND<5>(m, v);
737 BLAKE2B_ROUND<6>(m, v);
738 BLAKE2B_ROUND<7>(m, v);
739 BLAKE2B_ROUND<8>(m, v);
740 BLAKE2B_ROUND<9>(m, v);
741 BLAKE2B_ROUND<10>(m, v);
742 BLAKE2B_ROUND<11>(m, v);
744 word64* h = state.h();
745 for (
unsigned int i = 0; i < 8; ++i)
749 void BLAKE2_Compress32_CXX(
const byte* input,
BLAKE2s_State& state)
754 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]);
757 get2(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7]);
759 const word32* iv = BLAKE2S_IV;
760 const word32* tf = state.t();
765 v[12] = tf[0] ^ iv[4];
766 v[13] = tf[1] ^ iv[5];
767 v[14] = tf[2] ^ iv[6];
768 v[15] = tf[3] ^ iv[7];
770 BLAKE2S_ROUND<0>(m, v);
771 BLAKE2S_ROUND<1>(m, v);
772 BLAKE2S_ROUND<2>(m, v);
773 BLAKE2S_ROUND<3>(m, v);
774 BLAKE2S_ROUND<4>(m, v);
775 BLAKE2S_ROUND<5>(m, v);
776 BLAKE2S_ROUND<6>(m, v);
777 BLAKE2S_ROUND<7>(m, v);
778 BLAKE2S_ROUND<8>(m, v);
779 BLAKE2S_ROUND<9>(m, v);
781 word32* h = state.h();
782 for (
unsigned int i = 0; i < 8; ++i)
Used to pass byte array input as part of a NameValuePairs object.
Standard names for retrieving values by name when working with NameValuePairs.
const char * DigestSize()
int, in bytes
const char * TreeMode()
byte
void Update(const byte *input, size_t length)
Updates a hash with additional input.
Classes for working with NameValuePairs.
bool HasAltivec()
Determine if a PowerPC processor has Altivec available.
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
unsigned int OptimalDataAlignment() const
Provides input and output data alignment for optimal performance.
size_t size() const
Length of the memory block.
void resize(size_type newSize)
Change size and preserve contents.
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
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()
void TruncatedFinal(byte *hash, size_t size)
Computes the hash of the current message.
Library configuration file.
BLAKE2s(bool treeMode=false, unsigned int digestSize=DIGESTSIZE)
Construct a BLAKE2s hash.
void New(size_type newSize)
Change size without preserving contents.
byte order is little-endian
bool HasPower7()
Determine if a PowerPC processor has Power7 available.
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.
bool HasPower8()
Determine if a PowerPC processor has Power8 available.
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
const char * Salt()
ConstByteArrayParameter.
Classes for BLAKE2b and BLAKE2s message digests and keyed message digests.
void Update(const byte *input, size_t length)
Updates a hash with additional input.
const char * Personalization()
ConstByteArrayParameter.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Functions for CPU features and intrinsics.
void Restart()
Restart the hash.
BLAKE2s state information.
BLAKE2b state information.
T rotrConstant(T x)
Performs a right rotate.
Access a block of memory.
void TruncatedFinal(byte *hash, size_t size)
Computes the hash of the current message.
bool HasSSE41()
Determines SSE4.1 availability.
Access a block of memory.
Crypto++ library namespace.
BLAKE2b(bool treeMode=false, unsigned int digestSize=DIGESTSIZE)
Construct a BLAKE2b hash.
unsigned int OptimalDataAlignment() const
Provides input and output data alignment for optimal performance.
bool HasNEON()
Determine if an ARM processor has Advanced SIMD available.
void Restart()
Restart the hash.