fullcodec_plonk/constraint_system/
constraint.rs1use crate::constraint_system::{TurboComposer, Witness};
8use dusk_bls12_381::BlsScalar;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub(crate) enum Selector {
13 Multiplication = 0x00,
15 Left = 0x01,
17 Right = 0x02,
19 Output = 0x03,
21 Fourth = 0x04,
23 Constant = 0x05,
25 PublicInput = 0x06,
27
28 Arithmetic = 0x07,
30 Range = 0x08,
32 Logic = 0x09,
34 GroupAddFixedBase = 0x0a,
36 GroupAddVariableBase = 0x0b,
38 Lookup = 0x0c,
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44pub(crate) enum WiredWitness {
45 A = 0x00,
47 B = 0x01,
49 O = 0x02,
51 D = 0x03,
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
58pub struct Constraint {
59 coefficients: [BlsScalar; 13],
60 witnesses: [Witness; 4],
61
62 has_public_input: bool,
82}
83
84impl Default for Constraint {
85 fn default() -> Self {
86 Self::new()
87 }
88}
89
90impl AsRef<[BlsScalar]> for Constraint {
91 fn as_ref(&self) -> &[BlsScalar] {
92 &self.coefficients
93 }
94}
95
96impl Constraint {
97 pub const fn new() -> Self {
99 Self {
100 coefficients: [BlsScalar::zero(); 13],
101 witnesses: [TurboComposer::constant_zero(); 4],
102 has_public_input: false,
103 }
104 }
105
106 fn set<T: Into<BlsScalar>>(mut self, r: Selector, s: T) -> Self {
107 self.coefficients[r as usize] = s.into();
108
109 self
110 }
111
112 fn from_external(constraint: &Self) -> Self {
113 const EXTERNAL: usize = Selector::Arithmetic as usize;
114
115 let mut s = Self::default();
116
117 let src = &constraint.coefficients[..EXTERNAL];
118 let dst = &mut s.coefficients[..EXTERNAL];
119
120 dst.copy_from_slice(src);
121
122 s.has_public_input = constraint.has_public_input();
123 s.witnesses.copy_from_slice(&constraint.witnesses);
124
125 s
126 }
127
128 pub(crate) const fn coeff(&self, r: Selector) -> &BlsScalar {
130 &self.coefficients[r as usize]
131 }
132
133 pub(crate) const fn witness(&self, w: WiredWitness) -> Witness {
135 self.witnesses[w as usize]
136 }
137
138 pub fn mult<T: Into<BlsScalar>>(self, s: T) -> Self {
140 self.set(Selector::Multiplication, s)
141 }
142
143 pub fn left<T: Into<BlsScalar>>(self, s: T) -> Self {
145 self.set(Selector::Left, s)
146 }
147
148 pub fn right<T: Into<BlsScalar>>(self, s: T) -> Self {
150 self.set(Selector::Right, s)
151 }
152
153 pub fn output<T: Into<BlsScalar>>(self, s: T) -> Self {
155 self.set(Selector::Output, s)
156 }
157
158 pub fn fourth<T: Into<BlsScalar>>(self, s: T) -> Self {
160 self.set(Selector::Fourth, s)
161 }
162
163 pub fn constant<T: Into<BlsScalar>>(self, s: T) -> Self {
165 self.set(Selector::Constant, s)
166 }
167
168 pub fn public<T: Into<BlsScalar>>(mut self, s: T) -> Self {
170 self.has_public_input = true;
171
172 self.set(Selector::PublicInput, s)
173 }
174
175 pub fn a(mut self, w: Witness) -> Self {
177 self.witnesses[WiredWitness::A as usize] = w;
178
179 self
180 }
181
182 pub fn b(mut self, w: Witness) -> Self {
184 self.witnesses[WiredWitness::B as usize] = w;
185
186 self
187 }
188
189 pub fn o(mut self, w: Witness) -> Self {
191 self.witnesses[WiredWitness::O as usize] = w;
192
193 self
194 }
195
196 pub fn d(mut self, w: Witness) -> Self {
198 self.witnesses[WiredWitness::D as usize] = w;
199
200 self
201 }
202
203 pub(crate) const fn has_public_input(&self) -> bool {
204 self.has_public_input
205 }
206
207 pub(crate) fn arithmetic(s: &Self) -> Self {
208 Self::from_external(s).set(Selector::Arithmetic, 1)
209 }
210
211 #[allow(dead_code)]
212 pub(crate) fn range(s: &Self) -> Self {
215 Self::from_external(s).set(Selector::Range, 1)
216 }
217
218 #[allow(dead_code)]
219 pub(crate) fn logic(s: &Self) -> Self {
222 Self::from_external(s)
223 .set(Selector::Constant, 1)
224 .set(Selector::Logic, 1)
225 }
226
227 #[allow(dead_code)]
228 pub(crate) fn logic_xor(s: &Self) -> Self {
231 Self::from_external(s)
232 .set(Selector::Constant, -BlsScalar::one())
233 .set(Selector::Logic, -BlsScalar::one())
234 }
235
236 #[allow(dead_code)]
237 pub(crate) fn group_add_fixed_base(s: &Self) -> Self {
240 Self::from_external(s).set(Selector::GroupAddFixedBase, 1)
241 }
242
243 #[allow(dead_code)]
244 pub(crate) fn group_add_variable_base(s: &Self) -> Self {
247 Self::from_external(s).set(Selector::GroupAddVariableBase, 1)
248 }
249
250 #[allow(dead_code)]
251 pub(crate) fn lookup(s: &Self) -> Self {
254 Self::from_external(s).set(Selector::Lookup, 1)
255 }
256}