secretsharing 1.0.0 → 2.0.1

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.
@@ -16,5 +16,5 @@
16
16
 
17
17
  # Module for specifying the current version of the gem.
18
18
  module SecretSharing
19
- VERSION = '1.0.0'
19
+ VERSION = '2.0.1'
20
20
  end
@@ -5,27 +5,32 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'secretsharing/version'
6
6
 
7
7
  Gem::Specification.new do |s|
8
- s.name = "secretsharing"
8
+ s.name = 'secretsharing'
9
9
  s.version = SecretSharing::VERSION
10
10
  s.platform = Gem::Platform::RUBY
11
- s.authors = ["Alexander Klink", "Glenn Rempe"]
12
- s.email = ["glenn@rempe.us"]
13
- s.homepage = "https://github.com/grempe/secretsharing"
14
- s.summary = %q{A Ruby Gem to enable sharing secrets using Shamirs Secret Sharing.}
15
- s.license = "APACHE 2.0"
11
+ s.authors = ['Alexander Klink', 'Glenn Rempe']
12
+ s.email = ['glenn@rempe.us']
13
+ s.homepage = 'https://github.com/grempe/secretsharing'
14
+ s.summary = 'A Ruby Gem to enable sharing secrets using Shamirs Secret Sharing.'
15
+ s.license = 'APACHE 2.0'
16
16
 
17
17
  s.has_rdoc = 'true'
18
18
  s.extra_rdoc_files = ['README.md']
19
19
 
20
- s.rubyforge_project = "secretsharing"
20
+ s.rubyforge_project = 'secretsharing'
21
21
 
22
+ # rubocop:disable Style/SpecialGlobalVars
22
23
  s.files = `git ls-files`.split($/)
24
+ # rubocop:enable Style/SpecialGlobalVars
25
+
23
26
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
24
27
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
25
- s.require_paths = ["lib"]
28
+ s.require_paths = ['lib']
26
29
 
27
- s.add_dependency 'highline', '~> 1.6'
28
- s.add_dependency 'multi_json', '~> 1.10'
30
+ s.add_dependency 'rbnacl-libsodium', '~> 1.0.8'
31
+ s.add_dependency 'rbnacl', '~> 3.3.0'
32
+ s.add_dependency 'highline', '~> 1.7.8'
33
+ s.add_dependency 'multi_json', '~> 1.11.2'
29
34
 
30
35
  s.add_development_dependency 'mocha'
31
36
  s.add_development_dependency 'minitest'
@@ -33,15 +38,17 @@ Gem::Specification.new do |s|
33
38
  s.add_development_dependency 'rb-fsevent'
34
39
  s.add_development_dependency 'rerun'
35
40
  s.add_development_dependency 'rubocop'
36
- s.add_development_dependency 'bundler', '~> 1.7'
37
- s.add_development_dependency 'rake', '~> 10.4'
38
-
39
- s.description =<<'XEOF'
40
- Shamir's Secret Sharing is an algorithm in cryptography. It is a
41
- form of secret sharing, where a secret is divided into parts,
42
- giving each participant its own unique part, where some of the
43
- parts or all of them are needed in order to reconstruct the
44
- secret. Holders of a share gain no knowledge of the larger secret.
45
- XEOF
46
-
41
+ s.add_development_dependency 'bundler'
42
+ s.add_development_dependency 'rake'
43
+
44
+ # http://rubyquicktips.com/post/4438542511/heredoc-and-indent
45
+ s.description = <<-EOF.gsub(/^ {4}/, '')
46
+ 4/12/2016 - NO LONGER MAINTAINED - See README.md
47
+
48
+ Shamirs Secret Sharing is an algorithm in cryptography. It is a
49
+ form of secret sharing, where a secret is divided into parts,
50
+ giving each participant its own unique part, where some of the
51
+ parts or all of them are needed in order to reconstruct the
52
+ secret. Holders of a share gain no knowledge of the larger secret.
53
+ EOF
47
54
  end
@@ -17,9 +17,7 @@
17
17
  require File.expand_path('../spec_helper', __FILE__)
18
18
 
19
19
  describe SecretSharing::Shamir::Container do
20
-
21
20
  describe 'initialization' do
22
-
23
21
  it 'will raise when instantiated with no args' do
24
22
  lambda { SecretSharing::Shamir::Container.new }.must_raise(ArgumentError)
25
23
  end
@@ -101,15 +99,13 @@ describe SecretSharing::Shamir::Container do
101
99
  it 'must return the correct max shares constant value' do
102
100
  SecretSharing::Shamir::Container::MAX_SHARES.must_equal(512)
103
101
  end
104
-
105
102
  end # describe initialization
106
103
 
107
104
  describe 'creating a container and setting a secret' do
108
-
109
105
  before do
110
106
  @num_shares = 5
111
107
  @c = SecretSharing::Shamir::Container.new(@num_shares)
112
- @secret_num = OpenSSL::BN.new('1234567890')
108
+ @secret_num = 1234567890
113
109
  @c.secret = SecretSharing::Shamir::Secret.new(:secret => @secret_num)
114
110
  end
115
111
 
@@ -142,14 +138,12 @@ describe SecretSharing::Shamir::Container do
142
138
  it 'must raise an exception if a secret is attempted to be set more than once' do
143
139
  lambda { @c.secret = SecretSharing::Shamir::Secret.new }.must_raise(ArgumentError)
144
140
  end
145
-
146
141
  end # creating a container and setting a secret
147
142
 
148
143
  describe 'generating shares when a secret is provided' do
149
-
150
144
  it 'should generate unique shares for the min number of shares and a tiny secret' do
151
145
  c1 = SecretSharing::Shamir::Container.new(2)
152
- c1.secret = SecretSharing::Shamir::Secret.new(:secret => OpenSSL::BN.new('123'))
146
+ c1.secret = SecretSharing::Shamir::Secret.new(:secret => 123)
153
147
  shares = c1.shares
154
148
  shares.size.must_equal(2)
155
149
  uniq_shares = shares.uniq
@@ -158,7 +152,7 @@ describe SecretSharing::Shamir::Container do
158
152
 
159
153
  it 'should generate unique shares for the max number of shares and a tiny secret' do
160
154
  c1 = SecretSharing::Shamir::Container.new(512)
161
- c1.secret = SecretSharing::Shamir::Secret.new(:secret => OpenSSL::BN.new('123'))
155
+ c1.secret = SecretSharing::Shamir::Secret.new(:secret => 123)
162
156
  shares = c1.shares
163
157
  shares.size.must_equal(512)
164
158
  uniq_shares = shares.uniq
@@ -167,8 +161,9 @@ describe SecretSharing::Shamir::Container do
167
161
 
168
162
  it 'should generate unique shares for the min number of shares and a large secret' do
169
163
  c1 = SecretSharing::Shamir::Container.new(2)
170
- # FIXME : Major Perf Issue : If OpenSSL::BN::rand(512) is given with 4096 instead of 512 this takes FOREVER
171
- c1.secret = SecretSharing::Shamir::Secret.new(:secret => OpenSSL::BN::rand(512))
164
+ # FIXME : Major Perf Issue : Large bit length secrets (>4096) cause major perf issue.
165
+ random_num = RbNaCl::Util.bin2hex(RbNaCl::Random.random_bytes(32).to_s).to_i(16)
166
+ c1.secret = SecretSharing::Shamir::Secret.new(:secret => random_num)
172
167
  shares = c1.shares
173
168
  shares.size.must_equal(2)
174
169
  uniq_shares = shares.uniq
@@ -177,18 +172,17 @@ describe SecretSharing::Shamir::Container do
177
172
 
178
173
  it 'should generate unique shares for the max number of shares and a large secret' do
179
174
  c1 = SecretSharing::Shamir::Container.new(512)
180
- # FIXME : Major Perf Issue : If OpenSSL::BN::rand(512) is given with 4096 instead of 512 this takes FOREVER
181
- c1.secret = SecretSharing::Shamir::Secret.new(:secret => OpenSSL::BN::rand(512))
175
+ # FIXME : Major Perf Issue : Large bit length secrets (>4096) cause major perf issue.
176
+ random_num = RbNaCl::Util.bin2hex(RbNaCl::Random.random_bytes(32).to_s).to_i(16)
177
+ c1.secret = SecretSharing::Shamir::Secret.new(:secret => random_num)
182
178
  shares = c1.shares
183
179
  shares.size.must_equal(512)
184
180
  uniq_shares = shares.uniq
185
181
  shares.must_equal(uniq_shares)
186
182
  end
187
-
188
183
  end
189
184
 
190
185
  describe 'recovering a secret from a container' do
191
-
192
186
  before do
193
187
  @c1 = SecretSharing::Shamir::Container.new(5) # creator
