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)
}