using the SRP 6a algorithm for calculating M
authorAzul <azul@riseup.net>
Thu, 4 Oct 2012 11:08:21 +0000 (13:08 +0200)
committerAzul <azul@riseup.net>
Thu, 4 Oct 2012 11:08:21 +0000 (13:08 +0200)
lib/srp/session.rb
lib/srp/util.rb
test/util_test.rb

index 367f5e2..a1153e0 100644 (file)
@@ -65,8 +65,10 @@ module SRP
 
     # this is outdated - SRP 6a uses
     # M = H(H(N) xor H(g), H(I), s, A, B, K)
-    def calculate_m(s)
-      sha256_int(@aa, @bb, s).hex
+    def calculate_m(secret)
+      n_xor_g_hash = sha256_str(hn_xor_hg).hex
+      username_hash = sha256_str(@user.username).hex
+      sha256_int(n_xor_g_hash, username_hash, @user.salt, @aa, @bb, secret).hex
     end
 
     def calculate_m2(m, secret)
index 50ff9bb..1e4beac 100644 (file)
@@ -19,6 +19,10 @@ d15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e5
     EOS
     GENERATOR = 2 # g
 
+    def hn_xor_hg
+      byte_xor_hex(sha256_int(BIG_PRIME_N), sha256_int(GENERATOR))
+    end
+
     # a^n (mod m)
     def modpow(a, n, m = BIG_PRIME_N)
       r = 1
@@ -32,7 +36,7 @@ d15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e5
 
     #  Hashes the (long) int args
     def sha256_int(*args)
-      sha256_hex(*args.map{|a| a.to_s(16)})
+      sha256_hex(*args.map{|a| "%02x" % a})
     end
 
     #  Hashes the hex args
@@ -56,9 +60,18 @@ d15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e5
     protected
 
     def calculate_multiplier
-      # GENERATOR hex needs to be prefixed with 0 so it's not "2" -> 32
-      ghex = '0%x' % GENERATOR
-      sha256_hex(BIG_PRIME_N.to_s(16), ghex).hex
+      sha256_int(BIG_PRIME_N, GENERATOR).hex
+    end
+
+    # turn two hex strings into byte arrays and xor them
+    #
+    # returns byte array
+    def byte_xor_hex(a, b)
+      a = [a].pack('H*')
+      b = [b].pack('H*')
+      a.bytes.each_with_index.map do |a_byte, i|
+        (a_byte ^ (b[i] || 0)).chr
+      end.join
     end
 
   end
index 9b1d09b..4dd6d86 100644 (file)
@@ -30,4 +30,10 @@ class UtilTest < Test::Unit::TestCase
       "%x" % multiplier
   end
 
+  def test_hn_xor_hg
+    # >>> binascii.hexlify (pysrp.HNxorg(hashlib.sha256, N, g))
+    assert_equal '928ade491bc87bba9eb578701d44d30ed9080e60e542ba0d3b9c20ded9f592bf',
+      hn_xor_hg.bytes.map{|b| "%02x" % b.ord}.join
+  end
+
 end