-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtable.rs
79 lines (69 loc) · 2.54 KB
/
table.rs
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
use std::marker::PhantomData;
use halo2_proofs::{
arithmetic::FieldExt,
circuit::{Layouter, Value},
plonk::{ConstraintSystem, Error, TableColumn},
};
/// A lookup table of values up to RANGE
/// e.g. RANGE = 256, values = [0..255]
/// This table is tagged by an index `k`, where `k` is the number of bits of the element in the `value` column.
#[derive(Debug, Clone)]
pub(super) struct RangeTableConfig<F: FieldExt, const NUM_BITS: usize, const RANGE: usize> {
pub(super) num_bits: TableColumn,
pub(super) value: TableColumn,
_marker: PhantomData<F>,
}
impl<F: FieldExt, const NUM_BITS: usize, const RANGE: usize> RangeTableConfig<F, NUM_BITS, RANGE> {
pub(super) fn configure(meta: &mut ConstraintSystem<F>) -> Self {
assert_eq!(1 << NUM_BITS, RANGE);
let num_bits = meta.lookup_table_column();
let value = meta.lookup_table_column();
Self {
num_bits,
value,
_marker: PhantomData,
}
}
pub(super) fn load(&self, layouter: &mut impl Layouter<F>) -> Result<(), Error> {
layouter.assign_table(
|| "load range-check table",
|mut table| {
let mut offset = 0;
// Assign (num_bits = 1, value = 0)
{
table.assign_cell(
|| "assign num_bits",
self.num_bits,
offset,
|| Value::known(F::one()),
)?;
table.assign_cell(
|| "assign value",
self.value,
offset,
|| Value::known(F::zero()),
)?;
offset += 1;
}
for num_bits in 1..=NUM_BITS {
for value in (1 << (num_bits - 1))..(1 << num_bits) {
table.assign_cell(
|| "assign num_bits",
self.num_bits,
offset,
|| Value::known(F::from(num_bits as u64)),
)?;
table.assign_cell(
|| "assign value",
self.value,
offset,
|| Value::known(F::from(value as u64)),
)?;
offset += 1;
}
}
Ok(())
}
)
}
}