Skip to main content

ed448_goldilocks/curve/twedwards/
extensible.rs

1#![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/// This is the representation that we will do most of the group operations on.
10// In affine (x,y) is the extensible point (X, Y, Z, T1, T2)
11// Where x = X/Z , y = Y/Z , T1 * T2 = T
12// XXX: I think we have too many point representations,
13// But let's not remove any yet
14#[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    /// Doubles a point
56    /// (3.3) https://iacr.org/archive/asiacrypt2008/53500329/53500329.pdf
57    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    /// Converts an extensible point to an extended point
76    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    /// Converts an extended point to Affine co-ordinates
86    pub(crate) fn to_affine(self) -> AffinePoint {
87        // Points to consider:
88        // - All points where Z=0, translate to (0,0)
89        // - The identity point has z=1, so it is not a problem
90
91        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}