OpenCores
URL https://opencores.org/ocsvn/bluespec_md6/bluespec_md6/trunk

Subversion Repositories bluespec_md6

[/] [bluespec_md6/] [trunk/] [C_implementation/] [md6_mode.c] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kfleming
/* File:    md6_mode.c
2
** Author:  Ronald L. Rivest
3
** Address: Room 32G-692 Stata Center
4
**          32 Vassar Street
5
**          Cambridge, MA 02139
6
** Email:   rivest@mit.edu
7
** Date:    9/25/2008
8
**
9
** (The following license is known as "The MIT License")
10
**
11
** Copyright (c) 2008 Ronald L. Rivest
12
**
13
** Permission is hereby granted, free of charge, to any person obtaining a copy
14
** of this software and associated documentation files (the "Software"), to deal
15
** in the Software without restriction, including without limitation the rights
16
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
** copies of the Software, and to permit persons to whom the Software is
18
** furnished to do so, subject to the following conditions:
19
**
20
** The above copyright notice and this permission notice shall be included in
21
** all copies or substantial portions of the Software.
22
**
23
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29
** THE SOFTWARE.
30
**
31
** (end of license)
32
**
33
** This is part of the definition of the MD6 hash function.
34
** The files defining the md6 hash function are:
35
**    md6.h
36
**    md6_compress.c
37
**    md6_mode.c
38
**
39
** The files defining the interface between MD6 and the NIST SHA-3
40
** API are:
41
**    md6_nist.h
42
**    md6_nist.c
43
** The NIST SHA-3 API is defined in:
44
**    http://www.csrc.nist.gov/groups/ST/hash/documents/SHA3-C-API.pdf
45
**
46
** See  http://groups.csail.mit.edu/cis/md6  for more information.
47
*/
48
/* MD6 standard mode of operation
49
**
50
** Defines the following interfaces (documentation copied from md6.h)
51
*/
52
#if 0
53
 
54
/* The next routines are used according to the pattern:
55
**    md6_init        (or md6_full_init if you use additional parameters)
56
**    md6_update         (once for each portion of the data to be hashed)
57
**    md6_final                           (to finish up hash computation)
58
** Note: md6_final can return the hash value to a desired location, but
59
** hash value also remains available inside the md6_state, in both binary
60
** and hex formats (state->hashval and state->hexhashval).
61
*/
62
 
63
extern int md6_init( md6_state *st,             /* state to initialize */
64
                     int d                          /* hash bit length */
65
                     );
66
 
67
extern int md6_full_init( md6_state *st,        /* state to initialize */
68
                          int d,                    /* hash bit length */
69
                          unsigned char *key,       /* OK to give NULL */
70
                          int keylen,       /* (in bytes) OK to give 0 */
71
                          int L,     /* mode; OK to give md6_default_L */
72
                          int r                    /* number of rounds */
73
                          );
74
 
75
extern int md6_update( md6_state *st,             /* initialized state */
76
                       unsigned char *data,            /* data portion */
77
                       uint64_t datalen          /* its length in bits */
78
                       );
79
 
80
extern int md6_final( md6_state *st,            /* initialized/updated */
81
                      unsigned char *hashval,      /* output; NULL OK  */
82
                      );
83
 
84
/* The next routines compute a hash for a message given all at once.
85
** The resulting hash value is returned to a specified location.
86
** Only one call is needed.  Use md6_hash for the standard md6 hash,
87
** and md6_full_hash if you want to specify additional parameters.
88
*/
89
 
90
extern int md6_hash( int d,                         /* hash bit length */
91
                     unsigned char *data,     /* complete data to hash */
92
                     uint64_t datalen            /* its length in bits */
93
                     unsigned char *hashval,                 /* output */
94
                     );
95
 
96
extern int md6_full_hash( int d,                    /* hash bit length */
97
                          unsigned char *data,/* complete data to hash */
98
                          uint64_t datalen,      /* its length in bits */
99
                          unsigned char *key,       /* OK to give NULL */
100
                          int keylen,       /* (in bytes) OK to give 0 */
101
                          int L,     /* mode; OK to give md6_default_L */
102
                          int r,                   /* number of rounds */
103
                          unsigned char *hashval,            /* output */
104
                          );
105
#endif
106
 
107
#include <assert.h>
108
#include <stdio.h> 
109
#include <string.h>
110
 
111
#include "md6.h"
112
 
113
/* MD6 constants independent of mode of operation (from md6.h) */
114
#define w md6_w     /* # bits in a word                   (64) */
115
#define n md6_n     /* # words in compression input       (89) */
116
#define c md6_c     /* # words in compression output      (16) */
117
 
