From eecf528cfc88b516bcff904f47226f5103ef2043 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 15 Aug 2006 02:50:07 +0000 Subject: Implement decryption in the Serpent assembly code --- modules/alg_ia32/modinfo.txt | 1 + modules/alg_ia32/serp_asm.S | 395 ++++++++++++++++++++++++++++++++++++++----- modules/alg_ia32/serpent.cpp | 164 +----------------- modules/alg_ia32/serpent.h | 33 ++++ 4 files changed, 386 insertions(+), 207 deletions(-) create mode 100644 modules/alg_ia32/serpent.h (limited to 'modules/alg_ia32') 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,17 +413,61 @@ 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 */ @@ -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 + +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 round_key; + }; + +} + +#endif -- cgit v1.2.3