arnaucube
arnaucube/arkeddsaPublic Self-hosted repository
arkeddsa/src/ed_on_bn254_twist.rs
src/ed_on_bn254_twist.rsRaw
  1use ark_ec::{
  2    models::CurveConfig,
  3    twisted_edwards::{Affine, MontCurveConfig, Projective, TECurveConfig},
  4};
  5use ark_ff::MontFp;
  6pub type EdwardsAffine = Affine<EdwardsConfig>;
  7pub type EdwardsProjective = Projective<EdwardsConfig>;
  8
  9pub use ark_ed_on_bn254::{Fq, Fr};
 10pub type BaseField = ark_ed_on_bn254::Fq;
 11pub type ScalarField = ark_ed_on_bn254::Fr;
 12
 13/// Twist of `Baby-JubJub` is a twist of twisted Edwards curve. These curves have equations of the
 14/// form: ax² + y² = 1 + dx²y².
 15/// over some base finite field BaseField.
 16///
 17/// q = 21888242871839275222246405745257275088548364400416034343698204186575808495617
 18#[derive(Clone, Default, PartialEq, Eq)]
 19pub struct EdwardsConfig;
 20
 21#[cfg(test)]
 22ark_algebra_test_templates::test_group!(te; EdwardsProjective; te);
 23
 24impl CurveConfig for EdwardsConfig {
 25    type BaseField = BaseField;
 26    type ScalarField = ScalarField;
 27
 28    /// COFACTOR = 8
 29    const COFACTOR: &'static [u64] = &[8];
 30
 31    /// COFACTOR^(-1) mod r =
 32    /// 2394026564107420727433200628387514462817212225638746351800188703329891451411
 33    const COFACTOR_INV: ScalarField =
 34        MontFp!("2394026564107420727433200628387514462817212225638746351800188703329891451411");
 35}
 36
 37impl TECurveConfig for EdwardsConfig {
 38    const COEFF_A: BaseField = MontFp!("168700");
 39
 40    #[inline(always)]
 41    fn mul_by_a(elem: Self::BaseField) -> Self::BaseField {
 42        elem * <Self as TECurveConfig>::COEFF_A
 43    }
 44
 45    const COEFF_D: BaseField = MontFp!("168696");
 46
 47    const GENERATOR: EdwardsAffine = EdwardsAffine::new_unchecked(GENERATOR_X, GENERATOR_Y);
 48
 49    type MontCurveConfig = EdwardsConfig;
 50}
 51
 52impl MontCurveConfig for EdwardsConfig {
 53    /// COEFF_A = 168698
 54    const COEFF_A: BaseField = MontFp!("168698");
 55    /// COEFF_B = 168700
 56    const COEFF_B: BaseField = MontFp!("1");
 57
 58    type TECurveConfig = EdwardsConfig;
 59}
 60
 61/// GENERATOR_X =
 62/// 19698561148652590122159747500897617769866003486955115824547446575314762165298
 63pub const GENERATOR_X: BaseField =
 64    MontFp!("5299619240641551281634865583518297030282874472190772894086521144482721001553");
 65
 66/// GENERATOR_Y =
 67/// 19298250018296453272277890825869354524455968081175474282777126169995084727839
 68pub const GENERATOR_Y: BaseField =
 69    MontFp!("16950150798460657717958625567821834550301663161624707787222815936182638968203");
 70
 71#[test]
 72fn test_twist() {
 73    fn twist(twist: ark_ed_on_bn254::EdwardsAffine) -> EdwardsAffine {
 74        use ark_ff::Field;
 75        let inv_sqrt_a = MontFp!("168700").sqrt().unwrap().inverse().unwrap();
 76        EdwardsAffine {
 77            x: twist.x * inv_sqrt_a,
 78            y: twist.y,
 79        }
 80    }
 81
 82    fn untwist(curve: EdwardsAffine) -> ark_ed_on_bn254::EdwardsAffine {
 83        use ark_ff::Field;
 84        const A: BaseField = MontFp!("168700");
 85        let sqrt_a = A.sqrt().unwrap();
 86        ark_ed_on_bn254::EdwardsAffine {
 87            x: curve.x * sqrt_a,
 88            y: curve.y,
 89        }
 90    }
 91
 92    use ark_ec::{AffineRepr, CurveGroup};
 93    use ark_std::UniformRand;
 94    use rand_core::OsRng;
 95
 96    let v0: ark_ed_on_bn254::EdwardsAffine = ark_ed_on_bn254::EdwardsAffine::generator();
 97    let u0: crate::ed_on_bn254_twist::EdwardsAffine = twist(v0);
 98    assert!(u0.is_on_curve());
 99    assert!(u0.is_in_correct_subgroup_assuming_on_curve());
100    let x = Fr::rand(&mut OsRng);
101    let u1 = (u0 * x).into_affine();
102    let v1 = (v0 * x).into_affine();
103    let v2 = untwist(u1);
104    assert_eq!(v1, v2);
105}
106
107// constraints related logic
108#[cfg(feature = "r1cs")]
109pub mod constraints {
110    use ark_r1cs_std::fields::fp::FpVar;
111    use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar;
112
113    use crate::ed_on_bn254_twist::{BaseField as Fq, EdwardsConfig};
114
115    /// A variable that is the R1CS equivalent of `crate::Fq`.
116    pub type FqVar = FpVar<Fq>;
117
118    /// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
119    pub type EdwardsVar = AffineVar<EdwardsConfig, FqVar>;
120}