]> FriiDump Source - friidump.git/blob - libmultihash/edonkey.c
FriiDump 0.5.3.16: finalize release identity and documentation
[friidump.git] / libmultihash / edonkey.c
1 /***************************************************************************
2  *   Copyright (C) 2007 by SukkoPera   *
3  *   sukkopera@sukkology.net   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 /* As Wikipedia (http://en.wikipedia.org/wiki/Ed2k_link) says:
22  * The ed2k hash function is a MD4 root hash of a MD4 hash list, and gives a
23  * different result than simply MD4: The file data is divided into full
24  * chunks of 9728000 bytes plus a remainder chunk, and a separate 128-bit
25  * MD4 checksum is computed for each. The ed2k hash is computed by
26  * concatenating the chunks' MD4 checksums in order and hashing the result
27  *using MD4.
28  */
29
30 #include <stdio.h>
31 #include "edonkey.h"
32 #include "md4.h"
33
34 void ed2khash_starts (ed2khash_context *ctx) {
35         md4_starts (&(ctx -> md4cur));
36         md4_starts (&(ctx -> md4final));
37         ctx -> bytes_processed = 0;
38         ctx -> chunks = 0;
39
40         return;
41 }
42
43
44 void ed2khash_update (ed2khash_context *ctx, unsigned char *input, int ilen) {
45         unsigned long x;
46         
47         while (ilen > 0) {
48                 if (ctx -> bytes_processed + ilen >= ED2KHASH_CHUNKSIZE)
49                         x = ED2KHASH_CHUNKSIZE - ctx -> bytes_processed;
50                 else
51                         x = ilen;
52                 
53                 md4_update (&(ctx -> md4cur), input, x);
54
55                 if ((ctx -> bytes_processed += x) % ED2KHASH_CHUNKSIZE == 0) {
56                         /* End of a chunk, save current MD4 and start a new one */
57                         md4_finish (&(ctx -> md4cur), ctx -> lastmd4);
58                         md4_starts (&(ctx -> md4cur));
59                         ctx -> bytes_processed = 0;
60                         ctx -> chunks++;
61
62                         md4_update (&(ctx -> md4final), ctx -> lastmd4, MD4_DIGESTSIZE);
63                 }
64                 ilen -= x;
65                 input += x;
66         }
67
68         return;
69 }
70
71
72 void ed2khash_finish (ed2khash_context *ctx, unsigned char *output) {
73         if (ctx -> chunks > 0) {
74                 md4_finish (&(ctx -> md4cur), ctx -> lastmd4);
75                 md4_update (&(ctx -> md4final), ctx -> lastmd4, MD4_DIGESTSIZE);
76                 md4_finish (&(ctx -> md4final), output);
77         } else {
78                 /* If we have a single chunk, use its MD4 straight away */
79                 md4_finish (&(ctx -> md4cur), output);
80         }
81
82         return;
83 }