halo2_proofs/plonk/permutation/
keygen.rs
1use ff::Field;
2use group::Curve;
3
4use super::{Argument, ProvingKey, VerifyingKey};
5use crate::{
6 arithmetic::{CurveAffine, FieldExt},
7 plonk::{Any, Column, Error},
8 poly::{
9 commitment::{Blind, Params},
10 EvaluationDomain,
11 },
12};
13
14#[derive(Debug)]
15pub(crate) struct Assembly {
16 columns: Vec<Column<Any>>,
17 pub(crate) mapping: Vec<Vec<(usize, usize)>>,
18 aux: Vec<Vec<(usize, usize)>>,
19 sizes: Vec<Vec<usize>>,
20}
21
22impl Assembly {
23 pub(crate) fn new(n: usize, p: &Argument) -> Self {
24 let mut columns = vec![];
27 for i in 0..p.columns.len() {
28 columns.push((0..n).map(|j| (i, j)).collect());
30 }
31
32 Assembly {
36 columns: p.columns.clone(),
37 mapping: columns.clone(),
38 aux: columns,
39 sizes: vec![vec![1usize; n]; p.columns.len()],
40 }
41 }
42
43 pub(crate) fn copy(
44 &mut self,
45 left_column: Column<Any>,
46 left_row: usize,
47 right_column: Column<Any>,
48 right_row: usize,
49 ) -> Result<(), Error> {
50 let left_column = self
51 .columns
52 .iter()
53 .position(|c| c == &left_column)
54 .ok_or(Error::ColumnNotInPermutation(left_column))?;
55 let right_column = self
56 .columns
57 .iter()
58 .position(|c| c == &right_column)
59 .ok_or(Error::ColumnNotInPermutation(right_column))?;
60
61 if left_row >= self.mapping[left_column].len()
63 || right_row >= self.mapping[right_column].len()
64 {
65 return Err(Error::BoundsFailure);
66 }
67
68 let mut left_cycle = self.aux[left_column][left_row];
71 let mut right_cycle = self.aux[right_column][right_row];
72
73 if left_cycle == right_cycle {
75 return Ok(());
76 }
77
78 if self.sizes[left_cycle.0][left_cycle.1] < self.sizes[right_cycle.0][right_cycle.1] {
79 std::mem::swap(&mut left_cycle, &mut right_cycle);
80 }
81
82 self.sizes[left_cycle.0][left_cycle.1] += self.sizes[right_cycle.0][right_cycle.1];
84 let mut i = right_cycle;
85 loop {
86 self.aux[i.0][i.1] = left_cycle;
87 i = self.mapping[i.0][i.1];
88 if i == right_cycle {
89 break;
90 }
91 }
92
93 let tmp = self.mapping[left_column][left_row];
94 self.mapping[left_column][left_row] = self.mapping[right_column][right_row];
95 self.mapping[right_column][right_row] = tmp;
96
97 Ok(())
98 }
99
100 pub(crate) fn build_vk<C: CurveAffine>(
101 self,
102 params: &Params<C>,
103 domain: &EvaluationDomain<C::Scalar>,
104 p: &Argument,
105 ) -> VerifyingKey<C> {
106 let mut omega_powers = Vec::with_capacity(params.n as usize);
108 {
109 let mut cur = C::Scalar::one();
110 for _ in 0..params.n {
111 omega_powers.push(cur);
112 cur *= &domain.get_omega();
113 }
114 }
115
116 let mut deltaomega = Vec::with_capacity(p.columns.len());
118 {
119 let mut cur = C::Scalar::one();
120 for _ in 0..p.columns.len() {
121 let mut omega_powers = omega_powers.clone();
122 for o in &mut omega_powers {
123 *o *= &cur;
124 }
125
126 deltaomega.push(omega_powers);
127
128 cur *= &C::Scalar::DELTA;
129 }
130 }
131
132 let mut commitments = vec![];
134 for i in 0..p.columns.len() {
135 let mut permutation_poly = domain.empty_lagrange();
138 for (j, p) in permutation_poly.iter_mut().enumerate() {
139 let (permuted_i, permuted_j) = self.mapping[i][j];
140 *p = deltaomega[permuted_i][permuted_j];
141 }
142
143 commitments.push(
145 params
146 .commit_lagrange(&permutation_poly, Blind::default())
147 .to_affine(),
148 );
149 }
150 VerifyingKey { commitments }
151 }
152
153 pub(crate) fn build_pk<C: CurveAffine>(
154 self,
155 params: &Params<C>,
156 domain: &EvaluationDomain<C::Scalar>,
157 p: &Argument,
158 ) -> ProvingKey<C> {
159 let mut omega_powers = Vec::with_capacity(params.n as usize);
161 {
162 let mut cur = C::Scalar::one();
163 for _ in 0..params.n {
164 omega_powers.push(cur);
165 cur *= &domain.get_omega();
166 }
167 }
168
169 let mut deltaomega = Vec::with_capacity(p.columns.len());
171 {
172 let mut cur = C::Scalar::one();
173 for _ in 0..p.columns.len() {
174 let mut omega_powers = omega_powers.clone();
175 for o in &mut omega_powers {
176 *o *= &cur;
177 }
178
179 deltaomega.push(omega_powers);
180
181 cur *= &C::Scalar::DELTA;
182 }
183 }
184
185 let mut permutations = vec![];
187 let mut polys = vec![];
188 let mut cosets = vec![];
189 for i in 0..p.columns.len() {
190 let mut permutation_poly = domain.empty_lagrange();
193 for (j, p) in permutation_poly.iter_mut().enumerate() {
194 let (permuted_i, permuted_j) = self.mapping[i][j];
195 *p = deltaomega[permuted_i][permuted_j];
196 }
197
198 permutations.push(permutation_poly.clone());
200 let poly = domain.lagrange_to_coeff(permutation_poly);
201 polys.push(poly.clone());
202 cosets.push(domain.coeff_to_extended(poly));
203 }
204 ProvingKey {
205 permutations,
206 polys,
207 cosets,
208 }
209 }
210}