different .cfg & .sh file for merkle hashing and linear hashing, check for enough argument added and running from executable build from cargo build

This commit is contained in:
Manish Kumar 2024-01-08 22:53:37 +05:30
parent ac71b3f2a7
commit 8e0eaa92fb
12 changed files with 113 additions and 202 deletions

View File

@ -1,101 +1,12 @@
# RISC Zero Rust Starter Template Benchmarking different hashes inside risc'0 zkvm
-----------------------------------------------
Welcome to the RISC Zero Rust Starter Template! This template is intended to The benchmark is defined by the following shell scripts:
give you a starting point for building a project using the RISC Zero zkVM.
Throughout the template (including in this README), you'll find comments
labelled `TODO` in places where you'll need to make changes. To better
understand the concepts behind this template, check out the [zkVM
Overview][zkvm-overview].
## Quick Start - `build.sh` - build the code. you can set the number of threads by setting the environment variable `CARGO_BUILD_JOBS` otherwise the code will build using default number of threads.
First, make sure [rustup] is installed. The - `run.sh` and `run2.sh` - run the benchmark itself (`run.sh` for sha256, keccak, blake2b, blake3 and `run2.sh` for poseidon2 over bn128 and babybear)
[`rust-toolchain.toml`][rust-toolchain] file will be used by `cargo` to
automatically install the correct version.
To build all methods and execute the method within the zkVM, run the following Benchmarks can be parameterized using environment variables. By convention, we start the names of these environment variables with the `ZKBENCH_` prefix.
command:
```bash Additional files `bench.cfg` and `bench_tree.cfg` specifies the configurations and parameters.
cargo run
```
This is an empty template, and so there is no expected output (until you modify
the code).
### Running proofs remotely on Bonsai
_Note: The Bonsai proving service is still in early Alpha; an API key is
required for access. [Click here to request access][bonsai access]._
If you have access to the URL and API key to Bonsai you can run your proofs
remotely. To prove in Bonsai mode, invoke `cargo run` with two additional
environment variables:
```bash
BONSAI_API_KEY="YOUR_API_KEY" BONSAI_API_URL="BONSAI_URL" cargo run
```
## How to create a project based on this template
Search this template for the string `TODO`, and make the necessary changes to
implement the required feature described by the `TODO` comment. Some of these
changes will be complex, and so we have a number of instructional resources to
assist you in learning how to write your own code for the RISC Zero zkVM:
- The [RISC Zero Developer Docs][dev-docs] is a great place to get started.
- Example projects are available in the [examples folder][examples] of
[`risc0`][risc0-repo] repository.
- Reference documentation is available at [https://docs.rs][docs.rs], including
[`risc0-zkvm`][risc0-zkvm], [`cargo-risczero`][cargo-risczero],
[`risc0-build`][risc0-build], and [others][crates].
## Directory Structure
It is possible to organize the files for these components in various ways.
However, in this starter template we use a standard directory structure for zkVM
applications, which we think is a good starting point for your applications.
```text
project_name
├── Cargo.toml
├── host
│ ├── Cargo.toml
│ └── src
│ └── main.rs <-- [Host code goes here]
└── methods
├── Cargo.toml
├── build.rs
├── guest
│ ├── Cargo.toml
│ └── src
│ └── bin
│ └── method_name.rs <-- [Guest code goes here]
└── src
└── lib.rs
```
## Video Tutorial
For a walk-through of how to build with this template, check out this [excerpt
from our workshop at ZK HACK III][zkhack-iii].
## Questions, Feedback, and Collaborations
We'd love to hear from you on [Discord][discord] or [Twitter][twitter].
[bonsai access]: https://bonsai.xyz/apply
[cargo-risczero]: https://docs.rs/cargo-risczero
[crates]: https://github.com/risc0/risc0/blob/main/README.md#rust-binaries
[dev-docs]: https://dev.risczero.com
[discord]: https://discord.gg/risczero
[docs.rs]: https://docs.rs/releases/search?query=risc0
[examples]: https://github.com/risc0/risc0/tree/main/examples
[risc0-build]: https://docs.rs/risc0-build
[risc0-repo]: https://www.github.com/risc0/risc0
[risc0-zkvm]: https://docs.rs/risc0-zkvm
[rustup]: https://rustup.rs
[rust-toolchain]: rust-toolchain.toml
[twitter]: https://twitter.com/risczero
[zkvm-overview]: https://dev.risczero.com/zkvm
[zkhack-iii]: https://www.youtube.com/watch?v=Yg_BGqj_6lg&list=PLcPzhUaCxlCgig7ofeARMPwQ8vbuD6hC5&index=5

View File

@ -1,12 +1,11 @@
name: "Hashes benchmarking using risc0 prover" name: "Hashes benchmarking using risc0 prover"
author: author:
timeout: 100 timeout: 200
params: params:
[ PROVER: [ risc0 ] [ HASH_TYPE: [ "sha256", "keccak", "blake2b", "blake3"]
, INPUT_SIZE: [ 256, 512, 1024, 2048 ] , INPUT_SIZE_BYTES: [ 256, 512, 1024, 2048 ]
, WHICH: [ LINEAR ]
] ]
tags: CPU, SHA256, KECCAK, BLAKE2B, BLAKE3, POSEIDON2, BN128, BABYBEAR tags: risc0, $HASH_TYPE
comments: comments:
The benchmarks includes for sha256, keccak, blake2b, blake3 & poseidon2(merkle hashing). The benchmarks includes for sha256, keccak, blake2b, blake3.
the hashing is done inside the guest and receipt is received which is verified. the hashing is done inside the guest and receipt is received which is verified.

View File

@ -0,0 +1,11 @@
name: "Hashes benchmarking using risc0 prover"
author:
timeout: 1000
params:
[ HASH_TYPE: [ "poseidon2_babybear", "poseidon2_babybear_native", "poseidon2_bn128"]
, TREE_DEPTH: [ 2, 4, 8, 16 ]
]
tags: risc0, $HASH_TYPE
comments:
The benchmarks includes for poseidon2(merkle hashing) over bn128 and babybear.
the hashing is done inside the guest and receipt is received which is verified.

View File

@ -1,3 +1,7 @@
#!/bin/bash #!/bin/bash
cargo build --release if [ -z ${ZKBENCH_NTHREADS} ]; then
ZKBENCH_NTHREADS="default" # https://doc.rust-lang.org/cargo/reference/config.html#buildjobs
fi
CARGO_BUILD_JOBS=$ZKBENCH_NTHREADS cargo build --release

View File

@ -11,17 +11,3 @@ pub fn main() {
env::commit(&hash) env::commit(&hash)
} }
// accelerated sha2 crate
// #![no_main]
// use risc0_zkvm::{guest::env};
// use sha2::{Sha256, Digest};
// // use base16ct::lower::encode_str;
// risc0_zkvm::guest::entry!(main);
// pub fn main() {
// let data: Vec<u8> = env::read();
// let result: [u8;32] = Sha256::digest(data).into();
// env::commit(&result)
// }

