digest-whirlpool 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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