8#include <botan/serp_simd.h>
9#include <botan/internal/simd_32.h>
10#include <botan/loadstor.h>
16#define SBoxE1(B0, B1, B2, B3) \
41#define SBoxE2(B0, B1, B2, B3) \
67#define SBoxE3(B0, B1, B2, B3) \
90#define SBoxE4(B0, B1, B2, B3) \
116#define SBoxE5(B0, B1, B2, B3) \
143#define SBoxE6(B0, B1, B2, B3) \
170#define SBoxE7(B0, B1, B2, B3) \
193#define SBoxE8(B0, B1, B2, B3) \
221#define SBoxD1(B0, B1, B2, B3) \
246#define SBoxD2(B0, B1, B2, B3) \
274#define SBoxD3(B0, B1, B2, B3) \
299#define SBoxD4(B0, B1, B2, B3) \
325#define SBoxD5(B0, B1, B2, B3) \
351#define SBoxD6(B0, B1, B2, B3) \
379#define SBoxD7(B0, B1, B2, B3) \
403#define SBoxD8(B0, B1, B2, B3) \
430#define key_xor(round, B0, B1, B2, B3) \
432 B0 ^= SIMD_32(keys[4*round ]); \
433 B1 ^= SIMD_32(keys[4*round+1]); \
434 B2 ^= SIMD_32(keys[4*round+2]); \
435 B3 ^= SIMD_32(keys[4*round+3]); \
441#define transform(B0, B1, B2, B3) \
443 B0.rotate_left(13); \
446 B3 ^= B2 ^ (B0 << 3); \
450 B2 ^= B3 ^ (B1 << 7); \
452 B2.rotate_left(22); \
455#define i_transform(B0, B1, B2, B3) \
457 B2.rotate_right(22); \
458 B0.rotate_right(5); \
459 B2 ^= B3 ^ (B1 << 7); \
461 B3.rotate_right(7); \
462 B1.rotate_right(1); \
463 B3 ^= B2 ^ (B0 << 3); \
465 B2.rotate_right(3); \
466 B0.rotate_right(13); \
472void serpent_encrypt_4(
const byte in[64],
476 SIMD_32 B0 = SIMD_32::load_le(in);
477 SIMD_32 B1 = SIMD_32::load_le(in + 16);
478 SIMD_32 B2 = SIMD_32::load_le(in + 32);
479 SIMD_32 B3 = SIMD_32::load_le(in + 48);
481 SIMD_32::transpose(B0, B1, B2, B3);
483 key_xor( 0,B0,B1,B2,B3);
SBoxE1(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
484 key_xor( 1,B0,B1,B2,B3);
SBoxE2(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
485 key_xor( 2,B0,B1,B2,B3);
SBoxE3(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
486 key_xor( 3,B0,B1,B2,B3);
SBoxE4(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
487 key_xor( 4,B0,B1,B2,B3);
SBoxE5(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
488 key_xor( 5,B0,B1,B2,B3);
SBoxE6(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
489 key_xor( 6,B0,B1,B2,B3);
SBoxE7(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
490 key_xor( 7,B0,B1,B2,B3);
SBoxE8(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
492 key_xor( 8,B0,B1,B2,B3);
SBoxE1(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
493 key_xor( 9,B0,B1,B2,B3);
SBoxE2(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
494 key_xor(10,B0,B1,B2,B3);
SBoxE3(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
495 key_xor(11,B0,B1,B2,B3);
SBoxE4(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
496 key_xor(12,B0,B1,B2,B3);
SBoxE5(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
497 key_xor(13,B0,B1,B2,B3);
SBoxE6(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
498 key_xor(14,B0,B1,B2,B3);
SBoxE7(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
499 key_xor(15,B0,B1,B2,B3);
SBoxE8(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
501 key_xor(16,B0,B1,B2,B3);
SBoxE1(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
502 key_xor(17,B0,B1,B2,B3);
SBoxE2(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
503 key_xor(18,B0,B1,B2,B3);
SBoxE3(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
504 key_xor(19,B0,B1,B2,B3);
SBoxE4(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
505 key_xor(20,B0,B1,B2,B3);
SBoxE5(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
506 key_xor(21,B0,B1,B2,B3);
SBoxE6(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
507 key_xor(22,B0,B1,B2,B3);
SBoxE7(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
508 key_xor(23,B0,B1,B2,B3);
SBoxE8(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
510 key_xor(24,B0,B1,B2,B3);
SBoxE1(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
511 key_xor(25,B0,B1,B2,B3);
SBoxE2(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
512 key_xor(26,B0,B1,B2,B3);
SBoxE3(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
513 key_xor(27,B0,B1,B2,B3);
SBoxE4(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
514 key_xor(28,B0,B1,B2,B3);
SBoxE5(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
515 key_xor(29,B0,B1,B2,B3);
SBoxE6(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
516 key_xor(30,B0,B1,B2,B3);
SBoxE7(B0,B1,B2,B3);
transform(B0,B1,B2,B3);
517 key_xor(31,B0,B1,B2,B3);
SBoxE8(B0,B1,B2,B3);
key_xor(32,B0,B1,B2,B3);
519 SIMD_32::transpose(B0, B1, B2, B3);
522 B1.store_le(out + 16);
523 B2.store_le(out + 32);
524 B3.store_le(out + 48);
530void serpent_decrypt_4(
const byte in[64],
534 SIMD_32 B0 = SIMD_32::load_le(in);
535 SIMD_32 B1 = SIMD_32::load_le(in + 16);
536 SIMD_32 B2 = SIMD_32::load_le(in + 32);
537 SIMD_32 B3 = SIMD_32::load_le(in + 48);
539 SIMD_32::transpose(B0, B1, B2, B3);
541 key_xor(32,B0,B1,B2,B3);
SBoxD8(B0,B1,B2,B3);
key_xor(31,B0,B1,B2,B3);
542 i_transform(B0,B1,B2,B3);
SBoxD7(B0,B1,B2,B3);
key_xor(30,B0,B1,B2,B3);
543 i_transform(B0,B1,B2,B3);
SBoxD6(B0,B1,B2,B3);
key_xor(29,B0,B1,B2,B3);
544 i_transform(B0,B1,B2,B3);
SBoxD5(B0,B1,B2,B3);
key_xor(28,B0,B1,B2,B3);
545 i_transform(B0,B1,B2,B3);
SBoxD4(B0,B1,B2,B3);
key_xor(27,B0,B1,B2,B3);
546 i_transform(B0,B1,B2,B3);
SBoxD3(B0,B1,B2,B3);
key_xor(26,B0,B1,B2,B3);
547 i_transform(B0,B1,B2,B3);
SBoxD2(B0,B1,B2,B3);
key_xor(25,B0,B1,B2,B3);
548 i_transform(B0,B1,B2,B3);
SBoxD1(B0,B1,B2,B3);
key_xor(24,B0,B1,B2,B3);
550 i_transform(B0,B1,B2,B3);
SBoxD8(B0,B1,B2,B3);
key_xor(23,B0,B1,B2,B3);
551 i_transform(B0,B1,B2,B3);
SBoxD7(B0,B1,B2,B3);
key_xor(22,B0,B1,B2,B3);
552 i_transform(B0,B1,B2,B3);
SBoxD6(B0,B1,B2,B3);
key_xor(21,B0,B1,B2,B3);
553 i_transform(B0,B1,B2,B3);
SBoxD5(B0,B1,B2,B3);
key_xor(20,B0,B1,B2,B3);
554 i_transform(B0,B1,B2,B3);
SBoxD4(B0,B1,B2,B3);
key_xor(19,B0,B1,B2,B3);
555 i_transform(B0,B1,B2,B3);
SBoxD3(B0,B1,B2,B3);
key_xor(18,B0,B1,B2,B3);
556 i_transform(B0,B1,B2,B3);
SBoxD2(B0,B1,B2,B3);
key_xor(17,B0,B1,B2,B3);
557 i_transform(B0,B1,B2,B3);
SBoxD1(B0,B1,B2,B3);
key_xor(16,B0,B1,B2,B3);
559 i_transform(B0,B1,B2,B3);
SBoxD8(B0,B1,B2,B3);
key_xor(15,B0,B1,B2,B3);
560 i_transform(B0,B1,B2,B3);
SBoxD7(B0,B1,B2,B3);
key_xor(14,B0,B1,B2,B3);
561 i_transform(B0,B1,B2,B3);
SBoxD6(B0,B1,B2,B3);
key_xor(13,B0,B1,B2,B3);
562 i_transform(B0,B1,B2,B3);
SBoxD5(B0,B1,B2,B3);
key_xor(12,B0,B1,B2,B3);
563 i_transform(B0,B1,B2,B3);
SBoxD4(B0,B1,B2,B3);
key_xor(11,B0,B1,B2,B3);
564 i_transform(B0,B1,B2,B3);
SBoxD3(B0,B1,B2,B3);
key_xor(10,B0,B1,B2,B3);
565 i_transform(B0,B1,B2,B3);
SBoxD2(B0,B1,B2,B3);
key_xor( 9,B0,B1,B2,B3);
566 i_transform(B0,B1,B2,B3);
SBoxD1(B0,B1,B2,B3);
key_xor( 8,B0,B1,B2,B3);
568 i_transform(B0,B1,B2,B3);
SBoxD8(B0,B1,B2,B3);
key_xor( 7,B0,B1,B2,B3);
569 i_transform(B0,B1,B2,B3);
SBoxD7(B0,B1,B2,B3);
key_xor( 6,B0,B1,B2,B3);
570 i_transform(B0,B1,B2,B3);
SBoxD6(B0,B1,B2,B3);
key_xor( 5,B0,B1,B2,B3);
571 i_transform(B0,B1,B2,B3);
SBoxD5(B0,B1,B2,B3);
key_xor( 4,B0,B1,B2,B3);
572 i_transform(B0,B1,B2,B3);
SBoxD4(B0,B1,B2,B3);
key_xor( 3,B0,B1,B2,B3);
573 i_transform(B0,B1,B2,B3);
SBoxD3(B0,B1,B2,B3);
key_xor( 2,B0,B1,B2,B3);
574 i_transform(B0,B1,B2,B3);
SBoxD2(B0,B1,B2,B3);
key_xor( 1,B0,B1,B2,B3);
575 i_transform(B0,B1,B2,B3);
SBoxD1(B0,B1,B2,B3);
key_xor( 0,B0,B1,B2,B3);
577 SIMD_32::transpose(B0, B1, B2, B3);
580 B1.store_le(out + 16);
581 B2.store_le(out + 32);
582 B3.store_le(out + 48);
618 serpent_encrypt_4(in, out, KS);
637 serpent_decrypt_4(in, out, KS);
void encrypt_n(const byte in[], byte out[], size_t blocks) const
void decrypt_n(const byte in[], byte out[], size_t blocks) const
const SecureVector< u32bit > & get_round_keys() const
void encrypt_n(const byte in[], byte out[], size_t blocks) const
void decrypt_n(const byte in[], byte out[], size_t blocks) const
#define SBoxE7(B0, B1, B2, B3)
#define SBoxE1(B0, B1, B2, B3)
#define SBoxE5(B0, B1, B2, B3)
#define SBoxD6(B0, B1, B2, B3)
#define SBoxD8(B0, B1, B2, B3)
#define SBoxD1(B0, B1, B2, B3)
#define i_transform(B0, B1, B2, B3)
#define SBoxD7(B0, B1, B2, B3)
#define SBoxE4(B0, B1, B2, B3)
#define SBoxE3(B0, B1, B2, B3)
#define SBoxE2(B0, B1, B2, B3)
#define SBoxD5(B0, B1, B2, B3)
#define transform(B0, B1, B2, B3)
#define SBoxE6(B0, B1, B2, B3)
#define SBoxD2(B0, B1, B2, B3)
#define SBoxE8(B0, B1, B2, B3)
#define SBoxD4(B0, B1, B2, B3)
#define SBoxD3(B0, B1, B2, B3)
#define key_xor(round, B0, B1, B2, B3)