1use 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
18pub trait KimchiCurve<const FULL_ROUNDS: usize>: EndoCurve + NamedCurve {
21 fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField, FULL_ROUNDS>;
23
24 fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField, FULL_ROUNDS>;
26
27 fn endos() -> &'static (Self::BaseField, Self::ScalarField);
30
31 fn other_curve_endo() -> &'static Self::ScalarField;
34
35 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
112impl 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 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 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 (44u64.into(), 88u64.into())
210 }
211}