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