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 # undef CRYPTOPP_POWER7_AVAILABLE
42 # undef CRYPTOPP_POWER8_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_POWER8_AVAILABLE
175 extern void BLAKE2_Compress32_POWER8(
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_POWER8_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_POWER8_AVAILABLE)
264 #elif (CRYPTOPP_ALTIVEC_AVAILABLE)
272 void BLAKE2s_State::Reset()
278 void BLAKE2b_State::Reset()
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 : m_digestSize(digestSize), m_keyLength(0), m_treeMode(false)
357 : m_digestSize(digestSize), m_keyLength(0), m_treeMode(false)
367 const byte* personalization,
size_t personalizationLength,
bool treeMode,
unsigned int digestSize)
368 : m_digestSize(digestSize), m_keyLength(static_cast<unsigned int>(keyLength)), m_treeMode(treeMode)
375 UncheckedSetKey(key,
static_cast<unsigned int>(keyLength),
MakeParameters
383 const byte* personalization,
size_t personalizationLength,
bool treeMode,
unsigned int digestSize)
384 : m_digestSize(digestSize), m_keyLength(static_cast<unsigned int>(keyLength)), m_treeMode(treeMode)
391 UncheckedSetKey(key,
static_cast<unsigned int>(keyLength),
MakeParameters
398 void BLAKE2s::UncheckedSetKey(
const byte *key,
unsigned int length,
const CryptoPP::NameValuePairs& params)
402 m_key.
New(BLOCKSIZE);
403 std::memcpy(m_key, key, length);
404 std::memset(m_key + length, 0x00, BLOCKSIZE - length);
405 m_keyLength = length;
413 m_digestSize =
static_cast<unsigned int>(params.GetIntValueWithDefault(
417 m_block.Reset(m_digestSize, m_keyLength);
430 void BLAKE2b::UncheckedSetKey(
const byte *key,
unsigned int length,
const CryptoPP::NameValuePairs& params)
434 m_key.
New(BLOCKSIZE);
435 std::memcpy(m_key, key, length);
436 std::memset(m_key + length, 0x00, BLOCKSIZE - length);
437 m_keyLength = length;
445 m_digestSize =
static_cast<unsigned int>(params.GetIntValueWithDefault(
449 m_block.Reset(m_digestSize, m_keyLength);
464 static const word32 zero[2] = {0,0};
470 static const word64 zero[2] = {0,0};
478 if (counter != NULLPTR)
480 word32* t = m_state.t();
487 if (block.data() == m_block.data())
488 m_block.Reset(m_digestSize, m_keyLength);
491 std::memcpy(m_block.data(), block.data(), m_block.size());
492 m_block.m_data[BLAKE2s_ParameterBlock::DigestOff] = (byte)m_digestSize;
493 m_block.m_data[BLAKE2s_ParameterBlock::KeyOff] = (byte)m_keyLength;
496 const word32* iv = BLAKE2S_IV;
498 put(iv[0])(iv[1])(iv[2])(iv[3])(iv[4])(iv[5])(iv[6])(iv[7]);
511 if (counter != NULLPTR)
513 word64* t = m_state.t();
520 if (block.data() == m_block.data())
521 m_block.Reset(m_digestSize, m_keyLength);
524 std::memcpy(m_block.data(), block.data(), m_block.size());
525 m_block.m_data[BLAKE2b_ParameterBlock::DigestOff] = (byte)m_digestSize;
526 m_block.m_data[BLAKE2b_ParameterBlock::KeyOff] = (byte)m_keyLength;
529 const word64* iv = BLAKE2B_IV;
531 put(iv[0])(iv[1])(iv[2])(iv[3])(iv[4])(iv[5])(iv[6])(iv[7]);
544 if (length > BLOCKSIZE - m_state.m_len)
546 if (m_state.m_len != 0)
549 const size_t fill = BLOCKSIZE - m_state.m_len;
550 std::memcpy(m_state.m_buf+m_state.m_len, input, fill);
552 IncrementCounter(BLOCKSIZE);
553 Compress(m_state.m_buf);
556 length -= fill, input += fill;
560 while (length > BLOCKSIZE)
562 IncrementCounter(BLOCKSIZE);
564 length -= BLOCKSIZE, input += BLOCKSIZE;
572 std::memcpy(m_state.m_buf+m_state.m_len, input, length);
573 m_state.m_len +=
static_cast<unsigned int>(length);
581 if (length > BLOCKSIZE - m_state.m_len)
583 if (m_state.m_len != 0)
586 const size_t fill = BLOCKSIZE - m_state.m_len;
587 std::memcpy(m_state.m_buf+m_state.m_len, input, fill);
589 IncrementCounter(BLOCKSIZE);
590 Compress(m_state.m_buf);
593 length -= fill, input += fill;
597 while (length > BLOCKSIZE)
600 IncrementCounter(BLOCKSIZE);
602 length -= BLOCKSIZE, input += BLOCKSIZE;
610 std::memcpy(m_state.m_buf + m_state.m_len, input, length);
611 m_state.m_len +=
static_cast<unsigned int>(length);
618 this->ThrowIfInvalidTruncatedSize(size);
619 word32* f = m_state.f();
622 f[0] = ~static_cast<word32>(0);
626 f[1] = ~static_cast<word32>(0);
629 IncrementCounter(m_state.m_len);
631 std::memset(m_state.m_buf + m_state.m_len, 0x00, BLOCKSIZE - m_state.m_len);
632 Compress(m_state.m_buf);
635 std::memcpy(hash, m_state.h(), size);
643 this->ThrowIfInvalidTruncatedSize(size);
644 word64* f = m_state.f();
647 f[0] = ~static_cast<word64>(0);
651 f[1] = ~static_cast<word64>(0);
654 IncrementCounter(m_state.m_len);
656 std::memset(m_state.m_buf + m_state.m_len, 0x00, BLOCKSIZE - m_state.m_len);
657 Compress(m_state.m_buf);
660 std::memcpy(hash, m_state.h(), size);
665 void BLAKE2s::IncrementCounter(
size_t count)
667 word32* t = m_state.t();
668 t[0] +=
static_cast<word32
>(count);
669 t[1] += !!(t[0] < count);
672 void BLAKE2b::IncrementCounter(
size_t count)
674 word64* t = m_state.t();
675 t[0] +=
static_cast<word64
>(count);
676 t[1] += !!(t[0] < count);
679 void BLAKE2s::Compress(
const byte *input)
681 #if CRYPTOPP_SSE41_AVAILABLE
684 return BLAKE2_Compress32_SSE4(input, m_state);
687 #if CRYPTOPP_ARM_NEON_AVAILABLE
690 return BLAKE2_Compress32_NEON(input, m_state);
693 #if CRYPTOPP_POWER8_AVAILABLE
696 return BLAKE2_Compress32_POWER8(input, m_state);
698 #elif CRYPTOPP_ALTIVEC_AVAILABLE
701 return BLAKE2_Compress32_ALTIVEC(input, m_state);
704 return BLAKE2_Compress32_CXX(input, m_state);
707 void BLAKE2b::Compress(
const byte *input)
709 #if CRYPTOPP_SSE41_AVAILABLE
712 return BLAKE2_Compress64_SSE4(input, m_state);
715 #if CRYPTOPP_ARM_NEON_AVAILABLE
718 return BLAKE2_Compress64_NEON(input, m_state);
721 #if CRYPTOPP_POWER8_AVAILABLE
724 return BLAKE2_Compress64_POWER8(input, m_state);
727 return BLAKE2_Compress64_CXX(input, m_state);
730 void BLAKE2_Compress64_CXX(
const byte* input,
BLAKE2b_State& state)
735 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]);
738 get2(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7]);
740 const word64* iv = BLAKE2B_IV;
741 const word64* tf = state.t();
746 v[12] = tf[0] ^ iv[4];
747 v[13] = tf[1] ^ iv[5];
748 v[14] = tf[2] ^ iv[6];
749 v[15] = tf[3] ^ iv[7];
751 BLAKE2B_ROUND<0>(m, v);
752 BLAKE2B_ROUND<1>(m, v);
753 BLAKE2B_ROUND<2>(m, v);
754 BLAKE2B_ROUND<3>(m, v);
755 BLAKE2B_ROUND<4>(m, v);
756 BLAKE2B_ROUND<5>(m, v);
757 BLAKE2B_ROUND<6>(m, v);
758 BLAKE2B_ROUND<7>(m, v);
759 BLAKE2B_ROUND<8>(m, v);
760 BLAKE2B_ROUND<9>(m, v);
761 BLAKE2B_ROUND<10>(m, v);
762 BLAKE2B_ROUND<11>(m, v);
764 word64* h = state.h();
765 for (
unsigned int i = 0; i < 8; ++i)
769 void BLAKE2_Compress32_CXX(
const byte* input,
BLAKE2s_State& state)
774 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]);
777 get2(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7]);
779 const word32* iv = BLAKE2S_IV;
780 const word32* tf = state.t();
785 v[12] = tf[0] ^ iv[4];
786 v[13] = tf[1] ^ iv[5];
787 v[14] = tf[2] ^ iv[6];
788 v[15] = tf[3] ^ iv[7];
790 BLAKE2S_ROUND<0>(m, v);
791 BLAKE2S_ROUND<1>(m, v);
792 BLAKE2S_ROUND<2>(m, v);
793 BLAKE2S_ROUND<3>(m, v);
794 BLAKE2S_ROUND<4>(m, v);
795 BLAKE2S_ROUND<5>(m, v);
796 BLAKE2S_ROUND<6>(m, v);
797 BLAKE2S_ROUND<7>(m, v);
798 BLAKE2S_ROUND<8>(m, v);
799 BLAKE2S_ROUND<9>(m, v);
801 word32* h = state.h();
802 for (
unsigned int i = 0; i < 8; ++i)
Classes for working with NameValuePairs.
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Standard names for retrieving values by name when working with NameValuePairs.
Classes for BLAKE2b and BLAKE2s message digests and keyed message digests.
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
void TruncatedFinal(byte *hash, size_t size)
Computes the hash of the current message.
unsigned int OptimalDataAlignment() const
Provides input and output data alignment for optimal performance.
void Restart()
Restart the hash.
void Update(const byte *input, size_t length)
Updates a hash with additional input.
BLAKE2b(bool treeMode=false, unsigned int digestSize=DIGESTSIZE)
Construct a BLAKE2b hash.
void Update(const byte *input, size_t length)
Updates a hash with additional input.
void Restart()
Restart the hash.
void TruncatedFinal(byte *hash, size_t size)
Computes the hash of the current message.
BLAKE2s(bool treeMode=false, unsigned int digestSize=DIGESTSIZE)
Construct a BLAKE2s hash.
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
unsigned int OptimalDataAlignment() const
Provides input and output data alignment for optimal performance.
Used to pass byte array input as part of a NameValuePairs object.
size_t size() const
Length of the memory block.
const byte * begin() const
Pointer to the first byte in the memory block.
Access a block of memory.
Access a block of memory.
void New(size_type newSize)
Change size without preserving contents.
size_type SizeInBytes() const
Provides the number of bytes in the SecBlock.
size_type size() const
Provides the count of elements in the SecBlock.
void resize(size_type newSize)
Change size and preserve contents.
Library configuration file.
Functions for CPU features and intrinsics.
bool HasAltivec()
Determine if a PowerPC processor has Altivec available.
bool HasNEON()
Determine if an ARM processor has Advanced SIMD available.
bool HasPower8()
Determine if a PowerPC processor has Power8 available.
bool HasSSE41()
Determines SSE4.1 availability.
Abstract base classes that provide a uniform interface to this library.
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
Bounds checking replacement for memcpy()
T rotrConstant(T x)
Performs a right rotate.
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
Crypto++ library namespace.
const char * TreeMode()
byte
const char * Personalization()
ConstByteArrayParameter.
const char * Salt()
ConstByteArrayParameter.
const char * DigestSize()
int, in bytes
BLAKE2b state information.
BLAKE2s state information.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.