pasta_curves/
pallas.rs

1//! The Pallas and iso-Pallas elliptic curve groups.
2
3use super::{Ep, EpAffine, Fp, Fq};
4
5/// The base field of the Pallas and iso-Pallas curves.
6pub type Base = Fp;
7
8/// The scalar field of the Pallas and iso-Pallas curves.
9pub type Scalar = Fq;
10
11/// A Pallas point in the projective coordinate space.
12pub type Point = Ep;
13
14/// A Pallas point in the affine coordinate space (or the point at infinity).
15pub type Affine = EpAffine;
16
17#[cfg(feature = "alloc")]
18#[test]
19#[allow(clippy::many_single_char_names)]
20fn test_iso_map() {
21    use crate::arithmetic::CurveExt;
22    use group::Group;
23
24    // This is a regression test (it's the same input to iso_map as for hash_to_curve
25    // with domain prefix "z.cash:test", Shake128, and input b"hello"). We don't
26    // implement Shake128 any more but that's fine.
27    let r = super::IsoEp::new_jacobian(
28        Base::from_raw([
29            0xc37f111df5c4419e,
30            0x593c053e5e2337ad,
31            0x9c6cfc47bce1aba6,
32            0x0a881e4d556945aa,
33        ]),
34        Base::from_raw([
35            0xf234e04434502b47,
36            0x6979f7f2b0acf188,
37            0xa62eec46f662cb4e,
38            0x035e5c8a06d5cfb4,
39        ]),
40        Base::from_raw([
41            0x11ab791d4fb6f6b4,
42            0x575baa717958ef1f,
43            0x6ac4e343558dcbf3,
44            0x3af37975b0933125,
45        ]),
46    )
47    .unwrap();
48    let p = super::hashtocurve::iso_map::<_, Point, super::IsoEp>(&r, &Ep::ISOGENY_CONSTANTS);
49    let (x, y, z) = p.jacobian_coordinates();
50    assert!(
51        format!("{:?}", x) == "0x318cc15f281662b3f26d0175cab97b924870c837879cac647e877be51a85e898"
52    );
53    assert!(
54        format!("{:?}", y) == "0x1e91e2fa2a5a6a5bc86ff9564ae9336084470e7119dffcb85ae8c1383a3defd7"
55    );
56    assert!(
57        format!("{:?}", z) == "0x1e049436efa754f5f189aec69c2c3a4a559eca6a12b45c3f2e4a769deeca6187"
58    );
59
60    // check that iso_map([2] r) = [2] iso_map(r)
61    let r2 = r.double();
62    assert!(bool::from(r2.is_on_curve()));
63    let p2 = super::hashtocurve::iso_map::<_, Point, super::IsoEp>(&r2, &Ep::ISOGENY_CONSTANTS);
64    assert!(bool::from(p2.is_on_curve()));
65    assert!(p2 == p.double());
66}
67
68#[cfg(feature = "alloc")]
69#[test]
70fn test_iso_map_identity() {
71    use crate::arithmetic::CurveExt;
72    use group::Group;
73
74    let r = super::IsoEp::new_jacobian(
75        Base::from_raw([
76            0xc37f111df5c4419e,
77            0x593c053e5e2337ad,
78            0x9c6cfc47bce1aba6,
79            0x0a881e4d556945aa,
80        ]),
81        Base::from_raw([
82            0xf234e04434502b47,
83            0x6979f7f2b0acf188,
84            0xa62eec46f662cb4e,
85            0x035e5c8a06d5cfb4,
86        ]),
87        Base::from_raw([
88            0x11ab791d4fb6f6b4,
89            0x575baa717958ef1f,
90            0x6ac4e343558dcbf3,
91            0x3af37975b0933125,
92        ]),
93    )
94    .unwrap();
95    let r = (r * -Fq::one()) + r;
96    assert!(bool::from(r.is_on_curve()));
97    assert!(bool::from(r.is_identity()));
98    let p = super::hashtocurve::iso_map::<_, Point, super::IsoEp>(&r, &Ep::ISOGENY_CONSTANTS);
99    assert!(bool::from(p.is_on_curve()));
100    assert!(bool::from(p.is_identity()));
101}
102
103#[cfg(feature = "alloc")]
104#[test]
105fn test_map_to_curve_simple_swu() {
106    use crate::arithmetic::CurveExt;
107    use crate::curves::IsoEp;
108    use crate::hashtocurve::map_to_curve_simple_swu;
109
110    // The zero input is a special case.
111    let p: IsoEp = map_to_curve_simple_swu::<Fp, Ep, IsoEp>(&Fp::zero(), Ep::THETA, Ep::Z);
112    let (x, y, z) = p.jacobian_coordinates();
113
114    assert!(
115        format!("{:?}", x) == "0x28c1a6a534f56c52e25295b339129a8af5f42525dea727f485ca3433519b096e"
116    );
117    assert!(
118        format!("{:?}", y) == "0x3bfc658bee6653c63c7d7f0927083fd315d29c270207b7c7084fa1ee6ac5ae8d"
119    );
120    assert!(
121        format!("{:?}", z) == "0x054b3ba10416dc104157b1318534a19d5d115472da7d746f8a5f250cd8cdef36"
122    );
123
124    let p: IsoEp = map_to_curve_simple_swu::<Fp, Ep, IsoEp>(&Fp::one(), Ep::THETA, Ep::Z);
125    let (x, y, z) = p.jacobian_coordinates();
126
127    assert!(
128        format!("{:?}", x) == "0x010cba5957e876534af5e967c026a1856d64b071068280837913b9a5a3561505"
129    );
130    assert!(
131        format!("{:?}", y) == "0x062fc61f9cd3118e7d6e65a065ebf46a547514d6b08078e976fa6d515dcc9c81"
132    );
133    assert!(
134        format!("{:?}", z) == "0x3f86cb8c311250c3101c4e523e7793605ccff5623de1753a7c75bc9a29a73688"
135    );
136}
137
138#[cfg(feature = "alloc")]
139#[test]
140fn test_hash_to_curve() {
141    use crate::arithmetic::CurveExt;
142    use group::Group;
143
144    // This test vector is chosen so that the first map_to_curve_simple_swu takes the gx1 square
145    // "branch" and the second takes the gx1 non-square "branch" (opposite to the Vesta test vector).
146    let hash = Point::hash_to_curve("z.cash:test");
147    let p: Point = hash(b"Trans rights now!");
148    let (x, y, z) = p.jacobian_coordinates();
149
150    assert!(
151        format!("{:?}", x) == "0x36a6e3a9c50b7b6540cb002c977c82f37f8a875fb51eb35327ee1452e6ce7947"
152    );
153    assert!(
154        format!("{:?}", y) == "0x01da3b4403d73252f2d7e9c19bc23dc6a080f2d02f8262fca4f7e3d756ac6a7c"
155    );
156    assert!(
157        format!("{:?}", z) == "0x1d48103df8fcbb70d1809c1806c95651dd884a559fec0549658537ce9d94bed9"
158    );
159    assert!(bool::from(p.is_on_curve()));
160
161    let p = (p * -Fq::one()) + p;
162    assert!(bool::from(p.is_on_curve()));
163    assert!(bool::from(p.is_identity()));
164}