From f04131578fe8265287f6179b702c49a86381ea25 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 29 Jul 2020 09:34:28 -0700 Subject: [PATCH] elliptic-curve: add FromPublicKey/FromSecretKey traits These traits allow converting: - SecretKey => Scalar - PublicKey => AffinePoint ...in a curve-agnostic way. --- elliptic-curve/src/lib.rs | 9 ++++++--- elliptic-curve/src/secret_key.rs | 9 +++++++++ elliptic-curve/src/weierstrass.rs | 2 +- elliptic-curve/src/weierstrass/public_key.rs | 19 +++++++++++++++++++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 141bff378..dbb6292e9 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -30,7 +30,10 @@ pub mod secret_key; #[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))] pub mod weierstrass; -pub use self::{error::Error, secret_key::SecretKey}; +pub use self::{ + error::Error, + secret_key::{FromSecretKey, SecretKey}, +}; pub use generic_array::{self, typenum::consts}; pub use subtle; @@ -62,13 +65,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; + type Scalar: FromSecretKey; /// Affine point type for a given curve type AffinePoint; } -/// Trait for randomly generating a value. +/// Randomly generate a value. /// /// Primarily intended for use with scalar types for a particular curve. #[cfg(feature = "rand_core")] diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 31de82fd9..d431cf2f0 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -13,6 +13,7 @@ use core::{ fmt::{self, Debug}, }; use generic_array::{typenum::Unsigned, GenericArray}; +use subtle::CtOption; #[cfg(feature = "rand_core")] use { @@ -89,3 +90,11 @@ impl Drop for SecretKey { self.scalar.zeroize(); } } + +/// Trait for deserializing a value from a secret key. +/// +/// This is intended for use with the `Scalar` type for a given elliptic curve. +pub trait FromSecretKey: Sized { + /// Deserialize this value from a [`SecretKey`] + fn from_secret_key(secret_key: &SecretKey) -> CtOption; +} diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index 362ea1704..424f28fbb 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -5,7 +5,7 @@ pub mod public_key; pub use self::{ point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, - public_key::PublicKey, + public_key::{FromPublicKey, PublicKey}, }; use crate::{Arithmetic, ScalarBytes}; diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs index dde6000d1..3aaaa520d 100644 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -12,6 +12,7 @@ use generic_array::{ typenum::{Unsigned, U1}, ArrayLength, GenericArray, }; +use subtle::CtOption; /// Size of an untagged point for given elliptic curve. pub type UntaggedPointSize = <::ElementSize as Add>::Output; @@ -192,3 +193,21 @@ where PublicKey::Uncompressed(point) } } + +/// Trait for deserializing a value from a public key. +/// +/// This is intended for use with the `AffinePoint` type for a given elliptic curve. +pub trait FromPublicKey: Sized +where + C::ElementSize: Add, + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Deserialize this value from a [`PublicKey`] + /// + /// # Returns + /// + /// `None` if the public key is not on the curve. + fn from_public_key(public_key: &PublicKey) -> CtOption; +}