diff --git a/common/Cargo.toml b/common/Cargo.toml index 54923a3..dcb5f60 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -10,7 +10,6 @@ serde_json.workspace = true serde.workspace = true reqwest.workspace = true k256.workspace = true -rand.workspace = true rs_merkle.workspace = true sha2.workspace = true diff --git a/integration_tests/Cargo.toml b/integration_tests/Cargo.toml index df2bad8..16e1b2e 100644 --- a/integration_tests/Cargo.toml +++ b/integration_tests/Cargo.toml @@ -5,15 +5,12 @@ edition = "2024" [dependencies] anyhow.workspace = true -serde_json.workspace = true env_logger.workspace = true log.workspace = true -serde.workspace = true actix.workspace = true actix-web.workspace = true tokio.workspace = true -toml.workspace = true hex.workspace = true tempfile.workspace = true @@ -21,9 +18,6 @@ tempfile.workspace = true features = ["derive", "env"] workspace = true -[dependencies.sequencer_rpc] -path = "../sequencer_rpc" - [dependencies.sequencer_core] path = "../sequencer_core" @@ -35,6 +29,3 @@ path = "../wallet" [dependencies.common] path = "../common" - -[dependencies.key_protocol] -path = "../key_protocol" diff --git a/key_protocol/Cargo.toml b/key_protocol/Cargo.toml index 3150dfe..ba8edc7 100644 --- a/key_protocol/Cargo.toml +++ b/key_protocol/Cargo.toml @@ -6,7 +6,6 @@ edition = "2024" [dependencies] anyhow.workspace = true serde_json.workspace = true -env_logger.workspace = true log.workspace = true serde.workspace = true k256.workspace = true @@ -16,8 +15,6 @@ elliptic-curve.workspace = true hex.workspace = true aes-gcm.workspace = true lazy_static.workspace = true -tiny-keccak.workspace = true -nssa-core = { path = "../nssa/core" } [dependencies.common] path = "../common" diff --git a/mempool/Cargo.toml b/mempool/Cargo.toml index 16327ac..c47d2b0 100644 --- a/mempool/Cargo.toml +++ b/mempool/Cargo.toml @@ -4,8 +4,3 @@ version = "0.1.0" edition = "2024" [dependencies] -anyhow.workspace = true -serde_json.workspace = true -env_logger.workspace = true -log.workspace = true -serde.workspace = true diff --git a/nssa/Cargo.toml b/nssa/Cargo.toml index 98a0adf..3163902 100644 --- a/nssa/Cargo.toml +++ b/nssa/Cargo.toml @@ -13,7 +13,6 @@ sha2 = "0.10.9" secp256k1 = "0.31.1" rand = "0.8" borsh = "1.5.7" -bytemuck = "1.13" hex = "0.4.3" [dev-dependencies] diff --git a/nssa/src/privacy_preserving_transaction/message.rs b/nssa/src/privacy_preserving_transaction/message.rs index 4877e3d..244a81f 100644 --- a/nssa/src/privacy_preserving_transaction/message.rs +++ b/nssa/src/privacy_preserving_transaction/message.rs @@ -1,16 +1,45 @@ use nssa_core::{ - Commitment, CommitmentSetDigest, Nullifier, PrivacyPreservingCircuitOutput, + Commitment, CommitmentSetDigest, Nullifier, NullifierPublicKey, PrivacyPreservingCircuitOutput, account::{Account, Nonce}, - encryption::{Ciphertext, EphemeralPublicKey}, + encryption::{Ciphertext, EphemeralPublicKey, IncomingViewingPublicKey}, }; +use sha2::{Digest, Sha256}; use crate::{Address, error::NssaError}; +pub type ViewTag = u8; + #[derive(Debug, Clone, PartialEq, Eq)] pub struct EncryptedAccountData { pub(crate) ciphertext: Ciphertext, pub(crate) epk: EphemeralPublicKey, - pub(crate) view_tag: u8, + pub(crate) view_tag: ViewTag, +} + +impl EncryptedAccountData { + fn new( + ciphertext: Ciphertext, + npk: NullifierPublicKey, + ivk: IncomingViewingPublicKey, + epk: EphemeralPublicKey, + ) -> Self { + let view_tag = Self::compute_view_tag(npk, ivk); + Self { + ciphertext, + epk, + view_tag, + } + } + + /// Computes the tag as the first byte of SHA256("/NSSA/v0.1/ViewTag" || Npk || Ivk) + pub fn compute_view_tag(npk: NullifierPublicKey, ivk: IncomingViewingPublicKey) -> ViewTag { + let mut hasher = Sha256::new(); + hasher.update(b"/NSSA/v0.1/ViewTag"); + hasher.update(npk.to_byte_array()); + hasher.update(ivk.to_bytes()); + let digest: [u8; 32] = hasher.finalize().into(); + digest[0] + } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -27,10 +56,14 @@ impl Message { pub fn try_from_circuit_output( public_addresses: Vec
, nonces: Vec, - ephemeral_public_keys: Vec, + public_keys: Vec<( + NullifierPublicKey, + IncomingViewingPublicKey, + EphemeralPublicKey, + )>, output: PrivacyPreservingCircuitOutput, ) -> Result { - if ephemeral_public_keys.len() != output.ciphertexts.len() { + if public_keys.len() != output.ciphertexts.len() { return Err(NssaError::InvalidInput( "Ephemeral public keys and ciphertexts length mismatch".into(), )); @@ -39,11 +72,9 @@ impl Message { let encrypted_private_post_states = output .ciphertexts .into_iter() - .zip(ephemeral_public_keys) - .map(|(ciphertext, epk)| EncryptedAccountData { - ciphertext, - epk, - view_tag: 0, // TODO: implement + .zip(public_keys) + .map(|(ciphertext, (npk, ivk, epk))| { + EncryptedAccountData::new(ciphertext, npk, ivk, epk) }) .collect(); Ok(Self { @@ -61,9 +92,17 @@ impl Message { pub mod tests { use std::io::Cursor; - use nssa_core::{Commitment, Nullifier, NullifierPublicKey, account::Account}; + use nssa_core::{ + Commitment, EncryptionScheme, Nullifier, NullifierPublicKey, SharedSecretKey, + account::Account, + encryption::{EphemeralPublicKey, IncomingViewingPublicKey}, + }; + use sha2::{Digest, Sha256}; - use crate::{Address, privacy_preserving_transaction::message::Message}; + use crate::{ + Address, + privacy_preserving_transaction::message::{EncryptedAccountData, Message}, + }; pub fn message_for_tests() -> Message { let account1 = Account::default(); @@ -108,4 +147,35 @@ pub mod tests { assert_eq!(message, message_from_cursor); } + + #[test] + fn test_encrypted_account_data_constructor() { + let npk = NullifierPublicKey::from(&[1; 32]); + let ivk = IncomingViewingPublicKey::from(&[2; 32]); + let account = Account::default(); + let commitment = Commitment::new(&npk, &account); + let esk = [3; 32]; + let shared_secret = SharedSecretKey::new(&esk, &ivk); + let epk = EphemeralPublicKey::from_scalar(esk); + let ciphertext = EncryptionScheme::encrypt(&account, &shared_secret, &commitment, 2); + let encrypted_account_data = + EncryptedAccountData::new(ciphertext.clone(), npk.clone(), ivk.clone(), epk.clone()); + + let expected_view_tag = { + let mut hasher = Sha256::new(); + hasher.update(b"/NSSA/v0.1/ViewTag"); + hasher.update(npk.to_byte_array()); + hasher.update(ivk.to_bytes()); + let digest: [u8; 32] = hasher.finalize().into(); + digest[0] + }; + + assert_eq!(encrypted_account_data.ciphertext, ciphertext); + assert_eq!(encrypted_account_data.epk, epk); + assert_eq!( + encrypted_account_data.view_tag, + EncryptedAccountData::compute_view_tag(npk, ivk) + ); + assert_eq!(encrypted_account_data.view_tag, expected_view_tag); + } } diff --git a/nssa/src/state.rs b/nssa/src/state.rs index 93ee06c..f975804 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -801,7 +801,7 @@ pub mod tests { let message = Message::try_from_circuit_output( vec![sender_keys.address()], vec![sender_nonce], - vec![epk], + vec![(recipient_keys.npk(), recipient_keys.ivk(), epk)], output, ) .unwrap(); @@ -854,8 +854,16 @@ pub mod tests { ) .unwrap(); - let message = - Message::try_from_circuit_output(vec![], vec![], vec![epk_1, epk_2], output).unwrap(); + let message = Message::try_from_circuit_output( + vec![], + vec![], + vec![ + (sender_keys.npk(), sender_keys.ivk(), epk_1), + (recipient_keys.npk(), recipient_keys.ivk(), epk_2), + ], + output, + ) + .unwrap(); let witness_set = WitnessSet::for_message(&message, proof, &[]); @@ -899,9 +907,13 @@ pub mod tests { ) .unwrap(); - let message = - Message::try_from_circuit_output(vec![*recipient_address], vec![], vec![epk], output) - .unwrap(); + let message = Message::try_from_circuit_output( + vec![*recipient_address], + vec![], + vec![(sender_keys.npk(), sender_keys.ivk(), epk)], + output, + ) + .unwrap(); let witness_set = WitnessSet::for_message(&message, proof, &[]); diff --git a/nssa/test_program_methods/guest/Cargo.toml b/nssa/test_program_methods/guest/Cargo.toml index da4dbe8..2289292 100644 --- a/nssa/test_program_methods/guest/Cargo.toml +++ b/nssa/test_program_methods/guest/Cargo.toml @@ -6,5 +6,4 @@ edition = "2024" [workspace] [dependencies] -risc0-zkvm = { version = "3.0.3", default-features = false, features = ['std'] } nssa-core = { path = "../../core" } diff --git a/sequencer_core/Cargo.toml b/sequencer_core/Cargo.toml index d818916..cf98855 100644 --- a/sequencer_core/Cargo.toml +++ b/sequencer_core/Cargo.toml @@ -6,14 +6,8 @@ edition = "2024" [dependencies] hex.workspace = true anyhow.workspace = true -serde_json.workspace = true -env_logger.workspace = true -log = "0.4.28" serde.workspace = true rand.workspace = true -elliptic-curve.workspace = true -k256.workspace = true -tiny-keccak.workspace = true tempfile.workspace = true [dependencies.storage] @@ -22,15 +16,8 @@ path = "../storage" [dependencies.mempool] path = "../mempool" -[dependencies.key_protocol] -path = "../key_protocol" - [dependencies.common] path = "../common" [dependencies.nssa] path = "../nssa" - -[dependencies.secp256k1-zkp] -workspace = true -features = ["std", "rand-std", "rand", "serde", "global-context"] diff --git a/sequencer_rpc/Cargo.toml b/sequencer_rpc/Cargo.toml index a0111f6..7972342 100644 --- a/sequencer_rpc/Cargo.toml +++ b/sequencer_rpc/Cargo.toml @@ -6,10 +6,8 @@ edition = "2024" [dependencies] anyhow.workspace = true serde_json.workspace = true -env_logger.workspace = true log.workspace = true serde.workspace = true -actix.workspace = true actix-cors.workspace = true futures.workspace = true hex.workspace = true @@ -19,18 +17,9 @@ base64.workspace = true actix-web.workspace = true tokio.workspace = true -[dependencies.mempool] -path = "../mempool" - -[dependencies.key_protocol] -path = "../key_protocol" - [dependencies.sequencer_core] path = "../sequencer_core" -[dependencies.storage] -path = "../storage" - [dependencies.common] path = "../common" diff --git a/sequencer_runner/Cargo.toml b/sequencer_runner/Cargo.toml index a610f8d..4da788d 100644 --- a/sequencer_runner/Cargo.toml +++ b/sequencer_runner/Cargo.toml @@ -8,20 +8,15 @@ anyhow.workspace = true serde_json.workspace = true env_logger.workspace = true log.workspace = true -serde.workspace = true actix.workspace = true actix-web.workspace = true tokio.workspace = true -toml.workspace = true [dependencies.clap] features = ["derive", "env"] workspace = true -[dependencies.mempool] -path = "../mempool" - [dependencies.sequencer_rpc] path = "../sequencer_rpc" diff --git a/storage/Cargo.toml b/storage/Cargo.toml index d756dd3..604b2fe 100644 --- a/storage/Cargo.toml +++ b/storage/Cargo.toml @@ -6,12 +6,8 @@ edition = "2024" [dependencies] anyhow.workspace = true serde_json.workspace = true -env_logger.workspace = true -log.workspace = true serde.workspace = true -lru.workspace = true thiserror.workspace = true -hex.workspace = true rocksdb.workspace = true diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index 6078f68..2caa7ff 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -9,18 +9,8 @@ serde_json.workspace = true env_logger.workspace = true log.workspace = true serde.workspace = true -rand.workspace = true -k256.workspace = true -sha2.workspace = true -bincode.workspace = true -elliptic-curve.workspace = true -reqwest.workspace = true -thiserror.workspace = true tokio.workspace = true tempfile.workspace = true -risc0-zkvm = "3.0.3" -hex.workspace = true -actix-rt.workspace = true clap.workspace = true nssa-core = { path = "../nssa/core" } base64.workspace = true @@ -33,7 +23,3 @@ path = "../nssa" [dependencies.common] path = "../common" - -[dependencies.secp256k1-zkp] -workspace = true -features = ["std", "rand-std", "rand", "serde", "global-context"]