yong-stropheruby 0.0.5

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/ext/sha1.c ADDED
@@ -0,0 +1,389 @@
1
+ /** @file
2
+ * SHA-1 hash.
3
+ */
4
+
5
+ /*
6
+ SHA-1 in C
7
+ By Steve Reid <sreid@sea-to-sky.net>
8
+ 100% Public Domain
9
+
10
+ -----------------
11
+ Modified 7/98
12
+ By James H. Brown <jbrown@burgoyne.com>
13
+ Still 100% Public Domain
14
+
15
+ Corrected a problem which generated improper hash values on 16 bit machines
16
+ Routine SHA1Update changed from
17
+ void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
18
+ len)
19
+ to
20
+ void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
21
+ long len)
22
+
23
+ The 'len' parameter was declared an int which works fine on 32 bit machines.
24
+ However, on 16 bit machines an int is too small for the shifts being done
25
+ against
26
+ it. This caused the hash function to generate incorrect values if len was
27
+ greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
28
+
29
+ Since the file IO in main() reads 16K at a time, any file 8K or larger would
30
+ be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
31
+ "a"s).
32
+
33
+ I also changed the declaration of variables i & j in SHA1Update to
34
+ unsigned long from unsigned int for the same reason.
35
+
36
+ These changes should make no difference to any 32 bit implementations since
37
+ an
38
+ int and a long are the same size in those environments.
39
+
40
+ --
41
+ I also corrected a few compiler warnings generated by Borland C.
42
+ 1. Added #include <process.h> for exit() prototype
43
+ 2. Removed unused variable 'j' in SHA1Final
44
+ 3. Changed exit(0) to return(0) at end of main.
45
+
46
+ ALL changes I made can be located by searching for comments containing 'JHB'
47
+ -----------------
48
+ Modified 8/98
49
+ By Steve Reid <sreid@sea-to-sky.net>
50
+ Still 100% public domain
51
+
52
+ 1- Removed #include <process.h> and used return() instead of exit()
53
+ 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
54
+ 3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
55
+
56
+ -----------------
57
+ Modified 4/01
58
+ By Saul Kravitz <Saul.Kravitz@celera.com>
59
+ Still 100% PD
60
+ Modified to run on Compaq Alpha hardware.
61
+
62
+ -----------------
63
+ Modified 07/2002
64
+ By Ralph Giles <giles@artofcode.com>
65
+ Still 100% public domain
66
+ modified for use with stdint types, autoconf
67
+ code cleanup, removed attribution comments
68
+ switched SHA1Final() argument order for consistency
69
+ use SHA1_ prefix for public api
70
+ move public api to sha1.h
71
+ */
72
+
73
+ /*
74
+ Test Vectors (from FIPS PUB 180-1)
75
+ "abc"
76
+ A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
77
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
78
+ 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
79
+ A million repetitions of "a"
80
+ 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
81
+ */
82
+
83
+ /* #define SHA1HANDSOFF */
84
+
85
+ #include <stdio.h>
86
+ #include <string.h>
87
+
88
+ /* make sure the stdint.h types are available */
89
+ #if defined(_MSC_VER) /* Microsoft Visual C++ */
90
+ typedef signed char int8_t;
91
+ typedef short int int16_t;
92
+ typedef int int32_t;
93
+ typedef __int64 int64_t;
94
+
95
+ typedef unsigned char uint8_t;
96
+ typedef unsigned short int uint16_t;
97
+ typedef unsigned int uint32_t;
98
+ /* no uint64_t */
99
+ #else
100
+ #include <stdint.h>
101
+ #endif
102
+
103
+ #include "sha1.h"
104
+
105
+ void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
106
+
107
+ #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
108
+
109
+ /* blk0() and blk() perform the initial expand. */
110
+ /* I got the idea of expanding during the round function from SSLeay */
111
+ /* FIXME: can we do this in an endian-proof way? */
112
+ #ifdef WORDS_BIGENDIAN
113
+ #define blk0(i) block->l[i]
114
+ #else
115
+ #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
116
+ |(rol(block->l[i],8)&0x00FF00FF))
117
+ #endif
118
+ #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
119
+ ^block->l[(i+2)&15]^block->l[i&15],1))
120
+
121
+ /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
122
+ #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
123
+ #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
124
+ #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
125
+ #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
126
+ #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
127
+
128
+
129
+ #ifdef VERBOSE /* SAK */
130
+ void SHAPrintContext(SHA1_CTX *context, char *msg){
131
+ printf("%s (%d,%d) %x %x %x %x %x\n",
132
+ msg,
133
+ context->count[0], context->count[1],
134
+ context->state[0],
135
+ context->state[1],
136
+ context->state[2],
137
+ context->state[3],
138
+ context->state[4]);
139
+ }
140
+ #endif /* VERBOSE */
141
+
142
+ /* Hash a single 512-bit block. This is the core of the algorithm. */
143
+ void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
144
+ {
145
+ uint32_t a, b, c, d, e;
146
+ typedef union {
147
+ uint8_t c[64];
148
+ uint32_t l[16];
149
+ } CHAR64LONG16;
150
+ CHAR64LONG16* block;
151
+
152
+ #ifdef SHA1HANDSOFF
153
+ static uint8_t workspace[64];
154
+ block = (CHAR64LONG16*)workspace;
155
+ memcpy(block, buffer, 64);
156
+ #else
157
+ block = (CHAR64LONG16*)buffer;
158
+ #endif
159
+
160
+ /* Copy context->state[] to working vars */
161
+ a = state[0];
162
+ b = state[1];
163
+ c = state[2];
164
+ d = state[3];
165
+ e = state[4];
166
+
167
+ /* 4 rounds of 20 operations each. Loop unrolled. */
168
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
169
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
170
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
171
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
172
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
173
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
174
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
175
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
176
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
177
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
178
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
179
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
180
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
181
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
182
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
183
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
184
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
185
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
186
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
187
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
188
+
189
+ /* Add the working vars back into context.state[] */
190
+ state[0] += a;
191
+ state[1] += b;
192
+ state[2] += c;
193
+ state[3] += d;
194
+ state[4] += e;
195
+
196
+ /* Wipe variables */
197
+ a = b = c = d = e = 0;
198
+ }
199
+
200
+
201
+ /* SHA1Init - Initialize new context */
202
+ void SHA1_Init(SHA1_CTX* context)
203
+ {
204
+ /* SHA1 initialization constants */
205
+ context->state[0] = 0x67452301;
206
+ context->state[1] = 0xEFCDAB89;
207
+ context->state[2] = 0x98BADCFE;
208
+ context->state[3] = 0x10325476;
209
+ context->state[4] = 0xC3D2E1F0;
210
+ context->count[0] = context->count[1] = 0;
211
+ }
212
+
213
+
214
+ /* Run your data through this. */
215
+ void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len)
216
+ {
217
+ size_t i, j;
218
+
219
+ #ifdef VERBOSE
220
+ SHAPrintContext(context, "before");
221
+ #endif
222
+
223
+ j = (context->count[0] >> 3) & 63;
224
+ if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
225
+ context->count[1] += (len >> 29);
226
+ if ((j + len) > 63) {
227
+ memcpy(&context->buffer[j], data, (i = 64-j));
228
+ SHA1_Transform(context->state, context->buffer);
229
+ for ( ; i + 63 < len; i += 64) {
230
+ SHA1_Transform(context->state, data + i);
231
+ }
232
+ j = 0;
233
+ }
234
+ else i = 0;
235
+ memcpy(&context->buffer[j], &data[i], len - i);
236
+
237
+ #ifdef VERBOSE
238
+ SHAPrintContext(context, "after ");
239
+ #endif
240
+ }
241
+
242
+
243
+ /* Add padding and return the message digest. */
244
+ void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE])
245
+ {
246
+ uint32_t i;
247
+ uint8_t finalcount[8];
248
+
249
+ for (i = 0; i < 8; i++) {
250
+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
251
+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
252
+ }
253
+ SHA1_Update(context, (uint8_t *)"\200", 1);
254
+ while ((context->count[0] & 504) != 448) {
255
+ SHA1_Update(context, (uint8_t *)"\0", 1);
256
+ }
257
+ SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */
258
+ for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
259
+ digest[i] = (uint8_t)
260
+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
261
+ }
262
+
263
+ /* Wipe variables */
264
+ i = 0;
265
+ memset(context->buffer, 0, 64);
266
+ memset(context->state, 0, 20);
267
+ memset(context->count, 0, 8);
268
+ memset(finalcount, 0, 8); /* SWR */
269
+
270
+ #ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
271
+ SHA1_Transform(context->state, context->buffer);
272
+ #endif
273
+ }
274
+
275
+ /*************************************************************/
276
+
277
+ #if 0
278
+ int main(int argc, char** argv)
279
+ {
280
+ int i, j;
281
+ SHA1_CTX context;
282
+ unsigned char digest[SHA1_DIGEST_SIZE], buffer[16384];
283
+ FILE* file;
284
+
285
+ if (argc > 2) {
286
+ puts("Public domain SHA-1 implementation - by Steve Reid <sreid@sea-to-sky.net>");
287
+ puts("Modified for 16 bit environments 7/98 - by James H. Brown <jbrown@burgoyne.com>"); /* JHB */
288
+ puts("Produces the SHA-1 hash of a file, or stdin if no file is specified.");
289
+ return(0);
290
+ }
291
+ if (argc < 2) {
292
+ file = stdin;
293
+ }
294
+ else {
295
+ if (!(file = fopen(argv[1], "rb"))) {
296
+ fputs("Unable to open file.", stderr);
297
+ return(-1);
298
+ }
299
+ }
300
+ SHA1_Init(&context);
301
+ while (!feof(file)) { /* note: what if ferror(file) */
302
+ i = fread(buffer, 1, 16384, file);
303
+ SHA1_Update(&context, buffer, i);
304
+ }
305
+ SHA1_Final(&context, digest);
306
+ fclose(file);
307
+ for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) {
308
+ for (j = 0; j < 4; j++) {
309
+ printf("%02X", digest[i*4+j]);
310
+ }
311
+ putchar(' ');
312
+ }
313
+ putchar('\n');
314
+ return(0); /* JHB */
315
+ }
316
+ #endif
317
+
318
+ /* self test */
319
+
320
+ #ifdef TEST
321
+
322
+ static char *test_data[] = {
323
+ "abc",
324
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
325
+ "A million repetitions of 'a'"};
326
+ static char *test_results[] = {
327
+ "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D",
328
+ "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1",
329
+ "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F"};
330
+
331
+
332
+ void digest_to_hex(const uint8_t digest[SHA1_DIGEST_SIZE], char *output)
333
+ {
334
+ int i,j;
335
+ char *c = output;
336
+
337
+ for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) {
338
+ for (j = 0; j < 4; j++) {
339
+ sprintf(c,"%02X", digest[i*4+j]);
340
+ c += 2;
341
+ }
342
+ sprintf(c, " ");
343
+ c += 1;
344
+ }
345
+ *(c - 1) = '\0';
346
+ }
347
+
348
+ int main(int argc, char** argv)
349
+ {
350
+ int k;
351
+ SHA1_CTX context;
352
+ uint8_t digest[20];
353
+ char output[80];
354
+
355
+ fprintf(stdout, "verifying SHA-1 implementation... ");
356
+
357
+ for (k = 0; k < 2; k++){
358
+ SHA1_Init(&context);
359
+ SHA1_Update(&context, (uint8_t*)test_data[k], strlen(test_data[k]));
360
+ SHA1_Final(&context, digest);
361
+ digest_to_hex(digest, output);
362
+
363
+ if (strcmp(output, test_results[k])) {
364
+ fprintf(stdout, "FAIL\n");
365
+ fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[k]);
366
+ fprintf(stderr,"\t%s returned\n", output);
367
+ fprintf(stderr,"\t%s is correct\n", test_results[k]);
368
+ return (1);
369
+ }
370
+ }
371
+ /* million 'a' vector we feed separately */
372
+ SHA1_Init(&context);
373
+ for (k = 0; k < 1000000; k++)
374
+ SHA1_Update(&context, (uint8_t*)"a", 1);
375
+ SHA1_Final(&context, digest);
376
+ digest_to_hex(digest, output);
377
+ if (strcmp(output, test_results[2])) {
378
+ fprintf(stdout, "FAIL\n");
379
+ fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[2]);
380
+ fprintf(stderr,"\t%s returned\n", output);
381
+ fprintf(stderr,"\t%s is correct\n", test_results[2]);
382
+ return (1);
383
+ }
384
+
385
+ /* success */
386
+ fprintf(stdout, "ok\n");
387
+ return(0);
388
+ }
389
+ #endif /* TEST */
data/ext/sha1.h ADDED
@@ -0,0 +1,31 @@
1
+ /* public api for steve reid's public domain SHA-1 implementation */
2
+ /* this file is in the public domain */
3
+
4
+ /** @file
5
+ * SHA-1 hash API.
6
+ */
7
+
8
+ #ifndef __SHA1_H
9
+ #define __SHA1_H
10
+
11
+ #ifdef __cplusplus
12
+ extern "C" {
13
+ #endif
14
+
15
+ typedef struct {
16
+ uint32_t state[5];
17
+ uint32_t count[2];
18
+ uint8_t buffer[64];
19
+ } SHA1_CTX;
20
+
21
+ #define SHA1_DIGEST_SIZE 20
22
+
23
+ void SHA1_Init(SHA1_CTX* context);
24
+ void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len);
25
+ void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]);
26
+
27
+ #ifdef __cplusplus
28
+ }
29
+ #endif
30
+
31
+ #endif /* __SHA1_H */