Skip to content

Latest commit

 

History

History
113 lines (89 loc) · 5.83 KB

File metadata and controls

113 lines (89 loc) · 5.83 KB

LP-0002 Security Model

Threat model for the private M-of-N multisig on the Logos Execution Zone (LEZ v0.2.0).

1. Trusted setup

What is trusted. LEZ uses RISC0's STARK-to-SNARK pipeline (Groth16 over BN254 for the outer succinct proof). The BN254 Groth16 parameters were generated by the RISC0 team in a multi-party ceremony; transcript and instructions at https://github.com/risc0/risc0. If the ceremony is compromised (a trapdoor is known), an adversary can forge proofs.

Scope. The multisig logic (threshold check, nullifier set, rider binding, state serialization) runs inside the LEZ zkVM. A ceremony compromise would allow forging any LEZ proof — this is not specific to this multisig, which adds no additional trusted setup beyond what LEZ requires.

2. Membership-set privacy under chain analysis

What observers see. The multisig account is program-owned. Votes arrive as privacy-preserving transactions. Each vote transaction exposes:

  • The multisig account ID (public; it is the governance target).
  • A nullifier (one per member per proposal, derived as SHA256("multisig/v1/vote" || nsk || proposal_id || multisig_id)).
  • One private-account commitment rotation (the member's voting account riding the LEZ privacy circuit) — indistinguishable from any private transfer's commitment/nullifier pair on-chain.
  • The updated multisig state: vote count increments, nullifier added. The registered commitment set is visible.

What is hidden. Which member voted. The nsk never leaves the client; the vote instruction (including the nsk and member index) is private initial-call data. The nullifier cannot be linked to a registered commitment without knowing the nsk, and the rider's rotated commitment cannot be linked to a specific voting account without the account keys.

Chain analysis risk. The voting account is dedicated (identifier 0 under the member's key tree) and funded by a shielded transfer, so it has no public transaction graph. Residual correlation vectors: timing (a vote lands shortly after a member comes online) and RPC-level metadata. Mitigations: (a) add jitter between proposal publication and voting; (b) route submissions through Tor or a proxy; (c) fund the voting account well before any vote.

Member set size. For small N (e.g., 2-of-3), the anonymity set is at most N. An adversary who knows which members did not vote can narrow it down. This is inherent to small-N multisig; full anonymity requires larger N.

3. Sequencer adversary

Threat. A malicious or compromised sequencer could:

  • Censor vote transactions (drop them): the proposal never reaches threshold.
  • Reorder votes (no security impact: votes are idempotent once their nullifier is spent).
  • Attempt to replay a nullifier across a fork: rejected, because the nullifier set is part of the on-chain state committed in each block.

Mitigations. LEZ is designed for multiple sequencers and forced-inclusion paths; until deployed, a censored member can retry through an alternative RPC endpoint. There is no sequencer-level secret that can forge a vote — proof generation is entirely client-side.

4. Nullifier unlinkability

SHA256("multisig/v1/vote" || nsk || proposal_id || multisig_id) has:

  • Binding: one nullifier per (member, proposal, multisig) triple. Re-voting with the same nsk reproduces the same nullifier and is rejected in-circuit (ERR_6004).
  • Hiding: without the nsk, the nullifier is a uniformly random 32-byte value; linking it to a commitment SHA256("member" || nsk || multisig_id) requires a SHA256 preimage.
  • Cross-proposal independence: nullifiers for different proposals are independent — a vote on proposal A reveals nothing about proposal B.
  • Cross-multisig independence: multisig_id is mixed in, so the same nsk in two deployments produces unrelated nullifiers.

Known limitation: SHA256 anonymity arguments are random-oracle-model; a production system with tighter requirements could use an audited ZK-native hash (e.g. Poseidon). On RISC0, SHA256 is hardware-accelerated in-circuit, which keeps vote proofs small and fast.

5. Live-account rider binding

A vote must ride the member's LIVE shielded voting account. In-circuit, the program asserts:

  1. rider.account_id == AccountId::for_regular_private_account(npk(nsk), 0) — the rider is derived from the SAME secret as the membership commitment (ERR_6012 otherwise);
  2. rider.account != Account::default() — the account exists on chain (ERR_6013 otherwise).

The LEZ privacy circuit additionally proves the rider's pre-state commitment is a member of the live commitment tree and derives its account-update nullifier from the same nsk, so a vote cannot be fabricated for an account the voter does not control, and cannot be cast at all without controlling a live shielded account enrolled in the member set. A bug in the LEZ privacy circuit's commitment-membership proof would weaken this binding; that circuit is LEZ core protocol and outside this program's audit scope.

6. Known limitations

Limitation Impact Status
SHA256 (not Poseidon) for commitments/nullifiers Random-oracle assumption; no security break Accepted for v1 (RISC0-accelerated)
Small anonymity set for small N Members can be narrowed down by exclusion Inherent to M-of-N; documented
Member set fixed at initialization Adding/removing members requires a new multisig instance Planned: membership-rotation instruction
No forced-inclusion path (sequencer dependency) Votes can be censored LEZ protocol work; out of scope
Trusted setup (RISC0 ceremony) Ceremony compromise allows proof forgery External dependency
execute finalizes action bytes (parameter change), no chained call into a target program Downstream programs must read the executed action from multisig state v2 roadmap: chained-call execution