diff --git a/goas/cl/ledger/src/input.rs b/goas/cl/ledger/src/input.rs deleted file mode 100644 index f1ea9ee..0000000 --- a/goas/cl/ledger/src/input.rs +++ /dev/null @@ -1,181 +0,0 @@ -use ledger_proof_statements::input::{InputPrivate, InputPublic}; - -use crate::error::{Error, Result}; - -const MAX_NOTE_COMMS: usize = 2usize.pow(8); - -#[derive(Debug, Clone)] -pub struct ProvedInput { - pub input: InputPublic, - pub risc0_receipt: risc0_zkvm::Receipt, -} - -impl ProvedInput { - pub fn prove( - input: &cl::InputWitness, - note_commitments: &[cl::NoteCommitment], - ) -> Result { - let output_cm = input.note_commitment(); - - let cm_leaves = note_commitment_leaves(note_commitments); - let cm_idx = note_commitments - .iter() - .position(|c| c == &output_cm) - .unwrap(); - let cm_path = cl::merkle::path(cm_leaves, cm_idx); - - let secrets = InputPrivate { - input: *input, - cm_path, - }; - - let env = risc0_zkvm::ExecutorEnv::builder() - .write(&secrets) - .unwrap() - .build() - .unwrap(); - - // Obtain the default prover. - let prover = risc0_zkvm::default_prover(); - - let start_t = std::time::Instant::now(); - - // Proof information by proving the specified ELF binary. - // This struct contains the receipt along with statistics about execution of the guest - let opts = risc0_zkvm::ProverOpts::succinct(); - let prove_info = prover - .prove_with_opts(env, nomos_cl_risc0_proofs::INPUT_ELF, &opts) - .map_err(|_| Error::Risc0ProofFailed)?; - - println!( - "STARK 'input' prover time: {:.2?}, total_cycles: {}", - start_t.elapsed(), - prove_info.stats.total_cycles - ); - // extract the receipt. - let receipt = prove_info.receipt; - - Ok(Self { - input: InputPublic { - cm_root: cl::merkle::root(cm_leaves), - input: input.commit(), - }, - risc0_receipt: receipt, - }) - } - - pub fn public(&self) -> Result { - Ok(self.risc0_receipt.journal.decode()?) - } - - pub fn verify(&self) -> bool { - let Ok(proved_public_inputs) = self.public() else { - return false; - }; - - self.input == proved_public_inputs - && self - .risc0_receipt - .verify(nomos_cl_risc0_proofs::INPUT_ID) - .is_ok() - } -} - -fn note_commitment_leaves(note_commitments: &[cl::NoteCommitment]) -> [[u8; 32]; MAX_NOTE_COMMS] { - let note_comm_bytes = Vec::from_iter(note_commitments.iter().map(|c| c.as_bytes().to_vec())); - let cm_leaves = cl::merkle::padded_leaves::(¬e_comm_bytes); - cm_leaves -} - -#[cfg(test)] -mod test { - use super::*; - use cl::note::unit_point; - use rand::thread_rng; - - #[test] - fn test_input_prover() { - let nmo = unit_point("NMO"); - - let mut rng = thread_rng(); - - let input = cl::InputWitness { - note: cl::NoteWitness::basic(32, nmo), - balance_blinding: cl::BalanceWitness::random(&mut rng), - nf_sk: cl::NullifierSecret::random(&mut rng), - nonce: cl::NullifierNonce::random(&mut rng), - }; - - let notes = vec![input.note_commitment()]; - - let mut proved_input = ProvedInput::prove(&input, ¬es).unwrap(); - - let expected_public_inputs = InputPublic { - cm_root: cl::merkle::root(note_commitment_leaves(¬es)), - input: input.commit(), - }; - - assert_eq!(proved_input.input, expected_public_inputs); - assert!(proved_input.verify()); - - let wrong_public_inputs = [ - InputPublic { - cm_root: cl::merkle::root([cl::merkle::leaf(b"bad_root")]), - ..expected_public_inputs - }, - InputPublic { - input: cl::Input { - nullifier: cl::Nullifier::new( - cl::NullifierSecret::random(&mut rng), - input.note_commitment(), - ), - ..expected_public_inputs.input - }, - ..expected_public_inputs - }, - InputPublic { - input: cl::Input { - death_cm: cl::note::death_commitment(b"wrong death vk"), - ..expected_public_inputs.input - }, - ..expected_public_inputs - }, - InputPublic { - input: cl::Input { - balance: cl::BalanceWitness::random(&mut rng) - .commit(&cl::NoteWitness::basic(32, nmo)), - ..expected_public_inputs.input - }, - ..expected_public_inputs - }, - ]; - - for wrong_input in wrong_public_inputs { - proved_input.input = wrong_input; - assert!(!proved_input.verify()); - } - } - - // ----- The following tests still need to be built. ----- - // #[test] - // fn test_input_ptx_coupling() { - // let mut rng = rand::thread_rng(); - - // let note = cl::NoteWitness::new(10, "NMO", [0u8; 32], &mut rng); - // let nf_sk = cl::NullifierSecret::random(&mut rng); - // let nonce = cl::NullifierNonce::random(&mut rng); - - // let witness = cl::InputWitness { note, nf_sk, nonce }; - - // let input = witness.commit(); - - // let ptx_root = cl::PtxRoot::random(&mut rng); - // let proof = input.prove(&witness, ptx_root, vec![]).unwrap(); - - // assert!(input.verify(ptx_root, &proof)); - - // // The same input proof can not be used in another partial transaction. - // let another_ptx_root = cl::PtxRoot::random(&mut rng); - // assert!(!input.verify(another_ptx_root, &proof)); - // } -} diff --git a/goas/cl/ledger/src/lib.rs b/goas/cl/ledger/src/lib.rs index d5b1744..e365360 100644 --- a/goas/cl/ledger/src/lib.rs +++ b/goas/cl/ledger/src/lib.rs @@ -1,8 +1,6 @@ pub mod bundle; pub mod death_constraint; pub mod error; -pub mod input; -pub mod output; pub mod partial_tx; pub use death_constraint::DeathProof; diff --git a/goas/cl/ledger/src/output.rs b/goas/cl/ledger/src/output.rs deleted file mode 100644 index 89a9238..0000000 --- a/goas/cl/ledger/src/output.rs +++ /dev/null @@ -1,119 +0,0 @@ -use crate::error::{Error, Result}; - -pub struct ProvedOutput { - pub output: cl::Output, - pub risc0_receipt: risc0_zkvm::Receipt, -} - -impl ProvedOutput { - pub fn prove(witness: &cl::OutputWitness) -> Result { - let env = risc0_zkvm::ExecutorEnv::builder() - .write(&witness) - .unwrap() - .build() - .unwrap(); - - let prover = risc0_zkvm::default_prover(); - - let start_t = std::time::Instant::now(); - - let opts = risc0_zkvm::ProverOpts::succinct(); - let prove_info = prover - .prove_with_opts(env, nomos_cl_risc0_proofs::OUTPUT_ELF, &opts) - .map_err(|_| Error::Risc0ProofFailed)?; - - println!( - "STARK 'output' prover time: {:.2?}, total_cycles: {}", - start_t.elapsed(), - prove_info.stats.total_cycles - ); - - let receipt = prove_info.receipt; - - Ok(Self { - output: witness.commit(), - risc0_receipt: receipt, - }) - } - - pub fn public(&self) -> Result { - Ok(self.risc0_receipt.journal.decode()?) - } - - pub fn verify(&self) -> bool { - let Ok(output_commitments) = self.public() else { - return false; - }; - - self.output == output_commitments - && self - .risc0_receipt - .verify(nomos_cl_risc0_proofs::OUTPUT_ID) - .is_ok() - } -} - -#[cfg(test)] -mod test { - use super::*; - use cl::note::unit_point; - use rand::thread_rng; - - #[test] - fn test_output_prover() { - let nmo = unit_point("NMO"); - - let mut rng = thread_rng(); - - let output = cl::OutputWitness { - note: cl::NoteWitness::basic(32, nmo), - balance_blinding: cl::BalanceWitness::random(&mut rng), - nf_pk: cl::NullifierSecret::random(&mut rng).commit(), - nonce: cl::NullifierNonce::random(&mut rng), - }; - - let mut proved_output = ProvedOutput::prove(&output).unwrap(); - - let expected_output_cm = output.commit(); - - assert_eq!(proved_output.output, expected_output_cm); - assert!(proved_output.verify()); - - let wrong_output_cms = [ - cl::Output { - note_comm: cl::NoteWitness::basic(100, nmo).commit( - cl::NullifierSecret::random(&mut rng).commit(), - cl::NullifierNonce::random(&mut rng), - ), - ..expected_output_cm - }, - cl::Output { - note_comm: cl::NoteWitness::basic(100, nmo).commit( - cl::NullifierSecret::random(&mut rng).commit(), - cl::NullifierNonce::random(&mut rng), - ), - balance: cl::BalanceWitness::random(&mut rng) - .commit(&cl::NoteWitness::basic(100, nmo)), - }, - ]; - - for wrong_output_cm in wrong_output_cms { - proved_output.output = wrong_output_cm; - assert!(!proved_output.verify()); - } - } - - #[test] - fn test_zero_output_is_rejected() { - let nmo = unit_point("NMO"); - let mut rng = thread_rng(); - - let output = cl::OutputWitness::random( - cl::NoteWitness::basic(0, nmo), - cl::NullifierSecret::random(&mut rng).commit(), - &mut rng, - ); - - assert!(ProvedOutput::prove(&output).is_err()); - } -} diff --git a/goas/cl/ledger_proof_statements/src/input.rs b/goas/cl/ledger_proof_statements/src/input.rs deleted file mode 100644 index 20dab89..0000000 --- a/goas/cl/ledger_proof_statements/src/input.rs +++ /dev/null @@ -1,21 +0,0 @@ -use serde::{Deserialize, Serialize}; - -/// for public inputs `nf` (nullifier), `root_cm` (root of merkle tree over commitment set) and `death_cm` (commitment to death constraint). -/// the prover has knowledge of `output = (note, nf_pk, nonce)`, `nf` and `path` s.t. that the following constraints hold -/// 0. nf_pk = hash(nf_sk) -/// 1. nf = hash(nonce||nf_sk) -/// 2. note_cm = output_commitment(output) -/// 3. verify_merkle_path(note_cm, root, path) -/// 4. death_cm = death_commitment(note.death_constraint) - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] -pub struct InputPublic { - pub cm_root: [u8; 32], - pub input: cl::Input, -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct InputPrivate { - pub input: cl::InputWitness, - pub cm_path: Vec, -} diff --git a/goas/cl/ledger_proof_statements/src/lib.rs b/goas/cl/ledger_proof_statements/src/lib.rs index 8e58650..4845666 100644 --- a/goas/cl/ledger_proof_statements/src/lib.rs +++ b/goas/cl/ledger_proof_statements/src/lib.rs @@ -1,3 +1,2 @@ pub mod death_constraint; -pub mod input; pub mod ptx; diff --git a/goas/cl/risc0_proofs/Cargo.toml b/goas/cl/risc0_proofs/Cargo.toml index 8415ca7..d53a6fd 100644 --- a/goas/cl/risc0_proofs/Cargo.toml +++ b/goas/cl/risc0_proofs/Cargo.toml @@ -7,5 +7,5 @@ edition = "2021" risc0-build = { version = "1.0" } [package.metadata.risc0] -methods = ["input", "output", "bundle", "death_constraint_nop", "ptx"] +methods = ["bundle", "death_constraint_nop", "ptx"] diff --git a/goas/cl/risc0_proofs/input/Cargo.toml b/goas/cl/risc0_proofs/input/Cargo.toml deleted file mode 100644 index fd1f63f..0000000 --- a/goas/cl/risc0_proofs/input/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "input" -version = "0.1.0" -edition = "2021" - -[workspace] - -[dependencies] -risc0-zkvm = { version = "1.0", default-features = false, features = ['std'] } -serde = { version = "1.0", features = ["derive"] } -cl = { path = "../../cl" } -ledger_proof_statements = { path = "../../ledger_proof_statements" } - - -[patch.crates-io] -# add RISC Zero accelerator support for all downstream usages of the following crates. -sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2-v0.10.8-risczero.0" } -crypto-bigint = { git = "https://github.com/risc0/RustCrypto-crypto-bigint", tag = "v0.5.5-risczero.0" } -curve25519-dalek = { git = "https://github.com/risc0/curve25519-dalek", tag = "curve25519-4.1.2-risczero.0" } diff --git a/goas/cl/risc0_proofs/input/src/main.rs b/goas/cl/risc0_proofs/input/src/main.rs deleted file mode 100644 index ada2145..0000000 --- a/goas/cl/risc0_proofs/input/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -/// Input Proof -use cl::merkle; -use ledger_proof_statements::input::{InputPrivate, InputPublic}; -use risc0_zkvm::guest::env; - -fn main() { - let secret: InputPrivate = env::read(); - - let out_cm = secret.input.note_commitment(); - let cm_leaf = merkle::leaf(out_cm.as_bytes()); - let cm_root = merkle::path_root(cm_leaf, &secret.cm_path); - - env::commit(&InputPublic { - input: secret.input.commit(), - cm_root, - }); -} diff --git a/goas/cl/risc0_proofs/output/Cargo.toml b/goas/cl/risc0_proofs/output/Cargo.toml deleted file mode 100644 index e33aea6..0000000 --- a/goas/cl/risc0_proofs/output/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "output" -version = "0.1.0" -edition = "2021" - -[workspace] - -[dependencies] -risc0-zkvm = { version = "1.0", default-features = false, features = ['std'] } -serde = { version = "1.0", features = ["derive"] } -cl = { path = "../../cl" } -ledger_proof_statements = { path = "../../ledger_proof_statements" } - - -[patch.crates-io] -# add RISC Zero accelerator support for all downstream usages of the following crates. -sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2-v0.10.8-risczero.0" } -crypto-bigint = { git = "https://github.com/risc0/RustCrypto-crypto-bigint", tag = "v0.5.5-risczero.0" } -curve25519-dalek = { git = "https://github.com/risc0/curve25519-dalek", tag = "curve25519-4.1.2-risczero.0" } diff --git a/goas/cl/risc0_proofs/output/src/main.rs b/goas/cl/risc0_proofs/output/src/main.rs deleted file mode 100644 index 2674230..0000000 --- a/goas/cl/risc0_proofs/output/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -/// Output Proof -/// -/// given randomness `r` and `note=(value, unit, ...)` prove that -/// - balance = balance_commit(value, unit, r) -/// - note_cm = note_commit(note) -use risc0_zkvm::guest::env; - -fn main() { - let output: cl::OutputWitness = env::read(); - - // 0 does not contribute to balance, implications of this are unclear - // therefore out of an abundance of caution, we disallow these zero - // valued "dummy notes". - assert!(output.note.value > 0); - - let output_cm = output.commit(); - env::commit(&output_cm); -}