Skip to main content

miden_protocol/protocol_config/
proof_verification.rs

1use alloc::string::ToString;
2use alloc::vec::Vec;
3
4use super::ProtocolConfigError;
5use crate::crypto::SequentialCommit;
6use crate::utils::serde::{
7    ByteReader,
8    ByteWriter,
9    Deserializable,
10    DeserializationError,
11    Serializable,
12};
13use crate::{Felt, Word, ZERO};
14
15// PROOF VERIFICATION CONFIG
16// ================================================================================================
17
18/// The parameters that define which proofs the protocol accepts.
19///
20/// The verifier roots implicitly define which versions of the VM can be used to produce a proof.
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct ProofVerificationConfig {
23    /// The root of the procedure that verifies proofs produced by the VM. The batch kernel uses it
24    /// to verify transaction proofs and the block kernel uses it to verify batch proofs.
25    vm_verifier_root: Word,
26
27    /// The root of the procedure that verifies precompile VM proofs.
28    precompile_verifier_root: Word,
29
30    /// The policy deciding whether a given proof is secure enough to be accepted.
31    security_policy: ProofSecurityPolicy,
32}
33
34impl ProofVerificationConfig {
35    // CONSTRUCTORS
36    // --------------------------------------------------------------------------------------------
37
38    /// Creates a new [`ProofVerificationConfig`] from the provided inputs.
39    pub fn new(
40        vm_verifier_root: Word,
41        precompile_verifier_root: Word,
42        security_policy: ProofSecurityPolicy,
43    ) -> Self {
44        Self {
45            vm_verifier_root,
46            precompile_verifier_root,
47            security_policy,
48        }
49    }
50
51    // PUBLIC ACCESSORS
52    // --------------------------------------------------------------------------------------------
53
54    /// Returns the root of the VM proof verification procedure.
55    pub fn vm_verifier_root(&self) -> Word {
56        self.vm_verifier_root
57    }
58
59    /// Returns the root of the precompile proof verification procedure.
60    pub fn precompile_verifier_root(&self) -> Word {
61        self.precompile_verifier_root
62    }
63
64    /// Returns the [`ProofSecurityPolicy`] of this configuration.
65    pub fn security_policy(&self) -> &ProofSecurityPolicy {
66        &self.security_policy
67    }
68
69    /// Returns a commitment to this configuration.
70    pub fn to_commitment(&self) -> Word {
71        <Self as SequentialCommit>::to_commitment(self)
72    }
73
74    /// Returns the preimage of [`ProofVerificationConfig::to_commitment`] as a sequence of field
75    /// elements.
76    pub fn to_elements(&self) -> Vec<Felt> {
77        <Self as SequentialCommit>::to_elements(self)
78    }
79}
80
81impl SequentialCommit for ProofVerificationConfig {
82    type Commitment = Word;
83
84    fn to_elements(&self) -> Vec<Felt> {
85        [
86            self.vm_verifier_root.as_elements(),
87            self.precompile_verifier_root.as_elements(),
88            &self.security_policy.to_elements(),
89        ]
90        .concat()
91    }
92}
93
94impl Serializable for ProofVerificationConfig {
95    fn write_into<W: ByteWriter>(&self, target: &mut W) {
96        let Self {
97            vm_verifier_root,
98            precompile_verifier_root,
99            security_policy,
100        } = self;
101
102        vm_verifier_root.write_into(target);
103        precompile_verifier_root.write_into(target);
104        security_policy.write_into(target);
105    }
106}
107
108impl Deserializable for ProofVerificationConfig {
109    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
110        let vm_verifier_root = source.read()?;
111        let precompile_verifier_root = source.read()?;
112        let security_policy = source.read()?;
113
114        Ok(Self::new(vm_verifier_root, precompile_verifier_root, security_policy))
115    }
116}
117
118// PROOF SECURITY POLICY
119// ================================================================================================
120
121/// The policy that decides whether a proof is secure enough for the protocol to accept it.
122#[derive(Debug, Clone, PartialEq, Eq)]
123pub struct ProofSecurityPolicy {
124    /// The root of the procedure which computes the security level of a proof in bits from its
125    /// proof parameters.
126    security_estimator_root: Word,
127
128    /// The minimum security in bits that a proof must reach to be accepted.
129    minimum_bits: u8,
130}
131
132impl ProofSecurityPolicy {
133    // CONSTRUCTORS
134    // --------------------------------------------------------------------------------------------
135
136    /// Creates a new [`ProofSecurityPolicy`] from the provided inputs.
137    ///
138    /// # Errors
139    ///
140    /// Returns an error if `minimum_bits` is zero.
141    pub fn new(
142        security_estimator_root: Word,
143        minimum_bits: u8,
144    ) -> Result<Self, ProtocolConfigError> {
145        if minimum_bits == 0 {
146            return Err(ProtocolConfigError::MinimumSecurityBitsMustBeNonZero);
147        }
148
149        Ok(Self { security_estimator_root, minimum_bits })
150    }
151
152    // PUBLIC ACCESSORS
153    // --------------------------------------------------------------------------------------------
154
155    /// Returns the root of the proof security estimator procedure.
156    pub fn security_estimator_root(&self) -> Word {
157        self.security_estimator_root
158    }
159
160    /// Returns the minimum security in bits that a proof must reach to be accepted.
161    pub fn minimum_bits(&self) -> u8 {
162        self.minimum_bits
163    }
164
165    /// Returns this policy as a sequence of field elements, contributed to the preimage of
166    /// [`ProofVerificationConfig::to_commitment`].
167    pub fn to_elements(&self) -> Vec<Felt> {
168        [
169            self.security_estimator_root.as_elements(),
170            &[Felt::from(self.minimum_bits), ZERO, ZERO, ZERO],
171        ]
172        .concat()
173    }
174}
175
176impl Serializable for ProofSecurityPolicy {
177    fn write_into<W: ByteWriter>(&self, target: &mut W) {
178        let Self { security_estimator_root, minimum_bits } = self;
179
180        security_estimator_root.write_into(target);
181        minimum_bits.write_into(target);
182    }
183}
184
185impl Deserializable for ProofSecurityPolicy {
186    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
187        let security_estimator_root = source.read()?;
188        let minimum_bits = source.read()?;
189
190        Self::new(security_estimator_root, minimum_bits)
191            .map_err(|err| DeserializationError::InvalidValue(err.to_string()))
192    }
193}
194
195// TESTS
196// ================================================================================================
197
198#[cfg(test)]
199mod tests {
200    use assert_matches::assert_matches;
201    use miden_crypto::rand::test_utils::rand_value;
202
203    use super::*;
204
205    fn config() -> ProofVerificationConfig {
206        let policy = ProofSecurityPolicy::new(rand_value::<Word>(), 96).unwrap();
207        ProofVerificationConfig::new(rand_value::<Word>(), rand_value::<Word>(), policy)
208    }
209
210    #[test]
211    fn to_elements_is_pipeable() {
212        // The kernel pipes the protocol config into memory, which requires the element count of
213        // every nested preimage to be a multiple of the hasher's rate width.
214        assert_eq!(config().to_elements().len(), 16);
215    }
216
217    #[test]
218    fn new_rejects_zero_minimum_bits() {
219        let error = ProofSecurityPolicy::new(Word::empty(), 0).unwrap_err();
220        assert_matches!(error, ProtocolConfigError::MinimumSecurityBitsMustBeNonZero);
221    }
222
223    #[test]
224    fn serde_round_trip() -> anyhow::Result<()> {
225        let config = config();
226
227        let deserialized = ProofVerificationConfig::read_from_bytes(&config.to_bytes())?;
228        assert_eq!(config, deserialized);
229
230        Ok(())
231    }
232}