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
use rand_core::{Error, RngCore};
use crate::{
core::{
sha::{Digest, Sha},
sha_rng::ShaRng,
},
field::{self},
};
#[derive(Debug)]
pub struct ReadIOP<'a, S: Sha + 'a> {
sha: S,
proof: &'a [u32],
rng: ShaRng<S>,
}
impl<'a, S: Sha + 'a> ReadIOP<'a, S> {
pub fn new(sha: &'a S, proof: &'a [u32]) -> Self {
ReadIOP {
sha: sha.clone(),
proof,
rng: ShaRng::new(sha),
}
}
pub fn get_sha(&self) -> &S {
&self.sha
}
pub fn read_u32s(&mut self, n: usize) -> &'a [u32] {
let u32s;
(u32s, self.proof) = self.proof.split_at(n);
u32s
}
pub fn read_field_elem_slice<T: field::Elem>(&mut self, n: usize) -> &'a [T] {
let u32s = self.read_u32s(n * T::WORDS);
T::from_u32_slice(u32s)
}
pub fn read_pod_slice<T: bytemuck::Pod>(&mut self, n: usize) -> &'a [T] {
let u32s;
(u32s, self.proof) = self
.proof
.split_at(n * core::mem::size_of::<T>() / core::mem::size_of::<u32>());
bytemuck::cast_slice(u32s)
}
pub fn commit(&mut self, digest: &Digest) {
self.rng.mix(digest);
}
pub fn verify_complete(&self) {
assert_eq!(self.proof.len(), 0);
}
}
impl<'a, S: Sha> RngCore for ReadIOP<'a, S> {
fn next_u32(&mut self) -> u32 {
self.rng.next_u32()
}
fn next_u64(&mut self) -> u64 {
self.rng.next_u64()
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
self.rng.fill_bytes(dest)
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
self.rng.try_fill_bytes(dest)
}
}