Add `ToConstraintFieldGadget` (#278)
Weikeng Chen w.k@berkeley.edu
Mon, 14 Sep 2020 21:56:51 -0700
7 files changed,
115 insertions(+),
7 deletions(-)
M
r1cs-std/src/bits/boolean.rs
→
r1cs-std/src/bits/boolean.rs
@@ -1,6 +1,6 @@
-use algebra::{BitIteratorBE, Field}; +use algebra::{BitIteratorBE, Field, PrimeField}; -use crate::{prelude::*, Assignment, Vec}; +use crate::{fields::fp::FpVar, prelude::*, Assignment, ToConstraintFieldGadget, Vec}; use core::borrow::Borrow; use r1cs_core::{lc, ConstraintSystemRef, LinearCombination, Namespace, SynthesisError, Variable};@@ -594,6 +594,14 @@ bits.extend(vec![Boolean::constant(false); 7]);
let value = self.value().map(u8::from).ok(); let byte = UInt8 { bits, value }; Ok(vec![byte]) + } +} + +impl<F: PrimeField> ToConstraintFieldGadget<F> for Boolean<F> { + #[tracing::instrument(target = "r1cs")] + fn to_constraint_field(&self) -> Result<Vec<FpVar<F>>, SynthesisError> { + let var = From::from(self.clone()); + Ok(vec![var]) } }
M
r1cs-std/src/fields/cubic_extension.rs
→
r1cs-std/src/fields/cubic_extension.rs
@@ -5,10 +5,11 @@ };
use core::{borrow::Borrow, marker::PhantomData}; use r1cs_core::{ConstraintSystemRef, Namespace, SynthesisError}; +use crate::fields::fp::FpVar; use crate::{ fields::{FieldOpsBounds, FieldVar}, prelude::*, - Assignment, Vec, + Assignment, ToConstraintFieldGadget, Vec, }; #[derive(Derivative)]@@ -437,6 +438,25 @@ c0.append(&mut c1);
c0.append(&mut c2); Ok(c0) + } +} + +impl<BF, P> ToConstraintFieldGadget<P::BasePrimeField> for CubicExtVar<BF, P> +where + BF: FieldVar<P::BaseField, P::BasePrimeField>, + for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, + P: CubicExtVarParams<BF>, + BF: ToConstraintFieldGadget<P::BasePrimeField>, +{ + #[tracing::instrument(target = "r1cs")] + fn to_constraint_field(&self) -> Result<Vec<FpVar<P::BasePrimeField>>, SynthesisError> { + let mut res = Vec::new(); + + res.extend_from_slice(&self.c0.to_constraint_field()?); + res.extend_from_slice(&self.c1.to_constraint_field()?); + res.extend_from_slice(&self.c2.to_constraint_field()?); + + Ok(res) } }
M
r1cs-std/src/fields/fp/mod.rs
→
r1cs-std/src/fields/fp/mod.rs
@@ -4,7 +4,7 @@
use core::borrow::Borrow; use crate::fields::{FieldOpsBounds, FieldVar}; -use crate::{prelude::*, Assignment, Vec}; +use crate::{prelude::*, Assignment, ToConstraintFieldGadget, Vec}; pub mod cmp;@@ -432,6 +432,13 @@ Ok(bytes)
} } +impl<F: PrimeField> ToConstraintFieldGadget<F> for AllocatedFp<F> { + #[tracing::instrument(target = "r1cs")] + fn to_constraint_field(&self) -> Result<Vec<FpVar<F>>, SynthesisError> { + Ok(vec![self.clone().into()]) + } +} + impl<F: PrimeField> CondSelectGadget<F> for AllocatedFp<F> { #[inline] #[tracing::instrument(target = "r1cs")]@@ -842,6 +849,13 @@ match self {
Self::Constant(c) => Ok(UInt8::constant_vec(&to_bytes![c].unwrap())), Self::Var(v) => v.to_non_unique_bytes(), } + } +} + +impl<F: PrimeField> ToConstraintFieldGadget<F> for FpVar<F> { + #[tracing::instrument(target = "r1cs")] + fn to_constraint_field(&self) -> Result<Vec<FpVar<F>>, SynthesisError> { + Ok(vec![self.clone()]) } }
M
r1cs-std/src/fields/quadratic_extension.rs
→
r1cs-std/src/fields/quadratic_extension.rs
@@ -5,10 +5,11 @@ };
use core::{borrow::Borrow, marker::PhantomData}; use r1cs_core::{ConstraintSystemRef, Namespace, SynthesisError}; +use crate::fields::fp::FpVar; use crate::{ fields::{FieldOpsBounds, FieldVar}, prelude::*, - Assignment, Vec, + Assignment, ToConstraintFieldGadget, Vec, }; #[derive(Derivative)]@@ -427,6 +428,24 @@ let mut c0 = self.c0.to_non_unique_bytes()?;
let mut c1 = self.c1.to_non_unique_bytes()?; c0.append(&mut c1); Ok(c0) + } +} + +impl<BF, P> ToConstraintFieldGadget<P::BasePrimeField> for QuadExtVar<BF, P> +where + BF: FieldVar<P::BaseField, P::BasePrimeField>, + for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, + P: QuadExtVarParams<BF>, + BF: ToConstraintFieldGadget<P::BasePrimeField>, +{ + #[tracing::instrument(target = "r1cs")] + fn to_constraint_field(&self) -> Result<Vec<FpVar<P::BasePrimeField>>, SynthesisError> { + let mut res = Vec::new(); + + res.extend_from_slice(&self.c0.to_constraint_field()?); + res.extend_from_slice(&self.c1.to_constraint_field()?); + + Ok(res) } }
M
r1cs-std/src/groups/curves/short_weierstrass/mod.rs
→
r1cs-std/src/groups/curves/short_weierstrass/mod.rs
@@ -8,7 +8,8 @@ };
use core::{borrow::Borrow, marker::PhantomData}; use r1cs_core::{ConstraintSystemRef, Namespace, SynthesisError}; -use crate::{prelude::*, Vec}; +use crate::fields::fp::FpVar; +use crate::{prelude::*, ToConstraintFieldGadget, Vec}; pub mod bls12; pub mod mnt4;@@ -77,6 +78,25 @@ self.x.value()?,
self.y.value()?, self.infinity.value()?, )) + } +} + +impl<P, F> ToConstraintFieldGadget<<P::BaseField as Field>::BasePrimeField> for AffineVar<P, F> +where + P: SWModelParameters, + F: FieldVar<P::BaseField, <P::BaseField as Field>::BasePrimeField>, + for<'a> &'a F: FieldOpsBounds<'a, P::BaseField, F>, + F: ToConstraintFieldGadget<<P::BaseField as Field>::BasePrimeField>, +{ + fn to_constraint_field( + &self, + ) -> Result<Vec<FpVar<<P::BaseField as Field>::BasePrimeField>>, SynthesisError> { + let mut res = Vec::<FpVar<<P::BaseField as Field>::BasePrimeField>>::new(); + + res.extend_from_slice(&self.x.to_constraint_field()?); + res.extend_from_slice(&self.y.to_constraint_field()?); + + Ok(res) } }
M
r1cs-std/src/groups/curves/twisted_edwards/mod.rs
→
r1cs-std/src/groups/curves/twisted_edwards/mod.rs
@@ -8,8 +8,9 @@ };
use r1cs_core::{ConstraintSystemRef, Namespace, SynthesisError}; -use crate::{prelude::*, Vec}; +use crate::{prelude::*, ToConstraintFieldGadget, Vec}; +use crate::fields::fp::FpVar; use core::{borrow::Borrow, marker::PhantomData}; #[derive(Derivative)]@@ -643,6 +644,25 @@ f: impl FnOnce() -> Result<Point, SynthesisError>,
mode: AllocationMode, ) -> Result<Self, SynthesisError> { Self::new_variable(cs, || f().map(|b| b.borrow().into_projective()), mode) + } +} + +impl<P, F> ToConstraintFieldGadget<<P::BaseField as Field>::BasePrimeField> for AffineVar<P, F> +where + P: TEModelParameters, + F: FieldVar<P::BaseField, <P::BaseField as Field>::BasePrimeField>, + for<'a> &'a F: FieldOpsBounds<'a, P::BaseField, F>, + F: ToConstraintFieldGadget<<P::BaseField as Field>::BasePrimeField>, +{ + fn to_constraint_field( + &self, + ) -> Result<Vec<FpVar<<P::BaseField as Field>::BasePrimeField>>, SynthesisError> { + let mut res = Vec::new(); + + res.extend_from_slice(&self.x.to_constraint_field()?); + res.extend_from_slice(&self.y.to_constraint_field()?); + + Ok(res) } }
M
r1cs-std/src/lib.rs
→
r1cs-std/src/lib.rs
@@ -154,3 +154,10 @@ fn get(self) -> Result<T, r1cs_core::SynthesisError> {
self.ok_or(r1cs_core::SynthesisError::AssignmentMissing) } } + +/// Obtains the field variables +pub trait ToConstraintFieldGadget<ConstraintF: algebra::PrimeField> { + fn to_constraint_field( + &self, + ) -> Result<Vec<crate::fields::fp::FpVar<ConstraintF>>, r1cs_core::SynthesisError>; +}