From fde29acbeb656bcffe13b91f08f847eee4509670 Mon Sep 17 00:00:00 2001 From: lloyd Date: Sun, 28 Sep 2008 19:58:49 +0000 Subject: Make mdx_hash also a module, which most of the hash functions depend on. Correct the configure program so modules are not autoloaded if their dependences are not available. (Eg, --no-module=mdx_hash will disable MD4, MD5, SHA-1, etc rather than cause a compliation failure) --- configure.pl | 30 ++-- include/mdx_hash.h | 40 ----- src/asm/sha1_sse2/modinfo.txt | 22 --- src/asm/sha1_sse2/sha160.cpp | 52 ------- src/asm/sha1_sse2/sha160.h | 32 ---- src/asm/sha1_sse2/sha1core.cpp | 327 ---------------------------------------- src/hash/fork256/modinfo.txt | 4 + src/hash/has160/modinfo.txt | 4 + src/hash/md4/modinfo.txt | 4 + src/hash/md5/modinfo.txt | 4 + src/hash/mdx_hash/mdx_hash.cpp | 102 +++++++++++++ src/hash/mdx_hash/mdx_hash.h | 40 +++++ src/hash/rmd128/modinfo.txt | 4 + src/hash/rmd160/modinfo.txt | 4 + src/hash/sha1/modinfo.txt | 4 + src/hash/sha1_sse2/modinfo.txt | 19 +++ src/hash/sha1_sse2/sha160.cpp | 52 +++++++ src/hash/sha1_sse2/sha160.h | 32 ++++ src/hash/sha1_sse2/sha1_sse.cpp | 327 ++++++++++++++++++++++++++++++++++++++++ src/hash/sha2/modinfo.txt | 4 + src/hash/tiger/modinfo.txt | 4 + src/hash/whirlpool/modinfo.txt | 4 + src/mdx_hash.cpp | 102 ------------- 23 files changed, 630 insertions(+), 587 deletions(-) delete mode 100644 include/mdx_hash.h delete mode 100644 src/asm/sha1_sse2/modinfo.txt delete mode 100644 src/asm/sha1_sse2/sha160.cpp delete mode 100644 src/asm/sha1_sse2/sha160.h delete mode 100644 src/asm/sha1_sse2/sha1core.cpp create mode 100644 src/hash/mdx_hash/mdx_hash.cpp create mode 100644 src/hash/mdx_hash/mdx_hash.h create mode 100644 src/hash/sha1_sse2/modinfo.txt create mode 100644 src/hash/sha1_sse2/sha160.cpp create mode 100644 src/hash/sha1_sse2/sha160.h create mode 100644 src/hash/sha1_sse2/sha1_sse.cpp delete mode 100644 src/mdx_hash.cpp diff --git a/configure.pl b/configure.pl index a20125391..200f6683c 100755 --- a/configure.pl +++ b/configure.pl @@ -417,15 +417,12 @@ sub autoload_modules { my $asm_ok = $$config{'asm_ok'}; - foreach my $mod (sort keys %MODULES) { + MOD: foreach my $mod (sort keys %MODULES) { my %modinfo = %{ $MODULES{$mod} }; - trace("Loading $mod"); - my $realname = $modinfo{'realname'}; if(defined($$config{'modules'}{$mod})) { - my $n = $$config{'modules'}{$mod}; if($n < 0) { @@ -438,6 +435,23 @@ sub autoload_modules { } } + foreach my $req_mod (@{$modinfo{'requires'}}) { + if(defined($$config{'modules'}{$req_mod})) { + if($$config{'modules'}{$req_mod} < 0) { + autoconfig("Disabling $mod since required module " . + "$req_mod is disabled"); + + $$config{'modules'}{$mod} = -1; + next MOD; + } + + } else { + autoconfig("Enabling module $req_mod - required by $mod"); + $$config{'modules'}{$req_mod} = 1; + load_module($config, $req_mod); + } + } + my @arch_list = @{ $modinfo{'arch'} }; if(scalar @arch_list > 0 && !in_array($arch, \@arch_list) && @@ -997,14 +1011,6 @@ sub load_modules { load_module($config, $mod); - foreach my $req_mod (@{$MODULES{$mod}{'requires'}}) { - unless(defined($$config{'modules'}{$req_mod})) { - autoconfig("Module $req_mod - required by $mod"); - $$config{'modules'}{$req_mod} = 1; - load_module($config, $req_mod); - } - } - push @mod_names, $mod; } diff --git a/include/mdx_hash.h b/include/mdx_hash.h deleted file mode 100644 index 84f92493b..000000000 --- a/include/mdx_hash.h +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************* -* MDx Hash Function Header File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#ifndef BOTAN_MDX_BASE_H__ -#define BOTAN_MDX_BASE_H__ - -#include - -namespace Botan { - -/************************************************* -* MDx Hash Function Base Class * -*************************************************/ -class BOTAN_DLL MDx_HashFunction : public HashFunction - { - public: - MDx_HashFunction(u32bit, u32bit, bool, bool, u32bit = 8); - virtual ~MDx_HashFunction() {} - protected: - void clear() throw(); - SecureVector buffer; - u64bit count; - u32bit position; - private: - void add_data(const byte[], u32bit); - void final_result(byte output[]); - - virtual void hash(const byte[]) = 0; - virtual void copy_out(byte[]) = 0; - virtual void write_count(byte[]); - - const bool BIG_BYTE_ENDIAN, BIG_BIT_ENDIAN; - const u32bit COUNT_SIZE; - }; - -} - -#endif diff --git a/src/asm/sha1_sse2/modinfo.txt b/src/asm/sha1_sse2/modinfo.txt deleted file mode 100644 index e1805260c..000000000 --- a/src/asm/sha1_sse2/modinfo.txt +++ /dev/null @@ -1,22 +0,0 @@ -realname "SSE2 implementation of SHA-1" - -load_on request - - -sha160.cpp -sha160.h - - - -sha1core.cpp - - - -pentium4 -amd64 - - - -gcc -icc - diff --git a/src/asm/sha1_sse2/sha160.cpp b/src/asm/sha1_sse2/sha160.cpp deleted file mode 100644 index dfb5fdfe5..000000000 --- a/src/asm/sha1_sse2/sha160.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************* -* SHA-160 Source File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include -#include -#include - -namespace Botan { - -extern "C" void botan_sha1_sse(u32bit[5], const byte[64]); - -/************************************************* -* SHA-160 Compression Function * -*************************************************/ -void SHA_160::hash(const byte input[]) - { - botan_sha1_sse(digest, input); - } - -/************************************************* -* Copy out the digest * -*************************************************/ -void SHA_160::copy_out(byte output[]) - { - for(u32bit j = 0; j != OUTPUT_LENGTH; ++j) - output[j] = get_byte(j % 4, digest[j/4]); - } - -/************************************************* -* Clear memory of sensitive data * -*************************************************/ -void SHA_160::clear() throw() - { - MDx_HashFunction::clear(); - digest[0] = 0x67452301; - digest[1] = 0xEFCDAB89; - digest[2] = 0x98BADCFE; - digest[3] = 0x10325476; - digest[4] = 0xC3D2E1F0; - } - -/************************************************* -* SHA_160 Constructor * -*************************************************/ -SHA_160::SHA_160() : MDx_HashFunction(20, 64, true, true) - { - clear(); - } - -} diff --git a/src/asm/sha1_sse2/sha160.h b/src/asm/sha1_sse2/sha160.h deleted file mode 100644 index c6f8482cf..000000000 --- a/src/asm/sha1_sse2/sha160.h +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************* -* SHA-160 Header File * -* (C) 1999-2007 The Botan Project * -*************************************************/ - -#ifndef BOTAN_SHA_160_H__ -#define BOTAN_SHA_160_H__ - -#include - -namespace Botan { - -/************************************************* -* SHA-160 * -*************************************************/ -class SHA_160 : public MDx_HashFunction - { - public: - void clear() throw(); - std::string name() const { return "SHA-160"; } - HashFunction* clone() const { return new SHA_160; } - SHA_160(); - private: - void hash(const byte[]); - void copy_out(byte[]); - - SecureBuffer digest; - }; - -} - -#endif diff --git a/src/asm/sha1_sse2/sha1core.cpp b/src/asm/sha1_sse2/sha1core.cpp deleted file mode 100644 index 23dbfc5e2..000000000 --- a/src/asm/sha1_sse2/sha1core.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* 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. - * - */ -#include -#include - -namespace Botan { - -typedef union { - u32bit u32[4]; - __m128i u128; - } v4si __attribute__((aligned(16))); - -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 - -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); \ - 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: - -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 rol(u32bit src, u32bit amt) - { - /* gcc and icc appear to turn this into a rotate */ - return (src << amt) | (src >> (32 - amt)); - } - - -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) = rol((xb), 30); \ - (xt) += ((xe) + rol((xa), 5)); \ - } while(0) - -extern "C" void botan_sha1_sse(u32bit* H, - 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]; - - /* 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 = load(&input[0]); - prep00_15(prep0, W0); /* prepare for 00 through 03 */ - W1 = load(&input[1]); - prep00_15(prep1, W1); /* prepare for 04 through 07 */ - W2 = load(&input[2]); - prep00_15(prep2, W2); /* prepare for 08 through 11 */ - - W3 = load(&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; - } - -} diff --git a/src/hash/fork256/modinfo.txt b/src/hash/fork256/modinfo.txt index 677834b63..ae0c9f1a4 100644 --- a/src/hash/fork256/modinfo.txt +++ b/src/hash/fork256/modinfo.txt @@ -8,3 +8,7 @@ load_on auto fork256.cpp fork256.h + + +mdx_hash + diff --git a/src/hash/has160/modinfo.txt b/src/hash/has160/modinfo.txt index 7574ba293..a945f3225 100644 --- a/src/hash/has160/modinfo.txt +++ b/src/hash/has160/modinfo.txt @@ -8,3 +8,7 @@ load_on auto has160.cpp has160.h + + +mdx_hash + diff --git a/src/hash/md4/modinfo.txt b/src/hash/md4/modinfo.txt index 6d32dbd90..fc9cbe116 100644 --- a/src/hash/md4/modinfo.txt +++ b/src/hash/md4/modinfo.txt @@ -8,3 +8,7 @@ load_on auto md4.cpp md4.h + + +mdx_hash + diff --git a/src/hash/md5/modinfo.txt b/src/hash/md5/modinfo.txt index fb17add4a..525a45ab5 100644 --- a/src/hash/md5/modinfo.txt +++ b/src/hash/md5/modinfo.txt @@ -8,3 +8,7 @@ load_on auto md5.cpp md5.h + + +mdx_hash + diff --git a/src/hash/mdx_hash/mdx_hash.cpp b/src/hash/mdx_hash/mdx_hash.cpp new file mode 100644 index 000000000..96b885d87 --- /dev/null +++ b/src/hash/mdx_hash/mdx_hash.cpp @@ -0,0 +1,102 @@ +/************************************************* +* MDx Hash Function Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include +#include + +namespace Botan { + +/************************************************* +* MDx_HashFunction Constructor * +*************************************************/ +MDx_HashFunction::MDx_HashFunction(u32bit hash_len, u32bit block_len, + bool byte_end, bool bit_end, + u32bit cnt_size) : + HashFunction(hash_len, block_len), buffer(block_len), + BIG_BYTE_ENDIAN(byte_end), BIG_BIT_ENDIAN(bit_end), COUNT_SIZE(cnt_size) + { + if(COUNT_SIZE >= OUTPUT_LENGTH || COUNT_SIZE >= HASH_BLOCK_SIZE) + throw Invalid_Argument("MDx_HashFunction: COUNT_SIZE is too big"); + count = position = 0; + } + +/************************************************* +* Clear memory of sensitive data * +*************************************************/ +void MDx_HashFunction::clear() throw() + { + buffer.clear(); + count = position = 0; + } + +/************************************************* +* Update the hash * +*************************************************/ +void MDx_HashFunction::add_data(const byte input[], u32bit length) + { + count += length; + + if(position) + { + buffer.copy(position, input, length); + + if(position + length >= HASH_BLOCK_SIZE) + { + hash(buffer.begin()); + input += (HASH_BLOCK_SIZE - position); + length -= (HASH_BLOCK_SIZE - position); + position = 0; + } + } + + while(length >= HASH_BLOCK_SIZE) + { + hash(input); + input += HASH_BLOCK_SIZE; + length -= HASH_BLOCK_SIZE; + } + + buffer.copy(position, input, length); + + position += length; + } + +/************************************************* +* Finalize a Hash * +*************************************************/ +void MDx_HashFunction::final_result(byte output[]) + { + buffer[position] = (BIG_BIT_ENDIAN ? 0x80 : 0x01); + for(u32bit j = position+1; j != HASH_BLOCK_SIZE; ++j) + buffer[j] = 0; + if(position >= HASH_BLOCK_SIZE - COUNT_SIZE) + { + hash(buffer); + buffer.clear(); + } + write_count(buffer + HASH_BLOCK_SIZE - COUNT_SIZE); + + hash(buffer); + copy_out(output); + clear(); + } + +/************************************************* +* Write the count bits to the buffer * +*************************************************/ +void MDx_HashFunction::write_count(byte out[]) + { + if(COUNT_SIZE < 8) + throw Invalid_State("MDx_HashFunction::write_count: COUNT_SIZE < 8"); + + const u64bit bit_count = count * 8; + + if(BIG_BYTE_ENDIAN) + store_be(bit_count, out + COUNT_SIZE - 8); + else + store_le(bit_count, out + COUNT_SIZE - 8); + } + +} diff --git a/src/hash/mdx_hash/mdx_hash.h b/src/hash/mdx_hash/mdx_hash.h new file mode 100644 index 000000000..84f92493b --- /dev/null +++ b/src/hash/mdx_hash/mdx_hash.h @@ -0,0 +1,40 @@ +/************************************************* +* MDx Hash Function Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_MDX_BASE_H__ +#define BOTAN_MDX_BASE_H__ + +#include + +namespace Botan { + +/************************************************* +* MDx Hash Function Base Class * +*************************************************/ +class BOTAN_DLL MDx_HashFunction : public HashFunction + { + public: + MDx_HashFunction(u32bit, u32bit, bool, bool, u32bit = 8); + virtual ~MDx_HashFunction() {} + protected: + void clear() throw(); + SecureVector buffer; + u64bit count; + u32bit position; + private: + void add_data(const byte[], u32bit); + void final_result(byte output[]); + + virtual void hash(const byte[]) = 0; + virtual void copy_out(byte[]) = 0; + virtual void write_count(byte[]); + + const bool BIG_BYTE_ENDIAN, BIG_BIT_ENDIAN; + const u32bit COUNT_SIZE; + }; + +} + +#endif diff --git a/src/hash/rmd128/modinfo.txt b/src/hash/rmd128/modinfo.txt index 9be80268b..402271da5 100644 --- a/src/hash/rmd128/modinfo.txt +++ b/src/hash/rmd128/modinfo.txt @@ -8,3 +8,7 @@ load_on auto rmd128.cpp rmd128.h + + +mdx_hash + diff --git a/src/hash/rmd160/modinfo.txt b/src/hash/rmd160/modinfo.txt index 11183b03e..af4b5c230 100644 --- a/src/hash/rmd160/modinfo.txt +++ b/src/hash/rmd160/modinfo.txt @@ -8,3 +8,7 @@ load_on auto rmd160.cpp rmd160.h + + +mdx_hash + diff --git a/src/hash/sha1/modinfo.txt b/src/hash/sha1/modinfo.txt index 38cea256c..a0ae30b4b 100644 --- a/src/hash/sha1/modinfo.txt +++ b/src/hash/sha1/modinfo.txt @@ -8,3 +8,7 @@ load_on auto sha160.cpp sha160.h + + +mdx_hash + diff --git a/src/hash/sha1_sse2/modinfo.txt b/src/hash/sha1_sse2/modinfo.txt new file mode 100644 index 000000000..58d1851b0 --- /dev/null +++ b/src/hash/sha1_sse2/modinfo.txt @@ -0,0 +1,19 @@ +realname "SHA-1 (SSE2)" + +load_on request + + +sha160.cpp +sha160.h +sha1_sse.cpp + + + +pentium4 +amd64 + + + +gcc +icc + diff --git a/src/hash/sha1_sse2/sha160.cpp b/src/hash/sha1_sse2/sha160.cpp new file mode 100644 index 000000000..dfb5fdfe5 --- /dev/null +++ b/src/hash/sha1_sse2/sha160.cpp @@ -0,0 +1,52 @@ +/************************************************* +* SHA-160 Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include +#include +#include + +namespace Botan { + +extern "C" void botan_sha1_sse(u32bit[5], const byte[64]); + +/************************************************* +* SHA-160 Compression Function * +*************************************************/ +void SHA_160::hash(const byte input[]) + { + botan_sha1_sse(digest, input); + } + +/************************************************* +* Copy out the digest * +*************************************************/ +void SHA_160::copy_out(byte output[]) + { + for(u32bit j = 0; j != OUTPUT_LENGTH; ++j) + output[j] = get_byte(j % 4, digest[j/4]); + } + +/************************************************* +* Clear memory of sensitive data * +*************************************************/ +void SHA_160::clear() throw() + { + MDx_HashFunction::clear(); + digest[0] = 0x67452301; + digest[1] = 0xEFCDAB89; + digest[2] = 0x98BADCFE; + digest[3] = 0x10325476; + digest[4] = 0xC3D2E1F0; + } + +/************************************************* +* SHA_160 Constructor * +*************************************************/ +SHA_160::SHA_160() : MDx_HashFunction(20, 64, true, true) + { + clear(); + } + +} diff --git a/src/hash/sha1_sse2/sha160.h b/src/hash/sha1_sse2/sha160.h new file mode 100644 index 000000000..c6f8482cf --- /dev/null +++ b/src/hash/sha1_sse2/sha160.h @@ -0,0 +1,32 @@ +/************************************************* +* SHA-160 Header File * +* (C) 1999-2007 The Botan Project * +*************************************************/ + +#ifndef BOTAN_SHA_160_H__ +#define BOTAN_SHA_160_H__ + +#include + +namespace Botan { + +/************************************************* +* SHA-160 * +*************************************************/ +class SHA_160 : public MDx_HashFunction + { + public: + void clear() throw(); + std::string name() const { return "SHA-160"; } + HashFunction* clone() const { return new SHA_160; } + SHA_160(); + private: + void hash(const byte[]); + void copy_out(byte[]); + + SecureBuffer digest; + }; + +} + +#endif diff --git a/src/hash/sha1_sse2/sha1_sse.cpp b/src/hash/sha1_sse2/sha1_sse.cpp new file mode 100644 index 000000000..23dbfc5e2 --- /dev/null +++ b/src/hash/sha1_sse2/sha1_sse.cpp @@ -0,0 +1,327 @@ +/* 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. + * + */ +#include +#include + +namespace Botan { + +typedef union { + u32bit u32[4]; + __m128i u128; + } v4si __attribute__((aligned(16))); + +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 + +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); \ + 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: + +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 rol(u32bit src, u32bit amt) + { + /* gcc and icc appear to turn this into a rotate */ + return (src << amt) | (src >> (32 - amt)); + } + + +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) = rol((xb), 30); \ + (xt) += ((xe) + rol((xa), 5)); \ + } while(0) + +extern "C" void botan_sha1_sse(u32bit* H, + 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]; + + /* 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 = load(&input[0]); + prep00_15(prep0, W0); /* prepare for 00 through 03 */ + W1 = load(&input[1]); + prep00_15(prep1, W1); /* prepare for 04 through 07 */ + W2 = load(&input[2]); + prep00_15(prep2, W2); /* prepare for 08 through 11 */ + + W3 = load(&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; + } + +} diff --git a/src/hash/sha2/modinfo.txt b/src/hash/sha2/modinfo.txt index c7dc29fac..71df4510b 100644 --- a/src/hash/sha2/modinfo.txt +++ b/src/hash/sha2/modinfo.txt @@ -10,3 +10,7 @@ sha256.h sha_64.cpp sha_64.h + + +mdx_hash + diff --git a/src/hash/tiger/modinfo.txt b/src/hash/tiger/modinfo.txt index e117d6701..7d4cd7177 100644 --- a/src/hash/tiger/modinfo.txt +++ b/src/hash/tiger/modinfo.txt @@ -9,3 +9,7 @@ tig_tab.cpp tiger.cpp tiger.h + + +mdx_hash + diff --git a/src/hash/whirlpool/modinfo.txt b/src/hash/whirlpool/modinfo.txt index 9d069efee..be55b5c3b 100644 --- a/src/hash/whirlpool/modinfo.txt +++ b/src/hash/whirlpool/modinfo.txt @@ -9,3 +9,7 @@ whrl_tab.cpp whrlpool.cpp whrlpool.h + + +mdx_hash + diff --git a/src/mdx_hash.cpp b/src/mdx_hash.cpp deleted file mode 100644 index 96b885d87..000000000 --- a/src/mdx_hash.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************* -* MDx Hash Function Source File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include -#include - -namespace Botan { - -/************************************************* -* MDx_HashFunction Constructor * -*************************************************/ -MDx_HashFunction::MDx_HashFunction(u32bit hash_len, u32bit block_len, - bool byte_end, bool bit_end, - u32bit cnt_size) : - HashFunction(hash_len, block_len), buffer(block_len), - BIG_BYTE_ENDIAN(byte_end), BIG_BIT_ENDIAN(bit_end), COUNT_SIZE(cnt_size) - { - if(COUNT_SIZE >= OUTPUT_LENGTH || COUNT_SIZE >= HASH_BLOCK_SIZE) - throw Invalid_Argument("MDx_HashFunction: COUNT_SIZE is too big"); - count = position = 0; - } - -/************************************************* -* Clear memory of sensitive data * -*************************************************/ -void MDx_HashFunction::clear() throw() - { - buffer.clear(); - count = position = 0; - } - -/************************************************* -* Update the hash * -*************************************************/ -void MDx_HashFunction::add_data(const byte input[], u32bit length) - { - count += length; - - if(position) - { - buffer.copy(position, input, length); - - if(position + length >= HASH_BLOCK_SIZE) - { - hash(buffer.begin()); - input += (HASH_BLOCK_SIZE - position); - length -= (HASH_BLOCK_SIZE - position); - position = 0; - } - } - - while(length >= HASH_BLOCK_SIZE) - { - hash(input); - input += HASH_BLOCK_SIZE; - length -= HASH_BLOCK_SIZE; - } - - buffer.copy(position, input, length); - - position += length; - } - -/************************************************* -* Finalize a Hash * -*************************************************/ -void MDx_HashFunction::final_result(byte output[]) - { - buffer[position] = (BIG_BIT_ENDIAN ? 0x80 : 0x01); - for(u32bit j = position+1; j != HASH_BLOCK_SIZE; ++j) - buffer[j] = 0; - if(position >= HASH_BLOCK_SIZE - COUNT_SIZE) - { - hash(buffer); - buffer.clear(); - } - write_count(buffer + HASH_BLOCK_SIZE - COUNT_SIZE); - - hash(buffer); - copy_out(output); - clear(); - } - -/************************************************* -* Write the count bits to the buffer * -*************************************************/ -void MDx_HashFunction::write_count(byte out[]) - { - if(COUNT_SIZE < 8) - throw Invalid_State("MDx_HashFunction::write_count: COUNT_SIZE < 8"); - - const u64bit bit_count = count * 8; - - if(BIG_BYTE_ENDIAN) - store_be(bit_count, out + COUNT_SIZE - 8); - else - store_le(bit_count, out + COUNT_SIZE - 8); - } - -} -- cgit v1.2.3