Fix EC-SRP5 server: use stored gamma parity, not hardcoded true
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:
Siavash Sameni
2026-03-31 17:22:06 +04:00
parent a87dd7510f
commit 6c82228dd1

View File

@@ -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);