Code:
function calculateSRP6Verifier($username, $password, $salt)
{
// algorithm constants
$g = gmp_init(7);
$N = gmp_init('894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7', 16);
// calculate first hash
$h1 = sha1(strtoupper($username . ':' . $password), TRUE);
// calculate second hash
$h2 = sha1($salt.$h1, TRUE);
// convert to integer (little-endian)
$h2 = gmp_import($h2, 1, GMP_LSW_FIRST);
// g^h2 mod N
$verifier = gmp_powm($g, $h2, $N);
// convert back to a byte array (little-endian)
$verifier = gmp_export($verifier, 1, GMP_LSW_FIRST);
// pad to 32 bytes, remember that zeros go on the end in little-endian!
$verifier = str_pad($verifier, 32, chr(0), STR_PAD_RIGHT);
// done!
return $verifier;
}
// Returns SRP6 parameters to register this username/password combination with
function getRegistrationData($username, $password)
{
// generate a random salt
$salt = random_bytes(32);
// calculate verifier using this salt
$verifier = $this->calculateSRP6Verifier($username, $password, $salt);
// done - this is what you put in the account table!
return array($salt, $verifier);
}
function verifySRP6($user, $pass, $salt, $verifier)
{
$g = gmp_init(7);
$N = gmp_init('894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7', 16);
$x = gmp_import(
sha1($salt . sha1(strtoupper($user . ':' . $pass), TRUE), TRUE),
1,
GMP_LSW_FIRST
);
$v = gmp_powm($g, $x, $N);
return ($verifier === str_pad(gmp_export($v, 1, GMP_LSW_FIRST), 32, chr(0), STR_PAD_RIGHT));
}
to get the salt and verifier you just have to use
Code:
list($salt, $verifier) = getRegistrationData($username, $password);
I'm not 100% sure if list works on php5.6 but the following will work as well
Code:
$data = = getRegistrationData($username, $password);
$salt = $data[0];
$verifier = $data[1];
and for log in you'll need the following function
Code:
function verifySRP6($user, $pass, $salt, $verifier)
{
$g = gmp_init(7);
$N = gmp_init('894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7', 16);
$x = gmp_import(
sha1($salt . sha1(strtoupper($user . ':' . $pass), TRUE), TRUE),
1,
GMP_LSW_FIRST
);
$v = gmp_powm($g, $x, $N);
return ($verifier === str_pad(gmp_export($v, 1, GMP_LSW_FIRST), 32, chr(0), STR_PAD_RIGHT));
}