Botan 1.10.17
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
11namespace 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*/
66void 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*/
123void 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}
void encrypt_n(const byte in[], byte out[], size_t blocks) const
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
static const byte RC[17]
Definition noekeon.h:33
void encrypt_n(const byte in[], byte out[], size_t blocks) const
Definition noekeon.cpp:87
const SecureVector< u32bit > & get_EK() const
Definition noekeon.h:38
#define NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3)
#define NOK_SIMD_GAMMA(A0, A1, A2, A3)