14 #if defined(__GNUC__) && (__GNUC__ < 4) 15 # undef CRYPTOPP_SSE2_INTRIN_AVAILABLE 20 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 21 extern void ChaCha_OperateKeystream_NEON(
const word32 *state,
const byte* input, byte *output,
unsigned int rounds);
24 #if (CRYPTOPP_AVX2_AVAILABLE) 25 extern void ChaCha_OperateKeystream_AVX2(
const word32 *state,
const byte* input, byte *output,
unsigned int rounds);
27 #if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) 28 extern void ChaCha_OperateKeystream_SSE2(
const word32 *state,
const byte* input, byte *output,
unsigned int rounds);
31 #if (CRYPTOPP_POWER8_AVAILABLE) 32 extern void ChaCha_OperateKeystream_POWER8(
const word32 *state,
const byte* input, byte *output,
unsigned int rounds);
33 #elif (CRYPTOPP_ALTIVEC_AVAILABLE) 34 extern void ChaCha_OperateKeystream_ALTIVEC(
const word32 *state,
const byte* input, byte *output,
unsigned int rounds);
37 #if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) 38 void ChaCha_TestInstantiations()
50 #define CHACHA_QUARTER_ROUND(a,b,c,d) \ 51 a += b; d ^= a; d = rotlConstant<16,word32>(d); \ 52 c += d; b ^= c; b = rotlConstant<12,word32>(b); \ 53 a += b; d ^= a; d = rotlConstant<8,word32>(d); \ 54 c += d; b ^= c; b = rotlConstant<7,word32>(b); 56 #define CHACHA_OUTPUT(x){\ 57 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 0, x0 + state[0]);\ 58 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 1, x1 + state[1]);\ 59 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 2, x2 + state[2]);\ 60 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 3, x3 + state[3]);\ 61 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 4, x4 + state[4]);\ 62 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 5, x5 + state[5]);\ 63 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 6, x6 + state[6]);\ 64 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 7, x7 + state[7]);\ 65 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 8, x8 + state[8]);\ 66 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 9, x9 + state[9]);\ 67 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 10, x10 + state[10]);\ 68 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 11, x11 + state[11]);\ 69 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 12, x12 + state[12]);\ 70 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 13, x13 + state[13]);\ 71 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 14, x14 + state[14]);\ 72 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 15, x15 + state[15]);} 74 ANONYMOUS_NAMESPACE_BEGIN
79 typedef word32 WordType;
80 enum {BYTES_PER_ITERATION=64};
88 inline bool MultiBlockSafe(
unsigned int ctrLow,
unsigned int blocks)
90 return 0xffffffff - ctrLow > blocks;
97 word32 state[16], word32& ctrLow, word32& ctrHigh, word32 rounds,
98 byte *output,
const byte *input,
size_t iterationCount)
102 #if (CRYPTOPP_AVX2_AVAILABLE) 105 while (iterationCount >= 8 && MultiBlockSafe(state[12], 8))
108 ChaCha_OperateKeystream_AVX2(state, xorInput ? input : NULLPTR, output, rounds);
113 input += (!!xorInput) * 8 * BYTES_PER_ITERATION;
114 output += 8 * BYTES_PER_ITERATION;
120 #if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) 123 while (iterationCount >= 4 && MultiBlockSafe(state[12], 4))
126 ChaCha_OperateKeystream_SSE2(state, xorInput ? input : NULLPTR, output, rounds);
131 input += (!!xorInput)*4*BYTES_PER_ITERATION;
132 output += 4*BYTES_PER_ITERATION;
138 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 141 while (iterationCount >= 4 && MultiBlockSafe(state[12], 4))
144 ChaCha_OperateKeystream_NEON(state, xorInput ? input : NULLPTR, output, rounds);
149 input += (!!xorInput)*4*BYTES_PER_ITERATION;
150 output += 4*BYTES_PER_ITERATION;
156 #if (CRYPTOPP_POWER8_AVAILABLE) 159 while (iterationCount >= 4 && MultiBlockSafe(state[12], 4))
162 ChaCha_OperateKeystream_POWER8(state, xorInput ? input : NULLPTR, output, rounds);
167 input += (!!xorInput)*4*BYTES_PER_ITERATION;
168 output += 4*BYTES_PER_ITERATION;
172 #elif (CRYPTOPP_ALTIVEC_AVAILABLE) 175 while (iterationCount >= 4 && MultiBlockSafe(state[12], 4))
178 ChaCha_OperateKeystream_ALTIVEC(state, xorInput ? input : NULLPTR, output, rounds);
183 input += (!!xorInput)*4*BYTES_PER_ITERATION;
184 output += 4*BYTES_PER_ITERATION;
192 word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
194 x0 = state[0]; x1 = state[1]; x2 = state[2]; x3 = state[3];
195 x4 = state[4]; x5 = state[5]; x6 = state[6]; x7 = state[7];
196 x8 = state[8]; x9 = state[9]; x10 = state[10]; x11 = state[11];
197 x12 = state[12]; x13 = state[13]; x14 = state[14]; x15 = state[15];
199 for (
int i = static_cast<int>(rounds); i > 0; i -= 2)
201 CHACHA_QUARTER_ROUND(x0, x4, x8, x12);
202 CHACHA_QUARTER_ROUND(x1, x5, x9, x13);
203 CHACHA_QUARTER_ROUND(x2, x6, x10, x14);
204 CHACHA_QUARTER_ROUND(x3, x7, x11, x15);
206 CHACHA_QUARTER_ROUND(x0, x5, x10, x15);
207 CHACHA_QUARTER_ROUND(x1, x6, x11, x12);
208 CHACHA_QUARTER_ROUND(x2, x7, x8, x13);
209 CHACHA_QUARTER_ROUND(x3, x4, x9, x14);
221 }
while (iterationCount--);
225 void HChaCha_OperateKeystream(
const word32 state[16], word32 output[8])
227 word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
229 x0 = state[0]; x1 = state[1]; x2 = state[2]; x3 = state[3];
230 x4 = state[4]; x5 = state[5]; x6 = state[6]; x7 = state[7];
231 x8 = state[8]; x9 = state[9]; x10 = state[10]; x11 = state[11];
232 x12 = state[12]; x13 = state[13]; x14 = state[14]; x15 = state[15];
234 for (
int i = 20; i > 0; i -= 2)
236 CHACHA_QUARTER_ROUND(x0, x4, x8, x12);
237 CHACHA_QUARTER_ROUND(x1, x5, x9, x13);
238 CHACHA_QUARTER_ROUND(x2, x6, x10, x14);
239 CHACHA_QUARTER_ROUND(x3, x7, x11, x15);
241 CHACHA_QUARTER_ROUND(x0, x5, x10, x15);
242 CHACHA_QUARTER_ROUND(x1, x6, x11, x12);
243 CHACHA_QUARTER_ROUND(x2, x7, x8, x13);
244 CHACHA_QUARTER_ROUND(x3, x4, x9, x14);
247 output[0] = x0; output[1] = x1;
248 output[2] = x2; output[3] = x3;
249 output[4] = x12; output[5] = x13;
250 output[6] = x14; output[7] = x15;
253 std::string ChaCha_AlgorithmProvider()
255 #if (CRYPTOPP_AVX2_AVAILABLE) 260 #if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) 265 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 270 #if (CRYPTOPP_POWER8_AVAILABLE) 274 #elif (CRYPTOPP_ALTIVEC_AVAILABLE) 282 unsigned int ChaCha_GetAlignment()
284 #if (CRYPTOPP_AVX2_AVAILABLE) 289 #if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) 294 #if (CRYPTOPP_ALTIVEC_AVAILABLE) 299 return GetAlignmentOf<word32>();
302 unsigned int ChaCha_GetOptimalBlockSize()
304 #if (CRYPTOPP_AVX2_AVAILABLE) 306 return 8 * BYTES_PER_ITERATION;
309 #if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) 311 return 4*BYTES_PER_ITERATION;
314 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 316 return 4*BYTES_PER_ITERATION;
319 #if (CRYPTOPP_ALTIVEC_AVAILABLE) 321 return 4*BYTES_PER_ITERATION;
324 return BYTES_PER_ITERATION;
327 ANONYMOUS_NAMESPACE_END
333 std::string ChaCha_Policy::AlgorithmName()
const 335 return std::string(
"ChaCha")+
IntToString(m_rounds);
338 std::string ChaCha_Policy::AlgorithmProvider()
const 340 return ChaCha_AlgorithmProvider();
343 void ChaCha_Policy::CipherSetKey(
const NameValuePairs ¶ms,
const byte *key,
size_t length)
346 CRYPTOPP_UNUSED(key); CRYPTOPP_UNUSED(length);
350 if (rounds != 20 && rounds != 12 && rounds != 8)
357 m_state[0] = 0x61707865;
358 m_state[1] = (length == 16) ? 0x3120646e : 0x3320646e;
359 m_state[2] = (length == 16) ? 0x79622d36 : 0x79622d32;
360 m_state[3] = 0x6b206574;
363 get1(m_state[4])(m_state[5])(m_state[6])(m_state[7]);
366 get2(m_state[8])(m_state[9])(m_state[10])(m_state[11]);
369 void ChaCha_Policy::CipherResynchronize(byte *keystreamBuffer,
const byte *
IV,
size_t length)
371 CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length);
375 m_state[12] = m_state[13] = 0;
376 get(m_state[14])(m_state[15]);
379 void ChaCha_Policy::SeekToIteration(lword iterationCount)
381 m_state[12] = (word32)iterationCount;
382 m_state[13] = (word32)SafeRightShift<32>(iterationCount);
385 unsigned int ChaCha_Policy::GetAlignment()
const 387 return ChaCha_GetAlignment();
390 unsigned int ChaCha_Policy::GetOptimalBlockSize()
const 392 return ChaCha_GetOptimalBlockSize();
396 byte *output,
const byte *input,
size_t iterationCount)
398 ChaCha_OperateKeystream(operation, m_state, m_state[12], m_state[13],
399 m_rounds, output, input, iterationCount);
404 std::string ChaChaTLS_Policy::AlgorithmName()
const 406 return std::string(
"ChaChaTLS");
409 std::string ChaChaTLS_Policy::AlgorithmProvider()
const 411 return ChaCha_AlgorithmProvider();
414 void ChaChaTLS_Policy::CipherSetKey(
const NameValuePairs ¶ms,
const byte *key,
size_t length)
417 CRYPTOPP_UNUSED(length);
432 if (params.
GetValue(
"InitialBlock", block))
433 m_counter = static_cast<word32>(block);
439 get(m_state[KEY+0])(m_state[KEY+1])(m_state[KEY+2])(m_state[KEY+3])
440 (m_state[KEY+4])(m_state[KEY+5])(m_state[KEY+6])(m_state[KEY+7]);
443 void ChaChaTLS_Policy::CipherResynchronize(byte *keystreamBuffer,
const byte *
IV,
size_t length)
445 CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length);
449 m_state[0] = 0x61707865; m_state[1] = 0x3320646e;
450 m_state[2] = 0x79622d32; m_state[3] = 0x6b206574;
453 std::memcpy(m_state+4, m_state+KEY, 8*
sizeof(word32));
457 m_state[12] = m_counter;
458 get(m_state[13])(m_state[14])(m_state[15]);
461 void ChaChaTLS_Policy::SeekToIteration(lword iterationCount)
468 m_state[12] = (word32)iterationCount;
471 unsigned int ChaChaTLS_Policy::GetAlignment()
const 473 return ChaCha_GetAlignment();
476 unsigned int ChaChaTLS_Policy::GetOptimalBlockSize()
const 478 return ChaCha_GetOptimalBlockSize();
482 byte *output,
const byte *input,
size_t iterationCount)
485 ChaCha_OperateKeystream(operation, m_state, m_state[12], discard,
486 ROUNDS, output, input, iterationCount);
500 std::string XChaCha20_Policy::AlgorithmName()
const 502 return std::string(
"XChaCha20");
505 std::string XChaCha20_Policy::AlgorithmProvider()
const 507 return ChaCha_AlgorithmProvider();
510 void XChaCha20_Policy::CipherSetKey(
const NameValuePairs ¶ms,
const byte *key,
size_t length)
513 CRYPTOPP_UNUSED(length);
517 if (rounds != 20 && rounds != 12)
524 if (params.
GetValue(
"InitialBlock", block))
525 m_counter = static_cast<word32>(block);
531 get(m_state[KEY+0])(m_state[KEY+1])(m_state[KEY+2])(m_state[KEY+3])
532 (m_state[KEY+4])(m_state[KEY+5])(m_state[KEY+6])(m_state[KEY+7]);
535 void XChaCha20_Policy::CipherResynchronize(byte *keystreamBuffer,
const byte *iv,
size_t length)
537 CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length);
541 m_state[0] = 0x61707865; m_state[1] = 0x3320646e;
542 m_state[2] = 0x79622d32; m_state[3] = 0x6b206574;
545 std::memcpy(m_state+4, m_state+KEY, 8*
sizeof(word32));
548 get(m_state[12])(m_state[13])(m_state[14])(m_state[15]);
553 HChaCha_OperateKeystream(m_state, m_state+4);
556 m_state[0] = 0x61707865; m_state[1] = 0x3320646e;
557 m_state[2] = 0x79622d32; m_state[3] = 0x6b206574;
560 m_state[12] = m_counter;
566 void XChaCha20_Policy::SeekToIteration(lword iterationCount)
573 unsigned int XChaCha20_Policy::GetAlignment()
const 575 return ChaCha_GetAlignment();
578 unsigned int XChaCha20_Policy::GetOptimalBlockSize()
const 580 return ChaCha_GetOptimalBlockSize();
584 byte *output,
const byte *input,
size_t iterationCount)
586 ChaCha_OperateKeystream(operation, m_state, m_state[12], m_state[13],
587 m_rounds, output, input, iterationCount);
static const char * StaticAlgorithmName()
The algorithm name.
int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
Standard names for retrieving values by name when working with NameValuePairs.
static const char * StaticAlgorithmName()
The algorithm name.
bool HasAltivec()
Determine if a PowerPC processor has Altivec available.
Utility functions for the Crypto++ library.
bool HasAVX2()
Determines AVX2 availability.
Library configuration file.
#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y)
Helper macro to implement OperateKeystream.
byte order is little-endian
Exception thrown when an invalid number of rounds is encountered.
bool HasPower8()
Determine if a PowerPC processor has Power8 available.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Functions for CPU features and intrinsics.
const char * IV()
ConstByteArrayParameter, also accepts const byte * for backwards compatibility.
bool HasSSE2()
Determines SSE2 availability.
Access a block of memory.
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
KeystreamOperation
Keystream operation flags.
Crypto++ library namespace.
bool GetValue(const char *name, T &value) const
Get a named value.
SymmetricCipher implementation.
Classes for ChaCha8, ChaCha12 and ChaCha20 stream ciphers.
bool HasNEON()
Determine if an ARM processor has Advanced SIMD available.
Interface for retrieving values given their names.