From 0d6f1a7c2a45d1b2043af432cb413e116107eac9 Mon Sep 17 00:00:00 2001 From: Yuwen Zhang Date: Mon, 7 Oct 2024 12:00:50 -0700 Subject: [PATCH] chore: cleanup (#2) --- Cargo.lock | 4 +-- README.md | 4 +++ example/README.md | 13 ++++++++- example/script/Cargo.lock | 3 +-- example/script/Cargo.toml | 3 +-- example/script/src/main.rs | 49 +++++++++++++++++++++------------- example/vk/groth16_v2.0.0.bin | Bin 0 -> 520 bytes verifier/src/lib.rs | 6 ++--- 8 files changed, 53 insertions(+), 29 deletions(-) create mode 100644 example/vk/groth16_v2.0.0.bin diff --git a/Cargo.lock b/Cargo.lock index d82dcd4..084d84b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1548,9 +1548,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.3.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] diff --git a/README.md b/README.md index fc0bb03..228786e 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ A Groth16 verifier implementation for Solana using BN254 precompiles. This crate verifies Groth16 proofs generated with SP1, leveraging Solana's BN254 precompiles for efficient cryptographic operations. +> [!CAUTION] +> +> This repository is under active development and is not yet ready for production use. + ## Features - **Groth16 Proof Verification**: Implements the Groth16 protocol for zero-knowledge proof verification. diff --git a/example/README.md b/example/README.md index 5fc43fe..cf4b487 100644 --- a/example/README.md +++ b/example/README.md @@ -19,4 +19,15 @@ And run the following commands: cd script cargo build RUST_LOG=info cargo run --release -- --elf fibonacci -``` \ No newline at end of file +``` + +Pass in the `--prove` flag to generate a fresh proof and save it to a file: + +```shell +cd script +cargo build +RUST_LOG=info cargo run --release -- --elf fibonacci --prove +``` + +Note: The pre-generated proof for `fibonacci` assumes the input `n` is 20. The pre-generated proof +for `is-prime` assumes the input `n` is 11. \ No newline at end of file diff --git a/example/script/Cargo.lock b/example/script/Cargo.lock index dc02735..fae3ef7 100644 --- a/example/script/Cargo.lock +++ b/example/script/Cargo.lock @@ -1850,7 +1850,7 @@ dependencies = [ ] [[package]] -name = "example-usage" +name = "example" version = "0.1.0" dependencies = [ "clap", @@ -1859,7 +1859,6 @@ dependencies = [ "num-bigint 0.4.6", "num-traits", "sp1-helper", - "sp1-prover", "sp1-sdk", "strum 0.25.0", "strum_macros 0.25.3", diff --git a/example/script/Cargo.toml b/example/script/Cargo.toml index 52ac3cf..ea4a7ee 100644 --- a/example/script/Cargo.toml +++ b/example/script/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "example-usage" +name = "example" authors = ["Bhargav Annem"] version = "0.1.0" edition = "2021" @@ -10,7 +10,6 @@ hex = "0.4.3" num-bigint = "0.4.6" num-traits = "0.2.19" groth16-solana = { path = "../../verifier" } -sp1-prover = "2.0.0" sp1-sdk = "2.0.0" strum = "0.25" strum_macros = "0.25" diff --git a/example/script/src/main.rs b/example/script/src/main.rs index 22f7f66..d00ffa7 100644 --- a/example/script/src/main.rs +++ b/example/script/src/main.rs @@ -13,8 +13,7 @@ pub const SHA2_ELF: &[u8] = include_bytes!("../../elfs/sha2-riscv32im-succinct-z pub const TENDERMINT_ELF: &[u8] = include_bytes!("../../elfs/tendermint-riscv32im-succinct-zkvm-elf"); -pub(crate) const GROTH16_VK_BYTES: &[u8] = - include_bytes!("../../../../.sp1/circuits/v2.0.0/groth16_vk.bin"); +pub const GROTH16_VK_BYTES: &[u8] = include_bytes!("../../vk/groth16_v2.0.0.bin"); #[derive(clap::Parser)] #[command(name = "zkVM Proof Generator")] @@ -26,6 +25,13 @@ struct Cli { help = "Specifies the ELF file to use (e.g., fibonacci, is-prime)" )] elf: String, + #[arg( + long, + value_name = "prove", + default_value = "false", + help = "Specifies the ELF file to use (e.g., fibonacci, is-prime)" + )] + prove: bool, } #[derive(Debug, EnumString, EnumIter, Display)] @@ -52,10 +58,10 @@ impl Elf { } fn main() { - // Setup logging for the application + // Setup logging for the application. utils::setup_logger(); - // Parse command line arguments + // Parse command line arguments. let args = Cli::parse(); let mut stdin = SP1Stdin::new(); @@ -75,20 +81,25 @@ fn main() { Elf::Sha2 | Elf::Tendermint => elf_enum.get_elf(), }; - // Initialize the prover client - let client = ProverClient::new(); - let (pk, _) = client.setup(elf); - - // Generate a proof for the specified program - let proof = client - .prove(&pk, stdin) - .groth16() - .run() - .expect("Groth16 proof generation failed"); - - // Save the generated proof to a binary file + // Where to save / load the proof from. let proof_file = format!("../binaries/{}_proof.bin", args.elf); - proof.save(&proof_file).unwrap(); + + // Only generate a proof if the prove flag is set. + if args.prove { + // Initialize the prover client + let client = ProverClient::new(); + let (pk, _) = client.setup(elf); + + // Generate a proof for the specified program. + let proof = client + .prove(&pk, stdin) + .groth16() + .run() + .expect("Groth16 proof generation failed"); + + // Save the generated proof to `proof_file`. + proof.save(&proof_file).unwrap(); + } // Load the saved proof and convert it to a Groth16 proof let (raw_proof, public_inputs) = SP1ProofWithPublicValues::load(&proof_file) @@ -101,7 +112,7 @@ fn main() { }) .expect("Failed to load proof"); - // Convert public inputs to byte representations + // Convert public inputs to byte representations. let vkey_hash = BigUint::from_str_radix(&public_inputs[0], 10) .unwrap() .to_bytes_be(); @@ -141,7 +152,7 @@ mod tests { }) .expect("Failed to load proof"); - // Convert public inputs to byte representations + // Convert public inputs to byte representations. let vkey_hash = BigUint::from_str_radix(&public_inputs[0], 10) .unwrap() .to_bytes_be(); diff --git a/example/vk/groth16_v2.0.0.bin b/example/vk/groth16_v2.0.0.bin new file mode 100644 index 0000000000000000000000000000000000000000..0821162b88095d85bafefd362759ee56dec711ff GIT binary patch literal 520 zcmV+j0{8u^lfdP>_#zosviH}G9WI31|4V{Y6g~X%m3S1aG zsolliTlA8rumEy}Cw2hIFq6wN&{D((QkkG^E)A;8Dw^)9IsFupr_E|xlPt&Bxkz6F zlP(3w+i5GgN@kK2?-ocKzAmg$a%r%gY%|Nq*h&SZCh**0No}ujGtGCeiLGB^8EwY{ z!2Gw(i*NGP(!1zn(gZn&=~R<9*f0zPvU3huDm(y44lZ@!6Ay?+Tq_2G zA$o$;n2+4Ktnw6N5`otTU=lT|wNKRFzug#z{Jqft0002mvQMfBD7kDKezoO=tn4)7 z!JJ7Fr78?QJJ%US2%`uIJz=VvUz|X6mQOOq`0K>q> { } pub fn decompress_g1(g1_bytes: &[u8; 32]) -> Result<[u8; 64], Error> { - let g1_bytes = gnark_commpressed_x_to_ark_commpressed_x(g1_bytes)?; + let g1_bytes = gnark_compressed_x_to_ark_compressed_x(g1_bytes)?; let g1_bytes = convert_endianness::<32, 32>(&g1_bytes.as_slice().try_into().unwrap()); groth16_solana::decompression::decompress_g1(&g1_bytes).map_err(|_| Error::G1CompressionError) } pub fn decompress_g2(g2_bytes: &[u8; 64]) -> Result<[u8; 128], Error> { - let g2_bytes = gnark_commpressed_x_to_ark_commpressed_x(g2_bytes)?; + let g2_bytes = gnark_compressed_x_to_ark_compressed_x(g2_bytes)?; let g2_bytes = convert_endianness::<64, 64>(&g2_bytes.as_slice().try_into().unwrap()); groth16_solana::decompression::decompress_g2(&g2_bytes).map_err(|_| Error::G2CompressionError) } @@ -100,7 +100,7 @@ fn gnark_flag_to_ark_flag(msb: u8) -> Result { Ok(msb & !ARK_MASK | ark_flag) } -fn gnark_commpressed_x_to_ark_commpressed_x(x: &[u8]) -> Result, Error> { +fn gnark_compressed_x_to_ark_compressed_x(x: &[u8]) -> Result, Error> { if x.len() != 32 && x.len() != 64 { return Err(Error::InvalidInput); }