Class: CcipherFactory::ShamirSharing

Inherits:
Object
  • Object
show all
Defined in:
lib/ccipher_factory/shamir/shamir_sharing.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(threshold, secretdata = nil) ⇒ ShamirSharing

Returns a new instance of ShamirSharing.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/ccipher_factory/shamir/shamir_sharing.rb', line 15

def initialize(threshold, secretdata=nil)
  @threshold = threshold
  @secretdata = secretdata
  @_coefficients = []

  if secretdata
    secretdata.each_char do |secretbyte|
      rand = Ccrypto::AlgoFactory.engine(Ccrypto::SecureRandomConfig)
      randVal = rand.random_bytes(@threshold-1)
      thesecoefficients = secretbyte+randVal
      #thesecoefficients = secretbyte+OpenSSL::Random.random_bytes(@threshold-1)
      @_coefficients << thesecoefficients
    end
  end
end

Instance Attribute Details

#_coefficientsObject (readonly)

Returns the value of attribute _coefficients.



12
13
14
# File 'lib/ccipher_factory/shamir/shamir_sharing.rb', line 12

def _coefficients
  @_coefficients
end

#secretdataObject (readonly)

Returns the value of attribute secretdata.



13
14
15
# File 'lib/ccipher_factory/shamir/shamir_sharing.rb', line 13

def secretdata
  @secretdata
end

Instance Method Details

#compute_share(x) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/ccipher_factory/shamir/shamir_sharing.rb', line 44

def compute_share(x)
  raise "x should be integer" unless x.class == Fixnum
  raise "x must be between 1 and 255" if x <= 0 || x  >256
  raise "@_coefficient must be initialized" if @_coefficients.empty?

  sharebytes = []

  @_coefficients.each do |thiscoefficient|
    thisshare = _f(x,thiscoefficient)
    sharebytes << thisshare
  end

  return x, sharebytes
end

#is_valid_share?(share) ⇒ Boolean

Returns:

  • (Boolean)


31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/ccipher_factory/shamir/shamir_sharing.rb', line 31

def is_valid_share?(share)
  raise "Share is of incorrect length: #{share.size}" if share.size !=2
  raise "Must initialize coefficient before checking is_valid_share?" unless @_coefficients
  raise "Must initialize coefficient before checking is_valid_share?" if @_coefficients.size != share[1].size

  x  = share[0]
  fx = share[1]

  correctshare = compute_share(x)

  correctshare == share
end

#recover_secretdata(shares) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/ccipher_factory/shamir/shamir_sharing.rb', line 59

def recover_secretdata(shares)
  newshares = []

  shares.each do |share|
    newshares << share unless newshares.include?(share)
  end

  shares = newshares

  if @threshold > shares.size
    raise "Threshold: #{@threshold} is smaller than the number of uniquie shares: #{shares.size}"
  end

  if @secretdata
    raise "Recovoring secretdata when some is stored. Use check_share instead"
  end

  xs = []

  shares.each do |share|
    if xs.include?(share[0])
      raise "Different shares with the same first byte: #{share[0]}"
    end

    if share[1].size != shares[0][1].size
      raise "Shares have different lengths!"
    end

    xs << share[0]
  end

  mycoefficients = []
  mysecretdata = ''

  shares[0][1].size.times.each do |byte_to_use|
    fxs = []
    shares.each do |share|
      fxs << share[1][byte_to_use]
    end

    resulting_poly = _full_lagrange(xs,fxs)

    if resulting_poly[0..@threshold-1] + [0]*(shares.size - @threshold) != resulting_poly
      raise "Share do not match. Cannot decode"
    end

    mycoefficients << resulting_poly.map{|p| p.chr}.join

    mysecretdata += resulting_poly[0].chr
  end

  @_coefficients = mycoefficients
  @secretdata = mysecretdata
end