sssa-ruby 0.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.
- checksums.yaml +7 -0
- data/lib/sssa.rb +82 -0
- data/lib/utils.rb +96 -0
- metadata +45 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3aecd0e42e5047d1532c46b18f66ec58a524bc18
|
4
|
+
data.tar.gz: 27e881caf6974a1fa15cd8193d17adf544a71195
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1af87f8d90b8f3424c7076398a04aeed005ccacfc96b8de5baef55de43ae34bb5b9bde7aee275a01745a884b7d88e1d982ec072f96213efe5826a6d96966139f
|
7
|
+
data.tar.gz: 487e533db0993f2ec11e29bd5cefe07703cc7e2394ac52ccd65617d872430f283613cd06ec80f52acd7c70878f3d5fd616a13bdb1c7d2a3cb8ad45e5cf6fd123
|
data/lib/sssa.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative './utils.rb'
|
2
|
+
|
3
|
+
module SSSA
|
4
|
+
@prime = 99995644905598542077721161034987774965417302630805822064337798850767846245779
|
5
|
+
@util = SSSA::Utils.new
|
6
|
+
|
7
|
+
def self.create(minimum, shares, raw)
|
8
|
+
secret = @util.split_ints(raw)
|
9
|
+
numbers = [0]
|
10
|
+
polynomial = []
|
11
|
+
(0...secret.size).each do |i|
|
12
|
+
polynomial.push [secret[i]]
|
13
|
+
(1...minimum).each do |j|
|
14
|
+
value = @util.random()
|
15
|
+
while numbers.include? value
|
16
|
+
value = @util.random()
|
17
|
+
end
|
18
|
+
numbers.push value
|
19
|
+
polynomial[i].push value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
result = [""]*shares
|
24
|
+
|
25
|
+
(0...shares).each do |i|
|
26
|
+
(0...secret.size).each do |j|
|
27
|
+
value = @util.random()
|
28
|
+
while numbers.include? value
|
29
|
+
value = @util.random()
|
30
|
+
end
|
31
|
+
|
32
|
+
y = @util.evaluate_polynomial(polynomial[j], value)
|
33
|
+
|
34
|
+
result[i] += @util.to_base64(value)
|
35
|
+
result[i] += @util.to_base64(y)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
return result
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.combine(shares)
|
43
|
+
secrets = []
|
44
|
+
|
45
|
+
shares.each_with_index do |share, index|
|
46
|
+
if share.size % 88 != 0
|
47
|
+
return
|
48
|
+
end
|
49
|
+
|
50
|
+
count = share.size / 88
|
51
|
+
secrets.push []
|
52
|
+
|
53
|
+
(0...count).each do |i|
|
54
|
+
cshare = share[i*88, (i+1)*88]
|
55
|
+
secrets[index][i] = [@util.from_base64(cshare[0...44]), @util.from_base64(cshare[44...88])]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
secret = [0] * secrets[0].size
|
60
|
+
|
61
|
+
secret.each_with_index do |part, part_index|
|
62
|
+
secrets.each_with_index do |share, share_index|
|
63
|
+
origin = share[part_index][0]
|
64
|
+
originy = share[part_index][1]
|
65
|
+
numerator = 1
|
66
|
+
denominator = 1
|
67
|
+
secrets.each_with_index do |product, product_index|
|
68
|
+
if product_index != share_index
|
69
|
+
current = product[part_index][0]
|
70
|
+
numerator = (numerator * (-1*current)) % @prime
|
71
|
+
denominator = (denominator * (origin - current)) % @prime
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
working = ((originy * numerator * @util.mod_inverse(denominator)) + @prime)
|
76
|
+
secret[part_index] = (secret[part_index] + working) % @prime
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
return @util.merge_ints(secret)
|
81
|
+
end
|
82
|
+
end
|
data/lib/utils.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module SSSA
|
5
|
+
class Utils
|
6
|
+
attr_accessor :prime
|
7
|
+
|
8
|
+
def initialize()
|
9
|
+
# 256-bit prime
|
10
|
+
@prime = 99995644905598542077721161034987774965417302630805822064337798850767846245779
|
11
|
+
end
|
12
|
+
|
13
|
+
def random()
|
14
|
+
return SecureRandom.random_number(@prime)
|
15
|
+
end
|
16
|
+
|
17
|
+
def split_ints(secret)
|
18
|
+
result = []
|
19
|
+
|
20
|
+
secret.scan(/.{1,32}/) do |part|
|
21
|
+
segment = part.split('').map do |x|
|
22
|
+
if x.ord > 15
|
23
|
+
x.ord.to_s(16)
|
24
|
+
else
|
25
|
+
"0" + x.ord.to_s(16)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
result.push (segment+["00"]*(32-segment.size)).join.hex
|
29
|
+
end
|
30
|
+
|
31
|
+
return result
|
32
|
+
end
|
33
|
+
|
34
|
+
def merge_ints(secrets)
|
35
|
+
result = ""
|
36
|
+
|
37
|
+
secrets.each_with_index do |secret, index|
|
38
|
+
if index == secrets.size-1
|
39
|
+
result += ("0"*(64-secret.to_s(16).size) + secret.to_s(16)).scan(/../).map{|x| x.hex.chr}.join.gsub(/\x00*$/, '')
|
40
|
+
else
|
41
|
+
result += ("0"*(64-secret.to_s(16).size) + secret.to_s(16)).scan(/../).map{|x| x.hex.chr}.join
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
return result
|
46
|
+
end
|
47
|
+
|
48
|
+
def evaluate_polynomial(coefficients, value)
|
49
|
+
result = 0
|
50
|
+
coefficients.each_with_index do |coefficient, exponent|
|
51
|
+
expmod = 1
|
52
|
+
(0...exponent).each do
|
53
|
+
expmod = (expmod * value) % @prime
|
54
|
+
end
|
55
|
+
result += coefficient * expmod
|
56
|
+
result = result % @prime
|
57
|
+
end
|
58
|
+
|
59
|
+
return result
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_base64(number)
|
63
|
+
return Base64.urlsafe_encode64(("0"*(64-number.to_s(16).size) + number.to_s(16)).scan(/../).map{|x| x.hex.chr}.join)
|
64
|
+
end
|
65
|
+
|
66
|
+
def from_base64(number)
|
67
|
+
segment = Base64.urlsafe_decode64(number).split('').map do |x|
|
68
|
+
if x.ord > 15
|
69
|
+
x.ord.to_s(16)
|
70
|
+
else
|
71
|
+
"0" + x.ord.to_s(16)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
return (segment+["00"]*(32-segment.size)).join.hex
|
75
|
+
end
|
76
|
+
|
77
|
+
def gcd(a, b)
|
78
|
+
if b == 0
|
79
|
+
return [a, 1, 0]
|
80
|
+
else
|
81
|
+
n = (a*1.0/b).floor
|
82
|
+
c = a % b
|
83
|
+
r = gcd(b, c)
|
84
|
+
return [r[0], r[2], r[1]-r[2]*n]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def mod_inverse(number)
|
89
|
+
remainder = gcd(@prime, number % @prime)[2]
|
90
|
+
if (number < 0)
|
91
|
+
remainder *= -1
|
92
|
+
end
|
93
|
+
return (@prime + remainder) % @prime
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sssa-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexander Scheel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-18 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Helper cryptography module for Ruby
|
14
|
+
email: alexander.m.scheel@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/sssa.rb
|
20
|
+
- lib/utils.rb
|
21
|
+
homepage: https://github.com/SSSAAS/sssa-ruby
|
22
|
+
licenses:
|
23
|
+
- MIT
|
24
|
+
metadata: {}
|
25
|
+
post_install_message:
|
26
|
+
rdoc_options: []
|
27
|
+
require_paths:
|
28
|
+
- lib
|
29
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
requirements: []
|
40
|
+
rubyforge_project:
|
41
|
+
rubygems_version: 2.0.14
|
42
|
+
signing_key:
|
43
|
+
specification_version: 4
|
44
|
+
summary: Shamir's Secret Sharing Algorithm
|
45
|
+
test_files: []
|