bai-crypt-isaac 0.9.2

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/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,14 @@
1
+ Copyright (c) 2009 beawesomeinstead
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4
+ documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
5
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
6
+ persons to whom the Software is furnished to do so, subject to the following conditions:
7
+
8
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
9
+ Software.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
12
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
13
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
14
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,51 @@
1
+ Crypt::ISAAC README
2
+ ============
3
+
4
+ ISAAC is a cryptographically secure PRNG for generating high quality random numbers. Detailed information about the
5
+ algorithm can be found at: http://burtleburtle.net/bob/rand/isaac.html
6
+
7
+ This is a pure Ruby implementation of the algorithm. It is reasonably fast for a pure Ruby implementation. On an 800Mhz
8
+ PIII computer running Ruby 1.8.2, and while the machine is also serving as general desktop, the library seems to
9
+ consistently generate between 15000 and 16000 random numbers per second.
10
+
11
+ Ruby uses the Mersenne Twister as its PRNG, and while this the Twister is a fast PRNG that produces highly random
12
+ numbers, it is not strong for cryptographic purposes, nor is it suitable when one needs multiple independent streams of
13
+ random numbers. Crypt::ISAAC is suitable for either purpose.
14
+
15
+
16
+ Requirements
17
+ ------------
18
+
19
+ * Ruby 1.6
20
+ * Ruby 1.8
21
+ * Ruby 1.9
22
+
23
+
24
+ Install
25
+ -------
26
+
27
+ If you have never installed Crypt::ISAAC, you may run the testsuite to confirm that it works with:
28
+
29
+ # rake test
30
+
31
+
32
+ Usage
33
+ -----
34
+
35
+ require 'crypt-isaac'
36
+
37
+ rng = Crypt::ISAAC.new
38
+
39
+ r1 = rng.rand() # returns a floating point between 0 and 1
40
+ r2 = rng.rand(1000) # returns an integer between 0 and 999
41
+
42
+ rand() should work identically to the Kernel.rand().
43
+
44
+ Enjoy it. Let me know if you find anything that can be improved or that needs to be fixed.
45
+
46
+
47
+ License
48
+ -------
49
+
50
+ The Crypt::ISAAC library is licensed with an MIT style licence. See the LICENSE file for details. As for the ISAAC
51
+ algorithm itself, see: http://burtleburtle.net/bob/rand/isaac.html
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.9.2
@@ -0,0 +1,46 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{crypt-isaac}
5
+ s.version = "0.9.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["beawesomeinstead"]
9
+ s.date = %q{2009-07-07}
10
+ s.email = %q{beawesomeinstead@yahoo.com}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README.rdoc"
14
+ ]
15
+ s.files = [
16
+ ".gitignore",
17
+ "LICENSE",
18
+ "README.rdoc",
19
+ "VERSION",
20
+ "crypt-isaac.gemspec",
21
+ "lib/crypt-isaac.rb",
22
+ "rakefile",
23
+ "test/crypt-isaac_test.rb",
24
+ "test/test_helper.rb"
25
+ ]
26
+ s.has_rdoc = true
27
+ s.homepage = %q{http://github.com/bai/crypt-isaac}
28
+ s.rdoc_options = ["--charset=UTF-8"]
29
+ s.require_paths = ["lib"]
30
+ s.rubygems_version = %q{1.3.2}
31
+ s.summary = %q{Ruby implementation of the ISAAC PRNG}
32
+ s.test_files = [
33
+ "test/crypt-isaac_test.rb",
34
+ "test/test_helper.rb"
35
+ ]
36
+
37
+ if s.respond_to? :specification_version then
38
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
39
+ s.specification_version = 3
40
+
41
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
42
+ else
43
+ end
44
+ else
45
+ end
46
+ end
@@ -0,0 +1,158 @@
1
+ module Crypt
2
+ # ISAAC is a fast, strong random number generator. Details on the algorithm can be found
3
+ # here: http://burtleburtle.net/bob/rand/isaac.html
4
+ # This provides a consistent and capable algorithm for producing independent streams of quality random numbers.
5
+ class ISAAC
6
+ attr_accessor :randrsl, :randcnt
7
+ attr_accessor :mm, :aa, :bb, :cc
8
+
9
+ # When a Crypt::ISAAC object is created, it needs to be seeded for random number generation. If the system has a
10
+ # /dev/urandom file, that will be used to do the seeding by default. If false is explictly passed when creating the
11
+ # object, it will instead use /dev/random to generate its seeds. Be warned that this may make for SLOW
12
+ # initialization. If the requested source (/dev/urandom or /dev/random) do not exist, the system will fall back to
13
+ # a simplistic initialization mechanism using the builtin Mersenne Twister PRNG.
14
+ def initialize(noblock = true)
15
+ @mm = []
16
+ @randrsl = []
17
+ # Best initialization of the generator would be by pulling numbers from /dev/random.
18
+ rnd_source = noblock ? '/dev/urandom' : '/dev/random'
19
+ if (FileTest.exist? rnd_source)
20
+ File.open(rnd_source,'r') do |r|
21
+ 256.times do |t|
22
+ z = r.read(4)
23
+ x = z.unpack('V')[0]
24
+ @randrsl[t] = x
25
+ end
26
+ end
27
+ else
28
+ # If urandom isn't available, the standard Ruby PRNG makes an adequate fallback.
29
+ 256.times do |t|
30
+ @randrsl[t] = Kernel.rand(4294967295)
31
+ end
32
+ end
33
+ randinit(true)
34
+ nil
35
+ end
36
+
37
+ # Works just like the standard rand() function. If called with an integer argument, rand() will return positive
38
+ # random number in the range of 0 to (argument - 1). If called without an integer argument, rand() returns a
39
+ # positive floating point number less than 1.
40
+ def rand(*num)
41
+ if (@randcnt == 1)
42
+ isaac
43
+ @randcnt = 256
44
+ end
45
+ @randcnt -= 1
46
+ if num[0].to_i > 0
47
+ @randrsl[@randcnt].modulo(num[0])
48
+ else
49
+ ".#{@randrsl[@randcnt]}".to_f
50
+ end
51
+ end
52
+
53
+ def isaac
54
+ i = 0
55
+ x = 0
56
+ y = 0
57
+
58
+ @cc += 1
59
+ @bb += @cc
60
+ @bb & 0xffffffff
61
+
62
+ while (i < 256) do
63
+ x = @mm[i]
64
+ @aa = (@mm[(i + 128) & 255] + (@aa^(@aa << 13)) ) & 0xffffffff
65
+ @mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
66
+ @randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
67
+ i += 1
68
+
69
+ x = @mm[i]
70
+ @aa = (@mm[(i+128)&255] + (@aa^(0x03ffffff & (@aa >> 6))) ) & 0xffffffff
71
+ @mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
72
+ @randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
73
+ i += 1
74
+
75
+ x = @mm[i]
76
+ @aa = (@mm[(i + 128)&255] + (@aa^(@aa << 2)) ) & 0xffffffff
77
+ @mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
78
+ @randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
79
+ i += 1
80
+
81
+ x = @mm[i]
82
+ @aa = (@mm[(i+128)&255] + (@aa^(0x0000ffff & (@aa >> 16))) ) & 0xffffffff
83
+ @mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
84
+ @randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
85
+ i += 1
86
+ end
87
+ end
88
+
89
+ def randinit(flag)
90
+ i = 0
91
+ a = 0
92
+ b = 0
93
+ c = 0
94
+ d = 0
95
+ e = 0
96
+ f = 0
97
+ g = 0
98
+ @aa = @bb = @cc = 0
99
+ a = b = c = d = e = f = g = h = 0x9e3779b9
100
+
101
+ while (i < 4) do
102
+ a ^= b<<1; d += a; b += c
103
+ b ^= 0x3fffffff & (c>>2); e += b; c += d
104
+ c ^= d << 8; f += c; d += e
105
+ d ^= 0x0000ffff & (e >> 16); g += d; e += f
106
+ e ^= f << 10; h += e; f += g
107
+ f ^= 0x0fffffff & (g >> 4); a += f; g += h
108
+ g ^= h << 8; b += g; h += a
109
+ h ^= 0x007fffff & (a >> 9); c += h; a += b
110
+ i += 1
111
+ end
112
+
113
+ i = 0
114
+ while (i < 256) do
115
+ if (flag)
116
+ a+=@randrsl[i ].to_i; b+=@randrsl[i+1].to_i;
117
+ c+=@randrsl[i+2]; d+=@randrsl[i+3];
118
+ e+=@randrsl[i+4]; f+=@randrsl[i+5];
119
+ g+=@randrsl[i+6]; h+=@randrsl[i+7];
120
+ end
121
+
122
+ a^=b<<11; d+=a; b+=c;
123
+ b^=0x3fffffff & (c>>2); e+=b; c+=d;
124
+ c^=d<<8; f+=c; d+=e;
125
+ d^=0x0000ffff & (e>>16); g+=d; e+=f;
126
+ e^=f<<10; h+=e; f+=g;
127
+ f^=0x0fffffff & (g>>4); a+=f; g+=h;
128
+ g^=h<<8; b+=g; h+=a;
129
+ h^=0x007fffff & (a>>9); c+=h; a+=b;
130
+ @mm[i]=a;@mm[i+1]=b; @mm[i+2]=c; @mm[i+3]=d;
131
+ @mm[i+4]=e; @mm[i+5]=f; @mm[i+6]=g; @mm[i+7]=h;
132
+ i += 8
133
+ end
134
+
135
+ if flag
136
+ i = 0
137
+ while (i < 256)
138
+ a+=@mm[i ]; b+=@mm[i+1]; c+=@mm[i+2]; d+=@mm[i+3];
139
+ e+=@mm[i+4]; f+=@mm[i+5]; g+=@mm[i+6]; h+=@mm[i+7];
140
+ a^=b<<11; d+=a; b+=c;
141
+ b^=0x3fffffff & (c>>2); e+=b; c+=d;
142
+ c^=d<<8; f+=c; d+=e;
143
+ d^=0x0000ffff & (e>>16); g+=d; e+=f;
144
+ e^=f<<10; h+=e; f+=g;
145
+ f^=0x0fffffff & (g>>4); a+=f; g+=h;
146
+ g^=h<<8; b+=g; h+=a;
147
+ h^=0x007fffff & (a>>9); c+=h; a+=b;
148
+ @mm[i ]=a; @mm[i+1]=b; @mm[i+2]=c; @mm[i+3]=d;
149
+ @mm[i+4]=e; @mm[i+5]=f; @mm[i+6]=g; @mm[i+7]=h;
150
+ i += 8
151
+ end
152
+ end
153
+
154
+ isaac()
155
+ @randcnt=256; # /* prepare to use the first set of results */
156
+ end
157
+ end
158
+ end
data/rakefile ADDED
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "crypt-isaac"
8
+ gem.summary = %q(Ruby implementation of the ISAAC PRNG)
9
+ gem.email = "beawesomeinstead@yahoo.com"
10
+ gem.homepage = "http://github.com/bai/crypt-isaac"
11
+ gem.authors = ["beawesomeinstead"]
12
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
+ end
14
+
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
17
+ end
18
+
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new(:test) do |test|
21
+ test.libs << 'lib' << 'test'
22
+ test.pattern = 'test/**/*_test.rb'
23
+ test.verbose = true
24
+ end
25
+
26
+ begin
27
+ require 'rcov/rcovtask'
28
+ Rcov::RcovTask.new do |test|
29
+ test.libs << 'test'
30
+ test.pattern = 'test/**/*_test.rb'
31
+ test.verbose = true
32
+ end
33
+ rescue LoadError
34
+ task :rcov do
35
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
36
+ end
37
+ end
38
+
39
+
40
+ task :default => :test
41
+
42
+ require 'rake/rdoctask'
43
+ Rake::RDocTask.new do |rdoc|
44
+ if File.exist?('VERSION.yml')
45
+ config = YAML.load(File.read('VERSION.yml'))
46
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
47
+ else
48
+ version = ""
49
+ end
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "crypt-isaac #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
56
+
@@ -0,0 +1,63 @@
1
+ require 'test_helper'
2
+
3
+ class CryptIsaacTest < Test::Unit::TestCase
4
+ def setup
5
+ assert_nothing_raised("Failed to create a Crypt::ISAAC object.") do
6
+ @generator = Crypt::ISAAC.new
7
+ end
8
+ end
9
+
10
+ def test_kind
11
+ assert_kind_of(Crypt::ISAAC, @generator, "The created object is not a Crypt::ISAAC or subclass thereof.")
12
+ end
13
+
14
+ def test_integer
15
+ assert_nothing_raised("Failed while generating an integer random number.") do
16
+ mynum = @generator.rand(1000000)
17
+ assert_kind_of(Integer, mynum, "The generator failed to return an integer number in response to @generator.rand(1000000).")
18
+ assert((mynum >= 0), "The generator returned a number that is less than 0 (#{mynum}).")
19
+ assert((mynum < 1000000), "The generator returned a number that is greater than or equal to 1000000 (#{mynum}).")
20
+ end
21
+ end
22
+
23
+ def test_float
24
+ assert_nothing_raised("Failed while generating a floating point random number.") do
25
+ mynum = @generator.rand()
26
+ assert_kind_of(Float, mynum, "The generator failed to return a floating point number in response to @generator.rand().")
27
+ assert((mynum >= 0), "The generator returned a number that is less than 0 (#{mynum}).")
28
+ assert((mynum < 1), "The generator returned a number that is greater than or equal to 1 (#{mynum}).")
29
+ end
30
+ end
31
+
32
+ def test_iterations
33
+ puts
34
+ count = 0
35
+ assert_nothing_raised("Failed on iteration #{count} while trying to generate 100000 random numbers.") do
36
+ 100000.times do
37
+ count += 1
38
+ x = @generator.rand(4294967295)
39
+ print [x].pack('V').unpack('H8') if count % 1000 == 0
40
+ if (count % 7000) == 0
41
+ print "\n"
42
+ else
43
+ print " " if count % 1000 == 0
44
+ end
45
+ end
46
+ puts "\n100000 numbers generated"
47
+ end
48
+ end
49
+
50
+ def test_dual_streams
51
+ g1 = nil
52
+ g2 = nil
53
+ assert_nothing_raised("Failed to pull numbers from two independent streams.") do
54
+ g1 = Crypt::ISAAC.new
55
+ g2 = Crypt::ISAAC.new
56
+ assert((g1 != g2),"The generators are the same. This should not happen.")
57
+ 1000.times do
58
+ g1.rand(4294967295)
59
+ g2.rand(4294967295)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'crypt-isaac'
7
+
8
+ class Test::Unit::TestCase
9
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bai-crypt-isaac
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.2
5
+ platform: ruby
6
+ authors:
7
+ - beawesomeinstead
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-07 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: beawesomeinstead@yahoo.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - .gitignore
27
+ - LICENSE
28
+ - README.rdoc
29
+ - VERSION
30
+ - crypt-isaac.gemspec
31
+ - lib/crypt-isaac.rb
32
+ - rakefile
33
+ - test/crypt-isaac_test.rb
34
+ - test/test_helper.rb
35
+ has_rdoc: true
36
+ homepage: http://github.com/bai/crypt-isaac
37
+ post_install_message:
38
+ rdoc_options:
39
+ - --charset=UTF-8
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ requirements: []
55
+
56
+ rubyforge_project:
57
+ rubygems_version: 1.2.0
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Ruby implementation of the ISAAC PRNG
61
+ test_files:
62
+ - test/crypt-isaac_test.rb
63
+ - test/test_helper.rb