1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
use ark_crypto_primitives::{Error, SNARK};
use ark_ec::PairingEngine;
use ark_ff::fields::PrimeField;
use ark_groth16::{Groth16, Proof, ProvingKey, VerifyingKey};
use ark_relations::r1cs::ConstraintSynthesizer;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_std::{
	marker::PhantomData,
	rand::{CryptoRng, RngCore},
	vec::Vec,
};
use arkworks_gadgets::{
	identity::{constraints::CRHGadget as IdentityCRHGadget, CRH as IdentityCRH},
	merkle_tree::{Config as MerkleConfig, SparseMerkleTree},
	poseidon::{constraints::CRHGadget, CRH},
};

pub type PoseidonCRH_x3_3<F> = CRH<F>;
pub type PoseidonCRH_x3_3Gadget<F> = CRHGadget<F>;

pub type PoseidonCRH_x3_5<F> = CRH<F>;
pub type PoseidonCRH_x3_5Gadget<F> = CRHGadget<F>;

pub type PoseidonCRH_x5_3<F> = CRH<F>;
pub type PoseidonCRH_x5_3Gadget<F> = CRHGadget<F>;

pub type PoseidonCRH_x5_5<F> = CRH<F>;
pub type PoseidonCRH_x5_5Gadget<F> = CRHGadget<F>;

pub type PoseidonCRH_x5_4<F> = CRH<F>;
pub type PoseidonCRH_x5_4Gadget<F> = CRHGadget<F>;

pub type PoseidonCRH_x5_2<F> = CRH<F>;
pub type PoseidonCRH_x5_2Gadget<F> = CRHGadget<F>;

pub type PoseidonCRH_x17_3<F> = CRH<F>;
pub type PoseidonCRH_x17_3Gadget<F> = CRHGadget<F>;

pub type PoseidonCRH_x17_5<F> = CRH<F>;
pub type PoseidonCRH_x17_5Gadget<F> = CRHGadget<F>;

#[derive(Default, Clone)]
pub struct MiMCRounds_220_3;

impl arkworks_gadgets::mimc::Rounds for MiMCRounds_220_3 {
	const ROUNDS: usize = 220;
	const WIDTH: usize = 3;
}

pub type MiMCCRH_220<F> = arkworks_gadgets::mimc::CRH<F, MiMCRounds_220_3>;
pub type MiMCCRH_220Gadget<F> = arkworks_gadgets::mimc::constraints::CRHGadget<F, MiMCRounds_220_3>;

pub type LeafCRH<F> = IdentityCRH<F>;
pub type LeafCRHGadget<F> = IdentityCRHGadget<F>;
pub type Tree_x5<F> = SparseMerkleTree<TreeConfig_x5<F>>;
pub type Tree_x17<F> = SparseMerkleTree<TreeConfig_x17<F>>;
pub type Tree_MiMC220<F> = SparseMerkleTree<TreeConfig_MiMC220<F>>;

#[derive(Clone, PartialEq)]
pub struct TreeConfig_x5<F: PrimeField>(PhantomData<F>);
impl<F: PrimeField> MerkleConfig for TreeConfig_x5<F> {
	type H = PoseidonCRH_x5_3<F>;
	type LeafH = LeafCRH<F>;

	const HEIGHT: u8 = 30;
}

#[derive(Clone, PartialEq)]
pub struct TreeConfig_x17<F: PrimeField>(PhantomData<F>);
impl<F: PrimeField> MerkleConfig for TreeConfig_x17<F> {
	type H = PoseidonCRH_x17_3<F>;
	type LeafH = LeafCRH<F>;

	const HEIGHT: u8 = 30;
}

#[derive(Clone, PartialEq)]
pub struct TreeConfig_MiMC220<F: PrimeField>(PhantomData<F>);
impl<F: PrimeField> MerkleConfig for TreeConfig_MiMC220<F> {
	type H = MiMCCRH_220<F>;
	type LeafH = LeafCRH<F>;

	const HEIGHT: u8 = 30;
}