194
188
  @c2 = SecretSharing::Shamir::Container.new(5) # recipient
@@ -200,7 +194,6 @@ describe SecretSharing::Shamir::Container do
200
194
  end
201
195
 
202
196
  describe 'with a mix of valid and invalid shares' do
203
-
204
197
  before do
205
198
  # set a secret on the 'creators'
206
199
  @c1.secret = SecretSharing::Shamir::Secret.new
@@ -258,11 +251,9 @@ describe SecretSharing::Shamir::Container do
258
251
  @c2 << @c1.shares[3]
259
252
  lambda { @c2 << @c1.shares[4] }.must_raise(ArgumentError)
260
253
  end
261
-
262
254
  end
263
255
 
264
256
  describe 'with valid shares resulting from a random secret' do
265
-
266
257
  before do
267
258
  extend SecretSharing::Shamir
268
259
  # set a secret on both of the 'creators'
@@ -272,12 +263,12 @@ describe SecretSharing::Shamir::Container do
272
263
 
273
264
  # This exposed a bug in the prime number generation; for instance 4*8
274
265
  # passes.
275
- it 'should be able to recover secret with a bitlength of 5*8' do
276
- secret = SecretSharing::Shamir::Secret.new(:secret => get_random_number(5*8))
277
- c = SecretSharing::Shamir::Container.new(4,2)
266
+ it 'should be able to recover 40 bit secret' do
267
+ secret = SecretSharing::Shamir::Secret.new(:secret => get_random_number_with_bitlength(40))
268
+ c = SecretSharing::Shamir::Container.new(4, 2)
278
269
  c.secret = secret
279
270
 
280
- (0...4).to_a.permutation(2).collect{|e| e.sort}.uniq.each do |indexes|
271
+ (0...4).to_a.permutation(2).collect(&:sort).uniq.each do |indexes|
281
272
  c2 = SecretSharing::Shamir::Container.new(2)
282
273
  indexes.each do |index|
283
274
  c2 << c.shares[index]
@@ -365,9 +356,6 @@ describe SecretSharing::Shamir::Container do
365
356
  @c4.secret?.must_equal(true)
366
357
  @c4.secret.must_equal(@c3.secret)
367
358
  end
368
-
369
359
  end
370
-
371
360
  end # recovering a secret from a container
372
-
373
361
  end # describe SecretSharing::Shamir::Container
@@ -17,11 +17,21 @@
17
17
  require File.expand_path('../spec_helper', __FILE__)
18
18
 
19
19
  describe SecretSharing::Shamir::Secret do
20
+ describe 'initialization with Fixnum' do
21
+ before do
22
+ @num = 12345
23
+ @s = SecretSharing::Shamir::Secret.new(:secret => @num)
24
+ end
20
25
 
21
- describe 'initialization' do
26
+ it 'must initialize with a random secret and set @secret and @bitlength by default' do
27
+ @s.secret.is_a?(Integer).must_equal(true)
28
+ @s.bitlength.is_a?(Integer).must_equal(true)
29
+ end
30
+ end # describe initialization with Integer
22
31
 
32
+ describe 'initialization with Bignum' do
23
33
  before do
24
- @num = OpenSSL::BN.new('1234567890')
34
+ @num = 12345678909123098902183908908213829013
25
35
  @s = SecretSharing::Shamir::Secret.new(:secret => @num)
26
36
  end
27
37
 
@@ -42,24 +52,26 @@ describe SecretSharing::Shamir::Secret do
42
52
  end
43
53
 
44
54
  it 'must initialize with a random secret and set @secret and @bitlength by default' do
45
- @s.secret.is_a?(OpenSSL::BN).must_equal(true)
55
+ @s.secret.is_a?(Integer).must_equal(true)
46
56
  @s.bitlength.is_a?(Integer).must_equal(true)
47
57
  end
48
58
 
49
- it 'must raise an ArgumentError if an Integer instead of an OpenSSL::BN is provided to the constructor' do
50
- lambda { SecretSharing::Shamir::Secret.new(:secret => 1_234_567_890) }.must_raise(ArgumentError)
59
+ it 'must not raise an ArgumentError if the bitlength of the secret is equal to MAX_BITLENGTH' do
60
+ str_bits = '1' * SecretSharing::Shamir::Secret::MAX_BITLENGTH
61
+ s = SecretSharing::Shamir::Secret.new(:secret => str_bits.to_i(2))
62
+ s.is_a?(SecretSharing::Shamir::Secret).must_equal(true)
51
63
  end
