mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-02 13:23:10 +00:00
add encodings
This commit is contained in:
parent
1e1ab787bc
commit
a185e52203
@ -6,7 +6,7 @@ edition = "2024"
|
||||
[dependencies]
|
||||
thiserror = "2.0.12"
|
||||
risc0-zkvm = "2.3.1"
|
||||
nssa-core = { path = "core" }
|
||||
nssa-core = { path = "core", features=["host"]}
|
||||
program-methods = { path = "program_methods" }
|
||||
serde = "1.0.219"
|
||||
sha2 = "0.10.9"
|
||||
|
||||
@ -6,3 +6,8 @@ edition = "2024"
|
||||
[dependencies]
|
||||
risc0-zkvm = "2.3.1"
|
||||
serde = { version = "1.0", default-features = false }
|
||||
thiserror = { version = "2.0.12", optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
host = ["thiserror"]
|
||||
|
||||
@ -13,7 +13,21 @@ impl Commitment {
|
||||
pub fn new(Npk: &NullifierPublicKey, account: &Account) -> Self {
|
||||
let mut bytes = Vec::new();
|
||||
bytes.extend_from_slice(&Npk.to_byte_array());
|
||||
bytes.extend_from_slice(&account.to_bytes());
|
||||
let account_bytes_with_hashed_data = {
|
||||
let mut this = Vec::new();
|
||||
for word in &account.program_owner {
|
||||
this.extend_from_slice(&word.to_le_bytes());
|
||||
}
|
||||
this.extend_from_slice(&account.balance.to_le_bytes());
|
||||
this.extend_from_slice(&account.nonce.to_le_bytes());
|
||||
let hashed_data: [u8; 32] = Impl::hash_bytes(&account.data)
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
this.extend_from_slice(&hashed_data);
|
||||
this
|
||||
};
|
||||
bytes.extend_from_slice(&account_bytes_with_hashed_data);
|
||||
Self(Impl::hash_bytes(&bytes).as_bytes().try_into().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
use risc0_zkvm::{
|
||||
serde::to_vec,
|
||||
sha::{Impl, Sha256},
|
||||
};
|
||||
use risc0_zkvm::sha::{Impl, Sha256};
|
||||
|
||||
use crate::account::{Account, Commitment, NullifierPublicKey};
|
||||
#[cfg(feature = "host")]
|
||||
use std::io::Cursor;
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
use std::io::Read;
|
||||
|
||||
use crate::account::{Account, Commitment, Nullifier, NullifierPublicKey};
|
||||
#[cfg(feature = "host")]
|
||||
use crate::error::NssaCoreError;
|
||||
|
||||
impl Account {
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
@ -13,28 +18,82 @@ impl Account {
|
||||
}
|
||||
bytes.extend_from_slice(&self.balance.to_le_bytes());
|
||||
bytes.extend_from_slice(&self.nonce.to_le_bytes());
|
||||
let hashed_data: [u8; 32] = Impl::hash_bytes(&self.data).as_bytes().try_into().unwrap();
|
||||
bytes.extend_from_slice(&hashed_data);
|
||||
let data_length: u32 = self.data.len() as u32;
|
||||
bytes.extend_from_slice(&data_length.to_le_bytes());
|
||||
bytes.extend_from_slice(self.data.as_slice());
|
||||
bytes
|
||||
}
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result<Self, NssaCoreError> {
|
||||
let mut u32_bytes = [0u8; 4];
|
||||
let mut u128_bytes = [0u8; 16];
|
||||
|
||||
// program owner
|
||||
let mut program_owner = [0u32; 8];
|
||||
for word in &mut program_owner {
|
||||
cursor.read_exact(&mut u32_bytes)?;
|
||||
*word = u32::from_le_bytes(u32_bytes);
|
||||
}
|
||||
|
||||
// balance
|
||||
cursor.read_exact(&mut u128_bytes)?;
|
||||
let balance = u128::from_le_bytes(u128_bytes);
|
||||
|
||||
// nonce
|
||||
cursor.read_exact(&mut u128_bytes)?;
|
||||
let nonce = u128::from_le_bytes(u128_bytes);
|
||||
|
||||
//data
|
||||
cursor.read_exact(&mut u32_bytes)?;
|
||||
let data_length = u32::from_le_bytes(u32_bytes);
|
||||
let mut data = vec![0; data_length as usize];
|
||||
cursor.read_exact(&mut data)?;
|
||||
|
||||
Ok(Self {
|
||||
program_owner,
|
||||
balance,
|
||||
data,
|
||||
nonce,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Commitment {
|
||||
pub(crate) fn to_byte_array(&self) -> [u8; 32] {
|
||||
pub fn to_byte_array(&self) -> [u8; 32] {
|
||||
self.0
|
||||
}
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result<Self, NssaCoreError> {
|
||||
let mut bytes = [0u8; 32];
|
||||
cursor.read_exact(&mut bytes)?;
|
||||
Ok(Self(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl NullifierPublicKey {
|
||||
pub fn to_byte_array(&self) -> [u8; 32] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl NullifierPublicKey {
|
||||
pub(crate) fn to_byte_array(&self) -> [u8; 32] {
|
||||
#[cfg(feature = "host")]
|
||||
impl Nullifier {
|
||||
pub fn to_byte_array(&self) -> [u8; 32] {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result<Self, NssaCoreError> {
|
||||
let mut bytes = [0u8; 32];
|
||||
cursor.read_exact(&mut bytes)?;
|
||||
Ok(Self(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::account::Account;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_enconding() {
|
||||
@ -49,12 +108,64 @@ mod tests {
|
||||
let expected_bytes = [
|
||||
1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8,
|
||||
0, 0, 0, 192, 186, 220, 114, 113, 65, 236, 234, 222, 15, 215, 191, 227, 198, 23, 0, 42,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 137, 65, 102, 211, 51, 100, 53, 200,
|
||||
0, 190, 163, 111, 242, 27, 41, 234, 168, 1, 165, 47, 88, 76, 0, 108, 73, 40, 154, 13,
|
||||
207, 110, 47,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 104, 111, 108, 97, 32, 109,
|
||||
117, 110, 100, 111,
|
||||
];
|
||||
|
||||
let bytes = account.to_bytes();
|
||||
assert_eq!(bytes, expected_bytes);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_commitment_to_bytes() {
|
||||
let commitment = Commitment((0..32).collect::<Vec<u8>>().try_into().unwrap());
|
||||
let expected_bytes: [u8; 32] = (0..32).collect::<Vec<u8>>().try_into().unwrap();
|
||||
|
||||
let bytes = commitment.to_byte_array();
|
||||
assert_eq!(expected_bytes, bytes);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nullifier_to_bytes() {
|
||||
let nullifier = Nullifier((0..32).collect::<Vec<u8>>().try_into().unwrap());
|
||||
let expected_bytes: [u8; 32] = (0..32).collect::<Vec<u8>>().try_into().unwrap();
|
||||
|
||||
let bytes = nullifier.to_byte_array();
|
||||
assert_eq!(expected_bytes, bytes);
|
||||
}
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
#[test]
|
||||
fn test_commitment_to_bytes_roundtrip() {
|
||||
let commitment = Commitment((0..32).collect::<Vec<u8>>().try_into().unwrap());
|
||||
let bytes = commitment.to_byte_array();
|
||||
let mut cursor = Cursor::new(bytes.as_ref());
|
||||
let commitment_from_cursor = Commitment::from_cursor(&mut cursor).unwrap();
|
||||
assert_eq!(commitment, commitment_from_cursor);
|
||||
}
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
#[test]
|
||||
fn test_nullifier_to_bytes_roundtrip() {
|
||||
let nullifier = Nullifier((0..32).collect::<Vec<u8>>().try_into().unwrap());
|
||||
let bytes = nullifier.to_byte_array();
|
||||
let mut cursor = Cursor::new(bytes.as_ref());
|
||||
let nullifier_from_cursor = Nullifier::from_cursor(&mut cursor).unwrap();
|
||||
assert_eq!(nullifier, nullifier_from_cursor);
|
||||
}
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
#[test]
|
||||
fn test_account_to_bytes_roundtrip() {
|
||||
let account = Account {
|
||||
program_owner: [1, 2, 3, 4, 5, 6, 7, 8],
|
||||
balance: 123456789012345678901234567890123456,
|
||||
nonce: 42,
|
||||
data: b"hola mundo".to_vec(),
|
||||
};
|
||||
let bytes = account.to_bytes();
|
||||
let mut cursor = Cursor::new(bytes.as_ref());
|
||||
let account_from_cursor = Account::from_cursor(&mut cursor).unwrap();
|
||||
assert_eq!(account, account_from_cursor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ impl From<&NullifierSecretKey> for NullifierPublicKey {
|
||||
pub type NullifierSecretKey = [u8; 32];
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Nullifier([u8; 32]);
|
||||
pub struct Nullifier(pub(super) [u8; 32]);
|
||||
|
||||
impl Nullifier {
|
||||
pub fn new(commitment: &Commitment, nsk: &NullifierSecretKey) -> Self {
|
||||
@ -53,12 +53,12 @@ mod tests {
|
||||
#[test]
|
||||
fn test_from_secret_key() {
|
||||
let nsk = [
|
||||
50, 139, 109, 225, 82, 86, 80, 108, 140, 248, 232, 229, 96, 80, 148, 250, 15, 9, 155,
|
||||
44, 196, 224, 115, 180, 160, 44, 113, 133, 15, 196, 253, 42,
|
||||
57, 5, 64, 115, 153, 56, 184, 51, 207, 238, 99, 165, 147, 214, 213, 151, 30, 251, 30,
|
||||
196, 134, 22, 224, 211, 237, 120, 136, 225, 188, 220, 249, 28,
|
||||
];
|
||||
let expected_Npk = NullifierPublicKey([
|
||||
38, 90, 215, 216, 195, 66, 157, 77, 161, 59, 121, 18, 118, 37, 57, 199, 189, 251, 95,
|
||||
130, 12, 9, 171, 169, 140, 221, 87, 242, 46, 243, 111, 85,
|
||||
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);
|
||||
|
||||
12
nssa/core/src/error.rs
Normal file
12
nssa/core/src/error.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use std::io;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum NssaCoreError {
|
||||
#[error("Invalid transaction: {0}")]
|
||||
DeserializationError(String),
|
||||
|
||||
#[error("IO error: {0}")]
|
||||
Io(#[from] io::Error),
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
use crate::error::NssaCoreError;
|
||||
use crate::{
|
||||
account::{
|
||||
Account, AccountWithMetadata, Commitment, Nonce, Nullifier, NullifierPublicKey,
|
||||
@ -8,9 +10,15 @@ use crate::{
|
||||
program::{ProgramId, ProgramOutput},
|
||||
};
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
use std::io::Cursor;
|
||||
|
||||
pub mod account;
|
||||
pub mod program;
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
pub mod error;
|
||||
|
||||
pub type CommitmentSetDigest = [u32; 8];
|
||||
pub type MembershipProof = Vec<[u8; 32]>;
|
||||
pub fn verify_membership_proof(
|
||||
@ -51,6 +59,18 @@ impl EncryptedAccountData {
|
||||
// TODO: implement
|
||||
Self
|
||||
}
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result<Self, NssaCoreError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl EncryptedAccountData {
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
// TODO: implement
|
||||
vec![0]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
|
||||
@ -31,4 +31,9 @@ pub enum NssaError {
|
||||
#[error("Risc0 error: {0}")]
|
||||
ProgramProveFailed(String),
|
||||
|
||||
#[error("Invalid transaction: {0}")]
|
||||
TransactionDeserializationError(String),
|
||||
|
||||
#[error("Core error")]
|
||||
Core(#[from] nssa_core::error::NssaCoreError),
|
||||
}
|
||||
|
||||
140
nssa/src/privacy_preserving_transaction/encoding.rs
Normal file
140
nssa/src/privacy_preserving_transaction/encoding.rs
Normal file
@ -0,0 +1,140 @@
|
||||
use std::io::{Cursor, Read};
|
||||
|
||||
use nssa_core::{
|
||||
EncryptedAccountData,
|
||||
account::{Account, Commitment, Nullifier},
|
||||
};
|
||||
|
||||
use crate::{Address, error::NssaError};
|
||||
|
||||
use super::message::Message;
|
||||
|
||||
const MESSAGE_ENCODING_PREFIX_LEN: usize = 37;
|
||||
const MESSAGE_ENCODING_PREFIX: &[u8; MESSAGE_ENCODING_PREFIX_LEN] =
|
||||
b"NSSA/v0.1/TxMessage/PrivacyPreserving";
|
||||
|
||||
impl Message {
|
||||
pub(crate) fn to_bytes(&self) -> Vec<u8> {
|
||||
let mut bytes = MESSAGE_ENCODING_PREFIX.to_vec();
|
||||
|
||||
// Public addresses
|
||||
let public_addresses_len: u32 = self.public_addresses.len() as u32;
|
||||
bytes.extend_from_slice(&public_addresses_len.to_le_bytes());
|
||||
for address in &self.public_addresses {
|
||||
bytes.extend_from_slice(address.value());
|
||||
}
|
||||
// Nonces
|
||||
let nonces_len = self.nonces.len() as u32;
|
||||
bytes.extend(&nonces_len.to_le_bytes());
|
||||
for nonce in &self.nonces {
|
||||
bytes.extend(&nonce.to_le_bytes());
|
||||
}
|
||||
// Public post states
|
||||
let public_post_states_len: u32 = self.public_post_states.len() as u32;
|
||||
bytes.extend_from_slice(&public_post_states_len.to_le_bytes());
|
||||
for account in &self.public_post_states {
|
||||
bytes.extend_from_slice(&account.to_bytes());
|
||||
}
|
||||
|
||||
// Encrypted post states
|
||||
let encrypted_accounts_post_states_len: u32 =
|
||||
self.encrypted_private_post_states.len() as u32;
|
||||
for encrypted_account in &self.encrypted_private_post_states {
|
||||
bytes.extend_from_slice(&encrypted_account.to_bytes());
|
||||
}
|
||||
|
||||
// New commitments
|
||||
let new_commitments_len: u32 = self.new_commitments.len() as u32;
|
||||
for commitment in &self.new_commitments {
|
||||
bytes.extend_from_slice(&commitment.to_byte_array());
|
||||
}
|
||||
|
||||
// New nullifiers
|
||||
let new_nullifiers_len: u32 = self.new_nullifiers.len() as u32;
|
||||
for nullifier in &self.new_nullifiers {
|
||||
bytes.extend_from_slice(&nullifier.to_byte_array());
|
||||
}
|
||||
bytes
|
||||
}
|
||||
|
||||
pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result<Self, NssaError> {
|
||||
let prefix = {
|
||||
let mut this = [0u8; MESSAGE_ENCODING_PREFIX_LEN];
|
||||
cursor.read_exact(&mut this)?;
|
||||
this
|
||||
};
|
||||
let prefix = {
|
||||
let mut this = [0u8; MESSAGE_ENCODING_PREFIX_LEN];
|
||||
cursor.read_exact(&mut this)?;
|
||||
this
|
||||
};
|
||||
if &prefix != MESSAGE_ENCODING_PREFIX {
|
||||
return Err(NssaError::TransactionDeserializationError(
|
||||
"Invalid privacy preserving message prefix".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let mut len_bytes = [0u8; 4];
|
||||
|
||||
// Public addresses
|
||||
cursor.read_exact(&mut len_bytes)?;
|
||||
let public_addresses_len = u32::from_le_bytes(len_bytes) as usize;
|
||||
let mut public_addresses = Vec::with_capacity(public_addresses_len);
|
||||
for _ in 0..public_addresses_len {
|
||||
let mut value = [0u8; 32];
|
||||
cursor.read_exact(&mut value)?;
|
||||
public_addresses.push(Address::new(value))
|
||||
}
|
||||
|
||||
// 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);
|
||||
for _ in 0..nonces_len {
|
||||
let mut buf = [0u8; 16];
|
||||
cursor.read_exact(&mut buf)?;
|
||||
nonces.push(u128::from_le_bytes(buf))
|
||||
}
|
||||
|
||||
// Public post states
|
||||
cursor.read_exact(&mut len_bytes)?;
|
||||
let public_post_states_len = u32::from_le_bytes(len_bytes) as usize;
|
||||
let mut public_post_states = Vec::with_capacity(public_post_states_len);
|
||||
for _ in 0..public_post_states_len {
|
||||
public_post_states.push(Account::from_cursor(cursor)?);
|
||||
}
|
||||
|
||||
// Encrypted private post states
|
||||
cursor.read_exact(&mut len_bytes)?;
|
||||
let encrypted_len = u32::from_le_bytes(len_bytes) as usize;
|
||||
let mut encrypted_private_post_states = Vec::with_capacity(encrypted_len);
|
||||
for _ in 0..encrypted_len {
|
||||
encrypted_private_post_states.push(EncryptedAccountData::from_cursor(cursor)?);
|
||||
}
|
||||
|
||||
// New commitments
|
||||
cursor.read_exact(&mut len_bytes)?;
|
||||
let new_commitments_len = u32::from_le_bytes(len_bytes) as usize;
|
||||
let mut new_commitments = Vec::with_capacity(new_commitments_len);
|
||||
for _ in 0..new_commitments_len {
|
||||
new_commitments.push(Commitment::from_cursor(cursor)?);
|
||||
}
|
||||
|
||||
// New nullifiers
|
||||
cursor.read_exact(&mut len_bytes)?;
|
||||
let new_nullifiers_len = u32::from_le_bytes(len_bytes) as usize;
|
||||
let mut new_nullifiers = Vec::with_capacity(new_nullifiers_len);
|
||||
for _ in 0..new_nullifiers_len {
|
||||
new_nullifiers.push(Nullifier::from_cursor(cursor)?);
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
public_addresses,
|
||||
nonces,
|
||||
public_post_states,
|
||||
encrypted_private_post_states,
|
||||
new_commitments,
|
||||
new_nullifiers,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -36,7 +36,7 @@ impl Message {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
pub mod tests {
|
||||
use nssa_core::account::{
|
||||
Account, Commitment, Nullifier, NullifierPublicKey, NullifierSecretKey,
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
mod transaction;
|
||||
mod message;
|
||||
mod witness_set;
|
||||
mod encoding;
|
||||
|
||||
pub use transaction::PrivacyPreservingTransaction;
|
||||
|
||||
@ -146,3 +146,8 @@ fn n_unique<T: Eq + Hash>(data: &[T]) -> usize {
|
||||
let set: HashSet<&T> = data.iter().collect();
|
||||
set.len()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ pub struct WitnessSet {
|
||||
}
|
||||
|
||||
impl WitnessSet {
|
||||
pub fn for_message(message: &Message, private_keys: &[&PrivateKey]) -> Self {
|
||||
pub fn for_message(message: &Message, proof: Proof, private_keys: &[&PrivateKey]) -> Self {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
||||
@ -8,8 +8,9 @@ use crate::{
|
||||
public_transaction::{Message, WitnessSet},
|
||||
};
|
||||
|
||||
const MESSAGE_ENCODING_PREFIX_LEN: usize = 19;
|
||||
const MESSAGE_ENCODING_PREFIX: &[u8; MESSAGE_ENCODING_PREFIX_LEN] = b"NSSA/v0.1/TxMessage";
|
||||
const MESSAGE_ENCODING_PREFIX_LEN: usize = 37;
|
||||
const MESSAGE_ENCODING_PREFIX: &[u8; MESSAGE_ENCODING_PREFIX_LEN] =
|
||||
b"NSSA/v0.1/TxMessage/Public\0\0\0\0\0\0\0\0\0\0\0";
|
||||
|
||||
impl Message {
|
||||
/// Serializes a `Message` into bytes in the following layout:
|
||||
@ -52,7 +53,12 @@ impl Message {
|
||||
cursor.read_exact(&mut this)?;
|
||||
this
|
||||
};
|
||||
assert_eq!(&prefix, MESSAGE_ENCODING_PREFIX);
|
||||
if &prefix != MESSAGE_ENCODING_PREFIX {
|
||||
return Err(NssaError::TransactionDeserializationError(
|
||||
"Invalid public message prefix".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let program_id: ProgramId = {
|
||||
let mut this = [0u32; 8];
|
||||
for item in &mut this {
|
||||
|
||||
@ -21,6 +21,10 @@ impl CommitmentSet {
|
||||
// TODO: implement
|
||||
[0; 8]
|
||||
}
|
||||
|
||||
fn contains(&self, commitment: &Commitment) -> bool {
|
||||
self.0.contains(commitment)
|
||||
}
|
||||
}
|
||||
|
||||
type NullifierSet = HashSet<Nullifier>;
|
||||
@ -139,14 +143,28 @@ impl V01State {
|
||||
&self,
|
||||
new_commitments: &[Commitment],
|
||||
) -> Result<(), NssaError> {
|
||||
todo!()
|
||||
for commitment in new_commitments.iter() {
|
||||
if self.private_state.0.contains(commitment) {
|
||||
return Err(NssaError::InvalidInput(
|
||||
"Commitment already seen".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn check_nullifiers_are_new(
|
||||
&self,
|
||||
new_nullifiers: &[Nullifier],
|
||||
) -> Result<(), NssaError> {
|
||||
todo!()
|
||||
for nullifier in new_nullifiers.iter() {
|
||||
if self.private_state.1.contains(nullifier) {
|
||||
return Err(NssaError::InvalidInput(
|
||||
"Nullifier already seen".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user