mirror of
https://github.com/shadps4-emu/ext-cryptopp.git
synced 2025-02-22 22:30:35 +00:00

These changes made it in by accident at Commit b74a6f444568. We were going to try to let them ride but they broke versioning. They may be added later but we should avoid the change at this time.
152 lines
5.4 KiB
C++
152 lines
5.4 KiB
C++
// chacha.cpp - written and placed in the public domain by Jeffrey Walton.
|
|
// Based on Wei Dai's Salsa20 and Bernstein's reference ChaCha
|
|
// family implementation at http://cr.yp.to/chacha.html.
|
|
|
|
#include "pch.h"
|
|
#include "config.h"
|
|
#include "chacha.h"
|
|
#include "argnames.h"
|
|
#include "misc.h"
|
|
#include "cpu.h"
|
|
|
|
NAMESPACE_BEGIN(CryptoPP)
|
|
|
|
#define CHACHA_QUARTER_ROUND(a,b,c,d) \
|
|
a += b; d ^= a; d = rotlConstant<16,word32>(d); \
|
|
c += d; b ^= c; b = rotlConstant<12,word32>(b); \
|
|
a += b; d ^= a; d = rotlConstant<8,word32>(d); \
|
|
c += d; b ^= c; b = rotlConstant<7,word32>(b);
|
|
|
|
#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
|
|
void ChaCha_TestInstantiations()
|
|
{
|
|
ChaCha8::Encryption x1;
|
|
ChaCha12::Encryption x2;
|
|
ChaCha20::Encryption x3;
|
|
}
|
|
#endif
|
|
|
|
template<unsigned int R>
|
|
void ChaCha_Policy<R>::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length)
|
|
{
|
|
CRYPTOPP_UNUSED(params);
|
|
CRYPTOPP_ASSERT(length == 16 || length == 32);
|
|
|
|
// "expand 16-byte k" or "expand 32-byte k"
|
|
m_state[0] = 0x61707865;
|
|
m_state[1] = (length == 16) ? 0x3120646e : 0x3320646e;
|
|
m_state[2] = (length == 16) ? 0x79622d36 : 0x79622d32;
|
|
m_state[3] = 0x6b206574;
|
|
|
|
GetBlock<word32, LittleEndian> get1(key);
|
|
get1(m_state[4])(m_state[5])(m_state[6])(m_state[7]);
|
|
|
|
GetBlock<word32, LittleEndian> get2(key + ((length == 32) ? 16 : 0));
|
|
get2(m_state[8])(m_state[9])(m_state[10])(m_state[11]);
|
|
}
|
|
|
|
template<unsigned int R>
|
|
void ChaCha_Policy<R>::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length)
|
|
{
|
|
CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length);
|
|
CRYPTOPP_ASSERT(length==8);
|
|
|
|
GetBlock<word32, LittleEndian> get(IV);
|
|
m_state[12] = m_state[13] = 0;
|
|
get(m_state[14])(m_state[15]);
|
|
}
|
|
|
|
template<unsigned int R>
|
|
void ChaCha_Policy<R>::SeekToIteration(lword iterationCount)
|
|
{
|
|
CRYPTOPP_UNUSED(iterationCount);
|
|
throw NotImplemented(std::string(ChaCha_Info<R>::StaticAlgorithmName()) + ": SeekToIteration is not yet implemented");
|
|
|
|
// TODO: these were Salsa20, and Wei re-arranged the state array for SSE2 operations.
|
|
// If we can generate some out-of-band test vectors, then test and implement. Also
|
|
// see the test vectors in salsa.txt and the use of Seek test argument.
|
|
// m_state[8] = (word32)iterationCount;
|
|
// m_state[5] = (word32)SafeRightShift<32>(iterationCount);
|
|
}
|
|
|
|
template<unsigned int R>
|
|
unsigned int ChaCha_Policy<R>::GetAlignment() const
|
|
{
|
|
#if CRYPTOPP_SSE2_ASM_AVAILABLE && 0
|
|
if (HasSSE2())
|
|
return 16;
|
|
else
|
|
#endif
|
|
return GetAlignmentOf<word32>();
|
|
}
|
|
|
|
template<unsigned int R>
|
|
unsigned int ChaCha_Policy<R>::GetOptimalBlockSize() const
|
|
{
|
|
#if CRYPTOPP_SSE2_ASM_AVAILABLE && 0
|
|
if (HasSSE2())
|
|
return 4*BYTES_PER_ITERATION;
|
|
else
|
|
#endif
|
|
return BYTES_PER_ITERATION;
|
|
}
|
|
|
|
template<unsigned int R>
|
|
void ChaCha_Policy<R>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
|
|
{
|
|
word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
|
|
|
|
while (iterationCount--)
|
|
{
|
|
x0 = m_state[0]; x1 = m_state[1]; x2 = m_state[2]; x3 = m_state[3];
|
|
x4 = m_state[4]; x5 = m_state[5]; x6 = m_state[6]; x7 = m_state[7];
|
|
x8 = m_state[8]; x9 = m_state[9]; x10 = m_state[10]; x11 = m_state[11];
|
|
x12 = m_state[12]; x13 = m_state[13]; x14 = m_state[14]; x15 = m_state[15];
|
|
|
|
for (int i = static_cast<int>(ROUNDS); i > 0; i -= 2)
|
|
{
|
|
CHACHA_QUARTER_ROUND(x0, x4, x8, x12);
|
|
CHACHA_QUARTER_ROUND(x1, x5, x9, x13);
|
|
CHACHA_QUARTER_ROUND(x2, x6, x10, x14);
|
|
CHACHA_QUARTER_ROUND(x3, x7, x11, x15);
|
|
|
|
CHACHA_QUARTER_ROUND(x0, x5, x10, x15);
|
|
CHACHA_QUARTER_ROUND(x1, x6, x11, x12);
|
|
CHACHA_QUARTER_ROUND(x2, x7, x8, x13);
|
|
CHACHA_QUARTER_ROUND(x3, x4, x9, x14);
|
|
}
|
|
|
|
#undef CHACHA_OUTPUT
|
|
#define CHACHA_OUTPUT(x){\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 0, x0 + m_state[0]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 1, x1 + m_state[1]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 2, x2 + m_state[2]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 3, x3 + m_state[3]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 4, x4 + m_state[4]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 5, x5 + m_state[5]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 6, x6 + m_state[6]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 7, x7 + m_state[7]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 8, x8 + m_state[8]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 9, x9 + m_state[9]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 10, x10 + m_state[10]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 11, x11 + m_state[11]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 12, x12 + m_state[12]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 13, x13 + m_state[13]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 14, x14 + m_state[14]);\
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 15, x15 + m_state[15]);}
|
|
|
|
#ifndef CRYPTOPP_DOXYGEN_PROCESSING
|
|
CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(CHACHA_OUTPUT, BYTES_PER_ITERATION);
|
|
#endif
|
|
|
|
++m_state[12];
|
|
m_state[13] += static_cast<word32>(m_state[12] == 0);
|
|
}
|
|
}
|
|
|
|
template class ChaCha_Policy<8>;
|
|
template class ChaCha_Policy<12>;
|
|
template class ChaCha_Policy<20>;
|
|
|
|
NAMESPACE_END
|