11#if CRYPTOPP_MSC_VERSION
12# pragma warning(disable: 4244)
15#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
16# pragma GCC diagnostic ignored "-Wmissing-braces"
19NAMESPACE_BEGIN(CryptoPP)
24 static const byte G[4][4] =
26 0x02U, 0x01U, 0x01U, 0x03U,
27 0x03U, 0x02U, 0x01U, 0x01U,
28 0x01U, 0x03U, 0x02U, 0x01U,
29 0x01U, 0x01U, 0x03U, 0x02U
34 for (
int i = 0; i < 4; i++)
37 for (
unsigned int j = 0; j < 4; j++)
38 for (
unsigned int k = 0; k < 4; k++)
39 temp ^= (
word32)gf256.Multiply(GETBYTE(in[i], 3-k), G[k][j]) << ((3-j)*8);
44#define roundkeys(i, j) m_roundkeys[(i)*4+(j)]
45#define roundkeys4(i) (m_roundkeys+(i)*4)
47void Square::Base::UncheckedSetKey(
const byte *userKey,
unsigned int length,
const NameValuePairs &)
49 AssertValidKeyLength(length);
51 static const word32 offset[ROUNDS] = {
52 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL,
53 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL,
59 for (
int i = 1; i < ROUNDS+1; i++)
61 roundkeys(i, 0) = roundkeys(i-1, 0) ^ rotlConstant<8>(roundkeys(i-1, 3)) ^ offset[i-1];
62 roundkeys(i, 1) = roundkeys(i-1, 1) ^ roundkeys(i, 0);
63 roundkeys(i, 2) = roundkeys(i-1, 2) ^ roundkeys(i, 1);
64 roundkeys(i, 3) = roundkeys(i-1, 3) ^ roundkeys(i, 2);
68 if (IsForwardTransformation())
70 for (
int i = 0; i < ROUNDS; i++)
71 SquareTransform (roundkeys4(i), roundkeys4(i));
75 for (
int i = 0; i < ROUNDS/2; i++)
76 for (
int j = 0; j < 4; j++)
77 std::swap(roundkeys(i, j), roundkeys(ROUNDS-i, j));
78 SquareTransform (roundkeys4(ROUNDS), roundkeys4(ROUNDS));
82#define MSB(x) (((x) >> 24) & 0xffU)
83#define SSB(x) (((x) >> 16) & 0xffU)
84#define TSB(x) (((x) >> 8) & 0xffU)
85#define LSB(x) (((x) ) & 0xffU)
87#define squareRound(text, temp, T0, T1, T2, T3, roundkey) \
89 temp[0] = T0[MSB (text[0])] \
94 temp[1] = T0[SSB (text[0])] \
99 temp[2] = T0[TSB (text[0])] \
100 ^ T1[TSB (text[1])] \
101 ^ T2[TSB (text[2])] \
102 ^ T3[TSB (text[3])] \
104 temp[3] = T0[LSB (text[0])] \
105 ^ T1[LSB (text[1])] \
106 ^ T2[LSB (text[2])] \
107 ^ T3[LSB (text[3])] \
111#define squareFinal(text, temp, S, roundkey) \
113 text[0] = ((word32) (S[MSB (temp[0])]) << 24) \
114 ^ ((word32) (S[MSB (temp[1])]) << 16) \
115 ^ ((word32) (S[MSB (temp[2])]) << 8) \
116 ^ (word32) (S[MSB (temp[3])]) \
118 text[1] = ((word32) (S[SSB (temp[0])]) << 24) \
119 ^ ((word32) (S[SSB (temp[1])]) << 16) \
120 ^ ((word32) (S[SSB (temp[2])]) << 8) \
121 ^ (word32) (S[SSB (temp[3])]) \
123 text[2] = ((word32) (S[TSB (temp[0])]) << 24) \
124 ^ ((word32) (S[TSB (temp[1])]) << 16) \
125 ^ ((word32) (S[TSB (temp[2])]) << 8) \
126 ^ (word32) (S[TSB (temp[3])]) \
128 text[3] = ((word32) (S[LSB (temp[0])]) << 24) \
129 ^ ((word32) (S[LSB (temp[1])]) << 16) \
130 ^ ((word32) (S[LSB (temp[2])]) << 8) \
131 ^ (word32) (S[LSB (temp[3])]) \
137void Square::Enc::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
140 Block::Get(inBlock)(text[0])(text[1])(text[2])(text[3]);
143 text[0] ^= roundkeys(0, 0);
144 text[1] ^= roundkeys(0, 1);
145 text[2] ^= roundkeys(0, 2);
146 text[3] ^= roundkeys(0, 3);
149 for (
int i=1; i+1<ROUNDS; i+=2)
151 squareRound (text, temp, Te[0], Te[1], Te[2], Te[3], roundkeys4(i));
152 squareRound (temp, text, Te[0], Te[1], Te[2], Te[3], roundkeys4(i+1));
154 squareRound (text, temp, Te[0], Te[1], Te[2], Te[3], roundkeys4(ROUNDS-1));
157 squareFinal (text, temp, Se, roundkeys4(ROUNDS));
159 Block::Put(xorBlock, outBlock)(text[0])(text[1])(text[2])(text[3]);
162void Square::Dec::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
165 Block::Get(inBlock)(text[0])(text[1])(text[2])(text[3]);
168 text[0] ^= roundkeys(0, 0);
169 text[1] ^= roundkeys(0, 1);
170 text[2] ^= roundkeys(0, 2);
171 text[3] ^= roundkeys(0, 3);
174 for (
int i=1; i+1<ROUNDS; i+=2)
176 squareRound (text, temp, Td[0], Td[1], Td[2], Td[3], roundkeys4(i));
177 squareRound (temp, text, Td[0], Td[1], Td[2], Td[3], roundkeys4(i+1));
179 squareRound (text, temp, Td[0], Td[1], Td[2], Td[3], roundkeys4(ROUNDS-1));
182 squareFinal (text, temp, Sd, roundkeys4(ROUNDS));
184 Block::Put(xorBlock, outBlock)(text[0])(text[1])(text[2])(text[3]);
GF(256) with polynomial basis.
Interface for retrieving values given their names.
Access a block of memory.
Library configuration file.
unsigned int word32
32-bit unsigned datatype
@ BIG_ENDIAN_ORDER
byte order is big-endian
Classes and functions for schemes over GF(256)
Utility functions for the Crypto++ library.
void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen)
Copy bytes in a buffer to an array of elements in big-endian order.
Classes for the Square block cipher.
Access a block of memory.