mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-05-12 12:49:36 +00:00
docs: drop "wallet" references from nssa crate
Addresses the following review comments: - "I'd keep this crate independent of wallet references" I replaced all with "supplied npk". - Rename request on locals attested_keys/wallet_keys In mask_3_wallet_npk_mismatch_panics the two key sets play distinct roles, one produces the pre_state's account_id (the registered pair) and the other is supplied in private_account_keys as the mismatched npk. Collapsing both to `keys` would be misleading. I renamed to keys_a and keys_b with an inline comment noting which one is the registered one and which one is mismatched.
This commit is contained in:
parent
34f8b6cac8
commit
00cae12d41
@ -68,8 +68,8 @@ pub struct ChainedCall {
|
||||
/// PDA seeds authorized for the callee. For each callee `pre_state`, the outer circuit
|
||||
/// checks whether its `AccountId` matches a public PDA derivation
|
||||
/// `AccountId::from((&caller, seed))` (mask 0) or a private PDA derivation
|
||||
/// `private_pda_account_id(&caller, seed, npk)` (mask 3, where `npk` is the wallet-supplied
|
||||
/// npk for that `pre_state`). Programs stay privacy-agnostic: they emit seeds, the circuit
|
||||
/// `private_pda_account_id(&caller, seed, npk)` (mask 3, where `npk` is the supplied npk
|
||||
/// for that `pre_state`). Programs stay privacy-agnostic: they emit seeds, the circuit
|
||||
/// resolves public vs private based on the `pre_state`'s mask.
|
||||
pub pda_seeds: Vec<PdaSeed>,
|
||||
}
|
||||
@ -123,7 +123,7 @@ pub enum Claim {
|
||||
/// The program requests ownership of the account through a PDA. The `pre_state`'s
|
||||
/// visibility mask selects the derivation formula: mask 0 uses
|
||||
/// `AccountId::from((&program_id, &seed))`, mask 3 uses
|
||||
/// `private_pda_account_id(&program_id, &seed, &npk)` with the wallet-supplied npk for that
|
||||
/// `private_pda_account_id(&program_id, &seed, &npk)` with the supplied npk for that
|
||||
/// `pre_state`. Programs stay privacy-agnostic: they emit a seed, the circuit resolves the
|
||||
/// rest from the mask.
|
||||
Pda(PdaSeed),
|
||||
@ -520,8 +520,8 @@ pub fn private_pda_account_id(
|
||||
///
|
||||
/// Returns only public-form derivations, suitable for contexts where all accounts are public
|
||||
/// (e.g. the public-execution path). The privacy circuit must additionally check each mask-3
|
||||
/// `pre_state` against `private_pda_account_id(caller, seed, npk)` with the wallet-supplied
|
||||
/// npk for that `pre_state`.
|
||||
/// `pre_state` against `private_pda_account_id(caller, seed, npk)` with the supplied npk for
|
||||
/// that `pre_state`.
|
||||
#[must_use]
|
||||
pub fn compute_authorized_pdas(
|
||||
caller_program_id: Option<ProgramId>,
|
||||
|
||||
@ -2315,9 +2315,9 @@ pub mod tests {
|
||||
}
|
||||
|
||||
/// A mask-3 account that no program claims via `Claim::Pda` and no caller authorizes via
|
||||
/// `ChainedCall.pda_seeds` has no binding between its wallet-supplied npk and its
|
||||
/// `account_id`, so the circuit must reject. Here `simple_balance_transfer` emits no claim
|
||||
/// for the second account, leaving position 1 unbound.
|
||||
/// `ChainedCall.pda_seeds` has no binding between its supplied npk and its `account_id`,
|
||||
/// so the circuit must reject. Here `simple_balance_transfer` emits no claim for the
|
||||
/// second account, leaving position 1 unbound.
|
||||
#[test]
|
||||
fn mask_3_without_binding_panics() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
@ -2354,7 +2354,7 @@ pub mod tests {
|
||||
/// reads the npk for that `pre_state` from `private_account_keys` at the `pre_state`'s
|
||||
/// position, derives `AccountId` via `private_pda_account_id(program_id, seed, npk)`, and
|
||||
/// asserts it equals the `pre_state`'s `account_id`. The equality both validates the claim
|
||||
/// and binds the wallet-supplied npk to the `account_id`.
|
||||
/// and binds the supplied npk to the `account_id`.
|
||||
#[test]
|
||||
fn mask_3_private_pda_claim_succeeds() {
|
||||
let program = Program::pda_claimer();
|
||||
@ -2384,29 +2384,31 @@ pub mod tests {
|
||||
assert!(output.public_post_states.is_empty());
|
||||
}
|
||||
|
||||
/// The wallet supplies an npk that does not match the `pre_state`'s `account_id` under
|
||||
/// An npk is supplied that does not match the `pre_state`'s `account_id` under
|
||||
/// `private_pda_account_id(program, claim_seed, npk)`. The claim equality check rejects.
|
||||
#[test]
|
||||
fn mask_3_wallet_npk_mismatch_panics() {
|
||||
// `keys_a` produces the `pre_state`'s `account_id` (the registered pair), `keys_b` is
|
||||
// the mismatched pair supplied in `private_account_keys` for that pre_state.
|
||||
let program = Program::pda_claimer();
|
||||
let attested_keys = test_private_account_keys_1();
|
||||
let wallet_keys = test_private_account_keys_2();
|
||||
let attested_npk = attested_keys.npk();
|
||||
let wallet_npk = wallet_keys.npk();
|
||||
let keys_a = test_private_account_keys_1();
|
||||
let keys_b = test_private_account_keys_2();
|
||||
let npk_a = keys_a.npk();
|
||||
let npk_b = keys_b.npk();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
let shared_secret = SharedSecretKey::new(&[55; 32], &wallet_keys.vpk());
|
||||
let shared_secret = SharedSecretKey::new(&[55; 32], &keys_b.vpk());
|
||||
|
||||
// account_id is derived from `attested_npk`, but the wallet provides `wallet_npk` for
|
||||
// this pre_state. `private_pda_account_id(program, seed, wallet_npk) != account_id`, so
|
||||
// the claim check in the circuit must reject.
|
||||
let account_id = private_pda_account_id(&program.id(), &seed, &attested_npk);
|
||||
// `account_id` is derived from `npk_a`, but `npk_b` is supplied for this pre_state.
|
||||
// `private_pda_account_id(program, seed, npk_b) != account_id`, so the claim check in
|
||||
// the circuit must reject.
|
||||
let account_id = private_pda_account_id(&program.id(), &seed, &npk_a);
|
||||
let pre_state = AccountWithMetadata::new(Account::default(), false, account_id);
|
||||
|
||||
let result = execute_and_prove(
|
||||
vec![pre_state],
|
||||
Program::serialize_instruction(seed).unwrap(),
|
||||
vec![3],
|
||||
vec![(wallet_npk, shared_secret)],
|
||||
vec![(npk_b, shared_secret)],
|
||||
vec![],
|
||||
vec![None],
|
||||
&program.into(),
|
||||
|
||||
@ -187,7 +187,7 @@ impl ExecutionState {
|
||||
// Every mask-3 pre_state must have had its npk bound to its account_id, either via a
|
||||
// `Claim::Pda(seed)` in some program's post_state or via a caller's `pda_seeds` matching
|
||||
// the private derivation. An unbound mask-3 pre_state has no cryptographic link between
|
||||
// the wallet-supplied npk and the account_id, and must be rejected.
|
||||
// the supplied npk and the account_id, and must be rejected.
|
||||
for (pos, &mask) in visibility_mask.iter().enumerate() {
|
||||
if mask == 3 {
|
||||
assert!(
|
||||
@ -575,7 +575,7 @@ fn compute_circuit_output(
|
||||
.unwrap_or_else(|| panic!("Too many private accounts, output index overflow"));
|
||||
}
|
||||
3 => {
|
||||
// Private PDA account. The wallet-supplied npk has already been bound to
|
||||
// Private PDA account. The supplied npk has already been bound to
|
||||
// `pre_state.account_id` upstream in `validate_and_sync_states`, either via a
|
||||
// `Claim::Pda(seed)` match or via a caller `pda_seeds` match, both of which
|
||||
// assert `private_pda_account_id(owner, seed, npk) == account_id`. The post-loop
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user