From 0a3f093d6083fb970798570c1bd61c351909a985 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Wed, 27 Aug 2025 16:24:20 -0300 Subject: [PATCH] fmt and clippy --- nssa/Cargo.toml | 2 +- nssa/core/Cargo.toml | 4 +- nssa/core/src/account.rs | 2 +- nssa/core/src/circuit_io.rs | 1 + nssa/core/src/commitment.rs | 2 +- nssa/core/src/encoding.rs | 1 + nssa/core/src/encryption/mod.rs | 2 +- nssa/core/src/nullifier.rs | 4 +- nssa/program_methods/Cargo.toml | 1 - nssa/src/lib.rs | 6 +- nssa/src/merkle_tree/mod.rs | 57 ++++++++-------- .../privacy_preserving_transaction/circuit.rs | 26 ++----- .../encoding.rs | 5 +- .../privacy_preserving_transaction/message.rs | 13 ++-- .../src/privacy_preserving_transaction/mod.rs | 8 +-- .../transaction.rs | 1 - nssa/src/program.rs | 14 ++-- nssa/src/public_transaction/encoding.rs | 3 +- nssa/src/state.rs | 68 +++++++------------ 19 files changed, 90 insertions(+), 130 deletions(-) diff --git a/nssa/Cargo.toml b/nssa/Cargo.toml index aad78af..5162167 100644 --- a/nssa/Cargo.toml +++ b/nssa/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [dependencies] thiserror = "2.0.12" risc0-zkvm = "2.3.1" -nssa-core = { path = "core", features=["host"]} +nssa-core = { path = "core", features = ["host"] } program-methods = { path = "program_methods" } serde = "1.0.219" sha2 = "0.10.9" diff --git a/nssa/core/Cargo.toml b/nssa/core/Cargo.toml index 97d7558..44491de 100644 --- a/nssa/core/Cargo.toml +++ b/nssa/core/Cargo.toml @@ -4,12 +4,12 @@ version = "0.1.0" edition = "2024" [dependencies] -risc0-zkvm = { version = "2.3.1"} +risc0-zkvm = { version = "2.3.1" } serde = { version = "1.0", default-features = false } thiserror = { version = "2.0.12", optional = true } bytemuck = { version = "1.13", optional = true } chacha20 = { version = "0.9", default-features = false } -k256 = { version = "0.13.3", optional = true} +k256 = { version = "0.13.3", optional = true } [features] default = [] diff --git a/nssa/core/src/account.rs b/nssa/core/src/account.rs index 4b2f51d..688611e 100644 --- a/nssa/core/src/account.rs +++ b/nssa/core/src/account.rs @@ -1,5 +1,5 @@ -use serde::{Deserialize, Serialize}; use crate::program::ProgramId; +use serde::{Deserialize, Serialize}; pub type Nonce = u128; type Data = Vec; diff --git a/nssa/core/src/circuit_io.rs b/nssa/core/src/circuit_io.rs index f16d010..e619b2d 100644 --- a/nssa/core/src/circuit_io.rs +++ b/nssa/core/src/circuit_io.rs @@ -35,6 +35,7 @@ impl PrivacyPreservingCircuitOutput { } } +#[cfg(feature = "host")] #[cfg(test)] mod tests { use super::*; diff --git a/nssa/core/src/commitment.rs b/nssa/core/src/commitment.rs index a4a4efb..bc22c8f 100644 --- a/nssa/core/src/commitment.rs +++ b/nssa/core/src/commitment.rs @@ -1,7 +1,7 @@ use risc0_zkvm::sha::{Impl, Sha256}; use serde::{Deserialize, Serialize}; -use crate::{account::Account, NullifierPublicKey}; +use crate::{NullifierPublicKey, account::Account}; #[derive(Serialize, Deserialize)] #[cfg_attr(any(feature = "host", test), derive(Debug, Clone, PartialEq, Eq, Hash))] diff --git a/nssa/core/src/encoding.rs b/nssa/core/src/encoding.rs index 0bf2383..6f7e36f 100644 --- a/nssa/core/src/encoding.rs +++ b/nssa/core/src/encoding.rs @@ -171,6 +171,7 @@ mod tests { assert_eq!(expected_bytes, bytes); } + #[cfg(feature = "host")] #[test] fn test_nullifier_to_bytes() { let nullifier = Nullifier((0..32).collect::>().try_into().unwrap()); diff --git a/nssa/core/src/encryption/mod.rs b/nssa/core/src/encryption/mod.rs index 8fc45bd..b79e75c 100644 --- a/nssa/core/src/encryption/mod.rs +++ b/nssa/core/src/encryption/mod.rs @@ -11,7 +11,7 @@ pub(crate) mod shared_key_derivation; #[cfg(feature = "host")] pub use shared_key_derivation::{EphemeralPublicKey, EphemeralSecretKey, IncomingViewingPublicKey}; -use crate::{Commitment, NullifierPublicKey, account::Account}; +use crate::{Commitment, account::Account}; #[derive(Serialize, Deserialize, Clone)] pub struct SharedSecretKey([u8; 32]); diff --git a/nssa/core/src/nullifier.rs b/nssa/core/src/nullifier.rs index 346a815..d1410de 100644 --- a/nssa/core/src/nullifier.rs +++ b/nssa/core/src/nullifier.rs @@ -62,7 +62,7 @@ mod tests { 202, 120, 42, 189, 194, 218, 78, 244, 31, 6, 108, 169, 29, 61, 22, 221, 69, 138, 197, 161, 241, 39, 142, 242, 242, 50, 188, 201, 99, 28, 176, 238, ]); - let Npk = NullifierPublicKey::from(&nsk); - assert_eq!(Npk, expected_npk); + let npk = NullifierPublicKey::from(&nsk); + assert_eq!(npk, expected_npk); } } diff --git a/nssa/program_methods/Cargo.toml b/nssa/program_methods/Cargo.toml index 0f31c9b..ea7e36b 100644 --- a/nssa/program_methods/Cargo.toml +++ b/nssa/program_methods/Cargo.toml @@ -8,4 +8,3 @@ risc0-build = { version = "2.3.1" } [package.metadata.risc0] methods = ["guest"] - diff --git a/nssa/src/lib.rs b/nssa/src/lib.rs index ac94f1e..ed88047 100644 --- a/nssa/src/lib.rs +++ b/nssa/src/lib.rs @@ -1,16 +1,18 @@ pub mod address; pub mod error; +mod merkle_tree; mod privacy_preserving_transaction; pub mod program; pub mod public_transaction; mod signature; mod state; -mod merkle_tree; pub use address::Address; +pub use privacy_preserving_transaction::{ + PrivacyPreservingTransaction, circuit::execute_and_prove, +}; pub use public_transaction::PublicTransaction; pub use signature::PrivateKey; pub use signature::PublicKey; pub use signature::Signature; pub use state::V01State; - diff --git a/nssa/src/merkle_tree/mod.rs b/nssa/src/merkle_tree/mod.rs index a242379..2306efd 100644 --- a/nssa/src/merkle_tree/mod.rs +++ b/nssa/src/merkle_tree/mod.rs @@ -1,5 +1,3 @@ -use std::collections::{HashMap, HashSet}; - use sha2::{Digest, Sha256}; mod default_values; @@ -47,8 +45,7 @@ impl MerkleTree { /// Number of levels required to hold all values fn depth(&self) -> usize { - let result = self.length.next_power_of_two().trailing_zeros() as usize; - result + self.length.next_power_of_two().trailing_zeros() as usize } fn get_node(&self, index: usize) -> &Node { @@ -108,7 +105,6 @@ impl MerkleTree { self.set_node(node_index, node_hash); self.length += 1; - let root_index = self.root_index(); for _ in 0..self.depth() { let parent_index = (node_index - 1) >> 1; let left_child = self.get_node((parent_index << 1) + 1); @@ -121,14 +117,6 @@ impl MerkleTree { new_index } - pub fn new(values: &[Value]) -> Self { - let mut this = Self::with_capacity(values.len()); - for value in values.iter().cloned() { - this.insert(value); - } - this - } - pub fn get_authentication_path_for(&self, index: usize) -> Option> { if index >= self.length { return None; @@ -155,22 +143,6 @@ impl MerkleTree { } } -// Reference implementation -fn verify_authentication_path(value: &Value, index: usize, path: &[Node], root: &Node) -> bool { - let mut result = hash_value(value); - let mut level_index = index; - for node in path { - let is_left_child = level_index & 1 == 0; - if is_left_child { - result = hash_two(&result, node); - } else { - result = hash_two(node, &result); - } - level_index >>= 1; - } - &result == root -} - fn prev_power_of_two(x: usize) -> usize { if x == 0 { return 0; @@ -180,10 +152,19 @@ fn prev_power_of_two(x: usize) -> usize { #[cfg(test)] mod tests { + impl MerkleTree { + pub fn new(values: &[Value]) -> Self { + let mut this = Self::with_capacity(values.len()); + for value in values.iter().cloned() { + this.insert(value); + } + this + } + } + use hex_literal::hex; use super::*; - #[test] fn test_empty_merkle_tree() { let tree = MerkleTree::with_capacity(4); @@ -398,6 +379,22 @@ mod tests { assert_eq!(expected_tree, tree); } + // Reference implementation + fn verify_authentication_path(value: &Value, index: usize, path: &[Node], root: &Node) -> bool { + let mut result = hash_value(value); + let mut level_index = index; + for node in path { + let is_left_child = level_index & 1 == 0; + if is_left_child { + result = hash_two(&result, node); + } else { + result = hash_two(node, &result); + } + level_index >>= 1; + } + &result == root + } + #[test] fn test_authentication_path_1() { let values = [[1; 32], [2; 32], [3; 32], [4; 32]]; diff --git a/nssa/src/privacy_preserving_transaction/circuit.rs b/nssa/src/privacy_preserving_transaction/circuit.rs index ad4b03c..687e214 100644 --- a/nssa/src/privacy_preserving_transaction/circuit.rs +++ b/nssa/src/privacy_preserving_transaction/circuit.rs @@ -1,8 +1,8 @@ use nssa_core::{ - CommitmentSetDigest, MembershipProof, NullifierPublicKey, NullifierSecretKey, - PrivacyPreservingCircuitInput, PrivacyPreservingCircuitOutput, SharedSecretKey, - account::{Account, AccountWithMetadata, Nonce}, - program::{InstructionData, ProgramId, ProgramOutput}, + MembershipProof, NullifierPublicKey, NullifierSecretKey, PrivacyPreservingCircuitInput, + PrivacyPreservingCircuitOutput, SharedSecretKey, + account::AccountWithMetadata, + program::{InstructionData, ProgramOutput}, }; use risc0_zkvm::{ExecutorEnv, InnerReceipt, Receipt, default_prover}; @@ -91,19 +91,12 @@ fn execute_and_prove_program( #[cfg(test)] mod tests { use nssa_core::{ - Commitment, EncryptionScheme, Nullifier, NullifierPublicKey, NullifierSecretKey, + Commitment, EncryptionScheme, Nullifier, account::{Account, AccountWithMetadata}, - encryption::EphemeralPublicKey, }; - use risc0_zkvm::{InnerReceipt, Journal, Receipt}; use crate::{ - Address, V01State, - merkle_tree::MerkleTree, - privacy_preserving_transaction::{ - circuit::{Proof, execute_and_prove}, - message::EncryptedAccountData, - }, + privacy_preserving_transaction::circuit::execute_and_prove, program::Program, state::{ CommitmentSet, @@ -111,8 +104,6 @@ mod tests { }, }; - use rand::{Rng, RngCore, rngs::OsRng}; - use super::*; #[test] @@ -152,7 +143,6 @@ mod tests { let esk = [3; 32]; let shared_secret = SharedSecretKey::new(&esk, &recipient_keys.ivk()); - let epk = EphemeralPublicKey::from_scalar(esk); let (output, proof) = execute_and_prove( &[sender, recipient], @@ -206,7 +196,7 @@ mod tests { let balance_to_move: u128 = 37; let mut commitment_set = CommitmentSet::with_capacity(2); - commitment_set.extend(&[commitment_sender.clone()]); + commitment_set.extend(std::slice::from_ref(&commitment_sender)); let expected_new_nullifiers = vec![( Nullifier::new(&commitment_sender, &sender_keys.nsk), @@ -234,11 +224,9 @@ mod tests { let esk_1 = [3; 32]; let shared_secret_1 = SharedSecretKey::new(&esk_1, &sender_keys.ivk()); - let epk_1 = EphemeralPublicKey::from_scalar(esk_1); let esk_2 = [5; 32]; let shared_secret_2 = SharedSecretKey::new(&esk_2, &recipient_keys.ivk()); - let epk_2 = EphemeralPublicKey::from_scalar(esk_2); let (output, proof) = execute_and_prove( &[sender_pre.clone(), recipient], diff --git a/nssa/src/privacy_preserving_transaction/encoding.rs b/nssa/src/privacy_preserving_transaction/encoding.rs index bfaf4ff..b5d4950 100644 --- a/nssa/src/privacy_preserving_transaction/encoding.rs +++ b/nssa/src/privacy_preserving_transaction/encoding.rs @@ -88,6 +88,7 @@ impl Message { bytes } + #[allow(unused)] pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result { let prefix = { let mut this = [0u8; MESSAGE_ENCODING_PREFIX_LEN]; @@ -115,7 +116,7 @@ impl Message { // Nonces cursor.read_exact(&mut len_bytes)?; let nonces_len = u32::from_le_bytes(len_bytes) as usize; - let mut nonces = Vec::with_capacity(nonces_len as usize); + let mut nonces = Vec::with_capacity(nonces_len); for _ in 0..nonces_len { let mut buf = [0u8; 16]; cursor.read_exact(&mut buf)?; @@ -153,7 +154,7 @@ impl Message { for _ in 0..new_nullifiers_len { let nullifier = Nullifier::from_cursor(cursor)?; let mut commitment_set_digest = [0; 32]; - cursor.read_exact(&mut commitment_set_digest); + cursor.read_exact(&mut commitment_set_digest)?; new_nullifiers.push((nullifier, commitment_set_digest)); } diff --git a/nssa/src/privacy_preserving_transaction/message.rs b/nssa/src/privacy_preserving_transaction/message.rs index b2f8247..4877e3d 100644 --- a/nssa/src/privacy_preserving_transaction/message.rs +++ b/nssa/src/privacy_preserving_transaction/message.rs @@ -1,11 +1,8 @@ -use std::io::Cursor; - use nssa_core::{ Commitment, CommitmentSetDigest, Nullifier, PrivacyPreservingCircuitOutput, account::{Account, Nonce}, encryption::{Ciphertext, EphemeralPublicKey}, }; -use serde::{Deserialize, Serialize}; use crate::{Address, error::NssaError}; @@ -64,7 +61,7 @@ impl Message { pub mod tests { use std::io::Cursor; - use nssa_core::{account::Account, Commitment, Nullifier, NullifierPublicKey}; + use nssa_core::{Commitment, Nullifier, NullifierPublicKey, account::Account}; use crate::{Address, privacy_preserving_transaction::message::Message}; @@ -75,8 +72,8 @@ pub mod tests { let nsk1 = [11; 32]; let nsk2 = [12; 32]; - let Npk1 = NullifierPublicKey::from(&nsk1); - let Npk2 = NullifierPublicKey::from(&nsk2); + let npk1 = NullifierPublicKey::from(&nsk1); + let npk2 = NullifierPublicKey::from(&nsk2); let public_addresses = vec![Address::new([1; 32])]; @@ -86,9 +83,9 @@ pub mod tests { let encrypted_private_post_states = Vec::new(); - let new_commitments = vec![Commitment::new(&Npk2, &account2)]; + let new_commitments = vec![Commitment::new(&npk2, &account2)]; - let old_commitment = Commitment::new(&Npk1, &account1); + let old_commitment = Commitment::new(&npk1, &account1); let new_nullifiers = vec![(Nullifier::new(&old_commitment, &nsk1), [0; 32])]; Message { diff --git a/nssa/src/privacy_preserving_transaction/mod.rs b/nssa/src/privacy_preserving_transaction/mod.rs index 448a488..54fc94b 100644 --- a/nssa/src/privacy_preserving_transaction/mod.rs +++ b/nssa/src/privacy_preserving_transaction/mod.rs @@ -1,10 +1,8 @@ mod encoding; -mod message; -mod transaction; -mod witness_set; +pub mod message; +pub mod transaction; +pub mod witness_set; pub mod circuit; -pub use message::{Message, EncryptedAccountData}; pub use transaction::PrivacyPreservingTransaction; -pub use witness_set::WitnessSet; diff --git a/nssa/src/privacy_preserving_transaction/transaction.rs b/nssa/src/privacy_preserving_transaction/transaction.rs index 632aec9..9aac54e 100644 --- a/nssa/src/privacy_preserving_transaction/transaction.rs +++ b/nssa/src/privacy_preserving_transaction/transaction.rs @@ -3,7 +3,6 @@ use std::collections::{HashMap, HashSet}; use nssa_core::{ Commitment, CommitmentSetDigest, Nullifier, PrivacyPreservingCircuitOutput, account::{Account, AccountWithMetadata}, - encryption::Ciphertext, }; use crate::error::NssaError; diff --git a/nssa/src/program.rs b/nssa/src/program.rs index 410d674..d504313 100644 --- a/nssa/src/program.rs +++ b/nssa/src/program.rs @@ -1,11 +1,10 @@ -use borsh::{BorshDeserialize, BorshSerialize}; use nssa_core::{ account::{Account, AccountWithMetadata}, - program::{DEFAULT_PROGRAM_ID, InstructionData, ProgramId, ProgramOutput}, + program::{InstructionData, ProgramId, ProgramOutput}, }; use program_methods::{AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID}; use risc0_zkvm::{ - ExecutorEnv, ExecutorEnvBuilder, Journal, Receipt, default_executor, default_prover, + ExecutorEnv, ExecutorEnvBuilder, default_executor, serde::to_vec, }; use serde::Serialize; @@ -51,7 +50,7 @@ impl Program { // Get outputs let ProgramOutput { - mut post_states, .. + post_states, .. } = session_info .journal .decode() @@ -83,11 +82,8 @@ impl Program { #[cfg(test)] mod tests { - use nssa_core::{ - account::{Account, AccountWithMetadata}, - program::ProgramOutput, - }; - use risc0_zkvm::{InnerReceipt, Receipt, serde::to_vec}; + use nssa_core::account::{Account, AccountWithMetadata}; + use crate::program::Program; diff --git a/nssa/src/public_transaction/encoding.rs b/nssa/src/public_transaction/encoding.rs index 70b5288..e8890de 100644 --- a/nssa/src/public_transaction/encoding.rs +++ b/nssa/src/public_transaction/encoding.rs @@ -11,8 +11,7 @@ use crate::{ }; const MESSAGE_ENCODING_PREFIX_LEN: usize = 22; -const MESSAGE_ENCODING_PREFIX: &[u8; MESSAGE_ENCODING_PREFIX_LEN] = - b"\x00/NSSA/v0.1/TxMessage/"; +const MESSAGE_ENCODING_PREFIX: &[u8; MESSAGE_ENCODING_PREFIX_LEN] = b"\x00/NSSA/v0.1/TxMessage/"; impl Message { /// Serializes a `Message` into bytes in the following layout: diff --git a/nssa/src/state.rs b/nssa/src/state.rs index 81d8746..93ee06c 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -4,14 +4,16 @@ use crate::{ public_transaction::PublicTransaction, }; use nssa_core::{ - account::Account, program::{ProgramId, DEFAULT_PROGRAM_ID}, Commitment, CommitmentSetDigest, MembershipProof, Nullifier + Commitment, CommitmentSetDigest, MembershipProof, Nullifier, + account::Account, + program::{DEFAULT_PROGRAM_ID, ProgramId}, }; use std::collections::{HashMap, HashSet}; pub(crate) struct CommitmentSet { merkle_tree: MerkleTree, commitments: HashMap, - pub root_history: HashSet, + root_history: HashSet, } impl CommitmentSet { @@ -19,13 +21,12 @@ impl CommitmentSet { self.merkle_tree.root() } - pub(crate) fn get_proof_for(&self, commitment: &Commitment) -> Option { + pub fn get_proof_for(&self, commitment: &Commitment) -> Option { let index = *self.commitments.get(commitment)?; - let proof = self - .merkle_tree + + self.merkle_tree .get_authentication_path_for(index) - .map(|path| (index, path)); - proof + .map(|path| (index, path)) } pub(crate) fn extend(&mut self, commitments: &[Commitment]) { @@ -53,7 +54,7 @@ type NullifierSet = HashSet; pub struct V01State { public_state: HashMap, - pub private_state: (CommitmentSet, NullifierSet), + private_state: (CommitmentSet, NullifierSet), builtin_programs: HashMap, } @@ -159,6 +160,10 @@ impl V01State { .unwrap_or(Account::default()) } + pub fn get_proof_for_commitment(&self, commitment: &Commitment) -> Option { + self.private_state.0.get_proof_for(commitment) + } + pub(crate) fn builtin_programs(&self) -> &HashMap { &self.builtin_programs } @@ -199,16 +204,6 @@ impl V01State { } Ok(()) } - - pub(crate) fn check_commitment_set_digest_is_valid( - &self, - commitment_set_digest: &CommitmentSetDigest, - ) -> bool { - self.private_state - .0 - .root_history - .contains(commitment_set_digest) - } } #[cfg(test)] @@ -220,7 +215,7 @@ pub mod tests { Address, PublicKey, PublicTransaction, V01State, error::NssaError, privacy_preserving_transaction::{ - EncryptedAccountData, Message, PrivacyPreservingTransaction, WitnessSet, circuit, + PrivacyPreservingTransaction, circuit, message::Message, witness_set::WitnessSet, }, program::Program, public_transaction, @@ -228,11 +223,10 @@ pub mod tests { }; use nssa_core::{ - account::{ - Account, AccountWithMetadata, Nonce, - }, encryption::{EphemeralPublicKey, IncomingViewingPublicKey}, Commitment, Nullifier, NullifierPublicKey, NullifierSecretKey, SharedSecretKey + Commitment, Nullifier, NullifierPublicKey, NullifierSecretKey, SharedSecretKey, + account::{Account, AccountWithMetadata, Nonce}, + encryption::{EphemeralPublicKey, IncomingViewingPublicKey}, }; - use program_methods::AUTHENTICATED_TRANSFER_ID; fn transfer_transaction( from: Address, @@ -482,7 +476,7 @@ pub mod tests { } pub fn with_private_account(mut self, keys: &TestPrivateKeys, account: &Account) -> Self { - let commitment = Commitment::new(&keys.npk(), &account); + let commitment = Commitment::new(&keys.npk(), account); self.private_state.0.extend(&[commitment]); self } @@ -825,7 +819,7 @@ pub mod tests { state: &V01State, ) -> PrivacyPreservingTransaction { let program = Program::authenticated_transfer_program(); - let sender_commitment = Commitment::new(&sender_keys.npk(), &sender_private_account); + let sender_commitment = Commitment::new(&sender_keys.npk(), sender_private_account); let sender_pre = AccountWithMetadata { account: sender_private_account.clone(), is_authorized: true, @@ -854,11 +848,7 @@ pub mod tests { ], &[( sender_keys.nsk, - state - .private_state - .0 - .get_proof_for(&sender_commitment) - .unwrap(), + state.get_proof_for_commitment(&sender_commitment).unwrap(), )], &program, ) @@ -881,7 +871,7 @@ pub mod tests { state: &V01State, ) -> PrivacyPreservingTransaction { let program = Program::authenticated_transfer_program(); - let sender_commitment = Commitment::new(&sender_keys.npk(), &sender_private_account); + let sender_commitment = Commitment::new(&sender_keys.npk(), sender_private_account); let sender_pre = AccountWithMetadata { account: sender_private_account.clone(), is_authorized: true, @@ -903,23 +893,15 @@ pub mod tests { &[(sender_keys.npk(), shared_secret)], &[( sender_keys.nsk, - state - .private_state - .0 - .get_proof_for(&sender_commitment) - .unwrap(), + state.get_proof_for_commitment(&sender_commitment).unwrap(), )], &program, ) .unwrap(); - let message = Message::try_from_circuit_output( - vec![recipient_address.clone()], - vec![], - vec![epk], - output, - ) - .unwrap(); + let message = + Message::try_from_circuit_output(vec![*recipient_address], vec![], vec![epk], output) + .unwrap(); let witness_set = WitnessSet::for_message(&message, proof, &[]);