ed448_goldilocks/curve/twedwards/
projective.rs1#![allow(non_snake_case)]
2
3use super::extensible::ExtensiblePoint;
4use crate::field::FieldElement;
5use subtle::{Choice, ConditionallyNegatable, ConditionallySelectable};
6
7impl Default for ProjectiveNielsPoint {
8 fn default() -> ProjectiveNielsPoint {
9 ProjectiveNielsPoint::IDENTITY
10 }
11}
12
13#[derive(Copy, Clone, Debug)]
16pub struct ProjectiveNielsPoint {
17 pub(crate) Y_plus_X: FieldElement,
18 pub(crate) Y_minus_X: FieldElement,
19 pub(crate) Td: FieldElement,
20 pub(crate) Z: FieldElement,
21}
22
23impl PartialEq for ProjectiveNielsPoint {
24 fn eq(&self, other: &ProjectiveNielsPoint) -> bool {
25 self.to_extensible().eq(&other.to_extensible())
26 }
27}
28impl Eq for ProjectiveNielsPoint {}
29
30impl ConditionallySelectable for ProjectiveNielsPoint {
31 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
32 ProjectiveNielsPoint {
33 Y_plus_X: FieldElement::conditional_select(&a.Y_plus_X, &b.Y_plus_X, choice),
34 Y_minus_X: FieldElement::conditional_select(&a.Y_minus_X, &b.Y_minus_X, choice),
35 Td: FieldElement::conditional_select(&a.Td, &b.Td, choice),
36 Z: FieldElement::conditional_select(&a.Z, &b.Z, choice),
37 }
38 }
39}
40impl ConditionallyNegatable for ProjectiveNielsPoint {
41 fn conditional_negate(&mut self, choice: Choice) {
42 FieldElement::conditional_swap(&mut self.Y_minus_X, &mut self.Y_plus_X, choice);
43 self.Td.conditional_negate(choice);
44 }
45}
46
47impl ProjectiveNielsPoint {
48 pub const IDENTITY: ProjectiveNielsPoint = ProjectiveNielsPoint {
49 Y_plus_X: FieldElement::ONE,
50 Y_minus_X: FieldElement::ONE,
51 Td: FieldElement::ZERO,
52 Z: FieldElement::TWO,
53 };
54
55 pub fn to_extensible(self) -> ExtensiblePoint {
56 let A = self.Y_plus_X - self.Y_minus_X;
57 let B = self.Y_plus_X + self.Y_minus_X;
58 ExtensiblePoint {
59 X: self.Z * A,
60 Y: self.Z * B,
61 Z: self.Z.square(),
62 T1: B,
63 T2: A,
64 }
65 }
66}
67#[cfg(test)]
68mod tests {
69 use super::*;
70 use crate::curve::twedwards::extended::ExtendedPoint;
71
72 #[test]
73 fn identity() {
74 assert_eq!(
78 ProjectiveNielsPoint::IDENTITY,
79 ExtendedPoint::IDENTITY.to_projective_niels(),
80 );
81 assert_eq!(
83 ProjectiveNielsPoint::IDENTITY.to_extensible(),
84 ExtendedPoint::IDENTITY,
85 );
86 }
87
88 #[test]
89 fn test_conditional_negate() {
90 let bp = ExtendedPoint::GENERATOR;
91
92 let mut bp_neg = bp.to_projective_niels();
93 bp_neg.conditional_negate(1.into());
94
95 let expect_identity = bp_neg.to_extensible().to_extended().add_extended(&bp);
96 assert_eq!(ExtendedPoint::IDENTITY, expect_identity);
97 }
98}