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