ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Digest-Hashcash/Hashcash.xs
(Generate patch)

Comparing Digest-Hashcash/Hashcash.xs (file contents):
Revision 1.6 by root, Sun Jun 27 13:30:43 2004 UTC vs.
Revision 1.8 by root, Wed Jul 22 10:33:08 2015 UTC

3#include "XSUB.h" 3#include "XSUB.h"
4 4
5#include <time.h> 5#include <time.h>
6#include <stdlib.h> 6#include <stdlib.h>
7#include <stdint.h> 7#include <stdint.h>
8
9#include "perlmulticore.h"
8 10
9/* NIST Secure Hash Algorithm */ 11/* NIST Secure Hash Algorithm */
10/* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> */ 12/* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> */
11/* from Peter C. Gutmann's implementation as found in */ 13/* from Peter C. Gutmann's implementation as found in */
12/* Applied Cryptography by Bruce Schneier */ 14/* Applied Cryptography by Bruce Schneier */
51#define a_const __attribute__((__const__)) 53#define a_const __attribute__((__const__))
52 54
53/* Useful defines & typedefs */ 55/* Useful defines & typedefs */
54 56
55#if defined(U64TYPE) && (defined(USE_64_BIT_INT) || ((BYTEORDER != 0x1234) && (BYTEORDER != 0x4321))) 57#if defined(U64TYPE) && (defined(USE_64_BIT_INT) || ((BYTEORDER != 0x1234) && (BYTEORDER != 0x4321)))
56typedef U64TYPE ULONG; 58typedef U64TYPE XULONG;
57# if BYTEORDER == 0x1234 59# if BYTEORDER == 0x1234
58# undef BYTEORDER 60# undef BYTEORDER
59# define BYTEORDER 0x12345678 61# define BYTEORDER 0x12345678
60# elif BYTEORDER == 0x4321 62# elif BYTEORDER == 0x4321
61# undef BYTEORDER 63# undef BYTEORDER
62# define BYTEORDER 0x87654321 64# define BYTEORDER 0x87654321
63# endif 65# endif
64#else 66#else
65typedef uint_fast32_t ULONG; /* 32-or-more-bit quantity */ 67typedef uint_fast32_t XULONG; /* 32-or-more-bit quantity */
66#endif 68#endif
67 69
68#if GCCX86ASM 70#if GCCX86ASM
69# define zprefix(n) ({ int _r; __asm__ ("bsrl %1, %0" : "=r" (_r) : "r" (n)); 31 - _r ; }) 71# define zprefix(n) ({ int _r; __asm__ ("bsrl %1, %0" : "=r" (_r) : "r" (n)); 31 - _r ; })
70#elif __GNUC__ > 2 && __GNUC_MINOR__ > 3 72#elif __GNUC__ > 2 && __GNUC_MINOR__ > 3
71# define zprefix(n) (__extension__ ({ uint32_t n__ = (n); n ? __builtin_clz (n) : 32; })) 73# define zprefix(n) (__extension__ ({ uint32_t n__ = (n); n ? __builtin_clz (n) : 32; }))
72#else 74#else
73static int a_const zprefix (ULONG n) 75static int a_const zprefix (U32 n)
74{ 76{
75 static char zp[256] = 77 static char zp[256] =
76 { 78 {
77 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 79 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
78 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 80 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
102 104
103#define SHA_BLOCKSIZE 64 105#define SHA_BLOCKSIZE 64
104#define SHA_DIGESTSIZE 20 106#define SHA_DIGESTSIZE 20
105 107
106typedef struct { 108typedef struct {
107 ULONG digest[5]; /* message digest */ 109 U32 digest[5]; /* message digest */
108 ULONG count; /* 32-bit bit count */ 110 U32 count; /* 32-bit bit count */
109 int local; /* unprocessed amount in data */ 111 int local; /* unprocessed amount in data */
110 U8 data[SHA_BLOCKSIZE]; /* SHA data buffer */ 112 U8 data[SHA_BLOCKSIZE]; /* SHA data buffer */
111} SHA_INFO; 113} SHA_INFO;
112 114
113 115
150 152
151static void a_regparm(1) sha_transform(SHA_INFO *restrict sha_info) 153static void a_regparm(1) sha_transform(SHA_INFO *restrict sha_info)
152{ 154{
153 int i; 155 int i;
154 U8 *restrict dp; 156 U8 *restrict dp;
155 ULONG T, A, B, C, D, E, W[80], *restrict WP; 157 U32 A, B, C, D, E, W[80], *restrict WP;
158 XULONG T;
156 159
157 dp = sha_info->data; 160 dp = sha_info->data;
158 161
159#if BYTEORDER == 0x1234 162#if BYTEORDER == 0x1234
160 assert(sizeof(ULONG) == 4); 163 assert(sizeof(XULONG) == 4);
161# ifdef HAS_NTOHL 164# ifdef HAS_NTOHL
162 for (i = 0; i < 16; ++i) { 165 for (i = 0; i < 16; ++i) {
163 T = *((ULONG *) dp); 166 T = *((XULONG *) dp);
164 dp += 4; 167 dp += 4;
165 W[i] = ntohl (T); 168 W[i] = ntohl (T);
166 } 169 }
167# else 170# else
168 for (i = 0; i < 16; ++i) { 171 for (i = 0; i < 16; ++i) {
169 T = *((ULONG *) dp); 172 T = *((XULONG *) dp);
170 dp += 4; 173 dp += 4;
171 W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | 174 W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
172 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); 175 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
173 } 176 }
174# endif 177# endif
175#elif BYTEORDER == 0x4321 178#elif BYTEORDER == 0x4321
176 assert(sizeof(ULONG) == 4); 179 assert(sizeof(XULONG) == 4);
177 for (i = 0; i < 16; ++i) { 180 for (i = 0; i < 16; ++i) {
178 T = *((ULONG *) dp); 181 T = *((XULONG *) dp);
179 dp += 4; 182 dp += 4;
180 W[i] = T32(T); 183 W[i] = T32(T);
181 } 184 }
182#elif BYTEORDER == 0x12345678 185#elif BYTEORDER == 0x12345678
183 assert(sizeof(ULONG) == 8); 186 assert(sizeof(XULONG) == 8);
184 for (i = 0; i < 16; i += 2) { 187 for (i = 0; i < 16; i += 2) {
185 T = *((ULONG *) dp); 188 T = *((XULONG *) dp);
186 dp += 8; 189 dp += 8;
187 W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | 190 W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
188 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); 191 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
189 T >>= 32; 192 T >>= 32;
190 W[i+1] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | 193 W[i+1] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
191 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); 194 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
192 } 195 }
193#elif BYTEORDER == 0x87654321 196#elif BYTEORDER == 0x87654321
194 assert(sizeof(ULONG) == 8); 197 assert(sizeof(XULONG) == 8);
195 for (i = 0; i < 16; i += 2) { 198 for (i = 0; i < 16; i += 2) {
196 T = *((ULONG *) dp); 199 T = *((XULONG *) dp);
197 dp += 8; 200 dp += 8;
198 W[i] = T32(T >> 32); 201 W[i] = T32(T >> 32);
199 W[i+1] = T32(T); 202 W[i+1] = T32(T);
200 } 203 }
201#else 204#else
302 : zprefix (sha_info->digest[1]) + 32; 305 : zprefix (sha_info->digest[1]) + 32;
303} 306}
304 307
305#define TRIALCHAR "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&()*+,-./;<=>?@[]{}^_|" 308#define TRIALCHAR "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&()*+,-./;<=>?@[]{}^_|"
306 309
307static char nextenc[256]; 310static char
311nextenc[256];
308 312
309static char rand_char () 313static char
314rand_char ()
310{ 315{
311 return TRIALCHAR[rand () % sizeof (TRIALCHAR)]; 316 return TRIALCHAR[(int)(Drand01 () * sizeof (TRIALCHAR))];
312} 317}
313 318
314typedef double (*NVTime)(void); 319typedef double (*NVTime)(void);
315 320
316static double simple_nvtime (void) 321static double
322simple_nvtime (void)
317{ 323{
318 return time (0); 324 return time (0);
319} 325}
320 326
321static NVTime get_nvtime (void) 327static NVTime
328get_nvtime (void)
322{ 329{
323 SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0); 330 SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0);
324 331
325 if (svp && SvIOK(*svp)) 332 if (svp && SvIOK(*svp))
326 return INT2PTR(NVTime, SvIV(*svp)); 333 return INT2PTR(NVTime, SvIV(*svp));
404 resource, trial); 411 resource, trial);
405 412
406 if (toklen > 8000) 413 if (toklen > 8000)
407 croak ("token length must be <= 8000 in this implementation\n"); 414 croak ("token length must be <= 8000 in this implementation\n");
408 415
416 perlinterp_release ();
417
409 i = toklen + extrarand; 418 i = toklen + extrarand;
410 while (toklen < i) 419 while (toklen < i)
411 token[toklen++] = rand_char (); 420 token[toklen++] = rand_char ();
412 421
413 sha_init (&ctx1); 422 sha_init (&ctx1);
431 do { 440 do {
432 *s = nextenc [*s]; 441 *s = nextenc [*s];
433 } while (*s++ == 'a'); 442 } while (*s++ == 'a');
434 } 443 }
435 444
445 perlinterp_acquire ();
446
436 RETVAL = newSVpvn (token, toklen); 447 RETVAL = newSVpvn (token, toklen);
437} 448}
438 OUTPUT: 449 OUTPUT:
439 RETVAL 450 RETVAL
440 451

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines