secretsharing 0.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,208 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ # Copyright 2011-2015 Glenn Rempe
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require File.expand_path('../spec_helper', __FILE__)
18
+
19
+ describe SecretSharing::Shamir::Secret do
20
+
21
+ describe 'initialization' do
22
+
23
+ before do
24
+ @num = OpenSSL::BN.new('1234567890')
25
+ @s = SecretSharing::Shamir::Secret.new(:secret => @num)
26
+ end
27
+
28
+ it 'must return the correct max secret bitlength constant value' do
29
+ SecretSharing::Shamir::Secret::MAX_BITLENGTH.must_equal(4096)
30
+ end
31
+
32
+ it 'must respond to #secret' do
33
+ @s.respond_to?(:secret).must_equal(true)
34
+ end
35
+
36
+ it 'must respond to #bitlength' do
37
+ @s.respond_to?(:bitlength).must_equal(true)
38
+ end
39
+
40
+ it 'must respond to #valid_hmac?' do
41
+ @s.respond_to?(:valid_hmac?).must_equal(true)
42
+ end
43
+
44
+ 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)
46
+ @s.bitlength.is_a?(Integer).must_equal(true)
47
+ end
48
+
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)
51
+ end
52
+
53
+ 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)
56
+ end
57
+
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)
60
+ @s.secret.must_equal(@num)
61
+ @s.bitlength.is_a?(Integer).must_equal(true)
62
+ @s.bitlength.must_equal(@num.num_bits)
63
+ end
64
+
65
+ 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
66
+ lambda { SecretSharing::Shamir::Secret.new(:secret => 'foo') }.must_raise(ArgumentError)
67
+ end
68
+
69
+ it 'must throw an exception if initialized with a String that contains \n on platform that is not true for Base64.respond_to?(:urlsafe_encode64)' do
70
+ Base64.stub(:respond_to?, false) do
71
+ lambda { SecretSharing::Shamir::Secret.new(:secret => 'foo\nbar') }.must_raise(ArgumentError)
72
+ end
73
+ end
74
+
75
+ it 'must use Base64.decode64 instead of Base64.urlsafe_decode64 on platform that is not true for Base64.respond_to?(:urlsafe_encode64)' do
76
+ Base64.stub(:respond_to?, false) do
77
+ num = OpenSSL::BN.new('1234567890123456789012345678901234567890')
78
+ s1 = SecretSharing::Shamir::Secret.new(:secret => num)
79
+ s1_str = s1.to_s
80
+ s1_str.must_equal('MWl6aWJqZjR6dmRibXZxNjZkNndtOGcxY2k=')
81
+
82
+ # Re-hydrate a new Secret object from the previously de-hydrated String
83
+ s2 = SecretSharing::Shamir::Secret.new(:secret => s1_str)
84
+ s2.must_equal(s1)
85
+ end
86
+ end
87
+
88
+ 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')
91
+ str = 'MWl6aWJqZjR6dmRibXZxNjZkNndtOGcxY2k='
92
+ s2 = nil
93
+ s3 = nil
94
+
95
+ s1 = SecretSharing::Shamir::Secret.new(:secret => str)
96
+ s1_str = s1.to_s
97
+ s1_str.must_equal(str)
98
+
99
+ Base64.stub(:respond_to?, false) do
100
+ s2 = SecretSharing::Shamir::Secret.new(:secret => str)
101
+ s2_str = s2.to_s
102
+ s2_str.must_equal(str)
103
+ end
104
+
105
+ Base64.stub(:respond_to?, false) do
106
+ s3 = SecretSharing::Shamir::Secret.new(:secret => str)
107
+ s3_str = s3.to_s
108
+ s3_str.must_equal(str)
109
+ end
110
+
111
+ s1.must_equal(s2)
112
+ s1.must_equal(s3)
113
+ end
114
+
115
+ it 'must throw an ArgumentError if an unknown option hash key is passed in' do
116
+ lambda { SecretSharing::Shamir::Secret.new(:secret => 'foo\nbar', :unknown_arg => true) }.must_raise(ArgumentError)
117
+ end
118
+
119
+ end # describe initialization
120
+
121
+ describe '==' do
122
+
123
+ before do
124
+ @num = OpenSSL::BN.new('1234567890')
125
+ @s = SecretSharing::Shamir::Secret.new(:secret => @num)
126
+ end
127
+
128
+ it 'must return true if two secrets have the same OpenSSL::BN set internally' do
129
+ s2 = @s
130
+ (@s == s2).must_equal(true)
131
+ end
132
+
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'))
135
+ (@s == s2).must_equal(false)
136
+ end
137
+ end
138
+
139
+ describe 'secret?' do
140
+ before do
141
+ @num = OpenSSL::BN.new('1234567890')
142
+ @s = SecretSharing::Shamir::Secret.new(:secret => @num)
143
+ end
144
+
145
+ it 'must return true if a secret is set' do
146
+ @s.secret.is_a?(OpenSSL::BN).must_equal(true)
147
+ @s.secret?.must_equal(true)
148
+ end
149
+
150
+ it 'must return false if a secret is not set' do
151
+ @s.secret = nil
152
+ @s.secret?.must_equal(false)
153
+ end
154
+ end
155
+
156
+ describe 'secret()' do
157
+ before do
158
+ @num = OpenSSL::BN.new('1234567890')
159
+ @s = SecretSharing::Shamir::Secret.new(:secret => @num)
160
+ end
161
+
162
+ it 'must return true if a secret is set' do
163
+ @s.secret.is_a?(OpenSSL::BN).must_equal(true)
164
+ @s.secret?.must_equal(true)
165
+ end
166
+
167
+ it 'must return false if a secret is not set' do
168
+ @s.secret = nil
169
+ @s.secret?.must_equal(false)
170
+ end
171
+ end
172
+
173
+ describe 'to_s' do
174
+ 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')
176
+ s1 = SecretSharing::Shamir::Secret.new(:secret => num)
177
+ s1_str = s1.to_s
178
+ s1_str.must_equal('MWl6aWJqZjR6dmRibXZxNjZkNndtOGcxY2k=')
179
+
180
+ # Re-hydrate a new Secret object from the previously de-hydrated String
181
+ s2 = SecretSharing::Shamir::Secret.new(:secret => s1_str)
182
+ s2.must_equal(s1)
183
+ end
184
+ end
185
+
186
+ describe 'valid_hmac?' do
187
+ before do
188
+ @num = OpenSSL::BN.new('1234567890')
189
+ @s = SecretSharing::Shamir::Secret.new(:secret => @num)
190
+ end
191
+
192
+ it 'must return true if a a valid HMAC based on the secret is set' do
193
+ @s.valid_hmac?.must_equal(true)
194
+ end
195
+
196
+ it 'must return false if a secret is not set' do
197
+ @s.secret = nil
198
+ @s.valid_hmac?.must_equal(false)
199
+ end
200
+
201
+ it 'must return false if the HMAC was tampered with at all' do
202
+ @s.hmac = @s.hmac + 'a'
203
+ @s.valid_hmac?.must_equal(false)
204
+ end
205
+
206
+ end
207
+
208
+ end # describe SecretSharing::Shamir::Secret
@@ -0,0 +1,59 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ # Copyright 2011-2015 Glenn Rempe
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require File.expand_path('../spec_helper', __FILE__)
18
+
19
+ describe SecretSharing::Shamir::Share do
20
+
21
+ describe 'initialization' do
22
+
23
+ before do
24
+ @args = { :hmac => 'foo', :k => 3, :n => 4, :x => 1, :y => 1, :prime => 1, :prime_bitlength => 1 }
25
+ end
26
+
27
+ it 'will raise when instantiated with no args' do
28
+ lambda { SecretSharing::Shamir::Share.new }.must_raise(ArgumentError)
29
+ end
30
+
31
+ it 'will raise if an unknown option hash key is passed in' do
32
+ lambda { SecretSharing::Shamir::Share.new(@args.merge(:foo => 'bar')) }.must_raise(ArgumentError)
33
+ end
34
+
35
+ it 'will raise when instantiated with missing args' do
36
+ lambda { SecretSharing::Shamir::Share.new(@args.merge(:version => nil)) }.must_raise(ArgumentError)
37
+ lambda { SecretSharing::Shamir::Share.new(@args.merge(:hmac => nil)) }.must_raise(ArgumentError)
38
+ lambda { SecretSharing::Shamir::Share.new(@args.merge(:k => nil)) }.must_raise(ArgumentError)
39
+ lambda { SecretSharing::Shamir::Share.new(@args.merge(:n => nil)) }.must_raise(ArgumentError)
40
+ lambda { SecretSharing::Shamir::Share.new(@args.merge(:x => nil)) }.must_raise(ArgumentError)
41
+ lambda { SecretSharing::Shamir::Share.new(@args.merge(:y => nil)) }.must_raise(ArgumentError)
42
+ lambda { SecretSharing::Shamir::Share.new(@args.merge(:prime => nil)) }.must_raise(ArgumentError)
43
+ lambda { SecretSharing::Shamir::Share.new(@args.merge(:prime_bitlength => nil)) }.must_raise(ArgumentError)
44
+ end
45
+
46
+ it 'will be instantiated when provided with complete args' do
47
+ @s = SecretSharing::Shamir::Share.new(:hmac => 'foo', :k => 3, :n => 4, :x => 1, :y => 1, :prime => 1, :prime_bitlength => 1)
48
+ @s.must_be_kind_of(SecretSharing::Shamir::Share)
49
+ end
50
+
51
+ it 'must be able to be compared directly to another share (==)' do
52
+ @s1 = SecretSharing::Shamir::Share.new(:hmac => 'foo', :k => 3, :n => 4, :x => 1, :y => 1, :prime => 1, :prime_bitlength => 1)
53
+ @s2 = SecretSharing::Shamir::Share.new(:hmac => 'foo', :k => 3, :n => 4, :x => 1, :y => 1, :prime => 1, :prime_bitlength => 1)
54
+ @s1.must_equal(@s2)
55
+ end
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ # Copyright 2011-2015 Glenn Rempe
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require File.expand_path('../spec_helper', __FILE__)
18
+
19
+
20
+ describe SecretSharing::Shamir do
21
+
22
+ describe 'usafe_encode64 and usafe_decode64' do
23
+
24
+ include SecretSharing::Shamir
25
+
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)
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ # Copyright 2011-2015 Glenn Rempe
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'rubygems'
18
+ require 'bundler'
19
+ Bundler.setup
20
+
21
+ # code coverage
22
+ begin
23
+ require 'coco'
24
+ rescue LoadError
25
+ # Don't blow up if coco isn't available.
26
+ # It won't install on MRI Ruby < 1.9.2 or
27
+ # other platforms. It is not installed
28
+ # in the Travis CI build environment.
29
+ end
30
+
31
+ require File.expand_path('../../lib/secretsharing', __FILE__)
32
+ require 'minitest/autorun'
33
+ require 'mocha/setup'
metadata CHANGED
@@ -1,74 +1,221 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: secretsharing
3
- version: !ruby/object:Gem::Version
4
- hash: 13
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 3
9
- version: "0.3"
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
10
5
  platform: ruby
