use std::{fmt::Debug, marker::PhantomData}; use crate::crh::{ FixedLengthCRHGadget, injective_map::{InjectiveMap, PedersenCRHCompressor, TECompressor}, pedersen::{ PedersenWindow, constraints::{PedersenCRHGadget, PedersenCRHGadgetParameters}, } }; use algebra::{ curves::{ models::{ModelParameters, TEModelParameters}, twisted_edwards_extended::{GroupAffine as TEAffine, GroupProjective as TEProjective}, }, fields::{Field, PrimeField, SquareRootField}, groups::Group, }; use r1cs_core::{ConstraintSystem, SynthesisError}; use r1cs_std::{ fields::fp::FpGadget, groups::{curves::twisted_edwards::AffineGadget as TwistedEdwardsGadget, GroupGadget}, prelude::*, }; pub trait InjectiveMapGadget, ConstraintF: Field, GG: GroupGadget> { type OutputGadget: EqGadget + ToBytesGadget + CondSelectGadget + AllocGadget + Debug + Clone + Sized; fn evaluate_map>( cs: CS, ge: &GG, ) -> Result; } pub struct TECompressorGadget; impl InjectiveMapGadget, TECompressor, ConstraintF, TwistedEdwardsGadget>> for TECompressorGadget where ConstraintF: PrimeField + SquareRootField, P: TEModelParameters + ModelParameters, { type OutputGadget = FpGadget; fn evaluate_map>( _cs: CS, ge: &TwistedEdwardsGadget>, ) -> Result { Ok(ge.x.clone()) } } impl InjectiveMapGadget, TECompressor, ConstraintF, TwistedEdwardsGadget>> for TECompressorGadget where ConstraintF: PrimeField + SquareRootField, P: TEModelParameters + ModelParameters, { type OutputGadget = FpGadget; fn evaluate_map>( _cs: CS, ge: &TwistedEdwardsGadget>, ) -> Result { Ok(ge.x.clone()) } } pub struct PedersenCRHCompressorGadget where G: Group, I: InjectiveMap, ConstraintF: Field, GG: GroupGadget, IG: InjectiveMapGadget, { _compressor: PhantomData, _compressor_gadget: PhantomData, _crh: PedersenCRHGadget, } impl FixedLengthCRHGadget, ConstraintF> for PedersenCRHCompressorGadget where G: Group, I: InjectiveMap, ConstraintF: Field, GG: GroupGadget, IG: InjectiveMapGadget, W: PedersenWindow, { type OutputGadget = IG::OutputGadget; type ParametersGadget = PedersenCRHGadgetParameters; fn check_evaluation_gadget>( mut cs: CS, parameters: &Self::ParametersGadget, input: &[UInt8], ) -> Result { let result = PedersenCRHGadget::::check_evaluation_gadget( cs.ns(|| "PedCRH"), parameters, input, )?; IG::evaluate_map(cs.ns(|| "InjectiveMap"), &result) } }