Installation
What You Install
Hekate ships in two halves: an open-source toolkit of Rust crates you compile against, and a closed prover
cdylib distributed as a signed binary, one per (target, variant) pair.
hekate-prover-sys— the open shim. Safe Rust API over a stable C ABI. Itsbuild.rsresolves the prover cdylib, verifies SHA-256 + Ed25519 + ML-DSA-65 against a pinned manifest, and dynamically links it.hekate-verifier,hekate-program,hekate-core,hekate-math,hekate-gadgets,hekate-sdk— open crates. You authorProgram<F>impls against them. Verification is pure Rust, no cdylib involved.
Verify-only consumers (rollup nodes, light clients, recursive verifiers) depend on hekate-verifier and skip
hekate-prover-sys entirely. No native binary in the dependency tree.
Prove: Program -> hekate_prover_sys::prove(...) -> InnerProof<Block128>
Verify: Program -> HekateVerifier::verify(...) -> bool
The witness rides through the FFI as borrowed column views; the cdylib never copies it. You hold the trace buffers; you free them.
Requirements
- Rust edition 2024, toolchain ≥ 1.87
- Network at first
cargo build— the cdylib is downloaded from the release CDN and cached under~/.cache/hekate-prover-sys/<version>/<variant>/<triple>/. Subsequent builds are offline. - OS matching one of the published targets (see Supported targets)
Dependencies
[dependencies]
hekate-prover-sys = { version = "0.27", features = ["ct", "blake3"] } # omit on verify-only builds
hekate-verifier = "0.27"
hekate-program = "0.27"
hekate-core = "0.27"
hekate-math = "0.6"
hekate-gadgets = "0.27" # only if you use built-in chiplets (Keccak, AES, RAM, ROM, NTT, IntArith, BaseMul, ML-KEM, ML-DSA, …)
hekate-sdk = "0.27" # only if you call the bundle wire-format helpers directly
hekate-prover-sys re-exports nothing the verifier needs. Verify-only builds drop it cleanly.
Variants — pick exactly one
hekate-prover-sys requires exactly one of ct or public. The build fails fast if neither or both are set.
| Feature | Witness data | Performance | Use for |
|---|---|---|---|
ct | Private | Baseline | Any prover touching secrets (PQC, RAM, user data) |
public | Public only | Faster via variable-time table-math | Rollup batch provers, recursive verifiers, public-input-only programs |
public leaks the witness through timing side channels. Never use it on a private witness. The variant
selection is enforced at link time — a ct-feature binary links the ct cdylib; a public-feature binary
links the public cdylib. Mixing is rejected by build.rs.
Hash backend
Pick the one your verifier uses. Default is blake3.
| Feature | Algorithm |
|---|---|
blake3 | BLAKE3 (default) |
sha2 | SHA-256 |
sha3 | SHA-3-256 |
Mismatch between prover and verifier hash backend silently fails verification — they must match.
How the cdylib is resolved at build time
hekate-prover-sys/build.rs walks three sources in order. First hit wins.
HEKATE_PROVER_DYLIB_DIR— absolute path to a directory containinglibhekate_prover_cdylib.{dylib,so}. Skips cache and download. Use this for local development against an unreleased build.- Cache —
~/.cache/hekate-prover-sys/<version>/<variant>/<triple>/<filename>. Override the root withHEKATE_PROVER_CACHE_DIR. - CDN download — HTTPS
GETto the URL pinned inartifacts/manifest.toml, atomic-renamed into the cache.
Every resolved cdylib is verified before linking:
- SHA-256 digest against the manifest
- Ed25519 signature against the publisher's classical pubkey
- ML-DSA-65 signature against the publisher's post-quantum pubkey (NIST FIPS 204, level 3)
Both pubkey PEMs are embedded in the shim's pinned manifest. The build fails loudly on any mismatch — there is
no --insecure flag, no opt-out.
Proving
use Config;
use Block128;
use ;
use ;
let mut config = default;
OsRng.try_fill_bytes.unwrap;
let mut blinding_seed = ;
OsRng.try_fill_bytes.unwrap;
let proof = prove?;
prove returns Result<InnerProof<Block128>, Error>. The cdylib only ever sees Block128 — the type is
monomorphized inside it. The shim builds a bundle for the small payload (program + instance + config +
chiplet defs) and threads the witness columns through as borrowed views; no defensive copies on the witness
path.
Verifying
Verification is pure Rust, no cdylib. The call is identical whether the proof came from hekate-prover-sys,
a peer, or a remote service.
use DefaultHasher;
use Transcript;
use Block128;
use HekateVerifier;
let mut transcript = new;
let ok = verify?;
The transcript label must byte-match the prover's transcript_label. The hash type must match the prover's
DefaultHasher (selected by the blake3 / sha2 / sha3 feature).
Cancellation
CancelToken is a cooperative token allocated on the cdylib side. The prover checks it at sumcheck round
boundaries, Brakedown phase boundaries, and evaluator phase boundaries — granularity is tens to hundreds of
milliseconds. Cancellation is best-effort: a request may run up to one checkpoint before prove returns
Error::Ffi { code: ErrorCode::Cancelled, .. }.
CancelToken is Send + Sync; share it across threads through Arc.
use Arc;
use thread;
use ;
let token = new;
let canceler = ;
let result = prove;
canceler.join.unwrap;
match result
The cdylib never frees witness buffers — even on cancel, the dev's allocations are untouched.
Supported targets
The 0.5.0 release ships these (triple, variant) pairs. Both variants for every triple.
| Target triple | Platform | Artifact extension |
|---|---|---|
aarch64-apple-darwin | macOS, Apple Silicon | .dylib |
aarch64-apple-ios | iOS, ARM64 | .dylib |
aarch64-unknown-linux-gnu | Linux ARM64, glibc | .so |
aarch64-linux-android | Android ARM64 | .so |
See Releases for per-version SHA-256s and download links.
Next Steps
- Your First ZK Program — write a program, generate a proof, verify it
- System Architecture — binary tower fields, Sumcheck, Brakedown, LogUp internals
- Preflight — constraint diagnostics before proving