14#if defined(__GNUC__) && (__GNUC__ < 4) 
   15# undef CRYPTOPP_SSE2_INTRIN_AVAILABLE 
   20#if (CRYPTOPP_ARM_NEON_AVAILABLE) 
   21extern void ChaCha_OperateKeystream_NEON(
const word32 *state, 
const byte* input, 
byte *output, 
unsigned int rounds);
 
   24#if (CRYPTOPP_AVX2_AVAILABLE) 
   25extern void ChaCha_OperateKeystream_AVX2(
const word32 *state, 
const byte* input, 
byte *output, 
unsigned int rounds);
 
   27#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) 
   28extern void ChaCha_OperateKeystream_SSE2(
const word32 *state, 
const byte* input, 
byte *output, 
unsigned int rounds);
 
   31#if (CRYPTOPP_ALTIVEC_AVAILABLE) 
   32extern void ChaCha_OperateKeystream_ALTIVEC(
const word32 *state, 
const byte* input, 
byte *output, 
unsigned int rounds);
 
   35#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) 
   36void ChaCha_TestInstantiations()
 
   48#define CHACHA_QUARTER_ROUND(a,b,c,d) \ 
   49    a += b; d ^= a; d = rotlConstant<16,word32>(d); \ 
   50    c += d; b ^= c; b = rotlConstant<12,word32>(b); \ 
   51    a += b; d ^= a; d = rotlConstant<8,word32>(d); \ 
   52    c += d; b ^= c; b = rotlConstant<7,word32>(b); 
   54#define CHACHA_OUTPUT(x){\ 
   55    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 0, x0 + state[0]);\ 
   56    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 1, x1 + state[1]);\ 
   57    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 2, x2 + state[2]);\ 
   58    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 3, x3 + state[3]);\ 
   59    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 4, x4 + state[4]);\ 
   60    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 5, x5 + state[5]);\ 
   61    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 6, x6 + state[6]);\ 
   62    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 7, x7 + state[7]);\ 
   63    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 8, x8 + state[8]);\ 
   64    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 9, x9 + state[9]);\ 
   65    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 10, x10 + state[10]);\ 
   66    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 11, x11 + state[11]);\ 
   67    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 12, x12 + state[12]);\ 
   68    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 13, x13 + state[13]);\ 
   69    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 14, x14 + state[14]);\ 
   70    CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 15, x15 + state[15]);} 
   72ANONYMOUS_NAMESPACE_BEGIN
 
   78enum {BYTES_PER_ITERATION=64};
 
   86inline bool MultiBlockSafe(
unsigned int ctrLow, 
unsigned int blocks)
 
   88    return 0xffffffff - ctrLow > blocks;
 
   96        byte *output, 
