mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-04 22:33:06 +00:00
wip
This commit is contained in:
parent
64048ccf1d
commit
4bd5494370
@ -10,7 +10,8 @@ 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 }
|
||||
hex = { version = "0.4.3", optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
host = ["thiserror", "bytemuck", "k256"]
|
||||
host = ["thiserror", "bytemuck", "k256", "hex"]
|
||||
|
||||
132
nssa/core/src/address.rs
Normal file
132
nssa/core/src/address.rs
Normal file
@ -0,0 +1,132 @@
|
||||
use risc0_zkvm::sha::{Impl, Sha256};
|
||||
use std::{fmt::Display, str::FromStr};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::account::AccountId;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
pub struct Address {
|
||||
value: [u8; 32],
|
||||
}
|
||||
|
||||
impl Address {
|
||||
pub fn new(value: [u8; 32]) -> Self {
|
||||
Self { value }
|
||||
}
|
||||
|
||||
pub fn value(&self) -> &[u8; 32] {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for Address {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum AddressError {
|
||||
#[error("invalid hex")]
|
||||
InvalidHex(#[from] hex::FromHexError),
|
||||
#[error("invalid length: expected 32 bytes, got {0}")]
|
||||
InvalidLength(usize),
|
||||
}
|
||||
|
||||
impl FromStr for Address {
|
||||
type Err = AddressError;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let bytes = hex::decode(s)?;
|
||||
if bytes.len() != 32 {
|
||||
return Err(AddressError::InvalidLength(bytes.len()));
|
||||
}
|
||||
let mut value = [0u8; 32];
|
||||
value.copy_from_slice(&bytes);
|
||||
Ok(Address { value })
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Address {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", hex::encode(self.value))
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Address {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let hex_string = self.to_string();
|
||||
|
||||
hex_string.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Address {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let hex_string = String::deserialize(deserializer)?;
|
||||
|
||||
Address::from_str(&hex_string).map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Address> for AccountId {
|
||||
fn from(address: &Address) -> Self {
|
||||
const PUBLIC_ACCOUNT_ID_PREFIX: &[u8; 32] = b"/NSSA/v0.1/AccountId/Public/\x00\x00\x00\x00";
|
||||
|
||||
let mut bytes = PUBLIC_ACCOUNT_ID_PREFIX.to_vec();
|
||||
bytes.extend_from_slice(&address.value);
|
||||
AccountId::new(Impl::hash_bytes(&bytes).as_bytes().try_into().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{Address, AddressError};
|
||||
|
||||
#[test]
|
||||
fn parse_valid_address() {
|
||||
let hex_str = "00".repeat(32); // 64 hex chars = 32 bytes
|
||||
let addr: Address = hex_str.parse().unwrap();
|
||||
assert_eq!(addr.value, [0u8; 32]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_invalid_hex() {
|
||||
let hex_str = "zz".repeat(32); // invalid hex chars
|
||||
let result = hex_str.parse::<Address>().unwrap_err();
|
||||
assert!(matches!(result, AddressError::InvalidHex(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_wrong_length_short() {
|
||||
let hex_str = "00".repeat(31); // 62 chars = 31 bytes
|
||||
let result = hex_str.parse::<Address>().unwrap_err();
|
||||
assert!(matches!(result, AddressError::InvalidLength(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_wrong_length_long() {
|
||||
let hex_str = "00".repeat(33); // 66 chars = 33 bytes
|
||||
let result = hex_str.parse::<Address>().unwrap_err();
|
||||
assert!(matches!(result, AddressError::InvalidLength(_)));
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn test_account_id_from_address() {
|
||||
// let address: Address = "37".repeat(32).parse().unwrap();
|
||||
// let expected_account_id = AccountId::new([
|
||||
// 93, 223, 66, 245, 78, 230, 157, 188, 110, 161, 134, 255, 137, 177, 220, 88, 37, 44,
|
||||
// 243, 91, 236, 4, 36, 147, 185, 112, 21, 49, 234, 4, 107, 185,
|
||||
// ]);
|
||||
//
|
||||
// let account_id = AccountId::from(&address);
|
||||
//
|
||||
// assert_eq!(account_id, expected_account_id);
|
||||
// }
|
||||
}
|
||||
@ -6,6 +6,9 @@ pub mod encryption;
|
||||
mod nullifier;
|
||||
pub mod program;
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
pub mod address;
|
||||
|
||||
pub use circuit_io::{PrivacyPreservingCircuitInput, PrivacyPreservingCircuitOutput};
|
||||
pub use commitment::{Commitment, CommitmentSetDigest, MembershipProof, compute_digest_for_path};
|
||||
pub use encryption::{EncryptionScheme, SharedSecretKey};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pub mod address;
|
||||
// pub mod address;
|
||||
pub mod encoding;
|
||||
pub mod error;
|
||||
mod merkle_tree;
|
||||
@ -8,7 +8,7 @@ pub mod public_transaction;
|
||||
mod signature;
|
||||
mod state;
|
||||
|
||||
pub use address::Address;
|
||||
pub use nssa_core::address::Address;
|
||||
pub use nssa_core::account::{Account, AccountId};
|
||||
pub use privacy_preserving_transaction::{
|
||||
PrivacyPreservingTransaction, circuit::execute_and_prove,
|
||||
|
||||
@ -1,14 +1,12 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use nssa_core::{
|
||||
account::{Account, AccountWithMetadata},
|
||||
program::validate_execution,
|
||||
account::{Account, AccountWithMetadata}, address::Address, program::validate_execution
|
||||
};
|
||||
use sha2::{Digest, digest::FixedOutput};
|
||||
|
||||
use crate::{
|
||||
V01State,
|
||||
address::Address,
|
||||
error::NssaError,
|
||||
public_transaction::{Message, WitnessSet},
|
||||
};
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
use nssa_core::address::Address;
|
||||
|
||||
use crate::{PrivateKey, error::NssaError};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@ -27,6 +29,13 @@ impl PublicKey {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&PublicKey> for Address {
|
||||
fn from(value: &PublicKey) -> Self {
|
||||
// TODO: Check specs
|
||||
Self::new(*value.value())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{PublicKey, error::NssaError, signature::bip340_test_vectors};
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
use crate::{
|
||||
address::Address, error::NssaError, merkle_tree::MerkleTree,
|
||||
error::NssaError, merkle_tree::MerkleTree,
|
||||
privacy_preserving_transaction::PrivacyPreservingTransaction, program::Program,
|
||||
public_transaction::PublicTransaction,
|
||||
};
|
||||
use nssa_core::{
|
||||
Commitment, CommitmentSetDigest, MembershipProof, Nullifier,
|
||||
account::Account,
|
||||
program::{DEFAULT_PROGRAM_ID, ProgramId},
|
||||
account::Account, address::Address, program::{ProgramId, DEFAULT_PROGRAM_ID}, Commitment, CommitmentSetDigest, MembershipProof, Nullifier
|
||||
};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user