diff --git a/nssa/core/src/account.rs b/nssa/core/src/account.rs index 94986c2..45e6e2c 100644 --- a/nssa/core/src/account.rs +++ b/nssa/core/src/account.rs @@ -1,4 +1,4 @@ -use crate::program::ProgramId; +use crate::{NullifierPublicKey, program::ProgramId}; use serde::{Deserialize, Serialize}; pub type Nonce = u128; @@ -14,7 +14,14 @@ pub struct Account { pub nonce: Nonce, } -pub type FingerPrint = [u8; 32]; +#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)] +#[cfg_attr(any(feature = "host", test), derive(Debug))] +pub struct FingerPrint([u8; 32]); +impl FingerPrint { + pub fn new(value: [u8; 32]) -> Self { + Self(value) + } +} #[derive(Serialize, Deserialize, Clone)] #[cfg_attr(any(feature = "host", test), derive(Debug, PartialEq, Eq))] diff --git a/nssa/core/src/circuit_io.rs b/nssa/core/src/circuit_io.rs index 194b371..2473475 100644 --- a/nssa/core/src/circuit_io.rs +++ b/nssa/core/src/circuit_io.rs @@ -40,8 +40,7 @@ impl PrivacyPreservingCircuitOutput { mod tests { use super::*; use crate::{ - Commitment, Nullifier, NullifierPublicKey, - account::{Account, AccountWithMetadata}, + account::{Account, AccountWithMetadata, FingerPrint}, Commitment, Nullifier, NullifierPublicKey }; use risc0_zkvm::serde::from_slice; @@ -57,7 +56,7 @@ mod tests { nonce: 18446744073709551614, }, is_authorized: true, - fingerprint: [0; 32], + fingerprint: FingerPrint::new([0; 32]), }, AccountWithMetadata { account: Account { @@ -67,7 +66,7 @@ mod tests { nonce: 9999999999999999999999, }, is_authorized: false, - fingerprint: [1; 32], + fingerprint: FingerPrint::new([1; 32]), }, ], public_post_states: vec![Account { diff --git a/nssa/core/src/nullifier.rs b/nssa/core/src/nullifier.rs index d1410de..c783091 100644 --- a/nssa/core/src/nullifier.rs +++ b/nssa/core/src/nullifier.rs @@ -1,12 +1,24 @@ use risc0_zkvm::sha::{Impl, Sha256}; use serde::{Deserialize, Serialize}; -use crate::Commitment; +use crate::{Commitment, account::FingerPrint}; #[derive(Serialize, Deserialize, PartialEq, Eq)] #[cfg_attr(any(feature = "host", test), derive(Debug, Clone, Hash))] pub struct NullifierPublicKey(pub(super) [u8; 32]); +impl From<&NullifierPublicKey> for FingerPrint { + fn from(value: &NullifierPublicKey) -> Self { + FingerPrint::new(value.0) + } +} + +impl From for FingerPrint { + fn from(value: NullifierPublicKey) -> Self { + FingerPrint::new(value.0) + } +} + impl From<&NullifierSecretKey> for NullifierPublicKey { fn from(value: &NullifierSecretKey) -> Self { let mut bytes = Vec::new(); diff --git a/nssa/program_methods/guest/src/bin/privacy_preserving_circuit.rs b/nssa/program_methods/guest/src/bin/privacy_preserving_circuit.rs index 83f593a..346682d 100644 --- a/nssa/program_methods/guest/src/bin/privacy_preserving_circuit.rs +++ b/nssa/program_methods/guest/src/bin/privacy_preserving_circuit.rs @@ -1,12 +1,7 @@ use risc0_zkvm::{guest::env, serde::to_vec}; use nssa_core::{ - account::{Account, AccountWithMetadata}, - compute_digest_for_path, - encryption::Ciphertext, - program::{validate_execution, ProgramOutput, DEFAULT_PROGRAM_ID}, - Commitment, CommitmentSetDigest, EncryptionScheme, Nullifier, NullifierPublicKey, - PrivacyPreservingCircuitInput, PrivacyPreservingCircuitOutput, + account::{Account, AccountWithMetadata, FingerPrint}, compute_digest_for_path, encryption::Ciphertext, program::{validate_execution, ProgramOutput, DEFAULT_PROGRAM_ID}, Commitment, CommitmentSetDigest, EncryptionScheme, Nullifier, NullifierPublicKey, PrivacyPreservingCircuitInput, PrivacyPreservingCircuitOutput }; fn main() { @@ -70,6 +65,10 @@ fn main() { let new_nonce = private_nonces_iter.next().expect("Missing private nonce"); let (npk, shared_secret) = private_keys_iter.next().expect("Missing keys"); + if FingerPrint::from(npk) != pre_states[i].fingerprint { + panic!("Fingerprint mismatch"); + } + if visibility_mask[i] == 1 { // Private account with authentication let (nsk, membership_proof) = diff --git a/nssa/src/address.rs b/nssa/src/address.rs index 93304d5..0dba65a 100644 --- a/nssa/src/address.rs +++ b/nssa/src/address.rs @@ -1,5 +1,6 @@ use std::{fmt::Display, str::FromStr}; +use nssa_core::account::FingerPrint; use serde::{Deserialize, Serialize}; use crate::signature::PublicKey; @@ -81,6 +82,20 @@ impl<'de> Deserialize<'de> for Address { } } + +impl From<&Address> for FingerPrint { + fn from(address: &Address) -> Self { + FingerPrint::new(address.value) + } +} + +impl From
for FingerPrint { + fn from(address: Address) -> Self { + FingerPrint::new(address.value) + } +} + + #[cfg(test)] mod tests { use crate::{Address, address::AddressError}; diff --git a/nssa/src/privacy_preserving_transaction/circuit.rs b/nssa/src/privacy_preserving_transaction/circuit.rs index ba7647c..c1afe39 100644 --- a/nssa/src/privacy_preserving_transaction/circuit.rs +++ b/nssa/src/privacy_preserving_transaction/circuit.rs @@ -75,11 +75,7 @@ fn execute_and_prove_program( ) -> Result { // Write inputs to the program let mut env_builder = ExecutorEnv::builder(); - Program::write_inputs( - pre_states, - instruction_data, - &mut env_builder, - )?; + Program::write_inputs(pre_states, instruction_data, &mut env_builder)?; let env = env_builder.build().unwrap(); // Prove the program @@ -110,6 +106,7 @@ mod tests { #[test] fn prove_privacy_preserving_execution_circuit_public_and_private_pre_accounts() { + let recipient_keys = test_private_account_keys_1(); let program = Program::authenticated_transfer_program(); let sender = AccountWithMetadata { account: Account { @@ -117,13 +114,13 @@ mod tests { ..Account::default() }, is_authorized: true, - fingerprint: [0; 32], + fingerprint: FingerPrint::new([0; 32]), }; let recipient = AccountWithMetadata { account: Account::default(), is_authorized: false, - fingerprint: [1; 32], + fingerprint: recipient_keys.npk().into(), }; let balance_to_move: u128 = 37; @@ -143,7 +140,6 @@ mod tests { }; let expected_sender_pre = sender.clone(); - let recipient_keys = test_private_account_keys_1(); let esk = [3; 32]; let shared_secret = SharedSecretKey::new(&esk, &recipient_keys.ivk()); @@ -181,6 +177,9 @@ mod tests { #[test] fn prove_privacy_preserving_execution_circuit_fully_private() { + let sender_keys = test_private_account_keys_1(); + let recipient_keys = test_private_account_keys_2(); + let sender_pre = AccountWithMetadata { account: Account { balance: 100, @@ -188,16 +187,14 @@ mod tests { ..Account::default() }, is_authorized: true, - fingerprint: [0; 32], + fingerprint: sender_keys.npk().into(), }; - let sender_keys = test_private_account_keys_1(); - let recipient_keys = test_private_account_keys_2(); let commitment_sender = Commitment::new(&sender_keys.npk(), &sender_pre.account); let recipient = AccountWithMetadata { account: Account::default(), is_authorized: false, - fingerprint: [1; 32], + fingerprint: recipient_keys.npk().into(), }; let balance_to_move: u128 = 37; diff --git a/nssa/src/privacy_preserving_transaction/transaction.rs b/nssa/src/privacy_preserving_transaction/transaction.rs index ee8eeba..a683f85 100644 --- a/nssa/src/privacy_preserving_transaction/transaction.rs +++ b/nssa/src/privacy_preserving_transaction/transaction.rs @@ -93,7 +93,7 @@ impl PrivacyPreservingTransaction { .map(|address| AccountWithMetadata { account: state.get_account_by_address(address), is_authorized: signer_addresses.contains(address), - fingerprint: *address.value(), + fingerprint: address.into(), }) .collect(); diff --git a/nssa/src/program.rs b/nssa/src/program.rs index 0c05902..cf7c9da 100644 --- a/nssa/src/program.rs +++ b/nssa/src/program.rs @@ -77,7 +77,7 @@ impl Program { #[cfg(test)] mod tests { - use nssa_core::account::{Account, AccountWithMetadata}; + use nssa_core::account::{Account, AccountWithMetadata, FingerPrint}; use crate::program::Program; @@ -174,12 +174,12 @@ mod tests { ..Account::default() }, is_authorized: true, - fingerprint: [0; 32], + fingerprint: FingerPrint::new([0; 32]), }; let recipient = AccountWithMetadata { account: Account::default(), is_authorized: false, - fingerprint: [1; 32], + fingerprint: FingerPrint::new([1; 32]), }; let expected_sender_post = Account { diff --git a/nssa/src/public_transaction/transaction.rs b/nssa/src/public_transaction/transaction.rs index f3a8ed6..64e0707 100644 --- a/nssa/src/public_transaction/transaction.rs +++ b/nssa/src/public_transaction/transaction.rs @@ -94,7 +94,7 @@ impl PublicTransaction { .map(|address| AccountWithMetadata { account: state.get_account_by_address(address), is_authorized: signer_addresses.contains(address), - fingerprint: *address.value() + fingerprint: address.into() }) .collect(); diff --git a/nssa/src/state.rs b/nssa/src/state.rs index 8662323..347102a 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -779,7 +779,7 @@ pub mod tests { let sender = AccountWithMetadata { account: state.get_account_by_address(&sender_keys.address()), is_authorized: true, - fingerprint: *sender_keys.address().value(), + fingerprint: sender_keys.address().into(), }; let sender_nonce = sender.account.nonce; @@ -787,7 +787,7 @@ pub mod tests { let recipient = AccountWithMetadata { account: Account::default(), is_authorized: false, - fingerprint: recipient_keys.npk().to_byte_array(), + fingerprint: recipient_keys.npk().into(), }; let esk = [3; 32]; @@ -830,12 +830,12 @@ pub mod tests { let sender_pre = AccountWithMetadata { account: sender_private_account.clone(), is_authorized: true, - fingerprint: sender_keys.npk().to_byte_array(), + fingerprint: sender_keys.npk().into(), }; let recipient_pre = AccountWithMetadata { account: Account::default(), is_authorized: false, - fingerprint: recipient_keys.npk().to_byte_array(), + fingerprint: recipient_keys.npk().into(), }; let esk_1 = [3; 32]; @@ -892,12 +892,12 @@ pub mod tests { let sender_pre = AccountWithMetadata { account: sender_private_account.clone(), is_authorized: true, - fingerprint: sender_keys.npk().to_byte_array(), + fingerprint: sender_keys.npk().into(), }; let recipient_pre = AccountWithMetadata { account: state.get_account_by_address(recipient_address), is_authorized: false, - fingerprint: *recipient_address.value(), + fingerprint: recipient_address.into(), }; let esk = [3; 32];