You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Design and implement a first-class, typed contract for verifying externally
generated zero-knowledge proofs in CellScript CKB artifacts.
The proposed boundary is deliberately narrower than "add ZK to the language":
proving and circuit execution remain off chain;
scheme-specific cryptography remains in a separately built, reviewed, and
hash-bound CKB RISC-V verifier;
CellScript owns the security-critical composition layer: verifier identity,
verification-key identity, canonical proof/public-input codecs, public-input
binding to the CKB state transition, bounded Spawn/IPC execution, ProofPlan
coverage, builder contracts, and evidence.
CellScript should not become a circuit DSL, a finite-field language, or an
on-chain prover. The product goal is to make a ZK-backed state transition as
auditable and fail-closed as an ordinary typed CellScript transition.
This issue is an RFC/design candidate, not a release commitment. The active nightly-0.26 bounded consensus-runtime work should remain scoped to its
current Cell-group and output-correspondence closure while Phase 0 of this issue
can proceed independently.
Why this belongs at the language and artifact boundary
CKB is a crypto-agnostic RISC-V verification platform. Its design explicitly
supports deploying new cryptographic primitives, including zkSNARKs and
zkSTARKs, as ordinary VM code rather than protocol precompiles. CKB-VM v2 also
identifies zero-knowledge verification as a performance motivation and adds
isolated child execution through Spawn.
CellScript already has most of the generic substrate:
typed transaction and Script Group views;
fixed-width values and bounded witness/runtime contracts;
spawn, pipe, wait, and file-descriptor flow checking;
ckb::require_cell_data_hash for runtime CellDep preflight;
a frozen BIP340 verifier CellDep ABI as one concrete external-verifier path;
ProofPlan evidence tiers and strict production gates;
verified lowering records, source maps, and a standalone artifact checker;
Registry runtime_verifier artifacts with TCB consumption mode;
builder, CKB-VM, stateful, deployment, and chain evidence kept distinct.
What is missing is a generic semantic contract connecting those pieces. An
author can manually spawn a verifier today, but the compiler cannot answer:
Which exact verifier binary and ABI were intended?
Which verification key and circuit/statement identity were used?
What is the canonical proof and public-input encoding?
Which public input binds the proof to the consumed Cells, proposed output
Cells, current action, current Script, and replay domain?
Was the verifier result actually checked on every accepting path?
Are proof size, public-input size, process count, memory, and cycles bounded?
Can the independent checker connect the source-level claim to the final
CellDep preflight, IPC envelope, Spawn/Wait path, and rejecting branch?
Those are language, artifact, and builder questions rather than elliptic-curve
implementation questions.
Current gap
The BIP340 path proves that a fixed external-verifier ABI can be made
executable and fail-closed, but it is intentionally scheme-specific:
the source namespace is verifier::btc::bip340;
the type checker fixes one message/key/signature shape;
codegen constructs one 144-byte NovaSeal envelope;
a literal CellDep index is required for the explicit form;
Generic Spawn/IPC is lower level still. It exposes process and descriptor
mechanics, but not a typed cryptographic statement. Treating raw spawn() as
"ZK support" would leave the most dangerous bindings invisible to interfaces,
ProofPlan, strict production checks, generated builders, and artifact review.
There is also a terminology hazard: CellScript ProofPlan is an audit and
enforcement plan for compiler obligations. It is not a cryptographic proof.
The proposed metadata and documentation must keep ProofPlan and ZkProof
unambiguously separate.
Design principles
Exact profile first. Ship one exact verifier/profile contract before any
open scheme registry or compatibility-based dispatch.
No ambient verifier authority. A source name or Registry coordinate is
not authority. On-chain execution must bind the resolved CellDep bytes.
Typed statement, opaque proof. CellScript understands the statement
schema and source bindings, but does not interpret proof internals.
Canonical encoding only. No free-form bytes, implicit field reduction,
alternative endianness, ignored trailing data, or permissive decoding.
No inferred security context. The compiler never infers replay,
authorization, or state-transition bindings from action/field names.
Bound every runtime dimension. Proof length, public-input length,
statement field count, verifier processes, IPC bytes, memory profile, and
measured cycles need explicit limits.
Fail closed before codegen when incomplete. A production build with a
missing verifier, key, codec, statement binding, or executable ProofPlan
record must stop before ASM/ELF generation.
Separate evidence levels. Structural checker acceptance, CKB-VM
execution, builder dry-run, deployment identity, and live-chain acceptance
must never collapse into one verified flag.
No privacy overclaim. Verifying a succinct proof does not by itself
establish that the circuit, prover, setup, or application provides a
specific zero-knowledge/privacy property.
An accepted design may place the verifier declaration in Cell.toml and emit a
typed source handle instead of adding a top-level block. The non-negotiable
contract is the information and evidence, not the syntax.
optionally VerifiedStatement<Statement, Profile>: an ephemeral,
non-serializable, non-escaping value produced only by the generated
fail-closed verifier path.
ZkProof is not a Cell-backed resource and grants no lifecycle capability.
Copy/borrow behavior should be conservative and driven by its bounded byte
representation. VerifiedStatement must not be constructible, serializable,
stored in a Cell, accepted from a witness, or preserved across an entry.
The RFC must decide whether require_valid returns Unit and directly
discharges a named ProofPlan obligation, or returns VerifiedStatement for
explicit flow-sensitive discharge. A boolean-returning API is not sufficient
because ignoring the result must be impossible.
Verifier identity contract
The first production-capable path must bind one exact verifier contract:
verifier_contract_id = H(
verifier-profile ID and version
|| IPC ABI ID and version
|| exact RISC-V executable/data hash
|| target and CKB-VM profile
|| verification-key commitment
|| statement/public-input schema hash
|| proof and public-input codec IDs
|| declared runtime limits
)
The exact canonical hashing profile must be specified and versioned rather than
copied from this illustrative formula.
Source code refers to a stable policy name. Package metadata declares the
required identity. Deployment records resolve that policy to a network-specific
outpoint. The builder places the dependency at a resolved index, and the parent
Script verifies the selected code/data identity before Spawn.
Required rules:
a Registry package name is discovery metadata, not consensus authority;
a raw CellDep index is not a verifier identity;
data_hash, type_hash, Type ID, and outpoint policies remain distinct;
DepGroup resolution must bind the actual spawned member, not merely the
container name;
a verification key supplied solely by witness cannot define the accepted
verifier contract;
unknown profiles, ABI versions, codec versions, or reserved flags reject.
This work should update or supersede the existing draft named-CellDep RFC rather
than introducing a ZK-only positional binding.
Public-input and replay binding
The central security property is not merely "the proof verifies." It is:
The exact reviewed verifier accepted a canonical proof for the exact typed
statement that authorizes this exact CKB state transition and context.
The compiler cannot guess a universally correct statement. It can require that
the selected verifier profile explicitly declares and fills its binding classes:
Binding class
Examples
Required behavior
application domain
protocol/version/domain tag
fixed or manifest-bound, never witness-selected by default
verifier/circuit identity
profile, VK/circuit commitment
part of the verifier contract
current verifier context
current Script hash, Lock/Type role, action ID
typed source with explicit codec
consumed state
input Cell data hash, typed state commitment, outpoint/nonce
Not every profile needs every field, but every omitted class must be explicit in
metadata and justified by the use case. The production gate should reject a
profile whose mandatory binding classes are unresolved.
Public inputs require:
a versioned schema hash;
deterministic field order and exact widths;
explicit integer endianness and range checks;
strict canonical field-element encoding with no implicit modular reduction;
exact handling of optional/list fields with compile-time or runtime bounds;
no ignored trailing bytes or duplicate aliases;
source-span and expression-origin retention for every field;
one evaluation of state-producing expressions before serialization;
shared vectors across compiler, builder, child verifier, simulator, CKB-VM,
and independent checker fixtures.
The transport envelope may use Molecule while scheme-specific scalar encodings
remain registered sub-codecs. The documentation must not call an ad hoc packed
field encoding "Molecule."
Canonical Spawn/IPC verifier ABI
Phase 0 must specify a bounded cellscript-zk-ipc-v1 request. At minimum, the
strict Molecule envelope should bind:
magic and ABI version;
verifier-profile ID/hash;
statement schema hash;
verification-key commitment;
flags, all reserved bits required to be zero;
proof codec ID and exact proof byte length;
public-input codec ID and exact public-input byte length/count;
The ABI must define maximum byte and element counts before decoding. Unknown
fields/versions, noncanonical Molecule offsets, truncated reads, extra bytes,
overflowing counts, partial pipe operations, wrong descriptor direction,
double close, unclosed descriptors, Spawn failure, child rejection, Wait
failure, or scheduler deadlock all reject with stable parent runtime errors.
The parent must:
validate and materialize all bounded sources;
verify the exact named CellDep identity;
create the pipe and child with explicit descriptor ownership;
write the complete canonical envelope;
close the writer;
wait for the exact child PID;
accept only child exit code 0;
reject every failure path before allowing the protected transition path to
return success.
The first version should spawn at most one child per verifier call and impose a
small compile-time bound on verifier calls per entry. Batch or recursive proof
verification is a later profile, not an implicit loop over witness data.
ProofPlan, typed semantics, and independent checking
Add a dedicated category such as cryptographic-verifier-call, not a generic require record. Each record should contain:
entry/origin/source span;
exact verifier-contract identity;
profile, ABI, proof codec, public-input codec, and VK commitment;
proof source, witness placement, and byte bound;
statement schema and every public-input source binding;
application domain and replay-policy declarations;
named CellDep policy and resolved-index requirement;
Spawn/IPC process, descriptor, byte, and memory limits;
stable runtime-error mapping;
generated lowering helper/block identities;
codegen coverage and final ELF ranges;
evidence tier and unresolved assumptions;
measured/allowed cycle evidence and fixture identities.
checked-runtime is allowed only when the selected entry's lowering contains
the exact verifier preflight, canonical request construction, Spawn/Wait path,
and rejection branch. A declaration without that executable path remains runtime-helper-required or metadata-only and must fail production gates.
The standalone artifact checker should validate bounded structural properties:
metadata, typed semantics, lowering, source map, and ELF identities agree;
the verifier-call block is reachable from the entry;
required preflight, IPC, Spawn, Wait, and rejection edges are present;
declared request sizes and stack ranges are respected;
the checked child result dominates every accepting continuation that claims
the verifier evidence;
mutation of verifier identity, VK hash, statement hash, source binding,
request length, call edge, branch, or runtime error is rejected.
The checker must not claim cryptographic implementation correctness, circuit
correctness, zero knowledge, trusted-setup integrity, or complete
source-to-machine semantic equivalence.
Builder and prover boundary
The compiler should emit a versioned prover/builder contract containing:
statement schema and canonical public-input vectors;
proof codec and maximum size;
verifier/VK/circuit identities;
exact witness placement;
named CellDep/deployment requirements;
transaction roles used to derive each public input;
required dry-run and resource evidence.
An off-chain adapter may invoke an external prover SDK, but the core compiler
must not contain proving keys or execute untrusted prover plugins during normal
compilation. Prover integrations require explicit process/tool boundaries,
input/output size limits, pinned versions, and reproducible statement vectors.
Generated builders should recompute the public inputs from the candidate
transaction, compare them with prover output, place the proof, resolve the exact
verifier CellDep, then dry-run the final serialized transaction. Builder success
is still not consensus evidence; the on-chain parent and child checks remain
authoritative.
For multi-Script protocols, #9ProtocolBundle should carry the verifier role,
statement inputs, witness ownership, CellDep resolution, and per-Script cycle
evidence without merging trust boundaries.
Registry may later add hash-bound circuit, proving-key, verification-key, or
setup-transcript artifact roles. Registry presence or an audited label must
not be treated as on-chain identity or proof of cryptographic soundness.
Resource and performance contract
CKB charges cycles for ordinary RISC-V cryptography, and Spawn has explicit
process/VM limits. Scheme selection therefore requires measurement, not a
language-design assumption.
Every admitted profile should declare and test:
maximum proof bytes;
maximum public-input count and bytes;
maximum verification-key bytes loaded by the child;
maximum IPC bytes and calls;
parent stack/scratch use;
child memory configuration;
maximum verifier calls and live processes per entry;
valid worst-case, invalid worst-case, and malformed-input cycles;
total transaction size and occupied-capacity effects;
the exact CKB/CKB-VM version used for evidence.
Phase 0 should benchmark real RISC-V implementations of candidate systems such
as Groth16, PLONK-family, STARK-family, or zkVM receipts without preselecting a
winner. Admission criteria include strict decoding, no_std/RISC-V portability,
determinism, reproducible builds, acceptable license, test vectors, auditability,
and bounded CKB-VM resources. Only one profile should advance first.
Threat model and adversarial matrix
Case
Expected result
valid proof, exact verifier/VK, exact state transition
pass
invalid proof
stable child rejection
valid proof for different public inputs
reject
public inputs reordered or re-encoded
reject
noncanonical field element or implicit modular reduction
reject
proof truncated, oversized, or contains trailing bytes
reject
public-input count/bytes exceed declared bound
reject before/inside child with stable error
same proof replayed for another action or Script
reject when the profile claims those bindings
old state bound correctly but proposed output omitted or changed
reject
correct state roots but wrong nonce/nullifier/replay domain
reject
verifier CellDep index points to different bytes
parent preflight rejects
correct Registry package name but wrong on-chain CellDep
reject
matching DepGroup container but wrong resolved verifier member
reject
valid verifier binary with wrong VK/circuit
reject
compatible name/version but unapproved verifier upgrade
reject
verification key selected solely from witness
production rejection unless independently committed by the exact profile
child exits nonzero or Wait uses wrong PID
reject
partial write/read, descriptor misuse, or deadlock
stable fail-closed error
verifier result computed but ignored on one branch
compiler/checker rejection
metadata claims checked-runtime but ELF call/branch is removed
standalone checker rejection
valid fast proof but malformed input takes excessive cycles
profile rejected until bounded/measured
proof is sound but circuit omits an application rule
outside compiler proof; profile/security review must state the gap
Implementation phases
Phase 0 — use case, threat model, benchmarks, and RFC
select one concrete primary use case, such as a rollup/state-root transition,
privacy-preserving credential spend, or cross-chain validity proof;
specify the exact statement and replay bindings for that use case;
benchmark candidate verifier implementations in the pinned CKB-VM;
choose one exact initial profile;
specify verifier/VK/circuit identity, codecs, IPC, bounds, errors, upgrades,
and evidence;
add opaque bounded proof and typed statement representations;
add the canonical bounded IPC envelope and generated fail-closed call path;
add typed-semantics, ProofPlan, lowering-record, source-map, and checker
schemas;
add stable errors and FD/process/resource validation;
use a deliberately simple deterministic test verifier to exercise the
infrastructure without making a ZK security claim;
complete parser/formatter/type/IR/codegen/LSP/VS Code/Playground-summary/docs
closure for the admitted surface.
Phase 2 — first real ZK verifier profile
pin one reproducible, reviewed RISC-V verifier implementation;
pin the exact verification key, circuit/statement identity, ABI, codecs, and
runtime limits;
add canonical upstream and CellScript-owned positive/negative vectors;
add real CKB-VM and stateful transaction fixtures;
measure cycles, memory, transaction bytes, witness bytes, and capacity;
add generated builder plus one bounded external prover adapter;
independently review the verifier TCB and the parent statement-binding path;
keep deployment and chain evidence separate from local CKB-VM results.
Only after this phase may documentation describe the selected profile as an
executable ZK verification path.
Phase 3 — composition and ecosystem closure
integrate with ProtocolBundle and multi-Script transaction roles;
add Registry artifact roles only where identity/evidence contracts justify
them;
add CI/release gates for reproducible verifier builds and pinning;
publish SDK vectors and audit templates;
evaluate batched or additional verifier profiles only from measured demand.
Completion criteria
An accepted RFC defines the first use case, exact scheme/profile, verifier
identity, VK/circuit identity, statement, replay policy, codecs, ABI,
resource limits, errors, and upgrade policy.
The source/manifest model uses a named exact verifier dependency, not a
bare positional authority.
Proofs are opaque and bounded; public inputs are typed and canonically
encoded.
Every public input retains its source expression/span through typed
semantics, ProofPlan, lowering, and checker records.
Invalid, ignored, or partially checked verifier results cannot reach a
successful entry return.
Production compilation rejects missing verifier identity, VK identity,
statement binding, executable coverage, or resource bounds before
codegen.
The verifier and parent artifacts build reproducibly with pinned hashes.
Summary
Design and implement a first-class, typed contract for verifying externally
generated zero-knowledge proofs in CellScript CKB artifacts.
The proposed boundary is deliberately narrower than "add ZK to the language":
hash-bound CKB RISC-V verifier;
verification-key identity, canonical proof/public-input codecs, public-input
binding to the CKB state transition, bounded Spawn/IPC execution, ProofPlan
coverage, builder contracts, and evidence.
CellScript should not become a circuit DSL, a finite-field language, or an
on-chain prover. The product goal is to make a ZK-backed state transition as
auditable and fail-closed as an ordinary typed CellScript transition.
This issue is an RFC/design candidate, not a release commitment. The active
nightly-0.26bounded consensus-runtime work should remain scoped to itscurrent Cell-group and output-correspondence closure while Phase 0 of this issue
can proceed independently.
Why this belongs at the language and artifact boundary
CKB is a crypto-agnostic RISC-V verification platform. Its design explicitly
supports deploying new cryptographic primitives, including zkSNARKs and
zkSTARKs, as ordinary VM code rather than protocol precompiles. CKB-VM v2 also
identifies zero-knowledge verification as a performance motivation and adds
isolated child execution through Spawn.
CellScript already has most of the generic substrate:
spawn,pipe,wait, and file-descriptor flow checking;ckb::require_cell_data_hashfor runtime CellDep preflight;runtime_verifierartifacts with TCB consumption mode;What is missing is a generic semantic contract connecting those pieces. An
author can manually spawn a verifier today, but the compiler cannot answer:
Cells, current action, current Script, and replay domain?
CellDep preflight, IPC envelope, Spawn/Wait path, and rejecting branch?
Those are language, artifact, and builder questions rather than elliptic-curve
implementation questions.
Current gap
The BIP340 path proves that a fixed external-verifier ABI can be made
executable and fail-closed, but it is intentionally scheme-specific:
verifier::btc::bip340;binding remain application responsibilities.
Generic Spawn/IPC is lower level still. It exposes process and descriptor
mechanics, but not a typed cryptographic statement. Treating raw
spawn()as"ZK support" would leave the most dangerous bindings invisible to interfaces,
ProofPlan, strict production checks, generated builders, and artifact review.
There is also a terminology hazard: CellScript
ProofPlanis an audit andenforcement plan for compiler obligations. It is not a cryptographic proof.
The proposed metadata and documentation must keep
ProofPlanandZkProofunambiguously separate.
Design principles
open scheme registry or compatibility-based dispatch.
not authority. On-chain execution must bind the resolved CellDep bytes.
schema and source bindings, but does not interpret proof internals.
alternative endianness, ignored trailing data, or permissive decoding.
authorization, or state-transition bindings from action/field names.
statement field count, verifier processes, IPC bytes, memory profile, and
measured cycles need explicit limits.
missing verifier, key, codec, statement binding, or executable ProofPlan
record must stop before ASM/ELF generation.
execution, builder dry-run, deployment identity, and live-chain acceptance
must never collapse into one
verifiedflag.establish that the circuit, prover, setup, or application provides a
specific zero-knowledge/privacy property.
Target architecture
flowchart LR OLD["Input Cells / old state"] --> STMT["Typed public-input constructor"] NEW["Output Cells / new state"] --> STMT CTX["action + Script + replay context"] --> STMT WIT["Bounded proof witness"] --> PARENT["CellScript parent artifact"] STMT --> PARENT HANDLE["Exact verifier handle\nABI + ELF hash + VK hash"] --> PARENT PARENT --> PREFLIGHT["Resolve named CellDep\nand check exact identity"] PREFLIGHT --> IPC["Canonical bounded Molecule IPC request"] IPC --> CHILD["Isolated CKB-VM verifier child"] CHILD --> RESULT{"exit 0?"} RESULT -- "no / syscall failure" --> REJECT["Stable fail-closed runtime error"] RESULT -- "yes" --> TOKEN["Checked-runtime verifier evidence"] TOKEN --> TRANSITION["Permit the declared transition path"] META["Typed semantics + ProofPlan + lowering + source map"] --> CHECKER["Standalone structural checker"] PARENT --> METAThe child verifier owns scheme-specific cryptography. The parent owns exact
identity, statement construction, CKB source selection, bounded transport, and
result enforcement.
Proposed source model
The final spelling requires an accepted RFC. This strawman illustrates the
semantic information; it does not preselect parser syntax:
An accepted design may place the verifier declaration in
Cell.tomland emit atyped source handle instead of adding a top-level block. The non-negotiable
contract is the information and evidence, not the syntax.
Required nominal types
The first version should model at least:
ZkProof<Statement, Profile>: opaque, bounded transaction evidence;ZkPublicInputs<Statement, Profile>or a registered ordinary struct whosecanonical public-input codec is part of its identity;
VerificationKeyCommitment<Profile>: exact fixed-width commitment, never anuntrusted witness-selected authority;
VerifierHandle<Interface>: exact verifier artifact/deployment/ABI binding,aligned with [Language/ABI] Bind runtime Script values to verified package interfaces #11 rather than a second handle system;
VerifiedStatement<Statement, Profile>: an ephemeral,non-serializable, non-escaping value produced only by the generated
fail-closed verifier path.
ZkProofis not a Cell-backed resource and grants no lifecycle capability.Copy/borrow behavior should be conservative and driven by its bounded byte
representation.
VerifiedStatementmust not be constructible, serializable,stored in a Cell, accepted from a witness, or preserved across an entry.
The RFC must decide whether
require_validreturnsUnitand directlydischarges a named ProofPlan obligation, or returns
VerifiedStatementforexplicit flow-sensitive discharge. A boolean-returning API is not sufficient
because ignoring the result must be impossible.
Verifier identity contract
The first production-capable path must bind one exact verifier contract:
The exact canonical hashing profile must be specified and versioned rather than
copied from this illustrative formula.
Source code refers to a stable policy name. Package metadata declares the
required identity. Deployment records resolve that policy to a network-specific
outpoint. The builder places the dependency at a resolved index, and the parent
Script verifies the selected code/data identity before Spawn.
Required rules:
data_hash,type_hash, Type ID, and outpoint policies remain distinct;container name;
verifier contract;
[Language/ABI] Bind runtime Script values to verified package interfaces #11; exact hash-bound deployment ships first;
This work should update or supersede the existing draft named-CellDep RFC rather
than introducing a ZK-only positional binding.
Public-input and replay binding
The central security property is not merely "the proof verifies." It is:
The compiler cannot guess a universally correct statement. It can require that
the selected verifier profile explicitly declares and fills its binding classes:
Not every profile needs every field, but every omitted class must be explicit in
metadata and justified by the use case. The production gate should reject a
profile whose mandatory binding classes are unresolved.
Public inputs require:
and independent checker fixtures.
The transport envelope may use Molecule while scheme-specific scalar encodings
remain registered sub-codecs. The documentation must not call an ad hoc packed
field encoding "Molecule."
Canonical Spawn/IPC verifier ABI
Phase 0 must specify a bounded
cellscript-zk-ipc-v1request. At minimum, thestrict Molecule envelope should bind:
The ABI must define maximum byte and element counts before decoding. Unknown
fields/versions, noncanonical Molecule offsets, truncated reads, extra bytes,
overflowing counts, partial pipe operations, wrong descriptor direction,
double close, unclosed descriptors, Spawn failure, child rejection, Wait
failure, or scheduler deadlock all reject with stable parent runtime errors.
The parent must:
0;return success.
The first version should spawn at most one child per verifier call and impose a
small compile-time bound on verifier calls per entry. Batch or recursive proof
verification is a later profile, not an implicit loop over witness data.
ProofPlan, typed semantics, and independent checking
Add a dedicated category such as
cryptographic-verifier-call, not a genericrequirerecord. Each record should contain:checked-runtimeis allowed only when the selected entry's lowering containsthe exact verifier preflight, canonical request construction, Spawn/Wait path,
and rejection branch. A declaration without that executable path remains
runtime-helper-requiredormetadata-onlyand must fail production gates.The standalone artifact checker should validate bounded structural properties:
the verifier evidence;
request length, call edge, branch, or runtime error is rejected.
The checker must not claim cryptographic implementation correctness, circuit
correctness, zero knowledge, trusted-setup integrity, or complete
source-to-machine semantic equivalence.
Builder and prover boundary
The compiler should emit a versioned prover/builder contract containing:
An off-chain adapter may invoke an external prover SDK, but the core compiler
must not contain proving keys or execute untrusted prover plugins during normal
compilation. Prover integrations require explicit process/tool boundaries,
input/output size limits, pinned versions, and reproducible statement vectors.
Generated builders should recompute the public inputs from the candidate
transaction, compare them with prover output, place the proof, resolve the exact
verifier CellDep, then dry-run the final serialized transaction. Builder success
is still not consensus evidence; the on-chain parent and child checks remain
authoritative.
For multi-Script protocols, #9
ProtocolBundleshould carry the verifier role,statement inputs, witness ownership, CellDep resolution, and per-Script cycle
evidence without merging trust boundaries.
Registry may later add hash-bound circuit, proving-key, verification-key, or
setup-transcript artifact roles. Registry presence or an
auditedlabel mustnot be treated as on-chain identity or proof of cryptographic soundness.
Resource and performance contract
CKB charges cycles for ordinary RISC-V cryptography, and Spawn has explicit
process/VM limits. Scheme selection therefore requires measurement, not a
language-design assumption.
Every admitted profile should declare and test:
Phase 0 should benchmark real RISC-V implementations of candidate systems such
as Groth16, PLONK-family, STARK-family, or zkVM receipts without preselecting a
winner. Admission criteria include strict decoding, no_std/RISC-V portability,
determinism, reproducible builds, acceptable license, test vectors, auditability,
and bounded CKB-VM resources. Only one profile should advance first.
Threat model and adversarial matrix
Implementation phases
Phase 0 — use case, threat model, benchmarks, and RFC
privacy-preserving credential spend, or cross-chain validity proof;
and evidence;
research, notimplemented.No positive production lowering should land in this phase.
Phase 1 — generic exact-verifier infrastructure
VerifierHandle/named dependency resolution;schemas;
infrastructure without making a ZK security claim;
closure for the admitted surface.
Phase 2 — first real ZK verifier profile
runtime limits;
Only after this phase may documentation describe the selected profile as an
executable ZK verification path.
Phase 3 — composition and ecosystem closure
them;
Completion criteria
identity, VK/circuit identity, statement, replay policy, codecs, ABI,
resource limits, errors, and upgrade policy.
bare positional authority.
encoded.
semantics, ProofPlan, lowering, and checker records.
successful entry return.
statement binding, executable coverage, or resource bounds before
codegen.
control-flow, stack, and result-binding changes.
verifier.
Script, and replay context as specified by the selected use case.
envelopes across supported SDKs.
capacity evidence are recorded with exact environment identity.
builders, Registry profile, docs, website summary, and gates agree.
substitution, codec ambiguity, public-input omission/reordering, replay,
CKB source selection, IPC failure, and resource exhaustion.
structural checker evidence, CKB-VM execution, and chain evidence.
Non-goals
application privacy from successful verification alone;
future verifier upgrades;
nightly-0.26bounded-runtime gates or scope.Dependencies and relationship to existing work
VerifierHandle/artifact-interface binding; thisissue adds the ZK statement, VK, codec, and execution contract.
multi-Script transactions.
success must not be mistaken for peer behavioral equivalence.
committed-substate public inputs.
statements may reference; a proof must not bypass their lifecycle authority.
executable surface until implementation closure is real.
Open RFC decisions
require_validreturnUnitor an ephemeralVerifiedStatement?CellDep, or another committed profile artifact?
represented and gated?
codec?
WitnessArgswithout conflicting with entrywitness and other Script roles?
Spawn limits?
audit evidence packaged without making Registry a consensus dependency?
version?
References