elliptic_curve/
sec1.rs

1//! Support for SEC1 elliptic curve encoding formats.
2//!
3//! <https://www.secg.org/sec1-v2.pdf>
4
5pub use sec1::point::{Coordinates, ModulusSize, Tag};
6
7use crate::{Curve, FieldSize, Result, SecretKey};
8use generic_array::GenericArray;
9use subtle::CtOption;
10
11#[cfg(feature = "arithmetic")]
12use crate::{AffinePoint, Error, ProjectiveArithmetic};
13
14/// Encoded elliptic curve point with point compression.
15pub type CompressedPoint<C> = GenericArray<u8, CompressedPointSize<C>>;
16
17/// Size of a compressed elliptic curve point.
18pub type CompressedPointSize<C> = <FieldSize<C> as ModulusSize>::CompressedPointSize;
19
20/// Encoded elliptic curve point sized appropriately for a given curve.
21pub type EncodedPoint<C> = sec1::point::EncodedPoint<FieldSize<C>>;
22
23/// Encoded elliptic curve point *without* point compression.
24pub type UncompressedPoint<C> = GenericArray<u8, UncompressedPointSize<C>>;
25
26/// Size of an uncompressed elliptic curve point.
27pub type UncompressedPointSize<C> = <FieldSize<C> as ModulusSize>::UncompressedPointSize;
28
29/// Trait for deserializing a value from a SEC1 encoded curve point.
30///
31/// This is intended for use with the `AffinePoint` type for a given elliptic curve.
32pub trait FromEncodedPoint<C>
33where
34    Self: Sized,
35    C: Curve,
36    FieldSize<C>: ModulusSize,
37{
38    /// Deserialize the type this trait is impl'd on from an [`EncodedPoint`].
39    fn from_encoded_point(point: &EncodedPoint<C>) -> CtOption<Self>;
40}
41
42/// Trait for serializing a value to a SEC1 encoded curve point.
43///
44/// This is intended for use with the `AffinePoint` type for a given elliptic curve.
45pub trait ToEncodedPoint<C>
46where
47    C: Curve,
48    FieldSize<C>: ModulusSize,
49{
50    /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying
51    /// point compression.
52    fn to_encoded_point(&self, compress: bool) -> EncodedPoint<C>;
53}
54
55/// Trait for serializing a value to a SEC1 encoded curve point with compaction.
56///
57/// This is intended for use with the `AffinePoint` type for a given elliptic curve.
58pub trait ToCompactEncodedPoint<C>
59where
60    C: Curve,
61    FieldSize<C>: ModulusSize,
62{
63    /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying
64    /// point compression.
65    fn to_compact_encoded_point(&self) -> CtOption<EncodedPoint<C>>;
66}
67
68/// Validate that the given [`EncodedPoint`] represents the encoded public key
69/// value of the given secret.
70///
71/// Curve implementations which also impl [`ProjectiveArithmetic`] will receive
72/// a blanket default impl of this trait.
73pub trait ValidatePublicKey
74where
75    Self: Curve,
76    FieldSize<Self>: ModulusSize,
77{
78    /// Validate that the given [`EncodedPoint`] is a valid public key for the
79    /// provided secret value.
80    #[allow(unused_variables)]
81    fn validate_public_key(
82        secret_key: &SecretKey<Self>,
83        public_key: &EncodedPoint<Self>,
84    ) -> Result<()> {
85        // Provide a default "always succeeds" implementation.
86        // This is the intended default for curve implementations which
87        // do not provide an arithmetic implementation, since they have no
88        // way to verify this.
89        //
90        // Implementations with an arithmetic impl will receive a blanket impl
91        // of this trait.
92        Ok(())
93    }
94}
95
96#[cfg(all(feature = "arithmetic"))]
97impl<C> ValidatePublicKey for C
98where
99    C: Curve + ProjectiveArithmetic,
100    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
101    FieldSize<C>: ModulusSize,
102{
103    fn validate_public_key(secret_key: &SecretKey<C>, public_key: &EncodedPoint<C>) -> Result<()> {
104        let pk = secret_key
105            .public_key()
106            .to_encoded_point(public_key.is_compressed());
107
108        if public_key == &pk {
109            Ok(())
110        } else {
111            Err(Error)
112        }
113    }
114}