diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index c9088f065..53bdedaed 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -4,11 +4,12 @@ pub use sec1::point::{Coordinates, ModulusSize, Tag}; -use crate::{Curve, FieldBytesSize, Result, SecretKey, ctutils::CtOption}; -use array::Array; +use crate::{Curve, Error, FieldBytesSize, Result, SecretKey, array::Array, ctutils::CtOption}; #[cfg(feature = "arithmetic")] -use crate::{AffinePoint, CurveArithmetic, Error}; +use crate::{AffinePoint, CurveArithmetic}; +#[cfg(feature = "alloc")] +use {crate::point::PointCompression, alloc::boxed::Box}; /// Encoded elliptic curve point with point compression. pub type CompressedPoint = Array>; @@ -17,7 +18,7 @@ pub type CompressedPoint = Array>; pub type CompressedPointSize = as ModulusSize>::CompressedPointSize; /// Encoded elliptic curve point sized appropriately for a given curve. -pub type EncodedPoint = sec1::point::EncodedPoint>; +pub type EncodedPoint = ::sec1::point::EncodedPoint>; /// Encoded elliptic curve point *without* point compression. pub type UncompressedPoint = Array>; @@ -25,30 +26,61 @@ pub type UncompressedPoint = Array>; /// Size of an uncompressed elliptic curve point. pub type UncompressedPointSize = as ModulusSize>::UncompressedPointSize; -/// Trait for deserializing a value from a SEC1 encoded curve point. -/// -/// This is intended for use with the `AffinePoint` type for a given elliptic curve. +/// Decode curve point using the `Octet-String-to-Elliptic-Curve-Point` conversion described in +/// [SEC 1: Elliptic Curve Cryptography (Version 2.0)](https://www.secg.org/sec1-v2.pdf) +/// §2.3.4 (page 11). pub trait FromEncodedPoint where Self: Sized, C: Curve, FieldBytesSize: ModulusSize, { - /// Deserialize the type this trait is impl'd on from an [`EncodedPoint`]. + /// Decode curve point from a SEC1 [`EncodedPoint`]. fn from_encoded_point(point: &EncodedPoint) -> CtOption; + + /// Decode curve point from the provided SEC1 encoding (compressed, uncompressed, or + /// identity) using the `Octet-String-to-Elliptic-Curve-Point` conversion. + fn from_sec1_bytes(bytes: &[u8]) -> Result { + let point = EncodedPoint::::from_bytes(bytes)?; + Self::from_encoded_point(&point).into_option().ok_or(Error) + } } -/// Trait for serializing a value to a SEC1 encoded curve point. -/// -/// This is intended for use with the `AffinePoint` type for a given elliptic curve. +/// Encode curve point using the `Elliptic-Curve-Point-to-Octet-String` conversion described in +/// [SEC 1: Elliptic Curve Cryptography (Version 2.0)](https://www.secg.org/sec1-v2.pdf) +/// §2.3.3 (page 10). pub trait ToEncodedPoint where C: Curve, FieldBytesSize: ModulusSize, { - /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying - /// point compression. + /// Serialize curve point as a SEC1 [`EncodedPoint`], optionally applying point compression + /// according to the `compress` flag. fn to_encoded_point(&self, compress: bool) -> EncodedPoint; + + /// Serialize curve point as a [`CompressedPoint`]. + fn to_compressed_point(&self) -> CompressedPoint { + let mut ret = CompressedPoint::::default(); + ret.copy_from_slice(self.to_encoded_point(true).as_bytes()); + ret + } + + /// Serialize curve point as a [`CompressedPoint`]. + fn to_uncompressed_point(&self) -> UncompressedPoint { + let mut ret = UncompressedPoint::::default(); + ret.copy_from_slice(self.to_encoded_point(false).as_bytes()); + ret + } + + /// Encode curve point using the `Elliptic-Curve-Point-to-Octet-String` conversion and the + /// point compression default for this curve as specified by the [`PointCompression`] trait. + #[cfg(feature = "alloc")] + fn to_sec1_bytes(&self) -> Box<[u8]> + where + C: PointCompression, + { + self.to_encoded_point(C::COMPRESS_POINTS).to_bytes() + } } /// Trait for serializing a value to a SEC1 encoded curve point with compaction.