**Situation — why CRT leaks p or q**CRT speeds RSA signing by computing s_p = m^(d_p) mod p and s_q = m^(d_q) mod q then recombining. If an attacker measures timing (or injects faults) that depend on operations modulo p or q (e.g., variable-time Montgomery reductions, branch-dependent multiprecision loops, or a single-fault that corrupts s_p), they can recover p or q by:- Timing: correlate operation timing with bit-length or conditional reductions to infer bits of p or q.- Fault: a single wrong CRT share yields s'; gcd(s - s', N) often reveals p or q.**Why it happens (concise)**- CRT decomposes into smaller moduli; operations leak more information per operation.- Recombination without verification exposes corrupted shares.Mitigations (practical, prioritized)1. RSA blinding before exponentiation (randomize message/signature call)2. Constant-time modular exponentiation and arithmetic (avoid data-dependent branches/lengths)3. Verify CRT result; on failure recompute without CRT or abort4. Fault-detection: redundant computation or exponent blindingPseudocode-level changes1) Blinding (per-sign)python
# Inputs: m, private key (p,q,d_p,d_q,qinv)
r = random(1..N-1)
r_e = r^e mod N # e is public exponent
m_blinded = (m * r_e) mod N
# compute signature on m_blinded using CRT (or full exp)
s_blinded = rsa_crt_sign(m_blinded)
# unblind
s = (s_blinded * inv_mod(r, N)) mod N
2) Constant-time CRT exponentiation (use fixed-window Montgomery, constant loops)python
# compute s_p = pow_ct(m, d_p, p) # constant-time modular exponent
# compute s_q = pow_ct(m, d_q, q)
# pow_ct implements fixed-window, avoids data-dependent branches/time
3) Recombination + verification (detect faults)python
# recombine
h = ((s_p - s_q) * qinv) mod p
s = s_q + q * h
# verify: check s^e mod N == m
if pow_ct(s, e, N) != m:
# optional: recompute full exp (no CRT) or abort and log
s_full = pow_ct(m, d, N) # single-modulus safe path
if pow_ct(s_full, e, N) != m:
raise SecurityError("Signing failed integrity check")
s = s_full
return s
Notes on implementation- Use side-channel resistant bignum libraries (constant-time limb ops, no secret-dependent memory access).- Blinding prevents timing leakage of exponentiation; verification prevents fault extraction.- Logging and rate-limiting on verification failures reduce fault attack utility.Complexity/practical trade-offs- Blinding and constant-time ops add ~2x slowdown; recompute-on-fail adds occasional cost but prevents key recovery.- For high-assurance systems prefer full-exponent constant-time signing or hardware roots with fault detection.This set of changes defends against both timing and single-fault CRT attacks while providing fallbacks for integrity failures.