Skip to content

Commit

Permalink
rembrand lmao
Browse files Browse the repository at this point in the history
  • Loading branch information
arag0re committed Jan 6, 2023
1 parent 3ba75fd commit d18dbb5
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 62 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2015 Sudhi Herle
Copyright (c) 2023 arag0re

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
13 changes: 7 additions & 6 deletions example/example.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package main

// Simple test program to test the SRP library
// Author: Sudhi Herle
// April 2014
//
// Copyright 2013-2023 arag0re <arag0re.eth-at-protonmail-dot-com>
// License: MIT
//

package main

import (
"crypto/subtle"
Expand All @@ -11,11 +13,10 @@ import (
)

func main() {
bits := 1024
pass := []byte("password string that's too long")
i := []byte("foouser")

s, err := srp.New(bits)
s, err := srp.New()
if err != nil {
panic(err)
}
Expand Down
2 changes: 1 addition & 1 deletion example/primefield.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// Usage: ./primefield bits [bits ..]
//
// Copyright 2013-2017 Sudhi Herle <sudhi.herle-at-gmail-dot-com>
// Copyright 2013-2023 arag0re <arag0re.eth-at-protonmail-dot-com>
// License: MIT
//

Expand Down
3 changes: 2 additions & 1 deletion prime.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// prime.go - Generate safe primes
//
// Copyright 2013-2023 Sudhi Herle <sudhi.herle-at-gmail-dot-com> && arag0re <arag0re-at-protonmail-dot-com>
// Copyright 2013-2023 arag0re <arag0re.eth-at-protonmail-dot-com>

// License: MIT
package srp

Expand Down
92 changes: 41 additions & 51 deletions srp.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// srp.go - golang implementation of SRP-6a
// srp.go - golang implementation of SRP-6a like apple wants it
//
// Copyright 2013-2023 Sudhi Herle <sudhi.herle-at-gmail-dot-com> && arag0re <arag0re.eth-at-protonmail-dot-com>
// Copyright 2013-2023 arag0re <arag0re.eth-at-protonmail-dot-com>
// License: MIT
//

Expand All @@ -15,26 +15,22 @@
// validate that the server also has the same value, it requires the server to send
// its own proof. In the SRP paper [1], the authors use:
//
// M = H(H(N) xor H(g), H(I), s, A, B, K)
// M' = H(A, M, K)
//
// We use a simpler construction:
//
// M = H(K, A, B, I, s, N, g)
// M' = H(M, K)
// M1 = H(H(N) xor H(g), H(I), s, A, B, K)
// M2 = H(A, M, K)
//
// In this implementation:
//
// H = BLAKE2()
// k = H(N, g)
// x = H(s, I, P)
// I = anonymized form of user identity (BLAKE2 of value sent by client)
// P = hashed password (expands short passwords)
// H = SHA1()
// k = H(N | g)
// t = H(I | ':' |P)
// x = H(s | t)
// I = clear text
// P = clear text
//
// Per RFC-5054, we adopt the following padding convention:
//
// k = H(N, pad(g))
// u = H(pad(A), pad(B))
// k = H(PAD(N) | PAD(g))
// u = H(PAD(A) | PAD(B))
//
// References:
//
Expand All @@ -49,25 +45,26 @@ package srp
// N A large safe prime (N = 2q+1, where q is prime)
// All arithmetic is done modulo N.
// g A generator modulo N
// k Multiplier parameter (k = H(N, g) in SRP-6a, k = 3 for legacy SRP-6)
// s User's salt
// I Username
// k Multiplier parameter (k = H(PAD(N) | PAD(g)) in SRP-6a, k = 3 for legacy SRP-6)
// s User's salt
// I Cleartext Username
// p Cleartext Password
// H() One-way hash function
// t auth pair (t = H(I | ':' | p))
// H() One-way hash function, in this case SHA1
// ^ (Modular) Exponentiation
// u Random scrambling parameter
// u Random scrambling parameter (u = H(PAD(A) | PAD(B)))
// a,b Secret ephemeral values
// A,B Public ephemeral values
// x Private key (derived from p and s)
// x Private key (x = H(s | t))
// v Password verifier
//
// The host stores passwords using the following formula:
//
// s = randomsalt() (same length as N)
// I = H(I)
// p = H(p) (hash/expand I & p)
// t = H(I, ":", p)
// x = H(s, t)
// t = H(I | ":" | p)
// x = H(s | t)
// v = g^x (computes password verifier)
//
// The host then keeps {I, s, v} in its password database.
Expand Down Expand Up @@ -111,8 +108,8 @@ package srp
// validate that the server also has the same value, it requires the server to send
// its own proof. We use a simpler construction:
//
// M = H(K, A, B, I, s, N, g)
// M' = H(M, K)
// M1 = H(H(N) xor H(g), H(I), s, A, B, K)
// M2 = H(A, M, K)
//
// Client & Server also employ the following safeguards:
//
Expand All @@ -132,14 +129,11 @@ import (
"math/big"
"strconv"
"strings"

// stdlib has an enum for Blake2b_256; this lib registers itself against it.
_ "golang.org/x/crypto/blake2b"
)

// SRP represents an environment for the client and server to share certain properties;
// notably the hash function and prime-field size. The default hash function is
// Blake2b-256. Any valid hash function as documented in "crypto" can be used.
// SHA1. Any valid hash function as documented in "crypto" can be used.
// There are two ways for creating an SRP environment:
//
// New()
Expand All @@ -154,10 +148,10 @@ func (s *SRP) FieldSize() int {
return s.pf.n * 8
}

// New creates a new SRP environment using a 'bits' sized prime-field for
// use by SRP clients and Servers.The default hash function is Blake-2b-256.
func New(bits int) (*SRP, error) {
return NewWithHash(crypto.BLAKE2b_256, bits)
// New creates a new SRP environment 2048 bits
// use by SRP clients and Servers.The default hash function is SHA1.
func New() (*SRP, error) {
return NewWithHash(crypto.SHA1, 2048)
}

// NewWithHash creates a new SRP environment using the hash function 'h' and
Expand Down Expand Up @@ -346,16 +340,12 @@ type Client struct {

// NewClient constructs an SRP client instance.
func (s *SRP) NewClient(I, p []byte) (*Client, error) {
//a, err := hex.DecodeString("a18b940d3e1302e932a64defccf560a0714b3fa2683bbe3cea808b3abfa58b7d")
//if err != nil {
// print(err)
//}
pf := s.pf
c := &Client{
s: s,
i: I,
p: p,
a: randBigInt(pf.n * 8), /*new(big.Int).SetBytes(a)*/
a: randBigInt(pf.n * 8),
k: s.hashint(pad(pf.N, pf.n), pad(pf.g, pf.n)),
}

Expand Down Expand Up @@ -405,17 +395,17 @@ func (c *Client) Generate(srv string) (string, error) {
if u.Cmp(zero) == 0 {
return "", fmt.Errorf("srp: invalid server public key")
}
auth := c.s.hashbyte(c.i, []byte{':'}, c.p) // H(I | ":" | p)
x := c.s.hashint(salt, auth) // H(s | H(I | ":" | p))
c.S = computeSessionKey(pf.N, pf.g, c.k, x, u, c.a, B) //
K1 := c.s.hashbyte(c.S.Bytes(), []byte{0, 0, 0, 0})
K2 := c.s.hashbyte(c.S.Bytes(), []byte{0, 0, 0, 1})
c.xK = append(K1, K2...) // K = H(S | \x00\x00\x00\x00) | H(S | \x00\x00\x00\x01)
hN := c.s.hashbyte(pf.N.Bytes())
hg := c.s.hashbyte(pf.g.Bytes())
hNhg := xor(hN, hg)
hu := c.s.hashbyte(c.i)
c.xM = c.s.hashbyte(hNhg, hu, salt, c.xA.Bytes(), B.Bytes(), c.xK)
t := c.s.hashbyte(c.i, []byte{':'}, c.p) // t = H(I | ":" | p)
x := c.s.hashint(salt, t) // x = H(s | t)
c.S = computeSessionKey(pf.N, pf.g, c.k, x, u, c.a, B) // S =
K1 := c.s.hashbyte(c.S.Bytes(), []byte{0, 0, 0, 0}) // creates first half of K (K1)
K2 := c.s.hashbyte(c.S.Bytes(), []byte{0, 0, 0, 1}) // creates second half of K (K2)
c.xK = append(K1, K2...) // K = H(S | \x00\x00\x00\x00) | H(S | \x00\x00\x00\x01)
hN := c.s.hashbyte(pf.N.Bytes()) // hN = H(N)
hg := c.s.hashbyte(pf.g.Bytes()) // hg = H(g)
hNhg := xor(hN, hg) // hNhg = hN ^ hg
hu := c.s.hashbyte(c.i) // hu = H(I)
c.xM = c.s.hashbyte(hNhg, hu, salt, c.xA.Bytes(), B.Bytes(), c.xK) // M1 = H(hNhg | hu | A | B | K)
//fmt.Println(len(c.xM))

return hex.EncodeToString(c.xM), nil
Expand All @@ -442,7 +432,7 @@ func computeSessionKey(N, g, k, x, u, a, B *big.Int) *big.Int {
// ServerOk takes a 'proof' offered by the server and verifies that it is valid.
// i.e., we should compute the same hash() on M that the server did.
func (c *Client) ServerOk(proof string) bool {
h := c.s.hashbyte(c.xA.Bytes(), c.xM, c.xK)
h := c.s.hashbyte(c.xA.Bytes(), c.xM, c.xK) // H(A | M1 | K)
myh := hex.EncodeToString(h)
return subtle.ConstantTimeCompare([]byte(myh), []byte(proof)) == 1
}
Expand Down
4 changes: 2 additions & 2 deletions srp_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// self test for srp
//
// Copyright 2013-2017 Sudhi Herle <sudhi.herle-at-gmail-dot-com>
// Copyright 2013-2023 arag0re <arag0re.eth-at-protonmail-dot-com>
// License: MIT
//

Expand Down Expand Up @@ -38,7 +38,7 @@ type userdb struct {

func newUserDB(user, pass []byte, p int) (*userdb, error) {

s, err := New(p)
s, err := New()
if err != nil {
return nil, err
}
Expand Down

0 comments on commit d18dbb5

Please sign in to comment.