Prove that a JSON field fetched over HTTPS exceeds a threshold — with a zero-knowledge proof. Two paths live in this repo:
- Self-prove (SP1 only) — host captures raw TLS bytes +
esk_client; guest re-verifies the full TLS 1.3 handshake and cert chain inside the zkVM. - Notary + SP1 —
notary_demo+notary_proxyrun split-key 2PC TLS; host exports aTlsWitnessfor the SP1 guest notary path (bundle signature + record commits).
No server modification. Real HTTPS. See INFO.md for crate/module map and
DEMO.md for the notary demo.
| Doc | Purpose |
|---|---|
INFO.md |
Repository guide (crates, modules, crypto) |
DEMO.md |
Notary E2E quick start (modes 0–2) |
ECDH.md |
ECDH wire protocol |
TODO.md |
Engineering backlog |
PROD.md |
Production roadmap |
Phase 1 — Key generation.
The host generates a fresh X25519 ephemeral (esk_client, epk_client). The private key stays
on the host; epk_client is injected into the TLS handshake.
Phase 2 — TLS relay.
The host opens TLS 1.3 using epk_client (host/src/crypto.rs
ExternalKxGroup) and records all raw bytes (host/src/stream.rs
CapturingStream). The host does not pass traffic secrets to the guest.
Phase 3 — Prove.
The host passes esk_client and raw wire bytes to the SP1 guest (guest/src/main.rs).
The guest:
- Parses
epk_clientfromClientHellokey_share - Asserts
epk_client == esk_client × G - Parses
epk_serverfromServerHellokey_share - Computes
shared_secret = X25519(esk_client, epk_server) - Derives TLS 1.3 traffic keys via HKDF-SHA256
- Decrypts handshake records; verifies cert chain (
webpki-roots), hostname,CertificateVerify, ServerFinished - Decrypts application data (AES-128-GCM)
- Asserts
json[field] > threshold - Commits
{ host, field, threshold, value }as public outputs
The host knows esk_client and can derive server_write_key, so a malicious prover could
forge application-data records. This is acceptable when the user runs the prover on their
own machine (they attested their own fetch). Delegated proving requires split keys — see
Path B and PROD.md.
- Run
notary_proxy+notary_demo(mode 2 recommended) — seeDEMO.md. - Export witness:
notary_demo … --witness-out witness.bin --field "/x" --threshold 0 - Prove:
cargo run --release -p sp1-demo-host --bin notarized -- --witness-in witness.bin [--prove]
The guest notary path verifies the Ed25519 bundle, checks record commit hashes, reconstructs
K = K_N ⊕ K_C, decrypts, and runs the JSON claim (no full in-guest cert verify today).
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shcurl -L https://sp1up.succinct.xyz | bash
sp1up
cargo prove --versionFrom repo root (builds guest ELF via host/build.rs on first compile):
cargo build --releaseOr build the guest explicitly:
cd guest && cargo prove buildNotary binaries (separate crate):
cd notary && cargo build --release --bin notary_proxy --bin notary_demo --bin notary_verifycargo run --release -- \
--url "https://blockchain.info/ticker" \
--field "/USD/last" \
--threshold 1000SP1_PROVER=mock cargo run --release -- \
--url "https://blockchain.info/ticker" \
--field "/USD/last" \
--threshold 1000 \
--provecargo run --release -- \
--url "https://blockchain.info/ticker" \
--field "/USD/last" \
--threshold 1000 \
--proveUse SP1_PROVER=mock on smaller machines.
| Flag | Required | Description |
|---|---|---|
--url |
yes | HTTPS URL (TLS 1.3, JSON body) |
--field |
yes | JSON pointer (RFC 6901), e.g. /USD/last |
--threshold |
yes | Guest asserts value > threshold |
--prove |
no | Generate proof (default: execute only) |
| Variable | Effect |
|---|---|
SP1_PROVER=mock |
Mock prover (fast, unsound) |
SP1_SKIP_PROGRAM_BUILD=1 |
Skip guest rebuild (after first build) |
sp1-demo/
├── Cargo.toml # Workspace: guest, host, common (+ SP1 crypto patches)
├── common/src/lib.rs # TlsWitness, NotaryBundle, SessionBinding, PublicClaim
├── guest/src/main.rs # SP1 zkVM program
├── host/
│ ├── src/crypto.rs # ExternalKxGroup (inject epk into rustls)
│ ├── src/stream.rs # CapturingStream
│ ├── src/bin/main.rs # Self-prove CLI
│ └── src/bin/notarized.rs # Witness file → SP1
├── notary/ # 2PC MPC-TLS (not in workspace; swanky deps)
│ ├── src/ # aes, ecdh, hkdf, ghash, garble, tls, …
│ └── src/bin/ # notary_proxy, notary_demo, notary_verify
├── DEMO.md, INFO.md, PROD.md, TODO.md, ECDH.md
└── README.md # this file
| Primitive | Crate | Accelerated |
|---|---|---|
| X25519 | x25519-dalek |
yes (curve25519) |
| SHA-256 | sha2 |
yes |
| P-256 ECDSA | p256 |
yes (patched) |
| RSA | rsa |
yes (patched) |
| AES-128-GCM | aes-gcm |
no (software) |
| P-384 ECDSA | p384 |
no |
Patches: root Cargo.toml [patch.crates-io].
# SP1 workspace
cargo clippy --all-targets -- -D warnings
# Notary (fast suite ~18 s)
cd notary && cargo test --release -p notary --libHeavy WRK17 integration tests are #[ignore] — see TODO.md.