1use ark_crypto_primitives::{Error, SNARK};
2use ark_ec::PairingEngine;
3use ark_ff::fields::PrimeField;
4use ark_groth16::{Groth16, Proof, ProvingKey, VerifyingKey};
5use ark_relations::r1cs::ConstraintSynthesizer;
6use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
7use ark_std::{
8 marker::PhantomData,
9 rand::{CryptoRng, RngCore},
10 vec::Vec,
11};
12use arkworks_gadgets::{
13 identity::{constraints::CRHGadget as IdentityCRHGadget, CRH as IdentityCRH},
14 merkle_tree::{Config as MerkleConfig, SparseMerkleTree},
15 poseidon::{constraints::CRHGadget, CRH},
16};
17
18pub struct Leaf {
19 pub secret_bytes: Vec<u8>,
20 pub nullifier_bytes: Vec<u8>,
21 pub leaf_bytes: Vec<u8>,
22 pub nullifier_hash_bytes: Vec<u8>,
23}
24
25pub struct AnchorProof {
26 pub proof: Vec<u8>,
27 pub leaf_raw: Vec<u8>,
28 pub nullifier_hash_raw: Vec<u8>,
29 pub roots_raw: Vec<Vec<u8>>,
30 pub public_inputs_raw: Vec<Vec<u8>>,
31}
32
33pub struct MixerProof {
34 pub proof: Vec<u8>,
35 pub leaf_raw: Vec<u8>,
36 pub nullifier_hash_raw: Vec<u8>,
37 pub root_raw: Vec<u8>,
38 pub public_inputs_raw: Vec<Vec<u8>>,
39}
40
41pub struct Keys {
42 pub pk: Vec<u8>,
43 pub vk: Vec<u8>,
44}
45
46pub type PoseidonCRH_x3_3<F> = CRH<F>;
47pub type PoseidonCRH_x3_3Gadget<F> = CRHGadget<F>;
48
49pub type PoseidonCRH_x3_5<F> = CRH<F>;
50pub type PoseidonCRH_x3_5Gadget<F> = CRHGadget<F>;
51
52pub type PoseidonCRH_x5_3<F> = CRH<F>;
53pub type PoseidonCRH_x5_3Gadget<F> = CRHGadget<F>;
54
55pub type PoseidonCRH_x5_5<F> = CRH<F>;
56pub type PoseidonCRH_x5_5Gadget<F> = CRHGadget<F>;
57
58pub type PoseidonCRH_x5_4<F> = CRH<F>;
59pub type PoseidonCRH_x5_4Gadget<F> = CRHGadget<F>;
60
61pub type PoseidonCRH_x5_2<F> = CRH<F>;
62pub type PoseidonCRH_x5_2Gadget<F> = CRHGadget<F>;
63
64pub type PoseidonCRH_x17_3<F> = CRH<F>;
65pub type PoseidonCRH_x17_3Gadget<F> = CRHGadget<F>;
66
67pub type PoseidonCRH_x17_5<F> = CRH<F>;
68pub type PoseidonCRH_x17_5Gadget<F> = CRHGadget<F>;
69
70#[derive(Default, Clone)]
71pub struct MiMCRounds_220_3;
72
73impl arkworks_gadgets::mimc::Rounds for MiMCRounds_220_3 {
74 const ROUNDS: usize = 220;
75 const WIDTH: usize = 3;
76}
77
78pub type MiMCCRH_220<F> = arkworks_gadgets::mimc::CRH<F, MiMCRounds_220_3>;
79pub type MiMCCRH_220Gadget<F> = arkworks_gadgets::mimc::constraints::CRHGadget<F, MiMCRounds_220_3>;
80
81pub type LeafCRH<F> = IdentityCRH<F>;
82pub type LeafCRHGadget<F> = IdentityCRHGadget<F>;
83pub type Tree_x5<F> = SparseMerkleTree<TreeConfig_x5<F>>;
84pub type Tree_x17<F> = SparseMerkleTree<TreeConfig_x17<F>>;
85pub type Tree_MiMC220<F> = SparseMerkleTree<TreeConfig_MiMC220<F>>;
86
87#[derive(Clone, PartialEq)]
88pub struct TreeConfig_x5<F: PrimeField>(PhantomData<F>);
89impl<F: PrimeField> MerkleConfig for TreeConfig_x5<F> {
90 type H = PoseidonCRH_x5_3<F>;
91 type LeafH = LeafCRH<F>;
92
93 const HEIGHT: u8 = 30;
94}
95
96#[derive(Clone, PartialEq)]
97pub struct TreeConfig_x17<F: PrimeField>(PhantomData<F>);
98impl<F: PrimeField> MerkleConfig for TreeConfig_x17<F> {
99 type H = PoseidonCRH_x17_3<F>;
100 type LeafH = LeafCRH<F>;
101
102 const HEIGHT: u8 = 30;
103}
104
105#[derive(Clone, PartialEq)]
106pub struct TreeConfig_MiMC220<F: PrimeField>(PhantomData<F>);
107impl<F: PrimeField> MerkleConfig for TreeConfig_MiMC220<F> {
108 type H = MiMCCRH_220<F>;
109 type LeafH = LeafCRH<F>;
110
111 const HEIGHT: u8 = 30;
112}
113
114pub fn setup_keys<E: PairingEngine, R: RngCore + CryptoRng, C: ConstraintSynthesizer<E::Fr>>(
115 circuit: C,
116 rng: &mut R,
117) -> Result<(Vec<u8>, Vec<u8>), Error> {
118 let (pk, vk) = Groth16::<E>::circuit_specific_setup(circuit, rng)?;
119
120 let mut pk_bytes = Vec::new();
121 let mut vk_bytes = Vec::new();
122 pk.serialize(&mut pk_bytes)?;
123 vk.serialize(&mut vk_bytes)?;
124 Ok((pk_bytes, vk_bytes))
125}
126
127pub fn setup_keys_unchecked<
128 E: PairingEngine,
129 R: RngCore + CryptoRng,
130 C: ConstraintSynthesizer<E::Fr>,
131>(
132 circuit: C,
133 rng: &mut R,
134) -> Result<(Vec<u8>, Vec<u8>), Error> {
135 let (pk, vk) = Groth16::<E>::circuit_specific_setup(circuit, rng)?;
136
137 let mut pk_bytes = Vec::new();
138 let mut vk_bytes = Vec::new();
139 pk.serialize_unchecked(&mut pk_bytes)?;
140 vk.serialize_unchecked(&mut vk_bytes)?;
141 Ok((pk_bytes, vk_bytes))
142}
143
144pub fn prove<E: PairingEngine, R: RngCore + CryptoRng, C: ConstraintSynthesizer<E::Fr>>(
145 circuit: C,
146 pk_bytes: &[u8],
147 rng: &mut R,
148) -> Result<Vec<u8>, Error> {
149 let pk = ProvingKey::<E>::deserialize(pk_bytes)?;
150
151 let proof = Groth16::prove(&pk, circuit, rng)?;
152 let mut proof_bytes = Vec::new();
153 proof.serialize(&mut proof_bytes)?;
154 Ok(proof_bytes)
155}
156
157pub fn prove_unchecked<
158 E: PairingEngine,
159 R: RngCore + CryptoRng,
160 C: ConstraintSynthesizer<E::Fr>,
161>(
162 circuit: C,
163 pk_unchecked_bytes: &[u8],
164 rng: &mut R,
165) -> Result<Vec<u8>, Error> {
166 let pk = ProvingKey::<E>::deserialize_unchecked(pk_unchecked_bytes)?;
167
168 let proof = Groth16::prove(&pk, circuit, rng)?;
169 let mut proof_bytes = Vec::new();
170 proof.serialize(&mut proof_bytes)?;
171 Ok(proof_bytes)
172}
173
174pub fn verify<E: PairingEngine>(
175 public_inputs: &[E::Fr],
176 vk_bytes: &[u8],
177 proof: &[u8],
178) -> Result<bool, Error> {
179 let vk = VerifyingKey::<E>::deserialize(vk_bytes)?;
180 let proof = Proof::<E>::deserialize(proof)?;
181 verify_groth16(&vk, &public_inputs, &proof)
182}
183
184pub fn verify_unchecked<E: PairingEngine>(
185 public_inputs: &[E::Fr],
186 vk_unchecked_bytes: &[u8],
187 proof: &[u8],
188) -> Result<bool, Error> {
189 let vk = VerifyingKey::<E>::deserialize_unchecked(vk_unchecked_bytes)?;
190 let proof = Proof::<E>::deserialize(proof)?;
191 verify_groth16(&vk, &public_inputs, &proof)
192}
193
194pub fn verify_unchecked_raw<E: PairingEngine>(
195 public_inputs: &[Vec<u8>],
196 vk_unchecked_bytes: &[u8],
197 proof: &[u8],
198) -> Result<bool, Error> {
199 let pub_ins: Vec<E::Fr> = public_inputs
200 .iter()
201 .map(|x| E::Fr::from_le_bytes_mod_order(&x))
202 .collect();
203 let vk = VerifyingKey::<E>::deserialize_unchecked(vk_unchecked_bytes)?;
204 let proof = Proof::<E>::deserialize(proof)?;
205 verify_groth16(&vk, &pub_ins, &proof)
206}
207
208pub fn verify_groth16<E: PairingEngine>(
209 vk: &VerifyingKey<E>,
210 public_inputs: &[E::Fr],
211 proof: &Proof<E>,
212) -> Result<bool, Error> {
213 let res = Groth16::<E>::verify(vk, public_inputs, proof)?;
214 Ok(res)
215}