halo2curves_axiom/pasta/
mod.rs

1use crate::arithmetic::mul_512;
2use crate::arithmetic::sbb;
3use crate::{
4    arithmetic::{CurveEndo, EndoParameters},
5    endo,
6};
7use ff::PrimeField;
8use ff::WithSmallOrderMulGroup;
9pub use pasta_curves::{pallas, vesta, Ep, EpAffine, Eq, EqAffine, Fp, Fq};
10use std::convert::TryInto;
11
12// Generated using https://github.com/ConsenSys/gnark-crypto/blob/master/ecc/utils.go
13// with `pasta_curves::Fp::ZETA`
14// See https://github.com/demining/Endomorphism-Secp256k1/blob/main/README.md
15// to have more details about the endomorphism.
16const ENDO_PARAMS_EQ: EndoParameters = EndoParameters {
17    // round(b2/n)
18    gamma1: [0x32c49e4c00000003, 0x279a745902a2654e, 0x1, 0x0],
19    // round(-b1/n)
20    gamma2: [0x31f0256800000002, 0x4f34e8b2066389a4, 0x2, 0x0],
21    b1: [0x8cb1279300000001, 0x49e69d1640a89953, 0x0, 0x0],
22    b2: [0x0c7c095a00000001, 0x93cd3a2c8198e269, 0x0, 0x0],
23};
24
25// Generated using https://github.com/ConsenSys/gnark-crypto/blob/master/ecc/utils.go
26// with `pasta_curves::Fq::ZETA`
27// See https://github.com/demining/Endomorphism-Secp256k1/blob/main/README.md
28// to have more details about the endomorphism.
29const ENDO_PARAMS_EP: EndoParameters = EndoParameters {
30    // round(b2/n)
31    gamma1: [0x32c49e4bffffffff, 0x279a745902a2654e, 0x1, 0x0],
32    // round(-b1/n)
33    gamma2: [0x31f0256800000002, 0x4f34e8b2066389a4, 0x2, 0x0],
34    b1: [0x8cb1279300000000, 0x49e69d1640a89953, 0x0, 0x0],
35    b2: [0x0c7c095a00000001, 0x93cd3a2c8198e269, 0x0, 0x0],
36};
37
38endo!(Eq, Fp, ENDO_PARAMS_EQ);
39endo!(Ep, Fq, ENDO_PARAMS_EP);
40
41#[test]
42fn test_endo() {
43    use ff::Field;
44    use rand_core::OsRng;
45
46    for _ in 0..100000 {
47        let k = Fp::random(OsRng);
48        let (k1, k1_neg, k2, k2_neg) = Eq::decompose_scalar(&k);
49        if k1_neg & k2_neg {
50            assert_eq!(k, -Fp::from_u128(k1) + Fp::ZETA * Fp::from_u128(k2))
51        } else if k1_neg {
52            assert_eq!(k, -Fp::from_u128(k1) - Fp::ZETA * Fp::from_u128(k2))
53        } else if k2_neg {
54            assert_eq!(k, Fp::from_u128(k1) + Fp::ZETA * Fp::from_u128(k2))
55        } else {
56            assert_eq!(k, Fp::from_u128(k1) - Fp::ZETA * Fp::from_u128(k2))
57        }
58    }
59
60    for _ in 0..100000 {
61        let k = Fp::random(OsRng);
62        let (k1, k1_neg, k2, k2_neg) = Eq::decompose_scalar(&k);
63        if k1_neg & k2_neg {
64            assert_eq!(k, -Fp::from_u128(k1) + Fp::ZETA * Fp::from_u128(k2))
65        } else if k1_neg {
66            assert_eq!(k, -Fp::from_u128(k1) - Fp::ZETA * Fp::from_u128(k2))
67        } else if k2_neg {
68            assert_eq!(k, Fp::from_u128(k1) + Fp::ZETA * Fp::from_u128(k2))
69        } else {
70            assert_eq!(k, Fp::from_u128(k1) - Fp::ZETA * Fp::from_u128(k2))
71        }
72    }
73}