crypt-isaac 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,142 @@
1
+ /*
2
+ ------------------------------------------------------------------------------
3
+ rand.c: By Bob Jenkins. My random number generator, ISAAC. Public Domain
4
+ MODIFIED:
5
+ 960327: Creation (addition of randinit, really)
6
+ 970719: use context, not global variables, for internal state
7
+ 980324: make a portable version
8
+ 010626: Note this is public domain
9
+ 100725: Mask on use of >32 bits, not on assignment: from Paul Eggert
10
+ ------------------------------------------------------------------------------
11
+ */
12
+ #ifndef STANDARD
13
+ #include "standard.h"
14
+ #endif
15
+ #ifndef RAND
16
+ #include "rand.h"
17
+ #endif
18
+
19
+
20
+ #define ind(mm,x) ((mm)[(x>>2)&(RANDSIZ-1)])
21
+ #define rngstep(mix,a,b,mm,m,m2,r,x) \
22
+ { \
23
+ x = *m; \
24
+ a = ((a^(mix)) + *(m2++)); \
25
+ *(m++) = y = (ind(mm,x) + a + b); \
26
+ *(r++) = b = (ind(mm,y>>RANDSIZL) + x) & 0xffffffff; \
27
+ }
28
+
29
+ void isaac(ctx)
30
+ randctx *ctx;
31
+ {
32
+ ub4 a,b,x,y,*m,*mm,*m2,*r,*mend;
33
+ mm=ctx->randmem; r=ctx->randrsl;
34
+ a = ctx->randa; b = ctx->randb + (++ctx->randc);
35
+ for (m = mm, mend = m2 = m+(RANDSIZ/2); m<mend; )
36
+ {
37
+ rngstep( a<<13, a, b, mm, m, m2, r, x);
38
+ rngstep( (a & 0xffffffff) >>6 , a, b, mm, m, m2, r, x);
39
+ rngstep( a<<2 , a, b, mm, m, m2, r, x);
40
+ rngstep( (a & 0xffffffff) >>16, a, b, mm, m, m2, r, x);
41
+ }
42
+ for (m2 = mm; m2<mend; )
43
+ {
44
+ rngstep( a<<13, a, b, mm, m, m2, r, x);
45
+ rngstep( (a & 0xffffffff) >>6 , a, b, mm, m, m2, r, x);
46
+ rngstep( a<<2 , a, b, mm, m, m2, r, x);
47
+ rngstep( (a & 0xffffffff) >>16, a, b, mm, m, m2, r, x);
48
+ }
49
+ ctx->randb = b; ctx->randa = a;
50
+ }
51
+
52
+
53
+ #define mix(a,b,c,d,e,f,g,h) \
54
+ { \
55
+ a^=b<<11; d+=a; b+=c; \
56
+ b^=(c&0xffffffff)>>2; e+=b; c+=d; \
57
+ c^=d<<8; f+=c; d+=e; \
58
+ d^=(e&0xffffffff)>>16; g+=d; e+=f; \
59
+ e^=f<<10; h+=e; f+=g; \
60
+ f^=(g&0xffffffff)>>4; a+=f; g+=h; \
61
+ g^=h<<8; b+=g; h+=a; \
62
+ h^=(a&0xffffffff)>>9; c+=h; a+=b; \
63
+ }
64
+
65
+ /* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */
66
+ void randinit(ctx, flag)
67
+ randctx *ctx;
68
+ word flag;
69
+ {
70
+ word i;
71
+ ub4 a,b,c,d,e,f,g,h;
72
+ ub4 *m,*r;
73
+ ctx->randa = ctx->randb = ctx->randc = 0;
74
+ m=ctx->randmem;
75
+ r=ctx->randrsl;
76
+ a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */
77
+
78
+ for (i=0; i<4; ++i) /* scramble it */
79
+ {
80
+ mix(a,b,c,d,e,f,g,h);
81
+ }
82
+
83
+ if (flag)
84
+ {
85
+ /* initialize using the contents of r[] as the seed */
86
+ for (i=0; i<RANDSIZ; i+=8)
87
+ {
88
+ a+=r[i ]; b+=r[i+1];
89
+ c+=r[i+2]; d+=r[i+3];
90
+ e+=r[i+4]; f+=r[i+5];
91
+ g+=r[i+6]; h+=r[i+7];
92
+ mix(a,b,c,d,e,f,g,h);
93
+ m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
94
+ m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
95
+ }
96
+ /* do a second pass to make all of the seed affect all of m */
97
+ for (i=0; i<RANDSIZ; i+=8)
98
+ {
99
+ a+=m[i ]; b+=m[i+1];
100
+ c+=m[i+2]; d+=m[i+3];
101
+ e+=m[i+4]; f+=m[i+5];
102
+ g+=m[i+6]; h+=m[i+7];
103
+ mix(a,b,c,d,e,f,g,h);
104
+ m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
105
+ m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
106
+ }
107
+ }
108
+ else
109
+ {
110
+ for (i=0; i<RANDSIZ; i+=8)
111
+ {
112
+ /* fill in mm[] with messy stuff */
113
+ mix(a,b,c,d,e,f,g,h);
114
+ m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
115
+ m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
116
+ }
117
+ }
118
+
119
+ isaac(ctx); /* fill in the first set of results */
120
+ ctx->randcnt=RANDSIZ; /* prepare to use the first set of results */
121
+ }
122
+
123
+
124
+ #ifdef NEVER
125
+ int main()
126
+ {
127
+ ub4 i,j;
128
+ randctx ctx;
129
+ ctx.randa=ctx.randb=ctx.randc=(ub4)0;
130
+ for (i=0; i<256; ++i) ctx.randrsl[i]=(ub4)0;
131
+ randinit(&ctx, TRUE);
132
+ for (i=0; i<2; ++i)
133
+ {
134
+ isaac(&ctx);
135
+ for (j=0; j<256; ++j)
136
+ {
137
+ printf("%.8lx",ctx.randrsl[j]);
138
+ if ((j&7)==7) printf("\n");
139
+ }
140
+ }
141
+ }
142
+ #endif
@@ -0,0 +1,56 @@
1
+ /*
2
+ ------------------------------------------------------------------------------
3
+ rand.h: definitions for a random number generator
4
+ By Bob Jenkins, 1996, Public Domain
5
+ MODIFIED:
6
+ 960327: Creation (addition of randinit, really)
7
+ 970719: use context, not global variables, for internal state
8
+ 980324: renamed seed to flag
9
+ 980605: recommend RANDSIZL=4 for noncryptography.
10
+ 010626: note this is public domain
11
+ ------------------------------------------------------------------------------
12
+ */
13
+ #ifndef STANDARD
14
+ #include "standard.h"
15
+ #endif
16
+
17
+ #ifndef RAND
18
+ #define RAND
19
+ #define RANDSIZL (8)
20
+ #define RANDSIZ (1<<RANDSIZL)
21
+
22
+ /* context of random number generator */
23
+ struct randctx
24
+ {
25
+ ub4 randcnt;
26
+ ub4 randrsl[RANDSIZ];
27
+ ub4 randmem[RANDSIZ];
28
+ ub4 randa;
29
+ ub4 randb;
30
+ ub4 randc;
31
+ };
32
+ typedef struct randctx randctx;
33
+
34
+ /*
35
+ ------------------------------------------------------------------------------
36
+ If (flag==TRUE), then use the contents of randrsl[0..RANDSIZ-1] as the seed.
37
+ ------------------------------------------------------------------------------
38
+ */
39
+ void randinit( randctx *r, word flag );
40
+
41
+ void isaac( randctx *r );
42
+
43
+
44
+ /*
45
+ ------------------------------------------------------------------------------
46
+ Call rand(/o_ randctx *r _o/) to retrieve a single 32-bit random value
47
+ ------------------------------------------------------------------------------
48
+ */
49
+ #define rand(r) \
50
+ (!(r)->randcnt-- ? \
51
+ (isaac(r), (r)->randcnt=RANDSIZ-1, (r)->randrsl[(r)->randcnt]) : \
52
+ (r)->randrsl[(r)->randcnt])
53
+
54
+ #endif /* RAND */
55
+
56
+
@@ -0,0 +1,57 @@
1
+ /*
2
+ ------------------------------------------------------------------------------
3
+ Standard definitions and types, Bob Jenkins
4
+ ------------------------------------------------------------------------------
5
+ */
6
+ #ifndef STANDARD
7
+ # define STANDARD
8
+ # ifndef STDIO
9
+ # include <stdio.h>
10
+ # define STDIO
11
+ # endif
12
+ # ifndef STDDEF
13
+ # include <stddef.h>
14
+ # define STDDEF
15
+ # endif
16
+ typedef unsigned long long ub8;
17
+ #define UB8MAXVAL 0xffffffffffffffffLL
18
+ #define UB8BITS 64
19
+ typedef signed long long sb8;
20
+ #define SB8MAXVAL 0x7fffffffffffffffLL
21
+ typedef unsigned long int ub4; /* unsigned 4-byte quantities */
22
+ #define UB4MAXVAL 0xffffffff
23
+ typedef signed long int sb4;
24
+ #define UB4BITS 32
25
+ #define SB4MAXVAL 0x7fffffff
26
+ typedef unsigned short int ub2;
27
+ #define UB2MAXVAL 0xffff
28
+ #define UB2BITS 16
29
+ typedef signed short int sb2;
30
+ #define SB2MAXVAL 0x7fff
31
+ typedef unsigned char ub1;
32
+ #define UB1MAXVAL 0xff
33
+ #define UB1BITS 8
34
+ typedef signed char sb1; /* signed 1-byte quantities */
35
+ #define SB1MAXVAL 0x7f
36
+ typedef int word; /* fastest type available */
37
+
38
+ #define bis(target,mask) ((target) |= (mask))
39
+ #define bic(target,mask) ((target) &= ~(mask))
40
+ #define bit(target,mask) ((target) & (mask))
41
+ #ifndef min
42
+ # define min(a,b) (((a)<(b)) ? (a) : (b))
43
+ #endif /* min */
44
+ #ifndef max
45
+ # define max(a,b) (((a)<(b)) ? (b) : (a))
46
+ #endif /* max */
47
+ #ifndef align
48
+ # define align(a) (((ub4)a+(sizeof(void *)-1))&(~(sizeof(void *)-1)))
49
+ #endif /* align */
50
+ #ifndef abs
51
+ # define abs(a) (((a)>0) ? (a) : -(a))
52
+ #endif
53
+ #define TRUE 1
54
+ #define FALSE 0
55
+ #define SUCCESS 0 /* 1 on VAX */
56
+
57
+ #endif /* STANDARD */
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile("crypt/isaac/xorshift/ext")
@@ -0,0 +1,121 @@
1
+ #include "ruby.h"
2
+ #include <sys/types.h>
3
+ #include <unistd.h>
4
+
5
+ static VALUE CryptModule;
6
+ static VALUE Xorshift64StarClass;
7
+ static int16_t seed_counter = 0;
8
+
9
+ static void Xorshift64Star_free( uint64_t* seed ) {
10
+ if ( seed ) {
11
+ xfree( seed );
12
+ }
13
+ }
14
+
15
+ static VALUE Xorshift64Star_alloc( VALUE klass ) {
16
+ uint64_t* seed;
17
+
18
+ return Data_Make_Struct( klass, uint64_t, NULL, Xorshift64Star_free, seed );
19
+ }
20
+
21
+ static VALUE Xorshift64Star_initialize( VALUE self, VALUE args ) {
22
+ VALUE _seed ;
23
+ long len = RARRAY_LEN( args );
24
+
25
+ if ( len == 0 ) {
26
+ _seed = rb_funcall( self, rb_intern( "srand" ), 0 );
27
+ } else {
28
+ _seed = rb_funcall( self, rb_intern( "srand" ), 1, rb_ary_entry( args, 0 ) );
29
+ }
30
+
31
+ _seed = rb_funcall( self, rb_intern( "srand" ), 1, _seed );
32
+ rb_iv_set( self, "@old_seed", _seed );
33
+ return _seed;
34
+ }
35
+
36
+ static VALUE to_hex_block( VALUE arg, VALUE data, int argc, VALUE* argv ) {
37
+ return rb_funcall( arg, rb_intern( "to_s" ), 1, INT2FIX( 16 ) );
38
+ }
39
+
40
+ static VALUE Xorshift64Star_new_seed( VALUE self ) {
41
+ VALUE now;
42
+ VALUE ary;
43
+ now = rb_funcall( rb_cTime, rb_intern( "now" ), 0 );
44
+ ary = rb_ary_new();
45
+ seed_counter++;
46
+
47
+ rb_ary_push( ary, rb_funcall( rb_funcall( now, rb_intern( "usec" ), 0 ), rb_intern( "%" ), 1, INT2FIX( 65536 ) ) );
48
+ rb_ary_push( ary, rb_funcall( rb_funcall( now, rb_intern( "to_i" ), 0 ), rb_intern( "%" ), 1, INT2FIX( 65536 ) ) );
49
+ rb_ary_push( ary, rb_funcall( INT2FIX( getpid() ), rb_intern( "%" ), 1, INT2FIX( 65536 ) ) );
50
+ rb_ary_push( ary, INT2FIX( seed_counter ) );
51
+ return rb_funcall( rb_funcall(
52
+ rb_block_call( ary, rb_intern( "collect" ), 0, 0, to_hex_block, Qnil ),
53
+ rb_intern( "join" ),
54
+ 0
55
+ ), rb_intern( "to_i" ), 1, INT2FIX( 16 ) );
56
+ }
57
+
58
+ static VALUE Xorshift64Star_srand( VALUE self, VALUE args ) {
59
+ uint64_t *seed;
60
+ long len = RARRAY_LEN( args );
61
+ VALUE _seed ;
62
+
63
+ Data_Get_Struct( self, uint64_t, seed);
64
+
65
+ if ( ( len == 0 ) || ( ( len == 1 ) && ( rb_ary_entry( args, 0 ) == Qnil ) ) ) {
66
+ _seed = rb_funcall( self, rb_intern( "new_seed" ), 0 );
67
+ } else {
68
+ _seed = rb_ary_entry( args, 0 );
69
+ }
70
+
71
+ rb_iv_set( self, "@old_seed", ULL2NUM( (*seed) ) );
72
+
73
+ (*seed) = NUM2ULL(_seed);
74
+ return _seed;
75
+ }
76
+
77
+ static VALUE Xorshift64Star_rand( VALUE self, VALUE args ) {
78
+ long len = RARRAY_LEN( args );
79
+ uint64_t *seed;
80
+ uint64_t limit;
81
+ uint64_t random;
82
+ Data_Get_Struct( self, uint64_t, seed );
83
+
84
+ if ( len == 0 ) {
85
+ limit = 0;
86
+ } else {
87
+ limit = NUM2ULL( rb_ary_entry( args, 0 ) );
88
+ }
89
+
90
+ *seed ^= *seed >> 12;
91
+ *seed ^= *seed << 25;
92
+ *seed ^= *seed >> 27;
93
+ random = *seed * UINT64_C(2685821657736338717);
94
+
95
+ if ( limit == 0 ) {
96
+ return DBL2NUM( (double)( random / 2 ) / 9223372036854775807 );
97
+ } else {
98
+ return ULL2NUM( random % limit );
99
+ }
100
+ }
101
+
102
+ static VALUE Xorshift64Star_seed(VALUE self) {
103
+ return rb_iv_get( self, "@old_seed" );
104
+ }
105
+
106
+ static VALUE Xorshift64Star_eq(VALUE self, VALUE v) {
107
+ return ( ( rb_obj_classname( self ) == rb_obj_classname( v ) ) && ( rb_iv_get( self, "@old_seed" ) == rb_funcall( v, rb_intern( "seed" ), 0 ) ) ) ? Qtrue : Qfalse ;
108
+ }
109
+
110
+ void Init_ext() {
111
+ CryptModule = rb_define_module( "Crypt" );
112
+ Xorshift64StarClass = rb_define_class_under( CryptModule, "Xorshift64Star", rb_cObject );
113
+
114
+ rb_define_alloc_func( Xorshift64StarClass, Xorshift64Star_alloc );
115
+ rb_define_method( Xorshift64StarClass, "initialize", Xorshift64Star_initialize, -2 );
116
+ rb_define_method( Xorshift64StarClass, "srand", Xorshift64Star_srand, -2 );
117
+ rb_define_method( Xorshift64StarClass, "rand", Xorshift64Star_rand, -2 );
118
+ rb_define_method( Xorshift64StarClass, "new_seed", Xorshift64Star_new_seed, 0 );
119
+ rb_define_method( Xorshift64StarClass, "seed", Xorshift64Star_seed, 0 );
120
+ rb_define_method( Xorshift64StarClass, "==", Xorshift64Star_eq, 1 );
121
+ }
data/lib/crypt/isaac.rb CHANGED
@@ -1,213 +1,16 @@
1
- module Crypt
2
-
3
- # ISAAC is a fast, strong random number generator. Details on the
4
- # algorithm can be found here: http://burtleburtle.net/bob/rand/isaac.html
5
- # This provides a consistent and capable algorithm for producing
6
- # independent streams of quality random numbers.
7
-
8
- class ISAAC
9
-
10
- attr_accessor :randrsl, :randcnt
11
- attr_accessor :mm, :aa, :bb, :cc
12
-
13
- # When a Crypt::ISAAC object is created, it needs to be seeded for
14
- # random number generation. If the system has a /dev/urandom file,
15
- # that will be used to do the seeding by default. If false is explictly
16
- # passed when creating the object, it will instead use /dev/random to
17
- # generate its seeds. Be warned that this may make for SLOW
18
- # initialization.
19
- # If the requested source (/dev/urandom or /dev/random) do not exist,
20
- # the system will fall back to a simplistic initialization mechanism
21
- # using the builtin Mersenne Twister PRNG.
22
-
23
- def initialize(seed = true)
24
- @mm = []
25
-
26
- if Integer === seed || Random === seed
27
- self.srand(seed)
28
- else
29
- @seed = seed
30
- rnd_source = ( ( seed == true ) || ( seed == false ) ) ?
31
- ( seed ? '/dev/urandom' : '/dev/random' ) :
32
- seed
33
- if (FileTest.exist? rnd_source)
34
- @randrsl = []
35
- File.open(rnd_source,'r') do |r|
36
- 256.times do |t|
37
- z = r.read(4)
38
- x = z.unpack('V')[0]
39
- @randrsl[t] = x
40
- end
41
- end
42
- randinit(true)
43
- else
44
- raise "Entropy source (#{rnd_source}) doesn't exist. The ISAAC algorithm can not be seeded."
45
- end
46
- end
47
- end
48
-
49
- # If seeded with an integer, use that to seed a standard Ruby Mersenne Twister
50
- # PRNG, and then use that to generate seed value for ISAAC. This is mostly useful
51
- # for producing repeated, deterministic results, which may be needed for testing.
52
- def srand(seed)
53
- @seed = seed
54
- @randrsl = []
55
- seed_prng = ( Random === seed ) ? seed : Random.new(seed)
56
- 256.times do |t|
57
- @randrsl[t] = seed_prng.rand(4294967295)
58
- end
59
- randinit(true)
60
- end
61
-
62
- # Works just like the standard rand() function. If called with an
63
- # integer argument, rand() will return positive random number in
64
- # the range of 0 to (argument - 1). If called without an integer
65
- # argument, rand() returns a positive floating point number less than 1.
66
- # If called with a Range, returns a number that is in the range.
67
-
68
- def rand(arg = nil)
69
- if (@randcnt == 1)
70
- isaac
71
- @randcnt = 256
72
- end
73
- @randcnt -= 1
74
- if arg.nil?
75
- ( @randrsl[@randcnt] / 536870912.0 ) % 1
76
- elsif Integer === arg || Float === arg
77
- @randrsl[@randcnt] % arg
78
- elsif Range === arg
79
- arg.min + @randrsl[@randcnt] % (arg.max - arg.min)
80
- else
81
- @randrsl[@randcnt] % Integer(arg)
82
- end
83
- end
84
-
85
- def seed
86
- Random === @seed ? @seed.seed : @seed
87
- end
88
-
89
- def state
90
- @randrsl + [@randcnt]
91
- end
92
-
93
- def ==(gen)
94
- self.state == gen.state
95
- end
96
-
97
- def bytes(size)
98
- buffer = ""
99
- ( size / 4 ).times { buffer << [rand(4294967295)].pack("L").unpack("aaaa").join }
100
-
101
- if size % 4 != 0
102
- buffer << [rand(4294967295)].pack("L").unpack("aaaa")[0..(size % 4 - 1)].join
103
- end
104
-
105
- buffer
106
- end
107
-
108
- def isaac
109
- i = 0
110
- x = 0
111
- y = 0
112
-
113
- @cc += 1
114
- @bb += @cc
115
- @bb & 0xffffffff
116
-
117
- while (i < 256) do
118
- x = @mm[i]
119
- @aa = (@mm[(i + 128) & 255] + (@aa^(@aa << 13)) ) & 0xffffffff
120
- @mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
121
- @randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
122
- i += 1
123
-
124
- x = @mm[i]
125
- @aa = (@mm[(i+128)&255] + (@aa^(0x03ffffff & (@aa >> 6))) ) & 0xffffffff
126
- @mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
127
- @randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
128
- i += 1
129
-
130
- x = @mm[i]
131
- @aa = (@mm[(i + 128)&255] + (@aa^(@aa << 2)) ) & 0xffffffff
132
- @mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
133
- @randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
134
- i += 1
135
-
136
- x = @mm[i]
137
- @aa = (@mm[(i+128)&255] + (@aa^(0x0000ffff & (@aa >> 16))) ) & 0xffffffff
138
- @mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
139
- @randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
140
- i += 1
141
- end
142
- end
143
-
144
- def randinit(flag)
145
- i = 0
146
- a = 0
147
- b = 0
148
- c = 0
149
- d = 0
150
- e = 0
151
- f = 0
152
- g = 0
153
- @aa = @bb = @cc = 0
154
- a = b = c = d = e = f = g = h = 0x9e3779b9
155
-
156
- while (i < 4) do
157
- a ^= b<<1; d += a; b += c
158
- b ^= 0x3fffffff & (c>>2); e += b; c += d
159
- c ^= d << 8; f += c; d += e
160
- d ^= 0x0000ffff & (e >> 16); g += d; e += f
161
- e ^= f << 10; h += e; f += g
162
- f ^= 0x0fffffff & (g >> 4); a += f; g += h
163
- g ^= h << 8; b += g; h += a
164
- h ^= 0x007fffff & (a >> 9); c += h; a += b
165
- i += 1
166
- end
167
-
168
- i = 0
169
- while (i < 256) do
170
- if (flag)
171
- a+=@randrsl[i ].to_i; b+=@randrsl[i+1].to_i;
172
- c+=@randrsl[i+2]; d+=@randrsl[i+3];
173
- e+=@randrsl[i+4]; f+=@randrsl[i+5];
174
- g+=@randrsl[i+6]; h+=@randrsl[i+7];
175
- end
176
-
177
- a^=b<<11; d+=a; b+=c;
178
- b^=0x3fffffff & (c>>2); e+=b; c+=d;
179
- c^=d<<8; f+=c; d+=e;
180
- d^=0x0000ffff & (e>>16); g+=d; e+=f;
181
- e^=f<<10; h+=e; f+=g;
182
- f^=0x0fffffff & (g>>4); a+=f; g+=h;
183
- g^=h<<8; b+=g; h+=a;
184
- h^=0x007fffff & (a>>9); c+=h; a+=b;
185
- @mm[i]=a;@mm[i+1]=b; @mm[i+2]=c; @mm[i+3]=d;
186
- @mm[i+4]=e; @mm[i+5]=f; @mm[i+6]=g; @mm[i+7]=h;
187
- i += 8
188
- end
189
-
190
- if flag
191
- i = 0
192
- while (i < 256)
193
- a+=@mm[i ]; b+=@mm[i+1]; c+=@mm[i+2]; d+=@mm[i+3];
194
- e+=@mm[i+4]; f+=@mm[i+5]; g+=@mm[i+6]; h+=@mm[i+7];
195
- a^=b<<11; d+=a; b+=c;
196
- b^=0x3fffffff & (c>>2); e+=b; c+=d;
197
- c^=d<<8; f+=c; d+=e;
198
- d^=0x0000ffff & (e>>16); g+=d; e+=f;
199
- e^=f<<10; h+=e; f+=g;
200
- f^=0x0fffffff & (g>>4); a+=f; g+=h;
201
- g^=h<<8; b+=g; h+=a;
202
- h^=0x007fffff & (a>>9); c+=h; a+=b;
203
- @mm[i ]=a; @mm[i+1]=b; @mm[i+2]=c; @mm[i+3]=d;
204
- @mm[i+4]=e; @mm[i+5]=f; @mm[i+6]=g; @mm[i+7]=h;
205
- i += 8
206
- end
207
- end
1
+ begin
2
+ require 'crypt/isaac/ext'
3
+ rescue LoadError
4
+ require 'crypt/isaac/pure'
5
+ end
208
6
 
209
- isaac()
210
- @randcnt=256; # /* prepare to use the first set of results */
211
- end
212
- end
7
+ begin
8
+ # Use a non-cryptographic alternative to the Mersenne Twister for an internal
9
+ # pseudo-random source of numbers if the library is required to seed itself.
10
+ # https://en.wikipedia.org/wiki/Xorshift
11
+ require 'crypt-xorshift'
12
+ rescue LoadError
13
+ # Fallback on an internal micro-implementation.
14
+ require 'crypt/isaac/xorshift'
213
15
  end
16
+