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}