aboutsummaryrefslogtreecommitdiffstats
path: root/src/block
diff options
context:
space:
mode:
authorlloyd <[email protected]>2009-11-03 23:41:56 +0000
committerlloyd <[email protected]>2009-11-03 23:41:56 +0000
commit30f6169ebf9164a6fdb35519030975440a5b07d7 (patch)
tree8435e826dd692066c6c3fc56d02f8f4479188c02 /src/block
parentcb0d4a18f2fc77a40f6055fedb43b78606068b7b (diff)
parent226d96ee4e64994beb9ec9436a29ac6656d61924 (diff)
propagate from branch 'net.randombit.botan.1_8' (head 6e8c18515725a70923b34118951252723dd4c29a)
to branch 'net.randombit.botan' (head 77ba4ea5a4be36d6d029bcc852b2271edff0d679)
Diffstat (limited to 'src/block')
-rw-r--r--src/block/aes/aes.cpp268
-rw-r--r--src/block/aes/aes.h10
-rw-r--r--src/block/aes/info.txt10
-rw-r--r--src/block/block_cipher.h22
-rw-r--r--src/block/blowfish/blowfish.cpp72
-rw-r--r--src/block/blowfish/blowfish.h10
-rw-r--r--src/block/blowfish/info.txt10
-rw-r--r--src/block/cast/cast128.cpp100
-rw-r--r--src/block/cast/cast128.h8
-rw-r--r--src/block/cast/cast256.cpp140
-rw-r--r--src/block/cast/cast256.h8
-rw-r--r--src/block/cast/info.txt12
-rw-r--r--src/block/des/des.cpp143
-rw-r--r--src/block/des/des.h16
-rw-r--r--src/block/des/desx.cpp28
-rw-r--r--src/block/des/desx.h8
-rw-r--r--src/block/des/info.txt12
-rw-r--r--src/block/gost_28147/gost_28147.cpp67
-rw-r--r--src/block/gost_28147/gost_28147.h7
-rw-r--r--src/block/gost_28147/info.txt9
-rw-r--r--src/block/idea/idea.cpp132
-rw-r--r--src/block/idea/idea.h8
-rw-r--r--src/block/idea/info.txt9
-rw-r--r--src/block/info.txt8
-rw-r--r--src/block/kasumi/info.txt9
-rw-r--r--src/block/kasumi/kasumi.cpp110
-rw-r--r--src/block/kasumi/kasumi.h7
-rw-r--r--src/block/lion/info.txt9
-rw-r--r--src/block/lion/lion.cpp54
-rw-r--r--src/block/lion/lion.h7
-rw-r--r--src/block/lubyrack/info.txt9
-rw-r--r--src/block/lubyrack/lubyrack.cpp106
-rw-r--r--src/block/lubyrack/lubyrack.h8
-rw-r--r--src/block/mars/info.txt10
-rw-r--r--src/block/mars/mars.cpp138
-rw-r--r--src/block/mars/mars.h8
-rw-r--r--src/block/misty1/info.txt9
-rw-r--r--src/block/misty1/misty1.cpp130
-rw-r--r--src/block/misty1/misty1.h8
-rw-r--r--src/block/noekeon/info.txt9
-rw-r--r--src/block/noekeon/noekeon.cpp94
-rw-r--r--src/block/noekeon/noekeon.h8
-rw-r--r--src/block/rc2/info.txt9
-rw-r--r--src/block/rc2/rc2.cpp104
-rw-r--r--src/block/rc2/rc2.h8
-rw-r--r--src/block/rc5/info.txt9
-rw-r--r--src/block/rc5/rc5.cpp72
-rw-r--r--src/block/rc5/rc5.h8
-rw-r--r--src/block/rc6/info.txt9
-rw-r--r--src/block/rc6/rc6.cpp140
-rw-r--r--src/block/rc6/rc6.h8
-rw-r--r--src/block/safer/info.txt10
-rw-r--r--src/block/safer/safer_sk.cpp97
-rw-r--r--src/block/safer/safer_sk.h9
-rw-r--r--src/block/seed/info.txt10
-rw-r--r--src/block/seed/seed.cpp116
-rw-r--r--src/block/seed/seed.h8
-rw-r--r--src/block/serpent/info.txt9
-rw-r--r--src/block/serpent/serpent.cpp172
-rw-r--r--src/block/serpent/serpent.h7
-rw-r--r--src/block/serpent_ia32/info.txt8
-rw-r--r--src/block/serpent_ia32/serp_ia32.cpp20
-rw-r--r--src/block/serpent_ia32/serp_ia32.h5
-rw-r--r--src/block/serpent_simd/info.txt7
-rw-r--r--src/block/serpent_simd/serp_simd.cpp206
-rw-r--r--src/block/serpent_simd/serp_simd.h29
-rw-r--r--src/block/serpent_simd/serp_simd_sbox.h426
-rw-r--r--src/block/skipjack/info.txt9
-rw-r--r--src/block/skipjack/skipjack.cpp70
-rw-r--r--src/block/skipjack/skipjack.h9
-rw-r--r--src/block/square/info.txt10
-rw-r--r--src/block/square/square.cpp194
-rw-r--r--src/block/square/square.h8
-rw-r--r--src/block/tea/info.txt9
-rw-r--r--src/block/tea/tea.cpp52
-rw-r--r--src/block/tea/tea.h8
-rw-r--r--src/block/twofish/info.txt10
-rw-r--r--src/block/twofish/twofish.cpp158
-rw-r--r--src/block/twofish/twofish.h8
-rw-r--r--src/block/xtea/info.txt9
-rw-r--r--src/block/xtea/xtea.cpp103
-rw-r--r--src/block/xtea/xtea.h10
-rw-r--r--src/block/xtea_simd/info.txt14
-rw-r--r--src/block/xtea_simd/xtea_simd.cpp124
-rw-r--r--src/block/xtea_simd/xtea_simd.h28
85 files changed, 2620 insertions, 1569 deletions
diff --git a/src/block/aes/aes.cpp b/src/block/aes/aes.cpp
index 9072b507b..7ba8136ec 100644
--- a/src/block/aes/aes.cpp
+++ b/src/block/aes/aes.cpp
@@ -1,6 +1,6 @@
/**
* AES
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -13,163 +13,175 @@ namespace Botan {
/**
* AES Encryption
*/
-void AES::enc(const byte in[], byte out[]) const
+void AES::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
const u32bit* TE0 = TE;
const u32bit* TE1 = TE + 256;
const u32bit* TE2 = TE + 512;
const u32bit* TE3 = TE + 768;
- u32bit T0 = load_be<u32bit>(in, 0) ^ EK[0];
- u32bit T1 = load_be<u32bit>(in, 1) ^ EK[1];
- u32bit T2 = load_be<u32bit>(in, 2) ^ EK[2];
- u32bit T3 = load_be<u32bit>(in, 3) ^ EK[3];
-
- u32bit B0, B1, B2, B3;
- B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(1, T1)] ^
- TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4];
- B1 = TE0[get_byte(0, T1)] ^ TE1[get_byte(1, T2)] ^
- TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ EK[5];
- B2 = TE0[get_byte(0, T2)] ^ TE1[get_byte(1, T3)] ^
- TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ EK[6];
- B3 = TE0[get_byte(0, T3)] ^ TE1[get_byte(1, T0)] ^
- TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ EK[7];
-
- for(u32bit j = 2; j != ROUNDS; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- const u32bit K0 = EK[4*j];
- const u32bit K1 = EK[4*j+1];
- const u32bit K2 = EK[4*j+2];
- const u32bit K3 = EK[4*j+3];
-
- T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(1, B1)] ^
- TE2[get_byte(2, B2)] ^ TE3[get_byte(3, B3)] ^ K0;
- T1 = TE0[get_byte(0, B1)] ^ TE1[get_byte(1, B2)] ^
- TE2[get_byte(2, B3)] ^ TE3[get_byte(3, B0)] ^ K1;
- T2 = TE0[get_byte(0, B2)] ^ TE1[get_byte(1, B3)] ^
- TE2[get_byte(2, B0)] ^ TE3[get_byte(3, B1)] ^ K2;
- T3 = TE0[get_byte(0, B3)] ^ TE1[get_byte(1, B0)] ^
- TE2[get_byte(2, B1)] ^ TE3[get_byte(3, B2)] ^ K3;
-
- const u32bit K4 = EK[4*(j+1)+0];
- const u32bit K5 = EK[4*(j+1)+1];
- const u32bit K6 = EK[4*(j+1)+2];
- const u32bit K7 = EK[4*(j+1)+3];
+ u32bit T0 = load_be<u32bit>(in, 0) ^ EK[0];
+ u32bit T1 = load_be<u32bit>(in, 1) ^ EK[1];
+ u32bit T2 = load_be<u32bit>(in, 2) ^ EK[2];
+ u32bit T3 = load_be<u32bit>(in, 3) ^ EK[3];
+ u32bit B0, B1, B2, B3;
B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(1, T1)] ^
- TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ K4;
+ TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4];
B1 = TE0[get_byte(0, T1)] ^ TE1[get_byte(1, T2)] ^
- TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ K5;
+ TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ EK[5];
B2 = TE0[get_byte(0, T2)] ^ TE1[get_byte(1, T3)] ^
- TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ K6;
+ TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ EK[6];
B3 = TE0[get_byte(0, T3)] ^ TE1[get_byte(1, T0)] ^
- TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ K7;
- }
+ TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ EK[7];
+
+ for(u32bit j = 2; j != ROUNDS; j += 2)
+ {
+ const u32bit K0 = EK[4*j];
+ const u32bit K1 = EK[4*j+1];
+ const u32bit K2 = EK[4*j+2];
+ const u32bit K3 = EK[4*j+3];
+
+ T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(1, B1)] ^
+ TE2[get_byte(2, B2)] ^ TE3[get_byte(3, B3)] ^ K0;
+ T1 = TE0[get_byte(0, B1)] ^ TE1[get_byte(1, B2)] ^
+ TE2[get_byte(2, B3)] ^ TE3[get_byte(3, B0)] ^ K1;
+ T2 = TE0[get_byte(0, B2)] ^ TE1[get_byte(1, B3)] ^
+ TE2[get_byte(2, B0)] ^ TE3[get_byte(3, B1)] ^ K2;
+ T3 = TE0[get_byte(0, B3)] ^ TE1[get_byte(1, B0)] ^
+ TE2[get_byte(2, B1)] ^ TE3[get_byte(3, B2)] ^ K3;
+
+ const u32bit K4 = EK[4*(j+1)+0];
+ const u32bit K5 = EK[4*(j+1)+1];
+ const u32bit K6 = EK[4*(j+1)+2];
+ const u32bit K7 = EK[4*(j+1)+3];
- /*
- Joseph Bonneau and Ilya Mironov's paper
- <a href = "http://icme2007.org/users/mironov/papers/aes-timing.pdf">
- Cache-Collision Timing Attacks Against AES</a> describes an attack
- that can recover AES keys with as few as 2<sup>13</sup> samples.
-
- """In addition to OpenSSL v. 0.9.8.(a), which was used in our
- experiments, the AES implementations of Crypto++ 5.2.1 and
- LibTomCrypt 1.09 use the original Rijndael C implementation with
- very few changes and are highly vulnerable. The AES implementations
- in libgcrypt v. 1.2.2 and Botan v. 1.4.2 are also vulnerable, but
- use a smaller byte-wide final table which lessens the effectiveness
- of the attacks."""
- */
- out[ 0] = SE[get_byte(0, B0)] ^ ME[0];
- out[ 1] = SE[get_byte(1, B1)] ^ ME[1];
- out[ 2] = SE[get_byte(2, B2)] ^ ME[2];
- out[ 3] = SE[get_byte(3, B3)] ^ ME[3];
- out[ 4] = SE[get_byte(0, B1)] ^ ME[4];
- out[ 5] = SE[get_byte(1, B2)] ^ ME[5];
- out[ 6] = SE[get_byte(2, B3)] ^ ME[6];
- out[ 7] = SE[get_byte(3, B0)] ^ ME[7];
- out[ 8] = SE[get_byte(0, B2)] ^ ME[8];
- out[ 9] = SE[get_byte(1, B3)] ^ ME[9];
- out[10] = SE[get_byte(2, B0)] ^ ME[10];
- out[11] = SE[get_byte(3, B1)] ^ ME[11];
- out[12] = SE[get_byte(0, B3)] ^ ME[12];
- out[13] = SE[get_byte(1, B0)] ^ ME[13];
- out[14] = SE[get_byte(2, B1)] ^ ME[14];
- out[15] = SE[get_byte(3, B2)] ^ ME[15];
+ B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(1, T1)] ^
+ TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ K4;
+ B1 = TE0[get_byte(0, T1)] ^ TE1[get_byte(1, T2)] ^
+ TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ K5;
+ B2 = TE0[get_byte(0, T2)] ^ TE1[get_byte(1, T3)] ^
+ TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ K6;
+ B3 = TE0[get_byte(0, T3)] ^ TE1[get_byte(1, T0)] ^
+ TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ K7;
+ }
+
+ /*
+ Joseph Bonneau and Ilya Mironov's paper
+ <a href = "http://icme2007.org/users/mironov/papers/aes-timing.pdf">
+ Cache-Collision Timing Attacks Against AES</a> describes an attack
+ that can recover AES keys with as few as 2<sup>13</sup> samples.
+
+ """In addition to OpenSSL v. 0.9.8.(a), which was used in our
+ experiments, the AES implementations of Crypto++ 5.2.1 and
+ LibTomCrypt 1.09 use the original Rijndael C implementation with
+ very few changes and are highly vulnerable. The AES implementations
+ in libgcrypt v. 1.2.2 and Botan v. 1.4.2 are also vulnerable, but
+ use a smaller byte-wide final table which lessens the effectiveness
+ of the attacks."""
+ */
+ out[ 0] = SE[get_byte(0, B0)] ^ ME[0];
+ out[ 1] = SE[get_byte(1, B1)] ^ ME[1];
+ out[ 2] = SE[get_byte(2, B2)] ^ ME[2];
+ out[ 3] = SE[get_byte(3, B3)] ^ ME[3];
+ out[ 4] = SE[get_byte(0, B1)] ^ ME[4];
+ out[ 5] = SE[get_byte(1, B2)] ^ ME[5];
+ out[ 6] = SE[get_byte(2, B3)] ^ ME[6];
+ out[ 7] = SE[get_byte(3, B0)] ^ ME[7];
+ out[ 8] = SE[get_byte(0, B2)] ^ ME[8];
+ out[ 9] = SE[get_byte(1, B3)] ^ ME[9];
+ out[10] = SE[get_byte(2, B0)] ^ ME[10];
+ out[11] = SE[get_byte(3, B1)] ^ ME[11];
+ out[12] = SE[get_byte(0, B3)] ^ ME[12];
+ out[13] = SE[get_byte(1, B0)] ^ ME[13];
+ out[14] = SE[get_byte(2, B1)] ^ ME[14];
+ out[15] = SE[get_byte(3, B2)] ^ ME[15];
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/**
* AES Decryption
*/
-void AES::dec(const byte in[], byte out[]) const
+void AES::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
const u32bit* TD0 = TD;
const u32bit* TD1 = TD + 256;
const u32bit* TD2 = TD + 512;
const u32bit* TD3 = TD + 768;
- u32bit T0 = load_be<u32bit>(in, 0) ^ DK[0];
- u32bit T1 = load_be<u32bit>(in, 1) ^ DK[1];
- u32bit T2 = load_be<u32bit>(in, 2) ^ DK[2];
- u32bit T3 = load_be<u32bit>(in, 3) ^ DK[3];
-
- u32bit B0, B1, B2, B3;
- B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(1, T3)] ^
- TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ DK[4];
- B1 = TD0[get_byte(0, T1)] ^ TD1[get_byte(1, T0)] ^
- TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ DK[5];
- B2 = TD0[get_byte(0, T2)] ^ TD1[get_byte(1, T1)] ^
- TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ DK[6];
- B3 = TD0[get_byte(0, T3)] ^ TD1[get_byte(1, T2)] ^
- TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ DK[7];
-
- for(u32bit j = 2; j != ROUNDS; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- const u32bit K0 = DK[4*j+0];
- const u32bit K1 = DK[4*j+1];
- const u32bit K2 = DK[4*j+2];
- const u32bit K3 = DK[4*j+3];
-
- T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(1, B3)] ^
- TD2[get_byte(2, B2)] ^ TD3[get_byte(3, B1)] ^ K0;
- T1 = TD0[get_byte(0, B1)] ^ TD1[get_byte(1, B0)] ^
- TD2[get_byte(2, B3)] ^ TD3[get_byte(3, B2)] ^ K1;
- T2 = TD0[get_byte(0, B2)] ^ TD1[get_byte(1, B1)] ^
- TD2[get_byte(2, B0)] ^ TD3[get_byte(3, B3)] ^ K2;
- T3 = TD0[get_byte(0, B3)] ^ TD1[get_byte(1, B2)] ^
- TD2[get_byte(2, B1)] ^ TD3[get_byte(3, B0)] ^ K3;
-
- const u32bit K4 = DK[4*(j+1)+0];
- const u32bit K5 = DK[4*(j+1)+1];
- const u32bit K6 = DK[4*(j+1)+2];
- const u32bit K7 = DK[4*(j+1)+3];
+ u32bit T0 = load_be<u32bit>(in, 0) ^ DK[0];
+ u32bit T1 = load_be<u32bit>(in, 1) ^ DK[1];
+ u32bit T2 = load_be<u32bit>(in, 2) ^ DK[2];
+ u32bit T3 = load_be<u32bit>(in, 3) ^ DK[3];
+ u32bit B0, B1, B2, B3;
B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(1, T3)] ^
- TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ K4;
+ TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ DK[4];
B1 = TD0[get_byte(0, T1)] ^ TD1[get_byte(1, T0)] ^
- TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ K5;
+ TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ DK[5];
B2 = TD0[get_byte(0, T2)] ^ TD1[get_byte(1, T1)] ^
- TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ K6;
+ TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ DK[6];
B3 = TD0[get_byte(0, T3)] ^ TD1[get_byte(1, T2)] ^
- TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ K7;
- }
+ TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ DK[7];
+
+ for(u32bit j = 2; j != ROUNDS; j += 2)
+ {
+ const u32bit K0 = DK[4*j+0];
+ const u32bit K1 = DK[4*j+1];
+ const u32bit K2 = DK[4*j+2];
+ const u32bit K3 = DK[4*j+3];
+
+ T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(1, B3)] ^
+ TD2[get_byte(2, B2)] ^ TD3[get_byte(3, B1)] ^ K0;
+ T1 = TD0[get_byte(0, B1)] ^ TD1[get_byte(1, B0)] ^
+ TD2[get_byte(2, B3)] ^ TD3[get_byte(3, B2)] ^ K1;
+ T2 = TD0[get_byte(0, B2)] ^ TD1[get_byte(1, B1)] ^
+ TD2[get_byte(2, B0)] ^ TD3[get_byte(3, B3)] ^ K2;
+ T3 = TD0[get_byte(0, B3)] ^ TD1[get_byte(1, B2)] ^
+ TD2[get_byte(2, B1)] ^ TD3[get_byte(3, B0)] ^ K3;
+
+ const u32bit K4 = DK[4*(j+1)+0];
+ const u32bit K5 = DK[4*(j+1)+1];
+ const u32bit K6 = DK[4*(j+1)+2];
+ const u32bit K7 = DK[4*(j+1)+3];
- out[ 0] = SD[get_byte(0, B0)] ^ MD[0];
- out[ 1] = SD[get_byte(1, B3)] ^ MD[1];
- out[ 2] = SD[get_byte(2, B2)] ^ MD[2];
- out[ 3] = SD[get_byte(3, B1)] ^ MD[3];
- out[ 4] = SD[get_byte(0, B1)] ^ MD[4];
- out[ 5] = SD[get_byte(1, B0)] ^ MD[5];
- out[ 6] = SD[get_byte(2, B3)] ^ MD[6];
- out[ 7] = SD[get_byte(3, B2)] ^ MD[7];
- out[ 8] = SD[get_byte(0, B2)] ^ MD[8];
- out[ 9] = SD[get_byte(1, B1)] ^ MD[9];
- out[10] = SD[get_byte(2, B0)] ^ MD[10];
- out[11] = SD[get_byte(3, B3)] ^ MD[11];
- out[12] = SD[get_byte(0, B3)] ^ MD[12];
- out[13] = SD[get_byte(1, B2)] ^ MD[13];
- out[14] = SD[get_byte(2, B1)] ^ MD[14];
- out[15] = SD[get_byte(3, B0)] ^ MD[15];
+ B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(1, T3)] ^
+ TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ K4;
+ B1 = TD0[get_byte(0, T1)] ^ TD1[get_byte(1, T0)] ^
+ TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ K5;
+ B2 = TD0[get_byte(0, T2)] ^ TD1[get_byte(1, T1)] ^
+ TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ K6;
+ B3 = TD0[get_byte(0, T3)] ^ TD1[get_byte(1, T2)] ^
+ TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ K7;
+ }
+
+ out[ 0] = SD[get_byte(0, B0)] ^ MD[0];
+ out[ 1] = SD[get_byte(1, B3)] ^ MD[1];
+ out[ 2] = SD[get_byte(2, B2)] ^ MD[2];
+ out[ 3] = SD[get_byte(3, B1)] ^ MD[3];
+ out[ 4] = SD[get_byte(0, B1)] ^ MD[4];
+ out[ 5] = SD[get_byte(1, B0)] ^ MD[5];
+ out[ 6] = SD[get_byte(2, B3)] ^ MD[6];
+ out[ 7] = SD[get_byte(3, B2)] ^ MD[7];
+ out[ 8] = SD[get_byte(0, B2)] ^ MD[8];
+ out[ 9] = SD[get_byte(1, B1)] ^ MD[9];
+ out[10] = SD[get_byte(2, B0)] ^ MD[10];
+ out[11] = SD[get_byte(3, B3)] ^ MD[11];
+ out[12] = SD[get_byte(0, B3)] ^ MD[12];
+ out[13] = SD[get_byte(1, B2)] ^ MD[13];
+ out[14] = SD[get_byte(2, B1)] ^ MD[14];
+ out[15] = SD[get_byte(3, B0)] ^ MD[15];
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/**
@@ -246,7 +258,7 @@ AES::AES(u32bit key_size) : BlockCipher(16, key_size)
/**
* Clear memory of sensitive data
*/
-void AES::clear() throw()
+void AES::clear()
{
EK.clear();
DK.clear();
diff --git a/src/block/aes/aes.h b/src/block/aes/aes.h
index 05e2e3123..229ce307c 100644
--- a/src/block/aes/aes.h
+++ b/src/block/aes/aes.h
@@ -1,6 +1,6 @@
/**
* AES
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -18,14 +18,16 @@ namespace Botan {
class BOTAN_DLL AES : public BlockCipher
{
public:
- void clear() throw();
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear();
std::string name() const { return "AES"; }
BlockCipher* clone() const { return new AES; }
+
AES() : BlockCipher(16, 16, 32, 8) { ROUNDS = 14; }
AES(u32bit);
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static u32bit S(u32bit);
diff --git a/src/block/aes/info.txt b/src/block/aes/info.txt
index 2803ccc4e..480973100 100644
--- a/src/block/aes/info.txt
+++ b/src/block/aes/info.txt
@@ -1,11 +1 @@
-realname "AES"
-
define AES
-
-load_on auto
-
-<add>
-aes.cpp
-aes.h
-aes_tab.cpp
-</add>
diff --git a/src/block/block_cipher.h b/src/block/block_cipher.h
index 01c45af04..1dcdde7c7 100644
--- a/src/block/block_cipher.h
+++ b/src/block/block_cipher.h
@@ -1,6 +1,6 @@
/**
* Block Cipher Base Class
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -45,7 +45,8 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
* @param out The byte array designated to hold the encrypted block.
* Must be of length BLOCK_SIZE.
*/
- void encrypt(const byte in[], byte out[]) const { enc(in, out); }
+ void encrypt(const byte in[], byte out[]) const
+ { encrypt_n(in, out, 1); }
/**
* Decrypt a block.
@@ -54,7 +55,8 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
* @param out The byte array designated to hold the decrypted block.
* Must be of length BLOCK_SIZE.
*/
- void decrypt(const byte in[], byte out[]) const { dec(in, out); }
+ void decrypt(const byte in[], byte out[]) const
+ { decrypt_n(in, out, 1); }
/**
* Encrypt a block.
@@ -62,7 +64,7 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
* Must be of length BLOCK_SIZE. Will hold the result when the function
* has finished.
*/
- void encrypt(byte block[]) const { enc(block, block); }
+ void encrypt(byte block[]) const { encrypt_n(block, block, 1); }
/**
* Decrypt a block.
@@ -70,7 +72,12 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
* Must be of length BLOCK_SIZE. Will hold the result when the function
* has finished.
*/
- void decrypt(byte block[]) const { dec(block, block); }
+ void decrypt(byte block[]) const { decrypt_n(block, block, 1); }
+
+ virtual void encrypt_n(const byte in[], byte out[],
+ u32bit blocks) const = 0;
+ virtual void decrypt_n(const byte in[], byte out[],
+ u32bit blocks) const = 0;
/**
* Get a new object representing the same algorithm as *this
@@ -80,7 +87,7 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
/**
* Zeroize internal state
*/
- virtual void clear() throw() = 0;
+ virtual void clear() = 0;
BlockCipher(u32bit block_size,
u32bit key_min,
@@ -90,9 +97,6 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
BLOCK_SIZE(block_size) {}
virtual ~BlockCipher() {}
- private:
- virtual void enc(const byte[], byte[]) const = 0;
- virtual void dec(const byte[], byte[]) const = 0;
};
}
diff --git a/src/block/blowfish/blowfish.cpp b/src/block/blowfish/blowfish.cpp
index b0599d6c5..d0b182a84 100644
--- a/src/block/blowfish/blowfish.cpp
+++ b/src/block/blowfish/blowfish.cpp
@@ -1,6 +1,6 @@
/*
* Blowfish
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -13,59 +13,71 @@ namespace Botan {
/*
* Blowfish Encryption
*/
-void Blowfish::enc(const byte in[], byte out[]) const
+void Blowfish::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
const u32bit* S1 = S + 0;
const u32bit* S2 = S + 256;
const u32bit* S3 = S + 512;
const u32bit* S4 = S + 768;
- u32bit L = load_be<u32bit>(in, 0);
- u32bit R = load_be<u32bit>(in, 1);
-
- for(u32bit j = 0; j != 16; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- L ^= P[j];
- R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^
- S3[get_byte(2, L)]) + S4[get_byte(3, L)];
+ u32bit L = load_be<u32bit>(in, 0);
+ u32bit R = load_be<u32bit>(in, 1);
- R ^= P[j+1];
- L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^
- S3[get_byte(2, R)]) + S4[get_byte(3, R)];
- }
+ for(u32bit j = 0; j != 16; j += 2)
+ {
+ L ^= P[j];
+ R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^
+ S3[get_byte(2, L)]) + S4[get_byte(3, L)];
- L ^= P[16]; R ^= P[17];
+ R ^= P[j+1];
+ L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^
+ S3[get_byte(2, R)]) + S4[get_byte(3, R)];
+ }
+
+ L ^= P[16]; R ^= P[17];
- store_be(out, R, L);
+ store_be(out, R, L);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Blowfish Decryption
*/
-void Blowfish::dec(const byte in[], byte out[]) const
+void Blowfish::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
const u32bit* S1 = S + 0;
const u32bit* S2 = S + 256;
const u32bit* S3 = S + 512;
const u32bit* S4 = S + 768;
- u32bit L = load_be<u32bit>(in, 0);
- u32bit R = load_be<u32bit>(in, 1);
-
- for(u32bit j = 17; j != 1; j -= 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- L ^= P[j];
- R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^
- S3[get_byte(2, L)]) + S4[get_byte(3, L)];
+ u32bit L = load_be<u32bit>(in, 0);
+ u32bit R = load_be<u32bit>(in, 1);
- R ^= P[j-1];
- L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^
- S3[get_byte(2, R)]) + S4[get_byte(3, R)];
- }
+ for(u32bit j = 17; j != 1; j -= 2)
+ {
+ L ^= P[j];
+ R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^
+ S3[get_byte(2, L)]) + S4[get_byte(3, L)];
- L ^= P[1]; R ^= P[0];
+ R ^= P[j-1];
+ L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^
+ S3[get_byte(2, R)]) + S4[get_byte(3, R)];
+ }
+
+ L ^= P[1]; R ^= P[0];
- store_be(out, R, L);
+ store_be(out, R, L);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
@@ -116,7 +128,7 @@ void Blowfish::generate_sbox(u32bit Box[], u32bit size,
/*
* Clear memory of sensitive data
*/
-void Blowfish::clear() throw()
+void Blowfish::clear()
{
P.copy(P_INIT, 18);
S.copy(S_INIT, 1024);
diff --git a/src/block/blowfish/blowfish.h b/src/block/blowfish/blowfish.h
index f0f26418d..5419308ca 100644
--- a/src/block/blowfish/blowfish.h
+++ b/src/block/blowfish/blowfish.h
@@ -1,6 +1,6 @@
/*
* Blowfish
-* (C) 1999-2008 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL Blowfish : public BlockCipher
{
public:
- void clear() throw();
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear();
std::string name() const { return "Blowfish"; }
BlockCipher* clone() const { return new Blowfish; }
+
Blowfish() : BlockCipher(8, 1, 56) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
void generate_sbox(u32bit[], u32bit, u32bit&, u32bit&) const;
diff --git a/src/block/blowfish/info.txt b/src/block/blowfish/info.txt
index 0a9d2adc2..c935fb3ab 100644
--- a/src/block/blowfish/info.txt
+++ b/src/block/blowfish/info.txt
@@ -1,11 +1 @@
-realname "Blowfish"
-
define BLOWFISH
-
-load_on auto
-
-<add>
-blfs_tab.cpp
-blowfish.cpp
-blowfish.h
-</add>
diff --git a/src/block/cast/cast128.cpp b/src/block/cast/cast128.cpp
index 046638ab9..887dcf994 100644
--- a/src/block/cast/cast128.cpp
+++ b/src/block/cast/cast128.cpp
@@ -48,57 +48,69 @@ inline void R3(u32bit& L, u32bit R, u32bit MK, u32bit RK)
/*
* CAST-128 Encryption
*/
-void CAST_128::enc(const byte in[], byte out[]) const
+void CAST_128::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit L = load_be<u32bit>(in, 0);
- u32bit R = load_be<u32bit>(in, 1);
-
- R1(L, R, MK[ 0], RK[ 0]);
- R2(R, L, MK[ 1], RK[ 1]);
- R3(L, R, MK[ 2], RK[ 2]);
- R1(R, L, MK[ 3], RK[ 3]);
- R2(L, R, MK[ 4], RK[ 4]);
- R3(R, L, MK[ 5], RK[ 5]);
- R1(L, R, MK[ 6], RK[ 6]);
- R2(R, L, MK[ 7], RK[ 7]);
- R3(L, R, MK[ 8], RK[ 8]);
- R1(R, L, MK[ 9], RK[ 9]);
- R2(L, R, MK[10], RK[10]);
- R3(R, L, MK[11], RK[11]);
- R1(L, R, MK[12], RK[12]);
- R2(R, L, MK[13], RK[13]);
- R3(L, R, MK[14], RK[14]);
- R1(R, L, MK[15], RK[15]);
-
- store_be(out, R, L);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit L = load_be<u32bit>(in, 0);
+ u32bit R = load_be<u32bit>(in, 1);
+
+ R1(L, R, MK[ 0], RK[ 0]);
+ R2(R, L, MK[ 1], RK[ 1]);
+ R3(L, R, MK[ 2], RK[ 2]);
+ R1(R, L, MK[ 3], RK[ 3]);
+ R2(L, R, MK[ 4], RK[ 4]);
+ R3(R, L, MK[ 5], RK[ 5]);
+ R1(L, R, MK[ 6], RK[ 6]);
+ R2(R, L, MK[ 7], RK[ 7]);
+ R3(L, R, MK[ 8], RK[ 8]);
+ R1(R, L, MK[ 9], RK[ 9]);
+ R2(L, R, MK[10], RK[10]);
+ R3(R, L, MK[11], RK[11]);
+ R1(L, R, MK[12], RK[12]);
+ R2(R, L, MK[13], RK[13]);
+ R3(L, R, MK[14], RK[14]);
+ R1(R, L, MK[15], RK[15]);
+
+ store_be(out, R, L);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* CAST-128 Decryption
*/
-void CAST_128::dec(const byte in[], byte out[]) const
+void CAST_128::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit L = load_be<u32bit>(in, 0);
- u32bit R = load_be<u32bit>(in, 1);
-
- R1(L, R, MK[15], RK[15]);
- R3(R, L, MK[14], RK[14]);
- R2(L, R, MK[13], RK[13]);
- R1(R, L, MK[12], RK[12]);
- R3(L, R, MK[11], RK[11]);
- R2(R, L, MK[10], RK[10]);
- R1(L, R, MK[ 9], RK[ 9]);
- R3(R, L, MK[ 8], RK[ 8]);
- R2(L, R, MK[ 7], RK[ 7]);
- R1(R, L, MK[ 6], RK[ 6]);
- R3(L, R, MK[ 5], RK[ 5]);
- R2(R, L, MK[ 4], RK[ 4]);
- R1(L, R, MK[ 3], RK[ 3]);
- R3(R, L, MK[ 2], RK[ 2]);
- R2(L, R, MK[ 1], RK[ 1]);
- R1(R, L, MK[ 0], RK[ 0]);
-
- store_be(out, R, L);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit L = load_be<u32bit>(in, 0);
+ u32bit R = load_be<u32bit>(in, 1);
+
+ R1(L, R, MK[15], RK[15]);
+ R3(R, L, MK[14], RK[14]);
+ R2(L, R, MK[13], RK[13]);
+ R1(R, L, MK[12], RK[12]);
+ R3(L, R, MK[11], RK[11]);
+ R2(R, L, MK[10], RK[10]);
+ R1(L, R, MK[ 9], RK[ 9]);
+ R3(R, L, MK[ 8], RK[ 8]);
+ R2(L, R, MK[ 7], RK[ 7]);
+ R1(R, L, MK[ 6], RK[ 6]);
+ R3(L, R, MK[ 5], RK[ 5]);
+ R2(R, L, MK[ 4], RK[ 4]);
+ R1(L, R, MK[ 3], RK[ 3]);
+ R3(R, L, MK[ 2], RK[ 2]);
+ R2(L, R, MK[ 1], RK[ 1]);
+ R1(R, L, MK[ 0], RK[ 0]);
+
+ store_be(out, R, L);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/cast/cast128.h b/src/block/cast/cast128.h
index 680481482..caffb97ea 100644
--- a/src/block/cast/cast128.h
+++ b/src/block/cast/cast128.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL CAST_128 : public BlockCipher
{
public:
- void clear() throw() { MK.clear(); RK.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { MK.clear(); RK.clear(); }
std::string name() const { return "CAST-128"; }
BlockCipher* clone() const { return new CAST_128; }
+
CAST_128() : BlockCipher(8, 11, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static void key_schedule(u32bit[16], u32bit[4]);
diff --git a/src/block/cast/cast256.cpp b/src/block/cast/cast256.cpp
index 22ff876fa..7a4a4e805 100644
--- a/src/block/cast/cast256.cpp
+++ b/src/block/cast/cast256.cpp
@@ -48,77 +48,89 @@ void round3(u32bit& out, u32bit in, u32bit mask, u32bit rot)
/*
* CAST-256 Encryption
*/
-void CAST_256::enc(const byte in[], byte out[]) const
+void CAST_256::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_be<u32bit>(in, 0);
- u32bit B = load_be<u32bit>(in, 1);
- u32bit C = load_be<u32bit>(in, 2);
- u32bit D = load_be<u32bit>(in, 3);
-
- round1(C, D, MK[ 0], RK[ 0]); round2(B, C, MK[ 1], RK[ 1]);
- round3(A, B, MK[ 2], RK[ 2]); round1(D, A, MK[ 3], RK[ 3]);
- round1(C, D, MK[ 4], RK[ 4]); round2(B, C, MK[ 5], RK[ 5]);
- round3(A, B, MK[ 6], RK[ 6]); round1(D, A, MK[ 7], RK[ 7]);
- round1(C, D, MK[ 8], RK[ 8]); round2(B, C, MK[ 9], RK[ 9]);
- round3(A, B, MK[10], RK[10]); round1(D, A, MK[11], RK[11]);
- round1(C, D, MK[12], RK[12]); round2(B, C, MK[13], RK[13]);
- round3(A, B, MK[14], RK[14]); round1(D, A, MK[15], RK[15]);
- round1(C, D, MK[16], RK[16]); round2(B, C, MK[17], RK[17]);
- round3(A, B, MK[18], RK[18]); round1(D, A, MK[19], RK[19]);
- round1(C, D, MK[20], RK[20]); round2(B, C, MK[21], RK[21]);
- round3(A, B, MK[22], RK[22]); round1(D, A, MK[23], RK[23]);
- round1(D, A, MK[27], RK[27]); round3(A, B, MK[26], RK[26]);
- round2(B, C, MK[25], RK[25]); round1(C, D, MK[24], RK[24]);
- round1(D, A, MK[31], RK[31]); round3(A, B, MK[30], RK[30]);
- round2(B, C, MK[29], RK[29]); round1(C, D, MK[28], RK[28]);
- round1(D, A, MK[35], RK[35]); round3(A, B, MK[34], RK[34]);
- round2(B, C, MK[33], RK[33]); round1(C, D, MK[32], RK[32]);
- round1(D, A, MK[39], RK[39]); round3(A, B, MK[38], RK[38]);
- round2(B, C, MK[37], RK[37]); round1(C, D, MK[36], RK[36]);
- round1(D, A, MK[43], RK[43]); round3(A, B, MK[42], RK[42]);
- round2(B, C, MK[41], RK[41]); round1(C, D, MK[40], RK[40]);
- round1(D, A, MK[47], RK[47]); round3(A, B, MK[46], RK[46]);
- round2(B, C, MK[45], RK[45]); round1(C, D, MK[44], RK[44]);
-
- store_be(out, A, B, C, D);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit A = load_be<u32bit>(in, 0);
+ u32bit B = load_be<u32bit>(in, 1);
+ u32bit C = load_be<u32bit>(in, 2);
+ u32bit D = load_be<u32bit>(in, 3);
+
+ round1(C, D, MK[ 0], RK[ 0]); round2(B, C, MK[ 1], RK[ 1]);
+ round3(A, B, MK[ 2], RK[ 2]); round1(D, A, MK[ 3], RK[ 3]);
+ round1(C, D, MK[ 4], RK[ 4]); round2(B, C, MK[ 5], RK[ 5]);
+ round3(A, B, MK[ 6], RK[ 6]); round1(D, A, MK[ 7], RK[ 7]);
+ round1(C, D, MK[ 8], RK[ 8]); round2(B, C, MK[ 9], RK[ 9]);
+ round3(A, B, MK[10], RK[10]); round1(D, A, MK[11], RK[11]);
+ round1(C, D, MK[12], RK[12]); round2(B, C, MK[13], RK[13]);
+ round3(A, B, MK[14], RK[14]); round1(D, A, MK[15], RK[15]);
+ round1(C, D, MK[16], RK[16]); round2(B, C, MK[17], RK[17]);
+ round3(A, B, MK[18], RK[18]); round1(D, A, MK[19], RK[19]);
+ round1(C, D, MK[20], RK[20]); round2(B, C, MK[21], RK[21]);
+ round3(A, B, MK[22], RK[22]); round1(D, A, MK[23], RK[23]);
+ round1(D, A, MK[27], RK[27]); round3(A, B, MK[26], RK[26]);
+ round2(B, C, MK[25], RK[25]); round1(C, D, MK[24], RK[24]);
+ round1(D, A, MK[31], RK[31]); round3(A, B, MK[30], RK[30]);
+ round2(B, C, MK[29], RK[29]); round1(C, D, MK[28], RK[28]);
+ round1(D, A, MK[35], RK[35]); round3(A, B, MK[34], RK[34]);
+ round2(B, C, MK[33], RK[33]); round1(C, D, MK[32], RK[32]);
+ round1(D, A, MK[39], RK[39]); round3(A, B, MK[38], RK[38]);
+ round2(B, C, MK[37], RK[37]); round1(C, D, MK[36], RK[36]);
+ round1(D, A, MK[43], RK[43]); round3(A, B, MK[42], RK[42]);
+ round2(B, C, MK[41], RK[41]); round1(C, D, MK[40], RK[40]);
+ round1(D, A, MK[47], RK[47]); round3(A, B, MK[46], RK[46]);
+ round2(B, C, MK[45], RK[45]); round1(C, D, MK[44], RK[44]);
+
+ store_be(out, A, B, C, D);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* CAST-256 Decryption
*/
-void CAST_256::dec(const byte in[], byte out[]) const
+void CAST_256::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_be<u32bit>(in, 0);
- u32bit B = load_be<u32bit>(in, 1);
- u32bit C = load_be<u32bit>(in, 2);
- u32bit D = load_be<u32bit>(in, 3);
-
- round1(C, D, MK[44], RK[44]); round2(B, C, MK[45], RK[45]);
- round3(A, B, MK[46], RK[46]); round1(D, A, MK[47], RK[47]);
- round1(C, D, MK[40], RK[40]); round2(B, C, MK[41], RK[41]);
- round3(A, B, MK[42], RK[42]); round1(D, A, MK[43], RK[43]);
- round1(C, D, MK[36], RK[36]); round2(B, C, MK[37], RK[37]);
- round3(A, B, MK[38], RK[38]); round1(D, A, MK[39], RK[39]);
- round1(C, D, MK[32], RK[32]); round2(B, C, MK[33], RK[33]);
- round3(A, B, MK[34], RK[34]); round1(D, A, MK[35], RK[35]);
- round1(C, D, MK[28], RK[28]); round2(B, C, MK[29], RK[29]);
- round3(A, B, MK[30], RK[30]); round1(D, A, MK[31], RK[31]);
- round1(C, D, MK[24], RK[24]); round2(B, C, MK[25], RK[25]);
- round3(A, B, MK[26], RK[26]); round1(D, A, MK[27], RK[27]);
- round1(D, A, MK[23], RK[23]); round3(A, B, MK[22], RK[22]);
- round2(B, C, MK[21], RK[21]); round1(C, D, MK[20], RK[20]);
- round1(D, A, MK[19], RK[19]); round3(A, B, MK[18], RK[18]);
- round2(B, C, MK[17], RK[17]); round1(C, D, MK[16], RK[16]);
- round1(D, A, MK[15], RK[15]); round3(A, B, MK[14], RK[14]);
- round2(B, C, MK[13], RK[13]); round1(C, D, MK[12], RK[12]);
- round1(D, A, MK[11], RK[11]); round3(A, B, MK[10], RK[10]);
- round2(B, C, MK[ 9], RK[ 9]); round1(C, D, MK[ 8], RK[ 8]);
- round1(D, A, MK[ 7], RK[ 7]); round3(A, B, MK[ 6], RK[ 6]);
- round2(B, C, MK[ 5], RK[ 5]); round1(C, D, MK[ 4], RK[ 4]);
- round1(D, A, MK[ 3], RK[ 3]); round3(A, B, MK[ 2], RK[ 2]);
- round2(B, C, MK[ 1], RK[ 1]); round1(C, D, MK[ 0], RK[ 0]);
-
- store_be(out, A, B, C, D);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit A = load_be<u32bit>(in, 0);
+ u32bit B = load_be<u32bit>(in, 1);
+ u32bit C = load_be<u32bit>(in, 2);
+ u32bit D = load_be<u32bit>(in, 3);
+
+ round1(C, D, MK[44], RK[44]); round2(B, C, MK[45], RK[45]);
+ round3(A, B, MK[46], RK[46]); round1(D, A, MK[47], RK[47]);
+ round1(C, D, MK[40], RK[40]); round2(B, C, MK[41], RK[41]);
+ round3(A, B, MK[42], RK[42]); round1(D, A, MK[43], RK[43]);
+ round1(C, D, MK[36], RK[36]); round2(B, C, MK[37], RK[37]);
+ round3(A, B, MK[38], RK[38]); round1(D, A, MK[39], RK[39]);
+ round1(C, D, MK[32], RK[32]); round2(B, C, MK[33], RK[33]);
+ round3(A, B, MK[34], RK[34]); round1(D, A, MK[35], RK[35]);
+ round1(C, D, MK[28], RK[28]); round2(B, C, MK[29], RK[29]);
+ round3(A, B, MK[30], RK[30]); round1(D, A, MK[31], RK[31]);
+ round1(C, D, MK[24], RK[24]); round2(B, C, MK[25], RK[25]);
+ round3(A, B, MK[26], RK[26]); round1(D, A, MK[27], RK[27]);
+ round1(D, A, MK[23], RK[23]); round3(A, B, MK[22], RK[22]);
+ round2(B, C, MK[21], RK[21]); round1(C, D, MK[20], RK[20]);
+ round1(D, A, MK[19], RK[19]); round3(A, B, MK[18], RK[18]);
+ round2(B, C, MK[17], RK[17]); round1(C, D, MK[16], RK[16]);
+ round1(D, A, MK[15], RK[15]); round3(A, B, MK[14], RK[14]);
+ round2(B, C, MK[13], RK[13]); round1(C, D, MK[12], RK[12]);
+ round1(D, A, MK[11], RK[11]); round3(A, B, MK[10], RK[10]);
+ round2(B, C, MK[ 9], RK[ 9]); round1(C, D, MK[ 8], RK[ 8]);
+ round1(D, A, MK[ 7], RK[ 7]); round3(A, B, MK[ 6], RK[ 6]);
+ round2(B, C, MK[ 5], RK[ 5]); round1(C, D, MK[ 4], RK[ 4]);
+ round1(D, A, MK[ 3], RK[ 3]); round3(A, B, MK[ 2], RK[ 2]);
+ round2(B, C, MK[ 1], RK[ 1]); round1(C, D, MK[ 0], RK[ 0]);
+
+ store_be(out, A, B, C, D);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/cast/cast256.h b/src/block/cast/cast256.h
index cd48edd5e..0db3682ba 100644
--- a/src/block/cast/cast256.h
+++ b/src/block/cast/cast256.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL CAST_256 : public BlockCipher
{
public:
- void clear() throw() { MK.clear(); RK.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { MK.clear(); RK.clear(); }
std::string name() const { return "CAST-256"; }
BlockCipher* clone() const { return new CAST_256; }
+
CAST_256() : BlockCipher(16, 4, 32, 4) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static const u32bit KEY_MASK[192];
diff --git a/src/block/cast/info.txt b/src/block/cast/info.txt
index 73d3f900f..faba491c2 100644
--- a/src/block/cast/info.txt
+++ b/src/block/cast/info.txt
@@ -1,13 +1 @@
-realname "CAST"
-
define CAST
-
-load_on auto
-
-<add>
-cast128.cpp
-cast128.h
-cast256.cpp
-cast256.h
-cast_tab.cpp
-</add>
diff --git a/src/block/des/des.cpp b/src/block/des/des.cpp
index 37520e0fc..05287304f 100644
--- a/src/block/des/des.cpp
+++ b/src/block/des/des.cpp
@@ -139,51 +139,62 @@ void des_decrypt(u32bit& L, u32bit& R,
/*
* DES Encryption
*/
-void DES::enc(const byte in[], byte out[]) const
+void DES::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
- (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
- (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
- (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
+ (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
+ (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
+ (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
- u32bit L = static_cast<u32bit>(T >> 32);
- u32bit R = static_cast<u32bit>(T);
+ u32bit L = static_cast<u32bit>(T >> 32);
+ u32bit R = static_cast<u32bit>(T);
- des_encrypt(L, R, round_key);
+ des_encrypt(L, R, round_key);
- T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
- (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
- (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
- (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
+ T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
+ (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
+ (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
+ (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
+ T = rotate_left(T, 32);
- T = rotate_left(T, 32);
+ store_be(T, out);
- store_be(T, out);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* DES Decryption
*/
-void DES::dec(const byte in[], byte out[]) const
+void DES::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
- (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
- (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
- (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
+ (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
+ (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
+ (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
- u32bit L = static_cast<u32bit>(T >> 32);
- u32bit R = static_cast<u32bit>(T);
+ u32bit L = static_cast<u32bit>(T >> 32);
+ u32bit R = static_cast<u32bit>(T);
- des_decrypt(L, R, round_key);
+ des_decrypt(L, R, round_key);
- T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
- (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
- (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
- (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
+ T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
+ (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
+ (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
+ (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
- T = rotate_left(T, 32);
+ T = rotate_left(T, 32);
- store_be(T, out);
+ store_be(T, out);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
@@ -197,55 +208,67 @@ void DES::key_schedule(const byte key[], u32bit)
/*
* TripleDES Encryption
*/
-void TripleDES::enc(const byte in[], byte out[]) const
+void TripleDES::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
- (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
- (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
- (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
+ (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
+ (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
+ (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
- u32bit L = static_cast<u32bit>(T >> 32);
- u32bit R = static_cast<u32bit>(T);
+ u32bit L = static_cast<u32bit>(T >> 32);
+ u32bit R = static_cast<u32bit>(T);
- des_encrypt(L, R, round_key);
- des_decrypt(R, L, round_key + 32);
- des_encrypt(L, R, round_key + 64);
+ des_encrypt(L, R, round_key);
+ des_decrypt(R, L, round_key + 32);
+ des_encrypt(L, R, round_key + 64);
- T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
- (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
- (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
- (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
+ T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
+ (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
+ (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
+ (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
- T = rotate_left(T, 32);
+ T = rotate_left(T, 32);
- store_be(T, out);
+ store_be(T, out);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* TripleDES Decryption
*/
-void TripleDES::dec(const byte in[], byte out[]) const
+void TripleDES::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
- (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
- (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
- (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
+ (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
+ (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
+ (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
- u32bit L = static_cast<u32bit>(T >> 32);
- u32bit R = static_cast<u32bit>(T);
+ u32bit L = static_cast<u32bit>(T >> 32);
+ u32bit R = static_cast<u32bit>(T);
- des_decrypt(L, R, round_key + 64);
- des_encrypt(R, L, round_key + 32);
- des_decrypt(L, R, round_key);
+ des_decrypt(L, R, round_key + 64);
+ des_encrypt(R, L, round_key + 32);
+ des_decrypt(L, R, round_key);
- T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
- (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
- (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
- (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
+ T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
+ (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
+ (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
+ (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
- T = rotate_left(T, 32);
+ T = rotate_left(T, 32);
- store_be(T, out);
+ store_be(T, out);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/des/des.h b/src/block/des/des.h
index 6fa59de5e..b28990178 100644
--- a/src/block/des/des.h
+++ b/src/block/des/des.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL DES : public BlockCipher
{
public:
- void clear() throw() { round_key.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { round_key.clear(); }
std::string name() const { return "DES"; }
BlockCipher* clone() const { return new DES; }
+
DES() : BlockCipher(8, 8) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 32> round_key;
@@ -36,13 +38,15 @@ class BOTAN_DLL DES : public BlockCipher
class BOTAN_DLL TripleDES : public BlockCipher
{
public:
- void clear() throw() { round_key.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { round_key.clear(); }
std::string name() const { return "TripleDES"; }
BlockCipher* clone() const { return new TripleDES; }
+
TripleDES() : BlockCipher(8, 16, 24, 8) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 96> round_key;
diff --git a/src/block/des/desx.cpp b/src/block/des/desx.cpp
index e557901d3..1fc1c47f2 100644
--- a/src/block/des/desx.cpp
+++ b/src/block/des/desx.cpp
@@ -13,21 +13,33 @@ namespace Botan {
/*
* DESX Encryption
*/
-void DESX::enc(const byte in[], byte out[]) const
+void DESX::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- xor_buf(out, in, K1.begin(), BLOCK_SIZE);
- des.encrypt(out);
- xor_buf(out, K2.begin(), BLOCK_SIZE);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ xor_buf(out, in, K1.begin(), BLOCK_SIZE);
+ des.encrypt(out);
+ xor_buf(out, K2.begin(), BLOCK_SIZE);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* DESX Decryption
*/
-void DESX::dec(const byte in[], byte out[]) const
+void DESX::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- xor_buf(out, in, K2.begin(), BLOCK_SIZE);
- des.decrypt(out);
- xor_buf(out, K1.begin(), BLOCK_SIZE);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ xor_buf(out, in, K2.begin(), BLOCK_SIZE);
+ des.decrypt(out);
+ xor_buf(out, K1.begin(), BLOCK_SIZE);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/des/desx.h b/src/block/des/desx.h
index 49ecc2421..89664d064 100644
--- a/src/block/des/desx.h
+++ b/src/block/des/desx.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL DESX : public BlockCipher
{
public:
- void clear() throw() { des.clear(); K1.clear(); K2.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { des.clear(); K1.clear(); K2.clear(); }
std::string name() const { return "DESX"; }
BlockCipher* clone() const { return new DESX; }
+
DESX() : BlockCipher(8, 24) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<byte, 8> K1, K2;
DES des;
diff --git a/src/block/des/info.txt b/src/block/des/info.txt
index ed05979c9..8e4f4e82d 100644
--- a/src/block/des/info.txt
+++ b/src/block/des/info.txt
@@ -1,13 +1 @@
-realname "DES"
-
define DES
-
-load_on auto
-
-<add>
-des.cpp
-des.h
-des_tab.cpp
-desx.h
-desx.cpp
-</add>
diff --git a/src/block/gost_28147/gost_28147.cpp b/src/block/gost_28147/gost_28147.cpp
index bfd092c56..272f1bcab 100644
--- a/src/block/gost_28147/gost_28147.cpp
+++ b/src/block/gost_28147/gost_28147.cpp
@@ -84,47 +84,58 @@ GOST_28147_89::GOST_28147_89(const GOST_28147_89_Params& param) :
/*
* GOST Encryption
*/
-void GOST_28147_89::enc(const byte in[], byte out[]) const
+void GOST_28147_89::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1);
-
- for(size_t i = 0; i != 3; ++i)
+ for(u32bit i = 0; i != blocks; ++i)
{
- GOST_2ROUND(N1, N2, 0, 1);
- GOST_2ROUND(N1, N2, 2, 3);
- GOST_2ROUND(N1, N2, 4, 5);
- GOST_2ROUND(N1, N2, 6, 7);
- }
+ u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1);
- GOST_2ROUND(N1, N2, 7, 6);
- GOST_2ROUND(N1, N2, 5, 4);
- GOST_2ROUND(N1, N2, 3, 2);
- GOST_2ROUND(N1, N2, 1, 0);
+ for(size_t j = 0; j != 3; ++j)
+ {
+ GOST_2ROUND(N1, N2, 0, 1);
+ GOST_2ROUND(N1, N2, 2, 3);
+ GOST_2ROUND(N1, N2, 4, 5);
+ GOST_2ROUND(N1, N2, 6, 7);
+ }
- store_le(out, N2, N1);
+ GOST_2ROUND(N1, N2, 7, 6);
+ GOST_2ROUND(N1, N2, 5, 4);
+ GOST_2ROUND(N1, N2, 3, 2);
+ GOST_2ROUND(N1, N2, 1, 0);
+
+ store_le(out, N2, N1);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* GOST Decryption
*/
-void GOST_28147_89::dec(const byte in[], byte out[]) const
+void GOST_28147_89::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1);
- GOST_2ROUND(N1, N2, 0, 1);
- GOST_2ROUND(N1, N2, 2, 3);
- GOST_2ROUND(N1, N2, 4, 5);
- GOST_2ROUND(N1, N2, 6, 7);
+ GOST_2ROUND(N1, N2, 0, 1);
+ GOST_2ROUND(N1, N2, 2, 3);
+ GOST_2ROUND(N1, N2, 4, 5);
+ GOST_2ROUND(N1, N2, 6, 7);
- for(size_t i = 0; i != 3; ++i)
- {
- GOST_2ROUND(N1, N2, 7, 6);
- GOST_2ROUND(N1, N2, 5, 4);
- GOST_2ROUND(N1, N2, 3, 2);
- GOST_2ROUND(N1, N2, 1, 0);
- }
+ for(size_t i = 0; i != 3; ++i)
+ {
+ GOST_2ROUND(N1, N2, 7, 6);
+ GOST_2ROUND(N1, N2, 5, 4);
+ GOST_2ROUND(N1, N2, 3, 2);
+ GOST_2ROUND(N1, N2, 1, 0);
+ }
- store_le(out, N2, N1);
+ store_le(out, N2, N1);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/gost_28147/gost_28147.h b/src/block/gost_28147/gost_28147.h
index 96d24c669..bf6f8178b 100644
--- a/src/block/gost_28147/gost_28147.h
+++ b/src/block/gost_28147/gost_28147.h
@@ -44,7 +44,10 @@ class GOST_28147_89_Params
class BOTAN_DLL GOST_28147_89 : public BlockCipher
{
public:
- void clear() throw() { EK.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { EK.clear(); }
std::string name() const { return "GOST-28147-89"; }
BlockCipher* clone() const { return new GOST_28147_89(SBOX); }
@@ -54,8 +57,6 @@ class BOTAN_DLL GOST_28147_89 : public BlockCipher
GOST_28147_89(const SecureBuffer<u32bit, 1024>& other_SBOX) :
BlockCipher(8, 32), SBOX(other_SBOX) {}
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 1024> SBOX;
diff --git a/src/block/gost_28147/info.txt b/src/block/gost_28147/info.txt
index 6e187fd48..530f147e5 100644
--- a/src/block/gost_28147/info.txt
+++ b/src/block/gost_28147/info.txt
@@ -1,10 +1 @@
-realname "GOST 28147-89"
-
define GOST_28147_89
-
-load_on auto
-
-<add>
-gost_28147.cpp
-gost_28147.h
-</add>
diff --git a/src/block/idea/idea.cpp b/src/block/idea/idea.cpp
index 5bbe47087..fb5fe83f1 100644
--- a/src/block/idea/idea.cpp
+++ b/src/block/idea/idea.cpp
@@ -60,77 +60,89 @@ u16bit mul_inv(u16bit x)
/*
* IDEA Encryption
*/
-void IDEA::enc(const byte in[], byte out[]) const
+void IDEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit X1 = load_be<u16bit>(in, 0);
- u16bit X2 = load_be<u16bit>(in, 1);
- u16bit X3 = load_be<u16bit>(in, 2);
- u16bit X4 = load_be<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 8; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- X1 = mul(X1, EK[6*j+0]);
- X2 += EK[6*j+1];
- X3 += EK[6*j+2];
- X4 = mul(X4, EK[6*j+3]);
-
- u16bit T0 = X3;
- X3 = mul(X3 ^ X1, EK[6*j+4]);
-
- u16bit T1 = X2;
- X2 = mul((X2 ^ X4) + X3, EK[6*j+5]);
- X3 += X2;
-
- X1 ^= X2;
- X4 ^= X3;
- X2 ^= T0;
- X3 ^= T1;
+ u16bit X1 = load_be<u16bit>(in, 0);
+ u16bit X2 = load_be<u16bit>(in, 1);
+ u16bit X3 = load_be<u16bit>(in, 2);
+ u16bit X4 = load_be<u16bit>(in, 3);
+
+ for(u32bit j = 0; j != 8; ++j)
+ {
+ X1 = mul(X1, EK[6*j+0]);
+ X2 += EK[6*j+1];
+ X3 += EK[6*j+2];
+ X4 = mul(X4, EK[6*j+3]);
+
+ u16bit T0 = X3;
+ X3 = mul(X3 ^ X1, EK[6*j+4]);
+
+ u16bit T1 = X2;
+ X2 = mul((X2 ^ X4) + X3, EK[6*j+5]);
+ X3 += X2;
+
+ X1 ^= X2;
+ X4 ^= X3;
+ X2 ^= T0;
+ X3 ^= T1;
+ }
+
+ X1 = mul(X1, EK[48]);
+ X2 += EK[50];
+ X3 += EK[49];
+ X4 = mul(X4, EK[51]);
+
+ store_be(out, X1, X3, X2, X4);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
-
- X1 = mul(X1, EK[48]);
- X2 += EK[50];
- X3 += EK[49];
- X4 = mul(X4, EK[51]);
-
- store_be(out, X1, X3, X2, X4);
}
/*
* IDEA Decryption
*/
-void IDEA::dec(const byte in[], byte out[]) const
+void IDEA::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit X1 = load_be<u16bit>(in, 0);
- u16bit X2 = load_be<u16bit>(in, 1);
- u16bit X3 = load_be<u16bit>(in, 2);
- u16bit X4 = load_be<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 8; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- X1 = mul(X1, DK[6*j+0]);
- X2 += DK[6*j+1];
- X3 += DK[6*j+2];
- X4 = mul(X4, DK[6*j+3]);
-
- u16bit T0 = X3;
- X3 = mul(X3 ^ X1, DK[6*j+4]);
-
- u16bit T1 = X2;
- X2 = mul((X2 ^ X4) + X3, DK[6*j+5]);
- X3 += X2;
-
- X1 ^= X2;
- X4 ^= X3;
- X2 ^= T0;
- X3 ^= T1;
+ u16bit X1 = load_be<u16bit>(in, 0);
+ u16bit X2 = load_be<u16bit>(in, 1);
+ u16bit X3 = load_be<u16bit>(in, 2);
+ u16bit X4 = load_be<u16bit>(in, 3);
+
+ for(u32bit j = 0; j != 8; ++j)
+ {
+ X1 = mul(X1, DK[6*j+0]);
+ X2 += DK[6*j+1];
+ X3 += DK[6*j+2];
+ X4 = mul(X4, DK[6*j+3]);
+
+ u16bit T0 = X3;
+ X3 = mul(X3 ^ X1, DK[6*j+4]);
+
+ u16bit T1 = X2;
+ X2 = mul((X2 ^ X4) + X3, DK[6*j+5]);
+ X3 += X2;
+
+ X1 ^= X2;
+ X4 ^= X3;
+ X2 ^= T0;
+ X3 ^= T1;
+ }
+
+ X1 = mul(X1, DK[48]);
+ X2 += DK[50];
+ X3 += DK[49];
+ X4 = mul(X4, DK[51]);
+
+ store_be(out, X1, X3, X2, X4);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
-
- X1 = mul(X1, DK[48]);
- X2 += DK[50];
- X3 += DK[49];
- X4 = mul(X4, DK[51]);
-
- store_be(out, X1, X3, X2, X4);
}
/*
diff --git a/src/block/idea/idea.h b/src/block/idea/idea.h
index 2c53cd0e4..c1a79f423 100644
--- a/src/block/idea/idea.h
+++ b/src/block/idea/idea.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL IDEA : public BlockCipher
{
public:
- void clear() throw() { EK.clear(); DK.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { EK.clear(); DK.clear(); }
std::string name() const { return "IDEA"; }
BlockCipher* clone() const { return new IDEA; }
+
IDEA() : BlockCipher(8, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u16bit, 52> EK, DK;
};
diff --git a/src/block/idea/info.txt b/src/block/idea/info.txt
index 2da3ffb43..a868d7cc7 100644
--- a/src/block/idea/info.txt
+++ b/src/block/idea/info.txt
@@ -1,10 +1 @@
-realname "IDEA"
-
define IDEA
-
-load_on auto
-
-<add>
-idea.cpp
-idea.h
-</add>
diff --git a/src/block/info.txt b/src/block/info.txt
index ff48fb04a..b4302a6d8 100644
--- a/src/block/info.txt
+++ b/src/block/info.txt
@@ -1,13 +1,5 @@
-realname "Block Ciphers"
-
-load_on auto
-
define BLOCK_CIPHER
-<add>
-block_cipher.h
-</add>
-
<requires>
sym_algo
</requires>
diff --git a/src/block/kasumi/info.txt b/src/block/kasumi/info.txt
index 8ea879b6d..cb8340fad 100644
--- a/src/block/kasumi/info.txt
+++ b/src/block/kasumi/info.txt
@@ -1,10 +1 @@
-realname "Kasumi"
-
define KASUMI
-
-load_on auto
-
-<add>
-kasumi.cpp
-kasumi.h
-</add>
diff --git a/src/block/kasumi/kasumi.cpp b/src/block/kasumi/kasumi.cpp
index e051ddefb..dff6db13c 100644
--- a/src/block/kasumi/kasumi.cpp
+++ b/src/block/kasumi/kasumi.cpp
@@ -109,79 +109,91 @@ u16bit FI(u16bit I, u16bit K)
/*
* KASUMI Encryption
*/
-void KASUMI::enc(const byte in[], byte out[]) const
+void KASUMI::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit B0 = load_be<u16bit>(in, 0);
- u16bit B1 = load_be<u16bit>(in, 1);
- u16bit B2 = load_be<u16bit>(in, 2);
- u16bit B3 = load_be<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 8; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- const u16bit* K = EK + 8*j;
+ u16bit B0 = load_be<u16bit>(in, 0);
+ u16bit B1 = load_be<u16bit>(in, 1);
+ u16bit B2 = load_be<u16bit>(in, 2);
+ u16bit B3 = load_be<u16bit>(in, 3);
- u16bit R = B1 ^ (rotate_left(B0, 1) & K[0]);
- u16bit L = B0 ^ (rotate_left(R, 1) | K[1]);
+ for(u32bit j = 0; j != 8; j += 2)
+ {
+ const u16bit* K = EK + 8*j;
- L = FI(L ^ K[ 2], K[ 3]) ^ R;
- R = FI(R ^ K[ 4], K[ 5]) ^ L;
- L = FI(L ^ K[ 6], K[ 7]) ^ R;
+ u16bit R = B1 ^ (rotate_left(B0, 1) & K[0]);
+ u16bit L = B0 ^ (rotate_left(R, 1) | K[1]);
- R = B2 ^= R;
- L = B3 ^= L;
+ L = FI(L ^ K[ 2], K[ 3]) ^ R;
+ R = FI(R ^ K[ 4], K[ 5]) ^ L;
+ L = FI(L ^ K[ 6], K[ 7]) ^ R;
- R = FI(R ^ K[10], K[11]) ^ L;
- L = FI(L ^ K[12], K[13]) ^ R;
- R = FI(R ^ K[14], K[15]) ^ L;
+ R = B2 ^= R;
+ L = B3 ^= L;
- R ^= (rotate_left(L, 1) & K[8]);
- L ^= (rotate_left(R, 1) | K[9]);
+ R = FI(R ^ K[10], K[11]) ^ L;
+ L = FI(L ^ K[12], K[13]) ^ R;
+ R = FI(R ^ K[14], K[15]) ^ L;
- B0 ^= L;
- B1 ^= R;
- }
+ R ^= (rotate_left(L, 1) & K[8]);
+ L ^= (rotate_left(R, 1) | K[9]);
+
+ B0 ^= L;
+ B1 ^= R;
+ }
- store_be(out, B0, B1, B2, B3);
+ store_be(out, B0, B1, B2, B3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* KASUMI Decryption
*/
-void KASUMI::dec(const byte in[], byte out[]) const
+void KASUMI::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit B0 = load_be<u16bit>(in, 0);
- u16bit B1 = load_be<u16bit>(in, 1);
- u16bit B2 = load_be<u16bit>(in, 2);
- u16bit B3 = load_be<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 8; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- const u16bit* K = EK + 8*(6-j);
+ u16bit B0 = load_be<u16bit>(in, 0);
+ u16bit B1 = load_be<u16bit>(in, 1);
+ u16bit B2 = load_be<u16bit>(in, 2);
+ u16bit B3 = load_be<u16bit>(in, 3);
- u16bit L = B2, R = B3;
+ for(u32bit j = 0; j != 8; j += 2)
+ {
+ const u16bit* K = EK + 8*(6-j);
- L = FI(L ^ K[10], K[11]) ^ R;
- R = FI(R ^ K[12], K[13]) ^ L;
- L = FI(L ^ K[14], K[15]) ^ R;
+ u16bit L = B2, R = B3;
- L ^= (rotate_left(R, 1) & K[8]);
- R ^= (rotate_left(L, 1) | K[9]);
+ L = FI(L ^ K[10], K[11]) ^ R;
+ R = FI(R ^ K[12], K[13]) ^ L;
+ L = FI(L ^ K[14], K[15]) ^ R;
- R = B0 ^= R;
- L = B1 ^= L;
+ L ^= (rotate_left(R, 1) & K[8]);
+ R ^= (rotate_left(L, 1) | K[9]);
- L ^= (rotate_left(R, 1) & K[0]);
- R ^= (rotate_left(L, 1) | K[1]);
+ R = B0 ^= R;
+ L = B1 ^= L;
- R = FI(R ^ K[2], K[3]) ^ L;
- L = FI(L ^ K[4], K[5]) ^ R;
- R = FI(R ^ K[6], K[7]) ^ L;
+ L ^= (rotate_left(R, 1) & K[0]);
+ R ^= (rotate_left(L, 1) | K[1]);
- B2 ^= L;
- B3 ^= R;
- }
+ R = FI(R ^ K[2], K[3]) ^ L;
+ L = FI(L ^ K[4], K[5]) ^ R;
+ R = FI(R ^ K[6], K[7]) ^ L;
+
+ B2 ^= L;
+ B3 ^= R;
+ }
- store_be(out, B0, B1, B2, B3);
+ store_be(out, B0, B1, B2, B3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/kasumi/kasumi.h b/src/block/kasumi/kasumi.h
index df49fa9eb..c3db1cb05 100644
--- a/src/block/kasumi/kasumi.h
+++ b/src/block/kasumi/kasumi.h
@@ -18,14 +18,15 @@ namespace Botan {
class BOTAN_DLL KASUMI : public BlockCipher
{
public:
- void clear() throw() { EK.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { EK.clear(); }
std::string name() const { return "KASUMI"; }
BlockCipher* clone() const { return new KASUMI; }
KASUMI() : BlockCipher(8, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u16bit, 64> EK;
diff --git a/src/block/lion/info.txt b/src/block/lion/info.txt
index 81ef58511..9562be1d0 100644
--- a/src/block/lion/info.txt
+++ b/src/block/lion/info.txt
@@ -1,14 +1,5 @@
-realname "Lion"
-
define LION
-load_on auto
-
-<add>
-lion.cpp
-lion.h
-</add>
-
<requires>
hash
stream
diff --git a/src/block/lion/lion.cpp b/src/block/lion/lion.cpp
index c7cdf6d13..e71091258 100644
--- a/src/block/lion/lion.cpp
+++ b/src/block/lion/lion.cpp
@@ -14,41 +14,53 @@ namespace Botan {
/*
* Lion Encryption
*/
-void Lion::enc(const byte in[], byte out[]) const
+void Lion::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
SecureVector<byte> buffer(LEFT_SIZE);
- xor_buf(buffer, in, key1, LEFT_SIZE);
- cipher->set_key(buffer, LEFT_SIZE);
- cipher->encrypt(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ xor_buf(buffer, in, key1, LEFT_SIZE);
+ cipher->set_key(buffer, LEFT_SIZE);
+ cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE);
- hash->update(out + LEFT_SIZE, RIGHT_SIZE);
- hash->final(buffer);
- xor_buf(out, in, buffer, LEFT_SIZE);
+ hash->update(out + LEFT_SIZE, RIGHT_SIZE);
+ hash->final(buffer);
+ xor_buf(out, in, buffer, LEFT_SIZE);
- xor_buf(buffer, out, key2, LEFT_SIZE);
- cipher->set_key(buffer, LEFT_SIZE);
- cipher->encrypt(out + LEFT_SIZE, RIGHT_SIZE);
+ xor_buf(buffer, out, key2, LEFT_SIZE);
+ cipher->set_key(buffer, LEFT_SIZE);
+ cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Lion Decryption
*/
-void Lion::dec(const byte in[], byte out[]) const
+void Lion::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
SecureVector<byte> buffer(LEFT_SIZE);
- xor_buf(buffer, in, key2, LEFT_SIZE);
- cipher->set_key(buffer, LEFT_SIZE);
- cipher->encrypt(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ xor_buf(buffer, in, key2, LEFT_SIZE);
+ cipher->set_key(buffer, LEFT_SIZE);
+ cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE);
+
+ hash->update(out + LEFT_SIZE, RIGHT_SIZE);
+ hash->final(buffer);
+ xor_buf(out, in, buffer, LEFT_SIZE);
- hash->update(out + LEFT_SIZE, RIGHT_SIZE);
- hash->final(buffer);
- xor_buf(out, in, buffer, LEFT_SIZE);
+ xor_buf(buffer, out, key1, LEFT_SIZE);
+ cipher->set_key(buffer, LEFT_SIZE);
+ cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE);
- xor_buf(buffer, out, key1, LEFT_SIZE);
- cipher->set_key(buffer, LEFT_SIZE);
- cipher->encrypt(out + LEFT_SIZE, RIGHT_SIZE);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
@@ -83,7 +95,7 @@ BlockCipher* Lion::clone() const
/*
* Clear memory of sensitive data
*/
-void Lion::clear() throw()
+void Lion::clear()
{
hash->clear();
cipher->clear();
diff --git a/src/block/lion/lion.h b/src/block/lion/lion.h
index 5bc4e72c0..f24acdb72 100644
--- a/src/block/lion/lion.h
+++ b/src/block/lion/lion.h
@@ -20,15 +20,16 @@ namespace Botan {
class BOTAN_DLL Lion : public BlockCipher
{
public:
- void clear() throw();
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear();
std::string name() const;
BlockCipher* clone() const;
Lion(HashFunction*, StreamCipher*, u32bit);
~Lion() { delete hash; delete cipher; }
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
const u32bit LEFT_SIZE, RIGHT_SIZE;
diff --git a/src/block/lubyrack/info.txt b/src/block/lubyrack/info.txt
index a478526f4..41c395097 100644
--- a/src/block/lubyrack/info.txt
+++ b/src/block/lubyrack/info.txt
@@ -1,14 +1,5 @@
-realname "Luby-Rackoff"
-
define LUBY_RACKOFF
-load_on auto
-
-<add>
-lubyrack.cpp
-lubyrack.h
-</add>
-
<requires>
hash
</requires>
diff --git a/src/block/lubyrack/lubyrack.cpp b/src/block/lubyrack/lubyrack.cpp
index a9d2b1db2..2003d2a89 100644
--- a/src/block/lubyrack/lubyrack.cpp
+++ b/src/block/lubyrack/lubyrack.cpp
@@ -13,59 +13,71 @@ namespace Botan {
/*
* Luby-Rackoff Encryption
*/
-void LubyRackoff::enc(const byte in[], byte out[]) const
+void LubyRackoff::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- const u32bit len = hash->OUTPUT_LENGTH;
-
- SecureVector<byte> buffer(len);
- hash->update(K1);
- hash->update(in, len);
- hash->final(buffer);
- xor_buf(out + len, in + len, buffer, len);
-
- hash->update(K2);
- hash->update(out + len, len);
- hash->final(buffer);
- xor_buf(out, in, buffer, len);
-
- hash->update(K1);
- hash->update(out, len);
- hash->final(buffer);
- xor_buf(out + len, buffer, len);
-
- hash->update(K2);
- hash->update(out + len, len);
- hash->final(buffer);
- xor_buf(out, buffer, len);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ const u32bit len = hash->OUTPUT_LENGTH;
+
+ SecureVector<byte> buffer(len);
+ hash->update(K1);
+ hash->update(in, len);
+ hash->final(buffer);
+ xor_buf(out + len, in + len, buffer, len);
+
+ hash->update(K2);
+ hash->update(out + len, len);
+ hash->final(buffer);
+ xor_buf(out, in, buffer, len);
+
+ hash->update(K1);
+ hash->update(out, len);
+ hash->final(buffer);
+ xor_buf(out + len, buffer, len);
+
+ hash->update(K2);
+ hash->update(out + len, len);
+ hash->final(buffer);
+ xor_buf(out, buffer, len);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Luby-Rackoff Decryption
*/
-void LubyRackoff::dec(const byte in[], byte out[]) const
+void LubyRackoff::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- const u32bit len = hash->OUTPUT_LENGTH;
-
- SecureVector<byte> buffer(len);
- hash->update(K2);
- hash->update(in + len, len);
- hash->final(buffer);
- xor_buf(out, in, buffer, len);
-
- hash->update(K1);
- hash->update(out, len);
- hash->final(buffer);
- xor_buf(out + len, in + len, buffer, len);
-
- hash->update(K2);
- hash->update(out + len, len);
- hash->final(buffer);
- xor_buf(out, buffer, len);
-
- hash->update(K1);
- hash->update(out, len);
- hash->final(buffer);
- xor_buf(out + len, buffer, len);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ const u32bit len = hash->OUTPUT_LENGTH;
+
+ SecureVector<byte> buffer(len);
+ hash->update(K2);
+ hash->update(in + len, len);
+ hash->final(buffer);
+ xor_buf(out, in, buffer, len);
+
+ hash->update(K1);
+ hash->update(out, len);
+ hash->final(buffer);
+ xor_buf(out + len, in + len, buffer, len);
+
+ hash->update(K2);
+ hash->update(out + len, len);
+ hash->final(buffer);
+ xor_buf(out, buffer, len);
+
+ hash->update(K1);
+ hash->update(out, len);
+ hash->final(buffer);
+ xor_buf(out + len, buffer, len);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
@@ -80,7 +92,7 @@ void LubyRackoff::key_schedule(const byte key[], u32bit length)
/*
* Clear memory of sensitive data
*/
-void LubyRackoff::clear() throw()
+void LubyRackoff::clear()
{
K1.clear();
K2.clear();
diff --git a/src/block/lubyrack/lubyrack.h b/src/block/lubyrack/lubyrack.h
index ebde31304..7249cf157 100644
--- a/src/block/lubyrack/lubyrack.h
+++ b/src/block/lubyrack/lubyrack.h
@@ -19,16 +19,18 @@ namespace Botan {
class BOTAN_DLL LubyRackoff : public BlockCipher
{
public:
- void clear() throw();
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear();
std::string name() const;
BlockCipher* clone() const;
LubyRackoff(HashFunction* hash);
~LubyRackoff() { delete hash; }
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
+
HashFunction* hash;
SecureVector<byte> K1, K2;
};
diff --git a/src/block/mars/info.txt b/src/block/mars/info.txt
index b0ad8af9c..afdcebe67 100644
--- a/src/block/mars/info.txt
+++ b/src/block/mars/info.txt
@@ -1,11 +1 @@
-realname "MARS"
-
define MARS
-
-load_on auto
-
-<add>
-mars.cpp
-mars.h
-mars_tab.cpp
-</add>
diff --git a/src/block/mars/mars.cpp b/src/block/mars/mars.cpp
index 08c8409c5..69556acb3 100644
--- a/src/block/mars/mars.cpp
+++ b/src/block/mars/mars.cpp
@@ -1,6 +1,6 @@
/*
* MARS
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -50,75 +50,87 @@ u32bit gen_mask(u32bit input)
/*
* MARS Encryption
*/
-void MARS::enc(const byte in[], byte out[]) const
+void MARS::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0) + EK[0];
- u32bit B = load_le<u32bit>(in, 1) + EK[1];
- u32bit C = load_le<u32bit>(in, 2) + EK[2];
- u32bit D = load_le<u32bit>(in, 3) + EK[3];
-
- forward_mix(A, B, C, D);
-
- encrypt_round(A, B, C, D, 0);
- encrypt_round(B, C, D, A, 1);
- encrypt_round(C, D, A, B, 2);
- encrypt_round(D, A, B, C, 3);
- encrypt_round(A, B, C, D, 4);
- encrypt_round(B, C, D, A, 5);
- encrypt_round(C, D, A, B, 6);
- encrypt_round(D, A, B, C, 7);
-
- encrypt_round(A, D, C, B, 8);
- encrypt_round(B, A, D, C, 9);
- encrypt_round(C, B, A, D, 10);
- encrypt_round(D, C, B, A, 11);
- encrypt_round(A, D, C, B, 12);
- encrypt_round(B, A, D, C, 13);
- encrypt_round(C, B, A, D, 14);
- encrypt_round(D, C, B, A, 15);
-
- reverse_mix(A, B, C, D);
-
- A -= EK[36]; B -= EK[37]; C -= EK[38]; D -= EK[39];
-
- store_le(out, A, B, C, D);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit A = load_le<u32bit>(in, 0) + EK[0];
+ u32bit B = load_le<u32bit>(in, 1) + EK[1];
+ u32bit C = load_le<u32bit>(in, 2) + EK[2];
+ u32bit D = load_le<u32bit>(in, 3) + EK[3];
+
+ forward_mix(A, B, C, D);
+
+ encrypt_round(A, B, C, D, 0);
+ encrypt_round(B, C, D, A, 1);
+ encrypt_round(C, D, A, B, 2);
+ encrypt_round(D, A, B, C, 3);
+ encrypt_round(A, B, C, D, 4);
+ encrypt_round(B, C, D, A, 5);
+ encrypt_round(C, D, A, B, 6);
+ encrypt_round(D, A, B, C, 7);
+
+ encrypt_round(A, D, C, B, 8);
+ encrypt_round(B, A, D, C, 9);
+ encrypt_round(C, B, A, D, 10);
+ encrypt_round(D, C, B, A, 11);
+ encrypt_round(A, D, C, B, 12);
+ encrypt_round(B, A, D, C, 13);
+ encrypt_round(C, B, A, D, 14);
+ encrypt_round(D, C, B, A, 15);
+
+ reverse_mix(A, B, C, D);
+
+ A -= EK[36]; B -= EK[37]; C -= EK[38]; D -= EK[39];
+
+ store_le(out, A, B, C, D);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* MARS Decryption
*/
-void MARS::dec(const byte in[], byte out[]) const
+void MARS::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 3) + EK[39];
- u32bit B = load_le<u32bit>(in, 2) + EK[38];
- u32bit C = load_le<u32bit>(in, 1) + EK[37];
- u32bit D = load_le<u32bit>(in, 0) + EK[36];
-
- forward_mix(A, B, C, D);
-
- decrypt_round(A, B, C, D, 15);
- decrypt_round(B, C, D, A, 14);
- decrypt_round(C, D, A, B, 13);
- decrypt_round(D, A, B, C, 12);
- decrypt_round(A, B, C, D, 11);
- decrypt_round(B, C, D, A, 10);
- decrypt_round(C, D, A, B, 9);
- decrypt_round(D, A, B, C, 8);
-
- decrypt_round(A, D, C, B, 7);
- decrypt_round(B, A, D, C, 6);
- decrypt_round(C, B, A, D, 5);
- decrypt_round(D, C, B, A, 4);
- decrypt_round(A, D, C, B, 3);
- decrypt_round(B, A, D, C, 2);
- decrypt_round(C, B, A, D, 1);
- decrypt_round(D, C, B, A, 0);
-
- reverse_mix(A, B, C, D);
-
- A -= EK[3]; B -= EK[2]; C -= EK[1]; D -= EK[0];
-
- store_le(out, D, C, B, A);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit A = load_le<u32bit>(in, 3) + EK[39];
+ u32bit B = load_le<u32bit>(in, 2) + EK[38];
+ u32bit C = load_le<u32bit>(in, 1) + EK[37];
+ u32bit D = load_le<u32bit>(in, 0) + EK[36];
+
+ forward_mix(A, B, C, D);
+
+ decrypt_round(A, B, C, D, 15);
+ decrypt_round(B, C, D, A, 14);
+ decrypt_round(C, D, A, B, 13);
+ decrypt_round(D, A, B, C, 12);
+ decrypt_round(A, B, C, D, 11);
+ decrypt_round(B, C, D, A, 10);
+ decrypt_round(C, D, A, B, 9);
+ decrypt_round(D, A, B, C, 8);
+
+ decrypt_round(A, D, C, B, 7);
+ decrypt_round(B, A, D, C, 6);
+ decrypt_round(C, B, A, D, 5);
+ decrypt_round(D, C, B, A, 4);
+ decrypt_round(A, D, C, B, 3);
+ decrypt_round(B, A, D, C, 2);
+ decrypt_round(C, B, A, D, 1);
+ decrypt_round(D, C, B, A, 0);
+
+ reverse_mix(A, B, C, D);
+
+ A -= EK[3]; B -= EK[2]; C -= EK[1]; D -= EK[0];
+
+ store_le(out, D, C, B, A);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/mars/mars.h b/src/block/mars/mars.h
index ca49695af..8173fb984 100644
--- a/src/block/mars/mars.h
+++ b/src/block/mars/mars.h
@@ -15,13 +15,15 @@ namespace Botan {
class BOTAN_DLL MARS : public BlockCipher
{
public:
- void clear() throw() { EK.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { EK.clear(); }
std::string name() const { return "MARS"; }
BlockCipher* clone() const { return new MARS; }
+
MARS() : BlockCipher(16, 16, 32, 4) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
void encrypt_round(u32bit&, u32bit&, u32bit&, u32bit&, u32bit) const;
diff --git a/src/block/misty1/info.txt b/src/block/misty1/info.txt
index d45058bd4..290b8b1d7 100644
--- a/src/block/misty1/info.txt
+++ b/src/block/misty1/info.txt
@@ -1,10 +1 @@
-realname "MISTY-1"
-
define MISTY1
-
-load_on auto
-
-<add>
-misty1.cpp
-misty1.h
-</add>
diff --git a/src/block/misty1/misty1.cpp b/src/block/misty1/misty1.cpp
index a35ff584d..8a92824cc 100644
--- a/src/block/misty1/misty1.cpp
+++ b/src/block/misty1/misty1.cpp
@@ -1,6 +1,6 @@
/*
* MISTY1
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -102,89 +102,101 @@ u16bit FI(u16bit input, u16bit key7, u16bit key9)
/*
* MISTY1 Encryption
*/
-void MISTY1::enc(const byte in[], byte out[]) const
+void MISTY1::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit B0 = load_be<u16bit>(in, 0);
- u16bit B1 = load_be<u16bit>(in, 1);
- u16bit B2 = load_be<u16bit>(in, 2);
- u16bit B3 = load_be<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 12; j += 3)
+ for(u32bit i = 0; i != blocks; ++i)
{
- const u16bit* RK = EK + 8 * j;
+ u16bit B0 = load_be<u16bit>(in, 0);
+ u16bit B1 = load_be<u16bit>(in, 1);
+ u16bit B2 = load_be<u16bit>(in, 2);
+ u16bit B3 = load_be<u16bit>(in, 3);
- B1 ^= B0 & RK[0];
- B0 ^= B1 | RK[1];
- B3 ^= B2 & RK[2];
- B2 ^= B3 | RK[3];
+ for(u32bit j = 0; j != 12; j += 3)
+ {
+ const u16bit* RK = EK + 8 * j;
- u32bit T0, T1;
+ B1 ^= B0 & RK[0];
+ B0 ^= B1 | RK[1];
+ B3 ^= B2 & RK[2];
+ B2 ^= B3 | RK[3];
- T0 = FI(B0 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B1;
- T1 = FI(B1 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0;
- T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1;
+ u32bit T0, T1;
- B2 ^= T1 ^ RK[13];
- B3 ^= T0;
+ T0 = FI(B0 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B1;
+ T1 = FI(B1 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0;
+ T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1;
- T0 = FI(B2 ^ RK[14], RK[15], RK[16]) ^ B3;
- T1 = FI(B3 ^ RK[17], RK[18], RK[19]) ^ T0;
- T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1;
+ B2 ^= T1 ^ RK[13];
+ B3 ^= T0;
- B0 ^= T1 ^ RK[23];
- B1 ^= T0;
- }
+ T0 = FI(B2 ^ RK[14], RK[15], RK[16]) ^ B3;
+ T1 = FI(B3 ^ RK[17], RK[18], RK[19]) ^ T0;
+ T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1;
+
+ B0 ^= T1 ^ RK[23];
+ B1 ^= T0;
+ }
- B1 ^= B0 & EK[96];
- B0 ^= B1 | EK[97];
- B3 ^= B2 & EK[98];
- B2 ^= B3 | EK[99];
+ B1 ^= B0 & EK[96];
+ B0 ^= B1 | EK[97];
+ B3 ^= B2 & EK[98];
+ B2 ^= B3 | EK[99];
- store_be(out, B2, B3, B0, B1);
+ store_be(out, B2, B3, B0, B1);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* MISTY1 Decryption
*/
-void MISTY1::dec(const byte in[], byte out[]) const
+void MISTY1::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit B0 = load_be<u16bit>(in, 2);
- u16bit B1 = load_be<u16bit>(in, 3);
- u16bit B2 = load_be<u16bit>(in, 0);
- u16bit B3 = load_be<u16bit>(in, 1);
-
- for(u32bit j = 0; j != 12; j += 3)
+ for(u32bit i = 0; i != blocks; ++i)
{
- const u16bit* RK = DK + 8 * j;
+ u16bit B0 = load_be<u16bit>(in, 2);
+ u16bit B1 = load_be<u16bit>(in, 3);
+ u16bit B2 = load_be<u16bit>(in, 0);
+ u16bit B3 = load_be<u16bit>(in, 1);
- B2 ^= B3 | RK[0];
- B3 ^= B2 & RK[1];
- B0 ^= B1 | RK[2];
- B1 ^= B0 & RK[3];
+ for(u32bit j = 0; j != 12; j += 3)
+ {
+ const u16bit* RK = DK + 8 * j;
- u32bit T0, T1;
+ B2 ^= B3 | RK[0];
+ B3 ^= B2 & RK[1];
+ B0 ^= B1 | RK[2];
+ B1 ^= B0 & RK[3];
- T0 = FI(B2 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B3;
- T1 = FI(B3 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0;
- T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1;
+ u32bit T0, T1;
- B0 ^= T1 ^ RK[13];
- B1 ^= T0;
+ T0 = FI(B2 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B3;
+ T1 = FI(B3 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0;
+ T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1;
- T0 = FI(B0 ^ RK[14], RK[15], RK[16]) ^ B1;
- T1 = FI(B1 ^ RK[17], RK[18], RK[19]) ^ T0;
- T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1;
+ B0 ^= T1 ^ RK[13];
+ B1 ^= T0;
- B2 ^= T1 ^ RK[23];
- B3 ^= T0;
- }
+ T0 = FI(B0 ^ RK[14], RK[15], RK[16]) ^ B1;
+ T1 = FI(B1 ^ RK[17], RK[18], RK[19]) ^ T0;
+ T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1;
+
+ B2 ^= T1 ^ RK[23];
+ B3 ^= T0;
+ }
- B2 ^= B3 | DK[96];
- B3 ^= B2 & DK[97];
- B0 ^= B1 | DK[98];
- B1 ^= B0 & DK[99];
+ B2 ^= B3 | DK[96];
+ B3 ^= B2 & DK[97];
+ B0 ^= B1 | DK[98];
+ B1 ^= B0 & DK[99];
- store_be(out, B0, B1, B2, B3);
+ store_be(out, B0, B1, B2, B3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/misty1/misty1.h b/src/block/misty1/misty1.h
index 62d4f856f..000830915 100644
--- a/src/block/misty1/misty1.h
+++ b/src/block/misty1/misty1.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL MISTY1 : public BlockCipher
{
public:
- void clear() throw() { EK.clear(); DK.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { EK.clear(); DK.clear(); }
std::string name() const { return "MISTY1"; }
BlockCipher* clone() const { return new MISTY1; }
+
MISTY1(u32bit = 8);
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u16bit, 100> EK, DK;
diff --git a/src/block/noekeon/info.txt b/src/block/noekeon/info.txt
index 8025c2073..31f7e7de3 100644
--- a/src/block/noekeon/info.txt
+++ b/src/block/noekeon/info.txt
@@ -1,10 +1 @@
-realname "Noekeon"
-
define NOEKEON
-
-load_on auto
-
-<add>
-noekeon.cpp
-noekeon.h
-</add>
diff --git a/src/block/noekeon/noekeon.cpp b/src/block/noekeon/noekeon.cpp
index 90eb9ad2b..0bfce1882 100644
--- a/src/block/noekeon/noekeon.cpp
+++ b/src/block/noekeon/noekeon.cpp
@@ -84,65 +84,77 @@ const byte Noekeon::RC[] = {
/*
* Noekeon Encryption
*/
-void Noekeon::enc(const byte in[], byte out[]) const
+void Noekeon::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A0 = load_be<u32bit>(in, 0);
- u32bit A1 = load_be<u32bit>(in, 1);
- u32bit A2 = load_be<u32bit>(in, 2);
- u32bit A3 = load_be<u32bit>(in, 3);
-
- for(u32bit j = 0; j != 16; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- A0 ^= RC[j];
- theta(A0, A1, A2, A3, EK);
+ u32bit A0 = load_be<u32bit>(in, 0);
+ u32bit A1 = load_be<u32bit>(in, 1);
+ u32bit A2 = load_be<u32bit>(in, 2);
+ u32bit A3 = load_be<u32bit>(in, 3);
- A1 = rotate_left(A1, 1);
- A2 = rotate_left(A2, 5);
- A3 = rotate_left(A3, 2);
+ for(u32bit j = 0; j != 16; ++j)
+ {
+ A0 ^= RC[j];
+ theta(A0, A1, A2, A3, EK);
- gamma(A0, A1, A2, A3);
+ A1 = rotate_left(A1, 1);
+ A2 = rotate_left(A2, 5);
+ A3 = rotate_left(A3, 2);
- A1 = rotate_right(A1, 1);
- A2 = rotate_right(A2, 5);
- A3 = rotate_right(A3, 2);
- }
+ gamma(A0, A1, A2, A3);
- A0 ^= RC[16];
- theta(A0, A1, A2, A3, EK);
+ A1 = rotate_right(A1, 1);
+ A2 = rotate_right(A2, 5);
+ A3 = rotate_right(A3, 2);
+ }
+
+ A0 ^= RC[16];
+ theta(A0, A1, A2, A3, EK);
+
+ store_be(out, A0, A1, A2, A3);
- store_be(out, A0, A1, A2, A3);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Noekeon Encryption
*/
-void Noekeon::dec(const byte in[], byte out[]) const
+void Noekeon::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A0 = load_be<u32bit>(in, 0);
- u32bit A1 = load_be<u32bit>(in, 1);
- u32bit A2 = load_be<u32bit>(in, 2);
- u32bit A3 = load_be<u32bit>(in, 3);
-
- for(u32bit j = 16; j != 0; --j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- theta(A0, A1, A2, A3, DK);
- A0 ^= RC[j];
+ u32bit A0 = load_be<u32bit>(in, 0);
+ u32bit A1 = load_be<u32bit>(in, 1);
+ u32bit A2 = load_be<u32bit>(in, 2);
+ u32bit A3 = load_be<u32bit>(in, 3);
- A1 = rotate_left(A1, 1);
- A2 = rotate_left(A2, 5);
- A3 = rotate_left(A3, 2);
+ for(u32bit j = 16; j != 0; --j)
+ {
+ theta(A0, A1, A2, A3, DK);
+ A0 ^= RC[j];
- gamma(A0, A1, A2, A3);
+ A1 = rotate_left(A1, 1);
+ A2 = rotate_left(A2, 5);
+ A3 = rotate_left(A3, 2);
- A1 = rotate_right(A1, 1);
- A2 = rotate_right(A2, 5);
- A3 = rotate_right(A3, 2);
- }
+ gamma(A0, A1, A2, A3);
- theta(A0, A1, A2, A3, DK);
- A0 ^= RC[0];
+ A1 = rotate_right(A1, 1);
+ A2 = rotate_right(A2, 5);
+ A3 = rotate_right(A3, 2);
+ }
- store_be(out, A0, A1, A2, A3);
+ theta(A0, A1, A2, A3, DK);
+ A0 ^= RC[0];
+
+ store_be(out, A0, A1, A2, A3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
@@ -189,7 +201,7 @@ void Noekeon::key_schedule(const byte key[], u32bit)
/*
* Clear memory of sensitive data
*/
-void Noekeon::clear() throw()
+void Noekeon::clear()
{
EK.clear();
DK.clear();
diff --git a/src/block/noekeon/noekeon.h b/src/block/noekeon/noekeon.h
index 893892446..4532c1be2 100644
--- a/src/block/noekeon/noekeon.h
+++ b/src/block/noekeon/noekeon.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL Noekeon : public BlockCipher
{
public:
- void clear() throw();
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear();
std::string name() const { return "Noekeon"; }
BlockCipher* clone() const { return new Noekeon; }
+
Noekeon() : BlockCipher(16, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static const byte RC[17];
diff --git a/src/block/rc2/info.txt b/src/block/rc2/info.txt
index 099141de7..7eee38d6b 100644
--- a/src/block/rc2/info.txt
+++ b/src/block/rc2/info.txt
@@ -1,10 +1 @@
-realname "RC2"
-
define RC2
-
-load_on auto
-
-<add>
-rc2.cpp
-rc2.h
-</add>
diff --git a/src/block/rc2/rc2.cpp b/src/block/rc2/rc2.cpp
index 5827bdb68..b5e4a7d50 100644
--- a/src/block/rc2/rc2.cpp
+++ b/src/block/rc2/rc2.cpp
@@ -14,73 +14,85 @@ namespace Botan {
/*
* RC2 Encryption
*/
-void RC2::enc(const byte in[], byte out[]) const
+void RC2::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit R0 = load_le<u16bit>(in, 0);
- u16bit R1 = load_le<u16bit>(in, 1);
- u16bit R2 = load_le<u16bit>(in, 2);
- u16bit R3 = load_le<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 16; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- R0 += (R1 & ~R3) + (R2 & R3) + K[4*j];
- R0 = rotate_left(R0, 1);
+ u16bit R0 = load_le<u16bit>(in, 0);
+ u16bit R1 = load_le<u16bit>(in, 1);
+ u16bit R2 = load_le<u16bit>(in, 2);
+ u16bit R3 = load_le<u16bit>(in, 3);
+
+ for(u32bit j = 0; j != 16; ++j)
+ {
+ R0 += (R1 & ~R3) + (R2 & R3) + K[4*j];
+ R0 = rotate_left(R0, 1);
- R1 += (R2 & ~R0) + (R3 & R0) + K[4*j + 1];
- R1 = rotate_left(R1, 2);
+ R1 += (R2 & ~R0) + (R3 & R0) + K[4*j + 1];
+ R1 = rotate_left(R1, 2);
- R2 += (R3 & ~R1) + (R0 & R1) + K[4*j + 2];
- R2 = rotate_left(R2, 3);
+ R2 += (R3 & ~R1) + (R0 & R1) + K[4*j + 2];
+ R2 = rotate_left(R2, 3);
- R3 += (R0 & ~R2) + (R1 & R2) + K[4*j + 3];
- R3 = rotate_left(R3, 5);
+ R3 += (R0 & ~R2) + (R1 & R2) + K[4*j + 3];
+ R3 = rotate_left(R3, 5);
- if(j == 4 || j == 10)
- {
- R0 += K[R3 % 64];
- R1 += K[R0 % 64];
- R2 += K[R1 % 64];
- R3 += K[R2 % 64];
+ if(j == 4 || j == 10)
+ {
+ R0 += K[R3 % 64];
+ R1 += K[R0 % 64];
+ R2 += K[R1 % 64];
+ R3 += K[R2 % 64];
+ }
}
- }
- store_le(out, R0, R1, R2, R3);
+ store_le(out, R0, R1, R2, R3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* RC2 Decryption
*/
-void RC2::dec(const byte in[], byte out[]) const
+void RC2::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit R0 = load_le<u16bit>(in, 0);
- u16bit R1 = load_le<u16bit>(in, 1);
- u16bit R2 = load_le<u16bit>(in, 2);
- u16bit R3 = load_le<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 16; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- R3 = rotate_right(R3, 5);
- R3 -= (R0 & ~R2) + (R1 & R2) + K[63 - (4*j + 0)];
+ u16bit R0 = load_le<u16bit>(in, 0);
+ u16bit R1 = load_le<u16bit>(in, 1);
+ u16bit R2 = load_le<u16bit>(in, 2);
+ u16bit R3 = load_le<u16bit>(in, 3);
+
+ for(u32bit j = 0; j != 16; ++j)
+ {
+ R3 = rotate_right(R3, 5);
+ R3 -= (R0 & ~R2) + (R1 & R2) + K[63 - (4*j + 0)];
- R2 = rotate_right(R2, 3);
- R2 -= (R3 & ~R1) + (R0 & R1) + K[63 - (4*j + 1)];
+ R2 = rotate_right(R2, 3);
+ R2 -= (R3 & ~R1) + (R0 & R1) + K[63 - (4*j + 1)];
- R1 = rotate_right(R1, 2);
- R1 -= (R2 & ~R0) + (R3 & R0) + K[63 - (4*j + 2)];
+ R1 = rotate_right(R1, 2);
+ R1 -= (R2 & ~R0) + (R3 & R0) + K[63 - (4*j + 2)];
- R0 = rotate_right(R0, 1);
- R0 -= (R1 & ~R3) + (R2 & R3) + K[63 - (4*j + 3)];
+ R0 = rotate_right(R0, 1);
+ R0 -= (R1 & ~R3) + (R2 & R3) + K[63 - (4*j + 3)];
- if(j == 4 || j == 10)
- {
- R3 -= K[R2 % 64];
- R2 -= K[R1 % 64];
- R1 -= K[R0 % 64];
- R0 -= K[R3 % 64];
+ if(j == 4 || j == 10)
+ {
+ R3 -= K[R2 % 64];
+ R2 -= K[R1 % 64];
+ R1 -= K[R0 % 64];
+ R0 -= K[R3 % 64];
+ }
}
- }
- store_le(out, R0, R1, R2, R3);
+ store_le(out, R0, R1, R2, R3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/rc2/rc2.h b/src/block/rc2/rc2.h
index cb6f58f04..c6e4946f9 100644
--- a/src/block/rc2/rc2.h
+++ b/src/block/rc2/rc2.h
@@ -18,15 +18,17 @@ namespace Botan {
class BOTAN_DLL RC2 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
static byte EKB_code(u32bit);
- void clear() throw() { K.clear(); }
+ void clear() { K.clear(); }
std::string name() const { return "RC2"; }
BlockCipher* clone() const { return new RC2; }
+
RC2() : BlockCipher(8, 1, 32) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u16bit, 64> K;
diff --git a/src/block/rc5/info.txt b/src/block/rc5/info.txt
index 4a150c3b0..3da32710d 100644
--- a/src/block/rc5/info.txt
+++ b/src/block/rc5/info.txt
@@ -1,10 +1 @@
-realname "RC5"
-
define RC5
-
-load_on auto
-
-<add>
-rc5.cpp
-rc5.h
-</add>
diff --git a/src/block/rc5/rc5.cpp b/src/block/rc5/rc5.cpp
index 5d83d5a4e..4bfa27ea0 100644
--- a/src/block/rc5/rc5.cpp
+++ b/src/block/rc5/rc5.cpp
@@ -16,47 +16,59 @@ namespace Botan {
/*
* RC5 Encryption
*/
-void RC5::enc(const byte in[], byte out[]) const
+void RC5::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0), B = load_le<u32bit>(in, 1);
-
- A += S[0]; B += S[1];
- for(u32bit j = 0; j != ROUNDS; j += 4)
+ for(u32bit i = 0; i != blocks; ++i)
{
- A = rotate_left(A ^ B, B % 32) + S[2*j+2];
- B = rotate_left(B ^ A, A % 32) + S[2*j+3];
- A = rotate_left(A ^ B, B % 32) + S[2*j+4];
- B = rotate_left(B ^ A, A % 32) + S[2*j+5];
- A = rotate_left(A ^ B, B % 32) + S[2*j+6];
- B = rotate_left(B ^ A, A % 32) + S[2*j+7];
- A = rotate_left(A ^ B, B % 32) + S[2*j+8];
- B = rotate_left(B ^ A, A % 32) + S[2*j+9];
- }
+ u32bit A = load_le<u32bit>(in, 0), B = load_le<u32bit>(in, 1);
+
+ A += S[0]; B += S[1];
+ for(u32bit j = 0; j != ROUNDS; j += 4)
+ {
+ A = rotate_left(A ^ B, B % 32) + S[2*j+2];
+ B = rotate_left(B ^ A, A % 32) + S[2*j+3];
+ A = rotate_left(A ^ B, B % 32) + S[2*j+4];
+ B = rotate_left(B ^ A, A % 32) + S[2*j+5];
+ A = rotate_left(A ^ B, B % 32) + S[2*j+6];
+ B = rotate_left(B ^ A, A % 32) + S[2*j+7];
+ A = rotate_left(A ^ B, B % 32) + S[2*j+8];
+ B = rotate_left(B ^ A, A % 32) + S[2*j+9];
+ }
- store_le(out, A, B);
+ store_le(out, A, B);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* RC5 Decryption
*/
-void RC5::dec(const byte in[], byte out[]) const
+void RC5::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0), B = load_le<u32bit>(in, 1);
-
- for(u32bit j = ROUNDS; j != 0; j -= 4)
+ for(u32bit i = 0; i != blocks; ++i)
{
- B = rotate_right(B - S[2*j+1], A % 32) ^ A;
- A = rotate_right(A - S[2*j ], B % 32) ^ B;
- B = rotate_right(B - S[2*j-1], A % 32) ^ A;
- A = rotate_right(A - S[2*j-2], B % 32) ^ B;
- B = rotate_right(B - S[2*j-3], A % 32) ^ A;
- A = rotate_right(A - S[2*j-4], B % 32) ^ B;
- B = rotate_right(B - S[2*j-5], A % 32) ^ A;
- A = rotate_right(A - S[2*j-6], B % 32) ^ B;
- }
- B -= S[1]; A -= S[0];
+ u32bit A = load_le<u32bit>(in, 0), B = load_le<u32bit>(in, 1);
+
+ for(u32bit j = ROUNDS; j != 0; j -= 4)
+ {
+ B = rotate_right(B - S[2*j+1], A % 32) ^ A;
+ A = rotate_right(A - S[2*j ], B % 32) ^ B;
+ B = rotate_right(B - S[2*j-1], A % 32) ^ A;
+ A = rotate_right(A - S[2*j-2], B % 32) ^ B;
+ B = rotate_right(B - S[2*j-3], A % 32) ^ A;
+ A = rotate_right(A - S[2*j-4], B % 32) ^ B;
+ B = rotate_right(B - S[2*j-5], A % 32) ^ A;
+ A = rotate_right(A - S[2*j-6], B % 32) ^ B;
+ }
+ B -= S[1]; A -= S[0];
- store_le(out, A, B);
+ store_le(out, A, B);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/rc5/rc5.h b/src/block/rc5/rc5.h
index 083224720..82931c1d2 100644
--- a/src/block/rc5/rc5.h
+++ b/src/block/rc5/rc5.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL RC5 : public BlockCipher
{
public:
- void clear() throw() { S.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { S.clear(); }
std::string name() const;
BlockCipher* clone() const { return new RC5(ROUNDS); }
+
RC5(u32bit);
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureVector<u32bit> S;
const u32bit ROUNDS;
diff --git a/src/block/rc6/info.txt b/src/block/rc6/info.txt
index 1457e78c1..fc7d2acb4 100644
--- a/src/block/rc6/info.txt
+++ b/src/block/rc6/info.txt
@@ -1,10 +1 @@
-realname "RC6"
-
define RC6
-
-load_on auto
-
-<add>
-rc6.cpp
-rc6.h
-</add>
diff --git a/src/block/rc6/rc6.cpp b/src/block/rc6/rc6.cpp
index 3b30ea93a..8bda62259 100644
--- a/src/block/rc6/rc6.cpp
+++ b/src/block/rc6/rc6.cpp
@@ -15,85 +15,97 @@ namespace Botan {
/*
* RC6 Encryption
*/
-void RC6::enc(const byte in[], byte out[]) const
+void RC6::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0);
- u32bit B = load_le<u32bit>(in, 1);
- u32bit C = load_le<u32bit>(in, 2);
- u32bit D = load_le<u32bit>(in, 3);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit A = load_le<u32bit>(in, 0);
+ u32bit B = load_le<u32bit>(in, 1);
+ u32bit C = load_le<u32bit>(in, 2);
+ u32bit D = load_le<u32bit>(in, 3);
- B += S[0]; D += S[1];
+ B += S[0]; D += S[1];
- for(u32bit j = 0; j != 20; j += 4)
- {
- u32bit T1, T2;
-
- T1 = rotate_left(B*(2*B+1), 5);
- T2 = rotate_left(D*(2*D+1), 5);
- A = rotate_left(A ^ T1, T2 % 32) + S[2*j+2];
- C = rotate_left(C ^ T2, T1 % 32) + S[2*j+3];
-
- T1 = rotate_left(C*(2*C+1), 5);
- T2 = rotate_left(A*(2*A+1), 5);
- B = rotate_left(B ^ T1, T2 % 32) + S[2*j+4];
- D = rotate_left(D ^ T2, T1 % 32) + S[2*j+5];
-
- T1 = rotate_left(D*(2*D+1), 5);
- T2 = rotate_left(B*(2*B+1), 5);
- C = rotate_left(C ^ T1, T2 % 32) + S[2*j+6];
- A = rotate_left(A ^ T2, T1 % 32) + S[2*j+7];
-
- T1 = rotate_left(A*(2*A+1), 5);
- T2 = rotate_left(C*(2*C+1), 5);
- D = rotate_left(D ^ T1, T2 % 32) + S[2*j+8];
- B = rotate_left(B ^ T2, T1 % 32) + S[2*j+9];
- }
+ for(u32bit j = 0; j != 20; j += 4)
+ {
+ u32bit T1, T2;
+
+ T1 = rotate_left(B*(2*B+1), 5);
+ T2 = rotate_left(D*(2*D+1), 5);
+ A = rotate_left(A ^ T1, T2 % 32) + S[2*j+2];
+ C = rotate_left(C ^ T2, T1 % 32) + S[2*j+3];
+
+ T1 = rotate_left(C*(2*C+1), 5);
+ T2 = rotate_left(A*(2*A+1), 5);
+ B = rotate_left(B ^ T1, T2 % 32) + S[2*j+4];
+ D = rotate_left(D ^ T2, T1 % 32) + S[2*j+5];
- A += S[42]; C += S[43];
+ T1 = rotate_left(D*(2*D+1), 5);
+ T2 = rotate_left(B*(2*B+1), 5);
+ C = rotate_left(C ^ T1, T2 % 32) + S[2*j+6];
+ A = rotate_left(A ^ T2, T1 % 32) + S[2*j+7];
- store_le(out, A, B, C, D);
+ T1 = rotate_left(A*(2*A+1), 5);
+ T2 = rotate_left(C*(2*C+1), 5);
+ D = rotate_left(D ^ T1, T2 % 32) + S[2*j+8];
+ B = rotate_left(B ^ T2, T1 % 32) + S[2*j+9];
+ }
+
+ A += S[42]; C += S[43];
+
+ store_le(out, A, B, C, D);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* RC6 Decryption
*/
-void RC6::dec(const byte in[], byte out[]) const
+void RC6::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0);
- u32bit B = load_le<u32bit>(in, 1);
- u32bit C = load_le<u32bit>(in, 2);
- u32bit D = load_le<u32bit>(in, 3);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit A = load_le<u32bit>(in, 0);
+ u32bit B = load_le<u32bit>(in, 1);
+ u32bit C = load_le<u32bit>(in, 2);
+ u32bit D = load_le<u32bit>(in, 3);
- C -= S[43]; A -= S[42];
+ C -= S[43]; A -= S[42];
- for(u32bit j = 0; j != 20; j += 4)
- {
- u32bit T1, T2;
-
- T1 = rotate_left(A*(2*A+1), 5);
- T2 = rotate_left(C*(2*C+1), 5);
- B = rotate_right(B - S[41 - 2*j], T1 % 32) ^ T2;
- D = rotate_right(D - S[40 - 2*j], T2 % 32) ^ T1;
-
- T1 = rotate_left(D*(2*D+1), 5);
- T2 = rotate_left(B*(2*B+1), 5);
- A = rotate_right(A - S[39 - 2*j], T1 % 32) ^ T2;
- C = rotate_right(C - S[38 - 2*j], T2 % 32) ^ T1;
-
- T1 = rotate_left(C*(2*C+1), 5);
- T2 = rotate_left(A*(2*A+1), 5);
- D = rotate_right(D - S[37 - 2*j], T1 % 32) ^ T2;
- B = rotate_right(B - S[36 - 2*j], T2 % 32) ^ T1;
-
- T1 = rotate_left(B*(2*B+1), 5);
- T2 = rotate_left(D*(2*D+1), 5);
- C = rotate_right(C - S[35 - 2*j], T1 % 32) ^ T2;
- A = rotate_right(A - S[34 - 2*j], T2 % 32) ^ T1;
- }
+ for(u32bit j = 0; j != 20; j += 4)
+ {
+ u32bit T1, T2;
+
+ T1 = rotate_left(A*(2*A+1), 5);
+ T2 = rotate_left(C*(2*C+1), 5);
+ B = rotate_right(B - S[41 - 2*j], T1 % 32) ^ T2;
+ D = rotate_right(D - S[40 - 2*j], T2 % 32) ^ T1;
+
+ T1 = rotate_left(D*(2*D+1), 5);
+ T2 = rotate_left(B*(2*B+1), 5);
+ A = rotate_right(A - S[39 - 2*j], T1 % 32) ^ T2;
+ C = rotate_right(C - S[38 - 2*j], T2 % 32) ^ T1;
- D -= S[1]; B -= S[0];
+ T1 = rotate_left(C*(2*C+1), 5);
+ T2 = rotate_left(A*(2*A+1), 5);
+ D = rotate_right(D - S[37 - 2*j], T1 % 32) ^ T2;
+ B = rotate_right(B - S[36 - 2*j], T2 % 32) ^ T1;
- store_le(out, A, B, C, D);
+ T1 = rotate_left(B*(2*B+1), 5);
+ T2 = rotate_left(D*(2*D+1), 5);
+ C = rotate_right(C - S[35 - 2*j], T1 % 32) ^ T2;
+ A = rotate_right(A - S[34 - 2*j], T2 % 32) ^ T1;
+ }
+
+ D -= S[1]; B -= S[0];
+
+ store_le(out, A, B, C, D);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/rc6/rc6.h b/src/block/rc6/rc6.h
index cb2800be7..6cd0f54db 100644
--- a/src/block/rc6/rc6.h
+++ b/src/block/rc6/rc6.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL RC6 : public BlockCipher
{
public:
- void clear() throw() { S.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { S.clear(); }
std::string name() const { return "RC6"; }
BlockCipher* clone() const { return new RC6; }
+
RC6() : BlockCipher(16, 1, 32) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 44> S;
diff --git a/src/block/safer/info.txt b/src/block/safer/info.txt
index 973cbff19..0ca49602d 100644
--- a/src/block/safer/info.txt
+++ b/src/block/safer/info.txt
@@ -1,11 +1 @@
-realname "SAFER"
-
define SAFER
-
-load_on auto
-
-<add>
-safe_tab.cpp
-safer_sk.cpp
-safer_sk.h
-</add>
diff --git a/src/block/safer/safer_sk.cpp b/src/block/safer/safer_sk.cpp
index f72c4773b..eb5c22fc9 100644
--- a/src/block/safer/safer_sk.cpp
+++ b/src/block/safer/safer_sk.cpp
@@ -1,6 +1,6 @@
/*
* SAFER-SK
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -15,54 +15,75 @@ namespace Botan {
/*
* SAFER-SK Encryption
*/
-void SAFER_SK::enc(const byte in[], byte out[]) const
+void SAFER_SK::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- byte A = in[0], B = in[1], C = in[2], D = in[3],
- E = in[4], F = in[5], G = in[6], H = in[7], X, Y;
- for(u32bit j = 0; j != 16*ROUNDS; j += 16)
+ for(u32bit i = 0; i != blocks; ++i)
{
- A = EXP[A ^ EK[j ]]; B = LOG[B + EK[j+1]];
- C = LOG[C + EK[j+2]]; D = EXP[D ^ EK[j+3]];
- E = EXP[E ^ EK[j+4]]; F = LOG[F + EK[j+5]];
- G = LOG[G + EK[j+6]]; H = EXP[H ^ EK[j+7]];
- A += EK[j+ 8]; B ^= EK[j+ 9]; C ^= EK[j+10]; D += EK[j+11];
- E += EK[j+12]; F ^= EK[j+13]; G ^= EK[j+14]; H += EK[j+15];
- B += A; D += C; F += E; H += G; A += B; C += D; E += F; G += H;
- C += A; G += E; D += B; H += F; A += C; E += G; B += D; F += H;
- H += D; Y = D + H; D = B + F; X = B + D; B = A + E;
- A += B; F = C + G; E = C + F; C = X; G = Y;
+ byte A = in[0], B = in[1], C = in[2], D = in[3],
+ E = in[4], F = in[5], G = in[6], H = in[7], X, Y;
+
+ for(u32bit j = 0; j != 16*ROUNDS; j += 16)
+ {
+ A = EXP[A ^ EK[j ]]; B = LOG[B + EK[j+1]];
+ C = LOG[C + EK[j+2]]; D = EXP[D ^ EK[j+3]];
+ E = EXP[E ^ EK[j+4]]; F = LOG[F + EK[j+5]];
+ G = LOG[G + EK[j+6]]; H = EXP[H ^ EK[j+7]];
+
+ A += EK[j+ 8]; B ^= EK[j+ 9]; C ^= EK[j+10]; D += EK[j+11];
+ E += EK[j+12]; F ^= EK[j+13]; G ^= EK[j+14]; H += EK[j+15];
+
+ B += A; D += C; F += E; H += G; A += B; C += D; E += F; G += H;
+ C += A; G += E; D += B; H += F; A += C; E += G; B += D; F += H;
+ H += D; Y = D + H; D = B + F; X = B + D; B = A + E;
+ A += B; F = C + G; E = C + F; C = X; G = Y;
+ }
+
+ out[0] = A ^ EK[16*ROUNDS+0]; out[1] = B + EK[16*ROUNDS+1];
+ out[2] = C + EK[16*ROUNDS+2]; out[3] = D ^ EK[16*ROUNDS+3];
+ out[4] = E ^ EK[16*ROUNDS+4]; out[5] = F + EK[16*ROUNDS+5];
+ out[6] = G + EK[16*ROUNDS+6]; out[7] = H ^ EK[16*ROUNDS+7];
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
- out[0] = A ^ EK[16*ROUNDS+0]; out[1] = B + EK[16*ROUNDS+1];
- out[2] = C + EK[16*ROUNDS+2]; out[3] = D ^ EK[16*ROUNDS+3];
- out[4] = E ^ EK[16*ROUNDS+4]; out[5] = F + EK[16*ROUNDS+5];
- out[6] = G + EK[16*ROUNDS+6]; out[7] = H ^ EK[16*ROUNDS+7];
}
/*
* SAFER-SK Decryption
*/
-void SAFER_SK::dec(const byte in[], byte out[]) const
+void SAFER_SK::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- byte A = in[0], B = in[1], C = in[2], D = in[3],
- E = in[4], F = in[5], G = in[6], H = in[7];
- A ^= EK[16*ROUNDS+0]; B -= EK[16*ROUNDS+1]; C -= EK[16*ROUNDS+2];
- D ^= EK[16*ROUNDS+3]; E ^= EK[16*ROUNDS+4]; F -= EK[16*ROUNDS+5];
- G -= EK[16*ROUNDS+6]; H ^= EK[16*ROUNDS+7];
- for(s32bit j = 16*(ROUNDS-1); j >= 0; j -= 16)
+ for(u32bit i = 0; i != blocks; ++i)
{
- byte T = E; E = B; B = C; C = T; T = F; F = D; D = G; G = T;
- A -= E; B -= F; C -= G; D -= H; E -= A; F -= B; G -= C; H -= D;
- A -= C; E -= G; B -= D; F -= H; C -= A; G -= E; D -= B; H -= F;
- A -= B; C -= D; E -= F; G -= H; B -= A; D -= C; F -= E; H -= G;
- A = LOG[A - EK[j+8 ] + 256]; B = EXP[B ^ EK[j+9 ]];
- C = EXP[C ^ EK[j+10]]; D = LOG[D - EK[j+11] + 256];
- E = LOG[E - EK[j+12] + 256]; F = EXP[F ^ EK[j+13]];
- G = EXP[G ^ EK[j+14]]; H = LOG[H - EK[j+15] + 256];
- A ^= EK[j+0]; B -= EK[j+1]; C -= EK[j+2]; D ^= EK[j+3];
- E ^= EK[j+4]; F -= EK[j+5]; G -= EK[j+6]; H ^= EK[j+7];
+ byte A = in[0], B = in[1], C = in[2], D = in[3],
+ E = in[4], F = in[5], G = in[6], H = in[7];
+
+ A ^= EK[16*ROUNDS+0]; B -= EK[16*ROUNDS+1]; C -= EK[16*ROUNDS+2];
+ D ^= EK[16*ROUNDS+3]; E ^= EK[16*ROUNDS+4]; F -= EK[16*ROUNDS+5];
+ G -= EK[16*ROUNDS+6]; H ^= EK[16*ROUNDS+7];
+
+ for(s32bit j = 16*(ROUNDS-1); j >= 0; j -= 16)
+ {
+ byte T = E; E = B; B = C; C = T; T = F; F = D; D = G; G = T;
+ A -= E; B -= F; C -= G; D -= H; E -= A; F -= B; G -= C; H -= D;
+ A -= C; E -= G; B -= D; F -= H; C -= A; G -= E; D -= B; H -= F;
+ A -= B; C -= D; E -= F; G -= H; B -= A; D -= C; F -= E; H -= G;
+
+ A = LOG[A - EK[j+8 ] + 256]; B = EXP[B ^ EK[j+9 ]];
+ C = EXP[C ^ EK[j+10]]; D = LOG[D - EK[j+11] + 256];
+ E = LOG[E - EK[j+12] + 256]; F = EXP[F ^ EK[j+13]];
+ G = EXP[G ^ EK[j+14]]; H = LOG[H - EK[j+15] + 256];
+
+ A ^= EK[j+0]; B -= EK[j+1]; C -= EK[j+2]; D ^= EK[j+3];
+ E ^= EK[j+4]; F -= EK[j+5]; G -= EK[j+6]; H ^= EK[j+7];
+ }
+
+ out[0] = A; out[1] = B; out[2] = C; out[3] = D;
+ out[4] = E; out[5] = F; out[6] = G; out[7] = H;
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
- out[0] = A; out[1] = B; out[2] = C; out[3] = D;
- out[4] = E; out[5] = F; out[6] = G; out[7] = H;
}
/*
diff --git a/src/block/safer/safer_sk.h b/src/block/safer/safer_sk.h
index e52c5837c..80d2dc069 100644
--- a/src/block/safer/safer_sk.h
+++ b/src/block/safer/safer_sk.h
@@ -18,19 +18,22 @@ namespace Botan {
class BOTAN_DLL SAFER_SK : public BlockCipher
{
public:
- void clear() throw() { EK.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { EK.clear(); }
std::string name() const;
BlockCipher* clone() const;
+
SAFER_SK(u32bit);
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static const byte EXP[256];
static const byte LOG[512];
static const byte BIAS[208];
static const byte KEY_INDEX[208];
+
SecureVector<byte> EK;
const u32bit ROUNDS;
};
diff --git a/src/block/seed/info.txt b/src/block/seed/info.txt
index d04979335..96f4b75f2 100644
--- a/src/block/seed/info.txt
+++ b/src/block/seed/info.txt
@@ -1,11 +1 @@
-realname "SEED"
-
define SEED
-
-load_on auto
-
-<add>
-seed.cpp
-seed.h
-seed_tab.cpp
-</add>
diff --git a/src/block/seed/seed.cpp b/src/block/seed/seed.cpp
index b06a7cd77..378be16e4 100644
--- a/src/block/seed/seed.cpp
+++ b/src/block/seed/seed.cpp
@@ -22,69 +22,81 @@ u32bit SEED::G_FUNC::operator()(u32bit X) const
/*
* SEED Encryption
*/
-void SEED::enc(const byte in[], byte out[]) const
+void SEED::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit B0 = load_be<u32bit>(in, 0);
- u32bit B1 = load_be<u32bit>(in, 1);
- u32bit B2 = load_be<u32bit>(in, 2);
- u32bit B3 = load_be<u32bit>(in, 3);
-
- G_FUNC G;
-
- for(u32bit j = 0; j != 16; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- u32bit T0, T1;
-
- T0 = B2 ^ K[2*j];
- T1 = G(B2 ^ B3 ^ K[2*j+1]);
- T0 = G(T1 + T0);
- T1 = G(T1 + T0);
- B1 ^= T1;
- B0 ^= T0 + T1;
-
- T0 = B0 ^ K[2*j+2];
- T1 = G(B0 ^ B1 ^ K[2*j+3]);
- T0 = G(T1 + T0);
- T1 = G(T1 + T0);
- B3 ^= T1;
- B2 ^= T0 + T1;
+ u32bit B0 = load_be<u32bit>(in, 0);
+ u32bit B1 = load_be<u32bit>(in, 1);
+ u32bit B2 = load_be<u32bit>(in, 2);
+ u32bit B3 = load_be<u32bit>(in, 3);
+
+ G_FUNC G;
+
+ for(u32bit j = 0; j != 16; j += 2)
+ {
+ u32bit T0, T1;
+
+ T0 = B2 ^ K[2*j];
+ T1 = G(B2 ^ B3 ^ K[2*j+1]);
+ T0 = G(T1 + T0);
+ T1 = G(T1 + T0);
+ B1 ^= T1;
+ B0 ^= T0 + T1;
+
+ T0 = B0 ^ K[2*j+2];
+ T1 = G(B0 ^ B1 ^ K[2*j+3]);
+ T0 = G(T1 + T0);
+ T1 = G(T1 + T0);
+ B3 ^= T1;
+ B2 ^= T0 + T1;
+ }
+
+ store_be(out, B2, B3, B0, B1);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
-
- store_be(out, B2, B3, B0, B1);
}
/*
* SEED Decryption
*/
-void SEED::dec(const byte in[], byte out[]) const
+void SEED::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit B0 = load_be<u32bit>(in, 0);
- u32bit B1 = load_be<u32bit>(in, 1);
- u32bit B2 = load_be<u32bit>(in, 2);
- u32bit B3 = load_be<u32bit>(in, 3);
-
- G_FUNC G;
-
- for(u32bit j = 0; j != 16; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- u32bit T0, T1;
-
- T0 = B2 ^ K[30-2*j];
- T1 = G(B2 ^ B3 ^ K[31-2*j]);
- T0 = G(T1 + T0);
- T1 = G(T1 + T0);
- B1 ^= T1;
- B0 ^= T0 + T1;
-
- T0 = B0 ^ K[28-2*j];
- T1 = G(B0 ^ B1 ^ K[29-2*j]);
- T0 = G(T1 + T0);
- T1 = G(T1 + T0);
- B3 ^= T1;
- B2 ^= T0 + T1;
+ u32bit B0 = load_be<u32bit>(in, 0);
+ u32bit B1 = load_be<u32bit>(in, 1);
+ u32bit B2 = load_be<u32bit>(in, 2);
+ u32bit B3 = load_be<u32bit>(in, 3);
+
+ G_FUNC G;
+
+ for(u32bit j = 0; j != 16; j += 2)
+ {
+ u32bit T0, T1;
+
+ T0 = B2 ^ K[30-2*j];
+ T1 = G(B2 ^ B3 ^ K[31-2*j]);
+ T0 = G(T1 + T0);
+ T1 = G(T1 + T0);
+ B1 ^= T1;
+ B0 ^= T0 + T1;
+
+ T0 = B0 ^ K[28-2*j];
+ T1 = G(B0 ^ B1 ^ K[29-2*j]);
+ T0 = G(T1 + T0);
+ T1 = G(T1 + T0);
+ B3 ^= T1;
+ B2 ^= T0 + T1;
+ }
+
+ store_be(out, B2, B3, B0, B1);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
-
- store_be(out, B2, B3, B0, B1);
}
/*
diff --git a/src/block/seed/seed.h b/src/block/seed/seed.h
index 54c25d580..5a4b44057 100644
--- a/src/block/seed/seed.h
+++ b/src/block/seed/seed.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL SEED : public BlockCipher
{
public:
- void clear() throw() { K.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { K.clear(); }
std::string name() const { return "SEED"; }
BlockCipher* clone() const { return new SEED; }
+
SEED() : BlockCipher(16, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
class G_FUNC
diff --git a/src/block/serpent/info.txt b/src/block/serpent/info.txt
index baaccbf01..5fcc14f74 100644
--- a/src/block/serpent/info.txt
+++ b/src/block/serpent/info.txt
@@ -1,10 +1 @@
-realname "Serpent"
-
define SERPENT
-
-load_on auto
-
-<add>
-serpent.cpp
-serpent.h
-</add>
diff --git a/src/block/serpent/serpent.cpp b/src/block/serpent/serpent.cpp
index df7592fea..2fa27308f 100644
--- a/src/block/serpent/serpent.cpp
+++ b/src/block/serpent/serpent.cpp
@@ -243,93 +243,105 @@ inline void i_transform(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
/*
* Serpent Encryption
*/
-void Serpent::enc(const byte in[], byte out[]) const
+void Serpent::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit B0 = load_le<u32bit>(in, 0);
- u32bit B1 = load_le<u32bit>(in, 1);
- u32bit B2 = load_le<u32bit>(in, 2);
- u32bit B3 = load_le<u32bit>(in, 3);
-
- key_xor( 0,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 1,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 2,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 3,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 4,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 5,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 6,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 7,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 8,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 9,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(10,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(11,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(12,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(13,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(14,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(15,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(16,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(17,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(18,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(19,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(20,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(21,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(22,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(23,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(24,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(25,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(26,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(27,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(28,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(29,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(30,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(31,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3);
-
- store_le(out, B0, B1, B2, B3);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit B0 = load_le<u32bit>(in, 0);
+ u32bit B1 = load_le<u32bit>(in, 1);
+ u32bit B2 = load_le<u32bit>(in, 2);
+ u32bit B3 = load_le<u32bit>(in, 3);
+
+ key_xor( 0,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 1,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 2,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 3,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 4,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 5,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 6,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 7,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 8,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 9,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(10,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(11,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(12,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(13,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(14,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(15,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(16,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(17,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(18,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(19,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(20,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(21,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(22,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(23,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(24,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(25,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(26,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(27,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(28,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(29,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(30,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(31,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3);
+
+ store_le(out, B0, B1, B2, B3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Serpent Decryption
*/
-void Serpent::dec(const byte in[], byte out[]) const
+void Serpent::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit B0 = load_le<u32bit>(in, 0);
- u32bit B1 = load_le<u32bit>(in, 1);
- u32bit B2 = load_le<u32bit>(in, 2);
- u32bit B3 = load_le<u32bit>(in, 3);
-
- 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);
-
- store_le(out, B0, B1, B2, B3);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit B0 = load_le<u32bit>(in, 0);
+ u32bit B1 = load_le<u32bit>(in, 1);
+ u32bit B2 = load_le<u32bit>(in, 2);
+ u32bit B3 = load_le<u32bit>(in, 3);
+
+ 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);
+
+ store_le(out, B0, B1, B2, B3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/serpent/serpent.h b/src/block/serpent/serpent.h
index 5b9be257f..4fa7451b9 100644
--- a/src/block/serpent/serpent.h
+++ b/src/block/serpent/serpent.h
@@ -18,13 +18,14 @@ namespace Botan {
class BOTAN_DLL Serpent : public BlockCipher
{
public:
- void clear() throw() { round_key.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { round_key.clear(); }
std::string name() const { return "Serpent"; }
BlockCipher* clone() const { return new Serpent; }
Serpent() : BlockCipher(16, 16, 32, 8) {}
protected:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 132> round_key;
diff --git a/src/block/serpent_ia32/info.txt b/src/block/serpent_ia32/info.txt
index ea0506299..fa6d9b9d9 100644
--- a/src/block/serpent_ia32/info.txt
+++ b/src/block/serpent_ia32/info.txt
@@ -1,15 +1,7 @@
-realname "Serpent (IA-32)"
-
define SERPENT_IA32
load_on asm_ok
-<add>
-serp_ia32_imp.S
-serp_ia32.cpp
-serp_ia32.h
-</add>
-
<arch>
ia32
</arch>
diff --git a/src/block/serpent_ia32/serp_ia32.cpp b/src/block/serpent_ia32/serp_ia32.cpp
index 37dd4e637..721584b18 100644
--- a/src/block/serpent_ia32/serp_ia32.cpp
+++ b/src/block/serpent_ia32/serp_ia32.cpp
@@ -21,17 +21,27 @@ void botan_serpent_ia32_key_schedule(u32bit[140]);
/*
* Serpent Encryption
*/
-void Serpent_IA32::enc(const byte in[], byte out[]) const
+void Serpent_IA32::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- botan_serpent_ia32_encrypt(in, out, round_key);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ botan_serpent_ia32_encrypt(in, out, round_key);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Serpent Decryption
*/
-void Serpent_IA32::dec(const byte in[], byte out[]) const
+void Serpent_IA32::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- botan_serpent_ia32_decrypt(in, out, round_key);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ botan_serpent_ia32_decrypt(in, out, round_key);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
@@ -41,7 +51,7 @@ void Serpent_IA32::key_schedule(const byte key[], u32bit length)
{
SecureBuffer<u32bit, 140> W;
for(u32bit j = 0; j != length / 4; ++j)
- W[j] = make_u32bit(key[4*j+3], key[4*j+2], key[4*j+1], key[4*j]);
+ W[j] = load_le<u32bit>(key, j);
W[length / 4] |= u32bit(1) << ((length%4)*8);
botan_serpent_ia32_key_schedule(W);
diff --git a/src/block/serpent_ia32/serp_ia32.h b/src/block/serpent_ia32/serp_ia32.h
index 565e9889d..dc6beaf13 100644
--- a/src/block/serpent_ia32/serp_ia32.h
+++ b/src/block/serpent_ia32/serp_ia32.h
@@ -18,10 +18,11 @@ namespace Botan {
class BOTAN_DLL Serpent_IA32 : public Serpent
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
BlockCipher* clone() const { return new Serpent_IA32; }
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
};
diff --git a/src/block/serpent_simd/info.txt b/src/block/serpent_simd/info.txt
new file mode 100644
index 000000000..d65b41235
--- /dev/null
+++ b/src/block/serpent_simd/info.txt
@@ -0,0 +1,7 @@
+define SERPENT_SIMD
+
+<requires>
+serpent
+simd_32
+simd_engine
+</requires>
diff --git a/src/block/serpent_simd/serp_simd.cpp b/src/block/serpent_simd/serp_simd.cpp
new file mode 100644
index 000000000..b394b0c26
--- /dev/null
+++ b/src/block/serpent_simd/serp_simd.cpp
@@ -0,0 +1,206 @@
+/*
+* Serpent (SIMD)
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/serp_simd.h>
+#include <botan/serp_simd_sbox.h>
+#include <botan/simd_32.h>
+#include <botan/loadstor.h>
+
+namespace Botan {
+
+namespace {
+
+#define key_xor(round, B0, B1, B2, B3) \
+ do { \
+ B0 ^= SIMD_32(keys[4*round ]); \
+ B1 ^= SIMD_32(keys[4*round+1]); \
+ B2 ^= SIMD_32(keys[4*round+2]); \
+ B3 ^= SIMD_32(keys[4*round+3]); \
+ } while(0);
+
+/*
+* Serpent's linear transformations
+*/
+#define transform(B0, B1, B2, B3) \
+ do { \
+ B0.rotate_left(13); \
+ B2.rotate_left(3); \
+ B1 ^= B0 ^ B2; \
+ B3 ^= B2 ^ (B0 << 3); \
+ B1.rotate_left(1); \
+ B3.rotate_left(7); \
+ B0 ^= B1 ^ B3; \
+ B2 ^= B3 ^ (B1 << 7); \
+ B0.rotate_left(5); \
+ B2.rotate_left(22); \
+ } while(0);
+
+#define i_transform(B0, B1, B2, B3) \
+ do { \
+ B2.rotate_right(22); \
+ B0.rotate_right(5); \
+ B2 ^= B3 ^ (B1 << 7); \
+ B0 ^= B1 ^ B3; \
+ B3.rotate_right(7); \
+ B1.rotate_right(1); \
+ B3 ^= B2 ^ (B0 << 3); \
+ B1 ^= B0 ^ B2; \
+ B2.rotate_right(3); \
+ B0.rotate_right(13); \
+ } while(0);
+
+/*
+* SIMD Serpent Encryption of 4 blocks in parallel
+*/
+void serpent_encrypt_4(const byte in[64],
+ byte out[64],
+ const u32bit keys[132])
+ {
+ SIMD_32 B0 = SIMD_32::load_le(in);
+ SIMD_32 B1 = SIMD_32::load_le(in + 16);
+ SIMD_32 B2 = SIMD_32::load_le(in + 32);
+ SIMD_32 B3 = SIMD_32::load_le(in + 48);
+
+ SIMD_32::transpose(B0, B1, B2, B3);
+
+ key_xor( 0,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 1,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 2,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 3,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 4,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 5,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 6,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 7,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+
+ key_xor( 8,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 9,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(10,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(11,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(12,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(13,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(14,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(15,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+
+ key_xor(16,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(17,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(18,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(19,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(20,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(21,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(22,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(23,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+
+ key_xor(24,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(25,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(26,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(27,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(28,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(29,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(30,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(31,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3);
+
+ SIMD_32::transpose(B0, B1, B2, B3);
+
+ B0.store_le(out);
+ B1.store_le(out + 16);
+ B2.store_le(out + 32);
+ B3.store_le(out + 48);
+ }
+
+/*
+* SIMD Serpent Decryption of 4 blocks in parallel
+*/
+void serpent_decrypt_4(const byte in[64],
+ byte out[64],
+ const u32bit keys[132])
+ {
+ SIMD_32 B0 = SIMD_32::load_le(in);
+ SIMD_32 B1 = SIMD_32::load_le(in + 16);
+ SIMD_32 B2 = SIMD_32::load_le(in + 32);
+ SIMD_32 B3 = SIMD_32::load_le(in + 48);
+
+ SIMD_32::transpose(B0, B1, B2, B3);
+
+ 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);
+
+ SIMD_32::transpose(B0, B1, B2, B3);
+
+ B0.store_le(out);
+ B1.store_le(out + 16);
+ B2.store_le(out + 32);
+ B3.store_le(out + 48);
+ }
+
+}
+
+/*
+* Serpent Encryption
+*/
+void Serpent_SIMD::encrypt_n(const byte in[], byte out[], u32bit blocks) const
+ {
+ while(blocks >= 4)
+ {
+ serpent_encrypt_4(in, out, this->round_key);
+ in += 4 * BLOCK_SIZE;
+ out += 4 * BLOCK_SIZE;
+ blocks -= 4;
+ }
+
+ Serpent::encrypt_n(in, out, blocks);
+ }
+
+/*
+* Serpent Decryption
+*/
+void Serpent_SIMD::decrypt_n(const byte in[], byte out[], u32bit blocks) const
+ {
+ while(blocks >= 4)
+ {
+ serpent_decrypt_4(in, out, this->round_key);
+ in += 4 * BLOCK_SIZE;
+ out += 4 * BLOCK_SIZE;
+ blocks -= 4;
+ }
+
+ Serpent::decrypt_n(in, out, blocks);
+ }
+
+}
diff --git a/src/block/serpent_simd/serp_simd.h b/src/block/serpent_simd/serp_simd.h
new file mode 100644
index 000000000..1ecb70159
--- /dev/null
+++ b/src/block/serpent_simd/serp_simd.h
@@ -0,0 +1,29 @@
+/*
+* Serpent (SIMD)
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_SERPENT_SIMD_H__
+#define BOTAN_SERPENT_SIMD_H__
+
+#include <botan/serpent.h>
+
+namespace Botan {
+
+/*
+* Serpent
+*/
+class BOTAN_DLL Serpent_SIMD : public Serpent
+ {
+ public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ BlockCipher* clone() const { return new Serpent_SIMD; }
+ };
+
+}
+
+#endif
diff --git a/src/block/serpent_simd/serp_simd_sbox.h b/src/block/serpent_simd/serp_simd_sbox.h
new file mode 100644
index 000000000..6e3da7359
--- /dev/null
+++ b/src/block/serpent_simd/serp_simd_sbox.h
@@ -0,0 +1,426 @@
+/*
+* Serpent Sboxes in SIMD form
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef SERPENT_SIMD_SBOXES_H__
+#define SERPENT_SIMD_SBOXES_H__
+
+#define SBoxE1(B0, B1, B2, B3) \
+ do { \
+ B3 ^= B0; \
+ SIMD_32 B4 = B1; \
+ B1 &= B3; \
+ B4 ^= B2; \
+ B1 ^= B0; \
+ B0 |= B3; \
+ B0 ^= B4; \
+ B4 ^= B3; \
+ B3 ^= B2; \
+ B2 |= B1; \
+ B2 ^= B4; \
+ B4 = ~B4; \
+ B4 |= B1; \
+ B1 ^= B3; \
+ B1 ^= B4; \
+ B3 |= B0; \
+ B1 ^= B3; \
+ B4 ^= B3; \
+ B3 = B0; \
+ B0 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxE2(B0, B1, B2, B3) \
+ do { \
+ B0 = ~B0; \
+ B2 = ~B2; \
+ SIMD_32 B4 = B0; \
+ B0 &= B1; \
+ B2 ^= B0; \
+ B0 |= B3; \
+ B3 ^= B2; \
+ B1 ^= B0; \
+ B0 ^= B4; \
+ B4 |= B1; \
+ B1 ^= B3; \
+ B2 |= B0; \
+ B2 &= B4; \
+ B0 ^= B1; \
+ B1 &= B2; \
+ B1 ^= B0; \
+ B0 &= B2; \
+ B4 ^= B0; \
+ B0 = B2; \
+ B2 = B3; \
+ B3 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxE3(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B0; \
+ B0 &= B2; \
+ B0 ^= B3; \
+ B2 ^= B1; \
+ B2 ^= B0; \
+ B3 |= B4; \
+ B3 ^= B1; \
+ B4 ^= B2; \
+ B1 = B3; \
+ B3 |= B4; \
+ B3 ^= B0; \
+ B0 &= B1; \
+ B4 ^= B0; \
+ B1 ^= B3; \
+ B1 ^= B4; \
+ B4 = ~B4; \
+ B0 = B2; \
+ B2 = B1; \
+ B1 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxE4(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B0; \
+ B0 |= B3; \
+ B3 ^= B1; \
+ B1 &= B4; \
+ B4 ^= B2; \
+ B2 ^= B3; \
+ B3 &= B0; \
+ B4 |= B1; \
+ B3 ^= B4; \
+ B0 ^= B1; \
+ B4 &= B0; \
+ B1 ^= B3; \
+ B4 ^= B2; \
+ B1 |= B0; \
+ B1 ^= B2; \
+ B0 ^= B3; \
+ B2 = B1; \
+ B1 |= B3; \
+ B0 ^= B1; \
+ B1 = B2; \
+ B2 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxE5(B0, B1, B2, B3) \
+ do { \
+ B1 ^= B3; \
+ B3 = ~B3; \
+ B2 ^= B3; \
+ B3 ^= B0; \
+ SIMD_32 B4 = B1; \
+ B1 &= B3; \
+ B1 ^= B2; \
+ B4 ^= B3; \
+ B0 ^= B4; \
+ B2 &= B4; \
+ B2 ^= B0; \
+ B0 &= B1; \
+ B3 ^= B0; \
+ B4 |= B1; \
+ B4 ^= B0; \
+ B0 |= B3; \
+ B0 ^= B2; \
+ B2 &= B3; \
+ B0 = ~B0; \
+ B4 ^= B2; \
+ B2 = B0; \
+ B0 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxE6(B0, B1, B2, B3) \
+ do { \
+ B0 ^= B1; \
+ B1 ^= B3; \
+ B3 = ~B3; \
+ SIMD_32 B4 = B1; \
+ B1 &= B0; \
+ B2 ^= B3; \
+ B1 ^= B2; \
+ B2 |= B4; \
+ B4 ^= B3; \
+ B3 &= B1; \
+ B3 ^= B0; \
+ B4 ^= B1; \
+ B4 ^= B2; \
+ B2 ^= B0; \
+ B0 &= B3; \
+ B2 = ~B2; \
+ B0 ^= B4; \
+ B4 |= B3; \
+ B4 ^= B2; \
+ B2 = B0; \
+ B0 = B1; \
+ B1 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxE7(B0, B1, B2, B3) \
+ do { \
+ B2 = ~B2; \
+ SIMD_32 B4 = B3; \
+ B3 &= B0; \
+ B0 ^= B4; \
+ B3 ^= B2; \
+ B2 |= B4; \
+ B1 ^= B3; \
+ B2 ^= B0; \
+ B0 |= B1; \
+ B2 ^= B1; \
+ B4 ^= B0; \
+ B0 |= B3; \
+ B0 ^= B2; \
+ B4 ^= B3; \
+ B4 ^= B0; \
+ B3 = ~B3; \
+ B2 &= B4; \
+ B3 ^= B2; \
+ B2 = B4; \
+ } while(0);
+
+#define SBoxE8(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B1; \
+ B1 |= B2; \
+ B1 ^= B3; \
+ B4 ^= B2; \
+ B2 ^= B1; \
+ B3 |= B4; \
+ B3 &= B0; \
+ B4 ^= B2; \
+ B3 ^= B1; \
+ B1 |= B4; \
+ B1 ^= B0; \
+ B0 |= B4; \
+ B0 ^= B2; \
+ B1 ^= B4; \
+ B2 ^= B1; \
+ B1 &= B0; \
+ B1 ^= B4; \
+ B2 = ~B2; \
+ B2 |= B0; \
+ B4 ^= B2; \
+ B2 = B1; \
+ B1 = B3; \
+ B3 = B0; \
+ B0 = B4; \
+ } while(0);
+
+#define SBoxD1(B0, B1, B2, B3) \
+ do { \
+ B2 = ~B2; \
+ SIMD_32 B4 = B1; \
+ B1 |= B0; \
+ B4 = ~B4; \
+ B1 ^= B2; \
+ B2 |= B4; \
+ B1 ^= B3; \
+ B0 ^= B4; \
+ B2 ^= B0; \
+ B0 &= B3; \
+ B4 ^= B0; \
+ B0 |= B1; \
+ B0 ^= B2; \
+ B3 ^= B4; \
+ B2 ^= B1; \
+ B3 ^= B0; \
+ B3 ^= B1; \
+ B2 &= B3; \
+ B4 ^= B2; \
+ B2 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxD2(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B1; \
+ B1 ^= B3; \
+ B3 &= B1; \
+ B4 ^= B2; \
+ B3 ^= B0; \
+ B0 |= B1; \
+ B2 ^= B3; \
+ B0 ^= B4; \
+ B0 |= B2; \
+ B1 ^= B3; \
+ B0 ^= B1; \
+ B1 |= B3; \
+ B1 ^= B0; \
+ B4 = ~B4; \
+ B4 ^= B1; \
+ B1 |= B0; \
+ B1 ^= B0; \
+ B1 |= B4; \
+ B3 ^= B1; \
+ B1 = B0; \
+ B0 = B4; \
+ B4 = B2; \
+ B2 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxD3(B0, B1, B2, B3) \
+ do { \
+ B2 ^= B3; \
+ B3 ^= B0; \
+ SIMD_32 B4 = B3; \
+ B3 &= B2; \
+ B3 ^= B1; \
+ B1 |= B2; \
+ B1 ^= B4; \
+ B4 &= B3; \
+ B2 ^= B3; \
+ B4 &= B0; \
+ B4 ^= B2; \
+ B2 &= B1; \
+ B2 |= B0; \
+ B3 = ~B3; \
+ B2 ^= B3; \
+ B0 ^= B3; \
+ B0 &= B1; \
+ B3 ^= B4; \
+ B3 ^= B0; \
+ B0 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxD4(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B2; \
+ B2 ^= B1; \
+ B0 ^= B2; \
+ B4 &= B2; \
+ B4 ^= B0; \
+ B0 &= B1; \
+ B1 ^= B3; \
+ B3 |= B4; \
+ B2 ^= B3; \
+ B0 ^= B3; \
+ B1 ^= B4; \
+ B3 &= B2; \
+ B3 ^= B1; \
+ B1 ^= B0; \
+ B1 |= B2; \
+ B0 ^= B3; \
+ B1 ^= B4; \
+ B0 ^= B1; \
+ B4 = B0; \
+ B0 = B2; \
+ B2 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxD5(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B2; \
+ B2 &= B3; \
+ B2 ^= B1; \
+ B1 |= B3; \
+ B1 &= B0; \
+ B4 ^= B2; \
+ B4 ^= B1; \
+ B1 &= B2; \
+ B0 = ~B0; \
+ B3 ^= B4; \
+ B1 ^= B3; \
+ B3 &= B0; \
+ B3 ^= B2; \
+ B0 ^= B1; \
+ B2 &= B0; \
+ B3 ^= B0; \
+ B2 ^= B4; \
+ B2 |= B3; \
+ B3 ^= B0; \
+ B2 ^= B1; \
+ B1 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxD6(B0, B1, B2, B3) \
+ do { \
+ B1 = ~B1; \
+ SIMD_32 B4 = B3; \
+ B2 ^= B1; \
+ B3 |= B0; \
+ B3 ^= B2; \
+ B2 |= B1; \
+ B2 &= B0; \
+ B4 ^= B3; \
+ B2 ^= B4; \
+ B4 |= B0; \
+ B4 ^= B1; \
+ B1 &= B2; \
+ B1 ^= B3; \
+ B4 ^= B2; \
+ B3 &= B4; \
+ B4 ^= B1; \
+ B3 ^= B4; \
+ B4 = ~B4; \
+ B3 ^= B0; \
+ B0 = B1; \
+ B1 = B4; \
+ B4 = B3; \
+ B3 = B2; \
+ B2 = B4; \
+ } while(0);
+
+#define SBoxD7(B0, B1, B2, B3) \
+ do { \
+ B0 ^= B2; \
+ SIMD_32 B4 = B2; \
+ B2 &= B0; \
+ B4 ^= B3; \
+ B2 = ~B2; \
+ B3 ^= B1; \
+ B2 ^= B3; \
+ B4 |= B0; \
+ B0 ^= B2; \
+ B3 ^= B4; \
+ B4 ^= B1; \
+ B1 &= B3; \
+ B1 ^= B0; \
+ B0 ^= B3; \
+ B0 |= B2; \
+ B3 ^= B1; \
+ B4 ^= B0; \
+ B0 = B1; \
+ B1 = B2; \
+ B2 = B4; \
+ } while(0);
+
+#define SBoxD8(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B2; \
+ B2 ^= B0; \
+ B0 &= B3; \
+ B4 |= B3; \
+ B2 = ~B2; \
+ B3 ^= B1; \
+ B1 |= B0; \
+ B0 ^= B2; \
+ B2 &= B4; \
+ B3 &= B4; \
+ B1 ^= B2; \
+ B2 ^= B0; \
+ B0 |= B2; \
+ B4 ^= B1; \
+ B0 ^= B3; \
+ B3 ^= B4; \
+ B4 |= B0; \
+ B3 ^= B2; \
+ B4 ^= B2; \
+ B2 = B1; \
+ B1 = B0; \
+ B0 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#endif
diff --git a/src/block/skipjack/info.txt b/src/block/skipjack/info.txt
index 4b38d6d28..7dfffda4e 100644
--- a/src/block/skipjack/info.txt
+++ b/src/block/skipjack/info.txt
@@ -1,10 +1 @@
-realname "Skipjack"
-
define SKIPJACK
-
-load_on auto
-
-<add>
-skipjack.cpp
-skipjack.h
-</add>
diff --git a/src/block/skipjack/skipjack.cpp b/src/block/skipjack/skipjack.cpp
index f5ffc861e..e8b2cfb8d 100644
--- a/src/block/skipjack/skipjack.cpp
+++ b/src/block/skipjack/skipjack.cpp
@@ -13,51 +13,63 @@ namespace Botan {
/*
* Skipjack Encryption
*/
-void Skipjack::enc(const byte in[], byte out[]) const
+void Skipjack::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit W1 = load_le<u16bit>(in, 3);
- u16bit W2 = load_le<u16bit>(in, 2);
- u16bit W3 = load_le<u16bit>(in, 1);
- u16bit W4 = load_le<u16bit>(in, 0);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u16bit W1 = load_le<u16bit>(in, 3);
+ u16bit W2 = load_le<u16bit>(in, 2);
+ u16bit W3 = load_le<u16bit>(in, 1);
+ u16bit W4 = load_le<u16bit>(in, 0);
- step_A(W1,W4, 1); step_A(W4,W3, 2); step_A(W3,W2, 3); step_A(W2,W1, 4);
- step_A(W1,W4, 5); step_A(W4,W3, 6); step_A(W3,W2, 7); step_A(W2,W1, 8);
+ step_A(W1,W4, 1); step_A(W4,W3, 2); step_A(W3,W2, 3); step_A(W2,W1, 4);
+ step_A(W1,W4, 5); step_A(W4,W3, 6); step_A(W3,W2, 7); step_A(W2,W1, 8);
- step_B(W1,W2, 9); step_B(W4,W1,10); step_B(W3,W4,11); step_B(W2,W3,12);
- step_B(W1,W2,13); step_B(W4,W1,14); step_B(W3,W4,15); step_B(W2,W3,16);
+ step_B(W1,W2, 9); step_B(W4,W1,10); step_B(W3,W4,11); step_B(W2,W3,12);
+ step_B(W1,W2,13); step_B(W4,W1,14); step_B(W3,W4,15); step_B(W2,W3,16);
- step_A(W1,W4,17); step_A(W4,W3,18); step_A(W3,W2,19); step_A(W2,W1,20);
- step_A(W1,W4,21); step_A(W4,W3,22); step_A(W3,W2,23); step_A(W2,W1,24);
+ step_A(W1,W4,17); step_A(W4,W3,18); step_A(W3,W2,19); step_A(W2,W1,20);
+ step_A(W1,W4,21); step_A(W4,W3,22); step_A(W3,W2,23); step_A(W2,W1,24);
- step_B(W1,W2,25); step_B(W4,W1,26); step_B(W3,W4,27); step_B(W2,W3,28);
- step_B(W1,W2,29); step_B(W4,W1,30); step_B(W3,W4,31); step_B(W2,W3,32);
+ step_B(W1,W2,25); step_B(W4,W1,26); step_B(W3,W4,27); step_B(W2,W3,28);
+ step_B(W1,W2,29); step_B(W4,W1,30); step_B(W3,W4,31); step_B(W2,W3,32);
- store_le(out, W4, W3, W2, W1);
+ store_le(out, W4, W3, W2, W1);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Skipjack Decryption
*/
-void Skipjack::dec(const byte in[], byte out[]) const
+void Skipjack::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit W1 = load_le<u16bit>(in, 3);
- u16bit W2 = load_le<u16bit>(in, 2);
- u16bit W3 = load_le<u16bit>(in, 1);
- u16bit W4 = load_le<u16bit>(in, 0);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u16bit W1 = load_le<u16bit>(in, 3);
+ u16bit W2 = load_le<u16bit>(in, 2);
+ u16bit W3 = load_le<u16bit>(in, 1);
+ u16bit W4 = load_le<u16bit>(in, 0);
+
+ step_Bi(W2,W3,32); step_Bi(W3,W4,31); step_Bi(W4,W1,30); step_Bi(W1,W2,29);
+ step_Bi(W2,W3,28); step_Bi(W3,W4,27); step_Bi(W4,W1,26); step_Bi(W1,W2,25);
- step_Bi(W2,W3,32); step_Bi(W3,W4,31); step_Bi(W4,W1,30); step_Bi(W1,W2,29);
- step_Bi(W2,W3,28); step_Bi(W3,W4,27); step_Bi(W4,W1,26); step_Bi(W1,W2,25);
+ step_Ai(W1,W2,24); step_Ai(W2,W3,23); step_Ai(W3,W4,22); step_Ai(W4,W1,21);
+ step_Ai(W1,W2,20); step_Ai(W2,W3,19); step_Ai(W3,W4,18); step_Ai(W4,W1,17);
- step_Ai(W1,W2,24); step_Ai(W2,W3,23); step_Ai(W3,W4,22); step_Ai(W4,W1,21);
- step_Ai(W1,W2,20); step_Ai(W2,W3,19); step_Ai(W3,W4,18); step_Ai(W4,W1,17);
+ step_Bi(W2,W3,16); step_Bi(W3,W4,15); step_Bi(W4,W1,14); step_Bi(W1,W2,13);
+ step_Bi(W2,W3,12); step_Bi(W3,W4,11); step_Bi(W4,W1,10); step_Bi(W1,W2, 9);
- step_Bi(W2,W3,16); step_Bi(W3,W4,15); step_Bi(W4,W1,14); step_Bi(W1,W2,13);
- step_Bi(W2,W3,12); step_Bi(W3,W4,11); step_Bi(W4,W1,10); step_Bi(W1,W2, 9);
+ step_Ai(W1,W2, 8); step_Ai(W2,W3, 7); step_Ai(W3,W4, 6); step_Ai(W4,W1, 5);
+ step_Ai(W1,W2, 4); step_Ai(W2,W3, 3); step_Ai(W3,W4, 2); step_Ai(W4,W1, 1);
- step_Ai(W1,W2, 8); step_Ai(W2,W3, 7); step_Ai(W3,W4, 6); step_Ai(W4,W1, 5);
- step_Ai(W1,W2, 4); step_Ai(W2,W3, 3); step_Ai(W3,W4, 2); step_Ai(W4,W1, 1);
+ store_le(out, W4, W3, W2, W1);
- store_le(out, W4, W3, W2, W1);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
@@ -153,7 +165,7 @@ void Skipjack::key_schedule(const byte key[], u32bit)
/*
* Clear memory of sensitive data
*/
-void Skipjack::clear() throw()
+void Skipjack::clear()
{
for(u32bit j = 0; j != 10; ++j)
FTABLE[j].clear();
diff --git a/src/block/skipjack/skipjack.h b/src/block/skipjack/skipjack.h
index 231cd9c87..60fad6310 100644
--- a/src/block/skipjack/skipjack.h
+++ b/src/block/skipjack/skipjack.h
@@ -18,18 +18,21 @@ namespace Botan {
class BOTAN_DLL Skipjack : public BlockCipher
{
public:
- void clear() throw();
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear();
std::string name() const { return "Skipjack"; }
BlockCipher* clone() const { return new Skipjack; }
+
Skipjack() : BlockCipher(8, 10) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
void step_A(u16bit&, u16bit&, u32bit) const;
void step_B(u16bit&, u16bit&, u32bit) const;
void step_Ai(u16bit&, u16bit&, u32bit) const;
void step_Bi(u16bit&, u16bit&, u32bit) const;
+
SecureBuffer<byte, 256> FTABLE[10];
};
diff --git a/src/block/square/info.txt b/src/block/square/info.txt
index a20697923..d33379815 100644
--- a/src/block/square/info.txt
+++ b/src/block/square/info.txt
@@ -1,11 +1 @@
-realname "Square"
-
define SQUARE
-
-load_on auto
-
-<add>
-sqr_tab.cpp
-square.cpp
-square.h
-</add>
diff --git a/src/block/square/square.cpp b/src/block/square/square.cpp
index cb226542d..90f2301cf 100644
--- a/src/block/square/square.cpp
+++ b/src/block/square/square.cpp
@@ -14,103 +14,123 @@ namespace Botan {
/*
* Square Encryption
*/
-void Square::enc(const byte in[], byte out[]) const
+void Square::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit T0, T1, T2, T3, B0, B1, B2, B3;
- B0 = TE0[in[ 0] ^ ME[ 0]] ^ TE1[in[ 4] ^ ME[ 4]] ^
- TE2[in[ 8] ^ ME[ 8]] ^ TE3[in[12] ^ ME[12]] ^ EK[0];
- B1 = TE0[in[ 1] ^ ME[ 1]] ^ TE1[in[ 5] ^ ME[ 5]] ^
- TE2[in[ 9] ^ ME[ 9]] ^ TE3[in[13] ^ ME[13]] ^ EK[1];
- B2 = TE0[in[ 2] ^ ME[ 2]] ^ TE1[in[ 6] ^ ME[ 6]] ^
- TE2[in[10] ^ ME[10]] ^ TE3[in[14] ^ ME[14]] ^ EK[2];
- B3 = TE0[in[ 3] ^ ME[ 3]] ^ TE1[in[ 7] ^ ME[ 7]] ^
- TE2[in[11] ^ ME[11]] ^ TE3[in[15] ^ ME[15]] ^ EK[3];
- for(u32bit j = 1; j != 7; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(0, B1)] ^
- TE2[get_byte(0, B2)] ^ TE3[get_byte(0, B3)] ^ EK[4*j+0];
- T1 = TE0[get_byte(1, B0)] ^ TE1[get_byte(1, B1)] ^
- TE2[get_byte(1, B2)] ^ TE3[get_byte(1, B3)] ^ EK[4*j+1];
- T2 = TE0[get_byte(2, B0)] ^ TE1[get_byte(2, B1)] ^
- TE2[get_byte(2, B2)] ^ TE3[get_byte(2, B3)] ^ EK[4*j+2];
- T3 = TE0[get_byte(3, B0)] ^ TE1[get_byte(3, B1)] ^
- TE2[get_byte(3, B2)] ^ TE3[get_byte(3, B3)] ^ EK[4*j+3];
- B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(0, T1)] ^
- TE2[get_byte(0, T2)] ^ TE3[get_byte(0, T3)] ^ EK[4*j+4];
- B1 = TE0[get_byte(1, T0)] ^ TE1[get_byte(1, T1)] ^
- TE2[get_byte(1, T2)] ^ TE3[get_byte(1, T3)] ^ EK[4*j+5];
- B2 = TE0[get_byte(2, T0)] ^ TE1[get_byte(2, T1)] ^
- TE2[get_byte(2, T2)] ^ TE3[get_byte(2, T3)] ^ EK[4*j+6];
- B3 = TE0[get_byte(3, T0)] ^ TE1[get_byte(3, T1)] ^
- TE2[get_byte(3, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4*j+7];
+ u32bit T0, T1, T2, T3, B0, B1, B2, B3;
+
+ B0 = TE0[in[ 0] ^ ME[ 0]] ^ TE1[in[ 4] ^ ME[ 4]] ^
+ TE2[in[ 8] ^ ME[ 8]] ^ TE3[in[12] ^ ME[12]] ^ EK[0];
+ B1 = TE0[in[ 1] ^ ME[ 1]] ^ TE1[in[ 5] ^ ME[ 5]] ^
+ TE2[in[ 9] ^ ME[ 9]] ^ TE3[in[13] ^ ME[13]] ^ EK[1];
+ B2 = TE0[in[ 2] ^ ME[ 2]] ^ TE1[in[ 6] ^ ME[ 6]] ^
+ TE2[in[10] ^ ME[10]] ^ TE3[in[14] ^ ME[14]] ^ EK[2];
+ B3 = TE0[in[ 3] ^ ME[ 3]] ^ TE1[in[ 7] ^ ME[ 7]] ^
+ TE2[in[11] ^ ME[11]] ^ TE3[in[15] ^ ME[15]] ^ EK[3];
+
+ for(u32bit j = 1; j != 7; j += 2)
+ {
+ T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(0, B1)] ^
+ TE2[get_byte(0, B2)] ^ TE3[get_byte(0, B3)] ^ EK[4*j+0];
+ T1 = TE0[get_byte(1, B0)] ^ TE1[get_byte(1, B1)] ^
+ TE2[get_byte(1, B2)] ^ TE3[get_byte(1, B3)] ^ EK[4*j+1];
+ T2 = TE0[get_byte(2, B0)] ^ TE1[get_byte(2, B1)] ^
+ TE2[get_byte(2, B2)] ^ TE3[get_byte(2, B3)] ^ EK[4*j+2];
+ T3 = TE0[get_byte(3, B0)] ^ TE1[get_byte(3, B1)] ^
+ TE2[get_byte(3, B2)] ^ TE3[get_byte(3, B3)] ^ EK[4*j+3];
+
+ B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(0, T1)] ^
+ TE2[get_byte(0, T2)] ^ TE3[get_byte(0, T3)] ^ EK[4*j+4];
+ B1 = TE0[get_byte(1, T0)] ^ TE1[get_byte(1, T1)] ^
+ TE2[get_byte(1, T2)] ^ TE3[get_byte(1, T3)] ^ EK[4*j+5];
+ B2 = TE0[get_byte(2, T0)] ^ TE1[get_byte(2, T1)] ^
+ TE2[get_byte(2, T2)] ^ TE3[get_byte(2, T3)] ^ EK[4*j+6];
+ B3 = TE0[get_byte(3, T0)] ^ TE1[get_byte(3, T1)] ^
+ TE2[get_byte(3, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4*j+7];
+ }
+
+ out[ 0] = SE[get_byte(0, B0)] ^ ME[16];
+ out[ 1] = SE[get_byte(0, B1)] ^ ME[17];
+ out[ 2] = SE[get_byte(0, B2)] ^ ME[18];
+ out[ 3] = SE[get_byte(0, B3)] ^ ME[19];
+ out[ 4] = SE[get_byte(1, B0)] ^ ME[20];
+ out[ 5] = SE[get_byte(1, B1)] ^ ME[21];
+ out[ 6] = SE[get_byte(1, B2)] ^ ME[22];
+ out[ 7] = SE[get_byte(1, B3)] ^ ME[23];
+ out[ 8] = SE[get_byte(2, B0)] ^ ME[24];
+ out[ 9] = SE[get_byte(2, B1)] ^ ME[25];
+ out[10] = SE[get_byte(2, B2)] ^ ME[26];
+ out[11] = SE[get_byte(2, B3)] ^ ME[27];
+ out[12] = SE[get_byte(3, B0)] ^ ME[28];
+ out[13] = SE[get_byte(3, B1)] ^ ME[29];
+ out[14] = SE[get_byte(3, B2)] ^ ME[30];
+ out[15] = SE[get_byte(3, B3)] ^ ME[31];
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
- out[ 0] = SE[get_byte(0, B0)] ^ ME[16];
- out[ 1] = SE[get_byte(0, B1)] ^ ME[17];
- out[ 2] = SE[get_byte(0, B2)] ^ ME[18];
- out[ 3] = SE[get_byte(0, B3)] ^ ME[19];
- out[ 4] = SE[get_byte(1, B0)] ^ ME[20];
- out[ 5] = SE[get_byte(1, B1)] ^ ME[21];
- out[ 6] = SE[get_byte(1, B2)] ^ ME[22];
- out[ 7] = SE[get_byte(1, B3)] ^ ME[23];
- out[ 8] = SE[get_byte(2, B0)] ^ ME[24];
- out[ 9] = SE[get_byte(2, B1)] ^ ME[25];
- out[10] = SE[get_byte(2, B2)] ^ ME[26];
- out[11] = SE[get_byte(2, B3)] ^ ME[27];
- out[12] = SE[get_byte(3, B0)] ^ ME[28];
- out[13] = SE[get_byte(3, B1)] ^ ME[29];
- out[14] = SE[get_byte(3, B2)] ^ ME[30];
- out[15] = SE[get_byte(3, B3)] ^ ME[31];
}
/*
* Square Decryption
*/
-void Square::dec(const byte in[], byte out[]) const
+void Square::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit T0, T1, T2, T3, B0, B1, B2, B3;
- B0 = TD0[in[ 0] ^ MD[ 0]] ^ TD1[in[ 4] ^ MD[ 4]] ^
- TD2[in[ 8] ^ MD[ 8]] ^ TD3[in[12] ^ MD[12]] ^ DK[0];
- B1 = TD0[in[ 1] ^ MD[ 1]] ^ TD1[in[ 5] ^ MD[ 5]] ^
- TD2[in[ 9] ^ MD[ 9]] ^ TD3[in[13] ^ MD[13]] ^ DK[1];
- B2 = TD0[in[ 2] ^ MD[ 2]] ^ TD1[in[ 6] ^ MD[ 6]] ^
- TD2[in[10] ^ MD[10]] ^ TD3[in[14] ^ MD[14]] ^ DK[2];
- B3 = TD0[in[ 3] ^ MD[ 3]] ^ TD1[in[ 7] ^ MD[ 7]] ^
- TD2[in[11] ^ MD[11]] ^ TD3[in[15] ^ MD[15]] ^ DK[3];
- for(u32bit j = 1; j != 7; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(0, B1)] ^
- TD2[get_byte(0, B2)] ^ TD3[get_byte(0, B3)] ^ DK[4*j+0];
- T1 = TD0[get_byte(1, B0)] ^ TD1[get_byte(1, B1)] ^
- TD2[get_byte(1, B2)] ^ TD3[get_byte(1, B3)] ^ DK[4*j+1];
- T2 = TD0[get_byte(2, B0)] ^ TD1[get_byte(2, B1)] ^
- TD2[get_byte(2, B2)] ^ TD3[get_byte(2, B3)] ^ DK[4*j+2];
- T3 = TD0[get_byte(3, B0)] ^ TD1[get_byte(3, B1)] ^
- TD2[get_byte(3, B2)] ^ TD3[get_byte(3, B3)] ^ DK[4*j+3];
- B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(0, T1)] ^
- TD2[get_byte(0, T2)] ^ TD3[get_byte(0, T3)] ^ DK[4*j+4];
- B1 = TD0[get_byte(1, T0)] ^ TD1[get_byte(1, T1)] ^
- TD2[get_byte(1, T2)] ^ TD3[get_byte(1, T3)] ^ DK[4*j+5];
- B2 = TD0[get_byte(2, T0)] ^ TD1[get_byte(2, T1)] ^
- TD2[get_byte(2, T2)] ^ TD3[get_byte(2, T3)] ^ DK[4*j+6];
- B3 = TD0[get_byte(3, T0)] ^ TD1[get_byte(3, T1)] ^
- TD2[get_byte(3, T2)] ^ TD3[get_byte(3, T3)] ^ DK[4*j+7];
+ u32bit T0, T1, T2, T3, B0, B1, B2, B3;
+
+ B0 = TD0[in[ 0] ^ MD[ 0]] ^ TD1[in[ 4] ^ MD[ 4]] ^
+ TD2[in[ 8] ^ MD[ 8]] ^ TD3[in[12] ^ MD[12]] ^ DK[0];
+ B1 = TD0[in[ 1] ^ MD[ 1]] ^ TD1[in[ 5] ^ MD[ 5]] ^
+ TD2[in[ 9] ^ MD[ 9]] ^ TD3[in[13] ^ MD[13]] ^ DK[1];
+ B2 = TD0[in[ 2] ^ MD[ 2]] ^ TD1[in[ 6] ^ MD[ 6]] ^
+ TD2[in[10] ^ MD[10]] ^ TD3[in[14] ^ MD[14]] ^ DK[2];
+ B3 = TD0[in[ 3] ^ MD[ 3]] ^ TD1[in[ 7] ^ MD[ 7]] ^
+ TD2[in[11] ^ MD[11]] ^ TD3[in[15] ^ MD[15]] ^ DK[3];
+
+ for(u32bit j = 1; j != 7; j += 2)
+ {
+ T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(0, B1)] ^
+ TD2[get_byte(0, B2)] ^ TD3[get_byte(0, B3)] ^ DK[4*j+0];
+ T1 = TD0[get_byte(1, B0)] ^ TD1[get_byte(1, B1)] ^
+ TD2[get_byte(1, B2)] ^ TD3[get_byte(1, B3)] ^ DK[4*j+1];
+ T2 = TD0[get_byte(2, B0)] ^ TD1[get_byte(2, B1)] ^
+ TD2[get_byte(2, B2)] ^ TD3[get_byte(2, B3)] ^ DK[4*j+2];
+ T3 = TD0[get_byte(3, B0)] ^ TD1[get_byte(3, B1)] ^
+ TD2[get_byte(3, B2)] ^ TD3[get_byte(3, B3)] ^ DK[4*j+3];
+
+ B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(0, T1)] ^
+ TD2[get_byte(0, T2)] ^ TD3[get_byte(0, T3)] ^ DK[4*j+4];
+ B1 = TD0[get_byte(1, T0)] ^ TD1[get_byte(1, T1)] ^
+ TD2[get_byte(1, T2)] ^ TD3[get_byte(1, T3)] ^ DK[4*j+5];
+ B2 = TD0[get_byte(2, T0)] ^ TD1[get_byte(2, T1)] ^
+ TD2[get_byte(2, T2)] ^ TD3[get_byte(2, T3)] ^ DK[4*j+6];
+ B3 = TD0[get_byte(3, T0)] ^ TD1[get_byte(3, T1)] ^
+ TD2[get_byte(3, T2)] ^ TD3[get_byte(3, T3)] ^ DK[4*j+7];
+ }
+
+ out[ 0] = SD[get_byte(0, B0)] ^ MD[16];
+ out[ 1] = SD[get_byte(0, B1)] ^ MD[17];
+ out[ 2] = SD[get_byte(0, B2)] ^ MD[18];
+ out[ 3] = SD[get_byte(0, B3)] ^ MD[19];
+ out[ 4] = SD[get_byte(1, B0)] ^ MD[20];
+ out[ 5] = SD[get_byte(1, B1)] ^ MD[21];
+ out[ 6] = SD[get_byte(1, B2)] ^ MD[22];
+ out[ 7] = SD[get_byte(1, B3)] ^ MD[23];
+ out[ 8] = SD[get_byte(2, B0)] ^ MD[24];
+ out[ 9] = SD[get_byte(2, B1)] ^ MD[25];
+ out[10] = SD[get_byte(2, B2)] ^ MD[26];
+ out[11] = SD[get_byte(2, B3)] ^ MD[27];
+ out[12] = SD[get_byte(3, B0)] ^ MD[28];
+ out[13] = SD[get_byte(3, B1)] ^ MD[29];
+ out[14] = SD[get_byte(3, B2)] ^ MD[30];
+ out[15] = SD[get_byte(3, B3)] ^ MD[31];
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
- out[ 0] = SD[get_byte(0, B0)] ^ MD[16];
- out[ 1] = SD[get_byte(0, B1)] ^ MD[17];
- out[ 2] = SD[get_byte(0, B2)] ^ MD[18];
- out[ 3] = SD[get_byte(0, B3)] ^ MD[19];
- out[ 4] = SD[get_byte(1, B0)] ^ MD[20];
- out[ 5] = SD[get_byte(1, B1)] ^ MD[21];
- out[ 6] = SD[get_byte(1, B2)] ^ MD[22];
- out[ 7] = SD[get_byte(1, B3)] ^ MD[23];
- out[ 8] = SD[get_byte(2, B0)] ^ MD[24];
- out[ 9] = SD[get_byte(2, B1)] ^ MD[25];
- out[10] = SD[get_byte(2, B2)] ^ MD[26];
- out[11] = SD[get_byte(2, B3)] ^ MD[27];
- out[12] = SD[get_byte(3, B0)] ^ MD[28];
- out[13] = SD[get_byte(3, B1)] ^ MD[29];
- out[14] = SD[get_byte(3, B2)] ^ MD[30];
- out[15] = SD[get_byte(3, B3)] ^ MD[31];
}
/*
@@ -176,7 +196,7 @@ void Square::transform(u32bit round_key[4])
/*
* Clear memory of sensitive data
*/
-void Square::clear() throw()
+void Square::clear()
{
EK.clear();
DK.clear();
diff --git a/src/block/square/square.h b/src/block/square/square.h
index 94a1fc370..088122181 100644
--- a/src/block/square/square.h
+++ b/src/block/square/square.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL Square : public BlockCipher
{
public:
- void clear() throw();
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear();
std::string name() const { return "Square"; }
BlockCipher* clone() const { return new Square; }
+
Square() : BlockCipher(16, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static void transform(u32bit[4]);
diff --git a/src/block/tea/info.txt b/src/block/tea/info.txt
index 6a0e76b15..67ed5a656 100644
--- a/src/block/tea/info.txt
+++ b/src/block/tea/info.txt
@@ -1,10 +1 @@
-realname "TEA"
-
define TEA
-
-load_on auto
-
-<add>
-tea.cpp
-tea.h
-</add>
diff --git a/src/block/tea/tea.cpp b/src/block/tea/tea.cpp
index 2b4212d9c..de30858da 100644
--- a/src/block/tea/tea.cpp
+++ b/src/block/tea/tea.cpp
@@ -13,37 +13,49 @@ namespace Botan {
/*
* TEA Encryption
*/
-void TEA::enc(const byte in[], byte out[]) const
+void TEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
-
- u32bit S = 0;
- for(u32bit j = 0; j != 32; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- S += 0x9E3779B9;
- L += ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]);
- R += ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]);
- }
+ u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
+
+ u32bit S = 0;
+ for(u32bit j = 0; j != 32; ++j)
+ {
+ S += 0x9E3779B9;
+ L += ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]);
+ R += ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]);
+ }
- store_be(out, L, R);
+ store_be(out, L, R);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* TEA Decryption
*/
-void TEA::dec(const byte in[], byte out[]) const
+void TEA::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
-
- u32bit S = 0xC6EF3720;
- for(u32bit j = 0; j != 32; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- R -= ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]);
- L -= ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]);
- S -= 0x9E3779B9;
- }
+ u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
+
+ u32bit S = 0xC6EF3720;
+ for(u32bit j = 0; j != 32; ++j)
+ {
+ R -= ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]);
+ L -= ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]);
+ S -= 0x9E3779B9;
+ }
- store_be(out, L, R);
+ store_be(out, L, R);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/tea/tea.h b/src/block/tea/tea.h
index 8ddf3e330..c19f272a6 100644
--- a/src/block/tea/tea.h
+++ b/src/block/tea/tea.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL TEA : public BlockCipher
{
public:
- void clear() throw() { K.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { K.clear(); }
std::string name() const { return "TEA"; }
BlockCipher* clone() const { return new TEA; }
+
TEA() : BlockCipher(8, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 4> K;
};
diff --git a/src/block/twofish/info.txt b/src/block/twofish/info.txt
index 35639d858..88eae9ce7 100644
--- a/src/block/twofish/info.txt
+++ b/src/block/twofish/info.txt
@@ -1,11 +1 @@
-realname "Twofish"
-
define TWOFISH
-
-load_on auto
-
-<add>
-two_tab.cpp
-twofish.cpp
-twofish.h
-</add>
diff --git a/src/block/twofish/twofish.cpp b/src/block/twofish/twofish.cpp
index 9784b00a2..3136837aa 100644
--- a/src/block/twofish/twofish.cpp
+++ b/src/block/twofish/twofish.cpp
@@ -14,91 +14,103 @@ namespace Botan {
/*
* Twofish Encryption
*/
-void Twofish::enc(const byte in[], byte out[]) const
+void Twofish::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0) ^ round_key[0];
- u32bit B = load_le<u32bit>(in, 1) ^ round_key[1];
- u32bit C = load_le<u32bit>(in, 2) ^ round_key[2];
- u32bit D = load_le<u32bit>(in, 3) ^ round_key[3];
-
- for(u32bit j = 0; j != 16; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- u32bit X, Y;
-
- X = SBox0[get_byte(3, A)] ^ SBox1[get_byte(2, A)] ^
- SBox2[get_byte(1, A)] ^ SBox3[get_byte(0, A)];
- Y = SBox0[get_byte(0, B)] ^ SBox1[get_byte(3, B)] ^
- SBox2[get_byte(2, B)] ^ SBox3[get_byte(1, B)];
- X += Y;
- Y += X + round_key[2*j + 9];
- X += round_key[2*j + 8];
-
- C = rotate_right(C ^ X, 1);
- D = rotate_left(D, 1) ^ Y;
-
- X = SBox0[get_byte(3, C)] ^ SBox1[get_byte(2, C)] ^
- SBox2[get_byte(1, C)] ^ SBox3[get_byte(0, C)];
- Y = SBox0[get_byte(0, D)] ^ SBox1[get_byte(3, D)] ^
- SBox2[get_byte(2, D)] ^ SBox3[get_byte(1, D)];
- X += Y;
- Y += X + round_key[2*j + 11];
- X += round_key[2*j + 10];
-
- A = rotate_right(A ^ X, 1);
- B = rotate_left(B, 1) ^ Y;
- }
+ u32bit A = load_le<u32bit>(in, 0) ^ round_key[0];
+ u32bit B = load_le<u32bit>(in, 1) ^ round_key[1];
+ u32bit C = load_le<u32bit>(in, 2) ^ round_key[2];
+ u32bit D = load_le<u32bit>(in, 3) ^ round_key[3];
- C ^= round_key[4];
- D ^= round_key[5];
- A ^= round_key[6];
- B ^= round_key[7];
+ for(u32bit j = 0; j != 16; j += 2)
+ {
+ u32bit X, Y;
+
+ X = SBox0[get_byte(3, A)] ^ SBox1[get_byte(2, A)] ^
+ SBox2[get_byte(1, A)] ^ SBox3[get_byte(0, A)];
+ Y = SBox0[get_byte(0, B)] ^ SBox1[get_byte(3, B)] ^
+ SBox2[get_byte(2, B)] ^ SBox3[get_byte(1, B)];
+ X += Y;
+ Y += X + round_key[2*j + 9];
+ X += round_key[2*j + 8];
+
+ C = rotate_right(C ^ X, 1);
+ D = rotate_left(D, 1) ^ Y;
+
+ X = SBox0[get_byte(3, C)] ^ SBox1[get_byte(2, C)] ^
+ SBox2[get_byte(1, C)] ^ SBox3[get_byte(0, C)];
+ Y = SBox0[get_byte(0, D)] ^ SBox1[get_byte(3, D)] ^
+ SBox2[get_byte(2, D)] ^ SBox3[get_byte(1, D)];
+ X += Y;
+ Y += X + round_key[2*j + 11];
+ X += round_key[2*j + 10];
+
+ A = rotate_right(A ^ X, 1);
+ B = rotate_left(B, 1) ^ Y;
+ }
- store_le(out, C, D, A, B);
+ C ^= round_key[4];
+ D ^= round_key[5];
+ A ^= round_key[6];
+ B ^= round_key[7];
+
+ store_le(out, C, D, A, B);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Twofish Decryption
*/
-void Twofish::dec(const byte in[], byte out[]) const
+void Twofish::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0) ^ round_key[4];
- u32bit B = load_le<u32bit>(in, 1) ^ round_key[5];
- u32bit C = load_le<u32bit>(in, 2) ^ round_key[6];
- u32bit D = load_le<u32bit>(in, 3) ^ round_key[7];
-
- for(u32bit j = 0; j != 16; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- u32bit X, Y;
-
- X = SBox0[get_byte(3, A)] ^ SBox1[get_byte(2, A)] ^
- SBox2[get_byte(1, A)] ^ SBox3[get_byte(0, A)];
- Y = SBox0[get_byte(0, B)] ^ SBox1[get_byte(3, B)] ^
- SBox2[get_byte(2, B)] ^ SBox3[get_byte(1, B)];
- X += Y;
- Y += X + round_key[39 - 2*j];
- X += round_key[38 - 2*j];
-
- C = rotate_left(C, 1) ^ X;
- D = rotate_right(D ^ Y, 1);
-
- X = SBox0[get_byte(3, C)] ^ SBox1[get_byte(2, C)] ^
- SBox2[get_byte(1, C)] ^ SBox3[get_byte(0, C)];
- Y = SBox0[get_byte(0, D)] ^ SBox1[get_byte(3, D)] ^
- SBox2[get_byte(2, D)] ^ SBox3[get_byte(1, D)];
- X += Y;
- Y += X + round_key[37 - 2*j];
- X += round_key[36 - 2*j];
-
- A = rotate_left(A, 1) ^ X;
- B = rotate_right(B ^ Y, 1);
- }
+ u32bit A = load_le<u32bit>(in, 0) ^ round_key[4];
+ u32bit B = load_le<u32bit>(in, 1) ^ round_key[5];
+ u32bit C = load_le<u32bit>(in, 2) ^ round_key[6];
+ u32bit D = load_le<u32bit>(in, 3) ^ round_key[7];
- C ^= round_key[0];
- D ^= round_key[1];
- A ^= round_key[2];
- B ^= round_key[3];
+ for(u32bit j = 0; j != 16; j += 2)
+ {
+ u32bit X, Y;
+
+ X = SBox0[get_byte(3, A)] ^ SBox1[get_byte(2, A)] ^
+ SBox2[get_byte(1, A)] ^ SBox3[get_byte(0, A)];
+ Y = SBox0[get_byte(0, B)] ^ SBox1[get_byte(3, B)] ^
+ SBox2[get_byte(2, B)] ^ SBox3[get_byte(1, B)];
+ X += Y;
+ Y += X + round_key[39 - 2*j];
+ X += round_key[38 - 2*j];
+
+ C = rotate_left(C, 1) ^ X;
+ D = rotate_right(D ^ Y, 1);
+
+ X = SBox0[get_byte(3, C)] ^ SBox1[get_byte(2, C)] ^
+ SBox2[get_byte(1, C)] ^ SBox3[get_byte(0, C)];
+ Y = SBox0[get_byte(0, D)] ^ SBox1[get_byte(3, D)] ^
+ SBox2[get_byte(2, D)] ^ SBox3[get_byte(1, D)];
+ X += Y;
+ Y += X + round_key[37 - 2*j];
+ X += round_key[36 - 2*j];
+
+ A = rotate_left(A, 1) ^ X;
+ B = rotate_right(B ^ Y, 1);
+ }
- store_le(out, C, D, A, B);
+ C ^= round_key[0];
+ D ^= round_key[1];
+ A ^= round_key[2];
+ B ^= round_key[3];
+
+ store_le(out, C, D, A, B);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
@@ -206,7 +218,7 @@ void Twofish::rs_mul(byte S[4], byte key, u32bit offset)
/*
* Clear memory of sensitive data
*/
-void Twofish::clear() throw()
+void Twofish::clear()
{
SBox0.clear();
SBox1.clear();
diff --git a/src/block/twofish/twofish.h b/src/block/twofish/twofish.h
index 0640e32f8..71a1e8781 100644
--- a/src/block/twofish/twofish.h
+++ b/src/block/twofish/twofish.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL Twofish : public BlockCipher
{
public:
- void clear() throw();
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear();
std::string name() const { return "Twofish"; }
BlockCipher* clone() const { return new Twofish; }
+
Twofish() : BlockCipher(16, 16, 32, 8) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static void rs_mul(byte[4], byte, u32bit);
diff --git a/src/block/xtea/info.txt b/src/block/xtea/info.txt
index 0120a3bce..d9d37607c 100644
--- a/src/block/xtea/info.txt
+++ b/src/block/xtea/info.txt
@@ -1,10 +1 @@
-realname "XTEA"
-
define XTEA
-
-load_on auto
-
-<add>
-xtea.cpp
-xtea.h
-</add>
diff --git a/src/block/xtea/xtea.cpp b/src/block/xtea/xtea.cpp
index 5047f6594..fc14c0a57 100644
--- a/src/block/xtea/xtea.cpp
+++ b/src/block/xtea/xtea.cpp
@@ -7,40 +7,113 @@
#include <botan/xtea.h>
#include <botan/loadstor.h>
-#include <botan/parsing.h>
namespace Botan {
+namespace {
+
+void xtea_encrypt_4(const byte in[32], byte out[32], const u32bit EK[64])
+ {
+ u32bit L0, R0, L1, R1, L2, R2, L3, R3;
+ load_be(in, L0, R0, L1, R1, L2, R2, L3, R3);
+
+ for(u32bit i = 0; i != 32; ++i)
+ {
+ L0 += (((R0 << 4) ^ (R0 >> 5)) + R0) ^ EK[2*i];
+ L1 += (((R1 << 4) ^ (R1 >> 5)) + R1) ^ EK[2*i];
+ L2 += (((R2 << 4) ^ (R2 >> 5)) + R2) ^ EK[2*i];
+ L3 += (((R3 << 4) ^ (R3 >> 5)) + R3) ^ EK[2*i];
+
+ R0 += (((L0 << 4) ^ (L0 >> 5)) + L0) ^ EK[2*i+1];
+ R1 += (((L1 << 4) ^ (L1 >> 5)) + L1) ^ EK[2*i+1];
+ R2 += (((L2 << 4) ^ (L2 >> 5)) + L2) ^ EK[2*i+1];
+ R3 += (((L3 << 4) ^ (L3 >> 5)) + L3) ^ EK[2*i+1];
+ }
+
+ store_be(out, L0, R0, L1, R1, L2, R2, L3, R3);
+ }
+
+void xtea_decrypt_4(const byte in[32], byte out[32], const u32bit EK[64])
+ {
+ u32bit L0, R0, L1, R1, L2, R2, L3, R3;
+ load_be(in, L0, R0, L1, R1, L2, R2, L3, R3);
+
+ for(u32bit i = 0; i != 32; ++i)
+ {
+ R0 -= (((L0 << 4) ^ (L0 >> 5)) + L0) ^ EK[63 - 2*i];
+ R1 -= (((L1 << 4) ^ (L1 >> 5)) + L1) ^ EK[63 - 2*i];
+ R2 -= (((L2 << 4) ^ (L2 >> 5)) + L2) ^ EK[63 - 2*i];
+ R3 -= (((L3 << 4) ^ (L3 >> 5)) + L3) ^ EK[63 - 2*i];
+
+ L0 -= (((R0 << 4) ^ (R0 >> 5)) + R0) ^ EK[62 - 2*i];
+ L1 -= (((R1 << 4) ^ (R1 >> 5)) + R1) ^ EK[62 - 2*i];
+ L2 -= (((R2 << 4) ^ (R2 >> 5)) + R2) ^ EK[62 - 2*i];
+ L3 -= (((R3 << 4) ^ (R3 >> 5)) + R3) ^ EK[62 - 2*i];
+ }
+
+ store_be(out, L0, R0, L1, R1, L2, R2, L3, R3);
+ }
+
+}
+
/*
* XTEA Encryption
*/
-void XTEA::enc(const byte in[], byte out[]) const
+void XTEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
-
- for(u32bit j = 0; j != 32; ++j)
+ while(blocks >= 4)
{
- L += (((R << 4) ^ (R >> 5)) + R) ^ EK[2*j];
- R += (((L << 4) ^ (L >> 5)) + L) ^ EK[2*j+1];
+ xtea_encrypt_4(in, out, this->EK);
+ in += 4 * BLOCK_SIZE;
+ out += 4 * BLOCK_SIZE;
+ blocks -= 4;
}
- store_be(out, L, R);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
+
+ for(u32bit j = 0; j != 32; ++j)
+ {
+ L += (((R << 4) ^ (R >> 5)) + R) ^ EK[2*j];
+ R += (((L << 4) ^ (L >> 5)) + L) ^ EK[2*j+1];
+ }
+
+ store_be(out, L, R);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* XTEA Decryption
*/
-void XTEA::dec(const byte in[], byte out[]) const
+void XTEA::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
-
- for(u32bit j = 0; j != 32; ++j)
+ while(blocks >= 4)
{
- R -= (((L << 4) ^ (L >> 5)) + L) ^ EK[63 - 2*j];
- L -= (((R << 4) ^ (R >> 5)) + R) ^ EK[62 - 2*j];
+ xtea_decrypt_4(in, out, this->EK);
+ in += 4 * BLOCK_SIZE;
+ out += 4 * BLOCK_SIZE;
+ blocks -= 4;
}
- store_be(out, L, R);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
+
+ for(u32bit j = 0; j != 32; ++j)
+ {
+ R -= (((L << 4) ^ (L >> 5)) + L) ^ EK[63 - 2*j];
+ L -= (((R << 4) ^ (R >> 5)) + R) ^ EK[62 - 2*j];
+ }
+
+ store_be(out, L, R);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/xtea/xtea.h b/src/block/xtea/xtea.h
index d9c6066cb..9982d0712 100644
--- a/src/block/xtea/xtea.h
+++ b/src/block/xtea/xtea.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL XTEA : public BlockCipher
{
public:
- void clear() throw() { EK.clear(); }
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear() { EK.clear(); }
std::string name() const { return "XTEA"; }
BlockCipher* clone() const { return new XTEA; }
+
XTEA() : BlockCipher(8, 16) {}
- private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
+ protected:
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 64> EK;
};
diff --git a/src/block/xtea_simd/info.txt b/src/block/xtea_simd/info.txt
new file mode 100644
index 000000000..98a6e941f
--- /dev/null
+++ b/src/block/xtea_simd/info.txt
@@ -0,0 +1,14 @@
+define XTEA_SIMD
+
+load_on auto
+
+<add>
+xtea_simd.cpp
+xtea_simd.h
+</add>
+
+<requires>
+xtea
+simd_32
+simd_engine
+</requires>
diff --git a/src/block/xtea_simd/xtea_simd.cpp b/src/block/xtea_simd/xtea_simd.cpp
new file mode 100644
index 000000000..6151c355c
--- /dev/null
+++ b/src/block/xtea_simd/xtea_simd.cpp
@@ -0,0 +1,124 @@
+/*
+* XTEA in SIMD
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/xtea_simd.h>
+#include <botan/loadstor.h>
+#include <botan/simd_32.h>
+
+namespace Botan {
+
+namespace {
+
+void xtea_encrypt_8(const byte in[64], byte out[64], const u32bit EK[64])
+ {
+ SIMD_32 L0 = SIMD_32::load_be(in );
+ SIMD_32 R0 = SIMD_32::load_be(in + 16);
+ SIMD_32 L1 = SIMD_32::load_be(in + 32);
+ SIMD_32 R1 = SIMD_32::load_be(in + 48);
+
+ SIMD_32::transpose(L0, R0, L1, R1);
+
+ for(u32bit i = 0; i != 32; i += 2)
+ {
+ SIMD_32 K0(EK[2*i ]);
+ SIMD_32 K1(EK[2*i+1]);
+ SIMD_32 K2(EK[2*i+2]);
+ SIMD_32 K3(EK[2*i+3]);
+
+ L0 += (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K0;
+ L1 += (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K0;
+
+ R0 += (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K1;
+ R1 += (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K1;
+
+ L0 += (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K2;
+ L1 += (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K2;
+
+ R0 += (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K3;
+ R1 += (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K3;
+ }
+
+ SIMD_32::transpose(L0, R0, L1, R1);
+
+ L0.store_be(out);
+ R0.store_be(out + 16);
+ L1.store_be(out + 32);
+ R1.store_be(out + 48);
+ }
+
+void xtea_decrypt_8(const byte in[64], byte out[64], const u32bit EK[64])
+ {
+ SIMD_32 L0 = SIMD_32::load_be(in );
+ SIMD_32 R0 = SIMD_32::load_be(in + 16);
+ SIMD_32 L1 = SIMD_32::load_be(in + 32);
+ SIMD_32 R1 = SIMD_32::load_be(in + 48);
+
+ SIMD_32::transpose(L0, R0, L1, R1);
+
+ for(u32bit i = 0; i != 32; i += 2)
+ {
+ SIMD_32 K0(EK[63 - 2*i]);
+ SIMD_32 K1(EK[62 - 2*i]);
+ SIMD_32 K2(EK[61 - 2*i]);
+ SIMD_32 K3(EK[60 - 2*i]);
+
+ R0 -= (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K0;
+ R1 -= (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K0;
+
+ L0 -= (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K1;
+ L1 -= (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K1;
+
+ R0 -= (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K2;
+ R1 -= (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K2;
+
+ L0 -= (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K3;
+ L1 -= (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K3;
+ }
+
+ SIMD_32::transpose(L0, R0, L1, R1);
+
+ L0.store_be(out);
+ R0.store_be(out + 16);
+ L1.store_be(out + 32);
+ R1.store_be(out + 48);
+ }
+
+}
+
+/*
+* XTEA Encryption
+*/
+void XTEA_SIMD::encrypt_n(const byte in[], byte out[], u32bit blocks) const
+ {
+ while(blocks >= 8)
+ {
+ xtea_encrypt_8(in, out, this->EK);
+ in += 8 * BLOCK_SIZE;
+ out += 8 * BLOCK_SIZE;
+ blocks -= 8;
+ }
+
+ XTEA::encrypt_n(in, out, blocks);
+ }
+
+/*
+* XTEA Decryption
+*/
+void XTEA_SIMD::decrypt_n(const byte in[], byte out[], u32bit blocks) const
+ {
+ while(blocks >= 8)
+ {
+ xtea_decrypt_8(in, out, this->EK);
+ in += 8 * BLOCK_SIZE;
+ out += 8 * BLOCK_SIZE;
+ blocks -= 8;
+ }
+
+ XTEA::decrypt_n(in, out, blocks);
+ }
+
+}
diff --git a/src/block/xtea_simd/xtea_simd.h b/src/block/xtea_simd/xtea_simd.h
new file mode 100644
index 000000000..e4ce734ed
--- /dev/null
+++ b/src/block/xtea_simd/xtea_simd.h
@@ -0,0 +1,28 @@
+/*
+* XTEA in SIMD
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_XTEA_SIMD_H__
+#define BOTAN_XTEA_SIMD_H__
+
+#include <botan/xtea.h>
+
+namespace Botan {
+
+/*
+* XTEA (SIMD variant)
+*/
+class BOTAN_DLL XTEA_SIMD : public XTEA
+ {
+ public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ BlockCipher* clone() const { return new XTEA_SIMD; }
+ };
+
+}
+
+#endif