Skip to main content

kimchi/
curve.rs

1//! This module contains a useful trait for recursion: [KimchiCurve],
2//! which defines how a pair of curves interact.
3
4use ark_ec::{short_weierstrass::Affine, AffineRepr, CurveConfig};
5use mina_curves::{
6    named::NamedCurve,
7    pasta::curves::{
8        pallas::{LegacyPallasParameters, PallasParameters},
9        vesta::{LegacyVestaParameters, VestaParameters},
10    },
11};
12use mina_poseidon::{pasta::FULL_ROUNDS, poseidon::ArithmeticSpongeParams};
13use poly_commitment::{
14    commitment::{CommitmentCurve, EndoCurve},
15    ipa::endos,
16};
17
18/// Represents additional information that a curve needs in order to be used
19/// with Kimchi
20pub trait KimchiCurve<const FULL_ROUNDS: usize>: EndoCurve + NamedCurve {
21    /// Provides the sponge params to be used with this curve.
22    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField, FULL_ROUNDS>;
23
24    /// Provides the sponge params to be used with the other curve.
25    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField, FULL_ROUNDS>;
26
27    /// Provides the coefficients for the curve endomorphism, called (q,r) in
28    /// some places.
29    fn endos() -> &'static (Self::BaseField, Self::ScalarField);
30
31    /// Provides the coefficient for the curve endomorphism over the other
32    /// field, called q in some places.
33    fn other_curve_endo() -> &'static Self::ScalarField;
34
35    /// Accessor for the other curve's prime subgroup generator, as coordinates
36    // TODO: This leaked from snarky.rs. Stop the bleed.
37    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField);
38}
39
40pub fn vesta_endos() -> &'static (
41    <VestaParameters as CurveConfig>::BaseField,
42    <VestaParameters as CurveConfig>::ScalarField,
43) {
44    static VESTA_ENDOS: o1_utils::lazy_lock::LazyLock<(
45        <VestaParameters as CurveConfig>::BaseField,
46        <VestaParameters as CurveConfig>::ScalarField,
47    )> = o1_utils::lazy_lock::LazyLock::new(endos::<Affine<VestaParameters>>);
48    &VESTA_ENDOS
49}
50
51pub fn pallas_endos() -> &'static (
52    <PallasParameters as CurveConfig>::BaseField,
53    <PallasParameters as CurveConfig>::ScalarField,
54) {
55    static PALLAS_ENDOS: o1_utils::lazy_lock::LazyLock<(
56        <PallasParameters as CurveConfig>::BaseField,
57        <PallasParameters as CurveConfig>::ScalarField,
58    )> = o1_utils::lazy_lock::LazyLock::new(endos::<Affine<PallasParameters>>);
59    &PALLAS_ENDOS
60}
61
62impl KimchiCurve<FULL_ROUNDS> for Affine<VestaParameters> {
63    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField, FULL_ROUNDS> {
64        mina_poseidon::pasta::fp_kimchi::static_params()
65    }
66
67    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField, FULL_ROUNDS>
68    {
69        mina_poseidon::pasta::fq_kimchi::static_params()
70    }
71
72    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
73        vesta_endos()
74    }
75
76    fn other_curve_endo() -> &'static Self::ScalarField {
77        &pallas_endos().0
78    }
79
80    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
81        Affine::<PallasParameters>::generator()
82            .to_coordinates()
83            .unwrap()
84    }
85}
86
87impl KimchiCurve<FULL_ROUNDS> for Affine<PallasParameters> {
88    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField, FULL_ROUNDS> {
89        mina_poseidon::pasta::fq_kimchi::static_params()
90    }
91
92    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField, FULL_ROUNDS>
93    {
94        mina_poseidon::pasta::fp_kimchi::static_params()
95    }
96
97    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
98        pallas_endos()
99    }
100
101    fn other_curve_endo() -> &'static Self::ScalarField {
102        &vesta_endos().0
103    }
104
105    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
106        Affine::<VestaParameters>::generator()
107            .to_coordinates()
108            .unwrap()
109    }
110}
111
112//
113// Legacy curves
114//
115
116impl KimchiCurve<{ mina_poseidon::pasta::LEGACY_ROUNDS }> for Affine<LegacyVestaParameters> {
117    fn sponge_params(
118    ) -> &'static ArithmeticSpongeParams<Self::ScalarField, { mina_poseidon::pasta::LEGACY_ROUNDS }>
119    {
120        mina_poseidon::pasta::fp_legacy::static_params()
121    }
122
123    fn other_curve_sponge_params(
124    ) -> &'static ArithmeticSpongeParams<Self::BaseField, { mina_poseidon::pasta::LEGACY_ROUNDS }>
125    {
126        mina_poseidon::pasta::fq_legacy::static_params()
127    }
128
129    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
130        vesta_endos()
131    }
132
133    fn other_curve_endo() -> &'static Self::ScalarField {
134        &pallas_endos().0
135    }
136
137    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
138        Affine::<PallasParameters>::generator()
139            .to_coordinates()
140            .unwrap()
141    }
142}
143
144impl KimchiCurve<{ mina_poseidon::pasta::LEGACY_ROUNDS }> for Affine<LegacyPallasParameters> {
145    fn sponge_params(
146    ) -> &'static ArithmeticSpongeParams<Self::ScalarField, { mina_poseidon::pasta::LEGACY_ROUNDS }>
147    {
148        mina_poseidon::pasta::fq_legacy::static_params()
149    }
150
151    fn other_curve_sponge_params(
152    ) -> &'static ArithmeticSpongeParams<Self::BaseField, { mina_poseidon::pasta::LEGACY_ROUNDS }>
153    {
154        mina_poseidon::pasta::fp_legacy::static_params()
155    }
156
157    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
158        pallas_endos()
159    }
160
161    fn other_curve_endo() -> &'static Self::ScalarField {
162        &vesta_endos().0
163    }
164
165    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
166        Affine::<VestaParameters>::generator()
167            .to_coordinates()
168            .unwrap()
169    }
170}
171
172#[cfg(feature = "bn254")]
173use mina_poseidon::dummy_values::kimchi_dummy;
174
175#[cfg(feature = "bn254")]
176impl KimchiCurve<FULL_ROUNDS> for Affine<ark_bn254::g1::Config> {
177    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField, FULL_ROUNDS> {
178        use o1_utils::lazy_lock::LazyLock;
179        // TODO: Generate some params
180        static PARAMS: LazyLock<ArithmeticSpongeParams<ark_bn254::Fr, FULL_ROUNDS>> =
181            LazyLock::new(kimchi_dummy);
182        &PARAMS
183    }
184
185    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField, FULL_ROUNDS>
186    {
187        use o1_utils::lazy_lock::LazyLock;
188        // TODO: Generate some params
189        static PARAMS: LazyLock<ArithmeticSpongeParams<ark_bn254::Fq, FULL_ROUNDS>> =
190            LazyLock::new(kimchi_dummy);
191        &PARAMS
192    }
193
194    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
195        use o1_utils::lazy_lock::LazyLock;
196        static ENDOS: LazyLock<(ark_bn254::Fq, ark_bn254::Fr)> =
197            LazyLock::new(endos::<ark_bn254::G1Affine>);
198        &ENDOS
199    }
200
201    fn other_curve_endo() -> &'static Self::ScalarField {
202        use o1_utils::lazy_lock::LazyLock;
203        static ENDO: LazyLock<ark_bn254::Fr> = LazyLock::new(|| 13u64.into());
204        &ENDO
205    }
206
207    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
208        // TODO: Dummy value, this is definitely not right
209        (44u64.into(), 88u64.into())
210    }
211}