Skip to content

Solution: LP-0002 Private M-of-N Multisig - #125

Open
edenbd1 wants to merge 3 commits into
logos-co:masterfrom
edenbd1:lp-0002-submission
Open

Solution: LP-0002 Private M-of-N Multisig#125
edenbd1 wants to merge 3 commits into
logos-co:masterfrom
edenbd1:lp-0002-submission

Conversation

@edenbd1

@edenbd1 edenbd1 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

A threshold multisig for LEZ where an approval is unlinkable to the member who
gave it — including to the other members — and the chain records only that the
threshold was met.

What is verified on chain

Each approve declares a ChainedCall to a LEZ-native membership program, so
the privacy circuit composes it with a real env::verify and the sequencer
checks the receipt against the node-pinned PRIVACY_PRESERVING_CIRCUIT_ID. The
member set and the threshold are folded into the PDA address, so neither can be
invented nor lowered — a forged configuration resolves to an address nobody ever
created.

Transactions — a 2-of-3 lifecycle on the current public testnet

Step Transaction
deploy membership_lez fb8eb10f7f394286c109cb6502a1c95294180523f30d06f707fc087a589bea98
deploy multisig_verifier 517efe12a0b592abe4d21a03246866b95c4379483e87af62fd9f26f7b8fe45ff
create_multisig 2930c1db4521b7c0b912278f4025e430704cfb9a7ebfcb5d22c374fd7ce85b70
create_proposal 68d5127e1e5570936f8d78e9a2da4d485562566cd8b7487a59322bf059406978
approve (member A, privacy tx) 41f5bb99346a0bef6aa0c69243473a554b84f0f0ad65e460bbb6890b11644942
approve (member B, privacy tx) ae006465f5f945b8ba2666f28a5357d0a2aab4af05508c9c2811e0101d0ac649
execute b43e46505f571e31d6051f7da43563db605b6a74b90c670da2d3582d53412ecd

Check any of them:

curl -s -X POST https://testnet.lez.logos.co -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"getTransaction","params":["<hash>"]}'

Every hash above links to its page on the block explorer, and all seven render there. The two privacy transactions show as Privacy-Preserving Transaction — which is the part that matters: an approval is on the proving path, not the public one.

The two deployment hashes are SHA256(borsh(bytecode)) of the binaries committed
under artifacts/programs/, so they can be recomputed from the repository
without trusting this table.

The accounts, which are the stronger evidence

Account Address
multisig 4wqJXoEhqqqYknt1s7gHcgBL6pkfwNJDfhbVVeAqwtnX
proposal E11Awng7j59dVft83VVrwftXp41roJPKY5QRMb45Zcoe
approval marker A DaG2Qan1ie5YhEpcti2LMCsvbkYi7WjWxnNKvxiqxi7B
approval marker B FMj5yL8cpcrQzN7xhENHC2vysTrNwbtokPbTYjr98rPt
execution marker CpiuicNDii6uCeMXtjd1W6hek6Vq35HJ7k3mz1Q82Fui

./scripts/verify-onchain.sh reads all five and confirms the verifier program
owns them. Each approval marker exists only because a membership proof was
verified on chain, and nothing in the pair names a member — read them and you
learn the threshold was met, and nothing about who met it.

On the explorer: all seven render. The explorer is a separate index and reaches a transaction later than the sequencer does — measured on this chain at about an hour and three quarters — so a hash submitted minutes ago shows "Transaction not found" there while getTransaction already returns it. That is an indexing delay, not a gap, and it affects anything recent by anyone.

./scripts/check-explorer.py re-measures it by rendering each page in a headless browser with an impossible hash as the control, because the explorer is a WASM application that returns an identical shell for every /transaction/<hash> URL — an indexed transaction and one that cannot exist are byte-identical over curl, so a size or status comparison proves nothing.

Note on versions

The testnet was reset onto a newer chain in August, so everything here was
rebuilt against LEZ v0.2.4 and redeployed. That is also why the repository
vendors SPEL: no published SPEL release builds against a current LEZ, and
vendor/spel/PATCH.md documents every change, how to reproduce the directory,
and when it should be deleted.

Against the criteria

61 tests, CI green on Linux and macOS, including a workflow that runs the whole
lifecycle against a real standalone LEZ sequencer with RISC0_DEV_MODE=0. CU
costs are measured rather than estimated, per instruction and per machine. The
Basecamp module ships as a .lgx with darwin-arm64 and linux-amd64 variants and
was verified loading in Basecamp 0.2.2, not merely built.

Happy to address anything in review.

@github-actions

Copy link
Copy Markdown

✅ Validation passed

A reviewer will assess against the prize criteria.
ℹ️ Solution submission for LP-0002.
ℹ️ Checking repo: https://github.com/edenbd1/lp-0002-private-multisig


Automated check. See solution template and TERMS.

The video is recorded and linked, so the two places that still said it was
outstanding are gone. The security write-up is presented by what the design
defends against rather than by the order in which it was built; every property
and every test it refers to is unchanged.
`lee/state_machine/src/program.rs` does not exist: the file is `program/mod.rs`,
and the split predates the LEZ release this targets, so the path never resolved.
`execution_state.rs:149` sat four lines above the `env::verify` it names; the
call is at 153, and 149-155 brackets it with its comment.

The executor suite is 25 adversarial rejections plus five honest controls, not
28 rejections.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant