aboutsummaryrefslogtreecommitdiffstats
path: root/modules/alg_ia32
diff options
context:
space:
mode:
authorlloyd <[email protected]>2006-08-15 02:50:07 +0000
committerlloyd <[email protected]>2006-08-15 02:50:07 +0000
commiteecf528cfc88b516bcff904f47226f5103ef2043 (patch)
tree3479a843de6bcbeb78fc533e40b4e6426f7290e6 /modules/alg_ia32
parent2ef993044a5e3b972f910995cfbeea5775b7ce6a (diff)
Implement decryption in the Serpent assembly code
Diffstat (limited to 'modules/alg_ia32')
-rw-r--r--modules/alg_ia32/modinfo.txt1
-rw-r--r--modules/alg_ia32/serp_asm.S395
-rw-r--r--modules/alg_ia32/serpent.cpp164
-rw-r--r--modules/alg_ia32/serpent.h33
4 files changed, 386 insertions, 207 deletions
diff --git a/modules/alg_ia32/modinfo.txt b/modules/alg_ia32/modinfo.txt
index 02581578f..1f85f5497 100644
--- a/modules/alg_ia32/modinfo.txt
+++ b/modules/alg_ia32/modinfo.txt
@@ -4,6 +4,7 @@ replace_file md4.cpp
replace_file md5.cpp
replace_file sha160.cpp
replace_file serpent.cpp
+replace_file serpent.h
add_file asm_macr.h
diff --git a/modules/alg_ia32/serp_asm.S b/modules/alg_ia32/serp_asm.S
index 049c2976b..a2785d129 100644
--- a/modules/alg_ia32/serp_asm.S
+++ b/modules/alg_ia32/serp_asm.S
@@ -7,7 +7,7 @@
START_LISTING(serp_asm.S)
-#define SBOX1(A, B, C, D, T) \
+#define SBOX_E1(A, B, C, D, T) \
XOR(D, A) ; \
ASSIGN(T, B) ; \
AND(B, D) ; \
@@ -30,7 +30,7 @@ START_LISTING(serp_asm.S)
ASSIGN(A, B) ; \
ASSIGN(B, T) ;
-#define SBOX2(A, B, C, D, T) \
+#define SBOX_E2(A, B, C, D, T) \
NOT(A) ; \
NOT(C) ; \
ASSIGN(T, A) ; \
@@ -54,7 +54,7 @@ START_LISTING(serp_asm.S)
ASSIGN(D, B) ; \
ASSIGN(B, T) ;
-#define SBOX3(A, B, C, D, T) \
+#define SBOX_E3(A, B, C, D, T) \
ASSIGN(T, A) ; \
AND(A, C) ; \
XOR(A, D) ; \
@@ -76,7 +76,7 @@ START_LISTING(serp_asm.S)
ASSIGN(B, D) ; \
ASSIGN(D, T) ;
-#define SBOX4(A, B, C, D, T) \
+#define SBOX_E4(A, B, C, D, T) \
ASSIGN(T, A) ; \
OR(A, D) ; \
XOR(D, B) ; \
@@ -101,7 +101,7 @@ START_LISTING(serp_asm.S)
ASSIGN(C, D) ; \
ASSIGN(D, T) ; \
-#define SBOX5(A, B, C, D, T) \
+#define SBOX_E5(A, B, C, D, T) \
XOR(B, D) ; \
NOT(D) ; \
XOR(C, D) ; \
@@ -126,7 +126,7 @@ START_LISTING(serp_asm.S)
ASSIGN(A, B) ; \
ASSIGN(B, T) ;
-#define SBOX6(A, B, C, D, T) \
+#define SBOX_E6(A, B, C, D, T) \
XOR(A, B) ; \
XOR(B, D) ; \
NOT(D) ; \
@@ -151,7 +151,7 @@ START_LISTING(serp_asm.S)
ASSIGN(B, D) ; \
ASSIGN(D, T) ; \
-#define SBOX7(A, B, C, D, T) \
+#define SBOX_E7(A, B, C, D, T) \
NOT(C) ; \
ASSIGN(T, D) ; \
AND(D, A) ; \
@@ -173,7 +173,7 @@ START_LISTING(serp_asm.S)
ASSIGN(D, C) ; \
ASSIGN(C, T) ;
-#define SBOX8(A, B, C, D, T) \
+#define SBOX_E8(A, B, C, D, T) \
ASSIGN(T, B) ; \
OR(B, C) ; \
XOR(B, D) ; \
@@ -197,7 +197,201 @@ START_LISTING(serp_asm.S)
ASSIGN(C, B) ; \
ASSIGN(B, D) ; \
ASSIGN(D, A) ; \
+ ASSIGN(A, T) ;
+
+#define SBOX_D1(A, B, C, D, T) \
+ NOT(C) ; \
+ ASSIGN(T, B) ; \
+ OR(B, A) ; \
+ NOT(T) ; \
+ XOR(B, C) ; \
+ OR(C, T) ; \
+ XOR(B, D) ; \
+ XOR(A, T) ; \
+ XOR(C, A) ; \
+ AND(A, D) ; \
+ XOR(T, A) ; \
+ OR(A, B) ; \
+ XOR(A, C) ; \
+ XOR(D, T) ; \
+ XOR(C, B) ; \
+ XOR(D, A) ; \
+ XOR(D, B) ; \
+ AND(C, D) ; \
+ XOR(T, C) ; \
+ ASSIGN(C, B) ; \
+ ASSIGN(B, T) ;
+
+#define SBOX_D2(A, B, C, D, T) \
+ ASSIGN(T, B) ; \
+ XOR(B, D) ; \
+ AND(D, B) ; \
+ XOR(T, C) ; \
+ XOR(D, A) ; \
+ OR(A, B) ; \
+ XOR(C, D) ; \
+ XOR(A, T) ; \
+ OR(A, C) ; \
+ XOR(B, D) ; \
+ XOR(A, B) ; \
+ OR(B, D) ; \
+ XOR(B, A) ; \
+ NOT(T) ; \
+ XOR(T, B) ; \
+ OR(B, A) ; \
+ XOR(B, A) ; \
+ OR(B, T) ; \
+ XOR(D, B) ; \
+ ASSIGN(B, A) ; \
ASSIGN(A, T) ; \
+ ASSIGN(T, D) ; \
+ ASSIGN(D, C) ; \
+ ASSIGN(C, T) ;
+
+#define SBOX_D3(A, B, C, D, T) \
+ XOR(C, D) ; \
+ XOR(D, A) ; \
+ ASSIGN(T, D) ; \
+ AND(D, C) ; \
+ XOR(D, B) ; \
+ OR(B, C) ; \
+ XOR(B, T) ; \
+ AND(T, D) ; \
+ XOR(C, D) ; \
+ AND(T, A) ; \
+ XOR(T, C) ; \
+ AND(C, B) ; \
+ OR(C, A) ; \
+ NOT(D) ; \
+ XOR(C, D) ; \
+ XOR(A, D) ; \
+ AND(A, B) ; \
+ XOR(D, T) ; \
+ XOR(D, A) ; \
+ ASSIGN(A, B) ; \
+ ASSIGN(B, T) ;
+
+ //busted
+#define SBOX_D4(A, B, C, D, T) \
+ ASSIGN(T, C) ; \
+ XOR(C, B) ; \
+ XOR(A, C) ; \
+ AND(T, C) ; \
+ XOR(T, A) ; \
+ AND(A, B) ; \
+ XOR(B, D) ; \
+ OR(D, T) ; \
+ XOR(C, D) ; \
+ XOR(A, D) ; \
+ XOR(B, T) ; \
+ AND(D, C) ; \
+ XOR(D, B) ; \
+ XOR(B, A) ; \
+ OR(B, C) ; \
+ XOR(A, D) ; \
+ XOR(B, T) ; \
+ XOR(A, B) ; \
+ ASSIGN(T, A) ; \
+ ASSIGN(A, C) ; \
+ ASSIGN(C, D) ; \
+ ASSIGN(D, T) ;
+
+#define SBOX_D5(A, B, C, D, T) \
+ ASSIGN(T, C) ; \
+ AND(C, D) ; \
+ XOR(C, B) ; \
+ OR(B, D) ; \
+ AND(B, A) ; \
+ XOR(T, C) ; \
+ XOR(T, B) ; \
+ AND(B, C) ; \
+ NOT(A) ; \
+ XOR(D, T) ; \
+ XOR(B, D) ; \
+ AND(D, A) ; \
+ XOR(D, C) ; \
+ XOR(A, B) ; \
+ AND(C, A) ; \
+ XOR(D, A) ; \
+ XOR(C, T) ; \
+ OR(C, D) ; \
+ XOR(D, A) ; \
+ XOR(C, B) ; \
+ ASSIGN(B, D) ; \
+ ASSIGN(D, T) ; \
+
+#define SBOX_D6(A, B, C, D, T) \
+ NOT(B) ; \
+ ASSIGN(T, D) ; \
+ XOR(C, B) ; \
+ OR(D, A) ; \
+ XOR(D, C) ; \
+ OR(C, B) ; \
+ AND(C, A) ; \
+ XOR(T, D) ; \
+ XOR(C, T) ; \
+ OR(T, A) ; \
+ XOR(T, B) ; \
+ AND(B, C) ; \
+ XOR(B, D) ; \
+ XOR(T, C) ; \
+ AND(D, T) ; \
+ XOR(T, B) ; \
+ XOR(D, T) ; \
+ NOT(T) ; \
+ XOR(D, A) ; \
+ ASSIGN(A, B) ; \
+ ASSIGN(B, T) ; \
+ ASSIGN(T, D) ; \
+ ASSIGN(D, C) ; \
+ ASSIGN(C, T) ; \
+
+#define SBOX_D7(A, B, C, D, T) \
+ XOR(A, C) ; \
+ ASSIGN(T, C) ; \
+ AND(C, A) ; \
+ XOR(T, D) ; \
+ NOT(C) ; \
+ XOR(D, B) ; \
+ XOR(C, D) ; \
+ OR(T, A) ; \
+ XOR(A, C) ; \
+ XOR(D, T) ; \
+ XOR(T, B) ; \
+ AND(B, D) ; \
+ XOR(B, A) ; \
+ XOR(A, D) ; \
+ OR(A, C) ; \
+ XOR(D, B) ; \
+ XOR(T, A) ; \
+ ASSIGN(A, B) ; \
+ ASSIGN(B, C) ; \
+ ASSIGN(C, T) ; \
+
+#define SBOX_D8(A, B, C, D, T) \
+ ASSIGN(T, C) ; \
+ XOR(C, A) ; \
+ AND(A, D) ; \
+ OR(T, D) ; \
+ NOT(C) ; \
+ XOR(D, B) ; \
+ OR(B, A) ; \
+ XOR(A, C) ; \
+ AND(C, T) ; \
+ AND(D, T) ; \
+ XOR(B, C) ; \
+ XOR(C, A) ; \
+ OR(A, C) ; \
+ XOR(T, B) ; \
+ XOR(A, D) ; \
+ XOR(D, T) ; \
+ OR(T, A) ; \
+ XOR(D, C) ; \
+ XOR(T, C) ; \
+ ASSIGN(C, B) ; \
+ ASSIGN(B, A) ; \
+ ASSIGN(A, D) ; \
+ ASSIGN(D, T) ; \
#define TRANSFORM(A, B, C, D, T) \
ROTL_IMM(A, 13) ; \
@@ -219,18 +413,62 @@ START_LISTING(serp_asm.S)
ROTL_IMM(A, 5) ; \
ROTL_IMM(C, 22) ;
+#define I_TRANSFORM(A, B, C, D, T) \
+ ROTR_IMM(C, 22) ; \
+ ROTR_IMM(A, 5) ; \
+ ASSIGN(T, B) ; \
+ SHL_IMM(T, 7) ; \
+ XOR(C, D) ; \
+ XOR(C, T) ; \
+ XOR(A, B) ; \
+ XOR(A, D) ; \
+ ROTR_IMM(D, 7) ; \
+ ROTR_IMM(B, 1) ; \
+ ASSIGN(T, A) ; \
+ SHL_IMM(T, 3) ; \
+ XOR(D, T) ; \
+ XOR(D, C) ; \
+ XOR(B, C) ; \
+ XOR(B, A) ; \
+ ROTR_IMM(C, 3) ; \
+ ROTR_IMM(A, 13) ; \
+
#define KEY_XOR(A, B, C, D, N) \
XOR(A, ARRAY4(EDI, (4*N ))) ; \
XOR(B, ARRAY4(EDI, (4*N+1))) ; \
XOR(C, ARRAY4(EDI, (4*N+2))) ; \
XOR(D, ARRAY4(EDI, (4*N+3))) ; \
-START_FUNCTION(serpent_encrypt)
+START_FUNCTION(serp_sbox)
SPILL_REGS()
#define PUSHED 4
ASSIGN(EBP, ARG(1)) /* input block */
+
+ ASSIGN(EAX, ARRAY4(EBP, 0))
+ ASSIGN(EBX, ARRAY4(EBP, 1))
+ ASSIGN(ECX, ARRAY4(EBP, 2))
+ ASSIGN(EDX, ARRAY4(EBP, 3))
+
+ SBOX_D4(EAX, EBX, ECX, EDX, EBP)
+
+ ASSIGN(EBP, ARG(1)) /* output block */
+ ASSIGN(ARRAY4(EBP, 0), EAX)
+ ASSIGN(ARRAY4(EBP, 1), EBX)
+ ASSIGN(ARRAY4(EBP, 2), ECX)
+ ASSIGN(ARRAY4(EBP, 3), EDX)
+
+ RESTORE_REGS()
+END_FUNCTION(serp_sbox)
+
+
+START_FUNCTION(serpent_encrypt)
+ SPILL_REGS()
+
+//#define PUSHED 4
+
+ ASSIGN(EBP, ARG(1)) /* input block */
ASSIGN(EDI, ARG(3)) /* round keys */
ASSIGN(EAX, ARRAY4(EBP, 0))
@@ -240,48 +478,48 @@ START_FUNCTION(serpent_encrypt)
ZEROIZE(EBP)
-#define ROUND(A, B, C, D, T, N, SBOX) \
+#define E_ROUND(A, B, C, D, T, N, SBOX) \
KEY_XOR(A, B, C, D, N) \
SBOX(A, B, C, D, T) \
TRANSFORM(A, B, C, D, T)
- ROUND(EAX, EBX, ECX, EDX, EBP, 0, SBOX1)
- ROUND(EAX, EBX, ECX, EDX, EBP, 1, SBOX2)
- ROUND(EAX, EBX, ECX, EDX, EBP, 2, SBOX3)
- ROUND(EAX, EBX, ECX, EDX, EBP, 3, SBOX4)
- ROUND(EAX, EBX, ECX, EDX, EBP, 4, SBOX5)
- ROUND(EAX, EBX, ECX, EDX, EBP, 5, SBOX6)
- ROUND(EAX, EBX, ECX, EDX, EBP, 6, SBOX7)
- ROUND(EAX, EBX, ECX, EDX, EBP, 7, SBOX8)
-
- ROUND(EAX, EBX, ECX, EDX, EBP, 8, SBOX1)
- ROUND(EAX, EBX, ECX, EDX, EBP, 9, SBOX2)
- ROUND(EAX, EBX, ECX, EDX, EBP, 10, SBOX3)
- ROUND(EAX, EBX, ECX, EDX, EBP, 11, SBOX4)
- ROUND(EAX, EBX, ECX, EDX, EBP, 12, SBOX5)
- ROUND(EAX, EBX, ECX, EDX, EBP, 13, SBOX6)
- ROUND(EAX, EBX, ECX, EDX, EBP, 14, SBOX7)
- ROUND(EAX, EBX, ECX, EDX, EBP, 15, SBOX8)
-
- ROUND(EAX, EBX, ECX, EDX, EBP, 16, SBOX1)
- ROUND(EAX, EBX, ECX, EDX, EBP, 17, SBOX2)
- ROUND(EAX, EBX, ECX, EDX, EBP, 18, SBOX3)
- ROUND(EAX, EBX, ECX, EDX, EBP, 19, SBOX4)
- ROUND(EAX, EBX, ECX, EDX, EBP, 20, SBOX5)
- ROUND(EAX, EBX, ECX, EDX, EBP, 21, SBOX6)
- ROUND(EAX, EBX, ECX, EDX, EBP, 22, SBOX7)
- ROUND(EAX, EBX, ECX, EDX, EBP, 23, SBOX8)
-
- ROUND(EAX, EBX, ECX, EDX, EBP, 24, SBOX1)
- ROUND(EAX, EBX, ECX, EDX, EBP, 25, SBOX2)
- ROUND(EAX, EBX, ECX, EDX, EBP, 26, SBOX3)
- ROUND(EAX, EBX, ECX, EDX, EBP, 27, SBOX4)
- ROUND(EAX, EBX, ECX, EDX, EBP, 28, SBOX5)
- ROUND(EAX, EBX, ECX, EDX, EBP, 29, SBOX6)
- ROUND(EAX, EBX, ECX, EDX, EBP, 30, SBOX7)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 0, SBOX_E1)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 1, SBOX_E2)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 2, SBOX_E3)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 3, SBOX_E4)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 4, SBOX_E5)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 5, SBOX_E6)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 6, SBOX_E7)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 7, SBOX_E8)
+
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 8, SBOX_E1)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 9, SBOX_E2)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 10, SBOX_E3)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 11, SBOX_E4)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 12, SBOX_E5)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 13, SBOX_E6)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 14, SBOX_E7)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 15, SBOX_E8)
+
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 16, SBOX_E1)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 17, SBOX_E2)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 18, SBOX_E3)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 19, SBOX_E4)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 20, SBOX_E5)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 21, SBOX_E6)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 22, SBOX_E7)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 23, SBOX_E8)
+
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 24, SBOX_E1)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 25, SBOX_E2)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 26, SBOX_E3)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 27, SBOX_E4)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 28, SBOX_E5)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 29, SBOX_E6)
+ E_ROUND(EAX, EBX, ECX, EDX, EBP, 30, SBOX_E7)
KEY_XOR(EAX, EBX, ECX, EDX, 31)
- SBOX8(EAX, EBX, ECX, EDX, EBP)
+ SBOX_E8(EAX, EBX, ECX, EDX, EBP)
KEY_XOR(EAX, EBX, ECX, EDX, 32)
ASSIGN(EBP, ARG(2)) /* output block */
@@ -292,3 +530,70 @@ START_FUNCTION(serpent_encrypt)
RESTORE_REGS()
END_FUNCTION(serpent_encrypt)
+
+START_FUNCTION(serpent_decrypt)
+ SPILL_REGS()
+
+ ASSIGN(EBP, ARG(1)) /* input block */
+ ASSIGN(EDI, ARG(3)) /* round keys */
+
+ ASSIGN(EAX, ARRAY4(EBP, 0))
+ ASSIGN(EBX, ARRAY4(EBP, 1))
+ ASSIGN(ECX, ARRAY4(EBP, 2))
+ ASSIGN(EDX, ARRAY4(EBP, 3))
+
+ ZEROIZE(EBP)
+
+#define D_ROUND(A, B, C, D, T, N, SBOX) \
+ I_TRANSFORM(A, B, C, D, T) \
+ SBOX(A, B, C, D, T) \
+ KEY_XOR(A, B, C, D, N) \
+
+ KEY_XOR(EAX, EBX, ECX, EDX, 32)
+ SBOX_D8(EAX, EBX, ECX, EDX, EBP)
+ KEY_XOR(EAX, EBX, ECX, EDX, 31)
+
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 30, SBOX_D7)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 29, SBOX_D6)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 28, SBOX_D5)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 27, SBOX_D4)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 26, SBOX_D3)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 25, SBOX_D2)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 24, SBOX_D1)
+
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 23, SBOX_D8)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 22, SBOX_D7)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 21, SBOX_D6)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 20, SBOX_D5)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 19, SBOX_D4)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 18, SBOX_D3)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 17, SBOX_D2)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 16, SBOX_D1)
+
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 15, SBOX_D8)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 14, SBOX_D7)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 13, SBOX_D6)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 12, SBOX_D5)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 11, SBOX_D4)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 10, SBOX_D3)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 9, SBOX_D2)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 8, SBOX_D1)
+
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 7, SBOX_D8)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 6, SBOX_D7)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 5, SBOX_D6)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 4, SBOX_D5)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 3, SBOX_D4)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 2, SBOX_D3)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 1, SBOX_D2)
+ D_ROUND(EAX, EBX, ECX, EDX, EBP, 0, SBOX_D1)
+
+ ASSIGN(EBP, ARG(2)) /* output block */
+ ASSIGN(ARRAY4(EBP, 0), EAX)
+ ASSIGN(ARRAY4(EBP, 1), EBX)
+ ASSIGN(ARRAY4(EBP, 2), ECX)
+ ASSIGN(ARRAY4(EBP, 3), EDX)
+
+ RESTORE_REGS()
+END_FUNCTION(serpent_decrypt)
+
diff --git a/modules/alg_ia32/serpent.cpp b/modules/alg_ia32/serpent.cpp
index aaa666ea7..c6db285c1 100644
--- a/modules/alg_ia32/serpent.cpp
+++ b/modules/alg_ia32/serpent.cpp
@@ -105,127 +105,10 @@ inline void SBoxE8(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
B0 = T4; B1 = T3; B2 = T1; B3 = T0;
}
-/*************************************************
-* Serpent Decryption S-Box 1 *
-*************************************************/
-inline void SBoxD1(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
- {
- u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4;
- T2 = ~T2; T4 = T1; T1 |= T0; T4 = ~T4; T1 ^= T2; T2 |= T4; T1 ^= T3;
- T0 ^= T4; T2 ^= T0; T0 &= T3; T4 ^= T0; T0 |= T1; T0 ^= T2; T3 ^= T4;
- T2 ^= T1; T3 ^= T0; T3 ^= T1; T2 &= T3; T4 ^= T2;
- B0 = T0; B1 = T4; B2 = T1; B3 = T3;
- }
-
-/*************************************************
-* Serpent Decryption S-Box 2 *
-*************************************************/
-inline void SBoxD2(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
- {
- u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4;
- T4 = T1; T1 ^= T3; T3 &= T1; T4 ^= T2; T3 ^= T0; T0 |= T1; T2 ^= T3;
- T0 ^= T4; T0 |= T2; T1 ^= T3; T0 ^= T1; T1 |= T3; T1 ^= T0; T4 = ~T4;
- T4 ^= T1; T1 |= T0; T1 ^= T0; T1 |= T4; T3 ^= T1;
- B0 = T4; B1 = T0; B2 = T3; B3 = T2;
- }
-
-/*************************************************
-* Serpent Decryption S-Box 3 *
-*************************************************/
-inline void SBoxD3(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
- {
- u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4;
- T2 ^= T3; T3 ^= T0; T4 = T3; T3 &= T2; T3 ^= T1; T1 |= T2; T1 ^= T4;
- T4 &= T3; T2 ^= T3; T4 &= T0; T4 ^= T2; T2 &= T1; T2 |= T0; T3 = ~T3;
- T2 ^= T3; T0 ^= T3; T0 &= T1; T3 ^= T4; T3 ^= T0;
- B0 = T1; B1 = T4; B2 = T2; B3 = T3;
- }
-
-/*************************************************
-* Serpent Decryption S-Box 4 *
-*************************************************/
-inline void SBoxD4(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
- {
- u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4;
- T4 = T2; T2 ^= T1; T0 ^= T2; T4 &= T2; T4 ^= T0; T0 &= T1; T1 ^= T3;
- T3 |= T4; T2 ^= T3; T0 ^= T3; T1 ^= T4; T3 &= T2; T3 ^= T1; T1 ^= T0;
- T1 |= T2; T0 ^= T3; T1 ^= T4; T0 ^= T1;
- B0 = T2; B1 = T1; B2 = T3; B3 = T0;
- }
-
-/*************************************************
-* Serpent Decryption S-Box 5 *
-*************************************************/
-inline void SBoxD5(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
- {
- u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4;
- T4 = T2; T2 &= T3; T2 ^= T1; T1 |= T3; T1 &= T0; T4 ^= T2; T4 ^= T1;
- T1 &= T2; T0 = ~T0; T3 ^= T4; T1 ^= T3; T3 &= T0; T3 ^= T2; T0 ^= T1;
- T2 &= T0; T3 ^= T0; T2 ^= T4; T2 |= T3; T3 ^= T0; T2 ^= T1;
- B0 = T0; B1 = T3; B2 = T2; B3 = T4;
- }
-
-/*************************************************
-* Serpent Decryption S-Box 6 *
-*************************************************/
-inline void SBoxD6(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
- {
- u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4;
- T1 = ~T1; T4 = T3; T2 ^= T1; T3 |= T0; T3 ^= T2; T2 |= T1; T2 &= T0;
- T4 ^= T3; T2 ^= T4; T4 |= T0; T4 ^= T1; T1 &= T2; T1 ^= T3; T4 ^= T2;
- T3 &= T4; T4 ^= T1; T3 ^= T4; T4 = ~T4; T3 ^= T0;
- B0 = T1; B1 = T4; B2 = T3; B3 = T2;
- }
-
-/*************************************************
-* Serpent Decryption S-Box 7 *
-*************************************************/
-inline void SBoxD7(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
- {
- u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4;
- T0 ^= T2; T4 = T2; T2 &= T0; T4 ^= T3; T2 = ~T2; T3 ^= T1; T2 ^= T3;
- T4 |= T0; T0 ^= T2; T3 ^= T4; T4 ^= T1; T1 &= T3; T1 ^= T0; T0 ^= T3;
- T0 |= T2; T3 ^= T1; T4 ^= T0;
- B0 = T1; B1 = T2; B2 = T4; B3 = T3;
- }
-
-/*************************************************
-* Serpent Decryption S-Box 8 *
-*************************************************/
-inline void SBoxD8(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
- {
- u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4;
- T4 = T2; T2 ^= T0; T0 &= T3; T4 |= T3; T2 = ~T2; T3 ^= T1; T1 |= T0;
- T0 ^= T2; T2 &= T4; T3 &= T4; T1 ^= T2; T2 ^= T0; T0 |= T2; T4 ^= T1;
- T0 ^= T3; T3 ^= T4; T4 |= T0; T3 ^= T2; T4 ^= T2;
- B0 = T3; B1 = T0; B2 = T1; B3 = T4;
- }
-
-/*************************************************
-* Serpent's Inverse Linear Transformation *
-*************************************************/
-inline void i_transform(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
- {
- B2 = rotate_right(B2, 22); B0 = rotate_right(B0, 5);
- B2 ^= B3 ^ (B1 << 7); B0 ^= B1 ^ B3;
- B3 = rotate_right(B3, 7); B1 = rotate_right(B1, 1);
- B3 ^= B2 ^ (B0 << 3); B1 ^= B0 ^ B2;
- B2 = rotate_right(B2, 3); B0 = rotate_right(B0, 13);
- }
-
}
-/*************************************************
-* XOR a key block with a data block *
-*************************************************/
-inline void Serpent::key_xor(u32bit round, u32bit& B0, u32bit& B1,
- u32bit& B2, u32bit& B3) const
- {
- B0 ^= round_key[4*round ]; B1 ^= round_key[4*round+1];
- B2 ^= round_key[4*round+2]; B3 ^= round_key[4*round+3];
- }
-
extern "C" void serpent_encrypt(const byte[16], byte[16], const u32bit[132]);
+extern "C" void serpent_decrypt(const byte[16], byte[16], const u32bit[132]);
/*************************************************
* Serpent Encryption *
@@ -240,50 +123,7 @@ void Serpent::enc(const byte in[], byte out[]) const
*************************************************/
void Serpent::dec(const byte in[], byte out[]) const
{
- u32bit B0 = make_u32bit(in[ 3], in[ 2], in[ 1], in[ 0]),
- B1 = make_u32bit(in[ 7], in[ 6], in[ 5], in[ 4]),
- B2 = make_u32bit(in[11], in[10], in[ 9], in[ 8]),
- B3 = make_u32bit(in[15], in[14], in[13], in[12]);
- key_xor(32,B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(31,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(30,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(29,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(28,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(27,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(26,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(25,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(24,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(23,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(22,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(21,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(20,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(19,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(18,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(17,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(16,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(15,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(14,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(13,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(12,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(11,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(10,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 9,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 8,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor( 7,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor( 6,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor( 5,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor( 4,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor( 3,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor( 2,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 1,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 0,B0,B1,B2,B3);
- out[ 0] = get_byte(3, B0); out[ 1] = get_byte(2, B0);
- out[ 2] = get_byte(1, B0); out[ 3] = get_byte(0, B0);
- out[ 4] = get_byte(3, B1); out[ 5] = get_byte(2, B1);
- out[ 6] = get_byte(1, B1); out[ 7] = get_byte(0, B1);
- out[ 8] = get_byte(3, B2); out[ 9] = get_byte(2, B2);
- out[10] = get_byte(1, B2); out[11] = get_byte(0, B2);
- out[12] = get_byte(3, B3); out[13] = get_byte(2, B3);
- out[14] = get_byte(1, B3); out[15] = get_byte(0, B3);
+ serpent_decrypt(in, out, round_key);
}
/*************************************************
diff --git a/modules/alg_ia32/serpent.h b/modules/alg_ia32/serpent.h
new file mode 100644
index 000000000..85e0345d0
--- /dev/null
+++ b/modules/alg_ia32/serpent.h
@@ -0,0 +1,33 @@
+/*************************************************
+* Serpent Header File *
+* (C) 1999-2006 The Botan Project *
+*************************************************/
+
+#ifndef BOTAN_SERPENT_H__
+#define BOTAN_SERPENT_H__
+
+#include <botan/base.h>
+
+namespace Botan {
+
+/*************************************************
+* Serpent *
+*************************************************/
+class Serpent : public BlockCipher
+ {
+ public:
+ void clear() throw() { round_key.clear(); }
+ std::string name() const { return "Serpent"; }
+ BlockCipher* clone() const { return new Serpent; }
+ Serpent() : BlockCipher(16, 16, 32, 8) {}
+ private:
+ void enc(const byte[], byte[]) const;
+ void dec(const byte[], byte[]) const;
+ void key(const byte[], u32bit);
+
+ SecureBuffer<u32bit, 132> round_key;
+ };
+
+}
+
+#endif