elliptic_curve/hash2curve/
isogeny.rs

1//! Traits for mapping an isogeny to another curve
2//!
3//! <https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve>
4
5use core::ops::{AddAssign, Mul};
6use ff::Field;
7use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};
8
9/// The coefficients for mapping from one isogenous curve to another
10pub struct IsogenyCoefficients<F: Field + AddAssign + Mul<Output = F>> {
11    /// The coefficients for the x numerator
12    pub xnum: &'static [F],
13    /// The coefficients for the x denominator
14    pub xden: &'static [F],
15    /// The coefficients for the y numerator
16    pub ynum: &'static [F],
17    /// The coefficients for the x denominator
18    pub yden: &'static [F],
19}
20
21/// The [`Isogeny`] methods to map to another curve.
22pub trait Isogeny: Field + AddAssign + Mul<Output = Self> {
23    /// The maximum number of coefficients
24    type Degree: ArrayLength<Self>;
25    /// The isogeny coefficients
26    const COEFFICIENTS: IsogenyCoefficients<Self>;
27
28    /// Map from the isogeny points to the main curve
29    fn isogeny(x: Self, y: Self) -> (Self, Self) {
30        let mut xs = GenericArray::<Self, Self::Degree>::default();
31        xs[0] = Self::ONE;
32        xs[1] = x;
33        xs[2] = x.square();
34        for i in 3..Self::Degree::to_usize() {
35            xs[i] = xs[i - 1] * x;
36        }
37        let x_num = Self::compute_iso(&xs, Self::COEFFICIENTS.xnum);
38        let x_den = Self::compute_iso(&xs, Self::COEFFICIENTS.xden)
39            .invert()
40            .unwrap();
41        let y_num = Self::compute_iso(&xs, Self::COEFFICIENTS.ynum) * y;
42        let y_den = Self::compute_iso(&xs, Self::COEFFICIENTS.yden)
43            .invert()
44            .unwrap();
45
46        (x_num * x_den, y_num * y_den)
47    }
48
49    /// Compute the ISO transform
50    fn compute_iso(xxs: &[Self], k: &[Self]) -> Self {
51        let mut xx = Self::ZERO;
52        for (xi, ki) in xxs.iter().zip(k.iter()) {
53            xx += *xi * ki;
54        }
55        xx
56    }
57}