52
64
 
53
65
  it 'must raise an ArgumentError if the bitlength of the secret is greater than MAX_BITLENGTH' do
54
- # 1234 * 1's is 4097 num_bits
55
- lambda { SecretSharing::Shamir::Secret.new(:secret => OpenSSL::BN.new("#{'1' * 1234}")) }.must_raise(ArgumentError)
66
+ str_bits = '1' * (SecretSharing::Shamir::Secret::MAX_BITLENGTH + 1)
67
+ lambda { SecretSharing::Shamir::Secret.new(:secret => str_bits.to_i(2)) }.must_raise(ArgumentError)
56
68
  end
57
69
 
58
- it 'must initialize with a fixed secret and set @secret and @bitlength to the same if passed an OpenSSL::BN' do
59
- @s.secret.is_a?(OpenSSL::BN).must_equal(true)
70
+ it 'must initialize with a fixed secret and set @secret and @bitlength to the same if passed a Bignum' do
71
+ @s.secret.is_a?(Integer).must_equal(true)
60
72
  @s.secret.must_equal(@num)
61
73
  @s.bitlength.is_a?(Integer).must_equal(true)
62
- @s.bitlength.must_equal(@num.num_bits)
74
+ @s.bitlength.must_equal(@num.bit_length)
63
75
  end
64
76
 
65
77
  it 'must throw an exception if initialized with a String that does not base64 re-hydrate as expected from the output of #to_s' do
@@ -74,7 +86,7 @@ describe SecretSharing::Shamir::Secret do
74
86
 
75
87
  it 'must use Base64.decode64 instead of Base64.urlsafe_decode64 on platform that is not true for Base64.respond_to?(:urlsafe_encode64)' do
76
88
  Base64.stub(:respond_to?, false) do
77
- num = OpenSSL::BN.new('1234567890123456789012345678901234567890')
89
+ num = 1234567890123456789012345678901234567890
78
90
  s1 = SecretSharing::Shamir::Secret.new(:secret => num)
79
91
  s1_str = s1.to_s
80
92
  s1_str.must_equal('MWl6aWJqZjR6dmRibXZxNjZkNndtOGcxY2k=')
@@ -86,8 +98,7 @@ describe SecretSharing::Shamir::Secret do
86
98
  end
87
99
 
88
100
  it 'must decode to the SAME String on mixed platforms that are, or are not, truthy for Base64.respond_to?(:urlsafe_decode64)' do
89
-
90
- # NOTE : OpenSSL::BN.new('1234567890123456789012345678901234567890')
101
+ # NOTE : 1234567890123456789012345678901234567890
91
102
  str = 'MWl6aWJqZjR6dmRibXZxNjZkNndtOGcxY2k='
92
103
  s2 = nil
93
104
  s3 = nil
@@ -115,35 +126,33 @@ describe SecretSharing::Shamir::Secret do
115
126
  it 'must throw an ArgumentError if an unknown option hash key is passed in' do
116
127
  lambda { SecretSharing::Shamir::Secret.new(:secret => 'foo\nbar', :unknown_arg => true) }.must_raise(ArgumentError)
117
128
  end
118
-
119
129
  end # describe initialization
120
130
 
121
131
  describe '==' do
122
-
123
132
  before do
124
- @num = OpenSSL::BN.new('1234567890')
133
+ @num = 1234567890
125
134
  @s = SecretSharing::Shamir::Secret.new(:secret => @num)
126
135
  end
127
136
 
128
- it 'must return true if two secrets have the same OpenSSL::BN set internally' do
137
+ it 'must return true if two secrets have the same Integer set internally' do
129
138
  s2 = @s
130
139
  (@s == s2).must_equal(true)
131
140
  end
132
141
 
133
- it 'must return false if two secrets have different OpenSSL::BN set internally' do
134
- s2 = SecretSharing::Shamir::Secret.new(:secret => OpenSSL::BN.new('987654321'))
142
+ it 'must return false if two secrets have different Integers set internally' do
143
+ s2 = SecretSharing::Shamir::Secret.new(:secret => 987654321)
135
144
  (@s == s2).must_equal(false)
136
145
  end
137
146
  end
138
147
 
139
148
  describe 'secret?' do
140
149
  before do
141
- @num = OpenSSL::BN.new('1234567890')
150
+ @num = 1234567890
142
151
  @s = SecretSharing::Shamir::Secret.new(:secret => @num)
