risc0_zkp/verify/
read_iop.rs1use alloc::boxed::Box;
16
17use risc0_core::field::{Elem, Field};
18
19use crate::{
20 core::{
21 digest::Digest,
22 hash::{Rng, RngFactory},
23 },
24 verify::VerificationError,
25};
26
27pub struct ReadIOP<'a, F: Field> {
28 proof: &'a [u32],
29 rng: Box<dyn Rng<F>>,
30}
31
32impl<'a, F: Field> ReadIOP<'a, F> {
33 pub fn new(proof: &'a [u32], rng: &dyn RngFactory<F>) -> Self {
34 ReadIOP {
35 proof,
36 rng: rng.new_rng(),
37 }
38 }
39
40 pub fn read_u32s(&mut self, n: usize) -> Result<&'a [u32], VerificationError> {
41 let Some(u32s) = self.proof.split_off(..n) else {
42 tracing::debug!(
43 "Tried to read {n} u32s from seal; seal length remaining {}",
44 self.proof.len()
45 );
46 return Err(VerificationError::ReceiptFormatError);
47 };
48 Ok(u32s)
49 }
50
51 pub fn read_field_elem_slice<T: Elem>(
54 &mut self,
55 n: usize,
56 ) -> Result<&'a [T], VerificationError> {
57 let u32s = self.read_u32s(n * T::WORDS)?;
58 T::try_from_u32_slice(u32s).map_err(|e| {
59 tracing::debug!("casting seal elems to field slice failed: {e}");
60 VerificationError::ReceiptFormatError
61 })
62 }
63
64 pub fn read_pod_slice<T: bytemuck::Pod>(
68 &mut self,
69 n: usize,
70 ) -> Result<&'a [T], VerificationError> {
71 let read_size = n * core::mem::size_of::<T>() / core::mem::size_of::<u32>();
72 let u32s = self.read_u32s(read_size)?;
73 bytemuck::try_cast_slice(u32s).map_err(|e| {
74 tracing::debug!("casting seal elems to slice failed: {e}");
75 VerificationError::ReceiptFormatError
76 })
77 }
78
79 pub fn commit(&mut self, digest: &Digest) {
80 self.rng.mix(digest);
81 }
82
83 pub fn verify_complete(&self) -> Result<(), VerificationError> {
85 if !self.proof.is_empty() {
86 tracing::debug!(
87 "verify_complete called with {} words remaining in seal",
88 self.proof.len()
89 );
90 return Err(VerificationError::ReceiptFormatError);
91 }
92 Ok(())
93 }
94
95 pub fn random_bits(&mut self, bits: usize) -> u32 {
97 self.rng.random_bits(bits)
98 }
99
100 pub fn random_elem(&mut self) -> F::Elem {
102 self.rng.random_elem()
103 }
104
105 pub fn random_ext_elem(&mut self) -> F::ExtElem {
107 self.rng.random_ext_elem()
108 }
109}