1 /*
2 * (C) 2018 Jack Lloyd
3 *
4 * Botan is released under the Simplified BSD License (see license.txt)
5 */
6
7 #include <botan/serpent.h>
8 #include <botan/internal/serpent_sbox.h>
9 #include <botan/internal/simd_avx2.h>
10
11 namespace Botan {
12
13
14 #define key_xor(round, B0, B1, B2, B3) \
15 do { \
16 B0 ^= SIMD_8x32::splat(m_round_key[4*round ]); \
17 B1 ^= SIMD_8x32::splat(m_round_key[4*round+1]); \
18 B2 ^= SIMD_8x32::splat(m_round_key[4*round+2]); \
19 B3 ^= SIMD_8x32::splat(m_round_key[4*round+3]); \
20 } while(0)
21
22 /*
23 * Serpent's linear transformations
24 */
25 #define transform(B0, B1, B2, B3) \
26 do { \
27 B0 = B0.rotl<13>(); \
28 B2 = B2.rotl<3>(); \
29 B1 ^= B0 ^ B2; \
30 B3 ^= B2 ^ B0.shl<3>(); \
31 B1 = B1.rotl<1>(); \
32 B3 = B3.rotl<7>(); \
33 B0 ^= B1 ^ B3; \
34 B2 ^= B3 ^ B1.shl<7>(); \
35 B0 = B0.rotl<5>(); \
36 B2 = B2.rotl<22>(); \
37 } while(0)
38
39 #define i_transform(B0, B1, B2, B3) \
40 do { \
41 B2 = B2.rotr<22>(); \
42 B0 = B0.rotr<5>(); \
43 B2 ^= B3 ^ B1.shl<7>(); \
44 B0 ^= B1 ^ B3; \
45 B3 = B3.rotr<7>(); \
46 B1 = B1.rotr<1>(); \
47 B3 ^= B2 ^ B0.shl<3>(); \
48 B1 ^= B0 ^ B2; \
49 B2 = B2.rotr<3>(); \
50 B0 = B0.rotr<13>(); \
51 } while(0)
52
53 BOTAN_FUNC_ISA("avx2")
avx2_encrypt_8(const uint8_t in[128],uint8_t out[128]) const54 void Serpent::avx2_encrypt_8(const uint8_t in[128], uint8_t out[128]) const
55 {
56 SIMD_8x32::reset_registers();
57
58 SIMD_8x32 B0 = SIMD_8x32::load_le(in);
59 SIMD_8x32 B1 = SIMD_8x32::load_le(in + 32);
60 SIMD_8x32 B2 = SIMD_8x32::load_le(in + 64);
61 SIMD_8x32 B3 = SIMD_8x32::load_le(in + 96);
62
63 SIMD_8x32::transpose(B0, B1, B2, B3);
64
65 key_xor( 0,B0,B1,B2,B3); SBoxE0(B0,B1,B2,B3); transform(B0,B1,B2,B3);
66 key_xor( 1,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
67 key_xor( 2,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
68 key_xor( 3,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
69 key_xor( 4,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
70 key_xor( 5,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
71 key_xor( 6,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
72 key_xor( 7,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
73 key_xor( 8,B0,B1,B2,B3); SBoxE0(B0,B1,B2,B3); transform(B0,B1,B2,B3);
74 key_xor( 9,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
75 key_xor(10,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
76 key_xor(11,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
77 key_xor(12,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
78 key_xor(13,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
79 key_xor(14,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
80 key_xor(15,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
81 key_xor(16,B0,B1,B2,B3); SBoxE0(B0,B1,B2,B3); transform(B0,B1,B2,B3);
82 key_xor(17,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
83 key_xor(18,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
84 key_xor(19,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
85 key_xor(20,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
86 key_xor(21,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
87 key_xor(22,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
88 key_xor(23,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
89 key_xor(24,B0,B1,B2,B3); SBoxE0(B0,B1,B2,B3); transform(B0,B1,B2,B3);
90 key_xor(25,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
91 key_xor(26,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
92 key_xor(27,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
93 key_xor(28,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
94 key_xor(29,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
95 key_xor(30,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
96 key_xor(31,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3);
97
98 SIMD_8x32::transpose(B0, B1, B2, B3);
99 B0.store_le(out);
100 B1.store_le(out + 32);
101 B2.store_le(out + 64);
102 B3.store_le(out + 96);
103
104 SIMD_8x32::zero_registers();
105 }
106
107 BOTAN_FUNC_ISA("avx2")
avx2_decrypt_8(const uint8_t in[128],uint8_t out[128]) const108 void Serpent::avx2_decrypt_8(const uint8_t in[128], uint8_t out[128]) const
109 {
110 SIMD_8x32::reset_registers();
111
112 SIMD_8x32 B0 = SIMD_8x32::load_le(in);
113 SIMD_8x32 B1 = SIMD_8x32::load_le(in + 32);
114 SIMD_8x32 B2 = SIMD_8x32::load_le(in + 64);
115 SIMD_8x32 B3 = SIMD_8x32::load_le(in + 96);
116
117 SIMD_8x32::transpose(B0, B1, B2, B3);
118
119 key_xor(32,B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(31,B0,B1,B2,B3);
120 i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(30,B0,B1,B2,B3);
121 i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(29,B0,B1,B2,B3);
122 i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(28,B0,B1,B2,B3);
123 i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(27,B0,B1,B2,B3);
124 i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(26,B0,B1,B2,B3);
125 i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(25,B0,B1,B2,B3);
126 i_transform(B0,B1,B2,B3); SBoxD0(B0,B1,B2,B3); key_xor(24,B0,B1,B2,B3);
127
128 i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(23,B0,B1,B2,B3);
129 i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(22,B0,B1,B2,B3);
130 i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(21,B0,B1,B2,B3);
131 i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(20,B0,B1,B2,B3);
132 i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(19,B0,B1,B2,B3);
133 i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(18,B0,B1,B2,B3);
134 i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(17,B0,B1,B2,B3);
135 i_transform(B0,B1,B2,B3); SBoxD0(B0,B1,B2,B3); key_xor(16,B0,B1,B2,B3);
136
137 i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(15,B0,B1,B2,B3);
138 i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(14,B0,B1,B2,B3);
139 i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(13,B0,B1,B2,B3);
140 i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(12,B0,B1,B2,B3);
141 i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(11,B0,B1,B2,B3);
142 i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(10,B0,B1,B2,B3);
143 i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 9,B0,B1,B2,B3);
144 i_transform(B0,B1,B2,B3); SBoxD0(B0,B1,B2,B3); key_xor( 8,B0,B1,B2,B3);
145
146 i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor( 7,B0,B1,B2,B3);
147 i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor( 6,B0,B1,B2,B3);
148 i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor( 5,B0,B1,B2,B3);
149 i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor( 4,B0,B1,B2,B3);
150 i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor( 3,B0,B1,B2,B3);
151 i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 2,B0,B1,B2,B3);
152 i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 1,B0,B1,B2,B3);
153 i_transform(B0,B1,B2,B3); SBoxD0(B0,B1,B2,B3); key_xor( 0,B0,B1,B2,B3);
154
155 SIMD_8x32::transpose(B0, B1, B2, B3);
156
157 B0.store_le(out);
158 B1.store_le(out + 32);
159 B2.store_le(out + 64);
160 B3.store_le(out + 96);
161
162 SIMD_8x32::zero_registers();
163 }
164
165 #undef key_xor
166 #undef transform
167 #undef i_transform
168
169 }
170