Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions elliptic-curve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,46 @@ pub use subtle;
#[cfg(feature = "rand_core")]
pub use rand_core;

use core::{fmt::Debug, ops::Add};
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

#[cfg(feature = "rand_core")]
use rand_core::{CryptoRng, RngCore};

/// Byte array containing a serialized scalar value (i.e. an integer)
pub type ScalarBytes<Size> = generic_array::GenericArray<u8, Size>;
/// Elliptic curve.
///
/// This trait is intended to be impl'd by a ZST which represents a concrete
/// elliptic curve.
///
/// Other traits in this crate which are bounded by [`Curve`] are intended to
/// be impl'd by these ZSTs, facilitating types which are generic over elliptic
/// curves (e.g. [`SecretKey`]).
pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync {
/// Number of bytes required to serialize elements of field elements
/// associated with this curve, e.g. elements of the base/scalar fields.
///
/// This is used for computing the sizes for types related to this curve.
type ElementSize: ArrayLength<u8> + Add + Eq + Ord + Unsigned;
}

/// Elliptic curve with curve arithmetic support
pub trait Arithmetic: Curve {
/// Scalar type for a given curve
type Scalar;

/// Trait for randomly generating a value
/// Affine point type for a given curve
type AffinePoint;
}

/// Trait for randomly generating a value.
///
/// Primarily intended for use with scalar types for a particular curve.
#[cfg(feature = "rand_core")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
pub trait Generate {
/// Generate a random element of this type using the provided [`CryptoRng`]
fn generate(rng: impl CryptoRng + RngCore) -> Self;
}

/// Byte array containing a serialized scalar value (i.e. an integer)
pub type ScalarBytes<C> = GenericArray<u8, <C as Curve>::ElementSize>;
50 changes: 16 additions & 34 deletions elliptic-curve/src/secret_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,26 @@
//! When the `zeroize` feature of this crate is enabled, it also handles
//! zeroing it out of memory securely on drop.

use crate::{error::Error, ScalarBytes};
use crate::{error::Error, Curve, ScalarBytes};
use core::{
convert::{TryFrom, TryInto},
fmt,
fmt::{self, Debug},
};
use generic_array::ArrayLength;
use generic_array::{typenum::Unsigned, GenericArray};

/// Secret keys.
/// Elliptic curve secret keys.
///
/// In elliptic curve cryptography, secret keys are concretely privately known
/// scalar values.
///
/// This type wraps a (serialized) scalar value, helping to prevent accidental
/// This type wraps a serialized scalar value, helping to prevent accidental
/// exposure and securely erasing the value from memory when dropped
/// (when the `zeroize` feature of this crate is enabled).
pub struct SecretKey<ScalarSize>
where
ScalarSize: ArrayLength<u8>,
{
pub struct SecretKey<C: Curve> {
/// Private scalar value
scalar: ScalarBytes<ScalarSize>,
scalar: ScalarBytes<C>,
}

impl<ScalarSize> SecretKey<ScalarSize>
where
ScalarSize: ArrayLength<u8>,
{
impl<C: Curve> SecretKey<C> {
/// Create a new secret key from a serialized scalar value
pub fn new(bytes: ScalarBytes<ScalarSize>) -> Self {
pub fn new(bytes: ScalarBytes<C>) -> Self {
Self { scalar: bytes }
}

Expand All @@ -45,42 +36,33 @@ where
}

/// Expose the secret [`ScalarBytes`] value this [`SecretKey`] wraps
pub fn secret_scalar(&self) -> &ScalarBytes<ScalarSize> {
pub fn secret_scalar(&self) -> &ScalarBytes<C> {
&self.scalar
}
}

impl<ScalarSize> TryFrom<&[u8]> for SecretKey<ScalarSize>
where
ScalarSize: ArrayLength<u8>,
{
impl<C: Curve> TryFrom<&[u8]> for SecretKey<C> {
type Error = Error;

fn try_from(slice: &[u8]) -> Result<Self, Error> {
if slice.len() == ScalarSize::to_usize() {
if slice.len() == C::ElementSize::to_usize() {
Ok(SecretKey {
scalar: ScalarBytes::clone_from_slice(slice),
scalar: GenericArray::clone_from_slice(slice),
})
} else {
Err(Error)
}
}
}

impl<ScalarSize> fmt::Debug for SecretKey<ScalarSize>
where
ScalarSize: ArrayLength<u8>,
{
impl<C: Curve> Debug for SecretKey<C> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SecretKey<U{}>{{ ... }}", ScalarSize::to_usize())
write!(f, "SecretKey<{:?}>{{ ... }}", C::default())
}
}

#[cfg(feature = "zeroize")]
impl<ScalarSize> Drop for SecretKey<ScalarSize>
where
ScalarSize: ArrayLength<u8>,
{
impl<C: Curve> Drop for SecretKey<C> {
fn drop(&mut self) {
use zeroize::Zeroize;
self.scalar.zeroize();
Expand Down
30 changes: 17 additions & 13 deletions elliptic-curve/src/weierstrass.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//! Elliptic curves in short Weierstrass form.

pub mod curve;
pub mod point;
pub mod public_key;

pub use curve::Curve;
pub use point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize};
pub use public_key::PublicKey;
pub use self::{
point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize},
public_key::PublicKey,
};

use crate::{consts::U1, ScalarBytes};
use core::ops::Add;
Expand All @@ -19,21 +19,25 @@ use crate::secret_key::SecretKey;
#[cfg(feature = "rand_core")]
use rand_core::{CryptoRng, RngCore};

/// Marker trait for elliptic curves in short Weierstrass form
pub trait Curve: super::Curve {}

/// Fixed-base scalar multiplication
pub trait FixedBaseScalarMul: Curve
where
<Self::ScalarSize as Add>::Output: Add<U1>,
CompressedPoint<Self>: From<Self::Point>,
UncompressedPoint<Self>: From<Self::Point>,
CompressedPointSize<Self::ScalarSize>: ArrayLength<u8>,
UncompressedPointSize<Self::ScalarSize>: ArrayLength<u8>,
Self::ElementSize: Add<U1>,
<Self::ElementSize as Add>::Output: Add<U1>,
CompressedPoint<Self>: From<Self::AffinePoint>,
UncompressedPoint<Self>: From<Self::AffinePoint>,
CompressedPointSize<Self>: ArrayLength<u8>,
UncompressedPointSize<Self>: ArrayLength<u8>,
{
/// Elliptic curve point type
type Point: ConditionallySelectable;
/// Affine point type for this elliptic curve
type AffinePoint: ConditionallySelectable;

/// Multiply the given scalar by the generator point for this elliptic
/// curve.
fn mul_base(scalar: &ScalarBytes<Self::ScalarSize>) -> CtOption<Self::Point>;
fn mul_base(scalar: &ScalarBytes<Self>) -> CtOption<Self::AffinePoint>;
}

/// Generate a secret key for this elliptic curve
Expand All @@ -42,5 +46,5 @@ where
pub trait GenerateSecretKey: Curve {
/// Generate a random [`SecretKey`] for this elliptic curve using the
/// provided [`CryptoRng`]
fn generate_secret_key(rng: impl CryptoRng + RngCore) -> SecretKey<Self::ScalarSize>;
fn generate_secret_key(rng: impl CryptoRng + RngCore) -> SecretKey<Self>;
}
29 changes: 0 additions & 29 deletions elliptic-curve/src/weierstrass/curve.rs

This file was deleted.

Loading