passwordping 1.0.0 → 1.0.1
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/Gemfile +1 -1
- data/Rakefile +17 -0
- data/ext/argon2-wrapper/extconf.rb +1 -1
- data/ext/digest/whirlpool/extconf.rb +10 -0
- data/ext/digest/whirlpool/whirlpool-algorithm.c +476 -0
- data/ext/digest/whirlpool/whirlpool-algorithm.h +86 -0
- data/ext/digest/whirlpool/whirlpool-constants.h +1116 -0
- data/ext/digest/whirlpool/whirlpool-portability.h +142 -0
- data/ext/digest/whirlpool/whirlpool.c +51 -0
- data/lib/digest/whirlpool.bundle +0 -0
- data/lib/passwordping.rb +2 -2
- data/lib/passwordping/hashing.rb +66 -9
- data/lib/passwordping/version.rb +1 -1
- data/passwordping.gemspec +2 -2
- metadata +30 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31d4b9fb4475b1fabca8031eea2650e53f4c0102
|
4
|
+
data.tar.gz: 724759e58a8f0c95a3fb9cd7d57b7188d0d1335f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e71c6c80d4284d94c6865ddccf7163ada73f7e8a5bf98bbb0e4bd30c786f7ad70bd9fb13245624ab26436d1aa798086540599d2a8faf25fab7fee4c5fa37886
|
7
|
+
data.tar.gz: e3c9ec3cefc0de5bf8d2cc68a6b39c3ee13334559d1c9134a2a000df1e0993c5da0058c783042d672895b69e0c9201fe412f15b55dadc4754decb4f1229705fa
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rake/testtask"
|
3
|
+
require "rake/clean"
|
4
|
+
require 'rake/extensiontask'
|
5
|
+
|
6
|
+
gemspec = Bundler::GemHelper.gemspec
|
7
|
+
|
8
|
+
CLEAN.include [ 'lib/digest/whirlpool.*', 'ext/argon2-wrapper/libargon2-wrapper.*' ]
|
9
|
+
CLOBBER.include [ 'ext/digest/whirlpool/mkmf.log', 'ext/digest/whirlpool/Makefile' ]
|
3
10
|
|
4
11
|
Rake::TestTask.new(:test) do |t|
|
5
12
|
t.libs << "test"
|
@@ -8,4 +15,14 @@ Rake::TestTask.new(:test) do |t|
|
|
8
15
|
t.test_files = FileList['test/**/*_test.rb']
|
9
16
|
end
|
10
17
|
|
18
|
+
Rake::ExtensionTask.new('whirlpool', gemspec) do |ext|
|
19
|
+
ext.ext_dir = 'ext/digest/whirlpool'
|
20
|
+
ext.lib_dir = 'lib/digest'
|
21
|
+
end
|
22
|
+
|
23
|
+
# Rake::ExtensionTask.new('argon2-wrapper', gemspec) do |ext|
|
24
|
+
# ext.ext_dir = 'ext/argon2-wrapper'
|
25
|
+
# ext.lib_dir = 'lib/passwordping'
|
26
|
+
# end
|
27
|
+
|
11
28
|
task :default => :test
|
@@ -1 +1 @@
|
|
1
|
-
#
|
1
|
+
#placeholder
|
@@ -0,0 +1,476 @@
|
|
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
|
+
int
|
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
|
+
return 1;
|
283
|
+
}
|
284
|
+
|
285
|
+
void WP_Add(const unsigned char * const source,
|
286
|
+
unsigned long sourceBits,
|
287
|
+
WP_Struct * const structpointer) {
|
288
|
+
/*
|
289
|
+
sourcePos
|
290
|
+
|
|
291
|
+
+-------+-------+-------
|
292
|
+
||||||||||||||||||||| source
|
293
|
+
+-------+-------+-------
|
294
|
+
+-------+-------+-------+-------+-------+-------
|
295
|
+
|||||||||||||||||||||| buffer
|
296
|
+
+-------+-------+-------+-------+-------+-------
|
297
|
+
|
|
298
|
+
bufferPos
|
299
|
+
*/
|
300
|
+
int sourcePos = 0; /* index of leftmost source u8 containing data (1 to 8 bits). */
|
301
|
+
int sourceGap = (8 - ((int)sourceBits & 7)) & 7; /* space on source[sourcePos]. */
|
302
|
+
int bufferRem = structpointer->bufferBits & 7; /* occupied bits on buffer[bufferPos]. */
|
303
|
+
int i;
|
304
|
+
u32 b, carry;
|
305
|
+
u8 *buffer = structpointer->buffer;
|
306
|
+
u8 *bitLength = structpointer->bitLength;
|
307
|
+
int bufferBits = structpointer->bufferBits;
|
308
|
+
int bufferPos = structpointer->bufferPos;
|
309
|
+
|
310
|
+
/*
|
311
|
+
* This method maintains the invariant: bufferBits < DIGESTBITS
|
312
|
+
*/
|
313
|
+
|
314
|
+
/*
|
315
|
+
* tally the length of the added data:
|
316
|
+
*/
|
317
|
+
u64 value = sourceBits;
|
318
|
+
for (i = 31, carry = 0; i >= 0 && (carry != 0 || value != LL(0)); i--) {
|
319
|
+
carry += bitLength[i] + ((u32)value & 0xff);
|
320
|
+
bitLength[i] = (u8)carry;
|
321
|
+
carry >>= 8;
|
322
|
+
value >>= 8;
|
323
|
+
}
|
324
|
+
/*
|
325
|
+
* process data in chunks of 8 bits (a more efficient approach would be to take whole-word chunks):
|
326
|
+
*/
|
327
|
+
while (sourceBits > 8) {
|
328
|
+
/* N.B. at least source[sourcePos] and source[sourcePos+1] contain data. */
|
329
|
+
/*
|
330
|
+
* take a byte from the source:
|
331
|
+
*/
|
332
|
+
b = ((source[sourcePos] << sourceGap) & 0xff) |
|
333
|
+
((source[sourcePos + 1] & 0xff) >> (8 - sourceGap));
|
334
|
+
/*
|
335
|
+
* process this byte:
|
336
|
+
*/
|
337
|
+
buffer[bufferPos++] |= (u8)(b >> bufferRem);
|
338
|
+
bufferBits += 8 - bufferRem; /* bufferBits = 8*bufferPos; */
|
339
|
+
if (bufferBits == DIGESTBITS) {
|
340
|
+
/*
|
341
|
+
* process data block:
|
342
|
+
*/
|
343
|
+
processBuffer(structpointer);
|
344
|
+
/*
|
345
|
+
* reset buffer:
|
346
|
+
*/
|
347
|
+
bufferBits = bufferPos = 0;
|
348
|
+
}
|
349
|
+
buffer[bufferPos] = b << (8 - bufferRem);
|
350
|
+
bufferBits += bufferRem;
|
351
|
+
/*
|
352
|
+
* proceed to remaining data:
|
353
|
+
*/
|
354
|
+
sourceBits -= 8;
|
355
|
+
sourcePos++;
|
356
|
+
}
|
357
|
+
/* now 0 <= sourceBits <= 8;
|
358
|
+
* furthermore, all data (if any is left) is in source[sourcePos].
|
359
|
+
*/
|
360
|
+
if (sourceBits > 0) {
|
361
|
+
b = (source[sourcePos] << sourceGap) & 0xff; /* bits are left-justified on b. */
|
362
|
+
/*
|
363
|
+
* process the remaining bits:
|
364
|
+
*/
|
365
|
+
buffer[bufferPos] |= b >> bufferRem;
|
366
|
+
} else {
|
367
|
+
b = 0;
|
368
|
+
}
|
369
|
+
if (bufferRem + sourceBits < 8) {
|
370
|
+
/*
|
371
|
+
* all remaining data fits on buffer[bufferPos],
|
372
|
+
* and there still remains some space.
|
373
|
+
*/
|
374
|
+
bufferBits += sourceBits;
|
375
|
+
} else {
|
376
|
+
/*
|
377
|
+
* buffer[bufferPos] is full:
|
378
|
+
*/
|
379
|
+
bufferPos++;
|
380
|
+
bufferBits += 8 - bufferRem; /* bufferBits = 8*bufferPos; */
|
381
|
+
sourceBits -= 8 - bufferRem;
|
382
|
+
/* now 0 <= sourceBits < 8;
|
383
|
+
* furthermore, all data (if any is left) is in source[sourcePos].
|
384
|
+
*/
|
385
|
+
if (bufferBits == DIGESTBITS) {
|
386
|
+
/*
|
387
|
+
* process data block:
|
388
|
+
*/
|
389
|
+
processBuffer(structpointer);
|
390
|
+
/*
|
391
|
+
* reset buffer:
|
392
|
+
*/
|
393
|
+
bufferBits = bufferPos = 0;
|
394
|
+
}
|
395
|
+
buffer[bufferPos] = b << (8 - bufferRem);
|
396
|
+
bufferBits += (int)sourceBits;
|
397
|
+
}
|
398
|
+
structpointer->bufferBits = bufferBits;
|
399
|
+
structpointer->bufferPos = bufferPos;
|
400
|
+
}
|
401
|
+
|
402
|
+
int WP_Finalize(WP_Struct * const structpointer,
|
403
|
+
unsigned char * const result) {
|
404
|
+
int i;
|
405
|
+
u8 *buffer = structpointer->buffer;
|
406
|
+
u8 *bitLength = structpointer->bitLength;
|
407
|
+
int bufferBits = structpointer->bufferBits;
|
408
|
+
int bufferPos = structpointer->bufferPos;
|
409
|
+
u8 *digest = result;
|
410
|
+
|
411
|
+
/*
|
412
|
+
* This method uses the invariant: bufferBits < DIGESTBITS
|
413
|
+
*/
|
414
|
+
|
415
|
+
/*
|
416
|
+
* append a '1'-bit:
|
417
|
+
*/
|
418
|
+
buffer[bufferPos] |= 0x80U >> (bufferBits & 7);
|
419
|
+
bufferPos++; /* all remaining bits on the current u8 are set to zero. */
|
420
|
+
/*
|
421
|
+
* pad with zero bits to complete (N*WBLOCKBITS - LENGTHBITS) bits:
|
422
|
+
*/
|
423
|
+
if (bufferPos > WBLOCKBYTES - LENGTHBYTES) {
|
424
|
+
if (bufferPos < WBLOCKBYTES) {
|
425
|
+
memset(&buffer[bufferPos], 0, WBLOCKBYTES - bufferPos);
|
426
|
+
}
|
427
|
+
/*
|
428
|
+
* process data block:
|
429
|
+
*/
|
430
|
+
processBuffer(structpointer);
|
431
|
+
/*
|
432
|
+
* reset buffer:
|
433
|
+
*/
|
434
|
+
bufferPos = 0;
|
435
|
+
}
|
436
|
+
if (bufferPos < WBLOCKBYTES - LENGTHBYTES) {
|
437
|
+
memset(&buffer[bufferPos], 0, (WBLOCKBYTES - LENGTHBYTES) - bufferPos);
|
438
|
+
}
|
439
|
+
bufferPos = WBLOCKBYTES - LENGTHBYTES;
|
440
|
+
/*
|
441
|
+
* append bit length of hashed data:
|
442
|
+
*/
|
443
|
+
memcpy(&buffer[WBLOCKBYTES - LENGTHBYTES], bitLength, LENGTHBYTES);
|
444
|
+
/*
|
445
|
+
* process data block:
|
446
|
+
*/
|
447
|
+
processBuffer(structpointer);
|
448
|
+
/*
|
449
|
+
* return the completed message digest:
|
450
|
+
*/
|
451
|
+
for (i = 0; i < DIGESTBYTES/8; i++) {
|
452
|
+
digest[0] = (u8)(structpointer->hash[i] >> 56);
|
453
|
+
digest[1] = (u8)(structpointer->hash[i] >> 48);
|
454
|
+
digest[2] = (u8)(structpointer->hash[i] >> 40);
|
455
|
+
digest[3] = (u8)(structpointer->hash[i] >> 32);
|
456
|
+
digest[4] = (u8)(structpointer->hash[i] >> 24);
|
457
|
+
digest[5] = (u8)(structpointer->hash[i] >> 16);
|
458
|
+
digest[6] = (u8)(structpointer->hash[i] >> 8);
|
459
|
+
digest[7] = (u8)(structpointer->hash[i] );
|
460
|
+
digest += 8;
|
461
|
+
}
|
462
|
+
structpointer->bufferBits = bufferBits;
|
463
|
+
structpointer->bufferPos = bufferPos;
|
464
|
+
|
465
|
+
return 1;
|
466
|
+
}
|
467
|
+
|
468
|
+
void
|
469
|
+
WP_Free(WP_Struct *wp) {
|
470
|
+
free(wp);
|
471
|
+
}
|
472
|
+
|
473
|
+
|
474
|
+
#ifdef __cplusplus
|
475
|
+
}
|
476
|
+
#endif
|