Recursive PoW

This commit is contained in:
wborgeaud 2021-06-04 16:02:48 +02:00
parent 42d5b80a7a
commit 51c06d74ee
6 changed files with 45 additions and 16 deletions

View File

@ -149,6 +149,11 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
self.copy_constraints.push((x, y));
}
pub fn assert_zero(&mut self, x: Target) {
let zero = self.zero();
self.assert_equal(x, zero);
}
pub fn add_generators(&mut self, generators: Vec<Box<dyn WitnessGenerator<F>>>) {
self.generators.extend(generators);
}

View File

@ -49,14 +49,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
inputs.push(proof.pow_witness);
let hash = self.hash_n_to_m(inputs, 1, false)[0];
let purported_hash_bits = self.split_le_virtual(hash, 64);
// for &b in &purported_hash_bits {
// self.generate_copy(b, self.zero());
// }
// ensure!(
// hash.to_canonical_u64().trailing_zeros() >= config.proof_of_work_bits,
// "Invalid proof of work witness."
// );
self.assert_trailing_zeros(hash, config.proof_of_work_bits);
Ok(())
}

View File

@ -1,4 +1,5 @@
pub mod arithmetic;
pub mod hash;
pub mod polynomial;
pub mod split_base;
pub(crate) mod split_join;

33
src/gadgets/split_base.rs Normal file
View File

@ -0,0 +1,33 @@
use crate::circuit_builder::CircuitBuilder;
use crate::field::extension_field::Extendable;
use crate::field::field::Field;
use crate::gates::base_sum::{BaseSplitGenerator, BaseSumGate};
use crate::generator::{SimpleGenerator, WitnessGenerator};
use crate::target::Target;
use crate::util::ceil_div_usize;
use crate::wire::Wire;
use crate::witness::PartialWitness;
impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
/// Split the given element into a list of 11 targets, where each one represents a
/// base-64 limb of the element, with little-endian ordering.
pub(crate) fn split_le_base64(&mut self, x: Target) -> Vec<Target> {
let gate = self.add_gate(BaseSumGate::<64>::new(11), vec![]);
let sum = Target::Wire(Wire {
gate,
input: BaseSumGate::<64>::WIRE_SUM,
});
self.route(x, sum);
(BaseSumGate::<64>::WIRE_LIMBS_START..BaseSumGate::<64>::WIRE_LIMBS_START + 11)
.map(|i| Target::Wire(Wire { gate, input: i }))
.collect()
}
/// Asserts that `x`'s bit representation has at least `trailing_zeros` trailing zeros.
pub(crate) fn assert_trailing_zeros(&mut self, x: Target, trailing_zeros: u32) {
let limbs = self.split_le_base64(x);
for i in 0..ceil_div_usize(trailing_zeros as usize, 6) {
self.assert_zero(limbs[i]);
}
}
}

View File

@ -19,10 +19,8 @@ pub struct BaseSumGate<const B: usize> {
}
impl<const B: usize> BaseSumGate<B> {
pub fn new<F: Extendable<D>, const D: usize>(config: &CircuitConfig) -> GateRef<F, D> {
GateRef::new(BaseSumGate::<B> {
num_limbs: config.num_routed_wires - 1,
})
pub fn new<F: Extendable<D>, const D: usize>(num_limbs: usize) -> GateRef<F, D> {
GateRef::new(BaseSumGate::<B> { num_limbs })
}
pub const WIRE_SUM: usize = 0;
@ -36,7 +34,7 @@ impl<const B: usize> BaseSumGate<B> {
impl<F: Extendable<D>, const D: usize, const B: usize> Gate<F, D> for BaseSumGate<B> {
fn id(&self) -> String {
format!("{:?}", self)
format!("{:?} + Base: {}", self, B)
}
fn eval_unfiltered(&self, vars: EvaluationVars<F, D>) -> Vec<F::Extension> {
@ -163,7 +161,6 @@ mod tests {
#[test]
fn low_degree() {
let config = CircuitConfig::default();
test_low_degree(BaseSumGate::<6>::new::<CrandallField, 4>(&config))
test_low_degree(BaseSumGate::<6>::new::<CrandallField, 4>(11))
}
}

View File

@ -1,10 +1,10 @@
pub(crate) mod arithmetic;
pub mod base_sum;
pub mod constant;
pub(crate) mod gate;
pub mod gmimc;
mod interpolation;
pub(crate) mod noop;
mod base_sum;
#[cfg(test)]
mod gate_testing;