From clauflibitFriiDump-0.5.3.1
This commit is contained in:
parent
fe937e7f4b
commit
87b108d6a1
63 changed files with 11067 additions and 26 deletions
77
libmultihash/CMakeLists.txt
Normal file
77
libmultihash/CMakeLists.txt
Normal 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
120
libmultihash/crc32.c
Normal 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
53
libmultihash/crc32.h
Normal 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
83
libmultihash/edonkey.c
Normal 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
36
libmultihash/edonkey.h
Normal 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
441
libmultihash/md4.c
Normal 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
121
libmultihash/md4.h
Normal 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
477
libmultihash/md5.c
Normal 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
59
libmultihash/md5.h
Normal 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
130
libmultihash/multihash.c
Normal 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
127
libmultihash/multihash.h
Normal 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
231
libmultihash/sha1.c
Normal 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
39
libmultihash/sha1.h
Normal 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__ */
|
Loading…
Add table
Add a link
Reference in a new issue