From clauflibitFriiDump-0.5.3.1

This commit is contained in:
Braden McDaniel 2013-11-01 12:26:04 -04:00
parent fe937e7f4b
commit 87b108d6a1
63 changed files with 11067 additions and 26 deletions

View file

@ -0,0 +1,77 @@
# Create a library called "Hello" which includes the source file "hello.cxx".
# The extension is already found. Any number of sources could be listed here.
add_library (
multihashlib
${libmultihash_type}
#SHARED
#STATIC
crc32.c
edonkey.c
md4.c
md5.c
multihash.c
sha1.c
crc32.h
edonkey.h
md4.h
md5.h
multihash.h
sha1.h
)
set_target_properties (multihashlib PROPERTIES OUTPUT_NAME "multihash")
# Before making a release, the LTVERSION string should be modified.
# The string is of the form CURRENT:REVISION:AGE.
#
# CURRENT (C)
# The most recent interface number that this library implements.
#
# REVISION (R)
# The implementation number that this library implements.
#
# AGE (A)
# The difference between the newest and oldest interfaces that this
# library implements. In other works, the library implements all the
# interface numbers in the range from number 'CURRENT - AGE' to
# 'CURRENT'.
#
# This means that:
#
# - If interfaces have been changed or added, but binary compatibility has
# been preserved, change to C+1:0:A+1
#
# - If binary compatibility has been broken (eg removed or changed
# interfaces) change to C+1:0:0
#
# - If the interface is the same as the previous version, change to C:R+1:A
#
set_target_properties (multihashlib PROPERTIES SOVERSION 1.0.0)
#get_target_property(libhash_type multihashlib TYPE)
if (WIN32)
if (libhash_type STREQUAL "SHARED")
# MESSAGE ("Building libmultihash DLL")
ADD_DEFINITIONS (-DMULTIHASH_BUILD_DLL)
set_target_properties (multihashlib PROPERTIES DEFINE_SYMBOL MULTIHASH_EXPORTS)
install (
TARGETS multihashlib
RUNTIME DESTINATION /
#ARCHIVE DESTINATION lib
)
endif (libhash_type STREQUAL "SHARED")
else (WIN32)
# Install stuff, only if a shared library is being built
if (libhash_type STREQUAL "SHARED")
install (
TARGETS multihashlib
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static
)
endif (libhash_type STREQUAL "SHARED")
endif (WIN32)

120
libmultihash/crc32.c Normal file
View file

@ -0,0 +1,120 @@
/*
* Copyright (c) 1995, Edward B. Hamrick
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that
*
* (i) the above copyright notice and the text in this "C" comment block
* appear in all copies of the software and related documentation, and
*
* (ii) any modifications to this source file must be sent, via e-mail
* to the copyright owner (currently hamrick@primenet.com) within
* 30 days of such modification.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL EDWARD B. HAMRICK BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "crc32.h"
/* This is a pre-computed table to make crc computations efficient */
static unsigned long crctable[] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
};
/*
* This CRC algorithm is the same as that used in zip. Normally it
* should be initialized with 0xffffffff, and the final CRC stored
* should be crc ^ 0xffffffff.
*
* It implements the polynomial:
*
* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
*/
unsigned long CrcUpdate( /* returns updated crc */
unsigned long crc, /* starting crc */
unsigned char *buffer, /* buffer to use to update crc */
long length /* length of buffer */
)
{
long i;
for (i=0; i<length; i++)
{
crc = crctable[buffer[i] ^ ((unsigned char) crc)] ^ (crc >> 8);
}
return crc;
}

53
libmultihash/crc32.h Normal file
View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 1995, Edward B. Hamrick
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that
*
* (i) the above copyright notice and the text in this "C" comment block
* appear in all copies of the software and related documentation, and
*
* (ii) any modifications to this source file must be sent, via e-mail
* to the copyright owner (currently hamrick@primenet.com) within
* 30 days of such modification.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL EDWARD B. HAMRICK BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This CRC algorithm is the same as that used in zip. Normally it
* should be initialized with 0xffffffff, and the final CRC stored
* should be crc ^ 0xffffffff.
*
* It implements the polynomial:
*
* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
*/
#ifndef __CRC_H
#define __CRC_H
#ifdef __cplusplus
extern "C" {
#endif
unsigned long CrcUpdate( /* returns updated crc */
unsigned long crc, /* starting crc */
unsigned char *buffer, /* buffer to use to update crc */
long length /* length of buffer */
);
#ifdef __cplusplus
}
#endif
#endif

83
libmultihash/edonkey.c Normal file
View file

@ -0,0 +1,83 @@
/***************************************************************************
* Copyright (C) 2007 by SukkoPera *
* sukkopera@sukkology.net *
* *
* 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. *
***************************************************************************/
/* As Wikipedia (http://en.wikipedia.org/wiki/Ed2k_link) says:
* The ed2k hash function is a MD4 root hash of a MD4 hash list, and gives a
* different result than simply MD4: The file data is divided into full
* chunks of 9728000 bytes plus a remainder chunk, and a separate 128-bit
* MD4 checksum is computed for each. The ed2k hash is computed by
* concatenating the chunks' MD4 checksums in order and hashing the result
*using MD4.
*/
#include <stdio.h>
#include "edonkey.h"
#include "md4.h"
void ed2khash_starts (ed2khash_context *ctx) {
md4_starts (&(ctx -> md4cur));
md4_starts (&(ctx -> md4final));
ctx -> bytes_processed = 0;
ctx -> chunks = 0;
return;
}
void ed2khash_update (ed2khash_context *ctx, unsigned char *input, int ilen) {
unsigned long x;
while (ilen > 0) {
if (ctx -> bytes_processed + ilen >= ED2KHASH_CHUNKSIZE)
x = ED2KHASH_CHUNKSIZE - ctx -> bytes_processed;
else
x = ilen;
md4_update (&(ctx -> md4cur), input, x);
if ((ctx -> bytes_processed += x) % ED2KHASH_CHUNKSIZE == 0) {
/* End of a chunk, save current MD4 and start a new one */
md4_finish (&(ctx -> md4cur), ctx -> lastmd4);
md4_starts (&(ctx -> md4cur));
ctx -> bytes_processed = 0;
ctx -> chunks++;
md4_update (&(ctx -> md4final), ctx -> lastmd4, MD4_DIGESTSIZE);
}
ilen -= x;
input += x;
}
return;
}
void ed2khash_finish (ed2khash_context *ctx, unsigned char *output) {
if (ctx -> chunks > 0) {
md4_finish (&(ctx -> md4cur), ctx -> lastmd4);
md4_update (&(ctx -> md4final), ctx -> lastmd4, MD4_DIGESTSIZE);
md4_finish (&(ctx -> md4final), output);
} else {
/* If we have a single chunk, use its MD4 straight away */
md4_finish (&(ctx -> md4cur), output);
}
return;
}

