Crypto++ 8.2
Free C&
chacha.cpp
1// chacha.cpp - written and placed in the public domain by Jeffrey Walton.
2// Based on Wei Dai's Salsa20, Botan's SSE2 implementation,
3// and Bernstein's reference ChaCha family implementation at
4// http://cr.yp.to/chacha.html.
5
6#include "pch.h"
7#include "config.h"
8#include "chacha.h"
9#include "argnames.h"
10#include "misc.h"
11#include "cpu.h"
12
13// Internal compiler error in GCC 3.3 and below
14#if defined(__GNUC__) && (__GNUC__ < 4)
15# undef CRYPTOPP_SSE2_INTRIN_AVAILABLE
16#endif
17
18NAMESPACE_BEGIN(CryptoPP)
19
20#if (CRYPTOPP_ARM_NEON_AVAILABLE)
21extern void ChaCha_OperateKeystream_NEON(const word32 *state, const byte* input, byte *output, unsigned int rounds);
22#endif
23
24#if (CRYPTOPP_AVX2_AVAILABLE)
25extern void ChaCha_OperateKeystream_AVX2(const word32 *state, const byte* input, byte *output, unsigned int rounds);
26#endif
27#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE)
28extern void ChaCha_OperateKeystream_SSE2(const word32 *state, const byte* input, byte *output, unsigned int rounds);
29#endif
30
31#if (CRYPTOPP_POWER8_AVAILABLE)
32extern void ChaCha_OperateKeystream_POWER8(const word32 *state, const byte* input, byte *output, unsigned int rounds);
33#elif (CRYPTOPP_ALTIVEC_AVAILABLE)
34extern void ChaCha_OperateKeystream_ALTIVEC(const word32 *state, const byte* input, byte *output, unsigned int rounds);
35#endif
36
37#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
38void ChaCha_TestInstantiations()
39{
43}
44#endif
45
46NAMESPACE_END // CryptoPP
47
48////////////////////////////// ChaCha Core //////////////////////////////
49
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);
55
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]);}
73
74ANONYMOUS_NAMESPACE_BEGIN
75
76// Hacks... Bring in all symbols, and supply
77// the stuff the templates normally provide.
78using namespace CryptoPP;
79typedef word32 WordType;
80enum {BYTES_PER_ITERATION=64};
81
82// MultiBlockSafe detects a condition that can arise in the SIMD
83// implementations where we overflow one of the 32-bit state words during
84// addition in an intermediate result. Preconditions for the issue include
85// a user seeks to around 2^32 blocks (256 GB of data) for ChaCha; or a
86// user specifies an arbitrarily large initial counter block for ChaChaTLS.
87// Also see https://github.com/weidai11/cryptopp/issues/732.
88inline bool MultiBlockSafe(unsigned int ctrLow, unsigned int blocks)
89{
90 return 0xffffffff - ctrLow > blocks;
91}
92
93// OperateKeystream always produces a key stream. The key stream is written
94// to output. Optionally a message may be supplied to xor with the key stream.
95// The message is input, and output = output ^ input.
96void ChaCha_OperateKeystream(KeystreamOperation operation,
97 word32 state[16], word32& ctrLow, word32& ctrHigh, word32 rounds,
98 byte *output, const byte *input, size_t iterationCount)
99{
100 do
101 {
102#if (CRYPTOPP_AVX2_AVAILABLE)
103 if (HasAVX2())
104 {
105 while (iterationCount >= 8 && MultiBlockSafe(state[12], 8))
106 {
107 const bool xorInput = (operation & INPUT_NULL) != INPUT_NULL;
108 ChaCha_OperateKeystream_AVX2(state, xorInput ? input : NULLPTR, output, rounds);
109
110 // MultiBlockSafe avoids overflow on the counter words
111 state[12] += 8;
112
113 input += (!!xorInput) * 8 * BYTES_PER_ITERATION;
114 output += 8 * BYTES_PER_ITERATION;
115 iterationCount -= 8;
116 }
117 }
118#endif
119
120#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE)
121 if (HasSSE2())
122 {
123 while (iterationCount >= 4 && MultiBlockSafe(state[12], 4))
124 {
125 const bool xorInput = (operation & INPUT_NULL) != INPUT_NULL;
126 ChaCha_OperateKeystream_SSE2(state, xorInput ? input : NULLPTR, output, rounds);
127
128 // MultiBlockSafe avoids overflow on the counter words
129 state[12] += 4;
130
131 input += (!!xorInput)*4*BYTES_PER_ITERATION;
132 output += 4*BYTES_PER_ITERATION;
133 iterationCount -= 4;
134 }
135 }
136#endif
137
138#if (CRYPTOPP_ARM_NEON_AVAILABLE)
139 if (HasNEON())
140 {
141 while (iterationCount >= 4 && MultiBlockSafe(state[12], 4))
142 {
143 const bool xorInput = (operation & INPUT_NULL) != INPUT_NULL;
144 ChaCha_OperateKeystream_NEON(state, xorInput ? input : NULLPTR, output, rounds);
145
146 // MultiBlockSafe avoids overflow on the counter words
147 state[12] += 4;
148
149 input += (!!xorInput)*4*BYTES_PER_ITERATION;
150 output += 4*BYTES_PER_ITERATION;
151 iterationCount -= 4;
152 }
153 }
154#endif
155
156#if (CRYPTOPP_POWER8_AVAILABLE)
157 if (HasPower8())
158 {
159 while (iterationCount >= 4 && MultiBlockSafe(state[12], 4))
160 {
161 const bool xorInput = (operation & INPUT_NULL) != INPUT_NULL;
162 ChaCha_OperateKeystream_POWER8(state, xorInput ? input : NULLPTR, output, rounds);
163
164 // MultiBlockSafe avoids overflow on the counter words
165 state[12] += 4;
166
167 input += (!!xorInput)*4*BYTES_PER_ITERATION;
168 output += 4*BYTES_PER_ITERATION;
169 iterationCount -= 4;
170 }
171 }
172#elif (CRYPTOPP_ALTIVEC_AVAILABLE)
173 if (HasAltivec())
174 {
175 while (iterationCount >= 4 && MultiBlockSafe(state[12], 4))
176 {
177 const bool xorInput = (operation & INPUT_NULL) != INPUT_NULL;
178 ChaCha_OperateKeystream_ALTIVEC(state, xorInput ? input : NULLPTR, output, rounds);
179
180 // MultiBlockSafe avoids overflow on the counter words
181 state[12] += 4;
182
183 input += (!!xorInput)*4*BYTES_PER_ITERATION;
184 output += 4*BYTES_PER_ITERATION;
185 iterationCount -= 4;
186 }
187 }
188#endif
189
190 if (iterationCount)
191 {
192 word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
193
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];
198
199 for (int i = static_cast<int>(rounds); i > 0; i -= 2)
200 {
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);
205
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);
210 }
211
212 CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(CHACHA_OUTPUT, BYTES_PER_ITERATION);
213
214 // This is state[12] and state[13] from ChaCha. In the case of
215 // ChaChaTLS ctrHigh is a reference to a discard value.
216 if (++ctrLow == 0)
217 ctrHigh++;
218 }
219
220 // We may re-enter a SIMD keystream operation from here.
221 } while (iterationCount--);
222}
223
224// XChaCha key derivation
225void HChaCha_OperateKeystream(const word32 state[16], word32 output[8])
226{
227 word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
228
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];
233
234 for (int i = 20; i > 0; i -= 2)
235 {
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);
240
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);
245 }
246
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;
251}
252
253std::string ChaCha_AlgorithmProvider()
254{
255#if (CRYPTOPP_AVX2_AVAILABLE)
256 if (HasAVX2())
257 return "AVX2";
258 else
259#endif
260#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE)
261 if (HasSSE2())
262 return "SSE2";
263 else
264#endif
265#if (CRYPTOPP_ARM_NEON_AVAILABLE)
266 if (HasNEON())
267 return "NEON";
268 else
269#endif
270#if (CRYPTOPP_POWER8_AVAILABLE)
271 if (HasPower8())
272 return "Power8";
273 else
274#elif (CRYPTOPP_ALTIVEC_AVAILABLE)
275 if (HasAltivec())
276 return "Altivec";
277 else
278#endif
279 return "C++";
280}
281
282unsigned int ChaCha_GetAlignment()
283{
284#if (CRYPTOPP_AVX2_AVAILABLE)
285 if (HasAVX2())
286 return 16;
287 else
288#endif
289#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE)
290 if (HasSSE2())
291 return 16;
292 else
293#endif
294#if (CRYPTOPP_ALTIVEC_AVAILABLE)
295 if (HasAltivec())
296 return 16;
297 else
298#endif
299 return GetAlignmentOf<word32>();
300}
301
302unsigned int ChaCha_GetOptimalBlockSize()
303{
304#if (CRYPTOPP_AVX2_AVAILABLE)
305 if (HasAVX2())
306 return 8 * BYTES_PER_ITERATION;
307 else
308#endif
309#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE)
310 if (HasSSE2())
311 return 4*BYTES_PER_ITERATION;
312 else
313#endif
314#if (CRYPTOPP_ARM_NEON_AVAILABLE)
315 if (HasNEON())
316 return 4*BYTES_PER_ITERATION;
317 else
318#endif
319#if (CRYPTOPP_ALTIVEC_AVAILABLE)
320 if (HasAltivec())
321 return 4*BYTES_PER_ITERATION;
322 else
323#endif
324 return BYTES_PER_ITERATION;
325}
326
327ANONYMOUS_NAMESPACE_END
328
329NAMESPACE_BEGIN(CryptoPP)
330
331////////////////////////////// Bernstein ChaCha //////////////////////////////
332
333std::string ChaCha_Policy::AlgorithmName() const
334{
335 return std::string("ChaCha")+IntToString(m_rounds);
336}
337
338std::string ChaCha_Policy::AlgorithmProvider() const
339{
340 return ChaCha_AlgorithmProvider();
341}
342
343void ChaCha_Policy::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
344{
345 CRYPTOPP_ASSERT(key); CRYPTOPP_ASSERT(length == 16 || length == 32);
346 CRYPTOPP_UNUSED(key); CRYPTOPP_UNUSED(length);
347
348 // Use previous rounds as the default value
349 int rounds = params.GetIntValueWithDefault(Name::Rounds(), m_rounds);
350 if (rounds != 20 && rounds != 12 && rounds != 8)
352
353 // Latch a good value
354 m_rounds = rounds;
355
356 // "expand 16-byte k" or "expand 32-byte k"
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;
361
363 get1(m_state[4])(m_state[5])(m_state[6])(m_state[7]);
364
365 GetBlock<word32, LittleEndian> get2(key + ((length == 32) ? 16 : 0));
366 get2(m_state[8])(m_state[9])(m_state[10])(m_state[11]);
367}
368
369void ChaCha_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length)
370{
371 CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length);
372 CRYPTOPP_ASSERT(length==8); CRYPTOPP_UNUSED(length);
373
375 m_state[12] = m_state[13] = 0;
376 get(m_state[14])(m_state[15]);
377}
378
379void ChaCha_Policy::SeekToIteration(lword iterationCount)
380{
381 m_state[12] = (word32)iterationCount; // low word
382 m_state[13] = (word32)SafeRightShift<32>(iterationCount);
383}
384
385unsigned int ChaCha_Policy::GetAlignment() const
386{
387 return ChaCha_GetAlignment();
388}
389
390unsigned int ChaCha_Policy::GetOptimalBlockSize() const
391{
392 return ChaCha_GetOptimalBlockSize();
393}
394
395void ChaCha_Policy::OperateKeystream(KeystreamOperation operation,
396 byte *output, const byte *input, size_t iterationCount)
397{
398 ChaCha_OperateKeystream(operation, m_state, m_state[12], m_state[13],
399 m_rounds, output, input, iterationCount);
400}
401
402////////////////////////////// IETF ChaChaTLS //////////////////////////////
403
404std::string ChaChaTLS_Policy::AlgorithmName() const
405{
406 return std::string("ChaChaTLS");
407}
408
409std::string ChaChaTLS_Policy::AlgorithmProvider() const
410{
411 return ChaCha_AlgorithmProvider();
412}
413
414void ChaChaTLS_Policy::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
415{
416 CRYPTOPP_ASSERT(key); CRYPTOPP_ASSERT(length == 32);
417 CRYPTOPP_UNUSED(length);
418
419 // ChaChaTLS is always 20 rounds. Fetch Rounds() to avoid a spurious failure.
420 int rounds = params.GetIntValueWithDefault(Name::Rounds(), ROUNDS);
421 if (rounds != 20)
423
424 // RFC 8439 test vectors use an initial block counter. However, the counter
425 // can be an arbitrary value per RFC 8439 Section 2.4. We stash the counter
426 // away in state[16] and use it for a Resynchronize() operation. I think
427 // the initial counter is used more like a Tweak when non-0, and it should
428 // be provided in Resynchronize() (light-weight re-keying). However,
429 // Resynchronize() does not have an overload that allows us to pass it into
430 // the function, so we have to use the heavier-weight SetKey to change it.
431 word64 block;
432 if (params.GetValue("InitialBlock", block))
433 m_counter = static_cast<word32>(block);
434 else
435 m_counter = 0;
436
437 // State words are defined in RFC 8439, Section 2.3. Key is 32-bytes.
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]);
441}
442
443void ChaChaTLS_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length)
444{
445 CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length);
446 CRYPTOPP_ASSERT(length==12);
447
448 // State words are defined in RFC 8439, Section 2.3.
449 m_state[0] = 0x61707865; m_state[1] = 0x3320646e;
450 m_state[2] = 0x79622d32; m_state[3] = 0x6b206574;
451
452 // Copy saved key into state
453 std::memcpy(m_state+4, m_state+KEY, 8*sizeof(word32));
454
455 // State words are defined in RFC 8439, Section 2.3
457 m_state[12] = m_counter;
458 get(m_state[13])(m_state[14])(m_state[15]);
459}
460
461void ChaChaTLS_Policy::SeekToIteration(lword iterationCount)
462{
463 // Should we throw here??? If the initial block counter is
464 // large then we can wrap and process more data as long as
465 // data processed in the security context does not exceed
466 // 2^32 blocks or approximately 256 GB of data.
467 CRYPTOPP_ASSERT(iterationCount <= std::numeric_limits<word32>::max());
468 m_state[12] = (word32)iterationCount; // low word
469}
470
471unsigned int ChaChaTLS_Policy::GetAlignment() const
472{
473 return ChaCha_GetAlignment();
474}
475
476unsigned int ChaChaTLS_Policy::GetOptimalBlockSize() const
477{
478 return ChaCha_GetOptimalBlockSize();
479}
480
481void ChaChaTLS_Policy::OperateKeystream(KeystreamOperation operation,
482 byte *output, const byte *input, size_t iterationCount)
483{
484 word32 discard=0;
485 ChaCha_OperateKeystream(operation, m_state, m_state[12], discard,
486 ROUNDS, output, input, iterationCount);
487
488 // If this fires it means ChaCha_OperateKeystream generated a counter
489 // block carry that was discarded. The problem is, the RFC does not
490 // specify what should happen when the counter block wraps. All we can
491 // do is inform the user that something bad may happen because we don't
492 // know what we should do.
493 // Also see https://github.com/weidai11/cryptopp/issues/790 and
494 // https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU
495 // CRYPTOPP_ASSERT(discard==0);
496}
497
498////////////////////////////// IETF XChaCha20 //////////////////////////////
499
500std::string XChaCha20_Policy::AlgorithmName() const
501{
502 return std::string("XChaCha20");
503}
504
505std::string XChaCha20_Policy::AlgorithmProvider() const
506{
507 return ChaCha_AlgorithmProvider();
508}
509
510void XChaCha20_Policy::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
511{
512 CRYPTOPP_ASSERT(key); CRYPTOPP_ASSERT(length == 32);
513 CRYPTOPP_UNUSED(length);
514
515 // Use previous rounds as the default value
516 int rounds = params.GetIntValueWithDefault(Name::Rounds(), m_rounds);
517 if (rounds != 20 && rounds != 12)
519
520 // Latch a good value
521 m_rounds = rounds;
522
523 word64 block;
524 if (params.GetValue("InitialBlock", block))
525 m_counter = static_cast<word32>(block);
526 else
527 m_counter = 1;
528
529 // Stash key away for use in CipherResynchronize
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]);
533}
534
535void XChaCha20_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
536{
537 CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length);
538 CRYPTOPP_ASSERT(length==24);
539
540 // HChaCha derivation
541 m_state[0] = 0x61707865; m_state[1] = 0x3320646e;
542 m_state[2] = 0x79622d32; m_state[3] = 0x6b206574;
543
544 // Copy saved key into state
545 std::memcpy(m_state+4, m_state+KEY, 8*sizeof(word32));
546
548 get(m_state[12])(m_state[13])(m_state[14])(m_state[15]);
549
550 // Operate the keystream without adding state back in.
551 // This function also gathers the key words into a
552 // contiguous 8-word block.
553 HChaCha_OperateKeystream(m_state, m_state+4);
554
555 // XChaCha state
556 m_state[0] = 0x61707865; m_state[1] = 0x3320646e;
557 m_state[2] = 0x79622d32; m_state[3] = 0x6b206574;
558
559 // Setup new IV
560 m_state[12] = m_counter;
561 m_state[13] = 0;
562 m_state[14] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, iv+16);
563 m_state[15] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, iv+20);
564}
565
566void XChaCha20_Policy::SeekToIteration(lword iterationCount)
567{
568 // Should we throw here??? XChaCha does not have a block
569 // counter, so I'm not sure how to seek on it.
570 CRYPTOPP_ASSERT(0); CRYPTOPP_UNUSED(iterationCount);
571}
572
573unsigned int XChaCha20_Policy::GetAlignment() const
574{
575 return ChaCha_GetAlignment();
576}
577
578unsigned int XChaCha20_Policy::GetOptimalBlockSize() const
579{
580 return ChaCha_GetOptimalBlockSize();
581}
582
583void XChaCha20_Policy::OperateKeystream(KeystreamOperation operation,
584 byte *output, const byte *input, size_t iterationCount)
585{
586 ChaCha_OperateKeystream(operation, m_state, m_state[12], m_state[13],
587 m_rounds, output, input, iterationCount);
588}
589
590NAMESPACE_END
Standard names for retrieving values by name when working with NameValuePairs.
Classes for ChaCha8, ChaCha12 and ChaCha20 stream ciphers.
Access a block of memory.
Definition: misc.h:2455
Exception thrown when an invalid number of rounds is encountered.
Definition: simple.h:60
Interface for retrieving values given their names.
Definition: cryptlib.h:294
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:350
int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
Definition: cryptlib.h:395
SymmetricCipher implementation.
Definition: strciphr.h:674
Library configuration file.
Functions for CPU features and intrinsics.
bool HasAltivec()
Determine if a PowerPC processor has Altivec available.
Definition: cpu.h:614
bool HasNEON()
Determine if an ARM processor has Advanced SIMD available.
Definition: cpu.h:387
bool HasPower8()
Determine if a PowerPC processor has Power8 available.
Definition: cpu.h:640
bool HasSSE2()
Determines SSE2 availability.
Definition: cpu.h:116
bool HasAVX2()
Determines AVX2 availability.
Definition: cpu.h:225
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Definition: cryptlib.h:145
Utility functions for the Crypto++ library.
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition: misc.h:636
Crypto++ library namespace.
const char * Rounds()
int
Definition: argnames.h:24
Precompiled header file.
#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y)
Helper macro to implement OperateKeystream.
Definition: strciphr.h:268
KeystreamOperation
Keystream operation flags.
Definition: strciphr.h:88
@ INPUT_NULL
Input buffer is NULL.
Definition: strciphr.h:82
static const char * StaticAlgorithmName()
The algorithm name.
Definition: chacha.h:50
static const char * StaticAlgorithmName()
The algorithm name.
Definition: chacha.h:107
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:69