ed448_goldilocks/curve/twedwards/
extensible.rs1#![allow(non_snake_case)]
2#![allow(dead_code)]
3
4use super::affine::AffinePoint;
5use super::extended::ExtendedPoint;
6use crate::field::FieldElement;
7use subtle::{Choice, ConstantTimeEq};
8
9#[derive(Copy, Clone, Debug)]
15pub struct ExtensiblePoint {
16 pub(crate) X: FieldElement,
17 pub(crate) Y: FieldElement,
18 pub(crate) Z: FieldElement,
19 pub(crate) T1: FieldElement,
20 pub(crate) T2: FieldElement,
21}
22
23impl ConstantTimeEq for ExtensiblePoint {
24 fn ct_eq(&self, other: &Self) -> Choice {
25 let XZ = self.X * other.Z;
26 let ZX = self.Z * other.X;
27
28 let YZ = self.Y * other.Z;
29 let ZY = self.Z * other.Y;
30
31 XZ.ct_eq(&ZX) & YZ.ct_eq(&ZY)
32 }
33}
34impl PartialEq for ExtensiblePoint {
35 fn eq(&self, other: &ExtensiblePoint) -> bool {
36 self.ct_eq(other).into()
37 }
38}
39impl PartialEq<ExtendedPoint> for ExtensiblePoint {
40 fn eq(&self, other: &ExtendedPoint) -> bool {
41 self.ct_eq(&other.to_extensible()).into()
42 }
43}
44impl Eq for ExtensiblePoint {}
45
46impl ExtensiblePoint {
47 pub const IDENTITY: ExtensiblePoint = ExtensiblePoint {
48 X: FieldElement::ZERO,
49 Y: FieldElement::ONE,
50 Z: FieldElement::ONE,
51 T1: FieldElement::ZERO,
52 T2: FieldElement::ONE,
53 };
54
55 pub fn double(&self) -> ExtensiblePoint {
58 let A = self.X.square();
59 let B = self.Y.square();
60 let C = self.Z.square().double();
61 let D = -A;
62 let E = (self.X + self.Y).square() - A - B;
63 let G = D + B;
64 let F = G - C;
65 let H = D - B;
66 ExtensiblePoint {
67 X: E * F,
68 Y: G * H,
69 Z: F * G,
70 T1: E,
71 T2: H,
72 }
73 }
74
75 pub fn to_extended(self) -> ExtendedPoint {
77 ExtendedPoint {
78 X: self.X,
79 Y: self.Y,
80 Z: self.Z,
81 T: self.T1 * self.T2,
82 }
83 }
84
85 pub(crate) fn to_affine(self) -> AffinePoint {
87 let INV_Z = self.Z.invert();
92
93 let x = self.X * INV_Z;
94 let y = self.Y * INV_Z;
95
96 AffinePoint { x, y }
97 }
98}