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