pub fn setup_keys<E: PairingEngine, R: RngCore + CryptoRng, C: ConstraintSynthesizer<E::Fr>>(
	circuit: C,
	rng: &mut R,
) -> Result<(Vec<u8>, Vec<u8>), Error> {
	let (pk, vk) = Groth16::<E>::circuit_specific_setup(circuit, rng)?;

	let mut pk_bytes = Vec::new();
	let mut vk_bytes = Vec::new();
	pk.serialize(&mut pk_bytes)?;
	vk.serialize(&mut vk_bytes)?;
	Ok((pk_bytes, vk_bytes))
}

pub fn setup_keys_unchecked<
	E: PairingEngine,
	R: RngCore + CryptoRng,
	C: ConstraintSynthesizer<E::Fr>,
>(
	circuit: C,
	rng: &mut R,
) -> Result<(Vec<u8>, Vec<u8>), Error> {
	let (pk, vk) = Groth16::<E>::circuit_specific_setup(circuit, rng)?;

	let mut pk_bytes = Vec::new();
	let mut vk_bytes = Vec::new();
	pk.serialize_unchecked(&mut pk_bytes)?;
	vk.serialize_unchecked(&mut vk_bytes)?;
	Ok((pk_bytes, vk_bytes))
}

pub fn prove<E: PairingEngine, R: RngCore + CryptoRng, C: ConstraintSynthesizer<E::Fr>>(
	circuit: C,
	pk_bytes: &[u8],
	rng: &mut R,
) -> Result<Vec<u8>, Error> {
	let pk = ProvingKey::<E>::deserialize(pk_bytes)?;

	let proof = Groth16::prove(&pk, circuit, rng)?;
	let mut proof_bytes = Vec::new();
	proof.serialize(&mut proof_bytes)?;
	Ok(proof_bytes)
}

pub fn prove_unchecked<
	E: PairingEngine,
	R: RngCore + CryptoRng,
	C: ConstraintSynthesizer<E::Fr>,
>(
	circuit: C,
	pk_unchecked_bytes: &[u8],
	rng: &mut R,
) -> Result<Vec<u8>, Error> {
	let pk = ProvingKey::<E>::deserialize_unchecked(pk_unchecked_bytes)?;

	let proof = Groth16::prove(&pk, circuit, rng)?;
	let mut proof_bytes = Vec::new();
	proof.serialize(&mut proof_bytes)?;
	Ok(proof_bytes)
}

pub fn verify<E: PairingEngine>(
	public_inputs: &[E::Fr],
	vk_bytes: &[u8],
	proof: &[u8],
) -> Result<bool, Error> {
	let vk = VerifyingKey::<E>::deserialize(vk_bytes)?;
	let proof = Proof::<E>::deserialize(proof)?;
	verify_groth16(&vk, &public_inputs, &proof)
}

pub fn verify_unchecked<E: PairingEngine>(
	public_inputs: &[E::Fr],
	vk_unchecked_bytes: &[u8],
	proof: &[u8],
) -> Result<bool, Error> {
	let vk = VerifyingKey::<E>::deserialize_unchecked(vk_unchecked_bytes)?;
	let proof = Proof::<E>::deserialize(proof)?;
	verify_groth16(&vk, &public_inputs, &proof)
}

pub fn verify_unchecked_raw<E: PairingEngine>(
	public_inputs: &[Vec<u8>],
	vk_unchecked_bytes: &[u8],
	proof: &[u8],
) -> Result<bool, Error> {
	let pub_ins: Vec<E::Fr> = public_inputs
		.iter()
		.map(|x| E::Fr::from_le_bytes_mod_order(&x))
		.collect();
	let vk = VerifyingKey::<E>::deserialize_unchecked(vk_unchecked_bytes)?;
	let proof = Proof::<E>::deserialize(proof)?;
	verify_groth16(&vk, &pub_ins, &proof)
}

pub fn verify_groth16<E: PairingEngine>(
	vk: &VerifyingKey<E>,
	public_inputs: &[E::Fr],
	proof: &Proof<E>,
) -> Result<bool, Error> {
	let res = Groth16::<E>::verify(vk, public_inputs, proof)?;
	Ok(res)
}