1use super::common::*;
2use crate::circuit::mixer::MixerCircuit;
3use ark_crypto_primitives::Error;
4use ark_ec::PairingEngine;
5use ark_ff::{BigInteger, PrimeField};
6use ark_std::{
7 rand::{CryptoRng, Rng, RngCore},
8 rc::Rc,
9 vec::Vec,
10};
11use arkworks_gadgets::{
12 arbitrary::mixer_data::Input as MixerDataInput,
13 leaf::mixer::{constraints::MixerLeafGadget, MixerLeaf, Private as LeafPrivate},
14 merkle_tree::Path,
15};
16use arkworks_utils::{
17 poseidon::PoseidonParameters,
18 utils::common::{setup_params_x5_3, setup_params_x5_5, Curve},
19};
20
21pub type MixerConstraintDataInput<F> = MixerDataInput<F>;
22
23pub type Leaf_x5<F> = MixerLeaf<F, PoseidonCRH_x5_5<F>>;
24
25pub type LeafGadget_x5<F> = MixerLeafGadget<F, PoseidonCRH_x5_5<F>, PoseidonCRH_x5_5Gadget<F>>;
26
27pub type Circuit_x5<F, const N: usize> = MixerCircuit<
28 F,
29 PoseidonCRH_x5_5<F>,
30 PoseidonCRH_x5_5Gadget<F>,
31 TreeConfig_x5<F>,
32 LeafCRHGadget<F>,
33 PoseidonCRH_x5_3Gadget<F>,
34 N,
35>;
36
37pub type Leaf_x17<F> = MixerLeaf<F, PoseidonCRH_x17_5<F>>;
38pub type LeafGadget_x17<F> = MixerLeafGadget<F, PoseidonCRH_x17_5<F>, PoseidonCRH_x17_5Gadget<F>>;
39
40pub type Circuit_x17<F, const N: usize> = MixerCircuit<
41 F,
42 PoseidonCRH_x17_5<F>,
43 PoseidonCRH_x17_5Gadget<F>,
44 TreeConfig_x17<F>,
45 LeafCRHGadget<F>,
46 PoseidonCRH_x17_3Gadget<F>,
47 N,
48>;
49
50pub type Leaf_MiMC220<F> = MixerLeaf<F, MiMCCRH_220<F>>;
51pub type LeafGadget_MiMC220<F> = MixerLeafGadget<F, MiMCCRH_220<F>, MiMCCRH_220Gadget<F>>;
52
53pub type Circuit_MiMC220<F, const N: usize> = MixerCircuit<
54 F,
55 MiMCCRH_220<F>,
56 MiMCCRH_220Gadget<F>,
57 TreeConfig_MiMC220<F>,
58 LeafCRHGadget<F>,
59 MiMCCRH_220Gadget<F>,
60 N,
61>;
62
63pub fn setup_leaf_x5_5<F: PrimeField, R: RngCore>(
64 curve: Curve,
65 rng: &mut R,
66) -> Result<Leaf, Error> {
67 let params5 = setup_params_x5_5::<F>(curve);
68 let leaf_private = LeafPrivate::generate(rng);
70
71 let leaf_hash = Leaf_x5::create_leaf(&leaf_private, ¶ms5)?;
72 let nullifier_hash = Leaf_x5::create_nullifier(&leaf_private, ¶ms5)?;
73
74 let secret_bytes = leaf_private.secret().into_repr().to_bytes_le();
75 let nullifier_bytes = leaf_private.nullifier().into_repr().to_bytes_le();
76
77 let leaf_bytes = leaf_hash.into_repr().to_bytes_le();
78 let nullifier_hash_bytes = nullifier_hash.into_repr().to_bytes_le();
79 Ok(Leaf {
80 secret_bytes,
81 nullifier_bytes,
82 leaf_bytes,
83 nullifier_hash_bytes,
84 })
85}
86
87pub fn setup_leaf_with_privates_raw_x5_5<F: PrimeField>(
88 curve: Curve,
89 secret_bytes: Vec<u8>,
90 nullifier_bytes: Vec<u8>,
91) -> Result<Leaf, Error> {
92 let params5 = setup_params_x5_5::<F>(curve);
93
94 let secret = F::from_le_bytes_mod_order(&secret_bytes);
95 let nullifier = F::from_le_bytes_mod_order(&nullifier_bytes);
96 let leaf_private = LeafPrivate::new(secret, nullifier);
98
99 let leaf_hash = Leaf_x5::create_leaf(&leaf_private, ¶ms5)?;
100 let nullifier_hash = Leaf_x5::create_nullifier(&leaf_private, ¶ms5)?;
101
102 let leaf_bytes = leaf_hash.into_repr().to_bytes_le();
103 let nullifier_hash_bytes = nullifier_hash.into_repr().to_bytes_le();
104 Ok(Leaf {
105 secret_bytes,
106 nullifier_bytes,
107 leaf_bytes,
108 nullifier_hash_bytes,
109 })
110}
111
112pub const LEN: usize = 30;
113type MixerProverSetupBn254_30<F> = MixerProverSetup<F, LEN>;
114
115pub fn setup_proof_x5_5<E: PairingEngine, R: RngCore + CryptoRng>(
116 curve: Curve,
117 secret_raw: Vec<u8>,
118 nullifier_raw: Vec<u8>,
119 leaves_raw: Vec<Vec<u8>>,
120 index: u64,
121 recipient_raw: Vec<u8>,
122 relayer_raw: Vec<u8>,
123 fee: u128,
124 refund: u128,
125 pk: Vec<u8>,
126 rng: &mut R,
127) -> Result<MixerProof, Error> {
128 let params3 = setup_params_x5_3::<E::Fr>(curve);
129 let params5 = setup_params_x5_5::<E::Fr>(curve);
130 let prover = MixerProverSetupBn254_30::new(params3, params5);
131
132 let (circuit, leaf_raw, nullifier_hash_raw, root_raw, public_inputs_raw) = prover
133 .setup_circuit_with_privates_raw(
134 secret_raw,
135 nullifier_raw,
136 &leaves_raw,
137 index,
138 recipient_raw,
139 relayer_raw,
140 fee,
141 refund,
142 )?;
143
144 let proof = prove_unchecked::<E, _, _>(circuit, &pk, rng)?;
145
146 Ok(MixerProof {
147 proof,
148 leaf_raw,
149 nullifier_hash_raw,
150 root_raw,
151 public_inputs_raw,
152 })
153}
154
155pub fn setup_keys_x5_5<E: PairingEngine, R: RngCore + CryptoRng>(
156 curve: Curve,
157 rng: &mut R,
158) -> Result<Keys, Error> {
159 let params3 = setup_params_x5_3::<E::Fr>(curve);
160 let params5 = setup_params_x5_5::<E::Fr>(curve);
161 let prover = MixerProverSetupBn254_30::new(params3, params5);
162
163 let (circuit, ..) = prover.setup_random_circuit(rng)?;
164
165 let (pk, vk) = setup_keys_unchecked::<E, _, _>(circuit, rng)?;
166
167 Ok(Keys { pk, vk })
168}
169
170pub struct MixerProverSetup<F: PrimeField, const N: usize> {
171 params3: PoseidonParameters<F>,
172 params5: PoseidonParameters<F>,
173}
174
175impl<F: PrimeField, const N: usize> MixerProverSetup<F, N> {
176 pub fn new(params3: PoseidonParameters<F>, params5: PoseidonParameters<F>) -> Self {
177 Self { params3, params5 }
178 }
179
180 pub fn setup_arbitrary_data(
181 recipient: F,
182 relayer: F,
183 fee: F,
184 refund: F,
185 ) -> MixerConstraintDataInput<F> {
186 MixerConstraintDataInput::new(recipient, relayer, fee, refund)
187 }
188
189 pub fn construct_public_inputs(
190 nullifier_hash: F,
191 root: F,
192 recipient: F,
193 relayer: F,
194 fee: F,
195 refund: F,
196 ) -> Vec<F> {
197 vec![nullifier_hash, root, recipient, relayer, fee, refund]
198 }
199
200 pub fn deconstruct_public_inputs(
201 public_inputs: &[F],
202 ) -> (
203 F, F, F, F, F, F, ) {
210 (
211 public_inputs[0],
212 public_inputs[1],
213 public_inputs[2],
214 public_inputs[3],
215 public_inputs[4],
216 public_inputs[6],
217 )
218 }
219
220 pub fn setup_leaf<R: Rng>(&self, rng: &mut R) -> Result<(LeafPrivate<F>, F, F), Error> {
221 let leaf_private = LeafPrivate::generate(rng);
223
224 let leaf_hash = Leaf_x5::create_leaf(&leaf_private, &self.params5)?;
226 let nullifier_hash = Leaf_x5::create_nullifier(&leaf_private, &self.params5)?;
227 Ok((leaf_private, leaf_hash, nullifier_hash))
228 }
229
230 pub fn setup_leaf_with_privates(
231 &self,
232 secret: F,
233 nullifier: F,
234 ) -> Result<(LeafPrivate<F>, F, F), Error> {
235 let leaf_private = LeafPrivate::new(secret, nullifier);
237
238 let leaf_hash = Leaf_x5::create_leaf(&leaf_private, &self.params5)?;
240 let nullifier_hash = Leaf_x5::create_nullifier(&leaf_private, &self.params5)?;
241 Ok((leaf_private, leaf_hash, nullifier_hash))
242 }
243
244 pub fn setup_leaf_with_privates_raw(
245 &self,
246 secret: Vec<u8>,
247 nullifier: Vec<u8>,
248 ) -> Result<(LeafPrivate<F>, F, F), Error> {
249 let secret_f = F::from_le_bytes_mod_order(&secret);
251 let nullifier_f = F::from_le_bytes_mod_order(&nullifier);
252
253 self.setup_leaf_with_privates(secret_f, nullifier_f)
254 }
255
256 #[allow(clippy::too_many_arguments)]
257 pub fn setup_circuit_with_privates(
258 self,
259 secret: F,
260 nullifier: F,
261 leaves: &[F],
262 index: u64,
263 recipient: F,
264 relayer: F,
265 fee: F,
266 refund: F,
267 ) -> Result<(Circuit_x5<F, N>, F, F, F, Vec<F>), Error> {
268 let arbitrary_input = Self::setup_arbitrary_data(recipient, relayer, fee, refund);
269 let (leaf_private, leaf, nullifier_hash) =
270 self.setup_leaf_with_privates(secret, nullifier)?;
271 let (tree, path) = self.setup_tree_and_create_path(&leaves, index)?;
272 let root = tree.root().inner();
273
274 let mc = Circuit_x5::new(
275 arbitrary_input,
276 leaf_private,
277 self.params5,
278 path,
279 root,
280 nullifier_hash,
281 );
282 let public_inputs =
283 Self::construct_public_inputs(nullifier_hash, root, recipient, relayer, fee, refund);
284 Ok((mc, leaf, nullifier_hash, root, public_inputs))
285 }
286
287 #[allow(clippy::too_many_arguments)]
288 pub fn setup_circuit_with_privates_raw(
289 self,
290 secret: Vec<u8>,
291 nullifier: Vec<u8>,
292 leaves: &[Vec<u8>],
293 index: u64,
294 recipient: Vec<u8>,
295 relayer: Vec<u8>,
296 fee: u128,
297 refund: u128,
298 ) -> Result<(Circuit_x5<F, N>, Vec<u8>, Vec<u8>, Vec<u8>, Vec<Vec<u8>>), Error> {
299 let secret_f = F::from_le_bytes_mod_order(&secret);
300 let nullifier_f = F::from_le_bytes_mod_order(&nullifier);
301 let leaves_f: Vec<F> = leaves
302 .iter()
303 .map(|x| F::from_le_bytes_mod_order(x))
304 .collect();
305 let recipient_f = F::from_le_bytes_mod_order(&recipient);
306 let relayer_f = F::from_le_bytes_mod_order(&relayer);
307 let fee_f = F::from(fee);
308 let refund_f = F::from(refund);
309
310 let (mc, leaf, nullifier_hash, root, public_inputs) = self.setup_circuit_with_privates(
311 secret_f,
312 nullifier_f,
313 &leaves_f,
314 index,
315 recipient_f,
316 relayer_f,
317 fee_f,
318 refund_f,
319 )?;
320
321 let leaf_raw = leaf.into_repr().to_bytes_le();
322 let nullifier_hash_raw = nullifier_hash.into_repr().to_bytes_le();
323 let root_raw = root.into_repr().to_bytes_le();
324 let public_inputs_raw: Vec<Vec<u8>> = public_inputs
325 .iter()
326 .map(|x| x.into_repr().to_bytes_le())
327 .collect();
328
329 Ok((
330 mc,
331 leaf_raw,
332 nullifier_hash_raw,
333 root_raw,
334 public_inputs_raw,
335 ))
336 }
337
338 pub fn setup_random_circuit<R: Rng>(
339 self,
340 rng: &mut R,
341 ) -> Result<(Circuit_x5<F, N>, F, F, F, Vec<F>), Error> {
342 let recipient = F::rand(rng);
343 let relayer = F::rand(rng);
344 let fee = F::rand(rng);
345 let refund = F::rand(rng);
346
347 let (leaf_privates, leaf_hash, ..) = self.setup_leaf(rng).unwrap();
348 let secret = leaf_privates.secret();
349 let nullifier = leaf_privates.nullifier();
350 let leaves = vec![leaf_hash];
351 let index = 0;
352
353 self.setup_circuit_with_privates(
354 secret, nullifier, &leaves, index, recipient, relayer, fee, refund,
355 )
356 }
357
358 pub fn create_circuit(
359 self,
360 arbitrary_input: MixerConstraintDataInput<F>,
361 leaf_private: LeafPrivate<F>,
362 path: Path<TreeConfig_x5<F>, N>,
363 root: F,
364 nullifier_hash: F,
365 ) -> Circuit_x5<F, N> {
366 let mc = Circuit_x5::new(
367 arbitrary_input,
368 leaf_private,
369 self.params5,
370 path,
371 root,
372 nullifier_hash,
373 );
374 mc
375 }
376
377 pub fn setup_tree(&self, leaves: &[F]) -> Result<Tree_x5<F>, Error> {
378 let inner_params = Rc::new(self.params3.clone());
379 let mt = Tree_x5::new_sequential(inner_params, Rc::new(()), leaves)?;
380 Ok(mt)
381 }
382
383 pub fn setup_tree_and_create_path(
384 &self,
385 leaves: &[F],
386 index: u64,
387 ) -> Result<(Tree_x5<F>, Path<TreeConfig_x5<F>, N>), Error> {
388 let mt = self.setup_tree(leaves)?;
390 let path = mt.generate_membership_proof(index);
392 Ok((mt, path))
393 }
394}