118
/* MD6 constants needed for mode of operation                  */
119
#define q md6_q     /* # words in Q                       (15) */
120
#define k md6_k     /* # words in key (aka salt)          (8)  */
121
#define u md6_u     /* # words in unique node ID          (1)  */
122
#define v md6_v     /* # words in control word            (1)  */
123
#define b md6_b     /* # data words per compression block (64) */
124
 
125
/* Useful macros: min and max */
126
#ifndef min
127
#define min(a,b) ((a)<(b)? (a) : (b))
128
#endif
129
#ifndef max
130
#define max(a,b) ((a)>(b)? (a) : (b))
131
#endif
132
 
133
/* Default number of rounds (as a function of digest size d)   */
134
int md6_default_r( int d )
135
{
136
  /* Default number of rounds is forty plus floor(d/4) */
137
  return 40 + (d/4);
138
}
139
 
140
 
141
/* MD6 Constant Vector Q
142
** Q = initial 960 bits of fractional part of sqrt(6)
143
**
144
** Given here for w = 64, 32, 16, and 8, although only
145
** w = 64 is needed for the standard version of MD6.
146
*/
147
 
148
#if (w==64)                      /* for standard version */
149
/* 15 64-bit words */
150
static const md6_word Q[15] =
151
  {
152
    0x7311c2812425cfa0ULL,
153
    0x6432286434aac8e7ULL,
154
    0xb60450e9ef68b7c1ULL,
155
    0xe8fb23908d9f06f1ULL,
156
    0xdd2e76cba691e5bfULL,
157
    0x0cd0d63b2c30bc41ULL,
158
    0x1f8ccf6823058f8aULL,
159
    0x54e5ed5b88e3775dULL,
160
    0x4ad12aae0a6d6031ULL,
161
    0x3e7f16bb88222e0dULL,
162
    0x8af8671d3fb50c2cULL,
163
    0x995ad1178bd25c31ULL,
164
    0xc878c1dd04c4b633ULL,
165
    0x3b72066c7a1552acULL,
166
    0x0d6f3522631effcbULL,
167
  };
168
#endif
169
 
170
#if (w==32)                      /* for variant version */
171
/* 30 32-bit words */
172
static const md6_word Q[30] =
173
  {
174
    0x7311c281UL, 0x2425cfa0UL,
175
    0x64322864UL, 0x34aac8e7UL,
176
    0xb60450e9UL, 0xef68b7c1UL,
177
    0xe8fb2390UL, 0x8d9f06f1UL,
178
    0xdd2e76cbUL, 0xa691e5bfUL,
179
    0x0cd0d63bUL, 0x2c30bc41UL,
180
    0x1f8ccf68UL, 0x23058f8aUL,
181
    0x54e5ed5bUL, 0x88e3775dUL,
182
    0x4ad12aaeUL, 0x0a6d6031UL,
183
    0x3e7f16bbUL, 0x88222e0dUL,
184
    0x8af8671dUL, 0x3fb50c2cUL,
185
    0x995ad117UL, 0x8bd25c31UL,
186
    0xc878c1ddUL, 0x04c4b633UL,
187
    0x3b72066cUL, 0x7a1552acUL,
188
    0x0d6f3522UL, 0x631effcbUL,
189
  };
190
#endif
191
 
192
/* MD6 Constant Vector Q (continued).
193
*/
194
 
195
#if (w==16)                      /* for variant version */
196
/* 60 16-bit words */
197
static const md6_word Q[60] =
198
  {
199
    0x7311, 0xc281, 0x2425, 0xcfa0,
200
    0x6432, 0x2864, 0x34aa, 0xc8e7,
201
    0xb604, 0x50e9, 0xef68, 0xb7c1,
202
    0xe8fb, 0x2390, 0x8d9f, 0x06f1,
203
    0xdd2e, 0x76cb, 0xa691, 0xe5bf,
204
    0x0cd0, 0xd63b, 0x2c30, 0xbc41,
205
    0x1f8c, 0xcf68, 0x2305, 0x8f8a,
206
    0x54e5, 0xed5b, 0x88e3, 0x775d,
207
    0x4ad1, 0x2aae, 0x0a6d, 0x6031,
208
    0x3e7f, 0x16bb, 0x8822, 0x2e0d,
209
    0x8af8, 0x671d, 0x3fb5, 0x0c2c,
210
    0x995a, 0xd117, 0x8bd2, 0x5c31,
211
    0xc878, 0xc1dd, 0x04c4, 0xb633,
212
    0x3b72, 0x066c, 0x7a15, 0x52ac,
213
    0x0d6f, 0x3522, 0x631e, 0xffcb,
214
  };
