blake3 and poseidon2 bench, script for running merkle hash

This commit is contained in:
Manish Kumar 2024-03-11 23:52:27 +05:30
parent 1c7f257fea
commit e2701150c0
16 changed files with 222 additions and 8 deletions

View File

@ -2,14 +2,14 @@
#![no_main]
sp1_zkvm::entrypoint!(main);
//The patched sha2 rust crate https://github.com/sp1-patches/RustCrypto-hashes
// blake2 of RustCrypto
use blake2::Digest;
use blake2::Blake2b;
pub fn main() {
let input = sp1_zkvm::io::read::<Vec<u8>>();
// create a Blake2b512 object
// create a Blake2b object
let mut hasher = Blake2b::new();
// write input message

View File

@ -0,0 +1,9 @@
[workspace]
[package]
version = "0.1.0"
name = "blake3-program"
edition = "2021"
[dependencies]
sp1-zkvm = { git = "https://github.com/succinctlabs/sp1.git" }
blake3 = "1.5.0"

Binary file not shown.

View File

@ -0,0 +1,22 @@
#![no_main]
sp1_zkvm::entrypoint!(main);
// blake3 of https://github.com/BLAKE3-team/BLAKE3 (official implementation)
use blake3::Hasher;
pub fn main() {
let input = sp1_zkvm::io::read::<Vec<u8>>();
// create a Blake3 object
let mut hasher = Hasher::new();
// write input message
hasher.update(&input);
// read hash digest
let result: [u8;32] = hasher.finalize().into();
sp1_zkvm::io::write(&result);
}

View File

@ -5,5 +5,9 @@ cd ../keccak
cargo prove build
cd ../sha256
cargo prove build
cd ../blake3
cargo prove build
cd ../poseidon2
cargo prove build
cd ../script
cargo build --release

View File

@ -1,6 +1,8 @@
#![no_main]
sp1_zkvm::entrypoint!(main);
// patched keccak rust crate https://github.com/sp1-patches/tiny-keccak
use tiny_keccak::{Hasher, Keccak};
pub fn main() {

View File

@ -0,0 +1,12 @@
[workspace]
[package]
version = "0.1.0"
name = "poseidon2-program"
edition = "2021"
[dependencies]
sp1-zkvm = { git = "https://github.com/succinctlabs/sp1.git" }
zkhash = {git = "https://github.com/HorizenLabs/poseidon2"}
ark-serialize = "0.4"

Binary file not shown.

View File

@ -0,0 +1,35 @@
#![no_main]
sp1_zkvm::entrypoint!(main);
// poseidon2 https://github.com/HorizenLabs/poseidon2
use zkhash::poseidon2::poseidon2::Poseidon2;
use zkhash::poseidon2::poseidon2_instance_bn256::POSEIDON2_BN256_PARAMS;
use zkhash::merkle_tree::merkle_tree_fp::MerkleTree;
use zkhash::fields::bn256::FpBN256;
use ark_serialize::{CanonicalSerialize, CanonicalDeserialize};
pub fn main() {
let input = sp1_zkvm::io::read::<Vec<Vec<u8>>>();
//build input
let mut hash_data: Vec<FpBN256> = Vec::new();
for i in 0..input.len() {
let a_uncompressed = FpBN256::deserialize_uncompressed(&**input.get(i).unwrap()).unwrap();
hash_data.push(a_uncompressed);
}
// create a poseidon2 merkle object
let perm = Poseidon2::new(&POSEIDON2_BN256_PARAMS);
let mut mt = MerkleTree::new(perm.clone());
let hash_final = mt.accumulate(&hash_data);
let mut hash_bytes: Vec<u8> = Vec::new();
hash_final.serialize_uncompressed(&mut hash_bytes).unwrap();
sp1_zkvm::io::write(&hash_bytes);
}

16
hash/sp1/bench/run_tree.sh Executable file
View File

@ -0,0 +1,16 @@
#!/bin/bash
if [ -z ${ZKBENCH_HASH_TYPE_TREE} ]; then
ZKBENCH_HASH_TYPE_TREE="poseidon2"
fi
if [ -z ${ZKBENCH_TREE_DEPTH} ]; then
ZKBENCH_TREE_DEPTH=4
fi
cd script
echo "Running benchmarks with the following configurations:"
echo "HASH = $ZKBENCH_HASH_TYPE_TREE"
echo "Tree Depth = $ZKBENCH_TREE_DEPTH"
# Run the benchmarks
./target/release/bench-script $ZKBENCH_HASH_TYPE_TREE $ZKBENCH_TREE_DEPTH

View File

@ -7,4 +7,6 @@ edition = "2021"
[dependencies]
sp1-core = { git = "https://github.com/succinctlabs/sp1.git" }
rand = "0.8"
hex = "0.4"
hex = "0.4"
zkhash = {git = "https://github.com/HorizenLabs/poseidon2"}
ark-serialize = "0.4"

View File

@ -23,7 +23,7 @@ pub fn blake2_benchmark(size: usize) {
let mut proof = SP1Prover::prove(BLAKE2_ELF, stdin).expect("proving failed");
let t1 = t0.elapsed();
// Read output.
let hash_bytes = proof.stdout.read::<[u8;64]>();
let hash_bytes = proof.stdout.read::<[u8;32]>();
let hash = encode(hash_bytes);
println!("hash: {}", hash);

View File

@ -0,0 +1,43 @@
use sp1_core::{SP1Prover, SP1Stdin, SP1Verifier};
use rand::Rng;
use hex::encode;
const BLAKE3_ELF: &[u8] = include_bytes!("../../../blake3/elf/riscv32im-succinct-zkvm-elf");
pub fn generate_random_bytes(length: usize) -> Vec<u8> {
let mut rng = rand::thread_rng();
(0..length).map(|_| rng.gen::<u8>()).collect()
}
pub fn blake3_benchmark(size: usize) {
// Generate proof.
let mut stdin = SP1Stdin::new();
let data = generate_random_bytes(size);
stdin.write(&data);
let t0 = std::time::Instant::now();
let mut proof = SP1Prover::prove(BLAKE3_ELF, stdin).expect("proving failed");
let t1 = t0.elapsed();
// Read output.
let hash_bytes = proof.stdout.read::<[u8;32]>();
let hash = encode(hash_bytes);
println!("hash: {}", hash);
// Verify proof.
let t2 = std::time::Instant::now();
SP1Verifier::verify(BLAKE3_ELF, &proof).expect("verification failed");
let t3 = t2.elapsed();
// Save proof.
proof
.save("proof-with-io.json")
.expect("saving proof failed");
println!("succesfully generated and verified proof for the program!");
println!("Proof Generation Time: {:?}", t1);
println!("Proof verification Time: {:?}", t3);
}

View File

@ -0,0 +1,50 @@
use sp1_core::{SP1Prover, SP1Stdin, SP1Verifier};
use zkhash::fields::{bn256::FpBN256, utils::random_scalar};
use ark_serialize::{CanonicalSerialize, CanonicalDeserialize};
const POSEIDON2_ELF: &[u8] = include_bytes!("../../../poseidon2/elf/riscv32im-succinct-zkvm-elf");
pub fn poseidon2_benchmark(mt_depth: usize) {
// Generate proof.
let mut stdin = SP1Stdin::new();
type Scalar = FpBN256;
// generating data and serialize
let mut input_scalar: Vec<Vec<u8>> = Vec::new();
let number_of_leaves: u32 = 1 << mt_depth;
for _ in 0..number_of_leaves {
let mut uncompressed_bytes = Vec::new();
let a: Scalar = random_scalar();
a.serialize_uncompressed(&mut uncompressed_bytes).unwrap();
input_scalar.push(uncompressed_bytes);
}
stdin.write(&input_scalar);
let t0 = std::time::Instant::now();
let mut proof = SP1Prover::prove(POSEIDON2_ELF, stdin).expect("proving failed");
let t1 = t0.elapsed();
// Read output.
let hash_bytes = proof.stdout.read::<Vec<u8>>();
let hash_final = Scalar::deserialize_uncompressed(&*hash_bytes).unwrap();
println!("hash: {}", hash_final);
// Verify proof.
let t2 = std::time::Instant::now();
SP1Verifier::verify(POSEIDON2_ELF, &proof).expect("verification failed");
let t3 = t2.elapsed();
// Save proof.
proof
.save("proof-with-io.json")
.expect("saving proof failed");
println!("succesfully generated and verified proof for the program!");
println!("Proof Generation Time: {:?}", t1);
println!("Proof verification Time: {:?}", t3);
}

View File

@ -10,7 +10,6 @@ pub fn generate_random_bytes(length: usize) -> Vec<u8> {
(0..length).map(|_| rng.gen::<u8>()).collect()
}
pub fn sha256_benchmark(size: usize) {
// Generate proof.

View File

@ -1,9 +1,19 @@
pub mod benches{
pub mod keccak;
pub mod sha256;
pub mod blake2;
pub mod blake3;
pub mod poseidon2;
}
use crate::benches::keccak::keccak_benchmark;
use crate::benches::sha256::sha256_benchmark;
use crate::benches::{
keccak::keccak_benchmark,
sha256::sha256_benchmark,
blake2::blake2_benchmark,
blake3::blake3_benchmark,
poseidon2::poseidon2_benchmark
};
use std::process;
fn main() {
@ -32,7 +42,17 @@ fn main() {
"blake2" => {
println!("Running blake2 benchmark: ");
let _ = keccak_benchmark(size);
let _ = blake2_benchmark(size);
}
"blake3" => {
println!("Running blake3 benchmark: ");
let _ = blake3_benchmark(size);
}
"poseidon2" => {
println!("Running poseidon2 benchmark: ");
let _ = poseidon2_benchmark(size);
}
_ => {