1use super::TEPoint;
19use ark_ec::short_weierstrass::{Affine as SWAffine, SWCurveConfig as SWParam};
20use ark_ff::{BigInteger256, BigInteger384, BigInteger768, PrimeField};
21
22impl<F, P> From<SWAffine<P>> for TEPoint<F>
23where
24 F: PrimeField + SWToTEConParam,
25 P: SWParam<BaseField = F>,
26{
27 fn from(p: SWAffine<P>) -> Self {
28 if p.infinity {
34 return Self(F::zero(), F::one());
35 }
36
37 let s = F::from(F::S);
42 let neg_alpha = F::from(F::NEG_ALPHA);
43 let beta = F::from(F::BETA);
44
45 let montgomery_x = s * (p.x + neg_alpha);
49 let montgomery_y = s * p.y;
50 let edwards_x = beta * montgomery_x / montgomery_y;
54 let edwards_y = (montgomery_x - F::one()) / (montgomery_x + F::one());
55
56 TEPoint(edwards_x, edwards_y)
57 }
58}
59
60pub trait SWToTEConParam: PrimeField {
63 const S: Self::BigInt;
65 const NEG_ALPHA: Self::BigInt;
67 const BETA: Self::BigInt;
69}
70
71use ark_bls12_377::Fq as Fq377;
75impl SWToTEConParam for Fq377 {
76 const S: Self::BigInt = BigInteger384::new([
78 0x3401d618f0339eab,
79 0x0f793b8504b428d4,
80 0x0ff643cca95ccc0d,
81 0xd7a504665d66cc8c,
82 0x1dc07a44b1eeea84,
83 0x10f272020f118a,
84 ]);
85
86 const NEG_ALPHA: Self::BigInt = BigInteger384::new([1, 0, 0, 0, 0, 0]);
88
89 const BETA: Self::BigInt = BigInteger384::new([
91 0x450ae9206343e6e4,
92 0x7af39509df5027b6,
93 0xab82b31405cf8a30,
94 0x80d743e1f6c15c7c,
95 0x0cec22e650360183,
96 0x272fd56ac5c669,
97 ]);
98}
99
100use ark_bn254::Fq as Fq254;
104impl SWToTEConParam for Fq254 {
106 const S: Self::BigInt = BigInteger256::new([0, 0, 0, 0]);
107 const NEG_ALPHA: Self::BigInt = BigInteger256::new([0, 0, 0, 0]);
108 const BETA: Self::BigInt = BigInteger256::new([0, 0, 0, 0]);
109}
110
111use ark_bls12_381::Fq as Fq381;
115impl SWToTEConParam for Fq381 {
117 const S: Self::BigInt = BigInteger384::new([0, 0, 0, 0, 0, 0]);
118 const NEG_ALPHA: Self::BigInt = BigInteger384::new([0, 0, 0, 0, 0, 0]);
119 const BETA: Self::BigInt = BigInteger384::new([0, 0, 0, 0, 0, 0]);
120}
121
122use ark_bw6_761::Fq as Fq761;
126impl SWToTEConParam for Fq761 {
128 const S: Self::BigInt = BigInteger768::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
129 const NEG_ALPHA: Self::BigInt = BigInteger768::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
130 const BETA: Self::BigInt = BigInteger768::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
131}
132
133#[cfg(test)]
134mod test {
135 use super::*;
136 use ark_bls12_377::{G1Affine, G1Projective};
137 use ark_ec::{AffineRepr, CurveGroup};
138 use ark_ff::{MontFp, One};
139 use ark_std::{UniformRand, Zero};
140 use jf_utils::test_rng;
141
142 fn is_on_bls12_377_ed_curve(p: &TEPoint<Fq377>) -> bool {
145 let a = MontFp!("-1");
147 let d = MontFp!("122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179");
148
149 let x2 = p.0 * p.0;
150 let y2 = p.1 * p.1;
151
152 let left = a * x2 + y2;
153 let right = Fq377::one() + d * x2 * y2;
154
155 left == right
156 }
157
158 #[allow(non_snake_case)]
159 #[test]
160 fn test_sw_to_te_conversion() {
161 let mut rng = test_rng();
162
163 let g1 = G1Affine::generator();
165 let p: TEPoint<Fq377> = g1.into();
166 assert!(is_on_bls12_377_ed_curve(&p));
167
168 let g1 = G1Affine::zero();
170 let p: TEPoint<Fq377> = g1.into();
171 assert_eq!(p.0, Fq377::zero());
172 assert_eq!(p.1, Fq377::one());
173 assert!(is_on_bls12_377_ed_curve(&p));
174
175 let g1 = G1Projective::rand(&mut rng).into_affine();
177 let p: TEPoint<Fq377> = g1.into();
178 assert!(is_on_bls12_377_ed_curve(&p));
179 }
180}