halo2curves/grumpkin/
curve.rs

1use core::{
2    cmp,
3    fmt::Debug,
4    iter::Sum,
5    ops::{Add, Mul, Neg, Sub},
6};
7
8use rand::RngCore;
9use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
10
11use crate::{
12    arithmetic::{mul_512, sbb, CurveEndo, EndoParameters},
13    endo,
14    ff::{Field, PrimeField, WithSmallOrderMulGroup},
15    group::{prime::PrimeCurveAffine, Curve, Group, GroupEncoding},
16    grumpkin::{Fq, Fr},
17    impl_binops_additive, impl_binops_additive_specify_output, impl_binops_multiplicative,
18    impl_binops_multiplicative_mixed, new_curve_impl, Coordinates, CurveAffine, CurveExt,
19};
20
21new_curve_impl!(
22    (pub),
23    G1,
24    G1Affine,
25    Fq,
26    Fr,
27    (G1_GENERATOR_X, G1_GENERATOR_Y),
28    G1_A,
29    G1_B,
30    "grumpkin_g1",
31    |domain_prefix| crate::hash_to_curve::hash_to_curve(domain_prefix, G1::default_hash_to_curve_suite()),
32    crate::serde::CompressedFlagConfig::TwoSpare,
33    standard_sign
34);
35
36// Parameters in montgomery form taken from
37// https://github.com/AztecProtocol/barretenberg/blob/97ccf76c42db581a8b8f8bfbcffe8ca015a3dd22/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.hpp#L14
38const G1_GENERATOR_X: Fq = Fq::one();
39const G1_GENERATOR_Y: Fq = Fq([
40    0x11b2dff1448c41d8,
41    0x23d3446f21c77dc3,
42    0xaa7b8cf435dfafbb,
43    0x14b34cf69dc25d68,
44]);
45const G1_A: Fq = Fq::zero();
46const G1_B: Fq = Fq([
47    0xdd7056026000005a,
48    0x223fa97acb319311,
49    0xcc388229877910c0,
50    0x034394632b724eaa,
51]);
52
53// Generated using https://github.com/ConsenSys/gnark-crypto/blob/master/ecc/utils.go
54// with `bn256::Fq::ZETA`
55// See https://github.com/demining/Endomorphism-Secp256k1/blob/main/README.md
56// to have more details about the endomorphism.
57const ENDO_PARAMS_GRUMPKIN: EndoParameters = EndoParameters {
58    gamma1: [0xd91d232ec7e0b3d2, 0x2, 0, 0],
59    gamma2: [0x5398fd0300ff655f, 0x4ccef014a773d2d2, 0x02, 0],
60    b1: [0x89d3256894d213e2, 0, 0, 0],
61    b2: [0x0be4e1541221250b, 0x6f4d8248eeb859fd, 0, 0],
62};
63
64endo!(G1, Fr, ENDO_PARAMS_GRUMPKIN);
65
66impl group::cofactor::CofactorGroup for G1 {
67    type Subgroup = G1;
68
69    fn clear_cofactor(&self) -> Self {
70        *self
71    }
72
73    fn into_subgroup(self) -> CtOption<Self::Subgroup> {
74        CtOption::new(self, 1.into())
75    }
76
77    fn is_torsion_free(&self) -> Choice {
78        1.into()
79    }
80}
81
82impl G1 {
83    const SVDW_Z: Fq = Fq::ONE;
84
85    fn default_hash_to_curve_suite() -> crate::hash_to_curve::Suite<Self, sha2::Sha256, 48> {
86        crate::hash_to_curve::Suite::<G1, sha2::Sha256, 48>::new(
87            b"GRUMPKIN_XMD:SHA-256_SVDW_RO_",
88            Self::SVDW_Z,
89            crate::hash_to_curve::Method::SVDW,
90        )
91    }
92}
93
94#[cfg(test)]
95mod test {
96    use group::UncompressedEncoding;
97    use rand_core::OsRng;
98
99    use super::*;
100    use crate::serde::SerdeObject;
101    crate::curve_testing_suite!(G1);
102    crate::curve_testing_suite!(G1, "endo_consistency");
103    crate::curve_testing_suite!(G1, "endo");
104    crate::curve_testing_suite!(
105        G1,
106        "constants",
107        Fq::MODULUS,
108        G1_A,
109        G1_B,
110        G1_GENERATOR_X,
111        G1_GENERATOR_Y,
112        Fr::MODULUS
113    );
114}