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::poseidon::ArithmeticSpongeParams;
13use once_cell::sync::Lazy;
14use poly_commitment::{
15    commitment::{CommitmentCurve, EndoCurve},
16    ipa::endos,
17};
18
19/// Represents additional information that a curve needs in order to be used
20/// with Kimchi
21pub trait KimchiCurve: CommitmentCurve + EndoCurve + NamedCurve {
22    /// Provides the sponge params to be used with this curve.
23    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField>;
24
25    /// Provides the sponge params to be used with the other curve.
26    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField>;
27
28    /// Provides the coefficients for the curve endomorphism, called (q,r) in
29    /// some places.
30    fn endos() -> &'static (Self::BaseField, Self::ScalarField);
31
32    /// Provides the coefficient for the curve endomorphism over the other
33    /// field, called q in some places.
34    fn other_curve_endo() -> &'static Self::ScalarField;
35
36    /// Accessor for the other curve's prime subgroup generator, as coordinates
37    // TODO: This leaked from snarky.rs. Stop the bleed.
38    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField);
39}
40
41pub fn vesta_endos() -> &'static (
42    <VestaParameters as CurveConfig>::BaseField,
43    <VestaParameters as CurveConfig>::ScalarField,
44) {
45    static VESTA_ENDOS: Lazy<(
46        <VestaParameters as CurveConfig>::BaseField,
47        <VestaParameters as CurveConfig>::ScalarField,
48    )> = Lazy::new(endos::<Affine<VestaParameters>>);
49    &VESTA_ENDOS
50}
51
52pub fn pallas_endos() -> &'static (
53    <PallasParameters as CurveConfig>::BaseField,
54    <PallasParameters as CurveConfig>::ScalarField,
55) {
56    static PALLAS_ENDOS: Lazy<(
57        <PallasParameters as CurveConfig>::BaseField,
58        <PallasParameters as CurveConfig>::ScalarField,
59    )> = Lazy::new(endos::<Affine<PallasParameters>>);
60    &PALLAS_ENDOS
61}
62
63impl KimchiCurve for Affine<VestaParameters> {
64    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField> {
65        mina_poseidon::pasta::fp_kimchi::static_params()
66    }
67
68    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField> {
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 for Affine<PallasParameters> {
88    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField> {
89        mina_poseidon::pasta::fq_kimchi::static_params()
90    }
91
92    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField> {
93        mina_poseidon::pasta::fp_kimchi::static_params()
94    }
95
96    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
97        pallas_endos()
98    }
99
100    fn other_curve_endo() -> &'static Self::ScalarField {
101        &vesta_endos().0
102    }
103
104    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
105        Affine::<VestaParameters>::generator()
106            .to_coordinates()
107            .unwrap()
108    }
109}
110
111//
112// Legacy curves
113//
114
115impl KimchiCurve for Affine<LegacyVestaParameters> {
116    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField> {
117        mina_poseidon::pasta::fp_legacy::static_params()
118    }
119
120    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField> {
121        mina_poseidon::pasta::fq_legacy::static_params()
122    }
123
124    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
125        vesta_endos()
126    }
127
128    fn other_curve_endo() -> &'static Self::ScalarField {
129        &pallas_endos().0
130    }
131
132    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
133        Affine::<PallasParameters>::generator()
134            .to_coordinates()
135            .unwrap()
136    }
137}
138
139impl KimchiCurve for Affine<LegacyPallasParameters> {
140    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField> {
141        mina_poseidon::pasta::fq_legacy::static_params()
142    }
143
144    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField> {
145        mina_poseidon::pasta::fp_legacy::static_params()
146    }
147
148    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
149        pallas_endos()
150    }
151
152    fn other_curve_endo() -> &'static Self::ScalarField {
153        &vesta_endos().0
154    }
155
156    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
157        Affine::<VestaParameters>::generator()
158            .to_coordinates()
159            .unwrap()
160    }
161}
162
163#[cfg(feature = "bn254")]
164use mina_poseidon::dummy_values::kimchi_dummy;
165
166#[cfg(feature = "bn254")]
167impl KimchiCurve for Affine<ark_bn254::g1::Config> {
168    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField> {
169        // TODO: Generate some params
170        static PARAMS: Lazy<ArithmeticSpongeParams<ark_bn254::Fr>> = Lazy::new(kimchi_dummy);
171        &PARAMS
172    }
173
174    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField> {
175        // TODO: Generate some params
176        static PARAMS: Lazy<ArithmeticSpongeParams<ark_bn254::Fq>> = Lazy::new(kimchi_dummy);
177        &PARAMS
178    }
179
180    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
181        static ENDOS: Lazy<(ark_bn254::Fq, ark_bn254::Fr)> =
182            Lazy::new(endos::<ark_bn254::G1Affine>);
183        &ENDOS
184    }
185
186    fn other_curve_endo() -> &'static Self::ScalarField {
187        // TODO: Dummy value, this is definitely not right
188        static ENDO: Lazy<ark_bn254::Fr> = Lazy::new(|| 13u64.into());
189        &ENDO
190    }
191
192    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
193        // TODO: Dummy value, this is definitely not right
194        (44u64.into(), 88u64.into())
195    }
196}