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
48#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
49# define ALIGN_SPEC32 16
50# define ALIGN_SPEC64 16
52# define ALIGN_SPEC32 4
53# define ALIGN_SPEC64 8
59extern const word32 BLAKE2S_IV[8];
60extern const word64 BLAKE2B_IV[8];
62CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32)
63const word32 BLAKE2S_IV[8] = {
64 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
65 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
68CRYPTOPP_ALIGN_DATA(ALIGN_SPEC64)
69const word64 BLAKE2B_IV[8] = {
78ANONYMOUS_NAMESPACE_BEGIN
81using CryptoPP::word32;
82using CryptoPP::word64;
83using CryptoPP::rotrConstant;
85CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32)
86const byte BLAKE2S_SIGMA[10][16] = {
87 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
88 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
89 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
90 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
91 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
92 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
93 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
94 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
95 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
96 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
99CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32)
100const byte BLAKE2B_SIGMA[12][16] = {
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 },
103 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
104 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
105 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
106 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
107 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
108 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
109 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
110 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
111 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
112 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
115template <
unsigned int R,
unsigned int N>
118 a = a + b + m[BLAKE2B_SIGMA[R][2*N+0]];
119 d = rotrConstant<32>(d ^ a);
121 b = rotrConstant<24>(b ^ c);
122 a = a + b + m[BLAKE2B_SIGMA[R][2*N+1]];
123 d = rotrConstant<16>(d ^ a);
125 b = rotrConstant<63>(b ^ c);
128template <
unsigned int R>
129inline void BLAKE2B_ROUND(
const word64 m[16],
word64 v[16])
131 BLAKE2B_G<R,0>(m,v[ 0],v[ 4],v[ 8],v[12]);
132 BLAKE2B_G<R,1>(m,v[ 1],v[ 5],v[ 9],v[13]);
133 BLAKE2B_G<R,2>(m,v[ 2],v[ 6],v[10],v[14]);
134 BLAKE2B_G<R,3>(m,v[ 3],v[ 7],v[11],v[15]);
135 BLAKE2B_G<R,4>(m,v[ 0],v[ 5],v[10],v[15]);
136 BLAKE2B_G<R,5>(m,v[ 1],v[ 6],v[11],v[12]);
137 BLAKE2B_G<R,6>(m,v[ 2],v[ 7],v[ 8],v[13]);
138 BLAKE2B_G<R,7>(m,v[ 3],v[ 4],v[ 9],v[14]);
141template <
unsigned int R,
unsigned int N>
144 a = a + b + m[BLAKE2S_SIGMA[R][2*N+0]];
145 d = rotrConstant<16>(d ^ a);
147 b = rotrConstant<12>(b ^ c);
148 a = a + b + m[BLAKE2S_SIGMA[R][2*N+1]];
149 d = rotrConstant<8>(d ^ a);
151 b = rotrConstant<7>(b ^ c);
154template <
unsigned int R>
155inline void BLAKE2S_ROUND(
const word32 m[16],
word32 v[])
157 BLAKE2S_G<R,0>(m,v[ 0],v[ 4],v[ 8],v[12]);
158 BLAKE2S_G<R,1>(m,v[ 1],v[ 5],v[ 9],v[13]);
159 BLAKE2S_G<R,2>(m,v[ 2],v[ 6],v[10],v[14]);
160 BLAKE2S_G<R,3>(m,v[ 3],v[ 7],v[11],v[15]);
161 BLAKE2S_G<R,4>(m,v[ 0],v[ 5],v[10],v[15]);
162 BLAKE2S_G<R,5>(m,v[ 1],v[ 6],v[11],v[12]);
163 BLAKE2S_G<R,6>(m,v[ 2],v[ 7],v[ 8],v[13]);
164 BLAKE2S_G<R,7>(m,v[ 3],v[ 4],v[ 9],v[14]);
167ANONYMOUS_NAMESPACE_END
171void BLAKE2_Compress32_CXX(
const byte* input,
BLAKE2s_State& state);
172void BLAKE2_Compress64_CXX(
const byte* input,
BLAKE2b_State& state);
174#if CRYPTOPP_SSE41_AVAILABLE
175extern void BLAKE2_Compress32_SSE4(
const byte* input,
BLAKE2s_State& state);
176extern void BLAKE2_Compress64_SSE4(
const byte* input,
BLAKE2b_State& state);
179#if CRYPTOPP_ARM_NEON_AVAILABLE
180extern void BLAKE2_Compress32_NEON(
const byte* input,
BLAKE2s_State& state);
181extern void BLAKE2_Compress64_NEON(
const byte* input,
BLAKE2b_State& state);
184#if CRYPTOPP_ALTIVEC_AVAILABLE
185extern void BLAKE2_Compress32_ALTIVEC(
const byte* input,
BLAKE2s_State& state);
188#if CRYPTOPP_POWER8_AVAILABLE
189extern void BLAKE2_Compress64_POWER8(
const byte* input,
BLAKE2b_State& state);
194#if defined(CRYPTOPP_SSE41_AVAILABLE)
199#if (CRYPTOPP_ARM_NEON_AVAILABLE)
204#if (CRYPTOPP_POWER8_AVAILABLE)
209 return GetAlignmentOf<word64>();
214#if defined(CRYPTOPP_SSE41_AVAILABLE)
219#if (CRYPTOPP_ARM_NEON_AVAILABLE)
224#if (CRYPTOPP_POWER8_AVAILABLE)
234#if defined(CRYPTOPP_SSE41_AVAILABLE)
239#if (CRYPTOPP_ARM_NEON_AVAILABLE)
244#if (CRYPTOPP_ALTIVEC_AVAILABLE)
249 return GetAlignmentOf<word32>();
254#if defined(CRYPTOPP_SSE41_AVAILABLE)
259#if (CRYPTOPP_ARM_NEON_AVAILABLE)
264#if (CRYPTOPP_ALTIVEC_AVAILABLE)
272void BLAKE2s_State::Reset()
278void BLAKE2b_State::Reset()
284BLAKE2s_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);
297BLAKE2b_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);
310void 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;
318void 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
398void 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);
430void 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)
487 if (block.data() != m_block.data()) {
488 std::memcpy(m_block.data(), block.data(), m_block.size());
491 m_block.m_data[BLAKE2s_ParameterBlock::DigestOff] = (
byte)m_digestSize;
492 m_block.m_data[BLAKE2s_ParameterBlock::KeyOff] = (
byte)m_keyLength;
494 const word32* iv = BLAKE2S_IV;
496 put(iv[0])(iv[1])(iv[2])(iv[3])(iv[4])(iv[5])(iv[6])(iv[7]);
509 if (counter != NULLPTR)
518 if (block.data() != m_block.data()) {
519 std::memcpy(m_block.data(), block.data(), m_block.size());
522 m_block.m_data[BLAKE2b_ParameterBlock::DigestOff] = (
byte)m_digestSize;
523 m_block.m_data[BLAKE2b_ParameterBlock::KeyOff] = (
byte)m_keyLength;
525 const word64* iv = BLAKE2B_IV;
527 put(iv[0])(iv[1])(iv[2])(iv[3])(iv[4])(iv[5])(iv[6])(iv[7]);
540 if (length > BLOCKSIZE - m_state.m_len)
542 if (m_state.m_len != 0)
545 const size_t fill = BLOCKSIZE - m_state.m_len;
546 std::memcpy(m_state.m_buf+m_state.m_len, input, fill);
548 IncrementCounter(BLOCKSIZE);
549 Compress(m_state.m_buf);
552 length -= fill, input += fill;
556 while (length > BLOCKSIZE)
558 IncrementCounter(BLOCKSIZE);
560 length -= BLOCKSIZE, input += BLOCKSIZE;
568 std::memcpy(m_state.m_buf+m_state.m_len, input, length);
569 m_state.m_len +=
static_cast<unsigned int>(length);
577 if (length > BLOCKSIZE - m_state.m_len)
579 if (m_state.m_len != 0)
582 const size_t fill = BLOCKSIZE - m_state.m_len;
583 std::memcpy(m_state.m_buf+m_state.m_len, input, fill);
585 IncrementCounter(BLOCKSIZE);
586 Compress(m_state.m_buf);
589 length -= fill, input += fill;
593 while (length > BLOCKSIZE)
596 IncrementCounter(BLOCKSIZE);
598 length -= BLOCKSIZE, input += BLOCKSIZE;
606 std::memcpy(m_state.m_buf + m_state.m_len, input, length);
607 m_state.m_len +=
static_cast<unsigned int>(length);
614 this->ThrowIfInvalidTruncatedSize(size);
618 f[0] = ~static_cast<word32>(0);
622 f[1] = ~static_cast<word32>(0);
625 IncrementCounter(m_state.m_len);
627 std::memset(m_state.m_buf + m_state.m_len, 0x00, BLOCKSIZE - m_state.m_len);
628 Compress(m_state.m_buf);
631 std::memcpy(hash, m_state.h(), size);
639 this->ThrowIfInvalidTruncatedSize(size);
643 f[0] = ~static_cast<word64>(0);
647 f[1] = ~static_cast<word64>(0);
650 IncrementCounter(m_state.m_len);
652 std::memset(m_state.m_buf + m_state.m_len, 0x00, BLOCKSIZE - m_state.m_len);
653 Compress(m_state.m_buf);
656 std::memcpy(hash, m_state.h(), size);
661void BLAKE2s::IncrementCounter(
size_t count)
664 t[0] +=
static_cast<word32>(count);
665 t[1] += !!(t[0] < count);
668void BLAKE2b::IncrementCounter(
size_t count)
671 t[0] +=
static_cast<word64>(count);
672 t[1] += !!(t[0] < count);
675void BLAKE2s::Compress(
const byte *input)
677#if CRYPTOPP_SSE41_AVAILABLE
680 return BLAKE2_Compress32_SSE4(input, m_state);
683#if CRYPTOPP_ARM_NEON_AVAILABLE
686 return BLAKE2_Compress32_NEON(input, m_state);
689#if CRYPTOPP_ALTIVEC_AVAILABLE
692 return BLAKE2_Compress32_ALTIVEC(input, m_state);
695 return BLAKE2_Compress32_CXX(input, m_state);
698void BLAKE2b::Compress(
const byte *input)
700#if CRYPTOPP_SSE41_AVAILABLE
703 return BLAKE2_Compress64_SSE4(input, m_state);
706#if CRYPTOPP_ARM_NEON_AVAILABLE
709 return BLAKE2_Compress64_NEON(input, m_state);
712#if CRYPTOPP_POWER8_AVAILABLE
715 return BLAKE2_Compress64_POWER8(input, m_state);
718 return BLAKE2_Compress64_CXX(input, m_state);
721void BLAKE2_Compress64_CXX(
const byte* input,
BLAKE2b_State& state)
726 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]);
729 get2(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7]);
731 const word64* iv = BLAKE2B_IV;
732 const word64* tf = state.t();
737 v[12] = tf[0] ^ iv[4];
738 v[13] = tf[1] ^ iv[5];
739 v[14] = tf[2] ^ iv[6];
740 v[15] = tf[3] ^ iv[7];
742 BLAKE2B_ROUND<0>(m, v);
743 BLAKE2B_ROUND<1>(m, v);
744 BLAKE2B_ROUND<2>(m, v);
745 BLAKE2B_ROUND<3>(m, v);
746 BLAKE2B_ROUND<4>(m, v);
747 BLAKE2B_ROUND<5>(m, v);
748 BLAKE2B_ROUND<6>(m, v);
749 BLAKE2B_ROUND<7>(m, v);
750 BLAKE2B_ROUND<8>(m, v);
751 BLAKE2B_ROUND<9>(m, v);
752 BLAKE2B_ROUND<10>(m, v);
753 BLAKE2B_ROUND<11>(m, v);
756 for (
unsigned int i = 0; i < 8; ++i)
760void BLAKE2_Compress32_CXX(
const byte* input,
BLAKE2s_State& state)
765 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]);
768 get2(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7]);
770 const word32* iv = BLAKE2S_IV;
771 const word32* tf = state.t();
776 v[12] = tf[0] ^ iv[4];
777 v[13] = tf[1] ^ iv[5];
778 v[14] = tf[2] ^ iv[6];
779 v[15] = tf[3] ^ iv[7];
781 BLAKE2S_ROUND<0>(m, v);
782 BLAKE2S_ROUND<1>(m, v);
783 BLAKE2S_ROUND<2>(m, v);
784 BLAKE2S_ROUND<3>(m, v);
785 BLAKE2S_ROUND<4>(m, v);
786 BLAKE2S_ROUND<5>(m, v);
787 BLAKE2S_ROUND<6>(m, v);
788 BLAKE2S_ROUND<7>(m, v);
789 BLAKE2S_ROUND<8>(m, v);
790 BLAKE2S_ROUND<9>(m, v);
793 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.
const byte * begin() const
Pointer to the first byte in the memory block.
size_t size() const
Length of 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.
unsigned char byte
8-bit unsigned datatype
#define W64LIT(x)
Declare an unsigned word64.
unsigned int word32
32-bit unsigned datatype
unsigned long long word64
64-bit unsigned datatype
Functions for CPU features and intrinsics.
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 ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
Crypto++ library namespace.
const char * DigestSize()
int, in bytes
const char * TreeMode()
byte
const char * Personalization()
ConstByteArrayParameter.
const char * Salt()
ConstByteArrayParameter.
BLAKE2b state information.
BLAKE2s state information.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.