Skip to content

ZK proof condition: trustless off-chain data verification #3

@martinjms

Description

@martinjms

Summary

Replace the signed attestation trust model with zero-knowledge proofs for trustless verification of off-chain data. The condition interface stays the same — only the verification method changes from ed25519 signature to groth16 proof.

Current: Signed Attestation (implemented)

Off-chain server → reads chain state → signs attestation → player passes signature on-chain

Trust model: you trust the attestor server.

Future: ZK Proof (this issue)

Off-chain prover → reads chain state → generates ZK proof → player passes proof on-chain

Trust model: trustless — the proof mathematically guarantees the claim is true.

Architecture

Off-chain Prover Service

  1. Reads Sui chain state via GraphQL/gRPC (SSU inventories, balances, etc.)
  2. Runs a ZK circuit that proves the claim (e.g. "player holds ≥100 ore across all SSUs")
  3. Returns the proof bytes to the player's DApp

On-chain Verifier (condition module)

module ef_guard::condition_zk_proof {
    use sui::groth16;
    
    public struct ZkCondition has key, store {
        id: UID,
        verifying_key: vector<u8>,  // groth16 verifying key
        // public inputs defined by the circuit
    }
    
    public fun verify(
        condition: &ZkCondition,
        ctx: &EvalContext,
        proof_bytes: vector<u8>,
        public_inputs: vector<u8>,
    ): ConditionProof {
        let valid = groth16::verify_groth16_proof(
            &condition.verifying_key,
            &public_inputs,
            &proof_bytes,
        );
        assembly_binding::new_condition_proof(object::id(condition), valid)
    }
}

ZK Circuit Examples

Inventory check: "Player owns ≥N units of item type X across all their SSUs"

  • Public inputs: char_game_id, item_type_id, min_quantity
  • Private inputs: list of SSU IDs, inventory contents
  • Proves: sum of quantities across all SSUs ≥ min_quantity

Net worth check: "Player's total asset value exceeds X"

  • Public inputs: char_game_id, min_value
  • Private inputs: all owned items with market prices
  • Proves: total value ≥ min_value

Activity check: "Player has been active in the last N days"

  • Public inputs: char_game_id, min_recent_tx_count, time_window
  • Private inputs: transaction history
  • Proves: tx count in window ≥ threshold

Implementation Plan

  1. Choose a ZK framework — circom/snarkjs (JS-friendly) or Arkworks (Rust, more performant)
  2. Build the circuit — start with the inventory check (simplest useful case)
  3. Build the prover service — reads chain state, runs the circuit, returns proof
  4. Build the on-chain verifiercondition_zk_proof module using sui::groth16
  5. Integrate with DApp — player's browser calls prover API, passes proof in PTB

Dependencies

  • Sui's native groth16 module (already available)
  • A ZK circuit compiler (circom or equivalent)
  • A prover service (can be serverless / edge function)

Notes

  • The condition_attestation module serves as the interim solution
  • Same ConditionProof interface — switching from attestation to ZK is transparent to ef_guard
  • The prover service could be run by anyone (decentralized prover market)
  • EVE Frontier's eve-frontier-proximity-zk-poc repo shows CCP is already exploring ZK for location proofs

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions