sssa-ruby 0.0.1 → 0.0.2

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sssa.rb +9 -2
  3. data/lib/utils.rb +36 -22
  4. metadata +5 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3aecd0e42e5047d1532c46b18f66ec58a524bc18
4
- data.tar.gz: 27e881caf6974a1fa15cd8193d17adf544a71195
3
+ metadata.gz: fd3e16a5c803de5268c6a029a45f74fe14624866
4
+ data.tar.gz: 14373c800240d29842118335d6191f025dfd3d18
5
5
  SHA512:
6
- metadata.gz: 1af87f8d90b8f3424c7076398a04aeed005ccacfc96b8de5baef55de43ae34bb5b9bde7aee275a01745a884b7d88e1d982ec072f96213efe5826a6d96966139f
7
- data.tar.gz: 487e533db0993f2ec11e29bd5cefe07703cc7e2394ac52ccd65617d872430f283613cd06ec80f52acd7c70878f3d5fd616a13bdb1c7d2a3cb8ad45e5cf6fd123
6
+ metadata.gz: 6b6b44262ac3afb47f64323dc4ab005d68b09df76a78cc86997582250b5c02d1f9a739627a0df8119f1131a45b14799665777bf00cb3c015d178f2edeb8ad118
7
+ data.tar.gz: 40b8a027c381ac44e9c10f3cf98c88be79c469103dc2f748dfd4c2bc593e286f22f6730c8da7e7b4583d2b5c8bc70a27452ccb2a53fb071e141d99d92f3cf4c6
data/lib/sssa.rb CHANGED
@@ -1,9 +1,13 @@
1
1
  require_relative './utils.rb'
2
2
 
3
3
  module SSSA
4
- @prime = 99995644905598542077721161034987774965417302630805822064337798850767846245779
5
- @util = SSSA::Utils.new
4
+ @prime = 115792089237316195423570985008687907853269984665640564039457584007913129639747
5
+ @util = SSSA::Utils.new(@prime)
6
6
 
7
+ # Create a new array of Shamir's Shares with a minimum, total, and secret
8
+ # Note: output is an array of base64 strings, of length a multiple of 88,
9
+ # as each x, y point is a 256 bit (i.e., 44 base64 character) integer and
10
+ # each share is one pair, per number of integers secret must be split into
7
11
  def self.create(minimum, shares, raw)
8
12
  secret = @util.split_ints(raw)
9
13
  numbers = [0]
@@ -39,6 +43,9 @@ module SSSA
39
43
  return result
40
44
  end
41
45
 
46
+ # Takes a set of shares and combines them to a secret value using Shamir's
47
+ # Secret Sharing Algorithm. Each share must be a string of base-64 encoded
48
+ # shares of length modulo 88 base64 characters (512 bits in binary)
42
49
  def self.combine(shares)
43
50
  secrets = []
44
51
 
data/lib/utils.rb CHANGED
@@ -5,46 +5,47 @@ module SSSA
5
5
  class Utils
6
6
  attr_accessor :prime
7
7
 
8
- def initialize()
9
- # 256-bit prime
10
- @prime = 99995644905598542077721161034987774965417302630805822064337798850767846245779
8
+ def initialize(prime=115792089237316195423570985008687907853269984665640564039457584007913129639747)
9
+ @prime = prime
11
10
  end
12
11
 
12
+ # Returns a random number on 0 to @prime-1, inclusive.
13
13
  def random()
14
14
  return SecureRandom.random_number(@prime)
15
15
  end
16
16
 
17
+ # split_ints and merge_ints converts between string and integer array,
18
+ # where the integer is right-padded until it fits a 256 bit integer.
17
19
  def split_ints(secret)
18
20
  result = []
19
21
 
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
22
+ secret.split('').map { |x|
23
+ data = x.unpack("H*")[0]
24
+ "0"*(data.size % 2) + data
25
+ }.join("").scan(/.{1,64}/) { |segment|
26
+ result.push (segment+"0"*(64-segment.size)).hex
27
+ }
30
28
 
31
29
  return result
32
30
  end
33
31
 
34
32
  def merge_ints(secrets)
35
- result = ""
33
+ result = []
36
34
 
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
35
+ secrets.each { |int|
36
+ data = int.to_s(16)
37
+ ("0"*(64-data.size) + data).scan(/../) { |segment|
38
+ result.push segment.hex
39
+ }
40
+ }
44
41
 
45
- return result
42
+ return result.pack('C*').force_encoding("utf-8").gsub(/\u0000*$/, '')
46
43
  end
47
44
 
45
+ # This evaluates a polynomial with reversed coefficients at a given
46
+ # value. Namely, given the array [a, b, c, d], and x=value, the equation
47
+ # is:
48
+ # a + bx + cx^2 + dx^3
48
49
  def evaluate_polynomial(coefficients, value)
49
50
  result = 0
50
51
  coefficients.each_with_index do |coefficient, exponent|
@@ -59,6 +60,11 @@ module SSSA
59
60
  return result
60
61
  end
61
62
 
63
+ # The to_base64 and from_base64 converts between base 10 and base 64
64
+ # integers, with a left-zero-padded, fixed-size hex representation.
65
+ # This is cross-compatible with the go implementation, and by changing
66
+ # base versus encoding as a string, it reduces the size of the
67
+ # representation. Note: the output is always 44 characters.
62
68
  def to_base64(number)
63
69
  return Base64.urlsafe_encode64(("0"*(64-number.to_s(16).size) + number.to_s(16)).scan(/../).map{|x| x.hex.chr}.join)
64
70
  end
@@ -74,6 +80,11 @@ module SSSA
74
80
  return (segment+["00"]*(32-segment.size)).join.hex
75
81
  end
76
82
 
83
+ # Uses extended Euclidian algorithm to compute the GCD of a pair of
84
+ # numbers, and returns [gcd, x, y], such that gcd = ax+ by.
85
+ #
86
+ # Note: computing the GCD over a finite field with a = @prime means that
87
+ # GCD will always return 1.
77
88
  def gcd(a, b)
78
89
  if b == 0
79
90
  return [a, 1, 0]
@@ -85,6 +96,9 @@ module SSSA
85
96
  end
86
97
  end
87
98
 
99
+ # Computes the multiplicitive inverse of the given number on the finite
100
+ # field. Note: number should never be less than zero; however, if it is,
101
+ # the inverse is inverted
88
102
  def mod_inverse(number)
89
103
  remainder = gcd(@prime, number % @prime)[2]
90
104
  if (number < 0)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sssa-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Scheel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-18 00:00:00.000000000 Z
11
+ date: 2015-11-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Helper cryptography module for Ruby
14
14
  email: alexander.m.scheel@gmail.com
@@ -28,17 +28,17 @@ require_paths:
28
28
  - lib
29
29
  required_ruby_version: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  required_rubygems_version: !ruby/object:Gem::Requirement
35
35
  requirements:
36
- - - '>='
36
+ - - ">="
37
37
  - !ruby/object:Gem::Version
38
38
  version: '0'
39
39
  requirements: []
40
40
  rubyforge_project:
41
- rubygems_version: 2.0.14
41
+ rubygems_version: 2.4.5
42
42
  signing_key:
43
43
  specification_version: 4
44
44
  summary: Shamir's Secret Sharing Algorithm