Phase 1.5 Release on Bitcoin Cash: CTv1 Amount Envelope, Sigma64 Range Proof, and a CashVM-Shaped Pool Hash Fold (chipnet)
Phase 1.5 is live.
This milestone tightens the “confidential assets” prototype into something much closer to a real confidential-transaction building block: we now have a concrete amount envelope format, a deterministic off-chain range proof implementation, and (crucially) a working covenant pattern that looks like the direction BCH is headed in 2026 (bounded loops, functions, introspection).
If you want the code-level details, here’s the merge PR:
This post is the higher-level “what changed and why it matters” version, plus how it leads into Phase 2 and Phase 3.
The destination (what we’re building toward)
The long-term goal is simple to say and hard to build:
Make Bitcoin Cash payments feel like cash: observers shouldn’t learn who paid whom or how much — while the network still enforces no inflation, no double-spend, and authorization.
That implies two big outcomes:
- confidential identities (who can authorize/spend without revealing a static identity), and
- confidential amounts (hidden values, with enforced conservation and range constraints),
with on-chain verifiability (the chain still enforces correctness).
We’re tackling this in phases because the end-state isn’t a single feature — it’s a system.
Quick recap: what Phase 1 proved
Phase 1 was the “prove the shape” milestone: an end-to-end confidential-asset flow that closes the loop on chipnet.
In the basic demo:
- Alice funds a covenant output carrying a CashTokens NFT (“note”), plus a BCH amount
- Bob spends the covenant and returns the NFT + amount to an RPA/paycode-derived one-time address
- Alice spends the one-time output back to her base wallet
Phase 1 wasn’t “perfect privacy.” It was validating constraints that matter:
- no oracles and no custodians,
- ordinary-looking outputs (no obvious marker outputs required),
- and a clean off-chain handoff where the recipient learns what they need to spend.
What Phase 1.5 adds (the two big upgrades)
Phase 1.5 adds two building blocks that we’ll need no matter what proof system we ultimately pick later:
- a concrete “amount envelope” format plus a real range proof implementation (Sigma64), and
- a CashVM-shaped covenant that updates state via a bounded loop + functions + introspection (a rehearsal for how proof blobs will be handled on-chain).
1) CTv1 “amount envelope” + Sigma64 range proof (deterministic regeneration)
Phase 1.5 introduces a concrete CTv1 envelope format and a Sigma64 range proof implementation that can be regenerated deterministically from:
seed = sha256(ephemPub33 || uint64le(amount))
In plain terms:
- the envelope carries proof bytes plus just enough context to bind it to the right place, and
- the proof can be reproduced deterministically (given the same ephemeral pubkey and amount), which is useful for testing, reproducibility, and wallet restoration workflows.
The envelope includes:
- the core proof bytes
- contextual binding fields (for example: asset ID, outIndex, extraCtx)
Then we bind everything into the on-chain objects in two places:
- the Pedersen commitment point
Cis embedded into the CashTokens NFT commitment, and proofHash(envelope)is bound into the covenant, so an on-chain spend implies a consistent envelope.
Why this matters:
- the receiver can verify off-chain that the note they received matches the on-chain NFT commitment and the claimed amount, without any oracle.
- we’ve moved from “hand-wavy CT talk” to explicit formats and real binding points.
- we’re already treating “proofs” the right way architecturally: opaque bytes + public inputs, with stable hashing conventions.
This still isn’t “confidential amounts enforced on-chain” — but it’s a real, measurable step toward that end-state.
2) Pool Hash Fold covenant: a minimal “state update” contract (CashVM-shaped)
BCH is a UTXO chain. That means “contract state” needs to live inside UTXOs (not in a global storage slot).
To practice the covenant style that future on-chain verifiers will need, Phase 1.5 adds a tiny contract that updates an NFT commitment via a hash fold:
acc0 = oldCommit
for limb in stackItems:
acc = HASH256(acc || limb)
This does two important things for the roadmap:
- It demonstrates state carried in an NFT commitment (a portable “state baton”).
- It demonstrates loop/function-driven processing of arbitrary unlock data (the same structural pattern that parsing proof blobs will require).
v1.1: chipnet-introspective (the important upgrade)
The v1.1 script moves from “trust the spender to provide old/new commitments” to deriving both commitments by introspection:
- old commitment comes from the input NFT commitment (
OP_UTXOTOKENCOMMITMENT) - new commitment is required to match output[0] NFT commitment (
OP_OUTPUTTOKENCOMMITMENT)
The fold itself is implemented with:
- a function (
OP_DEFINE/OP_INVOKE) - a bounded loop (
OP_BEGIN/OP_UNTIL)
This ran successfully on chipnet and updates the NFT commitment to the computed fold value, end-to-end.
Why this matters:
- introspection makes the covenant stricter and more “self-contained.”
- and we now have a working example of the exact covenant architecture we’ll want when we start hosting verification logic on-chain later.
Why Phase 1.5 is a real milestone (not just “more code”)
Phase 1.5 is a convergence point:
- We now have an amount-related proof artifact with a defined format and deterministic regeneration.
- We have real binding points into both the token commitment and the covenant.
- And we have a working state update covenant pattern that looks like how future “verifier-host” covenants will be structured.
That’s a big deal because the scary part of privacy engineering isn’t just the cryptography — it’s getting the on-chain/off-chain boundary right, making the binding unambiguous, and making the covenant logic auditable and bounded.
Where this goes next: Phase 2 and Phase 3 (the ladder)
We’re climbing a pragmatic ladder toward full confidential transactions on BCH L1:
- Phase 1: confidential delivery (paycodes/RPA) + covenant-locked assets (CashTokens) with proof hash bound on-chain
- Phase 1.5 (this release): CTv1 amount envelope + deterministic off-chain range proof (Sigma64) bound into token commitment + covenant; plus a CashVM-shaped minimal covenant that proves the loop/function/introspection skeleton works on chipnet
- Phase 2 (next): replace “revealed key + signature” with a ZK identity proof; make covenants ZK-aware; stabilize public inputs + transcript hashing + bounded parsing so proof backends can plug in safely
- Phase 3 (later): full confidential transactions: logical amounts live only in commitments; proofs enforce conservation + range constraints (eventually on-chain)
If you squint, the path is clear:
- we can already bind opaque proof blobs to real on-chain commitments,
- we can already write covenants in the “CashVM-shaped” style we’ll need for verifiers,
- next is making identity proofs real, then making conservation proofs real.
Closing
Phase 1 proved we can deliver private notes without beacons, using paycodes and RPA.
Phase 1.5 proves we can bind an off-chain proof artifact into an on-chain covenant and token commitment — and that a CashVM-style covenant skeleton works on chipnet.
Now we’re ready for Phase 2: making the demo community-runnable and turning “proofs as opaque blobs” into a stable, ZK-aware interface that can later host real on-chain verification.
If you’re following along, reviewing, or thinking about contributing, Phase 1.5 is the foundation that makes the next steps concrete.
Donate
If you’d like to support more of this kind of research and engineering, you can send a tip in Bitcoin Cash.
Scan to donate in Bitcoin Cash
bitcoincash:qr399w3awgzgf86520tajj9qjsf8jnwtmurfp9gymc
Every bit helps carve out time for the unglamorous parts of this work: writing specs, tightening scripts, building reference implementations, and iterating toward a privacy stack that’s actually deployable in wallets instead of just living in whitepapers.