215
#endif
216
 
217
#if (w==8)                      /* for variant version */
218
/* 120 8-bit words */
219
static const md6_word Q[120] =
220
  {
221
    0x73, 0x11, 0xc2, 0x81, 0x24, 0x25, 0xcf, 0xa0,
222
    0x64, 0x32, 0x28, 0x64, 0x34, 0xaa, 0xc8, 0xe7,
223
    0xb6, 0x04, 0x50, 0xe9, 0xef, 0x68, 0xb7, 0xc1,
224
    0xe8, 0xfb, 0x23, 0x90, 0x8d, 0x9f, 0x06, 0xf1,
225
    0xdd, 0x2e, 0x76, 0xcb, 0xa6, 0x91, 0xe5, 0xbf,
226
    0x0c, 0xd0, 0xd6, 0x3b, 0x2c, 0x30, 0xbc, 0x41,
227
    0x1f, 0x8c, 0xcf, 0x68, 0x23, 0x05, 0x8f, 0x8a,
228
    0x54, 0xe5, 0xed, 0x5b, 0x88, 0xe3, 0x77, 0x5d,
229
    0x4a, 0xd1, 0x2a, 0xae, 0x0a, 0x6d, 0x60, 0x31,
230
    0x3e, 0x7f, 0x16, 0xbb, 0x88, 0x22, 0x2e, 0x0d,
231
    0x8a, 0xf8, 0x67, 0x1d, 0x3f, 0xb5, 0x0c, 0x2c,
232
    0x99, 0x5a, 0xd1, 0x17, 0x8b, 0xd2, 0x5c, 0x31,
233
    0xc8, 0x78, 0xc1, 0xdd, 0x04, 0xc4, 0xb6, 0x33,
234
    0x3b, 0x72, 0x06, 0x6c, 0x7a, 0x15, 0x52, 0xac,
235
    0x0d, 0x6f, 0x35, 0x22, 0x63, 0x1e, 0xff, 0xcb,
236
  };
237
#endif
238
 
239
/* Endianness.
240
*/
241
 
242
/* routines for dealing with byte ordering */
243
 
244
int md6_byte_order = 0;
245
/* md6_byte_order describes the endianness of the
246
** underlying machine:
247
** 0 = unknown
248
** 1 = little-endian
249
** 2 = big-endian
250
*/
251
 
252
/* Macros to detect machine byte order; these
253
** presume that md6_byte_order has been setup by
254
** md6_detect_byte_order()
255
*/
256
#define MD6_LITTLE_ENDIAN (md6_byte_order == 1)
257
#define MD6_BIG_ENDIAN    (md6_byte_order == 2)
258
 
259
void md6_detect_byte_order( void )
260
/* determine if underlying machine is little-endian or big-endian
261
** set global variable md6_byte_order to reflect result
262
** Written to work for any w.
263
*/
264
{ md6_word x = 1 | (((md6_word)2)<<(w-8));
265
  unsigned char *cp = (unsigned char *)&x;
266
  if ( *cp == 1 )        md6_byte_order = 1;      /* little-endian */
267
  else if ( *cp == 2 )   md6_byte_order = 2;      /* big-endian    */
268
  else                   md6_byte_order = 0;      /* unknown       */
269
}
270
 
271
md6_word md6_byte_reverse( md6_word x )
272
/* return byte-reversal of md6_word x.
273
** Written to work for any w, w=8,16,32,64.
274
*/
275
{
276
#define mask8  ((md6_word)0x00ff00ff00ff00ffULL)
277
#define mask16 ((md6_word)0x0000ffff0000ffffULL)
278
#if (w==64)
279
  x = (x << 32) | (x >> 32);
280
#endif
281
#if (w >= 32)
282
  x = ((x & mask16) << 16) | ((x & ~mask16) >> 16);
283
#endif
284
#if (w >= 16)
285
  x = ((x & mask8) << 8) | ((x & ~mask8) >> 8);
286
#endif
287
  return x;
288
}
289
 
290
void md6_reverse_little_endian( md6_word *x, int count )
291
/* Byte-reverse words x[0...count-1] if machine is little_endian */
292
{
293
  int i;
294
  if (MD6_LITTLE_ENDIAN)
295
    for (i=0;i<count;i++)
296
      x[i] = md6_byte_reverse(x[i]);
297
}
298
 
299
/* Appending one bit string onto another.
300
*/
301
 
302
void append_bits( unsigned char *dest, unsigned int destlen,
303
                  unsigned char *src,  unsigned int srclen )
304
/* Append bit string src to the end of bit string dest
305
** Input:
306
**     dest         a bit string of destlen bits, starting in dest[0]
307
**                  if destlen is not a multiple of 8, the high-order
308
**                  bits are used first
309
**     src          a bit string of srclen bits, starting in src[0]
310
**                  if srclen is not a multiple of 8, the high-order
311
**                  bits are used first
312
** Modifies:
313
**     dest         when append_bits returns, dest will be modified to
314
**                  be a bit-string of length (destlen+srclen).
315
**                  zeros will fill any unused bit positions in the
316
**                  last byte.
317
*/
318
{ int i, di, accumlen;
319
  uint16_t accum;
320
  int srcbytes;
321
 
322
  if (srclen == 0) return;
323
 
324
  /* Initialize accum, accumlen, and di */
325
  accum = 0;    /* accumulates bits waiting to be moved, right-justified */
326
  accumlen = 0; /* number of bits in accumulator */
327
  if (destlen%8 != 0)
328
    { accumlen = destlen%8;
329
      accum = dest[destlen/8];        /* grab partial byte from dest     */
330
      accum = accum >> (8-accumlen);  /* right-justify it in accumulator */
331
    }
332
  di = destlen/8;        /* index of where next byte will go within dest */
333
 
334
  /* Now process each byte of src */
335
  srcbytes = (srclen+7)/8;   /* number of bytes (full or partial) in src */
336
  for (i=0;i<srcbytes;i++)
337
    { /* shift good bits from src[i] into accum */
338
      if (i != srcbytes-1) /* not last byte */
339
        { accum = (accum << 8) ^ src[i];
340
          accumlen += 8;
341
        }
342
      else /* last byte */
343
        { int newbits = ((srclen%8 == 0) ? 8 : (srclen%8));
344
          accum = (accum << newbits) | (src[i] >> (8-newbits));
345
          accumlen += newbits;
346
        }
347
      /* do as many high-order bits of accum as you can (or need to) */
348
      while ( ( (i != srcbytes-1) & (accumlen >= 8) ) ||
349
              ( (i == srcbytes-1) & (accumlen > 0) ) )
350
        { int numbits = min(8,accumlen);
351
          unsigned char bits;
352
          bits = accum >> (accumlen - numbits);    /* right justified */
353
          bits = bits << (8-numbits);              /* left justified  */
354
          bits &= (0xff00 >> numbits);             /* mask            */
355
          dest[di++] = bits;                       /* save            */
356
          accumlen -= numbits;
357
        }
358
    }
359
}
360
 
361
/* State initialization. (md6_full_init, with all parameters specified)
362
**
363
*/
364
 
365
int md6_full_init( md6_state *st,       /* uninitialized state to use */
366
                   int d,                          /* hash bit length */
367
                   unsigned char *key,        /* key; OK to give NULL */
368
                   int keylen,     /* keylength (bytes); OK to give 0 */
369
                   int L,           /* mode; OK to give md6_default_L */
370
                   int r                          /* number of rounds */
371
                   )
372
/* Initialize md6_state
373
** Input:
374
**     st         md6_state to be initialized
375
**     d          desired hash bit length 1 <= d <= w*(c/2)    (<=512 bits)
376
**     key        key (aka salt) for this hash computation     (byte array)
377
**                defaults to all-zero key if key==NULL or keylen==0
378
**     keylen     length of key in bytes; 0 <= keylen <= (k*8) (<=64 bytes)
379
**     L          md6 mode parameter; 0 <= L <= 255
380
**                md6.h defines md6_default_L for when you want default
381
**     r          number of rounds; 0 <= r <= 255
382
** Output:
383
**     updates components of state
384
**     returns one of the following:
385
**       MD6_SUCCESS
386
**       MD6_NULLSTATE
387
**       MD6_BADKEYLEN
388
**       MD6_BADHASHLEN
389
*/
390
{ /* check that md6_full_init input parameters make some sense */
391
  if (st == NULL) return MD6_NULLSTATE;
392
  if ( (key != NULL) && ((keylen < 0) || (keylen > k*(w/8))) )
393
    return MD6_BADKEYLEN;
394
  if ( d < 1 || d > 512 || d > w*c/2 ) return MD6_BADHASHLEN;
395
 
396
  md6_detect_byte_order();
397
  memset(st,0,sizeof(md6_state));  /* clear state to zero */
398
  st->d = d;                       /* save hashbitlen */
399
  if (key != NULL && keylen > 0)   /* if no key given, use memset zeros*/
400
    { memcpy(st->K,key,keylen);    /* else save key (with zeros added) */
401
      st->keylen = keylen;
402
      /* handle endian-ness */       /* first byte went into high end */
403
      md6_reverse_little_endian(st->K,k);
404
    }
405
  else
406
    st->keylen = 0;
407
  if ( (L<0) | (L>255) ) return MD6_BAD_L;
408
  st->L = L;
409
  if ( (r<0) | (r>255) ) return MD6_BAD_r;
410
  st->r = r;
411
  st->initialized = 1;
412
  st->top = 1;
413
  /* if SEQ mode for level 1; use IV=0  */
414
  /* zero bits already there by memset; */
415
  /* we just need to set st->bits[1]    */
416
  if (L==0) st->bits[1] = c*w;
417
  compression_hook = NULL;     /* just to be sure default is "not set" */
418
  return MD6_SUCCESS;
419
}
420
 
421
/* State initialization. (md6_init, which defaults most parameters.)
422
**
423
*/
424
 
425
int md6_init( md6_state *st,
426
              int d
427
              )
428
/* Same as md6_full_init, but with default key, L, and r */
429
{ return md6_full_init(st,
430
                       d,
431
                       NULL,
432
                       0,
433
                       md6_default_L,
434
                       md6_default_r(d)
435
                       );
436
}
437
 
438
/* Data structure notes.
439
*/
440
 
441
/*
442
Here are some notes on the data structures used (inside state).
443
 
444
* The variable B[] is a stack of length-b (b-64) word records,
445
  each corresponding to a node in the tree.  B[ell] corresponds
446
  to a node at level ell.  Specifically, it represents the record which,
447
  when compressed, will yield the value at that level. (It only
448
  contains the data payload, not the auxiliary information.)
449
  Note that B[i] is used to store the *inputs* to the computation at
450
  level i, not the output for the node at that level.
451
  Thus, for example, the message input is stored in B[1], not B[0].
452
 
453
* Level 0 is not used.  The message bytes are placed into B[1].
454
 
455
* top is the largest ell for which B[ell] has received data,
456
  or is equal to 1 in case no data has been received yet at all.
457
 
458
* top is never greater than L+1.  If B[L+1] is
459
  compressed, the result is put back into B[L+1]  (this is SEQ).
460
 
461
* bits[ell] says how many bits have been placed into
462
  B[ell].  An invariant maintained is that of the bits in B[ell],
463
  only the first bits[ell] may be nonzero; the following bits must be zero.
464
 
465
* The B nodes may have somewhat different formats, depending on the level:
466
  -- Level 1 node contains a variable-length bit-string, and so
467
 
468
  -- Levels 2...top always receive data in c-word chunks (from
469
     children), so for them bits[ell] is between 0 and b*w,
470
     inclusive, but is also a multiple of cw.  We can think of these
471
     nodes as have (b/c) (i.e. 4) "slots" for chunks.
472
  -- Level L+1 is special, in that the first c words of B are dedicated
473
     to the "chaining variable" (or IV, for the first node on the level).
474
 
475
* When the hashing is over, B[top] will contain the
476
  final hash value, in the first or second (if top = L+1) slot.
477
 
478
*/
479
/* Compress one block -- compress data at a node (md6_compress_block).
480
*/
481
 
482
int md6_compress_block( md6_word *C,
483
                        md6_state *st,
484
                        int ell,
485
                        int z
486
                        )
