Skip to content

Commit db7879d

Browse files
committed
refactor: implement our own TE config
Previously defining the cofactor was done on `AffineCurve`: this let us set it to 1 since decaf377 provides a prime-order group. However, the cofactor is now moved to the curve configuration via the trait `CurveConfig`. This means we can no longer use the upstream `ark_ed_on_bls12_377` curve configuration type: we need to define our own and implement the required traits, and then use that to define `EdwardsAffine`, `EdwardsProjective`, and `EdwardsVar` (R1CS) instead of the upstream provided definitions of those types.
1 parent d762be0 commit db7879d

File tree

12 files changed

+111
-47
lines changed

12 files changed

+111
-47
lines changed

src/constants.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ pub static B_T: Lazy<Fq> = Lazy::new(|| {
5454
});
5555
pub static B_Z: Lazy<Fq> = Lazy::new(|| ark_ff::MontFp!("1"));
5656

57+
// Canonical basepoint affine coordinates
58+
pub const GENERATOR_X: Fq =
59+
ark_ff::MontFp!("4959445789346820725352484487855828915252512307947624787834978378872129235627");
60+
pub const GENERATOR_Y: Fq =
61+
ark_ff::MontFp!("6060471950081851567114691557659790004756535011754163002297540472747064943288");
62+
5763
// Modulus of basefield
5864
pub static R: Lazy<Fr> = Lazy::new(|| {
5965
ark_ff::MontFp!("2111115437357092606062206234695386632838870926408408195193685246394721360383")

src/element.rs

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,75 @@
1-
use ark_ec::{AffineRepr, CurveGroup, Group, ScalarMul, VariableBaseMSM};
2-
use ark_ed_on_bls12_377::{EdwardsAffine, EdwardsConfig, EdwardsProjective};
1+
use ark_ec::{
2+
twisted_edwards::{Affine, MontCurveConfig, Projective, TECurveConfig},
3+
AffineRepr, CurveConfig, CurveGroup, Group, ScalarMul, VariableBaseMSM,
4+
};
5+
use ark_ed_on_bls12_377::EdwardsConfig;
6+
use ark_ff::MontFp;
37
use ark_serialize::Valid;
48

5-
use crate::{Fq, Fr};
9+
use crate::{
10+
constants::{GENERATOR_X, GENERATOR_Y},
11+
Fq, Fr,
12+
};
613

714
pub mod affine;
815
pub mod projective;
916

1017
pub use affine::AffineElement;
1118
pub use projective::Element;
1219

20+
#[derive(Clone, Default, PartialEq, Eq)]
21+
pub struct Decaf377EdwardsConfig;
22+
23+
// These types should not be exported. They are similar to `EdwardsAffine` and
24+
// `EdwardsProjective` from the `ark_ed_on_bls12_377` crate, except using our own
25+
// `Decaf377Config` that has the cofactor set to 1. Consumers of this
26+
// library should use the `AffineElement` and `Element` (projective)
27+
// types.
28+
pub(crate) type EdwardsAffine = Affine<Decaf377EdwardsConfig>;
29+
pub(crate) type EdwardsProjective = Projective<Decaf377EdwardsConfig>;
30+
31+
impl CurveConfig for Decaf377EdwardsConfig {
32+
type BaseField = Fq;
33+
type ScalarField = Fr;
34+
35+
const COFACTOR: &'static [u64] = &[1];
36+
37+
const COFACTOR_INV: Fr = MontFp!("1");
38+
}
39+
40+
impl TECurveConfig for Decaf377EdwardsConfig {
41+
/// COEFF_A = -1
42+
const COEFF_A: Fq = <EdwardsConfig as ark_ec::twisted_edwards::TECurveConfig>::COEFF_A;
43+
44+
/// COEFF_D = 3021
45+
const COEFF_D: Fq = <EdwardsConfig as ark_ec::twisted_edwards::TECurveConfig>::COEFF_D;
46+
47+
const GENERATOR: EdwardsAffine = EdwardsAffine::new_unchecked(GENERATOR_X, GENERATOR_Y);
48+
49+
type MontCurveConfig = EdwardsConfig;
50+
51+
/// Multiplication by `a` is just negation.
52+
#[inline(always)]
53+
fn mul_by_a(elem: Self::BaseField) -> Self::BaseField {
54+
-elem
55+
}
56+
57+
fn is_in_correct_subgroup_assuming_on_curve(_: &Affine<Self>) -> bool {
58+
true
59+
}
60+
}
61+
62+
impl MontCurveConfig for Decaf377EdwardsConfig {
63+
const COEFF_A: Fq = <EdwardsConfig as ark_ec::twisted_edwards::MontCurveConfig>::COEFF_A;
64+
65+
const COEFF_B: Fq = <EdwardsConfig as ark_ec::twisted_edwards::MontCurveConfig>::COEFF_B;
66+
67+
type TECurveConfig = Decaf377EdwardsConfig;
68+
}
69+
1370
impl Valid for Element {
1471
fn check(&self) -> Result<(), ark_serialize::SerializationError> {
15-
todo!()
72+
Ok(())
1673
}
1774
}
1875

@@ -84,7 +141,7 @@ impl CurveGroup for Element {
84141

85142
impl Valid for AffineElement {
86143
fn check(&self) -> Result<(), ark_serialize::SerializationError> {
87-
todo!()
144+
Ok(())
88145
}
89146
}
90147

src/element/affine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::hash::Hash;
22

3-
use ark_ed_on_bls12_377::EdwardsAffine;
3+
use crate::element::EdwardsAffine;
44
use ark_std::fmt::{Display, Formatter, Result as FmtResult};
55
use ark_std::Zero;
66

src/element/projective.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
use std::borrow::Borrow;
22
use std::hash::Hash;
33

4-
use ark_ed_on_bls12_377::EdwardsProjective;
54
use ark_ff::Zero;
65
use ark_std::fmt::{Display, Formatter, Result as FmtResult};
76

87
use zeroize::Zeroize;
98

10-
use crate::{Fq, Fr};
9+
use crate::{EdwardsProjective, Fq, Fr};
1110

1211
#[derive(Copy, Clone)]
1312
pub struct Element {

src/elligator.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#![allow(non_snake_case)]
22
use ark_ec::twisted_edwards::TECurveConfig;
3-
use ark_ed_on_bls12_377::{EdwardsConfig, EdwardsProjective};
43
use ark_ff::Field;
54

5+
use crate::element::{Decaf377EdwardsConfig, EdwardsProjective};
6+
67
use crate::{
78
constants::{ONE, TWO, ZETA},
89
Element, Fq, OnCurve, Sign, SqrtRatioZeta,
@@ -12,8 +13,8 @@ impl Element {
1213
/// Elligator 2 map to decaf377 point
1314
fn elligator_map(r_0: &Fq) -> Element {
1415
// Ref: `Decaf_1_1_Point.elligator` (optimized) in `ristretto.sage`
15-
let A = EdwardsConfig::COEFF_A;
16-
let D = EdwardsConfig::COEFF_D;
16+
let A = Decaf377EdwardsConfig::COEFF_A;
17+
let D = Decaf377EdwardsConfig::COEFF_D;
1718

1819
let r = *ZETA * r_0.square();
1920

@@ -44,8 +45,8 @@ impl Element {
4445

4546
// Convert point to extended projective (X : Y : Z : T)
4647
let E = *TWO * s;
47-
let F = *ONE + EdwardsConfig::COEFF_A * s.square();
48-
let G = *ONE - EdwardsConfig::COEFF_A * s.square();
48+
let F = *ONE + Decaf377EdwardsConfig::COEFF_A * s.square();
49+
let G = *ONE - Decaf377EdwardsConfig::COEFF_A * s.square();
4950
let H = t;
5051
let result = Element {
5152
inner: EdwardsProjective::new(E * H, F * G, E * G, F * H),
@@ -86,7 +87,7 @@ impl Element {
8687

8788
#[cfg(test)]
8889
mod tests {
89-
use ark_ed_on_bls12_377::EdwardsAffine;
90+
use crate::element::EdwardsAffine;
9091

9192
use super::*;
9293

src/encoding.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
use std::convert::{TryFrom, TryInto};
44

55
use ark_ec::twisted_edwards::TECurveConfig;
6-
use ark_ed_on_bls12_377::{EdwardsConfig, EdwardsProjective};
76
use ark_ff::{Field, One};
87
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
98

10-
use crate::{constants::TWO, Element, EncodingError, Fq, OnCurve, Sign, SqrtRatioZeta};
9+
use crate::{
10+
constants::TWO, element::Decaf377EdwardsConfig, EdwardsProjective, Element, EncodingError, Fq,
11+
OnCurve, Sign, SqrtRatioZeta,
12+
};
1113

1214
#[derive(Copy, Clone, Default, Eq, Ord, PartialOrd, PartialEq)]
1315
pub struct Encoding(pub [u8; 32]);
@@ -35,7 +37,7 @@ impl Encoding {
3537

3638
// This isn't a constant, only because traits don't have const methods
3739
// yet and multiplication is only implemented as part of the Mul trait.
38-
let D4: Fq = EdwardsConfig::COEFF_D * Fq::from(4u32);
40+
let D4: Fq = Decaf377EdwardsConfig::COEFF_D * Fq::from(4u32);
3941

4042
// 1/2. Reject unless s is canonically encoded and nonnegative.
4143
let s =
@@ -90,7 +92,7 @@ impl Element {
9092
pub fn vartime_compress_to_field(&self) -> Fq {
9193
// This isn't a constant, only because traits don't have const methods
9294
// yet and subtraction is only implemented as part of the Sub trait.
93-
let A_MINUS_D = EdwardsConfig::COEFF_A - EdwardsConfig::COEFF_D;
95+
let A_MINUS_D = Decaf377EdwardsConfig::COEFF_A - Decaf377EdwardsConfig::COEFF_D;
9496
let p = &self.inner;
9597

9698
// 1.

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ pub mod rand;
1414
pub mod serialize;
1515
mod sign;
1616

17-
use ark_ed_on_bls12_377::EdwardsProjective;
1817
pub use constants::ZETA;
1918
pub use element::{AffineElement, Element};
19+
pub(crate) use element::{Decaf377EdwardsConfig, EdwardsProjective};
2020
pub use encoding::Encoding;
2121
pub use error::EncodingError;
2222
pub use field_ext::FieldExt;

src/ops/affine.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
22

33
use ark_ec::twisted_edwards::Projective;
4-
use ark_ed_on_bls12_377::EdwardsConfig;
54

6-
use crate::{element::AffineElement, Element, Fr};
5+
use crate::{element::AffineElement, Decaf377EdwardsConfig, Element, Fr};
76

87
impl<'a, 'b> Add<&'b AffineElement> for &'a AffineElement {
98
type Output = AffineElement;
@@ -102,7 +101,7 @@ impl Neg for AffineElement {
102101

103102
impl<'b> MulAssign<&'b Fr> for AffineElement {
104103
fn mul_assign(&mut self, point: &'b Fr) {
105-
let mut p: Projective<EdwardsConfig> = self.inner.into();
104+
let mut p: Projective<Decaf377EdwardsConfig> = self.inner.into();
106105
p *= *point;
107106
*self = AffineElement { inner: p.into() }
108107
}
@@ -118,7 +117,7 @@ impl<'a, 'b> Mul<&'b Fr> for &'a AffineElement {
118117
type Output = AffineElement;
119118

120119
fn mul(self, point: &'b Fr) -> AffineElement {
121-
let mut p: Projective<EdwardsConfig> = self.inner.into();
120+
let mut p: Projective<Decaf377EdwardsConfig> = self.inner.into();
122121
p *= *point;
123122
AffineElement { inner: p.into() }
124123
}

src/ops/projective.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ impl Neg for Element {
105105

106106
impl<'b> MulAssign<&'b Fr> for Element {
107107
// Scalar multiplication is performed through the implementation
108-
// of `MulAssign` on `EdwardsProjective` which is a type alias for
108+
// of `MulAssign` on `ProjectiveDecaf377` which is a type alias for
109109
// `Group<EdwardsConfig>`.
110110
fn mul_assign(&mut self, point: &'b Fr) {
111111
let mut p = self.inner;

src/r1cs/element.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@
22
use std::borrow::Borrow;
33

44
use ark_ec::AffineRepr;
5-
use ark_ed_on_bls12_377::{
6-
constraints::{EdwardsVar, FqVar},
7-
EdwardsAffine,
8-
};
5+
use ark_ed_on_bls12_377::constraints::FqVar;
96
use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget, prelude::*, R1CSVar};
107
use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError};
118

12-
use crate::r1cs::inner::ElementVar as InnerElementVar;
139
use crate::r1cs::lazy::LazyElementVar;
10+
use crate::{element::EdwardsAffine, r1cs::inner::ElementVar as InnerElementVar};
1411
use crate::{AffineElement, Element, Fq};
1512

13+
use super::inner::Decaf377EdwardsVar;
14+
1615
#[derive(Clone, Debug)]
1716
/// Represents the R1CS equivalent of a `decaf377::Element`
1817
///
@@ -115,7 +114,7 @@ impl CondSelectGadget<Fq> for ElementVar {
115114
let y = cond.select(&true_element.inner.y, &false_element.inner.y)?;
116115

117116
let new_element = InnerElementVar {
118-
inner: EdwardsVar::new(x, y),
117+
inner: Decaf377EdwardsVar::new(x, y),
119118
};
120119
Ok(Self {
121120
inner: LazyElementVar::new_from_element(new_element),

0 commit comments

Comments
 (0)