1#![allow(non_snake_case)]
2use core::iter;
3
4use ark_bls12_381::{Fr, G1Affine, G1Projective};
5use ark_ec::group::Group;
6use ark_ec::ProjectiveCurve;
7use ark_ff::PrimeField;
8use ark_std::rand::RngCore;
9
10use crate::transcript::CurdleproofsTranscript;
11use merlin::Transcript;
12
13use crate::errors::ProofError;
14use crate::grand_product_argument::GrandProductProof;
15use crate::msm_accumulator::MsmAccumulator;
16use crate::util::{get_permutation, msm};
17
18#[derive(Clone, Debug)]
20pub struct SamePermutationProof {
21 B: G1Projective,
22
23 grand_product_proof: GrandProductProof,
24}
25
26impl SamePermutationProof {
27 pub fn new<T: RngCore>(
41 crs_G_vec: &Vec<G1Affine>,
42 crs_H_vec: &Vec<G1Affine>,
43 crs_U: &G1Projective, A: G1Projective,
46 M: G1Projective,
47 vec_a: &Vec<Fr>,
48
49 permutation: Vec<u32>,
50 vec_a_blinders: Vec<Fr>, vec_m_blinders: Vec<Fr>, transcript: &mut Transcript,
54 rng: &mut T,
55 ) -> SamePermutationProof {
56 let n_blinders = vec_a_blinders.len();
57 let ell = crs_G_vec.len();
58
59 transcript.append_list(b"same_perm_step1", &[&A, &M]);
61 transcript.append_list(b"same_perm_step1", &[vec_a]);
62 let alpha = transcript.get_and_append_challenge(b"same_perm_alpha");
63 let beta = transcript.get_and_append_challenge(b"same_perm_beta");
64
65 let vec_a_permuted = get_permutation(vec_a, &permutation);
67 let permutation_as_fr = permutation.iter().map(|s| Fr::from(*s));
68 let permuted_polynomial_factors: Vec<Fr> = vec_a_permuted
69 .iter()
70 .zip(permutation_as_fr)
71 .map(|(a, m)| *a + m * alpha + beta)
72 .collect();
73 let gprod_result: Fr = permuted_polynomial_factors.iter().product();
74
75 let vec_beta_repeated: Vec<Fr> = iter::repeat(beta).take(ell).collect();
76 let B = A + M.mul(alpha.into_repr()) + msm(crs_G_vec, &vec_beta_repeated);
77
78 let mut vec_b_blinders = Vec::with_capacity(n_blinders);
79 for i in 0..n_blinders {
80 vec_b_blinders.push(vec_a_blinders[i] + alpha * vec_m_blinders[i]);
81 }
82
83 let grand_product_proof = GrandProductProof::new(
84 crs_G_vec,
85 crs_H_vec,
86 crs_U,
87 B,
88 gprod_result,
89 permuted_polynomial_factors,
90 vec_b_blinders,
91 transcript,
92 rng,
93 );
94
95 SamePermutationProof {
96 B,
97 grand_product_proof,
98 }
99 }
100
101 pub fn verify<T: RngCore>(
112 &self,
113
114 crs_G_vec: &Vec<G1Affine>,
115 crs_H_vec: &Vec<G1Affine>,
116 crs_U: &G1Projective, crs_G_sum: &G1Affine,
118 crs_H_sum: &G1Affine,
119
120 A: &G1Projective,
121 M: &G1Projective,
122 vec_a: &Vec<Fr>,
123
124 n_blinders: usize,
125 transcript: &mut Transcript,
126 msm_accumulator: &mut MsmAccumulator,
127
128 rng: &mut T,
129 ) -> Result<(), ProofError> {
130 let ell = crs_G_vec.len();
131
132 transcript.append_list(b"same_perm_step1", &[A, M]);
134 transcript.append_list(b"same_perm_step1", &[vec_a]);
135 let alpha = transcript.get_and_append_challenge(b"same_perm_alpha");
136 let beta = transcript.get_and_append_challenge(b"same_perm_beta");
137
138 let range_as_fr = (0..ell as u32).map(Fr::from);
140 let polynomial_factors = vec_a
141 .iter()
142 .zip(range_as_fr)
143 .map(|(a, i)| *a + i * alpha + beta);
144 let gprod_result: Fr = polynomial_factors.product();
145
146 let vec_beta_repeated: Vec<Fr> = iter::repeat(beta).take(ell).collect();
147
148 msm_accumulator.accumulate_check(
149 &(self.B - A - M.mul(&alpha)),
150 &vec_beta_repeated,
151 crs_G_vec,
152 rng,
153 );
154
155 self.grand_product_proof.verify(
156 crs_G_vec,
157 crs_H_vec,
158 crs_U,
159 crs_G_sum,
160 crs_H_sum,
161 self.B,
162 gprod_result,
163 n_blinders,
164 transcript,
165 msm_accumulator,
166 rng,
167 )?;
168
169 Ok(())
170 }
171}
172
173#[cfg(test)]
174mod tests {
175 use super::*;
176 use ark_ec::ProjectiveCurve;
177 use ark_std::rand::prelude::SliceRandom;
178 use ark_std::rand::{rngs::StdRng, Rng, SeedableRng};
179 use ark_std::UniformRand;
180 use core::iter;
181
182 use crate::util::generate_blinders;
183
184 #[test]
185 fn test_same_perm_argument() {
186 let mut rng = StdRng::seed_from_u64(0u64);
187 let mut transcript_prover = merlin::Transcript::new(b"sameperm");
188
189 let n = 128;
190 let n_blinders = 4;
191 let ell = n - n_blinders;
192
193 let crs_G_vec: Vec<_> = iter::repeat_with(|| G1Projective::rand(&mut rng).into_affine())
194 .take(ell)
195 .collect();
196 let crs_H_vec: Vec<_> = iter::repeat_with(|| G1Projective::rand(&mut rng).into_affine())
197 .take(n_blinders)
198 .collect();
199 let crs_U = G1Projective::rand(&mut rng);
200 let crs_G_sum: G1Affine = crs_G_vec.iter().sum();
201 let crs_H_sum: G1Affine = crs_H_vec.iter().sum();
202
203 let vec_a_blinders = generate_blinders(&mut rng, n_blinders);
204 let vec_m_blinders = generate_blinders(&mut rng, n_blinders);
205
206 let mut permutation: Vec<u32> = (0..ell as u32).collect();
207 permutation.shuffle(&mut rng);
208 let permutation_as_fr: Vec<Fr> = permutation.iter().map(|s| Fr::from(*s)).collect();
209
210 let vec_a: Vec<Fr> = iter::repeat_with(|| rng.gen()).take(ell).collect();
211 let vec_a_permuted = get_permutation(&vec_a, &permutation);
212
213 let A = msm(&crs_G_vec, &vec_a_permuted) + msm(&crs_H_vec, &vec_a_blinders);
214 let M = msm(&crs_G_vec, &permutation_as_fr) + msm(&crs_H_vec, &vec_m_blinders);
215
216 let same_perm_proof = SamePermutationProof::new(
217 &crs_G_vec,
218 &crs_H_vec,
219 &crs_U,
220 A,
221 M,
222 &vec_a,
223 permutation,
224 vec_a_blinders,
225 vec_m_blinders,
226 &mut transcript_prover,
227 &mut rng,
228 );
229
230 let mut transcript_verifier = merlin::Transcript::new(b"sameperm");
232 let mut msm_accumulator = MsmAccumulator::new();
233
234 assert!(same_perm_proof
235 .verify(
236 &crs_G_vec,
237 &crs_H_vec,
238 &crs_U,
239 &crs_G_sum,
240 &crs_H_sum,
241 &A,
242 &M,
243 &vec_a,
244 n_blinders,
245 &mut transcript_verifier,
246 &mut msm_accumulator,
247 &mut rng,
248 )
249 .is_ok());
250
251 assert!(msm_accumulator.verify().is_ok());
252
253 let mut transcript_verifier = merlin::Transcript::new(b"sameperm");
256 let mut msm_accumulator = MsmAccumulator::new();
257
258 assert!(same_perm_proof
259 .verify(
260 &crs_G_vec,
261 &crs_H_vec,
262 &crs_U,
263 &crs_G_sum,
264 &crs_H_sum,
265 &A,
266 &M,
267 &vec_a,
268 n_blinders,
269 &mut transcript_verifier,
270 &mut msm_accumulator,
271 &mut rng,
272 )
273 .is_ok());
274
275 assert!(msm_accumulator.verify().is_ok())
276 }
277}