diff --git a/JMMContracts/JMMContracts.csproj b/JMMContracts/JMMContracts.csproj
index 01889de1e..62384fa7f 100644
--- a/JMMContracts/JMMContracts.csproj
+++ b/JMMContracts/JMMContracts.csproj
@@ -32,13 +32,14 @@
prompt
4
false
+ AnyCPU
true
bin\x86\Debug\
DEBUG;TRACE
full
- x86
+ x64
prompt
true
true
@@ -187,6 +188,10 @@
+
+
+
+
ecx=_nLength
mov esi, ebp
- lea edi, [edi+m_nBuffer+eax]
+ lea edi, [edi+m_pBuffer+eax]
rep movsb
get_out: popa
- ret
+ ret 12
MD4_Add_p5 ENDP
- end
+ end
\ No newline at end of file
diff --git a/hasher/MD5.cpp b/hasher/MD5.cpp
new file mode 100644
index 000000000..84880c957
--- /dev/null
+++ b/hasher/MD5.cpp
@@ -0,0 +1,276 @@
+//
+// MD5.cpp
+//
+// Copyright (c) Shareaza Development Team, 2002-2008.
+// This file is part of SHAREAZA (shareaza.sourceforge.net)
+//
+// Shareaza is free software; you can redistribute it
+// and/or modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Shareaza is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Shareaza; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+// other copyright notices: see end of file
+
+#include "StdAfx.h"
+#include "MD5.h"
+
+
+#ifdef HASHLIB_USE_ASM
+extern "C" void __stdcall MD5_Add_p5(CMD5::MD5State*, const void* pData, std::size_t nLength);
+#endif
+
+const unsigned char hashPadding[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+
+CMD5::CMD5()
+{
+ Reset();
+}
+
+void CMD5::GetHash(__in_bcount(16) uchar* pHash) const
+{
+ std::transform(m_State.m_nState,
+ m_State.m_nState + sizeof(m_State.m_nState) / sizeof(m_State.m_nState[0]),
+ (uint32*)pHash, transformToLE< uint32 >);
+}
+
+void CMD5::Reset()
+{
+ m_State.m_nCount = 0;
+ // Load magic initialization constants
+ m_State.m_nState[0] = 0x67452301;
+ m_State.m_nState[1] = 0xefcdab89;
+ m_State.m_nState[2] = 0x98badcfe;
+ m_State.m_nState[3] = 0x10325476;
+}
+
+void CMD5::Finish()
+{
+ // Save number of bits
+ uint64 bits = transformToLE(m_State.m_nCount * 8);
+ // Pad out to 56 mod 64.
+ uint32 index = static_cast< uint32 >(m_State.m_nCount % m_State.blockSize);
+ Add(hashPadding, m_State.blockSize - sizeof(bits) - index
+ + (index < m_State.blockSize - sizeof(bits) ? 0 : m_State.blockSize));
+ Add(&bits, sizeof(bits));
+}
+
+#ifdef HASHLIB_USE_ASM
+
+void CMD5::Add(const void* pData, std::size_t nLength)
+{
+ MD5_Add_p5(&m_State, pData, nLength);
+}
+
+#else // HASHLIB_USE_ASM
+
+namespace
+{
+ // Constants for Transform routine.
+ template< uint32 tier, uint32 stage > struct S;
+ template<> struct S< 0, 0 > { static const uint32 value = 7; };
+ template<> struct S< 0, 1 > { static const uint32 value = 12; };
+ template<> struct S< 0, 2 > { static const uint32 value = 17; };
+ template<> struct S< 0, 3 > { static const uint32 value = 22; };
+ template<> struct S< 1, 0 > { static const uint32 value = 5; };
+ template<> struct S< 1, 1 > { static const uint32 value = 9; };
+ template<> struct S< 1, 2 > { static const uint32 value = 14; };
+ template<> struct S< 1, 3 > { static const uint32 value = 20; };
+ template<> struct S< 2, 0 > { static const uint32 value = 4; };
+ template<> struct S< 2, 1 > { static const uint32 value = 11; };
+ template<> struct S< 2, 2 > { static const uint32 value = 16; };
+ template<> struct S< 2, 3 > { static const uint32 value = 23; };
+ template<> struct S< 3, 0 > { static const uint32 value = 6; };
+ template<> struct S< 3, 1 > { static const uint32 value = 10; };
+ template<> struct S< 3, 2 > { static const uint32 value = 15; };
+ template<> struct S< 3, 3 > { static const uint32 value = 21; };
+
+ // F transformation
+ template< uint32 round, uint32 magic >
+ __forceinline void F(const uint32* data, uint32& a, uint32 b, uint32 c, uint32 d)
+ {
+ static const uint32 x = round;
+ static const uint32 s = S< 0, round % 4 >::value;
+ a += (d ^ (b & (c ^ d))) + transformFromLE(data[x]) + magic;
+ a = rotateLeft(a, s) + b;
+ }
+ // G transformation
+ template< uint32 round, uint32 magic >
+ __forceinline void G(const uint32* data, uint32& a, uint32 b, uint32 c, uint32 d)
+ {
+ static const uint32 x = (1 + (round & 3) * 5 + (round & 12)) & 15;
+ static const uint32 s = S< 1, round % 4 >::value;
+ a += (c ^ (d & (b ^ c))) + transformFromLE(data[x]) + magic;
+ a = rotateLeft(a, s) + b;
+ }
+ // H transformation
+ template< uint32 round, uint32 magic >
+ __forceinline void H(const uint32* data, uint32& a, uint32 b, uint32 c, uint32 d)
+ {
+ static const uint32 x = (5 + (round & 7) * 3 + (round & 8)) & 15;
+ static const uint32 s = S< 2, round % 4 >::value;
+ a += (b ^ c ^ d) + transformFromLE(data[x]) + magic;
+ a = rotateLeft(a, s) + b;
+ }
+ // I transformation
+ template< uint32 round, uint32 magic >
+ __forceinline void I(const uint32* data, uint32& a, uint32 b, uint32 c, uint32 d)
+ {
+ static const uint32 x = ((round & 3) * 7 + (round & 4) * 3 + (round & 8)) & 15;
+ static const uint32 s = S< 3, round % 4 >::value;
+ a += (c ^ (b | ~d)) + transformFromLE(data[x]) + magic;
+ a = rotateLeft(a, s) + b;
+ }
+} // namespace
+
+// MD5 basic transformation. Transforms state based on block.
+void CMD5::Transform(const uint32* data)
+{
+ uint32 a = m_State.m_nState[0];
+ uint32 b = m_State.m_nState[1];
+ uint32 c = m_State.m_nState[2];
+ uint32 d = m_State.m_nState[3];
+
+ F< 0, 0xd76aa478 >(data, a, b, c, d);
+ F< 1, 0xe8c7b756 >(data, d, a, b, c);
+ F< 2, 0x242070db >(data, c, d, a, b);
+ F< 3, 0xc1bdceee >(data, b, c, d, a);
+ F< 4, 0xf57c0faf >(data, a, b, c, d);
+ F< 5, 0x4787c62a >(data, d, a, b, c);
+ F< 6, 0xa8304613 >(data, c, d, a, b);
+ F< 7, 0xfd469501 >(data, b, c, d, a);
+ F< 8, 0x698098d8 >(data, a, b, c, d);
+ F< 9, 0x8b44f7af >(data, d, a, b, c);
+ F< 10, 0xffff5bb1 >(data, c, d, a, b);
+ F< 11, 0x895cd7be >(data, b, c, d, a);
+ F< 12, 0x6b901122 >(data, a, b, c, d);
+ F< 13, 0xfd987193 >(data, d, a, b, c);
+ F< 14, 0xa679438e >(data, c, d, a, b);
+ F< 15, 0x49b40821 >(data, b, c, d, a);
+
+ G< 0, 0xf61e2562 >(data, a, b, c, d);
+ G< 1, 0xc040b340 >(data, d, a, b, c);
+ G< 2, 0x265e5a51 >(data, c, d, a, b);
+ G< 3, 0xe9b6c7aa >(data, b, c, d, a);
+ G< 4, 0xd62f105d >(data, a, b, c, d);
+ G< 5, 0x02441453 >(data, d, a, b, c);
+ G< 6, 0xd8a1e681 >(data, c, d, a, b);
+ G< 7, 0xe7d3fbc8 >(data, b, c, d, a);
+ G< 8, 0x21e1cde6 >(data, a, b, c, d);
+ G< 9, 0xc33707d6 >(data, d, a, b, c);
+ G< 10, 0xf4d50d87 >(data, c, d, a, b);
+ G< 11, 0x455a14ed >(data, b, c, d, a);
+ G< 12, 0xa9e3e905 >(data, a, b, c, d);
+ G< 13, 0xfcefa3f8 >(data, d, a, b, c);
+ G< 14, 0x676f02d9 >(data, c, d, a, b);
+ G< 15, 0x8d2a4c8a >(data, b, c, d, a);
+
+ H< 0, 0xfffa3942 >(data, a, b, c, d);
+ H< 1, 0x8771f681 >(data, d, a, b, c);
+ H< 2, 0x6d9d6122 >(data, c, d, a, b);
+ H< 3, 0xfde5380c >(data, b, c, d, a);
+ H< 4, 0xa4beea44 >(data, a, b, c, d);
+ H< 5, 0x4bdecfa9 >(data, d, a, b, c);
+ H< 6, 0xf6bb4b60 >(data, c, d, a, b);
+ H< 7, 0xbebfbc70 >(data, b, c, d, a);
+ H< 8, 0x289b7ec6 >(data, a, b, c, d);
+ H< 9, 0xeaa127fa >(data, d, a, b, c);
+ H< 10, 0xd4ef3085 >(data, c, d, a, b);
+ H< 11, 0x04881d05 >(data, b, c, d, a);
+ H< 12, 0xd9d4d039 >(data, a, b, c, d);
+ H< 13, 0xe6db99e5 >(data, d, a, b, c);
+ H< 14, 0x1fa27cf8 >(data, c, d, a, b);
+ H< 15, 0xc4ac5665 >(data, b, c, d, a);
+
+ I< 0, 0xf4292244 >(data, a, b, c, d);
+ I< 1, 0x432aff97 >(data, d, a, b, c);
+ I< 2, 0xab9423a7 >(data, c, d, a, b);
+ I< 3, 0xfc93a039 >(data, b, c, d, a);
+ I< 4, 0x655b59c3 >(data, a, b, c, d);
+ I< 5, 0x8f0ccc92 >(data, d, a, b, c);
+ I< 6, 0xffeff47d >(data, c, d, a, b);
+ I< 7, 0x85845dd1 >(data, b, c, d, a);
+ I< 8, 0x6fa87e4f >(data, a, b, c, d);
+ I< 9, 0xfe2ce6e0 >(data, d, a, b, c);
+ I< 10, 0xa3014314 >(data, c, d, a, b);
+ I< 11, 0x4e0811a1 >(data, b, c, d, a);
+ I< 12, 0xf7537e82 >(data, a, b, c, d);
+ I< 13, 0xbd3af235 >(data, d, a, b, c);
+ I< 14, 0x2ad7d2bb >(data, c, d, a, b);
+ I< 15, 0xeb86d391 >(data, b, c, d, a);
+
+ m_State.m_nState[0] += a;
+ m_State.m_nState[1] += b;
+ m_State.m_nState[2] += c;
+ m_State.m_nState[3] += d;
+}
+
+void CMD5::Add(const void* pData, std::size_t nLength)
+{
+ // Update number of bytes
+ const char* input = static_cast< const char* >(pData);
+ {
+ uint32 index = static_cast< uint32 >(m_State.m_nCount % m_State.blockSize);
+ m_State.m_nCount += nLength;
+ if (index)
+ {
+ // buffer has some data already - lets fill it
+ // before doing the rest of the transformation on the original data
+ if (index + nLength < m_State.blockSize)
+ {
+ std::memcpy(m_State.m_oBuffer + index, input, nLength);
+ return;
+ }
+ std::memcpy(m_State.m_oBuffer + index, input, m_State.blockSize - index);
+ nLength -= m_State.blockSize - index;
+ input += m_State.blockSize - index;
+ Transform(reinterpret_cast< const uint32* >(m_State.m_oBuffer));
+ }
+ }
+ // Transform as many times as possible using the original data stream
+ const char* const end = input + nLength - nLength % m_State.blockSize;
+ nLength %= m_State.blockSize;
+ for (; input != end; input += m_State.blockSize)
+ Transform(reinterpret_cast< const uint32* >(input));
+ // Buffer remaining input
+ if (nLength)
+ std::memcpy(m_State.m_oBuffer, input, nLength);
+}
+
+#endif // HASHLIB_USE_ASM
+
+// MD5.CPP - RSA Data Security, Inc., MD5 message-digest algorithm
+
+// Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+// Copyrights reserved.
+//
+// License to copy and use this software is granted provided that it
+// is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+// Algorithm" in all material mentioning or referencing this software
+// or this function.
+//
+// License is also granted to make and use derivative works provided
+// that such works are identified as "derived from the RSA Data
+// Security, Inc. MD5 Message-Digest Algorithm" in all material
+// mentioning or referencing the derived work.
+//
+// RSA Data Security, Inc. makes no representations concerning either
+// the merchantability of this software or the suitability of this
+// software for any particular purpose. It is provided "as is"
+// without express or implied warranty of any kind.
+//
+// These notices must be retained in any copies of any part of this
+// documentation and/or software.
diff --git a/hasher/MD5.h b/hasher/MD5.h
new file mode 100644
index 000000000..eaf4038f9
--- /dev/null
+++ b/hasher/MD5.h
@@ -0,0 +1,58 @@
+//
+// MD5.h
+//
+// Copyright (c) Shareaza Development Team, 2002-2014.
+// This file is part of SHAREAZA (shareaza.sourceforge.net)
+//
+// Shareaza is free software; you can redistribute it
+// and/or modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Shareaza is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Shareaza; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#pragma once
+#include "Utility.hpp"
+
+class CMD5
+{
+public:
+ CMD5();
+ ~CMD5() {}
+
+ void Reset();
+ void Add(const void* pData, size_t nLength);
+ void Finish();
+
+ struct Digest // 128 bit
+ {
+ uint32& operator[](size_t i) { return data[i]; }
+ const uint32& operator[](size_t i) const { return data[i]; }
+ uint32 data[4];
+ };
+
+ void GetHash(__in_bcount(16) uchar* pHash) const;
+
+ struct MD5State
+ {
+ static const size_t blockSize = 64;
+ uint64 m_nCount;
+ uint32 m_nState[4];
+ uchar m_oBuffer[blockSize];
+ };
+
+private:
+ MD5State m_State;
+
+#ifndef HASHLIB_USE_ASM
+ __forceinline void Transform(const uint32* data);
+#endif
+};
diff --git a/hasher/MD5_asm.asm b/hasher/MD5_asm.asm
new file mode 100644
index 000000000..24152d9a6
--- /dev/null
+++ b/hasher/MD5_asm.asm
@@ -0,0 +1,303 @@
+; #####################################################################################################################
+;
+; MD5_asm.asm
+;
+; Copyright (c) Shareaza Development Team, 2002-2007.
+; This file is part of SHAREAZA (shareaza.sourceforge.net)
+;
+; Shareaza is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; as published by the Free Software Foundation; either version 2 of
+; the License, or (at your option) any later version.
+;
+; Shareaza is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with Shareaza; if not, write to the Free Software
+; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+;
+; #####################################################################################################################
+;
+; MD5_asm - Implementation of MD5 for x86 - use together with MD5.cpp and MD5.h
+;
+; #####################################################################################################################
+
+ .586p
+ .model flat, stdcall
+ option casemap:none ; case sensitive
+ option prologue:none ; we generate our own entry/exit code
+ option epilogue:none
+
+; #####################################################################################################################
+
+
+m_nCount0 equ 0
+m_nCount1 equ 4
+
+m_nState0 equ 8 ; offsets as laid out in MD5.h
+m_nState1 equ 12
+m_nState2 equ 16
+m_nState3 equ 20
+
+m_pBuffer equ 24
+
+; Some magic numbers for Transform...
+MD5_S11 equ 7
+MD5_S12 equ 12
+MD5_S13 equ 17
+MD5_S14 equ 22
+MD5_S21 equ 5
+MD5_S22 equ 9
+MD5_S23 equ 14
+MD5_S24 equ 20
+MD5_S31 equ 4
+MD5_S32 equ 11
+MD5_S33 equ 16
+MD5_S34 equ 23
+MD5_S41 equ 6
+MD5_S42 equ 10
+MD5_S43 equ 15
+MD5_S44 equ 21
+
+MD5FF MACRO count:REQ,s:REQ,ac:REQ
+; a = b+(a+x[count]+ac+((b&c)|(~b&d)))rol s
+; a = b+(a+x[count]+ax+(d^(b&(c^d))))rol s
+ mov reg_temp1, reg_c
+reg_t textequ reg_temp1
+reg_temp1 textequ reg_c
+reg_c textequ reg_t
+ xor reg_temp1, reg_d
+ add reg_a, [reg_base+count*4]
+ and reg_temp1, reg_b
+ add reg_a, ac
+ xor reg_temp1, reg_d
+ add reg_a, reg_temp1
+ rol reg_a, s
+ add reg_a, reg_b
+reg_t textequ reg_d
+reg_d textequ reg_c
+reg_c textequ reg_b
+reg_b textequ reg_a
+reg_a textequ reg_t
+ ENDM
+
+
+MD5GG MACRO count:REQ,s:REQ,ac:REQ
+; a = b+(a+x[count]+ac+((d&b)|(~d&c)))rol s
+; a = b+(a+x[count]+ac+(c^(d&(b^c))))rols s
+ mov reg_temp1, reg_b
+reg_t textequ reg_temp1
+reg_temp1 textequ reg_b
+reg_b textequ reg_t
+ xor reg_temp1, reg_c
+ add reg_a, [reg_base+count*4]
+ and reg_temp1, reg_d
+ add reg_a, ac
+ xor reg_temp1, reg_c
+ add reg_a, reg_temp1
+ rol reg_a, s
+ add reg_a, reg_b
+reg_t textequ reg_d
+reg_d textequ reg_c
+reg_c textequ reg_b
+reg_b textequ reg_a
+reg_a textequ reg_t
+ ENDM
+
+MD5HH MACRO count:REQ,s:REQ,ac:REQ
+; a = b+(a+x[count]+ac+(b^c^d)) rol s
+ mov reg_temp1, reg_b
+reg_t textequ reg_temp1
+reg_temp1 textequ reg_b
+reg_b textequ reg_t
+ xor reg_temp1, reg_c
+ add reg_a, [reg_base+count*4]
+ xor reg_temp1, reg_d
+ add reg_a, ac
+ add reg_a, reg_temp1
+ rol reg_a, s
+ add reg_a, reg_b
+reg_t textequ reg_d
+reg_d textequ reg_c
+reg_c textequ reg_b
+reg_b textequ reg_a
+reg_a textequ reg_t
+ ENDM
+
+MD5II MACRO count:REQ,s:REQ,ac:REQ
+; a = b+(a+x[count]+ac+(c^(~d|b))) rol s
+ mov reg_temp1, reg_d
+reg_t textequ reg_temp1
+reg_temp1 textequ reg_d
+reg_d textequ reg_t
+ not reg_temp1
+ add reg_a, [reg_base+count*4]
+ or reg_temp1, reg_b
+ add reg_a, ac
+ xor reg_temp1, reg_c
+ add reg_a, reg_temp1
+ rol reg_a, s
+ add reg_a, reg_b
+reg_t textequ reg_d
+reg_d textequ reg_c
+reg_c textequ reg_b
+reg_b textequ reg_a
+reg_a textequ reg_t
+ ENDM
+
+ .code
+
+MD5_Transform_p5 PROC ; we expect ebp to point to the Data stream
+ ; all other registers (eax,ebx,ecx,edx,esi,edi) will be destroyed
+__this textequ <[esp+32+2*4]> ; 1*pusha+2*call
+
+; set alias for registers
+reg_a textequ
+reg_b textequ
+reg_c textequ
+reg_d textequ
+reg_temp1 textequ
+reg_temp2 textequ
+reg_base textequ
+ mov reg_temp2, __this
+ mov reg_a, [reg_temp2+m_nState0]
+ mov reg_b, [reg_temp2+m_nState1]
+ mov reg_c, [reg_temp2+m_nState2]
+ mov reg_d, [reg_temp2+m_nState3]
+; round 1
+ MD5FF 0, MD5_S11,0D76AA478H ; 1
+ MD5FF 1, MD5_S12,0E8C7B756H ; 2
+ MD5FF 2, MD5_S13, 242070DBH ; 3
+ MD5FF 3, MD5_S14,0C1BDCEEEH ; 4
+ MD5FF 4, MD5_S11,0F57C0FAFH ; 5
+ MD5FF 5, MD5_S12, 4787C62AH ; 6
+ MD5FF 6, MD5_S13,0A8304613H ; 7
+ MD5FF 7, MD5_S14,0FD469501H ; 8
+ MD5FF 8, MD5_S11, 698098D8H ; 9
+ MD5FF 9, MD5_S12, 8B44F7AFH ; 10
+ MD5FF 10, MD5_S13,0FFFF5BB1H ; 11
+ MD5FF 11, MD5_S14, 895CD7BEH ; 12
+ MD5FF 12, MD5_S11, 6B901122H ; 13
+ MD5FF 13, MD5_S12,0FD987193H ; 14
+ MD5FF 14, MD5_S13,0A679438EH ; 15
+ MD5FF 15, MD5_S14, 49B40821H ; 16
+; round 2
+ MD5GG 1, MD5_S21,0F61E2562H ; 17
+ MD5GG 6, MD5_S22,0C040B340H ; 18
+ MD5GG 11, MD5_S23, 265E5A51H ; 19
+ MD5GG 0, MD5_S24,0E9B6C7AAH ; 20
+ MD5GG 5, MD5_S21,0D62F105DH ; 21
+ MD5GG 10, MD5_S22, 2441453H ; 22
+ MD5GG 15, MD5_S23,0D8A1E681H ; 23
+ MD5GG 4, MD5_S24,0E7D3FBC8H ; 24
+ MD5GG 9, MD5_S21, 21E1CDE6H ; 25
+ MD5GG 14, MD5_S22,0C33707D6H ; 26
+ MD5GG 3, MD5_S23,0F4D50D87H ; 27
+ MD5GG 8, MD5_S24, 455A14EDH ; 28
+ MD5GG 13, MD5_S21,0A9E3E905H ; 29
+ MD5GG 2, MD5_S22,0FCEFA3F8H ; 30
+ MD5GG 7, MD5_S23, 676F02D9H ; 31
+ MD5GG 12, MD5_S24, 8D2A4C8AH ; 32
+; round 3
+ MD5HH 5, MD5_S31,0FFFA3942H ; 33
+ MD5HH 8, MD5_S32, 8771F681H ; 34
+ MD5HH 11, MD5_S33, 6D9D6122H ; 35
+ MD5HH 14, MD5_S34,0FDE5380CH ; 36
+ MD5HH 1, MD5_S31,0A4BEEA44H ; 37
+ MD5HH 4, MD5_S32, 4BDECFA9H ; 38
+ MD5HH 7, MD5_S33,0F6BB4B60H ; 39
+ MD5HH 10, MD5_S34,0BEBFBC70H ; 40
+ MD5HH 13, MD5_S31, 289B7EC6H ; 41
+ MD5HH 0, MD5_S32,0EAA127FAH ; 42
+ MD5HH 3, MD5_S33,0D4EF3085H ; 43
+ MD5HH 6, MD5_S34, 4881D05H ; 44
+ MD5HH 9, MD5_S31,0D9D4D039H ; 45
+ MD5HH 12, MD5_S32,0E6DB99E5H ; 46
+ MD5HH 15, MD5_S33, 1FA27CF8H ; 47
+ MD5HH 2, MD5_S34,0C4AC5665H ; 48
+; round 4
+ MD5II 0, MD5_S41,0F4292244H ; 49
+ MD5II 7, MD5_S42, 432AFF97H ; 50
+ MD5II 14, MD5_S43,0AB9423A7H ; 51
+ MD5II 5, MD5_S44,0FC93A039H ; 52
+ MD5II 12, MD5_S41, 655B59C3H ; 53
+ MD5II 3, MD5_S42, 8F0CCC92H ; 54
+ MD5II 10, MD5_S43,0FFEFF47DH ; 55
+ MD5II 1, MD5_S44, 85845DD1H ; 56
+ MD5II 8, MD5_S41, 6FA87E4FH ; 57
+ MD5II 15, MD5_S42,0FE2CE6E0H ; 58
+ MD5II 6, MD5_S43,0A3014314H ; 59
+ MD5II 13, MD5_S44, 4E0811A1H ; 60
+ MD5II 4, MD5_S41,0F7537E82H ; 61
+ MD5II 11, MD5_S42,0BD3AF235H ; 62
+ MD5II 2, MD5_S43, 2AD7D2BBH ; 63
+ MD5II 9, MD5_S44,0EB86D391H ; 64
+ add [reg_temp2+m_nState0], reg_a
+ add [reg_temp2+m_nState1], reg_b
+ add [reg_temp2+m_nState2], reg_c
+ add [reg_temp2+m_nState3], reg_d
+ ret
+MD5_Transform_p5 ENDP
+
+MD5_Add_p5 PROC PUBLIC, _this:DWORD, _Data:DWORD, _nLength:DWORD
+ pusha
+__this textequ <[esp+36]> ; different offset due to pusha
+__Data textequ <[esp+40]>
+__nLength textequ <[esp+44]>
+ mov ecx, __nLength
+ and ecx, ecx
+ jz get_out
+ xor edx, edx
+ mov ebp, __Data
+ mov edi, __this
+ mov ebx, [edi+m_nCount0]
+ mov eax, ebx
+ add ebx, ecx
+ mov [edi+m_nCount0], ebx
+ adc [edi+m_nCount1], edx
+ and eax, 63
+ jnz partial_buffer
+full_blocks: mov ecx, __nLength
+ and ecx, ecx
+ jz get_out
+ sub ecx, 64
+ jb end_of_stream
+ mov __nLength, ecx
+ call MD5_Transform_p5
+ add ebp, 64
+ jmp full_blocks
+end_of_stream: mov edi, __this
+ mov esi, ebp
+ lea edi, [edi+m_pBuffer]
+ add ecx, 64
+ rep movsb
+ jmp get_out
+partial_buffer: add ecx, eax ; eax = offset in buffer, ecx = _nLength
+ cmp ecx, 64
+ jb short_stream ; we can't fill the buffer
+ mov ecx, -64
+ add ecx, eax
+ add __nLength, ecx ; _nlength += (offset-64)
+@@: mov bl, [ebp]
+ inc ebp
+ mov byte ptr [edi+m_pBuffer+64+ecx], bl
+ inc ecx
+ jnz @B ; offset = 64
+ mov __Data, ebp
+ lea ebp, [edi+m_pBuffer]
+ call MD5_Transform_p5
+ mov ebp, __Data
+ jmp full_blocks
+short_stream: sub ecx, eax ; --> ecx=_nLength
+ mov esi, ebp
+ lea edi, [edi+m_pBuffer+eax]
+ rep movsb
+get_out: popa
+ ret 12
+
+MD5_Add_p5 ENDP
+
+ end
diff --git a/hasher/SHA.cpp b/hasher/SHA.cpp
index b5d947bfa..a1237eb96 100644
--- a/hasher/SHA.cpp
+++ b/hasher/SHA.cpp
@@ -1,251 +1,372 @@
//
-// This file is part of the aMule Project.
+// MD5.cpp
//
-// Copyright (c) 2003-2006 Angel Vidal (Kry) ( kry@amule.org )
-// Copyright (c) 2003-2006 aMule Team ( admin@amule.org / http://www.amule.org )
+// Copyright (c) Shareaza Development Team, 2002-2008.
+// This file is part of SHAREAZA (shareaza.sourceforge.net)
//
-// Any parts of this program derived from the xMule, lMule or eMule project,
-// or contributed by third-party developers are copyrighted by their
-// respective authors.
+// Shareaza is free software; you can redistribute it
+// and/or modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
+// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
//
-// Kry - Modified version of the original SHA.cpp to work on linux and
-// use wxWidgets. Original license follows.
+// You should have received a copy of the GNU General Public License
+// along with Shareaza; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2002, Dr Brian Gladman , Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
+// other copyright notices: see end of file
- 1. distributions of this source code include the above copyright
- notice, this list of conditions and the following disclaimer;
-
- 2. distributions in binary form include the above copyright
- notice, this list of conditions and the following disclaimer
- in the documentation and/or other associated materials;
+#include "StdAfx.h"
+#include "SHA.h"
- 3. the copyright holder's name is not used to endorse products
- built using this software without specific written permission.
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
+#ifdef HASHLIB_USE_ASM
+extern "C" void __stdcall SHA1_Add_p5(CSHA::SHA1State*, const void* pData, std::size_t nLength);
+#endif
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 30/11/2002
-
- This is a byte oriented version of SHA1 that operates on arrays of bytes
- stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor
-*/
-#include "stdafx.h"
-#include "SHA.h"
+const unsigned char hashPadding[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
CSHA::CSHA()
{
Reset();
}
-/*
- To obtain the highest speed on processors with 32-bit words, this code
- needs to determine the order in which bytes are packed into such words.
- The following block of code is an attempt to capture the most obvious
- ways in which various environemnts specify their endian definitions.
- It may well fail, in which case the definitions will need to be set by
- editing at the points marked **** EDIT HERE IF NECESSARY **** below.
-*/
-#define SHA_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
-#define SHA_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
-
-// Kry - Use wxWidgets byte order definitions
-#if wxBYTE_ORDER == wxLITTLE_ENDIAN
- #define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
-#else
- #define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
-#endif
-
-#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
-
-#if (PLATFORM_BYTE_ORDER == SHA_BIG_ENDIAN)
-#define swap_b32(x) (x)
-#elif defined(bswap_32)
-#define swap_b32(x) bswap_32(x)
-#else
-#define swap_b32(x) ((rotl32((x), 8) & 0x00ff00ff) | (rotl32((x), 24) & 0xff00ff00))
-#endif
-
-#define SHA1_MASK (SHA1_BLOCK_SIZE - 1)
-
-/* reverse byte order in 32-bit words */
-#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
-#define parity(x,y,z) ((x) ^ (y) ^ (z))
-#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-
-/* A normal version as set out in the FIPS. This version uses */
-/* partial loop unrolling and is optimised for the Pentium 4 */
-
-#define rnd(f,k) t = a; a = rotl32(a,5) + f(b,c,d) + e + k + w[i]; e = d; d = c; c = rotl32(b, 30); b = t
-
-void CSHA::Compile()
+void CSHA::GetHash(__in_bcount(20) uchar* pHash) const
{
- uint32 w[80], i, a, b, c, d, e, t;
-
- /* note that words are compiled from the buffer into 32-bit */
- /* words in big-endian order so an order reversal is needed */
- /* here on little endian machines */
- for(i = 0; i < SHA1_BLOCK_SIZE / 4; ++i)
- w[i] = swap_b32(m_nBuffer[i]);
-
- for(i = SHA1_BLOCK_SIZE / 4; i < 80; ++i)
- w[i] = rotl32(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
-
- a = m_nHash[0];
- b = m_nHash[1];
- c = m_nHash[2];
- d = m_nHash[3];
- e = m_nHash[4];
-
- for(i = 0; i < 20; ++i)
- {
- rnd(ch, 0x5a827999);
- }
-
- for(i = 20; i < 40; ++i)
- {
- rnd(parity, 0x6ed9eba1);
- }
-
- for(i = 40; i < 60; ++i)
- {
- rnd(maj, 0x8f1bbcdc);
- }
-
- for(i = 60; i < 80; ++i)
- {
- rnd(parity, 0xca62c1d6);
- }
-
- m_nHash[0] += a;
- m_nHash[1] += b;
- m_nHash[2] += c;
- m_nHash[3] += d;
- m_nHash[4] += e;
+ std::transform(m_State.m_nState,
+ m_State.m_nState + sizeof(m_State.m_nState) / sizeof(m_State.m_nState[0]),
+ (uint32*)pHash, transformToBE< uint32 >);
}
void CSHA::Reset()
{
- m_nCount[0] = m_nCount[1] = 0;
- m_nHash[0] = 0x67452301;
- m_nHash[1] = 0xefcdab89;
- m_nHash[2] = 0x98badcfe;
- m_nHash[3] = 0x10325476;
- m_nHash[4] = 0xc3d2e1f0;
+ m_State.m_nCount = 0;
+ m_State.m_nState[0] = 0x67452301;
+ m_State.m_nState[1] = 0xefcdab89;
+ m_State.m_nState[2] = 0x98badcfe;
+ m_State.m_nState[3] = 0x10325476;
+ m_State.m_nState[4] = 0xc3d2e1f0;
}
-void CSHA::GetHash(CAICHHash& Hash)
+void CSHA::Finish()
{
- /* extract the hash value as bytes in case the hash buffer is */
- /* misaligned for 32-bit words*/
+ // Save number of bits
+ uint64 bits = transformToBE(m_State.m_nCount * 8);
+ // Pad out to 56 mod 64.
+ uint32 index = static_cast< uint32 >(m_State.m_nCount % m_State.blockSize);
+ Add(hashPadding, m_State.blockSize - sizeof(bits) - index
+ + (index < m_State.blockSize - sizeof(bits) ? 0 : m_State.blockSize));
+ Add(&bits, sizeof(bits));
+}
- //wxASSERT( Hash.GetHashSize() == 20 );
- for(int i = 0; i < SHA1_DIGEST_SIZE; ++i)
- Hash.GetRawHash()[i] = (unsigned char)(m_nHash[i >> 2] >> 8 * (~i & 3));
+#ifdef HASHLIB_USE_ASM
+
+void CSHA::Add(const void* pData, std::size_t nLength)
+{
+ SHA1_Add_p5(&m_State, pData, nLength);
}
-/* SHA1 hash data in an array of bytes into hash buffer and call the */
-/* hash_compile function as required. */
+#else // HASHLIB_USE_ASM
-void CSHA::Add(const void* pData, uint32 nLength)
+CSHA::TransformArray::TransformArray(const uint32* const buffer)
{
- const unsigned char* data = (const unsigned char*)pData;
-
- uint32 pos = (uint32)(m_nCount[0] & SHA1_MASK),
- space = SHA1_BLOCK_SIZE - pos;
- const unsigned char *sp = data;
-
- if((m_nCount[0] += nLength) < nLength)
- ++(m_nCount[1]);
-
- while(nLength >= space) /* tranfer whole blocks while possible */
- {
- memcpy(((unsigned char*)m_nBuffer) + pos, sp, space);
- sp += space; nLength -= space; space = SHA1_BLOCK_SIZE; pos = 0;
- Compile();
- }
-
- memcpy(((unsigned char*)m_nBuffer) + pos, sp, nLength);
+ m_buffer[0] = transformFromBE(buffer[0]),
+ m_buffer[1] = transformFromBE(buffer[1]),
+ m_buffer[2] = transformFromBE(buffer[2]),
+ m_buffer[3] = transformFromBE(buffer[3]),
+ m_buffer[4] = transformFromBE(buffer[4]),
+ m_buffer[5] = transformFromBE(buffer[5]),
+ m_buffer[6] = transformFromBE(buffer[6]),
+ m_buffer[7] = transformFromBE(buffer[7]),
+ m_buffer[8] = transformFromBE(buffer[8]),
+ m_buffer[9] = transformFromBE(buffer[9]),
+ m_buffer[10] = transformFromBE(buffer[10]),
+ m_buffer[11] = transformFromBE(buffer[11]),
+ m_buffer[12] = transformFromBE(buffer[12]),
+ m_buffer[13] = transformFromBE(buffer[13]),
+ m_buffer[14] = transformFromBE(buffer[14]),
+ m_buffer[15] = transformFromBE(buffer[15]);
+
+ m_buffer[16] = rotateLeft(m_buffer[0] ^ m_buffer[2] ^ m_buffer[8] ^ m_buffer[13], 1);
+ m_buffer[17] = rotateLeft(m_buffer[1] ^ m_buffer[3] ^ m_buffer[9] ^ m_buffer[14], 1);
+ m_buffer[18] = rotateLeft(m_buffer[2] ^ m_buffer[4] ^ m_buffer[10] ^ m_buffer[15], 1);
+ m_buffer[19] = rotateLeft(m_buffer[3] ^ m_buffer[5] ^ m_buffer[11] ^ m_buffer[16], 1);
+ m_buffer[20] = rotateLeft(m_buffer[4] ^ m_buffer[6] ^ m_buffer[12] ^ m_buffer[17], 1);
+ m_buffer[21] = rotateLeft(m_buffer[5] ^ m_buffer[7] ^ m_buffer[13] ^ m_buffer[18], 1);
+ m_buffer[22] = rotateLeft(m_buffer[6] ^ m_buffer[8] ^ m_buffer[14] ^ m_buffer[19], 1);
+ m_buffer[23] = rotateLeft(m_buffer[7] ^ m_buffer[9] ^ m_buffer[15] ^ m_buffer[20], 1);
+ m_buffer[24] = rotateLeft(m_buffer[8] ^ m_buffer[10] ^ m_buffer[16] ^ m_buffer[21], 1);
+ m_buffer[25] = rotateLeft(m_buffer[9] ^ m_buffer[11] ^ m_buffer[17] ^ m_buffer[22], 1);
+ m_buffer[26] = rotateLeft(m_buffer[10] ^ m_buffer[12] ^ m_buffer[18] ^ m_buffer[23], 1);
+ m_buffer[27] = rotateLeft(m_buffer[11] ^ m_buffer[13] ^ m_buffer[19] ^ m_buffer[24], 1);
+ m_buffer[28] = rotateLeft(m_buffer[12] ^ m_buffer[14] ^ m_buffer[20] ^ m_buffer[25], 1);
+ m_buffer[29] = rotateLeft(m_buffer[13] ^ m_buffer[15] ^ m_buffer[21] ^ m_buffer[26], 1);
+ m_buffer[30] = rotateLeft(m_buffer[14] ^ m_buffer[16] ^ m_buffer[22] ^ m_buffer[27], 1);
+ m_buffer[31] = rotateLeft(m_buffer[15] ^ m_buffer[17] ^ m_buffer[23] ^ m_buffer[28], 1);
+
+ m_buffer[32] = rotateLeft(m_buffer[16] ^ m_buffer[18] ^ m_buffer[24] ^ m_buffer[29], 1);
+ m_buffer[33] = rotateLeft(m_buffer[17] ^ m_buffer[19] ^ m_buffer[25] ^ m_buffer[30], 1);
+ m_buffer[34] = rotateLeft(m_buffer[18] ^ m_buffer[20] ^ m_buffer[26] ^ m_buffer[31], 1);
+ m_buffer[35] = rotateLeft(m_buffer[19] ^ m_buffer[21] ^ m_buffer[27] ^ m_buffer[32], 1);
+ m_buffer[36] = rotateLeft(m_buffer[20] ^ m_buffer[22] ^ m_buffer[28] ^ m_buffer[33], 1);
+ m_buffer[37] = rotateLeft(m_buffer[21] ^ m_buffer[23] ^ m_buffer[29] ^ m_buffer[34], 1);
+ m_buffer[38] = rotateLeft(m_buffer[22] ^ m_buffer[24] ^ m_buffer[30] ^ m_buffer[35], 1);
+ m_buffer[39] = rotateLeft(m_buffer[23] ^ m_buffer[25] ^ m_buffer[31] ^ m_buffer[36], 1);
+ m_buffer[40] = rotateLeft(m_buffer[24] ^ m_buffer[26] ^ m_buffer[32] ^ m_buffer[37], 1);
+ m_buffer[41] = rotateLeft(m_buffer[25] ^ m_buffer[27] ^ m_buffer[33] ^ m_buffer[38], 1);
+ m_buffer[42] = rotateLeft(m_buffer[26] ^ m_buffer[28] ^ m_buffer[34] ^ m_buffer[39], 1);
+ m_buffer[43] = rotateLeft(m_buffer[27] ^ m_buffer[29] ^ m_buffer[35] ^ m_buffer[40], 1);
+ m_buffer[44] = rotateLeft(m_buffer[28] ^ m_buffer[30] ^ m_buffer[36] ^ m_buffer[41], 1);
+ m_buffer[45] = rotateLeft(m_buffer[29] ^ m_buffer[31] ^ m_buffer[37] ^ m_buffer[42], 1);
+ m_buffer[46] = rotateLeft(m_buffer[30] ^ m_buffer[32] ^ m_buffer[38] ^ m_buffer[43], 1);
+ m_buffer[47] = rotateLeft(m_buffer[31] ^ m_buffer[33] ^ m_buffer[39] ^ m_buffer[44], 1);
+
+ m_buffer[48] = rotateLeft(m_buffer[32] ^ m_buffer[34] ^ m_buffer[40] ^ m_buffer[45], 1);
+ m_buffer[49] = rotateLeft(m_buffer[33] ^ m_buffer[35] ^ m_buffer[41] ^ m_buffer[46], 1);
+ m_buffer[50] = rotateLeft(m_buffer[34] ^ m_buffer[36] ^ m_buffer[42] ^ m_buffer[47], 1);
+ m_buffer[51] = rotateLeft(m_buffer[35] ^ m_buffer[37] ^ m_buffer[43] ^ m_buffer[48], 1);
+ m_buffer[52] = rotateLeft(m_buffer[36] ^ m_buffer[38] ^ m_buffer[44] ^ m_buffer[49], 1);
+ m_buffer[53] = rotateLeft(m_buffer[37] ^ m_buffer[39] ^ m_buffer[45] ^ m_buffer[50], 1);
+ m_buffer[54] = rotateLeft(m_buffer[38] ^ m_buffer[40] ^ m_buffer[46] ^ m_buffer[51], 1);
+ m_buffer[55] = rotateLeft(m_buffer[39] ^ m_buffer[41] ^ m_buffer[47] ^ m_buffer[52], 1);
+ m_buffer[56] = rotateLeft(m_buffer[40] ^ m_buffer[42] ^ m_buffer[48] ^ m_buffer[53], 1);
+ m_buffer[57] = rotateLeft(m_buffer[41] ^ m_buffer[43] ^ m_buffer[49] ^ m_buffer[54], 1);
+ m_buffer[58] = rotateLeft(m_buffer[42] ^ m_buffer[44] ^ m_buffer[50] ^ m_buffer[55], 1);
+ m_buffer[59] = rotateLeft(m_buffer[43] ^ m_buffer[45] ^ m_buffer[51] ^ m_buffer[56], 1);
+ m_buffer[60] = rotateLeft(m_buffer[44] ^ m_buffer[46] ^ m_buffer[52] ^ m_buffer[57], 1);
+ m_buffer[61] = rotateLeft(m_buffer[45] ^ m_buffer[47] ^ m_buffer[53] ^ m_buffer[58], 1);
+ m_buffer[62] = rotateLeft(m_buffer[46] ^ m_buffer[48] ^ m_buffer[54] ^ m_buffer[59], 1);
+ m_buffer[63] = rotateLeft(m_buffer[47] ^ m_buffer[49] ^ m_buffer[55] ^ m_buffer[60], 1);
+
+ m_buffer[64] = rotateLeft(m_buffer[48] ^ m_buffer[50] ^ m_buffer[56] ^ m_buffer[61], 1);
+ m_buffer[65] = rotateLeft(m_buffer[49] ^ m_buffer[51] ^ m_buffer[57] ^ m_buffer[62], 1);
+ m_buffer[66] = rotateLeft(m_buffer[50] ^ m_buffer[52] ^ m_buffer[58] ^ m_buffer[63], 1);
+ m_buffer[67] = rotateLeft(m_buffer[51] ^ m_buffer[53] ^ m_buffer[59] ^ m_buffer[64], 1);
+ m_buffer[68] = rotateLeft(m_buffer[52] ^ m_buffer[54] ^ m_buffer[60] ^ m_buffer[65], 1);
+ m_buffer[69] = rotateLeft(m_buffer[53] ^ m_buffer[55] ^ m_buffer[61] ^ m_buffer[66], 1);
+ m_buffer[70] = rotateLeft(m_buffer[54] ^ m_buffer[56] ^ m_buffer[62] ^ m_buffer[67], 1);
+ m_buffer[71] = rotateLeft(m_buffer[55] ^ m_buffer[57] ^ m_buffer[63] ^ m_buffer[68], 1);
+ m_buffer[72] = rotateLeft(m_buffer[56] ^ m_buffer[58] ^ m_buffer[64] ^ m_buffer[69], 1);
+ m_buffer[73] = rotateLeft(m_buffer[57] ^ m_buffer[59] ^ m_buffer[65] ^ m_buffer[70], 1);
+ m_buffer[74] = rotateLeft(m_buffer[58] ^ m_buffer[60] ^ m_buffer[66] ^ m_buffer[71], 1);
+ m_buffer[75] = rotateLeft(m_buffer[59] ^ m_buffer[61] ^ m_buffer[67] ^ m_buffer[72], 1);
+ m_buffer[76] = rotateLeft(m_buffer[60] ^ m_buffer[62] ^ m_buffer[68] ^ m_buffer[73], 1);
+ m_buffer[77] = rotateLeft(m_buffer[61] ^ m_buffer[63] ^ m_buffer[69] ^ m_buffer[74], 1);
+ m_buffer[78] = rotateLeft(m_buffer[62] ^ m_buffer[64] ^ m_buffer[70] ^ m_buffer[75], 1);
+ m_buffer[79] = rotateLeft(m_buffer[63] ^ m_buffer[65] ^ m_buffer[71] ^ m_buffer[76], 1);
}
-/* SHA1 final padding and digest calculation */
-
-#if (PLATFORM_BYTE_ORDER == SHA_LITTLE_ENDIAN)
-static uint32 mask[4] =
- { 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff };
-static uint32 bits[4] =
- { 0x00000080, 0x00008000, 0x00800000, 0x80000000 };
-#else
-static uint32 mask[4] =
- { 0x00000000, 0xff000000, 0xffff0000, 0xffffff00 };
-static uint32 bits[4] =
- { 0x80000000, 0x00800000, 0x00008000, 0x00000080 };
-#endif
+namespace
+{
+ // ch transformation
+ template< uint32 round >
+ __forceinline void F(const CSHA::TransformArray& data, uint32& a, uint32& b, uint32 c, uint32 d, uint32 e, uint32& t)
+ {
+ t = a;
+ a = rotateLeft(a, 5) + e + data[round] + 0x5a827999 + (d ^ (b & (c ^ d)));
+ b = rotateLeft(b, 30);
+ }
+ // parity transformation
+ template< uint32 round >
+ __forceinline void G(const CSHA::TransformArray& data, uint32& a, uint32& b, uint32 c, uint32 d, uint32 e, uint32& t)
+ {
+ t = a;
+ a = rotateLeft(a, 5) + e + data[round + 20] + 0x6ed9eba1 + (b ^ c ^ d);
+ b = rotateLeft(b, 30);
+ }
+ // maj transformation
+ template< uint32 round >
+ __forceinline void H(const CSHA::TransformArray& data, uint32& a, uint32& b, uint32 c, uint32 d, uint32 e, uint32& t)
+ {
+ t = a;
+ a = rotateLeft(a, 5) + e + data[round + 40] + 0x8f1bbcdc + ((c & d) ^ (b & (c ^ d)));
+ b = rotateLeft(b, 30);
+ }
+ // parity transformation
+ template< uint32 round >
+ __forceinline void I(const CSHA::TransformArray& data, uint32& a, uint32& b, uint32 c, uint32 d, uint32 e, uint32& t)
+ {
+ t = a;
+ a = rotateLeft(a, 5) + e + data[round + 60] + 0xca62c1d6 + (b ^ c ^ d);
+ b = rotateLeft(b, 30);
+ }
+} // namespace
+
+void CSHA::Transform(TransformArray w)
+{
+ uint32 a = m_State.m_nState[0];
+ uint32 b = m_State.m_nState[1];
+ uint32 c = m_State.m_nState[2];
+ uint32 d = m_State.m_nState[3];
+ uint32 e = m_State.m_nState[4];
+ uint32 t;
+
+ F< 0 >(w, a, b, c, d, e, t);
+ F< 1 >(w, a, t, b, c, d, e);
+ F< 2 >(w, a, e, t, b, c, d);
+ F< 3 >(w, a, d, e, t, b, c);
+ F< 4 >(w, a, c, d, e, t, b);
+ F< 5 >(w, a, b, c, d, e, t);
+ F< 6 >(w, a, t, b, c, d, e);
+ F< 7 >(w, a, e, t, b, c, d);
+ F< 8 >(w, a, d, e, t, b, c);
+ F< 9 >(w, a, c, d, e, t, b);
+ F< 10 >(w, a, b, c, d, e, t);
+ F< 11 >(w, a, t, b, c, d, e);
+ F< 12 >(w, a, e, t, b, c, d);
+ F< 13 >(w, a, d, e, t, b, c);
+ F< 14 >(w, a, c, d, e, t, b);
+ F< 15 >(w, a, b, c, d, e, t);
+ F< 16 >(w, a, t, b, c, d, e);
+ F< 17 >(w, a, e, t, b, c, d);
+ F< 18 >(w, a, d, e, t, b, c);
+ F< 19 >(w, a, c, d, e, t, b);
+
+ G< 0 >(w, a, b, c, d, e, t);
+ G< 1 >(w, a, t, b, c, d, e);
+ G< 2 >(w, a, e, t, b, c, d);
+ G< 3 >(w, a, d, e, t, b, c);
+ G< 4 >(w, a, c, d, e, t, b);
+ G< 5 >(w, a, b, c, d, e, t);
+ G< 6 >(w, a, t, b, c, d, e);
+ G< 7 >(w, a, e, t, b, c, d);
+ G< 8 >(w, a, d, e, t, b, c);
+ G< 9 >(w, a, c, d, e, t, b);
+ G< 10 >(w, a, b, c, d, e, t);
+ G< 11 >(w, a, t, b, c, d, e);
+ G< 12 >(w, a, e, t, b, c, d);
+ G< 13 >(w, a, d, e, t, b, c);
+ G< 14 >(w, a, c, d, e, t, b);
+ G< 15 >(w, a, b, c, d, e, t);
+ G< 16 >(w, a, t, b, c, d, e);
+ G< 17 >(w, a, e, t, b, c, d);
+ G< 18 >(w, a, d, e, t, b, c);
+ G< 19 >(w, a, c, d, e, t, b);
+
+ H< 0 >(w, a, b, c, d, e, t);
+ H< 1 >(w, a, t, b, c, d, e);
+ H< 2 >(w, a, e, t, b, c, d);
+ H< 3 >(w, a, d, e, t, b, c);
+ H< 4 >(w, a, c, d, e, t, b);
+ H< 5 >(w, a, b, c, d, e, t);
+ H< 6 >(w, a, t, b, c, d, e);
+ H< 7 >(w, a, e, t, b, c, d);
+ H< 8 >(w, a, d, e, t, b, c);
+ H< 9 >(w, a, c, d, e, t, b);
+ H< 10 >(w, a, b, c, d, e, t);
+ H< 11 >(w, a, t, b, c, d, e);
+ H< 12 >(w, a, e, t, b, c, d);
+ H< 13 >(w, a, d, e, t, b, c);
+ H< 14 >(w, a, c, d, e, t, b);
+ H< 15 >(w, a, b, c, d, e, t);
+ H< 16 >(w, a, t, b, c, d, e);
+ H< 17 >(w, a, e, t, b, c, d);
+ H< 18 >(w, a, d, e, t, b, c);
+ H< 19 >(w, a, c, d, e, t, b);
+
+ I< 0 >(w, a, b, c, d, e, t);
+ I< 1 >(w, a, t, b, c, d, e);
+ I< 2 >(w, a, e, t, b, c, d);
+ I< 3 >(w, a, d, e, t, b, c);
+ I< 4 >(w, a, c, d, e, t, b);
+ I< 5 >(w, a, b, c, d, e, t);
+ I< 6 >(w, a, t, b, c, d, e);
+ I< 7 >(w, a, e, t, b, c, d);
+ I< 8 >(w, a, d, e, t, b, c);
+ I< 9 >(w, a, c, d, e, t, b);
+ I< 10 >(w, a, b, c, d, e, t);
+ I< 11 >(w, a, t, b, c, d, e);
+ I< 12 >(w, a, e, t, b, c, d);
+ I< 13 >(w, a, d, e, t, b, c);
+ I< 14 >(w, a, c, d, e, t, b);
+ I< 15 >(w, a, b, c, d, e, t);
+ I< 16 >(w, a, t, b, c, d, e);
+ I< 17 >(w, a, e, t, b, c, d);
+ I< 18 >(w, a, d, e, t, b, c);
+ I< 19 >(w, a, c, d, e, t, b);
+
+ m_State.m_nState[0] += a;
+ m_State.m_nState[1] += b;
+ m_State.m_nState[2] += c;
+ m_State.m_nState[3] += d;
+ m_State.m_nState[4] += e;
+}
-void CSHA::Finish(CAICHHash& Hash)
+void CSHA::Add(const void* pData, std::size_t nLength)
{
- uint32 i = (uint32)(m_nCount[0] & SHA1_MASK);
-
- /* mask out the rest of any partial 32-bit word and then set */
- /* the next byte to 0x80. On big-endian machines any bytes in */
- /* the buffer will be at the top end of 32 bit words, on little */
- /* endian machines they will be at the bottom. Hence the AND */
- /* and OR masks above are reversed for little endian systems */
- /* Note that we can always add the first padding byte at this */
- /* because the buffer always contains at least one empty slot */
- m_nBuffer[i >> 2] = (m_nBuffer[i >> 2] & mask[i & 3]) | bits[i & 3];
-
- /* we need 9 or more empty positions, one for the padding byte */
- /* (above) and eight for the length count. If there is not */
- /* enough space pad and empty the buffer */
- if(i > SHA1_BLOCK_SIZE - 9)
- {
- if(i < 60) m_nBuffer[15] = 0;
- Compile();
- i = 0;
- }
- else /* compute a word index for the empty buffer positions */
- i = (i >> 2) + 1;
-
- while(i < 14) /* and zero pad all but last two positions */
- m_nBuffer[i++] = 0;
-
- /* assemble the eight byte counter in in big-endian format */
- m_nBuffer[14] = swap_b32((m_nCount[1] << 3) | (m_nCount[0] >> 29));
- m_nBuffer[15] = swap_b32(m_nCount[0] << 3);
-
- Compile();
- GetHash(Hash);
+ // Update number of bytes
+ const char* input = static_cast< const char* >(pData);
+ {
+ uint32 index = static_cast< uint32 >(m_State.m_nCount % m_State.blockSize);
+ m_State.m_nCount += nLength;
+ if (index)
+ {
+ // buffer has some data already - lets fill it
+ // before doing the rest of the transformation on the original data
+ if (index + nLength < m_State.blockSize)
+ {
+ std::memcpy(m_State.m_oBuffer + index, input, nLength);
+ return;
+ }
+ std::memcpy(m_State.m_oBuffer + index, input, m_State.blockSize - index);
+ nLength -= m_State.blockSize - index;
+ input += m_State.blockSize - index;
+ Transform(reinterpret_cast< const uint32* >(m_State.m_oBuffer));
+ }
+ }
+ // Transform as many times as possible using the original data stream
+ const char* const end = input + nLength - nLength % m_State.blockSize;
+ nLength %= m_State.blockSize;
+ for (; input != end; input += m_State.blockSize)
+ {
+ Transform(reinterpret_cast< const uint32* >(input));
+ }
+ // Buffer remaining input
+ if (nLength)
+ std::memcpy(m_State.m_oBuffer, input, nLength);
}
+
+#endif // HASHLIB_USE_ASM
+
+// ---------------------------------------------------------------------------
+// Copyright (c) 2002, Dr Brian Gladman , Worcester, UK.
+// All rights reserved.
+
+// LICENSE TERMS
+
+// The free distribution and use of this software in both source and binary
+// form is allowed (with or without changes) provided that:
+
+// 1. distributions of this source code include the above copyright
+// notice, this list of conditions and the following disclaimer;
+
+// 2. distributions in binary form include the above copyright
+// notice, this list of conditions and the following disclaimer
+// in the documentation and/or other associated materials;
+
+// 3. the copyright holder's name is not used to endorse products
+// built using this software without specific written permission.
+
+// ALTERNATIVELY, provided that this notice is retained in full, this product
+// may be distributed under the terms of the GNU General Public License (GPL),
+// in which case the provisions of the GPL apply INSTEAD OF those given above.
+//
+// DISCLAIMER
+
+// This software is provided 'as is' with no explicit or implied warranties
+// in respect of its properties, including, but not limited to, correctness
+// and/or fitness for purpose.
+// ---------------------------------------------------------------------------
+// Issue Date: 30/11/2002
+
+// This is a byte oriented version of SHA1 that operates on arrays of bytes
+// stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor
\ No newline at end of file
diff --git a/hasher/SHA.h b/hasher/SHA.h
index f9175732c..a9efa0c4b 100644
--- a/hasher/SHA.h
+++ b/hasher/SHA.h
@@ -1,93 +1,69 @@
//
-// This file is part of the aMule Project.
+// SHA.h
//
-// Copyright (c) 2003-2006 Angel Vidal (Kry) ( kry@amule.org )
-// Copyright (c) 2003-2006 aMule Team ( admin@amule.org / http://www.amule.org )
+// Copyright (c) Shareaza Development Team, 2002-2014.
+// This file is part of SHAREAZA (shareaza.sourceforge.net)
//
-// Any parts of this program derived from the xMule, lMule or eMule project,
-// or contributed by third-party developers are copyrighted by their
-// respective authors.
+// Shareaza is free software; you can redistribute it
+// and/or modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
+// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
//
-// Kry - Modified version of the original SHA.cpp to work on linux and
-// use wxWidgets. Original license follows.
+// You should have received a copy of the GNU General Public License
+// along with Shareaza; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2002, Dr Brian Gladman , Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
- 1. distributions of this source code include the above copyright
- notice, this list of conditions and the following disclaimer;
-
- 2. distributions in binary form include the above copyright
- notice, this list of conditions and the following disclaimer
- in the documentation and/or other associated materials;
-
- 3. the copyright holder's name is not used to endorse products
- built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
+#pragma once
+#include "Utility.hpp"
+class CSHA
+{
+public:
+ CSHA();
+ ~CSHA() {}
- DISCLAIMER
+ void Reset();
+ void Add(const void* pData, size_t nLength);
+ void Finish();
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 30/11/2002
+ struct Digest // 160 bit
+ {
+ uint32& operator[](size_t i) { return data[i]; }
+ const uint32& operator[](size_t i) const { return data[i]; }
+ uint32 data[5];
+ };
- This is a byte oriented version of SHA1 that operates on arrays of bytes
- stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor
-*/
+ void GetHash(__in_bcount(20) uchar* pHash) const;
-#ifndef __SHA_H__
-#define __SHA_H__
+#ifndef HASHLIB_USE_ASM
+ struct TransformArray
+ {
+ __forceinline TransformArray(const uint32* const buffer);
+ __forceinline uint32 operator[](uint32 index) const
+ {
+ return m_buffer[index];
+ }
+ uint32 m_buffer[80];
+ };
+#endif
-#include "ShaHashSet.h"
+ struct SHA1State
+ {
+ static const size_t blockSize = 64;
+ uint64 m_nCount;
+ uint32 m_nState[5];
+ uchar m_oBuffer[blockSize];
+ };
-class CSHA : public CAICHHashAlgo
-{
-// Construction
-public:
- CSHA();
- virtual ~CSHA() {};
-// Operations
-public:
- virtual void Reset();
- virtual void Add(const void* pData, uint32 nLength);
- virtual void Finish(CAICHHash& Hash);
- virtual void GetHash(CAICHHash& Hash);
-protected:
- void Compile();
private:
- uint32 m_nCount[2];
- uint32 m_nHash[5];
- uint32 m_nBuffer[16];
-};
-
-#define SHA1_BLOCK_SIZE 64
-#define SHA1_DIGEST_SIZE 20
+ SHA1State m_State;
-#endif // __SHA_H__
+#ifndef HASHLIB_USE_ASM
+ __forceinline void Transform(const TransformArray w);
+#endif
+};
\ No newline at end of file
diff --git a/hasher/SHAHashSet.cpp b/hasher/SHAHashSet.cpp
deleted file mode 100644
index 86cbcf572..000000000
--- a/hasher/SHAHashSet.cpp
+++ /dev/null
@@ -1,957 +0,0 @@
-//
-// This file is part of the aMule Project.
-//
-// Copyright (c) 2003-2006 Angel Vidal (Kry) ( kry@amule.org )
-// Copyright (c) 2003-2006 aMule Team ( admin@amule.org / http://www.amule.org )
-// Copyright (c) 2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
-//
-// Any parts of this program derived from the xMule, lMule or eMule project,
-// or contributed by third-party developers are copyrighted by their
-// respective authors.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
-//
-#include "StdAfx.h"
-#include "SHAHashSet.h"
-//#include "Types.h"
-//#include "OPCodes.h"
-//#include "amule.h"
-//#include "MemFile.h"
-//#include "KnownFile.h"
-//#include "Preferences.h"
-#include "SHA.h"
-//#include "updownclient.h"
-//#include "DownloadQueue.h"
-//#include "PartFile.h"
-//#include "Logger.h"
-//#include
-
-#define ASSERT(b){if(!(b))printf("ASSERT!\n");}
-#define VERIFY(b){if(!(b))printf("VERIFY!\n");}
-void out(const char * str){
- printf("OUT: %s\n",str);
-}
-
-//#include
-
-//using namespace std;
-
-/*#ifdef _DEBUG
-#undef THIS_FILE
-static char THIS_FILE[]=__FILE__;
-#define new DEBUG_NEW
-#endif*/
-
-// for this version the limits are set very high, they might be lowered later
-// to make a hash trustworthy, at least 10 unique Ips (255.255.128.0) must have send it
-// and if we have received more than one hash for the file, one hash has to be send by more than 95% of all unique IPs
-//#define MINUNIQUEIPS_TOTRUST 10 // how many unique IPs most have send us a hash to make it trustworthy
-//#define MINPERCENTAGE_TOTRUST 92 // how many percentage of clients most have sent the same hash to make it trustworthy
-
-//CAICHRequestedDataList CAICHHashSet::m_liRequestedData;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-///CAICHHash
-/*wxString CAICHHash::GetString() const{
- return EncodeBase32(m_abyBuffer, HASHSIZE);
-}*/
-
-
-/*void CAICHHash::Read(CFileDataIO* file) {
- file->Read(m_abyBuffer,HASHSIZE);
-}
-
-
-void CAICHHash::Write(CFileDataIO* file) const{
- file->Write(m_abyBuffer,HASHSIZE);
-}*/
-
-/*unsigned int CAICHHash::DecodeBase32(const wxString &base32)
-{
- return ::DecodeBase32(base32, HASHSIZE, m_abyBuffer);
-} */
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-///CAICHHashTree
-
-CAICHHashTree::CAICHHashTree(uint64 nDataSize, bool bLeftBranch, uint64 nBaseSize){
- m_nDataSize = nDataSize;
- m_nBaseSize = nBaseSize;
- m_bIsLeftBranch = bLeftBranch;
- m_pLeftTree = NULL;
- m_pRightTree = NULL;
- m_bHashValid = false;
-}
-
-CAICHHashTree::~CAICHHashTree(){
- if (m_pLeftTree)
- delete m_pLeftTree;
- if (m_pRightTree)
- delete m_pRightTree;
-}
-
-// recursive
-CAICHHashTree* CAICHHashTree::FindHash(uint64 nStartPos, uint64 nSize, uint8* nLevel){
- (*nLevel)++;
- if (*nLevel > 22){ // sanity
- ASSERT ( false );
- return false;
- }
- if (nStartPos + nSize > m_nDataSize){ // sanity
- ASSERT ( false );
- return NULL;
- }
- if (nSize > m_nDataSize){ // sanity
- ASSERT ( false );
- return NULL;
- }
-
- if (nStartPos == 0 && nSize == m_nDataSize){
- // this is the searched hash
- return this;
- }
- else if (m_nDataSize <= m_nBaseSize){ // sanity
- // this is already the last level, cant go deeper
- ASSERT( false );
- return NULL;
- }
- else{
- uint64 nBlocks = m_nDataSize / m_nBaseSize + ((m_nDataSize % m_nBaseSize != 0 )? 1:0);
- uint64 nLeft = ( ((m_bIsLeftBranch) ? nBlocks+1:nBlocks) / 2)* m_nBaseSize;
- uint64 nRight = m_nDataSize - nLeft;
- if (nStartPos < nLeft){
- if (nStartPos + nSize > nLeft){ // sanity
- ASSERT ( false );
- return NULL;
- }
- if (m_pLeftTree == NULL)
- m_pLeftTree = new CAICHHashTree(nLeft, true, (nLeft <= PARTSIZE) ? EMBLOCKSIZE : PARTSIZE);
- else{
- ASSERT( m_pLeftTree->m_nDataSize == nLeft );
- }
- return m_pLeftTree->FindHash(nStartPos, nSize, nLevel);
- }
- else{
- nStartPos -= nLeft;
- if (nStartPos + nSize > nRight){ // sanity
- ASSERT ( false );
- return NULL;
- }
- if (m_pRightTree == NULL)
- m_pRightTree = new CAICHHashTree(nRight, false, (nRight <= PARTSIZE) ? EMBLOCKSIZE : PARTSIZE);
- else{
- ASSERT( m_pRightTree->m_nDataSize == nRight );
- }
- return m_pRightTree->FindHash(nStartPos, nSize, nLevel);
- }
- }
-}
-
-// recursive
-// calculates missing hash fromt he existing ones
-// overwrites existing hashs
-// fails if no hash is found for any branch
-bool CAICHHashTree::ReCalculateHash(CAICHHashAlgo* hashalg, bool bDontReplace){
- ASSERT ( !( (m_pLeftTree != NULL) ^ (m_pRightTree != NULL)) );
- if (m_pLeftTree && m_pRightTree){
- if ( !m_pLeftTree->ReCalculateHash(hashalg, bDontReplace) || !m_pRightTree->ReCalculateHash(hashalg, bDontReplace) )
- return false;
- if (bDontReplace && m_bHashValid)
- return true;
- if (m_pRightTree->m_bHashValid && m_pLeftTree->m_bHashValid){
- hashalg->Reset();
- hashalg->Add(m_pLeftTree->m_Hash.GetRawHash(), HASHSIZE);
- hashalg->Add(m_pRightTree->m_Hash.GetRawHash(), HASHSIZE);
- hashalg->Finish(m_Hash);
- m_bHashValid = true;
- return true;
- }
- else
- return m_bHashValid;
- }
- else
- return true;
-}
-
-bool CAICHHashTree::VerifyHashTree(CAICHHashAlgo* hashalg, bool bDeleteBadTrees){
- if (!m_bHashValid){
- ASSERT ( false );
- if (bDeleteBadTrees){
- if (m_pLeftTree){
- delete m_pLeftTree;
- m_pLeftTree = NULL;
- }
- if (m_pRightTree){
- delete m_pRightTree;
- m_pRightTree = NULL;
- }
- }
- //AddDebugLogLineM( false, logSHAHashSet, wxT("VerifyHashTree - No masterhash available"));
- printf("VerifyHashTree - No masterhash available\n");
- return false;
- }
-
- // calculated missing hashs without overwriting anything
- if (m_pLeftTree && !m_pLeftTree->m_bHashValid)
- m_pLeftTree->ReCalculateHash(hashalg, true);
- if (m_pRightTree && !m_pRightTree->m_bHashValid)
- m_pRightTree->ReCalculateHash(hashalg, true);
-
- if ((m_pRightTree && m_pRightTree->m_bHashValid) ^ (m_pLeftTree && m_pLeftTree->m_bHashValid)){
- // one branch can never be verified
- if (bDeleteBadTrees){
- if (m_pLeftTree){
- delete m_pLeftTree;
- m_pLeftTree = NULL;
- }
- if (m_pRightTree){
- delete m_pRightTree;
- m_pRightTree = NULL;
- }
- }
- //AddDebugLogLineM( false, logSHAHashSet, wxT("VerifyHashSet failed - Hashtree incomplete"));
- printf("VerifyHashSet failed - Hashtree incomplete\n");
- return false;
- }
- if ((m_pRightTree && m_pRightTree->m_bHashValid) && (m_pLeftTree && m_pLeftTree->m_bHashValid)){
- // check verify the hashs of both child nodes against my hash
-
- CAICHHash CmpHash;
- hashalg->Reset();
- hashalg->Add(m_pLeftTree->m_Hash.GetRawHash(), HASHSIZE);
- hashalg->Add(m_pRightTree->m_Hash.GetRawHash(), HASHSIZE);
- hashalg->Finish(CmpHash);
-
- if (m_Hash != CmpHash){
- if (bDeleteBadTrees){
- if (m_pLeftTree){
- delete m_pLeftTree;
- m_pLeftTree = NULL;
- }
- if (m_pRightTree){
- delete m_pRightTree;
- m_pRightTree = NULL;
- }
- }
- return false;
- }
- return m_pLeftTree->VerifyHashTree(hashalg, bDeleteBadTrees) && m_pRightTree->VerifyHashTree(hashalg, bDeleteBadTrees);
- }
- else
- // last hash in branch - nothing below to verify
- return true;
-
-}
-
-void CAICHHashTree::SetBlockHash(uint64 nSize, uint64 nStartPos, CAICHHashAlgo* pHashAlg){
- ASSERT ( nSize <= EMBLOCKSIZE );
- CAICHHashTree* pToInsert = FindHash(nStartPos, nSize);
- if (pToInsert == NULL){ // sanity
- ASSERT ( false );
- //AddDebugLogLineM( false, logSHAHashSet, wxT("Critical Error: Failed to Insert SHA-HashBlock, FindHash() failed!"));
- out("Critical Error: Failed to Insert SHA-HashBlock, FindHash() failed!");
- return;
- }
-
- //sanity
- if (pToInsert->m_nBaseSize != EMBLOCKSIZE || pToInsert->m_nDataSize != nSize){
- ASSERT ( false );
- //AddDebugLogLineM( false, logSHAHashSet, wxT("Critical Error: Logical error on values in SetBlockHashFromData"));
- out("Critical Error: Logical error on values in SetBlockHashFromData");
- return;
- }
-
- pHashAlg->Finish(pToInsert->m_Hash);
- pToInsert->m_bHashValid = true;
-}
-/*
-bool CAICHHashTree::CreatePartRecoveryData(uint32 nStartPos, uint32 nSize, CFileDataIO* fileDataOut, uint16 wHashIdent){
- if (nStartPos + nSize > m_nDataSize){ // sanity
- ASSERT ( false );
- return false;
- }
- if (nSize > m_nDataSize){ // sanity
- ASSERT ( false );
- return false;
- }
-
- if (nStartPos == 0 && nSize == m_nDataSize){
- // this is the searched part, now write all blocks of this part
- // hashident for this level will be adjsuted by WriteLowestLevelHash
- return WriteLowestLevelHashs(fileDataOut, wHashIdent);
- }
- else if (m_nDataSize <= m_nBaseSize){ // sanity
- // this is already the last level, cant go deeper
- ASSERT( false );
- return false;
- }
- else{
- wHashIdent <<= 1;
- wHashIdent |= (m_bIsLeftBranch) ? 1: 0;
-
- uint32 nBlocks = m_nDataSize / m_nBaseSize + ((m_nDataSize % m_nBaseSize != 0 )? 1:0);
- uint32 nLeft = ( ((m_bIsLeftBranch) ? nBlocks+1:nBlocks) / 2)* m_nBaseSize;
- uint32 nRight = m_nDataSize - nLeft;
- if (m_pLeftTree == NULL || m_pRightTree == NULL){
- ASSERT( false );
- return false;
- }
- if (nStartPos < nLeft){
- if (nStartPos + nSize > nLeft || !m_pRightTree->m_bHashValid){ // sanity
- ASSERT ( false );
- return false;
- }
- m_pRightTree->WriteHash(fileDataOut, wHashIdent);
- return m_pLeftTree->CreatePartRecoveryData(nStartPos, nSize, fileDataOut, wHashIdent);
- }
- else{
- nStartPos -= nLeft;
- if (nStartPos + nSize > nRight || !m_pLeftTree->m_bHashValid){ // sanity
- ASSERT ( false );
- return false;
- }
- m_pLeftTree->WriteHash(fileDataOut, wHashIdent);
- return m_pRightTree->CreatePartRecoveryData(nStartPos, nSize, fileDataOut, wHashIdent);
-
- }
- }
-}
-
-void CAICHHashTree::WriteHash(CFileDataIO* fileDataOut, uint16 wHashIdent) const{
- ASSERT( m_bHashValid );
- wHashIdent <<= 1;
- wHashIdent |= (m_bIsLeftBranch) ? 1: 0;
- fileDataOut->WriteUInt16(wHashIdent);
- m_Hash.Write(fileDataOut);
-}
-
-// write lowest level hashs into file, ordered from left to right optional without identifier
-bool CAICHHashTree::WriteLowestLevelHashs(CFileDataIO* fileDataOut, uint16 wHashIdent, bool bNoIdent) const{
- wHashIdent <<= 1;
- wHashIdent |= (m_bIsLeftBranch) ? 1: 0;
- if (m_pLeftTree == NULL && m_pRightTree == NULL){
- if (m_nDataSize <= m_nBaseSize && m_bHashValid ){
- if (!bNoIdent)
- fileDataOut->WriteUInt16(wHashIdent);
- m_Hash.Write(fileDataOut);
- return true;
- }
- else{
- ASSERT( false );
- return false;
- }
- }
- else if (m_pLeftTree == NULL || m_pRightTree == NULL){
- ASSERT( false );
- return false;
- }
- else{
- return m_pLeftTree->WriteLowestLevelHashs(fileDataOut, wHashIdent, bNoIdent)
- && m_pRightTree->WriteLowestLevelHashs(fileDataOut, wHashIdent, bNoIdent);
- }
-}
-
-// recover all low level hashs from given data. hashs are assumed to be ordered in left to right - no identifier used
-bool CAICHHashTree::LoadLowestLevelHashs(CFileDataIO* fileInput){
- if (m_nDataSize <= m_nBaseSize){ // sanity
- // lowest level, read hash
- m_Hash.Read(fileInput);
- m_bHashValid = true;
- return true;
- }
- else{
- uint32 nBlocks = m_nDataSize / m_nBaseSize + ((m_nDataSize % m_nBaseSize != 0 )? 1:0);
- uint32 nLeft = ( ((m_bIsLeftBranch) ? nBlocks+1:nBlocks) / 2)* m_nBaseSize;
- uint32 nRight = m_nDataSize - nLeft;
- if (m_pLeftTree == NULL)
- m_pLeftTree = new CAICHHashTree(nLeft, true, (nLeft <= PARTSIZE) ? EMBLOCKSIZE : PARTSIZE);
- else{
- ASSERT( m_pLeftTree->m_nDataSize == nLeft );
- }
- if (m_pRightTree == NULL)
- m_pRightTree = new CAICHHashTree(nRight, false, (nRight <= PARTSIZE) ? EMBLOCKSIZE : PARTSIZE);
- else{
- ASSERT( m_pRightTree->m_nDataSize == nRight );
- }
- return m_pLeftTree->LoadLowestLevelHashs(fileInput)
- && m_pRightTree->LoadLowestLevelHashs(fileInput);
- }
-}
-
-
-// write the hash, specified by wHashIdent, with Data from fileInput.
-bool CAICHHashTree::SetHash(CFileDataIO* fileInput, uint16 wHashIdent, sint8 nLevel, bool bAllowOverwrite){
- if (nLevel == (-1)){
- // first call, check how many level we need to go
- uint8 i;
- for (i = 0; i != 16 && (wHashIdent & 0x8000) == 0; ++i){
- wHashIdent <<= 1;
- }
- if (i > 15){
- AddDebugLogLineM( false, logSHAHashSet, wxT("CAICHHashTree::SetHash - found invalid HashIdent (0)"));
- return false;
- }
- else{
- nLevel = 15 - i;
- }
- }
- if (nLevel == 0){
- // this is the searched hash
- if (m_bHashValid && !bAllowOverwrite){
- // not allowed to overwrite this hash, however move the filepointer by reading a hash
- CAICHHash(file);
- return true;
- }
- m_Hash.Read(fileInput);
- m_bHashValid = true;
- return true;
- }
- else if (m_nDataSize <= m_nBaseSize){ // sanity
- // this is already the last level, cant go deeper
- ASSERT( false );
- return false;
- }
- else{
- // adjust ident to point the path to the next node
- wHashIdent <<= 1;
- nLevel--;
- uint32 nBlocks = m_nDataSize / m_nBaseSize + ((m_nDataSize % m_nBaseSize != 0 )? 1:0);
- uint32 nLeft = ( ((m_bIsLeftBranch) ? nBlocks+1:nBlocks) / 2)* m_nBaseSize;
- uint32 nRight = m_nDataSize - nLeft;
- if ((wHashIdent & 0x8000) > 0){
- if (m_pLeftTree == NULL)
- m_pLeftTree = new CAICHHashTree(nLeft, true, (nLeft <= PARTSIZE) ? EMBLOCKSIZE : PARTSIZE);
- else{
- ASSERT( m_pLeftTree->m_nDataSize == nLeft );
- }
- return m_pLeftTree->SetHash(fileInput, wHashIdent, nLevel);
- }
- else{
- if (m_pRightTree == NULL)
- m_pRightTree = new CAICHHashTree(nRight, false, (nRight <= PARTSIZE) ? EMBLOCKSIZE : PARTSIZE);
- else{
- ASSERT( m_pRightTree->m_nDataSize == nRight );
- }
- return m_pRightTree->SetHash(fileInput, wHashIdent, nLevel);
- }
- }
-}*/
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-///CAICHUntrustedHash
-/*bool CAICHUntrustedHash::AddSigningIP(uint32 dwIP){
- dwIP &= 0x00F0FFFF; // we use only the 20 most significant bytes for unique IPs
- return m_adwIpsSigning.insert(dwIP).second;
-}*/
-
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-///CAICHHashSet
-
-CAICHHashSet::CAICHHashSet()//CKnownFile* pOwner)
- : m_pHashTree(0, true, PARTSIZE)
-{
- m_eStatus = AICH_EMPTY;
- //m_pOwner = pOwner;
-}
-
-CAICHHashSet::~CAICHHashSet(void)
-{
- FreeHashSet();
-}
-/*
-bool CAICHHashSet::CreatePartRecoveryData(uint32 nPartStartPos, CFileDataIO* fileDataOut, bool bDbgDontLoad){
- ASSERT( m_pOwner );
- if (m_pOwner->IsPartFile() || m_eStatus != AICH_HASHSETCOMPLETE){
- ASSERT( false );
- return false;
- }
- if (m_pHashTree.m_nDataSize <= EMBLOCKSIZE){
- ASSERT( false );
- return false;
- }
- if (!bDbgDontLoad){
- if (!LoadHashSet()){
- AddDebugLogLineM( false, logSHAHashSet, wxT("Created RecoveryData error: failed to load hashset. File:") + m_pOwner->GetFileName() );
- SetStatus(AICH_ERROR);
- return false;
- }
- }
- bool bResult;
- uint8 nLevel = 0;
- uint32 nPartSize = min(PARTSIZE, m_pOwner->GetFileSize()-nPartStartPos);
- m_pHashTree.FindHash(nPartStartPos, nPartSize,&nLevel);
- uint16 nHashsToWrite = (nLevel-1) + nPartSize/EMBLOCKSIZE + ((nPartSize % EMBLOCKSIZE != 0 )? 1:0);
- fileDataOut->WriteUInt16(nHashsToWrite);
- uint32 nCheckFilePos = fileDataOut->GetPosition();
- if (m_pHashTree.CreatePartRecoveryData(nPartStartPos, nPartSize, fileDataOut, 0)){
- if (nHashsToWrite*(HASHSIZE+2u) != fileDataOut->GetPosition() - nCheckFilePos){
- ASSERT( false );
- AddDebugLogLineM( false, logSHAHashSet, wxT("Created RecoveryData has wrong length. File: ") + m_pOwner->GetFileName() );
- bResult = false;
- SetStatus(AICH_ERROR);
- }
- else
- bResult = true;
- } else {
- AddDebugLogLineM( false, logSHAHashSet, wxT("Failed to create RecoveryData for ") + m_pOwner->GetFileName() );
- bResult = false;
- SetStatus(AICH_ERROR);
- }
- if (!bDbgDontLoad){
- FreeHashSet();
- }
- return bResult;
-}
-
-bool CAICHHashSet::ReadRecoveryData(uint32 nPartStartPos, CMemFile* fileDataIn)
-{
- if (!(m_eStatus == AICH_VERIFIED || m_eStatus == AICH_TRUSTED) ){
- ASSERT( false );
- return false;
- }
- // at this time we check the recoverydata for the correct ammounts of hashs only
- // all hash are then taken into the tree, depending on there hashidentifier (except the masterhash)
-
- uint8 nLevel = 0;
- uint32 nPartSize = min(PARTSIZE, m_pOwner->GetFileSize()-nPartStartPos);
- m_pHashTree.FindHash(nPartStartPos, nPartSize,&nLevel);
- uint16 nHashsToRead = (nLevel-1) + nPartSize/EMBLOCKSIZE + ((nPartSize % EMBLOCKSIZE != 0 )? 1:0);
- uint16 nHashsAvailable = fileDataIn->ReadUInt16();
- if (fileDataIn->GetLength()-fileDataIn->GetPosition() < nHashsToRead*(HASHSIZE+2u) || nHashsToRead != nHashsAvailable){
- // this check is redunant, CSafememfile would catch such an error too
- AddDebugLogLineM( false, logSHAHashSet, wxT("Failed to read RecoveryData for ") + m_pOwner->GetFileName() + wxT("%s - Received datasize/amounts of hashs was invalid"));
- return false;
- }
- for (uint32 i = 0; i != nHashsToRead; ++i){
- uint16 wHashIdent = fileDataIn->ReadUInt16();
- if (wHashIdent == 1 //never allow masterhash to be overwritten
- || !m_pHashTree.SetHash(fileDataIn, wHashIdent,(-1), false))
- {
- AddDebugLogLineM( false, logSHAHashSet, wxT("Failed to read RecoveryData for ") + m_pOwner->GetFileName() + wxT(" - Error when trying to read hash into tree"));
- VerifyHashTree(true); // remove invalid hashs which we have already written
- return false;
- }
- }
- if (VerifyHashTree(true)){
- // some final check if all hashs we wanted are there
- for (uint32 nPartPos = 0; nPartPos < nPartSize; nPartPos += EMBLOCKSIZE){
- CAICHHashTree* phtToCheck = m_pHashTree.FindHash(nPartStartPos+nPartPos, min(EMBLOCKSIZE, nPartSize-nPartPos));
- if (phtToCheck == NULL || !phtToCheck->m_bHashValid){
- AddDebugLogLineM( false, logSHAHashSet, wxT("Failed to read RecoveryData for ") + m_pOwner->GetFileName() + wxT(" - Error while verifying presence of all lowest level hashs"));
- return false;
- }
- }
- // all done
- return true;
- }
- else{
- AddDebugLogLineM( false, logSHAHashSet, wxT("Failed to read RecoveryData for ") + m_pOwner->GetFileName() + wxT(" - Verifying received hashtree failed"));
- return false;
- }
-}
-
-// this function is only allowed to be called right after successfully calculating the hashset (!)
-// will delete the hashset, after saving to free the memory
-bool CAICHHashSet::SaveHashSet(){
- if (m_eStatus != AICH_HASHSETCOMPLETE){
- ASSERT( false );
- return false;
- }
- if ( !m_pHashTree.m_bHashValid || m_pHashTree.m_nDataSize != m_pOwner->GetFileSize()){
- ASSERT( false );
- return false;
- }
- wxString fullpath = theApp.ConfigDir + KNOWN2_MET_FILENAME;
- CFile file;
- if (wxFileExists(fullpath)) {
- if (!file.Open(fullpath, CFile::read_write)) {
- // Add logline about unable to open file
- return false;
- }
- } else {
- if (!file.Create(fullpath)) {
- // Add logline about unable to create file
- return false;
- }
- }
-
- try {
- // first we check if the hashset we want to write is already stored
- CAICHHash CurrentHash;
- uint32 nExistingSize = file.GetLength();
- while (file.GetPosition() < nExistingSize){
- CurrentHash.Read(&file);
- if (m_pHashTree.m_Hash == CurrentHash){
- // this hashset if already available, no need to save it again
- return true;
- }
- uint16 nHashCount = file.ReadUInt16();
- if (file.GetPosition() + nHashCount*HASHSIZE > nExistingSize){
- throw fullpath;
- }
- // skip the rest of this hashset
- file.Seek(nHashCount*HASHSIZE, wxFromCurrent);
- }
- // write hashset
- m_pHashTree.m_Hash.Write(&file);
- uint16 nHashCount = (PARTSIZE/EMBLOCKSIZE + ((PARTSIZE % EMBLOCKSIZE != 0)? 1 : 0)) * (m_pHashTree.m_nDataSize/PARTSIZE);
- if (m_pHashTree.m_nDataSize % PARTSIZE != 0)
- nHashCount += (m_pHashTree.m_nDataSize % PARTSIZE)/EMBLOCKSIZE + (((m_pHashTree.m_nDataSize % PARTSIZE) % EMBLOCKSIZE != 0)? 1 : 0);
- file.WriteUInt16(nHashCount);
- if (!m_pHashTree.WriteLowestLevelHashs(&file, 0, true)){
- // thats bad... really
- file.SetLength(nExistingSize);
- AddDebugLogLineM( true, logSHAHashSet, wxT("Failed to save HashSet: WriteLowestLevelHashs() failed!"));
- return false;
- }
- if (file.GetLength() != nExistingSize + (nHashCount+1)*HASHSIZE + 2){
- // thats even worse
- file.SetLength(nExistingSize);
- AddDebugLogLineM( true, logSHAHashSet, wxT("Failed to save HashSet: Calculated and real size of hashset differ!"));
- return false;
- }
- AddDebugLogLineM( false, logSHAHashSet, wxString::Format(wxT("Sucessfully saved eMuleAC Hashset, %u Hashs + 1 Masterhash written"), nHashCount));
- } catch (const wxString& error){
- AddDebugLogLineM(true, logSHAHashSet, wxT("Error: ") + error);
- return false;
- } catch (const CSafeIOException& e) {
- AddDebugLogLineM(true, logSHAHashSet, wxT("IO error while saving AICH HashSet: ") + e.what());
- return false;
- }
-
- FreeHashSet();
- return true;
-}
-
-
-bool CAICHHashSet::LoadHashSet()
-{
- if (m_eStatus != AICH_HASHSETCOMPLETE){
- ASSERT( false );
- return false;
- }
- if ( !m_pHashTree.m_bHashValid || m_pHashTree.m_nDataSize != m_pOwner->GetFileSize() || m_pHashTree.m_nDataSize == 0){
- ASSERT( false );
- return false;
- }
- wxString fullpath = theApp.ConfigDir + KNOWN2_MET_FILENAME;
- CFile file(fullpath, CFile::read_write);
- if (!file.IsOpened()){
- if (wxFileExists(fullpath)) {
- wxString strError(wxT("Failed to load ") KNOWN2_MET_FILENAME wxT(" file"));
- AddDebugLogLineM( true, logSHAHashSet, strError);
- }
- return false;
- }
-
- try {
- //setvbuf(file.m_pStream, NULL, _IOFBF, 16384);
- CAICHHash CurrentHash;
- uint32 nExistingSize = file.GetLength();
- uint16 nHashCount;
- while (file.GetPosition() < nExistingSize){
- CurrentHash.Read(&file);
- if (m_pHashTree.m_Hash == CurrentHash){
- // found Hashset
- uint32 nExpectedCount = (PARTSIZE/EMBLOCKSIZE + ((PARTSIZE % EMBLOCKSIZE != 0)? 1 : 0)) * (m_pHashTree.m_nDataSize/PARTSIZE);
- if (m_pHashTree.m_nDataSize % PARTSIZE != 0)
- nExpectedCount += (m_pHashTree.m_nDataSize % PARTSIZE)/EMBLOCKSIZE + (((m_pHashTree.m_nDataSize % PARTSIZE) % EMBLOCKSIZE != 0)? 1 : 0);
- nHashCount = file.ReadUInt16();
- if (nHashCount != nExpectedCount){
- AddDebugLogLineM( true, logSHAHashSet, wxT("Failed to load HashSet: Available Hashs and expected hashcount differ!"));
- return false;
- }
- if (!m_pHashTree.LoadLowestLevelHashs(&file)){
- AddDebugLogLineM( true, logSHAHashSet, wxT("Failed to load HashSet: LoadLowestLevelHashs failed!"));
- return false;
- }
- if (!ReCalculateHash(false)){
- AddDebugLogLineM( true, logSHAHashSet, wxT("Failed to load HashSet: Calculating loaded hashs failed!"));
- return false;
- }
- if (CurrentHash != m_pHashTree.m_Hash){
- AddDebugLogLineM( true, logSHAHashSet, wxT("Failed to load HashSet: Calculated Masterhash differs from given Masterhash - hashset corrupt!"));
- return false;
- }
- return true;
- }
- nHashCount = file.ReadUInt16();
- if (file.GetPosition() + nHashCount*HASHSIZE > nExistingSize){
- throw fullpath;
- }
- // skip the rest of this hashset
- file.Seek(nHashCount*HASHSIZE, wxFromCurrent);
- }
- AddDebugLogLineM( true, logSHAHashSet, wxT("Failed to load HashSet: HashSet not found!"));
- } catch (const wxString& error) {
- AddDebugLogLineM(true, logSHAHashSet, wxT("Error: ") + error);
- return false;
- } catch (const CSafeIOException& e) {
- AddDebugLogLineM(true, logSHAHashSet, wxT("IO error while loading AICH HashSet: ") + e.what());
- return false;
- }
-
-
- return false;
-}*/
-
-// delete the hashset except the masterhash (we dont keep aich hashsets in memory to save ressources)
-void CAICHHashSet::FreeHashSet(){
- if (m_pHashTree.m_pLeftTree){
- delete m_pHashTree.m_pLeftTree;
- m_pHashTree.m_pLeftTree = NULL;
- }
- if (m_pHashTree.m_pRightTree){
- delete m_pHashTree.m_pRightTree;
- m_pHashTree.m_pRightTree = NULL;
- }
-}
-
-/*void CAICHHashSet::SetMasterHash(const CAICHHash& Hash, EAICHStatus eNewStatus){
- m_pHashTree.m_Hash = Hash;
- m_pHashTree.m_bHashValid = true;
- SetStatus(eNewStatus);
-}*/
-
-CAICHHashAlgo* CAICHHashSet::GetNewHashAlgo(){
- return new CSHA();
-}
-
-bool CAICHHashSet::ReCalculateHash(bool bDontReplace){
- CAICHHashAlgo* hashalg = GetNewHashAlgo();
- bool bResult = m_pHashTree.ReCalculateHash(hashalg, bDontReplace);
- delete hashalg;
- return bResult;
-}
-
-bool CAICHHashSet::VerifyHashTree(bool bDeleteBadTrees){
- CAICHHashAlgo* hashalg = GetNewHashAlgo();
- bool bResult = m_pHashTree.VerifyHashTree(hashalg, bDeleteBadTrees);
- delete hashalg;
- return bResult;
-}
-
-void CAICHHashSet::SetFileSize(EMFileSize nSize){
- m_pHashTree.m_nDataSize = nSize;
- m_pHashTree.m_nBaseSize = (nSize <= (uint64)PARTSIZE) ? EMBLOCKSIZE : PARTSIZE;
-}
-/*
-void CAICHHashSet::UntrustedHashReceived(const CAICHHash& Hash, uint32 dwFromIP){
- switch(GetStatus()){
- case AICH_EMPTY:
- case AICH_UNTRUSTED:
- case AICH_TRUSTED:
- break;
- default:
- return;
- }
- bool bFound = false;
- bool bAdded = false;
- for (uint32 i = 0; i < m_aUntrustedHashs.size(); ++i){
- if (m_aUntrustedHashs[i].m_Hash == Hash){
- bAdded = m_aUntrustedHashs[i].AddSigningIP(dwFromIP);
- bFound = true;
- break;
- }
- }
- if (!bFound){
- bAdded = true;
- CAICHUntrustedHash uhToAdd;
- uhToAdd.m_Hash = Hash;
- uhToAdd.AddSigningIP(dwFromIP);
- m_aUntrustedHashs.push_back(uhToAdd);
- }
-
- uint32 nSigningIPsTotal = 0; // unique clients who send us a hash
- sint32 nMostTrustedPos = (-1); // the hash which most clients send us
- uint32 nMostTrustedIPs = 0;
- for (uint32 i = 0; i < (uint32)m_aUntrustedHashs.size(); ++i){
- nSigningIPsTotal += m_aUntrustedHashs[i].m_adwIpsSigning.size();
- if ((uint32)m_aUntrustedHashs[i].m_adwIpsSigning.size() > nMostTrustedIPs){
- nMostTrustedIPs = m_aUntrustedHashs[i].m_adwIpsSigning.size();
- nMostTrustedPos = i;
- }
- }
- if (nMostTrustedPos == (-1) || nSigningIPsTotal == 0){
- ASSERT( false );
- return;
- }
- // the check if we trust any hash
- if ( thePrefs::IsTrustingEveryHash() ||
- (nMostTrustedIPs >= MINUNIQUEIPS_TOTRUST && (100 * nMostTrustedIPs)/nSigningIPsTotal >= MINPERCENTAGE_TOTRUST)){
- //trusted
- AddDebugLogLineM(false, logSHAHashSet,
- CFormat(wxT("IACH Hash recieved (%sadded), We have now %u hash(es) from %u unique IP(s). ")
- wxT("We trust the Hash %s from %u client(s) (%u%%). File: %s"))
- % (bAdded ? wxT("") : wxT("not "))
- % m_aUntrustedHashs.size()
- % nSigningIPsTotal
- % m_aUntrustedHashs[nMostTrustedPos].m_Hash.GetString()
- % nMostTrustedIPs
- % ((100 * nMostTrustedIPs) / nSigningIPsTotal)
- % m_pOwner->GetFileName());
-
- SetStatus(AICH_TRUSTED);
- if (!HasValidMasterHash() || GetMasterHash() != m_aUntrustedHashs[nMostTrustedPos].m_Hash){
- SetMasterHash(m_aUntrustedHashs[nMostTrustedPos].m_Hash, AICH_TRUSTED);
- FreeHashSet();
- }
- } else {
- // untrusted
- AddDebugLogLineM(false, logSHAHashSet,
- CFormat(wxT("IACH Hash recieved (%sadded), We have now %u hash(es) from %u unique IP(s). ")
- wxT("Best Hash %s from %u clients (%u%%) - but we dont trust it yet. File: %s"))
- % (bAdded ? wxT(""): wxT("not "))
- % m_aUntrustedHashs.size()
- % nSigningIPsTotal
- % m_aUntrustedHashs[nMostTrustedPos].m_Hash.GetString()
- % nMostTrustedIPs
- % ((100 * nMostTrustedIPs) / nSigningIPsTotal)
- % m_pOwner->GetFileName());
-
- SetStatus(AICH_UNTRUSTED);
- if (!HasValidMasterHash() || GetMasterHash() != m_aUntrustedHashs[nMostTrustedPos].m_Hash){
- SetMasterHash(m_aUntrustedHashs[nMostTrustedPos].m_Hash, AICH_UNTRUSTED);
- FreeHashSet();
- }
- }
-}
-
-#ifndef CLIENT_GUI
-
-void CAICHHashSet::ClientAICHRequestFailed(CUpDownClient* pClient){
- pClient->SetReqFileAICHHash(NULL);
- CAICHRequestedData data = GetAICHReqDetails(pClient);
- RemoveClientAICHRequest(pClient);
- if (data.m_pClient != pClient)
- return;
- if( theApp.downloadqueue->IsPartFile(data.m_pPartFile)){
- AddDebugLogLineM( false, logSHAHashSet, wxT("IACH Request failed, Trying to ask another client (file ") + data.m_pPartFile->GetFileName() + wxString::Format(wxT(", Part: %u, Client"),data.m_nPart) + pClient->GetClientFullInfo());
- data.m_pPartFile->RequestAICHRecovery(data.m_nPart);
- }
-}
-
-#endif
-
-void CAICHHashSet::RemoveClientAICHRequest(const CUpDownClient* pClient) {
-
- for (CAICHRequestedDataList::iterator it = m_liRequestedData.begin();it != m_liRequestedData.end(); ++it) {
- if ((*(it)).m_pClient == pClient){
- m_liRequestedData.erase(it);
- return;
- }
- }
- ASSERT( false );
-}
-
-bool CAICHHashSet::IsClientRequestPending(const CPartFile* pForFile, uint16 nPart){
- for (CAICHRequestedDataList::iterator it = m_liRequestedData.begin();it != m_liRequestedData.end(); ++it) {
- if ((*(it)).m_pPartFile == pForFile && (*(it)).m_nPart == nPart){
- return true;
- }
- }
- return false;
-}
-
-CAICHRequestedData CAICHHashSet::GetAICHReqDetails(const CUpDownClient* pClient){
- for (CAICHRequestedDataList::iterator it = m_liRequestedData.begin();it != m_liRequestedData.end(); ++it) {
- if ((*(it)).m_pClient == pClient){
- return *(it);
- }
- }
- ASSERT( false );
- CAICHRequestedData empty;
- return empty;
-}
-
-bool CAICHHashSet::IsPartDataAvailable(uint32 nPartStartPos){
- if (!(m_eStatus == AICH_VERIFIED || m_eStatus == AICH_TRUSTED || m_eStatus == AICH_HASHSETCOMPLETE) ){
- ASSERT( false );
- return false;
- }
- uint32 nPartSize = min(PARTSIZE, m_pOwner->GetFileSize()-nPartStartPos);
- for (uint32 nPartPos = 0; nPartPos < nPartSize; nPartPos += EMBLOCKSIZE){
- CAICHHashTree* phtToCheck = m_pHashTree.FindHash(nPartStartPos+nPartPos, min(EMBLOCKSIZE, nPartSize-nPartPos));
- if (phtToCheck == NULL || !phtToCheck->m_bHashValid){
- return false;
- }
- }
- return true;
-}
-
-// VC++ defines Assert as ASSERT. VC++ also defines VERIFY MACRO, which is the equivalent of ASSERT but also works in Released builds.
-
-#define VERIFY(x) ASSERT(x)
-
-void CAICHHashSet::DbgTest(){
-
- //define TESTSIZE 4294567295
- uint8 maxLevel = 0;
- uint32 cHash = 1;
- uint8 curLevel = 0;
- maxLevel = 0;
-
-#define TESTSIZE m_pHashTree.m_nDataSize
- if (m_pHashTree.m_nDataSize <= EMBLOCKSIZE)
- return;
- CAICHHashSet TestHashSet(m_pOwner);
- TestHashSet.SetFileSize(m_pOwner->GetFileSize());
- TestHashSet.SetMasterHash(GetMasterHash(), AICH_VERIFIED);
- CMemFile file;
- uint64 i = 0;
- for (i = 0; i+9728000 < TESTSIZE; i += 9728000){
- VERIFY( CreatePartRecoveryData(i, &file) );
-
- file.Seek(0,wxFromStart);
- VERIFY( TestHashSet.ReadRecoveryData(i, &file) );
- file.Seek(0,wxFromStart);
- TestHashSet.FreeHashSet();
- uint32 j = 0;
- for (j = 0; j+EMBLOCKSIZE < 9728000; j += EMBLOCKSIZE){
- VERIFY( m_pHashTree.FindHash(i+j, EMBLOCKSIZE, &curLevel) );
- //TRACE(wxT("%u - %s\r\n"), cHash, m_pHashTree.FindHash(i+j, EMBLOCKSIZE, &curLevel)->m_Hash.GetString());
- maxLevel = max(curLevel, maxLevel);
- curLevel = 0;
- cHash++;
- }
- VERIFY( m_pHashTree.FindHash(i+j, 9728000-j, &curLevel) );
- //TRACE(wxT("%u - %s\r\n"), cHash, m_pHashTree.FindHash(i+j, 9728000-j, &curLevel)->m_Hash.GetString());
- maxLevel = max(curLevel, maxLevel);
- curLevel = 0;
- cHash++;
-
- }
- VERIFY( CreatePartRecoveryData(i, &file) );
- file.Seek(0,wxFromStart);
- VERIFY( TestHashSet.ReadRecoveryData(i, &file) );
- file.Seek(0,wxFromStart);
- TestHashSet.FreeHashSet();
- uint64 j = 0;
- for (j = 0; j+EMBLOCKSIZE < TESTSIZE-i; j += EMBLOCKSIZE){
- VERIFY( m_pHashTree.FindHash(i+j, EMBLOCKSIZE, &curLevel) );
- //TRACE(wxT("%u - %s\r\n"), cHash,m_pHashTree.FindHash(i+j, EMBLOCKSIZE, &curLevel)->m_Hash.GetString());
- maxLevel = max(curLevel, maxLevel);
- curLevel = 0;
- cHash++;
- }
- //VERIFY( m_pHashTree.FindHash(i+j, (TESTSIZE-i)-j, &curLevel) );
-// TRACE(wxT("%u - %s\r\n"), cHash,m_pHashTree.FindHash(i+j, (TESTSIZE-i)-j, &curLevel)->m_Hash.GetString());
- maxLevel = max(curLevel, maxLevel);
-
-}*/
diff --git a/hasher/SHAHashSet.h b/hasher/SHAHashSet.h
deleted file mode 100644
index 76fe51149..000000000
--- a/hasher/SHAHashSet.h
+++ /dev/null
@@ -1,257 +0,0 @@
-//
-// This file is part of the aMule Project.
-//
-// Copyright (c) 2003-2006 Angel Vidal (Kry) ( kry@amule.org )
-// Copyright (c) 2003-2006 aMule Team ( admin@amule.org / http://www.amule.org )
-// Copyright (c) 2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
-//
-// Any parts of this program derived from the xMule, lMule or eMule project,
-// or contributed by third-party developers are copyrighted by their
-// respective authors.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
-//
-
-/*
- SHA haset basically exists of 1 Tree for all Parts (9.28MB) + n Trees
- for all blocks (180KB) while n is the number of Parts.
- This means it is NOT a complete hashtree, since the 9.28MB is a given level, in order
- to be able to create a hashset format similar to the MD4 one.
-
- If the number of elements for the next level are odd (for example 21 blocks to spread into 2 hashs)
- the majority of elements will go into the left branch if the parent node was a left branch
- and into the right branch if the parent node was a right branch. The first node is always
- taken as a left branch.
-
-Example tree:
- FileSize: 19506000 Bytes = 18,6 MB
-
- X (18,6) MasterHash
- / \
- X (18,55) \
- / \ \
- X(9,28) x(9,28) X (0,05MB) PartHashs
- / \ / \ \
- X(4,75) X(4,57) X(4,57) X(4,75) \
-
- [...............]
-X(180KB) X(180KB) [...] X(140KB) | X(180KB) X(180KB [...] BlockHashs
- v
- Border between first and second Part (9.28MB)
-
-HashsIdentifier:
-When sending hashs, they are send with a 16bit identifier which specifies its postion in the
-tree (so StartPosition + HashDataSize would lead to the same hash)
-The identifier basically describes the way from the top of the tree to the hash. a set bit (1)
-means follow the left branch, a 0 means follow the right. The highest bit which is set is seen as the start-
-postion (since the first node is always seend as left).
-
-Example
-
- x 0000000000000001
- / \
- x \ 0000000000000011
- / \ \
- x _X_ x 0000000000000110
-
-
-*/
-
-#ifndef __SHAHAHSET_H__
-#define __SHAHAHSET_H__
-
-/*#include
-#include
-#include */
-
-#include "Types.h"
-#define PARTSIZE 9728000
-#define EMBLOCKSIZE 184320
-//typedef unsigned char uint8;
-//typedef unsigned char uchar;
-
-#include "stdinc.h"
-
-
-//typedef unsigned int uint32;
-//typedef unsigned __int64 uint64;
-#define HASHSIZE 20
-//#define KNOWN2_MET_FILENAME wxT("known2.met")
-
-enum EAICHStatus {
- AICH_ERROR = 0,
- AICH_EMPTY,
- AICH_UNTRUSTED,
- AICH_TRUSTED,
- AICH_VERIFIED,
- AICH_HASHSETCOMPLETE
-};
-
-/*class CFileDataIO;
-class CKnownFile;
-class CMemFile;
-class CPartFile;
-class CUpDownClient;*/
-
-//using namespace std;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-///CAICHHash
-typedef unsigned char byte;
-
-class CAICHHash
-{
-public:
- ~CAICHHash() {;}
- CAICHHash() { memset(m_abyBuffer, 0, HASHSIZE); }
- //CAICHHash(CFileDataIO* file) { Read(file); }
- CAICHHash(byte* data) { Read(data); }
- CAICHHash(const CAICHHash& k1) { *this = k1; }
- CAICHHash& operator=(const CAICHHash& k1) { memcpy(m_abyBuffer, k1.m_abyBuffer, HASHSIZE); return *this; }
- friend bool operator==(const CAICHHash& k1,const CAICHHash& k2) { return memcmp(k1.m_abyBuffer, k2.m_abyBuffer, HASHSIZE) == 0;}
- friend bool operator!=(const CAICHHash& k1,const CAICHHash& k2) { return !(k1 == k2); }
- //void Read(CFileDataIO* file);
- //void Write(CFileDataIO* file) const;
- void Read(byte* data) { memcpy(m_abyBuffer, data, HASHSIZE); }
-// wxString GetString() const;
- byte* GetRawHash() { return m_abyBuffer; }
-
- static unsigned int GetHashSize() { return HASHSIZE;}
-
- //unsigned int DecodeBase32(const wxString &base32);
-
-private:
- byte m_abyBuffer[HASHSIZE];
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-///CAICHHashAlgo
-class CAICHHashAlgo
-{
-public:
- virtual ~CAICHHashAlgo() {};
- virtual void Reset() = 0;
- virtual void Add(const void* pData, uint32 nLength) = 0;
- virtual void Finish(CAICHHash& Hash) = 0;
- virtual void GetHash(CAICHHash& Hash) = 0;
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-///CAICHHashTree
-class CAICHHashTree
-{
- // Madness from eMule, and gcc don't like being friend with itself...
- // That probably means gcc is not friend of gcc. So gcc hates itself.
- // friend class CAICHHashTree;
- friend class CAICHHashSet;
-public:
- CAICHHashTree(uint64 nDataSize, bool bLeftBranch, uint64 nBaseSize);
- ~CAICHHashTree();
- void SetBlockHash(uint64 nSize, uint64 nStartPos, CAICHHashAlgo* pHashAlg);
- bool ReCalculateHash(CAICHHashAlgo* hashalg, bool bDontReplace );
- bool VerifyHashTree(CAICHHashAlgo* hashalg, bool bDeleteBadTrees);
- CAICHHashTree* FindHash(uint64 nStartPos, uint64 nSize) {uint8 buffer = 0; return FindHash(nStartPos, nSize, &buffer);}
-
-protected:
- CAICHHashTree* FindHash(uint64 nStartPos, uint64 nSize, uint8* nLevel);
-// bool CreatePartRecoveryData(uint32 nStartPos, uint32 nSize, CFileDataIO* fileDataOut, uint16 wHashIdent);
-// void WriteHash(CFileDataIO* fileDataOut, uint16 wHashIdent) const;
-// bool WriteLowestLevelHashs(CFileDataIO* fileDataOut, uint16 wHashIdent, bool bNoIdent = false) const;
-// bool LoadLowestLevelHashs(CFileDataIO* fileInput);
-// bool SetHash(CFileDataIO* fileInput, uint16 wHashIdent, sint8 nLevel = (-1), bool bAllowOverwrite = true);
- CAICHHashTree* m_pLeftTree;
- CAICHHashTree* m_pRightTree;
-
-public:
- CAICHHash m_Hash;
- uint64 m_nDataSize; // size of data which is covered by this hash
- uint64 m_nBaseSize; // blocksize on which the lowest hash is based on
- bool m_bIsLeftBranch; // left or right branch of the tree
- bool m_bHashValid; // the hash is valid and not empty
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-///CAICHUntrustedHashs
-/*class CAICHUntrustedHash {
-public:
- CAICHUntrustedHash& operator=(const CAICHUntrustedHash& k1) { m_adwIpsSigning = k1.m_adwIpsSigning; m_Hash = k1.m_Hash ; return *this; }
- bool AddSigningIP(uint32 dwIP);
-
- CAICHHash m_Hash;
- set m_adwIpsSigning;
-};*/
-
-/////////////////////////////////////////////////////////////////////////////////////////
-///CAICHUntrustedHashs
-/*class CAICHRequestedData {
-public:
- CAICHRequestedData() {m_nPart = 0; m_pPartFile = NULL; m_pClient= NULL;}
- CAICHRequestedData& operator=(const CAICHRequestedData& k1) { m_nPart = k1.m_nPart; m_pPartFile = k1.m_pPartFile; m_pClient = k1.m_pClient; return *this; }
- uint16 m_nPart;
- CPartFile* m_pPartFile;
- CUpDownClient* m_pClient;
-};
-
-
-using namespace std;
-
-typedef std::list CAICHRequestedDataList;
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-///CAICHHashSet
-class CAICHHashSet
-{
-public:
- CAICHHashSet();//CKnownFile* pOwner);
- ~CAICHHashSet(void);
-// bool CreatePartRecoveryData(uint32 nPartStartPos, CFileDataIO* fileDataOut, bool bDbgDontLoad = false);
-// bool ReadRecoveryData(uint32 nPartStartPos, CMemFile* fileDataIn);
- bool ReCalculateHash(bool bDontReplace = false);
- bool VerifyHashTree(bool bDeleteBadTrees);
-// void UntrustedHashReceived(const CAICHHash& Hash, uint32 dwFromIP);
-// bool IsPartDataAvailable(uint32 nPartStartPos);
- void SetStatus(EAICHStatus bNewValue) {m_eStatus = bNewValue;}
- EAICHStatus GetStatus() const {return m_eStatus;}
-//
- void FreeHashSet();
- void SetFileSize(uint64 nSize);
-//
- CAICHHash& GetMasterHash() {return m_pHashTree.m_Hash;}
-// void SetMasterHash(const CAICHHash& Hash, EAICHStatus eNewStatus);
- bool HasValidMasterHash() {return m_pHashTree.m_bHashValid;}
-
-// bool SaveHashSet();
-// bool LoadHashSet(); // only call directly when debugging
-
- CAICHHashAlgo* GetNewHashAlgo();
-// static void ClientAICHRequestFailed(CUpDownClient* pClient);
-// static void RemoveClientAICHRequest(const CUpDownClient* pClient);
-// static bool IsClientRequestPending(const CPartFile* pForFile, uint16 nPart);
-// static CAICHRequestedData GetAICHReqDetails(const CUpDownClient* pClient);
-// void DbgTest();
-
-// void SetOwner(CKnownFile* owner) { m_pOwner = owner;}
-
- CAICHHashTree m_pHashTree;
-
- //static CAICHRequestedDataList m_liRequestedData;
-
-private:
- //CKnownFile* m_pOwner;
- EAICHStatus m_eStatus;
- //deque m_aUntrustedHashs;
-};
-
-#endif //__SHAHAHSET_H__
diff --git a/hasher/SHA_asm.asm b/hasher/SHA_asm.asm
new file mode 100644
index 000000000..fc02c1375
--- /dev/null
+++ b/hasher/SHA_asm.asm
@@ -0,0 +1,298 @@
+; #####################################################################################################################
+;
+; SHA_asm.asm
+;
+; Copyright (c) Shareaza Development Team, 2002-2007.
+; This file is part of SHAREAZA (shareaza.sourceforge.net)
+;
+; Shareaza is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; as published by the Free Software Foundation; either version 2 of
+; the License, or (at your option) any later version.
+;
+; Shareaza is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with Shareaza; if not, write to the Free Software
+; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+;
+; #####################################################################################################################
+;
+; SHA_asm - Implementation of SHA-1 for x86 - use together with SHA.cpp and SHA.h
+;
+; #####################################################################################################################
+
+ .586p
+ .model flat, stdcall
+ option casemap:none ; case sensitive
+ option prologue:none ; we generate our own entry/exit code
+ option epilogue:none
+
+; #####################################################################################################################
+
+m_nCount0 equ 0 ; offsets as found in SHA.h
+m_nCount1 equ 4
+
+m_nHash0 equ 8
+m_nHash1 equ 12
+m_nHash2 equ 16
+m_nHash3 equ 20
+m_nHash4 equ 24
+
+m_nBuffer equ 28
+
+RND_CH MACRO const:REQ
+; t=a; a=rotl32(a,5)+e+k+w[i]+((b&c)^(~b&d)); e=d; d=c; c=rotl32(b,30); b=t
+; a=rotl32(a,5)+e+k+w[i]+(d^(b&(c^d)));
+ mov reg_temp1, reg_a ; t=a
+ mov reg_temp2, reg_c
+ rol reg_a, 5
+ xor reg_temp2, reg_d
+ add reg_a, reg_e
+ and reg_temp2, reg_b
+ add reg_a, const
+ xor reg_temp2, reg_d
+ add reg_a, [_w+count*4]
+ ror reg_b, 2
+ add reg_a, reg_temp2
+reg_t textequ reg_e
+reg_e textequ reg_d
+reg_d textequ reg_c
+reg_c textequ reg_b
+reg_b textequ reg_temp1
+reg_temp1 textequ reg_t
+count = count + 1
+ ENDM ; RND_CH
+
+RND_PARITY MACRO const:REQ
+; t=a; a=rotl32(a,5)+e+k+w[i]+(b^c^d); e=d; d=c; c=rotl32(b,30); b=t
+ mov reg_temp1, reg_a ; t=a
+ rol reg_a, 5
+ mov reg_temp2, reg_d
+ add reg_a, reg_e
+ xor reg_temp2, reg_c
+ add reg_a, const
+ xor reg_temp2, reg_b
+ add reg_a, [_w+count*4]
+ ror reg_b, 2
+ add reg_a, reg_temp2
+reg_t textequ reg_e
+reg_e textequ reg_d ; e=d
+reg_d textequ reg_c ; d=c
+reg_c textequ reg_b ; c=rotl(b,30)
+reg_b textequ reg_temp1 ; b=t
+reg_temp1 textequ reg_t
+count = count + 1
+ ENDM ; RND_PARITY
+
+RND_MAJ MACRO const:REQ
+; t=a; a=rotl32(a,5)+e+k+w[i]+((b&c)^(b&d)^(c&d)); e=d; d=c; c=rotl32(b,30); b=t
+; a=rotl32(a,5)+e+k+w[i]+((c&d)^(b&(c^d)))
+ mov reg_temp2, reg_d
+ mov reg_temp1, reg_a
+ rol reg_a, 5
+ xor reg_temp2, reg_c
+ add reg_a, reg_e
+ and reg_temp2, reg_b
+ add reg_a, const
+ mov reg_e, reg_c
+ add reg_a, [_w+count*4]
+ and reg_e, reg_d
+ xor reg_temp2, reg_e
+ ror reg_b, 2
+ add reg_a, reg_temp2
+reg_t textequ reg_e
+reg_e textequ reg_d
+reg_d textequ reg_c
+reg_c textequ reg_b
+reg_b textequ reg_temp1
+reg_temp1 textequ reg_t
+count = count + 1
+ ENDM ; RND_MAJ
+
+INIT_REG_ALIAS MACRO
+reg_accu textequ
+reg_base textequ
+reg_i_1 textequ
+reg_i_2 textequ
+reg_i_3 textequ
+reg_i_15 textequ
+reg_i_16 textequ
+ ENDM
+
+ .code
+
+ ALIGN 16
+
+SHA_Compile_p5 PROC
+
+__this textequ <[esp+40+320]> ; pusha + 2 * ret addr in between
+_w textequ
+
+ INIT_REG_ALIAS
+
+count = 0
+ REPEAT 16
+ IF count eq 0
+ mov reg_i_16, [ebp+count*4]
+ bswap reg_i_16
+ mov [_w+count*4], reg_i_16
+ ELSEIF count eq 1
+ mov reg_i_15, [ebp+count*4]
+ bswap reg_i_15
+ mov [_w+count*4], reg_i_15
+ ELSEIF count eq 13
+ mov reg_i_3, [ebp+count*4]
+ bswap reg_i_3
+ mov [_w+count*4], reg_i_3
+ ELSEIF count eq 14
+ mov reg_i_2, [ebp+count*4]
+ bswap reg_i_2
+ mov [_w+count*4], reg_i_2
+ ELSE
+ mov reg_i_1, [ebp+count*4]
+ bswap reg_i_1
+ mov [_w+count*4], reg_i_1
+ ENDIF
+count = count + 1
+ ENDM
+count = 16
+ REPEAT 64
+ xor reg_i_3, reg_i_16 ; w[i-16]^w[i-3]
+reg_i_14 textequ reg_i_16 ; we forget w[i-16]
+ IF count le 77
+ mov reg_i_14, [_w+(count-14)*4]
+ xor reg_i_3, reg_i_14
+ ELSE
+ xor reg_i_3, [_w+(count-14)*4]
+ ENDIF
+ xor reg_i_3, [_w+(count-8)*4]
+ rol reg_i_3, 1
+ mov [_w+count*4], reg_i_3
+;now we prepare for the next iteration
+reg_i_0 textequ reg_i_3
+reg_i_3 textequ reg_i_2
+reg_i_2 textequ reg_i_1
+reg_i_1 textequ reg_i_0
+reg_i_16 textequ reg_i_15
+reg_i_15 textequ reg_i_14
+count = count + 1
+ ENDM
+
+reg_a textequ
+reg_b textequ
+reg_c textequ
+reg_d textequ
+reg_e textequ
+reg_temp1 textequ
+reg_temp2 textequ
+
+ mov reg_temp2, __this
+ mov reg_a, [reg_temp2+m_nHash0]
+ mov reg_b, [reg_temp2+m_nHash1]
+ mov reg_c, [reg_temp2+m_nHash2]
+ mov reg_d, [reg_temp2+m_nHash3]
+ mov reg_e, [reg_temp2+m_nHash4]
+
+count = 0
+
+ REPEAT 20
+ RND_CH 05a827999H
+ ENDM
+ REPEAT 20
+ RND_PARITY 06ed9eba1H
+ ENDM
+ REPEAT 20
+ RND_MAJ 08f1bbcdcH
+ ENDM
+ REPEAT 20
+ RND_PARITY 0ca62c1d6H
+ ENDM
+
+ mov reg_temp2, __this
+ add [reg_temp2+m_nHash0], reg_a
+ add [reg_temp2+m_nHash1], reg_b
+ add [reg_temp2+m_nHash2], reg_c
+ add [reg_temp2+m_nHash3], reg_d
+ add [reg_temp2+m_nHash4], reg_e
+
+ ret
+
+SHA_Compile_p5 ENDP
+
+ ALIGN 16
+
+SHA1_Add_p5 PROC PUBLIC, _this:DWORD, _Data:DWORD, _nLength:DWORD
+
+ pusha
+__this textequ <[esp+36+320]> ; different offset due to pusha
+__Data textequ <[esp+40+320]>
+__nLength textequ <[esp+44+320]>
+
+ sub esp, 320
+
+ mov ecx, __nLength
+ and ecx, ecx
+ jz get_out
+ xor edx, edx
+ mov ebp, __Data
+ mov edi, __this
+ mov ebx, [edi+m_nCount0]
+ mov eax, ebx
+ add ebx, ecx
+ mov [edi+m_nCount0], ebx
+ adc [edi+m_nCount1], edx
+
+ and eax, 63
+ jnz partial_buffer
+full_blocks: mov ecx, __nLength
+ and ecx, ecx
+ jz get_out
+ sub ecx, 64
+ jb end_of_stream
+ mov __nLength, ecx
+ call SHA_Compile_p5
+ mov ebp, __Data
+ add ebp, 64
+ mov __Data, ebp
+ jmp full_blocks
+
+end_of_stream: mov edi, __this
+ mov esi, ebp
+ lea edi, [edi+m_nBuffer]
+ add ecx, 64
+ rep movsb
+ jmp get_out
+
+partial_buffer: add ecx, eax ; eax = offset in buffer, ecx = _nLength
+ cmp ecx, 64
+ jb short_stream ; we can't fill the buffer
+ mov ecx, -64
+ add ecx, eax
+ add __nLength, ecx ; _nlength += (offset-64)
+@@: mov bl, [ebp]
+ inc ebp
+ mov byte ptr [edi+m_nBuffer+64+ecx], bl
+ inc ecx
+ jnz @B ; offset = 64
+ mov __Data, ebp
+ lea ebp, [edi+m_nBuffer]
+ call SHA_Compile_p5
+ mov ebp, __Data
+ jmp full_blocks
+
+short_stream: sub ecx, eax ; --> ecx=_nLength
+ mov esi, ebp
+ lea edi, [edi+m_nBuffer+eax]
+ rep movsb
+
+get_out: add esp, 320
+ popa
+ ret 12
+
+SHA1_Add_p5 ENDP
+
+ end
diff --git a/hasher/StdAfx.h b/hasher/StdAfx.h
index af43e51f2..5a55c6cd2 100644
--- a/hasher/StdAfx.h
+++ b/hasher/StdAfx.h
@@ -1,27 +1,38 @@
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently, but
-// are changed infrequently
+//
+// stdafx.h
+//
+// Copyright (c) Shareaza Development Team, 2002-2014.
+// This file is part of SHAREAZA (shareaza.sourceforge.net)
+//
+// Shareaza is free software; you can redistribute it
+// and/or modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Shareaza is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Shareaza; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-#if !defined(AFX_STDAFX_H__FE1C0E5C_BC20_4818_BC9B_601686BB10FA__INCLUDED_)
-#define AFX_STDAFX_H__FE1C0E5C_BC20_4818_BC9B_601686BB10FA__INCLUDED_
-
-#if _MSC_VER > 1000
#pragma once
-#endif // _MSC_VER > 1000
+// For /Wall
+#pragma warning(disable:4668)
+#pragma warning(disable:4820)
+#pragma warning(disable:4548)
-// Insert your headers here
-#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+#define _WIN32_WINNT 0x0600
-#define UNICODE
-#define _UNICODE
+#define STRICT
+#define WIN32_LEAN_AND_MEAN
+#define BOOST_USE_WINDOWS_H
#include
+#include
-// TODO: reference additional headers your program requires here
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_STDAFX_H__FE1C0E5C_BC20_4818_BC9B_601686BB10FA__INCLUDED_)
+// define HASHLIB_USE_ASM for assembler use (several times faster)
\ No newline at end of file
diff --git a/hasher/Types.h b/hasher/Types.h
deleted file mode 100644
index c6a90c469..000000000
--- a/hasher/Types.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-typedef unsigned char uchar;
-typedef unsigned char uint8;
-typedef signed char sint8;
-
-typedef unsigned short uint16;
-typedef signed short sint16;
-
-typedef unsigned int uint32;
-typedef signed int sint32;
-
-typedef unsigned __int64 uint64;
-typedef signed __int64 sint64;
-
-//#ifdef _DEBUG
-//#include "Debug_FileSize.h"
-//typedef CEMFileSize EMFileSize;
-//#else
-typedef unsigned __int64 EMFileSize;
-//#endif
\ No newline at end of file
diff --git a/hasher/Utility.hpp b/hasher/Utility.hpp
new file mode 100644
index 000000000..65e0ba1cb
--- /dev/null
+++ b/hasher/Utility.hpp
@@ -0,0 +1,338 @@
+//
+// Utility.hpp
+//
+// Copyright (c) Shareaza Development Team, 2002-2008.
+// This file is part of SHAREAZA (shareaza.sourceforge.net)
+//
+// Shareaza is free software; you can redistribute it
+// and/or modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Shareaza is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Shareaza; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#pragma once
+
+#include
+
+// Work-around for Microsoft double declaration
+#define _interlockedbittestandset _ms_set
+#define _interlockedbittestandreset _ms_reset
+#define _interlockedbittestandset64 _ms_set64
+#define _interlockedbittestandreset64 _ms_reset64
+#include
+#undef _interlockedbittestandset
+#undef _interlockedbittestandreset
+#undef _interlockedbittestandset
+#undef _interlockedbittestandreset
+
+//! \brief platform independent signed 8 bit integer type.
+typedef char int8;
+//! \brief platform independent signed 16 bit integer type.
+typedef short int16;
+//! \brief platform independent signed 32 bit integer type.
+typedef long int32;
+//! \brief platform independent signed 64 bit integer type.
+typedef __int64 int64;
+
+//! \brief platform independent unsigned 8 bit integer type.
+typedef unsigned char uint8;
+//! \brief platform independent unsigned 16 bit integer type.
+typedef unsigned short uint16;
+//! \brief platform independent unsigned 32 bit integer type.
+typedef unsigned long uint32;
+//! \brief platform independent unsigned 64 bit integer type.
+typedef unsigned __int64 uint64;
+
+//! \brief alias for unsigned char.
+typedef unsigned char uchar;
+//! \brief alias for signed char.
+typedef signed char schar;
+//! \brief alias for wchar_t.
+typedef wchar_t wchar;
+//! \brief unsigned integer type of the same size as a wchar_t
+typedef uint16 uwchar;
+
+//! \brief enumeration to specify the byte ordering of a sequence.
+enum Endianess
+{
+ //! \brief specifies little endian order,
+ //! the least significant byte comes first.
+ littleEndian,
+ //! \brief specifies big endian order,
+ //! the most significant byte comes first.
+ bigEndian
+};
+
+//! \brief This namespace is used to hold machine dependent definitions for
+//! the target machine.
+namespace Machine
+{
+ //! \brief Specifies the natural byte ordering of the target machine.
+ //! \todo detect endianess during compilation.
+ const Endianess endianess = littleEndian; // x86
+
+ inline bool SupportsMMX()
+ {
+ int CPUInfo[4] = {};
+ __cpuid(CPUInfo, 1);
+ return (CPUInfo[3] & 0x00800000) != 0;
+ }
+
+ inline bool SupportsSSE()
+ {
+ int CPUInfo[4] = {};
+ __cpuid(CPUInfo, 1);
+ return (CPUInfo[3] & 0x02000000) != 0;
+ }
+
+ inline bool SupportsSSE2()
+ {
+ int CPUInfo[4] = {};
+ __cpuid(CPUInfo, 1);
+ return (CPUInfo[3] & 0x04000000) != 0;
+ }
+
+ inline bool SupportsSSE3()
+ {
+ int CPUInfo[4] = {};
+ __cpuid(CPUInfo, 1);
+ return (CPUInfo[2] & 0x00000001) != 0;
+ }
+
+ inline bool SupportsSSSE3()
+ {
+ int CPUInfo[4] = {};
+ __cpuid(CPUInfo, 1);
+ return (CPUInfo[2] & 0x00000200) != 0;
+ }
+
+ inline bool SupportsSSE41()
+ {
+ int CPUInfo[4] = {};
+ __cpuid(CPUInfo, 1);
+ return (CPUInfo[2] & 0x00080000) != 0;
+ }
+
+ inline bool SupportsSSE42()
+ {
+ int CPUInfo[4] = {};
+ __cpuid(CPUInfo, 1);
+ return (CPUInfo[2] & 0x00100000) != 0;
+ }
+
+ inline bool SupportsSSE4A()
+ {
+ int CPUInfo[4] = {};
+ __cpuid(CPUInfo, 0x80000000);
+ if (CPUInfo[0] >= 0x80000001)
+ {
+ __cpuid(CPUInfo, 0x80000001);
+ return (CPUInfo[2] & 0x00000040) != 0;
+ }
+ return false;
+ }
+
+ inline bool SupportsSSE5()
+ {
+ int CPUInfo[4] = {};
+ __cpuid(CPUInfo, 0x80000000);
+ if (CPUInfo[0] >= 0x80000001)
+ {
+ __cpuid(CPUInfo, 0x80000001);
+ return (CPUInfo[2] & 0x00000800) != 0;
+ }
+ return false;
+ }
+
+ inline bool Supports3DNOW()
+ {
+ int CPUInfo[4] = {};
+ __cpuid(CPUInfo, 0x80000000);
+ if (CPUInfo[0] >= 0x80000001)
+ {
+ __cpuid(CPUInfo, 0x80000001);
+ return (CPUInfo[3] & 0x80000000) != 0;
+ }
+ return false;
+ }
+
+ inline bool Supports3DNOWEXT()
+ {
+ int CPUInfo[4] = {};
+ __cpuid(CPUInfo, 0x80000000);
+ if (CPUInfo[0] >= 0x80000001)
+ {
+ __cpuid(CPUInfo, 0x80000001);
+ return (CPUInfo[3] & 0x40000000) != 0;
+ }
+ return false;
+ }
+}
+
+//! \brief generic function to swap the byte ordering of a given type
+//!
+//! The byte ordering can be swapped meaningfully only for unsigned integer types
+//! therefore specializations are provided only for those types. We use
+//! template specialization in order to avoid automatic argument conversion.
+template
+struct SwapEndianess {};
+
+template<> struct SwapEndianess< uint8 >
+{
+ uint8 operator()(uint8 value) const { return value; }
+};
+ template<> struct SwapEndianess< uint16 >
+ {
+ uint16 operator()(uint16 value) const
+ {
+ return _byteswap_ushort(value);
+ }
+ };
+
+ template<> struct SwapEndianess< uint32 >
+ {
+ uint32 operator()(uint32 value) const
+ {
+ return _byteswap_ulong(value);
+ }
+ };
+
+ template<> struct SwapEndianess< uint64 >
+ {
+ uint64 operator()(uint64 value) const
+ {
+ return _byteswap_uint64(value);
+ }
+ };
+
+ template
+ inline T swapEndianess(T value)
+ {
+ return SwapEndianess< T >()(value);
+ }
+
+ //! \brief Generic function object to give its char serialization a given
+ //! specified byte ordering.
+ //!
+ //! The byte ordering of the argument is swapped unless it matches the byte
+ //! ordering of the target machine.
+ //! We use partial specialization to achieve this.
+ template struct TransformTo
+ {
+ T operator()(T value) const { return swapEndianess< T >(value); }
+ };
+ template struct TransformTo< T, Machine::endianess >
+ {
+ T operator()(T value) const { return value; }
+ };
+
+ //! \brief Generic function object to reconstruct a value out of its serialized
+ //! form with a specified byte ordering.
+ //!
+ //! This function objects behaves the same as TransformTo does but its purpose
+ //! is different. Having both functions allows to make that purpose explicit in
+ //! code.
+ template struct TransformFrom
+ {
+ T operator()(T value) const { return TransformTo< T, endianPolicy >()(value); }
+ };
+
+ //! \brief Generic function to bring a given value into little endian order.
+ template inline T transformToLE(T value)
+ {
+ return TransformTo< T, littleEndian >()(value);
+ }
+
+ //! \brief Generic function to bring a given value into big endian order.
+ template inline T transformToBE(T value)
+ {
+ return TransformTo< T, bigEndian >()(value);
+ }
+
+ //! \brief Generic function to reconstruct a given value from little endian
+ //! order.
+ template inline T transformFromLE(T value)
+ {
+ return TransformFrom< T, littleEndian >()(value);
+ }
+
+ //! \brief Generic function to reconstruct a given value from big endian
+ //! order.
+ template inline T transformFromBE(T value)
+ {
+ return TransformFrom< T, bigEndian >()(value);
+ }
+
+ template struct StaticSwapEndianess;
+ template struct StaticSwapEndianess< uint8, v >
+ {
+ static const uint8 value = v;
+ };
+ template struct StaticSwapEndianess< uint16, v >
+ {
+ static const uint16 value = (v << 8) | (v >> 8);
+ };
+ template struct StaticSwapEndianess< uint32, v >
+ {
+ static const uint32 value = (v << 24) | ((v & 0xff00) << 8)
+ | ((v & 0xff0000) >> 8) | (v >> 24);
+ };
+ template struct StaticSwapEndianess< uint64, v >
+ {
+ static const uint64 value
+ = StaticSwapEndianess< uint32, (v >> 32) >::value
+ | (uint64(StaticSwapEndianess< uint32, v >::value) << 32);
+ };
+
+ template struct StaticTransformTo
+ {
+ static const T value = StaticSwapEndianess< T, v >::value;
+ };
+ template struct StaticTransformTo< T, v, Machine::endianess >
+ {
+ static const T value = v;
+ };
+
+ //! \brief for_each with predicate.
+ //!
+ //! A generalization of the for_each algorithm that takes a predicate that
+ //! must be fulfilled in order to apply the given function. This function
+ //! may mutate the input sequence, provided no iterators become invalid.
+ template
+ inline void for_each_if(InputIterator first, InputIterator last,
+ Predicate pred, Function f)
+ {
+ for (; first != last; ++first)
+ {
+ if (pred(*first))
+ f(*first)
+ }
+ }
+
+ //! Helper function to rotate the bits of a given unsigned value.
+ template inline T rotateLeft(T value, uint8 shift);
+ template<> inline uint8 rotateLeft(uint8 value, uint8 shift)
+ {
+ return uint8(value << shift | value >> (8 - shift));
+ }
+ template<> inline uint16 rotateLeft(uint16 value, uint8 shift)
+ {
+ return uint16(value << shift | value >> (16 - shift));
+ }
+ template<> inline uint32 rotateLeft(uint32 value, uint8 shift)
+ {
+ return uint32(value << shift | value >> (32 - shift));
+ }
+ template<> inline uint64 rotateLeft(uint64 value, uint8 shift)
+ {
+ return uint64(value << shift | value >> (64 - shift));
+ }
\ No newline at end of file
diff --git a/hasher/config.h b/hasher/config.h
deleted file mode 100644
index 9d46a7f03..000000000
--- a/hasher/config.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2001-2005 Jacek Sieka, arnetheduck on gmail point com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#if !defined(CONFIG_H)
-#define CONFIG_H
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#ifdef HAVE_CONFIG_H
-#include "autoconf.h"
-#endif
-
-// Changing this number will change the maximum number of simultaneous users
-// we can handle (when using select)...
-#define FD_SETSIZE 4096
-
-// Remove this line if hashes are not available in your stl
-#define HAVE_HASH 1
-
-// This enables stlport's debug mode (and slows it down to a crawl...)
-//# define _STLP_DEBUG 1
-
-// --- Shouldn't have to change anything under here...
-
-#ifndef _REENTRANT
-# define _REENTRANT 1
-#endif
-
-#ifdef HAVE_STLPORT
-# define _STLP_DONT_USE_SHORT_STRING_OPTIM 1 // Lots of memory issues with this undefined...wonder what's up with that..
-# define _STLP_USE_PTR_SPECIALIZATIONS 1
-# define _STLP_USE_TEMPLATE_EXPRESSION 1
-# define _STLP_NO_ANACHRONISMS 1
-# define _STLP_NO_CUSTOM_IO 1
-# define _STLP_NO_IOSTREAMS 1
-# ifndef _DEBUG
-# define _STLP_DONT_USE_EXCEPTIONS 1
-# endif
-#endif
-
-#ifdef _MSC_VER
-# pragma warning(disable: 4711) // function 'xxx' selected for automatic inline expansion
-# pragma warning(disable: 4786) // identifier was truncated to '255' characters in the debug information
-# pragma warning(disable: 4290) // C++ Exception Specification ignored
-# pragma warning(disable: 4127) // constant expression
-# pragma warning(disable: 4710) // function not inlined
-# pragma warning(disable: 4503) // decorated name length exceeded, name was truncated
-//# if _MSC_VER == 1200 || _MSC_VER == 1300 || _MSC_VER == 1310
-
-typedef signed char int8_t;
-typedef signed short int16_t;
-typedef signed long int32_t;
-typedef signed __int64 int64_t;
-
-typedef unsigned char u_int8_t;
-typedef unsigned short u_int16_t;
-typedef unsigned long u_int32_t;
-typedef unsigned __int64 u_int64_t;
-
-//# endif
-
-#endif
-
-#if defined(_MSC_VER)
-#define _LL(x) x##ll
-#define _ULL(x) x##ull
-#define I64_FMT "%I64d"
-#elif defined(SIZEOF_LONG) && SIZEOF_LONG == 8
-#define _LL(x) x##l
-#define _ULL(x) x##ul
-#define I64_FMT "%ld"
-#else
-#define _LL(x) x##ll
-#define _ULL(x) x##ull
-#define I64_FMT "%lld"
-#endif
-
-#ifdef _WIN32
-
-# define PATH_SEPARATOR '\\'
-# define PATH_SEPARATOR_STR "\\"
-
-#else
-
-# define PATH_SEPARATOR '/'
-# define PATH_SEPARATOR_STR "/"
-
-#endif
-
-#ifdef _MSC_VER
-
-# ifndef CDECL
-# define CDECL _cdecl
-# endif
-
-#else // _MSC_VER
-
-# ifndef CDECL
-# define CDECL
-# endif
-
-#endif // _MSC_VER
-
-#define BZ_NO_STDIO
-
-
-
-#endif // !defined(CONFIG_H)
-
-/**
- * @file
- * $Id: config.h,v 1.35 2005/12/03 20:36:50 arnetheduck Exp $
- */
diff --git a/hasher/crc32x64.asm b/hasher/crc32x64.asm
new file mode 100644
index 000000000..02fe36de4
--- /dev/null
+++ b/hasher/crc32x64.asm
@@ -0,0 +1,41 @@
+.code
+crcCalc PROC PUBLIC USES rax rbx rcx rdx rdi rsi pdwCrc32:PTR DWORD, ptrCrc32Table:PTR DWORD,bufferAsm:PTR BYTE,dwBytesReadAsm:DWORD
+
+ ;mov rax, pdwCrc32 ; Load the pointer to dwCrc32
+ mov rsi, rcx
+ mov ecx, [rsi] ; Dereference the pointer to load dwCrc32
+
+ ;mov rdi, ptrCrc32Table ; Load the CRC32 table
+
+ ;mov rsi, bufferAsm ; Load buffer
+ xor rbx, rbx
+ ;mov ebx, dwBytesReadAsm ; Load dwBytesRead
+ lea rdi, [r8 + r9] ; Calculate the end of the buffer
+
+ crc32loop:
+ xor rax, rax ; Clear the eax register
+ mov bl, byte ptr [r8] ; Load the current source byte
+
+ mov al, cl ; Copy crc value into eax
+ inc r8 ; Advance the source pointer
+
+ xor al, bl ; Create the index into the CRC32 table
+ shr ecx, 8
+
+ mov ebx, [rdx + rax * 4] ; Get the value out of the table
+ xor ecx, ebx ; xor with the current byte
+
+ cmp rdi, r8 ; Have we reached the end of the buffer?
+ jne crc32loop
+
+ ; Restore the edi and esi registers
+ ;pop edi
+ ;pop esi
+
+ ;mov rax, pdwCrc32 ; Load the pointer to dwCrc32
+ mov [rsi], ecx ; Write the result
+
+ ret
+
+crcCalc ENDP
+END
\ No newline at end of file
diff --git a/hasher/crc32x86.asm b/hasher/crc32x86.asm
new file mode 100644
index 000000000..44f9460fb
--- /dev/null
+++ b/hasher/crc32x86.asm
@@ -0,0 +1,42 @@
+.586p
+.model flat, C
+
+.code
+crcCalc PROC PUBLIC USES eax ebx ecx edx edi esi pdwCrc32:PTR DWORD, ptrCrc32Table:PTR DWORD,bufferAsm:PTR BYTE,dwBytesReadAsm:DWORD
+
+ mov eax, pdwCrc32 ; Load the pointer to dwCrc32
+ mov ecx, [eax] ; Dereference the pointer to load dwCrc32
+
+ mov edi, ptrCrc32Table ; Load the CRC32 table
+
+ mov esi, bufferAsm ; Load buffer
+ mov ebx, dwBytesReadAsm ; Load dwBytesRead
+ lea edx, [esi + ebx] ; Calculate the end of the buffer
+
+ crc32loop:
+ xor eax, eax ; Clear the eax register
+ mov bl, byte ptr [esi] ; Load the current source byte
+
+ mov al, cl ; Copy crc value into eax
+ inc esi ; Advance the source pointer
+
+ xor al, bl ; Create the index into the CRC32 table
+ shr ecx, 8
+
+ mov ebx, [edi + eax * 4] ; Get the value out of the table
+ xor ecx, ebx ; xor with the current byte
+
+ cmp edx, esi ; Have we reached the end of the buffer?
+ jne crc32loop
+
+ ; Restore the edi and esi registers
+ ;pop edi
+ ;pop esi
+
+ mov eax, pdwCrc32 ; Load the pointer to dwCrc32
+ mov [eax], ecx ; Write the result
+
+ ret
+
+crcCalc ENDP
+END
\ No newline at end of file
diff --git a/hasher/hash_crc.cpp b/hasher/hash_crc.cpp
index aeb27b4c6..d857d6e4a 100644
--- a/hasher/hash_crc.cpp
+++ b/hasher/hash_crc.cpp
@@ -20,63 +20,98 @@
#include
#include
+#ifdef _WIN64
+extern "C" void __fastcall crcCalc(DWORD *pdwCrc32, DWORD *ptrCrc32Table, BYTE *bufferAsm, DWORD dwBytesReadAsm);
+#else
+extern "C" void crcCalc(DWORD *pdwCrc32, DWORD *ptrCrc32Table, BYTE *bufferAsm, DWORD dwBytesReadAsm);
+#endif
/* Table of CRCs of all 8-bit messages. */
-unsigned long crc_table[256];
+static CONST DWORD arrdwCrc32Table[256] =
+{
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
-/* Flag: has the table been computed? Initially false. */
-int crc_table_computed = 0;
+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
-/* Make the table for a fast CRC. */
-void make_crc_table(void){
- unsigned long c;
- int n, k;
+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
- for (n = 0; n < 256; n++) {
- c = (unsigned long) n;
- for (k = 0; k < 8; k++) {
- if (c & 1)
- c = 0xedb88320L ^ (c >> 1);
- else
- c = c >> 1;
- }
- crc_table[n] = c;
- }
- crc_table_computed = 1;
-}
+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
+};
/* Update a running CRC with the bytes buf[0..len-1]--the CRC
should be initialized to all 1's, and the transmitted value
is the 1's complement of the final running CRC (see the
crc() routine below)). */
-unsigned long update_crc(unsigned long crc, unsigned char *buf, int len)
-{
- unsigned long c = crc;
- int n;
-
-
- for (n = 0; n < len; n++) {
- c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
- }
- return c;
-}
-
-/* Return the CRC of the bytes buf[0..len-1]. */
-unsigned long crc(unsigned char *buf, int len)
+DigestCRC::DigestCRC()
{
- return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;
-}
-
-DigestCRC::DigestCRC(){
- if (!crc_table_computed)
- make_crc_table();
crc_value = 0xffffffffL;
}
void DigestCRC::clean(){
}
-void DigestCRC::update(char* s, int len){
- crc_value = update_crc(crc_value, (unsigned char *)s, len);
+void DigestCRC::update(char* s, int len)
+{
+ crcCalc(&crc_value, (DWORD *)&arrdwCrc32Table,(BYTE *)s, (DWORD)len);
}
int DigestCRC::digest(char* sum, int len){
int val=crc_value^0xffffffffL;
diff --git a/hasher/hash_md5.cpp b/hasher/hash_md5.cpp
index 5b72ba534..3d03d4a82 100644
--- a/hasher/hash_md5.cpp
+++ b/hasher/hash_md5.cpp
@@ -14,221 +14,26 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//#include
-
#include "stdafx.h"
-#include "stdinc.h"
#include "hash_wrapper.h"
+#include "MD5.h"
-// Code by: B-Con (http://b-con.us)
-// Released under the GNU GPL
-// MD5 Hash Digest implementation (little endian byte order)
-
-
-// Bah, signed variables are for wimps
-#define uchar unsigned char
-#define uint unsigned int
-
-// DBL_INT_ADD treats two unsigned ints a and b as one 64-bit integer and adds c to it
-#define DBL_INT_ADD(a,b,c) if (a > 0xffffffff - c) ++b; a += c;
-#define ROTLEFT(a,b) ((a << b) | (a >> (32-b)))
-
-#define F(x,y,z) ((x & y) | (~x & z))
-#define G(x,y,z) ((x & z) | (y & ~z))
-#define H(x,y,z) (x ^ y ^ z)
-#define I(x,y,z) (y ^ (x | ~z))
-
-#define FF(a,b,c,d,m,s,t) { a += F(b,c,d) + m + t; \
- a = b + ROTLEFT(a,s); }
-#define GG(a,b,c,d,m,s,t) { a += G(b,c,d) + m + t; \
- a = b + ROTLEFT(a,s); }
-#define HH(a,b,c,d,m,s,t) { a += H(b,c,d) + m + t; \
- a = b + ROTLEFT(a,s); }
-#define II(a,b,c,d,m,s,t) { a += I(b,c,d) + m + t; \
- a = b + ROTLEFT(a,s); }
-
-
-typedef struct {
- uchar data[64];
- uint datalen;
- uint bitlen[2];
- uint state[4];
-} MD5_CTX;
-
-
-void md5_transform(MD5_CTX *ctx, uchar data[])
-{
- uint a,b,c,d,m[16],i,j;
-
- // MD5 specifies big endian byte order, but this implementation assumes a little
- // endian byte order CPU. Reverse all the bytes upon input, and re-reverse them
- // on output (in md5_final()).
- for (i=0,j=0; i < 16; ++i, j += 4)
- m[i] = (data[j]) + (data[j+1] << 8) + (data[j+2] << 16) + (data[j+3] << 24);
-
- a = ctx->state[0];
- b = ctx->state[1];
- c = ctx->state[2];
- d = ctx->state[3];
-
- 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);
- FF(a,b,c,d,m[4], 7,0xf57c0faf);
- FF(d,a,b,c,m[5], 12,0x4787c62a);
- FF(c,d,a,b,m[6], 17,0xa8304613);
- FF(b,c,d,a,m[7], 22,0xfd469501);
- FF(a,b,c,d,m[8], 7,0x698098d8);
- FF(d,a,b,c,m[9], 12,0x8b44f7af);
- FF(c,d,a,b,m[10],17,0xffff5bb1);
- FF(b,c,d,a,m[11],22,0x895cd7be);
- FF(a,b,c,d,m[12], 7,0x6b901122);
- FF(d,a,b,c,m[13],12,0xfd987193);
- FF(c,d,a,b,m[14],17,0xa679438e);
- FF(b,c,d,a,m[15],22,0x49b40821);
-
- GG(a,b,c,d,m[1], 5,0xf61e2562);
- GG(d,a,b,c,m[6], 9,0xc040b340);
- GG(c,d,a,b,m[11],14,0x265e5a51);
- GG(b,c,d,a,m[0], 20,0xe9b6c7aa);
- GG(a,b,c,d,m[5], 5,0xd62f105d);
- GG(d,a,b,c,m[10], 9,0x02441453);
- GG(c,d,a,b,m[15],14,0xd8a1e681);
- GG(b,c,d,a,m[4], 20,0xe7d3fbc8);
- GG(a,b,c,d,m[9], 5,0x21e1cde6);
- GG(d,a,b,c,m[14], 9,0xc33707d6);
- GG(c,d,a,b,m[3], 14,0xf4d50d87);
- GG(b,c,d,a,m[8], 20,0x455a14ed);
- GG(a,b,c,d,m[13], 5,0xa9e3e905);
- GG(d,a,b,c,m[2], 9,0xfcefa3f8);
- GG(c,d,a,b,m[7], 14,0x676f02d9);
- GG(b,c,d,a,m[12],20,0x8d2a4c8a);
-
- HH(a,b,c,d,m[5], 4,0xfffa3942);
- HH(d,a,b,c,m[8], 11,0x8771f681);
- HH(c,d,a,b,m[11],16,0x6d9d6122);
- HH(b,c,d,a,m[14],23,0xfde5380c);
- HH(a,b,c,d,m[1], 4,0xa4beea44);
- HH(d,a,b,c,m[4], 11,0x4bdecfa9);
- HH(c,d,a,b,m[7], 16,0xf6bb4b60);
- HH(b,c,d,a,m[10],23,0xbebfbc70);
- HH(a,b,c,d,m[13], 4,0x289b7ec6);
- HH(d,a,b,c,m[0], 11,0xeaa127fa);
- HH(c,d,a,b,m[3], 16,0xd4ef3085);
- HH(b,c,d,a,m[6], 23,0x04881d05);
- HH(a,b,c,d,m[9], 4,0xd9d4d039);
- HH(d,a,b,c,m[12],11,0xe6db99e5);
- HH(c,d,a,b,m[15],16,0x1fa27cf8);
- HH(b,c,d,a,m[2], 23,0xc4ac5665);
-
- II(a,b,c,d,m[0], 6,0xf4292244);
- II(d,a,b,c,m[7], 10,0x432aff97);
- II(c,d,a,b,m[14],15,0xab9423a7);
- II(b,c,d,a,m[5], 21,0xfc93a039);
- II(a,b,c,d,m[12], 6,0x655b59c3);
- II(d,a,b,c,m[3], 10,0x8f0ccc92);
- II(c,d,a,b,m[10],15,0xffeff47d);
- II(b,c,d,a,m[1], 21,0x85845dd1);
- II(a,b,c,d,m[8], 6,0x6fa87e4f);
- II(d,a,b,c,m[15],10,0xfe2ce6e0);
- II(c,d,a,b,m[6], 15,0xa3014314);
- II(b,c,d,a,m[13],21,0x4e0811a1);
- II(a,b,c,d,m[4], 6,0xf7537e82);
- II(d,a,b,c,m[11],10,0xbd3af235);
- II(c,d,a,b,m[2], 15,0x2ad7d2bb);
- II(b,c,d,a,m[9], 21,0xeb86d391);
-
- ctx->state[0] += a;
- ctx->state[1] += b;
- ctx->state[2] += c;
- ctx->state[3] += d;
-}
-
-void md5_init(MD5_CTX *ctx)
-{
- ctx->datalen = 0;
- ctx->bitlen[0] = 0;
- ctx->bitlen[1] = 0;
- ctx->state[0] = 0x67452301;
- ctx->state[1] = 0xEFCDAB89;
- ctx->state[2] = 0x98BADCFE;
- ctx->state[3] = 0x10325476;
-}
-
-void md5_update(MD5_CTX *ctx, uchar *data, uint len)
-{
- uint i;
-
- for (i=0; i < len; ++i) {
- ctx->data[ctx->datalen] = data[i];
- ctx->datalen++;
- if (ctx->datalen == 64) {
- md5_transform(ctx,ctx->data);
- DBL_INT_ADD(ctx->bitlen[0],ctx->bitlen[1],512);
- ctx->datalen = 0;
- }
- }
-}
-
-void md5_final(MD5_CTX *ctx, uchar hash[])
-{
- uint i;
-
- i = ctx->datalen;
-
- // Pad whatever data is left in the buffer.
- if (ctx->datalen < 56) {
- ctx->data[i++] = 0x80;
- while (i < 56)
- ctx->data[i++] = 0x00;
- }
- else if (ctx->datalen >= 56) {
- ctx->data[i++] = 0x80;
- while (i < 64)
- ctx->data[i++] = 0x00;
- md5_transform(ctx,ctx->data);
- memset(ctx->data,0,56);
- }
-
- // Append to the padding the total message's length in bits and transform.
- DBL_INT_ADD(ctx->bitlen[0],ctx->bitlen[1],8 * ctx->datalen);
- ctx->data[56] = ctx->bitlen[0];
- ctx->data[57] = ctx->bitlen[0] >> 8;
- ctx->data[58] = ctx->bitlen[0] >> 16;
- ctx->data[59] = ctx->bitlen[0] >> 24;
- ctx->data[60] = ctx->bitlen[1];
- ctx->data[61] = ctx->bitlen[1] >> 8;
- ctx->data[62] = ctx->bitlen[1] >> 16;
- ctx->data[63] = ctx->bitlen[1] >> 24;
- md5_transform(ctx,ctx->data);
-
- // Since this implementation uses little endian byte ordering and MD uses big endian,
- // reverse all the bytes when copying the final state to the output hash.
- for (i=0; i < 4; ++i) {
- hash[i] = (ctx->state[0] >> (i*8)) & 0x000000ff;
- hash[i+4] = (ctx->state[1] >> (i*8)) & 0x000000ff;
- hash[i+8] = (ctx->state[2] >> (i*8)) & 0x000000ff;
- hash[i+12] = (ctx->state[3] >> (i*8)) & 0x000000ff;
- }
-}
DigestMD5::DigestMD5(){
- MD5_CTX* my = new MD5_CTX;
- md5_init(my);
- addr = (void*)my;
+ addr = (void*)new CMD5();
}
void DigestMD5::clean(){
- delete (MD5_CTX*)addr;
- //free((MD5_CTX*)addr);
+ CMD5* md5 = (CMD5*)addr;
+ delete md5;
}
-void DigestMD5::update(char* s, int len){
- md5_update((MD5_CTX*)addr,(uchar*)s,len);
+void DigestMD5::update(char* buf, int len){
+ CMD5* md5 = (CMD5*)addr;
+ md5->Add(buf, len);
}
int DigestMD5::digest(char* sum, int len){
- uchar hash[16];
- md5_final((MD5_CTX*)addr,hash);
- memcpy(sum,hash,16);
+ CMD5* md5= (CMD5*)addr;
+ md5->Finish();
+ md5->GetHash((uchar *)sum);
return 16;
-}
\ No newline at end of file
+}
diff --git a/hasher/hash_sha.cpp b/hasher/hash_sha.cpp
index be2c8b186..93dbdbbf1 100644
--- a/hasher/hash_sha.cpp
+++ b/hasher/hash_sha.cpp
@@ -33,8 +33,7 @@ void DigestSHA::update(char* buf, int len){
}
int DigestSHA::digest(char* sum, int len){
CSHA* sha = (CSHA*)addr;
- CAICHHash hash;
- sha->Finish(hash);
- memcpy(sum,hash.GetRawHash(), hash.GetHashSize());
- return hash.GetHashSize();
+ sha->Finish();
+ sha->GetHash((uchar *)sum);
+ return 20;
}
diff --git a/hasher/hash_wrapper.h b/hasher/hash_wrapper.h
index f0aeea855..bccb23cfc 100644
--- a/hasher/hash_wrapper.h
+++ b/hasher/hash_wrapper.h
@@ -27,7 +27,7 @@ virtual void clean()=0;
class DigestCRC : public Digest{
private:
-unsigned long crc_value;
+DWORD crc_value;
public:
DigestCRC();
void update(char* buf, int len);
diff --git a/hasher/hasher.cpp b/hasher/hasher.cpp
index 7b241e9f3..3dc1ff367 100644
--- a/hasher/hasher.cpp
+++ b/hasher/hasher.cpp
@@ -9,6 +9,8 @@
#include
#include
#include
+#include
+
/////////////////////////////////////////////////////////////////////////////////
#define ED2K_CHUNK_SIZE 9728000
@@ -79,7 +81,7 @@ extern "C" __declspec(dllexport) int __cdecl CalculateHashes_SyncIO(const TCHAR
}
MD4Engine.Finish();
- MD4Engine.GetHash(&md4);
+ MD4Engine.GetHash((uchar *)&md4);
BYTE * pData = (BYTE*)&md4;
for (int n=0; n<16; n++)
pTemp[nChunk*16+n] = pData[n];
@@ -113,7 +115,7 @@ extern "C" __declspec(dllexport) int __cdecl CalculateHashes_SyncIO(const TCHAR
MD4Engine.Reset();
MD4Engine.Add(pTemp, nChunks*16);
MD4Engine.Finish();
- MD4Engine.GetHash(&md4);
+ MD4Engine.GetHash((uchar *)&md4);
BYTE * pData = (BYTE*)&md4;
for (int n=0; n<16; n++)
pResult[n] = pData[n];
@@ -269,7 +271,7 @@ extern "C" __declspec(dllexport) int __cdecl CalculateHashes_AsyncIO(const TCHAR
if (getMD5) md5.update(blocks[iMaskedReaderPos], dwBytesChunkLeft);
//calculate MD4 of chunk
MD4Engine.Finish();
- MD4Engine.GetHash(&md4);
+ MD4Engine.GetHash((uchar *)&md4);
BYTE * pData = (BYTE*)&md4;
for (int n=0; n<16; n++)
pTemp[nChunk*16+n] = pData[n];
@@ -326,7 +328,7 @@ extern "C" __declspec(dllexport) int __cdecl CalculateHashes_AsyncIO(const TCHAR
MD4Engine.Reset();
MD4Engine.Add(pTemp, nChunks*16);
MD4Engine.Finish();
- MD4Engine.GetHash(&md4);
+ MD4Engine.GetHash((uchar *)&md4);
BYTE * pData = (BYTE*)&md4;
for (int n=0; n<16; n++)
pResult[n] = pData[n];
diff --git a/hasher/stdinc.h b/hasher/stdinc.h
deleted file mode 100644
index 687d3d39b..000000000
--- a/hasher/stdinc.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2001-2005 Jacek Sieka, arnetheduck on gmail point com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#if !defined(STDINC_H)
-#define STDINC_H
-
-#include "config.h"
-
-#ifdef _WIN32
-
-
-#define WIN32_LEAN_AND_MEAN
-#define _WTL_NO_CSTRING
-#define _ATL_NO_OPENGL
-#define _ATL_NO_MSIMG
-#define _ATL_NO_COM
-#define _ATL_NO_HOSTING
-#define _ATL_NO_OLD_NAMES
-
-#include
-
-#include
-#include
-#include
-
-#else
-#include
-#endif
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include