15 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 16 extern void ChaCha_OperateKeystream_NEON(
const word32 *state,
const byte* input, byte *output,
unsigned int rounds);
19 #if (CRYPTOPP_SSE2_INTRIN_AVAILABLE || CRYPTOPP_SSE2_ASM_AVAILABLE) 20 extern void ChaCha_OperateKeystream_SSE2(
const word32 *state,
const byte* input, byte *output,
unsigned int rounds);
23 #if (CRYPTOPP_AVX2_AVAILABLE) 24 extern void ChaCha_OperateKeystream_AVX2(
const word32 *state,
const byte* input, byte *output,
unsigned int rounds);
27 #if (CRYPTOPP_POWER7_AVAILABLE) 28 extern void ChaCha_OperateKeystream_POWER7(
const word32 *state,
const byte* input, byte *output,
unsigned int rounds);
29 #elif (CRYPTOPP_ALTIVEC_AVAILABLE) 30 extern void ChaCha_OperateKeystream_ALTIVEC(
const word32 *state,
const byte* input, byte *output,
unsigned int rounds);
33 #define CHACHA_QUARTER_ROUND(a,b,c,d) \ 34 a += b; d ^= a; d = rotlConstant<16,word32>(d); \ 35 c += d; b ^= c; b = rotlConstant<12,word32>(b); \ 36 a += b; d ^= a; d = rotlConstant<8,word32>(d); \ 37 c += d; b ^= c; b = rotlConstant<7,word32>(b); 39 #define CHACHA_OUTPUT(x){\ 40 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 0, x0 + m_state[0]);\ 41 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 1, x1 + m_state[1]);\ 42 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 2, x2 + m_state[2]);\ 43 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 3, x3 + m_state[3]);\ 44 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 4, x4 + m_state[4]);\ 45 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 5, x5 + m_state[5]);\ 46 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 6, x6 + m_state[6]);\ 47 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 7, x7 + m_state[7]);\ 48 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 8, x8 + m_state[8]);\ 49 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 9, x9 + m_state[9]);\ 50 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 10, x10 + m_state[10]);\ 51 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 11, x11 + m_state[11]);\ 52 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 12, x12 + m_state[12]);\ 53 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 13, x13 + m_state[13]);\ 54 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 14, x14 + m_state[14]);\ 55 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 15, x15 + m_state[15]);} 57 #if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) 58 void ChaCha_TestInstantiations()
64 std::string ChaCha_Policy::AlgorithmName()
const 69 std::string ChaCha_Policy::AlgorithmProvider()
const 71 #if (CRYPTOPP_AVX2_AVAILABLE) 76 #if (CRYPTOPP_SSE2_INTRIN_AVAILABLE || CRYPTOPP_SSE2_ASM_AVAILABLE) 81 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 86 #if (CRYPTOPP_POWER7_AVAILABLE) 90 #elif (CRYPTOPP_ALTIVEC_AVAILABLE) 98 void ChaCha_Policy::CipherSetKey(
const NameValuePairs ¶ms,
const byte *key,
size_t length)
100 CRYPTOPP_UNUSED(params);
104 if (!(m_rounds == 8 || m_rounds == 12 || m_rounds == 20))
108 m_state[0] = 0x61707865;
109 m_state[1] = (length == 16) ? 0x3120646e : 0x3320646e;
110 m_state[2] = (length == 16) ? 0x79622d36 : 0x79622d32;
111 m_state[3] = 0x6b206574;
114 get1(m_state[4])(m_state[5])(m_state[6])(m_state[7]);
117 get2(m_state[8])(m_state[9])(m_state[10])(m_state[11]);
120 void ChaCha_Policy::CipherResynchronize(byte *keystreamBuffer,
const byte *
IV,
size_t length)
122 CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length);
126 m_state[12] = m_state[13] = 0;
127 get(m_state[14])(m_state[15]);
130 void ChaCha_Policy::SeekToIteration(lword iterationCount)
132 m_state[12] = (word32)iterationCount;
133 m_state[13] = (word32)SafeRightShift<32>(iterationCount);
136 unsigned int ChaCha_Policy::GetAlignment()
const 138 #if (CRYPTOPP_AVX2_AVAILABLE) 143 #if (CRYPTOPP_SSE2_INTRIN_AVAILABLE || CRYPTOPP_SSE2_ASM_AVAILABLE) 148 #if (CRYPTOPP_ALTIVEC_AVAILABLE) 153 return GetAlignmentOf<word32>();
156 unsigned int ChaCha_Policy::GetOptimalBlockSize()
const 158 #if (CRYPTOPP_AVX2_AVAILABLE) 160 return 8 * BYTES_PER_ITERATION;
163 #if (CRYPTOPP_SSE2_INTRIN_AVAILABLE || CRYPTOPP_SSE2_ASM_AVAILABLE) 165 return 4*BYTES_PER_ITERATION;
168 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 170 return 4*BYTES_PER_ITERATION;
173 #if (CRYPTOPP_ALTIVEC_AVAILABLE) 175 return 4*BYTES_PER_ITERATION;
178 return BYTES_PER_ITERATION;
181 bool ChaCha_Policy::MultiBlockSafe(
unsigned int blocks)
const 183 return 0xffffffff - m_state[12] > blocks;
190 byte *output,
const byte *input,
size_t iterationCount)
194 #if (CRYPTOPP_AVX2_AVAILABLE) 197 while (iterationCount >= 8 && MultiBlockSafe(8))
200 ChaCha_OperateKeystream_AVX2(m_state, xorInput ? input : NULLPTR, output, m_rounds);
207 input += (!!xorInput) * 8 * BYTES_PER_ITERATION;
208 output += 8 * BYTES_PER_ITERATION;
214 #if (CRYPTOPP_SSE2_INTRIN_AVAILABLE || CRYPTOPP_SSE2_ASM_AVAILABLE) 217 while (iterationCount >= 4 && MultiBlockSafe(4))
220 ChaCha_OperateKeystream_SSE2(m_state, xorInput ? input : NULLPTR, output, m_rounds);
227 input += (!!xorInput)*4*BYTES_PER_ITERATION;
228 output += 4*BYTES_PER_ITERATION;
234 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 237 while (iterationCount >= 4 && MultiBlockSafe(4))
240 ChaCha_OperateKeystream_NEON(m_state, xorInput ? input : NULLPTR, output, m_rounds);
247 input += (!!xorInput)*4*BYTES_PER_ITERATION;
248 output += 4*BYTES_PER_ITERATION;
254 #if (CRYPTOPP_POWER7_AVAILABLE) 257 while (iterationCount >= 4 && MultiBlockSafe(4))
260 ChaCha_OperateKeystream_POWER7(m_state, xorInput ? input : NULLPTR, output, m_rounds);
267 input += (!!xorInput)*4*BYTES_PER_ITERATION;
268 output += 4*BYTES_PER_ITERATION;
272 #elif (CRYPTOPP_ALTIVEC_AVAILABLE) 275 while (iterationCount >= 4 && MultiBlockSafe(4))
278 ChaCha_OperateKeystream_ALTIVEC(m_state, xorInput ? input : NULLPTR, output, m_rounds);
285 input += (!!xorInput)*4*BYTES_PER_ITERATION;
286 output += 4*BYTES_PER_ITERATION;
294 word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
296 x0 = m_state[0]; x1 = m_state[1]; x2 = m_state[2]; x3 = m_state[3];
297 x4 = m_state[4]; x5 = m_state[5]; x6 = m_state[6]; x7 = m_state[7];
298 x8 = m_state[8]; x9 = m_state[9]; x10 = m_state[10]; x11 = m_state[11];
299 x12 = m_state[12]; x13 = m_state[13]; x14 = m_state[14]; x15 = m_state[15];
301 for (
int i = static_cast<int>(m_rounds); i > 0; i -= 2)
303 CHACHA_QUARTER_ROUND(x0, x4, x8, x12);
304 CHACHA_QUARTER_ROUND(x1, x5, x9, x13);
305 CHACHA_QUARTER_ROUND(x2, x6, x10, x14);
306 CHACHA_QUARTER_ROUND(x3, x7, x11, x15);
308 CHACHA_QUARTER_ROUND(x0, x5, x10, x15);
309 CHACHA_QUARTER_ROUND(x1, x6, x11, x12);
310 CHACHA_QUARTER_ROUND(x2, x7, x8, x13);
311 CHACHA_QUARTER_ROUND(x3, x4, x9, x14);
316 if (++m_state[12] == 0)
321 }
while (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.
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.
bool HasPower7()
Determine if a PowerPC processor has Power7 available.
Exception thrown when an invalid number of rounds is encountered.
#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.
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.