Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

noekeon_simd.cpp
Go to the documentation of this file.
1 /*
2 * Noekeon in SIMD
3 * (C) 2010 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/noekeon.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_4(const uint8_t in[], uint8_t out[]) const
67 {
68 const SIMD_32 K0 = SIMD_32::splat(m_EK[0]);
69 const SIMD_32 K1 = SIMD_32::splat(m_EK[1]);
70 const SIMD_32 K2 = SIMD_32::splat(m_EK[2]);
71 const SIMD_32 K3 = SIMD_32::splat(m_EK[3]);
72
73 SIMD_32 A0 = SIMD_32::load_be(in );
74 SIMD_32 A1 = SIMD_32::load_be(in + 16);
75 SIMD_32 A2 = SIMD_32::load_be(in + 32);
76 SIMD_32 A3 = SIMD_32::load_be(in + 48);
77
78 SIMD_32::transpose(A0, A1, A2, A3);
79
80 for(size_t i = 0; i != 16; ++i)
81 {
82 A0 ^= SIMD_32::splat(RC[i]);
83
84 NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3);
85
86 A1.rotate_left(1);
87 A2.rotate_left(5);
88 A3.rotate_left(2);
89
90 NOK_SIMD_GAMMA(A0, A1, A2, A3);
91
92 A1.rotate_right(1);
93 A2.rotate_right(5);
94 A3.rotate_right(2);
95 }
96
97 A0 ^= SIMD_32::splat(RC[16]);
98 NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3);
99
100 SIMD_32::transpose(A0, A1, A2, A3);
101
102 A0.store_be(out);
103 A1.store_be(out + 16);
104 A2.store_be(out + 32);
105 A3.store_be(out + 48);
106 }
107
108 /*
109 * Noekeon Encryption
110 */
111 void Noekeon::simd_decrypt_4(const uint8_t in[], uint8_t out[]) const
112 {
113 const SIMD_32 K0 = SIMD_32::splat(m_DK[0]);
114 const SIMD_32 K1 = SIMD_32::splat(m_DK[1]);
115 const SIMD_32 K2 = SIMD_32::splat(m_DK[2]);
116 const SIMD_32 K3 = SIMD_32::splat(m_DK[3]);
117
118 SIMD_32 A0 = SIMD_32::load_be(in );
119 SIMD_32 A1 = SIMD_32::load_be(in + 16);
120 SIMD_32 A2 = SIMD_32::load_be(in + 32);
121 SIMD_32 A3 = SIMD_32::load_be(in + 48);
122
123 SIMD_32::transpose(A0, A1, A2, A3);
124
125 for(size_t i = 0; i != 16; ++i)
126 {
127 NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3);
128
129 A0 ^= SIMD_32::splat(RC[16-i]);
130
131 A1.rotate_left(1);
132 A2.rotate_left(5);
133 A3.rotate_left(2);
134
135 NOK_SIMD_GAMMA(A0, A1, A2, A3);
136
137 A1.rotate_right(1);
138 A2.rotate_right(5);
139 A3.rotate_right(2);
140 }
141
142 NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3);
143 A0 ^= SIMD_32::splat(RC[0]);
144
145 SIMD_32::transpose(A0, A1, A2, A3);
146
147 A0.store_be(out);
148 A1.store_be(out + 16);
149 A2.store_be(out + 32);
150 A3.store_be(out + 48);
151 }
152
153 }
Botan::SIMD_4x32::transpose
static void transpose(SIMD_4x32 &B0, SIMD_4x32 &B1, SIMD_4x32 &B2, SIMD_4x32 &B3)
Definition: simd_32.h:564
NOK_SIMD_GAMMA
#define NOK_SIMD_GAMMA(A0, A1, A2, A3)
Definition: noekeon_simd.cpp:47
Botan::SIMD_4x32::load_be
static SIMD_4x32 load_be(const void *in)
Definition: simd_32.h:168
Botan
Definition: alg_id.cpp:13
Botan::SIMD_4x32::splat
static SIMD_4x32 splat(uint32_t B)
Definition: simd_32.h:114
NOK_SIMD_THETA
#define NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3)
Definition: noekeon_simd.cpp:16
Botan::SIMD_32
SIMD_4x32 SIMD_32
Definition: simd_32.h:650