11
- authors:
6
+ authors:
12
7
  - Alexander Klink
8
+ - Glenn Rempe
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2011-06-27 00:00:00 +02:00
18
- default_executable:
19
- dependencies: []
20
-
12
+ date: 2015-01-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: highline
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.6'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.6'
28
+ - !ruby/object:Gem::Dependency
29
+ name: multi_json
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.10'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.10'
42
+ - !ruby/object:Gem::Dependency
43
+ name: mocha
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: minitest
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: coco
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rb-fsevent
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: rerun
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: rubocop
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: bundler
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: '1.7'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '1.7'
140
+ - !ruby/object:Gem::Dependency
141
+ name: rake
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - "~>"
145
+ - !ruby/object:Gem::Version
146
+ version: '10.4'
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - "~>"
152
+ - !ruby/object:Gem::Version
153
+ version: '10.4'
21
154
  description: |
22
- A libary for sharing secrets in an information-theoretically secure way.
23
- It uses Shamir's secret sharing to enable sharing a (random) secret between
24
- n persons where k <= n persons are enough to recover the secret. k-1 secret
25
- share holders learn nothing about the secret when they combine their shares.
26
-
27
- email: secretsharing@alech.de
28
- executables: []
29
-
155
+ Shamir's Secret Sharing is an algorithm in cryptography. It is a
156
+ form of secret sharing, where a secret is divided into parts,
157
+ giving each participant its own unique part, where some of the
158
+ parts or all of them are needed in order to reconstruct the
159
+ secret. Holders of a share gain no knowledge of the larger secret.
160
+ email:
161
+ - glenn@rempe.us
162
+ executables:
163
+ - secretsharing
30
164
  extensions: []
