secretsharing 1.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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