use ark_ec::short_weierstrass::{Affine, SWCurveConfig};
use ark_ff::PrimeField;
use kimchi::curve::{pallas_endos, vesta_endos};
use mina_curves::pasta::curves::{pallas::PallasParameters, vesta::VestaParameters};
use mina_poseidon::{
constants::SpongeConstants, poseidon::ArithmeticSpongeParams, sponge::DefaultFqSponge, FqSponge,
};
use poly_commitment::commitment::{CommitmentCurve, EndoCurve};
#[derive(Clone)]
pub struct PlonkSpongeConstants {}
impl SpongeConstants for PlonkSpongeConstants {
const SPONGE_CAPACITY: usize = 1;
const SPONGE_WIDTH: usize = 3;
const SPONGE_RATE: usize = 2;
const PERM_ROUNDS_FULL: usize = 60;
const PERM_ROUNDS_PARTIAL: usize = 0;
const PERM_HALF_ROUNDS_FULL: usize = 0;
const PERM_SBOX: u32 = 5;
const PERM_FULL_MDS: bool = true;
const PERM_INITIAL_ARK: bool = false;
}
pub trait ArrabbiataCurve: CommitmentCurve + EndoCurve
where
Self::BaseField: PrimeField,
{
const NAME: &'static str;
type SpongeConstants: SpongeConstants;
const SPONGE_CONSTANTS: Self::SpongeConstants;
fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField>;
fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField>;
fn endos() -> &'static (Self::BaseField, Self::ScalarField);
fn other_curve_endo() -> &'static Self::ScalarField;
fn get_curve_params() -> (Self::BaseField, Self::BaseField);
fn create_new_sponge() -> DefaultFqSponge<Self::Params, Self::SpongeConstants>;
fn absorb_fq(
sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
fq: Self::BaseField,
);
fn absorb_curve_points(
sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
comms: &[Self],
);
fn squeeze_challenge(
sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
) -> Self::ScalarField;
}
impl ArrabbiataCurve for Affine<PallasParameters> {
const NAME: &'static str = "pallas";
type SpongeConstants = PlonkSpongeConstants;
const SPONGE_CONSTANTS: Self::SpongeConstants = PlonkSpongeConstants {};
fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField> {
crate::poseidon_3_60_0_5_5_fq::static_params()
}
fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField> {
crate::poseidon_3_60_0_5_5_fp::static_params()
}
fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
pallas_endos()
}
fn other_curve_endo() -> &'static Self::ScalarField {
&vesta_endos().0
}
fn get_curve_params() -> (Self::BaseField, Self::BaseField) {
(PallasParameters::COEFF_A, PallasParameters::COEFF_B)
}
fn create_new_sponge() -> DefaultFqSponge<Self::Params, Self::SpongeConstants> {
let sponge: DefaultFqSponge<PallasParameters, PlonkSpongeConstants> =
DefaultFqSponge::new(Self::other_curve_sponge_params());
sponge
}
fn absorb_fq(
sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
fq: Self::BaseField,
) {
sponge.absorb_fq(&[fq])
}
fn absorb_curve_points(
sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
comms: &[Self],
) {
sponge.absorb_g(comms)
}
fn squeeze_challenge(
sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
) -> Self::ScalarField {
sponge.challenge()
}
}
impl ArrabbiataCurve for Affine<VestaParameters> {
const NAME: &'static str = "vesta";
type SpongeConstants = PlonkSpongeConstants;
const SPONGE_CONSTANTS: Self::SpongeConstants = PlonkSpongeConstants {};
fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField> {
crate::poseidon_3_60_0_5_5_fp::static_params()
}
fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams<Self::BaseField> {
crate::poseidon_3_60_0_5_5_fq::static_params()
}
fn endos() -> &'static (Self::BaseField, Self::ScalarField) {
vesta_endos()
}
fn other_curve_endo() -> &'static Self::ScalarField {
&pallas_endos().0
}
fn get_curve_params() -> (Self::BaseField, Self::BaseField) {
(VestaParameters::COEFF_A, VestaParameters::COEFF_B)
}
fn create_new_sponge() -> DefaultFqSponge<Self::Params, Self::SpongeConstants> {
let sponge: DefaultFqSponge<VestaParameters, PlonkSpongeConstants> =
DefaultFqSponge::new(Self::other_curve_sponge_params());
sponge
}
fn absorb_fq(
sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
fq: Self::BaseField,
) {
sponge.absorb_fq(&[fq])
}
fn absorb_curve_points(
sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
comms: &[Self],
) {
sponge.absorb_g(comms)
}
fn squeeze_challenge(
sponge: &mut DefaultFqSponge<Self::Params, Self::SpongeConstants>,
) -> Self::ScalarField {
sponge.challenge()
}
}