Botan  2.1.0
Crypto and TLS for C++11
serpent_simd.cpp
Go to the documentation of this file.
1 /*
2 * Serpent (SIMD)
3 * (C) 2009,2013 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/serpent.h>
9 #include <botan/internal/serpent_sbox.h>
10 #include <botan/internal/simd_32.h>
11 
12 namespace Botan {
13 
14 namespace {
15 
16 #define key_xor(round, B0, B1, B2, B3) \
17  do { \
18  B0 ^= SIMD_32::splat(m_round_key[4*round ]); \
19  B1 ^= SIMD_32::splat(m_round_key[4*round+1]); \
20  B2 ^= SIMD_32::splat(m_round_key[4*round+2]); \
21  B3 ^= SIMD_32::splat(m_round_key[4*round+3]); \
22  } while(0);
23 
24 /*
25 * Serpent's linear transformations
26 */
27 #define transform(B0, B1, B2, B3) \
28  do { \
29  B0.rotate_left(13); \
30  B2.rotate_left(3); \
31  B1 ^= B0 ^ B2; \
32  B3 ^= B2 ^ (B0 << 3); \
33  B1.rotate_left(1); \
34  B3.rotate_left(7); \
35  B0 ^= B1 ^ B3; \
36  B2 ^= B3 ^ (B1 << 7); \
37  B0.rotate_left(5); \
38  B2.rotate_left(22); \
39  } while(0);
40 
41 #define i_transform(B0, B1, B2, B3) \
42  do { \
43  B2.rotate_right(22); \
44  B0.rotate_right(5); \
45  B2 ^= B3 ^ (B1 << 7); \
46  B0 ^= B1 ^ B3; \
47  B3.rotate_right(7); \
48  B1.rotate_right(1); \
49  B3 ^= B2 ^ (B0 << 3); \
50  B1 ^= B0 ^ B2; \
51  B2.rotate_right(3); \
52  B0.rotate_right(13); \
53  } while(0);
54 
55 }
56 
57 /*
58 * SIMD Serpent Encryption of 4 blocks in parallel
59 */
60 void Serpent::simd_encrypt_4(const uint8_t in[64], uint8_t out[64]) const
61  {
62  SIMD_32 B0 = SIMD_32::load_le(in);
63  SIMD_32 B1 = SIMD_32::load_le(in + 16);
64  SIMD_32 B2 = SIMD_32::load_le(in + 32);
65  SIMD_32 B3 = SIMD_32::load_le(in + 48);
66 
67  SIMD_32::transpose(B0, B1, B2, B3);
68 
69  key_xor( 0,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
70  key_xor( 1,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
71  key_xor( 2,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
72  key_xor( 3,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
73  key_xor( 4,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
74  key_xor( 5,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
75  key_xor( 6,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
76  key_xor( 7,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
77 
78  key_xor( 8,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
79  key_xor( 9,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
80  key_xor(10,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
81  key_xor(11,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
82  key_xor(12,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
83  key_xor(13,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
84  key_xor(14,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
85  key_xor(15,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
86 
87  key_xor(16,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
88  key_xor(17,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
89  key_xor(18,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
90  key_xor(19,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
91  key_xor(20,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
92  key_xor(21,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
93  key_xor(22,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
94  key_xor(23,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
95 
96  key_xor(24,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
97  key_xor(25,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
98  key_xor(26,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
99  key_xor(27,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
100  key_xor(28,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
101  key_xor(29,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
102  key_xor(30,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
103  key_xor(31,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3);
104 
105  SIMD_32::transpose(B0, B1, B2, B3);
106 
107  B0.store_le(out);
108  B1.store_le(out + 16);
109  B2.store_le(out + 32);
110  B3.store_le(out + 48);
111  }
112 
113 /*
114 * SIMD Serpent Decryption of 4 blocks in parallel
115 */
116 void Serpent::simd_decrypt_4(const uint8_t in[64], uint8_t out[64]) const
117  {
118  SIMD_32 B0 = SIMD_32::load_le(in);
119  SIMD_32 B1 = SIMD_32::load_le(in + 16);
120  SIMD_32 B2 = SIMD_32::load_le(in + 32);
121  SIMD_32 B3 = SIMD_32::load_le(in + 48);
122 
123  SIMD_32::transpose(B0, B1, B2, B3);
124 
125  key_xor(32,B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(31,B0,B1,B2,B3);
126  i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(30,B0,B1,B2,B3);
127  i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(29,B0,B1,B2,B3);
128  i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(28,B0,B1,B2,B3);
129  i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(27,B0,B1,B2,B3);
130  i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(26,B0,B1,B2,B3);
131  i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(25,B0,B1,B2,B3);
132  i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(24,B0,B1,B2,B3);
133 
134  i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(23,B0,B1,B2,B3);
135  i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(22,B0,B1,B2,B3);
136  i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(21,B0,B1,B2,B3);
137  i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(20,B0,B1,B2,B3);
138  i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(19,B0,B1,B2,B3);
139  i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(18,B0,B1,B2,B3);
140  i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(17,B0,B1,B2,B3);
141  i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(16,B0,B1,B2,B3);
142 
143  i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(15,B0,B1,B2,B3);
144  i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(14,B0,B1,B2,B3);
145  i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(13,B0,B1,B2,B3);
146  i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(12,B0,B1,B2,B3);
147  i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(11,B0,B1,B2,B3);
148  i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(10,B0,B1,B2,B3);
149  i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 9,B0,B1,B2,B3);
150  i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 8,B0,B1,B2,B3);
151 
152  i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor( 7,B0,B1,B2,B3);
153  i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor( 6,B0,B1,B2,B3);
154  i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor( 5,B0,B1,B2,B3);
155  i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor( 4,B0,B1,B2,B3);
156  i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor( 3,B0,B1,B2,B3);
157  i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor( 2,B0,B1,B2,B3);
158  i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 1,B0,B1,B2,B3);
159  i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 0,B0,B1,B2,B3);
160 
161  SIMD_32::transpose(B0, B1, B2, B3);
162 
163  B0.store_le(out);
164  B1.store_le(out + 16);
165  B2.store_le(out + 32);
166  B3.store_le(out + 48);
167  }
168 
169 #undef key_xor
170 #undef transform
171 #undef i_transform
172 
173 }
#define i_transform(B0, B1, B2, B3)
#define SBoxE5(B0, B1, B2, B3)
Definition: serpent_sbox.h:114
#define SBoxD4(B0, B1, B2, B3)
Definition: serpent_sbox.h:297
static SIMD_4x32 load_le(const void *in)
Definition: simd_32.h:128
#define SBoxE1(B0, B1, B2, B3)
Definition: serpent_sbox.h:14
#define SBoxD2(B0, B1, B2, B3)
Definition: serpent_sbox.h:244
#define SBoxD6(B0, B1, B2, B3)
Definition: serpent_sbox.h:349
#define key_xor(round, B0, B1, B2, B3)
void simd_encrypt_4(const uint8_t in[64], uint8_t out[64]) const
static void transpose(SIMD_4x32 &B0, SIMD_4x32 &B1, SIMD_4x32 &B2, SIMD_4x32 &B3)
Definition: simd_32.h:564
#define SBoxE2(B0, B1, B2, B3)
Definition: serpent_sbox.h:39
#define SBoxE6(B0, B1, B2, B3)
Definition: serpent_sbox.h:141
#define SBoxE7(B0, B1, B2, B3)
Definition: serpent_sbox.h:168
#define SBoxE3(B0, B1, B2, B3)
Definition: serpent_sbox.h:65
void store_le(uint8_t out[]) const
Definition: simd_32.h:209
Definition: alg_id.cpp:13
#define SBoxD1(B0, B1, B2, B3)
Definition: serpent_sbox.h:219
void simd_decrypt_4(const uint8_t in[64], uint8_t out[64]) const
#define SBoxD3(B0, B1, B2, B3)
Definition: serpent_sbox.h:272
#define SBoxE4(B0, B1, B2, B3)
Definition: serpent_sbox.h:88
#define SBoxD8(B0, B1, B2, B3)
Definition: serpent_sbox.h:401
#define SBoxE8(B0, B1, B2, B3)
Definition: serpent_sbox.h:191
#define SBoxD7(B0, B1, B2, B3)
Definition: serpent_sbox.h:377
#define transform(B0, B1, B2, B3)
#define SBoxD5(B0, B1, B2, B3)
Definition: serpent_sbox.h:323