• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 4855067158

01 May 2023 10:17PM UTC coverage: 91.719% (-0.4%) from 92.147%
4855067158

push

github

77610 of 84617 relevant lines covered (91.72%)

11851668.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.75
/src/lib/block/serpent/serpent.cpp
1
/*
2
* Serpent
3
* (C) 1999-2007 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/internal/serpent.h>
9

10
#include <botan/internal/loadstor.h>
11
#include <botan/internal/rotate.h>
12
#include <botan/internal/serpent_sbox.h>
13

14
#if defined(BOTAN_HAS_SERPENT_SIMD) || defined(BOTAN_HAS_SERPENT_AVX2) || defined(BOTAN_HAS_SERPENT_AVX512)
15
  #include <botan/internal/cpuid.h>
16
#endif
17

18
namespace Botan {
19

20
/*
21
* Serpent Encryption
22
*/
23
void Serpent::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
25,700✔
24
   {
25
   using namespace Botan::Serpent_F;
25,700✔
26

27
   assert_key_material_set();
25,700✔
28

29
#if defined(BOTAN_HAS_SERPENT_AVX512)
30
   if(CPUID::has_avx512())
19,412✔
31
      {
32
      while(blocks >= 16)
×
33
         {
34
         avx512_encrypt_16(in, out);
×
35
         in += 16 * BLOCK_SIZE;
×
36
         out += 16 * BLOCK_SIZE;
×
37
         blocks -= 16;
×
38
         }
39
      }
40
#endif
41

42
#if defined(BOTAN_HAS_SERPENT_AVX2)
43
   if(CPUID::has_avx2())
19,412✔
44
      {
45
      while(blocks >= 8)
16,782✔
46
         {
47
         avx2_encrypt_8(in, out);
3,646✔
48
         in += 8 * BLOCK_SIZE;
3,646✔
49
         out += 8 * BLOCK_SIZE;
3,646✔
50
         blocks -= 8;
3,646✔
51
         }
52
      }
53
#endif
54

55
#if defined(BOTAN_HAS_SERPENT_SIMD)
56
   if(CPUID::has_simd_32())
19,412✔
57
      {
58
      while(blocks >= 4)
16,780✔
59
         {
60
         simd_encrypt_4(in, out);
506✔
61
         in += 4 * BLOCK_SIZE;
506✔
62
         out += 4 * BLOCK_SIZE;
506✔
63
         blocks -= 4;
506✔
64
         }
65
      }
66
#endif
67

68
   const Key_Inserter key_xor(m_round_key.data());
19,412✔
69

70
   BOTAN_PARALLEL_SIMD_FOR(size_t i = 0; i < blocks; ++i)
37,859✔
71
      {
72
      uint32_t B0, B1, B2, B3;
18,447✔
73
      load_le(in + 16*i, B0, B1, B2, B3);
18,447✔
74

75
      key_xor( 0,B0,B1,B2,B3); SBoxE0(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
76
      key_xor( 1,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
77
      key_xor( 2,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
78
      key_xor( 3,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
79
      key_xor( 4,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
80
      key_xor( 5,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
81
      key_xor( 6,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
82
      key_xor( 7,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
83
      key_xor( 8,B0,B1,B2,B3); SBoxE0(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
84
      key_xor( 9,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
85
      key_xor(10,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
86
      key_xor(11,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
87
      key_xor(12,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
88
      key_xor(13,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
89
      key_xor(14,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
90
      key_xor(15,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
91
      key_xor(16,B0,B1,B2,B3); SBoxE0(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
92
      key_xor(17,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
93
      key_xor(18,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
94
      key_xor(19,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
95
      key_xor(20,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
96
      key_xor(21,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
97
      key_xor(22,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
98
      key_xor(23,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
99
      key_xor(24,B0,B1,B2,B3); SBoxE0(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
100
      key_xor(25,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
101
      key_xor(26,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
102
      key_xor(27,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
103
      key_xor(28,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
104
      key_xor(29,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
105
      key_xor(30,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
18,447✔
106
      key_xor(31,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3);
18,447✔
107

108
      store_le(out + 16*i, B0, B1, B2, B3);
18,447✔
109
      }
110
   }
19,412✔
111

112
/*
113
* Serpent Decryption
114
*/
115
void Serpent::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
17,723✔
116
   {
117
   using namespace Botan::Serpent_F;
17,723✔
118

119
   assert_key_material_set();
17,723✔
120

121
#if defined(BOTAN_HAS_SERPENT_AVX512)
122
   if(CPUID::has_avx512())
11,447✔
123
      {
124
      while(blocks >= 16)
×
125
         {
126
         avx512_decrypt_16(in, out);
×
127
         in += 16 * BLOCK_SIZE;
×
128
         out += 16 * BLOCK_SIZE;
×
129
         blocks -= 16;
×
130
         }
131
      }
132
#endif
133

134
#if defined(BOTAN_HAS_SERPENT_AVX2)
135
   if(CPUID::has_avx2())
11,447✔
136
      {
137
      while(blocks >= 8)
7,799✔
138
         {
139
         avx2_decrypt_8(in, out);
536✔
140
         in += 8 * BLOCK_SIZE;
536✔
141
         out += 8 * BLOCK_SIZE;
536✔
142
         blocks -= 8;
536✔
143
         }
144
      }
145
#endif
146

147
#if defined(BOTAN_HAS_SERPENT_SIMD)
148
   if(CPUID::has_simd_32())
11,447✔
149
      {
150
      while(blocks >= 4)
9,861✔
151
         {
152
         simd_decrypt_4(in, out);
506✔
153
         in += 4 * BLOCK_SIZE;
506✔
154
         out += 4 * BLOCK_SIZE;
506✔
155
         blocks -= 4;
506✔
156
         }
157
      }
158
#endif
159

160
   const Key_Inserter key_xor(m_round_key.data());
11,447✔
161

162
   BOTAN_PARALLEL_SIMD_FOR(size_t i = 0; i < blocks; ++i)
23,484✔
163
      {
164
      uint32_t B0, B1, B2, B3;
12,037✔
165
      load_le(in + 16*i, B0, B1, B2, B3);
12,037✔
166

167
      key_xor(32,B0,B1,B2,B3);  SBoxD7(B0,B1,B2,B3); key_xor(31,B0,B1,B2,B3);
12,037✔
168
      i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(30,B0,B1,B2,B3);
12,037✔
169
      i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(29,B0,B1,B2,B3);
12,037✔
170
      i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(28,B0,B1,B2,B3);
12,037✔
171
      i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(27,B0,B1,B2,B3);
12,037✔
172
      i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(26,B0,B1,B2,B3);
12,037✔
173
      i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(25,B0,B1,B2,B3);
12,037✔
174
      i_transform(B0,B1,B2,B3); SBoxD0(B0,B1,B2,B3); key_xor(24,B0,B1,B2,B3);
12,037✔
175
      i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(23,B0,B1,B2,B3);
12,037✔
176
      i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(22,B0,B1,B2,B3);
12,037✔
177
      i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(21,B0,B1,B2,B3);
12,037✔
178
      i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(20,B0,B1,B2,B3);
12,037✔
179
      i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(19,B0,B1,B2,B3);
12,037✔
180
      i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(18,B0,B1,B2,B3);
12,037✔
181
      i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(17,B0,B1,B2,B3);
12,037✔
182
      i_transform(B0,B1,B2,B3); SBoxD0(B0,B1,B2,B3); key_xor(16,B0,B1,B2,B3);
12,037✔
183
      i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(15,B0,B1,B2,B3);
12,037✔
184
      i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(14,B0,B1,B2,B3);
12,037✔
185
      i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(13,B0,B1,B2,B3);
12,037✔
186
      i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(12,B0,B1,B2,B3);
12,037✔
187
      i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(11,B0,B1,B2,B3);
12,037✔
188
      i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(10,B0,B1,B2,B3);
12,037✔
189
      i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 9,B0,B1,B2,B3);
12,037✔
190
      i_transform(B0,B1,B2,B3); SBoxD0(B0,B1,B2,B3); key_xor( 8,B0,B1,B2,B3);
12,037✔
191
      i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor( 7,B0,B1,B2,B3);
12,037✔
192
      i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor( 6,B0,B1,B2,B3);
12,037✔
193
      i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor( 5,B0,B1,B2,B3);
12,037✔
194
      i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor( 4,B0,B1,B2,B3);
12,037✔
195
      i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor( 3,B0,B1,B2,B3);
12,037✔
196
      i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 2,B0,B1,B2,B3);
12,037✔
197
      i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 1,B0,B1,B2,B3);
12,037✔
198
      i_transform(B0,B1,B2,B3); SBoxD0(B0,B1,B2,B3); key_xor( 0,B0,B1,B2,B3);
12,037✔
199

200
      store_le(out + 16*i, B0, B1, B2, B3);
12,037✔
201
      }
202
   }
11,447✔
203

204
bool Serpent::has_keying_material() const
61,699✔
205
   {
206
   return !m_round_key.empty();
61,699✔
207
   }
208

209
/*
210
* Serpent Key Schedule
211
*/
212
void Serpent::key_schedule(const uint8_t key[], size_t length)
12,899✔
213
   {
214
   using namespace Botan::Serpent_F;
12,899✔
215

216
   const uint32_t PHI = 0x9E3779B9;
12,899✔
217

218
   secure_vector<uint32_t> W(140);
12,899✔
219
   for(size_t i = 0; i != length / 4; ++i)
110,913✔
220
      W[i] = load_le<uint32_t>(key, i);
98,014✔
221

222
   W[length / 4] |= uint32_t(1) << ((length%4)*8);
12,899✔
223

224
   for(size_t i = 8; i != 140; ++i)
1,715,567✔
225
      {
226
      uint32_t wi = W[i-8] ^ W[i-5] ^ W[i-3] ^ W[i-1] ^ PHI ^ uint32_t(i-8);
1,702,668✔
227
      W[i] = rotl<11>(wi);
1,702,668✔
228
      }
229

230
   SBoxE0(W[ 20],W[ 21],W[ 22],W[ 23]);
12,899✔
231
   SBoxE0(W[ 52],W[ 53],W[ 54],W[ 55]);
12,899✔
232
   SBoxE0(W[ 84],W[ 85],W[ 86],W[ 87]);
12,899✔
233
   SBoxE0(W[116],W[117],W[118],W[119]);
12,899✔
234

235
   SBoxE1(W[ 16],W[ 17],W[ 18],W[ 19]);
12,899✔
236
   SBoxE1(W[ 48],W[ 49],W[ 50],W[ 51]);
12,899✔
237
   SBoxE1(W[ 80],W[ 81],W[ 82],W[ 83]);
12,899✔
238
   SBoxE1(W[112],W[113],W[114],W[115]);
12,899✔
239

240
   SBoxE2(W[ 12],W[ 13],W[ 14],W[ 15]);
12,899✔
241
   SBoxE2(W[ 44],W[ 45],W[ 46],W[ 47]);
12,899✔
242
   SBoxE2(W[ 76],W[ 77],W[ 78],W[ 79]);
12,899✔
243
   SBoxE2(W[108],W[109],W[110],W[111]);
12,899✔
244

245
   SBoxE3(W[  8],W[  9],W[ 10],W[ 11]);
12,899✔
246
   SBoxE3(W[ 40],W[ 41],W[ 42],W[ 43]);
12,899✔
247
   SBoxE3(W[ 72],W[ 73],W[ 74],W[ 75]);
12,899✔
248
   SBoxE3(W[104],W[105],W[106],W[107]);
12,899✔
249
   SBoxE3(W[136],W[137],W[138],W[139]);
12,899✔
250

251
   SBoxE4(W[ 36],W[ 37],W[ 38],W[ 39]);
12,899✔
252
   SBoxE4(W[ 68],W[ 69],W[ 70],W[ 71]);
12,899✔
253
   SBoxE4(W[100],W[101],W[102],W[103]);
12,899✔
254
   SBoxE4(W[132],W[133],W[134],W[135]);
12,899✔
255

256
   SBoxE5(W[ 32],W[ 33],W[ 34],W[ 35]);
12,899✔
257
   SBoxE5(W[ 64],W[ 65],W[ 66],W[ 67]);
12,899✔
258
   SBoxE5(W[ 96],W[ 97],W[ 98],W[ 99]);
12,899✔
259
   SBoxE5(W[128],W[129],W[130],W[131]);
12,899✔
260

261
   SBoxE6(W[ 28],W[ 29],W[ 30],W[ 31]);
12,899✔
262
   SBoxE6(W[ 60],W[ 61],W[ 62],W[ 63]);
12,899✔
263
   SBoxE6(W[ 92],W[ 93],W[ 94],W[ 95]);
12,899✔
264
   SBoxE6(W[124],W[125],W[126],W[127]);
12,899✔
265

266
   SBoxE7(W[ 24],W[ 25],W[ 26],W[ 27]);
12,899✔
267
   SBoxE7(W[ 56],W[ 57],W[ 58],W[ 59]);
12,899✔
268
   SBoxE7(W[ 88],W[ 89],W[ 90],W[ 91]);
12,899✔
269
   SBoxE7(W[120],W[121],W[122],W[123]);
12,899✔
270

271
   m_round_key.assign(W.begin() + 8, W.end());
12,899✔
272
   }
12,899✔
273

274
void Serpent::clear()
7,431✔
275
   {
276
   zap(m_round_key);
7,431✔
277
   }
7,431✔
278

279
std::string Serpent::provider() const
3,138✔
280
   {
281
#if defined(BOTAN_HAS_SERPENT_AVX512)
282
   if(CPUID::has_avx512())
3,138✔
283
      {
284
      return "avx512";
×
285
      }
286
#endif
287

288
#if defined(BOTAN_HAS_SERPENT_AVX2)
289
   if(CPUID::has_avx2())
3,138✔
290
      {
291
      return "avx2";
1,046✔
292
      }
293
#endif
294

295
#if defined(BOTAN_HAS_SERPENT_SIMD)
296
   if(CPUID::has_simd_32())
2,092✔
297
      {
298
      return "simd";
1,046✔
299
      }
300
#endif
301

302
   return "base";
1,046✔
303
   }
304

305
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc