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

Subversion Repositories bluespec_md6

[/] [bluespec_md6/] [trunk/] [C_implementation/] [md6.h] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kfleming
/* File:    md6.h
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 file 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.
38
** (Note that md6.h includes inttypes.h, which includes stdint.h;
39
** versions of these header files compatible with MS Visual Studio
40
** are available, as noted below.)
41
**
42
** The files defining the interface between MD6 and the NIST SHA-3
43
** API are:
44
**    md6_nist.h
45
**    md6_nist.c
46
** The NIST SHA-3 API is defined in:
47
**    http://www.csrc.nist.gov/groups/ST/hash/documents/SHA3-C-API.pdf
48
**
49
** See  http://groups.csail.mit.edu/cis/md6  for more information.
50
**
51
** These files define the ``standard'' version of MD6.  However,
52
** they are written in such a way that one may relatively easily
53
** define and experiment with ``variant'' versions.
54
*/
55
 
56
/* Prevent multiple includes
57
** Matching endif is at end of md6.h
58
*/
59
#ifndef MD6_H_INCLUDED
60
#define MD6_H_INCLUDED
61
 
62
 
63
/* inttypes.h (which includes stdint.h)
64
** inttypes.h and stdint.h  are part of the normal environment
65
** for gcc, but not for MS Visual Studio.  Fortunately,
66
** compatible implementations are available from Google at:
67
**   http://msinttypes.googlecode.com/svn/trunk/stdint.h
68
**   http://msinttypes.googlecode.com/svn/trunk/inttypes.h
69
** If these two files are in the same directory as md6.h, then
70
** MD6 will compile OK with MS Visual Studio.
71
*/
72
#if defined  _MSC_VER
73
#include "inttypes.h"
74
#else
75
#include <inttypes.h>
76
#endif
77
 
78
/* MD6 wordsize.
79
**
80
** Define md6 wordsize md6_w, in bits.
81
** Note that this is the "word size" relevant to the
82
** definition of md6 (it defines how many bits in an
83
** "md6_word");  it does *not* refer to the word size
84
** on the platform for which this is being compiled.
85
*/
86
 
87
#define   md6_w    64
88
 
89
/* Define "md6_word" appropriately for given value of md6_w.
90
** Also define PR_MD6_WORD to be the appropriate hex format string,
91
** using the format strings from inttypes.h .
92
** The term `word' in comments means an `md6_word'.
93
*/
94
 
95
#if (md6_w==64)                    /* standard md6 */
96
typedef uint64_t md6_word;
97
#define PR_MD6_WORD "%.16" PRIx64
98
 
99
#elif (md6_w==32)                  /* nonstandard variant */
100
typedef uint32_t md6_word;
101
#define PR_MD6_WORD "%.8" PRIx32
102
 
103
#elif (md6_w==16)                  /* nonstandard variant */
104
typedef uint16_t md6_word;
105
#define PR_MD6_WORD "%.4" PRIx16
106
 
107
#elif (md6_w==8)                   /* nonstandard variant */
108
typedef uint8_t md6_word;
109
#define PR_MD6_WORD "%.2" PRIx8
110
 
111
#endif
112
 
113
/* MD6 compression function.
114
**
115
** MD6 compression function is defined in file md6_compress.c
116
*/
117
 
118
/* MD6 compression function constants                                  */
119
 
120
#define md6_n      89    /* size of compression input block, in words  */
121
#define md6_c      16    /* size of compression output, in words       */
122
                         /* a c-word block is also called a "chunk"    */
123
#define md6_max_r 255    /* max allowable value for number r of rounds */
124
 
125
/* Compression function routines
126
** These are ``internal'' routines that need not be called for
127
** ordinary md6 usage.
128
*/
129
 
130
extern int md6_default_r( int d );    /* returns default r for given d */
131
 
132
void md6_main_compression_loop( md6_word *A,          /* working array */
133
                                int r              /* number of rounds */
134
                                );
135
 
136
int md6_compress( md6_word *C,                               /* output */
137
                  md6_word *N,                                /* input */
138
                  int r,                              /* number rounds */
139
                  md6_word *A /* (optional) working array, may be NULL */
140
                );
141
 
142
 
143
typedef uint64_t md6_control_word;                      /* (r,L,z,p,d) */
144
md6_control_word md6_make_control_word( int r,        /* number rounds */
145
                                        int L,      /* parallel passes */
146
                                        int z,      /* final node flag */
147
                                        int p,         /* padding bits */
148
                                        int keylen,    /* bytes in key */
149
                                        int d           /* digest size */
150
                                        );
