proof_of_sql/proof_primitive/dory/
dynamic_dory_commitment.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! Module containing the `DoryCommitment` type and its implementation.
//!
//! While this can be used as a black box, it can be helpful to understand the underlying structure of the commitment.
//! Ultimately, the commitment is a commitment to a Matrix. This matrix is filled out from a column in the following fashion.
//!
//! We let `sigma` be a parameter that specifies the number of non-zero columns in the matrix.
//! More specifically, the number of non-zero columns is `2^sigma`.
//!
//! For an example, we will set `sigma=2` and thus, the number of columns is 4.
//! The column `[100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115]` with offset 9 is converted to the following matrix:
//! ```ignore
//!  0   0   0   0
//!  0   0   0   0
//!  0  100 101 102
//! 103 104 105 106
//! 107 108 109 110
//! 111 112 113 114
//! 115  0   0   0
//! ```
//! This matrix is then committed to using a matrix commitment.
//!
//! Note: the `VecCommitmentExt` trait requires using this offset when computing commitments.
//! This is to allow for updateability of the commitments as well as to allow for smart indexing/partitioning.

use super::{DoryScalar, ProverSetup, GT};
use crate::base::{
    commitment::{Commitment, CommittableColumn},
    impl_serde_for_ark_serde_checked,
};
use alloc::vec::Vec;
use ark_ec::pairing::PairingOutput;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use core::ops::Mul;
use derive_more::{AddAssign, Neg, Sub, SubAssign};
use num_traits::One;

#[derive(
    Debug,
    Sub,
    Eq,
    PartialEq,
    Neg,
    Copy,
    Clone,
    AddAssign,
    SubAssign,
    CanonicalSerialize,
    CanonicalDeserialize,
)]
/// The Dory commitment type.
pub struct DynamicDoryCommitment(pub(super) GT);

/// The default for GT is the the additive identity, but should be the multiplicative identity.
impl Default for DynamicDoryCommitment {
    fn default() -> Self {
        Self(PairingOutput(One::one()))
    }
}

// Traits required for `DoryCommitment` to impl `Commitment`.
impl_serde_for_ark_serde_checked!(DynamicDoryCommitment);
impl Mul<DynamicDoryCommitment> for DoryScalar {
    type Output = DynamicDoryCommitment;
    fn mul(self, rhs: DynamicDoryCommitment) -> Self::Output {
        DynamicDoryCommitment(rhs.0 * self.0)
    }
}
impl<'a> Mul<&'a DynamicDoryCommitment> for DoryScalar {
    type Output = DynamicDoryCommitment;
    fn mul(self, rhs: &'a DynamicDoryCommitment) -> Self::Output {
        DynamicDoryCommitment(rhs.0 * self.0)
    }
}
impl Commitment for DynamicDoryCommitment {
    type Scalar = DoryScalar;
    type PublicSetup<'a> = &'a ProverSetup<'a>;

    fn compute_commitments(
        committable_columns: &[CommittableColumn],
        offset: usize,
        setup: &Self::PublicSetup<'_>,
    ) -> Vec<Self> {
        super::compute_dynamic_dory_commitments(committable_columns, offset, setup)
    }

    fn append_to_transcript(&self, transcript: &mut impl crate::base::proof::Transcript) {
        transcript.extend_canonical_serialize_as_le(&self.0);
    }
}

#[cfg(test)]
mod tests {
    use super::{DynamicDoryCommitment, GT};
    use crate::base::{
        commitment::Commitment,
        proof::{Keccak256Transcript, Transcript},
    };
    use ark_ff::UniformRand;
    use rand::{rngs::StdRng, SeedableRng};

    #[test]
    fn we_can_append_different_dynamic_dory_commitments_and_get_different_transcripts() {
        let mut rng = StdRng::seed_from_u64(42);
        let commitment1 = DynamicDoryCommitment(GT::rand(&mut rng));
        let commitment2 = DynamicDoryCommitment(GT::rand(&mut rng));

        let mut transcript1 = Keccak256Transcript::new();
        let mut transcript2 = Keccak256Transcript::new();

        commitment1.append_to_transcript(&mut transcript1);
        commitment2.append_to_transcript(&mut transcript2);

        assert_ne!(transcript1.challenge_as_le(), transcript2.challenge_as_le());
    }
}