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::poseidon::ArithmeticSpongeParams;
13use once_cell::sync::Lazy;
14use poly_commitment::{
15 commitment::{CommitmentCurve, EndoCurve},
16 ipa::endos,
17};
18
19pub trait KimchiCurve: CommitmentCurve + EndoCurve + NamedCurve {
22 fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField>;
24
25 fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField>;
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 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
111impl 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 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 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 static ENDO: Lazy<ark_bn254::Fr> = Lazy::new(|| 13u64.into());
189 &ENDO
190 }
191
192 fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField) {
193 (44u64.into(), 88u64.into())
195 }
196}