31
-
32
- extra_rdoc_files:
33
- - README
34
- files:
165
+ extra_rdoc_files:
166
+ - README.md
167
+ files:
168
+ - ".coco.yml"
169
+ - ".gitignore"
170
+ - ".rubocop.yml"
171
+ - ".travis.yml"
172
+ - CHANGES
173
+ - Gemfile
174
+ - LICENSE.txt
175
+ - README.md
176
+ - Rakefile
177
+ - SIGNED.md
178
+ - bin/secretsharing
179
+ - gemfiles/Gemfile.ci
35
180
  - lib/secretsharing.rb
36
181
  - lib/secretsharing/shamir.rb
37
- - test/test_shamir.rb
38
- - README
39
- has_rdoc: true
40
- homepage:
41
- licenses: []
42
-
182
+ - lib/secretsharing/shamir/container.rb
183
+ - lib/secretsharing/shamir/secret.rb
184
+ - lib/secretsharing/shamir/share.rb
185
+ - lib/secretsharing/version.rb
186
+ - secretsharing.gemspec
187
+ - spec/shamir_container_spec.rb
188
+ - spec/shamir_secret_spec.rb
189
+ - spec/shamir_share_spec.rb
190
+ - spec/shamir_spec.rb
191
+ - spec/spec_helper.rb
192
+ homepage: https://github.com/grempe/secretsharing
193
+ licenses:
194
+ - APACHE 2.0
195
+ metadata: {}
43
196
  post_install_message:
