proof_of_sql/base/commitment/
mod.rs

1//! Types for creation and utilization of cryptographic commitments to proof-of-sql data.
2use crate::base::scalar::Scalar;
3use alloc::vec::Vec;
4#[cfg(feature = "blitzar")]
5pub use blitzar::{
6    compute::{init_backend, init_backend_with_config, BackendConfig},
7    proof::InnerProductProof,
8};
9use core::ops::{AddAssign, SubAssign};
10use curve25519_dalek::ristretto::RistrettoPoint;
11
12mod committable_column;
13pub use committable_column::CommittableColumn;
14
15mod vec_commitment_ext;
16pub use vec_commitment_ext::{NumColumnsMismatch, VecCommitmentExt};
17
18mod column_bounds;
19use super::scalar::Curve25519Scalar;
20pub use column_bounds::{Bounds, ColumnBounds, NegativeBounds};
21
22mod column_commitment_metadata;
23pub use column_commitment_metadata::ColumnCommitmentMetadata;
24
25mod column_commitment_metadata_map;
26pub use column_commitment_metadata_map::{
27    ColumnCommitmentMetadataMap, ColumnCommitmentMetadataMapExt, ColumnCommitmentsMismatch,
28};
29
30mod column_commitments;
31pub use column_commitments::{AppendColumnCommitmentsError, ColumnCommitments, DuplicateIdents};
32
33mod table_commitment;
34pub use table_commitment::{
35    AppendTableCommitmentError, MixedLengthColumns, NegativeRange, TableCommitment,
36    TableCommitmentArithmeticError, TableCommitmentFromColumnsError,
37};
38
39mod query_commitments;
40pub use query_commitments::{QueryCommitments, QueryCommitmentsExt};
41
42/// Module for providing a mock commitment.
43#[cfg(test)]
44pub mod naive_commitment;
45
46/// Module for providing a test commitment evaluation proof.
47#[cfg(test)]
48pub mod naive_evaluation_proof;
49
50#[cfg(test)]
51mod naive_commitment_test;
52
53/// A trait for using commitment schemes generically.
54pub trait Commitment:
55    AddAssign
56    + SubAssign
57    + Sized
58    + Default
59    + Clone
60    + core::ops::Neg<Output = Self>
61    + Eq
62    + core::ops::Sub<Output = Self>
63    + core::fmt::Debug
64    + core::marker::Sync
65    + core::marker::Send
66{
67    /// The associated scalar that the commitment is for.
68    /// There are multiple possible commitment schemes for a scalar, but only one scalar for any commitment.
69    type Scalar: Scalar
70        + for<'a> core::ops::Mul<&'a Self, Output = Self>
71        + core::ops::Mul<Self, Output = Self>
72        + serde::Serialize
73        + for<'a> serde::Deserialize<'a>;
74
75    /// The public setup for the commitment scheme.
76    type PublicSetup<'a>;
77
78    /// Compute the commitments for the given columns.
79    ///
80    /// The resulting commitments are written to the slice in `commitments`, which is a buffer.
81    /// `commitments` is expected to have the same length as `committable_columns` and the behavior is undefined if it does not.
82    /// The length of each [`CommittableColumn`] should be the same.
83    ///
84    /// `offset` is the amount that `committable_columns` is "offset" by. Logically adding `offset` many 0s to the beginning of each of the `committable_columns`.
85    fn compute_commitments(
86        committable_columns: &[CommittableColumn],
87        offset: usize,
88        setup: &Self::PublicSetup<'_>,
89    ) -> Vec<Self>;
90
91    /// Converts the commitment to bytes that will be appended to the transcript.
92    ///
93    /// This is also useful for serialization purposes.
94    fn to_transcript_bytes(&self) -> Vec<u8>;
95}
96
97impl Commitment for RistrettoPoint {
98    type Scalar = Curve25519Scalar;
99    type PublicSetup<'a> = ();
100    #[cfg(feature = "blitzar")]
101    fn compute_commitments(
102        committable_columns: &[CommittableColumn],
103        offset: usize,
104        _setup: &Self::PublicSetup<'_>,
105    ) -> Vec<Self> {
106        use curve25519_dalek::ristretto::CompressedRistretto;
107
108        let sequences: Vec<_> = committable_columns.iter().map(Into::into).collect();
109        let mut compressed_commitments =
110            vec![CompressedRistretto::default(); committable_columns.len()];
111        blitzar::compute::compute_curve25519_commitments(
112            &mut compressed_commitments,
113            &sequences,
114            offset as u64,
115        );
116        compressed_commitments
117            .into_iter()
118            .map(|cc| {
119                cc.decompress().expect(
120                    "invalid ristretto point decompression in Commitment::compute_commitments",
121                )
122            })
123            .collect()
124    }
125    #[cfg(not(feature = "blitzar"))]
126    fn compute_commitments(
127        _committable_columns: &[CommittableColumn],
128        _offset: usize,
129        _setup: &Self::PublicSetup<'_>,
130    ) -> Vec<Self> {
131        unimplemented!()
132    }
133
134    fn to_transcript_bytes(&self) -> Vec<u8> {
135        self.compress().as_bytes().to_vec()
136    }
137}
138
139mod commitment_evaluation_proof;
140pub use commitment_evaluation_proof::CommitmentEvaluationProof;
141#[cfg(test)]
142pub(crate) mod commitment_evaluation_proof_test;
143
144#[cfg(test)]
145mod tests {
146    use super::*;
147    use curve25519_dalek::{constants::RISTRETTO_BASEPOINT_POINT, ristretto::RistrettoPoint};
148
149    #[test]
150    fn we_get_different_transcript_bytes_from_different_ristretto_point_commitments() {
151        let commitment1 = RistrettoPoint::default();
152        let commitment2 = RISTRETTO_BASEPOINT_POINT;
153
154        assert_ne!(
155            commitment1.to_transcript_bytes(),
156            commitment2.to_transcript_bytes()
157        );
158    }
159}