487
/* compress block at level ell, and put c-word result into C.
488
** Input:
489
**     st         current md6 computation state
490
**     ell        0 <= ell < max_stack_height-1
491
**     z          z = 1 if this is very last compression; else 0
492
** Output:
493
**     C          c-word array to put result in
494
** Modifies:
495
**     st->bits[ell]  (zeroed)
496
**     st->i_for_level[ell] (incremented)
497
**     st->B[ell] (zeroed)
498
**     st->compression_calls (incremented)
499
** Returns one of the following:
500
**     MD6_SUCCESS
501
**     MD6_NULLSTATE
502
**     MD6_STATENOTINIT
503
**     MD6_STACKUNDERFLOW
504
**     MD6_STACKOVERFLOW
505
*/
506
{ int p, err;
507
 
508
  /* check that input values are sensible */
509
  if ( st == NULL) return MD6_NULLSTATE;
510
  if ( st->initialized == 0 ) return MD6_STATENOTINIT;
511
  if ( ell < 0 ) return MD6_STACKUNDERFLOW;
512
  if ( ell >= md6_max_stack_height-1 ) return MD6_STACKOVERFLOW;
513
 
514
  st->compression_calls++;
515
 
516
  if (ell==1) /* leaf; hashing data; reverse bytes if nec. */
517
    { if (ell<(st->L + 1)) /* PAR (tree) node */
518
        md6_reverse_little_endian(&(st->B[ell][0]),b);
519
      else /* SEQ (sequential) node; don't reverse chaining vars */
520
        md6_reverse_little_endian(&(st->B[ell][c]),b-c);
521
    }
522
 
523
  p = b*w - st->bits[ell];          /* number of pad bits */
524
 
525
  err =
526
    md6_standard_compress(
527
      C,                                      /* C    */
528
      Q,                                      /* Q    */
529
      st->K,                                  /* K    */
530
      ell, st->i_for_level[ell],              /* -> U */
531
      st->r, st->L, z, p, st->keylen, st->d,  /* -> V */
532
      st->B[ell]                              /* B    */
533
                           );
534
  if (err) return err;
535
 
536
  st->bits[ell] = 0; /* clear bits used count this level */
537
  st->i_for_level[ell]++;
538
 
539
  memset(&(st->B[ell][0]),0,b*sizeof(md6_word));     /* clear B[ell] */
540
  return MD6_SUCCESS;
541
}
542
 
543
/* Process (compress) a node and its compressible ancestors.
544
*/
545
 
546
int md6_process( md6_state *st,
547
                 int ell,
548
                 int final )
549
/*
550
** Do processing of level ell (and higher, if necessary) blocks.
551
**
552
** Input:
553
**     st         md6 state that has been accumulating message bits
554
**                and/or intermediate results
555
**     ell        level number of block to process
556
**     final      true if this routine called from md6_final
557
**                     (no more input will come)
558
**                false if more input will be coming
559
**                (This is not same notion as "final bit" (i.e. z)
560
**                 indicating the last compression operation.)
561
** Output (by side effect on state):
562
**     Sets st->hashval to final chaining value on final compression.
563
** Returns one of the following:
564
**     MD6_SUCCESS
565
**     MD6_NULLSTATE
566
**     MD6_STATENOTINIT
567
*/
568
{ int err, z, next_level;
569
  md6_word C[c];
570
 
571
  /* check that input values are sensible */
572
  if ( st == NULL) return MD6_NULLSTATE;
573
  if ( st->initialized == 0 ) return MD6_STATENOTINIT;
574
 
575
  if (!final) /* not final -- more input will be coming */
576
    { /* if not final and block on this level not full, nothing to do */
577
      if ( st->bits[ell] < b*w )
578
        return MD6_SUCCESS;
579
      /* else fall through to compress this full block,
580
      **       since more input will be coming
581
      */
582
    }
583
  else /* final -- no more input will be coming */
584
    { if ( ell == st->top )
585
        { if (ell == (st->L + 1)) /* SEQ node */
586
            { if ( st->bits[ell]==c*w && st->i_for_level[ell]>0 )
587
                return MD6_SUCCESS;
588
              /* else (bits>cw or i==0, so fall thru to compress */
589
            }
590
           else /* st->top == ell <= st->L so we are at top tree node */
591
             { if ( ell>1 && st->bits[ell]==c*w)
592
                 return MD6_SUCCESS;
593
               /* else (ell==1 or bits>cw, so fall thru to compress */
594
             }
595
        }
596
      /* else (here ell < st->top so fall through to compress */
597
    }
598
 
599
  /* compress block at this level; result goes into C */
600
  /* first set z to 1 iff this is the very last compression */
601
  z = 0; if (final && (ell == st->top)) z = 1;
602
  if ((err = md6_compress_block(C,st,ell,z)))
603
      return err;
604
  if (z==1) /* save final chaining value in st->hashval */
605
    { memcpy( st->hashval, C, md6_c*(w/8) );
606
      return MD6_SUCCESS;
607
    }
608
 
609
  /* where should result go? To "next level" */
610
  next_level = min(ell+1,st->L+1);
611
  /* Start sequential mode with IV=0 at that level if necessary
612
  ** (All that is needed is to set bits[next_level] to c*w,
613
  ** since the bits themselves are already zeroed, either
614
  ** initially, or at the end of md6_compress_block.)
615
  */
616
  if (next_level == st->L + 1
617
      && st->i_for_level[next_level]==0
618
      && st->bits[next_level]==0 )
619
    st->bits[next_level] = c*w;
620
  /* now copy C onto next level */
621
  memcpy((char *)st->B[next_level] + st->bits[next_level]/8,
622
         C,
623
         c*(w/8));
624
  st->bits[next_level] += c*w;
625
  if (next_level > st->top) st->top = next_level;
626
 
627
  return md6_process(st,next_level,final);
628
}
629
/* Update -- incorporate data string into hash computation.
630
*/
631
 
