dusk_cdf/
polynomial.rs

1use std::io;
2
3use crate::{
4    Config, DecodableElement, DecoderContext, Element, EncodableElement, EncoderContext, Preamble,
5    Scalar,
6};
7
8/// Polynomial selectors
9#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub struct Selectors {
11    /// Qm (mult) selector
12    pub qm: Scalar,
13    /// Ql (left) selector
14    pub ql: Scalar,
15    /// Qr (right) selector
16    pub qr: Scalar,
17    /// Qd (fourth) selector
18    pub qd: Scalar,
19    /// Qc (constant) selector
20    pub qc: Scalar,
21    /// Qo (output) selector
22    pub qo: Scalar,
23    /// Public input
24    pub pi: Scalar,
25    /// Qarith (arithmetic) internal selector
26    pub qarith: Scalar,
27    /// Qlogic (logical) internal selector
28    pub qlogic: Scalar,
29    /// Qrange (range check) internal selector
30    pub qrange: Scalar,
31    /// Qgroup_variable (ecc group variable add) internal selector
32    pub qgroup_variable: Scalar,
33    /// Qgroup_fixed (ecc group fixed add) internal selector
34    pub qfixed_add: Scalar,
35}
36
37impl Element for Selectors {
38    fn len(ctx: &Config) -> usize {
39        12 * Scalar::len(ctx)
40    }
41
42    fn validate(&self, preamble: &Preamble) -> io::Result<()> {
43        self.qm.validate(preamble)?;
44        self.ql.validate(preamble)?;
45        self.qr.validate(preamble)?;
46        self.qd.validate(preamble)?;
47        self.qc.validate(preamble)?;
48        self.qo.validate(preamble)?;
49        self.pi.validate(preamble)?;
50        self.qarith.validate(preamble)?;
51        self.qlogic.validate(preamble)?;
52        self.qrange.validate(preamble)?;
53        self.qgroup_variable.validate(preamble)?;
54        self.qfixed_add.validate(preamble)?;
55
56        Ok(())
57    }
58}
59
60impl EncodableElement for Selectors {
61    fn to_buffer(&self, ctx: &mut EncoderContext, buf: &mut [u8]) {
62        let buf = self.qm.encode(ctx, buf);
63        let buf = self.ql.encode(ctx, buf);
64        let buf = self.qr.encode(ctx, buf);
65        let buf = self.qd.encode(ctx, buf);
66        let buf = self.qc.encode(ctx, buf);
67        let buf = self.qo.encode(ctx, buf);
68        let buf = self.pi.encode(ctx, buf);
69        let buf = self.qarith.encode(ctx, buf);
70        let buf = self.qlogic.encode(ctx, buf);
71        let buf = self.qrange.encode(ctx, buf);
72        let buf = self.qgroup_variable.encode(ctx, buf);
73        let _ = self.qfixed_add.encode(ctx, buf);
74    }
75}
76
77impl DecodableElement for Selectors {
78    fn try_from_buffer_in_place<'a, 'b>(
79        &'a mut self,
80        ctx: &DecoderContext<'a>,
81        buf: &'b [u8],
82    ) -> io::Result<()> {
83        Self::validate_buffer(ctx.config(), buf)?;
84
85        let buf = self.qm.try_decode_in_place(ctx, buf)?;
86        let buf = self.ql.try_decode_in_place(ctx, buf)?;
87        let buf = self.qr.try_decode_in_place(ctx, buf)?;
88        let buf = self.qd.try_decode_in_place(ctx, buf)?;
89        let buf = self.qc.try_decode_in_place(ctx, buf)?;
90        let buf = self.qo.try_decode_in_place(ctx, buf)?;
91        let buf = self.pi.try_decode_in_place(ctx, buf)?;
92        let buf = self.qarith.try_decode_in_place(ctx, buf)?;
93        let buf = self.qlogic.try_decode_in_place(ctx, buf)?;
94        let buf = self.qrange.try_decode_in_place(ctx, buf)?;
95        let buf = self.qgroup_variable.try_decode_in_place(ctx, buf)?;
96        let _ = self.qfixed_add.try_decode_in_place(ctx, buf)?;
97
98        Ok(())
99    }
100}
101
102/// Polynomial witnesses allocated to a constraint system
103#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
104pub struct WiredWitnesses {
105    /// Wired `a`
106    pub a: usize,
107    /// Wired `b`
108    pub b: usize,
109    /// Wired `d` (fourth)
110    pub d: usize,
111    /// Wired `o` (output)
112    pub o: usize,
113}
114
115impl Element for WiredWitnesses {
116    fn len(ctx: &Config) -> usize {
117        4 * usize::len(ctx)
118    }
119
120    fn validate(&self, preamble: &Preamble) -> io::Result<()> {
121        self.a.validate(preamble)?;
122        self.b.validate(preamble)?;
123        self.d.validate(preamble)?;
124        self.o.validate(preamble)?;
125
126        Ok(())
127    }
128}
129
130impl EncodableElement for WiredWitnesses {
131    fn to_buffer(&self, ctx: &mut EncoderContext, buf: &mut [u8]) {
132        let buf = self.a.encode(ctx, buf);
133        let buf = self.b.encode(ctx, buf);
134        let buf = self.d.encode(ctx, buf);
135        let _ = self.o.encode(ctx, buf);
136    }
137}
138
139impl DecodableElement for WiredWitnesses {
140    fn try_from_buffer_in_place<'a, 'b>(
141        &'a mut self,
142        ctx: &DecoderContext<'a>,
143        buf: &'b [u8],
144    ) -> io::Result<()> {
145        let buf = self.a.try_decode_in_place(ctx, buf)?;
146        let buf = self.b.try_decode_in_place(ctx, buf)?;
147        let buf = self.d.try_decode_in_place(ctx, buf)?;
148        let _ = self.o.try_decode_in_place(ctx, buf)?;
149
150        Ok(())
151    }
152}
153
154/// PLONK polynomial expression representation with its selectors and witnesses.
155#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
156pub struct Polynomial {
157    /// Selectors of the polynomial
158    pub selectors: Selectors,
159    /// Wired witnesses
160    pub witnesses: WiredWitnesses,
161    /// Polynomial evaluated to zero?
162    pub evaluation: bool,
163}
164
165impl Element for Polynomial {
166    fn len(ctx: &Config) -> usize {
167        Selectors::len(ctx) + WiredWitnesses::len(ctx) + bool::len(ctx)
168    }
169
170    fn validate(&self, preamble: &Preamble) -> io::Result<()> {
171        self.selectors.validate(preamble)?;
172        self.witnesses.validate(preamble)?;
173        self.evaluation.validate(preamble)?;
174
175        Ok(())
176    }
177}
178
179impl EncodableElement for Polynomial {
180    fn to_buffer(&self, ctx: &mut EncoderContext, buf: &mut [u8]) {
181        let buf = self.selectors.encode(ctx, buf);
182        let buf = self.witnesses.encode(ctx, buf);
183        let _ = self.evaluation.encode(ctx, buf);
184    }
185}
186
187impl DecodableElement for Polynomial {
188    fn try_from_buffer_in_place<'a, 'b>(
189        &'a mut self,
190        ctx: &DecoderContext<'a>,
191        buf: &'b [u8],
192    ) -> io::Result<()> {
193        let buf = self.selectors.try_decode_in_place(ctx, buf)?;
194        let buf = self.witnesses.try_decode_in_place(ctx, buf)?;
195        let _ = self.evaluation.try_decode_in_place(ctx, buf)?;
196
197        Ok(())
198    }
199}
200
201impl Polynomial {
202    /// Create a new polynomial with evaluation to either correct or incorrect
203    pub const fn new(selectors: Selectors, witnesses: WiredWitnesses, evaluation: bool) -> Self {
204        Self {
205            selectors,
206            witnesses,
207            evaluation,
208        }
209    }
210
211    /// Check if the polynomial evaluation is ok
212    pub const fn is_ok(&self) -> bool {
213        self.evaluation
214    }
215
216    /// Wire selectors
217    pub const fn selectors(&self) -> &Selectors {
218        &self.selectors
219    }
220
221    /// Wired witnesses
222    pub const fn witnesses(&self) -> &WiredWitnesses {
223        &self.witnesses
224    }
225}