secretsharing 0.3 → 1.0.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.
- checksums.yaml +7 -0
- data/.coco.yml +6 -0
- data/.gitignore +18 -0
- data/.rubocop.yml +29 -0
- data/.travis.yml +16 -0
- data/CHANGES +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +202 -0
- data/README.md +286 -0
- data/Rakefile +12 -0
- data/SIGNED.md +99 -0
- data/bin/secretsharing +111 -0
- data/gemfiles/Gemfile.ci +7 -0
- data/lib/secretsharing.rb +25 -0
- data/lib/secretsharing/shamir.rb +91 -293
- data/lib/secretsharing/shamir/container.rb +93 -0
- data/lib/secretsharing/shamir/secret.rb +123 -0
- data/lib/secretsharing/shamir/share.rb +156 -0
- data/lib/secretsharing/version.rb +20 -0
- data/secretsharing.gemspec +47 -0
- data/spec/shamir_container_spec.rb +373 -0
- data/spec/shamir_secret_spec.rb +208 -0
- data/spec/shamir_share_spec.rb +59 -0
- data/spec/shamir_spec.rb +35 -0
- data/spec/spec_helper.rb +33 -0
- metadata +204 -57
- data/README +0 -67
- data/test/test_shamir.rb +0 -161
data/README
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
== Description
|
2
|
-
A libary for sharing secrets in an information-theoretically secure way.
|
3
|
-
It uses Shamir's secret sharing to enable sharing a (random) secret between
|
4
|
-
n persons where k <= n persons are enough to recover the secret. k-1 secret
|
5
|
-
share holders learn nothing about the secret when they combine their shares.
|
6
|
-
|
7
|
-
This library is based on the OpenXPKI::Crypto::Secret::Split Perl module used
|
8
|
-
in the open source PKI software OpenXPKI, which was written by Alexander Klink
|
9
|
-
for the OpenXPKI project in 2006.
|
10
|
-
|
11
|
-
== Prerequisites
|
12
|
-
This package requires Ruby 1.8 or later.
|
13
|
-
|
14
|
-
== Installation instructions
|
15
|
-
rake test (optional)
|
16
|
-
rake install (non-gem) or rake install_gem (gem)
|
17
|
-
|
18
|
-
== Synopsis
|
19
|
-
require 'secretsharing'
|
20
|
-
|
21
|
-
# create an object for 3 out of 5 secret sharing
|
22
|
-
s = SecretSharing::Shamir.new(5,3)
|
23
|
-
|
24
|
-
# create a random secret (returns the secret)
|
25
|
-
s.create_random_secret()
|
26
|
-
|
27
|
-
# show secret
|
28
|
-
puts s.secret
|
29
|
-
|
30
|
-
# show password representation of secret (Base64)
|
31
|
-
puts s.secret_password
|
32
|
-
|
33
|
-
# show shares
|
34
|
-
s.shares.each { |share| puts share }
|
35
|
-
|
36
|
-
# recover secret from shares
|
37
|
-
|
38
|
-
s2 = SecretSharing::Shamir.new(3)
|
39
|
-
# accepts SecretSharing::Shamir::Share objects or
|
40
|
-
# string representations thereof
|
41
|
-
s2 << s.shares[0]
|
42
|
-
s2 << s.shares[2]
|
43
|
-
s2 << s.shares[4]
|
44
|
-
puts s2.secret
|
45
|
-
|
46
|
-
== Copyright
|
47
|
-
(c) 2010-2011 Alexander Klink
|
48
|
-
|
49
|
-
== License
|
50
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
51
|
-
you may not use this file except in compliance with the License.
|
52
|
-
You may obtain a copy of the License at
|
53
|
-
|
54
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
55
|
-
|
56
|
-
== Warranty
|
57
|
-
Unless required by applicable law or agreed to in writing, software
|
58
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
59
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
60
|
-
See the License for the specific language governing permissions and
|
61
|
-
limitations under the License.
|
62
|
-
|
63
|
-
== Author
|
64
|
-
Alexander Klink
|
65
|
-
secretsharing@alech.de
|
66
|
-
http://www.alech.de
|
67
|
-
@alech on Twitter
|
data/test/test_shamir.rb
DELETED
@@ -1,161 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'lib/secretsharing/shamir'
|
3
|
-
|
4
|
-
DEFAULT_SECRET_BITLENGTH = 256
|
5
|
-
|
6
|
-
class TestShamir < Test::Unit::TestCase
|
7
|
-
def test_instantiation
|
8
|
-
assert_raise( ArgumentError ) { SecretSharing::Shamir.new }
|
9
|
-
s1 = SecretSharing::Shamir.new(5)
|
10
|
-
assert_equal(5, s1.n)
|
11
|
-
assert_equal(5, s1.k)
|
12
|
-
assert(! s1.secret_set?)
|
13
|
-
s2 = SecretSharing::Shamir.new(5, 3)
|
14
|
-
assert_equal(5, s2.n)
|
15
|
-
assert_equal(3, s2.k)
|
16
|
-
assert(! s2.secret_set?)
|
17
|
-
assert_raise( ArgumentError ) { SecretSharing::Shamir.new(5, 7) }
|
18
|
-
assert_raise( ArgumentError ) { SecretSharing::Shamir.new(1) }
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_create_random_secret
|
22
|
-
s = SecretSharing::Shamir.new(5)
|
23
|
-
s.create_random_secret()
|
24
|
-
assert(s.secret_set?)
|
25
|
-
assert_not_nil(s.secret)
|
26
|
-
assert_not_nil(s.shares)
|
27
|
-
assert_equal(Array, s.shares.class)
|
28
|
-
assert_equal(5, s.shares.length)
|
29
|
-
assert_equal(SecretSharing::Shamir::Share, s.shares[0].class)
|
30
|
-
assert_equal(DEFAULT_SECRET_BITLENGTH, s.secret_bitlength)
|
31
|
-
|
32
|
-
# can only be called once
|
33
|
-
assert_raise( RuntimeError) { s.create_random_secret() }
|
34
|
-
|
35
|
-
s2 = SecretSharing::Shamir.new(7)
|
36
|
-
s2.create_random_secret(512)
|
37
|
-
assert_equal(512, s2.secret_bitlength)
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_set_fixed_secret
|
41
|
-
s = SecretSharing::Shamir.new(5)
|
42
|
-
s.set_fixed_secret(OpenSSL::BN.new('12345678901234567890'))
|
43
|
-
assert(s.secret_set?)
|
44
|
-
assert_not_nil(s.secret)
|
45
|
-
assert_not_nil(s.shares)
|
46
|
-
assert_equal(Array, s.shares.class)
|
47
|
-
assert_equal(5, s.shares.length)
|
48
|
-
assert_equal(SecretSharing::Shamir::Share, s.shares[0].class)
|
49
|
-
assert_equal(64, s.secret_bitlength)
|
50
|
-
|
51
|
-
# can only be called once
|
52
|
-
assert_raise( RuntimeError) {
|
53
|
-
s.set_fixed_secret(OpenSSL::BN.new('12345678901234567891')) }
|
54
|
-
|
55
|
-
# test using string as parameter instead of OpenSSL::BN instance
|
56
|
-
s2 = SecretSharing::Shamir.new(5)
|
57
|
-
s2.set_fixed_secret('12345678901234567890')
|
58
|
-
assert(s2.secret_set?)
|
59
|
-
assert_not_nil(s2.secret)
|
60
|
-
assert_not_nil(s2.shares)
|
61
|
-
assert_equal(Array, s2.shares.class)
|
62
|
-
assert_equal(5, s2.shares.length)
|
63
|
-
assert_equal(SecretSharing::Shamir::Share, s2.shares[0].class)
|
64
|
-
assert_equal(64, s2.secret_bitlength)
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_recover_secret_k_eq_n
|
68
|
-
s = SecretSharing::Shamir.new(5)
|
69
|
-
s.create_random_secret()
|
70
|
-
|
71
|
-
s2 = SecretSharing::Shamir.new(5)
|
72
|
-
s2 << s.shares[0]
|
73
|
-
assert(! s2.secret_set?)
|
74
|
-
assert_nil(s2.secret)
|
75
|
-
# adding the same share raises an error
|
76
|
-
assert_raise( RuntimeError ) { s2 << s.shares[0] }
|
77
|
-
# add more shares
|
78
|
-
s2 << s.shares[1]
|
79
|
-
assert(! s2.secret_set?)
|
80
|
-
s2 << s.shares[2]
|
81
|
-
assert(! s2.secret_set?)
|
82
|
-
s2 << s.shares[3]
|
83
|
-
assert(! s2.secret_set?)
|
84
|
-
s2 << s.shares[4]
|
85
|
-
assert(s2.secret_set?)
|
86
|
-
assert_equal(s.secret, s2.secret)
|
87
|
-
end
|
88
|
-
|
89
|
-
def test_recover_secret_k_eq_n_fixed_secret
|
90
|
-
s = SecretSharing::Shamir.new(5)
|
91
|
-
secret = OpenSSL::BN.new('1234567890123456789012345678901234567890')
|
92
|
-
|
93
|
-
s.set_fixed_secret(secret)
|
94
|
-
|
95
|
-
s2 = SecretSharing::Shamir.new(5)
|
96
|
-
s2 << s.shares[0]
|
97
|
-
assert(! s2.secret_set?)
|
98
|
-
assert_nil(s2.secret)
|
99
|
-
# adding the same share raises an error
|
100
|
-
assert_raise( RuntimeError ) { s2 << s.shares[0] }
|
101
|
-
# add more shares
|
102
|
-
s2 << s.shares[1]
|
103
|
-
assert(! s2.secret_set?)
|
104
|
-
s2 << s.shares[2]
|
105
|
-
assert(! s2.secret_set?)
|
106
|
-
s2 << s.shares[3]
|
107
|
-
assert(! s2.secret_set?)
|
108
|
-
s2 << s.shares[4]
|
109
|
-
assert(s2.secret_set?)
|
110
|
-
assert_equal(secret, s2.secret)
|
111
|
-
end
|
112
|
-
|
113
|
-
def test_recover_secret_k_eq_n_strings
|
114
|
-
s = SecretSharing::Shamir.new(2)
|
115
|
-
s.create_random_secret()
|
116
|
-
|
117
|
-
s2 = SecretSharing::Shamir.new(2)
|
118
|
-
s2 << s.shares[0].to_s
|
119
|
-
s2 << s.shares[1].to_s
|
120
|
-
|
121
|
-
assert_equal(s.secret, s2.secret)
|
122
|
-
end
|
123
|
-
|
124
|
-
def test_recover_secret_k_le_n
|
125
|
-
s = SecretSharing::Shamir.new(5, 3)
|
126
|
-
s.create_random_secret()
|
127
|
-
|
128
|
-
s2 = SecretSharing::Shamir.new(5, 3)
|
129
|
-
s2 << s.shares[0]
|
130
|
-
assert(! s2.secret_set?)
|
131
|
-
assert_nil(s2.secret)
|
132
|
-
# add more shares
|
133
|
-
s2 << s.shares[1]
|
134
|
-
assert(! s2.secret_set?)
|
135
|
-
s2 << s.shares[2]
|
136
|
-
assert(s2.secret_set?)
|
137
|
-
assert_equal(s.secret, s2.secret)
|
138
|
-
|
139
|
-
# adding more shares than needed raises an error
|
140
|
-
assert_raise( RuntimeError ) { s2 << s.shares[3] }
|
141
|
-
end
|
142
|
-
|
143
|
-
def test_recover_secret_k_le_n_strings
|
144
|
-
s = SecretSharing::Shamir.new(5, 3)
|
145
|
-
s.create_random_secret()
|
146
|
-
|
147
|
-
s2 = SecretSharing::Shamir.new(5, 3)
|
148
|
-
s2 << "#{s.shares[0]}"
|
149
|
-
assert(! s2.secret_set?)
|
150
|
-
assert_nil(s2.secret)
|
151
|
-
# add more shares
|
152
|
-
s2 << "#{s.shares[1]}"
|
153
|
-
assert(! s2.secret_set?)
|
154
|
-
s2 << s.shares[2].to_s
|
155
|
-
assert(s2.secret_set?)
|
156
|
-
assert_equal(s.secret, s2.secret)
|
157
|
-
|
158
|
-
# adding more shares than needed raises an error
|
159
|
-
assert_raise( RuntimeError ) { s2 << s.shares[3] }
|
160
|
-
end
|
161
|
-
end
|