View File

@ -3,35 +3,13 @@ if [ -z ${ZKBENCH_HASH_TYPE} ]; then
ZKBENCH_HASH_TYPE="sha256" ZKBENCH_HASH_TYPE="sha256"
fi fi
if [ -z ${ZKBENCH_WHICH} ]; then if [ -z ${ZKBENCH_INPUT_SIZE_BYTES} ]; then
ZKBENCH_WHICH="LINEAR" ZKBENCH_INPUT_SIZE_BYTES=1024
fi fi
if [ -z ${ZKBENCH_NTHREADS} ]; then
ZKBENCH_NTHREADS=1
fi
if [ -z ${ZKBENCH_INPUT_SIZE_KB} ]; then
ZKBENCH_INPUT_SIZE_KB=1024
fi
if [ -z ${ZKBENCH_TREE_DEPTH} ]; then
ZKBENCH_TREE_DEPTH=4
fi
echo "Running benchmarks with the following configurations:" echo "Running benchmarks with the following configurations:"
echo "HASH = $ZKBENCH_HASH_TYPE" echo "HASH = $ZKBENCH_HASH_TYPE"
# echo "WHICH = $ZKBENCH_WHICH" echo "Input Size (Bytes) = $ZKBENCH_INPUT_SIZE_BYTES"
echo "NTHREADS = $ZKBENCH_NTHREADS"
echo "Input Size (KB) = $ZKBENCH_INPUT_SIZE_KB"
# Run the benchmarks using cargo run # Run the benchmarks
# Check if the environment variable is set to "poseidon2_bn128" ./target/release/benchmark $ZKBENCH_HASH_TYPE $ZKBENCH_INPUT_SIZE_BYTES
if [[ "$ZKBENCH_HASH_TYPE" == "poseidon2_bn128" || "$ZKBENCH_HASH_TYPE" == "poseidon2_babybear" || "$ZKBENCH_HASH_TYPE" == "poseidon2_babybear_native" ]]; then
# echo "Running Poseidon2 benchmark over bn128 field"
CARGO_BUILD_JOBS=$ZKBENCH_NTHREADS cargo run $ZKBENCH_HASH_TYPE $ZKBENCH_TREE_DEPTH
else
CARGO_BUILD_JOBS=$ZKBENCH_NTHREADS cargo run $ZKBENCH_HASH_TYPE $ZKBENCH_INPUT_SIZE_KB
fi

