mirror of
https://github.com/shadps4-emu/ext-cryptopp.git
synced 2024-11-23 09:59:42 +00:00
140 lines
3.1 KiB
C++
Executable File
140 lines
3.1 KiB
C++
Executable File
// salsa.cpp - written and placed in the public domain by Wei Dai
|
|
|
|
#include "pch.h"
|
|
#include "salsa.h"
|
|
#include "misc.h"
|
|
#include "argnames.h"
|
|
|
|
NAMESPACE_BEGIN(CryptoPP)
|
|
|
|
void Salsa20_TestInstantiations()
|
|
{
|
|
Salsa20::Encryption x;
|
|
}
|
|
|
|
void Salsa20_Policy::CipherGetNextIV(byte *IV)
|
|
{
|
|
word32 j6 = m_state[6] + 1;
|
|
word32 j7 = m_state[7] + (j6 == 0);
|
|
|
|
UnalignedPutWord(LITTLE_ENDIAN_ORDER, IV, j6);
|
|
UnalignedPutWord(LITTLE_ENDIAN_ORDER, IV+4, j7);
|
|
}
|
|
|
|
void Salsa20_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length)
|
|
{
|
|
m_rounds = params.GetIntValueWithDefault(Name::Rounds(), 20);
|
|
|
|
if (!(m_rounds == 8 || m_rounds == 12 || m_rounds == 20))
|
|
throw InvalidRounds(StaticAlgorithmName(), m_rounds);
|
|
|
|
GetUserKey(LITTLE_ENDIAN_ORDER, m_state+1, 4, key, 16);
|
|
GetUserKey(LITTLE_ENDIAN_ORDER, m_state+11, 4, key + length - 16, 16);
|
|
|
|
// m_state[0,5,10,15] forms "expand 16-byte k" or "expand 32-byte k"
|
|
m_state[0] = 0x61707865;
|
|
m_state[5] = (length == 16) ? 0x3120646e : 0x3320646e;
|
|
m_state[10] = (length == 16) ? 0x79622d36 : 0x79622d32;
|
|
m_state[15] = 0x6b206574;
|
|
}
|
|
|
|
void Salsa20_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV)
|
|
{
|
|
GetUserKey(LITTLE_ENDIAN_ORDER, m_state+6, 4, IV, 8);
|
|
}
|
|
|
|
void Salsa20_Policy::SeekToIteration(lword iterationCount)
|
|
{
|
|
m_state[8] = (word32)iterationCount;
|
|
m_state[9] = (word32)SafeRightShift<32>(iterationCount);
|
|
}
|
|
|
|
void Salsa20_Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
|
|
{
|
|
KeystreamOutput<LittleEndian> keystreamOutput(operation, output, input);
|
|
|
|
word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
|
|
word32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
|
|
|
|
j0 = m_state[0];
|
|
j1 = m_state[1];
|
|
j2 = m_state[2];
|
|
j3 = m_state[3];
|
|
j4 = m_state[4];
|
|
j5 = m_state[5];
|
|
j6 = m_state[6];
|
|
j7 = m_state[7];
|
|
j8 = m_state[8];
|
|
j9 = m_state[9];
|
|
j10 = m_state[10];
|
|
j11 = m_state[11];
|
|
j12 = m_state[12];
|
|
j13 = m_state[13];
|
|
j14 = m_state[14];
|
|
j15 = m_state[15];
|
|
|
|
for (size_t iteration = 0; iteration < iterationCount; ++iteration)
|
|
{
|
|
x0 = j0;
|
|
x1 = j1;
|
|
x2 = j2;
|
|
x3 = j3;
|
|
x4 = j4;
|
|
x5 = j5;
|
|
x6 = j6;
|
|
x7 = j7;
|
|
x8 = j8;
|
|
x9 = j9;
|
|
x10 = j10;
|
|
x11 = j11;
|
|
x12 = j12;
|
|
x13 = j13;
|
|
x14 = j14;
|
|
x15 = j15;
|
|
|
|
for (int i=m_rounds; i>0; i-=2)
|
|
{
|
|
#define QUARTER_ROUND(a, b, c, d) \
|
|
b = b ^ rotlFixed(a + d, 7); \
|
|
c = c ^ rotlFixed(b + a, 9); \
|
|
d = d ^ rotlFixed(c + b, 13); \
|
|
a = a ^ rotlFixed(d + c, 18);
|
|
|
|
QUARTER_ROUND(x0, x4, x8, x12)
|
|
QUARTER_ROUND(x5, x9, x13, x1)
|
|
QUARTER_ROUND(x10, x14, x2, x6)
|
|
QUARTER_ROUND(x15, x3, x7, x11)
|
|
|
|
QUARTER_ROUND(x0, x1, x2, x3)
|
|
QUARTER_ROUND(x5, x6, x7, x4)
|
|
QUARTER_ROUND(x10, x11, x8, x9)
|
|
QUARTER_ROUND(x15, x12, x13, x14)
|
|
}
|
|
|
|
keystreamOutput (x0 + j0)
|
|
(x1 + j1)
|
|
(x2 + j2)
|
|
(x3 + j3)
|
|
(x4 + j4)
|
|
(x5 + j5)
|
|
(x6 + j6)
|
|
(x7 + j7)
|
|
(x8 + j8)
|
|
(x9 + j9)
|
|
(x10 + j10)
|
|
(x11 + j11)
|
|
(x12 + j12)
|
|
(x13 + j13)
|
|
(x14 + j14)
|
|
(x15 + j15);
|
|
|
|
if (++j8 == 0)
|
|
++j9;
|
|
}
|
|
|
|
m_state[8] = j8;
|
|
m_state[9] = j9;
|
|
}
|
|
|
|
NAMESPACE_END
|