const byte *input, 
size_t iterationCount)
 
  100#if (CRYPTOPP_AVX2_AVAILABLE) 
  103            while (iterationCount >= 8 && MultiBlockSafe(state[12], 8))
 
  106                ChaCha_OperateKeystream_AVX2(state, xorInput ? input : NULLPTR, output, rounds);
 
  111                input += (!!xorInput) * 8 * BYTES_PER_ITERATION;
 
  112                output += 8 * BYTES_PER_ITERATION;
 
  118#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) 
  121            while (iterationCount >= 4 && MultiBlockSafe(state[12], 4))
 
  124                ChaCha_OperateKeystream_SSE2(state, xorInput ? input : NULLPTR, output, rounds);
 
  129                input += (!!xorInput)*4*BYTES_PER_ITERATION;
 
  130                output += 4*BYTES_PER_ITERATION;
 
  136#if (CRYPTOPP_ARM_NEON_AVAILABLE) 
  139            while (iterationCount >= 4 && MultiBlockSafe(state[12], 4))
 
  142                ChaCha_OperateKeystream_NEON(state, xorInput ? input : NULLPTR, output, rounds);
 
  147                input += (!!xorInput)*4*BYTES_PER_ITERATION;
 
  148                output += 4*BYTES_PER_ITERATION;
 
  154#if (CRYPTOPP_ALTIVEC_AVAILABLE) 
  157            while (iterationCount >= 4 && MultiBlockSafe(state[12], 4))
 
  160                ChaCha_OperateKeystream_ALTIVEC(state, xorInput ? input : NULLPTR, output, rounds);
 
  165                input += (!!xorInput)*4*BYTES_PER_ITERATION;
 
  166                output += 4*BYTES_PER_ITERATION;
 
  174            word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
 
  176            x0 = state[0];    x1 = state[1];    x2 = state[2];    x3 = state[3];
 
  177            x4 = state[4];    x5 = state[5];    x6 = state[6];    x7 = state[7];
 
  178            x8 = state[8];    x9 = state[9];    x10 = state[10];  x11 = state[11];
 
  179            x12 = state[12];  x13 = state[13];  x14 = state[14];  x15 = state[15];
 
  181            for (
int i = 
static_cast<int>(rounds); i > 0; i -= 2)
 
  183                CHACHA_QUARTER_ROUND(x0, x4,  x8, x12);
 
  184                CHACHA_QUARTER_ROUND(x1, x5,  x9, x13);
 
  185                CHACHA_QUARTER_ROUND(x2, x6, x10, x14);
 
  186                CHACHA_QUARTER_ROUND(x3, x7, x11, x15);
 
  188                CHACHA_QUARTER_ROUND(x0, x5, x10, x15);
 
  189                CHACHA_QUARTER_ROUND(x1, x6, x11, x12);
 
  190                CHACHA_QUARTER_ROUND(x2, x7,  x8, x13);
 
  191                CHACHA_QUARTER_ROUND(x3, x4,  x9, x14);
 
  203    } 
while (iterationCount--);
 
  207void HChaCha_OperateKeystream(
const word32 state[16], 
word32 output[8])
 
  209    word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
 
  211    x0 = state[0];    x1 = state[1];    x2 = state[2];    x3 = state[3];
 
  212    x4 = state[4];    x5 = state[5];    x6 = state[6];    x7 = state[7];
 
  213    x8 = state[8];    x9 = state[9];    x10 = state[10];  x11 = state[11];
 
  214    x12 = state[12];  x13 = state[13];  x14 = state[14];  x15 = state[15];
 
  216    for (
int i = 20; i > 0; i -= 2)
 
  218        CHACHA_QUARTER_ROUND(x0, x4,  x8, x12);
 
  219        CHACHA_QUARTER_ROUND(x1, x5,  x9, x13);
 
  220        CHACHA_QUARTER_ROUND(x2, x6, x10, x14);
 
  221        CHACHA_QUARTER_ROUND(x3, x7, x11, x15);
 
  223        CHACHA_QUARTER_ROUND(x0, x5, x10, x15);
 
  224        CHACHA_QUARTER_ROUND(x1, x6, x11, x12);
 
  225        CHACHA_QUARTER_ROUND(x2, x7,  x8, x13);
 
  226        CHACHA_QUARTER_ROUND(x3, x4,  x9, x14);
 
  229    output[0] =  x0; output[1] =  x1;
 
  230    output[2] =  x2; output[3] =  x3;
 
  231    output[4] = x12; output[5] = x13;
 
  232    output[6] = x14; output[7] = x15;
 
  235std::string ChaCha_AlgorithmProvider()
 
  237#if (CRYPTOPP_AVX2_AVAILABLE) 
  242#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) 
  247#if (CRYPTOPP_ARM_NEON_AVAILABLE) 
  252#if (CRYPTOPP_ALTIVEC_AVAILABLE) 
  260unsigned int ChaCha_GetAlignment()
 
  262#if (CRYPTOPP_AVX2_AVAILABLE) 
  267#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) 
  272#if (CRYPTOPP_ALTIVEC_AVAILABLE) 
  277        return GetAlignmentOf<word32>();
 
  280unsigned int ChaCha_GetOptimalBlockSize()
 
  282#if (CRYPTOPP_AVX2_AVAILABLE) 
  284        return 8 * BYTES_PER_ITERATION;
 
  287#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) 
  289        return 4*BYTES_PER_ITERATION;
 
  292#if (CRYPTOPP_ARM_NEON_AVAILABLE) 
  294        return 4*BYTES_PER_ITERATION;
 
  297#if (CRYPTOPP_ALTIVEC_AVAILABLE) 
  299        return 4*BYTES_PER_ITERATION;
 
  302        return BYTES_PER_ITERATION;
 
  305ANONYMOUS_NAMESPACE_END
 
  311std::string ChaCha_Policy::AlgorithmName()
 const 
  313    return std::string(
"ChaCha")+
IntToString(m_rounds);
 
  316std::string ChaCha_Policy::AlgorithmProvider()
 const 
  318    return ChaCha_AlgorithmProvider();
 
  321void ChaCha_Policy::CipherSetKey(
const NameValuePairs ¶ms, 
const byte *key, 
size_t length)
 
  324    CRYPTOPP_UNUSED(key); CRYPTOPP_UNUSED(length);
 
  328    if (rounds != 20 && rounds != 12 && rounds != 8)
 
  335    m_state[0] = 0x61707865;
 
  336    m_state[1] = (length == 16) ? 0x3120646e : 0x3320646e;
 
  337    m_state[2] = (length == 16) ? 0x79622d36 : 0x79622d32;
 
  338    m_state[3] = 0x6b206574;
 
  341    get1(m_state[4])(m_state[5])(m_state[6])(m_state[7]);
 
  344    get2(m_state[8])(m_state[9])(m_state[10])(m_state[11]);
 
  347void ChaCha_Policy::CipherResynchronize(
byte *keystreamBuffer, 
const byte *IV, 
size_t length)
 
  349    CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length);
 
  353    m_state[12] = m_state[13] = 0;
 
  354    get(m_state[14])(m_state[15]);
 
  357void ChaCha_Policy::SeekToIteration(
lword iterationCount)
 
  359    m_state[12] = (
word32)iterationCount;  
 
  360    m_state[13] = (
word32)SafeRightShift<32>(iterationCount);
 
  363unsigned int ChaCha_Policy::GetAlignment()
 const 
  365    return ChaCha_GetAlignment();
 
  368unsigned int ChaCha_Policy::GetOptimalBlockSize()
 const 
  370    return ChaCha_GetOptimalBlockSize();
 
  374        byte *output, 