36
libmultihash/edonkey.h Normal file
View file

@ -0,0 +1,36 @@
/***************************************************************************
* Copyright (C) 2007 by SukkoPera *
* sukkopera@sukkology.net *
* *
* 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. *
***************************************************************************/
#include "md4.h"
#define ED2KHASH_CHUNKSIZE 9728000
#define MD4_DIGESTSIZE 16
typedef struct {
unsigned long bytes_processed;
unsigned int chunks;
md4_context md4cur;
md4_context md4final;
unsigned char lastmd4[MD4_DIGESTSIZE];
} ed2khash_context;
void ed2khash_starts (ed2khash_context *ctx);
void ed2khash_update (ed2khash_context *ctx, unsigned char *input, int ilen);
void ed2khash_finish (ed2khash_context *ctx, unsigned char *output);

441
libmultihash/md4.c Normal file
View file

@ -0,0 +1,441 @@
/*
* RFC 1186/1320 compliant MD4 implementation
*
* Copyright (C) 2006-2007 Christophe Devine
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License, version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
/*
* The MD4 algorithm was designed by Ron Rivest in 1990.
*
* http://www.ietf.org/rfc/rfc1186.txt
* http://www.ietf.org/rfc/rfc1320.txt
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <string.h>
#include <stdio.h>
#include "md4.h"
/*
* 32-bit integer manipulation macros (little endian)
*/
#ifndef GET_UINT32_LE
#define GET_UINT32_LE(n,b,i) \
{ \
(n) = ( (unsigned long) (b)[(i) ] ) \
| ( (unsigned long) (b)[(i) + 1] << 8 ) \
| ( (unsigned long) (b)[(i) + 2] << 16 ) \
| ( (unsigned long) (b)[(i) + 3] << 24 ); \
}
#endif
#ifndef PUT_UINT32_LE
#define PUT_UINT32_LE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
}
#endif
/*
* MD4 context setup
*/
void md4_starts( md4_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
}
static void md4_process( md4_context *ctx, unsigned char data[64] )
{
unsigned long X[16], A, B, C, D;
GET_UINT32_LE( X[ 0], data, 0 );
GET_UINT32_LE( X[ 1], data, 4 );
GET_UINT32_LE( X[ 2], data, 8 );
GET_UINT32_LE( X[ 3], data, 12 );
GET_UINT32_LE( X[ 4], data, 16 );
GET_UINT32_LE( X[ 5], data, 20 );
GET_UINT32_LE( X[ 6], data, 24 );
GET_UINT32_LE( X[ 7], data, 28 );
GET_UINT32_LE( X[ 8], data, 32 );
GET_UINT32_LE( X[ 9], data, 36 );
GET_UINT32_LE( X[10], data, 40 );
GET_UINT32_LE( X[11], data, 44 );
GET_UINT32_LE( X[12], data, 48 );
GET_UINT32_LE( X[13], data, 52 );
GET_UINT32_LE( X[14], data, 56 );
GET_UINT32_LE( X[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
#define F(x, y, z) ((x & y) | ((~x) & z))
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 1], 7 );
P( C, D, A, B, X[ 2], 11 );
P( B, C, D, A, X[ 3], 19 );
P( A, B, C, D, X[ 4], 3 );
P( D, A, B, C, X[ 5], 7 );
P( C, D, A, B, X[ 6], 11 );
P( B, C, D, A, X[ 7], 19 );
P( A, B, C, D, X[ 8], 3 );
P( D, A, B, C, X[ 9], 7 );
P( C, D, A, B, X[10], 11 );
P( B, C, D, A, X[11], 19 );
P( A, B, C, D, X[12], 3 );
P( D, A, B, C, X[13], 7 );
P( C, D, A, B, X[14], 11 );
P( B, C, D, A, X[15], 19 );
#undef P
#undef F
#define F(x,y,z) ((x & y) | (x & z) | (y & z))
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 4], 5 );
P( C, D, A, B, X[ 8], 9 );
P( B, C, D, A, X[12], 13 );
P( A, B, C, D, X[ 1], 3 );
P( D, A, B, C, X[ 5], 5 );
P( C, D, A, B, X[ 9], 9 );
P( B, C, D, A, X[13], 13 );
P( A, B, C, D, X[ 2], 3 );
P( D, A, B, C, X[ 6], 5 );
P( C, D, A, B, X[10], 9 );
P( B, C, D, A, X[14], 13 );
P( A, B, C, D, X[ 3], 3 );
P( D, A, B, C, X[ 7], 5 );
P( C, D, A, B, X[11], 9 );
P( B, C, D, A, X[15], 13 );
#undef P
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 8], 9 );
P( C, D, A, B, X[ 4], 11 );
P( B, C, D, A, X[12], 15 );
P( A, B, C, D, X[ 2], 3 );
P( D, A, B, C, X[10], 9 );
P( C, D, A, B, X[ 6], 11 );
P( B, C, D, A, X[14], 15 );
P( A, B, C, D, X[ 1], 3 );
P( D, A, B, C, X[ 9], 9 );
P( C, D, A, B, X[ 5], 11 );
P( B, C, D, A, X[13], 15 );
P( A, B, C, D, X[ 3], 3 );
P( D, A, B, C, X[11], 9 );
P( C, D, A, B, X[ 7], 11 );
P( B, C, D, A, X[15], 15 );
#undef F
#undef P
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
}
/*
* MD4 process buffer
*/
void md4_update( md4_context *ctx, unsigned char *input, int ilen )
{
int fill;
unsigned long left;
if( ilen <= 0 )
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (unsigned long) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, fill );
md4_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
md4_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, ilen );
}
}
static const unsigned char md4_padding[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
};
/*
* MD4 final digest
*/
void md4_finish( md4_context *ctx, unsigned char *output )
{
unsigned long last, padn;
unsigned long high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_LE( low, msglen, 0 );
PUT_UINT32_LE( high, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
md4_update( ctx, (unsigned char *) md4_padding, padn );
md4_update( ctx, msglen, 8 );
PUT_UINT32_LE( ctx->state[0], output, 0 );
PUT_UINT32_LE( ctx->state[1], output, 4 );
PUT_UINT32_LE( ctx->state[2], output, 8 );
PUT_UINT32_LE( ctx->state[3], output, 12 );
}
/*
* Output = MD4( input buffer )
*/
void md4( unsigned char *input, int ilen,
unsigned char *output )
{
md4_context ctx;
md4_starts( &ctx );
md4_update( &ctx, input, ilen );
md4_finish( &ctx, output );
memset( &ctx, 0, sizeof( md4_context ) );
}
/*
* Output = MD4( file contents )
*/
int md4_file( char *path, unsigned char *output )
{
FILE *f;
size_t n;
md4_context ctx;
unsigned char buf[1024];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( 1 );
md4_starts( &ctx );
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
md4_update( &ctx, buf, (int) n );
md4_finish( &ctx, output );
memset( &ctx, 0, sizeof( md4_context ) );
if( ferror( f ) != 0 )
{
fclose( f );
return( 2 );
}
fclose( f );
return( 0 );
}
/*
* MD4 HMAC context setup
*/
void md4_hmac_starts( md4_context *ctx,
unsigned char *key, int keylen )
{
int i;
memset( ctx->ipad, 0x36, 64 );
memset( ctx->opad, 0x5C, 64 );
for( i = 0; i < keylen; i++ )
{
if( i >= 64 ) break;
ctx->ipad[i] ^= key[i];
ctx->opad[i] ^= key[i];
}
md4_starts( ctx );
md4_update( ctx, ctx->ipad, 64 );
}
/*
* MD4 HMAC process buffer
*/
void md4_hmac_update( md4_context *ctx,
unsigned char *input, int ilen )
{
md4_update( ctx, input, ilen );
}
/*
* MD4 HMAC final digest
*/
void md4_hmac_finish( md4_context *ctx, unsigned char *output )
{
unsigned char tmpbuf[16];
md4_finish( ctx, tmpbuf );
md4_starts( ctx );
md4_update( ctx, ctx->opad, 64 );
md4_update( ctx, tmpbuf, 16 );
md4_finish( ctx, output );
memset( tmpbuf, 0, sizeof( tmpbuf ) );
}
/*
* Output = HMAC-MD4( hmac key, input buffer )
*/
void md4_hmac( unsigned char *key, int keylen,
unsigned char *input, int ilen,
unsigned char *output )
{
md4_context ctx;
md4_hmac_starts( &ctx, key, keylen );
md4_hmac_update( &ctx, input, ilen );
md4_hmac_finish( &ctx, output );
memset( &ctx, 0, sizeof( md4_context ) );
}
static const char _md4_src[] = "_md4_src";
#if defined(SELF_TEST)
/*
* RFC 1320 test vectors
*/
static const char md4_test_str[7][81] =
{
{ "" },
{ "a" },
{ "abc" },
{ "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012" \
"345678901234567890" }
};
static const unsigned char md4_test_sum[7][16] =
{
{ 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
{ 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
{ 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
{ 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
{ 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
{ 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
{ 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
};
/*
* Checkup routine
*/
int md4_self_test( int verbose )
{
int i;
unsigned char md4sum[16];
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
printf( " MD4 test #%d: ", i + 1 );
md4( (unsigned char *) md4_test_str[i],
strlen( md4_test_str[i] ), md4sum );
if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#else
int md4_self_test( int verbose )
{
return( 0 );
}
#endif

121
libmultihash/md4.h Normal file
View file

@ -0,0 +1,121 @@
/**
* \file md4.h
*/
#ifndef _MD4_H
#define _MD4_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD4 context structure
*/
typedef struct
{
unsigned long total[2]; /*!< number of bytes processed */
unsigned long state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
}
md4_context;
/**
* \brief MD4 context setup
*
* \param ctx context to be initialized
*/
void md4_starts( md4_context *ctx );
/**
* \brief MD4 process buffer
*
* \param ctx MD4 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md4_update( md4_context *ctx, unsigned char *input, int ilen );
/**
* \brief MD4 final digest
*
* \param ctx MD4 context
* \param output MD4 checksum result
*/
void md4_finish( md4_context *ctx, unsigned char *output );
/**
* \brief Output = MD4( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD4 checksum result
*/
void md4( unsigned char *input, int ilen,
unsigned char *output );
/**
* \brief Output = MD4( file contents )
*
* \param path input file name
* \param output MD4 checksum result
*
* \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed
*/
int md4_file( char *path, unsigned char *output );
/**
* \brief MD4 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void md4_hmac_starts( md4_context *ctx,
unsigned char *key, int keylen );
/**
* \brief MD4 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md4_hmac_update( md4_context *ctx,
unsigned char *input, int ilen );
/**
* \brief MD4 HMAC final digest
*
* \param ctx HMAC context
* \param output MD4 HMAC checksum result
*/
void md4_hmac_finish( md4_context *ctx, unsigned char *output );
/**
* \brief Output = HMAC-MD4( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-MD4 result
*/
void md4_hmac( unsigned char *key, int keylen,
unsigned char *input, int ilen,
unsigned char *output );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int md4_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* md4.h */

477
libmultihash/md5.c Normal file
View file

@ -0,0 +1,477 @@
/*
**********************************************************************
** md5.c **
** RSA Data Security, Inc. MD5 Message Digest Algorithm **
** Created: 2/17/90 RLR **
** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version **
**********************************************************************
*/
/*
**********************************************************************
** Copyright (C) 1990, RSA Data Security, Inc. All rights 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. **
**********************************************************************
*/
/* -- include the following line if the md5.h header file is separate -- */
#include "md5.h"
/* forward declaration */
static void Transform ();
static unsigned char PADDING[64] = {
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/* F, G and H are basic MD5 functions: selection, majority, parity */
#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)))
/* ROTATE_LEFT rotates x left n bits */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
/* Rotation is separate from addition to prevent recomputation */
#define FF(a, b, c, d, x, s, ac) \
{(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) \
{(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) \
{(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) \
{(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
void MD5Init (mdContext)
MD5_CTX *mdContext;
{
mdContext->i[0] = mdContext->i[1] = (UINT4)0;
/* Load magic initialization constants.
*/
mdContext->buf[0] = (UINT4)0x67452301;
mdContext->buf[1] = (UINT4)0xefcdab89;
mdContext->buf[2] = (UINT4)0x98badcfe;
mdContext->buf[3] = (UINT4)0x10325476;
}
void MD5Update (mdContext, inBuf, inLen)
MD5_CTX *mdContext;
unsigned char *inBuf;
unsigned int inLen;
{
UINT4 in[16];
int mdi;
unsigned int i, ii;
/* compute number of bytes mod 64 */
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
/* update number of bits */
if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
mdContext->i[1]++;
mdContext->i[0] += ((UINT4)inLen << 3);
mdContext->i[1] += ((UINT4)inLen >> 29);
while (inLen--) {
/* add new character to buffer, increment mdi */
mdContext->in[mdi++] = *inBuf++;
/* transform if necessary */
if (mdi == 0x40) {
for (i = 0, ii = 0; i < 16; i++, ii += 4)
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
(((UINT4)mdContext->in[ii+2]) << 16) |
(((UINT4)mdContext->in[ii+1]) << 8) |
((UINT4)mdContext->in[ii]);
Transform (mdContext->buf, in);
mdi = 0;
}
}
}
void MD5Final (mdContext)
MD5_CTX *mdContext;
{
UINT4 in[16];
int mdi;
unsigned int i, ii;
unsigned int padLen;
/* save number of bits */
in[14] = mdContext->i[0];
in[15] = mdContext->i[1];
/* compute number of bytes mod 64 */
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
/* pad out to 56 mod 64 */
padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
MD5Update (mdContext, PADDING, padLen);
/* append length in bits and transform */
for (i = 0, ii = 0; i < 14; i++, ii += 4)
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
(((UINT4)mdContext->in[ii+2]) << 16) |
(((UINT4)mdContext->in[ii+1]) << 8) |
((UINT4)mdContext->in[ii]);
Transform (mdContext->buf, in);
/* store buffer in digest */
for (i = 0, ii = 0; i < 4; i++, ii += 4) {
mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
mdContext->digest[ii+1] =
(unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
mdContext->digest[ii+2] =
(unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
mdContext->digest[ii+3] =
(unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
}
}
/* Basic MD5 step. Transform buf based on in.
*/
static void Transform (buf, in)
UINT4 *buf;
UINT4 *in;
{
UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
/* Round 1 */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
FF ( a, b, c, d, in[ 0], S11, 3614090360U); /* 1 */
FF ( d, a, b, c, in[ 1], S12, 3905402710U); /* 2 */
FF ( c, d, a, b, in[ 2], S13, 606105819U); /* 3 */
FF ( b, c, d, a, in[ 3], S14, 3250441966U); /* 4 */
FF ( a, b, c, d, in[ 4], S11, 4118548399U); /* 5 */
FF ( d, a, b, c, in[ 5], S12, 1200080426U); /* 6 */
FF ( c, d, a, b, in[ 6], S13, 2821735955U); /* 7 */
FF ( b, c, d, a, in[ 7], S14, 4249261313U); /* 8 */
FF ( a, b, c, d, in[ 8], S11, 1770035416U); /* 9 */
FF ( d, a, b, c, in[ 9], S12, 2336552879U); /* 10 */
FF ( c, d, a, b, in[10], S13, 4294925233U); /* 11 */
FF ( b, c, d, a, in[11], S14, 2304563134U); /* 12 */
FF ( a, b, c, d, in[12], S11, 1804603682U); /* 13 */
FF ( d, a, b, c, in[13], S12, 4254626195U); /* 14 */
FF ( c, d, a, b, in[14], S13, 2792965006U); /* 15 */
FF ( b, c, d, a, in[15], S14, 1236535329U); /* 16 */
/* Round 2 */
#define S21 5
#define S22 9
#define S23 14
#define S24 20
GG ( a, b, c, d, in[ 1], S21, 4129170786U); /* 17 */
GG ( d, a, b, c, in[ 6], S22, 3225465664U); /* 18 */
GG ( c, d, a, b, in[11], S23, 643717713U); /* 19 */
GG ( b, c, d, a, in[ 0], S24, 3921069994U); /* 20 */
GG ( a, b, c, d, in[ 5], S21, 3593408605U); /* 21 */
GG ( d, a, b, c, in[10], S22, 38016083U); /* 22 */
GG ( c, d, a, b, in[15], S23, 3634488961U); /* 23 */
GG ( b, c, d, a, in[ 4], S24, 3889429448U); /* 24 */
GG ( a, b, c, d, in[ 9], S21, 568446438U); /* 25 */
GG ( d, a, b, c, in[14], S22, 3275163606U); /* 26 */
GG ( c, d, a, b, in[ 3], S23, 4107603335U); /* 27 */
GG ( b, c, d, a, in[ 8], S24, 1163531501U); /* 28 */
GG ( a, b, c, d, in[13], S21, 2850285829U); /* 29 */
GG ( d, a, b, c, in[ 2], S22, 4243563512U); /* 30 */
GG ( c, d, a, b, in[ 7], S23, 1735328473U); /* 31 */
GG ( b, c, d, a, in[12], S24, 2368359562U); /* 32 */
/* Round 3 */
#define S31 4
#define S32 11
#define S33 16
#define S34 23
HH ( a, b, c, d, in[ 5], S31, 4294588738U); /* 33 */
HH ( d, a, b, c, in[ 8], S32, 2272392833U); /* 34 */
HH ( c, d, a, b, in[11], S33, 1839030562U); /* 35 */
HH ( b, c, d, a, in[14], S34, 4259657740U); /* 36 */
HH ( a, b, c, d, in[ 1], S31, 2763975236U); /* 37 */
HH ( d, a, b, c, in[ 4], S32, 1272893353U); /* 38 */
HH ( c, d, a, b, in[ 7], S33, 4139469664U); /* 39 */
HH ( b, c, d, a, in[10], S34, 3200236656U); /* 40 */
HH ( a, b, c, d, in[13], S31, 681279174U); /* 41 */
HH ( d, a, b, c, in[ 0], S32, 3936430074U); /* 42 */
HH ( c, d, a, b, in[ 3], S33, 3572445317U); /* 43 */
HH ( b, c, d, a, in[ 6], S34, 76029189U); /* 44 */
HH ( a, b, c, d, in[ 9], S31, 3654602809U); /* 45 */
HH ( d, a, b, c, in[12], S32, 3873151461U); /* 46 */
HH ( c, d, a, b, in[15], S33, 530742520U); /* 47 */
HH ( b, c, d, a, in[ 2], S34, 3299628645U); /* 48 */
/* Round 4 */
#define S41 6
#define S42 10
#define S43 15
#define S44 21
II ( a, b, c, d, in[ 0], S41, 4096336452U); /* 49 */
II ( d, a, b, c, in[ 7], S42, 1126891415U); /* 50 */
II ( c, d, a, b, in[14], S43, 2878612391U); /* 51 */
II ( b, c, d, a, in[ 5], S44, 4237533241U); /* 52 */
II ( a, b, c, d, in[12], S41, 1700485571U); /* 53 */
II ( d, a, b, c, in[ 3], S42, 2399980690U); /* 54 */
II ( c, d, a, b, in[10], S43, 4293915773U); /* 55 */
II ( b, c, d, a, in[ 1], S44, 2240044497U); /* 56 */
II ( a, b, c, d, in[ 8], S41, 1873313359U); /* 57 */
II ( d, a, b, c, in[15], S42, 4264355552U); /* 58 */
II ( c, d, a, b, in[ 6], S43, 2734768916U); /* 59 */
II ( b, c, d, a, in[13], S44, 1309151649U); /* 60 */
II ( a, b, c, d, in[ 4], S41, 4149444226U); /* 61 */
II ( d, a, b, c, in[11], S42, 3174756917U); /* 62 */
II ( c, d, a, b, in[ 2], S43, 718787259U); /* 63 */
II ( b, c, d, a, in[ 9], S44, 3951481745U); /* 64 */
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
/*
**********************************************************************
** End of md5.c **
******************************* (cut) ********************************
*/
#if 0
/*
**********************************************************************
** md5driver.c -- sample routines to test **
** RSA Data Security, Inc. MD5 message digest algorithm. **
** Created: 2/16/90 RLR **
** Updated: 1/91 SRD **
**********************************************************************
*/
/*
**********************************************************************
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
** **
** 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. **
**********************************************************************
*/
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
#include <string.h>
/* -- include the following file if the file md5.h is separate -- */
/* #include "md5.h" */
/* Prints message digest buffer in mdContext as 32 hexadecimal digits.
Order is from low-order byte to high-order byte of digest.
Each byte is printed with high-order hexadecimal digit first.
*/
static void MDPrint (mdContext)
MD5_CTX *mdContext;
{
int i;
for (i = 0; i < 16; i++)
printf ("%02x", mdContext->digest[i]);
}
/* size of test block */
#define TEST_BLOCK_SIZE 1000
/* number of blocks to process */
#define TEST_BLOCKS 10000
/* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */
static long TEST_BYTES = (long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS;
/* A time trial routine, to measure the speed of MD5.
Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE
characters.
*/
static void MDTimeTrial ()
{
MD5_CTX mdContext;
time_t endTime, startTime;
unsigned char data[TEST_BLOCK_SIZE];
unsigned int i;
/* initialize test data */
for (i = 0; i < TEST_BLOCK_SIZE; i++)
data[i] = (unsigned char)(i & 0xFF);
/* start timer */
printf ("MD5 time trial. Processing %ld characters...\n", TEST_BYTES);
time (&startTime);
/* digest data in TEST_BLOCK_SIZE byte blocks */
MD5Init (&mdContext);
for (i = TEST_BLOCKS; i > 0; i--)
MD5Update (&mdContext, data, TEST_BLOCK_SIZE);
MD5Final (&mdContext);
/* stop timer, get time difference */
time (&endTime);
MDPrint (&mdContext);
printf (" is digest of test input.\n");
printf
("Seconds to process test input: %ld\n", (long)(endTime-startTime));
printf
("Characters processed per second: %ld\n",
TEST_BYTES/(endTime-startTime));
}
/* Computes the message digest for string inString.
Prints out message digest, a space, the string (in quotes) and a
carriage return.
*/
static void MDString (inString)
char *inString;
{
MD5_CTX mdContext;
unsigned int len = strlen (inString);
MD5Init (&mdContext);
MD5Update (&mdContext, inString, len);
MD5Final (&mdContext);
MDPrint (&mdContext);
printf (" \"%s\"\n\n", inString);
}
/* Computes the message digest for a specified file.
Prints out message digest, a space, the file name, and a carriage
return.
*/
static void MDFile (filename)
char *filename;
{
FILE *inFile = fopen (filename, "rb");
MD5_CTX mdContext;
int bytes;
unsigned char data[1024];
if (inFile == NULL) {
printf ("%s can't be opened.\n", filename);
return;
}
MD5Init (&mdContext);
while ((bytes = fread (data, 1, 1024, inFile)) != 0)
MD5Update (&mdContext, data, bytes);
MD5Final (&mdContext);
MDPrint (&mdContext);
printf (" %s\n", filename);
fclose (inFile);
}
/* Writes the message digest of the data from stdin onto stdout,
followed by a carriage return.
*/
static void MDFilter ()
{
MD5_CTX mdContext;
int bytes;
unsigned char data[16];
MD5Init (&mdContext);
while ((bytes = fread (data, 1, 16, stdin)) != 0)
MD5Update (&mdContext, data, bytes);
MD5Final (&mdContext);
MDPrint (&mdContext);
printf ("\n");
}
/* Runs a standard suite of test data.
*/
static void MDTestSuite ()
{
printf ("MD5 test suite results:\n\n");
MDString ("");
MDString ("a");
MDString ("abc");
MDString ("message digest");
MDString ("abcdefghijklmnopqrstuvwxyz");
MDString
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
MDString
("1234567890123456789012345678901234567890\
1234567890123456789012345678901234567890");
/* Contents of file foo are "abc" */
MDFile ("foo");
}
void main (argc, argv)
int argc;
char *argv[];
{
int i;
/* For each command line argument in turn:
** filename -- prints message digest and name of file
** -sstring -- prints message digest and contents of string
** -t -- prints time trial statistics for 1M characters
** -x -- execute a standard suite of test data
** (no args) -- writes messages digest of stdin onto stdout
*/
if (argc == 1)
MDFilter ();
else
for (i = 1; i < argc; i++)
if (argv[i][0] == '-' && argv[i][1] == 's')
MDString (argv[i] + 2);
else if (strcmp (argv[i], "-t") == 0)
MDTimeTrial ();
else if (strcmp (argv[i], "-x") == 0)
MDTestSuite ();
else MDFile (argv[i]);
}
/*
**********************************************************************
** End of md5driver.c **
******************************* (cut) ********************************
*/
#endif

59
libmultihash/md5.h Normal file
View file

@ -0,0 +1,59 @@
/*
**********************************************************************
** md5.h -- Header file for implementation of MD5 **
** RSA Data Security, Inc. MD5 Message Digest Algorithm **
** Created: 2/17/90 RLR **
** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
** Revised (for MD5): RLR 4/27/91 **
** -- G modified to have y&~z instead of y&z **
** -- FF, GG, HH modified to add in last register done **
** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **
** -- distinct additive constant for each step **
** -- round 4 added, working mod 7 **
**********************************************************************
*/
/*
**********************************************************************
** Copyright (C) 1990, RSA Data Security, Inc. All rights 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. **
**********************************************************************
*/
/* typedef a 32 bit type */
typedef unsigned long int UINT4;
/* Data structure for MD5 (Message Digest) computation */
typedef struct {
UINT4 i[2]; /* number of _bits_ handled mod 2^64 */
UINT4 buf[4]; /* scratch buffer */
unsigned char in[64]; /* input buffer */
unsigned char digest[16]; /* actual digest after MD5Final call */
} MD5_CTX;
void MD5Init ();
void MD5Update ();
void MD5Final ();
/*
**********************************************************************
** End of md5.h **
******************************* (cut) ********************************
*/

130
libmultihash/multihash.c Normal file
View file

@ -0,0 +1,130 @@
/***************************************************************************
* Copyright (C) 2007 by SukkoPera *
* sukkopera@sukkology.net *
* *
* 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. *
***************************************************************************/
#include "multihash.h"
#include <stdio.h>
#define READBUF_SIZE 8192
void multihash_init (multihash *mh) {
#ifdef USE_CRC32
(mh -> crc32_s)[0] = '\0';
mh -> crc32 = 0xffffffff;
#endif
#ifdef USE_MD4
(mh -> md4_s)[0] = '\0';
md4_starts (&(mh -> md4));
#endif
#ifdef USE_MD5
(mh -> md5_s)[0] = '\0';
MD5Init (&(mh -> md5));
#endif
#ifdef USE_ED2K
(mh -> ed2k_s)[0] = '\0';
ed2khash_starts (&(mh -> ed2k));
#endif
#ifdef USE_SHA1
(mh -> sha1_s)[0] = '\0';
SHA1Init (&(mh -> sha1));
#endif
return;
}
void multihash_update (multihash *mh, unsigned char *data, int bytes) {
#ifdef USE_CRC32
mh -> crc32 = CrcUpdate (mh -> crc32, data, bytes);
#endif
#ifdef USE_MD4
// md4_update (&(mh -> md4), data, bytes);
#endif
#ifdef USE_MD5
MD5Update (&(mh -> md5), data, bytes);
#endif
#ifdef USE_ED2K
// ed2khash_update (&(mh -> ed2k), data, bytes);
#endif
#ifdef USE_SHA1
SHA1Update (&(mh -> sha1), data, bytes); /* WARNING: SHA1Update() destroys data! */
#endif
return;
}
void multihash_finish (multihash *mh) {
unsigned char buf[MAX_DIGESTSIZE];
int bytes;
#ifdef USE_CRC32
mh -> crc32 ^= 0xffffffff;
snprintf (mh -> crc32_s, LEN_CRC32 + 1, "%08x", mh -> crc32);
#endif
#ifdef USE_MD4
md4_finish (&(mh -> md4), buf);
for (bytes = 0; bytes < LEN_MD4 / 2; bytes++)
sprintf (mh -> md4_s, "%s%02x", mh -> md4_s, buf[bytes]);
(mh -> md4_s)[LEN_MD4] = '\0';
#endif
#ifdef USE_MD5
MD5Final (&(mh -> md5));
for (bytes = 0; bytes < LEN_MD5 / 2; bytes++)
sprintf (mh -> md5_s, "%s%02x", mh -> md5_s, (mh -> md5).digest[bytes]);
(mh -> md5_s)[LEN_MD5] = '\0';
#endif
#ifdef USE_ED2K
ed2khash_finish (&(mh -> ed2k), buf);
for (bytes = 0; bytes < LEN_ED2K / 2; bytes++)
sprintf (mh -> ed2k_s, "%s%02x", mh -> ed2k_s, buf[bytes]);
(mh -> ed2k_s)[LEN_ED2K] = '\0';
#endif
#ifdef USE_SHA1
SHA1Final (buf, &(mh -> sha1));
for (bytes = 0; bytes < LEN_SHA1 / 2; bytes++)
sprintf (mh -> sha1_s, "%s%02x", mh -> sha1_s, buf[bytes]);
(mh -> sha1_s)[LEN_SHA1] = '\0';
#endif
return;
}
int multihash_file (multihash *mh, char *filename) {
FILE *fp;
int bytes, out;
unsigned char data[READBUF_SIZE];
multihash_init (mh);
if ((fp = fopen (filename, "r"))) {
while ((bytes = fread (data, 1, READBUF_SIZE, fp)) != 0)
multihash_update (mh, data, bytes);
multihash_finish (mh);
fclose (fp);
out = 0;
} else {
/* Cannot open file */
out = -1;
}
return (out);
}

127
libmultihash/multihash.h Normal file
View file

@ -0,0 +1,127 @@
/***************************************************************************
* Copyright (C) 2007 by SukkoPera *
* sukkopera@sukkology.net *
* *
* 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. *
***************************************************************************/
#ifndef MULTIHASH_H_INCLUDED
#define MULTIHASH_H_INCLUDED
#ifdef WIN32
#include <windows.h>
/* Definition of the types we use for Windows */
#define u_int8_t BYTE
#define u_int16_t WORD
#define u_int32_t DWORD
/* Some functions have different names */
#define snprintf _snprintf
/* Stuff to export library symbols */
#ifdef MULTIHASH_BUILD_DLL
#ifdef MULTIHASH_EXPORTS
#define MULTIHASH_EXPORT __declspec(dllexport) /* Building the lib */
#else
#define MULTIHASH_EXPORT __declspec(dllimport) /* Building user code */
#endif
#else
#define MULTIHASH_EXPORT
#endif
#else /* !WIN32 */
#define MULTIHASH_EXPORT
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define USE_CRC32
#define USE_MD4
#define USE_MD5
#define USE_ED2K
#define USE_SHA1
#ifdef USE_CRC32
#include <sys/types.h>
#include "crc32.h"
#define LEN_CRC32 8
#endif
#ifdef USE_MD4
#include "md4.h"
#define LEN_MD4 32
#define MD4_DIGESTSIZE 16
#endif
#ifdef USE_MD5
#include "md5.h"
#define LEN_MD5 32
#endif
#ifdef USE_ED2K
#include "edonkey.h"
#define LEN_ED2K 32
#endif
#ifdef USE_SHA1
#include "sha1.h"
#define LEN_SHA1 40
#endif
/* This must be as long as the longest hash (in bytes) */
#define MAX_DIGESTSIZE 20
typedef struct {
#ifdef USE_CRC32
u_int32_t crc32;
char crc32_s[LEN_CRC32 + 1];
#endif
#ifdef USE_MD4
md4_context md4;
char md4_s[LEN_MD4 + 1];
#endif
#ifdef USE_MD5
MD5_CTX md5;
char md5_s[LEN_MD5 + 1];
#endif
#ifdef USE_ED2K
ed2khash_context ed2k;
char ed2k_s[LEN_ED2K + 1];
#endif
#ifdef USE_SHA1
SHA1_CTX sha1;
char sha1_s[LEN_SHA1 + 1];
#endif
} multihash;
/* Prototypes */
MULTIHASH_EXPORT void multihash_init (multihash *mh);
MULTIHASH_EXPORT void multihash_update (multihash *mh, unsigned char *data, int bytes);
MULTIHASH_EXPORT void multihash_finish (multihash *mh);
MULTIHASH_EXPORT int multihash_file (multihash *mh, char *filename);
#ifdef __cplusplus
}
#endif
#endif

231
libmultihash/sha1.c Normal file
View file

@ -0,0 +1,231 @@
/*
** sha1.c
**
** Contains all of the SHA1 functions: SHA1Transform, SHA1Init, SHA1Update, and SHA1Final.
** Make sure to define _LITTLE_ENDIAN if running on a little endian machine and NOT to
** define it otherwise.
**
** Copyright NTT MCL, 2000.
**
** Satomi Okazaki
** Security Group, NTT MCL
** November 1999
**
**************************
** 13 December 1999. In SHA1Transform, changed "buffer" to be const.
** In SHA1Update, changed "data to be const. -- S.O.
*/
#include "sha1.h"
#define _LITTLE_ENDIAN /* should be defined if so */
/* Rotation of "value" by "bits" to the left */
#define rotLeft(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* Basic SHA1 functions */
#define f(u,v,w) (((u) & (v)) | ((~u) & (w)))
#define g(u,v,w) (((u) & (v)) | ((u) & (w)) | ((v) & (w)))
#define h(u,v,w) ((u) ^ (v) ^ (w))
/* These are the 16 4-byte words of the 64-byte block */
#ifdef _LITTLE_ENDIAN
/* Reverse the order of the bytes in the i-th 4-byte word */
#define x(i) (block->l[i] = (rotLeft(block->l[i], 24)& 0xff00ff00) \
| (rotLeft(block->l[i], 8) & 0x00ff00ff))
#else
#define x(i) (block->l[i])
#endif
/* Used in expanding from a 16 word block into an 80 word block */
#define X(i) (block->l[(i)%16] = rotLeft (block->l[((i)-3)%16] ^ block->l[((i)-8)%16] \
^ block->l[((i)-14)%16] ^ block->l[((i)-16)%16],1))
/* (R0+R1), R2, R3, R4 are the different round operations used in SHA1 */
#define R0(a, b, c, d, e, i) { \
(e) += f((b), (c), (d)) + (x(i)) + 0x5A827999 + rotLeft((a),5); \
(b) = rotLeft((b), 30); \
}
#define R1(a, b, c, d, e, i) { \
(e) += f((b), (c), (d)) + (X(i)) + 0x5A827999 + rotLeft((a),5); \
(b) = rotLeft((b), 30); \
}
#define R2(a, b, c, d, e, i) { \
(e) += h((b), (c), (d)) + (X(i)) + 0x6ED9EBA1 + rotLeft((a),5); \
(b) = rotLeft((b), 30); \
}
#define R3(a, b, c, d, e, i) { \
(e) += g((b), (c), (d)) + (X(i)) + 0x8F1BBCDC + rotLeft((a),5); \
(b) = rotLeft((b), 30); \
}
#define R4(a, b, c, d, e, i) { \
(e) += h((b), (c), (d)) + (X(i)) + 0xCA62C1D6 + rotLeft((a),5); \
(b) = rotLeft((b), 30); \
}
/* Hashes a single 512-bit block. This is the compression function - the core of the algorithm.
**/
void SHA1Transform(
unsigned long state[5],
const unsigned char buffer[SHA1_BLOCKSIZE]
)
{
unsigned long a, b, c, d, e;
typedef union {
unsigned char c[64];
unsigned long l[16];
} CHAR64LONG16;
/* This is for the X array */
CHAR64LONG16* block = (CHAR64LONG16*)buffer;
/* Initialize working variables */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. */
/* Round 1 */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e, 10); R0(e,a,b,c,d, 11);
R0(d,e,a,b,c, 12); R0(c,d,e,a,b, 13); R0(b,c,d,e,a, 14); R0(a,b,c,d,e, 15);
R1(e,a,b,c,d, 16); R1(d,e,a,b,c, 17); R1(c,d,e,a,b, 18); R1(b,c,d,e,a, 19);
/* Round 2 */
R2(a,b,c,d,e, 20); R2(e,a,b,c,d, 21); R2(d,e,a,b,c, 22); R2(c,d,e,a,b, 23);
R2(b,c,d,e,a, 24); R2(a,b,c,d,e, 25); R2(e,a,b,c,d, 26); R2(d,e,a,b,c, 27);
R2(c,d,e,a,b, 28); R2(b,c,d,e,a, 29); R2(a,b,c,d,e, 30); R2(e,a,b,c,d, 31);
R2(d,e,a,b,c, 32); R2(c,d,e,a,b, 33); R2(b,c,d,e,a, 34); R2(a,b,c,d,e, 35);
R2(e,a,b,c,d, 36); R2(d,e,a,b,c, 37); R2(c,d,e,a,b, 38); R2(b,c,d,e,a, 39);
/* Round 3 */
R3(a,b,c,d,e, 40); R3(e,a,b,c,d, 41); R3(d,e,a,b,c, 42); R3(c,d,e,a,b, 43);
R3(b,c,d,e,a, 44); R3(a,b,c,d,e, 45); R3(e,a,b,c,d, 46); R3(d,e,a,b,c, 47);
R3(c,d,e,a,b, 48); R3(b,c,d,e,a, 49); R3(a,b,c,d,e, 50); R3(e,a,b,c,d, 51);
R3(d,e,a,b,c, 52); R3(c,d,e,a,b, 53); R3(b,c,d,e,a, 54); R3(a,b,c,d,e, 55);
R3(e,a,b,c,d, 56); R3(d,e,a,b,c, 57); R3(c,d,e,a,b, 58); R3(b,c,d,e,a, 59);
/* Round 4 */
R4(a,b,c,d,e, 60); R4(e,a,b,c,d, 61); R4(d,e,a,b,c, 62); R4(c,d,e,a,b, 63);
R4(b,c,d,e,a, 64); R4(a,b,c,d,e, 65); R4(e,a,b,c,d, 66); R4(d,e,a,b,c, 67);
R4(c,d,e,a,b, 68); R4(b,c,d,e,a, 69); R4(a,b,c,d,e, 70); R4(e,a,b,c,d, 71);
R4(d,e,a,b,c, 72); R4(c,d,e,a,b, 73); R4(b,c,d,e,a, 74); R4(a,b,c,d,e, 75);
R4(e,a,b,c,d, 76); R4(d,e,a,b,c, 77); R4(c,d,e,a,b, 78); R4(b,c,d,e,a, 79);
/* Update the chaining values */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
}
/* SHA1Init - Initialize new context.
**/
void SHA1Init(
SHA1_CTX* context
)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
/* Run your data through this. This will call the compression function SHA1Transform for each
** 64-byte block of data.
**/
void SHA1Update(
SHA1_CTX* context,
const unsigned char* data,
unsigned long dataLen
)
{
unsigned long numByteDataProcessed; /* Number of bytes processed so far */
unsigned long numByteInBuffMod64; /* Number of bytes in the buffer mod 64 */
numByteInBuffMod64 = (context->count[0] >> 3) % 64;
/* Adding in the number of bits of data */
if ((context->count[0] += dataLen << 3) < (dataLen << 3)) {
context->count[1]++; /* add in the carry bit */
}
context->count[1] += (dataLen >> 29);
/* If there is at least one block to be processed... */
if ((numByteInBuffMod64 + dataLen) > 63) {
/* Copy over 64-numByteInBuffMod64 bytes of data to the end of buffer */
memcpy(&context->buffer[numByteInBuffMod64], data,
(numByteDataProcessed = 64 - numByteInBuffMod64));
/* Perform the transform on the buffer */
SHA1Transform(context->state, context->buffer);
/* As long as there are 64-bit blocks of data remaining, transform each one. */
for ( ; numByteDataProcessed + 63 < dataLen; numByteDataProcessed += 64) {
SHA1Transform(context->state, &data[numByteDataProcessed]);
}
numByteInBuffMod64 = 0;
}
/* Else there is not enough to process one block. */
else
numByteDataProcessed = 0;
/* Copy over the remaining data into the buffer */
memcpy(&context->buffer[numByteInBuffMod64], &data[numByteDataProcessed],
dataLen - numByteDataProcessed);
}
/* Add padding and return the message digest.
**/
void SHA1Final(
unsigned char digest[SHA1_DIGESTSIZE],
SHA1_CTX* context
)
{
unsigned long i, j;
unsigned char numBits[8];
/* Record the number of bits */
for (i = 1, j = 0; j < 8; i--, j += 4) {
numBits[j] = (unsigned char)((context->count[i] >> 24) & 0xff);
numBits[j+1] = (unsigned char)((context->count[i] >> 16) & 0xff);
numBits[j+2] = (unsigned char)((context->count[i] >> 8) & 0xff);
numBits[j+3] = (unsigned char)(context->count[i] & 0xff);
}
/* Add padding */
SHA1Update(context, (unsigned char *)"\200", 1);
while ((context->count[0] & 504) != 448)
SHA1Update(context, (unsigned char *)"\0", 1);
/* Append length */
SHA1Update(context, numBits, 8); /* Should cause a SHA1Transform() */
/* Store state in digest */
for (i = 0, j = 0; j < 20; i++, j += 4) {
digest[j] = (unsigned char)((context->state[i] >> 24) & 0xff);
digest[j+1] = (unsigned char)((context->state[i] >> 16) & 0xff);
digest[j+2] = (unsigned char)((context->state[i] >> 8) & 0xff);
digest[j+3] = (unsigned char)((context->state[i]) & 0xff);
}
/* Wipe variables */
i = 0;
j = 0;
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
memset(&numBits, 0, 8);
}

39
libmultihash/sha1.h Normal file
View file

@ -0,0 +1,39 @@
/*
** sha1.h
**
** Copyright NTT MCL, 2000.
**
** Satomi Okazaki
** Security Group, NTT MCL
** November 1999
**
**************************
** 13 December 1999. In SHA1Transform, changed "buffer" to be const.
** In SHA1Update, changed "data to be const. -- S.O.
*/
#ifndef __SHA1_H__
#define __SHA1_H__
#include <stdio.h>
#include <string.h>
#ifndef SHA1_DIGESTSIZE
#define SHA1_DIGESTSIZE 20
#endif
#ifndef SHA1_BLOCKSIZE
#define SHA1_BLOCKSIZE 64
#endif
typedef struct {
unsigned long state[5];
unsigned long count[2]; /* stores the number of bits */
unsigned char buffer[SHA1_BLOCKSIZE];
} SHA1_CTX;
void SHA1Transform(unsigned long state[5], const unsigned char buffer[SHA1_BLOCKSIZE]);
void SHA1Init(SHA1_CTX *context);
void SHA1Update(SHA1_CTX *context, const unsigned char *data, unsigned long len);
void SHA1Final(unsigned char digest[SHA1_DIGESTSIZE], SHA1_CTX *context);
#endif /* __SHA1_H__ */