fullcodec_plonk/proof_system/widget/permutation/
proverkey.rs1use crate::fft::{EvaluationDomain, Evaluations, Polynomial};
8use crate::permutation::constants::{K1, K2, K3};
9use dusk_bls12_381::BlsScalar;
10
11#[derive(Debug, Eq, PartialEq, Clone)]
12pub(crate) struct ProverKey {
13 pub(crate) left_sigma: (Polynomial, Evaluations),
14 pub(crate) right_sigma: (Polynomial, Evaluations),
15 pub(crate) out_sigma: (Polynomial, Evaluations),
16 pub(crate) fourth_sigma: (Polynomial, Evaluations),
17 pub(crate) linear_evaluations: Evaluations,
18 }
25
26impl ProverKey {
27 pub(crate) fn compute_quotient_i(
28 &self,
29 index: usize,
30 w_l_i: &BlsScalar,
31 w_r_i: &BlsScalar,
32 w_o_i: &BlsScalar,
33 w_4_i: &BlsScalar,
34 z_i: &BlsScalar,
35 z_i_next: &BlsScalar,
36 alpha: &BlsScalar,
37 l1_alpha_sq: &BlsScalar,
38 beta: &BlsScalar,
39 gamma: &BlsScalar,
40 ) -> BlsScalar {
41 let a = self.compute_quotient_identity_range_check_i(
42 index, w_l_i, w_r_i, w_o_i, w_4_i, z_i, alpha, beta, gamma,
43 );
44 let b = self.compute_quotient_copy_range_check_i(
45 index, w_l_i, w_r_i, w_o_i, w_4_i, z_i_next, alpha, beta, gamma,
46 );
47 let c = self.compute_quotient_term_check_one_i(z_i, l1_alpha_sq);
48 a + b + c
49 }
50 fn compute_quotient_identity_range_check_i(
53 &self,
54 index: usize,
55 w_l_i: &BlsScalar,
56 w_r_i: &BlsScalar,
57 w_o_i: &BlsScalar,
58 w_4_i: &BlsScalar,
59 z_i: &BlsScalar,
60 alpha: &BlsScalar,
61 beta: &BlsScalar,
62 gamma: &BlsScalar,
63 ) -> BlsScalar {
64 let x = self.linear_evaluations[index];
65
66 (w_l_i + (beta * x) + gamma)
67 * (w_r_i + (beta * K1 * x) + gamma)
68 * (w_o_i + (beta * K2 * x) + gamma)
69 * (w_4_i + (beta * K3 * x) + gamma)
70 * z_i
71 * alpha
72 }
73 fn compute_quotient_copy_range_check_i(
77 &self,
78 index: usize,
79 w_l_i: &BlsScalar,
80 w_r_i: &BlsScalar,
81 w_o_i: &BlsScalar,
82 w_4_i: &BlsScalar,
83 z_i_next: &BlsScalar,
84 alpha: &BlsScalar,
85 beta: &BlsScalar,
86 gamma: &BlsScalar,
87 ) -> BlsScalar {
88 let left_sigma_eval = self.left_sigma.1[index];
89 let right_sigma_eval = self.right_sigma.1[index];
90 let out_sigma_eval = self.out_sigma.1[index];
91 let fourth_sigma_eval = self.fourth_sigma.1[index];
92
93 let product = (w_l_i + (beta * left_sigma_eval) + gamma)
94 * (w_r_i + (beta * right_sigma_eval) + gamma)
95 * (w_o_i + (beta * out_sigma_eval) + gamma)
96 * (w_4_i + (beta * fourth_sigma_eval) + gamma)
97 * z_i_next
98 * alpha;
99
100 -product
101 }
102 fn compute_quotient_term_check_one_i(
104 &self,
105 z_i: &BlsScalar,
106 l1_alpha_sq: &BlsScalar,
107 ) -> BlsScalar {
108 (z_i - BlsScalar::one()) * l1_alpha_sq
109 }
110
111 pub(crate) fn compute_linearisation(
112 &self,
113 z_challenge: &BlsScalar,
114 (alpha, beta, gamma): (&BlsScalar, &BlsScalar, &BlsScalar),
115 (a_eval, b_eval, c_eval, d_eval): (
116 &BlsScalar,
117 &BlsScalar,
118 &BlsScalar,
119 &BlsScalar,
120 ),
121 (sigma_1_eval, sigma_2_eval, sigma_3_eval): (
122 &BlsScalar,
123 &BlsScalar,
124 &BlsScalar,
125 ),
126 z_eval: &BlsScalar,
127 z_poly: &Polynomial,
128 ) -> Polynomial {
129 let a = self.compute_lineariser_identity_range_check(
130 (a_eval, b_eval, c_eval, d_eval),
131 z_challenge,
132 (alpha, beta, gamma),
133 z_poly,
134 );
135 let b = self.compute_lineariser_copy_range_check(
136 (a_eval, b_eval, c_eval),
137 z_eval,
138 sigma_1_eval,
139 sigma_2_eval,
140 sigma_3_eval,
141 (alpha, beta, gamma),
142 &self.fourth_sigma.0,
143 );
144
145 let domain = EvaluationDomain::new(z_poly.degree()).unwrap();
146 let c = self.compute_lineariser_check_is_one(
147 &domain,
148 z_challenge,
149 &alpha.square(),
150 z_poly,
151 );
152 &(&a + &b) + &c
153 }
154 fn compute_lineariser_identity_range_check(
157 &self,
158 (a_eval, b_eval, c_eval, d_eval): (
159 &BlsScalar,
160 &BlsScalar,
161 &BlsScalar,
162 &BlsScalar,
163 ),
164 z_challenge: &BlsScalar,
165 (alpha, beta, gamma): (&BlsScalar, &BlsScalar, &BlsScalar),
166 z_poly: &Polynomial,
167 ) -> Polynomial {
168 let beta_z = beta * z_challenge;
169
170 let mut a_0 = a_eval + beta_z;
172 a_0 += gamma;
173
174 let beta_z_k1 = K1 * beta_z;
176 let mut a_1 = b_eval + beta_z_k1;
177 a_1 += gamma;
178
179 let beta_z_k2 = K2 * beta_z;
181 let mut a_2 = c_eval + beta_z_k2;
182 a_2 += gamma;
183
184 let beta_z_k3 = K3 * beta_z;
186 let mut a_3 = d_eval + beta_z_k3;
187 a_3 += gamma;
188
189 let mut a = a_0 * a_1;
190 a *= a_2;
191 a *= a_3;
192 a *= alpha; z_poly * &a }
199 fn compute_lineariser_copy_range_check(
202 &self,
203 (a_eval, b_eval, c_eval): (&BlsScalar, &BlsScalar, &BlsScalar),
204 z_eval: &BlsScalar,
205 sigma_1_eval: &BlsScalar,
206 sigma_2_eval: &BlsScalar,
207 sigma_3_eval: &BlsScalar,
208 (alpha, beta, gamma): (&BlsScalar, &BlsScalar, &BlsScalar),
209 fourth_sigma_poly: &Polynomial,
210 ) -> Polynomial {
211 let beta_sigma_1 = beta * sigma_1_eval;
213 let mut a_0 = a_eval + beta_sigma_1;
214 a_0 += gamma;
215
216 let beta_sigma_2 = beta * sigma_2_eval;
218 let mut a_1 = b_eval + beta_sigma_2;
219 a_1 += gamma;
220
221 let beta_sigma_3 = beta * sigma_3_eval;
223 let mut a_2 = c_eval + beta_sigma_3;
224 a_2 += gamma;
225
226 let beta_z_eval = beta * z_eval;
227
228 let mut a = a_0 * a_1 * a_2;
229 a *= beta_z_eval;
230 a *= alpha; fourth_sigma_poly * &-a }
238
239 fn compute_lineariser_check_is_one(
240 &self,
241 domain: &EvaluationDomain,
242 z_challenge: &BlsScalar,
243 alpha_sq: &BlsScalar,
244 z_coeffs: &Polynomial,
245 ) -> Polynomial {
246 let l_1_z = domain.evaluate_all_lagrange_coefficients(*z_challenge)[0];
248
249 z_coeffs * &(l_1_z * alpha_sq)
250 }
251}