Fix EC-SRP5 server: use stored gamma parity, not hardcoded true
All checks were successful
CI / test (push) Successful in 1m21s
All checks were successful
CI / test (push) Successful in 1m21s
The gamma point's y-parity depends on the random salt. Using hardcoded parity=true caused ~50% of auth attempts to fail (whenever the actual parity was 0). Now stored from key derivation and used correctly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -469,6 +469,7 @@ pub async fn client_authenticate<S: AsyncReadExt + AsyncWriteExt + Unpin>(
|
|||||||
pub struct EcSrp5Credentials {
|
pub struct EcSrp5Credentials {
|
||||||
salt: [u8; 16],
|
salt: [u8; 16],
|
||||||
x_gamma: [u8; 32],
|
x_gamma: [u8; 32],
|
||||||
|
gamma_parity: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EcSrp5Credentials {
|
impl EcSrp5Credentials {
|
||||||
@@ -477,10 +478,11 @@ impl EcSrp5Credentials {
|
|||||||
let salt: [u8; 16] = rand::random();
|
let salt: [u8; 16] = rand::random();
|
||||||
let w = WCurve::new();
|
let w = WCurve::new();
|
||||||
let i = w.gen_password_validator_priv(username, password, &salt);
|
let i = w.gen_password_validator_priv(username, password, &salt);
|
||||||
let (x_gamma, _parity) = w.gen_public_key(&i);
|
let (x_gamma, parity) = w.gen_public_key(&i);
|
||||||
Self {
|
Self {
|
||||||
salt,
|
salt,
|
||||||
x_gamma,
|
x_gamma,
|
||||||
|
gamma_parity: parity != 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -555,7 +557,7 @@ pub async fn server_authenticate<S: AsyncReadExt + AsyncWriteExt + Unpin>(
|
|||||||
// gamma = lift_x(x_gamma, parity=1) — the raw validator public key point
|
// gamma = lift_x(x_gamma, parity=1) — the raw validator public key point
|
||||||
// (NOT redp1 — that's used for blinding W_b, not for verification)
|
// (NOT redp1 — that's used for blinding W_b, not for verification)
|
||||||
let w_a = w.lift_x(&BigUint::from_bytes_be(&x_w_a), x_w_a_parity);
|
let w_a = w.lift_x(&BigUint::from_bytes_be(&x_w_a), x_w_a_parity);
|
||||||
let gamma = w.lift_x(&BigUint::from_bytes_be(&creds.x_gamma), true);
|
let gamma = w.lift_x(&BigUint::from_bytes_be(&creds.x_gamma), creds.gamma_parity);
|
||||||
let j_gamma = gamma.scalar_mul(&j_int);
|
let j_gamma = gamma.scalar_mul(&j_int);
|
||||||
let sum = w_a.add(&j_gamma);
|
let sum = w_a.add(&j_gamma);
|
||||||
let z_point = sum.scalar_mul(&s_b_int);
|
let z_point = sum.scalar_mul(&s_b_int);
|
||||||
|
|||||||
Reference in New Issue
Block a user