refactor utils and params
This commit is contained in:
parent
b1c13a9bc1
commit
5a13ac3650
|
@ -2,3 +2,5 @@ pub mod capped_tree_circuit;
|
|||
pub mod safe_tree_circuit;
|
||||
pub mod prove_single_cell;
|
||||
pub mod sample_cells;
|
||||
pub mod utils;
|
||||
pub mod params;
|
|
@ -0,0 +1,20 @@
|
|||
// global params for the circuits
|
||||
// only change params here
|
||||
|
||||
use plonky2::hash::poseidon::PoseidonHash;
|
||||
|
||||
// constants and types used throughout the circuit
|
||||
pub const N_FIELD_ELEMS_PER_CELL: usize = 4;
|
||||
pub const BOT_DEPTH: usize = 5; // block depth - depth of the block merkle tree
|
||||
pub const MAX_DEPTH: usize = 16; // depth of big tree (slot tree depth + block tree depth)
|
||||
pub const N_CELLS_IN_BLOCKS: usize = 1<<BOT_DEPTH; //2^BOT_DEPTH
|
||||
pub const N_BLOCKS: usize = 1<<(MAX_DEPTH - BOT_DEPTH); // 2^(MAX_DEPTH - BOT_DEPTH)
|
||||
pub const N_CELLS: usize = N_CELLS_IN_BLOCKS * N_BLOCKS;
|
||||
|
||||
pub const DATASET_DEPTH: usize = 2;
|
||||
pub const N_SAMPLES: usize = 5;
|
||||
|
||||
// hash function used. this is hackish way of doing it because
|
||||
// H::Hash is not consistent with HashOut<F> and causing a lot of headache
|
||||
// will look into this later.
|
||||
pub type HF = PoseidonHash;
|
|
@ -29,18 +29,8 @@ use plonky2::plonk::config::PoseidonGoldilocksConfig;
|
|||
|
||||
use plonky2::hash::hashing::PlonkyPermutation;
|
||||
use crate::circuits::safe_tree_circuit::{MerkleTreeCircuit, MerkleTreeTargets};
|
||||
|
||||
// constants and types used throughout the circuit
|
||||
pub const N_FIELD_ELEMS_PER_CELL: usize = 4;
|
||||
pub const BOT_DEPTH: usize = 5; // block depth - depth of the block merkle tree
|
||||
pub const MAX_DEPTH: usize = 16; // depth of big tree (slot tree depth + block tree depth)
|
||||
const N_CELLS_IN_BLOCKS: usize = 1<<BOT_DEPTH; //2^BOT_DEPTH
|
||||
const N_BLOCKS: usize = 1<<(MAX_DEPTH - BOT_DEPTH); // 2^(MAX_DEPTH - BOT_DEPTH)
|
||||
const N_CELLS: usize = N_CELLS_IN_BLOCKS * N_BLOCKS;
|
||||
// hash function used. this is hackish way of doing it because
|
||||
// H::Hash is not consistent with HashOut<F> and causing a lot of headache
|
||||
// will look into this later.
|
||||
type HF = PoseidonHash;
|
||||
use crate::circuits::utils::usize_to_bits_le_padded;
|
||||
use crate::circuits::params::{MAX_DEPTH, BOT_DEPTH, N_FIELD_ELEMS_PER_CELL, N_CELLS_IN_BLOCKS, N_BLOCKS, N_CELLS, HF};
|
||||
|
||||
// ------ Slot Tree --------
|
||||
|
||||
|
@ -157,9 +147,9 @@ impl<F: RichField, H: Hasher<F>> SlotTree<F, H> {
|
|||
|
||||
/// verify the given proof for slot tree, checks equality with given root
|
||||
pub fn verify_cell_proof(&self, proof: MerkleProof<F, H>, root: HashOut<F>) -> Result<bool>{
|
||||
let mut block_path_bits = self.usize_to_bits_le_padded(proof.index, MAX_DEPTH);
|
||||
let mut block_path_bits = usize_to_bits_le_padded(proof.index, MAX_DEPTH);
|
||||
let last_index = N_CELLS - 1;
|
||||
let mut block_last_bits = self.usize_to_bits_le_padded(last_index, MAX_DEPTH);
|
||||
let mut block_last_bits = usize_to_bits_le_padded(last_index, MAX_DEPTH);
|
||||
|
||||
let split_point = BOT_DEPTH;
|
||||
|
||||
|
@ -186,18 +176,18 @@ impl<F: RichField, H: Hasher<F>> SlotTree<F, H> {
|
|||
return block_tree;
|
||||
}
|
||||
|
||||
/// Converts an index to a vector of bits (LSB first) with padding.
|
||||
pub(crate) fn usize_to_bits_le_padded(&self, index: usize, bit_length: usize) -> Vec<bool> {
|
||||
let mut bits = Vec::with_capacity(bit_length);
|
||||
for i in 0..bit_length {
|
||||
bits.push(((index >> i) & 1) == 1);
|
||||
}
|
||||
// If index requires fewer bits, pad with `false`
|
||||
while bits.len() < bit_length {
|
||||
bits.push(false);
|
||||
}
|
||||
bits
|
||||
}
|
||||
// /// Converts an index to a vector of bits (LSB first) with padding.
|
||||
// pub(crate) fn usize_to_bits_le_padded(&self, index: usize, bit_length: usize) -> Vec<bool> {
|
||||
// let mut bits = Vec::with_capacity(bit_length);
|
||||
// for i in 0..bit_length {
|
||||
// bits.push(((index >> i) & 1) == 1);
|
||||
// }
|
||||
// // If index requires fewer bits, pad with `false`
|
||||
// while bits.len() < bit_length {
|
||||
// bits.push(false);
|
||||
// }
|
||||
// bits
|
||||
// }
|
||||
}
|
||||
|
||||
//------- single cell struct ------
|
||||
|
@ -329,14 +319,14 @@ impl<
|
|||
}
|
||||
|
||||
// Convert `leaf_index` to binary bits and assign as path_bits
|
||||
let path_bits = self.usize_to_bits_le_padded(leaf_index, MAX_DEPTH);
|
||||
let path_bits = usize_to_bits_le_padded(leaf_index, MAX_DEPTH);
|
||||
for (i, bit) in path_bits.iter().enumerate() {
|
||||
pw.set_bool_target(targets.path_bits[i], *bit);
|
||||
}
|
||||
|
||||
// get `last_index` (nleaves - 1) in binary bits and assign
|
||||
let last_index = N_CELLS - 1;
|
||||
let last_bits = self.usize_to_bits_le_padded(last_index, MAX_DEPTH);
|
||||
let last_bits = usize_to_bits_le_padded(last_index, MAX_DEPTH);
|
||||
for (i, bit) in last_bits.iter().enumerate() {
|
||||
pw.set_bool_target(targets.last_bits[i], *bit);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ use plonky2::plonk::proof::{Proof, ProofWithPublicInputs};
|
|||
use std::marker::PhantomData;
|
||||
use plonky2_poseidon2::poseidon2_hash::poseidon2::Poseidon2;
|
||||
use serde::Serialize;
|
||||
use crate::circuits::utils::usize_to_bits_le_padded;
|
||||
|
||||
use crate::merkle_tree::merkle_safe::{MerkleTree, MerkleProofTarget};
|
||||
use crate::merkle_tree::merkle_safe::{KEY_NONE,KEY_BOTTOM_LAYER};
|
||||
|
@ -144,14 +145,14 @@ impl<
|
|||
pw.set_hash_target(targets.leaf, leaf_hash);
|
||||
|
||||
// Convert `leaf_index` to binary bits and assign as path_bits
|
||||
let path_bits = self.usize_to_bits_le_padded(leaf_index, depth);
|
||||
let path_bits = usize_to_bits_le_padded(leaf_index, depth);
|
||||
for (i, bit) in path_bits.iter().enumerate() {
|
||||
pw.set_bool_target(targets.path_bits[i], *bit);
|
||||
}
|
||||
|
||||
// get `last_index` (nleaves - 1) in binary bits and assign
|
||||
let last_index = nleaves - 1;
|
||||
let last_bits = self.usize_to_bits_le_padded(last_index, depth);
|
||||
let last_bits = usize_to_bits_le_padded(last_index, depth);
|
||||
for (i, bit) in last_bits.iter().enumerate() {
|
||||
pw.set_bool_target(targets.last_bits[i], *bit);
|
||||
}
|
||||
|
@ -234,25 +235,25 @@ impl<
|
|||
}
|
||||
|
||||
// --------- helper functions ---------
|
||||
impl<
|
||||
F: RichField + Extendable<D> + Poseidon2,
|
||||
C: GenericConfig<D, F = F>,
|
||||
const D: usize,
|
||||
H: Hasher<F> + AlgebraicHasher<F>,
|
||||
> MerkleTreeCircuit<F, C, D, H> {
|
||||
/// Converts an index to a vector of bits (LSB first) with padding.
|
||||
pub(crate) fn usize_to_bits_le_padded(&self, index: usize, bit_length: usize) -> Vec<bool> {
|
||||
let mut bits = Vec::with_capacity(bit_length);
|
||||
for i in 0..bit_length {
|
||||
bits.push(((index >> i) & 1) == 1);
|
||||
}
|
||||
// If index requires fewer bits, pad with `false`
|
||||
while bits.len() < bit_length {
|
||||
bits.push(false);
|
||||
}
|
||||
bits
|
||||
}
|
||||
}
|
||||
// impl<
|
||||
// F: RichField + Extendable<D> + Poseidon2,
|
||||
// C: GenericConfig<D, F = F>,
|
||||
// const D: usize,
|
||||
// H: Hasher<F> + AlgebraicHasher<F>,
|
||||
// > MerkleTreeCircuit<F, C, D, H> {
|
||||
// /// Converts an index to a vector of bits (LSB first) with padding.
|
||||
// pub(crate) fn usize_to_bits_le_padded(&self, index: usize, bit_length: usize) -> Vec<bool> {
|
||||
// let mut bits = Vec::with_capacity(bit_length);
|
||||
// for i in 0..bit_length {
|
||||
// bits.push(((index >> i) & 1) == 1);
|
||||
// }
|
||||
// // If index requires fewer bits, pad with `false`
|
||||
// while bits.len() < bit_length {
|
||||
// bits.push(false);
|
||||
// }
|
||||
// bits
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// NOTE: for now these tests don't check the reconstructed root is equal to expected_root
|
||||
|
|
|
@ -27,15 +27,11 @@ use plonky2::field::goldilocks_field::GoldilocksField;
|
|||
use plonky2::plonk::config::PoseidonGoldilocksConfig;
|
||||
|
||||
use plonky2::hash::hashing::PlonkyPermutation;
|
||||
use crate::circuits::prove_single_cell::{MAX_DEPTH, SlotTree};
|
||||
use crate::circuits::prove_single_cell::{SingleCellTargets, SlotTree};
|
||||
use crate::circuits::params::{MAX_DEPTH, BOT_DEPTH, N_FIELD_ELEMS_PER_CELL, N_CELLS_IN_BLOCKS, N_BLOCKS, N_CELLS, HF, DATASET_DEPTH, N_SAMPLES};
|
||||
|
||||
use crate::circuits::safe_tree_circuit::{MerkleTreeCircuit, MerkleTreeTargets};
|
||||
|
||||
// constatnts and types
|
||||
const DATASET_DEPTH: usize = 2;
|
||||
const N_SAMPLES: usize = 5;
|
||||
|
||||
type HF = PoseidonHash;
|
||||
|
||||
// ------ Dataset Tree --------
|
||||
///dataset tree containing all slot trees
|
||||
#[derive(Clone)]
|
||||
|
@ -155,6 +151,78 @@ impl<F: RichField, H: Hasher<F>> DatasetTree<F, H> {
|
|||
}
|
||||
}
|
||||
|
||||
//------- single cell struct ------
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct DatasetTargets<
|
||||
F: RichField + Extendable<D> + Poseidon2,
|
||||
C: GenericConfig<D, F = F>,
|
||||
const D: usize,
|
||||
H: Hasher<F> + AlgebraicHasher<F>,
|
||||
> {
|
||||
// pub expected_dataset_root_target: HashOutTarget,
|
||||
// pub slot_index: Target,
|
||||
// pub entropy_target: Target,
|
||||
// pub slot_root: HashOutTarget,
|
||||
pub slot_proofs: Vec<SingleCellTargets<F, C, D, H>>,
|
||||
|
||||
|
||||
// pub proof_target: MerkleProofTarget,
|
||||
// pub leaf_target: Vec<Target>,
|
||||
// pub path_bits: Vec<BoolTarget>,
|
||||
// pub last_bits: Vec<BoolTarget>,
|
||||
_phantom: PhantomData<(C,H)>,
|
||||
}
|
||||
|
||||
//------- circuit impl --------
|
||||
impl<
|
||||
F: RichField + Extendable<D> + Poseidon2,
|
||||
C: GenericConfig<D, F=F>,
|
||||
const D: usize,
|
||||
H: Hasher<F> + AlgebraicHasher<F> + Hasher<F>,
|
||||
> MerkleTreeCircuit<F, C, D, H> {
|
||||
|
||||
// the in-circuit sampling of a slot in a dataset
|
||||
pub fn sample_slot_circuit(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder::<F, D>,
|
||||
)-> DatasetTargets<F,C,D,H>{
|
||||
|
||||
// Create virtual targets
|
||||
// let slot_root = builder.add_virtual_hash();
|
||||
let mut slot_proofs =vec![];
|
||||
for i in 0..N_SAMPLES{
|
||||
let proof_i = self.prove_single_cell2(builder);
|
||||
slot_proofs.push(proof_i);
|
||||
}
|
||||
|
||||
DatasetTargets::<F,C,D,H>{
|
||||
// expected_dataset_root_target: HashOutTarget {},
|
||||
// slot_index: Default::default(),
|
||||
// entropy_target: Default::default(),
|
||||
// slot_root: HashOutTarget {},
|
||||
slot_proofs,
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
// assign the witnesses to the target
|
||||
// takes the dataset tree, slot index, and entropy
|
||||
pub fn sample_slot_assign_witness(
|
||||
&mut self,
|
||||
pw: &mut PartialWitness<F>,
|
||||
targets: DatasetTargets<F,C,D,H>,
|
||||
dataset_tree: DatasetTree<F,H>,
|
||||
slot_index:usize,
|
||||
entropy:usize,
|
||||
){
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// --------- helper functions --------------
|
||||
fn calculate_cell_index_bits<F: RichField>(p0: usize, p1: HashOut<F>, p2: usize) -> Vec<bool> {
|
||||
let p0_field = F::from_canonical_u64(p0 as u64);
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
|
||||
|
||||
// --------- helper functions ---------
|
||||
|
||||
/// Converts an index to a vector of bits (LSB first) with padding.
|
||||
pub(crate) fn usize_to_bits_le_padded(index: usize, bit_length: usize) -> Vec<bool> {
|
||||
let mut bits = Vec::with_capacity(bit_length);
|
||||
for i in 0..bit_length {
|
||||
bits.push(((index >> i) & 1) == 1);
|
||||
}
|
||||
// If index requires fewer bits, pad with `false`
|
||||
while bits.len() < bit_length {
|
||||
bits.push(false);
|
||||
}
|
||||
bits
|
||||
}
|
Loading…
Reference in New Issue