serpent.c
Go to the documentation of this file.
1 /**
2  * @file serpent.c
3  * @brief Serpent encryption algorithm
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @section Description
28  *
29  * Serpent is a block cipher algorithm which supports a key size of 128, 192
30  * or 256 bits. S-box functions are implemented as per Dag Arne Osvik's
31  * paper "Speeding up Serpent"
32  *
33  * @author Oryx Embedded SARL (www.oryx-embedded.com)
34  * @version 2.4.0
35  **/
36 
37 //Switch to the appropriate trace level
38 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
39 
40 //Dependencies
41 #include "core/crypto.h"
42 #include "cipher/serpent.h"
43 
44 //Check crypto library configuration
45 #if (SERPENT_SUPPORT == ENABLED)
46 
47 //Golden ration
48 #define PHI 0x9E3779B9
49 
50 //S-box 0
51 #define SBOX0(r0, r1, r2, r3) \
52 { \
53  uint32_t r4; \
54  r3 ^= r0; r4 = r1; \
55  r1 &= r3; r4 ^= r2; \
56  r1 ^= r0; r0 |= r3; \
57  r0 ^= r4; r4 ^= r3; \
58  r3 ^= r2; r2 |= r1; \
59  r2 ^= r4; r4 = ~r4; \
60  r4 |= r1; r1 ^= r3; \
61  r1 ^= r4; r3 |= r0; \
62  r1 ^= r3; r4 ^= r3; \
63  r3 = r0; r0 = r1; r1 = r4; \
64 }
65 
66 //Inverse S-box 0
67 #define SBOX0_INV(r0, r1, r2, r3) \
68 { \
69  uint32_t r4; \
70  r2 = ~r2; r4 = r1; \
71  r1 |= r0; r4 = ~r4; \
72  r1 ^= r2; r2 |= r4; \
73  r1 ^= r3; r0 ^= r4; \
74  r2 ^= r0; r0 &= r3; \
75  r4 ^= r0; r0 |= r1; \
76  r0 ^= r2; r3 ^= r4; \
77  r2 ^= r1; r3 ^= r0; \
78  r3 ^= r1; \
79  r2 &= r3; \
80  r4 ^= r2; \
81  r2 = r1; r1 = r4; \
82 }
83 
84 //S-box 1
85 #define SBOX1(r0, r1, r2, r3) \
86 { \
87  uint32_t r4; \
88  r0 = ~r0; r2 = ~r2; \
89  r4 = r0; r0 &= r1; \
90  r2 ^= r0; r0 |= r3; \
91  r3 ^= r2; r1 ^= r0; \
92  r0 ^= r4; r4 |= r1; \
93  r1 ^= r3; r2 |= r0; \
94  r2 &= r4; r0 ^= r1; \
95  r1 &= r2; \
96  r1 ^= r0; r0 &= r2; \
97  r0 ^= r4; \
98  r4 = r0; r0 = r2; r2 = r3; r3 = r1; r1 = r4; \
99 }
100 
101 //Inverse S-box 1
102 #define SBOX1_INV(r0, r1, r2, r3) \
103 { \
104  uint32_t r4; \
105  r4 = r1; r1 ^= r3; \
106  r3 &= r1; r4 ^= r2; \
107  r3 ^= r0; r0 |= r1; \
108  r2 ^= r3; r0 ^= r4; \
109  r0 |= r2; r1 ^= r3; \
110  r0 ^= r1; r1 |= r3; \
111  r1 ^= r0; r4 = ~r4; \
112  r4 ^= r1; r1 |= r0; \
113  r1 ^= r0; \
114  r1 |= r4; \
115  r3 ^= r1; \
116  r1 = r0; r0 = r4; r4 = r2; r2 = r3; r3 = r4; \
117 }
118 
119 //S-box 2
120 #define SBOX2(r0, r1, r2, r3) \
121 { \
122  uint32_t r4; \
123  r4 = r0; r0 &= r2; \
124  r0 ^= r3; r2 ^= r1; \
125  r2 ^= r0; r3 |= r4; \
126  r3 ^= r1; r4 ^= r2; \
127  r1 = r3; r3 |= r4; \
128  r3 ^= r0; r0 &= r1; \
129  r4 ^= r0; r1 ^= r3; \
130  r1 ^= r4; r4 = ~r4; \
131  r0 = r2; r2 = r1; r1 = r3; r3 = r4; \
132 }
133 
134 //Inverse S-box 2
135 #define SBOX2_INV(r0, r1, r2, r3) \
136 { \
137  uint32_t r4; \
138  r2 ^= r3; r3 ^= r0; \
139  r4 = r3; r3 &= r2; \
140  r3 ^= r1; r1 |= r2; \
141  r1 ^= r4; r4 &= r3; \
142  r2 ^= r3; r4 &= r0; \
143  r4 ^= r2; r2 &= r1; \
144  r2 |= r0; r3 = ~r3; \
145  r2 ^= r3; r0 ^= r3; \
146  r0 &= r1; r3 ^= r4; \
147  r3 ^= r0; \
148  r0 = r1; r1 = r4; \
149 }
150 
151 //S-box 3
152 #define SBOX3(r0, r1, r2, r3) \
153 { \
154  uint32_t r4; \
155  r4 = r0; r0 |= r3; \
156  r3 ^= r1; r1 &= r4; \
157  r4 ^= r2; r2 ^= r3; \
158  r3 &= r0; r4 |= r1; \
159  r3 ^= r4; r0 ^= r1; \
160  r4 &= r0; r1 ^= r3; \
161  r4 ^= r2; r1 |= r0; \
162  r1 ^= r2; r0 ^= r3; \
163  r2 = r1; r1 |= r3; \
164  r1 ^= r0; \
165  r0 = r1; r1 = r2; r2 = r3; r3 = r4; \
166 }
167 
168 //Inverse S-box 3
169 #define SBOX3_INV(r0, r1, r2, r3) \
170 { \
171  uint32_t r4; \
172  r4 = r2; r2 ^= r1; \
173  r0 ^= r2; r4 &= r2; \
174  r4 ^= r0; r0 &= r1; \
175  r1 ^= r3; r3 |= r4; \
176  r2 ^= r3; r0 ^= r3; \
177  r1 ^= r4; r3 &= r2; \
178  r3 ^= r1; r1 ^= r0; \
179  r1 |= r2; r0 ^= r3; \
180  r1 ^= r4; \
181  r0 ^= r1; \
182  r4 = r0; r0 = r2; r2 = r3; r3 = r4; \
183 }
184 
185 //S-box 4
186 #define SBOX4(r0, r1, r2, r3) \
187 { \
188  uint32_t r4; \
189  r1 ^= r3; r3 = ~r3; \
190  r2 ^= r3; r3 ^= r0; \
191  r4 = r1; r1 &= r3; \
192  r1 ^= r2; r4 ^= r3; \
193  r0 ^= r4; r2 &= r4; \
194  r2 ^= r0; r0 &= r1; \
195  r3 ^= r0; r4 |= r1; \
196  r4 ^= r0; r0 |= r3; \
197  r0 ^= r2; r2 &= r3; \
198  r0 = ~r0; r4 ^= r2; \
199  r2 = r0; r0 = r1; r1 = r4; \
200 }
201 
202 
203 //Inverse S-box 4
204 #define SBOX4_INV(r0, r1, r2, r3) \
205 { \
206  uint32_t r4; \
207  r4 = r2; r2 &= r3; \
208  r2 ^= r1; r1 |= r3; \
209  r1 &= r0; r4 ^= r2; \
210  r4 ^= r1; r1 &= r2; \
211  r0 = ~r0; r3 ^= r4; \
212  r1 ^= r3; r3 &= r0; \
213  r3 ^= r2; r0 ^= r1; \
214  r2 &= r0; r3 ^= r0; \
215  r2 ^= r4; \
216  r2 |= r3; r3 ^= r0; \
217  r2 ^= r1; \
218  r1 = r3; r3 = r4; \
219 }
220 
221 //S-box 5
222 #define SBOX5(r0, r1, r2, r3) \
223 { \
224  uint32_t r4; \
225  r0 ^= r1; r1 ^= r3; \
226  r3 = ~r3; r4 = r1; \
227  r1 &= r0; r2 ^= r3; \
228  r1 ^= r2; r2 |= r4; \
229  r4 ^= r3; r3 &= r1; \
230  r3 ^= r0; r4 ^= r1; \
231  r4 ^= r2; r2 ^= r0; \
232  r0 &= r3; r2 = ~r2; \
233  r0 ^= r4; r4 |= r3; \
234  r2 ^= r4; \
235  r4 = r0; r0 = r1; r1 = r3; r3 = r2; r2 = r4; \
236 }
237 
238 //Inverse S-box 5
239 #define SBOX5_INV(r0, r1, r2, r3) \
240 { \
241  uint32_t r4; \
242  r1 = ~r1; r4 = r3; \
243  r2 ^= r1; r3 |= r0; \
244  r3 ^= r2; r2 |= r1; \
245  r2 &= r0; r4 ^= r3; \
246  r2 ^= r4; r4 |= r0; \
247  r4 ^= r1; r1 &= r2; \
248  r1 ^= r3; r4 ^= r2; \
249  r3 &= r4; r4 ^= r1; \
250  r3 ^= r4; r4 = ~r4; \
251  r3 ^= r0; \
252  r0 = r1; r1 = r4; r4 = r2; r2 = r3; r3 = r4; \
253 }
254 
255 //S-box 6
256 #define SBOX6(r0, r1, r2, r3) \
257 { \
258  uint32_t r4; \
259  r2 = ~r2; r4 = r3; \
260  r3 &= r0; r0 ^= r4; \
261  r3 ^= r2; r2 |= r4; \
262  r1 ^= r3; r2 ^= r0; \
263  r0 |= r1; r2 ^= r1; \
264  r4 ^= r0; r0 |= r3; \
265  r0 ^= r2; r4 ^= r3; \
266  r4 ^= r0; r3 = ~r3; \
267  r2 &= r4; \
268  r2 ^= r3; \
269  r3 = r2; r2 = r4; \
270 }
271 
272 //Inverse S-box 6
273 #define SBOX6_INV(r0, r1, r2, r3) \
274 { \
275  uint32_t r4; \
276  r0 ^= r2; r4 = r2; \
277  r2 &= r0; r4 ^= r3; \
278  r2 = ~r2; r3 ^= r1; \
279  r2 ^= r3; r4 |= r0; \
280  r0 ^= r2; r3 ^= r4; \
281  r4 ^= r1; r1 &= r3; \
282  r1 ^= r0; r0 ^= r3; \
283  r0 |= r2; r3 ^= r1; \
284  r4 ^= r0; \
285  r0 = r1; r1 = r2; r2 = r4; \
286 }
287 
288 //S-box 7
289 #define SBOX7(r0, r1, r2, r3) \
290 { \
291  uint32_t r4; \
292  r4 = r1; r1 |= r2; \
293  r1 ^= r3; r4 ^= r2; \
294  r2 ^= r1; r3 |= r4; \
295  r3 &= r0; r4 ^= r2; \
296  r3 ^= r1; r1 |= r4; \
297  r1 ^= r0; r0 |= r4; \
298  r0 ^= r2; r1 ^= r4; \
299  r2 ^= r1; r1 &= r0; \
300  r1 ^= r4; r2 = ~r2; \
301  r2 |= r0; \
302  r4 ^= r2; \
303  r2 = r1; r1 = r3; r3 = r0; r0 = r4; \
304 }
305 
306 //Inverse S-box 7
307 #define SBOX7_INV(r0, r1, r2, r3) \
308 { \
309  uint32_t r4; \
310  r4 = r2; r2 ^= r0; \
311  r0 &= r3; r4 |= r3; \
312  r2 = ~r2; r3 ^= r1; \
313  r1 |= r0; r0 ^= r2; \
314  r2 &= r4; r3 &= r4; \
315  r1 ^= r2; r2 ^= r0; \
316  r0 |= r2; r4 ^= r1; \
317  r0 ^= r3; r3 ^= r4; \
318  r4 |= r0; r3 ^= r2; \
319  r4 ^= r2; \
320  r2 = r1; r1 = r0; r0 = r3; r3 = r4; \
321 }
322 
323 //Linear transformation
324 #define LT(x0, x1, x2, x3) \
325 { \
326  x0 = ROL32(x0, 13); \
327  x2 = ROL32(x2, 3); \
328  x1 ^= x0 ^ x2; \
329  x3 ^= x2 ^ (x0 << 3); \
330  x1 = ROL32(x1, 1); \
331  x3 = ROL32(x3, 7); \
332  x0 ^= x1 ^ x3; \
333  x2 ^= x3 ^ (x1 << 7); \
334  x0 = ROL32(x0, 5); \
335  x2 = ROL32(x2, 22); \
336 }
337 
338 //Inverse linear transformation
339 #define LT_INV(x0, x1, x2, x3) \
340 { \
341  x2 = ROR32(x2, 22); \
342  x0 = ROR32(x0, 5); \
343  x2 ^= x3 ^ (x1 << 7); \
344  x0 ^= x1 ^ x3; \
345  x3 = ROR32(x3, 7); \
346  x1 = ROR32(x1, 1); \
347  x3 ^= x2 ^ (x0 << 3); \
348  x1 ^= x0 ^ x2; \
349  x2 = ROR32(x2, 3); \
350  x0 = ROR32(x0, 13); \
351 }
352 
353 //XOR operation
354 #define XOR(x0, x1, x2, x3, k) \
355 { \
356  x0 ^= k[0]; \
357  x1 ^= k[1]; \
358  x2 ^= k[2]; \
359  x3 ^= k[3]; \
360 }
361 
362 //Encryption round
363 #define ROUND(n, x0, x1, x2, x3, k) \
364 { \
365  XOR(x0, x1, x2, x3, k); \
366  SBOX##n(x0, x1, x2, x3); \
367  LT(x0, x1, x2, x3); \
368 }
369 
370 //Decryption round
371 #define ROUND_INV(n, x0, x1, x2, x3, k) \
372 { \
373  LT_INV(x0, x1, x2, x3); \
374  SBOX##n##_INV(x0, x1, x2, x3); \
375  XOR(x0, x1, x2, x3, k); \
376 }
377 
378 //Common interface for encryption algorithms
380 {
381  "Serpent",
382  sizeof(SerpentContext),
386  NULL,
387  NULL,
391 };
392 
393 
394 /**
395  * @brief Key expansion
396  * @param[in] context Pointer to the Serpent context to initialize
397  * @param[in] key Pointer to the key
398  * @param[in] keyLen Length of the key
399  * @return Error code
400  **/
401 
402 error_t serpentInit(SerpentContext *context, const uint8_t *key, size_t keyLen)
403 {
404  uint_t i;
405  uint32_t t;
406  uint32_t *w;
407  uint32_t p[8];
408 
409  //Check parameters
410  if(context == NULL || key == NULL)
412 
413  //Check the length of the key
414  if(keyLen != 16 && keyLen != 24 && keyLen != 32)
416 
417  //Determine the number of 32-bit words in the key
418  keyLen /= 4;
419 
420  //Copy the original key
421  for(i = 0; i < keyLen; i++)
422  {
423  p[i] = LOAD32LE(key + 4 * i);
424  }
425 
426  //Short keys with less than 256 bits are mapped to full-length keys of 256
427  //bits by appending one '1' bit to the MSB end
428  if(i < 8)
429  {
430  p[i++] = 0x00000001;
431  }
432 
433  //Append as many '0' bits as required to make up 256 bits
434  while(i < 8)
435  {
436  p[i++] = 0;
437  }
438 
439  //Point to the intermediate prekey
440  w = (uint32_t *) context->k;
441 
442  //Generate the first 8 words of the prekey
443  t = p[0] ^ p[3] ^ p[5] ^ p[7] ^ PHI ^ 0;
444  w[0] = ROL32(t, 11);
445  t = p[1] ^ p[4] ^ p[6] ^ w[0] ^ PHI ^ 1;
446  w[1] = ROL32(t, 11);
447  t = p[2] ^ p[5] ^ p[7] ^ w[1] ^ PHI ^ 2;
448  w[2] = ROL32(t, 11);
449  t = p[3] ^ p[6] ^ w[0] ^ w[2] ^ PHI ^ 3;
450  w[3] = ROL32(t, 11);
451  t = p[4] ^ p[7] ^ w[1] ^ w[3] ^ PHI ^ 4;
452  w[4] = ROL32(t, 11);
453  t = p[5] ^ w[0] ^ w[2] ^ w[4] ^ PHI ^ 5;
454  w[5] = ROL32(t, 11);
455  t = p[6] ^ w[1] ^ w[3] ^ w[5] ^ PHI ^ 6;
456  w[6] = ROL32(t, 11);
457  t = p[7] ^ w[2] ^ w[4] ^ w[6] ^ PHI ^ 7;
458  w[7] = ROL32(t, 11);
459 
460  //Expand the prekey using affine recurrence
461  for(i = 8; i < 132; i++)
462  {
463  t = w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i;
464  w[i] = ROL32(t, 11);
465  }
466 
467  //The round keys are now calculated from the prekeys using the S-boxes
468  for(i = 0; i < 128; i += 32)
469  {
470  SBOX3(w[i + 0], w[i + 1], w[i + 2], w[i + 3]);
471  SBOX2(w[i + 4], w[i + 5], w[i + 6], w[i + 7]);
472  SBOX1(w[i + 8], w[i + 9], w[i + 10], w[i + 11]);
473  SBOX0(w[i + 12], w[i + 13], w[i + 14], w[i + 15]);
474  SBOX7(w[i + 16], w[i + 17], w[i + 18], w[i + 19]);
475  SBOX6(w[i + 20], w[i + 21], w[i + 22], w[i + 23]);
476  SBOX5(w[i + 24], w[i + 25], w[i + 26], w[i + 27]);
477  SBOX4(w[i + 28], w[i + 29], w[i + 30], w[i + 31]);
478  }
479 
480  //Calculate the last round key
481  SBOX3(w[128], w[129], w[130], w[131]);
482 
483  //No error to report
484  return NO_ERROR;
485 }
486 
487 
488 /**
489  * @brief Encrypt a 16-byte block using Serpent algorithm
490  * @param[in] context Pointer to the Serpent context
491  * @param[in] input Plaintext block to encrypt
492  * @param[out] output Ciphertext block resulting from encryption
493  **/
494 
495 void serpentEncryptBlock(SerpentContext *context, const uint8_t *input,
496  uint8_t *output)
497 {
498  uint_t i;
499  uint32_t r0;
500  uint32_t r1;
501  uint32_t r2;
502  uint32_t r3;
503 
504  //The 16 bytes of plaintext are split into 4 words
505  r0 = LOAD32LE(input + 0);
506  r1 = LOAD32LE(input + 4);
507  r2 = LOAD32LE(input + 8);
508  r3 = LOAD32LE(input + 12);
509 
510  //The 32 rounds use 8 different S-boxes
511  for(i = 0; i < 32; i += 8)
512  {
513  ROUND(0, r0, r1, r2, r3, context->k[i]);
514  ROUND(1, r0, r1, r2, r3, context->k[i + 1]);
515  ROUND(2, r0, r1, r2, r3, context->k[i + 2]);
516  ROUND(3, r0, r1, r2, r3, context->k[i + 3]);
517  ROUND(4, r0, r1, r2, r3, context->k[i + 4]);
518  ROUND(5, r0, r1, r2, r3, context->k[i + 5]);
519  ROUND(6, r0, r1, r2, r3, context->k[i + 6]);
520  ROUND(7, r0, r1, r2, r3, context->k[i + 7]);
521  }
522 
523  //In the last round, the linear transformation is replaced by an additional
524  //key mixing
525  LT_INV(r0, r1, r2, r3);
526  XOR(r0, r1, r2, r3, context->k[32]);
527 
528  //The 4 words of ciphertext are then written as 16 bytes
529  STORE32LE(r0, output + 0);
530  STORE32LE(r1, output + 4);
531  STORE32LE(r2, output + 8);
532  STORE32LE(r3, output + 12);
533 }
534 
535 
536 /**
537  * @brief Decrypt a 16-byte block using Serpent algorithm
538  * @param[in] context Pointer to the Serpent context
539  * @param[in] input Ciphertext block to decrypt
540  * @param[out] output Plaintext block resulting from decryption
541  **/
542 
543 void serpentDecryptBlock(SerpentContext *context, const uint8_t *input,
544  uint8_t *output)
545 {
546  uint_t i;
547  uint32_t r0;
548  uint32_t r1;
549  uint32_t r2;
550  uint32_t r3;
551 
552  //The 16 bytes of ciphertext are split into 4 words
553  r0 = LOAD32LE(input + 0);
554  r1 = LOAD32LE(input + 4);
555  r2 = LOAD32LE(input + 8);
556  r3 = LOAD32LE(input + 12);
557 
558  //In the first decryption round, the inverse linear transformation is
559  //replaced by an additional key mixing
560  XOR(r0, r1, r2, r3, context->k[32]);
561  LT(r0, r1, r2, r3);
562 
563  //Decryption is different from encryption in that the inverse of the
564  //S-boxes must be used in the reverse order, as well as the inverse linear
565  //transformation and reverse order of the subkeys
566  for(i = 0; i < 32; i += 8)
567  {
568  ROUND_INV(7, r0, r1, r2, r3, context->k[31 - i]);
569  ROUND_INV(6, r0, r1, r2, r3, context->k[30 - i]);
570  ROUND_INV(5, r0, r1, r2, r3, context->k[29 - i]);
571  ROUND_INV(4, r0, r1, r2, r3, context->k[28 - i]);
572  ROUND_INV(3, r0, r1, r2, r3, context->k[27 - i]);
573  ROUND_INV(2, r0, r1, r2, r3, context->k[26 - i]);
574  ROUND_INV(1, r0, r1, r2, r3, context->k[25 - i]);
575  ROUND_INV(0, r0, r1, r2, r3, context->k[24 - i]);
576  }
577 
578  //The 4 words of plaintext are then written as 16 bytes
579  STORE32LE(r0, output + 0);
580  STORE32LE(r1, output + 4);
581  STORE32LE(r2, output + 8);
582  STORE32LE(r3, output + 12);
583 }
584 
585 
586 /**
587  * @brief Release Serpent context
588  * @param[in] context Pointer to the Serpent context
589  **/
590 
592 {
593  //Clear Serpent context
594  osMemset(context, 0, sizeof(SerpentContext));
595 }
596 
597 #endif
unsigned int uint_t
Definition: compiler_port.h:50
#define LOAD32LE(p)
Definition: cpu_endian.h:203
#define STORE32LE(a, p)
Definition: cpu_endian.h:279
General definitions for cryptographic algorithms.
void(* CipherAlgoDeinit)(void *context)
Definition: crypto.h:983
void(* CipherAlgoDecryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:980
error_t(* CipherAlgoInit)(void *context, const uint8_t *key, size_t keyLen)
Definition: crypto.h:968
void(* CipherAlgoEncryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:977
#define ROL32(a, n)
Definition: crypto.h:776
@ CIPHER_ALGO_TYPE_BLOCK
Definition: crypto.h:932
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_KEY_LENGTH
Definition: error.h:107
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
uint8_t t
Definition: lldp_ext_med.h:212
uint8_t p
Definition: ndp.h:300
#define osMemset(p, value, length)
Definition: os_port.h:135
#define SBOX2(r0, r1, r2, r3)
Definition: serpent.c:120
#define PHI
Definition: serpent.c:48
#define SBOX6(r0, r1, r2, r3)
Definition: serpent.c:256
#define SBOX0(r0, r1, r2, r3)
Definition: serpent.c:51
void serpentDeinit(SerpentContext *context)
Release Serpent context.
Definition: serpent.c:591
error_t serpentInit(SerpentContext *context, const uint8_t *key, size_t keyLen)
Key expansion.
Definition: serpent.c:402
#define SBOX3(r0, r1, r2, r3)
Definition: serpent.c:152
#define LT_INV(x0, x1, x2, x3)
Definition: serpent.c:339
void serpentEncryptBlock(SerpentContext *context, const uint8_t *input, uint8_t *output)
Encrypt a 16-byte block using Serpent algorithm.
Definition: serpent.c:495
#define SBOX7(r0, r1, r2, r3)
Definition: serpent.c:289
#define SBOX4(r0, r1, r2, r3)
Definition: serpent.c:186
const CipherAlgo serpentCipherAlgo
Definition: serpent.c:379
#define XOR(x0, x1, x2, x3, k)
Definition: serpent.c:354
void serpentDecryptBlock(SerpentContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 16-byte block using Serpent algorithm.
Definition: serpent.c:543
#define SBOX5(r0, r1, r2, r3)
Definition: serpent.c:222
#define SBOX1(r0, r1, r2, r3)
Definition: serpent.c:85
#define ROUND(n, x0, x1, x2, x3, k)
Definition: serpent.c:363
#define ROUND_INV(n, x0, x1, x2, x3, k)
Definition: serpent.c:371
#define LT(x0, x1, x2, x3)
Definition: serpent.c:324
Serpent encryption algorithm.
#define SERPENT_BLOCK_SIZE
Definition: serpent.h:38
Common interface for encryption algorithms.
Definition: crypto.h:1036
Serpent algorithm context.
Definition: serpent.h:53
uint32_t k[33][4]
Definition: serpent.h:54