From 492019c63a03197221516aa796a70b5ab92e50a5 Mon Sep 17 00:00:00 2001 From: Weikeng Chen <w.k@berkeley.edu> Date: Mon, 8 Feb 2021 01:56:34 -0800 Subject: [PATCH] Add the non-constraint part of the Constraints PR (#71) --- Cargo.toml | 4 ++- src/constraints.rs | 2 +- src/data_structures.rs | 10 ++++++- src/kzg10/data_structures.rs | 28 ++++++++++++++++- src/marlin/marlin_pc/data_structures.rs | 40 ++++++++++++++++++++++++- 5 files changed, 79 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4528fc4..75f8be2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,8 @@ digest = "0.9" rayon = { version = "1", optional = true } derivative = { version = "2", features = [ "use_core" ] } +tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } + [dev-dependencies] rand = { version = "0.7", default-features = false } ark-ed-on-bls12-381 = { git = "https://github.com/arkworks-rs/curves", default-features = false } @@ -60,7 +62,7 @@ debug = true [features] default = [ "std", "parallel" ] -std = [ "ark-ff/std", "ark-ec/std", "ark-poly/std", "ark-std/std", "ark-serialize/std" ] +std = [ "ark-ff/std", "ark-ec/std", "ark-nonnative-field/std", "ark-poly/std", "ark-std/std", "ark-relations/std", "ark-serialize/std" ] r1cs = [ "ark-relations", "ark-r1cs-std", "ark-nonnative-field", "hashbrown" ] print-trace = [ "bench-utils/print-trace" ] parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon" ] diff --git a/src/constraints.rs b/src/constraints.rs index 57f74d1..41fe358 100644 --- a/src/constraints.rs +++ b/src/constraints.rs @@ -73,7 +73,7 @@ impl<TargetField: PrimeField, BaseField: PrimeField> } } -#[derive(Clone)] +#[derive(Clone, Debug)] /// A collection of random data used in the polynomial commitment checking. pub struct PCCheckRandomDataVar<TargetField: PrimeField, BaseField: PrimeField> { /// Opening challenges. diff --git a/src/data_structures.rs b/src/data_structures.rs index 1485d59..f509819 100644 --- a/src/data_structures.rs +++ b/src/data_structures.rs @@ -1,5 +1,5 @@ use crate::{Polynomial, PolynomialCommitment, Rc, String, Vec}; -use ark_ff::Field; +use ark_ff::{Field, ToConstraintField}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}; use ark_std::{ borrow::Borrow, @@ -192,6 +192,14 @@ pub struct LabeledCommitment<C: PCCommitment> { degree_bound: Option<usize>, } +impl<F: Field, C: PCCommitment + ToConstraintField<F>> ToConstraintField<F> + for LabeledCommitment<C> +{ + fn to_field_elements(&self) -> Option<Vec<F>> { + self.commitment.to_field_elements() + } +} + impl<C: PCCommitment> LabeledCommitment<C> { /// Instantiate a new polynomial_context. pub fn new(label: PolynomialLabel, commitment: C, degree_bound: Option<usize>) -> Self { diff --git a/src/kzg10/data_structures.rs b/src/kzg10/data_structures.rs index ebc3e34..4bb9543 100644 --- a/src/kzg10/data_structures.rs +++ b/src/kzg10/data_structures.rs @@ -1,6 +1,6 @@ use crate::*; use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; -use ark_ff::{PrimeField, ToBytes, Zero}; +use ark_ff::{PrimeField, ToBytes, ToConstraintField, Zero}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}; use ark_std::{ borrow::Cow, @@ -297,6 +297,23 @@ impl<E: PairingEngine> ToBytes for VerifierKey<E> { } } +impl<E: PairingEngine> ToConstraintField<<E::Fq as Field>::BasePrimeField> for VerifierKey<E> +where + E::G1Affine: ToConstraintField<<E::Fq as Field>::BasePrimeField>, + E::G2Affine: ToConstraintField<<E::Fq as Field>::BasePrimeField>, +{ + fn to_field_elements(&self) -> Option<Vec<<E::Fq as Field>::BasePrimeField>> { + let mut res = Vec::new(); + + res.extend_from_slice(&self.g.to_field_elements().unwrap()); + res.extend_from_slice(&self.gamma_g.to_field_elements().unwrap()); + res.extend_from_slice(&self.h.to_field_elements().unwrap()); + res.extend_from_slice(&self.beta_h.to_field_elements().unwrap()); + + Some(res) + } +} + /// `PreparedVerifierKey` is the fully prepared version for checking evaluation proofs for a given commitment. /// We omit gamma here for simplicity. #[derive(Derivative)] @@ -368,6 +385,15 @@ impl<E: PairingEngine> PCCommitment for Commitment<E> { } } +impl<E: PairingEngine> ToConstraintField<<E::Fq as Field>::BasePrimeField> for Commitment<E> +where + E::G1Affine: ToConstraintField<<E::Fq as Field>::BasePrimeField>, +{ + fn to_field_elements(&self) -> Option<Vec<<E::Fq as Field>::BasePrimeField>> { + self.0.to_field_elements() + } +} + impl<'a, E: PairingEngine> AddAssign<(E::Fr, &'a Commitment<E>)> for Commitment<E> { #[inline] fn add_assign(&mut self, (f, other): (E::Fr, &'a Commitment<E>)) { diff --git a/src/marlin/marlin_pc/data_structures.rs b/src/marlin/marlin_pc/data_structures.rs index bf6a578..b47a2d9 100644 --- a/src/marlin/marlin_pc/data_structures.rs +++ b/src/marlin/marlin_pc/data_structures.rs @@ -3,7 +3,7 @@ use crate::{ PCVerifierKey, UVPolynomial, Vec, }; use ark_ec::{PairingEngine, ProjectiveCurve}; -use ark_ff::{PrimeField, ToBytes}; +use ark_ff::{Field, PrimeField, ToBytes, ToConstraintField}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}; use ark_std::io::{Read, Write}; use ark_std::ops::{Add, AddAssign}; @@ -148,6 +148,28 @@ impl<E: PairingEngine> ToBytes for VerifierKey<E> { } } +impl<E: PairingEngine> ToConstraintField<<E::Fq as Field>::BasePrimeField> for VerifierKey<E> +where + E::G1Affine: ToConstraintField<<E::Fq as Field>::BasePrimeField>, + E::G2Affine: ToConstraintField<<E::Fq as Field>::BasePrimeField>, +{ + fn to_field_elements(&self) -> Option<Vec<<E::Fq as Field>::BasePrimeField>> { + let mut res = Vec::new(); + res.extend_from_slice(&self.vk.to_field_elements().unwrap()); + + if let Some(degree_bounds_and_shift_powers) = &self.degree_bounds_and_shift_powers { + for (d, shift_power) in degree_bounds_and_shift_powers.iter() { + let d_elem: <E::Fq as Field>::BasePrimeField = (*d as u64).into(); + + res.push(d_elem); + res.extend_from_slice(&shift_power.to_field_elements().unwrap()); + } + } + + Some(res) + } +} + /// `PreparedVerifierKey` is used to check evaluation proofs for a given commitment. #[derive(Derivative)] #[derivative(Clone(bound = ""), Debug(bound = ""))] @@ -240,6 +262,22 @@ impl<E: PairingEngine> ToBytes for Commitment<E> { } } +impl<E: PairingEngine> ToConstraintField<<E::Fq as Field>::BasePrimeField> for Commitment<E> +where + E::G1Affine: ToConstraintField<<E::Fq as Field>::BasePrimeField>, +{ + fn to_field_elements(&self) -> Option<Vec<<E::Fq as Field>::BasePrimeField>> { + let mut res = Vec::new(); + res.extend_from_slice(&self.comm.to_field_elements().unwrap()); + + if let Some(shifted_comm) = &self.shifted_comm { + res.extend_from_slice(&shifted_comm.to_field_elements().unwrap()); + } + + Some(res) + } +} + impl<E: PairingEngine> PCCommitment for Commitment<E> { #[inline] fn empty() -> Self { -- GitLab