const byte *input, 
size_t iterationCount)
 
  376    ChaCha_OperateKeystream(operation, m_state, m_state[12], m_state[13],
 
  377        m_rounds, output, input, iterationCount);
 
  382std::string ChaChaTLS_Policy::AlgorithmName()
 const 
  384    return std::string(
"ChaChaTLS");
 
  387std::string ChaChaTLS_Policy::AlgorithmProvider()
 const 
  389    return ChaCha_AlgorithmProvider();
 
  392void ChaChaTLS_Policy::CipherSetKey(
const NameValuePairs ¶ms, 
const byte *key, 
size_t length)
 
  395    CRYPTOPP_UNUSED(length);
 
  410    if (params.
GetValue(
"InitialBlock", block))
 
  411        m_counter = 
static_cast<word32>(block);
 
  417    get(m_state[KEY+0])(m_state[KEY+1])(m_state[KEY+2])(m_state[KEY+3])
 
  418        (m_state[KEY+4])(m_state[KEY+5])(m_state[KEY+6])(m_state[KEY+7]);
 
  421void ChaChaTLS_Policy::CipherResynchronize(
byte *keystreamBuffer, 
const byte *IV, 
size_t length)
 
  423    CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length);
 
  427    m_state[0] = 0x61707865; m_state[1] = 0x3320646e;
 
  428    m_state[2] = 0x79622d32; m_state[3] = 0x6b206574;
 
  431    std::memcpy(m_state+4, m_state+KEY, 8*
sizeof(
word32));
 
  435    m_state[12] = m_counter;
 
  436    get(m_state[13])(m_state[14])(m_state[15]);
 
  439void ChaChaTLS_Policy::SeekToIteration(
lword iterationCount)
 
  445    CRYPTOPP_ASSERT(iterationCount <= (std::numeric_limits<word32>::max)());
 
  446    m_state[12] = (
word32)iterationCount;  
 
  449unsigned int ChaChaTLS_Policy::GetAlignment()
 const 
  451    return ChaCha_GetAlignment();
 
  454unsigned int ChaChaTLS_Policy::GetOptimalBlockSize()
 const 
  456    return ChaCha_GetOptimalBlockSize();
 
  460        byte *output, 
