mirror of https://github.com/zcash/orchard.git
lookup_range_check: Replace short_lookup_bitshift with selector.
Previously, the short_lookup_bitshift fixed column was a non-binary selector that both provided a constant value and toggled a gate. Now, the constant value is copied in from the global constants API, and the toggle is handled by a q_lookup_bitshift selector.
This commit is contained in:
parent
283b45169a
commit
76c73531c8
|
@ -17,7 +17,7 @@ use super::*;
|
||||||
pub struct LookupRangeCheckConfig<F: FieldExt + PrimeFieldBits, const K: usize> {
|
pub struct LookupRangeCheckConfig<F: FieldExt + PrimeFieldBits, const K: usize> {
|
||||||
pub q_lookup: Selector,
|
pub q_lookup: Selector,
|
||||||
pub q_lookup_short: Selector,
|
pub q_lookup_short: Selector,
|
||||||
pub short_lookup_bitshift: Column<Fixed>,
|
pub q_lookup_bitshift: Selector,
|
||||||
pub running_sum: Column<Advice>,
|
pub running_sum: Column<Advice>,
|
||||||
table_idx: Column<Fixed>,
|
table_idx: Column<Fixed>,
|
||||||
_marker: PhantomData<F>,
|
_marker: PhantomData<F>,
|
||||||
|
@ -44,11 +44,11 @@ impl<F: FieldExt + PrimeFieldBits, const K: usize> LookupRangeCheckConfig<F, K>
|
||||||
|
|
||||||
let q_lookup = meta.selector();
|
let q_lookup = meta.selector();
|
||||||
let q_lookup_short = meta.selector();
|
let q_lookup_short = meta.selector();
|
||||||
let short_lookup_bitshift = meta.fixed_column();
|
let q_lookup_bitshift = meta.selector();
|
||||||
let config = LookupRangeCheckConfig {
|
let config = LookupRangeCheckConfig {
|
||||||
q_lookup,
|
q_lookup,
|
||||||
q_lookup_short,
|
q_lookup_short,
|
||||||
short_lookup_bitshift,
|
q_lookup_bitshift,
|
||||||
running_sum,
|
running_sum,
|
||||||
table_idx,
|
table_idx,
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
|
@ -78,15 +78,16 @@ impl<F: FieldExt + PrimeFieldBits, const K: usize> LookupRangeCheckConfig<F, K>
|
||||||
|
|
||||||
// For short lookups, check that the word has been shifted by the correct number of bits.
|
// For short lookups, check that the word has been shifted by the correct number of bits.
|
||||||
meta.create_gate("Short lookup bitshift", |meta| {
|
meta.create_gate("Short lookup bitshift", |meta| {
|
||||||
let inv_two_pow_s = meta.query_fixed(config.short_lookup_bitshift, Rotation::cur());
|
let q_lookup_bitshift = meta.query_selector(config.q_lookup_bitshift);
|
||||||
let word = meta.query_advice(config.running_sum, Rotation::prev());
|
let word = meta.query_advice(config.running_sum, Rotation::prev());
|
||||||
let shifted_word = meta.query_advice(config.running_sum, Rotation::cur());
|
let shifted_word = meta.query_advice(config.running_sum, Rotation::cur());
|
||||||
|
let inv_two_pow_s = meta.query_advice(config.running_sum, Rotation::next());
|
||||||
|
|
||||||
let two_pow_k = F::from_u64(1 << K);
|
let two_pow_k = F::from_u64(1 << K);
|
||||||
|
|
||||||
// shifted_word = word * 2^{K-s}
|
// shifted_word = word * 2^{K-s}
|
||||||
// = word * 2^K * inv_two_pow_s
|
// = word * 2^K * inv_two_pow_s
|
||||||
vec![inv_two_pow_s.clone() * (word * two_pow_k * inv_two_pow_s - shifted_word)]
|
vec![q_lookup_bitshift * (word * two_pow_k * inv_two_pow_s - shifted_word)]
|
||||||
});
|
});
|
||||||
|
|
||||||
config
|
config
|
||||||
|
@ -317,17 +318,11 @@ impl<F: FieldExt + PrimeFieldBits, const K: usize> LookupRangeCheckConfig<F, K>
|
||||||
// Enable lookup for `element`, to constrain it to 10 bits.
|
// Enable lookup for `element`, to constrain it to 10 bits.
|
||||||
self.q_lookup_short.enable(region, 0)?;
|
self.q_lookup_short.enable(region, 0)?;
|
||||||
|
|
||||||
// Assign 2^{-num_bits} in a fixed column.
|
// Enable lookup for shifted element, to constrain it to 10 bits.
|
||||||
{
|
self.q_lookup_short.enable(region, 1)?;
|
||||||
// 2^{-num_bits}
|
|
||||||
let inv_two_pow_s = F::from_u64(1 << num_bits).invert().unwrap();
|
// Check element has been shifted by the correct number of bits.
|
||||||
region.assign_fixed(
|
self.q_lookup_bitshift.enable(region, 1)?;
|
||||||
|| format!("2^(-{})", num_bits),
|
|
||||||
self.short_lookup_bitshift,
|
|
||||||
1,
|
|
||||||
|| Ok(inv_two_pow_s),
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign shifted `element * 2^{K - num_bits}`
|
// Assign shifted `element * 2^{K - num_bits}`
|
||||||
let shifted = element.value().map(|element| {
|
let shifted = element.value().map(|element| {
|
||||||
|
@ -342,8 +337,14 @@ impl<F: FieldExt + PrimeFieldBits, const K: usize> LookupRangeCheckConfig<F, K>
|
||||||
|| shifted.ok_or(Error::SynthesisError),
|
|| shifted.ok_or(Error::SynthesisError),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Enable lookup for shifted element, to constrain it to 10 bits.
|
// Assign 2^{-num_bits} from a fixed column.
|
||||||
self.q_lookup_short.enable(region, 1)?;
|
let inv_two_pow_s = F::from_u64(1 << num_bits).invert().unwrap();
|
||||||
|
region.assign_advice_from_constant(
|
||||||
|
|| format!("2^(-{})", num_bits),
|
||||||
|
self.running_sum,
|
||||||
|
2,
|
||||||
|
inv_two_pow_s,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue