83 lines
3 KiB
C
83 lines
3 KiB
C
/***************************************************************************
|
|
* 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;
|
|
}
|