arrabbiata/
curve.rs

1//! This file defines a trait similar to [kimchi::curve::KimchiCurve] for Pallas and
2//! Vesta. It aims to define all the parameters that are needed by a curve to be
3//! used in Arrabbiata. For instance, the sponge parameters, the endomorphism
4//! coefficients, etc.
5//! The goal of this trait is to parametrize the whole library with the
6//! different curves.
7
8use ark_ec::short_weierstrass::{Affine, SWCurveConfig};
9use ark_ff::PrimeField;
10use kimchi::curve::{pallas_endos, vesta_endos};
11use mina_curves::pasta::curves::{pallas::PallasParameters, vesta::VestaParameters};
12use mina_poseidon::{
13    constants::SpongeConstants, poseidon::ArithmeticSpongeParams as SpongeParams, sponge, FqSponge,
14};
15use poly_commitment::commitment::EndoCurve;
16
17const SPONGE_PARAM_FULL_ROUNDS: usize = 60;
18type ArithmeticSpongeParams<F> = SpongeParams<F, 60>;
19type DefaultFqSponge<P, SC> = sponge::DefaultFqSponge<P, SC, SPONGE_PARAM_FULL_ROUNDS>;
20
21#[derive(Clone)]
22pub struct PlonkSpongeConstants {}
23
24impl SpongeConstants for PlonkSpongeConstants {
25    const SPONGE_CAPACITY: usize = 1;
26    const SPONGE_WIDTH: usize = 3;
27    const SPONGE_RATE: usize = 2;
28    const PERM_ROUNDS_FULL: usize = 60;
29    const PERM_ROUNDS_PARTIAL: usize = 0;
30    const PERM_HALF_ROUNDS_FULL: usize = 0;
31    const PERM_SBOX: u32 = 5;
32    const PERM_FULL_MDS: bool = true;
33    const PERM_INITIAL_ARK: bool = false;
34}
35
36/// Represents additional information that a curve needs in order to be used
37/// with Arrabbiata.
38///
39/// The trait [CommitmentCurve](poly_commitment::commitment::CommitmentCurve) enforces the curve to be given in short
40/// Weierstrass form.
41pub trait ArrabbiataCurve: EndoCurve
42where
43    Self::BaseField: PrimeField,
44{
45    /// A human readable name.
46    const NAME: &'static str;
47
48    // FIXME: use this in the codebase.
49    // We might want to use different sponge constants for different curves.
50    // For now, it does use the same constants for both curves.
51    type SpongeConstants: SpongeConstants;
52
53    const SPONGE_CONSTANTS: Self::SpongeConstants;
54
55    /// Provides the sponge params to be used with this curve.
56    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField>;
57
58    /// Provides the sponge params to be used with the other curve.
59    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField>;
60
61    /// Provides the coefficients for the curve endomorphism, called (q,r) in
62    /// some places.
63    fn endos() -> &'static (Self::BaseField, Self::ScalarField);
64
65    /// Provides the coefficient for the curve endomorphism over the other
66    /// field, called q in some places.
67    fn other_curve_endo() -> &'static Self::ScalarField;
68
69    /// Return the coefficients `a` and `b` of the equation
70    /// `y^2 = x^3 + a x + b` defining the curve.
71    fn get_curve_params() -> (Self::BaseField, Self::BaseField);
72
73    /// Create a new sponge, with an empty state (i.e. initialized to zero).
74    fn create_new_sponge() -> DefaultFqSponge<Self::Params, Self::SpongeConstants>;
75
76    /// Absorb an element of the base field into the sponge.
77    ///
78    /// This method is supposed to be an alias to `sponge.absorb_fq(&[fq])`.
79    /// However, it seems that the compiler requests some additional type
80    /// constraints if there is generic code over the trait `ArrabbiataCurve`.
81    fn absorb_fq(
82        sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
83        fq: Self::BaseField,
84    );
85
86    /// Absorb a list of curve points into the sponge.
87    ///
88    /// This method is supposed to be an alias to `sponge.absorb_g(&[gs])`.
89    /// However, it seems that the compiler requests some additional type
90    /// constraints if there is generic code over the trait `ArrabbiataCurve`.
91    fn absorb_curve_points(
92        sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
93        comms: &[Self],
94    );
95
96    /// Coin a challenge from the sponge.
97    /// Note that a challenge set might not be covering the whole set the scalar
98    /// field is defined on.
99    ///
100    /// In particular, for the Pasta curves, a 128-bits value is expected as an
101    /// output.
102    ///
103    /// This method is supposed to be an alias to `sponge.challenge()`.
104    /// However, it seems that the compiler requests some additional type
105    /// constraints if there is generic code over the trait `ArrabbiataCurve`.
106    fn squeeze_challenge(
107        sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
108    ) -> Self::ScalarField;
109}
110
111impl ArrabbiataCurve for Affine<PallasParameters> {
112    const NAME: &'static str = "pallas";
113
114    type SpongeConstants = PlonkSpongeConstants;
115
116    const SPONGE_CONSTANTS: Self::SpongeConstants = PlonkSpongeConstants {};
117
118    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField> {
119        crate::poseidon_3_60_0_5_5_fq::static_params()
120    }
121
122    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField> {
123        crate::poseidon_3_60_0_5_5_fp::static_params()
124    }
125
126    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
127        pallas_endos()
128    }
129
130    fn other_curve_endo() -> &'static Self::ScalarField {
131        &vesta_endos().0
132    }
133
134    fn get_curve_params() -> (Self::BaseField, Self::BaseField) {
135        (PallasParameters::COEFF_A, PallasParameters::COEFF_B)
136    }
137
138    fn create_new_sponge() -> DefaultFqSponge<Self::Params, Self::SpongeConstants> {
139        let sponge: DefaultFqSponge<PallasParameters, PlonkSpongeConstants> =
140            DefaultFqSponge::new(Self::other_curve_sponge_params());
141        sponge
142    }
143
144    fn absorb_fq(
145        sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
146        fq: Self::BaseField,
147    ) {
148        sponge.absorb_fq(&[fq])
149    }
150
151    fn absorb_curve_points(
152        sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
153        comms: &[Self],
154    ) {
155        sponge.absorb_g(comms)
156    }
157
158    fn squeeze_challenge(
159        sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
160    ) -> Self::ScalarField {
161        // This gives a 128 bits value.
162        sponge.challenge()
163    }
164}
165
166impl ArrabbiataCurve for Affine<VestaParameters> {
167    const NAME: &'static str = "vesta";
168
169    type SpongeConstants = PlonkSpongeConstants;
170
171    const SPONGE_CONSTANTS: Self::SpongeConstants = PlonkSpongeConstants {};
172
173    fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField> {
174        crate::poseidon_3_60_0_5_5_fp::static_params()
175    }
176
177    fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField> {
178        crate::poseidon_3_60_0_5_5_fq::static_params()
179    }
180
181    fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
182        vesta_endos()
183    }
184
185    fn other_curve_endo() -> &'static Self::ScalarField {
186        &pallas_endos().0
187    }
188
189    fn get_curve_params() -> (Self::BaseField, Self::BaseField) {
190        (VestaParameters::COEFF_A, VestaParameters::COEFF_B)
191    }
192
193    fn create_new_sponge() -> DefaultFqSponge<Self::Params, Self::SpongeConstants> {
194        let sponge: DefaultFqSponge<VestaParameters, PlonkSpongeConstants> =
195            DefaultFqSponge::new(Self::other_curve_sponge_params());
196        sponge
197    }
198
199    fn absorb_fq(
200        sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
201        fq: Self::BaseField,
202    ) {
203        sponge.absorb_fq(&[fq])
204    }
205
206    fn absorb_curve_points(
207        sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
208        comms: &[Self],
209    ) {
210        sponge.absorb_g(comms)
211    }
212
213    fn squeeze_challenge(
214        sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
215    ) -> Self::ScalarField {
216        // This gives a 128 bits value.
217        sponge.challenge()
218    }
219}