diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index dbb6292e9..31ee72515 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -30,10 +30,7 @@ pub mod secret_key; #[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))] pub mod weierstrass; -pub use self::{ - error::Error, - secret_key::{FromSecretKey, SecretKey}, -}; +pub use self::{error::Error, secret_key::SecretKey}; pub use generic_array::{self, typenum::consts}; pub use subtle; @@ -42,6 +39,7 @@ pub use rand_core; use core::{fmt::Debug, ops::Add}; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +use subtle::ConditionallySelectable; #[cfg(feature = "rand_core")] use rand_core::{CryptoRng, RngCore}; @@ -65,10 +63,13 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { /// Elliptic curve with curve arithmetic support pub trait Arithmetic: Curve { /// Scalar type for a given curve - type Scalar: FromSecretKey; + type Scalar: ConditionallySelectable + + Default + + secret_key::FromSecretKey + + ops::MulBase; /// Affine point type for a given curve - type AffinePoint; + type AffinePoint: ConditionallySelectable; } /// Randomly generate a value. diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 09f811d7e..4d8f09523 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -10,3 +10,12 @@ pub trait Invert { /// Invert a field element. fn invert(&self) -> CtOption; } + +/// Fixed-base scalar multiplication +pub trait MulBase { + /// Affine point type + type Output; + + /// Multiply this value by the generator point for the elliptic curve + fn mul_base(&self) -> CtOption; +} diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index 424f28fbb..d98cc3791 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -8,16 +8,5 @@ pub use self::{ public_key::{FromPublicKey, PublicKey}, }; -use crate::{Arithmetic, ScalarBytes}; -use subtle::CtOption; - /// Marker trait for elliptic curves in short Weierstrass form pub trait Curve: super::Curve {} - -/// Fixed-base scalar multiplication -pub trait FixedBaseScalarMul: Curve + Arithmetic { - /// Multiply the given scalar by the generator point for this elliptic - /// curve. - // TODO(tarcieri): use `Self::Scalar` for the `scalar` param - fn mul_base(scalar: &ScalarBytes) -> CtOption; -} diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs index 3aaaa520d..b369e8f2d 100644 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -3,9 +3,9 @@ use super::{ point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, - Curve, FixedBaseScalarMul, + Curve, }; -use crate::{Error, SecretKey}; +use crate::{ops::MulBase, secret_key::FromSecretKey, Arithmetic, Error, SecretKey}; use core::fmt::{self, Debug}; use core::ops::Add; use generic_array::{ @@ -104,9 +104,9 @@ where } } -impl PublicKey +impl PublicKey where - C: FixedBaseScalarMul, + C: Curve + Arithmetic, C::ElementSize: Add, ::Output: Add, CompressedPoint: From, @@ -118,18 +118,18 @@ where /// /// The `compress` flag requests point compression. pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Result { - let ct_option = C::mul_base(secret_key.secret_scalar()); + let ct_option = C::Scalar::from_secret_key(&secret_key).and_then(|s| s.mul_base()); + + if ct_option.is_none().into() { + return Err(Error); + } - if ct_option.is_some().into() { - let affine_point = ct_option.unwrap(); + let affine_point = ct_option.unwrap(); - if compress { - Ok(PublicKey::Compressed(affine_point.into())) - } else { - Ok(PublicKey::Uncompressed(affine_point.into())) - } + if compress { + Ok(PublicKey::Compressed(affine_point.into())) } else { - Err(Error) + Ok(PublicKey::Uncompressed(affine_point.into())) } } }