diff --git a/r1cs-std/src/bits/boolean.rs b/r1cs-std/src/bits/boolean.rs index 46ec3b0..df0e88b 100644 --- a/r1cs-std/src/bits/boolean.rs +++ b/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}; @@ -597,6 +597,14 @@ impl ToBytesGadget for Boolean { } } +impl ToConstraintFieldGadget for Boolean { + #[tracing::instrument(target = "r1cs")] + fn to_constraint_field(&self) -> Result>, SynthesisError> { + let var = From::from(self.clone()); + Ok(vec![var]) + } +} + impl CondSelectGadget for Boolean { #[tracing::instrument(target = "r1cs")] fn conditionally_select( diff --git a/r1cs-std/src/fields/cubic_extension.rs b/r1cs-std/src/fields/cubic_extension.rs index d2ceb87..a3edb4f 100644 --- a/r1cs-std/src/fields/cubic_extension.rs +++ b/r1cs-std/src/fields/cubic_extension.rs @@ -5,10 +5,11 @@ use algebra::{ 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)] @@ -440,6 +441,25 @@ where } } +impl ToConstraintFieldGadget for CubicExtVar +where + BF: FieldVar, + for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, + P: CubicExtVarParams, + BF: ToConstraintFieldGadget, +{ + #[tracing::instrument(target = "r1cs")] + fn to_constraint_field(&self) -> Result>, 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) + } +} + impl CondSelectGadget for CubicExtVar where BF: FieldVar, diff --git a/r1cs-std/src/fields/fp/mod.rs b/r1cs-std/src/fields/fp/mod.rs index 356d499..f11177c 100644 --- a/r1cs-std/src/fields/fp/mod.rs +++ b/r1cs-std/src/fields/fp/mod.rs @@ -4,7 +4,7 @@ use r1cs_core::{lc, ConstraintSystemRef, LinearCombination, Namespace, Synthesis 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 @@ impl ToBytesGadget for AllocatedFp { } } +impl ToConstraintFieldGadget for AllocatedFp { + #[tracing::instrument(target = "r1cs")] + fn to_constraint_field(&self) -> Result>, SynthesisError> { + Ok(vec![self.clone().into()]) + } +} + impl CondSelectGadget for AllocatedFp { #[inline] #[tracing::instrument(target = "r1cs")] @@ -845,6 +852,13 @@ impl ToBytesGadget for FpVar { } } +impl ToConstraintFieldGadget for FpVar { + #[tracing::instrument(target = "r1cs")] + fn to_constraint_field(&self) -> Result>, SynthesisError> { + Ok(vec![self.clone()]) + } +} + impl CondSelectGadget for FpVar { #[tracing::instrument(target = "r1cs")] fn conditionally_select( diff --git a/r1cs-std/src/fields/quadratic_extension.rs b/r1cs-std/src/fields/quadratic_extension.rs index f37802b..de87f74 100644 --- a/r1cs-std/src/fields/quadratic_extension.rs +++ b/r1cs-std/src/fields/quadratic_extension.rs @@ -5,10 +5,11 @@ use algebra::{ 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)] @@ -430,6 +431,24 @@ where } } +impl ToConstraintFieldGadget for QuadExtVar +where + BF: FieldVar, + for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, + P: QuadExtVarParams, + BF: ToConstraintFieldGadget, +{ + #[tracing::instrument(target = "r1cs")] + fn to_constraint_field(&self) -> Result>, 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) + } +} + impl CondSelectGadget for QuadExtVar where BF: FieldVar, diff --git a/r1cs-std/src/groups/curves/short_weierstrass/mod.rs b/r1cs-std/src/groups/curves/short_weierstrass/mod.rs index 70be540..73ad21d 100644 --- a/r1cs-std/src/groups/curves/short_weierstrass/mod.rs +++ b/r1cs-std/src/groups/curves/short_weierstrass/mod.rs @@ -8,7 +8,8 @@ use algebra::{ 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; @@ -80,6 +81,25 @@ where } } +impl ToConstraintFieldGadget<::BasePrimeField> for AffineVar +where + P: SWModelParameters, + F: FieldVar::BasePrimeField>, + for<'a> &'a F: FieldOpsBounds<'a, P::BaseField, F>, + F: ToConstraintFieldGadget<::BasePrimeField>, +{ + fn to_constraint_field( + &self, + ) -> Result::BasePrimeField>>, SynthesisError> { + let mut res = Vec::::BasePrimeField>>::new(); + + res.extend_from_slice(&self.x.to_constraint_field()?); + res.extend_from_slice(&self.y.to_constraint_field()?); + + Ok(res) + } +} + impl R1CSVar<::BasePrimeField> for ProjectiveVar where P: SWModelParameters, diff --git a/r1cs-std/src/groups/curves/twisted_edwards/mod.rs b/r1cs-std/src/groups/curves/twisted_edwards/mod.rs index 30a1b38..e77f3c0 100644 --- a/r1cs-std/src/groups/curves/twisted_edwards/mod.rs +++ b/r1cs-std/src/groups/curves/twisted_edwards/mod.rs @@ -8,8 +8,9 @@ use algebra::{ 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)] @@ -646,6 +647,25 @@ where } } +impl ToConstraintFieldGadget<::BasePrimeField> for AffineVar +where + P: TEModelParameters, + F: FieldVar::BasePrimeField>, + for<'a> &'a F: FieldOpsBounds<'a, P::BaseField, F>, + F: ToConstraintFieldGadget<::BasePrimeField>, +{ + fn to_constraint_field( + &self, + ) -> Result::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) + } +} + #[inline] fn div2(limbs: &mut [u64]) { let mut t = 0; diff --git a/r1cs-std/src/lib.rs b/r1cs-std/src/lib.rs index 1d4166d..ce2b89e 100644 --- a/r1cs-std/src/lib.rs +++ b/r1cs-std/src/lib.rs @@ -154,3 +154,10 @@ impl Assignment for Option { self.ok_or(r1cs_core::SynthesisError::AssignmentMissing) } } + +/// Obtains the field variables +pub trait ToConstraintFieldGadget { + fn to_constraint_field( + &self, + ) -> Result>, r1cs_core::SynthesisError>; +}