1use core::marker::PhantomData;
10
11use crate::{
12 constants::{GATE_WIDTH, N_MUL_SELECTORS},
13 gates::Gate,
14};
15use ark_ec::twisted_edwards::TECurveConfig as Config;
16use ark_ff::PrimeField;
17use derive_where::derive_where;
18
19#[inline]
20fn edwards_coeff_d<P: Config>() -> P::BaseField {
21 P::COEFF_D
22}
23
24#[derive_where(Clone; P: Config)]
26pub struct EdwardsCurveEquationGate<P: Config> {
27 pub(crate) _phantom: PhantomData<P>,
28}
29
30impl<F, P> Gate<F> for EdwardsCurveEquationGate<P>
31where
32 F: PrimeField,
33 P: Config<BaseField = F>,
34{
35 fn name(&self) -> &'static str {
36 "Curve Equation Gate"
37 }
38 fn q_mul(&self) -> [F; N_MUL_SELECTORS] {
39 [-P::COEFF_A, -F::one()]
43 }
44 fn q_c(&self) -> F {
45 F::one()
46 }
47 fn q_ecc(&self) -> F {
48 edwards_coeff_d::<P>()
49 }
50}
51
52#[derive_where(Clone; P: Config)]
54pub struct CurvePointXAdditionGate<P: Config> {
55 pub(crate) _phantom: PhantomData<P>,
56}
57
58impl<F, P> Gate<F> for CurvePointXAdditionGate<P>
59where
60 F: PrimeField,
61 P: Config<BaseField = F>,
62{
63 fn name(&self) -> &'static str {
64 "Point Addition X-coordinate Gate"
65 }
66 fn q_mul(&self) -> [F; N_MUL_SELECTORS] {
67 [F::one(), F::one()]
68 }
69 fn q_o(&self) -> F {
70 F::one()
71 }
72 fn q_ecc(&self) -> F {
73 let d: F = edwards_coeff_d::<P>();
74 -d
75 }
76}
77
78#[derive_where(Clone; P: Config)]
80pub struct CurvePointYAdditionGate<P: Config> {
81 pub(crate) _phantom: PhantomData<P>,
82}
83
84impl<F, P> Gate<F> for CurvePointYAdditionGate<P>
85where
86 F: PrimeField,
87 P: Config<BaseField = F>,
88{
89 fn name(&self) -> &'static str {
90 "Point Addition Y-coordinate Gate"
91 }
92 fn q_mul(&self) -> [F; N_MUL_SELECTORS] {
93 [-P::COEFF_A, F::one()]
94 }
95 fn q_o(&self) -> F {
96 F::one()
97 }
98 fn q_ecc(&self) -> F {
99 edwards_coeff_d::<P>()
100 }
101}
102
103#[derive(Clone)]
107pub struct QuaternaryPointSelectXGate<F: PrimeField> {
108 pub(crate) x1: F,
109 pub(crate) x2: F,
110 pub(crate) x3: F,
111}
112
113impl<F> Gate<F> for QuaternaryPointSelectXGate<F>
114where
115 F: PrimeField,
116{
117 fn name(&self) -> &'static str {
118 "4-ary Point Selection X-coordinate Gate"
119 }
120 fn q_lc(&self) -> [F; GATE_WIDTH] {
121 [self.x1, self.x2, F::zero(), F::zero()]
122 }
123 fn q_mul(&self) -> [F; N_MUL_SELECTORS] {
124 [self.x3 - self.x2 - self.x1, F::zero()]
125 }
126 fn q_o(&self) -> F {
127 F::one()
128 }
129}
130
131#[derive(Clone)]
135pub struct QuaternaryPointSelectYGate<F: PrimeField> {
136 pub(crate) y1: F,
137 pub(crate) y2: F,
138 pub(crate) y3: F,
139}
140
141impl<F> Gate<F> for QuaternaryPointSelectYGate<F>
142where
143 F: PrimeField,
144{
145 fn name(&self) -> &'static str {
146 "4-ary Point Selection Y-coordinate Gate"
147 }
148 fn q_lc(&self) -> [F; GATE_WIDTH] {
149 [self.y1 - F::one(), self.y2 - F::one(), F::zero(), F::zero()]
150 }
151 fn q_mul(&self) -> [F; N_MUL_SELECTORS] {
152 [self.y3 - self.y2 - self.y1 + F::one(), F::zero()]
153 }
154 fn q_c(&self) -> F {
155 F::one()
156 }
157 fn q_o(&self) -> F {
158 F::one()
159 }
160}