15
hash/risc0/bench/run_tree.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
if [ -z ${ZKBENCH_HASH_TYPE} ]; then
ZKBENCH_HASH_TYPE="poseidon2_babybear_native"
fi
if [ -z ${ZKBENCH_TREE_DEPTH} ]; then
ZKBENCH_TREE_DEPTH=2
fi
echo "Running benchmarks with the following configurations:"
echo "HASH = $ZKBENCH_HASH_TYPE"
echo "Tree Depth = $ZKBENCH_TREE_DEPTH"
# Run the benchmarks
./target/release/benchmark $ZKBENCH_HASH_TYPE $ZKBENCH_TREE_DEPTH

View File

@ -42,6 +42,11 @@ pub fn poseidon2_babybear_bench(mt_depth: usize) {
let receipt = prover.prove_elf(env, POSEIDON2_BABYBEAR_ELF).unwrap(); let receipt = prover.prove_elf(env, POSEIDON2_BABYBEAR_ELF).unwrap();
let elapsed_time = start_time.elapsed(); let elapsed_time = start_time.elapsed();
// verify your receipt
receipt.verify(POSEIDON2_BABYBEAR_ID).unwrap();
let elapsed_time2 = start_time.elapsed();
// For example: // For example:
let output: Vec<Vec<u8>> = receipt.journal.decode().unwrap(); let output: Vec<Vec<u8>> = receipt.journal.decode().unwrap();
@ -52,12 +57,9 @@ pub fn poseidon2_babybear_bench(mt_depth: usize) {
} }
eprintln!("hash: {:?}", output_deseralised); eprintln!("hash: {:?}", output_deseralised);
eprintln!("Total time: {:?}", elapsed_time2);
eprintln!("Verification time: {:?}", elapsed_time2 - elapsed_time);
// verify your receipt
receipt.verify(POSEIDON2_BABYBEAR_ID).unwrap();
eprintln!("Total time: {:?}", elapsed_time);
// eprintln!("Hash: {:?}", hash_final); // eprintln!("Hash: {:?}", hash_final);

View File

@ -8,7 +8,6 @@ use risc0_zkvm::{
ExecutorEnv ExecutorEnv
}; };
use std::time::Instant; use std::time::Instant;
// use risc0_core::field::baby_bear::BabyBearElem;
use rand::Rng; use rand::Rng;
pub fn poseidon2_babybear_native_bench(mt_depth: usize) { pub fn poseidon2_babybear_native_bench(mt_depth: usize) {
@ -33,24 +32,16 @@ pub fn poseidon2_babybear_native_bench(mt_depth: usize) {
let receipt = prover.prove_elf(env, POSEIDON2_BABYBEAR_NATIVE_ELF).unwrap(); let receipt = prover.prove_elf(env, POSEIDON2_BABYBEAR_NATIVE_ELF).unwrap();
let elapsed_time = start_time.elapsed(); let elapsed_time = start_time.elapsed();
// For example:
let output: Vec<u32> = receipt.journal.decode().unwrap();
// let mut output_deseralised: Vec<Scalar> = Vec::new();
// for i in 0..output.len() {
// output_deseralised.push(Scalar::deserialize_uncompressed(&**output.get(i).unwrap()).unwrap());
// }
eprintln!("hash: {:?}", output);
// let hash_final = FpBabyBear::deserialize_uncompressed(&*output).unwrap();
// verify your receipt // verify your receipt
receipt.verify(POSEIDON2_BABYBEAR_NATIVE_ID).unwrap(); receipt.verify(POSEIDON2_BABYBEAR_NATIVE_ID).unwrap();
let elapsed_time2 = start_time.elapsed();
eprintln!("Total time: {:?}", elapsed_time);
// eprintln!("Hash: {:?}", hash_final);
let output: Vec<u32> = receipt.journal.decode().unwrap();
eprintln!("hash: {:?}", output);
eprintln!("Total time: {:?}", elapsed_time2);
eprintln!("Verification time: {:?}", elapsed_time2 - elapsed_time);
} }

View File

@ -30,16 +30,19 @@ pub fn poseidon2_bn128_bench(mt_depth: usize) {
let receipt = prover.prove_elf(env, POSEIDON2_BN128_ELF).unwrap(); let receipt = prover.prove_elf(env, POSEIDON2_BN128_ELF).unwrap();
let elapsed_time = start_time.elapsed(); let elapsed_time = start_time.elapsed();
// verify your receipt
receipt.verify(POSEIDON2_BN128_ID).unwrap();
let elapsed_time2 = start_time.elapsed();
// For example: // For example:
let output: Vec<u8> = receipt.journal.decode().unwrap(); let output: Vec<u8> = receipt.journal.decode().unwrap();
let hash_final = Scalar::deserialize_uncompressed(&*output).unwrap(); let hash_final = Scalar::deserialize_uncompressed(&*output).unwrap();
// verify your receipt
receipt.verify(POSEIDON2_BN128_ID).unwrap();
eprintln!("Total time: {:?}", elapsed_time);
eprintln!("Hash: {:?}", hash_final); eprintln!("Hash: {:?}", hash_final);
eprintln!("Total time: {:?}", elapsed_time2);
eprintln!("Verification time: {:?}", elapsed_time2 - elapsed_time);
} }

