Skip to content

ft: extend rsk-rust-cli for zk-proofs#28

Open
michojekunle wants to merge 16 commits into
rsksmart:mainfrom
michojekunle:ft-extend-rust-cli-for-zk-proofs
Open

ft: extend rsk-rust-cli for zk-proofs#28
michojekunle wants to merge 16 commits into
rsksmart:mainfrom
michojekunle:ft-extend-rust-cli-for-zk-proofs

Conversation

@michojekunle

@michojekunle michojekunle commented Nov 11, 2025

Copy link
Copy Markdown

This PR introduces Zero-Knowledge (ZK) capabilities to the Rootstock Rust SDK.

It includes a complete ZK framework based on RISC Zero (risc0), a proof-of-concept private voting system, and full CLI tooling for rapid prototyping and verification.

Major Features Added

  • ZK-SNARK Framework (zk-circuits crate)

    • Integrated risc0 for proof generation and verification.
    • Implemented two core circuits:
      • transfer: Validates balance checks without revealing user details.
      • vote: Validates voting logic (choice 0/1) with nullifier derivation for privacy.
  • Robust Cross-Compilation

    • Custom build.rs to reliably compile RISC-V guest code (riscv32im-risc0-zkvm-elf) from host environment.
    • Handles toolchain isolation (via rzup/rustup) and artifact embedding.
  • SDK Extensions & CLI

    • Added zk module to rootstock-wallet for proof orchestration.
    • New CLI commands:
      • cargo run -- zk generate ... → Generate proofs and journals.
      • cargo run -- zk verify ... → Verify proofs locally.
    • Type safety via shared types.rs structs (VoteInputs, VotePublicOutput) for host/guest consistency.
  • Private Voting Demo (demo_voting)

    • End-to-end: Generates local ZK proof of a valid vote.
    • Submits proof + journal to smart contract on RSK Testnet.
    • Includes simulation logic to detect failures (e.g., "Double voting detected") before broadcasting.
    • Optimized for RSK: Handles legacy tx fields (nonce, gas_price) and node tx size limits.
  • Smart Contract (PrivateVoting.sol)

    • Verifies proofs (mocked for MVP).
    • Prevents double voting using nullifiers.
    • ABI-compatible with Rust ZK outputs (fixed 8-byte vs 64-byte padding mismatches).

Technical Challenges Resolved

  • Compilation Hell — Fixed "Invalid Magic Bytes" and miscompilation by manually managing risc0 toolchain in build scripts.
  • ABI Mismatch — Resolved Risc0 compact output causing Solidity decoding reverts; updated guest to EVM-compliant Big-Endian padded words ([u8; 32]).
  • RSK Compatibility — Adjusted tx building for legacy non-EIP-1559 networks and large proof handling.

Documentation Updates

  • Updated README.md with:
    • Prerequisites (rzup toolchain installation).
    • Setup instructions (env vars, faucet links).
    • Step-by-step CLI + demo usage guide.

How Has This Been Tested?

  • Unit Tests

    • cargo test passes for ZK proof generation/verification logic.
  • Integration

    • Deployed contract to RSK Testnet.
    • Ran demo_voting binary successfully.
    • Verified on-chain state updates (vote counts incremented).
    • Confirmed reverts on double-voting attempts.

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • New and existing unit tests pass locally with my changes

Feel free to review, test the demo, or suggest improvements — especially around production proof verification, circuit optimizations, or additional circuits! 🚀

- Integrate `risc0` ZKVM and implement Transfer/Vote circuits.
- Add CLI commands `zk generate/verify` and `demo_voting` binary.
- Resolve cross-compilation target issues in `zk-circuits` build system.
- Ensure ABI compatibility between Rust guest and Solidity contract.
- Add comprehensive documentation and end-to-end testing support.
@michojekunle michojekunle marked this pull request as ready for review December 30, 2025 15:06
@michojekunle

Copy link
Copy Markdown
Author

Hi @ezequiel-rodriguez

My PR is now ready for review.
Please review.

Thank you.

michojekunle and others added 14 commits December 30, 2025 16:15
- Simplified the main function in `src/main.rs` to conditionally run the wallet setup only for non-ZK commands.
- Enhanced error handling in `zk_generate_proof` to include pre-flight validation for transfer and vote inputs.
- Updated `zk_verify_proof` to ensure receipt verification is handled correctly.
- Moved ZK circuit types to a shared `types.rs` file for consistency across host and guest code.
- Added comprehensive integration tests for transfer and vote circuits, covering both happy and error paths.
- Introduced a mock verifier contract for local development and testing.
- Improved build scripts to ensure the RISC Zero toolchain is installed and configured correctly.
- Updated guest binaries to include nonce in transfer inputs for replay protection.
- Enhanced documentation and comments throughout the codebase for clarity.
- Add proposal existence checks in smart contract
- Fix race condition by reading proposalCount directly
- Replace thread_rng with OsRng for better security
- Enforce non-zero randomness in ElGamal encryption
- Zeroize sensitive secrets after proof generation
- Implement gas limit bounds checking
- Add zeroize to clear sensitive data like passwords and private keys from memory
- Directly pass credentials without exposing them in CLI struct types
- Add explicit warning about plaintext API key storage
- Prioritize reading API keys from environment variables
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