fullcodec_plonk/plonkup/table/witness_table.rs
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4//
5// Copyright (c) DUSK NETWORK. All rights reserved.
6
7use crate::error::Error;
8use crate::plonkup::LookupTable;
9use crate::plonkup::MultiSet;
10use dusk_bls12_381::BlsScalar;
11
12/// This witness table contains quieries
13/// to a lookup table for lookup gates
14/// This table is of arity 3.
15#[derive(Clone, Eq, PartialEq, Debug)]
16pub struct WitnessTable {
17 /// This column represents the
18 /// first values inside the lookup
19 /// table. At gate checks, this
20 /// can be regarded as the first
21 /// wire
22 pub f_1: MultiSet,
23
24 /// This column represents the
25 /// first values inside the lookup
26 /// table. At gate checks, this
27 /// can be regarded as the second
28 /// wire
29 pub f_2: MultiSet,
30
31 /// This column represents the
32 /// first values inside the lookup
33 /// table. At gate checks, this
34 /// can be regarded as the third
35 /// wire
36 pub f_3: MultiSet,
37
38 /// This column represents the
39 /// first values inside the lookup
40 /// table. At gate checks, this
41 /// can be regarded as the fourth
42 /// wire
43 pub f_4: MultiSet,
44}
45
46impl Default for WitnessTable {
47 fn default() -> Self {
48 WitnessTable::new()
49 }
50}
51
52impl WitnessTable {
53 /// Initialses empty witness table of arity 4
54 pub fn new() -> Self {
55 WitnessTable {
56 f_1: MultiSet::new(),
57 f_2: MultiSet::new(),
58 f_3: MultiSet::new(),
59 f_4: MultiSet::new(),
60 }
61 }
62 /// This allows the witness table to be filled directly without
63 /// taking any vaules, or the the results, from the lookup table.
64 /// If the values do no exists in the lookup table, then the proof
65 /// will fail when witness and preprocessed tables are concatenated.
66 pub fn from_wire_values(
67 &mut self,
68 left_wire_val: BlsScalar,
69 right_wire_val: BlsScalar,
70 output_wire_val: BlsScalar,
71 fourth_wire_val: BlsScalar,
72 ) {
73 self.f_1.push(left_wire_val);
74 self.f_2.push(right_wire_val);
75 self.f_3.push(output_wire_val);
76 self.f_4.push(fourth_wire_val);
77 }
78
79 /// Attempts to look up a value from a lookup table. If successful, all four
80 /// elements are pushed to their respective multisets.
81 pub fn value_from_table(
82 &mut self,
83 lookup_table: &LookupTable,
84 left_wire_val: BlsScalar,
85 right_wire_val: BlsScalar,
86 fourth_wire_val: BlsScalar,
87 ) -> Result<(), Error> {
88 let output_wire_val = lookup_table.lookup(
89 left_wire_val,
90 right_wire_val,
91 fourth_wire_val,
92 )?;
93 self.f_1.push(left_wire_val);
94 self.f_2.push(right_wire_val);
95 self.f_3.push(output_wire_val);
96 self.f_4.push(fourth_wire_val);
97 Ok(())
98 }
99}
100#[cfg(test)]
101mod test {
102 use super::*;
103 use crate::plonkup::LookupTable;
104
105 #[test]
106 fn test_lookup() {
107 // Build empty lookup tables
108 let mut lookup_table = LookupTable::new();
109
110 // Add a consecutive set of tables, with
111 // XOR operationd and addition operations
112 lookup_table.insert_multi_xor(0, 4);
113 lookup_table.insert_multi_add(2, 3);
114
115 // Build empty witness table
116 let mut f = WitnessTable::new();
117
118 // Check for output of wires within lookup table and
119 // if they exist input them to the witness table
120 assert!(f
121 .value_from_table(
122 &lookup_table,
123 BlsScalar::from(2),
124 BlsScalar::from(3),
125 -BlsScalar::one()
126 )
127 .is_ok());
128 assert!(f
129 .value_from_table(
130 &lookup_table,
131 BlsScalar::from(4),
132 BlsScalar::from(6),
133 BlsScalar::zero()
134 )
135 .is_ok());
136
137 // Check that values not contained in the lookup table
138 // do not get added to the witness table
139 assert!(f
140 .value_from_table(
141 &lookup_table,
142 BlsScalar::from(22),
143 BlsScalar::from(1),
144 -BlsScalar::one()
145 )
146 .is_err());
147 assert!(f
148 .value_from_table(
149 &lookup_table,
150 BlsScalar::from(0),
151 BlsScalar::from(1),
152 BlsScalar::zero()
153 )
154 .is_err());
155 }
156}