-
Notifications
You must be signed in to change notification settings - Fork 19
Solution: LP-0016 — Anonymous Forum with Threshold Moderation and Membership Revocation #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
syafiqeil
wants to merge
14
commits into
logos-co:master
Choose a base branch
from
syafiqeil:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+151
−0
Open
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
cc888aa
docs: add submission for LP-0016 Anonymous Forum
syafiqeil fcefd3e
Merge from upstream/master
syafiqeil 4f26ecf
align with the latest changes
syafiqeil 94b6acd
align with the latest changes
syafiqeil 20871c0
docs: add submission for LP-0016 Anonymous Forum
syafiqeil db89be5
align with the latest changes
syafiqeil 74d4e05
Revise video demonstration section in LP-0016
syafiqeil d4d1426
align with the latest change
syafiqeil ac16a1f
Merge remote-tracking branch 'origin/master'
syafiqeil 1bbdb91
Update Basecamp Integration video link
syafiqeil f4a7623
Correct repository section header in LP-0016.md
syafiqeil 39816fe
fix: point repo URL to fork for CI file validation
syafiqeil 45dc37e
fix: update refs to standalone logos-anonymous-forum repo
syafiqeil 8ed9501
ci: re-trigger validation for logos-anonymous-forum
syafiqeil File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| # Solution: LP-0016 — Anonymous Forum with Threshold Moderation and Membership Revocation | ||
|
|
||
| **Submitted by:** Syafiq (Evice Labs) | ||
|
|
||
| ## Summary | ||
|
|
||
| A privacy-preserving forum protocol built on the Logos Execution Zone (LEZ) where members post anonymously via ZK proofs, moderators issue strikes through N-of-M threshold consensus, and K accumulated strikes cryptographically reconstruct the offender's secret key — enabling on-chain slashing and retroactive deanonymization. The deliverable includes a forum-agnostic moderation library (standalone SDK) and a working Logos Basecamp app demonstrating the full lifecycle. | ||
|
|
||
| ## Repository | ||
|
|
||
| - **Main Implementation (On-Chain + SDK):** https://github.com/syafiqeil/logos-anonymous-forum | ||
| - **Implementation PR:** https://github.com/logos-blockchain/logos-execution-zone/pull/465 | ||
| - **Basecamp Core Module (C++ Qt Plugin):** https://github.com/syafiqeil/anonymous_forum_core | ||
| - **Basecamp UI Module (QML):** https://github.com/syafiqeil/anonymous_forum_ui | ||
|
|
||
| ## Approach | ||
|
|
||
| ### Architecture | ||
|
|
||
| The system is split into five components across three repositories: | ||
|
|
||
| 1. **On-chain program** (`programs/membership_registry/`) — A SPEL framework guest program compiled to RISC-V for the RISC Zero ZKVM. Exposes 4 instructions: `initialize_forum`, `register_member`, `verify_post`, and `slash_member`. Each forum instance is identified by a unique `forum_id`, enabling multiple independent instances with different parameters on the same deployment. State is stored in a PDA account derived from `["forum", forum_id]`. | ||
|
|
||
| 2. **ZK membership proof circuit** (`program_methods/guest/src/bin/forum_membership_proof.rs`) — A standalone RISC Zero guest program that proves three properties in zero-knowledge: (a) the poster's commitment exists in the registry Merkle tree, (b) the commitment is not in the revocation list, and (c) the tracing tag was correctly derived from the poster's NSK. The proof reveals only the registry root, tracing tag, and message hash — never the poster's identity. | ||
|
|
||
| 3. **Off-chain moderation library** (`logos_moderation_sdk/`) — A forum-agnostic SDK operating on abstract byte identifiers. Three clients handle the moderation lifecycle: `MemberClient` (post preparation with ECDH-encrypted Shamir shares), `ModeratorClient` (strike issuance with Schnorr-signed certificates), and `SlashAggregator` (two-tier Lagrange reconstruction of NSK). The SDK is compiled to both WASM (for web) and a C-ABI shared library (`liblogos_moderation_sdk.so`) with a `cbindgen`-generated C header for native Basecamp integration. | ||
|
|
||
| 4. **Basecamp core module** (`anonymous_forum_core/`) — A C++ Qt plugin built with `logos-module-builder` that wraps the Rust FFI layer as `Q_INVOKABLE` methods. Published via Qt RemoteObjects IPC, it exposes 12 methods (member, moderator, and aggregator operations) callable from any Logos Basecamp UI module. | ||
|
|
||
| 5. **Basecamp UI module** (`anonymous_forum_ui/`) — A pure QML module built with `mkLogosQmlModule` providing three views: Register (member creation + aggregator setup), Post (anonymous message preparation), and Moderate (strike issuance + NSK reconstruction). All UI operations flow through `logos.callModule("anonymous_forum_core", ...)` via Logos IPC. | ||
|
|
||
| ### Key Design Decisions | ||
|
|
||
| **SPEL framework over raw NSSA.** Existing LEZ programs (token, AMM) use raw `read_nssa_inputs`/`ProgramOutput` because they predate SPEL. We chose SPEL's `#[lez_program]` and `#[instruction]` macros for declarative account constraints (PDA, signer, init, mut) and automatic IDL generation. This aligns with the evolving LEZ ecosystem direction. The alternative — manual NSSA boilerplate — was rejected because it provides no benefit while making the codebase harder to audit and maintain. | ||
|
|
||
| **Per-instance PDA via `forum_id`.** Initially we used a hardcoded PDA seed (`"forum_state"`), which limited deployment to one instance per program. We refactored to `pda = ["forum", forum_id]` so any number of independent forum instances can coexist under a single deployed program. The alternative — deploying separate program binaries per forum — was rejected as wasteful and operationally complex. | ||
|
|
||
| **Two-tier Shamir Secret Sharing.** The member's NSK is the root secret of a degree-(K-1) polynomial. Each post evaluates this polynomial at a unique x-coordinate, producing a per-post secret `s_post`. This `s_post` is then split into N-of-M Shamir shares (Tier 1) distributed to moderators. This two-tier design means an adversary must breach N moderators across K distinct posts — not just N moderators once. | ||
|
|
||
| **ECDH per-moderator encryption.** Each post generates an ephemeral secp256k1 keypair. Shares are encrypted using ECDH shared secrets between the ephemeral private key and each moderator's public key, with SHA-256 domain-separated key derivation. The alternative — broadcasting shares in plaintext — was rejected for obvious confidentiality reasons. Using a group encryption scheme was considered but rejected as unnecessarily complex for the N-of-M threshold already provided by Shamir. | ||
|
|
||
| **Per-member stake tracking.** The initial implementation used aggregate `total_staked`. We migrated to `member_stakes: Vec<([u8; 32], u64)>` to track exact per-member deposits, ensuring slash returns the precise staked amount rather than a hardcoded value. | ||
|
|
||
| ### Why the Logos Stack | ||
|
|
||
| The Logos stack provides three properties essential for this protocol: | ||
|
|
||
| - **Trustless execution (LEZ):** The membership registry runs inside the RISC Zero ZKVM, ensuring that stake accounting, revocation, and slash verification are enforced by mathematical proof — not by trusting a server operator. A centralized alternative could selectively refuse to process slashes or modify stake balances. | ||
|
|
||
| - **Censorship-resistant state (Bedrock L1):** Finalized blocks on the L1 layer guarantee that once a slash transaction is included, it cannot be reverted or censored. A member who has accumulated K strikes cannot prevent their revocation by bribing or pressuring a centralized service. | ||
|
|
||
| - **Decentralized off-chain coordination:** Moderation certificates are exchanged off-chain without on-chain transaction costs for the common path (posting and moderating). On-chain interaction occurs only at the point of revocation — a single slash transaction. Building on a centralized messaging service would introduce a single point of censorship for moderation activity. | ||
|
|
||
| ## Success Criteria Checklist | ||
|
|
||
| ### Functionality | ||
|
|
||
| - [x] **Member registration with stake and anonymous posting:** `register_member` instruction registers a commitment to the Merkle tree and debits the member's balance. `forum_membership_proof` circuit generates a ZK proof of membership. Posts are unlinkable due to per-post random salt in `SHA256(NSK ∥ H(M) ∥ Salt)`. | ||
|
|
||
| - [x] **Retroactive linkability upon slash:** When NSK is exposed via slashing, any observer can recompute `SHA256(NSK_slashed ∥ H(M_i) ∥ Salt_i)` for every historical post and compare against published tracing tags. Documented in `docs/protocol.md` (Theorem 2). | ||
|
|
||
| - [x] **N-of-M moderation certificates:** `ModeratorClient.issue_strike()` produces Schnorr-signed certificates. `SlashAggregator.reconstruct_strike()` requires exactly N valid certificates — fewer are rejected with error `"The number of certificates has not yet reached the N-of-M moderator threshold."`. | ||
|
|
||
| - [x] **K strikes → slash transaction:** `SlashAggregator.reconstruct_nsk()` performs Lagrange interpolation over K strike points to recover the member's NSK. This NSK is submitted on-chain via `slash_member`, which is admin-only. | ||
|
|
||
| - [x] **Slashed commitment rejection:** The ZK circuit asserts `commitment ∉ revoked_commitments` via explicit byte comparison. Slashed members cannot generate valid proofs. | ||
|
|
||
| - [x] **Parameterisable K and N-of-M:** Set at `initialize_forum` time per forum instance. Different instances operate independently with different parameters. | ||
|
|
||
| - [x] **Forum-agnostic moderation library:** `logos_moderation_sdk` operates on `[u8; 32]` identifiers, makes no assumptions about content type, and exposes documented APIs for registration, proof generation, certificate construction, and slash submission. | ||
|
|
||
| - [x] **Working Basecamp app:** Native Logos Basecamp application consisting of a C++ Qt core module (`anonymous_forum_core`) and a QML UI module (`anonymous_forum_ui`). The core module wraps the Rust SDK via C-ABI FFI (`liblogos_moderation_sdk.so`), and the UI communicates with it through `logos.callModule()` over Logos IPC (Qt RemoteObjects). Supports member registration, anonymous posting, moderator login, strike issuance, and NSK reconstruction — all running natively within the Logos Basecamp standalone app via `nix run --impure`. | ||
|
|
||
| - [x] **Two forum instances with different parameters:** Supported via `forum_id`-parameterized PDA accounts. Demonstrated in deployment with different K and N-of-M values. | ||
|
|
||
| ### Usability | ||
|
|
||
| - [x] **Library as importable SDK:** `logos_moderation_sdk` is a standalone Rust crate with `cdylib` and `rlib` targets. Any application can add it as a dependency without modification. | ||
|
|
||
| - [x] **IDL via SPEL framework:** Generated from `#[lez_program]` annotations. Shows 4 instructions, `ForumInstance` account type, and `MerkleTree` type definition. | ||
|
|
||
| ### Reliability | ||
|
|
||
| - [x] **Proof failure handling:** `prepare_post()` increments `post_counter` only after all operations succeed, preventing nullifier consumption on error. ZK proof errors surface via `Result` types. | ||
|
|
||
| - [x] **Partial certificate rejection:** `SlashAggregator` enforces the N threshold client-side before reconstruction. Insufficient certificates return an explicit error. | ||
|
|
||
| - [x] **Transient failure handling:** The SDK design supports retry by separating post preparation (idempotent per counter value) from network submission. The Basecamp app queues operations client-side. | ||
|
|
||
| ### Performance | ||
|
|
||
| - [x] **ZK proof generation:** ~98 seconds on Intel i7-6600U (2C/4T, 2015 Skylake). Expected <10 seconds on modern 8+ core hardware (Apple M-series, AMD Ryzen 7) due to RISC Zero's parallel proving architecture. | ||
|
|
||
| - [x] **CU cost documentation:** Registration and slash transactions execute in <30ms on the LEZ sequencer (observed: 26.5ms for deploy, 10.9ms for subsequent transactions). Exact CU counts visible in sequencer logs during deployment. | ||
|
|
||
| ### Supportability | ||
|
|
||
| - [x] **Deployed on LEZ:** Programs deployed to local LEZ sequencer via `wallet deploy-program`. Block creation and transaction validation confirmed in sequencer logs. | ||
|
|
||
| - [x] **Integration tests:** `integration_tests/tests/forum.rs` covers the full lifecycle: initialization, registration, ZK proof generation, N-of-M moderation with 3 strikes, NSK reconstruction, and slashing with stake confiscation. Runs with both `RISC0_DEV_MODE=1` (1.3s) and `RISC0_DEV_MODE=0` (98s). | ||
|
|
||
| - [x] **README:** `README.md` in `logos-anonymous-forum` documents build instructions, program architecture, API usage, and step-by-step demo instructions. | ||
|
|
||
| - [x] **Reproducible demo:** `demo.sh` script and integration test suite. Build via `cargo build --release`. Test command: `./demo.sh`. | ||
|
|
||
| - [x] **Video demo:** Narrated walkthrough covering architecture explanation, code highlights, IDL generation, E2E test with `RISC0_DEV_MODE=0` (real proofs), LEZ local deployment with bedrock/sequencer/indexer, and Basecamp app demonstration of the full moderation lifecycle. | ||
|
|
||
| - [x] **Native Basecamp module integration:** The forum operates as a first-class Logos Basecamp module: Rust SDK → C FFI (cbindgen) → C++ Qt plugin (logos-module-builder) → QML UI (mkLogosQmlModule). Verified end-to-end via standalone app with all method calls dispatched through Logos IPC. | ||
|
|
||
| ## Supporting Materials | ||
|
|
||
| - **Video Demonstration (SDK + On-Chain):** https://youtu.be/Bj0GwITfYwM | ||
| - **Video Demonstration (Basecamp Integration):** https://youtu.be/_9RvF-oS7jM | ||
| - **Protocol Specification Document:** Found within the PR at `docs/protocol.md`. | ||
|
|
||
| ## FURPS Self-Assessment | ||
|
|
||
| ### Functionality | ||
|
|
||
| The program supports the complete anonymous forum lifecycle: forum creation with configurable parameters, member registration with stake, anonymous posting via ZK membership proofs, threshold moderation with N-of-M certificate construction, K-strike accumulation, on-chain slashing with stake confiscation, and post-revocation rejection. Each forum instance operates independently via unique `forum_id` identifiers. The `verify_post` instruction maintains tracing tag uniqueness to prevent replay attacks. | ||
|
|
||
| **Limitations:** The `member_stakes` field uses `Vec<([u8; 32], u64)>` which scales linearly. For production use with thousands of members, this should be migrated to a Merkle map or separate PDA accounts per member. | ||
|
|
||
| ### Usability | ||
|
|
||
| The moderation library exposes three client types (`MemberClient`, `ModeratorClient`, `SlashAggregator`) with straightforward APIs. WASM bindings enable browser-based usage, while the C-ABI FFI layer (`liblogos_moderation_sdk.so` + `cbindgen` header) enables native integration with Logos Basecamp. The Basecamp app — built as a native C++ Qt core module and QML UI module — provides a visual interface for all core actions: member registration, anonymous posting, moderator login, strike issuance, and NSK reconstruction. The entire stack runs via `nix run --impure` with zero manual setup. The IDL generated via SPEL allows any tooling built on the SPEL ecosystem to interact with the program. | ||
|
|
||
| ### Reliability | ||
|
|
||
| Error handling follows Rust idioms with `Result` types throughout. The SDK enforces invariants client-side: duplicate registrations are rejected, partial certificates (< N) cannot be submitted, tracing tag replay is blocked, double-slashing returns an error, and invalid NSK submissions are caught before state mutation. Post counter increments are deferred until all cryptographic operations succeed. | ||
|
|
||
| ### Performance | ||
|
|
||
| ZK proof generation is the primary bottleneck (~98s on i7-6600U). All other operations complete in milliseconds. On-chain transactions execute in <30ms on the LEZ sequencer. The moderation SDK operates entirely in-memory with no I/O overhead. WASM bindings add negligible overhead for browser usage. | ||
|
|
||
| ### Supportability | ||
|
|
||
| The codebase is organized across three repositories with clear separation: `logos-anonymous-forum` contains the on-chain programs (`programs/membership_registry`), ZKVM binaries (`program_methods/guest`), and the off-chain Rust SDK (`logos_moderation_sdk` with FFI layer). `anonymous_forum_core` contains the C++ Qt plugin built with `logos-module-builder`. `anonymous_forum_ui` contains the QML interface built with `mkLogosQmlModule`. Formal protocol specification is provided in `docs/protocol.md`, including the Basecamp integration architecture (Section 5). Nix flakes are used for deterministic Basecamp module builds. The E2E integration test (with ZK proofs) runs within the LEZ workspace environment. | ||
|
|
||
| ## Supporting Materials | ||
|
|
||
| - **Protocol specification:** `docs/protocol.md` — formal unlinkability proofs, retroactive deanonymization analysis, N-of-M trust model, two-tier collusion resistance, and Basecamp integration architecture (Section 5) | ||
| - **Architecture audit:** Comparison of SPEL-based approach vs native NSSA programs | ||
| - **IDL:** Generated via `spel generate-idl` — 4 instructions, ForumInstance account type | ||
| - **Video demo:** Narrated architecture walkthrough + E2E test with RISC0_DEV_MODE=0 + LEZ deployment + Basecamp app demonstration | ||
| - **README:** `README.md` in `logos-anonymous-forum` — comprehensive build and usage instructions (covers all 3 repositories) | ||
| - **Basecamp module READMEs:** `anonymous_forum_core/README.md` and `anonymous_forum_ui/README.md` — API reference, build/run instructions, architecture diagrams | ||
|
|
||
| ## Terms & Conditions | ||
|
|
||
| By submitting this solution, I confirm that I have read and agree to the [Terms & Conditions](../TERMS.md). | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback @jzaki! You're right. The initial submission incorrectly added code directly to the LEZ repo. I initially structured it within the LEZ workspace assuming that was the expected approach for SPEL-base programs.
I've since decoupled the project into a standalone repository (logos-anonymous-forum: https://github.com/syafiqeil/logos-anonymous-forum), which references LEZ as a git dependency rather than modifying it. The ## Repository section has been updated accordingly.
The standalone repo contains:
The original LEZ PR (#465) is kept for reference but is no longer the primary implementation link.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain if this is/isn't a logos module? How can a user use this within Logos Basecamp, and via what qt ui plugin/module?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is a Logos module, split into two Basecamp modules following the core/UI architecture:
To run within Basecamp:
cd anonymous_forum_ui nix run --impureThis launches a standalone Basecamp app with both modules loaded, demonstrating the full moderation lifecycle.
Video demo of the Basecamp integration: https://youtu.be/_9RvF-oS7jM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The metadata.json module configs are in their respective repos:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@syafiqeil Does the video have audio? I can't here anything. Please msg me on the discord, might be easier to cover some points on a call
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate the offer @jzaki. But as a non native english speaker (indonesian), I'm much more effective communicating in writing than speaking. I hope that's okay.
Apologies about the audio, if narration text is not enough, I'll check and fix that.
If there are specific points that need clarification or anything misaligned with lp-0016 requirements, I'm happy to address them in detail here. Please let me know what needs attention and I'll respond thoroughly.