sonobe_primitives/commitments/
mod.rs1use ark_ff::UniformRand;
4use ark_r1cs_std::{GR1CSVar, alloc::AllocVar, fields::fp::FpVar, select::CondSelectGadget};
5use ark_relations::gr1cs::SynthesisError;
6use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
7use ark_std::{
8 fmt::Debug,
9 iter::Sum,
10 ops::{Add, Mul},
11 rand::RngCore,
12};
13use thiserror::Error;
14
15use crate::{
16 algebra::{
17 Val,
18 field::{TwoStageFieldVar, emulated::EmulatedFieldVar},
19 group::emulated::EmulatedAffineVar,
20 ops::bits::FromBitsGadget,
21 },
22 traits::{CF1, CF2, SonobeCurve, SonobeField},
23 transcripts::{Absorbable, AbsorbableVar},
24};
25
26pub mod pedersen;
27#[derive(Debug, Error)]
31pub enum Error {
32 #[error(
35 "The message being committed to has length {1}, exceeding the maximum supported length ({0})"
36 )]
37 MessageTooLong(usize, usize),
38 #[error("Commitment verification failed")]
41 CommitmentVerificationFail,
42}
43
44pub trait CommitmentKey: Clone + Send + Sync + CanonicalSerialize + CanonicalDeserialize {
47 fn max_scalars_len(&self) -> usize;
50}
51
52pub trait CommitmentDef: 'static + Clone + Debug + PartialEq + Eq {
56 const IS_HIDING: bool;
59
60 type Key: CommitmentKey;
62 type Scalar: Clone + Copy + Default + Debug + PartialEq + Eq + Sync + Absorbable + UniformRand;
67 type Commitment: Clone + Default + Debug + PartialEq + Eq + Sync + Absorbable;
73 type Randomness: Clone
83 + Copy
84 + Default
85 + Debug
86 + PartialEq
87 + Eq
88 + Sync
89 + Add<Self::Scalar, Output = Self::Randomness>
90 + Mul<Self::Scalar, Output = Self::Randomness>
91 + for<'a> Add<&'a Self::Scalar, Output = Self::Randomness>
92 + for<'a> Mul<&'a Self::Scalar, Output = Self::Randomness>
93 + Add<Output = Self::Randomness>
94 + Mul<Output = Self::Randomness>
95 + Sum;
96}
97
98pub trait CommitmentOps: CommitmentDef {
100 fn generate_key(len: usize, rng: impl RngCore) -> Result<Self::Key, Error>;
105
106 fn commit(
111 ck: &Self::Key,
112 v: &[Self::Scalar],
113 rng: impl RngCore,
114 ) -> Result<(Self::Commitment, Self::Randomness), Error>;
115
116 fn open(
121 ck: &Self::Key,
122 v: &[Self::Scalar],
123 r: &Self::Randomness,
124 cm: &Self::Commitment,
125 ) -> Result<(), Error>;
126}
127
128pub trait CommitmentDefGadget: Clone {
131 type ConstraintField: SonobeField;
134
135 type KeyVar: AllocVar<<Self::Widget as CommitmentDef>::Key, Self::ConstraintField>;
138 type ScalarVar: AbsorbableVar<Self::ConstraintField>
141 + CondSelectGadget<Self::ConstraintField>
142 + FromBitsGadget<Self::ConstraintField>
143 + AllocVar<<Self::Widget as CommitmentDef>::Scalar, Self::ConstraintField>
144 + GR1CSVar<Self::ConstraintField, Value = <Self::Widget as CommitmentDef>::Scalar>
145 + TwoStageFieldVar;
146 type CommitmentVar: Clone
149 + AbsorbableVar<Self::ConstraintField>
150 + CondSelectGadget<Self::ConstraintField>
151 + AllocVar<<Self::Widget as CommitmentDef>::Commitment, Self::ConstraintField>
152 + GR1CSVar<Self::ConstraintField, Value = <Self::Widget as CommitmentDef>::Commitment>;
153 type RandomnessVar: AllocVar<<Self::Widget as CommitmentDef>::Randomness, Self::ConstraintField>
156 + GR1CSVar<Self::ConstraintField, Value = <Self::Widget as CommitmentDef>::Randomness>;
157
158 type Widget: CommitmentDef;
161}
162
163pub trait CommitmentOpsGadget: CommitmentDefGadget<Widget: CommitmentOps> {
166 fn open(
169 ck: &Self::KeyVar,
170 v: &[Self::ScalarVar],
171 r: &Self::RandomnessVar,
172 cm: &Self::CommitmentVar,
173 ) -> Result<(), SynthesisError>;
174}
175
176pub trait GroupBasedCommitment:
179 CommitmentDef<Commitment: SonobeCurve, Scalar = CF1<<Self as CommitmentDef>::Commitment>>
180 + CommitmentOps
181{
182 type Gadget1: CommitmentOpsGadget
185 + CommitmentDefGadget<
186 ConstraintField = CF2<Self::Commitment>,
187 ScalarVar = EmulatedFieldVar<CF2<Self::Commitment>, Self::Scalar>,
188 CommitmentVar = <Self::Commitment as Val>::Var,
189 Widget = Self,
190 >;
191 type Gadget2: CommitmentDefGadget<
194 ConstraintField = Self::Scalar,
195 ScalarVar = FpVar<Self::Scalar>,
196 CommitmentVar = EmulatedAffineVar<Self::Scalar, Self::Commitment>,
197 Widget = Self,
198 >;
199}
200
201#[cfg(test)]
202mod tests {
203 use ark_ff::UniformRand;
204 use ark_relations::gr1cs::ConstraintSystem;
205 use ark_std::error::Error;
206
207 use super::*;
208
209 pub fn test_commitment_correctness<CM: CommitmentOps>(
210 mut rng: impl RngCore,
211 len: usize,
212 ) -> Result<(), Box<dyn Error>> {
213 let v = (0..len)
214 .map(|_| CM::Scalar::rand(&mut rng))
215 .collect::<Vec<_>>();
216
217 let ck = CM::generate_key(len, &mut rng)?;
218 let (cm, r) = CM::commit(&ck, &v, &mut rng)?;
219 CM::open(&ck, &v, &r, &cm)?;
220 Ok(())
221 }
222
223 pub fn test_commitment_gadget_correctness<CM: CommitmentOpsGadget>(
224 mut rng: impl RngCore,
225 len: usize,
226 ) -> Result<(), Box<dyn Error>> {
227 let v = (0..len)
228 .map(|_| UniformRand::rand(&mut rng))
229 .collect::<Vec<_>>();
230
231 let ck = CM::Widget::generate_key(len, &mut rng)?;
232 let (cm, r) = CM::Widget::commit(&ck, &v, &mut rng)?;
233
234 let cs = ConstraintSystem::new_ref();
235
236 let v_var = Vec::new_witness(cs.clone(), || Ok(v))?;
237 let r_var = AllocVar::new_witness(cs.clone(), || Ok(r))?;
238 let ck_var = AllocVar::new_constant(cs.clone(), ck)?;
239 let cm_var = AllocVar::new_witness(cs.clone(), || Ok(cm))?;
240
241 CM::open(&ck_var, &v_var, &r_var, &cm_var)?;
242
243 assert!(cs.is_satisfied()?);
244
245 Ok(())
246 }
247}