signatures icon indicating copy to clipboard operation
signatures copied to clipboard

dsa: Eq is missing for Components, SigningKey and VerifyingKey

Open dignifiedquire opened this issue 1 year ago • 9 comments

I don't see any internal details that would make an impl/derive invalid

dignifiedquire avatar Jan 06 '25 14:01 dignifiedquire

Derived Eq on SigningKey would introduce a timing sidechannel

tarcieri avatar Jan 06 '25 14:01 tarcieri

how so, if there is already PartialEq, to which it could delegate?

dignifiedquire avatar Jan 07 '25 12:01 dignifiedquire

It doesn't currently impl PartialEq, but regardless, the derived implementation will use a data-dependent short-circuiting check, rather than one that always performs the comparison in constant-time

tarcieri avatar Jan 09 '25 16:01 tarcieri

I'm probably missing something obvious, but doesn't SigningKey currently do short-circuit comparison because it derives PartialEq? As far as I can tell BigUint doesn't do constant time comparison.

/// DSA private key.
///
/// The [`(try_)sign_digest_with_rng`](::signature::RandomizedDigestSigner) API uses regular non-deterministic signatures,
/// while the [`(try_)sign_digest`](::signature::DigestSigner) API uses deterministic signatures as described in RFC 6979
#[derive(Clone, PartialEq)]
#[must_use]
pub struct SigningKey {
    /// Public key
    verifying_key: VerifyingKey,

    /// Private component x
    x: Zeroizing<BigUint>,
}

json420 avatar Mar 07 '25 14:03 json420

Oh, I guess it does derive PartialEq (not sure how I missed that before). I guess that will be less of an issue when #906 lands and it switches to crypto-bigint

tarcieri avatar Mar 07 '25 14:03 tarcieri

Yeah, crypto-bigint will nearly solve it, but correct me if I'm wrong, comparing Component would still short-circuit after the first non-matching struct member, right?

/// The common components of an DSA keypair
///
/// (the prime p, quotient q and generator g)
#[derive(Clone, Debug, PartialEq, PartialOrd)]
#[must_use]
pub struct Components {
    /// Prime p
    p: BigUint,

    /// Quotient q
    q: BigUint,

    /// Generator g
    g: BigUint,
}

I don't know enough about DSA to know how much of a problem that is security wise... but it does sound like a fun thing for me to try to fix after #906 lands.

json420 avatar Mar 07 '25 14:03 json420

Only x is secret, the other components are part of the public key

tarcieri avatar Mar 07 '25 14:03 tarcieri

Short circuiting doesn't matter as long as it isn't on the limbs of the private factor in the signing key, since the components are public knowledge anyway. So after the crypto-bigint migration it should be fine IMO?

aumetra avatar Mar 07 '25 14:03 aumetra

Yep, crypto_bigint::Uint compares in constant-time internally, even when using the PartialEq API

tarcieri avatar Mar 07 '25 14:03 tarcieri