Botan  1.10.9
noekeon_simd.cpp
Go to the documentation of this file.
1 /*
2 * Noekeon in SIMD
3 * (C) 2010 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/noekeon_simd.h>
9 #include <botan/internal/simd_32.h>
10 
11 namespace Botan {
12 
13 /*
14 * Noekeon's Theta Operation
15 */
16 #define NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3) \
17  do { \
18  SIMD_32 T = A0 ^ A2; \
19  SIMD_32 T_l8 = T; \
20  SIMD_32 T_r8 = T; \
21  T_l8.rotate_left(8); \
22  T_r8.rotate_right(8); \
23  T ^= T_l8; \
24  T ^= T_r8; \
25  A1 ^= T; \
26  A3 ^= T; \
27  \
28  A0 ^= K0; \
29  A1 ^= K1; \
30  A2 ^= K2; \
31  A3 ^= K3; \
32  \
33  T = A1 ^ A3; \
34  T_l8 = T; \
35  T_r8 = T; \
36  T_l8.rotate_left(8); \
37  T_r8.rotate_right(8); \
38  T ^= T_l8; \
39  T ^= T_r8; \
40  A0 ^= T; \
41  A2 ^= T; \
42  } while(0)
43 
44 /*
45 * Noekeon's Gamma S-Box Layer
46 */
47 #define NOK_SIMD_GAMMA(A0, A1, A2, A3) \
48  do \
49  { \
50  A1 ^= A3.andc(~A2); \
51  A0 ^= A2 & A1; \
52  \
53  SIMD_32 T = A3; \
54  A3 = A0; \
55  A0 = T; \
56  \
57  A2 ^= A0 ^ A1 ^ A3; \
58  \
59  A1 ^= A3.andc(~A2); \
60  A0 ^= A2 & A1; \
61  } while(0)
62 
63 /*
64 * Noekeon Encryption
65 */
66 void Noekeon_SIMD::encrypt_n(const byte in[], byte out[], size_t blocks) const
67  {
68  const SecureVector<u32bit>& EK = this->get_EK();
69 
70  SIMD_32 K0 = SIMD_32(EK[0]);
71  SIMD_32 K1 = SIMD_32(EK[1]);
72  SIMD_32 K2 = SIMD_32(EK[2]);
73  SIMD_32 K3 = SIMD_32(EK[3]);
74 
75  while(blocks >= 4)
76  {
77  SIMD_32 A0 = SIMD_32::load_be(in );
78  SIMD_32 A1 = SIMD_32::load_be(in + 16);
79  SIMD_32 A2 = SIMD_32::load_be(in + 32);
80  SIMD_32 A3 = SIMD_32::load_be(in + 48);
81 
82  SIMD_32::transpose(A0, A1, A2, A3);
83 
84  for(size_t i = 0; i != 16; ++i)
85  {
86  A0 ^= SIMD_32(RC[i]);
87 
88  NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3);
89 
90  A1.rotate_left(1);
91  A2.rotate_left(5);
92  A3.rotate_left(2);
93 
94  NOK_SIMD_GAMMA(A0, A1, A2, A3);
95 
96  A1.rotate_right(1);
97  A2.rotate_right(5);
98  A3.rotate_right(2);
99  }
100 
101  A0 ^= SIMD_32(RC[16]);
102  NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3);
103 
104  SIMD_32::transpose(A0, A1, A2, A3);
105 
106  A0.store_be(out);
107  A1.store_be(out + 16);
108  A2.store_be(out + 32);
109  A3.store_be(out + 48);
110 
111  in += 64;
112  out += 64;
113  blocks -= 4;
114  }
115 
116  if(blocks)
117  Noekeon::encrypt_n(in, out, blocks);
118  }
119 
120 /*
121 * Noekeon Encryption
122 */
123 void Noekeon_SIMD::decrypt_n(const byte in[], byte out[], size_t blocks) const
124  {
125  const SecureVector<u32bit>& DK = this->get_DK();
126 
127  SIMD_32 K0 = SIMD_32(DK[0]);
128  SIMD_32 K1 = SIMD_32(DK[1]);
129  SIMD_32 K2 = SIMD_32(DK[2]);
130  SIMD_32 K3 = SIMD_32(DK[3]);
131 
132  while(blocks >= 4)
133  {
134  SIMD_32 A0 = SIMD_32::load_be(in );
135  SIMD_32 A1 = SIMD_32::load_be(in + 16);
136  SIMD_32 A2 = SIMD_32::load_be(in + 32);
137  SIMD_32 A3 = SIMD_32::load_be(in + 48);
138 
139  SIMD_32::transpose(A0, A1, A2, A3);
140 
141  for(size_t i = 0; i != 16; ++i)
142  {
143  NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3);
144 
145  A0 ^= SIMD_32(RC[16-i]);
146 
147  A1.rotate_left(1);
148  A2.rotate_left(5);
149  A3.rotate_left(2);
150 
151  NOK_SIMD_GAMMA(A0, A1, A2, A3);
152 
153  A1.rotate_right(1);
154  A2.rotate_right(5);
155  A3.rotate_right(2);
156  }
157 
158  NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3);
159  A0 ^= SIMD_32(RC[0]);
160 
161  SIMD_32::transpose(A0, A1, A2, A3);
162 
163  A0.store_be(out);
164  A1.store_be(out + 16);
165  A2.store_be(out + 32);
166  A3.store_be(out + 48);
167 
168  in += 64;
169  out += 64;
170  blocks -= 4;
171  }
172 
173  if(blocks)
174  Noekeon::decrypt_n(in, out, blocks);
175  }
176 
177 }
T load_be(const byte in[], size_t off)
Definition: loadstor.h:100
void encrypt_n(const byte in[], byte out[], size_t blocks) const
unsigned char byte
Definition: types.h:22
void encrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: noekeon.cpp:87
#define NOK_SIMD_GAMMA(A0, A1, A2, A3)
static const byte RC[17]
Definition: noekeon.h:33
const SecureVector< u32bit > & get_EK() const
Definition: noekeon.h:38
#define NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3)
void decrypt_n(const byte in[], byte out[], size_t blocks) const
void decrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: noekeon.cpp:125
const SecureVector< u32bit > & get_DK() const
Definition: noekeon.h:43