1 // serpent.cpp - written and placed in the public domain by Wei Dai
3 /* Adapted for TrueCrypt by the TrueCrypt Foundation */
6 #pragma optimize ("t", on)
10 #include "Common/Endian.h"
14 #if defined(_WIN32) && !defined(_DEBUG)
16 #define rotlFixed _rotl
17 #define rotrFixed _rotr
19 #define rotlFixed(x,n) (((x) << (n)) | ((x) >> (32 - (n))))
20 #define rotrFixed(x,n) (((x) >> (n)) | ((x) << (32 - (n))))
23 // linear transformation
24 #define LT(i,a,b,c,d,e) {\
25 a = rotlFixed(a, 13); \
26 c = rotlFixed(c, 3); \
27 d = rotlFixed(d ^ c ^ (a << 3), 7); \
28 b = rotlFixed(b ^ a ^ c, 1); \
29 a = rotlFixed(a ^ b ^ d, 5); \
30 c = rotlFixed(c ^ d ^ (b << 7), 22);}
32 // inverse linear transformation
33 #define ILT(i,a,b,c,d,e) {\
34 c = rotrFixed(c, 22); \
35 a = rotrFixed(a, 5); \
38 b = rotrFixed(b, 1); \
39 d = rotrFixed(d, 7) ^ c ^ (a << 3); \
41 c = rotrFixed(c, 3); \
42 a = rotrFixed(a, 13);}
44 // order of output from S-box functions
45 #define beforeS0(f) f(0,a,b,c,d,e)
46 #define afterS0(f) f(1,b,e,c,a,d)
47 #define afterS1(f) f(2,c,b,a,e,d)
48 #define afterS2(f) f(3,a,e,b,d,c)
49 #define afterS3(f) f(4,e,b,d,c,a)
50 #define afterS4(f) f(5,b,a,e,c,d)
51 #define afterS5(f) f(6,a,c,b,e,d)
52 #define afterS6(f) f(7,a,c,d,b,e)
53 #define afterS7(f) f(8,d,e,b,a,c)
55 // order of output from inverse S-box functions
56 #define beforeI7(f) f(8,a,b,c,d,e)
57 #define afterI7(f) f(7,d,a,b,e,c)
58 #define afterI6(f) f(6,a,b,c,e,d)
59 #define afterI5(f) f(5,b,d,e,c,a)
60 #define afterI4(f) f(4,b,c,e,a,d)
61 #define afterI3(f) f(3,a,b,e,c,d)
62 #define afterI2(f) f(2,b,d,e,c,a)
63 #define afterI1(f) f(1,a,b,c,e,d)
64 #define afterI0(f) f(0,a,d,b,e,c)
66 // The instruction sequences for the S-box functions
67 // come from Dag Arne Osvik's paper "Speeding up Serpent".
69 #define S0(i, r0, r1, r2, r3, r4) \
91 #define I0(i, r0, r1, r2, r3, r4) \
114 #define S1(i, r0, r1, r2, r3, r4) \
136 #define I1(i, r0, r1, r2, r3, r4) \
159 #define S2(i, r0, r1, r2, r3, r4) \
179 #define I2(i, r0, r1, r2, r3, r4) \
202 #define S3(i, r0, r1, r2, r3, r4) \
225 #define I3(i, r0, r1, r2, r3, r4) \
247 #define S4(i, r0, r1, r2, r3, r4) \
271 #define I4(i, r0, r1, r2, r3, r4) \
295 #define S5(i, r0, r1, r2, r3, r4) \
318 #define I5(i, r0, r1, r2, r3, r4) \
341 #define S6(i, r0, r1, r2, r3, r4) \
363 #define I6(i, r0, r1, r2, r3, r4) \
384 #define S7(i, r0, r1, r2, r3, r4) \
408 #define I7(i, r0, r1, r2, r3, r4) \
432 #define KX(r, a, b, c, d, e) {\
439 #ifdef TC_MINIMIZE_CODE_SIZE
441 static void S0f (unsigned __int32
*r0
, unsigned __int32
*r1
, unsigned __int32
*r2
, unsigned __int32
*r3
, unsigned __int32
*r4
)
463 static void S1f (unsigned __int32
*r0
, unsigned __int32
*r1
, unsigned __int32
*r2
, unsigned __int32
*r3
, unsigned __int32
*r4
)
485 static void S2f (unsigned __int32
*r0
, unsigned __int32
*r1
, unsigned __int32
*r2
, unsigned __int32
*r3
, unsigned __int32
*r4
)
505 static void S3f (unsigned __int32
*r0
, unsigned __int32
*r1
, unsigned __int32
*r2
, unsigned __int32
*r3
, unsigned __int32
*r4
)
528 static void S4f (unsigned __int32
*r0
, unsigned __int32
*r1
, unsigned __int32
*r2
, unsigned __int32
*r3
, unsigned __int32
*r4
)
552 static void S5f (unsigned __int32
*r0
, unsigned __int32
*r1
, unsigned __int32
*r2
, unsigned __int32
*r3
, unsigned __int32
*r4
)
575 static void S6f (unsigned __int32
*r0
, unsigned __int32
*r1
, unsigned __int32
*r2
, unsigned __int32
*r3
, unsigned __int32
*r4
)
597 static void S7f (unsigned __int32
*r0
, unsigned __int32
*r1
, unsigned __int32
*r2
, unsigned __int32
*r3
, unsigned __int32
*r4
)
621 static void KXf (const unsigned __int32
*k
, unsigned int r
, unsigned __int32
*a
, unsigned __int32
*b
, unsigned __int32
*c
, unsigned __int32
*d
)
629 #endif // TC_MINIMIZE_CODE_SIZE
631 #ifndef TC_MINIMIZE_CODE_SIZE
633 void serpent_set_key(const unsigned __int8 userKey
[], int keylen
, unsigned __int8
*ks
)
635 unsigned __int32 a
,b
,c
,d
,e
;
636 unsigned __int32
*k
= (unsigned __int32
*)ks
;
640 for (i
= 0; i
< keylen
/ (int)sizeof(__int32
); i
++)
641 k
[i
] = LE32(((unsigned __int32
*)userKey
)[i
]);
644 k
[keylen
/4] |= (unsigned __int32
)1 << ((keylen
%4)*8);
648 for (i
= 0; i
< 132; ++i
)
649 k
[i
] = t
= rotlFixed(k
[i
-8] ^ k
[i
-5] ^ k
[i
-3] ^ t
^ 0x9e3779b9 ^ i
, 11);
652 #define LK(r, a, b, c, d, e) {\
653 a = k[(8-r)*4 + 0]; \
654 b = k[(8-r)*4 + 1]; \
655 c = k[(8-r)*4 + 2]; \
658 #define SK(r, a, b, c, d, e) {\
659 k[(8-r)*4 + 4] = a; \
660 k[(8-r)*4 + 5] = b; \
661 k[(8-r)*4 + 6] = c; \
662 k[(8-r)*4 + 7] = d;} \
666 afterS2(LK
); afterS2(S3
); afterS3(SK
);
667 afterS1(LK
); afterS1(S2
); afterS2(SK
);
668 afterS0(LK
); afterS0(S1
); afterS1(SK
);
669 beforeS0(LK
); beforeS0(S0
); afterS0(SK
);
671 afterS6(LK
); afterS6(S7
); afterS7(SK
);
672 afterS5(LK
); afterS5(S6
); afterS6(SK
);
673 afterS4(LK
); afterS4(S5
); afterS5(SK
);
674 afterS3(LK
); afterS3(S4
); afterS4(SK
);
676 afterS2(LK
); afterS2(S3
); afterS3(SK
);
679 #else // TC_MINIMIZE_CODE_SIZE
681 static void LKf (unsigned __int32
*k
, unsigned int r
, unsigned __int32
*a
, unsigned __int32
*b
, unsigned __int32
*c
, unsigned __int32
*d
)
689 static void SKf (unsigned __int32
*k
, unsigned int r
, unsigned __int32
*a
, unsigned __int32
*b
, unsigned __int32
*c
, unsigned __int32
*d
)
697 void serpent_set_key(const unsigned __int8 userKey
[], int keylen
, unsigned __int8
*ks
)
699 unsigned __int32 a
,b
,c
,d
,e
;
700 unsigned __int32
*k
= (unsigned __int32
*)ks
;
704 for (i
= 0; i
< keylen
/ (int)sizeof(__int32
); i
++)
705 k
[i
] = LE32(((unsigned __int32
*)userKey
)[i
]);
708 k
[keylen
/4] |= (unsigned __int32
)1 << ((keylen
%4)*8);
712 for (i
= 0; i
< 132; ++i
)
713 k
[i
] = t
= rotlFixed(k
[i
-8] ^ k
[i
-5] ^ k
[i
-3] ^ t
^ 0x9e3779b9 ^ i
, 11);
718 LKf (k
, 20, &a
, &e
, &b
, &d
); S3f (&a
, &e
, &b
, &d
, &c
); SKf (k
, 16, &e
, &b
, &d
, &c
);
719 LKf (k
, 24, &c
, &b
, &a
, &e
); S2f (&c
, &b
, &a
, &e
, &d
); SKf (k
, 20, &a
, &e
, &b
, &d
);
720 LKf (k
, 28, &b
, &e
, &c
, &a
); S1f (&b
, &e
, &c
, &a
, &d
); SKf (k
, 24, &c
, &b
, &a
, &e
);
721 LKf (k
, 32, &a
, &b
, &c
, &d
); S0f (&a
, &b
, &c
, &d
, &e
); SKf (k
, 28, &b
, &e
, &c
, &a
);
723 LKf (k
, 4, &a
, &c
, &d
, &b
); S7f (&a
, &c
, &d
, &b
, &e
); SKf (k
, 0, &d
, &e
, &b
, &a
);
724 LKf (k
, 8, &a
, &c
, &b
, &e
); S6f (&a
, &c
, &b
, &e
, &d
); SKf (k
, 4, &a
, &c
, &d
, &b
);
725 LKf (k
, 12, &b
, &a
, &e
, &c
); S5f (&b
, &a
, &e
, &c
, &d
); SKf (k
, 8, &a
, &c
, &b
, &e
);
726 LKf (k
, 16, &e
, &b
, &d
, &c
); S4f (&e
, &b
, &d
, &c
, &a
); SKf (k
, 12, &b
, &a
, &e
, &c
);
728 LKf (k
, 20, &a
, &e
, &b
, &d
); S3f (&a
, &e
, &b
, &d
, &c
); SKf (k
, 16, &e
, &b
, &d
, &c
);
731 #endif // TC_MINIMIZE_CODE_SIZE
734 #ifndef TC_MINIMIZE_CODE_SIZE
736 void serpent_encrypt(const unsigned __int8
*inBlock
, unsigned __int8
*outBlock
, unsigned __int8
*ks
)
738 unsigned __int32 a
, b
, c
, d
, e
;
740 const unsigned __int32
*k
= (unsigned __int32
*)ks
+ 8;
741 unsigned __int32
*in
= (unsigned __int32
*) inBlock
;
742 unsigned __int32
*out
= (unsigned __int32
*) outBlock
;
751 beforeS0(KX
); beforeS0(S0
); afterS0(LT
);
752 afterS0(KX
); afterS0(S1
); afterS1(LT
);
753 afterS1(KX
); afterS1(S2
); afterS2(LT
);
754 afterS2(KX
); afterS2(S3
); afterS3(LT
);
755 afterS3(KX
); afterS3(S4
); afterS4(LT
);
756 afterS4(KX
); afterS4(S5
); afterS5(LT
);
757 afterS5(KX
); afterS5(S6
); afterS6(LT
);
758 afterS6(KX
); afterS6(S7
);
782 #else // TC_MINIMIZE_CODE_SIZE
784 typedef unsigned __int32 uint32
;
786 static void LTf (uint32
*a
, uint32
*b
, uint32
*c
, uint32
*d
)
788 *a
= rotlFixed(*a
, 13);
789 *c
= rotlFixed(*c
, 3);
790 *d
= rotlFixed(*d
^ *c
^ (*a
<< 3), 7);
791 *b
= rotlFixed(*b
^ *a
^ *c
, 1);
792 *a
= rotlFixed(*a
^ *b
^ *d
, 5);
793 *c
= rotlFixed(*c
^ *d
^ (*b
<< 7), 22);
796 void serpent_encrypt(const unsigned __int8
*inBlock
, unsigned __int8
*outBlock
, unsigned __int8
*ks
)
798 unsigned __int32 a
, b
, c
, d
, e
;
800 const unsigned __int32
*k
= (unsigned __int32
*)ks
+ 8;
801 unsigned __int32
*in
= (unsigned __int32
*) inBlock
;
802 unsigned __int32
*out
= (unsigned __int32
*) outBlock
;
811 KXf (k
, 0, &a
, &b
, &c
, &d
); S0f (&a
, &b
, &c
, &d
, &e
); LTf (&b
, &e
, &c
, &a
);
812 KXf (k
, 4, &b
, &e
, &c
, &a
); S1f (&b
, &e
, &c
, &a
, &d
); LTf (&c
, &b
, &a
, &e
);
813 KXf (k
, 8, &c
, &b
, &a
, &e
); S2f (&c
, &b
, &a
, &e
, &d
); LTf (&a
, &e
, &b
, &d
);
814 KXf (k
, 12, &a
, &e
, &b
, &d
); S3f (&a
, &e
, &b
, &d
, &c
); LTf (&e
, &b
, &d
, &c
);
815 KXf (k
, 16, &e
, &b
, &d
, &c
); S4f (&e
, &b
, &d
, &c
, &a
); LTf (&b
, &a
, &e
, &c
);
816 KXf (k
, 20, &b
, &a
, &e
, &c
); S5f (&b
, &a
, &e
, &c
, &d
); LTf (&a
, &c
, &b
, &e
);
817 KXf (k
, 24, &a
, &c
, &b
, &e
); S6f (&a
, &c
, &b
, &e
, &d
); LTf (&a
, &c
, &d
, &b
);
818 KXf (k
, 28, &a
, &c
, &d
, &b
); S7f (&a
, &c
, &d
, &b
, &e
);
834 KXf (k
, 32, &d
, &e
, &b
, &a
);
842 #endif // TC_MINIMIZE_CODE_SIZE
844 #if !defined (TC_MINIMIZE_CODE_SIZE) || defined (TC_WINDOWS_BOOT_SERPENT)
846 void serpent_decrypt(const unsigned __int8
*inBlock
, unsigned __int8
*outBlock
, unsigned __int8
*ks
)
848 unsigned __int32 a
, b
, c
, d
, e
;
849 const unsigned __int32
*k
= (unsigned __int32
*)ks
+ 104;
851 unsigned __int32
*in
= (unsigned __int32
*) inBlock
;
852 unsigned __int32
*out
= (unsigned __int32
*) outBlock
;
870 beforeI7(I7
); afterI7(KX
);
871 afterI7(ILT
); afterI7(I6
); afterI6(KX
);
872 afterI6(ILT
); afterI6(I5
); afterI5(KX
);
873 afterI5(ILT
); afterI5(I4
); afterI4(KX
);
874 afterI4(ILT
); afterI4(I3
); afterI3(KX
);
875 afterI3(ILT
); afterI3(I2
); afterI2(KX
);
876 afterI2(ILT
); afterI2(I1
); afterI1(KX
);
877 afterI1(ILT
); afterI1(I0
); afterI0(KX
);
887 #else // TC_MINIMIZE_CODE_SIZE && !TC_WINDOWS_BOOT_SERPENT
889 static void ILTf (uint32
*a
, uint32
*b
, uint32
*c
, uint32
*d
)
891 *c
= rotrFixed(*c
, 22);
892 *a
= rotrFixed(*a
, 5);
893 *c
^= *d
^ (*b
<< 7);
895 *b
= rotrFixed(*b
, 1);
896 *d
= rotrFixed(*d
, 7) ^ *c
^ (*a
<< 3);
898 *c
= rotrFixed(*c
, 3);
899 *a
= rotrFixed(*a
, 13);
902 void serpent_decrypt(const unsigned __int8
*inBlock
, unsigned __int8
*outBlock
, unsigned __int8
*ks
)
904 unsigned __int32 a
, b
, c
, d
, e
;
905 const unsigned __int32
*k
= (unsigned __int32
*)ks
+ 104;
907 unsigned __int32
*in
= (unsigned __int32
*) inBlock
;
908 unsigned __int32
*out
= (unsigned __int32
*) outBlock
;
915 KXf (k
, 32, &a
, &b
, &c
, &d
);
926 beforeI7(I7
); KXf (k
, 28, &d
, &a
, &b
, &e
);
927 ILTf (&d
, &a
, &b
, &e
); afterI7(I6
); KXf (k
, 24, &a
, &b
, &c
, &e
);
928 ILTf (&a
, &b
, &c
, &e
); afterI6(I5
); KXf (k
, 20, &b
, &d
, &e
, &c
);
929 ILTf (&b
, &d
, &e
, &c
); afterI5(I4
); KXf (k
, 16, &b
, &c
, &e
, &a
);
930 ILTf (&b
, &c
, &e
, &a
); afterI4(I3
); KXf (k
, 12, &a
, &b
, &e
, &c
);
931 ILTf (&a
, &b
, &e
, &c
); afterI3(I2
); KXf (k
, 8, &b
, &d
, &e
, &c
);
932 ILTf (&b
, &d
, &e
, &c
); afterI2(I1
); KXf (k
, 4, &a
, &b
, &c
, &e
);
933 ILTf (&a
, &b
, &c
, &e
); afterI1(I0
); KXf (k
, 0, &a
, &d
, &b
, &e
);
943 #endif // TC_MINIMIZE_CODE_SIZE && !TC_WINDOWS_BOOT_SERPENT