Skip to content

Commit

Permalink
elliptic-curve: make ScalarBytes<C> the SecretKey<C> internal repr
Browse files Browse the repository at this point in the history
Previously SecretKey<C> had a generic internal value, depending on
whether or not the `arithmetic` feature was activated. This was mostly
trying to work around the fact that there wasn't a baseline arithmetic
impl available to validate secret keys.

Now there is! SecretBytes<C> uses C::UInt and its may features as a
`crypto-bigint` to always validate the internal bytes.

This means we can simply use `SecretBytes<C>` as the inner value of a
`SecretKey<C>`, and still provide infallible conversions to
`NonZeroScalar<C>`.
  • Loading branch information
tarcieri committed Jun 3, 2021
1 parent cc442ac commit 97269d5
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 139 deletions.
14 changes: 4 additions & 10 deletions elliptic-curve/src/jwk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
sec1::{
Coordinates, EncodedPoint, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey,
},
secret_key::{SecretKey, SecretValue},
secret_key::SecretKey,
weierstrass::Curve,
Error, FieldBytes,
};
Expand Down Expand Up @@ -135,9 +135,7 @@ impl JwkEcKey {
#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
pub fn to_secret_key<C>(&self) -> Result<SecretKey<C>, Error>
where
C: Curve + JwkParameters + ValidatePublicKey + SecretValue,
C::Secret: Clone + Zeroize,
FieldBytes<C>: From<C::Secret>,
C: Curve + JwkParameters + ValidatePublicKey,
UntaggedPointSize<C>: Add<U1> + ArrayLength<u8>,
UncompressedPointSize<C>: ArrayLength<u8>,
{
Expand Down Expand Up @@ -232,9 +230,7 @@ where
#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
impl<C> TryFrom<JwkEcKey> for SecretKey<C>
where
C: Curve + JwkParameters + ValidatePublicKey + SecretValue,
C::Secret: Clone + Zeroize,
FieldBytes<C>: From<C::Secret>,
C: Curve + JwkParameters + ValidatePublicKey,
UntaggedPointSize<C>: Add<U1> + ArrayLength<u8>,
UncompressedPointSize<C>: ArrayLength<u8>,
{
Expand All @@ -248,9 +244,7 @@ where
#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
impl<C> TryFrom<&JwkEcKey> for SecretKey<C>
where
C: Curve + JwkParameters + ValidatePublicKey + SecretValue,
C::Secret: Clone + Zeroize,
FieldBytes<C>: From<C::Secret>,
C: Curve + JwkParameters + ValidatePublicKey,
UntaggedPointSize<C>: Add<U1> + ArrayLength<u8>,
UncompressedPointSize<C>: ArrayLength<u8>,
{
Expand Down
3 changes: 0 additions & 3 deletions elliptic-curve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,6 @@ pub use {
#[cfg(feature = "bits")]
pub use crate::scalar::ScalarBits;

#[cfg(all(feature = "hazmat", feature = "zeroize"))]
pub use secret_key::{SecretBytes, SecretValue};

#[cfg(feature = "jwk")]
pub use crate::jwk::{JwkEcKey, JwkParameters};

Expand Down
41 changes: 40 additions & 1 deletion elliptic-curve/src/scalar/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ use generic_array::GenericArray;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeLess, CtOption};

#[cfg(feature = "arithmetic")]
use crate::{group::ff::PrimeField, ProjectiveArithmetic, Scalar};
use crate::{group::ff::PrimeField, NonZeroScalar, ProjectiveArithmetic, Scalar};

#[cfg(feature = "zeroize")]
use zeroize::Zeroize;

/// Scalar bytes: wrapper for [`FieldBytes`] which guarantees that the the
/// inner byte value is within range of the [`Curve::ORDER`].
Expand Down Expand Up @@ -161,6 +164,32 @@ where
}
}

#[cfg(feature = "arithmetic")]
impl<C> From<NonZeroScalar<C>> for ScalarBytes<C>
where
C: Curve + ProjectiveArithmetic,
Scalar<C>: PrimeField<Repr = FieldBytes<C>>,
{
fn from(scalar: NonZeroScalar<C>) -> ScalarBytes<C> {
ScalarBytes {
inner: scalar.into(),
}
}
}

#[cfg(feature = "arithmetic")]
impl<C> TryFrom<ScalarBytes<C>> for NonZeroScalar<C>
where
C: Curve + ProjectiveArithmetic,
Scalar<C>: PrimeField<Repr = FieldBytes<C>>,
{
type Error = Error;

fn try_from(bytes: ScalarBytes<C>) -> Result<NonZeroScalar<C>> {
NonZeroScalar::<C>::from_repr(bytes.inner).ok_or(Error)
}
}

impl<C> PartialEq for ScalarBytes<C>
where
C: Curve,
Expand All @@ -185,6 +214,16 @@ where
}
}

#[cfg(feature = "zeroize")]
impl<C> Zeroize for ScalarBytes<C>
where
C: Curve,
{
fn zeroize(&mut self) {
self.inner.zeroize();
}
}

#[cfg(all(test, feature = "dev"))]
mod tests {
use crate::dev::MockCurve;
Expand Down
16 changes: 15 additions & 1 deletion elliptic-curve/src/scalar/non_zero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use generic_array::GenericArray;
use subtle::{Choice, ConditionallySelectable, CtOption};

#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
use {crate::SecretKey, zeroize::Zeroize};

/// Non-zero scalar type.
///
Expand Down Expand Up @@ -114,6 +114,20 @@ where
}
}

#[cfg(feature = "zeroize")]
#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
impl<C> From<&SecretKey<C>> for NonZeroScalar<C>
where
C: Curve + ProjectiveArithmetic,
Scalar<C>: PrimeField<Repr = FieldBytes<C>>,
{
fn from(sk: &SecretKey<C>) -> NonZeroScalar<C> {
let scalar = sk.as_scalar_bytes().to_scalar();
debug_assert!(!scalar.is_zero());
Self { scalar }
}
}

impl<C> Invert for NonZeroScalar<C>
where
C: Curve + ProjectiveArithmetic,
Expand Down
9 changes: 3 additions & 6 deletions elliptic-curve/src/sec1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ use crate::{
};

#[cfg(feature = "zeroize")]
use crate::{
secret_key::{SecretKey, SecretValue},
zeroize::Zeroize,
};
use crate::{secret_key::SecretKey, zeroize::Zeroize};

/// Size of a compressed point for the given elliptic curve when encoded
/// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm
Expand Down Expand Up @@ -134,7 +131,7 @@ where
AffinePoint<C>: ToEncodedPoint<C>,
Scalar<C>: PrimeField<Repr = FieldBytes<C>> + Zeroize,
{
(C::ProjectivePoint::generator() * secret_key.secret_scalar().as_ref())
(C::ProjectivePoint::generator() * secret_key.to_secret_scalar().as_ref())
.to_affine()
.to_encoded_point(compress)
}
Expand Down Expand Up @@ -496,7 +493,7 @@ where
#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
pub trait ValidatePublicKey
where
Self: Curve + SecretValue,
Self: Curve,
UntaggedPointSize<Self>: Add<U1> + ArrayLength<u8>,
UncompressedPointSize<Self>: ArrayLength<u8>,
{
Expand Down
Loading

0 comments on commit 97269d5

Please sign in to comment.