From b85002ff129fded95749453dfd9f0d40bbcf852b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=99=EC=9A=B1?= <69969001+dongwook1214@users.noreply.github.com> Date: Wed, 1 Oct 2025 17:17:14 +0900 Subject: [PATCH 1/5] Add xy, x, y functions to CurveVar --- src/groups/curves/short_weierstrass/mod.rs | 7 ++++++- src/groups/curves/twisted_edwards/mod.rs | 6 +++++- src/groups/mod.rs | 15 ++++++++++++++- src/pairing/bls12/mod.rs | 5 ++++- src/pairing/mnt4/mod.rs | 4 +++- src/pairing/mnt6/mod.rs | 4 +++- src/pairing/mod.rs | 11 ++++++++--- 7 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/groups/curves/short_weierstrass/mod.rs b/src/groups/curves/short_weierstrass/mod.rs index fbfa8e3..442f756 100644 --- a/src/groups/curves/short_weierstrass/mod.rs +++ b/src/groups/curves/short_weierstrass/mod.rs @@ -371,7 +371,7 @@ where } } -impl CurveVar, BasePrimeField

> for ProjectiveVar +impl CurveVar, BasePrimeField

, F> for ProjectiveVar where P: SWCurveConfig, F: FieldVar>, @@ -573,6 +573,11 @@ where *self += Self::constant(base).scalar_mul_le(bits.iter())?; Ok(()) } + + fn xy(&self) -> Result<(F, F), SynthesisError> { + let self_affine = self.to_affine()?; + Ok((self_affine.x, self_affine.y)) + } } impl ToConstraintFieldGadget> for ProjectiveVar diff --git a/src/groups/curves/twisted_edwards/mod.rs b/src/groups/curves/twisted_edwards/mod.rs index 83c50a0..ee82ccc 100644 --- a/src/groups/curves/twisted_edwards/mod.rs +++ b/src/groups/curves/twisted_edwards/mod.rs @@ -395,7 +395,7 @@ where } } -impl CurveVar, BasePrimeField

> for AffineVar +impl CurveVar, BasePrimeField

, F> for AffineVar where P: TECurveConfig, F: FieldVar> @@ -547,6 +547,10 @@ where Ok(()) } + + fn xy(&self) -> Result<(F, F), SynthesisError> { + Ok((self.x.clone(), self.y.clone())) + } } impl AllocVar, BasePrimeField

> for AffineVar diff --git a/src/groups/mod.rs b/src/groups/mod.rs index 85cdeea..7d8330f 100644 --- a/src/groups/mod.rs +++ b/src/groups/mod.rs @@ -29,7 +29,7 @@ pub trait GroupOpsBounds<'a, G, T: 'a>: /// A variable that represents a curve point for /// the curve `C`. -pub trait CurveVar: +pub trait CurveVar>: 'static + Sized + Clone @@ -68,6 +68,19 @@ pub trait CurveVar: /// This *should not* allocate any variables. fn constant(other: C) -> Self; + /// Returns the x and y coordinates of this affine point. + fn xy(&self) -> Result<(F, F), SynthesisError>; + + /// Returns the x coordinate of this affine point. + fn x(&self) -> Result { + self.xy().map(|(x, _)| x) + } + + /// Returns the y coordinate of this affine point. + fn y(&self) -> Result { + self.xy().map(|(_, y)| y) + } + /// Allocates a variable in the subgroup without checking if it's in the /// prime-order subgroup. fn new_variable_omit_prime_order_check( diff --git a/src/pairing/bls12/mod.rs b/src/pairing/bls12/mod.rs index 8a9c432..1c58010 100644 --- a/src/pairing/bls12/mod.rs +++ b/src/pairing/bls12/mod.rs @@ -59,7 +59,10 @@ impl PairingVar

{ } } -impl PG> for PairingVar

