Skip to content

Commit

Permalink
refine
Browse files Browse the repository at this point in the history
  • Loading branch information
zk-steve committed May 15, 2024
1 parent 381d240 commit addf4d1
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 93 deletions.
1 change: 0 additions & 1 deletion fri/src/fields/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
pub mod goldilocks;
pub mod utils;
13 changes: 0 additions & 13 deletions fri/src/fields/utils.rs

This file was deleted.

2 changes: 1 addition & 1 deletion fri/src/fri_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl<F: PrimeField> FriLayer<F> {
poly.evaluate(&cur1)
})
.collect::<Vec<_>>();
let merkle_tree = MerkleTree::new(&evaluations);
let merkle_tree = MerkleTree::new(evaluations.clone());

Self {
evaluations,
Expand Down
31 changes: 10 additions & 21 deletions fri/src/hasher.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
use ark_ff::PrimeField;
use sha2::{Digest, Sha256};

#[derive(Clone, Debug)]
pub struct CustomizedHash<F: PrimeField> {
_f: F,
pub fn hash<F: PrimeField>(data: &F) -> F {
let mut hasher = Sha256::new();
hasher.update(data.to_string());
let h = hasher.finalize();
F::from_le_bytes_mod_order(&h)
}

impl<F: PrimeField> CustomizedHash<F> {
pub fn hash_one(data: F) -> F {
let d: Vec<u8> = data.to_string().into();
let mut hasher = Sha256::new();
hasher.update(d);
let h = hasher.finalize();
F::from_le_bytes_mod_order(&h)
}

pub fn hash_two(data1: F, data2: F) -> F {
let mut d: Vec<u8> = data1.to_string().into();
let mut d1: Vec<u8> = data2.to_string().into();
d.append(&mut d1);
let mut hasher = Sha256::new();
hasher.update(d);
let h = hasher.finalize();
F::from_le_bytes_mod_order(&h)
}
pub fn hash_slice<F: PrimeField>(data: &[F]) -> F {
let mut hasher = Sha256::new();
data.into_iter().for_each(|d| hasher.update(d.to_string()));
let h = hasher.finalize();
F::from_le_bytes_mod_order(&h)
}
59 changes: 30 additions & 29 deletions fri/src/merkle_tree.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use ark_ff::PrimeField;

use crate::hasher::CustomizedHash;
use crate::hasher::{hash, hash_slice};

#[derive(Debug, Clone)]
pub struct MerkleProof<F: PrimeField> {
Expand All @@ -10,14 +10,16 @@ pub struct MerkleProof<F: PrimeField> {
pub leaf_val: F,
/// Hash value of the neighbouring node
hash_proof: Vec<F>,
/// Root value of the commited merkle tree
root: F,
}

impl<F: PrimeField> MerkleProof<F> {

Check failure

Code scanning / clippy

mismatched types Error

mismatched types
fn root(&self) -> F {

Check failure

Code scanning / clippy

mismatched types Error

mismatched types
self.hash_proof.last().clone()

Check failure on line 17 in fri/src/merkle_tree.rs

View workflow job for this annotation

GitHub Actions / Cargo check

mismatched types

Check failure

Code scanning / clippy

mismatched types Error

mismatched types
}
}

#[derive(Debug, Clone)]
pub struct MerkleTree<F: PrimeField> {
pub root: F,
/// the hash of internal nodes
/// merkle tree upside down
internal_nodes: Vec<Vec<F>>,
/// value of leaves nodes.
Expand All @@ -26,42 +28,43 @@ pub struct MerkleTree<F: PrimeField> {
}

impl<F: PrimeField> MerkleTree<F> {
pub fn new(evaluations: &[F]) -> Self {
let mut leaves = evaluations.to_owned();
pub fn new(mut evaluations: Vec<F>) -> Self {
let new_len = evaluations.len().next_power_of_two();
leaves.resize(new_len, F::ZERO); //fill the rest of the tree with 0
let depth = (new_len as f64).log2() as usize;

let mut internal_nodes: Vec<Vec<F>> = Vec::new();
let depth = new_len.ilog2() as usize;

let first_level = evaluations
.iter()
.map(|v| CustomizedHash::<F>::hash_one(*v))
.collect();
internal_nodes.push(first_level);
.map(hash)
.collect::<Vec<_>>();

let mut internal_nodes = vec![first_level];

for i in 0..depth {
let current_layer = internal_nodes[i].clone();
let next_level = current_layer
let next_level = internal_nodes[i]
.chunks(2)
.map(|nodes| CustomizedHash::<F>::hash_two(nodes[0], nodes[1]))
.map(hash_slice)
.collect();
internal_nodes.push(next_level);
}

let merkle_root = internal_nodes[depth][0];
evaluations.resize(new_len, F::ZERO); //fill the rest of the tree with 0

Self {
root: merkle_root,
internal_nodes,
leaves,
leaves: evaluations,
depth,
}
}
}

impl<F: PrimeField> MerkleTree<F> {
pub fn root(&self) -> F {
self.internal_nodes.last().unwrap()[0]
}

pub fn generate_proof(&self, index: usize) -> MerkleProof<F> {
let leaf_val = self.leaves[index];
let mut hash_proof = Vec::new();
let mut hash_proof = Vec::with_capacity(self.depth);
let mut cur_index = index;
for i in 0..self.depth {
let neighbour = if cur_index % 2 == 0 {
Expand All @@ -78,22 +81,22 @@ impl<F: PrimeField> MerkleTree<F> {
index,
leaf_val,
hash_proof,
root: self.root,
root: self.root(),

Check failure on line 84 in fri/src/merkle_tree.rs

View workflow job for this annotation

GitHub Actions / Cargo check

struct `MerkleProof<F>` has no field named `root`

Check failure

Code scanning / clippy

struct merkle_tree::MerkleProof<F> has no field named root Error

struct merkle_tree::MerkleProof<F> has no field named root
}
}
}

pub fn verify_merkle_proof<F: PrimeField>(proof: &MerkleProof<F>) -> bool {
let mut cur_index = proof.index;
let mut cur_hash = CustomizedHash::<F>::hash_one(proof.leaf_val);
let mut cur_hash = hash(&proof.leaf_val);
for i in 0..proof.hash_proof.len() {
if cur_index % 2 == 0 {
// The current node is a left node
let neighbour = proof.hash_proof[i];
cur_hash = CustomizedHash::<F>::hash_two(cur_hash, neighbour);
cur_hash = hash_slice(&[cur_hash, neighbour]);
} else {
let neighbour = proof.hash_proof[i];
cur_hash = CustomizedHash::<F>::hash_two(neighbour, cur_hash);
cur_hash = hash_slice(&[neighbour, cur_hash]);
}
cur_index /= 2;
}
Expand All @@ -109,10 +112,8 @@ mod tests {
#[test]
fn test_merkle() {
let leaves = vec![1, 2, 3, 4];
let new_leaves: Vec<Fq> = leaves.iter().map(|x| Fq::from(x.clone())).collect();
let tree = MerkleTree::<Fq>::new(&new_leaves);

let _root = tree.root;
let new_leaves: Vec<Fq> = leaves.into_iter().map(|x| Fq::from(x)).collect();
let tree = MerkleTree::new(new_leaves);

let merkle_proof = tree.generate_proof(1);
println!("{:?}", merkle_proof);
Expand Down
41 changes: 14 additions & 27 deletions fri/src/prover.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::ops::Mul;
use ark_ff::PrimeField;
use ark_poly::univariate::DensePolynomial;
use ark_poly::DenseUVPolynomial;

use crate::fiat_shamir::Transcript;

use crate::fri_layer::FriLayer;
use crate::merkle_tree::MerkleProof;

Expand Down Expand Up @@ -34,40 +35,34 @@ pub fn fold_polynomial<F: PrimeField>(
poly: &DensePolynomial<F>,
random_r: F,
) -> DensePolynomial<F> {
let coeff = poly.clone().coeffs;
let coeff = poly.coeffs.clone();
let even_coeff = coeff.iter().step_by(2).cloned().collect();
let odd_coeff_mul_r: Vec<F> = coeff
.iter()
.into_iter()
.skip(1)
.step_by(2)
.cloned()
.map(|v| v * random_r)
.collect();

let even_poly = DensePolynomial::from_coefficients_vec(even_coeff);
let odd_poly = DensePolynomial::from_coefficients_vec(odd_coeff_mul_r);
even_poly + odd_poly
even_poly + odd_poly.mul(random_r)
}

/// Verify that [poly] have degree [k] or [number_layers]
///
/// Also create prove for the evaluation of the polynomial
pub fn folding_phase<F: PrimeField>(
poly: DensePolynomial<F>,
coset: F,
domain_size: usize,
mut poly: DensePolynomial<F>,
mut coset: F,
mut domain_size: usize,
number_layers: usize,
) -> (F, Transcript<F>, Vec<FriLayer<F>>) {
let mut fri_layers: Vec<FriLayer<F>> = Vec::with_capacity(log2_of_usize(number_layers) + 1);
let mut fri_layers: Vec<FriLayer<F>> = Vec::with_capacity(number_layers.ilog2() as usize + 1);
let mut transcript = Transcript::<F>::new(F::ZERO);
let mut current_layer;
let mut poly = poly.to_owned();
let mut coset = coset;
let mut domain_size = domain_size;

for _ in 0..number_layers {
current_layer = FriLayer::new(&poly, coset, domain_size);
transcript.insert_last_message(current_layer.merkle_tree.root);
let current_layer = FriLayer::new(&poly, coset, domain_size);
transcript.insert_last_message(current_layer.merkle_tree.root());
fri_layers.push(current_layer);

poly = fold_polynomial(&poly, transcript.generate_a_challenge());
Expand Down Expand Up @@ -96,7 +91,7 @@ pub fn query_phase<F: PrimeField>(
.generate_challenge_list_usize(number_of_queries)
.iter()
.map(|v| *v % domain_size)
.collect::<Vec<usize>>();
.collect::<Vec<_>>();

let mut decommitment_list = Vec::new();

Expand Down Expand Up @@ -140,22 +135,14 @@ pub fn query_phase<F: PrimeField>(
}
}

fn log2_of_usize(n: usize) -> usize {
if n == 0 {
return 0; // log2(0) is undefined, return 0 or handle error accordingly
}
let bits = 8 * std::mem::size_of::<usize>();
bits - n.leading_zeros() as usize - if n.is_power_of_two() { 1 } else { 0 }
}

pub fn generate_proof<F: PrimeField>(
poly: DensePolynomial<F>,
blowup_factor: usize,
number_of_queries: usize,
) -> Proof<F> {
let domain_size = (poly.coeffs.len() * blowup_factor).next_power_of_two();
let coset = F::GENERATOR;
let number_of_layers = log2_of_usize(domain_size);
let number_of_layers = domain_size.ilog2() as usize;

let (const_val, mut transcript, fri_layers) =
folding_phase(poly, coset, domain_size, number_of_layers);
Expand All @@ -164,7 +151,7 @@ pub fn generate_proof<F: PrimeField>(

let fri_layers_root: Vec<F> = fri_layers
.iter()
.map(|layer| layer.merkle_tree.root)
.map(|layer| layer.merkle_tree.root())
.collect();

Proof {
Expand Down
2 changes: 1 addition & 1 deletion fri/src/verifier.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use ark_ff::PrimeField;
use ark_poly::{EvaluationDomain, GeneralEvaluationDomain};

use crate::fiat_shamir::Transcript;

use crate::merkle_tree::verify_merkle_proof;
use crate::prover::{Decommitment, Proof};

Expand Down

0 comments on commit addf4d1

Please sign in to comment.