From f51841ba5237952dda3e76df643d3ae13bed3df5 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 11 Aug 2009 02:31:17 +0000 Subject: Change the BlockCipher interface to support multi-block encryption and decryption. Currently only used for counter mode. Doesn't offer much advantage as-is (though might help slightly, in terms of cache effects), but allows for SIMD implementations to process multiple blocks in parallel when possible. Particularly thinking here of Serpent; TEA/XTEA also seem promising in this sense, as is Threefish once that is implemented as a standalone block cipher. --- src/block/aes/aes.cpp | 266 ++++++++++++++++++----------------- src/block/aes/aes.h | 6 +- src/block/block_cipher.h | 20 +-- src/block/blowfish/blowfish.cpp | 70 +++++---- src/block/blowfish/blowfish.h | 6 +- src/block/cast/cast128.cpp | 100 +++++++------ src/block/cast/cast128.h | 4 +- src/block/cast/cast256.cpp | 140 +++++++++--------- src/block/cast/cast256.h | 4 +- src/block/des/des.cpp | 144 +++++++++++-------- src/block/des/des.h | 8 +- src/block/des/desx.cpp | 28 ++-- src/block/des/desx.h | 4 +- src/block/gost_28147/gost_28147.cpp | 67 +++++---- src/block/gost_28147/gost_28147.h | 4 +- src/block/idea/idea.cpp | 132 +++++++++-------- src/block/idea/idea.h | 4 +- src/block/kasumi/kasumi.cpp | 110 ++++++++------- src/block/kasumi/kasumi.h | 4 +- src/block/lion/lion.cpp | 56 +++++--- src/block/lion/lion.h | 4 +- src/block/lubyrack/lubyrack.cpp | 104 ++++++++------ src/block/lubyrack/lubyrack.h | 4 +- src/block/mars/mars.cpp | 138 +++++++++--------- src/block/mars/mars.h | 4 +- src/block/misty1/misty1.cpp | 130 +++++++++-------- src/block/misty1/misty1.h | 4 +- src/block/noekeon/noekeon.cpp | 92 ++++++------ src/block/noekeon/noekeon.h | 4 +- src/block/rc2/rc2.cpp | 104 ++++++++------ src/block/rc2/rc2.h | 4 +- src/block/rc5/rc5.cpp | 72 ++++++---- src/block/rc5/rc5.h | 4 +- src/block/rc6/rc6.cpp | 140 +++++++++--------- src/block/rc6/rc6.h | 4 +- src/block/safer/safer_sk.cpp | 97 ++++++++----- src/block/safer/safer_sk.h | 4 +- src/block/seed/seed.cpp | 116 ++++++++------- src/block/seed/seed.h | 4 +- src/block/serpent/serpent.cpp | 172 +++++++++++----------- src/block/serpent/serpent.h | 4 +- src/block/serpent_ia32/serp_ia32.cpp | 18 ++- src/block/serpent_ia32/serp_ia32.h | 4 +- src/block/skipjack/skipjack.cpp | 68 +++++---- src/block/skipjack/skipjack.h | 4 +- src/block/square/square.cpp | 192 ++++++++++++++----------- src/block/square/square.h | 4 +- src/block/tea/tea.cpp | 52 ++++--- src/block/tea/tea.h | 4 +- src/block/twofish/twofish.cpp | 156 ++++++++++---------- src/block/twofish/twofish.h | 4 +- src/block/xtea/xtea.cpp | 44 +++--- src/block/xtea/xtea.h | 4 +- src/modes/ctr/ctr.cpp | 104 +++++++++++--- src/modes/ctr/ctr.h | 17 ++- 55 files changed, 1740 insertions(+), 1321 deletions(-) (limited to 'src') diff --git a/src/block/aes/aes.cpp b/src/block/aes/aes.cpp index 9072b507b..34698ae7f 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(in, 0) ^ EK[0]; - u32bit T1 = load_be(in, 1) ^ EK[1]; - u32bit T2 = load_be(in, 2) ^ EK[2]; - u32bit T3 = load_be(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(in, 0) ^ EK[0]; + u32bit T1 = load_be(in, 1) ^ EK[1]; + u32bit T2 = load_be(in, 2) ^ EK[2]; + u32bit T3 = load_be(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 - - Cache-Collision Timing Attacks Against AES describes an attack - that can recover AES keys with as few as 213 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 + + Cache-Collision Timing Attacks Against AES describes an attack + that can recover AES keys with as few as 213 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(in, 0) ^ DK[0]; - u32bit T1 = load_be(in, 1) ^ DK[1]; - u32bit T2 = load_be(in, 2) ^ DK[2]; - u32bit T3 = load_be(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(in, 0) ^ DK[0]; + u32bit T1 = load_be(in, 1) ^ DK[1]; + u32bit T2 = load_be(in, 2) ^ DK[2]; + u32bit T3 = load_be(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; + } } /** diff --git a/src/block/aes/aes.h b/src/block/aes/aes.h index 05e2e3123..940e11a48 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 */ @@ -24,8 +24,8 @@ class BOTAN_DLL AES : public BlockCipher AES() : BlockCipher(16, 16, 32, 8) { ROUNDS = 14; } AES(u32bit); private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); static u32bit S(u32bit); diff --git a/src/block/block_cipher.h b/src/block/block_cipher.h index 01c45af04..a27609171 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 @@ -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..312603c3a 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(in, 0); - u32bit R = load_be(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(in, 0); + u32bit R = load_be(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(in, 0); - u32bit R = load_be(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(in, 0); + u32bit R = load_be(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; + } } /* diff --git a/src/block/blowfish/blowfish.h b/src/block/blowfish/blowfish.h index f0f26418d..3623c2087 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 */ @@ -23,8 +23,8 @@ class BOTAN_DLL Blowfish : public BlockCipher 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); void generate_sbox(u32bit[], u32bit, u32bit&, u32bit&) const; 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(in, 0); - u32bit R = load_be(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(in, 0); + u32bit R = load_be(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(in, 0); - u32bit R = load_be(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(in, 0); + u32bit R = load_be(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..092ee824b 100644 --- a/src/block/cast/cast128.h +++ b/src/block/cast/cast128.h @@ -23,8 +23,8 @@ class BOTAN_DLL CAST_128 : public BlockCipher 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) 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(in, 0); - u32bit B = load_be(in, 1); - u32bit C = load_be(in, 2); - u32bit D = load_be(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(in, 0); + u32bit B = load_be(in, 1); + u32bit C = load_be(in, 2); + u32bit D = load_be(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(in, 0); - u32bit B = load_be(in, 1); - u32bit C = load_be(in, 2); - u32bit D = load_be(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(in, 0); + u32bit B = load_be(in, 1); + u32bit C = load_be(in, 2); + u32bit D = load_be(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..ea80df65d 100644 --- a/src/block/cast/cast256.h +++ b/src/block/cast/cast256.h @@ -23,8 +23,8 @@ class BOTAN_DLL CAST_256 : public BlockCipher 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); static const u32bit KEY_MASK[192]; diff --git a/src/block/des/des.cpp b/src/block/des/des.cpp index 37520e0fc..1c9d37e6b 100644 --- a/src/block/des/des.cpp +++ b/src/block/des/des.cpp @@ -139,51 +139,63 @@ 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(T >> 32); + u32bit R = static_cast(T); - u32bit L = static_cast(T >> 32); - u32bit R = static_cast(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(T >> 32); + u32bit R = static_cast(T); - u32bit L = static_cast(T >> 32); - u32bit R = static_cast(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 +209,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(T >> 32); + u32bit R = static_cast(T); - u32bit L = static_cast(T >> 32); - u32bit R = static_cast(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(T >> 32); + u32bit R = static_cast(T); - u32bit L = static_cast(T >> 32); - u32bit R = static_cast(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..39d1ac404 100644 --- a/src/block/des/des.h +++ b/src/block/des/des.h @@ -23,8 +23,8 @@ class BOTAN_DLL DES : public BlockCipher BlockCipher* clone() const { return new DES; } DES() : BlockCipher(8, 8) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer round_key; @@ -41,8 +41,8 @@ class BOTAN_DLL TripleDES : public BlockCipher 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer 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..d71335071 100644 --- a/src/block/des/desx.h +++ b/src/block/des/desx.h @@ -23,8 +23,8 @@ class BOTAN_DLL DESX : public BlockCipher BlockCipher* clone() const { return new DESX; } DESX() : BlockCipher(8, 24) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer K1, K2; DES des; 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(in, 0), N2 = load_le(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(in, 0), N2 = load_le(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(in, 0), N2 = load_le(in, 1); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit N1 = load_le(in, 0), N2 = load_le(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..825e106a2 100644 --- a/src/block/gost_28147/gost_28147.h +++ b/src/block/gost_28147/gost_28147.h @@ -54,8 +54,8 @@ class BOTAN_DLL GOST_28147_89 : public BlockCipher GOST_28147_89(const SecureBuffer& other_SBOX) : BlockCipher(8, 32), SBOX(other_SBOX) {} - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer SBOX; 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(in, 0); - u16bit X2 = load_be(in, 1); - u16bit X3 = load_be(in, 2); - u16bit X4 = load_be(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(in, 0); + u16bit X2 = load_be(in, 1); + u16bit X3 = load_be(in, 2); + u16bit X4 = load_be(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(in, 0); - u16bit X2 = load_be(in, 1); - u16bit X3 = load_be(in, 2); - u16bit X4 = load_be(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(in, 0); + u16bit X2 = load_be(in, 1); + u16bit X3 = load_be(in, 2); + u16bit X4 = load_be(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..a3384b667 100644 --- a/src/block/idea/idea.h +++ b/src/block/idea/idea.h @@ -23,8 +23,8 @@ class BOTAN_DLL IDEA : public BlockCipher BlockCipher* clone() const { return new IDEA; } IDEA() : BlockCipher(8, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer EK, DK; }; 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(in, 0); - u16bit B1 = load_be(in, 1); - u16bit B2 = load_be(in, 2); - u16bit B3 = load_be(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(in, 0); + u16bit B1 = load_be(in, 1); + u16bit B2 = load_be(in, 2); + u16bit B3 = load_be(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(in, 0); - u16bit B1 = load_be(in, 1); - u16bit B2 = load_be(in, 2); - u16bit B3 = load_be(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(in, 0); + u16bit B1 = load_be(in, 1); + u16bit B2 = load_be(in, 2); + u16bit B3 = load_be(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..3b18e675b 100644 --- a/src/block/kasumi/kasumi.h +++ b/src/block/kasumi/kasumi.h @@ -24,8 +24,8 @@ class BOTAN_DLL KASUMI : public BlockCipher KASUMI() : BlockCipher(8, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer EK; diff --git a/src/block/lion/lion.cpp b/src/block/lion/lion.cpp index c7cdf6d13..bfff64b67 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 buffer(LEFT_SIZE); + for(u32bit i = 0; i != blocks; ++i) + { + SecureVector 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); + xor_buf(buffer, in, key1, LEFT_SIZE); + cipher->set_key(buffer, LEFT_SIZE); + cipher->encrypt(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->encrypt(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 buffer(LEFT_SIZE); + for(u32bit i = 0; i != blocks; ++i) + { + SecureVector 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); - xor_buf(buffer, in, key2, LEFT_SIZE); - cipher->set_key(buffer, LEFT_SIZE); - cipher->encrypt(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->encrypt(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; + } } /* diff --git a/src/block/lion/lion.h b/src/block/lion/lion.h index 5bc4e72c0..d9f933846 100644 --- a/src/block/lion/lion.h +++ b/src/block/lion/lion.h @@ -27,8 +27,8 @@ class BOTAN_DLL Lion : public BlockCipher Lion(HashFunction*, StreamCipher*, u32bit); ~Lion() { delete hash; delete cipher; } private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); const u32bit LEFT_SIZE, RIGHT_SIZE; diff --git a/src/block/lubyrack/lubyrack.cpp b/src/block/lubyrack/lubyrack.cpp index a9d2b1db2..6ad64f2b0 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 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 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 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 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; + } } /* diff --git a/src/block/lubyrack/lubyrack.h b/src/block/lubyrack/lubyrack.h index ebde31304..1e83748a6 100644 --- a/src/block/lubyrack/lubyrack.h +++ b/src/block/lubyrack/lubyrack.h @@ -26,8 +26,8 @@ class BOTAN_DLL LubyRackoff : public BlockCipher LubyRackoff(HashFunction* hash); ~LubyRackoff() { delete hash; } private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); HashFunction* hash; SecureVector K1, K2; 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(in, 0) + EK[0]; - u32bit B = load_le(in, 1) + EK[1]; - u32bit C = load_le(in, 2) + EK[2]; - u32bit D = load_le(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(in, 0) + EK[0]; + u32bit B = load_le(in, 1) + EK[1]; + u32bit C = load_le(in, 2) + EK[2]; + u32bit D = load_le(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(in, 3) + EK[39]; - u32bit B = load_le(in, 2) + EK[38]; - u32bit C = load_le(in, 1) + EK[37]; - u32bit D = load_le(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(in, 3) + EK[39]; + u32bit B = load_le(in, 2) + EK[38]; + u32bit C = load_le(in, 1) + EK[37]; + u32bit D = load_le(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..b3d74b179 100644 --- a/src/block/mars/mars.h +++ b/src/block/mars/mars.h @@ -20,8 +20,8 @@ class BOTAN_DLL MARS : public BlockCipher 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); void encrypt_round(u32bit&, u32bit&, u32bit&, u32bit&, u32bit) const; 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(in, 0); - u16bit B1 = load_be(in, 1); - u16bit B2 = load_be(in, 2); - u16bit B3 = load_be(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(in, 0); + u16bit B1 = load_be(in, 1); + u16bit B2 = load_be(in, 2); + u16bit B3 = load_be(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(in, 2); - u16bit B1 = load_be(in, 3); - u16bit B2 = load_be(in, 0); - u16bit B3 = load_be(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(in, 2); + u16bit B1 = load_be(in, 3); + u16bit B2 = load_be(in, 0); + u16bit B3 = load_be(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..14b7c8e45 100644 --- a/src/block/misty1/misty1.h +++ b/src/block/misty1/misty1.h @@ -23,8 +23,8 @@ class BOTAN_DLL MISTY1 : public BlockCipher BlockCipher* clone() const { return new MISTY1; } MISTY1(u32bit = 8); private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer EK, DK; diff --git a/src/block/noekeon/noekeon.cpp b/src/block/noekeon/noekeon.cpp index 90eb9ad2b..1b327aa47 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(in, 0); - u32bit A1 = load_be(in, 1); - u32bit A2 = load_be(in, 2); - u32bit A3 = load_be(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(in, 0); + u32bit A1 = load_be(in, 1); + u32bit A2 = load_be(in, 2); + u32bit A3 = load_be(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(in, 0); - u32bit A1 = load_be(in, 1); - u32bit A2 = load_be(in, 2); - u32bit A3 = load_be(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(in, 0); + u32bit A1 = load_be(in, 1); + u32bit A2 = load_be(in, 2); + u32bit A3 = load_be(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; + } } /* diff --git a/src/block/noekeon/noekeon.h b/src/block/noekeon/noekeon.h index 893892446..b4f3980d7 100644 --- a/src/block/noekeon/noekeon.h +++ b/src/block/noekeon/noekeon.h @@ -23,8 +23,8 @@ class BOTAN_DLL Noekeon : public BlockCipher BlockCipher* clone() const { return new Noekeon; } Noekeon() : BlockCipher(16, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); static const byte RC[17]; 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(in, 0); - u16bit R1 = load_le(in, 1); - u16bit R2 = load_le(in, 2); - u16bit R3 = load_le(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(in, 0); + u16bit R1 = load_le(in, 1); + u16bit R2 = load_le(in, 2); + u16bit R3 = load_le(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(in, 0); - u16bit R1 = load_le(in, 1); - u16bit R2 = load_le(in, 2); - u16bit R3 = load_le(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(in, 0); + u16bit R1 = load_le(in, 1); + u16bit R2 = load_le(in, 2); + u16bit R3 = load_le(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..0d94d69a2 100644 --- a/src/block/rc2/rc2.h +++ b/src/block/rc2/rc2.h @@ -25,8 +25,8 @@ class BOTAN_DLL RC2 : public BlockCipher 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer K; 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(in, 0), B = load_le(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(in, 0), B = load_le(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(in, 0), B = load_le(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(in, 0), B = load_le(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..1816994dc 100644 --- a/src/block/rc5/rc5.h +++ b/src/block/rc5/rc5.h @@ -23,8 +23,8 @@ class BOTAN_DLL RC5 : public BlockCipher BlockCipher* clone() const { return new RC5(ROUNDS); } RC5(u32bit); private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureVector S; const u32bit ROUNDS; 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(in, 0); - u32bit B = load_le(in, 1); - u32bit C = load_le(in, 2); - u32bit D = load_le(in, 3); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit A = load_le(in, 0); + u32bit B = load_le(in, 1); + u32bit C = load_le(in, 2); + u32bit D = load_le(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(in, 0); - u32bit B = load_le(in, 1); - u32bit C = load_le(in, 2); - u32bit D = load_le(in, 3); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit A = load_le(in, 0); + u32bit B = load_le(in, 1); + u32bit C = load_le(in, 2); + u32bit D = load_le(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..f634ebcd9 100644 --- a/src/block/rc6/rc6.h +++ b/src/block/rc6/rc6.h @@ -23,8 +23,8 @@ class BOTAN_DLL RC6 : public BlockCipher 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer S; 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..ae3d4f9a8 100644 --- a/src/block/safer/safer_sk.h +++ b/src/block/safer/safer_sk.h @@ -23,8 +23,8 @@ class BOTAN_DLL SAFER_SK : public BlockCipher BlockCipher* clone() const; SAFER_SK(u32bit); private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); static const byte EXP[256]; 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(in, 0); - u32bit B1 = load_be(in, 1); - u32bit B2 = load_be(in, 2); - u32bit B3 = load_be(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(in, 0); + u32bit B1 = load_be(in, 1); + u32bit B2 = load_be(in, 2); + u32bit B3 = load_be(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(in, 0); - u32bit B1 = load_be(in, 1); - u32bit B2 = load_be(in, 2); - u32bit B3 = load_be(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(in, 0); + u32bit B1 = load_be(in, 1); + u32bit B2 = load_be(in, 2); + u32bit B3 = load_be(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..0c9c2c8af 100644 --- a/src/block/seed/seed.h +++ b/src/block/seed/seed.h @@ -23,8 +23,8 @@ class BOTAN_DLL SEED : public BlockCipher BlockCipher* clone() const { return new SEED; } SEED() : BlockCipher(16, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); class G_FUNC 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(in, 0); - u32bit B1 = load_le(in, 1); - u32bit B2 = load_le(in, 2); - u32bit B3 = load_le(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(in, 0); + u32bit B1 = load_le(in, 1); + u32bit B2 = load_le(in, 2); + u32bit B3 = load_le(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(in, 0); - u32bit B1 = load_le(in, 1); - u32bit B2 = load_le(in, 2); - u32bit B3 = load_le(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(in, 0); + u32bit B1 = load_le(in, 1); + u32bit B2 = load_le(in, 2); + u32bit B3 = load_le(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..9c9fb59f2 100644 --- a/src/block/serpent/serpent.h +++ b/src/block/serpent/serpent.h @@ -23,8 +23,8 @@ class BOTAN_DLL Serpent : public BlockCipher 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer round_key; diff --git a/src/block/serpent_ia32/serp_ia32.cpp b/src/block/serpent_ia32/serp_ia32.cpp index 37dd4e637..997bec2fc 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; + } } /* diff --git a/src/block/serpent_ia32/serp_ia32.h b/src/block/serpent_ia32/serp_ia32.h index 565e9889d..2b4a95d3d 100644 --- a/src/block/serpent_ia32/serp_ia32.h +++ b/src/block/serpent_ia32/serp_ia32.h @@ -20,8 +20,8 @@ class BOTAN_DLL Serpent_IA32 : public Serpent public: BlockCipher* clone() const { return new Serpent_IA32; } private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); }; diff --git a/src/block/skipjack/skipjack.cpp b/src/block/skipjack/skipjack.cpp index f5ffc861e..6c308c0f8 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(in, 3); - u16bit W2 = load_le(in, 2); - u16bit W3 = load_le(in, 1); - u16bit W4 = load_le(in, 0); + for(u32bit i = 0; i != blocks; ++i) + { + u16bit W1 = load_le(in, 3); + u16bit W2 = load_le(in, 2); + u16bit W3 = load_le(in, 1); + u16bit W4 = load_le(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(in, 3); - u16bit W2 = load_le(in, 2); - u16bit W3 = load_le(in, 1); - u16bit W4 = load_le(in, 0); + for(u32bit i = 0; i != blocks; ++i) + { + u16bit W1 = load_le(in, 3); + u16bit W2 = load_le(in, 2); + u16bit W3 = load_le(in, 1); + u16bit W4 = load_le(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; + } } /* diff --git a/src/block/skipjack/skipjack.h b/src/block/skipjack/skipjack.h index 231cd9c87..ec071dfe7 100644 --- a/src/block/skipjack/skipjack.h +++ b/src/block/skipjack/skipjack.h @@ -23,8 +23,8 @@ class BOTAN_DLL Skipjack : public BlockCipher BlockCipher* clone() const { return new Skipjack; } Skipjack() : BlockCipher(8, 10) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); void step_A(u16bit&, u16bit&, u32bit) const; void step_B(u16bit&, u16bit&, u32bit) const; diff --git a/src/block/square/square.cpp b/src/block/square/square.cpp index cb226542d..fdd47d3b2 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]; } /* diff --git a/src/block/square/square.h b/src/block/square/square.h index 94a1fc370..0de4c20bd 100644 --- a/src/block/square/square.h +++ b/src/block/square/square.h @@ -23,8 +23,8 @@ class BOTAN_DLL Square : public BlockCipher BlockCipher* clone() const { return new Square; } Square() : BlockCipher(16, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); static void transform(u32bit[4]); 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(in, 0), R = load_be(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(in, 0), R = load_be(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(in, 0), R = load_be(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(in, 0), R = load_be(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..141899e88 100644 --- a/src/block/tea/tea.h +++ b/src/block/tea/tea.h @@ -23,8 +23,8 @@ class BOTAN_DLL TEA : public BlockCipher BlockCipher* clone() const { return new TEA; } TEA() : BlockCipher(8, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer K; }; diff --git a/src/block/twofish/twofish.cpp b/src/block/twofish/twofish.cpp index 9784b00a2..6a482a8f3 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(in, 0) ^ round_key[0]; - u32bit B = load_le(in, 1) ^ round_key[1]; - u32bit C = load_le(in, 2) ^ round_key[2]; - u32bit D = load_le(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(in, 0) ^ round_key[0]; + u32bit B = load_le(in, 1) ^ round_key[1]; + u32bit C = load_le(in, 2) ^ round_key[2]; + u32bit D = load_le(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(in, 0) ^ round_key[4]; - u32bit B = load_le(in, 1) ^ round_key[5]; - u32bit C = load_le(in, 2) ^ round_key[6]; - u32bit D = load_le(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(in, 0) ^ round_key[4]; + u32bit B = load_le(in, 1) ^ round_key[5]; + u32bit C = load_le(in, 2) ^ round_key[6]; + u32bit D = load_le(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; + } } /* diff --git a/src/block/twofish/twofish.h b/src/block/twofish/twofish.h index 0640e32f8..640fb58ad 100644 --- a/src/block/twofish/twofish.h +++ b/src/block/twofish/twofish.h @@ -23,8 +23,8 @@ class BOTAN_DLL Twofish : public BlockCipher 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); static void rs_mul(byte[4], byte, u32bit); diff --git a/src/block/xtea/xtea.cpp b/src/block/xtea/xtea.cpp index 5047f6594..0dba5f2be 100644 --- a/src/block/xtea/xtea.cpp +++ b/src/block/xtea/xtea.cpp @@ -14,33 +14,45 @@ namespace Botan { /* * 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(in, 0), R = load_be(in, 1); - - for(u32bit j = 0; j != 32; ++j) + for(u32bit i = 0; i != blocks; ++i) { - L += (((R << 4) ^ (R >> 5)) + R) ^ EK[2*j]; - R += (((L << 4) ^ (L >> 5)) + L) ^ EK[2*j+1]; - } + u32bit L = load_be(in, 0), R = load_be(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); + 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(in, 0), R = load_be(in, 1); - - for(u32bit j = 0; j != 32; ++j) + for(u32bit i = 0; i != blocks; ++i) { - R -= (((L << 4) ^ (L >> 5)) + L) ^ EK[63 - 2*j]; - L -= (((R << 4) ^ (R >> 5)) + R) ^ EK[62 - 2*j]; - } + u32bit L = load_be(in, 0), R = load_be(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); + 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..b50f487b4 100644 --- a/src/block/xtea/xtea.h +++ b/src/block/xtea/xtea.h @@ -23,8 +23,8 @@ class BOTAN_DLL XTEA : public BlockCipher BlockCipher* clone() const { return new XTEA; } XTEA() : BlockCipher(8, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer EK; }; diff --git a/src/modes/ctr/ctr.cpp b/src/modes/ctr/ctr.cpp index 9eb42ec5a..5c27ca63c 100644 --- a/src/modes/ctr/ctr.cpp +++ b/src/modes/ctr/ctr.cpp @@ -1,6 +1,6 @@ /* * CTR Mode -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -14,9 +14,13 @@ namespace Botan { /* * CTR-BE Constructor */ -CTR_BE::CTR_BE(BlockCipher* ciph) : - BlockCipherMode(ciph, "CTR-BE", ciph->BLOCK_SIZE, 1) +CTR_BE::CTR_BE(BlockCipher* ciph) : cipher(ciph) { + base_ptr = cipher; + position = 0; + + counter.create(ciph->BLOCK_SIZE * CTR_BLOCKS_PARALLEL); + enc_buffer.create(ciph->BLOCK_SIZE * CTR_BLOCKS_PARALLEL); } /* @@ -24,39 +28,86 @@ CTR_BE::CTR_BE(BlockCipher* ciph) : */ CTR_BE::CTR_BE(BlockCipher* ciph, const SymmetricKey& key, const InitializationVector& iv) : - BlockCipherMode(ciph, "CTR-BE", ciph->BLOCK_SIZE, 1) + cipher(ciph) { + base_ptr = cipher; + position = 0; + + counter.create(ciph->BLOCK_SIZE * CTR_BLOCKS_PARALLEL); + enc_buffer.create(ciph->BLOCK_SIZE * CTR_BLOCKS_PARALLEL); + set_key(key); set_iv(iv); } +/* +* CTR_BE Destructor +*/ +CTR_BE::~CTR_BE() + { + delete cipher; + } + +/* +* Return the name of this type +*/ +std::string CTR_BE::name() const + { + return ("CTR-BE/" + cipher->name()); + } + +/* +* Set CTR-BE IV +*/ +void CTR_BE::set_iv(const InitializationVector& iv) + { + if(iv.length() != cipher->BLOCK_SIZE) + throw Invalid_IV_Length(name(), iv.length()); + + enc_buffer.clear(); + position = 0; + + for(u32bit i = 0; i != CTR_BLOCKS_PARALLEL; ++i) + { + counter.copy(i*cipher->BLOCK_SIZE, iv.begin(), iv.length()); + + // FIXME: this is stupid + for(u32bit j = 0; j != i; ++j) + for(s32bit k = cipher->BLOCK_SIZE - 1; k >= 0; --k) + if(++counter[i*cipher->BLOCK_SIZE+k]) + break; + } + + cipher->encrypt_n(counter, enc_buffer, CTR_BLOCKS_PARALLEL); + } + /* * CTR-BE Encryption/Decryption */ void CTR_BE::write(const byte input[], u32bit length) { - u32bit copied = std::min(BLOCK_SIZE - position, length); - xor_buf(buffer + position, input, copied); - send(buffer + position, copied); + u32bit copied = std::min(enc_buffer.size() - position, length); + xor_buf(enc_buffer + position, input, copied); + send(enc_buffer + position, copied); input += copied; length -= copied; position += copied; - if(position == BLOCK_SIZE) + if(position == enc_buffer.size()) increment_counter(); - while(length >= BLOCK_SIZE) + while(length >= enc_buffer.size()) { - xor_buf(buffer, input, BLOCK_SIZE); - send(buffer, BLOCK_SIZE); + xor_buf(enc_buffer, input, enc_buffer.size()); + send(enc_buffer, enc_buffer.size()); - input += BLOCK_SIZE; - length -= BLOCK_SIZE; + input += enc_buffer.size(); + length -= enc_buffer.size(); increment_counter(); } - xor_buf(buffer + position, input, length); - send(buffer + position, length); + xor_buf(enc_buffer + position, input, length); + send(enc_buffer + position, length); position += length; } @@ -65,10 +116,25 @@ void CTR_BE::write(const byte input[], u32bit length) */ void CTR_BE::increment_counter() { - for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j) - if(++state[j]) - break; - cipher->encrypt(state, buffer); + for(u32bit i = 0; i != CTR_BLOCKS_PARALLEL; ++i) + { + // FIXME: Can do it in a single loop + /* + for(u32bit j = 1; j != cipher->BLOCK_SIZE; ++j) + { + byte carry = 0; + byte z = counter[(i+1)*cipher->BLOCK_SIZE-1] + CTR_BLOCKS_PARALLEL; + + if( + */ + for(u32bit j = 0; j != CTR_BLOCKS_PARALLEL; ++j) + for(s32bit k = cipher->BLOCK_SIZE - 1; k >= 0; --k) + if(++counter[i*cipher->BLOCK_SIZE+k]) + break; + } + + cipher->encrypt_n(counter, enc_buffer, CTR_BLOCKS_PARALLEL); + position = 0; } diff --git a/src/modes/ctr/ctr.h b/src/modes/ctr/ctr.h index aa0db5761..3d509f02c 100644 --- a/src/modes/ctr/ctr.h +++ b/src/modes/ctr/ctr.h @@ -8,22 +8,33 @@ #ifndef BOTAN_COUNTER_MODE_H__ #define BOTAN_COUNTER_MODE_H__ -#include -#include +#include +#include namespace Botan { /* * CTR-BE Mode */ -class BOTAN_DLL CTR_BE : public BlockCipherMode +class BOTAN_DLL CTR_BE : public Keyed_Filter { public: + std::string name() const; + void set_iv(const InitializationVector&); + CTR_BE(BlockCipher*); CTR_BE(BlockCipher*, const SymmetricKey&, const InitializationVector&); + + ~CTR_BE(); private: + static const u32bit CTR_BLOCKS_PARALLEL = 8; + void write(const byte[], u32bit); void increment_counter(); + + BlockCipher* cipher; + SecureVector counter, enc_buffer; + u32bit position; }; } -- cgit v1.2.3 From 13d50de7b7675d798437c0d465acedd23e08b092 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 11 Aug 2009 17:12:00 +0000 Subject: Modify Keyed_Filter so it is a pure interface Modify ECB to use parallel encryption/decryption where possible Add toggles in build.h specifying how many blocks to process in parallel. Defaults to 8 blocks for all modes, which is sufficient that any likely parallelism can be extracted (via SIMD or concurrent execution) but not so much as to seem likely to cause cache problems (8*128 bits = 128 bytes, or two x86 cache lines) --- checks/validate.dat | 89 ++++++++++++++++++++ src/build-data/buildh.in | 6 ++ src/codec/openpgp/openpgp.cpp | 1 + src/filters/algo_filt.cpp | 10 +-- src/filters/basefilt.cpp | 21 ----- src/filters/basefilt.h | 33 -------- src/filters/filters.h | 42 +++++++++- src/filters/info.txt | 1 + src/filters/key_filt.h | 45 ++++++++++ src/modes/ctr/ctr.cpp | 30 ++++--- src/modes/ctr/ctr.h | 10 ++- src/modes/eax/eax.h | 2 +- src/modes/ecb/ecb.cpp | 191 ++++++++++++++++++++++++++++++++++-------- src/modes/ecb/ecb.h | 68 ++++++++------- src/modes/modebase.cpp | 2 +- src/modes/modebase.h | 9 +- src/modes/xts/xts.h | 8 +- 17 files changed, 418 insertions(+), 150 deletions(-) create mode 100644 src/filters/key_filt.h (limited to 'src') diff --git a/checks/validate.dat b/checks/validate.dat index b8566b62a..c4e0d0121 100644 --- a/checks/validate.dat +++ b/checks/validate.dat @@ -19472,7 +19472,20 @@ D261D6041824D259290EABD3E9132DB8:7E3B14847526572FF2AA5D7BD626B560:\ 01000000000000000000000000000000:07E5E5AD7097B849BADC2D5D803B7F6A:\ 0000000000000000000000000000000000000000000000000000000000000000 +1032547698BADCFEEFCDAB8967452301:D5BAA00A4BB9D8A7C981C8DC90D89D92:\ +FFEEDDCCBBAA99887766554433221100 +145F0B8B663176B95DCAB7E9DCD5CC24:1032547698BADCFEEFCDAB8967452301:\ +FFEEDDCCBBAA99887766554433221100 + +1032547698BADCFEEFCDAB8967452301:DA860842B720802BF404A4C71034879A:\ +8899AABBCCDDEEFFFFEEDDCCBBAA99887766554433221100 + +B2696BD0D98C17953E4239225D27202C:1032547698BADCFEEFCDAB8967452301:\ +8899AABBCCDDEEFFFFEEDDCCBBAA99887766554433221100 + +1032547698BADCFEEFCDAB8967452301:93DF9A3CAFE387BD999EEBE393A17FCA:\ +00112233445566778899AABBCCDDEEFFFFEEDDCCBBAA99887766554433221100 # Corrected test vectors, based on NIST's clarification of May 9, 2002 [Skipjack] @@ -22938,6 +22951,51 @@ B4ECC305C3DBD8E5:FBBEC8F5DBF4CEFD:1B5E23EBD915C1FEE59F57DD91AF7347 # The block cipher tests above are distinct from these ECB mode tests # for testing reasons. They could otherwise easily be CIPHER/ECB/NoPadding + +[AES/ECB/NoPadding] +D8F532538289EF7D06B506A4FD5BE9C9FD7A929E0FD917686D9520ED236A276D\ +69E63C821F9DE0BF23CF1D19C7374FD1C3139DE2E1BA4693C3E9D29D774C2FF4\ +69E63C821F9DE0BF23CF1D19C7374FD1C3139DE2E1BA4693C3E9D29D774C2FF4\ +D8F532538289EF7D06B506A4FD5BE9C9FD7A929E0FD917686D9520ED236A276D\ +D8F532538289EF7D06B506A4FD5BE9C9C3139DE2E1BA4693C3E9D29D774C2FF4:\ +FD7A929E0FD917686D9520ED236A276D69E63C821F9DE0BF23CF1D19C7374FD1\ +C3139DE2E1BA4693C3E9D29D774C2FF46BA2DCF84C0E7E4D75CB53AD11BA76D6\ +C3139DE2E1BA4693C3E9D29D774C2FF46BA2DCF84C0E7E4D75CB53AD11BA76D6\ +FD7A929E0FD917686D9520ED236A276D69E63C821F9DE0BF23CF1D19C7374FD1\ +FD7A929E0FD917686D9520ED236A276D6BA2DCF84C0E7E4D75CB53AD11BA76D6:\ +00010203050607080A0B0C0D0F101112 + +[Serpent/ECB/NoPadding] +D29D576FCEA3A3A7ED9099F29273D78E2D62A890CEA3A3A7ED9099F29273D78E\ +D29D576F315C5C58ED9099F29273D78E2D62A890315C5C58ED9099F29273D78E\ +D29D576FCEA3A3A7126F660D9273D78E2D62A890CEA3A3A7126F660D9273D78E\ +D29D576F315C5C58126F660D9273D78E2D62A890315C5C58126F660D9273D78E\ +D29D576FCEA3A3A7ED9099F26D8C28712D62A890CEA3A3A7ED9099F26D8C2871\ +D29D576F315C5C58ED9099F26D8C28712D62A890315C5C58ED9099F26D8C2871\ +D29D576FCEA3A3A7126F660D6D8C28712D62A890CEA3A3A7126F660D6D8C2871\ +D29D576F315C5C58126F660D6D8C28712D62A890315C5C58126F660D6D8C2871\ +AA26D561F567520E8AE47528C24C18D731A2193D9A97FED6922B17AAA6372B74\ +BE5DEBD559E303C9C92B174A5107BBFEB626D8F65EDCCDF3AEE475C8A1837722\ +41DDE7C1F1631F5FDED4F42746471BD651D238BA86176EFE39E4695AAEB73B52\ +EA5926CADAD8018962E469BA920CB8BF1EA9062E4D9CEDD5FAD4F4C7990367A4\ +B966E5C5D2277288C61B96A559CC84AFB6A6583C5AACFCD6212B0BD8AEF3C6A9\ +A11DDBD175639341052B0B384678D8D9352299B71DD880E29D1B96452DB86540:\ +B2288B968AE8B08648D1CE9606FD992D717EB02EB81A2E939D54ACA91087112D\ +0D809C5EE82F477EBA7B956DBB23463B0F0190D616F5294112FFB7884E8B37F9\ +41BA1B505386B7428B88338188F7E718A3348230BF5CFA552F88D22463D9703A\ +115351622E016BCA26918D17E13225F67EE4E3F2C46FE52ECBDA044C585717DC\ +563A8403FF5309D62370B1DCF5A11EDD2F7D73602B70CD2553E44C1D3F170126\ +155BBD9BE3A965B345E834718F651CEF6CC65E8C5C566E894817350F497816F1\ +EEFA51FC91FEBB6E9F8CB141CC0EB6AF3C6F8380CBD3C996167F2F0E90E71B75\ +6C87EB62A4975356B28DCBF6A64A0BD107206D48FE6DBE19D50314B90AC87B83\ +35706F9B26007071AD8105CFAA1C1E2FF7FEAE5CEC4D11477F24E6B200906870\ +3C0E29E2950F2AC2DACD63DEEB5C7EFA9FDB9F3B740563D5518287DC981FC9CB\ +46D4B5A5A86FEC08FE70D18297DCF51072DDBE038DA040EBB12C509F5940A212\ +DDEB59F02132BE4581FC23EABAA960D6341D9352E36DFD6E4EAF0F6F439BC8CE\ +73A9AB3164FF30350F2DC08E939A104D6DF0C2C28F8E2D44468A61278BB6B429\ +4DAE45AE0CAA032FC97CD4D8C57FB83BBA8AFCAE22070BC882D3A42B38A09E65:\ +00000000000000000000000000000000 + [DES/ECB/NoPadding] 059B5E0851CF143A:86A560F10EC6D85B:0113B970FD34F2CE 4E6F772069732074:3FA40E8A984D4815:0123456789ABCDEF @@ -24901,6 +24959,37 @@ E5C7CDDE872BF27C43E934008C389C0F683788499A7C05F662C16A27E4FCF277:\ 4E6F77206973207468652074696D6520666F7220616C6C20:\ 0123456789ABCDEF:1234567890ABCDEF +[Serpent/ECB/NoPadding] +B2288B968AE8B08648D1CE9606FD992D717EB02EB81A2E939D54ACA91087112D\ +0D809C5EE82F477EBA7B956DBB23463B0F0190D616F5294112FFB7884E8B37F9\ +41BA1B505386B7428B88338188F7E718A3348230BF5CFA552F88D22463D9703A\ +115351622E016BCA26918D17E13225F67EE4E3F2C46FE52ECBDA044C585717DC\ +563A8403FF5309D62370B1DCF5A11EDD2F7D73602B70CD2553E44C1D3F170126\ +155BBD9BE3A965B345E834718F651CEF6CC65E8C5C566E894817350F497816F1\ +EEFA51FC91FEBB6E9F8CB141CC0EB6AF3C6F8380CBD3C996167F2F0E90E71B75\ +6C87EB62A4975356B28DCBF6A64A0BD107206D48FE6DBE19D50314B90AC87B83\ +35706F9B26007071AD8105CFAA1C1E2FF7FEAE5CEC4D11477F24E6B200906870\ +3C0E29E2950F2AC2DACD63DEEB5C7EFA9FDB9F3B740563D5518287DC981FC9CB\ +46D4B5A5A86FEC08FE70D18297DCF51072DDBE038DA040EBB12C509F5940A212\ +DDEB59F02132BE4581FC23EABAA960D6341D9352E36DFD6E4EAF0F6F439BC8CE\ +73A9AB3164FF30350F2DC08E939A104D6DF0C2C28F8E2D44468A61278BB6B429\ +4DAE45AE0CAA032FC97CD4D8C57FB83BBA8AFCAE22070BC882D3A42B38A09E65:\ +D29D576FCEA3A3A7ED9099F29273D78E2D62A890CEA3A3A7ED9099F29273D78E\ +D29D576F315C5C58ED9099F29273D78E2D62A890315C5C58ED9099F29273D78E\ +D29D576FCEA3A3A7126F660D9273D78E2D62A890CEA3A3A7126F660D9273D78E\ +D29D576F315C5C58126F660D9273D78E2D62A890315C5C58126F660D9273D78E\ +D29D576FCEA3A3A7ED9099F26D8C28712D62A890CEA3A3A7ED9099F26D8C2871\ +D29D576F315C5C58ED9099F26D8C28712D62A890315C5C58ED9099F26D8C2871\ +D29D576FCEA3A3A7126F660D6D8C28712D62A890CEA3A3A7126F660D6D8C2871\ +D29D576F315C5C58126F660D6D8C28712D62A890315C5C58126F660D6D8C2871\ +AA26D561F567520E8AE47528C24C18D731A2193D9A97FED6922B17AAA6372B74\ +BE5DEBD559E303C9C92B174A5107BBFEB626D8F65EDCCDF3AEE475C8A1837722\ +41DDE7C1F1631F5FDED4F42746471BD651D238BA86176EFE39E4695AAEB73B52\ +EA5926CADAD8018962E469BA920CB8BF1EA9062E4D9CEDD5FAD4F4C7990367A4\ +B966E5C5D2277288C61B96A559CC84AFB6A6583C5AACFCD6212B0BD8AEF3C6A9\ +A11DDBD175639341052B0B384678D8D9352299B71DD880E29D1B96452DB86540:\ +00000000000000000000000000000000 + [RC5(8)/CBC/PKCS7] 7875DBF6738C64788F34C3C681C99695:FFFFFFFFFFFFFFFF:0102030405:0000000000000000 7875DBF6738C64787CB3F1DF34F948117FD1A023A5BBA217:\ diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index e4ab0f44b..bd900d412 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -22,6 +22,12 @@ #define BOTAN_KARAT_SQR_THRESHOLD 32 #define BOTAN_PRIVATE_KEY_OP_BLINDING_BITS 64 +/* Toggles for parallel block cipher mode processing */ +#define BOTAN_PARALLEL_BLOCKS_ECB 8 +#define BOTAN_PARALLEL_BLOCKS_CTR 8 +#define BOTAN_PARALLEL_BLOCKS_EAX 8 +#define BOTAN_PARALLEL_BLOCKS_XTS 8 + /* PK key consistency checking toggles */ #define BOTAN_PUBLIC_KEY_STRONG_CHECKS_ON_LOAD 1 #define BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_LOAD 1 diff --git a/src/codec/openpgp/openpgp.cpp b/src/codec/openpgp/openpgp.cpp index 7f9cf5f9c..bfba828af 100644 --- a/src/codec/openpgp/openpgp.cpp +++ b/src/codec/openpgp/openpgp.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include diff --git a/src/filters/algo_filt.cpp b/src/filters/algo_filt.cpp index 23f7a20cf..3268276a6 100644 --- a/src/filters/algo_filt.cpp +++ b/src/filters/algo_filt.cpp @@ -18,7 +18,7 @@ StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : buffer(DEFAULT_BUFFERSIZE) { Algorithm_Factory& af = global_state().algorithm_factory(); - base_ptr = cipher = af.make_stream_cipher(sc_name); + cipher = af.make_stream_cipher(sc_name); } /* @@ -27,7 +27,7 @@ StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : StreamCipher_Filter::StreamCipher_Filter(StreamCipher* stream_cipher) : buffer(DEFAULT_BUFFERSIZE) { - base_ptr = cipher = stream_cipher; + cipher = stream_cipher; } /* @@ -38,7 +38,7 @@ StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name, buffer(DEFAULT_BUFFERSIZE) { Algorithm_Factory& af = global_state().algorithm_factory(); - base_ptr = cipher = af.make_stream_cipher(sc_name); + cipher = af.make_stream_cipher(sc_name); cipher->set_key(key); } @@ -95,7 +95,7 @@ MAC_Filter::MAC_Filter(const std::string& mac_name, u32bit len) : OUTPUT_LENGTH(len) { Algorithm_Factory& af = global_state().algorithm_factory(); - base_ptr = mac = af.make_mac(mac_name); + mac = af.make_mac(mac_name); } /* @@ -105,7 +105,7 @@ MAC_Filter::MAC_Filter(const std::string& mac_name, const SymmetricKey& key, u32bit len) : OUTPUT_LENGTH(len) { Algorithm_Factory& af = global_state().algorithm_factory(); - base_ptr = mac = af.make_mac(mac_name); + mac = af.make_mac(mac_name); mac->set_key(key); } diff --git a/src/filters/basefilt.cpp b/src/filters/basefilt.cpp index 02dbd8a73..c91a5aa62 100644 --- a/src/filters/basefilt.cpp +++ b/src/filters/basefilt.cpp @@ -50,25 +50,4 @@ Fork::Fork(Filter* filters[], u32bit count) set_next(filters, count); } -/* -* Set the algorithm key -*/ -void Keyed_Filter::set_key(const SymmetricKey& key) - { - if(base_ptr) - base_ptr->set_key(key); - else - throw Invalid_State("Keyed_Filter::set_key: No base algorithm set"); - } - -/* -* Check if a keylength is valid -*/ -bool Keyed_Filter::valid_keylength(u32bit n) const - { - if(base_ptr) - return base_ptr->valid_keylength(n); - throw Invalid_State("Keyed_Filter::valid_keylength: No base algorithm set"); - } - } diff --git a/src/filters/basefilt.h b/src/filters/basefilt.h index 75625abb0..348ad6fd3 100644 --- a/src/filters/basefilt.h +++ b/src/filters/basefilt.h @@ -9,7 +9,6 @@ #define BOTAN_BASEFILT_H__ #include -#include namespace Botan { @@ -62,38 +61,6 @@ class BOTAN_DLL Fork : public Fanout_Filter Fork(Filter* filter_arr[], u32bit length); }; -/** -* This class represents keyed filters, i.e. filters that have to be -* fed with a key in order to function. -*/ -class BOTAN_DLL Keyed_Filter : public Filter - { - public: - - /** - * Set the key of this filter. - * @param key the key to set - */ - virtual void set_key(const SymmetricKey& key); - - /** - * Set the initialization vector of this filter. - * @param iv the initialization vector to set - */ - virtual void set_iv(const InitializationVector&) {} - - /** - * Check whether a key length is valid for this filter. - * @param length the key length to be checked for validity - * @return true if the key length is valid, false otherwise - */ - virtual bool valid_keylength(u32bit length) const; - - Keyed_Filter() { base_ptr = 0; } - protected: - SymmetricAlgorithm* base_ptr; - }; - } #endif diff --git a/src/filters/filters.h b/src/filters/filters.h index 725651f7d..26de6e63c 100644 --- a/src/filters/filters.h +++ b/src/filters/filters.h @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include @@ -35,6 +35,13 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter { public: + /** + * Write input data + * @param input data + * @param input_len length of input in bytes + */ + void write(const byte input[], u32bit input_len); + /** * Seek in the stream. * @param position the position to seek ahead @@ -53,7 +60,20 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter * @param iv the initialization vector to set */ void set_iv(const InitializationVector& iv); - void write(const byte[], u32bit); + + /** + * Set the key of this filter. + * @param key the key to set + */ + void set_key(const SymmetricKey& key) { cipher->set_key(key); } + + /** + * Check whether a key length is valid for this filter. + * @param length the key length to be checked for validity + * @return true if the key length is valid, false otherwise + */ + bool valid_keylength(u32bit length) const + { return cipher->valid_keylength(length); } /** * Construct a stream cipher filter. @@ -125,6 +145,20 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter void write(const byte input[], u32bit len) { mac->update(input, len); } void end_msg(); + /** + * Set the key of this filter. + * @param key the key to set + */ + void set_key(const SymmetricKey& key) { mac->set_key(key); } + + /** + * Check whether a key length is valid for this filter. + * @param length the key length to be checked for validity + * @return true if the key length is valid, false otherwise + */ + bool valid_keylength(u32bit length) const + { return mac->valid_keylength(length); } + /** * Construct a MAC filter. The MAC key will be left empty. * @param mac the MAC to use @@ -136,7 +170,7 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter MAC_Filter(MessageAuthenticationCode* mac_obj, u32bit out_len = 0) : OUTPUT_LENGTH(out_len) { - base_ptr = mac = mac_obj; + mac = mac_obj; } /** @@ -152,7 +186,7 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter const SymmetricKey& key, u32bit out_len = 0) : OUTPUT_LENGTH(out_len) { - base_ptr = mac = mac_obj; + mac = mac_obj; mac->set_key(key); } diff --git a/src/filters/info.txt b/src/filters/info.txt index 79a92a9c5..fb8108659 100644 --- a/src/filters/info.txt +++ b/src/filters/info.txt @@ -17,6 +17,7 @@ data_src.h filter.cpp filter.h filters.h +key_filt.h out_buf.cpp out_buf.h pbe.h diff --git a/src/filters/key_filt.h b/src/filters/key_filt.h new file mode 100644 index 000000000..36af91f88 --- /dev/null +++ b/src/filters/key_filt.h @@ -0,0 +1,45 @@ +/* +* Keyed_Filter +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_KEYED_FILTER_H__ +#define BOTAN_KEYED_FILTER_H__ + +#include +#include + +namespace Botan { + +/** +* This class represents keyed filters, i.e. filters that have to be +* fed with a key in order to function. +*/ +class BOTAN_DLL Keyed_Filter : public Filter + { + public: + /** + * Set the key of this filter. + * @param key the key to set + */ + virtual void set_key(const SymmetricKey& key) = 0; + + /** + * Set the initialization vector of this filter. + * @param iv the initialization vector to set + */ + virtual void set_iv(const InitializationVector&) {} + + /** + * Check whether a key length is valid for this filter. + * @param length the key length to be checked for validity + * @return true if the key length is valid, false otherwise + */ + virtual bool valid_keylength(u32bit length) const = 0; + }; + +} + +#endif diff --git a/src/modes/ctr/ctr.cpp b/src/modes/ctr/ctr.cpp index 5c27ca63c..a3476c474 100644 --- a/src/modes/ctr/ctr.cpp +++ b/src/modes/ctr/ctr.cpp @@ -11,16 +11,21 @@ namespace Botan { +namespace { + +const u32bit PARALLEL_BLOCKS = BOTAN_PARALLEL_BLOCKS_CTR; + +} + /* * CTR-BE Constructor */ CTR_BE::CTR_BE(BlockCipher* ciph) : cipher(ciph) { - base_ptr = cipher; position = 0; - counter.create(ciph->BLOCK_SIZE * CTR_BLOCKS_PARALLEL); - enc_buffer.create(ciph->BLOCK_SIZE * CTR_BLOCKS_PARALLEL); + counter.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS); + enc_buffer.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS); } /* @@ -30,13 +35,12 @@ CTR_BE::CTR_BE(BlockCipher* ciph, const SymmetricKey& key, const InitializationVector& iv) : cipher(ciph) { - base_ptr = cipher; position = 0; - counter.create(ciph->BLOCK_SIZE * CTR_BLOCKS_PARALLEL); - enc_buffer.create(ciph->BLOCK_SIZE * CTR_BLOCKS_PARALLEL); + counter.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS); + enc_buffer.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS); - set_key(key); + cipher->set_key(key); set_iv(iv); } @@ -67,7 +71,7 @@ void CTR_BE::set_iv(const InitializationVector& iv) enc_buffer.clear(); position = 0; - for(u32bit i = 0; i != CTR_BLOCKS_PARALLEL; ++i) + for(u32bit i = 0; i != PARALLEL_BLOCKS; ++i) { counter.copy(i*cipher->BLOCK_SIZE, iv.begin(), iv.length()); @@ -78,7 +82,7 @@ void CTR_BE::set_iv(const InitializationVector& iv) break; } - cipher->encrypt_n(counter, enc_buffer, CTR_BLOCKS_PARALLEL); + cipher->encrypt_n(counter, enc_buffer, PARALLEL_BLOCKS); } /* @@ -116,24 +120,24 @@ void CTR_BE::write(const byte input[], u32bit length) */ void CTR_BE::increment_counter() { - for(u32bit i = 0; i != CTR_BLOCKS_PARALLEL; ++i) + for(u32bit i = 0; i != PARALLEL_BLOCKS; ++i) { // FIXME: Can do it in a single loop /* for(u32bit j = 1; j != cipher->BLOCK_SIZE; ++j) { byte carry = 0; - byte z = counter[(i+1)*cipher->BLOCK_SIZE-1] + CTR_BLOCKS_PARALLEL; + byte z = counter[(i+1)*cipher->BLOCK_SIZE-1] + PARALLEL_BLOCKS; if( */ - for(u32bit j = 0; j != CTR_BLOCKS_PARALLEL; ++j) + for(u32bit j = 0; j != PARALLEL_BLOCKS; ++j) for(s32bit k = cipher->BLOCK_SIZE - 1; k >= 0; --k) if(++counter[i*cipher->BLOCK_SIZE+k]) break; } - cipher->encrypt_n(counter, enc_buffer, CTR_BLOCKS_PARALLEL); + cipher->encrypt_n(counter, enc_buffer, PARALLEL_BLOCKS); position = 0; } diff --git a/src/modes/ctr/ctr.h b/src/modes/ctr/ctr.h index 3d509f02c..1948ffe48 100644 --- a/src/modes/ctr/ctr.h +++ b/src/modes/ctr/ctr.h @@ -8,7 +8,7 @@ #ifndef BOTAN_COUNTER_MODE_H__ #define BOTAN_COUNTER_MODE_H__ -#include +#include #include namespace Botan { @@ -20,15 +20,19 @@ class BOTAN_DLL CTR_BE : public Keyed_Filter { public: std::string name() const; + void set_iv(const InitializationVector&); + void set_key(const SymmetricKey& key) { cipher->set_key(key); } + + bool valid_keylength(u32bit key_len) const + { return cipher->valid_keylength(key_len); } + CTR_BE(BlockCipher*); CTR_BE(BlockCipher*, const SymmetricKey&, const InitializationVector&); ~CTR_BE(); private: - static const u32bit CTR_BLOCKS_PARALLEL = 8; - void write(const byte[], u32bit); void increment_counter(); diff --git a/src/modes/eax/eax.h b/src/modes/eax/eax.h index 1bb2e510d..f569f2ede 100644 --- a/src/modes/eax/eax.h +++ b/src/modes/eax/eax.h @@ -8,7 +8,7 @@ #ifndef BOTAN_EAX_H__ #define BOTAN_EAX_H__ -#include +#include #include #include diff --git a/src/modes/ecb/ecb.cpp b/src/modes/ecb/ecb.cpp index 8da0a4802..988a8b3f2 100644 --- a/src/modes/ecb/ecb.cpp +++ b/src/modes/ecb/ecb.cpp @@ -9,22 +9,60 @@ namespace Botan { +namespace { + +const u32bit PARALLEL_BLOCKS = BOTAN_PARALLEL_BLOCKS_ECB; + +} + /* -* Verify the IV is not set +* ECB_Encryption Constructor */ -bool ECB::valid_iv_size(u32bit iv_size) const +ECB_Encryption::ECB_Encryption(BlockCipher* ciph, + BlockCipherModePaddingMethod* pad) { - if(iv_size == 0) - return true; - return false; + cipher = ciph; + padder = pad; + + plaintext.create(cipher->BLOCK_SIZE); + ciphertext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS); + + position = 0; + } + +/* +* ECB_Encryption Constructor +*/ +ECB_Encryption::ECB_Encryption(BlockCipher* ciph, + BlockCipherModePaddingMethod* pad, + const SymmetricKey& key) + { + cipher = ciph; + padder = pad; + + plaintext.create(cipher->BLOCK_SIZE); + ciphertext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS); + + position = 0; + + cipher->set_key(key); + } + +/* +* ECB_Encryption Destructor +*/ +ECB_Encryption::~ECB_Encryption() + { + delete cipher; + delete padder; } /* * Return an ECB mode name */ -std::string ECB::name() const +std::string ECB_Encryption::name() const { - return (cipher->name() + "/" + mode_name + "/" + padder->name()); + return (cipher->name() + "/ECB/" + padder->name()); } /* @@ -32,23 +70,34 @@ std::string ECB::name() const */ void ECB_Encryption::write(const byte input[], u32bit length) { - buffer.copy(position, input, length); - if(position + length >= BLOCK_SIZE) + const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; + + if(position) { - cipher->encrypt(buffer); - send(buffer, BLOCK_SIZE); - input += (BLOCK_SIZE - position); - length -= (BLOCK_SIZE - position); - while(length >= BLOCK_SIZE) + plaintext.copy(position, input, length); + + if(position + length >= BLOCK_SIZE) { - cipher->encrypt(input, buffer); - send(buffer, BLOCK_SIZE); - input += BLOCK_SIZE; - length -= BLOCK_SIZE; + cipher->encrypt(plaintext, ciphertext); + send(ciphertext, BLOCK_SIZE); + input += (BLOCK_SIZE - position); + length -= (BLOCK_SIZE - position); + position = 0; } - buffer.copy(input, length); - position = 0; } + + while(length >= BLOCK_SIZE) + { + const u32bit to_proc = + std::min(length, ciphertext.size()) / BLOCK_SIZE; + + cipher->encrypt_n(input, ciphertext, to_proc); + send(ciphertext, to_proc * BLOCK_SIZE); + input += to_proc * BLOCK_SIZE; + length -= to_proc * BLOCK_SIZE; + } + + plaintext.copy(position, input, length); position += length; } @@ -57,6 +106,8 @@ void ECB_Encryption::write(const byte input[], u32bit length) */ void ECB_Encryption::end_msg() { + const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; + SecureVector padding(BLOCK_SIZE); padder->pad(padding, padding.size(), position); write(padding, padder->pad_bytes(BLOCK_SIZE, position)); @@ -64,28 +115,94 @@ void ECB_Encryption::end_msg() throw Encoding_Error(name() + ": Did not pad to full blocksize"); } +/* +* ECB_Decryption Constructor +*/ +ECB_Decryption::ECB_Decryption(BlockCipher* ciph, + BlockCipherModePaddingMethod* pad) + { + cipher = ciph; + padder = pad; + + ciphertext.create(cipher->BLOCK_SIZE); + plaintext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS); + + position = 0; + } + +/* +* ECB_Decryption Constructor +*/ +ECB_Decryption::ECB_Decryption(BlockCipher* ciph, + BlockCipherModePaddingMethod* pad, + const SymmetricKey& key) + { + cipher = ciph; + padder = pad; + + ciphertext.create(cipher->BLOCK_SIZE); + plaintext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS); + + position = 0; + + cipher->set_key(key); + } + +/* +* ECB_Decryption Destructor +*/ +ECB_Decryption::~ECB_Decryption() + { + delete cipher; + delete padder; + } + +/* +* Return an ECB mode name +*/ +std::string ECB_Decryption::name() const + { + return (cipher->name() + "/ECB/" + padder->name()); + } + /* * Decrypt in ECB mode */ void ECB_Decryption::write(const byte input[], u32bit length) { - buffer.copy(position, input, length); - if(position + length > BLOCK_SIZE) + const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; + + if(position) { - cipher->decrypt(buffer); - send(buffer, BLOCK_SIZE); - input += (BLOCK_SIZE - position); - length -= (BLOCK_SIZE - position); - while(length > BLOCK_SIZE) + ciphertext.copy(position, input, length); + + if(position + length > BLOCK_SIZE) { - cipher->decrypt(input, buffer); - send(buffer, BLOCK_SIZE); - input += BLOCK_SIZE; - length -= BLOCK_SIZE; + cipher->decrypt(ciphertext, plaintext); + send(plaintext, BLOCK_SIZE); + input += (BLOCK_SIZE - position); + length -= (BLOCK_SIZE - position); + position = 0; } - buffer.copy(input, length); - position = 0; } + + while(length > BLOCK_SIZE) + { + /* Always leave at least 1 byte left over, to ensure that (as long + as the input message actually is a multiple of the block size) + we will have the full final block left over in end_msg so as + to remove the padding + */ + const u32bit to_proc = + std::min(length - 1, plaintext.size()) / BLOCK_SIZE; + + cipher->decrypt_n(input, plaintext, to_proc); + send(plaintext, to_proc * BLOCK_SIZE); + input += to_proc * BLOCK_SIZE; + length -= to_proc * BLOCK_SIZE; + } + + ciphertext.copy(position, input, length); position += length; } @@ -94,11 +211,11 @@ void ECB_Decryption::write(const byte input[], u32bit length) */ void ECB_Decryption::end_msg() { - if(position != BLOCK_SIZE) + if(position != cipher->BLOCK_SIZE) throw Decoding_Error(name()); - cipher->decrypt(buffer); - send(buffer, padder->unpad(buffer, BLOCK_SIZE)); - state = buffer; + + cipher->decrypt(ciphertext); + send(ciphertext, padder->unpad(ciphertext, cipher->BLOCK_SIZE)); position = 0; } diff --git a/src/modes/ecb/ecb.h b/src/modes/ecb/ecb.h index 5230f9b14..ff9ea9635 100644 --- a/src/modes/ecb/ecb.h +++ b/src/modes/ecb/ecb.h @@ -1,6 +1,6 @@ /* * ECB Mode -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -8,64 +8,74 @@ #ifndef BOTAN_ECB_H__ #define BOTAN_ECB_H__ -#include -#include +#include #include +#include -namespace Botan { - -/* -* ECB -*/ -class BOTAN_DLL ECB : public BlockCipherMode - { - protected: - ECB(BlockCipher* ciph, BlockCipherModePaddingMethod* pad) : - BlockCipherMode(ciph, "ECB", 0), padder(pad) {} - ~ECB() { delete padder; } +#include - std::string name() const; - BlockCipherModePaddingMethod* padder; - private: - bool valid_iv_size(u32bit) const; - }; +namespace Botan { /* * ECB Encryption */ -class BOTAN_DLL ECB_Encryption : public ECB +class BOTAN_DLL ECB_Encryption : public Keyed_Filter { public: + std::string name() const; + + void set_key(const SymmetricKey& key) { cipher->set_key(key); } + + bool valid_keylength(u32bit key_len) const + { return cipher->valid_keylength(key_len); } + ECB_Encryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad) : - ECB(ciph, pad) {} + BlockCipherModePaddingMethod* pad); ECB_Encryption(BlockCipher* ciph, BlockCipherModePaddingMethod* pad, - const SymmetricKey& key) : - ECB(ciph, pad) { set_key(key); } + const SymmetricKey& key); + + ~ECB_Encryption(); private: void write(const byte[], u32bit); void end_msg(); + + BlockCipher* cipher; + BlockCipherModePaddingMethod* padder; + SecureVector plaintext, ciphertext; + u32bit position; }; /* * ECB Decryption */ -class BOTAN_DLL ECB_Decryption : public ECB +class BOTAN_DLL ECB_Decryption : public Keyed_Filter { public: + std::string name() const; + + void set_key(const SymmetricKey& key) { cipher->set_key(key); } + + bool valid_keylength(u32bit key_len) const + { return cipher->valid_keylength(key_len); } + ECB_Decryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad) : - ECB(ciph, pad) {} + BlockCipherModePaddingMethod* pad); ECB_Decryption(BlockCipher* ciph, BlockCipherModePaddingMethod* pad, - const SymmetricKey& key) : - ECB(ciph, pad) { set_key(key); } + const SymmetricKey& key); + + ~ECB_Decryption(); private: void write(const byte[], u32bit); void end_msg(); + + BlockCipher* cipher; + BlockCipherModePaddingMethod* padder; + SecureVector plaintext, ciphertext; + u32bit position; }; } diff --git a/src/modes/modebase.cpp b/src/modes/modebase.cpp index 8293acc54..b048862a4 100644 --- a/src/modes/modebase.cpp +++ b/src/modes/modebase.cpp @@ -19,7 +19,7 @@ BlockCipherMode::BlockCipherMode(BlockCipher* cipher_ptr, BLOCK_SIZE(cipher_ptr->BLOCK_SIZE), BUFFER_SIZE(buf_mult * BLOCK_SIZE), IV_METHOD(iv_meth), mode_name(cipher_mode_name) { - base_ptr = cipher = cipher_ptr; + cipher = cipher_ptr; buffer.create(BUFFER_SIZE); state.create(iv_size); position = 0; diff --git a/src/modes/modebase.h b/src/modes/modebase.h index 173fde58c..4a15524b6 100644 --- a/src/modes/modebase.h +++ b/src/modes/modebase.h @@ -8,7 +8,7 @@ #ifndef BOTAN_MODEBASE_H__ #define BOTAN_MODEBASE_H__ -#include +#include #include namespace Botan { @@ -21,12 +21,17 @@ class BOTAN_DLL BlockCipherMode : public Keyed_Filter public: std::string name() const; + void set_iv(const InitializationVector&); + void set_key(const SymmetricKey& key) { cipher->set_key(key); } + + bool valid_keylength(u32bit key_len) const + { return cipher->valid_keylength(key_len); } + BlockCipherMode(BlockCipher*, const std::string&, u32bit, u32bit = 0, u32bit = 1); virtual ~BlockCipherMode() { delete cipher; } protected: - void set_iv(const InitializationVector&); const u32bit BLOCK_SIZE, BUFFER_SIZE, IV_METHOD; const std::string mode_name; BlockCipher* cipher; diff --git a/src/modes/xts/xts.h b/src/modes/xts/xts.h index 01558175b..9badd3666 100644 --- a/src/modes/xts/xts.h +++ b/src/modes/xts/xts.h @@ -8,7 +8,7 @@ #ifndef BOTAN_XTS_H__ #define BOTAN_XTS_H__ -#include +#include #include namespace Botan { @@ -22,6 +22,9 @@ class BOTAN_DLL XTS_Encryption : public Keyed_Filter void set_key(const SymmetricKey& key); void set_iv(const InitializationVector& iv); + bool valid_keylength(u32bit key_len) const + { return cipher->valid_keylength(key_len); } + std::string name() const; XTS_Encryption(BlockCipher* ciph); @@ -52,6 +55,9 @@ class BOTAN_DLL XTS_Decryption : public Keyed_Filter void set_key(const SymmetricKey& key); void set_iv(const InitializationVector& iv); + bool valid_keylength(u32bit key_len) const + { return cipher->valid_keylength(key_len); } + std::string name() const; XTS_Decryption(BlockCipher* ciph); -- cgit v1.2.3 From c8c3d7f6eecd753aa87a882b1458346682e606db Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 11 Aug 2009 19:34:50 +0000 Subject: Make encrypt_n public for all BlockCipher implementations - unlike the enc/dec functions it replaces, these are public interfaces. Add the first bits of a SSE2 implementation of Serpent. Currently incomplete. --- src/block/aes/aes.h | 6 +- src/block/blowfish/blowfish.h | 6 +- src/block/cast/cast128.h | 6 +- src/block/cast/cast256.h | 6 +- src/block/des/des.h | 12 ++- src/block/des/desx.h | 6 +- src/block/gost_28147/gost_28147.h | 5 +- src/block/idea/idea.h | 6 +- src/block/kasumi/kasumi.h | 5 +- src/block/lion/lion.h | 5 +- src/block/lubyrack/lubyrack.h | 6 +- src/block/mars/mars.h | 6 +- src/block/misty1/misty1.h | 6 +- src/block/noekeon/noekeon.h | 6 +- src/block/rc2/rc2.h | 6 +- src/block/rc5/rc5.h | 6 +- src/block/rc6/rc6.h | 6 +- src/block/safer/safer_sk.h | 7 +- src/block/seed/seed.h | 6 +- src/block/serpent/serpent.h | 5 +- src/block/serpent_ia32/serp_ia32.h | 5 +- src/block/serpent_sse2/info.txt | 27 ++++++ src/block/serpent_sse2/serp_sse2.cpp | 170 +++++++++++++++++++++++++++++++++++ src/block/serpent_sse2/serp_sse2.h | 29 ++++++ src/block/skipjack/skipjack.h | 7 +- src/block/square/square.h | 6 +- src/block/tea/tea.h | 6 +- src/block/twofish/twofish.h | 6 +- src/block/xtea/xtea.h | 6 +- src/engine/sse2_eng/eng_sse2.cpp | 23 ++++- src/engine/sse2_eng/eng_sse2.h | 5 +- 31 files changed, 355 insertions(+), 58 deletions(-) create mode 100644 src/block/serpent_sse2/info.txt create mode 100644 src/block/serpent_sse2/serp_sse2.cpp create mode 100644 src/block/serpent_sse2/serp_sse2.h (limited to 'src') diff --git a/src/block/aes/aes.h b/src/block/aes/aes.h index 940e11a48..768bb09e7 100644 --- a/src/block/aes/aes.h +++ b/src/block/aes/aes.h @@ -18,14 +18,16 @@ namespace Botan { class BOTAN_DLL AES : 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; + void clear() throw(); std::string name() const { return "AES"; } BlockCipher* clone() const { return new AES; } + AES() : BlockCipher(16, 16, 32, 8) { ROUNDS = 14; } AES(u32bit); private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); static u32bit S(u32bit); diff --git a/src/block/blowfish/blowfish.h b/src/block/blowfish/blowfish.h index 3623c2087..345c1ce49 100644 --- a/src/block/blowfish/blowfish.h +++ b/src/block/blowfish/blowfish.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL Blowfish : 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; + void clear() throw(); std::string name() const { return "Blowfish"; } BlockCipher* clone() const { return new Blowfish; } + Blowfish() : BlockCipher(8, 1, 56) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); void generate_sbox(u32bit[], u32bit, u32bit&, u32bit&) const; diff --git a/src/block/cast/cast128.h b/src/block/cast/cast128.h index 092ee824b..864a4e47e 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); static void key_schedule(u32bit[16], u32bit[4]); diff --git a/src/block/cast/cast256.h b/src/block/cast/cast256.h index ea80df65d..1be7fa9cf 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); static const u32bit KEY_MASK[192]; diff --git a/src/block/des/des.h b/src/block/des/des.h index 39d1ac404..856aaf60c 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { round_key.clear(); } std::string name() const { return "DES"; } BlockCipher* clone() const { return new DES; } + DES() : BlockCipher(8, 8) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer round_key; @@ -36,13 +38,15 @@ class BOTAN_DLL DES : public BlockCipher class BOTAN_DLL TripleDES : 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; + void clear() throw() { round_key.clear(); } std::string name() const { return "TripleDES"; } BlockCipher* clone() const { return new TripleDES; } + TripleDES() : BlockCipher(8, 16, 24, 8) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer round_key; diff --git a/src/block/des/desx.h b/src/block/des/desx.h index d71335071..d22895296 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { des.clear(); K1.clear(); K2.clear(); } std::string name() const { return "DESX"; } BlockCipher* clone() const { return new DESX; } + DESX() : BlockCipher(8, 24) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer K1, K2; DES des; diff --git a/src/block/gost_28147/gost_28147.h b/src/block/gost_28147/gost_28147.h index 825e106a2..18c1d0a29 100644 --- a/src/block/gost_28147/gost_28147.h +++ b/src/block/gost_28147/gost_28147.h @@ -44,6 +44,9 @@ class GOST_28147_89_Params class BOTAN_DLL GOST_28147_89 : 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; + void clear() throw() { EK.clear(); } std::string name() const { return "GOST-28147-89"; } @@ -54,8 +57,6 @@ class BOTAN_DLL GOST_28147_89 : public BlockCipher GOST_28147_89(const SecureBuffer& other_SBOX) : BlockCipher(8, 32), SBOX(other_SBOX) {} - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer SBOX; diff --git a/src/block/idea/idea.h b/src/block/idea/idea.h index a3384b667..59484531b 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { EK.clear(); DK.clear(); } std::string name() const { return "IDEA"; } BlockCipher* clone() const { return new IDEA; } + IDEA() : BlockCipher(8, 16) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer EK, DK; }; diff --git a/src/block/kasumi/kasumi.h b/src/block/kasumi/kasumi.h index 3b18e675b..0f5a5d182 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { EK.clear(); } std::string name() const { return "KASUMI"; } BlockCipher* clone() const { return new KASUMI; } KASUMI() : BlockCipher(8, 16) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer EK; diff --git a/src/block/lion/lion.h b/src/block/lion/lion.h index d9f933846..d421771d6 100644 --- a/src/block/lion/lion.h +++ b/src/block/lion/lion.h @@ -20,6 +20,9 @@ namespace Botan { class BOTAN_DLL Lion : 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; + void clear() throw(); std::string name() const; BlockCipher* clone() const; @@ -27,8 +30,6 @@ class BOTAN_DLL Lion : public BlockCipher Lion(HashFunction*, StreamCipher*, u32bit); ~Lion() { delete hash; delete cipher; } private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); const u32bit LEFT_SIZE, RIGHT_SIZE; diff --git a/src/block/lubyrack/lubyrack.h b/src/block/lubyrack/lubyrack.h index 1e83748a6..940b34603 100644 --- a/src/block/lubyrack/lubyrack.h +++ b/src/block/lubyrack/lubyrack.h @@ -19,6 +19,9 @@ namespace Botan { class BOTAN_DLL LubyRackoff : 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; + void clear() throw(); std::string name() const; BlockCipher* clone() const; @@ -26,9 +29,8 @@ class BOTAN_DLL LubyRackoff : public BlockCipher LubyRackoff(HashFunction* hash); ~LubyRackoff() { delete hash; } private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); + HashFunction* hash; SecureVector K1, K2; }; diff --git a/src/block/mars/mars.h b/src/block/mars/mars.h index b3d74b179..7d0bfe4fa 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { EK.clear(); } std::string name() const { return "MARS"; } BlockCipher* clone() const { return new MARS; } + MARS() : BlockCipher(16, 16, 32, 4) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); void encrypt_round(u32bit&, u32bit&, u32bit&, u32bit&, u32bit) const; diff --git a/src/block/misty1/misty1.h b/src/block/misty1/misty1.h index 14b7c8e45..8db6881de 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { EK.clear(); DK.clear(); } std::string name() const { return "MISTY1"; } BlockCipher* clone() const { return new MISTY1; } + MISTY1(u32bit = 8); private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer EK, DK; diff --git a/src/block/noekeon/noekeon.h b/src/block/noekeon/noekeon.h index b4f3980d7..37b24fb7d 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw(); std::string name() const { return "Noekeon"; } BlockCipher* clone() const { return new Noekeon; } + Noekeon() : BlockCipher(16, 16) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); static const byte RC[17]; diff --git a/src/block/rc2/rc2.h b/src/block/rc2/rc2.h index 0d94d69a2..db623b385 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(); } std::string name() const { return "RC2"; } BlockCipher* clone() const { return new RC2; } + RC2() : BlockCipher(8, 1, 32) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer K; diff --git a/src/block/rc5/rc5.h b/src/block/rc5/rc5.h index 1816994dc..ff9204710 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { S.clear(); } std::string name() const; BlockCipher* clone() const { return new RC5(ROUNDS); } + RC5(u32bit); private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureVector S; const u32bit ROUNDS; diff --git a/src/block/rc6/rc6.h b/src/block/rc6/rc6.h index f634ebcd9..5171006f5 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { S.clear(); } std::string name() const { return "RC6"; } BlockCipher* clone() const { return new RC6; } + RC6() : BlockCipher(16, 1, 32) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer S; diff --git a/src/block/safer/safer_sk.h b/src/block/safer/safer_sk.h index ae3d4f9a8..4d17bba51 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { EK.clear(); } std::string name() const; BlockCipher* clone() const; + SAFER_SK(u32bit); private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) 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 EK; const u32bit ROUNDS; }; diff --git a/src/block/seed/seed.h b/src/block/seed/seed.h index 0c9c2c8af..5a5a512e7 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { K.clear(); } std::string name() const { return "SEED"; } BlockCipher* clone() const { return new SEED; } + SEED() : BlockCipher(16, 16) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); class G_FUNC diff --git a/src/block/serpent/serpent.h b/src/block/serpent/serpent.h index 9c9fb59f2..d919c3008 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { round_key.clear(); } std::string name() const { return "Serpent"; } BlockCipher* clone() const { return new Serpent; } Serpent() : BlockCipher(16, 16, 32, 8) {} protected: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer round_key; diff --git a/src/block/serpent_ia32/serp_ia32.h b/src/block/serpent_ia32/serp_ia32.h index 2b4a95d3d..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: - BlockCipher* clone() const { return new Serpent_IA32; } - private: 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 key_schedule(const byte[], u32bit); }; diff --git a/src/block/serpent_sse2/info.txt b/src/block/serpent_sse2/info.txt new file mode 100644 index 000000000..ad8323f53 --- /dev/null +++ b/src/block/serpent_sse2/info.txt @@ -0,0 +1,27 @@ +realname "Serpent (SSE2)" + +define SERPENT_SSE2 + +load_on auto + + +serp_sse2.cpp +serp_sse2.h + + + +pentium-m +pentium4 +prescott +amd64 + + + +gcc +icc + + + +serpent +sse2_eng + diff --git a/src/block/serpent_sse2/serp_sse2.cpp b/src/block/serpent_sse2/serp_sse2.cpp new file mode 100644 index 000000000..759f3e1d6 --- /dev/null +++ b/src/block/serpent_sse2/serp_sse2.cpp @@ -0,0 +1,170 @@ +/* +* Serpent (SSE2) +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include + +namespace Botan { + +namespace { + +#define SBoxE1(b0, b1, b2, b3, b4) \ + do { \ + b3 = _mm_xor_si128(b3, b0); \ + b4 = b1; \ + b1 = _mm_and_si128(b1, b3); \ + b4 = _mm_xor_si128(b4, b2); \ + b1 = _mm_xor_si128(b1, b0); \ + b0 = _mm_or_si128(b0, b3); \ + b0 = _mm_xor_si128(b0, b4); \ + b4 = _mm_xor_si128(b4, b3); \ + b3 = _mm_xor_si128(b3, b2); \ + b2 = _mm_or_si128(b2, b1); \ + b2 = _mm_xor_si128(b2, b4); \ + b4 = _mm_andnot_si128(b4, all_ones); \ + b4 = _mm_or_si128(b4, b1); \ + b1 = _mm_xor_si128(b1, b3); \ + b1 = _mm_xor_si128(b1, b4); \ + b3 = _mm_or_si128(b3, b0); \ + b1 = _mm_xor_si128(b1, b3); \ + b4 = _mm_xor_si128(b4, b3); \ + b3 = b0; b0 = b1; b1 = b4; \ + } while(0); + +#define rotate_left_m128(vec, rot) \ + _mm_or_si128(_mm_slli_epi32(vec, rot), _mm_srli_epi32(vec, 32-rot)) + +#define key_xor(round, b0, b1, b2, b3) \ + do { \ + __m128i key = _mm_loadu_si128(keys + round); \ + b0 = _mm_xor_si128(b0, _mm_shuffle_epi32(key, _MM_SHUFFLE(0,0,0,0))); \ + b1 = _mm_xor_si128(b1, _mm_shuffle_epi32(key, _MM_SHUFFLE(1,1,1,1))); \ + b2 = _mm_xor_si128(b2, _mm_shuffle_epi32(key, _MM_SHUFFLE(2,2,2,2))); \ + b3 = _mm_xor_si128(b3, _mm_shuffle_epi32(key, _MM_SHUFFLE(3,3,3,3))); \ + } while(0); + +#define transform(b0, b1, b2, b3) \ + do \ + { \ + b0 = rotate_left_m128(b0, 13); \ + b2 = rotate_left_m128(b2, 3); \ + b1 = _mm_xor_si128(b1, _mm_xor_si128(b0, b2)); \ + b3 = _mm_xor_si128(b3, _mm_xor_si128(b2, _mm_slli_epi32(b0, 3))); \ + b1 = rotate_left_m128(b1, 1); \ + b3 = rotate_left_m128(b3, 7); \ + b0 = _mm_xor_si128(b0, _mm_xor_si128(b1, b3)); \ + b2 = _mm_xor_si128(b2, _mm_xor_si128(b3, _mm_slli_epi32(b1, 7))); \ + b0 = rotate_left_m128(b0, 5); \ + b2 = rotate_left_m128(b2, 22); \ + } while(0); + +void print_simd(const char* name, __m128i vec) + { + union { __m128i v; int32_t ints[4]; } u = { vec }; + + printf("%s: ", name); + for(u32bit i = 0; i != 4; ++i) + printf("%08X ", u.ints[i]); + printf("\n"); + } + +void serpent_encrypt_4(const byte in[64], + byte out[64], + const u32bit keys_32[132]) + { + const __m128i* keys = (const __m128i*)(keys_32); + + /* + FIXME: figure out a fast way to do this with 4 loads with + _mm_loadu_si128 plus shuffle/interleave ops + */ + union { __m128i v; u32bit u32[4]; } convert; + + convert.u32[0] = load_le(in, 0); + convert.u32[1] = load_le(in, 4); + convert.u32[2] = load_le(in, 8); + convert.u32[3] = load_le(in, 12); + + __m128i b0 = convert.v; + + convert.u32[0] = load_le(in, 1); + convert.u32[1] = load_le(in, 5); + convert.u32[2] = load_le(in, 9); + convert.u32[3] = load_le(in, 13); + + __m128i b1 = convert.v; + + convert.u32[0] = load_le(in, 2); + convert.u32[1] = load_le(in, 6); + convert.u32[2] = load_le(in, 10); + convert.u32[3] = load_le(in, 14); + + __m128i b2 = convert.v; + + convert.u32[0] = load_le(in, 3); + convert.u32[1] = load_le(in, 7); + convert.u32[2] = load_le(in, 11); + convert.u32[3] = load_le(in, 15); + + + __m128i b3 = convert.v; + + __m128i b4; // temp + + const __m128i all_ones = _mm_set1_epi8(0xFF); + + key_xor(0, b0, b1, b2, b3); + SBoxE1(b0, b1, b2, b3, b4); + transform(b0, b1, b2, b3); + + key_xor(b0, b1, b2, b3, 1); + + print_simd("b0", b0); + print_simd("b1", b1); + print_simd("b2", b2); + print_simd("b3", b3); + } + +} + +/* +* Serpent Encryption +*/ +void Serpent_SSE2::encrypt_n(const byte in[], byte out[], u32bit blocks) const + { + while(blocks >= 4) + { + serpent_encrypt_4(in, out, this->round_key); + //Serpent::encrypt_n(in, out, 4); + in += 4 * BLOCK_SIZE; + out += 4 * BLOCK_SIZE; + blocks -= 4; + } + + for(u32bit i = 0; i != blocks; ++i) + { + Serpent::encrypt_n(in, out, 1); + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } + } + +/* +* Serpent Decryption +*/ +void Serpent_SSE2::decrypt_n(const byte in[], byte out[], u32bit blocks) const + { + for(u32bit i = 0; i != blocks; ++i) + { + Serpent::decrypt_n(in, out, 1); + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } + } + +} diff --git a/src/block/serpent_sse2/serp_sse2.h b/src/block/serpent_sse2/serp_sse2.h new file mode 100644 index 000000000..f1e5c2028 --- /dev/null +++ b/src/block/serpent_sse2/serp_sse2.h @@ -0,0 +1,29 @@ +/* +* Serpent (SSE2) +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SERPENT_SSE2_H__ +#define BOTAN_SERPENT_SSE2_H__ + +#include + +namespace Botan { + +/* +* Serpent +*/ +class BOTAN_DLL Serpent_SSE2 : 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_SSE2; } + }; + +} + +#endif diff --git a/src/block/skipjack/skipjack.h b/src/block/skipjack/skipjack.h index ec071dfe7..f12032f36 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw(); std::string name() const { return "Skipjack"; } BlockCipher* clone() const { return new Skipjack; } + Skipjack() : BlockCipher(8, 10) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) 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 FTABLE[10]; }; diff --git a/src/block/square/square.h b/src/block/square/square.h index 0de4c20bd..5d9cfc78c 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw(); std::string name() const { return "Square"; } BlockCipher* clone() const { return new Square; } + Square() : BlockCipher(16, 16) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); static void transform(u32bit[4]); diff --git a/src/block/tea/tea.h b/src/block/tea/tea.h index 141899e88..825a051aa 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { K.clear(); } std::string name() const { return "TEA"; } BlockCipher* clone() const { return new TEA; } + TEA() : BlockCipher(8, 16) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer K; }; diff --git a/src/block/twofish/twofish.h b/src/block/twofish/twofish.h index 640fb58ad..87b9aa626 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw(); std::string name() const { return "Twofish"; } BlockCipher* clone() const { return new Twofish; } + Twofish() : BlockCipher(16, 16, 32, 8) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); static void rs_mul(byte[4], byte, u32bit); diff --git a/src/block/xtea/xtea.h b/src/block/xtea/xtea.h index b50f487b4..de265818d 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 encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + void clear() throw() { EK.clear(); } std::string name() const { return "XTEA"; } BlockCipher* clone() const { return new XTEA; } + XTEA() : BlockCipher(8, 16) {} private: - void encrypt_n(const byte in[], byte out[], u32bit blocks) const; - void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); SecureBuffer EK; }; diff --git a/src/engine/sse2_eng/eng_sse2.cpp b/src/engine/sse2_eng/eng_sse2.cpp index c738b3d96..9f68a070e 100644 --- a/src/engine/sse2_eng/eng_sse2.cpp +++ b/src/engine/sse2_eng/eng_sse2.cpp @@ -1,6 +1,6 @@ /** * SSE2 Assembly Engine -* (C) 1999-2008 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -11,10 +11,27 @@ #include #endif +#if defined(BOTAN_HAS_SERPENT_SSE2) + #include +#endif + namespace Botan { -HashFunction* SSE2_Assembler_Engine::find_hash(const SCAN_Name& request, - Algorithm_Factory&) const +BlockCipher* +SSE2_Assembler_Engine::find_block_cipher(const SCAN_Name& request, + Algorithm_Factory&) const + { +#if defined(BOTAN_HAS_SERPENT_SSE2) + if(request.algo_name() == "Serpent") + return new Serpent_SSE2; +#endif + + return 0; + } + +HashFunction* +SSE2_Assembler_Engine::find_hash(const SCAN_Name& request, + Algorithm_Factory&) const { #if defined(BOTAN_HAS_SHA1_SSE2) if(request.algo_name() == "SHA-160") diff --git a/src/engine/sse2_eng/eng_sse2.h b/src/engine/sse2_eng/eng_sse2.h index 129697e8f..c6b0ce889 100644 --- a/src/engine/sse2_eng/eng_sse2.h +++ b/src/engine/sse2_eng/eng_sse2.h @@ -1,6 +1,6 @@ /** * SSE2 Assembly Engine -* (C) 1999-2008 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -17,6 +17,9 @@ class BOTAN_DLL SSE2_Assembler_Engine : public Engine public: std::string provider_name() const { return "sse2"; } private: + BlockCipher* find_block_cipher(const SCAN_Name&, + Algorithm_Factory&) const; + HashFunction* find_hash(const SCAN_Name& reqeust, Algorithm_Factory&) const; }; -- cgit v1.2.3 From 285d350ed62d2714592a27bf577832a92cb6902f Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 12 Aug 2009 12:23:16 +0000 Subject: Add full 4-way SSE2 Serpent encryption. Load/store operations are via unions and can be made much faster using interleave operations I think. Currently ~2.5x faster in ECB or CTR mode on a Core2, which isn't too bad. --- src/block/serpent_sse2/info.txt | 1 + src/block/serpent_sse2/serp_sse2.cpp | 111 +++++++++------- src/block/serpent_sse2/serp_sse2_sbox.h | 225 ++++++++++++++++++++++++++++++++ 3 files changed, 290 insertions(+), 47 deletions(-) create mode 100644 src/block/serpent_sse2/serp_sse2_sbox.h (limited to 'src') diff --git a/src/block/serpent_sse2/info.txt b/src/block/serpent_sse2/info.txt index ad8323f53..09733e98f 100644 --- a/src/block/serpent_sse2/info.txt +++ b/src/block/serpent_sse2/info.txt @@ -7,6 +7,7 @@ load_on auto serp_sse2.cpp serp_sse2.h +serp_sse2_sbox.h diff --git a/src/block/serpent_sse2/serp_sse2.cpp b/src/block/serpent_sse2/serp_sse2.cpp index 759f3e1d6..3e78f0bac 100644 --- a/src/block/serpent_sse2/serp_sse2.cpp +++ b/src/block/serpent_sse2/serp_sse2.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -13,29 +14,6 @@ namespace Botan { namespace { -#define SBoxE1(b0, b1, b2, b3, b4) \ - do { \ - b3 = _mm_xor_si128(b3, b0); \ - b4 = b1; \ - b1 = _mm_and_si128(b1, b3); \ - b4 = _mm_xor_si128(b4, b2); \ - b1 = _mm_xor_si128(b1, b0); \ - b0 = _mm_or_si128(b0, b3); \ - b0 = _mm_xor_si128(b0, b4); \ - b4 = _mm_xor_si128(b4, b3); \ - b3 = _mm_xor_si128(b3, b2); \ - b2 = _mm_or_si128(b2, b1); \ - b2 = _mm_xor_si128(b2, b4); \ - b4 = _mm_andnot_si128(b4, all_ones); \ - b4 = _mm_or_si128(b4, b1); \ - b1 = _mm_xor_si128(b1, b3); \ - b1 = _mm_xor_si128(b1, b4); \ - b3 = _mm_or_si128(b3, b0); \ - b1 = _mm_xor_si128(b1, b3); \ - b4 = _mm_xor_si128(b4, b3); \ - b3 = b0; b0 = b1; b1 = b4; \ - } while(0); - #define rotate_left_m128(vec, rot) \ _mm_or_si128(_mm_slli_epi32(vec, rot), _mm_srli_epi32(vec, 32-rot)) @@ -89,45 +67,84 @@ void serpent_encrypt_4(const byte in[64], convert.u32[1] = load_le(in, 4); convert.u32[2] = load_le(in, 8); convert.u32[3] = load_le(in, 12); - - __m128i b0 = convert.v; + __m128i B0 = convert.v; convert.u32[0] = load_le(in, 1); convert.u32[1] = load_le(in, 5); convert.u32[2] = load_le(in, 9); convert.u32[3] = load_le(in, 13); - - __m128i b1 = convert.v; + __m128i B1 = convert.v; convert.u32[0] = load_le(in, 2); convert.u32[1] = load_le(in, 6); convert.u32[2] = load_le(in, 10); convert.u32[3] = load_le(in, 14); - - __m128i b2 = convert.v; + __m128i B2 = convert.v; convert.u32[0] = load_le(in, 3); convert.u32[1] = load_le(in, 7); convert.u32[2] = load_le(in, 11); convert.u32[3] = load_le(in, 15); - - - __m128i b3 = convert.v; - - __m128i b4; // temp - - const __m128i all_ones = _mm_set1_epi8(0xFF); - - key_xor(0, b0, b1, b2, b3); - SBoxE1(b0, b1, b2, b3, b4); - transform(b0, b1, b2, b3); - - key_xor(b0, b1, b2, b3, 1); - - print_simd("b0", b0); - print_simd("b1", b1); - print_simd("b2", b2); - print_simd("b3", b3); + __m128i B3 = convert.v; + + 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); + + // FIXME: figure out how to do this fast + union { __m128i v; u32bit u32[4]; } convert_B0; + union { __m128i v; u32bit u32[4]; } convert_B1; + union { __m128i v; u32bit u32[4]; } convert_B2; + union { __m128i v; u32bit u32[4]; } convert_B3; + convert_B0.v = B0; + convert_B1.v = B1; + convert_B2.v = B2; + convert_B3.v = B3; + store_le(out, + convert_B0.u32[0], convert_B1.u32[0], + convert_B2.u32[0], convert_B3.u32[0]); + + store_le(out + 16, + convert_B0.u32[1], convert_B1.u32[1], + convert_B2.u32[1], convert_B3.u32[1]); + + store_le(out + 32, + convert_B0.u32[2], convert_B1.u32[2], + convert_B2.u32[2], convert_B3.u32[2]); + + store_le(out + 48, + convert_B0.u32[3], convert_B1.u32[3], + convert_B2.u32[3], convert_B3.u32[3]); } } diff --git a/src/block/serpent_sse2/serp_sse2_sbox.h b/src/block/serpent_sse2/serp_sse2_sbox.h new file mode 100644 index 000000000..2c4d9d9cb --- /dev/null +++ b/src/block/serpent_sse2/serp_sse2_sbox.h @@ -0,0 +1,225 @@ +/* +* Serpent Sboxes in SSE2 form +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef SERPENT_SSE2_SBOXES_H__ +#define SERPENT_SSE2_SBOXES_H__ + +#define SBoxE1(b0, b1, b2, b3) \ + do { \ + b3 = _mm_xor_si128(b3, b0); \ + __m128i b4 = b1; \ + b1 = _mm_and_si128(b1, b3); \ + b4 = _mm_xor_si128(b4, b2); \ + b1 = _mm_xor_si128(b1, b0); \ + b0 = _mm_or_si128(b0, b3); \ + b0 = _mm_xor_si128(b0, b4); \ + b4 = _mm_xor_si128(b4, b3); \ + b3 = _mm_xor_si128(b3, b2); \ + b2 = _mm_or_si128(b2, b1); \ + b2 = _mm_xor_si128(b2, b4); \ + b4 = _mm_andnot_si128(b4, _mm_set1_epi8(0xFF)); \ + b4 = _mm_or_si128(b4, b1); \ + b1 = _mm_xor_si128(b1, b3); \ + b1 = _mm_xor_si128(b1, b4); \ + b3 = _mm_or_si128(b3, b0); \ + b1 = _mm_xor_si128(b1, b3); \ + b4 = _mm_xor_si128(b4, b3); \ + b3 = b0; \ + b0 = b1; \ + b1 = b4; \ + } while(0); + +#define SBoxE2(b0, b1, b2, b3) \ + do \ + { \ + b0 = _mm_andnot_si128(b0, _mm_set1_epi8(0xFF)); \ + b2 = _mm_andnot_si128(b2, _mm_set1_epi8(0xFF)); \ + __m128i b4 = b0; \ + b0 = _mm_and_si128(b0, b1); \ + b2 = _mm_xor_si128(b2, b0); \ + b0 = _mm_or_si128(b0, b3); \ + b3 = _mm_xor_si128(b3, b2); \ + b1 = _mm_xor_si128(b1, b0); \ + b0 = _mm_xor_si128(b0, b4); \ + b4 = _mm_or_si128(b4, b1); \ + b1 = _mm_xor_si128(b1, b3); \ + b2 = _mm_or_si128(b2, b0); \ + b2 = _mm_and_si128(b2, b4); \ + b0 = _mm_xor_si128(b0, b1); \ + b1 = _mm_and_si128(b1, b2); \ + b1 = _mm_xor_si128(b1, b0); \ + b0 = _mm_and_si128(b0, b2); \ + b4 = _mm_xor_si128(b4, b0); \ + b0 = b2; \ + b2 = b3; \ + b3 = b1; \ + b1 = b4; \ + } while(0); + +#define SBoxE3(b0, b1, b2, b3) \ + do \ + { \ + __m128i b4 = b0; \ + b0 = _mm_and_si128(b0, b2); \ + b0 = _mm_xor_si128(b0, b3); \ + b2 = _mm_xor_si128(b2, b1); \ + b2 = _mm_xor_si128(b2, b0); \ + b3 = _mm_or_si128(b3, b4); \ + b3 = _mm_xor_si128(b3, b1); \ + b4 = _mm_xor_si128(b4, b2); \ + b1 = b3; \ + b3 = _mm_or_si128(b3, b4); \ + b3 = _mm_xor_si128(b3, b0); \ + b0 = _mm_and_si128(b0, b1); \ + b4 = _mm_xor_si128(b4, b0); \ + b1 = _mm_xor_si128(b1, b3); \ + b1 = _mm_xor_si128(b1, b4); \ + b4 = _mm_andnot_si128(b4, _mm_set1_epi8(0xFF)); \ + b0 = b2; \ + b2 = b1; \ + b1 = b3; \ + b3 = b4; \ + } while(0); + +#define SBoxE4(b0, b1, b2, b3) \ + do \ + { \ + __m128i b4 = b0; \ + b0 = _mm_or_si128(b0, b3); \ + b3 = _mm_xor_si128(b3, b1); \ + b1 = _mm_and_si128(b1, b4); \ + b4 = _mm_xor_si128(b4, b2); \ + b2 = _mm_xor_si128(b2, b3); \ + b3 = _mm_and_si128(b3, b0); \ + b4 = _mm_or_si128(b4, b1); \ + b3 = _mm_xor_si128(b3, b4); \ + b0 = _mm_xor_si128(b0, b1); \ + b4 = _mm_and_si128(b4, b0); \ + b1 = _mm_xor_si128(b1, b3); \ + b4 = _mm_xor_si128(b4, b2); \ + b1 = _mm_or_si128(b1, b0); \ + b1 = _mm_xor_si128(b1, b2); \ + b0 = _mm_xor_si128(b0, b3); \ + b2 = b1; \ + b1 = _mm_or_si128(b1, b3); \ + b1 = _mm_xor_si128(b1, b0); \ + b0 = b1; \ + b1 = b2; \ + b2 = b3; \ + b3 = b4; \ + } while(0); + +#define SBoxE5(b0, b1, b2, b3) \ + do \ + { \ + b1 = _mm_xor_si128(b1, b3); \ + b3 = _mm_andnot_si128(b3, _mm_set1_epi8(0xFF)); \ + b2 = _mm_xor_si128(b2, b3); \ + b3 = _mm_xor_si128(b3, b0); \ + __m128i b4 = b1; \ + b1 = _mm_and_si128(b1, b3); \ + b1 = _mm_xor_si128(b1, b2); \ + b4 = _mm_xor_si128(b4, b3); \ + b0 = _mm_xor_si128(b0, b4); \ + b2 = _mm_and_si128(b2, b4); \ + b2 = _mm_xor_si128(b2, b0); \ + b0 = _mm_and_si128(b0, b1); \ + b3 = _mm_xor_si128(b3, b0); \ + b4 = _mm_or_si128(b4, b1); \ + b4 = _mm_xor_si128(b4, b0); \ + b0 = _mm_or_si128(b0, b3); \ + b0 = _mm_xor_si128(b0, b2); \ + b2 = _mm_and_si128(b2, b3); \ + b0 = _mm_andnot_si128(b0, _mm_set1_epi8(0xFF)); \ + b4 = _mm_xor_si128(b4, b2); \ + b2 = b0; \ + b0 = b1; \ + b1 = b4; \ + } while(0); + +#define SBoxE6(b0, b1, b2, b3) \ + do \ + { \ + b0 = _mm_xor_si128(b0, b1); \ + b1 = _mm_xor_si128(b1, b3); \ + b3 = _mm_andnot_si128(b3, _mm_set1_epi8(0xFF)); \ + __m128i b4 = b1; \ + b1 = _mm_and_si128(b1, b0); \ + b2 = _mm_xor_si128(b2, b3); \ + b1 = _mm_xor_si128(b1, b2); \ + b2 = _mm_or_si128(b2, b4); \ + b4 = _mm_xor_si128(b4, b3); \ + b3 = _mm_and_si128(b3, b1); \ + b3 = _mm_xor_si128(b3, b0); \ + b4 = _mm_xor_si128(b4, b1); \ + b4 = _mm_xor_si128(b4, b2); \ + b2 = _mm_xor_si128(b2, b0); \ + b0 = _mm_and_si128(b0, b3); \ + b2 = _mm_andnot_si128(b2, _mm_set1_epi8(0xFF)); \ + b0 = _mm_xor_si128(b0, b4); \ + b4 = _mm_or_si128(b4, b3); \ + b4 = _mm_xor_si128(b4, b2); \ + b2 = b0; \ + b0 = b1; \ + b1 = b3; \ + b3 = b4; \ + } while(0); + +#define SBoxE7(b0, b1, b2, b3) \ + do \ + { \ + b2 = _mm_andnot_si128(b2, _mm_set1_epi8(0xFF)); \ + __m128i b4 = b3; \ + b3 = _mm_and_si128(b3, b0); \ + b0 = _mm_xor_si128(b0, b4); \ + b3 = _mm_xor_si128(b3, b2); \ + b2 = _mm_or_si128(b2, b4); \ + b1 = _mm_xor_si128(b1, b3); \ + b2 = _mm_xor_si128(b2, b0); \ + b0 = _mm_or_si128(b0, b1); \ + b2 = _mm_xor_si128(b2, b1); \ + b4 = _mm_xor_si128(b4, b0); \ + b0 = _mm_or_si128(b0, b3); \ + b0 = _mm_xor_si128(b0, b2); \ + b4 = _mm_xor_si128(b4, b3); \ + b4 = _mm_xor_si128(b4, b0); \ + b3 = _mm_andnot_si128(b3, _mm_set1_epi8(0xFF)); \ + b2 = _mm_and_si128(b2, b4); \ + b3 = _mm_xor_si128(b3, b2); \ + b2 = b4; \ + } while(0); + +#define SBoxE8(b0, b1, b2, b3) \ + do \ + { \ + __m128i b4 = b1; \ + b1 = _mm_or_si128(b1, b2); \ + b1 = _mm_xor_si128(b1, b3); \ + b4 = _mm_xor_si128(b4, b2); \ + b2 = _mm_xor_si128(b2, b1); \ + b3 = _mm_or_si128(b3, b4); \ + b3 = _mm_and_si128(b3, b0); \ + b4 = _mm_xor_si128(b4, b2); \ + b3 = _mm_xor_si128(b3, b1); \ + b1 = _mm_or_si128(b1, b4); \ + b1 = _mm_xor_si128(b1, b0); \ + b0 = _mm_or_si128(b0, b4); \ + b0 = _mm_xor_si128(b0, b2); \ + b1 = _mm_xor_si128(b1, b4); \ + b2 = _mm_xor_si128(b2, b1); \ + b1 = _mm_and_si128(b1, b0); \ + b1 = _mm_xor_si128(b1, b4); \ + b2 = _mm_andnot_si128(b2, _mm_set1_epi8(0xFF)); \ + b2 = _mm_or_si128(b2, b0); \ + b4 = _mm_xor_si128(b4, b2); \ + b2 = b1; \ + b1 = b3; \ + b3 = b0; \ + b0 = b4; \ + } while(0); + +#endif -- cgit v1.2.3 From 89eb757b344d3605f3f8012079749f01ef23bb6b Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 12 Aug 2009 13:49:19 +0000 Subject: Use SSE2 unpack instructions instead of unions for input/output conversion. About 10% faster than previous. Currently 112 MiB/s in ECB mode, versus about 40 MiB/s in scalar mode, on my 2.4 GHz Core2 --- src/block/serpent_sse2/serp_sse2.cpp | 162 ++++++------- src/block/serpent_sse2/serp_sse2_sbox.h | 401 ++++++++++++++++---------------- 2 files changed, 263 insertions(+), 300 deletions(-) (limited to 'src') diff --git a/src/block/serpent_sse2/serp_sse2.cpp b/src/block/serpent_sse2/serp_sse2.cpp index 3e78f0bac..ea937c95a 100644 --- a/src/block/serpent_sse2/serp_sse2.cpp +++ b/src/block/serpent_sse2/serp_sse2.cpp @@ -14,88 +14,76 @@ namespace Botan { namespace { +#define key_xor(round, B0, B1, B2, B3) \ + do { \ + __m128i key = _mm_loadu_si128(keys + round); \ + B0 = _mm_xor_si128(B0, _mm_shuffle_epi32(key, _MM_SHUFFLE(0,0,0,0))); \ + B1 = _mm_xor_si128(B1, _mm_shuffle_epi32(key, _MM_SHUFFLE(1,1,1,1))); \ + B2 = _mm_xor_si128(B2, _mm_shuffle_epi32(key, _MM_SHUFFLE(2,2,2,2))); \ + B3 = _mm_xor_si128(B3, _mm_shuffle_epi32(key, _MM_SHUFFLE(3,3,3,3))); \ + } while(0); + +/* +* Serpent's linear transformation +*/ #define rotate_left_m128(vec, rot) \ _mm_or_si128(_mm_slli_epi32(vec, rot), _mm_srli_epi32(vec, 32-rot)) -#define key_xor(round, b0, b1, b2, b3) \ - do { \ - __m128i key = _mm_loadu_si128(keys + round); \ - b0 = _mm_xor_si128(b0, _mm_shuffle_epi32(key, _MM_SHUFFLE(0,0,0,0))); \ - b1 = _mm_xor_si128(b1, _mm_shuffle_epi32(key, _MM_SHUFFLE(1,1,1,1))); \ - b2 = _mm_xor_si128(b2, _mm_shuffle_epi32(key, _MM_SHUFFLE(2,2,2,2))); \ - b3 = _mm_xor_si128(b3, _mm_shuffle_epi32(key, _MM_SHUFFLE(3,3,3,3))); \ - } while(0); - -#define transform(b0, b1, b2, b3) \ - do \ - { \ - b0 = rotate_left_m128(b0, 13); \ - b2 = rotate_left_m128(b2, 3); \ - b1 = _mm_xor_si128(b1, _mm_xor_si128(b0, b2)); \ - b3 = _mm_xor_si128(b3, _mm_xor_si128(b2, _mm_slli_epi32(b0, 3))); \ - b1 = rotate_left_m128(b1, 1); \ - b3 = rotate_left_m128(b3, 7); \ - b0 = _mm_xor_si128(b0, _mm_xor_si128(b1, b3)); \ - b2 = _mm_xor_si128(b2, _mm_xor_si128(b3, _mm_slli_epi32(b1, 7))); \ - b0 = rotate_left_m128(b0, 5); \ - b2 = rotate_left_m128(b2, 22); \ - } while(0); - -void print_simd(const char* name, __m128i vec) - { - union { __m128i v; int32_t ints[4]; } u = { vec }; +#define transform(B0, B1, B2, B3) \ + do { \ + B0 = rotate_left_m128(B0, 13); \ + B2 = rotate_left_m128(B2, 3); \ + B1 = _mm_xor_si128(B1, _mm_xor_si128(B0, B2)); \ + B3 = _mm_xor_si128(B3, _mm_xor_si128(B2, _mm_slli_epi32(B0, 3))); \ + B1 = rotate_left_m128(B1, 1); \ + B3 = rotate_left_m128(B3, 7); \ + B0 = _mm_xor_si128(B0, _mm_xor_si128(B1, B3)); \ + B2 = _mm_xor_si128(B2, _mm_xor_si128(B3, _mm_slli_epi32(B1, 7))); \ + B0 = rotate_left_m128(B0, 5); \ + B2 = rotate_left_m128(B2, 22); \ + } while(0); - printf("%s: ", name); - for(u32bit i = 0; i != 4; ++i) - printf("%08X ", u.ints[i]); - printf("\n"); - } +/* +* 4x4 SSE2 integer matrix transpose +*/ +#define transpose(B0, B1, B2, B3) \ + do { \ + __m128i T0 = _mm_unpacklo_epi32(B0, B1); \ + __m128i T1 = _mm_unpacklo_epi32(B2, B3); \ + __m128i T2 = _mm_unpackhi_epi32(B0, B1); \ + __m128i T3 = _mm_unpackhi_epi32(B2, B3); \ + B0 = _mm_unpacklo_epi64(T0, T1); \ + B1 = _mm_unpackhi_epi64(T0, T1); \ + B2 = _mm_unpacklo_epi64(T2, T3); \ + B3 = _mm_unpackhi_epi64(T2, T3); \ + } while(0); +/* +* SSE2 Serpent Encryption of 4 blocks in parallel +*/ void serpent_encrypt_4(const byte in[64], byte out[64], const u32bit keys_32[132]) { const __m128i* keys = (const __m128i*)(keys_32); - - /* - FIXME: figure out a fast way to do this with 4 loads with - _mm_loadu_si128 plus shuffle/interleave ops - */ - union { __m128i v; u32bit u32[4]; } convert; - - convert.u32[0] = load_le(in, 0); - convert.u32[1] = load_le(in, 4); - convert.u32[2] = load_le(in, 8); - convert.u32[3] = load_le(in, 12); - __m128i B0 = convert.v; - - convert.u32[0] = load_le(in, 1); - convert.u32[1] = load_le(in, 5); - convert.u32[2] = load_le(in, 9); - convert.u32[3] = load_le(in, 13); - __m128i B1 = convert.v; - - convert.u32[0] = load_le(in, 2); - convert.u32[1] = load_le(in, 6); - convert.u32[2] = load_le(in, 10); - convert.u32[3] = load_le(in, 14); - __m128i B2 = convert.v; - - convert.u32[0] = load_le(in, 3); - convert.u32[1] = load_le(in, 7); - convert.u32[2] = load_le(in, 11); - convert.u32[3] = load_le(in, 15); - __m128i B3 = convert.v; - - 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); - + __m128i* out_mm = (__m128i*)(out); + __m128i* in_mm = (__m128i*)(in); + + __m128i B0 = _mm_loadu_si128(in_mm); + __m128i B1 = _mm_loadu_si128(in_mm + 1); + __m128i B2 = _mm_loadu_si128(in_mm + 2); + __m128i B3 = _mm_loadu_si128(in_mm + 3); + + 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); @@ -121,30 +109,12 @@ void serpent_encrypt_4(const byte in[64], 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); - // FIXME: figure out how to do this fast - union { __m128i v; u32bit u32[4]; } convert_B0; - union { __m128i v; u32bit u32[4]; } convert_B1; - union { __m128i v; u32bit u32[4]; } convert_B2; - union { __m128i v; u32bit u32[4]; } convert_B3; - convert_B0.v = B0; - convert_B1.v = B1; - convert_B2.v = B2; - convert_B3.v = B3; - store_le(out, - convert_B0.u32[0], convert_B1.u32[0], - convert_B2.u32[0], convert_B3.u32[0]); - - store_le(out + 16, - convert_B0.u32[1], convert_B1.u32[1], - convert_B2.u32[1], convert_B3.u32[1]); - - store_le(out + 32, - convert_B0.u32[2], convert_B1.u32[2], - convert_B2.u32[2], convert_B3.u32[2]); - - store_le(out + 48, - convert_B0.u32[3], convert_B1.u32[3], - convert_B2.u32[3], convert_B3.u32[3]); + transpose(B0, B1, B2, B3); + + _mm_storeu_si128(out_mm , B0); + _mm_storeu_si128(out_mm + 1, B1); + _mm_storeu_si128(out_mm + 2, B2); + _mm_storeu_si128(out_mm + 3, B3); } } diff --git a/src/block/serpent_sse2/serp_sse2_sbox.h b/src/block/serpent_sse2/serp_sse2_sbox.h index 2c4d9d9cb..bc8678a89 100644 --- a/src/block/serpent_sse2/serp_sse2_sbox.h +++ b/src/block/serpent_sse2/serp_sse2_sbox.h @@ -8,218 +8,211 @@ #ifndef SERPENT_SSE2_SBOXES_H__ #define SERPENT_SSE2_SBOXES_H__ -#define SBoxE1(b0, b1, b2, b3) \ +#define SBoxE1(B0, B1, B2, B3) \ do { \ - b3 = _mm_xor_si128(b3, b0); \ - __m128i b4 = b1; \ - b1 = _mm_and_si128(b1, b3); \ - b4 = _mm_xor_si128(b4, b2); \ - b1 = _mm_xor_si128(b1, b0); \ - b0 = _mm_or_si128(b0, b3); \ - b0 = _mm_xor_si128(b0, b4); \ - b4 = _mm_xor_si128(b4, b3); \ - b3 = _mm_xor_si128(b3, b2); \ - b2 = _mm_or_si128(b2, b1); \ - b2 = _mm_xor_si128(b2, b4); \ - b4 = _mm_andnot_si128(b4, _mm_set1_epi8(0xFF)); \ - b4 = _mm_or_si128(b4, b1); \ - b1 = _mm_xor_si128(b1, b3); \ - b1 = _mm_xor_si128(b1, b4); \ - b3 = _mm_or_si128(b3, b0); \ - b1 = _mm_xor_si128(b1, b3); \ - b4 = _mm_xor_si128(b4, b3); \ - b3 = b0; \ - b0 = b1; \ - b1 = b4; \ + B3 = _mm_xor_si128(B3, B0); \ + __m128i B4 = B1; \ + B1 = _mm_and_si128(B1, B3); \ + B4 = _mm_xor_si128(B4, B2); \ + B1 = _mm_xor_si128(B1, B0); \ + B0 = _mm_or_si128(B0, B3); \ + B0 = _mm_xor_si128(B0, B4); \ + B4 = _mm_xor_si128(B4, B3); \ + B3 = _mm_xor_si128(B3, B2); \ + B2 = _mm_or_si128(B2, B1); \ + B2 = _mm_xor_si128(B2, B4); \ + B4 = _mm_andnot_si128(B4, _mm_set1_epi8(0xFF)); \ + B4 = _mm_or_si128(B4, B1); \ + B1 = _mm_xor_si128(B1, B3); \ + B1 = _mm_xor_si128(B1, B4); \ + B3 = _mm_or_si128(B3, B0); \ + B1 = _mm_xor_si128(B1, B3); \ + B4 = _mm_xor_si128(B4, B3); \ + B3 = B0; \ + B0 = B1; \ + B1 = B4; \ } while(0); -#define SBoxE2(b0, b1, b2, b3) \ - do \ - { \ - b0 = _mm_andnot_si128(b0, _mm_set1_epi8(0xFF)); \ - b2 = _mm_andnot_si128(b2, _mm_set1_epi8(0xFF)); \ - __m128i b4 = b0; \ - b0 = _mm_and_si128(b0, b1); \ - b2 = _mm_xor_si128(b2, b0); \ - b0 = _mm_or_si128(b0, b3); \ - b3 = _mm_xor_si128(b3, b2); \ - b1 = _mm_xor_si128(b1, b0); \ - b0 = _mm_xor_si128(b0, b4); \ - b4 = _mm_or_si128(b4, b1); \ - b1 = _mm_xor_si128(b1, b3); \ - b2 = _mm_or_si128(b2, b0); \ - b2 = _mm_and_si128(b2, b4); \ - b0 = _mm_xor_si128(b0, b1); \ - b1 = _mm_and_si128(b1, b2); \ - b1 = _mm_xor_si128(b1, b0); \ - b0 = _mm_and_si128(b0, b2); \ - b4 = _mm_xor_si128(b4, b0); \ - b0 = b2; \ - b2 = b3; \ - b3 = b1; \ - b1 = b4; \ - } while(0); +#define SBoxE2(B0, B1, B2, B3) \ + do { \ + B0 = _mm_andnot_si128(B0, _mm_set1_epi8(0xFF)); \ + B2 = _mm_andnot_si128(B2, _mm_set1_epi8(0xFF)); \ + __m128i B4 = B0; \ + B0 = _mm_and_si128(B0, B1); \ + B2 = _mm_xor_si128(B2, B0); \ + B0 = _mm_or_si128(B0, B3); \ + B3 = _mm_xor_si128(B3, B2); \ + B1 = _mm_xor_si128(B1, B0); \ + B0 = _mm_xor_si128(B0, B4); \ + B4 = _mm_or_si128(B4, B1); \ + B1 = _mm_xor_si128(B1, B3); \ + B2 = _mm_or_si128(B2, B0); \ + B2 = _mm_and_si128(B2, B4); \ + B0 = _mm_xor_si128(B0, B1); \ + B1 = _mm_and_si128(B1, B2); \ + B1 = _mm_xor_si128(B1, B0); \ + B0 = _mm_and_si128(B0, B2); \ + B4 = _mm_xor_si128(B4, B0); \ + B0 = B2; \ + B2 = B3; \ + B3 = B1; \ + B1 = B4; \ + } while(0); -#define SBoxE3(b0, b1, b2, b3) \ - do \ - { \ - __m128i b4 = b0; \ - b0 = _mm_and_si128(b0, b2); \ - b0 = _mm_xor_si128(b0, b3); \ - b2 = _mm_xor_si128(b2, b1); \ - b2 = _mm_xor_si128(b2, b0); \ - b3 = _mm_or_si128(b3, b4); \ - b3 = _mm_xor_si128(b3, b1); \ - b4 = _mm_xor_si128(b4, b2); \ - b1 = b3; \ - b3 = _mm_or_si128(b3, b4); \ - b3 = _mm_xor_si128(b3, b0); \ - b0 = _mm_and_si128(b0, b1); \ - b4 = _mm_xor_si128(b4, b0); \ - b1 = _mm_xor_si128(b1, b3); \ - b1 = _mm_xor_si128(b1, b4); \ - b4 = _mm_andnot_si128(b4, _mm_set1_epi8(0xFF)); \ - b0 = b2; \ - b2 = b1; \ - b1 = b3; \ - b3 = b4; \ - } while(0); +#define SBoxE3(B0, B1, B2, B3) \ + do { \ + __m128i B4 = B0; \ + B0 = _mm_and_si128(B0, B2); \ + B0 = _mm_xor_si128(B0, B3); \ + B2 = _mm_xor_si128(B2, B1); \ + B2 = _mm_xor_si128(B2, B0); \ + B3 = _mm_or_si128(B3, B4); \ + B3 = _mm_xor_si128(B3, B1); \ + B4 = _mm_xor_si128(B4, B2); \ + B1 = B3; \ + B3 = _mm_or_si128(B3, B4); \ + B3 = _mm_xor_si128(B3, B0); \ + B0 = _mm_and_si128(B0, B1); \ + B4 = _mm_xor_si128(B4, B0); \ + B1 = _mm_xor_si128(B1, B3); \ + B1 = _mm_xor_si128(B1, B4); \ + B4 = _mm_andnot_si128(B4, _mm_set1_epi8(0xFF)); \ + B0 = B2; \ + B2 = B1; \ + B1 = B3; \ + B3 = B4; \ + } while(0); -#define SBoxE4(b0, b1, b2, b3) \ - do \ - { \ - __m128i b4 = b0; \ - b0 = _mm_or_si128(b0, b3); \ - b3 = _mm_xor_si128(b3, b1); \ - b1 = _mm_and_si128(b1, b4); \ - b4 = _mm_xor_si128(b4, b2); \ - b2 = _mm_xor_si128(b2, b3); \ - b3 = _mm_and_si128(b3, b0); \ - b4 = _mm_or_si128(b4, b1); \ - b3 = _mm_xor_si128(b3, b4); \ - b0 = _mm_xor_si128(b0, b1); \ - b4 = _mm_and_si128(b4, b0); \ - b1 = _mm_xor_si128(b1, b3); \ - b4 = _mm_xor_si128(b4, b2); \ - b1 = _mm_or_si128(b1, b0); \ - b1 = _mm_xor_si128(b1, b2); \ - b0 = _mm_xor_si128(b0, b3); \ - b2 = b1; \ - b1 = _mm_or_si128(b1, b3); \ - b1 = _mm_xor_si128(b1, b0); \ - b0 = b1; \ - b1 = b2; \ - b2 = b3; \ - b3 = b4; \ - } while(0); +#define SBoxE4(B0, B1, B2, B3) \ + do { \ + __m128i B4 = B0; \ + B0 = _mm_or_si128(B0, B3); \ + B3 = _mm_xor_si128(B3, B1); \ + B1 = _mm_and_si128(B1, B4); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = _mm_xor_si128(B2, B3); \ + B3 = _mm_and_si128(B3, B0); \ + B4 = _mm_or_si128(B4, B1); \ + B3 = _mm_xor_si128(B3, B4); \ + B0 = _mm_xor_si128(B0, B1); \ + B4 = _mm_and_si128(B4, B0); \ + B1 = _mm_xor_si128(B1, B3); \ + B4 = _mm_xor_si128(B4, B2); \ + B1 = _mm_or_si128(B1, B0); \ + B1 = _mm_xor_si128(B1, B2); \ + B0 = _mm_xor_si128(B0, B3); \ + B2 = B1; \ + B1 = _mm_or_si128(B1, B3); \ + B1 = _mm_xor_si128(B1, B0); \ + B0 = B1; \ + B1 = B2; \ + B2 = B3; \ + B3 = B4; \ + } while(0); -#define SBoxE5(b0, b1, b2, b3) \ - do \ - { \ - b1 = _mm_xor_si128(b1, b3); \ - b3 = _mm_andnot_si128(b3, _mm_set1_epi8(0xFF)); \ - b2 = _mm_xor_si128(b2, b3); \ - b3 = _mm_xor_si128(b3, b0); \ - __m128i b4 = b1; \ - b1 = _mm_and_si128(b1, b3); \ - b1 = _mm_xor_si128(b1, b2); \ - b4 = _mm_xor_si128(b4, b3); \ - b0 = _mm_xor_si128(b0, b4); \ - b2 = _mm_and_si128(b2, b4); \ - b2 = _mm_xor_si128(b2, b0); \ - b0 = _mm_and_si128(b0, b1); \ - b3 = _mm_xor_si128(b3, b0); \ - b4 = _mm_or_si128(b4, b1); \ - b4 = _mm_xor_si128(b4, b0); \ - b0 = _mm_or_si128(b0, b3); \ - b0 = _mm_xor_si128(b0, b2); \ - b2 = _mm_and_si128(b2, b3); \ - b0 = _mm_andnot_si128(b0, _mm_set1_epi8(0xFF)); \ - b4 = _mm_xor_si128(b4, b2); \ - b2 = b0; \ - b0 = b1; \ - b1 = b4; \ - } while(0); +#define SBoxE5(B0, B1, B2, B3) \ + do { \ + B1 = _mm_xor_si128(B1, B3); \ + B3 = _mm_andnot_si128(B3, _mm_set1_epi8(0xFF)); \ + B2 = _mm_xor_si128(B2, B3); \ + B3 = _mm_xor_si128(B3, B0); \ + __m128i B4 = B1; \ + B1 = _mm_and_si128(B1, B3); \ + B1 = _mm_xor_si128(B1, B2); \ + B4 = _mm_xor_si128(B4, B3); \ + B0 = _mm_xor_si128(B0, B4); \ + B2 = _mm_and_si128(B2, B4); \ + B2 = _mm_xor_si128(B2, B0); \ + B0 = _mm_and_si128(B0, B1); \ + B3 = _mm_xor_si128(B3, B0); \ + B4 = _mm_or_si128(B4, B1); \ + B4 = _mm_xor_si128(B4, B0); \ + B0 = _mm_or_si128(B0, B3); \ + B0 = _mm_xor_si128(B0, B2); \ + B2 = _mm_and_si128(B2, B3); \ + B0 = _mm_andnot_si128(B0, _mm_set1_epi8(0xFF)); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = B0; \ + B0 = B1; \ + B1 = B4; \ + } while(0); -#define SBoxE6(b0, b1, b2, b3) \ - do \ - { \ - b0 = _mm_xor_si128(b0, b1); \ - b1 = _mm_xor_si128(b1, b3); \ - b3 = _mm_andnot_si128(b3, _mm_set1_epi8(0xFF)); \ - __m128i b4 = b1; \ - b1 = _mm_and_si128(b1, b0); \ - b2 = _mm_xor_si128(b2, b3); \ - b1 = _mm_xor_si128(b1, b2); \ - b2 = _mm_or_si128(b2, b4); \ - b4 = _mm_xor_si128(b4, b3); \ - b3 = _mm_and_si128(b3, b1); \ - b3 = _mm_xor_si128(b3, b0); \ - b4 = _mm_xor_si128(b4, b1); \ - b4 = _mm_xor_si128(b4, b2); \ - b2 = _mm_xor_si128(b2, b0); \ - b0 = _mm_and_si128(b0, b3); \ - b2 = _mm_andnot_si128(b2, _mm_set1_epi8(0xFF)); \ - b0 = _mm_xor_si128(b0, b4); \ - b4 = _mm_or_si128(b4, b3); \ - b4 = _mm_xor_si128(b4, b2); \ - b2 = b0; \ - b0 = b1; \ - b1 = b3; \ - b3 = b4; \ - } while(0); +#define SBoxE6(B0, B1, B2, B3) \ + do { \ + B0 = _mm_xor_si128(B0, B1); \ + B1 = _mm_xor_si128(B1, B3); \ + B3 = _mm_andnot_si128(B3, _mm_set1_epi8(0xFF)); \ + __m128i B4 = B1; \ + B1 = _mm_and_si128(B1, B0); \ + B2 = _mm_xor_si128(B2, B3); \ + B1 = _mm_xor_si128(B1, B2); \ + B2 = _mm_or_si128(B2, B4); \ + B4 = _mm_xor_si128(B4, B3); \ + B3 = _mm_and_si128(B3, B1); \ + B3 = _mm_xor_si128(B3, B0); \ + B4 = _mm_xor_si128(B4, B1); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = _mm_xor_si128(B2, B0); \ + B0 = _mm_and_si128(B0, B3); \ + B2 = _mm_andnot_si128(B2, _mm_set1_epi8(0xFF)); \ + B0 = _mm_xor_si128(B0, B4); \ + B4 = _mm_or_si128(B4, B3); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = B0; \ + B0 = B1; \ + B1 = B3; \ + B3 = B4; \ + } while(0); -#define SBoxE7(b0, b1, b2, b3) \ - do \ - { \ - b2 = _mm_andnot_si128(b2, _mm_set1_epi8(0xFF)); \ - __m128i b4 = b3; \ - b3 = _mm_and_si128(b3, b0); \ - b0 = _mm_xor_si128(b0, b4); \ - b3 = _mm_xor_si128(b3, b2); \ - b2 = _mm_or_si128(b2, b4); \ - b1 = _mm_xor_si128(b1, b3); \ - b2 = _mm_xor_si128(b2, b0); \ - b0 = _mm_or_si128(b0, b1); \ - b2 = _mm_xor_si128(b2, b1); \ - b4 = _mm_xor_si128(b4, b0); \ - b0 = _mm_or_si128(b0, b3); \ - b0 = _mm_xor_si128(b0, b2); \ - b4 = _mm_xor_si128(b4, b3); \ - b4 = _mm_xor_si128(b4, b0); \ - b3 = _mm_andnot_si128(b3, _mm_set1_epi8(0xFF)); \ - b2 = _mm_and_si128(b2, b4); \ - b3 = _mm_xor_si128(b3, b2); \ - b2 = b4; \ - } while(0); +#define SBoxE7(B0, B1, B2, B3) \ + do { \ + B2 = _mm_andnot_si128(B2, _mm_set1_epi8(0xFF)); \ + __m128i B4 = B3; \ + B3 = _mm_and_si128(B3, B0); \ + B0 = _mm_xor_si128(B0, B4); \ + B3 = _mm_xor_si128(B3, B2); \ + B2 = _mm_or_si128(B2, B4); \ + B1 = _mm_xor_si128(B1, B3); \ + B2 = _mm_xor_si128(B2, B0); \ + B0 = _mm_or_si128(B0, B1); \ + B2 = _mm_xor_si128(B2, B1); \ + B4 = _mm_xor_si128(B4, B0); \ + B0 = _mm_or_si128(B0, B3); \ + B0 = _mm_xor_si128(B0, B2); \ + B4 = _mm_xor_si128(B4, B3); \ + B4 = _mm_xor_si128(B4, B0); \ + B3 = _mm_andnot_si128(B3, _mm_set1_epi8(0xFF)); \ + B2 = _mm_and_si128(B2, B4); \ + B3 = _mm_xor_si128(B3, B2); \ + B2 = B4; \ + } while(0); -#define SBoxE8(b0, b1, b2, b3) \ - do \ - { \ - __m128i b4 = b1; \ - b1 = _mm_or_si128(b1, b2); \ - b1 = _mm_xor_si128(b1, b3); \ - b4 = _mm_xor_si128(b4, b2); \ - b2 = _mm_xor_si128(b2, b1); \ - b3 = _mm_or_si128(b3, b4); \ - b3 = _mm_and_si128(b3, b0); \ - b4 = _mm_xor_si128(b4, b2); \ - b3 = _mm_xor_si128(b3, b1); \ - b1 = _mm_or_si128(b1, b4); \ - b1 = _mm_xor_si128(b1, b0); \ - b0 = _mm_or_si128(b0, b4); \ - b0 = _mm_xor_si128(b0, b2); \ - b1 = _mm_xor_si128(b1, b4); \ - b2 = _mm_xor_si128(b2, b1); \ - b1 = _mm_and_si128(b1, b0); \ - b1 = _mm_xor_si128(b1, b4); \ - b2 = _mm_andnot_si128(b2, _mm_set1_epi8(0xFF)); \ - b2 = _mm_or_si128(b2, b0); \ - b4 = _mm_xor_si128(b4, b2); \ - b2 = b1; \ - b1 = b3; \ - b3 = b0; \ - b0 = b4; \ - } while(0); +#define SBoxE8(B0, B1, B2, B3) \ + do { \ + __m128i B4 = B1; \ + B1 = _mm_or_si128(B1, B2); \ + B1 = _mm_xor_si128(B1, B3); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = _mm_xor_si128(B2, B1); \ + B3 = _mm_or_si128(B3, B4); \ + B3 = _mm_and_si128(B3, B0); \ + B4 = _mm_xor_si128(B4, B2); \ + B3 = _mm_xor_si128(B3, B1); \ + B1 = _mm_or_si128(B1, B4); \ + B1 = _mm_xor_si128(B1, B0); \ + B0 = _mm_or_si128(B0, B4); \ + B0 = _mm_xor_si128(B0, B2); \ + B1 = _mm_xor_si128(B1, B4); \ + B2 = _mm_xor_si128(B2, B1); \ + B1 = _mm_and_si128(B1, B0); \ + B1 = _mm_xor_si128(B1, B4); \ + B2 = _mm_andnot_si128(B2, _mm_set1_epi8(0xFF)); \ + B2 = _mm_or_si128(B2, B0); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = B1; \ + B1 = B3; \ + B3 = B0; \ + B0 = B4; \ + } while(0); #endif -- cgit v1.2.3 From 8d2ceae6d43ab1e21604e112f437b1494def5ef8 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 12 Aug 2009 14:42:34 +0000 Subject: Small code cleanups in SSE2 Serpent --- src/block/serpent_sse2/serp_sse2.cpp | 6 +- src/block/serpent_sse2/serp_sse2_sbox.h | 381 ++++++++++++++++---------------- 2 files changed, 195 insertions(+), 192 deletions(-) (limited to 'src') diff --git a/src/block/serpent_sse2/serp_sse2.cpp b/src/block/serpent_sse2/serp_sse2.cpp index ea937c95a..5ce7d8f47 100644 --- a/src/block/serpent_sse2/serp_sse2.cpp +++ b/src/block/serpent_sse2/serp_sse2.cpp @@ -65,6 +65,8 @@ void serpent_encrypt_4(const byte in[64], byte out[64], const u32bit keys_32[132]) { + const __m128i all_ones = _mm_set1_epi8(0xFF); + const __m128i* keys = (const __m128i*)(keys_32); __m128i* out_mm = (__m128i*)(out); __m128i* in_mm = (__m128i*)(in); @@ -84,6 +86,7 @@ void serpent_encrypt_4(const byte in[64], 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); @@ -92,6 +95,7 @@ void serpent_encrypt_4(const byte in[64], 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); @@ -100,6 +104,7 @@ void serpent_encrypt_4(const byte in[64], 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); @@ -127,7 +132,6 @@ void Serpent_SSE2::encrypt_n(const byte in[], byte out[], u32bit blocks) const while(blocks >= 4) { serpent_encrypt_4(in, out, this->round_key); - //Serpent::encrypt_n(in, out, 4); in += 4 * BLOCK_SIZE; out += 4 * BLOCK_SIZE; blocks -= 4; diff --git a/src/block/serpent_sse2/serp_sse2_sbox.h b/src/block/serpent_sse2/serp_sse2_sbox.h index bc8678a89..1660643ad 100644 --- a/src/block/serpent_sse2/serp_sse2_sbox.h +++ b/src/block/serpent_sse2/serp_sse2_sbox.h @@ -8,211 +8,210 @@ #ifndef SERPENT_SSE2_SBOXES_H__ #define SERPENT_SSE2_SBOXES_H__ -#define SBoxE1(B0, B1, B2, B3) \ - do { \ - B3 = _mm_xor_si128(B3, B0); \ - __m128i B4 = B1; \ - B1 = _mm_and_si128(B1, B3); \ - B4 = _mm_xor_si128(B4, B2); \ - B1 = _mm_xor_si128(B1, B0); \ - B0 = _mm_or_si128(B0, B3); \ - B0 = _mm_xor_si128(B0, B4); \ - B4 = _mm_xor_si128(B4, B3); \ - B3 = _mm_xor_si128(B3, B2); \ - B2 = _mm_or_si128(B2, B1); \ - B2 = _mm_xor_si128(B2, B4); \ - B4 = _mm_andnot_si128(B4, _mm_set1_epi8(0xFF)); \ - B4 = _mm_or_si128(B4, B1); \ - B1 = _mm_xor_si128(B1, B3); \ - B1 = _mm_xor_si128(B1, B4); \ - B3 = _mm_or_si128(B3, B0); \ - B1 = _mm_xor_si128(B1, B3); \ - B4 = _mm_xor_si128(B4, B3); \ - B3 = B0; \ - B0 = B1; \ - B1 = B4; \ +#define SBoxE1(B0, B1, B2, B3) \ + do { \ + B3 = _mm_xor_si128(B3, B0); \ + __m128i B4 = B1; \ + B1 = _mm_and_si128(B1, B3); \ + B4 = _mm_xor_si128(B4, B2); \ + B1 = _mm_xor_si128(B1, B0); \ + B0 = _mm_or_si128(B0, B3); \ + B0 = _mm_xor_si128(B0, B4); \ + B4 = _mm_xor_si128(B4, B3); \ + B3 = _mm_xor_si128(B3, B2); \ + B2 = _mm_or_si128(B2, B1); \ + B2 = _mm_xor_si128(B2, B4); \ + B4 = _mm_xor_si128(B4, all_ones); \ + B4 = _mm_or_si128(B4, B1); \ + B1 = _mm_xor_si128(B1, B3); \ + B1 = _mm_xor_si128(B1, B4); \ + B3 = _mm_or_si128(B3, B0); \ + B1 = _mm_xor_si128(B1, B3); \ + B4 = _mm_xor_si128(B4, B3); \ + B3 = B0; \ + B0 = B1; \ + B1 = B4; \ } while(0); -#define SBoxE2(B0, B1, B2, B3) \ - do { \ - B0 = _mm_andnot_si128(B0, _mm_set1_epi8(0xFF)); \ - B2 = _mm_andnot_si128(B2, _mm_set1_epi8(0xFF)); \ - __m128i B4 = B0; \ - B0 = _mm_and_si128(B0, B1); \ - B2 = _mm_xor_si128(B2, B0); \ - B0 = _mm_or_si128(B0, B3); \ - B3 = _mm_xor_si128(B3, B2); \ - B1 = _mm_xor_si128(B1, B0); \ - B0 = _mm_xor_si128(B0, B4); \ - B4 = _mm_or_si128(B4, B1); \ - B1 = _mm_xor_si128(B1, B3); \ - B2 = _mm_or_si128(B2, B0); \ - B2 = _mm_and_si128(B2, B4); \ - B0 = _mm_xor_si128(B0, B1); \ - B1 = _mm_and_si128(B1, B2); \ - B1 = _mm_xor_si128(B1, B0); \ - B0 = _mm_and_si128(B0, B2); \ - B4 = _mm_xor_si128(B4, B0); \ - B0 = B2; \ - B2 = B3; \ - B3 = B1; \ - B1 = B4; \ +#define SBoxE2(B0, B1, B2, B3) \ + do { \ + B0 = _mm_xor_si128(B0, all_ones); \ + B2 = _mm_xor_si128(B2, all_ones); \ + __m128i B4 = B0; \ + B0 = _mm_and_si128(B0, B1); \ + B2 = _mm_xor_si128(B2, B0); \ + B0 = _mm_or_si128(B0, B3); \ + B3 = _mm_xor_si128(B3, B2); \ + B1 = _mm_xor_si128(B1, B0); \ + B0 = _mm_xor_si128(B0, B4); \ + B4 = _mm_or_si128(B4, B1); \ + B1 = _mm_xor_si128(B1, B3); \ + B2 = _mm_or_si128(B2, B0); \ + B2 = _mm_and_si128(B2, B4); \ + B0 = _mm_xor_si128(B0, B1); \ + B1 = _mm_and_si128(B1, B2); \ + B1 = _mm_xor_si128(B1, B0); \ + B0 = _mm_and_si128(B0, B2); \ + B4 = _mm_xor_si128(B4, B0); \ + B0 = B2; \ + B2 = B3; \ + B3 = B1; \ + B1 = B4; \ } while(0); -#define SBoxE3(B0, B1, B2, B3) \ - do { \ - __m128i B4 = B0; \ - B0 = _mm_and_si128(B0, B2); \ - B0 = _mm_xor_si128(B0, B3); \ - B2 = _mm_xor_si128(B2, B1); \ - B2 = _mm_xor_si128(B2, B0); \ - B3 = _mm_or_si128(B3, B4); \ - B3 = _mm_xor_si128(B3, B1); \ - B4 = _mm_xor_si128(B4, B2); \ - B1 = B3; \ - B3 = _mm_or_si128(B3, B4); \ - B3 = _mm_xor_si128(B3, B0); \ - B0 = _mm_and_si128(B0, B1); \ - B4 = _mm_xor_si128(B4, B0); \ - B1 = _mm_xor_si128(B1, B3); \ - B1 = _mm_xor_si128(B1, B4); \ - B4 = _mm_andnot_si128(B4, _mm_set1_epi8(0xFF)); \ - B0 = B2; \ - B2 = B1; \ - B1 = B3; \ - B3 = B4; \ +#define SBoxE3(B0, B1, B2, B3) \ + do { \ + __m128i B4 = B0; \ + B0 = _mm_and_si128(B0, B2); \ + B0 = _mm_xor_si128(B0, B3); \ + B2 = _mm_xor_si128(B2, B1); \ + B2 = _mm_xor_si128(B2, B0); \ + B3 = _mm_or_si128(B3, B4); \ + B3 = _mm_xor_si128(B3, B1); \ + B4 = _mm_xor_si128(B4, B2); \ + B1 = B3; \ + B3 = _mm_or_si128(B3, B4); \ + B3 = _mm_xor_si128(B3, B0); \ + B0 = _mm_and_si128(B0, B1); \ + B4 = _mm_xor_si128(B4, B0); \ + B1 = _mm_xor_si128(B1, B3); \ + B1 = _mm_xor_si128(B1, B4); \ + B4 = _mm_xor_si128(B4, all_ones); \ + B0 = B2; \ + B2 = B1; \ + B1 = B3; \ + B3 = B4; \ } while(0); -#define SBoxE4(B0, B1, B2, B3) \ - do { \ - __m128i B4 = B0; \ - B0 = _mm_or_si128(B0, B3); \ - B3 = _mm_xor_si128(B3, B1); \ - B1 = _mm_and_si128(B1, B4); \ - B4 = _mm_xor_si128(B4, B2); \ - B2 = _mm_xor_si128(B2, B3); \ - B3 = _mm_and_si128(B3, B0); \ - B4 = _mm_or_si128(B4, B1); \ - B3 = _mm_xor_si128(B3, B4); \ - B0 = _mm_xor_si128(B0, B1); \ - B4 = _mm_and_si128(B4, B0); \ - B1 = _mm_xor_si128(B1, B3); \ - B4 = _mm_xor_si128(B4, B2); \ - B1 = _mm_or_si128(B1, B0); \ - B1 = _mm_xor_si128(B1, B2); \ - B0 = _mm_xor_si128(B0, B3); \ - B2 = B1; \ - B1 = _mm_or_si128(B1, B3); \ - B1 = _mm_xor_si128(B1, B0); \ - B0 = B1; \ - B1 = B2; \ - B2 = B3; \ - B3 = B4; \ +#define SBoxE4(B0, B1, B2, B3) \ + do { \ + __m128i B4 = B0; \ + B0 = _mm_or_si128(B0, B3); \ + B3 = _mm_xor_si128(B3, B1); \ + B1 = _mm_and_si128(B1, B4); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = _mm_xor_si128(B2, B3); \ + B3 = _mm_and_si128(B3, B0); \ + B4 = _mm_or_si128(B4, B1); \ + B3 = _mm_xor_si128(B3, B4); \ + B0 = _mm_xor_si128(B0, B1); \ + B4 = _mm_and_si128(B4, B0); \ + B1 = _mm_xor_si128(B1, B3); \ + B4 = _mm_xor_si128(B4, B2); \ + B1 = _mm_or_si128(B1, B0); \ + B1 = _mm_xor_si128(B1, B2); \ + B0 = _mm_xor_si128(B0, B3); \ + B2 = B1; \ + B1 = _mm_or_si128(B1, B3); \ + B0 = _mm_xor_si128(B0, B1); \ + B1 = B2; \ + B2 = B3; \ + B3 = B4; \ } while(0); -#define SBoxE5(B0, B1, B2, B3) \ - do { \ - B1 = _mm_xor_si128(B1, B3); \ - B3 = _mm_andnot_si128(B3, _mm_set1_epi8(0xFF)); \ - B2 = _mm_xor_si128(B2, B3); \ - B3 = _mm_xor_si128(B3, B0); \ - __m128i B4 = B1; \ - B1 = _mm_and_si128(B1, B3); \ - B1 = _mm_xor_si128(B1, B2); \ - B4 = _mm_xor_si128(B4, B3); \ - B0 = _mm_xor_si128(B0, B4); \ - B2 = _mm_and_si128(B2, B4); \ - B2 = _mm_xor_si128(B2, B0); \ - B0 = _mm_and_si128(B0, B1); \ - B3 = _mm_xor_si128(B3, B0); \ - B4 = _mm_or_si128(B4, B1); \ - B4 = _mm_xor_si128(B4, B0); \ - B0 = _mm_or_si128(B0, B3); \ - B0 = _mm_xor_si128(B0, B2); \ - B2 = _mm_and_si128(B2, B3); \ - B0 = _mm_andnot_si128(B0, _mm_set1_epi8(0xFF)); \ - B4 = _mm_xor_si128(B4, B2); \ - B2 = B0; \ - B0 = B1; \ - B1 = B4; \ +#define SBoxE5(B0, B1, B2, B3) \ + do { \ + B1 = _mm_xor_si128(B1, B3); \ + B3 = _mm_xor_si128(B3, all_ones); \ + B2 = _mm_xor_si128(B2, B3); \ + B3 = _mm_xor_si128(B3, B0); \ + __m128i B4 = B1; \ + B1 = _mm_and_si128(B1, B3); \ + B1 = _mm_xor_si128(B1, B2); \ + B4 = _mm_xor_si128(B4, B3); \ + B0 = _mm_xor_si128(B0, B4); \ + B2 = _mm_and_si128(B2, B4); \ + B2 = _mm_xor_si128(B2, B0); \ + B0 = _mm_and_si128(B0, B1); \ + B3 = _mm_xor_si128(B3, B0); \ + B4 = _mm_or_si128(B4, B1); \ + B4 = _mm_xor_si128(B4, B0); \ + B0 = _mm_or_si128(B0, B3); \ + B0 = _mm_xor_si128(B0, B2); \ + B2 = _mm_and_si128(B2, B3); \ + B0 = _mm_xor_si128(B0, all_ones); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = B0; \ + B0 = B1; \ + B1 = B4; \ } while(0); -#define SBoxE6(B0, B1, B2, B3) \ - do { \ - B0 = _mm_xor_si128(B0, B1); \ - B1 = _mm_xor_si128(B1, B3); \ - B3 = _mm_andnot_si128(B3, _mm_set1_epi8(0xFF)); \ - __m128i B4 = B1; \ - B1 = _mm_and_si128(B1, B0); \ - B2 = _mm_xor_si128(B2, B3); \ - B1 = _mm_xor_si128(B1, B2); \ - B2 = _mm_or_si128(B2, B4); \ - B4 = _mm_xor_si128(B4, B3); \ - B3 = _mm_and_si128(B3, B1); \ - B3 = _mm_xor_si128(B3, B0); \ - B4 = _mm_xor_si128(B4, B1); \ - B4 = _mm_xor_si128(B4, B2); \ - B2 = _mm_xor_si128(B2, B0); \ - B0 = _mm_and_si128(B0, B3); \ - B2 = _mm_andnot_si128(B2, _mm_set1_epi8(0xFF)); \ - B0 = _mm_xor_si128(B0, B4); \ - B4 = _mm_or_si128(B4, B3); \ - B4 = _mm_xor_si128(B4, B2); \ - B2 = B0; \ - B0 = B1; \ - B1 = B3; \ - B3 = B4; \ +#define SBoxE6(B0, B1, B2, B3) \ + do { \ + B0 = _mm_xor_si128(B0, B1); \ + B1 = _mm_xor_si128(B1, B3); \ + B3 = _mm_xor_si128(B3, all_ones); \ + __m128i B4 = B1; \ + B1 = _mm_and_si128(B1, B0); \ + B2 = _mm_xor_si128(B2, B3); \ + B1 = _mm_xor_si128(B1, B2); \ + B2 = _mm_or_si128(B2, B4); \ + B4 = _mm_xor_si128(B4, B3); \ + B3 = _mm_and_si128(B3, B1); \ + B3 = _mm_xor_si128(B3, B0); \ + B4 = _mm_xor_si128(B4, B1); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = _mm_xor_si128(B2, B0); \ + B0 = _mm_and_si128(B0, B3); \ + B2 = _mm_xor_si128(B2, all_ones); \ + B0 = _mm_xor_si128(B0, B4); \ + B4 = _mm_or_si128(B4, B3); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = B0; \ + B0 = B1; \ + B1 = B3; \ + B3 = B4; \ } while(0); -#define SBoxE7(B0, B1, B2, B3) \ - do { \ - B2 = _mm_andnot_si128(B2, _mm_set1_epi8(0xFF)); \ - __m128i B4 = B3; \ - B3 = _mm_and_si128(B3, B0); \ - B0 = _mm_xor_si128(B0, B4); \ - B3 = _mm_xor_si128(B3, B2); \ - B2 = _mm_or_si128(B2, B4); \ - B1 = _mm_xor_si128(B1, B3); \ - B2 = _mm_xor_si128(B2, B0); \ - B0 = _mm_or_si128(B0, B1); \ - B2 = _mm_xor_si128(B2, B1); \ - B4 = _mm_xor_si128(B4, B0); \ - B0 = _mm_or_si128(B0, B3); \ - B0 = _mm_xor_si128(B0, B2); \ - B4 = _mm_xor_si128(B4, B3); \ - B4 = _mm_xor_si128(B4, B0); \ - B3 = _mm_andnot_si128(B3, _mm_set1_epi8(0xFF)); \ - B2 = _mm_and_si128(B2, B4); \ - B3 = _mm_xor_si128(B3, B2); \ - B2 = B4; \ +#define SBoxE7(B0, B1, B2, B3) \ + do { \ + B2 = _mm_xor_si128(B2, all_ones); \ + __m128i B4 = B3; \ + B3 = _mm_and_si128(B3, B0); \ + B0 = _mm_xor_si128(B0, B4); \ + B3 = _mm_xor_si128(B3, B2); \ + B2 = _mm_or_si128(B2, B4); \ + B1 = _mm_xor_si128(B1, B3); \ + B2 = _mm_xor_si128(B2, B0); \ + B0 = _mm_or_si128(B0, B1); \ + B2 = _mm_xor_si128(B2, B1); \ + B4 = _mm_xor_si128(B4, B0); \ + B0 = _mm_or_si128(B0, B3); \ + B0 = _mm_xor_si128(B0, B2); \ + B4 = _mm_xor_si128(B4, B3); \ + B4 = _mm_xor_si128(B4, B0); \ + B3 = _mm_xor_si128(B3, all_ones); \ + B2 = _mm_and_si128(B2, B4); \ + B3 = _mm_xor_si128(B3, B2); \ + B2 = B4; \ } while(0); -#define SBoxE8(B0, B1, B2, B3) \ - do { \ - __m128i B4 = B1; \ - B1 = _mm_or_si128(B1, B2); \ - B1 = _mm_xor_si128(B1, B3); \ - B4 = _mm_xor_si128(B4, B2); \ - B2 = _mm_xor_si128(B2, B1); \ - B3 = _mm_or_si128(B3, B4); \ - B3 = _mm_and_si128(B3, B0); \ - B4 = _mm_xor_si128(B4, B2); \ - B3 = _mm_xor_si128(B3, B1); \ - B1 = _mm_or_si128(B1, B4); \ - B1 = _mm_xor_si128(B1, B0); \ - B0 = _mm_or_si128(B0, B4); \ - B0 = _mm_xor_si128(B0, B2); \ - B1 = _mm_xor_si128(B1, B4); \ - B2 = _mm_xor_si128(B2, B1); \ - B1 = _mm_and_si128(B1, B0); \ - B1 = _mm_xor_si128(B1, B4); \ - B2 = _mm_andnot_si128(B2, _mm_set1_epi8(0xFF)); \ - B2 = _mm_or_si128(B2, B0); \ - B4 = _mm_xor_si128(B4, B2); \ - B2 = B1; \ - B1 = B3; \ - B3 = B0; \ - B0 = B4; \ +#define SBoxE8(B0, B1, B2, B3) \ + do { \ + __m128i B4 = B1; \ + B1 = _mm_or_si128(B1, B2); \ + B1 = _mm_xor_si128(B1, B3); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = _mm_xor_si128(B2, B1); \ + B3 = _mm_or_si128(B3, B4); \ + B3 = _mm_and_si128(B3, B0); \ + B4 = _mm_xor_si128(B4, B2); \ + B3 = _mm_xor_si128(B3, B1); \ + B1 = _mm_or_si128(B1, B4); \ + B1 = _mm_xor_si128(B1, B0); \ + B0 = _mm_or_si128(B0, B4); \ + B0 = _mm_xor_si128(B0, B2); \ + B1 = _mm_xor_si128(B1, B4); \ + B2 = _mm_xor_si128(B2, B1); \ + B1 = _mm_and_si128(B1, B0); \ + B1 = _mm_xor_si128(B1, B4); \ + B2 = _mm_xor_si128(B2, all_ones); \ + B2 = _mm_or_si128(B2, B0); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = B1; \ + B1 = B3; \ + B3 = B0; \ + B0 = B4; \ } while(0); #endif -- cgit v1.2.3 From fdba61bb05f26f8ed979543b8ee9cfab96295800 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 12 Aug 2009 15:20:34 +0000 Subject: Add SSE2 Serpent decryption --- src/block/serpent_sse2/serp_sse2.cpp | 91 +++++++++++++- src/block/serpent_sse2/serp_sse2_sbox.h | 217 ++++++++++++++++++++++++++++++++ 2 files changed, 307 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/block/serpent_sse2/serp_sse2.cpp b/src/block/serpent_sse2/serp_sse2.cpp index 5ce7d8f47..a3319afec 100644 --- a/src/block/serpent_sse2/serp_sse2.cpp +++ b/src/block/serpent_sse2/serp_sse2.cpp @@ -24,11 +24,14 @@ namespace { } while(0); /* -* Serpent's linear transformation +* Serpent's linear transformations */ #define rotate_left_m128(vec, rot) \ _mm_or_si128(_mm_slli_epi32(vec, rot), _mm_srli_epi32(vec, 32-rot)) +#define rotate_right_m128(vec, rot) \ + _mm_or_si128(_mm_srli_epi32(vec, rot), _mm_slli_epi32(vec, 32-rot)) + #define transform(B0, B1, B2, B3) \ do { \ B0 = rotate_left_m128(B0, 13); \ @@ -43,6 +46,20 @@ namespace { B2 = rotate_left_m128(B2, 22); \ } while(0); +#define i_transform(B0, B1, B2, B3) \ + do { \ + B2 = rotate_right_m128(B2, 22); \ + B0 = rotate_right_m128(B0, 5); \ + B2 = _mm_xor_si128(B2, _mm_xor_si128(B3, _mm_slli_epi32(B1, 7))); \ + B0 = _mm_xor_si128(B0, _mm_xor_si128(B1, B3)); \ + B3 = rotate_right_m128(B3, 7); \ + B1 = rotate_right_m128(B1, 1); \ + B3 = _mm_xor_si128(B3, _mm_xor_si128(B2, _mm_slli_epi32(B0, 3))); \ + B1 = _mm_xor_si128(B1, _mm_xor_si128(B0, B2)); \ + B2 = rotate_right_m128(B2, 3); \ + B0 = rotate_right_m128(B0, 13); \ + } while(0); + /* * 4x4 SSE2 integer matrix transpose */ @@ -122,6 +139,70 @@ void serpent_encrypt_4(const byte in[64], _mm_storeu_si128(out_mm + 3, B3); } +/* +* SSE2 Serpent Decryption of 4 blocks in parallel +*/ +void serpent_decrypt_4(const byte in[64], + byte out[64], + const u32bit keys_32[132]) + { + const __m128i all_ones = _mm_set1_epi8(0xFF); + + const __m128i* keys = (const __m128i*)(keys_32); + __m128i* out_mm = (__m128i*)(out); + __m128i* in_mm = (__m128i*)(in); + + __m128i B0 = _mm_loadu_si128(in_mm); + __m128i B1 = _mm_loadu_si128(in_mm + 1); + __m128i B2 = _mm_loadu_si128(in_mm + 2); + __m128i B3 = _mm_loadu_si128(in_mm + 3); + + 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); + + transpose(B0, B1, B2, B3); + + _mm_storeu_si128(out_mm , B0); + _mm_storeu_si128(out_mm + 1, B1); + _mm_storeu_si128(out_mm + 2, B2); + _mm_storeu_si128(out_mm + 3, B3); + } + } /* @@ -150,6 +231,14 @@ void Serpent_SSE2::encrypt_n(const byte in[], byte out[], u32bit blocks) const */ void Serpent_SSE2::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; + } + for(u32bit i = 0; i != blocks; ++i) { Serpent::decrypt_n(in, out, 1); diff --git a/src/block/serpent_sse2/serp_sse2_sbox.h b/src/block/serpent_sse2/serp_sse2_sbox.h index 1660643ad..40c552e87 100644 --- a/src/block/serpent_sse2/serp_sse2_sbox.h +++ b/src/block/serpent_sse2/serp_sse2_sbox.h @@ -214,4 +214,221 @@ B0 = B4; \ } while(0); +#define SBoxD1(B0, B1, B2, B3) \ + do \ + { \ + B2 = _mm_xor_si128(B2, all_ones); \ + __m128i B4 = B1; \ + B1 = _mm_or_si128(B1, B0); \ + B4 = _mm_xor_si128(B4, all_ones); \ + B1 = _mm_xor_si128(B1, B2); \ + B2 = _mm_or_si128(B2, B4); \ + B1 = _mm_xor_si128(B1, B3); \ + B0 = _mm_xor_si128(B0, B4); \ + B2 = _mm_xor_si128(B2, B0); \ + B0 = _mm_and_si128(B0, B3); \ + B4 = _mm_xor_si128(B4, B0); \ + B0 = _mm_or_si128(B0, B1); \ + B0 = _mm_xor_si128(B0, B2); \ + B3 = _mm_xor_si128(B3, B4); \ + B2 = _mm_xor_si128(B2, B1); \ + B3 = _mm_xor_si128(B3, B0); \ + B3 = _mm_xor_si128(B3, B1); \ + B2 = _mm_and_si128(B2, B3); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxD2(B0, B1, B2, B3) \ + do \ + { \ + __m128i B4 = B1; \ + B1 = _mm_xor_si128(B1, B3); \ + B3 = _mm_and_si128(B3, B1); \ + B4 = _mm_xor_si128(B4, B2); \ + B3 = _mm_xor_si128(B3, B0); \ + B0 = _mm_or_si128(B0, B1); \ + B2 = _mm_xor_si128(B2, B3); \ + B0 = _mm_xor_si128(B0, B4); \ + B0 = _mm_or_si128(B0, B2); \ + B1 = _mm_xor_si128(B1, B3); \ + B0 = _mm_xor_si128(B0, B1); \ + B1 = _mm_or_si128(B1, B3); \ + B1 = _mm_xor_si128(B1, B0); \ + B4 = _mm_xor_si128(B4, all_ones); \ + B4 = _mm_xor_si128(B4, B1); \ + B1 = _mm_or_si128(B1, B0); \ + B1 = _mm_xor_si128(B1, B0); \ + B1 = _mm_or_si128(B1, B4); \ + B3 = _mm_xor_si128(B3, B1); \ + B1 = B0; \ + B0 = B4; \ + B4 = B2; \ + B2 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxD3(B0, B1, B2, B3) \ + do \ + { \ + B2 = _mm_xor_si128(B2, B3); \ + B3 = _mm_xor_si128(B3, B0); \ + __m128i B4 = B3; \ + B3 = _mm_and_si128(B3, B2); \ + B3 = _mm_xor_si128(B3, B1); \ + B1 = _mm_or_si128(B1, B2); \ + B1 = _mm_xor_si128(B1, B4); \ + B4 = _mm_and_si128(B4, B3); \ + B2 = _mm_xor_si128(B2, B3); \ + B4 = _mm_and_si128(B4, B0); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = _mm_and_si128(B2, B1); \ + B2 = _mm_or_si128(B2, B0); \ + B3 = _mm_xor_si128(B3, all_ones); \ + B2 = _mm_xor_si128(B2, B3); \ + B0 = _mm_xor_si128(B0, B3); \ + B0 = _mm_and_si128(B0, B1); \ + B3 = _mm_xor_si128(B3, B4); \ + B3 = _mm_xor_si128(B3, B0); \ + B0 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxD4(B0, B1, B2, B3) \ + do \ + { \ + __m128i B4 = B2; \ + B2 = _mm_xor_si128(B2, B1); \ + B0 = _mm_xor_si128(B0, B2); \ + B4 = _mm_and_si128(B4, B2); \ + B4 = _mm_xor_si128(B4, B0); \ + B0 = _mm_and_si128(B0, B1); \ + B1 = _mm_xor_si128(B1, B3); \ + B3 = _mm_or_si128(B3, B4); \ + B2 = _mm_xor_si128(B2, B3); \ + B0 = _mm_xor_si128(B0, B3); \ + B1 = _mm_xor_si128(B1, B4); \ + B3 = _mm_and_si128(B3, B2); \ + B3 = _mm_xor_si128(B3, B1); \ + B1 = _mm_xor_si128(B1, B0); \ + B1 = _mm_or_si128(B1, B2); \ + B0 = _mm_xor_si128(B0, B3); \ + B1 = _mm_xor_si128(B1, B4); \ + B0 = _mm_xor_si128(B0, B1); \ + B4 = B0; \ + B0 = B2; \ + B2 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxD5(B0, B1, B2, B3) \ + do \ + { \ + __m128i B4 = B2; \ + B2 = _mm_and_si128(B2, B3); \ + B2 = _mm_xor_si128(B2, B1); \ + B1 = _mm_or_si128(B1, B3); \ + B1 = _mm_and_si128(B1, B0); \ + B4 = _mm_xor_si128(B4, B2); \ + B4 = _mm_xor_si128(B4, B1); \ + B1 = _mm_and_si128(B1, B2); \ + B0 = _mm_xor_si128(B0, all_ones); \ + B3 = _mm_xor_si128(B3, B4); \ + B1 = _mm_xor_si128(B1, B3); \ + B3 = _mm_and_si128(B3, B0); \ + B3 = _mm_xor_si128(B3, B2); \ + B0 = _mm_xor_si128(B0, B1); \ + B2 = _mm_and_si128(B2, B0); \ + B3 = _mm_xor_si128(B3, B0); \ + B2 = _mm_xor_si128(B2, B4); \ + B2 = _mm_or_si128(B2, B3); \ + B3 = _mm_xor_si128(B3, B0); \ + B2 = _mm_xor_si128(B2, B1); \ + B1 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxD6(B0, B1, B2, B3) \ + do \ + { \ + B1 = _mm_xor_si128(B1, all_ones); \ + __m128i B4 = B3; \ + B2 = _mm_xor_si128(B2, B1); \ + B3 = _mm_or_si128(B3, B0); \ + B3 = _mm_xor_si128(B3, B2); \ + B2 = _mm_or_si128(B2, B1); \ + B2 = _mm_and_si128(B2, B0); \ + B4 = _mm_xor_si128(B4, B3); \ + B2 = _mm_xor_si128(B2, B4); \ + B4 = _mm_or_si128(B4, B0); \ + B4 = _mm_xor_si128(B4, B1); \ + B1 = _mm_and_si128(B1, B2); \ + B1 = _mm_xor_si128(B1, B3); \ + B4 = _mm_xor_si128(B4, B2); \ + B3 = _mm_and_si128(B3, B4); \ + B4 = _mm_xor_si128(B4, B1); \ + B3 = _mm_xor_si128(B3, B4); \ + B4 = _mm_xor_si128(B4, all_ones); \ + B3 = _mm_xor_si128(B3, B0); \ + B0 = B1; \ + B1 = B4; \ + B4 = B3; \ + B3 = B2; \ + B2 = B4; \ + } while(0); + +#define SBoxD7(B0, B1, B2, B3) \ + do \ + { \ + B0 = _mm_xor_si128(B0, B2); \ + __m128i B4 = B2; \ + B2 = _mm_and_si128(B2, B0); \ + B4 = _mm_xor_si128(B4, B3); \ + B2 = _mm_xor_si128(B2, all_ones); \ + B3 = _mm_xor_si128(B3, B1); \ + B2 = _mm_xor_si128(B2, B3); \ + B4 = _mm_or_si128(B4, B0); \ + B0 = _mm_xor_si128(B0, B2); \ + B3 = _mm_xor_si128(B3, B4); \ + B4 = _mm_xor_si128(B4, B1); \ + B1 = _mm_and_si128(B1, B3); \ + B1 = _mm_xor_si128(B1, B0); \ + B0 = _mm_xor_si128(B0, B3); \ + B0 = _mm_or_si128(B0, B2); \ + B3 = _mm_xor_si128(B3, B1); \ + B4 = _mm_xor_si128(B4, B0); \ + B0 = B1; \ + B1 = B2; \ + B2 = B4; \ + } while(0); + +#define SBoxD8(B0, B1, B2, B3) \ + do \ + { \ + __m128i B4 = B2; \ + B2 = _mm_xor_si128(B2, B0); \ + B0 = _mm_and_si128(B0, B3); \ + B4 = _mm_or_si128(B4, B3); \ + B2 = _mm_xor_si128(B2, all_ones); \ + B3 = _mm_xor_si128(B3, B1); \ + B1 = _mm_or_si128(B1, B0); \ + B0 = _mm_xor_si128(B0, B2); \ + B2 = _mm_and_si128(B2, B4); \ + B3 = _mm_and_si128(B3, B4); \ + B1 = _mm_xor_si128(B1, B2); \ + B2 = _mm_xor_si128(B2, B0); \ + B0 = _mm_or_si128(B0, B2); \ + B4 = _mm_xor_si128(B4, B1); \ + B0 = _mm_xor_si128(B0, B3); \ + B3 = _mm_xor_si128(B3, B4); \ + B4 = _mm_or_si128(B4, B0); \ + B3 = _mm_xor_si128(B3, B2); \ + B4 = _mm_xor_si128(B4, B2); \ + B2 = B1; \ + B1 = B0; \ + B0 = B3; \ + B3 = B4; \ + } while(0); + #endif -- cgit v1.2.3 From 1c9b4fda79951b1d0cd3c49ad8db8549cf9d9444 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 12 Aug 2009 18:19:39 +0000 Subject: For handling the last few blocks in Serpent_SSE2, invoke encrypt_n with however many blocks remain, rather than looping calling encrypt_n with a block size of 1 each time. --- src/block/serpent_sse2/serp_sse2.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/block/serpent_sse2/serp_sse2.cpp b/src/block/serpent_sse2/serp_sse2.cpp index a3319afec..c51bb69ab 100644 --- a/src/block/serpent_sse2/serp_sse2.cpp +++ b/src/block/serpent_sse2/serp_sse2.cpp @@ -218,12 +218,7 @@ void Serpent_SSE2::encrypt_n(const byte in[], byte out[], u32bit blocks) const blocks -= 4; } - for(u32bit i = 0; i != blocks; ++i) - { - Serpent::encrypt_n(in, out, 1); - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } + Serpent::encrypt_n(in, out, blocks); } /* @@ -239,12 +234,7 @@ void Serpent_SSE2::decrypt_n(const byte in[], byte out[], u32bit blocks) const blocks -= 4; } - for(u32bit i = 0; i != blocks; ++i) - { - Serpent::decrypt_n(in, out, 1); - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } + Serpent::decrypt_n(in, out, blocks); } } -- cgit v1.2.3 From 690e9fc77872f253004c37d4c6a0707f1a3f1856 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 12 Aug 2009 18:38:15 +0000 Subject: In benchmark.cpp, use encrypt_n when benchmarking block ciphers --- src/benchmark/benchmark.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/benchmark/benchmark.cpp b/src/benchmark/benchmark.cpp index 01e3b94f3..3bbc1f883 100644 --- a/src/benchmark/benchmark.cpp +++ b/src/benchmark/benchmark.cpp @@ -57,8 +57,7 @@ bench_block_cipher(BlockCipher* block_cipher, while(nanoseconds_used < nanoseconds_max) { - for(u32bit i = 0; i != in_blocks; ++i) - block_cipher->encrypt(buf + block_cipher->BLOCK_SIZE * i); + block_cipher->encrypt_n(buf, buf, in_blocks); ++reps; nanoseconds_used = timer.clock() - start; -- cgit v1.2.3 From 921ef0147666aca06693f04155e590e16dde9726 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 12 Aug 2009 20:44:09 +0000 Subject: Use a much faster counter increment system, noticable speedups (~15%) for both Serpent and AES-128 in CTR mode. --- src/modes/ctr/ctr.cpp | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/modes/ctr/ctr.cpp b/src/modes/ctr/ctr.cpp index a3476c474..d458d7848 100644 --- a/src/modes/ctr/ctr.cpp +++ b/src/modes/ctr/ctr.cpp @@ -65,21 +65,24 @@ std::string CTR_BE::name() const */ void CTR_BE::set_iv(const InitializationVector& iv) { - if(iv.length() != cipher->BLOCK_SIZE) + const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; + + if(iv.length() != BLOCK_SIZE) throw Invalid_IV_Length(name(), iv.length()); enc_buffer.clear(); position = 0; - for(u32bit i = 0; i != PARALLEL_BLOCKS; ++i) + counter.copy(0, iv.begin(), iv.length()); + + for(u32bit i = 1; i != PARALLEL_BLOCKS; ++i) { - counter.copy(i*cipher->BLOCK_SIZE, iv.begin(), iv.length()); + counter.copy(i*BLOCK_SIZE, + counter.begin() + (i-1)*BLOCK_SIZE, BLOCK_SIZE); - // FIXME: this is stupid - for(u32bit j = 0; j != i; ++j) - for(s32bit k = cipher->BLOCK_SIZE - 1; k >= 0; --k) - if(++counter[i*cipher->BLOCK_SIZE+k]) - break; + for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j) + if(++counter[i*BLOCK_SIZE+j]) + break; } cipher->encrypt_n(counter, enc_buffer, PARALLEL_BLOCKS); @@ -122,19 +125,17 @@ void CTR_BE::increment_counter() { for(u32bit i = 0; i != PARALLEL_BLOCKS; ++i) { - // FIXME: Can do it in a single loop - /* - for(u32bit j = 1; j != cipher->BLOCK_SIZE; ++j) - { - byte carry = 0; - byte z = counter[(i+1)*cipher->BLOCK_SIZE-1] + PARALLEL_BLOCKS; - - if( - */ - for(u32bit j = 0; j != PARALLEL_BLOCKS; ++j) - for(s32bit k = cipher->BLOCK_SIZE - 1; k >= 0; --k) - if(++counter[i*cipher->BLOCK_SIZE+k]) + byte* this_ctr = counter + i*cipher->BLOCK_SIZE; + + byte last_byte = this_ctr[cipher->BLOCK_SIZE-1]; + last_byte += PARALLEL_BLOCKS; + + if(this_ctr[cipher->BLOCK_SIZE-1] > last_byte) + for(s32bit j = cipher->BLOCK_SIZE - 2; j >= 0; --j) + if(++this_ctr[j]) break; + + this_ctr[cipher->BLOCK_SIZE-1] = last_byte; } cipher->encrypt_n(counter, enc_buffer, PARALLEL_BLOCKS); -- cgit v1.2.3 From 5a1329ff7d80349598e50a1ec63abb5334ddc2ac Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 13 Aug 2009 18:32:38 +0000 Subject: Include basefilt.h in filters.h --- src/filters/filters.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/filters/filters.h b/src/filters/filters.h index 26de6e63c..964be0bd8 100644 --- a/src/filters/filters.h +++ b/src/filters/filters.h @@ -14,8 +14,10 @@ #include #include +#include #include #include + #include #if defined(BOTAN_HAS_BASE64_CODEC) -- cgit v1.2.3 From 6897292463197ed6880d91e76c4ee13f624905c3 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 27 Aug 2009 18:14:55 +0000 Subject: Instead of each SSE2 implementation specifying which compilers + CPUs it works on, have sse2_eng rely on a specific compiler/arch; each sse2 impl depends on the engine anyway, so they will only be loaded if OK. --- src/block/serpent_sse2/info.txt | 12 ------------ src/engine/sse2_eng/info.txt | 9 ++++++++- src/hash/sha1_sse2/info.txt | 12 ------------ 3 files changed, 8 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/block/serpent_sse2/info.txt b/src/block/serpent_sse2/info.txt index 09733e98f..b00ab6e88 100644 --- a/src/block/serpent_sse2/info.txt +++ b/src/block/serpent_sse2/info.txt @@ -10,18 +10,6 @@ serp_sse2.h serp_sse2_sbox.h - -pentium-m -pentium4 -prescott -amd64 - - - -gcc -icc - - serpent sse2_eng diff --git a/src/engine/sse2_eng/info.txt b/src/engine/sse2_eng/info.txt index 6242c7fee..7595b8eb5 100644 --- a/src/engine/sse2_eng/info.txt +++ b/src/engine/sse2_eng/info.txt @@ -10,6 +10,13 @@ eng_sse2.h -ia32 +pentium-m +pentium4 +prescott amd64 + + +gcc +icc + diff --git a/src/hash/sha1_sse2/info.txt b/src/hash/sha1_sse2/info.txt index b8d693b70..995c2513e 100644 --- a/src/hash/sha1_sse2/info.txt +++ b/src/hash/sha1_sse2/info.txt @@ -10,18 +10,6 @@ sha1_sse2.cpp sha1_sse2.h - -pentium-m -pentium4 -prescott -amd64 - - - -gcc -icc - - sha1 sse2_eng -- cgit v1.2.3 From 7c35179056ef9f223eb3ad4c20e16ed8f8540bbb Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 27 Aug 2009 18:15:12 +0000 Subject: Remove unneeded include in xtea.cpp --- src/block/xtea/xtea.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/block/xtea/xtea.cpp b/src/block/xtea/xtea.cpp index 0dba5f2be..77543e1e8 100644 --- a/src/block/xtea/xtea.cpp +++ b/src/block/xtea/xtea.cpp @@ -7,7 +7,6 @@ #include #include -#include namespace Botan { -- cgit v1.2.3 From de705485bccc89a695488ebe69b744433388bf21 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 31 Aug 2009 18:19:09 +0000 Subject: Hoist creation of buffer in Lion encrypt loop --- src/block/lion/lion.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/block/lion/lion.cpp b/src/block/lion/lion.cpp index bfff64b67..83c1e3aa3 100644 --- a/src/block/lion/lion.cpp +++ b/src/block/lion/lion.cpp @@ -16,10 +16,10 @@ namespace Botan { */ void Lion::encrypt_n(const byte in[], byte out[], u32bit blocks) const { + SecureVector buffer(LEFT_SIZE); + for(u32bit i = 0; i != blocks; ++i) { - SecureVector 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); @@ -42,10 +42,10 @@ void Lion::encrypt_n(const byte in[], byte out[], u32bit blocks) const */ void Lion::decrypt_n(const byte in[], byte out[], u32bit blocks) const { + SecureVector buffer(LEFT_SIZE); + for(u32bit i = 0; i != blocks; ++i) { - SecureVector 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); -- cgit v1.2.3 From 74d860bb2b35ee5184f77a1e3e2bb1b5b92cacd6 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 31 Aug 2009 18:37:43 +0000 Subject: Combine the 4 sbox calculations in the key schedule so that all four are computed in parallel. Not a huge win but slightly faster (which affects things like Lion when using Turing), most likely due to more available ILP --- src/stream/turing/turing.cpp | 48 +++++++++++++++++++++++--------------------- src/stream/turing/turing.h | 2 -- 2 files changed, 25 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/stream/turing/turing.cpp b/src/stream/turing/turing.cpp index b988568c3..1e2203480 100644 --- a/src/stream/turing/turing.cpp +++ b/src/stream/turing/turing.cpp @@ -217,25 +217,6 @@ u32bit Turing::fixedS(u32bit W) return W; } -/* -* Generate the expanded Turing Sbox tables -*/ -void Turing::gen_sbox(MemoryRegion& S, u32bit which, - const MemoryRegion& K) - { - for(u32bit j = 0; j != 256; ++j) - { - u32bit W = 0, C = j; - - for(u32bit k = 0; k < K.size(); ++k) - { - C = SBOX[get_byte(which, K[k]) ^ C]; - W ^= rotate_left(Q_BOX[C], k + 8*which); - } - S[j] = (W & rotate_right(0x00FFFFFF, 8*which)) | (C << (24 - 8*which)); - } - } - /* * Turing Key Schedule */ @@ -250,10 +231,31 @@ void Turing::key_schedule(const byte key[], u32bit length) PHT(K); - gen_sbox(S0, 0, K); - gen_sbox(S1, 1, K); - gen_sbox(S2, 2, K); - gen_sbox(S3, 3, K); + for(u32bit i = 0; i != 256; ++i) + { + u32bit W0 = 0, C0 = i; + u32bit W1 = 0, C1 = i; + u32bit W2 = 0, C2 = i; + u32bit W3 = 0, C3 = i; + + for(u32bit j = 0; j < K.size(); ++j) + { + C0 = SBOX[get_byte(0, K[j]) ^ C0]; + C1 = SBOX[get_byte(1, K[j]) ^ C1]; + C2 = SBOX[get_byte(2, K[j]) ^ C2]; + C3 = SBOX[get_byte(3, K[j]) ^ C3]; + + W0 ^= rotate_left(Q_BOX[C0], j); + W1 ^= rotate_left(Q_BOX[C1], j + 8); + W2 ^= rotate_left(Q_BOX[C2], j + 16); + W3 ^= rotate_left(Q_BOX[C3], j + 24); + } + + S0[i] = (W0 & 0x00FFFFFF) | (C0 << 24); + S1[i] = (W1 & 0xFF00FFFF) | (C1 << 16); + S2[i] = (W2 & 0xFFFF00FF) | (C2 << 8); + S3[i] = (W3 & 0xFFFFFF00) | C3; + } resync(0, 0); } diff --git a/src/stream/turing/turing.h b/src/stream/turing/turing.h index d48c1d8a8..455d3c612 100644 --- a/src/stream/turing/turing.h +++ b/src/stream/turing/turing.h @@ -29,8 +29,6 @@ class BOTAN_DLL Turing : public StreamCipher void generate(); static u32bit fixedS(u32bit); - static void gen_sbox(MemoryRegion&, u32bit, - const MemoryRegion&); static const u32bit Q_BOX[256]; static const byte SBOX[256]; -- cgit v1.2.3 From 8381ceca38f0eee44e893921cbd74fdb3014f7ba Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 31 Aug 2009 18:40:51 +0000 Subject: Add Rivest's package transform --- doc/log.txt | 2 + src/aont/info.txt | 17 +++++++ src/aont/package.cpp | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/aont/package.h | 45 ++++++++++++++++++ 4 files changed, 192 insertions(+) create mode 100644 src/aont/info.txt create mode 100644 src/aont/package.cpp create mode 100644 src/aont/package.h (limited to 'src') diff --git a/doc/log.txt b/doc/log.txt index 992829b39..a84e72d62 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -2,6 +2,8 @@ * 1.9.0-pre, 2009-??-?? - Add support for parallel invocation of block ciphers where possible - Add SSE2 implementation of Serpent + - Add Rivest's package transform (an all or nothing transform) + - Minor speedups to the Turing key schedule * 1.8.6, 2009-08-13 - Add Cryptobox, a set of simple password-based encryption routines diff --git a/src/aont/info.txt b/src/aont/info.txt new file mode 100644 index 000000000..a0387f358 --- /dev/null +++ b/src/aont/info.txt @@ -0,0 +1,17 @@ +realname "All or Nothing Transforms" + +define PACKAGE_TRANSFORM + +load_on auto + + +package.cpp +package.h + + + +block +ctr +rng +filters + diff --git a/src/aont/package.cpp b/src/aont/package.cpp new file mode 100644 index 000000000..6c6b56865 --- /dev/null +++ b/src/aont/package.cpp @@ -0,0 +1,128 @@ +/* +* Rivest's Package Tranform +* +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +namespace AllOrNothingTransform { + +void package(RandomNumberGenerator& rng, + BlockCipher* cipher, + const byte input[], u32bit input_len, + byte output[]) + { + if(!cipher->valid_keylength(cipher->BLOCK_SIZE)) + throw Invalid_Argument("AONT::package: Invalid cipher"); + + // The all-zero string which is used both as the CTR IV and as K0 + const std::string all_zeros(cipher->BLOCK_SIZE*2, '0'); + + SymmetricKey package_key(rng, cipher->BLOCK_SIZE); + + // takes ownership of cipher object + Keyed_Filter* ctr_mode = new CTR_BE(cipher, + package_key, + InitializationVector(all_zeros)); + + Pipe pipe(ctr_mode); + + pipe.process_msg(input, input_len); + pipe.read(output, pipe.remaining()); + + // Set K0 (the all zero key) + cipher->set_key(SymmetricKey(all_zeros)); + + SecureVector buf(cipher->BLOCK_SIZE); + + const u32bit blocks = + (input_len + cipher->BLOCK_SIZE - 1) / cipher->BLOCK_SIZE; + + byte* final_block = output + input_len; + clear_mem(final_block, cipher->BLOCK_SIZE); + + // XOR the hash blocks into the final block + for(u32bit i = 0; i != blocks; ++i) + { + u32bit left = std::min(cipher->BLOCK_SIZE, + input_len - cipher->BLOCK_SIZE * i); + + buf.clear(); + copy_mem(&buf[0], output + cipher->BLOCK_SIZE * i, left); + + for(u32bit j = 0; j != 4; ++j) + buf[cipher->BLOCK_SIZE - 1 - j] ^= get_byte(3-j, i); + + cipher->encrypt(buf); + + xor_buf(final_block, buf, cipher->BLOCK_SIZE); + } + + // XOR the random package key into the final block + xor_buf(final_block, package_key.begin(), cipher->BLOCK_SIZE); + } + +void unpackage(BlockCipher* cipher, + const byte input[], u32bit input_len, + byte output[]) + { + if(!cipher->valid_keylength(cipher->BLOCK_SIZE)) + throw Invalid_Argument("AONT::unpackage: Invalid cipher"); + + if(input_len < cipher->BLOCK_SIZE) + throw Invalid_Argument("AONT::unpackage: Input too short"); + + // The all-zero string which is used both as the CTR IV and as K0 + const std::string all_zeros(cipher->BLOCK_SIZE*2, '0'); + + cipher->set_key(SymmetricKey(all_zeros)); + + SecureVector package_key(cipher->BLOCK_SIZE); + SecureVector buf(cipher->BLOCK_SIZE); + + // Copy the package key (masked with the block hashes) + copy_mem(&package_key[0], + input + (input_len - cipher->BLOCK_SIZE), + cipher->BLOCK_SIZE); + + const u32bit blocks = ((input_len - 1) / cipher->BLOCK_SIZE); + + // XOR the blocks into the package key bits + for(u32bit i = 0; i != blocks; ++i) + { + u32bit left = std::min(cipher->BLOCK_SIZE, + input_len - cipher->BLOCK_SIZE * (i+1)); + + buf.clear(); + copy_mem(&buf[0], input + cipher->BLOCK_SIZE * i, left); + + for(u32bit j = 0; j != 4; ++j) + buf[cipher->BLOCK_SIZE - 1 - j] ^= get_byte(3-j, i); + + cipher->encrypt(buf); + + xor_buf(&package_key[0], buf, cipher->BLOCK_SIZE); + } + + // takes ownership of cipher object + Pipe pipe(new CTR_BE(cipher, + SymmetricKey(package_key), + InitializationVector(all_zeros))); + + pipe.process_msg(input, input_len - cipher->BLOCK_SIZE); + + pipe.read(output, pipe.remaining()); + } + +} + +} diff --git a/src/aont/package.h b/src/aont/package.h new file mode 100644 index 000000000..35d2a23fc --- /dev/null +++ b/src/aont/package.h @@ -0,0 +1,45 @@ +/* +* Rivest's Package Tranform +* +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include + +namespace Botan { + +namespace AllOrNothingTransform { + +/** +* Rivest's Package Tranform +* @arg rng the random number generator to use +* @arg cipher the block cipher to use +* @arg input the input data buffer +* @arg input_len the length of the input data in bytes +* @arg output the output data buffer (must be at least +* input_len + cipher->BLOCK_SIZE bytes long) +*/ +void package(RandomNumberGenerator& rng, + BlockCipher* cipher, + const byte input[], u32bit input_len, + byte output[]); + +/** +* Rivest's Package Tranform (Inversion) +* @arg rng the random number generator to use +* @arg cipher the block cipher to use +* @arg input the input data buffer +* @arg input_len the length of the input data in bytes +* @arg output the output data buffer (must be at least +* input_len - cipher->BLOCK_SIZE bytes long) +*/ +void unpackage(BlockCipher* cipher, + const byte input[], u32bit input_len, + byte output[]); + +} + +} -- cgit v1.2.3 From f7595eeae651ff36709793989fd1688303915f5a Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 4 Sep 2009 16:11:40 +0000 Subject: According to the Linux sources, S/390 and PowerPC can both do unaligned memory accesses. Since this can be a pretty big win, enable it for them. The m68k apparently also can, except in its (modern) Coldfire version, but it's always big endian so mark that as such. --- src/build-data/arch/m68k | 5 +++++ src/build-data/arch/ppc | 1 + src/build-data/arch/s390 | 3 +++ src/build-data/arch/s390x | 3 +++ 4 files changed, 12 insertions(+) (limited to 'src') diff --git a/src/build-data/arch/m68k b/src/build-data/arch/m68k index 27f246abc..759a3dac1 100644 --- a/src/build-data/arch/m68k +++ b/src/build-data/arch/m68k @@ -2,6 +2,11 @@ realname "Motorola 680x0" default_submodel 68020 +endian big + +# Except for Coldfire +#unaligned ok + 680x0 68k diff --git a/src/build-data/arch/ppc b/src/build-data/arch/ppc index 16112f389..e2dfa6ea2 100644 --- a/src/build-data/arch/ppc +++ b/src/build-data/arch/ppc @@ -1,6 +1,7 @@ realname "PowerPC" endian big +unaligned ok default_submodel ppc604 diff --git a/src/build-data/arch/s390 b/src/build-data/arch/s390 index 392f51397..312b262c4 100644 --- a/src/build-data/arch/s390 +++ b/src/build-data/arch/s390 @@ -2,6 +2,9 @@ realname "S/390 31-bit" default_submodel s390 +endian big +unaligned ok + s390 diff --git a/src/build-data/arch/s390x b/src/build-data/arch/s390x index 49fb0bda7..9fe6bd615 100644 --- a/src/build-data/arch/s390x +++ b/src/build-data/arch/s390x @@ -2,6 +2,9 @@ realname "S/390 64-bit" default_submodel s390x +endian big +unaligned ok + s390x -- cgit v1.2.3 From 0a7e8ead1a85f7003b729742d795730f2b782116 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 8 Sep 2009 15:22:31 +0000 Subject: Add *s before comment lines in file headers --- src/algo_factory/algo_factory.cpp | 4 ++-- src/libstate/scan_name.cpp | 4 ++-- src/libstate/scan_name.h | 4 ++-- src/mac/mac.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/algo_factory/algo_factory.cpp b/src/algo_factory/algo_factory.cpp index 269c58c3b..3523b19d4 100644 --- a/src/algo_factory/algo_factory.cpp +++ b/src/algo_factory/algo_factory.cpp @@ -1,6 +1,6 @@ /* -Algorithm Factory -(C) 2008 Jack Lloyd +* Algorithm Factory +* (C) 2008 Jack Lloyd * * Distributed under the terms of the Botan license */ diff --git a/src/libstate/scan_name.cpp b/src/libstate/scan_name.cpp index ef771871d..88992d66e 100644 --- a/src/libstate/scan_name.cpp +++ b/src/libstate/scan_name.cpp @@ -1,6 +1,6 @@ /** -SCAN Name Abstraction -(C) 2008 Jack Lloyd +* SCAN Name Abstraction +* (C) 2008 Jack Lloyd * * Distributed under the terms of the Botan license */ diff --git a/src/libstate/scan_name.h b/src/libstate/scan_name.h index 9e7af40d6..b3f2004e2 100644 --- a/src/libstate/scan_name.h +++ b/src/libstate/scan_name.h @@ -1,6 +1,6 @@ /** -SCAN Name Abstraction -(C) 2008 Jack Lloyd +* SCAN Name Abstraction +* (C) 2008 Jack Lloyd * * Distributed under the terms of the Botan license */ diff --git a/src/mac/mac.cpp b/src/mac/mac.cpp index 96df25503..04b259647 100644 --- a/src/mac/mac.cpp +++ b/src/mac/mac.cpp @@ -1,6 +1,6 @@ /** -Message Authentication Code base class -(C) 1999-2008 Jack Lloyd +* Message Authentication Code base class +* (C) 1999-2008 Jack Lloyd * * Distributed under the terms of the Botan license */ -- cgit v1.2.3 From 166e979eebe6e3f136df4deba626b584e1d735ae Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 8 Sep 2009 15:54:09 +0000 Subject: Throw Internal_Error instead of Algorithm_Not_Found if no usable RNG is enabled in the build. --- src/rng/auto_rng/auto_rng.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/rng/auto_rng/auto_rng.cpp b/src/rng/auto_rng/auto_rng.cpp index 171c83cca..07b2ddec2 100644 --- a/src/rng/auto_rng/auto_rng.cpp +++ b/src/rng/auto_rng/auto_rng.cpp @@ -140,7 +140,7 @@ AutoSeeded_RNG::AutoSeeded_RNG(u32bit poll_bits) #endif if(!rng) - throw Algorithm_Not_Found("No usable RNG found enabled in build"); + throw Internal_Error("No usable RNG found enabled in build"); /* If X9.31 is available, use it to wrap the other RNG as a failsafe */ #if defined(BOTAN_HAS_X931_RNG) -- cgit v1.2.3 From 1a0f377896cb88b9933b857579113283324d9464 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 9 Sep 2009 15:15:26 +0000 Subject: The first argument of Library_State::set_option was accidentally being passed as a 'const std::string' instead of a const reference. Can't fix in 1.8 since it is ABI breaking. --- src/libstate/libstate.cpp | 2 +- src/libstate/libstate.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libstate/libstate.cpp b/src/libstate/libstate.cpp index 3275c6493..20e736868 100644 --- a/src/libstate/libstate.cpp +++ b/src/libstate/libstate.cpp @@ -212,7 +212,7 @@ std::string Library_State::deref_alias(const std::string& key) const /* * Set/Add an option */ -void Library_State::set_option(const std::string key, +void Library_State::set_option(const std::string& key, const std::string& value) { set("conf", key, value); diff --git a/src/libstate/libstate.h b/src/libstate/libstate.h index 2493863a9..a0421953e 100644 --- a/src/libstate/libstate.h +++ b/src/libstate/libstate.h @@ -77,7 +77,7 @@ class BOTAN_DLL Library_State * @param key the key of the option to set * @param value the value to set */ - void set_option(const std::string key, const std::string& value); + void set_option(const std::string& key, const std::string& value); /** * Add a parameter value to the "alias" section. -- cgit v1.2.3 From d61103aada1e69598792addb026aa9f10137e586 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 10 Sep 2009 00:16:18 +0000 Subject: Add parallel block toggles for CBC and CFB (decrypt direction only) --- src/build-data/buildh.in | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index bd900d412..e0d8368ed 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -22,8 +22,14 @@ #define BOTAN_KARAT_SQR_THRESHOLD 32 #define BOTAN_PRIVATE_KEY_OP_BLINDING_BITS 64 -/* Toggles for parallel block cipher mode processing */ +/* +* Toggles for parallel block cipher mode processing +* +* CBC and CFB can only use parallel processing in decryption mode +*/ #define BOTAN_PARALLEL_BLOCKS_ECB 8 +#define BOTAN_PARALLEL_BLOCKS_CBC 8 +#define BOTAN_PARALLEL_BLOCKS_CFB 8 #define BOTAN_PARALLEL_BLOCKS_CTR 8 #define BOTAN_PARALLEL_BLOCKS_EAX 8 #define BOTAN_PARALLEL_BLOCKS_XTS 8 -- cgit v1.2.3 From a10e163e3a557cbc2d5291ab45ad068158cff525 Mon Sep 17 00:00:00 2001 From: lloyd Date: Sun, 13 Sep 2009 17:59:36 +0000 Subject: Make some changes to the SSE2 implementation of SHA-1 for compatability with Visual C++. --- src/hash/sha1_sse2/sha1_sse2_imp.cpp | 108 +++++++++++++++-------------------- 1 file changed, 46 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/hash/sha1_sse2/sha1_sse2_imp.cpp b/src/hash/sha1_sse2/sha1_sse2_imp.cpp index 90a8dccd5..57b287bdb 100644 --- a/src/hash/sha1_sse2/sha1_sse2_imp.cpp +++ b/src/hash/sha1_sse2/sha1_sse2_imp.cpp @@ -20,8 +20,10 @@ * on a Linux/Core2 system. */ + #include -#include +#include +#include namespace Botan { @@ -30,21 +32,13 @@ namespace { typedef union { u32bit u32[4]; __m128i u128; - } v4si __attribute__((aligned(16))); + } v4si; static const v4si K00_19 = { { 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999 } }; static const v4si K20_39 = { { 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1 } }; static const v4si K40_59 = { { 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc } }; static const v4si K60_79 = { { 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6 } }; -#define UNALIGNED 1 -#if UNALIGNED -#define load(p) _mm_loadu_si128(p) -#else -#define load(p) (*p) -#endif - - /* the first 16 bytes only need byte swapping @@ -57,19 +51,15 @@ and is overwritten with the swapped bytes __m128i r1, r2; \ \ r1 = (W); \ - if (1) { \ r1 = _mm_shufflehi_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ r1 = _mm_shufflelo_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ r2 = _mm_slli_epi16(r1, 8); \ r1 = _mm_srli_epi16(r1, 8); \ r1 = _mm_or_si128(r1, r2); \ (W) = r1; \ - } \ (prep).u128 = _mm_add_epi32(K00_19.u128, r1); \ } while(0) - - /* for each multiple of 4, t, we want to calculate this: @@ -115,45 +105,38 @@ W0 = W[t]..W[t+3] * efficeon, pentium-m, and opteron but shifts are available in * only one unit. */ -#define prep(prep, XW0, XW1, XW2, XW3, K) do { \ - __m128i r0, r1, r2, r3; \ - \ - /* load W[t-4] 16-byte aligned, and shift */ \ - r3 = _mm_srli_si128((XW3), 4); \ - r0 = (XW0); \ - /* get high 64-bits of XW0 into low 64-bits */ \ - r1 = _mm_shuffle_epi32((XW0), _MM_SHUFFLE(1,0,3,2)); \ - /* load high 64-bits of r1 */ \ - r1 = _mm_unpacklo_epi64(r1, (XW1)); \ - r2 = (XW2); \ - \ - r0 = _mm_xor_si128(r1, r0); \ - r2 = _mm_xor_si128(r3, r2); \ - r0 = _mm_xor_si128(r2, r0); \ - /* unrotated W[t]..W[t+2] in r0 ... still need W[t+3] */ \ - \ - r2 = _mm_slli_si128(r0, 12); \ - r1 = _mm_cmplt_epi32(r0, _mm_setzero_si128()); \ - r0 = _mm_add_epi32(r0, r0); /* shift left by 1 */ \ - r0 = _mm_sub_epi32(r0, r1); /* r0 has W[t]..W[t+2] */ \ - \ - r3 = _mm_srli_epi32(r2, 30); \ - r2 = _mm_slli_epi32(r2, 2); \ - \ - r0 = _mm_xor_si128(r0, r3); \ - r0 = _mm_xor_si128(r0, r2); /* r0 now has W[t+3] */ \ - \ - (XW0) = r0; \ - (prep).u128 = _mm_add_epi32(r0, (K).u128); \ - } while(0) - - -static inline u32bit rol(u32bit src, u32bit amt) - { - /* gcc and icc appear to turn this into a rotate */ - return (src << amt) | (src >> (32 - amt)); - } - +#define prep(prep, XW0, XW1, XW2, XW3, K) \ + do { \ + __m128i r0, r1, r2, r3; \ + \ + /* load W[t-4] 16-byte aligned, and shift */ \ + r3 = _mm_srli_si128((XW3), 4); \ + r0 = (XW0); \ + /* get high 64-bits of XW0 into low 64-bits */ \ + r1 = _mm_shuffle_epi32((XW0), _MM_SHUFFLE(1,0,3,2)); \ + /* load high 64-bits of r1 */ \ + r1 = _mm_unpacklo_epi64(r1, (XW1)); \ + r2 = (XW2); \ + \ + r0 = _mm_xor_si128(r1, r0); \ + r2 = _mm_xor_si128(r3, r2); \ + r0 = _mm_xor_si128(r2, r0); \ + /* unrotated W[t]..W[t+2] in r0 ... still need W[t+3] */ \ + \ + r2 = _mm_slli_si128(r0, 12); \ + r1 = _mm_cmplt_epi32(r0, _mm_setzero_si128()); \ + r0 = _mm_add_epi32(r0, r0); /* shift left by 1 */ \ + r0 = _mm_sub_epi32(r0, r1); /* r0 has W[t]..W[t+2] */ \ + \ + r3 = _mm_srli_epi32(r2, 30); \ + r2 = _mm_slli_epi32(r2, 2); \ + \ + r0 = _mm_xor_si128(r0, r3); \ + r0 = _mm_xor_si128(r0, r2); /* r0 now has W[t+3] */ \ + \ + (XW0) = r0; \ + (prep).u128 = _mm_add_epi32(r0, (K).u128); \ + } while(0) static inline u32bit f00_19(u32bit x, u32bit y, u32bit z) { @@ -184,11 +167,12 @@ static inline u32bit f60_79(u32bit x, u32bit y, u32bit z) return f20_39(x, y, z); } -#define step(nn_mm, xa, xb, xc, xd, xe, xt, input) do { \ - (xt) = (input) + f##nn_mm((xb), (xc), (xd)); \ - (xb) = rol((xb), 30); \ - (xt) += ((xe) + rol((xa), 5)); \ - } while(0) +#define step(nn_mm, xa, xb, xc, xd, xe, xt, input) \ + do { \ + (xt) = (input) + f##nn_mm((xb), (xc), (xd)); \ + (xb) = rotate_left((xb), 30); \ + (xt) += ((xe) + rotate_left((xa), 5)); \ + } while(0) } @@ -210,14 +194,14 @@ extern "C" void botan_sha1_sse2_compress(u32bit H[5], * steps ahead of the integer code. 12 steps ahead seems * to produce the best performance. -dean */ - W0 = load(&input[0]); + W0 = _mm_loadu_si128(&input[0]); prep00_15(prep0, W0); /* prepare for 00 through 03 */ - W1 = load(&input[1]); + W1 = _mm_loadu_si128(&input[1]); prep00_15(prep1, W1); /* prepare for 04 through 07 */ - W2 = load(&input[2]); + W2 = _mm_loadu_si128(&input[2]); prep00_15(prep2, W2); /* prepare for 08 through 11 */ - W3 = load(&input[3]); + W3 = _mm_loadu_si128(&input[3]); step(00_19, a, b, c, d, e, t, prep0.u32[0]); /* 00 */ step(00_19, t, a, b, c, d, e, prep0.u32[1]); /* 01 */ step(00_19, e, t, a, b, c, d, prep0.u32[2]); /* 02 */ -- cgit v1.2.3 From 02fc388212efa21a3f489a28e7b3738956a1358c Mon Sep 17 00:00:00 2001 From: lloyd Date: Sun, 13 Sep 2009 18:00:05 +0000 Subject: Enable SSE2 engine under VC++ --- src/engine/sse2_eng/info.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/engine/sse2_eng/info.txt b/src/engine/sse2_eng/info.txt index 7595b8eb5..7508b9874 100644 --- a/src/engine/sse2_eng/info.txt +++ b/src/engine/sse2_eng/info.txt @@ -19,4 +19,5 @@ amd64 gcc icc +msvc -- cgit v1.2.3 From 7f6a017a61fc6ef97d9d7b37236df52d6170e7d6 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 15 Sep 2009 14:14:32 +0000 Subject: Add an implementation of Blue Midnight Wish (512 bit version only) --- checks/algos.cpp | 2 +- checks/validate.dat | 1914 +++++++++++++++++++++++++++++++++ doc/examples/bench.cpp | 43 +- doc/log.txt | 1 + src/engine/def_engine/lookup_hash.cpp | 9 + src/hash/bmw/bmw_512.cpp | 174 +++ src/hash/bmw/bmw_512.h | 31 + src/hash/bmw/info.txt | 14 + 8 files changed, 2164 insertions(+), 24 deletions(-) create mode 100644 src/hash/bmw/bmw_512.cpp create mode 100644 src/hash/bmw/bmw_512.h create mode 100644 src/hash/bmw/info.txt (limited to 'src') diff --git a/checks/algos.cpp b/checks/algos.cpp index dff903e21..fd75bc463 100644 --- a/checks/algos.cpp +++ b/checks/algos.cpp @@ -74,10 +74,10 @@ std::vector get_algos() algos.push_back(algorithm("Hash", "Adler32")); algos.push_back(algorithm("Hash", "CRC24")); algos.push_back(algorithm("Hash", "CRC32")); + algos.push_back(algorithm("Hash", "BMW-512")); algos.push_back(algorithm("Hash", "FORK-256")); algos.push_back(algorithm("Hash", "GOST-34.11")); algos.push_back(algorithm("Hash", "HAS-160")); - algos.push_back(algorithm("Hash", "HAS-V")); algos.push_back(algorithm("Hash", "MD2")); algos.push_back(algorithm("Hash", "MD4")); algos.push_back(algorithm("Hash", "MD5")); diff --git a/checks/validate.dat b/checks/validate.dat index 524cc4b2f..19db5441f 100644 --- a/checks/validate.dat +++ b/checks/validate.dat @@ -30753,6 +30753,1920 @@ D8C1D4BD9C3086F1FDA0ECD33C4FFAFF:72D73FE9 # MARKER: Hash Functions # Hash function format is input:hash +[BMW-512] +:\ +73DB7B1DC6DEF4DDF2F94A22E1F6D2162B3123828369FF4FD750832AEDE94E52\ +D4D5C8B866860424991527175B6F62DBE0F764AC18290B92A26812D641CD5287 + +CC:\ +9840F373D940E19FB25945134874977D0A4562CA50F358013E72C9679B3C82BD\ +3988E1BF8FE495C7FBC7D5F2B5F1EEDFC65EB8E54A7D039FA51661C0D4733484 + +41FB:\ +92B5AD91B8F774D1BDA764B10658BFB714E742EE872E0AABC3E0456DB1A7A8AF\ +40768A8EDFFDC995C1F84151F94E3EFAB9978F03CCBCB29A2170AA291F22E0AC + +1F877C:\ +159F8BEE2626872E66E7378F9C9D814411630F47B5B2F5F76FAA2140517238BB\ +8781257F20C896F4FA4DFECBC4CB2D1E5932EDEDC5D35E0F3D1C1C93766881CB + +C1ECFDFC:\ +63F6DA9795970160FE9431D1046972B2815D9793AE146102FA8941FCC8B3D447\ +369DCC78E6EE054775DD081E59BA3E0D0653497993CDD413DA1BC099C48D75C0 + +21F134AC57:\ +042445884DCC2C42B7B6C463B402B0538AE18BB9BAE1D0A85F13FD2A6A6F2FD2\ +CB8B78D25D6A98C33848EEBC2D84513B54901A208812D629EBE354BDD6C978AE + +C6F50BB74E29:\ +05D923A6960DFF2151830FBCDB9C45E4FDD62B3CEB9CB1780787A07F7CAE5278\ +69D346707CFBAB8D0C853F609D7B494DCD6DCB0F911CD27DA11702D357DB5432 + +119713CC83EEEF:\ +EBAEDFE8FDFCC34ABE5939FD2A3F520263BA3C1103084C1F8B66180FCDB7264D\ +2384C6151791E72401A8AFF1000229EDF0ECAB8316F44C1F0D39616758951668 + +4A4F202484512526:\ +745995D3EEF74E331B94C791D96CE8A33716379E4D9DF744460ABE87F6495149\ +BD1B71DA2F884850F520866123FBEFB5D51F6330398A1E86380B622C437E4C9B + +1F66AB4185ED9B6375:\ +0551C3FE28BC3E0ADB52A201FEBD788B7F39DB7342934D10AC8FA87DBB52F2BD\ +B81F5BB316098D2236041083B37854720CD7A6B325405C58A9C690AEBBBC9630 + +EED7422227613B6F53C9:\ +6BABFCFDF2AD51C3BC23F3B5961375B0C5EF16A3E56628ACC052A86188FB94EB\ +0E0516187737BB716D9228E115219D5C5A64E608721952A8DC3506233E814DE4 + +EAEED5CDFFD89DECE455F1:\ +735E5418F3586FCF2DA76018A9B1816AB70031FB23A43D394B5DECD9953C1810\ +3DC129ACE0EF740B3C15B914921ED1EC4AA1078D8F5456F2A24B6109FCB5B2C6 + +5BE43C90F22902E4FE8ED2D3:\ +30F325A100BE24398ABB02FE6F86F9DCEE4D77873EFB5A4FD8EF89547D8143DC\ +B05067EE69015C915DD26889DD360C28D155CECABAE7852AB853125997602053 + +A746273228122F381C3B46E4F1:\ +CA08832D082A30BFC303C4854994B905EB5A115B76E1772EC5D3DD5576681121\ +A0ADF3DF365391E764AD0C0054CD0190F9BDFFAC6A4EE3C47139B6F2A550A365 + +3C5871CD619C69A63B540EB5A625:\ +9192799953AE4140D2D210DF6291C40F09F91B2D440EC81EB10FA06FA183A6D5\ +8C6D20F7B69365155E431323DFA8B52ACF23A0E5CA2392F5C606F8463567D793 + +FA22874BCC068879E8EF11A69F0722:\ +D760AE02DFB92518516BF94F16F366700BE7043DF94DFD6DE89E2773EAE7ECE4\ +E6CA64A82E29402550DE531A72CC74F9BD7E8DAEFA91D4B36E092D9C87D98117 + +52A608AB21CCDD8A4457A57EDE782176:\ +58B7F75E1F58C8235471511D88C4513FCB60C03C47E20D5FF198F5E0DD980A84\ +4C343598486573EF972198BA506BF2C07BDA6C83E71F6C42D290B9412A7F5118 + +82E192E4043DDCD12ECF52969D0F807EED:\ +B8E6C00BEEECE767393D959B3137CDB4F69EF82AFB8A6BFA99375B7BD33918C8\ +8D59197675612D7DC8D42947A3CE22F3A167B396B2E7F0E29C677369E4B7C937 + +75683DCB556140C522543BB6E9098B21A21E:\ +B578944870EC6AE4AF742DBD72EB2067772467ADDE3EE007CDE159C8BFAA7CE4\ +83FFDC7C89B2C73363823CA58949880A289C7B61EC0A1D207C3AE95B3CF5C183 + +06E4EFE45035E61FAAF4287B4D8D1F12CA97E5:\ +64D481A9BD15634C715EF3E8AF4FC94664FC380B51218E9786AFAC187B362B00\ +8DD54ADD1B62779A35A10A991C27F22A7A624B451DBEF425E3633B50EDE78835 + +E26193989D06568FE688E75540AEA06747D9F851:\ +7DBF6124910547C284FB8664B197DB48E1CA950A13DE136DF86EF41C6D9AF327\ +E493D0171C6D8426F938445B260B779F8F28667C7525067B55273B25AA553A9D + +D8DC8FDEFBDCE9D44E4CBAFE78447BAE3B5436102A:\ +76831676159CBC50D761800DE6C042D0CADD770840799F31970DE8B147D751AD\ +014A6D0E0ABA7441A4CCD3AADBB175923E33D1343AF83DB0AA943AFAA7DB5DAF + +57085FD7E14216AB102D8317B0CB338A786D5FC32D8F:\ +3F00ECD88535CF4EAD4644134C13473BAEF3F9223660C41E0B2BE8CE08DEF2B3\ +24DFED32E559880031A19DE2BAEF73296F980AC0B87B9620FB0CEBF5CC812016 + +A05404DF5DBB57697E2C16FA29DEFAC8AB3560D6126FA0:\ +A5DF86B0021E4028EC79AEE1DF59CEBBD071F041D82F10DE014BB19445C07E78\ +2DA69484F1F93CBA27264E83759DD54CB1D88DAF883862F0176F451702336C69 + +AECBB02759F7433D6FCB06963C74061CD83B5B3FFA6F13C6:\ +F3172A73831AD1596F920735786B83F6236BBCC121C805DC31067362C530CED0\ +304E8CAD619BC4162760AAF34353E581A5CA43CC74CEB6F11D72C4401CC48C7D + +AAFDC9243D3D4A096558A360CC27C8D862F0BE73DB5E88AA55:\ +B7A8160FACFA8A4110558796D99A793D714E128E5D3CEE5188FB2C85880498BC\ +884B0DA80AE65D1275EF5B8207FEEEF1ED55278B271571F64C63A37C822DBF5B + +7BC84867F6F9E9FDC3E1046CAE3A52C77ED485860EE260E30B15:\ +50A1BF96E0DE3CF9B9A7FC4C97E1BB02BC843113E731472FAE6970C6351F7E40\ +71F909435DA1707A52288252CABF2B46C0167A674C17159F053AFBF7008B2CBA + +FAC523575A99EC48279A7A459E98FF901918A475034327EFB55843:\ +C73850851A15D4B730D97773A82788B4486AAD26092EF29E980D5315BF0414E3\ +8FB300C5900B708B11D51F90124D603AF84C870594BC1DCD119E406F9BE92762 + +0F8B2D8FCFD9D68CFFC17CCFB117709B53D26462A3F346FB7C79B85E:\ +6B3491AEB10987090D570688DADAF9EB5F3A6A8131FAD207DC4505DBF3AEE8FF\ +0D81AA3D6D066AF9F64333226BB3FAC7F363D44C30BEADF623D3FF452EACB818 + +A963C3E895FF5A0BE4824400518D81412F875FA50521E26E85EAC90C04:\ +EC5930D611D58A2B87B8505256BDC24D150C238CCDE3C7AA9FA9A2470BEDDE29\ +591208BD924C474CD849B9B005BD4D930D0BACF87DB15D7395E68FBDF8FC0435 + +03A18688B10CC0EDF83ADF0A84808A9718383C4070C6C4F295098699AC2C:\ +7D2A97D59AF2707F481804C7A3BCC6D226941406CB1852A28475F3434B512F22\ +D5EE88E7FB47EB065745417CB8D5001FCD7072349090BCC1F8A5E8BED877886B + +84FB51B517DF6C5ACCB5D022F8F28DA09B10232D42320FFC32DBECC3835B29:\ +9429625B5A17F44E3B1B56436FE8348C4D3FD2CD634884A0DFBB24AF765FA415\ +DC223A6D6A7818CEB1557693A364434D363760D51266C067B5E22A4B07A7B643 + +9F2FCC7C90DE090D6B87CD7E9718C1EA6CB21118FC2D5DE9F97E5DB6AC1E9C10:\ +994F4F57EEAFC3C4CC9D5275906A15BFDBDA5EA71C4479FCD420AF19062A3651\ +2F1D4C3298F08BB23CEE9756CC0927249792948095E085B3EA98FC25346FE471 + +DE8F1B3FAA4B7040ED4563C3B8E598253178E87E4D0DF75E4FF2F2DEDD5A0BE0\ +46:\ +E589801B2213C47DD246602C5F018E5A53267FDF5D087092BAEF60BBBD878B7D\ +05C6247924C9E49B7BE22F578F245186B6E8275A3EA543FC0388DB167A4B0A67 + +62F154EC394D0BC757D045C798C8B87A00E0655D0481A7D2D9FB58D93AEDC676\ +B5A0:\ +535741C4D3702052B90129D720ED909A79398C9113566424DF9C25936C957DE4\ +13082F2B21DBB549D7A98C1DE017AB0BE217DD6FCA6FDFDBAB88DB95392A27ED + +B2DCFE9FF19E2B23CE7DA2A4207D3E5EC7C6112A8A22AEC9675A886378E14E5B\ +FBAD4E:\ +5D5E007A1CD5AD33EBD29FB0F54C025BB2A354865012463E05D644C90407E989\ +0CBE0314606BD215DEBABAAED4A01E498639DE7BAE3FC6EACA63007A3F4C4734 + +47F5697AC8C31409C0868827347A613A3562041C633CF1F1F86865A576E02835\ +ED2C2492:\ +AC05269EC62DAB42AE70ECC0C3FA98118C90C22A087124E26DD070B33E331E18\ +4F0BE667A97F041B8EA0274AC69E0F233D580F4CED044134F5C5F6FF06CFB253 + +512A6D292E67ECB2FE486BFE92660953A75484FF4C4F2ECA2B0AF0EDCDD4339C\ +6B2EE4E542:\ +7CEAF4D520D389D2C2F1A3496F350B73A7C524FA3B68C5034C9196B7A5B61184\ +26BC04E527317B0948328081529ED3E3DF94D3945D6DC8C7639C41F39C003403 + +973CF2B4DCF0BFA872B41194CB05BB4E16760A1840D8343301802576197EC19E\ +2A1493D8F4FB:\ +B0A5E7A2A632D2E860010A8526ACA19D028AFCD986213E8D92284173FB9FFD01\ +492B985A3142A9A5145EF823284F10E59CE4D96294A9F5C9344C2A2AF307C061 + +80BEEBCD2E3F8A9451D4499961C9731AE667CDC24EA020CE3B9AA4BBC0A7F79E\ +30A934467DA4B0:\ +AAA6227F450D3155AE0B7CE3177772958A5F62156B38154936EAB3DB4753D882\ +FBC6E2480277C6889EE3CEFB29E2A4AC51FCB9DE94C323BF222CB54061BAC061 + +7ABAA12EC2A7347674E444140AE0FB659D08E1C66DECD8D6EAE925FA451D65F3\ +C0308E29446B8ED3:\ +523FF9E4D5D00A01EF877EFB99BF5F8060943539D90A894D3C6CD132DE40EDA0\ +1BF41C8040B41C134F7A166FDF3C85A45D2B49F3EB584EEF73404B21F40B1393 + +C88DEE9927679B8AF422ABCBACF283B904FF31E1CAC58C7819809F65D5807D46\ +723B20F67BA610C2B7:\ +D129F5142CB0590FDF8C4F1EAA9FE01CDFCD605FF472C88BB93671F866D5C05B\ +5FBA76CC0BD92EDB88052829FFD12AFDF1C78A8B0216A8F8DFC6DD42C9BA0DEF + +01E43FE350FCEC450EC9B102053E6B5D56E09896E0DDD9074FE138E603821027\ +0C834CE6EADC2BB86BF6:\ +31C927D5EF8D6C7FF6ED7AEB3AA3BDC0EDBB7840351D3648DF4493C9BBDC3BC1\ +B9C5B16EA56D0AF05356C76915B9A99CD3A8E971428FEC18A855EDC8AD572BF1 + +337023370A48B62EE43546F17C4EF2BF8D7ECD1D49F90BAB604B839C2E6E5BD2\ +1540D29BA27AB8E309A4B7:\ +A95CF125F407B69A4C06E1C21887C12C9D8385A5989E9A18739EA444292135A2\ +D93A44CAF9506A033D1FA6389B345D2D5950D6611D496C0E6027689A81949456 + +6892540F964C8C74BD2DB02C0AD884510CB38AFD4438AF31FC912756F3EFEC6B\ +32B58EBC38FC2A6B913596A8:\ +7CBF30547921746CBE27FC5DEA6705A070631002447BDA20262CC5FCB0259083\ +9A2A3185443D502554296E7655F5CBB9EEED60C840E61E90A4DA3070B3FE63DF + +F5961DFD2B1FFFFDA4FFBF30560C165BFEDAB8CE0BE525845DEB8DC61004B7DB\ +38467205F5DCFB34A2ACFE96C0:\ +A1A9A9FBA7A83D85796E0800931A3044E48454C34542A6373DB9EC602C0760ED\ +816EC32028013FD9EA976A898081852A7E3C17FA7DA2F048492AC9539D92DD6D + +CA061A2EB6CEED8881CE2057172D869D73A1951E63D57261384B80CEB5451E77\ +B06CF0F5A0EA15CA907EE1C27EBA:\ +34825B3A2CBD58E217B7C76593B02479451B6C9A2C809FC289857F4CC70147DE\ +00F3104EDEE8B1CA54F712996D609D32C988AB70749D0868D4B690BAD1CFB1AD + +1743A77251D69242750C4F1140532CD3C33F9B5CCDF7514E8584D4A5F9FBD730\ +BCF84D0D4726364B9BF95AB251D9BB:\ +47BAF3BF878E7EE0D803457EB4C689A9CCFEB1C552382A36229615A8A46BE0AE\ +46D0F40F309D3BD9FAAECD123B60C43AC29909D77C8E20D886034B9A1E145DC4 + +D8FABA1F5194C4DB5F176FABFFF856924EF627A37CD08CF55608BBA8F1E324D7\ +C7F157298EABC4DCE7D89CE5162499F9:\ +052FE499E96A76C8D20BB911F9A819BC177159D54C30A697F7E0E97CFD0F2442\ +460A48BF5D6B5BE59C2317A84F10E6B19A0DFEEC2077C88787630E1E12A91589 + +BE9684BE70340860373C9C482BA517E899FC81BAAA12E5C6D7727975D1D41BA8\ +BEF788CDB5CF4606C9C1C7F61AED59F97D:\ +C51B893CE23BAF7018CBC69F9CA7C49697792C35845D542A3F2970F6E69072FA\ +22E9B81A78AD609BCACD890EB0B9ADFA8C88283735F406F1604277F87535588C + +7E15D2B9EA74CA60F66C8DFAB377D9198B7B16DEB6A1BA0EA3C7EE2042F89D37\ +86E779CF053C77785AA9E692F821F14A7F51:\ +01756CBD8188A16ECF85C24FFE017F202C6106DF941E043666E4285AFE2DD60F\ +BD19E86D95FBAFCABA45A26FF7FBF3DC82A72FFB803055346FE5F40F15E38D6A + +9A219BE43713BD578015E9FDA66C0F2D83CAC563B776AB9F38F3E4F7EF229CB4\ +43304FBA401EFB2BDBD7ECE939102298651C86:\ +51475D5155F7F33D25A1698B7A93093ADABF7CEB18D549BEE87BDD4F2117407B\ +ED4FD4310EBE8F378D7C9E0E2A1C627C1AAE16C4940E92B2F8E43289EFCE223F + +C8F2B693BD0D75EF99CAEBDC22ADF4088A95A3542F637203E283BBC3268780E7\ +87D68D28CC3897452F6A22AA8573CCEBF245972A:\ +9A7B45C8A0E0349CFE3A77A964EBA8858CE70DC7467BDCBEE97349A63E960732\ +D08E32F8CF33BE42B839777CA7F7217989A2E15022CEF55E418C7EAE6F5C125B + +EC0F99711016C6A2A07AD80D16427506CE6F441059FD269442BAAA28C6CA037B\ +22EEAC49D5D894C0BF66219F2C08E9D0E8AB21DE52:\ +D871B9BB85CF7910F49CAE84414F37A6C26034362E8267A4BCCA0E1A9269C6BF\ +7022B8EE03DBC5EDAFEF60ADF16012FF8AA939678614B383130F55A7A3780230 + +0DC45181337CA32A8222FE7A3BF42FC9F89744259CFF653504D6051FE84B1A7F\ +FD20CB47D4696CE212A686BB9BE9A8AB1C697B6D6A33:\ +93FB224AF201888068A73981DD63652F7600ADE60B22AE37EF9545702C8340B2\ +9F2CFB705D9421EE09449743E97D522037DBEC9DE50ADF91FD629663AEF116AC + +DE286BA4206E8B005714F80FB1CDFAEBDE91D29F84603E4A3EBC04686F99A46C\ +9E880B96C574825582E8812A26E5A857FFC6579F63742F:\ +2B6F8FBE583B60E750D3689CD6A681ECEBE6384BC6B444B8A9346D52A5826354\ +61C0E9CE40CCF8033BBF4F3A43C05D4313E5AB38A066DEDFD6CE8D46476AF6F5 + +EEBCC18057252CBF3F9C070F1A73213356D5D4BC19AC2A411EC8CDEEE7A571E2\ +E20EAF61FD0C33A0FFEB297DDB77A97F0A415347DB66BCAF:\ +A88163B4C6C5275B0A09069A3689EA208CBFF8687CFFBF799D209B248B9DC67D\ +11F32A18C4AACA6726874F8D2D0365EDFD17DB9A4AD24084CE2918B91F21D4B4 + +416B5CDC9FE951BD361BD7ABFC120A5054758EBA88FDD68FD84E39D3B09AC254\ +97D36B43CBE7B85A6A3CEBDA8DB4E5549C3EE51BB6FCB6AC1E:\ +BAAA6AD28EA720D8ADFD0466141B465F741992F9CCC35B4A281119F4CC654320\ +6C4C31D952FBE17B11F0E1A82653DBA16C35486CF8879E6C677F38A857C23523 + +5C5FAF66F32E0F8311C32E8DA8284A4ED60891A5A7E50FB2956B3CBAA79FC66C\ +A376460E100415401FC2B8518C64502F187EA14BFC9503759705:\ +108807312C29DEDA857D162A043427302A12E1CA38CB6A17665BE5D71223C258\ +21BE12FC18AB1CE23B2CAD9795F9DF0231DE8EE39E64111F912D257C00946F9E + +7167E1E02BE1A7CA69D788666F823AE4EEF39271F3C26A5CF7CEE05BCA831610\ +66DC2E217B330DF821103799DF6D74810EED363ADC4AB99F36046A:\ +23013C3939B713F4C410AE1D5BED0977D63F3403C9A1B2E176F13C13402A1CD1\ +58DA92045A605173B6BD46057B9E3F9E7891BC487EB7289D948452DBF72098C3 + +2FDA311DBBA27321C5329510FAE6948F03210B76D43E7448D1689A063877B6D1\ +4C4F6D0EAA96C150051371F7DD8A4119F7DA5C483CC3E6723C01FB7D:\ +2422F221BBA5965522072EA5CA8DF78D573484460B62BECDEB412AF92668EA7F\ +E4DE75B1C11DE0AE048BE00EE897C05BD9FD4E477E5AC3CDEFB1F01E090424E4 + +95D1474A5AAB5D2422ACA6E481187833A6212BD2D0F91451A67DD786DFC91DFE\ +D51B35F47E1DEB8A8AB4B9CB67B70179CC26F553AE7B569969CE151B8D:\ +83C62DC6985C154771320F9FF0E14AAD86D713D6AC56BCFD9BA445FD6C35A748\ +B89FDC7CC3AF80157F0F56FA48AA54181C1117276DC195E7A68C8942341F7D79 + +C71BD7941F41DF044A2927A8FF55B4B467C33D089F0988AA253D294ADDBDB325\ +30C0D4208B10D9959823F0C0F0734684006DF79F7099870F6BF53211A88D:\ +FCEF35C5CFDCB906711A24D5B3EA2D106E15A65B5E87BF7B438597A2A37E1BCD\ +08F8B8E6C3A2E493A47B439671724D38D2A42855411F32FCB13FFB5A21A86B2C + +F57C64006D9EA761892E145C99DF1B24640883DA79D9ED5262859DCDA8C3C32E\ +05B03D984F1AB4A230242AB6B78D368DC5AAA1E6D3498D53371E84B0C1D4BA:\ +8204F6D09AEB41690BBC4AEEB8437579EC8362A0CB2B5351014E99E3B7EBD80B\ +654E23F8EF938ADC7F31D17F78DD7582D178F6C3A89B8B7C603410381447A3CA + +E926AE8B0AF6E53176DBFFCC2A6B88C6BD765F939D3D178A9BDE9EF3AA131C61\ +E31C1E42CDFAF4B4DCDE579A37E150EFBEF5555B4C1CB40439D835A724E2FAE7:\ +926F142A64C9DE0CB07F1A35B635D9839B1DFB045B64AC087C47D533F1D62237\ +C18F9EDB76963A1D4683E3ED14E8792C1D2E9889EC37F2A42AC36CFBA9361ECD + +16E8B3D8F988E9BB04DE9C96F2627811C973CE4A5296B4772CA3EEFEB80A652B\ +DF21F50DF79F32DB23F9F73D393B2D57D9A0297F7A2F2E79CFDA39FA393DF1AC\ +00:\ +7F4CE24C8D7C8E19577E3C1ECA97ACAF15D280E312580C031845B1B40153EAD8\ +F55B9FFD6997C2C8EDE6879334ADD187F255C300240603452AAC651B4B901F31 + +FC424EEB27C18A11C01F39C555D8B78A805B88DBA1DC2A42ED5E2C0EC737FF68\ +B2456D80EB85E11714FA3F8EABFB906D3C17964CB4F5E76B29C1765DB03D91BE\ +37FC:\ +42659DFBA135041D8B9D8EB4FE57514236FA5F8CC63F6DC07258CA01AD9772AB\ +92EB6898B2B83F2B2977110D565F9ABA18FE1B1F3B7400AD69C05CB8AE578762 + +ABE3472B54E72734BDBA7D9158736464251C4F21B33FBBC92D7FAC9A35C4E332\ +2FF01D2380CBAA4EF8FB07D21A2128B7B9F5B6D9F34E13F39C7FFC2E72E47888\ +599BA5:\ +74E130CAE5866A10C53D7296A724BA1FD52F370FD01DDFFBE987D6D63AF90D11\ +3EB294E34871C1C753230C467B4E19ADD030A160499F7A84E15DFB33460E53A2 + +36F9F0A65F2CA498D739B944D6EFF3DA5EBBA57E7D9C41598A2B0E4380F3CF4B\ +479EC2348D015FFE6256273511154AFCF3B4B4BF09D6C4744FDD0F62D75079D4\ +40706B05:\ +D8837EE8E91BE8823EC9B792DDC180EA180DFEC7803083BB7EE86CF4B26FFB5E\ +1F27D2D13858201791ED4A15E30BB248280D5EAD0F798299BAFF961651949658 + +ABC87763CAE1CA98BD8C5B82CABA54AC83286F87E9610128AE4DE68AC95DF5E3\ +29C360717BD349F26B872528492CA7C94C2C1E1EF56B74DBB65C2AC351981FDB\ +31D06C77A4:\ +627C41B2215B346FD315F40073FCEB990D56A927C56ACF61EC5C6CA1C165C141\ +8030E12F83E24E8343ED0D12BBEE5E0328C21653AC1746B85D85451719EC499E + +94F7CA8E1A54234C6D53CC734BB3D3150C8BA8C5F880EAB8D25FED13793A9701\ +EBE320509286FD8E422E931D99C98DA4DF7E70AE447BAB8CFFD92382D8A77760\ +A259FC4FBD72:\ +8C7FDBF9EB06DFE9AD23BD461B67D75C7C4E450602812B496F3244D6FC30AC8E\ +1BB3A2F6761612DCB42F12AA1DD5C7CE14B7B2D375793A7BD6DE3DB593D81C27 + +13BD2811F6ED2B6F04FF3895ACEED7BEF8DCD45EB121791BC194A0F806206BFF\ +C3B9281C2B308B1A729CE008119DD3066E9378ACDCC50A98A82E20738800B6CD\ +DBE5FE9694AD6D:\ +25069EEB77DCA02E9FA7FE6B8B75A73BB54003DF9242050F8084626C32163189\ +5E5426D59AE5C89D2F6AE5B1B4883793E853C30718F0CFBBF4EEDB09949DFBC2 + +1EED9CBA179A009EC2EC5508773DD305477CA117E6D569E66B5F64C6BC64801C\ +E25A8424CE4A26D575B8A6FB10EAD3FD1992EDDDEEC2EBE7150DC98F63ADC323\ +7EF57B91397AA8A7:\ +10983820E5AC1F63D5F9155BB731FBEA51DC29C94A6C754ECE1DE4C15015E38B\ +5214446B64A8B1FC5C8D2071D0323A9179FD667E373B80DDB43E120DA70A7285 + +BA5B67B5EC3A3FFAE2C19DD8176A2EF75C0CD903725D45C9CB7009A900C0B0CA\ +7A2967A95AE68269A6DBF8466C7B6844A1D608AC661F7EFF00538E323DB5F2C6\ +44B78B2D48DE1A08AA:\ +7B8FFAB30873F60DA93EA5822843F3F47048B0B0B8B034A22FC7A2A63511A411\ +C4AE65E6370E5683B47A9AD1D25A53D1B6B08214019E60BD908DAA63529EA1BA + +0EFA26AC5673167DCACAB860932ED612F65FF49B80FA9AE65465E5542CB62075\ +DF1C5AE54FBA4DB807BE25B070033EFA223BDD5B1D3C94C6E1909C02B620D4B1\ +B3A6C9FED24D70749604:\ +C8C74FC231FC8A701FA4AD641028F7F59024330661CEA2907EA442A1BF961A88\ +F5A025E096CCB67BA8F3B8DC141AEA5C0B066393DA11CB9C3380368A86C5C13F + +BBFD933D1FD7BF594AC7F435277DC17D8D5A5B8E4D13D96D2F64E771ABBD51A5\ +A8AEA741BECCBDDB177BCEA05243EBD003CFDEAE877CCA4DA94605B67691919D\ +8B033F77D384CA01593C1B:\ +690B25D978A43A4DDFFCDE4240F18E95B388EF0CB3B0F4018E9F6B2BC3187EDD\ +75EBAD33FD75B3A6468666556E92695B5E494FB0D4DDAECD223144BEF702C36A + +90078999FD3C35B8AFBF4066CBDE335891365F0FC75C1286CDD88FA51FAB94F9\ +B8DEF7C9AC582A5DBCD95817AFB7D1B48F63704E19C2BAA4DF347F48D4A6D603\ +013C23F1E9611D595EBAC37C:\ +8DBFDF512CCFD357E6437640FEDCDCA8DAD285AA8E5A8AC08C4A5572AD653C60\ +7CFCB9049CFF6B7F4D3C9C3495B8C70A19DFEC8642639ABD54408F25EF55D475 + +64105ECA863515C20E7CFBAA0A0B8809046164F374D691CDBD6508AAABC1819F\ +9AC84B52BAFC1B0FE7CDDBC554B608C01C8904C669D8DB316A0953A4C68ECE32\ +4EC5A49FFDB59A1BD6A292AA0E:\ +D3F093F883036869820520A75D7F1C389474558B3E5742AD02B1E2AC6A380898\ +D3237BA3AE6D7738EA25AD0B925DBBF1BC825178BE80C1CFAFC35980A5B9700E + +D4654BE288B9F3B711C2D02015978A8CC57471D5680A092AA534F7372C71CEAA\ +B725A383C4FCF4D8DEAA57FCA3CE056F312961ECCF9B86F14981BA5BED6AB5B4\ +498E1F6C82C6CAE6FC14845B3C8A:\ +FC6E8BF596ACA6BF88A65B185BE195ADC1C53ABE3F2C485A28F4BC9A22E4A779\ +8731DB8BF26625CB3D04276910DB6465FBCA57641CE38389264889147E9E5144 + +12D9394888305AC96E65F2BF0E1B18C29C90FE9D714DD59F651F52B88B3008C5\ +88435548066EA2FC4C101118C91F32556224A540DE6EFDDBCA296EF1FB00341F\ +5B01FECFC146BDB251B3BDAD556CD2:\ +FAAF8737AFAEF553F042073BC8172F380A26780920DF3B12B5F42A76E8FE9324\ +B8146092BB8CA2ED014BD41704F4825605AB1EE7FA352A420E3E3DB5022CC43C + +871A0D7A5F36C3DA1DFCE57ACD8AB8487C274FAD336BC137EBD6FF4658B547C1\ +DCFAB65F037AA58F35EF16AFF4ABE77BA61F65826F7BE681B5B6D5A1EA8085E2\ +AE9CD5CF0991878A311B549A6D6AF230:\ +36C0947410D52F264BB450C77C0822B8C7F7DF5E425478919861CD90E0820BFB\ +3F24B30757040C1AB28EB2342368D315F2B5A5584A0CE735CEC219B4AACFC5B0 + +E90B4FFEF4D457BC7711FF4AA72231CA25AF6B2E206F8BF859D8758B89A7CD36\ +105DB2538D06DA83BAD5F663BA11A5F6F61F236FD5F8D53C5E89F183A3CEC615\ +B50C7C681E773D109FF7491B5CC22296C5:\ +82DC90329F774C2F54E86A04496DB2CA6ABE31C0C930499008227432C4B08875\ +FF26680BFF326D67DC1F16DE7ABFCA303ACAD9154E9D712A2FBC461E5613269F + +E728DE62D75856500C4C77A428612CD804F30C3F10D36FB219C5CA0AA30726AB\ +190E5F3F279E0733D77E7267C17BE27D21650A9A4D1E32F649627638DBADA970\ +2C7CA303269ED14014B2F3CF8B894EAC8554:\ +38EA632A13CAF8C0144C99755446235901233D8618DBD47DC13CAFA488E1006F\ +73794945AFF9C4AF418AD7EDCEAF76841775007080F0AFF4443189AB5F93AE1D + +6348F229E7B1DF3B770C77544E5166E081850FA1C6C88169DB74C76E42EB983F\ +ACB276AD6A0D1FA7B50D3E3B6FCD799EC97470920A7ABED47D288FF883E24CA2\ +1C7F8016B93BB9B9E078BDB9703D2B781B616E:\ +A58D6008392293665E8C9CDA03632471EE474F946FF29D2D03E5BA7ED7E574D9\ +C37346A0713004081872DDD37397665DAF634671C1123A539ABCEBB88A0CF3DF + +4B127FDE5DE733A1680C2790363627E63AC8A3F1B4707D982CAEA258655D9BF1\ +8F89AFE54127482BA01E08845594B671306A025C9A5C5B6F93B0A39522DC8774\ +37BE5C2436CBF300CE7AB6747934FCFC30AEAAF6:\ +FF7E839D9DF579713B7D9E02BCD979B2C24A25AB13BB6B8E80F170344F3C61C1\ +4D2532A993081F47EA9DAE2346EFF8A1CBEADEFA7BCE11D3CB547901D1354D64 + +08461F006CFF4CC64B752C957287E5A0FAABC05C9BFF89D23FD902D324C79903\ +B48FCB8F8F4B01F3E4DDB483593D25F000386698F5ADE7FAADE9615FDC50D327\ +85EA51D49894E45BAA3DC707E224688C6408B68B11:\ +42F2DA8296D7305DFF934BCC21AD52DAC181D937A840A739816ACD74300B4FFF\ +61A1486114DCD6EDC9E6101CCA43B3B5B2815AB8ACABE29CC71FF7F09940E9A3 + +68C8F8849B120E6E0C9969A5866AF591A829B92F33CD9A4A3196957A148C4913\ +8E1E2F5C7619A6D5EDEBE995ACD81EC8BB9C7B9CFCA678D081EA9E25A75D39DB\ +04E18D475920CE828B94E72241F24DB72546B352A0E4:\ +068CC9BECFAC3BEECC23A1767FF00238D2227B164EE5B22238A70953D2E34C6A\ +39F638F97BE9FE71BCD503497548B18F40951050D6828C0118FA4892252AE247 + +B8D56472954E31FB54E28FCA743F84D8DC34891CB564C64B08F7B71636DEBD64\ +CA1EDBDBA7FC5C3E40049CE982BBA8C7E0703034E331384695E9DE76B5104F2F\ +BC4535ECBEEBC33BC27F29F18F6F27E8023B0FBB6F563C:\ +1E2890C88D9FA31AC0952F2EE9309450DFC6391A241E2FAF55A7FA550FBBACF5\ +C6CDD85B0A95B5AB6117C38A85F9C82B7F7066FE1D7900CD8FC27DD1200ADEAA + +0D58AC665FA84342E60CEFEE31B1A4EACDB092F122DFC68309077AED1F3E528F\ +578859EE9E4CEFB4A728E946324927B675CD4F4AC84F64DB3DACFE850C1DD187\ +44C74CECCD9FE4DC214085108F404EAB6D8F452B5442A47D:\ +244B9AF6F4A80FAAE1F81E523BDCF3CC361AB27788FB4B6A2628B778F8B39513\ +C225BDCD1F814EAFF459C90DDC99D62A5BAFDB967E207350BC718FF7142657E3 + +1755E2D2E5D1C1B0156456B539753FF416651D44698E87002DCF61DCFA2B4E72\ +F264D9AD591DF1FDEE7B41B2EB00283C5AEBB3411323B672EAA145C512518510\ +4F20F335804B02325B6DEA65603F349F4D5D8B782DD3469CCD:\ +BBE9E91FACBA93DA63322E8B59BB1C64B881211194251C1237E997E551796DA5\ +2995C34B40036EDE7D15C597EC4431B5AB2E05EB03DF46A9086A48D58650722E + +B180DE1A611111EE7584BA2C4B020598CD574AC77E404E853D15A101C6F5A2E5\ +C801D7D85DC95286A1804C870BB9F00FD4DCB03AA8328275158819DCAD7253F3\ +E3D237AEAA7979268A5DB1C6CE08A9EC7C2579783C8AFC1F91A7:\ +EFB0D1C9E0EB8DD9B5A33E642FA4F93CBC8F62FF67003ADB42A58BE7B86AD308\ +19ED1A656C17D5D5A01FD442210F4EA1F7FC4D75F13560FB08504844350DFFA1 + +CF3583CBDFD4CBC17063B1E7D90B02F0E6E2EE05F99D77E24E560392535E47E0\ +5077157F96813544A17046914F9EFB64762A23CF7A49FE52A0A4C01C630CFE87\ +27B81FB99A89FF7CC11DCA5173057E0417B8FE7A9EFBA6D95C555F:\ +144639558BB4321A5968021BFA84F7241955BA9237773488BBBABBAB9286EE00\ +E6A8A6EFFBC21F217111510AAEE5EE0ED906D9EA5DEA52415F708CA0BC156B9D + +072FC02340EF99115BAD72F92C01E4C093B9599F6CFC45CB380EE686CB5EB019\ +E806AB9BD55E634AB10AA62A9510CC0672CD3EDDB589C7DF2B67FCD3329F61B1\ +A4441ECA87A33C8F55DA4FBBAD5CF2B2527B8E983BB31A2FADEC7523:\ +AB961D00600EBB3C3E3500547077C31C0F975D9A2CFF1519C013C48222700BA8\ +03ABBF23B967E0A082F00FB1DD3C520C38C7F5298A06F6CFEABEBB951DE9B364 + +76EECF956A52649F877528146DE33DF249CD800E21830F65E90F0F25CA9D6540\ +FDE40603230ECA6760F1139C7F268DEBA2060631EEA92B1FFF05F93FD5572FBE\ +29579ECD48BC3A8D6C2EB4A6B26E38D6C5FBF2C08044AEEA470A8F2F26:\ +6815226C40917DC69411050D38DC1A8F94BC99D095A7BB74529291E6CCD5E71A\ +405869F6E7E9111F54C9B2528E72B3BFFDDC2F9EB6FD02271B3786C1398049D8 + +7ADC0B6693E61C269F278E6944A5A2D8300981E40022F839AC644387BFAC9086\ +650085C2CDC585FEA47B9D2E52D65A2B29A7DC370401EF5D60DD0D21F9E2B90F\ +AE919319B14B8C5565B0423CEFB827D5F1203302A9D01523498A4DB10374:\ +F40CAB07D41D001D2EF64E5B2B590A8F1EB54A248B55D5BC8AC411A33CFC32CB\ +D5F30330EF9AD6DF62EE3DAF91EE282392BBD53D4E04686DA6A75944A8541259 + +E1FFFA9826CCE8B86BCCEFB8794E48C46CDF372013F782ECED1E378269B7BE2B\ +7BF51374092261AE120E822BE685F2E7A83664BCFBE38FE8633F24E633FFE198\ +8E1BC5ACF59A587079A57A910BDA60060E85B5F5B6F776F0529639D9CCE4BD:\ +BFA7856A28597491D01D1FE04F028779B6884ECCB14578E985AE43FE6F26DE55\ +D1484B87813B88D233EC8B8E1ADAFB7F2938051E4ED2A3B56B35012B9085E9E1 + +69F9ABBA65592EE01DB4DCE52DBAB90B08FC04193602792EE4DAA263033D5908\ +1587B09BBE49D0B49C9825D22840B2FF5D9C5155F975F8F2C2E7A90C75D2E4A8\ +040FE39F63BBAFB403D9E28CC3B86E04E394A9C9E8065BD3C85FA9F0C7891600:\ +C39F4A7E6B45DB2FDF146887FAD15CB83541A5BBD51367D9A0D971E312FFED28\ +5B380C0E4B3BBE8D492D259B713981600FBC62FECE7A904399857E41BB5AA574 + +38A10A352CA5AEDFA8E19C64787D8E9C3A75DBF3B8674BFAB29B5DBFC15A63D1\ +0FAE66CD1A6E6D2452D557967EAAD89A4C98449787B0B3164CA5B717A93F24EB\ +0B506CEB70CBBCB8D72B2A72993F909AAD92F044E0B5A2C9AC9CB16A0CA2F81F\ +49:\ +C86DBAFBCC87C1A9F23846B856FEB881FA1C663AA3A50E1B71F9E70E7FB4A21E\ +B8165F22505169B3F360876328D799F618175B29D26D650A804CD2926BDE6A05 + +6D8C6E449BC13634F115749C248C17CD148B72157A2C37BF8969EA83B4D6BA8C\ +0EE2711C28EE11495F43049596520CE436004B026B6C1F7292B9C436B055CBB7\ +2D530D860D1276A1502A5140E3C3F54A93663E4D20EDEC32D284E25564F62495\ +5B52:\ +BB59022C4426826788E09DE943EFE4D7FAE71BCDD31270FBCFA0385EFEF6BF96\ +5F7D49D3B296897DF0FAEA677E6D1E62417BD08198FF3C76FAC765F27E0B9AD6 + +6EFCBCAF451C129DBE00B9CEF0C3749D3EE9D41C7BD500ADE40CDC65DEDBBBAD\ +B885A5B14B32A0C0D087825201E303288A733842FA7E599C0C514E078F05C821\ +C7A4498B01C40032E9F1872A1C925FA17CE253E8935E4C3C71282242CB716B20\ +89CCC1:\ +80A11F3D809C269942F4E17D5A13FDB4A7E3EDBE1177ECC4816A883FD924A0F3\ +30A6E27286364464609B566A2D4951B6817BF5D828D24DECE963630FB06B3C94 + +433C5303131624C0021D868A30825475E8D0BD3052A022180398F4CA4423B982\ +14B6BEAAC21C8807A2C33F8C93BD42B092CC1B06CEDF3224D5ED1EC29784444F\ +22E08A55AA58542B524B02CD3D5D5F6907AFE71C5D7462224A3F9D9E53E7E084\ +6DCBB4CE:\ +506AE4A6B5F39DA18FAA39A6E110BD1B2889D739F4A56AFD9867A6948C063C7F\ +CC9DBE16FC804F387DD48510D39F07EF5C3FAD3B73C53AECE1D359D853D8FCC7 + +A873E0C67CA639026B6683008F7AA6324D4979550E9BCE064CA1E1FB97A30B14\ +7A24F3F666C0A72D71348EDE701CF2D17E2253C34D1EC3B647DBCEF2F879F4EB\ +881C4830B791378C901EB725EA5C172316C6D606E0AF7DF4DF7F76E490CD30B2\ +BADF45685F:\ +E8F6B97FF2429752891F69F91893B9AFEC04E931ECD58AF96AEF937233404F68\ +D83D111BD2AE642A960FC7365BDC820BC1FB686022E6C2BC0422577789A7507A + +006917B64F9DCDF1D2D87C8A6173B64F6587168E80FAA80F82D84F60301E561E\ +312D9FBCE62F39A6FB476E01E925F26BCC91DE621449BE6504C504830AAE3940\ +96C8FC7694651051365D4EE9070101EC9B68086F2EA8F8AB7B811EA8AD934D5C\ +9B62C60A4771:\ +36C1FF38C5F3BC8E642AFC2EDD8DC67A9B0F46F5A1A46AE970A94204FE0DB95E\ +540F46A5DE01F5C0D9E357A4FA7A8EB070F2BF98C9CF553B6D2AD2CD2ED0EC38 + +F13C972C52CB3CC4A4DF28C97F2DF11CE089B815466BE88863243EB318C2ADB1\ +A417CB1041308598541720197B9B1CB5BA2318BD5574D1DF2174AF14884149BA\ +9B2F446D609DF240CE335599957B8EC80876D9A085AE084907BC5961B20BF5F6\ +CA58D5DAB38ADB:\ +9715FA25210B31BA4E700755A8CE75992C0620ED22243A18F7F08F6240A3C09B\ +3ADAFC89C356DE6009507A532D435FE44785C9FC06A30F97C43C536848DBAAF6 + +E35780EB9799AD4C77535D4DDB683CF33EF367715327CF4C4A58ED9CBDCDD486\ +F669F80189D549A9364FA82A51A52654EC721BB3AAB95DCEB4A86A6AFA93826D\ +B923517E928F33E3FBA850D45660EF83B9876ACCAFA2A9987A254B137C6E140A\ +21691E1069413848:\ +D00A87501AEE7D7457E8B463B43604E9688440E83AC76D0601553E0E6281CF55\ +8A92ACBA1F90DADB84737C6851075B415CE5FBCE1DFC85EADAAEFD43765866B5 + +64EC021C9585E01FFE6D31BB50D44C79B6993D72678163DB474947A053674619\ +D158016ADB243F5C8D50AA92F50AB36E579FF2DABB780A2B529370DAA299207C\ +FBCDD3A9A25006D19C4F1FE33E4B1EAEC315D8C6EE1E730623FD1941875B924E\ +B57D6D0C2EDC4E78D6:\ +88FECE207FCEF6BA2DC893289E8FF4401175DF1D8CD00E2C44D31701F6C0BADE\ +386C94DFE91104D002E92B5F84DA89DC2AB2EA527D2877D319FAE51DA1F1D9AF + +5954BAB512CF327D66B5D9F296180080402624AD7628506B555EEA8382562324\ +CF452FBA4A2130DE3E165D11831A270D9CB97CE8C2D32A96F50D71600BB4CA26\ +8CF98E90D6496B0A6619A5A8C63DB6D8A0634DFC6C7EC8EA9C006B6C456F1B20\ +CD19E781AF20454AC880:\ +DBAF5302A755CC44F28B4E8083089E5D17810F9E1C191D97C862560327AE568D\ +1459058AE9343C8565A0AEC6D94C5E0F88982827A92CAB1CA551843DFD937E9F + +03D9F92B2C565709A568724A0AFF90F8F347F43B02338F94A03ED32E6F33666F\ +F5802DA4C81BDCE0D0E86C04AFD4EDC2FC8B4141C2975B6F07639B1994C973D9\ +A9AFCE3D9D365862003498513BFA166D2629E314D97441667B007414E739D7FE\ +BF0FE3C32C17AA188A8683:\ +88DB17A8B022D2E52A9A3B9BE7790C5E623CB0FEE52103FB5F3BC2715FF400FD\ +D1DE8093E95570253462693A1D4BD5B1B6867139FECF7AABF19DC6D7A89CF398 + +F31E8B4F9E0621D531D22A380BE5D9ABD56FAEC53CBD39B1FAB230EA67184440\ +E5B1D15457BD25F56204FA917FA48E669016CB48C1FFC1E1E45274B3B47379E0\ +0A43843CF8601A5551411EC12503E5AAC43D8676A1B2297EC7A0800DBFEE0429\ +2E937F21C005F17411473041:\ +1039453D77ACDD8719FE013FE904F49339574B64A28662A399A010DC6DFCF80F\ +B61A0D9CECDAD0FADCDD30480C8225CA3423746575C564EF6EA1DB7B557A5A66 + +758EA3FEA738973DB0B8BE7E599BBEF4519373D6E6DCD7195EA885FC991D8967\ +62992759C2A09002912FB08E0CB5B76F49162AEB8CF87B172CF3AD190253DF61\ +2F77B1F0C532E3B5FC99C2D31F8F65011695A087A35EE4EEE5E334C369D8EE5D\ +29F695815D866DA99DF3F79403:\ +4437B0252F715304BEE9B06B31EBB029D51BDA7C01E5EE614AB2F5B981AEFBF3\ +5F4C9A093C8F26672D77D08AAAA49F9C672C0F5AC8AD6ABB0AE30B4A098F2447 + +47C6E0C2B74948465921868804F0F7BD50DD323583DC784F998A93CD1CA4C6EF\ +84D41DC81C2C40F34B5BEE6A93867B3BDBA0052C5F59E6F3657918C382E771D3\ +3109122CC8BB0E1E53C4E3D13B43CE44970F5E0C079D2AD7D7A3549CD75760C2\ +1BB15B447589E86E8D76B1E9CED2:\ +72C9B767071710D37FEF19E7939F9A245615532E9D4FA643974B211A8D9E5A64\ +AF75A4A365F2503B8B2C71A7A9A6D65BA08E671A044B2E4FA4873DD4EA59154D + +F690A132AB46B28EDFA6479283D6444E371C6459108AFD9C35DBD235E0B6B6FF\ +4C4EA58E7554BD002460433B2164CA51E868F7947D7D7A0D792E4ABF0BE5F450\ +853CC40D85485B2B8857EA31B5EA6E4CCFA2F3A7EF3380066D7D8979FDAC618A\ +AD3D7E886DEA4F005AE4AD05E5065F:\ +01C1E76E50BDD370BCA1EEFFACF6E56F61AC91D193DDB738A75F062FBFAFED79\ +F5618EB34F3ACB06D7850A40CF5E10DE41F6F9D61F3F6A3DDA9C5CB8D63FD691 + +58D6A99BC6458824B256916770A8417040721CCCFD4B79EACD8B65A3767CE5BA\ +7E74104C985AC56B8CC9AEBD16FEBD4CDA5ADB130B0FF2329CC8D611EB14DAC2\ +68A2F9E633C99DE33997FEA41C52A7C5E1317D5B5DAED35EBA7D5A60E45D1FA7\ +EAABC35F5C2B0A0F2379231953322C4E:\ +AE45DDCA514264B8ACE8283E675AEAB6F75631FF5E0693DD4E798DB122D425C3\ +83CB8008CFAD1417755C6ECCEE33EB4979079A1BFB81E08D059D2F196E1935AB + +BEFAB574396D7F8B6705E2D5B58B2C1C820BB24E3F4BAE3E8FBCD36DBF734EE1\ +4E5D6AB972AEDD3540235466E825850EE4C512EA9795ABFD33F330D9FD7F79E6\ +2BBB63A6EA85DE15BEAEEA6F8D204A28956059E2632D11861DFB0E65BC07AC8A\ +159388D5C3277E227286F65FF5E5B5AEC1:\ +CCDA0F2420E7E550353D455172C7D96B3C73BA96154BA850FC316B65D2988B3C\ +2A88AFA619A0E325E61973A4F7D0B260CA3DC5288D21338E5691D775B9596186 + +8E58144FA9179D686478622CE450C748260C95D1BA43B8F9B59ABECA8D93488D\ +A73463EF40198B4D16FB0B0707201347E0506FF19D01BEA0F42B8AF9E71A1F1B\ +D168781069D4D338FDEF00BF419FBB003031DF671F4A37979564F69282DE9C65\ +407847DD0DA505AB1641C02DEA4F0D834986:\ +C86A3FC28768D1B12141216F2211F902CAA1F0FFFBE41710AA1186A8CE35CEED\ +23044C5F4464B79BE81E40B4C9903F9C6807958B440D059C5A9A6911CF600E43 + +B55C10EAE0EC684C16D13463F29291BF26C82E2FA0422A99C71DB4AF14DD9C7F\ +33EDA52FD73D017CC0F2DBE734D831F0D820D06D5F89DACC485739144F8CFD47\ +99223B1AFF9031A105CB6A029BA71E6E5867D85A554991C38DF3C9EF8C1E1E9A\ +7630BE61CAABCA69280C399C1FB7A12D12AEFC:\ +17DF80D04C1B2D4FAFCCDABFCC6E109261A61FF525F845FC5DCC354BC19984F7\ +4F94A6CA82C95055CCD22D9F70D0DC68AC306DA361C135E9B40764A936E6947F + +2EEEA693F585F4ED6F6F8865BBAE47A6908AECD7C429E4BEC4F0DE1D0CA0183F\ +A201A0CB14A529B7D7AC0E6FF6607A3243EE9FB11BCF3E2304FE75FFCDDD6C5C\ +2E2A4CD45F63C962D010645058D36571404A6D2B4F44755434D76998E83409C3\ +205AA1615DB44057DB991231D2CB42624574F545:\ +885461034C5ED300812411297256FA74CCA8D5D61858AEF4E3F5E3737643C5BD\ +B92E65626B685C810D901D33CE22C30072634C431F95EA76936068D686999DC3 + +DAB11DC0B047DB0420A585F56C42D93175562852428499F66A0DB811FCDDDAB2\ +F7CDFFED1543E5FB72110B64686BC7B6887A538AD44C050F1E42631BC4EC8A9F\ +2A047163D822A38989EE4AAB01B4C1F161B062D873B1CFA388FD301514F62224\ +157B9BEF423C7783B7AAC8D30D65CD1BBA8D689C2D:\ +EABFDA04298F0CCBB7DDD4318C98A6F4FFB749D8EFD902823511CF548C3DE032\ +E206F295FD9EC9FE44A05A4E1E7C5F01B19BBCBBE0A0AC142231B0860FAFA4CB + +42E99A2F80AEE0E001279A2434F731E01D34A44B1A8101726921C0590C30F312\ +0EB83059F325E894A5AC959DCA71CE2214799916424E859D27D789437B9D2724\ +0BF8C35ADBAFCECC322B48AA205B293962D858652ABACBD588BCF6CBC388D099\ +3BD622F96ED54614C25B6A9AA527589EAAFFCF17DDF7:\ +BAFFEB5AC8E9BB44791F112B5FA090EF60CB13D05F3F137DAD89E2AD70DC9FF1\ +5BD6C44075A7A4F979FCFAE0ED57A68151F81E68C65AEBA44BCC19057EA93E98 + +3C9B46450C0F2CAE8E3823F8BDB4277F31B744CE2EB17054BDDC6DFF36AF7F49\ +FB8A2320CC3BDF8E0A2EA29AD3A55DE1165D219ADEDDB5175253E2D1489E9B6F\ +DD02E2C3D3A4B54D60E3A47334C37913C5695378A669E9B72DEC32AF5434F93F\ +46176EBF044C4784467C700470D0C0B40C8A088C815816:\ +7197F27D300980CBFC230639E8DD20832A6CEF9E39EA54A2C9CD37C905134952\ +64B2BEF2393B5F2E0B3C14AF80BD63275EB4D653AAC91CFB805AF9C14B833C4B + +D1E654B77CB155F5C77971A64DF9E5D34C26A3CAD6C7F6B300D39DEB19100946\ +91ADAA095BE4BA5D86690A976428635D5526F3E946F7DC3BD4DBC78999E65344\ +1187A81F9ADCD5A3C5F254BC8256B0158F54673DCC1232F6E918EBFC6C51CE67\ +EAEB042D9F57EEC4BFE910E169AF78B3DE48D137DF4F2840:\ +88E837536AC03572D8A41E6F59E6F8530F581E4FF3DB097A849037DF26665CBA\ +B72241AF292A3DF1E738E39209A8B293B65ACB77E07F577A22DF24E8B5A58AD7 + +626F68C18A69A6590159A9C46BE03D5965698F2DAC3DE779B878B3D9C421E0F2\ +1B955A16C715C1EC1E22CE3EB645B8B4F263F60660EA3028981EEBD6C8C3A367\ +285B691C8EE56944A7CD1217997E1D9C21620B536BDBD5DE8925FF71DEC6FBC0\ +6624AB6B21E329813DE90D1E572DFB89A18120C3F606355D25:\ +4D6BD6E1B24AD612BBC238E64AB89084D2703007FD59C8B4718E65124DB8E926\ +70DEF8282470F0E78CDE6AC9A28E1BFA42BEB8442BDC5904082DEC9271995281 + +651A6FB3C4B80C7C68C6011675E6094EB56ABF5FC3057324EBC6477825061F9F\ +27E7A94633ABD1FA598A746E4A577CAF524C52EC1788471F92B8C37F23795CA1\ +9D559D446CAB16CBCDCE90B79FA1026CEE77BF4AB1B503C5B94C2256AD75B3EA\ +C6FD5DCB96ACA4B03A834BFB4E9AF988CECBF2AE597CB9097940:\ +502F271E81519BC7AAA67C4F7AB71BDECF7717C0F56A23539C969922977FA7BD\ +88922BA4BC556DC806672A1C734E4373F2E82FE605567E0EEC383EE6078360D3 + +8AAF072FCE8A2D96BC10B3C91C809EE93072FB205CA7F10ABD82ECD82CF040B1\ +BC49EA13D1857815C0E99781DE3ADBB5443CE1C897E55188CEAF221AA9681638\ +DE05AE1B322938F46BCE51543B57ECDB4C266272259D1798DE13BE90E10EFEC2\ +D07484D9B21A3870E2AA9E06C21AA2D0C9CF420080A80A91DEE16F:\ +47583501739DAC6F5A99D13719F6C5A44D88CA4A503EF2CFCFDEEA17D018CE03\ +345F75034F782450B67DEE9C27660DC6FD050FAED16F8630436EF5D87EBD7068 + +53F918FD00B1701BD504F8CDEA803ACCA21AC18C564AB90C2A17DA592C7D6968\ +8F6580575395551E8CD33E0FEF08CA6ED4588D4D140B3E44C032355DF1C53156\ +4D7F4835753344345A6781E11CD5E095B73DF5F82C8AE3AD00877936896671E9\ +47CC52E2B29DCD463D90A0C9929128DA222B5A211450BBC0E02448E2:\ +B4D44B02CFB3BF59A42E35B4263FF91BEEA9E978C71DBD5E1DA3E53730A1F7C1\ +A838D2AA5FA6F134A575F269C9677943F5CAC9D8D47CE0FB8157E4BF8E2BE416 + +A64599B8A61B5CCEC9E67AED69447459C8DA3D1EC6C7C7C82A7428B9B584FA67\ +E90F68E2C00FBBED4613666E5168DA4A16F395F7A3C3832B3B134BFC9CBAA95D\ +2A0FE252F44AC6681EB6D40AB91C1D0282FED6701C57463D3C5F2BB8C6A7301F\ +B4576AA3B5F15510DB8956FF77478C26A7C09BEA7B398CFC83503F538E:\ +46BA7F2CC804F2573AB08B3D4F152370DCD0299AA82D4E090DE6C69A07FC83B3\ +821905128838125F0BC4ABCDF41FB64AF63A5915842750DE768D2C5445DA1313 + +0E3AB0E054739B00CDB6A87BD12CAE024B54CB5E550E6C425360C2E87E59401F\ +5EC24EF0314855F0F56C47695D56A7FB1417693AF2A1ED5291F2FEE95F75EED5\ +4A1B1C2E81226FBFF6F63ADE584911C71967A8EB70933BC3F5D15BC91B5C2644\ +D9516D3C3A8C154EE48E118BD1442C043C7A0DBA5AC5B1D5360AAE5B9065:\ +48AEE486EFCBDF1979B9E59B54EC8117C6E00EB94307F642CA136CEC7354CC91\ +8700522477F80347A7E91CA4CEA327EEC390C975AF974F1A03474ACB7CF3B6D4 + +A62FC595B4096E6336E53FCDFC8D1CC175D71DAC9D750A6133D23199EAAC2882\ +07944CEA6B16D27631915B4619F743DA2E30A0C00BBDB1BBB35AB852EF3B9AEC\ +6B0A8DCC6E9E1ABAA3AD62AC0A6C5DE765DE2C3711B769E3FDE44A74016FFF82\ +AC46FA8F1797D3B2A726B696E3DEA5530439ACEE3A45C2A51BC32DD055650B:\ +A5FBFEB1FD1CED918FD189B7E8E49A2A26F99A9898B7469AD421F16DCF934E56\ +F17C68083F731F172FE9D6F26B141C8E7617A6369DB97CD31131B259ECE05C3A + +2B6DB7CED8665EBE9DEB080295218426BDAA7C6DA9ADD2088932CDFFBAA1C141\ +29BCCDD70F369EFB149285858D2B1D155D14DE2FDB680A8B027284055182A0CA\ +E275234CC9C92863C1B4AB66F304CF0621CD54565F5BFF461D3B461BD40DF281\ +98E3732501B4860EADD503D26D6E69338F4E0456E9E9BAF3D827AE685FB1D817:\ +FC79270DC468C4663FEC45C4581C49AB6C0631A77FFBBE8882C396A06C685231\ +CF91651BF810C765213D4160C6D64C36CD8B2EA0A87EACF31690B54BC8EB7636 + +10DB509B2CDCABA6C062AE33BE48116A29EB18E390E1BBADA5CA0A2718AFBCD2\ +3431440106594893043CC7F2625281BF7DE2655880966A23705F0C5155C2F5CC\ +A9F2C2142E96D0A2E763B70686CD421B5DB812DACED0C6D65035FDE558E94F26\ +B3E6DDE5BD13980CC80292B723013BD033284584BFF27657871B0CF07A849F4A\ +E2:\ +1C54E058E303ED843CEC563E57F5BC283085BCD6285C36F7C4AE124FF0F42C75\ +865689746B4C1119C54E0782AFAD3D507E0C0DED767B8937D87CB3A8A09416B7 + +9334DE60C997BDA6086101A6314F64E4458F5FF9450C509DF006E8C547983C65\ +1CA97879175AABA0C539E82D05C1E02C480975CBB30118121061B1EBAC4F8D9A\ +3781E2DB6B18042E01ECF9017A64A0E57447EC7FCBE6A7F82585F7403EE2223D\ +52D37B4BF426428613D6B4257980972A0ACAB508A7620C1CB28EB4E9D30FC413\ +61EC:\ +269AD5A2BCD1943138C9BC13A6E410559B4ABE511C357C1CDA3283AFD9DBA2A5\ +8DA526166041555D780610DD5C36BE7097258233949B8D42E4DF1E0908BBDCB4 + +E88AB086891693AA535CEB20E64C7AB97C7DD3548F3786339897A5F0C3903154\ +9CA870166E477743CCFBE016B4428D89738E426F5FFE81626137F17AECFF61B7\ +2DBEE2DC20961880CFE281DFAB5EE38B1921881450E16032DE5E4D55AD8D4FCA\ +609721B0692BAC79BE5A06E177FE8C80C0C83519FB3347DE9F43D5561CB8107B\ +9B5EDC:\ +6D49BBE0A468811E6068D4CEA22D9E5116D4F79E24584160647F8FFE460EA496\ +C47A9B47C8A5029BE941D02A739F89D594CD0BC312BD25FEB9CFC2B05925292E + +FD19E01A83EB6EC810B94582CB8FBFA2FCB992B53684FB748D2264F020D3B960\ +CB1D6B8C348C2B54A9FCEA72330C2AAA9A24ECDB00C436ABC702361A82BB8828\ +B85369B8C72ECE0082FE06557163899C2A0EFA466C33C04343A839417057399A\ +63A3929BE1EE4805D6CE3E5D0D0967FE9004696A5663F4CAC9179006A2CEB755\ +42D75D68:\ +8D327AAEF3FF05C0DE51B40347D11EC4D5ACB50ACC24B39C44273839D1878AC8\ +7939855B86B03195F67CF7D7FC7F41C74A4968C489A4ED7EFC4DFB199536BB8C + +59AE20B6F7E0B3C7A989AFB28324A40FCA25D8651CF1F46AE383EF6D8441587A\ +A1C04C3E3BF88E8131CE6145CFB8973D961E8432B202FA5AF3E09D625FAAD825\ +BC19DA9B5C6C20D02ABDA2FCC58B5BD3FE507BF201263F30543819510C12BC23\ +E2DDB4F711D087A86EDB1B355313363A2DE996B891025E147036087401CCF3CA\ +7815BF3C49:\ +786D18C6816FE5AF627CCCB692D79AC99825C57F76E63B93CC774FCAEA388D4A\ +354EE7D39651EB11BFE6DC96BED877E71DA5F7AE1BB5114795B96C1AE4B56173 + +77EE804B9F3295AB2362798B72B0A1B2D3291DCEB8139896355830F34B3B3285\ +61531F8079B79A6E9980705150866402FDC176C05897E359A6CB1A7AB067383E\ +B497182A7E5AEF7038E4C96D133B2782917417E391535B5E1B51F47D8ED7E4D4\ +025FE98DC87B9C1622614BFF3D1029E68E372DE719803857CA52067CDDAAD958\ +951CB2068CC6:\ +6ED0CEB2C0404260D2466A80FAA097C0BE4B68F537610474D3368224D4862CFC\ +C569294915E4E447645562BE785B9D2850BE8F4962D421AB7346D8E4C0DD02FC + +B771D5CEF5D1A41A93D15643D7181D2A2EF0A8E84D91812F20ED21F147BEF732\ +BF3A60EF4067C3734B85BC8CD471780F10DC9E8291B58339A677B960218F71E7\ +93F2797AEA349406512829065D37BB55EA796FA4F56FD8896B49B2CD19B43215\ +AD967C712B24E5032D065232E02C127409D2ED4146B9D75D763D52DB98D949D3\ +B0FED6A8052FBB:\ +87DDFDED0BAEBC090A82B8BAF67BECCF72E46D2D4C91A5C6A26583467D2A41E0\ +D04384A58BF9C5C209A82696AC54A760E571331D16A04F5D926CA104A3F42740 + +B32D95B0B9AAD2A8816DE6D06D1F86008505BD8C14124F6E9A163B5A2ADE55F8\ +35D0EC3880EF50700D3B25E42CC0AF050CCD1BE5E555B23087E04D7BF9813622\ +780C7313A1954F8740B6EE2D3F71F768DD417F520482BD3A08D4F222B4EE9DBD\ +015447B33507DD50F3AB4247C5DE9A8ABD62A8DECEA01E3B87C8B927F5B08BEB\ +37674C6F8E380C04:\ +9C32DFB92D2079F704C30734843B70B6670FDA53507DEAD248E644AB1CEDCF91\ +1BE16C04FE35FB861195A4EEEA9ED929D3249E0107DCB15BA76BFC6F534895AF + +04410E31082A47584B406F051398A6ABE74E4DA59BB6F85E6B49E8A1F7F2CA00\ +DFBA5462C2CD2BFDE8B64FB21D70C083F11318B56A52D03B81CAC5EEC29EB31B\ +D0078B6156786DA3D6D8C33098C5C47BB67AC64DB14165AF65B44544D806DDE5\ +F487D5373C7F9792C299E9686B7E5821E7C8E2458315B996B5677D926DAC57B3\ +F22DA873C601016A0D:\ +C0F684549025FB7AC404D5DCD997DC1E2392B3DD10A071CF17A1773D80877CC3\ +EA2A109263161D343C6B06BA6288D303A137647BB5A1992842FD97D1B200ECA9 + +8B81E9BADDE026F14D95C019977024C9E13DB7A5CD21F9E9FC491D716164BBAC\ +DC7060D882615D411438AEA056C340CDF977788F6E17D118DE55026855F93270\ +472D1FD18B9E7E812BAE107E0DFDE7063301B71F6CFE4E225CAB3B232905A56E\ +994F08EE2891BA922D49C3DAFEB75F7C69750CB67D822C96176C46BD8A29F170\ +1373FB09A1A6E3C7158F:\ +CE1BAF61F4215C7E4802AEDEB5FE0843868A173A005755CDC84D5E270AC0D127\ +6C53B72EFEA7A25D1090F32637B4582DD2D5E85D00C16B4A87F347E8267CB72F + +FA6EED24DA6666A22208146B19A532C2EC9BA94F09F1DEF1E7FC13C399A48E41\ +ACC2A589D099276296348F396253B57CB0E40291BD282773656B6E0D8BEA1CDA\ +084A3738816A840485FCF3FB307F777FA5FEAC48695C2AF4769720258C77943F\ +B4556C362D9CBA8BF103AEB9034BAA8EA8BFB9C4F8E6742CE0D52C49EA8E974F\ +339612E830E9E7A9C29065:\ +FAE974D0586C79EC9E5957B99EFDAF4DE4510D554D8F689EAA8841234B33BA2C\ +D75B62B5300BFFEB2E6C64007D363756E987183BB8779266E07BED49246C10DB + +9BB4AF1B4F09C071CE3CAFA92E4EB73CE8A6F5D82A85733440368DEE4EB1CBC7\ +B55AC150773B6FE47DBE036C45582ED67E23F4C74585DAB509DF1B8361056454\ +5642B2B1EC463E18048FC23477C6B2AA035594ECD33791AF6AF4CBC2A1166ABA\ +8D628C57E707F0B0E8707CAF91CD44BDB915E0296E0190D56D33D8DDE10B5B60\ +377838973C1D943C22ED335E:\ +EC6DED9C61223888BCD03EBF8E1037BDA52F94FF110B42524163010490B12204\ +37A68947D80FFE967B5317D2F8B1CE9C4ADB4FF2C6F89E4D54A7256C660106ED + +2167F02118CC62043E9091A647CADBED95611A521FE0D64E8518F16C808AB297\ +725598AE296880A773607A798F7C3CFCE80D251EBEC6885015F9ABF7EAABAE46\ +798F82CB5926DE5C23F44A3F9F9534B3C6F405B5364C2F8A8BDC5CA49C749BED\ +8CE4BA48897062AE8424CA6DDE5F55C0E42A95D1E292CA54FB46A84FBC9CD87F\ +2D0C9E7448DE3043AE22FDD229:\ +66C863F11E3149CAE8F0629FE48CAA35D7475812644286B2F9DF5598259FFCB2\ +46BB83919CA664CF9F5B0CF151BA8AECAEAB1938E69AB3B628770C0E93DB2444 + +94B7FA0BC1C44E949B1D7617D31B4720CBE7CA57C6FA4F4094D4761567E389EC\ +C64F6968E4064DF70DF836A47D0C713336B5028B35930D29EB7A7F9A5AF9AD5C\ +F441745BAEC9BB014CEEFF5A41BA5C1CE085FEB980BAB9CF79F2158E03EF7E63\ +E29C38D7816A84D4F71E0F548B7FC316085AE38A060FF9B8DEC36F91AD9EBC0A\ +5B6C338CBB8F6659D342A24368CF:\ +049A414B5A3DA568A5A9166CA7D9135FFA0E0B49DF43E4E796AF60D6613BDDCE\ +1006161AAC9BBCAB6B80199DCB52648B3CE998EA0AE27B37AADB3A9C914171CC + +EA40E83CB18B3A242C1ECC6CCD0B7853A439DAB2C569CFC6DC38A19F5C90ACBF\ +76AEF9EA3742FF3B54EF7D36EB7CE4FF1C9AB3BC119CFF6BE93C03E208783335\ +C0AB8137BE5B10CDC66FF3F89A1BDDC6A1EED74F504CBE7290690BB295A872B9\ +E3FE2CEE9E6C67C41DB8EFD7D863CF10F840FE618E7936DA3DCA5CA6DF933F24\ +F6954BA0801A1294CD8D7E66DFAFEC:\ +2B9131F248BE3B340BA45642E3DC9270543156FE2150700E36A7CE5887C60A35\ +5B4B055926888EAEF79743E1B038CA724F506366E8706176B382DBA414114FCB + +157D5B7E4507F66D9A267476D33831E7BB768D4D04CC3438DA12F9010263EA5F\ +CAFBDE2579DB2F6B58F911D593D5F79FB05FE3596E3FA80FF2F761D1B0E57080\ +055C118C53E53CDB63055261D7C9B2B39BD90ACC32520CBBDBDA2C4FD8856DBC\ +EE173132A2679198DAF83007A9B5C51511AE49766C792A29520388444EBEFE28\ +256FB33D4260439CBA73A9479EE00C63:\ +574A12CEEE655CBD90E3F3E483ACF5CE445D30029F34A5B364E73124AF129A7A\ +40D4BECD4233C83911D4E92E4FAF23DA979D11F3FCCC3BFC6F2E39B2FE0CBFFE + +836B34B515476F613FE447A4E0C3F3B8F20910AC89A3977055C960D2D5D2B72B\ +D8ACC715A9035321B86703A411DDE0466D58A59769672AA60AD587B8481DE4BB\ +A552A1645779789501EC53D540B904821F32B0BD1855B04E4848F9F8CFE9EBD8\ +911BE95781A759D7AD9724A7102DBE576776B7C632BC39B9B5E19057E226552A\ +5994C1DBB3B5C7871A11F5537011044C53:\ +FF04FF3D476E6B1E418B6C656DF2CA4577843B0F8300304F312E8DECE522D9AD\ +F994EBFEBD02050E7A622261B31875863DBEFFB50C07CFCBCE40D33FBC087110 + +CC7784A4912A7AB5AD3620AAB29BA87077CD3CB83636ADC9F3DC94F51EDF521B\ +2161EF108F21A0A298557981C0E53CE6CED45BDF782C1EF200D29BAB81DD6460\ +586964EDAB7CEBDBBEC75FD7925060F7DA2B853B2B089588FA0F8C16EC6498B1\ +4C55DCEE335CB3A91D698E4D393AB8E8EAC0825F8ADEBEEE196DF41205C01167\ +4E53426CAA453F8DE1CBB57932B0B741D4C6:\ +0427F9E924540E619A2E3CA21C1139A26529F032DB801389BB3B156F74662D59\ +114B6C65E800D554C88FB39F945D67446B2D56C36D882805EDD7F533CD5D726B + +7639B461FFF270B2455AC1D1AFCE782944AEA5E9087EB4A39EB96BB5C3BAAF0E\ +868C8526D3404F9405E79E77BFAC5FFB89BF1957B523E17D341D7323C302EA70\ +83872DD5E8705694ACDDA36D5A1B895AAA16ECA6104C82688532C8BFE1790B5D\ +C9F4EC5FE95BAED37E1D287BE710431F1E5E8EE105BC42ED37D74B1E55984BF1\ +C09FE6A1FA13EF3B96FAEAED6A2A1950A12153:\ +5CAB5FC3B20EDFAC061F3DE3434A42BCAFADBFE4BD7C15D2A5FA7FA7A81CA028\ +C8073E8A5BD54618CAA1C2AA22C7C636831D23227753BFF5CAE342C0DF86A840 + +EB6513FC61B30CFBA58D4D7E80F94D14589090CF1D80B1DF2E68088DC6104959\ +BA0D583D585E9578AB0AEC0CF36C48435EB52ED9AB4BBCE7A5ABE679C97AE2DB\ +E35E8CC1D45B06DDA3CF418665C57CBEE4BBB47FA4CAF78F4EE656FEC237FE4E\ +EBBAFA206E1EF2BD0EE4AE71BD0E9B2F54F91DAADF1FEBFD7032381D636B733D\ +CB3BF76FB14E23AFF1F68ED3DBCF75C9B99C6F26:\ +8CA096F3F386895CEDC7924785316E53585F0D9F6BD62687DDE376B12024DAC3\ +CFA860EAAC59ACEAE26FDC1FA92CDB81536E30BB89EF0B02C9DD5D6D1B0CB597 + +1594D74BF5DDE444265D4C04DAD9721FF3E34CBF622DAF341FE16B96431F6C4D\ +F1F760D34F296EB97D98D560AD5286FEC4DCE1724F20B54FD7DF51D4BF137ADD\ +656C80546FB1BF516D62EE82BAA992910EF4CC18B70F3F8698276FCFB44E0EC5\ +46C2C39CFD8EE91034FF9303058B4252462F86C823EB15BF481E6B79CC3A0221\ +8595B3658E8B37382BD5048EAED5FD02C37944E73B:\ +A7496CD71B2503BF3E61A50F269C639342A50C27A5474724919A56722B530EB6\ +F587265016003AEA5E89AFA8D5E4B825DF2AA20F2EE3B1D24A320F9E4FD79599 + +4CFA1278903026F66FEDD41374558BE1B585D03C5C55DAC94361DF286D4BD39C\ +7CB8037ED3B267B07C346626449D0CC5B0DD2CF221F7E4C3449A4BE99985D2D5\ +E67BFF2923357DDEAB5ABCB4619F3A3A57B2CF928A022EB27676C6CF80568900\ +4FCA4D41EA6C2D0A4789C7605F7BB838DD883B3AD3E6027E775BCF2628814280\ +99C7FFF95B14C095EA130E0B9938A5E22FC52650F591:\ +7DF2F4E99989DFCB586C604725C000AD32DA859247E422479A7629F3117E93D6\ +50F6A272F2CADE0F07B92382C5FC0D0E3B5313F16DF54FEA12D63BDDBA98FAB6 + +D3E65CB92CFA79662F6AF493D696A07CCF32AAADCCEFF06E73E8D9F6F909209E\ +66715D6E978788C49EFB9087B170ECF3AA86D2D4D1A065AE0EFC8924F365D676\ +B3CB9E2BEC918FD96D0B43DEE83727C9A93BF56CA2B2E59ADBA85696546A8150\ +67FC7A78039629D4948D157E7B0D826D1BF8E81237BAB7321312FDAA4D521744\ +F988DB6FDF04549D0FDCA393D639C729AF716E9C8BBA48:\ +1785ABB837E1EFB2EF35D2EE92250985380C702C700660FBCE71F0E962FA67C0\ +C525987A546F5310CE2489D7661229441A7D82BDFAB66D475826A21B95ADEDD8 + +842CC583504539622D7F71E7E31863A2B885C56A0BA62DB4C2A3F2FD12E79660\ +DC7205CA29A0DC0A87DB4DC62EE47A41DB36B9DDB3293B9AC4BAAE7DF5C6E720\ +1E17F717AB56E12CAD476BE49608AD2D50309E7D48D2D8DE4FA58AC3CFEAFEEE\ +48C0A9EEC88498E3EFC51F54D300D828DDDCCB9D0B06DD021A29CF5CB5B25069\ +15BEB8A11998B8B886E0F9B7A80E97D91A7D01270F9A7717:\ +C1383A968195C1A6796C5E53DC9756B9DEE39FB7116DCBFE2B5DB9CB9AD6A296\ +77C3F14A156D4D78B3C709DCD49CD247F676CCE0AD693EA208B8433D8C3F7BF6 + +6C4B0A0719573E57248661E98FEBE326571F9A1CA813D3638531AE28B4860F23\ +C3A3A8AC1C250034A660E2D71E16D3ACC4BF9CE215C6F15B1C0FC7E77D3D2715\ +7E66DA9CEEC9258F8F2BF9E02B4AC93793DD6E29E307EDE3695A0DF63CBDC0FC\ +66FB770813EB149CA2A916911BEE4902C47C7802E69E405FE3C04CEB5522792A\ +5503FA829F707272226621F7C488A7698C0D69AA561BE9F378:\ +44A8B042FC42ABDEB224A4FD7E934148BC86A30E5F2F94E713BFF7FC5BB414F3\ +66CE221316D2F79E5DE124BCC35585447E6B678FA02A5D947323D5C7E614072D + +51B7DBB7CE2FFEB427A91CCFE5218FD40F9E0B7E24756D4C47CD55606008BDC2\ +7D16400933906FD9F30EFFDD4880022D081155342AF3FB6CD53672AB7FB5B3A3\ +BCBE47BE1FD3A2278CAE8A5FD61C1433F7D350675DD21803746CADCA574130F0\ +1200024C6340AB0CC2CF74F2234669F34E9009EF2EB94823D62B31407F4BA46F\ +1A1EEC41641E84D77727B59E746B8A671BEF936F05BE820759FA:\ +8CD46B15C0F963EA6FF65FD4D3BD6597B3AFBCC7E7DD8C9FD54B93D02286040D\ +7426895B27BB21C9DCE2A99D307388AD54F2B10BC4030A044759A1378A3C5681 + +83599D93F5561E821BD01A472386BC2FF4EFBD4AED60D5821E84AAE74D807102\ +9810F5E286F8F17651CD27DA07B1EB4382F754CD1C95268783AD09220F550284\ +0370D494BEB17124220F6AFCE91EC8A0F55231F9652433E5CE3489B727716CF4\ +AEBA7DCDA20CD29AA9A859201253F948DD94395ABA9E3852BD1D60DDA7AE5DC0\ +45B283DA006E1CBAD83CC13292A315DB5553305C628DD091146597:\ +92DDE2B72137F776D310E1D5E85D83CB0BAA12496B21A850FA4A5E75AF17D510\ +D286C494400C999811B7992032D61B32098157085C8363850D4ADE61D4D9D2A9 + +2BE9BF526C9D5A75D565DD11EF63B979D068659C7F026C08BEA4AF161D85A462\ +D80E45040E91F4165C074C43AC661380311A8CBED59CC8E4C4518E80CD2C78AB\ +1CABF66BFF83EAB3A80148550307310950D034A6286C93A1ECE8929E6385C5E3\ +BB6EA8A7C0FB6D6332E320E71CC4EB462A2A62E2BFE08F0CCAD93E61BEDB5DD0\ +B786A728AB666F07E0576D189C92BF9FB20DCA49AC2D3956D47385E2:\ +BB878BE3D0F55077194E3B67B2E916324B1637B23AAEC1155E54A3146D7ED2B2\ +ED0D2AC5AEB816291FA89DD5FC11CD07ACDFF5D416F70D433BE262D6AF157C7E + +CA76D3A12595A817682617006848675547D3E8F50C2210F9AF906C0E7CE50B44\ +60186FE70457A9E879E79FD4D1A688C70A347361C847BA0DD6AA52936EAF8E58\ +A1BE2F5C1C704E20146D366AEB3853BED9DE9BEFE9569AC8AAEA37A9FB7139A1\ +A1A7D5C748605A8DEFB297869EBEDD71D615A5DA23496D11E11ABBB126B206FA\ +0A7797EE7DE117986012D0362DCEF775C2FE145ADA6BDA1CCB326BF644:\ +7F071AA99ABED8FD376C967FFF12CDF9926409131D3945A37F30F427C8C42899\ +2E6F1133F4211EDD38062445F5054D8D642C40E54935DBB937B96250D4A9D801 + +F76B85DC67421025D64E93096D1D712B7BAF7FB001716F02D33B2160C2C882C3\ +10EF13A576B1C2D30EF8F78EF8D2F465007109AAD93F74CB9E7D7BEF7C9590E8\ +AF3B267C89C15DB238138C45833C98CC4A471A7802723EF4C744A853CF80A0C2\ +568DD4ED58A2C9644806F42104CEE53628E5BDF7B63B0B338E931E31B87C24B1\ +46C6D040605567CEEF5960DF9E022CB469D4C787F4CBA3C544A1AC91F95F:\ +C176D062E50C7329273ED6A485B0A62FE18622E6A783108FAB8FBCBC645C4931\ +FF101A575368FBD65C06FAC22E72AD2FCCADA2AEB066B6649C531C1F74DD96B3 + +25B8C9C032EA6BCD733FFC8718FBB2A503A4EA8F71DEA1176189F694304F0FF6\ +8E862A8197B839957549EF243A5279FC2646BD4C009B6D1EDEBF24738197ABB4\ +C992F6B1DC9BA891F570879ACCD5A6B18691A93C7D0A8D38F95B639C1DAEB48C\ +4C2F15CCF5B9D508F8333C32DE78781B41850F261B855C4BEBCC125A380C54D5\ +01C5D3BD07E6B52102116088E53D76583B0161E2A58D0778F091206AABD5A1:\ +D5BF89C144445B9D3455C198D2630C643E4B51F35884EACB0B4F70864B2472B1\ +7AFD66DFBFAFF9482E34BDD6F6BF1EFDED5029EC7E74F80751384762BFC998E8 + +21CFDC2A7CCB7F331B3D2EEFFF37E48AD9FA9C788C3F3C200E0173D99963E1CB\ +CA93623B264E920394AE48BB4C3A5BB96FFBC8F0E53F30E22956ADABC2765F57\ +FB761E147ECBF8567533DB6E50C8A1F894310A94EDF806DD8CA6A0E141C0FA7C\ +9FAE6C6AE65F18C93A8529E6E5B553BF55F25BE2E80A9882BD37F145FECBEB3D\ +447A3C4E46C21524CC55CDD62F521AB92A8BA72B897996C49BB273198B7B1C9E:\ +AB3090870B65CA635BDAC16D1C2F877BDE48C3DE1DA17A88B89E86BE9DD9F4E3\ +A2D116CA899A4C4FE5494689D7BF8C1432276E4216DADB3011ABD058FCC56C70 + +4E452BA42127DCC956EF4F8F35DD68CB225FB73B5BC7E1EC5A898BBA2931563E\ +74FAFF3B67314F241EC49F4A7061E3BD0213AE826BAB380F1F14FAAB8B0EFDDD\ +5FD1BB49373853A08F30553D5A55CCBBB8153DE4704F29CA2BDEEF0419468E05\ +DD51557CCC80C0A96190BBCC4D77ECFF21C66BDF486459D427F986410F883A80\ +A5BCC32C20F0478BB9A97A126FC5F95451E40F292A4614930D054C851ACD019C\ +CF:\ +8C311A20F4BB608CE2D697A64C1029B6E000C16EA5D64538715EE0778D93EABA\ +708BAB844DF99EBABAE526639AE4435B74BE87A00128A1D5F227ABADB550B091 + +FA85671DF7DADF99A6FFEE97A3AB9991671F5629195049880497487867A6C446\ +B60087FAC9A0F2FCC8E3B24E97E42345B93B5F7D3691829D3F8CCD4BB36411B8\ +5FC2328EB0C51CB3151F70860AD3246CE0623A8DC8B3C49F958F8690F8E3860E\ +71EB2B1479A5CEA0B3F8BEFD87ACAF5362435EAECCB52F38617BC6C5C2C6E269\ +EAD1FBD69E941D4AD2012DA2C5B21BCFBF98E4A77AB2AF1F3FDA3233F046D38F\ +1DC8:\ +DB71A082A16BC8CE55235901A826E41D15016F26093C474086F2D0D3EE36FFD4\ +EDE1F75DCD811F74A7A64036969D53F20ADA190A2284E891C9F6CE98631EE2BC + +E90847AE6797FBC0B6B36D6E588C0A743D725788CA50B6D792352EA8294F5BA6\ +54A15366B8E1B288D84F5178240827975A763BC45C7B0430E8A559DF4488505E\ +009C63DA994F1403F407958203CEBB6E37D89C94A5EACF6039A327F6C4DBBC7A\ +2A307D976AA39E41AF6537243FC218DFA6AB4DD817B6A397DF5CA69107A91987\ +99ED248641B63B42CB4C29BFDD7975AC96EDFC274AC562D0474C60347A078CE4\ +C25E88:\ +B5219A12D02F6C17257BB2AC9911FBAA84FFA5E4BCD3351CE37D1D3E5E5CB9D1\ +72FD92DCD567C825DC86EB70C4F97ACE90324CDAA760E458C08B80E87A8B9858 + +F6D5C2B6C93954FC627602C00C4CA9A7D3ED12B27173F0B2C9B0E4A5939398A6\ +65E67E69D0B12FB7E4CEB253E8083D1CEB724AC07F009F094E42F2D6F2129489\ +E846EAFF0700A8D4453EF453A3EDDC18F408C77A83275617FABC4EA3A2833AA7\ +3406C0E966276079D38E8E38539A70E194CC5513AAA457C699383FD1900B1E72\ +BDFB835D1FD321B37BA80549B078A49EA08152869A918CA57F5B54ED71E4FD3A\ +C5C06729:\ +DF93616C367AF33B7D33B5F7FBD3332B9AA48FDF102F1D28767449EE4F8C3FC9\ +57BBFD94C7D52D98AEA7C2D5B4A0DC1ACE3DD878BD7F21D307403A3C5A2E57E6 + +CF8562B1BED89892D67DDAAF3DEEB28246456E972326DBCDB5CF3FB289ACA01E\ +68DA5D59896E3A6165358B071B304D6AB3D018944BE5049D5E0E2BB819ACF67A\ +6006111089E6767132D72DD85BEDDCBB2D64496DB0CC92955AB4C6234F1EEA24\ +F2D51483F2E209E4589BF9519FAC51B4D061E801125E605F8093BB6997BC163D\ +551596FE4AB7CFAE8FB9A90F6980480CE0C229FD1675409BD788354DAF316240\ +CFE0AF93EB:\ +899287D20D7D50E5B95308F1CFD16591DA081D5D1A65FE4EBECA519AF27298C8\ +2D4B9B8CBE92EFA03E3F7E856B20CA6E8CA9FF9388AB8F89A8CD96F2F36E03D3 + +2ACE31ABB0A2E3267944D2F75E1559985DB7354C6E605F18DC8470423FCA30B7\ +331D9B33C4A4326783D1CAAE1B4F07060EFF978E4746BF0C7E30CD61040BD5EC\ +2746B29863EB7F103EBDA614C4291A805B6A4C8214230564A0557BC7102E0BD3\ +ED23719252F7435D64D210EE2AAFC585BE903FA41E1968C50FD5D5367926DF7A\ +05E3A42CF07E656FF92DE73B036CF8B19898C0CB34557C0C12C2D8B84E91181A\ +F467BC75A9D1:\ +55B57907035DF0F13C09C2B87425A359281C39B37BE89DC62A7D3A9C91B42160\ +B96AF8C2A6BE6B1FC319970A4EC63A0365467A02D0F23DB67BF03681A0E38F7B + +0D8D09AED19F1013969CE5E7EB92F83A209AE76BE31C754844EA9116CEB39A22\ +EBB6003017BBCF26555FA6624185187DB8F0CB3564B8B1C06BF685D47F3286ED\ +A20B83358F599D2044BBF0583FAB8D78F854FE0A596183230C5EF8E54426750E\ +AF2CC4E29D3BDD037E734D863C2BD9789B4C243096138F7672C232314EFFDFC6\ +513427E2DA76916B5248933BE312EB5DDE4CF70804FB258AC5FB82D58D08177A\ +C6F4756017FFF5:\ +98E5DAC81EF43D68526A72206AEC6CB22C7381BEEB09B54761F5F979E0EC9675\ +32512D1864A1F8EABE6AEC3B0809B83217D654C8FF6EB2CA86E3CDF41AD348A1 + +C3236B73DEB7662BF3F3DAA58F137B358BA610560EF7455785A9BEFDB035A066\ +E90704F929BD9689CEF0CE3BDA5ACF4480BCEB8D09D10B098AD8500D9B6071DF\ +C3A14AF6C77511D81E3AA8844986C3BEA6F469F9E02194C92868CD5F51646256\ +798FF0424954C1434BDFED9FACB390B07D342E992936E0F88BFD0E884A0DDB67\ +9D0547CCDEC6384285A45429D115AC7D235A717242021D1DC35641F5F0A48E84\ +45DBA58E6CB2C8EA:\ +113A41F7819CA13ABC6D1E02906C5911006F407822821F32E55D808E51E15BCD\ +EA473E02F01B74F2E7EECBCD90448CC24D2363039E0FA99B769506F19CB38DC4 + +B39FEB8283EADC63E8184B51DF5AE3FD41AAC8A963BB0BE1CD08AA5867D8D910\ +C669221E73243360646F6553D1CA05A84E8DC0DE05B6419EC349CA994480193D\ +01C92525F3FB3DCEFB08AFC6D26947BDBBFD85193F53B50609C6140905C53A66\ +86B58E53A319A57B962331EDE98149AF3DE3118A819DA4D76706A0424B4E1D29\ +10B0ED26AF61D150EBCB46595D4266A0BD7F651BA47D0C7F179CA28545007D92\ +E8419D48FDFBD744CE:\ +D3CC7B4F7EF29FB4B1145F18C80D10F9568B7B597BED8C8FCA0D1E2F0A52EAA5\ +746C832AF9402DA8035FFCBB759A1B7078053E0A1148484FA31C0402B829D4B7 + +A983D54F503803E8C7999F4EDBBE82E9084F422143A932DDDDC47A17B0B7564A\ +7F37A99D0786E99476428D29E29D3C197A72BFAB1342C12A0FC4787FD7017D7A\ +6174049EA43B5779169EF7472BDBBD941DCB82FC73AAC45A8A94C9F2BD3477F6\ +1FD3B796F02A1B8264A214C6FEA74B7051B226C722099EC7883A462B83B6AFDD\ +4009248B8A237F605FE5A08FE7D8B45321421EBBA67BD70A0B00DDBF94BAAB7F\ +359D5D1EEA105F28DCFB:\ +9F064FDC60802C9382DA2875A370F3208EB36E192FA958995A586D1F735DBD55\ +E26A656942E5CC2050457E866371594D5928AFAE70F8C10DD31252B965D5FDCA + +E4D1C1897A0A866CE564635B74222F9696BF2C7F640DD78D7E2ACA66E1B61C64\ +2BB03EA7536AAE597811E9BF4A7B453EDE31F97B46A5F0EF51A071A2B3918DF1\ +6B152519AE3776F9F1EDAB4C2A377C3292E96408359D3613844D5EB393000283\ +D5AD3401A318B12FD1474B8612F2BB50FB6A8B9E023A54D7DDE28C43D6D8854C\ +8D9D1155935C199811DBFC87E9E0072E90EB88681CC7529714F8FB8A2C9D8856\ +7ADFB974EE205A9BF7B848:\ +9A04ECD9BB469A9501EBE71B9748128C4726019D76A4A3C1DE6A211902CA9C06\ +7979F2996501449188BE0A75244AB369E032F1D9C73DEA1882CC383DE8084E8F + +B10C59723E3DCADD6D75DF87D0A1580E73133A9B7D00CB95EC19F5547027323B\ +E75158B11F80B6E142C6A78531886D9047B08E551E75E6261E79785366D7024B\ +D7CD9CF322D9BE7D57FB661069F2481C7BB759CD71B4B36CA2BC2DF6D3A328FA\ +EBDB995A9794A8D72155ED551A1F87C80BF6059B43FC764900B18A1C2441F748\ +7743CF84E565F61F8DD2ECE6B6CCC9444049197AAAF53E926FBEE3BFCA8BE588\ +EC77F29D211BE89DE18B15F6:\ +F20C6D8BB06FBAEBFA3C2A9DF6E294D2CF64EF359973B438B7FA1192EBF607BC\ +0464CB53154A50291614FD094D9B60BDD27077898130C22CF4316B6176358EE5 + +DB11F609BABA7B0CA634926B1DD539C8CBADA24967D7ADD4D9876F77C2D80C0F\ +4DCEFBD7121548373582705CCA2495BD2A43716FE64ED26D059CFB566B3364BD\ +49EE0717BDD9810DD14D8FAD80DBBDC4CAFB37CC60FB0FE2A80FB4541B8CA9D5\ +9DCE457738A9D3D8F641AF8C3FD6DA162DC16FC01AAC527A4A0255B4D231C0BE\ +50F44F0DB0B713AF03D968FE7F0F61ED0824C55C4B5265548FEBD6AAD5C5EEDF\ +63EFE793489C39B8FD29D104CE:\ +2BC62B625A06D5F275FB633800AA00DB13AFC03DFBBE4CE287722BE3E7A55041\ +1A8FF84545CCEE032822FF43345C9841D6502914539C78038692628A143212E6 + +BEBD4F1A84FC8B15E4452A54BD02D69E304B7F32616AADD90537937106AE4E28\ +DE9D8AAB02D19BC3E2FDE1D651559E296453E4DBA94370A14DBBB2D1D4E20223\ +02EE90E208321EFCD8528AD89E46DC839EA9DF618EA8394A6BFF308E7726BAE0\ +C19BCD4BE52DA6258E2EF4E96AA21244429F49EF5CB486D7FF35CAC1BACB7E95\ +711944BCCB2AB34700D42D1EB38B5D536B947348A458EDE3DC6BD6EC547B1B0C\ +AE5B257BE36A7124E1060C170FFA:\ +248F4AEC829773B1E7525BD318960310B81316078474525BCEFD1AA71757FDE1\ +3483F9A30B0F53E538635FF9CABA15625F6DAF03478669EE60D054A90CB100DE + +5ACA56A03A13784BDC3289D9364F79E2A85C12276B49B92DB0ADAA4F206D5028\ +F213F678C3510E111F9DC4C1C1F8B6ACB17A6413AA227607C515C62A733817BA\ +5E762CC6748E7E0D6872C984D723C9BB3B117EB8963185300A80BFA65CDE495D\ +70A46C44858605FCCBED086C2B45CEF963D33294DBE9706B13AF22F1B7C4CD5A\ +001CFEC251FBA18E722C6E1C4B1166918B4F6F48A98B64B3C07FC86A6B17A6D0\ +480AB79D4E6415B520F1C484D675B1:\ +BA89BFC6C669413652B22BD2EB1E8C520FCE131FB9ADB84470E3163752EA7E6D\ +F663B3631E0629FA90BB05B738BD2BCBC1A83C4AE03E6845860BF027B73CBB20 + +A5AAD0E4646A32C85CFCAC73F02FC5300F1982FABB2F2179E28303E447854094\ +CDFC854310E5C0F60993CEFF54D84D6B46323D930ADB07C17599B35B505F09E7\ +84BCA5985E0172257797FB53649E2E9723EFD16865C31B5C3D5113B58BB0BFC8\ +920FABDDA086D7537E66D709D050BD14D0C960873F156FAD5B3D3840CDFCDC9B\ +E6AF519DB262A27F40896AB25CC39F96984D650611C0D5A3080D5B3A1BF186AB\ +D42956588B3B58CD948970D298776060:\ +011124D568ADA8413909D3E0C1BDB23EBF6389A80CC7EF03B9CA1556E70EC67C\ +81DE188C2DC900D4DF8DD7412ECEAAF91EB6495B4BC218B38722099D415D22A5 + +06CBBE67E94A978203EAD6C057A1A5B098478B4B4CBEF5A97E93C8E42F557271\ +3575FC2A884531D7622F8F879387A859A80F10EF02708CD8F7413AB385AFC357\ +678B9578C0EBF641EF076A1A30F1F75379E9DCB2A885BDD295905EE80C0168A6\ +2A9597D10CF12DD2D8CEE46645C7E5A141F6E0E23AA482ABE5661C16E69EF1E2\ +8371E2E236C359BA4E92C25626A7B7FF13F6EA4AE906E1CFE163E91719B1F750\ +A96CBDE5FBC953D9E576CD216AFC90323A:\ +8D03C8E3B207C306EB3BB093A4750176F3B458699731A7690FEC874363CF662A\ +2BD27C41FE86E4B410460C1581EC48A9D8F2AFB6C1BB91433AEC5C4147DC3F50 + +F1C528CF7739874707D4D8AD5B98F7C77169DE0B57188DF233B2DC8A5B31EDA5\ +DB4291DD9F68E6BAD37B8D7F6C9C0044B3BF74BBC3D7D1798E138709B0D75E7C\ +593D3CCCDC1B20C7174B4E692ADD820ACE262D45CCFAE2077E87879634716806\ +0A162ECCA8C38C1A88350BD63BB539134F700FD4ADDD5959E255337DAA06BC86\ +358FABCBEFDFB5BC889783D843C08AADC6C4F6C36F65F156E851C9A0F917E4A3\ +67B5AD93D874812A1DE6A7B93CD53AD97232:\ +14B3D36C24E80F3B0D7C69F01FCEDE9F109664541ED6E63C75271219BFFAD474\ +F130E984AC82B6B8DDF7F58D7FF93A931CFFEED7991F1FF7E07DEFD7E74F521D + +9D9F3A7ECD51B41F6572FD0D0881E30390DFB780991DAE7DB3B47619134718E6\ +F987810E542619DFAA7B505C76B7350C6432D8BF1CFEBDF1069B90A35F0D04CB\ +DF130B0DFC7875F4A4E62CDB8E525AADD7CE842520A482AC18F09442D78305FE\ +85A74E39E760A4837482ED2F437DD13B2EC1042AFCF9DECDC3E877E50FF4106A\ +D10A525230D11920324A81094DA31DEAB6476AA42F20C84843CFC1C58545EE80\ +352BDD3740DD6A16792AE2D86F11641BB717C2:\ +A2F336A9D8816018E4A1B8968D3BEF6800A3B390488AD2E2E119F18EA2B7522B\ +CF21DF4C5333BBCC5ECB3E9D9E8909DFC1733A417AF9F5B9FC4D8B9AABE7C650 + +5179888724819FBAD3AFA927D3577796660E6A81C52D98E9303261D5A4A83232\ +F6F758934D50AA83FF9E20A5926DFEBAAC49529D006EB923C5AE5048ED544EC4\ +71ED7191EDF46363383824F915769B3E688094C682B02151E5EE01E510B431C8\ +865AFF8B6B6F2F59CB6D129DA79E97C6D2B8FA6C6DA3F603199D2D1BCAB54768\ +2A81CD6CF65F6551121391D78BCC23B5BD0E922EC6D8BF97C952E84DD28AEF90\ +9ABA31EDB903B28FBFC33B7703CD996215A11238:\ +BED7C99B12478DE47C358637E8977FBC10FD763014196439611D1DE3D6479AED\ +20C5CB3897E70A4B9D428F689835A7E7C99177DD306333D12C5E6B7B88EAF5E4 + +576EF3520D30B7A4899B8C0D5E359E45C5189ADD100E43BE429A02FB3DE5FF4F\ +8FD0E79D9663ACCA72CD29C94582B19292A557C5B1315297D168FBB54E9E2ECD\ +13809C2B5FCE998EDC6570545E1499DBE7FB74D47CD7F35823B212B05BF3F5A7\ +9CAA34224FDD670D335FCB106F5D92C3946F44D3AFCBAE2E41AC554D8E6759F3\ +32B76BE89A0324AA12C5482D1EA3EE89DED4936F3E3C080436F539FA137E74C6\ +D3389BDF5A45074C47BC7B20B0948407A66D855E2F:\ +47F5829780E5F634981B4EA095F79CB05395B7FDC3430D4FE0316EDC20B7FCAC\ +81148B900AE95E356F2D194EB69FB6E6786FABC5BF8A6F13F56D881E2A4D6D27 + +0DF2152FA4F4357C8741529DD77E783925D3D76E95BAFA2B542A2C33F3D1D117\ +D159CF473F82310356FEE4C90A9E505E70F8F24859656368BA09381FA245EB6C\ +3D763F3093F0C89B972E66B53D59406D9F01AEA07F8B3B615CAC4EE4D05F542E\ +7D0DAB45D67CCCCD3A606CCBEB31EA1FA7005BA07176E60DAB7D78F6810EF086\ +F42F08E595F0EC217372B98970CC6321576D92CE38F7C397A403BADA1548D205\ +C343AC09DECA86325373C3B76D9F32028FEA8EB32515:\ +477AD92922C418C83FF158D20A806242D41670C1F8FD39315C6651D0D81E49FF\ +27D631892972C88D31FBF448EB135B2FCCA0873B2C37F2DDC0B0E71BAC857E8B + +3E15350D87D6EBB5C8AD99D42515CFE17980933C7A8F6B8BBBF0A63728CEFAAD\ +2052623C0BD5931839112A48633FB3C2004E0749C87A41B26A8B48945539D1FF\ +41A4B269462FD199BFECD45374756F55A9116E92093AC99451AEFB2AF9FD32D6\ +D7F5FBC7F7A540D5097C096EBC3B3A721541DE073A1CC02F7FB0FB1B9327FB0B\ +1218CA49C9487AB5396622A13AE546C97ABDEF6B56380DDA7012A8384091B665\ +6D0AB272D363CEA78163FF765CDD13AB1738B940D16CAE:\ +24ADD48203FC4772BE68A87FDEFEC3F762DD8945CF421697B70C6612BB19224F\ +EA974E3876FE3F2B745FA53F3A89E569989B735F63A46491E4627AFFD6B6CEFA + +C38D6B0B757CB552BE40940ECE0009EF3B0B59307C1451686F1A22702922800D\ +58BCE7A636C1727EE547C01B214779E898FC0E560F8AE7F61BEF4D75EAA696B9\ +21FD6B735D171535E9EDD267C192B99880C87997711002009095D8A7A437E258\ +104A41A505E5EF71E5613DDD2008195F0C574E6BA3FE40099CFA116E5F1A2FA8\ +A6DA04BADCB4E2D5D0DE31FDC4800891C45781A0AAC7C907B56D631FCA5CE8B2\ +CDE620D11D1777ED9FA603541DE794DDC5758FCD5FAD78C0:\ +8A7340C39AB7450164B915C02B6A6B5EE8361E4BF6EE43E931E3AD7EC3CCA66F\ +20558DF5EEAE5D56E9ABAD9A9F48F8ADC8646D55638993B27EA080226445E7EF + +8D2DE3F0B37A6385C90739805B170057F091CD0C7A0BC951540F26A5A75B3E69\ +4631BB64C7635EED316F51318E9D8DE13C70A2ABA04A14836855F35E480528B7\ +76D0A1E8A23B547C8B8D6A0D09B241D3BE9377160CCA4E6793D00A515DC2992C\ +B7FC741DACA171431DA99CCE6F7789F129E2AC5CF65B40D703035CD2185BB936\ +C82002DAF8CBC27A7A9E554B06196630446A6F0A14BA155ED26D95BD627B7205\ +C072D02B60DB0FD7E49EA058C2E0BA202DAFF0DE91E845CF79:\ +C18DA8AC3BD52C9C27AF65DDBB21C7DC87C65E5F6FE23C181CC2D76E6E35E0D6\ +DD8B2CE9C5B707D91459549F08FED2E28891658833818531829932372928FD4B + +C464BBDAD275C50DCD983B65AD1019B9FF85A1E71C807F3204BB2C921DC31FBC\ +D8C5FC45868AE9EF85B6C9B83BBA2A5A822201ED68586EC5EC27FB2857A5D1A2\ +D09D09115F22DCC39FE61F5E1BA0FF6E8B4ACB4C6DA748BE7F3F0839739394FF\ +7FA8E39F7F7E84A33C3866875C01BCB1263C9405D91908E9E0B50E7459FABB63\ +D8C6BBB73D8E3483C099B55BC30FF092FF68B6ADEDFD477D63570C9F5515847F\ +36E24BA0B705557130CEC57EBAD1D0B31A378E91894EE26E3A04:\ +F987CA0943562B86D5CB09CF4BDC06532B4BE5F4B349AFE31B50D1CC052E3638\ +79DBBD78C3D7F642F9A29E5DECB7888806811E9F2115132DABF6720F8EE42368 + +8B8D68BB8A75732FE272815A68A1C9C5AA31B41DEDC8493E76525D1D013D33CE\ +BD9E21A5BB95DB2616976A8C07FCF411F5F6BC6F7E0B57ACA78CC2790A6F9B89\ +8858AC9C79B165FF24E66677531E39F572BE5D81EB3264524181115F32780257\ +BFB9AEEC6AF12AF28E587CAC068A1A2953B59AD680F4C245B2E3EC36F59940D3\ +7E1D3DB38E13EDB29B5C0F404F6FF87F80FC8BE7A225FF22FBB9C8B6B1D7330C\ +57840D24BC75B06B80D30DAD6806544D510AF6C4785E823AC3E0B8:\ +A08812A778848BCC4CCDC27B297C2A39313EF0D2A3E490295C7AECC687163458\ +62768DD92EB7CB7F521AEEE5545A807ACCA74828AD13FF9AB9F7516FA76147FA + +6B018710446F368E7421F1BC0CCF562D9C1843846BC8D98D1C9BF7D9D6FCB48B\ +FC3BF83B36D44C4FA93430AF75CD190BDE36A7F92F867F58A803900DF8018150\ +384D85D82132F123006AC2AEBA58E02A037FE6AFBD65ECA7C44977DD3DC74F48\ +B6E7A1BFD5CC4DCF24E4D52E92BD4455848E4928B0EAC8B7476FE3CC03E862AA\ +4DFF4470DBFED6DE48E410F25096487ECFC32A27277F3F5023B2725ADE461B13\ +55889554A8836C9CF53BD767F5737D55184EEA1AB3F53EDD0976C485:\ +241EF5BC35C9FD842699C4BA03AFB4FED737CDBDE73B12CE0F7D118C92139C29\ +E9126AA81E3E06102BC3009043F0BEA6AE2E48C2D5D93A467991397F5E99D8FD + +C9534A24714BD4BE37C88A3DA1082EDA7CABD154C309D7BD670DCCD95AA53559\ +4463058A29F79031D6ECAA9F675D1211E9359BE82669A79C855EA8D89DD38C2C\ +761DDD0EC0CE9E97597432E9A1BEAE062CDD71EDFDFD464119BE9E69D18A7A7F\ +D7CE0E2106F0C8B0ABF4715E2CA48EF9F454DC203C96656653B727083513F8EF\ +B86E49C513BB758B3B052FE21F1C05BB33C37129D6CC81F1AEF6ADC45B0E8827\ +A830FE545CF57D0955802C117D23CCB55EA28F95C0D8C2F9C5A242B33F:\ +7F013A499D91DAD964C5D32F428EE352EBACD1B900F09186CA769A3B1C370D4F\ +CAC310C5F217DA581AC7B0202AE038AAE7E3F0CB484605C7F54CEE4FD3C3A272 + +07906C87297B867ABF4576E9F3CC7F82F22B154AFCBF293B9319F1B0584DA6A4\ +0C27B32E0B1B7F412C4F1B82480E70A9235B12EC27090A5A33175A2BB28D8ADC\ +475CEFE33F7803F8CE27967217381F02E67A3B4F84A71F1C5228E0C2AD971373\ +F6F672624FCEA8D1A9F85170FAD30FA0BBD25035C3B41A6175D467998BD1215F\ +6F3866F53847F9CF68EF3E2FBB54BC994DE2302B829C5EEA68EC441FCBAFD7D1\ +6AE4FE9FFF98BF00E5BC2AD54DD91FF9FDA4DD77B6C754A91955D1FBAAD0:\ +F9B6C3E55260AD9459E78CBF77EF9F46EE94658BEA13F31C34A1548355A4A301\ +7E11BFB20427F4A98B9ABFFB80C168FDCE3B58513D4E05B005B10B1CD41D1DAF + +588E94B9054ABC2189DF69B8BA34341B77CDD528E7860E5DEFCAA79B0C9A452A\ +D4B82AA306BE84536EB7CEDCBE058D7B84A6AEF826B028B8A0271B69AC3605A9\ +635EA9F5EA0AA700F3EB7835BC54611B922964300C953EFE7491E3677C2CEBE0\ +822E956CD16433B02C68C4A23252C3F9E151A416B4963257B783E038F6B4D5C9\ +F110F871652C7A649A7BCEDCBCCC6F2D0725BB903CC196BA76C76AA9F10A190B\ +1D1168993BAA9FFC96A1655216773458BEC72B0E39C9F2C121378FEAB4E76A:\ +41CAAC4E9A2258FE986991DE2FBDD35B0A44BFCD7E7AFB5826ABFD98407143B1\ +2661C4C5CC326A6A5002D4175B8CCC96CCFACA175671D67673E0E7A9B3A2EE43 + +08959A7E4BAAE874928813364071194E2939772F20DB7C3157078987C557C2A6\ +D5ABE68D520EEF3DC491692E1E21BCD880ADEBF63BB4213B50897FA005256ED4\ +1B5690F78F52855C8D9168A4B666FCE2DA2B456D7A7E7C17AB5F2FB1EE90B79E\ +698712E963715983FD07641AE4B4E9DC73203FAC1AE11FA1F8C7941FCC82EAB2\ +47ADDB56E2638447E9D609E610B60CE086656AAEBF1DA3C8A231D7D94E2FD0AF\ +E46B391FF14A72EAEB3F44AD4DF85866DEF43D4781A0B3578BC996C87970B132:\ +95B7B94203B6625E36BDF04A3F40E79209D5A8BF5B27C836068EB3E944F76FF7\ +6AC5086D1AA510F8CB560360E02FDE47C324DFA6412E31923BECF5B9A5CE74F7 + +CB2A234F45E2ECD5863895A451D389A369AAB99CFEF0D5C9FFCA1E6E63F763B5\ +C14FB9B478313C8E8C0EFEB3AC9500CF5FD93791B789E67EAC12FD038E2547CC\ +8E0FC9DB591F33A1E4907C64A922DDA23EC9827310B306098554A4A78F050262\ +DB5B545B159E1FF1DCA6EB734B872343B842C57EAFCFDA8405EEDBB48EF32E99\ +696D135979235C3A05364E371C2D76F1902F1D83146DF9495C0A6C57D7BF9EE7\ +7E80F9787AEE27BE1FE126CDC9EF893A4A7DCBBC367E40FE4E1EE90B42EA25AF\ +01:\ +9C212622F625449B5F09544816DE7792F99FDAE01405EB667210A8566E4A48FF\ +7948F1A8DA07CDB8ABE38660CA4D5D6E87B4D078493DA1A22574ECEA221E4FAA + +D16BEADF02AB1D4DC6F88B8C4554C51E866DF830B89C06E786A5F8757E890931\ +0AF51C840EFE8D20B35331F4355D80F73295974653DDD620CDDE4730FB6C8D0D\ +2DCB2B45D92D4FBDB567C0A3E86BD1A8A795AF26FBF29FC6C65941CDDB090FF7\ +CD230AC5268AB4606FCCBA9EDED0A2B5D014EE0C34F0B2881AC036E24E151BE8\ +9EEB6CD9A7A790AFCCFF234D7CB11B99EBF58CD0C589F20BDAC4F9F0E28F75E3\ +E04E5B3DEBCE607A496D848D67FA7B49132C71B878FD5557E082A18ECA1FBDA9\ +4D4B:\ +04EC35E912AF0ACB1914785EE00506E96D633E81ED6AD7B971CD0434EE61CCE6\ +F6FF3DC1BD1B1282E9A2A9D25D5480D4C6C47681212B24CDE68A632A0294ADEA + +8F65F6BC59A85705016E2BAE7FE57980DE3127E5AB275F573D334F73F8603106\ +EC3553016608EF2DD6E69B24BE0B7113BF6A760BA6E9CE1C48F9E186012CF96A\ +1D4849D75DF5BB8315387FD78E9E153E76F8BA7EC6C8849810F59FB4BB9B0043\ +18210B37F1299526866F44059E017E22E96CBE418699D014C6EA01C9F0038B10\ +299884DBEC3199BB05ADC94E955A1533219C1115FED0E5F21228B071F40DD57C\ +4240D98D37B73E412FE0FA4703120D7C0C67972ED233E5DEB300A22605472FA3\ +A3BA86:\ +177D4D8DAD1C6C05147B8D4FD8713E988CEF19B417810387B68B90DA075CDDDF\ +08C927328A69F4D21CD6E6CFF1B446F2980261BE7842ED07B7609D5FA23A13B9 + +84891E52E0D451813210C3FD635B39A03A6B7A7317B221A7ABC270DFA946C426\ +69AACBBBDF801E1584F330E28C729847EA14152BD637B3D0F2B38B4BD5BF9C79\ +1C58806281103A3EABBAEDE5E711E539E6A8B2CF297CF351C078B4FA8F7F35CF\ +61BEBF8814BF248A01D41E86C5715EA40C63F7375379A7EB1D78F27622FB468A\ +B784AAABA4E534A6DFD1DF6FA15511341E725ED2E87F98737CCB7B6A6DFAE416\ +477472B046BF1811187D151BFA9F7B2BF9ACDB23A3BE507CDF14CFDF517D2CB5\ +FB9E4AB6:\ +D109E4EA58F1E95BB67D4B4C33C23DCD91E8E659CCD2F71D63D63EF62445A4A0\ +029AF5F9B40280D8BD461DE3AAC765A8894568853B0E2146E407E1B31E5F7511 + +FDD7A9433A3B4AFABD7A3A5E3457E56DEBF78E84B7A0B0CA0E8C6D53BD0C2DAE\ +31B2700C6128334F43981BE3B213B1D7A118D59C7E6B6493A86F866A1635C128\ +59CFB9AD17460A77B4522A5C1883C3D6ACC86E6162667EC414E9A104AA892053\ +A2B1D72165A855BACD8FAF8034A5DD9B716F47A0818C09BB6BAF22AA503C06B4\ +CA261F557761989D2AFBD88B6A678AD128AF68672107D0F1FC73C5CA74045929\ +7B3292B281E93BCEB761BDE7221C3A55708E5EC84472CDDCAA84ECF23723CC09\ +91355C6280:\ +8973998BEF6F4971835BF108EC3A815AE1120557F39BA502979E963FC811D356\ +67B4614A09ADE41F9086166B614ACE97821EFB3E27F956E33FC1152905481E0A + +70A40BFBEF92277A1AAD72F6B79D0177197C4EBD432668CFEC05D099ACCB6510\ +62B5DFF156C0B27336687A94B26679CFDD9DAF7AD204338DD9C4D14114033A5C\ +225BD11F217B5F4732DA167EE3F939262D4043FC9CBA92303B7B5E96AEA12ADD\ +A64859DF4B86E9EE0B58E39091E6B188B408AC94E1294A8911245EE361E60E60\ +1EFF58D1D37639F3753BEC80EBB4EFDE25817436076623FC65415FE51D1B0280\ +366D12C554D86743F3C3B6572E400361A60726131441BA493A83FBE9AFDA90F7\ +AF1AE717238D:\ +537817B86EFAD56797435E4F81BF20791C52506554B550A14FEED4B8DE53A871\ +BB35D275D2C144B6A4F5626A8AEE56B6975F8B6D621C520E6DB30F710DEB7B73 + +74356E449F4BF8644F77B14F4D67CB6BD9C1F5AE357621D5B8147E562B65C665\ +85CAF2E491B48529A01A34D226D436959153815380D5689E30B35357CDAC6E08\ +D3F2B0E88E200600D62BD9F5EAF488DF86A4470EA227006182E44809009868C4\ +C280C43D7D64A5268FA719074960087B3A6ABC837882F882C837834535929389\ +A12B2C78187E2EA07EF8B8EEF27DC85002C3AE35F1A50BEE6A1C48BA7E175F33\ +16670B27983472AA6A61EED0A683A39EE323080620EA44A9F74411AE5CE99030\ +528F9AB49C79F2:\ +EB0B4CBCC5B846BF9342D74E6D555D7768A049F1CD4D98055BC3328C08477DA8\ +7CC9017215766F83CBF8E7C74204643F38741931672E178ECB6C33C6F97BD8A9 + +8C3798E51BC68482D7337D3ABB75DC9FFE860714A9AD73551E120059860DDE24\ +AB87327222B64CF774415A70F724CDF270DE3FE47DDA07B61C9EF2A3551F45A5\ +584860248FABDE676E1CD75F6355AA3EAEABE3B51DC813D9FB2EAA4F0F1D9F83\ +4D7CAD9C7C695AE84B329385BC0BEF895B9F1EDF44A03D4B410CC23A79A6B62E\ +4F346A5E8DD851C2857995DDBF5B2D717AEB847310E1F6A46AC3D26A7F9B4498\ +5AF656D2B7C9406E8A9E8F47DCB4EF6B83CAACF9AEFB6118BFCFF7E44BEF6937\ +EBDDC89186839B77:\ +75EDFA49C1995B191F5EE4689580A6C4A5AB9637C257AED28E8D9C0002EAB048\ +6E1AAA86FF81C8095EB21A7A04EAF33C8E637E771DB4EE970567870F0E0FFC00 + +FA56BF730C4F8395875189C10C4FB251605757A8FECC31F9737E3C2503B02608\ +E6731E85D7A38393C67DE516B85304824BFB135E33BF22B3A23B913BF6ACD2B7\ +AB85198B8187B2BCD454D5E3318CACB32FD6261C31AE7F6C54EF6A7A2A4C9F3E\ +CB81CE3555D4F0AD466DD4C108A90399D70041997C3B25345A9653F3C9A6711A\ +B1B91D6A9D2216442DA2C973CBD685EE7643BFD77327A2F7AE9CB283620A0871\ +6DFB462E5C1D65432CA9D56A90E811443CD1ECB8F0DE179C9CB48BA4F6FEC360\ +C66F252F6E64EDC96B:\ +689A1EE00FAA07E5CF96DA422ABE07962C42222B6B9928B761CFE7BA61762FE1\ +BE30267AD53B483E503B1EF21017C083DF32692C5D0CD65979B416F231A1F654 + +B6134F9C3E91DD8000740D009DD806240811D51AB1546A974BCB18D344642BAA\ +5CD5903AF84D58EC5BA17301D5EC0F10CCD0509CBB3FD3FFF9172D193AF0F782\ +252FD1338C7244D40E0E42362275B22D01C4C3389F19DD69BDF958EBE28E31A4\ +FFE2B5F18A87831CFB7095F58A87C9FA21DB72BA269379B2DC2384B3DA953C79\ +25761FED324620ACEA435E52B424A7723F6A2357374157A34CD8252351C25A1B\ +232826CEFE1BD3E70FFC15A31E7C0598219D7F00436294D11891B82497BC78AA\ +5363892A2495DF8C1EEF:\ +23A1FFD72251693480A286725193A64A83F11367DFB38F039F117FF7351934C9\ +009C83DB46BA13EE7C8CE2045C1F6E418963CDCD8FD051B8A71ADBC6481ECEAE + +C941CDB9C28AB0A791F2E5C8E8BB52850626AA89205BEC3A7E22682313D198B1\ +FA33FC7295381354858758AE6C8EC6FAC3245C6E454D16FA2F51C4166FAB51DF\ +272858F2D603770C40987F64442D487AF49CD5C3991CE858EA2A60DAB6A65A34\ +414965933973AC2457089E359160B7CDEDC42F29E10A91921785F6B7224EE0B3\ +49393CDCFF6151B50B377D609559923D0984CDA6000829B916AB6896693EF6A2\ +199B3C22F7DC5500A15B8258420E314C222BC000BC4E5413E6DD82C993F8330F\ +5C6D1BE4BC79F08A1A0A46:\ +3B8BF1BF8A10E06238CCF7CD7EF2694F942EF6C720381CDE80E0396F4560BB1B\ +B40FB6C3BF6CC08DF574C3EEEC1BEF8F27A1F9D33BA7344F502BCA40E7321636 + +4499EFFFAC4BCEA52747EFD1E4F20B73E48758BE915C88A1FFE5299B0B005837\ +A46B2F20A9CB3C6E64A9E3C564A27C0F1C6AD1960373036EC5BFE1A8FC6A435C\ +2185ED0F114C50E8B3E4C7ED96B06A036819C9463E864A58D6286F785E32A804\ +443A56AF0B4DF6ABC57ED5C2B185DDEE8489EA080DEEEE66AA33C2E6DAB36251\ +C402682B6824821F998C32163164298E1FAFD31BABBCFFB594C91888C6219079\ +D907FDB438ED89529D6D96212FD55ABE20399DBEFD342248507436931CDEAD49\ +6EB6E4A80358ACC78647D043:\ +25318513F5A4FFDF6CCB164F9A01286656B4F3F2F47CCCFCC9EBA895AB98C2BE\ +5EBE30BDD7573B471D3B952318BCD8D6D3BF8BD5427ABA6F039F7EB5031D3876 + +EECBB8FDFA4DA62170FD06727F697D81F83F601FF61E478105D3CB7502F2C89B\ +F3E8F56EDD469D049807A38882A7EEFBC85FC9A950952E9FA84B8AFEBD3CE782\ +D4DA598002827B1EB98882EA1F0A8F7AA9CE013A6E9BC462FB66C8D4A18DA214\ +01E1B93356EB12F3725B6DB1684F2300A98B9A119E5D27FF704AFFB618E12708\ +E77E6E5F34139A5A41131FD1D6336C272A8FC37080F041C71341BEE6AB550CB4\ +A20A6DDB6A8E0299F2B14BC730C54B8B1C1C487B494BDCCFD3A53535AB2F2315\ +90BF2C4062FD2AD58F906A2D0D:\ +093591FBF29F8D4D493F2F8890D2BA59A17C4D31F8D42288859365AF1B74E0CA\ +D8274493BFB2E0A0656EB09B447721E577BBBBB92E97A8CC32E6EEDDCDADAD58 + +E64F3E4ACE5C8418D65FEC2BC5D2A303DD458034736E3B0DF719098BE7A206DE\ +AF52D6BA82316CAF330EF852375188CDE2B39CC94AA449578A7E2A8E3F5A9D68\ +E816B8D16889FBC0EBF0939D04F63033AE9AE2BDAB73B88C26D6BD25EE460EE1\ +EF58FB0AFA92CC539F8C76D3D097E7A6A63EBB9B5887EDF3CF076028C5BBD5B9\ +DB3211371AD3FE121D4E9BF44229F4E1ECF5A0F9F0EBA4D5CEB72878AB22C3F0\ +EB5A625323AC66F7061F4A81FAC834471E0C59553F108475FE290D43E6A055AE\ +3EE46FB67422F814A68C4BE3E8C9:\ +2F911D4C83F7304E72E22E4412932D949654CC446EA5104F9BFA2AC82447B668\ +3097AA3E5E04615F1A1EF2A652CC2FCCAF1663B35ED33A711E37D14E520A2595 + +D2CB2D733033F9E91395312808383CC4F0CA974E87EC68400D52E96B3FA6984A\ +C58D9AD0938DDE5A973008D818C49607D9DE2284E7618F1B8AED8372FBD52ED5\ +4557AF4220FAC09DFA8443011699B97D743F8F2B1AEF3537EBB45DCC9E13DFB4\ +38428EE190A4EFDB3CAEB7F3933117BF63ABDC7E57BEB4171C7E1AD260AB0587\ +806C4D137B6316B50ABC9CCE0DFF3ACADA47BBB86BE777E617BBE578FF451984\ +4DB360E0A96C6701290E76BB95D26F0F804C8A4F2717EAC4E7DE9F2CFF3BBC55\ +A17E776C0D02856032A6CD10AD2838:\ +E1F645AB256B807E20C728F60F8594123359322355D32A42A559F0F7FDF873D2\ +15806C3E9375B70469FB0696246E396239DC0286815EB423026951A2CDA7AE0B + +F2998955613DD414CC111DF5CE30A995BB792E260B0E37A5B1D942FE90171A4A\ +C2F66D4928D7AD377F4D0554CBF4C523D21F6E5F379D6F4B028CDCB9B1758D3B\ +39663242FF3CB6EDE6A36A6F05DB3BC41E0D861B384B6DEC58BB096D0A422FD5\ +42DF175E1BE1571FB52AE66F2D86A2F6824A8CFAACBAC4A7492AD0433EEB1545\ +4AF8F312B3B2A577750E3EFBD370E8A8CAC1582581971FBA3BA4BD0D76E718DA\ +CF8433D33A59D287F8CC92234E7A271041B526E389EFB0E40B6A18B3AAF658E8\ +2ED1C78631FD23B4C3EB27C3FAEC8685:\ +7661221986EC665F0DE59D89DFE577A1489F1B92DAAF0D4AD3BCFE0F9551FB3F\ +F85AC4971B91787D06D0640941E303C054840AB3FE1EC8B2F2EFD650A11AD785 + +447797E2899B72A356BA55BF4DF3ACCA6CDB1041EB477BD1834A9F9ACBC340A2\ +94D729F2F97DF3A610BE0FF15EDB9C6D5DB41644B9874360140FC64F52AA03F0\ +286C8A640670067A84E017926A70438DB1BB361DEFEE7317021425F8821DEF26\ +D1EFD77FC853B818545D055ADC9284796E583C76E6FE74C9AC2587AA46AA8F88\ +04F2FEB5836CC4B3ABABAB8429A5783E17D5999F32242EB59EF30CD7ADABC16D\ +72DBDB097623047C98989F88D14EAF02A7212BE16EC2D07981AAA99949DDF89E\ +CD90333A77BC4E1988A82ABF7C7CAF3291:\ +62E8BC85C0BE0C756C0B8246D251D54B2680CC4C5F38B3748AB10C0DEED191A4\ +EFEB55A02A7177EFC1285801502758B2A865851F746347876DC20994911D2F0D + +9F2C18ADE9B380C784E170FB763E9AA205F64303067EB1BCEA93DF5DAC4BF5A2\ +E00B78195F808DF24FC76E26CB7BE31DC35F0844CDED1567BBA29858CFFC97FB\ +29010331B01D6A3FB3159CC1B973D255DA9843E34A0A4061CABDB9ED37F241BF\ +ABB3C20D32743F4026B59A4CCC385A2301F83C0B0A190B0F2D01ACB8F0D41111\ +E10F2F4E149379275599A52DC089B35FDD5234B0CFB7B6D8AEBD563CA1FA653C\ +5C021DFD6F5920E6F18BFAFDBECBF0AB00281333ED50B9A999549C1C8F8C63D7\ +626C48322E9791D5FF72294049BDE91E73F8:\ +EDB827225836DACAA2BAF1ACF153396E786722C78A67C8160B26C95068EA6FB0\ +2A95F3FAF9A2A25B4225C7347101C322A9F89059E11A01DAAD438BF9B47659A7 + +AE159F3FA33619002AE6BCCE8CBBDD7D28E5ED9D61534595C4C9F43C402A9BB3\ +1F3B301CBFD4A43CE4C24CD5C9849CC6259ECA90E2A79E01FFBAC07BA0E147FA\ +42676A1D668570E0396387B5BCD599E8E66AAED1B8A191C5A47547F61373021F\ +A6DEADCB55363D233C24440F2C73DBB519F7C9FA5A8962EFD5F6252C0407F190\ +DFEFAD707F3C7007D69FF36B8489A5B6B7C557E79DD4F50C06511F599F56C896\ +B35C917B63BA35C6FF8092BAF7D1658E77FC95D8A6A43EEB4C01F33F03877F92\ +774BE89C1114DD531C011E53A34DC248A2F0E6:\ +60EE213745C9CB94BC472F96E1BF9EF79C26BA3CEC017CC50A56DAE4E7C882D2\ +8E6425CC1DF5FEF68441AB13286E0407FA36C3280ED1E5ADDA4E33EE03F3D471 + +3B8E97C5FFC2D6A40FA7DE7FCEFC90F3B12C940E7AB415321E29EE692DFAC799\ +B009C99DCDDB708FCE5A178C5C35EE2B8617143EDC4C40B4D313661F49ABDD93\ +CEA79D117518805496FE6ACF292C4C2A1F76B403A97D7C399DAF85B46AD84E16\ +246C67D6836757BDE336C290D5D401E6C1386AB32797AF6BB251E9B2D8FE754C\ +47482B72E0B394EAB76916126FD68EA7D65EB93D59F5B4C5AC40F7C3B37E7F36\ +94F29424C24AF8C8F0EF59CD9DBF1D28E0E10F799A6F78CAD1D45B9DB3D7DEE4\ +A7059ABE99182714983B9C9D44D7F5643596D4F3:\ +FC1110441C703610FCF45C284C7232FC39E97D1EE83D44B4DC6D3EB0C3634184\ +804710E64CBEF1F6BEF193A6B903565C48AAEADB2B9EE9A66F370FF7D8A0621B + +3434EC31B10FAFDBFEEC0DD6BD94E80F7BA9DCA19EF075F7EB017512AF66D6A4\ +BCF7D16BA0819A1892A6372F9B35BCC7CA8155EE19E8428BC22D214856ED5FA9\ +374C3C09BDE169602CC219679F65A1566FC7316F4CC3B631A18FB4449FA6AFA1\ +6A3DB2BC4212EFF539C67CF184680826535589C7111D73BFFCE431B4C40492E7\ +63D9279560AAA38EB2DC14A212D723F994A1FE656FF4DD14551CE4E7C621B2AA\ +5604A10001B2878A897A28A08095C325E10A26D2FB1A75BFD64C250309BB55A4\ +4F23BBAC0D5516A1C687D3B41EF2FBBF9CC56D4739:\ +7AE06EEE293E04B371C06AAFF35F04549D87D36E8CF2B568EE3905B9EC11BCD6\ +EC62E2483BBCE0079AA9432FCAE99D67947ACCD4FFAA0DB1025392F1104E049A + +7C7953D81C8D208FD1C97681D48F49DD003456DE60475B84070EF4847C333B74\ +575B1FC8D2A186964485A3B8634FEAA3595AAA1A2F4595A7D6B6153563DEE31B\ +BAC443C8A33EED6D5D956A980A68366C2527B550EE950250DFB691EACBD5D56A\ +E14B970668BE174C89DF2FEA43AE52F13142639C884FD62A3683C0C3792F0F24\ +AB1318BCB27E21F4737FAB62C77EA38BC8FD1CF41F7DAB64C13FEBE7152BF5BB\ +7AB5A78F5346D43CC741CB6F72B7B8980F268B68BF62ABDFB1577A52438FE14B\ +591498CC95F071228460C7C5D5CEB4A7BDE588E7F21C:\ +91365C03B561AC61FDAE98ED1376AB5587AC1FF722155A873790B5165EF955BD\ +460434A838B15288B0B5EFC3D0CD0D8EDA5D6E09F87D731C873D22F35EAA392A + +7A6A4F4FDC59A1D223381AE5AF498D74B7252ECF59E389E49130C7EAEE626E7B\ +D9897EFFD92017F4CCDE66B0440462CDEDFD352D8153E6A4C8D7A0812F701CC7\ +37B5178C2556F07111200EB627DBC299CAA792DFA58F35935299FA3A3519E9B0\ +3166DFFA159103FFA35E8577F7C0A86C6B46FE13DB8E2CDD9DCFBA85BDDDCCE0\ +A7A8E155F81F712D8E9FE646153D3D22C811BD39F830433B2213DD46301941B5\ +9293FD0A33E2B63ADBD95239BC01315C46FDB678875B3C81E053A40F581CFBEC\ +24A1404B1671A1B88A6D06120229518FB13A74CA0AC5AE:\ +0B5816F638F9A1BB84B3CC174AC45D6A04015095906E399075099149429194A8\ +6E0E8BC6A8D699249EAB9D8A89A87C553D474F003C1222C721E295D1C1ACA5F0 + +D9FAA14CEBE9B7DE551B6C0765409A33938562013B5E8E0E1E0A6418DF7399D0\ +A6A771FB81C3CA9BD3BB8E2951B0BC792525A294EBD1083688806FE5E7F1E17F\ +D4E3A41D00C89E8FCF4A363CAEDB1ACB558E3D562F1302B3D83BB886ED27B760\ +33798131DAB05B4217381EAAA7BA15EC820BB5C13B516DD640EAEC5A27D05FDF\ +CA0F35B3A5312146806B4C0275BCD0AAA3B2017F346975DB566F9B4D137F4EE1\ +0644C2A2DA66DEECA5342E236495C3C6280528BFD32E90AF4CD9BB908F34012B\ +52B4BC56D48CC8A6B59BAB014988EABD12E1A0A1C2E170E7:\ +0A6F1F2ECA200D2191A4FA74AF69CD369A55574D96ECFB2EEAF6B51714925D5E\ +789B6926601776BF2F5F38D7189BF02ADB8E7F1BFD55B7D0E6188E9B6A81C01A + +2D8427433D0C61F2D96CFE80CF1E932265A191365C3B61AAA3D6DCC039F6BA2A\ +D52A6A8CC30FC10F705E6B7705105977FA496C1C708A277A124304F1FC40911E\ +7441D1B5E77B951AAD7B01FD5DB1B377D165B05BBF898042E39660CAF8B279FE\ +5229D1A8DB86C0999ED65E53D01CCBC4B43173CCF992B3A14586F6BA42F5FE30\ +AFA8AE40C5DF29966F9346DA5F8B35F16A1DE3AB6DE0F477D8D8660918060E88\ +B9B9E9CA6A4207033B87A812DBF5544D39E4882010F82B6CE005F8E8FF6FE3C3\ +806BC2B73C2B83AFB704345629304F9F86358712E9FAE3CA3E:\ +22E578997BB6985E3FFE451B513CBD38CA7A585F8EE89AFCBFE18F280C1A58FC\ +F748F148764DCBB732B8091606006A6D981EEF3311B0621ADF9F098F3DF72793 + +5E19D97887FCAAC0387E22C6F803C34A3DACD2604172433F7A8A7A526CA4A2A1\ +271ECFC5D5D7BE5AC0D85D921095350DFC65997D443C21C8094E0A3FEFD2961B\ +CB94AED03291AE310CCDA75D8ACE4BC7D89E7D3E5D1650BDA5D668B8B50BFC8E\ +608E184F4D3A9A2BADC4FF5F07E0C0BC8A9F2E0B2A26FD6D8C550008FAAAB75F\ +D71AF2A424BEC9A7CD9D83FAD4C8E9319115656A8717D3B523A68FF8004258B9\ +990ED362308461804BA3E3A7E92D8F2FFAE5C2FBA55BA5A3C27C0A2F71BD711D\ +2FE1799C2ADB31B200035481E9EE5C4ADF2AB9C0FA50B23975CF:\ +36F7E04B2CAD56BDDCAE84B77637F323CFF486B68359F271B6D91EA56D06CEC4\ +CED9BDF928A8ECC713F41D058250FACC1318F67743B8B40F354EBAAE351FDA86 + +C8E976AB4638909387CE3B8D4E510C3230E5690E02C45093B1D297910ABC481E\ +56EEA0F296F98379DFC9080AF69E73B2399D1C143BEE80AE1328162CE1BA7F6A\ +8374679B20AACD380EB4E61382C99998704D62701AFA914F9A2705CDB065885F\ +50D086C3EB5753700C387118BB142F3E6DA1E988DFB31AC75D7368931E45D139\ +1A274B22F83CEB072F9BCABC0B216685BFD789F5023971024B1878A205442522\ +F9EA7D8797A4102A3DF41703768251FD5E017C85D1200A464118AA35654E7CA3\ +9F3C375B8EF8CBE7534DBC64BC20BEFB417CF60EC92F63D9EE7397:\ +A4270E9F05E43A3F770AACA85020914A8B118B59297312B271B1AA4252BDE3BA\ +878EF3B3D0D33645A2847C6423279C478E7B1A7CE757F74E0128AD0D1C1966A4 + +7145FA124B7429A1FC2231237A949BA7201BCC1822D3272DE005B682398196C2\ +5F7E5CC2F289FBF44415F699CB7FE6757791B1443410234AE061EDF623359E2B\ +4E32C19BF88450432DD01CAA5EB16A1DC378F391CA5E3C4E5F356728BDDD4975\ +DB7C890DA8BBC84CC73FF244394D0D48954978765E4A00B593F70F2CA082673A\ +261ED88DBCEF1127728D8CD89BC2C597E9102CED6010F65FA75A14EBE467FA57\ +CE3BD4948B6867D74A9DF5C0EC6F530CBF2EE61CE6F06BC8F2864DFF5583776B\ +31DF8C7FFCB61428A56BF7BD37188B4A5123BBF338393AF46EDA85E6:\ +AD1A59ABE9786DBA20ECEA2CB6FB44A9EA5D8D89A220700508BB18CFCAD6ACCB\ +ACAC75A9E0882391F0FD2B5AD4274CCFB6277E7963A04D4E44A43161D7CCC30C + +7FDFADCC9D29BAD23AE038C6C65CDA1AEF757221B8872ED3D75FF8DF7DA0627D\ +266E224E812C39F7983E4558BFD0A1F2BEF3FEB56BA09120EF762917B9C09386\ +7948547AEE98600D10D87B20106878A8D22C64378BF634F7F75900C03986B077\ +B0BF8B740A82447B61B99FEE5376C5EB6680EC9E3088F0BDD0C56883413D60C1\ +357D3C811950E5890E7600103C916341B80C743C6A852B7B4FB60C3BA21F3BC1\ +5B8382437A68454779CF3CD7F9F90CCC8EF28D0B706535B1E4108EB5627BB45D\ +719CB046839AEE311CA1ABDC8319E050D67972CB35A6B1601B25DBF487:\ +696558AE97B276A78C5A32D9FC84BC068E369BB2471C2FD5DD30C3FE1D079557\ +090D0C10F83454A722A23681AC215B688C46C5EC2AB4BEC48A4A59F2686C29AE + +988638219FD3095421F826F56E4F09E356296B628C3CE6930C9F2E758FD1A80C\ +8273F2F61E4DAAE65C4F110D3E7CA0965AC7D24E34C0DC4BA2D6FF0BF5BBE93B\ +3585F354D7543CB542A1AA54674D375077F2D360A8F4D42F3DB131C3B7AB7306\ +267BA107659864A90C8C909460A73621D1F5D9D3FD95BEB19B23DB1CB6C0D0FB\ +A91D36891529B8BD8263CAA1BAB56A4AFFAED44962DF096D8D5B1EB845EF3118\ +8B3E10F1AF811A13F156BEB7A288AAE593EBD1471B624AA1A7C6ADF01E2200B3\ +D72D88A3AED3100C88231E41EFC376906F0B580DC895F080FDA5741DB1CB:\ +A199EF2227154794D6409C0439774B7127AC77E03E798AA4CADB21E95F19AAB4\ +429866C37711BE7527E42A966B344AA8F60415077E435FC3F87D7A4A4B309182 + +5AAB62756D307A669D146ABA988D9074C5A159B3DE85151A819B117CA1FF6597\ +F6156E80FDD28C9C3176835164D37DA7DA11D94E09ADD770B68A6E081CD22CA0\ +C004BFE7CD283BF43A588DA91F509B27A6584C474A4A2F3EE0F1F56447379240\ +A5AB1FB77FDCA49B305F07BA86B62756FB9EFB4FC225C86845F026EA542076B9\ +1A0BC2CDD136E122C659BE259D98E5841DF4C2F60330D4D8CDEE7BF1A0A24452\ +4EECC68FF2AEF5BF0069C9E87A11C6E519DE1A4062A10C83837388F7EF58598A\ +3846F49D499682B683C4A062B421594FAFBC1383C943BA83BDEF515EFCF10D:\ +FC2E7DE13ED475ED2A53102B46329134210FAD3938BDC20A5E6A8CDC325C6204\ +963D46AC350DBB626AD0FFBAB1A8B29C282DD5A6C3B1ADC38D9D8E1CC7100F0A + +47B8216AA0FBB5D67966F2E82C17C07AA2D6327E96FCD83E3DE7333689F3EE79\ +994A1BF45082C4D725ED8D41205CB5BCDF5C341F77FACB1DA46A5B9B2CBC49EA\ +DF786BCD881F371A95FA17DF73F606519AEA0FF79D5A11427B98EE7F13A5C006\ +37E2854134691059839121FEA9ABE2CD1BCBBBF27C74CAF3678E05BFB1C94989\ +7EA01F56FFA4DAFBE8644611685C617A3206C7A7036E4AC816799F693DAFE7F1\ +9F303CE4EBA09D21E03610201BFC665B72400A547A1E00FA9B7AD8D84F84B34A\ +EF118515E74DEF11B9188BD1E1F97D9A12C30132EC2806339BDADACDA2FD8B78:\ +6A7398EF52E606BFAEEADACC5031002265E9E5F279440E798A25461DF3335986\ +DBFACF54A484FFC20736796251B9474C8AA7CF6F70301900DABF1A572A1BCE7F + +8CFF1F67FE53C098896D9136389BD8881816CCAB34862BB67A656E3D98896F3C\ +E6FFD4DA73975809FCDF9666760D6E561C55238B205D8049C1CEDEEF374D1735\ +DAA533147BFA960B2CCE4A4F254176BB4D1BD1E89654432B8DBE1A135C42115B\ +394B024856A2A83DC85D6782BE4B444239567CCEC4B184D4548EAE3FF6A192F3\ +43292BA2E32A0F267F31CC26719EB85245D415FB897AC2DA433EE91A99424C9D\ +7F1766A44171D1651001C38FC79294ACCC68CEB5665D36218454D3BA169AE058\ +A831338C17743603F81EE173BFC0927464F9BD728DEE94C6AEAB7AAE6EE3A627\ +E8:\ +E7CD2794FACC6407A59E1F9630FE5728ED102CADD594D1504021D39A658634F2\ +5A5711F57CFDF5D69BC96A9AF8BD83EDFE2B4AD4297917B67582D211279CD9E6 + +EACD07971CFF9B9939903F8C1D8CBB5D4DB1B548A85D04E037514A583604E787\ +F32992BF2111B97AC5E8A938233552731321522AB5E8583561260B7D13EBEEF7\ +85B23A41FD8576A6DA764A8ED6D822D4957A545D5244756C18AA80E1AAD4D1F9\ +C20D259DEE1711E2CC8FD013169FB7CC4CE38B362F8E0936AE9198B7E838DCEA\ +4F7A5B9429BB3F6BBCF2DC92565E3676C1C5E6EB3DD2A0F86AA23EDD3D0891F1\ +97447692794B3DFA269611AD97F72B795602B4FDB198F3FD3EB41B415064256E\ +345E8D8C51C555DC8A21904A9B0F1AD0EFFAB7786AAC2DA3B196507E9F33CA35\ +6427:\ +CCDF5E0EEEA0CE7A7B56DF1AD74E9845384C747375C08DCF472698202A6BE369\ +6AD4A47A259FE195D863865BDD1DAB962721592CAD55A2F8AB42DF865D348709 + +23AC4E9A42C6EF45C3336CE6DFC2FF7DE8884CD23DC912FEF0F7756C09D335C1\ +89F3AD3A23697ABDA851A81881A0C8CCAFC980AB2C702564C2BE15FE4C4B9F10\ +DFB2248D0D0CB2E2887FD4598A1D4ACDA897944A2FFC580FF92719C95CF2AA42\ +DC584674CB5A9BC5765B9D6DDF5789791D15F8DD925AA12BFFAFBCE60827B490\ +BB7DF3DDA6F2A143C8BF96ABC903D83D59A791E2D62814A89B8080A28060568C\ +F24A80AE61179FE84E0FFAD00388178CB6A617D37EFD54CC01970A4A41D1A8D3\ +DDCE46EDBBA4AB7C90AD565398D376F431189CE8C1C33E132FEAE6A8CD17A61C\ +630012:\ +FA5AF2DDE57145CE00156176309499D6B4A801C806177B5A4CC972EF9D021376\ +76ABF467B2F74103DB1D97F555FD87DBE782C7A7E4EF7BC4D9A0BBBFAEC10CF0 + +0172DF732282C9D488669C358E3492260CBE91C95CFBC1E3FEA6C4B0EC129B45\ +F242ACE09F152FC6234E1BEE8AAB8CD56E8B486E1DCBA9C05407C2F95DA8D8F1\ +C0AF78EE2ED82A3A79EC0CB0709396EE62AADB84F8A4EE8A7CCCA3C1EE84E302\ +A09EA802204AFECF04097E67D0F8E8A9D2651126C0A598A37081E42D168B0AE8\ +A71951C524259E4E2054E535B779679BDADE566FE55700858618E626B4A0FAF8\ +95BCCE9011504A49E05FD56127EAE3D1F8917AFB548ECADABDA1020111FEC931\ +4C413498A360B08640549A22CB23C731ACE743252A8227A0D2689D4C60016066\ +78DFB921:\ +F09FA792B17868C35A49A69C75F1D6DF5A8A5273DBFDBCB904821401F3B71EC8\ +BCC96D28E9DC5B3B488B863C40235B1B9503845EF7614CB7A10B8839D907EC61 + +3875B9240CF3E0A8B59C658540F26A701CF188496E2C2174788B126FD29402D6\ +A75453BA0635284D08835F40051A2A9683DC92AFB9383719191231170379BA6F\ +4ADC816FECBB0F9C446B785BF520796841E58878B73C58D3EBB097CE4761FDEA\ +BE15DE2F319DFBAF1742CDEB389559C788131A6793E193856661376C81CE9568\ +DA19AA6925B47FFD77A43C7A0E758C37D69254909FF0FBD415EF8EB937BCD49F\ +91468B49974C07DC819ABD67395DB0E05874FF83DDDAB895344ABD0E7111B2DF\ +9E58D76D85AD98106B36295826BE04D435615595605E4B4BB824B33C4AFEB5E7\ +BB0D19F909:\ +32ABC489EBA1BCA1EDCB275224F9BEC0D1CF04ED2C33F518DB23EFCF0C64861F\ +B4FA2F28BDA1098588E2971B8CC39C9817B98A6D88E5748DB4B12DE8FDE6916D + +747CC1A59FEFBA94A9C75BA866C30DC5C1CB0C0F8E9361D98484956DD5D1A40F\ +6184AFBE3DAC9F76028D1CAECCFBF69199C6CE2B4C092A3F4D2A56FE5A33A007\ +57F4D7DEE5DFB0524311A97AE0668A47971B95766E2F6DD48C3F57841F91F04A\ +00AD5EA70F2D479A2620DC5CD78EAAB3A3B011719B7E78D19DDF70D9423798AF\ +77517EBC55392FCD01FC600D8D466B9E7A7A85BF33F9CC5419E9BD874DDFD609\ +81150DDAF8D7FEBAA4374F0872A5628D318000311E2F5655365AD4D407C20E5C\ +04DF17A222E7DEEC79C5AB1116D8572F91CD06E1CCC7CED53736FC867FD49ECE\ +BE6BF8082E8A:\ +21953763A36299B39B33610211A69F0F0AF1C74E3B11F392CA95E7B8E46987C0\ +BA31A11401EC3B781106024B4C07CCE4E738B06818B9D528FA1CEDA90D5A7E3A + +57AF971FCCAEC97435DC2EC9EF0429BCEDC6B647729EA168858A6E49AC1071E7\ +06F4A5A645CA14E8C7746D65511620682C906C8B86EC901F3DDED4167B3F00B0\ +6CBFAC6AEE3728051B3E5FF10B4F9ED8BD0B8DA94303C833755B3CA3AEDDF0B5\ +4BC8D6632138B5D25BAB03D17B3458A9D782108006F5BB7DE75B5C0BA854B423\ +D8BB801E701E99DC4FEAAD59BC1C7112453B04D33EA3635639FB802C73C2B71D\ +58A56BBD671B18FE34ED2E3DCA38827D63FDB1D4FB3285405004B2B3E26081A8\ +FF08CD6D2B08F8E7B7E90A2AB1ED7A41B1D0128522C2F8BFF56A7FE67969422C\ +E839A9D4608F03:\ +7E1821FB111387BFBED27202BDB87C9B6C97F4496BD3F36AD387644DA3902258\ +377BBAACF79EC3510C1381BFAE6F07BB71615DB43F5B3D67BDBE37D04235AE4C + +04E16DEDC1227902BAAF332D3D08923601BDD64F573FAA1BB7201918CFE16B1E\ +10151DAE875DA0C0D63C59C3DD050C4C6A874011B018421AFC4623AB0381831B\ +2DA2A8BA42C96E4F70864AC44E106F94311051E74C77C1291BF5DB9539E69567\ +BF6A11CF6932BBBAD33F8946BF5814C066D851633D1A513510039B349939BFD4\ +2B858C21827C8FF05F1D09B1B0765DC78A135B5CA4DFBA0801BCADDFA175623C\ +8B647EACFB4444B85A44F73890607D06D507A4F8393658788669F6EF4DEB58D0\ +8C50CA0756D5E2F49D1A7AD73E0F0B3D3B5F090ACF622B1878C59133E4A848E0\ +5153592EA81C6FBF:\ +47E3E3BEA0783D1938BE236D64A56E414E808A04FA8544908E958C00297B37C8\ +3F06766E4399F808DCAA746C3C0B26923810DF0FC01FFC5CBC514AD200EC9A4A + +7C815C384EEE0F288ECE27CCED52A01603127B079C007378BC5D1E6C5E9E6D1C\ +735723ACBBD5801AC49854B2B569D4472D33F40BBB8882956245C366DC3582D7\ +1696A97A4E19557E41E54DEE482A14229005F93AFD2C4A7D8614D10A97A9DFA0\ +7F7CD946FA45263063DDD29DB8F9E34DB60DAA32684F0072EA2A9426ECEBFA52\ +39FB67F29C18CBAA2AF6ED4BF4283936823AC1790164FEC5457A9CBA7C767CA5\ +9392D94CAB7448F50EB34E9A93A80027471CE59736F099C886DEA1AB4CBA4D89\ +F5FC7AE2F21CCD27F611ECA4626B2D08DC22382E92C1EFB2F6AFDC8FDC3D2172\ +604F5035C46B8197D3:\ +71888C037DB742E312F41B0C35A7DBF9251E2570434A572919618C5CBE5AE6A5\ +719991A7FE08AB8368B0E5FA1A4C2A69DBE5E102F2131BBE9256A30F83B13C93 + +E29D505158DBDD937D9E3D2145658EE6F5992A2FC790F4F608D9CDB44A091D5B\ +94B88E81FAC4FDF5C49442F13B911C55886469629551189EAFF62488F1A479B7\ +DB11A1560E198DDCCCCF50159093425FF7F1CB8D1D1246D0978764087D6BAC25\ +7026B090EFAE8CEC5F22B6F21C59ACE1AC7386F5B8837CA6A12B6FBF5534DD05\ +60EF05CA78104D3B943DDB220FEAEC89AA5E692A00F822A2AB9A2FE60350D75E\ +7BE16FF2526DC643872502D01F42F188ABED0A6E9A6F5FD0D1CE7D5755C9FFA6\ +6B0AF0B20BD806F08E06156690D81AC811778CA3DAC2C249B96002017FCE93E5\ +07E3B953ACF99964B847:\ +3A34914F60EF0640FD020D33511DD4702BB9D446DEEAC314DD69A29426A98707\ +A3EF3B568BD9BB4482B3C06E660BF247DCF4338469D46445FDE2E655DC8D5179 + +D85588696F576E65ECA0155F395F0CFACD83F36A99111ED5768DF2D116D2121E\ +32357BA4F54EDE927F189F297D3A97FAD4E9A0F5B41D8D89DD7FE20156799C2B\ +7B6BF9C957BA0D6763F5C3BC5129747BBB53652B49290CFF1C87E2CDF2C4B95D\ +8AAEE09BC8FBFA6883E62D237885810491BFC101F1D8C636E3D0EDE838AD05C2\ +07A3DF4FAD76452979EB99F29AFAECEDD1C63B8D36CF378454A1BB67A741C77A\ +C6B6B3F95F4F02B64DABC15438613EA49750DF42EE90101F115AA9ABB9FF6432\ +4DDE9DABBB01054E1BD6B4BCDC7930A44C2300D87CA78C06924D0323AD7887E4\ +6C90E8C4D100ACD9EED21E:\ +5544DC0EE3FF599ECB2886C96A7EBFE47673D03FA690666855F159F45861C57F\ +666EB0E5B57D1D211802861BDA5C283BF83CE9A8399748D576E2E0BF7DA083B9 + +3A12F8508B40C32C74492B66323375DCFE49184C78F73179F3314B79E63376B8\ +AC683F5A51F1534BD729B02B04D002F55CBD8E8FC9B5EC1EA6BBE6A0D0E74315\ +18E6BA45D124035F9D3DCE0A8BB7BF1430A9F657E0B4EA9F20EB20C786A58181\ +A1E20A96F1628F8728A13BDF7A4B4B32FC8AA7054CC4881AE7FA19AFA65C6C3E\ +E1B3ADE3192AF42054A8A911B8EC1826865D46D93F1E7C5E2B7813C92A506E53\ +886F3D4701BB93D2A681AD109C845904BB861AF8AF0646B6E399B38B614051D3\ +4F6842563A0F37EC00CB3D865FC5D746C4987DE2A65071100883A2A9C7A2BFE1\ +E2DD603D9EA24DC7C5FD06BE:\ +4875DBCB1EE61EDEBDA1F13D1AEEDF38995BB1C6BBA1440233B27367E251E75C\ +F5087EEC74F1FBA132D18FD4B6D6E72DE3E98943477783051ADDEEDDA3047C26 + +1861EDCE46FA5AD17E1FF1DEAE084DEC580F97D0A67885DFE834B9DFAC1AE076\ +742CE9E267512CA51F6DF5A455AF0C5FD6ABF94ACEA103A3370C354485A7846F\ +B84F3AC7C2904B5B2FBF227002CE512133BB7E1C4E50057BFD1E44DB33C7CDB9\ +69A99E284B184F50A14B068A1FC5009D9B298DBE92239572A7627AAC02ABE8F3\ +E3B473417F36D4D2505D16B7577F4526C9D94A270A2DFE450D06DA8F6FA95687\ +9A0A55CFE99E742EA555EA477BA3E9B44CCD508C375423611AF92E55345DC215\ +779B2D5119EBA49C71D49B9FE3F1569FA24E5CA3E332D042422A8B8158D3EC66\ +A80012976F31FFDF305F0C9C5E:\ +2D6A9F1D1BCF3FF53266A1E68CF2BBEB5EBA9B84534C36E8462471EE1CC14D5E\ +57123D6DD1FBE51EF6A2D111D97A332128044B122083498E132295F52DBCFCFD + +08D0FFDE3A6E4EF65608EA672E4830C12943D7187CCFF08F4941CFC13E545F3B\ +9C7AD5EEBBE2B01642B486CAF855C2C73F58C1E4E3391DA8E2D63D96E15FD849\ +53AE5C231911B00AD6050CD7AAFDAAC9B0F663AE6AAB45519D0F5391A541707D\ +479034E73A6AD805AE3598096AF078F1393301493D663DD71F83869CA27BA508\ +B7E91E81E128C1716DC3ACFE3084B2201E04CF8006617EECF1B640474A5D45CF\ +DE9F4D3EF92D6D055B909892194D8A8218DB6D8203A84261D200D71473D7488F\ +3427416B6896C137D455F231071CACBC86E0415AB88AEC841D96B7B8AF41E05B\ +B461A40645BF176601F1E760DE5F:\ +C709FCF02BF7DB2A73C6E8FAF1443FAB5E963C12C0BD5EC498FAD3BC5D769D42\ +8832AD6AB85B3299645993B7170685A3E2A25E8A3F8B822CDD31681A8BF1E180 + +D782ABB72A5BE3392757BE02D3E45BE6E2099D6F000D042C8A543F50ED6EBC05\ +5A7F133B0DD8E9BC348536EDCAAE2E12EC18E8837DF7A1B3C87EC46D50C241DE\ +E820FD586197552DC20BEEA50F445A07A38F1768A39E2B2FF05DDDEDF751F1DE\ +F612D2E4D810DAA3A0CC904516F9A43AF660315385178A529E51F8AAE141808C\ +8BC5D7B60CAC26BB984AC1890D0436EF780426C547E94A7B08F01ACBFC4A3825\ +EAE04F520A9016F2FB8BF5165ED12736FC71E36A49A73614739EAA3EC834069B\ +1B40F1350C2B3AB885C02C640B9F7686ED5F99527E41CFCD796FE4C256C91731\ +86C226169FF257954EBDA81C0E5F99:\ +EFAF0DD633F502AF10B5A14ABDC91D140892BBD5F3A6D7401099B2196FADF61E\ +9C6AA7123EC75AF0354FA1F55A3C1C68D9324368B2FB54CC6E370459B642B68D + +5FCE8109A358570E40983E1184E541833BB9091E280F258CFB144387B05D190E\ +431CB19BAA67273BA0C58ABE91308E1844DCD0B3678BAA42F335F2FA05267A02\ +40B3C718A5942B3B3E3BFA98A55C25A1466E8D7A603722CB2BBF03AFA54CD769\ +A99F310735EE5A05DAE2C22D397BD95635F58C48A67F90E1B73AAFCD3F82117F\ +0166657838691005B18DA6F341D6E90FC1CDB352B30FAE45D348294E501B6325\ +2DE14740F2B85AE5299DDEC3172DE8B6D0BA219A20A23BB5E10FF434D39DB3F5\ +83305E9F5C039D98569E377B75A70AB837D1DF269B8A4B566F40BB91B577455F\ +D3C356C914FA06B9A7CE24C7317A172D:\ +A9D32B2C3876DD44D5DA3FBBD12200B61D817834EA5E16E3487AAD3EFDF757D4\ +B11567232879F52FC6FC9A26F03595A2377A52D18872A71F6160111C5B1597F5 + +6172F1971A6E1E4E6170AFBAD95D5FEC99BF69B24B674BC17DD78011615E502D\ +E6F56B86B1A71D3F4348087218AC7B7D09302993BE272E4A591968AEF18A1262\ +D665610D1070EE91CC8DA36E1F841A69A7A682C580E836941D21D909A3AFC1F0\ +B963E1CA5AB193E124A1A53DF1C587470E5881FB54DAE1B0D840F0C8F9D1B04C\ +645BA1041C7D8DBF22030A623AA15638B3D99A2C400FF76F3252079AF88D2B37\ +F35EE66C1AD7801A28D3D388AC450B97D5F0F79E4541755356B3B1A5696B023F\ +39AB7AB5F28DF4202936BC97393B93BC915CB159EA1BD7A0A414CB4B7A1AC3AF\ +68F50D79F0C9C7314E750F7D02FAA58BFA:\ +18E8604561DA7971FA12B82807468750AC3177155BFD8EE32476CCA602BEDDDE\ +6FDE2DCEB474E5B69E7AE6CC4EA9CCF69A221D28AFE9002AF1B8DD03BB5166A3 + +5668ECD99DFBE215C4118398AC9C9EAF1A1433FAB4CCDD3968064752B625EA94\ +4731F75D48A27D047D67547F14DD0FFAA55FA5E29F7AF0D161D85EAFC4F2029B\ +717C918EAB9D304543290BDBA7158B68020C0BA4E079BC95B5BC0FC044A992B9\ +4B4CCD3BD66D0EABB5DBBAB904D62E00752C4E3B0091D773BCF4C14B4377DA3E\ +FFF824B1CB2FA01B32D1E46C909E626ED2DAE920F4C7DBEB635BC754FACBD8D4\ +9BEBA3F23C1C41CCBFCD0EE0C114E69737F5597C0BF1D859F0C767E18002AE8E\ +39C26261FFDE2920D3D0BAF0E906138696CFE5B7E32B600F45DF3AAA39932F3A\ +7DF95B60FA8712A2271FCAF3911CE7B511B1:\ +28282DCB2629E8F9EFEE080ABE51CEB7AFBE3A6E49FD3A2CAADEBAC24E12549B\ +7F0C20A71A03B52A96016CFAF31DD2C0237AA255BEAA867A1B53D31F7D8CAB15 + +03D625488354DF30E3F875A68EDFCF340E8366A8E1AB67F9D5C5486A96829DFA\ +C0578289082B2A62117E1CF418B43B90E0ADC881FC6AE8105C888E9ECD21AEA1\ +C9AE1A4038DFD17378FED71D02AE492087D7CDCD98F746855227967CB1AB4714\ +261EE3BEAD3F4DB118329D3EBEF4BC48A875C19BA763966DA0EBEA800E01B2F5\ +0B00E9DD4CACA6DCB314D00184EF71EA2391D760C950710DB4A70F9212FFC548\ +61F9DC752CE18867B8AD0C48DF8466EF7231E7AC567F0EB55099E622EBB86CB2\ +37520190A61C66AD34F1F4E289CB3282AE3EAAC6152ED24D2C92BAE5A7658252\ +A53C49B7B02DFE54FDB2E90074B6CF310AC661:\ +13D40918BED7651EB67B8AB70CC1C45A4B55070E898B1F3A462BD28CE20DBB24\ +FBEB0EBFDE934734ED1D7002094DD9D798CB9670E5423047DEDEA64A0B02DEF5 + +2EDC282FFB90B97118DD03AAA03B145F363905E3CBD2D50ECD692B37BF000185\ +C651D3E9726C690D3773EC1E48510E42B17742B0B0377E7DE6B8F55E00A8A4DB\ +4740CEE6DB0830529DD19617501DC1E9359AA3BCF147E0A76B3AB70C4984C13E\ +339E6806BB35E683AF8527093670859F3D8A0FC7D493BCBA6BB12B5F65E71E70\ +5CA5D6C948D66ED3D730B26DB395B3447737C26FAD089AA0AD0E306CB28BF0AC\ +F106F89AF3745F0EC72D534968CCA543CD2CA50C94B1456743254E358C1317C0\ +7A07BF2B0ECA438A709367FAFC89A57239028FC5FECFD53B8EF958EF10EE0608\ +B7F5CB9923AD97058EC067700CC746C127A61EE3:\ +68A370AC86CCE98209A9DB13174C27FD786820054FFDD09CA18B62112248A85D\ +A929A8E56F499D467DFB503AB5523C09317DD8E5C9D50BD4BE105086DAECA1DB + +90B28A6AA1FE533915BCB8E81ED6CACDC10962B7FF82474F845EEB86977600CF\ +70B07BA8E3796141EE340E3FCE842A38A50AFBE90301A3BDCC591F2E7D9DE53E\ +495525560B908C892439990A2CA2679C5539FFDF636777AD9C1CDEF809CDA9E8\ +DCDB451ABB9E9C17EFA4379ABD24B182BD981CAFC792640A183B61694301D04C\ +5B3EAAD694A6BD4CC06EF5DA8FA23B4FA2A64559C5A68397930079D250C51BCF\ +00E2B16A6C49171433B0AADFD80231276560B80458DD77089B7A1BBCC9E7E4B9\ +F881EACD6C92C4318348A13F4914EB27115A1CFC5D16D7FD94954C3532EFACA2\ +CAB025103B2D02C6FD71DA3A77F417D7932685888A:\ +CA5795E813341812738D01EDD488E424E7AD9B20AB6BDC119DD1FAA5C8FE81D8\ +08AF72F761EEA4FF6AADF4B676CEF23BD94E50DC750BDB95B1413BE258D3492F + +2969447D175490F2AA9BB055014DBEF2E6854C95F8D60950BFE8C0BE8DE254C2\ +6B2D31B9E4DE9C68C9ADF49E4EE9B1C2850967F29F5D08738483B417BB96B2A5\ +6F0C8ACA632B552059C59AAC3F61F7B45C966B75F1D9931FF4E596406378CEE9\ +1AAA726A3A84C33F37E9CDBE626B5745A0B06064A8A8D56E53AAF102D23DD9DF\ +0A3FDF7A638509A6761A33FA42FA8DDBD8E16159C93008B53765019C3F0E9F10\ +B144CE2AC57F5D7297F9C9949E4FF68B70D339F87501CE8550B772F32C6DA8AD\ +2CE2100A895D8B08FA1EEAD7C376B407709703C510B50F87E73E43F8E7348F87\ +C3832A547EF2BBE5799ABEDCF5E1F372EA809233F006:\ +AEBEA537873B9F4E686EA96CBA636DBB86C01E95C22998AA418478BE9F5C459D\ +125F0D50E1CB3046C09795E79FB2A2480F753BCF8A4A66B001FC37DB289CC7C0 + +721645633A44A2C78B19024EAECF58575AB23C27190833C26875DC0F0D50B46A\ +EA9C343D82EA7D5B3E50EC700545C615DAEAEA64726A0F05607576DCD396D812\ +B03FB6551C641087856D050B10E6A4D5577B82A98AFB89CEE8594C9DC19E79FE\ +FF0382FCFD127F1B803A4B9946F4AC9A4378E1E6E041B1389A53E3450CD32D9D\ +2941B0CBABDB50DA8EA2513145164C3AB6BCBD251C448D2D4B087AC57A59C228\ +5D564F16DA4ED5E607ED979592146FFB0EF3F3DB308FB342DF5EB5924A48256F\ +C763141A278814C82D6D6348577545870AE3A83C7230AC02A1540FE1798F7EF0\ +9E335A865A2AE0949B21E4F748FB8A51F44750E213A8FB:\ +AD29A31BB70BAA848D6837251D4892E7C9B1FDBB07B2DFB1F88158D76CA2C194\ +1924EE62EAD10C053EE0EC6CEA8BBC4F08EC4DEBB90B80AAA6AC91CE190078EC + +6B860D39725A14B498BB714574B4D37CA787404768F64C648B1751B353AC92BA\ +C2C3A28EA909FDF0423336401A02E63EC24325300D823B6864BB701F9D7C7A1F\ +8EC9D0AE3584AA6DD62EA1997CD831B4BABD9A4DA50932D4EFDA745C61E41308\ +90E156AEE6113716DAF95764222A91187DB2EFFEA49D5D0596102D619BD26A61\ +6BBFDA8335505FBB0D90B4C180D1A2335B91538E1668F9F9642790B4E55F9CAB\ +0FE2BDD2935D001EE6419ABAB5457880D0DBFF20ED8758F4C20FE759EFB33141\ +CF0E892587FE8187E5FBC57786B7E8B089612C936DFC03D27EFBBE7C8673F160\ +6BD51D5FF386F4A7AB68EDF59F385EB1291F117BFE717399:\ +918F9F10D39C9C75786958573AC487B3A66FAD5AF00C47FC359E1042EE01673B\ +C7DE432E34C84A84C8D7AAE9223B833348A8AEAB102D581A4D51EE5C9A554CEC + +6A01830AF3889A25183244DECB508BD01253D5B508AB490D3124AFBF42626B2E\ +70894E9B562B288D0A2450CFACF14A0DDAE5C04716E5A0082C33981F6037D23D\ +5E045EE1EF2283FB8B6378A914C5D9441627A722C282FF452E25A7EA608D69CE\ +E4393A0725D17963D0342684F255496D8A18C2961145315130549311FC07F031\ +2FB78E6077334F87EAA873BEE8AA95698996EB21375EB2B4EF53C14401207DEB\ +4568398E5DD9A7CF97E8C9663E23334B46912F8344C19EFCF8C2BA6F04325F1A\ +27E062B62A58D0766FC6DB4D2C6A1928604B0175D872D16B7908EBC041761187\ +CC785526C2A3873FEAC3A642BB39F5351550AF9770C328AF7B:\ +EA67ECB1057F745B90EDC6327F94320AD9B452889B079E9FC39F5440F795502C\ +3939DD7B393B54C608CF6519902F8D2B3E20629DF4CBF7BB54AEE5525F206489 + +B3C5E74B69933C2533106C563B4CA20238F2B6E675E8681E34A389894785BDAD\ +E59652D4A73D80A5C85BD454FD1E9FFDAD1C3815F5038E9EF432AAC5C3C4FE84\ +0CC370CF86580A6011778BBEDAF511A51B56D1A2EB68394AA299E26DA9ADA6A2\ +F39B9FAFF7FBA457689B9C1A577B2A1E505FDF75C7A0A64B1DF81B3A356001BF\ +0DF4E02A1FC59F651C9D585EC6224BB279C6BEBA2966E8882D68376081B98746\ +8E7AED1EF90EBD090AE825795CDCA1B4F09A979C8DFC21A48D8A53CDBB26C4DB\ +547FC06EFE2F9850EDD2685A4661CB4911F165D4B63EF25B87D0A96D3DFF6AB0\ +758999AAD214D07BD4F133A6734FDE445FE474711B69A98F7E2B:\ +86995F59B4D11D960E5A6DD3FFC513BE7659D1957159284477472B61504E1055\ +B51F07C253EE597426BF18308E5C807D8A8FDDA683FA8EE2A0556B8507B663F4 + +83AF34279CCB5430FEBEC07A81950D30F4B66F484826AFEE7456F0071A51E1BB\ +C55570B5CC7EC6F9309C17BF5BEFDD7C6BA6E968CF218A2B34BD5CF927AB846E\ +38A40BBD81759E9E33381016A755F699DF35D660007B5EADF292FEEFB735207E\ +BF70B5BD17834F7BFA0E16CB219AD4AF524AB1EA37334AA66435E5D397FC0A06\ +5C411EBBCE32C240B90476D307CE802EC82C1C49BC1BEC48C0675EC2A6C6F3ED\ +3E5B741D13437095707C565E10D8A20B8C20468FF9514FCF31B4249CD82DCEE5\ +8C0A2AF538B291A87E3390D737191A07484A5D3F3FB8C8F15CE056E5E5F8FEBE\ +5E1FB59D6740980AA06CA8A0C20F5712B4CDE5D032E92AB89F0AE1:\ +09B7DEB81713594A5938A41083F728DF3F0BF93BF0EBE61DB6982885D96B40A5\ +112E7440BBA919D259F6F8173FF0942BDFE95B65BB22BF62606FF49998AF4C0A + +A7ED84749CCC56BB1DFBA57119D279D412B8A986886D810F067AF349E8749E9E\ +A746A60B03742636C464FC1EE233ACC52C1983914692B64309EDFDF29F1AB912\ +EC3E8DA074D3F1D231511F5756F0B6EEAD3E89A6A88FE330A10FACE267BFFBFC\ +3E3090C7FD9A850561F363AD75EA881E7244F80FF55802D5EF7A1A4E7B89FCFA\ +80F16DF54D1B056EE637E6964B9E0FFD15B6196BDD7DB270C56B47251485348E\ +49813B4EB9ED122A01B3EA45AD5E1A929DF61D5C0F3E77E1FDC356B63883A60E\ +9CBB9FC3E00C2F32DBD469659883F690C6772E335F617BC33F161D6F6984252E\ +E12E62B6000AC5231E0C9BC65BE223D8DFD94C5004A101AF9FD6C0FB:\ +4B0469116292A76D4767F4FAAA420BDB66F8578D39390E65E5858ACE28715944\ +A394AA7903F2BC1B466A5F3E1EFD8EE56EFB42D71D877C4BD9666B24D677D9E9 + +A6FE30DCFCDA1A329E82AB50E32B5F50EB25C873C5D2305860A835AECEE6264A\ +A36A47429922C4B8B3AFD00DA16035830EDB897831C4E7B00F2C23FC0B15FDC3\ +0D85FB70C30C431C638E1A25B51CAF1D7E8B050B7F89BFB30F59F0F20FECFF3D\ +639ABC4255B3868FC45DD81E47EB12AB40F2AAC735DF5D1DC1AD997CEFC4D836\ +B854CEE9AC02900036F3867FE0D84AFFF37BDE3308C2206C62C4743375094108\ +877C73B87B2546FE05EA137BEDFC06A2796274099A0D554DA8F7D7223A48CBF3\ +1B7DECAA1EBC8B145763E3673168C1B1B715C1CD99ECD3DDB238B06049885ECA\ +D9347C2436DFF32C771F34A38587A44A82C5D3D137A03CAA27E66C8FF6:\ +B4FF987CD5FB38C70E24DF63FC1EE4C237E992028E92F6470C721501E5761380\ +C89E590538C3EF9060DE9D957CBC18CB4E0F2AE429E934FE433725EDD6C3F4FA + +83167FF53704C3AA19E9FB3303539759C46DD4091A52DDAE9AD86408B6933598\ +9E61414BC20AB4D01220E35241EFF5C9522B079FBA597674C8D716FE441E5661\ +10B6211531CECCF8FD06BC8E511D00785E57788ED9A1C5C73524F01830D2E114\ +8C92D0EDC97113E3B7B5CD3049627ABDB8B39DD4D6890E0EE91993F92B03354A\ +88F52251C546E64434D9C3D74544F23FB93E5A2D2F1FB15545B4E1367C97335B\ +0291944C8B730AD3D4789273FA44FB98D78A36C3C3764ABEEAC7C569C1E43A35\ +2E5B770C3504F87090DEE075A1C4C85C0C39CF421BDCC615F9EFF6CB4FE64680\ +04AECE5F30E1ECC6DB22AD9939BB2B0CCC96521DFBF4AE008B5B46BC006E:\ +36CE68F98A2A0910E1030C58EAA78631A6509BBA62A524E3B59AE3562B66CFB3\ +42DE8155AA9899205FD8005BF1535A986F84CB16BBBE309C33855C85721CA09F + +3A3A819C48EFDE2AD914FBF00E18AB6BC4F14513AB27D0C178A188B61431E7F5\ +623CB66B23346775D386B50E982C493ADBBFC54B9A3CD383382336A1A0B2150A\ +15358F336D03AE18F666C7573D55C4FD181C29E6CCFDE63EA35F0ADF5885CFC0\ +A3D84A2B2E4DD24496DB789E663170CEF74798AA1BBCD4574EA0BBA40489D764\ +B2F83AADC66B148B4A0CD95246C127D5871C4F11418690A5DDF01246A0C80A43\ +C70088B6183639DCFDA4125BD113A8F49EE23ED306FAAC576C3FB0C1E256671D\ +817FC2534A52F5B439F72E424DE376F4C565CCA82307DD9EF76DA5B7C4EB7E08\ +5172E328807C02D011FFBF33785378D79DC266F6A5BE6BB0E4A92ECEEBAEB1:\ +E47D7A2CA60627F7A1416FF0E0CC9F9E6CE06A1E01A4F6D58F516927032AC757\ +1CA29BB3299430E48AFF05FF0C025BE561002C9FBA30E63B24A3E35469F904D1 + # FORK-256 vectors generated by the implementation in Botan; there is only one # test vector, and it only covers the compression function, not the entire # hash. The implementation of FORK-256 used to generate these vectors did pass diff --git a/doc/examples/bench.cpp b/doc/examples/bench.cpp index 37ef1104d..5bb8e27bf 100644 --- a/doc/examples/bench.cpp +++ b/doc/examples/bench.cpp @@ -7,26 +7,6 @@ using namespace Botan; #include -double best_speed(const std::string& algorithm, - u32bit milliseconds, - RandomNumberGenerator& rng, - Timer& timer) - { - std::map speeds = - algorithm_benchmark(algorithm, milliseconds, - timer, rng, - global_state().algorithm_factory()); - - double best_time = 0; - - for(std::map::const_iterator i = speeds.begin(); - i != speeds.end(); ++i) - if(i->second > best_time) - best_time = i->second; - - return best_time; - } - const std::string algos[] = { "AES-128", "AES-192", @@ -62,7 +42,6 @@ const std::string algos[] = { "FORK-256", "GOST-34.11", "HAS-160", - "HAS-V", "MD2", "MD4", "MD5", @@ -89,10 +68,28 @@ int main() AutoSeeded_RNG rng; Default_Benchmark_Timer timer; + Algorithm_Factory& af = global_state().algorithm_factory(); + + std::vector providers = af.providers_of("Serpent"); + for(size_t i = 0; i != providers.size(); ++i) + std::cout << providers[i].c_str() << "\n"; + + + for(u32bit i = 0; algos[i] != ""; ++i) { std::string algo = algos[i]; - std::cout << algo << ' ' - << best_speed(algo, milliseconds, rng, timer) << "\n"; + + std::map speeds = + algorithm_benchmark(algos[i], milliseconds, timer, rng, af); + + std::cout << algo << ":"; + + for(std::map::const_iterator i = speeds.begin(); + i != speeds.end(); ++i) + { + std::cout << " " << i->second << " [" << i->first << "]"; + } + std::cout << "\n"; } } diff --git a/doc/log.txt b/doc/log.txt index 4fa9da368..df48d532c 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -1,6 +1,7 @@ * 1.9.1-pre, 2009-??-?? - Enable SSE2 optimizations under Visual C++ + - Add an implementation of Blue Midnight Wish (BMW-512) - Alter Skein-512 to match the tweaked 1.2 specification * 1.9.0, 2009-09-09 diff --git a/src/engine/def_engine/lookup_hash.cpp b/src/engine/def_engine/lookup_hash.cpp index 58136fc5a..9b2018736 100644 --- a/src/engine/def_engine/lookup_hash.cpp +++ b/src/engine/def_engine/lookup_hash.cpp @@ -22,6 +22,10 @@ #include #endif +#if defined(BOTAN_HAS_BMW_512) + #include +#endif + #if defined(BOTAN_HAS_FORK_256) #include #endif @@ -103,6 +107,11 @@ Default_Engine::find_hash(const SCAN_Name& request, return new CRC32; #endif +#if defined(BOTAN_HAS_BMW_512) + if(request.algo_name() == "BMW-512") + return new BMW_512; +#endif + #if defined(BOTAN_HAS_FORK_256) if(request.algo_name() == "FORK-256") return new FORK_256; diff --git a/src/hash/bmw/bmw_512.cpp b/src/hash/bmw/bmw_512.cpp new file mode 100644 index 000000000..42389beea --- /dev/null +++ b/src/hash/bmw/bmw_512.cpp @@ -0,0 +1,174 @@ +/* +* Blue Midnight Wish 512 +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include + +#include + +namespace Botan { + +namespace { + +inline u64bit S0(u64bit X) + { + return (X >> 1) ^ (X << 3) ^ rotate_left(X, 4) ^ rotate_left(X, 37); + } + +inline u64bit S1(u64bit X) + { + return (X >> 1) ^ (X << 2) ^ rotate_left(X, 13) ^ rotate_left(X, 43); + } + +inline u64bit S2(u64bit X) + { + return (X >> 2) ^ (X << 1) ^ rotate_left(X, 19) ^ rotate_left(X, 53); + } + +inline u64bit S3(u64bit X) + { + return (X >> 2) ^ (X << 2) ^ rotate_left(X, 28) ^ rotate_left(X, 59); + } + +inline u64bit S4(u64bit X) + { + return (X >> 1) ^ X; + } +} + +void BMW_512::compress_n(const byte input[], u32bit blocks) + { + for(u32bit i = 0; i != blocks; ++i) + { + u64bit Q[32] = { 0 }; + u64bit M[16] = { 0 }; + + for(u32bit j = 0; j != 16; ++j) + H[j] ^= M[j] = load_le(input, j); + input += HASH_BLOCK_SIZE; + + Q[ 0] = H[ 5] - H[ 7] + H[10] + H[13] + H[14]; + Q[ 1] = H[ 6] - H[ 8] + H[11] + H[14] - H[15]; + Q[ 2] = H[ 0] + H[ 7] + H[ 9] - H[12] + H[15]; + Q[ 3] = H[ 0] - H[ 1] + H[ 8] - H[10] + H[13]; + Q[ 4] = H[ 1] + H[ 2] + H[ 9] - H[11] - H[14]; + Q[ 5] = H[ 3] - H[ 2] + H[10] - H[12] + H[15]; + Q[ 6] = H[ 4] - H[ 0] - H[ 3] - H[11] + H[13]; + Q[ 7] = H[ 1] - H[ 4] - H[ 5] - H[12] - H[14]; + Q[ 8] = H[ 2] - H[ 5] - H[ 6] + H[13] - H[15]; + Q[ 9] = H[ 0] - H[ 3] + H[ 6] - H[ 7] + H[14]; + Q[10] = H[ 8] - H[ 1] - H[ 4] - H[ 7] + H[15]; + Q[11] = H[ 8] - H[ 0] - H[ 2] - H[ 5] + H[ 9]; + Q[12] = H[ 1] + H[ 3] - H[ 6] - H[ 9] + H[10]; + Q[13] = H[ 2] + H[ 4] + H[ 7] + H[10] + H[11]; + Q[14] = H[ 3] - H[ 5] + H[ 8] - H[11] - H[12]; + Q[15] = H[12] - H[ 4] - H[ 6] - H[ 9] + H[13]; + + Q[ 0] = S0(Q[ 0]); + Q[ 1] = S1(Q[ 1]); + Q[ 2] = S2(Q[ 2]); + Q[ 3] = S3(Q[ 3]); + Q[ 4] = S4(Q[ 4]); + Q[ 5] = S0(Q[ 5]); + Q[ 6] = S1(Q[ 6]); + Q[ 7] = S2(Q[ 7]); + Q[ 8] = S3(Q[ 8]); + Q[ 9] = S4(Q[ 9]); + Q[10] = S0(Q[10]); + Q[11] = S1(Q[11]); + Q[12] = S2(Q[12]); + Q[13] = S3(Q[13]); + Q[14] = S4(Q[14]); + Q[15] = S0(Q[15]); + + for(u32bit j = 16; j != 18; ++j) + { + Q[j] = S1(Q[j-16]) + S2(Q[j-15]) + S3(Q[j-14]) + S0(Q[j-13]) + + S1(Q[j-12]) + S2(Q[j-11]) + S3(Q[j-10]) + S0(Q[j- 9]) + + S1(Q[j- 8]) + S2(Q[j- 7]) + S3(Q[j- 6]) + S0(Q[j- 5]) + + S1(Q[j- 4]) + S2(Q[j- 3]) + S3(Q[j- 2]) + S0(Q[j- 1]) + + M[j-16] + M[j-13] - M[j-6] + + (0x0555555555555555 * j); + } + + for(u32bit j = 18; j != 32; ++j) + { + Q[j] = Q[j-16] + rotate_left(Q[j-15], 5) + + Q[j-14] + rotate_left(Q[j-13], 11) + + Q[j-12] + rotate_left(Q[j-11], 27) + + Q[j-10] + rotate_left(Q[j- 9], 32) + + Q[j- 8] + rotate_left(Q[j- 7], 37) + + Q[j- 6] + rotate_left(Q[j- 5], 43) + + Q[j- 4] + rotate_left(Q[j- 3], 53) + + (Q[j- 2] >> 2 ^ Q[j- 2]) + S4(Q[j- 1]) + + M[j-16] + M[(j-13) % 16] - M[(j-6) % 16] + + (0x0555555555555555 * j); + } + + u64bit XL = Q[16] ^ Q[17] ^ Q[18] ^ Q[19] ^ + Q[20] ^ Q[21] ^ Q[22] ^ Q[23]; + + u64bit XH = Q[24] ^ Q[25] ^ Q[26] ^ Q[27] ^ + Q[28] ^ Q[29] ^ Q[30] ^ Q[31]; + + XH ^= XL; + + H[ 0] = ((XH << 5) ^ (Q[16] >> 5) ^ M[0]) + (XL ^ Q[24] ^ Q[0]); + H[ 1] = ((XH >> 7) ^ (Q[17] << 8) ^ M[1]) + (XL ^ Q[25] ^ Q[1]); + H[ 2] = ((XH >> 5) ^ (Q[18] << 5) ^ M[2]) + (XL ^ Q[26] ^ Q[2]); + H[ 3] = ((XH >> 1) ^ (Q[19] << 5) ^ M[3]) + (XL ^ Q[27] ^ Q[3]); + H[ 4] = ((XH >> 3) ^ (Q[20] ) ^ M[4]) + (XL ^ Q[28] ^ Q[4]); + H[ 5] = ((XH << 6) ^ (Q[21] >> 6) ^ M[5]) + (XL ^ Q[29] ^ Q[5]); + H[ 6] = ((XH >> 4) ^ (Q[22] << 6) ^ M[6]) + (XL ^ Q[30] ^ Q[6]); + H[ 7] = ((XH >> 11) ^ (Q[23] << 2) ^ M[7]) + (XL ^ Q[31] ^ Q[7]); + + H[ 8] = rotate_left(H[4], 9) + (XH ^ Q[24] ^ M[ 8]) + ((XL << 8) ^ Q[23] ^ Q[ 8]); + H[ 9] = rotate_left(H[5], 10) + (XH ^ Q[25] ^ M[ 9]) + ((XL >> 6) ^ Q[16] ^ Q[ 9]); + H[10] = rotate_left(H[6], 11) + (XH ^ Q[26] ^ M[10]) + ((XL << 6) ^ Q[17] ^ Q[10]); + H[11] = rotate_left(H[7], 12) + (XH ^ Q[27] ^ M[11]) + ((XL << 4) ^ Q[18] ^ Q[11]); + H[12] = rotate_left(H[0], 13) + (XH ^ Q[28] ^ M[12]) + ((XL >> 3) ^ Q[19] ^ Q[12]); + H[13] = rotate_left(H[1], 14) + (XH ^ Q[29] ^ M[13]) + ((XL >> 4) ^ Q[20] ^ Q[13]); + H[14] = rotate_left(H[2], 15) + (XH ^ Q[30] ^ M[14]) + ((XL >> 7) ^ Q[21] ^ Q[14]); + H[15] = rotate_left(H[3], 16) + (XH ^ Q[31] ^ M[15]) + ((XL >> 2) ^ Q[22] ^ Q[15]); + } + } + +/* +* Copy out the digest +*/ +void BMW_512::copy_out(byte output[]) + { + for(u32bit i = 0; i != OUTPUT_LENGTH; i += 8) + store_le(H[8 + i/8], output + i); + } + +/* +* Clear memory of sensitive data +*/ +void BMW_512::clear() throw() + { + MDx_HashFunction::clear(); + H[ 0] = 0x8081828384858687; + H[ 1] = 0x88898A8B8C8D8E8F; + H[ 2] = 0x9091929394959697; + H[ 3] = 0x98999A9B9C9D9E9F; + H[ 4] = 0xA0A1A2A3A4A5A6A7; + H[ 5] = 0xA8A9AAABACADAEAF; + H[ 6] = 0xB0B1B2B3B4B5B6B7; + H[ 7] = 0xB8B9BABBBCBDBEBF; + H[ 8] = 0xC0C1C2C3C4C5C6C7; + H[ 9] = 0xC8C9CACBCCCDCECF; + H[10] = 0xD0D1D2D3D4D5D6D7; + H[11] = 0xD8D9DADBDCDDDEDF; + H[12] = 0xE0E1E2E3E4E5E6E7; + H[13] = 0xE8E9EAEBECEDEEEF; + H[14] = 0xF0F1F2F3F4F5F6F7; + H[15] = 0xF8F9FAFBFCFDFEFF; + } + +} diff --git a/src/hash/bmw/bmw_512.h b/src/hash/bmw/bmw_512.h new file mode 100644 index 000000000..da4b42598 --- /dev/null +++ b/src/hash/bmw/bmw_512.h @@ -0,0 +1,31 @@ +/* +* Blue Midnight Wish 512 +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_BMW_512_H__ +#define BOTAN_BMW_512_H__ + +#include + +namespace Botan { + +class BMW_512 : public MDx_HashFunction + { + public: + void clear() throw(); + std::string name() const { return "BMW512"; } + HashFunction* clone() const { return new BMW_512; } + BMW_512() : MDx_HashFunction(64, 128, false, true) { clear(); } + private: + void compress_n(const byte input[], u32bit blocks); + void copy_out(byte output[]); + + SecureBuffer H; + }; + +} + +#endif diff --git a/src/hash/bmw/info.txt b/src/hash/bmw/info.txt new file mode 100644 index 000000000..3e7e04b31 --- /dev/null +++ b/src/hash/bmw/info.txt @@ -0,0 +1,14 @@ +realname "Blue Midnight Wish" + +define BMW_512 + +load_on auto + + +bmw_512.cpp +bmw_512.h + + + +mdx_hash + -- cgit v1.2.3 From 34f9ef45565ed4052b3a50026827c5171a8dad2f Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 15 Sep 2009 14:30:25 +0000 Subject: In BMW-512, don't use the stack, instead use class SecureBuffers to reduce info leakage. --- src/hash/bmw/bmw_512.cpp | 137 +++++++++++++++++++++++------------------------ src/hash/bmw/bmw_512.h | 3 +- 2 files changed, 70 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/hash/bmw/bmw_512.cpp b/src/hash/bmw/bmw_512.cpp index 42389beea..4019c0ff2 100644 --- a/src/hash/bmw/bmw_512.cpp +++ b/src/hash/bmw/bmw_512.cpp @@ -45,96 +45,93 @@ void BMW_512::compress_n(const byte input[], u32bit blocks) { for(u32bit i = 0; i != blocks; ++i) { - u64bit Q[32] = { 0 }; - u64bit M[16] = { 0 }; - for(u32bit j = 0; j != 16; ++j) H[j] ^= M[j] = load_le(input, j); input += HASH_BLOCK_SIZE; - Q[ 0] = H[ 5] - H[ 7] + H[10] + H[13] + H[14]; - Q[ 1] = H[ 6] - H[ 8] + H[11] + H[14] - H[15]; - Q[ 2] = H[ 0] + H[ 7] + H[ 9] - H[12] + H[15]; - Q[ 3] = H[ 0] - H[ 1] + H[ 8] - H[10] + H[13]; - Q[ 4] = H[ 1] + H[ 2] + H[ 9] - H[11] - H[14]; - Q[ 5] = H[ 3] - H[ 2] + H[10] - H[12] + H[15]; - Q[ 6] = H[ 4] - H[ 0] - H[ 3] - H[11] + H[13]; - Q[ 7] = H[ 1] - H[ 4] - H[ 5] - H[12] - H[14]; - Q[ 8] = H[ 2] - H[ 5] - H[ 6] + H[13] - H[15]; - Q[ 9] = H[ 0] - H[ 3] + H[ 6] - H[ 7] + H[14]; - Q[10] = H[ 8] - H[ 1] - H[ 4] - H[ 7] + H[15]; - Q[11] = H[ 8] - H[ 0] - H[ 2] - H[ 5] + H[ 9]; - Q[12] = H[ 1] + H[ 3] - H[ 6] - H[ 9] + H[10]; - Q[13] = H[ 2] + H[ 4] + H[ 7] + H[10] + H[11]; - Q[14] = H[ 3] - H[ 5] + H[ 8] - H[11] - H[12]; - Q[15] = H[12] - H[ 4] - H[ 6] - H[ 9] + H[13]; - - Q[ 0] = S0(Q[ 0]); - Q[ 1] = S1(Q[ 1]); - Q[ 2] = S2(Q[ 2]); - Q[ 3] = S3(Q[ 3]); - Q[ 4] = S4(Q[ 4]); - Q[ 5] = S0(Q[ 5]); - Q[ 6] = S1(Q[ 6]); - Q[ 7] = S2(Q[ 7]); - Q[ 8] = S3(Q[ 8]); - Q[ 9] = S4(Q[ 9]); - Q[10] = S0(Q[10]); - Q[11] = S1(Q[11]); - Q[12] = S2(Q[12]); - Q[13] = S3(Q[13]); - Q[14] = S4(Q[14]); - Q[15] = S0(Q[15]); + H[16] = H[ 5] - H[ 7] + H[10] + H[13] + H[14]; + H[17] = H[ 6] - H[ 8] + H[11] + H[14] - H[15]; + H[18] = H[ 0] + H[ 7] + H[ 9] - H[12] + H[15]; + H[19] = H[ 0] - H[ 1] + H[ 8] - H[10] + H[13]; + H[20] = H[ 1] + H[ 2] + H[ 9] - H[11] - H[14]; + H[21] = H[ 3] - H[ 2] + H[10] - H[12] + H[15]; + H[22] = H[ 4] - H[ 0] - H[ 3] - H[11] + H[13]; + H[23] = H[ 1] - H[ 4] - H[ 5] - H[12] - H[14]; + H[24] = H[ 2] - H[ 5] - H[ 6] + H[13] - H[15]; + H[25] = H[ 0] - H[ 3] + H[ 6] - H[ 7] + H[14]; + H[26] = H[ 8] - H[ 1] - H[ 4] - H[ 7] + H[15]; + H[27] = H[ 8] - H[ 0] - H[ 2] - H[ 5] + H[ 9]; + H[28] = H[ 1] + H[ 3] - H[ 6] - H[ 9] + H[10]; + H[29] = H[ 2] + H[ 4] + H[ 7] + H[10] + H[11]; + H[30] = H[ 3] - H[ 5] + H[ 8] - H[11] - H[12]; + H[31] = H[12] - H[ 4] - H[ 6] - H[ 9] + H[13]; + + H[ 0] = S0(H[16]); + H[ 1] = S1(H[17]); + H[ 2] = S2(H[18]); + H[ 3] = S3(H[19]); + H[ 4] = S4(H[20]); + H[ 5] = S0(H[21]); + H[ 6] = S1(H[22]); + H[ 7] = S2(H[23]); + H[ 8] = S3(H[24]); + H[ 9] = S4(H[25]); + H[10] = S0(H[26]); + H[11] = S1(H[27]); + H[12] = S2(H[28]); + H[13] = S3(H[29]); + H[14] = S4(H[30]); + H[15] = S0(H[31]); for(u32bit j = 16; j != 18; ++j) { - Q[j] = S1(Q[j-16]) + S2(Q[j-15]) + S3(Q[j-14]) + S0(Q[j-13]) + - S1(Q[j-12]) + S2(Q[j-11]) + S3(Q[j-10]) + S0(Q[j- 9]) + - S1(Q[j- 8]) + S2(Q[j- 7]) + S3(Q[j- 6]) + S0(Q[j- 5]) + - S1(Q[j- 4]) + S2(Q[j- 3]) + S3(Q[j- 2]) + S0(Q[j- 1]) + + H[j] = S1(H[j-16]) + S2(H[j-15]) + S3(H[j-14]) + S0(H[j-13]) + + S1(H[j-12]) + S2(H[j-11]) + S3(H[j-10]) + S0(H[j- 9]) + + S1(H[j- 8]) + S2(H[j- 7]) + S3(H[j- 6]) + S0(H[j- 5]) + + S1(H[j- 4]) + S2(H[j- 3]) + S3(H[j- 2]) + S0(H[j- 1]) + M[j-16] + M[j-13] - M[j-6] + (0x0555555555555555 * j); } for(u32bit j = 18; j != 32; ++j) { - Q[j] = Q[j-16] + rotate_left(Q[j-15], 5) + - Q[j-14] + rotate_left(Q[j-13], 11) + - Q[j-12] + rotate_left(Q[j-11], 27) + - Q[j-10] + rotate_left(Q[j- 9], 32) + - Q[j- 8] + rotate_left(Q[j- 7], 37) + - Q[j- 6] + rotate_left(Q[j- 5], 43) + - Q[j- 4] + rotate_left(Q[j- 3], 53) + - (Q[j- 2] >> 2 ^ Q[j- 2]) + S4(Q[j- 1]) + + H[j] = H[j-16] + rotate_left(H[j-15], 5) + + H[j-14] + rotate_left(H[j-13], 11) + + H[j-12] + rotate_left(H[j-11], 27) + + H[j-10] + rotate_left(H[j- 9], 32) + + H[j- 8] + rotate_left(H[j- 7], 37) + + H[j- 6] + rotate_left(H[j- 5], 43) + + H[j- 4] + rotate_left(H[j- 3], 53) + + (H[j- 2] >> 2 ^ H[j- 2]) + S4(H[j- 1]) + M[j-16] + M[(j-13) % 16] - M[(j-6) % 16] + (0x0555555555555555 * j); } - u64bit XL = Q[16] ^ Q[17] ^ Q[18] ^ Q[19] ^ - Q[20] ^ Q[21] ^ Q[22] ^ Q[23]; + u64bit XL = H[16] ^ H[17] ^ H[18] ^ H[19] ^ + H[20] ^ H[21] ^ H[22] ^ H[23]; - u64bit XH = Q[24] ^ Q[25] ^ Q[26] ^ Q[27] ^ - Q[28] ^ Q[29] ^ Q[30] ^ Q[31]; + u64bit XH = H[24] ^ H[25] ^ H[26] ^ H[27] ^ + H[28] ^ H[29] ^ H[30] ^ H[31]; XH ^= XL; - H[ 0] = ((XH << 5) ^ (Q[16] >> 5) ^ M[0]) + (XL ^ Q[24] ^ Q[0]); - H[ 1] = ((XH >> 7) ^ (Q[17] << 8) ^ M[1]) + (XL ^ Q[25] ^ Q[1]); - H[ 2] = ((XH >> 5) ^ (Q[18] << 5) ^ M[2]) + (XL ^ Q[26] ^ Q[2]); - H[ 3] = ((XH >> 1) ^ (Q[19] << 5) ^ M[3]) + (XL ^ Q[27] ^ Q[3]); - H[ 4] = ((XH >> 3) ^ (Q[20] ) ^ M[4]) + (XL ^ Q[28] ^ Q[4]); - H[ 5] = ((XH << 6) ^ (Q[21] >> 6) ^ M[5]) + (XL ^ Q[29] ^ Q[5]); - H[ 6] = ((XH >> 4) ^ (Q[22] << 6) ^ M[6]) + (XL ^ Q[30] ^ Q[6]); - H[ 7] = ((XH >> 11) ^ (Q[23] << 2) ^ M[7]) + (XL ^ Q[31] ^ Q[7]); - - H[ 8] = rotate_left(H[4], 9) + (XH ^ Q[24] ^ M[ 8]) + ((XL << 8) ^ Q[23] ^ Q[ 8]); - H[ 9] = rotate_left(H[5], 10) + (XH ^ Q[25] ^ M[ 9]) + ((XL >> 6) ^ Q[16] ^ Q[ 9]); - H[10] = rotate_left(H[6], 11) + (XH ^ Q[26] ^ M[10]) + ((XL << 6) ^ Q[17] ^ Q[10]); - H[11] = rotate_left(H[7], 12) + (XH ^ Q[27] ^ M[11]) + ((XL << 4) ^ Q[18] ^ Q[11]); - H[12] = rotate_left(H[0], 13) + (XH ^ Q[28] ^ M[12]) + ((XL >> 3) ^ Q[19] ^ Q[12]); - H[13] = rotate_left(H[1], 14) + (XH ^ Q[29] ^ M[13]) + ((XL >> 4) ^ Q[20] ^ Q[13]); - H[14] = rotate_left(H[2], 15) + (XH ^ Q[30] ^ M[14]) + ((XL >> 7) ^ Q[21] ^ Q[14]); - H[15] = rotate_left(H[3], 16) + (XH ^ Q[31] ^ M[15]) + ((XL >> 2) ^ Q[22] ^ Q[15]); + H[ 0] = ((XH << 5) ^ (H[16] >> 5) ^ M[0]) + (XL ^ H[24] ^ H[0]); + H[ 1] = ((XH >> 7) ^ (H[17] << 8) ^ M[1]) + (XL ^ H[25] ^ H[1]); + H[ 2] = ((XH >> 5) ^ (H[18] << 5) ^ M[2]) + (XL ^ H[26] ^ H[2]); + H[ 3] = ((XH >> 1) ^ (H[19] << 5) ^ M[3]) + (XL ^ H[27] ^ H[3]); + H[ 4] = ((XH >> 3) ^ (H[20] ) ^ M[4]) + (XL ^ H[28] ^ H[4]); + H[ 5] = ((XH << 6) ^ (H[21] >> 6) ^ M[5]) + (XL ^ H[29] ^ H[5]); + H[ 6] = ((XH >> 4) ^ (H[22] << 6) ^ M[6]) + (XL ^ H[30] ^ H[6]); + H[ 7] = ((XH >> 11) ^ (H[23] << 2) ^ M[7]) + (XL ^ H[31] ^ H[7]); + + H[ 8] = rotate_left(H[4], 9) + (XH ^ H[24] ^ M[ 8]) + ((XL << 8) ^ H[23] ^ H[ 8]); + H[ 9] = rotate_left(H[5], 10) + (XH ^ H[25] ^ M[ 9]) + ((XL >> 6) ^ H[16] ^ H[ 9]); + H[10] = rotate_left(H[6], 11) + (XH ^ H[26] ^ M[10]) + ((XL << 6) ^ H[17] ^ H[10]); + H[11] = rotate_left(H[7], 12) + (XH ^ H[27] ^ M[11]) + ((XL << 4) ^ H[18] ^ H[11]); + H[12] = rotate_left(H[0], 13) + (XH ^ H[28] ^ M[12]) + ((XL >> 3) ^ H[19] ^ H[12]); + H[13] = rotate_left(H[1], 14) + (XH ^ H[29] ^ M[13]) + ((XL >> 4) ^ H[20] ^ H[13]); + H[14] = rotate_left(H[2], 15) + (XH ^ H[30] ^ M[14]) + ((XL >> 7) ^ H[21] ^ H[14]); + H[15] = rotate_left(H[3], 16) + (XH ^ H[31] ^ M[15]) + ((XL >> 2) ^ H[22] ^ H[15]); } } @@ -153,6 +150,8 @@ void BMW_512::copy_out(byte output[]) void BMW_512::clear() throw() { MDx_HashFunction::clear(); + M.clear(); + H[ 0] = 0x8081828384858687; H[ 1] = 0x88898A8B8C8D8E8F; H[ 2] = 0x9091929394959697; diff --git a/src/hash/bmw/bmw_512.h b/src/hash/bmw/bmw_512.h index da4b42598..4be6afd04 100644 --- a/src/hash/bmw/bmw_512.h +++ b/src/hash/bmw/bmw_512.h @@ -23,7 +23,8 @@ class BMW_512 : public MDx_HashFunction void compress_n(const byte input[], u32bit blocks); void copy_out(byte output[]); - SecureBuffer H; + SecureBuffer H; + SecureBuffer M; }; } -- cgit v1.2.3 From 268c1b8902fccc4e942f6ccd5651dab826846a92 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 17 Sep 2009 13:46:29 +0000 Subject: Update OpenSSL engine with encrypt_n interface for block ciphers. Add support for SHA-2 and SEED. Wrap block cipher usage in checks for OPENSSL_NO_XXX --- src/engine/openssl/ossl_bc.cpp | 34 +++++++++++++++++++++++++++------- src/engine/openssl/ossl_md.cpp | 24 +++++++++++++++++++----- 2 files changed, 46 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/engine/openssl/ossl_bc.cpp b/src/engine/openssl/ossl_bc.cpp index 4d3761adb..dd6bb38db 100644 --- a/src/engine/openssl/ossl_bc.cpp +++ b/src/engine/openssl/ossl_bc.cpp @@ -27,8 +27,8 @@ class EVP_BlockCipher : public BlockCipher ~EVP_BlockCipher(); private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); std::string cipher_name; mutable EVP_CIPHER_CTX encrypt, decrypt; @@ -90,19 +90,21 @@ EVP_BlockCipher::~EVP_BlockCipher() /* * Encrypt a block */ -void EVP_BlockCipher::enc(const byte in[], byte out[]) const +void EVP_BlockCipher::encrypt_n(const byte in[], byte out[], + u32bit blocks) const { int out_len = 0; - EVP_EncryptUpdate(&encrypt, out, &out_len, in, BLOCK_SIZE); + EVP_EncryptUpdate(&encrypt, out, &out_len, in, blocks * BLOCK_SIZE); } /* * Decrypt a block */ -void EVP_BlockCipher::dec(const byte in[], byte out[]) const +void EVP_BlockCipher::decrypt_n(const byte in[], byte out[], + u32bit blocks) const { int out_len = 0; - EVP_DecryptUpdate(&decrypt, out, &out_len, in, BLOCK_SIZE); + EVP_DecryptUpdate(&decrypt, out, &out_len, in, blocks * BLOCK_SIZE); } /* @@ -174,7 +176,7 @@ OpenSSL_Engine::find_block_cipher(const SCAN_Name& request, if(request.algo_name() == NAME && request.arg_count() == 0) \ return new EVP_BlockCipher(EVP, NAME, MIN, MAX, MOD); -#if 0 +#if 0 && !defined(OPENSSL_NO_AES) /* Using OpenSSL's AES causes crashes inside EVP on x86-64 with OpenSSL 0.9.8g cause is unknown @@ -184,12 +186,30 @@ OpenSSL_Engine::find_block_cipher(const SCAN_Name& request, HANDLE_EVP_CIPHER("AES-256", EVP_aes_256_ecb()); #endif +#if !defined(OPENSSL_NO_DES) HANDLE_EVP_CIPHER("DES", EVP_des_ecb()); HANDLE_EVP_CIPHER_KEYLEN("TripleDES", EVP_des_ede3_ecb(), 16, 24, 8); +#endif +#if !defined(OPENSSL_NO_BF) HANDLE_EVP_CIPHER_KEYLEN("Blowfish", EVP_bf_ecb(), 1, 56, 1); +#endif + +#if !defined(OPENSSL_NO_CAST) HANDLE_EVP_CIPHER_KEYLEN("CAST-128", EVP_cast5_ecb(), 1, 16, 1); +#endif + +#if !defined(OPENSSL_NO_RC2) HANDLE_EVP_CIPHER_KEYLEN("RC2", EVP_rc2_ecb(), 1, 32, 1); +#endif + +#if !defined(OPENSSL_NO_IDEA) + HANDLE_EVP_CIPHER("IDEA", EVP_idea_ecb()); +#endif + +#if !defined(OPENSSL_NO_SEED) + HANDLE_EVP_CIPHER("SEED", EVP_seed_ecb()); +#endif #undef HANDLE_EVP_CIPHER #undef HANDLE_EVP_CIPHER_KEYLEN diff --git a/src/engine/openssl/ossl_md.cpp b/src/engine/openssl/ossl_md.cpp index 7c8fb678c..42975c8a3 100644 --- a/src/engine/openssl/ossl_md.cpp +++ b/src/engine/openssl/ossl_md.cpp @@ -95,27 +95,41 @@ EVP_HashFunction::~EVP_HashFunction() HashFunction* OpenSSL_Engine::find_hash(const SCAN_Name& request, Algorithm_Factory&) const { -#ifndef OPENSSL_NO_SHA +#if !defined(OPENSSL_NO_SHA) if(request.algo_name() == "SHA-160") return new EVP_HashFunction(EVP_sha1(), "SHA-160"); #endif -#ifndef OPENSSL_NO_MD2 +#if !defined(OPENSSL_NO_SHA256) + if(request.algo_name() == "SHA-224") + return new EVP_HashFunction(EVP_sha224(), "SHA-224"); + if(request.algo_name() == "SHA-256") + return new EVP_HashFunction(EVP_sha256(), "SHA-256"); +#endif + +#if !defined(OPENSSL_NO_SHA512) + if(request.algo_name() == "SHA-384") + return new EVP_HashFunction(EVP_sha384(), "SHA-384"); + if(request.algo_name() == "SHA-512") + return new EVP_HashFunction(EVP_sha512(), "SHA-512"); +#endif + +#if !defined(OPENSSL_NO_MD2) if(request.algo_name() == "MD2") return new EVP_HashFunction(EVP_md2(), "MD2"); #endif -#ifndef OPENSSL_NO_MD4 +#if !defined(OPENSSL_NO_MD4) if(request.algo_name() == "MD4") return new EVP_HashFunction(EVP_md4(), "MD4"); #endif -#ifndef OPENSSL_NO_MD5 +#if !defined(OPENSSL_NO_MD5) if(request.algo_name() == "MD5") return new EVP_HashFunction(EVP_md5(), "MD5"); #endif -#ifndef OPENSSL_NO_RIPEMD +#if !defined(OPENSSL_NO_RIPEMD) if(request.algo_name() == "RIPEMD-160") return new EVP_HashFunction(EVP_ripemd160(), "RIPEMD-160"); #endif -- cgit v1.2.3 From 7d51181d2841b29277da9a31752cae612d64b534 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 17 Sep 2009 13:48:12 +0000 Subject: Move memory locking function decls to mlock.h Inline round_up and round_down --- src/alloc/system_alloc/defalloc.cpp | 2 +- src/utils/info.txt | 1 + src/utils/mlock.cpp | 2 +- src/utils/mlock.h | 32 ++++++++++++++++++++++++++++++++ src/utils/util.cpp | 18 ------------------ src/utils/util.h | 18 ++++++++++++------ 6 files changed, 47 insertions(+), 26 deletions(-) create mode 100644 src/utils/mlock.h (limited to 'src') diff --git a/src/alloc/system_alloc/defalloc.cpp b/src/alloc/system_alloc/defalloc.cpp index 8791c74e4..b1b338d71 100644 --- a/src/alloc/system_alloc/defalloc.cpp +++ b/src/alloc/system_alloc/defalloc.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include diff --git a/src/utils/info.txt b/src/utils/info.txt index ab50b88ad..bf9778369 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -17,6 +17,7 @@ exceptn.cpp exceptn.h loadstor.h mem_ops.h +mlock.h mlock.cpp parsing.cpp parsing.h diff --git a/src/utils/mlock.cpp b/src/utils/mlock.cpp index 9bb062da5..6453d8a30 100644 --- a/src/utils/mlock.cpp +++ b/src/utils/mlock.cpp @@ -5,7 +5,7 @@ * Distributed under the terms of the Botan license */ -#include +#include #if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) #include diff --git a/src/utils/mlock.h b/src/utils/mlock.h new file mode 100644 index 000000000..0811e8190 --- /dev/null +++ b/src/utils/mlock.h @@ -0,0 +1,32 @@ +/* +* Memory Locking Functions +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_MLOCK_H__ +#define BOTAN_MLOCK_H__ + +#include + +namespace Botan { + +/** +* Lock memory into RAM if possible +* @param addr the start of the memory block +* @param length the length of the memory block in bytes +* @returns true if successful, false otherwise +*/ +BOTAN_DLL bool lock_mem(void* addr, u32bit length); + +/** +* Unlock memory locked with lock_mem() +* @param addr the start of the memory block +* @param length the length of the memory block in bytes +*/ +BOTAN_DLL void unlock_mem(void* addr, u32bit length); + +} + +#endif diff --git a/src/utils/util.cpp b/src/utils/util.cpp index 84dfd1a14..09ac9f1ca 100644 --- a/src/utils/util.cpp +++ b/src/utils/util.cpp @@ -11,24 +11,6 @@ namespace Botan { -/* -* Round up n to multiple of align_to -*/ -u32bit round_up(u32bit n, u32bit align_to) - { - if(n % align_to || n == 0) - n += align_to - (n % align_to); - return n; - } - -/* -* Round down n to multiple of align_to -*/ -u32bit round_down(u32bit n, u32bit align_to) - { - return (n - (n % align_to)); - } - /* * Choose the exponent size for a DL group */ diff --git a/src/utils/util.h b/src/utils/util.h index ac7867390..e3dadc64b 100644 --- a/src/utils/util.h +++ b/src/utils/util.h @@ -18,16 +18,22 @@ namespace Botan { BOTAN_DLL u64bit system_time(); /* -* Memory Locking Functions +* Round up n to multiple of align_to */ -BOTAN_DLL bool lock_mem(void*, u32bit); -BOTAN_DLL void unlock_mem(void*, u32bit); +inline u32bit round_up(u32bit n, u32bit align_to) + { + if(n % align_to || n == 0) + n += align_to - (n % align_to); + return n; + } /* -* Misc Utility Functions +* Round down n to multiple of align_to */ -BOTAN_DLL u32bit round_up(u32bit, u32bit); -BOTAN_DLL u32bit round_down(u32bit, u32bit); +inline u32bit round_down(u32bit n, u32bit align_to) + { + return (n - (n % align_to)); + } /* * Work Factor Estimates -- cgit v1.2.3 From e1d81327dde6c6837ed81c61c58876bd261fb47d Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 17 Sep 2009 13:59:56 +0000 Subject: Split up util.h into 3 files - rounding.h (round_up, round_down) - workfactor.h (dl_work_factor) - timer.h (system_time) And update all users of the previous util.h --- checks/cvc_tests.cpp | 2 +- src/alloc/mem_pool/mem_pool.cpp | 2 +- src/benchmark/benchmark.cpp | 1 - src/cert/cvc/cvc_ca.cpp | 1 - src/cert/cvc/cvc_self.cpp | 2 +- src/cert/x509/crl_ent.cpp | 2 +- src/cert/x509/x509_ca.cpp | 2 +- src/cert/x509/x509opt.cpp | 4 +-- src/cert/x509/x509stor.cpp | 2 +- src/math/bigint/bigint.cpp | 2 +- src/math/numbertheory/mp_numth.cpp | 2 +- src/modes/mode_pad/mode_pad.cpp | 1 - src/pubkey/dh/dh.cpp | 2 +- src/pubkey/dl_group/dl_group.cpp | 2 +- src/pubkey/ecc_key/ecc_key.cpp | 1 - src/pubkey/ecdsa/ecdsa.cpp | 1 - src/pubkey/eckaeg/eckaeg.cpp | 1 - src/pubkey/elgamal/elgamal.cpp | 2 +- src/pubkey/info.txt | 2 ++ src/pubkey/workfactor.cpp | 51 ++++++++++++++++++++++++++++++++++++++ src/pubkey/workfactor.h | 22 ++++++++++++++++ src/rng/hmac_rng/hmac_rng.cpp | 1 - src/rng/randpool/randpool.cpp | 2 +- src/timer/gettimeofday/tm_unix.cpp | 1 - src/timer/posix_rt/tm_posix.cpp | 1 - src/timer/timer.cpp | 1 - src/timer/timer.h | 5 ++++ src/utils/info.txt | 3 +-- src/utils/rounding.h | 35 ++++++++++++++++++++++++++ src/utils/util.cpp | 50 ------------------------------------- src/utils/util.h | 45 --------------------------------- 31 files changed, 130 insertions(+), 121 deletions(-) create mode 100644 src/pubkey/workfactor.cpp create mode 100644 src/pubkey/workfactor.h create mode 100644 src/utils/rounding.h delete mode 100644 src/utils/util.cpp delete mode 100644 src/utils/util.h (limited to 'src') diff --git a/checks/cvc_tests.cpp b/checks/cvc_tests.cpp index 792e9c58d..d62099b6e 100644 --- a/checks/cvc_tests.cpp +++ b/checks/cvc_tests.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #define TEST_DATA_DIR "checks/ecc_testdata" diff --git a/src/alloc/mem_pool/mem_pool.cpp b/src/alloc/mem_pool/mem_pool.cpp index 38e0c3285..dabf5e310 100644 --- a/src/alloc/mem_pool/mem_pool.cpp +++ b/src/alloc/mem_pool/mem_pool.cpp @@ -8,7 +8,7 @@ */ #include -#include +#include #include #include #include diff --git a/src/benchmark/benchmark.cpp b/src/benchmark/benchmark.cpp index 3bbc1f883..9be845974 100644 --- a/src/benchmark/benchmark.cpp +++ b/src/benchmark/benchmark.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include namespace Botan { diff --git a/src/cert/cvc/cvc_ca.cpp b/src/cert/cvc/cvc_ca.cpp index 638d3f984..8ca8db0c2 100644 --- a/src/cert/cvc/cvc_ca.cpp +++ b/src/cert/cvc/cvc_ca.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include namespace Botan { diff --git a/src/cert/cvc/cvc_self.cpp b/src/cert/cvc/cvc_self.cpp index 91ea38724..777347a18 100644 --- a/src/cert/cvc/cvc_self.cpp +++ b/src/cert/cvc/cvc_self.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include namespace Botan { diff --git a/src/cert/x509/crl_ent.cpp b/src/cert/x509/crl_ent.cpp index afea8cf6b..a8a989c24 100644 --- a/src/cert/x509/crl_ent.cpp +++ b/src/cert/x509/crl_ent.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include namespace Botan { diff --git a/src/cert/x509/x509_ca.cpp b/src/cert/x509/x509_ca.cpp index 41e314724..f0eb9c3e5 100644 --- a/src/cert/x509/x509_ca.cpp +++ b/src/cert/x509/x509_ca.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/cert/x509/x509opt.cpp b/src/cert/x509/x509opt.cpp index de9d589a3..988ab2cfa 100644 --- a/src/cert/x509/x509opt.cpp +++ b/src/cert/x509/x509opt.cpp @@ -6,9 +6,9 @@ */ #include -#include -#include #include +#include +#include #include namespace Botan { diff --git a/src/cert/x509/x509stor.cpp b/src/cert/x509/x509stor.cpp index cb61bc2d2..40801148c 100644 --- a/src/cert/x509/x509stor.cpp +++ b/src/cert/x509/x509stor.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/math/bigint/bigint.cpp b/src/math/bigint/bigint.cpp index 926bedc02..63bdc3605 100644 --- a/src/math/bigint/bigint.cpp +++ b/src/math/bigint/bigint.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include namespace Botan { diff --git a/src/math/numbertheory/mp_numth.cpp b/src/math/numbertheory/mp_numth.cpp index 45a398440..2cb36b8a3 100644 --- a/src/math/numbertheory/mp_numth.cpp +++ b/src/math/numbertheory/mp_numth.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include namespace Botan { diff --git a/src/modes/mode_pad/mode_pad.cpp b/src/modes/mode_pad/mode_pad.cpp index b8badd7a7..2204c28b5 100644 --- a/src/modes/mode_pad/mode_pad.cpp +++ b/src/modes/mode_pad/mode_pad.cpp @@ -7,7 +7,6 @@ #include #include -#include namespace Botan { diff --git a/src/pubkey/dh/dh.cpp b/src/pubkey/dh/dh.cpp index 0c9d02f0e..149bc5882 100644 --- a/src/pubkey/dh/dh.cpp +++ b/src/pubkey/dh/dh.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include namespace Botan { diff --git a/src/pubkey/dl_group/dl_group.cpp b/src/pubkey/dl_group/dl_group.cpp index 81c5d5e1d..13ea03016 100644 --- a/src/pubkey/dl_group/dl_group.cpp +++ b/src/pubkey/dl_group/dl_group.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include namespace Botan { diff --git a/src/pubkey/ecc_key/ecc_key.cpp b/src/pubkey/ecc_key/ecc_key.cpp index 615efecf1..677a5088e 100644 --- a/src/pubkey/ecc_key/ecc_key.cpp +++ b/src/pubkey/ecc_key/ecc_key.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp index 9640c6397..ea2c35a19 100644 --- a/src/pubkey/ecdsa/ecdsa.cpp +++ b/src/pubkey/ecdsa/ecdsa.cpp @@ -9,7 +9,6 @@ #include #include -#include #include #include #include diff --git a/src/pubkey/eckaeg/eckaeg.cpp b/src/pubkey/eckaeg/eckaeg.cpp index b8ff75d89..dc6eb925b 100644 --- a/src/pubkey/eckaeg/eckaeg.cpp +++ b/src/pubkey/eckaeg/eckaeg.cpp @@ -9,7 +9,6 @@ #include #include -#include #include #include #include diff --git a/src/pubkey/elgamal/elgamal.cpp b/src/pubkey/elgamal/elgamal.cpp index 1f79df57a..8c07c5735 100644 --- a/src/pubkey/elgamal/elgamal.cpp +++ b/src/pubkey/elgamal/elgamal.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include namespace Botan { diff --git a/src/pubkey/info.txt b/src/pubkey/info.txt index ee8da5b9d..63af86c47 100644 --- a/src/pubkey/info.txt +++ b/src/pubkey/info.txt @@ -15,6 +15,8 @@ pubkey.cpp pubkey.h pubkey_enums.cpp pubkey_enums.h +workfactor.cpp +workfactor.h diff --git a/src/pubkey/workfactor.cpp b/src/pubkey/workfactor.cpp new file mode 100644 index 000000000..e40b7919c --- /dev/null +++ b/src/pubkey/workfactor.cpp @@ -0,0 +1,51 @@ +/* +* Public Key Work Factor Functions +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include + +namespace Botan { + +/* +* Choose the exponent size for a DL group +*/ +u32bit dl_work_factor(u32bit bits) + { +#if 0 + /* + These values were taken from RFC 3526 + */ + if(bits <= 1536) + return 90; + else if(bits <= 2048) + return 110; + else if(bits <= 3072) + return 130; + else if(bits <= 4096) + return 150; + else if(bits <= 6144) + return 170; + else if(bits <= 8192) + return 190; + return 256; +#else + const u32bit MIN_ESTIMATE = 64; + + const double log_x = bits / 1.44; + + const double strength = + 2.76 * std::pow(log_x, 1.0/3.0) * std::pow(std::log(log_x), 2.0/3.0); + + if(strength > MIN_ESTIMATE) + return static_cast(strength); + return MIN_ESTIMATE; +#endif + } + + +} diff --git a/src/pubkey/workfactor.h b/src/pubkey/workfactor.h new file mode 100644 index 000000000..653f697e3 --- /dev/null +++ b/src/pubkey/workfactor.h @@ -0,0 +1,22 @@ +/* +* Public Key Work Factor Functions +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_WORKFACTOR_H__ +#define BOTAN_WORKFACTOR_H__ + +#include + +namespace Botan { + +/* +* Work Factor Estimates +*/ +BOTAN_DLL u32bit dl_work_factor(u32bit prime_group_size); + +} + +#endif diff --git a/src/rng/hmac_rng/hmac_rng.cpp b/src/rng/hmac_rng/hmac_rng.cpp index 113489db3..8444b1083 100644 --- a/src/rng/hmac_rng/hmac_rng.cpp +++ b/src/rng/hmac_rng/hmac_rng.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include diff --git a/src/rng/randpool/randpool.cpp b/src/rng/randpool/randpool.cpp index 77a5228c6..fe83f4361 100644 --- a/src/rng/randpool/randpool.cpp +++ b/src/rng/randpool/randpool.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/timer/gettimeofday/tm_unix.cpp b/src/timer/gettimeofday/tm_unix.cpp index e32df7166..9d8ac4a04 100644 --- a/src/timer/gettimeofday/tm_unix.cpp +++ b/src/timer/gettimeofday/tm_unix.cpp @@ -6,7 +6,6 @@ */ #include -#include #include namespace Botan { diff --git a/src/timer/posix_rt/tm_posix.cpp b/src/timer/posix_rt/tm_posix.cpp index d356384ab..96182025c 100644 --- a/src/timer/posix_rt/tm_posix.cpp +++ b/src/timer/posix_rt/tm_posix.cpp @@ -6,7 +6,6 @@ */ #include -#include #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 199309 diff --git a/src/timer/timer.cpp b/src/timer/timer.cpp index 035c217f9..e3e3c5a16 100644 --- a/src/timer/timer.cpp +++ b/src/timer/timer.cpp @@ -7,7 +7,6 @@ #include #include -#include #include namespace Botan { diff --git a/src/timer/timer.h b/src/timer/timer.h index b6e8ef448..3bbe85a5e 100644 --- a/src/timer/timer.h +++ b/src/timer/timer.h @@ -12,6 +12,11 @@ namespace Botan { +/* +* Time Access Functions +*/ +BOTAN_DLL u64bit system_time(); + /** * Timer Interface */ diff --git a/src/utils/info.txt b/src/utils/info.txt index bf9778369..68981729f 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -22,12 +22,11 @@ mlock.cpp parsing.cpp parsing.h rotate.h +rounding.h stl_util.h types.h ui.cpp ui.h -util.cpp -util.h version.cpp version.h xor_buf.h diff --git a/src/utils/rounding.h b/src/utils/rounding.h new file mode 100644 index 000000000..11ab90b8d --- /dev/null +++ b/src/utils/rounding.h @@ -0,0 +1,35 @@ +/* +* Integer Rounding Functions +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_ROUNDING_H__ +#define BOTAN_ROUNDING_H__ + +#include + +namespace Botan { + +/* +* Round up n to multiple of align_to +*/ +inline u32bit round_up(u32bit n, u32bit align_to) + { + if(n % align_to || n == 0) + n += align_to - (n % align_to); + return n; + } + +/* +* Round down n to multiple of align_to +*/ +inline u32bit round_down(u32bit n, u32bit align_to) + { + return (n - (n % align_to)); + } + +} + +#endif diff --git a/src/utils/util.cpp b/src/utils/util.cpp deleted file mode 100644 index 09ac9f1ca..000000000 --- a/src/utils/util.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* -* Utility Functions -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include - -namespace Botan { - -/* -* Choose the exponent size for a DL group -*/ -u32bit dl_work_factor(u32bit bits) - { -#if 0 - /* - These values were taken from RFC 3526 - */ - if(bits <= 1536) - return 90; - else if(bits <= 2048) - return 110; - else if(bits <= 3072) - return 130; - else if(bits <= 4096) - return 150; - else if(bits <= 6144) - return 170; - else if(bits <= 8192) - return 190; - return 256; -#else - const u32bit MIN_ESTIMATE = 64; - - const double log_x = bits / 1.44; - - const double strength = - 2.76 * std::pow(log_x, 1.0/3.0) * std::pow(std::log(log_x), 2.0/3.0); - - if(strength > MIN_ESTIMATE) - return static_cast(strength); - return MIN_ESTIMATE; -#endif - } - -} diff --git a/src/utils/util.h b/src/utils/util.h deleted file mode 100644 index e3dadc64b..000000000 --- a/src/utils/util.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -* Utility Functions -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_UTIL_H__ -#define BOTAN_UTIL_H__ - -#include - -namespace Botan { - -/* -* Time Access Functions -*/ -BOTAN_DLL u64bit system_time(); - -/* -* Round up n to multiple of align_to -*/ -inline u32bit round_up(u32bit n, u32bit align_to) - { - if(n % align_to || n == 0) - n += align_to - (n % align_to); - return n; - } - -/* -* Round down n to multiple of align_to -*/ -inline u32bit round_down(u32bit n, u32bit align_to) - { - return (n - (n % align_to)); - } - -/* -* Work Factor Estimates -*/ -BOTAN_DLL u32bit dl_work_factor(u32bit); - -} - -#endif -- cgit v1.2.3 From 7e839d037119055b572f40ce0cd882f85583db2e Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 17 Sep 2009 14:12:57 +0000 Subject: The get_tm function was duplicated. Move single version to timer.{h,cpp} --- doc/examples/bench.cpp | 44 ++++++++++++++++++++------------- src/asn1/asn1_tm.cpp | 22 ++--------------- src/cert/cvc/asn1_eac_tm.cpp | 59 ++++++++++++-------------------------------- src/cert/x509/x509opt.cpp | 1 - src/timer/timer.cpp | 13 ++++++++++ src/timer/timer.h | 5 +++- 6 files changed, 62 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/doc/examples/bench.cpp b/doc/examples/bench.cpp index 0aedc699d..cc43fade0 100644 --- a/doc/examples/bench.cpp +++ b/doc/examples/bench.cpp @@ -60,30 +60,40 @@ const std::string algos[] = { "", }; -int main() +void benchmark_algo(const std::string& algo, + RandomNumberGenerator& rng) { - LibraryInitializer init; - - u32bit milliseconds = 1000; - AutoSeeded_RNG rng; + u32bit milliseconds = 3000; Default_Benchmark_Timer timer; - Algorithm_Factory& af = global_state().algorithm_factory(); - for(u32bit i = 0; algos[i] != ""; ++i) + std::map speeds = + algorithm_benchmark(algo, milliseconds, timer, rng, af); + + std::cout << algo << ":"; + + for(std::map::const_iterator i = speeds.begin(); + i != speeds.end(); ++i) { - std::string algo = algos[i]; + std::cout << " " << i->second << " [" << i->first << "]"; + } + std::cout << "\n"; + } - std::map speeds = - algorithm_benchmark(algos[i], milliseconds, timer, rng, af); +int main(int argc, char* argv[]) + { + LibraryInitializer init; - std::cout << algo << ":"; + AutoSeeded_RNG rng; - for(std::map::const_iterator i = speeds.begin(); - i != speeds.end(); ++i) - { - std::cout << " " << i->second << " [" << i->first << "]"; - } - std::cout << "\n"; + if(argc == 1) // no args, benchmark everything + { + for(u32bit i = 0; algos[i] != ""; ++i) + benchmark_algo(algos[i], rng); + } + else + { + for(int i = 1; argv[i]; ++i) + benchmark_algo(argv[i], rng); } } diff --git a/src/asn1/asn1_tm.cpp b/src/asn1/asn1_tm.cpp index f85ea128b..09bc4d347 100644 --- a/src/asn1/asn1_tm.cpp +++ b/src/asn1/asn1_tm.cpp @@ -10,28 +10,10 @@ #include #include #include -#include +#include namespace Botan { -namespace { - -/* -* Convert a time_t to a struct tm -*/ -std::tm get_tm(u64bit timer) - { - std::time_t time_val = static_cast(timer); - - std::tm* tm_p = std::gmtime(&time_val); - if(tm_p == 0) - throw Encoding_Error("X509_Time: gmtime could not encode " + - to_string(timer)); - return (*tm_p); - } - -} - /* * Create an X509_Time */ @@ -45,7 +27,7 @@ X509_Time::X509_Time(const std::string& time_str) */ X509_Time::X509_Time(u64bit timer) { - std::tm time_info = get_tm(timer); + std::tm time_info = time_t_to_tm(timer); year = time_info.tm_year + 1900; month = time_info.tm_mon + 1; diff --git a/src/cert/cvc/asn1_eac_tm.cpp b/src/cert/cvc/asn1_eac_tm.cpp index 05533b520..947b9e66d 100644 --- a/src/cert/cvc/asn1_eac_tm.cpp +++ b/src/cert/cvc/asn1_eac_tm.cpp @@ -11,53 +11,39 @@ #include #include #include -#include -#include +#include +#include namespace Botan { namespace { -/* -* Convert a time_t to a struct tm -*/ -std::tm get_tm(u64bit timer) - { - std::time_t time_val = static_cast(timer); - - std::tm* tm_p = std::gmtime(&time_val); - if (tm_p == 0) - throw Encoding_Error("EAC_Time: gmtime could not encode " + - to_string(timer)); - return (*tm_p); - } SecureVector enc_two_digit(u32bit in) { SecureVector result; in %= 100; if (in < 10) - { result.append(0x00); - } else { - u32bit y_first_pos = (in - (in%10))/10; + u32bit y_first_pos = round_down(in, 10) / 10; result.append(static_cast(y_first_pos)); } - u32bit y_sec_pos = in%10; + + u32bit y_sec_pos = in % 10; result.append(static_cast(y_sec_pos)); return result; } + u32bit dec_two_digit(byte b1, byte b2) { u32bit upper = (u32bit)b1; u32bit lower = (u32bit)b2; - if (upper > 9 || lower > 9) - { - throw Invalid_Argument("u32bit dec_two_digit(byte b1, byte b2): value too large"); - } - return upper*10 + lower; + if(upper > 9 || lower > 9) + throw Invalid_Argument("CVC dec_two_digit value too large"); + + return upper*10 + lower; } } @@ -67,12 +53,11 @@ u32bit dec_two_digit(byte b1, byte b2) EAC_Time::EAC_Time(u64bit timer, ASN1_Tag t) :tag(t) { - std::tm time_info = get_tm(timer); + std::tm time_info = time_t_to_tm(timer); year = time_info.tm_year + 1900; month = time_info.tm_mon + 1; day = time_info.tm_mday; - } /* @@ -272,27 +257,15 @@ bool operator<(const EAC_Time& t1, const EAC_Time& t2) void EAC_Time::decode_from(BER_Decoder& source) { BER_Object obj = source.get_next_object(); - if (obj.type_tag != this->tag) - { - std::string message("decoding type mismatch for EAC_Time, tag is "); - std::stringstream ss; - std::string str_is; - ss << std::hex << obj.type_tag; - ss >> str_is; - message.append(str_is); - message.append(", while it should be "); - std::stringstream ss2; - std::string str_should; - ss2 << std::hex << this->tag; - ss2 >> str_should; - message.append(str_should); - throw Decoding_Error(message); - } - if (obj.value.size() != 6) + if(obj.type_tag != this->tag) + throw BER_Decoding_Error("Tag mismatch when decoding"); + + if(obj.value.size() != 6) { throw Decoding_Error("EAC_Time decoding failed"); } + try { u32bit tmp_year = dec_two_digit(obj.value[0], obj.value[1]); diff --git a/src/cert/x509/x509opt.cpp b/src/cert/x509/x509opt.cpp index 988ab2cfa..03bcd20f4 100644 --- a/src/cert/x509/x509opt.cpp +++ b/src/cert/x509/x509opt.cpp @@ -9,7 +9,6 @@ #include #include #include -#include namespace Botan { diff --git a/src/timer/timer.cpp b/src/timer/timer.cpp index e3e3c5a16..16d7dc368 100644 --- a/src/timer/timer.cpp +++ b/src/timer/timer.cpp @@ -19,6 +19,19 @@ u64bit system_time() return static_cast(std::time(0)); } +/* +* Convert a time_t to a struct tm +*/ +std::tm time_t_to_tm(u64bit timer) + { + std::time_t time_val = static_cast(timer); + + std::tm* tm_p = std::gmtime(&time_val); + if (tm_p == 0) + throw Encoding_Error("time_t_to_tm could not convert"); + return (*tm_p); + } + /** * Read the clock and return the output */ diff --git a/src/timer/timer.h b/src/timer/timer.h index 3bbe85a5e..603027f6d 100644 --- a/src/timer/timer.h +++ b/src/timer/timer.h @@ -9,14 +9,17 @@ #define BOTAN_TIMERS_H__ #include +#include namespace Botan { /* -* Time Access Functions +* Time Access/Conversion Functions */ BOTAN_DLL u64bit system_time(); +BOTAN_DLL std::tm time_t_to_tm(u64bit); + /** * Timer Interface */ -- cgit v1.2.3 From 57849f8f9a9de40abbf29a2fdb453dfe7d726974 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 21 Sep 2009 16:44:01 +0000 Subject: Indentation fix --- src/block/des/des.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/block/des/des.cpp b/src/block/des/des.cpp index 1c9d37e6b..05287304f 100644 --- a/src/block/des/des.cpp +++ b/src/block/des/des.cpp @@ -144,9 +144,9 @@ void DES::encrypt_n(const byte in[], byte out[], u32bit blocks) const 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]] ); + (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(T >> 32); u32bit R = static_cast(T); @@ -154,10 +154,9 @@ void DES::encrypt_n(const byte in[], byte out[], u32bit blocks) const 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)] ); - + (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); store_be(T, out); @@ -175,9 +174,9 @@ void DES::decrypt_n(const byte in[], byte out[], u32bit blocks) const 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]] ); + (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(T >> 32); u32bit R = static_cast(T); @@ -185,9 +184,9 @@ void DES::decrypt_n(const byte in[], byte out[], u32bit blocks) const 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)] ); + (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); -- cgit v1.2.3 From 6f77fb7beaf2cdc2d2381a6b2d2ca036cc41a502 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 21 Sep 2009 17:46:51 +0000 Subject: Update the implementation of Blue Midnight Wish to use the Round 2 tweaked version. --- checks/validate.dat | 1634 +++++++++++++++++++++++++++++++--------------- doc/log.txt | 2 +- src/hash/bmw/bmw_512.cpp | 206 +++--- src/hash/bmw/bmw_512.h | 6 +- 4 files changed, 1245 insertions(+), 603 deletions(-) (limited to 'src') diff --git a/checks/validate.dat b/checks/validate.dat index 19db5441f..26ed818fa 100644 --- a/checks/validate.dat +++ b/checks/validate.dat @@ -30755,968 +30755,968 @@ D8C1D4BD9C3086F1FDA0ECD33C4FFAFF:72D73FE9 [BMW-512] :\ -73DB7B1DC6DEF4DDF2F94A22E1F6D2162B3123828369FF4FD750832AEDE94E52\ -D4D5C8B866860424991527175B6F62DBE0F764AC18290B92A26812D641CD5287 +6A725655C42BC8A2A20549DD5A233A6A2BEB01616975851FD122504E604B46AF\ +7D96697D0B6333DB1D1709D6DF328D2A6C786551B0CCE2255E8C7332B4819C0E CC:\ -9840F373D940E19FB25945134874977D0A4562CA50F358013E72C9679B3C82BD\ -3988E1BF8FE495C7FBC7D5F2B5F1EEDFC65EB8E54A7D039FA51661C0D4733484 +0309CD7A44E6022671E84C43CDB92F613931D1C6B71467C039034B1263C2BF92\ +203E27604BC53FCEA9C2DF3B10862C9B6FB6E8C617754EF49A2B80F51C74ACD3 41FB:\ -92B5AD91B8F774D1BDA764B10658BFB714E742EE872E0AABC3E0456DB1A7A8AF\ -40768A8EDFFDC995C1F84151F94E3EFAB9978F03CCBCB29A2170AA291F22E0AC +1FD4AC6551D39EF27B5F1F886D7A3A72EC60E0AE2966649C3701952F29B2DBF8\ +58AB6E18101D038BBF019299C7FE5F62A4BC3973E089EF929AAF25B9A8BB7D39 1F877C:\ -159F8BEE2626872E66E7378F9C9D814411630F47B5B2F5F76FAA2140517238BB\ -8781257F20C896F4FA4DFECBC4CB2D1E5932EDEDC5D35E0F3D1C1C93766881CB +8987D458CF27D4C1B1DDD115FE5C15A67AF431561812B1D2028C3AF0A52FB8F7\ +334205CBE003CEAB1446261550870EEA6921C2315D750F9C49AD7877590A9BDE C1ECFDFC:\ -63F6DA9795970160FE9431D1046972B2815D9793AE146102FA8941FCC8B3D447\ -369DCC78E6EE054775DD081E59BA3E0D0653497993CDD413DA1BC099C48D75C0 +5A443348F0B3330CBA5060B16EF21D5597ECDD597603B3E86999099C5595BE38\ +F726D10090472DAF5EA77315B6BA62B2507A7C08A1B6786DCB30148DD1517882 21F134AC57:\ -042445884DCC2C42B7B6C463B402B0538AE18BB9BAE1D0A85F13FD2A6A6F2FD2\ -CB8B78D25D6A98C33848EEBC2D84513B54901A208812D629EBE354BDD6C978AE +C1ABFEF8AC91FDC20900045A226EA8D5FF2E3E5D0F00CC9194D19F6546075558\ +7F72492E5D5F5A30AE63F95E9DFEE6F07051A8E9856E701451BE1CC58D320E3D C6F50BB74E29:\ -05D923A6960DFF2151830FBCDB9C45E4FDD62B3CEB9CB1780787A07F7CAE5278\ -69D346707CFBAB8D0C853F609D7B494DCD6DCB0F911CD27DA11702D357DB5432 +B1EC7BD5A91DE2480BEE26C93A84E38030E2B2BC469B7D4A8D91D32CCB889805\ +436739DCB5A14B1D4C0811EE2A0D9A667C0FBA00F48800F39AEBE8D7DA7EDF1C 119713CC83EEEF:\ -EBAEDFE8FDFCC34ABE5939FD2A3F520263BA3C1103084C1F8B66180FCDB7264D\ -2384C6151791E72401A8AFF1000229EDF0ECAB8316F44C1F0D39616758951668 +8652D6C03E8B42F46D96E2357DE252C9B4CC483C32ABCADFECED70A07C8E1C8B\ +637A6FA1E278C8BDF651D6FDD8A29A48DAA8ACA71C2277F709A83A80C62C5DA5 4A4F202484512526:\ -745995D3EEF74E331B94C791D96CE8A33716379E4D9DF744460ABE87F6495149\ -BD1B71DA2F884850F520866123FBEFB5D51F6330398A1E86380B622C437E4C9B +86E05AB43DEC6C078B18369AC5485B4FAFCA9C55C36E736BFB08E169A2667C67\ +C14A7D0409FC735B18618E84483E1B39DA47A41E48915096A8DEBACA7A148A03 1F66AB4185ED9B6375:\ -0551C3FE28BC3E0ADB52A201FEBD788B7F39DB7342934D10AC8FA87DBB52F2BD\ -B81F5BB316098D2236041083B37854720CD7A6B325405C58A9C690AEBBBC9630 +E072E9D923E334A5C0E129E46D4EE6E5FA2A1494F6CFC4D1498B80470A0B920F\ +2B2D56575A771D8271205D973F23A8DA0FCD3DE5E569269B50B3BD823DC8D955 EED7422227613B6F53C9:\ -6BABFCFDF2AD51C3BC23F3B5961375B0C5EF16A3E56628ACC052A86188FB94EB\ -0E0516187737BB716D9228E115219D5C5A64E608721952A8DC3506233E814DE4 +6D8B04C1DAB6BEACDF7410B9FDBC96E74D9FB11A949DD164C817BDF4ED2DE978\ +B61ADABF27BE4FB8DDFE6B9AADEF8038C217BC56B17C78D19A80922CF84DF8F5 EAEED5CDFFD89DECE455F1:\ -735E5418F3586FCF2DA76018A9B1816AB70031FB23A43D394B5DECD9953C1810\ -3DC129ACE0EF740B3C15B914921ED1EC4AA1078D8F5456F2A24B6109FCB5B2C6 +66022F69F321D34378271556AD6793DEE887BB6DCD07344CB0C9F9FD8F6C9080\ +F296B99D7D42A6B4242A84889F41894258419CE871D54F21D78AD5BD7FC81A7C 5BE43C90F22902E4FE8ED2D3:\ -30F325A100BE24398ABB02FE6F86F9DCEE4D77873EFB5A4FD8EF89547D8143DC\ -B05067EE69015C915DD26889DD360C28D155CECABAE7852AB853125997602053 +BF48CFBDF5876FF02D095482F4DB28693A3D09B9FCE1DD25BDDB2F80D1100AA8\ +1D166E37421A3281B9F25A981DCD6741272E3F4E596B5003FD86F85C9C31BB92 A746273228122F381C3B46E4F1:\ -CA08832D082A30BFC303C4854994B905EB5A115B76E1772EC5D3DD5576681121\ -A0ADF3DF365391E764AD0C0054CD0190F9BDFFAC6A4EE3C47139B6F2A550A365 +99F9C27A26186098430839356FD651A6C203E39ADC06EFB3A6C35C3265FE37F7\ +CD3B4EE520218D820F3189B44341EAA6CD753A472A8FDFD7386CB5E3A1D9DBB7 3C5871CD619C69A63B540EB5A625:\ -9192799953AE4140D2D210DF6291C40F09F91B2D440EC81EB10FA06FA183A6D5\ -8C6D20F7B69365155E431323DFA8B52ACF23A0E5CA2392F5C606F8463567D793 +2630080B86DC7DBF5AC325F645B94E0A5FA967913AE02BCE4B762DC03E8DAC4B\ +463A881DEA606FCCD2767F6044040DFACFCB774E19FBDBB8CE89AF937077EC0C FA22874BCC068879E8EF11A69F0722:\ -D760AE02DFB92518516BF94F16F366700BE7043DF94DFD6DE89E2773EAE7ECE4\ -E6CA64A82E29402550DE531A72CC74F9BD7E8DAEFA91D4B36E092D9C87D98117 +9828CAC020097A5A74E5817EC37034DC0346F07E0CC17AC03E386C7045B6977B\ +9B276EEE6C591E970D0D1F2402515BB63E520C6737B4131BFD114E8D58B4F035 52A608AB21CCDD8A4457A57EDE782176:\ -58B7F75E1F58C8235471511D88C4513FCB60C03C47E20D5FF198F5E0DD980A84\ -4C343598486573EF972198BA506BF2C07BDA6C83E71F6C42D290B9412A7F5118 +7BE3BD61CECEE09EF1160C1CF7DBCF94F5E1BEE3A30F2B27B0580C3BAC5D2592\ +8291372CE81237B867D4CA09868A0CC7984F2CFA4EF14479761E2EA58FB78BA6 82E192E4043DDCD12ECF52969D0F807EED:\ -B8E6C00BEEECE767393D959B3137CDB4F69EF82AFB8A6BFA99375B7BD33918C8\ -8D59197675612D7DC8D42947A3CE22F3A167B396B2E7F0E29C677369E4B7C937 +68A2B3C34D5E023F3BCA7508BB0B5E9BDA5375E245FA394D2CF508A03B48AF97\ +005B3A4DBFFC0D38CA4416ADF504745F94FE9B0D3F5CE334DA9805F1F3ECC978 75683DCB556140C522543BB6E9098B21A21E:\ -B578944870EC6AE4AF742DBD72EB2067772467ADDE3EE007CDE159C8BFAA7CE4\ -83FFDC7C89B2C73363823CA58949880A289C7B61EC0A1D207C3AE95B3CF5C183 +345692802192594F5516D2B22215DECB648E6611B9A24D159FD2978BF712846F\ +1FCB61F1E5A5AC25832D7E7BBCC0D0FF2E55EC2C9C90EC1E0078697117ADCFAD 06E4EFE45035E61FAAF4287B4D8D1F12CA97E5:\ -64D481A9BD15634C715EF3E8AF4FC94664FC380B51218E9786AFAC187B362B00\ -8DD54ADD1B62779A35A10A991C27F22A7A624B451DBEF425E3633B50EDE78835 +3E3CBB918CF27C6A73D0145CDD3A8F159C56AEF938F69884AC6FC8C3207593FC\ +8D3E712ADFF0CE52FEAB8B693D8933D87DCF8A3F58BE330B4B5DF14EE3D635FA E26193989D06568FE688E75540AEA06747D9F851:\ -7DBF6124910547C284FB8664B197DB48E1CA950A13DE136DF86EF41C6D9AF327\ -E493D0171C6D8426F938445B260B779F8F28667C7525067B55273B25AA553A9D +D1C6A2F12589D77610EC236DB751DCAFEF5A9DFEEA63E307DE01FB4B852DC577\ +6CD59CC6DC2369584B9DDB214BDDF5D5C89D0D1EAC9FB8F7C0F041452CBC11F7 D8DC8FDEFBDCE9D44E4CBAFE78447BAE3B5436102A:\ -76831676159CBC50D761800DE6C042D0CADD770840799F31970DE8B147D751AD\ -014A6D0E0ABA7441A4CCD3AADBB175923E33D1343AF83DB0AA943AFAA7DB5DAF +64659D7B159C8F276DB1295039EB6FE2435405DC1A81BF4575B9C27A2C41208A\ +0BD331F34A60DFF31AD29F8730C0786ABDEE4ABC767092D448CEA3F97C7A6976 57085FD7E14216AB102D8317B0CB338A786D5FC32D8F:\ -3F00ECD88535CF4EAD4644134C13473BAEF3F9223660C41E0B2BE8CE08DEF2B3\ -24DFED32E559880031A19DE2BAEF73296F980AC0B87B9620FB0CEBF5CC812016 +6CEA91D04E9D4A3C994BE9BB24FEFAF967B4DE36D2566F368C04CC2ED9FAF736\ +DB71170C207F31A7F08B7B8D634E7C38FD591A38948DE4ABE70CC64F3A2EE108 A05404DF5DBB57697E2C16FA29DEFAC8AB3560D6126FA0:\ -A5DF86B0021E4028EC79AEE1DF59CEBBD071F041D82F10DE014BB19445C07E78\ -2DA69484F1F93CBA27264E83759DD54CB1D88DAF883862F0176F451702336C69 +5B5CDE06BF8B5AE80A67D96306AC7E96AD15575195B269378EA65C6F23DFF53E\ +A4E02639F3EC61D640D3D9B2776DEF2FBB3B8AFA1FCA3AA55BB5208788671770 AECBB02759F7433D6FCB06963C74061CD83B5B3FFA6F13C6:\ -F3172A73831AD1596F920735786B83F6236BBCC121C805DC31067362C530CED0\ -304E8CAD619BC4162760AAF34353E581A5CA43CC74CEB6F11D72C4401CC48C7D +0374C843999A2898BD79A0CC8DFB924E7BB9E5CCAECDD151B502C1A234F1D369\ +1F3CE29D0BC6F044A2CCA8174F7537078F3FF0CA73E8CF1D2040D25D1AF3295D AAFDC9243D3D4A096558A360CC27C8D862F0BE73DB5E88AA55:\ -B7A8160FACFA8A4110558796D99A793D714E128E5D3CEE5188FB2C85880498BC\ -884B0DA80AE65D1275EF5B8207FEEEF1ED55278B271571F64C63A37C822DBF5B +7F1E7A420B60E6B42622E4B5E2900D6CF01230C962565A6F7CB8270C8CBCB4E4\ +77D171E183B3C856FCE7369FD25D5E285E21777E3C738090215D97E25ADF1FF6 7BC84867F6F9E9FDC3E1046CAE3A52C77ED485860EE260E30B15:\ -50A1BF96E0DE3CF9B9A7FC4C97E1BB02BC843113E731472FAE6970C6351F7E40\ -71F909435DA1707A52288252CABF2B46C0167A674C17159F053AFBF7008B2CBA +52A8179F441682C0CCF7F781C0CB905442ED82CA60ABED14BF032DBC5202CCE9\ +1A66369424DEC0E4C45AC16F156A9AC7982FA4A7AE941B4F24F8DA7A4FEEC4C7 FAC523575A99EC48279A7A459E98FF901918A475034327EFB55843:\ -C73850851A15D4B730D97773A82788B4486AAD26092EF29E980D5315BF0414E3\ -8FB300C5900B708B11D51F90124D603AF84C870594BC1DCD119E406F9BE92762 +50EC175DC458FB3DED1E3AF7CA87DD6CD08FD89B0BA403EF666E98787D3E38CA\ +48946DB41F38C8FDFB82FD0AA71B08D9069E7136775D22E0583BDA3D8228D3DC 0F8B2D8FCFD9D68CFFC17CCFB117709B53D26462A3F346FB7C79B85E:\ -6B3491AEB10987090D570688DADAF9EB5F3A6A8131FAD207DC4505DBF3AEE8FF\ -0D81AA3D6D066AF9F64333226BB3FAC7F363D44C30BEADF623D3FF452EACB818 +47BE44B33C90FD2EC18B839C5A60175EB76DF0A8A587D6EF4A6712868CADBCC5\ +4AC88BE47987F7A4875C16C31B8A6D691939C007B6724139187E76413716F226 A963C3E895FF5A0BE4824400518D81412F875FA50521E26E85EAC90C04:\ -EC5930D611D58A2B87B8505256BDC24D150C238CCDE3C7AA9FA9A2470BEDDE29\ -591208BD924C474CD849B9B005BD4D930D0BACF87DB15D7395E68FBDF8FC0435 +E0F91DA11320E76952D42C897503DDF79670C841DFD059AD40F41D9C5BAE0526\ +27887F5EF09A214AB6F2E5425AA1C634C29C533C596B1BE95B1D39EA06335694 03A18688B10CC0EDF83ADF0A84808A9718383C4070C6C4F295098699AC2C:\ -7D2A97D59AF2707F481804C7A3BCC6D226941406CB1852A28475F3434B512F22\ -D5EE88E7FB47EB065745417CB8D5001FCD7072349090BCC1F8A5E8BED877886B +0CF4B313265173B60D2F99B87E81E76C10E855A0F67FD5F2D61216CAEF046A86\ +BC2B7E907412C5499A162BD1D019729653F2A80969A534776494A00C8193B8EE 84FB51B517DF6C5ACCB5D022F8F28DA09B10232D42320FFC32DBECC3835B29:\ -9429625B5A17F44E3B1B56436FE8348C4D3FD2CD634884A0DFBB24AF765FA415\ -DC223A6D6A7818CEB1557693A364434D363760D51266C067B5E22A4B07A7B643 +B3483C99D6B488DC2E34F5024BBEE33B55D9A66B7EFE39657748650AC4301BA6\ +DC64A3E3E8C15945575DA963D29399BA0B1AC3A6CECF549E132A5E2DB3B5BBE7 9F2FCC7C90DE090D6B87CD7E9718C1EA6CB21118FC2D5DE9F97E5DB6AC1E9C10:\ -994F4F57EEAFC3C4CC9D5275906A15BFDBDA5EA71C4479FCD420AF19062A3651\ -2F1D4C3298F08BB23CEE9756CC0927249792948095E085B3EA98FC25346FE471 +DA79A14B066580178121D3F60E0D3370F667A297FD9C0435CF8C65D35BB3B4AA\ +894AF7946F65CCAA5F7D9FC199CBCA9BE3FBFA958C0DABC992A50DB2236ED51C DE8F1B3FAA4B7040ED4563C3B8E598253178E87E4D0DF75E4FF2F2DEDD5A0BE0\ 46:\ -E589801B2213C47DD246602C5F018E5A53267FDF5D087092BAEF60BBBD878B7D\ -05C6247924C9E49B7BE22F578F245186B6E8275A3EA543FC0388DB167A4B0A67 +4A7873D42769DA269B9869E0DFD5695AE343DBD69FF8A68D93542B5EBBE79480\ +6B2D84ADC69DEAA58F54008164FB3E2AB02577865FBDEA88A8BE7D23EAA9441C 62F154EC394D0BC757D045C798C8B87A00E0655D0481A7D2D9FB58D93AEDC676\ B5A0:\ -535741C4D3702052B90129D720ED909A79398C9113566424DF9C25936C957DE4\ -13082F2B21DBB549D7A98C1DE017AB0BE217DD6FCA6FDFDBAB88DB95392A27ED +CF42B5F7ABF540B69018484583A7B1CD1A38064C6E4208CE0ACEE27B7EE74CCE\ +C544FB2FA1921E95B5CACC12546D35C628ECA4C7053F37FD236E63346D474D00 B2DCFE9FF19E2B23CE7DA2A4207D3E5EC7C6112A8A22AEC9675A886378E14E5B\ FBAD4E:\ -5D5E007A1CD5AD33EBD29FB0F54C025BB2A354865012463E05D644C90407E989\ -0CBE0314606BD215DEBABAAED4A01E498639DE7BAE3FC6EACA63007A3F4C4734 +9F955DF8BAA1A5ECF0BDFD408002B1EAC93B89C8AEDFABB9E5239D6D1AD1C129\ +9901E96C822BE23207570E1EAE9CB82429899158313AF79FBB06EA3915436F7A 47F5697AC8C31409C0868827347A613A3562041C633CF1F1F86865A576E02835\ ED2C2492:\ -AC05269EC62DAB42AE70ECC0C3FA98118C90C22A087124E26DD070B33E331E18\ -4F0BE667A97F041B8EA0274AC69E0F233D580F4CED044134F5C5F6FF06CFB253 +0FD1772A21CF32F0D43C00DF44754096704B0DBBC3B323500C3B231C7FC47B8F\ +35E8F10017F4B1061E82E5CC1D823014DCD54AD7F3588614E2149020CD8989B4 512A6D292E67ECB2FE486BFE92660953A75484FF4C4F2ECA2B0AF0EDCDD4339C\ 6B2EE4E542:\ -7CEAF4D520D389D2C2F1A3496F350B73A7C524FA3B68C5034C9196B7A5B61184\ -26BC04E527317B0948328081529ED3E3DF94D3945D6DC8C7639C41F39C003403 +41D2D44C32A90B30ACE1C7F6E4AF5C3DC3ABDB1AC7365262C56CB1AE6DB6B5D4\ +2AD2BCFD9228D9DFFD5664756E326E9E88D053FD3A3D252211463B7171F5CB5C 973CF2B4DCF0BFA872B41194CB05BB4E16760A1840D8343301802576197EC19E\ 2A1493D8F4FB:\ -B0A5E7A2A632D2E860010A8526ACA19D028AFCD986213E8D92284173FB9FFD01\ -492B985A3142A9A5145EF823284F10E59CE4D96294A9F5C9344C2A2AF307C061 +4AF72DFCF27B0CDA02F35AAD1A90C67378B63523E80DD50A2AB512F2CFF2969F\ +A48DD8EDDE239F6BD5484D98FB26F0757831D7AFAAB5A21DBADB1C1B5BEA2336 80BEEBCD2E3F8A9451D4499961C9731AE667CDC24EA020CE3B9AA4BBC0A7F79E\ 30A934467DA4B0:\ -AAA6227F450D3155AE0B7CE3177772958A5F62156B38154936EAB3DB4753D882\ -FBC6E2480277C6889EE3CEFB29E2A4AC51FCB9DE94C323BF222CB54061BAC061 +7161CDE092AE657F61BFA5957B5BADB16712A173EADEA014F622BA0CCF8B4BF9\ +E0E87B92032A5E1EF762FC7B734BD3B2AA526303C7EDE369885CE63DA6DD6DAE 7ABAA12EC2A7347674E444140AE0FB659D08E1C66DECD8D6EAE925FA451D65F3\ C0308E29446B8ED3:\ -523FF9E4D5D00A01EF877EFB99BF5F8060943539D90A894D3C6CD132DE40EDA0\ -1BF41C8040B41C134F7A166FDF3C85A45D2B49F3EB584EEF73404B21F40B1393 +52E566F481EBA7268B1C9440CCCC29EDFA7E03B4D5BE7689D9E6B9C0E097FC07\ +E378D7F189A144A31A7CA4280B3D566732C3DF2213A534B37D19A1AEFC332E90 C88DEE9927679B8AF422ABCBACF283B904FF31E1CAC58C7819809F65D5807D46\ 723B20F67BA610C2B7:\ -D129F5142CB0590FDF8C4F1EAA9FE01CDFCD605FF472C88BB93671F866D5C05B\ -5FBA76CC0BD92EDB88052829FFD12AFDF1C78A8B0216A8F8DFC6DD42C9BA0DEF +CFB6068414E7ABFBA715292306824859C4A8034964CC77C5DB1208FAED6274C3\ +7196850F81071E904BDA8CD1ECE8D66ACAB354EC5802846CA42A217941186AC3 01E43FE350FCEC450EC9B102053E6B5D56E09896E0DDD9074FE138E603821027\ 0C834CE6EADC2BB86BF6:\ -31C927D5EF8D6C7FF6ED7AEB3AA3BDC0EDBB7840351D3648DF4493C9BBDC3BC1\ -B9C5B16EA56D0AF05356C76915B9A99CD3A8E971428FEC18A855EDC8AD572BF1 +7CBE1D832F1530C7527FB3D8BB8F0BF7A2AF523A507EFE68AFDD1DCDE2852DD7\ +89AE87BA2DE8C6CE85AA0D6FD8EB2C4C0DC9E489A1D10105B56D4FFB1260EC0C 337023370A48B62EE43546F17C4EF2BF8D7ECD1D49F90BAB604B839C2E6E5BD2\ 1540D29BA27AB8E309A4B7:\ -A95CF125F407B69A4C06E1C21887C12C9D8385A5989E9A18739EA444292135A2\ -D93A44CAF9506A033D1FA6389B345D2D5950D6611D496C0E6027689A81949456 +2B4F480C3799B7FF87DC0DBE2DC4348E2D42522EE803D89165002E8810734373\ +7B8605909795397DCA7442CD95799B91EAAB9993641F0578D4C86C7D01F564AD 6892540F964C8C74BD2DB02C0AD884510CB38AFD4438AF31FC912756F3EFEC6B\ 32B58EBC38FC2A6B913596A8:\ -7CBF30547921746CBE27FC5DEA6705A070631002447BDA20262CC5FCB0259083\ -9A2A3185443D502554296E7655F5CBB9EEED60C840E61E90A4DA3070B3FE63DF +1556B21828CD8C1F98BFCC63415D4A4F9A916403EE0D65ACAB7AF2280FFA044F\ +5A0B773B7B6210C2D390A17464A791F52398264714FA89F990B03E810155BEF4 F5961DFD2B1FFFFDA4FFBF30560C165BFEDAB8CE0BE525845DEB8DC61004B7DB\ 38467205F5DCFB34A2ACFE96C0:\ -A1A9A9FBA7A83D85796E0800931A3044E48454C34542A6373DB9EC602C0760ED\ -816EC32028013FD9EA976A898081852A7E3C17FA7DA2F048492AC9539D92DD6D +C17C6DD9964329D4F1AB10C57967E985A15EDF1DD3DEF79436198459A4D33136\ +7FADE1D20967BF3EAB50A8FBB892F0E71B0BAB981BB1D3EC64EBAB88447A66E9 CA061A2EB6CEED8881CE2057172D869D73A1951E63D57261384B80CEB5451E77\ B06CF0F5A0EA15CA907EE1C27EBA:\ -34825B3A2CBD58E217B7C76593B02479451B6C9A2C809FC289857F4CC70147DE\ -00F3104EDEE8B1CA54F712996D609D32C988AB70749D0868D4B690BAD1CFB1AD +81B3181C9610CA1EB3359A05329F597A7EFB663B86B413246C0755583B04B0D8\ +B266AD0343AD5813195DBFEDD031AE5CECE6DBA846803CB1C1787B838D66F295 1743A77251D69242750C4F1140532CD3C33F9B5CCDF7514E8584D4A5F9FBD730\ BCF84D0D4726364B9BF95AB251D9BB:\ -47BAF3BF878E7EE0D803457EB4C689A9CCFEB1C552382A36229615A8A46BE0AE\ -46D0F40F309D3BD9FAAECD123B60C43AC29909D77C8E20D886034B9A1E145DC4 +48D1EBCCBCEE10E72A9AEE1785A2E97D0612BA7443152514A6F59A232F6D1A17\ +EC4415044A946DF2073FB1B979501B24ECE23C380EA1246C3F09B024C53D83EC D8FABA1F5194C4DB5F176FABFFF856924EF627A37CD08CF55608BBA8F1E324D7\ C7F157298EABC4DCE7D89CE5162499F9:\ -052FE499E96A76C8D20BB911F9A819BC177159D54C30A697F7E0E97CFD0F2442\ -460A48BF5D6B5BE59C2317A84F10E6B19A0DFEEC2077C88787630E1E12A91589 +6470A4A9540F4B9DEBBAECF5A95D05AFA9646FAC17B57944602F37740BBC3FA3\ +1C8F1D199013D15D4227209F89C333A493C4D83C8AEB186A9394619EDD1EB8DA BE9684BE70340860373C9C482BA517E899FC81BAAA12E5C6D7727975D1D41BA8\ BEF788CDB5CF4606C9C1C7F61AED59F97D:\ -C51B893CE23BAF7018CBC69F9CA7C49697792C35845D542A3F2970F6E69072FA\ -22E9B81A78AD609BCACD890EB0B9ADFA8C88283735F406F1604277F87535588C +4446970CCDF75D54F79CCB3881A1ACA24D6CA8DEFBF0C248FD6E477223F2758B\ +9369B8140EE48BD0229B097F514E7A688506A890605C816714279105BEFDF112 7E15D2B9EA74CA60F66C8DFAB377D9198B7B16DEB6A1BA0EA3C7EE2042F89D37\ 86E779CF053C77785AA9E692F821F14A7F51:\ -01756CBD8188A16ECF85C24FFE017F202C6106DF941E043666E4285AFE2DD60F\ -BD19E86D95FBAFCABA45A26FF7FBF3DC82A72FFB803055346FE5F40F15E38D6A +4FEB1F07404D63A06BCDB2BCC319480CA02BEB7981972A092AF5C27001042EF6\ +3500955E57F5C3C54E0E964BD94ABC50BBAAC74F635E522D9ACF6740F26FC4CC 9A219BE43713BD578015E9FDA66C0F2D83CAC563B776AB9F38F3E4F7EF229CB4\ 43304FBA401EFB2BDBD7ECE939102298651C86:\ -51475D5155F7F33D25A1698B7A93093ADABF7CEB18D549BEE87BDD4F2117407B\ -ED4FD4310EBE8F378D7C9E0E2A1C627C1AAE16C4940E92B2F8E43289EFCE223F +DE3F70F58116EF74466997946469929B5283B0289513AAF1F8DF770AEA21D9E1\ +308A5D1A30CF3912F4351BA6B1ADC4C2B35185C6479E5D160D678EE34BFC6CE5 C8F2B693BD0D75EF99CAEBDC22ADF4088A95A3542F637203E283BBC3268780E7\ 87D68D28CC3897452F6A22AA8573CCEBF245972A:\ -9A7B45C8A0E0349CFE3A77A964EBA8858CE70DC7467BDCBEE97349A63E960732\ -D08E32F8CF33BE42B839777CA7F7217989A2E15022CEF55E418C7EAE6F5C125B +89C23F143C74B2A3EA4E1B52765B01CD38725DD432813816CFEDCDEF7090C01D\ +9964DAF8F0EEC99A23B20F1502CC8CB41F77CD35D1E1B1CCFFD96821525705E2 EC0F99711016C6A2A07AD80D16427506CE6F441059FD269442BAAA28C6CA037B\ 22EEAC49D5D894C0BF66219F2C08E9D0E8AB21DE52:\ -D871B9BB85CF7910F49CAE84414F37A6C26034362E8267A4BCCA0E1A9269C6BF\ -7022B8EE03DBC5EDAFEF60ADF16012FF8AA939678614B383130F55A7A3780230 +770FDA46E0435A36A9F4B9E81BB9945CD82F05ECCD6B46DAD48FF92825E2B4F5\ +D21608AE6B945AFAC4650F2408168D3538488FC20A8447FD01EC2DFDF55F8F36 0DC45181337CA32A8222FE7A3BF42FC9F89744259CFF653504D6051FE84B1A7F\ FD20CB47D4696CE212A686BB9BE9A8AB1C697B6D6A33:\ -93FB224AF201888068A73981DD63652F7600ADE60B22AE37EF9545702C8340B2\ -9F2CFB705D9421EE09449743E97D522037DBEC9DE50ADF91FD629663AEF116AC +6FD2A68D85527B6A15F4E7499FF2C6028C74DE9CD2AD0837DFA4FDF64FEC3164\ +6BB89A80125F27D244718C635B5997D7CF014B5ED30A7CC5547C6C24C188B223 DE286BA4206E8B005714F80FB1CDFAEBDE91D29F84603E4A3EBC04686F99A46C\ 9E880B96C574825582E8812A26E5A857FFC6579F63742F:\ -2B6F8FBE583B60E750D3689CD6A681ECEBE6384BC6B444B8A9346D52A5826354\ -61C0E9CE40CCF8033BBF4F3A43C05D4313E5AB38A066DEDFD6CE8D46476AF6F5 +0AE21935400D5DEFDB036321F900999BC9AFD61703510168190CC8D36D2BE4F4\ +9DE95C902C286DBAA91F516D231EC4D2AC55425D05FCDEDD211E67A3EFE51E12 EEBCC18057252CBF3F9C070F1A73213356D5D4BC19AC2A411EC8CDEEE7A571E2\ E20EAF61FD0C33A0FFEB297DDB77A97F0A415347DB66BCAF:\ -A88163B4C6C5275B0A09069A3689EA208CBFF8687CFFBF799D209B248B9DC67D\ -11F32A18C4AACA6726874F8D2D0365EDFD17DB9A4AD24084CE2918B91F21D4B4 +24DCD83A82A389C7DCBDE997F9F1D0A52A64566699E5D8B8CDBFF0F88A427AAE\ +7C6BBB419F013B8CFC780D47101616BAF0B2C41CFDDD24BAF46610364FC82A03 416B5CDC9FE951BD361BD7ABFC120A5054758EBA88FDD68FD84E39D3B09AC254\ 97D36B43CBE7B85A6A3CEBDA8DB4E5549C3EE51BB6FCB6AC1E:\ -BAAA6AD28EA720D8ADFD0466141B465F741992F9CCC35B4A281119F4CC654320\ -6C4C31D952FBE17B11F0E1A82653DBA16C35486CF8879E6C677F38A857C23523 +DD99BE3D8FB3C4A307E6ADFB18B638904CC12A033D61D1095DDFDC0F6FC62AE5\ +27CC5AF45084D2BE4A416E1BDED2E855650A9CEC6FE618B0856563FA1FDDFF38 5C5FAF66F32E0F8311C32E8DA8284A4ED60891A5A7E50FB2956B3CBAA79FC66C\ A376460E100415401FC2B8518C64502F187EA14BFC9503759705:\ -108807312C29DEDA857D162A043427302A12E1CA38CB6A17665BE5D71223C258\ -21BE12FC18AB1CE23B2CAD9795F9DF0231DE8EE39E64111F912D257C00946F9E +359D189247A6B503F66FBA5CCE4BEBC7F6551239301BFCC608CFCCF8E9896305\ +5A6E6DD96F6813605B486403BB943A747EDE6C9F8AC586ED6E73DD4D4DC0296E 7167E1E02BE1A7CA69D788666F823AE4EEF39271F3C26A5CF7CEE05BCA831610\ 66DC2E217B330DF821103799DF6D74810EED363ADC4AB99F36046A:\ -23013C3939B713F4C410AE1D5BED0977D63F3403C9A1B2E176F13C13402A1CD1\ -58DA92045A605173B6BD46057B9E3F9E7891BC487EB7289D948452DBF72098C3 +347E5762FA00809092ED5E660E399CF51EA861687AF8AD6D4EA50BE431764442\ +5000D1B33D9F3B05D7A961E2B385C4AF3ED5B5E767E4580C931747E5D3005CC8 2FDA311DBBA27321C5329510FAE6948F03210B76D43E7448D1689A063877B6D1\ 4C4F6D0EAA96C150051371F7DD8A4119F7DA5C483CC3E6723C01FB7D:\ -2422F221BBA5965522072EA5CA8DF78D573484460B62BECDEB412AF92668EA7F\ -E4DE75B1C11DE0AE048BE00EE897C05BD9FD4E477E5AC3CDEFB1F01E090424E4 +710B3E6D37198D55FE6DF676CF727F982E2B24E38456627D711E18C789AB9D99\ +6276C12F9605A567D1B7FA524296DB2E53D4DAC2F6089874CA099EBBB10E2071 95D1474A5AAB5D2422ACA6E481187833A6212BD2D0F91451A67DD786DFC91DFE\ D51B35F47E1DEB8A8AB4B9CB67B70179CC26F553AE7B569969CE151B8D:\ -83C62DC6985C154771320F9FF0E14AAD86D713D6AC56BCFD9BA445FD6C35A748\ -B89FDC7CC3AF80157F0F56FA48AA54181C1117276DC195E7A68C8942341F7D79 +9E8D69EEDAEEE8F426D478B39693767D1B28CAC4CB47CD1416C73F82E29EBE06\ +2FBC41AD10A398F4EF4C124A70D96384EC5DBD2BE869DD84C9BA6808BAE6368F C71BD7941F41DF044A2927A8FF55B4B467C33D089F0988AA253D294ADDBDB325\ 30C0D4208B10D9959823F0C0F0734684006DF79F7099870F6BF53211A88D:\ -FCEF35C5CFDCB906711A24D5B3EA2D106E15A65B5E87BF7B438597A2A37E1BCD\ -08F8B8E6C3A2E493A47B439671724D38D2A42855411F32FCB13FFB5A21A86B2C +8F109A4B2F65CFC881CB456966630C91EF26E79838CF1E090488B9DC348FAD9F\ +F050197B373BA326AC5F42FD81F3D9C944238918E748453233EC309FA0000670 F57C64006D9EA761892E145C99DF1B24640883DA79D9ED5262859DCDA8C3C32E\ 05B03D984F1AB4A230242AB6B78D368DC5AAA1E6D3498D53371E84B0C1D4BA:\ -8204F6D09AEB41690BBC4AEEB8437579EC8362A0CB2B5351014E99E3B7EBD80B\ -654E23F8EF938ADC7F31D17F78DD7582D178F6C3A89B8B7C603410381447A3CA +A94A8BBAAF30DA2D1BC52EFCE0541B8BD109663AD73830261B6179CA31D08CC5\ +ABF512CE3DE1118DE1230B31AFD5A01B5D6A49B370BEEE77A3988F9CBD32618C E926AE8B0AF6E53176DBFFCC2A6B88C6BD765F939D3D178A9BDE9EF3AA131C61\ E31C1E42CDFAF4B4DCDE579A37E150EFBEF5555B4C1CB40439D835A724E2FAE7:\ -926F142A64C9DE0CB07F1A35B635D9839B1DFB045B64AC087C47D533F1D62237\ -C18F9EDB76963A1D4683E3ED14E8792C1D2E9889EC37F2A42AC36CFBA9361ECD +548D7A65D8BEEBE56C466DA17F8DD80722A7A2A59352465A150F58C1CDC75E80\ +49F5734EA16F32F5CE5B339CDFD99D930D20A6B8655B6F20DE4E7E7438C405E8 16E8B3D8F988E9BB04DE9C96F2627811C973CE4A5296B4772CA3EEFEB80A652B\ DF21F50DF79F32DB23F9F73D393B2D57D9A0297F7A2F2E79CFDA39FA393DF1AC\ 00:\ -7F4CE24C8D7C8E19577E3C1ECA97ACAF15D280E312580C031845B1B40153EAD8\ -F55B9FFD6997C2C8EDE6879334ADD187F255C300240603452AAC651B4B901F31 +19152CBECBB159ED38D70436671A47CC9373EBC74EBB31FB22E36DD22E0DA921\ +15745AD7B1B0114596F940B6BC90C19EDD53A9AD012BF1F5B6B419FC8A1A6597 FC424EEB27C18A11C01F39C555D8B78A805B88DBA1DC2A42ED5E2C0EC737FF68\ B2456D80EB85E11714FA3F8EABFB906D3C17964CB4F5E76B29C1765DB03D91BE\ 37FC:\ -42659DFBA135041D8B9D8EB4FE57514236FA5F8CC63F6DC07258CA01AD9772AB\ -92EB6898B2B83F2B2977110D565F9ABA18FE1B1F3B7400AD69C05CB8AE578762 +F08612959457304C50026B146FAED6FEFE60EC27008F986130DE8D487C9BB29F\ +7A6A5F51F5083C6EEDBD2E9DE7A7B7658B8C10AD6F01807B4460FD3B36FC01BC ABE3472B54E72734BDBA7D9158736464251C4F21B33FBBC92D7FAC9A35C4E332\ 2FF01D2380CBAA4EF8FB07D21A2128B7B9F5B6D9F34E13F39C7FFC2E72E47888\ 599BA5:\ -74E130CAE5866A10C53D7296A724BA1FD52F370FD01DDFFBE987D6D63AF90D11\ -3EB294E34871C1C753230C467B4E19ADD030A160499F7A84E15DFB33460E53A2 +436A9BAE3CA9FA4E8627C359D8D2628B0E2C341C75502B3EA80253E5448A6A52\ +4201DFABA2A2B42185DF0F94B06A8074216F057E300E16669A0271AE69B1A54C 36F9F0A65F2CA498D739B944D6EFF3DA5EBBA57E7D9C41598A2B0E4380F3CF4B\ 479EC2348D015FFE6256273511154AFCF3B4B4BF09D6C4744FDD0F62D75079D4\ 40706B05:\ -D8837EE8E91BE8823EC9B792DDC180EA180DFEC7803083BB7EE86CF4B26FFB5E\ -1F27D2D13858201791ED4A15E30BB248280D5EAD0F798299BAFF961651949658 +BDDEB8D9A990C8B92FFD27D8B0EDA074D9F1DAF0E3FCA1F1D708D7B3922D5FB7\ +A92BD49523F74516CF373ECD835E399EF6E8ACFEB2C7A61166FA3FA9FEE0B5C7 ABC87763CAE1CA98BD8C5B82CABA54AC83286F87E9610128AE4DE68AC95DF5E3\ 29C360717BD349F26B872528492CA7C94C2C1E1EF56B74DBB65C2AC351981FDB\ 31D06C77A4:\ -627C41B2215B346FD315F40073FCEB990D56A927C56ACF61EC5C6CA1C165C141\ -8030E12F83E24E8343ED0D12BBEE5E0328C21653AC1746B85D85451719EC499E +76D74B7AA7C1787F7D2689144A9665416AABBA5B2646EC52C22F7DF5A20C7F6F\ +B2B1FD5C45668EDB0EE468A99567766F594D3E18F1D8162321445EF8F25A3D20 94F7CA8E1A54234C6D53CC734BB3D3150C8BA8C5F880EAB8D25FED13793A9701\ EBE320509286FD8E422E931D99C98DA4DF7E70AE447BAB8CFFD92382D8A77760\ A259FC4FBD72:\ -8C7FDBF9EB06DFE9AD23BD461B67D75C7C4E450602812B496F3244D6FC30AC8E\ -1BB3A2F6761612DCB42F12AA1DD5C7CE14B7B2D375793A7BD6DE3DB593D81C27 +2D26A2CA37790EA1ED334F854CB6127F9D6EBBC716341A175B7C6625511974AB\ +1B6ADBC71014F258677089C2BB397F0669C34F686C008706E1DEB560B5D43DEE 13BD2811F6ED2B6F04FF3895ACEED7BEF8DCD45EB121791BC194A0F806206BFF\ C3B9281C2B308B1A729CE008119DD3066E9378ACDCC50A98A82E20738800B6CD\ DBE5FE9694AD6D:\ -25069EEB77DCA02E9FA7FE6B8B75A73BB54003DF9242050F8084626C32163189\ -5E5426D59AE5C89D2F6AE5B1B4883793E853C30718F0CFBBF4EEDB09949DFBC2 +B28CF291DB775DEC4E87BD30792BC2CCF1B528F62537176C9206CF255F8B7959\ +10C65E3C308FA2275B021FFD737F88856107BDA44AEB4199EE5675471E789A81 1EED9CBA179A009EC2EC5508773DD305477CA117E6D569E66B5F64C6BC64801C\ E25A8424CE4A26D575B8A6FB10EAD3FD1992EDDDEEC2EBE7150DC98F63ADC323\ 7EF57B91397AA8A7:\ -10983820E5AC1F63D5F9155BB731FBEA51DC29C94A6C754ECE1DE4C15015E38B\ -5214446B64A8B1FC5C8D2071D0323A9179FD667E373B80DDB43E120DA70A7285 +DABF7F4D5455F3C9505CA6B49CABD8ABD3EE4928CCEF88DC60FAAC08607CD686\ +1C316294D3954AA514672A289182C3FBE49B15051D4645214C5D01A6FC783899 BA5B67B5EC3A3FFAE2C19DD8176A2EF75C0CD903725D45C9CB7009A900C0B0CA\ 7A2967A95AE68269A6DBF8466C7B6844A1D608AC661F7EFF00538E323DB5F2C6\ 44B78B2D48DE1A08AA:\ -7B8FFAB30873F60DA93EA5822843F3F47048B0B0B8B034A22FC7A2A63511A411\ -C4AE65E6370E5683B47A9AD1D25A53D1B6B08214019E60BD908DAA63529EA1BA +D4B8A36DE3B40CBCA69B5819C5D4E524E8C36FECAEB8092A5B02FFD12C19A17D\ +EA1B09F1430F1F62EB046CB0F7697233FB51E3EEFEA61CA2C320E97B34BA6ED8 0EFA26AC5673167DCACAB860932ED612F65FF49B80FA9AE65465E5542CB62075\ DF1C5AE54FBA4DB807BE25B070033EFA223BDD5B1D3C94C6E1909C02B620D4B1\ B3A6C9FED24D70749604:\ -C8C74FC231FC8A701FA4AD641028F7F59024330661CEA2907EA442A1BF961A88\ -F5A025E096CCB67BA8F3B8DC141AEA5C0B066393DA11CB9C3380368A86C5C13F +61CD40E83B900F9730DE8BC331EA9F75F81D138992E500082FCFA41610BEEBBB\ +5ACE85FFF570462D9960D17A67A2D2BDC8CAD0D401DD642957386C553310CD42 BBFD933D1FD7BF594AC7F435277DC17D8D5A5B8E4D13D96D2F64E771ABBD51A5\ A8AEA741BECCBDDB177BCEA05243EBD003CFDEAE877CCA4DA94605B67691919D\ 8B033F77D384CA01593C1B:\ -690B25D978A43A4DDFFCDE4240F18E95B388EF0CB3B0F4018E9F6B2BC3187EDD\ -75EBAD33FD75B3A6468666556E92695B5E494FB0D4DDAECD223144BEF702C36A +DBE49B8A74C886BA4B5E3E1FBF23274D8122019F7E66C61DB04CF5F61D75340D\ +34811558A575B179F2B45C7C7B60D3FDC1C5D9BB8F6DE53591AB9BC905702157 90078999FD3C35B8AFBF4066CBDE335891365F0FC75C1286CDD88FA51FAB94F9\ B8DEF7C9AC582A5DBCD95817AFB7D1B48F63704E19C2BAA4DF347F48D4A6D603\ 013C23F1E9611D595EBAC37C:\ -8DBFDF512CCFD357E6437640FEDCDCA8DAD285AA8E5A8AC08C4A5572AD653C60\ -7CFCB9049CFF6B7F4D3C9C3495B8C70A19DFEC8642639ABD54408F25EF55D475 +826E66301DC5F89FA5559170A9AE0E07B1DCE27A5EB90029DC4E7C9A2F005D25\ +EE319DBD74A0F2D3034027ED03566F2D6D768A4F4BF88BF208AED0AD623D339E 64105ECA863515C20E7CFBAA0A0B8809046164F374D691CDBD6508AAABC1819F\ 9AC84B52BAFC1B0FE7CDDBC554B608C01C8904C669D8DB316A0953A4C68ECE32\ 4EC5A49FFDB59A1BD6A292AA0E:\ -D3F093F883036869820520A75D7F1C389474558B3E5742AD02B1E2AC6A380898\ -D3237BA3AE6D7738EA25AD0B925DBBF1BC825178BE80C1CFAFC35980A5B9700E +70FFCA06DC5C2ECC63E938915A70755843AE11990C4285FF4448D5DECCF9CF00\ +4C04774B6419E80D5E96CACF830F16595C995F37F629D4C82D7D5837AF28E6FA D4654BE288B9F3B711C2D02015978A8CC57471D5680A092AA534F7372C71CEAA\ B725A383C4FCF4D8DEAA57FCA3CE056F312961ECCF9B86F14981BA5BED6AB5B4\ 498E1F6C82C6CAE6FC14845B3C8A:\ -FC6E8BF596ACA6BF88A65B185BE195ADC1C53ABE3F2C485A28F4BC9A22E4A779\ -8731DB8BF26625CB3D04276910DB6465FBCA57641CE38389264889147E9E5144 +E5C313F54B334BAB5746161EDBEA426AB1EE8FB01521C0BBE3B10B41F88498C0\ +A53D14D4F0951C0BEF8110ED3DBB4FE93CF0C538E7B4FC04D9D87FF98B690736 12D9394888305AC96E65F2BF0E1B18C29C90FE9D714DD59F651F52B88B3008C5\ 88435548066EA2FC4C101118C91F32556224A540DE6EFDDBCA296EF1FB00341F\ 5B01FECFC146BDB251B3BDAD556CD2:\ -FAAF8737AFAEF553F042073BC8172F380A26780920DF3B12B5F42A76E8FE9324\ -B8146092BB8CA2ED014BD41704F4825605AB1EE7FA352A420E3E3DB5022CC43C +40A3015076E0BD34B7A5EDDABE5C948A93C0C62C84470CD24EA4B624CADDB37A\ +FF2A9C654988231085A216F619697175F5AA2B6211C9E32D0FF4253EA95FD7D5 871A0D7A5F36C3DA1DFCE57ACD8AB8487C274FAD336BC137EBD6FF4658B547C1\ DCFAB65F037AA58F35EF16AFF4ABE77BA61F65826F7BE681B5B6D5A1EA8085E2\ AE9CD5CF0991878A311B549A6D6AF230:\ -36C0947410D52F264BB450C77C0822B8C7F7DF5E425478919861CD90E0820BFB\ -3F24B30757040C1AB28EB2342368D315F2B5A5584A0CE735CEC219B4AACFC5B0 +F69BD0F7B6AEF0BA7FCA622865756298B881A4E747090C77F48B5BE74BA70DB2\ +2BDFAA758FF43698CA821472A121D46B3CDCFC62D139243B757A9456660843B4 E90B4FFEF4D457BC7711FF4AA72231CA25AF6B2E206F8BF859D8758B89A7CD36\ 105DB2538D06DA83BAD5F663BA11A5F6F61F236FD5F8D53C5E89F183A3CEC615\ B50C7C681E773D109FF7491B5CC22296C5:\ -82DC90329F774C2F54E86A04496DB2CA6ABE31C0C930499008227432C4B08875\ -FF26680BFF326D67DC1F16DE7ABFCA303ACAD9154E9D712A2FBC461E5613269F +7DC20435E62DEA8C32FA4D6F90D16D711F4E43A14D74FA29F648EC2D0F0FD22E\ +10BF36220A639AC67AA2F5DFA0454565C9AF02A90F97F0202A1EBBEFB5859A1F E728DE62D75856500C4C77A428612CD804F30C3F10D36FB219C5CA0AA30726AB\ 190E5F3F279E0733D77E7267C17BE27D21650A9A4D1E32F649627638DBADA970\ 2C7CA303269ED14014B2F3CF8B894EAC8554:\ -38EA632A13CAF8C0144C99755446235901233D8618DBD47DC13CAFA488E1006F\ -73794945AFF9C4AF418AD7EDCEAF76841775007080F0AFF4443189AB5F93AE1D +9C7CFFFBFFE1E8783080510B7F9F11E04B3F9C5A6D17F5ACA02E07650347C352\ +A3CC60096FBCF21055385B0BA1EB3C6E4282690BFB32413FD55DE09E06403BE9 6348F229E7B1DF3B770C77544E5166E081850FA1C6C88169DB74C76E42EB983F\ ACB276AD6A0D1FA7B50D3E3B6FCD799EC97470920A7ABED47D288FF883E24CA2\ 1C7F8016B93BB9B9E078BDB9703D2B781B616E:\ -A58D6008392293665E8C9CDA03632471EE474F946FF29D2D03E5BA7ED7E574D9\ -C37346A0713004081872DDD37397665DAF634671C1123A539ABCEBB88A0CF3DF +A0E94AEB83183E924DEA9C94DE5F76EBDED8FB2D344C3CDF46FA8D738FF331EF\ +1061F96FD3D5D1F75EB95525B8388F4AB481D5BF9A48B9DE8E5DDE2F6C0B526B 4B127FDE5DE733A1680C2790363627E63AC8A3F1B4707D982CAEA258655D9BF1\ 8F89AFE54127482BA01E08845594B671306A025C9A5C5B6F93B0A39522DC8774\ 37BE5C2436CBF300CE7AB6747934FCFC30AEAAF6:\ -FF7E839D9DF579713B7D9E02BCD979B2C24A25AB13BB6B8E80F170344F3C61C1\ -4D2532A993081F47EA9DAE2346EFF8A1CBEADEFA7BCE11D3CB547901D1354D64 +FAC419F422D0A0C09653EB9938D6FEDA794CFE6162FEA02D35AD0C53F70CDFBF\ +5D60C4D33A5FAE394AC6938371A088977413172BC2284EA3C78623508726508C 08461F006CFF4CC64B752C957287E5A0FAABC05C9BFF89D23FD902D324C79903\ B48FCB8F8F4B01F3E4DDB483593D25F000386698F5ADE7FAADE9615FDC50D327\ 85EA51D49894E45BAA3DC707E224688C6408B68B11:\ -42F2DA8296D7305DFF934BCC21AD52DAC181D937A840A739816ACD74300B4FFF\ -61A1486114DCD6EDC9E6101CCA43B3B5B2815AB8ACABE29CC71FF7F09940E9A3 +3722EE99604E8C8C7069FB1CC07B67F9DB082BE5BA359AC8FBBA285FFCC00204\ +39F96DFAD898124A779E758D3E8D28A41F3B59990C027F6E88D1FAD75112779D 68C8F8849B120E6E0C9969A5866AF591A829B92F33CD9A4A3196957A148C4913\ 8E1E2F5C7619A6D5EDEBE995ACD81EC8BB9C7B9CFCA678D081EA9E25A75D39DB\ 04E18D475920CE828B94E72241F24DB72546B352A0E4:\ -068CC9BECFAC3BEECC23A1767FF00238D2227B164EE5B22238A70953D2E34C6A\ -39F638F97BE9FE71BCD503497548B18F40951050D6828C0118FA4892252AE247 +BC30D45D62D909FC5ACD1B87B9C70065228D2722A360A1D25F726A8469F725FC\ +163496C39E7D31AA2B3BD9016A2253D7CD05E4D678A35358847090A778D8CF8D B8D56472954E31FB54E28FCA743F84D8DC34891CB564C64B08F7B71636DEBD64\ CA1EDBDBA7FC5C3E40049CE982BBA8C7E0703034E331384695E9DE76B5104F2F\ BC4535ECBEEBC33BC27F29F18F6F27E8023B0FBB6F563C:\ -1E2890C88D9FA31AC0952F2EE9309450DFC6391A241E2FAF55A7FA550FBBACF5\ -C6CDD85B0A95B5AB6117C38A85F9C82B7F7066FE1D7900CD8FC27DD1200ADEAA +E1DF1CF42A685BAD183FE9E7C3A21DF52826174DB659CA114E8EAE39569E5B20\ +EACF33A97ED436207F95568248FFBF922833A1D7153785FD869BAFC494ED82B1 0D58AC665FA84342E60CEFEE31B1A4EACDB092F122DFC68309077AED1F3E528F\ 578859EE9E4CEFB4A728E946324927B675CD4F4AC84F64DB3DACFE850C1DD187\ 44C74CECCD9FE4DC214085108F404EAB6D8F452B5442A47D:\ -244B9AF6F4A80FAAE1F81E523BDCF3CC361AB27788FB4B6A2628B778F8B39513\ -C225BDCD1F814EAFF459C90DDC99D62A5BAFDB967E207350BC718FF7142657E3 +B986BEA853B9CA92ED1F11D2205CDD09ACD3DD7DD4A4F48ADB1892F9B0296AB3\ +99B4CEDD69A6EC8C1E8E4FB30FD3040EB7057CDD3C0104EA910875196F93C53D 1755E2D2E5D1C1B0156456B539753FF416651D44698E87002DCF61DCFA2B4E72\ F264D9AD591DF1FDEE7B41B2EB00283C5AEBB3411323B672EAA145C512518510\ 4F20F335804B02325B6DEA65603F349F4D5D8B782DD3469CCD:\ -BBE9E91FACBA93DA63322E8B59BB1C64B881211194251C1237E997E551796DA5\ -2995C34B40036EDE7D15C597EC4431B5AB2E05EB03DF46A9086A48D58650722E +4DCE35639B8F219455E77AB4E0B99A94CB2DE19842D9213F11552EE9DD7A57E8\ +54EEB7E91F7E13152F757068E40105BB355306B3F16540991B11D215C02E8B80 B180DE1A611111EE7584BA2C4B020598CD574AC77E404E853D15A101C6F5A2E5\ C801D7D85DC95286A1804C870BB9F00FD4DCB03AA8328275158819DCAD7253F3\ E3D237AEAA7979268A5DB1C6CE08A9EC7C2579783C8AFC1F91A7:\ -EFB0D1C9E0EB8DD9B5A33E642FA4F93CBC8F62FF67003ADB42A58BE7B86AD308\ -19ED1A656C17D5D5A01FD442210F4EA1F7FC4D75F13560FB08504844350DFFA1 +E71B2170F0F3761D1FFF4C20A01374886E483724954F5F683120E4CDE589011C\ +7EAF775F3E0CD93953513DC0A119412E12611757F3BA846A33545FD257E5591B CF3583CBDFD4CBC17063B1E7D90B02F0E6E2EE05F99D77E24E560392535E47E0\ 5077157F96813544A17046914F9EFB64762A23CF7A49FE52A0A4C01C630CFE87\ 27B81FB99A89FF7CC11DCA5173057E0417B8FE7A9EFBA6D95C555F:\ -144639558BB4321A5968021BFA84F7241955BA9237773488BBBABBAB9286EE00\ -E6A8A6EFFBC21F217111510AAEE5EE0ED906D9EA5DEA52415F708CA0BC156B9D +29036EEE2CFF84925CE84157EC3B90EDE0A434B52AD89C0F91E84D0F2CFD0357\ +1F610E18829B9B69984BB57FA055DE6288F43C33A9A19CF71B4045195B2908AD 072FC02340EF99115BAD72F92C01E4C093B9599F6CFC45CB380EE686CB5EB019\ E806AB9BD55E634AB10AA62A9510CC0672CD3EDDB589C7DF2B67FCD3329F61B1\ A4441ECA87A33C8F55DA4FBBAD5CF2B2527B8E983BB31A2FADEC7523:\ -AB961D00600EBB3C3E3500547077C31C0F975D9A2CFF1519C013C48222700BA8\ -03ABBF23B967E0A082F00FB1DD3C520C38C7F5298A06F6CFEABEBB951DE9B364 +06E45A1A77F1CA437BB4554E9AC2791C74D7C3E7202D94C64C6ACF258FF7217A\ +46A8FCC49C6C9E56B53ADE741FA30060E35E365FFC9CD7BD3AEA92D011924D7E 76EECF956A52649F877528146DE33DF249CD800E21830F65E90F0F25CA9D6540\ FDE40603230ECA6760F1139C7F268DEBA2060631EEA92B1FFF05F93FD5572FBE\ 29579ECD48BC3A8D6C2EB4A6B26E38D6C5FBF2C08044AEEA470A8F2F26:\ -6815226C40917DC69411050D38DC1A8F94BC99D095A7BB74529291E6CCD5E71A\ -405869F6E7E9111F54C9B2528E72B3BFFDDC2F9EB6FD02271B3786C1398049D8 +3A08CE7F48E71FB89CA12701C6BFB6D6ACBC3847351E0C4840CEC0FEEF141B69\ +A7780128837FA082E6803FCAC832DD57E5E8AA776B058ED5062AAEE0D3B10EA2 7ADC0B6693E61C269F278E6944A5A2D8300981E40022F839AC644387BFAC9086\ 650085C2CDC585FEA47B9D2E52D65A2B29A7DC370401EF5D60DD0D21F9E2B90F\ AE919319B14B8C5565B0423CEFB827D5F1203302A9D01523498A4DB10374:\ -F40CAB07D41D001D2EF64E5B2B590A8F1EB54A248B55D5BC8AC411A33CFC32CB\ -D5F30330EF9AD6DF62EE3DAF91EE282392BBD53D4E04686DA6A75944A8541259 +797015514DF48346879712ED2AD3BE484DB7F19B94DD8A4A77DA987287298674\ +F68E331432B15CFA0CEB395E40E2BD424B850293CD3BEE39B6F042B58469FE54 E1FFFA9826CCE8B86BCCEFB8794E48C46CDF372013F782ECED1E378269B7BE2B\ 7BF51374092261AE120E822BE685F2E7A83664BCFBE38FE8633F24E633FFE198\ 8E1BC5ACF59A587079A57A910BDA60060E85B5F5B6F776F0529639D9CCE4BD:\ -BFA7856A28597491D01D1FE04F028779B6884ECCB14578E985AE43FE6F26DE55\ -D1484B87813B88D233EC8B8E1ADAFB7F2938051E4ED2A3B56B35012B9085E9E1 +8930CF8606BF372E0F355E6036146EA14AC2F0605B2C192CCF3E60DEE5DD95C7\ +730581274AAF4DF61438051FF8A566B0A537E1ED13FF250F11EFD7F3257F9F60 69F9ABBA65592EE01DB4DCE52DBAB90B08FC04193602792EE4DAA263033D5908\ 1587B09BBE49D0B49C9825D22840B2FF5D9C5155F975F8F2C2E7A90C75D2E4A8\ 040FE39F63BBAFB403D9E28CC3B86E04E394A9C9E8065BD3C85FA9F0C7891600:\ -C39F4A7E6B45DB2FDF146887FAD15CB83541A5BBD51367D9A0D971E312FFED28\ -5B380C0E4B3BBE8D492D259B713981600FBC62FECE7A904399857E41BB5AA574 +375AD74C0E39D401D4022174A5FA4363447C85D72ECCF1D380845149240DFD32\ +09F81E4AF263F429B8FB6116062880152AD9E40F01EC23B61E390EAB9AE3F502 38A10A352CA5AEDFA8E19C64787D8E9C3A75DBF3B8674BFAB29B5DBFC15A63D1\ 0FAE66CD1A6E6D2452D557967EAAD89A4C98449787B0B3164CA5B717A93F24EB\ 0B506CEB70CBBCB8D72B2A72993F909AAD92F044E0B5A2C9AC9CB16A0CA2F81F\ 49:\ -C86DBAFBCC87C1A9F23846B856FEB881FA1C663AA3A50E1B71F9E70E7FB4A21E\ -B8165F22505169B3F360876328D799F618175B29D26D650A804CD2926BDE6A05 +B0DD4E0619AAD0B8C44B30D106A0A57B8C10172520E072865B6CF5B12CFCA23A\ +F742AE9FE222C5D900C84BCE529C87F93BE4264331A7EDF7A1C0071F2265B1F5 6D8C6E449BC13634F115749C248C17CD148B72157A2C37BF8969EA83B4D6BA8C\ 0EE2711C28EE11495F43049596520CE436004B026B6C1F7292B9C436B055CBB7\ 2D530D860D1276A1502A5140E3C3F54A93663E4D20EDEC32D284E25564F62495\ 5B52:\ -BB59022C4426826788E09DE943EFE4D7FAE71BCDD31270FBCFA0385EFEF6BF96\ -5F7D49D3B296897DF0FAEA677E6D1E62417BD08198FF3C76FAC765F27E0B9AD6 +4F70DF19FFAA4650A834B1BF154B61F077C76467F2EB38B3A60E26D82702294C\ +7E91611C63522D62B1EF007981516018833F9C7030BDA0A3661373F4739C8E94 6EFCBCAF451C129DBE00B9CEF0C3749D3EE9D41C7BD500ADE40CDC65DEDBBBAD\ B885A5B14B32A0C0D087825201E303288A733842FA7E599C0C514E078F05C821\ C7A4498B01C40032E9F1872A1C925FA17CE253E8935E4C3C71282242CB716B20\ 89CCC1:\ -80A11F3D809C269942F4E17D5A13FDB4A7E3EDBE1177ECC4816A883FD924A0F3\ -30A6E27286364464609B566A2D4951B6817BF5D828D24DECE963630FB06B3C94 +24B8C31CA0EA5A1C627BBAEE4BA822323AC4198415FB69D99B90B26DAF42520E\ +6B489F05F9C48AF52BB7E11FC4D72C37CBFAA04433559EFC388CE9C83008C9F6 433C5303131624C0021D868A30825475E8D0BD3052A022180398F4CA4423B982\ 14B6BEAAC21C8807A2C33F8C93BD42B092CC1B06CEDF3224D5ED1EC29784444F\ 22E08A55AA58542B524B02CD3D5D5F6907AFE71C5D7462224A3F9D9E53E7E084\ 6DCBB4CE:\ -506AE4A6B5F39DA18FAA39A6E110BD1B2889D739F4A56AFD9867A6948C063C7F\ -CC9DBE16FC804F387DD48510D39F07EF5C3FAD3B73C53AECE1D359D853D8FCC7 +E1573F9C0D6D49D8A1D6B29663DB387A1EBB5F107C37A4E6330673B1A23DF7D1\ +B1475E14EA001319D683CD902CABA8E33B90A10FB7F1C5468E9A4FDBC7BFD2E1 A873E0C67CA639026B6683008F7AA6324D4979550E9BCE064CA1E1FB97A30B14\ 7A24F3F666C0A72D71348EDE701CF2D17E2253C34D1EC3B647DBCEF2F879F4EB\ 881C4830B791378C901EB725EA5C172316C6D606E0AF7DF4DF7F76E490CD30B2\ BADF45685F:\ -E8F6B97FF2429752891F69F91893B9AFEC04E931ECD58AF96AEF937233404F68\ -D83D111BD2AE642A960FC7365BDC820BC1FB686022E6C2BC0422577789A7507A +669CAA7CE8599AF49B6AA8963FF4C19E43247953E0EAA7453EB954217AB9CA86\ +A82245E4C0916F7E9631F763A12B8EF516E5AB33DAC41D8FEB1F88B8778BF185 006917B64F9DCDF1D2D87C8A6173B64F6587168E80FAA80F82D84F60301E561E\ 312D9FBCE62F39A6FB476E01E925F26BCC91DE621449BE6504C504830AAE3940\ 96C8FC7694651051365D4EE9070101EC9B68086F2EA8F8AB7B811EA8AD934D5C\ 9B62C60A4771:\ -36C1FF38C5F3BC8E642AFC2EDD8DC67A9B0F46F5A1A46AE970A94204FE0DB95E\ -540F46A5DE01F5C0D9E357A4FA7A8EB070F2BF98C9CF553B6D2AD2CD2ED0EC38 +B0D673B7F25D73616323175F04CD969285914F163CDD0513CC97350C4BC50574\ +228BF1271026013A82260281554EAF29471F4CE3CC4472AA8030A6CF20982C32 F13C972C52CB3CC4A4DF28C97F2DF11CE089B815466BE88863243EB318C2ADB1\ A417CB1041308598541720197B9B1CB5BA2318BD5574D1DF2174AF14884149BA\ 9B2F446D609DF240CE335599957B8EC80876D9A085AE084907BC5961B20BF5F6\ CA58D5DAB38ADB:\ -9715FA25210B31BA4E700755A8CE75992C0620ED22243A18F7F08F6240A3C09B\ -3ADAFC89C356DE6009507A532D435FE44785C9FC06A30F97C43C536848DBAAF6 +61FE4777C89455B9FA259F9F8DEA012CBE1DC51538C54E77CE7D95EAC48E73F9\ +00B77B51B00018A6AF84C407877EE9B0DC3FF5788638A52AC8B150E823416640 E35780EB9799AD4C77535D4DDB683CF33EF367715327CF4C4A58ED9CBDCDD486\ F669F80189D549A9364FA82A51A52654EC721BB3AAB95DCEB4A86A6AFA93826D\ B923517E928F33E3FBA850D45660EF83B9876ACCAFA2A9987A254B137C6E140A\ 21691E1069413848:\ -D00A87501AEE7D7457E8B463B43604E9688440E83AC76D0601553E0E6281CF55\ -8A92ACBA1F90DADB84737C6851075B415CE5FBCE1DFC85EADAAEFD43765866B5 +2227BF50BD45C41592EB42EDAB9FEE3E78DD0FCF0497BFA733B99D9B5699D3A2\ +7932F4F81F7D4AF43A23E94CA7A9A88D82C2781602EF5E1ECF4712CE6F72E8F4 64EC021C9585E01FFE6D31BB50D44C79B6993D72678163DB474947A053674619\ D158016ADB243F5C8D50AA92F50AB36E579FF2DABB780A2B529370DAA299207C\ FBCDD3A9A25006D19C4F1FE33E4B1EAEC315D8C6EE1E730623FD1941875B924E\ B57D6D0C2EDC4E78D6:\ -88FECE207FCEF6BA2DC893289E8FF4401175DF1D8CD00E2C44D31701F6C0BADE\ -386C94DFE91104D002E92B5F84DA89DC2AB2EA527D2877D319FAE51DA1F1D9AF +67F82DCA717D47E9E0854BEDC55A1756CD624F58DF755CF9702DE5CD73B57F6A\ +EF7BBF40922A915F383D7D3A910FF95936EC74E35B3B2AA6146F30E11AF3725B 5954BAB512CF327D66B5D9F296180080402624AD7628506B555EEA8382562324\ CF452FBA4A2130DE3E165D11831A270D9CB97CE8C2D32A96F50D71600BB4CA26\ 8CF98E90D6496B0A6619A5A8C63DB6D8A0634DFC6C7EC8EA9C006B6C456F1B20\ CD19E781AF20454AC880:\ -DBAF5302A755CC44F28B4E8083089E5D17810F9E1C191D97C862560327AE568D\ -1459058AE9343C8565A0AEC6D94C5E0F88982827A92CAB1CA551843DFD937E9F +83665C2BCA49C95BBE584DF52242068193F7A9DAAA67B0EE36FA9A81516E4CD6\ +A3D15A222F95A2DDB7494C5DBB7E83EB30A72BA342DC98060D1F78B9C8F0E893 03D9F92B2C565709A568724A0AFF90F8F347F43B02338F94A03ED32E6F33666F\ F5802DA4C81BDCE0D0E86C04AFD4EDC2FC8B4141C2975B6F07639B1994C973D9\ A9AFCE3D9D365862003498513BFA166D2629E314D97441667B007414E739D7FE\ BF0FE3C32C17AA188A8683:\ -88DB17A8B022D2E52A9A3B9BE7790C5E623CB0FEE52103FB5F3BC2715FF400FD\ -D1DE8093E95570253462693A1D4BD5B1B6867139FECF7AABF19DC6D7A89CF398 +C505A3841C5589D0B2A428D684C9D14520C6359A5AAED6A560663947899E42B5\ +88D5D7BE55D580931B25AC2E2FC5F3AF360D60741C0BA82D5A94BE61D2CCC830 F31E8B4F9E0621D531D22A380BE5D9ABD56FAEC53CBD39B1FAB230EA67184440\ E5B1D15457BD25F56204FA917FA48E669016CB48C1FFC1E1E45274B3B47379E0\ 0A43843CF8601A5551411EC12503E5AAC43D8676A1B2297EC7A0800DBFEE0429\ 2E937F21C005F17411473041:\ -1039453D77ACDD8719FE013FE904F49339574B64A28662A399A010DC6DFCF80F\ -B61A0D9CECDAD0FADCDD30480C8225CA3423746575C564EF6EA1DB7B557A5A66 +EB6FD4B2B90F79F0071C8D2744C352DBDC7807D40EAF5979DBF21410CEFC2CA2\ +B867010A213C34090E3AFD0C8EA65F43D1AC48EAB67721AF5508D6F193031611 758EA3FEA738973DB0B8BE7E599BBEF4519373D6E6DCD7195EA885FC991D8967\ 62992759C2A09002912FB08E0CB5B76F49162AEB8CF87B172CF3AD190253DF61\ 2F77B1F0C532E3B5FC99C2D31F8F65011695A087A35EE4EEE5E334C369D8EE5D\ 29F695815D866DA99DF3F79403:\ -4437B0252F715304BEE9B06B31EBB029D51BDA7C01E5EE614AB2F5B981AEFBF3\ -5F4C9A093C8F26672D77D08AAAA49F9C672C0F5AC8AD6ABB0AE30B4A098F2447 +FF96DEEADD3C3668F9C9FCF23EABB6C08A908D89B997ED4005FDB4ADDFDBC165\ +D47CBDC2A9A064D95BEDDEDFE1F5AE0D7A05EED7D1B30D3DC1D3AC8850425575 47C6E0C2B74948465921868804F0F7BD50DD323583DC784F998A93CD1CA4C6EF\ 84D41DC81C2C40F34B5BEE6A93867B3BDBA0052C5F59E6F3657918C382E771D3\ 3109122CC8BB0E1E53C4E3D13B43CE44970F5E0C079D2AD7D7A3549CD75760C2\ 1BB15B447589E86E8D76B1E9CED2:\ -72C9B767071710D37FEF19E7939F9A245615532E9D4FA643974B211A8D9E5A64\ -AF75A4A365F2503B8B2C71A7A9A6D65BA08E671A044B2E4FA4873DD4EA59154D +E0269128AD1687BB7C35926E98CC9A9C7670C1276C3F10C37853928AA6C0AE7F\ +E414D379FCBAE20DF0161781690053B9322D8AD14D66C1A4B7B35FFFF9CF3F16 F690A132AB46B28EDFA6479283D6444E371C6459108AFD9C35DBD235E0B6B6FF\ 4C4EA58E7554BD002460433B2164CA51E868F7947D7D7A0D792E4ABF0BE5F450\ 853CC40D85485B2B8857EA31B5EA6E4CCFA2F3A7EF3380066D7D8979FDAC618A\ AD3D7E886DEA4F005AE4AD05E5065F:\ -01C1E76E50BDD370BCA1EEFFACF6E56F61AC91D193DDB738A75F062FBFAFED79\ -F5618EB34F3ACB06D7850A40CF5E10DE41F6F9D61F3F6A3DDA9C5CB8D63FD691 +CA5FA777561C6C13ECBCAD526527343009BB1EB77B4BCE263FC24E00A5A5FB92\ +96D2BA13598A646BF936397E43A7BF9D303CAE83E3654CC25F636F7FAB03C2B1 58D6A99BC6458824B256916770A8417040721CCCFD4B79EACD8B65A3767CE5BA\ 7E74104C985AC56B8CC9AEBD16FEBD4CDA5ADB130B0FF2329CC8D611EB14DAC2\ 68A2F9E633C99DE33997FEA41C52A7C5E1317D5B5DAED35EBA7D5A60E45D1FA7\ EAABC35F5C2B0A0F2379231953322C4E:\ -AE45DDCA514264B8ACE8283E675AEAB6F75631FF5E0693DD4E798DB122D425C3\ -83CB8008CFAD1417755C6ECCEE33EB4979079A1BFB81E08D059D2F196E1935AB +FBCAE8C494C5FD0ADB640CEB4A15BF634293EC37CCF119AFF5BEC95F55578ED9\ +0D26861A045E0F242302158D3EAC801185498D6D8033662F2E0E6BA5B6F04ACE BEFAB574396D7F8B6705E2D5B58B2C1C820BB24E3F4BAE3E8FBCD36DBF734EE1\ 4E5D6AB972AEDD3540235466E825850EE4C512EA9795ABFD33F330D9FD7F79E6\ 2BBB63A6EA85DE15BEAEEA6F8D204A28956059E2632D11861DFB0E65BC07AC8A\ 159388D5C3277E227286F65FF5E5B5AEC1:\ -CCDA0F2420E7E550353D455172C7D96B3C73BA96154BA850FC316B65D2988B3C\ -2A88AFA619A0E325E61973A4F7D0B260CA3DC5288D21338E5691D775B9596186 +28500180D6F48671A4ACD83C9BB5FE3665CF9A6163D8797A2A2F9EA3974619B3\ +12769F67C1BB279A409C05A6B4E371F57FC658096923B5EB086D920EE8C748E8 8E58144FA9179D686478622CE450C748260C95D1BA43B8F9B59ABECA8D93488D\ A73463EF40198B4D16FB0B0707201347E0506FF19D01BEA0F42B8AF9E71A1F1B\ D168781069D4D338FDEF00BF419FBB003031DF671F4A37979564F69282DE9C65\ 407847DD0DA505AB1641C02DEA4F0D834986:\ -C86A3FC28768D1B12141216F2211F902CAA1F0FFFBE41710AA1186A8CE35CEED\ -23044C5F4464B79BE81E40B4C9903F9C6807958B440D059C5A9A6911CF600E43 +B205C2E223BF2A741F35294E9B7E1C33EF745A31F5CE2A00F6EC43B05044034C\ +4993D5112E4BA7CEB2BDA4C2E2C8E09B52CE6C2AC7B5374260BFEED8752B65C1 B55C10EAE0EC684C16D13463F29291BF26C82E2FA0422A99C71DB4AF14DD9C7F\ 33EDA52FD73D017CC0F2DBE734D831F0D820D06D5F89DACC485739144F8CFD47\ 99223B1AFF9031A105CB6A029BA71E6E5867D85A554991C38DF3C9EF8C1E1E9A\ 7630BE61CAABCA69280C399C1FB7A12D12AEFC:\ -17DF80D04C1B2D4FAFCCDABFCC6E109261A61FF525F845FC5DCC354BC19984F7\ -4F94A6CA82C95055CCD22D9F70D0DC68AC306DA361C135E9B40764A936E6947F +38FA9FFE97CA84452F56C26702F561BBB105D1AE19D78C3528132DAA809B006E\ +E2359EFE54EB35FE0760699070D2B33B2401A5C12132797DF0BDAF96A8DDB04A 2EEEA693F585F4ED6F6F8865BBAE47A6908AECD7C429E4BEC4F0DE1D0CA0183F\ A201A0CB14A529B7D7AC0E6FF6607A3243EE9FB11BCF3E2304FE75FFCDDD6C5C\ 2E2A4CD45F63C962D010645058D36571404A6D2B4F44755434D76998E83409C3\ 205AA1615DB44057DB991231D2CB42624574F545:\ -885461034C5ED300812411297256FA74CCA8D5D61858AEF4E3F5E3737643C5BD\ -B92E65626B685C810D901D33CE22C30072634C431F95EA76936068D686999DC3 +F5D3FCDDF5C8E2E0513700B11775B0B3C73CD16B18AE52BD3ED225306EE9B5E6\ +B5E402334BC5A4FD1AF5D47138D44217DABF5CBDFFD6978B956EED71C21E05CF DAB11DC0B047DB0420A585F56C42D93175562852428499F66A0DB811FCDDDAB2\ F7CDFFED1543E5FB72110B64686BC7B6887A538AD44C050F1E42631BC4EC8A9F\ 2A047163D822A38989EE4AAB01B4C1F161B062D873B1CFA388FD301514F62224\ 157B9BEF423C7783B7AAC8D30D65CD1BBA8D689C2D:\ -EABFDA04298F0CCBB7DDD4318C98A6F4FFB749D8EFD902823511CF548C3DE032\ -E206F295FD9EC9FE44A05A4E1E7C5F01B19BBCBBE0A0AC142231B0860FAFA4CB +1A25D0833B2CC0A1A0D7C892639D0DF281D10334860F70878287DD4015A3F731\ +2093AEF197D49A1BE99F1615EA38D52A5F3665AA87BF20E89DD7A04E3DC09CA7 42E99A2F80AEE0E001279A2434F731E01D34A44B1A8101726921C0590C30F312\ 0EB83059F325E894A5AC959DCA71CE2214799916424E859D27D789437B9D2724\ 0BF8C35ADBAFCECC322B48AA205B293962D858652ABACBD588BCF6CBC388D099\ 3BD622F96ED54614C25B6A9AA527589EAAFFCF17DDF7:\ -BAFFEB5AC8E9BB44791F112B5FA090EF60CB13D05F3F137DAD89E2AD70DC9FF1\ -5BD6C44075A7A4F979FCFAE0ED57A68151F81E68C65AEBA44BCC19057EA93E98 +0942326FEECAAD788EEB7D50863FD9280211C9F63B16ECD51AC874A80B47988D\ +61799A10D3B23DC23AE26C179ED5EBC9E32B7697B0566079852BBFA5FA21FFAC 3C9B46450C0F2CAE8E3823F8BDB4277F31B744CE2EB17054BDDC6DFF36AF7F49\ FB8A2320CC3BDF8E0A2EA29AD3A55DE1165D219ADEDDB5175253E2D1489E9B6F\ DD02E2C3D3A4B54D60E3A47334C37913C5695378A669E9B72DEC32AF5434F93F\ 46176EBF044C4784467C700470D0C0B40C8A088C815816:\ -7197F27D300980CBFC230639E8DD20832A6CEF9E39EA54A2C9CD37C905134952\ -64B2BEF2393B5F2E0B3C14AF80BD63275EB4D653AAC91CFB805AF9C14B833C4B +E9F908BC91CE95ABBA48644FC7C1F8E211E3D2EEA459021FF7E4496C6F1AA3EC\ +A73AEF2813B33819139CEB6ADD5FCFB4EBEBCE72AA1E30DC328454CA69FFBF31 D1E654B77CB155F5C77971A64DF9E5D34C26A3CAD6C7F6B300D39DEB19100946\ 91ADAA095BE4BA5D86690A976428635D5526F3E946F7DC3BD4DBC78999E65344\ 1187A81F9ADCD5A3C5F254BC8256B0158F54673DCC1232F6E918EBFC6C51CE67\ EAEB042D9F57EEC4BFE910E169AF78B3DE48D137DF4F2840:\ -88E837536AC03572D8A41E6F59E6F8530F581E4FF3DB097A849037DF26665CBA\ -B72241AF292A3DF1E738E39209A8B293B65ACB77E07F577A22DF24E8B5A58AD7 +5CEEE2800816DDF676BBD3C8B7D95012808E62A1838CD292893B05085DD08B95\ +EA245FB84283BEF479FD0E2B8BF9DD1BA722344E83DC391A85AEE2C930F985C5 626F68C18A69A6590159A9C46BE03D5965698F2DAC3DE779B878B3D9C421E0F2\ 1B955A16C715C1EC1E22CE3EB645B8B4F263F60660EA3028981EEBD6C8C3A367\ 285B691C8EE56944A7CD1217997E1D9C21620B536BDBD5DE8925FF71DEC6FBC0\ 6624AB6B21E329813DE90D1E572DFB89A18120C3F606355D25:\ -4D6BD6E1B24AD612BBC238E64AB89084D2703007FD59C8B4718E65124DB8E926\ -70DEF8282470F0E78CDE6AC9A28E1BFA42BEB8442BDC5904082DEC9271995281 +ED0C620D495F5190D8667F0F9B50C9FEA28FC01AE9B219027973A341BA87118A\ +821451D5EEE580C4FAEE46DAD21C43C72523AE86A8579576247EB8E38D0C6BA6 651A6FB3C4B80C7C68C6011675E6094EB56ABF5FC3057324EBC6477825061F9F\ 27E7A94633ABD1FA598A746E4A577CAF524C52EC1788471F92B8C37F23795CA1\ 9D559D446CAB16CBCDCE90B79FA1026CEE77BF4AB1B503C5B94C2256AD75B3EA\ C6FD5DCB96ACA4B03A834BFB4E9AF988CECBF2AE597CB9097940:\ -502F271E81519BC7AAA67C4F7AB71BDECF7717C0F56A23539C969922977FA7BD\ -88922BA4BC556DC806672A1C734E4373F2E82FE605567E0EEC383EE6078360D3 +138F2DF9686F705E5C55020B89F04AB66654B0CACCC1A8D374334B6BF6534335\ +C7514206B6F772DDB0550CFABA22D22B913928D3ADF78BFD25DF9DD517B2E3A3 8AAF072FCE8A2D96BC10B3C91C809EE93072FB205CA7F10ABD82ECD82CF040B1\ BC49EA13D1857815C0E99781DE3ADBB5443CE1C897E55188CEAF221AA9681638\ DE05AE1B322938F46BCE51543B57ECDB4C266272259D1798DE13BE90E10EFEC2\ D07484D9B21A3870E2AA9E06C21AA2D0C9CF420080A80A91DEE16F:\ -47583501739DAC6F5A99D13719F6C5A44D88CA4A503EF2CFCFDEEA17D018CE03\ -345F75034F782450B67DEE9C27660DC6FD050FAED16F8630436EF5D87EBD7068 +3348F4E8C4768C3EF687A8E2A02E307FD8591B41235F8C14E5983AE7361968D0\ +CB877AF488B975001AA1E7ACF0E5844C107A102BF028FCEE89CFE751266D88A3 53F918FD00B1701BD504F8CDEA803ACCA21AC18C564AB90C2A17DA592C7D6968\ 8F6580575395551E8CD33E0FEF08CA6ED4588D4D140B3E44C032355DF1C53156\ 4D7F4835753344345A6781E11CD5E095B73DF5F82C8AE3AD00877936896671E9\ 47CC52E2B29DCD463D90A0C9929128DA222B5A211450BBC0E02448E2:\ -B4D44B02CFB3BF59A42E35B4263FF91BEEA9E978C71DBD5E1DA3E53730A1F7C1\ -A838D2AA5FA6F134A575F269C9677943F5CAC9D8D47CE0FB8157E4BF8E2BE416 +CA7257AC51700539DF617C3B7EE9ACC7C4576332996F905D9D3733F1AAF3287E\ +2F852BE394E533F64EA19733276B0E448496F88500770675835E133904E4071B A64599B8A61B5CCEC9E67AED69447459C8DA3D1EC6C7C7C82A7428B9B584FA67\ E90F68E2C00FBBED4613666E5168DA4A16F395F7A3C3832B3B134BFC9CBAA95D\ 2A0FE252F44AC6681EB6D40AB91C1D0282FED6701C57463D3C5F2BB8C6A7301F\ B4576AA3B5F15510DB8956FF77478C26A7C09BEA7B398CFC83503F538E:\ -46BA7F2CC804F2573AB08B3D4F152370DCD0299AA82D4E090DE6C69A07FC83B3\ -821905128838125F0BC4ABCDF41FB64AF63A5915842750DE768D2C5445DA1313 +ADB3B6E2083CB37ED5F822D1AA2ADA18560C663011CB16CFB804A5F24C0525F3\ +4D8CB10D19528BA02BB43BD501BF0D0AC67968B0687DCB21C013527A99AE9D84 0E3AB0E054739B00CDB6A87BD12CAE024B54CB5E550E6C425360C2E87E59401F\ 5EC24EF0314855F0F56C47695D56A7FB1417693AF2A1ED5291F2FEE95F75EED5\ 4A1B1C2E81226FBFF6F63ADE584911C71967A8EB70933BC3F5D15BC91B5C2644\ D9516D3C3A8C154EE48E118BD1442C043C7A0DBA5AC5B1D5360AAE5B9065:\ -48AEE486EFCBDF1979B9E59B54EC8117C6E00EB94307F642CA136CEC7354CC91\ -8700522477F80347A7E91CA4CEA327EEC390C975AF974F1A03474ACB7CF3B6D4 +EA781FDD2DDDE4B42E1A6B75AB70CFCF17DC413CD9591254F91F1E9741811916\ +56EDC92823A3145DBE4AB491E86233DAACD748CCD2A86B551D6D47EDEA943C82 A62FC595B4096E6336E53FCDFC8D1CC175D71DAC9D750A6133D23199EAAC2882\ 07944CEA6B16D27631915B4619F743DA2E30A0C00BBDB1BBB35AB852EF3B9AEC\ 6B0A8DCC6E9E1ABAA3AD62AC0A6C5DE765DE2C3711B769E3FDE44A74016FFF82\ AC46FA8F1797D3B2A726B696E3DEA5530439ACEE3A45C2A51BC32DD055650B:\ -A5FBFEB1FD1CED918FD189B7E8E49A2A26F99A9898B7469AD421F16DCF934E56\ -F17C68083F731F172FE9D6F26B141C8E7617A6369DB97CD31131B259ECE05C3A +B2DCDDF444C51976F2D71D020BEF76810C8CCAE2B94C34178C600CCDD04B233B\ +A2D27DB4E8F07EE01D611E490564B6071858BC8B8F8D23BC6B8DA746DAD4A132 2B6DB7CED8665EBE9DEB080295218426BDAA7C6DA9ADD2088932CDFFBAA1C141\ 29BCCDD70F369EFB149285858D2B1D155D14DE2FDB680A8B027284055182A0CA\ E275234CC9C92863C1B4AB66F304CF0621CD54565F5BFF461D3B461BD40DF281\ 98E3732501B4860EADD503D26D6E69338F4E0456E9E9BAF3D827AE685FB1D817:\ -FC79270DC468C4663FEC45C4581C49AB6C0631A77FFBBE8882C396A06C685231\ -CF91651BF810C765213D4160C6D64C36CD8B2EA0A87EACF31690B54BC8EB7636 +447C299F7E5C90CEE70A7577EC148FEF194F40BA7C3C8CBC96FF81D14490A16E\ +397CA01F3C0883E050F805239FBD4189122B45B1101EE1F303281D2AC1580E2C 10DB509B2CDCABA6C062AE33BE48116A29EB18E390E1BBADA5CA0A2718AFBCD2\ 3431440106594893043CC7F2625281BF7DE2655880966A23705F0C5155C2F5CC\ A9F2C2142E96D0A2E763B70686CD421B5DB812DACED0C6D65035FDE558E94F26\ B3E6DDE5BD13980CC80292B723013BD033284584BFF27657871B0CF07A849F4A\ E2:\ -1C54E058E303ED843CEC563E57F5BC283085BCD6285C36F7C4AE124FF0F42C75\ -865689746B4C1119C54E0782AFAD3D507E0C0DED767B8937D87CB3A8A09416B7 +E21AEB7109CA41F1C41F4B66E80A6A4248AED43341F1EFFABB61341C3F0B6355\ +EFE3DAA8D28D60F9BF851E6837625BF2EBFD8A68CDCB50718660D5CCBFD93910 9334DE60C997BDA6086101A6314F64E4458F5FF9450C509DF006E8C547983C65\ 1CA97879175AABA0C539E82D05C1E02C480975CBB30118121061B1EBAC4F8D9A\ 3781E2DB6B18042E01ECF9017A64A0E57447EC7FCBE6A7F82585F7403EE2223D\ 52D37B4BF426428613D6B4257980972A0ACAB508A7620C1CB28EB4E9D30FC413\ 61EC:\ -269AD5A2BCD1943138C9BC13A6E410559B4ABE511C357C1CDA3283AFD9DBA2A5\ -8DA526166041555D780610DD5C36BE7097258233949B8D42E4DF1E0908BBDCB4 +FC015B69F1AE0DC7004343FF941378B8A23AA45A3825310E9A81C2A9EA2D4F96\ +1F4C9B8CACBC91F0D2414590C389D24ED482B95252F37B5A6CC6BFAEA5C98C32 E88AB086891693AA535CEB20E64C7AB97C7DD3548F3786339897A5F0C3903154\ 9CA870166E477743CCFBE016B4428D89738E426F5FFE81626137F17AECFF61B7\ 2DBEE2DC20961880CFE281DFAB5EE38B1921881450E16032DE5E4D55AD8D4FCA\ 609721B0692BAC79BE5A06E177FE8C80C0C83519FB3347DE9F43D5561CB8107B\ 9B5EDC:\ -6D49BBE0A468811E6068D4CEA22D9E5116D4F79E24584160647F8FFE460EA496\ -C47A9B47C8A5029BE941D02A739F89D594CD0BC312BD25FEB9CFC2B05925292E +45CCB97F9524BA87A7E69354030C71A07D875C5E958EA167EFF581703B1D5037\ +BD91B8806980E3D4EAE0ACB010D210CD89F781DED33F5697DAC285AEB37629A4 FD19E01A83EB6EC810B94582CB8FBFA2FCB992B53684FB748D2264F020D3B960\ CB1D6B8C348C2B54A9FCEA72330C2AAA9A24ECDB00C436ABC702361A82BB8828\ B85369B8C72ECE0082FE06557163899C2A0EFA466C33C04343A839417057399A\ 63A3929BE1EE4805D6CE3E5D0D0967FE9004696A5663F4CAC9179006A2CEB755\ 42D75D68:\ -8D327AAEF3FF05C0DE51B40347D11EC4D5ACB50ACC24B39C44273839D1878AC8\ -7939855B86B03195F67CF7D7FC7F41C74A4968C489A4ED7EFC4DFB199536BB8C +142922E983887BFF20D0EE26BCBCBA34A1A70717172B8FBDE0AEABC5CA258C39\ +85B00F7908A21A75C014D4B2542A1BFCB7469BA9454F66670B6C05BBBD7A92D3 59AE20B6F7E0B3C7A989AFB28324A40FCA25D8651CF1F46AE383EF6D8441587A\ A1C04C3E3BF88E8131CE6145CFB8973D961E8432B202FA5AF3E09D625FAAD825\ BC19DA9B5C6C20D02ABDA2FCC58B5BD3FE507BF201263F30543819510C12BC23\ E2DDB4F711D087A86EDB1B355313363A2DE996B891025E147036087401CCF3CA\ 7815BF3C49:\ -786D18C6816FE5AF627CCCB692D79AC99825C57F76E63B93CC774FCAEA388D4A\ -354EE7D39651EB11BFE6DC96BED877E71DA5F7AE1BB5114795B96C1AE4B56173 +41DF07681C94633DC430AD7FFF9AB7146F1CC3A66DF3A81D990ED3D247D8F9A5\ +880EFF20C2652FB6C6631EA41F54D6C331651FDC20783EED65B83AF458D0AC72 77EE804B9F3295AB2362798B72B0A1B2D3291DCEB8139896355830F34B3B3285\ 61531F8079B79A6E9980705150866402FDC176C05897E359A6CB1A7AB067383E\ B497182A7E5AEF7038E4C96D133B2782917417E391535B5E1B51F47D8ED7E4D4\ 025FE98DC87B9C1622614BFF3D1029E68E372DE719803857CA52067CDDAAD958\ 951CB2068CC6:\ -6ED0CEB2C0404260D2466A80FAA097C0BE4B68F537610474D3368224D4862CFC\ -C569294915E4E447645562BE785B9D2850BE8F4962D421AB7346D8E4C0DD02FC +9BEE78530C0A93CE8564AEDE785D7086CE066CB74C3B8F70D3851CD57DB8E647\ +E67DF0D543EAFEDED491613BD3268CC7CE8DE34614A79D6413C3FEE218B6965A B771D5CEF5D1A41A93D15643D7181D2A2EF0A8E84D91812F20ED21F147BEF732\ BF3A60EF4067C3734B85BC8CD471780F10DC9E8291B58339A677B960218F71E7\ 93F2797AEA349406512829065D37BB55EA796FA4F56FD8896B49B2CD19B43215\ AD967C712B24E5032D065232E02C127409D2ED4146B9D75D763D52DB98D949D3\ B0FED6A8052FBB:\ -87DDFDED0BAEBC090A82B8BAF67BECCF72E46D2D4C91A5C6A26583467D2A41E0\ -D04384A58BF9C5C209A82696AC54A760E571331D16A04F5D926CA104A3F42740 +E2548952816803ED478241CBAB10F69DB4CBDD98447BFAF4E92AF9A3179B6EFA\ +CEC56C757944B519C69D1759811732FE3C52912611271231342D9D62F3472967 B32D95B0B9AAD2A8816DE6D06D1F86008505BD8C14124F6E9A163B5A2ADE55F8\ 35D0EC3880EF50700D3B25E42CC0AF050CCD1BE5E555B23087E04D7BF9813622\ 780C7313A1954F8740B6EE2D3F71F768DD417F520482BD3A08D4F222B4EE9DBD\ 015447B33507DD50F3AB4247C5DE9A8ABD62A8DECEA01E3B87C8B927F5B08BEB\ 37674C6F8E380C04:\ -9C32DFB92D2079F704C30734843B70B6670FDA53507DEAD248E644AB1CEDCF91\ -1BE16C04FE35FB861195A4EEEA9ED929D3249E0107DCB15BA76BFC6F534895AF +0E673628FA620668F73E652DF7927EC7D9DF9426F157B055E39D23AD7FA9CCCD\ +C8013FB8F6A0D2EFFEBE00BB5563B100B5361F33808AE20E23580D414F909CED 04410E31082A47584B406F051398A6ABE74E4DA59BB6F85E6B49E8A1F7F2CA00\ DFBA5462C2CD2BFDE8B64FB21D70C083F11318B56A52D03B81CAC5EEC29EB31B\ D0078B6156786DA3D6D8C33098C5C47BB67AC64DB14165AF65B44544D806DDE5\ F487D5373C7F9792C299E9686B7E5821E7C8E2458315B996B5677D926DAC57B3\ F22DA873C601016A0D:\ -C0F684549025FB7AC404D5DCD997DC1E2392B3DD10A071CF17A1773D80877CC3\ -EA2A109263161D343C6B06BA6288D303A137647BB5A1992842FD97D1B200ECA9 +1B0E41061FF47E71F22FCD508E8560F8E4C9748DD8E520A9CA478F3E3827330C\ +6F19E299E221367E6B02E1606A1B23F2B3F66762D0F408B3A68C9DA9018A45DD 8B81E9BADDE026F14D95C019977024C9E13DB7A5CD21F9E9FC491D716164BBAC\ DC7060D882615D411438AEA056C340CDF977788F6E17D118DE55026855F93270\ 472D1FD18B9E7E812BAE107E0DFDE7063301B71F6CFE4E225CAB3B232905A56E\ 994F08EE2891BA922D49C3DAFEB75F7C69750CB67D822C96176C46BD8A29F170\ 1373FB09A1A6E3C7158F:\ -CE1BAF61F4215C7E4802AEDEB5FE0843868A173A005755CDC84D5E270AC0D127\ -6C53B72EFEA7A25D1090F32637B4582DD2D5E85D00C16B4A87F347E8267CB72F +FEE0EA0269154ADD8FCC28BC61D290CCE0CA04FEBD3EF646D5AEED6542461D4C\ +DA983932BE7ABF3E0C2639ACF75AE2770D1B511D996E19536542FB4D76505F69 FA6EED24DA6666A22208146B19A532C2EC9BA94F09F1DEF1E7FC13C399A48E41\ ACC2A589D099276296348F396253B57CB0E40291BD282773656B6E0D8BEA1CDA\ 084A3738816A840485FCF3FB307F777FA5FEAC48695C2AF4769720258C77943F\ B4556C362D9CBA8BF103AEB9034BAA8EA8BFB9C4F8E6742CE0D52C49EA8E974F\ 339612E830E9E7A9C29065:\ -FAE974D0586C79EC9E5957B99EFDAF4DE4510D554D8F689EAA8841234B33BA2C\ -D75B62B5300BFFEB2E6C64007D363756E987183BB8779266E07BED49246C10DB +82DFF74AC5CDFFA0D1D03049F2FC227DCB77E373381C2E74FA316BBF9F6D55AE\ +B7667A95AE4D4D367130620217E245E9DDC641AFF823475AE40E4E3CE56FCD40 9BB4AF1B4F09C071CE3CAFA92E4EB73CE8A6F5D82A85733440368DEE4EB1CBC7\ B55AC150773B6FE47DBE036C45582ED67E23F4C74585DAB509DF1B8361056454\ 5642B2B1EC463E18048FC23477C6B2AA035594ECD33791AF6AF4CBC2A1166ABA\ 8D628C57E707F0B0E8707CAF91CD44BDB915E0296E0190D56D33D8DDE10B5B60\ 377838973C1D943C22ED335E:\ -EC6DED9C61223888BCD03EBF8E1037BDA52F94FF110B42524163010490B12204\ -37A68947D80FFE967B5317D2F8B1CE9C4ADB4FF2C6F89E4D54A7256C660106ED +97D7C677B7D8EA600DE069CC23C492C0C293EB8E9B8987978CD43B2CACE445A9\ +0D1CDFA4E0F347EC9B7E6394DEF55702A13DC5DE3C5E43B8B08F260BF0E654D5 2167F02118CC62043E9091A647CADBED95611A521FE0D64E8518F16C808AB297\ 725598AE296880A773607A798F7C3CFCE80D251EBEC6885015F9ABF7EAABAE46\ 798F82CB5926DE5C23F44A3F9F9534B3C6F405B5364C2F8A8BDC5CA49C749BED\ 8CE4BA48897062AE8424CA6DDE5F55C0E42A95D1E292CA54FB46A84FBC9CD87F\ 2D0C9E7448DE3043AE22FDD229:\ -66C863F11E3149CAE8F0629FE48CAA35D7475812644286B2F9DF5598259FFCB2\ -46BB83919CA664CF9F5B0CF151BA8AECAEAB1938E69AB3B628770C0E93DB2444 +A0A9203714A9DCAE2402958E6BCF759B7E900D13D5A8654501ADAC70B5CEDF27\ +D21F5E92219DAD31DDC8466D8F559470C638D9F9B45D4F539D36C54651C4852C 94B7FA0BC1C44E949B1D7617D31B4720CBE7CA57C6FA4F4094D4761567E389EC\ C64F6968E4064DF70DF836A47D0C713336B5028B35930D29EB7A7F9A5AF9AD5C\ F441745BAEC9BB014CEEFF5A41BA5C1CE085FEB980BAB9CF79F2158E03EF7E63\ E29C38D7816A84D4F71E0F548B7FC316085AE38A060FF9B8DEC36F91AD9EBC0A\ 5B6C338CBB8F6659D342A24368CF:\ -049A414B5A3DA568A5A9166CA7D9135FFA0E0B49DF43E4E796AF60D6613BDDCE\ -1006161AAC9BBCAB6B80199DCB52648B3CE998EA0AE27B37AADB3A9C914171CC +E6D9B97F5BDB0BB4F5D2322CEFF8A1A747361BB937BCFA69EB8C23D98BEA5C5E\ +E25F9587648912D5E7F90E73C031A27E27FB11276CCB63E47C25B18649AE5DD8 EA40E83CB18B3A242C1ECC6CCD0B7853A439DAB2C569CFC6DC38A19F5C90ACBF\ 76AEF9EA3742FF3B54EF7D36EB7CE4FF1C9AB3BC119CFF6BE93C03E208783335\ C0AB8137BE5B10CDC66FF3F89A1BDDC6A1EED74F504CBE7290690BB295A872B9\ E3FE2CEE9E6C67C41DB8EFD7D863CF10F840FE618E7936DA3DCA5CA6DF933F24\ F6954BA0801A1294CD8D7E66DFAFEC:\ -2B9131F248BE3B340BA45642E3DC9270543156FE2150700E36A7CE5887C60A35\ -5B4B055926888EAEF79743E1B038CA724F506366E8706176B382DBA414114FCB +0A14506B804455218133711A3BA8307615E4F80A5334B86555B9CEC77C93450A\ +92F6A18BED9BD55B1848F78C2A49A76057FCF3509663F2E9010C39D94FC9918C 157D5B7E4507F66D9A267476D33831E7BB768D4D04CC3438DA12F9010263EA5F\ CAFBDE2579DB2F6B58F911D593D5F79FB05FE3596E3FA80FF2F761D1B0E57080\ 055C118C53E53CDB63055261D7C9B2B39BD90ACC32520CBBDBDA2C4FD8856DBC\ EE173132A2679198DAF83007A9B5C51511AE49766C792A29520388444EBEFE28\ 256FB33D4260439CBA73A9479EE00C63:\ -574A12CEEE655CBD90E3F3E483ACF5CE445D30029F34A5B364E73124AF129A7A\ -40D4BECD4233C83911D4E92E4FAF23DA979D11F3FCCC3BFC6F2E39B2FE0CBFFE +8D03AFCB3940007FCBCEEB023C105918E6540D87658E59109CC6568CF804BD3F\ +A2B3968C28C650E55276218482BB8E42944272673D6A137D326477A1BAFE8F3D 836B34B515476F613FE447A4E0C3F3B8F20910AC89A3977055C960D2D5D2B72B\ D8ACC715A9035321B86703A411DDE0466D58A59769672AA60AD587B8481DE4BB\ A552A1645779789501EC53D540B904821F32B0BD1855B04E4848F9F8CFE9EBD8\ 911BE95781A759D7AD9724A7102DBE576776B7C632BC39B9B5E19057E226552A\ 5994C1DBB3B5C7871A11F5537011044C53:\ -FF04FF3D476E6B1E418B6C656DF2CA4577843B0F8300304F312E8DECE522D9AD\ -F994EBFEBD02050E7A622261B31875863DBEFFB50C07CFCBCE40D33FBC087110 +4862476DDDADDCDE60A35260AB6C448B9B6DAD7ED296FC48B81E288D0E397E69\ +4535CC8999F4D7F2F3E09F5CE034DB0F71EF5C812F3C6BBD73FBEF14B252BC55 CC7784A4912A7AB5AD3620AAB29BA87077CD3CB83636ADC9F3DC94F51EDF521B\ 2161EF108F21A0A298557981C0E53CE6CED45BDF782C1EF200D29BAB81DD6460\ 586964EDAB7CEBDBBEC75FD7925060F7DA2B853B2B089588FA0F8C16EC6498B1\ 4C55DCEE335CB3A91D698E4D393AB8E8EAC0825F8ADEBEEE196DF41205C01167\ 4E53426CAA453F8DE1CBB57932B0B741D4C6:\ -0427F9E924540E619A2E3CA21C1139A26529F032DB801389BB3B156F74662D59\ -114B6C65E800D554C88FB39F945D67446B2D56C36D882805EDD7F533CD5D726B +4B239C5B1C8B83924AE736E9D30582D16BF00A547023244247B389259BC62649\ +81606439AC9DDE0A7D371B73A34CAC998823803D7BD62ABF8905C9BD550EBAB8 7639B461FFF270B2455AC1D1AFCE782944AEA5E9087EB4A39EB96BB5C3BAAF0E\ 868C8526D3404F9405E79E77BFAC5FFB89BF1957B523E17D341D7323C302EA70\ 83872DD5E8705694ACDDA36D5A1B895AAA16ECA6104C82688532C8BFE1790B5D\ C9F4EC5FE95BAED37E1D287BE710431F1E5E8EE105BC42ED37D74B1E55984BF1\ C09FE6A1FA13EF3B96FAEAED6A2A1950A12153:\ -5CAB5FC3B20EDFAC061F3DE3434A42BCAFADBFE4BD7C15D2A5FA7FA7A81CA028\ -C8073E8A5BD54618CAA1C2AA22C7C636831D23227753BFF5CAE342C0DF86A840 +2B0D1C2780D8826CCE4B71A77C9833AE59C2BD0213789A8892CCD7B4FFF1D8A7\ +80E81AD4C2C1228D55DF5BA3625DE4860DB05743E4D07934C434BAD5A769131B EB6513FC61B30CFBA58D4D7E80F94D14589090CF1D80B1DF2E68088DC6104959\ BA0D583D585E9578AB0AEC0CF36C48435EB52ED9AB4BBCE7A5ABE679C97AE2DB\ E35E8CC1D45B06DDA3CF418665C57CBEE4BBB47FA4CAF78F4EE656FEC237FE4E\ EBBAFA206E1EF2BD0EE4AE71BD0E9B2F54F91DAADF1FEBFD7032381D636B733D\ CB3BF76FB14E23AFF1F68ED3DBCF75C9B99C6F26:\ -8CA096F3F386895CEDC7924785316E53585F0D9F6BD62687DDE376B12024DAC3\ -CFA860EAAC59ACEAE26FDC1FA92CDB81536E30BB89EF0B02C9DD5D6D1B0CB597 +0880376CD5FFC7EBCC6E80FAE0D78DBB3532500BAB96CD4B755584D23E68CF59\ +F5297A34AE0A90184773412BC9548A80E4C54391B4CB59CE292D704C614DD1A1 1594D74BF5DDE444265D4C04DAD9721FF3E34CBF622DAF341FE16B96431F6C4D\ F1F760D34F296EB97D98D560AD5286FEC4DCE1724F20B54FD7DF51D4BF137ADD\ 656C80546FB1BF516D62EE82BAA992910EF4CC18B70F3F8698276FCFB44E0EC5\ 46C2C39CFD8EE91034FF9303058B4252462F86C823EB15BF481E6B79CC3A0221\ 8595B3658E8B37382BD5048EAED5FD02C37944E73B:\ -A7496CD71B2503BF3E61A50F269C639342A50C27A5474724919A56722B530EB6\ -F587265016003AEA5E89AFA8D5E4B825DF2AA20F2EE3B1D24A320F9E4FD79599 +E725B8C82C8D1F3963A77D505B0A929FD58846061BEA2BA7040B7D3B2AD95EE3\ +781CACA60B372EB5258A44A65BB9EE655A1EF9102F8BBD9E41FCFB2871DAEC7D 4CFA1278903026F66FEDD41374558BE1B585D03C5C55DAC94361DF286D4BD39C\ 7CB8037ED3B267B07C346626449D0CC5B0DD2CF221F7E4C3449A4BE99985D2D5\ E67BFF2923357DDEAB5ABCB4619F3A3A57B2CF928A022EB27676C6CF80568900\ 4FCA4D41EA6C2D0A4789C7605F7BB838DD883B3AD3E6027E775BCF2628814280\ 99C7FFF95B14C095EA130E0B9938A5E22FC52650F591:\ -7DF2F4E99989DFCB586C604725C000AD32DA859247E422479A7629F3117E93D6\ -50F6A272F2CADE0F07B92382C5FC0D0E3B5313F16DF54FEA12D63BDDBA98FAB6 +31175C65FF1133F5F53DB80DEB90F6B2E79727D4C8E77C5E3F5DEF70525B871B\ +50249C6F2EE1CA6F11A7CD9C578CF13D5FCBD74DE1D05AF6076A5459E10B4B9D D3E65CB92CFA79662F6AF493D696A07CCF32AAADCCEFF06E73E8D9F6F909209E\ 66715D6E978788C49EFB9087B170ECF3AA86D2D4D1A065AE0EFC8924F365D676\ B3CB9E2BEC918FD96D0B43DEE83727C9A93BF56CA2B2E59ADBA85696546A8150\ 67FC7A78039629D4948D157E7B0D826D1BF8E81237BAB7321312FDAA4D521744\ F988DB6FDF04549D0FDCA393D639C729AF716E9C8BBA48:\ -1785ABB837E1EFB2EF35D2EE92250985380C702C700660FBCE71F0E962FA67C0\ -C525987A546F5310CE2489D7661229441A7D82BDFAB66D475826A21B95ADEDD8 +870B40EE6B774B732E15DEE647F75BF3D5DD6FD364C7E1BB184D8AC1F0C991E2\ +486DCE6BD6CEFA1DFFE13C50260D4A0FB6C23E29D7E62CFF0F8DE785CA53C2A2 842CC583504539622D7F71E7E31863A2B885C56A0BA62DB4C2A3F2FD12E79660\ DC7205CA29A0DC0A87DB4DC62EE47A41DB36B9DDB3293B9AC4BAAE7DF5C6E720\ 1E17F717AB56E12CAD476BE49608AD2D50309E7D48D2D8DE4FA58AC3CFEAFEEE\ 48C0A9EEC88498E3EFC51F54D300D828DDDCCB9D0B06DD021A29CF5CB5B25069\ 15BEB8A11998B8B886E0F9B7A80E97D91A7D01270F9A7717:\ -C1383A968195C1A6796C5E53DC9756B9DEE39FB7116DCBFE2B5DB9CB9AD6A296\ -77C3F14A156D4D78B3C709DCD49CD247F676CCE0AD693EA208B8433D8C3F7BF6 +8FDE68D448144F3B4BD12011DF94A463C40BE946821F80EC8197E36EB46554F7\ +AD8B6CA9F6FCC8C05B3C0C2C909966AACBA2A1AA6E980E57AEA1CB35B01DC991 6C4B0A0719573E57248661E98FEBE326571F9A1CA813D3638531AE28B4860F23\ C3A3A8AC1C250034A660E2D71E16D3ACC4BF9CE215C6F15B1C0FC7E77D3D2715\ 7E66DA9CEEC9258F8F2BF9E02B4AC93793DD6E29E307EDE3695A0DF63CBDC0FC\ 66FB770813EB149CA2A916911BEE4902C47C7802E69E405FE3C04CEB5522792A\ 5503FA829F707272226621F7C488A7698C0D69AA561BE9F378:\ -44A8B042FC42ABDEB224A4FD7E934148BC86A30E5F2F94E713BFF7FC5BB414F3\ -66CE221316D2F79E5DE124BCC35585447E6B678FA02A5D947323D5C7E614072D +F19E37E56DE97B6EF009CB1B0A8FEB42891DE80A9895C7413367C71FF34815F9\ +77A053FD621C30738C347262DF2B07EC3E455DC729803FA3D68BFBFF42415500 51B7DBB7CE2FFEB427A91CCFE5218FD40F9E0B7E24756D4C47CD55606008BDC2\ 7D16400933906FD9F30EFFDD4880022D081155342AF3FB6CD53672AB7FB5B3A3\ BCBE47BE1FD3A2278CAE8A5FD61C1433F7D350675DD21803746CADCA574130F0\ 1200024C6340AB0CC2CF74F2234669F34E9009EF2EB94823D62B31407F4BA46F\ 1A1EEC41641E84D77727B59E746B8A671BEF936F05BE820759FA:\ -8CD46B15C0F963EA6FF65FD4D3BD6597B3AFBCC7E7DD8C9FD54B93D02286040D\ -7426895B27BB21C9DCE2A99D307388AD54F2B10BC4030A044759A1378A3C5681 +BC3199569054F2DBDC66744F3B6B7DC23D3708BCD96A8C7B7C5D9E58087E2E4A\ +5D5606CEF88AD63044C9A4F0D019358846EE83FE98CFE9C5B03B29A2D31B3134 83599D93F5561E821BD01A472386BC2FF4EFBD4AED60D5821E84AAE74D807102\ 9810F5E286F8F17651CD27DA07B1EB4382F754CD1C95268783AD09220F550284\ 0370D494BEB17124220F6AFCE91EC8A0F55231F9652433E5CE3489B727716CF4\ AEBA7DCDA20CD29AA9A859201253F948DD94395ABA9E3852BD1D60DDA7AE5DC0\ 45B283DA006E1CBAD83CC13292A315DB5553305C628DD091146597:\ -92DDE2B72137F776D310E1D5E85D83CB0BAA12496B21A850FA4A5E75AF17D510\ -D286C494400C999811B7992032D61B32098157085C8363850D4ADE61D4D9D2A9 +C44780E409877812578CF0D738A6394B1EBF7183941323C2891D9604B93E5748\ +EAB2FD4732DCE6D9A5D1F27B7FADFD5DFDC87264BE97F86F700AE87A5D1B8227 2BE9BF526C9D5A75D565DD11EF63B979D068659C7F026C08BEA4AF161D85A462\ D80E45040E91F4165C074C43AC661380311A8CBED59CC8E4C4518E80CD2C78AB\ 1CABF66BFF83EAB3A80148550307310950D034A6286C93A1ECE8929E6385C5E3\ BB6EA8A7C0FB6D6332E320E71CC4EB462A2A62E2BFE08F0CCAD93E61BEDB5DD0\ B786A728AB666F07E0576D189C92BF9FB20DCA49AC2D3956D47385E2:\ -BB878BE3D0F55077194E3B67B2E916324B1637B23AAEC1155E54A3146D7ED2B2\ -ED0D2AC5AEB816291FA89DD5FC11CD07ACDFF5D416F70D433BE262D6AF157C7E +98474C61C2639BA15B58D98429F0E3489504CC6ED3BF638ACCF6859443AF2BCB\ +F85EDBEF50191EDB6923636B21C2E76E985831F187575BA82E9AB4CA40CC482F CA76D3A12595A817682617006848675547D3E8F50C2210F9AF906C0E7CE50B44\ 60186FE70457A9E879E79FD4D1A688C70A347361C847BA0DD6AA52936EAF8E58\ A1BE2F5C1C704E20146D366AEB3853BED9DE9BEFE9569AC8AAEA37A9FB7139A1\ A1A7D5C748605A8DEFB297869EBEDD71D615A5DA23496D11E11ABBB126B206FA\ 0A7797EE7DE117986012D0362DCEF775C2FE145ADA6BDA1CCB326BF644:\ -7F071AA99ABED8FD376C967FFF12CDF9926409131D3945A37F30F427C8C42899\ -2E6F1133F4211EDD38062445F5054D8D642C40E54935DBB937B96250D4A9D801 +F94556B89FA106C94D32F723061D2E88EBC4164B1B02D0485851782F84CC3229\ +7D7A3AF9A1CC430702B78B5BDC9E50ABDD703201AA73F8811AEB4A80A5992C64 F76B85DC67421025D64E93096D1D712B7BAF7FB001716F02D33B2160C2C882C3\ 10EF13A576B1C2D30EF8F78EF8D2F465007109AAD93F74CB9E7D7BEF7C9590E8\ AF3B267C89C15DB238138C45833C98CC4A471A7802723EF4C744A853CF80A0C2\ 568DD4ED58A2C9644806F42104CEE53628E5BDF7B63B0B338E931E31B87C24B1\ 46C6D040605567CEEF5960DF9E022CB469D4C787F4CBA3C544A1AC91F95F:\ -C176D062E50C7329273ED6A485B0A62FE18622E6A783108FAB8FBCBC645C4931\ -FF101A575368FBD65C06FAC22E72AD2FCCADA2AEB066B6649C531C1F74DD96B3 +60440509E00573D66609563D8F1504A196AF06D46F6CDBFEEAFF61FE46AD0845\ +6EE24BCA13DDED11818776CAC19376AE7415338A3D4F0035FF276188BF11420F 25B8C9C032EA6BCD733FFC8718FBB2A503A4EA8F71DEA1176189F694304F0FF6\ 8E862A8197B839957549EF243A5279FC2646BD4C009B6D1EDEBF24738197ABB4\ C992F6B1DC9BA891F570879ACCD5A6B18691A93C7D0A8D38F95B639C1DAEB48C\ 4C2F15CCF5B9D508F8333C32DE78781B41850F261B855C4BEBCC125A380C54D5\ 01C5D3BD07E6B52102116088E53D76583B0161E2A58D0778F091206AABD5A1:\ -D5BF89C144445B9D3455C198D2630C643E4B51F35884EACB0B4F70864B2472B1\ -7AFD66DFBFAFF9482E34BDD6F6BF1EFDED5029EC7E74F80751384762BFC998E8 +2D552519EC54E5BBBFDBB543EAE5482D9B964A952E880A88567E7DDF1DCD0D5A\ +A353F7BE15D7634ADBDBEFA85355839FDA2B738DA987BA568103EABE2CB53D23 21CFDC2A7CCB7F331B3D2EEFFF37E48AD9FA9C788C3F3C200E0173D99963E1CB\ CA93623B264E920394AE48BB4C3A5BB96FFBC8F0E53F30E22956ADABC2765F57\ FB761E147ECBF8567533DB6E50C8A1F894310A94EDF806DD8CA6A0E141C0FA7C\ 9FAE6C6AE65F18C93A8529E6E5B553BF55F25BE2E80A9882BD37F145FECBEB3D\ 447A3C4E46C21524CC55CDD62F521AB92A8BA72B897996C49BB273198B7B1C9E:\ -AB3090870B65CA635BDAC16D1C2F877BDE48C3DE1DA17A88B89E86BE9DD9F4E3\ -A2D116CA899A4C4FE5494689D7BF8C1432276E4216DADB3011ABD058FCC56C70 +AFB37A28A4F216A6CC3D6AED09E82F40B93E445F892040F21D1AABAFE99AF7F0\ +01837CF0AD8DD2E2983282F35ADFB9DCEB49B2C80C85153772A8E587ABE7F18A 4E452BA42127DCC956EF4F8F35DD68CB225FB73B5BC7E1EC5A898BBA2931563E\ 74FAFF3B67314F241EC49F4A7061E3BD0213AE826BAB380F1F14FAAB8B0EFDDD\ @@ -31724,8 +31724,8 @@ A2D116CA899A4C4FE5494689D7BF8C1432276E4216DADB3011ABD058FCC56C70 DD51557CCC80C0A96190BBCC4D77ECFF21C66BDF486459D427F986410F883A80\ A5BCC32C20F0478BB9A97A126FC5F95451E40F292A4614930D054C851ACD019C\ CF:\ -8C311A20F4BB608CE2D697A64C1029B6E000C16EA5D64538715EE0778D93EABA\ -708BAB844DF99EBABAE526639AE4435B74BE87A00128A1D5F227ABADB550B091 +721B1BC60845499B1A50B716F97FA9FD584132C1E30A1705779DBBAE644CBB57\ +51AD1B1B379CC91BA4C3054BD060B88050BABA98BE1864B1B96C3691A096EF21 FA85671DF7DADF99A6FFEE97A3AB9991671F5629195049880497487867A6C446\ B60087FAC9A0F2FCC8E3B24E97E42345B93B5F7D3691829D3F8CCD4BB36411B8\ @@ -31733,8 +31733,8 @@ B60087FAC9A0F2FCC8E3B24E97E42345B93B5F7D3691829D3F8CCD4BB36411B8\ 71EB2B1479A5CEA0B3F8BEFD87ACAF5362435EAECCB52F38617BC6C5C2C6E269\ EAD1FBD69E941D4AD2012DA2C5B21BCFBF98E4A77AB2AF1F3FDA3233F046D38F\ 1DC8:\ -DB71A082A16BC8CE55235901A826E41D15016F26093C474086F2D0D3EE36FFD4\ -EDE1F75DCD811F74A7A64036969D53F20ADA190A2284E891C9F6CE98631EE2BC +EFFFB02598398243D8784EB8ADA33D314C8D396406BB7FB6A668085B23438AB4\ +580BFB5258E5D616F9030C6A8928F4F753D6800C90EA2812482BED268A806E8E E90847AE6797FBC0B6B36D6E588C0A743D725788CA50B6D792352EA8294F5BA6\ 54A15366B8E1B288D84F5178240827975A763BC45C7B0430E8A559DF4488505E\ @@ -31742,8 +31742,8 @@ E90847AE6797FBC0B6B36D6E588C0A743D725788CA50B6D792352EA8294F5BA6\ 2A307D976AA39E41AF6537243FC218DFA6AB4DD817B6A397DF5CA69107A91987\ 99ED248641B63B42CB4C29BFDD7975AC96EDFC274AC562D0474C60347A078CE4\ C25E88:\ -B5219A12D02F6C17257BB2AC9911FBAA84FFA5E4BCD3351CE37D1D3E5E5CB9D1\ -72FD92DCD567C825DC86EB70C4F97ACE90324CDAA760E458C08B80E87A8B9858 +F1CF53FFC952C446EEF49F9D89370757C74CB8F2D99223C47EABD296151161CB\ +86C6A34833E7AC6B75E8119A8274FD2B9066EBB9B787A4A37C9036E6E01BA9CE F6D5C2B6C93954FC627602C00C4CA9A7D3ED12B27173F0B2C9B0E4A5939398A6\ 65E67E69D0B12FB7E4CEB253E8083D1CEB724AC07F009F094E42F2D6F2129489\ @@ -31751,8 +31751,8 @@ E846EAFF0700A8D4453EF453A3EDDC18F408C77A83275617FABC4EA3A2833AA7\ 3406C0E966276079D38E8E38539A70E194CC5513AAA457C699383FD1900B1E72\ BDFB835D1FD321B37BA80549B078A49EA08152869A918CA57F5B54ED71E4FD3A\ C5C06729:\ -DF93616C367AF33B7D33B5F7FBD3332B9AA48FDF102F1D28767449EE4F8C3FC9\ -57BBFD94C7D52D98AEA7C2D5B4A0DC1ACE3DD878BD7F21D307403A3C5A2E57E6 +F1C9A73B10BA528A61AB86F91A9A05261B447049C7ECCF37AB1E0C1219F14F0F\ +0F2C5B419A7595550F2D651A17368C3FB7538A14FF9FFC4C4D9098803D942D3B CF8562B1BED89892D67DDAAF3DEEB28246456E972326DBCDB5CF3FB289ACA01E\ 68DA5D59896E3A6165358B071B304D6AB3D018944BE5049D5E0E2BB819ACF67A\ @@ -31760,8 +31760,8 @@ CF8562B1BED89892D67DDAAF3DEEB28246456E972326DBCDB5CF3FB289ACA01E\ F2D51483F2E209E4589BF9519FAC51B4D061E801125E605F8093BB6997BC163D\ 551596FE4AB7CFAE8FB9A90F6980480CE0C229FD1675409BD788354DAF316240\ CFE0AF93EB:\ -899287D20D7D50E5B95308F1CFD16591DA081D5D1A65FE4EBECA519AF27298C8\ -2D4B9B8CBE92EFA03E3F7E856B20CA6E8CA9FF9388AB8F89A8CD96F2F36E03D3 +5A1A31490BC85FACC5101EE18093BEC7C2CB717A54AFDEE47F98660032D912F2\ +3792F1D0AB0BE8A3C7F0D000DAC238DE843CC84178CBAA910090AC827197AD85 2ACE31ABB0A2E3267944D2F75E1559985DB7354C6E605F18DC8470423FCA30B7\ 331D9B33C4A4326783D1CAAE1B4F07060EFF978E4746BF0C7E30CD61040BD5EC\ @@ -31769,8 +31769,8 @@ CFE0AF93EB:\ ED23719252F7435D64D210EE2AAFC585BE903FA41E1968C50FD5D5367926DF7A\ 05E3A42CF07E656FF92DE73B036CF8B19898C0CB34557C0C12C2D8B84E91181A\ F467BC75A9D1:\ -55B57907035DF0F13C09C2B87425A359281C39B37BE89DC62A7D3A9C91B42160\ -B96AF8C2A6BE6B1FC319970A4EC63A0365467A02D0F23DB67BF03681A0E38F7B +24B5A99041785BC5C5519190B4AAAF92770E35D07213A6DE55EB8811324CC63E\ +3AFCF61F973A896CFB30315873C0071E2BF3BB976A53163422A01192915B9C1E 0D8D09AED19F1013969CE5E7EB92F83A209AE76BE31C754844EA9116CEB39A22\ EBB6003017BBCF26555FA6624185187DB8F0CB3564B8B1C06BF685D47F3286ED\ @@ -31778,8 +31778,8 @@ A20B83358F599D2044BBF0583FAB8D78F854FE0A596183230C5EF8E54426750E\ AF2CC4E29D3BDD037E734D863C2BD9789B4C243096138F7672C232314EFFDFC6\ 513427E2DA76916B5248933BE312EB5DDE4CF70804FB258AC5FB82D58D08177A\ C6F4756017FFF5:\ -98E5DAC81EF43D68526A72206AEC6CB22C7381BEEB09B54761F5F979E0EC9675\ -32512D1864A1F8EABE6AEC3B0809B83217D654C8FF6EB2CA86E3CDF41AD348A1 +7FF6491E79CD3F743C3D735A0AC1BC5EC3395950C65111D7BC2E5E3719AB0FE9\ +20DDA443B1FD8A8D557633B95E68354EF8F78A91A769CF0798871F8B11B77478 C3236B73DEB7662BF3F3DAA58F137B358BA610560EF7455785A9BEFDB035A066\ E90704F929BD9689CEF0CE3BDA5ACF4480BCEB8D09D10B098AD8500D9B6071DF\ @@ -31787,8 +31787,8 @@ C3A14AF6C77511D81E3AA8844986C3BEA6F469F9E02194C92868CD5F51646256\ 798FF0424954C1434BDFED9FACB390B07D342E992936E0F88BFD0E884A0DDB67\ 9D0547CCDEC6384285A45429D115AC7D235A717242021D1DC35641F5F0A48E84\ 45DBA58E6CB2C8EA:\ -113A41F7819CA13ABC6D1E02906C5911006F407822821F32E55D808E51E15BCD\ -EA473E02F01B74F2E7EECBCD90448CC24D2363039E0FA99B769506F19CB38DC4 +0154D5832EC5594FF994034BE3FD3E61E7EEBC8E43C20C6CC9910F15650FBAED\ +2915087AC641DBF60A2083FF14AB084A27B5CC9A4E84C54A6B361D38C72746D5 B39FEB8283EADC63E8184B51DF5AE3FD41AAC8A963BB0BE1CD08AA5867D8D910\ C669221E73243360646F6553D1CA05A84E8DC0DE05B6419EC349CA994480193D\ @@ -31796,8 +31796,8 @@ C669221E73243360646F6553D1CA05A84E8DC0DE05B6419EC349CA994480193D\ 86B58E53A319A57B962331EDE98149AF3DE3118A819DA4D76706A0424B4E1D29\ 10B0ED26AF61D150EBCB46595D4266A0BD7F651BA47D0C7F179CA28545007D92\ E8419D48FDFBD744CE:\ -D3CC7B4F7EF29FB4B1145F18C80D10F9568B7B597BED8C8FCA0D1E2F0A52EAA5\ -746C832AF9402DA8035FFCBB759A1B7078053E0A1148484FA31C0402B829D4B7 +5B617AB6F6FFA82197ED058D4CFDF54398FA3CD95074A745D389C05D8DCE1B9D\ +4B9E88CE4B519017EA3A55EB89D06D2CE321F4801D079D5867EAC366BC270968 A983D54F503803E8C7999F4EDBBE82E9084F422143A932DDDDC47A17B0B7564A\ 7F37A99D0786E99476428D29E29D3C197A72BFAB1342C12A0FC4787FD7017D7A\ @@ -31805,8 +31805,8 @@ A983D54F503803E8C7999F4EDBBE82E9084F422143A932DDDDC47A17B0B7564A\ 1FD3B796F02A1B8264A214C6FEA74B7051B226C722099EC7883A462B83B6AFDD\ 4009248B8A237F605FE5A08FE7D8B45321421EBBA67BD70A0B00DDBF94BAAB7F\ 359D5D1EEA105F28DCFB:\ -9F064FDC60802C9382DA2875A370F3208EB36E192FA958995A586D1F735DBD55\ -E26A656942E5CC2050457E866371594D5928AFAE70F8C10DD31252B965D5FDCA +1D96D1CE0C82A43D4135ED8A022A5F145AB42FDFA024C894939D6FA422EC4F62\ +1A1402113E1105A96273DD4F7884879F63EF41830A1EA0B4516937BBB2DBE44D E4D1C1897A0A866CE564635B74222F9696BF2C7F640DD78D7E2ACA66E1B61C64\ 2BB03EA7536AAE597811E9BF4A7B453EDE31F97B46A5F0EF51A071A2B3918DF1\ @@ -31814,8 +31814,8 @@ E4D1C1897A0A866CE564635B74222F9696BF2C7F640DD78D7E2ACA66E1B61C64\ D5AD3401A318B12FD1474B8612F2BB50FB6A8B9E023A54D7DDE28C43D6D8854C\ 8D9D1155935C199811DBFC87E9E0072E90EB88681CC7529714F8FB8A2C9D8856\ 7ADFB974EE205A9BF7B848:\ -9A04ECD9BB469A9501EBE71B9748128C4726019D76A4A3C1DE6A211902CA9C06\ -7979F2996501449188BE0A75244AB369E032F1D9C73DEA1882CC383DE8084E8F +DE1255FCB5A191E19B663DF4A9DC5471F39F13BE5F8A9CC1C3F6FE2844EB8CF0\ +38E7FF1825D26A8F135AAA77120925ADDB6ACC12EA1BF0E60DFA236FBE38458F B10C59723E3DCADD6D75DF87D0A1580E73133A9B7D00CB95EC19F5547027323B\ E75158B11F80B6E142C6A78531886D9047B08E551E75E6261E79785366D7024B\ @@ -31823,8 +31823,8 @@ D7CD9CF322D9BE7D57FB661069F2481C7BB759CD71B4B36CA2BC2DF6D3A328FA\ EBDB995A9794A8D72155ED551A1F87C80BF6059B43FC764900B18A1C2441F748\ 7743CF84E565F61F8DD2ECE6B6CCC9444049197AAAF53E926FBEE3BFCA8BE588\ EC77F29D211BE89DE18B15F6:\ -F20C6D8BB06FBAEBFA3C2A9DF6E294D2CF64EF359973B438B7FA1192EBF607BC\ -0464CB53154A50291614FD094D9B60BDD27077898130C22CF4316B6176358EE5 +B17A24CA14830ED093C39E8323EC0DFD903172458D023D10FE4125D0EB4AF0E7\ +578B1EA1D5148348AB8D6CAB98B20B18BCC52A6CBA85851D2B74B20735BE6E48 DB11F609BABA7B0CA634926B1DD539C8CBADA24967D7ADD4D9876F77C2D80C0F\ 4DCEFBD7121548373582705CCA2495BD2A43716FE64ED26D059CFB566B3364BD\ @@ -31832,8 +31832,8 @@ DB11F609BABA7B0CA634926B1DD539C8CBADA24967D7ADD4D9876F77C2D80C0F\ 9DCE457738A9D3D8F641AF8C3FD6DA162DC16FC01AAC527A4A0255B4D231C0BE\ 50F44F0DB0B713AF03D968FE7F0F61ED0824C55C4B5265548FEBD6AAD5C5EEDF\ 63EFE793489C39B8FD29D104CE:\ -2BC62B625A06D5F275FB633800AA00DB13AFC03DFBBE4CE287722BE3E7A55041\ -1A8FF84545CCEE032822FF43345C9841D6502914539C78038692628A143212E6 +602B683C28F25E9F20C413D2B357DCDF3E339945C5BD41FCA69FFFD2E1658F9F\ +B654B94B62BEE72087EABEF2F2F6AEDE72C7DC45DD4549CBC75465CC10D4C554 BEBD4F1A84FC8B15E4452A54BD02D69E304B7F32616AADD90537937106AE4E28\ DE9D8AAB02D19BC3E2FDE1D651559E296453E4DBA94370A14DBBB2D1D4E20223\ @@ -31841,8 +31841,8 @@ DE9D8AAB02D19BC3E2FDE1D651559E296453E4DBA94370A14DBBB2D1D4E20223\ C19BCD4BE52DA6258E2EF4E96AA21244429F49EF5CB486D7FF35CAC1BACB7E95\ 711944BCCB2AB34700D42D1EB38B5D536B947348A458EDE3DC6BD6EC547B1B0C\ AE5B257BE36A7124E1060C170FFA:\ -248F4AEC829773B1E7525BD318960310B81316078474525BCEFD1AA71757FDE1\ -3483F9A30B0F53E538635FF9CABA15625F6DAF03478669EE60D054A90CB100DE +E90126404BFED0DCF726CA50A6D0620305D1A84EFB0E768044D2DB920FB041E7\ +DEAA465777D312E2867E6E9E50559BB5ECE3A4ED6F844504C39E12988917FFF5 5ACA56A03A13784BDC3289D9364F79E2A85C12276B49B92DB0ADAA4F206D5028\ F213F678C3510E111F9DC4C1C1F8B6ACB17A6413AA227607C515C62A733817BA\ @@ -31850,8 +31850,8 @@ F213F678C3510E111F9DC4C1C1F8B6ACB17A6413AA227607C515C62A733817BA\ 70A46C44858605FCCBED086C2B45CEF963D33294DBE9706B13AF22F1B7C4CD5A\ 001CFEC251FBA18E722C6E1C4B1166918B4F6F48A98B64B3C07FC86A6B17A6D0\ 480AB79D4E6415B520F1C484D675B1:\ -BA89BFC6C669413652B22BD2EB1E8C520FCE131FB9ADB84470E3163752EA7E6D\ -F663B3631E0629FA90BB05B738BD2BCBC1A83C4AE03E6845860BF027B73CBB20 +D98758D0CBE6C5FEF11A4EDD8E9170FFA7F37F40914B4D836025B3FD71FA2B51\ +8164266D974A40AE2D7C3C359CA675E94B04D08D3EE56346A51B82366F1EF0F0 A5AAD0E4646A32C85CFCAC73F02FC5300F1982FABB2F2179E28303E447854094\ CDFC854310E5C0F60993CEFF54D84D6B46323D930ADB07C17599B35B505F09E7\ @@ -31859,8 +31859,8 @@ CDFC854310E5C0F60993CEFF54D84D6B46323D930ADB07C17599B35B505F09E7\ 920FABDDA086D7537E66D709D050BD14D0C960873F156FAD5B3D3840CDFCDC9B\ E6AF519DB262A27F40896AB25CC39F96984D650611C0D5A3080D5B3A1BF186AB\ D42956588B3B58CD948970D298776060:\ -011124D568ADA8413909D3E0C1BDB23EBF6389A80CC7EF03B9CA1556E70EC67C\ -81DE188C2DC900D4DF8DD7412ECEAAF91EB6495B4BC218B38722099D415D22A5 +7EA57C6B9741AE7C07E11766DC6F69C83A72533126ACAFCA968832FCBC7A28DF\ +18968BB582E6933898672E322235C9D8FA310F485169C55E04672FFDA2A01099 06CBBE67E94A978203EAD6C057A1A5B098478B4B4CBEF5A97E93C8E42F557271\ 3575FC2A884531D7622F8F879387A859A80F10EF02708CD8F7413AB385AFC357\ @@ -31868,8 +31868,8 @@ D42956588B3B58CD948970D298776060:\ 2A9597D10CF12DD2D8CEE46645C7E5A141F6E0E23AA482ABE5661C16E69EF1E2\ 8371E2E236C359BA4E92C25626A7B7FF13F6EA4AE906E1CFE163E91719B1F750\ A96CBDE5FBC953D9E576CD216AFC90323A:\ -8D03C8E3B207C306EB3BB093A4750176F3B458699731A7690FEC874363CF662A\ -2BD27C41FE86E4B410460C1581EC48A9D8F2AFB6C1BB91433AEC5C4147DC3F50 +CEFB46600FC757512E917DFA063BEC761DA6140893D3B7BA01677C6D142CA296\ +0B4B016CCF9C9A175D8E83CC2F1A9D4171D6074E2405B866CDEE57683BD4334F F1C528CF7739874707D4D8AD5B98F7C77169DE0B57188DF233B2DC8A5B31EDA5\ DB4291DD9F68E6BAD37B8D7F6C9C0044B3BF74BBC3D7D1798E138709B0D75E7C\ @@ -31877,8 +31877,8 @@ DB4291DD9F68E6BAD37B8D7F6C9C0044B3BF74BBC3D7D1798E138709B0D75E7C\ 0A162ECCA8C38C1A88350BD63BB539134F700FD4ADDD5959E255337DAA06BC86\ 358FABCBEFDFB5BC889783D843C08AADC6C4F6C36F65F156E851C9A0F917E4A3\ 67B5AD93D874812A1DE6A7B93CD53AD97232:\ -14B3D36C24E80F3B0D7C69F01FCEDE9F109664541ED6E63C75271219BFFAD474\ -F130E984AC82B6B8DDF7F58D7FF93A931CFFEED7991F1FF7E07DEFD7E74F521D +EB861B333F0763CC1F0747ECE23FF46B98962B096CBF95335B6BA9992F291611\ +5887E77A812CE6F78B00530194C71B97ABF4082F31C09F547B025B4388199E75 9D9F3A7ECD51B41F6572FD0D0881E30390DFB780991DAE7DB3B47619134718E6\ F987810E542619DFAA7B505C76B7350C6432D8BF1CFEBDF1069B90A35F0D04CB\ @@ -31886,8 +31886,8 @@ DF130B0DFC7875F4A4E62CDB8E525AADD7CE842520A482AC18F09442D78305FE\ 85A74E39E760A4837482ED2F437DD13B2EC1042AFCF9DECDC3E877E50FF4106A\ D10A525230D11920324A81094DA31DEAB6476AA42F20C84843CFC1C58545EE80\ 352BDD3740DD6A16792AE2D86F11641BB717C2:\ -A2F336A9D8816018E4A1B8968D3BEF6800A3B390488AD2E2E119F18EA2B7522B\ -CF21DF4C5333BBCC5ECB3E9D9E8909DFC1733A417AF9F5B9FC4D8B9AABE7C650 +51CBA976ABC7E8D55F67B1A056B311B861FEE85D2FD69BED53DD274024D87DBD\ +269C41B85F6A1C19FF3D32C444CC7BD8F11478147BBCE99DCBD29E34988EA808 5179888724819FBAD3AFA927D3577796660E6A81C52D98E9303261D5A4A83232\ F6F758934D50AA83FF9E20A5926DFEBAAC49529D006EB923C5AE5048ED544EC4\ @@ -31895,8 +31895,8 @@ F6F758934D50AA83FF9E20A5926DFEBAAC49529D006EB923C5AE5048ED544EC4\ 865AFF8B6B6F2F59CB6D129DA79E97C6D2B8FA6C6DA3F603199D2D1BCAB54768\ 2A81CD6CF65F6551121391D78BCC23B5BD0E922EC6D8BF97C952E84DD28AEF90\ 9ABA31EDB903B28FBFC33B7703CD996215A11238:\ -BED7C99B12478DE47C358637E8977FBC10FD763014196439611D1DE3D6479AED\ -20C5CB3897E70A4B9D428F689835A7E7C99177DD306333D12C5E6B7B88EAF5E4 +10863687D6D1144DCF9D03C10CB66B33E9813EFB9118EEFB947FC68997E6CCF6\ +D93DCD4C2E33A2D187F5E6F5569D291F16B985908F4015599A6214C24AF791B9 576EF3520D30B7A4899B8C0D5E359E45C5189ADD100E43BE429A02FB3DE5FF4F\ 8FD0E79D9663ACCA72CD29C94582B19292A557C5B1315297D168FBB54E9E2ECD\ @@ -31904,8 +31904,8 @@ BED7C99B12478DE47C358637E8977FBC10FD763014196439611D1DE3D6479AED\ 9CAA34224FDD670D335FCB106F5D92C3946F44D3AFCBAE2E41AC554D8E6759F3\ 32B76BE89A0324AA12C5482D1EA3EE89DED4936F3E3C080436F539FA137E74C6\ D3389BDF5A45074C47BC7B20B0948407A66D855E2F:\ -47F5829780E5F634981B4EA095F79CB05395B7FDC3430D4FE0316EDC20B7FCAC\ -81148B900AE95E356F2D194EB69FB6E6786FABC5BF8A6F13F56D881E2A4D6D27 +DE8591FD57ABD6D73CF01C94083F916C897FC0CABC1049BCD75D64C768D3B4C4\ +2F05BA4DEAAB83BB643BA451CC224B0A61110647FA35AC14F63D9C2FEA5231C9 0DF2152FA4F4357C8741529DD77E783925D3D76E95BAFA2B542A2C33F3D1D117\ D159CF473F82310356FEE4C90A9E505E70F8F24859656368BA09381FA245EB6C\ @@ -31913,8 +31913,8 @@ D159CF473F82310356FEE4C90A9E505E70F8F24859656368BA09381FA245EB6C\ 7D0DAB45D67CCCCD3A606CCBEB31EA1FA7005BA07176E60DAB7D78F6810EF086\ F42F08E595F0EC217372B98970CC6321576D92CE38F7C397A403BADA1548D205\ C343AC09DECA86325373C3B76D9F32028FEA8EB32515:\ -477AD92922C418C83FF158D20A806242D41670C1F8FD39315C6651D0D81E49FF\ -27D631892972C88D31FBF448EB135B2FCCA0873B2C37F2DDC0B0E71BAC857E8B +4E529B73E0AFA555B75A7EF2B43F32D71002045F0ABF519C5C1E31F7213AE10B\ +B1474BED81450E9956779216B0DC2D4067B181744D9E66AF3F34306CEFD5FDE8 3E15350D87D6EBB5C8AD99D42515CFE17980933C7A8F6B8BBBF0A63728CEFAAD\ 2052623C0BD5931839112A48633FB3C2004E0749C87A41B26A8B48945539D1FF\ @@ -31922,8 +31922,8 @@ C343AC09DECA86325373C3B76D9F32028FEA8EB32515:\ D7F5FBC7F7A540D5097C096EBC3B3A721541DE073A1CC02F7FB0FB1B9327FB0B\ 1218CA49C9487AB5396622A13AE546C97ABDEF6B56380DDA7012A8384091B665\ 6D0AB272D363CEA78163FF765CDD13AB1738B940D16CAE:\ -24ADD48203FC4772BE68A87FDEFEC3F762DD8945CF421697B70C6612BB19224F\ -EA974E3876FE3F2B745FA53F3A89E569989B735F63A46491E4627AFFD6B6CEFA +CAD6B2E517A3A890D69C8058B427CF4CE48C775B84EC7E47D12C3D2BFD746D3F\ +6DD1814F6721B5DA519A6630E581846F999F727970C67940DFFF70015DAE9053 C38D6B0B757CB552BE40940ECE0009EF3B0B59307C1451686F1A22702922800D\ 58BCE7A636C1727EE547C01B214779E898FC0E560F8AE7F61BEF4D75EAA696B9\ @@ -31931,8 +31931,8 @@ C38D6B0B757CB552BE40940ECE0009EF3B0B59307C1451686F1A22702922800D\ 104A41A505E5EF71E5613DDD2008195F0C574E6BA3FE40099CFA116E5F1A2FA8\ A6DA04BADCB4E2D5D0DE31FDC4800891C45781A0AAC7C907B56D631FCA5CE8B2\ CDE620D11D1777ED9FA603541DE794DDC5758FCD5FAD78C0:\ -8A7340C39AB7450164B915C02B6A6B5EE8361E4BF6EE43E931E3AD7EC3CCA66F\ -20558DF5EEAE5D56E9ABAD9A9F48F8ADC8646D55638993B27EA080226445E7EF +24C90C5D7F0C9471FA119437C8CA847E81D556F66FB6316DD0FB53DD57DFB3BA\ +7D14AC4D1C9C55F04FB6FE2EA9E67178890A3501567059015B7D993256CA1C54 8D2DE3F0B37A6385C90739805B170057F091CD0C7A0BC951540F26A5A75B3E69\ 4631BB64C7635EED316F51318E9D8DE13C70A2ABA04A14836855F35E480528B7\ @@ -31940,8 +31940,8 @@ CDE620D11D1777ED9FA603541DE794DDC5758FCD5FAD78C0:\ B7FC741DACA171431DA99CCE6F7789F129E2AC5CF65B40D703035CD2185BB936\ C82002DAF8CBC27A7A9E554B06196630446A6F0A14BA155ED26D95BD627B7205\ C072D02B60DB0FD7E49EA058C2E0BA202DAFF0DE91E845CF79:\ -C18DA8AC3BD52C9C27AF65DDBB21C7DC87C65E5F6FE23C181CC2D76E6E35E0D6\ -DD8B2CE9C5B707D91459549F08FED2E28891658833818531829932372928FD4B +4BA61EFF8CEC62389A932E24775211189098BDCDFDC6615AE79948914D6361C6\ +BBC45B7DEAFB4A58B78AF4ABFBEB8991EDCF30A2A586BE8C6CECF9875C734D7A C464BBDAD275C50DCD983B65AD1019B9FF85A1E71C807F3204BB2C921DC31FBC\ D8C5FC45868AE9EF85B6C9B83BBA2A5A822201ED68586EC5EC27FB2857A5D1A2\ @@ -31949,8 +31949,8 @@ D09D09115F22DCC39FE61F5E1BA0FF6E8B4ACB4C6DA748BE7F3F0839739394FF\ 7FA8E39F7F7E84A33C3866875C01BCB1263C9405D91908E9E0B50E7459FABB63\ D8C6BBB73D8E3483C099B55BC30FF092FF68B6ADEDFD477D63570C9F5515847F\ 36E24BA0B705557130CEC57EBAD1D0B31A378E91894EE26E3A04:\ -F987CA0943562B86D5CB09CF4BDC06532B4BE5F4B349AFE31B50D1CC052E3638\ -79DBBD78C3D7F642F9A29E5DECB7888806811E9F2115132DABF6720F8EE42368 +1F6CD40F56856615AAFD4103618908530C8EEF746389ADCE64E2CADFFBACB9DA\ +B4E5F973CBB86E607AF00F32948E4CF8BAFD2782653710B38FBF890922773AE5 8B8D68BB8A75732FE272815A68A1C9C5AA31B41DEDC8493E76525D1D013D33CE\ BD9E21A5BB95DB2616976A8C07FCF411F5F6BC6F7E0B57ACA78CC2790A6F9B89\ @@ -31958,8 +31958,8 @@ BD9E21A5BB95DB2616976A8C07FCF411F5F6BC6F7E0B57ACA78CC2790A6F9B89\ BFB9AEEC6AF12AF28E587CAC068A1A2953B59AD680F4C245B2E3EC36F59940D3\ 7E1D3DB38E13EDB29B5C0F404F6FF87F80FC8BE7A225FF22FBB9C8B6B1D7330C\ 57840D24BC75B06B80D30DAD6806544D510AF6C4785E823AC3E0B8:\ -A08812A778848BCC4CCDC27B297C2A39313EF0D2A3E490295C7AECC687163458\ -62768DD92EB7CB7F521AEEE5545A807ACCA74828AD13FF9AB9F7516FA76147FA +2E6D38768361D7BA583A5314947E43FA294E29F87BD7CC2D6F49890912885F90\ +7D8FA6BEF24B4824A4FF777C5FCF04D655FB0F9C2A6C7ADABEC9B92A6698D33E 6B018710446F368E7421F1BC0CCF562D9C1843846BC8D98D1C9BF7D9D6FCB48B\ FC3BF83B36D44C4FA93430AF75CD190BDE36A7F92F867F58A803900DF8018150\ @@ -31967,8 +31967,8 @@ FC3BF83B36D44C4FA93430AF75CD190BDE36A7F92F867F58A803900DF8018150\ B6E7A1BFD5CC4DCF24E4D52E92BD4455848E4928B0EAC8B7476FE3CC03E862AA\ 4DFF4470DBFED6DE48E410F25096487ECFC32A27277F3F5023B2725ADE461B13\ 55889554A8836C9CF53BD767F5737D55184EEA1AB3F53EDD0976C485:\ -241EF5BC35C9FD842699C4BA03AFB4FED737CDBDE73B12CE0F7D118C92139C29\ -E9126AA81E3E06102BC3009043F0BEA6AE2E48C2D5D93A467991397F5E99D8FD +EB395350C2557F16601D19DC75031348103F059A0FB890CC2A002932E0619CE8\ +E52F0F39688DF0DB724CB095B69A5643154C9336FBBA50F35C6A4C05477737EC C9534A24714BD4BE37C88A3DA1082EDA7CABD154C309D7BD670DCCD95AA53559\ 4463058A29F79031D6ECAA9F675D1211E9359BE82669A79C855EA8D89DD38C2C\ @@ -31976,8 +31976,8 @@ C9534A24714BD4BE37C88A3DA1082EDA7CABD154C309D7BD670DCCD95AA53559\ D7CE0E2106F0C8B0ABF4715E2CA48EF9F454DC203C96656653B727083513F8EF\ B86E49C513BB758B3B052FE21F1C05BB33C37129D6CC81F1AEF6ADC45B0E8827\ A830FE545CF57D0955802C117D23CCB55EA28F95C0D8C2F9C5A242B33F:\ -7F013A499D91DAD964C5D32F428EE352EBACD1B900F09186CA769A3B1C370D4F\ -CAC310C5F217DA581AC7B0202AE038AAE7E3F0CB484605C7F54CEE4FD3C3A272 +01449772284E566C1E31A6924A2D9157BDCDD694B5ED1039370BBB11F58851FE\ +5677B25276EC84FDD8472426735C532BCA3D59ACB6FDCE13C0DEA9376DDA8AAE 07906C87297B867ABF4576E9F3CC7F82F22B154AFCBF293B9319F1B0584DA6A4\ 0C27B32E0B1B7F412C4F1B82480E70A9235B12EC27090A5A33175A2BB28D8ADC\ @@ -31985,8 +31985,8 @@ CAC310C5F217DA581AC7B0202AE038AAE7E3F0CB484605C7F54CEE4FD3C3A272 F6F672624FCEA8D1A9F85170FAD30FA0BBD25035C3B41A6175D467998BD1215F\ 6F3866F53847F9CF68EF3E2FBB54BC994DE2302B829C5EEA68EC441FCBAFD7D1\ 6AE4FE9FFF98BF00E5BC2AD54DD91FF9FDA4DD77B6C754A91955D1FBAAD0:\ -F9B6C3E55260AD9459E78CBF77EF9F46EE94658BEA13F31C34A1548355A4A301\ -7E11BFB20427F4A98B9ABFFB80C168FDCE3B58513D4E05B005B10B1CD41D1DAF +5E4DE3451E6BF67CEC13F960D86FA9035B1AA4A824F0AFF446271D39784A0E73\ +5FDD00AE53D6347DDFEC4EC6A552AD78AF145BBA1CD4C34C300E3AAEEF88838E 588E94B9054ABC2189DF69B8BA34341B77CDD528E7860E5DEFCAA79B0C9A452A\ D4B82AA306BE84536EB7CEDCBE058D7B84A6AEF826B028B8A0271B69AC3605A9\ @@ -31994,8 +31994,8 @@ D4B82AA306BE84536EB7CEDCBE058D7B84A6AEF826B028B8A0271B69AC3605A9\ 822E956CD16433B02C68C4A23252C3F9E151A416B4963257B783E038F6B4D5C9\ F110F871652C7A649A7BCEDCBCCC6F2D0725BB903CC196BA76C76AA9F10A190B\ 1D1168993BAA9FFC96A1655216773458BEC72B0E39C9F2C121378FEAB4E76A:\ -41CAAC4E9A2258FE986991DE2FBDD35B0A44BFCD7E7AFB5826ABFD98407143B1\ -2661C4C5CC326A6A5002D4175B8CCC96CCFACA175671D67673E0E7A9B3A2EE43 +814E7B36373B0276718212ABA4E0D9760E433B680FC59869533E4F1D34010047\ +977C91FA33C0C6DFC2F6A4DADCE34BC897A3F7E2CA9935B99D8E5425AB46060D 08959A7E4BAAE874928813364071194E2939772F20DB7C3157078987C557C2A6\ D5ABE68D520EEF3DC491692E1E21BCD880ADEBF63BB4213B50897FA005256ED4\ @@ -32003,8 +32003,8 @@ D5ABE68D520EEF3DC491692E1E21BCD880ADEBF63BB4213B50897FA005256ED4\ 698712E963715983FD07641AE4B4E9DC73203FAC1AE11FA1F8C7941FCC82EAB2\ 47ADDB56E2638447E9D609E610B60CE086656AAEBF1DA3C8A231D7D94E2FD0AF\ E46B391FF14A72EAEB3F44AD4DF85866DEF43D4781A0B3578BC996C87970B132:\ -95B7B94203B6625E36BDF04A3F40E79209D5A8BF5B27C836068EB3E944F76FF7\ -6AC5086D1AA510F8CB560360E02FDE47C324DFA6412E31923BECF5B9A5CE74F7 +9B28504942E11B4FE971337FBB905DD772EF9D4982AC4D5EC7C3EFCEBBD1F32D\ +6BC7EDCE173A75DE81C5651A3D1DD22A5D63A2763986356331F18BD02D77B036 CB2A234F45E2ECD5863895A451D389A369AAB99CFEF0D5C9FFCA1E6E63F763B5\ C14FB9B478313C8E8C0EFEB3AC9500CF5FD93791B789E67EAC12FD038E2547CC\ @@ -32013,8 +32013,8 @@ DB5B545B159E1FF1DCA6EB734B872343B842C57EAFCFDA8405EEDBB48EF32E99\ 696D135979235C3A05364E371C2D76F1902F1D83146DF9495C0A6C57D7BF9EE7\ 7E80F9787AEE27BE1FE126CDC9EF893A4A7DCBBC367E40FE4E1EE90B42EA25AF\ 01:\ -9C212622F625449B5F09544816DE7792F99FDAE01405EB667210A8566E4A48FF\ -7948F1A8DA07CDB8ABE38660CA4D5D6E87B4D078493DA1A22574ECEA221E4FAA +563AAB317672C0DAFC3578FD23DD1416A577D76099B850801C82B03A7FD9037D\ +DC84E7960817B893C2AA5444C46CC5ACED01821E0A299A8BFC13860B6DE3A0C2 D16BEADF02AB1D4DC6F88B8C4554C51E866DF830B89C06E786A5F8757E890931\ 0AF51C840EFE8D20B35331F4355D80F73295974653DDD620CDDE4730FB6C8D0D\ @@ -32023,8 +32023,8 @@ CD230AC5268AB4606FCCBA9EDED0A2B5D014EE0C34F0B2881AC036E24E151BE8\ 9EEB6CD9A7A790AFCCFF234D7CB11B99EBF58CD0C589F20BDAC4F9F0E28F75E3\ E04E5B3DEBCE607A496D848D67FA7B49132C71B878FD5557E082A18ECA1FBDA9\ 4D4B:\ -04EC35E912AF0ACB1914785EE00506E96D633E81ED6AD7B971CD0434EE61CCE6\ -F6FF3DC1BD1B1282E9A2A9D25D5480D4C6C47681212B24CDE68A632A0294ADEA +7365A562E0A02312B2B26D583CA242C479A96F50827B4E87B4E7D4F4B4174C39\ +A76E843FB1D3D2F3731B06161A02BA5E64860D916E607BB5954765B34F57072C 8F65F6BC59A85705016E2BAE7FE57980DE3127E5AB275F573D334F73F8603106\ EC3553016608EF2DD6E69B24BE0B7113BF6A760BA6E9CE1C48F9E186012CF96A\ @@ -32033,8 +32033,8 @@ EC3553016608EF2DD6E69B24BE0B7113BF6A760BA6E9CE1C48F9E186012CF96A\ 299884DBEC3199BB05ADC94E955A1533219C1115FED0E5F21228B071F40DD57C\ 4240D98D37B73E412FE0FA4703120D7C0C67972ED233E5DEB300A22605472FA3\ A3BA86:\ -177D4D8DAD1C6C05147B8D4FD8713E988CEF19B417810387B68B90DA075CDDDF\ -08C927328A69F4D21CD6E6CFF1B446F2980261BE7842ED07B7609D5FA23A13B9 +8B9F0CD8D4D56DCB17BB67DB05580A6B67296D4CA8297CA8A705ED9C9948EA9B\ +1DE211D205DF7836DA88C2CEA2ADDA29124E9DD9D5A95AA7E300BFC52E8931DB 84891E52E0D451813210C3FD635B39A03A6B7A7317B221A7ABC270DFA946C426\ 69AACBBBDF801E1584F330E28C729847EA14152BD637B3D0F2B38B4BD5BF9C79\ @@ -32043,8 +32043,8 @@ A3BA86:\ B784AAABA4E534A6DFD1DF6FA15511341E725ED2E87F98737CCB7B6A6DFAE416\ 477472B046BF1811187D151BFA9F7B2BF9ACDB23A3BE507CDF14CFDF517D2CB5\ FB9E4AB6:\ -D109E4EA58F1E95BB67D4B4C33C23DCD91E8E659CCD2F71D63D63EF62445A4A0\ -029AF5F9B40280D8BD461DE3AAC765A8894568853B0E2146E407E1B31E5F7511 +34C0FFBFE39B0ABD5B261D66499A8508F360B0D61296DB24E2496C2EDEBE80C2\ +642C12976FA54EF41A766F6722393D7B154AA0BC5C4E20A2CE0527F9A16C3AAC FDD7A9433A3B4AFABD7A3A5E3457E56DEBF78E84B7A0B0CA0E8C6D53BD0C2DAE\ 31B2700C6128334F43981BE3B213B1D7A118D59C7E6B6493A86F866A1635C128\ @@ -32053,8 +32053,8 @@ A2B1D72165A855BACD8FAF8034A5DD9B716F47A0818C09BB6BAF22AA503C06B4\ CA261F557761989D2AFBD88B6A678AD128AF68672107D0F1FC73C5CA74045929\ 7B3292B281E93BCEB761BDE7221C3A55708E5EC84472CDDCAA84ECF23723CC09\ 91355C6280:\ -8973998BEF6F4971835BF108EC3A815AE1120557F39BA502979E963FC811D356\ -67B4614A09ADE41F9086166B614ACE97821EFB3E27F956E33FC1152905481E0A +2EB1C4BD6D8E41981756A7F83A41D5DF0FC770707AFE22DADEE6BF92DF54096F\ +C4AEB6E0114AC3CBB33BD8D6A47260BAF4127CDE97371979B21E8E32EA205265 70A40BFBEF92277A1AAD72F6B79D0177197C4EBD432668CFEC05D099ACCB6510\ 62B5DFF156C0B27336687A94B26679CFDD9DAF7AD204338DD9C4D14114033A5C\ @@ -32063,8 +32063,8 @@ A64859DF4B86E9EE0B58E39091E6B188B408AC94E1294A8911245EE361E60E60\ 1EFF58D1D37639F3753BEC80EBB4EFDE25817436076623FC65415FE51D1B0280\ 366D12C554D86743F3C3B6572E400361A60726131441BA493A83FBE9AFDA90F7\ AF1AE717238D:\ -537817B86EFAD56797435E4F81BF20791C52506554B550A14FEED4B8DE53A871\ -BB35D275D2C144B6A4F5626A8AEE56B6975F8B6D621C520E6DB30F710DEB7B73 +18485311BE9C848C38BFA25EC4C557196F1E39A4AC812B77AD2975182A9C2768\ +706905562B0722A2A1B92A56EB47E2500EC1621F59B6B0059EE6FF8C2DB29326 74356E449F4BF8644F77B14F4D67CB6BD9C1F5AE357621D5B8147E562B65C665\ 85CAF2E491B48529A01A34D226D436959153815380D5689E30B35357CDAC6E08\ @@ -32073,8 +32073,8 @@ C280C43D7D64A5268FA719074960087B3A6ABC837882F882C837834535929389\ A12B2C78187E2EA07EF8B8EEF27DC85002C3AE35F1A50BEE6A1C48BA7E175F33\ 16670B27983472AA6A61EED0A683A39EE323080620EA44A9F74411AE5CE99030\ 528F9AB49C79F2:\ -EB0B4CBCC5B846BF9342D74E6D555D7768A049F1CD4D98055BC3328C08477DA8\ -7CC9017215766F83CBF8E7C74204643F38741931672E178ECB6C33C6F97BD8A9 +753B20F511FD288F732ADE82C0F97D7A05DC4E6B931F7D1D0F266911A3C7DDBA\ +5DB2BB233A12D9508DC071E760844F376AC74CDACC5C8321DB2E6DDA9EF2F9D1 8C3798E51BC68482D7337D3ABB75DC9FFE860714A9AD73551E120059860DDE24\ AB87327222B64CF774415A70F724CDF270DE3FE47DDA07B61C9EF2A3551F45A5\ @@ -32083,8 +32083,8 @@ AB87327222B64CF774415A70F724CDF270DE3FE47DDA07B61C9EF2A3551F45A5\ 4F346A5E8DD851C2857995DDBF5B2D717AEB847310E1F6A46AC3D26A7F9B4498\ 5AF656D2B7C9406E8A9E8F47DCB4EF6B83CAACF9AEFB6118BFCFF7E44BEF6937\ EBDDC89186839B77:\ -75EDFA49C1995B191F5EE4689580A6C4A5AB9637C257AED28E8D9C0002EAB048\ -6E1AAA86FF81C8095EB21A7A04EAF33C8E637E771DB4EE970567870F0E0FFC00 +E4ECE8FA8A82C0C44328A5B11C0C0EAB3B165A919555B8ECD121A828B0892E16\ +86EF62EAAD10C87B41BCCD85E60F37AEAE96503FBCE970D895E1E1E551CE1A85 FA56BF730C4F8395875189C10C4FB251605757A8FECC31F9737E3C2503B02608\ E6731E85D7A38393C67DE516B85304824BFB135E33BF22B3A23B913BF6ACD2B7\ @@ -32093,8 +32093,8 @@ CB81CE3555D4F0AD466DD4C108A90399D70041997C3B25345A9653F3C9A6711A\ B1B91D6A9D2216442DA2C973CBD685EE7643BFD77327A2F7AE9CB283620A0871\ 6DFB462E5C1D65432CA9D56A90E811443CD1ECB8F0DE179C9CB48BA4F6FEC360\ C66F252F6E64EDC96B:\ -689A1EE00FAA07E5CF96DA422ABE07962C42222B6B9928B761CFE7BA61762FE1\ -BE30267AD53B483E503B1EF21017C083DF32692C5D0CD65979B416F231A1F654 +0C2A1D85CB308CEA8D84108224FC6DA66A2654496A14CAB4457B672EF9BD2D25\ +F0D14098334846F0187D01D74CF8B18C22B3CF9E00ED31F1BE30E960E3C26AF1 B6134F9C3E91DD8000740D009DD806240811D51AB1546A974BCB18D344642BAA\ 5CD5903AF84D58EC5BA17301D5EC0F10CCD0509CBB3FD3FFF9172D193AF0F782\ @@ -32103,8 +32103,8 @@ FFE2B5F18A87831CFB7095F58A87C9FA21DB72BA269379B2DC2384B3DA953C79\ 25761FED324620ACEA435E52B424A7723F6A2357374157A34CD8252351C25A1B\ 232826CEFE1BD3E70FFC15A31E7C0598219D7F00436294D11891B82497BC78AA\ 5363892A2495DF8C1EEF:\ -23A1FFD72251693480A286725193A64A83F11367DFB38F039F117FF7351934C9\ -009C83DB46BA13EE7C8CE2045C1F6E418963CDCD8FD051B8A71ADBC6481ECEAE +46C390535747C9C16A4797C28DDEE9C2CECC3B8F1A89EE67C91A0D06220E6633\ +9E7B4A7D6C6B2B27D0A011D51BF7EA0DD61E6124D329269BCD4B92273C2A311D C941CDB9C28AB0A791F2E5C8E8BB52850626AA89205BEC3A7E22682313D198B1\ FA33FC7295381354858758AE6C8EC6FAC3245C6E454D16FA2F51C4166FAB51DF\ @@ -32113,8 +32113,8 @@ FA33FC7295381354858758AE6C8EC6FAC3245C6E454D16FA2F51C4166FAB51DF\ 49393CDCFF6151B50B377D609559923D0984CDA6000829B916AB6896693EF6A2\ 199B3C22F7DC5500A15B8258420E314C222BC000BC4E5413E6DD82C993F8330F\ 5C6D1BE4BC79F08A1A0A46:\ -3B8BF1BF8A10E06238CCF7CD7EF2694F942EF6C720381CDE80E0396F4560BB1B\ -B40FB6C3BF6CC08DF574C3EEEC1BEF8F27A1F9D33BA7344F502BCA40E7321636 +6C7060DBE2F17BAE9F4503FA61FCB2B3C6F9F8E1710FD2092CAB5865E05C6E3A\ +9A5D2E5A94E4C9DAFB9F3E47E52A6644990D8F397C93DAD4546A7C1C35BE8CA7 4499EFFFAC4BCEA52747EFD1E4F20B73E48758BE915C88A1FFE5299B0B005837\ A46B2F20A9CB3C6E64A9E3C564A27C0F1C6AD1960373036EC5BFE1A8FC6A435C\ @@ -32123,8 +32123,8 @@ A46B2F20A9CB3C6E64A9E3C564A27C0F1C6AD1960373036EC5BFE1A8FC6A435C\ C402682B6824821F998C32163164298E1FAFD31BABBCFFB594C91888C6219079\ D907FDB438ED89529D6D96212FD55ABE20399DBEFD342248507436931CDEAD49\ 6EB6E4A80358ACC78647D043:\ -25318513F5A4FFDF6CCB164F9A01286656B4F3F2F47CCCFCC9EBA895AB98C2BE\ -5EBE30BDD7573B471D3B952318BCD8D6D3BF8BD5427ABA6F039F7EB5031D3876 +A614F68BE815612E5E571B06DC69C3C86A8A4EFF9BBA9A981413F60C7B612B90\ +6A7805BE3E292F1154CB0E1B003B86F40B23B99C579DA381D06C734E60A49806 EECBB8FDFA4DA62170FD06727F697D81F83F601FF61E478105D3CB7502F2C89B\ F3E8F56EDD469D049807A38882A7EEFBC85FC9A950952E9FA84B8AFEBD3CE782\ @@ -32133,8 +32133,8 @@ D4DA598002827B1EB98882EA1F0A8F7AA9CE013A6E9BC462FB66C8D4A18DA214\ E77E6E5F34139A5A41131FD1D6336C272A8FC37080F041C71341BEE6AB550CB4\ A20A6DDB6A8E0299F2B14BC730C54B8B1C1C487B494BDCCFD3A53535AB2F2315\ 90BF2C4062FD2AD58F906A2D0D:\ -093591FBF29F8D4D493F2F8890D2BA59A17C4D31F8D42288859365AF1B74E0CA\ -D8274493BFB2E0A0656EB09B447721E577BBBBB92E97A8CC32E6EEDDCDADAD58 +402CC283CF76060F64F0DE59D14910D710221F63537D5E30A1388496CC2260DE\ +1E3BCACE354FC1AB344458DD9BEDF3FC36336D67B10EF21FC6D6F48ACD265C8D E64F3E4ACE5C8418D65FEC2BC5D2A303DD458034736E3B0DF719098BE7A206DE\ AF52D6BA82316CAF330EF852375188CDE2B39CC94AA449578A7E2A8E3F5A9D68\ @@ -32143,8 +32143,8 @@ EF58FB0AFA92CC539F8C76D3D097E7A6A63EBB9B5887EDF3CF076028C5BBD5B9\ DB3211371AD3FE121D4E9BF44229F4E1ECF5A0F9F0EBA4D5CEB72878AB22C3F0\ EB5A625323AC66F7061F4A81FAC834471E0C59553F108475FE290D43E6A055AE\ 3EE46FB67422F814A68C4BE3E8C9:\ -2F911D4C83F7304E72E22E4412932D949654CC446EA5104F9BFA2AC82447B668\ -3097AA3E5E04615F1A1EF2A652CC2FCCAF1663B35ED33A711E37D14E520A2595 +AEF42FDB10807FDAEA631638A64C06A9125CDB7F94BB91AB345E1EA30E606FC5\ +FBC6322075A50FE2D13D19FD34AB072C41B96CED205CC5143A1A5C98DEA311D0 D2CB2D733033F9E91395312808383CC4F0CA974E87EC68400D52E96B3FA6984A\ C58D9AD0938DDE5A973008D818C49607D9DE2284E7618F1B8AED8372FBD52ED5\ @@ -32153,8 +32153,8 @@ C58D9AD0938DDE5A973008D818C49607D9DE2284E7618F1B8AED8372FBD52ED5\ 806C4D137B6316B50ABC9CCE0DFF3ACADA47BBB86BE777E617BBE578FF451984\ 4DB360E0A96C6701290E76BB95D26F0F804C8A4F2717EAC4E7DE9F2CFF3BBC55\ A17E776C0D02856032A6CD10AD2838:\ -E1F645AB256B807E20C728F60F8594123359322355D32A42A559F0F7FDF873D2\ -15806C3E9375B70469FB0696246E396239DC0286815EB423026951A2CDA7AE0B +391C3A33EC4B5D75C910DF0F00F6AD5D4E8844CDB364B2D7B0155BDD4F9C0E1B\ +6C7825938F642840D06CD0E6F67F87DCCC34F6FD83587FD9266D603CA625548F F2998955613DD414CC111DF5CE30A995BB792E260B0E37A5B1D942FE90171A4A\ C2F66D4928D7AD377F4D0554CBF4C523D21F6E5F379D6F4B028CDCB9B1758D3B\ @@ -32163,8 +32163,8 @@ C2F66D4928D7AD377F4D0554CBF4C523D21F6E5F379D6F4B028CDCB9B1758D3B\ 4AF8F312B3B2A577750E3EFBD370E8A8CAC1582581971FBA3BA4BD0D76E718DA\ CF8433D33A59D287F8CC92234E7A271041B526E389EFB0E40B6A18B3AAF658E8\ 2ED1C78631FD23B4C3EB27C3FAEC8685:\ -7661221986EC665F0DE59D89DFE577A1489F1B92DAAF0D4AD3BCFE0F9551FB3F\ -F85AC4971B91787D06D0640941E303C054840AB3FE1EC8B2F2EFD650A11AD785 +E51079072C571D0E44C975F232F052F78B497A1C85995E194691A85AB026E4F8\ +0A4993D3A2B4D69F607558CEFF54D766915E5A4E0C7A42C8D307FA03C6DC4C74 447797E2899B72A356BA55BF4DF3ACCA6CDB1041EB477BD1834A9F9ACBC340A2\ 94D729F2F97DF3A610BE0FF15EDB9C6D5DB41644B9874360140FC64F52AA03F0\ @@ -32173,8 +32173,8 @@ D1EFD77FC853B818545D055ADC9284796E583C76E6FE74C9AC2587AA46AA8F88\ 04F2FEB5836CC4B3ABABAB8429A5783E17D5999F32242EB59EF30CD7ADABC16D\ 72DBDB097623047C98989F88D14EAF02A7212BE16EC2D07981AAA99949DDF89E\ CD90333A77BC4E1988A82ABF7C7CAF3291:\ -62E8BC85C0BE0C756C0B8246D251D54B2680CC4C5F38B3748AB10C0DEED191A4\ -EFEB55A02A7177EFC1285801502758B2A865851F746347876DC20994911D2F0D +019BE27AC6E4B1FB3F1602025A8DE3EFA7AD6E1D0C6975E8D2D519A997328154\ +FE0738A00366205FDF8467B36D8970A92EF450C20F5BEC013BA4CF8091F571CB 9F2C18ADE9B380C784E170FB763E9AA205F64303067EB1BCEA93DF5DAC4BF5A2\ E00B78195F808DF24FC76E26CB7BE31DC35F0844CDED1567BBA29858CFFC97FB\ @@ -32183,8 +32183,8 @@ ABB3C20D32743F4026B59A4CCC385A2301F83C0B0A190B0F2D01ACB8F0D41111\ E10F2F4E149379275599A52DC089B35FDD5234B0CFB7B6D8AEBD563CA1FA653C\ 5C021DFD6F5920E6F18BFAFDBECBF0AB00281333ED50B9A999549C1C8F8C63D7\ 626C48322E9791D5FF72294049BDE91E73F8:\ -EDB827225836DACAA2BAF1ACF153396E786722C78A67C8160B26C95068EA6FB0\ -2A95F3FAF9A2A25B4225C7347101C322A9F89059E11A01DAAD438BF9B47659A7 +B996713F0A3AB5F0198C127B5C3079DACE7D4D98A9433D9B790833B62395A379\ +7B7924EB8B9F586903079A8413597E37448F3222B751DEBE8A5B83385864F7B8 AE159F3FA33619002AE6BCCE8CBBDD7D28E5ED9D61534595C4C9F43C402A9BB3\ 1F3B301CBFD4A43CE4C24CD5C9849CC6259ECA90E2A79E01FFBAC07BA0E147FA\ @@ -32193,8 +32193,8 @@ A6DEADCB55363D233C24440F2C73DBB519F7C9FA5A8962EFD5F6252C0407F190\ DFEFAD707F3C7007D69FF36B8489A5B6B7C557E79DD4F50C06511F599F56C896\ B35C917B63BA35C6FF8092BAF7D1658E77FC95D8A6A43EEB4C01F33F03877F92\ 774BE89C1114DD531C011E53A34DC248A2F0E6:\ -60EE213745C9CB94BC472F96E1BF9EF79C26BA3CEC017CC50A56DAE4E7C882D2\ -8E6425CC1DF5FEF68441AB13286E0407FA36C3280ED1E5ADDA4E33EE03F3D471 +FB71A3351EA2FD4C44E271EA793596B245C6F0634E79ED1EC72C6A4CC9DBC892\ +A9498A7ACA0915AB20B0DAED223FAD794A6F3822C847CF52B3F217D0BC605B76 3B8E97C5FFC2D6A40FA7DE7FCEFC90F3B12C940E7AB415321E29EE692DFAC799\ B009C99DCDDB708FCE5A178C5C35EE2B8617143EDC4C40B4D313661F49ABDD93\ @@ -32203,8 +32203,8 @@ CEA79D117518805496FE6ACF292C4C2A1F76B403A97D7C399DAF85B46AD84E16\ 47482B72E0B394EAB76916126FD68EA7D65EB93D59F5B4C5AC40F7C3B37E7F36\ 94F29424C24AF8C8F0EF59CD9DBF1D28E0E10F799A6F78CAD1D45B9DB3D7DEE4\ A7059ABE99182714983B9C9D44D7F5643596D4F3:\ -FC1110441C703610FCF45C284C7232FC39E97D1EE83D44B4DC6D3EB0C3634184\ -804710E64CBEF1F6BEF193A6B903565C48AAEADB2B9EE9A66F370FF7D8A0621B +DBD3650B1739E8DA775381B5521C5CFDD689FE81309B3A69A4B3BCDC62DD6C45\ +68B84670E5E3B1B4E0E834600C36167E3447C5C1009E680C7932DB2BD91057A9 3434EC31B10FAFDBFEEC0DD6BD94E80F7BA9DCA19EF075F7EB017512AF66D6A4\ BCF7D16BA0819A1892A6372F9B35BCC7CA8155EE19E8428BC22D214856ED5FA9\ @@ -32213,8 +32213,8 @@ BCF7D16BA0819A1892A6372F9B35BCC7CA8155EE19E8428BC22D214856ED5FA9\ 63D9279560AAA38EB2DC14A212D723F994A1FE656FF4DD14551CE4E7C621B2AA\ 5604A10001B2878A897A28A08095C325E10A26D2FB1A75BFD64C250309BB55A4\ 4F23BBAC0D5516A1C687D3B41EF2FBBF9CC56D4739:\ -7AE06EEE293E04B371C06AAFF35F04549D87D36E8CF2B568EE3905B9EC11BCD6\ -EC62E2483BBCE0079AA9432FCAE99D67947ACCD4FFAA0DB1025392F1104E049A +55B84F2AC0B917467F20E9EC5F6CE98B3987C59A1ACAEFE3AD73D1C26D724CA0\ +C4D8052CE82E3C704C7834499BEC67620D4B073BF3DA41AAD2DE69AFA4943E3B 7C7953D81C8D208FD1C97681D48F49DD003456DE60475B84070EF4847C333B74\ 575B1FC8D2A186964485A3B8634FEAA3595AAA1A2F4595A7D6B6153563DEE31B\ @@ -32223,8 +32223,8 @@ E14B970668BE174C89DF2FEA43AE52F13142639C884FD62A3683C0C3792F0F24\ AB1318BCB27E21F4737FAB62C77EA38BC8FD1CF41F7DAB64C13FEBE7152BF5BB\ 7AB5A78F5346D43CC741CB6F72B7B8980F268B68BF62ABDFB1577A52438FE14B\ 591498CC95F071228460C7C5D5CEB4A7BDE588E7F21C:\ -91365C03B561AC61FDAE98ED1376AB5587AC1FF722155A873790B5165EF955BD\ -460434A838B15288B0B5EFC3D0CD0D8EDA5D6E09F87D731C873D22F35EAA392A +AD4231D8A6C04C1517D1091D399110019055D5C5EE1D3D75456DA17C5572C10B\ +B8B808493C3A69EBD668AFFD15A9E92A692A3C7A394F929B1E7798E692979665 7A6A4F4FDC59A1D223381AE5AF498D74B7252ECF59E389E49130C7EAEE626E7B\ D9897EFFD92017F4CCDE66B0440462CDEDFD352D8153E6A4C8D7A0812F701CC7\ @@ -32233,8 +32233,8 @@ D9897EFFD92017F4CCDE66B0440462CDEDFD352D8153E6A4C8D7A0812F701CC7\ A7A8E155F81F712D8E9FE646153D3D22C811BD39F830433B2213DD46301941B5\ 9293FD0A33E2B63ADBD95239BC01315C46FDB678875B3C81E053A40F581CFBEC\ 24A1404B1671A1B88A6D06120229518FB13A74CA0AC5AE:\ -0B5816F638F9A1BB84B3CC174AC45D6A04015095906E399075099149429194A8\ -6E0E8BC6A8D699249EAB9D8A89A87C553D474F003C1222C721E295D1C1ACA5F0 +70CDAED98ECA25B7099C73201427DE23F51D7115160A105DED7A2FB6B20F2DEB\ +31B6A2734CFFC2AA6189DAEA538291B34D0AAC7CA9C57CA7063A31EF202F38EC D9FAA14CEBE9B7DE551B6C0765409A33938562013B5E8E0E1E0A6418DF7399D0\ A6A771FB81C3CA9BD3BB8E2951B0BC792525A294EBD1083688806FE5E7F1E17F\ @@ -32243,8 +32243,8 @@ D4E3A41D00C89E8FCF4A363CAEDB1ACB558E3D562F1302B3D83BB886ED27B760\ CA0F35B3A5312146806B4C0275BCD0AAA3B2017F346975DB566F9B4D137F4EE1\ 0644C2A2DA66DEECA5342E236495C3C6280528BFD32E90AF4CD9BB908F34012B\ 52B4BC56D48CC8A6B59BAB014988EABD12E1A0A1C2E170E7:\ -0A6F1F2ECA200D2191A4FA74AF69CD369A55574D96ECFB2EEAF6B51714925D5E\ -789B6926601776BF2F5F38D7189BF02ADB8E7F1BFD55B7D0E6188E9B6A81C01A +45186098139174A1D4D657A79B71E6E4FB3AE790A52FF0A1690D787FCB6FBA70\ +25CF74E3CDBFAA5B2B6D1880699315FAC59FB18714C65D5EA66E6B1D47AE17C4 2D8427433D0C61F2D96CFE80CF1E932265A191365C3B61AAA3D6DCC039F6BA2A\ D52A6A8CC30FC10F705E6B7705105977FA496C1C708A277A124304F1FC40911E\ @@ -32253,8 +32253,8 @@ D52A6A8CC30FC10F705E6B7705105977FA496C1C708A277A124304F1FC40911E\ AFA8AE40C5DF29966F9346DA5F8B35F16A1DE3AB6DE0F477D8D8660918060E88\ B9B9E9CA6A4207033B87A812DBF5544D39E4882010F82B6CE005F8E8FF6FE3C3\ 806BC2B73C2B83AFB704345629304F9F86358712E9FAE3CA3E:\ -22E578997BB6985E3FFE451B513CBD38CA7A585F8EE89AFCBFE18F280C1A58FC\ -F748F148764DCBB732B8091606006A6D981EEF3311B0621ADF9F098F3DF72793 +7E804307383AFF5BCC80306043721A173E61461E401C1331ED95B8ADB1CFF5CD\ +0943CB3BA8C9A7A02987DD9B6EA2912368284CF14A55566BF264CC244A353227 5E19D97887FCAAC0387E22C6F803C34A3DACD2604172433F7A8A7A526CA4A2A1\ 271ECFC5D5D7BE5AC0D85D921095350DFC65997D443C21C8094E0A3FEFD2961B\ @@ -32263,8 +32263,8 @@ CB94AED03291AE310CCDA75D8ACE4BC7D89E7D3E5D1650BDA5D668B8B50BFC8E\ D71AF2A424BEC9A7CD9D83FAD4C8E9319115656A8717D3B523A68FF8004258B9\ 990ED362308461804BA3E3A7E92D8F2FFAE5C2FBA55BA5A3C27C0A2F71BD711D\ 2FE1799C2ADB31B200035481E9EE5C4ADF2AB9C0FA50B23975CF:\ -36F7E04B2CAD56BDDCAE84B77637F323CFF486B68359F271B6D91EA56D06CEC4\ -CED9BDF928A8ECC713F41D058250FACC1318F67743B8B40F354EBAAE351FDA86 +8B907F2B968634263C0CC229E917FDF0AD93D637299C10D8F76EFFEE6C6A6B83\ +85803FABEDEB1694EACBC11D94FD00CD310C287C2C537BDE39B88A4A15735DF3 C8E976AB4638909387CE3B8D4E510C3230E5690E02C45093B1D297910ABC481E\ 56EEA0F296F98379DFC9080AF69E73B2399D1C143BEE80AE1328162CE1BA7F6A\ @@ -32273,8 +32273,8 @@ C8E976AB4638909387CE3B8D4E510C3230E5690E02C45093B1D297910ABC481E\ 1A274B22F83CEB072F9BCABC0B216685BFD789F5023971024B1878A205442522\ F9EA7D8797A4102A3DF41703768251FD5E017C85D1200A464118AA35654E7CA3\ 9F3C375B8EF8CBE7534DBC64BC20BEFB417CF60EC92F63D9EE7397:\ -A4270E9F05E43A3F770AACA85020914A8B118B59297312B271B1AA4252BDE3BA\ -878EF3B3D0D33645A2847C6423279C478E7B1A7CE757F74E0128AD0D1C1966A4 +4739DB195476A74B06835BA91DD8DFDADE704A06557307E33019738083F36714\ +3C96ECF28523C1BE8CA272ADF7E0EEBB64EEF31FE4C5EF03CE7D46ED6FC86A71 7145FA124B7429A1FC2231237A949BA7201BCC1822D3272DE005B682398196C2\ 5F7E5CC2F289FBF44415F699CB7FE6757791B1443410234AE061EDF623359E2B\ @@ -32283,8 +32283,8 @@ DB7C890DA8BBC84CC73FF244394D0D48954978765E4A00B593F70F2CA082673A\ 261ED88DBCEF1127728D8CD89BC2C597E9102CED6010F65FA75A14EBE467FA57\ CE3BD4948B6867D74A9DF5C0EC6F530CBF2EE61CE6F06BC8F2864DFF5583776B\ 31DF8C7FFCB61428A56BF7BD37188B4A5123BBF338393AF46EDA85E6:\ -AD1A59ABE9786DBA20ECEA2CB6FB44A9EA5D8D89A220700508BB18CFCAD6ACCB\ -ACAC75A9E0882391F0FD2B5AD4274CCFB6277E7963A04D4E44A43161D7CCC30C +68B8AA5731F7D00D547D7E3690761046B54E91257984A46E2CF9BA2835ADB621\ +CE3DDCF81A02A95308300F1E992E3BEDF832FC0433F0A64D5CE277E679933E47 7FDFADCC9D29BAD23AE038C6C65CDA1AEF757221B8872ED3D75FF8DF7DA0627D\ 266E224E812C39F7983E4558BFD0A1F2BEF3FEB56BA09120EF762917B9C09386\ @@ -32293,8 +32293,8 @@ B0BF8B740A82447B61B99FEE5376C5EB6680EC9E3088F0BDD0C56883413D60C1\ 357D3C811950E5890E7600103C916341B80C743C6A852B7B4FB60C3BA21F3BC1\ 5B8382437A68454779CF3CD7F9F90CCC8EF28D0B706535B1E4108EB5627BB45D\ 719CB046839AEE311CA1ABDC8319E050D67972CB35A6B1601B25DBF487:\ -696558AE97B276A78C5A32D9FC84BC068E369BB2471C2FD5DD30C3FE1D079557\ -090D0C10F83454A722A23681AC215B688C46C5EC2AB4BEC48A4A59F2686C29AE +2CD87427875CC3480CD19F567B049B1181D7F46B85F3CDE505005452A0401A51\ +7E0E3D2A2157D789A6D63C8484386EFA9F9717498D35B20CA2A0FD2FDDDF7E15 988638219FD3095421F826F56E4F09E356296B628C3CE6930C9F2E758FD1A80C\ 8273F2F61E4DAAE65C4F110D3E7CA0965AC7D24E34C0DC4BA2D6FF0BF5BBE93B\ @@ -32303,8 +32303,8 @@ B0BF8B740A82447B61B99FEE5376C5EB6680EC9E3088F0BDD0C56883413D60C1\ A91D36891529B8BD8263CAA1BAB56A4AFFAED44962DF096D8D5B1EB845EF3118\ 8B3E10F1AF811A13F156BEB7A288AAE593EBD1471B624AA1A7C6ADF01E2200B3\ D72D88A3AED3100C88231E41EFC376906F0B580DC895F080FDA5741DB1CB:\ -A199EF2227154794D6409C0439774B7127AC77E03E798AA4CADB21E95F19AAB4\ -429866C37711BE7527E42A966B344AA8F60415077E435FC3F87D7A4A4B309182 +5E0A947E07586E1A7EB441B4F44211F3731595E273FBE30FD5478E762C08411D\ +B9DDAA9F9B9D860F5768DF78FBEAF9EFEB9ECAEE9A9874FD38E9EBDE9DDF11E7 5AAB62756D307A669D146ABA988D9074C5A159B3DE85151A819B117CA1FF6597\ F6156E80FDD28C9C3176835164D37DA7DA11D94E09ADD770B68A6E081CD22CA0\ @@ -32313,8 +32313,8 @@ A5AB1FB77FDCA49B305F07BA86B62756FB9EFB4FC225C86845F026EA542076B9\ 1A0BC2CDD136E122C659BE259D98E5841DF4C2F60330D4D8CDEE7BF1A0A24452\ 4EECC68FF2AEF5BF0069C9E87A11C6E519DE1A4062A10C83837388F7EF58598A\ 3846F49D499682B683C4A062B421594FAFBC1383C943BA83BDEF515EFCF10D:\ -FC2E7DE13ED475ED2A53102B46329134210FAD3938BDC20A5E6A8CDC325C6204\ -963D46AC350DBB626AD0FFBAB1A8B29C282DD5A6C3B1ADC38D9D8E1CC7100F0A +B8098CB26FCC5ACD64C492919EA1C7ECDC9B3DE4854D69E7947E05BD0BF6E84C\ +240FA83ACEE02C829A959614107CE03DB8ACA40D38F9CC57B7F94C3C220DEEEB 47B8216AA0FBB5D67966F2E82C17C07AA2D6327E96FCD83E3DE7333689F3EE79\ 994A1BF45082C4D725ED8D41205CB5BCDF5C341F77FACB1DA46A5B9B2CBC49EA\ @@ -32323,8 +32323,8 @@ DF786BCD881F371A95FA17DF73F606519AEA0FF79D5A11427B98EE7F13A5C006\ 7EA01F56FFA4DAFBE8644611685C617A3206C7A7036E4AC816799F693DAFE7F1\ 9F303CE4EBA09D21E03610201BFC665B72400A547A1E00FA9B7AD8D84F84B34A\ EF118515E74DEF11B9188BD1E1F97D9A12C30132EC2806339BDADACDA2FD8B78:\ -6A7398EF52E606BFAEEADACC5031002265E9E5F279440E798A25461DF3335986\ -DBFACF54A484FFC20736796251B9474C8AA7CF6F70301900DABF1A572A1BCE7F +0F4C4ECFD9A8431D5AB9A245A77CD70974FB75F1824FE68583E9F25E73BA5725\ +88AD0C328D73BEBEDF1FC99D898B7D1C9EB9AB048896CD0446A3E932A97710AB 8CFF1F67FE53C098896D9136389BD8881816CCAB34862BB67A656E3D98896F3C\ E6FFD4DA73975809FCDF9666760D6E561C55238B205D8049C1CEDEEF374D1735\ @@ -32334,8 +32334,8 @@ DAA533147BFA960B2CCE4A4F254176BB4D1BD1E89654432B8DBE1A135C42115B\ 7F1766A44171D1651001C38FC79294ACCC68CEB5665D36218454D3BA169AE058\ A831338C17743603F81EE173BFC0927464F9BD728DEE94C6AEAB7AAE6EE3A627\ E8:\ -E7CD2794FACC6407A59E1F9630FE5728ED102CADD594D1504021D39A658634F2\ -5A5711F57CFDF5D69BC96A9AF8BD83EDFE2B4AD4297917B67582D211279CD9E6 +C90025BE7F02FA18134B63681B5A635A51C06EE37878C4833E0A853FA474AEFD\ +06BEEBA4597ED8E59255EE4DEC81B34D6EF3DF617A885F50B79F6EF9E47B4003 EACD07971CFF9B9939903F8C1D8CBB5D4DB1B548A85D04E037514A583604E787\ F32992BF2111B97AC5E8A938233552731321522AB5E8583561260B7D13EBEEF7\ @@ -32345,8 +32345,8 @@ C20D259DEE1711E2CC8FD013169FB7CC4CE38B362F8E0936AE9198B7E838DCEA\ 97447692794B3DFA269611AD97F72B795602B4FDB198F3FD3EB41B415064256E\ 345E8D8C51C555DC8A21904A9B0F1AD0EFFAB7786AAC2DA3B196507E9F33CA35\ 6427:\ -CCDF5E0EEEA0CE7A7B56DF1AD74E9845384C747375C08DCF472698202A6BE369\ -6AD4A47A259FE195D863865BDD1DAB962721592CAD55A2F8AB42DF865D348709 +5C21E22D8B2887134F03D05945D91282B6321F122E53640C046FF9B1692F1210\ +CA46CD8471E95F3C74F7FEB1DA0DC8A421EEFFB3699351825F16BA621015EEEF 23AC4E9A42C6EF45C3336CE6DFC2FF7DE8884CD23DC912FEF0F7756C09D335C1\ 89F3AD3A23697ABDA851A81881A0C8CCAFC980AB2C702564C2BE15FE4C4B9F10\ @@ -32356,8 +32356,8 @@ BB7DF3DDA6F2A143C8BF96ABC903D83D59A791E2D62814A89B8080A28060568C\ F24A80AE61179FE84E0FFAD00388178CB6A617D37EFD54CC01970A4A41D1A8D3\ DDCE46EDBBA4AB7C90AD565398D376F431189CE8C1C33E132FEAE6A8CD17A61C\ 630012:\ -FA5AF2DDE57145CE00156176309499D6B4A801C806177B5A4CC972EF9D021376\ -76ABF467B2F74103DB1D97F555FD87DBE782C7A7E4EF7BC4D9A0BBBFAEC10CF0 +F1A7011447E8515E1502A3AE56F8BE61EB4200BC4D21C8E1875B73AB2A42DE46\ +13D6404B17A740B60B57F742C92F45C07880498C44C989C15CF1CD37B3F26E77 0172DF732282C9D488669C358E3492260CBE91C95CFBC1E3FEA6C4B0EC129B45\ F242ACE09F152FC6234E1BEE8AAB8CD56E8B486E1DCBA9C05407C2F95DA8D8F1\ @@ -32367,8 +32367,8 @@ A71951C524259E4E2054E535B779679BDADE566FE55700858618E626B4A0FAF8\ 95BCCE9011504A49E05FD56127EAE3D1F8917AFB548ECADABDA1020111FEC931\ 4C413498A360B08640549A22CB23C731ACE743252A8227A0D2689D4C60016066\ 78DFB921:\ -F09FA792B17868C35A49A69C75F1D6DF5A8A5273DBFDBCB904821401F3B71EC8\ -BCC96D28E9DC5B3B488B863C40235B1B9503845EF7614CB7A10B8839D907EC61 +02BE97BE60F581D73527490734CD5F8739DCB9A5089CC49C7619277CEB30D9A6\ +9B85C53EFC55C780A6494DD172B8BEB2B69F86DD4B7CBFA3E47F1720ED394383 3875B9240CF3E0A8B59C658540F26A701CF188496E2C2174788B126FD29402D6\ A75453BA0635284D08835F40051A2A9683DC92AFB9383719191231170379BA6F\ @@ -32378,8 +32378,8 @@ DA19AA6925B47FFD77A43C7A0E758C37D69254909FF0FBD415EF8EB937BCD49F\ 91468B49974C07DC819ABD67395DB0E05874FF83DDDAB895344ABD0E7111B2DF\ 9E58D76D85AD98106B36295826BE04D435615595605E4B4BB824B33C4AFEB5E7\ BB0D19F909:\ -32ABC489EBA1BCA1EDCB275224F9BEC0D1CF04ED2C33F518DB23EFCF0C64861F\ -B4FA2F28BDA1098588E2971B8CC39C9817B98A6D88E5748DB4B12DE8FDE6916D +38652A2D6674A539559F3ED0996542C23D48D8D108C2AF9C10DA45C9DBC11906\ +CB4AEE8EB04C88789B763C66B743356336C8950303B950D72A8FCA05B9C67CD9 747CC1A59FEFBA94A9C75BA866C30DC5C1CB0C0F8E9361D98484956DD5D1A40F\ 6184AFBE3DAC9F76028D1CAECCFBF69199C6CE2B4C092A3F4D2A56FE5A33A007\ @@ -32389,8 +32389,8 @@ B4FA2F28BDA1098588E2971B8CC39C9817B98A6D88E5748DB4B12DE8FDE6916D 81150DDAF8D7FEBAA4374F0872A5628D318000311E2F5655365AD4D407C20E5C\ 04DF17A222E7DEEC79C5AB1116D8572F91CD06E1CCC7CED53736FC867FD49ECE\ BE6BF8082E8A:\ -21953763A36299B39B33610211A69F0F0AF1C74E3B11F392CA95E7B8E46987C0\ -BA31A11401EC3B781106024B4C07CCE4E738B06818B9D528FA1CEDA90D5A7E3A +BC091874BAF2195324C56EE8386E13AC3F49FDB329C2D5835848AF2A3653BCEA\ +26EC8C370912CBCFB1C20D3EB9AB53C6160CDD5351836527C5719084A575EF64 57AF971FCCAEC97435DC2EC9EF0429BCEDC6B647729EA168858A6E49AC1071E7\ 06F4A5A645CA14E8C7746D65511620682C906C8B86EC901F3DDED4167B3F00B0\ @@ -32400,8 +32400,8 @@ D8BB801E701E99DC4FEAAD59BC1C7112453B04D33EA3635639FB802C73C2B71D\ 58A56BBD671B18FE34ED2E3DCA38827D63FDB1D4FB3285405004B2B3E26081A8\ FF08CD6D2B08F8E7B7E90A2AB1ED7A41B1D0128522C2F8BFF56A7FE67969422C\ E839A9D4608F03:\ -7E1821FB111387BFBED27202BDB87C9B6C97F4496BD3F36AD387644DA3902258\ -377BBAACF79EC3510C1381BFAE6F07BB71615DB43F5B3D67BDBE37D04235AE4C +D8025F57C003DDCC6ABDDCE2CCFFDB9C11BE984311A749A632D7EE4EB073C58F\ +0074096C17CE0A46B37700581D9FF074143F34322D5460C4BD1E9EE6AD497F40 04E16DEDC1227902BAAF332D3D08923601BDD64F573FAA1BB7201918CFE16B1E\ 10151DAE875DA0C0D63C59C3DD050C4C6A874011B018421AFC4623AB0381831B\ @@ -32411,8 +32411,8 @@ BF6A11CF6932BBBAD33F8946BF5814C066D851633D1A513510039B349939BFD4\ 8B647EACFB4444B85A44F73890607D06D507A4F8393658788669F6EF4DEB58D0\ 8C50CA0756D5E2F49D1A7AD73E0F0B3D3B5F090ACF622B1878C59133E4A848E0\ 5153592EA81C6FBF:\ -47E3E3BEA0783D1938BE236D64A56E414E808A04FA8544908E958C00297B37C8\ -3F06766E4399F808DCAA746C3C0B26923810DF0FC01FFC5CBC514AD200EC9A4A +99812EB8737BF609B3BF4B8ADE116403183DD7332DAB4F43BB4917DA0B62ABC5\ +A4772D572BDDA22FD555AF55309D31FB93492ED3EF4455FDE4FFFE7BF8DF84AE 7C815C384EEE0F288ECE27CCED52A01603127B079C007378BC5D1E6C5E9E6D1C\ 735723ACBBD5801AC49854B2B569D4472D33F40BBB8882956245C366DC3582D7\ @@ -32422,8 +32422,8 @@ BF6A11CF6932BBBAD33F8946BF5814C066D851633D1A513510039B349939BFD4\ 9392D94CAB7448F50EB34E9A93A80027471CE59736F099C886DEA1AB4CBA4D89\ F5FC7AE2F21CCD27F611ECA4626B2D08DC22382E92C1EFB2F6AFDC8FDC3D2172\ 604F5035C46B8197D3:\ -71888C037DB742E312F41B0C35A7DBF9251E2570434A572919618C5CBE5AE6A5\ -719991A7FE08AB8368B0E5FA1A4C2A69DBE5E102F2131BBE9256A30F83B13C93 +6B242888A6E956F10A8BE75E09287D59CC25155B0AA8D8BA02E095D0AFAA2910\ +4CB2051AA4B3430B724D500AD0317208C3BA9FB1265BF19A974E90F4BF0CE006 E29D505158DBDD937D9E3D2145658EE6F5992A2FC790F4F608D9CDB44A091D5B\ 94B88E81FAC4FDF5C49442F13B911C55886469629551189EAFF62488F1A479B7\ @@ -32433,8 +32433,8 @@ DB11A1560E198DDCCCCF50159093425FF7F1CB8D1D1246D0978764087D6BAC25\ 7BE16FF2526DC643872502D01F42F188ABED0A6E9A6F5FD0D1CE7D5755C9FFA6\ 6B0AF0B20BD806F08E06156690D81AC811778CA3DAC2C249B96002017FCE93E5\ 07E3B953ACF99964B847:\ -3A34914F60EF0640FD020D33511DD4702BB9D446DEEAC314DD69A29426A98707\ -A3EF3B568BD9BB4482B3C06E660BF247DCF4338469D46445FDE2E655DC8D5179 +FF77EF8DE1483F8A498E3554083BB69F7567FCED495E6BF0C9902CDCB5247FAC\ +6A4B50D1CF9CEE89C400ED3E4E6FEBB642F1AC3BBD018ECC04CB1A43A1331ECC D85588696F576E65ECA0155F395F0CFACD83F36A99111ED5768DF2D116D2121E\ 32357BA4F54EDE927F189F297D3A97FAD4E9A0F5B41D8D89DD7FE20156799C2B\ @@ -32444,8 +32444,8 @@ D85588696F576E65ECA0155F395F0CFACD83F36A99111ED5768DF2D116D2121E\ C6B6B3F95F4F02B64DABC15438613EA49750DF42EE90101F115AA9ABB9FF6432\ 4DDE9DABBB01054E1BD6B4BCDC7930A44C2300D87CA78C06924D0323AD7887E4\ 6C90E8C4D100ACD9EED21E:\ -5544DC0EE3FF599ECB2886C96A7EBFE47673D03FA690666855F159F45861C57F\ -666EB0E5B57D1D211802861BDA5C283BF83CE9A8399748D576E2E0BF7DA083B9 +83E0BEDD263922F016CF539F9E7B43ACAFDDF35C8CE730434EE3E92ACD264006\ +031073A705F5585BFB66E53EA6A733901AE40634B6F4D86FB554CE0EBC5CD807 3A12F8508B40C32C74492B66323375DCFE49184C78F73179F3314B79E63376B8\ AC683F5A51F1534BD729B02B04D002F55CBD8E8FC9B5EC1EA6BBE6A0D0E74315\ @@ -32455,8 +32455,8 @@ E1B3ADE3192AF42054A8A911B8EC1826865D46D93F1E7C5E2B7813C92A506E53\ 886F3D4701BB93D2A681AD109C845904BB861AF8AF0646B6E399B38B614051D3\ 4F6842563A0F37EC00CB3D865FC5D746C4987DE2A65071100883A2A9C7A2BFE1\ E2DD603D9EA24DC7C5FD06BE:\ -4875DBCB1EE61EDEBDA1F13D1AEEDF38995BB1C6BBA1440233B27367E251E75C\ -F5087EEC74F1FBA132D18FD4B6D6E72DE3E98943477783051ADDEEDDA3047C26 +E063490AC5C915BAF98C37660EB17A85798D728FB57CB0ACFAEDE8AFE847C902\ +5D8BF55B6EEA096A6F0B443B38D0BC77DD0BCB8228ED2681BB03A013D15CEB79 1861EDCE46FA5AD17E1FF1DEAE084DEC580F97D0A67885DFE834B9DFAC1AE076\ 742CE9E267512CA51F6DF5A455AF0C5FD6ABF94ACEA103A3370C354485A7846F\ @@ -32466,8 +32466,8 @@ E3B473417F36D4D2505D16B7577F4526C9D94A270A2DFE450D06DA8F6FA95687\ 9A0A55CFE99E742EA555EA477BA3E9B44CCD508C375423611AF92E55345DC215\ 779B2D5119EBA49C71D49B9FE3F1569FA24E5CA3E332D042422A8B8158D3EC66\ A80012976F31FFDF305F0C9C5E:\ -2D6A9F1D1BCF3FF53266A1E68CF2BBEB5EBA9B84534C36E8462471EE1CC14D5E\ -57123D6DD1FBE51EF6A2D111D97A332128044B122083498E132295F52DBCFCFD +2F2FBA371016CD20ADC35C032B61100C298FBAF81506E83CC6E9BCC61244838A\ +D83465658A6436BD488C55D27B82BA3FFC5223BB97A03AE33E05CA750FDF56E2 08D0FFDE3A6E4EF65608EA672E4830C12943D7187CCFF08F4941CFC13E545F3B\ 9C7AD5EEBBE2B01642B486CAF855C2C73F58C1E4E3391DA8E2D63D96E15FD849\ @@ -32477,8 +32477,8 @@ B7E91E81E128C1716DC3ACFE3084B2201E04CF8006617EECF1B640474A5D45CF\ DE9F4D3EF92D6D055B909892194D8A8218DB6D8203A84261D200D71473D7488F\ 3427416B6896C137D455F231071CACBC86E0415AB88AEC841D96B7B8AF41E05B\ B461A40645BF176601F1E760DE5F:\ -C709FCF02BF7DB2A73C6E8FAF1443FAB5E963C12C0BD5EC498FAD3BC5D769D42\ -8832AD6AB85B3299645993B7170685A3E2A25E8A3F8B822CDD31681A8BF1E180 +783AF05873F418BAF09AA3479FFBA6CC9949F90D7CB9DF1355B46B020712EDD4\ +0477F7B2980DEFC4474B2D3C24BF92ECB5DA64FBDF167EDD9D9D48792D2B4DF8 D782ABB72A5BE3392757BE02D3E45BE6E2099D6F000D042C8A543F50ED6EBC05\ 5A7F133B0DD8E9BC348536EDCAAE2E12EC18E8837DF7A1B3C87EC46D50C241DE\ @@ -32488,8 +32488,8 @@ F612D2E4D810DAA3A0CC904516F9A43AF660315385178A529E51F8AAE141808C\ EAE04F520A9016F2FB8BF5165ED12736FC71E36A49A73614739EAA3EC834069B\ 1B40F1350C2B3AB885C02C640B9F7686ED5F99527E41CFCD796FE4C256C91731\ 86C226169FF257954EBDA81C0E5F99:\ -EFAF0DD633F502AF10B5A14ABDC91D140892BBD5F3A6D7401099B2196FADF61E\ -9C6AA7123EC75AF0354FA1F55A3C1C68D9324368B2FB54CC6E370459B642B68D +B53D11E8514950F60345F266290DFD57B8550C011F2BBC1C7CD718E74CAA9847\ +3E98CF794975661C7D46D6DF10E14F0AF2E0EFBD480A350AC60E0881EA7090FD 5FCE8109A358570E40983E1184E541833BB9091E280F258CFB144387B05D190E\ 431CB19BAA67273BA0C58ABE91308E1844DCD0B3678BAA42F335F2FA05267A02\ @@ -32499,8 +32499,8 @@ A99F310735EE5A05DAE2C22D397BD95635F58C48A67F90E1B73AAFCD3F82117F\ 2DE14740F2B85AE5299DDEC3172DE8B6D0BA219A20A23BB5E10FF434D39DB3F5\ 83305E9F5C039D98569E377B75A70AB837D1DF269B8A4B566F40BB91B577455F\ D3C356C914FA06B9A7CE24C7317A172D:\ -A9D32B2C3876DD44D5DA3FBBD12200B61D817834EA5E16E3487AAD3EFDF757D4\ -B11567232879F52FC6FC9A26F03595A2377A52D18872A71F6160111C5B1597F5 +0E21302B185191492D2625F0FC4A3380ECD75D8EA945E35FD6E57EB7142DE249\ +90EEE2B6711392F8856874DE50E6D2FDF1D23A228877298C668251FD0F06B709 6172F1971A6E1E4E6170AFBAD95D5FEC99BF69B24B674BC17DD78011615E502D\ E6F56B86B1A71D3F4348087218AC7B7D09302993BE272E4A591968AEF18A1262\ @@ -32510,8 +32510,8 @@ B963E1CA5AB193E124A1A53DF1C587470E5881FB54DAE1B0D840F0C8F9D1B04C\ F35EE66C1AD7801A28D3D388AC450B97D5F0F79E4541755356B3B1A5696B023F\ 39AB7AB5F28DF4202936BC97393B93BC915CB159EA1BD7A0A414CB4B7A1AC3AF\ 68F50D79F0C9C7314E750F7D02FAA58BFA:\ -18E8604561DA7971FA12B82807468750AC3177155BFD8EE32476CCA602BEDDDE\ -6FDE2DCEB474E5B69E7AE6CC4EA9CCF69A221D28AFE9002AF1B8DD03BB5166A3 +1A77E749C8249D06F08943F5CDFEB5D65C804F1052B036CCD7A6F16120315AF7\ +B20C6BE56CA65861A2568F7E726420E909FAF47E4ED96A3C299AFF94EDFBF6EB 5668ECD99DFBE215C4118398AC9C9EAF1A1433FAB4CCDD3968064752B625EA94\ 4731F75D48A27D047D67547F14DD0FFAA55FA5E29F7AF0D161D85EAFC4F2029B\ @@ -32521,8 +32521,8 @@ FFF824B1CB2FA01B32D1E46C909E626ED2DAE920F4C7DBEB635BC754FACBD8D4\ 9BEBA3F23C1C41CCBFCD0EE0C114E69737F5597C0BF1D859F0C767E18002AE8E\ 39C26261FFDE2920D3D0BAF0E906138696CFE5B7E32B600F45DF3AAA39932F3A\ 7DF95B60FA8712A2271FCAF3911CE7B511B1:\ -28282DCB2629E8F9EFEE080ABE51CEB7AFBE3A6E49FD3A2CAADEBAC24E12549B\ -7F0C20A71A03B52A96016CFAF31DD2C0237AA255BEAA867A1B53D31F7D8CAB15 +CDF5CC029A5946BB96A524D865C6BAB024A2B598A9A657EF631FA582ED9BEBF5\ +6C18D955528A3DD5BC0D2466F7EE0EF8AF1C814E3858E5DA3A2BA951BB2D79A0 03D625488354DF30E3F875A68EDFCF340E8366A8E1AB67F9D5C5486A96829DFA\ C0578289082B2A62117E1CF418B43B90E0ADC881FC6AE8105C888E9ECD21AEA1\ @@ -32532,8 +32532,8 @@ C9AE1A4038DFD17378FED71D02AE492087D7CDCD98F746855227967CB1AB4714\ 61F9DC752CE18867B8AD0C48DF8466EF7231E7AC567F0EB55099E622EBB86CB2\ 37520190A61C66AD34F1F4E289CB3282AE3EAAC6152ED24D2C92BAE5A7658252\ A53C49B7B02DFE54FDB2E90074B6CF310AC661:\ -13D40918BED7651EB67B8AB70CC1C45A4B55070E898B1F3A462BD28CE20DBB24\ -FBEB0EBFDE934734ED1D7002094DD9D798CB9670E5423047DEDEA64A0B02DEF5 +2A4B61FEAAC1BC466DD77EBE6E800F87950B28532F71BE5E4D56DE28F93C1F7E\ +61C793745A91B8CCDC29914989730B7DF933E6C7F1B1A08638953F966F092560 2EDC282FFB90B97118DD03AAA03B145F363905E3CBD2D50ECD692B37BF000185\ C651D3E9726C690D3773EC1E48510E42B17742B0B0377E7DE6B8F55E00A8A4DB\ @@ -32543,8 +32543,8 @@ C651D3E9726C690D3773EC1E48510E42B17742B0B0377E7DE6B8F55E00A8A4DB\ F106F89AF3745F0EC72D534968CCA543CD2CA50C94B1456743254E358C1317C0\ 7A07BF2B0ECA438A709367FAFC89A57239028FC5FECFD53B8EF958EF10EE0608\ B7F5CB9923AD97058EC067700CC746C127A61EE3:\ -68A370AC86CCE98209A9DB13174C27FD786820054FFDD09CA18B62112248A85D\ -A929A8E56F499D467DFB503AB5523C09317DD8E5C9D50BD4BE105086DAECA1DB +A40028E17CD5DA2DB800437A58861565E0A55CD3DC017FE48C7D3F2D4706D7EC\ +742A21170CB86B32B5B9A1496C5C5DDE4E283915BFCDC883F08039679E29ED43 90B28A6AA1FE533915BCB8E81ED6CACDC10962B7FF82474F845EEB86977600CF\ 70B07BA8E3796141EE340E3FCE842A38A50AFBE90301A3BDCC591F2E7D9DE53E\ @@ -32554,8 +32554,8 @@ DCDB451ABB9E9C17EFA4379ABD24B182BD981CAFC792640A183B61694301D04C\ 00E2B16A6C49171433B0AADFD80231276560B80458DD77089B7A1BBCC9E7E4B9\ F881EACD6C92C4318348A13F4914EB27115A1CFC5D16D7FD94954C3532EFACA2\ CAB025103B2D02C6FD71DA3A77F417D7932685888A:\ -CA5795E813341812738D01EDD488E424E7AD9B20AB6BDC119DD1FAA5C8FE81D8\ -08AF72F761EEA4FF6AADF4B676CEF23BD94E50DC750BDB95B1413BE258D3492F +2A1F1C7FAFBE676D2A7BC67BD80C9387F493643E2395852AF8A6846A5DDC191C\ +B17FCAA17BB82266FEA390B3E45DED4A15408A29DF5AE390A1BC945D5D97C1C7 2969447D175490F2AA9BB055014DBEF2E6854C95F8D60950BFE8C0BE8DE254C2\ 6B2D31B9E4DE9C68C9ADF49E4EE9B1C2850967F29F5D08738483B417BB96B2A5\ @@ -32565,8 +32565,8 @@ CA5795E813341812738D01EDD488E424E7AD9B20AB6BDC119DD1FAA5C8FE81D8\ B144CE2AC57F5D7297F9C9949E4FF68B70D339F87501CE8550B772F32C6DA8AD\ 2CE2100A895D8B08FA1EEAD7C376B407709703C510B50F87E73E43F8E7348F87\ C3832A547EF2BBE5799ABEDCF5E1F372EA809233F006:\ -AEBEA537873B9F4E686EA96CBA636DBB86C01E95C22998AA418478BE9F5C459D\ -125F0D50E1CB3046C09795E79FB2A2480F753BCF8A4A66B001FC37DB289CC7C0 +80C5090FDDA7FB8B550602FBB156D650958E0EE131E21C09FCCB57FAA9A9C868\ +C5947E409BC5CFA89C8616619E625C7D1DAD8686FF59C2CD1D9940E336472145 721645633A44A2C78B19024EAECF58575AB23C27190833C26875DC0F0D50B46A\ EA9C343D82EA7D5B3E50EC700545C615DAEAEA64726A0F05607576DCD396D812\ @@ -32576,8 +32576,8 @@ FF0382FCFD127F1B803A4B9946F4AC9A4378E1E6E041B1389A53E3450CD32D9D\ 5D564F16DA4ED5E607ED979592146FFB0EF3F3DB308FB342DF5EB5924A48256F\ C763141A278814C82D6D6348577545870AE3A83C7230AC02A1540FE1798F7EF0\ 9E335A865A2AE0949B21E4F748FB8A51F44750E213A8FB:\ -AD29A31BB70BAA848D6837251D4892E7C9B1FDBB07B2DFB1F88158D76CA2C194\ -1924EE62EAD10C053EE0EC6CEA8BBC4F08EC4DEBB90B80AAA6AC91CE190078EC +A779BC3D4F6315BEFDA9CBBBDBA4C9E24D810CB46074D81A6E2D66947A30F62C\ +4D3EB92AFC6D9BFBF42DF3D8528982FCF7AECA66740D0E753040A2C6F71AC1DB 6B860D39725A14B498BB714574B4D37CA787404768F64C648B1751B353AC92BA\ C2C3A28EA909FDF0423336401A02E63EC24325300D823B6864BB701F9D7C7A1F\ @@ -32587,8 +32587,8 @@ C2C3A28EA909FDF0423336401A02E63EC24325300D823B6864BB701F9D7C7A1F\ 0FE2BDD2935D001EE6419ABAB5457880D0DBFF20ED8758F4C20FE759EFB33141\ CF0E892587FE8187E5FBC57786B7E8B089612C936DFC03D27EFBBE7C8673F160\ 6BD51D5FF386F4A7AB68EDF59F385EB1291F117BFE717399:\ -918F9F10D39C9C75786958573AC487B3A66FAD5AF00C47FC359E1042EE01673B\ -C7DE432E34C84A84C8D7AAE9223B833348A8AEAB102D581A4D51EE5C9A554CEC +46D64790833ABF3E17BB4B8CCDB4F0A2DCD23FDFA3135744306F4916A658CC5B\ +0BB60DD65DD2287287CA645C0B5904A7227ED1B40730A6F335BEC41706769E9D 6A01830AF3889A25183244DECB508BD01253D5B508AB490D3124AFBF42626B2E\ 70894E9B562B288D0A2450CFACF14A0DDAE5C04716E5A0082C33981F6037D23D\ @@ -32598,8 +32598,8 @@ E4393A0725D17963D0342684F255496D8A18C2961145315130549311FC07F031\ 4568398E5DD9A7CF97E8C9663E23334B46912F8344C19EFCF8C2BA6F04325F1A\ 27E062B62A58D0766FC6DB4D2C6A1928604B0175D872D16B7908EBC041761187\ CC785526C2A3873FEAC3A642BB39F5351550AF9770C328AF7B:\ -EA67ECB1057F745B90EDC6327F94320AD9B452889B079E9FC39F5440F795502C\ -3939DD7B393B54C608CF6519902F8D2B3E20629DF4CBF7BB54AEE5525F206489 +29EBB2B1BF14463500B983F8C9FE9EAD506514E9AF11202A9E0930B225EBC525\ +8A09324010C52FF35E902647D9701293A8F8A007ABC3D6A7BE629C5078A42BED B3C5E74B69933C2533106C563B4CA20238F2B6E675E8681E34A389894785BDAD\ E59652D4A73D80A5C85BD454FD1E9FFDAD1C3815F5038E9EF432AAC5C3C4FE84\ @@ -32609,8 +32609,8 @@ F39B9FAFF7FBA457689B9C1A577B2A1E505FDF75C7A0A64B1DF81B3A356001BF\ 8E7AED1EF90EBD090AE825795CDCA1B4F09A979C8DFC21A48D8A53CDBB26C4DB\ 547FC06EFE2F9850EDD2685A4661CB4911F165D4B63EF25B87D0A96D3DFF6AB0\ 758999AAD214D07BD4F133A6734FDE445FE474711B69A98F7E2B:\ -86995F59B4D11D960E5A6DD3FFC513BE7659D1957159284477472B61504E1055\ -B51F07C253EE597426BF18308E5C807D8A8FDDA683FA8EE2A0556B8507B663F4 +8DB46A5D23103103746C2FE2480CEEC56FD9796AD357F5BC45BF0BC2D2E8B95E\ +A0C286090AB858183C2A051B80FCA8776670FA3DA8722329848F057C6EAD4991 83AF34279CCB5430FEBEC07A81950D30F4B66F484826AFEE7456F0071A51E1BB\ C55570B5CC7EC6F9309C17BF5BEFDD7C6BA6E968CF218A2B34BD5CF927AB846E\ @@ -32620,8 +32620,8 @@ BF70B5BD17834F7BFA0E16CB219AD4AF524AB1EA37334AA66435E5D397FC0A06\ 3E5B741D13437095707C565E10D8A20B8C20468FF9514FCF31B4249CD82DCEE5\ 8C0A2AF538B291A87E3390D737191A07484A5D3F3FB8C8F15CE056E5E5F8FEBE\ 5E1FB59D6740980AA06CA8A0C20F5712B4CDE5D032E92AB89F0AE1:\ -09B7DEB81713594A5938A41083F728DF3F0BF93BF0EBE61DB6982885D96B40A5\ -112E7440BBA919D259F6F8173FF0942BDFE95B65BB22BF62606FF49998AF4C0A +BC933D42AD3267F608AB201D2813E54250499D87ECEEF837863F59D8ACE4ED6A\ +3239C4C7CD7E172F3CF3CDED5D84950E066E2F549A767BA421CAD4A223313C1D A7ED84749CCC56BB1DFBA57119D279D412B8A986886D810F067AF349E8749E9E\ A746A60B03742636C464FC1EE233ACC52C1983914692B64309EDFDF29F1AB912\ @@ -32631,8 +32631,8 @@ EC3E8DA074D3F1D231511F5756F0B6EEAD3E89A6A88FE330A10FACE267BFFBFC\ 49813B4EB9ED122A01B3EA45AD5E1A929DF61D5C0F3E77E1FDC356B63883A60E\ 9CBB9FC3E00C2F32DBD469659883F690C6772E335F617BC33F161D6F6984252E\ E12E62B6000AC5231E0C9BC65BE223D8DFD94C5004A101AF9FD6C0FB:\ -4B0469116292A76D4767F4FAAA420BDB66F8578D39390E65E5858ACE28715944\ -A394AA7903F2BC1B466A5F3E1EFD8EE56EFB42D71D877C4BD9666B24D677D9E9 +D84DDA22FBE020F57EFBC8C612B2F781EAA81E4C9B0F013BFC1B3C926A5BA778\ +28F8C6684A25B2C567DAD1B705E7BB417F5EAE6D8BD2BFA6ACBC7284F3C19E81 A6FE30DCFCDA1A329E82AB50E32B5F50EB25C873C5D2305860A835AECEE6264A\ A36A47429922C4B8B3AFD00DA16035830EDB897831C4E7B00F2C23FC0B15FDC3\ @@ -32642,8 +32642,8 @@ B854CEE9AC02900036F3867FE0D84AFFF37BDE3308C2206C62C4743375094108\ 877C73B87B2546FE05EA137BEDFC06A2796274099A0D554DA8F7D7223A48CBF3\ 1B7DECAA1EBC8B145763E3673168C1B1B715C1CD99ECD3DDB238B06049885ECA\ D9347C2436DFF32C771F34A38587A44A82C5D3D137A03CAA27E66C8FF6:\ -B4FF987CD5FB38C70E24DF63FC1EE4C237E992028E92F6470C721501E5761380\ -C89E590538C3EF9060DE9D957CBC18CB4E0F2AE429E934FE433725EDD6C3F4FA +C4966858DB87DFC7DAE95CB51A8B19DD481F75B3FF554B18458C0F25A285F613\ +5D73FF6F1B498B957E8481F16612D8B52E187BDE76B3A8D1A6324A3899F056D8 83167FF53704C3AA19E9FB3303539759C46DD4091A52DDAE9AD86408B6933598\ 9E61414BC20AB4D01220E35241EFF5C9522B079FBA597674C8D716FE441E5661\ @@ -32653,8 +32653,8 @@ C89E590538C3EF9060DE9D957CBC18CB4E0F2AE429E934FE433725EDD6C3F4FA 0291944C8B730AD3D4789273FA44FB98D78A36C3C3764ABEEAC7C569C1E43A35\ 2E5B770C3504F87090DEE075A1C4C85C0C39CF421BDCC615F9EFF6CB4FE64680\ 04AECE5F30E1ECC6DB22AD9939BB2B0CCC96521DFBF4AE008B5B46BC006E:\ -36CE68F98A2A0910E1030C58EAA78631A6509BBA62A524E3B59AE3562B66CFB3\ -42DE8155AA9899205FD8005BF1535A986F84CB16BBBE309C33855C85721CA09F +DEF5B398B53E2B884AAA19D86186EC7B386974386B24F5C993417C1B3377449D\ +0EE19D00AB789E2D63A56B01101E44692815644147D1C2D66A9A68579BEB2B50 3A3A819C48EFDE2AD914FBF00E18AB6BC4F14513AB27D0C178A188B61431E7F5\ 623CB66B23346775D386B50E982C493ADBBFC54B9A3CD383382336A1A0B2150A\ @@ -32664,8 +32664,618 @@ B2F83AADC66B148B4A0CD95246C127D5871C4F11418690A5DDF01246A0C80A43\ C70088B6183639DCFDA4125BD113A8F49EE23ED306FAAC576C3FB0C1E256671D\ 817FC2534A52F5B439F72E424DE376F4C565CCA82307DD9EF76DA5B7C4EB7E08\ 5172E328807C02D011FFBF33785378D79DC266F6A5BE6BB0E4A92ECEEBAEB1:\ -E47D7A2CA60627F7A1416FF0E0CC9F9E6CE06A1E01A4F6D58F516927032AC757\ -1CA29BB3299430E48AFF05FF0C025BE561002C9FBA30E63B24A3E35469F904D1 +59D674C09E78B40FADD298EE83FB2CB4468CA96AFAA75CE3F4B451C0D353C28A\ +632A0DE753800D49FDBD6EA190025C5340036910BDBACC91C2D988B6FB2F8789 + +724627916C50338643E6996F07877EAFD96BDF01DA7E991D4155B9BE1295EA7D\ +21C9391F4C4A41C75F77E5D27389253393725F1427F57914B273AB862B9E31DA\ +BCE506E558720520D33352D119F699E784F9E548FF91BC35CA14704212870982\ +0D69A8287EA3257857615EB0321270E94B84F446942765CE882B191FAEE7E1C8\ +7E0F0BD4E0CD8A927703524B559B769CA4ECE1F6DBF313FDCF67C572EC4185C1\ +A88E86EC11B6454B371980020F19633B6B95BD280E4FBCB0161E1A82470320CE\ +C6ECFA25AC73D09F1536F286D3F9DACAFB2CD1D0CE72D64D197F5C7520B3CCB2\ +FD74EB72664BA93853EF41EABF52F015DD591500D018DD162815CC993595B195:\ +7A3E81CDEA3E783B0D2E77373D7E3AD3E069DF3C9F16EA87E41CD7178EBA02D4\ +9AA344C562EA9DB6FB20645F5F3DB9B62EC1F18ADFB5C10C77C1EBACEECC5E25 + +3139840B8AD4BCD39092916FD9D01798FF5AA1E48F34702C72DFE74B12E98A11\ +4E318CDD2D47A9C320FFF908A8DBC2A5B1D87267C8E983829861A567558B37B2\ +92D4575E200DE9F1DE45755FAFF9EFAE34964E4336C259F1E66599A7C904EC02\ +539F1A8EAB8706E0B4F48F72FEC2794909EE4A7B092D6061C74481C9E21B9332\ +DC7C6E482D7F9CC3210B38A6F88F7918C2D8C55E64A428CE2B68FD07AB572A8B\ +0A2388664F99489F04EB54DF1376271810E0E7BCE396F52807710E0DEA94EB49\ +F4B367271260C3456B9818FC7A72234E6BF2205FF6A36546205015EBD7D8C252\ +7AA430F58E0E8AC97A7B6B793CD403D517D66295F37A34D0B7D2FA7BC345AC04\ +CA1E266480DEEC39F5C88641C9DC0BD1358158FDECDD96685BBBB5C1FE5EA89D\ +2CB4A9D5D12BB8C893281FF38E87D6B4841F0650092D447E013F20EA934E18:\ +B26C758C740DA514E7BE7966C2E371F96C263796688A771A955005D907AF23D1\ +9C47FB0FF920CA3DEF21E13B4C827E4AD586DBC3D28F3576DBC6694F48E8BC37 + +023D91AC532601C7CA3942D62827566D9268BB4276FCAA1AE927693A69616526\ +76DBA09219A01B3D5ADFA12547A946E78F3C5C62DD880B02D2EEEB4B96636529\ +C6B01120B23EFC49CCFB36B8497CD19767B53710A636683BC5E0E5C9534CFC00\ +4691E87D1BEE39B86B953572927BD668620EAB87836D9F3F8F28ACE41150776C\ +0BC6657178EBF297FE1F7214EDD9F215FFB491B681B06AC2032D35E6FDF832A8\ +B06056DA70D77F1E9B4D26AE712D8523C86F79250718405F91B0A87C725F2D3F\ +52088965F887D8CF87206DFDE422386E58EDDA34DDE2783B3049B86917B46280\ +27A05D4D1F429D2B49C4B1C898DDDCB82F343E145596DE11A54182F39F4718EC\ +AE8F506BD9739F5CD5D5686D7FEFC834514CD1B2C91C33B381B45E2E5335D7A8\ +720A8F17AFC8C2CB2BD88B14AA2DCA099B00AA575D0A0CCF099CDEC4870FB710\ +D2680E60C48BFC291FF0CEF2EEBF9B36902E9FBA8C889BF6B4B9F5CE53A19B0D\ +9399CD19D61BD08C0C2EC25E099959848E6A550CA7137B63F43138D7B651:\ +919998132C03BB57E2748C5715C4D3CCD72250633983A61174E5A9B53BFD3ED7\ +FA7BA8698BDF766B31B29E387B1E44E1C10402C3A9F4FCE845865803F805CB18 + +20FF454369A5D05B81A78F3DB05819FEA9B08C2384F75CB0AB6AA115DD690DA3\ +131874A1CA8F708AD1519EA952C1E249CB540D196392C79E87755424FEE7C890\ +808C562722359EEA52E8A12FBBB969DD7961D2BA52037493755A5FA04F0D50A1\ +AA26C9B44148C0D3B94D1C4A59A31ACA15AE8BD44ACB7833D8E91C4B86FA3135\ +A423387B8151B4133ED23F6D7187B50EC2204AD901AD74D396E44274E0ECAFAA\ +E17B3B9085E22260B35CA53B15CC52ABBA758AF6798FBD04ECEECED648F3AF4F\ +DB3DED7557A9A5CFB7382612A8A8F3F45947D1A29CE29072928EC193CA25D510\ +71BD5E1984ECF402F306EA762F0F25282F5296D997658BE3F983696FFA6D095C\ +6369B4DAF79E9A5D3136229128F8EB63C12B9E9FA78AFF7A3E9E19A62022493C\ +D136DEFBB5BB7BA1B938F367FD2F63EB5CA76C0B0FF21B9E36C3F07230CF3C30\ +74E5DA587040A76975D7E39F4494ACE5486FCBF380AB7558C4FE89656335B82E\ +4DB8659509EAB46A19613126E594042732DD4C411F41AA8CDEAC71C0FB40A94E\ +6DA558C05E77B6182806F26D9AFDF3DA00C69419222C8186A6EFAD600B410E6C\ +E2F2A797E49DC1F135319801FA6F396B06F975E2A190A023E474B618E7:\ +F0EECEC5514F8001BD7AF333B78AE40E0D20944AAA2710EB3524236ABE3EAF3C\ +999DB788869647B5737B60FD4BE4753722C2CA6E905E030EFD04749BA46251A5 + +4FBDC596508D24A2A0010E140980B809FB9C6D55EC75125891DD985D37665BD8\ +0F9BEB6A50207588ABF3CEEE8C77CD8A5AD48A9E0AA074ED388738362496D2FB\ +2C87543BB3349EA64997CE3E7B424EA92D122F57DBB0855A803058437FE08AFB\ +0C8B5E7179B9044BBF4D81A7163B3139E30888B536B0F957EFF99A7162F4CA5A\ +A756A4A982DFADBF31EF255083C4B5C6C1B99A107D7D3AFFFDB89147C2CC4C9A\ +2643F478E5E2D393AEA37B4C7CB4B5E97DADCF16B6B50AAE0F3B549ECE47746D\ +B6CE6F67DD4406CD4E75595D5103D13F9DFA79372924D328F8DD1FCBEB5A8E2E\ +8BF4C76DE08E3FC46AA021F989C49329C7ACAC5A688556D7BCBCB2A5D4BE69D3\ +284E9C40EC4838EE8592120CE20A0B635ECADAA84FD5690509F54F77E35A417C\ +584648BC9839B974E07BFAB0038E90295D0B13902530A830D1C2BDD53F1F9C9F\ +AED43CA4EED0A8DD761BC7EDBDDA28A287C60CD42AF5F9C758E5C7250231C09A\ +582563689AFC65E2B79A7A2B68200667752E9101746F03184E2399E4ED8835CB\ +8E9AE90E296AF220AE234259FE0BD0BCC60F7A4A5FF3F70C5ED4DE9C8C519A10\ +E962F673C82C5E9351786A8A3BFD570031857BD4C87F4FCA31ED4D50E14F2107\ +DA02CB5058700B74EA241A8B41D78461658F1B2B90BFD84A4C2C9D6543861AB3\ +C56451757DCFB9BA60333488DBDD02D601B41AAE317CA7474EB6E6DD:\ +E57A285664BF66D2D2C7F8AAB8B75224A793C799D16A4774BC0C8693976F33E3\ +10979C84FDC302822542581BAC488F68CA0987E7147A782B036DD211DC798408 + +D1890B4704E169C28E44DDF62A1091450404910539FC2DAEB26E8ACF4533B024\ +E5215C2D02820DD8FB2CFC1743955CBACFF0F8F35DFBB5E3F942F36247F68211\ +D518F3F601AAE12A1CDC000BAB43D4C973F287E80741DD1FCF6C34F2E6B4B6C3\ +13D01C4FF3CBF9166F26946F18EF2D58271BA9233F09A6B77BFD4F48B36EB3D7\ +3D1133C4F842A7DC3907F680B0B773242C11E3DD973A44327EA7CEA9C0F8E07D\ +682B6651E506B587559FE01ED721000BAF570A16FBDD9EA29FA3DEF4BE912058\ +321A8B720C5C102E48A6E7ED6F8838D400DD57D06EEDBCD15323F86D855C94B2\ +1E41B14EC9E1BBC8019211FD88138C91F9ABBD9BB3914D26C1DDC21673D2D512\ +63B39D66E741D924CF2B192C5D2C1A140126A3D64A2C77BE6C2C6EBE8599978A\ +E90BD36CBB9AF64D078910C4094AB3BF399C34F2AB8EF843E9FE1BF88BF443BA\ +21E4377E5F49C07FD9653B526E14562237F02D11B904BCA6AC31AE721A43E3C4\ +910A24AF6F4D80C031C109FC0FE49F15274BCA92BDA04C3B4196C192F6CE489C\ +63A806ACFC895AB52CAD657C1783B528E12D0ED856E1F8FC91F2AAFDFA0A9249\ +8D68530772EE73B359FCF1418D1096C46B34DCF90E5B468BBB2970BECBD70089\ +CFB039D64CC50FFF5EEF26384D34F24515A6558B06A1FDD88F1050C5BD78CC6E\ +D83D4C2B0E882AEBCF84AFB0430D0BF09F2FB42B8B4589158093A7709AAE75A7\ +90910E211EE1333FFB6FD80778DA3BF73858978E9DD647978841B18001DBAAEA\ +43CA0C0A03DBB9BCF30CE76A6F4B2CF2A9B6531B3E4051E7E05090CD421BC66C\ +4731E7122AD129FC42DEDC83BB460E3F889992FBD3CA072686E56B72C720FBC9\ +8D723EF7F247286F77CCDDC728738E941B1A74D4F16671C21FDD5643A115DDBC\ +B88EE7EC67EA66FD2BCE718DF6E085D4B5FC71A72696636A8F7B3A68AFA51A89\ +6771FAAA7F1F827430AC5E8089DBC0D4175E1B22A057BC5F1724EADC1A41E78F\ +A3ACAA8B97E5F2E19EF9D59AE12B04E7F0E8A621E098A66910E2A5ED2102B824\ +CD3EA044A854F1CD0B33E61E7F737414B2953549F25DD34D19AA1981DE7CD564\ +9FF6C6364A4F25312EF62395A747AB88AAD722C05AEC40DEEA8EEE5E779EF458\ +A68840BC6BD5D29AD40F98B3AE010B6213372ABB7BB8B8:\ +53BCB0FD89D9CF4A3738A01154D2B280F03B1D68EF7B512F6C657A0264488CA1\ +093D70F88C08DFE60CD418E938D74FE18EB3D525CD0492C8BF85FD2B2709516A + +4FA3DF1DEA75AD4B9C379206A95FED930000482E5B683FD2B17DC8E7D5C4BC1B\ +73186CCC13C9FF2DD09FC1D4F68034D120E84CA73A00B71A3B46D1EFC6FF88CF\ +2EDA65810B098CC5E651D9CF064E87076D5A871849F3B405D3D58EF5B1F10520\ +A9FB4FC84A81A87B13DBFBF9D8674943E28C257E46D8AD7BE1785F1DC7C9B1BD\ +574AD1DDA48F0255C853D2490BD3D63DA22A8369CFD02594999A2EF443308FB8\ +298266A11EFA177102C75DC674E89FC9DCC1A0D3C863BC26141102175D2678EB\ +6E13D90BBD9A5EB89AE8C0CB47D7F340D3D32042A2762BC9BF2B40EB40E87FB4\ +2610FE7E357051F01494704FBFF73321B47301A0799B7EE3FE5E62200F397A61\ +ED4509A62F7106ED0EFB0ABD6AE9E4A1FE9B02C092DCDC75015CF602F3B9A898\ +8B609E6C0D1C5C3E219FF57875C2EF01615F89447EA602DFC94EEC17A398C014\ +BD346691FE209A002771DC8164422CD166AFB457A8B3071282178A3EBD201D9B\ +07B27E711E7EE7D33AA5210ED4E4E92486775D14A6CED092E34A7AC826709399\ +48FEC149F9C018FCAAD3FC597D315713F44FC5E1725F448ECAED40E8D841BD02\ +F1E81C019B08F99412E360C0BD378391C67D964B47F50C26F0A483ED66402361\ +6B0FC9AFE43620DBE9CCFE070EF295C049EAC754C2123130C6B2C0232F6403AA\ +7F0DC35A5999BF95D34AD612234C6289277ADB60E4F72EC2DF570F05395B3BE8\ +A0A3C78B732821AA08927C524E15D65F66A3DB8C1C96FB70BC0686AAC310051F\ +469FC5EF880C0F66947C1C328F97684EA24CBE63BAED8D114F40507C2901034E\ +6AB3893F366D53F1CFCA309309218CABCECA4722FA9CCBC7249B87C12FF8397F\ +40487EB00082E7F551D27E301C3BC7B5389F7042534BF7E692DFEA4DA24F7C34\ +B8D2FF145F54B517FC97134EC5AC2CB925C508D7A6BD01FE7B764648274972BF\ +08560D30802E0EB7EDCC57AF4797BBF92E8688268606B0F1BC901FCC22136281\ +665EC16393FA9601C4FBDB18CD1D1EE382BC07973903E91FFA87399D1141D49F\ +4F0C064ACF3AC9897891DF10BCA0116F2C3FEF180FE6A8E937C478F2EF293AE9\ +186DCB1F76B6E48101DF64E57EA7C64C5C0025E221C8F5CBA5CC92D9CEC62814\ +0996B26D17F439B780F59A999301122F82D0495F8AB5AE1EA5790F45E992DFE0\ +0D5F82A7FF1354AEFDCEFC0D2D1731D22FA2B75AFD4FDA25AB194055FA962838\ +1055247C8C7587D22E73C60136C4282452D47AE03AA035FEBC26FCCD42A1CB79\ +CF866DB6418A49FD8261E877DDBB839CC39514DDB87A8A40D795532626FEA4A4\ +C35D13E028F9ED1BC09B06BE999B8DDD2258AA0596BCBBF72AF67E10BEDD58D5\ +99B8D577A583D676BF5561F80CE5E9528729A92DF578FE75DBC70474B75747A8\ +D55DE70E57BDD62D4344DC2115ED4DD62F1FC98BFA1E7421FC0700025C46D0ED\ +1BEF35C3B778563211B9FA9E8BA4BBCBF01C2FB626AB7EF325CE9F468DF2CACD\ +B178D36557CD85D542C067C289E926C1EA2F20ABD329E984168BB6DEF1DDCCF2\ +14DCB6A53AFD462F0E7E7A19E8C88F049244125A6D7DD41E58BC9B2FF7FA2478\ +DF76AF73090CB1AB59E388BA20E2C297C967737A1AF61793B68ECD7439444C48\ +E28E2D09C48FADA5E0D1D15E5B340A52F8B3B854CCA479F0A598445E14F53B3B\ +A36891050C79673DF3E2B5825C955A29E5C9A22F3991D0AA785718CFEA1D2385\ +F8E47E4A75ACBC7988D0558D541D71C4E6C5F1CB15B60CEA0C34A67BBCE105D7\ +A896025E0254DE7D7AF724C9027D44B8642192A08AB8E1EF3046DDA6014DF7F4\ +C9E63C635E48AB2E70B640D480998EC9357E665F99D76FE5529EF23C1BDFE017\ +C3A66CD4EB2DDB42EF85EA0CD65534:\ +6A6ACBD03B4A2CF63356C7B40B1C11B4E407349F13BE2A5EE0162D511B053760\ +CA9869B3036FE9D68475BFE3957B7007E0380F174B2CEC30ADD94DB65E43B4D0 + +523DE8B1F4CBB65E81FF0B6CCD6EB8EF0A0F0A691ACAF4A77F25ACD2D66AD4B3\ +EFD25BE70308853C094412A518A32020E3020A9F6AB32F0CD60EC0D7A194917D\ +6C457B168A54A4B46F7B0D0C71BD61CD202F4C718776A701E0770B0EFA054187\ +70F98E4E79CD066366FB3300E8BE359A98B82B764BC2FBBF59C7E8F94A157B01\ +C6C7577B1428138CD422BC47330F8ED99F4C0AAB0D984287445539839389EE08\ +D6345108AF26ADED0EC1D7BE774CFB8C5205DFE07CF6CAF8C1AFE37C7A2E4FE6\ +013B93EB2463DE4E0971C7178D6A76B16A0E8960C984CE8BBE71B3B466EDF044\ +5B835F09414D01F14C7B6167FF78FF118127BBD5F812C27FACD57B3B120E2BCF\ +E87315C7A92B82EF5D50CA14A7174D1BEA7E056523E055A6AE42EA3765094E55\ +44E5ED003C989C2F98F38A17E3DDA74DBAF9C669A319638A2698B0E4A611480D\ +8AD3CF016792ECD1034925F42B9811A7214D623D047ABCA31997DDEB03275F80\ +DD21F40DDC80616E7AD3D481E8EBC0A1A6A398E16A78369215541ED10B75671A\ +DEB1AAE6E11142A1CF665FC1B7332DFBB0E10C21A2B48F78E57319AC9C58DFA8\ +B1C2548E2979EF1ACCFEB215AFCD6C2C1B46FE97DD491758378330EFFC728366\ +1D2CB84FA05281E9E517408508D24D042E7B9BCD34DB87CE972E4CBCDB98615F\ +B93093369DFEDC782F44BCD03E81CF93051318B2401FF29F753A264BDA65AF19\ +9E3FCBB8B5D39C838A67D6C7A3DB046DC56C323DDBB5340CBC229E47CFF8C9D2\ +9B7A49AC0EC8C1440AE498C7D150EF91C29BEA7DF3EFCC2871A13A1D72D139CB\ +4603D9FFFE85F6DDD544850EF63C3944FB35DBC00D4308CEAA6394B6E23F650D\ +323F8F7EF50DDB68F1486EABF989BF44451F620EC9485C0B52D1415D3C909A2C\ +FBE9D77DB19D069D33BAEE4D77292E63FCBF65C1EBA24BFFDDEFE95211EF0AAF\ +8ABFDA9F94445E582976F986F5382CB669506AF2B4A5A0C43000A3C72C5CA4AA\ +CDC9D3D39FC5C492A393B6C341B86DACBBF6BA8B465100CC683EDB2D9B9F83ED\ +F9C6A32645F51CC79ADC22A52A007BAACA618BE35E356D1FD1CFBDA73F1ED092\ +53039DEF609450FD2D5943B9CD49CBD52A318EE3510D7CF3FD8FB388AC6CB9C6\ +EEFEF3D3CAD8501B91CC04A888D33E16D6A4C9666F5F5F3B257193F2B46DEDDE\ +11842909D8C48ADE57775B0B272E2DC9CEF1A083EB2CE58F4D1F211922FD6ADE\ +D1B82FE6F5B11251CD396E5A3666ED9626036E4E356231C146BBA0A91AFD3648\ +EB7BFE0B9C14F15AF2F92309826F468945CAD0AC422DE3D6A773B76178422107\ +CE0270E7F580B5CCEBA82CA0184AAFA8341141E65E39859885768FBC5CE63B96\ +5A0604B659E71D9DA2C7A43646088D8071D76926163AAFC69E25355BB0A222B7\ +B2DA9F0A20C021ADC462E905A9C3BF31C16D87FBEC3F014F3957A720F1432E17\ +41553092052FB58A198640479ABCAA51B104CC93E2636E1460643EA812BD44E8\ +19C2166EB6B349BA5BDEBAD59078910B5C22A56F004B8D9E4B1224D8D204B48A\ +BE7355548A402736C5CB110F3A1476ED631FF168F4F3EFD89B38DE4751536548\ +647523D334FAD7CC2D142973F2DB3C1FE08FC5CF83F9F2BD2DAA524B37864816\ +AF29EE05951FA09D1C51D9D14EE4F72FD7BBF18B1A724FF5A0958A063947C430\ +142AD2356E4400AAECA442E163372A8F1CD36E2DB988E7781165E5D4E7074ACE\ +40858E8370E883694AF09977704347FB735C8717C42BC4EEEB2AAA50DFE637C6\ +40909CE379BFB9E2608F88751377038D1669F248178AD580A908D7A1B8DCC7E5\ +3E01801F1E485B5893F103F03E0F53B2B1440BE95644D85AA7F6EB7EDFBB4665\ +2196695EA23C08573397B111FF909025E20C5201293B4D223BF7AA01DE7CB28B\ +94714370434B9588097E2401B62C7A0DEF1FBF89809E810749FD3CE9EC3C07CE\ +4BF4C43DC966429B2BEB4D711FC6C448A12097B36F1E6817EAF4937A983F85D9\ +CF3E62CC1B2AC6AE1EC9EAA8CD8EE2C3322239CFE5DB3D4E8786282E630A7D25\ +9C2FEFECA03031C960A66A71E436A3ED6F2F3CFAB4BD77C660D14205ABF606FE\ +561A346F7D849B69475AC9F6822D80B9A2E56D5D495E4B309B0EA963C9FC5C7E\ +F94B217EE5337989AFBC7107D233A8B362AC27C4F69DF9E191CD65AE97D6EB9E\ +5484EB6F10349575E4CAE51452380151F902415AC9CF42C824EB23C9541D2DA1\ +C26DB85F53CDAFB06A12B8393CD580A8E494EDB6710C720DCAE30832967E33E6\ +303A92B1DF0841D7724284FFD2E00B95C6D623B168D21AC1BD3C675EDA33182A\ +2C22370998DE1E5EB905372CC6EF32D5B765F5C94870DF4842D011603BE4CDB1\ +C227E41EB2F2E8542CD325884FEDC9C5C7BB07A92D20D64B836215C59F162A3D\ +A8BB67D6FC13FEF97CAB6ECB8A29E431A6519A6261C4521CCB90E6E609869E6F\ +E398404AE047F64EC4263566DEFEE66329DD40AC985EB8A08D26529A544891B6\ +F57CC235C63C09057AB6B6ED720EF41A3C9AE65768B43F6DCF4962A103DD93C2\ +13171DC2C9194E43265C689B49331450281A3FEBC618D1AA4D65A135137051FD\ +46B568CE294C89:\ +DE11315ECF713973B7D6E548DA33F68B53D8E9BC11F7E89C3CDD334EF748A58F\ +84B03B296F1B05357A8873449CDC49CEC6C893A629439B48B6DB517F4B0C9773 + +F5080D4C59E804BF8F34B334CABBCC7D32011BDE3677F4B9069416AC204114CD\ +9DA7A0ED0F4B4D8344416336EEC15553EF526B6DEC267B1242657DD0B508AF81\ +FECF9CFF9C82A6A7A9539814DD7E097615EF15373836B5D2F765CC8D5F82E904\ +49F13AA741D5EE2FE63898E55ACD85116846807606FE1E2E29F98F9940B067D0\ +D1DF01F080211B2EE4B0A30803782A7BC2EAFDC5EBDBA91EB05F7D7DC8E34BF6\ +D44FEC05824F53418F235FB64E899EE147BCB403C8855E94AF378D182D79C3EA\ +F977CB4E9D4A16D990A6C388CEB567B97785E6F2BC6745102B99AE765E960B6B\ +32BAF01E2379CD6ECB74D3E1A56552F5976DFE5C742BC92BE596CA742FFC3D0F\ +A032AC29F9F7C1A5C43BCCA62DF7D9DE35D0C7C179DB2E1AA255CEDCCA55064C\ +2049FEE1AF2CE5EF696ED4BC46B7C55BDD51F2D44C8713FB2475C0B85246AC01\ +03CC3863B7EB026AE076A600313F6FB40A4DF62A2AF81B7E917951EA870ECB31\ +B3401928B5046D9A1E62D14B30FDEBAF262868517318FE17EC3C0D52524F4412\ +0ED8ED3BA70C643300CD0BC70DA72C964A88F52C3A91EC20BFEB5CAEFCD4D9C7\ +685D8407476B5F34676C5EBD1E88A6CFF1C625322F8CD59B9ED60CEFB21F9491\ +B95E72791F7AC7EAA3C16159FE9DF7A989ADD6C2282C47585E11397EDA9F47DF\ +2B40166E03BCDD6186B46C6835118268DDBEF19A28BBADE1BDE0228FFD7E8B3C\ +3C598D89E24B8CDEE79C940254DE26CC6814BA2722E42F7571600B7325E1FF30\ +0251D52A895B8CCBD049B2953B8D231445F68F7C26EC25A4B8695C8AC116F736\ +BE939EDD762C9B4743E463C9B9B2F88E0BC0CE78781CDDC3BCA825ACD463C7CA\ +C2AA6C430BBE820EA94AF9A40B1B5C006E9641A2FFA6E427379E1AD49C81B983\ +20B3431FF0030DC683D61026438BC6A6D34B2C73704D9F62EAEB13ABB3E4B056\ +2B4E0482CD6B2D7AEBC0367EA29A88F4A76F3D76FA1197E1DCA92C8216C84C1A\ +F9B8C78C9E3A7799A4A79A783033B0F5547E8E75E69CF3615AB04EF989FE1A46\ +3B1672C571D50AB56972896E8A50C242F22C7F6E27CA4CA793F627E79608680F\ +5421B28BDD2589F05E65430DF774EE873FCD1234064F7A33CF5A1FA4E368137F\ +F9C1597F1FA0FA36493F20538077669EADFD3B06F788C912C715FB5D334DB6BE\ +D133A8FDC40F5496E66AD63881F0BA3727416715865253DC5290327B515BF68D\ +A188DD5B4B0EAC7CA712CAFA8FCAE0C5503FE58A219182F1C30DA6D0C19CFEE8\ +97B7D837C97996A35F4CA8CF0537A01D17E7DE0CC9C129E4DA0ADAF1FDA85030\ +DF9127BE628263B0624F372C47C3AC87EB945A57F5C732BEEE81A74030017989\ +92F3DC944114FF3D54C4666AC5AC8C98D0D5596CBDEB420665F5EDAAE747D54C\ +F7EDD37B162E372249D135938CF17D174D12D88279CB4C32BD6F018C766DA698\ +3D4EA51D6BD8FF0A9B34E9A93BBDA70CF1B4B867D60A74811FD98D52FAA559B5\ +2C755CB70A76C94BD19654CAE7017CCD70222BF08C5D7AD1F5E4E6344FDB3ABE\ +703452C29A696F39F9826ED8BC510A4A148E5BF8A5DBE6B82D7220164F08011C\ +05AC5159D52CE9D45D758B645BBB248C2D341DBEFA1F8602C5D458A64F38F3B0\ +4DB39089807B6A10E1BB52770B92CE72E2D3BB0C2241CDED35054B84558D1CC0\ +99EF7B2296951951D5B6A22F93BF962AC5EF8FB55EC6CC2B316428EDF12078ED\ +1B66D525D022819CBD489E1BEDB02FFBD507D55F9B5D4E22F6396EA233453754\ +688D20151A09C70044B8A5A9AC033C3C3B847AD833D5C05B33407666EE82F958\ +1DF9034EE15A9CA67D52F1D9B634B84C1B8BA9E515F1F060A5AC5CBAE2DE75F9\ +4E112F7198E239DF08D3103F065627438995026DF511C6E5BFDEEE5667D511D4\ +181850C7C5D179107C1B86D24D5532A88A4149A2810DCAE73731B0E1247281A6\ +FD31613DF6891B4C17B7A6A9AD9B77468254B93F85958AA0F01CEFC10B25169D\ +C46E035D3F24557B4BF0E7D60174219108D916FFDC55E25BFFD9809EFD058E12\ +C14F39C69D8FB73D3EC6458F47F2F8DB901BA76C86550B11B54D0641D4DB3EB0\ +00057DD00F2E511FB7A47E959A4402A3AC5462234B40B184020FCF7A0396C4D0\ +0A987C8741A4537BC17102A5C42AFEAB9F71EA66ED4CBC7B5EE682FF04F56F4B\ +A1EA0BB326C4089930F9E3F3FFA3E06637CCE32113881A06CC3A13837448145C\ +2BD01307A580FDBC385D8F46FB92FFEDBC8918D269DD1871164D4B3E2023441E\ +C8B99C82A5F09821CDDF6B38C9ACC3BF3A38D5628016159588C33EAA29D9463A\ +537C000A16AD8C177DC4CF716E625F46FC4CA8C19FBD8EF320F1D680639195C8\ +B195B0A02738E0665F4190D6287E589CD6DD45B9E8CC23B08E1681BFC6F66B88\ +DE6B091E825EA4BBFBD697E10BC407570AE4F2A3EBE569554639C2B8E051656C\ +C30C837F5A92260EAD1D552B45801B6D28134166796C87F900225CFDC3CC49D7\ +2DFBC18D8D95B1E160ED3CAFD5C3467D48AFF87402CBCB1E1420E3FCB588AA19\ +C8F42753B59DB6FB6A9FDBA127CA806DBA7DD97F2488FC2E438EEF57A4CC85B8\ +8DCFDE76AE1FF61225A1CA8BF4A14F729950322EA681B16D6492902506702DC8\ +F348E4D3AE7FB55FAC1231FDE82091B34F1791B6AE37587B10325F6FF5E23B85\ +5845B86EAE90785B9D10D90A16644D01BB626F343B908A9591F4069B21822CA4\ +ECF985C1E710475F33DF9AF4764CFB0FFE649063775338F15BEA7CFF29F16467\ +8160960A80ED148C9B7FAA58E9139911D3DD9536F69646F718F083DC9029D629\ +4FC4C607688AA75AF350AC2C0B001A157D023D73D86ED8133809FCB9592D1208\ +9CBD7A1BB6BBA882FE227C09A53FF088907CB4BC2FB4B7F62D41D3D397C4FE0A\ +D12BB3964370E21712951C679814D506E738C0201E42181D231136A435AE0397\ +B61CCBC5E8BBEBF8EA77C8BC48BD6211F29248F9D498D818E2B544D28A5E60BA\ +727F32EF4BA2707962230C900076FB764D0ED5CE078C9DB14DE894BBB836C6DE\ +9E83202AE89F9A8D8CB0341E1C81B5FA8B16731B8E231E969C0F1EF95336D4E7\ +3EAD6DA23DE3AD1EB608ACCE4D4D93996DD76EC1F5F2C576F6B3B76E07BD8A81\ +0FF5D88B00FFE48C42700B61CC499336E7FB57AD72FF44FC631C7222C9A3D1AB\ +F6E77B5ED7FE2F7228FED6C849BF7142C4103989A80F7C15642AE61650CDCA7E\ +854EB25E9E72F4C3E3768E6CCC8BFD556B56D3507EDDE9E5C331DDEA75568B07\ +813D20E8F4C9547838ED28448F2E67158ACF0C00B131473847816C5E2DC215:\ +740168046E1DE04598A62F5B92372B5198F2C44F579094D274EB5171CB4CD777\ +0763D54CB75D070184921C3CF65FA371E96F8FEC8138E7E1E1590CB0CA26007A + +08944CB473B828B118A31986DB67FC757F238182E790553404B792AA4F0095A6\ +A83291E287CDD16521A3AE8C48F56FBC909DFCCFAA7BCC570C2159F26592DCD6\ +B15BC4DD55CC05595AC634B2C3DE15360B0F07A03B5957BC9333CC5097919399\ +DD9973ACE15E55940178C4C96BB5E0A0A10BAE175769548EBCE11E0D7D9DB296\ +47F197D4B87F7039F5D4E59E016531DBEBF55A797AC9A6835032CDF34240A7EE\ +7423E89C09124829CAFC5F89431C8AFC54FD979E50D48A82B47A53523C84B600\ +4DAA323EFB708203E5388A6A5110C6CE2E341048A65FDEADEB3837A03420F9FA\ +DDC3F02A544F1E46D96B07C90C7971A7040A179E8198E90AA019268E00367120\ +D5F3D98A5CCE82C885E77144B1AAD66EE682847776B04F01F501DCBEFE390308\ +0A8058B3B8F1D823D917ECF31FC2D5B0795BF95A55C7093ECA7C801DD0BD0DBD\ +BEDE7D56513128B29FC0B4D25A6240B24C99E017BDFF7ACAFC8F8DE9FAF5A294\ +4384AECE82BEA04DCCC6D51FC6E6F27AA38F131B7959B13681A09B311D242E62\ +22A1CE5687DE5C080508B1DB16B6F8290D33A3CC0D0138AC61FD9093825E9D37\ +52889E9F20DB9F80F92750EAC88B38AC81C0016D40371EAB4A87E845E91446B0\ +A07081B84F559CDB95340CB020AF22AEA1BFF2FDA12F7A42973FF163A1C6F33D\ +B8B8214AE27ABDF1C54F5B03E29310FA210125E1296E8AF93A2996DBAEFBADD4\ +C51C2C3B8A3E2BC9FE060C42BA32768F6992A99599206CD2291CCC5BBD50856F\ +7F8D2D0AE1EFB5892C15A799B77482DE4553736B162ABB06631F1688F6746E7D\ +7A37EE7EF24E6CC901175F04960C01990178F81E957E941DEAAC8846B3704E24\ +204F43DDB0765C433F3F7D4D201459CD65682B7DDF3D47E95CDB31B96A4CB229\ +07F08BA6E92A4A07703B2DCF150F922C4B7CF181380303FB72547847305999C3\ +C8F9AC877D05D9DC4159DEB8A13D36AD1D533A56950E20F906D29D51DDC45BD1\ +5C1773991707480E37B827044BDC6473181B760A9036E0D3FA491C2F08C55130\ +D8CDD5AC8E97D0813164AF3D28A585F0C2EC7004D498F95C6B62231A632A56C2\ +D0C48FC3A6992D4051957B9ED6D9A86DBCCD962A8883CF82CAF01DA2F51A203D\ +56B6089BC8FD0B1BD414C8063031ED469555E22EF872689C130B1C101034D572\ +FD8CD0EDDABEC9EF1503D7F728B0941EFE2B9512438C7DDB176BE2EC2D9FFCD5\ +6495A4511428DF02819CDDA18D1ED5D3B16C6F42AA0AC681A9FAB51E8A1A856C\ +15C51A3EC1031427142EA12543014DD4ACAC640B8A7729E63AB7DF1051112CDE\ +FD4B988A2258334FA9A7F5B3A87A02074B9F69DD81B83FC74089A91D76AA4041\ +259E80FA255F2084902AEB9E996AC2288AB464BDEC47AAB26A28A2A819498975\ +5D48FC9A5C9279285F2F1DBB8B8018F3E4E13115D78A879792E45A8F4F24ED4A\ +317440BA63E6929056EFC1D2529B75A709D6C0097DC2D97F646F334EBE6195EC\ +5630132FDE58E25DBC17DAD822D9FA0938A2A2C926B105D108403DC29CF371C3\ +504FF73BCE9C7ACF9A74C4954CE6A32DA96B21CF3211B3E49953DAB78C49C3E5\ +32A349003C59C62F7D40261CBA63A9EA21C89A38AA63CE431C43AE261C4D9999\ +B1CAF491FAB8E7BE6E8C3454F1BE8793B2D27141FC107DA599A4694C41353D77\ +85C05B5E31440458D17C6DB66FEB8A9C5C073FB946A67AC0312BB669D9B12FAB\ +AA5272CA6631379EF4ED420A4424A5CD08526384C047C33A84D5D7DC0C215366\ +3B54C73DD799A3568C01B818992CDF8143F1DADD6B50CAE6EAE13AC66F31FFA2\ +B362CC4D2880592B7FEE4B9E4CD6AA5E5DE27AAB9B5DAD9F7D39407AE927530C\ +AB2B61CD7394A21EF47BFB813B5EA6091458D239664923280ED0D5CCA8285BB2\ +281A2F9FB3FFECC8E9147E1E8FAC957D90C9E5F513738745A47C2AD0C31FD898\ +6EF3B6388C6E821F166513811D547AB4336B5E04643497FC9F8D6E380EF6478B\ +82B6E2F5F65DD98A63C68C32B94610E1D3B9538F13A7688FBB1EC3448BE9BD77\ +BB93A34546172AE8D614F85228988E7FEB18C9A0C9827699E8B3CBC69750BDFE\ +CDA8268F694F4C509BEFC1A1166F85C829725299D173F867A300987A2D36D1BB\ +BE37BE3208FB8EFE9152A41A5F0E931B6382FF7F9B18937958FB180E61F2A8C2\ +8F36C3C80C3722935AACB81C24AA17FB3E7A1026F7031A7449818ED62BA7705C\ +A27C2D3268F90B6322921683DFF800A306CFC186CF2A61B37F35837B217E3B2C\ +ECB0843D84EAC67431E3D689F01522D4A4C73618B7C2965C9DABB15C0BE637D1\ +0CEEF72271CF39A7B803B41767BC34433C3E6FF449A439AE13DA1EAFA038CB9F\ +2E1C84F1CE39C05DF56FE3D7B82386C4E628B6E27CBC5D575C66ADA3510C246B\ +D04DB48F4AFC2D7352966DA2266C2BC9831532F53655D8BE42B421AC0D70D8AD\ +1D3587257886DBF93668E907E861BA64F45999BADB0F766EADCE5238B5ED397F\ +265935194812C03C5769137BAC97140525303CF48D65F39004A3F59B1FAB0989\ +5CEE05335D15B9B12265892F4ABB92AB1DD2002ED00CF3562CB67DFE1055968E\ +4AB3306BB34BB87D0F64B26848812A2F7B50424A21FF94081A7F70F7B684AB0F\ +092B2B085DCF84CA38414CF7290F607BF79C37EA84253ABCA8D4184D2DBE2E90\ +0200B81479E1CE8B71DCF2BD6E3C557A8E431D627BA669C2EA03068E0F7EA62C\ +29777B22142D7A1D451BD541EF8EBDDBBA4E3BD8FFCD340E935BE7C66EFC14A1\ +3EA48134F655B0DE3180101F09D204C379743A357E6DF1268B55A9F7524398EC\ +F3A59849A27B142239059998083E8FA91785E91C4D220B2FB17E3389EBAA384A\ +49D89B5D78136DD2454F06CDE9837F096B744D53221127869904AC227CDF30BF\ +EA78CC5545583F999B9C42A1184E2FB9FF3EC095B9DA0D138205C4EAC4C8C480\ +C43153608849F63E161135C79D8B6C9CFE9B8DFD8AFAB559D8B595DDD4383503\ +3B4BBD391E028BB2A60832D9B697EE61408F149744DCE71AA11BB2B0436C1E26\ +26AC3A27CDA293366B90B9CDE2D927855130758D3946B867192DCF3FCE9A3B9A\ +5276E8C37B8CB136FC90A6DC22650F95E796A9886EFD3F424BE63A66DBB1041C\ +B3D4A06F4E7EEE89F0B6D15C36F9EA010C66B332011C8888E8E4AB2B3AB52231\ +91E1388613A0FD0F07C1B26D7CC7CDF1AC62A226454D6291B431CC3EF2DB2B24\ +42B37DEFB942117FA247096BEAE598611B8104F37BEBEDD8BB8B949A89B5BF8E\ +228ECA1D8F16BFEC75A02FFBB4EEE3A6D4A6087C43634D675311E72A9F3253BB\ +5DD364E07EB4B9C84F586BA267BAFFAEFEC79E03B83B18595FE06D7E063EE604\ +FF287004D141C1A43AF0CA7C5651D98F633FA875B4743353FB07BDE59B6567AE\ +25F7095F1D9EDF30570E2F7D7EC194216898D910F9E295A41DFEE072CB56F914\ +BB78CC9854129250F9874B63BB3EBE9A1CDC6EBCB0916E1C440354DED6AA818F\ +2811DA913912A21D3961AC94A39F0827D3A419616905DC45842C8E69A43004B8\ +AE922C8DE1E8CD0668674A7760153213835BC63FAE4F8D65614AFD74A34D42AB\ +AD5025B884B34639340B45D49CCED423771916E18AA077291923017CA50795F3\ +B7A3F349A3D29923833CE57801C631576E23B838A7767CA1BDA92B82AC502DB3\ +688FFC83C09A4E40CAC31D20D9D32FA6724A80BE7091CDE9C7A6560CFB326B46\ +7CADDB9E9B7A491EDA283EFB0B61B4A1116DD859D5C0897EAA2A3FB2CD82FFB3\ +3770BF9E08091363B6B81D23E61C2A647D2BE440C5C79EA89690656D9F10B1F0\ +7942834E1CB6E2D2DF106EB6D6A21FA23819E65028515E88BD279F9317BEAFFD\ +394EA51F8639371C3A89F11305A4CA35FB0711F5E2C7C3DD1659C79024581211\ +3204B4ED8AAE9FF09D43C6DDB13F5070D98831B2C7639FB6B9B01C288812DDFA\ +8861DB32DC8268C07D30CF969953042B3DAD530D9D744C06AABE7A886C0FE57B\ +09B7F42D193FB3E9C06329818251A2F7E6474462C95DED:\ +9EF7A93FB957D1B7EF09E156186699159E65461C9C5F478CA8F1B25C6C6AF982\ +AC15F65E57ACD3ACACA75CC15C38616E0016685417E37DED05B4FE579EE2955D + +1A3DEAFCE70AF6F3F55D66AD9CE78D5F4D5C5F2638A810AFCD07D67E9F9A1380\ +D6B34BE482EF030C22F1E978F544609CCE35A74C5109EE7038495B6210CDBCA8\ +DC82C6E9E7B0D593FAD9665382B3C401AB8941DF71307DD77EBAF140AA66A1F7\ +6316478850E58886A9610631E9C722F459FA00C0B53124FB4F12778BBBA37608\ +26D3DBA67CD030A96B654AF93F8E395F5F439549489F8161683F124BC980E693\ +9C83A6085E4B6CAAF8BCD89A0E01ED70DB487166CC29735D9235A9CDC57B80C9\ +C2E591DF6322F5BEDD32937073F781A30389552AE83FBE147D1B3D3461A3DF96\ +C15CD96900C56718EAAE838417057579115936862679F5F2A45DADF65D14108A\ +F1641DF987B57986384FA1433789F5DFBE87E90BD4E9D8D4D0741FCDA7348322\ +B967B566B18612DBB8FE64F151947C3F7E361EE868676BCCD0CB3A1AFE046BE7\ +0057A05ADD3E65AF31E3FF414A627C0183E8FF583B41B75B203650420216E6DF\ +CAB289665F054CFE3EA0943647528518573BBB1D0F27E1449E98739EAF0D0094\ +32DF0C1EDC1625264B94A71DB762659FF5A3A7A867F182D1F1FD34B341A4A181\ +221870DC4A494013091A7E3B2B07E0160C438F1EE1E8A2B989C4FFEC36B5083E\ +A427606767C29672F44779A8505B422B25A56907F565B27690D011426A62DF00\ +36D57D967CD1D14E915BBC2691E7AF818C769D9E1F9EDD40894BE88FA1D7A595\ +2AFD898E837716ACD73953BF2D1D448123FD1A0276D2C2EBDC760A4B787416CF\ +AE5E963FCBDC8B551CB70F91DA0ED4A8090FEF178E879F2C34F3A269DFFFF097\ +72D44A13D7A17468B5834C460957D5243C325F63F05F89D4ED98D361E7F0AB8A\ +83948A64D0CFF8514841AA21C7F337920A9983E59BE4A0F1339E1E462F92DC1F\ +C070126206012458A499A8111FAE078E00B0CA3BC1D6C7087CD318D5603C1C7E\ +0425E6F729CEECA5F35B82F8A42E0E9B950EFB0904C5FB5C06D91D239913665E\ +D1F1EE4B82185A01BA86CA2D3EA94E5A8842231A94C05280183B7ACA28998410\ +3F122203EC2FBA4A382E6F5236D6F68DA05E3BB0C558421F0EFAB91DCEEF6D1E\ +CDC60F9B88F8BEFE31CDC3C2F024A1AF2C7336AA5D151E8CDA814A5FE898BADE\ +B9DD680E337E682EBC22BFAE445417E37D2D89A338659A280AB1206DB74DD42C\ +6F25639C1803BFDF2156DF613B0F5924D209F7F9003CE8794F989F4F27B82121\ +210F4F65EC5A1F7723305CEE438C41F793EE04496BBE337BBD2FD3023830B1C8\ +889C6F4D0C1192E364EDBE1CD987BA5D66224EE9C9405E1DFCEC0EEFFC5C73D3\ +123F6731C6295D1E6B854B884FD22B6A3BBBE5395312585CD138BCA67532C6AB\ +71BEBC6657C50DA87D2AC6068FA3970202C5E15EB7B4B3D2676C0134BCF1EAC2\ +B26BA46930B5E660B16060894884C88BFACD6779276B86F685AB6F17C6D53F62\ +1275FAD66D021D26D1D480AFAB4B5EC75E0E763FFC45F599EA02504DA5D91EB5\ +EFC3E4AE196F219E45E7CB05594958C876FF474A020EF73C1F09B1F7F7457E81\ +6D3AF51D86663D4D461754CD5E907456691E02446D6CACFD33516206A3187054\ +3D574592087773653D4086C2BDCBAB3C9B65CA11AD0D4E58DDDA8B4403099898\ +57103929549B7300CED42651D4086661694092C42875CB62858E6D1BE5F7274B\ +4BCD83AA4DA05CACA186A30902830790F9FFA24418E1F9DB00FA40477E83B05C\ +2D11AD7D81DDDB1E31F94A9DD5E9E13391C22479B570976E3AFC1BE41086D3BE\ +6689D87CA4326A7CDE8E5B396A678D3CDB2C80FECFBA2BC799AE8B1528E96D88\ +0CD098DDE910D097EAAE660AD4D7EA51C18F18AA1B39614299A172512521DFD2\ +31B9840909839EB69C892EE23F1BCEEC1FADBA75786C7DED93BC9983F74CEAB3\ +97EB8BA84F7E4130B34258D628594A6F9E2348FD91BA2594E07B8057E8A2AE3A\ +DFEA0EF919555385977041C5B6DC4F3880569171F7217AAA9A85F2F5BBDFE3FF\ +DF79248F2A35FD4DEC34980C67290339B1C0A5A6AB8838157AE2F5140B4A2492\ +4A6688AE5CE72A48103EE9029CE8A0F15B1FBB19A12FAAB80A7CD9C0E389FC27\ +75833E3190F1CF735ECDFE7F6B6C326506AA82613CBEDA8DD3691B81F4C1E3B0\ +FC32D7E6719CBFC12F4A26E0FC29D6417953ABC9568DB4ED9A294B9FD5F2A666\ +DDA546ABA301B1C60985033953EFD6F4538333B5C7DD3148814A3FD7927C366F\ +40B3D7ABBDEB2332DDB586AF80959097663CFAB2FEECAD6D368AE10EFF9663D5\ +F8BAB95935D25F45776F7F04B46817D05165A9DD4770509ABB92F8B9E7373CA7\ +80703569981754A51D6D376D65C57F55CD70E2DF5FDF5A6B829AE30CE3BF9428\ +15C8B4BE858DB58151D02A68AAB9FD373E047EFA51BD1A0CD1B61744D9E97CEB\ +A3334B3BAAFEA3BC9E43AE097CF2C3D713EECC247FF43EC74D54907D8BF45E45\ +B2E0E11D82B126A8179D3F66C055E11F69EA67AACC5FEE8AF01FAA379E51998F\ +5070F9EE0FD30A2EB22A925586FB1B39024EB5EB1E127C76A149E7F02AF1B73C\ +16E9E5A5DBE378E08A9FADF1194C625132AB3FDEFE8FE9A89BB8E0035A1A3AC5\ +278F5D3D0ADE0E41C81C6853A41C4AC45BE3F68180FE23F27F18BE2E339DE1D5\ +59D75DE63ADF7A32BAE42B037AEAA3E123A5314891BCD35CA48D57DF4C17540E\ +97202A8EA1328DA25B1FD6BE2B56AEC1E5DEB209F3B7A13ADB1CBE53EB645956\ +E577A7621D74E42376D70BC5C4AACD239A852FBB7B3F62CF59FE10438C1DC8E1\ +E46566325DA0CA43AAA63FB7E0B450A2DB3E3A2204704D894DB24B72B3078106\ +E096CD543DCF027650CB4965E38AC36A8AD588C5962B4E26548AB88F0BC20E10\ +ACC1C3FC00EF415B3C32499264552B14E2C0E789A3B8A8BFF9620FD939D0B34E\ +806177EC696A4B3B1CA4B32BA979B2690CFB3A6B17BCEE6877FFCE757E4116DA\ +01099FFE82ADD5A0C593E73449A96DB9CC2B9E846D166B095174F2CAF8B35DD8\ +78C836D9BB6EEEAF8E1BC5D0E149C739828CC480D731DC16B35B80D4AD82ED7D\ +29BD05018239EFECF8DEAE180C6A459DBCBFE4AAB9A5E2C1E1BC31418CF2EEEB\ +31FDF8BA02C9A91525E9163F672BAE2EDEC38C1BDB84EA237B4EF86BF5C0F0FF\ +E178E3761E82D94F66E5EA40BA8170BF768409E1B4177AAFD9937BCE3FBFF590\ +320D7C445372463FBBFB34F57447F42C16E026F179CBF82F617C86D1E8D42F6C\ +908F9C6B77E38D25D51303DBD781FFAB569B4CF31FD0B947C45E1768A2E9DFE8\ +369F520DC38D77937B69B821DB4FFEA8F50EBC404F0587B5598189F54B5A5B98\ +966FD16801C87DE2C3C7813DD70DC600824D426D88C55E89D47214D59206A7A6\ +5A65DA7CA2E42FA62ED17E7AA5B3ED446BCC71F17FEC8593BE96D2037BD07F94\ +76D4D732B32BC5DF8C921316B45699004716FC89F8D45BAE402C26DBCDF1A340\ +847B932FF882DBEAFBEDD252E126C89A1E1FDD8908A1F67D15D8E432DAD8E08E\ +950A3BC46B96CB89CC5BDAC703B3FA3E986EF1C6E7E6606E6845BA1EB2FBDCFE\ +E744B5E45206F4A419E1CB103C8490EB293EE9AEC1F0A0D294F9D3847737413D\ +30873F3C94740E8FD072817815EBBCE3F09EDEC9D1211A9E99547D620B2EC56C\ +89E9CB8144AE9E46636324BD13C6CCA3AB9CD9FD8F7F937ABABC598232384427\ +A2D4CE0CBF9765F7225E208C3CE128602B0AD08A1BAAB77EDB3111F0C6CA7BA0\ +EAC9D89D5B4378EB82C17F6EA08308A79A53D150D3F85EFAB77294F02EE0E288\ +5EE2AB2793392B87DB11FA77992F5B4FD75EF2F1A822E87407A4878894215AB8\ +9B6CC4A120F5A78B3C31AB80FFCC9ACEF53FC6F7F85685EB9D56D30D87C21ABB\ +F1652EEF8F32C7C567BD1F08623B09C29F33561D42727A5649A3850071AA6C11\ +735AE63C4FD31559CE560B27A362786A83353FE460B37074664A9421D3B2F6A8\ +64D5ACA087187B27E2B82F31CB3DF5E985CEA271C609B94B4E58356D40C7D5C7\ +FF2E5990FB39588154843EA5FCA92F120075D4C4D006661A0FA1B0585454BEA7\ +25473EEF7D58117D5840C8348999003736C5EEB7858FFD273A1C3EB2812F5697\ +C59110275B08F6BEFBE84C92497D5F73B7B6F794A849713B23AC5F29D5C7112F\ +B2E7A6E89EB54DDFA3122E6C79624C1BF25EBFB9FE5CE6DAA779F3ECB2984DA4\ +2F8C6ADC77B21DD291E684FCA50E46070962A2D4F00813D8DE1B8ED33FED9715\ +180C7EA8E2BB74FA65D9C7F6E142F3C81CDC59172E1020F62F65CA5A12CF2BED\ +9DEA04A4D8CABC2948F7BE823A3E792625275B3925A6C8D8E2B428C75A5DB0F7\ +120278CD7D6CAB768755C7FE2FBF89FDED1FB38AC7F76A2F8798CA36ED42CB7C\ +07F006271205F546A4812C20077F050D4CDC79459FA686E97F0704B7A9FF7DE1\ +6318E862C53D361BC635A55A264BE15016545DBFCE3C6D6849576ADEFB6884ED\ +D768214E0B438B0231B4F2692C2C0B5C177674F8A0DE236EACD9E0CEC7C8647E\ +4E9A5861B957EC834A2F8572F01304C3FD6A06019E5F1499B62BAA8670B65246\ +7FA9A4F10F053263BFE9743CC7D933F86136AAE3A6FB56754D7D238397A0030C\ +EBEA87CB255AF36138C373DBBAC41DD4A697032E4796C552AD9C9B3FA713C3A4\ +E09E0EC5581E94BE7F31065157662F9E9C678B1EF1B8B8A847C51789C22B1841\ +BCFC855820AF3258AF9E08231090B45D10046A00178E89BD515616B8A44E77BF\ +57795DABAF40687B2CDA7A5014168F:\ +A2C211D36CF26297E82789FDC7E1564AB1A615FC6277E2AE77E1FE7370C0FEF4\ +FB7B360424C44F393FC4EC2AD5061E633AFBC8D3FBB961322CDFB7AD5A4A443C + +1633256AB03B20CE079196B708A1C02D1B6072219070712C8589EE21341D5075\ +2ACB6CFDA17E982D828BBD6CDF54BC7232FD418A323D64939928597B9B52F07C\ +F488250C5E42BFD3AB48012D709F8D747225839296386FCE5FC5AECC4BA7A107\ +6D089DEA8ECEFAA0CF66FCA8602395719C12A04F929321784D7AB8239FCE2FF3\ +BDAE046A266132B5C2AD9F7261F3014E87B389A6695978693D9371D0B1FF9C40\ +5F338C2FDE4687359603950A54CF4B9CDD9B24480B239ACC5405C14C886BBB03\ +78391CEF0662A38882BDD09E3866AB9A66CFBD28EB5EE4F8009BDEFC4AEB1670\ +0EBA7DC557B489190A71FDA75E85F7EF841697F70FFD4FEA185E7A67C81C5B8F\ +273BFB97B2CEF695C1C74446C4B425BE6B2E66DC0AAACB247E4467B7C7D84EC3\ +3B6B5AB8FA1979F503008BDCFF948CDBF1226B1B066CBCF34797298F3BA8C60F\ +A01E0AC8B803223C656112FB91435D75453BAE4707B63330467DD13E0A4B992E\ +6F7E46995899A2D95D23F4AC3D0802B2A6E7D024DEA19CA408C4BBE053F14C9C\ +E264F129724A18BCB18F385B1CA091A11434EA96D98C8D0602E98EDC8DFA1414\ +1AF93ED0BA66E885E9FA108591AE59E109AE34D6B9F5586E4B4D75E7DF7C3295\ +8A65E88A9BAF41082A0A3F11539DC4EA2CBD9E1C6C3C439B622F1DE574FA7547\ +0C8C939B51D2D1C2A7204B859881D43086BFD8FB90346218D099C5AB36846F3B\ +98A7C847318BDFA01E09717943FCD864C5A8A17B6CEB89D98E872D388F20ADC2\ +BE5E2006846904F41682FB1283214F3D20DBC9FC9E0FF571844A1282E88590D7\ +C085B2C568EC5ACC4462B389FEAA5757F7033187E2DE31955FCE55FEDC909255\ +048B327CCAB2E582BBC9D8054BF5CB45145C7D3A3AF9CD5CF6ECBA490C634ECF\ +00E646BF95E8642C43A4978EF08A574EF1F78F6CE57C3B34B5A123D123617FC8\ +EC9B2AC0F9B70A7F6062D38DD7B8E9FB4ECCEF13DED5C0477483ADDAE4F1CC0C\ +FCA274B1307ED0DE72FBCB819154CDA897D7575213042615F1741A8CB646A39F\ +8D134FDF9E60E000EB8220F65CC30F5FA52C431B9E3B6101B96E25B8D0440B96\ +E572A18A01747C02AFCD7513542F7AACE194632099D16274F31EBABB60DDD94F\ +E43DACCE900EC0902EB5E686D48ED8D09AE63DA0E15C736809903A0297A92DE8\ +4E0260F11F446E1FC448E0EBF59FAEA3C726F97925C57CBDF85B1F77078D3625\ +7C85D56CBBEDCE180FE12B687ADA2DC9912FAC60334166BD2CEF06B089ED5C95\ +63844D71D8FEAD2F3A93F3C07C52537336A8A70BF5B596B9007B9FDF2D082000\ +F20E6B70D2A7E6C7ED27C4146895A6D85A246F623C1B9258A2F891F823ADE4CE\ +FFD59D4FFAD077351E2F506E9A5BDD3900F0204B9E8969AFE72F5DCCB9CDF986\ +D197AE4C4DB53014041AE6221B750E5290E307AD292C8DE6B899235212EF8CE9\ +54785537DC9435AF11E0F3427A9C7B22EFA752EA0B7EADE5F6EB4093BACB7867\ +6E506698139E4F774423B8942166F9A7D22480D814FC0AE19CF4960FBF6E01FF\ +A65C8DA5BED4F1AE2B9ECEC5BE7B3C38DD4045B0C93EE6CC77A7E61E85D331B2\ +3C0D164B104518B3405497054445A353E9B48F2AC5E8E96298D6655614336CFF\ +E6D8C9C915E387391519AD2632366AA3BC935030FD12927EFCA17505ED74C946\ +50C778539004854DF6C24269AAB9C273A493D3E5B0B1D687C33C2FACE46B4BB3\ +742D6DF743D09164D2E0EE7F6BA128BD5FBA2E3B33C199AE80FA9DEE3AD811D0\ +2BAA3D42A6362B2AD47BBA8A2C5CD00B46CF22CFE367281488A4852EB8B7FACE\ +79F0CA6F8E78D32578DFEE01711C4DCF3C26D0BA13F3075478E708C5C5315AFD\ +C2E4C0062D16458213BEC506A9E991A61825FF78DA9BA1BAABBEFA56B4A8C9E2\ +E7B60EC4B7B541C8E0F79C86BB5F03F736761A37169B2AAB8884EC6EA217B02C\ +59035F5BB327243D126B78D4AAB430212439B5A75B80618DAFEB66AA3AFF866C\ +4DAEE47D374B512E74ADA933EF24A841BA271C6F02C870E8AB950FE06E93C91D\ +F0E99165DC01BCB190E411ECCD85358FD4A88127A22E4CF4266A90845124BF97\ +B25D7B1C46D3A0D68A684F84E2A638C692A52CB6E8C651A3AC492B0460004073\ +D5349E35552359CA37660F77B2770D6B2B3F7B1922424AC4A8598B4C61A6DB50\ +7608A72A6A7D573CC055206276E14005A28A0EC41F28D7E260611D40F089FFE5\ +E529375691412F4E9E12E62C3BE2C563C26D2444EA9C69E6C935FEB4DC4E802E\ +5FE3906F8ACEF4798D940C3CD574BB5E74506C3E0B70CB62454A25F589EADB6B\ +0709FE3B50417CD1D98F08E08B7CF68A04CCCF8D6588F9FC2F31E533CDA6159B\ +AA4297FA446450D71C16EA2324EC09773E7C8817ECF680ED12F64A04863EFE3D\ +9D8760F34DE5B0860B3991FF0EE5EDBA22C4D69120DE19D5429E4AAE91C9E7CF\ +05CC807159A58F13B480872AC1609D87E7009DEDB71C09CEAAB640A2B6135855\ +CEAE4AC2954933A0255B425D9FDCD9C246F82AEB7C3BB78C6E73E03DB7AEC424\ +5A28693FBD36EF4938D59CCE19EAFC00671A0851612406A075713C5D1154D8E1\ +3B59B7C5B0902239D4BACFA386AC817AC5EE02A181A9A47C622B3ECF287E1484\ +3D452AF347110498A620B34AB4E116308D976062C9EE9CD35DB6CB79805B93AC\ +9A15AFBCB52F1ED4309879D1924A4BA190B0B86E60A516E77D34B4E0A49D4EF2\ +CEF3CC2F410FD8EC901363FC9EBD75EB460D4D8910BDF27CE26A8B4AEB94F9F7\ +6242401DC35D0644842B99FB6C439B82D82ECFE1AF0D01F9BECB15BEC83F13B2\ +60F7F714AA381032923FDE8F8018F3518547451435C9A5207294D08A907C7369\ +6F6CB000745E072E25B73B3EE11595433D27A1F11468686F08094F1D31F5ADA8\ +1F11F0677A29D72EBB2E1C4792CCC607CB938647E1F153F9EEF03D982595C631\ +E49B6B7C1FA003A6EB8D59CB8892CD0888B05240F12701753F89007C859515A2\ +FEF944BC60B36003A26702AC6FE04D2E942978FC31A97EB29871D6752399D352\ +1720729007B6A7215A4282B2A4EFC2C56BD129E74C9B00847692B96FCC71CF7A\ +7F19F3FD6B45C519FD73B4860880A2DD74E5727B31A93F0A87F0078155344AE9\ +F7BDBF00D83393B634B5DCA88A398E42C320EB95C4A826ACEA90B65E4767B2EB\ +A748F97C247568393E2FD3A66075CC12935B6D7EB5C2FF5282185CB62C73972A\ +37B3CA508004B4F796BDF82B83B5BDF90D6BFD32B5089B0CA2683DC7FB2337DE\ +42E650ED911DBEE1EF98257F9BA5AF54B1A54B04C0087A5A64BA779D86461BA1\ +5337C2E7D4955FDD777A025DE226306A17C384F1C52CDB5946FB0B46DD5C13BD\ +7A55FE2E27E4C6D40D61D6FFC024468F8EDFC7C7992DF5DC5D05063FE7231992\ +24F53678E48F25250EA28BDF1089718EB8B730D1C06735C2F871164E2EB5E885\ +A8DFD2A083BE97EDC94159CE9BF75D2433F1D782762F771903CBF9A1C9D13F71\ +0BA0E151B079DC0A8262BCEB1DBCBBC0F35DF6EECF7BAA7105B9808745853C96\ +B4372E95E482035916B726DAC7BE95A72B19DAD48DB1B19E6EB2EDAB5AC1B301\ +3839E7806625ABC129F41813E6D71EE4AB2040D81E42E6ED73ABBA64FF2EB433\ +B910EA7D4F5ED3D8D27D39BB454EC019DF6114F544D7B155549D0C56D14551FA\ +F353994A80F30F3C97E863A4F2AF316468A568038EB4D799350A6FACAFF90ECD\ +44E0F44EFB6DC42EE4B0DC2C59EA9C1827326DF08C0A6E55CF4F9C3EA0E78CFF\ +3635F5D08E44F1400D20F638D56BA84B4832090454DE57EF04B6C8805A36F63E\ +5CCC6E830C87FFC164647CED20E4C486D09DE7A5F9E4B68D5456CDB22B0DDED2\ +B95B3BCAE529215C2D25D6823C7D66A4FAE0A1E9F022BA5663204F2314DFA51A\ +1F10E11D6D62A8BA6C28B6AE7DA1DEB5B57F2B65D7456059AD9F03DC5A524054\ +DA39DD100D74EB657DE219795E3C45A0E4C762BA22F9DA9D8159E425A1EE783B\ +4B22C250D8894CBEC706CE16D5CA393404FF478F141BE7CC69E45B077BA1955F\ +1F49EFBE4847C795347F703300F672334F490ABF8B644A34B56DA00EC45A3503\ +14B9ADF27CAF7C51CB7DBA0C5477E7D37662F4F23247BCB8F7DD5F3E9CB8BDA4\ +0FA97568832AF0ADC68F71422E412254A6BFC8943BB465B01FCC8DE0B957677C\ +78BC1F7566953E9D2446239F602C682A521C14F741FEA98C7E27AABEC339B6F5\ +B94C78287A894AFDAE971F8DA7C7E4A4C92C8DA47BE82DC2532EC2DA9BACEDD2\ +BE6DB2B2FB34DCCDCB34116507376578CBCA105E5E443BEC0F2EF23BE34CDF86\ +2EDAB34F0FF21335E3ACD92F59688B419F824EA61EEA82BC80E3463452192377\ +131BA51FB0795E089FC077D0ECA8012E58B0637AD7022206887FE9EC00EE5DF7\ +AD2E26FE819EE35C7A179C579098AA3DF645D9064CD557DA90BDD21F871CEB04\ +8CA56DF9653A10ED60F5E9F0ED7F8D89BCF5C22D1143CF44718FF2DFD8E10CEF\ +8AABB67D2305F18177C1426BD4CD03F2625E459CE905067826A214E08E56D8F9\ +455593E6B324E72DEDCC429D3BEFE2AE0599E360DF95E80D453A3A849E48389F\ +A745635BEDE30E7932DE6A3816E31A2217F98D5E40238963D0A36C159FD4EC32\ +D8A5CF59D433DEF3378634AF6887FDB3F3EDB96FC8840FE1B538C329674AE810\ +E8C8B2B46DB208716D38E9D1AEAB097068AD83ADD7DD2647839B3A7388B0615B\ +DE26F8692E9C07D8ADECC2A875203C3D3A9C6CB1D7D06307E9E1D9C3BC536DD8\ +EB271E9A2159C904E61E8C9357FE759F36366AEF5A3D14CEE82913CD2708AA60\ +69369CED763C8E830D70924E82E9015C2998E86EFC1DCE6AC2EBCB49455542A6\ +D7DAB265AD6D7381FFEEE1AA40F8FAC0659B6FB56BB03CD8CAFAACD48D13672F\ +7D524EB9684CFED4DBB7476E99149C28EC08F33BA6AFF839AA178F86B8EEAF17\ +39C829177BA78547AD394136AA3FAD451A11E9642506568B39668B2436610E06\ +EA45FA11D04D3759B033B5382645F15B3C39270B81B80487643913A24F2F1C1A\ +1ED57C85CCDDC8CD6D59B62FA67CC80572968C8FD01894F0153634C88792A7C4\ +A407A4A4CE46CEC5FE5D2569F95A27DE242444EA0C715B357518CAEA23E767E8\ +545983F0D3A4DF66111B4AA1D399CCAFD796D7A80E592D5A51D2B3F60B5B04F8\ +D9C009CA56CBD4DD84127A29B72ADB7645FB7279C9818B2B43963BD605F45B65\ +75A5E2E369E0B401F5EC10EC703F1179B0AB9D4A89D6F096573952E513827364\ +A84D38922734137E969D8167D6959B70F42F2BDA37E4C989ABAA8024C1A84ED6\ +BEB74780927F78B32EA736B9B2B4A795C355C0319811729D9CC399D235197303\ +38D62E16E5035FC52A817090703FE776D65EF9FEF5BA5F4FFEC3CC8E9EB2E312\ +C50A479BDD4E6AB0A56C18C2DF69ED408417BEE28BB41DD13F8366FF6EDA4B34\ +090FC9BC045271:\ +B5BA769BC397D0F2B541E1C996C40F64C3E6BE52950898BC0380513F8E6F754A\ +41025B104D2B5BD872D1D427A8E98F089C9AAF3B5071668C65437F0EF48855CD # FORK-256 vectors generated by the implementation in Botan; there is only one # test vector, and it only covers the compression function, not the entire diff --git a/doc/log.txt b/doc/log.txt index df48d532c..d7c41f9d8 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -1,7 +1,7 @@ * 1.9.1-pre, 2009-??-?? - Enable SSE2 optimizations under Visual C++ - - Add an implementation of Blue Midnight Wish (BMW-512) + - Add an implementation of Blue Midnight Wish (Round 2 tweak version) - Alter Skein-512 to match the tweaked 1.2 specification * 1.9.0, 2009-09-09 diff --git a/src/hash/bmw/bmw_512.cpp b/src/hash/bmw/bmw_512.cpp index 4019c0ff2..fe6a61df0 100644 --- a/src/hash/bmw/bmw_512.cpp +++ b/src/hash/bmw/bmw_512.cpp @@ -1,5 +1,5 @@ /* -* Blue Midnight Wish 512 +* Blue Midnight Wish 512 (Round 2 tweaked) * (C) 2009 Jack Lloyd * * Distributed under the terms of the Botan license @@ -39,6 +39,106 @@ inline u64bit S4(u64bit X) { return (X >> 1) ^ X; } + +/** +* Blue Midnight Wish 512 compression function +*/ +void BMW_512_compress(u64bit H[16], const u64bit M[16], u64bit Q[32]) + { + const u32bit EXPAND_1_ROUNDS = 2; + + for(u32bit i = 0; i != 16; ++i) + Q[i] = H[i] ^ M[i]; + + Q[16] = Q[ 5] - Q[ 7] + Q[10] + Q[13] + Q[14]; + Q[17] = Q[ 6] - Q[ 8] + Q[11] + Q[14] - Q[15]; + Q[18] = Q[ 0] + Q[ 7] + Q[ 9] - Q[12] + Q[15]; + Q[19] = Q[ 0] - Q[ 1] + Q[ 8] - Q[10] + Q[13]; + Q[20] = Q[ 1] + Q[ 2] + Q[ 9] - Q[11] - Q[14]; + Q[21] = Q[ 3] - Q[ 2] + Q[10] - Q[12] + Q[15]; + Q[22] = Q[ 4] - Q[ 0] - Q[ 3] - Q[11] + Q[13]; + Q[23] = Q[ 1] - Q[ 4] - Q[ 5] - Q[12] - Q[14]; + Q[24] = Q[ 2] - Q[ 5] - Q[ 6] + Q[13] - Q[15]; + Q[25] = Q[ 0] - Q[ 3] + Q[ 6] - Q[ 7] + Q[14]; + Q[26] = Q[ 8] - Q[ 1] - Q[ 4] - Q[ 7] + Q[15]; + Q[27] = Q[ 8] - Q[ 0] - Q[ 2] - Q[ 5] + Q[ 9]; + Q[28] = Q[ 1] + Q[ 3] - Q[ 6] - Q[ 9] + Q[10]; + Q[29] = Q[ 2] + Q[ 4] + Q[ 7] + Q[10] + Q[11]; + Q[30] = Q[ 3] - Q[ 5] + Q[ 8] - Q[11] - Q[12]; + Q[31] = Q[12] - Q[ 4] - Q[ 6] - Q[ 9] + Q[13]; + + Q[ 0] = S0(Q[16]) + H[ 1]; + Q[ 1] = S1(Q[17]) + H[ 2]; + Q[ 2] = S2(Q[18]) + H[ 3]; + Q[ 3] = S3(Q[19]) + H[ 4]; + Q[ 4] = S4(Q[20]) + H[ 5]; + Q[ 5] = S0(Q[21]) + H[ 6]; + Q[ 6] = S1(Q[22]) + H[ 7]; + Q[ 7] = S2(Q[23]) + H[ 8]; + Q[ 8] = S3(Q[24]) + H[ 9]; + Q[ 9] = S4(Q[25]) + H[10]; + Q[10] = S0(Q[26]) + H[11]; + Q[11] = S1(Q[27]) + H[12]; + Q[12] = S2(Q[28]) + H[13]; + Q[13] = S3(Q[29]) + H[14]; + Q[14] = S4(Q[30]) + H[15]; + Q[15] = S0(Q[31]) + H[ 0]; + + for(u32bit i = 16; i != 16 + EXPAND_1_ROUNDS; ++i) + { + Q[i] = S1(Q[i-16]) + S2(Q[i-15]) + S3(Q[i-14]) + S0(Q[i-13]) + + S1(Q[i-12]) + S2(Q[i-11]) + S3(Q[i-10]) + S0(Q[i- 9]) + + S1(Q[i- 8]) + S2(Q[i- 7]) + S3(Q[i- 6]) + S0(Q[i- 5]) + + S1(Q[i- 4]) + S2(Q[i- 3]) + S3(Q[i- 2]) + S0(Q[i- 1]) + + ((rotate_left(M[(i-16) % 16], ((i-16)%16) + 1) + + rotate_left(M[(i-13) % 16], ((i-13)%16) + 1) - + rotate_left(M[(i- 6) % 16], ((i-6)%16) + 1) + + (0x0555555555555555 * i)) ^ H[(i-16+7)%16]); + } + + for(u32bit i = 16 + EXPAND_1_ROUNDS; i != 32; ++i) + { + Q[i] = Q[i-16] + rotate_left(Q[i-15], 5) + + Q[i-14] + rotate_left(Q[i-13], 11) + + Q[i-12] + rotate_left(Q[i-11], 27) + + Q[i-10] + rotate_left(Q[i- 9], 32) + + Q[i- 8] + rotate_left(Q[i- 7], 37) + + Q[i- 6] + rotate_left(Q[i- 5], 43) + + Q[i- 4] + rotate_left(Q[i- 3], 53) + + S4(Q[i - 2]) + ((Q[i-1] >> 2) ^ Q[i-1]) + + ((rotate_left(M[(i-16) % 16], ((i-16)%16 + 1)) + + rotate_left(M[(i-13) % 16], ((i-13)%16 + 1)) - + rotate_left(M[(i- 6) % 16], ((i-6)%16 + 1)) + + (0x0555555555555555 * i)) ^ H[(i-16+7)%16]); + } + + u64bit XL = Q[16] ^ Q[17] ^ Q[18] ^ Q[19] ^ + Q[20] ^ Q[21] ^ Q[22] ^ Q[23]; + + u64bit XH = Q[24] ^ Q[25] ^ Q[26] ^ Q[27] ^ + Q[28] ^ Q[29] ^ Q[30] ^ Q[31]; + + XH ^= XL; + + H[ 0] = ((XH << 5) ^ (Q[16] >> 5) ^ M[0]) + (XL ^ Q[24] ^ Q[0]); + H[ 1] = ((XH >> 7) ^ (Q[17] << 8) ^ M[1]) + (XL ^ Q[25] ^ Q[1]); + H[ 2] = ((XH >> 5) ^ (Q[18] << 5) ^ M[2]) + (XL ^ Q[26] ^ Q[2]); + H[ 3] = ((XH >> 1) ^ (Q[19] << 5) ^ M[3]) + (XL ^ Q[27] ^ Q[3]); + H[ 4] = ((XH >> 3) ^ (Q[20] ) ^ M[4]) + (XL ^ Q[28] ^ Q[4]); + H[ 5] = ((XH << 6) ^ (Q[21] >> 6) ^ M[5]) + (XL ^ Q[29] ^ Q[5]); + H[ 6] = ((XH >> 4) ^ (Q[22] << 6) ^ M[6]) + (XL ^ Q[30] ^ Q[6]); + H[ 7] = ((XH >> 11) ^ (Q[23] << 2) ^ M[7]) + (XL ^ Q[31] ^ Q[7]); + + H[ 8] = rotate_left(H[4], 9) + (XH ^ Q[24] ^ M[ 8]) + ((XL << 8) ^ Q[23] ^ Q[ 8]); + H[ 9] = rotate_left(H[5], 10) + (XH ^ Q[25] ^ M[ 9]) + ((XL >> 6) ^ Q[16] ^ Q[ 9]); + H[10] = rotate_left(H[6], 11) + (XH ^ Q[26] ^ M[10]) + ((XL << 6) ^ Q[17] ^ Q[10]); + H[11] = rotate_left(H[7], 12) + (XH ^ Q[27] ^ M[11]) + ((XL << 4) ^ Q[18] ^ Q[11]); + H[12] = rotate_left(H[0], 13) + (XH ^ Q[28] ^ M[12]) + ((XL >> 3) ^ Q[19] ^ Q[12]); + H[13] = rotate_left(H[1], 14) + (XH ^ Q[29] ^ M[13]) + ((XL >> 4) ^ Q[20] ^ Q[13]); + H[14] = rotate_left(H[2], 15) + (XH ^ Q[30] ^ M[14]) + ((XL >> 7) ^ Q[21] ^ Q[14]); + H[15] = rotate_left(H[3], 16) + (XH ^ Q[31] ^ M[15]) + ((XL >> 2) ^ Q[22] ^ Q[15]); + } + } void BMW_512::compress_n(const byte input[], u32bit blocks) @@ -46,92 +146,11 @@ void BMW_512::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { for(u32bit j = 0; j != 16; ++j) - H[j] ^= M[j] = load_le(input, j); - input += HASH_BLOCK_SIZE; + M[j] = load_le(input, j); - H[16] = H[ 5] - H[ 7] + H[10] + H[13] + H[14]; - H[17] = H[ 6] - H[ 8] + H[11] + H[14] - H[15]; - H[18] = H[ 0] + H[ 7] + H[ 9] - H[12] + H[15]; - H[19] = H[ 0] - H[ 1] + H[ 8] - H[10] + H[13]; - H[20] = H[ 1] + H[ 2] + H[ 9] - H[11] - H[14]; - H[21] = H[ 3] - H[ 2] + H[10] - H[12] + H[15]; - H[22] = H[ 4] - H[ 0] - H[ 3] - H[11] + H[13]; - H[23] = H[ 1] - H[ 4] - H[ 5] - H[12] - H[14]; - H[24] = H[ 2] - H[ 5] - H[ 6] + H[13] - H[15]; - H[25] = H[ 0] - H[ 3] + H[ 6] - H[ 7] + H[14]; - H[26] = H[ 8] - H[ 1] - H[ 4] - H[ 7] + H[15]; - H[27] = H[ 8] - H[ 0] - H[ 2] - H[ 5] + H[ 9]; - H[28] = H[ 1] + H[ 3] - H[ 6] - H[ 9] + H[10]; - H[29] = H[ 2] + H[ 4] + H[ 7] + H[10] + H[11]; - H[30] = H[ 3] - H[ 5] + H[ 8] - H[11] - H[12]; - H[31] = H[12] - H[ 4] - H[ 6] - H[ 9] + H[13]; - - H[ 0] = S0(H[16]); - H[ 1] = S1(H[17]); - H[ 2] = S2(H[18]); - H[ 3] = S3(H[19]); - H[ 4] = S4(H[20]); - H[ 5] = S0(H[21]); - H[ 6] = S1(H[22]); - H[ 7] = S2(H[23]); - H[ 8] = S3(H[24]); - H[ 9] = S4(H[25]); - H[10] = S0(H[26]); - H[11] = S1(H[27]); - H[12] = S2(H[28]); - H[13] = S3(H[29]); - H[14] = S4(H[30]); - H[15] = S0(H[31]); - - for(u32bit j = 16; j != 18; ++j) - { - H[j] = S1(H[j-16]) + S2(H[j-15]) + S3(H[j-14]) + S0(H[j-13]) + - S1(H[j-12]) + S2(H[j-11]) + S3(H[j-10]) + S0(H[j- 9]) + - S1(H[j- 8]) + S2(H[j- 7]) + S3(H[j- 6]) + S0(H[j- 5]) + - S1(H[j- 4]) + S2(H[j- 3]) + S3(H[j- 2]) + S0(H[j- 1]) + - M[j-16] + M[j-13] - M[j-6] + - (0x0555555555555555 * j); - } - - for(u32bit j = 18; j != 32; ++j) - { - H[j] = H[j-16] + rotate_left(H[j-15], 5) + - H[j-14] + rotate_left(H[j-13], 11) + - H[j-12] + rotate_left(H[j-11], 27) + - H[j-10] + rotate_left(H[j- 9], 32) + - H[j- 8] + rotate_left(H[j- 7], 37) + - H[j- 6] + rotate_left(H[j- 5], 43) + - H[j- 4] + rotate_left(H[j- 3], 53) + - (H[j- 2] >> 2 ^ H[j- 2]) + S4(H[j- 1]) + - M[j-16] + M[(j-13) % 16] - M[(j-6) % 16] + - (0x0555555555555555 * j); - } - - u64bit XL = H[16] ^ H[17] ^ H[18] ^ H[19] ^ - H[20] ^ H[21] ^ H[22] ^ H[23]; - - u64bit XH = H[24] ^ H[25] ^ H[26] ^ H[27] ^ - H[28] ^ H[29] ^ H[30] ^ H[31]; - - XH ^= XL; - - H[ 0] = ((XH << 5) ^ (H[16] >> 5) ^ M[0]) + (XL ^ H[24] ^ H[0]); - H[ 1] = ((XH >> 7) ^ (H[17] << 8) ^ M[1]) + (XL ^ H[25] ^ H[1]); - H[ 2] = ((XH >> 5) ^ (H[18] << 5) ^ M[2]) + (XL ^ H[26] ^ H[2]); - H[ 3] = ((XH >> 1) ^ (H[19] << 5) ^ M[3]) + (XL ^ H[27] ^ H[3]); - H[ 4] = ((XH >> 3) ^ (H[20] ) ^ M[4]) + (XL ^ H[28] ^ H[4]); - H[ 5] = ((XH << 6) ^ (H[21] >> 6) ^ M[5]) + (XL ^ H[29] ^ H[5]); - H[ 6] = ((XH >> 4) ^ (H[22] << 6) ^ M[6]) + (XL ^ H[30] ^ H[6]); - H[ 7] = ((XH >> 11) ^ (H[23] << 2) ^ M[7]) + (XL ^ H[31] ^ H[7]); - - H[ 8] = rotate_left(H[4], 9) + (XH ^ H[24] ^ M[ 8]) + ((XL << 8) ^ H[23] ^ H[ 8]); - H[ 9] = rotate_left(H[5], 10) + (XH ^ H[25] ^ M[ 9]) + ((XL >> 6) ^ H[16] ^ H[ 9]); - H[10] = rotate_left(H[6], 11) + (XH ^ H[26] ^ M[10]) + ((XL << 6) ^ H[17] ^ H[10]); - H[11] = rotate_left(H[7], 12) + (XH ^ H[27] ^ M[11]) + ((XL << 4) ^ H[18] ^ H[11]); - H[12] = rotate_left(H[0], 13) + (XH ^ H[28] ^ M[12]) + ((XL >> 3) ^ H[19] ^ H[12]); - H[13] = rotate_left(H[1], 14) + (XH ^ H[29] ^ M[13]) + ((XL >> 4) ^ H[20] ^ H[13]); - H[14] = rotate_left(H[2], 15) + (XH ^ H[30] ^ M[14]) + ((XL >> 7) ^ H[21] ^ H[14]); - H[15] = rotate_left(H[3], 16) + (XH ^ H[31] ^ M[15]) + ((XL >> 2) ^ H[22] ^ H[15]); + BMW_512_compress(H, M, Q); + + input += HASH_BLOCK_SIZE; } } @@ -140,8 +159,20 @@ void BMW_512::compress_n(const byte input[], u32bit blocks) */ void BMW_512::copy_out(byte output[]) { + u64bit final[16] = { + 0xAAAAAAAAAAAAAAA0, 0xAAAAAAAAAAAAAAA1, + 0xAAAAAAAAAAAAAAA2, 0xAAAAAAAAAAAAAAA3, + 0xAAAAAAAAAAAAAAA4, 0xAAAAAAAAAAAAAAA5, + 0xAAAAAAAAAAAAAAA6, 0xAAAAAAAAAAAAAAA7, + 0xAAAAAAAAAAAAAAA8, 0xAAAAAAAAAAAAAAA9, + 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAB, + 0xAAAAAAAAAAAAAAAC, 0xAAAAAAAAAAAAAAAD, + 0xAAAAAAAAAAAAAAAE, 0xAAAAAAAAAAAAAAAF }; + + BMW_512_compress(final, H, Q); + for(u32bit i = 0; i != OUTPUT_LENGTH; i += 8) - store_le(H[8 + i/8], output + i); + store_le(final[8 + i/8], output + i); } /* @@ -151,6 +182,7 @@ void BMW_512::clear() throw() { MDx_HashFunction::clear(); M.clear(); + Q.clear(); H[ 0] = 0x8081828384858687; H[ 1] = 0x88898A8B8C8D8E8F; diff --git a/src/hash/bmw/bmw_512.h b/src/hash/bmw/bmw_512.h index 4be6afd04..d1f2539e9 100644 --- a/src/hash/bmw/bmw_512.h +++ b/src/hash/bmw/bmw_512.h @@ -1,5 +1,5 @@ /* -* Blue Midnight Wish 512 +* Blue Midnight Wish 512 (Round 2 tweaked) * (C) 2009 Jack Lloyd * * Distributed under the terms of the Botan license @@ -23,8 +23,8 @@ class BMW_512 : public MDx_HashFunction void compress_n(const byte input[], u32bit blocks); void copy_out(byte output[]); - SecureBuffer H; - SecureBuffer M; + SecureBuffer H, M; + SecureBuffer Q; }; } -- cgit v1.2.3 From f5ae4519eb667df11df936b90d735b7bdfecea87 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 21 Sep 2009 21:17:26 +0000 Subject: Remove unneeded headers --- src/stream/salsa20/salsa20.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/stream/salsa20/salsa20.cpp b/src/stream/salsa20/salsa20.cpp index 75137798c..9c7c811f0 100644 --- a/src/stream/salsa20/salsa20.cpp +++ b/src/stream/salsa20/salsa20.cpp @@ -6,10 +6,8 @@ */ #include -#include #include #include -#include namespace Botan { -- cgit v1.2.3 From fec26d84bd9e3dd35d68429d91723eb2f56b7ff6 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 23 Sep 2009 19:35:33 +0000 Subject: In the benchmark code, set a random key for the block and stream ciphers. This, I think, was what was causing the OpenSSL AES code to crash (without a key being set, the rounds are unset and probably causes the code to loop out past the end of an array somewhere). Sadly, this also confirms that OpenSSL's AES is much faster than Botan's: AES-128: 115.032 [core] 152.994 [openssl] AES-192: 98.6724 [core] 130.087 [openssl] AES-256: 86.6348 [core] 113.608 [openssl] Definitely some improvement can be made there! :( --- src/benchmark/benchmark.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/benchmark/benchmark.cpp b/src/benchmark/benchmark.cpp index 9be845974..6e61baa59 100644 --- a/src/benchmark/benchmark.cpp +++ b/src/benchmark/benchmark.cpp @@ -54,6 +54,8 @@ bench_block_cipher(BlockCipher* block_cipher, const u32bit in_blocks = buf_len / block_cipher->BLOCK_SIZE; + block_cipher->set_key(buf, block_cipher->MAXIMUM_KEYLENGTH); + while(nanoseconds_used < nanoseconds_max) { block_cipher->encrypt_n(buf, buf, in_blocks); @@ -79,6 +81,8 @@ bench_stream_cipher(StreamCipher* stream_cipher, u64bit nanoseconds_used = 0; u64bit reps = 0; + stream_cipher->set_key(buf, stream_cipher->MAXIMUM_KEYLENGTH); + while(nanoseconds_used < nanoseconds_max) { stream_cipher->encrypt(buf, buf_len); -- cgit v1.2.3 From a20e93cae049a177801e87c9c741a0a02ae616e6 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 24 Sep 2009 14:37:50 +0000 Subject: Enable OpenSSL AES (fixed, I think). And add support for OpenSSL's RC5 --- src/engine/openssl/ossl_bc.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/engine/openssl/ossl_bc.cpp b/src/engine/openssl/ossl_bc.cpp index dd6bb38db..9c85439ca 100644 --- a/src/engine/openssl/ossl_bc.cpp +++ b/src/engine/openssl/ossl_bc.cpp @@ -176,7 +176,7 @@ OpenSSL_Engine::find_block_cipher(const SCAN_Name& request, if(request.algo_name() == NAME && request.arg_count() == 0) \ return new EVP_BlockCipher(EVP, NAME, MIN, MAX, MOD); -#if 0 && !defined(OPENSSL_NO_AES) +#if !defined(OPENSSL_NO_AES) /* Using OpenSSL's AES causes crashes inside EVP on x86-64 with OpenSSL 0.9.8g cause is unknown @@ -203,6 +203,12 @@ OpenSSL_Engine::find_block_cipher(const SCAN_Name& request, HANDLE_EVP_CIPHER_KEYLEN("RC2", EVP_rc2_ecb(), 1, 32, 1); #endif +#if !defined(OPENSSL_NO_RC5) + if(request.algo_name() == "RC5") + if(request.arg_as_u32bit(0, 12) == 12) + return new EVP_BlockCipher(EVP_rc5_32_12_16_ecb(), "RC5(12)", 1, 32, 1); +#endif + #if !defined(OPENSSL_NO_IDEA) HANDLE_EVP_CIPHER("IDEA", EVP_idea_ecb()); #endif -- cgit v1.2.3 From 4c9aacabce7724197fb5e2e3fb85281a964f6574 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 24 Sep 2009 14:38:13 +0000 Subject: Add engine deps on the asm_xxx modules so the engines get loaded --- src/utils/asm_amd64/info.txt | 4 ++++ src/utils/asm_ia32/info.txt | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'src') diff --git a/src/utils/asm_amd64/info.txt b/src/utils/asm_amd64/info.txt index 19035b545..6fa4d1de5 100644 --- a/src/utils/asm_amd64/info.txt +++ b/src/utils/asm_amd64/info.txt @@ -14,3 +14,7 @@ amd64 gcc icc + + +amd64_eng + diff --git a/src/utils/asm_ia32/info.txt b/src/utils/asm_ia32/info.txt index 4340c35aa..8485d33b9 100644 --- a/src/utils/asm_ia32/info.txt +++ b/src/utils/asm_ia32/info.txt @@ -14,3 +14,7 @@ ia32 gcc icc + + +ia32_eng + -- cgit v1.2.3 From e06cb7dcf09e17cb0e76d42e096ca838c17a60bc Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 24 Sep 2009 16:30:23 +0000 Subject: Add BitBucket to basefilt.h --- src/filters/basefilt.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/filters/basefilt.h b/src/filters/basefilt.h index 348ad6fd3..b1bcb1a00 100644 --- a/src/filters/basefilt.h +++ b/src/filters/basefilt.h @@ -12,6 +12,14 @@ namespace Botan { +/** +* BitBucket is a filter which simply discards all inputs +*/ +struct BitBucket : public Filter + { + void write(const byte[], u32bit) {} + }; + /** * This class represents Filter chains. A Filter chain is an ordered * concatenation of Filters, the input to a Chain sequentially passes -- cgit v1.2.3 From 03f41b6ceb6e9dcfbe4b134239431de43afd7e6b Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 25 Sep 2009 11:51:55 +0000 Subject: Add runtime cpuid support. Check in the SSE2 engine that SSE2 is actually existing on the current CPU before returning an object. --- doc/log.txt | 1 + src/engine/sse2_eng/eng_sse2.cpp | 7 +++ src/utils/cpuid.cpp | 108 +++++++++++++++++++++++++++++++++++++++ src/utils/cpuid.h | 51 ++++++++++++++++++ src/utils/info.txt | 2 + 5 files changed, 169 insertions(+) create mode 100644 src/utils/cpuid.cpp create mode 100644 src/utils/cpuid.h (limited to 'src') diff --git a/doc/log.txt b/doc/log.txt index df48d532c..5bb2d3ee1 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -1,6 +1,7 @@ * 1.9.1-pre, 2009-??-?? - Enable SSE2 optimizations under Visual C++ + - Add runtime checking for SSE2 availability - Add an implementation of Blue Midnight Wish (BMW-512) - Alter Skein-512 to match the tweaked 1.2 specification diff --git a/src/engine/sse2_eng/eng_sse2.cpp b/src/engine/sse2_eng/eng_sse2.cpp index 9f68a070e..07c625c7c 100644 --- a/src/engine/sse2_eng/eng_sse2.cpp +++ b/src/engine/sse2_eng/eng_sse2.cpp @@ -6,6 +6,7 @@ */ #include +#include #if defined(BOTAN_HAS_SHA1_SSE2) #include @@ -21,6 +22,9 @@ BlockCipher* SSE2_Assembler_Engine::find_block_cipher(const SCAN_Name& request, Algorithm_Factory&) const { + if(!CPUID::has_sse2()) + return 0; + #if defined(BOTAN_HAS_SERPENT_SSE2) if(request.algo_name() == "Serpent") return new Serpent_SSE2; @@ -33,6 +37,9 @@ HashFunction* SSE2_Assembler_Engine::find_hash(const SCAN_Name& request, Algorithm_Factory&) const { + if(!CPUID::has_sse2()) + return 0; + #if defined(BOTAN_HAS_SHA1_SSE2) if(request.algo_name() == "SHA-160") return new SHA_160_SSE2; diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp new file mode 100644 index 000000000..4f22ef867 --- /dev/null +++ b/src/utils/cpuid.cpp @@ -0,0 +1,108 @@ +/** +* Runtime CPU detection +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include + +#if defined(_MSC_VER) + #include +#endif + +namespace Botan { + +namespace CPUID { + +namespace { + +/* +* Call the x86 CPUID instruction and return the contents of ecx and +* edx, which contain the feature masks. +*/ +u64bit x86_processor_flags() + { + static u64bit proc_flags = 0; + + if(proc_flags) + return proc_flags; + +#if defined(BOTAN_TARGET_ARCH_IS_X86) || defined(BOTAN_TARGET_ARCH_IS_AMD64) + +#if defined(__GNUG__) + + u32bit a = 1, b = 0, c = 0, d = 0; + +#if defined(__i386__) && defined(__PIC__) + // ebx is used in PIC on 32-bit x86, so save and restore it + asm("xchgl %%ebx, %1\n\t" + "cpuid\n\t" + "xchgl %%ebx, %1\n\t" + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) : "0" (a)); +#else + // if not PIC or in 64-bit mode, can smash ebx + asm("cpuid" : "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "0" (a)); + +#endif + + proc_flags = ((u64bit)c << 32) | d; + +#elif defined(_MSC_VER) + + int cpuinfo[4] = { 0 }; + __cpuid(cpuinfo, 1); + + proc_flags = ((u64bit)cpuinfo[2] << 32) | cpuinfo[3]; + +#endif + +#endif + + return proc_flags; + } + +enum CPUID_bits { + CPUID_RDTSC_BIT = 4, + CPUID_SSE2_BIT = 26, + CPUID_SSSE3_BIT = 41, + CPUID_SSE41_BIT = 51, + CPUID_SSE42_BIT = 52 +}; + +} + +u32bit cache_line_size() + { + return 32; // FIXME! + } + +bool has_rdtsc() + { + return ((x86_processor_flags() >> CPUID_RDTSC_BIT) & 1); + } + +bool has_sse2() + { + return ((x86_processor_flags() >> CPUID_SSE2_BIT) & 1); + } + +bool has_ssse3() + { + return ((x86_processor_flags() >> CPUID_SSSE3_BIT) & 1); + } + +bool has_sse41() + { + return ((x86_processor_flags() >> CPUID_SSE41_BIT) & 1); + } + +bool has_sse42() + { + return ((x86_processor_flags() >> CPUID_SSE42_BIT) & 1); + } + +} + +} diff --git a/src/utils/cpuid.h b/src/utils/cpuid.h new file mode 100644 index 000000000..557590db8 --- /dev/null +++ b/src/utils/cpuid.h @@ -0,0 +1,51 @@ +/** +* Runtime CPU detection +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_CPUID_H__ +#define BOTAN_CPUID_H__ + +#include + +namespace Botan { + +namespace CPUID { + +/** +* Return a best guess of the cache line size +*/ +u32bit cache_line_size(); + +/** +* Check if the processor supports RDTSC +*/ +bool has_rdtsc(); + +/** +* Check if the processor supports SSE2 +*/ +bool has_sse2(); + +/** +* Check if the processor supports SSSE3 +*/ +bool has_ssse3(); + +/** +* Check if the processor supports SSE4.1 +*/ +bool has_sse41(); + +/** +* Check if the processor supports SSE4.2 +*/ +bool has_sse42(); + +} + +} + +#endif diff --git a/src/utils/info.txt b/src/utils/info.txt index 68981729f..f530fb03a 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -13,6 +13,8 @@ bit_ops.h bswap.h charset.cpp charset.h +cpuid.cpp +cpuid.h exceptn.cpp exceptn.h loadstor.h -- cgit v1.2.3 From 201015e56372c1937574b5dd9687ee49cc0f5d25 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 29 Sep 2009 18:14:17 +0000 Subject: Use load_le instead of make_u32bit in Serpent x86 key schedule code --- src/block/serpent_ia32/serp_ia32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/block/serpent_ia32/serp_ia32.cpp b/src/block/serpent_ia32/serp_ia32.cpp index 997bec2fc..721584b18 100644 --- a/src/block/serpent_ia32/serp_ia32.cpp +++ b/src/block/serpent_ia32/serp_ia32.cpp @@ -51,7 +51,7 @@ void Serpent_IA32::key_schedule(const byte key[], u32bit length) { SecureBuffer 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(key, j); W[length / 4] |= u32bit(1) << ((length%4)*8); botan_serpent_ia32_key_schedule(W); -- cgit v1.2.3 From 18d48581310d60e3c9cd0fbdc0a574d8ebaaeed4 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 29 Sep 2009 18:36:24 +0000 Subject: Add a new macro BOTAN_BUILD_COMPILER_IS_XXX to build.h --- configure.py | 19 ++++++++++++------- src/build-data/cc/bcc | 2 ++ src/build-data/cc/compaq | 2 ++ src/build-data/cc/ekopath | 2 ++ src/build-data/cc/gcc | 2 ++ src/build-data/cc/hpcc | 2 ++ src/build-data/cc/icc | 2 ++ src/build-data/cc/kai | 2 ++ src/build-data/cc/mipspro | 2 ++ src/build-data/cc/msvc | 2 ++ src/build-data/cc/open64 | 2 ++ src/build-data/cc/pgi | 2 ++ src/build-data/cc/sgipro64 | 2 ++ src/build-data/cc/sunwspro | 2 ++ src/build-data/cc/xlc | 2 ++ 15 files changed, 40 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/configure.py b/configure.py index 9d6641c12..5c8835a95 100755 --- a/configure.py +++ b/configure.py @@ -443,6 +443,7 @@ class CompilerInfo(object): ['so_link_flags', 'mach_opt', 'mach_abi_linking'], { 'realname': '', 'binary_name': None, + 'macro_name': None, 'compile_option': '-c ', 'output_to_option': '-o ', 'add_include_dir_option': '-I', @@ -483,6 +484,7 @@ class CompilerInfo(object): del self.mach_opt + def mach_abi_link_flags(self, osname, arch, submodel): abi_link = set() @@ -515,15 +517,18 @@ class CompilerInfo(object): return self.so_link_flags['default'] def defines(self, with_tr1): - if with_tr1: - if with_tr1 == 'boost': - return ['USE_BOOST_TR1'] - elif with_tr1 == 'system': + + def tr1_macro(): + if with_tr1: + if with_tr1 == 'boost': + return ['USE_BOOST_TR1'] + elif with_tr1 == 'system': + return ['USE_STD_TR1'] + elif self.compiler_has_tr1: return ['USE_STD_TR1'] - elif self.compiler_has_tr1: - return ['USE_STD_TR1'] + return [] - return [] + return ['BUILD_COMPILER_IS_' + self.macro_name] + tr1_macro() class OsInfo(object): def __init__(self, infofile): diff --git a/src/build-data/cc/bcc b/src/build-data/cc/bcc index df09daff0..fe88c270e 100644 --- a/src/build-data/cc/bcc +++ b/src/build-data/cc/bcc @@ -1,5 +1,7 @@ realname "Borland C++" +macro_name "BORLAND" + binary_name "bcc32" compile_option "-c " diff --git a/src/build-data/cc/compaq b/src/build-data/cc/compaq index 66d3a5219..94075e888 100644 --- a/src/build-data/cc/compaq +++ b/src/build-data/cc/compaq @@ -1,5 +1,7 @@ realname "Compaq C++" +macro_name "COMPAQ" + binary_name "cxx" compile_option "-c " diff --git a/src/build-data/cc/ekopath b/src/build-data/cc/ekopath index ca2471059..38516e2f3 100644 --- a/src/build-data/cc/ekopath +++ b/src/build-data/cc/ekopath @@ -1,5 +1,7 @@ realname "PathScale EKOPath C++" +macro_name "PATHSCALE" + binary_name "pathCC" compile_option "-c " diff --git a/src/build-data/cc/gcc b/src/build-data/cc/gcc index 978ed6d58..606b622f6 100644 --- a/src/build-data/cc/gcc +++ b/src/build-data/cc/gcc @@ -1,5 +1,7 @@ realname "GNU C++" +macro_name "GCC" + binary_name "g++" compiler_has_tr1 yes diff --git a/src/build-data/cc/hpcc b/src/build-data/cc/hpcc index 284e92ca6..9c0d4a784 100644 --- a/src/build-data/cc/hpcc +++ b/src/build-data/cc/hpcc @@ -1,5 +1,7 @@ realname "HP-UX C++" +macro_name "HP_ACC" + binary_name "aCC" compile_option "-c " diff --git a/src/build-data/cc/icc b/src/build-data/cc/icc index 7d8e9682f..9595714f6 100644 --- a/src/build-data/cc/icc +++ b/src/build-data/cc/icc @@ -1,5 +1,7 @@ realname "Intel C++" +macro_name "INTEL" + binary_name "icpc" compiler_has_tr1 yes diff --git a/src/build-data/cc/kai b/src/build-data/cc/kai index 8585e54e0..52ddba4ab 100644 --- a/src/build-data/cc/kai +++ b/src/build-data/cc/kai @@ -1,5 +1,7 @@ realname "KAI C++" +macro_name "KAI" + binary_name "KCC" compile_option "-c " diff --git a/src/build-data/cc/mipspro b/src/build-data/cc/mipspro index b75fc4fb3..a4cfbd1ee 100644 --- a/src/build-data/cc/mipspro +++ b/src/build-data/cc/mipspro @@ -1,5 +1,7 @@ realname "SGI MIPSPro C++" +macro_name "MIPSPRO" + binary_name "CC" compile_option "-c " diff --git a/src/build-data/cc/msvc b/src/build-data/cc/msvc index 68e4517f8..c19d93e2b 100644 --- a/src/build-data/cc/msvc +++ b/src/build-data/cc/msvc @@ -1,5 +1,7 @@ realname "Visual C++" +macro_name "MSVC" + binary_name "cl.exe" compile_option "/nologo /c " diff --git a/src/build-data/cc/open64 b/src/build-data/cc/open64 index b7c1e9e99..0157440cf 100644 --- a/src/build-data/cc/open64 +++ b/src/build-data/cc/open64 @@ -1,5 +1,7 @@ realname "Open64" +macro_name "OPEN64" + binary_name "openCC" compile_option "-c " diff --git a/src/build-data/cc/pgi b/src/build-data/cc/pgi index 35f466477..c4fdb9e70 100644 --- a/src/build-data/cc/pgi +++ b/src/build-data/cc/pgi @@ -1,5 +1,7 @@ realname "Portland Group C++" +macro_name "PORTLAND_GROUP" + binary_name "pgCC" compile_option "-c " diff --git a/src/build-data/cc/sgipro64 b/src/build-data/cc/sgipro64 index 28132ffcc..be91ac69a 100644 --- a/src/build-data/cc/sgipro64 +++ b/src/build-data/cc/sgipro64 @@ -1,5 +1,7 @@ realname "SGI Pro64" +macro_name "SGI_PRO64" + binary_name "sgiCC" compile_option "-c " diff --git a/src/build-data/cc/sunwspro b/src/build-data/cc/sunwspro index e1bc0b26f..9756f8538 100644 --- a/src/build-data/cc/sunwspro +++ b/src/build-data/cc/sunwspro @@ -1,5 +1,7 @@ realname "Sun Workshop Pro C++" +macro_name "SUN_WORKSHOP" + binary_name "CC" compile_option "-c " diff --git a/src/build-data/cc/xlc b/src/build-data/cc/xlc index 64b888421..6d06b4c43 100644 --- a/src/build-data/cc/xlc +++ b/src/build-data/cc/xlc @@ -1,5 +1,7 @@ realname "IBM XL C/C++" +macro_name "IBM_XLC" + binary_name "xlC" compile_option "-c " -- cgit v1.2.3 From 093f98e42a3ba6d51a6c676070090dd06cc39bc7 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 29 Sep 2009 18:37:08 +0000 Subject: Add some basic prefetching support (only supported with GNU C++ or things that claim to be by defining __GNUG__ (such as Intel C++)) in new utils header prefetch.h --- src/utils/cpuid.cpp | 6 +++--- src/utils/info.txt | 1 + src/utils/loadstor.h | 1 + src/utils/prefetch.h | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 src/utils/prefetch.h (limited to 'src') diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index 4f22ef867..d5149e2e5 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -31,12 +31,12 @@ u64bit x86_processor_flags() #if defined(BOTAN_TARGET_ARCH_IS_X86) || defined(BOTAN_TARGET_ARCH_IS_AMD64) -#if defined(__GNUG__) +#if defined(BOTAN_BUILD_COMPILER_IS_GCC) u32bit a = 1, b = 0, c = 0, d = 0; #if defined(__i386__) && defined(__PIC__) - // ebx is used in PIC on 32-bit x86, so save and restore it + // ebx is reserved for PIC on 32-bit x86, so save and restore it asm("xchgl %%ebx, %1\n\t" "cpuid\n\t" "xchgl %%ebx, %1\n\t" @@ -49,7 +49,7 @@ u64bit x86_processor_flags() proc_flags = ((u64bit)c << 32) | d; -#elif defined(_MSC_VER) +#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) int cpuinfo[4] = { 0 }; __cpuid(cpuinfo, 1); diff --git a/src/utils/info.txt b/src/utils/info.txt index f530fb03a..c9648af51 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -23,6 +23,7 @@ mlock.h mlock.cpp parsing.cpp parsing.h +prefetch.h rotate.h rounding.h stl_util.h diff --git a/src/utils/loadstor.h b/src/utils/loadstor.h index 77ed1554e..8c64deaee 100644 --- a/src/utils/loadstor.h +++ b/src/utils/loadstor.h @@ -12,6 +12,7 @@ #include #include #include +#include #if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK diff --git a/src/utils/prefetch.h b/src/utils/prefetch.h new file mode 100644 index 000000000..100829dce --- /dev/null +++ b/src/utils/prefetch.h @@ -0,0 +1,39 @@ +/* +* Prefetching Operations +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PREFETCH_H__ +#define BOTAN_PREFETCH_H__ + +#include + +namespace Botan { + +inline void prefetch_readonly(const void* addr_void, u32bit length) + { +#if defined(__GNUG__) + const byte* addr = static_cast(addr_void); + const u32bit cl_size = CPUID::cache_line_size(); + + for(u32bit i = 0; i <= length; i += cl_size) + __builtin_prefetch(addr + i, 0); +#endif + } + +inline void prefetch_readwrite(const void* addr_void, u32bit length) + { +#if defined(__GNUG__) + const byte* addr = static_cast(addr_void); + const u32bit cl_size = CPUID::cache_line_size(); + + for(u32bit i = 0; i <= length; i += cl_size) + __builtin_prefetch(addr + i, 1); +#endif + } + +} + +#endif -- cgit v1.2.3 From e98ba8ecc6a633c48b486b43ad53bcf7212cee55 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 29 Sep 2009 18:49:29 +0000 Subject: Remove add blocks from block cipher info files --- src/block/aes/info.txt | 8 -------- src/block/blowfish/info.txt | 8 -------- src/block/cast/info.txt | 10 ---------- src/block/des/info.txt | 10 ---------- src/block/gost_28147/info.txt | 7 ------- src/block/idea/info.txt | 7 ------- src/block/kasumi/info.txt | 7 ------- src/block/lion/info.txt | 7 ------- src/block/lubyrack/info.txt | 7 ------- src/block/mars/info.txt | 8 -------- src/block/misty1/info.txt | 7 ------- src/block/noekeon/info.txt | 7 ------- src/block/rc2/info.txt | 7 ------- src/block/rc5/info.txt | 7 ------- src/block/rc6/info.txt | 7 ------- src/block/safer/info.txt | 8 -------- src/block/seed/info.txt | 8 -------- src/block/serpent/info.txt | 7 ------- src/block/serpent_ia32/info.txt | 6 ------ src/block/serpent_sse2/info.txt | 8 -------- src/block/skipjack/info.txt | 7 ------- src/block/square/info.txt | 8 -------- src/block/tea/info.txt | 7 ------- src/block/twofish/info.txt | 8 -------- src/block/xtea/info.txt | 7 ------- 25 files changed, 188 deletions(-) (limited to 'src') diff --git a/src/block/aes/info.txt b/src/block/aes/info.txt index 2803ccc4e..0e11603bb 100644 --- a/src/block/aes/info.txt +++ b/src/block/aes/info.txt @@ -1,11 +1,3 @@ realname "AES" define AES - -load_on auto - - -aes.cpp -aes.h -aes_tab.cpp - diff --git a/src/block/blowfish/info.txt b/src/block/blowfish/info.txt index 0a9d2adc2..c63560989 100644 --- a/src/block/blowfish/info.txt +++ b/src/block/blowfish/info.txt @@ -1,11 +1,3 @@ realname "Blowfish" define BLOWFISH - -load_on auto - - -blfs_tab.cpp -blowfish.cpp -blowfish.h - diff --git a/src/block/cast/info.txt b/src/block/cast/info.txt index 73d3f900f..b9259042d 100644 --- a/src/block/cast/info.txt +++ b/src/block/cast/info.txt @@ -1,13 +1,3 @@ realname "CAST" define CAST - -load_on auto - - -cast128.cpp -cast128.h -cast256.cpp -cast256.h -cast_tab.cpp - diff --git a/src/block/des/info.txt b/src/block/des/info.txt index ed05979c9..6eec591a0 100644 --- a/src/block/des/info.txt +++ b/src/block/des/info.txt @@ -1,13 +1,3 @@ realname "DES" define DES - -load_on auto - - -des.cpp -des.h -des_tab.cpp -desx.h -desx.cpp - diff --git a/src/block/gost_28147/info.txt b/src/block/gost_28147/info.txt index 6e187fd48..9b24d1e22 100644 --- a/src/block/gost_28147/info.txt +++ b/src/block/gost_28147/info.txt @@ -1,10 +1,3 @@ realname "GOST 28147-89" define GOST_28147_89 - -load_on auto - - -gost_28147.cpp -gost_28147.h - diff --git a/src/block/idea/info.txt b/src/block/idea/info.txt index 2da3ffb43..f11b3d224 100644 --- a/src/block/idea/info.txt +++ b/src/block/idea/info.txt @@ -1,10 +1,3 @@ realname "IDEA" define IDEA - -load_on auto - - -idea.cpp -idea.h - diff --git a/src/block/kasumi/info.txt b/src/block/kasumi/info.txt index 8ea879b6d..e310488b3 100644 --- a/src/block/kasumi/info.txt +++ b/src/block/kasumi/info.txt @@ -1,10 +1,3 @@ realname "Kasumi" define KASUMI - -load_on auto - - -kasumi.cpp -kasumi.h - diff --git a/src/block/lion/info.txt b/src/block/lion/info.txt index 81ef58511..64f2989b1 100644 --- a/src/block/lion/info.txt +++ b/src/block/lion/info.txt @@ -2,13 +2,6 @@ realname "Lion" define LION -load_on auto - - -lion.cpp -lion.h - - hash stream diff --git a/src/block/lubyrack/info.txt b/src/block/lubyrack/info.txt index a478526f4..d915781d8 100644 --- a/src/block/lubyrack/info.txt +++ b/src/block/lubyrack/info.txt @@ -2,13 +2,6 @@ realname "Luby-Rackoff" define LUBY_RACKOFF -load_on auto - - -lubyrack.cpp -lubyrack.h - - hash diff --git a/src/block/mars/info.txt b/src/block/mars/info.txt index b0ad8af9c..ec958eaf5 100644 --- a/src/block/mars/info.txt +++ b/src/block/mars/info.txt @@ -1,11 +1,3 @@ realname "MARS" define MARS - -load_on auto - - -mars.cpp -mars.h -mars_tab.cpp - diff --git a/src/block/misty1/info.txt b/src/block/misty1/info.txt index d45058bd4..38087c83d 100644 --- a/src/block/misty1/info.txt +++ b/src/block/misty1/info.txt @@ -1,10 +1,3 @@ realname "MISTY-1" define MISTY1 - -load_on auto - - -misty1.cpp -misty1.h - diff --git a/src/block/noekeon/info.txt b/src/block/noekeon/info.txt index 8025c2073..6e940bb62 100644 --- a/src/block/noekeon/info.txt +++ b/src/block/noekeon/info.txt @@ -1,10 +1,3 @@ realname "Noekeon" define NOEKEON - -load_on auto - - -noekeon.cpp -noekeon.h - diff --git a/src/block/rc2/info.txt b/src/block/rc2/info.txt index 099141de7..7ec018422 100644 --- a/src/block/rc2/info.txt +++ b/src/block/rc2/info.txt @@ -1,10 +1,3 @@ realname "RC2" define RC2 - -load_on auto - - -rc2.cpp -rc2.h - diff --git a/src/block/rc5/info.txt b/src/block/rc5/info.txt index 4a150c3b0..2032b406f 100644 --- a/src/block/rc5/info.txt +++ b/src/block/rc5/info.txt @@ -1,10 +1,3 @@ realname "RC5" define RC5 - -load_on auto - - -rc5.cpp -rc5.h - diff --git a/src/block/rc6/info.txt b/src/block/rc6/info.txt index 1457e78c1..2897bc1f3 100644 --- a/src/block/rc6/info.txt +++ b/src/block/rc6/info.txt @@ -1,10 +1,3 @@ realname "RC6" define RC6 - -load_on auto - - -rc6.cpp -rc6.h - diff --git a/src/block/safer/info.txt b/src/block/safer/info.txt index 973cbff19..7c8067472 100644 --- a/src/block/safer/info.txt +++ b/src/block/safer/info.txt @@ -1,11 +1,3 @@ realname "SAFER" define SAFER - -load_on auto - - -safe_tab.cpp -safer_sk.cpp -safer_sk.h - diff --git a/src/block/seed/info.txt b/src/block/seed/info.txt index d04979335..c66e0c2cd 100644 --- a/src/block/seed/info.txt +++ b/src/block/seed/info.txt @@ -1,11 +1,3 @@ realname "SEED" define SEED - -load_on auto - - -seed.cpp -seed.h -seed_tab.cpp - diff --git a/src/block/serpent/info.txt b/src/block/serpent/info.txt index baaccbf01..4031a3f5f 100644 --- a/src/block/serpent/info.txt +++ b/src/block/serpent/info.txt @@ -1,10 +1,3 @@ realname "Serpent" define SERPENT - -load_on auto - - -serpent.cpp -serpent.h - diff --git a/src/block/serpent_ia32/info.txt b/src/block/serpent_ia32/info.txt index ea0506299..48d589724 100644 --- a/src/block/serpent_ia32/info.txt +++ b/src/block/serpent_ia32/info.txt @@ -4,12 +4,6 @@ define SERPENT_IA32 load_on asm_ok - -serp_ia32_imp.S -serp_ia32.cpp -serp_ia32.h - - ia32 diff --git a/src/block/serpent_sse2/info.txt b/src/block/serpent_sse2/info.txt index b00ab6e88..da7eef6bc 100644 --- a/src/block/serpent_sse2/info.txt +++ b/src/block/serpent_sse2/info.txt @@ -2,14 +2,6 @@ realname "Serpent (SSE2)" define SERPENT_SSE2 -load_on auto - - -serp_sse2.cpp -serp_sse2.h -serp_sse2_sbox.h - - serpent sse2_eng diff --git a/src/block/skipjack/info.txt b/src/block/skipjack/info.txt index 4b38d6d28..9cdddfe6b 100644 --- a/src/block/skipjack/info.txt +++ b/src/block/skipjack/info.txt @@ -1,10 +1,3 @@ realname "Skipjack" define SKIPJACK - -load_on auto - - -skipjack.cpp -skipjack.h - diff --git a/src/block/square/info.txt b/src/block/square/info.txt index a20697923..7c517be71 100644 --- a/src/block/square/info.txt +++ b/src/block/square/info.txt @@ -1,11 +1,3 @@ realname "Square" define SQUARE - -load_on auto - - -sqr_tab.cpp -square.cpp -square.h - diff --git a/src/block/tea/info.txt b/src/block/tea/info.txt index 6a0e76b15..85a19ee4c 100644 --- a/src/block/tea/info.txt +++ b/src/block/tea/info.txt @@ -1,10 +1,3 @@ realname "TEA" define TEA - -load_on auto - - -tea.cpp -tea.h - diff --git a/src/block/twofish/info.txt b/src/block/twofish/info.txt index 35639d858..319da6e6e 100644 --- a/src/block/twofish/info.txt +++ b/src/block/twofish/info.txt @@ -1,11 +1,3 @@ realname "Twofish" define TWOFISH - -load_on auto - - -two_tab.cpp -twofish.cpp -twofish.h - diff --git a/src/block/xtea/info.txt b/src/block/xtea/info.txt index 0120a3bce..1887e6673 100644 --- a/src/block/xtea/info.txt +++ b/src/block/xtea/info.txt @@ -1,10 +1,3 @@ realname "XTEA" define XTEA - -load_on auto - - -xtea.cpp -xtea.h - -- cgit v1.2.3 From 5f12c043733f7eec2487a31194f6b6bf17276008 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 29 Sep 2009 18:49:49 +0000 Subject: Remove add blocks from hash function info.txt files --- src/hash/bmw/info.txt | 7 ------- src/hash/fork256/info.txt | 7 ------- src/hash/gost_3411/info.txt | 7 ------- src/hash/has160/info.txt | 7 ------- src/hash/md2/info.txt | 7 ------- src/hash/md4/info.txt | 7 ------- src/hash/md4_ia32/info.txt | 6 ------ src/hash/md5/info.txt | 7 ------- src/hash/md5_ia32/info.txt | 6 ------ src/hash/mdx_hash/info.txt | 5 ----- src/hash/par_hash/info.txt | 7 ------- src/hash/rmd128/info.txt | 7 ------- src/hash/rmd160/info.txt | 7 ------- src/hash/sha1/info.txt | 7 ------- src/hash/sha1_amd64/info.txt | 6 ------ src/hash/sha1_ia32/info.txt | 6 ------ src/hash/sha1_sse2/info.txt | 8 -------- src/hash/sha2/info.txt | 9 --------- src/hash/skein/info.txt | 7 ------- src/hash/tiger/info.txt | 8 -------- src/hash/whirlpool/info.txt | 8 -------- 21 files changed, 146 deletions(-) (limited to 'src') diff --git a/src/hash/bmw/info.txt b/src/hash/bmw/info.txt index 3e7e04b31..27e069c0a 100644 --- a/src/hash/bmw/info.txt +++ b/src/hash/bmw/info.txt @@ -2,13 +2,6 @@ realname "Blue Midnight Wish" define BMW_512 -load_on auto - - -bmw_512.cpp -bmw_512.h - - mdx_hash diff --git a/src/hash/fork256/info.txt b/src/hash/fork256/info.txt index ae0c9f1a4..7c3c5bb94 100644 --- a/src/hash/fork256/info.txt +++ b/src/hash/fork256/info.txt @@ -2,13 +2,6 @@ realname "FORK-256" define FORK_256 -load_on auto - - -fork256.cpp -fork256.h - - mdx_hash diff --git a/src/hash/gost_3411/info.txt b/src/hash/gost_3411/info.txt index 65b9475e1..353ceb3e5 100644 --- a/src/hash/gost_3411/info.txt +++ b/src/hash/gost_3411/info.txt @@ -2,13 +2,6 @@ realname "GOST 34.11" define GOST_34_11 -load_on auto - - -gost_3411.cpp -gost_3411.h - - gost_28147 diff --git a/src/hash/has160/info.txt b/src/hash/has160/info.txt index a945f3225..98cbc5155 100644 --- a/src/hash/has160/info.txt +++ b/src/hash/has160/info.txt @@ -2,13 +2,6 @@ realname "HAS-160" define HAS_160 -load_on auto - - -has160.cpp -has160.h - - mdx_hash diff --git a/src/hash/md2/info.txt b/src/hash/md2/info.txt index ff33e1eb3..4428584fd 100644 --- a/src/hash/md2/info.txt +++ b/src/hash/md2/info.txt @@ -1,10 +1,3 @@ realname "MD2" define MD2 - -load_on auto - - -md2.cpp -md2.h - diff --git a/src/hash/md4/info.txt b/src/hash/md4/info.txt index fc9cbe116..6aa4a5d59 100644 --- a/src/hash/md4/info.txt +++ b/src/hash/md4/info.txt @@ -2,13 +2,6 @@ realname "MD4" define MD4 -load_on auto - - -md4.cpp -md4.h - - mdx_hash diff --git a/src/hash/md4_ia32/info.txt b/src/hash/md4_ia32/info.txt index fee7dd1a8..217c3fc21 100644 --- a/src/hash/md4_ia32/info.txt +++ b/src/hash/md4_ia32/info.txt @@ -4,12 +4,6 @@ define MD4_IA32 load_on asm_ok - -md4_ia32_imp.S -md4_ia32.cpp -md4_ia32.h - - ia32 diff --git a/src/hash/md5/info.txt b/src/hash/md5/info.txt index 525a45ab5..14861d635 100644 --- a/src/hash/md5/info.txt +++ b/src/hash/md5/info.txt @@ -2,13 +2,6 @@ realname "MD5" define MD5 -load_on auto - - -md5.cpp -md5.h - - mdx_hash diff --git a/src/hash/md5_ia32/info.txt b/src/hash/md5_ia32/info.txt index ad9923b26..d298f2005 100644 --- a/src/hash/md5_ia32/info.txt +++ b/src/hash/md5_ia32/info.txt @@ -4,12 +4,6 @@ define MD5_IA32 load_on asm_ok - -md5_ia32_imp.S -md5_ia32.cpp -md5_ia32.h - - ia32 diff --git a/src/hash/mdx_hash/info.txt b/src/hash/mdx_hash/info.txt index 412c93350..ee4ccd6da 100644 --- a/src/hash/mdx_hash/info.txt +++ b/src/hash/mdx_hash/info.txt @@ -3,8 +3,3 @@ realname "MDx Hash Base" define MDX_HASH_FUNCTION load_on dep - - -mdx_hash.cpp -mdx_hash.h - diff --git a/src/hash/par_hash/info.txt b/src/hash/par_hash/info.txt index 45716aac8..029939cb5 100644 --- a/src/hash/par_hash/info.txt +++ b/src/hash/par_hash/info.txt @@ -1,10 +1,3 @@ realname "Parallel Hash" define PARALLEL_HASH - -load_on auto - - -par_hash.cpp -par_hash.h - diff --git a/src/hash/rmd128/info.txt b/src/hash/rmd128/info.txt index 402271da5..0a1ef2c74 100644 --- a/src/hash/rmd128/info.txt +++ b/src/hash/rmd128/info.txt @@ -2,13 +2,6 @@ realname "RIPEMD-128" define RIPEMD_128 -load_on auto - - -rmd128.cpp -rmd128.h - - mdx_hash diff --git a/src/hash/rmd160/info.txt b/src/hash/rmd160/info.txt index af4b5c230..225106afc 100644 --- a/src/hash/rmd160/info.txt +++ b/src/hash/rmd160/info.txt @@ -2,13 +2,6 @@ realname "RIPEMD-160" define RIPEMD_160 -load_on auto - - -rmd160.cpp -rmd160.h - - mdx_hash diff --git a/src/hash/sha1/info.txt b/src/hash/sha1/info.txt index a0ae30b4b..8915f9ebd 100644 --- a/src/hash/sha1/info.txt +++ b/src/hash/sha1/info.txt @@ -2,13 +2,6 @@ realname "SHA-1" define SHA1 -load_on auto - - -sha160.cpp -sha160.h - - mdx_hash diff --git a/src/hash/sha1_amd64/info.txt b/src/hash/sha1_amd64/info.txt index ddbc7d380..183658ac7 100644 --- a/src/hash/sha1_amd64/info.txt +++ b/src/hash/sha1_amd64/info.txt @@ -4,12 +4,6 @@ define SHA1_AMD64 load_on asm_ok - -sha1_amd64_imp.S -sha1_amd64.cpp -sha1_amd64.h - - amd64 diff --git a/src/hash/sha1_ia32/info.txt b/src/hash/sha1_ia32/info.txt index bfb321145..e7709454f 100644 --- a/src/hash/sha1_ia32/info.txt +++ b/src/hash/sha1_ia32/info.txt @@ -4,12 +4,6 @@ define SHA1_IA32 load_on asm_ok - -sha1_ia32_imp.S -sha1_ia32.cpp -sha1_ia32.h - - ia32 diff --git a/src/hash/sha1_sse2/info.txt b/src/hash/sha1_sse2/info.txt index 995c2513e..4a7a1b5e9 100644 --- a/src/hash/sha1_sse2/info.txt +++ b/src/hash/sha1_sse2/info.txt @@ -2,14 +2,6 @@ realname "SHA-1 (SSE2)" define SHA1_SSE2 -load_on auto - - -sha1_sse2_imp.cpp -sha1_sse2.cpp -sha1_sse2.h - - sha1 sse2_eng diff --git a/src/hash/sha2/info.txt b/src/hash/sha2/info.txt index 9b92ff385..8cc50fa41 100644 --- a/src/hash/sha2/info.txt +++ b/src/hash/sha2/info.txt @@ -2,15 +2,6 @@ realname "SHA-2 (224, 256, 384, 512)" define SHA2 -load_on auto - - -sha2_32.cpp -sha2_32.h -sha2_64.cpp -sha2_64.h - - mdx_hash diff --git a/src/hash/skein/info.txt b/src/hash/skein/info.txt index bab8497c5..908033852 100644 --- a/src/hash/skein/info.txt +++ b/src/hash/skein/info.txt @@ -2,13 +2,6 @@ realname "Skein" define SKEIN_512 -load_on auto - - -skein_512.cpp -skein_512.h - - alloc diff --git a/src/hash/tiger/info.txt b/src/hash/tiger/info.txt index 7d4cd7177..92b5519c0 100644 --- a/src/hash/tiger/info.txt +++ b/src/hash/tiger/info.txt @@ -2,14 +2,6 @@ realname "Tiger" define TIGER -load_on auto - - -tig_tab.cpp -tiger.cpp -tiger.h - - mdx_hash diff --git a/src/hash/whirlpool/info.txt b/src/hash/whirlpool/info.txt index be55b5c3b..4fe4b2b25 100644 --- a/src/hash/whirlpool/info.txt +++ b/src/hash/whirlpool/info.txt @@ -2,14 +2,6 @@ realname "Whirlpool" define WHIRLPOOL -load_on auto - - -whrl_tab.cpp -whrlpool.cpp -whrlpool.h - - mdx_hash -- cgit v1.2.3 From 965ba216b6782e0b7717b92cbfc54da1e6f8f028 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 29 Sep 2009 18:50:08 +0000 Subject: Remove add block from block/info.txt --- src/block/info.txt | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/block/info.txt b/src/block/info.txt index ff48fb04a..f5840bf79 100644 --- a/src/block/info.txt +++ b/src/block/info.txt @@ -1,13 +1,7 @@ realname "Block Ciphers" -load_on auto - define BLOCK_CIPHER - -block_cipher.h - - sym_algo -- cgit v1.2.3 From f6f5270f04aaee5a29c3562991a1f2378b63652c Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 29 Sep 2009 18:50:58 +0000 Subject: Remove add block from utils/info.txt --- src/utils/info.txt | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'src') diff --git a/src/utils/info.txt b/src/utils/info.txt index c9648af51..6380fd6c2 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -7,30 +7,3 @@ load_on always tru64 -> rt - - -bit_ops.h -bswap.h -charset.cpp -charset.h -cpuid.cpp -cpuid.h -exceptn.cpp -exceptn.h -loadstor.h -mem_ops.h -mlock.h -mlock.cpp -parsing.cpp -parsing.h -prefetch.h -rotate.h -rounding.h -stl_util.h -types.h -ui.cpp -ui.h -version.cpp -version.h -xor_buf.h - -- cgit v1.2.3 From a5e83abdf7d63dd52147ff72bfb15593dcf63046 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 29 Sep 2009 18:51:42 +0000 Subject: Add interface for general runtime self-testing of ciphers, hashes, etc --- src/selftest/selftest.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++----- src/selftest/selftest.h | 7 +++++ 2 files changed, 75 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/selftest/selftest.cpp b/src/selftest/selftest.cpp index d644e866e..6fd6b7fcd 100644 --- a/src/selftest/selftest.cpp +++ b/src/selftest/selftest.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace Botan { @@ -21,17 +22,21 @@ namespace { /* * Perform a Known Answer Test */ +bool test_filter_kat(Filter* filter, + const std::string& input, + const std::string& output) + { + Pipe pipe(new Hex_Decoder, filter, new Hex_Encoder); + pipe.process_msg(input); + + return (output == pipe.read_all_as_string()); + } + void do_kat(const std::string& in, const std::string& out, const std::string& algo_name, Filter* filter) { - if(out.length()) - { - Pipe pipe(new Hex_Decoder, filter, new Hex_Encoder); - pipe.process_msg(in); - - if(out != pipe.read_all_as_string()) - throw Self_Test_Failure(algo_name + " startup test"); - } + if(!test_filter_kat(filter, in, out)) + throw Self_Test_Failure(algo_name + " startup test"); } /* @@ -75,6 +80,61 @@ void cipher_kat(const BlockCipher* proto, } +/* +* Run a set of KATs +*/ +std::map +algorithm_kat(const std::string& name, + const std::map& vars, + Algorithm_Factory& af) + { + std::vector providers = af.providers_of(name); + std::map all_results; + + if(providers.empty()) // no providers, nothing to do + return all_results; + + const std::string input = search_map(vars, std::string("input")); + const std::string output = search_map(vars, std::string("output")); + const std::string key = search_map(vars, std::string("key")); + + for(u32bit i = 0; i != providers.size(); ++i) + { + const std::string provider = providers[i]; + + if(const HashFunction* proto = + af.prototype_hash_function(name, provider)) + { + all_results[provider] = test_filter_kat(new Hash_Filter(proto->clone()), + input, output); + } + else if(const MessageAuthenticationCode* proto = + af.prototype_mac(name, provider)) + { + all_results[provider] = test_filter_kat(new MAC_Filter(proto->clone(), key), + input, output); + } + +#if 0 + if(const BlockCipher* proto = + af.prototype_block_cipher(name, provider)) + { + std::auto_ptr block_cipher(proto->clone()); + all_results[provider] = test_block_cipher(block_cipher.get()); + } + else if(const StreamCipher* proto = + af.prototype_stream_cipher(name, provider)) + { + std::auto_ptr stream_cipher(proto->clone()); + all_results[provider] = test_stream_cipher(stream_cipher.get()); + } + else +#endif + } + + return all_results; + } + /* * Perform Self Tests */ diff --git a/src/selftest/selftest.h b/src/selftest/selftest.h index 9e36d2298..b5fc9f80a 100644 --- a/src/selftest/selftest.h +++ b/src/selftest/selftest.h @@ -9,6 +9,8 @@ #define BOTAN_SELF_TESTS_H__ #include +#include +#include namespace Botan { @@ -17,6 +19,11 @@ namespace Botan { */ BOTAN_DLL bool passes_self_tests(Algorithm_Factory& af); +BOTAN_DLL std::map +algorithm_kat(const std::string& name, + const std::map& vars, + Algorithm_Factory& af); + } #endif -- cgit v1.2.3 From 096ed3cfa340aa7c917da7a92ddade6dd69ab758 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 29 Sep 2009 19:04:53 +0000 Subject: Change the prefetching interface; move to PREFETCH namespace, and add a helper function for fetching both inputs and outputs of block ciphers. --- src/utils/prefetch.h | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/utils/prefetch.h b/src/utils/prefetch.h index 100829dce..72b6de689 100644 --- a/src/utils/prefetch.h +++ b/src/utils/prefetch.h @@ -12,28 +12,44 @@ namespace Botan { -inline void prefetch_readonly(const void* addr_void, u32bit length) +namespace PREFETCH { + +template +inline void readonly(const T* addr, u32bit length) { #if defined(__GNUG__) - const byte* addr = static_cast(addr_void); - const u32bit cl_size = CPUID::cache_line_size(); + const u32bit Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); - for(u32bit i = 0; i <= length; i += cl_size) + for(u32bit i = 0; i <= length; i += Ts_per_cache_line) __builtin_prefetch(addr + i, 0); #endif } -inline void prefetch_readwrite(const void* addr_void, u32bit length) +template +inline void readwrite(const T* addr, u32bit length) { #if defined(__GNUG__) - const byte* addr = static_cast(addr_void); - const u32bit cl_size = CPUID::cache_line_size(); + const u32bit Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); - for(u32bit i = 0; i <= length; i += cl_size) - __builtin_prefetch(addr + i, 1); + for(u32bit i = 0; i <= length; i += Ts_per_cache_line) + __builtin_prefetch(addr + i, 0); #endif } +inline void cipher_fetch(const byte* in_block, + const byte* out_block, + u32bit blocks, + u32bit block_size) + { + // Only prefetch input specifically if in != out + if(in_block != out_block) + readonly(in_block, blocks * block_size); + + readwrite(out_block, blocks * block_size); + } + +} + } #endif -- cgit v1.2.3 From 9a45274e5d7e91fa8cc0a13de3ec9b8195f96611 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 29 Sep 2009 19:07:31 +0000 Subject: Use prefetching in AES. Nominally, this will help somewhat with preventing timing attacks, since once all the TE/SE tables are entirely in cache then timing attacks against it become somewhat harder. However for this to be a full defense it would be necessary to ensure the tables were entirely loaded into cache, which is not guaranteed by the normal SSE prefetch instructions. (Or prefetch instructions for other CPUs, AFAIK). Much more importantly, it provides a 10% speedup. --- src/block/aes/aes.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/block/aes/aes.cpp b/src/block/aes/aes.cpp index 34698ae7f..8ef9cd8fe 100644 --- a/src/block/aes/aes.cpp +++ b/src/block/aes/aes.cpp @@ -20,6 +20,10 @@ void AES::encrypt_n(const byte in[], byte out[], u32bit blocks) const const u32bit* TE2 = TE + 512; const u32bit* TE3 = TE + 768; + PREFETCH::readonly(TE, 1024); + PREFETCH::readonly(SE, 256); + PREFETCH::cipher_fetch(in, out, blocks, this->BLOCK_SIZE); + for(u32bit i = 0; i != blocks; ++i) { u32bit T0 = load_be(in, 0) ^ EK[0]; @@ -114,6 +118,10 @@ void AES::decrypt_n(const byte in[], byte out[], u32bit blocks) const const u32bit* TD2 = TD + 512; const u32bit* TD3 = TD + 768; + PREFETCH::readonly(TD, 1024); + PREFETCH::readonly(SD, 256); + PREFETCH::cipher_fetch(in, out, blocks, this->BLOCK_SIZE); + for(u32bit i = 0; i != blocks; ++i) { u32bit T0 = load_be(in, 0) ^ DK[0]; -- cgit v1.2.3 From 25fad1ac3bab1c8ed04673b223946e2510c93da9 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 29 Sep 2009 20:14:35 +0000 Subject: Significantly rework CPUID support. Add cache line detection --- doc/examples/cpuid.cpp | 15 +++++++ src/utils/cpuid.cpp | 118 ++++++++++++++++++++++++------------------------- src/utils/cpuid.h | 68 +++++++++++++++++----------- 3 files changed, 114 insertions(+), 87 deletions(-) create mode 100644 doc/examples/cpuid.cpp (limited to 'src') diff --git a/doc/examples/cpuid.cpp b/doc/examples/cpuid.cpp new file mode 100644 index 000000000..59940b500 --- /dev/null +++ b/doc/examples/cpuid.cpp @@ -0,0 +1,15 @@ +#include + +#include + +using namespace Botan; + +int main() + { + printf("Cache line size: %d\n", CPUID::cache_line_size()); + printf("RDTSC: %d\n", CPUID::has_rdtsc()); + printf("SSE2 %d\n", CPUID::has_sse2()); + printf("SSSE3 %d\n", CPUID::has_ssse3()); + printf("SSE41 %d\n", CPUID::has_sse41()); + printf("SSE42 %d\n", CPUID::has_sse42()); + } diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index d5149e2e5..6326e84ad 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -7,6 +7,10 @@ #include #include +#include +#include + +#include #if defined(_MSC_VER) #include @@ -14,95 +18,87 @@ namespace Botan { -namespace CPUID { - namespace { -/* -* Call the x86 CPUID instruction and return the contents of ecx and -* edx, which contain the feature masks. -*/ -u64bit x86_processor_flags() +void x86_cpuid(u32bit type, u32bit out[4]) { - static u64bit proc_flags = 0; - - if(proc_flags) - return proc_flags; - -#if defined(BOTAN_TARGET_ARCH_IS_X86) || defined(BOTAN_TARGET_ARCH_IS_AMD64) + out[0] = out[1] = out[2] = out[3] = 0; #if defined(BOTAN_BUILD_COMPILER_IS_GCC) - u32bit a = 1, b = 0, c = 0, d = 0; +#if defined(BOTAN_TARGET_ARCH_IS_X86) -#if defined(__i386__) && defined(__PIC__) - // ebx is reserved for PIC on 32-bit x86, so save and restore it - asm("xchgl %%ebx, %1\n\t" - "cpuid\n\t" - "xchgl %%ebx, %1\n\t" - : "=a" (a), "=r" (b), "=c" (c), "=d" (d) : "0" (a)); -#else - // if not PIC or in 64-bit mode, can smash ebx - asm("cpuid" : "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "0" (a)); + asm("pushq %%ebx; cpuid; mov %%ebx, %%edi; popq %%ebx" + : "=a" (out[0]), "=D" (out[1]), "=c" (out[2]), "=d" (out[3]) + : "0" (type)); -#endif +#elif defined(BOTAN_TARGET_ARCH_IS_AMD64) - proc_flags = ((u64bit)c << 32) | d; + asm("pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" + : "=a" (out[0]), "=D" (out[1]), "=c" (out[2]), "=d" (out[3]) + : "0" (type)); +#endif #elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) + __cpuid(out, type); +#endif + } - int cpuinfo[4] = { 0 }; - __cpuid(cpuinfo, 1); +u32bit get_x86_cache_line_size() + { + const u32bit INTEL_CPUID[3] = { 0x756E6547, 0x6C65746E, 0x49656E69 }; + const u32bit AMD_CPUID[3] = { 0, 0, 0 }; - proc_flags = ((u64bit)cpuinfo[2] << 32) | cpuinfo[3]; + u32bit cpuid[4] = { 0 }; + x86_cpuid(0, cpuid); -#endif + if(same_mem(cpuid + 1, INTEL_CPUID, 3) && cpuid[0] > 2) + { + x86_cpuid(1, cpuid); + return 8 * get_byte(2, cpuid[1]); + } -#endif + if(same_mem(cpuid + 1, AMD_CPUID, 3)) + { + x86_cpuid(0x80000005, cpuid); + return get_byte(3, cpuid[2]); + } - return proc_flags; + return 32; // default cache line guess } -enum CPUID_bits { - CPUID_RDTSC_BIT = 4, - CPUID_SSE2_BIT = 26, - CPUID_SSSE3_BIT = 41, - CPUID_SSE41_BIT = 51, - CPUID_SSE42_BIT = 52 -}; - } -u32bit cache_line_size() +/* +* Call the x86 CPUID instruction and return the contents of ecx and +* edx, which contain the feature masks. +*/ +u64bit CPUID::x86_processor_flags() { - return 32; // FIXME! - } + static u64bit proc_flags = 0; -bool has_rdtsc() - { - return ((x86_processor_flags() >> CPUID_RDTSC_BIT) & 1); - } + if(proc_flags) + return proc_flags; -bool has_sse2() - { - return ((x86_processor_flags() >> CPUID_SSE2_BIT) & 1); - } + u32bit cpuid[4] = { 0 }; + x86_cpuid(1, cpuid); -bool has_ssse3() - { - return ((x86_processor_flags() >> CPUID_SSSE3_BIT) & 1); - } + // Set the FPU bit on to force caching in proc_flags + proc_flags = ((u64bit)cpuid[2] << 32) | cpuid[3] | 1; -bool has_sse41() - { - return ((x86_processor_flags() >> CPUID_SSE41_BIT) & 1); + return proc_flags; } -bool has_sse42() +u32bit CPUID::cache_line_size() { - return ((x86_processor_flags() >> CPUID_SSE42_BIT) & 1); - } + static u32bit cl_size = 0; -} + if(cl_size) + return cl_size; + + cl_size = get_x86_cache_line_size(); + + return cl_size; + } } diff --git a/src/utils/cpuid.h b/src/utils/cpuid.h index 557590db8..5f21e2310 100644 --- a/src/utils/cpuid.h +++ b/src/utils/cpuid.h @@ -12,39 +12,55 @@ namespace Botan { -namespace CPUID { +class CPUID + { + public: + enum CPUID_bits { + CPUID_RDTSC_BIT = 4, + CPUID_SSE2_BIT = 26, + CPUID_SSSE3_BIT = 41, + CPUID_SSE41_BIT = 51, + CPUID_SSE42_BIT = 52 + }; -/** -* Return a best guess of the cache line size -*/ -u32bit cache_line_size(); + /** + * Return a best guess of the cache line size + */ + static u32bit cache_line_size(); -/** -* Check if the processor supports RDTSC -*/ -bool has_rdtsc(); + /** + * Check if the processor supports RDTSC + */ + static bool has_rdtsc() + { return ((x86_processor_flags() >> CPUID_RDTSC_BIT) & 1); } -/** -* Check if the processor supports SSE2 -*/ -bool has_sse2(); + /** + * Check if the processor supports SSE2 + */ + static bool has_sse2() + { return ((x86_processor_flags() >> CPUID_SSE2_BIT) & 1); } -/** -* Check if the processor supports SSSE3 -*/ -bool has_ssse3(); + /** + * Check if the processor supports SSSE3 + */ + static bool has_ssse3() + { return ((x86_processor_flags() >> CPUID_SSSE3_BIT) & 1); } -/** -* Check if the processor supports SSE4.1 -*/ -bool has_sse41(); + /** + * Check if the processor supports SSE4.1 + */ + static bool has_sse41() + { return ((x86_processor_flags() >> CPUID_SSE41_BIT) & 1); } -/** -* Check if the processor supports SSE4.2 -*/ -bool has_sse42(); + /** + * Check if the processor supports SSE4.2 + */ + static bool has_sse42() + { return ((x86_processor_flags() >> CPUID_SSE42_BIT) & 1); } -} + private: + static u64bit x86_processor_flags(); + }; } -- cgit v1.2.3 From 92fa61dd9909f39bacd8f2f64ae1d11c9fd1fb49 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 29 Sep 2009 20:17:50 +0000 Subject: Add vendor ID for AMD --- src/utils/cpuid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index 6326e84ad..eb50dee98 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -47,7 +47,7 @@ void x86_cpuid(u32bit type, u32bit out[4]) u32bit get_x86_cache_line_size() { const u32bit INTEL_CPUID[3] = { 0x756E6547, 0x6C65746E, 0x49656E69 }; - const u32bit AMD_CPUID[3] = { 0, 0, 0 }; + const u32bit AMD_CPUID[3] = { 0x68747541, 0x444D4163, 0x69746E65 }; u32bit cpuid[4] = { 0 }; x86_cpuid(0, cpuid); -- cgit v1.2.3 From 90180351e7370d0b6b93c2a69a5298bd4805ac83 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 30 Sep 2009 01:15:51 +0000 Subject: Add cpuid check for Intel AES --- src/utils/cpuid.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/utils/cpuid.h b/src/utils/cpuid.h index 5f21e2310..0b210768a 100644 --- a/src/utils/cpuid.h +++ b/src/utils/cpuid.h @@ -20,7 +20,8 @@ class CPUID CPUID_SSE2_BIT = 26, CPUID_SSSE3_BIT = 41, CPUID_SSE41_BIT = 51, - CPUID_SSE42_BIT = 52 + CPUID_SSE42_BIT = 52, + CPUID_INTEL_AES_BIT = 57, }; /** @@ -58,6 +59,12 @@ class CPUID static bool has_sse42() { return ((x86_processor_flags() >> CPUID_SSE42_BIT) & 1); } + /** + * Check if the processor supports Intel AES instructions + */ + static bool has_intel_aes() + { return ((x86_processor_flags() >> CPUID_INTEL_AES_BIT) & 1); } + private: static u64bit x86_processor_flags(); }; -- cgit v1.2.3 From 59b4eb0bd2d1b9d65c3921f5205a012f1a98fdf8 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 30 Sep 2009 01:29:06 +0000 Subject: Disable prefetch in AES for now. Problem: with iterative modes like CBC, the prefetch is called for each block of input, and so a total of (4096+256)/64 = 68 prefetches are executed for each block. This reduces performance of iterative modes dramatically. I'm not sure what the right approach for dealing with this is. --- src/block/aes/aes.cpp | 8 -------- src/utils/prefetch.h | 12 ------------ 2 files changed, 20 deletions(-) (limited to 'src') diff --git a/src/block/aes/aes.cpp b/src/block/aes/aes.cpp index 8ef9cd8fe..34698ae7f 100644 --- a/src/block/aes/aes.cpp +++ b/src/block/aes/aes.cpp @@ -20,10 +20,6 @@ void AES::encrypt_n(const byte in[], byte out[], u32bit blocks) const const u32bit* TE2 = TE + 512; const u32bit* TE3 = TE + 768; - PREFETCH::readonly(TE, 1024); - PREFETCH::readonly(SE, 256); - PREFETCH::cipher_fetch(in, out, blocks, this->BLOCK_SIZE); - for(u32bit i = 0; i != blocks; ++i) { u32bit T0 = load_be(in, 0) ^ EK[0]; @@ -118,10 +114,6 @@ void AES::decrypt_n(const byte in[], byte out[], u32bit blocks) const const u32bit* TD2 = TD + 512; const u32bit* TD3 = TD + 768; - PREFETCH::readonly(TD, 1024); - PREFETCH::readonly(SD, 256); - PREFETCH::cipher_fetch(in, out, blocks, this->BLOCK_SIZE); - for(u32bit i = 0; i != blocks; ++i) { u32bit T0 = load_be(in, 0) ^ DK[0]; diff --git a/src/utils/prefetch.h b/src/utils/prefetch.h index 72b6de689..7afdbda0a 100644 --- a/src/utils/prefetch.h +++ b/src/utils/prefetch.h @@ -36,18 +36,6 @@ inline void readwrite(const T* addr, u32bit length) #endif } -inline void cipher_fetch(const byte* in_block, - const byte* out_block, - u32bit blocks, - u32bit block_size) - { - // Only prefetch input specifically if in != out - if(in_block != out_block) - readonly(in_block, blocks * block_size); - - readwrite(out_block, blocks * block_size); - } - } } -- cgit v1.2.3 From 0e754f618419f586d8e56bd7632328390eff4b55 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 6 Oct 2009 01:24:05 +0000 Subject: Clean up cpuid calling --- src/utils/cpuid.cpp | 58 ++++++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index eb50dee98..ae82bdac8 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -10,39 +10,34 @@ #include #include -#include +#if defined(BOTAN_TARGET_ARCH_IS_X86) || defined(BOTAN_TARGET_ARCH_IS_AMD64) -#if defined(_MSC_VER) - #include -#endif - -namespace Botan { +#if defined(BOTAN_BUILD_COMPILER_IS_MSVC) -namespace { - -void x86_cpuid(u32bit type, u32bit out[4]) - { - out[0] = out[1] = out[2] = out[3] = 0; + #include + #define CALL_CPUID(type, out) do { __cpuid(out, type) } while(0) -#if defined(BOTAN_BUILD_COMPILER_IS_GCC) +#elif defined(BOTAN_BUILD_COMPILER_IS_ICC) -#if defined(BOTAN_TARGET_ARCH_IS_X86) + #include + #define CALL_CPUID(type, out) do { __cpuid(out, type) } while(0); - asm("pushq %%ebx; cpuid; mov %%ebx, %%edi; popq %%ebx" - : "=a" (out[0]), "=D" (out[1]), "=c" (out[2]), "=d" (out[3]) - : "0" (type)); +#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) -#elif defined(BOTAN_TARGET_ARCH_IS_AMD64) + #include + #define CALL_CPUID(type, out) \ + do { __get_cpuid(type, out, out+1, out+2, out+3); } while(0); - asm("pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" - : "=a" (out[0]), "=D" (out[1]), "=c" (out[2]), "=d" (out[3]) - : "0" (type)); #endif -#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) - __cpuid(out, type); +#else + // In all other cases, just zeroize the supposed cpuid output + #define CALL_CPUID(type, out) out[0] = out[1] = out[2] = out[3] = 0; #endif - } + +namespace Botan { + +namespace { u32bit get_x86_cache_line_size() { @@ -50,21 +45,20 @@ u32bit get_x86_cache_line_size() const u32bit AMD_CPUID[3] = { 0x68747541, 0x444D4163, 0x69746E65 }; u32bit cpuid[4] = { 0 }; - x86_cpuid(0, cpuid); + CALL_CPUID(0, cpuid); - if(same_mem(cpuid + 1, INTEL_CPUID, 3) && cpuid[0] > 2) + if(same_mem(cpuid + 1, INTEL_CPUID, 3)) { - x86_cpuid(1, cpuid); + CALL_CPUID(1, cpuid); return 8 * get_byte(2, cpuid[1]); } - - if(same_mem(cpuid + 1, AMD_CPUID, 3)) + else if(same_mem(cpuid + 1, AMD_CPUID, 3)) { - x86_cpuid(0x80000005, cpuid); + CALL_CPUID(0x80000005, cpuid); return get_byte(3, cpuid[2]); } - - return 32; // default cache line guess + else + return 32; // default cache line guess } } @@ -81,7 +75,7 @@ u64bit CPUID::x86_processor_flags() return proc_flags; u32bit cpuid[4] = { 0 }; - x86_cpuid(1, cpuid); + CALL_CPUID(1, cpuid); // Set the FPU bit on to force caching in proc_flags proc_flags = ((u64bit)cpuid[2] << 32) | cpuid[3] | 1; -- cgit v1.2.3 From a37a57edd56b3fcf449f7028f4fd70a2efb9c789 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 6 Oct 2009 14:12:34 +0000 Subject: Add an implementation of threshold secret sharing from draft-mcgrew-tss-02 --- doc/log.txt | 5 +- src/tss/info.txt | 8 ++ src/tss/tss.cpp | 265 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/tss/tss.h | 55 ++++++++++++ 4 files changed, 331 insertions(+), 2 deletions(-) create mode 100644 src/tss/info.txt create mode 100644 src/tss/tss.cpp create mode 100644 src/tss/tss.h (limited to 'src') diff --git a/doc/log.txt b/doc/log.txt index c0193c235..c321fee5b 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -1,9 +1,10 @@ * 1.9.1-pre, 2009-??-?? - - Enable SSE2 optimizations under Visual C++ - - Add runtime checking for SSE2 availability - Add an implementation of Blue Midnight Wish (Round 2 tweak version) + - Add threshold secret sharing (draft-mcgrew-tss-02) + - Add runtime cpu feature detection for x86/x86-64 - Alter Skein-512 to match the tweaked 1.2 specification + - Enable SSE2 optimizations under Visual C++ * 1.9.0, 2009-09-09 - Add support for parallel invocation of block ciphers where possible diff --git a/src/tss/info.txt b/src/tss/info.txt new file mode 100644 index 000000000..af4e0b930 --- /dev/null +++ b/src/tss/info.txt @@ -0,0 +1,8 @@ +realname "Threshold Secret Sharing" + + +hash +rng +filters +hex + diff --git a/src/tss/tss.cpp b/src/tss/tss.cpp new file mode 100644 index 000000000..5b8539330 --- /dev/null +++ b/src/tss/tss.cpp @@ -0,0 +1,265 @@ +/* +* RTSS (threshold secret sharing) +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace Botan { + +namespace { + +/** +Table for GF(2^8) arithmetic (exponentials) +*/ +const byte EXP[256] = { +0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, +0x96, 0xA1, 0xF8, 0x13, 0x35, 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, +0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA, 0xE5, +0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, +0x90, 0xAB, 0xE6, 0x31, 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, +0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD, 0x4C, 0xD4, +0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, +0x28, 0x78, 0x88, 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, +0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A, 0xB5, 0xC4, 0x57, +0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, +0x61, 0xA3, 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, +0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0, 0xFB, 0x16, 0x3A, 0x4E, +0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, +0x41, 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, +0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75, 0x9F, 0xBA, 0xD5, 0x64, 0xAC, +0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80, +0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, +0xB1, 0xC8, 0x43, 0xC5, 0x54, 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, +0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA, 0x45, +0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, +0xC6, 0x51, 0xF3, 0x0E, 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, +0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17, 0x39, 0x4B, +0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, +0x52, 0xF6, 0x01 }; + +/** +Table for GF(2^8) arithmetic (logarithms) +*/ +const byte LOG[] = { +0x90, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1A, 0xC6, 0x4B, 0xC7, 0x1B, +0x68, 0x33, 0xEE, 0xDF, 0x03, 0x64, 0x04, 0xE0, 0x0E, 0x34, 0x8D, +0x81, 0xEF, 0x4C, 0x71, 0x08, 0xC8, 0xF8, 0x69, 0x1C, 0xC1, 0x7D, +0xC2, 0x1D, 0xB5, 0xF9, 0xB9, 0x27, 0x6A, 0x4D, 0xE4, 0xA6, 0x72, +0x9A, 0xC9, 0x09, 0x78, 0x65, 0x2F, 0x8A, 0x05, 0x21, 0x0F, 0xE1, +0x24, 0x12, 0xF0, 0x82, 0x45, 0x35, 0x93, 0xDA, 0x8E, 0x96, 0x8F, +0xDB, 0xBD, 0x36, 0xD0, 0xCE, 0x94, 0x13, 0x5C, 0xD2, 0xF1, 0x40, +0x46, 0x83, 0x38, 0x66, 0xDD, 0xFD, 0x30, 0xBF, 0x06, 0x8B, 0x62, +0xB3, 0x25, 0xE2, 0x98, 0x22, 0x88, 0x91, 0x10, 0x7E, 0x6E, 0x48, +0xC3, 0xA3, 0xB6, 0x1E, 0x42, 0x3A, 0x6B, 0x28, 0x54, 0xFA, 0x85, +0x3D, 0xBA, 0x2B, 0x79, 0x0A, 0x15, 0x9B, 0x9F, 0x5E, 0xCA, 0x4E, +0xD4, 0xAC, 0xE5, 0xF3, 0x73, 0xA7, 0x57, 0xAF, 0x58, 0xA8, 0x50, +0xF4, 0xEA, 0xD6, 0x74, 0x4F, 0xAE, 0xE9, 0xD5, 0xE7, 0xE6, 0xAD, +0xE8, 0x2C, 0xD7, 0x75, 0x7A, 0xEB, 0x16, 0x0B, 0xF5, 0x59, 0xCB, +0x5F, 0xB0, 0x9C, 0xA9, 0x51, 0xA0, 0x7F, 0x0C, 0xF6, 0x6F, 0x17, +0xC4, 0x49, 0xEC, 0xD8, 0x43, 0x1F, 0x2D, 0xA4, 0x76, 0x7B, 0xB7, +0xCC, 0xBB, 0x3E, 0x5A, 0xFB, 0x60, 0xB1, 0x86, 0x3B, 0x52, 0xA1, +0x6C, 0xAA, 0x55, 0x29, 0x9D, 0x97, 0xB2, 0x87, 0x90, 0x61, 0xBE, +0xDC, 0xFC, 0xBC, 0x95, 0xCF, 0xCD, 0x37, 0x3F, 0x5B, 0xD1, 0x53, +0x39, 0x84, 0x3C, 0x41, 0xA2, 0x6D, 0x47, 0x14, 0x2A, 0x9E, 0x5D, +0x56, 0xF2, 0xD3, 0xAB, 0x44, 0x11, 0x92, 0xD9, 0x23, 0x20, 0x2E, +0x89, 0xB4, 0x7C, 0xB8, 0x26, 0x77, 0x99, 0xE3, 0xA5, 0x67, 0x4A, +0xED, 0xDE, 0xC5, 0x31, 0xFE, 0x18, 0x0D, 0x63, 0x8C, 0x80, 0xC0, +0xF7, 0x70, 0x07 }; + +byte gfp_mul(byte x, byte y) + { + if(x == 0 || y == 0) + return 0; + return EXP[(LOG[x] + LOG[y]) % 255]; + } + +byte rtss_hash_id(const std::string& hash_name) + { + if(hash_name == "SHA-160") + return 1; + else if(hash_name == "SHA-256") + return 2; + else + throw Invalid_Argument("RTSS only supports SHA-1 and SHA-256"); + } + +HashFunction* get_rtss_hash_by_id(byte id) + { + if(id == 1) + return new SHA_160; + else if(id == 2) + return new SHA_256; + else + throw Decoding_Error("Bad RTSS hash identifier"); + } + +} + +RTSS_Share::RTSS_Share(const std::string& hex_input) + { + Pipe pipe(new Hex_Decoder); + pipe.process_msg(hex_input); + contents = pipe.read_all(); + } + +byte RTSS_Share::share_id() const + { + if(!initialized()) + throw Invalid_State("RTSS_Share::share_id not initialized"); + + return contents[20]; + } + +std::string RTSS_Share::to_string() const + { + Pipe pipe(new Hex_Encoder); + pipe.process_msg(contents); + return pipe.read_all_as_string(); + } + +std::vector +RTSS_Share::split(byte M, byte N, + const byte S[], u16bit S_len, + const byte identifier[16], + RandomNumberGenerator& rng) + { + if(M == 0 || N == 0 || M > N) + throw Encoding_Error("RTSS_Share::split: M == 0 or N == 0 or M > N"); + + SHA_256 hash; // always use SHA-256 when generating shares + + std::vector shares(N); + + // Create RTSS header in each share + for(byte i = 0; i != N; ++i) + { + shares[i].contents.append(identifier, 16); + shares[i].contents.append(rtss_hash_id(hash.name())); + shares[i].contents.append(M); + shares[i].contents.append(get_byte(0, S_len)); + shares[i].contents.append(get_byte(1, S_len)); + } + + // Choose sequential values for X starting from 1 + for(byte i = 0; i != N; ++i) + shares[i].contents.append(i+1); + + // secret = S || H(S) + SecureVector secret(S, S_len); + secret.append(hash.process(S, S_len)); + + for(size_t i = 0; i != secret.size(); ++i) + { + std::vector coefficients(M-1); + rng.randomize(&coefficients[0], coefficients.size()); + + for(byte j = 0; j != N; ++j) + { + const byte X = j + 1; + + byte sum = secret[i]; + byte X_i = X; + + for(size_t k = 0; k != coefficients.size(); ++k) + { + sum ^= gfp_mul(X_i, coefficients[k]); + X_i = gfp_mul(X_i, X); + } + + shares[j].contents.append(sum); + } + } + + return shares; + } + +SecureVector +RTSS_Share::reconstruct(const std::vector& shares) + { + const u32bit RTSS_HEADER_SIZE = 20; + + for(size_t i = 0; i != shares.size(); ++i) + { + if(shares[i].size() != shares[0].size()) + throw Decoding_Error("Different sized RTSS shares detected"); + if(shares[i].share_id() == 0) + throw Decoding_Error("Invalid (id = 0) RTSS share detected"); + if(shares[i].size() < RTSS_HEADER_SIZE) + throw Decoding_Error("Missing or malformed RTSS header"); + + if(!same_mem(shares[0].contents.begin(), + shares[i].contents.begin(), RTSS_HEADER_SIZE)) + throw Decoding_Error("Different RTSS headers detected"); + } + + if(shares.size() < shares[0].contents[17]) + throw Decoding_Error("Insufficient shares to do TSS reconstruction"); + + u16bit secret_len = make_u16bit(shares[0].contents[18], + shares[0].contents[19]); + + byte hash_id = shares[0].contents[16]; + + std::auto_ptr hash(get_rtss_hash_by_id(hash_id)); + + if(shares[0].size() != secret_len + hash->OUTPUT_LENGTH + RTSS_HEADER_SIZE + 1) + throw Decoding_Error("Bad RTSS length field in header"); + + std::vector V(shares.size()); + SecureVector secret; + + for(size_t i = RTSS_HEADER_SIZE + 1; i != shares[0].size(); ++i) + { + for(size_t j = 0; j != V.size(); ++j) + V[j] = shares[j].contents[i]; + + byte r = 0; + for(size_t k = 0; k != shares.size(); ++k) + { + // L_i function: + byte r2 = 1; + for(size_t l = 0; l != shares.size(); ++l) + { + if(k == l) + continue; + + byte share_k = shares[k].share_id(); + byte share_l = shares[l].share_id(); + + if(share_k == share_l) + throw Decoding_Error("Duplicate shares found in RTSS recovery"); + + byte div = EXP[(255 + LOG[share_l] - LOG[share_k ^ share_l]) % 255]; + + r2 = gfp_mul(r2, div); + } + + r ^= gfp_mul(V[k], r2); + } + secret.append(r); + } + + if(secret.size() != secret_len + hash->OUTPUT_LENGTH) + throw Decoding_Error("Bad length in RTSS output"); + + hash->update(secret, secret_len); + SecureVector hash_check = hash->final(); + + if(!same_mem(hash_check.begin(), secret + secret_len, hash->OUTPUT_LENGTH)) + throw Decoding_Error("RTSS hash check failed"); + + return SecureVector(secret, secret_len); + } + +} diff --git a/src/tss/tss.h b/src/tss/tss.h new file mode 100644 index 000000000..0b26bfdcb --- /dev/null +++ b/src/tss/tss.h @@ -0,0 +1,55 @@ +/* +* RTSS (threshold secret sharing) +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_RTSS_H__ +#define BOTAN_RTSS_H__ + +#include +#include +#include +#include + +namespace Botan { + +class RTSS_Share + { + public: + /** + * @arg M the number of shares needed to reconstruct + * @arg N the number of shares generated + * @arg secret the secret to split + * @arg secret_len the length of the secret + * @arg identifier the 16 byte share identifier + * @arg rng the random number generator to use + */ + static std::vector + split(byte M, byte N, + const byte secret[], u16bit secret_len, + const byte identifier[16], + RandomNumberGenerator& rng); + + /** + * @arg shares the list of shares + */ + static SecureVector + reconstruct(const std::vector& shares); + + RTSS_Share() {} + RTSS_Share(const std::string&); + + std::string to_string() const; + byte share_id() const; + + u32bit size() const { return contents.size(); } + bool initialized() const { return contents.size(); } + private: + SecureVector contents; + }; + +} + +#endif -- cgit v1.2.3 From f05bf5994ae8955501e2355b63ec35e575125374 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 6 Oct 2009 16:02:54 +0000 Subject: In to_u32bit, ignore space characters in input --- src/utils/parsing.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/utils/parsing.cpp b/src/utils/parsing.cpp index bdb9e79dc..58a8e0b38 100644 --- a/src/utils/parsing.cpp +++ b/src/utils/parsing.cpp @@ -23,6 +23,9 @@ u32bit to_u32bit(const std::string& number) { const u32bit OVERFLOW_MARK = 0xFFFFFFFF / 10; + if(*j == ' ') + continue; + byte digit = Charset::char2digit(*j); if((n > OVERFLOW_MARK) || (n == OVERFLOW_MARK && digit > 5)) -- cgit v1.2.3 From c86253042f0dab70fcf15030b25fcbc1a00dde76 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 6 Oct 2009 16:03:33 +0000 Subject: Extensions to SCAN_Name for dealing with cipher mode names --- src/libstate/scan_name.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++--- src/libstate/scan_name.h | 19 +++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/libstate/scan_name.cpp b/src/libstate/scan_name.cpp index 88992d66e..13792720c 100644 --- a/src/libstate/scan_name.cpp +++ b/src/libstate/scan_name.cpp @@ -44,10 +44,50 @@ SCAN_Name::SCAN_Name(const std::string& algo_spec) { orig_algo_spec = algo_spec; - name = parse_and_deref_aliases(algo_spec); + try + { + name = parse_and_deref_aliases(algo_spec); + if(name.size() == 0) + throw Decoding_Error("Bad SCAN name " + algo_spec); + } + catch(Invalid_Algorithm_Name) + { + name.clear(); + } + + if(name.size() == 0 && algo_spec.find('/') != std::string::npos) + { + std::vector algo_parts = split_on(algo_spec, '/'); + + name = parse_and_deref_aliases(algo_parts[0]); + if(name.size() == 0) + throw Decoding_Error("Bad SCAN name " + algo_spec); + + for(size_t i = 1; i != algo_parts.size(); ++i) + mode_str.push_back(algo_parts[i]); + } + } - if(name.size() == 0) - throw Decoding_Error("Bad SCAN name " + algo_spec); +std::string SCAN_Name::algo_name_and_args() const + { + std::string out; + + out = name[0]; + + if(arg_count()) + { + out += '('; + for(u32bit i = 0; i != arg_count(); ++i) + { + out += arg(i); + if(i != arg_count() - 1) + out += ','; + } + out += ')'; + + } + + return out; } std::string SCAN_Name::arg(u32bit i) const diff --git a/src/libstate/scan_name.h b/src/libstate/scan_name.h index b3f2004e2..6dbd67c4f 100644 --- a/src/libstate/scan_name.h +++ b/src/libstate/scan_name.h @@ -37,6 +37,11 @@ class SCAN_Name */ std::string algo_name() const { return name[0]; } + /** + @return the algorithm name plus any arguments + */ + std::string algo_name_and_args() const; + /** @return the number of arguments */ @@ -67,9 +72,23 @@ class SCAN_Name @return the ith argument as a u32bit, or the default value */ u32bit arg_as_u32bit(u32bit i, u32bit def_value) const; + + /** + @return the cipher mode (if any) + */ + std::string cipher_mode() const + { return (mode_str.size() >= 1) ? mode_str[0] : ""; } + + /** + @return the cipher mode padding (if any) + */ + std::string cipher_mode_pad() const + { return (mode_str.size() >= 2) ? mode_str[1] : ""; } + private: std::string orig_algo_spec; std::vector name; + std::vector mode_str; }; } -- cgit v1.2.3 From aea376790ba658b267aa9b1d5decf5735a7f727d Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 6 Oct 2009 16:04:20 +0000 Subject: Refactor Default_Engine::get_cipher so bits can be called from selftest --- src/engine/def_engine/def_eng.h | 5 + src/engine/def_engine/def_mode.cpp | 183 ++++++++++++++++++++----------------- 2 files changed, 104 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/engine/def_engine/def_eng.h b/src/engine/def_engine/def_eng.h index 2d7145480..ba5bee8ef 100644 --- a/src/engine/def_engine/def_eng.h +++ b/src/engine/def_engine/def_eng.h @@ -78,6 +78,11 @@ class BOTAN_DLL Default_Engine : public Engine Algorithm_Factory&) const; }; +Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher, + Cipher_Dir direction, + const std::string& mode, + const std::string& padding); + } #endif diff --git a/src/engine/def_engine/def_mode.cpp b/src/engine/def_engine/def_mode.cpp index 2b093a0a3..0c7a1a2e2 100644 --- a/src/engine/def_engine/def_mode.cpp +++ b/src/engine/def_engine/def_mode.cpp @@ -51,22 +51,22 @@ namespace { /** * Get a block cipher padding method by name */ -BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec) +BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec, + const std::string& def_if_empty) { - SCAN_Name request(algo_spec); - #if defined(BOTAN_HAS_CIPHER_MODE_PADDING) - if(request.algo_name() == "PKCS7") + if(algo_spec == "NoPadding" || (algo_spec == "" && def_if_empty == "NoPadding")) + return new Null_Padding; + + if(algo_spec == "PKCS7" || (algo_spec == "" && def_if_empty == "PKCS7")) return new PKCS7_Padding; - if(request.algo_name() == "OneAndZeros") + if(algo_spec == "OneAndZeros") return new OneAndZeros_Padding; - if(request.algo_name() == "X9.23") + if(algo_spec == "X9.23") return new ANSI_X923_Padding; - if(request.algo_name() == "NoPadding") - return new Null_Padding; #endif throw Algorithm_Not_Found(algo_spec); @@ -74,58 +74,11 @@ BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec) } -/* -* Get a cipher object -*/ -Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, - Cipher_Dir direction, - Algorithm_Factory& af) +Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher, + Cipher_Dir direction, + const std::string& mode, + const std::string& padding) { - std::vector algo_parts = split_on(algo_spec, '/'); - if(algo_parts.empty()) - throw Invalid_Algorithm_Name(algo_spec); - - const std::string cipher_name = algo_parts[0]; - - // check if it is a stream cipher first (easy case) - const StreamCipher* stream_cipher = af.prototype_stream_cipher(cipher_name); - if(stream_cipher) - return new StreamCipher_Filter(stream_cipher->clone()); - - const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_name); - if(!block_cipher) - return 0; - - if(algo_parts.size() != 2 && algo_parts.size() != 3) - return 0; - - std::string mode = algo_parts[1]; - u32bit bits = 0; - - if(mode.find("CFB") != std::string::npos || - mode.find("EAX") != std::string::npos) - { - std::vector algo_info = parse_algorithm_name(mode); - mode = algo_info[0]; - if(algo_info.size() == 1) - bits = 8*block_cipher->BLOCK_SIZE; - else if(algo_info.size() == 2) - bits = to_u32bit(algo_info[1]); - else - throw Invalid_Algorithm_Name(algo_spec); - } - - std::string padding; - if(algo_parts.size() == 3) - padding = algo_parts[2]; - else - padding = (mode == "CBC") ? "PKCS7" : "NoPadding"; - - if(mode == "ECB" && padding == "CTS") - return 0; - else if((mode != "CBC" && mode != "ECB") && padding != "NoPadding") - throw Invalid_Algorithm_Name(algo_spec); - #if defined(BOTAN_HAS_OFB) if(mode == "OFB") return new OFB(block_cipher->clone()); @@ -137,22 +90,14 @@ Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, #endif #if defined(BOTAN_HAS_ECB) - if(mode == "ECB") - { - if(direction == ENCRYPTION) - return new ECB_Encryption(block_cipher->clone(), get_bc_pad(padding)); - else - return new ECB_Decryption(block_cipher->clone(), get_bc_pad(padding)); - } -#endif - -#if defined(BOTAN_HAS_CFB) - if(mode == "CFB") + if(mode == "ECB" || mode == "") { if(direction == ENCRYPTION) - return new CFB_Encryption(block_cipher->clone(), bits); + return new ECB_Encryption(block_cipher->clone(), + get_bc_pad(padding, "NoPadding")); else - return new CFB_Decryption(block_cipher->clone(), bits); + return new ECB_Decryption(block_cipher->clone(), + get_bc_pad(padding, "NoPadding")); } #endif @@ -173,25 +118,15 @@ Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, #if defined(BOTAN_HAS_CBC) if(direction == ENCRYPTION) return new CBC_Encryption(block_cipher->clone(), - get_bc_pad(padding)); + get_bc_pad(padding, "PKCS7")); else return new CBC_Decryption(block_cipher->clone(), - get_bc_pad(padding)); + get_bc_pad(padding, "PKCS7")); #else return 0; #endif } -#if defined(BOTAN_HAS_EAX) - if(mode == "EAX") - { - if(direction == ENCRYPTION) - return new EAX_Encryption(block_cipher->clone(), bits); - else - return new EAX_Decryption(block_cipher->clone(), bits); - } -#endif - #if defined(BOTAN_HAS_XTS) if(mode == "XTS") { @@ -202,6 +137,86 @@ Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, } #endif + if(mode.find("CFB") != std::string::npos || + mode.find("EAX") != std::string::npos) + { + u32bit bits = 0; + + std::vector algo_info = parse_algorithm_name(mode); + std::string mode_name = algo_info[0]; + if(algo_info.size() == 1) + bits = 8*block_cipher->BLOCK_SIZE; + else if(algo_info.size() == 2) + bits = to_u32bit(algo_info[1]); + else + return 0; + +#if defined(BOTAN_HAS_CFB) + if(mode_name == "CFB") + { + if(direction == ENCRYPTION) + return new CFB_Encryption(block_cipher->clone(), bits); + else + return new CFB_Decryption(block_cipher->clone(), bits); + } +#endif + +#if defined(BOTAN_HAS_EAX) + if(mode_name == "EAX") + { + if(direction == ENCRYPTION) + return new EAX_Encryption(block_cipher->clone(), bits); + else + return new EAX_Decryption(block_cipher->clone(), bits); + } +#endif + } + + return 0; + } + +/* +* Get a cipher object +*/ +Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, + Cipher_Dir direction, + Algorithm_Factory& af) + { + std::vector algo_parts = split_on(algo_spec, '/'); + if(algo_parts.empty()) + throw Invalid_Algorithm_Name(algo_spec); + + const std::string cipher_name = algo_parts[0]; + + // check if it is a stream cipher first (easy case) + const StreamCipher* stream_cipher = af.prototype_stream_cipher(cipher_name); + if(stream_cipher) + return new StreamCipher_Filter(stream_cipher->clone()); + + const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_name); + if(!block_cipher) + return 0; + + if(algo_parts.size() != 2 && algo_parts.size() != 3) + return 0; + + std::string mode = algo_parts[1]; + + std::string padding; + if(algo_parts.size() == 3) + padding = algo_parts[2]; + else + padding = (mode == "CBC") ? "PKCS7" : "NoPadding"; + + if(mode == "ECB" && padding == "CTS") + return 0; + else if((mode != "CBC" && mode != "ECB") && padding != "NoPadding") + throw Invalid_Algorithm_Name(algo_spec); + + Keyed_Filter* filt = get_cipher_mode(block_cipher, direction, mode, padding); + if(filt) + return filt; + throw Algorithm_Not_Found("get_mode: " + cipher_name + "/" + mode + "/" + padding); } -- cgit v1.2.3 From f6546e0ffc4d9fda308e8e043446d1940f533140 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 6 Oct 2009 16:32:43 +0000 Subject: Fix mode name parsing --- src/libstate/scan_name.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libstate/scan_name.cpp b/src/libstate/scan_name.cpp index 13792720c..bdafde225 100644 --- a/src/libstate/scan_name.cpp +++ b/src/libstate/scan_name.cpp @@ -55,7 +55,7 @@ SCAN_Name::SCAN_Name(const std::string& algo_spec) name.clear(); } - if(name.size() == 0 && algo_spec.find('/') != std::string::npos) + if(name.size() <= 1 && algo_spec.find('/') != std::string::npos) { std::vector algo_parts = split_on(algo_spec, '/'); -- cgit v1.2.3 From 7c71072fe090b9925715614861471b7e51a70a56 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 6 Oct 2009 16:33:22 +0000 Subject: Add cipher mode selftesting in selftest.cpp Convert hardcoded startup selftests to use the new selftest framework --- src/selftest/info.txt | 7 +- src/selftest/selftest.cpp | 339 ++++++++++++++++++++++++++-------------------- src/selftest/selftest.h | 3 +- 3 files changed, 198 insertions(+), 151 deletions(-) (limited to 'src') diff --git a/src/selftest/info.txt b/src/selftest/info.txt index 323a610a6..c4b61bb99 100644 --- a/src/selftest/info.txt +++ b/src/selftest/info.txt @@ -11,11 +11,6 @@ selftest.h algo_factory -cbc -cfb -ctr -ecb filters -hmac -ofb +def_engine diff --git a/src/selftest/selftest.cpp b/src/selftest/selftest.cpp index 6fd6b7fcd..c8c1b5f75 100644 --- a/src/selftest/selftest.cpp +++ b/src/selftest/selftest.cpp @@ -7,14 +7,11 @@ #include #include -#include -#include -#include -#include -#include -#include +#include #include +#include + namespace Botan { namespace { @@ -32,63 +29,19 @@ bool test_filter_kat(Filter* filter, return (output == pipe.read_all_as_string()); } -void do_kat(const std::string& in, const std::string& out, - const std::string& algo_name, Filter* filter) - { - if(!test_filter_kat(filter, in, out)) - throw Self_Test_Failure(algo_name + " startup test"); - } - -/* -* Perform a KAT for a cipher -*/ -void cipher_kat(const BlockCipher* proto, - const std::string& key_str, - const std::string& iv_str, - const std::string& in, - const std::string& ecb_out, - const std::string& cbc_out, - const std::string& cfb_out, - const std::string& ofb_out, - const std::string& ctr_out) - { - SymmetricKey key(key_str); - InitializationVector iv(iv_str); - - std::string name = proto->name(); - - do_kat(in, ecb_out, name + "/ECB", - new ECB_Encryption(proto->clone(), new Null_Padding, key)); - do_kat(ecb_out, in, name + "/ECB", - new ECB_Decryption(proto->clone(), new Null_Padding, key)); - - do_kat(in, cbc_out, name + "/CBC", - new CBC_Encryption(proto->clone(), new Null_Padding, key, iv)); - do_kat(cbc_out, in, name + "/CBC", - new CBC_Decryption(proto->clone(), new Null_Padding, key, iv)); - - do_kat(in, cfb_out, name + "/CFB", - new CFB_Encryption(proto->clone(), key, iv)); - do_kat(cfb_out, in, name + "/CFB", - new CFB_Decryption(proto->clone(), key, iv)); - - do_kat(in, ofb_out, name + "/OFB", new OFB(proto->clone(), key, iv)); - - do_kat(in, ctr_out, name + "/CTR-BE", - new CTR_BE(proto->clone(), key, iv)); - } - } /* * Run a set of KATs */ std::map -algorithm_kat(const std::string& name, +algorithm_kat(const SCAN_Name& algo_name, const std::map& vars, Algorithm_Factory& af) { - std::vector providers = af.providers_of(name); + const std::string& algo = algo_name.algo_name_and_args(); + + std::vector providers = af.providers_of(algo); std::map all_results; if(providers.empty()) // no providers, nothing to do @@ -97,44 +50,159 @@ algorithm_kat(const std::string& name, const std::string input = search_map(vars, std::string("input")); const std::string output = search_map(vars, std::string("output")); const std::string key = search_map(vars, std::string("key")); + const std::string iv = search_map(vars, std::string("iv")); for(u32bit i = 0; i != providers.size(); ++i) { const std::string provider = providers[i]; if(const HashFunction* proto = - af.prototype_hash_function(name, provider)) + af.prototype_hash_function(algo, provider)) { - all_results[provider] = test_filter_kat(new Hash_Filter(proto->clone()), - input, output); + Filter* filt = new Hash_Filter(proto->clone()); + all_results[provider] = test_filter_kat(filt, input, output); } else if(const MessageAuthenticationCode* proto = - af.prototype_mac(name, provider)) + af.prototype_mac(algo, provider)) { - all_results[provider] = test_filter_kat(new MAC_Filter(proto->clone(), key), - input, output); + Keyed_Filter* filt = new MAC_Filter(proto->clone(), key); + all_results[provider] = test_filter_kat(filt, input, output); } - -#if 0 - if(const BlockCipher* proto = - af.prototype_block_cipher(name, provider)) + else if(const StreamCipher* proto = + af.prototype_stream_cipher(algo, provider)) { - std::auto_ptr block_cipher(proto->clone()); - all_results[provider] = test_block_cipher(block_cipher.get()); + Keyed_Filter* filt = new StreamCipher_Filter(proto->clone()); + filt->set_key(key); + filt->set_iv(iv); + + all_results[provider] = test_filter_kat(filt, input, output); } - else if(const StreamCipher* proto = - af.prototype_stream_cipher(name, provider)) + else if(const BlockCipher* proto = + af.prototype_block_cipher(algo, provider)) { - std::auto_ptr stream_cipher(proto->clone()); - all_results[provider] = test_stream_cipher(stream_cipher.get()); + Keyed_Filter* enc = get_cipher_mode(proto, ENCRYPTION, + algo_name.cipher_mode(), + algo_name.cipher_mode_pad()); + + Keyed_Filter* dec = get_cipher_mode(proto, DECRYPTION, + algo_name.cipher_mode(), + algo_name.cipher_mode_pad()); + + if(!enc || !dec) + { + delete enc; + delete dec; + continue; + } + + enc->set_key(key); + enc->set_iv(iv); + + dec->set_key(key); + dec->set_iv(iv); + + bool enc_ok = test_filter_kat(enc, input, output); + bool dec_ok = test_filter_kat(dec, output, input); + + all_results[provider] = enc_ok && dec_ok; } - else -#endif } return all_results; } +namespace { + + +void do_kat(const std::string& in, const std::string& out, + const std::string& algo_name, Filter* filter) + { + if(!test_filter_kat(filter, in, out)) + throw Self_Test_Failure(algo_name + " startup test"); + } + + +void verify_results(const std::string& algo, + const std::map& results) + { + for(std::map::const_iterator i = results.begin(); + i != results.end(); ++i) + { + if(!i->second) + throw Self_Test_Failure(algo + " self-test failed, provider "+ + i->first); + } + } + +void hash_test(Algorithm_Factory& af, + const std::string& name, + const std::string& in, + const std::string& out) + { + std::map vars; + vars["input"] = in; + vars["output"] = out; + + verify_results(name, algorithm_kat(name, vars, af)); + } + +void mac_test(Algorithm_Factory& af, + const std::string& name, + const std::string& in, + const std::string& out, + const std::string& key) + { + std::map vars; + vars["input"] = in; + vars["output"] = out; + vars["key"] = key; + + verify_results(name, algorithm_kat(name, vars, af)); + } + +/* +* Perform a KAT for a cipher +*/ +void cipher_kat(Algorithm_Factory& af, + const std::string& algo, + const std::string& key_str, + const std::string& iv_str, + const std::string& in, + const std::string& ecb_out, + const std::string& cbc_out, + const std::string& cfb_out, + const std::string& ofb_out, + const std::string& ctr_out) + { + SymmetricKey key(key_str); + InitializationVector iv(iv_str); + + std::map vars; + vars["key"] = key_str; + vars["iv"] = iv_str; + vars["input"] = in; + + std::map results; + + vars["output"] = ecb_out; + verify_results(algo + "/ECB", algorithm_kat(algo + "/ECB", vars, af)); + + vars["output"] = cbc_out; + verify_results(algo + "/CBC", + algorithm_kat(algo + "/CBC/NoPadding", vars, af)); + + vars["output"] = cfb_out; + verify_results(algo + "/CFB", algorithm_kat(algo + "/CFB", vars, af)); + + vars["output"] = ofb_out; + verify_results(algo + "/OFB", algorithm_kat(algo + "/OFB", vars, af)); + + vars["output"] = ctr_out; + verify_results(algo + "/CTR", algorithm_kat(algo + "/CTR-BE", vars, af)); + } + +} + /* * Perform Self Tests */ @@ -142,9 +210,7 @@ bool passes_self_tests(Algorithm_Factory& af) { try { - if(const BlockCipher* proto = af.prototype_block_cipher("DES")) - { - cipher_kat(proto, + cipher_kat(af, "DES", "0123456789ABCDEF", "1234567890ABCDEF", "4E6F77206973207468652074696D6520666F7220616C6C20", "3FA40E8A984D48156A271787AB8883F9893D51EC4B563B53", @@ -152,11 +218,8 @@ bool passes_self_tests(Algorithm_Factory& af) "F3096249C7F46E51A69E839B1A92F78403467133898EA622", "F3096249C7F46E5135F24A242EEB3D3F3D6D5BE3255AF8C3", "F3096249C7F46E51163A8CA0FFC94C27FA2F80F480B86F75"); - } - if(const BlockCipher* proto = af.prototype_block_cipher("TripleDES")) - { - cipher_kat(proto, + cipher_kat(af, "TripleDES", "385D7189A5C3D485E1370AA5D408082B5CCCCB5E19F2D90E", "C141B5FCCD28DC8A", "6E1BD7C6120947A464A6AAB293A0F89A563D8D40D3461B68", @@ -165,75 +228,63 @@ bool passes_self_tests(Algorithm_Factory& af) "E26BA806A59B0330DE40CA38E77A3E494BE2B212F6DD624B", "E26BA806A59B03307DE2BCC25A08BA40A8BA335F5D604C62", "E26BA806A59B03303C62C2EFF32D3ACDD5D5F35EBCC53371"); - } - - if(const BlockCipher* proto = af.prototype_block_cipher("AES")) - { - cipher_kat(proto, - "2B7E151628AED2A6ABF7158809CF4F3C", - "000102030405060708090A0B0C0D0E0F", - "6BC1BEE22E409F96E93D7E117393172A" - "AE2D8A571E03AC9C9EB76FAC45AF8E51", - "3AD77BB40D7A3660A89ECAF32466EF97" - "F5D3D58503B9699DE785895A96FDBAAF", - "7649ABAC8119B246CEE98E9B12E9197D" - "5086CB9B507219EE95DB113A917678B2", - "3B3FD92EB72DAD20333449F8E83CFB4A" - "C8A64537A0B3A93FCDE3CDAD9F1CE58B", - "3B3FD92EB72DAD20333449F8E83CFB4A" - "7789508D16918F03F53C52DAC54ED825", - "3B3FD92EB72DAD20333449F8E83CFB4A" - "010C041999E03F36448624483E582D0E"); - } - - if(const HashFunction* proto = af.prototype_hash_function("SHA-1")) - { - do_kat("", "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", - proto->name(), new Hash_Filter(proto->clone())); - - do_kat("616263", "A9993E364706816ABA3E25717850C26C9CD0D89D", - proto->name(), new Hash_Filter(proto->clone())); - - do_kat("6162636462636465636465666465666765666768666768696768696A" + + cipher_kat(af, "AES-128", + "2B7E151628AED2A6ABF7158809CF4F3C", + "000102030405060708090A0B0C0D0E0F", + "6BC1BEE22E409F96E93D7E117393172A" + "AE2D8A571E03AC9C9EB76FAC45AF8E51", + "3AD77BB40D7A3660A89ECAF32466EF97" + "F5D3D58503B9699DE785895A96FDBAAF", + "7649ABAC8119B246CEE98E9B12E9197D" + "5086CB9B507219EE95DB113A917678B2", + "3B3FD92EB72DAD20333449F8E83CFB4A" + "C8A64537A0B3A93FCDE3CDAD9F1CE58B", + "3B3FD92EB72DAD20333449F8E83CFB4A" + "7789508D16918F03F53C52DAC54ED825", + "3B3FD92EB72DAD20333449F8E83CFB4A" + "010C041999E03F36448624483E582D0E"); + + hash_test(af, "SHA-1", + "", "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"); + + hash_test(af, "SHA-1", + "616263", "A9993E364706816ABA3E25717850C26C9CD0D89D"); + + hash_test(af, "SHA-1", + "6162636462636465636465666465666765666768666768696768696A" "68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071", - "84983E441C3BD26EBAAE4AA1F95129E5E54670F1", - proto->name(), new Hash_Filter(proto->clone())); - - do_kat("4869205468657265", - "B617318655057264E28BC0B6FB378C8EF146BE00", - "HMAC(" + proto->name() + ")", - new MAC_Filter(new HMAC(proto->clone()), - SymmetricKey("0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"))); - } - - if(const HashFunction* proto = af.prototype_hash_function("SHA-256")) - { - do_kat("", - "E3B0C44298FC1C149AFBF4C8996FB924" - "27AE41E4649B934CA495991B7852B855", - proto->name(), new Hash_Filter(proto->clone())); - - do_kat("616263", - "BA7816BF8F01CFEA414140DE5DAE2223" - "B00361A396177A9CB410FF61F20015AD", - proto->name(), new Hash_Filter(proto->clone())); - - do_kat("6162636462636465636465666465666765666768666768696768696A" + "84983E441C3BD26EBAAE4AA1F95129E5E54670F1"); + + mac_test(af, "HMAC(SHA-1)", + "4869205468657265", + "B617318655057264E28BC0B6FB378C8EF146BE00", + "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"); + + hash_test(af, "SHA-256", + "", + "E3B0C44298FC1C149AFBF4C8996FB924" + "27AE41E4649B934CA495991B7852B855"); + + hash_test(af, "SHA-256", + "616263", + "BA7816BF8F01CFEA414140DE5DAE2223" + "B00361A396177A9CB410FF61F20015AD"); + + hash_test(af, "SHA-256", + "6162636462636465636465666465666765666768666768696768696A" "68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071", "248D6A61D20638B8E5C026930C3E6039" - "A33CE45964FF2167F6ECEDD419DB06C1", - proto->name(), new Hash_Filter(proto->clone())); - - do_kat("4869205468657265", - "198A607EB44BFBC69903A0F1CF2BBDC5" - "BA0AA3F3D9AE3C1C7A3B1696A0B68CF7", - "HMAC(" + proto->name() + ")", - new MAC_Filter(new HMAC(proto->clone()), - SymmetricKey("0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B" - "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"))); - } + "A33CE45964FF2167F6ECEDD419DB06C1"); + + mac_test(af, "HMAC(SHA-256)", + "4869205468657265", + "198A607EB44BFBC69903A0F1CF2BBDC5" + "BA0AA3F3D9AE3C1C7A3B1696A0B68CF7", + "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B" + "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"); } - catch(std::exception) + catch(Self_Test_Failure) { return false; } diff --git a/src/selftest/selftest.h b/src/selftest/selftest.h index b5fc9f80a..4cb6e23d7 100644 --- a/src/selftest/selftest.h +++ b/src/selftest/selftest.h @@ -9,6 +9,7 @@ #define BOTAN_SELF_TESTS_H__ #include +#include #include #include @@ -20,7 +21,7 @@ namespace Botan { BOTAN_DLL bool passes_self_tests(Algorithm_Factory& af); BOTAN_DLL std::map -algorithm_kat(const std::string& name, +algorithm_kat(const SCAN_Name& algo_name, const std::map& vars, Algorithm_Factory& af); -- cgit v1.2.3 From 56ebd3dfdab9e0f6b84773f7447ea0a0c52236e5 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 7 Oct 2009 15:53:03 +0000 Subject: Add 'Distributed under...' text to files missing it. Some format cleanups --- src/algo_factory/algo_cache.h | 5 ++- src/hash/gost_3411/gost_3411.cpp | 2 ++ src/hash/gost_3411/gost_3411.h | 2 ++ src/hash/sha1_sse2/sha1_sse2_imp.cpp | 29 ++++++----------- src/math/gfpmath/curve_gfp.cpp | 10 +++--- src/math/gfpmath/gfp_element.cpp | 23 +++++++------- src/math/gfpmath/gfp_element.h | 60 ++++++++++++++++++------------------ src/math/gfpmath/gfp_modulus.h | 47 ++++++++++++++-------------- src/math/gfpmath/point_gfp.cpp | 15 ++++----- src/math/gfpmath/point_gfp.h | 8 ++--- src/pubkey/ec_dompar/ec_dompar.cpp | 8 +++++ src/pubkey/ec_dompar/ec_dompar.h | 3 +- 12 files changed, 106 insertions(+), 106 deletions(-) (limited to 'src') diff --git a/src/algo_factory/algo_cache.h b/src/algo_factory/algo_cache.h index 17ea9964a..08b25cd47 100644 --- a/src/algo_factory/algo_cache.h +++ b/src/algo_factory/algo_cache.h @@ -1,5 +1,8 @@ -/** +/* * An algorithm cache (used by Algorithm_Factory) +* (C) 2008-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license */ #ifndef BOTAN_ALGORITHM_CACHE_TEMPLATE_H__ diff --git a/src/hash/gost_3411/gost_3411.cpp b/src/hash/gost_3411/gost_3411.cpp index 3c7f5f92b..8f3982fca 100644 --- a/src/hash/gost_3411/gost_3411.cpp +++ b/src/hash/gost_3411/gost_3411.cpp @@ -1,6 +1,8 @@ /* * GOST 34.11 * (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license */ #include diff --git a/src/hash/gost_3411/gost_3411.h b/src/hash/gost_3411/gost_3411.h index c69555052..960adaa44 100644 --- a/src/hash/gost_3411/gost_3411.h +++ b/src/hash/gost_3411/gost_3411.h @@ -1,6 +1,8 @@ /** * GOST 34.11 * (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license */ #ifndef BOTAN_GOST_3411_H__ diff --git a/src/hash/sha1_sse2/sha1_sse2_imp.cpp b/src/hash/sha1_sse2/sha1_sse2_imp.cpp index 57b287bdb..5ee222cca 100644 --- a/src/hash/sha1_sse2/sha1_sse2_imp.cpp +++ b/src/hash/sha1_sse2/sha1_sse2_imp.cpp @@ -1,25 +1,14 @@ -/* this code is public domain. - - * dean gaudet - - * this code was inspired by this paper: - - * SHA: A Design for Parallel Architectures? - * Antoon Bosselaers, Ren´e Govaerts and Joos Vandewalle - * - - * more information available on this implementation here: - - * http://arctic.org/~dean/crypto/sha1.html - - * version: 2 - */ - /* - * Lightly modified for Botan, tested under GCC 4.1.1 and ICC 9.1 - * on a Linux/Core2 system. +* SHA-1 using SSE2 +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ - */ +/* +* Based on public domain code by Dean Gaudet +* http://arctic.org/~dean/crypto/sha1.html +*/ #include #include diff --git a/src/math/gfpmath/curve_gfp.cpp b/src/math/gfpmath/curve_gfp.cpp index e12ade081..9a3ffd482 100644 --- a/src/math/gfpmath/curve_gfp.cpp +++ b/src/math/gfpmath/curve_gfp.cpp @@ -1,11 +1,11 @@ -/****** +/* * Elliptic curves over GF(p) * -* (C) 2007 Martin Doering -* Christoph Ludwig -* Falko Strenzke +* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke * 2008 Jack Lloyd -******/ +* +* Distributed under the terms of the Botan license +*/ #include #include diff --git a/src/math/gfpmath/gfp_element.cpp b/src/math/gfpmath/gfp_element.cpp index b71809301..23887929a 100644 --- a/src/math/gfpmath/gfp_element.cpp +++ b/src/math/gfpmath/gfp_element.cpp @@ -1,13 +1,15 @@ -/****** - * Arithmetic for prime fields GF(p) (source file) - * - * (C) 2007 Martin Doering - * doering@cdc.informatik.tu-darmstadt.de - * Christoph Ludwig - * ludwig@fh-worms.de - * Falko Strenzke - * strenzke@flexsecure.de - ******/ +/* +* Arithmetic for prime fields GF(p) +* +* (C) 2007 Martin Doering +* doering@cdc.informatik.tu-darmstadt.de +* Christoph Ludwig +* ludwig@fh-worms.de +* Falko Strenzke +* strenzke@flexsecure.de +* +* Distributed under the terms of the Botan license +*/ #include #include @@ -15,7 +17,6 @@ #include #include #include -#include #include namespace Botan { diff --git a/src/math/gfpmath/gfp_element.h b/src/math/gfpmath/gfp_element.h index 4e0ee985b..18d9e51f9 100644 --- a/src/math/gfpmath/gfp_element.h +++ b/src/math/gfpmath/gfp_element.h @@ -1,13 +1,15 @@ -/****** - * Arithmetic for prime fields GF(p) (header file) - * - * (C) 2007 Martin Doering - * doering@cdc.informatik.tu-darmstadt.de - * Christoph Ludwig - * ludwig@fh-worms.de - * Falko Strenzke - * strenzke@flexsecure.de - ******/ +/* +* Arithmetic for prime fields GF(p) +* +* (C) 2007 Martin Doering +* doering@cdc.informatik.tu-darmstadt.de +* Christoph Ludwig +* ludwig@fh-worms.de +* Falko Strenzke +* strenzke@flexsecure.de +* +* Distributed under the terms of the Botan license +*/ #ifndef BOTAN_GFP_ELEMENT_H__ #define BOTAN_GFP_ELEMENT_H__ @@ -26,11 +28,11 @@ namespace Botan { -struct Illegal_Transformation : public Exception +struct BOTAN_DLL Illegal_Transformation : public Exception { Illegal_Transformation(const std::string& err = - "Requested transformation is not possible") - : Exception(err) {} + "Requested transformation is not possible") : + Exception(err) {} }; /** @@ -39,23 +41,6 @@ struct Illegal_Transformation : public Exception */ class BOTAN_DLL GFpElement { - private: - std::tr1::shared_ptr mp_mod; - mutable BigInt m_value; // ordinary residue or m-residue respectively - mutable BigInt workspace; - - // ***************************************** - // data members for montgomery multiplication - mutable bool m_use_montgm; - //mutable BigInt m_mres; - // this bool tells use whether the m_mres carries - // the actual value (in this case mValue doesn´t) - mutable bool m_is_trf; - - void ensure_montgm_precomp() const; - void trf_to_mres() const; - void trf_to_ordres() const; - public: /** construct an element of GF(p) with the given value. @@ -260,7 +245,22 @@ class BOTAN_DLL GFpElement * @param other The value to swap with */ void swap(GFpElement& other); + private: + void ensure_montgm_precomp() const; + void trf_to_mres() const; + void trf_to_ordres() const; + + std::tr1::shared_ptr mp_mod; + mutable BigInt m_value; // ordinary residue or m-residue respectively + mutable BigInt workspace; + // ***************************************** + // data members for montgomery multiplication + mutable bool m_use_montgm; + //mutable BigInt m_mres; + // this bool tells use whether the m_mres carries + // the actual value (in this case mValue doesn´t) + mutable bool m_is_trf; }; // relational operators diff --git a/src/math/gfpmath/gfp_modulus.h b/src/math/gfpmath/gfp_modulus.h index b5c085775..8e37e9a73 100644 --- a/src/math/gfpmath/gfp_modulus.h +++ b/src/math/gfpmath/gfp_modulus.h @@ -1,39 +1,33 @@ -/****** - * Modulus and related data for a specific - * implementation of GF(p) (header file) - * - * (C) 2008 Martin Döring - * doering@cdc.informatik.tu-darmstadt.de - * Christoph Ludwig - * ludwig@fh-worms.de - * Falko Strenzke - * strenzke@flexsecure.de - ******/ +/* +* Modulus and related data for a specific implementation of GF(p) +* +* (C) 2008 Martin Döring +* +* Christoph Ludwig +* +* Falko Strenzke +* +* +* Distributed under the terms of the Botan license +*/ #ifndef BOTAN_GFP_MODULUS_H__ #define BOTAN_GFP_MODULUS_H__ #include -namespace Botan -{ +namespace Botan { class BOTAN_DLL GFpElement; + /** -* This class represents a GFpElement modulus including the modulus related -* values necessary for the montgomery multiplication. -* -* Distributed under the terms of the Botan license +* This class represents a GFpElement modulus including the modulus +* related values necessary for the montgomery multiplication. */ class BOTAN_DLL GFpModulus { - friend class GFpElement; - private: - BigInt m_p; // the modulus itself - mutable BigInt m_p_dash; - mutable BigInt m_r; - mutable BigInt m_r_inv; public: + friend class GFpElement; /** * Construct a GF(P)-Modulus from a BigInt @@ -119,9 +113,14 @@ class BOTAN_DLL GFpModulus return m_p_dash; } // default cp-ctor, op= are fine + + private: + BigInt m_p; // the modulus itself + mutable BigInt m_p_dash; + mutable BigInt m_r; + mutable BigInt m_r_inv; }; } #endif - diff --git a/src/math/gfpmath/point_gfp.cpp b/src/math/gfpmath/point_gfp.cpp index 9139c3ef9..b67631f7b 100644 --- a/src/math/gfpmath/point_gfp.cpp +++ b/src/math/gfpmath/point_gfp.cpp @@ -1,12 +1,11 @@ -/****** -* Arithmetic for point groups of elliptic curves -* over GF(p) (source file) +/* +* Arithmetic for point groups of elliptic curves over GF(p) * -* (C) 2007 Martin Doering -* Christoph Ludwig -* Falko Strenzke +* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke * 2008 Jack Lloyd -******/ +* +* Distributed under the terms of the Botan license +*/ #include #include @@ -688,8 +687,6 @@ void PointGFp::turn_on_sp_red_mul() const * returns a point equivalent to *this but were * Z has value one, i.e. x and y correspond to * their values in affine coordinates -* -* Distributed under the terms of the Botan license */ PointGFp const PointGFp::get_z_to_one() const { diff --git a/src/math/gfpmath/point_gfp.h b/src/math/gfpmath/point_gfp.h index 771605efc..62b3bc7da 100644 --- a/src/math/gfpmath/point_gfp.h +++ b/src/math/gfpmath/point_gfp.h @@ -1,10 +1,8 @@ /* -* Arithmetic over GF(p) +* Arithmetic for point groups of elliptic curves over GF(p) * -* (C) 2007 Martin Doering -* Christoph Ludwig -* Falko Strenzke -* (C) 2008 Jack Lloyd +* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke +* 2008 Jack Lloyd * * Distributed under the terms of the Botan license */ diff --git a/src/pubkey/ec_dompar/ec_dompar.cpp b/src/pubkey/ec_dompar/ec_dompar.cpp index 6cfcc0619..0b5a6e681 100644 --- a/src/pubkey/ec_dompar/ec_dompar.cpp +++ b/src/pubkey/ec_dompar/ec_dompar.cpp @@ -1,3 +1,11 @@ +/* +* ECC Domain Parameters +* +* (C) 2007 Falko Strenzke, FlexSecure GmbH +* 2008 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ #include #include diff --git a/src/pubkey/ec_dompar/ec_dompar.h b/src/pubkey/ec_dompar/ec_dompar.h index 47971d802..5ea599c9d 100644 --- a/src/pubkey/ec_dompar/ec_dompar.h +++ b/src/pubkey/ec_dompar/ec_dompar.h @@ -1,5 +1,6 @@ /* -* ECDSA Domain Parameters +* ECC Domain Parameters +* * (C) 2007 Falko Strenzke, FlexSecure GmbH * 2008 Jack Lloyd * -- cgit v1.2.3 From 14781861531974130e48c996f2ac18e037c9bff6 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 7 Oct 2009 15:53:21 +0000 Subject: Run self tests at startup --- src/libstate/libstate.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/libstate/libstate.cpp b/src/libstate/libstate.cpp index 20e736868..ca454458b 100644 --- a/src/libstate/libstate.cpp +++ b/src/libstate/libstate.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -302,6 +303,9 @@ void Library_State::initialize(bool thread_safe) engines.push_back(new Default_Engine); m_algorithm_factory = new Algorithm_Factory(engines, *mutex_factory); + + if(!passes_self_tests(algorithm_factory())) + throw Self_Test_Failure("Startup self tests failed"); } /* -- cgit v1.2.3 From 2d2cb73d20d5f08e5091147a69aa7b2b633880de Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 7 Oct 2009 17:37:55 +0000 Subject: New parsing system for SCAN names --- src/libstate/scan_name.cpp | 118 ++++++++++++++++++++++++++++++++------------- src/libstate/scan_name.h | 13 ++--- 2 files changed, 92 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/libstate/scan_name.cpp b/src/libstate/scan_name.cpp index bdafde225..224d2e509 100644 --- a/src/libstate/scan_name.cpp +++ b/src/libstate/scan_name.cpp @@ -14,28 +14,50 @@ namespace Botan { namespace { -std::vector -parse_and_deref_aliases(const std::string& algo_spec) +std::string make_arg( + const std::vector >& name, u32bit start) { - std::vector parts = parse_algorithm_name(algo_spec); - std::vector out; + std::string output = name[start].second; + u32bit level = name[start].first; - for(size_t i = 0; i != parts.size(); ++i) + u32bit paren_depth = 0; + + for(u32bit i = start + 1; i != name.size(); ++i) { - std::string part_i = global_state().deref_alias(parts[i]); + if(name[i].first <= name[start].first) + break; - if(i == 0 && part_i.find_first_of(",()") != std::string::npos) + if(name[i].first > level) { - std::vector parts_i = parse_and_deref_aliases(part_i); - - for(size_t j = 0; j != parts_i.size(); ++j) - out.push_back(parts_i[j]); + output += '(' + name[i].second; + ++paren_depth; + } + else if(name[i].first < level) + { + output += ")," + name[i].second; + --paren_depth; } else - out.push_back(part_i); + { + if(output[output.size() - 1] != '(') + output += ","; + output += name[i].second; + } + + level = name[i].first; } - return out; + for(u32bit i = 0; i != paren_depth; ++i) + output += ')'; + + return output; + } + +std::pair +deref_aliases(const std::pair& in) + { + return std::make_pair(in.first, + global_state().deref_alias(in.second)); } } @@ -44,27 +66,57 @@ SCAN_Name::SCAN_Name(const std::string& algo_spec) { orig_algo_spec = algo_spec; - try - { - name = parse_and_deref_aliases(algo_spec); - if(name.size() == 0) - throw Decoding_Error("Bad SCAN name " + algo_spec); - } - catch(Invalid_Algorithm_Name) + std::vector > name; + u32bit level = 0; + std::pair accum = std::make_pair(level, ""); + + for(u32bit i = 0; i != algo_spec.size(); ++i) { - name.clear(); + char c = algo_spec[i]; + + if(c == '/' || c == ',' || c == '(' || c == ')') + { + if(c == '(') + ++level; + else if(c == ')') + { + if(level == 0) + throw Decoding_Error("Bad SCAN name " + algo_spec); + --level; + } + + if(c == '/' && level > 0) + accum.second.push_back(c); + else + { + if(accum.second != "") + name.push_back(deref_aliases(accum)); + accum = std::make_pair(level, ""); + } + } + else + accum.second.push_back(c); } - if(name.size() <= 1 && algo_spec.find('/') != std::string::npos) - { - std::vector algo_parts = split_on(algo_spec, '/'); + if(accum.second != "") + name.push_back(deref_aliases(accum)); + + if(level != 0 || name.size() == 0) + throw Decoding_Error("Bad SCAN name " + algo_spec); + + alg_name = name[0].second; - name = parse_and_deref_aliases(algo_parts[0]); - if(name.size() == 0) - throw Decoding_Error("Bad SCAN name " + algo_spec); + bool in_modes = false; - for(size_t i = 1; i != algo_parts.size(); ++i) - mode_str.push_back(algo_parts[i]); + for(u32bit i = 1; i != name.size(); ++i) + { + if(name[i].first == 0) + { + mode_info.push_back(make_arg(name, i)); + in_modes = true; + } + else if(name[i].first == 1 && !in_modes) + args.push_back(make_arg(name, i)); } } @@ -72,7 +124,7 @@ std::string SCAN_Name::algo_name_and_args() const { std::string out; - out = name[0]; + out = algo_name(); if(arg_count()) { @@ -94,21 +146,21 @@ std::string SCAN_Name::arg(u32bit i) const { if(i >= arg_count()) throw std::range_error("SCAN_Name::argument"); - return name[i+1]; + return args[i]; } std::string SCAN_Name::arg(u32bit i, const std::string& def_value) const { if(i >= arg_count()) return def_value; - return name[i+1]; + return args[i]; } u32bit SCAN_Name::arg_as_u32bit(u32bit i, u32bit def_value) const { if(i >= arg_count()) return def_value; - return to_u32bit(name[i+1]); + return to_u32bit(args[i]); } } diff --git a/src/libstate/scan_name.h b/src/libstate/scan_name.h index 6dbd67c4f..ced5f3e15 100644 --- a/src/libstate/scan_name.h +++ b/src/libstate/scan_name.h @@ -35,7 +35,7 @@ class SCAN_Name /** @return the algorithm name */ - std::string algo_name() const { return name[0]; } + std::string algo_name() const { return alg_name; } /** @return the algorithm name plus any arguments @@ -45,7 +45,7 @@ class SCAN_Name /** @return the number of arguments */ - u32bit arg_count() const { return name.size() - 1; } + u32bit arg_count() const { return args.size(); } /** @return if the number of arguments is between lower and upper @@ -77,18 +77,19 @@ class SCAN_Name @return the cipher mode (if any) */ std::string cipher_mode() const - { return (mode_str.size() >= 1) ? mode_str[0] : ""; } + { return (mode_info.size() >= 1) ? mode_info[0] : ""; } /** @return the cipher mode padding (if any) */ std::string cipher_mode_pad() const - { return (mode_str.size() >= 2) ? mode_str[1] : ""; } + { return (mode_info.size() >= 2) ? mode_info[1] : ""; } private: std::string orig_algo_spec; - std::vector name; - std::vector mode_str; + std::string alg_name; + std::vector args; + std::vector mode_info; }; } -- cgit v1.2.3 From 8493512f037325bc6cabcfe576bea1432b1abbe6 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 7 Oct 2009 17:38:14 +0000 Subject: Oops, removed assert.h from gfp_element.cpp which uses assert :( --- src/math/gfpmath/gfp_element.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/math/gfpmath/gfp_element.cpp b/src/math/gfpmath/gfp_element.cpp index 23887929a..f9e0b09c9 100644 --- a/src/math/gfpmath/gfp_element.cpp +++ b/src/math/gfpmath/gfp_element.cpp @@ -18,6 +18,7 @@ #include #include #include +#include namespace Botan { -- cgit v1.2.3 From 0d409578fecf39b6c2dc4926c4d95e353dcfcd78 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 7 Oct 2009 18:01:57 +0000 Subject: Remove includes of stdio.h --- src/hash/bmw/bmw_512.cpp | 2 -- src/selftest/selftest.cpp | 2 -- src/tss/tss.cpp | 2 -- 3 files changed, 6 deletions(-) (limited to 'src') diff --git a/src/hash/bmw/bmw_512.cpp b/src/hash/bmw/bmw_512.cpp index fe6a61df0..ad3826351 100644 --- a/src/hash/bmw/bmw_512.cpp +++ b/src/hash/bmw/bmw_512.cpp @@ -9,8 +9,6 @@ #include #include -#include - namespace Botan { namespace { diff --git a/src/selftest/selftest.cpp b/src/selftest/selftest.cpp index c8c1b5f75..26fe0538c 100644 --- a/src/selftest/selftest.cpp +++ b/src/selftest/selftest.cpp @@ -10,8 +10,6 @@ #include #include -#include - namespace Botan { namespace { diff --git a/src/tss/tss.cpp b/src/tss/tss.cpp index 5b8539330..3bd799727 100644 --- a/src/tss/tss.cpp +++ b/src/tss/tss.cpp @@ -13,8 +13,6 @@ #include #include -#include - namespace Botan { namespace { -- cgit v1.2.3 From cf8cbdce8e918ab8828d3b4feb38cbda83a2de60 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 7 Oct 2009 18:09:59 +0000 Subject: Remove a dead function --- src/selftest/selftest.cpp | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src') diff --git a/src/selftest/selftest.cpp b/src/selftest/selftest.cpp index 26fe0538c..660be36e4 100644 --- a/src/selftest/selftest.cpp +++ b/src/selftest/selftest.cpp @@ -111,15 +111,6 @@ algorithm_kat(const SCAN_Name& algo_name, namespace { - -void do_kat(const std::string& in, const std::string& out, - const std::string& algo_name, Filter* filter) - { - if(!test_filter_kat(filter, in, out)) - throw Self_Test_Failure(algo_name + " startup test"); - } - - void verify_results(const std::string& algo, const std::map& results) { -- cgit v1.2.3 From 22d3cefcb55369ceaece846bc2fa0c34edfb75fe Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 7 Oct 2009 18:34:45 +0000 Subject: Add support for GNU/Hurd --- doc/log.txt | 1 + src/build-data/os/hurd | 16 ++++++++++++++++ src/entropy/dev_random/info.txt | 1 + src/entropy/proc_walk/info.txt | 1 + 4 files changed, 19 insertions(+) create mode 100644 src/build-data/os/hurd (limited to 'src') diff --git a/doc/log.txt b/doc/log.txt index 8a5399151..883c3dabe 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -4,6 +4,7 @@ - Add threshold secret sharing (draft-mcgrew-tss-02) - Add runtime cpu feature detection for x86/x86-64 - Add code for general runtime self testing for hashes, MACs, and ciphers + - Add support for GNU/Hurd - New parsing code for SCAN algorithm names - Alter Skein-512 to match the tweaked 1.2 specification - Enable SSE2 optimizations under Visual C++ diff --git a/src/build-data/os/hurd b/src/build-data/os/hurd new file mode 100644 index 000000000..ed56dad75 --- /dev/null +++ b/src/build-data/os/hurd @@ -0,0 +1,16 @@ +realname "Hurd" + +os_type unix + + +posix_mlock + + +# Is this correct? + +all + + + +gnu + diff --git a/src/entropy/dev_random/info.txt b/src/entropy/dev_random/info.txt index fddb7ac06..5231b2901 100644 --- a/src/entropy/dev_random/info.txt +++ b/src/entropy/dev_random/info.txt @@ -18,6 +18,7 @@ darwin freebsd dragonfly hpux +hurd irix linux netbsd diff --git a/src/entropy/proc_walk/info.txt b/src/entropy/proc_walk/info.txt index db96ccdb8..b82929a73 100644 --- a/src/entropy/proc_walk/info.txt +++ b/src/entropy/proc_walk/info.txt @@ -17,6 +17,7 @@ darwin freebsd dragonfly hpux +hurd irix linux openbsd -- cgit v1.2.3 From b37dbf1f1c80168f79bcb59809be5002dc7515b4 Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 9 Oct 2009 16:11:45 +0000 Subject: Fix --enable-debug With GCC, only use -finline-functions if not a debug build --- configure.py | 14 +++++++++++--- src/build-data/cc/gcc | 5 +++-- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/configure.py b/configure.py index 1c4edb851..0f5e1502d 100755 --- a/configure.py +++ b/configure.py @@ -519,6 +519,14 @@ class CompilerInfo(object): return '' + def library_opt_flags(self, debug_build): + flags = self.lib_opt_flags + if debug_build and self.debug_flags != '': + flags += ' ' + self.debug_flags + if not debug_build and self.no_debug_flags != '': + flags += ' ' + self.no_debug_flags + return flags + def so_link_command_for(self, osname): if osname in self.so_link_flags: return self.so_link_flags[osname] @@ -731,7 +739,7 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): options.arch, options.cpu), - 'lib_opt': cc.lib_opt_flags, + 'lib_opt': cc.library_opt_flags(options.debug_build), 'mach_opt': cc.mach_opts(options.arch, options.cpu), 'check_opt': cc.check_opt_flags, 'lang_flags': cc.lang_flags + options.extra_flags, @@ -1139,7 +1147,7 @@ if __name__ == '__main__': main() except Exception, e: print >>sys.stderr, e - #import traceback - #traceback.print_exc(file=sys.stderr) + import traceback + traceback.print_exc(file=sys.stderr) sys.exit(1) sys.exit(0) diff --git a/src/build-data/cc/gcc b/src/build-data/cc/gcc index 606b622f6..9adef8cfb 100644 --- a/src/build-data/cc/gcc +++ b/src/build-data/cc/gcc @@ -16,10 +16,11 @@ lang_flags "-D_REENTRANT -ansi -Wno-long-long" warning_flags "-W -Wall" #warning_flags "-Wextra -Wall -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wno-unused-parameter" -lib_opt_flags "-O2 -finline-functions" -check_opt_flags "-O2" +lib_opt_flags "-O2" +check_opt_flags "-O" shared_flags "-fPIC" debug_flags "-g" +no_debug_flags "-finline-functions" dll_import_flags "" dll_export_flags "" -- cgit v1.2.3 From 997e6c97b8ace857d00f9fd57f621ba9323c75df Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 9 Oct 2009 18:06:06 +0000 Subject: Add more or less functional integration with Boost.Python. Use --use-boost-python to enable creating a second makefile, Makefile.python, which has targets for building and installing the Python module. --- .mtn-ignore | 2 +- configure.py | 42 ++++++- src/build-data/makefile/python.in | 29 +++++ src/build-data/makefile/unix.in | 2 +- src/build-data/makefile/unix_shr.in | 2 +- src/wrap/python/__init__.py | 4 + src/wrap/python/core.cpp | 203 +++++++++++++++++++++++++++++++ src/wrap/python/filter.cpp | 178 +++++++++++++++++++++++++++ src/wrap/python/pk.cpp | 125 +++++++++++++++++++ src/wrap/python/python_botan.h | 51 ++++++++ src/wrap/python/x509.cpp | 140 +++++++++++++++++++++ wrappers/boost-python/Makefile | 20 ++- wrappers/boost-python/botan/__init__.py | 4 - wrappers/boost-python/src/core.cpp | 203 ------------------------------- wrappers/boost-python/src/filter.cpp | 176 --------------------------- wrappers/boost-python/src/pk.cpp | 125 ------------------- wrappers/boost-python/src/python_botan.h | 51 -------- wrappers/boost-python/src/x509.cpp | 140 --------------------- 18 files changed, 785 insertions(+), 712 deletions(-) create mode 100644 src/build-data/makefile/python.in create mode 100644 src/wrap/python/__init__.py create mode 100644 src/wrap/python/core.cpp create mode 100644 src/wrap/python/filter.cpp create mode 100644 src/wrap/python/pk.cpp create mode 100644 src/wrap/python/python_botan.h create mode 100644 src/wrap/python/x509.cpp delete mode 100644 wrappers/boost-python/botan/__init__.py delete mode 100644 wrappers/boost-python/src/core.cpp delete mode 100644 wrappers/boost-python/src/filter.cpp delete mode 100644 wrappers/boost-python/src/pk.cpp delete mode 100644 wrappers/boost-python/src/python_botan.h delete mode 100644 wrappers/boost-python/src/x509.cpp (limited to 'src') diff --git a/.mtn-ignore b/.mtn-ignore index 63acd11e3..ec8588da0 100644 --- a/.mtn-ignore +++ b/.mtn-ignore @@ -1,4 +1,4 @@ -^Makefile$ +^Makefile.*$ ^botan-config$ ^botan.pc$ ^build$ diff --git a/configure.py b/configure.py index 0f5e1502d..857cab7e7 100755 --- a/configure.py +++ b/configure.py @@ -55,6 +55,12 @@ class BuildConfigurationInformation(object): self.checkobj_dir = os.path.join(self.build_dir, 'checks') self.libobj_dir = os.path.join(self.build_dir, 'lib') + self.python_dir = os.path.join(options.src_dir, 'wrap', 'python') + + self.use_boost_python = options.boost_python + + self.pyobject_dir = os.path.join(self.build_dir, 'python') + self.include_dir = os.path.join(self.build_dir, 'include') self.full_include_dir = os.path.join(self.include_dir, 'botan') @@ -71,6 +77,10 @@ class BuildConfigurationInformation(object): [os.path.join(checks_dir, file) for file in os.listdir(checks_dir) if file.endswith('.cpp')]) + self.python_sources = sorted( + [os.path.join(self.python_dir, file) for file in os.listdir(self.python_dir) + if file.endswith('.cpp')]) + def doc_files(self): docs = ['readme.txt'] @@ -87,6 +97,14 @@ class BuildConfigurationInformation(object): return 'botan-%d.%d.pc' % (self.version_major, self.version_minor) + def build_dirs(self): + dirs = [self.checkobj_dir, + self.libobj_dir, + self.full_include_dir] + if self.use_boost_python: + dirs.append(self.pyobject_dir) + return dirs + def username(self): return getpass.getuser() @@ -146,6 +164,10 @@ def process_command_line(args): build_group.add_option('--disable-debug', dest='debug_build', action='store_false', help=SUPPRESS_HELP) + build_group.add_option('--use-boost-python', dest='boost_python', + default=False, action='store_true', + help='enable Boost.Python wrapper') + build_group.add_option('--with-tr1-implementation', metavar='WHICH', dest='with_tr1', default=None, help='enable TR1 (options: none, system, boost)') @@ -781,6 +803,14 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): build_commands(build_config.check_sources, build_config.checkobj_dir, 'CHECK')), + 'python_objs': makefile_list( + objectfile_list(build_config.python_sources, + build_config.pyobject_dir)), + + 'python_build_cmds': '\n'.join( + build_commands(build_config.python_sources, + build_config.pyobject_dir, 'PYTHON')), + 'ar_command': cc.ar_command or osinfo.ar_command, 'ranlib_command': osinfo.ranlib_command(), 'install_cmd_exec': osinfo.install_cmd_exec, @@ -802,6 +832,8 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): 'mod_list': '\n'.join(['%s (%s)' % (m.basename, m.realname) for m in sorted(modules)]), + + 'python_version': '.'.join(map(str, sys.version_info[0:2])) } """ @@ -988,10 +1020,8 @@ def setup_build(build_config, options, template_vars): except OSError, e: logging.debug('Error while removing build dir: %s' % (e)) - for dirs in [build_config.checkobj_dir, - build_config.libobj_dir, - build_config.full_include_dir]: - os.makedirs(dirs) + for dir in build_config.build_dirs(): + os.makedirs(dir) makefile_template = os.path.join( options.makefile_dir, @@ -1010,6 +1040,10 @@ def setup_build(build_config, options, template_vars): templates_to_proc[os.path.join(options.build_data, template)] = \ os.path.join(build_config.build_dir, sink) + if options.boost_python: + templates_to_proc[ + os.path.join(options.makefile_dir, 'python.in')] = 'Makefile.python' + for (template, sink) in templates_to_proc.items(): try: f = open(sink, 'w') diff --git a/src/build-data/makefile/python.in b/src/build-data/makefile/python.in new file mode 100644 index 000000000..ee95f8d78 --- /dev/null +++ b/src/build-data/makefile/python.in @@ -0,0 +1,29 @@ +CXX = g++ + +PYTHON_ROOT = /usr/lib/python%{python_version}/config +PYTHON_INC = -I/usr/include/python%{python_version} +PYTHON_SITE_PACKAGE_DIR = /tmp/usr/lib/python%{python_version}/site-packages/ + +PYTHON_FLAGS = -Isrc/wrap/python -Os -fPIC -ftemplate-depth-255 -Wall -Wno-unused $(PYTHON_INC) + +PYTHON_OBJS = %{python_objs} + +BOTAN_PYTHON_MODDIR = build/botan-python + +all: $(BOTAN_PYTHON_MODDIR)/_botan.so + +%{python_build_cmds} + +$(BOTAN_PYTHON_MODDIR)/_botan.so: $(PYTHON_OBJS) + rm -rf $(BOTAN_PYTHON_MODDIR) + mkdir $(BOTAN_PYTHON_MODDIR) + cp src/wrap/python/*.py $(BOTAN_PYTHON_MODDIR) + $(CXX) -shared -o $@ $(PYTHON_OBJS) -L. -L$(PYTHON_ROOT) -lbotan -lboost_python -Wl,-rpath-link,. -Wl,-soname,$@ + +clean: + rm -f $(PYTHON_OBJS) $(BOTAN_PYTHON_MODDIR) + +install: + mkdir -p $(PYTHON_SITE_PACKAGE_DIR)/botan + cp $(BOTAN_PYTHON_MODDIR)/* $(PYTHON_SITE_PACKAGE_DIR)/botan + chmod -R u=rwX,go=rX $(PYTHON_SITE_PACKAGE_DIR)/botan diff --git a/src/build-data/makefile/unix.in b/src/build-data/makefile/unix.in index a48a5a17e..8e0e35b87 100644 --- a/src/build-data/makefile/unix.in +++ b/src/build-data/makefile/unix.in @@ -101,7 +101,7 @@ clean: distclean: clean $(RM_R) %{build_dir} $(RM_R) %{doc_src_dir}/doxygen %{doc_src_dir}/botan.doxy - $(RM) Makefile $(CONFIG_SCRIPT) $(PKGCONFIG) + $(RM) Makefile* $(CONFIG_SCRIPT) $(PKGCONFIG) install: $(LIBRARIES) $(ECHO) "Installing Botan into $(DESTDIR)... " diff --git a/src/build-data/makefile/unix_shr.in b/src/build-data/makefile/unix_shr.in index f718d1160..cfc8e3223 100644 --- a/src/build-data/makefile/unix_shr.in +++ b/src/build-data/makefile/unix_shr.in @@ -115,7 +115,7 @@ clean: distclean: clean $(RM_R) %{build_dir} $(RM_R) %{doc_src_dir}/doxygen %{doc_src_dir}/botan.doxy - $(RM) Makefile $(CONFIG_SCRIPT) $(PKGCONFIG) + $(RM) Makefile* $(CONFIG_SCRIPT) $(PKGCONFIG) install: $(LIBRARIES) $(ECHO) "Installing Botan into $(DESTDIR)... " diff --git a/src/wrap/python/__init__.py b/src/wrap/python/__init__.py new file mode 100644 index 000000000..2df9a456f --- /dev/null +++ b/src/wrap/python/__init__.py @@ -0,0 +1,4 @@ +from _botan import * + +# Initialize the library when the module is imported +init = LibraryInitializer() diff --git a/src/wrap/python/core.cpp b/src/wrap/python/core.cpp new file mode 100644 index 000000000..1992e3d61 --- /dev/null +++ b/src/wrap/python/core.cpp @@ -0,0 +1,203 @@ +/* +* Boost.Python module definition +* (C) 1999-2007 Jack Lloyd +*/ + +#include +#include +#include +using namespace Botan; + +#include "python_botan.h" + +class Python_RandomNumberGenerator + { + public: + Python_RandomNumberGenerator() + { rng = RandomNumberGenerator::make_rng(); } + ~Python_RandomNumberGenerator() { delete rng; } + + std::string name() const { return rng->name(); } + + void reseed() { rng->reseed(192); } + + int gen_random_byte() { return rng->next_byte(); } + + std::string gen_random(int n) + { + std::string s(n, 0); + rng->randomize(reinterpret_cast(&s[0]), n); + return s; + } + + void add_entropy(const std::string& in) + { rng->add_entropy(reinterpret_cast(in.c_str()), in.length()); } + + private: + RandomNumberGenerator* rng; + }; + +class Py_Cipher + { + public: + Py_Cipher(std::string algo_name, std::string direction, + std::string key); + + std::string cipher_noiv(const std::string& text); + + std::string cipher(const std::string& text, + const std::string& iv); + + std::string name() const { return algo_name; } + private: + std::string algo_name; + Keyed_Filter* filter; + Pipe pipe; + }; + +std::string Py_Cipher::cipher(const std::string& input, + const std::string& iv_str) + { + if(iv_str.size()) + { + const byte* iv_bytes = reinterpret_cast(iv_str.data()); + u32bit iv_len = iv_str.size(); + filter->set_iv(InitializationVector(iv_bytes, iv_len)); + } + + pipe.process_msg(input); + return pipe.read_all_as_string(Pipe::LAST_MESSAGE); + } + +// For IV-less algorithms +std::string Py_Cipher::cipher_noiv(const std::string& input) + { + pipe.process_msg(input); + return pipe.read_all_as_string(Pipe::LAST_MESSAGE); + } + +Py_Cipher::Py_Cipher(std::string algo_name, + std::string direction, + std::string key_str) + { + const byte* key_bytes = reinterpret_cast(key_str.data()); + u32bit key_len = key_str.size(); + + Cipher_Dir dir; + + if(direction == "encrypt") + dir = ENCRYPTION; + else if(direction == "decrypt") + dir = DECRYPTION; + else + throw std::invalid_argument("Bad cipher direction " + direction); + + filter = get_cipher(algo_name, dir); + filter->set_key(SymmetricKey(key_bytes, key_len)); + pipe.append(filter); + } + +class Py_HashFunction + { + public: + Py_HashFunction(const std::string& algo_name) + { + hash = get_hash(algo_name); + } + + ~Py_HashFunction() { delete hash; } + + void update(const std::string& input) + { + hash->update(input); + } + + std::string final() + { + std::string out(output_length(), 0); + hash->final(reinterpret_cast(&out[0])); + return out; + } + + std::string name() const + { + return hash->name(); + } + + u32bit output_length() const + { + return hash->OUTPUT_LENGTH; + } + + private: + HashFunction* hash; + }; + +class Py_MAC + { + public: + + Py_MAC(const std::string& name, const std::string& key_str) + { + mac = get_mac(name); + + mac->set_key(reinterpret_cast(key_str.data()), + key_str.size()); + } + + ~Py_MAC() { delete mac; } + + u32bit output_length() const { return mac->OUTPUT_LENGTH; } + + std::string name() const { return mac->name(); } + + void update(const std::string& in) { mac->update(in); } + + std::string final() + { + std::string out(output_length(), 0); + mac->final(reinterpret_cast(&out[0])); + return out; + } + private: + MessageAuthenticationCode* mac; + }; + +BOOST_PYTHON_MODULE(_botan) + { + python::class_("LibraryInitializer") + .def(python::init< python::optional >()); + + python::class_("RandomNumberGenerator") + .def(python::init<>()) + .def("__str__", &Python_RandomNumberGenerator::name) + .def("name", &Python_RandomNumberGenerator::name) + .def("reseed", &Python_RandomNumberGenerator::reseed) + .def("add_entropy", &Python_RandomNumberGenerator::add_entropy) + .def("gen_random_byte", &Python_RandomNumberGenerator::gen_random_byte) + .def("gen_random", &Python_RandomNumberGenerator::gen_random); + + python::class_ + ("Cipher", python::init()) + .def("name", &Py_Cipher::name) + .def("cipher", &Py_Cipher::cipher) + .def("cipher", &Py_Cipher::cipher_noiv); + + python::class_ + ("HashFunction", python::init()) + .def("update", &Py_HashFunction::update) + .def("final", &Py_HashFunction::final) + .def("name", &Py_HashFunction::name) + .def("output_length", &Py_HashFunction::output_length); + + python::class_ + ("MAC", python::init()) + .def("update", &Py_MAC::update) + .def("final", &Py_MAC::final) + .def("name", &Py_MAC::name) + .def("output_length", &Py_MAC::output_length); + + export_filters(); + export_pk(); + export_x509(); + } diff --git a/src/wrap/python/filter.cpp b/src/wrap/python/filter.cpp new file mode 100644 index 000000000..a678af9e5 --- /dev/null +++ b/src/wrap/python/filter.cpp @@ -0,0 +1,178 @@ +/************************************************* +* Boost.Python module definition * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include +using namespace boost::python; + +#include +#include +using namespace Botan; + +class Py_Filter : public Filter + { + public: + virtual void write_str(const std::string&) = 0; + + void write(const byte data[], u32bit length) + { + write_str(std::string((const char*)data, length)); + } + + void send_str(const std::string& str) + { + printf("Py_Filter::send_str\n"); + send((const byte*)str.data(), str.length()); + } + }; + +class FilterWrapper : public Py_Filter, public wrapper + { + public: + void start_msg() + { + printf("wrapper start_msg\n"); + if(override start_msg = this->get_override("start_msg")) + start_msg(); + } + + void end_msg() + { + printf("wrapper end_msg\n"); + if(override end_msg = this->get_override("end_msg")) + end_msg(); + } + + void default_start_msg() {} + void default_end_msg() {} + + virtual void write_str(const std::string& str) + { + printf("wrapper write\n"); + this->get_override("write")(str); + } + }; + +Filter* return_or_raise(Filter* filter, const std::string& name) + { + if(filter) + return filter; + throw Invalid_Argument("Filter " + name + " could not be found"); + } + +Filter* make_filter1(const std::string& name) + { + Filter* filter = 0; + + if(have_hash(name)) filter = new Hash_Filter(name); + else if(name == "Hex_Encoder") filter = new Hex_Encoder; + else if(name == "Hex_Decoder") filter = new Hex_Decoder; + else if(name == "Base64_Encoder") filter = new Base64_Encoder; + else if(name == "Base64_Decoder") filter = new Base64_Decoder; + + return return_or_raise(filter, name); + } + +Filter* make_filter2(const std::string& name, + const SymmetricKey& key) + { + Filter* filter = 0; + + if(have_mac(name)) + filter = new MAC_Filter(name, key); + else if(have_stream_cipher(name)) + filter = new StreamCipher_Filter(name, key); + + return return_or_raise(filter, name); + } + +// FIXME: add new wrapper for Keyed_Filter here +Filter* make_filter3(const std::string& name, + const SymmetricKey& key, + Cipher_Dir direction) + { + return return_or_raise( + get_cipher(name, key, direction), + name); + } + +Filter* make_filter4(const std::string& name, + const SymmetricKey& key, + const InitializationVector& iv, + Cipher_Dir direction) + { + return return_or_raise( + get_cipher(name, key, iv, direction), + name); + } + +void append_filter(Pipe& pipe, std::auto_ptr filter) + { + pipe.append(filter.get()); + filter.release(); + } + +void prepend_filter(Pipe& pipe, std::auto_ptr filter) + { + pipe.prepend(filter.get()); + filter.release(); + } + +void do_send(std::auto_ptr filter, const std::string& data) + { + printf("Sending %s to %p\n", data.c_str(), filter.get()); + filter->send_str(data); + } + +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(rallas_ovls, read_all_as_string, 0, 1) + +void export_filters() + { + class_, boost::noncopyable> + ("__Internal_FilterObj", no_init); + + def("make_filter", make_filter1, + return_value_policy()); + def("make_filter", make_filter2, + return_value_policy()); + def("make_filter", make_filter3, + return_value_policy()); + def("make_filter", make_filter4, + return_value_policy()); + + // This might not work - Pipe will delete the filter, but Python + // might have allocated the space with malloc() or who-knows-what -> bad + class_, + bases, boost::noncopyable> + ("FilterObj") + .def("write", pure_virtual(&Py_Filter::write_str)) + .def("send", &do_send) + .def("start_msg", &Filter::start_msg, &FilterWrapper::default_start_msg) + .def("end_msg", &Filter::end_msg, &FilterWrapper::default_end_msg); + + implicitly_convertible, + std::auto_ptr >(); + + void (Pipe::*pipe_write_str)(const std::string&) = &Pipe::write; + void (Pipe::*pipe_process_str)(const std::string&) = &Pipe::process_msg; + + class_("PipeObj") + .def(init<>()) + /* + .def_readonly("LAST_MESSAGE", &Pipe::LAST_MESSAGE) + .def_readonly("DEFAULT_MESSAGE", &Pipe::DEFAULT_MESSAGE) + */ + .add_property("default_msg", &Pipe::default_msg, &Pipe::set_default_msg) + .add_property("msg_count", &Pipe::message_count) + .def("append", append_filter) + .def("prepend", prepend_filter) + .def("reset", &Pipe::reset) + .def("pop", &Pipe::pop) + .def("end_of_data", &Pipe::end_of_data) + .def("start_msg", &Pipe::start_msg) + .def("end_msg", &Pipe::end_msg) + .def("write", pipe_write_str) + .def("process_msg", pipe_process_str) + .def("read_all", &Pipe::read_all_as_string, rallas_ovls()); + } diff --git a/src/wrap/python/pk.cpp b/src/wrap/python/pk.cpp new file mode 100644 index 000000000..72d3294b8 --- /dev/null +++ b/src/wrap/python/pk.cpp @@ -0,0 +1,125 @@ +/************************************************* +* Boost.Python module definition * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include +#include +#include +#include +using namespace Botan; + +#include +namespace python = boost::python; + +std::string encode_pub(const Public_Key* key, + const std::string& type) + { + if(type == "DER") + { + Pipe pipe; + pipe.start_msg(); + X509::encode(*key, pipe, RAW_BER); + pipe.end_msg(); + return pipe.read_all_as_string(); + } + else if(type == "PEM") + return X509::PEM_encode(*key); + else + throw Encoding_Error("Unknown key encoding method " + type); + } + +std::string encode_priv(const Private_Key* key, + const std::string& type) + { + if(type == "DER") + { + Pipe pipe; + PKCS8::encode(*key, pipe, RAW_BER); + return pipe.read_all_as_string(); + } + else if(type == "PEM") + return PKCS8::PEM_encode(*key); + else + throw Encoding_Error("Unknown key encoding method " + type); + } + +/* +Private_Key* load_priv(const std::string& file, const std::string& pass) + { + return PKCS8::load_key(file, pass); + } + +Public_Key* load_public(const std::string& file) + { + return X509::load_key(file); + } +*/ + +/* +std::string encrypt_string(const PK_Encryptor* enc, const std::string& in) + { + SecureVector cipher = enc->encrypt((const byte*)in.data(), in.length()); + return std::string((const char*)cipher.begin(), cipher.size()); + } + +std::string decrypt_string(const PK_Decryptor* dec, const std::string& in) + { + SecureVector plain = dec->decrypt((const byte*)in.data(), in.length()); + return std::string((const char*)plain.begin(), plain.size()); + } +*/ + +void export_pk() + { + /* + python::def("private_key", load_priv, + python::return_value_policy()); + python::def("public_key", load_public, + python::return_value_policy()); + */ + + python::class_ + ("Public_Key", python::no_init) + .add_property("name", &Public_Key::algo_name) + .add_property("max_input_bits", &Public_Key::max_input_bits) + .def("public_key", encode_pub); + + python::class_, boost::noncopyable> + ("PK_Encrypting_Key", python::no_init); + + python::class_, boost::noncopyable> + ("Private_Key", python::no_init) + .def("private_key", encode_priv); + + python::class_, boost::noncopyable> + ("PK_Decrypting_Key", python::no_init); + + python::class_ > + ("RSA_PublicKey", python::no_init); + + python::class_ > + ("DSA_PublicKey", python::no_init); + + /* + python::class_ > + ("RSA_PrivateKey", python::init()); + */ + + /* + python::class_ + ("PK_Encryptor", python::no_init) + .def("__init__", + python::make_constructor(get_pk_encryptor, + python::with_custodian_and_ward_postcall<0, 1>())) + .def("max_input", &PK_Encryptor::maximum_input_size) + .def("encrypt", encrypt_string); + */ + + /* + python::class_ + ("PK_Decryptor", python::no_init) + .def("__init__", python::make_constructor(get_pk_decryptor)) + .def("decrypt", decrypt_string); + */ + } diff --git a/src/wrap/python/python_botan.h b/src/wrap/python/python_botan.h new file mode 100644 index 000000000..18c51dbb1 --- /dev/null +++ b/src/wrap/python/python_botan.h @@ -0,0 +1,51 @@ + +#ifndef BOTAN_BOOST_PYTHON_COMMON_H__ +#define BOTAN_BOOST_PYTHON_COMMON_H__ + +#include +#include +#include +using namespace Botan; + +#include +namespace python = boost::python; + +extern void export_filters(); +extern void export_pk(); +extern void export_x509(); + +class Bad_Size : public Exception + { + public: + Bad_Size(u32bit got, u32bit expected) : + Exception("Bad size detected in Python/C++ conversion layer: got " + + to_string(got) + " bytes, expected " + to_string(expected)) + {} + }; + +inline std::string make_string(const byte input[], u32bit length) + { + return std::string((const char*)input, length); + } + +inline std::string make_string(const MemoryRegion& in) + { + return make_string(in.begin(), in.size()); + } + +inline void string2binary(const std::string& from, byte to[], u32bit expected) + { + if(from.size() != expected) + throw Bad_Size(from.size(), expected); + std::memcpy(to, from.data(), expected); + } + +template +inline python::object get_owner(T* me) + { + return python::object( + python::handle<>( + python::borrowed(python::detail::wrapper_base_::get_owner(*me)))); + } + +#endif diff --git a/src/wrap/python/x509.cpp b/src/wrap/python/x509.cpp new file mode 100644 index 000000000..90c2bba1c --- /dev/null +++ b/src/wrap/python/x509.cpp @@ -0,0 +1,140 @@ +/************************************************* +* Boost.Python module definition * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include +#include +#include +#include +#include +#include +using namespace Botan; + +#include +namespace python = boost::python; + +template +class vector_to_list + { + public: + static PyObject* convert(const std::vector& in) + { + python::list out; + typename std::vector::const_iterator i = in.begin(); + while(i != in.end()) + { + out.append(*i); + ++i; + } + return python::incref(out.ptr()); + } + + vector_to_list() + { + python::to_python_converter, vector_to_list >(); + } + }; + +template +class memvec_to_hexstr + { + public: + static PyObject* convert(const T& in) + { + Pipe pipe(new Hex_Encoder); + pipe.process_msg(in); + std::string result = pipe.read_all_as_string(); + return python::incref(python::str(result).ptr()); + } + + memvec_to_hexstr() + { + python::to_python_converter >(); + } + }; + +class X509_Store_Search_Wrap : public X509_Store::Search_Func, + public python::wrapper + { + public: + bool match(const X509_Certificate& cert) const + { + return this->get_override("match")(cert); + } + }; + +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(add_cert_ols, add_cert, 1, 2) +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(validate_cert_ols, validate_cert, 1, 2) + +void export_x509() + { + vector_to_list(); + vector_to_list(); + memvec_to_hexstr >(); + + python::class_ + ("X509_Certificate", python::init()) + .def(python::self == python::self) + .def(python::self != python::self) + .add_property("version", &X509_Certificate::x509_version) + .add_property("is_CA", &X509_Certificate::is_CA_cert) + .add_property("self_signed", &X509_Certificate::is_self_signed) + .add_property("pathlimit", &X509_Certificate::path_limit) + .add_property("as_pem", &X509_Object::PEM_encode) + .def("start_time", &X509_Certificate::start_time) + .def("end_time", &X509_Certificate::end_time) + .def("subject_info", &X509_Certificate::subject_info) + .def("issuer_info", &X509_Certificate::issuer_info) + .def("ex_constraints", &X509_Certificate::ex_constraints) + .def("policies", &X509_Certificate::policies) + .def("subject_key_id", &X509_Certificate::subject_key_id) + .def("authority_key_id", &X509_Certificate::authority_key_id); + + python::class_ + ("X509_CRL", python::init()) + .add_property("as_pem", &X509_Object::PEM_encode); + + python::enum_("verify_result") + .value("verified", VERIFIED) + .value("unknown_x509_error", UNKNOWN_X509_ERROR) + .value("cannot_establish_trust", CANNOT_ESTABLISH_TRUST) + .value("cert_chain_too_long", CERT_CHAIN_TOO_LONG) + .value("signature_error", SIGNATURE_ERROR) + .value("policy_error", POLICY_ERROR) + .value("invalid_usage", INVALID_USAGE) + .value("cert_format_error", CERT_FORMAT_ERROR) + .value("cert_issuer_not_found", CERT_ISSUER_NOT_FOUND) + .value("cert_not_yet_valid", CERT_NOT_YET_VALID) + .value("cert_has_expired", CERT_HAS_EXPIRED) + .value("cert_is_revoked", CERT_IS_REVOKED) + .value("crl_format_error", CRL_FORMAT_ERROR) + .value("crl_issuer_not_found", CRL_ISSUER_NOT_FOUND) + .value("crl_not_yet_valid", CRL_NOT_YET_VALID) + .value("crl_has_expired", CRL_HAS_EXPIRED) + .value("ca_cert_cannot_sign", CA_CERT_CANNOT_SIGN) + .value("ca_cert_not_for_cert_issuer", CA_CERT_NOT_FOR_CERT_ISSUER) + .value("ca_cert_not_for_crl_issuer", CA_CERT_NOT_FOR_CRL_ISSUER); + + python::enum_("cert_usage") + .value("any", X509_Store::ANY) + .value("tls_server", X509_Store::TLS_SERVER) + .value("tls_client", X509_Store::TLS_CLIENT) + .value("code_signing", X509_Store::CODE_SIGNING) + .value("email_protection", X509_Store::EMAIL_PROTECTION) + .value("time_stamping", X509_Store::TIME_STAMPING) + .value("crl_signing", X509_Store::CRL_SIGNING); + + { + python::scope in_class = + python::class_("X509_Store") + .def("add_cert", &X509_Store::add_cert, add_cert_ols()) + .def("validate", &X509_Store::validate_cert, validate_cert_ols()) + .def("get_certs", &X509_Store::get_certs) + .def("add_crl", &X509_Store::add_crl); + + python::class_ + ("Search_Func") + .def("match", python::pure_virtual(&X509_Store::Search_Func::match)); + } + } diff --git a/wrappers/boost-python/Makefile b/wrappers/boost-python/Makefile index e3a1acf37..2d2c38e58 100644 --- a/wrappers/boost-python/Makefile +++ b/wrappers/boost-python/Makefile @@ -2,8 +2,8 @@ CXX = g++ LANG_FLAGS = -fPIC -Wall -Wno-unused -ftemplate-depth-255 OPT_FLAGS = -g -Os -PYTHON_ROOT = /usr/lib/python2.5/config -PYTHON_INC = -I/usr/include/python2.5 +PYTHON_ROOT = /usr/lib/python2.6/config +PYTHON_INC = -I/usr/include/python2.6 PYTHON_DEF = -DBOOST_PYTHON_DYNAMIC_LIB -DBOOST_PYTHON_SOURCE WRAPPER_CFLAGS = $(shell botan-config --cflags) @@ -11,13 +11,21 @@ SHARED_CFLAGS = $(LANG_FLAGS) $(OPT_FLAGS) $(PYTHON_INC) BOOST_CFLAGS = $(PYTHON_DEF) $(SHARED_CFLAGS) -WRAP_SRC = $(wildcard src/*.cpp) -WRAP_OBJS = $(patsubst src/%.cpp,build/%.o,$(WRAP_SRC)) +WRAP_OBJS = build/python/core.o build/python/filter.o build/python/pk.o build/python/x509.o all: botan/_botan.so -build/%.o: src/%.cpp - $(CXX) -Isrc/ $(SHARED_CFLAGS) $(WRAPPER_CFLAGS) -c $< -o $@ +build/python/core.o: src/wrap/python/core.cpp + $(CXX) -Isrc/wrap/python $(SHARED_CFLAGS) $(WRAPPER_CFLAGS) -c $< -o $@ + +build/python/filter.o: src/wrap/python/filter.cpp + $(CXX) -Isrc/wrap/python $(SHARED_CFLAGS) $(WRAPPER_CFLAGS) -c $< -o $@ + +build/python/pk.o: src/wrap/python/pk.cpp + $(CXX) -Isrc/wrap/python $(SHARED_CFLAGS) $(WRAPPER_CFLAGS) -c $< -o $@ + +build/python/x509.o: src/wrap/python/x509.cpp + $(CXX) -Isrc/wrap/python $(SHARED_CFLAGS) $(WRAPPER_CFLAGS) -c $< -o $@ botan/_botan.so: $(WRAP_OBJS) $(CXX) -shared -o $@ $(shell botan-config --libs) -L$(PYTHON_ROOT) $(WRAP_OBJS) -lboost_python -Wl,-rpath-link,. -Wl,-soname,$@ diff --git a/wrappers/boost-python/botan/__init__.py b/wrappers/boost-python/botan/__init__.py deleted file mode 100644 index 2df9a456f..000000000 --- a/wrappers/boost-python/botan/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from _botan import * - -# Initialize the library when the module is imported -init = LibraryInitializer() diff --git a/wrappers/boost-python/src/core.cpp b/wrappers/boost-python/src/core.cpp deleted file mode 100644 index 1992e3d61..000000000 --- a/wrappers/boost-python/src/core.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* -* Boost.Python module definition -* (C) 1999-2007 Jack Lloyd -*/ - -#include -#include -#include -using namespace Botan; - -#include "python_botan.h" - -class Python_RandomNumberGenerator - { - public: - Python_RandomNumberGenerator() - { rng = RandomNumberGenerator::make_rng(); } - ~Python_RandomNumberGenerator() { delete rng; } - - std::string name() const { return rng->name(); } - - void reseed() { rng->reseed(192); } - - int gen_random_byte() { return rng->next_byte(); } - - std::string gen_random(int n) - { - std::string s(n, 0); - rng->randomize(reinterpret_cast(&s[0]), n); - return s; - } - - void add_entropy(const std::string& in) - { rng->add_entropy(reinterpret_cast(in.c_str()), in.length()); } - - private: - RandomNumberGenerator* rng; - }; - -class Py_Cipher - { - public: - Py_Cipher(std::string algo_name, std::string direction, - std::string key); - - std::string cipher_noiv(const std::string& text); - - std::string cipher(const std::string& text, - const std::string& iv); - - std::string name() const { return algo_name; } - private: - std::string algo_name; - Keyed_Filter* filter; - Pipe pipe; - }; - -std::string Py_Cipher::cipher(const std::string& input, - const std::string& iv_str) - { - if(iv_str.size()) - { - const byte* iv_bytes = reinterpret_cast(iv_str.data()); - u32bit iv_len = iv_str.size(); - filter->set_iv(InitializationVector(iv_bytes, iv_len)); - } - - pipe.process_msg(input); - return pipe.read_all_as_string(Pipe::LAST_MESSAGE); - } - -// For IV-less algorithms -std::string Py_Cipher::cipher_noiv(const std::string& input) - { - pipe.process_msg(input); - return pipe.read_all_as_string(Pipe::LAST_MESSAGE); - } - -Py_Cipher::Py_Cipher(std::string algo_name, - std::string direction, - std::string key_str) - { - const byte* key_bytes = reinterpret_cast(key_str.data()); - u32bit key_len = key_str.size(); - - Cipher_Dir dir; - - if(direction == "encrypt") - dir = ENCRYPTION; - else if(direction == "decrypt") - dir = DECRYPTION; - else - throw std::invalid_argument("Bad cipher direction " + direction); - - filter = get_cipher(algo_name, dir); - filter->set_key(SymmetricKey(key_bytes, key_len)); - pipe.append(filter); - } - -class Py_HashFunction - { - public: - Py_HashFunction(const std::string& algo_name) - { - hash = get_hash(algo_name); - } - - ~Py_HashFunction() { delete hash; } - - void update(const std::string& input) - { - hash->update(input); - } - - std::string final() - { - std::string out(output_length(), 0); - hash->final(reinterpret_cast(&out[0])); - return out; - } - - std::string name() const - { - return hash->name(); - } - - u32bit output_length() const - { - return hash->OUTPUT_LENGTH; - } - - private: - HashFunction* hash; - }; - -class Py_MAC - { - public: - - Py_MAC(const std::string& name, const std::string& key_str) - { - mac = get_mac(name); - - mac->set_key(reinterpret_cast(key_str.data()), - key_str.size()); - } - - ~Py_MAC() { delete mac; } - - u32bit output_length() const { return mac->OUTPUT_LENGTH; } - - std::string name() const { return mac->name(); } - - void update(const std::string& in) { mac->update(in); } - - std::string final() - { - std::string out(output_length(), 0); - mac->final(reinterpret_cast(&out[0])); - return out; - } - private: - MessageAuthenticationCode* mac; - }; - -BOOST_PYTHON_MODULE(_botan) - { - python::class_("LibraryInitializer") - .def(python::init< python::optional >()); - - python::class_("RandomNumberGenerator") - .def(python::init<>()) - .def("__str__", &Python_RandomNumberGenerator::name) - .def("name", &Python_RandomNumberGenerator::name) - .def("reseed", &Python_RandomNumberGenerator::reseed) - .def("add_entropy", &Python_RandomNumberGenerator::add_entropy) - .def("gen_random_byte", &Python_RandomNumberGenerator::gen_random_byte) - .def("gen_random", &Python_RandomNumberGenerator::gen_random); - - python::class_ - ("Cipher", python::init()) - .def("name", &Py_Cipher::name) - .def("cipher", &Py_Cipher::cipher) - .def("cipher", &Py_Cipher::cipher_noiv); - - python::class_ - ("HashFunction", python::init()) - .def("update", &Py_HashFunction::update) - .def("final", &Py_HashFunction::final) - .def("name", &Py_HashFunction::name) - .def("output_length", &Py_HashFunction::output_length); - - python::class_ - ("MAC", python::init()) - .def("update", &Py_MAC::update) - .def("final", &Py_MAC::final) - .def("name", &Py_MAC::name) - .def("output_length", &Py_MAC::output_length); - - export_filters(); - export_pk(); - export_x509(); - } diff --git a/wrappers/boost-python/src/filter.cpp b/wrappers/boost-python/src/filter.cpp deleted file mode 100644 index 830e090de..000000000 --- a/wrappers/boost-python/src/filter.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/************************************************* -* Boost.Python module definition * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include -using namespace boost::python; - -#include -#include -using namespace Botan; - -class Py_Filter : public Filter - { - public: - virtual void write_str(const std::string&) = 0; - - void write(const byte data[], u32bit length) - { - write_str(std::string((const char*)data, length)); - } - - void send_str(const std::string& str) - { - printf("Py_Filter::send_str\n"); - send((const byte*)str.data(), str.length()); - } - }; - -class FilterWrapper : public Py_Filter, public wrapper - { - public: - void start_msg() - { - printf("wrapper start_msg\n"); - if(override start_msg = this->get_override("start_msg")) - start_msg(); - } - - void end_msg() - { - printf("wrapper end_msg\n"); - if(override end_msg = this->get_override("end_msg")) - end_msg(); - } - - void default_start_msg() {} - void default_end_msg() {} - - virtual void write_str(const std::string& str) - { - printf("wrapper write\n"); - this->get_override("write")(str); - } - }; - -Filter* return_or_raise(Filter* filter, const std::string& name) - { - if(filter) - return filter; - throw Invalid_Argument("Filter " + name + " could not be found"); - } - -Filter* make_filter1(const std::string& name) - { - Filter* filter = 0; - - if(have_hash(name)) filter = new Hash_Filter(name); - else if(name == "Hex_Encoder") filter = new Hex_Encoder; - else if(name == "Hex_Decoder") filter = new Hex_Decoder; - else if(name == "Base64_Encoder") filter = new Base64_Encoder; - else if(name == "Base64_Decoder") filter = new Base64_Decoder; - - return return_or_raise(filter, name); - } - -Filter* make_filter2(const std::string& name, - const SymmetricKey& key) - { - Filter* filter = 0; - - if(have_mac(name)) - filter = new MAC_Filter(name, key); - else if(have_stream_cipher(name)) - filter = new StreamCipher_Filter(name, key); - - return return_or_raise(filter, name); - } - -// FIXME: add new wrapper for Keyed_Filter here -Filter* make_filter3(const std::string& name, - const SymmetricKey& key, - Cipher_Dir direction) - { - return return_or_raise( - get_cipher(name, key, direction), - name); - } - -Filter* make_filter4(const std::string& name, - const SymmetricKey& key, - const InitializationVector& iv, - Cipher_Dir direction) - { - return return_or_raise( - get_cipher(name, key, iv, direction), - name); - } - -void append_filter(Pipe& pipe, std::auto_ptr filter) - { - pipe.append(filter.get()); - filter.release(); - } - -void prepend_filter(Pipe& pipe, std::auto_ptr filter) - { - pipe.prepend(filter.get()); - filter.release(); - } - -void do_send(std::auto_ptr filter, const std::string& data) - { - printf("Sending %s to %p\n", data.c_str(), filter.get()); - filter->send_str(data); - } - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(rallas_ovls, read_all_as_string, 0, 1) - -void export_filters() - { - class_, boost::noncopyable> - ("__Internal_FilterObj", no_init); - - def("make_filter", make_filter1, - return_value_policy()); - def("make_filter", make_filter2, - return_value_policy()); - def("make_filter", make_filter3, - return_value_policy()); - def("make_filter", make_filter4, - return_value_policy()); - - // This might not work - Pipe will delete the filter, but Python - // might have allocated the space with malloc() or who-knows-what -> bad - class_, - bases, boost::noncopyable> - ("FilterObj") - .def("write", pure_virtual(&Py_Filter::write_str)) - .def("send", &do_send) - .def("start_msg", &Filter::start_msg, &FilterWrapper::default_start_msg) - .def("end_msg", &Filter::end_msg, &FilterWrapper::default_end_msg); - - implicitly_convertible, - std::auto_ptr >(); - - void (Pipe::*pipe_write_str)(const std::string&) = &Pipe::write; - void (Pipe::*pipe_process_str)(const std::string&) = &Pipe::process_msg; - - class_("PipeObj") - .def(init<>()) - .def_readonly("LAST_MESSAGE", &Pipe::LAST_MESSAGE) - .def_readonly("DEFAULT_MESSAGE", &Pipe::DEFAULT_MESSAGE) - .add_property("default_msg", &Pipe::default_msg, &Pipe::set_default_msg) - .add_property("msg_count", &Pipe::message_count) - .def("append", append_filter) - .def("prepend", prepend_filter) - .def("reset", &Pipe::reset) - .def("pop", &Pipe::pop) - .def("end_of_data", &Pipe::end_of_data) - .def("start_msg", &Pipe::start_msg) - .def("end_msg", &Pipe::end_msg) - .def("write", pipe_write_str) - .def("process_msg", pipe_process_str) - .def("read_all", &Pipe::read_all_as_string, rallas_ovls()); - } diff --git a/wrappers/boost-python/src/pk.cpp b/wrappers/boost-python/src/pk.cpp deleted file mode 100644 index 72d3294b8..000000000 --- a/wrappers/boost-python/src/pk.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/************************************************* -* Boost.Python module definition * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include -#include -#include -#include -using namespace Botan; - -#include -namespace python = boost::python; - -std::string encode_pub(const Public_Key* key, - const std::string& type) - { - if(type == "DER") - { - Pipe pipe; - pipe.start_msg(); - X509::encode(*key, pipe, RAW_BER); - pipe.end_msg(); - return pipe.read_all_as_string(); - } - else if(type == "PEM") - return X509::PEM_encode(*key); - else - throw Encoding_Error("Unknown key encoding method " + type); - } - -std::string encode_priv(const Private_Key* key, - const std::string& type) - { - if(type == "DER") - { - Pipe pipe; - PKCS8::encode(*key, pipe, RAW_BER); - return pipe.read_all_as_string(); - } - else if(type == "PEM") - return PKCS8::PEM_encode(*key); - else - throw Encoding_Error("Unknown key encoding method " + type); - } - -/* -Private_Key* load_priv(const std::string& file, const std::string& pass) - { - return PKCS8::load_key(file, pass); - } - -Public_Key* load_public(const std::string& file) - { - return X509::load_key(file); - } -*/ - -/* -std::string encrypt_string(const PK_Encryptor* enc, const std::string& in) - { - SecureVector cipher = enc->encrypt((const byte*)in.data(), in.length()); - return std::string((const char*)cipher.begin(), cipher.size()); - } - -std::string decrypt_string(const PK_Decryptor* dec, const std::string& in) - { - SecureVector plain = dec->decrypt((const byte*)in.data(), in.length()); - return std::string((const char*)plain.begin(), plain.size()); - } -*/ - -void export_pk() - { - /* - python::def("private_key", load_priv, - python::return_value_policy()); - python::def("public_key", load_public, - python::return_value_policy()); - */ - - python::class_ - ("Public_Key", python::no_init) - .add_property("name", &Public_Key::algo_name) - .add_property("max_input_bits", &Public_Key::max_input_bits) - .def("public_key", encode_pub); - - python::class_, boost::noncopyable> - ("PK_Encrypting_Key", python::no_init); - - python::class_, boost::noncopyable> - ("Private_Key", python::no_init) - .def("private_key", encode_priv); - - python::class_, boost::noncopyable> - ("PK_Decrypting_Key", python::no_init); - - python::class_ > - ("RSA_PublicKey", python::no_init); - - python::class_ > - ("DSA_PublicKey", python::no_init); - - /* - python::class_ > - ("RSA_PrivateKey", python::init()); - */ - - /* - python::class_ - ("PK_Encryptor", python::no_init) - .def("__init__", - python::make_constructor(get_pk_encryptor, - python::with_custodian_and_ward_postcall<0, 1>())) - .def("max_input", &PK_Encryptor::maximum_input_size) - .def("encrypt", encrypt_string); - */ - - /* - python::class_ - ("PK_Decryptor", python::no_init) - .def("__init__", python::make_constructor(get_pk_decryptor)) - .def("decrypt", decrypt_string); - */ - } diff --git a/wrappers/boost-python/src/python_botan.h b/wrappers/boost-python/src/python_botan.h deleted file mode 100644 index 18c51dbb1..000000000 --- a/wrappers/boost-python/src/python_botan.h +++ /dev/null @@ -1,51 +0,0 @@ - -#ifndef BOTAN_BOOST_PYTHON_COMMON_H__ -#define BOTAN_BOOST_PYTHON_COMMON_H__ - -#include -#include -#include -using namespace Botan; - -#include -namespace python = boost::python; - -extern void export_filters(); -extern void export_pk(); -extern void export_x509(); - -class Bad_Size : public Exception - { - public: - Bad_Size(u32bit got, u32bit expected) : - Exception("Bad size detected in Python/C++ conversion layer: got " + - to_string(got) + " bytes, expected " + to_string(expected)) - {} - }; - -inline std::string make_string(const byte input[], u32bit length) - { - return std::string((const char*)input, length); - } - -inline std::string make_string(const MemoryRegion& in) - { - return make_string(in.begin(), in.size()); - } - -inline void string2binary(const std::string& from, byte to[], u32bit expected) - { - if(from.size() != expected) - throw Bad_Size(from.size(), expected); - std::memcpy(to, from.data(), expected); - } - -template -inline python::object get_owner(T* me) - { - return python::object( - python::handle<>( - python::borrowed(python::detail::wrapper_base_::get_owner(*me)))); - } - -#endif diff --git a/wrappers/boost-python/src/x509.cpp b/wrappers/boost-python/src/x509.cpp deleted file mode 100644 index 90c2bba1c..000000000 --- a/wrappers/boost-python/src/x509.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/************************************************* -* Boost.Python module definition * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include -#include -#include -#include -#include -#include -using namespace Botan; - -#include -namespace python = boost::python; - -template -class vector_to_list - { - public: - static PyObject* convert(const std::vector& in) - { - python::list out; - typename std::vector::const_iterator i = in.begin(); - while(i != in.end()) - { - out.append(*i); - ++i; - } - return python::incref(out.ptr()); - } - - vector_to_list() - { - python::to_python_converter, vector_to_list >(); - } - }; - -template -class memvec_to_hexstr - { - public: - static PyObject* convert(const T& in) - { - Pipe pipe(new Hex_Encoder); - pipe.process_msg(in); - std::string result = pipe.read_all_as_string(); - return python::incref(python::str(result).ptr()); - } - - memvec_to_hexstr() - { - python::to_python_converter >(); - } - }; - -class X509_Store_Search_Wrap : public X509_Store::Search_Func, - public python::wrapper - { - public: - bool match(const X509_Certificate& cert) const - { - return this->get_override("match")(cert); - } - }; - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(add_cert_ols, add_cert, 1, 2) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(validate_cert_ols, validate_cert, 1, 2) - -void export_x509() - { - vector_to_list(); - vector_to_list(); - memvec_to_hexstr >(); - - python::class_ - ("X509_Certificate", python::init()) - .def(python::self == python::self) - .def(python::self != python::self) - .add_property("version", &X509_Certificate::x509_version) - .add_property("is_CA", &X509_Certificate::is_CA_cert) - .add_property("self_signed", &X509_Certificate::is_self_signed) - .add_property("pathlimit", &X509_Certificate::path_limit) - .add_property("as_pem", &X509_Object::PEM_encode) - .def("start_time", &X509_Certificate::start_time) - .def("end_time", &X509_Certificate::end_time) - .def("subject_info", &X509_Certificate::subject_info) - .def("issuer_info", &X509_Certificate::issuer_info) - .def("ex_constraints", &X509_Certificate::ex_constraints) - .def("policies", &X509_Certificate::policies) - .def("subject_key_id", &X509_Certificate::subject_key_id) - .def("authority_key_id", &X509_Certificate::authority_key_id); - - python::class_ - ("X509_CRL", python::init()) - .add_property("as_pem", &X509_Object::PEM_encode); - - python::enum_("verify_result") - .value("verified", VERIFIED) - .value("unknown_x509_error", UNKNOWN_X509_ERROR) - .value("cannot_establish_trust", CANNOT_ESTABLISH_TRUST) - .value("cert_chain_too_long", CERT_CHAIN_TOO_LONG) - .value("signature_error", SIGNATURE_ERROR) - .value("policy_error", POLICY_ERROR) - .value("invalid_usage", INVALID_USAGE) - .value("cert_format_error", CERT_FORMAT_ERROR) - .value("cert_issuer_not_found", CERT_ISSUER_NOT_FOUND) - .value("cert_not_yet_valid", CERT_NOT_YET_VALID) - .value("cert_has_expired", CERT_HAS_EXPIRED) - .value("cert_is_revoked", CERT_IS_REVOKED) - .value("crl_format_error", CRL_FORMAT_ERROR) - .value("crl_issuer_not_found", CRL_ISSUER_NOT_FOUND) - .value("crl_not_yet_valid", CRL_NOT_YET_VALID) - .value("crl_has_expired", CRL_HAS_EXPIRED) - .value("ca_cert_cannot_sign", CA_CERT_CANNOT_SIGN) - .value("ca_cert_not_for_cert_issuer", CA_CERT_NOT_FOR_CERT_ISSUER) - .value("ca_cert_not_for_crl_issuer", CA_CERT_NOT_FOR_CRL_ISSUER); - - python::enum_("cert_usage") - .value("any", X509_Store::ANY) - .value("tls_server", X509_Store::TLS_SERVER) - .value("tls_client", X509_Store::TLS_CLIENT) - .value("code_signing", X509_Store::CODE_SIGNING) - .value("email_protection", X509_Store::EMAIL_PROTECTION) - .value("time_stamping", X509_Store::TIME_STAMPING) - .value("crl_signing", X509_Store::CRL_SIGNING); - - { - python::scope in_class = - python::class_("X509_Store") - .def("add_cert", &X509_Store::add_cert, add_cert_ols()) - .def("validate", &X509_Store::validate_cert, validate_cert_ols()) - .def("get_certs", &X509_Store::get_certs) - .def("add_crl", &X509_Store::add_crl); - - python::class_ - ("Search_Func") - .def("match", python::pure_virtual(&X509_Store::Search_Func::match)); - } - } -- cgit v1.2.3 From 621d5391649011aa63b5d3f706f6f2544a03fc21 Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 9 Oct 2009 18:11:14 +0000 Subject: Drop the SWIG wrappers; never worked. Move the XS wrappers to src/wrap/perl-xs --- src/wrap/perl-xs/Botan.pm | 117 ++++++ src/wrap/perl-xs/Botan.xs | 829 ++++++++++++++++++++++++++++++++++++++ src/wrap/perl-xs/Changes | 4 + src/wrap/perl-xs/MANIFEST | 15 + src/wrap/perl-xs/Makefile.PL | 29 ++ src/wrap/perl-xs/data/ca.cert.der | Bin 0 -> 712 bytes src/wrap/perl-xs/data/ca.cert.pem | 17 + src/wrap/perl-xs/t/base64.t | 273 +++++++++++++ src/wrap/perl-xs/t/filt.t | 56 +++ src/wrap/perl-xs/t/hex.t | 256 ++++++++++++ src/wrap/perl-xs/t/oid.t | 45 +++ src/wrap/perl-xs/t/pipe.t | 98 +++++ src/wrap/perl-xs/t/testutl.pl | 26 ++ src/wrap/perl-xs/t/x509cert.t | 42 ++ src/wrap/perl-xs/typemap | 62 +++ wrappers/perl-xs/Botan.pm | 117 ------ wrappers/perl-xs/Botan.xs | 829 -------------------------------------- wrappers/perl-xs/Changes | 4 - wrappers/perl-xs/MANIFEST | 15 - wrappers/perl-xs/Makefile.PL | 29 -- wrappers/perl-xs/data/ca.cert.der | Bin 712 -> 0 bytes wrappers/perl-xs/data/ca.cert.pem | 17 - wrappers/perl-xs/t/base64.t | 273 ------------- wrappers/perl-xs/t/filt.t | 56 --- wrappers/perl-xs/t/hex.t | 256 ------------ wrappers/perl-xs/t/oid.t | 45 --- wrappers/perl-xs/t/pipe.t | 98 ----- wrappers/perl-xs/t/testutl.pl | 26 -- wrappers/perl-xs/t/x509cert.t | 42 -- wrappers/perl-xs/typemap | 62 --- wrappers/swig/Makefile | 32 -- wrappers/swig/base.cpp | 61 --- wrappers/swig/base.h | 102 ----- wrappers/swig/botan.swg | 26 -- wrappers/swig/doit.py | 49 --- wrappers/swig/filter.cpp | 39 -- wrappers/swig/pipe.cpp | 89 ---- wrappers/swig/pk.swg | 8 - wrappers/swig/readme.txt | 34 -- wrappers/swig/tests/block.py | 52 --- wrappers/swig/tests/block2.py | 44 -- wrappers/swig/tests/encrypt.py | 37 -- wrappers/swig/tests/filter.py | 27 -- wrappers/swig/tests/hash.py | 30 -- wrappers/swig/tests/mac.py | 12 - wrappers/swig/tests/pubkey.py | 10 - wrappers/swig/tests/stream.py | 17 - wrappers/swig/x509.swg | 9 - 48 files changed, 1869 insertions(+), 2547 deletions(-) create mode 100644 src/wrap/perl-xs/Botan.pm create mode 100644 src/wrap/perl-xs/Botan.xs create mode 100644 src/wrap/perl-xs/Changes create mode 100644 src/wrap/perl-xs/MANIFEST create mode 100644 src/wrap/perl-xs/Makefile.PL create mode 100644 src/wrap/perl-xs/data/ca.cert.der create mode 100644 src/wrap/perl-xs/data/ca.cert.pem create mode 100644 src/wrap/perl-xs/t/base64.t create mode 100644 src/wrap/perl-xs/t/filt.t create mode 100644 src/wrap/perl-xs/t/hex.t create mode 100644 src/wrap/perl-xs/t/oid.t create mode 100644 src/wrap/perl-xs/t/pipe.t create mode 100644 src/wrap/perl-xs/t/testutl.pl create mode 100644 src/wrap/perl-xs/t/x509cert.t create mode 100644 src/wrap/perl-xs/typemap delete mode 100644 wrappers/perl-xs/Botan.pm delete mode 100644 wrappers/perl-xs/Botan.xs delete mode 100644 wrappers/perl-xs/Changes delete mode 100644 wrappers/perl-xs/MANIFEST delete mode 100644 wrappers/perl-xs/Makefile.PL delete mode 100644 wrappers/perl-xs/data/ca.cert.der delete mode 100644 wrappers/perl-xs/data/ca.cert.pem delete mode 100644 wrappers/perl-xs/t/base64.t delete mode 100644 wrappers/perl-xs/t/filt.t delete mode 100644 wrappers/perl-xs/t/hex.t delete mode 100644 wrappers/perl-xs/t/oid.t delete mode 100644 wrappers/perl-xs/t/pipe.t delete mode 100644 wrappers/perl-xs/t/testutl.pl delete mode 100644 wrappers/perl-xs/t/x509cert.t delete mode 100644 wrappers/perl-xs/typemap delete mode 100644 wrappers/swig/Makefile delete mode 100644 wrappers/swig/base.cpp delete mode 100644 wrappers/swig/base.h delete mode 100644 wrappers/swig/botan.swg delete mode 100755 wrappers/swig/doit.py delete mode 100644 wrappers/swig/filter.cpp delete mode 100644 wrappers/swig/pipe.cpp delete mode 100644 wrappers/swig/pk.swg delete mode 100644 wrappers/swig/readme.txt delete mode 100644 wrappers/swig/tests/block.py delete mode 100644 wrappers/swig/tests/block2.py delete mode 100644 wrappers/swig/tests/encrypt.py delete mode 100644 wrappers/swig/tests/filter.py delete mode 100644 wrappers/swig/tests/hash.py delete mode 100644 wrappers/swig/tests/mac.py delete mode 100644 wrappers/swig/tests/pubkey.py delete mode 100644 wrappers/swig/tests/stream.py delete mode 100644 wrappers/swig/x509.swg (limited to 'src') diff --git a/src/wrap/perl-xs/Botan.pm b/src/wrap/perl-xs/Botan.pm new file mode 100644 index 000000000..ac4ad91fb --- /dev/null +++ b/src/wrap/perl-xs/Botan.pm @@ -0,0 +1,117 @@ +package Botan; + +use strict; +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $AUTOLOAD); + +require DynaLoader; +require AutoLoader; +use Carp; + +@ISA = qw(DynaLoader); +$VERSION = '0.01'; + +@EXPORT_OK = qw( + NONE + IGNORE_WS + FULL_CHECK +); + +%EXPORT_TAGS = ( + 'all' => [ @EXPORT_OK ], + 'decoder_checking' => [ qw( + NONE + IGNORE_WS + FULL_CHECK + )], + +); + + +sub AUTOLOAD +{ + # This AUTOLOAD is used to 'autoload' constants from the constant() + # XS function. If a constant is not found then control is passed + # to the AUTOLOAD in AutoLoader. + + my $constname = $AUTOLOAD; + $constname =~ s/.*:://; + croak '& not defined' if $constname eq 'constant'; +# my $val = constant($constname, @_ ? $_[0] : 0); + my $val = constant($constname); + if ($! != 0) { + if ( $! =~ /Invalid/ ) + { + $AutoLoader::AUTOLOAD = $AUTOLOAD; + goto &AutoLoader::AUTOLOAD; + } + else + { + croak "Your vendor has not defined Botan symbol $constname"; + } + } + no strict 'refs'; + *$AUTOLOAD = sub { $val }; + goto &$AUTOLOAD; +} + + +bootstrap Botan $VERSION; + +# to setup inheritance... + +package Botan::Filter; +use vars qw(@ISA); +@ISA = qw(); + +package Botan::Chain; +use vars qw(@ISA); +@ISA = qw( Botan::Filter ); + +package Botan::Fork; +use vars qw(@ISA); +@ISA = qw( Botan::Filter ); + +package Botan::Hex_Encoder; +use vars qw(@ISA); +@ISA = qw( Botan::Filter ); + +package Botan::Hex_Decoder; +use vars qw(@ISA); +@ISA = qw( Botan::Filter ); + +package Botan::Base64_Decoder; +use vars qw(@ISA); +@ISA = qw( Botan::Filter ); + +package Botan::Base64_Encoder; +use vars qw(@ISA); +@ISA = qw( Botan::Filter ); + + +package Botan; + +1; +__END__ + +=head1 NAME + +Botan - Perl extension for access to Botan ... + +=head1 SYNOPSIS + + use Botan; + blah blah blah + +=head1 DESCRIPTION + +Blah blah blah. + +=head1 AUTHOR + +Vaclav Ovsik + +=head1 SEE ALSO + +Bla + +=cut diff --git a/src/wrap/perl-xs/Botan.xs b/src/wrap/perl-xs/Botan.xs new file mode 100644 index 000000000..ded129d2e --- /dev/null +++ b/src/wrap/perl-xs/Botan.xs @@ -0,0 +1,829 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +#ifdef __cplusplus +} +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* xsubpp converts ':' to '_' in typemap. We create our types without ':' */ + +typedef Botan::ASN1_String Botan__ASN1_String; +typedef Botan::AlgorithmIdentifier Botan__AlgorithmIdentifier; +typedef Botan::AlternativeName Botan__AlternativeName; +typedef Botan::Attribute Botan__Attribute; +typedef Botan::Base64_Decoder Botan__Base64_Decoder; +typedef Botan::Base64_Encoder Botan__Base64_Encoder; +typedef Botan::Chain Botan__Chain; +typedef Botan::Certificate_Extension Botan__Extension; +typedef Botan::Filter Botan__Filter; +typedef Botan::Fork Botan__Fork; +typedef Botan::Hex_Decoder Botan__Hex_Decoder; +typedef Botan::Hex_Encoder Botan__Hex_Encoder; +typedef Botan::OID Botan__OID; +typedef Botan::Pipe Botan__Pipe; +typedef Botan::X509_Certificate Botan__X509_Certificate; +typedef Botan::X509_DN Botan__X509_DN; +typedef Botan::X509_Time Botan__X509_Time; +typedef Botan::u32bit Botan__u32bit; + + +/* Types to keep track of destruction C++ objects passed + * into other objects... + * An Botan object is deleted by his parent object into which is passed, + * e.g. some Filter is deleted when his Pipe is destructed. We must + * track this and not to delete object again in Perls destructor. + */ + +class ObjectInfo +{ +private: + I32 d_signature; + bool d_del; +public: + static I32 const SIGNVAL = 0x696a626f; + ObjectInfo() : d_signature(SIGNVAL), + d_del(true) {}; + ~ObjectInfo() {}; + void set_delete(bool del = true) { d_del = del; }; + void set_delete_no() { set_delete(false); }; + void set_delete_yes() { set_delete(true); }; + bool should_delete() const { return d_del; }; +}; + +/* Constant object in initial state - template */ + +ObjectInfo const oi_init; + + +/* Botan library initializer ... */ + +Botan::LibraryInitializer botan_init; + + + +/*============================================================================*/ + +MODULE = Botan PACKAGE = Botan + +PROTOTYPES: ENABLE + +void +constant(char *name) + CODE: + using namespace Botan; + errno = 0; + switch (name[0]) + { + case 'F': + if ( strEQ(name, "FULL_CHECK") ) + XSRETURN_IV( FULL_CHECK ); // Decoder_Checking enum + break; + case 'I': + if ( strEQ(name, "IGNORE_WS") ) + XSRETURN_IV( IGNORE_WS ); // Decoder_Checking enum + break; + case 'N': + if ( strEQ(name, "NONE") ) + XSRETURN_IV( NONE ); // Decoder_Checking enum + break; + } + errno = EINVAL; + XSRETURN_UNDEF; + + +# =========================== Botan::Chain ========================== + +MODULE = Botan PACKAGE = Botan::Chain + +Botan__Chain * +Botan__Chain::new(f1 = 0, f2 = 0, f3 = 0, f4 = 0) + Botan__Filter *f1; + Botan__Filter *f2; + Botan__Filter *f3; + Botan__Filter *f4; + PREINIT: + ObjectInfo *f1_oi; + ObjectInfo *f2_oi; + ObjectInfo *f3_oi; + ObjectInfo *f4_oi; + CODE: + try { + RETVAL = new Botan__Chain(f1, f2, f3, f4); + if ( f1 ) f1_oi->set_delete_no(); + if ( f2 ) f2_oi->set_delete_no(); + if ( f3 ) f3_oi->set_delete_no(); + if ( f4 ) f4_oi->set_delete_no(); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +void +Botan__Chain::DESTROY() + PREINIT: + ObjectInfo *THIS_oi; + CODE: + if ( THIS_oi->should_delete() ) + try { + delete THIS; + } + catch (const std::exception &e) { + croak(e.what()); + } + + +# =========================== Botan::Fork ========================== + +MODULE = Botan PACKAGE = Botan::Fork + +Botan__Fork * +Botan__Fork::new(f1 = 0, f2 = 0, f3 = 0, f4 = 0) + Botan__Filter *f1; + Botan__Filter *f2; + Botan__Filter *f3; + Botan__Filter *f4; + PREINIT: + ObjectInfo *f1_oi; + ObjectInfo *f2_oi; + ObjectInfo *f3_oi; + ObjectInfo *f4_oi; + CODE: + try { + RETVAL = new Botan__Fork(f1, f2, f3, f4); + if ( f1 ) f1_oi->set_delete_no(); + if ( f2 ) f2_oi->set_delete_no(); + if ( f3 ) f3_oi->set_delete_no(); + if ( f4 ) f4_oi->set_delete_no(); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +void +Botan__Fork::DESTROY() + PREINIT: + ObjectInfo *THIS_oi; + CODE: + if ( THIS_oi->should_delete() ) + try { + delete THIS; + } + catch (const std::exception &e) { + croak(e.what()); + } + + +# ============================ Botan::Base64_Decoder ============================ + +MODULE = Botan PACKAGE = Botan::Base64_Decoder + +Botan__Base64_Decoder * +Botan__Base64_Decoder::new(checking = Botan::NONE) + int checking; + CODE: + try { + using namespace Botan; + RETVAL = new Base64_Decoder((Decoder_Checking)checking); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +void +Botan__Base64_Decoder::DESTROY() + PREINIT: + ObjectInfo *THIS_oi; + CODE: + if ( THIS_oi->should_delete() ) + try { + delete THIS; + } + catch (const std::exception &e) { + croak(e.what()); + } + + +# =========================== Botan::Base64_Encoder ========================== + +MODULE = Botan PACKAGE = Botan::Base64_Encoder + +Botan__Base64_Encoder * +Botan__Base64_Encoder::new(breaks = false, length = 72) + bool breaks; + Botan__u32bit length; + CODE: + try { + RETVAL = new Botan__Base64_Encoder(breaks, length); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +void +Botan__Base64_Encoder::DESTROY() + PREINIT: + ObjectInfo *THIS_oi; + CODE: + if ( THIS_oi->should_delete() ) + try { + delete THIS; + } + catch (const std::exception &e) { + croak(e.what()); + } + + +# ============================ Botan::Hex_Decoder ============================ + +MODULE = Botan PACKAGE = Botan::Hex_Decoder + +Botan__Hex_Decoder * +Botan__Hex_Decoder::new(checking = Botan::NONE) + int checking; + CODE: + try { + using namespace Botan; + RETVAL = new Hex_Decoder((Decoder_Checking)checking); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +void +Botan__Hex_Decoder::DESTROY() + PREINIT: + ObjectInfo *THIS_oi; + CODE: + if ( THIS_oi->should_delete() ) + try { + delete THIS; + } + catch (const std::exception &e) { + croak(e.what()); + } + + +# ============================ Botan::Hex_Encoder ============================ + +MODULE = Botan PACKAGE = Botan::Hex_Encoder + +Botan__Hex_Encoder * +Botan__Hex_Encoder::new(breaks = false, length = 72, lcase = false) + bool breaks; + Botan__u32bit length; + bool lcase; + CODE: + try { + using Botan::Hex_Encoder; + RETVAL = new Hex_Encoder(breaks, length, + lcase ? Hex_Encoder::Lowercase : Hex_Encoder::Uppercase); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +void +Botan__Hex_Encoder::DESTROY() + PREINIT: + ObjectInfo *THIS_oi; + CODE: + if ( THIS_oi->should_delete() ) + try { + delete THIS; + } + catch (const std::exception &e) { + croak(e.what()); + } + + +# ================================ Botan::OID ================================ + +MODULE = Botan PACKAGE = Botan::OID + +Botan__OID * +Botan__OID::new(s) + char *s; + CODE: + try { + RETVAL = new Botan__OID(s); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +void +Botan__OID::DESTROY() + CODE: + try { + delete THIS; + } + catch (const std::exception &e) { + croak(e.what()); + } + +char * +Botan__OID::as_string() + CODE: + try { + RETVAL = const_cast(THIS->as_string().c_str()); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + + +# ================================ Botan::OIDS ================================ + +MODULE = Botan PACKAGE = Botan::OIDS + +void +add_oid(oid, name) + Botan__OID *oid; + char *name; + CODE: + try { + Botan::OIDS::add_oid(*oid, name); + } + catch (const std::exception &e) { + croak(e.what()); + } + +char * +lookup_by_oid(oid) + Botan__OID *oid; + CODE: + try { + RETVAL = const_cast(Botan::OIDS::lookup(*oid).c_str()); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +Botan__OID * +lookup_by_name(name) + char *name; + CODE: + try { + RETVAL = new Botan__OID(Botan::OIDS::lookup(name)); + } + catch (const std::exception &e) { + croak(e.what()); + } + char const * CLASS = "Botan::OID"; + OUTPUT: + RETVAL + +int +have_oid(name) + char *name; + CODE: + try { + RETVAL = Botan::OIDS::have_oid(name); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + + +# ================================ Botan::Pipe ================================ + +MODULE = Botan PACKAGE = Botan::Pipe + +Botan__Pipe * +Botan__Pipe::new(...) + CODE: + for (I32 i = 1; i < items; i++) + { + if ( !sv_isobject(ST(i)) || (SvTYPE(SvRV(ST(i))) != SVt_PVMG) ) + croak("Botan::Pipe::new() -- arg %u is not " + "a blessed SV reference", i +1); + if ( !sv_derived_from(ST(i), "Botan::Filter") ) + croak("Botan::Pipe::new() -- arg %u is not " + "an object derived from Botan::Filter", i +1); + MAGIC *mg = mg_find(SvRV(ST(i)), '~'); + if ( mg == 0 + || mg->mg_len != sizeof(ObjectInfo) + || *(I32 *)(mg->mg_ptr) != ObjectInfo::SIGNVAL ) + croak("Botan::Pipe::new() -- arg %u has no " + "valid private magic data (ObjectInfo)", i +1); + } + try { + RETVAL = new Botan__Pipe(); + for (I32 i = 1; i < items; i++) + { + SV *osv = (SV *)SvRV(ST(i)); + ObjectInfo *oi = (ObjectInfo *)(mg_find(osv, '~')->mg_ptr); + RETVAL->append((Botan__Filter *)(SvIV(osv))); + oi->set_delete_no(); + } + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +void +Botan__Pipe::DESTROY() + PREINIT: + ObjectInfo *THIS_oi; + CODE: + try { + delete THIS; + } + catch (const std::exception &e) { + croak(e.what()); + } + +void +Botan__Pipe::write(s) + SV *s; + PREINIT: + ObjectInfo *THIS_oi; + CODE: + STRLEN len; + char *ptr = SvPV(s, len); + try { + THIS->write((unsigned char *)ptr, len); + } + catch (const std::exception &e) { + croak(e.what()); + } + +void +Botan__Pipe::process_msg(s) + SV *s; + PREINIT: + ObjectInfo *THIS_oi; + CODE: + STRLEN len; + char *ptr = SvPV(s, len); + try { + THIS->process_msg((unsigned char *)ptr, len); + } + catch (const std::exception &e) { + croak(e.what()); + } + +Botan__u32bit +Botan__Pipe::remaining(msgno = Botan::Pipe::DEFAULT_MESSAGE) + Botan__u32bit msgno; + PREINIT: + ObjectInfo *THIS_oi; + CODE: + try { + RETVAL = THIS->remaining(msgno); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +SV * +Botan__Pipe::read(len = 0xFFFFFFFF, msgno = Botan::Pipe::DEFAULT_MESSAGE) + Botan__u32bit len; + Botan__u32bit msgno; + PREINIT: + ObjectInfo *THIS_oi; + CODE: + try { + if ( len > THIS->remaining(msgno) ) + len = THIS->remaining(msgno); + RETVAL = NEWSV(0, len); + SvPOK_on(RETVAL); + if ( len > 0 ) + SvCUR_set(RETVAL, THIS->read((unsigned char *)SvPVX(RETVAL), + len, msgno)); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +SV * +Botan__Pipe::peek(len = 0xFFFFFFFF, offset = 0, \ + msgno = Botan::Pipe::DEFAULT_MESSAGE) + Botan__u32bit len; + Botan__u32bit offset; + Botan__u32bit msgno; + PREINIT: + ObjectInfo *THIS_oi; + CODE: + try { + if ( len > THIS->remaining(msgno) ) + len = THIS->remaining(msgno); + RETVAL = NEWSV(0, len); + SvPOK_on(RETVAL); + if ( len > 0 ) + SvCUR_set(RETVAL, THIS->peek((unsigned char *)SvPVX(RETVAL), + len, offset, msgno)); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +Botan__u32bit +Botan__Pipe::default_msg() + PREINIT: + ObjectInfo *THIS_oi; + CODE: + try { + RETVAL = THIS->default_msg(); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +void +Botan__Pipe::set_default_msg(msgno) + Botan__u32bit msgno; + PREINIT: + ObjectInfo *THIS_oi; + CODE: + try { + THIS->set_default_msg(msgno); + } + catch (const std::exception &e) { + croak(e.what()); + } + +Botan__u32bit +Botan__Pipe::message_count() + PREINIT: + ObjectInfo *THIS_oi; + CODE: + try { + RETVAL = THIS->message_count(); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +bool +Botan__Pipe::end_of_data() + PREINIT: + ObjectInfo *THIS_oi; + CODE: + try { + RETVAL = THIS->end_of_data(); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +void +Botan__Pipe::start_msg() + PREINIT: + ObjectInfo *THIS_oi; + CODE: + try { + THIS->start_msg(); + } + catch (const std::exception &e) { + croak(e.what()); + } + +void +Botan__Pipe::end_msg() + PREINIT: + ObjectInfo *THIS_oi; + CODE: + try { + THIS->end_msg(); + } + catch (const std::exception &e) { + croak(e.what()); + } + +void +Botan__Pipe::reset() + PREINIT: + ObjectInfo *THIS_oi; + CODE: + try { + THIS->reset(); + } + catch (const std::exception &e) { + croak(e.what()); + } + + +# ========================== Botan::X509_Certificate ========================== + +MODULE = Botan PACKAGE = Botan::X509_Certificate + +Botan__X509_Certificate * +Botan__X509_Certificate::new(char *fn) + CODE: + try { + RETVAL = new Botan__X509_Certificate(fn); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +void +Botan__X509_Certificate::DESTROY() + CODE: + try { + delete THIS; + } + catch (const std::exception &e) { + croak(e.what()); + } + +unsigned int +Botan__X509_Certificate::x509_version() + CODE: + try { + RETVAL = THIS->x509_version(); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +char * +Botan__X509_Certificate::start_time() + CODE: + try { + RETVAL = const_cast(THIS->start_time().c_str()); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +char * +Botan__X509_Certificate::end_time() + CODE: + try { + RETVAL = const_cast(THIS->end_time().c_str()); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +char * +Botan__X509_Certificate::subject_info(char *info) + CODE: + try { + std::vector s = THIS->subject_info(info); + + if(s.size() > 0) + RETVAL = const_cast(s[0].c_str()); + else + RETVAL = "err"; + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +char * +Botan__X509_Certificate::issuer_info(char *info) + CODE: + try { + std::vector s = THIS->subject_info(info); + + if(s.size() > 0) + RETVAL = const_cast(s[0].c_str()); + else + RETVAL = "err"; + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +Botan__X509_DN * +Botan__X509_Certificate::subject_dn() + CODE: + try { + RETVAL = new Botan__X509_DN(THIS->subject_dn()); + } + catch (const std::exception &e) { + croak(e.what()); + } + char const * CLASS = "Botan::X509_DN"; + OUTPUT: + RETVAL + +Botan__X509_DN * +Botan__X509_Certificate::issuer_dn() + CODE: + try { + RETVAL = new Botan__X509_DN(THIS->issuer_dn()); + } + catch (const std::exception &e) { + croak(e.what()); + } + char const * CLASS = "Botan::X509_DN"; + OUTPUT: + RETVAL + + +# ============================== Botan::X509_DN ============================== + +MODULE = Botan PACKAGE = Botan::X509_DN + +Botan__X509_DN * +Botan__X509_DN::new() + CODE: + try { + RETVAL = new Botan__X509_DN(); + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL + +void +Botan__X509_DN::DESTROY() + CODE: + try { + delete THIS; + } + catch (const std::exception &e) { + croak(e.what()); + } + +AV * +Botan__X509_DN::get_attributes() + CODE: + try { + using namespace std; + using namespace Botan; + + typedef multimap::const_iterator rdn_iter; + + multimap const &atrmmap = THIS->get_attributes(); + RETVAL = newAV(); + for(rdn_iter i = atrmmap.begin(); i != atrmmap.end(); i++) + { + string const &atr = i->first.as_string(); + string const &val = i->second; + av_push(RETVAL, newSVpvn(atr.c_str(), atr.length())); + av_push(RETVAL, newSVpvn(val.c_str(), val.length())); + } + } + catch (const std::exception &e) { + croak(e.what()); + } + OUTPUT: + RETVAL diff --git a/src/wrap/perl-xs/Changes b/src/wrap/perl-xs/Changes new file mode 100644 index 000000000..5f32b0c63 --- /dev/null +++ b/src/wrap/perl-xs/Changes @@ -0,0 +1,4 @@ +Revision history for Perl extension to Botan. + +0.01 Fri, 20 Feb 2004 15:10:50 +0100 + - first version diff --git a/src/wrap/perl-xs/MANIFEST b/src/wrap/perl-xs/MANIFEST new file mode 100644 index 000000000..b9d8454d6 --- /dev/null +++ b/src/wrap/perl-xs/MANIFEST @@ -0,0 +1,15 @@ +Botan.pm +Botan.xs +Changes +MANIFEST +Makefile.PL +data/ca.cert.der +data/ca.cert.pem +t/base64.t +t/filt.t +t/hex.t +t/oid.t +t/pipe.t +t/testutl.pl +t/x509cert.t +typemap diff --git a/src/wrap/perl-xs/Makefile.PL b/src/wrap/perl-xs/Makefile.PL new file mode 100644 index 000000000..d35c99168 --- /dev/null +++ b/src/wrap/perl-xs/Makefile.PL @@ -0,0 +1,29 @@ +use ExtUtils::MakeMaker; + +my ($cc, $cflags, $lids); +if ( $^O eq 'MSWin32' ) +{ +# $cflags = ''; +# $libs = ':nosearch -lgdi32 -llibeay32'; +} +else +{ + $cc = 'g++'; + $cflags = '-fexceptions ' . qx( botan-config --cflags ); + $libs = qx( botan-config --libs ); +} + +WriteMakefile( + 'NAME' => 'Botan', + 'DISTNAME' => 'Botan-XS', + 'VERSION_FROM' => 'Botan.pm', # finds $VERSION + 'XSOPT' => '-C++', + 'CC' => $cc, + 'LD' => '$(CC)', + 'CCFLAGS' => $cflags, + 'LIBS' => [ $libs ], + 'OPTIMIZE' => '-g', +# 'clean' => { +# 'FILES' => 'neco.p12 rnd', +# }, +); diff --git a/src/wrap/perl-xs/data/ca.cert.der b/src/wrap/perl-xs/data/ca.cert.der new file mode 100644 index 000000000..d6ed8aeaf Binary files /dev/null and b/src/wrap/perl-xs/data/ca.cert.der differ diff --git a/src/wrap/perl-xs/data/ca.cert.pem b/src/wrap/perl-xs/data/ca.cert.pem new file mode 100644 index 000000000..012913b26 --- /dev/null +++ b/src/wrap/perl-xs/data/ca.cert.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxDCCAi2gAwIBAgIBEjANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJDWjER +MA8GA1UEChMISUNaIGEucy4xGDAWBgNVBAMTD1Rlc3QgcHJpbWFyeSBDQTEWMBQG +CSqGSIb3DQEJARYHY2FAaS5jejAeFw0wMDA4MjAyMTQ4MDBaFw0wMjA4MTAyMTQ4 +MDBaME8xCzAJBgNVBAYTAkNaMREwDwYDVQQKEwhJQ1ogYS5zLjEVMBMGA1UEAxMM +VGVzdCBzaWduIENBMRYwFAYJKoZIhvcNAQkBFgdjYUBpLmN6MIGfMA0GCSqGSIb3 +DQEBAQUAA4GNADCBiQKBgQCo2GReNqwU0/8bZZua5hgYaVHvD9QAmfILNXD25jRk +C8lqe5m/GzbmftSUso5HyUy1t+qzvRDTmxK8uRn0P00Mqj9gjwF8PGQvZE/FrDF7 +rta9GCcH4n2GfQ0iexlhRZW44AfOD4HCgq38Z0bzBclsvUslBWe1AT+S5+chZ5Wb +UwIDAQABo4GsMIGpMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLXqc1b1DOfGehii +k4Z+/ih9BYZmMHoGA1UdIwRzMHGAFL7x2ToS4RDAbDJu4fHnzzGjfGmgoVakVDBS +MQswCQYDVQQGEwJDWjERMA8GA1UEChMISUNaIGEucy4xGDAWBgNVBAMTD1Rlc3Qg +cHJpbWFyeSBDQTEWMBQGCSqGSIb3DQEJARYHY2FAaS5jeoIBADANBgkqhkiG9w0B +AQUFAAOBgQAKD9ku9kKXUGhSw8KuWJXTnEsIUzDtgmREBEUOtEvGfU45vogWN7ZL +9fQZ1deywN4RJ4T5ZTTcCTPodOdG+IXLJ+uPn/m9iQ/D86c3GKS3yx4JNAn5PH1m +qLsMYVjbFD2uREZQsqbg3RT6L1D8+oK0pN379u3bD6oJx/qa7+F4Jg== +-----END CERTIFICATE----- diff --git a/src/wrap/perl-xs/t/base64.t b/src/wrap/perl-xs/t/base64.t new file mode 100644 index 000000000..f0973e13e --- /dev/null +++ b/src/wrap/perl-xs/t/base64.t @@ -0,0 +1,273 @@ +# vim: set ft=perl: +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl test.pl' + +######################### We start with some black magic to print on failure. + +# Change 1..1 below to 1..last_test_to_print . +# (It may become useful if the test is moved to ./t subdirectory.) + +BEGIN { $| = 1; print "1..24\n"; } +END { print "not ok 1\n" unless $loaded; } + +require 't/testutl.pl'; +use Botan; + +$loaded = 1; +print "ok 1\n"; + +######################### End of black magic. + +# Insert your test code below (better if it prints "ok 13" +# (correspondingly "not ok 13") depending on the success of chunk 13 +# of the test code): + +use strict; + +# Data prep + +my $botan_lic_b64_garbage = <<'EOF'; +Q29weXJpZ2h0IChDKSAxOTk5LTIwMDQgVGhlIEJvdGFuIFByb2plY3QuIEFsbCBy__ì¹ +aWdodHMgcmVzZXJ2ZWQuCgpSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJj$$*: +ZSBhbmQgYmluYXJ5IGZvcm1zLCBmb3IgYW55IHVzZSwgd2l0aCBvciB3aXRob3V0!@#$%^&*( +Cm1vZGlmaWNhdGlvbiwgaXMgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZv[\] +bGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6CgoxLiBSZWRpc3RyaWJ1dGlvbnMg'~` +b2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBu() +b3RpY2UsIHRoaXMKbGlzdCBvZiBjb25kaXRpb25zLCBhbmQgdGhlIGZvbGxvd2lu +ZyBkaXNjbGFpbWVyLgoKMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3Jt +IG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAp0aGlz +IGxpc3Qgb2YgY29uZGl0aW9ucywgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1l +ciBpbiB0aGUgZG9jdW1lbnRhdGlvbgphbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHBy_,^ +b3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KClRISVMgU09GVFdBUkUgSVMg{|}~~~~~ +UFJPVklERUQgQlkgVEhFIEFVVEhPUihTKSAiQVMgSVMiIEFORCBBTlkgRVhQUkVT~~~~~~~~ +UyBPUiBJTVBMSUVECldBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1J__:; +VEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GCk1FUkNIQU5UQUJJTElU +WSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UsIEFSRSBESVND +TEFJTUVELgoKSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUihTKSBPUiBDT05U +UklCVVRPUihTKSBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsCklORElSRUNULCBJ +TkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwg +REFNQUdFUyAoSU5DTFVESU5HLApCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVN +RU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNF +LApEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhP +V0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GCkxJQUJJTElUWSwgV0hF +VEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5D +TFVESU5HIE5FR0xJR0VOQ0UKT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBX +QVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRgpBRFZJ +U0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4K +EOF + +my $botan_lic_b64_ws = $botan_lic_b64_garbage; +$botan_lic_b64_ws =~ s/[^A-Za-z0-9+\/= \n]//g; + +my $botan_lic_b64 = $botan_lic_b64_ws; +$botan_lic_b64 =~ s/[ \n]//g; + + +my $botan_lic = <<'EOF'; +Copyright (C) 1999-2004 The Botan Project. All rights reserved. + +Redistribution and use in source and binary forms, for any use, with or without +modification, is permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions, and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions, and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. + +IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +EOF + + +# Decoder... + +my $f; + +eval { $f = Botan::Base64_Decoder->new(&Botan::NONE); }; +print "not " if $@ || !defined $f; +print "ok 2\n"; + +my $dec; +eval { $dec = Botan::Pipe->new($f); }; +print "not " if $@ || !defined $dec; +print "ok 3\n"; + +eval { $f = Botan::Base64_Decoder->new(&Botan::IGNORE_WS); }; +print "not " if $@ || !defined $f; +print "ok 4\n"; + +my $dec_is; +eval { $dec_is = Botan::Pipe->new($f); }; +print "not " if $@ || !defined $dec_is; +print "ok 5\n"; + +eval { $f = Botan::Base64_Decoder->new(&Botan::FULL_CHECK); }; +print "not " if $@ || !defined $f; +print "ok 6\n"; + +my $dec_fc; +eval { $dec_fc = Botan::Pipe->new($f); }; +print "not " if $@ || !defined $dec_fc; +print "ok 7\n"; + + +# Testing clean base64 input + +my $data; + +undef $data; +eval { + $dec->process_msg($botan_lic_b64); + $data = $dec->read(); +}; + +print "not " if $@ || $data ne $botan_lic; +print "ok 8\n"; + +undef $data; +eval { + $dec_is->process_msg($botan_lic_b64); + $data = $dec_is->read(); +}; + +print "not " if $@ || $data ne $botan_lic; +print "ok 9\n"; + +undef $data; +eval { + $dec_fc->process_msg($botan_lic_b64); + $data = $dec_fc->read(); +}; + +print "not " if $@ || $data ne $botan_lic; +print "ok 10\n"; + + +# Testing base64 input with whitespaces + +undef $data; +eval { + $dec->process_msg($botan_lic_b64_ws); + $dec->set_default_msg(1); + $data = $dec->read(); +}; + +print "not " if $@ || $data ne $botan_lic; +print "ok 11\n"; + +undef $data; +eval { + $dec_is->process_msg($botan_lic_b64_ws); + $dec_is->set_default_msg(1); + $data = $dec_is->read(); +}; + +print "not " if $@ || $data ne $botan_lic; +print "ok 12\n"; + +undef $data; +eval { + $dec_fc->process_msg($botan_lic_b64_ws); + $dec_fc->set_default_msg(1); + $data = $dec_fc->read(); +}; + +print "not " unless $@ && !defined $data; +print "ok 13\n"; + + +# Testing base64 input with garbage + +undef $data; +eval { + $dec->process_msg($botan_lic_b64_garbage); + $dec->set_default_msg(2); + $data = $dec->read(); +}; + +print "not " if $@ || $data ne $botan_lic; +print "ok 14\n"; + +undef $data; +eval { + $dec_is->process_msg($botan_lic_b64_garbage); + $dec_is->set_default_msg(2); + $data = $dec_is->read(); +}; + +print "not " unless $@ && !defined $data; +print "ok 15\n"; + +undef $data; +eval { + $dec_fc->process_msg($botan_lic_b64_garbage); + $dec_fc->set_default_msg(2); + $data = $dec_fc->read(); +}; + +print "not " unless $@ && !defined $data; +print "ok 16\n"; + + +# Encoder... + +eval { $f = Botan::Base64_Encoder->new(); }; +print "not " if $@ || !defined $f; +print "ok 17\n"; + +my $enc; +eval { $enc = Botan::Pipe->new($f); }; +print "not " if $@ || !defined $enc; +print "ok 18\n"; + +eval { $f = Botan::Base64_Encoder->new(1, 5); }; +print "not " if $@ || !defined $f; +print "ok 19\n"; + +my $enc2; +eval { $enc2 = Botan::Pipe->new($f); }; +print "not " if $@ || !defined $enc2; +print "ok 20\n"; + +undef $data; +eval { + $enc->process_msg("Hello\n"); + $data = $enc->read(); +}; +print "not " if $@ || $data ne "SGVsbG8K"; +print "ok 21\n"; + +undef $data; +eval { + $enc2->process_msg("Hello\n"); + $data = $enc2->read(); +}; +print "not " if $@ || $data ne "SGVsb\nG8K\n"; +print "ok 22\n"; + + +# Encoder with decoder... + +my $p; +eval { + $p = Botan::Pipe->new( + Botan::Base64_Encoder->new(), + Botan::Base64_Decoder->new(), + ); +}; +print "not " if $@ || !defined $p; +print "ok 23\n"; + +print "not " unless random_message_ok($p); +print "ok 24\n"; diff --git a/src/wrap/perl-xs/t/filt.t b/src/wrap/perl-xs/t/filt.t new file mode 100644 index 000000000..2a7b4c8ba --- /dev/null +++ b/src/wrap/perl-xs/t/filt.t @@ -0,0 +1,56 @@ +# vim: set ft=perl: +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl test.pl' + +######################### We start with some black magic to print on failure. + +# Change 1..1 below to 1..last_test_to_print . +# (It may become useful if the test is moved to ./t subdirectory.) + +BEGIN { $| = 1; print "1..5\n"; } +END { print "not ok 1\n" unless $loaded; } + +use Botan; + +$loaded = 1; +print "ok 1\n"; + +######################### End of black magic. + +# Insert your test code below (better if it prints "ok 13" +# (correspondingly "not ok 13") depending on the success of chunk 13 +# of the test code): + +use strict; + +my $pipe = Botan::Pipe->new(Botan::Hex_Encoder->new()); + +print "not " unless $pipe; +print "ok 2\n"; + +$pipe->process_msg('FOO'); + +print "not " if $pipe->read() ne '464F4F'; +print "ok 3\n"; + +$pipe = Botan::Pipe->new(Botan::Hex_Encoder->new(0, 0, 1)); + +print "not " unless $pipe; +print "ok 4\n"; + +$pipe->process_msg('FOO'); + +print "not " if $pipe->read() ne '464f4f'; +print "ok 5\n"; + + + + + + +#my $pipe = Botan::Pipe->new(Botan::Base64_Encoder->new()); +#$pipe->process_msg('FOO'); +# +#print "not " if $pipe->read() ne 'Rk9P'; +#print "ok 4\n"; + diff --git a/src/wrap/perl-xs/t/hex.t b/src/wrap/perl-xs/t/hex.t new file mode 100644 index 000000000..6f447b25c --- /dev/null +++ b/src/wrap/perl-xs/t/hex.t @@ -0,0 +1,256 @@ +# vim: set ft=perl: +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl test.pl' + +######################### We start with some black magic to print on failure. + +# Change 1..1 below to 1..last_test_to_print . +# (It may become useful if the test is moved to ./t subdirectory.) + +BEGIN { $| = 1; print "1..24\n"; } +END { print "not ok 1\n" unless $loaded; } + +require 't/testutl.pl'; +use Botan; + +$loaded = 1; +print "ok 1\n"; + +######################### End of black magic. + +# Insert your test code below (better if it prints "ok 13" +# (correspondingly "not ok 13") depending on the success of chunk 13 +# of the test code): + +use strict; + +# Data prep + +my ($hex, $hex_ws, $hex_garbage); +while ( $_ = ) +{ + $hex_garbage .= $_; + s/[^[:xdigit:][:space:]]//g; + $hex_ws .= $_; + s/[^[:xdigit:]]//g; + $hex .= $_; +} +my $data_test = pack("H*", $hex); + +# Decoder... + +my $f; + +eval { $f = Botan::Hex_Decoder->new(&Botan::NONE); }; +print "not " if $@ || !defined $f; +print "ok 2\n"; + +my $dec; +eval { $dec = Botan::Pipe->new($f); }; +print "not " if $@ || !defined $dec; +print "ok 3\n"; + +eval { $f = Botan::Hex_Decoder->new(&Botan::IGNORE_WS); }; +print "not " if $@ || !defined $f; +print "ok 4\n"; + +my $dec_is; +eval { $dec_is = Botan::Pipe->new($f); }; +print "not " if $@ || !defined $dec_is; +print "ok 5\n"; + +eval { $f = Botan::Hex_Decoder->new(&Botan::FULL_CHECK); }; +print "not " if $@ || !defined $f; +print "ok 6\n"; + +my $dec_fc; +eval { $dec_fc = Botan::Pipe->new($f); }; +print "not " if $@ || !defined $dec_fc; +print "ok 7\n"; + + +# Testing clean hexadecimal input + +my $data; + +undef $data; +eval { + $dec->process_msg($hex); + $data = $dec->read(); +}; + +print "not " if $@ || $data ne $data_test; +print "ok 8\n"; + +undef $data; +eval { + $dec_is->process_msg($hex); + $data = $dec_is->read(); +}; + +print "not " if $@ || $data ne $data_test; +print "ok 9\n"; + +undef $data; +eval { + $dec_fc->process_msg($hex); + $data = $dec_fc->read(); +}; + +print "not " if $@ || $data ne $data_test; +print "ok 10\n"; + + +# Testing hexadecimal input with whitespaces + +undef $data; +eval { + $dec->process_msg($hex_ws); + $dec->set_default_msg(1); + $data = $dec->read(); +}; + +print "not " if $@ || $data ne $data_test; +print "ok 11\n"; + +undef $data; +eval { + $dec_is->process_msg($hex_ws); + $dec_is->set_default_msg(1); + $data = $dec_is->read(); +}; + +print "not " if $@ || $data ne $data_test; +print "ok 12\n"; + +undef $data; +eval { + $dec_fc->process_msg($hex_ws); + $dec_fc->set_default_msg(1); + $data = $dec_fc->read(); +}; + +print "not " unless $@ && !defined $data; +print "ok 13\n"; + + +# Testing hexadecimal input with garbage + +undef $data; +eval { + $dec->process_msg($hex_garbage); + $dec->set_default_msg(2); + $data = $dec->read(); +}; + +print "not " if $@ || $data ne $data_test; +print "ok 14\n"; + +undef $data; +eval { + $dec_is->process_msg($hex_garbage); + $dec_is->set_default_msg(2); + $data = $dec_is->read(); +}; + +print "not " unless $@ && !defined $data; +print "ok 15\n"; + +undef $data; +eval { + $dec_fc->process_msg($hex_garbage); + $dec_fc->set_default_msg(2); + $data = $dec_fc->read(); +}; + +print "not " unless $@ && !defined $data; +print "ok 16\n"; + + +# Encoder... + +eval { $f = Botan::Hex_Encoder->new(); }; +print "not " if $@ || !defined $f; +print "ok 17\n"; + +my $enc; +eval { $enc = Botan::Pipe->new($f); }; +print "not " if $@ || !defined $enc; +print "ok 18\n"; + +eval { $f = Botan::Hex_Encoder->new(1, 5, 1); }; +print "not " if $@ || !defined $f; +print "ok 19\n"; + +my $enc2; +eval { $enc2 = Botan::Pipe->new($f); }; +print "not " if $@ || !defined $enc2; +print "ok 20\n"; + +undef $data; +eval { + $enc->process_msg("Hello\n"); + $data = $enc->read(); +}; +print "not " if $@ || $data ne "48656C6C6F0A"; +print "ok 21\n"; + +undef $data; +eval { + $enc2->process_msg("Hello\n"); + $data = $enc2->read(); +}; +print "not " if $@ || $data ne "48656\nc6c6f\n0a\n"; +print "ok 22\n"; + + +# Encoder with decoder... + +my $p; +eval { + $p = Botan::Pipe->new( + Botan::Hex_Encoder->new(), + Botan::Hex_Decoder->new(), + ); +}; +print "not " if $@ || !defined $p; +print "ok 23\n"; + +print "not " unless random_message_ok($p); +print "ok 24\n"; + + + +__DATA__ +cb13 4a4d 7522 1fd3 c6f6 7786 d04b 3043 ..JMu"....w..K.. +4552 4bcf 4d2b 9d71 0cfe 4d6a 1caf bcfd .RK.M+.q..Mj.... +8f91 6151 ff85 e900 7e6a bafc 15e9 ae51 ...Q....~j.....Q +b14b 7210 bb40 5958 2b82 d49e b808 68a5 .Kr..@YX+.....h. +7945 9dec f686 9b98 989e 826d 8088 6ee7 y..........m..n. +d066 1eac 8c34 c461 bb54 7726 87ab d681 .........Tw&.... +a0be 52e5 1128 0cf2 759e cb2d e690 4ed9 ..R..(..u..-..N. +7e88 bda7 2523 4a0f 185a 02b1 f898 fc41 ~...%#J..Z...... +dd48 fa87 945d 7611 b8c9 a50a 2de2 b670 .H...]v.....-..p +0056 c8be 2cbb e7d0 1e70 4a3d 79f0 dce9 .V..,....pJ=y... +b57f 154b 2b3a db73 f086 de11 9f3e 1641 ...K+:.s.....>.. +3a28 8b9b bb0f 682b 80db b791 89e0 62c0 :(....h+........ +7204 db97 5432 2eb0 a04e f38e 809f 7223 r...T....N....r# +912e e552 1452 6dd2 e09f dd06 c715 7c1a ...R.Rm.......|. +fe3d d6cc b6d0 a17a 27d7 4327 4e43 8af3 .=.....z'..'N... +6eb5 e9f8 bfe9 34c3 6636 8243 358f 966d n..............m +7d87 d17b 5c37 6acb 4972 f4ec 6806 bbde }..{\.j.Ir..h... +2689 a019 a9e2 4101 7fe2 de72 bc03 eb5e &..........r...^ +b699 2d6b f8cd a08e 6e01 edfc a81a 94b6 ..-k....n....... +9073 15fb efb2 c8d9 9f85 6633 85f1 e9d0 .s.............. +20ce 578b ab9d 2e51 b947 69bf fba5 82c6 .W....Q.Gi..... +2ed0 dd36 d679 a399 7db3 8a0d cdef 0eda .....y..}....... +e761 e7f1 5b17 3f67 0c83 215a eddf 9d2a ....[.?g..!Z...* +5e70 0a77 c92e 94e1 a82b fd7c f10a 894f ^p.w.....+.|...O +2955 f0e8 7398 f409 2040 b797 da03 a5a6 )U..s... @...... +7ba4 c3c9 2659 b9f7 6a56 e17a b481 983f {...&Y..jV.z...? +00ed 3cc8 5a22 ad5c b6e0 3566 d717 35a6 ..<.Z".\........ +1523 4104 de63 477e fd24 68e5 e816 98df .#....G~.$h..... +1747 417e db72 a76a be5b b9dc 3dfb 2d05 .G.~.r.j.[..=.-. +d27f e597 eafc 9a29 15c5 792d 9c88 9aea .......)..y-.... +485e e431 96c3 7723 da6d 28b2 477a fd12 H^....w#.m(.Gz.. +e645 5dcd 7d5a d8b4 7acc 10b2 b41a e11d ..].}Z..z....... diff --git a/src/wrap/perl-xs/t/oid.t b/src/wrap/perl-xs/t/oid.t new file mode 100644 index 000000000..66204541f --- /dev/null +++ b/src/wrap/perl-xs/t/oid.t @@ -0,0 +1,45 @@ +# vim: set ft=perl: +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl test.pl' + +######################### We start with some black magic to print on failure. + +# Change 1..1 below to 1..last_test_to_print . +# (It may become useful if the test is moved to ./t subdirectory.) + +BEGIN { $| = 1; print "1..6\n"; } +END { print "not ok 1\n" unless $loaded; } + +use Botan; + +$loaded = 1; +print "ok 1\n"; + +######################### End of black magic. + +# Insert your test code below (better if it prints "ok 13" +# (correspondingly "not ok 13") depending on the success of chunk 13 +# of the test code): + +use strict; + +print "not " unless Botan::OIDS::have_oid('X520.CommonName'); +print "ok 2\n"; + +my $oid_c = Botan::OID->new('2.5.4.3'); +print "not " if Botan::OIDS::lookup_by_oid($oid_c) ne 'X520.CommonName'; +print "ok 3\n"; + +my $oid_x = Botan::OIDS::lookup_by_name('X520.CommonName'); +print "not " if $oid_x->as_string() ne '2.5.4.3'; +print "ok 4\n"; + +my $oid_foo_num = '1.2.3.4.5.6.7.8.9.10.11.12.13.14.15'; +my $oid_foo = Botan::OID->new($oid_foo_num); +print "not " if Botan::OIDS::lookup_by_oid($oid_foo) ne $oid_foo_num; +print "ok 5\n"; + +Botan::OIDS::add_oid($oid_foo, 'Zito.Foo'); + +print "not " if Botan::OIDS::lookup_by_oid($oid_foo) ne 'Zito.Foo'; +print "ok 6\n"; diff --git a/src/wrap/perl-xs/t/pipe.t b/src/wrap/perl-xs/t/pipe.t new file mode 100644 index 000000000..f850d8519 --- /dev/null +++ b/src/wrap/perl-xs/t/pipe.t @@ -0,0 +1,98 @@ +# vim: set ft=perl: +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl test.pl' + +######################### We start with some black magic to print on failure. + +# Change 1..1 below to 1..last_test_to_print . +# (It may become useful if the test is moved to ./t subdirectory.) + +BEGIN { $| = 1; print "1..20\n"; } +END { print "not ok 1\n" unless $loaded; } + +use Botan; + +$loaded = 1; +print "ok 1\n"; + +######################### End of black magic. + +# Insert your test code below (better if it prints "ok 13" +# (correspondingly "not ok 13") depending on the success of chunk 13 +# of the test code): + +use strict; + +my $pipe = Botan::Pipe->new(); + +print "not " unless $pipe; +print "ok 2\n"; + +$pipe->start_msg(); +$pipe->write('Hello world'); +$pipe->end_msg(); + +print "not " if $pipe->message_count() != 1; +print "ok 3\n"; + +print "not " if $pipe->remaining() != 11; +print "ok 4\n"; + +print "not " if $pipe->end_of_data(); +print "ok 5\n"; + +print "not " if $pipe->read() ne 'Hello world'; +print "ok 6\n"; + +print "not " if $pipe->remaining() != 0; +print "ok 7\n"; + +print "not " unless $pipe->end_of_data(); +print "ok 8\n"; + +$pipe->process_msg('Hello world'); + +print "not " if $pipe->message_count() != 2; +print "ok 9\n"; + +my $msg_num = $pipe->message_count() -1; + +print "not " if $pipe->read(5, $msg_num) ne 'Hello'; +print "ok 10\n"; + +print "not " if $pipe->read(6, $msg_num) ne ' world'; +print "ok 11\n"; + +print "not " if $pipe->remaining() != 0; +print "ok 12\n"; + +print "not " unless $pipe->end_of_data(); +print "ok 13\n"; + +$pipe->process_msg("The\0string\0with\0null\0chars\0"); +$msg_num = $pipe->message_count() -1; + +print "not " if $pipe->read(80, $msg_num) ne "The\0string\0with\0null\0chars\0"; +print "ok 14\n"; + +$pipe->process_msg('FOO BAR'); +$pipe->set_default_msg($pipe->message_count() -1); + +print "not " if $pipe->peek(3) ne 'FOO'; +print "ok 15\n"; + +print "not " if $pipe->peek(3, 4) ne 'BAR'; +print "ok 16\n"; + +print "not " if $pipe->peek() ne 'FOO BAR'; +print "ok 17\n"; + +print "not " if $pipe->read() ne 'FOO BAR'; +print "ok 18\n"; + +print "not " if $pipe->remaining() != 0; +print "ok 19\n"; + +print "not " unless $pipe->end_of_data(); +print "ok 20\n"; + diff --git a/src/wrap/perl-xs/t/testutl.pl b/src/wrap/perl-xs/t/testutl.pl new file mode 100644 index 000000000..add6f6a45 --- /dev/null +++ b/src/wrap/perl-xs/t/testutl.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl + +sub random_message_ok +{ + my ($pipe, $iter, $chunkmax) = @_; + $iter = 100 unless defined $iter; + $chunkmax = 300 unless defined $chunkmax; + eval { + my $input = ''; + $pipe->start_msg(); + for(my $i = 0; $i < $iter; $i++) + { + my $chunk = ''; + my $chunklen = int(rand($chunkmax)); + $chunk .= pack("C", int(rand(256))) while $chunklen--; + $input .= $chunk; + $pipe->write($chunk); + } + $pipe->end_msg(); + my $msg_num = $pipe->message_count() -1; + my $output = $pipe->read(0xFFFFFFFF, $msg_num); + return $input eq $output; + }; +} + +1; diff --git a/src/wrap/perl-xs/t/x509cert.t b/src/wrap/perl-xs/t/x509cert.t new file mode 100644 index 000000000..2a943aeac --- /dev/null +++ b/src/wrap/perl-xs/t/x509cert.t @@ -0,0 +1,42 @@ +# vim: set ft=perl: +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl test.pl' + +######################### We start with some black magic to print on failure. + +# Change 1..1 below to 1..last_test_to_print . +# (It may become useful if the test is moved to ./t subdirectory.) + +BEGIN { $| = 1; print "1..4\n"; } +END { print "not ok 1\n" unless $loaded; } + +use Botan; + +$loaded = 1; +print "ok 1\n"; + +######################### End of black magic. + +# Insert your test code below (better if it prints "ok 13" +# (correspondingly "not ok 13") depending on the success of chunk 13 +# of the test code): + +use strict; + +my $cert = Botan::X509_Certificate->new('data/ca.cert.der'); + +print "not " if $cert->x509_version() != 3; +print "ok 2\n"; + +print "not " if $cert->start_time() ne '2000/8/20 21:48:00 UTC'; +print "ok 3\n"; + +print "not " if $cert->end_time() ne '2002/8/10 21:48:00 UTC'; +print "ok 4\n"; + +#my $subject = $cert->subject_dn()->get_attributes(); +#print STDERR "subject=", join(',', @{$subject}), "\n"; +# +#my $issuer = $cert->issuer_dn()->get_attributes(); +#print STDERR "issuer=", join(',', @{$issuer}), "\n"; +# diff --git a/src/wrap/perl-xs/typemap b/src/wrap/perl-xs/typemap new file mode 100644 index 000000000..d7403d40d --- /dev/null +++ b/src/wrap/perl-xs/typemap @@ -0,0 +1,62 @@ +TYPEMAP + +Botan__ASN1_String * O_OBJECT +Botan__AlgorithmIdentifier * O_OBJECT +Botan__AlternativeName * O_OBJECT +Botan__Attribute * O_OBJECT +Botan__Base64_Decoder * O_EXTOBJECT +Botan__Base64_Encoder * O_EXTOBJECT +Botan__Chain * O_EXTOBJECT +Botan__Extension * O_OBJECT +Botan__Filter * O_EXTOBJECT +Botan__Fork * O_EXTOBJECT +Botan__Hex_Decoder * O_EXTOBJECT +Botan__Hex_Encoder * O_EXTOBJECT +Botan__OID * O_OBJECT +Botan__Pipe * O_OBJECT +Botan__X509_Certificate * O_OBJECT +Botan__X509_DN * O_OBJECT +Botan__X509_Time * O_OBJECT +Botan__u32bit T_UV + + +###################################################################### +OUTPUT + +# The Perl object is blessed into 'CLASS', which should be a +# char* having the name of the package for the blessing. +O_OBJECT + sv_setref_pv($arg, CLASS, (void*)$var); + +O_EXTOBJECT + sv_setref_pv($arg, CLASS, (void*)$var); + sv_magic(SvRV($arg), 0, '~', (char *)&oi_init, sizeof(oi_init)); + + +###################################################################### +INPUT + +O_OBJECT + if ( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) ) + $var = ($type)SvIV((SV*)SvRV( $arg )); + else + croak(\"${Package}::$func_name() -- \" + \"$var is not a blessed SV reference\"); + +# The pointer variable "ObjectInfo *${var}_oi;" must be declared +# in PREINIT section. I don't know how to emit this declaration safely here. +O_EXTOBJECT + if ( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) ) + $var = ($type)SvIV((SV*)SvRV($arg)); + else + croak(\"${Package}::$func_name() -- \" + \"$var is not a blessed SV reference\"); + { + MAGIC *mg = mg_find(SvRV($arg), '~'); + if ( mg == 0 + || mg->mg_len != sizeof(ObjectInfo) + || *(I32 *)(mg->mg_ptr) != ObjectInfo::SIGNVAL ) + croak(\"${Package}::$func_name() -- \" + \"private magic data for $var invalid\"); + ${var}_oi = (ObjectInfo *)(mg->mg_ptr); + } diff --git a/wrappers/perl-xs/Botan.pm b/wrappers/perl-xs/Botan.pm deleted file mode 100644 index ac4ad91fb..000000000 --- a/wrappers/perl-xs/Botan.pm +++ /dev/null @@ -1,117 +0,0 @@ -package Botan; - -use strict; -use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $AUTOLOAD); - -require DynaLoader; -require AutoLoader; -use Carp; - -@ISA = qw(DynaLoader); -$VERSION = '0.01'; - -@EXPORT_OK = qw( - NONE - IGNORE_WS - FULL_CHECK -); - -%EXPORT_TAGS = ( - 'all' => [ @EXPORT_OK ], - 'decoder_checking' => [ qw( - NONE - IGNORE_WS - FULL_CHECK - )], - -); - - -sub AUTOLOAD -{ - # This AUTOLOAD is used to 'autoload' constants from the constant() - # XS function. If a constant is not found then control is passed - # to the AUTOLOAD in AutoLoader. - - my $constname = $AUTOLOAD; - $constname =~ s/.*:://; - croak '& not defined' if $constname eq 'constant'; -# my $val = constant($constname, @_ ? $_[0] : 0); - my $val = constant($constname); - if ($! != 0) { - if ( $! =~ /Invalid/ ) - { - $AutoLoader::AUTOLOAD = $AUTOLOAD; - goto &AutoLoader::AUTOLOAD; - } - else - { - croak "Your vendor has not defined Botan symbol $constname"; - } - } - no strict 'refs'; - *$AUTOLOAD = sub { $val }; - goto &$AUTOLOAD; -} - - -bootstrap Botan $VERSION; - -# to setup inheritance... - -package Botan::Filter; -use vars qw(@ISA); -@ISA = qw(); - -package Botan::Chain; -use vars qw(@ISA); -@ISA = qw( Botan::Filter ); - -package Botan::Fork; -use vars qw(@ISA); -@ISA = qw( Botan::Filter ); - -package Botan::Hex_Encoder; -use vars qw(@ISA); -@ISA = qw( Botan::Filter ); - -package Botan::Hex_Decoder; -use vars qw(@ISA); -@ISA = qw( Botan::Filter ); - -package Botan::Base64_Decoder; -use vars qw(@ISA); -@ISA = qw( Botan::Filter ); - -package Botan::Base64_Encoder; -use vars qw(@ISA); -@ISA = qw( Botan::Filter ); - - -package Botan; - -1; -__END__ - -=head1 NAME - -Botan - Perl extension for access to Botan ... - -=head1 SYNOPSIS - - use Botan; - blah blah blah - -=head1 DESCRIPTION - -Blah blah blah. - -=head1 AUTHOR - -Vaclav Ovsik - -=head1 SEE ALSO - -Bla - -=cut diff --git a/wrappers/perl-xs/Botan.xs b/wrappers/perl-xs/Botan.xs deleted file mode 100644 index ded129d2e..000000000 --- a/wrappers/perl-xs/Botan.xs +++ /dev/null @@ -1,829 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - -#include "EXTERN.h" -#include "perl.h" -#include "XSUB.h" - -#ifdef __cplusplus -} -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* xsubpp converts ':' to '_' in typemap. We create our types without ':' */ - -typedef Botan::ASN1_String Botan__ASN1_String; -typedef Botan::AlgorithmIdentifier Botan__AlgorithmIdentifier; -typedef Botan::AlternativeName Botan__AlternativeName; -typedef Botan::Attribute Botan__Attribute; -typedef Botan::Base64_Decoder Botan__Base64_Decoder; -typedef Botan::Base64_Encoder Botan__Base64_Encoder; -typedef Botan::Chain Botan__Chain; -typedef Botan::Certificate_Extension Botan__Extension; -typedef Botan::Filter Botan__Filter; -typedef Botan::Fork Botan__Fork; -typedef Botan::Hex_Decoder Botan__Hex_Decoder; -typedef Botan::Hex_Encoder Botan__Hex_Encoder; -typedef Botan::OID Botan__OID; -typedef Botan::Pipe Botan__Pipe; -typedef Botan::X509_Certificate Botan__X509_Certificate; -typedef Botan::X509_DN Botan__X509_DN; -typedef Botan::X509_Time Botan__X509_Time; -typedef Botan::u32bit Botan__u32bit; - - -/* Types to keep track of destruction C++ objects passed - * into other objects... - * An Botan object is deleted by his parent object into which is passed, - * e.g. some Filter is deleted when his Pipe is destructed. We must - * track this and not to delete object again in Perls destructor. - */ - -class ObjectInfo -{ -private: - I32 d_signature; - bool d_del; -public: - static I32 const SIGNVAL = 0x696a626f; - ObjectInfo() : d_signature(SIGNVAL), - d_del(true) {}; - ~ObjectInfo() {}; - void set_delete(bool del = true) { d_del = del; }; - void set_delete_no() { set_delete(false); }; - void set_delete_yes() { set_delete(true); }; - bool should_delete() const { return d_del; }; -}; - -/* Constant object in initial state - template */ - -ObjectInfo const oi_init; - - -/* Botan library initializer ... */ - -Botan::LibraryInitializer botan_init; - - - -/*============================================================================*/ - -MODULE = Botan PACKAGE = Botan - -PROTOTYPES: ENABLE - -void -constant(char *name) - CODE: - using namespace Botan; - errno = 0; - switch (name[0]) - { - case 'F': - if ( strEQ(name, "FULL_CHECK") ) - XSRETURN_IV( FULL_CHECK ); // Decoder_Checking enum - break; - case 'I': - if ( strEQ(name, "IGNORE_WS") ) - XSRETURN_IV( IGNORE_WS ); // Decoder_Checking enum - break; - case 'N': - if ( strEQ(name, "NONE") ) - XSRETURN_IV( NONE ); // Decoder_Checking enum - break; - } - errno = EINVAL; - XSRETURN_UNDEF; - - -# =========================== Botan::Chain ========================== - -MODULE = Botan PACKAGE = Botan::Chain - -Botan__Chain * -Botan__Chain::new(f1 = 0, f2 = 0, f3 = 0, f4 = 0) - Botan__Filter *f1; - Botan__Filter *f2; - Botan__Filter *f3; - Botan__Filter *f4; - PREINIT: - ObjectInfo *f1_oi; - ObjectInfo *f2_oi; - ObjectInfo *f3_oi; - ObjectInfo *f4_oi; - CODE: - try { - RETVAL = new Botan__Chain(f1, f2, f3, f4); - if ( f1 ) f1_oi->set_delete_no(); - if ( f2 ) f2_oi->set_delete_no(); - if ( f3 ) f3_oi->set_delete_no(); - if ( f4 ) f4_oi->set_delete_no(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Chain::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - if ( THIS_oi->should_delete() ) - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# =========================== Botan::Fork ========================== - -MODULE = Botan PACKAGE = Botan::Fork - -Botan__Fork * -Botan__Fork::new(f1 = 0, f2 = 0, f3 = 0, f4 = 0) - Botan__Filter *f1; - Botan__Filter *f2; - Botan__Filter *f3; - Botan__Filter *f4; - PREINIT: - ObjectInfo *f1_oi; - ObjectInfo *f2_oi; - ObjectInfo *f3_oi; - ObjectInfo *f4_oi; - CODE: - try { - RETVAL = new Botan__Fork(f1, f2, f3, f4); - if ( f1 ) f1_oi->set_delete_no(); - if ( f2 ) f2_oi->set_delete_no(); - if ( f3 ) f3_oi->set_delete_no(); - if ( f4 ) f4_oi->set_delete_no(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Fork::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - if ( THIS_oi->should_delete() ) - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# ============================ Botan::Base64_Decoder ============================ - -MODULE = Botan PACKAGE = Botan::Base64_Decoder - -Botan__Base64_Decoder * -Botan__Base64_Decoder::new(checking = Botan::NONE) - int checking; - CODE: - try { - using namespace Botan; - RETVAL = new Base64_Decoder((Decoder_Checking)checking); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Base64_Decoder::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - if ( THIS_oi->should_delete() ) - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# =========================== Botan::Base64_Encoder ========================== - -MODULE = Botan PACKAGE = Botan::Base64_Encoder - -Botan__Base64_Encoder * -Botan__Base64_Encoder::new(breaks = false, length = 72) - bool breaks; - Botan__u32bit length; - CODE: - try { - RETVAL = new Botan__Base64_Encoder(breaks, length); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Base64_Encoder::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - if ( THIS_oi->should_delete() ) - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# ============================ Botan::Hex_Decoder ============================ - -MODULE = Botan PACKAGE = Botan::Hex_Decoder - -Botan__Hex_Decoder * -Botan__Hex_Decoder::new(checking = Botan::NONE) - int checking; - CODE: - try { - using namespace Botan; - RETVAL = new Hex_Decoder((Decoder_Checking)checking); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Hex_Decoder::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - if ( THIS_oi->should_delete() ) - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# ============================ Botan::Hex_Encoder ============================ - -MODULE = Botan PACKAGE = Botan::Hex_Encoder - -Botan__Hex_Encoder * -Botan__Hex_Encoder::new(breaks = false, length = 72, lcase = false) - bool breaks; - Botan__u32bit length; - bool lcase; - CODE: - try { - using Botan::Hex_Encoder; - RETVAL = new Hex_Encoder(breaks, length, - lcase ? Hex_Encoder::Lowercase : Hex_Encoder::Uppercase); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Hex_Encoder::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - if ( THIS_oi->should_delete() ) - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# ================================ Botan::OID ================================ - -MODULE = Botan PACKAGE = Botan::OID - -Botan__OID * -Botan__OID::new(s) - char *s; - CODE: - try { - RETVAL = new Botan__OID(s); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__OID::DESTROY() - CODE: - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - -char * -Botan__OID::as_string() - CODE: - try { - RETVAL = const_cast(THIS->as_string().c_str()); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - - -# ================================ Botan::OIDS ================================ - -MODULE = Botan PACKAGE = Botan::OIDS - -void -add_oid(oid, name) - Botan__OID *oid; - char *name; - CODE: - try { - Botan::OIDS::add_oid(*oid, name); - } - catch (const std::exception &e) { - croak(e.what()); - } - -char * -lookup_by_oid(oid) - Botan__OID *oid; - CODE: - try { - RETVAL = const_cast(Botan::OIDS::lookup(*oid).c_str()); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -Botan__OID * -lookup_by_name(name) - char *name; - CODE: - try { - RETVAL = new Botan__OID(Botan::OIDS::lookup(name)); - } - catch (const std::exception &e) { - croak(e.what()); - } - char const * CLASS = "Botan::OID"; - OUTPUT: - RETVAL - -int -have_oid(name) - char *name; - CODE: - try { - RETVAL = Botan::OIDS::have_oid(name); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - - -# ================================ Botan::Pipe ================================ - -MODULE = Botan PACKAGE = Botan::Pipe - -Botan__Pipe * -Botan__Pipe::new(...) - CODE: - for (I32 i = 1; i < items; i++) - { - if ( !sv_isobject(ST(i)) || (SvTYPE(SvRV(ST(i))) != SVt_PVMG) ) - croak("Botan::Pipe::new() -- arg %u is not " - "a blessed SV reference", i +1); - if ( !sv_derived_from(ST(i), "Botan::Filter") ) - croak("Botan::Pipe::new() -- arg %u is not " - "an object derived from Botan::Filter", i +1); - MAGIC *mg = mg_find(SvRV(ST(i)), '~'); - if ( mg == 0 - || mg->mg_len != sizeof(ObjectInfo) - || *(I32 *)(mg->mg_ptr) != ObjectInfo::SIGNVAL ) - croak("Botan::Pipe::new() -- arg %u has no " - "valid private magic data (ObjectInfo)", i +1); - } - try { - RETVAL = new Botan__Pipe(); - for (I32 i = 1; i < items; i++) - { - SV *osv = (SV *)SvRV(ST(i)); - ObjectInfo *oi = (ObjectInfo *)(mg_find(osv, '~')->mg_ptr); - RETVAL->append((Botan__Filter *)(SvIV(osv))); - oi->set_delete_no(); - } - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Pipe::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - -void -Botan__Pipe::write(s) - SV *s; - PREINIT: - ObjectInfo *THIS_oi; - CODE: - STRLEN len; - char *ptr = SvPV(s, len); - try { - THIS->write((unsigned char *)ptr, len); - } - catch (const std::exception &e) { - croak(e.what()); - } - -void -Botan__Pipe::process_msg(s) - SV *s; - PREINIT: - ObjectInfo *THIS_oi; - CODE: - STRLEN len; - char *ptr = SvPV(s, len); - try { - THIS->process_msg((unsigned char *)ptr, len); - } - catch (const std::exception &e) { - croak(e.what()); - } - -Botan__u32bit -Botan__Pipe::remaining(msgno = Botan::Pipe::DEFAULT_MESSAGE) - Botan__u32bit msgno; - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - RETVAL = THIS->remaining(msgno); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -SV * -Botan__Pipe::read(len = 0xFFFFFFFF, msgno = Botan::Pipe::DEFAULT_MESSAGE) - Botan__u32bit len; - Botan__u32bit msgno; - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - if ( len > THIS->remaining(msgno) ) - len = THIS->remaining(msgno); - RETVAL = NEWSV(0, len); - SvPOK_on(RETVAL); - if ( len > 0 ) - SvCUR_set(RETVAL, THIS->read((unsigned char *)SvPVX(RETVAL), - len, msgno)); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -SV * -Botan__Pipe::peek(len = 0xFFFFFFFF, offset = 0, \ - msgno = Botan::Pipe::DEFAULT_MESSAGE) - Botan__u32bit len; - Botan__u32bit offset; - Botan__u32bit msgno; - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - if ( len > THIS->remaining(msgno) ) - len = THIS->remaining(msgno); - RETVAL = NEWSV(0, len); - SvPOK_on(RETVAL); - if ( len > 0 ) - SvCUR_set(RETVAL, THIS->peek((unsigned char *)SvPVX(RETVAL), - len, offset, msgno)); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -Botan__u32bit -Botan__Pipe::default_msg() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - RETVAL = THIS->default_msg(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Pipe::set_default_msg(msgno) - Botan__u32bit msgno; - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - THIS->set_default_msg(msgno); - } - catch (const std::exception &e) { - croak(e.what()); - } - -Botan__u32bit -Botan__Pipe::message_count() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - RETVAL = THIS->message_count(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -bool -Botan__Pipe::end_of_data() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - RETVAL = THIS->end_of_data(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Pipe::start_msg() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - THIS->start_msg(); - } - catch (const std::exception &e) { - croak(e.what()); - } - -void -Botan__Pipe::end_msg() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - THIS->end_msg(); - } - catch (const std::exception &e) { - croak(e.what()); - } - -void -Botan__Pipe::reset() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - THIS->reset(); - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# ========================== Botan::X509_Certificate ========================== - -MODULE = Botan PACKAGE = Botan::X509_Certificate - -Botan__X509_Certificate * -Botan__X509_Certificate::new(char *fn) - CODE: - try { - RETVAL = new Botan__X509_Certificate(fn); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__X509_Certificate::DESTROY() - CODE: - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - -unsigned int -Botan__X509_Certificate::x509_version() - CODE: - try { - RETVAL = THIS->x509_version(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -char * -Botan__X509_Certificate::start_time() - CODE: - try { - RETVAL = const_cast(THIS->start_time().c_str()); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -char * -Botan__X509_Certificate::end_time() - CODE: - try { - RETVAL = const_cast(THIS->end_time().c_str()); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -char * -Botan__X509_Certificate::subject_info(char *info) - CODE: - try { - std::vector s = THIS->subject_info(info); - - if(s.size() > 0) - RETVAL = const_cast(s[0].c_str()); - else - RETVAL = "err"; - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -char * -Botan__X509_Certificate::issuer_info(char *info) - CODE: - try { - std::vector s = THIS->subject_info(info); - - if(s.size() > 0) - RETVAL = const_cast(s[0].c_str()); - else - RETVAL = "err"; - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -Botan__X509_DN * -Botan__X509_Certificate::subject_dn() - CODE: - try { - RETVAL = new Botan__X509_DN(THIS->subject_dn()); - } - catch (const std::exception &e) { - croak(e.what()); - } - char const * CLASS = "Botan::X509_DN"; - OUTPUT: - RETVAL - -Botan__X509_DN * -Botan__X509_Certificate::issuer_dn() - CODE: - try { - RETVAL = new Botan__X509_DN(THIS->issuer_dn()); - } - catch (const std::exception &e) { - croak(e.what()); - } - char const * CLASS = "Botan::X509_DN"; - OUTPUT: - RETVAL - - -# ============================== Botan::X509_DN ============================== - -MODULE = Botan PACKAGE = Botan::X509_DN - -Botan__X509_DN * -Botan__X509_DN::new() - CODE: - try { - RETVAL = new Botan__X509_DN(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__X509_DN::DESTROY() - CODE: - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - -AV * -Botan__X509_DN::get_attributes() - CODE: - try { - using namespace std; - using namespace Botan; - - typedef multimap::const_iterator rdn_iter; - - multimap const &atrmmap = THIS->get_attributes(); - RETVAL = newAV(); - for(rdn_iter i = atrmmap.begin(); i != atrmmap.end(); i++) - { - string const &atr = i->first.as_string(); - string const &val = i->second; - av_push(RETVAL, newSVpvn(atr.c_str(), atr.length())); - av_push(RETVAL, newSVpvn(val.c_str(), val.length())); - } - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL diff --git a/wrappers/perl-xs/Changes b/wrappers/perl-xs/Changes deleted file mode 100644 index 5f32b0c63..000000000 --- a/wrappers/perl-xs/Changes +++ /dev/null @@ -1,4 +0,0 @@ -Revision history for Perl extension to Botan. - -0.01 Fri, 20 Feb 2004 15:10:50 +0100 - - first version diff --git a/wrappers/perl-xs/MANIFEST b/wrappers/perl-xs/MANIFEST deleted file mode 100644 index b9d8454d6..000000000 --- a/wrappers/perl-xs/MANIFEST +++ /dev/null @@ -1,15 +0,0 @@ -Botan.pm -Botan.xs -Changes -MANIFEST -Makefile.PL -data/ca.cert.der -data/ca.cert.pem -t/base64.t -t/filt.t -t/hex.t -t/oid.t -t/pipe.t -t/testutl.pl -t/x509cert.t -typemap diff --git a/wrappers/perl-xs/Makefile.PL b/wrappers/perl-xs/Makefile.PL deleted file mode 100644 index d35c99168..000000000 --- a/wrappers/perl-xs/Makefile.PL +++ /dev/null @@ -1,29 +0,0 @@ -use ExtUtils::MakeMaker; - -my ($cc, $cflags, $lids); -if ( $^O eq 'MSWin32' ) -{ -# $cflags = ''; -# $libs = ':nosearch -lgdi32 -llibeay32'; -} -else -{ - $cc = 'g++'; - $cflags = '-fexceptions ' . qx( botan-config --cflags ); - $libs = qx( botan-config --libs ); -} - -WriteMakefile( - 'NAME' => 'Botan', - 'DISTNAME' => 'Botan-XS', - 'VERSION_FROM' => 'Botan.pm', # finds $VERSION - 'XSOPT' => '-C++', - 'CC' => $cc, - 'LD' => '$(CC)', - 'CCFLAGS' => $cflags, - 'LIBS' => [ $libs ], - 'OPTIMIZE' => '-g', -# 'clean' => { -# 'FILES' => 'neco.p12 rnd', -# }, -); diff --git a/wrappers/perl-xs/data/ca.cert.der b/wrappers/perl-xs/data/ca.cert.der deleted file mode 100644 index d6ed8aeaf..000000000 Binary files a/wrappers/perl-xs/data/ca.cert.der and /dev/null differ diff --git a/wrappers/perl-xs/data/ca.cert.pem b/wrappers/perl-xs/data/ca.cert.pem deleted file mode 100644 index 012913b26..000000000 --- a/wrappers/perl-xs/data/ca.cert.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICxDCCAi2gAwIBAgIBEjANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJDWjER -MA8GA1UEChMISUNaIGEucy4xGDAWBgNVBAMTD1Rlc3QgcHJpbWFyeSBDQTEWMBQG -CSqGSIb3DQEJARYHY2FAaS5jejAeFw0wMDA4MjAyMTQ4MDBaFw0wMjA4MTAyMTQ4 -MDBaME8xCzAJBgNVBAYTAkNaMREwDwYDVQQKEwhJQ1ogYS5zLjEVMBMGA1UEAxMM -VGVzdCBzaWduIENBMRYwFAYJKoZIhvcNAQkBFgdjYUBpLmN6MIGfMA0GCSqGSIb3 -DQEBAQUAA4GNADCBiQKBgQCo2GReNqwU0/8bZZua5hgYaVHvD9QAmfILNXD25jRk -C8lqe5m/GzbmftSUso5HyUy1t+qzvRDTmxK8uRn0P00Mqj9gjwF8PGQvZE/FrDF7 -rta9GCcH4n2GfQ0iexlhRZW44AfOD4HCgq38Z0bzBclsvUslBWe1AT+S5+chZ5Wb -UwIDAQABo4GsMIGpMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLXqc1b1DOfGehii -k4Z+/ih9BYZmMHoGA1UdIwRzMHGAFL7x2ToS4RDAbDJu4fHnzzGjfGmgoVakVDBS -MQswCQYDVQQGEwJDWjERMA8GA1UEChMISUNaIGEucy4xGDAWBgNVBAMTD1Rlc3Qg -cHJpbWFyeSBDQTEWMBQGCSqGSIb3DQEJARYHY2FAaS5jeoIBADANBgkqhkiG9w0B -AQUFAAOBgQAKD9ku9kKXUGhSw8KuWJXTnEsIUzDtgmREBEUOtEvGfU45vogWN7ZL -9fQZ1deywN4RJ4T5ZTTcCTPodOdG+IXLJ+uPn/m9iQ/D86c3GKS3yx4JNAn5PH1m -qLsMYVjbFD2uREZQsqbg3RT6L1D8+oK0pN379u3bD6oJx/qa7+F4Jg== ------END CERTIFICATE----- diff --git a/wrappers/perl-xs/t/base64.t b/wrappers/perl-xs/t/base64.t deleted file mode 100644 index f0973e13e..000000000 --- a/wrappers/perl-xs/t/base64.t +++ /dev/null @@ -1,273 +0,0 @@ -# vim: set ft=perl: -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### We start with some black magic to print on failure. - -# Change 1..1 below to 1..last_test_to_print . -# (It may become useful if the test is moved to ./t subdirectory.) - -BEGIN { $| = 1; print "1..24\n"; } -END { print "not ok 1\n" unless $loaded; } - -require 't/testutl.pl'; -use Botan; - -$loaded = 1; -print "ok 1\n"; - -######################### End of black magic. - -# Insert your test code below (better if it prints "ok 13" -# (correspondingly "not ok 13") depending on the success of chunk 13 -# of the test code): - -use strict; - -# Data prep - -my $botan_lic_b64_garbage = <<'EOF'; -Q29weXJpZ2h0IChDKSAxOTk5LTIwMDQgVGhlIEJvdGFuIFByb2plY3QuIEFsbCBy__ì¹ -aWdodHMgcmVzZXJ2ZWQuCgpSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJj$$*: -ZSBhbmQgYmluYXJ5IGZvcm1zLCBmb3IgYW55IHVzZSwgd2l0aCBvciB3aXRob3V0!@#$%^&*( -Cm1vZGlmaWNhdGlvbiwgaXMgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZv[\] -bGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6CgoxLiBSZWRpc3RyaWJ1dGlvbnMg'~` -b2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBu() -b3RpY2UsIHRoaXMKbGlzdCBvZiBjb25kaXRpb25zLCBhbmQgdGhlIGZvbGxvd2lu -ZyBkaXNjbGFpbWVyLgoKMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3Jt -IG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAp0aGlz -IGxpc3Qgb2YgY29uZGl0aW9ucywgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1l -ciBpbiB0aGUgZG9jdW1lbnRhdGlvbgphbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHBy_,^ -b3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KClRISVMgU09GVFdBUkUgSVMg{|}~~~~~ -UFJPVklERUQgQlkgVEhFIEFVVEhPUihTKSAiQVMgSVMiIEFORCBBTlkgRVhQUkVT~~~~~~~~ -UyBPUiBJTVBMSUVECldBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1J__:; -VEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GCk1FUkNIQU5UQUJJTElU -WSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UsIEFSRSBESVND -TEFJTUVELgoKSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUihTKSBPUiBDT05U -UklCVVRPUihTKSBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsCklORElSRUNULCBJ -TkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwg -REFNQUdFUyAoSU5DTFVESU5HLApCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVN -RU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNF -LApEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhP -V0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GCkxJQUJJTElUWSwgV0hF -VEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5D -TFVESU5HIE5FR0xJR0VOQ0UKT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBX -QVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRgpBRFZJ -U0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4K -EOF - -my $botan_lic_b64_ws = $botan_lic_b64_garbage; -$botan_lic_b64_ws =~ s/[^A-Za-z0-9+\/= \n]//g; - -my $botan_lic_b64 = $botan_lic_b64_ws; -$botan_lic_b64 =~ s/[ \n]//g; - - -my $botan_lic = <<'EOF'; -Copyright (C) 1999-2004 The Botan Project. All rights reserved. - -Redistribution and use in source and binary forms, for any use, with or without -modification, is permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this -list of conditions, and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, -this list of conditions, and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. - -IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -EOF - - -# Decoder... - -my $f; - -eval { $f = Botan::Base64_Decoder->new(&Botan::NONE); }; -print "not " if $@ || !defined $f; -print "ok 2\n"; - -my $dec; -eval { $dec = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $dec; -print "ok 3\n"; - -eval { $f = Botan::Base64_Decoder->new(&Botan::IGNORE_WS); }; -print "not " if $@ || !defined $f; -print "ok 4\n"; - -my $dec_is; -eval { $dec_is = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $dec_is; -print "ok 5\n"; - -eval { $f = Botan::Base64_Decoder->new(&Botan::FULL_CHECK); }; -print "not " if $@ || !defined $f; -print "ok 6\n"; - -my $dec_fc; -eval { $dec_fc = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $dec_fc; -print "ok 7\n"; - - -# Testing clean base64 input - -my $data; - -undef $data; -eval { - $dec->process_msg($botan_lic_b64); - $data = $dec->read(); -}; - -print "not " if $@ || $data ne $botan_lic; -print "ok 8\n"; - -undef $data; -eval { - $dec_is->process_msg($botan_lic_b64); - $data = $dec_is->read(); -}; - -print "not " if $@ || $data ne $botan_lic; -print "ok 9\n"; - -undef $data; -eval { - $dec_fc->process_msg($botan_lic_b64); - $data = $dec_fc->read(); -}; - -print "not " if $@ || $data ne $botan_lic; -print "ok 10\n"; - - -# Testing base64 input with whitespaces - -undef $data; -eval { - $dec->process_msg($botan_lic_b64_ws); - $dec->set_default_msg(1); - $data = $dec->read(); -}; - -print "not " if $@ || $data ne $botan_lic; -print "ok 11\n"; - -undef $data; -eval { - $dec_is->process_msg($botan_lic_b64_ws); - $dec_is->set_default_msg(1); - $data = $dec_is->read(); -}; - -print "not " if $@ || $data ne $botan_lic; -print "ok 12\n"; - -undef $data; -eval { - $dec_fc->process_msg($botan_lic_b64_ws); - $dec_fc->set_default_msg(1); - $data = $dec_fc->read(); -}; - -print "not " unless $@ && !defined $data; -print "ok 13\n"; - - -# Testing base64 input with garbage - -undef $data; -eval { - $dec->process_msg($botan_lic_b64_garbage); - $dec->set_default_msg(2); - $data = $dec->read(); -}; - -print "not " if $@ || $data ne $botan_lic; -print "ok 14\n"; - -undef $data; -eval { - $dec_is->process_msg($botan_lic_b64_garbage); - $dec_is->set_default_msg(2); - $data = $dec_is->read(); -}; - -print "not " unless $@ && !defined $data; -print "ok 15\n"; - -undef $data; -eval { - $dec_fc->process_msg($botan_lic_b64_garbage); - $dec_fc->set_default_msg(2); - $data = $dec_fc->read(); -}; - -print "not " unless $@ && !defined $data; -print "ok 16\n"; - - -# Encoder... - -eval { $f = Botan::Base64_Encoder->new(); }; -print "not " if $@ || !defined $f; -print "ok 17\n"; - -my $enc; -eval { $enc = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $enc; -print "ok 18\n"; - -eval { $f = Botan::Base64_Encoder->new(1, 5); }; -print "not " if $@ || !defined $f; -print "ok 19\n"; - -my $enc2; -eval { $enc2 = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $enc2; -print "ok 20\n"; - -undef $data; -eval { - $enc->process_msg("Hello\n"); - $data = $enc->read(); -}; -print "not " if $@ || $data ne "SGVsbG8K"; -print "ok 21\n"; - -undef $data; -eval { - $enc2->process_msg("Hello\n"); - $data = $enc2->read(); -}; -print "not " if $@ || $data ne "SGVsb\nG8K\n"; -print "ok 22\n"; - - -# Encoder with decoder... - -my $p; -eval { - $p = Botan::Pipe->new( - Botan::Base64_Encoder->new(), - Botan::Base64_Decoder->new(), - ); -}; -print "not " if $@ || !defined $p; -print "ok 23\n"; - -print "not " unless random_message_ok($p); -print "ok 24\n"; diff --git a/wrappers/perl-xs/t/filt.t b/wrappers/perl-xs/t/filt.t deleted file mode 100644 index 2a7b4c8ba..000000000 --- a/wrappers/perl-xs/t/filt.t +++ /dev/null @@ -1,56 +0,0 @@ -# vim: set ft=perl: -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### We start with some black magic to print on failure. - -# Change 1..1 below to 1..last_test_to_print . -# (It may become useful if the test is moved to ./t subdirectory.) - -BEGIN { $| = 1; print "1..5\n"; } -END { print "not ok 1\n" unless $loaded; } - -use Botan; - -$loaded = 1; -print "ok 1\n"; - -######################### End of black magic. - -# Insert your test code below (better if it prints "ok 13" -# (correspondingly "not ok 13") depending on the success of chunk 13 -# of the test code): - -use strict; - -my $pipe = Botan::Pipe->new(Botan::Hex_Encoder->new()); - -print "not " unless $pipe; -print "ok 2\n"; - -$pipe->process_msg('FOO'); - -print "not " if $pipe->read() ne '464F4F'; -print "ok 3\n"; - -$pipe = Botan::Pipe->new(Botan::Hex_Encoder->new(0, 0, 1)); - -print "not " unless $pipe; -print "ok 4\n"; - -$pipe->process_msg('FOO'); - -print "not " if $pipe->read() ne '464f4f'; -print "ok 5\n"; - - - - - - -#my $pipe = Botan::Pipe->new(Botan::Base64_Encoder->new()); -#$pipe->process_msg('FOO'); -# -#print "not " if $pipe->read() ne 'Rk9P'; -#print "ok 4\n"; - diff --git a/wrappers/perl-xs/t/hex.t b/wrappers/perl-xs/t/hex.t deleted file mode 100644 index 6f447b25c..000000000 --- a/wrappers/perl-xs/t/hex.t +++ /dev/null @@ -1,256 +0,0 @@ -# vim: set ft=perl: -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### We start with some black magic to print on failure. - -# Change 1..1 below to 1..last_test_to_print . -# (It may become useful if the test is moved to ./t subdirectory.) - -BEGIN { $| = 1; print "1..24\n"; } -END { print "not ok 1\n" unless $loaded; } - -require 't/testutl.pl'; -use Botan; - -$loaded = 1; -print "ok 1\n"; - -######################### End of black magic. - -# Insert your test code below (better if it prints "ok 13" -# (correspondingly "not ok 13") depending on the success of chunk 13 -# of the test code): - -use strict; - -# Data prep - -my ($hex, $hex_ws, $hex_garbage); -while ( $_ = ) -{ - $hex_garbage .= $_; - s/[^[:xdigit:][:space:]]//g; - $hex_ws .= $_; - s/[^[:xdigit:]]//g; - $hex .= $_; -} -my $data_test = pack("H*", $hex); - -# Decoder... - -my $f; - -eval { $f = Botan::Hex_Decoder->new(&Botan::NONE); }; -print "not " if $@ || !defined $f; -print "ok 2\n"; - -my $dec; -eval { $dec = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $dec; -print "ok 3\n"; - -eval { $f = Botan::Hex_Decoder->new(&Botan::IGNORE_WS); }; -print "not " if $@ || !defined $f; -print "ok 4\n"; - -my $dec_is; -eval { $dec_is = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $dec_is; -print "ok 5\n"; - -eval { $f = Botan::Hex_Decoder->new(&Botan::FULL_CHECK); }; -print "not " if $@ || !defined $f; -print "ok 6\n"; - -my $dec_fc; -eval { $dec_fc = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $dec_fc; -print "ok 7\n"; - - -# Testing clean hexadecimal input - -my $data; - -undef $data; -eval { - $dec->process_msg($hex); - $data = $dec->read(); -}; - -print "not " if $@ || $data ne $data_test; -print "ok 8\n"; - -undef $data; -eval { - $dec_is->process_msg($hex); - $data = $dec_is->read(); -}; - -print "not " if $@ || $data ne $data_test; -print "ok 9\n"; - -undef $data; -eval { - $dec_fc->process_msg($hex); - $data = $dec_fc->read(); -}; - -print "not " if $@ || $data ne $data_test; -print "ok 10\n"; - - -# Testing hexadecimal input with whitespaces - -undef $data; -eval { - $dec->process_msg($hex_ws); - $dec->set_default_msg(1); - $data = $dec->read(); -}; - -print "not " if $@ || $data ne $data_test; -print "ok 11\n"; - -undef $data; -eval { - $dec_is->process_msg($hex_ws); - $dec_is->set_default_msg(1); - $data = $dec_is->read(); -}; - -print "not " if $@ || $data ne $data_test; -print "ok 12\n"; - -undef $data; -eval { - $dec_fc->process_msg($hex_ws); - $dec_fc->set_default_msg(1); - $data = $dec_fc->read(); -}; - -print "not " unless $@ && !defined $data; -print "ok 13\n"; - - -# Testing hexadecimal input with garbage - -undef $data; -eval { - $dec->process_msg($hex_garbage); - $dec->set_default_msg(2); - $data = $dec->read(); -}; - -print "not " if $@ || $data ne $data_test; -print "ok 14\n"; - -undef $data; -eval { - $dec_is->process_msg($hex_garbage); - $dec_is->set_default_msg(2); - $data = $dec_is->read(); -}; - -print "not " unless $@ && !defined $data; -print "ok 15\n"; - -undef $data; -eval { - $dec_fc->process_msg($hex_garbage); - $dec_fc->set_default_msg(2); - $data = $dec_fc->read(); -}; - -print "not " unless $@ && !defined $data; -print "ok 16\n"; - - -# Encoder... - -eval { $f = Botan::Hex_Encoder->new(); }; -print "not " if $@ || !defined $f; -print "ok 17\n"; - -my $enc; -eval { $enc = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $enc; -print "ok 18\n"; - -eval { $f = Botan::Hex_Encoder->new(1, 5, 1); }; -print "not " if $@ || !defined $f; -print "ok 19\n"; - -my $enc2; -eval { $enc2 = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $enc2; -print "ok 20\n"; - -undef $data; -eval { - $enc->process_msg("Hello\n"); - $data = $enc->read(); -}; -print "not " if $@ || $data ne "48656C6C6F0A"; -print "ok 21\n"; - -undef $data; -eval { - $enc2->process_msg("Hello\n"); - $data = $enc2->read(); -}; -print "not " if $@ || $data ne "48656\nc6c6f\n0a\n"; -print "ok 22\n"; - - -# Encoder with decoder... - -my $p; -eval { - $p = Botan::Pipe->new( - Botan::Hex_Encoder->new(), - Botan::Hex_Decoder->new(), - ); -}; -print "not " if $@ || !defined $p; -print "ok 23\n"; - -print "not " unless random_message_ok($p); -print "ok 24\n"; - - - -__DATA__ -cb13 4a4d 7522 1fd3 c6f6 7786 d04b 3043 ..JMu"....w..K.. -4552 4bcf 4d2b 9d71 0cfe 4d6a 1caf bcfd .RK.M+.q..Mj.... -8f91 6151 ff85 e900 7e6a bafc 15e9 ae51 ...Q....~j.....Q -b14b 7210 bb40 5958 2b82 d49e b808 68a5 .Kr..@YX+.....h. -7945 9dec f686 9b98 989e 826d 8088 6ee7 y..........m..n. -d066 1eac 8c34 c461 bb54 7726 87ab d681 .........Tw&.... -a0be 52e5 1128 0cf2 759e cb2d e690 4ed9 ..R..(..u..-..N. -7e88 bda7 2523 4a0f 185a 02b1 f898 fc41 ~...%#J..Z...... -dd48 fa87 945d 7611 b8c9 a50a 2de2 b670 .H...]v.....-..p -0056 c8be 2cbb e7d0 1e70 4a3d 79f0 dce9 .V..,....pJ=y... -b57f 154b 2b3a db73 f086 de11 9f3e 1641 ...K+:.s.....>.. -3a28 8b9b bb0f 682b 80db b791 89e0 62c0 :(....h+........ -7204 db97 5432 2eb0 a04e f38e 809f 7223 r...T....N....r# -912e e552 1452 6dd2 e09f dd06 c715 7c1a ...R.Rm.......|. -fe3d d6cc b6d0 a17a 27d7 4327 4e43 8af3 .=.....z'..'N... -6eb5 e9f8 bfe9 34c3 6636 8243 358f 966d n..............m -7d87 d17b 5c37 6acb 4972 f4ec 6806 bbde }..{\.j.Ir..h... -2689 a019 a9e2 4101 7fe2 de72 bc03 eb5e &..........r...^ -b699 2d6b f8cd a08e 6e01 edfc a81a 94b6 ..-k....n....... -9073 15fb efb2 c8d9 9f85 6633 85f1 e9d0 .s.............. -20ce 578b ab9d 2e51 b947 69bf fba5 82c6 .W....Q.Gi..... -2ed0 dd36 d679 a399 7db3 8a0d cdef 0eda .....y..}....... -e761 e7f1 5b17 3f67 0c83 215a eddf 9d2a ....[.?g..!Z...* -5e70 0a77 c92e 94e1 a82b fd7c f10a 894f ^p.w.....+.|...O -2955 f0e8 7398 f409 2040 b797 da03 a5a6 )U..s... @...... -7ba4 c3c9 2659 b9f7 6a56 e17a b481 983f {...&Y..jV.z...? -00ed 3cc8 5a22 ad5c b6e0 3566 d717 35a6 ..<.Z".\........ -1523 4104 de63 477e fd24 68e5 e816 98df .#....G~.$h..... -1747 417e db72 a76a be5b b9dc 3dfb 2d05 .G.~.r.j.[..=.-. -d27f e597 eafc 9a29 15c5 792d 9c88 9aea .......)..y-.... -485e e431 96c3 7723 da6d 28b2 477a fd12 H^....w#.m(.Gz.. -e645 5dcd 7d5a d8b4 7acc 10b2 b41a e11d ..].}Z..z....... diff --git a/wrappers/perl-xs/t/oid.t b/wrappers/perl-xs/t/oid.t deleted file mode 100644 index 66204541f..000000000 --- a/wrappers/perl-xs/t/oid.t +++ /dev/null @@ -1,45 +0,0 @@ -# vim: set ft=perl: -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### We start with some black magic to print on failure. - -# Change 1..1 below to 1..last_test_to_print . -# (It may become useful if the test is moved to ./t subdirectory.) - -BEGIN { $| = 1; print "1..6\n"; } -END { print "not ok 1\n" unless $loaded; } - -use Botan; - -$loaded = 1; -print "ok 1\n"; - -######################### End of black magic. - -# Insert your test code below (better if it prints "ok 13" -# (correspondingly "not ok 13") depending on the success of chunk 13 -# of the test code): - -use strict; - -print "not " unless Botan::OIDS::have_oid('X520.CommonName'); -print "ok 2\n"; - -my $oid_c = Botan::OID->new('2.5.4.3'); -print "not " if Botan::OIDS::lookup_by_oid($oid_c) ne 'X520.CommonName'; -print "ok 3\n"; - -my $oid_x = Botan::OIDS::lookup_by_name('X520.CommonName'); -print "not " if $oid_x->as_string() ne '2.5.4.3'; -print "ok 4\n"; - -my $oid_foo_num = '1.2.3.4.5.6.7.8.9.10.11.12.13.14.15'; -my $oid_foo = Botan::OID->new($oid_foo_num); -print "not " if Botan::OIDS::lookup_by_oid($oid_foo) ne $oid_foo_num; -print "ok 5\n"; - -Botan::OIDS::add_oid($oid_foo, 'Zito.Foo'); - -print "not " if Botan::OIDS::lookup_by_oid($oid_foo) ne 'Zito.Foo'; -print "ok 6\n"; diff --git a/wrappers/perl-xs/t/pipe.t b/wrappers/perl-xs/t/pipe.t deleted file mode 100644 index f850d8519..000000000 --- a/wrappers/perl-xs/t/pipe.t +++ /dev/null @@ -1,98 +0,0 @@ -# vim: set ft=perl: -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### We start with some black magic to print on failure. - -# Change 1..1 below to 1..last_test_to_print . -# (It may become useful if the test is moved to ./t subdirectory.) - -BEGIN { $| = 1; print "1..20\n"; } -END { print "not ok 1\n" unless $loaded; } - -use Botan; - -$loaded = 1; -print "ok 1\n"; - -######################### End of black magic. - -# Insert your test code below (better if it prints "ok 13" -# (correspondingly "not ok 13") depending on the success of chunk 13 -# of the test code): - -use strict; - -my $pipe = Botan::Pipe->new(); - -print "not " unless $pipe; -print "ok 2\n"; - -$pipe->start_msg(); -$pipe->write('Hello world'); -$pipe->end_msg(); - -print "not " if $pipe->message_count() != 1; -print "ok 3\n"; - -print "not " if $pipe->remaining() != 11; -print "ok 4\n"; - -print "not " if $pipe->end_of_data(); -print "ok 5\n"; - -print "not " if $pipe->read() ne 'Hello world'; -print "ok 6\n"; - -print "not " if $pipe->remaining() != 0; -print "ok 7\n"; - -print "not " unless $pipe->end_of_data(); -print "ok 8\n"; - -$pipe->process_msg('Hello world'); - -print "not " if $pipe->message_count() != 2; -print "ok 9\n"; - -my $msg_num = $pipe->message_count() -1; - -print "not " if $pipe->read(5, $msg_num) ne 'Hello'; -print "ok 10\n"; - -print "not " if $pipe->read(6, $msg_num) ne ' world'; -print "ok 11\n"; - -print "not " if $pipe->remaining() != 0; -print "ok 12\n"; - -print "not " unless $pipe->end_of_data(); -print "ok 13\n"; - -$pipe->process_msg("The\0string\0with\0null\0chars\0"); -$msg_num = $pipe->message_count() -1; - -print "not " if $pipe->read(80, $msg_num) ne "The\0string\0with\0null\0chars\0"; -print "ok 14\n"; - -$pipe->process_msg('FOO BAR'); -$pipe->set_default_msg($pipe->message_count() -1); - -print "not " if $pipe->peek(3) ne 'FOO'; -print "ok 15\n"; - -print "not " if $pipe->peek(3, 4) ne 'BAR'; -print "ok 16\n"; - -print "not " if $pipe->peek() ne 'FOO BAR'; -print "ok 17\n"; - -print "not " if $pipe->read() ne 'FOO BAR'; -print "ok 18\n"; - -print "not " if $pipe->remaining() != 0; -print "ok 19\n"; - -print "not " unless $pipe->end_of_data(); -print "ok 20\n"; - diff --git a/wrappers/perl-xs/t/testutl.pl b/wrappers/perl-xs/t/testutl.pl deleted file mode 100644 index add6f6a45..000000000 --- a/wrappers/perl-xs/t/testutl.pl +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/perl - -sub random_message_ok -{ - my ($pipe, $iter, $chunkmax) = @_; - $iter = 100 unless defined $iter; - $chunkmax = 300 unless defined $chunkmax; - eval { - my $input = ''; - $pipe->start_msg(); - for(my $i = 0; $i < $iter; $i++) - { - my $chunk = ''; - my $chunklen = int(rand($chunkmax)); - $chunk .= pack("C", int(rand(256))) while $chunklen--; - $input .= $chunk; - $pipe->write($chunk); - } - $pipe->end_msg(); - my $msg_num = $pipe->message_count() -1; - my $output = $pipe->read(0xFFFFFFFF, $msg_num); - return $input eq $output; - }; -} - -1; diff --git a/wrappers/perl-xs/t/x509cert.t b/wrappers/perl-xs/t/x509cert.t deleted file mode 100644 index 2a943aeac..000000000 --- a/wrappers/perl-xs/t/x509cert.t +++ /dev/null @@ -1,42 +0,0 @@ -# vim: set ft=perl: -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### We start with some black magic to print on failure. - -# Change 1..1 below to 1..last_test_to_print . -# (It may become useful if the test is moved to ./t subdirectory.) - -BEGIN { $| = 1; print "1..4\n"; } -END { print "not ok 1\n" unless $loaded; } - -use Botan; - -$loaded = 1; -print "ok 1\n"; - -######################### End of black magic. - -# Insert your test code below (better if it prints "ok 13" -# (correspondingly "not ok 13") depending on the success of chunk 13 -# of the test code): - -use strict; - -my $cert = Botan::X509_Certificate->new('data/ca.cert.der'); - -print "not " if $cert->x509_version() != 3; -print "ok 2\n"; - -print "not " if $cert->start_time() ne '2000/8/20 21:48:00 UTC'; -print "ok 3\n"; - -print "not " if $cert->end_time() ne '2002/8/10 21:48:00 UTC'; -print "ok 4\n"; - -#my $subject = $cert->subject_dn()->get_attributes(); -#print STDERR "subject=", join(',', @{$subject}), "\n"; -# -#my $issuer = $cert->issuer_dn()->get_attributes(); -#print STDERR "issuer=", join(',', @{$issuer}), "\n"; -# diff --git a/wrappers/perl-xs/typemap b/wrappers/perl-xs/typemap deleted file mode 100644 index d7403d40d..000000000 --- a/wrappers/perl-xs/typemap +++ /dev/null @@ -1,62 +0,0 @@ -TYPEMAP - -Botan__ASN1_String * O_OBJECT -Botan__AlgorithmIdentifier * O_OBJECT -Botan__AlternativeName * O_OBJECT -Botan__Attribute * O_OBJECT -Botan__Base64_Decoder * O_EXTOBJECT -Botan__Base64_Encoder * O_EXTOBJECT -Botan__Chain * O_EXTOBJECT -Botan__Extension * O_OBJECT -Botan__Filter * O_EXTOBJECT -Botan__Fork * O_EXTOBJECT -Botan__Hex_Decoder * O_EXTOBJECT -Botan__Hex_Encoder * O_EXTOBJECT -Botan__OID * O_OBJECT -Botan__Pipe * O_OBJECT -Botan__X509_Certificate * O_OBJECT -Botan__X509_DN * O_OBJECT -Botan__X509_Time * O_OBJECT -Botan__u32bit T_UV - - -###################################################################### -OUTPUT - -# The Perl object is blessed into 'CLASS', which should be a -# char* having the name of the package for the blessing. -O_OBJECT - sv_setref_pv($arg, CLASS, (void*)$var); - -O_EXTOBJECT - sv_setref_pv($arg, CLASS, (void*)$var); - sv_magic(SvRV($arg), 0, '~', (char *)&oi_init, sizeof(oi_init)); - - -###################################################################### -INPUT - -O_OBJECT - if ( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) ) - $var = ($type)SvIV((SV*)SvRV( $arg )); - else - croak(\"${Package}::$func_name() -- \" - \"$var is not a blessed SV reference\"); - -# The pointer variable "ObjectInfo *${var}_oi;" must be declared -# in PREINIT section. I don't know how to emit this declaration safely here. -O_EXTOBJECT - if ( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) ) - $var = ($type)SvIV((SV*)SvRV($arg)); - else - croak(\"${Package}::$func_name() -- \" - \"$var is not a blessed SV reference\"); - { - MAGIC *mg = mg_find(SvRV($arg), '~'); - if ( mg == 0 - || mg->mg_len != sizeof(ObjectInfo) - || *(I32 *)(mg->mg_ptr) != ObjectInfo::SIGNVAL ) - croak(\"${Package}::$func_name() -- \" - \"private magic data for $var invalid\"); - ${var}_oi = (ObjectInfo *)(mg->mg_ptr); - } diff --git a/wrappers/swig/Makefile b/wrappers/swig/Makefile deleted file mode 100644 index ff55c793c..000000000 --- a/wrappers/swig/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -LANG=-python -LANG_INC=/usr/include/python2.3 - -CFLAGS=$(shell botan-config --cflags) -LIBS=$(shell botan-config --libs) - -CXX = g++ -g -SWIG = swig -Wall - -all: _botan.so - -_botan.so: base.o pipe.o filter.o botan_wrap.o - $(CXX) -shared $^ $(LIBS) -o $@ - -botan_wrap.cpp: botan.swg base.h - $(SWIG) $(LANG) -c++ -o $@ $< - -botan_wrap.o: botan_wrap.cpp - $(CXX) $(CFLAGS) -I$(LANG_INC) -c $^ -o $@ - -base.o: base.cpp base.h - $(CXX) $(CFLAGS) -c $< -o $@ - -pipe.o: pipe.cpp base.h - $(CXX) $(CFLAGS) -c $< -o $@ - -filter.o: filter.cpp base.h - $(CXX) $(CFLAGS) -c $< -o $@ - -clean: - rm -f *.o _botan.so botan.py botan.pyc - rm -f *_wrap.o *_wrap.cpp diff --git a/wrappers/swig/base.cpp b/wrappers/swig/base.cpp deleted file mode 100644 index 448b3d48e..000000000 --- a/wrappers/swig/base.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************* -* SWIG Interface for basic Botan interface * -* (C) 1999-2003 Jack Lloyd * -*************************************************/ - -#include "base.h" -#include - -#include - -/************************************************* -* Initialize the library * -*************************************************/ -LibraryInitializer::LibraryInitializer(const char* args) - { - Botan::Init::initialize(args); - } - -/************************************************* -* Shut down the library * -*************************************************/ -LibraryInitializer::~LibraryInitializer() - { - Botan::Init::deinitialize(); - } - -/************************************************* -* Create a SymmetricKey * -*************************************************/ -SymmetricKey::SymmetricKey(const std::string& str) - { - key = new Botan::SymmetricKey(str); - printf("STR CON: %p %p\n", this, key); - } - -/************************************************* -* Create a SymmetricKey * -*************************************************/ -SymmetricKey::SymmetricKey(u32bit n) - { - key = new Botan::SymmetricKey(n); - printf("N CON: %p %p\n", this, key); - } - -/************************************************* -* Destroy a SymmetricKey * -*************************************************/ -SymmetricKey::~SymmetricKey() - { - printf("DESTR: %p %p\n", this, key); - delete key; - key = 0; - //printf("deleted\n"); - } - -/************************************************* -* Create an InitializationVector * -*************************************************/ -InitializationVector::InitializationVector(const std::string& str) : iv(str) - { - } diff --git a/wrappers/swig/base.h b/wrappers/swig/base.h deleted file mode 100644 index 341a5c35a..000000000 --- a/wrappers/swig/base.h +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************* -* SWIG Interface for Botan * -* (C) 1999-2003 Jack Lloyd * -*************************************************/ - -#ifndef BOTAN_WRAP_BASE_H__ -#define BOTAN_WRAP_BASE_H__ - -#include - -#if !defined(SWIG) - #define OUTPUT - #define INOUT -#endif - -/************************************************* -* Typedefs * -*************************************************/ -typedef unsigned char byte; -typedef unsigned int u32bit; - -/************************************************* -* Library Initalization/Shutdown Object * -*************************************************/ -class LibraryInitializer - { - public: - LibraryInitializer(const char*); - ~LibraryInitializer(); - }; - -/************************************************* -* Symmetric Key Object * -*************************************************/ -class SymmetricKey - { - public: - std::string as_string() const { return key->as_string(); } - u32bit length() const { return key->length(); } - SymmetricKey(u32bit = 0); - SymmetricKey(const std::string&); - ~SymmetricKey(); - private: - Botan::SymmetricKey* key; - }; - -/************************************************* -* Initialization Vector Object * -*************************************************/ -class InitializationVector - { - public: - std::string as_string() const { return iv.as_string(); } - u32bit length() const { return iv.length(); } - InitializationVector(u32bit n = 0) { iv.change(n); } - InitializationVector(const std::string&); - private: - Botan::InitializationVector iv; - }; - -/************************************************* -* Filter Object * -*************************************************/ -class Filter - { - public: - Filter(const char*); - //Filter(const char*, const SymmetricKey&); - //Filter(const char*, const SymmetricKey&, const InitializationVector&); - ~Filter(); - private: - friend class Pipe; - Botan::Filter* filter; - bool pipe_owns; - }; - -/************************************************* -* Pipe Object * -*************************************************/ -class Pipe - { - public: - static const u32bit DEFAULT_MESSAGE = 0xFFFFFFFF; - - void write_file(const char*); - void write_string(const char*); - - u32bit read(byte*, u32bit, u32bit = DEFAULT_MESSAGE); - std::string read_all_as_string(u32bit = DEFAULT_MESSAGE); - - u32bit remaining(u32bit = DEFAULT_MESSAGE); - - void start_msg(); - void end_msg(); - - Pipe(Filter* = 0, Filter* = 0, Filter* = 0, Filter* = 0); - ~Pipe(); - private: - Botan::Pipe* pipe; - }; - -#endif diff --git a/wrappers/swig/botan.swg b/wrappers/swig/botan.swg deleted file mode 100644 index 9088f4272..000000000 --- a/wrappers/swig/botan.swg +++ /dev/null @@ -1,26 +0,0 @@ -/************************************************* -* SWIG Interface for Botan * -*************************************************/ -%module botan - -%include "typemaps.i" -%include "std_string.i" -%include "exception.i" -%include "constraints.i" -%include "carrays.i" - -%{ -#include "base.h" -%} - -%exception { - try { - $action - } - catch(std::exception& e) - { - SWIG_exception(SWIG_RuntimeError, e.what()); - } -} - -%include "base.h" diff --git a/wrappers/swig/doit.py b/wrappers/swig/doit.py deleted file mode 100755 index 98bc97087..000000000 --- a/wrappers/swig/doit.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/python2 - -import botan - -def hash_it(hash, input): - f1 = botan.Filter("MD5") - f2 = botan.Filter("Hex_Encoder") - pipe = botan.Pipe(f1, f2) - - pipe.start_msg() - pipe.write_string(input) - pipe.end_msg() - - print pipe.remaining() - - out = pipe.read(0) - - - - -def main: - init = botan.LibraryInitializer - - print hash_it("MD5", "foo") - - - key1 = botan.SymmetricKey("ABCD") - print key1.as_string() - key2 = botan.SymmetricKey(16) - print key2.as_string() - - iv1 = botan.InitializationVector(8) - print iv1.as_string() - - - f3 = pipe.read(pipe.remaining()) - - size = pipe.remaining() - out = botan.byte_array(size) - pipe.read(out.cast,size) - - for i in range (0,size): - print "%02X" % out[i] - - print pipe.read_all_as_string() - -if __name__ == "__main__": - sys.exit(main()) - diff --git a/wrappers/swig/filter.cpp b/wrappers/swig/filter.cpp deleted file mode 100644 index 53ff0e6a3..000000000 --- a/wrappers/swig/filter.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************* -* SWIG Interface for Filter Retrieval * -* (C) 1999-2003 Jack Lloyd * -*************************************************/ - -#include "base.h" -#include -#include - -/************************************************* -* Filter Creation * -*************************************************/ -Filter::Filter(const char* filt_string) - { - filter = 0; - pipe_owns = false; - - /* - Fixme: This is all so totally wrong. It needs to have full argument - processing for everything, all that kind of crap. - */ - const std::string filt_name = filt_string; - - if(Botan::have_hash(filt_name)) - filter = new Botan::Hash_Filter(filt_name); - else if(filt_name == "Hex_Encoder") - filter = new Botan::Hex_Encoder; - } - -/************************************************* -* Filter Destruction * -*************************************************/ -Filter::~Filter() - { - /* - if(!pipe_owns) - delete filter; - */ - } diff --git a/wrappers/swig/pipe.cpp b/wrappers/swig/pipe.cpp deleted file mode 100644 index 0f35d5a43..000000000 --- a/wrappers/swig/pipe.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************* -* SWIG Interface for Botan Pipe API * -* (C) 1999-2003 Jack Lloyd * -*************************************************/ - -#include "base.h" -#include - -#include - -/************************************************* -* Write the contents of a file into a Pipe * -*************************************************/ -void Pipe::write_file(const char* filename) - { - Botan::DataSource_Stream in(filename); - pipe->write(in); - } - -/************************************************* -* Write the contents of a string into a Pipe * -*************************************************/ -void Pipe::write_string(const char* string) - { - pipe->write(string); - } - -/************************************************* -* Read the contents of a Pipe into a buffer * -*************************************************/ -u32bit Pipe::read(byte* buf, u32bit length, u32bit msg) - { - printf("read %p %d\n", buf, length); - return 0; - //return pipe->read(buf, length, msg); - } - -/************************************************* -* Read the contents of a Pipe as a string * -*************************************************/ -std::string Pipe::read_all_as_string(u32bit msg) - { - return pipe->read_all_as_string(msg); - } - -/************************************************* -* Find out how much stuff the Pipe still has * -*************************************************/ -u32bit Pipe::remaining(u32bit msg) - { - return pipe->remaining(); - } - -/************************************************* -* Start a new message * -*************************************************/ -void Pipe::start_msg() - { - pipe->start_msg(); - } - -/************************************************* -* End the current msessage * -*************************************************/ -void Pipe::end_msg() - { - pipe->end_msg(); - } - -/************************************************* -* Create a new Pipe * -*************************************************/ -Pipe::Pipe(Filter* f1, Filter* f2, Filter* f3, Filter* f4) - { - pipe = new Botan::Pipe(); - - if(f1) { pipe->append(f1->filter); f1->pipe_owns = true; } - if(f2) { pipe->append(f2->filter); f2->pipe_owns = true; } - if(f3) { pipe->append(f3->filter); f3->pipe_owns = true; } - if(f4) { pipe->append(f4->filter); f4->pipe_owns = true; } - } - -/************************************************* -* Destroy this Pipe * -*************************************************/ -Pipe::~Pipe() - { - delete pipe; - } diff --git a/wrappers/swig/pk.swg b/wrappers/swig/pk.swg deleted file mode 100644 index 8e03cf120..000000000 --- a/wrappers/swig/pk.swg +++ /dev/null @@ -1,8 +0,0 @@ -%module botan - -%{ -#undef ANY -#include "botan/pubkey.h" -%} - -%include "botan/pubkey.h" diff --git a/wrappers/swig/readme.txt b/wrappers/swig/readme.txt deleted file mode 100644 index a9965d914..000000000 --- a/wrappers/swig/readme.txt +++ /dev/null @@ -1,34 +0,0 @@ -This is the beginning of an attempt to SWIG-ify Botan so it can be accessed by -other languages. You should use the latest SWIG 1.3 release (I am currently -using SWIG 1.3.19). Currently I am only testing this code with Python 2.2.1, -since that is the language I am mainly interested in at this point. Feel free -to send me patches so this is usable with Perl or whatever. - -I'm not attempting to make everything in Botan usable from a script - -basically, I just want the parts that *I* want to use. Most things are not -supported yet, and there are lots of bugs in the stuff that does exist. If -there is something in particular that you would like to be able to use from a -script, let me know (patches are good, too). - -Todo: - * Why does it seg fault if we don't create a LibraryInitializer. It should - throw an exception, like it does in C++. Maybe have it init Botan when the - module is loaded? That seems a lot cleaner/nicer, but I don't know how to - do it yet. - * Lots of problems with exceptions - * Use constraints to prevent bad args when possible - * Pipe/Filter - - Better argument processing for all filters - - Support for ciphers, MACs, etc - - Chain + Fork - - Support for append/prepend/pop/reset in Pipe? - * Public Key Crypto - - RSA - - DSA - - DH - - Generic X.509 and PKCS #8 stuff - * PKI - - X.509 certs + CRLs - - PKCS #10 requests - - X.509 stores - - X.509 CA diff --git a/wrappers/swig/tests/block.py b/wrappers/swig/tests/block.py deleted file mode 100644 index 593937c81..000000000 --- a/wrappers/swig/tests/block.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/python - -import botan, base64 - -class MyCipher(botan.BlockCipher): - def __init__(self): - botan.BlockCipher.__init__(self, 16, 16, 32, 8) - def encrypt(self, val): - print "encrypt", val - return val.swapcase() - def decrypt(self, val): - print "decrypt", val - return val.swapcase() - def set_key(self, key): - print "set_key", key - def clone(self): - print "cloning" - return MyCipher() - def name(self): - print "naming" - return "MyCipher" - -cipher = botan.BlockCipher("AES-128") - -print cipher.block_size -print cipher.keylength_min -print cipher.keylength_max -print cipher.keylength_mod -print cipher.name() - -for kl in range(1, 128): - if cipher.valid_keylength(kl): - print "1", - else: - print "0", -print -key = botan.SymmetricKey(16) - -cipher.set_key(key) -ciphertext = cipher.encrypt("ABCDEFGH12345678") -print base64.b16encode(ciphertext) - -cipher2 = cipher.clone() -cipher2.set_key(key) - -plaintext = cipher2.decrypt(ciphertext) -print plaintext - -botan.get_info(cipher) - -mycipher = MyCipher() -botan.get_info(mycipher) diff --git a/wrappers/swig/tests/block2.py b/wrappers/swig/tests/block2.py deleted file mode 100644 index 5faccaf9a..000000000 --- a/wrappers/swig/tests/block2.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/python - -import botan, base64 - -class MyCipher(botan.BlockCipherImpl): - def __init__(self): - botan.BlockCipherImpl.__init__(self, 8, 8, 16, 1) - - def name(self): - return "MyCipher" - - def encrypt(self, input): - return input.swapcase() - - def decrypt(self, input): - return input.swapcase() - - def set_key(self, key): - print "Got key",key - -def test(cipher): - print - print cipher - print "Testing", cipher.name() - print cipher.block_size - print cipher.keylength_min, cipher.keylength_max, cipher.keylength_mod - for i in range(1, 64): - if cipher.valid_keylength(i): - print "1", - else: - print "0", - print - cipher.set_key(botan.SymmetricKey(16)) - ciphertext = cipher.encrypt("aBcDeFgH" * (cipher.block_size / 8)) - print repr(ciphertext) - print cipher.decrypt(ciphertext) - -def main(): - test(botan.BlockCipher("Blowfish")) - test(MyCipher()) - test(botan.BlockCipher("AES")) - -if __name__ == "__main__": - main() diff --git a/wrappers/swig/tests/encrypt.py b/wrappers/swig/tests/encrypt.py deleted file mode 100644 index 9896777d4..000000000 --- a/wrappers/swig/tests/encrypt.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/python - -import sys, botan - -def encrypt(input): - cipher_key = botan.SymmetricKey("AABB") - print cipher_key.length - cipher_key = botan.SymmetricKey("AABBCCDD") - print cipher_key.length - - cipher = botan.Filter("ARC4", key = cipher_key) - - pipe = botan.Pipe(cipher, botan.Filter("Hex_Encoder")) - - pipe.start_msg() - pipe.write(input) - pipe.end_msg() - - str = pipe.read_all() - print str - return str - -def decrypt(input): - pipe = botan.Pipe(botan.Filter("Hex_Decoder"), - botan.Filter("ARC4", - key = botan.SymmetricKey("AABBCCDD"))) - - pipe.process_msg(input) - return pipe.read_all() - -def main(): - ciphertext = encrypt("hi chappy") - print ciphertext - print decrypt(ciphertext) - -if __name__ == "__main__": - sys.exit(main()) diff --git a/wrappers/swig/tests/filter.py b/wrappers/swig/tests/filter.py deleted file mode 100644 index 2b65d9ff2..000000000 --- a/wrappers/swig/tests/filter.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/python - -import sys, botan - -class MyFilter(botan.FilterObj): - def write(self, input): - print "MyFilter::write",input - self.send(input) - def start_msg(self): - print "MyFilter::start_msg" - def end_msg(self): - print "MyFilter::end_msg" - def __del__(self): - print "~MyFilter" - -def main(): - filter = MyFilter() - - pipe = botan.Pipe(botan.Filter("Hex_Encoder"), filter, - botan.Filter("Hex_Decoder")) - pipe.start_msg() - pipe.write("hi chappy") - pipe.end_msg() - print pipe.read_all() - -if __name__ == "__main__": - sys.exit(main()) diff --git a/wrappers/swig/tests/hash.py b/wrappers/swig/tests/hash.py deleted file mode 100644 index 930b8c81a..000000000 --- a/wrappers/swig/tests/hash.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/python - -import botan, base64, md5 - -class PyMD5(botan.HashFunctionImpl): - def name(self): - return "PyMD5" - def update(self, input): - self.md5.update(input) - def final(self): - output = self.md5.digest() - self.md5 = md5.new() - return output - def __init__(self): - botan.HashFunctionImpl.__init__(self, 16, 64) - self.md5 = md5.new() - -hash = botan.HashFunction("SHA-256") - -print hash.name() -print hash.digest_size - -hash.update("hi") -hash.update(" ") -hash.update("chappy") -print base64.b16encode(hash.final()) - -hash2 = PyMD5() -hash2.update("hi chappy") -print base64.b16encode(hash2.final()) diff --git a/wrappers/swig/tests/mac.py b/wrappers/swig/tests/mac.py deleted file mode 100644 index 6110b6102..000000000 --- a/wrappers/swig/tests/mac.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/python - -import botan, base64 - -mac = botan.MAC("HMAC(SHA-512)") - -print mac.name -print mac.output_length - -mac.set_key(botan.SymmetricKey("abcd")) -mac.update("hi chappy") -print base64.b16encode(mac.final()) diff --git a/wrappers/swig/tests/pubkey.py b/wrappers/swig/tests/pubkey.py deleted file mode 100644 index 456c52069..000000000 --- a/wrappers/swig/tests/pubkey.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/python - -import botan - -key = botan.X509_PublicKey("rsapub.pem") -print key -print key.key_id() -print key.max_input_bits -print key.algo -print key.oid diff --git a/wrappers/swig/tests/stream.py b/wrappers/swig/tests/stream.py deleted file mode 100644 index 59d3ffa16..000000000 --- a/wrappers/swig/tests/stream.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/python - -import botan, base64 - -cipher = botan.StreamCipher("ARC4") - -print cipher.name - -key = botan.SymmetricKey(16) - -cipher.set_key(key) -ciphertext = cipher.crypt("hi chappy") - -cipher.set_key(key) -plaintext = cipher.crypt(ciphertext) - -print plaintext diff --git a/wrappers/swig/x509.swg b/wrappers/swig/x509.swg deleted file mode 100644 index 736d3a385..000000000 --- a/wrappers/swig/x509.swg +++ /dev/null @@ -1,9 +0,0 @@ -%module botan - -class X509_Certificate - { - public: - - - private: - }; -- cgit v1.2.3 From 7f7b68d60b1286be70c07b315ed64cd9dfa48943 Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 9 Oct 2009 18:29:36 +0000 Subject: Use -Wno-write-strings in XS wrapper to avoid many warnings --- src/wrap/perl-xs/Makefile.PL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wrap/perl-xs/Makefile.PL b/src/wrap/perl-xs/Makefile.PL index d35c99168..46317e72b 100644 --- a/src/wrap/perl-xs/Makefile.PL +++ b/src/wrap/perl-xs/Makefile.PL @@ -9,7 +9,7 @@ if ( $^O eq 'MSWin32' ) else { $cc = 'g++'; - $cflags = '-fexceptions ' . qx( botan-config --cflags ); + $cflags = '-Wno-write-strings -fexceptions ' . qx( botan-config --cflags ); $libs = qx( botan-config --libs ); } -- cgit v1.2.3 From ebfa4f1f5d07857b1c000f36c8f8cea0984db121 Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 9 Oct 2009 18:48:11 +0000 Subject: Fix python install target. Add CryptoBox wrapper plus an example --- doc/log.txt | 1 + doc/python/cryptobox.py | 34 ++++++++++++++++++++++++++++++++++ src/build-data/makefile/python.in | 2 +- src/wrap/python/core.cpp | 24 ++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100755 doc/python/cryptobox.py (limited to 'src') diff --git a/doc/log.txt b/doc/log.txt index 883c3dabe..3dac507ca 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -1,5 +1,6 @@ * 1.9.1-pre, 2009-??-?? + - Better support for Python and Perl wrappers - Add an implementation of Blue Midnight Wish (Round 2 tweak version) - Add threshold secret sharing (draft-mcgrew-tss-02) - Add runtime cpu feature detection for x86/x86-64 diff --git a/doc/python/cryptobox.py b/doc/python/cryptobox.py new file mode 100755 index 000000000..1968b40e1 --- /dev/null +++ b/doc/python/cryptobox.py @@ -0,0 +1,34 @@ +#!/usr/bin/python + +import sys +import botan + +def main(args = None): + if args is None: + args = sys.argv + + if len(args) != 3: + raise Exception("Bad usage") + + password = args[1] + input = ''.join(open(args[2]).readlines()) + + rng = botan.RandomNumberGenerator() + + ciphertext = botan.cryptobox_encrypt(input, password, rng) + + print ciphertext + + plaintext = '' + + try: + plaintext = botan.cryptobox_decrypt(ciphertext, password + 'FAIL') + except Exception, e: + print "Oops -- ", e + + plaintext = botan.cryptobox_decrypt(ciphertext, password) + + print plaintext + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/build-data/makefile/python.in b/src/build-data/makefile/python.in index ee95f8d78..9658c70ce 100644 --- a/src/build-data/makefile/python.in +++ b/src/build-data/makefile/python.in @@ -2,7 +2,7 @@ CXX = g++ PYTHON_ROOT = /usr/lib/python%{python_version}/config PYTHON_INC = -I/usr/include/python%{python_version} -PYTHON_SITE_PACKAGE_DIR = /tmp/usr/lib/python%{python_version}/site-packages/ +PYTHON_SITE_PACKAGE_DIR = /usr/lib/python%{python_version}/site-packages/ PYTHON_FLAGS = -Isrc/wrap/python -Os -fPIC -ftemplate-depth-255 -Wall -Wno-unused $(PYTHON_INC) diff --git a/src/wrap/python/core.cpp b/src/wrap/python/core.cpp index 1992e3d61..59df863de 100644 --- a/src/wrap/python/core.cpp +++ b/src/wrap/python/core.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using namespace Botan; #include "python_botan.h" @@ -33,6 +34,7 @@ class Python_RandomNumberGenerator void add_entropy(const std::string& in) { rng->add_entropy(reinterpret_cast(in.c_str()), in.length()); } + RandomNumberGenerator& get_underlying_rng() { return *rng; } private: RandomNumberGenerator* rng; }; @@ -163,6 +165,25 @@ class Py_MAC MessageAuthenticationCode* mac; }; +std::string cryptobox_encrypt(const std::string& in, + const std::string& passphrase, + Python_RandomNumberGenerator& rng) + { + const byte* in_bytes = reinterpret_cast(in.data()); + + return CryptoBox::encrypt(in_bytes, in.size(), + passphrase, rng.get_underlying_rng()); + } + +std::string cryptobox_decrypt(const std::string& in, + const std::string& passphrase) + { + const byte* in_bytes = reinterpret_cast(in.data()); + + return CryptoBox::decrypt(in_bytes, in.size(), + passphrase); + } + BOOST_PYTHON_MODULE(_botan) { python::class_("LibraryInitializer") @@ -197,6 +218,9 @@ BOOST_PYTHON_MODULE(_botan) .def("name", &Py_MAC::name) .def("output_length", &Py_MAC::output_length); + python::def("cryptobox_encrypt", cryptobox_encrypt); + python::def("cryptobox_decrypt", cryptobox_decrypt); + export_filters(); export_pk(); export_x509(); -- cgit v1.2.3 From 9db719642349bc37126dee4b2837d3bba022d734 Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 9 Oct 2009 22:28:02 +0000 Subject: Reasonably functional RSA support; keygen, import/export, encrypt/decrypt, sign/verify --- src/pubkey/rsa/rsa.h | 8 +- src/wrap/python/core.cpp | 30 +------ src/wrap/python/pk.cpp | 125 -------------------------- src/wrap/python/python_botan.h | 30 ++++++- src/wrap/python/rsa.cpp | 194 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 231 insertions(+), 156 deletions(-) delete mode 100644 src/wrap/python/pk.cpp create mode 100644 src/wrap/python/rsa.cpp (limited to 'src') diff --git a/src/pubkey/rsa/rsa.h b/src/pubkey/rsa/rsa.h index f07533a4f..0580fe8eb 100644 --- a/src/pubkey/rsa/rsa.h +++ b/src/pubkey/rsa/rsa.h @@ -28,7 +28,13 @@ class BOTAN_DLL RSA_PublicKey : public PK_Encrypting_Key, SecureVector verify(const byte[], u32bit) const; RSA_PublicKey() {} - RSA_PublicKey(const BigInt&, const BigInt&); + + /** + * Create a RSA_PublicKey + * @arg n the modulus + * @arg e the exponent + */ + RSA_PublicKey(const BigInt& n, const BigInt& e); protected: BigInt public_op(const BigInt&) const; }; diff --git a/src/wrap/python/core.cpp b/src/wrap/python/core.cpp index 59df863de..40af71ecf 100644 --- a/src/wrap/python/core.cpp +++ b/src/wrap/python/core.cpp @@ -11,34 +11,6 @@ using namespace Botan; #include "python_botan.h" -class Python_RandomNumberGenerator - { - public: - Python_RandomNumberGenerator() - { rng = RandomNumberGenerator::make_rng(); } - ~Python_RandomNumberGenerator() { delete rng; } - - std::string name() const { return rng->name(); } - - void reseed() { rng->reseed(192); } - - int gen_random_byte() { return rng->next_byte(); } - - std::string gen_random(int n) - { - std::string s(n, 0); - rng->randomize(reinterpret_cast(&s[0]), n); - return s; - } - - void add_entropy(const std::string& in) - { rng->add_entropy(reinterpret_cast(in.c_str()), in.length()); } - - RandomNumberGenerator& get_underlying_rng() { return *rng; } - private: - RandomNumberGenerator* rng; - }; - class Py_Cipher { public: @@ -222,6 +194,6 @@ BOOST_PYTHON_MODULE(_botan) python::def("cryptobox_decrypt", cryptobox_decrypt); export_filters(); - export_pk(); + export_rsa(); export_x509(); } diff --git a/src/wrap/python/pk.cpp b/src/wrap/python/pk.cpp deleted file mode 100644 index 72d3294b8..000000000 --- a/src/wrap/python/pk.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/************************************************* -* Boost.Python module definition * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include -#include -#include -#include -using namespace Botan; - -#include -namespace python = boost::python; - -std::string encode_pub(const Public_Key* key, - const std::string& type) - { - if(type == "DER") - { - Pipe pipe; - pipe.start_msg(); - X509::encode(*key, pipe, RAW_BER); - pipe.end_msg(); - return pipe.read_all_as_string(); - } - else if(type == "PEM") - return X509::PEM_encode(*key); - else - throw Encoding_Error("Unknown key encoding method " + type); - } - -std::string encode_priv(const Private_Key* key, - const std::string& type) - { - if(type == "DER") - { - Pipe pipe; - PKCS8::encode(*key, pipe, RAW_BER); - return pipe.read_all_as_string(); - } - else if(type == "PEM") - return PKCS8::PEM_encode(*key); - else - throw Encoding_Error("Unknown key encoding method " + type); - } - -/* -Private_Key* load_priv(const std::string& file, const std::string& pass) - { - return PKCS8::load_key(file, pass); - } - -Public_Key* load_public(const std::string& file) - { - return X509::load_key(file); - } -*/ - -/* -std::string encrypt_string(const PK_Encryptor* enc, const std::string& in) - { - SecureVector cipher = enc->encrypt((const byte*)in.data(), in.length()); - return std::string((const char*)cipher.begin(), cipher.size()); - } - -std::string decrypt_string(const PK_Decryptor* dec, const std::string& in) - { - SecureVector plain = dec->decrypt((const byte*)in.data(), in.length()); - return std::string((const char*)plain.begin(), plain.size()); - } -*/ - -void export_pk() - { - /* - python::def("private_key", load_priv, - python::return_value_policy()); - python::def("public_key", load_public, - python::return_value_policy()); - */ - - python::class_ - ("Public_Key", python::no_init) - .add_property("name", &Public_Key::algo_name) - .add_property("max_input_bits", &Public_Key::max_input_bits) - .def("public_key", encode_pub); - - python::class_, boost::noncopyable> - ("PK_Encrypting_Key", python::no_init); - - python::class_, boost::noncopyable> - ("Private_Key", python::no_init) - .def("private_key", encode_priv); - - python::class_, boost::noncopyable> - ("PK_Decrypting_Key", python::no_init); - - python::class_ > - ("RSA_PublicKey", python::no_init); - - python::class_ > - ("DSA_PublicKey", python::no_init); - - /* - python::class_ > - ("RSA_PrivateKey", python::init()); - */ - - /* - python::class_ - ("PK_Encryptor", python::no_init) - .def("__init__", - python::make_constructor(get_pk_encryptor, - python::with_custodian_and_ward_postcall<0, 1>())) - .def("max_input", &PK_Encryptor::maximum_input_size) - .def("encrypt", encrypt_string); - */ - - /* - python::class_ - ("PK_Decryptor", python::no_init) - .def("__init__", python::make_constructor(get_pk_decryptor)) - .def("decrypt", decrypt_string); - */ - } diff --git a/src/wrap/python/python_botan.h b/src/wrap/python/python_botan.h index 18c51dbb1..646c2e2c1 100644 --- a/src/wrap/python/python_botan.h +++ b/src/wrap/python/python_botan.h @@ -11,7 +11,7 @@ using namespace Botan; namespace python = boost::python; extern void export_filters(); -extern void export_pk(); +extern void export_rsa(); extern void export_x509(); class Bad_Size : public Exception @@ -48,4 +48,32 @@ inline python::object get_owner(T* me) python::borrowed(python::detail::wrapper_base_::get_owner(*me)))); } +class Python_RandomNumberGenerator + { + public: + Python_RandomNumberGenerator() + { rng = RandomNumberGenerator::make_rng(); } + ~Python_RandomNumberGenerator() { delete rng; } + + std::string name() const { return rng->name(); } + + void reseed() { rng->reseed(192); } + + int gen_random_byte() { return rng->next_byte(); } + + std::string gen_random(int n) + { + std::string s(n, 0); + rng->randomize(reinterpret_cast(&s[0]), n); + return s; + } + + void add_entropy(const std::string& in) + { rng->add_entropy(reinterpret_cast(in.c_str()), in.length()); } + + RandomNumberGenerator& get_underlying_rng() { return *rng; } + private: + RandomNumberGenerator* rng; + }; + #endif diff --git a/src/wrap/python/rsa.cpp b/src/wrap/python/rsa.cpp new file mode 100644 index 000000000..895725384 --- /dev/null +++ b/src/wrap/python/rsa.cpp @@ -0,0 +1,194 @@ +/* +* Boost.Python module definition +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include +#include +using namespace Botan; + +#include "python_botan.h" +#include + +std::string bigint2str(const BigInt& n) + { + std::ostringstream out; + out << n; + return out.str(); + } + +std::string secvec2str(const MemoryRegion& vec) + { + std::string str(vec.size(), 0); + memcpy(&str[0], vec.begin(), vec.size()); + return str; + } + +class Py_RSA_PrivateKey + { + public: + Py_RSA_PrivateKey(std::string pem_str, + Python_RandomNumberGenerator& rng, + std::string pass); + + Py_RSA_PrivateKey(u32bit bits, Python_RandomNumberGenerator& rng); + ~Py_RSA_PrivateKey() { delete rsa_key; } + + std::string to_string() const + { + return PKCS8::PEM_encode(*rsa_key); + } + + std::string get_N() const { return bigint2str(get_bigint_N()); } + std::string get_E() const { return bigint2str(get_bigint_E()); } + + const BigInt& get_bigint_N() const { return rsa_key->get_n(); } + const BigInt& get_bigint_E() const { return rsa_key->get_e(); } + + std::string decrypt(const std::string& in, + const std::string& padding); + + std::string sign(const std::string& in, + const std::string& padding, + Python_RandomNumberGenerator& rng); + private: + RSA_PrivateKey* rsa_key; + }; + +std::string Py_RSA_PrivateKey::decrypt(const std::string& in, + const std::string& padding) + { + std::auto_ptr enc(get_pk_decryptor(*rsa_key, padding)); + + const byte* in_bytes = reinterpret_cast(in.data()); + + return secvec2str(enc->decrypt(in_bytes, in.size())); + } + +std::string Py_RSA_PrivateKey::sign(const std::string& in, + const std::string& padding, + Python_RandomNumberGenerator& rng) + { + std::auto_ptr sign(get_pk_signer(*rsa_key, padding)); + const byte* in_bytes = reinterpret_cast(in.data()); + sign->update(in_bytes, in.size()); + return secvec2str(sign->signature(rng.get_underlying_rng())); + } + +Py_RSA_PrivateKey::Py_RSA_PrivateKey(u32bit bits, + Python_RandomNumberGenerator& rng) + { + rsa_key = new RSA_PrivateKey(rng.get_underlying_rng(), bits); + } + +Py_RSA_PrivateKey::Py_RSA_PrivateKey(std::string pem_str, + Python_RandomNumberGenerator& rng, + std::string passphrase) + { + DataSource_Memory in(pem_str); + + Private_Key* pkcs8_key = + PKCS8::load_key(in, + rng.get_underlying_rng(), + passphrase); + + rsa_key = dynamic_cast(pkcs8_key); + + if(!rsa_key) + throw std::invalid_argument("Key is not an RSA key"); + } + +class Py_RSA_PublicKey + { + public: + Py_RSA_PublicKey(std::string pem_str); + Py_RSA_PublicKey(const Py_RSA_PrivateKey&); + ~Py_RSA_PublicKey() { delete rsa_key; } + + std::string get_N() const { return bigint2str(get_bigint_N()); } + std::string get_E() const { return bigint2str(get_bigint_E()); } + + const BigInt& get_bigint_N() const { return rsa_key->get_n(); } + const BigInt& get_bigint_E() const { return rsa_key->get_e(); } + + std::string to_string() const + { + return X509::PEM_encode(*rsa_key); + } + + std::string encrypt(const std::string& in, + const std::string& padding, + Python_RandomNumberGenerator& rng); + + bool verify(const std::string& in, + const std::string& padding, + const std::string& signature); + private: + RSA_PublicKey* rsa_key; + }; + +Py_RSA_PublicKey::Py_RSA_PublicKey(const Py_RSA_PrivateKey& priv) + { + rsa_key = new RSA_PublicKey(priv.get_bigint_N(), priv.get_bigint_E()); + } + +Py_RSA_PublicKey::Py_RSA_PublicKey(std::string pem_str) + { + DataSource_Memory in(pem_str); + Public_Key* x509_key = X509::load_key(in); + + rsa_key = dynamic_cast(x509_key); + + if(!rsa_key) + throw std::invalid_argument("Key is not an RSA key"); + } + +std::string Py_RSA_PublicKey::encrypt(const std::string& in, + const std::string& padding, + Python_RandomNumberGenerator& rng) + { + std::auto_ptr enc(get_pk_encryptor(*rsa_key, padding)); + + const byte* in_bytes = reinterpret_cast(in.data()); + + return secvec2str(enc->encrypt(in_bytes, in.size(), + rng.get_underlying_rng())); + } + +bool Py_RSA_PublicKey::verify(const std::string& in, + const std::string& signature, + const std::string& padding) + { + std::auto_ptr ver(get_pk_verifier(*rsa_key, padding)); + + const byte* in_bytes = reinterpret_cast(in.data()); + const byte* sig_bytes = reinterpret_cast(signature.data()); + + ver->update(in_bytes, in.size()); + return ver->check_signature(sig_bytes, signature.size()); + } + +void export_rsa() + { + python::class_ + ("RSA_PublicKey", python::init()) + .def(python::init()) + .def("to_string", &Py_RSA_PublicKey::to_string) + .def("encrypt", &Py_RSA_PublicKey::encrypt) + .def("verify", &Py_RSA_PublicKey::verify) + .def("get_N", &Py_RSA_PublicKey::get_N) + .def("get_E", &Py_RSA_PublicKey::get_E); + + python::class_ + ("RSA_PrivateKey", python::init()) + .def(python::init()) + .def("to_string", &Py_RSA_PrivateKey::to_string) + .def("decrypt", &Py_RSA_PrivateKey::decrypt) + .def("sign", &Py_RSA_PrivateKey::sign) + .def("get_N", &Py_RSA_PrivateKey::get_N) + .def("get_E", &Py_RSA_PrivateKey::get_E); + } -- cgit v1.2.3 From f87c490937dcd6a2e9affc72d4121e7d5daa5eee Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 9 Oct 2009 22:38:46 +0000 Subject: Add PBKDF2 wrapper --- src/wrap/python/core.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src') diff --git a/src/wrap/python/core.cpp b/src/wrap/python/core.cpp index 40af71ecf..fe26e16ee 100644 --- a/src/wrap/python/core.cpp +++ b/src/wrap/python/core.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include using namespace Botan; #include "python_botan.h" @@ -156,6 +158,20 @@ std::string cryptobox_decrypt(const std::string& in, passphrase); } +std::string python_pbkdf2(const std::string& passphrase, + const std::string& salt, + u32bit iterations, + u32bit output_size, + const std::string& hash_fn) + { + PKCS5_PBKDF2 pbkdf2(new HMAC(get_hash(hash_fn))); + + pbkdf2.set_iterations(iterations); + pbkdf2.change_salt(reinterpret_cast(salt.data()), salt.size()); + + return make_string(pbkdf2.derive_key(output_size, passphrase).bits_of()); + } + BOOST_PYTHON_MODULE(_botan) { python::class_("LibraryInitializer") @@ -192,6 +208,7 @@ BOOST_PYTHON_MODULE(_botan) python::def("cryptobox_encrypt", cryptobox_encrypt); python::def("cryptobox_decrypt", cryptobox_decrypt); + python::def("pbkdf2", python_pbkdf2); export_filters(); export_rsa(); -- cgit v1.2.3 From 9e6720cceee1429658175c92cc8edf101ab4a4b3 Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 9 Oct 2009 22:38:57 +0000 Subject: Remove redundant function --- src/wrap/python/rsa.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/wrap/python/rsa.cpp b/src/wrap/python/rsa.cpp index 895725384..900c3f93d 100644 --- a/src/wrap/python/rsa.cpp +++ b/src/wrap/python/rsa.cpp @@ -21,13 +21,6 @@ std::string bigint2str(const BigInt& n) return out.str(); } -std::string secvec2str(const MemoryRegion& vec) - { - std::string str(vec.size(), 0); - memcpy(&str[0], vec.begin(), vec.size()); - return str; - } - class Py_RSA_PrivateKey { public: @@ -66,7 +59,7 @@ std::string Py_RSA_PrivateKey::decrypt(const std::string& in, const byte* in_bytes = reinterpret_cast(in.data()); - return secvec2str(enc->decrypt(in_bytes, in.size())); + return make_string(enc->decrypt(in_bytes, in.size())); } std::string Py_RSA_PrivateKey::sign(const std::string& in, @@ -76,7 +69,7 @@ std::string Py_RSA_PrivateKey::sign(const std::string& in, std::auto_ptr sign(get_pk_signer(*rsa_key, padding)); const byte* in_bytes = reinterpret_cast(in.data()); sign->update(in_bytes, in.size()); - return secvec2str(sign->signature(rng.get_underlying_rng())); + return make_string(sign->signature(rng.get_underlying_rng())); } Py_RSA_PrivateKey::Py_RSA_PrivateKey(u32bit bits, @@ -155,7 +148,7 @@ std::string Py_RSA_PublicKey::encrypt(const std::string& in, const byte* in_bytes = reinterpret_cast(in.data()); - return secvec2str(enc->encrypt(in_bytes, in.size(), + return make_string(enc->encrypt(in_bytes, in.size(), rng.get_underlying_rng())); } -- cgit v1.2.3 From 0b23f4071f21564fb63d7b11768070658c4b8f77 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 13 Oct 2009 19:45:56 +0000 Subject: Check for cipher_mode() being set; if it is, not an algo_factory algo --- src/algo_factory/algo_factory.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/algo_factory/algo_factory.cpp b/src/algo_factory/algo_factory.cpp index 3523b19d4..22915d97c 100644 --- a/src/algo_factory/algo_factory.cpp +++ b/src/algo_factory/algo_factory.cpp @@ -62,6 +62,10 @@ const T* factory_prototype(const std::string& algo_spec, return cache_hit; SCAN_Name scan_name(algo_spec); + + if(scan_name.cipher_mode() != "") + return 0; + for(u32bit i = 0; i != engines.size(); ++i) { if(provider == "" || engines[i]->provider_name() == provider) -- cgit v1.2.3 From 09a17201a8132f8422a4c371cf1e56553317bc66 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 14 Oct 2009 22:35:03 +0000 Subject: Cleanups/random changes in the stream cipher code: Remove encrypt, decrypt - replace by cipher() and cipher1() Remove seek() - not well supported/tested, I want to redo with a new interface once CTR and OFB modes become stream ciphers. Rename resync to set_iv() Remove StreamCipher::IV_LENGTH and add StreamCipher::valid_iv_length() to allow multiple IV lengths (as for instance Turing allows, as would Salsa20 if XSalsa20 were supported). --- src/benchmark/benchmark.cpp | 2 +- src/block/lion/lion.cpp | 8 ++--- src/filters/algo_filt.cpp | 4 +-- src/filters/filters.h | 14 ++------- src/stream/arc4/arc4.h | 5 ++- src/stream/info.txt | 1 - src/stream/salsa20/salsa20.cpp | 8 ++--- src/stream/salsa20/salsa20.h | 12 ++++--- src/stream/stream_cipher.cpp | 30 ------------------ src/stream/stream_cipher.h | 67 ++++++++++++++++------------------------ src/stream/turing/turing.cpp | 6 ++-- src/stream/turing/turing.h | 8 +++-- src/stream/wid_wake/wid_wake.cpp | 9 +++--- src/stream/wid_wake/wid_wake.h | 10 ++++-- 14 files changed, 73 insertions(+), 111 deletions(-) delete mode 100644 src/stream/stream_cipher.cpp (limited to 'src') diff --git a/src/benchmark/benchmark.cpp b/src/benchmark/benchmark.cpp index 6e61baa59..41c9cd10c 100644 --- a/src/benchmark/benchmark.cpp +++ b/src/benchmark/benchmark.cpp @@ -85,7 +85,7 @@ bench_stream_cipher(StreamCipher* stream_cipher, while(nanoseconds_used < nanoseconds_max) { - stream_cipher->encrypt(buf, buf_len); + stream_cipher->cipher1(buf, buf_len); ++reps; nanoseconds_used = timer.clock() - start; } diff --git a/src/block/lion/lion.cpp b/src/block/lion/lion.cpp index 83c1e3aa3..0ed7b2630 100644 --- a/src/block/lion/lion.cpp +++ b/src/block/lion/lion.cpp @@ -22,7 +22,7 @@ void Lion::encrypt_n(const byte in[], byte out[], u32bit blocks) const { xor_buf(buffer, in, key1, LEFT_SIZE); cipher->set_key(buffer, LEFT_SIZE); - cipher->encrypt(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); + cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); hash->update(out + LEFT_SIZE, RIGHT_SIZE); hash->final(buffer); @@ -30,7 +30,7 @@ void Lion::encrypt_n(const byte in[], byte out[], u32bit blocks) const xor_buf(buffer, out, key2, LEFT_SIZE); cipher->set_key(buffer, LEFT_SIZE); - cipher->encrypt(out + LEFT_SIZE, RIGHT_SIZE); + cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE); in += BLOCK_SIZE; out += BLOCK_SIZE; @@ -48,7 +48,7 @@ void Lion::decrypt_n(const byte in[], byte out[], u32bit blocks) const { xor_buf(buffer, in, key2, LEFT_SIZE); cipher->set_key(buffer, LEFT_SIZE); - cipher->encrypt(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); + cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); hash->update(out + LEFT_SIZE, RIGHT_SIZE); hash->final(buffer); @@ -56,7 +56,7 @@ void Lion::decrypt_n(const byte in[], byte out[], u32bit blocks) const xor_buf(buffer, out, key1, LEFT_SIZE); cipher->set_key(buffer, LEFT_SIZE); - cipher->encrypt(out + LEFT_SIZE, RIGHT_SIZE); + cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE); in += BLOCK_SIZE; out += BLOCK_SIZE; diff --git a/src/filters/algo_filt.cpp b/src/filters/algo_filt.cpp index 3268276a6..9a469b2d8 100644 --- a/src/filters/algo_filt.cpp +++ b/src/filters/algo_filt.cpp @@ -47,7 +47,7 @@ StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name, */ void StreamCipher_Filter::set_iv(const InitializationVector& iv) { - cipher->resync(iv.begin(), iv.length()); + cipher->set_iv(iv.begin(), iv.length()); } /* @@ -58,7 +58,7 @@ void StreamCipher_Filter::write(const byte input[], u32bit length) while(length) { u32bit copied = std::min(length, buffer.size()); - cipher->encrypt(input, buffer, copied); + cipher->cipher(input, buffer, copied); send(buffer, copied); input += copied; length -= copied; diff --git a/src/filters/filters.h b/src/filters/filters.h index 964be0bd8..418caf0aa 100644 --- a/src/filters/filters.h +++ b/src/filters/filters.h @@ -44,18 +44,8 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter */ void write(const byte input[], u32bit input_len); - /** - * Seek in the stream. - * @param position the position to seek ahead - */ - void seek(u32bit position) { cipher->seek(position); } - - /** - * Find out whether the cipher underlying this filter supports - * resyncing. - * @return true if the cipher supports resyncing - */ - bool supports_resync() const { return (cipher->IV_LENGTH != 0); } + bool valid_iv_length(u32bit iv_len) + { return cipher->valid_iv_length(iv_len); } /** * Set the initialization vector for this filter. diff --git a/src/stream/arc4/arc4.h b/src/stream/arc4/arc4.h index aa2cea7fe..3f92fa914 100644 --- a/src/stream/arc4/arc4.h +++ b/src/stream/arc4/arc4.h @@ -19,13 +19,16 @@ namespace Botan { class BOTAN_DLL ARC4 : public StreamCipher { public: + void cipher(const byte in[], byte out[], u32bit length); + void clear() throw(); std::string name() const; + StreamCipher* clone() const { return new ARC4(SKIP); } + ARC4(u32bit = 0); ~ARC4() { clear(); } private: - void cipher(const byte[], byte[], u32bit); void key_schedule(const byte[], u32bit); void generate(); diff --git a/src/stream/info.txt b/src/stream/info.txt index 295c73708..f8f4b22d5 100644 --- a/src/stream/info.txt +++ b/src/stream/info.txt @@ -6,7 +6,6 @@ define STREAM_CIPHER stream_cipher.h -stream_cipher.cpp diff --git a/src/stream/salsa20/salsa20.cpp b/src/stream/salsa20/salsa20.cpp index 9c7c811f0..a147cdb45 100644 --- a/src/stream/salsa20/salsa20.cpp +++ b/src/stream/salsa20/salsa20.cpp @@ -162,15 +162,15 @@ void Salsa20::key_schedule(const byte key[], u32bit length) } const byte ZERO[8] = { 0 }; - resync(ZERO, sizeof(ZERO)); + set_iv(ZERO, sizeof(ZERO)); } /* * Return the name of this type */ -void Salsa20::resync(const byte iv[], u32bit length) +void Salsa20::set_iv(const byte iv[], u32bit length) { - if(length != IV_LENGTH) + if(!valid_iv_length(length)) throw Invalid_IV_Length(name(), length); state[6] = load_le(iv, 0); @@ -207,7 +207,7 @@ void Salsa20::clear() throw() /* * Salsa20 Constructor */ -Salsa20::Salsa20() : StreamCipher(16, 32, 16, 8) +Salsa20::Salsa20() : StreamCipher(16, 32, 16) { clear(); } diff --git a/src/stream/salsa20/salsa20.h b/src/stream/salsa20/salsa20.h index 3dbfddb50..a3e9a3706 100644 --- a/src/stream/salsa20/salsa20.h +++ b/src/stream/salsa20/salsa20.h @@ -18,17 +18,21 @@ namespace Botan { class BOTAN_DLL Salsa20 : public StreamCipher { public: + void cipher(const byte in[], byte out[], u32bit length); + + void set_iv(const byte iv[], u32bit iv_len); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == 8); } + void clear() throw(); std::string name() const; StreamCipher* clone() const { return new Salsa20; } - void resync(const byte[], u32bit); - Salsa20(); ~Salsa20() { clear(); } private: - void cipher(const byte[], byte[], u32bit); - void key_schedule(const byte[], u32bit); + void key_schedule(const byte key[], u32bit key_len); SecureBuffer state; diff --git a/src/stream/stream_cipher.cpp b/src/stream/stream_cipher.cpp deleted file mode 100644 index 68bb5d4f0..000000000 --- a/src/stream/stream_cipher.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/** -* Stream Cipher Default Implementation for IV and Seek -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Default StreamCipher Resync Operation -*/ -void StreamCipher::resync(const byte[], u32bit length) - { - if(length) - throw Exception("The stream cipher " + name() + - " does not support resyncronization"); - } - -/* -* Default StreamCipher Seek Operation -*/ -void StreamCipher::seek(u32bit) - { - throw Exception("The stream cipher " + name() + " does not support seek()"); - } - -} diff --git a/src/stream/stream_cipher.h b/src/stream/stream_cipher.h index 8ea359131..d6abb37fc 100644 --- a/src/stream/stream_cipher.h +++ b/src/stream/stream_cipher.h @@ -18,53 +18,40 @@ namespace Botan { class BOTAN_DLL StreamCipher : public SymmetricAlgorithm { public: - const u32bit IV_LENGTH; - - /** - * Encrypt a message. - * @param i the plaintext - * @param o the byte array to hold the output, i.e. the ciphertext - * @param len the length of both i and o - */ - void encrypt(const byte i[], byte o[], u32bit len) { cipher(i, o, len); } - /** - * Decrypt a message. - * @param i the ciphertext to decrypt - * @param o the byte array to hold the output, i.e. the plaintext - * @param len the length of both i and o + * Encrypt or decrypt a message + * @param in the plaintext + * @param out the byte array to hold the output, i.e. the ciphertext + * @param len the length of both in and out in bytes */ - void decrypt(const byte i[], byte o[], u32bit len) { cipher(i, o, len); } + virtual void cipher(const byte in[], byte out[], u32bit len) = 0; /** - * Encrypt a message. - * @param in the plaintext as input, after the function has - * returned it will hold the ciphertext - - * @param len the length of in + * Encrypt or decrypt a message + * @param buf the plaintext / ciphertext + * @param len the length of buf in bytes */ - void encrypt(byte in[], u32bit len) { cipher(in, in, len); } - - /** - * Decrypt a message. - * @param in the ciphertext as input, after the function has - * returned it will hold the plaintext - * @param len the length of in - */ - void decrypt(byte in[], u32bit len) { cipher(in, in, len); } + void cipher1(byte buf[], u32bit len) + { cipher(buf, buf, len); } /** * Resync the cipher using the IV * @param iv the initialization vector * @param iv_len the length of the IV in bytes */ - virtual void resync(const byte iv[], u32bit iv_len); + virtual void set_iv(const byte[], u32bit iv_len) + { + if(iv_len) + throw Exception("The stream cipher " + name() + + " does not support resyncronization"); + } /** - * Seek ahead in the stream. - * @param len the length to seek ahead. + * @param iv_len the length of the IV in bytes + * @return if the length is valid for this algorithm */ - virtual void seek(u32bit len); + virtual bool valid_iv_length(u32bit iv_len) const + { return (iv_len == 0); } /** * Get a new object representing the same algorithm as *this @@ -76,15 +63,15 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm */ virtual void clear() throw() = 0; - StreamCipher(u32bit key_min, u32bit key_max = 0, - u32bit key_mod = 1, - u32bit iv_len = 0) : - SymmetricAlgorithm(key_min, key_max, key_mod), - IV_LENGTH(iv_len) {} + /** + * StreamCipher constructor + */ + StreamCipher(u32bit key_min, + u32bit key_max = 0, + u32bit key_mod = 1) : + SymmetricAlgorithm(key_min, key_max, key_mod) {} virtual ~StreamCipher() {} - private: - virtual void cipher(const byte[], byte[], u32bit) = 0; }; } diff --git a/src/stream/turing/turing.cpp b/src/stream/turing/turing.cpp index 1e2203480..8336a70a7 100644 --- a/src/stream/turing/turing.cpp +++ b/src/stream/turing/turing.cpp @@ -257,15 +257,15 @@ void Turing::key_schedule(const byte key[], u32bit length) S3[i] = (W3 & 0xFFFFFF00) | C3; } - resync(0, 0); + set_iv(0, 0); } /* * Resynchronization */ -void Turing::resync(const byte iv[], u32bit length) +void Turing::set_iv(const byte iv[], u32bit length) { - if(length % 4 != 0 || length > 16) + if(!valid_iv_length(length)) throw Invalid_IV_Length(name(), length); SecureVector IV(length / 4); diff --git a/src/stream/turing/turing.h b/src/stream/turing/turing.h index 455d3c612..59290f640 100644 --- a/src/stream/turing/turing.h +++ b/src/stream/turing/turing.h @@ -18,14 +18,18 @@ namespace Botan { class BOTAN_DLL Turing : public StreamCipher { public: + void cipher(const byte in[], byte out[], u32bit length); + void set_iv(const byte[], u32bit); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len % 4 == 0 && iv_len <= 16); } + void clear() throw(); std::string name() const { return "Turing"; } StreamCipher* clone() const { return new Turing; } Turing() : StreamCipher(4, 32, 4) { position = 0; } private: - void cipher(const byte[], byte[], u32bit); void key_schedule(const byte[], u32bit); - void resync(const byte[], u32bit); void generate(); static u32bit fixedS(u32bit); diff --git a/src/stream/wid_wake/wid_wake.cpp b/src/stream/wid_wake/wid_wake.cpp index 1dc0fd7f9..56f938fac 100644 --- a/src/stream/wid_wake/wid_wake.cpp +++ b/src/stream/wid_wake/wid_wake.cpp @@ -110,16 +110,17 @@ void WiderWake_41_BE::key_schedule(const byte key[], u32bit) T[X] = Z; position = 0; - const byte iv[8] = { 0 }; - resync(iv, 8); + + const byte ZEROS[8] = { 0 }; + set_iv(ZEROS, sizeof(ZEROS)); } /* * Resynchronization */ -void WiderWake_41_BE::resync(const byte iv[], u32bit length) +void WiderWake_41_BE::set_iv(const byte iv[], u32bit length) { - if(length != 8) + if(!valid_iv_length(length)) throw Invalid_IV_Length(name(), length); for(u32bit j = 0; j != 4; ++j) diff --git a/src/stream/wid_wake/wid_wake.h b/src/stream/wid_wake/wid_wake.h index 4720afdb2..a037a056e 100644 --- a/src/stream/wid_wake/wid_wake.h +++ b/src/stream/wid_wake/wid_wake.h @@ -18,14 +18,18 @@ namespace Botan { class BOTAN_DLL WiderWake_41_BE : public StreamCipher { public: + void cipher(const byte[], byte[], u32bit); + void set_iv(const byte[], u32bit); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == 8); } + void clear() throw(); std::string name() const { return "WiderWake4+1-BE"; } StreamCipher* clone() const { return new WiderWake_41_BE; } - WiderWake_41_BE() : StreamCipher(16, 16, 1, 8) {} + WiderWake_41_BE() : StreamCipher(16, 16, 1) {} private: - void cipher(const byte[], byte[], u32bit); void key_schedule(const byte[], u32bit); - void resync(const byte[], u32bit); void generate(u32bit); -- cgit v1.2.3 From 01ea6faf1b9fb3ccd7233b1117e09c642c22d238 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 14 Oct 2009 23:13:23 +0000 Subject: Convert CTR_BE from a Filter to a StreamCipher. Must wrap in a StreamCipher_Filter to pass it directly to a Pipe now. --- checks/validate.dat | 7 ++ src/aont/package.cpp | 14 +--- src/cryptobox/cryptobox.cpp | 7 +- src/engine/def_engine/def_mode.cpp | 6 +- src/filters/algo_filt.cpp | 19 ++++- src/filters/filters.h | 7 ++ src/modes/ctr/ctr.cpp | 146 ------------------------------------- src/modes/ctr/ctr.h | 46 ------------ src/modes/ctr/info.txt | 15 ---- src/stream/ctr/ctr.cpp | 141 +++++++++++++++++++++++++++++++++++ src/stream/ctr/ctr.h | 49 +++++++++++++ src/stream/ctr/info.txt | 15 ++++ 12 files changed, 243 insertions(+), 229 deletions(-) delete mode 100644 src/modes/ctr/ctr.cpp delete mode 100644 src/modes/ctr/ctr.h delete mode 100644 src/modes/ctr/info.txt create mode 100644 src/stream/ctr/ctr.cpp create mode 100644 src/stream/ctr/ctr.h create mode 100644 src/stream/ctr/info.txt (limited to 'src') diff --git a/checks/validate.dat b/checks/validate.dat index de9db0b89..1ea88bcf3 100644 --- a/checks/validate.dat +++ b/checks/validate.dat @@ -23655,6 +23655,13 @@ DC7E84BFDA79164B7ECD8486985D38604FEBDC6740D20B3AC88F6AD82A4FB08D\ 5AE4DF3EDBD5D35E5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE:\ 2B7E151628AED2A6ABF7158809CF4F3C:F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF +# Test with 15 byte IV (last byte implicit zero) +AE2D8A571E03AC9C9EB76FAC45AF8E51\ +30C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710:\ +9806F66B7970FDFF8617187BB9FFFDFF\ +5AE4DF3EDBD5D35E5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE:\ +2B7E151628AED2A6ABF7158809CF4F3C:F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF + 6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E51\ 30C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710:\ 1ABC932417521CA24F2B0459FE7E6E0B090339EC0AA6FAEFD5CCC2C6F4CE8E94\ diff --git a/src/aont/package.cpp b/src/aont/package.cpp index 6c6b56865..37bad46c8 100644 --- a/src/aont/package.cpp +++ b/src/aont/package.cpp @@ -7,7 +7,7 @@ */ #include -#include +#include #include #include #include @@ -29,12 +29,7 @@ void package(RandomNumberGenerator& rng, SymmetricKey package_key(rng, cipher->BLOCK_SIZE); - // takes ownership of cipher object - Keyed_Filter* ctr_mode = new CTR_BE(cipher, - package_key, - InitializationVector(all_zeros)); - - Pipe pipe(ctr_mode); + Pipe pipe(new StreamCipher_Filter(new CTR_BE(cipher), package_key)); pipe.process_msg(input, input_len); pipe.read(output, pipe.remaining()); @@ -113,10 +108,7 @@ void unpackage(BlockCipher* cipher, xor_buf(&package_key[0], buf, cipher->BLOCK_SIZE); } - // takes ownership of cipher object - Pipe pipe(new CTR_BE(cipher, - SymmetricKey(package_key), - InitializationVector(all_zeros))); + Pipe pipe(new StreamCipher_Filter(new CTR_BE(cipher), package_key)); pipe.process_msg(input, input_len - cipher->BLOCK_SIZE); diff --git a/src/cryptobox/cryptobox.cpp b/src/cryptobox/cryptobox.cpp index c27bbaffa..ba7553c55 100644 --- a/src/cryptobox/cryptobox.cpp +++ b/src/cryptobox/cryptobox.cpp @@ -8,9 +8,8 @@ #include #include #include -#include +#include #include -#include #include #include #include @@ -59,7 +58,7 @@ std::string encrypt(const byte input[], u32bit input_len, InitializationVector iv(mk.begin() + CIPHER_KEY_LEN + MAC_KEY_LEN, CIPHER_IV_LEN); - Pipe pipe(new CTR_BE(new Serpent, cipher_key, iv), + Pipe pipe(get_cipher("Serpent/CTR-BE", cipher_key, iv, ENCRYPTION), new Fork( 0, new MAC_Filter(new HMAC(new SHA_512), @@ -121,7 +120,7 @@ std::string decrypt(const byte input[], u32bit input_len, CIPHER_IV_LEN); Pipe pipe(new Fork( - new CTR_BE(new Serpent, cipher_key, iv), + get_cipher("Serpent/CTR-BE", cipher_key, iv, ENCRYPTION), new MAC_Filter(new HMAC(new SHA_512), mac_key, MAC_OUTPUT_LEN))); diff --git a/src/engine/def_engine/def_mode.cpp b/src/engine/def_engine/def_mode.cpp index 0c7a1a2e2..120489b38 100644 --- a/src/engine/def_engine/def_mode.cpp +++ b/src/engine/def_engine/def_mode.cpp @@ -32,7 +32,7 @@ #include #endif -#if defined(BOTAN_HAS_CTR) +#if defined(BOTAN_HAS_CTR_BE) #include #endif @@ -84,9 +84,9 @@ Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher, return new OFB(block_cipher->clone()); #endif -#if defined(BOTAN_HAS_CTR) +#if defined(BOTAN_HAS_CTR_BE) if(mode == "CTR-BE") - return new CTR_BE(block_cipher->clone()); + return new StreamCipher_Filter(new CTR_BE(block_cipher->clone())); #endif #if defined(BOTAN_HAS_ECB) diff --git a/src/filters/algo_filt.cpp b/src/filters/algo_filt.cpp index 9a469b2d8..51bf92380 100644 --- a/src/filters/algo_filt.cpp +++ b/src/filters/algo_filt.cpp @@ -14,20 +14,31 @@ namespace Botan { /* * StreamCipher_Filter Constructor */ -StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : +StreamCipher_Filter::StreamCipher_Filter(StreamCipher* stream_cipher) : buffer(DEFAULT_BUFFERSIZE) { - Algorithm_Factory& af = global_state().algorithm_factory(); - cipher = af.make_stream_cipher(sc_name); + cipher = stream_cipher; } /* * StreamCipher_Filter Constructor */ -StreamCipher_Filter::StreamCipher_Filter(StreamCipher* stream_cipher) : +StreamCipher_Filter::StreamCipher_Filter(StreamCipher* stream_cipher, + const SymmetricKey& key) : buffer(DEFAULT_BUFFERSIZE) { cipher = stream_cipher; + cipher->set_key(key); + } + +/* +* StreamCipher_Filter Constructor +*/ +StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : + buffer(DEFAULT_BUFFERSIZE) + { + Algorithm_Factory& af = global_state().algorithm_factory(); + cipher = af.make_stream_cipher(sc_name); } /* diff --git a/src/filters/filters.h b/src/filters/filters.h index 418caf0aa..208332a56 100644 --- a/src/filters/filters.h +++ b/src/filters/filters.h @@ -73,6 +73,13 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter */ StreamCipher_Filter(StreamCipher* cipher_obj); + /** + * Construct a stream cipher filter. + * @param cipher_obj a cipher object to use + * @param key the key to use inside this filter + */ + StreamCipher_Filter(StreamCipher* cipher_obj, const SymmetricKey& key); + /** * Construct a stream cipher filter. * @param cipher the name of the desired cipher diff --git a/src/modes/ctr/ctr.cpp b/src/modes/ctr/ctr.cpp deleted file mode 100644 index d458d7848..000000000 --- a/src/modes/ctr/ctr.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* -* CTR Mode -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include - -namespace Botan { - -namespace { - -const u32bit PARALLEL_BLOCKS = BOTAN_PARALLEL_BLOCKS_CTR; - -} - -/* -* CTR-BE Constructor -*/ -CTR_BE::CTR_BE(BlockCipher* ciph) : cipher(ciph) - { - position = 0; - - counter.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS); - enc_buffer.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS); - } - -/* -* CTR-BE Constructor -*/ -CTR_BE::CTR_BE(BlockCipher* ciph, const SymmetricKey& key, - const InitializationVector& iv) : - cipher(ciph) - { - position = 0; - - counter.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS); - enc_buffer.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS); - - cipher->set_key(key); - set_iv(iv); - } - -/* -* CTR_BE Destructor -*/ -CTR_BE::~CTR_BE() - { - delete cipher; - } - -/* -* Return the name of this type -*/ -std::string CTR_BE::name() const - { - return ("CTR-BE/" + cipher->name()); - } - -/* -* Set CTR-BE IV -*/ -void CTR_BE::set_iv(const InitializationVector& iv) - { - const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; - - if(iv.length() != BLOCK_SIZE) - throw Invalid_IV_Length(name(), iv.length()); - - enc_buffer.clear(); - position = 0; - - counter.copy(0, iv.begin(), iv.length()); - - for(u32bit i = 1; i != PARALLEL_BLOCKS; ++i) - { - counter.copy(i*BLOCK_SIZE, - counter.begin() + (i-1)*BLOCK_SIZE, BLOCK_SIZE); - - for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j) - if(++counter[i*BLOCK_SIZE+j]) - break; - } - - cipher->encrypt_n(counter, enc_buffer, PARALLEL_BLOCKS); - } - -/* -* CTR-BE Encryption/Decryption -*/ -void CTR_BE::write(const byte input[], u32bit length) - { - u32bit copied = std::min(enc_buffer.size() - position, length); - xor_buf(enc_buffer + position, input, copied); - send(enc_buffer + position, copied); - input += copied; - length -= copied; - position += copied; - - if(position == enc_buffer.size()) - increment_counter(); - - while(length >= enc_buffer.size()) - { - xor_buf(enc_buffer, input, enc_buffer.size()); - send(enc_buffer, enc_buffer.size()); - - input += enc_buffer.size(); - length -= enc_buffer.size(); - increment_counter(); - } - - xor_buf(enc_buffer + position, input, length); - send(enc_buffer + position, length); - position += length; - } - -/* -* Increment the counter and update the buffer -*/ -void CTR_BE::increment_counter() - { - for(u32bit i = 0; i != PARALLEL_BLOCKS; ++i) - { - byte* this_ctr = counter + i*cipher->BLOCK_SIZE; - - byte last_byte = this_ctr[cipher->BLOCK_SIZE-1]; - last_byte += PARALLEL_BLOCKS; - - if(this_ctr[cipher->BLOCK_SIZE-1] > last_byte) - for(s32bit j = cipher->BLOCK_SIZE - 2; j >= 0; --j) - if(++this_ctr[j]) - break; - - this_ctr[cipher->BLOCK_SIZE-1] = last_byte; - } - - cipher->encrypt_n(counter, enc_buffer, PARALLEL_BLOCKS); - - position = 0; - } - -} diff --git a/src/modes/ctr/ctr.h b/src/modes/ctr/ctr.h deleted file mode 100644 index 1948ffe48..000000000 --- a/src/modes/ctr/ctr.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* CTR Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_COUNTER_MODE_H__ -#define BOTAN_COUNTER_MODE_H__ - -#include -#include - -namespace Botan { - -/* -* CTR-BE Mode -*/ -class BOTAN_DLL CTR_BE : public Keyed_Filter - { - public: - std::string name() const; - - void set_iv(const InitializationVector&); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(u32bit key_len) const - { return cipher->valid_keylength(key_len); } - - CTR_BE(BlockCipher*); - CTR_BE(BlockCipher*, const SymmetricKey&, const InitializationVector&); - - ~CTR_BE(); - private: - void write(const byte[], u32bit); - void increment_counter(); - - BlockCipher* cipher; - SecureVector counter, enc_buffer; - u32bit position; - }; - -} - -#endif diff --git a/src/modes/ctr/info.txt b/src/modes/ctr/info.txt deleted file mode 100644 index cb291a2c1..000000000 --- a/src/modes/ctr/info.txt +++ /dev/null @@ -1,15 +0,0 @@ -realname "CTR block cipher mode" - -define CTR - -load_on auto - - -ctr.cpp -ctr.h - - - -modes - - diff --git a/src/stream/ctr/ctr.cpp b/src/stream/ctr/ctr.cpp new file mode 100644 index 000000000..5ef5e447f --- /dev/null +++ b/src/stream/ctr/ctr.cpp @@ -0,0 +1,141 @@ +/* +* CTR-BE Mode Cipher +* (C) 1999-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include + +namespace Botan { + +/* +* CTR-BE Constructor +*/ + +CTR_BE::CTR_BE(BlockCipher* ciph) : + StreamCipher(ciph->MINIMUM_KEYLENGTH, + ciph->MAXIMUM_KEYLENGTH, + ciph->KEYLENGTH_MULTIPLE), + permutation(ciph) + { + position = 0; + + counter.create(permutation->BLOCK_SIZE * BOTAN_PARALLEL_BLOCKS_CTR); + buffer.create(permutation->BLOCK_SIZE * BOTAN_PARALLEL_BLOCKS_CTR); + } + +/* +* CTR_BE Destructor +*/ +CTR_BE::~CTR_BE() + { + delete permutation; + } + +/* +* Zeroize +*/ +void CTR_BE::clear() throw() + { + permutation->clear(); + buffer.clear(); + counter.clear(); + position = 0; + } + +/* +* Set the key +*/ +void CTR_BE::key_schedule(const byte key[], u32bit key_len) + { + permutation->set_key(key, key_len); + + // Set a default all-zeros IV + set_iv(0, 0); + } + +/* +* Return the name of this type +*/ +std::string CTR_BE::name() const + { + return ("CTR-BE(" + permutation->name() + ")"); + } + +/* +* CTR-BE Encryption/Decryption +*/ +void CTR_BE::cipher(const byte in[], byte out[], u32bit length) + { + while(length >= buffer.size() - position) + { + xor_buf(out, in, buffer.begin() + position, buffer.size() - position); + length -= (buffer.size() - position); + in += (buffer.size() - position); + out += (buffer.size() - position); + increment_counter(); + } + xor_buf(out, in, buffer.begin() + position, length); + position += length; + } + +/* +* Set CTR-BE IV +*/ +void CTR_BE::set_iv(const byte iv[], u32bit iv_len) + { + if(!valid_iv_length(iv_len)) + throw Invalid_IV_Length(name(), iv_len); + + const u32bit BLOCK_SIZE = permutation->BLOCK_SIZE; + + counter.clear(); + + counter.copy(0, iv, iv_len); + + const u32bit PARALLEL_BLOCKS = counter.size() / BLOCK_SIZE; + + for(u32bit i = 1; i != PARALLEL_BLOCKS; ++i) + { + counter.copy(i*BLOCK_SIZE, + counter.begin() + (i-1)*BLOCK_SIZE, BLOCK_SIZE); + + for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j) + if(++counter[i*BLOCK_SIZE+j]) + break; + } + + permutation->encrypt_n(counter, buffer, PARALLEL_BLOCKS); + position = 0; + } + +/* +* Increment the counter and update the buffer +*/ +void CTR_BE::increment_counter() + { + const u32bit PARALLEL_BLOCKS = counter.size() / permutation->BLOCK_SIZE; + + for(u32bit i = 0; i != PARALLEL_BLOCKS; ++i) + { + byte* this_ctr = counter + i*permutation->BLOCK_SIZE; + + byte last_byte = this_ctr[permutation->BLOCK_SIZE-1]; + last_byte += PARALLEL_BLOCKS; + + if(this_ctr[permutation->BLOCK_SIZE-1] > last_byte) + for(s32bit j = permutation->BLOCK_SIZE - 2; j >= 0; --j) + if(++this_ctr[j]) + break; + + this_ctr[permutation->BLOCK_SIZE-1] = last_byte; + } + + permutation->encrypt_n(counter, buffer, PARALLEL_BLOCKS); + + position = 0; + } + +} diff --git a/src/stream/ctr/ctr.h b/src/stream/ctr/ctr.h new file mode 100644 index 000000000..f60f21b5a --- /dev/null +++ b/src/stream/ctr/ctr.h @@ -0,0 +1,49 @@ +/* +* CTR-BE Mode +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_CTR_BE_H__ +#define BOTAN_CTR_BE_H__ + +#include +#include + +namespace Botan { + +/* +* CTR-BE (Counter, big-endian) +*/ +class BOTAN_DLL CTR_BE : public StreamCipher + { + public: + void cipher(const byte in[], byte out[], u32bit length); + + void set_iv(const byte iv[], u32bit iv_len); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len <= permutation->BLOCK_SIZE); } + + std::string name() const; + + CTR_BE* clone() const + { return new CTR_BE(permutation->clone()); } + + void clear() throw(); + + CTR_BE(BlockCipher*); + ~CTR_BE(); + private: + void key_schedule(const byte key[], u32bit key_len); + void increment_counter(); + + BlockCipher* permutation; + SecureVector counter, buffer; + u32bit position; + }; + +} + +#endif diff --git a/src/stream/ctr/info.txt b/src/stream/ctr/info.txt new file mode 100644 index 000000000..53ab0afa5 --- /dev/null +++ b/src/stream/ctr/info.txt @@ -0,0 +1,15 @@ +realname "CTR mode" + +define CTR_BE + +load_on auto + + +ctr.cpp +ctr.h + + + +stream + + -- cgit v1.2.3 From 1d54dbb30e97097ef74b302032430a97e56fb328 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 14 Oct 2009 23:23:29 +0000 Subject: Similiar treatment for OFB which is also just a plain stream cipher --- src/engine/def_engine/def_mode.cpp | 2 +- src/modes/ofb/info.txt | 14 ------ src/modes/ofb/ofb.cpp | 66 -------------------------- src/modes/ofb/ofb.h | 33 ------------- src/stream/ctr/info.txt | 1 + src/stream/ofb/info.txt | 15 ++++++ src/stream/ofb/ofb.cpp | 97 ++++++++++++++++++++++++++++++++++++++ src/stream/ofb/ofb.h | 48 +++++++++++++++++++ 8 files changed, 162 insertions(+), 114 deletions(-) delete mode 100644 src/modes/ofb/info.txt delete mode 100644 src/modes/ofb/ofb.cpp delete mode 100644 src/modes/ofb/ofb.h create mode 100644 src/stream/ofb/info.txt create mode 100644 src/stream/ofb/ofb.cpp create mode 100644 src/stream/ofb/ofb.h (limited to 'src') diff --git a/src/engine/def_engine/def_mode.cpp b/src/engine/def_engine/def_mode.cpp index 120489b38..b7373ef84 100644 --- a/src/engine/def_engine/def_mode.cpp +++ b/src/engine/def_engine/def_mode.cpp @@ -81,7 +81,7 @@ Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher, { #if defined(BOTAN_HAS_OFB) if(mode == "OFB") - return new OFB(block_cipher->clone()); + return new StreamCipher_Filter(new OFB(block_cipher->clone())); #endif #if defined(BOTAN_HAS_CTR_BE) diff --git a/src/modes/ofb/info.txt b/src/modes/ofb/info.txt deleted file mode 100644 index 3cba4151e..000000000 --- a/src/modes/ofb/info.txt +++ /dev/null @@ -1,14 +0,0 @@ -realname "OFB block cipher mode" - -define OFB - -load_on auto - - -ofb.cpp -ofb.h - - - -block - diff --git a/src/modes/ofb/ofb.cpp b/src/modes/ofb/ofb.cpp deleted file mode 100644 index cb40fdeaa..000000000 --- a/src/modes/ofb/ofb.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -* OFB Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include - -namespace Botan { - -/* -* OFB Constructor -*/ -OFB::OFB(BlockCipher* ciph) : - BlockCipherMode(ciph, "OFB", ciph->BLOCK_SIZE, 2) - { - } - -/* -* OFB Constructor -*/ -OFB::OFB(BlockCipher* ciph, const SymmetricKey& key, - const InitializationVector& iv) : - BlockCipherMode(ciph, "OFB", ciph->BLOCK_SIZE, 2) - { - set_key(key); - set_iv(iv); - } - -/* -* OFB Encryption/Decryption -*/ -void OFB::write(const byte input[], u32bit length) - { - u32bit copied = std::min(BLOCK_SIZE - position, length); - xor_buf(buffer, input, state + position, copied); - send(buffer, copied); - input += copied; - length -= copied; - position += copied; - - if(position == BLOCK_SIZE) - { - cipher->encrypt(state); - position = 0; - } - - while(length >= BLOCK_SIZE) - { - xor_buf(buffer, input, state, BLOCK_SIZE); - send(buffer, BLOCK_SIZE); - - input += BLOCK_SIZE; - length -= BLOCK_SIZE; - cipher->encrypt(state); - } - - xor_buf(buffer, input, state + position, length); - send(buffer, length); - position += length; - } - -} diff --git a/src/modes/ofb/ofb.h b/src/modes/ofb/ofb.h deleted file mode 100644 index a3aadc137..000000000 --- a/src/modes/ofb/ofb.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* OFB Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_OUTPUT_FEEDBACK_MODE_H__ -#define BOTAN_OUTPUT_FEEDBACK_MODE_H__ - -#include -#include - -namespace Botan { - -/* -* OFB Mode -*/ -class BOTAN_DLL OFB : public BlockCipherMode - { - public: - OFB(BlockCipher* cipher); - - OFB(BlockCipher* cipher, - const SymmetricKey& key, - const InitializationVector& iv); - private: - void write(const byte[], u32bit); - }; - -} - -#endif diff --git a/src/stream/ctr/info.txt b/src/stream/ctr/info.txt index 53ab0afa5..04d14518a 100644 --- a/src/stream/ctr/info.txt +++ b/src/stream/ctr/info.txt @@ -10,6 +10,7 @@ ctr.h +block stream diff --git a/src/stream/ofb/info.txt b/src/stream/ofb/info.txt new file mode 100644 index 000000000..444fe0ffe --- /dev/null +++ b/src/stream/ofb/info.txt @@ -0,0 +1,15 @@ +realname "OFB block cipher mode" + +define OFB + +load_on auto + + +ofb.cpp +ofb.h + + + +block +stream + diff --git a/src/stream/ofb/ofb.cpp b/src/stream/ofb/ofb.cpp new file mode 100644 index 000000000..577f61cbf --- /dev/null +++ b/src/stream/ofb/ofb.cpp @@ -0,0 +1,97 @@ +/* +* OFB Mode +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include + +namespace Botan { + +/* +* OFB Constructor +*/ +OFB::OFB(BlockCipher* ciph) : + StreamCipher(ciph->MINIMUM_KEYLENGTH, + ciph->MAXIMUM_KEYLENGTH, + ciph->KEYLENGTH_MULTIPLE), + permutation(ciph) + { + position = 0; + buffer.create(permutation->BLOCK_SIZE); + } + +/* +* OFB Destructor +*/ +OFB::~OFB() + { + delete permutation; + } + +/* +* Zeroize +*/ +void OFB::clear() throw() + { + permutation->clear(); + buffer.clear(); + position = 0; + } + +/* +* Set the key +*/ +void OFB::key_schedule(const byte key[], u32bit key_len) + { + permutation->set_key(key, key_len); + + // Set a default all-zeros IV + set_iv(0, 0); + } + +/* +* Return the name of this type +*/ +std::string OFB::name() const + { + return ("OFB(" + permutation->name() + ")"); + } + +/* +* CTR-BE Encryption/Decryption +*/ +void OFB::cipher(const byte in[], byte out[], u32bit length) + { + while(length >= buffer.size() - position) + { + xor_buf(out, in, buffer.begin() + position, buffer.size() - position); + length -= (buffer.size() - position); + in += (buffer.size() - position); + out += (buffer.size() - position); + permutation->encrypt(buffer); + position = 0; + } + xor_buf(out, in, buffer.begin() + position, length); + position += length; + } + +/* +* Set CTR-BE IV +*/ +void OFB::set_iv(const byte iv[], u32bit iv_len) + { + if(!valid_iv_length(iv_len)) + throw Invalid_IV_Length(name(), iv_len); + + buffer.clear(); + buffer.copy(0, iv, iv_len); + + permutation->encrypt(buffer); + position = 0; + } + +} diff --git a/src/stream/ofb/ofb.h b/src/stream/ofb/ofb.h new file mode 100644 index 000000000..5cd48716b --- /dev/null +++ b/src/stream/ofb/ofb.h @@ -0,0 +1,48 @@ +/* +* OFB Mode +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_OUTPUT_FEEDBACK_MODE_H__ +#define BOTAN_OUTPUT_FEEDBACK_MODE_H__ + +#include +#include + +namespace Botan { + +/* +* OFB Mode +*/ +class BOTAN_DLL OFB : public StreamCipher + { + public: + void cipher(const byte in[], byte out[], u32bit length); + + void set_iv(const byte iv[], u32bit iv_len); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len <= permutation->BLOCK_SIZE); } + + std::string name() const; + + OFB* clone() const + { return new OFB(permutation->clone()); } + + void clear() throw(); + + OFB(BlockCipher*); + ~OFB(); + private: + void key_schedule(const byte key[], u32bit key_len); + + BlockCipher* permutation; + SecureVector buffer; + u32bit position; + }; + +} + +#endif -- cgit v1.2.3 From da210a5de236583baa530d8500a3da9f80b635fd Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 15 Oct 2009 16:49:22 +0000 Subject: Avoid using word_add() in gfp_element.cpp, actually more complex than necessary, and was tickling a bug in the asm versions because of the constant 0. --- src/math/gfpmath/gfp_element.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/math/gfpmath/gfp_element.cpp b/src/math/gfpmath/gfp_element.cpp index f9e0b09c9..8ae9b3c3a 100644 --- a/src/math/gfpmath/gfp_element.cpp +++ b/src/math/gfpmath/gfp_element.cpp @@ -68,7 +68,9 @@ void inner_montg_mult_sos(word result[], const word* a_bar, const word* b_bar, c while (C > 0) { // we need not worry here about C > 1, because the other operand is zero - word tmp = word_add(t[i+s+cnt], 0, &C); + + word tmp = t[i+s+cnt] + C; + C = (tmp < t[i+s+cnt]); t[i+s+cnt] = tmp; cnt++; } -- cgit v1.2.3 From 5af082273a76205be07f510c3b82871ae88561fa Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 15 Oct 2009 16:49:51 +0000 Subject: Enable x86-64 asm word_add --- src/math/bigint/mp_amd64/mp_asmi.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src') diff --git a/src/math/bigint/mp_amd64/mp_asmi.h b/src/math/bigint/mp_amd64/mp_asmi.h index 8bccbaaf4..1a3ac1aaa 100644 --- a/src/math/bigint/mp_amd64/mp_asmi.h +++ b/src/math/bigint/mp_amd64/mp_asmi.h @@ -70,20 +70,12 @@ extern "C" { */ inline word word_add(word x, word y, word* carry) { -#if 0 asm( ADD_OR_SUBTRACT(ASM("adcq %[y],%[x]")) : [x]"=r"(x), [carry]"=r"(*carry) : "0"(x), [y]"rm"(y), "1"(*carry) : "cc"); return x; -#else - word z = x + y; - word c1 = (z < x); - z += *carry; - *carry = c1 | (z < *carry); - return z; -#endif } /* -- cgit v1.2.3 From 10db0e9d7d9bab7c3bf4e1560e04ae6b8ba5b8b3 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 15 Oct 2009 17:05:30 +0000 Subject: Also enable x86 asm word_add --- src/math/bigint/mp_ia32/mp_asmi.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src') diff --git a/src/math/bigint/mp_ia32/mp_asmi.h b/src/math/bigint/mp_ia32/mp_asmi.h index 28b99abcc..46bf302d5 100644 --- a/src/math/bigint/mp_ia32/mp_asmi.h +++ b/src/math/bigint/mp_ia32/mp_asmi.h @@ -70,20 +70,12 @@ extern "C" { */ inline word word_add(word x, word y, word* carry) { -#if 0 asm( ADD_OR_SUBTRACT(ASM("adcl %[y],%[x]")) : [x]"=r"(x), [carry]"=r"(*carry) : "0"(x), [y]"rm"(y), "1"(*carry) : "cc"); return x; -#else - word z = x + y; - word c1 = (z < x); - z += *carry; - *carry = c1 | (z < *carry); - return z; -#endif } /* -- cgit v1.2.3 From 32dc01dcdf042a3b7a32ce342c3420d15beea9d3 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 19 Oct 2009 20:19:23 +0000 Subject: Add theoreticaly support for Clang/LLVM. Current Gentoo clang ebuild doesn't seem to work with C++ at all so untested. --- src/build-data/cc/clang.txt | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/build-data/cc/clang.txt (limited to 'src') diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt new file mode 100644 index 000000000..480794faf --- /dev/null +++ b/src/build-data/cc/clang.txt @@ -0,0 +1,46 @@ +realname "Clang/LLVM" + +# Largely copied from the gcc config + +macro_name "CLANG" + +binary_name clang + +compile_option "-c " +output_to_option "-o " +add_include_dir_option "-I" +add_lib_dir_option "-L" +add_lib_option "-l" + +lang_flags "-D_REENTRANT -ansi -Wno-long-long" +warning_flags "-W -Wall" + +makefile_style unix + +lib_opt_flags "-O2" +check_opt_flags "-O2" +shared_flags "-fPIC" +debug_flags "-g" +no_debug_flags "-finline-functions" + + +# The default works for GNU ld and several other Unix linkers +default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" + + + +amd64 -> "-m64" +mips64 -> "-mabi=64" +s390 -> "-m31" +s390x -> "-m64" +sparc32 -> "-m32 -mno-app-regs" +sparc64 -> "-m64 -mno-app-regs" +ppc64 -> "-m64" + +# This should probably be used on most/all targets, but the docs are incomplete +openbsd -> "-pthread" +freebsd -> "-pthread" +dragonfly -> "-pthread" +netbsd -> "-pthread -D_NETBSD_SOURCE" +qnx -> "-fexceptions -D_QNX_SOURCE" + -- cgit v1.2.3 From e4e6abb78f2287fe44ba83f896e21bf59eca57c9 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 19 Oct 2009 20:20:04 +0000 Subject: Format, add names to params in header --- src/kdf/kdf.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/kdf/kdf.h b/src/kdf/kdf.h index 70f636b6c..67078218f 100644 --- a/src/kdf/kdf.h +++ b/src/kdf/kdf.h @@ -22,6 +22,7 @@ class BOTAN_DLL KDF SecureVector derive_key(u32bit key_len, const MemoryRegion& secret, const std::string& salt = "") const; + SecureVector derive_key(u32bit key_len, const MemoryRegion& secret, const MemoryRegion& salt) const; @@ -33,14 +34,17 @@ class BOTAN_DLL KDF SecureVector derive_key(u32bit key_len, const byte secret[], u32bit secret_len, const std::string& salt = "") const; + SecureVector derive_key(u32bit key_len, const byte secret[], u32bit secret_len, const byte salt[], u32bit salt_len) const; virtual ~KDF() {} private: - virtual SecureVector derive(u32bit, const byte[], u32bit, - const byte[], u32bit) const = 0; + virtual SecureVector + derive(u32bit key_len, + const byte secret[], u32bit secret_len, + const byte salt[], u32bit salt_len) const = 0; }; /* @@ -50,7 +54,7 @@ class BOTAN_DLL MGF { public: virtual void mask(const byte in[], u32bit in_len, - byte out[], u32bit out_len) const = 0; + byte out[], u32bit out_len) const = 0; virtual ~MGF() {} }; -- cgit v1.2.3 From 05963c0cb66137cc96b9e030bbc2547ee4c3f7e3 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 21 Oct 2009 05:53:25 +0000 Subject: Enable CPUID on x86 (checking wrong macro name) --- src/utils/cpuid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index ae82bdac8..63edd2737 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -10,7 +10,7 @@ #include #include -#if defined(BOTAN_TARGET_ARCH_IS_X86) || defined(BOTAN_TARGET_ARCH_IS_AMD64) +#if defined(BOTAN_TARGET_ARCH_IS_IA32) || defined(BOTAN_TARGET_ARCH_IS_AMD64) #if defined(BOTAN_BUILD_COMPILER_IS_MSVC) -- cgit v1.2.3 From bbe91cb8030c2d1a910082650a02a0747a718a8e Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 22 Oct 2009 17:35:04 +0000 Subject: Remove all exception specifications. The way these are designed in C++ is just too fragile and not that useful. Something like Java's checked exceptions might be nice, but simply killing the process entirely if an unexpected exception is thrown is not exactly useful for something trying to be robust. --- src/alloc/mem_pool/mem_pool.cpp | 6 +++--- src/alloc/mem_pool/mem_pool.h | 6 +++--- src/block/aes/aes.cpp | 2 +- src/block/aes/aes.h | 2 +- src/block/block_cipher.h | 2 +- src/block/blowfish/blowfish.cpp | 2 +- src/block/blowfish/blowfish.h | 2 +- src/block/cast/cast128.h | 2 +- src/block/cast/cast256.h | 2 +- src/block/des/des.h | 4 ++-- src/block/des/desx.h | 2 +- src/block/gost_28147/gost_28147.h | 2 +- src/block/idea/idea.h | 2 +- src/block/kasumi/kasumi.h | 2 +- src/block/lion/lion.cpp | 2 +- src/block/lion/lion.h | 2 +- src/block/lubyrack/lubyrack.cpp | 2 +- src/block/lubyrack/lubyrack.h | 2 +- src/block/mars/mars.h | 2 +- src/block/misty1/misty1.h | 2 +- src/block/noekeon/noekeon.cpp | 2 +- src/block/noekeon/noekeon.h | 2 +- src/block/rc2/rc2.h | 2 +- src/block/rc5/rc5.h | 2 +- src/block/rc6/rc6.h | 2 +- src/block/safer/safer_sk.h | 2 +- src/block/seed/seed.h | 2 +- src/block/serpent/serpent.h | 2 +- src/block/skipjack/skipjack.cpp | 2 +- src/block/skipjack/skipjack.h | 2 +- src/block/square/square.cpp | 2 +- src/block/square/square.h | 2 +- src/block/tea/tea.h | 2 +- src/block/twofish/twofish.cpp | 2 +- src/block/twofish/twofish.h | 2 +- src/block/xtea/xtea.h | 2 +- src/checksum/adler32/adler32.h | 2 +- src/checksum/crc24/crc24.h | 2 +- src/checksum/crc32/crc32.h | 2 +- src/engine/openssl/arc4_openssl.cpp | 2 +- src/engine/openssl/ossl_bc.cpp | 4 ++-- src/engine/openssl/ossl_md.cpp | 4 ++-- src/hash/bmw/bmw_512.cpp | 2 +- src/hash/bmw/bmw_512.h | 2 +- src/hash/fork256/fork256.cpp | 2 +- src/hash/fork256/fork256.h | 2 +- src/hash/gost_3411/gost_3411.cpp | 2 +- src/hash/gost_3411/gost_3411.h | 2 +- src/hash/has160/has160.cpp | 2 +- src/hash/has160/has160.h | 2 +- src/hash/hash.h | 2 +- src/hash/md2/md2.cpp | 2 +- src/hash/md2/md2.h | 2 +- src/hash/md4/md4.cpp | 2 +- src/hash/md4/md4.h | 2 +- src/hash/md5/md5.cpp | 2 +- src/hash/md5/md5.h | 2 +- src/hash/mdx_hash/mdx_hash.cpp | 2 +- src/hash/mdx_hash/mdx_hash.h | 2 +- src/hash/par_hash/par_hash.cpp | 2 +- src/hash/par_hash/par_hash.h | 2 +- src/hash/rmd128/rmd128.cpp | 2 +- src/hash/rmd128/rmd128.h | 2 +- src/hash/rmd160/rmd160.cpp | 2 +- src/hash/rmd160/rmd160.h | 2 +- src/hash/sha1/sha160.cpp | 2 +- src/hash/sha1/sha160.h | 2 +- src/hash/sha2/sha2_32.cpp | 6 +++--- src/hash/sha2/sha2_32.h | 6 +++--- src/hash/sha2/sha2_64.cpp | 6 +++--- src/hash/sha2/sha2_64.h | 6 +++--- src/hash/skein/skein_512.cpp | 2 +- src/hash/skein/skein_512.h | 2 +- src/hash/tiger/tiger.cpp | 2 +- src/hash/tiger/tiger.h | 2 +- src/hash/whirlpool/whrlpool.cpp | 2 +- src/hash/whirlpool/whrlpool.h | 2 +- src/mac/cbc_mac/cbc_mac.cpp | 2 +- src/mac/cbc_mac/cbc_mac.h | 2 +- src/mac/cmac/cmac.cpp | 2 +- src/mac/cmac/cmac.h | 2 +- src/mac/hmac/hmac.cpp | 2 +- src/mac/hmac/hmac.h | 2 +- src/mac/mac.h | 2 +- src/mac/ssl3mac/ssl3_mac.cpp | 2 +- src/mac/ssl3mac/ssl3_mac.h | 2 +- src/mac/x919_mac/x919_mac.cpp | 2 +- src/mac/x919_mac/x919_mac.h | 2 +- src/pk_pad/emsa.h | 2 +- src/pk_pad/emsa1/emsa1.cpp | 2 +- src/pk_pad/emsa1/emsa1.h | 2 +- src/pk_pad/emsa2/emsa2.cpp | 2 +- src/pk_pad/emsa2/emsa2.h | 2 +- src/pk_pad/emsa3/emsa3.cpp | 4 ++-- src/pk_pad/emsa3/emsa3.h | 4 ++-- src/pk_pad/emsa4/emsa4.cpp | 2 +- src/pk_pad/emsa4/emsa4.h | 2 +- src/pk_pad/emsa_raw/emsa_raw.cpp | 2 +- src/pk_pad/emsa_raw/emsa_raw.h | 2 +- src/rng/auto_rng/auto_rng.h | 2 +- src/rng/hmac_rng/hmac_rng.cpp | 2 +- src/rng/hmac_rng/hmac_rng.h | 2 +- src/rng/randpool/randpool.cpp | 2 +- src/rng/randpool/randpool.h | 2 +- src/rng/rng.h | 4 ++-- src/rng/x931_rng/x931_rng.cpp | 2 +- src/rng/x931_rng/x931_rng.h | 2 +- src/stream/arc4/arc4.cpp | 2 +- src/stream/arc4/arc4.h | 2 +- src/stream/ctr/ctr.cpp | 2 +- src/stream/ctr/ctr.h | 2 +- src/stream/ofb/ofb.cpp | 2 +- src/stream/ofb/ofb.h | 2 +- src/stream/salsa20/salsa20.cpp | 2 +- src/stream/salsa20/salsa20.h | 2 +- src/stream/stream_cipher.h | 2 +- src/stream/turing/turing.cpp | 2 +- src/stream/turing/turing.h | 2 +- src/stream/wid_wake/wid_wake.cpp | 2 +- src/stream/wid_wake/wid_wake.h | 2 +- src/sym_algo/sym_algo.h | 4 ++-- 121 files changed, 140 insertions(+), 140 deletions(-) (limited to 'src') diff --git a/src/alloc/mem_pool/mem_pool.cpp b/src/alloc/mem_pool/mem_pool.cpp index dabf5e310..e30a7b98a 100644 --- a/src/alloc/mem_pool/mem_pool.cpp +++ b/src/alloc/mem_pool/mem_pool.cpp @@ -42,7 +42,7 @@ Pooling_Allocator::Memory_Block::Memory_Block(void* buf) * See if ptr is contained by this block */ bool Pooling_Allocator::Memory_Block::contains(void* ptr, - u32bit length) const throw() + u32bit length) const { return ((buffer <= ptr) && (buffer_end >= static_cast(ptr) + length * BLOCK_SIZE)); @@ -51,7 +51,7 @@ bool Pooling_Allocator::Memory_Block::contains(void* ptr, /* * Allocate some memory, if possible */ -byte* Pooling_Allocator::Memory_Block::alloc(u32bit n) throw() +byte* Pooling_Allocator::Memory_Block::alloc(u32bit n) { if(n == 0 || n > BITMAP_SIZE) return 0; @@ -91,7 +91,7 @@ byte* Pooling_Allocator::Memory_Block::alloc(u32bit n) throw() /* * Mark this memory as free, if we own it */ -void Pooling_Allocator::Memory_Block::free(void* ptr, u32bit blocks) throw() +void Pooling_Allocator::Memory_Block::free(void* ptr, u32bit blocks) { clear_mem(static_cast(ptr), blocks * BLOCK_SIZE); diff --git a/src/alloc/mem_pool/mem_pool.h b/src/alloc/mem_pool/mem_pool.h index a57800972..51571405e 100644 --- a/src/alloc/mem_pool/mem_pool.h +++ b/src/alloc/mem_pool/mem_pool.h @@ -44,9 +44,9 @@ class BOTAN_DLL Pooling_Allocator : public Allocator static u32bit bitmap_size() { return BITMAP_SIZE; } static u32bit block_size() { return BLOCK_SIZE; } - bool contains(void*, u32bit) const throw(); - byte* alloc(u32bit) throw(); - void free(void*, u32bit) throw(); + bool contains(void*, u32bit) const; + byte* alloc(u32bit); + void free(void*, u32bit); bool operator<(const Memory_Block& other) const { diff --git a/src/block/aes/aes.cpp b/src/block/aes/aes.cpp index 34698ae7f..7ba8136ec 100644 --- a/src/block/aes/aes.cpp +++ b/src/block/aes/aes.cpp @@ -258,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 768bb09e7..229ce307c 100644 --- a/src/block/aes/aes.h +++ b/src/block/aes/aes.h @@ -21,7 +21,7 @@ class BOTAN_DLL AES : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw(); + void clear(); std::string name() const { return "AES"; } BlockCipher* clone() const { return new AES; } diff --git a/src/block/block_cipher.h b/src/block/block_cipher.h index a27609171..1dcdde7c7 100644 --- a/src/block/block_cipher.h +++ b/src/block/block_cipher.h @@ -87,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, diff --git a/src/block/blowfish/blowfish.cpp b/src/block/blowfish/blowfish.cpp index 312603c3a..d0b182a84 100644 --- a/src/block/blowfish/blowfish.cpp +++ b/src/block/blowfish/blowfish.cpp @@ -128,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 345c1ce49..5419308ca 100644 --- a/src/block/blowfish/blowfish.h +++ b/src/block/blowfish/blowfish.h @@ -21,7 +21,7 @@ class BOTAN_DLL Blowfish : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw(); + void clear(); std::string name() const { return "Blowfish"; } BlockCipher* clone() const { return new Blowfish; } diff --git a/src/block/cast/cast128.h b/src/block/cast/cast128.h index 864a4e47e..caffb97ea 100644 --- a/src/block/cast/cast128.h +++ b/src/block/cast/cast128.h @@ -21,7 +21,7 @@ class BOTAN_DLL CAST_128 : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { MK.clear(); RK.clear(); } + void clear() { MK.clear(); RK.clear(); } std::string name() const { return "CAST-128"; } BlockCipher* clone() const { return new CAST_128; } diff --git a/src/block/cast/cast256.h b/src/block/cast/cast256.h index 1be7fa9cf..0db3682ba 100644 --- a/src/block/cast/cast256.h +++ b/src/block/cast/cast256.h @@ -21,7 +21,7 @@ class BOTAN_DLL CAST_256 : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { MK.clear(); RK.clear(); } + void clear() { MK.clear(); RK.clear(); } std::string name() const { return "CAST-256"; } BlockCipher* clone() const { return new CAST_256; } diff --git a/src/block/des/des.h b/src/block/des/des.h index 856aaf60c..b28990178 100644 --- a/src/block/des/des.h +++ b/src/block/des/des.h @@ -21,7 +21,7 @@ class BOTAN_DLL DES : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { round_key.clear(); } + void clear() { round_key.clear(); } std::string name() const { return "DES"; } BlockCipher* clone() const { return new DES; } @@ -41,7 +41,7 @@ class BOTAN_DLL TripleDES : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { round_key.clear(); } + void clear() { round_key.clear(); } std::string name() const { return "TripleDES"; } BlockCipher* clone() const { return new TripleDES; } diff --git a/src/block/des/desx.h b/src/block/des/desx.h index d22895296..89664d064 100644 --- a/src/block/des/desx.h +++ b/src/block/des/desx.h @@ -21,7 +21,7 @@ class BOTAN_DLL DESX : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { des.clear(); K1.clear(); K2.clear(); } + void clear() { des.clear(); K1.clear(); K2.clear(); } std::string name() const { return "DESX"; } BlockCipher* clone() const { return new DESX; } diff --git a/src/block/gost_28147/gost_28147.h b/src/block/gost_28147/gost_28147.h index 18c1d0a29..bf6f8178b 100644 --- a/src/block/gost_28147/gost_28147.h +++ b/src/block/gost_28147/gost_28147.h @@ -47,7 +47,7 @@ class BOTAN_DLL GOST_28147_89 : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { EK.clear(); } + void clear() { EK.clear(); } std::string name() const { return "GOST-28147-89"; } BlockCipher* clone() const { return new GOST_28147_89(SBOX); } diff --git a/src/block/idea/idea.h b/src/block/idea/idea.h index 59484531b..c1a79f423 100644 --- a/src/block/idea/idea.h +++ b/src/block/idea/idea.h @@ -21,7 +21,7 @@ class BOTAN_DLL IDEA : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { EK.clear(); DK.clear(); } + void clear() { EK.clear(); DK.clear(); } std::string name() const { return "IDEA"; } BlockCipher* clone() const { return new IDEA; } diff --git a/src/block/kasumi/kasumi.h b/src/block/kasumi/kasumi.h index 0f5a5d182..c3db1cb05 100644 --- a/src/block/kasumi/kasumi.h +++ b/src/block/kasumi/kasumi.h @@ -21,7 +21,7 @@ class BOTAN_DLL KASUMI : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { EK.clear(); } + void clear() { EK.clear(); } std::string name() const { return "KASUMI"; } BlockCipher* clone() const { return new KASUMI; } diff --git a/src/block/lion/lion.cpp b/src/block/lion/lion.cpp index 0ed7b2630..e71091258 100644 --- a/src/block/lion/lion.cpp +++ b/src/block/lion/lion.cpp @@ -95,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 d421771d6..f24acdb72 100644 --- a/src/block/lion/lion.h +++ b/src/block/lion/lion.h @@ -23,7 +23,7 @@ class BOTAN_DLL Lion : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw(); + void clear(); std::string name() const; BlockCipher* clone() const; diff --git a/src/block/lubyrack/lubyrack.cpp b/src/block/lubyrack/lubyrack.cpp index 6ad64f2b0..2003d2a89 100644 --- a/src/block/lubyrack/lubyrack.cpp +++ b/src/block/lubyrack/lubyrack.cpp @@ -92,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 940b34603..7249cf157 100644 --- a/src/block/lubyrack/lubyrack.h +++ b/src/block/lubyrack/lubyrack.h @@ -22,7 +22,7 @@ class BOTAN_DLL LubyRackoff : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw(); + void clear(); std::string name() const; BlockCipher* clone() const; diff --git a/src/block/mars/mars.h b/src/block/mars/mars.h index 7d0bfe4fa..8173fb984 100644 --- a/src/block/mars/mars.h +++ b/src/block/mars/mars.h @@ -18,7 +18,7 @@ class BOTAN_DLL MARS : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { EK.clear(); } + void clear() { EK.clear(); } std::string name() const { return "MARS"; } BlockCipher* clone() const { return new MARS; } diff --git a/src/block/misty1/misty1.h b/src/block/misty1/misty1.h index 8db6881de..000830915 100644 --- a/src/block/misty1/misty1.h +++ b/src/block/misty1/misty1.h @@ -21,7 +21,7 @@ class BOTAN_DLL MISTY1 : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { EK.clear(); DK.clear(); } + void clear() { EK.clear(); DK.clear(); } std::string name() const { return "MISTY1"; } BlockCipher* clone() const { return new MISTY1; } diff --git a/src/block/noekeon/noekeon.cpp b/src/block/noekeon/noekeon.cpp index 1b327aa47..0bfce1882 100644 --- a/src/block/noekeon/noekeon.cpp +++ b/src/block/noekeon/noekeon.cpp @@ -201,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 37b24fb7d..4532c1be2 100644 --- a/src/block/noekeon/noekeon.h +++ b/src/block/noekeon/noekeon.h @@ -21,7 +21,7 @@ class BOTAN_DLL Noekeon : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw(); + void clear(); std::string name() const { return "Noekeon"; } BlockCipher* clone() const { return new Noekeon; } diff --git a/src/block/rc2/rc2.h b/src/block/rc2/rc2.h index db623b385..c6e4946f9 100644 --- a/src/block/rc2/rc2.h +++ b/src/block/rc2/rc2.h @@ -23,7 +23,7 @@ class BOTAN_DLL RC2 : public BlockCipher 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; } diff --git a/src/block/rc5/rc5.h b/src/block/rc5/rc5.h index ff9204710..82931c1d2 100644 --- a/src/block/rc5/rc5.h +++ b/src/block/rc5/rc5.h @@ -21,7 +21,7 @@ class BOTAN_DLL RC5 : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { S.clear(); } + void clear() { S.clear(); } std::string name() const; BlockCipher* clone() const { return new RC5(ROUNDS); } diff --git a/src/block/rc6/rc6.h b/src/block/rc6/rc6.h index 5171006f5..6cd0f54db 100644 --- a/src/block/rc6/rc6.h +++ b/src/block/rc6/rc6.h @@ -21,7 +21,7 @@ class BOTAN_DLL RC6 : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { S.clear(); } + void clear() { S.clear(); } std::string name() const { return "RC6"; } BlockCipher* clone() const { return new RC6; } diff --git a/src/block/safer/safer_sk.h b/src/block/safer/safer_sk.h index 4d17bba51..80d2dc069 100644 --- a/src/block/safer/safer_sk.h +++ b/src/block/safer/safer_sk.h @@ -21,7 +21,7 @@ class BOTAN_DLL SAFER_SK : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { EK.clear(); } + void clear() { EK.clear(); } std::string name() const; BlockCipher* clone() const; diff --git a/src/block/seed/seed.h b/src/block/seed/seed.h index 5a5a512e7..5a4b44057 100644 --- a/src/block/seed/seed.h +++ b/src/block/seed/seed.h @@ -21,7 +21,7 @@ class BOTAN_DLL SEED : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { K.clear(); } + void clear() { K.clear(); } std::string name() const { return "SEED"; } BlockCipher* clone() const { return new SEED; } diff --git a/src/block/serpent/serpent.h b/src/block/serpent/serpent.h index d919c3008..4fa7451b9 100644 --- a/src/block/serpent/serpent.h +++ b/src/block/serpent/serpent.h @@ -21,7 +21,7 @@ class BOTAN_DLL Serpent : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { round_key.clear(); } + void clear() { round_key.clear(); } std::string name() const { return "Serpent"; } BlockCipher* clone() const { return new Serpent; } Serpent() : BlockCipher(16, 16, 32, 8) {} diff --git a/src/block/skipjack/skipjack.cpp b/src/block/skipjack/skipjack.cpp index 6c308c0f8..e8b2cfb8d 100644 --- a/src/block/skipjack/skipjack.cpp +++ b/src/block/skipjack/skipjack.cpp @@ -165,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 f12032f36..60fad6310 100644 --- a/src/block/skipjack/skipjack.h +++ b/src/block/skipjack/skipjack.h @@ -21,7 +21,7 @@ class BOTAN_DLL Skipjack : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw(); + void clear(); std::string name() const { return "Skipjack"; } BlockCipher* clone() const { return new Skipjack; } diff --git a/src/block/square/square.cpp b/src/block/square/square.cpp index fdd47d3b2..90f2301cf 100644 --- a/src/block/square/square.cpp +++ b/src/block/square/square.cpp @@ -196,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 5d9cfc78c..088122181 100644 --- a/src/block/square/square.h +++ b/src/block/square/square.h @@ -21,7 +21,7 @@ class BOTAN_DLL Square : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw(); + void clear(); std::string name() const { return "Square"; } BlockCipher* clone() const { return new Square; } diff --git a/src/block/tea/tea.h b/src/block/tea/tea.h index 825a051aa..c19f272a6 100644 --- a/src/block/tea/tea.h +++ b/src/block/tea/tea.h @@ -21,7 +21,7 @@ class BOTAN_DLL TEA : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { K.clear(); } + void clear() { K.clear(); } std::string name() const { return "TEA"; } BlockCipher* clone() const { return new TEA; } diff --git a/src/block/twofish/twofish.cpp b/src/block/twofish/twofish.cpp index 6a482a8f3..3136837aa 100644 --- a/src/block/twofish/twofish.cpp +++ b/src/block/twofish/twofish.cpp @@ -218,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 87b9aa626..71a1e8781 100644 --- a/src/block/twofish/twofish.h +++ b/src/block/twofish/twofish.h @@ -21,7 +21,7 @@ class BOTAN_DLL Twofish : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw(); + void clear(); std::string name() const { return "Twofish"; } BlockCipher* clone() const { return new Twofish; } diff --git a/src/block/xtea/xtea.h b/src/block/xtea/xtea.h index de265818d..f3b554edb 100644 --- a/src/block/xtea/xtea.h +++ b/src/block/xtea/xtea.h @@ -21,7 +21,7 @@ class BOTAN_DLL XTEA : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - void clear() throw() { EK.clear(); } + void clear() { EK.clear(); } std::string name() const { return "XTEA"; } BlockCipher* clone() const { return new XTEA; } diff --git a/src/checksum/adler32/adler32.h b/src/checksum/adler32/adler32.h index 98a28bc81..79804a842 100644 --- a/src/checksum/adler32/adler32.h +++ b/src/checksum/adler32/adler32.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL Adler32 : public HashFunction { public: - void clear() throw() { S1 = 1; S2 = 0; } + void clear() { S1 = 1; S2 = 0; } std::string name() const { return "Adler32"; } HashFunction* clone() const { return new Adler32; } Adler32() : HashFunction(4) { clear(); } diff --git a/src/checksum/crc24/crc24.h b/src/checksum/crc24/crc24.h index bca4d0e89..f59ac4a45 100644 --- a/src/checksum/crc24/crc24.h +++ b/src/checksum/crc24/crc24.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL CRC24 : public HashFunction { public: - void clear() throw() { crc = 0xB704CE; } + void clear() { crc = 0xB704CE; } std::string name() const { return "CRC24"; } HashFunction* clone() const { return new CRC24; } CRC24() : HashFunction(3) { clear(); } diff --git a/src/checksum/crc32/crc32.h b/src/checksum/crc32/crc32.h index 390fb100e..998e8489e 100644 --- a/src/checksum/crc32/crc32.h +++ b/src/checksum/crc32/crc32.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL CRC32 : public HashFunction { public: - void clear() throw() { crc = 0xFFFFFFFF; } + void clear() { crc = 0xFFFFFFFF; } std::string name() const { return "CRC32"; } HashFunction* clone() const { return new CRC32; } CRC32() : HashFunction(4) { clear(); } diff --git a/src/engine/openssl/arc4_openssl.cpp b/src/engine/openssl/arc4_openssl.cpp index 08ed3eb10..793e1faff 100644 --- a/src/engine/openssl/arc4_openssl.cpp +++ b/src/engine/openssl/arc4_openssl.cpp @@ -19,7 +19,7 @@ namespace { class ARC4_OpenSSL : public StreamCipher { public: - void clear() throw() { std::memset(&state, 0, sizeof(state)); } + void clear() { std::memset(&state, 0, sizeof(state)); } std::string name() const; StreamCipher* clone() const { return new ARC4_OpenSSL(SKIP); } diff --git a/src/engine/openssl/ossl_bc.cpp b/src/engine/openssl/ossl_bc.cpp index 9c85439ca..7fdf54e42 100644 --- a/src/engine/openssl/ossl_bc.cpp +++ b/src/engine/openssl/ossl_bc.cpp @@ -18,7 +18,7 @@ namespace { class EVP_BlockCipher : public BlockCipher { public: - void clear() throw(); + void clear(); std::string name() const { return cipher_name; } BlockCipher* clone() const; EVP_BlockCipher(const EVP_CIPHER*, const std::string&); @@ -145,7 +145,7 @@ BlockCipher* EVP_BlockCipher::clone() const /* * Clear memory of sensitive data */ -void EVP_BlockCipher::clear() throw() +void EVP_BlockCipher::clear() { const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(&encrypt); diff --git a/src/engine/openssl/ossl_md.cpp b/src/engine/openssl/ossl_md.cpp index 42975c8a3..1e01a6f25 100644 --- a/src/engine/openssl/ossl_md.cpp +++ b/src/engine/openssl/ossl_md.cpp @@ -18,7 +18,7 @@ namespace { class EVP_HashFunction : public HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return algo_name; } HashFunction* clone() const; EVP_HashFunction(const EVP_MD*, const std::string&); @@ -52,7 +52,7 @@ void EVP_HashFunction::final_result(byte output[]) /* * Clear memory of sensitive data */ -void EVP_HashFunction::clear() throw() +void EVP_HashFunction::clear() { const EVP_MD* algo = EVP_MD_CTX_md(&md); EVP_DigestInit_ex(&md, algo, 0); diff --git a/src/hash/bmw/bmw_512.cpp b/src/hash/bmw/bmw_512.cpp index ad3826351..ae80d5725 100644 --- a/src/hash/bmw/bmw_512.cpp +++ b/src/hash/bmw/bmw_512.cpp @@ -176,7 +176,7 @@ void BMW_512::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void BMW_512::clear() throw() +void BMW_512::clear() { MDx_HashFunction::clear(); M.clear(); diff --git a/src/hash/bmw/bmw_512.h b/src/hash/bmw/bmw_512.h index d1f2539e9..55cd761a9 100644 --- a/src/hash/bmw/bmw_512.h +++ b/src/hash/bmw/bmw_512.h @@ -15,7 +15,7 @@ namespace Botan { class BMW_512 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "BMW512"; } HashFunction* clone() const { return new BMW_512; } BMW_512() : MDx_HashFunction(64, 128, false, true) { clear(); } diff --git a/src/hash/fork256/fork256.cpp b/src/hash/fork256/fork256.cpp index f80bff43a..6718f9f97 100644 --- a/src/hash/fork256/fork256.cpp +++ b/src/hash/fork256/fork256.cpp @@ -133,7 +133,7 @@ void FORK_256::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void FORK_256::clear() throw() +void FORK_256::clear() { MDx_HashFunction::clear(); digest[0] = 0x6A09E667; diff --git a/src/hash/fork256/fork256.h b/src/hash/fork256/fork256.h index 70d336cc9..f535370e6 100644 --- a/src/hash/fork256/fork256.h +++ b/src/hash/fork256/fork256.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL FORK_256 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "FORK-256"; } HashFunction* clone() const { return new FORK_256; } FORK_256() : MDx_HashFunction(32, 64, true, true) { clear(); } diff --git a/src/hash/gost_3411/gost_3411.cpp b/src/hash/gost_3411/gost_3411.cpp index 8f3982fca..90ef3e805 100644 --- a/src/hash/gost_3411/gost_3411.cpp +++ b/src/hash/gost_3411/gost_3411.cpp @@ -23,7 +23,7 @@ GOST_34_11::GOST_34_11() : position = 0; } -void GOST_34_11::clear() throw() +void GOST_34_11::clear() { cipher.clear(); sum.clear(); diff --git a/src/hash/gost_3411/gost_3411.h b/src/hash/gost_3411/gost_3411.h index 960adaa44..7b17bdc1f 100644 --- a/src/hash/gost_3411/gost_3411.h +++ b/src/hash/gost_3411/gost_3411.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL GOST_34_11 : public HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "GOST-R-34.11-94" ; } HashFunction* clone() const { return new GOST_34_11; } diff --git a/src/hash/has160/has160.cpp b/src/hash/has160/has160.cpp index 9a505d31d..533efe595 100644 --- a/src/hash/has160/has160.cpp +++ b/src/hash/has160/has160.cpp @@ -145,7 +145,7 @@ void HAS_160::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void HAS_160::clear() throw() +void HAS_160::clear() { MDx_HashFunction::clear(); X.clear(); diff --git a/src/hash/has160/has160.h b/src/hash/has160/has160.h index 44bb63b9d..cae66c93a 100644 --- a/src/hash/has160/has160.h +++ b/src/hash/has160/has160.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL HAS_160 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "HAS-160"; } HashFunction* clone() const { return new HAS_160; } HAS_160() : MDx_HashFunction(20, 64, false, true) { clear(); } diff --git a/src/hash/hash.h b/src/hash/hash.h index a30234be0..1098951d8 100644 --- a/src/hash/hash.h +++ b/src/hash/hash.h @@ -38,7 +38,7 @@ class BOTAN_DLL HashFunction : public BufferedComputation /** * Reset the internal state of this object. */ - virtual void clear() throw() = 0; + virtual void clear() = 0; HashFunction(u32bit hash_len, u32bit block_len = 0) : BufferedComputation(hash_len), HASH_BLOCK_SIZE(block_len) {} diff --git a/src/hash/md2/md2.cpp b/src/hash/md2/md2.cpp index c67e72b5a..f03518ec0 100644 --- a/src/hash/md2/md2.cpp +++ b/src/hash/md2/md2.cpp @@ -97,7 +97,7 @@ void MD2::final_result(byte output[]) /** * Clear memory of sensitive data */ -void MD2::clear() throw() +void MD2::clear() { X.clear(); checksum.clear(); diff --git a/src/hash/md2/md2.h b/src/hash/md2/md2.h index 9337c43f4..0a7125759 100644 --- a/src/hash/md2/md2.h +++ b/src/hash/md2/md2.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL MD2 : public HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "MD2"; } HashFunction* clone() const { return new MD2; } MD2() : HashFunction(16, 16) { clear(); } diff --git a/src/hash/md4/md4.cpp b/src/hash/md4/md4.cpp index 39e3c8c41..b2870066d 100644 --- a/src/hash/md4/md4.cpp +++ b/src/hash/md4/md4.cpp @@ -95,7 +95,7 @@ void MD4::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void MD4::clear() throw() +void MD4::clear() { MDx_HashFunction::clear(); M.clear(); diff --git a/src/hash/md4/md4.h b/src/hash/md4/md4.h index df6f2292d..0b76a70e4 100644 --- a/src/hash/md4/md4.h +++ b/src/hash/md4/md4.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL MD4 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "MD4"; } HashFunction* clone() const { return new MD4; } MD4() : MDx_HashFunction(16, 64, false, true) { clear(); } diff --git a/src/hash/md5/md5.cpp b/src/hash/md5/md5.cpp index 7c280aab7..163413bec 100644 --- a/src/hash/md5/md5.cpp +++ b/src/hash/md5/md5.cpp @@ -123,7 +123,7 @@ void MD5::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void MD5::clear() throw() +void MD5::clear() { MDx_HashFunction::clear(); M.clear(); diff --git a/src/hash/md5/md5.h b/src/hash/md5/md5.h index 85f684d8b..456a02c28 100644 --- a/src/hash/md5/md5.h +++ b/src/hash/md5/md5.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL MD5 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "MD5"; } HashFunction* clone() const { return new MD5; } MD5() : MDx_HashFunction(16, 64, false, true) { clear(); } diff --git a/src/hash/mdx_hash/mdx_hash.cpp b/src/hash/mdx_hash/mdx_hash.cpp index b630ec227..28402c2c5 100644 --- a/src/hash/mdx_hash/mdx_hash.cpp +++ b/src/hash/mdx_hash/mdx_hash.cpp @@ -28,7 +28,7 @@ MDx_HashFunction::MDx_HashFunction(u32bit hash_len, u32bit block_len, /** * Clear memory of sensitive data */ -void MDx_HashFunction::clear() throw() +void MDx_HashFunction::clear() { buffer.clear(); count = position = 0; diff --git a/src/hash/mdx_hash/mdx_hash.h b/src/hash/mdx_hash/mdx_hash.h index 0c3aa7806..2d70deed3 100644 --- a/src/hash/mdx_hash/mdx_hash.h +++ b/src/hash/mdx_hash/mdx_hash.h @@ -25,7 +25,7 @@ class BOTAN_DLL MDx_HashFunction : public HashFunction void final_result(byte output[]); virtual void compress_n(const byte block[], u32bit block_n) = 0; - void clear() throw(); + void clear(); virtual void copy_out(byte[]) = 0; virtual void write_count(byte[]); private: diff --git a/src/hash/par_hash/par_hash.cpp b/src/hash/par_hash/par_hash.cpp index 4b0c7c466..0ba3f5a4f 100644 --- a/src/hash/par_hash/par_hash.cpp +++ b/src/hash/par_hash/par_hash.cpp @@ -77,7 +77,7 @@ HashFunction* Parallel::clone() const /* * Clear memory of sensitive data */ -void Parallel::clear() throw() +void Parallel::clear() { for(u32bit j = 0; j != hashes.size(); ++j) hashes[j]->clear(); diff --git a/src/hash/par_hash/par_hash.h b/src/hash/par_hash/par_hash.h index 7e75c27be..874e491b1 100644 --- a/src/hash/par_hash/par_hash.h +++ b/src/hash/par_hash/par_hash.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL Parallel : public HashFunction { public: - void clear() throw(); + void clear(); std::string name() const; HashFunction* clone() const; diff --git a/src/hash/rmd128/rmd128.cpp b/src/hash/rmd128/rmd128.cpp index 8b2c0ccf8..899e50914 100644 --- a/src/hash/rmd128/rmd128.cpp +++ b/src/hash/rmd128/rmd128.cpp @@ -159,7 +159,7 @@ void RIPEMD_128::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void RIPEMD_128::clear() throw() +void RIPEMD_128::clear() { MDx_HashFunction::clear(); M.clear(); diff --git a/src/hash/rmd128/rmd128.h b/src/hash/rmd128/rmd128.h index 031ae5746..d9cb4ebb4 100644 --- a/src/hash/rmd128/rmd128.h +++ b/src/hash/rmd128/rmd128.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL RIPEMD_128 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "RIPEMD-128"; } HashFunction* clone() const { return new RIPEMD_128; } RIPEMD_128() : MDx_HashFunction(16, 64, false, true) { clear(); } diff --git a/src/hash/rmd160/rmd160.cpp b/src/hash/rmd160/rmd160.cpp index 863de8487..2baf5ab08 100644 --- a/src/hash/rmd160/rmd160.cpp +++ b/src/hash/rmd160/rmd160.cpp @@ -196,7 +196,7 @@ void RIPEMD_160::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void RIPEMD_160::clear() throw() +void RIPEMD_160::clear() { MDx_HashFunction::clear(); M.clear(); diff --git a/src/hash/rmd160/rmd160.h b/src/hash/rmd160/rmd160.h index f2babc582..aee007b98 100644 --- a/src/hash/rmd160/rmd160.h +++ b/src/hash/rmd160/rmd160.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL RIPEMD_160 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "RIPEMD-160"; } HashFunction* clone() const { return new RIPEMD_160; } RIPEMD_160() : MDx_HashFunction(20, 64, false, true) { clear(); } diff --git a/src/hash/sha1/sha160.cpp b/src/hash/sha1/sha160.cpp index 45323a11b..a9e6880a7 100644 --- a/src/hash/sha1/sha160.cpp +++ b/src/hash/sha1/sha160.cpp @@ -130,7 +130,7 @@ void SHA_160::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void SHA_160::clear() throw() +void SHA_160::clear() { MDx_HashFunction::clear(); W.clear(); diff --git a/src/hash/sha1/sha160.h b/src/hash/sha1/sha160.h index 232cf0322..142c6bf17 100644 --- a/src/hash/sha1/sha160.h +++ b/src/hash/sha1/sha160.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL SHA_160 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "SHA-160"; } HashFunction* clone() const { return new SHA_160; } SHA_160(); diff --git a/src/hash/sha2/sha2_32.cpp b/src/hash/sha2/sha2_32.cpp index 9da2ec23f..9fbcae44d 100644 --- a/src/hash/sha2/sha2_32.cpp +++ b/src/hash/sha2/sha2_32.cpp @@ -152,7 +152,7 @@ void SHA_224_256_BASE::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void SHA_224_256_BASE::clear() throw() +void SHA_224_256_BASE::clear() { MDx_HashFunction::clear(); W.clear(); @@ -161,7 +161,7 @@ void SHA_224_256_BASE::clear() throw() /* * Clear memory of sensitive data */ -void SHA_224::clear() throw() +void SHA_224::clear() { SHA_224_256_BASE::clear(); digest[0] = 0xc1059ed8; @@ -177,7 +177,7 @@ void SHA_224::clear() throw() /* * Clear memory of sensitive data */ -void SHA_256::clear() throw() +void SHA_256::clear() { SHA_224_256_BASE::clear(); digest[0] = 0x6A09E667; diff --git a/src/hash/sha2/sha2_32.h b/src/hash/sha2/sha2_32.h index 05083d19d..313eec676 100644 --- a/src/hash/sha2/sha2_32.h +++ b/src/hash/sha2/sha2_32.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL SHA_224_256_BASE : public MDx_HashFunction { protected: - void clear() throw(); + void clear(); SHA_224_256_BASE(u32bit out) : MDx_HashFunction(out, 64, true, true) { clear(); } @@ -36,7 +36,7 @@ class BOTAN_DLL SHA_224_256_BASE : public MDx_HashFunction class BOTAN_DLL SHA_224 : public SHA_224_256_BASE { public: - void clear() throw(); + void clear(); std::string name() const { return "SHA-224"; } HashFunction* clone() const { return new SHA_224; } SHA_224() : SHA_224_256_BASE(28) { clear(); } @@ -48,7 +48,7 @@ class BOTAN_DLL SHA_224 : public SHA_224_256_BASE class BOTAN_DLL SHA_256 : public SHA_224_256_BASE { public: - void clear() throw(); + void clear(); std::string name() const { return "SHA-256"; } HashFunction* clone() const { return new SHA_256; } SHA_256() : SHA_224_256_BASE(32) { clear (); } diff --git a/src/hash/sha2/sha2_64.cpp b/src/hash/sha2/sha2_64.cpp index e9b4c2e5a..3c771eb44 100644 --- a/src/hash/sha2/sha2_64.cpp +++ b/src/hash/sha2/sha2_64.cpp @@ -167,7 +167,7 @@ void SHA_384_512_BASE::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void SHA_384_512_BASE::clear() throw() +void SHA_384_512_BASE::clear() { MDx_HashFunction::clear(); W.clear(); @@ -176,7 +176,7 @@ void SHA_384_512_BASE::clear() throw() /* * Clear memory of sensitive data */ -void SHA_384::clear() throw() +void SHA_384::clear() { SHA_384_512_BASE::clear(); digest[0] = 0xCBBB9D5DC1059ED8; @@ -192,7 +192,7 @@ void SHA_384::clear() throw() /* * Clear memory of sensitive data */ -void SHA_512::clear() throw() +void SHA_512::clear() { SHA_384_512_BASE::clear(); digest[0] = 0x6A09E667F3BCC908; diff --git a/src/hash/sha2/sha2_64.h b/src/hash/sha2/sha2_64.h index dcc6dc83b..8e4d171f8 100644 --- a/src/hash/sha2/sha2_64.h +++ b/src/hash/sha2/sha2_64.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL SHA_384_512_BASE : public MDx_HashFunction { protected: - void clear() throw(); + void clear(); SHA_384_512_BASE(u32bit out) : MDx_HashFunction(out, 128, true, true, 16) {} @@ -37,7 +37,7 @@ class BOTAN_DLL SHA_384_512_BASE : public MDx_HashFunction class BOTAN_DLL SHA_384 : public SHA_384_512_BASE { public: - void clear() throw(); + void clear(); std::string name() const { return "SHA-384"; } HashFunction* clone() const { return new SHA_384; } SHA_384() : SHA_384_512_BASE(48) { clear(); } @@ -49,7 +49,7 @@ class BOTAN_DLL SHA_384 : public SHA_384_512_BASE class BOTAN_DLL SHA_512 : public SHA_384_512_BASE { public: - void clear() throw(); + void clear(); std::string name() const { return "SHA-512"; } HashFunction* clone() const { return new SHA_512; } SHA_512() : SHA_384_512_BASE(64) { clear(); } diff --git a/src/hash/skein/skein_512.cpp b/src/hash/skein/skein_512.cpp index a48cfc186..b24efd5f7 100644 --- a/src/hash/skein/skein_512.cpp +++ b/src/hash/skein/skein_512.cpp @@ -183,7 +183,7 @@ HashFunction* Skein_512::clone() const return new Skein_512(output_bits, personalization); } -void Skein_512::clear() throw() +void Skein_512::clear() { H.clear(); T.clear(); diff --git a/src/hash/skein/skein_512.h b/src/hash/skein/skein_512.h index fa558fc0d..db8d3c8b7 100644 --- a/src/hash/skein/skein_512.h +++ b/src/hash/skein/skein_512.h @@ -22,7 +22,7 @@ class BOTAN_DLL Skein_512 : public HashFunction HashFunction* clone() const; std::string name() const; - void clear() throw(); + void clear(); private: void add_data(const byte input[], u32bit length); void final_result(byte out[]); diff --git a/src/hash/tiger/tiger.cpp b/src/hash/tiger/tiger.cpp index e46f2cb77..975ea9b6b 100644 --- a/src/hash/tiger/tiger.cpp +++ b/src/hash/tiger/tiger.cpp @@ -129,7 +129,7 @@ void Tiger::mix(u64bit X[8]) /* * Clear memory of sensitive data */ -void Tiger::clear() throw() +void Tiger::clear() { MDx_HashFunction::clear(); X.clear(); diff --git a/src/hash/tiger/tiger.h b/src/hash/tiger/tiger.h index 63184a938..86ddcd270 100644 --- a/src/hash/tiger/tiger.h +++ b/src/hash/tiger/tiger.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL Tiger : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const; HashFunction* clone() const { return new Tiger(OUTPUT_LENGTH); } Tiger(u32bit = 24, u32bit = 3); diff --git a/src/hash/whirlpool/whrlpool.cpp b/src/hash/whirlpool/whrlpool.cpp index 8548d6192..b7a02a9b6 100644 --- a/src/hash/whirlpool/whrlpool.cpp +++ b/src/hash/whirlpool/whrlpool.cpp @@ -136,7 +136,7 @@ void Whirlpool::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void Whirlpool::clear() throw() +void Whirlpool::clear() { MDx_HashFunction::clear(); M.clear(); diff --git a/src/hash/whirlpool/whrlpool.h b/src/hash/whirlpool/whrlpool.h index b72ff609f..34b4d2302 100644 --- a/src/hash/whirlpool/whrlpool.h +++ b/src/hash/whirlpool/whrlpool.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL Whirlpool : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "Whirlpool"; } HashFunction* clone() const { return new Whirlpool; } Whirlpool() : MDx_HashFunction(64, 64, true, true, 32) { clear(); } diff --git a/src/mac/cbc_mac/cbc_mac.cpp b/src/mac/cbc_mac/cbc_mac.cpp index f5d9e1567..0617e3e90 100644 --- a/src/mac/cbc_mac/cbc_mac.cpp +++ b/src/mac/cbc_mac/cbc_mac.cpp @@ -62,7 +62,7 @@ void CBC_MAC::key_schedule(const byte key[], u32bit length) /* * Clear memory of sensitive data */ -void CBC_MAC::clear() throw() +void CBC_MAC::clear() { e->clear(); state.clear(); diff --git a/src/mac/cbc_mac/cbc_mac.h b/src/mac/cbc_mac/cbc_mac.h index d17d792d3..15026c0a9 100644 --- a/src/mac/cbc_mac/cbc_mac.h +++ b/src/mac/cbc_mac/cbc_mac.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL CBC_MAC : public MessageAuthenticationCode { public: - void clear() throw(); + void clear(); std::string name() const; MessageAuthenticationCode* clone() const; diff --git a/src/mac/cmac/cmac.cpp b/src/mac/cmac/cmac.cpp index 84aa61e03..58923138b 100644 --- a/src/mac/cmac/cmac.cpp +++ b/src/mac/cmac/cmac.cpp @@ -101,7 +101,7 @@ void CMAC::key_schedule(const byte key[], u32bit length) /* * Clear memory of sensitive data */ -void CMAC::clear() throw() +void CMAC::clear() { e->clear(); state.clear(); diff --git a/src/mac/cmac/cmac.h b/src/mac/cmac/cmac.h index 5a6deb7b0..8297e5ea1 100644 --- a/src/mac/cmac/cmac.h +++ b/src/mac/cmac/cmac.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL CMAC : public MessageAuthenticationCode { public: - void clear() throw(); + void clear(); std::string name() const; MessageAuthenticationCode* clone() const; diff --git a/src/mac/hmac/hmac.cpp b/src/mac/hmac/hmac.cpp index 717e2640c..99be479fa 100644 --- a/src/mac/hmac/hmac.cpp +++ b/src/mac/hmac/hmac.cpp @@ -58,7 +58,7 @@ void HMAC::key_schedule(const byte key[], u32bit length) /* * Clear memory of sensitive data */ -void HMAC::clear() throw() +void HMAC::clear() { hash->clear(); i_key.clear(); diff --git a/src/mac/hmac/hmac.h b/src/mac/hmac/hmac.h index 932af71fc..62bb69853 100644 --- a/src/mac/hmac/hmac.h +++ b/src/mac/hmac/hmac.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL HMAC : public MessageAuthenticationCode { public: - void clear() throw(); + void clear(); std::string name() const; MessageAuthenticationCode* clone() const; diff --git a/src/mac/mac.h b/src/mac/mac.h index 3ec5fff5f..7c73a2900 100644 --- a/src/mac/mac.h +++ b/src/mac/mac.h @@ -43,7 +43,7 @@ class BOTAN_DLL MessageAuthenticationCode : public BufferedComputation, /** * Reset the internal state of this object. */ - virtual void clear() throw() = 0; + virtual void clear() = 0; MessageAuthenticationCode(u32bit mac_len, u32bit key_min, diff --git a/src/mac/ssl3mac/ssl3_mac.cpp b/src/mac/ssl3mac/ssl3_mac.cpp index c29296ced..23a636424 100644 --- a/src/mac/ssl3mac/ssl3_mac.cpp +++ b/src/mac/ssl3mac/ssl3_mac.cpp @@ -46,7 +46,7 @@ void SSL3_MAC::key_schedule(const byte key[], u32bit length) /* * Clear memory of sensitive data */ -void SSL3_MAC::clear() throw() +void SSL3_MAC::clear() { hash->clear(); i_key.clear(); diff --git a/src/mac/ssl3mac/ssl3_mac.h b/src/mac/ssl3mac/ssl3_mac.h index dcaf7f404..828b072ed 100644 --- a/src/mac/ssl3mac/ssl3_mac.h +++ b/src/mac/ssl3mac/ssl3_mac.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL SSL3_MAC : public MessageAuthenticationCode { public: - void clear() throw(); + void clear(); std::string name() const; MessageAuthenticationCode* clone() const; diff --git a/src/mac/x919_mac/x919_mac.cpp b/src/mac/x919_mac/x919_mac.cpp index ef89cac9c..52260494a 100644 --- a/src/mac/x919_mac/x919_mac.cpp +++ b/src/mac/x919_mac/x919_mac.cpp @@ -63,7 +63,7 @@ void ANSI_X919_MAC::key_schedule(const byte key[], u32bit length) /* * Clear memory of sensitive data */ -void ANSI_X919_MAC::clear() throw() +void ANSI_X919_MAC::clear() { e->clear(); d->clear(); diff --git a/src/mac/x919_mac/x919_mac.h b/src/mac/x919_mac/x919_mac.h index 1c2a06bee..a4690fdcd 100644 --- a/src/mac/x919_mac/x919_mac.h +++ b/src/mac/x919_mac/x919_mac.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL ANSI_X919_MAC : public MessageAuthenticationCode { public: - void clear() throw(); + void clear(); std::string name() const; MessageAuthenticationCode* clone() const; diff --git a/src/pk_pad/emsa.h b/src/pk_pad/emsa.h index e2491e40f..8b19d3cb2 100644 --- a/src/pk_pad/emsa.h +++ b/src/pk_pad/emsa.h @@ -27,7 +27,7 @@ class BOTAN_DLL EMSA RandomNumberGenerator& rng) = 0; virtual bool verify(const MemoryRegion&, const MemoryRegion&, - u32bit) throw() = 0; + u32bit) = 0; virtual ~EMSA() {} }; diff --git a/src/pk_pad/emsa1/emsa1.cpp b/src/pk_pad/emsa1/emsa1.cpp index 26d709c28..0ae7e8d2d 100644 --- a/src/pk_pad/emsa1/emsa1.cpp +++ b/src/pk_pad/emsa1/emsa1.cpp @@ -72,7 +72,7 @@ SecureVector EMSA1::encoding_of(const MemoryRegion& msg, * EMSA1 Decode/Verify Operation */ bool EMSA1::verify(const MemoryRegion& coded, - const MemoryRegion& raw, u32bit key_bits) throw() + const MemoryRegion& raw, u32bit key_bits) { try { if(raw.size() != hash->OUTPUT_LENGTH) diff --git a/src/pk_pad/emsa1/emsa1.h b/src/pk_pad/emsa1/emsa1.h index a5dac07e2..d86020966 100644 --- a/src/pk_pad/emsa1/emsa1.h +++ b/src/pk_pad/emsa1/emsa1.h @@ -31,7 +31,7 @@ class BOTAN_DLL EMSA1 : public EMSA RandomNumberGenerator& rng); bool verify(const MemoryRegion&, const MemoryRegion&, - u32bit) throw(); + u32bit); HashFunction* hash; }; diff --git a/src/pk_pad/emsa2/emsa2.cpp b/src/pk_pad/emsa2/emsa2.cpp index 168f9209e..74a045931 100644 --- a/src/pk_pad/emsa2/emsa2.cpp +++ b/src/pk_pad/emsa2/emsa2.cpp @@ -79,7 +79,7 @@ SecureVector EMSA2::encoding_of(const MemoryRegion& msg, */ bool EMSA2::verify(const MemoryRegion& coded, const MemoryRegion& raw, - u32bit key_bits) throw() + u32bit key_bits) { try { diff --git a/src/pk_pad/emsa2/emsa2.h b/src/pk_pad/emsa2/emsa2.h index 76888d1f6..7efc80873 100644 --- a/src/pk_pad/emsa2/emsa2.h +++ b/src/pk_pad/emsa2/emsa2.h @@ -29,7 +29,7 @@ class BOTAN_DLL EMSA2 : public EMSA RandomNumberGenerator& rng); bool verify(const MemoryRegion&, const MemoryRegion&, - u32bit) throw(); + u32bit); SecureVector empty_hash; HashFunction* hash; diff --git a/src/pk_pad/emsa3/emsa3.cpp b/src/pk_pad/emsa3/emsa3.cpp index 4d50abd84..dc905a464 100644 --- a/src/pk_pad/emsa3/emsa3.cpp +++ b/src/pk_pad/emsa3/emsa3.cpp @@ -72,7 +72,7 @@ SecureVector EMSA3::encoding_of(const MemoryRegion& msg, */ bool EMSA3::verify(const MemoryRegion& coded, const MemoryRegion& raw, - u32bit key_bits) throw() + u32bit key_bits) { if(raw.size() != hash->OUTPUT_LENGTH) return false; @@ -137,7 +137,7 @@ SecureVector EMSA3_Raw::encoding_of(const MemoryRegion& msg, */ bool EMSA3_Raw::verify(const MemoryRegion& coded, const MemoryRegion& raw, - u32bit key_bits) throw() + u32bit key_bits) { try { diff --git a/src/pk_pad/emsa3/emsa3.h b/src/pk_pad/emsa3/emsa3.h index 301f2142a..c4a3d658b 100644 --- a/src/pk_pad/emsa3/emsa3.h +++ b/src/pk_pad/emsa3/emsa3.h @@ -32,7 +32,7 @@ class BOTAN_DLL EMSA3 : public EMSA RandomNumberGenerator& rng); bool verify(const MemoryRegion&, const MemoryRegion&, - u32bit) throw(); + u32bit); private: HashFunction* hash; SecureVector hash_id; @@ -54,7 +54,7 @@ class BOTAN_DLL EMSA3_Raw : public EMSA RandomNumberGenerator& rng); bool verify(const MemoryRegion&, const MemoryRegion&, - u32bit) throw(); + u32bit); private: SecureVector message; diff --git a/src/pk_pad/emsa4/emsa4.cpp b/src/pk_pad/emsa4/emsa4.cpp index cff9a1537..dba248662 100644 --- a/src/pk_pad/emsa4/emsa4.cpp +++ b/src/pk_pad/emsa4/emsa4.cpp @@ -68,7 +68,7 @@ SecureVector EMSA4::encoding_of(const MemoryRegion& msg, * EMSA4 Decode/Verify Operation */ bool EMSA4::verify(const MemoryRegion& const_coded, - const MemoryRegion& raw, u32bit key_bits) throw() + const MemoryRegion& raw, u32bit key_bits) { const u32bit HASH_SIZE = hash->OUTPUT_LENGTH; const u32bit KEY_BYTES = (key_bits + 7) / 8; diff --git a/src/pk_pad/emsa4/emsa4.h b/src/pk_pad/emsa4/emsa4.h index b716178a9..9e37684f5 100644 --- a/src/pk_pad/emsa4/emsa4.h +++ b/src/pk_pad/emsa4/emsa4.h @@ -31,7 +31,7 @@ class BOTAN_DLL EMSA4 : public EMSA SecureVector encoding_of(const MemoryRegion&, u32bit, RandomNumberGenerator& rng); bool verify(const MemoryRegion&, const MemoryRegion&, - u32bit) throw(); + u32bit); u32bit SALT_SIZE; HashFunction* hash; diff --git a/src/pk_pad/emsa_raw/emsa_raw.cpp b/src/pk_pad/emsa_raw/emsa_raw.cpp index d5973ee55..5dfe20a50 100644 --- a/src/pk_pad/emsa_raw/emsa_raw.cpp +++ b/src/pk_pad/emsa_raw/emsa_raw.cpp @@ -42,7 +42,7 @@ SecureVector EMSA_Raw::encoding_of(const MemoryRegion& msg, */ bool EMSA_Raw::verify(const MemoryRegion& coded, const MemoryRegion& raw, - u32bit) throw() + u32bit) { return (coded == raw); } diff --git a/src/pk_pad/emsa_raw/emsa_raw.h b/src/pk_pad/emsa_raw/emsa_raw.h index 1b0ad516e..5f2eaa2fe 100644 --- a/src/pk_pad/emsa_raw/emsa_raw.h +++ b/src/pk_pad/emsa_raw/emsa_raw.h @@ -24,7 +24,7 @@ class BOTAN_DLL EMSA_Raw : public EMSA SecureVector encoding_of(const MemoryRegion&, u32bit, RandomNumberGenerator&); bool verify(const MemoryRegion&, const MemoryRegion&, - u32bit) throw(); + u32bit); SecureVector message; }; diff --git a/src/rng/auto_rng/auto_rng.h b/src/rng/auto_rng/auto_rng.h index f18f8e5cd..a15b11b13 100644 --- a/src/rng/auto_rng/auto_rng.h +++ b/src/rng/auto_rng/auto_rng.h @@ -23,7 +23,7 @@ class BOTAN_DLL AutoSeeded_RNG : public RandomNumberGenerator { rng->randomize(out, len); } bool is_seeded() const { return rng->is_seeded(); } - void clear() throw() { rng->clear(); } + void clear() { rng->clear(); } std::string name() const { return "AutoSeeded(" + rng->name() + ")"; } diff --git a/src/rng/hmac_rng/hmac_rng.cpp b/src/rng/hmac_rng/hmac_rng.cpp index 8444b1083..9d5ee97e4 100644 --- a/src/rng/hmac_rng/hmac_rng.cpp +++ b/src/rng/hmac_rng/hmac_rng.cpp @@ -147,7 +147,7 @@ void HMAC_RNG::add_entropy_source(EntropySource* src) /* * Clear memory of sensitive data */ -void HMAC_RNG::clear() throw() +void HMAC_RNG::clear() { extractor->clear(); prf->clear(); diff --git a/src/rng/hmac_rng/hmac_rng.h b/src/rng/hmac_rng/hmac_rng.h index 318e2a931..97b0baf15 100644 --- a/src/rng/hmac_rng/hmac_rng.h +++ b/src/rng/hmac_rng/hmac_rng.h @@ -29,7 +29,7 @@ class BOTAN_DLL HMAC_RNG : public RandomNumberGenerator public: void randomize(byte buf[], u32bit len); bool is_seeded() const { return seeded; } - void clear() throw(); + void clear(); std::string name() const; void reseed(u32bit poll_bits); diff --git a/src/rng/randpool/randpool.cpp b/src/rng/randpool/randpool.cpp index fe83f4361..9ec92267d 100644 --- a/src/rng/randpool/randpool.cpp +++ b/src/rng/randpool/randpool.cpp @@ -149,7 +149,7 @@ void Randpool::add_entropy_source(EntropySource* src) /** * Clear memory of sensitive data */ -void Randpool::clear() throw() +void Randpool::clear() { cipher->clear(); mac->clear(); diff --git a/src/rng/randpool/randpool.h b/src/rng/randpool/randpool.h index b6a3adda4..ab6ed6748 100644 --- a/src/rng/randpool/randpool.h +++ b/src/rng/randpool/randpool.h @@ -23,7 +23,7 @@ class BOTAN_DLL Randpool : public RandomNumberGenerator public: void randomize(byte[], u32bit); bool is_seeded() const { return seeded; } - void clear() throw(); + void clear(); std::string name() const; void reseed(u32bit bits_to_collect); diff --git a/src/rng/rng.h b/src/rng/rng.h index 41904dbef..c53d8e22d 100644 --- a/src/rng/rng.h +++ b/src/rng/rng.h @@ -47,7 +47,7 @@ class BOTAN_DLL RandomNumberGenerator /** * Clear all internally held values of this RNG. */ - virtual void clear() throw() = 0; + virtual void clear() = 0; /** * Return the name of this object @@ -89,7 +89,7 @@ class BOTAN_DLL Null_RNG : public RandomNumberGenerator { public: void randomize(byte[], u32bit) { throw PRNG_Unseeded("Null_RNG"); } - void clear() throw() {} + void clear() {} std::string name() const { return "Null_RNG"; } void reseed(u32bit) {} diff --git a/src/rng/x931_rng/x931_rng.cpp b/src/rng/x931_rng/x931_rng.cpp index e239bce84..64d57ac1c 100644 --- a/src/rng/x931_rng/x931_rng.cpp +++ b/src/rng/x931_rng/x931_rng.cpp @@ -108,7 +108,7 @@ bool ANSI_X931_RNG::is_seeded() const /** * Clear memory of sensitive data */ -void ANSI_X931_RNG::clear() throw() +void ANSI_X931_RNG::clear() { cipher->clear(); prng->clear(); diff --git a/src/rng/x931_rng/x931_rng.h b/src/rng/x931_rng/x931_rng.h index 44e9b4428..d5ba2e9eb 100644 --- a/src/rng/x931_rng/x931_rng.h +++ b/src/rng/x931_rng/x931_rng.h @@ -21,7 +21,7 @@ class BOTAN_DLL ANSI_X931_RNG : public RandomNumberGenerator public: void randomize(byte[], u32bit); bool is_seeded() const; - void clear() throw(); + void clear(); std::string name() const; void reseed(u32bit poll_bits); diff --git a/src/stream/arc4/arc4.cpp b/src/stream/arc4/arc4.cpp index 0f78f7362..293a0a336 100644 --- a/src/stream/arc4/arc4.cpp +++ b/src/stream/arc4/arc4.cpp @@ -87,7 +87,7 @@ std::string ARC4::name() const /* * Clear memory of sensitive data */ -void ARC4::clear() throw() +void ARC4::clear() { state.clear(); buffer.clear(); diff --git a/src/stream/arc4/arc4.h b/src/stream/arc4/arc4.h index 3f92fa914..ae37cb165 100644 --- a/src/stream/arc4/arc4.h +++ b/src/stream/arc4/arc4.h @@ -21,7 +21,7 @@ class BOTAN_DLL ARC4 : public StreamCipher public: void cipher(const byte in[], byte out[], u32bit length); - void clear() throw(); + void clear(); std::string name() const; StreamCipher* clone() const { return new ARC4(SKIP); } diff --git a/src/stream/ctr/ctr.cpp b/src/stream/ctr/ctr.cpp index 5ef5e447f..5f0880fa5 100644 --- a/src/stream/ctr/ctr.cpp +++ b/src/stream/ctr/ctr.cpp @@ -37,7 +37,7 @@ CTR_BE::~CTR_BE() /* * Zeroize */ -void CTR_BE::clear() throw() +void CTR_BE::clear() { permutation->clear(); buffer.clear(); diff --git a/src/stream/ctr/ctr.h b/src/stream/ctr/ctr.h index f60f21b5a..5f94170cc 100644 --- a/src/stream/ctr/ctr.h +++ b/src/stream/ctr/ctr.h @@ -31,7 +31,7 @@ class BOTAN_DLL CTR_BE : public StreamCipher CTR_BE* clone() const { return new CTR_BE(permutation->clone()); } - void clear() throw(); + void clear(); CTR_BE(BlockCipher*); ~CTR_BE(); diff --git a/src/stream/ofb/ofb.cpp b/src/stream/ofb/ofb.cpp index 577f61cbf..0d12d23bd 100644 --- a/src/stream/ofb/ofb.cpp +++ b/src/stream/ofb/ofb.cpp @@ -35,7 +35,7 @@ OFB::~OFB() /* * Zeroize */ -void OFB::clear() throw() +void OFB::clear() { permutation->clear(); buffer.clear(); diff --git a/src/stream/ofb/ofb.h b/src/stream/ofb/ofb.h index 5cd48716b..1985ae5a9 100644 --- a/src/stream/ofb/ofb.h +++ b/src/stream/ofb/ofb.h @@ -31,7 +31,7 @@ class BOTAN_DLL OFB : public StreamCipher OFB* clone() const { return new OFB(permutation->clone()); } - void clear() throw(); + void clear(); OFB(BlockCipher*); ~OFB(); diff --git a/src/stream/salsa20/salsa20.cpp b/src/stream/salsa20/salsa20.cpp index a147cdb45..3aae64eae 100644 --- a/src/stream/salsa20/salsa20.cpp +++ b/src/stream/salsa20/salsa20.cpp @@ -197,7 +197,7 @@ std::string Salsa20::name() const /* * Clear memory of sensitive data */ -void Salsa20::clear() throw() +void Salsa20::clear() { state.clear(); buffer.clear(); diff --git a/src/stream/salsa20/salsa20.h b/src/stream/salsa20/salsa20.h index a3e9a3706..3ca781ea2 100644 --- a/src/stream/salsa20/salsa20.h +++ b/src/stream/salsa20/salsa20.h @@ -25,7 +25,7 @@ class BOTAN_DLL Salsa20 : public StreamCipher bool valid_iv_length(u32bit iv_len) const { return (iv_len == 8); } - void clear() throw(); + void clear(); std::string name() const; StreamCipher* clone() const { return new Salsa20; } diff --git a/src/stream/stream_cipher.h b/src/stream/stream_cipher.h index d6abb37fc..29c16c8b5 100644 --- a/src/stream/stream_cipher.h +++ b/src/stream/stream_cipher.h @@ -61,7 +61,7 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm /** * Zeroize internal state */ - virtual void clear() throw() = 0; + virtual void clear() = 0; /** * StreamCipher constructor diff --git a/src/stream/turing/turing.cpp b/src/stream/turing/turing.cpp index 8336a70a7..810f65ca4 100644 --- a/src/stream/turing/turing.cpp +++ b/src/stream/turing/turing.cpp @@ -295,7 +295,7 @@ void Turing::set_iv(const byte iv[], u32bit length) /* * Clear memory of sensitive data */ -void Turing::clear() throw() +void Turing::clear() { S0.clear(); S1.clear(); diff --git a/src/stream/turing/turing.h b/src/stream/turing/turing.h index 59290f640..7291647ea 100644 --- a/src/stream/turing/turing.h +++ b/src/stream/turing/turing.h @@ -24,7 +24,7 @@ class BOTAN_DLL Turing : public StreamCipher bool valid_iv_length(u32bit iv_len) const { return (iv_len % 4 == 0 && iv_len <= 16); } - void clear() throw(); + void clear(); std::string name() const { return "Turing"; } StreamCipher* clone() const { return new Turing; } Turing() : StreamCipher(4, 32, 4) { position = 0; } diff --git a/src/stream/wid_wake/wid_wake.cpp b/src/stream/wid_wake/wid_wake.cpp index 56f938fac..2a8946649 100644 --- a/src/stream/wid_wake/wid_wake.cpp +++ b/src/stream/wid_wake/wid_wake.cpp @@ -136,7 +136,7 @@ void WiderWake_41_BE::set_iv(const byte iv[], u32bit length) /* * Clear memory of sensitive data */ -void WiderWake_41_BE::clear() throw() +void WiderWake_41_BE::clear() { position = 0; t_key.clear(); diff --git a/src/stream/wid_wake/wid_wake.h b/src/stream/wid_wake/wid_wake.h index a037a056e..23e1eacab 100644 --- a/src/stream/wid_wake/wid_wake.h +++ b/src/stream/wid_wake/wid_wake.h @@ -24,7 +24,7 @@ class BOTAN_DLL WiderWake_41_BE : public StreamCipher bool valid_iv_length(u32bit iv_len) const { return (iv_len == 8); } - void clear() throw(); + void clear(); std::string name() const { return "WiderWake4+1-BE"; } StreamCipher* clone() const { return new WiderWake_41_BE; } WiderWake_41_BE() : StreamCipher(16, 16, 1) {} diff --git a/src/sym_algo/sym_algo.h b/src/sym_algo/sym_algo.h index 1c8b816fd..929f2a6f0 100644 --- a/src/sym_algo/sym_algo.h +++ b/src/sym_algo/sym_algo.h @@ -46,7 +46,7 @@ class BOTAN_DLL SymmetricAlgorithm * Set the symmetric key of this object. * @param key the SymmetricKey to be set. */ - void set_key(const SymmetricKey& key) throw(Invalid_Key_Length) + void set_key(const SymmetricKey& key) { set_key(key.begin(), key.length()); } /** @@ -54,7 +54,7 @@ class BOTAN_DLL SymmetricAlgorithm * @param key the to be set as a byte array. * @param the length of the byte array. */ - void set_key(const byte key[], u32bit length) throw(Invalid_Key_Length) + void set_key(const byte key[], u32bit length) { if(!valid_keylength(length)) throw Invalid_Key_Length(name(), length); -- cgit v1.2.3 From 377a213c32f33d42e66bad1eb7f7c66b63c1249a Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 23 Oct 2009 01:11:46 +0000 Subject: Increase the internal buffer size of the Hex coder/decoder, and put it into a named constant instead of being magic. Move from 64 bytes to 256. This was necessary to allow Pipe(new Hex_Decoder, filter, ...) to give filter a sufficiently large input block. It would be nicer if the filter itself (in this case, ECB_Decryption, but others apply as well) was smart enough to buffer on its own. It might also be useful if code could query what parallelism a block cipher provided and modify their actions accordingly. --- src/codec/hex/hex.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/codec/hex/hex.cpp b/src/codec/hex/hex.cpp index fbacc278b..201c9bfdf 100644 --- a/src/codec/hex/hex.cpp +++ b/src/codec/hex/hex.cpp @@ -13,13 +13,15 @@ namespace Botan { +const u32bit HEX_CODEC_BUFFER_SIZE = 256; + /* * Hex_Encoder Constructor */ Hex_Encoder::Hex_Encoder(bool breaks, u32bit length, Case c) : casing(c), line_length(breaks ? length : 0) { - in.create(64); + in.create(HEX_CODEC_BUFFER_SIZE); out.create(2*in.size()); counter = position = 0; } @@ -29,7 +31,7 @@ Hex_Encoder::Hex_Encoder(bool breaks, u32bit length, Case c) : */ Hex_Encoder::Hex_Encoder(Case c) : casing(c), line_length(0) { - in.create(64); + in.create(HEX_CODEC_BUFFER_SIZE); out.create(2*in.size()); counter = position = 0; } @@ -114,7 +116,7 @@ void Hex_Encoder::end_msg() */ Hex_Decoder::Hex_Decoder(Decoder_Checking c) : checking(c) { - in.create(64); + in.create(HEX_CODEC_BUFFER_SIZE); out.create(in.size() / 2); position = 0; } -- cgit v1.2.3 From a6fc4c8a57b6a65f1b893b4f6de59b74c66ff84b Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 23 Oct 2009 01:13:56 +0000 Subject: Simply unrolling the loop in XTEA and processing 4 blocks worth of data at a time more than doubles performance (from 38 MB/s to 90 MB/s on Core2 Q6600). Could do even better with SIMD, I'm sure, but this is fast and easy, and works everywhere. Probably will hurt on 32-bit x86 from the register pressure. --- src/block/xtea/xtea.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'src') diff --git a/src/block/xtea/xtea.cpp b/src/block/xtea/xtea.cpp index 77543e1e8..83c7d9ce5 100644 --- a/src/block/xtea/xtea.cpp +++ b/src/block/xtea/xtea.cpp @@ -8,13 +8,75 @@ #include #include +#include + namespace Botan { +namespace { + +void xtea_encrypt_4(const byte in[32], byte out[32], const u32bit EK[64]) + { + u32bit L0 = load_be(in, 0), R0 = load_be(in, 1); + u32bit L1 = load_be(in, 2), R1 = load_be(in, 3); + u32bit L2 = load_be(in, 4), R2 = load_be(in, 5); + u32bit L3 = load_be(in, 6), R3 = load_be(in, 7); + + 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); + store_be(out + 16, L2, R2, L3, R3); + } + +void xtea_decrypt_4(const byte in[32], byte out[32], const u32bit EK[64]) + { + u32bit L0 = load_be(in, 0), R0 = load_be(in, 1); + u32bit L1 = load_be(in, 2), R1 = load_be(in, 3); + u32bit L2 = load_be(in, 4), R2 = load_be(in, 5); + u32bit L3 = load_be(in, 6), R3 = load_be(in, 7); + + 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); + store_be(out + 16, L2, R2, L3, R3); + } + +} + /* * XTEA Encryption */ void XTEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const { + while(blocks >= 4) + { + xtea_encrypt_4(in, out, this->EK); + in += 4 * BLOCK_SIZE; + out += 4 * BLOCK_SIZE; + blocks -= 4; + } + for(u32bit i = 0; i != blocks; ++i) { u32bit L = load_be(in, 0), R = load_be(in, 1); @@ -37,6 +99,14 @@ void XTEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const */ void XTEA::decrypt_n(const byte in[], byte out[], u32bit blocks) const { + while(blocks >= 4) + { + xtea_decrypt_4(in, out, this->EK); + in += 4 * BLOCK_SIZE; + out += 4 * BLOCK_SIZE; + blocks -= 4; + } + for(u32bit i = 0; i != blocks; ++i) { u32bit L = load_be(in, 0), R = load_be(in, 1); -- cgit v1.2.3 From fd1e0bcf053a1f154604ecd6dcd82f7e06a5726c Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 23 Oct 2009 01:25:52 +0000 Subject: Add new store_[l|b]e variants taking 8 values. Add new load options that are passed a number of variables by reference, setting them all at once. Will allow for batching operations (eg using SIMD operations to do 128-bit wide bswaps) for future optimizations. --- src/utils/loadstor.h | 124 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 108 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/utils/loadstor.h b/src/utils/loadstor.h index 8c64deaee..6f91c2fa5 100644 --- a/src/utils/loadstor.h +++ b/src/utils/loadstor.h @@ -166,6 +166,70 @@ inline u64bit load_le(const byte in[], u32bit off) #endif } +template +inline void load_le(const byte in[], T& x0, T& x1) + { + x0 = load_le(in, 0); + x1 = load_le(in, 1); + } + +template +inline void load_le(const byte in[], + T& x0, T& x1, T& x2, T& x3) + { + x0 = load_le(in, 0); + x1 = load_le(in, 1); + x2 = load_le(in, 2); + x3 = load_le(in, 3); + } + +template +inline void load_le(const byte in[], + T& x0, T& x1, T& x2, T& x3, + T& x4, T& x5, T& x6, T& x7) + { + x0 = load_le(in, 0); + x1 = load_le(in, 1); + x2 = load_le(in, 2); + x3 = load_le(in, 3); + x4 = load_le(in, 4); + x5 = load_le(in, 5); + x6 = load_le(in, 6); + x7 = load_le(in, 7); + } + +template +inline void load_be(const byte in[], T& x0, T& x1) + { + x0 = load_be(in, 0); + x1 = load_be(in, 1); + } + +template +inline void load_be(const byte in[], + T& x0, T& x1, T& x2, T& x3) + { + x0 = load_be(in, 0); + x1 = load_be(in, 1); + x2 = load_be(in, 2); + x3 = load_be(in, 3); + } + +template +inline void load_be(const byte in[], + T& x0, T& x1, T& x2, T& x3, + T& x4, T& x5, T& x6, T& x7) + { + x0 = load_be(in, 0); + x1 = load_be(in, 1); + x2 = load_be(in, 2); + x3 = load_be(in, 3); + x4 = load_be(in, 4); + x5 = load_be(in, 5); + x6 = load_be(in, 6); + x7 = load_be(in, 7); + } + /* * Endian-Specific Word Storing Operations */ @@ -246,35 +310,63 @@ inline void store_le(u64bit in, byte out[8]) } template -inline void store_le(byte out[], T a, T b) +inline void store_le(byte out[], T x0, T x1) + { + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + } + +template +inline void store_be(byte out[], T x0, T x1) + { + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + } + +template +inline void store_le(byte out[], T x0, T x1, T x2, T x3) { - store_le(a, out + (0 * sizeof(T))); - store_le(b, out + (1 * sizeof(T))); + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + store_le(x2, out + (2 * sizeof(T))); + store_le(x3, out + (3 * sizeof(T))); } template -inline void store_be(byte out[], T a, T b) +inline void store_be(byte out[], T x0, T x1, T x2, T x3) { - store_be(a, out + (0 * sizeof(T))); - store_be(b, out + (1 * sizeof(T))); + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + store_be(x2, out + (2 * sizeof(T))); + store_be(x3, out + (3 * sizeof(T))); } template -inline void store_le(byte out[], T a, T b, T c, T d) +inline void store_le(byte out[], T x0, T x1, T x2, T x3, + T x4, T x5, T x6, T x7) { - store_le(a, out + (0 * sizeof(T))); - store_le(b, out + (1 * sizeof(T))); - store_le(c, out + (2 * sizeof(T))); - store_le(d, out + (3 * sizeof(T))); + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + store_le(x2, out + (2 * sizeof(T))); + store_le(x3, out + (3 * sizeof(T))); + store_le(x4, out + (4 * sizeof(T))); + store_le(x5, out + (5 * sizeof(T))); + store_le(x6, out + (6 * sizeof(T))); + store_le(x7, out + (7 * sizeof(T))); } template -inline void store_be(byte out[], T a, T b, T c, T d) +inline void store_be(byte out[], T x0, T x1, T x2, T x3, + T x4, T x5, T x6, T x7) { - store_be(a, out + (0 * sizeof(T))); - store_be(b, out + (1 * sizeof(T))); - store_be(c, out + (2 * sizeof(T))); - store_be(d, out + (3 * sizeof(T))); + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + store_be(x2, out + (2 * sizeof(T))); + store_be(x3, out + (3 * sizeof(T))); + store_be(x4, out + (4 * sizeof(T))); + store_be(x5, out + (5 * sizeof(T))); + store_be(x6, out + (6 * sizeof(T))); + store_be(x7, out + (7 * sizeof(T))); } } -- cgit v1.2.3 From 7cb65e4e768115b9475d6e14c4fe7660c481e841 Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 23 Oct 2009 01:26:05 +0000 Subject: Use new load/store ops in xtea x4 code --- src/block/xtea/xtea.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/block/xtea/xtea.cpp b/src/block/xtea/xtea.cpp index 83c7d9ce5..1179d011a 100644 --- a/src/block/xtea/xtea.cpp +++ b/src/block/xtea/xtea.cpp @@ -16,10 +16,8 @@ namespace { void xtea_encrypt_4(const byte in[32], byte out[32], const u32bit EK[64]) { - u32bit L0 = load_be(in, 0), R0 = load_be(in, 1); - u32bit L1 = load_be(in, 2), R1 = load_be(in, 3); - u32bit L2 = load_be(in, 4), R2 = load_be(in, 5); - u32bit L3 = load_be(in, 6), R3 = load_be(in, 7); + 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) { @@ -34,16 +32,13 @@ void xtea_encrypt_4(const byte in[32], byte out[32], const u32bit EK[64]) R3 += (((L3 << 4) ^ (L3 >> 5)) + L3) ^ EK[2*i+1]; } - store_be(out , L0, R0, L1, R1); - store_be(out + 16, L2, R2, L3, R3); + 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 = load_be(in, 0), R0 = load_be(in, 1); - u32bit L1 = load_be(in, 2), R1 = load_be(in, 3); - u32bit L2 = load_be(in, 4), R2 = load_be(in, 5); - u32bit L3 = load_be(in, 6), R3 = load_be(in, 7); + 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) { @@ -58,8 +53,7 @@ void xtea_decrypt_4(const byte in[32], byte out[32], const u32bit EK[64]) L3 -= (((R3 << 4) ^ (R3 >> 5)) + R3) ^ EK[62 - 2*i]; } - store_be(out , L0, R0, L1, R1); - store_be(out + 16, L2, R2, L3, R3); + store_be(out, L0, R0, L1, R1, L2, R2, L3, R3); } } -- cgit v1.2.3 From a25f42bb52627a9fd38288e0bc345f93998cc942 Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 23 Oct 2009 01:27:12 +0000 Subject: Kill stdio include --- src/block/xtea/xtea.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/block/xtea/xtea.cpp b/src/block/xtea/xtea.cpp index 1179d011a..fc14c0a57 100644 --- a/src/block/xtea/xtea.cpp +++ b/src/block/xtea/xtea.cpp @@ -8,8 +8,6 @@ #include #include -#include - namespace Botan { namespace { -- cgit v1.2.3 From 059e215aa10c0c69ea52fb787b8b2e7ea3d1ea01 Mon Sep 17 00:00:00 2001 From: lloyd Date: Sun, 25 Oct 2009 22:29:12 +0000 Subject: Cast the u32bit output array to an int* when calling the VC++ intrinsic, since it passes signed ints for whatever reason. Ensure CALL_CPUID is always defined (previously, it would not be if on an x86 but compiled with something other than GCC, ICC, VC++). --- src/utils/cpuid.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index 63edd2737..b92afbde3 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -15,7 +15,7 @@ #if defined(BOTAN_BUILD_COMPILER_IS_MSVC) #include - #define CALL_CPUID(type, out) do { __cpuid(out, type) } while(0) + #define CALL_CPUID(type, out) do { __cpuid((int*)out, type) } while(0) #elif defined(BOTAN_BUILD_COMPILER_IS_ICC) @@ -30,9 +30,12 @@ #endif -#else +#endif + +#ifndef CALL_CPUID // In all other cases, just zeroize the supposed cpuid output - #define CALL_CPUID(type, out) out[0] = out[1] = out[2] = out[3] = 0; + #define CALL_CPUID(type, out) \ + do { out[0] = out[1] = out[2] = out[3] = 0; } while(0); #endif namespace Botan { -- cgit v1.2.3 From 7ca895a057361cba037186b771f0e4ed00a6a0f3 Mon Sep 17 00:00:00 2001 From: lloyd Date: Sun, 25 Oct 2009 22:31:29 +0000 Subject: Add ; after call to VC++'s __cpuid, not a macro --- doc/scripts/dist.sh | 19 +++++++++++++------ src/utils/cpuid.cpp | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/doc/scripts/dist.sh b/doc/scripts/dist.sh index 9629446cf..8121bcd0e 100755 --- a/doc/scripts/dist.sh +++ b/doc/scripts/dist.sh @@ -3,11 +3,18 @@ # This is probably only useful if run on my machine, which is not # exactly ideal -SELECTOR=h:net.randombit.botan.1_8 +# Make that limitation explicit +if [ $(hostname -s) != 'chihiro' ]; then + echo "This script probably won't work on this machine without fixes" + exit 1 +fi + +SELECTOR=h:net.randombit.botan KEY_ID=EFBADFBC -MTN_DB=/storage/mtn/botan.mtn -WEB_DIR=~/projects/www +MTN_DB=$HOME/var/mtn/botan.mtn +WEB_DIR=/var/www/randombit.net/ DIST_DIR=~/Botan-dist +VERSION_DIR=v1.9 # You shouldn't have to change anything after this mkdir -p $DIST_DIR @@ -26,7 +33,7 @@ rm -f .mtn-ignore # Build docs cd doc -for doc in api tutorial building +for doc in api tutorial building python do latex $doc.tex latex $doc.tex @@ -60,5 +67,5 @@ read -a PASSWORD -p "Enter PGP password (or ^C to skip signatures): " echo $PASSWORD | gpg --batch --armor -b --passphrase-fd 0 -u $KEY_ID Botan-$VERSION.tgz echo $PASSWORD | gpg --batch --armor -b --passphrase-fd 0 -u $KEY_ID Botan-$VERSION.tbz -mv Botan-$VERSION.tgz* $WEB_DIR/files/botan/v1.8 -mv Botan-$VERSION.tbz* $WEB_DIR/files/botan/v1.8 +mv Botan-$VERSION.tgz* $WEB_DIR/files/botan/${VERSION_DIR} +mv Botan-$VERSION.tbz* $WEB_DIR/files/botan/${VERSION_DIR} diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index b92afbde3..f79e3a912 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -15,7 +15,7 @@ #if defined(BOTAN_BUILD_COMPILER_IS_MSVC) #include - #define CALL_CPUID(type, out) do { __cpuid((int*)out, type) } while(0) + #define CALL_CPUID(type, out) do { __cpuid((int*)out, type); } while(0) #elif defined(BOTAN_BUILD_COMPILER_IS_ICC) -- cgit v1.2.3 From 49896908c8a7893586271e353c431bb91b5215a8 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 26 Oct 2009 17:37:44 +0000 Subject: Add a wrapper for a set of SSE2 operations with convenient syntax for 4x32 operations. Also add a pure scalar code version. Convert Serpent to use this new interface, and add an implementation of XTEA in SIMD. The wrappers plus the scalar version allow SIMD-ish code to work on all platforms. This is often a win due to better ILP being visible to the processor (as with the recent XTEA optimizations). Only real danger is register starvation, mostly an issue on x86 these days. So it may (or may not) be a win to consolidate the standard C++ versions and the SIMD versions together. Future work: - Add AltiVec/VMX version - Maybe also for ARM's NEON extension? Less pressing, I would think. - Convert SHA-1 code to use SIMD_32 - Add XTEA SIMD decryption (currently only encrypt) - Change SSE2 engine to SIMD_engine - Modify configure.py to set BOTAN_TARGET_CPU_HAS_[SSE2|ALTIVEC|NEON|XXX] macros --- src/block/serpent_sse2/serp_sse2.cpp | 142 +++----- src/block/serpent_sse2/serp_sse2_sbox.h | 622 ++++++++++++++++---------------- src/block/xtea/xtea.h | 2 +- src/block/xtea_sse2/info.txt | 15 + src/block/xtea_sse2/xtea_sse2.cpp | 88 +++++ src/block/xtea_sse2/xtea_sse2.h | 28 ++ src/engine/sse2_eng/eng_sse2.cpp | 9 + src/utils/simd_32/info.txt | 18 + src/utils/simd_32/simd_32.h | 29 ++ src/utils/simd_32/simd_scalar.h | 172 +++++++++ src/utils/simd_32/simd_sse.h | 141 ++++++++ 11 files changed, 862 insertions(+), 404 deletions(-) create mode 100644 src/block/xtea_sse2/info.txt create mode 100644 src/block/xtea_sse2/xtea_sse2.cpp create mode 100644 src/block/xtea_sse2/xtea_sse2.h create mode 100644 src/utils/simd_32/info.txt create mode 100644 src/utils/simd_32/simd_32.h create mode 100644 src/utils/simd_32/simd_scalar.h create mode 100644 src/utils/simd_32/simd_sse.h (limited to 'src') diff --git a/src/block/serpent_sse2/serp_sse2.cpp b/src/block/serpent_sse2/serp_sse2.cpp index c51bb69ab..be79e870d 100644 --- a/src/block/serpent_sse2/serp_sse2.cpp +++ b/src/block/serpent_sse2/serp_sse2.cpp @@ -1,5 +1,5 @@ /* -* Serpent (SSE2) +* Serpent (SIMD) * (C) 2009 Jack Lloyd * * Distributed under the terms of the Botan license @@ -7,72 +7,50 @@ #include #include +#include #include -#include namespace Botan { namespace { -#define key_xor(round, B0, B1, B2, B3) \ - do { \ - __m128i key = _mm_loadu_si128(keys + round); \ - B0 = _mm_xor_si128(B0, _mm_shuffle_epi32(key, _MM_SHUFFLE(0,0,0,0))); \ - B1 = _mm_xor_si128(B1, _mm_shuffle_epi32(key, _MM_SHUFFLE(1,1,1,1))); \ - B2 = _mm_xor_si128(B2, _mm_shuffle_epi32(key, _MM_SHUFFLE(2,2,2,2))); \ - B3 = _mm_xor_si128(B3, _mm_shuffle_epi32(key, _MM_SHUFFLE(3,3,3,3))); \ +#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 rotate_left_m128(vec, rot) \ - _mm_or_si128(_mm_slli_epi32(vec, rot), _mm_srli_epi32(vec, 32-rot)) - -#define rotate_right_m128(vec, rot) \ - _mm_or_si128(_mm_srli_epi32(vec, rot), _mm_slli_epi32(vec, 32-rot)) - -#define transform(B0, B1, B2, B3) \ - do { \ - B0 = rotate_left_m128(B0, 13); \ - B2 = rotate_left_m128(B2, 3); \ - B1 = _mm_xor_si128(B1, _mm_xor_si128(B0, B2)); \ - B3 = _mm_xor_si128(B3, _mm_xor_si128(B2, _mm_slli_epi32(B0, 3))); \ - B1 = rotate_left_m128(B1, 1); \ - B3 = rotate_left_m128(B3, 7); \ - B0 = _mm_xor_si128(B0, _mm_xor_si128(B1, B3)); \ - B2 = _mm_xor_si128(B2, _mm_xor_si128(B3, _mm_slli_epi32(B1, 7))); \ - B0 = rotate_left_m128(B0, 5); \ - B2 = rotate_left_m128(B2, 22); \ +#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_m128(B2, 22); \ - B0 = rotate_right_m128(B0, 5); \ - B2 = _mm_xor_si128(B2, _mm_xor_si128(B3, _mm_slli_epi32(B1, 7))); \ - B0 = _mm_xor_si128(B0, _mm_xor_si128(B1, B3)); \ - B3 = rotate_right_m128(B3, 7); \ - B1 = rotate_right_m128(B1, 1); \ - B3 = _mm_xor_si128(B3, _mm_xor_si128(B2, _mm_slli_epi32(B0, 3))); \ - B1 = _mm_xor_si128(B1, _mm_xor_si128(B0, B2)); \ - B2 = rotate_right_m128(B2, 3); \ - B0 = rotate_right_m128(B0, 13); \ - } while(0); - -/* -* 4x4 SSE2 integer matrix transpose -*/ -#define transpose(B0, B1, B2, B3) \ - do { \ - __m128i T0 = _mm_unpacklo_epi32(B0, B1); \ - __m128i T1 = _mm_unpacklo_epi32(B2, B3); \ - __m128i T2 = _mm_unpackhi_epi32(B0, B1); \ - __m128i T3 = _mm_unpackhi_epi32(B2, B3); \ - B0 = _mm_unpacklo_epi64(T0, T1); \ - B1 = _mm_unpackhi_epi64(T0, T1); \ - B2 = _mm_unpacklo_epi64(T2, T3); \ - B3 = _mm_unpackhi_epi64(T2, T3); \ +#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); /* @@ -80,20 +58,14 @@ namespace { */ void serpent_encrypt_4(const byte in[64], byte out[64], - const u32bit keys_32[132]) + const u32bit keys[132]) { - const __m128i all_ones = _mm_set1_epi8(0xFF); + 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); - const __m128i* keys = (const __m128i*)(keys_32); - __m128i* out_mm = (__m128i*)(out); - __m128i* in_mm = (__m128i*)(in); - - __m128i B0 = _mm_loadu_si128(in_mm); - __m128i B1 = _mm_loadu_si128(in_mm + 1); - __m128i B2 = _mm_loadu_si128(in_mm + 2); - __m128i B3 = _mm_loadu_si128(in_mm + 3); - - transpose(B0, B1, B2, B3); + 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); @@ -131,12 +103,12 @@ void serpent_encrypt_4(const byte in[64], 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); - transpose(B0, B1, B2, B3); + SIMD_32::transpose(B0, B1, B2, B3); - _mm_storeu_si128(out_mm , B0); - _mm_storeu_si128(out_mm + 1, B1); - _mm_storeu_si128(out_mm + 2, B2); - _mm_storeu_si128(out_mm + 3, B3); + B0.store_le(out); + B1.store_le(out + 16); + B2.store_le(out + 32); + B3.store_le(out + 48); } /* @@ -144,20 +116,14 @@ void serpent_encrypt_4(const byte in[64], */ void serpent_decrypt_4(const byte in[64], byte out[64], - const u32bit keys_32[132]) + const u32bit keys[132]) { - const __m128i all_ones = _mm_set1_epi8(0xFF); - - const __m128i* keys = (const __m128i*)(keys_32); - __m128i* out_mm = (__m128i*)(out); - __m128i* in_mm = (__m128i*)(in); - - __m128i B0 = _mm_loadu_si128(in_mm); - __m128i B1 = _mm_loadu_si128(in_mm + 1); - __m128i B2 = _mm_loadu_si128(in_mm + 2); - __m128i B3 = _mm_loadu_si128(in_mm + 3); + 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); - transpose(B0, B1, B2, B3); + 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); @@ -195,12 +161,12 @@ void serpent_decrypt_4(const byte in[64], 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); - transpose(B0, B1, B2, B3); + SIMD_32::transpose(B0, B1, B2, B3); - _mm_storeu_si128(out_mm , B0); - _mm_storeu_si128(out_mm + 1, B1); - _mm_storeu_si128(out_mm + 2, B2); - _mm_storeu_si128(out_mm + 3, B3); + B0.store_le(out); + B1.store_le(out + 16); + B2.store_le(out + 32); + B3.store_le(out + 48); } } diff --git a/src/block/serpent_sse2/serp_sse2_sbox.h b/src/block/serpent_sse2/serp_sse2_sbox.h index 40c552e87..6e3da7359 100644 --- a/src/block/serpent_sse2/serp_sse2_sbox.h +++ b/src/block/serpent_sse2/serp_sse2_sbox.h @@ -1,33 +1,33 @@ /* -* Serpent Sboxes in SSE2 form +* Serpent Sboxes in SIMD form * (C) 2009 Jack Lloyd * * Distributed under the terms of the Botan license */ -#ifndef SERPENT_SSE2_SBOXES_H__ -#define SERPENT_SSE2_SBOXES_H__ +#ifndef SERPENT_SIMD_SBOXES_H__ +#define SERPENT_SIMD_SBOXES_H__ #define SBoxE1(B0, B1, B2, B3) \ do { \ - B3 = _mm_xor_si128(B3, B0); \ - __m128i B4 = B1; \ - B1 = _mm_and_si128(B1, B3); \ - B4 = _mm_xor_si128(B4, B2); \ - B1 = _mm_xor_si128(B1, B0); \ - B0 = _mm_or_si128(B0, B3); \ - B0 = _mm_xor_si128(B0, B4); \ - B4 = _mm_xor_si128(B4, B3); \ - B3 = _mm_xor_si128(B3, B2); \ - B2 = _mm_or_si128(B2, B1); \ - B2 = _mm_xor_si128(B2, B4); \ - B4 = _mm_xor_si128(B4, all_ones); \ - B4 = _mm_or_si128(B4, B1); \ - B1 = _mm_xor_si128(B1, B3); \ - B1 = _mm_xor_si128(B1, B4); \ - B3 = _mm_or_si128(B3, B0); \ - B1 = _mm_xor_si128(B1, B3); \ - B4 = _mm_xor_si128(B4, B3); \ + 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; \ @@ -35,24 +35,24 @@ #define SBoxE2(B0, B1, B2, B3) \ do { \ - B0 = _mm_xor_si128(B0, all_ones); \ - B2 = _mm_xor_si128(B2, all_ones); \ - __m128i B4 = B0; \ - B0 = _mm_and_si128(B0, B1); \ - B2 = _mm_xor_si128(B2, B0); \ - B0 = _mm_or_si128(B0, B3); \ - B3 = _mm_xor_si128(B3, B2); \ - B1 = _mm_xor_si128(B1, B0); \ - B0 = _mm_xor_si128(B0, B4); \ - B4 = _mm_or_si128(B4, B1); \ - B1 = _mm_xor_si128(B1, B3); \ - B2 = _mm_or_si128(B2, B0); \ - B2 = _mm_and_si128(B2, B4); \ - B0 = _mm_xor_si128(B0, B1); \ - B1 = _mm_and_si128(B1, B2); \ - B1 = _mm_xor_si128(B1, B0); \ - B0 = _mm_and_si128(B0, B2); \ - B4 = _mm_xor_si128(B4, B0); \ + 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; \ @@ -61,22 +61,22 @@ #define SBoxE3(B0, B1, B2, B3) \ do { \ - __m128i B4 = B0; \ - B0 = _mm_and_si128(B0, B2); \ - B0 = _mm_xor_si128(B0, B3); \ - B2 = _mm_xor_si128(B2, B1); \ - B2 = _mm_xor_si128(B2, B0); \ - B3 = _mm_or_si128(B3, B4); \ - B3 = _mm_xor_si128(B3, B1); \ - B4 = _mm_xor_si128(B4, B2); \ + SIMD_32 B4 = B0; \ + B0 &= B2; \ + B0 ^= B3; \ + B2 ^= B1; \ + B2 ^= B0; \ + B3 |= B4; \ + B3 ^= B1; \ + B4 ^= B2; \ B1 = B3; \ - B3 = _mm_or_si128(B3, B4); \ - B3 = _mm_xor_si128(B3, B0); \ - B0 = _mm_and_si128(B0, B1); \ - B4 = _mm_xor_si128(B4, B0); \ - B1 = _mm_xor_si128(B1, B3); \ - B1 = _mm_xor_si128(B1, B4); \ - B4 = _mm_xor_si128(B4, all_ones); \ + B3 |= B4; \ + B3 ^= B0; \ + B0 &= B1; \ + B4 ^= B0; \ + B1 ^= B3; \ + B1 ^= B4; \ + B4 = ~B4; \ B0 = B2; \ B2 = B1; \ B1 = B3; \ @@ -85,25 +85,25 @@ #define SBoxE4(B0, B1, B2, B3) \ do { \ - __m128i B4 = B0; \ - B0 = _mm_or_si128(B0, B3); \ - B3 = _mm_xor_si128(B3, B1); \ - B1 = _mm_and_si128(B1, B4); \ - B4 = _mm_xor_si128(B4, B2); \ - B2 = _mm_xor_si128(B2, B3); \ - B3 = _mm_and_si128(B3, B0); \ - B4 = _mm_or_si128(B4, B1); \ - B3 = _mm_xor_si128(B3, B4); \ - B0 = _mm_xor_si128(B0, B1); \ - B4 = _mm_and_si128(B4, B0); \ - B1 = _mm_xor_si128(B1, B3); \ - B4 = _mm_xor_si128(B4, B2); \ - B1 = _mm_or_si128(B1, B0); \ - B1 = _mm_xor_si128(B1, B2); \ - B0 = _mm_xor_si128(B0, B3); \ + 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 = _mm_or_si128(B1, B3); \ - B0 = _mm_xor_si128(B0, B1); \ + B1 |= B3; \ + B0 ^= B1; \ B1 = B2; \ B2 = B3; \ B3 = B4; \ @@ -111,26 +111,26 @@ #define SBoxE5(B0, B1, B2, B3) \ do { \ - B1 = _mm_xor_si128(B1, B3); \ - B3 = _mm_xor_si128(B3, all_ones); \ - B2 = _mm_xor_si128(B2, B3); \ - B3 = _mm_xor_si128(B3, B0); \ - __m128i B4 = B1; \ - B1 = _mm_and_si128(B1, B3); \ - B1 = _mm_xor_si128(B1, B2); \ - B4 = _mm_xor_si128(B4, B3); \ - B0 = _mm_xor_si128(B0, B4); \ - B2 = _mm_and_si128(B2, B4); \ - B2 = _mm_xor_si128(B2, B0); \ - B0 = _mm_and_si128(B0, B1); \ - B3 = _mm_xor_si128(B3, B0); \ - B4 = _mm_or_si128(B4, B1); \ - B4 = _mm_xor_si128(B4, B0); \ - B0 = _mm_or_si128(B0, B3); \ - B0 = _mm_xor_si128(B0, B2); \ - B2 = _mm_and_si128(B2, B3); \ - B0 = _mm_xor_si128(B0, all_ones); \ - B4 = _mm_xor_si128(B4, B2); \ + 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; \ @@ -138,25 +138,25 @@ #define SBoxE6(B0, B1, B2, B3) \ do { \ - B0 = _mm_xor_si128(B0, B1); \ - B1 = _mm_xor_si128(B1, B3); \ - B3 = _mm_xor_si128(B3, all_ones); \ - __m128i B4 = B1; \ - B1 = _mm_and_si128(B1, B0); \ - B2 = _mm_xor_si128(B2, B3); \ - B1 = _mm_xor_si128(B1, B2); \ - B2 = _mm_or_si128(B2, B4); \ - B4 = _mm_xor_si128(B4, B3); \ - B3 = _mm_and_si128(B3, B1); \ - B3 = _mm_xor_si128(B3, B0); \ - B4 = _mm_xor_si128(B4, B1); \ - B4 = _mm_xor_si128(B4, B2); \ - B2 = _mm_xor_si128(B2, B0); \ - B0 = _mm_and_si128(B0, B3); \ - B2 = _mm_xor_si128(B2, all_ones); \ - B0 = _mm_xor_si128(B0, B4); \ - B4 = _mm_or_si128(B4, B3); \ - B4 = _mm_xor_si128(B4, B2); \ + 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; \ @@ -165,49 +165,49 @@ #define SBoxE7(B0, B1, B2, B3) \ do { \ - B2 = _mm_xor_si128(B2, all_ones); \ - __m128i B4 = B3; \ - B3 = _mm_and_si128(B3, B0); \ - B0 = _mm_xor_si128(B0, B4); \ - B3 = _mm_xor_si128(B3, B2); \ - B2 = _mm_or_si128(B2, B4); \ - B1 = _mm_xor_si128(B1, B3); \ - B2 = _mm_xor_si128(B2, B0); \ - B0 = _mm_or_si128(B0, B1); \ - B2 = _mm_xor_si128(B2, B1); \ - B4 = _mm_xor_si128(B4, B0); \ - B0 = _mm_or_si128(B0, B3); \ - B0 = _mm_xor_si128(B0, B2); \ - B4 = _mm_xor_si128(B4, B3); \ - B4 = _mm_xor_si128(B4, B0); \ - B3 = _mm_xor_si128(B3, all_ones); \ - B2 = _mm_and_si128(B2, B4); \ - B3 = _mm_xor_si128(B3, B2); \ + 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 { \ - __m128i B4 = B1; \ - B1 = _mm_or_si128(B1, B2); \ - B1 = _mm_xor_si128(B1, B3); \ - B4 = _mm_xor_si128(B4, B2); \ - B2 = _mm_xor_si128(B2, B1); \ - B3 = _mm_or_si128(B3, B4); \ - B3 = _mm_and_si128(B3, B0); \ - B4 = _mm_xor_si128(B4, B2); \ - B3 = _mm_xor_si128(B3, B1); \ - B1 = _mm_or_si128(B1, B4); \ - B1 = _mm_xor_si128(B1, B0); \ - B0 = _mm_or_si128(B0, B4); \ - B0 = _mm_xor_si128(B0, B2); \ - B1 = _mm_xor_si128(B1, B4); \ - B2 = _mm_xor_si128(B2, B1); \ - B1 = _mm_and_si128(B1, B0); \ - B1 = _mm_xor_si128(B1, B4); \ - B2 = _mm_xor_si128(B2, all_ones); \ - B2 = _mm_or_si128(B2, B0); \ - B4 = _mm_xor_si128(B4, B2); \ + 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; \ @@ -215,53 +215,51 @@ } while(0); #define SBoxD1(B0, B1, B2, B3) \ - do \ - { \ - B2 = _mm_xor_si128(B2, all_ones); \ - __m128i B4 = B1; \ - B1 = _mm_or_si128(B1, B0); \ - B4 = _mm_xor_si128(B4, all_ones); \ - B1 = _mm_xor_si128(B1, B2); \ - B2 = _mm_or_si128(B2, B4); \ - B1 = _mm_xor_si128(B1, B3); \ - B0 = _mm_xor_si128(B0, B4); \ - B2 = _mm_xor_si128(B2, B0); \ - B0 = _mm_and_si128(B0, B3); \ - B4 = _mm_xor_si128(B4, B0); \ - B0 = _mm_or_si128(B0, B1); \ - B0 = _mm_xor_si128(B0, B2); \ - B3 = _mm_xor_si128(B3, B4); \ - B2 = _mm_xor_si128(B2, B1); \ - B3 = _mm_xor_si128(B3, B0); \ - B3 = _mm_xor_si128(B3, B1); \ - B2 = _mm_and_si128(B2, B3); \ - B4 = _mm_xor_si128(B4, B2); \ + 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 \ - { \ - __m128i B4 = B1; \ - B1 = _mm_xor_si128(B1, B3); \ - B3 = _mm_and_si128(B3, B1); \ - B4 = _mm_xor_si128(B4, B2); \ - B3 = _mm_xor_si128(B3, B0); \ - B0 = _mm_or_si128(B0, B1); \ - B2 = _mm_xor_si128(B2, B3); \ - B0 = _mm_xor_si128(B0, B4); \ - B0 = _mm_or_si128(B0, B2); \ - B1 = _mm_xor_si128(B1, B3); \ - B0 = _mm_xor_si128(B0, B1); \ - B1 = _mm_or_si128(B1, B3); \ - B1 = _mm_xor_si128(B1, B0); \ - B4 = _mm_xor_si128(B4, all_ones); \ - B4 = _mm_xor_si128(B4, B1); \ - B1 = _mm_or_si128(B1, B0); \ - B1 = _mm_xor_si128(B1, B0); \ - B1 = _mm_or_si128(B1, B4); \ - B3 = _mm_xor_si128(B3, B1); \ + 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; \ @@ -270,52 +268,50 @@ } while(0); #define SBoxD3(B0, B1, B2, B3) \ - do \ - { \ - B2 = _mm_xor_si128(B2, B3); \ - B3 = _mm_xor_si128(B3, B0); \ - __m128i B4 = B3; \ - B3 = _mm_and_si128(B3, B2); \ - B3 = _mm_xor_si128(B3, B1); \ - B1 = _mm_or_si128(B1, B2); \ - B1 = _mm_xor_si128(B1, B4); \ - B4 = _mm_and_si128(B4, B3); \ - B2 = _mm_xor_si128(B2, B3); \ - B4 = _mm_and_si128(B4, B0); \ - B4 = _mm_xor_si128(B4, B2); \ - B2 = _mm_and_si128(B2, B1); \ - B2 = _mm_or_si128(B2, B0); \ - B3 = _mm_xor_si128(B3, all_ones); \ - B2 = _mm_xor_si128(B2, B3); \ - B0 = _mm_xor_si128(B0, B3); \ - B0 = _mm_and_si128(B0, B1); \ - B3 = _mm_xor_si128(B3, B4); \ - B3 = _mm_xor_si128(B3, B0); \ + 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 \ - { \ - __m128i B4 = B2; \ - B2 = _mm_xor_si128(B2, B1); \ - B0 = _mm_xor_si128(B0, B2); \ - B4 = _mm_and_si128(B4, B2); \ - B4 = _mm_xor_si128(B4, B0); \ - B0 = _mm_and_si128(B0, B1); \ - B1 = _mm_xor_si128(B1, B3); \ - B3 = _mm_or_si128(B3, B4); \ - B2 = _mm_xor_si128(B2, B3); \ - B0 = _mm_xor_si128(B0, B3); \ - B1 = _mm_xor_si128(B1, B4); \ - B3 = _mm_and_si128(B3, B2); \ - B3 = _mm_xor_si128(B3, B1); \ - B1 = _mm_xor_si128(B1, B0); \ - B1 = _mm_or_si128(B1, B2); \ - B0 = _mm_xor_si128(B0, B3); \ - B1 = _mm_xor_si128(B1, B4); \ - B0 = _mm_xor_si128(B0, B1); \ + 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; \ @@ -323,54 +319,52 @@ } while(0); #define SBoxD5(B0, B1, B2, B3) \ - do \ - { \ - __m128i B4 = B2; \ - B2 = _mm_and_si128(B2, B3); \ - B2 = _mm_xor_si128(B2, B1); \ - B1 = _mm_or_si128(B1, B3); \ - B1 = _mm_and_si128(B1, B0); \ - B4 = _mm_xor_si128(B4, B2); \ - B4 = _mm_xor_si128(B4, B1); \ - B1 = _mm_and_si128(B1, B2); \ - B0 = _mm_xor_si128(B0, all_ones); \ - B3 = _mm_xor_si128(B3, B4); \ - B1 = _mm_xor_si128(B1, B3); \ - B3 = _mm_and_si128(B3, B0); \ - B3 = _mm_xor_si128(B3, B2); \ - B0 = _mm_xor_si128(B0, B1); \ - B2 = _mm_and_si128(B2, B0); \ - B3 = _mm_xor_si128(B3, B0); \ - B2 = _mm_xor_si128(B2, B4); \ - B2 = _mm_or_si128(B2, B3); \ - B3 = _mm_xor_si128(B3, B0); \ - B2 = _mm_xor_si128(B2, B1); \ + 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 = _mm_xor_si128(B1, all_ones); \ - __m128i B4 = B3; \ - B2 = _mm_xor_si128(B2, B1); \ - B3 = _mm_or_si128(B3, B0); \ - B3 = _mm_xor_si128(B3, B2); \ - B2 = _mm_or_si128(B2, B1); \ - B2 = _mm_and_si128(B2, B0); \ - B4 = _mm_xor_si128(B4, B3); \ - B2 = _mm_xor_si128(B2, B4); \ - B4 = _mm_or_si128(B4, B0); \ - B4 = _mm_xor_si128(B4, B1); \ - B1 = _mm_and_si128(B1, B2); \ - B1 = _mm_xor_si128(B1, B3); \ - B4 = _mm_xor_si128(B4, B2); \ - B3 = _mm_and_si128(B3, B4); \ - B4 = _mm_xor_si128(B4, B1); \ - B3 = _mm_xor_si128(B3, B4); \ - B4 = _mm_xor_si128(B4, all_ones); \ - B3 = _mm_xor_si128(B3, B0); \ + 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; \ @@ -379,52 +373,50 @@ } while(0); #define SBoxD7(B0, B1, B2, B3) \ - do \ - { \ - B0 = _mm_xor_si128(B0, B2); \ - __m128i B4 = B2; \ - B2 = _mm_and_si128(B2, B0); \ - B4 = _mm_xor_si128(B4, B3); \ - B2 = _mm_xor_si128(B2, all_ones); \ - B3 = _mm_xor_si128(B3, B1); \ - B2 = _mm_xor_si128(B2, B3); \ - B4 = _mm_or_si128(B4, B0); \ - B0 = _mm_xor_si128(B0, B2); \ - B3 = _mm_xor_si128(B3, B4); \ - B4 = _mm_xor_si128(B4, B1); \ - B1 = _mm_and_si128(B1, B3); \ - B1 = _mm_xor_si128(B1, B0); \ - B0 = _mm_xor_si128(B0, B3); \ - B0 = _mm_or_si128(B0, B2); \ - B3 = _mm_xor_si128(B3, B1); \ - B4 = _mm_xor_si128(B4, B0); \ + 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 \ - { \ - __m128i B4 = B2; \ - B2 = _mm_xor_si128(B2, B0); \ - B0 = _mm_and_si128(B0, B3); \ - B4 = _mm_or_si128(B4, B3); \ - B2 = _mm_xor_si128(B2, all_ones); \ - B3 = _mm_xor_si128(B3, B1); \ - B1 = _mm_or_si128(B1, B0); \ - B0 = _mm_xor_si128(B0, B2); \ - B2 = _mm_and_si128(B2, B4); \ - B3 = _mm_and_si128(B3, B4); \ - B1 = _mm_xor_si128(B1, B2); \ - B2 = _mm_xor_si128(B2, B0); \ - B0 = _mm_or_si128(B0, B2); \ - B4 = _mm_xor_si128(B4, B1); \ - B0 = _mm_xor_si128(B0, B3); \ - B3 = _mm_xor_si128(B3, B4); \ - B4 = _mm_or_si128(B4, B0); \ - B3 = _mm_xor_si128(B3, B2); \ - B4 = _mm_xor_si128(B4, B2); \ + 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; \ diff --git a/src/block/xtea/xtea.h b/src/block/xtea/xtea.h index f3b554edb..9982d0712 100644 --- a/src/block/xtea/xtea.h +++ b/src/block/xtea/xtea.h @@ -26,7 +26,7 @@ class BOTAN_DLL XTEA : public BlockCipher BlockCipher* clone() const { return new XTEA; } XTEA() : BlockCipher(8, 16) {} - private: + protected: void key_schedule(const byte[], u32bit); SecureBuffer EK; }; diff --git a/src/block/xtea_sse2/info.txt b/src/block/xtea_sse2/info.txt new file mode 100644 index 000000000..edcdd114d --- /dev/null +++ b/src/block/xtea_sse2/info.txt @@ -0,0 +1,15 @@ +realname "XTEA (SSE2)" + +define XTEA_SSE2 + +load_on auto + + +xtea_sse2.cpp +xtea_sse2.h + + + +xtea +sse2_eng + diff --git a/src/block/xtea_sse2/xtea_sse2.cpp b/src/block/xtea_sse2/xtea_sse2.cpp new file mode 100644 index 000000000..db7775103 --- /dev/null +++ b/src/block/xtea_sse2/xtea_sse2.cpp @@ -0,0 +1,88 @@ +/* +* XTEA SSE2 +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include + +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]), K1(EK[2*i+1]), K2(EK[2*i+2]), 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); + } + +} + +/* +* XTEA Encryption +*/ +void XTEA_SSE2::encrypt_n(const byte in[], byte out[], u32bit blocks) const + { + memset(out, 0, blocks * BLOCK_SIZE); + + 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_SSE2::decrypt_n(const byte in[], byte out[], u32bit blocks) const + { +#if 0 + while(blocks >= 4) + { + xtea_decrypt_4(in, out, this->EK); + in += 4 * BLOCK_SIZE; + out += 4 * BLOCK_SIZE; + blocks -= 4; + } +#endif + + XTEA::decrypt_n(in, out, blocks); + } + +} diff --git a/src/block/xtea_sse2/xtea_sse2.h b/src/block/xtea_sse2/xtea_sse2.h new file mode 100644 index 000000000..e691e5c40 --- /dev/null +++ b/src/block/xtea_sse2/xtea_sse2.h @@ -0,0 +1,28 @@ +/* +* XTEA in SSE2 +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_XTEA_SSE2_H__ +#define BOTAN_XTEA_SSE2_H__ + +#include + +namespace Botan { + +/* +* XTEA (SSE2 variant) +*/ +class BOTAN_DLL XTEA_SSE2 : 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_SSE2; } + }; + +} + +#endif diff --git a/src/engine/sse2_eng/eng_sse2.cpp b/src/engine/sse2_eng/eng_sse2.cpp index 07c625c7c..51b7d04e3 100644 --- a/src/engine/sse2_eng/eng_sse2.cpp +++ b/src/engine/sse2_eng/eng_sse2.cpp @@ -16,6 +16,10 @@ #include #endif +#if defined(BOTAN_HAS_XTEA_SSE2) + #include +#endif + namespace Botan { BlockCipher* @@ -30,6 +34,11 @@ SSE2_Assembler_Engine::find_block_cipher(const SCAN_Name& request, return new Serpent_SSE2; #endif +#if defined(BOTAN_HAS_XTEA_SSE2) + if(request.algo_name() == "XTEA") + return new XTEA_SSE2; +#endif + return 0; } diff --git a/src/utils/simd_32/info.txt b/src/utils/simd_32/info.txt new file mode 100644 index 000000000..c72f2a6ed --- /dev/null +++ b/src/utils/simd_32/info.txt @@ -0,0 +1,18 @@ +realname "SIMD" + +define SIMD_32 + +load_on always + + +pentium-m +pentium4 +prescott +amd64 + + + +gcc +icc +msvc + diff --git a/src/utils/simd_32/simd_32.h b/src/utils/simd_32/simd_32.h new file mode 100644 index 000000000..d9fac0d3d --- /dev/null +++ b/src/utils/simd_32/simd_32.h @@ -0,0 +1,29 @@ +/** +* Lightweight wrappers for SIMD operations +*/ + +#ifndef BOTAN_SIMD_32_H__ +#define BOTAN_SIMD_32_H__ + +#include + +//#define BOTAN_TARGET_CPU_HAS_SSE2 + +#if defined(BOTAN_TARGET_CPU_HAS_SSE2) + + #include + namespace Botan { typedef SIMD_SSE2 SIMD_32; } + +#elif defined(BOTAN_TARGET_CPU_HAS_ALTIVEC) + + #include + namespace Botan { typedef SIMD_Altivec SIMD_32; } + +#else + + #include + namespace Botan { typedef SIMD_Scalar SIMD_32; } + +#endif + +#endif diff --git a/src/utils/simd_32/simd_scalar.h b/src/utils/simd_32/simd_scalar.h new file mode 100644 index 000000000..a6067f115 --- /dev/null +++ b/src/utils/simd_32/simd_scalar.h @@ -0,0 +1,172 @@ +/** +* Scalar emulation of SIMD operations +*/ + +#ifndef BOTAN_SIMD_SCALAR_H__ +#define BOTAN_SIMD_SCALAR_H__ + +#include + +namespace Botan { + +class SIMD_Scalar + { + public: + SIMD_Scalar(const u32bit B[4]) + { + R0 = B[0]; + R1 = B[1]; + R2 = B[2]; + R3 = B[3]; + } + + SIMD_Scalar(u32bit B0, u32bit B1, u32bit B2, u32bit B3) + { + R0 = B0; + R1 = B1; + R2 = B2; + R3 = B3; + } + + SIMD_Scalar(u32bit B) + { + R0 = B; + R1 = B; + R2 = B; + R3 = B; + } + + static SIMD_Scalar load_le(const void* in) + { + const byte* in_b = static_cast(in); + return SIMD_Scalar(Botan::load_le(in_b, 0), + Botan::load_le(in_b, 1), + Botan::load_le(in_b, 2), + Botan::load_le(in_b, 3)); + } + + static SIMD_Scalar load_be(const void* in) + { + const byte* in_b = static_cast(in); + return SIMD_Scalar(Botan::load_be(in_b, 0), + Botan::load_be(in_b, 1), + Botan::load_be(in_b, 2), + Botan::load_be(in_b, 3)); + } + + void store_le(byte out[]) const + { + Botan::store_le(out, R0, R1, R2, R3); + } + + void store_be(byte out[]) const + { + Botan::store_be(out, R0, R1, R2, R3); + } + + void rotate_left(u32bit rot) + { + R0 = Botan::rotate_left(R0, rot); + R1 = Botan::rotate_left(R1, rot); + R2 = Botan::rotate_left(R2, rot); + R3 = Botan::rotate_left(R3, rot); + } + + void rotate_right(u32bit rot) + { + R0 = Botan::rotate_right(R0, rot); + R1 = Botan::rotate_right(R1, rot); + R2 = Botan::rotate_right(R2, rot); + R3 = Botan::rotate_right(R3, rot); + } + + void operator+=(const SIMD_Scalar& other) + { + R0 += other.R0; + R1 += other.R1; + R2 += other.R2; + R3 += other.R3; + } + + SIMD_Scalar operator+(const SIMD_Scalar& other) const + { + return SIMD_Scalar(R0 + other.R0, + R1 + other.R1, + R2 + other.R2, + R3 + other.R3); + } + + void operator^=(const SIMD_Scalar& other) + { + R0 ^= other.R0; + R1 ^= other.R1; + R2 ^= other.R2; + R3 ^= other.R3; + } + + SIMD_Scalar operator^(const SIMD_Scalar& other) const + { + return SIMD_Scalar(R0 ^ other.R0, + R1 ^ other.R1, + R2 ^ other.R2, + R3 ^ other.R3); + } + + void operator|=(const SIMD_Scalar& other) + { + R0 |= other.R0; + R1 |= other.R1; + R2 |= other.R2; + R3 |= other.R3; + } + + void operator&=(const SIMD_Scalar& other) + { + R0 &= other.R0; + R1 &= other.R1; + R2 &= other.R2; + R3 &= other.R3; + } + + SIMD_Scalar operator<<(u32bit shift) const + { + return SIMD_Scalar(R0 << shift, + R1 << shift, + R2 << shift, + R3 << shift); + } + + SIMD_Scalar operator>>(u32bit shift) const + { + return SIMD_Scalar(R0 >> shift, + R1 >> shift, + R2 >> shift, + R3 >> shift); + } + + SIMD_Scalar operator~() const + { + return SIMD_Scalar(~R0, ~R1, ~R2, ~R3); + } + + static void transpose(SIMD_Scalar& B0, SIMD_Scalar& B1, + SIMD_Scalar& B2, SIMD_Scalar& B3) + { + SIMD_Scalar T0(B0.R0, B1.R0, B2.R0, B3.R0); + SIMD_Scalar T1(B0.R1, B1.R1, B2.R1, B3.R1); + SIMD_Scalar T2(B0.R2, B1.R2, B2.R2, B3.R2); + SIMD_Scalar T3(B0.R3, B1.R3, B2.R3, B3.R3); + + B0 = T0; + B1 = T1; + B2 = T2; + B3 = T3; + } + + private: + u32bit R0, R1, R2, R3; + }; + +} + +#endif diff --git a/src/utils/simd_32/simd_sse.h b/src/utils/simd_32/simd_sse.h new file mode 100644 index 000000000..d9135f1c7 --- /dev/null +++ b/src/utils/simd_32/simd_sse.h @@ -0,0 +1,141 @@ +/** +* Lightweight wrappers for SSE2 intrinsics for 32-bit operations +*/ + +#ifndef BOTAN_SIMD_SSE_H__ +#define BOTAN_SIMD_SSE_H__ + +#include +#include + +namespace Botan { + +class SIMD_SSE2 + { + public: + SIMD_SSE2(const u32bit B[4]) + { + reg = _mm_loadu_si128((const __m128i*)B); + } + + SIMD_SSE2(u32bit B0, u32bit B1, u32bit B2, u32bit B3) + { + reg = _mm_set_epi32(B0, B1, B2, B3); + } + + SIMD_SSE2(u32bit B) + { + reg = _mm_set1_epi32(B); + } + + static SIMD_SSE2 load_le(const void* in) + { + return _mm_loadu_si128((const __m128i*)in); + } + + static SIMD_SSE2 load_be(const void* in) + { + return SIMD_SSE2(_mm_loadu_si128((const __m128i*)in)).bswap(); + } + + void store_le(byte out[]) const + { + _mm_storeu_si128((__m128i*)out, reg); + } + + void store_be(byte out[]) const + { + bswap().store_le(out); + } + + void rotate_left(u32bit rot) + { + reg = _mm_or_si128(_mm_slli_epi32(reg, rot), + _mm_srli_epi32(reg, 32-rot)); + } + + void rotate_right(u32bit rot) + { + reg = _mm_or_si128(_mm_srli_epi32(reg, rot), + _mm_slli_epi32(reg, 32-rot)); + } + + void operator+=(const SIMD_SSE2& other) + { + reg = _mm_add_epi32(reg, other.reg); + } + + SIMD_SSE2 operator+(const SIMD_SSE2& other) const + { + return _mm_add_epi32(reg, other.reg); + } + + void operator^=(const SIMD_SSE2& other) + { + reg = _mm_xor_si128(reg, other.reg); + } + + SIMD_SSE2 operator^(const SIMD_SSE2& other) const + { + return _mm_xor_si128(reg, other.reg); + } + + void operator|=(const SIMD_SSE2& other) + { + reg = _mm_or_si128(reg, other.reg); + } + + void operator&=(const SIMD_SSE2& other) + { + reg = _mm_and_si128(reg, other.reg); + } + + SIMD_SSE2 operator<<(u32bit shift) const + { + return _mm_slli_epi32(reg, shift); + } + + SIMD_SSE2 operator>>(u32bit shift) const + { + return _mm_srli_epi32(reg, shift); + } + + SIMD_SSE2 operator~() const + { + static const __m128i all_ones = _mm_set1_epi32(0xFFFFFFFF); + return _mm_xor_si128(reg, all_ones); + } + + static void transpose(SIMD_SSE2& B0, SIMD_SSE2& B1, + SIMD_SSE2& B2, SIMD_SSE2& B3) + { + __m128i T0 = _mm_unpacklo_epi32(B0.reg, B1.reg); + __m128i T1 = _mm_unpacklo_epi32(B2.reg, B3.reg); + __m128i T2 = _mm_unpackhi_epi32(B0.reg, B1.reg); + __m128i T3 = _mm_unpackhi_epi32(B2.reg, B3.reg); + B0.reg = _mm_unpacklo_epi64(T0, T1); + B1.reg = _mm_unpackhi_epi64(T0, T1); + B2.reg = _mm_unpacklo_epi64(T2, T3); + B3.reg = _mm_unpackhi_epi64(T2, T3); + } + + private: + SIMD_SSE2(__m128i in) { reg = in; } + + SIMD_SSE2 bswap() const + { + __m128i T = reg; + + T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); + T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); + + return _mm_or_si128(_mm_srli_epi16(T, 8), + _mm_slli_epi16(T, 8)); + } + + __m128i reg; + }; + +} + +#endif -- cgit v1.2.3 From 3f96a3c691e3f823de932f696f373b0399a9acc7 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 26 Oct 2009 17:45:47 +0000 Subject: Indent fix --- src/hash/sha2/sha2_32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hash/sha2/sha2_32.cpp b/src/hash/sha2/sha2_32.cpp index 9fbcae44d..2a63eef25 100644 --- a/src/hash/sha2/sha2_32.cpp +++ b/src/hash/sha2/sha2_32.cpp @@ -62,7 +62,7 @@ void SHA_224_256_BASE::compress_n(const byte input[], u32bit blocks) for(u32bit j = 16; j != 64; ++j) W[j] = sigma(W[j- 2], 17, 19, 10) + W[j- 7] + - sigma(W[j-15], 7, 18, 3) + W[j-16]; + sigma(W[j-15], 7, 18, 3) + W[j-16]; F1(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98); F1(H, A, B, C, D, E, F, G, W[ 1], 0x71374491); -- cgit v1.2.3 From ce2f07c4fc8b6967bc1418b4ab8770393c64bc80 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 26 Oct 2009 17:59:57 +0000 Subject: Add subtraction operators to SIMD_32 classes, needed for XTEA decrypt --- src/utils/simd_32/simd_scalar.h | 16 ++++++++++++++++ src/utils/simd_32/simd_sse.h | 10 ++++++++++ 2 files changed, 26 insertions(+) (limited to 'src') diff --git a/src/utils/simd_32/simd_scalar.h b/src/utils/simd_32/simd_scalar.h index a6067f115..4b81c183b 100644 --- a/src/utils/simd_32/simd_scalar.h +++ b/src/utils/simd_32/simd_scalar.h @@ -96,6 +96,22 @@ class SIMD_Scalar R3 + other.R3); } + void operator-=(const SIMD_Scalar& other) + { + R0 -= other.R0; + R1 -= other.R1; + R2 -= other.R2; + R3 -= other.R3; + } + + SIMD_Scalar operator-(const SIMD_Scalar& other) const + { + return SIMD_Scalar(R0 - other.R0, + R1 - other.R1, + R2 - other.R2, + R3 - other.R3); + } + void operator^=(const SIMD_Scalar& other) { R0 ^= other.R0; diff --git a/src/utils/simd_32/simd_sse.h b/src/utils/simd_32/simd_sse.h index d9135f1c7..d2ef4b211 100644 --- a/src/utils/simd_32/simd_sse.h +++ b/src/utils/simd_32/simd_sse.h @@ -70,6 +70,16 @@ class SIMD_SSE2 return _mm_add_epi32(reg, other.reg); } + void operator-=(const SIMD_SSE2& other) + { + reg = _mm_sub_epi32(reg, other.reg); + } + + SIMD_SSE2 operator-(const SIMD_SSE2& other) const + { + return _mm_sub_epi32(reg, other.reg); + } + void operator^=(const SIMD_SSE2& other) { reg = _mm_xor_si128(reg, other.reg); -- cgit v1.2.3 From cf41f3879a81691df613d9cde4dc2e9f14465ac5 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 26 Oct 2009 18:00:04 +0000 Subject: Add XTEA decryption --- src/block/xtea_sse2/xtea_sse2.cpp | 58 +++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/block/xtea_sse2/xtea_sse2.cpp b/src/block/xtea_sse2/xtea_sse2.cpp index db7775103..5d9c7dd05 100644 --- a/src/block/xtea_sse2/xtea_sse2.cpp +++ b/src/block/xtea_sse2/xtea_sse2.cpp @@ -1,5 +1,5 @@ /* -* XTEA SSE2 +* XTEA in SIMD * (C) 2009 Jack Lloyd * * Distributed under the terms of the Botan license @@ -24,7 +24,10 @@ void xtea_encrypt_8(const byte in[64], byte out[64], const u32bit EK[64]) for(u32bit i = 0; i != 32; i += 2) { - SIMD_32 K0(EK[2*i]), K1(EK[2*i+1]), K2(EK[2*i+2]), K3(EK[2*i+3]); + 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; @@ -47,6 +50,43 @@ void xtea_encrypt_8(const byte in[64], byte out[64], const u32bit EK[64]) 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); + } + } /* @@ -54,8 +94,6 @@ void xtea_encrypt_8(const byte in[64], byte out[64], const u32bit EK[64]) */ void XTEA_SSE2::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - memset(out, 0, blocks * BLOCK_SIZE); - while(blocks >= 8) { xtea_encrypt_8(in, out, this->EK); @@ -72,15 +110,13 @@ void XTEA_SSE2::encrypt_n(const byte in[], byte out[], u32bit blocks) const */ void XTEA_SSE2::decrypt_n(const byte in[], byte out[], u32bit blocks) const { -#if 0 - while(blocks >= 4) + while(blocks >= 8) { - xtea_decrypt_4(in, out, this->EK); - in += 4 * BLOCK_SIZE; - out += 4 * BLOCK_SIZE; - blocks -= 4; + xtea_decrypt_8(in, out, this->EK); + in += 8 * BLOCK_SIZE; + out += 8 * BLOCK_SIZE; + blocks -= 8; } -#endif XTEA::decrypt_n(in, out, blocks); } -- cgit v1.2.3 From f5d4cf7509011669c25746e3b4c681b5ebfede79 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 28 Oct 2009 17:58:31 +0000 Subject: Define SSE rotate_right in terms of rotate left, and load_be in terms of load_le + bswap --- src/utils/simd_32/simd_sse.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/utils/simd_32/simd_sse.h b/src/utils/simd_32/simd_sse.h index d2ef4b211..d32ffdc2e 100644 --- a/src/utils/simd_32/simd_sse.h +++ b/src/utils/simd_32/simd_sse.h @@ -35,7 +35,7 @@ class SIMD_SSE2 static SIMD_SSE2 load_be(const void* in) { - return SIMD_SSE2(_mm_loadu_si128((const __m128i*)in)).bswap(); + return load_le(in).bswap(); } void store_le(byte out[]) const @@ -56,8 +56,7 @@ class SIMD_SSE2 void rotate_right(u32bit rot) { - reg = _mm_or_si128(_mm_srli_epi32(reg, rot), - _mm_slli_epi32(reg, 32-rot)); + rotate_left(32 - rot); } void operator+=(const SIMD_SSE2& other) -- cgit v1.2.3 From 185d85338562627aa4800436a3fe6efa11886351 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 28 Oct 2009 19:50:06 +0000 Subject: Add an AltiVec SIMD_32 implementation. Tested and works for Serpent and XTEA on a PowerPC 970 running Gentoo with GCC 4.3.4 Uses a GCC syntax for creating literal values instead of the Motorola syntax [{1,2,3,4} instead of (1,2,3,4)]. In tests so far, this is much, much slower than either the standard scalar code, or using the SIMD-in-scalar-registers code. It looks like for whatever reason GCC is refusing to inline the function: SIMD_Altivec(__vector unsigned int input) { reg = input; } and calls it with a branch hundreds of times in each function. I don't know if this is the entire reason it's slower, but it definitely can't be helping. The code handles unaligned loads OK but assumes stores are to an aligned address. This will fail drastically some day, and needs to be fixed to either use scalar stores, which (most?) PPCs will handle (if slowly), or batch the loads and stores so we can work across the loads. Considering the code so far loads 4 vectors of data in one go this would probably be a big win (and also for loads, since instead of doing 8 loads for 4 registers only 5 are needed). --- src/utils/simd_32/simd_altivec.h | 178 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/utils/simd_32/simd_altivec.h (limited to 'src') diff --git a/src/utils/simd_32/simd_altivec.h b/src/utils/simd_32/simd_altivec.h new file mode 100644 index 000000000..d6aaa699d --- /dev/null +++ b/src/utils/simd_32/simd_altivec.h @@ -0,0 +1,178 @@ +/** +* Altivec SIMD +*/ + +#ifndef BOTAN_SIMD_ALTIVEC_H__ +#define BOTAN_SIMD_ALTIVEC_H__ + +#include +#include +#undef vector + +namespace Botan { + +class SIMD_Altivec + { + public: + + SIMD_Altivec(const u32bit B[4]) + { + reg = (__vector unsigned int){B[0], B[1], B[2], B[3]}; + } + + SIMD_Altivec(u32bit B0, u32bit B1, u32bit B2, u32bit B3) + { + reg = (__vector unsigned int){B0, B1, B2, B3}; + } + + SIMD_Altivec(u32bit B) + { + reg = (__vector unsigned int){B, B, B, B}; + } + + static SIMD_Altivec load_le(const void* in) + { + const u32bit* in_32 = static_cast(in); + + __vector unsigned int R0 = vec_ld(0, in_32); + __vector unsigned int R1 = vec_ld(12, in_32); + + __vector unsigned char perm = vec_lvsl(0, in_32); + + perm = vec_xor(perm, vec_splat_u8(3)); + + R0 = vec_perm(R0, R1, perm); + + return SIMD_Altivec(R0); + } + + static SIMD_Altivec load_be(const void* in) + { + const u32bit* in_32 = static_cast(in); + + __vector unsigned int R0 = vec_ld(0, in_32); + __vector unsigned int R1 = vec_ld(12, in_32); + + __vector unsigned char perm = vec_lvsl(0, in_32); + + R0 = vec_perm(R0, R1, perm); + + return SIMD_Altivec(R0); + } + + void store_le(byte out[]) const + { + u32bit* out_32 = reinterpret_cast(out); + + __vector unsigned char perm = vec_lvsl(0, (int*)0); + + perm = vec_xor(perm, vec_splat_u8(3)); + + __vector unsigned int swapped = vec_perm(reg, reg, perm); + + vec_st(swapped, 0, out_32); + } + + void store_be(byte out[]) const + { + u32bit* out_32 = reinterpret_cast(out); + vec_st(reg, 0, out_32); + } + + void rotate_left(u32bit rot) + { + __vector unsigned int rot_vec = + (__vector unsigned int){rot, rot, rot, rot}; + + reg = vec_rl(reg, rot_vec); + } + + void rotate_right(u32bit rot) + { + rotate_left(32 - rot); + } + + void operator+=(const SIMD_Altivec& other) + { + reg = vec_add(reg, other.reg); + } + + SIMD_Altivec operator+(const SIMD_Altivec& other) const + { + return vec_add(reg, other.reg); + } + + void operator-=(const SIMD_Altivec& other) + { + reg = vec_sub(reg, other.reg); + } + + SIMD_Altivec operator-(const SIMD_Altivec& other) const + { + return vec_sub(reg, other.reg); + } + + void operator^=(const SIMD_Altivec& other) + { + reg = vec_xor(reg, other.reg); + } + + SIMD_Altivec operator^(const SIMD_Altivec& other) const + { + return vec_xor(reg, other.reg); + } + + void operator|=(const SIMD_Altivec& other) + { + reg = vec_or(reg, other.reg); + } + + void operator&=(const SIMD_Altivec& other) + { + reg = vec_and(reg, other.reg); + } + + SIMD_Altivec operator<<(u32bit shift) const + { + __vector unsigned int shift_vec = + (__vector unsigned int){shift, shift, shift, shift}; + + return vec_sl(reg, shift_vec); + } + + SIMD_Altivec operator>>(u32bit shift) const + { + __vector unsigned int shift_vec = + (__vector unsigned int){shift, shift, shift, shift}; + + return vec_sr(reg, shift_vec); + } + + SIMD_Altivec operator~() const + { + return vec_nor(reg, reg); + } + + static void transpose(SIMD_Altivec& B0, SIMD_Altivec& B1, + SIMD_Altivec& B2, SIMD_Altivec& B3) + { + __vector unsigned int T0 = vec_mergeh(B0.reg, B2.reg); + __vector unsigned int T1 = vec_mergel(B0.reg, B2.reg); + __vector unsigned int T2 = vec_mergeh(B1.reg, B3.reg); + __vector unsigned int T3 = vec_mergel(B1.reg, B3.reg); + + B0.reg = vec_mergeh(T0, T2); + B1.reg = vec_mergel(T0, T2); + B2.reg = vec_mergeh(T1, T3); + B3.reg = vec_mergel(T1, T3); + } + + private: + SIMD_Altivec(__vector unsigned int input) { reg = input; } + + __vector unsigned int reg; + }; + +} + +#endif -- cgit v1.2.3 From 16adc6a5424aad033a18bae872586a52e54d7d8e Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 28 Oct 2009 19:55:44 +0000 Subject: Add copyright + license on the new SIMD files --- src/utils/simd_32/simd_32.h | 3 +++ src/utils/simd_32/simd_altivec.h | 5 ++++- src/utils/simd_32/simd_scalar.h | 5 ++++- src/utils/simd_32/simd_sse.h | 3 +++ 4 files changed, 14 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/utils/simd_32/simd_32.h b/src/utils/simd_32/simd_32.h index d9fac0d3d..be426efd6 100644 --- a/src/utils/simd_32/simd_32.h +++ b/src/utils/simd_32/simd_32.h @@ -1,5 +1,8 @@ /** * Lightweight wrappers for SIMD operations +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license */ #ifndef BOTAN_SIMD_32_H__ diff --git a/src/utils/simd_32/simd_altivec.h b/src/utils/simd_32/simd_altivec.h index d6aaa699d..a925f6dbc 100644 --- a/src/utils/simd_32/simd_altivec.h +++ b/src/utils/simd_32/simd_altivec.h @@ -1,5 +1,8 @@ /** -* Altivec SIMD +* Lightweight wrappers around AltiVec for 32-bit operations +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license */ #ifndef BOTAN_SIMD_ALTIVEC_H__ diff --git a/src/utils/simd_32/simd_scalar.h b/src/utils/simd_32/simd_scalar.h index 4b81c183b..38f69c294 100644 --- a/src/utils/simd_32/simd_scalar.h +++ b/src/utils/simd_32/simd_scalar.h @@ -1,5 +1,8 @@ /** -* Scalar emulation of SIMD operations +* Scalar emulation of SIMD 32-bit operations +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license */ #ifndef BOTAN_SIMD_SCALAR_H__ diff --git a/src/utils/simd_32/simd_sse.h b/src/utils/simd_32/simd_sse.h index d32ffdc2e..267852554 100644 --- a/src/utils/simd_32/simd_sse.h +++ b/src/utils/simd_32/simd_sse.h @@ -1,5 +1,8 @@ /** * Lightweight wrappers for SSE2 intrinsics for 32-bit operations +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license */ #ifndef BOTAN_SIMD_SSE_H__ -- cgit v1.2.3 From 50b4840e6dfd893ae2feecc3bd6ec49071796354 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 01:38:50 +0000 Subject: Remove the 'realname' attribute on all modules and cc/cpu/os info files. Pretty much useless and unused, except for listing the module names in build.h and the short versions totally suffice for that. --- configure.py | 15 +++++---------- src/algo_factory/info.txt | 2 -- src/alloc/alloc_mmap/info.txt | 2 -- src/alloc/info.txt | 2 -- src/alloc/mem_pool/info.txt | 2 -- src/alloc/system_alloc/info.txt | 2 -- src/aont/info.txt | 2 -- src/asn1/info.txt | 2 -- src/benchmark/info.txt | 2 -- src/block/aes/info.txt | 2 -- src/block/blowfish/info.txt | 2 -- src/block/cast/info.txt | 2 -- src/block/des/info.txt | 2 -- src/block/gost_28147/info.txt | 2 -- src/block/idea/info.txt | 2 -- src/block/info.txt | 2 -- src/block/kasumi/info.txt | 2 -- src/block/lion/info.txt | 2 -- src/block/lubyrack/info.txt | 2 -- src/block/mars/info.txt | 2 -- src/block/misty1/info.txt | 2 -- src/block/noekeon/info.txt | 2 -- src/block/rc2/info.txt | 2 -- src/block/rc5/info.txt | 2 -- src/block/rc6/info.txt | 2 -- src/block/safer/info.txt | 2 -- src/block/seed/info.txt | 2 -- src/block/serpent/info.txt | 2 -- src/block/serpent_ia32/info.txt | 2 -- src/block/serpent_sse2/info.txt | 2 -- src/block/skipjack/info.txt | 2 -- src/block/square/info.txt | 2 -- src/block/tea/info.txt | 2 -- src/block/twofish/info.txt | 2 -- src/block/xtea/info.txt | 2 -- src/build-data/arch/alpha.txt | 2 -- src/build-data/arch/amd64.txt | 2 -- src/build-data/arch/arm.txt | 2 -- src/build-data/arch/hitachi-sh.txt | 2 -- src/build-data/arch/hppa.txt | 2 -- src/build-data/arch/ia32.txt | 2 -- src/build-data/arch/ia64.txt | 2 -- src/build-data/arch/m68k.txt | 2 -- src/build-data/arch/mips32.txt | 2 -- src/build-data/arch/mips64.txt | 2 -- src/build-data/arch/ppc.txt | 2 -- src/build-data/arch/ppc64.txt | 2 -- src/build-data/arch/s390.txt | 2 -- src/build-data/arch/s390x.txt | 2 -- src/build-data/arch/sparc32.txt | 3 --- src/build-data/arch/sparc64.txt | 2 -- src/build-data/cc/bcc.txt | 2 -- src/build-data/cc/clang.txt | 2 -- src/build-data/cc/compaq.txt | 2 -- src/build-data/cc/ekopath.txt | 2 -- src/build-data/cc/gcc.txt | 2 -- src/build-data/cc/hpcc.txt | 2 -- src/build-data/cc/icc.txt | 2 -- src/build-data/cc/kai.txt | 2 -- src/build-data/cc/mipspro.txt | 2 -- src/build-data/cc/msvc.txt | 2 -- src/build-data/cc/open64.txt | 2 -- src/build-data/cc/pgi.txt | 2 -- src/build-data/cc/sgipro64.txt | 2 -- src/build-data/cc/sunwspro.txt | 2 -- src/build-data/cc/xlc.txt | 2 -- src/build-data/os/aix.txt | 2 -- src/build-data/os/beos.txt | 2 -- src/build-data/os/cygwin.txt | 2 -- src/build-data/os/darwin.txt | 2 -- src/build-data/os/dragonfly.txt | 2 -- src/build-data/os/freebsd.txt | 2 -- src/build-data/os/hpux.txt | 2 -- src/build-data/os/irix.txt | 2 -- src/build-data/os/linux.txt | 2 -- src/build-data/os/mingw.txt | 1 - src/build-data/os/netbsd.txt | 2 -- src/build-data/os/openbsd.txt | 2 -- src/build-data/os/qnx.txt | 2 -- src/build-data/os/solaris.txt | 2 -- src/build-data/os/tru64.txt | 2 -- src/build-data/os/windows.txt | 2 -- src/cert/cvc/info.txt | 2 -- src/cert/x509/info.txt | 2 -- src/checksum/adler32/info.txt | 2 -- src/checksum/crc24/info.txt | 2 -- src/checksum/crc32/info.txt | 2 -- src/cms/info.txt | 2 -- src/codec/base64/info.txt | 2 -- src/codec/bzip2/info.txt | 1 - src/codec/hex/info.txt | 2 -- src/codec/openpgp/info.txt | 2 -- src/codec/pem/info.txt | 2 -- src/codec/zlib/info.txt | 1 - src/cryptobox/info.txt | 2 -- src/engine/amd64_eng/info.txt | 2 -- src/engine/def_engine/info.txt | 2 -- src/engine/gnump/info.txt | 2 -- src/engine/ia32_eng/info.txt | 2 -- src/engine/info.txt | 2 -- src/engine/openssl/info.txt | 2 -- src/engine/sse2_eng/info.txt | 2 -- src/entropy/beos_stats/info.txt | 2 -- src/entropy/cryptoapi_rng/info.txt | 2 -- src/entropy/dev_random/info.txt | 2 -- src/entropy/egd/info.txt | 2 -- src/entropy/info.txt | 2 -- src/entropy/proc_walk/info.txt | 2 -- src/entropy/unix_procs/info.txt | 2 -- src/entropy/win32_stats/info.txt | 2 -- src/filters/fd_unix/info.txt | 2 -- src/filters/info.txt | 2 -- src/hash/bmw/info.txt | 2 -- src/hash/fork256/info.txt | 2 -- src/hash/gost_3411/info.txt | 2 -- src/hash/has160/info.txt | 2 -- src/hash/info.txt | 2 -- src/hash/md2/info.txt | 2 -- src/hash/md4/info.txt | 2 -- src/hash/md4_ia32/info.txt | 2 -- src/hash/md5/info.txt | 2 -- src/hash/md5_ia32/info.txt | 2 -- src/hash/mdx_hash/info.txt | 2 -- src/hash/par_hash/info.txt | 2 -- src/hash/rmd128/info.txt | 2 -- src/hash/rmd160/info.txt | 2 -- src/hash/sha1/info.txt | 2 -- src/hash/sha1_amd64/info.txt | 2 -- src/hash/sha1_ia32/info.txt | 2 -- src/hash/sha1_sse2/info.txt | 2 -- src/hash/sha2/info.txt | 2 -- src/hash/skein/info.txt | 2 -- src/hash/tiger/info.txt | 2 -- src/hash/whirlpool/info.txt | 2 -- src/kdf/info.txt | 2 -- src/kdf/kdf1/info.txt | 2 -- src/kdf/kdf2/info.txt | 2 -- src/kdf/mgf1/info.txt | 2 -- src/kdf/ssl_prf/info.txt | 2 -- src/kdf/tls_prf/info.txt | 2 -- src/kdf/x942_prf/info.txt | 2 -- src/libstate/info.txt | 2 -- src/libstate/oid_lookup/info.txt | 2 -- src/mac/cbc_mac/info.txt | 2 -- src/mac/cmac/info.txt | 2 -- src/mac/hmac/info.txt | 2 -- src/mac/info.txt | 2 -- src/mac/ssl3mac/info.txt | 2 -- src/mac/x919_mac/info.txt | 2 -- src/math/bigint/info.txt | 2 -- src/math/bigint/monty_amd64/info.txt | 2 -- src/math/bigint/monty_generic/info.txt | 2 -- src/math/bigint/mp_amd64/info.txt | 2 -- src/math/bigint/mp_asm64/info.txt | 2 -- src/math/bigint/mp_generic/info.txt | 2 -- src/math/bigint/mp_ia32/info.txt | 2 -- src/math/bigint/mp_ia32_msvc/info.txt | 2 -- src/math/bigint/mulop_amd64/info.txt | 2 -- src/math/bigint/mulop_generic/info.txt | 2 -- src/math/bigint/mulop_ia32/info.txt | 2 -- src/math/gfpmath/info.txt | 2 -- src/math/numbertheory/info.txt | 2 -- src/modes/cbc/info.txt | 2 -- src/modes/cfb/info.txt | 3 --- src/modes/cts/info.txt | 2 -- src/modes/eax/info.txt | 2 -- src/modes/ecb/info.txt | 2 -- src/modes/info.txt | 2 -- src/modes/mode_pad/info.txt | 2 -- src/modes/xts/info.txt | 2 -- src/mutex/info.txt | 2 -- src/mutex/noop_mutex/info.txt | 2 -- src/mutex/pthreads/info.txt | 2 -- src/mutex/qt_mutex/info.txt | 2 -- src/mutex/win32_crit_section/info.txt | 2 -- src/pbe/info.txt | 2 -- src/pbe/pbes1/info.txt | 2 -- src/pbe/pbes2/info.txt | 2 -- src/pk_pad/eme1/info.txt | 2 -- src/pk_pad/eme_pkcs/info.txt | 2 -- src/pk_pad/emsa1/info.txt | 2 -- src/pk_pad/emsa1_bsi/info.txt | 2 -- src/pk_pad/emsa2/info.txt | 2 -- src/pk_pad/emsa3/info.txt | 2 -- src/pk_pad/emsa4/info.txt | 2 -- src/pk_pad/emsa_raw/info.txt | 2 -- src/pk_pad/hash_id/info.txt | 2 -- src/pk_pad/info.txt | 2 -- src/pubkey/dh/info.txt | 2 -- src/pubkey/dl_algo/info.txt | 2 -- src/pubkey/dl_group/info.txt | 2 -- src/pubkey/dlies/info.txt | 2 -- src/pubkey/dsa/info.txt | 2 -- src/pubkey/ec_dompar/info.txt | 2 -- src/pubkey/ecc_key/info.txt | 2 -- src/pubkey/ecdsa/info.txt | 2 -- src/pubkey/eckaeg/info.txt | 2 -- src/pubkey/elgamal/info.txt | 2 -- src/pubkey/if_algo/info.txt | 2 -- src/pubkey/info.txt | 2 -- src/pubkey/keypair/info.txt | 2 -- src/pubkey/nr/info.txt | 2 -- src/pubkey/pk_codecs/info.txt | 2 -- src/pubkey/rsa/info.txt | 2 -- src/pubkey/rw/info.txt | 2 -- src/rng/auto_rng/info.txt | 2 -- src/rng/hmac_rng/info.txt | 2 -- src/rng/info.txt | 2 -- src/rng/randpool/info.txt | 2 -- src/rng/x931_rng/info.txt | 2 -- src/s2k/info.txt | 2 -- src/s2k/pbkdf1/info.txt | 2 -- src/s2k/pbkdf2/info.txt | 2 -- src/s2k/pgps2k/info.txt | 2 -- src/selftest/info.txt | 2 -- src/stream/arc4/info.txt | 2 -- src/stream/ctr/info.txt | 3 --- src/stream/info.txt | 2 -- src/stream/ofb/info.txt | 2 -- src/stream/salsa20/info.txt | 2 -- src/stream/turing/info.txt | 2 -- src/stream/wid_wake/info.txt | 2 -- src/sym_algo/info.txt | 2 -- src/timer/cpu_counter/info.txt | 2 -- src/timer/gettimeofday/info.txt | 3 --- src/timer/info.txt | 2 -- src/timer/posix_rt/info.txt | 3 --- src/timer/win32_query_perf_ctr/info.txt | 3 --- src/tss/info.txt | 2 -- src/utils/asm_amd64/info.txt | 2 -- src/utils/asm_ia32/info.txt | 2 -- src/utils/buf_comp/info.txt | 2 -- src/utils/datastor/info.txt | 2 -- src/utils/info.txt | 2 -- 234 files changed, 5 insertions(+), 479 deletions(-) (limited to 'src') diff --git a/configure.py b/configure.py index 88eb45963..be5cf7ad2 100755 --- a/configure.py +++ b/configure.py @@ -357,8 +357,7 @@ class ModuleInfo(object): lex_me_harder(infofile, self, ['add', 'requires', 'os', 'arch', 'cc', 'libs'], - { 'realname': '', - 'load_on': 'auto', + { 'load_on': 'auto', 'define': None, 'modset': None, 'uses_tr1': 'false', @@ -425,8 +424,7 @@ class ArchInfo(object): def __init__(self, infofile): lex_me_harder(infofile, self, ['aliases', 'submodels', 'submodel_aliases'], - { 'realname': '', - 'default_submodel': None, + { 'default_submodel': None, 'endian': None, 'unaligned': 'no' }) @@ -471,8 +469,7 @@ class CompilerInfo(object): def __init__(self, infofile): lex_me_harder(infofile, self, ['so_link_flags', 'mach_opt', 'mach_abi_linking'], - { 'realname': '', - 'binary_name': None, + { 'binary_name': None, 'macro_name': None, 'compile_option': '-c ', 'output_to_option': '-o ', @@ -572,8 +569,7 @@ class OsInfo(object): def __init__(self, infofile): lex_me_harder(infofile, self, ['aliases', 'target_features', 'supports_shared'], - { 'realname': '', - 'os_type': None, + { 'os_type': None, 'obj_suffix': 'o', 'so_suffix': 'so', 'static_suffix': 'a', @@ -833,8 +829,7 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): 'doc_files': makefile_list(build_config.doc_files()), - 'mod_list': '\n'.join(['%s (%s)' % (m.basename, m.realname) - for m in sorted(modules)]), + 'mod_list': '\n'.join(sorted([m.basename for m in modules])), 'python_version': '.'.join(map(str, sys.version_info[0:2])) } diff --git a/src/algo_factory/info.txt b/src/algo_factory/info.txt index dfc42230a..4b25c7fc5 100644 --- a/src/algo_factory/info.txt +++ b/src/algo_factory/info.txt @@ -1,5 +1,3 @@ -realname "Algorithm Factory" - load_on auto define ALGORITHM_FACTORY diff --git a/src/alloc/alloc_mmap/info.txt b/src/alloc/alloc_mmap/info.txt index 65d9b2977..e6bded3fb 100644 --- a/src/alloc/alloc_mmap/info.txt +++ b/src/alloc/alloc_mmap/info.txt @@ -1,5 +1,3 @@ -realname "Disk Based Allocation System" - define ALLOC_MMAP modset unix diff --git a/src/alloc/info.txt b/src/alloc/info.txt index fa50aa09f..99dbe3a4d 100644 --- a/src/alloc/info.txt +++ b/src/alloc/info.txt @@ -1,5 +1,3 @@ -realname "Allocator" - load_on auto diff --git a/src/alloc/mem_pool/info.txt b/src/alloc/mem_pool/info.txt index 0a762ccc4..73a548292 100644 --- a/src/alloc/mem_pool/info.txt +++ b/src/alloc/mem_pool/info.txt @@ -1,5 +1,3 @@ -realname "Memory Pool Allocator" - load_on auto diff --git a/src/alloc/system_alloc/info.txt b/src/alloc/system_alloc/info.txt index 5fade38cf..8b9a2f067 100644 --- a/src/alloc/system_alloc/info.txt +++ b/src/alloc/system_alloc/info.txt @@ -1,5 +1,3 @@ -realname "Default (Malloc) Allocators" - load_on auto diff --git a/src/aont/info.txt b/src/aont/info.txt index a0387f358..533b70eb5 100644 --- a/src/aont/info.txt +++ b/src/aont/info.txt @@ -1,5 +1,3 @@ -realname "All or Nothing Transforms" - define PACKAGE_TRANSFORM load_on auto diff --git a/src/asn1/info.txt b/src/asn1/info.txt index 7b8110c10..d836b4c0b 100644 --- a/src/asn1/info.txt +++ b/src/asn1/info.txt @@ -1,5 +1,3 @@ -realname "ASN.1/BER/DER module" - define ASN1 load_on auto diff --git a/src/benchmark/info.txt b/src/benchmark/info.txt index 0fbcdb2de..f148ae5ce 100644 --- a/src/benchmark/info.txt +++ b/src/benchmark/info.txt @@ -1,5 +1,3 @@ -realname "Benchmarking" - define RUNTIME_BENCHMARKING load_on auto diff --git a/src/block/aes/info.txt b/src/block/aes/info.txt index 0e11603bb..480973100 100644 --- a/src/block/aes/info.txt +++ b/src/block/aes/info.txt @@ -1,3 +1 @@ -realname "AES" - define AES diff --git a/src/block/blowfish/info.txt b/src/block/blowfish/info.txt index c63560989..c935fb3ab 100644 --- a/src/block/blowfish/info.txt +++ b/src/block/blowfish/info.txt @@ -1,3 +1 @@ -realname "Blowfish" - define BLOWFISH diff --git a/src/block/cast/info.txt b/src/block/cast/info.txt index b9259042d..faba491c2 100644 --- a/src/block/cast/info.txt +++ b/src/block/cast/info.txt @@ -1,3 +1 @@ -realname "CAST" - define CAST diff --git a/src/block/des/info.txt b/src/block/des/info.txt index 6eec591a0..8e4f4e82d 100644 --- a/src/block/des/info.txt +++ b/src/block/des/info.txt @@ -1,3 +1 @@ -realname "DES" - define DES diff --git a/src/block/gost_28147/info.txt b/src/block/gost_28147/info.txt index 9b24d1e22..530f147e5 100644 --- a/src/block/gost_28147/info.txt +++ b/src/block/gost_28147/info.txt @@ -1,3 +1 @@ -realname "GOST 28147-89" - define GOST_28147_89 diff --git a/src/block/idea/info.txt b/src/block/idea/info.txt index f11b3d224..a868d7cc7 100644 --- a/src/block/idea/info.txt +++ b/src/block/idea/info.txt @@ -1,3 +1 @@ -realname "IDEA" - define IDEA diff --git a/src/block/info.txt b/src/block/info.txt index f5840bf79..b4302a6d8 100644 --- a/src/block/info.txt +++ b/src/block/info.txt @@ -1,5 +1,3 @@ -realname "Block Ciphers" - define BLOCK_CIPHER diff --git a/src/block/kasumi/info.txt b/src/block/kasumi/info.txt index e310488b3..cb8340fad 100644 --- a/src/block/kasumi/info.txt +++ b/src/block/kasumi/info.txt @@ -1,3 +1 @@ -realname "Kasumi" - define KASUMI diff --git a/src/block/lion/info.txt b/src/block/lion/info.txt index 64f2989b1..9562be1d0 100644 --- a/src/block/lion/info.txt +++ b/src/block/lion/info.txt @@ -1,5 +1,3 @@ -realname "Lion" - define LION diff --git a/src/block/lubyrack/info.txt b/src/block/lubyrack/info.txt index d915781d8..41c395097 100644 --- a/src/block/lubyrack/info.txt +++ b/src/block/lubyrack/info.txt @@ -1,5 +1,3 @@ -realname "Luby-Rackoff" - define LUBY_RACKOFF diff --git a/src/block/mars/info.txt b/src/block/mars/info.txt index ec958eaf5..afdcebe67 100644 --- a/src/block/mars/info.txt +++ b/src/block/mars/info.txt @@ -1,3 +1 @@ -realname "MARS" - define MARS diff --git a/src/block/misty1/info.txt b/src/block/misty1/info.txt index 38087c83d..290b8b1d7 100644 --- a/src/block/misty1/info.txt +++ b/src/block/misty1/info.txt @@ -1,3 +1 @@ -realname "MISTY-1" - define MISTY1 diff --git a/src/block/noekeon/info.txt b/src/block/noekeon/info.txt index 6e940bb62..31f7e7de3 100644 --- a/src/block/noekeon/info.txt +++ b/src/block/noekeon/info.txt @@ -1,3 +1 @@ -realname "Noekeon" - define NOEKEON diff --git a/src/block/rc2/info.txt b/src/block/rc2/info.txt index 7ec018422..7eee38d6b 100644 --- a/src/block/rc2/info.txt +++ b/src/block/rc2/info.txt @@ -1,3 +1 @@ -realname "RC2" - define RC2 diff --git a/src/block/rc5/info.txt b/src/block/rc5/info.txt index 2032b406f..3da32710d 100644 --- a/src/block/rc5/info.txt +++ b/src/block/rc5/info.txt @@ -1,3 +1 @@ -realname "RC5" - define RC5 diff --git a/src/block/rc6/info.txt b/src/block/rc6/info.txt index 2897bc1f3..fc7d2acb4 100644 --- a/src/block/rc6/info.txt +++ b/src/block/rc6/info.txt @@ -1,3 +1 @@ -realname "RC6" - define RC6 diff --git a/src/block/safer/info.txt b/src/block/safer/info.txt index 7c8067472..0ca49602d 100644 --- a/src/block/safer/info.txt +++ b/src/block/safer/info.txt @@ -1,3 +1 @@ -realname "SAFER" - define SAFER diff --git a/src/block/seed/info.txt b/src/block/seed/info.txt index c66e0c2cd..96f4b75f2 100644 --- a/src/block/seed/info.txt +++ b/src/block/seed/info.txt @@ -1,3 +1 @@ -realname "SEED" - define SEED diff --git a/src/block/serpent/info.txt b/src/block/serpent/info.txt index 4031a3f5f..5fcc14f74 100644 --- a/src/block/serpent/info.txt +++ b/src/block/serpent/info.txt @@ -1,3 +1 @@ -realname "Serpent" - define SERPENT diff --git a/src/block/serpent_ia32/info.txt b/src/block/serpent_ia32/info.txt index 48d589724..fa6d9b9d9 100644 --- a/src/block/serpent_ia32/info.txt +++ b/src/block/serpent_ia32/info.txt @@ -1,5 +1,3 @@ -realname "Serpent (IA-32)" - define SERPENT_IA32 load_on asm_ok diff --git a/src/block/serpent_sse2/info.txt b/src/block/serpent_sse2/info.txt index da7eef6bc..a4ec561a8 100644 --- a/src/block/serpent_sse2/info.txt +++ b/src/block/serpent_sse2/info.txt @@ -1,5 +1,3 @@ -realname "Serpent (SSE2)" - define SERPENT_SSE2 diff --git a/src/block/skipjack/info.txt b/src/block/skipjack/info.txt index 9cdddfe6b..7dfffda4e 100644 --- a/src/block/skipjack/info.txt +++ b/src/block/skipjack/info.txt @@ -1,3 +1 @@ -realname "Skipjack" - define SKIPJACK diff --git a/src/block/square/info.txt b/src/block/square/info.txt index 7c517be71..d33379815 100644 --- a/src/block/square/info.txt +++ b/src/block/square/info.txt @@ -1,3 +1 @@ -realname "Square" - define SQUARE diff --git a/src/block/tea/info.txt b/src/block/tea/info.txt index 85a19ee4c..67ed5a656 100644 --- a/src/block/tea/info.txt +++ b/src/block/tea/info.txt @@ -1,3 +1 @@ -realname "TEA" - define TEA diff --git a/src/block/twofish/info.txt b/src/block/twofish/info.txt index 319da6e6e..88eae9ce7 100644 --- a/src/block/twofish/info.txt +++ b/src/block/twofish/info.txt @@ -1,3 +1 @@ -realname "Twofish" - define TWOFISH diff --git a/src/block/xtea/info.txt b/src/block/xtea/info.txt index 1887e6673..d9d37607c 100644 --- a/src/block/xtea/info.txt +++ b/src/block/xtea/info.txt @@ -1,3 +1 @@ -realname "XTEA" - define XTEA diff --git a/src/build-data/arch/alpha.txt b/src/build-data/arch/alpha.txt index 60b264396..b1d939ed1 100644 --- a/src/build-data/arch/alpha.txt +++ b/src/build-data/arch/alpha.txt @@ -1,5 +1,3 @@ -realname "DEC Alpha" - default_submodel alpha-ev4 endian little diff --git a/src/build-data/arch/amd64.txt b/src/build-data/arch/amd64.txt index 216588e7b..96da0e3a9 100644 --- a/src/build-data/arch/amd64.txt +++ b/src/build-data/arch/amd64.txt @@ -1,5 +1,3 @@ -realname "x86-64" - default_submodel opteron endian little diff --git a/src/build-data/arch/arm.txt b/src/build-data/arch/arm.txt index c6be4ad46..5f05d4cad 100644 --- a/src/build-data/arch/arm.txt +++ b/src/build-data/arch/arm.txt @@ -1,5 +1,3 @@ -realname "ARM" - default_submodel arm2 diff --git a/src/build-data/arch/hitachi-sh.txt b/src/build-data/arch/hitachi-sh.txt index 8e9f7eee3..85a741f59 100644 --- a/src/build-data/arch/hitachi-sh.txt +++ b/src/build-data/arch/hitachi-sh.txt @@ -1,5 +1,3 @@ -realname "Hitachi SH" - default_submodel hitachi-sh1 diff --git a/src/build-data/arch/hppa.txt b/src/build-data/arch/hppa.txt index 4cdd40889..67bca263d 100644 --- a/src/build-data/arch/hppa.txt +++ b/src/build-data/arch/hppa.txt @@ -1,5 +1,3 @@ -realname "HP-PA" - default_submodel hppa1.0 diff --git a/src/build-data/arch/ia32.txt b/src/build-data/arch/ia32.txt index aafcf9a77..0fe665e68 100644 --- a/src/build-data/arch/ia32.txt +++ b/src/build-data/arch/ia32.txt @@ -1,5 +1,3 @@ -realname "IA-32" - default_submodel i386 endian little diff --git a/src/build-data/arch/ia64.txt b/src/build-data/arch/ia64.txt index 7ca84c007..65309f0ff 100644 --- a/src/build-data/arch/ia64.txt +++ b/src/build-data/arch/ia64.txt @@ -1,5 +1,3 @@ -realname "IA-64" - # This is safe: only affects tuning, not ISA default_submodel itanium2 diff --git a/src/build-data/arch/m68k.txt b/src/build-data/arch/m68k.txt index 759a3dac1..3a8b5e8b3 100644 --- a/src/build-data/arch/m68k.txt +++ b/src/build-data/arch/m68k.txt @@ -1,5 +1,3 @@ -realname "Motorola 680x0" - default_submodel 68020 endian big diff --git a/src/build-data/arch/mips32.txt b/src/build-data/arch/mips32.txt index 9846c8fb2..ec9d4b5bf 100644 --- a/src/build-data/arch/mips32.txt +++ b/src/build-data/arch/mips32.txt @@ -1,5 +1,3 @@ -realname "MIPS" - default_submodel r3000 diff --git a/src/build-data/arch/mips64.txt b/src/build-data/arch/mips64.txt index dbb49d028..666ba7e18 100644 --- a/src/build-data/arch/mips64.txt +++ b/src/build-data/arch/mips64.txt @@ -1,5 +1,3 @@ -realname "MIPS64" - default_submodel r4400 diff --git a/src/build-data/arch/ppc.txt b/src/build-data/arch/ppc.txt index e2dfa6ea2..254643fdd 100644 --- a/src/build-data/arch/ppc.txt +++ b/src/build-data/arch/ppc.txt @@ -1,5 +1,3 @@ -realname "PowerPC" - endian big unaligned ok diff --git a/src/build-data/arch/ppc64.txt b/src/build-data/arch/ppc64.txt index 7c8944faf..f044ba98d 100644 --- a/src/build-data/arch/ppc64.txt +++ b/src/build-data/arch/ppc64.txt @@ -1,5 +1,3 @@ -realname "PowerPC 64" - endian big default_submodel power4 diff --git a/src/build-data/arch/s390.txt b/src/build-data/arch/s390.txt index 312b262c4..8024a4315 100644 --- a/src/build-data/arch/s390.txt +++ b/src/build-data/arch/s390.txt @@ -1,5 +1,3 @@ -realname "S/390 31-bit" - default_submodel s390 endian big diff --git a/src/build-data/arch/s390x.txt b/src/build-data/arch/s390x.txt index 9fe6bd615..00daab8b4 100644 --- a/src/build-data/arch/s390x.txt +++ b/src/build-data/arch/s390x.txt @@ -1,5 +1,3 @@ -realname "S/390 64-bit" - default_submodel s390x endian big diff --git a/src/build-data/arch/sparc32.txt b/src/build-data/arch/sparc32.txt index 6b752df87..57b19c519 100644 --- a/src/build-data/arch/sparc32.txt +++ b/src/build-data/arch/sparc32.txt @@ -1,5 +1,3 @@ -realname "SPARC" - # V7 doesn't have integer multiply, so it will be bitterly slow for some things # (especially BigInt). Also, it's fairly rare nowadays, so we default to V8. default_submodel sparc32-v8 @@ -31,4 +29,3 @@ sparc-v7 -> sparc32-v7 sparc-v8 -> sparc32-v8 sparc-v9 -> sparc32-v9 - diff --git a/src/build-data/arch/sparc64.txt b/src/build-data/arch/sparc64.txt index c0575efc4..e308055fa 100644 --- a/src/build-data/arch/sparc64.txt +++ b/src/build-data/arch/sparc64.txt @@ -1,5 +1,3 @@ -realname "SPARC64" - default_submodel sparc64-ultra diff --git a/src/build-data/cc/bcc.txt b/src/build-data/cc/bcc.txt index fe88c270e..4315c379f 100644 --- a/src/build-data/cc/bcc.txt +++ b/src/build-data/cc/bcc.txt @@ -1,5 +1,3 @@ -realname "Borland C++" - macro_name "BORLAND" binary_name "bcc32" diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt index 480794faf..18f3580ce 100644 --- a/src/build-data/cc/clang.txt +++ b/src/build-data/cc/clang.txt @@ -1,5 +1,3 @@ -realname "Clang/LLVM" - # Largely copied from the gcc config macro_name "CLANG" diff --git a/src/build-data/cc/compaq.txt b/src/build-data/cc/compaq.txt index 94075e888..9ad6514ab 100644 --- a/src/build-data/cc/compaq.txt +++ b/src/build-data/cc/compaq.txt @@ -1,5 +1,3 @@ -realname "Compaq C++" - macro_name "COMPAQ" binary_name "cxx" diff --git a/src/build-data/cc/ekopath.txt b/src/build-data/cc/ekopath.txt index 38516e2f3..ecd813629 100644 --- a/src/build-data/cc/ekopath.txt +++ b/src/build-data/cc/ekopath.txt @@ -1,5 +1,3 @@ -realname "PathScale EKOPath C++" - macro_name "PATHSCALE" binary_name "pathCC" diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt index 9adef8cfb..370bb84d7 100644 --- a/src/build-data/cc/gcc.txt +++ b/src/build-data/cc/gcc.txt @@ -1,5 +1,3 @@ -realname "GNU C++" - macro_name "GCC" binary_name "g++" diff --git a/src/build-data/cc/hpcc.txt b/src/build-data/cc/hpcc.txt index 9c0d4a784..5bde87de9 100644 --- a/src/build-data/cc/hpcc.txt +++ b/src/build-data/cc/hpcc.txt @@ -1,5 +1,3 @@ -realname "HP-UX C++" - macro_name "HP_ACC" binary_name "aCC" diff --git a/src/build-data/cc/icc.txt b/src/build-data/cc/icc.txt index 9595714f6..628a59e2d 100644 --- a/src/build-data/cc/icc.txt +++ b/src/build-data/cc/icc.txt @@ -1,5 +1,3 @@ -realname "Intel C++" - macro_name "INTEL" binary_name "icpc" diff --git a/src/build-data/cc/kai.txt b/src/build-data/cc/kai.txt index 52ddba4ab..d0ff1c28a 100644 --- a/src/build-data/cc/kai.txt +++ b/src/build-data/cc/kai.txt @@ -1,5 +1,3 @@ -realname "KAI C++" - macro_name "KAI" binary_name "KCC" diff --git a/src/build-data/cc/mipspro.txt b/src/build-data/cc/mipspro.txt index a4cfbd1ee..c518f4c26 100644 --- a/src/build-data/cc/mipspro.txt +++ b/src/build-data/cc/mipspro.txt @@ -1,5 +1,3 @@ -realname "SGI MIPSPro C++" - macro_name "MIPSPRO" binary_name "CC" diff --git a/src/build-data/cc/msvc.txt b/src/build-data/cc/msvc.txt index c19d93e2b..603ea449b 100644 --- a/src/build-data/cc/msvc.txt +++ b/src/build-data/cc/msvc.txt @@ -1,5 +1,3 @@ -realname "Visual C++" - macro_name "MSVC" binary_name "cl.exe" diff --git a/src/build-data/cc/open64.txt b/src/build-data/cc/open64.txt index 0157440cf..e794c755e 100644 --- a/src/build-data/cc/open64.txt +++ b/src/build-data/cc/open64.txt @@ -1,5 +1,3 @@ -realname "Open64" - macro_name "OPEN64" binary_name "openCC" diff --git a/src/build-data/cc/pgi.txt b/src/build-data/cc/pgi.txt index c4fdb9e70..a6d2416ab 100644 --- a/src/build-data/cc/pgi.txt +++ b/src/build-data/cc/pgi.txt @@ -1,5 +1,3 @@ -realname "Portland Group C++" - macro_name "PORTLAND_GROUP" binary_name "pgCC" diff --git a/src/build-data/cc/sgipro64.txt b/src/build-data/cc/sgipro64.txt index be91ac69a..073f2fec0 100644 --- a/src/build-data/cc/sgipro64.txt +++ b/src/build-data/cc/sgipro64.txt @@ -1,5 +1,3 @@ -realname "SGI Pro64" - macro_name "SGI_PRO64" binary_name "sgiCC" diff --git a/src/build-data/cc/sunwspro.txt b/src/build-data/cc/sunwspro.txt index 9756f8538..7065d4129 100644 --- a/src/build-data/cc/sunwspro.txt +++ b/src/build-data/cc/sunwspro.txt @@ -1,5 +1,3 @@ -realname "Sun Workshop Pro C++" - macro_name "SUN_WORKSHOP" binary_name "CC" diff --git a/src/build-data/cc/xlc.txt b/src/build-data/cc/xlc.txt index 6d06b4c43..521624395 100644 --- a/src/build-data/cc/xlc.txt +++ b/src/build-data/cc/xlc.txt @@ -1,5 +1,3 @@ -realname "IBM XL C/C++" - macro_name "IBM_XLC" binary_name "xlC" diff --git a/src/build-data/os/aix.txt b/src/build-data/os/aix.txt index cec818580..0063948c7 100644 --- a/src/build-data/os/aix.txt +++ b/src/build-data/os/aix.txt @@ -1,5 +1,3 @@ -realname "AIX" - os_type unix diff --git a/src/build-data/os/beos.txt b/src/build-data/os/beos.txt index 2b12792bb..b843bd525 100644 --- a/src/build-data/os/beos.txt +++ b/src/build-data/os/beos.txt @@ -1,5 +1,3 @@ -realname "BeOS" - os_type beos install_root /boot/beos diff --git a/src/build-data/os/cygwin.txt b/src/build-data/os/cygwin.txt index c2aadea98..7290648c2 100644 --- a/src/build-data/os/cygwin.txt +++ b/src/build-data/os/cygwin.txt @@ -1,5 +1,3 @@ -realname "Cygwin" - os_type unix install_root c:\Botan diff --git a/src/build-data/os/darwin.txt b/src/build-data/os/darwin.txt index 298621216..fb18ee191 100644 --- a/src/build-data/os/darwin.txt +++ b/src/build-data/os/darwin.txt @@ -1,5 +1,3 @@ -realname "Darwin / MacOS X" - os_type unix so_suffix dylib diff --git a/src/build-data/os/dragonfly.txt b/src/build-data/os/dragonfly.txt index 7e3663435..6823de5b6 100644 --- a/src/build-data/os/dragonfly.txt +++ b/src/build-data/os/dragonfly.txt @@ -1,5 +1,3 @@ -realname "DragonFly" - os_type unix diff --git a/src/build-data/os/freebsd.txt b/src/build-data/os/freebsd.txt index ea96b0c88..6823de5b6 100644 --- a/src/build-data/os/freebsd.txt +++ b/src/build-data/os/freebsd.txt @@ -1,5 +1,3 @@ -realname "FreeBSD" - os_type unix diff --git a/src/build-data/os/hpux.txt b/src/build-data/os/hpux.txt index 6e17d3b73..9ff0f7f62 100644 --- a/src/build-data/os/hpux.txt +++ b/src/build-data/os/hpux.txt @@ -1,5 +1,3 @@ -realname "HP-UX" - os_type unix so_suffix sl diff --git a/src/build-data/os/irix.txt b/src/build-data/os/irix.txt index fd8b43287..0063948c7 100644 --- a/src/build-data/os/irix.txt +++ b/src/build-data/os/irix.txt @@ -1,5 +1,3 @@ -realname "IRIX" - os_type unix diff --git a/src/build-data/os/linux.txt b/src/build-data/os/linux.txt index 53528511a..3a92f9dd7 100644 --- a/src/build-data/os/linux.txt +++ b/src/build-data/os/linux.txt @@ -1,5 +1,3 @@ -realname "Linux" - os_type unix diff --git a/src/build-data/os/mingw.txt b/src/build-data/os/mingw.txt index eb25017fc..2b7a16cf7 100644 --- a/src/build-data/os/mingw.txt +++ b/src/build-data/os/mingw.txt @@ -1,4 +1,3 @@ -realname "MS Windows (MinGW)" os_type windows obj_suffix o diff --git a/src/build-data/os/netbsd.txt b/src/build-data/os/netbsd.txt index 435d8f5e8..0063948c7 100644 --- a/src/build-data/os/netbsd.txt +++ b/src/build-data/os/netbsd.txt @@ -1,5 +1,3 @@ -realname "NetBSD" - os_type unix diff --git a/src/build-data/os/openbsd.txt b/src/build-data/os/openbsd.txt index cb44bd115..0063948c7 100644 --- a/src/build-data/os/openbsd.txt +++ b/src/build-data/os/openbsd.txt @@ -1,5 +1,3 @@ -realname "OpenBSD" - os_type unix diff --git a/src/build-data/os/qnx.txt b/src/build-data/os/qnx.txt index 28bc8dea9..0063948c7 100644 --- a/src/build-data/os/qnx.txt +++ b/src/build-data/os/qnx.txt @@ -1,5 +1,3 @@ -realname "QNX" - os_type unix diff --git a/src/build-data/os/solaris.txt b/src/build-data/os/solaris.txt index 8610b4898..47b06dcc4 100644 --- a/src/build-data/os/solaris.txt +++ b/src/build-data/os/solaris.txt @@ -1,5 +1,3 @@ -realname "Solaris" - os_type unix diff --git a/src/build-data/os/tru64.txt b/src/build-data/os/tru64.txt index e320c1df4..8fc301d79 100644 --- a/src/build-data/os/tru64.txt +++ b/src/build-data/os/tru64.txt @@ -1,5 +1,3 @@ -realname "Tru64" - os_type unix diff --git a/src/build-data/os/windows.txt b/src/build-data/os/windows.txt index a04d609b8..e2e8bb665 100644 --- a/src/build-data/os/windows.txt +++ b/src/build-data/os/windows.txt @@ -1,5 +1,3 @@ -realname "MS Windows" - os_type windows obj_suffix obj diff --git a/src/cert/cvc/info.txt b/src/cert/cvc/info.txt index e3e11f5fe..bdd496614 100644 --- a/src/cert/cvc/info.txt +++ b/src/cert/cvc/info.txt @@ -1,5 +1,3 @@ -realname "Card Verifiable Certificates" - define CARD_VERIFIABLE_CERTIFICATES uses_tr1 yes diff --git a/src/cert/x509/info.txt b/src/cert/x509/info.txt index 552e2aacb..37faea9fa 100644 --- a/src/cert/x509/info.txt +++ b/src/cert/x509/info.txt @@ -1,5 +1,3 @@ -realname "X.509" - define X509 load_on auto diff --git a/src/checksum/adler32/info.txt b/src/checksum/adler32/info.txt index 76662cdec..53bc66354 100644 --- a/src/checksum/adler32/info.txt +++ b/src/checksum/adler32/info.txt @@ -1,5 +1,3 @@ -realname "Adler32" - define ADLER32 load_on auto diff --git a/src/checksum/crc24/info.txt b/src/checksum/crc24/info.txt index 33b86a9da..8c61aa58b 100644 --- a/src/checksum/crc24/info.txt +++ b/src/checksum/crc24/info.txt @@ -1,5 +1,3 @@ -realname "CRC-24" - define CRC24 load_on auto diff --git a/src/checksum/crc32/info.txt b/src/checksum/crc32/info.txt index 15933b375..d86848cf4 100644 --- a/src/checksum/crc32/info.txt +++ b/src/checksum/crc32/info.txt @@ -1,5 +1,3 @@ -realname "CRC-32" - define CRC32 load_on auto diff --git a/src/cms/info.txt b/src/cms/info.txt index 82c31b564..55d559f83 100644 --- a/src/cms/info.txt +++ b/src/cms/info.txt @@ -1,5 +1,3 @@ -realname "CMS" - define CMS load_on auto diff --git a/src/codec/base64/info.txt b/src/codec/base64/info.txt index d4ed80976..1d36b948e 100644 --- a/src/codec/base64/info.txt +++ b/src/codec/base64/info.txt @@ -1,5 +1,3 @@ -realname "Base64 Codec" - define BASE64_CODEC load_on auto diff --git a/src/codec/bzip2/info.txt b/src/codec/bzip2/info.txt index 1be84e405..7fd426f90 100644 --- a/src/codec/bzip2/info.txt +++ b/src/codec/bzip2/info.txt @@ -1,6 +1,5 @@ # This module was written by Peter J. Jones -realname "Bzip2 Compressor" define COMPRESSOR_BZIP2 modset compression diff --git a/src/codec/hex/info.txt b/src/codec/hex/info.txt index 512a5de8b..817ff1a00 100644 --- a/src/codec/hex/info.txt +++ b/src/codec/hex/info.txt @@ -1,5 +1,3 @@ -realname "Hex Codec" - define HEX_CODEC load_on auto diff --git a/src/codec/openpgp/info.txt b/src/codec/openpgp/info.txt index 6b30850d0..f7774b147 100644 --- a/src/codec/openpgp/info.txt +++ b/src/codec/openpgp/info.txt @@ -1,5 +1,3 @@ -realname "OpenPGP Codec" - define OPENPGP_CODEC load_on auto diff --git a/src/codec/pem/info.txt b/src/codec/pem/info.txt index bbe8d4c70..5544e1bb0 100644 --- a/src/codec/pem/info.txt +++ b/src/codec/pem/info.txt @@ -1,5 +1,3 @@ -realname "PEM Codec" - define PEM_CODEC load_on auto diff --git a/src/codec/zlib/info.txt b/src/codec/zlib/info.txt index 9b1c35d84..267c3be92 100644 --- a/src/codec/zlib/info.txt +++ b/src/codec/zlib/info.txt @@ -1,4 +1,3 @@ -realname "Zlib Compressor" #realname "Zlib/Gzip Compressor" define COMPRESSOR_ZLIB diff --git a/src/cryptobox/info.txt b/src/cryptobox/info.txt index b9b98060f..0780f55aa 100644 --- a/src/cryptobox/info.txt +++ b/src/cryptobox/info.txt @@ -1,5 +1,3 @@ -realname "Crypto Box" - load_on auto define CRYPTO_BOX diff --git a/src/engine/amd64_eng/info.txt b/src/engine/amd64_eng/info.txt index 47f891445..03baf76ee 100644 --- a/src/engine/amd64_eng/info.txt +++ b/src/engine/amd64_eng/info.txt @@ -1,5 +1,3 @@ -realname "AMD64 Assembler Engine" - define ENGINE_AMD64_ASSEMBLER load_on dep diff --git a/src/engine/def_engine/info.txt b/src/engine/def_engine/info.txt index fd31ee2d0..e307fbf8e 100644 --- a/src/engine/def_engine/info.txt +++ b/src/engine/def_engine/info.txt @@ -1,5 +1,3 @@ -realname "Default Engine" - define DEFAULT_ENGINE load_on auto diff --git a/src/engine/gnump/info.txt b/src/engine/gnump/info.txt index 67a9bcd70..0805c1ba8 100644 --- a/src/engine/gnump/info.txt +++ b/src/engine/gnump/info.txt @@ -1,5 +1,3 @@ -realname "GMP Engine" - define ENGINE_GNU_MP load_on request diff --git a/src/engine/ia32_eng/info.txt b/src/engine/ia32_eng/info.txt index 3bf2a7f2b..98fd1f2cc 100644 --- a/src/engine/ia32_eng/info.txt +++ b/src/engine/ia32_eng/info.txt @@ -1,5 +1,3 @@ -realname "IA32 Assembler Engine" - define ENGINE_IA32_ASSEMBLER load_on dep diff --git a/src/engine/info.txt b/src/engine/info.txt index eef3c03b6..dcb26d9d6 100644 --- a/src/engine/info.txt +++ b/src/engine/info.txt @@ -1,5 +1,3 @@ -realname "Engines" - define ENGINES load_on auto diff --git a/src/engine/openssl/info.txt b/src/engine/openssl/info.txt index 3f2f1ab14..9f8c84b31 100644 --- a/src/engine/openssl/info.txt +++ b/src/engine/openssl/info.txt @@ -1,5 +1,3 @@ -realname "OpenSSL Engine" - define ENGINE_OPENSSL load_on request diff --git a/src/engine/sse2_eng/info.txt b/src/engine/sse2_eng/info.txt index 7508b9874..43df92343 100644 --- a/src/engine/sse2_eng/info.txt +++ b/src/engine/sse2_eng/info.txt @@ -1,5 +1,3 @@ -realname "SSE2 Assembler Engine" - define ENGINE_SSE2_ASSEMBLER load_on dep diff --git a/src/entropy/beos_stats/info.txt b/src/entropy/beos_stats/info.txt index a7e62cfb3..84ecf601d 100644 --- a/src/entropy/beos_stats/info.txt +++ b/src/entropy/beos_stats/info.txt @@ -1,5 +1,3 @@ -realname "BeOS Entropy Source" - define ENTROPY_SRC_BEOS modset beos diff --git a/src/entropy/cryptoapi_rng/info.txt b/src/entropy/cryptoapi_rng/info.txt index 643c67d2e..d7a5dbca0 100644 --- a/src/entropy/cryptoapi_rng/info.txt +++ b/src/entropy/cryptoapi_rng/info.txt @@ -1,5 +1,3 @@ -realname "Win32 CryptoAPI Entropy Source" - define ENTROPY_SRC_CAPI load_on auto modset win32 diff --git a/src/entropy/dev_random/info.txt b/src/entropy/dev_random/info.txt index 5231b2901..376f3b4ba 100644 --- a/src/entropy/dev_random/info.txt +++ b/src/entropy/dev_random/info.txt @@ -1,5 +1,3 @@ -realname "RNG Device Reader" - define ENTROPY_SRC_DEVICE load_on auto diff --git a/src/entropy/egd/info.txt b/src/entropy/egd/info.txt index 85ba86c00..77e7197dc 100644 --- a/src/entropy/egd/info.txt +++ b/src/entropy/egd/info.txt @@ -1,5 +1,3 @@ -realname "EGD Entropy Source" - define ENTROPY_SRC_EGD load_on auto diff --git a/src/entropy/info.txt b/src/entropy/info.txt index ec3be5f58..5f3d39dd5 100644 --- a/src/entropy/info.txt +++ b/src/entropy/info.txt @@ -1,5 +1,3 @@ -realname "Entropy Sources" - load_on auto diff --git a/src/entropy/proc_walk/info.txt b/src/entropy/proc_walk/info.txt index b82929a73..f6302df1a 100644 --- a/src/entropy/proc_walk/info.txt +++ b/src/entropy/proc_walk/info.txt @@ -1,5 +1,3 @@ -realname "File Tree Walking Entropy Source" - define ENTROPY_SRC_FTW load_on auto diff --git a/src/entropy/unix_procs/info.txt b/src/entropy/unix_procs/info.txt index 928ec13b3..de88cc1b8 100644 --- a/src/entropy/unix_procs/info.txt +++ b/src/entropy/unix_procs/info.txt @@ -1,5 +1,3 @@ -realname "Generic Unix Entropy Source" - define ENTROPY_SRC_UNIX modset unix,beos diff --git a/src/entropy/win32_stats/info.txt b/src/entropy/win32_stats/info.txt index ca7100923..da8ea72ff 100644 --- a/src/entropy/win32_stats/info.txt +++ b/src/entropy/win32_stats/info.txt @@ -1,5 +1,3 @@ -realname "Win32 Entropy Source" - # Probably not much of an issue anymore #note "This module will not run under NT4" diff --git a/src/filters/fd_unix/info.txt b/src/filters/fd_unix/info.txt index d87978cb0..bdd9b957f 100644 --- a/src/filters/fd_unix/info.txt +++ b/src/filters/fd_unix/info.txt @@ -1,5 +1,3 @@ -realname "Unix I/O support for Pipe" - define PIPE_UNIXFD_IO modset unix,beos diff --git a/src/filters/info.txt b/src/filters/info.txt index fb8108659..a76b6b4fe 100644 --- a/src/filters/info.txt +++ b/src/filters/info.txt @@ -1,5 +1,3 @@ -realname "Pipe/Filter" - load_on auto define FILTERS diff --git a/src/hash/bmw/info.txt b/src/hash/bmw/info.txt index 27e069c0a..7170223d7 100644 --- a/src/hash/bmw/info.txt +++ b/src/hash/bmw/info.txt @@ -1,5 +1,3 @@ -realname "Blue Midnight Wish" - define BMW_512 diff --git a/src/hash/fork256/info.txt b/src/hash/fork256/info.txt index 7c3c5bb94..c2f8c47f2 100644 --- a/src/hash/fork256/info.txt +++ b/src/hash/fork256/info.txt @@ -1,5 +1,3 @@ -realname "FORK-256" - define FORK_256 diff --git a/src/hash/gost_3411/info.txt b/src/hash/gost_3411/info.txt index 353ceb3e5..c4cb4e1a5 100644 --- a/src/hash/gost_3411/info.txt +++ b/src/hash/gost_3411/info.txt @@ -1,5 +1,3 @@ -realname "GOST 34.11" - define GOST_34_11 diff --git a/src/hash/has160/info.txt b/src/hash/has160/info.txt index 98cbc5155..f862bdb20 100644 --- a/src/hash/has160/info.txt +++ b/src/hash/has160/info.txt @@ -1,5 +1,3 @@ -realname "HAS-160" - define HAS_160 diff --git a/src/hash/info.txt b/src/hash/info.txt index ce55f7ddc..0e45806f8 100644 --- a/src/hash/info.txt +++ b/src/hash/info.txt @@ -1,5 +1,3 @@ -realname "Hash Functions" - load_on auto diff --git a/src/hash/md2/info.txt b/src/hash/md2/info.txt index 4428584fd..2359c5df7 100644 --- a/src/hash/md2/info.txt +++ b/src/hash/md2/info.txt @@ -1,3 +1 @@ -realname "MD2" - define MD2 diff --git a/src/hash/md4/info.txt b/src/hash/md4/info.txt index 6aa4a5d59..2b276e168 100644 --- a/src/hash/md4/info.txt +++ b/src/hash/md4/info.txt @@ -1,5 +1,3 @@ -realname "MD4" - define MD4 diff --git a/src/hash/md4_ia32/info.txt b/src/hash/md4_ia32/info.txt index 217c3fc21..732285c56 100644 --- a/src/hash/md4_ia32/info.txt +++ b/src/hash/md4_ia32/info.txt @@ -1,5 +1,3 @@ -realname "MD4 (IA-32)" - define MD4_IA32 load_on asm_ok diff --git a/src/hash/md5/info.txt b/src/hash/md5/info.txt index 14861d635..a4ad1462c 100644 --- a/src/hash/md5/info.txt +++ b/src/hash/md5/info.txt @@ -1,5 +1,3 @@ -realname "MD5" - define MD5 diff --git a/src/hash/md5_ia32/info.txt b/src/hash/md5_ia32/info.txt index d298f2005..48a8b4a10 100644 --- a/src/hash/md5_ia32/info.txt +++ b/src/hash/md5_ia32/info.txt @@ -1,5 +1,3 @@ -realname "MD5 (IA-32)" - define MD5_IA32 load_on asm_ok diff --git a/src/hash/mdx_hash/info.txt b/src/hash/mdx_hash/info.txt index ee4ccd6da..0c30a1a54 100644 --- a/src/hash/mdx_hash/info.txt +++ b/src/hash/mdx_hash/info.txt @@ -1,5 +1,3 @@ -realname "MDx Hash Base" - define MDX_HASH_FUNCTION load_on dep diff --git a/src/hash/par_hash/info.txt b/src/hash/par_hash/info.txt index 029939cb5..d641a9cee 100644 --- a/src/hash/par_hash/info.txt +++ b/src/hash/par_hash/info.txt @@ -1,3 +1 @@ -realname "Parallel Hash" - define PARALLEL_HASH diff --git a/src/hash/rmd128/info.txt b/src/hash/rmd128/info.txt index 0a1ef2c74..11e4181f4 100644 --- a/src/hash/rmd128/info.txt +++ b/src/hash/rmd128/info.txt @@ -1,5 +1,3 @@ -realname "RIPEMD-128" - define RIPEMD_128 diff --git a/src/hash/rmd160/info.txt b/src/hash/rmd160/info.txt index 225106afc..28be6854d 100644 --- a/src/hash/rmd160/info.txt +++ b/src/hash/rmd160/info.txt @@ -1,5 +1,3 @@ -realname "RIPEMD-160" - define RIPEMD_160 diff --git a/src/hash/sha1/info.txt b/src/hash/sha1/info.txt index 8915f9ebd..56403db21 100644 --- a/src/hash/sha1/info.txt +++ b/src/hash/sha1/info.txt @@ -1,5 +1,3 @@ -realname "SHA-1" - define SHA1 diff --git a/src/hash/sha1_amd64/info.txt b/src/hash/sha1_amd64/info.txt index 183658ac7..e54b032ca 100644 --- a/src/hash/sha1_amd64/info.txt +++ b/src/hash/sha1_amd64/info.txt @@ -1,5 +1,3 @@ -realname "SHA-1 (x86-64 assembler)" - define SHA1_AMD64 load_on asm_ok diff --git a/src/hash/sha1_ia32/info.txt b/src/hash/sha1_ia32/info.txt index e7709454f..0361395fe 100644 --- a/src/hash/sha1_ia32/info.txt +++ b/src/hash/sha1_ia32/info.txt @@ -1,5 +1,3 @@ -realname "SHA-1 (IA-32)" - define SHA1_IA32 load_on asm_ok diff --git a/src/hash/sha1_sse2/info.txt b/src/hash/sha1_sse2/info.txt index 4a7a1b5e9..ad61aa5fa 100644 --- a/src/hash/sha1_sse2/info.txt +++ b/src/hash/sha1_sse2/info.txt @@ -1,5 +1,3 @@ -realname "SHA-1 (SSE2)" - define SHA1_SSE2 diff --git a/src/hash/sha2/info.txt b/src/hash/sha2/info.txt index 8cc50fa41..e12f2b694 100644 --- a/src/hash/sha2/info.txt +++ b/src/hash/sha2/info.txt @@ -1,5 +1,3 @@ -realname "SHA-2 (224, 256, 384, 512)" - define SHA2 diff --git a/src/hash/skein/info.txt b/src/hash/skein/info.txt index 908033852..427f59121 100644 --- a/src/hash/skein/info.txt +++ b/src/hash/skein/info.txt @@ -1,5 +1,3 @@ -realname "Skein" - define SKEIN_512 diff --git a/src/hash/tiger/info.txt b/src/hash/tiger/info.txt index 92b5519c0..b50b745e3 100644 --- a/src/hash/tiger/info.txt +++ b/src/hash/tiger/info.txt @@ -1,5 +1,3 @@ -realname "Tiger" - define TIGER diff --git a/src/hash/whirlpool/info.txt b/src/hash/whirlpool/info.txt index 4fe4b2b25..7bec0c6cf 100644 --- a/src/hash/whirlpool/info.txt +++ b/src/hash/whirlpool/info.txt @@ -1,5 +1,3 @@ -realname "Whirlpool" - define WHIRLPOOL diff --git a/src/kdf/info.txt b/src/kdf/info.txt index 1965a2098..8eb4fc6e9 100644 --- a/src/kdf/info.txt +++ b/src/kdf/info.txt @@ -1,5 +1,3 @@ -realname "KDF Base Class" - define KDF_BASE load_on auto diff --git a/src/kdf/kdf1/info.txt b/src/kdf/kdf1/info.txt index ede10017e..2557f9472 100644 --- a/src/kdf/kdf1/info.txt +++ b/src/kdf/kdf1/info.txt @@ -1,5 +1,3 @@ -realname "KDF1" - define KDF1 load_on auto diff --git a/src/kdf/kdf2/info.txt b/src/kdf/kdf2/info.txt index 1858f8929..b71595449 100644 --- a/src/kdf/kdf2/info.txt +++ b/src/kdf/kdf2/info.txt @@ -1,5 +1,3 @@ -realname "KDF2" - define KDF2 load_on auto diff --git a/src/kdf/mgf1/info.txt b/src/kdf/mgf1/info.txt index f9e952f82..0f104c3b3 100644 --- a/src/kdf/mgf1/info.txt +++ b/src/kdf/mgf1/info.txt @@ -1,5 +1,3 @@ -realname "MGF1" - define MGF1 load_on dep diff --git a/src/kdf/ssl_prf/info.txt b/src/kdf/ssl_prf/info.txt index f862905a2..b306721b9 100644 --- a/src/kdf/ssl_prf/info.txt +++ b/src/kdf/ssl_prf/info.txt @@ -1,5 +1,3 @@ -realname "SSLv3 PRF" - define SSL_V3_PRF load_on auto diff --git a/src/kdf/tls_prf/info.txt b/src/kdf/tls_prf/info.txt index f95ef9c24..11a0d44f5 100644 --- a/src/kdf/tls_prf/info.txt +++ b/src/kdf/tls_prf/info.txt @@ -1,5 +1,3 @@ -realname "TLS v1.0 PRF" - define TLS_V10_PRF load_on auto diff --git a/src/kdf/x942_prf/info.txt b/src/kdf/x942_prf/info.txt index 295c2cde6..e38b2aac1 100644 --- a/src/kdf/x942_prf/info.txt +++ b/src/kdf/x942_prf/info.txt @@ -1,5 +1,3 @@ -realname "X942 PRF" - define X942_PRF load_on auto diff --git a/src/libstate/info.txt b/src/libstate/info.txt index 6eaa2f70b..e8271ce99 100644 --- a/src/libstate/info.txt +++ b/src/libstate/info.txt @@ -1,5 +1,3 @@ -realname "Botan Libstate Module" - load_on always define LIBSTATE_MODULE diff --git a/src/libstate/oid_lookup/info.txt b/src/libstate/oid_lookup/info.txt index 609eb9199..e0f6f099c 100644 --- a/src/libstate/oid_lookup/info.txt +++ b/src/libstate/oid_lookup/info.txt @@ -1,5 +1,3 @@ -realname "OID Lookup" - load_on dep define OID_LOOKUP diff --git a/src/mac/cbc_mac/info.txt b/src/mac/cbc_mac/info.txt index 3a5434974..80adc5fd0 100644 --- a/src/mac/cbc_mac/info.txt +++ b/src/mac/cbc_mac/info.txt @@ -1,5 +1,3 @@ -realname "CBC-MAC" - define CBC_MAC load_on auto diff --git a/src/mac/cmac/info.txt b/src/mac/cmac/info.txt index b593c9d38..5dad789de 100644 --- a/src/mac/cmac/info.txt +++ b/src/mac/cmac/info.txt @@ -1,5 +1,3 @@ -realname "CMAC" - define CMAC load_on auto diff --git a/src/mac/hmac/info.txt b/src/mac/hmac/info.txt index cdf2e67ab..26da83533 100644 --- a/src/mac/hmac/info.txt +++ b/src/mac/hmac/info.txt @@ -1,5 +1,3 @@ -realname "HMAC" - define HMAC load_on auto diff --git a/src/mac/info.txt b/src/mac/info.txt index 239eb633f..9a839d04d 100644 --- a/src/mac/info.txt +++ b/src/mac/info.txt @@ -1,5 +1,3 @@ -realname "Message Authentication Codes" - load_on auto diff --git a/src/mac/ssl3mac/info.txt b/src/mac/ssl3mac/info.txt index f8791169c..c4ef54629 100644 --- a/src/mac/ssl3mac/info.txt +++ b/src/mac/ssl3mac/info.txt @@ -1,5 +1,3 @@ -realname "SSLv3 MAC" - define SSL3_MAC load_on auto diff --git a/src/mac/x919_mac/info.txt b/src/mac/x919_mac/info.txt index f2ebd5b35..16955816c 100644 --- a/src/mac/x919_mac/info.txt +++ b/src/mac/x919_mac/info.txt @@ -1,5 +1,3 @@ -realname "ANSI X9.19 MAC" - define ANSI_X919_MAC load_on auto diff --git a/src/math/bigint/info.txt b/src/math/bigint/info.txt index 513703deb..30018b795 100644 --- a/src/math/bigint/info.txt +++ b/src/math/bigint/info.txt @@ -1,5 +1,3 @@ -realname "BigInt" - load_on auto define BIGINT diff --git a/src/math/bigint/monty_amd64/info.txt b/src/math/bigint/monty_amd64/info.txt index a897045b2..657cd0353 100644 --- a/src/math/bigint/monty_amd64/info.txt +++ b/src/math/bigint/monty_amd64/info.txt @@ -1,5 +1,3 @@ -realname "Montgomery Reduction (x86-64)" - mp_bits 64 load_on never diff --git a/src/math/bigint/monty_generic/info.txt b/src/math/bigint/monty_generic/info.txt index 6f5f0e722..c709229e6 100644 --- a/src/math/bigint/monty_generic/info.txt +++ b/src/math/bigint/monty_generic/info.txt @@ -1,5 +1,3 @@ -realname "Montgomery Reduction" - load_on dep diff --git a/src/math/bigint/mp_amd64/info.txt b/src/math/bigint/mp_amd64/info.txt index 84a5bcf53..a7da8806e 100644 --- a/src/math/bigint/mp_amd64/info.txt +++ b/src/math/bigint/mp_amd64/info.txt @@ -1,5 +1,3 @@ -realname "MPI Core (x86-64)" - mp_bits 64 load_on dep diff --git a/src/math/bigint/mp_asm64/info.txt b/src/math/bigint/mp_asm64/info.txt index 5c112c490..7bdbffb2c 100644 --- a/src/math/bigint/mp_asm64/info.txt +++ b/src/math/bigint/mp_asm64/info.txt @@ -1,5 +1,3 @@ -realname "MPI Core (Alpha/IA-64/MIPS64/PowerPC-64/SPARC64)" - mp_bits 64 load_on dep diff --git a/src/math/bigint/mp_generic/info.txt b/src/math/bigint/mp_generic/info.txt index 8bf75fec3..28f258ebb 100644 --- a/src/math/bigint/mp_generic/info.txt +++ b/src/math/bigint/mp_generic/info.txt @@ -1,5 +1,3 @@ -realname "MPI Core (C++)" - load_on dep diff --git a/src/math/bigint/mp_ia32/info.txt b/src/math/bigint/mp_ia32/info.txt index 51f98fda8..6e093a7e5 100644 --- a/src/math/bigint/mp_ia32/info.txt +++ b/src/math/bigint/mp_ia32/info.txt @@ -1,5 +1,3 @@ -realname "MPI Core (IA-32)" - mp_bits 32 load_on asm_ok diff --git a/src/math/bigint/mp_ia32_msvc/info.txt b/src/math/bigint/mp_ia32_msvc/info.txt index 9c7ac9b43..52839d89b 100644 --- a/src/math/bigint/mp_ia32_msvc/info.txt +++ b/src/math/bigint/mp_ia32_msvc/info.txt @@ -1,5 +1,3 @@ -realname "x86 MPI Assembler Core (MSVC)" - mp_bits 32 load_on dep diff --git a/src/math/bigint/mulop_amd64/info.txt b/src/math/bigint/mulop_amd64/info.txt index 77990df80..704e4dad8 100644 --- a/src/math/bigint/mulop_amd64/info.txt +++ b/src/math/bigint/mulop_amd64/info.txt @@ -1,5 +1,3 @@ -realname "BigInt Multiply-Add (x86-64)" - mp_bits 64 load_on never diff --git a/src/math/bigint/mulop_generic/info.txt b/src/math/bigint/mulop_generic/info.txt index 28ebe41eb..8fa2a40c9 100644 --- a/src/math/bigint/mulop_generic/info.txt +++ b/src/math/bigint/mulop_generic/info.txt @@ -1,5 +1,3 @@ -realname "BigInt Multiply-Add" - load_on dep diff --git a/src/math/bigint/mulop_ia32/info.txt b/src/math/bigint/mulop_ia32/info.txt index b995dd8d7..dd554773f 100644 --- a/src/math/bigint/mulop_ia32/info.txt +++ b/src/math/bigint/mulop_ia32/info.txt @@ -1,5 +1,3 @@ -realname "BigInt Multiply-Add (IA-32)" - mp_bits 32 # Out of date, still implements bigint_mul_add_words diff --git a/src/math/gfpmath/info.txt b/src/math/gfpmath/info.txt index 1a52144b7..abbdb0a47 100644 --- a/src/math/gfpmath/info.txt +++ b/src/math/gfpmath/info.txt @@ -1,5 +1,3 @@ -realname "GF(p) Math" - uses_tr1 yes load_on auto diff --git a/src/math/numbertheory/info.txt b/src/math/numbertheory/info.txt index 1595c7305..527f4fa29 100644 --- a/src/math/numbertheory/info.txt +++ b/src/math/numbertheory/info.txt @@ -1,5 +1,3 @@ -realname "Math Functions" - load_on auto define BIGINT_MATH diff --git a/src/modes/cbc/info.txt b/src/modes/cbc/info.txt index de81dcb8c..9b4be1b58 100644 --- a/src/modes/cbc/info.txt +++ b/src/modes/cbc/info.txt @@ -1,5 +1,3 @@ -realname "CBC block cipher mode" - define CBC load_on auto diff --git a/src/modes/cfb/info.txt b/src/modes/cfb/info.txt index d66df1ee7..b68afc7d0 100644 --- a/src/modes/cfb/info.txt +++ b/src/modes/cfb/info.txt @@ -1,5 +1,3 @@ -realname "CFB block cipher mode" - define CFB load_on auto @@ -12,4 +10,3 @@ cfb.h modes - diff --git a/src/modes/cts/info.txt b/src/modes/cts/info.txt index 9eb16add5..773254a30 100644 --- a/src/modes/cts/info.txt +++ b/src/modes/cts/info.txt @@ -1,5 +1,3 @@ -realname "CTS block cipher mode" - define CTS load_on auto diff --git a/src/modes/eax/info.txt b/src/modes/eax/info.txt index d1fc7e0e3..143944f03 100644 --- a/src/modes/eax/info.txt +++ b/src/modes/eax/info.txt @@ -1,5 +1,3 @@ -realname "EAX block cipher mode" - define EAX load_on auto diff --git a/src/modes/ecb/info.txt b/src/modes/ecb/info.txt index 06b7b4fd2..f5c831169 100644 --- a/src/modes/ecb/info.txt +++ b/src/modes/ecb/info.txt @@ -1,5 +1,3 @@ -realname "ECB block cipher mode" - define ECB load_on auto diff --git a/src/modes/info.txt b/src/modes/info.txt index e089e74a9..420233b46 100644 --- a/src/modes/info.txt +++ b/src/modes/info.txt @@ -1,5 +1,3 @@ -realname "Cipher Mode Base Class" - define CIPHER_MODEBASE load_on auto diff --git a/src/modes/mode_pad/info.txt b/src/modes/mode_pad/info.txt index f22cf7411..9629a7202 100644 --- a/src/modes/mode_pad/info.txt +++ b/src/modes/mode_pad/info.txt @@ -1,5 +1,3 @@ -realname "Cipher Mode Padding Method" - define CIPHER_MODE_PADDING load_on auto diff --git a/src/modes/xts/info.txt b/src/modes/xts/info.txt index 65c7df2f8..871bb987a 100644 --- a/src/modes/xts/info.txt +++ b/src/modes/xts/info.txt @@ -1,5 +1,3 @@ -realname "XTS block cipher mode" - define XTS load_on auto diff --git a/src/mutex/info.txt b/src/mutex/info.txt index ff79bf753..0f2836b64 100644 --- a/src/mutex/info.txt +++ b/src/mutex/info.txt @@ -1,5 +1,3 @@ -realname "Mutex Wrappers" - define MUTEX_WRAPPERS load_on auto diff --git a/src/mutex/noop_mutex/info.txt b/src/mutex/noop_mutex/info.txt index 1f49f5e1c..6025959c2 100644 --- a/src/mutex/noop_mutex/info.txt +++ b/src/mutex/noop_mutex/info.txt @@ -1,5 +1,3 @@ -realname "No-Op Mutex" - load_on auto define MUTEX_NOOP diff --git a/src/mutex/pthreads/info.txt b/src/mutex/pthreads/info.txt index f135dea48..7315c186a 100644 --- a/src/mutex/pthreads/info.txt +++ b/src/mutex/pthreads/info.txt @@ -1,5 +1,3 @@ -realname "Pthread Mutex" - define MUTEX_PTHREAD load_on auto diff --git a/src/mutex/qt_mutex/info.txt b/src/mutex/qt_mutex/info.txt index a21108c79..922c38ed1 100644 --- a/src/mutex/qt_mutex/info.txt +++ b/src/mutex/qt_mutex/info.txt @@ -1,5 +1,3 @@ -realname "Qt Mutex" - define MUTEX_QT note "You'll probably have to add -I/-L flags to the Makefile to find Qt" diff --git a/src/mutex/win32_crit_section/info.txt b/src/mutex/win32_crit_section/info.txt index a2d339c3b..ffa8a98e3 100644 --- a/src/mutex/win32_crit_section/info.txt +++ b/src/mutex/win32_crit_section/info.txt @@ -1,5 +1,3 @@ -realname "Win32 Mutex" - define MUTEX_WIN32 modset win32 diff --git a/src/pbe/info.txt b/src/pbe/info.txt index c4210b2a7..f58ed1da4 100644 --- a/src/pbe/info.txt +++ b/src/pbe/info.txt @@ -1,5 +1,3 @@ -realname "PBE Base" - load_on dep define PASSWORD_BASED_ENCRYPTION diff --git a/src/pbe/pbes1/info.txt b/src/pbe/pbes1/info.txt index 70c6baeee..5dcbf9510 100644 --- a/src/pbe/pbes1/info.txt +++ b/src/pbe/pbes1/info.txt @@ -1,5 +1,3 @@ -realname "PKCS5 v1.5 PBE" - define PBE_PKCS_V15 load_on auto diff --git a/src/pbe/pbes2/info.txt b/src/pbe/pbes2/info.txt index cd37b1e69..71fb6ea72 100644 --- a/src/pbe/pbes2/info.txt +++ b/src/pbe/pbes2/info.txt @@ -1,5 +1,3 @@ -realname "PKCS5 v2.0 PBE" - define PBE_PKCS_V20 load_on auto diff --git a/src/pk_pad/eme1/info.txt b/src/pk_pad/eme1/info.txt index 2f61265e2..794254e8e 100644 --- a/src/pk_pad/eme1/info.txt +++ b/src/pk_pad/eme1/info.txt @@ -1,5 +1,3 @@ -realname "EME1" - define EME1 load_on auto diff --git a/src/pk_pad/eme_pkcs/info.txt b/src/pk_pad/eme_pkcs/info.txt index 88d9caf17..95c568452 100644 --- a/src/pk_pad/eme_pkcs/info.txt +++ b/src/pk_pad/eme_pkcs/info.txt @@ -1,5 +1,3 @@ -realname "PKCSv1 v1.5 EME" - define EME_PKCS1v15 load_on auto diff --git a/src/pk_pad/emsa1/info.txt b/src/pk_pad/emsa1/info.txt index 086270b96..55832307b 100644 --- a/src/pk_pad/emsa1/info.txt +++ b/src/pk_pad/emsa1/info.txt @@ -1,5 +1,3 @@ -realname "EMSA1" - define EMSA1 load_on auto diff --git a/src/pk_pad/emsa1_bsi/info.txt b/src/pk_pad/emsa1_bsi/info.txt index 14a9fd396..5e8fe09ca 100644 --- a/src/pk_pad/emsa1_bsi/info.txt +++ b/src/pk_pad/emsa1_bsi/info.txt @@ -1,5 +1,3 @@ -realname "EMSA1 (BSI variant)" - define EMSA1_BSI load_on auto diff --git a/src/pk_pad/emsa2/info.txt b/src/pk_pad/emsa2/info.txt index 1c8161c5e..a6fff2a02 100644 --- a/src/pk_pad/emsa2/info.txt +++ b/src/pk_pad/emsa2/info.txt @@ -1,5 +1,3 @@ -realname "EMSA2" - define EMSA2 load_on auto diff --git a/src/pk_pad/emsa3/info.txt b/src/pk_pad/emsa3/info.txt index 90e4b9bfc..babd98711 100644 --- a/src/pk_pad/emsa3/info.txt +++ b/src/pk_pad/emsa3/info.txt @@ -1,5 +1,3 @@ -realname "EMSA3" - define EMSA3 load_on auto diff --git a/src/pk_pad/emsa4/info.txt b/src/pk_pad/emsa4/info.txt index 29ef4e0cf..ea1db30a1 100644 --- a/src/pk_pad/emsa4/info.txt +++ b/src/pk_pad/emsa4/info.txt @@ -1,5 +1,3 @@ -realname "EMSA4" - define EMSA4 load_on auto diff --git a/src/pk_pad/emsa_raw/info.txt b/src/pk_pad/emsa_raw/info.txt index 2a88d10fa..4bd850e11 100644 --- a/src/pk_pad/emsa_raw/info.txt +++ b/src/pk_pad/emsa_raw/info.txt @@ -1,5 +1,3 @@ -realname "EMSA-Raw" - define EMSA_RAW load_on auto diff --git a/src/pk_pad/hash_id/info.txt b/src/pk_pad/hash_id/info.txt index 935432588..af9f5cd4f 100644 --- a/src/pk_pad/hash_id/info.txt +++ b/src/pk_pad/hash_id/info.txt @@ -1,5 +1,3 @@ -realname "Hash Function Identifiers" - define HASH_ID load_on auto diff --git a/src/pk_pad/info.txt b/src/pk_pad/info.txt index c281b1563..14b05f458 100644 --- a/src/pk_pad/info.txt +++ b/src/pk_pad/info.txt @@ -1,5 +1,3 @@ -realname "Public Key EME/EMSA Padding Modes" - define PK_PADDING load_on auto diff --git a/src/pubkey/dh/info.txt b/src/pubkey/dh/info.txt index 33af9a8e5..8295a74f4 100644 --- a/src/pubkey/dh/info.txt +++ b/src/pubkey/dh/info.txt @@ -1,5 +1,3 @@ -realname "Diffie-Hellman Key Agreement" - define DIFFIE_HELLMAN load_on auto diff --git a/src/pubkey/dl_algo/info.txt b/src/pubkey/dl_algo/info.txt index 15a77516b..0ac91c887 100644 --- a/src/pubkey/dl_algo/info.txt +++ b/src/pubkey/dl_algo/info.txt @@ -1,5 +1,3 @@ -realname "Discrete Logarithm PK Algorithms" - define DL_PUBLIC_KEY_FAMILY load_on auto diff --git a/src/pubkey/dl_group/info.txt b/src/pubkey/dl_group/info.txt index 6b9884a4d..2e5273ac4 100644 --- a/src/pubkey/dl_group/info.txt +++ b/src/pubkey/dl_group/info.txt @@ -1,5 +1,3 @@ -realname "DL Group" - load_on auto define DL_GROUP diff --git a/src/pubkey/dlies/info.txt b/src/pubkey/dlies/info.txt index 5138aafc5..d3e950427 100644 --- a/src/pubkey/dlies/info.txt +++ b/src/pubkey/dlies/info.txt @@ -1,5 +1,3 @@ -realname "DLIES" - define DLIES load_on auto diff --git a/src/pubkey/dsa/info.txt b/src/pubkey/dsa/info.txt index c70e02d90..776a5da28 100644 --- a/src/pubkey/dsa/info.txt +++ b/src/pubkey/dsa/info.txt @@ -1,5 +1,3 @@ -realname "DSA" - define DSA load_on auto diff --git a/src/pubkey/ec_dompar/info.txt b/src/pubkey/ec_dompar/info.txt index 212783725..f32e4fc2f 100644 --- a/src/pubkey/ec_dompar/info.txt +++ b/src/pubkey/ec_dompar/info.txt @@ -1,5 +1,3 @@ -realname "ECC Domain Parameters" - define ECC_DOMAIN_PARAMATERS load_on auto diff --git a/src/pubkey/ecc_key/info.txt b/src/pubkey/ecc_key/info.txt index 2a3c9a3b2..f45533129 100644 --- a/src/pubkey/ecc_key/info.txt +++ b/src/pubkey/ecc_key/info.txt @@ -1,5 +1,3 @@ -realname "ECC Public Key" - define ECC_PUBLIC_KEY_CRYPTO load_on auto diff --git a/src/pubkey/ecdsa/info.txt b/src/pubkey/ecdsa/info.txt index 743440f8f..3da73dd34 100644 --- a/src/pubkey/ecdsa/info.txt +++ b/src/pubkey/ecdsa/info.txt @@ -1,5 +1,3 @@ -realname "ECDSA" - define ECDSA load_on auto diff --git a/src/pubkey/eckaeg/info.txt b/src/pubkey/eckaeg/info.txt index 6b78f7de5..3a9768df1 100644 --- a/src/pubkey/eckaeg/info.txt +++ b/src/pubkey/eckaeg/info.txt @@ -1,5 +1,3 @@ -realname "ECKAEG" - define ECKAEG load_on auto diff --git a/src/pubkey/elgamal/info.txt b/src/pubkey/elgamal/info.txt index d7ae614ea..8c55eb909 100644 --- a/src/pubkey/elgamal/info.txt +++ b/src/pubkey/elgamal/info.txt @@ -1,5 +1,3 @@ -realname "ElGamal" - define ELGAMAL load_on auto diff --git a/src/pubkey/if_algo/info.txt b/src/pubkey/if_algo/info.txt index d2142f42f..ec948aec3 100644 --- a/src/pubkey/if_algo/info.txt +++ b/src/pubkey/if_algo/info.txt @@ -1,5 +1,3 @@ -realname "Integer Factorization Algorithms" - define IF_PUBLIC_KEY_FAMILY load_on dep diff --git a/src/pubkey/info.txt b/src/pubkey/info.txt index 63af86c47..13cac9ca0 100644 --- a/src/pubkey/info.txt +++ b/src/pubkey/info.txt @@ -1,5 +1,3 @@ -realname "Public Key Base" - define PUBLIC_KEY_CRYPTO load_on auto diff --git a/src/pubkey/keypair/info.txt b/src/pubkey/keypair/info.txt index 9e758643f..360d317c5 100644 --- a/src/pubkey/keypair/info.txt +++ b/src/pubkey/keypair/info.txt @@ -1,5 +1,3 @@ -realname "Keypair Testing" - define KEYPAIR_TESTING load_on auto diff --git a/src/pubkey/nr/info.txt b/src/pubkey/nr/info.txt index c89820aeb..dcf22033e 100644 --- a/src/pubkey/nr/info.txt +++ b/src/pubkey/nr/info.txt @@ -1,5 +1,3 @@ -realname "Nyberg-Rueppel" - define NYBERG_RUEPPEL load_on auto diff --git a/src/pubkey/pk_codecs/info.txt b/src/pubkey/pk_codecs/info.txt index 96511a663..55c71b0c9 100644 --- a/src/pubkey/pk_codecs/info.txt +++ b/src/pubkey/pk_codecs/info.txt @@ -1,5 +1,3 @@ -realname "PK codecs (PKCS8, X.509)" - load_on auto diff --git a/src/pubkey/rsa/info.txt b/src/pubkey/rsa/info.txt index 7729fd83d..c8bde68d0 100644 --- a/src/pubkey/rsa/info.txt +++ b/src/pubkey/rsa/info.txt @@ -1,5 +1,3 @@ -realname "RSA" - define RSA load_on auto diff --git a/src/pubkey/rw/info.txt b/src/pubkey/rw/info.txt index ada6c37d6..39857bccc 100644 --- a/src/pubkey/rw/info.txt +++ b/src/pubkey/rw/info.txt @@ -1,5 +1,3 @@ -realname "Rabin-Williams" - define RW load_on auto diff --git a/src/rng/auto_rng/info.txt b/src/rng/auto_rng/info.txt index 7d5d5ddcc..d5abfc757 100644 --- a/src/rng/auto_rng/info.txt +++ b/src/rng/auto_rng/info.txt @@ -1,5 +1,3 @@ -realname "Auto-seeded Random Number Generator" - define AUTO_SEEDING_RNG load_on auto diff --git a/src/rng/hmac_rng/info.txt b/src/rng/hmac_rng/info.txt index 2c7f13e0a..f6135ee5a 100644 --- a/src/rng/hmac_rng/info.txt +++ b/src/rng/hmac_rng/info.txt @@ -1,5 +1,3 @@ -realname "HMAC RNG" - define HMAC_RNG load_on auto diff --git a/src/rng/info.txt b/src/rng/info.txt index 44a41665d..eea122cf9 100644 --- a/src/rng/info.txt +++ b/src/rng/info.txt @@ -1,5 +1,3 @@ -realname "Random Number Generators" - load_on auto diff --git a/src/rng/randpool/info.txt b/src/rng/randpool/info.txt index cc7f61552..cab276e15 100644 --- a/src/rng/randpool/info.txt +++ b/src/rng/randpool/info.txt @@ -1,5 +1,3 @@ -realname "Randpool RNG" - define RANDPOOL load_on auto diff --git a/src/rng/x931_rng/info.txt b/src/rng/x931_rng/info.txt index 633eb0268..35836b33b 100644 --- a/src/rng/x931_rng/info.txt +++ b/src/rng/x931_rng/info.txt @@ -1,5 +1,3 @@ -realname "ANSI X9.31 PRNG" - define X931_RNG load_on auto diff --git a/src/s2k/info.txt b/src/s2k/info.txt index e603fd937..17f2a8c42 100644 --- a/src/s2k/info.txt +++ b/src/s2k/info.txt @@ -1,5 +1,3 @@ -realname "String to Key Functions" - load_on auto diff --git a/src/s2k/pbkdf1/info.txt b/src/s2k/pbkdf1/info.txt index 4c5b27546..387043f1b 100644 --- a/src/s2k/pbkdf1/info.txt +++ b/src/s2k/pbkdf1/info.txt @@ -1,5 +1,3 @@ -realname "Pbkdf1" - define PBKDF1 load_on auto diff --git a/src/s2k/pbkdf2/info.txt b/src/s2k/pbkdf2/info.txt index 921aeb1ab..56359d13d 100644 --- a/src/s2k/pbkdf2/info.txt +++ b/src/s2k/pbkdf2/info.txt @@ -1,5 +1,3 @@ -realname "Pbkdf2" - define PBKDF2 load_on auto diff --git a/src/s2k/pgps2k/info.txt b/src/s2k/pgps2k/info.txt index 14b75a02b..a1f5b3dfd 100644 --- a/src/s2k/pgps2k/info.txt +++ b/src/s2k/pgps2k/info.txt @@ -1,5 +1,3 @@ -realname "Pgps2k" - define PGPS2K load_on auto diff --git a/src/selftest/info.txt b/src/selftest/info.txt index c4b61bb99..079fd5030 100644 --- a/src/selftest/info.txt +++ b/src/selftest/info.txt @@ -1,5 +1,3 @@ -realname "Selftests" - define SELFTESTS load_on auto diff --git a/src/stream/arc4/info.txt b/src/stream/arc4/info.txt index e4689cf69..bb373dbc5 100644 --- a/src/stream/arc4/info.txt +++ b/src/stream/arc4/info.txt @@ -1,5 +1,3 @@ -realname "ARC4" - define ARC4 load_on auto diff --git a/src/stream/ctr/info.txt b/src/stream/ctr/info.txt index 04d14518a..ac4f3f710 100644 --- a/src/stream/ctr/info.txt +++ b/src/stream/ctr/info.txt @@ -1,5 +1,3 @@ -realname "CTR mode" - define CTR_BE load_on auto @@ -13,4 +11,3 @@ ctr.h block stream - diff --git a/src/stream/info.txt b/src/stream/info.txt index f8f4b22d5..213c42137 100644 --- a/src/stream/info.txt +++ b/src/stream/info.txt @@ -1,5 +1,3 @@ -realname "Stream Ciphers" - load_on auto define STREAM_CIPHER diff --git a/src/stream/ofb/info.txt b/src/stream/ofb/info.txt index 444fe0ffe..a01e9e1a6 100644 --- a/src/stream/ofb/info.txt +++ b/src/stream/ofb/info.txt @@ -1,5 +1,3 @@ -realname "OFB block cipher mode" - define OFB load_on auto diff --git a/src/stream/salsa20/info.txt b/src/stream/salsa20/info.txt index db938307b..8171708b0 100644 --- a/src/stream/salsa20/info.txt +++ b/src/stream/salsa20/info.txt @@ -1,5 +1,3 @@ -realname "Salsa20" - define SALSA20 load_on auto diff --git a/src/stream/turing/info.txt b/src/stream/turing/info.txt index c251a0a30..dede0dd39 100644 --- a/src/stream/turing/info.txt +++ b/src/stream/turing/info.txt @@ -1,5 +1,3 @@ -realname "Turing" - define TURING load_on auto diff --git a/src/stream/wid_wake/info.txt b/src/stream/wid_wake/info.txt index 94416417e..6289e0369 100644 --- a/src/stream/wid_wake/info.txt +++ b/src/stream/wid_wake/info.txt @@ -1,5 +1,3 @@ -realname "WiderWake" - define WID_WAKE load_on auto diff --git a/src/sym_algo/info.txt b/src/sym_algo/info.txt index 03804a92d..fab46270e 100644 --- a/src/sym_algo/info.txt +++ b/src/sym_algo/info.txt @@ -1,5 +1,3 @@ -realname "Symmetric Algorithms" - load_on auto diff --git a/src/timer/cpu_counter/info.txt b/src/timer/cpu_counter/info.txt index 025663a84..d95e0fec5 100644 --- a/src/timer/cpu_counter/info.txt +++ b/src/timer/cpu_counter/info.txt @@ -1,5 +1,3 @@ -realname "Hardware Timer" - define TIMER_HARDWARE load_on asm_ok diff --git a/src/timer/gettimeofday/info.txt b/src/timer/gettimeofday/info.txt index a58e8088d..f8b65b4ba 100644 --- a/src/timer/gettimeofday/info.txt +++ b/src/timer/gettimeofday/info.txt @@ -1,5 +1,3 @@ -realname "Unix Timer" - define TIMER_UNIX load_on auto @@ -30,4 +28,3 @@ tru64 timer - diff --git a/src/timer/info.txt b/src/timer/info.txt index 6408dca45..1dff5ab6f 100644 --- a/src/timer/info.txt +++ b/src/timer/info.txt @@ -1,5 +1,3 @@ -realname "Timer Base Class" - define TIMER load_on auto diff --git a/src/timer/posix_rt/info.txt b/src/timer/posix_rt/info.txt index fa530ea1a..4b23a74fc 100644 --- a/src/timer/posix_rt/info.txt +++ b/src/timer/posix_rt/info.txt @@ -1,5 +1,3 @@ -realname "POSIX Timer" - define TIMER_POSIX load_on auto @@ -26,4 +24,3 @@ dragonfly timer - diff --git a/src/timer/win32_query_perf_ctr/info.txt b/src/timer/win32_query_perf_ctr/info.txt index 4bb1ddb34..d8611027a 100644 --- a/src/timer/win32_query_perf_ctr/info.txt +++ b/src/timer/win32_query_perf_ctr/info.txt @@ -1,5 +1,3 @@ -realname "Win32 Timer" - define TIMER_WIN32 modset win32 @@ -23,4 +21,3 @@ windows -> user32.lib timer - diff --git a/src/tss/info.txt b/src/tss/info.txt index af4e0b930..11cc471d2 100644 --- a/src/tss/info.txt +++ b/src/tss/info.txt @@ -1,5 +1,3 @@ -realname "Threshold Secret Sharing" - hash rng diff --git a/src/utils/asm_amd64/info.txt b/src/utils/asm_amd64/info.txt index 6fa4d1de5..a5588669c 100644 --- a/src/utils/asm_amd64/info.txt +++ b/src/utils/asm_amd64/info.txt @@ -1,5 +1,3 @@ -realname "Assembler Macros (x86-64)" - load_on dep diff --git a/src/utils/asm_ia32/info.txt b/src/utils/asm_ia32/info.txt index 8485d33b9..63b57e0f8 100644 --- a/src/utils/asm_ia32/info.txt +++ b/src/utils/asm_ia32/info.txt @@ -1,5 +1,3 @@ -realname "Assembler Macros (IA-32)" - load_on dep diff --git a/src/utils/buf_comp/info.txt b/src/utils/buf_comp/info.txt index bcbbc23e2..7aea580ce 100644 --- a/src/utils/buf_comp/info.txt +++ b/src/utils/buf_comp/info.txt @@ -1,5 +1,3 @@ -realname "Buffered Computation" - load_on auto diff --git a/src/utils/datastor/info.txt b/src/utils/datastor/info.txt index 8c38a3ac8..9c995adaf 100644 --- a/src/utils/datastor/info.txt +++ b/src/utils/datastor/info.txt @@ -1,5 +1,3 @@ -realname "Datastore" - load_on auto diff --git a/src/utils/info.txt b/src/utils/info.txt index 6380fd6c2..3d024fa09 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -1,5 +1,3 @@ -realname "Utility Functions" - define UTIL_FUNCTIONS load_on always -- cgit v1.2.3 From ee169027c6cd30923aa30a735eb801836ee593d2 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 01:39:54 +0000 Subject: Hurd file was missing txt extension, must have missed it before? --- src/build-data/os/hurd | 16 ---------------- src/build-data/os/hurd.txt | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 16 deletions(-) delete mode 100644 src/build-data/os/hurd create mode 100644 src/build-data/os/hurd.txt (limited to 'src') diff --git a/src/build-data/os/hurd b/src/build-data/os/hurd deleted file mode 100644 index ed56dad75..000000000 --- a/src/build-data/os/hurd +++ /dev/null @@ -1,16 +0,0 @@ -realname "Hurd" - -os_type unix - - -posix_mlock - - -# Is this correct? - -all - - - -gnu - diff --git a/src/build-data/os/hurd.txt b/src/build-data/os/hurd.txt new file mode 100644 index 000000000..ed56dad75 --- /dev/null +++ b/src/build-data/os/hurd.txt @@ -0,0 +1,16 @@ +realname "Hurd" + +os_type unix + + +posix_mlock + + +# Is this correct? + +all + + + +gnu + -- cgit v1.2.3 From 1bc4d2fb37c8f1e6e94a65ec67062826393dda7f Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 01:40:43 +0000 Subject: Rename SSE2 stuff to be generally SIMD since it supports at least SSE2 and Altivec (though Altivec is seemingly slower ATM...) --- src/block/serpent_simd/info.txt | 9 + src/block/serpent_simd/serp_simd.cpp | 206 +++++++++++++++ src/block/serpent_simd/serp_simd.h | 29 +++ src/block/serpent_simd/serp_simd_sbox.h | 426 ++++++++++++++++++++++++++++++++ src/block/serpent_sse2/info.txt | 8 - src/block/serpent_sse2/serp_sse2.cpp | 206 --------------- src/block/serpent_sse2/serp_sse2.h | 29 --- src/block/serpent_sse2/serp_sse2_sbox.h | 426 -------------------------------- src/block/xtea_simd/info.txt | 16 ++ src/block/xtea_simd/xtea_simd.cpp | 124 ++++++++++ src/block/xtea_simd/xtea_simd.h | 28 +++ src/block/xtea_sse2/info.txt | 15 -- src/block/xtea_sse2/xtea_sse2.cpp | 124 ---------- src/block/xtea_sse2/xtea_sse2.h | 28 --- src/engine/simd_engine/info.txt | 5 + src/engine/simd_engine/simd_engine.cpp | 54 ++++ src/engine/simd_engine/simd_engine.h | 29 +++ src/engine/sse2_eng/eng_sse2.cpp | 60 ----- src/engine/sse2_eng/eng_sse2.h | 29 --- src/engine/sse2_eng/info.txt | 23 -- src/hash/sha1_sse2/info.txt | 15 +- src/libstate/libstate.cpp | 8 +- 22 files changed, 944 insertions(+), 953 deletions(-) create mode 100644 src/block/serpent_simd/info.txt create mode 100644 src/block/serpent_simd/serp_simd.cpp create mode 100644 src/block/serpent_simd/serp_simd.h create mode 100644 src/block/serpent_simd/serp_simd_sbox.h delete mode 100644 src/block/serpent_sse2/info.txt delete mode 100644 src/block/serpent_sse2/serp_sse2.cpp delete mode 100644 src/block/serpent_sse2/serp_sse2.h delete mode 100644 src/block/serpent_sse2/serp_sse2_sbox.h create mode 100644 src/block/xtea_simd/info.txt create mode 100644 src/block/xtea_simd/xtea_simd.cpp create mode 100644 src/block/xtea_simd/xtea_simd.h delete mode 100644 src/block/xtea_sse2/info.txt delete mode 100644 src/block/xtea_sse2/xtea_sse2.cpp delete mode 100644 src/block/xtea_sse2/xtea_sse2.h create mode 100644 src/engine/simd_engine/info.txt create mode 100644 src/engine/simd_engine/simd_engine.cpp create mode 100644 src/engine/simd_engine/simd_engine.h delete mode 100644 src/engine/sse2_eng/eng_sse2.cpp delete mode 100644 src/engine/sse2_eng/eng_sse2.h delete mode 100644 src/engine/sse2_eng/info.txt (limited to 'src') diff --git a/src/block/serpent_simd/info.txt b/src/block/serpent_simd/info.txt new file mode 100644 index 000000000..4ec5d0dfe --- /dev/null +++ b/src/block/serpent_simd/info.txt @@ -0,0 +1,9 @@ +realname "Serpent (SIMD)" + +define SERPENT_SIMD + + +serpent +simd_32 +simd_engine + 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 +#include +#include +#include + +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 + +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/serpent_sse2/info.txt b/src/block/serpent_sse2/info.txt deleted file mode 100644 index da7eef6bc..000000000 --- a/src/block/serpent_sse2/info.txt +++ /dev/null @@ -1,8 +0,0 @@ -realname "Serpent (SSE2)" - -define SERPENT_SSE2 - - -serpent -sse2_eng - diff --git a/src/block/serpent_sse2/serp_sse2.cpp b/src/block/serpent_sse2/serp_sse2.cpp deleted file mode 100644 index be79e870d..000000000 --- a/src/block/serpent_sse2/serp_sse2.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* -* Serpent (SIMD) -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include -#include - -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); - -/* -* SSE2 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); - } - -/* -* SSE2 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_SSE2::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_SSE2::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_sse2/serp_sse2.h b/src/block/serpent_sse2/serp_sse2.h deleted file mode 100644 index f1e5c2028..000000000 --- a/src/block/serpent_sse2/serp_sse2.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -* Serpent (SSE2) -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_SERPENT_SSE2_H__ -#define BOTAN_SERPENT_SSE2_H__ - -#include - -namespace Botan { - -/* -* Serpent -*/ -class BOTAN_DLL Serpent_SSE2 : 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_SSE2; } - }; - -} - -#endif diff --git a/src/block/serpent_sse2/serp_sse2_sbox.h b/src/block/serpent_sse2/serp_sse2_sbox.h deleted file mode 100644 index 6e3da7359..000000000 --- a/src/block/serpent_sse2/serp_sse2_sbox.h +++ /dev/null @@ -1,426 +0,0 @@ -/* -* 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/xtea_simd/info.txt b/src/block/xtea_simd/info.txt new file mode 100644 index 000000000..0cdce14ef --- /dev/null +++ b/src/block/xtea_simd/info.txt @@ -0,0 +1,16 @@ +realname "XTEA (SIMD)" + +define XTEA_SIMD + +load_on auto + + +xtea_simd.cpp +xtea_simd.h + + + +xtea +simd_32 +simd_engine + 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 +#include +#include + +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 + +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 diff --git a/src/block/xtea_sse2/info.txt b/src/block/xtea_sse2/info.txt deleted file mode 100644 index edcdd114d..000000000 --- a/src/block/xtea_sse2/info.txt +++ /dev/null @@ -1,15 +0,0 @@ -realname "XTEA (SSE2)" - -define XTEA_SSE2 - -load_on auto - - -xtea_sse2.cpp -xtea_sse2.h - - - -xtea -sse2_eng - diff --git a/src/block/xtea_sse2/xtea_sse2.cpp b/src/block/xtea_sse2/xtea_sse2.cpp deleted file mode 100644 index 5d9c7dd05..000000000 --- a/src/block/xtea_sse2/xtea_sse2.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* -* XTEA in SIMD -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include - -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_SSE2::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_SSE2::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_sse2/xtea_sse2.h b/src/block/xtea_sse2/xtea_sse2.h deleted file mode 100644 index e691e5c40..000000000 --- a/src/block/xtea_sse2/xtea_sse2.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -* XTEA in SSE2 -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_XTEA_SSE2_H__ -#define BOTAN_XTEA_SSE2_H__ - -#include - -namespace Botan { - -/* -* XTEA (SSE2 variant) -*/ -class BOTAN_DLL XTEA_SSE2 : 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_SSE2; } - }; - -} - -#endif diff --git a/src/engine/simd_engine/info.txt b/src/engine/simd_engine/info.txt new file mode 100644 index 000000000..b19664491 --- /dev/null +++ b/src/engine/simd_engine/info.txt @@ -0,0 +1,5 @@ +realname "SIMD Engine" + +define ENGINE_SIMD + +load_on dep diff --git a/src/engine/simd_engine/simd_engine.cpp b/src/engine/simd_engine/simd_engine.cpp new file mode 100644 index 000000000..7e15f9ec1 --- /dev/null +++ b/src/engine/simd_engine/simd_engine.cpp @@ -0,0 +1,54 @@ +/** +* SIMD Engine +* (C) 1999-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include + +#if defined(BOTAN_HAS_SERPENT_SIMD) + #include +#endif + +#if defined(BOTAN_HAS_XTEA_SIMD) + #include +#endif + +#if defined(BOTAN_HAS_SHA1_SSE2) + #include +#endif + +namespace Botan { + +BlockCipher* +SIMD_Engine::find_block_cipher(const SCAN_Name& request, + Algorithm_Factory&) const + { +#if defined(BOTAN_HAS_SERPENT_SIMD) + if(request.algo_name() == "Serpent") + return new Serpent_SIMD; +#endif + +#if defined(BOTAN_HAS_XTEA_SIMD) + if(request.algo_name() == "XTEA") + return new XTEA_SIMD; +#endif + + return 0; + } + +HashFunction* +SIMD_Engine::find_hash(const SCAN_Name& request, + Algorithm_Factory&) const + { +#if defined(BOTAN_HAS_SHA1_SSE2) + if(request.algo_name() == "SHA-160" && CPUID::has_sse2()) + return new SHA_160_SSE2; +#endif + + return 0; + } + +} diff --git a/src/engine/simd_engine/simd_engine.h b/src/engine/simd_engine/simd_engine.h new file mode 100644 index 000000000..f7df6ff77 --- /dev/null +++ b/src/engine/simd_engine/simd_engine.h @@ -0,0 +1,29 @@ +/** +* SIMD Assembly Engine +* (C) 1999-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SIMD_ENGINE_H__ +#define BOTAN_SIMD_ENGINE_H__ + +#include + +namespace Botan { + +class BOTAN_DLL SIMD_Engine : public Engine + { + public: + std::string provider_name() const { return "sse2"; } + private: + BlockCipher* find_block_cipher(const SCAN_Name&, + Algorithm_Factory&) const; + + HashFunction* find_hash(const SCAN_Name& reqeust, + Algorithm_Factory&) const; + }; + +} + +#endif diff --git a/src/engine/sse2_eng/eng_sse2.cpp b/src/engine/sse2_eng/eng_sse2.cpp deleted file mode 100644 index 51b7d04e3..000000000 --- a/src/engine/sse2_eng/eng_sse2.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/** -* SSE2 Assembly Engine -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -#if defined(BOTAN_HAS_SHA1_SSE2) - #include -#endif - -#if defined(BOTAN_HAS_SERPENT_SSE2) - #include -#endif - -#if defined(BOTAN_HAS_XTEA_SSE2) - #include -#endif - -namespace Botan { - -BlockCipher* -SSE2_Assembler_Engine::find_block_cipher(const SCAN_Name& request, - Algorithm_Factory&) const - { - if(!CPUID::has_sse2()) - return 0; - -#if defined(BOTAN_HAS_SERPENT_SSE2) - if(request.algo_name() == "Serpent") - return new Serpent_SSE2; -#endif - -#if defined(BOTAN_HAS_XTEA_SSE2) - if(request.algo_name() == "XTEA") - return new XTEA_SSE2; -#endif - - return 0; - } - -HashFunction* -SSE2_Assembler_Engine::find_hash(const SCAN_Name& request, - Algorithm_Factory&) const - { - if(!CPUID::has_sse2()) - return 0; - -#if defined(BOTAN_HAS_SHA1_SSE2) - if(request.algo_name() == "SHA-160") - return new SHA_160_SSE2; -#endif - - return 0; - } - -} diff --git a/src/engine/sse2_eng/eng_sse2.h b/src/engine/sse2_eng/eng_sse2.h deleted file mode 100644 index c6b0ce889..000000000 --- a/src/engine/sse2_eng/eng_sse2.h +++ /dev/null @@ -1,29 +0,0 @@ -/** -* SSE2 Assembly Engine -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_SSE2_ASM_ENGINE_H__ -#define BOTAN_SSE2_ASM_ENGINE_H__ - -#include - -namespace Botan { - -class BOTAN_DLL SSE2_Assembler_Engine : public Engine - { - public: - std::string provider_name() const { return "sse2"; } - private: - BlockCipher* find_block_cipher(const SCAN_Name&, - Algorithm_Factory&) const; - - HashFunction* find_hash(const SCAN_Name& reqeust, - Algorithm_Factory&) const; - }; - -} - -#endif diff --git a/src/engine/sse2_eng/info.txt b/src/engine/sse2_eng/info.txt deleted file mode 100644 index 7508b9874..000000000 --- a/src/engine/sse2_eng/info.txt +++ /dev/null @@ -1,23 +0,0 @@ -realname "SSE2 Assembler Engine" - -define ENGINE_SSE2_ASSEMBLER - -load_on dep - - -eng_sse2.cpp -eng_sse2.h - - - -pentium-m -pentium4 -prescott -amd64 - - - -gcc -icc -msvc - diff --git a/src/hash/sha1_sse2/info.txt b/src/hash/sha1_sse2/info.txt index 4a7a1b5e9..a5a5200cf 100644 --- a/src/hash/sha1_sse2/info.txt +++ b/src/hash/sha1_sse2/info.txt @@ -4,5 +4,18 @@ define SHA1_SSE2 sha1 -sse2_eng +simd_engine + + +pentium-m +pentium4 +prescott +amd64 + + + +gcc +icc +msvc + diff --git a/src/libstate/libstate.cpp b/src/libstate/libstate.cpp index ca454458b..c78bce62d 100644 --- a/src/libstate/libstate.cpp +++ b/src/libstate/libstate.cpp @@ -37,8 +37,8 @@ #include #endif -#if defined(BOTAN_HAS_ENGINE_SSE2_ASSEMBLER) - #include +#if defined(BOTAN_HAS_ENGINE_SIMD) + #include #endif #if defined(BOTAN_HAS_ENGINE_GNU_MP) @@ -288,8 +288,8 @@ void Library_State::initialize(bool thread_safe) engines.push_back(new OpenSSL_Engine); #endif -#if defined(BOTAN_HAS_ENGINE_SSE2_ASSEMBLER) - engines.push_back(new SSE2_Assembler_Engine); +#if defined(BOTAN_HAS_ENGINE_SIMD) + engines.push_back(new SIMD_Engine); #endif #if defined(BOTAN_HAS_ENGINE_AMD64_ASSEMBLER) -- cgit v1.2.3 From f14c48a80cdbd2d134bf706c631018bf683e44d9 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 01:42:20 +0000 Subject: Kill straggling realnames --- src/build-data/os/hurd.txt | 2 -- src/codec/zlib/info.txt | 2 -- 2 files changed, 4 deletions(-) (limited to 'src') diff --git a/src/build-data/os/hurd.txt b/src/build-data/os/hurd.txt index ed56dad75..f0ab18a98 100644 --- a/src/build-data/os/hurd.txt +++ b/src/build-data/os/hurd.txt @@ -1,5 +1,3 @@ -realname "Hurd" - os_type unix diff --git a/src/codec/zlib/info.txt b/src/codec/zlib/info.txt index 267c3be92..6556359a8 100644 --- a/src/codec/zlib/info.txt +++ b/src/codec/zlib/info.txt @@ -1,5 +1,3 @@ -#realname "Zlib/Gzip Compressor" - define COMPRESSOR_ZLIB #define COMPRESSOR_ZLIB,COMPRESSOR_GZIP -- cgit v1.2.3 From ec71a46cfe5e4f975ec2ff5936809983a47849c8 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 01:42:56 +0000 Subject: Kill realnames on new modules not in mailine --- src/block/serpent_simd/info.txt | 1 - src/block/xtea_simd/info.txt | 2 -- src/utils/simd_32/info.txt | 2 -- 3 files changed, 5 deletions(-) (limited to 'src') diff --git a/src/block/serpent_simd/info.txt b/src/block/serpent_simd/info.txt index 5d9115a4d..d65b41235 100644 --- a/src/block/serpent_simd/info.txt +++ b/src/block/serpent_simd/info.txt @@ -1,4 +1,3 @@ -realname "Serpent (SIMD)" define SERPENT_SIMD diff --git a/src/block/xtea_simd/info.txt b/src/block/xtea_simd/info.txt index 0cdce14ef..98a6e941f 100644 --- a/src/block/xtea_simd/info.txt +++ b/src/block/xtea_simd/info.txt @@ -1,5 +1,3 @@ -realname "XTEA (SIMD)" - define XTEA_SIMD load_on auto diff --git a/src/utils/simd_32/info.txt b/src/utils/simd_32/info.txt index c72f2a6ed..64707c1e4 100644 --- a/src/utils/simd_32/info.txt +++ b/src/utils/simd_32/info.txt @@ -1,5 +1,3 @@ -realname "SIMD" - define SIMD_32 load_on always -- cgit v1.2.3 From e9cb78ddb6ad81e562fd466481b8d93e5144e7a6 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 02:04:05 +0000 Subject: Use register writes in the Altivec code for stores because Altivec's handling for unaligned writes is messy as hell. If writes are batched this is somewhat easier to deal with (somewhat). --- src/utils/simd_32/simd_altivec.h | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/utils/simd_32/simd_altivec.h b/src/utils/simd_32/simd_altivec.h index a925f6dbc..e63b9bdcc 100644 --- a/src/utils/simd_32/simd_altivec.h +++ b/src/utils/simd_32/simd_altivec.h @@ -65,21 +65,30 @@ class SIMD_Altivec void store_le(byte out[]) const { - u32bit* out_32 = reinterpret_cast(out); - - __vector unsigned char perm = vec_lvsl(0, (int*)0); + __vector unsigned char perm = vec_lvsl(0, (u32bit*)0); perm = vec_xor(perm, vec_splat_u8(3)); - __vector unsigned int swapped = vec_perm(reg, reg, perm); + union { + __vector unsigned int V; + u32bit R[4]; + } vec; + + vec.V = vec_perm(reg, reg, perm); - vec_st(swapped, 0, out_32); + Botan::store_be(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]); } void store_be(byte out[]) const { - u32bit* out_32 = reinterpret_cast(out); - vec_st(reg, 0, out_32); + union { + __vector unsigned int V; + u32bit R[4]; + } vec; + + vec.V = reg; + + Botan::store_be(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]); } void rotate_left(u32bit rot) -- cgit v1.2.3 From d5412353bec03ae91d69286ee53369cd9588dcda Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 02:07:39 +0000 Subject: Rename sse2 engine to simd --- src/algo_factory/prov_weight.cpp | 2 +- src/engine/simd_engine/simd_engine.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/algo_factory/prov_weight.cpp b/src/algo_factory/prov_weight.cpp index a55a8b1e6..d7e84a323 100644 --- a/src/algo_factory/prov_weight.cpp +++ b/src/algo_factory/prov_weight.cpp @@ -22,7 +22,7 @@ u32bit static_provider_weight(const std::string& prov_name) if(prov_name == "core") return 5; if(prov_name == "ia32") return 6; if(prov_name == "amd64") return 7; - if(prov_name == "sse2") return 8; + if(prov_name == "simd") return 8; if(prov_name == "openssl") return 2; if(prov_name == "gmp") return 1; diff --git a/src/engine/simd_engine/simd_engine.h b/src/engine/simd_engine/simd_engine.h index f7df6ff77..22a58e203 100644 --- a/src/engine/simd_engine/simd_engine.h +++ b/src/engine/simd_engine/simd_engine.h @@ -15,7 +15,7 @@ namespace Botan { class BOTAN_DLL SIMD_Engine : public Engine { public: - std::string provider_name() const { return "sse2"; } + std::string provider_name() const { return "simd"; } private: BlockCipher* find_block_cipher(const SCAN_Name&, Algorithm_Factory&) const; -- cgit v1.2.3 From 9b35547f5862ac2d34573d7421eb8be05c6064ae Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 04:17:35 +0000 Subject: Add CPUID::have_altivec for AltiVec runtime detection. Relies on mfspr emulation/trapping by the kernel, which works on (at least) Linux and NetBSD. --- doc/examples/cpuid.cpp | 2 ++ src/utils/cpuid.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/utils/cpuid.h | 1 + 3 files changed, 63 insertions(+) (limited to 'src') diff --git a/doc/examples/cpuid.cpp b/doc/examples/cpuid.cpp index 59940b500..1bdee787c 100644 --- a/doc/examples/cpuid.cpp +++ b/doc/examples/cpuid.cpp @@ -12,4 +12,6 @@ int main() printf("SSSE3 %d\n", CPUID::has_ssse3()); printf("SSE41 %d\n", CPUID::has_sse41()); printf("SSE42 %d\n", CPUID::has_sse42()); + + printf("AltiVec %d\n", CPUID::has_altivec()); } diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index f79e3a912..298caf078 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -98,4 +98,64 @@ u32bit CPUID::cache_line_size() return cl_size; } +bool CPUID::has_altivec() + { + static bool first_time = true; + static bool altivec_capable = false; + + if(first_time) + { +#if defined(BOTAN_TARGET_ARCH_IS_PPC) || defined(BOTAN_TARGET_ARCH_IS_PPC64) + + /* + PVR identifiers for various AltiVec enabled CPUs. Taken from + PearPC and Linux sources, mostly. + */ + const u16bit PVR_G4_7400 = 0x000C; + const u16bit PVR_G5_970 = 0x0039; + const u16bit PVR_G5_970FX = 0x003C; + const u16bit PVR_G5_970MP = 0x0044; + const u16bit PVR_G5_970GX = 0x0045; + const u16bit PVR_POWER6 = 0x003E; + const u16bit PVR_CELL_PPU = 0x0070; + + // Motorola produced G4s with PVR 0x800[0123C] (at least) + const u16bit PVR_G4_74xx_24 = 0x800; + + u32bit pvr = 0; + /* + On PowerPC, MSR 287 is PVR, the Processor Version Number + + Normally it is only accessible to ring 0, but Linux and NetBSD + (at least) will trap and emulate it for us. This is roughly 20x + saner than every other approach I've seen for this (all of which + are entirely OS specific, to boot). + + Apparently OS X doesn't support this, but then again OS X + doesn't really support PPC anymore, so I'm not worrying about it. + + For OSes that aren't (known to) support the emulation, leave pvr + as 0 which will cause all subsequent model number checks to fail. + */ +#if defined(BOTAN_TARGET_OS_IS_LINUX) || defined(BOTAN_TARGET_OS_IS_NETBSD) + asm volatile("mfspr %0, 287" : "=r" (pvr)); +#endif + // Top 16 bit suffice to identify model + pvr >>= 16; + + altivec_capable ||= (pvr == PVR_G4_7400); + altivec_capable ||= ((pvr >> 8) == PVR_G4_74xx_24); + altivec_capable ||= (pvr == PVR_G5_970); + altivec_capable ||= (pvr == PVR_G5_970FX); + altivec_capable ||= (pvr == PVR_G5_970MP); + altivec_capable ||= (pvr == PVR_G5_970GX); + altivec_capable ||= (pvr == PVR_CELL_PPU); +#endif + + first_time = false; + } + + return altivec_capable; + } + } diff --git a/src/utils/cpuid.h b/src/utils/cpuid.h index 0b210768a..8b8021754 100644 --- a/src/utils/cpuid.h +++ b/src/utils/cpuid.h @@ -65,6 +65,7 @@ class CPUID static bool has_intel_aes() { return ((x86_processor_flags() >> CPUID_INTEL_AES_BIT) & 1); } + static bool has_altivec(); private: static u64bit x86_processor_flags(); }; -- cgit v1.2.3 From 053ee3cc52a44a450001eb9b1f907ce91fad39f9 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 04:34:27 +0000 Subject: No ||= operator! --- src/utils/cpuid.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index 298caf078..2d3b5d92c 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -143,13 +143,13 @@ bool CPUID::has_altivec() // Top 16 bit suffice to identify model pvr >>= 16; - altivec_capable ||= (pvr == PVR_G4_7400); - altivec_capable ||= ((pvr >> 8) == PVR_G4_74xx_24); - altivec_capable ||= (pvr == PVR_G5_970); - altivec_capable ||= (pvr == PVR_G5_970FX); - altivec_capable ||= (pvr == PVR_G5_970MP); - altivec_capable ||= (pvr == PVR_G5_970GX); - altivec_capable ||= (pvr == PVR_CELL_PPU); + altivec_capable |= (pvr == PVR_G4_7400); + altivec_capable |= ((pvr >> 8) == PVR_G4_74xx_24); + altivec_capable |= (pvr == PVR_G5_970); + altivec_capable |= (pvr == PVR_G5_970FX); + altivec_capable |= (pvr == PVR_G5_970MP); + altivec_capable |= (pvr == PVR_G5_970GX); + altivec_capable |= (pvr == PVR_CELL_PPU); #endif first_time = false; -- cgit v1.2.3 From 511f670f32f920ace6352c4216a4a124dc9b01ac Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 04:40:49 +0000 Subject: Add new function enabled() to each of the SIMD_32 instantiations which returns true if they might plausibly work. AltiVec and SSE2 versions call into CPUID, scalar version always works. --- src/utils/simd_32/simd_altivec.h | 3 +++ src/utils/simd_32/simd_scalar.h | 2 ++ src/utils/simd_32/simd_sse.h | 5 ++++- 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/utils/simd_32/simd_altivec.h b/src/utils/simd_32/simd_altivec.h index e63b9bdcc..c3d1a76dc 100644 --- a/src/utils/simd_32/simd_altivec.h +++ b/src/utils/simd_32/simd_altivec.h @@ -9,6 +9,8 @@ #define BOTAN_SIMD_ALTIVEC_H__ #include +#include + #include #undef vector @@ -17,6 +19,7 @@ namespace Botan { class SIMD_Altivec { public: + bool enabled() const { return CPUID::has_altivec(); } SIMD_Altivec(const u32bit B[4]) { diff --git a/src/utils/simd_32/simd_scalar.h b/src/utils/simd_32/simd_scalar.h index 38f69c294..606923289 100644 --- a/src/utils/simd_32/simd_scalar.h +++ b/src/utils/simd_32/simd_scalar.h @@ -15,6 +15,8 @@ namespace Botan { class SIMD_Scalar { public: + bool enabled() const { return true; } + SIMD_Scalar(const u32bit B[4]) { R0 = B[0]; diff --git a/src/utils/simd_32/simd_sse.h b/src/utils/simd_32/simd_sse.h index 267852554..fcfe6f203 100644 --- a/src/utils/simd_32/simd_sse.h +++ b/src/utils/simd_32/simd_sse.h @@ -8,7 +8,8 @@ #ifndef BOTAN_SIMD_SSE_H__ #define BOTAN_SIMD_SSE_H__ -#include +#include + #include namespace Botan { @@ -16,6 +17,8 @@ namespace Botan { class SIMD_SSE2 { public: + bool enabled() const { return CPUID::has_sse2(); } + SIMD_SSE2(const u32bit B[4]) { reg = _mm_loadu_si128((const __m128i*)B); -- cgit v1.2.3 From 1cb38d792c7784133f0c022f09c33d02098c9291 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 04:57:59 +0000 Subject: Give each version of SIMD_32 a public bswap() --- src/utils/simd_32/simd_altivec.h | 9 +++++++++ src/utils/simd_32/simd_scalar.h | 9 +++++++++ src/utils/simd_32/simd_sse.h | 22 +++++++++++----------- 3 files changed, 29 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/utils/simd_32/simd_altivec.h b/src/utils/simd_32/simd_altivec.h index c3d1a76dc..e1aa62002 100644 --- a/src/utils/simd_32/simd_altivec.h +++ b/src/utils/simd_32/simd_altivec.h @@ -168,6 +168,15 @@ class SIMD_Altivec return vec_nor(reg, reg); } + SIMD_Altivec bswap() const + { + __vector unsigned char perm = vec_lvsl(0, (u32bit*)0); + + perm = vec_xor(perm, vec_splat_u8(3)); + + return SIMD_Altivec(vec_perm(reg, reg, perm)); + } + static void transpose(SIMD_Altivec& B0, SIMD_Altivec& B1, SIMD_Altivec& B2, SIMD_Altivec& B3) { diff --git a/src/utils/simd_32/simd_scalar.h b/src/utils/simd_32/simd_scalar.h index 606923289..5fc20b462 100644 --- a/src/utils/simd_32/simd_scalar.h +++ b/src/utils/simd_32/simd_scalar.h @@ -9,6 +9,7 @@ #define BOTAN_SIMD_SCALAR_H__ #include +#include namespace Botan { @@ -170,6 +171,14 @@ class SIMD_Scalar return SIMD_Scalar(~R0, ~R1, ~R2, ~R3); } + SIMD_Scalar bswap() const + { + return SIMD_Scalar(reverse_bytes(R0), + reverse_bytes(R1), + reverse_bytes(R2), + reverse_bytes(R3)); + } + static void transpose(SIMD_Scalar& B0, SIMD_Scalar& B1, SIMD_Scalar& B2, SIMD_Scalar& B3) { diff --git a/src/utils/simd_32/simd_sse.h b/src/utils/simd_32/simd_sse.h index fcfe6f203..c45d8032f 100644 --- a/src/utils/simd_32/simd_sse.h +++ b/src/utils/simd_32/simd_sse.h @@ -121,6 +121,17 @@ class SIMD_SSE2 return _mm_xor_si128(reg, all_ones); } + SIMD_SSE2 bswap() const + { + __m128i T = reg; + + T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); + T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); + + return _mm_or_si128(_mm_srli_epi16(T, 8), + _mm_slli_epi16(T, 8)); + } + static void transpose(SIMD_SSE2& B0, SIMD_SSE2& B1, SIMD_SSE2& B2, SIMD_SSE2& B3) { @@ -137,17 +148,6 @@ class SIMD_SSE2 private: SIMD_SSE2(__m128i in) { reg = in; } - SIMD_SSE2 bswap() const - { - __m128i T = reg; - - T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); - T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); - - return _mm_or_si128(_mm_srli_epi16(T, 8), - _mm_slli_epi16(T, 8)); - } - __m128i reg; }; -- cgit v1.2.3 From f46d52238ff12b45b37f91c257b7c39ab067dc18 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 05:46:19 +0000 Subject: Small cleanups (remove tab characters, change macros to fit the rest of the code stylistically, etc) --- src/hash/sha1_sse2/sha1_sse2_imp.cpp | 244 +++++++++++++++++------------------ 1 file changed, 121 insertions(+), 123 deletions(-) (limited to 'src') diff --git a/src/hash/sha1_sse2/sha1_sse2_imp.cpp b/src/hash/sha1_sse2/sha1_sse2_imp.cpp index 5ee222cca..f561cb1c8 100644 --- a/src/hash/sha1_sse2/sha1_sse2_imp.cpp +++ b/src/hash/sha1_sse2/sha1_sse2_imp.cpp @@ -36,18 +36,17 @@ prepared points to 4x u32bit, 16-byte aligned W points to the 4 dwords which need preparing -- and is overwritten with the swapped bytes */ -#define prep00_15(prep, W) do { \ - __m128i r1, r2; \ - \ - r1 = (W); \ - r1 = _mm_shufflehi_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ - r1 = _mm_shufflelo_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ - r2 = _mm_slli_epi16(r1, 8); \ - r1 = _mm_srli_epi16(r1, 8); \ - r1 = _mm_or_si128(r1, r2); \ - (W) = r1; \ - (prep).u128 = _mm_add_epi32(K00_19.u128, r1); \ - } while(0) +#define prep00_15(prep, W) \ + do { \ + __m128i r1 = (W); \ + r1 = _mm_shufflehi_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ + r1 = _mm_shufflelo_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ + __m128i r2 = _mm_slli_epi16(r1, 8); \ + r1 = _mm_srli_epi16(r1, 8); \ + r1 = _mm_or_si128(r1, r2); \ + (W) = r1; \ + (prep).u128 = _mm_add_epi32(K00_19.u128, r1); \ + } while(0) /* for each multiple of 4, t, we want to calculate this: @@ -96,14 +95,14 @@ W0 = W[t]..W[t+3] */ #define prep(prep, XW0, XW1, XW2, XW3, K) \ do { \ - __m128i r0, r1, r2, r3; \ + __m128i r0, r1, r2, r3; \ \ /* load W[t-4] 16-byte aligned, and shift */ \ - r3 = _mm_srli_si128((XW3), 4); \ + r3 = _mm_srli_si128((XW3), 4); \ r0 = (XW0); \ - /* get high 64-bits of XW0 into low 64-bits */ \ + /* get high 64-bits of XW0 into low 64-bits */ \ r1 = _mm_shuffle_epi32((XW0), _MM_SHUFFLE(1,0,3,2)); \ - /* load high 64-bits of r1 */ \ + /* load high 64-bits of r1 */ \ r1 = _mm_unpacklo_epi64(r1, (XW1)); \ r2 = (XW2); \ \ @@ -113,15 +112,15 @@ W0 = W[t]..W[t+3] /* unrotated W[t]..W[t+2] in r0 ... still need W[t+3] */ \ \ r2 = _mm_slli_si128(r0, 12); \ - r1 = _mm_cmplt_epi32(r0, _mm_setzero_si128()); \ - r0 = _mm_add_epi32(r0, r0); /* shift left by 1 */ \ - r0 = _mm_sub_epi32(r0, r1); /* r0 has W[t]..W[t+2] */ \ + r1 = _mm_cmplt_epi32(r0, _mm_setzero_si128()); \ + r0 = _mm_add_epi32(r0, r0); /* shift left by 1 */ \ + r0 = _mm_sub_epi32(r0, r1); /* r0 has W[t]..W[t+2] */ \ \ r3 = _mm_srli_epi32(r2, 30); \ r2 = _mm_slli_epi32(r2, 2); \ \ r0 = _mm_xor_si128(r0, r3); \ - r0 = _mm_xor_si128(r0, r2); /* r0 now has W[t+3] */ \ + r0 = _mm_xor_si128(r0, r2); /* r0 now has W[t+3] */ \ \ (XW0) = r0; \ (prep).u128 = _mm_add_epi32(r0, (K).u128); \ @@ -135,13 +134,11 @@ static inline u32bit f00_19(u32bit x, u32bit y, u32bit z) return ((y ^ z) & x) ^ z; } - static inline u32bit f20_39(u32bit x, u32bit y, u32bit z) { return (x ^ z) ^ y; } - static inline u32bit f40_59(u32bit x, u32bit y, u32bit z) { /* FIPS 180-2 says this: (x & y) ^ (x & z) ^ (y & z) @@ -150,7 +147,6 @@ static inline u32bit f40_59(u32bit x, u32bit y, u32bit z) return (x & z) | ((x | z) & y); } - static inline u32bit f60_79(u32bit x, u32bit y, u32bit z) { return f20_39(x, y, z); @@ -158,7 +154,7 @@ static inline u32bit f60_79(u32bit x, u32bit y, u32bit z) #define step(nn_mm, xa, xb, xc, xd, xe, xt, input) \ do { \ - (xt) = (input) + f##nn_mm((xb), (xc), (xd)); \ + (xt) = (input) + f##nn_mm((xb), (xc), (xd)); \ (xb) = rotate_left((xb), 30); \ (xt) += ((xe) + rotate_left((xa), 5)); \ } while(0) @@ -169,130 +165,132 @@ extern "C" void botan_sha1_sse2_compress(u32bit H[5], const u32bit* inputu) { const __m128i * input = (const __m128i *)inputu; - __m128i W0, W1, W2, W3; - v4si prep0, prep1, prep2; - u32bit a, b, c, d, e, t; - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; + u32bit a = H[0]; + u32bit b = H[1]; + u32bit c = H[2]; + u32bit d = H[3]; + u32bit e = H[4]; + u32bit t = 0; /* i've tried arranging the SSE2 code to be 4, 8, 12, and 16 * steps ahead of the integer code. 12 steps ahead seems * to produce the best performance. -dean */ - W0 = _mm_loadu_si128(&input[0]); - prep00_15(prep0, W0); /* prepare for 00 through 03 */ - W1 = _mm_loadu_si128(&input[1]); - prep00_15(prep1, W1); /* prepare for 04 through 07 */ - W2 = _mm_loadu_si128(&input[2]); - prep00_15(prep2, W2); /* prepare for 08 through 11 */ - - W3 = _mm_loadu_si128(&input[3]); - step(00_19, a, b, c, d, e, t, prep0.u32[0]); /* 00 */ - step(00_19, t, a, b, c, d, e, prep0.u32[1]); /* 01 */ - step(00_19, e, t, a, b, c, d, prep0.u32[2]); /* 02 */ - step(00_19, d, e, t, a, b, c, prep0.u32[3]); /* 03 */ + v4si prep0, prep1, prep2; + + __m128i W0 = _mm_loadu_si128(&input[0]); + prep00_15(prep0, W0); /* prepare for 00 through 03 */ + + __m128i W1 = _mm_loadu_si128(&input[1]); + prep00_15(prep1, W1); /* prepare for 04 through 07 */ + + __m128i W2 = _mm_loadu_si128(&input[2]); + prep00_15(prep2, W2); /* prepare for 08 through 11 */ + + __m128i W3 = _mm_loadu_si128(&input[3]); + step(00_19, a, b, c, d, e, t, prep0.u32[0]); /* 00 */ + step(00_19, t, a, b, c, d, e, prep0.u32[1]); /* 01 */ + step(00_19, e, t, a, b, c, d, prep0.u32[2]); /* 02 */ + step(00_19, d, e, t, a, b, c, prep0.u32[3]); /* 03 */ prep00_15(prep0, W3); - step(00_19, c, d, e, t, a, b, prep1.u32[0]); /* 04 */ - step(00_19, b, c, d, e, t, a, prep1.u32[1]); /* 05 */ - step(00_19, a, b, c, d, e, t, prep1.u32[2]); /* 06 */ - step(00_19, t, a, b, c, d, e, prep1.u32[3]); /* 07 */ - prep(prep1, W0, W1, W2, W3, K00_19); /* prepare for 16 through 19 */ - step(00_19, e, t, a, b, c, d, prep2.u32[0]); /* 08 */ - step(00_19, d, e, t, a, b, c, prep2.u32[1]); /* 09 */ - step(00_19, c, d, e, t, a, b, prep2.u32[2]); /* 10 */ - step(00_19, b, c, d, e, t, a, prep2.u32[3]); /* 11 */ - prep(prep2, W1, W2, W3, W0, K20_39); /* prepare for 20 through 23 */ - step(00_19, a, b, c, d, e, t, prep0.u32[0]); /* 12 */ - step(00_19, t, a, b, c, d, e, prep0.u32[1]); /* 13 */ - step(00_19, e, t, a, b, c, d, prep0.u32[2]); /* 14 */ - step(00_19, d, e, t, a, b, c, prep0.u32[3]); /* 15 */ + step(00_19, c, d, e, t, a, b, prep1.u32[0]); /* 04 */ + step(00_19, b, c, d, e, t, a, prep1.u32[1]); /* 05 */ + step(00_19, a, b, c, d, e, t, prep1.u32[2]); /* 06 */ + step(00_19, t, a, b, c, d, e, prep1.u32[3]); /* 07 */ + prep(prep1, W0, W1, W2, W3, K00_19); /* prepare for 16 through 19 */ + step(00_19, e, t, a, b, c, d, prep2.u32[0]); /* 08 */ + step(00_19, d, e, t, a, b, c, prep2.u32[1]); /* 09 */ + step(00_19, c, d, e, t, a, b, prep2.u32[2]); /* 10 */ + step(00_19, b, c, d, e, t, a, prep2.u32[3]); /* 11 */ + prep(prep2, W1, W2, W3, W0, K20_39); /* prepare for 20 through 23 */ + step(00_19, a, b, c, d, e, t, prep0.u32[0]); /* 12 */ + step(00_19, t, a, b, c, d, e, prep0.u32[1]); /* 13 */ + step(00_19, e, t, a, b, c, d, prep0.u32[2]); /* 14 */ + step(00_19, d, e, t, a, b, c, prep0.u32[3]); /* 15 */ prep(prep0, W2, W3, W0, W1, K20_39); - step(00_19, c, d, e, t, a, b, prep1.u32[0]); /* 16 */ - step(00_19, b, c, d, e, t, a, prep1.u32[1]); /* 17 */ - step(00_19, a, b, c, d, e, t, prep1.u32[2]); /* 18 */ - step(00_19, t, a, b, c, d, e, prep1.u32[3]); /* 19 */ + step(00_19, c, d, e, t, a, b, prep1.u32[0]); /* 16 */ + step(00_19, b, c, d, e, t, a, prep1.u32[1]); /* 17 */ + step(00_19, a, b, c, d, e, t, prep1.u32[2]); /* 18 */ + step(00_19, t, a, b, c, d, e, prep1.u32[3]); /* 19 */ prep(prep1, W3, W0, W1, W2, K20_39); - step(20_39, e, t, a, b, c, d, prep2.u32[0]); /* 20 */ - step(20_39, d, e, t, a, b, c, prep2.u32[1]); /* 21 */ - step(20_39, c, d, e, t, a, b, prep2.u32[2]); /* 22 */ - step(20_39, b, c, d, e, t, a, prep2.u32[3]); /* 23 */ + step(20_39, e, t, a, b, c, d, prep2.u32[0]); /* 20 */ + step(20_39, d, e, t, a, b, c, prep2.u32[1]); /* 21 */ + step(20_39, c, d, e, t, a, b, prep2.u32[2]); /* 22 */ + step(20_39, b, c, d, e, t, a, prep2.u32[3]); /* 23 */ prep(prep2, W0, W1, W2, W3, K20_39); - step(20_39, a, b, c, d, e, t, prep0.u32[0]); /* 24 */ - step(20_39, t, a, b, c, d, e, prep0.u32[1]); /* 25 */ - step(20_39, e, t, a, b, c, d, prep0.u32[2]); /* 26 */ - step(20_39, d, e, t, a, b, c, prep0.u32[3]); /* 27 */ + step(20_39, a, b, c, d, e, t, prep0.u32[0]); /* 24 */ + step(20_39, t, a, b, c, d, e, prep0.u32[1]); /* 25 */ + step(20_39, e, t, a, b, c, d, prep0.u32[2]); /* 26 */ + step(20_39, d, e, t, a, b, c, prep0.u32[3]); /* 27 */ prep(prep0, W1, W2, W3, W0, K20_39); - step(20_39, c, d, e, t, a, b, prep1.u32[0]); /* 28 */ - step(20_39, b, c, d, e, t, a, prep1.u32[1]); /* 29 */ - step(20_39, a, b, c, d, e, t, prep1.u32[2]); /* 30 */ - step(20_39, t, a, b, c, d, e, prep1.u32[3]); /* 31 */ + step(20_39, c, d, e, t, a, b, prep1.u32[0]); /* 28 */ + step(20_39, b, c, d, e, t, a, prep1.u32[1]); /* 29 */ + step(20_39, a, b, c, d, e, t, prep1.u32[2]); /* 30 */ + step(20_39, t, a, b, c, d, e, prep1.u32[3]); /* 31 */ prep(prep1, W2, W3, W0, W1, K40_59); - step(20_39, e, t, a, b, c, d, prep2.u32[0]); /* 32 */ - step(20_39, d, e, t, a, b, c, prep2.u32[1]); /* 33 */ - step(20_39, c, d, e, t, a, b, prep2.u32[2]); /* 34 */ - step(20_39, b, c, d, e, t, a, prep2.u32[3]); /* 35 */ + step(20_39, e, t, a, b, c, d, prep2.u32[0]); /* 32 */ + step(20_39, d, e, t, a, b, c, prep2.u32[1]); /* 33 */ + step(20_39, c, d, e, t, a, b, prep2.u32[2]); /* 34 */ + step(20_39, b, c, d, e, t, a, prep2.u32[3]); /* 35 */ prep(prep2, W3, W0, W1, W2, K40_59); - step(20_39, a, b, c, d, e, t, prep0.u32[0]); /* 36 */ - step(20_39, t, a, b, c, d, e, prep0.u32[1]); /* 37 */ - step(20_39, e, t, a, b, c, d, prep0.u32[2]); /* 38 */ - step(20_39, d, e, t, a, b, c, prep0.u32[3]); /* 39 */ + step(20_39, a, b, c, d, e, t, prep0.u32[0]); /* 36 */ + step(20_39, t, a, b, c, d, e, prep0.u32[1]); /* 37 */ + step(20_39, e, t, a, b, c, d, prep0.u32[2]); /* 38 */ + step(20_39, d, e, t, a, b, c, prep0.u32[3]); /* 39 */ prep(prep0, W0, W1, W2, W3, K40_59); - step(40_59, c, d, e, t, a, b, prep1.u32[0]); /* 40 */ - step(40_59, b, c, d, e, t, a, prep1.u32[1]); /* 41 */ - step(40_59, a, b, c, d, e, t, prep1.u32[2]); /* 42 */ - step(40_59, t, a, b, c, d, e, prep1.u32[3]); /* 43 */ + step(40_59, c, d, e, t, a, b, prep1.u32[0]); /* 40 */ + step(40_59, b, c, d, e, t, a, prep1.u32[1]); /* 41 */ + step(40_59, a, b, c, d, e, t, prep1.u32[2]); /* 42 */ + step(40_59, t, a, b, c, d, e, prep1.u32[3]); /* 43 */ prep(prep1, W1, W2, W3, W0, K40_59); - step(40_59, e, t, a, b, c, d, prep2.u32[0]); /* 44 */ - step(40_59, d, e, t, a, b, c, prep2.u32[1]); /* 45 */ - step(40_59, c, d, e, t, a, b, prep2.u32[2]); /* 46 */ - step(40_59, b, c, d, e, t, a, prep2.u32[3]); /* 47 */ + step(40_59, e, t, a, b, c, d, prep2.u32[0]); /* 44 */ + step(40_59, d, e, t, a, b, c, prep2.u32[1]); /* 45 */ + step(40_59, c, d, e, t, a, b, prep2.u32[2]); /* 46 */ + step(40_59, b, c, d, e, t, a, prep2.u32[3]); /* 47 */ prep(prep2, W2, W3, W0, W1, K40_59); - step(40_59, a, b, c, d, e, t, prep0.u32[0]); /* 48 */ - step(40_59, t, a, b, c, d, e, prep0.u32[1]); /* 49 */ - step(40_59, e, t, a, b, c, d, prep0.u32[2]); /* 50 */ - step(40_59, d, e, t, a, b, c, prep0.u32[3]); /* 51 */ + step(40_59, a, b, c, d, e, t, prep0.u32[0]); /* 48 */ + step(40_59, t, a, b, c, d, e, prep0.u32[1]); /* 49 */ + step(40_59, e, t, a, b, c, d, prep0.u32[2]); /* 50 */ + step(40_59, d, e, t, a, b, c, prep0.u32[3]); /* 51 */ prep(prep0, W3, W0, W1, W2, K60_79); - step(40_59, c, d, e, t, a, b, prep1.u32[0]); /* 52 */ - step(40_59, b, c, d, e, t, a, prep1.u32[1]); /* 53 */ - step(40_59, a, b, c, d, e, t, prep1.u32[2]); /* 54 */ - step(40_59, t, a, b, c, d, e, prep1.u32[3]); /* 55 */ + step(40_59, c, d, e, t, a, b, prep1.u32[0]); /* 52 */ + step(40_59, b, c, d, e, t, a, prep1.u32[1]); /* 53 */ + step(40_59, a, b, c, d, e, t, prep1.u32[2]); /* 54 */ + step(40_59, t, a, b, c, d, e, prep1.u32[3]); /* 55 */ prep(prep1, W0, W1, W2, W3, K60_79); - step(40_59, e, t, a, b, c, d, prep2.u32[0]); /* 56 */ - step(40_59, d, e, t, a, b, c, prep2.u32[1]); /* 57 */ - step(40_59, c, d, e, t, a, b, prep2.u32[2]); /* 58 */ - step(40_59, b, c, d, e, t, a, prep2.u32[3]); /* 59 */ + step(40_59, e, t, a, b, c, d, prep2.u32[0]); /* 56 */ + step(40_59, d, e, t, a, b, c, prep2.u32[1]); /* 57 */ + step(40_59, c, d, e, t, a, b, prep2.u32[2]); /* 58 */ + step(40_59, b, c, d, e, t, a, prep2.u32[3]); /* 59 */ prep(prep2, W1, W2, W3, W0, K60_79); - step(60_79, a, b, c, d, e, t, prep0.u32[0]); /* 60 */ - step(60_79, t, a, b, c, d, e, prep0.u32[1]); /* 61 */ - step(60_79, e, t, a, b, c, d, prep0.u32[2]); /* 62 */ - step(60_79, d, e, t, a, b, c, prep0.u32[3]); /* 63 */ + step(60_79, a, b, c, d, e, t, prep0.u32[0]); /* 60 */ + step(60_79, t, a, b, c, d, e, prep0.u32[1]); /* 61 */ + step(60_79, e, t, a, b, c, d, prep0.u32[2]); /* 62 */ + step(60_79, d, e, t, a, b, c, prep0.u32[3]); /* 63 */ prep(prep0, W2, W3, W0, W1, K60_79); - step(60_79, c, d, e, t, a, b, prep1.u32[0]); /* 64 */ - step(60_79, b, c, d, e, t, a, prep1.u32[1]); /* 65 */ - step(60_79, a, b, c, d, e, t, prep1.u32[2]); /* 66 */ - step(60_79, t, a, b, c, d, e, prep1.u32[3]); /* 67 */ + step(60_79, c, d, e, t, a, b, prep1.u32[0]); /* 64 */ + step(60_79, b, c, d, e, t, a, prep1.u32[1]); /* 65 */ + step(60_79, a, b, c, d, e, t, prep1.u32[2]); /* 66 */ + step(60_79, t, a, b, c, d, e, prep1.u32[3]); /* 67 */ prep(prep1, W3, W0, W1, W2, K60_79); - step(60_79, e, t, a, b, c, d, prep2.u32[0]); /* 68 */ - step(60_79, d, e, t, a, b, c, prep2.u32[1]); /* 69 */ - step(60_79, c, d, e, t, a, b, prep2.u32[2]); /* 70 */ - step(60_79, b, c, d, e, t, a, prep2.u32[3]); /* 71 */ - - step(60_79, a, b, c, d, e, t, prep0.u32[0]); /* 72 */ - step(60_79, t, a, b, c, d, e, prep0.u32[1]); /* 73 */ - step(60_79, e, t, a, b, c, d, prep0.u32[2]); /* 74 */ - step(60_79, d, e, t, a, b, c, prep0.u32[3]); /* 75 */ + step(60_79, e, t, a, b, c, d, prep2.u32[0]); /* 68 */ + step(60_79, d, e, t, a, b, c, prep2.u32[1]); /* 69 */ + step(60_79, c, d, e, t, a, b, prep2.u32[2]); /* 70 */ + step(60_79, b, c, d, e, t, a, prep2.u32[3]); /* 71 */ + + step(60_79, a, b, c, d, e, t, prep0.u32[0]); /* 72 */ + step(60_79, t, a, b, c, d, e, prep0.u32[1]); /* 73 */ + step(60_79, e, t, a, b, c, d, prep0.u32[2]); /* 74 */ + step(60_79, d, e, t, a, b, c, prep0.u32[3]); /* 75 */ /* no more input to prepare */ - step(60_79, c, d, e, t, a, b, prep1.u32[0]); /* 76 */ - step(60_79, b, c, d, e, t, a, prep1.u32[1]); /* 77 */ - step(60_79, a, b, c, d, e, t, prep1.u32[2]); /* 78 */ - step(60_79, t, a, b, c, d, e, prep1.u32[3]); /* 79 */ + step(60_79, c, d, e, t, a, b, prep1.u32[0]); /* 76 */ + step(60_79, b, c, d, e, t, a, prep1.u32[1]); /* 77 */ + step(60_79, a, b, c, d, e, t, prep1.u32[2]); /* 78 */ + step(60_79, t, a, b, c, d, e, prep1.u32[3]); /* 79 */ /* e, t, a, b, c, d */ H[0] += e; H[1] += t; -- cgit v1.2.3 From 132d60b77647c4a82cdba03ba2ac27773ca633ba Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 06:08:51 +0000 Subject: Format for easier reading --- src/hash/sha1/sha160.cpp | 74 ++++++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/hash/sha1/sha160.cpp b/src/hash/sha1/sha160.cpp index a9e6880a7..b4a556663 100644 --- a/src/hash/sha1/sha160.cpp +++ b/src/hash/sha1/sha160.cpp @@ -78,37 +78,49 @@ void SHA_160::compress_n(const byte input[], u32bit blocks) W[j+3] = rotate_left((W[j ] ^ W[j-5] ^ W[j-11] ^ W[j-13]), 1); } - F1(A,B,C,D,E,W[ 0]); F1(E,A,B,C,D,W[ 1]); F1(D,E,A,B,C,W[ 2]); - F1(C,D,E,A,B,W[ 3]); F1(B,C,D,E,A,W[ 4]); F1(A,B,C,D,E,W[ 5]); - F1(E,A,B,C,D,W[ 6]); F1(D,E,A,B,C,W[ 7]); F1(C,D,E,A,B,W[ 8]); - F1(B,C,D,E,A,W[ 9]); F1(A,B,C,D,E,W[10]); F1(E,A,B,C,D,W[11]); - F1(D,E,A,B,C,W[12]); F1(C,D,E,A,B,W[13]); F1(B,C,D,E,A,W[14]); - F1(A,B,C,D,E,W[15]); F1(E,A,B,C,D,W[16]); F1(D,E,A,B,C,W[17]); - F1(C,D,E,A,B,W[18]); F1(B,C,D,E,A,W[19]); - - F2(A,B,C,D,E,W[20]); F2(E,A,B,C,D,W[21]); F2(D,E,A,B,C,W[22]); - F2(C,D,E,A,B,W[23]); F2(B,C,D,E,A,W[24]); F2(A,B,C,D,E,W[25]); - F2(E,A,B,C,D,W[26]); F2(D,E,A,B,C,W[27]); F2(C,D,E,A,B,W[28]); - F2(B,C,D,E,A,W[29]); F2(A,B,C,D,E,W[30]); F2(E,A,B,C,D,W[31]); - F2(D,E,A,B,C,W[32]); F2(C,D,E,A,B,W[33]); F2(B,C,D,E,A,W[34]); - F2(A,B,C,D,E,W[35]); F2(E,A,B,C,D,W[36]); F2(D,E,A,B,C,W[37]); - F2(C,D,E,A,B,W[38]); F2(B,C,D,E,A,W[39]); - - F3(A,B,C,D,E,W[40]); F3(E,A,B,C,D,W[41]); F3(D,E,A,B,C,W[42]); - F3(C,D,E,A,B,W[43]); F3(B,C,D,E,A,W[44]); F3(A,B,C,D,E,W[45]); - F3(E,A,B,C,D,W[46]); F3(D,E,A,B,C,W[47]); F3(C,D,E,A,B,W[48]); - F3(B,C,D,E,A,W[49]); F3(A,B,C,D,E,W[50]); F3(E,A,B,C,D,W[51]); - F3(D,E,A,B,C,W[52]); F3(C,D,E,A,B,W[53]); F3(B,C,D,E,A,W[54]); - F3(A,B,C,D,E,W[55]); F3(E,A,B,C,D,W[56]); F3(D,E,A,B,C,W[57]); - F3(C,D,E,A,B,W[58]); F3(B,C,D,E,A,W[59]); - - F4(A,B,C,D,E,W[60]); F4(E,A,B,C,D,W[61]); F4(D,E,A,B,C,W[62]); - F4(C,D,E,A,B,W[63]); F4(B,C,D,E,A,W[64]); F4(A,B,C,D,E,W[65]); - F4(E,A,B,C,D,W[66]); F4(D,E,A,B,C,W[67]); F4(C,D,E,A,B,W[68]); - F4(B,C,D,E,A,W[69]); F4(A,B,C,D,E,W[70]); F4(E,A,B,C,D,W[71]); - F4(D,E,A,B,C,W[72]); F4(C,D,E,A,B,W[73]); F4(B,C,D,E,A,W[74]); - F4(A,B,C,D,E,W[75]); F4(E,A,B,C,D,W[76]); F4(D,E,A,B,C,W[77]); - F4(C,D,E,A,B,W[78]); F4(B,C,D,E,A,W[79]); + F1(A, B, C, D, E, W[ 0]); F1(E, A, B, C, D, W[ 1]); + F1(D, E, A, B, C, W[ 2]); F1(C, D, E, A, B, W[ 3]); + F1(B, C, D, E, A, W[ 4]); F1(A, B, C, D, E, W[ 5]); + F1(E, A, B, C, D, W[ 6]); F1(D, E, A, B, C, W[ 7]); + F1(C, D, E, A, B, W[ 8]); F1(B, C, D, E, A, W[ 9]); + F1(A, B, C, D, E, W[10]); F1(E, A, B, C, D, W[11]); + F1(D, E, A, B, C, W[12]); F1(C, D, E, A, B, W[13]); + F1(B, C, D, E, A, W[14]); F1(A, B, C, D, E, W[15]); + F1(E, A, B, C, D, W[16]); F1(D, E, A, B, C, W[17]); + F1(C, D, E, A, B, W[18]); F1(B, C, D, E, A, W[19]); + + F2(A, B, C, D, E, W[20]); F2(E, A, B, C, D, W[21]); + F2(D, E, A, B, C, W[22]); F2(C, D, E, A, B, W[23]); + F2(B, C, D, E, A, W[24]); F2(A, B, C, D, E, W[25]); + F2(E, A, B, C, D, W[26]); F2(D, E, A, B, C, W[27]); + F2(C, D, E, A, B, W[28]); F2(B, C, D, E, A, W[29]); + F2(A, B, C, D, E, W[30]); F2(E, A, B, C, D, W[31]); + F2(D, E, A, B, C, W[32]); F2(C, D, E, A, B, W[33]); + F2(B, C, D, E, A, W[34]); F2(A, B, C, D, E, W[35]); + F2(E, A, B, C, D, W[36]); F2(D, E, A, B, C, W[37]); + F2(C, D, E, A, B, W[38]); F2(B, C, D, E, A, W[39]); + + F3(A, B, C, D, E, W[40]); F3(E, A, B, C, D, W[41]); + F3(D, E, A, B, C, W[42]); F3(C, D, E, A, B, W[43]); + F3(B, C, D, E, A, W[44]); F3(A, B, C, D, E, W[45]); + F3(E, A, B, C, D, W[46]); F3(D, E, A, B, C, W[47]); + F3(C, D, E, A, B, W[48]); F3(B, C, D, E, A, W[49]); + F3(A, B, C, D, E, W[50]); F3(E, A, B, C, D, W[51]); + F3(D, E, A, B, C, W[52]); F3(C, D, E, A, B, W[53]); + F3(B, C, D, E, A, W[54]); F3(A, B, C, D, E, W[55]); + F3(E, A, B, C, D, W[56]); F3(D, E, A, B, C, W[57]); + F3(C, D, E, A, B, W[58]); F3(B, C, D, E, A, W[59]); + + F4(A, B, C, D, E, W[60]); F4(E, A, B, C, D, W[61]); + F4(D, E, A, B, C, W[62]); F4(C, D, E, A, B, W[63]); + F4(B, C, D, E, A, W[64]); F4(A, B, C, D, E, W[65]); + F4(E, A, B, C, D, W[66]); F4(D, E, A, B, C, W[67]); + F4(C, D, E, A, B, W[68]); F4(B, C, D, E, A, W[69]); + F4(A, B, C, D, E, W[70]); F4(E, A, B, C, D, W[71]); + F4(D, E, A, B, C, W[72]); F4(C, D, E, A, B, W[73]); + F4(B, C, D, E, A, W[74]); F4(A, B, C, D, E, W[75]); + F4(E, A, B, C, D, W[76]); F4(D, E, A, B, C, W[77]); + F4(C, D, E, A, B, W[78]); F4(B, C, D, E, A, W[79]); A = (digest[0] += A); B = (digest[1] += B); -- cgit v1.2.3 From ee39df482cb0e5ec9e5d1c1bf349ebdcc2a157c2 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 06:16:42 +0000 Subject: Clean up the SSE2 SHA-1 code quite a bit, make better use of C++ features and also make it stylistically much closer to the standard SHA-1 code. --- src/hash/sha1_sse2/sha1_sse2.cpp | 273 ++++++++++++++++++++++++++++++- src/hash/sha1_sse2/sha1_sse2_imp.cpp | 302 ----------------------------------- 2 files changed, 267 insertions(+), 308 deletions(-) delete mode 100644 src/hash/sha1_sse2/sha1_sse2_imp.cpp (limited to 'src') diff --git a/src/hash/sha1_sse2/sha1_sse2.cpp b/src/hash/sha1_sse2/sha1_sse2.cpp index dddc06b7b..cd1b7e97b 100644 --- a/src/hash/sha1_sse2/sha1_sse2.cpp +++ b/src/hash/sha1_sse2/sha1_sse2.cpp @@ -1,23 +1,284 @@ /* -* SHA-160 (SSE2) -* (C) 1999-2007 Jack Lloyd +* SHA-1 using SSE2 +* (C) 2009 Jack Lloyd * * Distributed under the terms of the Botan license +* +* Based on public domain code by Dean Gaudet +* Source - http://arctic.org/~dean/crypto/sha1.html */ #include +#include +#include namespace Botan { +namespace { + +/* +the first 16 bytes only need byte swapping + +prepared points to 4x u32bit, 16-byte aligned + +W points to the 4 dwords which need preparing -- +and is overwritten with the swapped bytes +*/ +#define prep00_15(prep, W) \ + do { \ + __m128i r1 = (W); \ + r1 = _mm_shufflehi_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ + r1 = _mm_shufflelo_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ + __m128i r2 = _mm_slli_epi16(r1, 8); \ + r1 = _mm_srli_epi16(r1, 8); \ + r1 = _mm_or_si128(r1, r2); \ + (W) = r1; \ + (prep).u128 = _mm_add_epi32(K00_19, r1); \ + } while(0) + +/* +for each multiple of 4, t, we want to calculate this: + +W[t+0] = rol(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); +W[t+1] = rol(W[t-2] ^ W[t-7] ^ W[t-13] ^ W[t-15], 1); +W[t+2] = rol(W[t-1] ^ W[t-6] ^ W[t-12] ^ W[t-14], 1); +W[t+3] = rol(W[t] ^ W[t-5] ^ W[t-11] ^ W[t-13], 1); + +we'll actually calculate this: + +W[t+0] = rol(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); +W[t+1] = rol(W[t-2] ^ W[t-7] ^ W[t-13] ^ W[t-15], 1); +W[t+2] = rol(W[t-1] ^ W[t-6] ^ W[t-12] ^ W[t-14], 1); +W[t+3] = rol( 0 ^ W[t-5] ^ W[t-11] ^ W[t-13], 1); +W[t+3] ^= rol(W[t+0], 1); + +the parameters are: + +W0 = &W[t-16]; +W1 = &W[t-12]; +W2 = &W[t- 8]; +W3 = &W[t- 4]; + +and on output: +prepared = W0 + K +W0 = W[t]..W[t+3] +*/ + +/* note that there is a step here where i want to do a rol by 1, which +* normally would look like this: +* +* r1 = psrld r0,$31 +* r0 = pslld r0,$1 +* r0 = por r0,r1 +* +* but instead i do this: +* +* r1 = pcmpltd r0,zero +* r0 = paddd r0,r0 +* r0 = psub r0,r1 +* +* because pcmpltd and paddd are availabe in both MMX units on +* efficeon, pentium-m, and opteron but shifts are available in +* only one unit. +*/ +#define prep(prep, XW0, XW1, XW2, XW3, K) \ + do { \ + __m128i r0, r1, r2, r3; \ + \ + /* load W[t-4] 16-byte aligned, and shift */ \ + r3 = _mm_srli_si128((XW3), 4); \ + r0 = (XW0); \ + /* get high 64-bits of XW0 into low 64-bits */ \ + r1 = _mm_shuffle_epi32((XW0), _MM_SHUFFLE(1,0,3,2)); \ + /* load high 64-bits of r1 */ \ + r1 = _mm_unpacklo_epi64(r1, (XW1)); \ + r2 = (XW2); \ + \ + r0 = _mm_xor_si128(r1, r0); \ + r2 = _mm_xor_si128(r3, r2); \ + r0 = _mm_xor_si128(r2, r0); \ + /* unrotated W[t]..W[t+2] in r0 ... still need W[t+3] */ \ + \ + r2 = _mm_slli_si128(r0, 12); \ + r1 = _mm_cmplt_epi32(r0, _mm_setzero_si128()); \ + r0 = _mm_add_epi32(r0, r0); /* shift left by 1 */ \ + r0 = _mm_sub_epi32(r0, r1); /* r0 has W[t]..W[t+2] */ \ + \ + r3 = _mm_srli_epi32(r2, 30); \ + r2 = _mm_slli_epi32(r2, 2); \ + \ + r0 = _mm_xor_si128(r0, r3); \ + r0 = _mm_xor_si128(r0, r2); /* r0 now has W[t+3] */ \ + \ + (XW0) = r0; \ + (prep).u128 = _mm_add_epi32(r0, K); \ + } while(0) + +/* +* SHA-160 F1 Function +*/ +inline void F1(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) + { + E += (D ^ (B & (C ^ D))) + msg + rotate_left(A, 5); + B = rotate_left(B, 30); + } + +/* +* SHA-160 F2 Function +*/ +inline void F2(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) + { + E += (B ^ C ^ D) + msg + rotate_left(A, 5); + B = rotate_left(B, 30); + } + +/* +* SHA-160 F3 Function +*/ +inline void F3(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) + { + E += ((B & C) | ((B | C) & D)) + msg + rotate_left(A, 5); + B = rotate_left(B, 30); + } + +/* +* SHA-160 F4 Function +*/ +inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) + { + E += (B ^ C ^ D) + msg + rotate_left(A, 5); + B = rotate_left(B, 30); + } + +} + /* -* SHA-160 Compression Function +* SHA-160 Compression Function using SSE for message expansion */ -void SHA_160_SSE2::compress_n(const byte input[], u32bit blocks) +void SHA_160_SSE2::compress_n(const byte input_bytes[], u32bit blocks) { + const __m128i K00_19 = _mm_set1_epi32(0x5A827999); + const __m128i K20_39 = _mm_set1_epi32(0x6ED9EBA1); + const __m128i K40_59 = _mm_set1_epi32(0x8F1BBCDC); + const __m128i K60_79 = _mm_set1_epi32(0xCA62C1D6); + + u32bit A = digest[0], B = digest[1], C = digest[2], + D = digest[3], E = digest[4]; + + const __m128i* input = (const __m128i *)input_bytes; + for(u32bit i = 0; i != blocks; ++i) { - botan_sha1_sse2_compress(digest, reinterpret_cast(input)); - input += HASH_BLOCK_SIZE; + + /* I've tried arranging the SSE2 code to be 4, 8, 12, and 16 + * steps ahead of the integer code. 12 steps ahead seems to + * produce the best performance. -dean + * + * Todo: check this is still true on Barcelona and Core2 -Jack + */ + + union v4si { + u32bit u32[4]; + __m128i u128; + }; + + v4si P0, P1, P2; + + __m128i W0 = _mm_loadu_si128(&input[0]); + prep00_15(P0, W0); + + __m128i W1 = _mm_loadu_si128(&input[1]); + prep00_15(P1, W1); + + __m128i W2 = _mm_loadu_si128(&input[2]); + prep00_15(P2, W2); + + __m128i W3 = _mm_loadu_si128(&input[3]); + + F1(A, B, C, D, E, P0.u32[0]); F1(E, A, B, C, D, P0.u32[1]); + F1(D, E, A, B, C, P0.u32[2]); F1(C, D, E, A, B, P0.u32[3]); + prep00_15(P0, W3); + + F1(B, C, D, E, A, P1.u32[0]); F1(A, B, C, D, E, P1.u32[1]); + F1(E, A, B, C, D, P1.u32[2]); F1(D, E, A, B, C, P1.u32[3]); + prep(P1, W0, W1, W2, W3, K00_19); + + F1(C, D, E, A, B, P2.u32[0]); F1(B, C, D, E, A, P2.u32[1]); + F1(A, B, C, D, E, P2.u32[2]); F1(E, A, B, C, D, P2.u32[3]); + prep(P2, W1, W2, W3, W0, K20_39); + + F1(D, E, A, B, C, P0.u32[0]); F1(C, D, E, A, B, P0.u32[1]); + F1(B, C, D, E, A, P0.u32[2]); F1(A, B, C, D, E, P0.u32[3]); + prep(P0, W2, W3, W0, W1, K20_39); + + F1(E, A, B, C, D, P1.u32[0]); F1(D, E, A, B, C, P1.u32[1]); + F1(C, D, E, A, B, P1.u32[2]); F1(B, C, D, E, A, P1.u32[3]); + prep(P1, W3, W0, W1, W2, K20_39); + + F2(A, B, C, D, E, P2.u32[0]); F2(E, A, B, C, D, P2.u32[1]); + F2(D, E, A, B, C, P2.u32[2]); F2(C, D, E, A, B, P2.u32[3]); + prep(P2, W0, W1, W2, W3, K20_39); + + F2(B, C, D, E, A, P0.u32[0]); F2(A, B, C, D, E, P0.u32[1]); + F2(E, A, B, C, D, P0.u32[2]); F2(D, E, A, B, C, P0.u32[3]); + prep(P0, W1, W2, W3, W0, K20_39); + + F2(C, D, E, A, B, P1.u32[0]); F2(B, C, D, E, A, P1.u32[1]); + F2(A, B, C, D, E, P1.u32[2]); F2(E, A, B, C, D, P1.u32[3]); + prep(P1, W2, W3, W0, W1, K40_59); + + F2(D, E, A, B, C, P2.u32[0]); F2(C, D, E, A, B, P2.u32[1]); + F2(B, C, D, E, A, P2.u32[2]); F2(A, B, C, D, E, P2.u32[3]); + prep(P2, W3, W0, W1, W2, K40_59); + + F2(E, A, B, C, D, P0.u32[0]); F2(D, E, A, B, C, P0.u32[1]); + F2(C, D, E, A, B, P0.u32[2]); F2(B, C, D, E, A, P0.u32[3]); + prep(P0, W0, W1, W2, W3, K40_59); + + F3(A, B, C, D, E, P1.u32[0]); F3(E, A, B, C, D, P1.u32[1]); + F3(D, E, A, B, C, P1.u32[2]); F3(C, D, E, A, B, P1.u32[3]); + prep(P1, W1, W2, W3, W0, K40_59); + + F3(B, C, D, E, A, P2.u32[0]); F3(A, B, C, D, E, P2.u32[1]); + F3(E, A, B, C, D, P2.u32[2]); F3(D, E, A, B, C, P2.u32[3]); + prep(P2, W2, W3, W0, W1, K40_59); + + F3(C, D, E, A, B, P0.u32[0]); F3(B, C, D, E, A, P0.u32[1]); + F3(A, B, C, D, E, P0.u32[2]); F3(E, A, B, C, D, P0.u32[3]); + prep(P0, W3, W0, W1, W2, K60_79); + + F3(D, E, A, B, C, P1.u32[0]); F3(C, D, E, A, B, P1.u32[1]); + F3(B, C, D, E, A, P1.u32[2]); F3(A, B, C, D, E, P1.u32[3]); + prep(P1, W0, W1, W2, W3, K60_79); + + F3(E, A, B, C, D, P2.u32[0]); F3(D, E, A, B, C, P2.u32[1]); + F3(C, D, E, A, B, P2.u32[2]); F3(B, C, D, E, A, P2.u32[3]); + prep(P2, W1, W2, W3, W0, K60_79); + + F4(A, B, C, D, E, P0.u32[0]); F4(E, A, B, C, D, P0.u32[1]); + F4(D, E, A, B, C, P0.u32[2]); F4(C, D, E, A, B, P0.u32[3]); + prep(P0, W2, W3, W0, W1, K60_79); + + F4(B, C, D, E, A, P1.u32[0]); F4(A, B, C, D, E, P1.u32[1]); + F4(E, A, B, C, D, P1.u32[2]); F4(D, E, A, B, C, P1.u32[3]); + prep(P1, W3, W0, W1, W2, K60_79); + + F4(C, D, E, A, B, P2.u32[0]); F4(B, C, D, E, A, P2.u32[1]); + F4(A, B, C, D, E, P2.u32[2]); F4(E, A, B, C, D, P2.u32[3]); + + F4(D, E, A, B, C, P0.u32[0]); F4(C, D, E, A, B, P0.u32[1]); + F4(B, C, D, E, A, P0.u32[2]); F4(A, B, C, D, E, P0.u32[3]); + + F4(E, A, B, C, D, P1.u32[0]); F4(D, E, A, B, C, P1.u32[1]); + F4(C, D, E, A, B, P1.u32[2]); F4(B, C, D, E, A, P1.u32[3]); + + A = (digest[0] += A); + B = (digest[1] += B); + C = (digest[2] += C); + D = (digest[3] += D); + E = (digest[4] += E); + + input += (HASH_BLOCK_SIZE / 16); } } diff --git a/src/hash/sha1_sse2/sha1_sse2_imp.cpp b/src/hash/sha1_sse2/sha1_sse2_imp.cpp deleted file mode 100644 index f561cb1c8..000000000 --- a/src/hash/sha1_sse2/sha1_sse2_imp.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/* -* SHA-1 using SSE2 -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -/* -* Based on public domain code by Dean Gaudet -* http://arctic.org/~dean/crypto/sha1.html -*/ - -#include -#include -#include - -namespace Botan { - -namespace { - -typedef union { - u32bit u32[4]; - __m128i u128; - } v4si; - -static const v4si K00_19 = { { 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999 } }; -static const v4si K20_39 = { { 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1 } }; -static const v4si K40_59 = { { 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc } }; -static const v4si K60_79 = { { 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6 } }; - -/* -the first 16 bytes only need byte swapping - -prepared points to 4x u32bit, 16-byte aligned - -W points to the 4 dwords which need preparing -- -and is overwritten with the swapped bytes -*/ -#define prep00_15(prep, W) \ - do { \ - __m128i r1 = (W); \ - r1 = _mm_shufflehi_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ - r1 = _mm_shufflelo_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ - __m128i r2 = _mm_slli_epi16(r1, 8); \ - r1 = _mm_srli_epi16(r1, 8); \ - r1 = _mm_or_si128(r1, r2); \ - (W) = r1; \ - (prep).u128 = _mm_add_epi32(K00_19.u128, r1); \ - } while(0) - -/* -for each multiple of 4, t, we want to calculate this: - -W[t+0] = rol(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); -W[t+1] = rol(W[t-2] ^ W[t-7] ^ W[t-13] ^ W[t-15], 1); -W[t+2] = rol(W[t-1] ^ W[t-6] ^ W[t-12] ^ W[t-14], 1); -W[t+3] = rol(W[t] ^ W[t-5] ^ W[t-11] ^ W[t-13], 1); - -we'll actually calculate this: - -W[t+0] = rol(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); -W[t+1] = rol(W[t-2] ^ W[t-7] ^ W[t-13] ^ W[t-15], 1); -W[t+2] = rol(W[t-1] ^ W[t-6] ^ W[t-12] ^ W[t-14], 1); -W[t+3] = rol( 0 ^ W[t-5] ^ W[t-11] ^ W[t-13], 1); -W[t+3] ^= rol(W[t+0], 1); - -the parameters are: - -W0 = &W[t-16]; -W1 = &W[t-12]; -W2 = &W[t- 8]; -W3 = &W[t- 4]; - -and on output: -prepared = W0 + K -W0 = W[t]..W[t+3] -*/ - -/* note that there is a step here where i want to do a rol by 1, which -* normally would look like this: -* -* r1 = psrld r0,$31 -* r0 = pslld r0,$1 -* r0 = por r0,r1 -* -* but instead i do this: -* -* r1 = pcmpltd r0,zero -* r0 = paddd r0,r0 -* r0 = psub r0,r1 -* -* because pcmpltd and paddd are availabe in both MMX units on -* efficeon, pentium-m, and opteron but shifts are available in -* only one unit. -*/ -#define prep(prep, XW0, XW1, XW2, XW3, K) \ - do { \ - __m128i r0, r1, r2, r3; \ - \ - /* load W[t-4] 16-byte aligned, and shift */ \ - r3 = _mm_srli_si128((XW3), 4); \ - r0 = (XW0); \ - /* get high 64-bits of XW0 into low 64-bits */ \ - r1 = _mm_shuffle_epi32((XW0), _MM_SHUFFLE(1,0,3,2)); \ - /* load high 64-bits of r1 */ \ - r1 = _mm_unpacklo_epi64(r1, (XW1)); \ - r2 = (XW2); \ - \ - r0 = _mm_xor_si128(r1, r0); \ - r2 = _mm_xor_si128(r3, r2); \ - r0 = _mm_xor_si128(r2, r0); \ - /* unrotated W[t]..W[t+2] in r0 ... still need W[t+3] */ \ - \ - r2 = _mm_slli_si128(r0, 12); \ - r1 = _mm_cmplt_epi32(r0, _mm_setzero_si128()); \ - r0 = _mm_add_epi32(r0, r0); /* shift left by 1 */ \ - r0 = _mm_sub_epi32(r0, r1); /* r0 has W[t]..W[t+2] */ \ - \ - r3 = _mm_srli_epi32(r2, 30); \ - r2 = _mm_slli_epi32(r2, 2); \ - \ - r0 = _mm_xor_si128(r0, r3); \ - r0 = _mm_xor_si128(r0, r2); /* r0 now has W[t+3] */ \ - \ - (XW0) = r0; \ - (prep).u128 = _mm_add_epi32(r0, (K).u128); \ - } while(0) - -static inline u32bit f00_19(u32bit x, u32bit y, u32bit z) - { - /* FIPS 180-2 says this: (x & y) ^ (~x & z) - * but we can calculate it in fewer steps. - */ - return ((y ^ z) & x) ^ z; - } - -static inline u32bit f20_39(u32bit x, u32bit y, u32bit z) - { - return (x ^ z) ^ y; - } - -static inline u32bit f40_59(u32bit x, u32bit y, u32bit z) - { - /* FIPS 180-2 says this: (x & y) ^ (x & z) ^ (y & z) - * but we can calculate it in fewer steps. - */ - return (x & z) | ((x | z) & y); - } - -static inline u32bit f60_79(u32bit x, u32bit y, u32bit z) - { - return f20_39(x, y, z); - } - -#define step(nn_mm, xa, xb, xc, xd, xe, xt, input) \ - do { \ - (xt) = (input) + f##nn_mm((xb), (xc), (xd)); \ - (xb) = rotate_left((xb), 30); \ - (xt) += ((xe) + rotate_left((xa), 5)); \ - } while(0) - -} - -extern "C" void botan_sha1_sse2_compress(u32bit H[5], - const u32bit* inputu) - { - const __m128i * input = (const __m128i *)inputu; - - u32bit a = H[0]; - u32bit b = H[1]; - u32bit c = H[2]; - u32bit d = H[3]; - u32bit e = H[4]; - u32bit t = 0; - - /* i've tried arranging the SSE2 code to be 4, 8, 12, and 16 - * steps ahead of the integer code. 12 steps ahead seems - * to produce the best performance. -dean - */ - v4si prep0, prep1, prep2; - - __m128i W0 = _mm_loadu_si128(&input[0]); - prep00_15(prep0, W0); /* prepare for 00 through 03 */ - - __m128i W1 = _mm_loadu_si128(&input[1]); - prep00_15(prep1, W1); /* prepare for 04 through 07 */ - - __m128i W2 = _mm_loadu_si128(&input[2]); - prep00_15(prep2, W2); /* prepare for 08 through 11 */ - - __m128i W3 = _mm_loadu_si128(&input[3]); - step(00_19, a, b, c, d, e, t, prep0.u32[0]); /* 00 */ - step(00_19, t, a, b, c, d, e, prep0.u32[1]); /* 01 */ - step(00_19, e, t, a, b, c, d, prep0.u32[2]); /* 02 */ - step(00_19, d, e, t, a, b, c, prep0.u32[3]); /* 03 */ - prep00_15(prep0, W3); - step(00_19, c, d, e, t, a, b, prep1.u32[0]); /* 04 */ - step(00_19, b, c, d, e, t, a, prep1.u32[1]); /* 05 */ - step(00_19, a, b, c, d, e, t, prep1.u32[2]); /* 06 */ - step(00_19, t, a, b, c, d, e, prep1.u32[3]); /* 07 */ - prep(prep1, W0, W1, W2, W3, K00_19); /* prepare for 16 through 19 */ - step(00_19, e, t, a, b, c, d, prep2.u32[0]); /* 08 */ - step(00_19, d, e, t, a, b, c, prep2.u32[1]); /* 09 */ - step(00_19, c, d, e, t, a, b, prep2.u32[2]); /* 10 */ - step(00_19, b, c, d, e, t, a, prep2.u32[3]); /* 11 */ - prep(prep2, W1, W2, W3, W0, K20_39); /* prepare for 20 through 23 */ - step(00_19, a, b, c, d, e, t, prep0.u32[0]); /* 12 */ - step(00_19, t, a, b, c, d, e, prep0.u32[1]); /* 13 */ - step(00_19, e, t, a, b, c, d, prep0.u32[2]); /* 14 */ - step(00_19, d, e, t, a, b, c, prep0.u32[3]); /* 15 */ - prep(prep0, W2, W3, W0, W1, K20_39); - step(00_19, c, d, e, t, a, b, prep1.u32[0]); /* 16 */ - step(00_19, b, c, d, e, t, a, prep1.u32[1]); /* 17 */ - step(00_19, a, b, c, d, e, t, prep1.u32[2]); /* 18 */ - step(00_19, t, a, b, c, d, e, prep1.u32[3]); /* 19 */ - - prep(prep1, W3, W0, W1, W2, K20_39); - step(20_39, e, t, a, b, c, d, prep2.u32[0]); /* 20 */ - step(20_39, d, e, t, a, b, c, prep2.u32[1]); /* 21 */ - step(20_39, c, d, e, t, a, b, prep2.u32[2]); /* 22 */ - step(20_39, b, c, d, e, t, a, prep2.u32[3]); /* 23 */ - prep(prep2, W0, W1, W2, W3, K20_39); - step(20_39, a, b, c, d, e, t, prep0.u32[0]); /* 24 */ - step(20_39, t, a, b, c, d, e, prep0.u32[1]); /* 25 */ - step(20_39, e, t, a, b, c, d, prep0.u32[2]); /* 26 */ - step(20_39, d, e, t, a, b, c, prep0.u32[3]); /* 27 */ - prep(prep0, W1, W2, W3, W0, K20_39); - step(20_39, c, d, e, t, a, b, prep1.u32[0]); /* 28 */ - step(20_39, b, c, d, e, t, a, prep1.u32[1]); /* 29 */ - step(20_39, a, b, c, d, e, t, prep1.u32[2]); /* 30 */ - step(20_39, t, a, b, c, d, e, prep1.u32[3]); /* 31 */ - prep(prep1, W2, W3, W0, W1, K40_59); - step(20_39, e, t, a, b, c, d, prep2.u32[0]); /* 32 */ - step(20_39, d, e, t, a, b, c, prep2.u32[1]); /* 33 */ - step(20_39, c, d, e, t, a, b, prep2.u32[2]); /* 34 */ - step(20_39, b, c, d, e, t, a, prep2.u32[3]); /* 35 */ - prep(prep2, W3, W0, W1, W2, K40_59); - step(20_39, a, b, c, d, e, t, prep0.u32[0]); /* 36 */ - step(20_39, t, a, b, c, d, e, prep0.u32[1]); /* 37 */ - step(20_39, e, t, a, b, c, d, prep0.u32[2]); /* 38 */ - step(20_39, d, e, t, a, b, c, prep0.u32[3]); /* 39 */ - - prep(prep0, W0, W1, W2, W3, K40_59); - step(40_59, c, d, e, t, a, b, prep1.u32[0]); /* 40 */ - step(40_59, b, c, d, e, t, a, prep1.u32[1]); /* 41 */ - step(40_59, a, b, c, d, e, t, prep1.u32[2]); /* 42 */ - step(40_59, t, a, b, c, d, e, prep1.u32[3]); /* 43 */ - prep(prep1, W1, W2, W3, W0, K40_59); - step(40_59, e, t, a, b, c, d, prep2.u32[0]); /* 44 */ - step(40_59, d, e, t, a, b, c, prep2.u32[1]); /* 45 */ - step(40_59, c, d, e, t, a, b, prep2.u32[2]); /* 46 */ - step(40_59, b, c, d, e, t, a, prep2.u32[3]); /* 47 */ - prep(prep2, W2, W3, W0, W1, K40_59); - step(40_59, a, b, c, d, e, t, prep0.u32[0]); /* 48 */ - step(40_59, t, a, b, c, d, e, prep0.u32[1]); /* 49 */ - step(40_59, e, t, a, b, c, d, prep0.u32[2]); /* 50 */ - step(40_59, d, e, t, a, b, c, prep0.u32[3]); /* 51 */ - prep(prep0, W3, W0, W1, W2, K60_79); - step(40_59, c, d, e, t, a, b, prep1.u32[0]); /* 52 */ - step(40_59, b, c, d, e, t, a, prep1.u32[1]); /* 53 */ - step(40_59, a, b, c, d, e, t, prep1.u32[2]); /* 54 */ - step(40_59, t, a, b, c, d, e, prep1.u32[3]); /* 55 */ - prep(prep1, W0, W1, W2, W3, K60_79); - step(40_59, e, t, a, b, c, d, prep2.u32[0]); /* 56 */ - step(40_59, d, e, t, a, b, c, prep2.u32[1]); /* 57 */ - step(40_59, c, d, e, t, a, b, prep2.u32[2]); /* 58 */ - step(40_59, b, c, d, e, t, a, prep2.u32[3]); /* 59 */ - - prep(prep2, W1, W2, W3, W0, K60_79); - step(60_79, a, b, c, d, e, t, prep0.u32[0]); /* 60 */ - step(60_79, t, a, b, c, d, e, prep0.u32[1]); /* 61 */ - step(60_79, e, t, a, b, c, d, prep0.u32[2]); /* 62 */ - step(60_79, d, e, t, a, b, c, prep0.u32[3]); /* 63 */ - prep(prep0, W2, W3, W0, W1, K60_79); - step(60_79, c, d, e, t, a, b, prep1.u32[0]); /* 64 */ - step(60_79, b, c, d, e, t, a, prep1.u32[1]); /* 65 */ - step(60_79, a, b, c, d, e, t, prep1.u32[2]); /* 66 */ - step(60_79, t, a, b, c, d, e, prep1.u32[3]); /* 67 */ - prep(prep1, W3, W0, W1, W2, K60_79); - step(60_79, e, t, a, b, c, d, prep2.u32[0]); /* 68 */ - step(60_79, d, e, t, a, b, c, prep2.u32[1]); /* 69 */ - step(60_79, c, d, e, t, a, b, prep2.u32[2]); /* 70 */ - step(60_79, b, c, d, e, t, a, prep2.u32[3]); /* 71 */ - - step(60_79, a, b, c, d, e, t, prep0.u32[0]); /* 72 */ - step(60_79, t, a, b, c, d, e, prep0.u32[1]); /* 73 */ - step(60_79, e, t, a, b, c, d, prep0.u32[2]); /* 74 */ - step(60_79, d, e, t, a, b, c, prep0.u32[3]); /* 75 */ - /* no more input to prepare */ - step(60_79, c, d, e, t, a, b, prep1.u32[0]); /* 76 */ - step(60_79, b, c, d, e, t, a, prep1.u32[1]); /* 77 */ - step(60_79, a, b, c, d, e, t, prep1.u32[2]); /* 78 */ - step(60_79, t, a, b, c, d, e, prep1.u32[3]); /* 79 */ - /* e, t, a, b, c, d */ - H[0] += e; - H[1] += t; - H[2] += a; - H[3] += b; - H[4] += c; - } - -} -- cgit v1.2.3 From 1419961fbc1ef832940d0f5184c3d71797270ef9 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 07:06:08 +0000 Subject: Clean up prep00_15 - same speed on Core2 --- src/hash/sha1_sse2/sha1_sse2.cpp | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/hash/sha1_sse2/sha1_sse2.cpp b/src/hash/sha1_sse2/sha1_sse2.cpp index cd1b7e97b..fc6466dd0 100644 --- a/src/hash/sha1_sse2/sha1_sse2.cpp +++ b/src/hash/sha1_sse2/sha1_sse2.cpp @@ -17,23 +17,17 @@ namespace Botan { namespace { /* -the first 16 bytes only need byte swapping - -prepared points to 4x u32bit, 16-byte aligned - -W points to the 4 dwords which need preparing -- -and is overwritten with the swapped bytes +First 16 bytes just need byte swapping. Preparing just means +adding in the round constants. */ -#define prep00_15(prep, W) \ - do { \ - __m128i r1 = (W); \ - r1 = _mm_shufflehi_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ - r1 = _mm_shufflelo_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ - __m128i r2 = _mm_slli_epi16(r1, 8); \ - r1 = _mm_srli_epi16(r1, 8); \ - r1 = _mm_or_si128(r1, r2); \ - (W) = r1; \ - (prep).u128 = _mm_add_epi32(K00_19, r1); \ + +#define prep00_15(P, W) \ + do { \ + W = _mm_shufflehi_epi16(W, _MM_SHUFFLE(2, 3, 0, 1)); \ + W = _mm_shufflelo_epi16(W, _MM_SHUFFLE(2, 3, 0, 1)); \ + W = _mm_or_si128(_mm_slli_epi16(W, 8), \ + _mm_srli_epi16(W, 8)); \ + P.u128 = _mm_add_epi32(W, K00_19); \ } while(0) /* -- cgit v1.2.3 From 073f9ebdb1463cac650ddf77ae1c034d79bbb166 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 07:52:39 +0000 Subject: Unroll the expansion loop in both SHA-2 implementations by 8. On a Core2, SHA-256 gets ~7% faster, SHA-512 ~10%. --- src/hash/sha2/sha2_32.cpp | 28 ++++++++++++++++++---------- src/hash/sha2/sha2_64.cpp | 14 +++++++++++--- 2 files changed, 29 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/hash/sha2/sha2_32.cpp b/src/hash/sha2/sha2_32.cpp index 2a63eef25..89efab123 100644 --- a/src/hash/sha2/sha2_32.cpp +++ b/src/hash/sha2/sha2_32.cpp @@ -60,9 +60,17 @@ void SHA_224_256_BASE::compress_n(const byte input[], u32bit blocks) W[j] = load_be(input, j); input += HASH_BLOCK_SIZE; - for(u32bit j = 16; j != 64; ++j) - W[j] = sigma(W[j- 2], 17, 19, 10) + W[j- 7] + - sigma(W[j-15], 7, 18, 3) + W[j-16]; + for(u32bit j = 16; j != 64; j += 8) + { + W[j ] = sigma(W[j-2], 17, 19, 10) + W[j-7] + sigma(W[j-15], 7, 18, 3) + W[j-16]; + W[j+1] = sigma(W[j-1], 17, 19, 10) + W[j-6] + sigma(W[j-14], 7, 18, 3) + W[j-15]; + W[j+2] = sigma(W[j ], 17, 19, 10) + W[j-5] + sigma(W[j-13], 7, 18, 3) + W[j-14]; + W[j+3] = sigma(W[j+1], 17, 19, 10) + W[j-4] + sigma(W[j-12], 7, 18, 3) + W[j-13]; + W[j+4] = sigma(W[j+2], 17, 19, 10) + W[j-3] + sigma(W[j-11], 7, 18, 3) + W[j-12]; + W[j+5] = sigma(W[j+3], 17, 19, 10) + W[j-2] + sigma(W[j-10], 7, 18, 3) + W[j-11]; + W[j+6] = sigma(W[j+4], 17, 19, 10) + W[j-1] + sigma(W[j- 9], 7, 18, 3) + W[j-10]; + W[j+7] = sigma(W[j+5], 17, 19, 10) + W[j ] + sigma(W[j- 8], 7, 18, 3) + W[j- 9]; + } F1(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98); F1(H, A, B, C, D, E, F, G, W[ 1], 0x71374491); @@ -164,14 +172,14 @@ void SHA_224_256_BASE::clear() void SHA_224::clear() { SHA_224_256_BASE::clear(); - digest[0] = 0xc1059ed8; - digest[1] = 0x367cd507; - digest[2] = 0x3070dd17; - digest[3] = 0xf70e5939; - digest[4] = 0xffc00b31; + digest[0] = 0xC1059ED8; + digest[1] = 0x367CD507; + digest[2] = 0x3070DD17; + digest[3] = 0xF70E5939; + digest[4] = 0xFFC00B31; digest[5] = 0x68581511; - digest[6] = 0x64f98fa7; - digest[7] = 0xbefa4fa4; + digest[6] = 0x64F98FA7; + digest[7] = 0xBEFA4FA4; } /* diff --git a/src/hash/sha2/sha2_64.cpp b/src/hash/sha2/sha2_64.cpp index 3c771eb44..e260d8338 100644 --- a/src/hash/sha2/sha2_64.cpp +++ b/src/hash/sha2/sha2_64.cpp @@ -59,9 +59,17 @@ void SHA_384_512_BASE::compress_n(const byte input[], u32bit blocks) W[j] = load_be(input, j); input += HASH_BLOCK_SIZE; - for(u32bit j = 16; j != 80; ++j) - W[j] = sigma(W[j- 2], 19, 61, 6) + W[j- 7] + - sigma(W[j-15], 1, 8, 7) + W[j-16]; + for(u32bit j = 16; j != 80; j += 8) + { + W[j ] = sigma(W[j-2], 19, 61, 6) + W[j-7] + sigma(W[j-15], 1, 8, 7) + W[j-16]; + W[j+1] = sigma(W[j-1], 19, 61, 6) + W[j-6] + sigma(W[j-14], 1, 8, 7) + W[j-15]; + W[j+2] = sigma(W[j ], 19, 61, 6) + W[j-5] + sigma(W[j-13], 1, 8, 7) + W[j-14]; + W[j+3] = sigma(W[j+1], 19, 61, 6) + W[j-4] + sigma(W[j-12], 1, 8, 7) + W[j-13]; + W[j+4] = sigma(W[j+2], 19, 61, 6) + W[j-3] + sigma(W[j-11], 1, 8, 7) + W[j-12]; + W[j+5] = sigma(W[j+3], 19, 61, 6) + W[j-2] + sigma(W[j-10], 1, 8, 7) + W[j-11]; + W[j+6] = sigma(W[j+4], 19, 61, 6) + W[j-1] + sigma(W[j- 9], 1, 8, 7) + W[j-10]; + W[j+7] = sigma(W[j+5], 19, 61, 6) + W[j ] + sigma(W[j- 8], 1, 8, 7) + W[j- 9]; + } F1(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98D728AE22); F1(H, A, B, C, D, E, F, G, W[ 1], 0x7137449123EF65CD); -- cgit v1.2.3 From 0cf1ad7aca8506bbd541641cb1ebc0c73c62bcd2 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 07:54:36 +0000 Subject: Unroll SHA-1's expansion loop from x4 to x8; ~7% faster on Core2 --- src/hash/sha1/sha160.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/hash/sha1/sha160.cpp b/src/hash/sha1/sha160.cpp index a9e6880a7..92f4f5f11 100644 --- a/src/hash/sha1/sha160.cpp +++ b/src/hash/sha1/sha160.cpp @@ -70,12 +70,16 @@ void SHA_160::compress_n(const byte input[], u32bit blocks) } input += HASH_BLOCK_SIZE; - for(u32bit j = 16; j != 80; j += 4) + for(u32bit j = 16; j != 80; j += 8) { W[j ] = rotate_left((W[j-3] ^ W[j-8] ^ W[j-14] ^ W[j-16]), 1); W[j+1] = rotate_left((W[j-2] ^ W[j-7] ^ W[j-13] ^ W[j-15]), 1); W[j+2] = rotate_left((W[j-1] ^ W[j-6] ^ W[j-12] ^ W[j-14]), 1); W[j+3] = rotate_left((W[j ] ^ W[j-5] ^ W[j-11] ^ W[j-13]), 1); + W[j+4] = rotate_left((W[j+1] ^ W[j-4] ^ W[j-10] ^ W[j-12]), 1); + W[j+5] = rotate_left((W[j+2] ^ W[j-3] ^ W[j- 9] ^ W[j-11]), 1); + W[j+6] = rotate_left((W[j+3] ^ W[j-2] ^ W[j- 8] ^ W[j-10]), 1); + W[j+7] = rotate_left((W[j+4] ^ W[j-1] ^ W[j- 7] ^ W[j- 9]), 1); } F1(A,B,C,D,E,W[ 0]); F1(E,A,B,C,D,W[ 1]); F1(D,E,A,B,C,W[ 2]); -- cgit v1.2.3 From 5553c5cf54563280a4ffc94baab7b94a83cb0000 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 08:33:45 +0000 Subject: Fix cpuid with icc (tested with 11.1) Document SHA optimizations, AltiVec runtime checking, fixes for cpuid for both icc and msvc. --- doc/log.txt | 3 +++ src/utils/cpuid.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/doc/log.txt b/doc/log.txt index 84379c3e8..c2728e8db 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -2,6 +2,9 @@ * 1.9.2-dev, ????-??-?? - Add SIMD version of XTEA - Support both SSE2 and AltiVec SIMD for Serpent and XTEA + - Optimizations for SHA-1 and SHA-2 + - Add AltiVec runtime detection + - Fix x86 CPU identification with Intel C++ and Visual C++ * 1.9.1, 2009-10-23 - Better support for Python and Perl wrappers diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index 2d3b5d92c..448054c49 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -17,10 +17,10 @@ #include #define CALL_CPUID(type, out) do { __cpuid((int*)out, type); } while(0) -#elif defined(BOTAN_BUILD_COMPILER_IS_ICC) +#elif defined(BOTAN_BUILD_COMPILER_IS_INTEL) #include - #define CALL_CPUID(type, out) do { __cpuid(out, type) } while(0); + #define CALL_CPUID(type, out) do { __cpuid(out, type); } while(0); #elif defined(BOTAN_BUILD_COMPILER_IS_GCC) -- cgit v1.2.3 From 7462977b8e5eb95a81a6253dc6e6224334ad6ae9 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 17:34:52 +0000 Subject: Add a new looping load_be / load_le for loading large arrays at once, and change some of the hash functions to use it as low hanging fruit. Probably could use further optimization (just unrolls x4 currently), but merely having it as syntax is good as it allows optimizing many functions at once (eg using SSE2 to do 4-way byteswaps). --- src/hash/bmw/bmw_512.cpp | 3 +-- src/hash/has160/has160.cpp | 18 ++++++++++------- src/hash/md4/md4.cpp | 1 + src/hash/md5/md5.cpp | 6 +++--- src/hash/rmd128/rmd128.cpp | 22 +++++++++++---------- src/hash/rmd160/rmd160.cpp | 6 +++--- src/hash/sha1/sha160.cpp | 11 +++-------- src/hash/sha2/sha2_32.cpp | 30 ++++++++++++++++++----------- src/hash/skein/skein_512.cpp | 4 ++-- src/hash/tiger/tiger.cpp | 6 +++--- src/utils/loadstor.h | 46 ++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 104 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/hash/bmw/bmw_512.cpp b/src/hash/bmw/bmw_512.cpp index ae80d5725..5ccb09579 100644 --- a/src/hash/bmw/bmw_512.cpp +++ b/src/hash/bmw/bmw_512.cpp @@ -143,8 +143,7 @@ void BMW_512::compress_n(const byte input[], u32bit blocks) { for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - M[j] = load_le(input, j); + load_le(M.begin(), input, M.size()); BMW_512_compress(H, M, Q); diff --git a/src/hash/has160/has160.cpp b/src/hash/has160/has160.cpp index 533efe595..ae45418ce 100644 --- a/src/hash/has160/has160.cpp +++ b/src/hash/has160/has160.cpp @@ -60,13 +60,12 @@ inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, */ void HAS_160::compress_n(const byte input[], u32bit blocks) { + u32bit A = digest[0], B = digest[1], C = digest[2], + D = digest[3], E = digest[4]; + for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - X[j] = load_le(input, j); - - u32bit A = digest[0], B = digest[1], C = digest[2], - D = digest[3], E = digest[4]; + load_le(X.begin(), input, 16); X[16] = X[ 0] ^ X[ 1] ^ X[ 2] ^ X[ 3]; X[17] = X[ 4] ^ X[ 5] ^ X[ 6] ^ X[ 7]; @@ -128,8 +127,13 @@ void HAS_160::compress_n(const byte input[], u32bit blocks) F4(E,A,B,C,D,X[11], 9); F4(D,E,A,B,C,X[ 6],14); F4(C,D,E,A,B,X[ 1], 5); F4(B,C,D,E,A,X[12],13); - digest[0] += A; digest[1] += B; digest[2] += C; - digest[3] += D; digest[4] += E; + A = (digest[0] += A); + B = (digest[1] += B); + C = (digest[2] += C); + D = (digest[3] += D); + E = (digest[4] += E); + + input += HASH_BLOCK_SIZE; } } diff --git a/src/hash/md4/md4.cpp b/src/hash/md4/md4.cpp index b2870066d..c50c73a8d 100644 --- a/src/hash/md4/md4.cpp +++ b/src/hash/md4/md4.cpp @@ -51,6 +51,7 @@ void MD4::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { + //load_le(M.begin(), input, M.size()); for(u32bit j = 0; j != 16; ++j) M[j] = load_le(input, j); input += HASH_BLOCK_SIZE; diff --git a/src/hash/md5/md5.cpp b/src/hash/md5/md5.cpp index 163413bec..8c1e5a8e1 100644 --- a/src/hash/md5/md5.cpp +++ b/src/hash/md5/md5.cpp @@ -64,9 +64,7 @@ void MD5::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - M[j] = load_le(input, j); - input += HASH_BLOCK_SIZE; + load_le(M.begin(), input, M.size()); FF(A,B,C,D,M[ 0], 7,0xD76AA478); FF(D,A,B,C,M[ 1],12,0xE8C7B756); FF(C,D,A,B,M[ 2],17,0x242070DB); FF(B,C,D,A,M[ 3],22,0xC1BDCEEE); @@ -108,6 +106,8 @@ void MD5::compress_n(const byte input[], u32bit blocks) B = (digest[1] += B); C = (digest[2] += C); D = (digest[3] += D); + + input += HASH_BLOCK_SIZE; } } diff --git a/src/hash/rmd128/rmd128.cpp b/src/hash/rmd128/rmd128.cpp index 899e50914..7e9da3bdd 100644 --- a/src/hash/rmd128/rmd128.cpp +++ b/src/hash/rmd128/rmd128.cpp @@ -60,18 +60,16 @@ inline void F4(u32bit& A, u32bit B, u32bit C, u32bit D, */ void RIPEMD_128::compress_n(const byte input[], u32bit blocks) { + const u32bit MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1, + MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0x50A28BE6, + MAGIC6 = 0x5C4DD124, MAGIC7 = 0x6D703EF3; + for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - M[j] = load_le(input, j); - input += HASH_BLOCK_SIZE; + load_le(M.begin(), input, M.size()); u32bit A1 = digest[0], A2 = A1, B1 = digest[1], B2 = B1, - C1 = digest[2], C2 = C1, D1 = digest[3], D2 = D1; - - const u32bit MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1, - MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0x50A28BE6, - MAGIC6 = 0x5C4DD124, MAGIC7 = 0x6D703EF3; + C1 = digest[2], C2 = C1, D1 = digest[3], D2 = D1; F1(A1,B1,C1,D1,M[ 0],11 ); F4(A2,B2,C2,D2,M[ 5], 8,MAGIC5); F1(D1,A1,B1,C1,M[ 1],14 ); F4(D2,A2,B2,C2,M[14], 9,MAGIC5); @@ -141,9 +139,13 @@ void RIPEMD_128::compress_n(const byte input[], u32bit blocks) F4(C1,D1,A1,B1,M[ 6], 5,MAGIC4); F1(C2,D2,A2,B2,M[10],15 ); F4(B1,C1,D1,A1,M[ 2],12,MAGIC4); F1(B2,C2,D2,A2,M[14], 8 ); - D2 = digest[1] + C1 + D2; digest[1] = digest[2] + D1 + A2; - digest[2] = digest[3] + A1 + B2; digest[3] = digest[0] + B1 + C2; + D2 = digest[1] + C1 + D2; + digest[1] = digest[2] + D1 + A2; + digest[2] = digest[3] + A1 + B2; + digest[3] = digest[0] + B1 + C2; digest[0] = D2; + + input += HASH_BLOCK_SIZE; } } diff --git a/src/hash/rmd160/rmd160.cpp b/src/hash/rmd160/rmd160.cpp index 2baf5ab08..5237f1e12 100644 --- a/src/hash/rmd160/rmd160.cpp +++ b/src/hash/rmd160/rmd160.cpp @@ -82,9 +82,7 @@ void RIPEMD_160::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - M[j] = load_le(input, j); - input += HASH_BLOCK_SIZE; + load_le(M.begin(), input, M.size()); u32bit A1 = digest[0], A2 = A1, B1 = digest[1], B2 = B1, C1 = digest[2], C2 = C1, D1 = digest[3], D2 = D1, @@ -181,6 +179,8 @@ void RIPEMD_160::compress_n(const byte input[], u32bit blocks) digest[3] = digest[4] + A1 + B2; digest[4] = digest[0] + B1 + C2; digest[0] = C1; + + input += HASH_BLOCK_SIZE; } } diff --git a/src/hash/sha1/sha160.cpp b/src/hash/sha1/sha160.cpp index 88f2161e2..ff44593f6 100644 --- a/src/hash/sha1/sha160.cpp +++ b/src/hash/sha1/sha160.cpp @@ -61,14 +61,7 @@ void SHA_160::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; j += 4) - { - W[j ] = load_be(input, j); - W[j+1] = load_be(input, j+1); - W[j+2] = load_be(input, j+2); - W[j+3] = load_be(input, j+3); - } - input += HASH_BLOCK_SIZE; + load_be(W.begin(), input, 16); for(u32bit j = 16; j != 80; j += 8) { @@ -131,6 +124,8 @@ void SHA_160::compress_n(const byte input[], u32bit blocks) C = (digest[2] += C); D = (digest[3] += D); E = (digest[4] += E); + + input += HASH_BLOCK_SIZE; } } diff --git a/src/hash/sha2/sha2_32.cpp b/src/hash/sha2/sha2_32.cpp index 89efab123..7068dd63f 100644 --- a/src/hash/sha2/sha2_32.cpp +++ b/src/hash/sha2/sha2_32.cpp @@ -56,20 +56,26 @@ void SHA_224_256_BASE::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - W[j] = load_be(input, j); - input += HASH_BLOCK_SIZE; + load_be(W.begin(), input, 16); for(u32bit j = 16; j != 64; j += 8) { - W[j ] = sigma(W[j-2], 17, 19, 10) + W[j-7] + sigma(W[j-15], 7, 18, 3) + W[j-16]; - W[j+1] = sigma(W[j-1], 17, 19, 10) + W[j-6] + sigma(W[j-14], 7, 18, 3) + W[j-15]; - W[j+2] = sigma(W[j ], 17, 19, 10) + W[j-5] + sigma(W[j-13], 7, 18, 3) + W[j-14]; - W[j+3] = sigma(W[j+1], 17, 19, 10) + W[j-4] + sigma(W[j-12], 7, 18, 3) + W[j-13]; - W[j+4] = sigma(W[j+2], 17, 19, 10) + W[j-3] + sigma(W[j-11], 7, 18, 3) + W[j-12]; - W[j+5] = sigma(W[j+3], 17, 19, 10) + W[j-2] + sigma(W[j-10], 7, 18, 3) + W[j-11]; - W[j+6] = sigma(W[j+4], 17, 19, 10) + W[j-1] + sigma(W[j- 9], 7, 18, 3) + W[j-10]; - W[j+7] = sigma(W[j+5], 17, 19, 10) + W[j ] + sigma(W[j- 8], 7, 18, 3) + W[j- 9]; + W[j ] = sigma(W[j- 2], 17, 19, 10) + W[j-7] + + sigma(W[j-15], 7, 18, 3) + W[j-16]; + W[j+1] = sigma(W[j- 1], 17, 19, 10) + W[j-6] + + sigma(W[j-14], 7, 18, 3) + W[j-15]; + W[j+2] = sigma(W[j ], 17, 19, 10) + W[j-5] + + sigma(W[j-13], 7, 18, 3) + W[j-14]; + W[j+3] = sigma(W[j+ 1], 17, 19, 10) + W[j-4] + + sigma(W[j-12], 7, 18, 3) + W[j-13]; + W[j+4] = sigma(W[j+ 2], 17, 19, 10) + W[j-3] + + sigma(W[j-11], 7, 18, 3) + W[j-12]; + W[j+5] = sigma(W[j+ 3], 17, 19, 10) + W[j-2] + + sigma(W[j-10], 7, 18, 3) + W[j-11]; + W[j+6] = sigma(W[j+ 4], 17, 19, 10) + W[j-1] + + sigma(W[j- 9], 7, 18, 3) + W[j-10]; + W[j+7] = sigma(W[j+ 5], 17, 19, 10) + W[j ] + + sigma(W[j- 8], 7, 18, 3) + W[j- 9]; } F1(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98); @@ -145,6 +151,8 @@ void SHA_224_256_BASE::compress_n(const byte input[], u32bit blocks) F = (digest[5] += F); G = (digest[6] += G); H = (digest[7] += H); + + input += HASH_BLOCK_SIZE; } } diff --git a/src/hash/skein/skein_512.cpp b/src/hash/skein/skein_512.cpp index b24efd5f7..e1ca08c15 100644 --- a/src/hash/skein/skein_512.cpp +++ b/src/hash/skein/skein_512.cpp @@ -34,8 +34,8 @@ void ubi_512(u64bit H[9], u64bit T[], const byte msg[], u64bit msg_len) T[0] += to_proc; u64bit M[8] = { 0 }; - for(u32bit j = 0; j != to_proc / 8; ++j) - M[j] = load_le(msg, j); + + load_le(M, msg, to_proc / 8); if(to_proc % 8) { diff --git a/src/hash/tiger/tiger.cpp b/src/hash/tiger/tiger.cpp index 975ea9b6b..4f4d4dc83 100644 --- a/src/hash/tiger/tiger.cpp +++ b/src/hash/tiger/tiger.cpp @@ -21,9 +21,7 @@ void Tiger::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 8; ++j) - X[j] = load_le(input, j); - input += HASH_BLOCK_SIZE; + load_le(X.begin(), input, X.size()); pass(A, B, C, X, 5); mix(X); pass(C, A, B, X, 7); mix(X); @@ -39,6 +37,8 @@ void Tiger::compress_n(const byte input[], u32bit blocks) A = (digest[0] ^= A); B = digest[1] = B - digest[1]; C = (digest[2] += C); + + input += HASH_BLOCK_SIZE; } } diff --git a/src/utils/loadstor.h b/src/utils/loadstor.h index 6f91c2fa5..8f430f36c 100644 --- a/src/utils/loadstor.h +++ b/src/utils/loadstor.h @@ -198,6 +198,29 @@ inline void load_le(const byte in[], x7 = load_le(in, 7); } +template +inline void load_le(T out[], + const byte in[], + u32bit count) + { + const u32bit blocks = count - (count % 4); + const u32bit left = count - blocks; + + for(u32bit i = 0; i != blocks; i += 4) + { + out[0] = load_le(in, 0); + out[1] = load_le(in, 1); + out[2] = load_le(in, 2); + out[3] = load_le(in, 3); + + out += 4; + in += 4*sizeof(T); + } + + for(u32bit i = 0; i != left; ++i) + out[i] = load_le(in, i); + } + template inline void load_be(const byte in[], T& x0, T& x1) { @@ -230,6 +253,29 @@ inline void load_be(const byte in[], x7 = load_be(in, 7); } +template +inline void load_be(T out[], + const byte in[], + u32bit count) + { + const u32bit blocks = count - (count % 4); + const u32bit left = count - blocks; + + for(u32bit i = 0; i != blocks; i += 4) + { + out[0] = load_be(in, 0); + out[1] = load_be(in, 1); + out[2] = load_be(in, 2); + out[3] = load_be(in, 3); + + out += 4; + in += 4*sizeof(T); + } + + for(u32bit i = 0; i != left; ++i) + out[i] = load_be(in, i); + } + /* * Endian-Specific Word Storing Operations */ -- cgit v1.2.3 From 6b617a55bd02bcc4fdb6f76af92e0cb65fd838a2 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 29 Oct 2009 17:47:55 +0000 Subject: Slight cleanups in the Altivec detection code for readability. --- src/utils/cpuid.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index 448054c49..2ba7f9b77 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -122,22 +122,29 @@ bool CPUID::has_altivec() // Motorola produced G4s with PVR 0x800[0123C] (at least) const u16bit PVR_G4_74xx_24 = 0x800; - u32bit pvr = 0; /* On PowerPC, MSR 287 is PVR, the Processor Version Number Normally it is only accessible to ring 0, but Linux and NetBSD (at least) will trap and emulate it for us. This is roughly 20x - saner than every other approach I've seen for this (all of which - are entirely OS specific, to boot). + saner than every other approach I've seen for AltiVec detection + (all of which are entirely OS specific, to boot). Apparently OS X doesn't support this, but then again OS X doesn't really support PPC anymore, so I'm not worrying about it. - For OSes that aren't (known to) support the emulation, leave pvr - as 0 which will cause all subsequent model number checks to fail. + For OSes that aren't (known to) support the emulation, skip the + call, leaving pvr as 0 which will cause all subsequent model + number checks to fail (and we'll assume no AltiVec) */ + #if defined(BOTAN_TARGET_OS_IS_LINUX) || defined(BOTAN_TARGET_OS_IS_NETBSD) + #define BOTAN_TARGET_OS_SUPPORTS_MFSPR_EMUL +#endif + + u32bit pvr = 0; + +#if defined(BOTAN_TARGET_OS_SUPPORTS_MFSPR_EMUL) asm volatile("mfspr %0, 287" : "=r" (pvr)); #endif // Top 16 bit suffice to identify model -- cgit v1.2.3 From fa8a8437b9ce3b5275133230708af0964427651a Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 3 Nov 2009 16:47:11 +0000 Subject: Conver the rest of the hash functions to use the array-based load instructions. I'm not totally happy with this - in particular in all cases the size is a compile time constant - it would be nice to make use of this via tempalate metaprogramming. Also for matching endian loads, a straight memcpy would do the work, which would probably be even faster. --- src/hash/fork256/fork256.cpp | 6 ++--- src/hash/gost_3411/gost_3411.cpp | 8 ++---- src/hash/md4/md4.cpp | 55 ++++++++++++++++++++++------------------ src/hash/sha2/sha2_64.cpp | 6 ++--- src/hash/whirlpool/whrlpool.cpp | 6 ++--- 5 files changed, 41 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/hash/fork256/fork256.cpp b/src/hash/fork256/fork256.cpp index 6718f9f97..bd85dfd7c 100644 --- a/src/hash/fork256/fork256.cpp +++ b/src/hash/fork256/fork256.cpp @@ -66,9 +66,7 @@ void FORK_256::compress_n(const byte input[], u32bit blocks) G1 = G2 = G3 = G4 = digest[6]; H1 = H2 = H3 = H4 = digest[7]; - for(u32bit j = 0; j != 16; ++j) - M[j] = load_be(input, j); - input += HASH_BLOCK_SIZE; + load_be(M.begin(), input, M.size()); step(A1, B1, C1, D1, E1, F1, G1, H1, M[ 0], M[ 1], DELTA[ 0], DELTA[ 1]); step(A2, B2, C2, D2, E2, F2, G2, H2, M[14], M[15], DELTA[15], DELTA[14]); @@ -118,6 +116,8 @@ void FORK_256::compress_n(const byte input[], u32bit blocks) digest[5] += (F1 + F2) ^ (F3 + F4); digest[6] += (G1 + G2) ^ (G3 + G4); digest[7] += (H1 + H2) ^ (H3 + H4); + + input += HASH_BLOCK_SIZE; } } diff --git a/src/hash/gost_3411/gost_3411.cpp b/src/hash/gost_3411/gost_3411.cpp index 90ef3e805..16b1311da 100644 --- a/src/hash/gost_3411/gost_3411.cpp +++ b/src/hash/gost_3411/gost_3411.cpp @@ -79,12 +79,8 @@ void GOST_34_11::compress_n(const byte input[], u32bit blocks) byte S[32] = { 0 }; u64bit U[4], V[4]; - - for(u32bit j = 0; j != 4; ++j) - { - U[j] = load_be(hash, j); - V[j] = load_be(input + 32*i, j); - } + load_be(U, hash, 4); + load_be(V, input + 32*i, 4); for(u32bit j = 0; j != 4; ++j) { diff --git a/src/hash/md4/md4.cpp b/src/hash/md4/md4.cpp index c50c73a8d..f573dae25 100644 --- a/src/hash/md4/md4.cpp +++ b/src/hash/md4/md4.cpp @@ -51,36 +51,41 @@ void MD4::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - //load_le(M.begin(), input, M.size()); - for(u32bit j = 0; j != 16; ++j) - M[j] = load_le(input, j); - input += HASH_BLOCK_SIZE; - - FF(A,B,C,D,M[ 0], 3); FF(D,A,B,C,M[ 1], 7); FF(C,D,A,B,M[ 2],11); - FF(B,C,D,A,M[ 3],19); FF(A,B,C,D,M[ 4], 3); FF(D,A,B,C,M[ 5], 7); - FF(C,D,A,B,M[ 6],11); FF(B,C,D,A,M[ 7],19); FF(A,B,C,D,M[ 8], 3); - FF(D,A,B,C,M[ 9], 7); FF(C,D,A,B,M[10],11); FF(B,C,D,A,M[11],19); - FF(A,B,C,D,M[12], 3); FF(D,A,B,C,M[13], 7); FF(C,D,A,B,M[14],11); - FF(B,C,D,A,M[15],19); - - GG(A,B,C,D,M[ 0], 3); GG(D,A,B,C,M[ 4], 5); GG(C,D,A,B,M[ 8], 9); - GG(B,C,D,A,M[12],13); GG(A,B,C,D,M[ 1], 3); GG(D,A,B,C,M[ 5], 5); - GG(C,D,A,B,M[ 9], 9); GG(B,C,D,A,M[13],13); GG(A,B,C,D,M[ 2], 3); - GG(D,A,B,C,M[ 6], 5); GG(C,D,A,B,M[10], 9); GG(B,C,D,A,M[14],13); - GG(A,B,C,D,M[ 3], 3); GG(D,A,B,C,M[ 7], 5); GG(C,D,A,B,M[11], 9); - GG(B,C,D,A,M[15],13); - - HH(A,B,C,D,M[ 0], 3); HH(D,A,B,C,M[ 8], 9); HH(C,D,A,B,M[ 4],11); - HH(B,C,D,A,M[12],15); HH(A,B,C,D,M[ 2], 3); HH(D,A,B,C,M[10], 9); - HH(C,D,A,B,M[ 6],11); HH(B,C,D,A,M[14],15); HH(A,B,C,D,M[ 1], 3); - HH(D,A,B,C,M[ 9], 9); HH(C,D,A,B,M[ 5],11); HH(B,C,D,A,M[13],15); - HH(A,B,C,D,M[ 3], 3); HH(D,A,B,C,M[11], 9); HH(C,D,A,B,M[ 7],11); - HH(B,C,D,A,M[15],15); + load_le(M.begin(), input, M.size()); + + FF(A,B,C,D,M[ 0], 3); FF(D,A,B,C,M[ 1], 7); + FF(C,D,A,B,M[ 2],11); FF(B,C,D,A,M[ 3],19); + FF(A,B,C,D,M[ 4], 3); FF(D,A,B,C,M[ 5], 7); + FF(C,D,A,B,M[ 6],11); FF(B,C,D,A,M[ 7],19); + FF(A,B,C,D,M[ 8], 3); FF(D,A,B,C,M[ 9], 7); + FF(C,D,A,B,M[10],11); FF(B,C,D,A,M[11],19); + FF(A,B,C,D,M[12], 3); FF(D,A,B,C,M[13], 7); + FF(C,D,A,B,M[14],11); FF(B,C,D,A,M[15],19); + + GG(A,B,C,D,M[ 0], 3); GG(D,A,B,C,M[ 4], 5); + GG(C,D,A,B,M[ 8], 9); GG(B,C,D,A,M[12],13); + GG(A,B,C,D,M[ 1], 3); GG(D,A,B,C,M[ 5], 5); + GG(C,D,A,B,M[ 9], 9); GG(B,C,D,A,M[13],13); + GG(A,B,C,D,M[ 2], 3); GG(D,A,B,C,M[ 6], 5); + GG(C,D,A,B,M[10], 9); GG(B,C,D,A,M[14],13); + GG(A,B,C,D,M[ 3], 3); GG(D,A,B,C,M[ 7], 5); + GG(C,D,A,B,M[11], 9); GG(B,C,D,A,M[15],13); + + HH(A,B,C,D,M[ 0], 3); HH(D,A,B,C,M[ 8], 9); + HH(C,D,A,B,M[ 4],11); HH(B,C,D,A,M[12],15); + HH(A,B,C,D,M[ 2], 3); HH(D,A,B,C,M[10], 9); + HH(C,D,A,B,M[ 6],11); HH(B,C,D,A,M[14],15); + HH(A,B,C,D,M[ 1], 3); HH(D,A,B,C,M[ 9], 9); + HH(C,D,A,B,M[ 5],11); HH(B,C,D,A,M[13],15); + HH(A,B,C,D,M[ 3], 3); HH(D,A,B,C,M[11], 9); + HH(C,D,A,B,M[ 7],11); HH(B,C,D,A,M[15],15); A = (digest[0] += A); B = (digest[1] += B); C = (digest[2] += C); D = (digest[3] += D); + + input += HASH_BLOCK_SIZE; } } diff --git a/src/hash/sha2/sha2_64.cpp b/src/hash/sha2/sha2_64.cpp index e260d8338..3e7c0e228 100644 --- a/src/hash/sha2/sha2_64.cpp +++ b/src/hash/sha2/sha2_64.cpp @@ -55,9 +55,7 @@ void SHA_384_512_BASE::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - W[j] = load_be(input, j); - input += HASH_BLOCK_SIZE; + load_be(W.begin(), input, 16); for(u32bit j = 16; j != 80; j += 8) { @@ -160,6 +158,8 @@ void SHA_384_512_BASE::compress_n(const byte input[], u32bit blocks) F = (digest[5] += F); G = (digest[6] += G); H = (digest[7] += H); + + input += HASH_BLOCK_SIZE; } } diff --git a/src/hash/whirlpool/whrlpool.cpp b/src/hash/whirlpool/whrlpool.cpp index b7a02a9b6..06755fe77 100644 --- a/src/hash/whirlpool/whrlpool.cpp +++ b/src/hash/whirlpool/whrlpool.cpp @@ -25,9 +25,7 @@ void Whirlpool::compress_n(const byte in[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 8; ++j) - M[j] = load_be(in, j); - in += HASH_BLOCK_SIZE; + load_be(M.begin(), in, M.size()); u64bit K0, K1, K2, K3, K4, K5, K6, K7; K0 = digest[0]; K1 = digest[1]; K2 = digest[2]; K3 = digest[3]; @@ -121,6 +119,8 @@ void Whirlpool::compress_n(const byte in[], u32bit blocks) digest[5] ^= B5 ^ M[5]; digest[6] ^= B6 ^ M[6]; digest[7] ^= B7 ^ M[7]; + + in += HASH_BLOCK_SIZE; } } -- cgit v1.2.3