| //! Support for SEC1 elliptic curve encoding formats. |
| //! |
| //! <https://www.secg.org/sec1-v2.pdf> |
| |
| pub use sec1::point::{Coordinates, ModulusSize, Tag}; |
| |
| use crate::{Curve, FieldBytesSize, Result, SecretKey}; |
| use generic_array::GenericArray; |
| use subtle::CtOption; |
| |
| #[cfg(feature = "arithmetic")] |
| use crate::{AffinePoint, CurveArithmetic, Error}; |
| |
| /// Encoded elliptic curve point with point compression. |
| pub type CompressedPoint<C> = GenericArray<u8, CompressedPointSize<C>>; |
| |
| /// Size of a compressed elliptic curve point. |
| pub type CompressedPointSize<C> = <FieldBytesSize<C> as ModulusSize>::CompressedPointSize; |
| |
| /// Encoded elliptic curve point sized appropriately for a given curve. |
| pub type EncodedPoint<C> = sec1::point::EncodedPoint<FieldBytesSize<C>>; |
| |
| /// Encoded elliptic curve point *without* point compression. |
| pub type UncompressedPoint<C> = GenericArray<u8, UncompressedPointSize<C>>; |
| |
| /// Size of an uncompressed elliptic curve point. |
| pub type UncompressedPointSize<C> = <FieldBytesSize<C> 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. |
| pub trait FromEncodedPoint<C> |
| where |
| Self: Sized, |
| C: Curve, |
| FieldBytesSize<C>: ModulusSize, |
| { |
| /// Deserialize the type this trait is impl'd on from an [`EncodedPoint`]. |
| fn from_encoded_point(point: &EncodedPoint<C>) -> CtOption<Self>; |
| } |
| |
| /// 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. |
| pub trait ToEncodedPoint<C> |
| where |
| C: Curve, |
| FieldBytesSize<C>: ModulusSize, |
| { |
| /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying |
| /// point compression. |
| fn to_encoded_point(&self, compress: bool) -> EncodedPoint<C>; |
| } |
| |
| /// Trait for serializing a value to a SEC1 encoded curve point with compaction. |
| /// |
| /// This is intended for use with the `AffinePoint` type for a given elliptic curve. |
| pub trait ToCompactEncodedPoint<C> |
| where |
| C: Curve, |
| FieldBytesSize<C>: ModulusSize, |
| { |
| /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying |
| /// point compression. |
| fn to_compact_encoded_point(&self) -> CtOption<EncodedPoint<C>>; |
| } |
| |
| /// Validate that the given [`EncodedPoint`] represents the encoded public key |
| /// value of the given secret. |
| /// |
| /// Curve implementations which also impl [`CurveArithmetic`] will receive |
| /// a blanket default impl of this trait. |
| pub trait ValidatePublicKey |
| where |
| Self: Curve, |
| FieldBytesSize<Self>: ModulusSize, |
| { |
| /// Validate that the given [`EncodedPoint`] is a valid public key for the |
| /// provided secret value. |
| #[allow(unused_variables)] |
| fn validate_public_key( |
| secret_key: &SecretKey<Self>, |
| public_key: &EncodedPoint<Self>, |
| ) -> Result<()> { |
| // Provide a default "always succeeds" implementation. |
| // This is the intended default for curve implementations which |
| // do not provide an arithmetic implementation, since they have no |
| // way to verify this. |
| // |
| // Implementations with an arithmetic impl will receive a blanket impl |
| // of this trait. |
| Ok(()) |
| } |
| } |
| |
| #[cfg(feature = "arithmetic")] |
| impl<C> ValidatePublicKey for C |
| where |
| C: CurveArithmetic, |
| AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>, |
| FieldBytesSize<C>: ModulusSize, |
| { |
| fn validate_public_key(secret_key: &SecretKey<C>, public_key: &EncodedPoint<C>) -> Result<()> { |
| let pk = secret_key |
| .public_key() |
| .to_encoded_point(public_key.is_compressed()); |
| |
| if public_key == &pk { |
| Ok(()) |
| } else { |
| Err(Error) |
| } |
| } |
| } |