{ +impl + PG, FpVar<

::Fp>, Fp2Var<

::Fp2Config>> + for PairingVar

+{ type G1Var = G1Var

; type G2Var = G2Var

; type G1PreparedVar = G1PreparedVar

; diff --git a/src/pairing/mnt4/mod.rs b/src/pairing/mnt4/mod.rs index 7eceefe..bca3704 100644 --- a/src/pairing/mnt4/mod.rs +++ b/src/pairing/mnt4/mod.rs @@ -196,7 +196,9 @@ impl PairingVar

{ } } -impl PG> for PairingVar

{ +impl PG, FpVar<

::Fp>, Fp2Var<

::Fp2Config>> + for PairingVar

+{ type G1Var = G1Var

; type G2Var = G2Var

; type G1PreparedVar = G1PreparedVar

; diff --git a/src/pairing/mnt6/mod.rs b/src/pairing/mnt6/mod.rs index 3af1240..4c4c978 100644 --- a/src/pairing/mnt6/mod.rs +++ b/src/pairing/mnt6/mod.rs @@ -191,7 +191,9 @@ impl PairingVar

{ } } -impl PG> for PairingVar

{ +impl PG, FpVar<

::Fp>, Fp3Var<

::Fp3Config>> + for PairingVar

+{ type G1Var = G1Var

; type G2Var = G2Var

; type G1PreparedVar = G1PreparedVar

; diff --git a/src/pairing/mod.rs b/src/pairing/mod.rs index 292e9c5..9349df6 100644 --- a/src/pairing/mod.rs +++ b/src/pairing/mod.rs @@ -14,14 +14,19 @@ type BasePrimeField = <::BaseField as ark_ff::Field>::BasePrime /// Specifies the constraints for computing a pairing in the yybilinear group /// `E`. -pub trait PairingVar { +pub trait PairingVar< + E: Pairing, + F1: FieldVar<::BaseField, E::BaseField>, + F2: FieldVar<::BaseField, E::BaseField>, +> +{ /// An variable representing an element of `G1`. /// This is the R1CS equivalent of `E::G1Projective`. - type G1Var: CurveVar>; + type G1Var: CurveVar, F1>; /// An variable representing an element of `G2`. /// This is the R1CS equivalent of `E::G2Projective`. - type G2Var: CurveVar>; + type G2Var: CurveVar, F2>; /// An variable representing an element of `GT`. /// This is the R1CS equivalent of `E::GT`. From f3c20b7e3117124ba8a099411110d737542bf61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=99=EC=9A=B1?= <69969001+dongwook1214@users.noreply.github.com> Date: Wed, 1 Oct 2025 19:04:09 +0900 Subject: [PATCH 2/5] Refactor --- src/groups/curves/short_weierstrass/mod.rs | 2 +- src/groups/curves/twisted_edwards/mod.rs | 2 +- src/groups/mod.rs | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/groups/curves/short_weierstrass/mod.rs b/src/groups/curves/short_weierstrass/mod.rs index 442f756..57a2aba 100644 --- a/src/groups/curves/short_weierstrass/mod.rs +++ b/src/groups/curves/short_weierstrass/mod.rs @@ -574,7 +574,7 @@ where Ok(()) } - fn xy(&self) -> Result<(F, F), SynthesisError> { + fn affine_xy(&self) -> Result<(F, F), SynthesisError> { let self_affine = self.to_affine()?; Ok((self_affine.x, self_affine.y)) } diff --git a/src/groups/curves/twisted_edwards/mod.rs b/src/groups/curves/twisted_edwards/mod.rs index ee82ccc..87e6c6f 100644 --- a/src/groups/curves/twisted_edwards/mod.rs +++ b/src/groups/curves/twisted_edwards/mod.rs @@ -548,7 +548,7 @@ where Ok(()) } - fn xy(&self) -> Result<(F, F), SynthesisError> { + fn affine_xy(&self) -> Result<(F, F), SynthesisError> { Ok((self.x.clone(), self.y.clone())) } } diff --git a/src/groups/mod.rs b/src/groups/mod.rs index 7d8330f..6986112 100644 --- a/src/groups/mod.rs +++ b/src/groups/mod.rs @@ -68,17 +68,17 @@ pub trait CurveVar Self; - /// Returns the x and y coordinates of this affine point. - fn xy(&self) -> Result<(F, F), SynthesisError>; + /// Returns the x and y coordinates in Affine representation. + fn affine_xy(&self) -> Result<(F, F), SynthesisError>; - /// Returns the x coordinate of this affine point. - fn x(&self) -> Result { - self.xy().map(|(x, _)| x) + /// Returns the x coordinate in Affine representation. + fn affine_x(&self) -> Result { + self.affine_xy().map(|(x, _)| x) } - /// Returns the y coordinate of this affine point. - fn y(&self) -> Result { - self.xy().map(|(_, y)| y) + /// Returns the y coordinate in Affine representation. + fn affine_y(&self) -> Result { + self.affine_xy().map(|(_, y)| y) } /// Allocates a variable in the subgroup without checking if it's in the From 2ee18631e84b56dbd3eae45b506fa733582f9a71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=99=EC=9A=B1?= <69969001+dongwook1214@users.noreply.github.com> Date: Wed, 1 Oct 2025 19:10:06 +0900 Subject: [PATCH 3/5] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c067f3..e58ad59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ - Add `UInt::{from_bytes_le, from_bytes_be, to_bytes_be}`. - [\#143](https://github.com/arkworks-rs/r1cs-std/pull/143) Add `AllocVar::new_variable_with_inferred_mode`. - [\#144](https://github.com/arkworks-rs/r1cs-std/pull/144) Add `ToConstraintFieldGadget` bounds to `CurveVar` and `FieldVar` +- [\#190](https://github.com/arkworks-rs/r1cs-std/pull/190) Add `affine_xy, affine_x, affine_y` functions to `CurveVar` ### Improvements From cf8d497f8ca5258895f510b473ab5fb8bcc2ac17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=99=EC=9A=B1?= <69969001+dongwook1214@users.noreply.github.com> Date: Thu, 2 Oct 2025 23:21:25 +0900 Subject: [PATCH 4/5] Refactor --- src/groups/curves/short_weierstrass/mod.rs | 4 +++- src/groups/curves/twisted_edwards/mod.rs | 4 +++- src/groups/mod.rs | 10 ++++++---- src/pairing/bls12/mod.rs | 5 +---- src/pairing/mnt4/mod.rs | 4 +--- src/pairing/mnt6/mod.rs | 4 +--- src/pairing/mod.rs | 11 +++-------- 7 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/groups/curves/short_weierstrass/mod.rs b/src/groups/curves/short_weierstrass/mod.rs index 57a2aba..87f49b5 100644 --- a/src/groups/curves/short_weierstrass/mod.rs +++ b/src/groups/curves/short_weierstrass/mod.rs @@ -371,12 +371,14 @@ where } } -impl CurveVar, BasePrimeField

, F> for ProjectiveVar +impl CurveVar, BasePrimeField

> for ProjectiveVar where P: SWCurveConfig, F: FieldVar>, for<'a> &'a F: FieldOpsBounds<'a, P::BaseField, F>, { + type F = F; + fn constant(g: SWProjective

) -> Self { let cs = ConstraintSystemRef::None; Self::new_variable_omit_on_curve_check(cs, || Ok(g), AllocationMode::Constant).unwrap() diff --git a/src/groups/curves/twisted_edwards/mod.rs b/src/groups/curves/twisted_edwards/mod.rs index 87e6c6f..fde57a8 100644 --- a/src/groups/curves/twisted_edwards/mod.rs +++ b/src/groups/curves/twisted_edwards/mod.rs @@ -395,13 +395,15 @@ where } } -impl CurveVar, BasePrimeField

, F> for AffineVar +impl CurveVar, BasePrimeField

> for AffineVar where P: TECurveConfig, F: FieldVar> + TwoBitLookupGadget, TableConstant = P::BaseField>, for<'a> &'a F: FieldOpsBounds<'a, P::BaseField, F>, { + type F = F; + fn constant(g: TEProjective

) -> Self { let cs = ConstraintSystemRef::None; Self::new_variable_omit_on_curve_check(cs, || Ok(g), AllocationMode::Constant).unwrap() diff --git a/src/groups/mod.rs b/src/groups/mod.rs index 6986112..d715f11 100644 --- a/src/groups/mod.rs +++ b/src/groups/mod.rs @@ -29,7 +29,7 @@ pub trait GroupOpsBounds<'a, G, T: 'a>: /// A variable that represents a curve point for /// the curve `C`. -pub trait CurveVar>: +pub trait CurveVar: 'static + Sized + Clone @@ -53,6 +53,8 @@ pub trait CurveVar Mul<&'a EmulatedFpVar, Output = Self> + MulAssign> { + type F: FieldVar; + /// Returns the constant `F::zero()`. This is the identity /// of the group. fn zero() -> Self; @@ -69,15 +71,15 @@ pub trait CurveVar Self; /// Returns the x and y coordinates in Affine representation. - fn affine_xy(&self) -> Result<(F, F), SynthesisError>; + fn affine_xy(&self) -> Result<(Self::F, Self::F), SynthesisError>; /// Returns the x coordinate in Affine representation. - fn affine_x(&self) -> Result { + fn affine_x(&self) -> Result { self.affine_xy().map(|(x, _)| x) } /// Returns the y coordinate in Affine representation. - fn affine_y(&self) -> Result { + fn affine_y(&self) -> Result { self.affine_xy().map(|(_, y)| y) } diff --git a/src/pairing/bls12/mod.rs b/src/pairing/bls12/mod.rs index 1c58010..8a9c432 100644 --- a/src/pairing/bls12/mod.rs +++ b/src/pairing/bls12/mod.rs @@ -59,10 +59,7 @@ impl PairingVar

{ } } -impl - PG, FpVar<

::Fp>, Fp2Var<

::Fp2Config>> - for PairingVar

-{ +impl PG> for PairingVar

{ type G1Var = G1Var

; type G2Var = G2Var

; type G1PreparedVar = G1PreparedVar

; diff --git a/src/pairing/mnt4/mod.rs b/src/pairing/mnt4/mod.rs index bca3704..7eceefe 100644 --- a/src/pairing/mnt4/mod.rs +++ b/src/pairing/mnt4/mod.rs @@ -196,9 +196,7 @@ impl PairingVar

{ } } -impl PG, FpVar<

::Fp>, Fp2Var<

::Fp2Config>> - for PairingVar

-{ +impl PG> for PairingVar

{ type G1Var = G1Var

; type G2Var = G2Var

; type G1PreparedVar = G1PreparedVar

; diff --git a/src/pairing/mnt6/mod.rs b/src/pairing/mnt6/mod.rs index 4c4c978..3af1240 100644 --- a/src/pairing/mnt6/mod.rs +++ b/src/pairing/mnt6/mod.rs @@ -191,9 +191,7 @@ impl PairingVar

{ } } -impl PG, FpVar<

::Fp>, Fp3Var<

::Fp3Config>> - for PairingVar

-{ +impl PG> for PairingVar

{ type G1Var = G1Var

; type G2Var = G2Var

; type G1PreparedVar = G1PreparedVar

; diff --git a/src/pairing/mod.rs b/src/pairing/mod.rs index 9349df6..292e9c5 100644 --- a/src/pairing/mod.rs +++ b/src/pairing/mod.rs @@ -14,19 +14,14 @@ type BasePrimeField = <::BaseField as ark_ff::Field>::BasePrime /// Specifies the constraints for computing a pairing in the yybilinear group /// `E`. -pub trait PairingVar< - E: Pairing, - F1: FieldVar<::BaseField, E::BaseField>, - F2: FieldVar<::BaseField, E::BaseField>, -> -{ +pub trait PairingVar { /// An variable representing an element of `G1`. /// This is the R1CS equivalent of `E::G1Projective`. - type G1Var: CurveVar, F1>; + type G1Var: CurveVar>; /// An variable representing an element of `G2`. /// This is the R1CS equivalent of `E::G2Projective`. - type G2Var: CurveVar, F2>; + type G2Var: CurveVar>; /// An variable representing an element of `GT`. /// This is the R1CS equivalent of `E::GT`. From 17e9166c115b2ad7917df34b49ab3f25b76c7829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=99=EC=9A=B1?= <69969001+dongwook1214@users.noreply.github.com> Date: Fri, 3 Oct 2025 09:09:11 +0900 Subject: [PATCH 5/5] Refactor --- src/groups/curves/short_weierstrass/mod.rs | 2 +- src/groups/curves/twisted_edwards/mod.rs | 2 +- src/groups/mod.rs | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/groups/curves/short_weierstrass/mod.rs b/src/groups/curves/short_weierstrass/mod.rs index 87f49b5..5fea123 100644 --- a/src/groups/curves/short_weierstrass/mod.rs +++ b/src/groups/curves/short_weierstrass/mod.rs @@ -377,7 +377,7 @@ where F: FieldVar>, for<'a> &'a F: FieldOpsBounds<'a, P::BaseField, F>, { - type F = F; + type BaseFieldVar = F; fn constant(g: SWProjective

) -> Self { let cs = ConstraintSystemRef::None; diff --git a/src/groups/curves/twisted_edwards/mod.rs b/src/groups/curves/twisted_edwards/mod.rs index fde57a8..7d8a957 100644 --- a/src/groups/curves/twisted_edwards/mod.rs +++ b/src/groups/curves/twisted_edwards/mod.rs @@ -402,7 +402,7 @@ where + TwoBitLookupGadget, TableConstant = P::BaseField>, for<'a> &'a F: FieldOpsBounds<'a, P::BaseField, F>, { - type F = F; + type BaseFieldVar = F; fn constant(g: TEProjective

) -> Self { let cs = ConstraintSystemRef::None; diff --git a/src/groups/mod.rs b/src/groups/mod.rs index d715f11..19193ae 100644 --- a/src/groups/mod.rs +++ b/src/groups/mod.rs @@ -53,7 +53,7 @@ pub trait CurveVar: + for<'a> Mul<&'a EmulatedFpVar, Output = Self> + MulAssign> { - type F: FieldVar; + type BaseFieldVar: FieldVar; /// Returns the constant `F::zero()`. This is the identity /// of the group. @@ -71,15 +71,15 @@ pub trait CurveVar: fn constant(other: C) -> Self; /// Returns the x and y coordinates in Affine representation. - fn affine_xy(&self) -> Result<(Self::F, Self::F), SynthesisError>; + fn affine_xy(&self) -> Result<(Self::BaseFieldVar, Self::BaseFieldVar), SynthesisError>; /// Returns the x coordinate in Affine representation. - fn affine_x(&self) -> Result { + fn affine_x(&self) -> Result { self.affine_xy().map(|(x, _)| x) } /// Returns the y coordinate in Affine representation. - fn affine_y(&self) -> Result { + fn affine_y(&self) -> Result { self.affine_xy().map(|(_, y)| y) }