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 once_cell::sync::Lazy;
14use poly_commitment::{
15 commitment::{CommitmentCurve, EndoCurve},
16 ipa::endos,
17};
18
19pub trait KimchiCurve<const FULL_ROUNDS: usize>: EndoCurve + NamedCurve {
22 fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField, FULL_ROUNDS>;
24
25 fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField, FULL_ROUNDS>;
27
28 fn endos() -> &'static (Self::BaseField, Self::ScalarField);
31
32 fn other_curve_endo() -> &'static Self::ScalarField;
35
36 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
113impl 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 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 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 static ENDO: Lazy<ark_bn254::Fr> = Lazy::new(|| 13u64.into());
202 &ENDO
203 }
204
205 fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
206 (44u64.into(), 88u64.into())
208 }
209}