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
/// 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 hahsed. /// - [`Jacobian`]: A non-normal represented internally in Jacobian coordinates. Usually the result of a point operation. Before being serialized or hashed, you have to normalize it. /// - [`BasePoint`]: A normal point that has pre-computed multiplication tables like [`G`]. /// - [`EvenY`]: A normal point whose y-coordinate is known to be _even_ at compile time. /// /// To normalize a `Point<Jacobian>` you mark it as [`Normal`]: /// ``` /// use secp256kfun::{g, marker::*, Scalar, G}; /// let scalar = Scalar::random(&mut rand::thread_rng()); /// let jacobian_point = g!(scalar * G); /// let normal_point = jacobian_point.mark::<Normal>(); /// let bytes = normal_point.to_bytes(); // we can now serialize it /// ``` /// [`G`]: crate::G /// [`Point<T,S,Z>`]: crate::Point pub trait PointType: Sized + Clone + Copy { /// The point type returned from the negation of a point of this type. type NegationType: Default; } /// 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)] #[cfg_attr(feautre = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Normal; #[derive(Default, Debug, Clone, Copy)] /// A Non-normalized Point. `Jacobian` points are represented internally as /// three field elements: `x`,`y` and `z`. Most point operations return /// `Jacobian` points. /// /// In general it's most efficient to normalize `Jacobian` points into [`Normal`] points, as late as possible. pub struct Jacobian; /// A [`Normal`] point whose `y` coordinate is known to be even. #[derive(Default, Debug, Clone, Copy)] #[cfg_attr(feautre = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct EvenY; /// A [`Normal`] point which has pre-computed tables for accelerating scalar /// multiplications. The only example of this is [`G`]. /// /// [`G`]: crate::G #[derive(Clone, Copy)] pub struct BasePoint(pub(crate) crate::backend::BasePoint); /// A marker trait that indicates a `PointType` uses a affine internal representation. #[rustc_specialization_trait] pub trait Normalized: PointType {} #[rustc_specialization_trait] pub(crate) trait NotBasePoint: Default {} impl Normalized for EvenY {} impl Normalized for Normal {} impl Normalized for BasePoint {} impl NotBasePoint for Jacobian {} impl NotBasePoint for EvenY {} impl NotBasePoint for Normal {} impl<N: Normalized> PointType for N { type NegationType = Normal; } impl PointType for Jacobian { type NegationType = Jacobian; } mod change_marks { use crate::{marker::*, Point}; impl<T, S, Z> ChangeMark<Point<T, S, Z>> for Normal { type Out = Point<Normal, S, Z>; fn change_mark(point: Point<T, S, Z>) -> Self::Out { use crate::op::PointUnary; Point::from_inner(point.normalize(), Normal) } } impl<Z, S, T> ChangeMark<Point<T, S, Z>> for Jacobian { type Out = Point<Jacobian, S, Z>; fn change_mark(point: Point<T, S, Z>) -> Self::Out { Point::from_inner(point.0, Jacobian) } } }