Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement RLP decoding verification circuit #225

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions plonky2x/src/debug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use std::marker::PhantomData;

use plonky2::field::types::PrimeField64;
use plonky2::iop::generator::{GeneratedValues, SimpleGenerator};
use plonky2::iop::target::Target;
use plonky2::iop::witness::PartitionWitness;
use plonky2::plonk::circuit_data::CommonCircuitData;
use plonky2::util::serialization::{Buffer, IoResult};

use crate::frontend::vars::{CircuitVariable, Variable};
use crate::prelude::{CircuitBuilder, PlonkParameters};

#[derive(Debug, Clone)]
pub struct DebugGenerator<L: PlonkParameters<D>, const D: usize> {
pub string: Vec<String>,
pub value: Vec<Variable>,
_phantom: PhantomData<L>,
}

impl<L: PlonkParameters<D>, const D: usize> DebugGenerator<L, D> {
pub fn new(
_builder: &mut CircuitBuilder<L, D>,
string: Vec<String>,
value: Vec<Variable>,
) -> Self {
Self {
string,
value,
_phantom: PhantomData,
}
}
}

impl<L: PlonkParameters<D>, const D: usize> SimpleGenerator<L::Field, D> for DebugGenerator<L, D> {
fn id(&self) -> String {
"DebugGenerator".to_string()
}

fn dependencies(&self) -> Vec<Target> {
let mut targets: Vec<Target> = Vec::new();
for v in &self.value {
targets.extend(v.targets());
}
targets
}

#[allow(unused_variables)]
fn run_once(
&self,
witness: &PartitionWitness<L::Field>,
out_buffer: &mut GeneratedValues<L::Field>,
) {
for i in 0..self.value.len() {
println!(
"{}: {}",
self.string[i],
self.value[i].get(witness).to_canonical_u64()
);
}
println!();
}

#[allow(unused_variables)]
fn serialize(
&self,
dst: &mut Vec<u8>,
common_data: &CommonCircuitData<L::Field, D>,
) -> IoResult<()> {
todo!()
}

#[allow(unused_variables)]
fn deserialize(
src: &mut Buffer,
common_data: &CommonCircuitData<L::Field, D>,
) -> IoResult<Self> {
todo!()
}
}

pub fn debug<L: PlonkParameters<D>, const D: usize>(
builder: &mut CircuitBuilder<L, D>,
format: Vec<String>,
variable: Vec<Variable>,
) {
let generator: DebugGenerator<L, D> = DebugGenerator::new(builder, format, variable);
builder.add_simple_generator(generator.clone());
}
23 changes: 23 additions & 0 deletions plonky2x/src/frontend/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,13 +309,27 @@ impl<L: PlonkParameters<D>, const D: usize> CircuitBuilder<L, D> {
self.api.is_equal(i1.0, zero).target.into()
}

/// Returns 1 if i1 is not zero, 0 otherwise as a boolean.
pub fn is_not_zero(&mut self, i1: Variable) -> BoolVariable {
let is_zero = self.is_zero(i1);
self.not(is_zero)
}

/// Fails if i1 != i2.
pub fn assert_is_equal<V: CircuitVariable>(&mut self, i1: V, i2: V) {
for (t1, t2) in i1.targets().iter().zip(i2.targets().iter()) {
self.api.connect(*t1, *t2);
}
}

/// Fails if i1 != true.
pub fn assert_is_true<V: CircuitVariable>(&mut self, i1: V) {
let one = self.api.one();
for t1 in i1.targets().iter() {
self.api.connect(*t1, one);
}
}

/// Returns 1 if i1 == i2 and 0 otherwise as a BoolVariable.
pub fn is_equal<V: CircuitVariable>(&mut self, i1: V, i2: V) -> BoolVariable {
let mut result = self._true();
Expand All @@ -342,6 +356,15 @@ impl<L: PlonkParameters<D>, const D: usize> CircuitBuilder<L, D> {
pub fn to_be_bits<V: EvmVariable>(&mut self, variable: V) -> Vec<BoolVariable> {
variable.to_be_bits(self)
}

/// Takes a slice of bits and returns the number with little-endian bit representation as a Variable.
pub fn le_sum(&mut self, bits: &[BoolVariable]) -> Variable {
let bits = bits
.iter()
.map(|x| BoolTarget::new_unsafe(x.0 .0))
.collect_vec();
Variable(self.api.le_sum(bits.into_iter()))
}
}

impl<L: PlonkParameters<D>, const D: usize> Default for CircuitBuilder<L, D> {
Expand Down
12 changes: 7 additions & 5 deletions plonky2x/src/frontend/eth/mpt/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,7 @@ impl<L: PlonkParameters<D>, const D: usize> CircuitBuilder<L, D> {
let case_len_le_32 = self.and(node_len_le_32, first_32_bytes_eq);
let inter = self.not(node_len_le_32);
let case_len_gt_32 = self.and(inter, hash_eq);
let equality_fulfilled = self.or(case_len_le_32, case_len_gt_32);
let checked_equality = self.or(equality_fulfilled, finished);
let checked_equality = self.or_many(&[case_len_le_32, case_len_gt_32, finished]);
let t = self._true();
self.assert_is_equal(checked_equality, t);
}
Expand Down Expand Up @@ -199,9 +198,12 @@ impl<L: PlonkParameters<D>, const D: usize> CircuitBuilder<L, D> {

let prefix_leaf_even_and_leaf = self.and(prefix_leaf_even, is_leaf);
let prefix_leaf_odd_and_leaf = self.and(prefix_leaf_odd, is_leaf);
let l = self.or(is_branch_and_key_terminated, prefix_leaf_even_and_leaf);
let m = self.or(l, prefix_leaf_odd_and_leaf);
finished = self.or(finished, m);
finished = self.or_many(&[
finished,
is_branch_and_key_terminated,
prefix_leaf_even_and_leaf,
prefix_leaf_odd_and_leaf,
]);
}

let current_node_len = self.sub_byte(current_node_id[0], const_128);
Expand Down
Loading
Loading