View File

@ -3,34 +3,35 @@ use methods::{
}; };
use risc0_zkvm::{default_prover, ExecutorEnv}; use risc0_zkvm::{default_prover, ExecutorEnv};
use risc0_zkvm::{ sha}; use risc0_zkvm::{ sha};
// use sha2;
// use rand::RngCore;
use std::time::Instant; use std::time::Instant;
use hex::encode;
pub fn sha_bench(input: Vec<u8>) { pub fn sha_bench(input: Vec<u8>) {
let env = ExecutorEnv::builder().write(&input).unwrap().build().unwrap(); let env = ExecutorEnv::builder().write(&input).unwrap().build().unwrap();
// Obtain the default prover. // Obtain the default prover.
let prover = default_prover(); let prover = default_prover();
eprintln!("------risc0_zkvm sha hashing------"); eprintln!("\n------risc0_zkvm sha hashing------\n");
let start_time = Instant::now(); let start_time = Instant::now();
// Produce a receipt by proving the specified ELF binary. // Produce a receipt by proving the specified ELF binary.
let receipt = prover.prove_elf(env, SHA256_ELF).unwrap(); let receipt = prover.prove_elf(env, SHA256_ELF).unwrap();
let elapsed_time = start_time.elapsed(); let elapsed_time = start_time.elapsed();
// For example:
let _output: sha::Digest = receipt.journal.decode().unwrap();
// verify your receipt // verify your receipt
receipt.verify(SHA256_ID).unwrap(); receipt.verify(SHA256_ID).unwrap();
eprintln!("Total time: {:?}", elapsed_time); let elapsed_time2 = start_time.elapsed();
let _output: sha::Digest = receipt.journal.decode().unwrap();
eprintln!("Total time: {:?}", elapsed_time2);
eprintln!("Verification time: {:?}", elapsed_time2 - elapsed_time);
eprintln!("Hash: {:?}", _output); eprintln!("Hash: {:?}", _output);
let env = ExecutorEnv::builder().write(&input).unwrap().build().unwrap(); let env = ExecutorEnv::builder().write(&input).unwrap().build().unwrap();
eprintln!("------RustCrypto sha hashing------"); eprintln!("\n------RustCrypto sha hashing(accelerated)------\n");
// Obtain the default prover. // Obtain the default prover.
let prover = default_prover(); let prover = default_prover();
@ -39,12 +40,15 @@ pub fn sha_bench(input: Vec<u8>) {
let receipt = prover.prove_elf(env, SHA256_ACCELERATED_ELF).unwrap(); let receipt = prover.prove_elf(env, SHA256_ACCELERATED_ELF).unwrap();
let elapsed_time = start_time.elapsed(); let elapsed_time = start_time.elapsed();
// For example:
let _output: [u8;32] = receipt.journal.decode().unwrap();
// verify your receipt // verify your receipt
receipt.verify(SHA256_ACCELERATED_ID).unwrap(); receipt.verify(SHA256_ACCELERATED_ID).unwrap();
eprintln!("Total time: {:?}", elapsed_time); let elapsed_time2 = start_time.elapsed();
eprintln!("Hash: {:?}", _output);
let _output: [u8;32] = receipt.journal.decode().unwrap();
let hash = encode(_output);
eprintln!("Total time: {:?}", elapsed_time2);
eprintln!("Verification time: {:?}", elapsed_time2 - elapsed_time);
eprintln!("Hash: {:?}", hash);
} }

View File

@ -9,6 +9,7 @@ use benches::{
poseidon2_babybear_native::poseidon2_babybear_native_bench, poseidon2_babybear_native::poseidon2_babybear_native_bench,
}; };
use rand::Rng; use rand::Rng;
use std::process;
fn generate_bytes(size: usize) -> Vec<u8> { fn generate_bytes(size: usize) -> Vec<u8> {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
@ -19,56 +20,62 @@ fn generate_bytes(size: usize) -> Vec<u8> {
fn main() { fn main() {
let args: Vec<String> = std::env::args().collect(); let args: Vec<String> = std::env::args().collect();
if args.len() != 3 {
println!("Wrong number of arguments");
// Exit the program with a non-zero exit code
process::exit(1);
}
let hash_type = &args[1]; let hash_type = &args[1];
let size_kb = args[2].parse::<usize>().unwrap(); let size = args[2].parse::<usize>().unwrap();
match hash_type.as_str() { match hash_type.as_str() {
"sha256" => { "sha256" => {
println!("SHA256 Benchmarking: "); println!("SHA256 Benchmarking: ");
eprintln!("data size(bytes): {:?}", size_kb); eprintln!("data size(bytes): {:?}", size);
let input = generate_bytes(size_kb); let input = generate_bytes(size);
sha_bench(input.clone()); sha_bench(input.clone());
} }
"keccak" => { "keccak" => {
println!("KECCAK Benchmarking: "); println!("KECCAK Benchmarking: ");
eprintln!("data size(bytes): {:?}", size_kb); eprintln!("data size(bytes): {:?}", size);
let input = generate_bytes(size_kb); let input = generate_bytes(size);
keccak_bench(input.clone()); keccak_bench(input.clone());
} }
"blake2b" => { "blake2b" => {
println!("Blake2b Benchmarking: "); println!("Blake2b Benchmarking: ");
eprintln!("data size(bytes): {:?}", size_kb); eprintln!("data size(bytes): {:?}", size);
let input = generate_bytes(size_kb); let input = generate_bytes(size);
blake2b_bench(input.clone()); blake2b_bench(input.clone());
} }
"blake3" => { "blake3" => {
println!("Blake3 Benchmarking: "); println!("Blake3 Benchmarking: ");
eprintln!("data size(bytes): {:?}", size_kb); eprintln!("data size(bytes): {:?}", size);
let input = generate_bytes(size_kb); let input = generate_bytes(size);
blake3_bench(input.clone()); blake3_bench(input.clone());
} }
"poseidon2_bn128" => { "poseidon2_bn128" => {
println!("Poseidon2 Benchmarking on the BN128 field: "); println!("Poseidon2 Benchmarking on the BN128 field: ");
eprintln!("Tree Depth: {:?}", size_kb); eprintln!("Tree Depth: {:?}", size);
poseidon2_bn128_bench(size_kb); poseidon2_bn128_bench(size);
} }
"poseidon2_babybear" => { "poseidon2_babybear" => {
println!("Poseidon2 Benchmarking on the BabyBear field: "); println!("Poseidon2 Benchmarking on the BabyBear field: ");
eprintln!("Tree Depth: {:?}", size_kb); eprintln!("Tree Depth: {:?}", size);
eprintln!("number of inputs {:?}", (1 << size_kb) * 8); eprintln!("number of inputs {:?}", (1 << size) * 8);
poseidon2_babybear_bench(size_kb); poseidon2_babybear_bench(size);
} }
"poseidon2_babybear_native" => { "poseidon2_babybear_native" => {
println!("Poseidon2 Benchmarking on the BabyBear field: "); println!("Poseidon2 Benchmarking on the BabyBear field: ");
eprintln!("Tree Depth: {:?}", size_kb); eprintln!("Tree Depth: {:?}", size);
eprintln!("number of inputs {:?}", (1 << size_kb) * 8); eprintln!("number of inputs {:?}", (1 << size) * 8);
poseidon2_babybear_native_bench(size_kb); poseidon2_babybear_native_bench(size);
} }
_ => { _ => {