44
197
  rdoc_options: []
45
-
46
- require_paths:
198
+ require_paths:
47
199
  - lib
48
- required_ruby_version: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
200
+ required_ruby_version: !ruby/object:Gem::Requirement
201
+ requirements:
51
202
  - - ">="
52
- - !ruby/object:Gem::Version
53
- hash: 3
54
- segments:
55
- - 0
56
- version: "0"
57
- required_rubygems_version: !ruby/object:Gem::Requirement
58
- none: false
59
- requirements:
203
+ - !ruby/object:Gem::Version
204
+ version: '0'
205
+ required_rubygems_version: !ruby/object:Gem::Requirement
206
+ requirements:
60
207
  - - ">="
61
- - !ruby/object:Gem::Version
62
- hash: 3
63
- segments:
64
- - 0
65
- version: "0"
208
+ - !ruby/object:Gem::Version
209
+ version: '0'
66
210
  requirements: []
67
-
68
- rubyforge_project:
69
- rubygems_version: 1.3.7
211
+ rubyforge_project: secretsharing
212
+ rubygems_version: 2.4.5
70
213
  signing_key:
71
- specification_version: 3
72
- summary: A library to share secrets in an information-theoretically secure way.
73
- test_files:
74
- - test/test_shamir.rb
214
+ specification_version: 4
215
+ summary: A Ruby Gem to enable sharing secrets using Shamirs Secret Sharing.
216
+ test_files:
217
+ - spec/shamir_container_spec.rb
218
+ - spec/shamir_secret_spec.rb
219
+ - spec/shamir_share_spec.rb
220
+ - spec/shamir_spec.rb
221
+ - spec/spec_helper.rb