Skip to content

Shake256 demo using R0#13

Open
moudyellaz wants to merge 24 commits into
mainfrom
risc0/shake256
Open

Shake256 demo using R0#13
moudyellaz wants to merge 24 commits into
mainfrom
risc0/shake256

Conversation

@moudyellaz
Copy link
Copy Markdown
Collaborator

@moudyellaz moudyellaz commented Aug 12, 2025

🎯 Purpose

This PR adds a minimal end-to-end SHAKE256 XOR-encryption demo on RISC Zero.

⚙️ Approach

This demo proves the correct execution of a simple stream encryption built from SHAKE256. We derive an encryption key with an NSSA-style KDF (SHA-256 over domain-separated inputs), then use SHAKE256 to expand that key + context info into a keystream and XOR it with the plaintext.

Note: this is encryption-only (no MAC); don’t use in production without integrity/authentication. Also, never reuse the same (key, info) pair for two different messages.

Flow

  • Guest (inside zkVM) — methods/guest/src/main.rs

    1. Reads EncInput from the zkVM environment:

      • ss_bytes: [u8; 32]
      • epk_bytes: Vec<u8> (33 bytes expected)
      • ipk_bytes: Vec<u8> (33 bytes expected)
      • commitment: [u8; 32]
      • out_index: u32
    2. Builds info = epk_bytes || ipk_bytes || commitment.

    3. Derives k_enc = SHA256("NSSA/v0.1/KDF-SHA256" || ss || epk || ipk || commitment || out_index_le).

    4. Runs SHAKE256 over a domain string + k_enc + info to get a keystream, XORs with the demo plaintext, and commits the ciphertext to the journal.

  • Host / Prover — src/main.rs

    • Builds an ExecutorEnv with EncInput and invokes default_prover().prove(env, GUEST_ELF).

    • Receives a receipt containing:

      • The journal (ciphertext)
      • A proof that the journal came from running this exact guest image (bound by image ID) on the provided inputs.
  • Verifier — src/main.rs

    • Anyone can call receipt.verify(GUEST_ID).
    • Succeeds only if the proof is valid and the guest image matches GUEST_ID.

Why this matters

  • XOR with a SHAKE256 keystream is straightforward; the difficult part is trust.
  • The RISC Zero receipt lets third parties trust the result was produced by the approved guest on the claimed inputs, without re-running it.

Files

  • methods/guest/src/main.rs — guest logic (#[entry] function), KDF + SHAKE256 XOR
  • src/lib.rs — shared types (EncInput), KDF / SHAKE helpers (host-side re-exports)
  • src/main.rs — host runner (prove + verify + read journal)
  • build.rs — emits methods.rs (guest image bindings)
  • Cargo.toml (guest) — tiny-keccak with features = ["shake"]

Notes / Gotchas

  • We use tiny-keccak’s Shake (features = ["shake"]) on the guest side.
  • For SHA-256 we use sha2. Where both Digest and Update are in scope, we disambiguate with sha2::Digest::update(...).
  • Journal access uses the current API: receipt.receipt.journal.bytes is a field (use .clone()/to_vec() as needed).

🧪 How to Run

From repo root:

# Build and run the demo
cargo clean -p shake256-demo
cargo build -p shake256-demo
cargo run -p shake256-demo --release

Output (example): the host prints the ciphertext hex and verifies the receipt against GUEST_ID.

🔗 Dependencies

  • The encryption section in NSSA v0.1 specs.

  • Guest Cargo.toml requires:

    tiny-keccak = { version = "2", default-features = false, features = ["shake"] }
    sha2 = "0.10"

🔜 Future Work

  • Add tests.
  • Benchmark proving time; add cargo bench.
  • CI job for cargo test + example run.

📋 PR Completion Checklist

  • Complete PR description.
  • Implement core functionality (KDF + SHAKE256 keystream + XOR).
  • Add/update documentation and inline comments.
  • Tests.

@moudyellaz moudyellaz requested review from Pravdyvy and schouhy August 13, 2025 07:29
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