You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1362 lines
55 KiB
1362 lines
55 KiB
// kalyna.cpp - written and placed in the public domain by Jeffrey Walton |
|
// This code relied upon three sources. First was Oliynykov, Gorbenko, Kazymyrov, Ruzhentsev, |
|
// Kuznetsov, Gorbenko, Dyrda, Dolgov, Pushkaryov, Mordvinov and Kaidalov's "A New Encryption |
|
// Standard of Ukraine: The Kalyna Block Cipher" (http://eprint.iacr.org/2015/650.pdf). Second |
|
// was Roman Oliynykov and Oleksandr Kazymyrov's GitHub with the reference implementation |
|
// (http://github.com/Roman-Oliynykov/Kalyna-reference). The third and most utilized resource |
|
// was Keru Kuro's public domain implementation of Kalyna in CppCrypto |
|
// (http://sourceforge.net/projects/cppcrypto/). Kuro has an outstanding implementation that |
|
// performed better than the reference implementation and our initial attempts. The only downside |
|
// was the missing big endian port. |
|
|
|
#include "pch.h" |
|
#include "config.h" |
|
|
|
#include "kalyna.h" |
|
#include "argnames.h" |
|
#include "misc.h" |
|
#include "cpu.h" |
|
|
|
NAMESPACE_BEGIN(CryptoPP) |
|
NAMESPACE_BEGIN(KalynaTab) |
|
|
|
// T can be shared between Kupyna and Kalyna; IT, S and IS are Kalyna specific |
|
extern const word64 T[8][256]; // Columns |
|
extern const word64 IT[8][256]; // Inverse |
|
extern const byte S[4][256]; // Substitution |
|
extern const byte IS[4][256]; // Inverse |
|
|
|
NAMESPACE_END |
|
NAMESPACE_END |
|
|
|
ANONYMOUS_NAMESPACE_BEGIN |
|
|
|
// The typedef here is to sidestep problems with byte in the global namespace |
|
typedef unsigned char byte; |
|
|
|
using CryptoPP::word64; |
|
using CryptoPP::KalynaTab::T; |
|
using CryptoPP::KalynaTab::S; |
|
using CryptoPP::KalynaTab::IT; |
|
using CryptoPP::KalynaTab::IS; |
|
|
|
template <unsigned int NB> |
|
inline void MakeOddKey(const word64 evenkey[NB], word64 oddkey[NB]) |
|
{ |
|
#if (CRYPTOPP_BIG_ENDIAN) |
|
if (NB == 2) |
|
{ |
|
oddkey[0] = (evenkey[1] << 8) | (evenkey[0] >> 56); |
|
oddkey[1] = (evenkey[0] << 8) | (evenkey[1] >> 56); |
|
} |
|
else if (NB == 4) |
|
{ |
|
oddkey[0] = (evenkey[2] << 40) | (evenkey[1] >> 24); |
|
oddkey[1] = (evenkey[3] << 40) | (evenkey[2] >> 24); |
|
oddkey[2] = (evenkey[0] << 40) | (evenkey[3] >> 24); |
|
oddkey[3] = (evenkey[1] << 40) | (evenkey[0] >> 24); |
|
} |
|
else if (NB == 8) |
|
{ |
|
oddkey[0] = (evenkey[3] << 40) | (evenkey[2] >> 24); |
|
oddkey[1] = (evenkey[4] << 40) | (evenkey[3] >> 24); |
|
oddkey[2] = (evenkey[5] << 40) | (evenkey[4] >> 24); |
|
oddkey[3] = (evenkey[6] << 40) | (evenkey[5] >> 24); |
|
|
|
oddkey[4] = (evenkey[7] << 40) | (evenkey[6] >> 24); |
|
oddkey[5] = (evenkey[0] << 40) | (evenkey[7] >> 24); |
|
oddkey[6] = (evenkey[1] << 40) | (evenkey[0] >> 24); |
|
oddkey[7] = (evenkey[2] << 40) | (evenkey[1] >> 24); |
|
} |
|
else |
|
{ |
|
CRYPTOPP_ASSERT(0); |
|
} |
|
#else |
|
static const unsigned int U = (NB == 2) ? 16 : (NB == 4) ? 32 : (NB == 8) ? 64 : -1; |
|
static const unsigned int V = (NB == 2) ? 7 : (NB == 4) ? 11 : (NB == 8) ? 19 : -1; |
|
|
|
const byte* even = reinterpret_cast<const byte*>(evenkey); |
|
byte* odd = reinterpret_cast<byte*>(oddkey); |
|
|
|
memcpy(odd, even + V, U - V); |
|
memcpy(odd + U - V, even, V); |
|
#endif |
|
} |
|
|
|
template <unsigned int NB> |
|
inline void SwapBlocks(word64 k[NB]) |
|
{ |
|
const word64 t = k[0]; |
|
k[0] = k[1]; |
|
|
|
if (NB > 2) |
|
{ |
|
k[1] = k[2]; |
|
k[2] = k[3]; |
|
} |
|
|
|
if (NB > 4) |
|
{ |
|
k[3] = k[4]; |
|
k[4] = k[5]; |
|
k[5] = k[6]; |
|
k[6] = k[7]; |
|
} |
|
|
|
k[NB - 1] = t; |
|
} |
|
|
|
template <unsigned int NB> |
|
inline void AddKey(const word64 x[NB], word64 y[NB], const word64 k[NB]) |
|
{ |
|
y[0] = x[0] + k[0]; |
|
y[1] = x[1] + k[1]; |
|
|
|
if (NB > 2) |
|
{ |
|
y[2] = x[2] + k[2]; |
|
y[3] = x[3] + k[3]; |
|
} |
|
|
|
if (NB > 4) |
|
{ |
|
y[4] = x[4] + k[4]; |
|
y[5] = x[5] + k[5]; |
|
y[6] = x[6] + k[6]; |
|
y[7] = x[7] + k[7]; |
|
} |
|
} |
|
|
|
template <unsigned int NB> |
|
inline void SubKey(const word64 x[NB], word64 y[NB], const word64 k[NB]) |
|
{ |
|
y[0] = x[0] - k[0]; |
|
y[1] = x[1] - k[1]; |
|
|
|
if (NB > 2) |
|
{ |
|
y[2] = x[2] - k[2]; |
|
y[3] = x[3] - k[3]; |
|
} |
|
|
|
if (NB > 4) |
|
{ |
|
y[4] = x[4] - k[4]; |
|
y[5] = x[5] - k[5]; |
|
y[6] = x[6] - k[6]; |
|
y[7] = x[7] - k[7]; |
|
} |
|
} |
|
|
|
template <unsigned int NB> |
|
static inline void AddConstant(word64 src[NB], word64 dst[NB], word64 constant) |
|
{ |
|
dst[0] = src[0] + constant; |
|
dst[1] = src[1] + constant; |
|
|
|
if (NB > 2) |
|
{ |
|
dst[2] = src[2] + constant; |
|
dst[3] = src[3] + constant; |
|
} |
|
|
|
if (NB > 4) |
|
{ |
|
dst[4] = src[4] + constant; |
|
dst[5] = src[5] + constant; |
|
dst[6] = src[6] + constant; |
|
dst[7] = src[7] + constant; |
|
} |
|
} |
|
|
|
inline void G0128(const word64 x[2], word64 y[2]) |
|
{ |
|
y[0] = T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ |
|
T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]; |
|
y[1] = T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ |
|
T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]; |
|
} |
|
|
|
inline void G0256(const word64 x[4], word64 y[4]) |
|
{ |
|
y[0] = T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^ |
|
T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]; |
|
y[1] = T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ |
|
T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[2] >> 56)]; |
|
y[2] = T[0][(byte)x[2]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ |
|
T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[3] >> 56)]; |
|
y[3] = T[0][(byte)x[3]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^ |
|
T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]; |
|
} |
|
|
|
inline void G0512(const word64 x[8], word64 y[8]) |
|
{ |
|
y[0] = T[0][(byte)x[0]] ^ T[1][(byte)(x[7] >> 8)] ^ T[2][(byte)(x[6] >> 16)] ^ T[3][(byte)(x[5] >> 24)] ^ |
|
T[4][(byte)(x[4] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[1] >> 56)]; |
|
y[1] = T[0][(byte)x[1]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[7] >> 16)] ^ T[3][(byte)(x[6] >> 24)] ^ |
|
T[4][(byte)(x[5] >> 32)] ^ T[5][(byte)(x[4] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[2] >> 56)]; |
|
y[2] = T[0][(byte)x[2]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[7] >> 24)] ^ |
|
T[4][(byte)(x[6] >> 32)] ^ T[5][(byte)(x[5] >> 40)] ^ T[6][(byte)(x[4] >> 48)] ^ T[7][(byte)(x[3] >> 56)]; |
|
y[3] = T[0][(byte)x[3]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ |
|
T[4][(byte)(x[7] >> 32)] ^ T[5][(byte)(x[6] >> 40)] ^ T[6][(byte)(x[5] >> 48)] ^ T[7][(byte)(x[4] >> 56)]; |
|
y[4] = T[0][(byte)x[4]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ |
|
T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[7] >> 40)] ^ T[6][(byte)(x[6] >> 48)] ^ T[7][(byte)(x[5] >> 56)]; |
|
y[5] = T[0][(byte)x[5]] ^ T[1][(byte)(x[4] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^ |
|
T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[7] >> 48)] ^ T[7][(byte)(x[6] >> 56)]; |
|
y[6] = T[0][(byte)x[6]] ^ T[1][(byte)(x[5] >> 8)] ^ T[2][(byte)(x[4] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^ |
|
T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[7] >> 56)]; |
|
y[7] = T[0][(byte)x[7]] ^ T[1][(byte)(x[6] >> 8)] ^ T[2][(byte)(x[5] >> 16)] ^ T[3][(byte)(x[4] >> 24)] ^ |
|
T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[0] >> 56)]; |
|
} |
|
|
|
inline void GL128(const word64 x[2], word64 y[2], const word64 k[2]) |
|
{ |
|
y[0] = k[0] + (T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ |
|
T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]); |
|
y[1] = k[1] + (T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ |
|
T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]); |
|
} |
|
|
|
inline void GL256(const word64 x[4], word64 y[4], const word64 k[4]) |
|
{ |
|
y[0] = k[0] + (T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^ |
|
T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]); |
|
y[1] = k[1] + (T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ |
|
T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[2] >> 56)]); |
|
y[2] = k[2] + (T[0][(byte)x[2]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ |
|
T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[3] >> 56)]); |
|
y[3] = k[3] + (T[0][(byte)x[3]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^ |
|
T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]); |
|
} |
|
|
|
inline void GL512(const word64 x[8], word64 y[8], const word64 k[8]) |
|
{ |
|
y[0] = k[0] + (T[0][(byte)x[0]] ^ T[1][(byte)(x[7] >> 8)] ^ T[2][(byte)(x[6] >> 16)] ^ T[3][(byte)(x[5] >> 24)] ^ |
|
T[4][(byte)(x[4] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[1] >> 56)]); |
|
y[1] = k[1] + (T[0][(byte)x[1]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[7] >> 16)] ^ T[3][(byte)(x[6] >> 24)] ^ |
|
T[4][(byte)(x[5] >> 32)] ^ T[5][(byte)(x[4] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[2] >> 56)]); |
|
y[2] = k[2] + (T[0][(byte)x[2]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[7] >> 24)] ^ |
|
T[4][(byte)(x[6] >> 32)] ^ T[5][(byte)(x[5] >> 40)] ^ T[6][(byte)(x[4] >> 48)] ^ T[7][(byte)(x[3] >> 56)]); |
|
y[3] = k[3] + (T[0][(byte)x[3]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ |
|
T[4][(byte)(x[7] >> 32)] ^ T[5][(byte)(x[6] >> 40)] ^ T[6][(byte)(x[5] >> 48)] ^ T[7][(byte)(x[4] >> 56)]); |
|
y[4] = k[4] + (T[0][(byte)x[4]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ |
|
T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[7] >> 40)] ^ T[6][(byte)(x[6] >> 48)] ^ T[7][(byte)(x[5] >> 56)]); |
|
y[5] = k[5] + (T[0][(byte)x[5]] ^ T[1][(byte)(x[4] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^ |
|
T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[7] >> 48)] ^ T[7][(byte)(x[6] >> 56)]); |
|
y[6] = k[6] + (T[0][(byte)x[6]] ^ T[1][(byte)(x[5] >> 8)] ^ T[2][(byte)(x[4] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^ |
|
T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[7] >> 56)]); |
|
y[7] = k[7] + (T[0][(byte)x[7]] ^ T[1][(byte)(x[6] >> 8)] ^ T[2][(byte)(x[5] >> 16)] ^ T[3][(byte)(x[4] >> 24)] ^ |
|
T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[0] >> 56)]); |
|
} |
|
|
|
inline void IMC128(word64 x[2]) |
|
{ |
|
x[0] = IT[0][S[0][(byte)x[0]]] ^ IT[1][S[1][(byte)(x[0] >> 8)]] ^ IT[2][S[2][(byte)(x[0] >> 16)]] ^ IT[3][S[3][(byte)(x[0] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[0] >> 32)]] ^ IT[5][S[1][(byte)(x[0] >> 40)]] ^ IT[6][S[2][(byte)(x[0] >> 48)]] ^ IT[7][S[3][(byte)(x[0] >> 56)]]; |
|
x[1] = IT[0][S[0][(byte)x[1]]] ^ IT[1][S[1][(byte)(x[1] >> 8)]] ^ IT[2][S[2][(byte)(x[1] >> 16)]] ^ IT[3][S[3][(byte)(x[1] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[1] >> 32)]] ^ IT[5][S[1][(byte)(x[1] >> 40)]] ^ IT[6][S[2][(byte)(x[1] >> 48)]] ^ IT[7][S[3][(byte)(x[1] >> 56)]]; |
|
} |
|
|
|
inline void IMC256(word64 x[4]) |
|
{ |
|
x[0] = IT[0][S[0][(byte)x[0]]] ^ IT[1][S[1][(byte)(x[0] >> 8)]] ^ IT[2][S[2][(byte)(x[0] >> 16)]] ^ IT[3][S[3][(byte)(x[0] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[0] >> 32)]] ^ IT[5][S[1][(byte)(x[0] >> 40)]] ^ IT[6][S[2][(byte)(x[0] >> 48)]] ^ IT[7][S[3][(byte)(x[0] >> 56)]]; |
|
x[1] = IT[0][S[0][(byte)x[1]]] ^ IT[1][S[1][(byte)(x[1] >> 8)]] ^ IT[2][S[2][(byte)(x[1] >> 16)]] ^ IT[3][S[3][(byte)(x[1] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[1] >> 32)]] ^ IT[5][S[1][(byte)(x[1] >> 40)]] ^ IT[6][S[2][(byte)(x[1] >> 48)]] ^ IT[7][S[3][(byte)(x[1] >> 56)]]; |
|
x[2] = IT[0][S[0][(byte)x[2]]] ^ IT[1][S[1][(byte)(x[2] >> 8)]] ^ IT[2][S[2][(byte)(x[2] >> 16)]] ^ IT[3][S[3][(byte)(x[2] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[2] >> 32)]] ^ IT[5][S[1][(byte)(x[2] >> 40)]] ^ IT[6][S[2][(byte)(x[2] >> 48)]] ^ IT[7][S[3][(byte)(x[2] >> 56)]]; |
|
x[3] = IT[0][S[0][(byte)x[3]]] ^ IT[1][S[1][(byte)(x[3] >> 8)]] ^ IT[2][S[2][(byte)(x[3] >> 16)]] ^ IT[3][S[3][(byte)(x[3] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[3] >> 32)]] ^ IT[5][S[1][(byte)(x[3] >> 40)]] ^ IT[6][S[2][(byte)(x[3] >> 48)]] ^ IT[7][S[3][(byte)(x[3] >> 56)]]; |
|
} |
|
|
|
inline void IMC512(word64 x[8]) |
|
{ |
|
x[0] = IT[0][S[0][(byte)x[0]]] ^ IT[1][S[1][(byte)(x[0] >> 8)]] ^ IT[2][S[2][(byte)(x[0] >> 16)]] ^ IT[3][S[3][(byte)(x[0] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[0] >> 32)]] ^ IT[5][S[1][(byte)(x[0] >> 40)]] ^ IT[6][S[2][(byte)(x[0] >> 48)]] ^ IT[7][S[3][(byte)(x[0] >> 56)]]; |
|
x[1] = IT[0][S[0][(byte)x[1]]] ^ IT[1][S[1][(byte)(x[1] >> 8)]] ^ IT[2][S[2][(byte)(x[1] >> 16)]] ^ IT[3][S[3][(byte)(x[1] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[1] >> 32)]] ^ IT[5][S[1][(byte)(x[1] >> 40)]] ^ IT[6][S[2][(byte)(x[1] >> 48)]] ^ IT[7][S[3][(byte)(x[1] >> 56)]]; |
|
x[2] = IT[0][S[0][(byte)x[2]]] ^ IT[1][S[1][(byte)(x[2] >> 8)]] ^ IT[2][S[2][(byte)(x[2] >> 16)]] ^ IT[3][S[3][(byte)(x[2] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[2] >> 32)]] ^ IT[5][S[1][(byte)(x[2] >> 40)]] ^ IT[6][S[2][(byte)(x[2] >> 48)]] ^ IT[7][S[3][(byte)(x[2] >> 56)]]; |
|
x[3] = IT[0][S[0][(byte)x[3]]] ^ IT[1][S[1][(byte)(x[3] >> 8)]] ^ IT[2][S[2][(byte)(x[3] >> 16)]] ^ IT[3][S[3][(byte)(x[3] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[3] >> 32)]] ^ IT[5][S[1][(byte)(x[3] >> 40)]] ^ IT[6][S[2][(byte)(x[3] >> 48)]] ^ IT[7][S[3][(byte)(x[3] >> 56)]]; |
|
x[4] = IT[0][S[0][(byte)x[4]]] ^ IT[1][S[1][(byte)(x[4] >> 8)]] ^ IT[2][S[2][(byte)(x[4] >> 16)]] ^ IT[3][S[3][(byte)(x[4] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[4] >> 32)]] ^ IT[5][S[1][(byte)(x[4] >> 40)]] ^ IT[6][S[2][(byte)(x[4] >> 48)]] ^ IT[7][S[3][(byte)(x[4] >> 56)]]; |
|
x[5] = IT[0][S[0][(byte)x[5]]] ^ IT[1][S[1][(byte)(x[5] >> 8)]] ^ IT[2][S[2][(byte)(x[5] >> 16)]] ^ IT[3][S[3][(byte)(x[5] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[5] >> 32)]] ^ IT[5][S[1][(byte)(x[5] >> 40)]] ^ IT[6][S[2][(byte)(x[5] >> 48)]] ^ IT[7][S[3][(byte)(x[5] >> 56)]]; |
|
x[6] = IT[0][S[0][(byte)x[6]]] ^ IT[1][S[1][(byte)(x[6] >> 8)]] ^ IT[2][S[2][(byte)(x[6] >> 16)]] ^ IT[3][S[3][(byte)(x[6] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[6] >> 32)]] ^ IT[5][S[1][(byte)(x[6] >> 40)]] ^ IT[6][S[2][(byte)(x[6] >> 48)]] ^ IT[7][S[3][(byte)(x[6] >> 56)]]; |
|
x[7] = IT[0][S[0][(byte)x[7]]] ^ IT[1][S[1][(byte)(x[7] >> 8)]] ^ IT[2][S[2][(byte)(x[7] >> 16)]] ^ IT[3][S[3][(byte)(x[7] >> 24)]] ^ |
|
IT[4][S[0][(byte)(x[7] >> 32)]] ^ IT[5][S[1][(byte)(x[7] >> 40)]] ^ IT[6][S[2][(byte)(x[7] >> 48)]] ^ IT[7][S[3][(byte)(x[7] >> 56)]]; |
|
} |
|
|
|
inline void IG128(const word64 x[2], word64 y[2], const word64 k[2]) |
|
{ |
|
y[0] = k[0] ^ IT[0][(byte)x[0]] ^ IT[1][(byte)(x[0] >> 8)] ^ IT[2][(byte)(x[0] >> 16)] ^ IT[3][(byte)(x[0] >> 24)] ^ |
|
IT[4][(byte)(x[1] >> 32)] ^ IT[5][(byte)(x[1] >> 40)] ^ IT[6][(byte)(x[1] >> 48)] ^ IT[7][(byte)(x[1] >> 56)]; |
|
y[1] = k[1] ^ IT[0][(byte)x[1]] ^ IT[1][(byte)(x[1] >> 8)] ^ IT[2][(byte)(x[1] >> 16)] ^ IT[3][(byte)(x[1] >> 24)] ^ |
|
IT[4][(byte)(x[0] >> 32)] ^ IT[5][(byte)(x[0] >> 40)] ^ IT[6][(byte)(x[0] >> 48)] ^ IT[7][(byte)(x[0] >> 56)]; |
|
} |
|
|
|
inline void IG256(const word64 x[4], word64 y[4], const word64 k[4]) |
|
{ |
|
y[0] = k[0] ^ IT[0][(byte)x[0]] ^ IT[1][(byte)(x[0] >> 8)] ^ IT[2][(byte)(x[1] >> 16)] ^ IT[3][(byte)(x[1] >> 24)] ^ |
|
IT[4][(byte)(x[2] >> 32)] ^ IT[5][(byte)(x[2] >> 40)] ^ IT[6][(byte)(x[3] >> 48)] ^ IT[7][(byte)(x[3] >> 56)]; |
|
y[1] = k[1] ^ IT[0][(byte)x[1]] ^ IT[1][(byte)(x[1] >> 8)] ^ IT[2][(byte)(x[2] >> 16)] ^ IT[3][(byte)(x[2] >> 24)] ^ |
|
IT[4][(byte)(x[3] >> 32)] ^ IT[5][(byte)(x[3] >> 40)] ^ IT[6][(byte)(x[0] >> 48)] ^ IT[7][(byte)(x[0] >> 56)]; |
|
y[2] = k[2] ^ IT[0][(byte)x[2]] ^ IT[1][(byte)(x[2] >> 8)] ^ IT[2][(byte)(x[3] >> 16)] ^ IT[3][(byte)(x[3] >> 24)] ^ |
|
IT[4][(byte)(x[0] >> 32)] ^ IT[5][(byte)(x[0] >> 40)] ^ IT[6][(byte)(x[1] >> 48)] ^ IT[7][(byte)(x[1] >> 56)]; |
|
y[3] = k[3] ^ IT[0][(byte)x[3]] ^ IT[1][(byte)(x[3] >> 8)] ^ IT[2][(byte)(x[0] >> 16)] ^ IT[3][(byte)(x[0] >> 24)] ^ |
|
IT[4][(byte)(x[1] >> 32)] ^ IT[5][(byte)(x[1] >> 40)] ^ IT[6][(byte)(x[2] >> 48)] ^ IT[7][(byte)(x[2] >> 56)]; |
|
} |
|
|
|
inline void IG512(const word64 x[8], word64 y[8], const word64 k[8]) |
|
{ |
|
y[0] = k[0] ^ IT[0][(byte)x[0]] ^ IT[1][(byte)(x[1] >> 8)] ^ IT[2][(byte)(x[2] >> 16)] ^ IT[3][(byte)(x[3] >> 24)] ^ |
|
IT[4][(byte)(x[4] >> 32)] ^ IT[5][(byte)(x[5] >> 40)] ^ IT[6][(byte)(x[6] >> 48)] ^ IT[7][(byte)(x[7] >> 56)]; |
|
y[1] = k[1] ^ IT[0][(byte)x[1]] ^ IT[1][(byte)(x[2] >> 8)] ^ IT[2][(byte)(x[3] >> 16)] ^ IT[3][(byte)(x[4] >> 24)] ^ |
|
IT[4][(byte)(x[5] >> 32)] ^ IT[5][(byte)(x[6] >> 40)] ^ IT[6][(byte)(x[7] >> 48)] ^ IT[7][(byte)(x[0] >> 56)]; |
|
y[2] = k[2] ^ IT[0][(byte)x[2]] ^ IT[1][(byte)(x[3] >> 8)] ^ IT[2][(byte)(x[4] >> 16)] ^ IT[3][(byte)(x[5] >> 24)] ^ |
|
IT[4][(byte)(x[6] >> 32)] ^ IT[5][(byte)(x[7] >> 40)] ^ IT[6][(byte)(x[0] >> 48)] ^ IT[7][(byte)(x[1] >> 56)]; |
|
y[3] = k[3] ^ IT[0][(byte)x[3]] ^ IT[1][(byte)(x[4] >> 8)] ^ IT[2][(byte)(x[5] >> 16)] ^ IT[3][(byte)(x[6] >> 24)] ^ |
|
IT[4][(byte)(x[7] >> 32)] ^ IT[5][(byte)(x[0] >> 40)] ^ IT[6][(byte)(x[1] >> 48)] ^ IT[7][(byte)(x[2] >> 56)]; |
|
y[4] = k[4] ^ IT[0][(byte)x[4]] ^ IT[1][(byte)(x[5] >> 8)] ^ IT[2][(byte)(x[6] >> 16)] ^ IT[3][(byte)(x[7] >> 24)] ^ |
|
IT[4][(byte)(x[0] >> 32)] ^ IT[5][(byte)(x[1] >> 40)] ^ IT[6][(byte)(x[2] >> 48)] ^ IT[7][(byte)(x[3] >> 56)]; |
|
y[5] = k[5] ^ IT[0][(byte)x[5]] ^ IT[1][(byte)(x[6] >> 8)] ^ IT[2][(byte)(x[7] >> 16)] ^ IT[3][(byte)(x[0] >> 24)] ^ |
|
IT[4][(byte)(x[1] >> 32)] ^ IT[5][(byte)(x[2] >> 40)] ^ IT[6][(byte)(x[3] >> 48)] ^ IT[7][(byte)(x[4] >> 56)]; |
|
y[6] = k[6] ^ IT[0][(byte)x[6]] ^ IT[1][(byte)(x[7] >> 8)] ^ IT[2][(byte)(x[0] >> 16)] ^ IT[3][(byte)(x[1] >> 24)] ^ |
|
IT[4][(byte)(x[2] >> 32)] ^ IT[5][(byte)(x[3] >> 40)] ^ IT[6][(byte)(x[4] >> 48)] ^ IT[7][(byte)(x[5] >> 56)]; |
|
y[7] = k[7] ^ IT[0][(byte)x[7]] ^ IT[1][(byte)(x[0] >> 8)] ^ IT[2][(byte)(x[1] >> 16)] ^ IT[3][(byte)(x[2] >> 24)] ^ |
|
IT[4][(byte)(x[3] >> 32)] ^ IT[5][(byte)(x[4] >> 40)] ^ IT[6][(byte)(x[5] >> 48)] ^ IT[7][(byte)(x[6] >> 56)]; |
|
} |
|
|
|
inline void IGL128(const word64 x[2], word64 y[2], const word64 k[2]) |
|
{ |
|
y[0] = (word64(IS[0][(byte)x[0]]) ^ word64(IS[1][(byte)(x[0] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[0] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[0] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[1] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[1] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[1] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[1] >> 56)]) << 56) - k[0]; |
|
y[1] = (word64(IS[0][(byte)x[1]]) ^ word64(IS[1][(byte)(x[1] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[1] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[1] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[0] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[0] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[0] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[0] >> 56)]) << 56) - k[1]; |
|
} |
|
|
|
inline void IGL256(const word64 x[4], word64 y[4], const word64 k[4]) |
|
{ |
|
y[0] = (word64(IS[0][(byte)x[0]]) ^ word64(IS[1][(byte)(x[0] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[1] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[1] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[2] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[2] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[3] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[3] >> 56)]) << 56) - k[0]; |
|
y[1] = (word64(IS[0][(byte)x[1]]) ^ word64(IS[1][(byte)(x[1] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[2] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[2] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[3] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[3] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[0] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[0] >> 56)]) << 56) - k[1]; |
|
y[2] = (word64(IS[0][(byte)x[2]]) ^ word64(IS[1][(byte)(x[2] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[3] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[3] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[0] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[0] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[1] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[1] >> 56)]) << 56) - k[2]; |
|
y[3] = (word64(IS[0][(byte)x[3]]) ^ word64(IS[1][(byte)(x[3] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[0] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[0] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[1] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[1] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[2] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[2] >> 56)]) << 56) - k[3]; |
|
} |
|
|
|
inline void IGL512(const word64 x[8], word64 y[8], const word64 k[8]) |
|
{ |
|
y[0] = (word64(IS[0][(byte)x[0]]) ^ word64(IS[1][(byte)(x[1] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[2] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[3] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[4] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[5] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[6] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[7] >> 56)]) << 56) - k[0]; |
|
y[1] = (word64(IS[0][(byte)x[1]]) ^ word64(IS[1][(byte)(x[2] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[3] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[4] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[5] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[6] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[7] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[0] >> 56)]) << 56) - k[1]; |
|
y[2] = (word64(IS[0][(byte)x[2]]) ^ word64(IS[1][(byte)(x[3] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[4] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[5] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[6] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[7] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[0] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[1] >> 56)]) << 56) - k[2]; |
|
y[3] = (word64(IS[0][(byte)x[3]]) ^ word64(IS[1][(byte)(x[4] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[5] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[6] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[7] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[0] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[1] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[2] >> 56)]) << 56) - k[3]; |
|
y[4] = (word64(IS[0][(byte)x[4]]) ^ word64(IS[1][(byte)(x[5] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[6] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[7] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[0] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[1] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[2] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[3] >> 56)]) << 56) - k[4]; |
|
y[5] = (word64(IS[0][(byte)x[5]]) ^ word64(IS[1][(byte)(x[6] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[7] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[0] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[1] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[2] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[3] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[4] >> 56)]) << 56) - k[5]; |
|
y[6] = (word64(IS[0][(byte)x[6]]) ^ word64(IS[1][(byte)(x[7] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[0] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[1] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[2] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[3] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[4] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[5] >> 56)]) << 56) - k[6]; |
|
y[7] = (word64(IS[0][(byte)x[7]]) ^ word64(IS[1][(byte)(x[0] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[1] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[2] >> 24)]) << 24 ^ |
|
word64(IS[0][(byte)(x[3] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[4] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[5] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[6] >> 56)]) << 56) - k[7]; |
|
} |
|
|
|
inline void G128(const word64 x[2], word64 y[2], const word64 k[2]) |
|
{ |
|
y[0] = k[0] ^ T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ |
|
T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]; |
|
y[1] = k[1] ^ T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ |
|
T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]; |
|
} |
|
|
|
inline void G256(const word64 x[4], word64 y[4], const word64 k[4]) |
|
{ |
|
y[0] = k[0] ^ T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^ |
|
T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]; |
|
y[1] = k[1] ^ T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ |
|
T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[2] >> 56)]; |
|
y[2] = k[2] ^ T[0][(byte)x[2]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ |
|
T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[3] >> 56)]; |
|
y[3] = k[3] ^ T[0][(byte)x[3]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^ |
|
T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]; |
|
} |
|
|
|
inline void G512(const word64 x[8], word64 y[8], const word64 k[8]) |
|
{ |
|
y[0] = k[0] ^ T[0][(byte)x[0]] ^ T[1][(byte)(x[7] >> 8)] ^ T[2][(byte)(x[6] >> 16)] ^ T[3][(byte)(x[5] >> 24)] ^ |
|
T[4][(byte)(x[4] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[1] >> 56)]; |
|
y[1] = k[1] ^ T[0][(byte)x[1]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[7] >> 16)] ^ T[3][(byte)(x[6] >> 24)] ^ |
|
T[4][(byte)(x[5] >> 32)] ^ T[5][(byte)(x[4] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[2] >> 56)]; |
|
y[2] = k[2] ^ T[0][(byte)x[2]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[7] >> 24)] ^ |
|
T[4][(byte)(x[6] >> 32)] ^ T[5][(byte)(x[5] >> 40)] ^ T[6][(byte)(x[4] >> 48)] ^ T[7][(byte)(x[3] >> 56)]; |
|
y[3] = k[3] ^ T[0][(byte)x[3]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ |
|
T[4][(byte)(x[7] >> 32)] ^ T[5][(byte)(x[6] >> 40)] ^ T[6][(byte)(x[5] >> 48)] ^ T[7][(byte)(x[4] >> 56)]; |
|
y[4] = k[4] ^ T[0][(byte)x[4]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ |
|
T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[7] >> 40)] ^ T[6][(byte)(x[6] >> 48)] ^ T[7][(byte)(x[5] >> 56)]; |
|
y[5] = k[5] ^ T[0][(byte)x[5]] ^ T[1][(byte)(x[4] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^ |
|
T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[7] >> 48)] ^ T[7][(byte)(x[6] >> 56)]; |
|
y[6] = k[6] ^ T[0][(byte)x[6]] ^ T[1][(byte)(x[5] >> 8)] ^ T[2][(byte)(x[4] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^ |
|
T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[7] >> 56)]; |
|
y[7] = k[7] ^ T[0][(byte)x[7]] ^ T[1][(byte)(x[6] >> 8)] ^ T[2][(byte)(x[5] >> 16)] ^ T[3][(byte)(x[4] >> 24)] ^ |
|
T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[0] >> 56)]; |
|
} |
|
|
|
ANONYMOUS_NAMESPACE_END |
|
|
|
NAMESPACE_BEGIN(CryptoPP) |
|
|
|
// *********************** UncheckedSetKey specializations *********************** // |
|
|
|
void Kalyna128::Base::SetKey_22(const word64 key[2]) |
|
{ |
|
word64 *ks = m_wspace+0, *ksc = m_wspace+2, *t1 = m_wspace+4; |
|
word64 *t2 = m_wspace+6, *k = m_wspace+8, *kswapped = m_wspace+10; |
|
|
|
memset(t1, 0, 2*8); |
|
t1[0] = (128 + 128 + 64) / 64; |
|
|
|
AddKey<2>(t1, t2, key); |
|
G128(t2, t1, key); |
|
GL128(t1, t2, key); |
|
G0128(t2, ks); |
|
|
|
word64 constant = W64LIT(0x0001000100010001); |
|
|
|
// round 0 |
|
memcpy(k, key, 16); |
|
kswapped[1] = k[0]; |
|
kswapped[0] = k[1]; |
|
|
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(k, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[0], ksc); |
|
MakeOddKey<2>(&m_rkeys[0], &m_rkeys[2]); |
|
|
|
// round 2 |
|
constant <<= 1; |
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(kswapped, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[4], ksc); |
|
MakeOddKey<2>(&m_rkeys[4], &m_rkeys[6]); |
|
|
|
// round 4 |
|
constant <<= 1; |
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(k, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[8], ksc); |
|
MakeOddKey<2>(&m_rkeys[8], &m_rkeys[10]); |
|
|
|
// round 6 |
|
constant <<= 1; |
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(kswapped, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[12], ksc); |
|
MakeOddKey<2>(&m_rkeys[12], &m_rkeys[14]); |
|
|
|
// round 8 |
|
constant <<= 1; |
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(k, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[16], ksc); |
|
MakeOddKey<2>(&m_rkeys[16], &m_rkeys[18]); |
|
|
|
// round 10 |
|
constant <<= 1; |
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(kswapped, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[20], ksc); |
|
|
|
if (!IsForwardTransformation()) |
|
{ |
|
IMC128(&m_rkeys[18]); IMC128(&m_rkeys[16]); |
|
IMC128(&m_rkeys[14]); IMC128(&m_rkeys[12]); |
|
IMC128(&m_rkeys[10]); IMC128(&m_rkeys[ 8]); |
|
IMC128(&m_rkeys[ 6]); IMC128(&m_rkeys[ 4]); |
|
IMC128(&m_rkeys[ 2]); |
|
} |
|
} |
|
|
|
void Kalyna128::Base::SetKey_24(const word64 key[4]) |
|
{ |
|
word64 *ks = m_wspace+0, *ksc = m_wspace+2, *t1 = m_wspace+4, *t2 = m_wspace+6; |
|
word64 *k = m_wspace+8, *ka = m_wspace+12, *ko = m_wspace+14; |
|
|
|
memset(t1, 0, 2*8); |
|
t1[0] = (128 + 256 + 64) / 64; |
|
memcpy(ka, key, 16); |
|
memcpy(ko, key + 2, 16); |
|
|
|
AddKey<2>(t1, t2, ka); |
|
G128(t2, t1, ko); |
|
GL128(t1, t2, ka); |
|
G0128(t2, ks); |
|
|
|
word64 constant = W64LIT(0x0001000100010001); |
|
|
|
// round 0 |
|
memcpy(k, key, 256 / 8); |
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(k, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[0], ksc); |
|
MakeOddKey<2>(&m_rkeys[0], &m_rkeys[2]); |
|
|
|
// round 2 |
|
constant <<= 1; |
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(k + 2, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[4], ksc); |
|
MakeOddKey<2>(&m_rkeys[4], &m_rkeys[6]); |
|
|
|
// round 4 |
|
SwapBlocks<4>(k); |
|
constant <<= 1; |
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(k, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[8], ksc); |
|
MakeOddKey<2>(&m_rkeys[8], &m_rkeys[10]); |
|
|
|
// round 6 |
|
constant <<= 1; |
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(k + 2, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[12], ksc); |
|
MakeOddKey<2>(&m_rkeys[12], &m_rkeys[14]); |
|
|
|
// round 8 |
|
SwapBlocks<4>(k); |
|
constant <<= 1; |
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(k, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[16], ksc); |
|
MakeOddKey<2>(&m_rkeys[16], &m_rkeys[18]); |
|
|
|
// round 10 |
|
constant <<= 1; |
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(k + 2, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[20], ksc); |
|
MakeOddKey<2>(&m_rkeys[20], &m_rkeys[22]); |
|
|
|
// round 12 |
|
SwapBlocks<4>(k); |
|
constant <<= 1; |
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(k, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[24], ksc); |
|
MakeOddKey<2>(&m_rkeys[24], &m_rkeys[26]); |
|
|
|
// round 14 |
|
constant <<= 1; |
|
AddConstant<2>(ks, ksc, constant); |
|
AddKey<2>(k + 2, t2, ksc); |
|
G128(t2, t1, ksc); |
|
GL128(t1, &m_rkeys[28], ksc); |
|
|
|
if (!IsForwardTransformation()) |
|
{ |
|
IMC128(&m_rkeys[26]); |
|
IMC128(&m_rkeys[24]); |
|
IMC128(&m_rkeys[22]); |
|
IMC128(&m_rkeys[20]); |
|
IMC128(&m_rkeys[18]); |
|
IMC128(&m_rkeys[16]); |
|
IMC128(&m_rkeys[14]); |
|
IMC128(&m_rkeys[12]); |
|
IMC128(&m_rkeys[10]); |
|
IMC128(&m_rkeys[8]); |
|
IMC128(&m_rkeys[6]); |
|
IMC128(&m_rkeys[4]); |
|
IMC128(&m_rkeys[2]); |
|
} |
|
} |
|
|
|
void Kalyna256::Base::SetKey_44(const word64 key[4]) |
|
{ |
|
word64 *ks = m_wspace+0, *ksc = m_wspace+4, *t1 = m_wspace+8; |
|
word64 *t2 = m_wspace+12, *k = m_wspace+16; |
|
|
|
memset(t1, 0, 32); |
|
t1[0] = (256 + 256 + 64) / 64; |
|
|
|
AddKey<4>(t1, t2, key); |
|
G256(t2, t1, key); |
|
GL256(t1, t2, key); |
|
G0256(t2, ks); |
|
|
|
word64 constant = W64LIT(0x0001000100010001); |
|
|
|
// round 0 |
|
memcpy(k, key, 32); |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[0], ksc); |
|
MakeOddKey<4>(&m_rkeys[0], &m_rkeys[4]); |
|
|
|
// round 2 |
|
SwapBlocks<4>(k); |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[8], ksc); |
|
MakeOddKey<4>(&m_rkeys[8], &m_rkeys[12]); |
|
|
|
// round 4 |
|
SwapBlocks<4>(k); |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[16], ksc); |
|
MakeOddKey<4>(&m_rkeys[16], &m_rkeys[20]); |
|
|
|
// round 6 |
|
SwapBlocks<4>(k); |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[24], ksc); |
|
MakeOddKey<4>(&m_rkeys[24], &m_rkeys[28]); |
|
|
|
// round 8 |
|
SwapBlocks<4>(k); |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[32], ksc); |
|
MakeOddKey<4>(&m_rkeys[32], &m_rkeys[36]); |
|
|
|
// round 10 |
|
SwapBlocks<4>(k); |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[40], ksc); |
|
MakeOddKey<4>(&m_rkeys[40], &m_rkeys[44]); |
|
|
|
// round 12 |
|
SwapBlocks<4>(k); |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[48], ksc); |
|
MakeOddKey<4>(&m_rkeys[48], &m_rkeys[52]); |
|
|
|
// round 14 |
|
SwapBlocks<4>(k); |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[56], ksc); |
|
|
|
if (!IsForwardTransformation()) |
|
{ |
|
IMC256(&m_rkeys[52]); |
|
IMC256(&m_rkeys[48]); |
|
IMC256(&m_rkeys[44]); |
|
IMC256(&m_rkeys[40]); |
|
IMC256(&m_rkeys[36]); |
|
IMC256(&m_rkeys[32]); |
|
IMC256(&m_rkeys[28]); |
|
IMC256(&m_rkeys[24]); |
|
IMC256(&m_rkeys[20]); |
|
IMC256(&m_rkeys[16]); |
|
IMC256(&m_rkeys[12]); |
|
IMC256(&m_rkeys[8]); |
|
IMC256(&m_rkeys[4]); |
|
} |
|
} |
|
|
|
void Kalyna256::Base::SetKey_48(const word64 key[8]) |
|
{ |
|
word64 *ks = m_wspace+0, *ksc = m_wspace+4, *t1 = m_wspace+8, *t2 = m_wspace+12; |
|
word64 *k = m_wspace+16, *ka = m_wspace+24, *ko = m_wspace+28; |
|
|
|
memset(t1, 0, 4*8); |
|
t1[0] = (512 + 256 + 64) / 64; |
|
memcpy(ka, key, 32); |
|
memcpy(ko, key+4, 32); |
|
|
|
AddKey<4>(t1, t2, ka); |
|
G256(t2, t1, ko); |
|
GL256(t1, t2, ka); |
|
G0256(t2, ks); |
|
|
|
word64 constant = W64LIT(0x0001000100010001); |
|
|
|
// round 0 |
|
memcpy(k, key, 512 / 8); |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[0], ksc); |
|
MakeOddKey<4>(&m_rkeys[0], &m_rkeys[4]); |
|
|
|
// round 2 |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k+4, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[8], ksc); |
|
MakeOddKey<4>(&m_rkeys[8], &m_rkeys[12]); |
|
|
|
// round 4 |
|
SwapBlocks<8>(k); |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[16], ksc); |
|
MakeOddKey<4>(&m_rkeys[16], &m_rkeys[20]); |
|
|
|
// round 6 |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k+4, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[24], ksc); |
|
MakeOddKey<4>(&m_rkeys[24], &m_rkeys[28]); |
|
|
|
// round 8 |
|
SwapBlocks<8>(k); |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[32], ksc); |
|
MakeOddKey<4>(&m_rkeys[32], &m_rkeys[36]); |
|
|
|
// round 10 |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k+4, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[40], ksc); |
|
MakeOddKey<4>(&m_rkeys[40], &m_rkeys[44]); |
|
|
|
// round 12 |
|
SwapBlocks<8>(k); |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[48], ksc); |
|
MakeOddKey<4>(&m_rkeys[48], &m_rkeys[52]); |
|
|
|
// round 14 |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k+4, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[56], ksc); |
|
MakeOddKey<4>(&m_rkeys[56], &m_rkeys[60]); |
|
|
|
// round 16 |
|
SwapBlocks<8>(k); |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[64], ksc); |
|
MakeOddKey<4>(&m_rkeys[64], &m_rkeys[68]); |
|
|
|
// round 18 |
|
constant <<= 1; |
|
AddConstant<4>(ks, ksc, constant); |
|
AddKey<4>(k+4, t2, ksc); |
|
G256(t2, t1, ksc); |
|
GL256(t1, &m_rkeys[72], ksc); |
|
|
|
if (!IsForwardTransformation()) |
|
{ |
|
IMC256(&m_rkeys[68]); |
|
IMC256(&m_rkeys[64]); |
|
IMC256(&m_rkeys[60]); |
|
IMC256(&m_rkeys[56]); |
|
IMC256(&m_rkeys[52]); |
|
IMC256(&m_rkeys[48]); |
|
IMC256(&m_rkeys[44]); |
|
IMC256(&m_rkeys[40]); |
|
IMC256(&m_rkeys[36]); |
|
IMC256(&m_rkeys[32]); |
|
IMC256(&m_rkeys[28]); |
|
IMC256(&m_rkeys[24]); |
|
IMC256(&m_rkeys[20]); |
|
IMC256(&m_rkeys[16]); |
|
IMC256(&m_rkeys[12]); |
|
IMC256(&m_rkeys[8]); |
|
IMC256(&m_rkeys[4]); |
|
} |
|
} |
|
|
|
void Kalyna512::Base::SetKey_88(const word64 key[8]) |
|
{ |
|
word64 *ks = m_wspace+0, *ksc = m_wspace+8, *t1 = m_wspace+16; |
|
word64 *t2 = m_wspace+24, *k = m_wspace+32; |
|
|
|
memset(t1, 0, 8*8); |
|
t1[0] = (512 + 512 + 64) / 64; |
|
|
|
AddKey<8>(t1, t2, key); |
|
G512(t2, t1, key); |
|
GL512(t1, t2, key); |
|
G0512(t2, ks); |
|
|
|
word64 constant = W64LIT(0x0001000100010001); |
|
|
|
// round 0 |
|
memcpy(k, key, 512 / 8); |
|
AddConstant<8>(ks, ksc, constant); |
|
AddKey<8>(k, t2, ksc); |
|
G512(t2, t1, ksc); |
|
GL512(t1, &m_rkeys[0], ksc); |
|
MakeOddKey<8>(&m_rkeys[0], &m_rkeys[8]); |
|
|
|
// round 2 |
|
SwapBlocks<8>(k); |
|
constant <<= 1; |
|
AddConstant<8>(ks, ksc, constant); |
|
AddKey<8>(k, t2, ksc); |
|
G512(t2, t1, ksc); |
|
GL512(t1, &m_rkeys[16], ksc); |
|
MakeOddKey<8>(&m_rkeys[16], &m_rkeys[24]); |
|
|
|
// round 4 |
|
SwapBlocks<8>(k); |
|
constant <<= 1; |
|
AddConstant<8>(ks, ksc, constant); |
|
AddKey<8>(k, t2, ksc); |
|
G512(t2, t1, ksc); |
|
GL512(t1, &m_rkeys[32], ksc); |
|
MakeOddKey<8>(&m_rkeys[32], &m_rkeys[40]); |
|
|
|
// round 6 |
|
SwapBlocks<8>(k); |
|
constant <<= 1; |
|
AddConstant<8>(ks, ksc, constant); |
|
AddKey<8>(k, t2, ksc); |
|
G512(t2, t1, ksc); |
|
GL512(t1, &m_rkeys[48], ksc); |
|
MakeOddKey<8>(&m_rkeys[48], &m_rkeys[56]); |
|
|
|
// round 8 |
|
SwapBlocks<8>(k); |
|
constant <<= 1; |
|
AddConstant<8>(ks, ksc, constant); |
|
AddKey<8>(k, t2, ksc); |
|
G512(t2, t1, ksc); |
|
GL512(t1, &m_rkeys[64], ksc); |
|
MakeOddKey<8>(&m_rkeys[64], &m_rkeys[72]); |
|
|
|
// round 10 |
|
SwapBlocks<8>(k); |
|
constant <<= 1; |
|
AddConstant<8>(ks, ksc, constant); |
|
AddKey<8>(k, t2, ksc); |
|
G512(t2, t1, ksc); |
|
GL512(t1, &m_rkeys[80], ksc); |
|
MakeOddKey<8>(&m_rkeys[80], &m_rkeys[88]); |
|
|
|
// round 12 |
|
SwapBlocks<8>(k); |
|
constant <<= 1; |
|
AddConstant<8>(ks, ksc, constant); |
|
AddKey<8>(k, t2, ksc); |
|
G512(t2, t1, ksc); |
|
GL512(t1, &m_rkeys[96], ksc); |
|
MakeOddKey<8>(&m_rkeys[96], &m_rkeys[104]); |
|
|
|
// round 14 |
|
SwapBlocks<8>(k); |
|
constant <<= 1; |
|
AddConstant<8>(ks, ksc, constant); |
|
AddKey<8>(k, t2, ksc); |
|
G512(t2, t1, ksc); |
|
GL512(t1, &m_rkeys[112], ksc); |
|
MakeOddKey<8>(&m_rkeys[112], &m_rkeys[120]); |
|
|
|
// round 16 |
|
SwapBlocks<8>(k); |
|
constant <<= 1; |
|
AddConstant<8>(ks, ksc, constant); |
|
AddKey<8>(k, t2, ksc); |
|
G512(t2, t1, ksc); |
|
GL512(t1, &m_rkeys[128], ksc); |
|
MakeOddKey<8>(&m_rkeys[128], &m_rkeys[136]); |
|
|
|
// round 18 |
|
SwapBlocks<8>(k); |
|
constant <<= 1; |
|
AddConstant<8>(ks, ksc, constant); |
|
AddKey<8>(k, t2, ksc); |
|
G512(t2, t1, ksc); |
|
GL512(t1, &m_rkeys[144], ksc); |
|
|
|
if (!IsForwardTransformation()) |
|
{ |
|
IMC512(&m_rkeys[136]); IMC512(&m_rkeys[128]); IMC512(&m_rkeys[120]); IMC512(&m_rkeys[112]); |
|
IMC512(&m_rkeys[104]); IMC512(&m_rkeys[ 96]); IMC512(&m_rkeys[ 88]); IMC512(&m_rkeys[ 80]); |
|
IMC512(&m_rkeys[ 72]); IMC512(&m_rkeys[ 64]); IMC512(&m_rkeys[ 56]); IMC512(&m_rkeys[ 48]); |
|
IMC512(&m_rkeys[ 40]); IMC512(&m_rkeys[ 32]); IMC512(&m_rkeys[ 24]); IMC512(&m_rkeys[ 16]); |
|
IMC512(&m_rkeys[ 8]); |
|
} |
|
} |
|
|
|
// *********************** ProcessAndXorBlock specializations *********************** // |
|
|
|
void Kalyna128::Base::ProcessBlock_22(const byte* inBlock, const byte* xorBlock, byte* outBlock) const |
|
{ |
|
word64 *t1 = m_wspace+0, *t2 = m_wspace+2, *msg = m_wspace+4; |
|
|
|
// Reverse bytes on BigEndian; Align pointer on LittleEndian |
|
typedef GetBlock<word64, LittleEndian, false> InBlock; |
|
InBlock iblk(inBlock); |
|
iblk(msg[0])(msg[1]); |
|
|
|
if (IsForwardTransformation()) |
|
{ |
|
AddKey<2>(msg, t1, m_rkeys); |
|
G128(t1, t2, &m_rkeys[2]); // 1 |
|
G128(t2, t1, &m_rkeys[4]); // 2 |
|
G128(t1, t2, &m_rkeys[6]); // 3 |
|
G128(t2, t1, &m_rkeys[8]); // 4 |
|
G128(t1, t2, &m_rkeys[10]); // 5 |
|
G128(t2, t1, &m_rkeys[12]); // 6 |
|
G128(t1, t2, &m_rkeys[14]); // 7 |
|
G128(t2, t1, &m_rkeys[16]); // 8 |
|
G128(t1, t2, &m_rkeys[18]); // 9 |
|
GL128(t2, t1, &m_rkeys[20]); // 10 |
|
} |
|
else |
|
{ |
|
SubKey<2>(msg, t1, &m_rkeys[20]); |
|
IMC128(t1); |
|
IG128(t1, t2, &m_rkeys[18]); |
|
IG128(t2, t1, &m_rkeys[16]); |
|
IG128(t1, t2, &m_rkeys[14]); |
|
IG128(t2, t1, &m_rkeys[12]); |
|
IG128(t1, t2, &m_rkeys[10]); |
|
IG128(t2, t1, &m_rkeys[8]); |
|
IG128(t1, t2, &m_rkeys[6]); |
|
IG128(t2, t1, &m_rkeys[4]); |
|
IG128(t1, t2, &m_rkeys[2]); |
|
IGL128(t2, t1, &m_rkeys[0]); |
|
} |
|
|
|
// Reverse bytes on BigEndian; Align pointer on LittleEndian |
|
typedef PutBlock<word64, LittleEndian, false> OutBlock; |
|
OutBlock oblk(xorBlock, outBlock); |
|
oblk(t1[0])(t1[1]); |
|
} |
|
|
|
void Kalyna128::Base::ProcessBlock_24(const byte *inBlock, const byte *xorBlock, byte *outBlock) const |
|
{ |
|
word64 *t1 = m_wspace+0, *t2 = m_wspace+2, *msg = m_wspace+4; |
|
|
|
// Reverse bytes on BigEndian; Align pointer on LittleEndian |
|
typedef GetBlock<word64, LittleEndian, false> InBlock; |
|
InBlock iblk(inBlock); |
|
iblk(msg[0])(msg[1]); |
|
|
|
if (IsForwardTransformation()) |
|
{ |
|
AddKey<2>(msg, t1, m_rkeys); |
|
G128(t1, t2, &m_rkeys[ 2]); // 1 |
|
G128(t2, t1, &m_rkeys[ 4]); // 2 |
|
G128(t1, t2, &m_rkeys[ 6]); // 3 |
|
G128(t2, t1, &m_rkeys[ 8]); // 4 |
|
G128(t1, t2, &m_rkeys[10]); // 5 |
|
G128(t2, t1, &m_rkeys[12]); // 6 |
|
G128(t1, t2, &m_rkeys[14]); // 7 |
|
G128(t2, t1, &m_rkeys[16]); // 8 |
|
G128(t1, t2, &m_rkeys[18]); // 9 |
|
G128(t2, t1, &m_rkeys[20]); // 10 |
|
G128(t1, t2, &m_rkeys[22]); // 11 |
|
G128(t2, t1, &m_rkeys[24]); // 12 |
|
G128(t1, t2, &m_rkeys[26]); // 13 |
|
GL128(t2, t1, &m_rkeys[28]); // 14 |
|
} |
|
else |
|
{ |
|
SubKey<2>(msg, t1, &m_rkeys[28]); |
|
IMC128(t1); |
|
IG128(t1, t2, &m_rkeys[26]); |
|
IG128(t2, t1, &m_rkeys[24]); |
|
IG128(t1, t2, &m_rkeys[22]); |
|
IG128(t2, t1, &m_rkeys[20]); |
|
IG128(t1, t2, &m_rkeys[18]); |
|
IG128(t2, t1, &m_rkeys[16]); |
|
IG128(t1, t2, &m_rkeys[14]); |
|
IG128(t2, t1, &m_rkeys[12]); |
|
IG128(t1, t2, &m_rkeys[10]); |
|
IG128(t2, t1, &m_rkeys[8]); |
|
IG128(t1, t2, &m_rkeys[6]); |
|
IG128(t2, t1, &m_rkeys[4]); |
|
IG128(t1, t2, &m_rkeys[2]); |
|
IGL128(t2, t1, &m_rkeys[0]); |
|
} |
|
|
|
// Reverse bytes on BigEndian; Align pointer on LittleEndian |
|
typedef PutBlock<word64, LittleEndian, false> OutBlock; |
|
OutBlock oblk(xorBlock, outBlock); |
|
oblk(t1[0])(t1[1]); |
|
} |
|
|
|
void Kalyna256::Base::ProcessBlock_44(const byte *inBlock, const byte *xorBlock, byte *outBlock) const |
|
{ |
|
word64 *t1 = m_wspace+0, *t2 = m_wspace+4, *msg = m_wspace+8; |
|
|
|
// Reverse bytes on BigEndian; Align pointer on LittleEndian |
|
typedef GetBlock<word64, LittleEndian, false> InBlock; |
|
InBlock iblk(inBlock); |
|
iblk(msg[0])(msg[1])(msg[2])(msg[3]); |
|
|
|
if (IsForwardTransformation()) |
|
{ |
|
AddKey<4>(msg, t1, m_rkeys); |
|
G256(t1, t2, &m_rkeys[4]); // 1 |
|
G256(t2, t1, &m_rkeys[8]); // 2 |
|
G256(t1, t2, &m_rkeys[12]); // 3 |
|
G256(t2, t1, &m_rkeys[16]); // 4 |
|
G256(t1, t2, &m_rkeys[20]); // 5 |
|
G256(t2, t1, &m_rkeys[24]); // 6 |
|
G256(t1, t2, &m_rkeys[28]); // 7 |
|
G256(t2, t1, &m_rkeys[32]); // 8 |
|
G256(t1, t2, &m_rkeys[36]); // 9 |
|
G256(t2, t1, &m_rkeys[40]); // 10 |
|
G256(t1, t2, &m_rkeys[44]); // 11 |
|
G256(t2, t1, &m_rkeys[48]); // 12 |
|
G256(t1, t2, &m_rkeys[52]); // 13 |
|
GL256(t2, t1, &m_rkeys[56]); // 14 |
|
} |
|
else |
|
{ |
|
SubKey<4>(msg, t1, &m_rkeys[56]); |
|
IMC256(t1); |
|
IG256(t1, t2, &m_rkeys[52]); |
|
IG256(t2, t1, &m_rkeys[48]); |
|
IG256(t1, t2, &m_rkeys[44]); |
|
IG256(t2, t1, &m_rkeys[40]); |
|
IG256(t1, t2, &m_rkeys[36]); |
|
IG256(t2, t1, &m_rkeys[32]); |
|
IG256(t1, t2, &m_rkeys[28]); |
|
IG256(t2, t1, &m_rkeys[24]); |
|
IG256(t1, t2, &m_rkeys[20]); |
|
IG256(t2, t1, &m_rkeys[16]); |
|
IG256(t1, t2, &m_rkeys[12]); |
|
IG256(t2, t1, &m_rkeys[8]); |
|
IG256(t1, t2, &m_rkeys[4]); |
|
IGL256(t2, t1, &m_rkeys[0]); |
|
} |
|
|
|
// Reverse bytes on BigEndian; Align pointer on LittleEndian |
|
typedef PutBlock<word64, LittleEndian, false> OutBlock; |
|
OutBlock oblk(xorBlock, outBlock); |
|
oblk(t1[0])(t1[1])(t1[2])(t1[3]); |
|
} |
|
|
|
void Kalyna256::Base::ProcessBlock_48(const byte *inBlock, const byte *xorBlock, byte *outBlock) const |
|
{ |
|
word64 *t1 = m_wspace+0, *t2 = m_wspace+4, *msg = m_wspace+8; |
|
|
|
// Reverse bytes on BigEndian; Align pointer on LittleEndian |
|
typedef GetBlock<word64, LittleEndian, false> InBlock; |
|
InBlock iblk(inBlock); |
|
iblk(msg[0])(msg[1])(msg[2])(msg[3]); |
|
|
|
if (IsForwardTransformation()) |
|
{ |
|
AddKey<4>(msg, t1, m_rkeys); |
|
G256(t1, t2, &m_rkeys[4]); // 1 |
|
G256(t2, t1, &m_rkeys[8]); // 2 |
|
G256(t1, t2, &m_rkeys[12]); // 3 |
|
G256(t2, t1, &m_rkeys[16]); // 4 |
|
G256(t1, t2, &m_rkeys[20]); // 5 |
|
G256(t2, t1, &m_rkeys[24]); // 6 |
|
G256(t1, t2, &m_rkeys[28]); // 7 |
|
G256(t2, t1, &m_rkeys[32]); // 8 |
|
G256(t1, t2, &m_rkeys[36]); // 9 |
|
G256(t2, t1, &m_rkeys[40]); // 10 |
|
G256(t1, t2, &m_rkeys[44]); // 11 |
|
G256(t2, t1, &m_rkeys[48]); // 12 |
|
G256(t1, t2, &m_rkeys[52]); // 13 |
|
G256(t2, t1, &m_rkeys[56]); // 14 |
|
G256(t1, t2, &m_rkeys[60]); // 15 |
|
G256(t2, t1, &m_rkeys[64]); // 16 |
|
G256(t1, t2, &m_rkeys[68]); // 17 |
|
GL256(t2, t1, &m_rkeys[72]); // 18 |
|
} |
|
else |
|
{ |
|
SubKey<4>(msg, t1, &m_rkeys[72]); |
|
IMC256(t1); |
|
IG256(t1, t2, &m_rkeys[68]); |
|
IG256(t2, t1, &m_rkeys[64]); |
|
IG256(t1, t2, &m_rkeys[60]); |
|
IG256(t2, t1, &m_rkeys[56]); |
|
IG256(t1, t2, &m_rkeys[52]); |
|
IG256(t2, t1, &m_rkeys[48]); |
|
IG256(t1, t2, &m_rkeys[44]); |
|
IG256(t2, t1, &m_rkeys[40]); |
|
IG256(t1, t2, &m_rkeys[36]); |
|
IG256(t2, t1, &m_rkeys[32]); |
|
IG256(t1, t2, &m_rkeys[28]); |
|
IG256(t2, t1, &m_rkeys[24]); |
|
IG256(t1, t2, &m_rkeys[20]); |
|
IG256(t2, t1, &m_rkeys[16]); |
|
IG256(t1, t2, &m_rkeys[12]); |
|
IG256(t2, t1, &m_rkeys[8]); |
|
IG256(t1, t2, &m_rkeys[4]); |
|
IGL256(t2, t1, &m_rkeys[0]); |
|
} |
|
|
|
// Reverse bytes on BigEndian; Align pointer on LittleEndian |
|
typedef PutBlock<word64, LittleEndian, false> OutBlock; |
|
OutBlock oblk(xorBlock, outBlock); |
|
oblk(t1[0])(t1[1])(t1[2])(t1[3]); |
|
} |
|
|
|
void Kalyna512::Base::ProcessBlock_88(const byte *inBlock, const byte *xorBlock, byte *outBlock) const |
|
{ |
|
word64 *t1 = m_wspace+0, *t2 = m_wspace+8, *msg = m_wspace+16; |
|
|
|
// Reverse bytes on BigEndian; Align pointer on LittleEndian |
|
typedef GetBlock<word64, LittleEndian, false> InBlock; |
|
InBlock iblk(inBlock); |
|
iblk(msg[0])(msg[1])(msg[2])(msg[3])(msg[4])(msg[5])(msg[6])(msg[7]); |
|
|
|
if (IsForwardTransformation()) |
|
{ |
|
AddKey<8>(msg, t1, m_rkeys); |
|
G512(t1, t2, &m_rkeys[8]); // 1 |
|
G512(t2, t1, &m_rkeys[16]); // 2 |
|
G512(t1, t2, &m_rkeys[24]); // 3 |
|
G512(t2, t1, &m_rkeys[32]); // 4 |
|
G512(t1, t2, &m_rkeys[40]); // 5 |
|
G512(t2, t1, &m_rkeys[48]); // 6 |
|
G512(t1, t2, &m_rkeys[56]); // 7 |
|
G512(t2, t1, &m_rkeys[64]); // 8 |
|
G512(t1, t2, &m_rkeys[72]); // 9 |
|
G512(t2, t1, &m_rkeys[80]); // 10 |
|
G512(t1, t2, &m_rkeys[88]); // 11 |
|
G512(t2, t1, &m_rkeys[96]); // 12 |
|
G512(t1, t2, &m_rkeys[104]); // 13 |
|
G512(t2, t1, &m_rkeys[112]); // 14 |
|
G512(t1, t2, &m_rkeys[120]); // 15 |
|
G512(t2, t1, &m_rkeys[128]); // 16 |
|
G512(t1, t2, &m_rkeys[136]); // 17 |
|
GL512(t2, t1, &m_rkeys[144]); // 18 |
|
} |
|
else |
|
{ |
|
SubKey<8>(msg, t1, &m_rkeys[144]); |
|
IMC512(t1); |
|
IG512(t1, t2, &m_rkeys[136]); |
|
IG512(t2, t1, &m_rkeys[128]); |
|
IG512(t1, t2, &m_rkeys[120]); |
|
IG512(t2, t1, &m_rkeys[112]); |
|
IG512(t1, t2, &m_rkeys[104]); |
|
IG512(t2, t1, &m_rkeys[96]); |
|
IG512(t1, t2, &m_rkeys[88]); |
|
IG512(t2, t1, &m_rkeys[80]); |
|
IG512(t1, t2, &m_rkeys[72]); |
|
IG512(t2, t1, &m_rkeys[64]); |
|
IG512(t1, t2, &m_rkeys[56]); |
|
IG512(t2, t1, &m_rkeys[48]); |
|
IG512(t1, t2, &m_rkeys[40]); |
|
IG512(t2, t1, &m_rkeys[32]); |
|
IG512(t1, t2, &m_rkeys[24]); |
|
IG512(t2, t1, &m_rkeys[16]); |
|
IG512(t1, t2, &m_rkeys[8]); |
|
IGL512(t2, t1, &m_rkeys[0]); |
|
} |
|
|
|
// Reverse bytes on BigEndian; Align pointer on LittleEndian |
|
typedef PutBlock<word64, LittleEndian, false> OutBlock; |
|
OutBlock oblk(xorBlock, outBlock); |
|
oblk(t1[0])(t1[1])(t1[2])(t1[3])(t1[4])(t1[5])(t1[6])(t1[7]); |
|
} |
|
|
|
// *********************** Library routines *********************** // |
|
|
|
void Kalyna128::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms) |
|
{ |
|
CRYPTOPP_UNUSED(params); |
|
m_nb = static_cast<unsigned int>(16U / sizeof(word64)); |
|
m_nk = static_cast<unsigned int>(keylen / sizeof(word64)); |
|
|
|
switch (keylen) |
|
{ |
|
case 16: // 128 |
|
m_kl = 16; |
|
m_mkey.New(2); |
|
m_rkeys.New(11*2); |
|
m_wspace.New(2*6); |
|
|
|
GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 2, key, 16); |
|
SetKey_22(m_mkey.begin()); |
|
break; |
|
case 32: // 256 |
|
m_kl = 32; |
|
m_mkey.New(4); |
|
m_rkeys.New(15*2); |
|
m_wspace.New(6*2+4); |
|
|
|
GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 4, key, 32); |
|
SetKey_24(m_mkey.begin()); |
|
break; |
|
default: |
|
CRYPTOPP_ASSERT(0); |
|
} |
|
} |
|
|
|
void Kalyna128::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const |
|
{ |
|
// Timing attack countermeasure. see comments in Rijndael for more details |
|
const int cacheLineSize = GetCacheLineSize(); |
|
volatile word64 _u = 0; |
|
word64 u = _u; |
|
|
|
const byte* p = reinterpret_cast<const byte*>(KalynaTab::S); |
|
for (unsigned int i=0; i<256; i+=cacheLineSize) |
|
u ^= *reinterpret_cast<const word64*>(p+i); |
|
m_wspace[0] = u; |
|
|
|
switch ((m_nb << 8) | m_nk) |
|
{ |
|
case (2 << 8) | 2: |
|
ProcessBlock_22(inBlock, xorBlock, outBlock); |
|
break; |
|
case (2 << 8) | 4: |
|
ProcessBlock_24(inBlock, xorBlock, outBlock); |
|
break; |
|
default: |
|
CRYPTOPP_ASSERT(0); |
|
} |
|
} |
|
|
|
void Kalyna256::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms) |
|
{ |
|
CRYPTOPP_UNUSED(params); |
|
m_nb = static_cast<unsigned int>(32U / sizeof(word64)); |
|
m_nk = static_cast<unsigned int>(keylen / sizeof(word64)); |
|
|
|
switch (keylen) |
|
{ |
|
case 32: // 256 |
|
m_kl = 32; |
|
m_mkey.New(4); |
|
m_rkeys.New(15*4); |
|
m_wspace.New(5*4); |
|
|
|
GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 4, key, 32); |
|
SetKey_44(m_mkey.begin()); |
|
break; |
|
case 64: // 512 |
|
m_kl = 64; |
|
m_mkey.New(8); |
|
m_rkeys.New(19*4); |
|
m_wspace.New(6*4+8); |
|
|
|
GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 8, key, 64); |
|
SetKey_48(m_mkey.begin()); |
|
break; |
|
default: |
|
CRYPTOPP_ASSERT(0); |
|
} |
|
} |
|
|
|
void Kalyna256::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const |
|
{ |
|
// Timing attack countermeasure. see comments in Rijndael for more details |
|
const int cacheLineSize = GetCacheLineSize(); |
|
volatile word64 _u = 0; |
|
word64 u = _u; |
|
|
|
const byte* p = reinterpret_cast<const byte*>(KalynaTab::S); |
|
for (unsigned int i=0; i<256; i+=cacheLineSize) |
|
u ^= *reinterpret_cast<const word64*>(p+i); |
|
m_wspace[0] = u; |
|
|
|
switch ((m_nb << 8) | m_nk) |
|
{ |
|
case (4 << 8) | 4: |
|
ProcessBlock_44(inBlock, xorBlock, outBlock); |
|
break; |
|
case (4 << 8) | 8: |
|
ProcessBlock_48(inBlock, xorBlock, outBlock); |
|
break; |
|
default: |
|
CRYPTOPP_ASSERT(0); |
|
} |
|
} |
|
|
|
void Kalyna512::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms) |
|
{ |
|
CRYPTOPP_UNUSED(params); |
|
m_nb = static_cast<unsigned int>(64U / sizeof(word64)); |
|
m_nk = static_cast<unsigned int>(keylen / sizeof(word64)); |
|
|
|
switch (keylen) |
|
{ |
|
case 64: // 512 |
|
m_kl = 64; |
|
m_nb = static_cast<unsigned int>(64U / sizeof(word64)); |
|
m_nk = static_cast<unsigned int>(keylen / sizeof(word64)); |
|
|
|
m_mkey.New(8); |
|
m_rkeys.New(19*8); |
|
m_wspace.New(5*8); |
|
|
|
GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 8, key, 64); |
|
SetKey_88(m_mkey.begin()); |
|
break; |
|
default: |
|
CRYPTOPP_ASSERT(0); |
|
} |
|
} |
|
|
|
void Kalyna512::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const |
|
{ |
|
// Timing attack countermeasure. see comments in Rijndael for more details |
|
const int cacheLineSize = GetCacheLineSize(); |
|
volatile word64 _u = 0; |
|
word64 u = _u; |
|
|
|
const byte* p = reinterpret_cast<const byte*>(KalynaTab::S); |
|
for (unsigned int i=0; i<256; i+=cacheLineSize) |
|
u ^= *reinterpret_cast<const word64*>(p+i); |
|
m_wspace[0] = u; |
|
|
|
ProcessBlock_88(inBlock, xorBlock, outBlock); |
|
} |
|
|
|
NAMESPACE_END
|
|
|