151
 
152
typedef uint64_t md6_nodeID;                                /* (ell,i) */
153
md6_nodeID md6_make_nodeID( int ell,                   /* level number */
154
                            int i    /* index (0,1,2,...) within level */
155
                            );
156
 
157
void md6_pack( md6_word* N,                                  /* output */
158
               const md6_word* Q,           /* fractional part sqrt(6) */
159
               md6_word* K,                                     /* key */
160
               int ell, int i,                                /* for U */
161
               int r, int L, int z, int p, int keylen, int d, /* for V */
162
               md6_word* B                               /* data input */
163
               );
164
 
165
int md6_standard_compress(
166
        md6_word *C,                                     /* output */
167
        const md6_word *Q,              /* fractional part sqrt(6) */
168
        md6_word *K,                                        /* key */
169
        int ell, int i,                                   /* for U */
170
        int r, int L, int z, int p, int keylen, int d,    /* for V */
171
        md6_word* B                                  /* data input */
172
                           );
173
 
174
/* MD6 mode of operation.
175
**
176
** MD6 mode of operation is defined in file md6_mode.c
177
*/
178
 
179
/* MD6 constants related to standard mode of operation                 */
180
 
181
/* These five values give lengths of the components of compression     */
182
/* input block; they should sum to md6_n.                              */
183
#define md6_q 15         /* # Q words in compression block (>=0)       */
184
#define md6_k  8         /* # key words per compression block (>=0)    */
185
#define md6_u (64/md6_w) /* # words for unique node ID (0 or 64/w)     */
186
#define md6_v (64/md6_w) /* # words for control word (0 or 64/w)       */
187
#define md6_b 64         /* # data words per compression block (>0)    */
188
 
189
#define md6_default_L 64    /* large so that MD6 is fully hierarchical */
190
 
191
#define md6_max_stack_height 29
192
    /* max_stack_height determines the maximum number of bits that
193
    ** can be processed by this implementation (with default L) to be:
194
    **    (b*w) * ((b/c) ** (max_stack_height-3)
195
    **    = 2 ** 64  for b = 64, w = 64, c = 16, and  max_stack_height = 29
196
    ** (We lose three off the height since level 0 is unused,
197
    ** level 1 contains the input data, and C has 0-origin indexing.)
198
    ** The smallest workable value for md6_max_stack_height is 3.
199
    ** (To avoid stack overflow for non-default L values,
200
    ** we should have max_stack_height >= L + 2.)
201
    ** (One level of storage could be saved by letting st->N[] use
202
    ** 1-origin indexing, since st->N[0] is now unused.)
203
    */
204
 
205
/* MD6 state.
206
**
207
** md6_state is the main data structure for the MD6 hash function.
208
*/
209
 
210
typedef struct {
211
 
212
  int d;           /* desired hash bit length. 1 <= d <= 512.      */
213
  int hashbitlen;  /* hashbitlen is the same as d; for NIST API    */
214
 
215
  unsigned char hashval[ (md6_c/2)*(md6_w/8) ];
216
      /* e.g. unsigned char hashval[64];  (Assumes d<=c/2.)        */
217
      /* contains hashval after call to md6_final                  */
218
      /* hashval appears in first floor(d/8) bytes, with           */
219
      /* remaining (d mod 8) bits (if any) appearing in            */
220
      /* high-order bit positions of hashval[1+floor(d/8)].        */
221
 
222
  unsigned char hexhashval[(md6_c*(md6_w/8))+1];
223
      /* e.g. unsigned char hexhashval[129];                       */
224
      /* zero-terminated string representing hex value of hashval  */
225
 
226
  int initialized;         /* zero, then one after md6_init called */
227
  uint64_t bits_processed;                /* bits processed so far */
228
  uint64_t compression_calls;    /* compression function calls made*/
229
  int finalized;          /* zero, then one after md6_final called */
230
 
231
  md6_word K[ md6_k ];
232
      /* k-word (8 word) key (aka "salt") for this instance of md6 */
233
  int keylen;
234
      /* number of bytes in key K. 0<=keylen<=k*(w/8)              */
235
 
236
  int L;
237
      /* md6 mode specification parameter. 0 <= L <= 255           */
238
      /* L == 0 means purely sequential (Merkle-Damgaard)          */
239
      /* L >= 29 means purely tree-based                           */
240
      /* Default is md6_default_L = 64 (hierarchical)              */
241
 
242
  int r;
243
      /* Number of rounds. 0 <= r <= 255                           */
244
 
245
  int top;
246
      /* index of block corresponding to top of stack              */
247
 
248
  md6_word B[ md6_max_stack_height ][ md6_b ];
249
      /* md6_word B[29][64]                                        */
250
      /* stack of 29 64-word partial blocks waiting to be          */
251
      /* completed and compressed.                                 */
252
      /* B[1] is for compressing text data (input);                */
253
      /* B[ell] corresponds to node at level ell in the tree.      */
254
 
255
  unsigned int bits[ md6_max_stack_height ];
256
      /* bits[ell] =                                               */
257
      /*    number of bits already placed in B[ell]                */
258
      /*    for 1 <= ell < max_stack_height                        */
259
      /* 0 <= bits[ell] <= b*w                                     */
260
 
261
  uint64_t i_for_level[ md6_max_stack_height ];
262
      /* i_for_level[ell] =                                        */
263
      /*    index of the node B[ ell ] on this level (0,1,...)     */
264
      /* when it is output   */
265
 
266
} md6_state;
267
/* MD6 main interface routines
268
**
269
** These routines are defined in md6_mode.c
270
*/
271
 