632
int md6_update( md6_state *st,
633
                unsigned char *data,
634
                uint64_t databitlen )
635
/* Process input byte string data, updating state to reflect result
636
** Input:
637
**     st               already initialized state to be updated
638
**     data             byte string of length databitlen bits
639
**                      to be processed (aka "M")
640
**     databitlen       number of bits in string data (aka "m")
641
** Modifies:
642
**     st               updated to reflect input of data
643
*/
644
{ unsigned int j, portion_size;
645
  int err;
646
 
647
  /* check that input values are sensible */
648
  if ( st == NULL ) return MD6_NULLSTATE;
649
  if ( st->initialized == 0 ) return MD6_STATENOTINIT;
650
  if ( data == NULL ) return MD6_NULLDATA;
651
 
652
  j = 0; /* j = number of bits processed so far with this update */
653
  while (j<databitlen)
654
    { /* handle input string in portions (portion_size in bits)
655
      ** portion_size may be zero (level 1 data block might be full,
656
      ** having size b*w bits) */
657
      portion_size = min(databitlen-j,
658
                         (unsigned int)(b*w-(st->bits[1])));
659
 
660
      if ((portion_size % 8 == 0) &&
661
          (st->bits[1] % 8 == 0) &&
662
          (j % 8 == 0))
663
        { /* use mempy to handle easy, but most common, case */
664
          memcpy((char *)st->B[1] + st->bits[1]/8,
665
                 &(data[j/8]),
666
                 portion_size/8);
667
        }
668
      else /* handle messy case where shifting is needed */
669
        { append_bits((unsigned char *)st->B[1], /* dest */
670
                      st->bits[1],   /* dest current bit size */
671
                      &(data[j/8]),  /* src */
672
                      portion_size); /* src size in bits  */
673
        }
674
      j += portion_size;
675
      st->bits[1] += portion_size;
676
      st->bits_processed += portion_size;
677
 
678
      /* compress level-1 block if it is now full
679
         but we're not done yet */
680
      if (st->bits[1] == b*w && j<databitlen)
681
        { if ((err=md6_process(st,
682
                               1,    /* ell */
683
 
684
                               )))
685
            return err;
686
        }
687
    } /* end of loop body handling input portion */
688
  return MD6_SUCCESS;
689
}
690
 
691
/* Convert hash value to hexadecimal, and store it in state.
692
*/
693
 
694
int md6_compute_hex_hashval( md6_state *st )
695
/*
696
** Convert hashval in st->hashval into hexadecimal, and
697
** save result in st->hexhashval
698
** This will be a zero-terminated string of length ceil(d/4).
699
** Assumes that hashval has already been "trimmed" to correct
700
** length.
701
**
702
** Returns one of the following:
703
**    MD6_SUCCESS
704
**    MD6_NULLSTATE                      (if input state pointer was NULL)
705
*/
706
{ int i;
707
  static unsigned char hex_digits[] = "0123456789abcdef";
708
 
709
  /* check that input is sensible */
710
  if ( st == NULL ) return MD6_NULLSTATE;
711
 
712
  for (i=0;i<((st->d+7)/8);i++)
713
    { st->hexhashval[2*i]
714
        = hex_digits[ ((st->hashval[i])>>4) & 0xf ];
715
      st->hexhashval[2*i+1]
716
        = hex_digits[ (st->hashval[i]) & 0xf ];
717
    }
718
 
719
  /* insert zero string termination byte at position ceil(d/4) */
720
  st->hexhashval[(st->d+3)/4] = 0;
721
  return MD6_SUCCESS;
722
}
723
 
724
/* Extract last d bits of chaining variable as hash value.
725
*/
726
 
