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 59 extern const word32 BLAKE2S_IV[8];
60 extern const word64 BLAKE2B_IV[8];
62 CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32)
63 const word32 BLAKE2S_IV[8] = {
64 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
65 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
68 CRYPTOPP_ALIGN_DATA(ALIGN_SPEC64)
69 const word64 BLAKE2B_IV[8] = {
70 W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
71 W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
72 W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f),
73 W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)
78 ANONYMOUS_NAMESPACE_BEGIN
81 using CryptoPP::word32;
82 using CryptoPP::word64;
85 CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32)
86 const 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 },
99 CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32)
100 const 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 }
115 template <
unsigned int R,
unsigned int N>
116 inline void BLAKE2B_G(
const word64 m[16], word64& a, word64& b, word64& c, word64& d)
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);
128 template <
unsigned int R>
129 inline 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]);
141 template <
unsigned int R,
unsigned int N>
142 inline void BLAKE2S_G(
const word32 m[16], word32& a, word32& b, word32& c, word32& d)
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);
154 template <
unsigned int R>
155 inline 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]);
167 ANONYMOUS_NAMESPACE_END
171 void BLAKE2_Compress32_CXX(
const byte* input,
BLAKE2s_State& state);
172 void BLAKE2_Compress64_CXX(
const byte* input,
BLAKE2b_State& state);
174 #if CRYPTOPP_SSE41_AVAILABLE 175 extern void BLAKE2_Compress32_SSE4(
const byte* input,
BLAKE2s_State& state);
176 extern void BLAKE2_Compress64_SSE4(
const byte* input,
BLAKE2b_State& state);
179 #if CRYPTOPP_ARM_NEON_AVAILABLE 180 extern void BLAKE2_Compress32_NEON(
const byte* input,
BLAKE2s_State& state);
181 extern void BLAKE2_Compress64_NEON(
const byte* input,
BLAKE2b_State& state);
184 #if CRYPTOPP_ALTIVEC_AVAILABLE 185 extern void BLAKE2_Compress32_ALTIVEC(
const byte* input,
BLAKE2s_State& state);
188 #if CRYPTOPP_POWER8_AVAILABLE 189 extern 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) 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 : 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 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)
511 word64* t = m_state.t();
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);
615 word32* f = m_state.f();
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);
640 word64* f = m_state.f();
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);
661 void BLAKE2s::IncrementCounter(
size_t count)
663 word32* t = m_state.t();
664 t[0] +=
static_cast<word32
>(count);
665 t[1] += !!(t[0] < count);
668 void BLAKE2b::IncrementCounter(
size_t count)
670 word64* t = m_state.t();
671 t[0] +=
static_cast<word64
>(count);
672 t[1] += !!(t[0] < count);
675 void 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);
698 void 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);
721 void 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);
755 word64* h = state.h();
756 for (
unsigned int i = 0; i < 8; ++i)
760 void 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);
792 word32* h = state.h();
793 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
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()
Determine 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.