reverie/transcript/verifier/
online.rs

1use num_traits::Zero;
2
3use super::*;
4#[cfg(debug_assertions)]
5use crate::algebra::EqIndex;
6use crate::algebra::{Domain, Hashable, Pack, PackSelected};
7use crate::crypto::hash::PackedHasher;
8use crate::generator::ShareGen;
9use crate::proof::OpenOnline;
10use crate::PACKED;
11
12pub struct VerifierTranscriptOnline<D: Domain> {
13    #[cfg(debug_assertions)]
14    omit: [usize; PACKED],
15    share_gen: Box<ShareGen<D>>,
16    hash_online: PackedHasher,
17    hash_preprocess: PackedHasher,
18    recons: std::vec::IntoIter<D::Share>,
19    corrs: std::vec::IntoIter<D::Recon>,
20    inputs: std::vec::IntoIter<D::Recon>,
21    okay: bool,
22}
23
24impl<D: Domain> VerifierTranscriptOnline<D> {
25    pub(crate) fn new(open_proofs: &[OpenOnline; PACKED]) -> Self {
26        //
27        #[cfg(debug_assertions)]
28        {
29            for proof in open_proofs.iter().take(PACKED) {
30                let omit = proof.omit as usize;
31                debug_assert!(omit < PLAYERS);
32                debug_assert_eq!(proof.seeds[omit], [0u8; KEY_SIZE]);
33            }
34        }
35
36        // deserialize the corrections (pre-preprocessing)
37        let mut corrs: Vec<D::Recon> = vec![];
38        D::Recon::unpack(
39            &mut corrs,
40            &[
41                &open_proofs[0].corrs[..],
42                &open_proofs[1].corrs[..],
43                &open_proofs[2].corrs[..],
44                &open_proofs[3].corrs[..],
45                &open_proofs[4].corrs[..],
46                &open_proofs[5].corrs[..],
47                &open_proofs[6].corrs[..],
48                &open_proofs[7].corrs[..],
49            ],
50        );
51
52        // deserialize masked input
53        let mut inputs: Vec<D::Recon> = vec![];
54        D::Recon::unpack(
55            &mut inputs,
56            &[
57                &open_proofs[0].inputs[..],
58                &open_proofs[1].inputs[..],
59                &open_proofs[2].inputs[..],
60                &open_proofs[3].inputs[..],
61                &open_proofs[4].inputs[..],
62                &open_proofs[5].inputs[..],
63                &open_proofs[6].inputs[..],
64                &open_proofs[7].inputs[..],
65            ],
66        );
67
68        // deserialize the broadcast messages from the unopened player
69        let mut recons: Vec<D::Share> = vec![];
70        let omit = [
71            open_proofs[0].omit as usize,
72            open_proofs[1].omit as usize,
73            open_proofs[2].omit as usize,
74            open_proofs[3].omit as usize,
75            open_proofs[4].omit as usize,
76            open_proofs[5].omit as usize,
77            open_proofs[6].omit as usize,
78            open_proofs[7].omit as usize,
79        ];
80
81        D::Share::unpack_selected(
82            &mut recons,
83            &[
84                &open_proofs[0].recons[..],
85                &open_proofs[1].recons[..],
86                &open_proofs[2].recons[..],
87                &open_proofs[3].recons[..],
88                &open_proofs[4].recons[..],
89                &open_proofs[5].recons[..],
90                &open_proofs[6].recons[..],
91                &open_proofs[7].recons[..],
92            ],
93            omit,
94        );
95
96        Self {
97            #[cfg(debug_assertions)]
98            omit,
99            share_gen: Box::new(ShareGen::new(
100                &[
101                    open_proofs[0].seeds,
102                    open_proofs[1].seeds,
103                    open_proofs[2].seeds,
104                    open_proofs[3].seeds,
105                    open_proofs[4].seeds,
106                    open_proofs[5].seeds,
107                    open_proofs[6].seeds,
108                    open_proofs[7].seeds,
109                ],
110                omit,
111            )),
112            hash_online: PackedHasher::new(),
113            hash_preprocess: PackedHasher::new(),
114            recons: recons.into_iter(),
115            inputs: inputs.into_iter(),
116            corrs: corrs.into_iter(),
117            okay: true,
118        }
119    }
120}
121
122impl<D: Domain> Transcript<D> for VerifierTranscriptOnline<D> {
123    fn input(&mut self) -> Wire<D> {
124        let corr = self.inputs.next().unwrap_or_default();
125        corr.hash(&mut self.hash_online);
126        Wire {
127            mask: self.share_gen.next(),
128            corr,
129        }
130    }
131
132    fn online_hash(&self) -> [Hash; PACKED] {
133        self.hash_online.finalize()
134    }
135
136    fn preprocess_hash(&self) -> [Hash; PACKED] {
137        self.hash_preprocess.finalize()
138    }
139
140    fn reconstruct(&mut self, mask: D::Share) -> D::Recon {
141        // sanity check: ensure that the share of the unopened player is set to zero
142        #[cfg(debug_assertions)]
143        {
144            for i in 0..PACKED {
145                debug_assert!(
146                    D::Share::compare_index(
147                        i,
148                        self.omit[i],
149                        &mask,
150                        i,
151                        self.omit[i],
152                        &D::Share::zero()
153                    ),
154                    "omit[{}] = {:?}, mask = {:?}",
155                    i,
156                    self.omit[i],
157                    &mask
158                );
159            }
160        }
161
162        // add share of unopened player
163        let msg = self.recons.next().unwrap_or_default();
164        let mask = mask + msg;
165        mask.hash(&mut self.hash_online);
166        D::reconstruct(&mask)
167    }
168
169    fn correction(&mut self, _corr: D::Recon) -> D::Recon {
170        // ignore input and use provided correction
171        let corr = self.corrs.next().unwrap_or_default();
172        corr.hash(&mut self.hash_preprocess);
173        corr
174    }
175
176    fn zero_check(&mut self, recon: D::Recon) {
177        self.okay &= recon.is_zero();
178    }
179
180    fn new_mask(&mut self) -> D::Share {
181        self.share_gen.next()
182    }
183}