727
void trim_hashval(md6_state *st)
728
{ /* trim hashval to desired length d bits by taking only last d bits */
729
  /* note that high-order bit of a byte is considered its *first* bit */
730
  int full_or_partial_bytes = (st->d+7)/8;
731
  int bits = st->d % 8;                 /* bits in partial byte */
732
  int i;
733
 
734
  /* move relevant bytes to the front */
735
  for ( i=0; i<full_or_partial_bytes; i++ )
736
    st->hashval[i] = st->hashval[c*(w/8)-full_or_partial_bytes+i];
737
 
738
  /* zero out following bytes */
739
  for ( i=full_or_partial_bytes; i<c*(w/8); i++ )
740
    st->hashval[i] = 0;
741
 
742
  /* shift result left by (8-bits) bit positions, per byte, if needed */
743
  if (bits>0)
744
    { for ( i=0; i<full_or_partial_bytes; i++ )
745
        { st->hashval[i] = (st->hashval[i] << (8-bits));
746
          if ( (i+1) < c*(w/8) )
747
            st->hashval[i] |= (st->hashval[i+1] >> bits);
748
        }
749
    }
750
}
751
 
752
/* Final -- no more data; finish up and produce hash value.
753
*/
754
 
755
int md6_final( md6_state *st , unsigned char *hashval)
756
/* Do final processing to produce md6 hash value
757
** Input:
758
**     st              md6 state that has been accumulating message bits
759
**                     and/or intermediate results
760
** Output (by side effect on state):
761
**     hashval         If this is non-NULL, final hash value copied here.
762
**                     (NULL means don't copy.)  In any case, the hash
763
**                     value remains in st->hashval.
764
**     st->hashval     this is a 64-byte array; the first st->d
765
**                     bits of which will be the desired hash value
766
**                     (with high-order bits of a byte used first), and
767
**                     remaining bits set to zero (same as hashval)
768
**     st->hexhashval  this is a 129-byte array which contains the
769
**                     zero-terminated hexadecimal version of the hash
770
** Returns one of the following:
771
**     MD6_SUCCESS
772
**     MD6_NULLSTATE
773
**     MD6_STATENOTINIT
774
*/
775
{ int ell, err;
776
 
777
  /* check that input values are sensible */
778
  if ( st == NULL) return MD6_NULLSTATE;
779
  if ( st->initialized == 0 ) return MD6_STATENOTINIT;
780
 
781
  /* md6_final was previously called */
782
  if ( st->finalized == 1 ) return MD6_SUCCESS;
783
 
784
  /* force any processing that needs doing */
785
  if (st->top == 1) ell = 1;
786
  else for (ell=1; ell<=st->top; ell++)
787
         if (st->bits[ell]>0) break;
788
  /* process starting at level ell, up to root */
789
  err = md6_process(st,ell,1);
790
  if (err) return err;
791
 
792
  /* md6_process has saved final chaining value in st->hashval */
793
 
794
  md6_reverse_little_endian( (md6_word*)st->hashval, c );
795
  if (hashval != NULL) memcpy( hashval, st->hashval, (st->d+7)/8 );
796
  trim_hashval( st );
797
  md6_compute_hex_hashval( st );
798
 
799
  st->finalized = 1;
800
  return MD6_SUCCESS;
801
}
802
 
803
/* Routines for hashing message given "all at once".
804
*/
805
 
806
int md6_full_hash( int d,                    /* hash bit length */
807
                   unsigned char *data,/* complete data to hash */
808
                   uint64_t databitlen,   /* its length in bits */
809
                   unsigned char *key,       /* OK to give NULL */
810
                   int keylen,       /* (in bytes) OK to give 0 */
811
                   int L,     /* mode; OK to give md6_default_L */
812
                   int r,                   /* number of rounds */
813
                   unsigned char *hashval             /* output */
814
                   )
815
{ md6_state st;
816
  int err;
817
 
818
  err = md6_full_init(&st,d,key,keylen,L,r);
819
  if (err) return err;
820
  err = md6_update(&st,data,databitlen);
821
  if (err) return err;
822
  md6_final(&st,hashval);
823
  if (err) return err;
824
  return MD6_SUCCESS;
825
}
826
 
827
int md6_hash( int d,                         /* hash bit length */
828
              unsigned char *data,     /* complete data to hash */
829
              uint64_t databitlen,        /* its length in bits */
830
              unsigned char *hashval                  /* output */
831
             )
832
{ int err;
833
 
834
  err = md6_full_hash(d,data,databitlen,
835
                      NULL,0,md6_default_L,md6_default_r(d),hashval);
836
  if (err) return err;
837
  return MD6_SUCCESS;
838
}
839
 
840
 
841
/*
842
** end of md6_mode.c
843
*/
844
 
845
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.