Botan  1.10.9
noekeon.cpp
Go to the documentation of this file.
1 /*
2 * Noekeon
3 * (C) 1999-2008 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/noekeon.h>
9 #include <botan/loadstor.h>
10 #include <botan/rotate.h>
11 
12 namespace Botan {
13 
14 namespace {
15 
16 /*
17 * Noekeon's Theta Operation
18 */
19 inline void theta(u32bit& A0, u32bit& A1,
20  u32bit& A2, u32bit& A3,
21  const u32bit EK[4])
22  {
23  u32bit T = A0 ^ A2;
24  T ^= rotate_left(T, 8) ^ rotate_right(T, 8);
25  A1 ^= T;
26  A3 ^= T;
27 
28  A0 ^= EK[0];
29  A1 ^= EK[1];
30  A2 ^= EK[2];
31  A3 ^= EK[3];
32 
33  T = A1 ^ A3;
34  T ^= rotate_left(T, 8) ^ rotate_right(T, 8);
35  A0 ^= T;
36  A2 ^= T;
37  }
38 
39 /*
40 * Theta With Null Key
41 */
42 inline void theta(u32bit& A0, u32bit& A1,
43  u32bit& A2, u32bit& A3)
44  {
45  u32bit T = A0 ^ A2;
46  T ^= rotate_left(T, 8) ^ rotate_right(T, 8);
47  A1 ^= T;
48  A3 ^= T;
49 
50  T = A1 ^ A3;
51  T ^= rotate_left(T, 8) ^ rotate_right(T, 8);
52  A0 ^= T;
53  A2 ^= T;
54  }
55 
56 /*
57 * Noekeon's Gamma S-Box Layer
58 */
59 inline void gamma(u32bit& A0, u32bit& A1, u32bit& A2, u32bit& A3)
60  {
61  A1 ^= ~A3 & ~A2;
62  A0 ^= A2 & A1;
63 
64  u32bit T = A3;
65  A3 = A0;
66  A0 = T;
67 
68  A2 ^= A0 ^ A1 ^ A3;
69 
70  A1 ^= ~A3 & ~A2;
71  A0 ^= A2 & A1;
72  }
73 
74 }
75 
76 /*
77 * Noekeon Round Constants
78 */
79 const byte Noekeon::RC[] = {
80  0x80, 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A,
81  0x2F, 0x5E, 0xBC, 0x63, 0xC6, 0x97, 0x35, 0x6A,
82  0xD4 };
83 
84 /*
85 * Noekeon Encryption
86 */
87 void Noekeon::encrypt_n(const byte in[], byte out[], size_t blocks) const
88  {
89  for(size_t i = 0; i != blocks; ++i)
90  {
91  u32bit A0 = load_be<u32bit>(in, 0);
92  u32bit A1 = load_be<u32bit>(in, 1);
93  u32bit A2 = load_be<u32bit>(in, 2);
94  u32bit A3 = load_be<u32bit>(in, 3);
95 
96  for(size_t j = 0; j != 16; ++j)
97  {
98  A0 ^= RC[j];
99  theta(A0, A1, A2, A3, &EK[0]);
100 
101  A1 = rotate_left(A1, 1);
102  A2 = rotate_left(A2, 5);
103  A3 = rotate_left(A3, 2);
104 
105  gamma(A0, A1, A2, A3);
106 
107  A1 = rotate_right(A1, 1);
108  A2 = rotate_right(A2, 5);
109  A3 = rotate_right(A3, 2);
110  }
111 
112  A0 ^= RC[16];
113  theta(A0, A1, A2, A3, &EK[0]);
114 
115  store_be(out, A0, A1, A2, A3);
116 
117  in += BLOCK_SIZE;
118  out += BLOCK_SIZE;
119  }
120  }
121 
122 /*
123 * Noekeon Encryption
124 */
125 void Noekeon::decrypt_n(const byte in[], byte out[], size_t blocks) const
126  {
127  for(size_t i = 0; i != blocks; ++i)
128  {
129  u32bit A0 = load_be<u32bit>(in, 0);
130  u32bit A1 = load_be<u32bit>(in, 1);
131  u32bit A2 = load_be<u32bit>(in, 2);
132  u32bit A3 = load_be<u32bit>(in, 3);
133 
134  for(size_t j = 16; j != 0; --j)
135  {
136  theta(A0, A1, A2, A3, &DK[0]);
137  A0 ^= RC[j];
138 
139  A1 = rotate_left(A1, 1);
140  A2 = rotate_left(A2, 5);
141  A3 = rotate_left(A3, 2);
142 
143  gamma(A0, A1, A2, A3);
144 
145  A1 = rotate_right(A1, 1);
146  A2 = rotate_right(A2, 5);
147  A3 = rotate_right(A3, 2);
148  }
149 
150  theta(A0, A1, A2, A3, &DK[0]);
151  A0 ^= RC[0];
152 
153  store_be(out, A0, A1, A2, A3);
154 
155  in += BLOCK_SIZE;
156  out += BLOCK_SIZE;
157  }
158  }
159 
160 /*
161 * Noekeon Key Schedule
162 */
163 void Noekeon::key_schedule(const byte key[], size_t)
164  {
165  u32bit A0 = load_be<u32bit>(key, 0);
166  u32bit A1 = load_be<u32bit>(key, 1);
167  u32bit A2 = load_be<u32bit>(key, 2);
168  u32bit A3 = load_be<u32bit>(key, 3);
169 
170  for(size_t i = 0; i != 16; ++i)
171  {
172  A0 ^= RC[i];
173  theta(A0, A1, A2, A3);
174 
175  A1 = rotate_left(A1, 1);
176  A2 = rotate_left(A2, 5);
177  A3 = rotate_left(A3, 2);
178 
179  gamma(A0, A1, A2, A3);
180 
181  A1 = rotate_right(A1, 1);
182  A2 = rotate_right(A2, 5);
183  A3 = rotate_right(A3, 2);
184  }
185 
186  A0 ^= RC[16];
187 
188  DK[0] = A0;
189  DK[1] = A1;
190  DK[2] = A2;
191  DK[3] = A3;
192 
193  theta(A0, A1, A2, A3);
194 
195  EK[0] = A0;
196  EK[1] = A1;
197  EK[2] = A2;
198  EK[3] = A3;
199  }
200 
201 /*
202 * Clear memory of sensitive data
203 */
205  {
206  zeroise(EK);
207  zeroise(DK);
208  }
209 
210 }
void clear()
Definition: noekeon.cpp:204
T rotate_left(T input, size_t rot)
Definition: rotate.h:21
unsigned char byte
Definition: types.h:22
void encrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: noekeon.cpp:87
T rotate_right(T input, size_t rot)
Definition: rotate.h:34
static const byte RC[17]
Definition: noekeon.h:33
u32bit load_be< u32bit >(const byte in[], size_t off)
Definition: loadstor.h:166
void store_be(u16bit in, byte out[2])
Definition: loadstor.h:412
void decrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: noekeon.cpp:125
void zeroise(MemoryRegion< T > &vec)
Definition: secmem.h:415
unsigned int u32bit
Definition: types.h:32