Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dsa: Eq is missing for Components, SigningKey and VerifyingKey #881

Open
dignifiedquire opened this issue Jan 6, 2025 · 9 comments
Open

Comments

@dignifiedquire
Copy link
Member

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

@tarcieri
Copy link
Member

tarcieri commented Jan 6, 2025

Derived Eq on SigningKey would introduce a timing sidechannel

@dignifiedquire
Copy link
Member Author

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

@tarcieri
Copy link
Member

tarcieri commented Jan 9, 2025

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

@json420
Copy link
Contributor

json420 commented Mar 7, 2025

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>,
}

@tarcieri
Copy link
Member

tarcieri commented Mar 7, 2025

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

@json420
Copy link
Contributor

json420 commented Mar 7, 2025

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.

@tarcieri
Copy link
Member

tarcieri commented Mar 7, 2025

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

@aumetra
Copy link
Contributor

aumetra commented Mar 7, 2025

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?

@tarcieri
Copy link
Member

tarcieri commented Mar 7, 2025

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants