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 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<const FULL_ROUNDS: usize>: EndoCurve + NamedCurve {
22    /// Provides the sponge params to be used with this curve.
23    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField, FULL_ROUNDS>;
24
25    /// Provides the sponge params to be used with the other curve.
26    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField, FULL_ROUNDS>;
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<FULL_ROUNDS> for Affine<VestaParameters> {
64    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField, FULL_ROUNDS> {
65        mina_poseidon::pasta::fp_kimchi::static_params()
66    }
67
68    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField, FULL_ROUNDS>
69    {
70        mina_poseidon::pasta::fq_kimchi::static_params()
71    }
72
73    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
74        vesta_endos()
75    }
76
77    fn other_curve_endo() -> &'static Self::ScalarField {
78        &pallas_endos().0
79    }
80
81    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
82        Affine::<PallasParameters>::generator()
83            .to_coordinates()
84            .unwrap()
85    }
86}
87
88impl KimchiCurve<FULL_ROUNDS> for Affine<PallasParameters> {
89    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField, FULL_ROUNDS> {
90        mina_poseidon::pasta::fq_kimchi::static_params()
91    }
92
93    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField, FULL_ROUNDS>
94    {
95        mina_poseidon::pasta::fp_kimchi::static_params()
96    }
97
98    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
99        pallas_endos()
100    }
101
102    fn other_curve_endo() -> &'static Self::ScalarField {
103        &vesta_endos().0
104    }
105
106    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
107        Affine::<VestaParameters>::generator()
108            .to_coordinates()
109            .unwrap()
110    }
111}
112
113//
114// Legacy curves
115//
116
117impl KimchiCurve<{ mina_poseidon::pasta::LEGACY_ROUNDS }> for Affine<LegacyVestaParameters> {
118    fn sponge_params(
119    ) -> &'static ArithmeticSpongeParams<Self::ScalarField, { mina_poseidon::pasta::LEGACY_ROUNDS }>
120    {
121        mina_poseidon::pasta::fp_legacy::static_params()
122    }
123
124    fn other_curve_sponge_params(
125    ) -> &'static ArithmeticSpongeParams<Self::BaseField, { mina_poseidon::pasta::LEGACY_ROUNDS }>
126    {
127        mina_poseidon::pasta::fq_legacy::static_params()
128    }
129
130    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
131        vesta_endos()
132    }
133
134    fn other_curve_endo() -> &'static Self::ScalarField {
135        &pallas_endos().0
136    }
137
138    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
139        Affine::<PallasParameters>::generator()
140            .to_coordinates()
141            .unwrap()
142    }
143}
144
145impl KimchiCurve<{ mina_poseidon::pasta::LEGACY_ROUNDS }> for Affine<LegacyPallasParameters> {
146    fn sponge_params(
147    ) -> &'static ArithmeticSpongeParams<Self::ScalarField, { mina_poseidon::pasta::LEGACY_ROUNDS }>
148    {
149        mina_poseidon::pasta::fq_legacy::static_params()
150    }
151
152    fn other_curve_sponge_params(
153    ) -> &'static ArithmeticSpongeParams<Self::BaseField, { mina_poseidon::pasta::LEGACY_ROUNDS }>
154    {
155        mina_poseidon::pasta::fp_legacy::static_params()
156    }
157
158    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
159        pallas_endos()
160    }
161
162    fn other_curve_endo() -> &'static Self::ScalarField {
163        &vesta_endos().0
164    }
165
166    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
167        Affine::<VestaParameters>::generator()
168            .to_coordinates()
169            .unwrap()
170    }
171}
172
173#[cfg(feature = "bn254")]
174use mina_poseidon::dummy_values::kimchi_dummy;
175
176#[cfg(feature = "bn254")]
177impl KimchiCurve<FULL_ROUNDS> for Affine<ark_bn254::g1::Config> {
178    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField, FULL_ROUNDS> {
179        // TODO: Generate some params
180        static PARAMS: Lazy<ArithmeticSpongeParams<ark_bn254::Fr, FULL_ROUNDS>> =
181            Lazy::new(kimchi_dummy);
182        &PARAMS
183    }
184
185    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField, FULL_ROUNDS>
186    {
187        // TODO: Generate some params
188        static PARAMS: Lazy<ArithmeticSpongeParams<ark_bn254::Fq, FULL_ROUNDS>> =
189            Lazy::new(kimchi_dummy);
190        &PARAMS
191    }
192
193    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
194        static ENDOS: Lazy<(ark_bn254::Fq, ark_bn254::Fr)> =
195            Lazy::new(endos::<ark_bn254::G1Affine>);
196        &ENDOS
197    }
198
199    fn other_curve_endo() -> &'static Self::ScalarField {
200        // TODO: Dummy value, this is definitely not right
201        static ENDO: Lazy<ark_bn254::Fr> = Lazy::new(|| 13u64.into());
202        &ENDO
203    }
204
205    fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
206        // TODO: Dummy value, this is definitely not right
207        (44u64.into(), 88u64.into())
208    }
209}