const byte *input, 
size_t iterationCount)
 
  463    ChaCha_OperateKeystream(operation, m_state, m_state[12], discard,
 
  464            ROUNDS, output, input, iterationCount);
 
  478std::string XChaCha20_Policy::AlgorithmName()
 const 
  480    return std::string(
"XChaCha20");
 
  483std::string XChaCha20_Policy::AlgorithmProvider()
 const 
  485    return ChaCha_AlgorithmProvider();
 
  488void XChaCha20_Policy::CipherSetKey(
const NameValuePairs ¶ms, 
const byte *key, 
size_t length)
 
  491    CRYPTOPP_UNUSED(length);
 
  495    if (rounds != 20 && rounds != 12)
 
  502    if (params.
GetValue(
"InitialBlock", block))
 
  503        m_counter = 
static_cast<word32>(block);
 
  509    get(m_state[KEY+0])(m_state[KEY+1])(m_state[KEY+2])(m_state[KEY+3])
 
  510        (m_state[KEY+4])(m_state[KEY+5])(m_state[KEY+6])(m_state[KEY+7]);
 
  513void XChaCha20_Policy::CipherResynchronize(
byte *keystreamBuffer, 
const byte *iv, 
size_t length)
 
  515    CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length);
 
  519    m_state[0] = 0x61707865; m_state[1] = 0x3320646e;
 
  520    m_state[2] = 0x79622d32; m_state[3] = 0x6b206574;
 
  523    std::memcpy(m_state+4, m_state+KEY, 8*
sizeof(
word32));
 
  526    get(m_state[12])(m_state[13])(m_state[14])(m_state[15]);
 
  531    HChaCha_OperateKeystream(m_state, m_state+4);
 
  534    m_state[0] = 0x61707865; m_state[1] = 0x3320646e;
 
  535    m_state[2] = 0x79622d32; m_state[3] = 0x6b206574;
 
  538    m_state[12] = m_counter;
 
  544void XChaCha20_Policy::SeekToIteration(
lword iterationCount)
 
  551unsigned int XChaCha20_Policy::GetAlignment()
 const 
  553    return ChaCha_GetAlignment();
 
  556unsigned int XChaCha20_Policy::GetOptimalBlockSize()
 const 
  558    return ChaCha_GetOptimalBlockSize();
 
  562        byte *output, 
const byte *input, 
size_t iterationCount)
 
  564    ChaCha_OperateKeystream(operation, m_state, m_state[12], m_state[13],
 
  565            m_rounds, output, input, iterationCount);
 
Standard names for retrieving values by name when working with NameValuePairs.
 
Classes for ChaCha8, ChaCha12 and ChaCha20 stream ciphers.
 
Access a block of memory.
 
Exception thrown when an invalid number of rounds is encountered.
 
Interface for retrieving values given their names.
 
bool GetValue(const char *name, T &value) const
Get a named value.
 
CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
 
SymmetricCipher implementation.
 
Library configuration file.
 
unsigned int word32
32-bit unsigned datatype
 
unsigned long long word64
64-bit unsigned datatype
 
word64 lword
Large word type.
 
Functions for CPU features and intrinsics.
 
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
 
Utility functions for the Crypto++ library.
 
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
 
#define EnumToInt(v)
Integer value.
 
Crypto++ library namespace.
 
#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y)
Helper macro to implement OperateKeystream.
 
KeystreamOperation
Keystream operation flags.
 
@ INPUT_NULL
Input buffer is NULL.
 
static const char * StaticAlgorithmName()
The algorithm name.
 
static const char * StaticAlgorithmName()
The algorithm name.
 
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.