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
/// Every `T` of a [`Point<T,S,Z>`] implements the `PointType` trait.
///
/// There are several different point types.
/// - [`Normal`]: A point represented internally with Affine coordinates, with x and y coordinates (if it's not zero). These can be directly serialized or hashed.
/// - [`NonNormal`]: A non-normalized represented internally as in three coordinates. Usually the result of a point operation. Before being serialized or hashed, you have to normalize it.
/// - [`BasePoint`]: A normal point that has (or may have in the future) pre-computed multiplication tables like [`G`].
/// - [`EvenY`]: A normal point whose y-coordinate is known to be _even_ at compile time.
///
/// [`Point<T,S,Z>`]: crate::Point
/// [`G`]: crate::G
pub trait PointType:
Sized + Clone + Copy + PartialEq + Eq + core::hash::Hash + Ord + PartialOrd
{
/// The point type returned from the negation of a point of this type.
type NegationType: Default;
/// Whether the point type is normalized or not (i.e. not [`NonNormal`])
fn is_normalized() -> bool;
}
/// A Fully Normalized Point. Internally `Normal` points are represented using
/// _affine_ coordinates with fully normalized `x` and `y` field elements.
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
pub struct Normal;
/// A Non-normalized Point. Usually, represented as three field elements three field elements:
/// `x`,`y` and `z` rather than just two in a [`Normal`] point.
///
/// In general it's most efficient to normalize `NonNormal` points into `Normal` points, as late as
/// possible. To normalize a `NonNormal` point call `normalize` on the point.
///
/// ```
/// use secp256kfun::{g, marker::*, Scalar, G};
/// let scalar = Scalar::random(&mut rand::thread_rng());
/// let non_normal_point = g!(scalar * G);
/// let normal_point = non_normal_point.normalize();
/// let bytes = normal_point.to_bytes(); // we can now serialize it
/// ```
///
/// [`normalize`]: crate::Point::normalize
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
pub struct NonNormal;
/// Backwards compatibility type alias.
#[deprecated(note = "use NonNormal instead")]
pub type Jacobian = NonNormal;
/// A [`Normal`] point whose `y` coordinate is known to be even.
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
pub struct EvenY;
/// A [`Normal`] point which may have pre-computed tables for accelerating scalar
/// multiplications. The only example of this is [`G`].
///
/// Note that whether G does have pre-computed tables depends on the current state of the backend.
/// At the time of writing no pre-computation is done.
///
/// [`G`]: crate::G
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct BasePoint;
/// A marker trait that indicates a `PointType` uses a affine internal representation.
pub trait Normalized: PointType {}
impl Normalized for EvenY {}
impl Normalized for Normal {}
impl Normalized for BasePoint {}
impl<N: Normalized> PointType for N {
type NegationType = Normal;
#[inline(always)]
fn is_normalized() -> bool {
true
}
}
impl PointType for NonNormal {
type NegationType = NonNormal;
#[inline(always)]
fn is_normalized() -> bool {
false
}
}