refactor: migrate programs to LEZ lez-core-v0.2.0

Bump the LEZ dependency from the `v0.2.0-rc3` tags to the released
`lez-core-v0.2.0` tag across the workspace and all guest manifests. The crate
was renamed upstream, so `nssa_core`/`nssa` now resolve via the `lee_core`/`lee`
packages, and spel-framework points at the `refactor/lez-v020-compat` fork
branch for compatibility.

Adapt the integration tests to the new API surface:

- `NssaError` is now `LeeError` (error variants unchanged).
- Account inputs move from numeric mask vectors (`vec![2, 0, 0]`) to typed
  `InputAccountIdentity` values (e.g. `PrivateUnauthorized { epk, view_tag,
  npk, ssk, identifier }`).
- `ViewingPublicKey::from_scalar` → `from_seed(d, z)`; `AccountId::from(&npk)`
  → `AccountId::for_regular_private_account(&npk, 0)`; ephemeral-key/shared-
  secret setup → `SharedSecretKey::encapsulate_deterministic(...)` with the
  circuit filling the EPK.

Regenerate all guest Cargo.lock files and the workspace lockfile to match.
This commit is contained in:
r4bbit
2026-06-30 15:13:47 +02:00
parent c9fbb626ea
commit c42d4b6c07
28 changed files with 1015 additions and 7896 deletions
+2 -2
View File
@@ -7,8 +7,8 @@ edition = "2021"
workspace = true
[dependencies]
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0" }
amm_core = { path = "core" }
token_core = { path = "../token/core" }
twap_oracle_core = { path = "../twap_oracle/core" }
+2 -2
View File
@@ -7,8 +7,8 @@ edition = "2021"
workspace = true
[dependencies]
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
spel-framework-macros = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework-macros" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
spel-framework-macros = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework-macros" }
token_core = { path = "../../token/core" }
borsh = { version = "1.5", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
+137 -1458
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -56,8 +56,8 @@ name = "amm"
path = "src/bin/amm.rs"
[dependencies]
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
spel-framework = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", package = "lee_core" }
risc0-zkvm = { version = "=3.0.5", default-features = false }
amm_core = { path = "../../core" }
amm_program = { path = "../..", package = "amm_program" }
+1 -1
View File
@@ -7,6 +7,6 @@ edition = "2021"
workspace = true
[dependencies]
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
ata_core = { path = "core" }
token_core = { path = "../token/core" }
+1 -1
View File
@@ -7,7 +7,7 @@ edition = "2021"
workspace = true
[dependencies]
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
borsh = { version = "1.5", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
risc0-zkvm = { version = "=3.0.5", default-features = false }
+123 -1649
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -56,8 +56,8 @@ name = "ata"
path = "src/bin/ata.rs"
[dependencies]
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
spel-framework = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", package = "lee_core" }
risc0-zkvm = { version = "=3.0.5", default-features = false }
# Pin ruint (transitive via risc0-binfmt) below 1.18, which raised its MSRV to
# rustc 1.90. The risc0 guest toolchain ships rustc 1.88, so 1.18+ fails the
+2 -2
View File
@@ -11,8 +11,8 @@ edition = "2021"
[workspace]
[dependencies]
nssa = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
nssa = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", package = "lee" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
twap_oracle_core = { path = "../twap_oracle/core" }
twap-oracle-methods = { path = "../twap_oracle/methods" }
# `prove` exposes `ExecutorImpl`/`Session` (the cycle split); we only execute, never prove.
+1 -1
View File
@@ -8,7 +8,7 @@ workspace = true
[dependencies]
nssa = { workspace = true }
nssa_core = { workspace = true, features = ["host"] }
nssa_core = { workspace = true, features = ["host", "test_utils"] }
amm_core = { workspace = true }
token_core = { workspace = true }
ata_core = { workspace = true }
+22 -21
View File
@@ -8,7 +8,7 @@ use amm_core::{
MINIMUM_LIQUIDITY,
};
use nssa::{
error::NssaError,
error::LeeError,
program_deployment_transaction::{self, ProgramDeploymentTransaction},
public_transaction, PrivateKey, PublicKey, PublicTransaction, V03State,
CLOCK_01_PROGRAM_ACCOUNT_ID,
@@ -1043,7 +1043,7 @@ fn try_execute_new_definition(
state: &mut V03State,
fees: u128,
authorize_user_lp: bool,
) -> Result<(), NssaError> {
) -> Result<(), LeeError> {
let instruction = amm_core::Instruction::NewDefinition {
token_a_amount: Balances::vault_a_init(),
token_b_amount: Balances::vault_b_init(),
@@ -1280,7 +1280,7 @@ fn execute_initialize(state: &mut V03State) {
fn execute_create_price_observations(
state: &mut V03State,
window_duration: u64,
) -> Result<(), NssaError> {
) -> Result<(), LeeError> {
let instruction = amm_core::Instruction::CreatePriceObservations { window_duration };
let message = public_transaction::Message::try_new(
@@ -1306,7 +1306,7 @@ fn execute_create_price_observations(
fn execute_create_oracle_price_account(
state: &mut V03State,
window_duration: u64,
) -> Result<(), NssaError> {
) -> Result<(), LeeError> {
let instruction = amm_core::Instruction::CreateOraclePriceAccount { window_duration };
let message = public_transaction::Message::try_new(
@@ -1421,7 +1421,7 @@ fn execute_update_config(
token_program_id: Option<nssa_core::program::ProgramId>,
twap_oracle_program_id: Option<nssa_core::program::ProgramId>,
new_authority: Option<AccountId>,
) -> Result<(), NssaError> {
) -> Result<(), LeeError> {
let signer_id = AccountId::from(&PublicKey::new_from_private_key(signer));
let instruction = amm_core::Instruction::UpdateConfig {
token_program_id,
@@ -1482,7 +1482,7 @@ fn amm_update_config_rejects_non_admin() {
// user_a is not the admin; even though they sign, the update is rejected and the config is
// left unchanged.
let result = execute_update_config(&mut state, &Keys::user_a(), Some([123u32; 8]), None, None);
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
let config = config_data(&state);
assert_eq!(config.token_program_id, Ids::token_program());
@@ -1500,7 +1500,7 @@ fn amm_update_config_authority_handoff_revokes_old_admin() {
// The original admin can no longer update.
let result = execute_update_config(&mut state, &Keys::admin(), Some([123u32; 8]), None, None);
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
// The new admin can.
execute_update_config(&mut state, &Keys::user_a(), Some([124u32; 8]), None, None).unwrap();
@@ -1609,7 +1609,7 @@ fn amm_create_oracle_price_account_rejects_existing_account() {
// A second creation for the same (pool, window) is rejected and leaves the account intact.
let result = execute_create_oracle_price_account(&mut state, window_duration);
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
assert_eq!(
state.get_account_by_id(Ids::oracle_price_account(window_duration)),
after_first
@@ -1633,7 +1633,7 @@ fn amm_create_price_observations_rejects_existing_account() {
// A second creation for the same (pool, window) is rejected because the observations account
// already exists, and leaves the existing account intact.
let result = execute_create_price_observations(&mut state, window_duration);
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
let feed_after_second = twap_oracle_core::PriceObservations::try_from(
&state
.get_account_by_id(Ids::price_observations(window_duration))
@@ -1653,7 +1653,7 @@ fn amm_create_price_observations_without_current_tick_account_fails() {
state.force_insert_account(Ids::current_tick_account(), Account::default());
let result = execute_create_price_observations(&mut state, window_duration);
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
assert_eq!(
state.get_account_by_id(Ids::price_observations(window_duration)),
Account::default()
@@ -1680,7 +1680,7 @@ fn advance_clock(state: &mut V03State, timestamp: u64) {
/// Calls the TWAP oracle's permissionless `RecordTick` directly (it is not wrapped by the AMM),
/// folding the pool's current tick into its observations ring buffer for the given window.
#[cfg(test)]
fn execute_record_tick(state: &mut V03State, window_duration: u64) -> Result<(), NssaError> {
fn execute_record_tick(state: &mut V03State, window_duration: u64) -> Result<(), LeeError> {
let instruction = twap_oracle_core::Instruction::RecordTick {
price_source_id: Ids::pool_definition(),
window_duration,
@@ -1746,7 +1746,7 @@ fn read_oracle_price(
/// the TWAP from the pool's observations — extrapolating the tail from the current tick — and
/// writes it to the oracle price account.
#[cfg(test)]
fn execute_publish_price(state: &mut V03State, window_duration: u64) -> Result<(), NssaError> {
fn execute_publish_price(state: &mut V03State, window_duration: u64) -> Result<(), LeeError> {
let instruction = twap_oracle_core::Instruction::PublishPrice {
price_source_id: Ids::pool_definition(),
window_duration,
@@ -2276,7 +2276,7 @@ fn amm_new_definition_without_user_lp_authorization_fails() {
let result = try_execute_new_definition(&mut state, Balances::fee_tier(), false);
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
assert_eq!(
state.get_account_by_id(Ids::pool_definition()),
Account::default()
@@ -2317,8 +2317,8 @@ fn amm_new_definition_precreated_user_lp_unsigned_fails() {
state.force_insert_account(Ids::vault_b(), Accounts::vault_b_reinitializable());
let result = try_execute_new_definition(&mut state, Balances::fee_tier(), false);
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
assert_eq!(
state.get_account_by_id(Ids::pool_definition()),
Account::default()
@@ -2380,9 +2380,10 @@ fn amm_new_definition_rejects_unsupported_fee_tier_transaction() {
Accounts::token_lp_definition_reinitializable(),
);
let result = try_execute_new_definition(&mut state, 2, false);
// `user_holding_lp` is signed so the rejection isolates the unsupported fee tier.
let result = try_execute_new_definition(&mut state, 2, true);
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
assert_eq!(
state.get_account_by_id(Ids::pool_definition()),
Accounts::pool_definition_zero_supply_reinitializable()
@@ -2789,7 +2790,7 @@ fn amm_swap_rejects_expired_deadline() {
let tx = PublicTransaction::new(message, witness_set);
assert!(matches!(
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
Err(NssaError::OutOfValidityWindow)
Err(LeeError::OutOfValidityWindow)
));
}
@@ -2832,7 +2833,7 @@ fn amm_swap_exact_output_rejects_expired_deadline() {
let tx = PublicTransaction::new(message, witness_set);
assert!(matches!(
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
Err(NssaError::OutOfValidityWindow)
Err(LeeError::OutOfValidityWindow)
));
}
@@ -2877,7 +2878,7 @@ fn amm_add_liquidity_rejects_expired_deadline() {
let tx = PublicTransaction::new(message, witness_set);
assert!(matches!(
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
Err(NssaError::OutOfValidityWindow)
Err(LeeError::OutOfValidityWindow)
));
}
@@ -2918,7 +2919,7 @@ fn amm_remove_liquidity_rejects_expired_deadline() {
let tx = PublicTransaction::new(message, witness_set);
assert!(matches!(
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
Err(NssaError::OutOfValidityWindow)
Err(LeeError::OutOfValidityWindow)
));
}
@@ -2967,7 +2968,7 @@ fn amm_new_definition_rejects_expired_deadline() {
let tx = PublicTransaction::new(message, witness_set);
assert!(matches!(
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
Err(NssaError::OutOfValidityWindow)
Err(LeeError::OutOfValidityWindow)
));
}
+23 -19
View File
@@ -8,13 +8,12 @@ use nssa::{
},
program::Program,
program_deployment_transaction::{self, ProgramDeploymentTransaction},
public_transaction, EphemeralPublicKey, PrivateKey, PublicKey, PublicTransaction,
SharedSecretKey, V03State,
public_transaction, PrivateKey, PublicKey, PublicTransaction, SharedSecretKey, V03State,
};
use nssa_core::{
account::{Account, AccountId, AccountWithMetadata, Data, Nonce},
encryption::{Scalar, ViewingPublicKey},
NullifierPublicKey, NullifierSecretKey,
encryption::{EphemeralPublicKey, ViewingPublicKey},
EncryptedAccountData, InputAccountIdentity, NullifierPublicKey, NullifierSecretKey,
};
use token_core::{TokenDefinition, TokenHolding};
@@ -511,16 +510,15 @@ fn ata_create_from_private_owner() {
// Private owner key material
let owner_nsk: NullifierSecretKey = [13u8; 32];
let owner_npk = NullifierPublicKey::from(&owner_nsk);
let owner_vsk: Scalar = [31u8; 32];
let owner_vpk = ViewingPublicKey::from_scalar(owner_vsk);
let owner_id = AccountId::from(&owner_npk);
// `ViewingPublicKey::from_seed` needs two 32-byte halves `(d, z)`.
let owner_vpk = ViewingPublicKey::from_seed(&[31u8; 32], &[32u8; 32]);
let owner_id = AccountId::for_regular_private_account(&owner_npk, 0);
// ATA derived from the private owner
let seed = compute_ata_seed(Ids::token_program(), owner_id, Ids::token_definition());
let owner_ata_id = get_associated_token_account_id(&Ids::ata_program(), &seed);
// Pre-states: private uninitialized owner (mask=2), public token definition (mask=0), public
// uninitialized ATA (mask=0)
// Pre-states: private uninitialized owner, public token definition, public uninitialized ATA.
let owner_pre = AccountWithMetadata::new(Account::default(), false, owner_id);
let def_pre = AccountWithMetadata::new(
Accounts::token_definition_init(),
@@ -534,10 +532,8 @@ fn ata_create_from_private_owner() {
};
let instruction_data = Program::serialize_instruction(instruction).unwrap();
// Ephemeral key for encrypting the private owner's post-state
let esk: Scalar = [3u8; 32];
let shared_secret = SharedSecretKey::new(&esk, &owner_vpk);
let epk = EphemeralPublicKey::from_scalar(esk);
// Encapsulate a shared secret against the owner's viewing key; the circuit fills the EPK.
let shared_secret = SharedSecretKey::encapsulate_deterministic(&owner_vpk, &[0u8; 32], 0).0;
let ata_program = Program::new(ata_methods::ATA_ELF.to_vec()).unwrap();
let token_program = Program::new(token_methods::TOKEN_ELF.to_vec()).unwrap();
@@ -549,11 +545,20 @@ fn ata_create_from_private_owner() {
let (output, proof) = execute_and_prove(
vec![owner_pre, def_pre, ata_pre],
instruction_data,
// owner=new private (2), token_definition=public (0), ata=public (0)
vec![2, 0, 0],
vec![(owner_npk, shared_secret)],
vec![], // no NSKs: new private accounts don't require one
vec![None], // no membership proof: owner is being created, not spending
vec![
// owner: new private account, not owned/spent by the caller (no nsk, no proof).
InputAccountIdentity::PrivateUnauthorized {
epk: EphemeralPublicKey(Vec::new()),
view_tag: EncryptedAccountData::compute_view_tag(&owner_npk, &owner_vpk),
npk: owner_npk,
ssk: shared_secret,
identifier: 0,
},
// token_definition: public
InputAccountIdentity::Public,
// ata: public
InputAccountIdentity::Public,
],
&program_with_deps,
)
.unwrap();
@@ -561,7 +566,6 @@ fn ata_create_from_private_owner() {
let message = Message::try_from_circuit_output(
vec![Ids::token_definition(), owner_ata_id],
vec![],
vec![(owner_npk, owner_vpk, epk)],
output,
)
.unwrap();
+93 -82
View File
@@ -1,15 +1,14 @@
use nssa::{
execute_and_prove,
privacy_preserving_transaction::{Message, WitnessSet},
privacy_preserving_transaction::{Message, PrivacyPreservingTransaction, WitnessSet},
program::Program,
program_deployment_transaction::{self, ProgramDeploymentTransaction},
public_transaction, PrivacyPreservingTransaction, PrivateKey, PublicKey, PublicTransaction,
SharedSecretKey, V03State,
public_transaction, PrivateKey, PublicKey, PublicTransaction, SharedSecretKey, V03State,
};
use nssa_core::{
account::{Account, AccountId, AccountWithMetadata, Data, Nonce},
encryption::{EphemeralPublicKey, ViewingPublicKey},
Commitment, NullifierPublicKey, NullifierSecretKey,
Commitment, EncryptedAccountData, InputAccountIdentity, NullifierPublicKey, NullifierSecretKey,
};
use token_core::{TokenDefinition, TokenHolding};
@@ -616,12 +615,14 @@ impl PrivateKeys {
NullifierPublicKey::from(&Self::holder_nsk())
}
fn holder_vsk() -> [u8; 32] {
[73; 32]
// `ViewingPublicKey::from_seed` needs two 32-byte halves `(d, z)`. We reuse the
// legacy viewing scalar as `d` and pick a fixed distinct `z`.
fn holder_vpk() -> ViewingPublicKey {
ViewingPublicKey::from_seed(&[73; 32], &[74; 32])
}
fn holder_vpk() -> ViewingPublicKey {
ViewingPublicKey::from_scalar(Self::holder_vsk())
fn holder_id() -> AccountId {
AccountId::for_regular_private_account(&Self::holder_npk(), 0)
}
fn recipient_nsk() -> NullifierSecretKey {
@@ -632,12 +633,12 @@ impl PrivateKeys {
NullifierPublicKey::from(&Self::recipient_nsk())
}
fn recipient_vsk() -> [u8; 32] {
[48; 32]
fn recipient_vpk() -> ViewingPublicKey {
ViewingPublicKey::from_seed(&[48; 32], &[49; 32])
}
fn recipient_vpk() -> ViewingPublicKey {
ViewingPublicKey::from_scalar(Self::recipient_vsk())
fn recipient_id() -> AccountId {
AccountId::for_regular_private_account(&Self::recipient_npk(), 0)
}
}
@@ -654,13 +655,16 @@ fn shielded_token_transfer(amount: u128, state: &mut V03State) -> Account {
let sender_account = state.get_account_by_id(sender_id);
let sender_nonce = sender_account.nonce;
let sender = AccountWithMetadata::new(sender_account, true, sender_id);
let recipient =
AccountWithMetadata::new(Account::default(), false, &PrivateKeys::recipient_npk());
let recipient_npk = PrivateKeys::recipient_npk();
let recipient_vpk = PrivateKeys::recipient_vpk();
let recipient_id = PrivateKeys::recipient_id();
let esk = [99u8; 32];
let shared_secret = SharedSecretKey::new(&esk, &PrivateKeys::recipient_vpk());
let epk = EphemeralPublicKey::from_scalar(esk);
let sender = AccountWithMetadata::new(sender_account, true, sender_id);
let recipient = AccountWithMetadata::new(Account::default(), false, recipient_id);
// Sender encapsulates a shared secret against the recipient's viewing key. The
// circuit fills the real EPK, so we pass an empty placeholder in the identity.
let shared_secret = SharedSecretKey::encapsulate_deterministic(&recipient_vpk, &[0u8; 32], 0).0;
let instruction = token_core::Instruction::Transfer {
amount_to_transfer: amount,
@@ -668,25 +672,22 @@ fn shielded_token_transfer(amount: u128, state: &mut V03State) -> Account {
let (output, proof) = execute_and_prove(
vec![sender, recipient],
Program::serialize_instruction(instruction).unwrap(),
vec![0, 2],
vec![(PrivateKeys::recipient_npk(), shared_secret)],
vec![],
vec![None],
vec![
InputAccountIdentity::Public,
InputAccountIdentity::PrivateUnauthorized {
epk: EphemeralPublicKey(Vec::new()),
view_tag: EncryptedAccountData::compute_view_tag(&recipient_npk, &recipient_vpk),
npk: recipient_npk,
ssk: shared_secret,
identifier: 0,
},
],
&token_program().into(),
)
.unwrap();
let message = Message::try_from_circuit_output(
vec![sender_id],
vec![sender_nonce],
vec![(
PrivateKeys::recipient_npk(),
PrivateKeys::recipient_vpk(),
epk,
)],
output,
)
.unwrap();
let message =
Message::try_from_circuit_output(vec![sender_id], vec![sender_nonce], output).unwrap();
let witness_set = WitnessSet::for_message(&message, proof, &[&Keys::holder_key()]);
let tx = PrivacyPreservingTransaction::new(message, witness_set);
@@ -701,7 +702,7 @@ fn shielded_token_transfer(amount: u128, state: &mut V03State) -> Account {
definition_id: Ids::token_definition(),
balance: amount,
}),
nonce: Nonce::private_account_nonce_init(&PrivateKeys::recipient_npk()),
nonce: Nonce::private_account_nonce_init(&recipient_id),
}
}
@@ -725,7 +726,7 @@ fn token_shielded_transfer() {
}
);
let recipient_commitment = Commitment::new(&PrivateKeys::recipient_npk(), &recipient_account);
let recipient_commitment = Commitment::new(&PrivateKeys::recipient_id(), &recipient_account);
assert!(state
.get_proof_for_commitment(&recipient_commitment)
.is_some());
@@ -742,22 +743,24 @@ fn token_private_transfer() {
let sender_npk = PrivateKeys::recipient_npk();
let sender_nsk = PrivateKeys::recipient_nsk();
let sender_vpk = PrivateKeys::recipient_vpk();
let sender_id = PrivateKeys::recipient_id();
let new_recipient_npk = PrivateKeys::holder_npk();
let new_recipient_vpk = PrivateKeys::holder_vpk();
let new_recipient_id = PrivateKeys::holder_id();
let sender_commitment = Commitment::new(&sender_npk, &sender_account);
let sender_commitment = Commitment::new(&sender_id, &sender_account);
let membership_proof = state
.get_proof_for_commitment(&sender_commitment)
.expect("sender's commitment must be in the set");
let esk_1 = [11u8; 32];
let shared_secret_1 = SharedSecretKey::new(&esk_1, &sender_vpk);
let epk_1 = EphemeralPublicKey::from_scalar(esk_1);
// Distinct `output_index` per private output keeps the encapsulated secrets reproducible.
let shared_secret_1 = SharedSecretKey::encapsulate_deterministic(&sender_vpk, &[0u8; 32], 0).0;
let shared_secret_2 =
SharedSecretKey::encapsulate_deterministic(&new_recipient_vpk, &[0u8; 32], 1).0;
let esk_2 = [22u8; 32];
let shared_secret_2 = SharedSecretKey::new(&esk_2, &new_recipient_vpk);
let epk_2 = EphemeralPublicKey::from_scalar(esk_2);
let sender_pre = AccountWithMetadata::new(sender_account.clone(), true, &sender_npk);
let new_recipient_pre = AccountWithMetadata::new(Account::default(), false, &new_recipient_npk);
let sender_pre = AccountWithMetadata::new(sender_account.clone(), true, sender_id);
let new_recipient_pre = AccountWithMetadata::new(Account::default(), false, new_recipient_id);
let instruction = token_core::Instruction::Transfer {
amount_to_transfer: transfer_amount,
@@ -765,27 +768,31 @@ fn token_private_transfer() {
let (output, proof) = execute_and_prove(
vec![sender_pre, new_recipient_pre],
Program::serialize_instruction(instruction).unwrap(),
vec![1, 2],
vec![
(sender_npk, shared_secret_1),
(new_recipient_npk, shared_secret_2),
InputAccountIdentity::PrivateAuthorizedUpdate {
epk: EphemeralPublicKey(Vec::new()),
view_tag: EncryptedAccountData::compute_view_tag(&sender_npk, &sender_vpk),
ssk: shared_secret_1,
nsk: sender_nsk,
membership_proof,
identifier: 0,
},
InputAccountIdentity::PrivateUnauthorized {
epk: EphemeralPublicKey(Vec::new()),
view_tag: EncryptedAccountData::compute_view_tag(
&new_recipient_npk,
&new_recipient_vpk,
),
npk: new_recipient_npk,
ssk: shared_secret_2,
identifier: 0,
},
],
vec![sender_nsk],
vec![state.get_proof_for_commitment(&sender_commitment), None],
&token_program().into(),
)
.unwrap();
let message = Message::try_from_circuit_output(
vec![],
vec![],
vec![
(sender_npk, sender_vpk, epk_1),
(new_recipient_npk, new_recipient_vpk, epk_2),
],
output,
)
.unwrap();
let message = Message::try_from_circuit_output(vec![], vec![], output).unwrap();
let witness_set = WitnessSet::for_message(&message, proof, &[]);
let tx = PrivacyPreservingTransaction::new(message, witness_set);
@@ -794,7 +801,7 @@ fn token_private_transfer() {
.unwrap();
let sender_nonce_after =
Nonce::private_account_nonce_init(&sender_npk).private_account_nonce_increment(&sender_nsk);
Nonce::private_account_nonce_init(&sender_id).private_account_nonce_increment(&sender_nsk);
let new_sender_account = Account {
program_owner: Ids::token_program(),
balance: 0,
@@ -805,7 +812,7 @@ fn token_private_transfer() {
nonce: sender_nonce_after,
};
assert!(state
.get_proof_for_commitment(&Commitment::new(&sender_npk, &new_sender_account))
.get_proof_for_commitment(&Commitment::new(&sender_id, &new_sender_account))
.is_some());
let new_recipient_account = Account {
@@ -815,10 +822,10 @@ fn token_private_transfer() {
definition_id: Ids::token_definition(),
balance: transfer_amount,
}),
nonce: Nonce::private_account_nonce_init(&new_recipient_npk),
nonce: Nonce::private_account_nonce_init(&new_recipient_id),
};
assert!(state
.get_proof_for_commitment(&Commitment::new(&new_recipient_npk, &new_recipient_account))
.get_proof_for_commitment(&Commitment::new(&new_recipient_id, &new_recipient_account))
.is_some());
}
@@ -833,20 +840,22 @@ fn token_deshielded_transfer() {
let sender_npk = PrivateKeys::recipient_npk();
let sender_nsk = PrivateKeys::recipient_nsk();
let sender_vpk = PrivateKeys::recipient_vpk();
let sender_id = PrivateKeys::recipient_id();
let public_recipient_id = Ids::recipient();
let sender_commitment = Commitment::new(&sender_npk, &sender_account);
let sender_commitment = Commitment::new(&sender_id, &sender_account);
let membership_proof = state
.get_proof_for_commitment(&sender_commitment)
.expect("sender's commitment must be in the set");
let esk = [55u8; 32];
let shared_secret = SharedSecretKey::new(&esk, &sender_vpk);
let epk = EphemeralPublicKey::from_scalar(esk);
let shared_secret = SharedSecretKey::encapsulate_deterministic(&sender_vpk, &[0u8; 32], 0).0;
let public_recipient_pre = AccountWithMetadata::new(
state.get_account_by_id(public_recipient_id),
false,
public_recipient_id,
);
let sender_pre = AccountWithMetadata::new(sender_account.clone(), true, &sender_npk);
let sender_pre = AccountWithMetadata::new(sender_account.clone(), true, sender_id);
let instruction = token_core::Instruction::Transfer {
amount_to_transfer: deshield_amount,
@@ -854,21 +863,23 @@ fn token_deshielded_transfer() {
let (output, proof) = execute_and_prove(
vec![sender_pre, public_recipient_pre],
Program::serialize_instruction(instruction).unwrap(),
vec![1, 0],
vec![(sender_npk, shared_secret)],
vec![sender_nsk],
vec![state.get_proof_for_commitment(&sender_commitment)],
vec![
InputAccountIdentity::PrivateAuthorizedUpdate {
epk: EphemeralPublicKey(Vec::new()),
view_tag: EncryptedAccountData::compute_view_tag(&sender_npk, &sender_vpk),
ssk: shared_secret,
nsk: sender_nsk,
membership_proof,
identifier: 0,
},
InputAccountIdentity::Public,
],
&token_program().into(),
)
.unwrap();
let message = Message::try_from_circuit_output(
vec![public_recipient_id],
vec![],
vec![(sender_npk, sender_vpk, epk)],
output,
)
.unwrap();
let message =
Message::try_from_circuit_output(vec![public_recipient_id], vec![], output).unwrap();
let witness_set = WitnessSet::for_message(&message, proof, &[]);
let tx = PrivacyPreservingTransaction::new(message, witness_set);
@@ -890,7 +901,7 @@ fn token_deshielded_transfer() {
);
let sender_nonce_after =
Nonce::private_account_nonce_init(&sender_npk).private_account_nonce_increment(&sender_nsk);
Nonce::private_account_nonce_init(&sender_id).private_account_nonce_increment(&sender_nsk);
let new_sender_account = Account {
program_owner: Ids::token_program(),
balance: 0,
@@ -901,6 +912,6 @@ fn token_deshielded_transfer() {
nonce: sender_nonce_after,
};
assert!(state
.get_proof_for_commitment(&Commitment::new(&sender_npk, &new_sender_account))
.get_proof_for_commitment(&Commitment::new(&sender_id, &new_sender_account))
.is_some());
}
+1 -1
View File
@@ -4,6 +4,6 @@ version = "0.1.0"
edition = "2021"
[dependencies]
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
stablecoin_core = { path = "core" }
token_core = { path = "../token/core" }
+2 -2
View File
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
borsh = { version = "1.5", features = ["derive"] }
alloy-primitives = { version = "1", default-features = false }
# Pin ruint (transitive via alloy-primitives) below 1.18, which raised its MSRV to rustc 1.90.
@@ -14,4 +14,4 @@ ruint = { version = "=1.17.0", default-features = false }
serde = { version = "1.0", features = ["derive"] }
twap_oracle_core = { path = "../../twap_oracle/core" }
risc0-zkvm = { version = "=3.0.5", default-features = false }
spel-framework-macros = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework-macros" }
spel-framework-macros = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework-macros" }
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -14,8 +14,8 @@ name = "stablecoin"
path = "src/bin/stablecoin.rs"
[dependencies]
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
spel-framework = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", package = "lee_core" }
risc0-zkvm = { version = "=3.0.5", default-features = false }
twap_oracle_core = { path = "../../../twap_oracle/core" }
stablecoin_core = { path = "../../core" }
+1 -1
View File
@@ -7,5 +7,5 @@ edition = "2021"
workspace = true
[dependencies]
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
token_core = { path = "core" }
+2 -2
View File
@@ -7,7 +7,7 @@ edition = "2021"
workspace = true
[dependencies]
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
spel-framework-macros = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework-macros" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
spel-framework-macros = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework-macros" }
borsh = { version = "1.5", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
+122 -1648
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -56,8 +56,8 @@ name = "token"
path = "src/bin/token.rs"
[dependencies]
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
spel-framework = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", package = "lee_core" }
risc0-zkvm = { version = "=3.0.5", default-features = false }
# Pin ruint (transitive via risc0-binfmt) below 1.18, which raised its MSRV to
# rustc 1.90. The risc0 guest toolchain ships rustc 1.88, so 1.18+ fails the
+2 -2
View File
@@ -4,8 +4,8 @@ version = "0.1.0"
edition = "2021"
[dependencies]
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0" }
twap_oracle_core = { path = "core" }
[lints]
+2 -2
View File
@@ -7,10 +7,10 @@ edition = "2021"
workspace = true
[dependencies]
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
borsh = { version = "1.5", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
spel-framework-macros = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework-macros" }
spel-framework-macros = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework-macros" }
risc0-zkvm = { version = "=3.0.5", default-features = false }
uniswap_v3_math = "0.6.2"
alloy-primitives = { version = "1", default-features = false }
File diff suppressed because it is too large Load Diff
@@ -14,9 +14,9 @@ name = "twap_oracle"
path = "src/bin/twap_oracle.rs"
[dependencies]
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
spel-framework = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", package = "lee_core" }
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0" }
risc0-zkvm = { version = "=3.0.5", default-features = false }
twap_oracle_core = { path = "../../core" }
twap_oracle_program = { path = "../..", package = "twap_oracle_program" }