272
/* The next routines are used according to the pattern:
273
**    md6_init        (or md6_full_init if you use additional parameters)
274
**    md6_update         (once for each portion of the data to be hashed)
275
**    md6_final                           (to finish up hash computation)
276
** Note: md6_final can return the hash value to a desired location, but
277
** hash value also remains available inside the md6_state, in both binary
278
** and hex formats (st->hashval and st->hexhashval).
279
*/
280
 
281
extern int md6_init( md6_state *st,             /* state to initialize */
282
                     int d                          /* hash bit length */
283
                     );
284
 
285
extern int md6_full_init( md6_state *st,        /* state to initialize */
286
                          int d,                    /* hash bit length */
287
                          unsigned char *key,       /* OK to give NULL */
288
                          int keylen,       /* (in bytes) OK to give 0 */
289
                          int L,     /* mode; OK to give md6_default_L */
290
                          int r                    /* number of rounds */
291
                          );
292
 
293
extern int md6_update( md6_state *st,             /* initialized state */
294
                       unsigned char *data,            /* data portion */
295
                       uint64_t databitlen       /* its length in bits */
296
                       );
297
 
298
extern int md6_final( md6_state *st,            /* initialized/updated */
299
                      unsigned char *hashval       /* output; NULL OK  */
300
                      );
301
 
302
/* MD6 main interface routines
303
**
304
** These routines are defined in md6_mode.c
305
**
306
** These routines compute a hash for a message given all at once.
307
** The resulting hash value is returned to a specified location.
308
** Only one call is needed.  Use md6_hash for the standard md6 hash,
309
** and md6_full_hash if you want to specify additional parameters.
310
*/
311
 
312
extern int md6_hash( int d,                         /* hash bit length */
313
                     unsigned char *data,     /* complete data to hash */
314
                     uint64_t databitlen,        /* its length in bits */
315
                     unsigned char *hashval                 /* output */
316
                     );
317
 
318
extern int md6_full_hash( int d,                    /* hash bit length */
319
                          unsigned char *data,/* complete data to hash */
320
                          uint64_t databitlen,   /* its length in bits */
321
                          unsigned char *key,       /* OK to give NULL */
322
                          int keylen,       /* (in bytes) OK to give 0 */
323
                          int L,     /* mode; OK to give md6_default_L */
324
                          int r,                   /* number of rounds */
325
                          unsigned char *hashval             /* output */
326
                          );
327
 
328
 
329
/* MD6 return codes.
330
**
331
** The interface routines defined in md6_mode.c always return a
332
** "return code": an integer giving the status of the call.
333
** The codes
334
** SUCCESS, FAIL, and BADHASHLEN same as for NIST API
335
*/
336
 
337
/* SUCCESS:  */
338
#define MD6_SUCCESS 0
339
 
