Skip to main content

nova_snark/traits/
commitment.rs

1//! This module defines a collection of traits that define the behavior of a commitment engine
2//! We require the commitment engine to provide a commitment to vectors with a single group element
3#[cfg(feature = "io")]
4use crate::provider::ptau::PtauFileError;
5use crate::traits::{AbsorbInRO2Trait, AbsorbInROTrait, Engine, TranscriptReprTrait};
6use core::{
7  fmt::Debug,
8  ops::{Add, Mul, MulAssign, Range},
9};
10use num_integer::Integer;
11use num_traits::ToPrimitive;
12use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
13use serde::{Deserialize, Serialize};
14
15/// A helper trait for types implementing scalar multiplication.
16pub trait ScalarMul<Rhs, Output = Self>: Mul<Rhs, Output = Output> + MulAssign<Rhs> {}
17
18impl<T, Rhs, Output> ScalarMul<Rhs, Output> for T where T: Mul<Rhs, Output = Output> + MulAssign<Rhs>
19{}
20
21/// This trait defines the behavior of the commitment
22pub trait CommitmentTrait<E: Engine>:
23  Clone
24  + Copy
25  + Debug
26  + Default
27  + PartialEq
28  + Eq
29  + Send
30  + Sync
31  + TranscriptReprTrait<E::GE>
32  + Serialize
33  + for<'de> Deserialize<'de>
34  + AbsorbInROTrait<E>
35  + AbsorbInRO2Trait<E>
36  + Add<Self, Output = Self>
37  + ScalarMul<E::Scalar>
38{
39  /// Returns the coordinate representation of the commitment
40  fn to_coordinates(&self) -> (E::Base, E::Base, bool);
41}
42
43/// A trait that helps determine the length of a structure.
44/// Note this does not impose any memory representation constraints on the structure.
45pub trait Len {
46  /// Returns the length of the structure.
47  fn length(&self) -> usize;
48}
49
50/// A trait that ties different pieces of the commitment generation together
51pub trait CommitmentEngineTrait<E: Engine>: Clone + Send + Sync {
52  /// Holds the type of the commitment key
53  /// The key should quantify its length in terms of group generators.
54  type CommitmentKey: Len + Clone + Debug + Send + Sync + Serialize + for<'de> Deserialize<'de>;
55
56  /// Holds the type of the derandomization key
57  type DerandKey: Clone + Debug + Send + Sync + Serialize + for<'de> Deserialize<'de>;
58
59  /// Holds the type of the commitment
60  type Commitment: CommitmentTrait<E>;
61
62  /// Load keys
63  #[cfg(feature = "io")]
64  fn load_setup(
65    reader: &mut (impl std::io::Read + std::io::Seek),
66    label: &'static [u8],
67    n: usize,
68  ) -> Result<Self::CommitmentKey, PtauFileError>;
69
70  /// Saves the key to the provided writer.
71  #[cfg(feature = "io")]
72  fn save_setup(
73    ck: &Self::CommitmentKey,
74    writer: &mut (impl std::io::Write + std::io::Seek),
75  ) -> Result<(), PtauFileError>;
76
77  /// Samples a new commitment key of a specified size.
78  ///
79  /// # Errors
80  ///
81  /// Returns an error if the setup cannot be performed (e.g., HyperKZG in production
82  /// builds without the `test-utils` feature).
83  fn setup(label: &'static [u8], n: usize)
84    -> Result<Self::CommitmentKey, crate::errors::NovaError>;
85
86  /// Extracts the blinding generator
87  fn derand_key(ck: &Self::CommitmentKey) -> Self::DerandKey;
88
89  /// Commits to the provided vector using the provided generators and random blind
90  fn commit(ck: &Self::CommitmentKey, v: &[E::Scalar], r: &E::Scalar) -> Self::Commitment;
91
92  /// Batch commits to the provided vectors using the provided generators and random blind
93  fn batch_commit(
94    ck: &Self::CommitmentKey,
95    v: &[Vec<E::Scalar>],
96    r: &[E::Scalar],
97  ) -> Vec<Self::Commitment> {
98    assert!(v.len() == r.len());
99    v.par_iter()
100      .zip(r.par_iter())
101      .map(|(v_i, r_i)| Self::commit(ck, v_i, r_i))
102      .collect()
103  }
104
105  /// Commits to the provided vector of sparse binary scalars using the provided generators and random blind
106  fn commit_sparse_binary(
107    ck: &Self::CommitmentKey,
108    non_zero_indices: &[usize],
109    r: &E::Scalar,
110  ) -> Self::Commitment;
111
112  /// Commits to the provided vector of "small" scalars (at most 64 bits) using the provided generators and random blind
113  fn commit_small<T: Integer + Into<u64> + Copy + Sync + ToPrimitive>(
114    ck: &Self::CommitmentKey,
115    v: &[T],
116    r: &E::Scalar,
117  ) -> Self::Commitment;
118
119  /// Commits to the provided vector of "small" scalars (at most 64 bits) using the provided generators and random blind (range)
120  fn commit_small_range<T: Integer + Into<u64> + Copy + Sync + ToPrimitive>(
121    ck: &Self::CommitmentKey,
122    v: &[T],
123    r: &E::Scalar,
124    range: Range<usize>,
125    max_num_bits: usize,
126  ) -> Self::Commitment;
127
128  /// Batch commits to the provided vectors of "small" scalars (at most 64 bits) using the provided generators and random blind
129  fn batch_commit_small<T: Integer + Into<u64> + Copy + Sync + ToPrimitive>(
130    ck: &Self::CommitmentKey,
131    v: &[Vec<T>],
132    r: &[E::Scalar],
133  ) -> Vec<Self::Commitment> {
134    assert!(v.len() == r.len());
135    v.par_iter()
136      .zip(r.par_iter())
137      .map(|(v_i, r_i)| Self::commit_small(ck, v_i, r_i))
138      .collect()
139  }
140
141  /// Remove given blind from commitment
142  fn derandomize(
143    dk: &Self::DerandKey,
144    commit: &Self::Commitment,
145    r: &E::Scalar,
146  ) -> Self::Commitment;
147
148  /// Returns the coordinates of each generator in the commitment key.
149  ///
150  /// This method extracts the (x, y) coordinates of each generator point
151  /// in the commitment key. This is useful for operations that need direct
152  /// access to the underlying elliptic curve points, such as in-circuit
153  /// verification of polynomial evaluations.
154  ///
155  /// # Panics
156  ///
157  /// Panics if any generator point is the point at infinity.
158  fn ck_to_coordinates(ck: &Self::CommitmentKey) -> Vec<(E::Base, E::Base)>;
159
160  /// Returns the generators as projective group elements.
161  ///
162  /// This provides full group-operation access (add, double, scalar mul)
163  /// on the commitment key generators, useful for precomputing correction
164  /// points in circuit optimizations.
165  fn ck_to_group_elements(ck: &Self::CommitmentKey) -> Vec<E::GE>;
166}