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.4 by root, Mon Oct 20 04:17:05 2003 UTC vs.
Revision 1.7 by root, Tue Jul 21 05:01:01 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 */
17/* pcg: I was tempted to just rip this code off, after all, if you don't 19/* pcg: I was tempted to just rip this code off, after all, if you don't
18 * demand anything I am inclined not to give anything. *Sigh* something 20 * demand anything I am inclined not to give anything. *Sigh* something
19 * kept me from doing it, so here's the truth: I took this code from the 21 * kept me from doing it, so here's the truth: I took this code from the
20 * SHA1 perl module, since it looked reasonably well-crafted. I modified 22 * SHA1 perl module, since it looked reasonably well-crafted. I modified
21 * it here and there, though. 23 * it here and there, though.
24 */
25
26/*
27 * we have lots of micro-optimizations here, this is just for toying
28 * around...
22 */ 29 */
23 30
24/* don't expect _too_ much from compilers for now. */ 31/* don't expect _too_ much from compilers for now. */
25#if __GNUC__ > 2 32#if __GNUC__ > 2
26# define restrict __restrict__ 33# define restrict __restrict__
31#elif __STDC_VERSION__ < 199900 38#elif __STDC_VERSION__ < 199900
32# define restrict 39# define restrict
33# define inline 40# define inline
34#endif 41#endif
35 42
43#if __GNUC__ < 2
44# define __attribute__(x)
45#endif
46
47#ifdef __i386
48# define a_regparm(n) __attribute__((__regparm__(n)))
49#else
50# define a_regparm(n)
51#endif
52
53#define a_const __attribute__((__const__))
54
36/* Useful defines & typedefs */ 55/* Useful defines & typedefs */
37 56
38#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)))
39typedef U64TYPE ULONG; 58typedef U64TYPE ULONG;
40# if BYTEORDER == 0x1234 59# if BYTEORDER == 0x1234
41# undef BYTEORDER 60# undef BYTEORDER
42# define BYTEORDER 0x12345678 61# define BYTEORDER 0x12345678
43# elif BYTEORDER == 0x4321 62# elif BYTEORDER == 0x4321
44# undef BYTEORDER 63# undef BYTEORDER
45# define BYTEORDER 0x87654321 64# define BYTEORDER 0x87654321
46# endif 65# endif
47#else 66#else
48typedef uint_fast32_t ULONG; /* 32-or-more-bit quantity */ 67typedef uint_fast32_t ULONG; /* 32-or-more-bit quantity */
49#endif 68#endif
50 69
51#if GCCX86ASM 70#if GCCX86ASM
52# 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 ; })
53#elif __GNUC__ > 2 && __GNUC_MINOR__ > 3 72#elif __GNUC__ > 2 && __GNUC_MINOR__ > 3
54# 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; }))
55#else 74#else
56static int zprefix (ULONG n) 75static int a_const zprefix (ULONG n)
57{ 76{
58 static char zp[256] = 77 static char zp[256] =
59 { 78 {
60 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,
61 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,
129 B = T32(R32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n); D = R32(D,30) 148 B = T32(R32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n); D = R32(D,30)
130 149
131#define FT(n) \ 150#define FT(n) \
132 A = T32(R32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n); C = R32(C,30) 151 A = T32(R32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n); C = R32(C,30)
133 152
134static void sha_transform(SHA_INFO *restrict sha_info) 153static void a_regparm(1) sha_transform(SHA_INFO *restrict sha_info)
135{ 154{
136 int i; 155 int i;
137 U8 *dp; 156 U8 *restrict dp;
138 ULONG T, A, B, C, D, E, W[80], *restrict WP; 157 ULONG T, A, B, C, D, E, W[80], *restrict WP;
139 158
140 dp = sha_info->data; 159 dp = sha_info->data;
141 160
142#if BYTEORDER == 0x1234 161#if BYTEORDER == 0x1234
285 : zprefix (sha_info->digest[1]) + 32; 304 : zprefix (sha_info->digest[1]) + 32;
286} 305}
287 306
288#define TRIALCHAR "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&()*+,-./;<=>?@[]{}^_|" 307#define TRIALCHAR "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&()*+,-./;<=>?@[]{}^_|"
289 308
290static char nextenc[256]; 309static char
310nextenc[256];
291 311
292static char rand_char () 312static char
313rand_char ()
293{ 314{
294 return TRIALCHAR[rand () % sizeof (TRIALCHAR)]; 315 return TRIALCHAR[(int)(Drand01 () * sizeof (TRIALCHAR))];
295} 316}
296 317
297typedef double (*NVTime)(void); 318typedef double (*NVTime)(void);
298 319
299static double simple_nvtime (void) 320static double
321simple_nvtime (void)
300{ 322{
301 return time (0); 323 return time (0);
302} 324}
303 325
304static NVTime get_nvtime (void) 326static NVTime
327get_nvtime (void)
305{ 328{
306 SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0); 329 SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0);
307 330
308 if (svp && SvIOK(*svp)) 331 if (svp && SvIOK(*svp))
309 return INT2PTR(NVTime, SvIV(*svp)); 332 return INT2PTR(NVTime, SvIV(*svp));
366 int toklen, i; 389 int toklen, i;
367 time_t tstamp = timestamp ? timestamp : time (0); 390 time_t tstamp = timestamp ? timestamp : time (0);
368 struct tm *tm = gmtime (&tstamp); 391 struct tm *tm = gmtime (&tstamp);
369 392
370 New (0, token, 393 New (0, token,
371 1 + 1 // version 394 1 + 1 // version
372 + 12 + 1 // time field sans century 395 + 12 + 1 // time field sans century
373 + strlen (resource) + 1 // ressource 396 + strlen (resource) + 1 // ressource
374 + strlen (trial) + extrarand + 8 + 1 // trial 397 + strlen (trial) + extrarand + 8 + 1 // trial
375 + 1, 398 + 1,
376 char); 399 char);
377 400
378 if (!token) 401 if (!token)
379 croak ("out of memory"); 402 croak ("out of memory");
380 403
381 if (size > 64) 404 if (size > 64)
386 tm->tm_hour, tm->tm_min, tm->tm_sec, 409 tm->tm_hour, tm->tm_min, tm->tm_sec,
387 resource, trial); 410 resource, trial);
388 411
389 if (toklen > 8000) 412 if (toklen > 8000)
390 croak ("token length must be <= 8000 in this implementation\n"); 413 croak ("token length must be <= 8000 in this implementation\n");
414
415 perlinterp_release ();
391 416
392 i = toklen + extrarand; 417 i = toklen + extrarand;
393 while (toklen < i) 418 while (toklen < i)
394 token[toklen++] = rand_char (); 419 token[toklen++] = rand_char ();
395 420
414 do { 439 do {
415 *s = nextenc [*s]; 440 *s = nextenc [*s];
416 } while (*s++ == 'a'); 441 } while (*s++ == 'a');
417 } 442 }
418 443
444 perlinterp_acquire ();
445
419 RETVAL = newSVpvn (token, toklen); 446 RETVAL = newSVpvn (token, toklen);
420} 447}
421 OUTPUT: 448 OUTPUT:
422 RETVAL 449 RETVAL
423 450

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines