ark_vrf/utils/
te_sw_map.rs1use ark_ec::{
7 CurveConfig,
8 short_weierstrass::{Affine as SWAffine, SWCurveConfig},
9 twisted_edwards::{Affine as TEAffine, MontCurveConfig, TECurveConfig},
10};
11use ark_ff::{Field, One};
12use ark_std::borrow::Cow;
13
14pub trait MapConfig: TECurveConfig + SWCurveConfig + MontCurveConfig {
20 const MONT_A_OVER_THREE: <Self as CurveConfig>::BaseField;
22
23 const MONT_B_INV: <Self as CurveConfig>::BaseField;
25}
26
27pub fn sw_to_te<C: MapConfig>(point: &SWAffine<C>) -> Option<TEAffine<C>> {
32 let mx = <C as MontCurveConfig>::COEFF_B * point.x - C::MONT_A_OVER_THREE;
35 let my = <C as MontCurveConfig>::COEFF_B * point.y;
36
37 let v_denom = my.inverse()?;
40 let x_p_1 = mx + <<C as CurveConfig>::BaseField as One>::one();
41 let w_denom = x_p_1.inverse()?;
42 let v = mx * v_denom;
43 let w = (mx - <<C as CurveConfig>::BaseField as One>::one()) * w_denom;
44
45 Some(TEAffine::new_unchecked(v, w))
46}
47
48pub fn te_to_sw<C: MapConfig>(point: &TEAffine<C>) -> Option<SWAffine<C>> {
53 let v_denom = <<C as CurveConfig>::BaseField as One>::one() - point.y;
55 let w_denom = point.x - point.x * point.y;
56 let v_denom_inv = v_denom.inverse()?;
57 let w_denom_inv = w_denom.inverse()?;
58 let v_w_num = <<C as CurveConfig>::BaseField as One>::one() + point.y;
59 let v = v_w_num * v_denom_inv;
60 let w = v_w_num * w_denom_inv;
61
62 let x = C::MONT_B_INV * (v + C::MONT_A_OVER_THREE);
64 let y = C::MONT_B_INV * w;
65
66 Some(SWAffine::new_unchecked(x, y))
67}
68
69pub trait SWMapping<C: SWCurveConfig> {
74 fn from_sw(sw: SWAffine<C>) -> Self;
76
77 fn into_sw(self) -> SWAffine<C>;
79
80 fn to_sw_slice(slice: &[Self]) -> Cow<'_, [SWAffine<C>]>
85 where
86 Self: Sized;
87}
88
89impl<C: SWCurveConfig> SWMapping<C> for SWAffine<C> {
90 #[inline(always)]
91 fn from_sw(sw: SWAffine<C>) -> Self {
92 sw
93 }
94
95 #[inline(always)]
96 fn into_sw(self) -> SWAffine<C> {
97 self
98 }
99
100 #[inline(always)]
101 fn to_sw_slice(slice: &[Self]) -> Cow<'_, [SWAffine<C>]> {
102 Cow::Borrowed(slice)
103 }
104}
105
106impl<C: MapConfig> SWMapping<C> for TEAffine<C> {
107 #[inline(always)]
108 fn from_sw(sw: SWAffine<C>) -> Self {
109 sw_to_te(&sw).expect("SW to TE mapping failed (identity or degenerate point)")
110 }
111
112 #[inline(always)]
113 fn into_sw(self) -> SWAffine<C> {
114 te_to_sw(&self).expect("TE to SW mapping failed (identity or degenerate point)")
115 }
116
117 #[inline(always)]
118 fn to_sw_slice(slice: &[Self]) -> Cow<'_, [SWAffine<C>]> {
119 let pks;
120 #[cfg(feature = "parallel")]
121 {
122 use rayon::prelude::*;
123 pks = slice.par_iter().map(|p| p.into_sw()).collect();
124 }
125 #[cfg(not(feature = "parallel"))]
126 {
127 pks = slice.iter().map(|p| p.into_sw()).collect();
128 }
129 Cow::Owned(pks)
130 }
131}
132
133pub trait TEMapping<C: TECurveConfig> {
138 fn from_te(te: TEAffine<C>) -> Self;
140
141 fn into_te(self) -> TEAffine<C>;
143
144 fn to_te_slice(slice: &[Self]) -> Cow<'_, [TEAffine<C>]>
149 where
150 Self: Sized;
151}
152
153impl<C: TECurveConfig> TEMapping<C> for TEAffine<C> {
154 #[inline(always)]
155 fn from_te(te: TEAffine<C>) -> Self {
156 te
157 }
158
159 #[inline(always)]
160 fn into_te(self) -> TEAffine<C> {
161 self
162 }
163
164 #[inline(always)]
165 fn to_te_slice(slice: &[Self]) -> Cow<'_, [TEAffine<C>]> {
166 Cow::Borrowed(slice)
167 }
168}
169
170impl<C: MapConfig> TEMapping<C> for SWAffine<C> {
171 #[inline(always)]
172 fn from_te(te: TEAffine<C>) -> Self {
173 te_to_sw(&te).expect("TE to SW mapping failed (identity or degenerate point)")
174 }
175
176 #[inline(always)]
177 fn into_te(self) -> TEAffine<C> {
178 sw_to_te(&self).expect("SW to TE mapping failed (identity or degenerate point)")
179 }
180
181 #[inline(always)]
182 fn to_te_slice(slice: &[Self]) -> Cow<'_, [TEAffine<C>]> {
183 let pks;
184 #[cfg(feature = "parallel")]
185 {
186 use rayon::prelude::*;
187 pks = slice.par_iter().map(|p| p.into_te()).collect();
188 }
189 #[cfg(not(feature = "parallel"))]
190 {
191 pks = slice.iter().map(|p| p.into_te()).collect();
192 }
193 Cow::Owned(pks)
194 }
195}