143
152
  end
144
153
 
145
154
  it 'must return true if a secret is set' do
146
- @s.secret.is_a?(OpenSSL::BN).must_equal(true)
155
+ @s.secret.is_a?(Integer).must_equal(true)
147
156
  @s.secret?.must_equal(true)
148
157
  end
149
158
 
@@ -155,12 +164,12 @@ describe SecretSharing::Shamir::Secret do
155
164
 
156
165
  describe 'secret()' do
157
166
  before do
158
- @num = OpenSSL::BN.new('1234567890')
167
+ @num = 1234567890
159
168
  @s = SecretSharing::Shamir::Secret.new(:secret => @num)
160
169
  end
161
170
 
162
171
  it 'must return true if a secret is set' do
163
- @s.secret.is_a?(OpenSSL::BN).must_equal(true)
172
+ @s.secret.is_a?(Integer).must_equal(true)
164
173
  @s.secret?.must_equal(true)
165
174
  end
166
175
 
@@ -172,7 +181,7 @@ describe SecretSharing::Shamir::Secret do
172
181
 
173
182
  describe 'to_s' do
174
183
  it 'must return a proper and consistent URL safe encoded String representation of @secret and allow round trip of that String' do
175
- num = OpenSSL::BN.new('1234567890123456789012345678901234567890')
184
+ num = 1234567890123456789012345678901234567890
176
185
  s1 = SecretSharing::Shamir::Secret.new(:secret => num)
177
186
  s1_str = s1.to_s
178
187
  s1_str.must_equal('MWl6aWJqZjR6dmRibXZxNjZkNndtOGcxY2k=')
@@ -185,7 +194,7 @@ describe SecretSharing::Shamir::Secret do
185
194
 
186
195
  describe 'valid_hmac?' do
187
196
  before do
188
- @num = OpenSSL::BN.new('1234567890')
197
+ @num = 1234567890
189
198
  @s = SecretSharing::Shamir::Secret.new(:secret => @num)
190
199
  end
191
200
 
@@ -202,7 +211,5 @@ describe SecretSharing::Shamir::Secret do
202
211
  @s.hmac = @s.hmac + 'a'
203
212
  @s.valid_hmac?.must_equal(false)
204
213
  end
205
-
206
214
  end
207
-
208
215
  end # describe SecretSharing::Shamir::Secret
@@ -17,9 +17,7 @@
17
17
  require File.expand_path('../spec_helper', __FILE__)
18
18
 
19
19
  describe SecretSharing::Shamir::Share do
20
-
21
20
  describe 'initialization' do
22
-
23
21
  before do
24
22
  @args = { :hmac => 'foo', :k => 3, :n => 4, :x => 1, :y => 1, :prime => 1, :prime_bitlength => 1 }
25
23
  end
@@ -53,7 +51,5 @@ describe SecretSharing::Shamir::Share do
53
51
  @s2 = SecretSharing::Shamir::Share.new(:hmac => 'foo', :k => 3, :n => 4, :x => 1, :y => 1, :prime => 1, :prime_bitlength => 1)
54
52
  @s1.must_equal(@s2)
55
53
  end
56
-
57
54
  end
58
-
59
55
  end
@@ -16,20 +16,120 @@
16
16
 
17
17
  require File.expand_path('../spec_helper', __FILE__)
18
18
 
19
-
20
19
  describe SecretSharing::Shamir do
