Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/square.cpp
Line
Count
Source
1
// square.cpp - originally written and placed in the public domain by Wei Dai
2
// Based on Paulo S.L.M. Barreto's public domain implementation
3
4
#include "pch.h"
5
#include "config.h"
6
7
#include "square.h"
8
#include "misc.h"
9
#include "gf256.h"
10
11
#if CRYPTOPP_MSC_VERSION
12
# pragma warning(disable: 4244)
13
#endif
14
15
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
16
# pragma GCC diagnostic ignored "-Wmissing-braces"
17
#endif
18
19
NAMESPACE_BEGIN(CryptoPP)
20
21
// apply theta to a roundkey
22
static void SquareTransform (word32 in[4], word32 out[4])
23
41
{
24
41
  static const byte G[4][4] =
25
41
  {
26
41
    {0x02U, 0x01U, 0x01U, 0x03U},
27
41
    {0x03U, 0x02U, 0x01U, 0x01U},
28
41
    {0x01U, 0x03U, 0x02U, 0x01U},
29
41
    {0x01U, 0x01U, 0x03U, 0x02U}
30
41
  };
31
32
41
  GF256 gf256(0xf5);
33
34
205
  for (int i = 0; i < 4; i++)
35
164
  {
36
164
    word32 temp = 0;
37
820
    for (unsigned int j = 0; j < 4; j++)
38
3.28k
      for (unsigned int k = 0; k < 4; k++)
39
2.62k
        temp ^= (word32)gf256.Multiply(GETBYTE(in[i], 3-k), G[k][j]) << ((3-j)*8);
40
164
    out[i] = temp;
41
164
  }
42
41
}
43
44
3.26k
#define roundkeys(i, j)   m_roundkeys[(i)*4+(j)]
45
82
#define roundkeys4(i)   (m_roundkeys+(i)*4)
46
47
void Square::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &)
48
6
{
49
6
  AssertValidKeyLength(length);
50
51
6
  static const word32 offset[ROUNDS] = {
52
6
  0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL,
53
6
  0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL,
54
6
  };
55
56
6
  GetUserKey(BIG_ENDIAN_ORDER, m_roundkeys.data(), KEYLENGTH/4, userKey, KEYLENGTH);
57
58
  /* apply the key evolution function */
59
54
  for (int i = 1; i < ROUNDS+1; i++)
60
48
  {
61
48
    roundkeys(i, 0) = roundkeys(i-1, 0) ^ rotlConstant<8>(roundkeys(i-1, 3)) ^ offset[i-1];
62
48
    roundkeys(i, 1) = roundkeys(i-1, 1) ^ roundkeys(i, 0);
63
48
    roundkeys(i, 2) = roundkeys(i-1, 2) ^ roundkeys(i, 1);
64
48
    roundkeys(i, 3) = roundkeys(i-1, 3) ^ roundkeys(i, 2);
65
48
  }
66
67
  /* produce the round keys */
68
6
  if (IsForwardTransformation())
69
5
  {
70
45
    for (int i = 0; i < ROUNDS; i++)
71
40
      SquareTransform (roundkeys4(i), roundkeys4(i));
72
5
  }
73
1
  else
74
1
  {
75
5
    for (int i = 0; i < ROUNDS/2; i++)
76
20
      for (int j = 0; j < 4; j++)
77
16
        std::swap(roundkeys(i, j), roundkeys(ROUNDS-i, j));
78
1
    SquareTransform (roundkeys4(ROUNDS), roundkeys4(ROUNDS));
79
1
  }
80
6
}
81
82
21.2k
#define MSB(x) (((x) >> 24) & 0xffU)  /* most  significant byte */
83
21.2k
#define SSB(x) (((x) >> 16) & 0xffU)  /* second in significance */
84
21.2k
#define TSB(x) (((x) >>  8) & 0xffU)  /* third  in significance */
85
21.2k
#define LSB(x) (((x)      ) & 0xffU)  /* least significant byte */
86
87
4.65k
#define squareRound(text, temp, T0, T1, T2, T3, roundkey) \
88
4.65k
{ \
89
4.65k
  temp[0] = T0[MSB (text[0])] \
90
4.65k
      ^ T1[MSB (text[1])] \
91
4.65k
      ^ T2[MSB (text[2])] \
92
4.65k
      ^ T3[MSB (text[3])] \
93
4.65k
      ^ roundkey[0]; \
94
4.65k
  temp[1] = T0[SSB (text[0])] \
95
4.65k
      ^ T1[SSB (text[1])] \
96
4.65k
      ^ T2[SSB (text[2])] \
97
4.65k
      ^ T3[SSB (text[3])] \
98
4.65k
      ^ roundkey[1]; \
99
4.65k
  temp[2] = T0[TSB (text[0])] \
100
4.65k
      ^ T1[TSB (text[1])] \
101
4.65k
      ^ T2[TSB (text[2])] \
102
4.65k
      ^ T3[TSB (text[3])] \
103
4.65k
      ^ roundkey[2]; \
104
4.65k
  temp[3] = T0[LSB (text[0])] \
105
4.65k
      ^ T1[LSB (text[1])] \
106
4.65k
      ^ T2[LSB (text[2])] \
107
4.65k
      ^ T3[LSB (text[3])] \
108
4.65k
      ^ roundkey[3]; \
109
4.65k
} /* squareRound */
110
111
665
#define squareFinal(text, temp, S, roundkey) \
112
665
{ \
113
665
  text[0] = ((word32) (S[MSB (temp[0])]) << 24) \
114
665
      ^ ((word32) (S[MSB (temp[1])]) << 16) \
115
665
      ^ ((word32) (S[MSB (temp[2])]) <<  8) \
116
665
      ^  (word32) (S[MSB (temp[3])]) \
117
665
      ^ roundkey[0]; \
118
665
  text[1] = ((word32) (S[SSB (temp[0])]) << 24) \
119
665
      ^ ((word32) (S[SSB (temp[1])]) << 16) \
120
665
      ^ ((word32) (S[SSB (temp[2])]) <<  8) \
121
665
      ^  (word32) (S[SSB (temp[3])]) \
122
665
      ^ roundkey[1]; \
123
665
  text[2] = ((word32) (S[TSB (temp[0])]) << 24) \
124
665
      ^ ((word32) (S[TSB (temp[1])]) << 16) \
125
665
      ^ ((word32) (S[TSB (temp[2])]) <<  8) \
126
665
      ^  (word32) (S[TSB (temp[3])]) \
127
665
      ^ roundkey[2]; \
128
665
  text[3] = ((word32) (S[LSB (temp[0])]) << 24) \
129
665
      ^ ((word32) (S[LSB (temp[1])]) << 16) \
130
665
      ^ ((word32) (S[LSB (temp[2])]) <<  8) \
131
665
      ^  (word32) (S[LSB (temp[3])]) \
132
665
      ^ roundkey[3]; \
133
665
} /* squareFinal */
134
135
typedef BlockGetAndPut<word32, BigEndian> Block;
136
137
void Square::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
138
334
{
139
334
  word32 text[4], temp[4];
140
334
  Block::Get(inBlock)(text[0])(text[1])(text[2])(text[3]);
141
142
  /* initial key addition */
143
334
  text[0] ^= roundkeys(0, 0);
144
334
  text[1] ^= roundkeys(0, 1);
145
334
  text[2] ^= roundkeys(0, 2);
146
334
  text[3] ^= roundkeys(0, 3);
147
148
  /* ROUNDS - 1 full rounds */
149
1.33k
  for (int i=1; i+1<ROUNDS; i+=2)
150
1.00k
  {
151
1.00k
    squareRound (text, temp, Te[0], Te[1], Te[2], Te[3], roundkeys4(i));
152
1.00k
    squareRound (temp, text, Te[0], Te[1], Te[2], Te[3], roundkeys4(i+1));
153
1.00k
  }
154
334
  squareRound (text, temp, Te[0], Te[1], Te[2], Te[3], roundkeys4(ROUNDS-1));
155
156
  /* last round (diffusion becomes only transposition) */
157
334
  squareFinal (text, temp, Se, roundkeys4(ROUNDS));
158
159
334
  Block::Put(xorBlock, outBlock)(text[0])(text[1])(text[2])(text[3]);
160
334
}
161
162
void Square::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
163
331
{
164
331
  word32 text[4], temp[4];
165
331
  Block::Get(inBlock)(text[0])(text[1])(text[2])(text[3]);
166
167
  /* initial key addition */
168
331
  text[0] ^= roundkeys(0, 0);
169
331
  text[1] ^= roundkeys(0, 1);
170
331
  text[2] ^= roundkeys(0, 2);
171
331
  text[3] ^= roundkeys(0, 3);
172
173
  /* ROUNDS - 1 full rounds */
174
1.32k
  for (int i=1; i+1<ROUNDS; i+=2)
175
993
  {
176
993
    squareRound (text, temp, Td[0], Td[1], Td[2], Td[3], roundkeys4(i));
177
993
    squareRound (temp, text, Td[0], Td[1], Td[2], Td[3], roundkeys4(i+1));
178
993
  }
179
331
  squareRound (text, temp, Td[0], Td[1], Td[2], Td[3], roundkeys4(ROUNDS-1));
180
181
  /* last round (diffusion becomes only transposition) */
182
331
  squareFinal (text, temp, Sd, roundkeys4(ROUNDS));
183
184
331
  Block::Put(xorBlock, outBlock)(text[0])(text[1])(text[2])(text[3]);
185
331
}
186
187
NAMESPACE_END