arnaucube
arnaucube/sonobePublic Self-hosted repository
sonobe/folding-schemes/src/folding/traits.rs
folding-schemes/src/folding/traits.rsRaw
  1use ark_crypto_primitives::sponge::{
  2    constraints::{AbsorbGadget, CryptographicSpongeVar},
  3    poseidon::constraints::PoseidonSpongeVar,
  4    Absorb,
  5};
  6use ark_ec::CurveGroup;
  7use ark_ff::PrimeField;
  8use ark_r1cs_std::{alloc::AllocVar, fields::fp::FpVar, ToConstraintFieldGadget};
  9use ark_relations::r1cs::SynthesisError;
 10
 11use crate::{transcript::Transcript, Error};
 12
 13use super::circuits::CF1;
 14
 15pub trait CommittedInstanceOps<C: CurveGroup>: Inputize<CF1<C>, Self::Var> {
 16    /// The in-circuit representation of the committed instance.
 17    type Var: AllocVar<Self, CF1<C>> + CommittedInstanceVarOps<C>;
 18    /// `hash` implements the committed instance hash compatible with the
 19    /// in-circuit implementation from `CommittedInstanceVarOps::hash`.
 20    ///
 21    /// Returns `H(i, z_0, z_i, U_i)`, where `i` can be `i` but also `i+1`, and
 22    /// `U_i` is the committed instance `self`.
 23    fn hash<T: Transcript<CF1<C>>>(
 24        &self,
 25        sponge: &T,
 26        pp_hash: CF1<C>, // public params hash
 27        i: CF1<C>,
 28        z_0: &[CF1<C>],
 29        z_i: &[CF1<C>],
 30    ) -> CF1<C>
 31    where
 32        CF1<C>: Absorb,
 33        Self: Sized + Absorb,
 34    {
 35        let mut sponge = sponge.clone();
 36        sponge.absorb(&pp_hash);
 37        sponge.absorb(&i);
 38        sponge.absorb(&z_0);
 39        sponge.absorb(&z_i);
 40        sponge.absorb(&self);
 41        sponge.squeeze_field_elements(1)[0]
 42    }
 43
 44    /// Returns the commitments contained in the committed instance.
 45    fn get_commitments(&self) -> Vec<C>;
 46
 47    /// Returns `true` if the committed instance is an incoming instance, and
 48    /// `false` if it is a running instance.
 49    fn is_incoming(&self) -> bool;
 50
 51    /// Checks if the committed instance is an incoming instance.
 52    fn check_incoming(&self) -> Result<(), Error> {
 53        self.is_incoming()
 54            .then_some(())
 55            .ok_or(Error::NotIncomingCommittedInstance)
 56    }
 57}
 58
 59pub trait CommittedInstanceVarOps<C: CurveGroup> {
 60    type PointVar: ToConstraintFieldGadget<CF1<C>>;
 61    /// `hash` implements the in-circuit committed instance hash compatible with
 62    /// the native implementation from `CommittedInstanceOps::hash`.
 63    /// Returns `H(i, z_0, z_i, U_i)`, where `i` can be `i` but also `i+1`, and
 64    /// `U_i` is the committed instance `self`.
 65    ///
 66    /// Additionally it returns the in-circuit representation of the committed
 67    /// instance `self` as a vector of field elements, so they can be reused in
 68    /// other gadgets avoiding recalculating (reconstraining) them.
 69    #[allow(clippy::type_complexity)]
 70    fn hash(
 71        &self,
 72        sponge: &PoseidonSpongeVar<CF1<C>>,
 73        pp_hash: &FpVar<CF1<C>>,
 74        i: &FpVar<CF1<C>>,
 75        z_0: &[FpVar<CF1<C>>],
 76        z_i: &[FpVar<CF1<C>>],
 77    ) -> Result<(FpVar<CF1<C>>, Vec<FpVar<CF1<C>>>), SynthesisError>
 78    where
 79        Self: AbsorbGadget<CF1<C>>,
 80    {
 81        let mut sponge = sponge.clone();
 82        let U_vec = self.to_sponge_field_elements()?;
 83        sponge.absorb(&pp_hash)?;
 84        sponge.absorb(&i)?;
 85        sponge.absorb(&z_0)?;
 86        sponge.absorb(&z_i)?;
 87        sponge.absorb(&U_vec)?;
 88        Ok((
 89            // `unwrap` is safe because the sponge is guaranteed to return a single element
 90            sponge.squeeze_field_elements(1)?.pop().unwrap(),
 91            U_vec,
 92        ))
 93    }
 94
 95    /// Returns the commitments contained in the committed instance.
 96    fn get_commitments(&self) -> Vec<Self::PointVar>;
 97
 98    /// Returns the public inputs contained in the committed instance.
 99    fn get_public_inputs(&self) -> &[FpVar<CF1<C>>];
100
101    /// Generates constraints to enforce that the committed instance is an
102    /// incoming instance.
103    fn enforce_incoming(&self) -> Result<(), SynthesisError>;
104
105    /// Generates constraints to enforce that the committed instance `self` is
106    /// partially equal to another committed instance `other`.
107    /// Here, only field elements are compared, while commitments (points) are
108    /// not.
109    fn enforce_partial_equal(&self, other: &Self) -> Result<(), SynthesisError>;
110}
111
112pub trait WitnessOps<F: PrimeField> {
113    /// The in-circuit representation of the witness.
114    type Var: AllocVar<Self, F> + WitnessVarOps<F>;
115
116    /// Returns the openings (i.e., the values being committed to and the
117    /// randomness) contained in the witness.
118    fn get_openings(&self) -> Vec<(&[F], F)>;
119}
120
121pub trait WitnessVarOps<F: PrimeField> {
122    /// Returns the openings (i.e., the values being committed to and the
123    /// randomness) contained in the witness.
124    fn get_openings(&self) -> Vec<(&[FpVar<F>], FpVar<F>)>;
125}
126
127pub trait Dummy<Cfg> {
128    fn dummy(cfg: Cfg) -> Self;
129}
130
131impl<T: Default + Clone> Dummy<usize> for Vec<T> {
132    fn dummy(cfg: usize) -> Self {
133        vec![Default::default(); cfg]
134    }
135}
136
137impl<T: Default> Dummy<()> for T {
138    fn dummy(_: ()) -> Self {
139        Default::default()
140    }
141}
142
143/// Converts a value `self` into a vector of field elements, ordered in the same
144/// way as how a variable of type `Var` would be represented in the circuit.
145/// This is useful for the verifier to compute the public inputs.
146pub trait Inputize<F, Var> {
147    fn inputize(&self) -> Vec<F>;
148}