crypt-isaac 1.0.0 → 1.1.0

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.
@@ -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
+