raise argumenterror if k < 2
[secretsharing.git] / lib / secretsharing / shamir.rb
blob025b35c1a7546400a1885b8227995c4f26c3ab9d
1 require 'openssl'
3 module SecretSharing
4         class Shamir
5                 attr_reader :n, :k, :secret, :secret_bitlength, :shares
7                 DEFAULT_SECRET_BITLENGTH = 128
9                 def initialize(n, k=n)
10                         if k > n then
11                                 raise ArgumentError, 'k must be smaller or equal than n'
12                         end     
13                         if k < 2 then
14                                 raise ArgumentError, 'k must be greater or equal to two'
15                         end
16                         @n = n
17                         @k = k
18                         @secret = nil
19                         @shares = []
20                 end
22                 def secret_set?
23                         ! @secret.nil?
24                 end
26                 def create_random_secret(bitlength = DEFAULT_SECRET_BITLENGTH)
27                         raise RuntimeError, 'secret already set' if secret_set?
28                         @secret = get_random_number(bitlength)
29                         @secret_bitlength = bitlength
30                 end
32                 private
33                 def get_random_number(bitlength, highest_bit_one = true)
34                         byte_length = (bitlength / 8.0).ceil
35                         rand_hex = OpenSSL::Random.random_bytes(byte_length).each_byte.to_a.map { |a| "%02x" % a }.join('')
36                         rand = OpenSSL::BN.new(rand_hex, 16)
37                         begin
38                                 rand.mask_bits!(bitlength)
39                         rescue OpenSSL::BNError
40                                 # never mind if there was an error, this just means
41                                 # rand was already smaller than 2^bitlength - 1
42                         end
43                         if highest_bit_one then
44                                 rand.set_bit!(bitlength)
45                         end     
46                         rand
47                 end
48         end
49 end