diff --git a/hash/sp1/bench/.gitignore b/hash/sp1/bench/.gitignore new file mode 100644 index 0000000..0be6e72 --- /dev/null +++ b/hash/sp1/bench/.gitignore @@ -0,0 +1,16 @@ +# Cargo build +**/target + +# Cargo config +.cargo + +# Profile-guided optimization +/tmp +pgo-data.profdata + +# MacOS nuisances +.DS_Store + +# Proofs +**/proof-with-pis.json +**/proof-with-io.json diff --git a/hash/sp1/bench/keccak/Cargo.toml b/hash/sp1/bench/keccak/Cargo.toml new file mode 100644 index 0000000..2d61e41 --- /dev/null +++ b/hash/sp1/bench/keccak/Cargo.toml @@ -0,0 +1,9 @@ +[workspace] +[package] +version = "0.1.0" +name = "keccak-program" +edition = "2021" + +[dependencies] +sp1-zkvm = { git = "https://github.com/succinctlabs/sp1.git" } +sha3 = "0.10.8" \ No newline at end of file diff --git a/hash/sp1/bench/keccak/elf/riscv32im-succinct-zkvm-elf b/hash/sp1/bench/keccak/elf/riscv32im-succinct-zkvm-elf new file mode 100755 index 0000000..9c17edc Binary files /dev/null and b/hash/sp1/bench/keccak/elf/riscv32im-succinct-zkvm-elf differ diff --git a/hash/sp1/bench/keccak/src/main.rs b/hash/sp1/bench/keccak/src/main.rs new file mode 100644 index 0000000..b7fd57e --- /dev/null +++ b/hash/sp1/bench/keccak/src/main.rs @@ -0,0 +1,20 @@ + +#![no_main] +sp1_zkvm::entrypoint!(main); +use sha3::{Digest, Keccak256}; + +pub fn main() { + + let input = sp1_zkvm::io::read::>(); + + // create a keccak object + let mut hasher = Keccak256::new(); + + // write input message + hasher.update(input); + + // read hash digest + let result: [u8;32] = hasher.finalize().into(); + + sp1_zkvm::io::write(&result); +} diff --git a/hash/sp1/bench/script/Cargo.toml b/hash/sp1/bench/script/Cargo.toml new file mode 100644 index 0000000..0b5f047 --- /dev/null +++ b/hash/sp1/bench/script/Cargo.toml @@ -0,0 +1,10 @@ +[workspace] +[package] +version = "0.1.0" +name = "bench-script" +edition = "2021" + +[dependencies] +sp1-core = { git = "https://github.com/succinctlabs/sp1.git" } +rand = "0.8" +hex = "0.4" \ No newline at end of file diff --git a/hash/sp1/bench/script/rust-toolchain b/hash/sp1/bench/script/rust-toolchain new file mode 100644 index 0000000..f7ee87e --- /dev/null +++ b/hash/sp1/bench/script/rust-toolchain @@ -0,0 +1,3 @@ +[toolchain] +channel = "nightly-2024-01-25" +components = ["llvm-tools", "rustc-dev"] \ No newline at end of file diff --git a/hash/sp1/bench/script/src/benches/keccak.rs b/hash/sp1/bench/script/src/benches/keccak.rs new file mode 100644 index 0000000..2ede7ca --- /dev/null +++ b/hash/sp1/bench/script/src/benches/keccak.rs @@ -0,0 +1,42 @@ + +use sp1_core::{SP1Prover, SP1Stdin, SP1Verifier}; +use rand::Rng; +use hex::encode; + +const KECCAK_ELF: &[u8] = include_bytes!("../../../keccak/elf/riscv32im-succinct-zkvm-elf"); + +pub fn generate_random_bytes(length: usize) -> Vec { + let mut rng = rand::thread_rng(); + (0..length).map(|_| rng.gen::()).collect() +} + + +pub fn keccak_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(KECCAK_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(KECCAK_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); +} diff --git a/hash/sp1/bench/script/src/benches/sha256.rs b/hash/sp1/bench/script/src/benches/sha256.rs new file mode 100644 index 0000000..eff61f3 --- /dev/null +++ b/hash/sp1/bench/script/src/benches/sha256.rs @@ -0,0 +1,43 @@ + +use sp1_core::{SP1Prover, SP1Stdin, SP1Verifier}; +use rand::Rng; +use hex::encode; + +const SHA256_ELF: &[u8] = include_bytes!("../../../sha256/elf/riscv32im-succinct-zkvm-elf"); + +pub fn generate_random_bytes(length: usize) -> Vec { + let mut rng = rand::thread_rng(); + (0..length).map(|_| rng.gen::()).collect() +} + + +pub fn sha256_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(SHA256_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(SHA256_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); +} diff --git a/hash/sp1/bench/script/src/main.rs b/hash/sp1/bench/script/src/main.rs new file mode 100644 index 0000000..267dc58 --- /dev/null +++ b/hash/sp1/bench/script/src/main.rs @@ -0,0 +1,37 @@ +pub mod benches{ + pub mod keccak; + pub mod sha256; +} +use crate::benches::keccak::keccak_benchmark; +use crate::benches::sha256::sha256_benchmark; +use std::process; + +fn main() { + let args: Vec = std::env::args().collect(); + + if args.len() != 3 { + println!("Wrong number of arguments! The program expects two arguments: and "); + // Exit the program with a non-zero exit code + process::exit(1); + } + + let bench_type = &args[1]; + let size = args[2].parse::().unwrap(); + + match bench_type.as_str() { + + "sha256" => { + println!("Running sha256: "); + let _ = sha256_benchmark(size); + } + + "keccak" => { + println!("Running keccak benchmark: "); + let _ = keccak_benchmark(size); + } + + _ => { + println!("Wrong Benchmark Name!"); + } + } +} diff --git a/hash/sp1/bench/sha256/Cargo.toml b/hash/sp1/bench/sha256/Cargo.toml new file mode 100644 index 0000000..9973ccb --- /dev/null +++ b/hash/sp1/bench/sha256/Cargo.toml @@ -0,0 +1,10 @@ +[workspace] +[package] +version = "0.1.0" +name = "sha256-program" +edition = "2021" + +[dependencies] +sp1-zkvm = { git = "https://github.com/succinctlabs/sp1.git" } +sha2-v0-10-8 = { git = "https://github.com/sp1-patches/RustCrypto-hashes", package = "sha2", branch = "patch-v0.10.8" } + diff --git a/hash/sp1/bench/sha256/elf/riscv32im-succinct-zkvm-elf b/hash/sp1/bench/sha256/elf/riscv32im-succinct-zkvm-elf new file mode 100755 index 0000000..d5f80e9 Binary files /dev/null and b/hash/sp1/bench/sha256/elf/riscv32im-succinct-zkvm-elf differ diff --git a/hash/sp1/bench/sha256/src/main.rs b/hash/sp1/bench/sha256/src/main.rs new file mode 100644 index 0000000..e5223fd --- /dev/null +++ b/hash/sp1/bench/sha256/src/main.rs @@ -0,0 +1,22 @@ + +#![no_main] +sp1_zkvm::entrypoint!(main); + +//The patched sha2 rust crate https://github.com/sp1-patches/RustCrypto-hashes +use sha2_v0_10_8::{Digest, Sha256}; + +pub fn main() { + + let input = sp1_zkvm::io::read::>(); + + // create a Sha256 object + let mut hasher = Sha256::new(); + + // write input message + hasher.update(input); + + // read hash digest + let result: [u8;32] = hasher.finalize().into(); + + sp1_zkvm::io::write(&result); +}