20
+ include SecretSharing::Shamir
21
+
22
+ describe 'get_random_number' do
23
+ it 'will return a Bignum' do
24
+ r = get_random_number(32)
25
+ r.class.must_equal(Bignum)
26
+ end
27
+
28
+ it 'will return a Bignum with a size equaling the requested number of Bytes' do
29
+ r = get_random_number(32)
30
+ r.class.must_equal(Bignum)
31
+ end
32
+ end
33
+
34
+ describe 'get_random_number_with_bitlength' do
35
+ it 'will return a Bignum' do
36
+ bitlength = 256
37
+ r = get_random_number_with_bitlength(bitlength)
38
+ r.class.must_equal(Bignum)
39
+ end
40
+
41
+ it 'will return a random number of bitlength bits when bitlength is evenly divisible by 8' do
42
+ bitlength = 256
43
+ r = get_random_number_with_bitlength(bitlength)
44
+ r.bit_length.must_equal(bitlength)
45
+ end
46
+
47
+ it 'will return a random number of bitlength bits when bitlength is not evenly divisible by 8' do
48
+ bitlength = 257
49
+ r = get_random_number_with_bitlength(bitlength)
50
+ r.bit_length.must_equal(bitlength)
51
+ end
52
+ end
53
+
54
+ describe 'miller_rabin_prime?' do
55
+ it 'will return true for the known primes <= 100' do
56
+ primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
57
+ primes.each do |p|
58
+ miller_rabin_prime?(p, 1000).must_equal(true)
59
+ end
60
+ end
61
+
62
+ it 'will return true for 128 bit known primes' do
63
+ # each generated with: get_prime_number(128)
64
+ # each was also confirmed to be prime with Wolfram Alpha "Is N prime?"
65
+ primes = [
66
+ 382767781724287998593870036291756450809,
67
+ 356939410756484930113231794428360705287,
68
+ 629759975992442345994901795062291065567,
69
+ 438321932766749553579901302755893165357,
70
+ 510959605072332037935633647489517878279
71
+ ]
72
+
73
+ primes.each do |p|
74
+ miller_rabin_prime?(p, 1000).must_equal(true)
75
+ end
76
+ end
77
+
78
+ it 'will return true for 512 bit known primes' do
79
+ # each generated with: get_prime_number(512)
80
+ # each was also confirmed to be prime with Wolfram Alpha "Is N prime?"
81
+ primes = [
82
+ 23999707866903326489156183307465540658883197873852940711009335379108363305023805329984215621371398530337791438685939745980557830310369653441114726729488047,
83
+ 26264879364280914726387337523874770984938759192907578453587351353319032004165834289093747124468183487116687747810871530759960877154788799650863513281542449,
84
+ 21419943505124415306535132543073126636345087246929370277918349432585089088938166354019597382594479966007308711525355781449302321333323114286893173242617447,
85
+ 15374852860017642027686544538337536903565786542098241857812378775632595902540222017334241111772863426942525633588495075859043584856426724378984665496611453,
86
+ 20279656133141646288468910535277192664988817199276725796792464746874102110167503650047272184232978918686592075892731325814289300758175615144548978275489781
87
+ ]
88
+
89
+ primes.each do |p|
90
+ miller_rabin_prime?(p, 1000).must_equal(true)
91
+ end
92
+ end
21
93
 
22
- describe 'usafe_encode64 and usafe_decode64' do
94
+ it 'will return false for 128 bit known non-primes' do
95
+ # each was also confirmed to NOT be prime with Wolfram Alpha "Is N prime?"
96
+ # these are the same as the 128 bit primes + 2
97
+ primes = [
98
+ 382767781724287998593870036291756450809 + 2,
99
+ 356939410756484930113231794428360705287 + 2,
100
+ 629759975992442345994901795062291065567 + 2,
101
+ 438321932766749553579901302755893165357 + 2,
102
+ 510959605072332037935633647489517878279 + 2
103
+ ]
23
104
 
24
- include SecretSharing::Shamir
105
+ primes.each do |p|
106
+ miller_rabin_prime?(p, 1000).must_equal(false)
107
+ end
108
+ end
109
+ end
110
+
111
+ describe 'get_prime_number' do
112
+ it 'will return a random prime odd number' do
113
+ p = get_prime_number(128)
114
+ p.odd?.must_equal(true)
115
+ end
25
116
 
26
- it 'will encode and decode back to the original String' do
27
- str = MultiJson.dump(:foo => 'bar', :bar => 12_345_678_748_390_743_789)
28
- enc = usafe_encode64(str)
29
- dec = usafe_decode64(enc)
30
- dec.must_equal(str)
117
+ it 'will return a random prime number of at least the specified bit length + 1' do
118
+ bit_length = 128
119
+ p = get_prime_number(bit_length)
120
+ (p.bit_length >= bit_length + 1).must_equal(true)
31
121
  end
32
122
 
123
+ it 'will return a random prime number that tests prime with the miller-rabin test' do
124
+ p = get_prime_number(128)
125
+ miller_rabin_prime?(p).must_equal(true)
126
+ end
33
127
  end
34
128
 
129
+ describe 'invmod' do
130
+ it 'will return a known value' do
131
+ # http://rosettacode.org/wiki/Modular_inverse#Ruby
132
+ invmod(42, 2017).must_equal(1969)
133
+ end
134
+ end
35
135
  end