adopted srp algo to srp-js way of doing things.
[ruby_srp.git] / lib / srp / util.rb
1 require 'digest'
2 require 'openssl'
3
4 module SRP
5   module Util
6
7     # constants both sides know
8     # in this case taken from srp-js
9     PRIME_N = <<-EOS.split.join.hex
10 115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3
11     EOS
12
13     BIG_PRIME_N = <<-EOS # 1024 bits modulus (N)
14 eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c25657
15 6d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089da
16 d15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e5
17 7ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb
18 06e3
19     EOS
20     GENERATOR = 2 # g
21
22     # a^n (mod m)
23     def modpow(a, n, m)
24       r = 1
25       while true
26         r = r * a % m if n[0] == 1
27         n >>= 1
28         return r if n == 0
29         a = a * a % m
30       end
31     end
32
33     def sha256_hex(h)
34       Digest::SHA2.hexdigest([h].pack('H*'))
35     end
36
37     def sha256_str(s)
38       Digest::SHA2.hexdigest(s)
39     end
40
41     def bigrand(bytes)
42       OpenSSL::Random.random_bytes(bytes).unpack("H*")[0]
43     end
44
45     def multiplier
46       return "c46d46600d87fef149bd79b81119842f3c20241fda67d06ef412d8f6d9479c58".hex % PRIME_N
47       @k ||= calculate_multiplier
48     end
49
50     protected
51
52     def calculate_multiplier
53       n = PRIME_N
54       g = GENERATOR
55       nhex = '%x' % [n]
56       nlen = nhex.length + (nhex.length.odd? ? 1 : 0 )
57       ghex = '%x' % [g]
58       hashin = '0' * (nlen - nhex.length) + nhex \
59         + '0' * (nlen - ghex.length) + ghex
60       sha256_hex(hashin).hex % n
61     end
62
63     def calculate_m(aa, bb, s)
64       # todo: we might want to 0fill this like for u
65       hashin = '%x%x%x' % [aa, bb, s]
66       sha256_str(hashin).hex
67     end
68
69   end
70
71 end
72