summaryrefslogtreecommitdiffstats
path: root/lib/srp.go
diff options
context:
space:
mode:
Diffstat (limited to 'lib/srp.go')
-rw-r--r--lib/srp.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/lib/srp.go b/lib/srp.go
index 2303793..a7f14e1 100644
--- a/lib/srp.go
+++ b/lib/srp.go
@@ -199,6 +199,30 @@ func (u *SRPUser) SetScramblingParam(a *big.Int) error {
return nil
}
+func (u *SRPUser) ComputeSessionKey(a *big.Int) error {
+ if a.Cmp(big.NewInt(0)) != 1 {
+ return CPError{"a is invalid"}
+ }
+
+ // v^u
+ vu := new(big.Int)
+ vu.Exp(u.v, u.u, u.n)
+
+ // S = (A * v^u) ^ b
+ s := new(big.Int)
+ s.Mul(a, vu)
+ s.Exp(s, u.b, u.n)
+ sb := s.Bytes()
+
+ // K = H(S)
+ m := make([]byte, 0)
+ m = append(m, sb...)
+ u.h.Message(m)
+ u.sk = u.h.Hash()
+
+ return nil
+}
+
func NewSRPClientSession(n, g, k, ident string) (*SRPClientSession, error) {
var ok bool
@@ -270,3 +294,56 @@ func (s *SRPClientSession) SetScramblingParam(b *big.Int) error {
}
return nil
}
+
+func (s *SRPClientSession) ComputeSessionKey(salt []byte,
+ pass string, b *big.Int) error {
+ if len(salt) < 1 {
+ return CPError{"salt invalid"}
+ }
+ if len(pass) < 1 {
+ return CPError{"pass invalid"}
+ }
+
+ // salt+pass
+ sp := make([]byte, 0)
+ copy(sp, salt)
+ sp = append(sp, StrToBytes(pass)...)
+
+ // x = H(salt+pass)
+ x := new(big.Int)
+ s.h.Message(sp)
+ x.SetBytes(s.h.Hash())
+
+ // g^x
+ gx := new(big.Int)
+ gx.Exp(s.g, x, s.n)
+
+ // k * g^x
+ kgx := new(big.Int)
+ kgx.Mul(s.k, gx)
+
+ // B - (k * g^x)
+ bkgx := new(big.Int)
+ bkgx.Sub(b, kgx)
+
+ // u * x
+ ux := new(big.Int)
+ ux.Mul(s.u, x)
+
+ // a + u*x
+ aux := new(big.Int)
+ aux.Add(s.a, ux)
+
+ // S = (B - (k * g^x)) ^ (a + u*x)
+ sec := new(big.Int)
+ sec.Exp(bkgx, aux, s.n)
+ sb := sec.Bytes()
+
+ // K = H(S)
+ m := make([]byte, 0)
+ m = append(m, sb...)
+ s.h.Message(m)
+ s.sk = s.h.Hash()
+
+ return nil
+}