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"]