risc0_zkp/verify/
read_iop.rs

1// Copyright 2024 RISC Zero, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use alloc::boxed::Box;
16
17use risc0_core::field::{Elem, Field};
18
19use crate::core::{
20    digest::Digest,
21    hash::{Rng, RngFactory},
22};
23
24pub struct ReadIOP<'a, F: Field> {
25    proof: &'a [u32],
26    rng: Box<dyn Rng<F>>,
27}
28
29impl<'a, F: Field> ReadIOP<'a, F> {
30    pub fn new(proof: &'a [u32], rng: &dyn RngFactory<F>) -> Self {
31        ReadIOP {
32            proof,
33            rng: rng.new_rng(),
34        }
35    }
36
37    pub fn read_u32s(&mut self, n: usize) -> &'a [u32] {
38        let u32s;
39        (u32s, self.proof) = self.proof.split_at(n);
40        u32s
41    }
42
43    /// Read some field elements from this IOP, and check to make sure
44    /// they're not INVALID.
45    pub fn read_field_elem_slice<T: Elem>(&mut self, n: usize) -> &'a [T] {
46        let u32s = self.read_u32s(n * T::WORDS);
47        T::from_u32_slice(u32s)
48    }
49
50    /// Read some plain old data from this IOP without doing any
51    /// validation.  Prefer to use read_field_elem_slice if reading
52    /// field elements.
53    pub fn read_pod_slice<T: bytemuck::Pod>(&mut self, n: usize) -> &'a [T] {
54        let u32s;
55        (u32s, self.proof) = self
56            .proof
57            .split_at(n * core::mem::size_of::<T>() / core::mem::size_of::<u32>());
58        bytemuck::cast_slice(u32s)
59    }
60
61    pub fn commit(&mut self, digest: &Digest) {
62        self.rng.mix(digest);
63    }
64
65    /// Checks that the entire data of the IOP has been read.
66    pub fn verify_complete(&self) {
67        assert_eq!(self.proof.len(), 0);
68    }
69
70    /// Get a cryptographically uniform u32
71    pub fn random_bits(&mut self, bits: usize) -> u32 {
72        self.rng.random_bits(bits)
73    }
74
75    /// Get a cryptographically uniform field element
76    pub fn random_elem(&mut self) -> F::Elem {
77        self.rng.random_elem()
78    }
79
80    /// Get a cryptographically uniform extension field element
81    pub fn random_ext_elem(&mut self) -> F::ExtElem {
82        self.rng.random_ext_elem()
83    }
84}