fixes (addressed comments)

This commit is contained in:
Nicholas Ward 2021-09-17 13:09:24 -07:00
parent 14fd1dfa6b
commit 2c1c116ead
2 changed files with 43 additions and 33 deletions

View File

@ -39,8 +39,8 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
) -> Vec<MemoryOpTarget> {
let n = ops.len();
let address_chunk_size = (address_bits as f64).sqrt() as usize;
let timestamp_chunk_size = (timestamp_bits as f64).sqrt() as usize;
let combined_bits = address_bits + timestamp_bits;
let chunk_size = 3;
let is_write_targets: Vec<_> = self
.add_virtual_targets(n)
@ -65,35 +65,26 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
})
.collect();
let two_n = self.constant(F::from_canonical_usize(1 << timestamp_bits));
let address_timestamp_combined: Vec<_> = output_targets
.iter()
.map(|op| self.mul_add(op.timestamp, two_n, op.address))
.collect();
for i in 1..n {
let (address_gate, address_gate_index) = {
let gate = ComparisonGate::new(address_bits, address_chunk_size);
let (gate, gate_index) = {
let gate = ComparisonGate::new(combined_bits, chunk_size);
let gate_index = self.add_gate(gate.clone(), vec![]);
(gate, gate_index)
};
self.connect(
Target::wire(address_gate_index, address_gate.wire_first_input()),
output_targets[i - 1].address,
Target::wire(gate_index, gate.wire_first_input()),
address_timestamp_combined[i - 1],
);
self.connect(
Target::wire(address_gate_index, address_gate.wire_second_input()),
output_targets[i].address,
);
let (timestamp_gate, timestamp_gate_index) = {
let gate = ComparisonGate::new(timestamp_bits, timestamp_chunk_size);
let gate_index = self.add_gate(gate.clone(), vec![]);
(gate, gate_index)
};
self.connect(
Target::wire(timestamp_gate_index, timestamp_gate.wire_first_input()),
output_targets[i - 1].timestamp,
);
self.connect(
Target::wire(timestamp_gate_index, timestamp_gate.wire_second_input()),
output_targets[i].timestamp,
Target::wire(gate_index, gate.wire_second_input()),
address_timestamp_combined[i],
);
}

View File

@ -13,7 +13,7 @@ use crate::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_recu
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
use crate::util::ceil_div_usize;
/// A gate for checking that one value is less than another.
/// A gate for checking that one value is less than or equal to another.
#[derive(Clone, Debug)]
pub(crate) struct ComparisonGate<F: PrimeField + Extendable<D>, const D: usize> {
pub(crate) num_bits: usize,
@ -137,7 +137,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ComparisonGate
constraints.push(most_significant_diff - most_significant_diff_so_far);
// Range check `most_significant_diff` to be less than `chunk_size`.
let product = (1..chunk_size)
let product = (0..chunk_size)
.map(|x| most_significant_diff - F::Extension::from_canonical_usize(x))
.product();
constraints.push(product);
@ -205,7 +205,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ComparisonGate
constraints.push(most_significant_diff - most_significant_diff_so_far);
// Range check `most_significant_diff` to be less than `chunk_size`.
let product = (1..chunk_size)
let product = (0..chunk_size)
.map(|x| most_significant_diff - F::from_canonical_usize(x))
.product();
constraints.push(product);
@ -286,7 +286,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ComparisonGate
// Range check `most_significant_diff` to be less than `chunk_size`.
let mut product = builder.one_extension();
for x in 1..chunk_size {
for x in 0..chunk_size {
let x_F = builder.constant_extension(F::Extension::from_canonical_usize(x));
let diff = builder.sub_extension(most_significant_diff, x_F);
product = builder.mul_extension(product, diff);
@ -553,7 +553,7 @@ mod tests {
let first_input_u64 = rng.gen_range(0..max);
let second_input_u64 = {
let mut val = rng.gen_range(0..max);
while val <= first_input_u64 {
while val < first_input_u64 {
val = rng.gen_range(0..max);
}
val
@ -562,20 +562,39 @@ mod tests {
let first_input = F::from_canonical_u64(first_input_u64);
let second_input = F::from_canonical_u64(second_input_u64);
let gate = ComparisonGate::<F, D> {
let less_than_gate = ComparisonGate::<F, D> {
num_bits,
num_chunks,
_phantom: PhantomData,
};
let vars = EvaluationVars {
let less_than_vars = EvaluationVars {
local_constants: &[],
local_wires: &get_wires(first_input, second_input),
public_inputs_hash: &HashOut::rand(),
};
assert!(
gate.eval_unfiltered(vars).iter().all(|x| x.is_zero()),
less_than_gate
.eval_unfiltered(less_than_vars)
.iter()
.all(|x| x.is_zero()),
"Gate constraints are not satisfied."
);
let equal_gate = ComparisonGate::<F, D> {
num_bits,
num_chunks,
_phantom: PhantomData,
};
let equal_vars = EvaluationVars {
local_constants: &[],
local_wires: &get_wires(first_input, first_input),
public_inputs_hash: &HashOut::rand(),
};
assert!(
equal_gate
.eval_unfiltered(equal_vars)
.iter()
.all(|x| x.is_zero()),
"Gate constraints are not satisfied."
);
}