340
/* ERROR CODES: */
341
#define MD6_FAIL 1           /* some other problem                     */
342
#define MD6_BADHASHLEN 2     /* hashbitlen<1 or >512 bits              */
343
#define MD6_NULLSTATE 3      /* null state passed to MD6               */
344
#define MD6_BADKEYLEN 4      /* key length is <0 or >512 bits          */
345
#define MD6_STATENOTINIT 5   /* state was never initialized            */
346
#define MD6_STACKUNDERFLOW 6 /* MD6 stack underflows (shouldn't happen)*/
347
#define MD6_STACKOVERFLOW 7  /* MD6 stack overflow (message too long)  */
348
#define MD6_NULLDATA 8       /* null data pointer                      */
349
#define MD6_NULL_N 9         /* compress: N is null                    */
350
#define MD6_NULL_B 10        /* standard compress: null B pointer      */
351
#define MD6_BAD_ELL 11       /* standard compress: ell not in {0,255}  */
352
#define MD6_BAD_p 12         /* standard compress: p<0 or p>b*w        */
353
#define MD6_NULL_K 13        /* standard compress: K is null           */
354
#define MD6_NULL_Q 14        /* standard compress: Q is null           */
355
#define MD6_NULL_C 15        /* standard compress: C is null           */
356
#define MD6_BAD_L 16         /* standard compress: L <0 or > 255       */ 
357
                             /* md6_init: L<0 or L>255                 */
358
#define MD6_BAD_r 17         /* compress: r<0 or r>255                 */
359
                             /* md6_init: r<0 or r>255                 */
360
#define MD6_OUT_OF_MEMORY 18 /* compress: storage allocation failed    */
361
 
362
 
363
/* The following code confirms that the defined MD6 constants satisfy
364
** some expected properties.  These tests should never fail; consider
365
** these tests to be documentation. Failure of these tests would cause
366
** compilation to fail.
367
*/
368
 
369
#if ( (md6_w!=8) && (md6_w!=16) && (md6_w!=32) && (md6_w!=64) )
370
  #error "md6.h Fatal error: md6_w must be one of 8,16,32, or 64."
371
#elif ( md6_n<=0 )
372
  #error "md6.h Fatal error: md6_n must be positive."
373
#elif ( md6_b<=0 )
374
  #error "md6.h Fatal error: md6_b must be positive."
375
#elif ( md6_c<=0 )
376
  #error "md6.h Fatal error: md6_c must be positive."
377
#elif ( md6_v<0 )
378
  #error "md6.h Fatal error: md6_v must be nonnegative."
379
#elif ( md6_u<0 )
380
  #error "md6.h Fatal error: md6_u must be nonnegative."
381
#elif ( md6_k<0 )
382
  #error "md6.h Fatal error: md6_k must be nonnegative."
383
#elif ( md6_q<0 )
384
  #error "md6.h Fatal error: md6_q must be nonnegative."
385
#elif ( md6_b>=md6_n )
386
  #error "md6.h Fatal error: md6_b must be smaller than md6_n."
387
#elif ( md6_c>=md6_b )
388
  #error "md6.h Fatal error: md6_c must be smaller than md6_b."
389
#elif ( (md6_b%md6_c)!=0 )
390
  #error "md6.h Fatal error: md6_b must be a multiple of md6_c."
391
#elif ( md6_n != md6_b + md6_v + md6_u + md6_k + md6_q )
392
  #error "md6.h Fatal error: md6_n must = md6_b + md6_v + md6_u + md6_k + md6_q."
393
#elif ( md6_max_stack_height < 3 )
394
  #error "md6.h Fatal error: md6_max_stack_height must be at least 3."
395
#elif ( md6_r * md6_c + md6_n >= 5000 )
396
  /* since md6_standard_compress allocates fixed-size array A[5000] */
397
  #error "md6.h Fatal error: r*c+n must be < 5000."
398
#if 0
399
  /* "sizeof" doesn't work in preprocessor, these checks don't work */
400
  #elif ( (md6_v != 0) && (md6_v != (sizeof(md6_control_word)/(md6_w/8))) )
401
    #error "md6.h Fatal error: md6_v must be 0 or match md6_control_word size."
402
  #elif ( (md6_u != 0) && (md6_u != (sizeof(md6_nodeID)/(md6_w/8))) )
403
    #error "md6.h Fatal error: md6_u must be 0 or match md6_nodeID size."
404
#endif
405
#endif
406
 
407
 
408
/* Debugging and testing.
409
*/
410
 
411
/* compression hook, if defined, points to a function that is
412
** called after each compression operation.
413
**
414
** compression hook must be set *after* md6_init or md6_full_init
415
** is called.
416
*/
417
 
418
void (* compression_hook)(md6_word *C,
419
                          const md6_word *Q,
420
                          md6_word *K,
421
                          int ell,
422
                          int i,
423
                          int r,
424
                          int L,
425
                          int z,
426
                          int p,
427
                          int keylen,
428
                          int d,
429
                          md6_word *N
430
                          );
431
 
432
/* end of #ifndef MD6_H_INCLUDED for multiple inclusion protection
433
*/
434
#endif
435
 
436
/* end of md6.h */

powered by: WebSVN 2.1.0

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