jf_relation/gates/
arithmetic.rs

1// Copyright (c) 2022 Espresso Systems (espressosys.com)
2// This file is part of the Jellyfish library.
3
4// You should have received a copy of the MIT License
5// along with the Jellyfish library. If not, see <https://mit-license.org/>.
6
7//! Implementation of arithmetic gates
8
9use super::Gate;
10use crate::constants::{GATE_WIDTH, N_MUL_SELECTORS};
11use ark_ff::Field;
12
13/// A constant gate
14#[derive(Debug, Clone)]
15pub struct ConstantGate<F: Field>(pub(crate) F);
16
17impl<F> Gate<F> for ConstantGate<F>
18where
19    F: Field,
20{
21    fn name(&self) -> &'static str {
22        "Constant Gate"
23    }
24    fn q_c(&self) -> F {
25        self.0
26    }
27    fn q_o(&self) -> F {
28        F::one()
29    }
30}
31
32/// An addition gate
33#[derive(Debug, Clone)]
34pub struct AdditionGate;
35
36impl<F> Gate<F> for AdditionGate
37where
38    F: Field,
39{
40    fn name(&self) -> &'static str {
41        "Addition Gate"
42    }
43    fn q_lc(&self) -> [F; GATE_WIDTH] {
44        [F::one(), F::one(), F::zero(), F::zero()]
45    }
46    fn q_o(&self) -> F {
47        F::one()
48    }
49}
50
51/// Adding a variable by a constant.
52#[derive(Debug, Clone)]
53pub struct ConstantAdditionGate<F: Field>(pub(crate) F);
54
55impl<F> Gate<F> for ConstantAdditionGate<F>
56where
57    F: Field,
58{
59    fn name(&self) -> &'static str {
60        "Constant addition Gate"
61    }
62    fn q_lc(&self) -> [F; GATE_WIDTH] {
63        [F::one(), F::zero(), F::zero(), F::zero()]
64    }
65    fn q_c(&self) -> F {
66        self.0
67    }
68    fn q_o(&self) -> F {
69        F::one()
70    }
71}
72
73/// A subtraction gate
74#[derive(Debug, Clone)]
75pub struct SubtractionGate;
76
77impl<F> Gate<F> for SubtractionGate
78where
79    F: Field,
80{
81    fn name(&self) -> &'static str {
82        "Subtraction Gate"
83    }
84    fn q_lc(&self) -> [F; GATE_WIDTH] {
85        [F::one(), -F::one(), F::zero(), F::zero()]
86    }
87    fn q_o(&self) -> F {
88        F::one()
89    }
90}
91
92/// A multiplication gate
93#[derive(Debug, Clone)]
94pub struct MultiplicationGate;
95
96impl<F> Gate<F> for MultiplicationGate
97where
98    F: Field,
99{
100    fn name(&self) -> &'static str {
101        "Multiplication Gate"
102    }
103    fn q_mul(&self) -> [F; N_MUL_SELECTORS] {
104        [F::one(), F::zero()]
105    }
106    fn q_o(&self) -> F {
107        F::one()
108    }
109}
110
111/// A mul constant gate.
112/// Multiply the first variable with the constant.
113#[derive(Debug, Clone)]
114pub struct ConstantMultiplicationGate<F>(pub(crate) F);
115
116impl<F> Gate<F> for ConstantMultiplicationGate<F>
117where
118    F: Field,
119{
120    fn name(&self) -> &'static str {
121        "Mul constant Gate"
122    }
123    fn q_lc(&self) -> [F; GATE_WIDTH] {
124        [self.0, F::zero(), F::zero(), F::zero()]
125    }
126    fn q_o(&self) -> F {
127        F::one()
128    }
129}
130
131/// A boolean gate, selectors identical to `MultiplicationGate`, achieve through
132/// constraining a * a = a
133#[derive(Debug, Clone)]
134pub struct BoolGate;
135
136impl<F> Gate<F> for BoolGate
137where
138    F: Field,
139{
140    fn name(&self) -> &'static str {
141        "Check Boolean Gate"
142    }
143    fn q_mul(&self) -> [F; N_MUL_SELECTORS] {
144        MultiplicationGate.q_mul()
145    }
146    fn q_o(&self) -> F {
147        MultiplicationGate.q_o()
148    }
149}
150
151/// An equality gate, selectors identical to `SubtractionGate`, achieve through
152/// constraining a - b = 0
153#[derive(Debug, Clone)]
154pub struct EqualityGate;
155
156impl<F> Gate<F> for EqualityGate
157where
158    F: Field,
159{
160    fn name(&self) -> &'static str {
161        "Check Equality Gate"
162    }
163    fn q_lc(&self) -> [F; GATE_WIDTH] {
164        SubtractionGate.q_lc()
165    }
166    fn q_o(&self) -> F {
167        SubtractionGate.q_o()
168    }
169}
170
171/// An I/O gate for public inputs
172#[derive(Debug, Clone)]
173pub struct IoGate;
174
175impl<F> Gate<F> for IoGate
176where
177    F: Field,
178{
179    fn name(&self) -> &'static str {
180        "Public I/O Gate"
181    }
182    fn q_o(&self) -> F {
183        F::one()
184    }
185}
186
187/// Gate for checking a value is the fifth root of another
188#[derive(Debug, Clone)]
189pub struct FifthRootGate;
190
191impl<F: Field> Gate<F> for FifthRootGate {
192    fn name(&self) -> &'static str {
193        "Raise to the inverse of 5 power Gate"
194    }
195
196    fn q_hash(&self) -> [F; GATE_WIDTH] {
197        [F::one(), F::zero(), F::zero(), F::zero()]
198    }
199
200    fn q_o(&self) -> F {
201        F::one()
202    }
203}
204
205/// A deg-2 polynomial gate
206#[derive(Clone)]
207pub struct QuadPolyGate<F: Field> {
208    pub(crate) q_lc: [F; GATE_WIDTH],
209    pub(crate) q_mul: [F; N_MUL_SELECTORS],
210    pub(crate) q_o: F,
211    pub(crate) q_c: F,
212}
213impl<F> Gate<F> for QuadPolyGate<F>
214where
215    F: Field,
216{
217    fn name(&self) -> &'static str {
218        "Deg-2 Polynomial Gate"
219    }
220    fn q_lc(&self) -> [F; GATE_WIDTH] {
221        self.q_lc
222    }
223    fn q_mul(&self) -> [F; N_MUL_SELECTORS] {
224        self.q_mul
225    }
226    fn q_o(&self) -> F {
227        self.q_o
228    }
229    fn q_c(&self) -> F {
230        self.q_c
231    }
232}
233
234/// A linear combination gate
235#[derive(Clone)]
236pub struct LinCombGate<F: Field> {
237    pub(crate) coeffs: [F; GATE_WIDTH],
238}
239impl<F> Gate<F> for LinCombGate<F>
240where
241    F: Field,
242{
243    fn name(&self) -> &'static str {
244        "Linear Combination Gate"
245    }
246    fn q_lc(&self) -> [F; GATE_WIDTH] {
247        self.coeffs
248    }
249    fn q_o(&self) -> F {
250        F::one()
251    }
252}
253
254/// A multiplication-then-addition gate
255#[derive(Clone)]
256pub struct MulAddGate<F: Field> {
257    pub(crate) coeffs: [F; N_MUL_SELECTORS],
258}
259impl<F> Gate<F> for MulAddGate<F>
260where
261    F: Field,
262{
263    fn name(&self) -> &'static str {
264        "Multiplication-then-addition Gate"
265    }
266    fn q_mul(&self) -> [F; N_MUL_SELECTORS] {
267        self.coeffs
268    }
269    fn q_o(&self) -> F {
270        F::one()
271    }
272}
273
274/// A gate for conditional selection
275#[derive(Clone)]
276pub struct CondSelectGate;
277
278impl<F> Gate<F> for CondSelectGate
279where
280    F: Field,
281{
282    fn name(&self) -> &'static str {
283        "Conditional Selection Gate"
284    }
285    fn q_lc(&self) -> [F; GATE_WIDTH] {
286        [F::zero(), F::one(), F::zero(), F::zero()]
287    }
288    fn q_mul(&self) -> [F; N_MUL_SELECTORS] {
289        [-F::one(), F::one()]
290    }
291    fn q_o(&self) -> F {
292        F::one()
293    }
294}