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