mina_tree/proofs/
witness.rs

1use super::{
2    constants::ProofConstants,
3    field::{FieldWitness, GroupAffine},
4    to_field_elements::ToFieldElements,
5    transaction::{add_fast, scalar_challenge, Check},
6};
7
8#[derive(Debug)]
9pub struct Witness<F: FieldWitness> {
10    pub(super) primary: Vec<F>,
11    aux: Vec<F>,
12    // Following fields are used to compare our witness with OCaml
13    pub ocaml_aux: Vec<F>,
14    ocaml_aux_index: usize,
15}
16
17impl<F: FieldWitness> Witness<F> {
18    pub fn new<C: ProofConstants>() -> Self {
19        Self {
20            primary: Vec::with_capacity(C::PRIMARY_LEN),
21            aux: Vec::with_capacity(C::AUX_LEN),
22            ocaml_aux: Vec::new(),
23            ocaml_aux_index: 0,
24        }
25    }
26
27    pub fn empty() -> Self {
28        Self {
29            primary: Vec::new(),
30            aux: Vec::new(),
31            ocaml_aux: Vec::new(),
32            ocaml_aux_index: 0,
33        }
34    }
35
36    pub(super) fn aux(&self) -> &[F] {
37        &self.aux
38    }
39
40    pub fn exists<T>(&mut self, data: T) -> T
41    where
42        T: ToFieldElements<F> + Check<F>,
43    {
44        let data = self.exists_no_check(data);
45        data.check(self);
46        data
47    }
48
49    /// Same as `Self::exists`, but do not call `Check::check` on `data`
50    /// We use this wherever `seal` is used in OCaml, or on `if_` conditions
51    pub fn exists_no_check<T>(&mut self, data: T) -> T
52    where
53        T: ToFieldElements<F>,
54    {
55        #[cfg(test)]
56        let start = self.aux.len();
57
58        data.to_field_elements(&mut self.aux);
59
60        #[cfg(test)]
61        self.assert_ocaml_aux(start);
62
63        data
64    }
65
66    /// Compare our witness with OCaml
67    #[cfg(test)]
68    fn assert_ocaml_aux(&mut self, start_offset: usize) {
69        if self.ocaml_aux.is_empty() {
70            return;
71        }
72
73        let new_fields = &self.aux[start_offset..];
74        let len = new_fields.len();
75        let ocaml_fields = &self.ocaml_aux[start_offset..start_offset + len];
76
77        assert_eq!(start_offset, self.ocaml_aux_index);
78        assert_eq!(new_fields, ocaml_fields);
79
80        self.ocaml_aux_index += len;
81
82        eprintln!(
83            "index={:?} w{:?}",
84            start_offset + self.primary.capacity(),
85            &self.aux[start_offset..]
86        );
87    }
88
89    /// Helper
90    pub fn to_field_checked_prime<const NBITS: usize>(&mut self, scalar: F) -> (F, F, F) {
91        scalar_challenge::to_field_checked_prime::<F, NBITS>(scalar, self)
92    }
93
94    /// Helper
95    pub fn add_fast(&mut self, p1: GroupAffine<F>, p2: GroupAffine<F>) -> GroupAffine<F> {
96        add_fast::<F>(p1, p2, None, self)
97    }
98}