diff --git a/Cargo.toml b/Cargo.toml index be1ce71..68e22fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ ark-serialize = { version = "0.4.0", default-features = false, features = [ "der ark-poly = { version = "0.4.0", default-features = false } ark-std = { version = "0.4.0", default-features = false } ark-relations = { version = "0.4.0", default-features = false } -ark-crypto-primitives = { version = "0.4.0", default-features = false, features = ["snark"] } +ark-crypto-primitives = { version = "0.4.0", default-features = false, features = ["snark", "sponge"] } ark-r1cs-std = { version = "0.4.0", default-features = false, optional = true } tracing = { version = "0.1", default-features = false, features = [ "attributes" ], optional = true } diff --git a/src/constraints.rs b/src/constraints.rs index ec3502b..d734bfe 100644 --- a/src/constraints.rs +++ b/src/constraints.rs @@ -2,16 +2,22 @@ use crate::{ r1cs_to_qap::{LibsnarkReduction, R1CSToQAP}, Groth16, PreparedVerifyingKey, Proof, VerifyingKey, }; -use ark_crypto_primitives::snark::constraints::{CircuitSpecificSetupSNARKGadget, SNARKGadget}; -use ark_crypto_primitives::snark::{BooleanInputVar, SNARK}; +use ark_crypto_primitives::{ + snark::{ + constraints::{CircuitSpecificSetupSNARKGadget, SNARKGadget}, + BooleanInputVar, SNARK, + }, + sponge::constraints::AbsorbGadget, +}; use ark_ec::{pairing::Pairing, AffineRepr}; use ark_ff::Field; -use ark_r1cs_std::groups::CurveVar; use ark_r1cs_std::{ alloc::{AllocVar, AllocationMode}, boolean::Boolean, convert::{ToBitsGadget, ToBytesGadget}, eq::EqGadget, + fields::fp::FpVar, + groups::CurveVar, pairing::PairingVar, uint8::UInt8, }; @@ -69,7 +75,42 @@ impl> VerifyingKeyVar { } } -/// Preprocessed verification key parameters variable for the Groth16 construction +impl AbsorbGadget for VerifyingKeyVar +where + E: Pairing, + P: PairingVar, + P::G1Var: AbsorbGadget, + P::G2Var: AbsorbGadget, +{ + fn to_sponge_bytes(&self) -> Result::BaseField>>, SynthesisError> { + let mut bytes = self.alpha_g1.to_sponge_bytes()?; + bytes.extend(self.beta_g2.to_sponge_bytes()?); + bytes.extend(self.gamma_g2.to_sponge_bytes()?); + bytes.extend(self.delta_g2.to_sponge_bytes()?); + self.gamma_abc_g1.iter().try_for_each(|g| { + bytes.extend(g.to_sponge_bytes()?); + Ok(()) + })?; + Ok(bytes) + } + + fn to_sponge_field_elements( + &self, + ) -> Result::BaseField>>, SynthesisError> { + let mut field_elements = self.alpha_g1.to_sponge_field_elements()?; + field_elements.extend(self.beta_g2.to_sponge_field_elements()?); + field_elements.extend(self.gamma_g2.to_sponge_field_elements()?); + field_elements.extend(self.delta_g2.to_sponge_field_elements()?); + self.gamma_abc_g1.iter().try_for_each(|g| { + field_elements.extend(g.to_sponge_field_elements()?); + Ok(()) + })?; + Ok(field_elements) + } +} + +/// Preprocessed verification key parameters variable for the Groth16 +/// construction #[derive(Derivative)] #[derivative( Clone(bound = "P::G1Var: Clone, P::GTVar: Clone, P::G1PreparedVar: Clone, \ @@ -411,22 +452,20 @@ where #[cfg(test)] mod test { use crate::{constraints::Groth16VerifierGadget, Groth16}; - use ark_crypto_primitives::snark::constraints::SNARKGadget; - use ark_crypto_primitives::snark::SNARK; + use ark_crypto_primitives::snark::{constraints::SNARKGadget, SNARK}; use ark_ec::pairing::Pairing; use ark_ff::{Field, UniformRand}; use ark_mnt4_298::{constraints::PairingVar as MNT4PairingVar, Fr as MNT4Fr, MNT4_298 as MNT4}; use ark_mnt6_298::Fr as MNT6Fr; - use ark_r1cs_std::boolean::Boolean; - use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget}; + use ark_r1cs_std::{alloc::AllocVar, boolean::Boolean, eq::EqGadget}; use ark_relations::{ lc, ns, r1cs::{ConstraintSynthesizer, ConstraintSystem, ConstraintSystemRef, SynthesisError}, }; - use ark_std::test_rng; use ark_std::{ ops::MulAssign, rand::{RngCore, SeedableRng}, + test_rng, }; #[derive(Copy, Clone)] diff --git a/src/data_structures.rs b/src/data_structures.rs index 637fe78..457f581 100644 --- a/src/data_structures.rs +++ b/src/data_structures.rs @@ -1,4 +1,6 @@ +use ark_crypto_primitives::sponge::Absorb; use ark_ec::pairing::Pairing; +use ark_ff::PrimeField; use ark_serialize::*; use ark_std::vec::Vec; @@ -23,7 +25,6 @@ impl Default for Proof { } } -//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// A verification key in the Groth16 SNARK. @@ -37,7 +38,8 @@ pub struct VerifyingKey { pub gamma_g2: E::G2Affine, /// The `delta * H`, where `H` is the generator of `E::G2`. pub delta_g2: E::G2Affine, - /// The `gamma^{-1} * (beta * a_i + alpha * b_i + c_i) * H`, where `H` is the generator of `E::G1`. + /// The `gamma^{-1} * (beta * a_i + alpha * b_i + c_i) * H`, where `H` is + /// the generator of `E::G1`. pub gamma_abc_g1: Vec, } @@ -53,6 +55,33 @@ impl Default for VerifyingKey { } } +impl Absorb for VerifyingKey +where + E: Pairing, + E::G1Affine: Absorb, + E::G2Affine: Absorb, +{ + fn to_sponge_bytes(&self, dest: &mut Vec) { + self.alpha_g1.to_sponge_bytes(dest); + self.beta_g2.to_sponge_bytes(dest); + self.gamma_g2.to_sponge_bytes(dest); + self.delta_g2.to_sponge_bytes(dest); + self.gamma_abc_g1 + .iter() + .for_each(|g| g.to_sponge_bytes(dest)); + } + + fn to_sponge_field_elements(&self, dest: &mut Vec) { + self.alpha_g1.to_sponge_field_elements(dest); + self.beta_g2.to_sponge_field_elements(dest); + self.gamma_g2.to_sponge_field_elements(dest); + self.delta_g2.to_sponge_field_elements(dest); + self.gamma_abc_g1 + .iter() + .for_each(|g| g.to_sponge_field_elements(dest)); + } +} + /// Preprocessed verification key parameters that enable faster verification /// at the expense of larger size in memory. #[derive(Clone, Debug, PartialEq, CanonicalSerialize, CanonicalDeserialize)] @@ -90,7 +119,6 @@ impl Default for PreparedVerifyingKey { } } -//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// The prover key for for the Groth16 zkSNARK.