1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
//! 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)
}
}
}