diff --git a/nexus/nullifier_test/Cargo.toml b/nexus/nullifier_test/Cargo.toml new file mode 100644 index 0000000..1ff8a81 --- /dev/null +++ b/nexus/nullifier_test/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "nullifier_test" +version = "0.1.0" +edition = "2024" + +[dependencies] +nexus-sdk = { git = "https://github.com/nexus-xyz/nexus-zkvm.git", tag = "0.3.4", version = "0.3.4" } + +[workspace] +members = [ + "src/guest" +] + + diff --git a/nexus/nullifier_test/rust-toolchain.toml b/nexus/nullifier_test/rust-toolchain.toml new file mode 100644 index 0000000..96e0415 --- /dev/null +++ b/nexus/nullifier_test/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly-2025-04-06" diff --git a/nexus/nullifier_test/src/guest/.cargo/config.toml b/nexus/nullifier_test/src/guest/.cargo/config.toml new file mode 100644 index 0000000..80e2c50 --- /dev/null +++ b/nexus/nullifier_test/src/guest/.cargo/config.toml @@ -0,0 +1,5 @@ +[target.riscv32i-unknown-none-elf] +rustflags = [ + "-C", "link-arg=-Tlink.x", +] +runner="nexus-run" diff --git a/nexus/nullifier_test/src/guest/Cargo.toml b/nexus/nullifier_test/src/guest/Cargo.toml new file mode 100644 index 0000000..127cfc7 --- /dev/null +++ b/nexus/nullifier_test/src/guest/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "guest" +version = "0.1.0" +edition = "2024" + +[dependencies] +nexus-rt = { git = "https://github.com/nexus-xyz/nexus-zkvm.git", tag = "0.3.4", version = "0.3.4" } +postcard = { version = "1.1.1", default-features = false, features = ["alloc"] } +jubjub = "0.10.0" +group = "0.13.0" +light-poseidon = "0.3.0" +ark-bn254 = "0.5.0" + +# Generated by cargo-nexus, do not remove! +# +[features] +cycles = [] # Enable cycle counting for run command + diff --git a/nexus/nullifier_test/src/guest/rust-toolchain.toml b/nexus/nullifier_test/src/guest/rust-toolchain.toml new file mode 100644 index 0000000..96e0415 --- /dev/null +++ b/nexus/nullifier_test/src/guest/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly-2025-04-06" diff --git a/nexus/nullifier_test/src/guest/src/main.rs b/nexus/nullifier_test/src/guest/src/main.rs new file mode 100644 index 0000000..e7e9b22 --- /dev/null +++ b/nexus/nullifier_test/src/guest/src/main.rs @@ -0,0 +1,31 @@ +#![cfg_attr(target_arch = "riscv32", no_std, no_main)] +use group::{Group, GroupEncoding}; +use ark_bn254::Fr; +use light_poseidon::PoseidonBytesHasher; + + +#[nexus_rt::main] +fn main() { + // TODO: do something with the input + let g1 = jubjub::SubgroupPoint::generator(); + let g2 = g1 + g1; + let g3 = g1 + g2; + let g4 = g1 + g3; + let g5 = g1 + g4; + + let s1 = jubjub::Fr::from(87329482u64); + let s2 = jubjub::Fr::from(37264829u64); + let s3 = jubjub::Fr::from(98098098u64); + let s4 = jubjub::Fr::from(63980948u64); + let s5 = jubjub::Fr::from(15098098u64); + + let utxo = g1*s1 + g2*s2 + g3*s3 + g4*s4 + g5*s5; + + let rep_nsk = s1.to_bytes(); + let rep_utxo = utxo.to_bytes(); + + //Note: Fr here is ark_bn254's and not jubjub's... + let mut poseidon = light_poseidon::Poseidon::::new_circom(2).unwrap(); + + let _ = poseidon.hash_bytes_le(&[&rep_utxo, &rep_nsk]); +} diff --git a/nexus/nullifier_test/src/main.rs b/nexus/nullifier_test/src/main.rs new file mode 100644 index 0000000..6ea72ac --- /dev/null +++ b/nexus/nullifier_test/src/main.rs @@ -0,0 +1,65 @@ +use nexus_sdk::{ + compile::{cargo::CargoPackager, Compile, Compiler}, + stwo::seq::Stwo, + ByGuestCompilation, Local, Prover, Verifiable, Viewable, +}; + +const PACKAGE: &str = "guest"; + +fn main() { + println!("Compiling guest program..."); + let mut prover_compiler = Compiler::::new(PACKAGE); + let prover: Stwo = + Stwo::compile(&mut prover_compiler).expect("failed to compile guest program"); + + let elf = prover.elf.clone(); // save elf for use with verification + + println!("Proving execution of vm..."); + let (view, proof) = prover.prove().expect("failed to prove program"); + + println!( + ">>>>> Logging\n{}<<<<<", + view.logs().expect("failed to retrieve debug logs").join("") + ); + assert_eq!( + view.exit_code().expect("failed to retrieve exit code"), + nexus_sdk::KnownExitCodes::ExitSuccess as u32 + ); + + // Normally the prover communicates the seralized proof to the verifier who deserializes it. + // + // The verifier must also possess the program binary and the public i/o. Usually, either + // the verifier will rebuild the elf in a reproducible way (e.g., within a container) or + // the prover will communicate it to the verifier who will then check that it is a valid + // compilation of the claimed guest program. Here we simulate the latter. + // + // If we instead wanted to simulate the former, it might look something like: + // + // println!("Verifier recompiling guest program..."); + // let mut verifier_compiler = Compiler::::new(PACKAGE); + // let path = verifier_compiler.build().expect("failed to (re)compile guest program"); + // + // print!("Verifying execution..."); + // proof.verify_expected_from_program_path::<&str, (), ()>( + // &(), // no public input + // nexus_sdk::KnownExitCodes::ExitSuccess as u32, + // &(), // no public output + // &path, // path to expected program binary + // &[] // no associated data, + // ).expect("failed to verify proof"); + + print!("Verifying execution..."); + + #[rustfmt::skip] + proof + .verify_expected::<(), ()>( + &(), // no public input + nexus_sdk::KnownExitCodes::ExitSuccess as u32, + &(), // no public output + &elf, // expected elf (program binary) + &[], // no associated data, + ) + .expect("failed to verify proof"); + + println!(" Succeeded!"); +} diff --git a/nexus/ped_vesta_test/src/guest/src/main.rs b/nexus/ped_vesta_test/src/guest/src/main.rs index b64f3f9..14418ad 100644 --- a/nexus/ped_vesta_test/src/guest/src/main.rs +++ b/nexus/ped_vesta_test/src/guest/src/main.rs @@ -1,19 +1,19 @@ #![cfg_attr(target_arch = "riscv32", no_std, no_main)] -use pasta_curves::group::Group; +//use pasta_curves::group::Group; #[nexus_rt::main] fn main() { - let g1 = pasta_curves::vesta::Point::generator(); - let g2 = g1 + g1; - let g3 = g1 + g2; - let g4 = g1 + g3; - let g5 = g1 + g4; + // let g1 = pasta_curves::vesta::Point::generator(); + // let g2 = g1 + g1; + // let g3 = g1 + g2; + // let g4 = g1 + g3; + // let g5 = g1 + g4; - let s1 = pasta_curves::vesta::Scalar::from(87329482u64); - let s2 = pasta_curves::vesta::Scalar::from(37264829u64); - let s3 = pasta_curves::vesta::Scalar::from(98098098u64); - let s4 = pasta_curves::vesta::Scalar::from(63980948u64); - let s5 = pasta_curves::vesta::Scalar::from(15098098u64); + //let s1 = pasta_curves::vesta::Scalar::from(87329482u64); + //let s2 = pasta_curves::vesta::Scalar::from(37264829u64); + //let s3 = pasta_curves::vesta::Scalar::from(98098098u64); + //let s4 = pasta_curves::vesta::Scalar::from(63980948u64); + //let s5 = pasta_curves::vesta::Scalar::from(15098098u64); - let _ = g1*s1 + g2*s2 + g3*s3 + g4*s4 + g5*s5; + // let _ = g1*s1 + g2*s2 + g3*s3 + g4*s4 + g5*s5; }