miden_protocol/protocol_config/
proof_verification.rs1use 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#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct ProofVerificationConfig {
23 vm_verifier_root: Word,
26
27 precompile_verifier_root: Word,
29
30 security_policy: ProofSecurityPolicy,
32}
33
34impl ProofVerificationConfig {
35 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 pub fn vm_verifier_root(&self) -> Word {
56 self.vm_verifier_root
57 }
58
59 pub fn precompile_verifier_root(&self) -> Word {
61 self.precompile_verifier_root
62 }
63
64 pub fn security_policy(&self) -> &ProofSecurityPolicy {
66 &self.security_policy
67 }
68
69 pub fn to_commitment(&self) -> Word {
71 <Self as SequentialCommit>::to_commitment(self)
72 }
73
74 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#[derive(Debug, Clone, PartialEq, Eq)]
123pub struct ProofSecurityPolicy {
124 security_estimator_root: Word,
127
128 minimum_bits: u8,
130}
131
132impl ProofSecurityPolicy {
133 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 pub fn security_estimator_root(&self) -> Word {
157 self.security_estimator_root
158 }
159
160 pub fn minimum_bits(&self) -> u8 {
162 self.minimum_bits
163 }
164
165 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#[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 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}