RustCrypto / traits

Collection of cryptography-related traits
553 stars 173 forks source link

`elliptic_curve::NonZeroScalar` non-zeroness guarantee #1607

Open kwantam opened 3 weeks ago

kwantam commented 3 weeks ago

Thanks a lot for the great libraries! Apologies if this has already been asked---I looked briefly and didn't see anything.

It looks like in release builds it's quite easy to construct a NonZeroScalar that equals zero (debug builds will panic).

let sk = SecretKey::new(ScalarPrimitive::ZERO);
let nzs = sk.to_nonzero_scalar();

I could easily be missing something, and of course it's easy enough to avoid with a careful check. But I think probably SecretKey::new wants to be fallible since ScalarPrimitive can be zero, while SecretKey and NonZeroScalar presumably want to be nonzero.

tarcieri commented 3 weeks ago

Indeed you have found a way around the NonZeroScalar invariant!

Either SecretKey::new needs to be changed to be fallible and reject an all-zero scalar, or to_nonzero_scalar needs to be changed to be fallible.

There are various opinions as to what should be allowable as secret keys. However I'd note that elliptic_curve::PublicKey already maintains an invariant that the inner curve point is a non-identity point, so a fallible constructor for SecretKey would make sense for symmetry.