digest-whirlpool 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,42 @@
1
+ whirlpool-algorithm.c:
2
+ whirlpool-algorithm.h:
3
+ whirlpool-constants.h:
4
+ whirlpool-portability.h:
5
+
6
+ These files are under the new-style BSD license.
7
+
8
+ Copyright (c) 2006, Hongli Lai
9
+ All rights reserved.
10
+
11
+ Redistribution and use in source and binary forms, with or without
12
+ modification, are permitted provided that the following conditions
13
+ are met:
14
+
15
+ 1. Redistributions of source code must retain the above copyright
16
+ notice, this list of conditions and the following disclaimer.
17
+
18
+ 2. Redistributions in binary form must reproduce the above copyright
19
+ notice, this list of conditions and the following disclaimer in the
20
+ documentation and/or other materials provided with the distribution.
21
+
22
+ 3. Neither the name of Hongli Lai nor the names of its contributors
23
+ may be used to endorse or promote products derived from this
24
+ software without specific prior written permission.
25
+
26
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
30
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
+
38
+ For the rest:
39
+
40
+ You can redistribute and/or modify it under the same terms as Ruby.
41
+
42
+ Copyright (c) 2006, 2009 Akinori MUSHA <knu@iDaemons.org>
@@ -0,0 +1,22 @@
1
+ = Digest::Whirlpool - Ruby interface to the Whirlpool message digest algorithm
2
+
3
+ == Summary
4
+
5
+ Digest::Whirlpool is a Ruby library for calculating message digests
6
+ using the Whirlpool algorithm. The library interface corforms to the
7
+ standard Digest API.
8
+
9
+ More information about Whirlpool:
10
+ http://en.wikipedia.org/wiki/Whirlpool_%28algorithm%29
11
+ http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html
12
+
13
+ The C code is based on the sample implementation, as available on the
14
+ mentioned website.
15
+
16
+ == Requirements
17
+
18
+ - Ruby 1.8.6 or later
19
+
20
+ == License
21
+
22
+ See the file LICENSE.
@@ -0,0 +1,6 @@
1
+ whirlpool-algorithm.o: whirlpool-algorithm.c whirlpool-algorithm.h \
2
+ whirlpool-portability.h whirlpool-constants.h
3
+ whirlpool.o: whirlpool.c whirlpool-algorithm.h whirlpool-portability.h \
4
+ whirlpool-constants.h \
5
+ $(hdrdir)/digest.h $(hdrdir)/ruby.h \
6
+ $(topdir)/config.h $(hdrdir)/defines.h $(hdrdir)/intern.h
@@ -0,0 +1,10 @@
1
+ # $Id$
2
+
3
+ require 'mkmf'
4
+
5
+ $defs << "-DHAVE_CONFIG_H"
6
+ $INCFLAGS << " -I$(srcdir)/.."
7
+
8
+ $preload = %w[digest]
9
+
10
+ create_makefile('digest/whirlpool')
@@ -0,0 +1,473 @@
1
+ /**
2
+ * The Whirlpool hashing function.
3
+ *
4
+ * The Whirlpool algorithm was developed by
5
+ * Paulo S. L. M. Barreto and Vincent Rijmen.
6
+ *
7
+ * See
8
+ * P.S.L.M. Barreto, V. Rijmen,
9
+ * ``The Whirlpool hashing function,''
10
+ * NESSIE submission, 2000 (tweaked version, 2001),
11
+ * <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
12
+ *
13
+ * @version 3.0 (2003.03.12)
14
+ *
15
+ * Modified for use in this software package.
16
+ */
17
+ #include <stdlib.h>
18
+ #include <string.h>
19
+ #include <limits.h>
20
+ #include "whirlpool-algorithm.h"
21
+ #include "whirlpool-portability.h"
22
+ #include "whirlpool-constants.h"
23
+
24
+ #ifdef __cplusplus
25
+ extern "C" {
26
+ #endif
27
+
28
+
29
+ /**
30
+ * The core Whirlpool transform.
31
+ */
32
+ static void
33
+ processBuffer(WP_Struct * const structpointer) {
34
+ int i, r;
35
+ u64 K[8]; /* the round key */
36
+ u64 block[8]; /* mu(buffer) */
37
+ u64 state[8]; /* the cipher state */
38
+ u64 L[8];
39
+ u8 *buffer = structpointer->buffer;
40
+
41
+ /*
42
+ * map the buffer to a block:
43
+ */
44
+ for (i = 0; i < 8; i++, buffer += 8) {
45
+ block[i] =
46
+ (((u64)buffer[0] ) << 56) ^
47
+ (((u64)buffer[1] & 0xffL) << 48) ^
48
+ (((u64)buffer[2] & 0xffL) << 40) ^
49
+ (((u64)buffer[3] & 0xffL) << 32) ^
50
+ (((u64)buffer[4] & 0xffL) << 24) ^
51
+ (((u64)buffer[5] & 0xffL) << 16) ^
52
+ (((u64)buffer[6] & 0xffL) << 8) ^
53
+ (((u64)buffer[7] & 0xffL) );
54
+ }
55
+ /*
56
+ * compute and apply K^0 to the cipher state:
57
+ */
58
+ state[0] = block[0] ^ (K[0] = structpointer->hash[0]);
59
+ state[1] = block[1] ^ (K[1] = structpointer->hash[1]);
60
+ state[2] = block[2] ^ (K[2] = structpointer->hash[2]);
61
+ state[3] = block[3] ^ (K[3] = structpointer->hash[3]);
62
+ state[4] = block[4] ^ (K[4] = structpointer->hash[4]);
63
+ state[5] = block[5] ^ (K[5] = structpointer->hash[5]);
64
+ state[6] = block[6] ^ (K[6] = structpointer->hash[6]);
65
+ state[7] = block[7] ^ (K[7] = structpointer->hash[7]);
66
+
67
+ /*
68
+ * iterate over all rounds:
69
+ */
70
+ for (r = 1; r <= R; r++) {
71
+ /*
72
+ * compute K^r from K^{r-1}:
73
+ */
74
+ L[0] =
75
+ C0[(int)(K[0] >> 56) ] ^
76
+ C1[(int)(K[7] >> 48) & 0xff] ^
77
+ C2[(int)(K[6] >> 40) & 0xff] ^
78
+ C3[(int)(K[5] >> 32) & 0xff] ^
79
+ C4[(int)(K[4] >> 24) & 0xff] ^
80
+ C5[(int)(K[3] >> 16) & 0xff] ^
81
+ C6[(int)(K[2] >> 8) & 0xff] ^
82
+ C7[(int)(K[1] ) & 0xff] ^
83
+ rc[r];
84
+ L[1] =
85
+ C0[(int)(K[1] >> 56) ] ^
86
+ C1[(int)(K[0] >> 48) & 0xff] ^
87
+ C2[(int)(K[7] >> 40) & 0xff] ^
88
+ C3[(int)(K[6] >> 32) & 0xff] ^
89
+ C4[(int)(K[5] >> 24) & 0xff] ^
90
+ C5[(int)(K[4] >> 16) & 0xff] ^
91
+ C6[(int)(K[3] >> 8) & 0xff] ^
92
+ C7[(int)(K[2] ) & 0xff];
93
+ L[2] =
94
+ C0[(int)(K[2] >> 56) ] ^
95
+ C1[(int)(K[1] >> 48) & 0xff] ^
96
+ C2[(int)(K[0] >> 40) & 0xff] ^
97
+ C3[(int)(K[7] >> 32) & 0xff] ^
98
+ C4[(int)(K[6] >> 24) & 0xff] ^
99
+ C5[(int)(K[5] >> 16) & 0xff] ^
100
+ C6[(int)(K[4] >> 8) & 0xff] ^
101
+ C7[(int)(K[3] ) & 0xff];
102
+ L[3] =
103
+ C0[(int)(K[3] >> 56) ] ^
104
+ C1[(int)(K[2] >> 48) & 0xff] ^
105
+ C2[(int)(K[1] >> 40) & 0xff] ^
106
+ C3[(int)(K[0] >> 32) & 0xff] ^
107
+ C4[(int)(K[7] >> 24) & 0xff] ^
108
+ C5[(int)(K[6] >> 16) & 0xff] ^
109
+ C6[(int)(K[5] >> 8) & 0xff] ^
110
+ C7[(int)(K[4] ) & 0xff];
111
+ L[4] =
112
+ C0[(int)(K[4] >> 56) ] ^
113
+ C1[(int)(K[3] >> 48) & 0xff] ^
114
+ C2[(int)(K[2] >> 40) & 0xff] ^
115
+ C3[(int)(K[1] >> 32) & 0xff] ^
116
+ C4[(int)(K[0] >> 24) & 0xff] ^
117
+ C5[(int)(K[7] >> 16) & 0xff] ^
118
+ C6[(int)(K[6] >> 8) & 0xff] ^
119
+ C7[(int)(K[5] ) & 0xff];
120
+ L[5] =
121
+ C0[(int)(K[5] >> 56) ] ^
122
+ C1[(int)(K[4] >> 48) & 0xff] ^
123
+ C2[(int)(K[3] >> 40) & 0xff] ^
124
+ C3[(int)(K[2] >> 32) & 0xff] ^
125
+ C4[(int)(K[1] >> 24) & 0xff] ^
126
+ C5[(int)(K[0] >> 16) & 0xff] ^
127
+ C6[(int)(K[7] >> 8) & 0xff] ^
128
+ C7[(int)(K[6] ) & 0xff];
129
+ L[6] =
130
+ C0[(int)(K[6] >> 56) ] ^
131
+ C1[(int)(K[5] >> 48) & 0xff] ^
132
+ C2[(int)(K[4] >> 40) & 0xff] ^
133
+ C3[(int)(K[3] >> 32) & 0xff] ^
134
+ C4[(int)(K[2] >> 24) & 0xff] ^
135
+ C5[(int)(K[1] >> 16) & 0xff] ^
136
+ C6[(int)(K[0] >> 8) & 0xff] ^
137
+ C7[(int)(K[7] ) & 0xff];
138
+ L[7] =
139
+ C0[(int)(K[7] >> 56) ] ^
140
+ C1[(int)(K[6] >> 48) & 0xff] ^
141
+ C2[(int)(K[5] >> 40) & 0xff] ^
142
+ C3[(int)(K[4] >> 32) & 0xff] ^
143
+ C4[(int)(K[3] >> 24) & 0xff] ^
144
+ C5[(int)(K[2] >> 16) & 0xff] ^
145
+ C6[(int)(K[1] >> 8) & 0xff] ^
146
+ C7[(int)(K[0] ) & 0xff];
147
+ K[0] = L[0];
148
+ K[1] = L[1];
149
+ K[2] = L[2];
150
+ K[3] = L[3];
151
+ K[4] = L[4];
152
+ K[5] = L[5];
153
+ K[6] = L[6];
154
+ K[7] = L[7];
155
+ /*
156
+ * apply the r-th round transformation:
157
+ */
158
+ L[0] =
159
+ C0[(int)(state[0] >> 56) ] ^
160
+ C1[(int)(state[7] >> 48) & 0xff] ^
161
+ C2[(int)(state[6] >> 40) & 0xff] ^
162
+ C3[(int)(state[5] >> 32) & 0xff] ^
163
+ C4[(int)(state[4] >> 24) & 0xff] ^
164
+ C5[(int)(state[3] >> 16) & 0xff] ^
165
+ C6[(int)(state[2] >> 8) & 0xff] ^
166
+ C7[(int)(state[1] ) & 0xff] ^
167
+ K[0];
168
+ L[1] =
169
+ C0[(int)(state[1] >> 56) ] ^
170
+ C1[(int)(state[0] >> 48) & 0xff] ^
171
+ C2[(int)(state[7] >> 40) & 0xff] ^
172
+ C3[(int)(state[6] >> 32) & 0xff] ^
173
+ C4[(int)(state[5] >> 24) & 0xff] ^
174
+ C5[(int)(state[4] >> 16) & 0xff] ^
175
+ C6[(int)(state[3] >> 8) & 0xff] ^
176
+ C7[(int)(state[2] ) & 0xff] ^
177
+ K[1];
178
+ L[2] =
179
+ C0[(int)(state[2] >> 56) ] ^
180
+ C1[(int)(state[1] >> 48) & 0xff] ^
181
+ C2[(int)(state[0] >> 40) & 0xff] ^
182
+ C3[(int)(state[7] >> 32) & 0xff] ^
183
+ C4[(int)(state[6] >> 24) & 0xff] ^
184
+ C5[(int)(state[5] >> 16) & 0xff] ^
185
+ C6[(int)(state[4] >> 8) & 0xff] ^
186
+ C7[(int)(state[3] ) & 0xff] ^
187
+ K[2];
188
+ L[3] =
189
+ C0[(int)(state[3] >> 56) ] ^
190
+ C1[(int)(state[2] >> 48) & 0xff] ^
191
+ C2[(int)(state[1] >> 40) & 0xff] ^
192
+ C3[(int)(state[0] >> 32) & 0xff] ^
193
+ C4[(int)(state[7] >> 24) & 0xff] ^
194
+ C5[(int)(state[6] >> 16) & 0xff] ^
195
+ C6[(int)(state[5] >> 8) & 0xff] ^
196
+ C7[(int)(state[4] ) & 0xff] ^
197
+ K[3];
198
+ L[4] =
199
+ C0[(int)(state[4] >> 56) ] ^
200
+ C1[(int)(state[3] >> 48) & 0xff] ^
201
+ C2[(int)(state[2] >> 40) & 0xff] ^
202
+ C3[(int)(state[1] >> 32) & 0xff] ^
203
+ C4[(int)(state[0] >> 24) & 0xff] ^
204
+ C5[(int)(state[7] >> 16) & 0xff] ^
205
+ C6[(int)(state[6] >> 8) & 0xff] ^
206
+ C7[(int)(state[5] ) & 0xff] ^
207
+ K[4];
208
+ L[5] =
209
+ C0[(int)(state[5] >> 56) ] ^
210
+ C1[(int)(state[4] >> 48) & 0xff] ^
211
+ C2[(int)(state[3] >> 40) & 0xff] ^
212
+ C3[(int)(state[2] >> 32) & 0xff] ^
213
+ C4[(int)(state[1] >> 24) & 0xff] ^
214
+ C5[(int)(state[0] >> 16) & 0xff] ^
215
+ C6[(int)(state[7] >> 8) & 0xff] ^
216
+ C7[(int)(state[6] ) & 0xff] ^
217
+ K[5];
218
+ L[6] =
219
+ C0[(int)(state[6] >> 56) ] ^
220
+ C1[(int)(state[5] >> 48) & 0xff] ^
221
+ C2[(int)(state[4] >> 40) & 0xff] ^
222
+ C3[(int)(state[3] >> 32) & 0xff] ^
223
+ C4[(int)(state[2] >> 24) & 0xff] ^
224
+ C5[(int)(state[1] >> 16) & 0xff] ^
225
+ C6[(int)(state[0] >> 8) & 0xff] ^
226
+ C7[(int)(state[7] ) & 0xff] ^
227
+ K[6];
228
+ L[7] =
229
+ C0[(int)(state[7] >> 56) ] ^
230
+ C1[(int)(state[6] >> 48) & 0xff] ^
231
+ C2[(int)(state[5] >> 40) & 0xff] ^
232
+ C3[(int)(state[4] >> 32) & 0xff] ^
233
+ C4[(int)(state[3] >> 24) & 0xff] ^
234
+ C5[(int)(state[2] >> 16) & 0xff] ^
235
+ C6[(int)(state[1] >> 8) & 0xff] ^
236
+ C7[(int)(state[0] ) & 0xff] ^
237
+ K[7];
238
+ state[0] = L[0];
239
+ state[1] = L[1];
240
+ state[2] = L[2];
241
+ state[3] = L[3];
242
+ state[4] = L[4];
243
+ state[5] = L[5];
244
+ state[6] = L[6];
245
+ state[7] = L[7];
246
+ }
247
+
248
+ /*
249
+ * apply the Miyaguchi-Preneel compression function:
250
+ */
251
+ structpointer->hash[0] ^= state[0] ^ block[0];
252
+ structpointer->hash[1] ^= state[1] ^ block[1];
253
+ structpointer->hash[2] ^= state[2] ^ block[2];
254
+ structpointer->hash[3] ^= state[3] ^ block[3];
255
+ structpointer->hash[4] ^= state[4] ^ block[4];
256
+ structpointer->hash[5] ^= state[5] ^ block[5];
257
+ structpointer->hash[6] ^= state[6] ^ block[6];
258
+ structpointer->hash[7] ^= state[7] ^ block[7];
259
+ }
260
+
261
+ WP_Struct *
262
+ WP_Create() {
263
+ WP_Struct *wp;
264
+
265
+ wp = (WP_Struct *) malloc(sizeof(WP_Struct));
266
+ if (wp != NULL) {
267
+ WP_Init(wp);
268
+ }
269
+ return wp;
270
+ }
271
+
272
+ void
273
+ WP_Init(WP_Struct *wp) {
274
+ int i;
275
+
276
+ memset(wp->bitLength, 0, 32);
277
+ wp->bufferBits = wp->bufferPos = 0;
278
+ wp->buffer[0] = 0; /* it's only necessary to cleanup buffer[bufferPos] */
279
+ for (i = 0; i < 8; i++) {
280
+ wp->hash[i] = 0L; /* initial value */
281
+ }
282
+ }
283
+
284
+ void WP_Add(const unsigned char * const source,
285
+ unsigned long sourceBits,
286
+ WP_Struct * const structpointer) {
287
+ /*
288
+ sourcePos
289
+ |
290
+ +-------+-------+-------
291
+ ||||||||||||||||||||| source
292
+ +-------+-------+-------
293
+ +-------+-------+-------+-------+-------+-------
294
+ |||||||||||||||||||||| buffer
295
+ +-------+-------+-------+-------+-------+-------
296
+ |
297
+ bufferPos
298
+ */
299
+ int sourcePos = 0; /* index of leftmost source u8 containing data (1 to 8 bits). */
300
+ int sourceGap = (8 - ((int)sourceBits & 7)) & 7; /* space on source[sourcePos]. */
301
+ int bufferRem = structpointer->bufferBits & 7; /* occupied bits on buffer[bufferPos]. */
302
+ int i;
303
+ u32 b, carry;
304
+ u8 *buffer = structpointer->buffer;
305
+ u8 *bitLength = structpointer->bitLength;
306
+ int bufferBits = structpointer->bufferBits;
307
+ int bufferPos = structpointer->bufferPos;
308
+
309
+ /*
310
+ * This method maintains the invariant: bufferBits < DIGESTBITS
311
+ */
312
+
313
+ /*
314
+ * tally the length of the added data:
315
+ */
316
+ u64 value = sourceBits;
317
+ for (i = 31, carry = 0; i >= 0 && (carry != 0 || value != LL(0)); i--) {
318
+ carry += bitLength[i] + ((u32)value & 0xff);
319
+ bitLength[i] = (u8)carry;
320
+ carry >>= 8;
321
+ value >>= 8;
322
+ }
323
+ /*
324
+ * process data in chunks of 8 bits (a more efficient approach would be to take whole-word chunks):
325
+ */
326
+ while (sourceBits > 8) {
327
+ /* N.B. at least source[sourcePos] and source[sourcePos+1] contain data. */
328
+ /*
329
+ * take a byte from the source:
330
+ */
331
+ b = ((source[sourcePos] << sourceGap) & 0xff) |
332
+ ((source[sourcePos + 1] & 0xff) >> (8 - sourceGap));
333
+ /*
334
+ * process this byte:
335
+ */
336
+ buffer[bufferPos++] |= (u8)(b >> bufferRem);
337
+ bufferBits += 8 - bufferRem; /* bufferBits = 8*bufferPos; */
338
+ if (bufferBits == DIGESTBITS) {
339
+ /*
340
+ * process data block:
341
+ */
342
+ processBuffer(structpointer);
343
+ /*
344
+ * reset buffer:
345
+ */
346
+ bufferBits = bufferPos = 0;
347
+ }
348
+ buffer[bufferPos] = b << (8 - bufferRem);
349
+ bufferBits += bufferRem;
350
+ /*
351
+ * proceed to remaining data:
352
+ */
353
+ sourceBits -= 8;
354
+ sourcePos++;
355
+ }
356
+ /* now 0 <= sourceBits <= 8;
357
+ * furthermore, all data (if any is left) is in source[sourcePos].
358
+ */
359
+ if (sourceBits > 0) {
360
+ b = (source[sourcePos] << sourceGap) & 0xff; /* bits are left-justified on b. */
361
+ /*
362
+ * process the remaining bits:
363
+ */
364
+ buffer[bufferPos] |= b >> bufferRem;
365
+ } else {
366
+ b = 0;
367
+ }
368
+ if (bufferRem + sourceBits < 8) {
369
+ /*
370
+ * all remaining data fits on buffer[bufferPos],
371
+ * and there still remains some space.
372
+ */
373
+ bufferBits += sourceBits;
374
+ } else {
375
+ /*
376
+ * buffer[bufferPos] is full:
377
+ */
378
+ bufferPos++;
379
+ bufferBits += 8 - bufferRem; /* bufferBits = 8*bufferPos; */
380
+ sourceBits -= 8 - bufferRem;
381
+ /* now 0 <= sourceBits < 8;
382
+ * furthermore, all data (if any is left) is in source[sourcePos].
383
+ */
384
+ if (bufferBits == DIGESTBITS) {
385
+ /*
386
+ * process data block:
387
+ */
388
+ processBuffer(structpointer);
389
+ /*
390
+ * reset buffer:
391
+ */
392
+ bufferBits = bufferPos = 0;
393
+ }
394
+ buffer[bufferPos] = b << (8 - bufferRem);
395
+ bufferBits += (int)sourceBits;
396
+ }
397
+ structpointer->bufferBits = bufferBits;
398
+ structpointer->bufferPos = bufferPos;
399
+ }
400
+
401
+ void WP_Finalize(WP_Struct * const structpointer,
402
+ unsigned char * const result) {
403
+ int i;
404
+ u8 *buffer = structpointer->buffer;
405
+ u8 *bitLength = structpointer->bitLength;
406
+ int bufferBits = structpointer->bufferBits;
407
+ int bufferPos = structpointer->bufferPos;
408
+ u8 *digest = result;
409
+
410
+ /*
411
+ * This method uses the invariant: bufferBits < DIGESTBITS
412
+ */
413
+
414
+ /*
415
+ * append a '1'-bit:
416
+ */
417
+ buffer[bufferPos] |= 0x80U >> (bufferBits & 7);
418
+ bufferPos++; /* all remaining bits on the current u8 are set to zero. */
419
+ /*
420
+ * pad with zero bits to complete (N*WBLOCKBITS - LENGTHBITS) bits:
421
+ */
422
+ if (bufferPos > WBLOCKBYTES - LENGTHBYTES) {
423
+ if (bufferPos < WBLOCKBYTES) {
424
+ memset(&buffer[bufferPos], 0, WBLOCKBYTES - bufferPos);
425
+ }
426
+ /*
427
+ * process data block:
428
+ */
429
+ processBuffer(structpointer);
430
+ /*
431
+ * reset buffer:
432
+ */
433
+ bufferPos = 0;
434
+ }
435
+ if (bufferPos < WBLOCKBYTES - LENGTHBYTES) {
436
+ memset(&buffer[bufferPos], 0, (WBLOCKBYTES - LENGTHBYTES) - bufferPos);
437
+ }
438
+ bufferPos = WBLOCKBYTES - LENGTHBYTES;
439
+ /*
440
+ * append bit length of hashed data:
441
+ */
442
+ memcpy(&buffer[WBLOCKBYTES - LENGTHBYTES], bitLength, LENGTHBYTES);
443
+ /*
444
+ * process data block:
445
+ */
446
+ processBuffer(structpointer);
447
+ /*
448
+ * return the completed message digest:
449
+ */
450
+ for (i = 0; i < DIGESTBYTES/8; i++) {
451
+ digest[0] = (u8)(structpointer->hash[i] >> 56);
452
+ digest[1] = (u8)(structpointer->hash[i] >> 48);
453
+ digest[2] = (u8)(structpointer->hash[i] >> 40);
454
+ digest[3] = (u8)(structpointer->hash[i] >> 32);
455
+ digest[4] = (u8)(structpointer->hash[i] >> 24);
456
+ digest[5] = (u8)(structpointer->hash[i] >> 16);
457
+ digest[6] = (u8)(structpointer->hash[i] >> 8);
458
+ digest[7] = (u8)(structpointer->hash[i] );
459
+ digest += 8;
460
+ }
461
+ structpointer->bufferBits = bufferBits;
462
+ structpointer->bufferPos = bufferPos;
463
+ }
464
+
465
+ void
466
+ WP_Free(WP_Struct *wp) {
467
+ free(wp);
468
+ }
469
+
470
+
471
+ #ifdef __cplusplus
472
+ }
473
+ #endif