diff --git a/miden-tx/Cargo.toml b/miden-tx/Cargo.toml index 1a4bbec52..ded21cc26 100644 --- a/miden-tx/Cargo.toml +++ b/miden-tx/Cargo.toml @@ -24,6 +24,7 @@ miden-core = { package = "miden-core", git = "https://github.com/0xPolygonMiden/ miden-objects = { package = "miden-objects", path = "../objects", default-features = false } miden-lib = { package = "miden-lib", path = "../miden-lib" } miden-stdlib = { package = "miden-stdlib", git = "https://github.com/0xPolygonMiden/miden-vm.git", branch = "next", default-features = false } +miden-verifier = { package = "miden-verifier", git = "https://github.com/0xPolygonMiden/miden-vm.git", branch = "next", default-features = false } [dev-dependencies] miden-objects = { package = "miden-objects", path = "../objects", default-features = false } diff --git a/miden-tx/src/lib.rs b/miden-tx/src/lib.rs index c02459b47..473cc8933 100644 --- a/miden-tx/src/lib.rs +++ b/miden-tx/src/lib.rs @@ -26,6 +26,8 @@ use error::{ pub use executor::TransactionExecutor; mod prover; pub use prover::TransactionProver; +mod verifier; +pub use verifier::TransactionVerifier; #[cfg(test)] mod tests; diff --git a/miden-tx/src/tests.rs b/miden-tx/src/tests.rs index ea614f876..9cf8cac43 100644 --- a/miden-tx/src/tests.rs +++ b/miden-tx/src/tests.rs @@ -1,13 +1,12 @@ use super::{ Account, AccountId, BlockHeader, ChainMmr, DataStore, DataStoreError, Note, NoteOrigin, - TransactionExecutor, TransactionProver, + TransactionExecutor, TransactionProver, TransactionVerifier, }; use assembly::{ ast::{ModuleAst, ProgramAst}, Assembler, }; use crypto::{StarkField, ONE}; -use miden_core::ProgramInfo; use miden_objects::{ mock::{ mock_inputs, prepare_word, CHILD_ROOT_PARENT_LEAF_INDEX, CHILD_SMT_DEPTH, @@ -249,7 +248,7 @@ fn test_transaction_result_account_delta() { } #[test] -fn test_prove_witness() { +fn test_prove_witness_and_verify() { let data_store = MockDataStore::new(); let mut executor = TransactionExecutor::new(data_store.clone()); @@ -272,9 +271,10 @@ fn test_prove_witness() { // prove the transaction with the witness let proof_options = ProvingOptions::default(); let prover = TransactionProver::new(proof_options); - let proven_transaction = prover.prove_transaction_witness(witness); + let proven_transaction = prover.prove_transaction_witness(witness).unwrap(); - assert!(proven_transaction.is_ok()); + let verifier = TransactionVerifier::new(); + assert!(verifier.verify(proven_transaction).is_ok()); } #[test] @@ -297,23 +297,11 @@ fn test_prove_and_verify_with_tx_executor() { .prepare_transaction(account_id, block_ref, ¬e_origins, None) .unwrap(); - // extract transaction data for later consumption - let program_hash = prepared_transaction.tx_program().hash(); - let kernel = prepared_transaction.tx_program().kernel().clone(); - // prove transaction let proof_options = ProvingOptions::default(); let prover = TransactionProver::new(proof_options); let proven_transaction = prover.prove_prepared_transaction(prepared_transaction).unwrap(); - let stack_inputs = proven_transaction.build_stack_inputs(); - let stack_outputs = proven_transaction.build_stack_outputs(); - let program_info = ProgramInfo::new(program_hash, kernel); - let result = miden_verifier::verify( - program_info, - stack_inputs, - stack_outputs, - proven_transaction.proof().clone(), - ); - assert!(result.is_ok()); + let verifier = TransactionVerifier::new(); + assert!(verifier.verify(proven_transaction).is_ok()); } diff --git a/miden-tx/src/verifier/mod.rs b/miden-tx/src/verifier/mod.rs new file mode 100644 index 000000000..ac59ee1a0 --- /dev/null +++ b/miden-tx/src/verifier/mod.rs @@ -0,0 +1,41 @@ +use super::{Assembler, MidenLib, SatKernel, StdLibrary}; +use miden_core::Kernel; +use miden_objects::transaction::ProvenTransaction; +use miden_verifier::{verify, ProgramInfo, VerificationError}; + +/// The [TransactionVerifier] is used to verify a [ProvenTransaction]. +/// +/// The [TransactionVerifier] contains a [Kernel] object which we use to verify a given +/// transaction against. +pub struct TransactionVerifier { + kernel: Kernel, +} + +impl TransactionVerifier { + // TODO: Do we want to allow the kernel to be passed as an argument to the constructor? + // It probably doesn't make sense to do so now as we only have a single kernel. + /// Creates a new [TransactionVerifier] object. + pub fn new() -> Self { + let kernel = Assembler::default() + .with_library(&MidenLib::default()) + .expect("library is well formed") + .with_library(&StdLibrary::default()) + .expect("library is well formed") + .with_kernel(SatKernel::kernel()) + .expect("kernel is well formed") + .kernel() + .clone(); + Self { kernel } + } + + /// Verifies the provided [ProvenTransaction] against the kernel. + pub fn verify(&self, transaction: ProvenTransaction) -> Result { + let program_info = ProgramInfo::new(transaction.program_hash(), self.kernel.clone()); + verify( + program_info, + transaction.build_stack_inputs(), + transaction.build_stack_outputs(), + transaction.proof().clone(), + ) + } +}