Confidential Transactions

Cash-Like Privacy on Bitcoin Cash

Bitcoin Cash is good at moving value cheaply and directly, but ordinary BCH payments still reveal too much. In most cases, the chain can expose who paid, who received, and how much was sent. That is not how cash works.

The project I’m building is aimed at changing that.

The goal is not just to make BCH payments a little harder to follow. The goal is to build a private payment path that shields both identity and amount while keeping the system self-custodied, enforced by the chain, and usable without trusting a coordinator as part of the base model.

At a high level, the design works like this: the public BCH transaction does not reveal the real amount being transferred. The visible on-chain BCH amount is only the fee required to move the private payment system forward. The real private value is carried inside protected protocol state rather than exposed directly in the visible transaction amount.

That is the privacy model this work is building toward.

The challenge this work is answering

A useful way to understand this project is through a public challenge @bitjson raised late last year: if BCH privacy is going to matter, it should not settle for a privacy-themed wrapper. It should aim for a much harder combination instead — actually zero-knowledge, post-quantum in direction, and compact enough to matter in practice, ideally under 100KB for one-off proofs.

First challenge post:
https://x.com/bitjson/status/1995873869077332056

This project is best understood as one attempt to answer that public challenge on BCH: build a private payment path that is actually zero-knowledge in direction, compact enough to matter, enforced on-chain, and strong enough to support a later optional aggregation market rather than depending on one from the start.

That challenge also aligns with broader public BCH work around more compact covenants, reusable contract factoring, and support for non-trivial cryptographic systems, including zero-knowledge and post-quantum designs. In other words, this is not a random detour. It fits a broader BCH design conversation that is already happening in public.

What this project is building

The current direction is a privacy protocol for BCH where the base path is self-sovereign and direct.

That matters because I do not think BCH privacy should begin with an aggregator as the trust base. Aggregation can still be extremely valuable later. In fact, I think a competitive aggregation market is one of the most interesting future directions for BCH privacy. But the base path should work without making a batching service or coordinator part of the protocol’s core authority.

So the current design starts from the simpler question:

Can BCH support a private payment path where a user can create the private activity themselves, prove what needs to be proved off-chain, and rely on the chain itself to verify and enforce the important transition rules on-chain?

That is the role of the current direct-spend path. It is the base layer first. Aggregation is deferred and treated as an optional later service layer rather than part of the current trust base.

The technical direction in plain language

At a high level, this project is building toward five properties that rarely appear together.

First, actual zero-knowledge direction rather than a system that still leaks too much public meaning.

Second, succinct proofs, because a private system that only works with huge proofs or heavy wallet assumptions is much less useful in practice.

Third, off-chain proving. The expensive proving work should happen outside the chain, where wallets and services can choose how to generate it.

Fourth, on-chain verification. BCH itself should enforce the important rules rather than outsourcing trust to an off-chain party.

Fifth, a post-quantum direction. Ordinary blockchain payments depend heavily on exposed signing-key meaning. This project is moving the meaningful authorization and consistency checks toward a proof-based path that is better aligned with longer-term quantum resilience.

This is also why the compact commitment format matters. A major part of the work is moving the live payment path onto a compact 128-byte commitment carrier. In simple terms, that gives the chain a compact way to carry forward the protected payment state without using the visible BCH amount to reveal the real private transfer amount.

Why BCH is an interesting place to build this

This is not just a generic privacy idea looking for a home.

Bitcoin Cash is an especially interesting place to build this because public BCH design discussions are already moving in the same direction: smaller and more efficient covenants, reusable contract factoring, and better support for non-trivial cryptographic constructions like zero-knowledge and post-quantum systems.

This also aligns with an important practical part of the current work: moving the live payment path onto a compact 128-byte token commitment. In simple terms, that gives BCH a compact on-chain carrier for protected payment state, allowing the system to move private value forward without exposing the real payment amount in the visible BCH transaction amount.

What is already true, and what is not

This project is not yet claiming a finished privacy system.

The current work is best described as a real private-payment base path under active R&D. It is already being developed and validated on Chipnet, and the current effort is about carrying it forward into something that people can run, inspect, and continue advancing toward Mainnet. But this is not yet a broad final claim of a complete deployed privacy system, and it is not yet the later aggregation-market phase.

That truth boundary matters.

This is also why I’m focusing first on a reference wallet and CLI, clear receiver identity surfaces, transparent bootstrap funding only where necessary, and live on-chain validation of the intended path. The job right now is to make the base path real and auditable, not to pretend the full end state already exists.

Why this matters

If BCH privacy is ever going to become more than a niche demo, it needs a real protocol path underneath it.

That path should not just hide the social graph a little better. It should aim to hide both identity and amount. It should be practical enough to use, compact enough to fit BCH constraints, and honest enough to state what is already true versus what is still future work.

That is the direction here.

So this post is the first in a short series leading up to May 15. The goal is to explain, in public and in plain language, what is being built, why BCH is a serious place to build it, and how this work is answering a harder public challenge: bringing cash-like privacy to Bitcoin Cash without giving up self-custody, on-chain enforceability, or the possibility of a later open market for privacy services built on top of something real.

Next post: why this work starts with direct spend first, and treats aggregation as a later optional layer rather than the trust base.

3 Likes

Cash-Like Privacy on Bitcoin Cash: First Explicit Packet-Plane Milestone

TL;DR

A live Chipnet transaction has accepted the first on-chain private-payment packet layout for this BCH confidential transaction protocol.

Txid:

https://chipnet.chaingraph.cash/tx/1fb716d7640fe821589a12389ebf4e2f9ff3d507a0081524f929ea3549054950

The important part: the intended private payment amount was 9,987,000 sats, but the public chain does not show a visible 9,987,000 sat recipient payment. It also does not show an ordinary visible BCH change output.

Instead, the chain shows:

  • one Plane A private state continuation output
  • twelve Plane B recipient recovery packet outputs
  • sender change retained inside the Plane A private state continuation output
  • no ordinary visible BCH change output
  • no fallback to the earlier compact carrier path

This does not mean the full privacy system is finished. It does not yet claim full end-to-end post-quantum privacy, final wallet recovery, or proof-bearing covenant enforcement.

But it is a real on-chain milestone: the intended private-payment layout can now land on Chipnet without falling back to ordinary visible change or the earlier compact carrier path.


What happened

The accepted transaction has 13 outputs:

  • output 0: Plane A private state continuation output
  • outputs 1 through 12: Plane B recipient recovery packet outputs
  • recipient packet profile: ml-kem-768-12x128
  • sender change retained inside the Plane A private state continuation output
  • no ordinary visible BCH change output
  • no fallback to the earlier compact carrier path

The transaction was accepted on Chipnet with a size of 2400 bytes and a 10,000 sat fee.

That matters because the public transaction does not look like an ordinary payment where the recipient amount is visible as a normal BCH output.

What Plane A and Plane B mean

The easiest way to understand the transaction is to split it into two roles.

Plane A is the private state continuation output. In this milestone transaction, output 0 is Plane A. It carries the next private protocol state and retains sender change, avoiding an ordinary visible BCH change output. This is the part of the transaction that keeps the private payment system moving forward without exposing the sender’s remaining value as conventional public change.

Plane B is the recipient recovery packet set. In this milestone transaction, outputs 1 through 12 are Plane B. These outputs carry the fixed ML-KEM-era recovery packet material the recipient wallet will later use to discover and recover the private payment.

So the public transaction does not have the usual structure:

“recipient payment output plus sender change output.”

Instead, it has:

“one private state continuation output plus a fixed recipient recovery packet set.”

That distinction is important. Plane A keeps the state transition moving forward. Plane B gives the recipient a packet set to recover against with wallet secrets. Public observers can see the layout, token commitments, and BCH values, but they do not see a normal visible recipient payment output or an ordinary visible BCH change output.

The accepted transaction demonstrates the on-chain packet layout. Final receiver discovery, recovery, and wallet reconciliation remain next engineering work.

Public value vs private value

The public chain sees this arithmetic:

20,000,000 sats input = 19,978,000 sats Plane A + 12,000 sats recovery packet outputs + 10,000 sats fee

But the operator-intended private payment amount was:

9,987,000 sats

There is no visible 9,987,000 sat recipient output on-chain.

That is the important privacy milestone: the visible BCH values are not the same thing as the actual intended private payment amount. The public chain sees the private-payment packet layout and token commitments. The actual payment meaning is carried inside the protocol state transition rather than exposed as a normal visible recipient payment.

An important detail here is how change is handled.

In an ordinary BCH transaction, leftover value often appears as a separate visible change output. That can be a privacy leak, because observers can often distinguish payment output from change output and use that distinction to reconstruct user activity.

This transaction avoids that pattern.

There is no ordinary visible BCH change output. Instead, sender change is retained inside Plane A, the private state continuation output. Plane B remains the recipient recovery packet set: twelve uniform packet outputs carrying the ML-KEM-era recipient recovery material.

So the public transaction does not say:

“here is the recipient payment, and here is the sender change.”

It says something closer to:

“here is the next private state continuation, plus a fixed recipient recovery packet set.”

That is a key part of the privacy direction. Public observers can still see the transaction graph, the input, the output count, token commitments, and visible BCH amounts. But they do not get a conventional visible recipient output or a conventional visible change output that directly reveals the payment split.

Why this matters

This is the first accepted explicit packet-plane shell for the ML-KEM-era path.

It demonstrates that the transaction can be shaped as:

  • one Plane A private state continuation output
  • twelve Plane B recipient recovery packet outputs
  • no ordinary visible BCH change output
  • sender change retained inside Plane A
  • Plane B reserved for the twelve recipient recovery packet outputs
  • no fallback to the earlier compact carrier path

That is a major step toward the target architecture: private value moving through authenticated protocol state rather than through publicly meaningful BCH payment outputs.

What this does not claim yet

This is still R&D, and the truth boundary matters.

This milestone does not yet claim:

  • full end-to-end post-quantum privacy
  • production-ready confidential transactions
  • final wallet reconciliation or receiver recovery
  • final proof-bearing covenant enforcement on this path
  • aggregation or coordinator-based privacy

The transaction proves the explicit packet-plane on-chain layout. It does not by itself prove that the whole final privacy protocol is complete.

Why I’m excited

This is the first time the intended ML-KEM packet-plane layout has made it onto Chipnet in the form the current protocol direction requires.

This milestone shows the explicit packet-plane layout (13 outputs) can be accepted on-chain without falling back to ordinary visible change or the earlier compact carrier path.

That is real progress toward cash-like BCH privacy: hiding the actual intended private payment amount inside protected protocol state while keeping the transaction self-custodied and visible enough to be audited on-chain.

Appendix: evidence data

The accepted packet-plane attempt was recorded as:

{
  "version": 1,
  "generatedAt": "2026-04-27T19:00:51.406Z",
  "attemptKind": "explicit-packet-plane-path",
  "attemptStage": "broadcast-observed",
  "profileId": "bob",
  "stateFilePath": "/tmp/bcloak-live-profiles.json",
  "signedArtifactIdHex": "1fb716d7640fe821589a12389ebf4e2f9ff3d507a0081524f929ea3549054950",
  "selectedFundingOutpoint": {
    "txidHex": "676ed5dd9a72949a59cd7c523d8e50279dc13c5084f2f949bbba7d85a540db77",
    "vout": 0
  },
  "outputCount": 13,
  "outputLayoutSummary": "output0=PlaneA, outputs1..12=PlaneB packet outputs",
  "planeAIndex": 0,
  "planeBRange": {
    "start": 1,
    "end": 12
  },
  "recipientPacketCount": 12,
  "recipientPacketProfile": "ml-kem-768-12x128",
  "transparentChangeAbsent": true,
  "compactCarrierFallbackAbsent": true,
  "residueState": "privately-folded",
  "txidHex": "1fb716d7640fe821589a12389ebf4e2f9ff3d507a0081524f929ea3549054950"
}

The live transaction facts were:

{
  "network": "chipnet",
  "txid": "1fb716d7640fe821589a12389ebf4e2f9ff3d507a0081524f929ea3549054950",
  "version": 2,
  "sizeBytes": 2400,
  "feeSats": 10000,
  "input": {
    "outpoint": "676ed5dd9a72949a59cd7c523d8e50279dc13c5084f2f949bbba7d85a540db77:0",
    "valueSats": 20000000
  },
  "outputs": {
    "count": 13,
    "planeA": {
      "index": 0,
      "valueSats": 19978000,
      "scriptHex": "51",
      "tokenNftCapability": "mutable"
    },
    "planeB": {
      "range": "1..12",
      "count": 12,
      "valueSatsEach": 1000,
      "totalValueSats": 12000,
      "scriptHex": "51",
      "tokenNftCapability": "none",
      "recipientPacketProfile": "ml-kem-768-12x128"
    }
  },
  "planeModel": {
    "planeA": {
      "outputIndex": 0,
      "role": "private state continuation output",
      "currentMilestoneFunction": "carries the next private protocol state and retains sender change at the current shell level"
    },
    "planeB": {
      "outputRange": "1..12",
      "role": "recipient recovery packet set",
      "currentMilestoneFunction": "carries the fixed ML-KEM-era recipient recovery packet material",
      "packetProfile": "ml-kem-768-12x128"
    }
  },
  "changeHandling": {
    "ordinaryVisibleBchChangeOutputPresent": false,
    "senderChangeHandling": "retained-inside-plane-a-private-state-continuation-output",
    "publicChangeClassification": "no conventional visible BCH change output"
  },
  "publicArithmetic": {
    "inputSats": 20000000,
    "planeASats": 19978000,
    "planeBRecoveryPacketSats": 12000,
    "feeSats": 10000
  },
  "operatorIntendedPrivatePaymentSats": 9987000,
  "visibleRecipientOutputForIntendedAmount": false,
  "ordinaryVisibleBchChangeOutputAbsent": true,
  "fallbackToEarlierCompactCarrierPathAbsent": true
}

Next steps toward full confidentiality

The next work is to move from an accepted packet-plane layout toward the full confidential transaction architecture.

Near-term work:

  • receiver discovery and recovery from Plane B recipient recovery packet outputs
  • proof-bearing continuation spend validation
  • covenant/state-cell enforcement of the private transition rules
  • clearer evidence tooling for comparing public chain values against intended private payment semantics

The key point is that this milestone proves the explicit packet-plane layout can land on-chain. The next stage is making that layout fully recoverable, enforceable, and spendable as a complete confidential payment path.

3 Likes

Milestone: first live proof-bearing P2S/kernel continuation spend on Chipnet

Direct Confidential Spend on BCH: Packet-Plane Source + Proof-Bearing State-Cell Continuation

I have live-validated a narrow but important milestone for a confidential transaction protocol on BCH:

  1. An explicit ML-KEM-768 packet-plane transaction was accepted on Chipnet.
  2. The recipient recovery path can use ML-KEM-era packet material rather than exposing a normal recipient payment output.
  3. A P2S/kernel state-cell continuation spend was accepted on Chipnet.
  4. That continuation spend carried compact proof material and advanced the protocol state cell.
  5. The public chain did not show a normal recipient output equal to the private transfer amount, and did not show ordinary transparent BCH change.

The next questions are:

  • Is the compact proof system used here properly classifiable as a STARK?
  • If so, is this STARK construction actually zero-knowledge for the defined public statement?
  • Does the full transaction transcript reveal only the intended public statement, or are there additional public-field, graph, timing, or metadata leaks?

That distinction matters because “proof-bearing,” “STARK-class,” and “actually zero-knowledge” are not the same claim.

The direct-path point

The most important architectural point is this:

This is still direct, self-sovereign spend. Aggregation is not required for correctness.

A confidential BCH protocol should not require users to depend on a coordinator, aggregator, server, or service market as part of the trust base. Those services may become useful later for batching, timing privacy, fee efficiency, and UX.

But the base path should work directly from wallet-controlled state, chain truth, and wallet secrets.

That is what this milestone demonstrates.

Source packet-plane tx:
76982788a0f653c31b42890ab1cd75a994af55b76c43d969f3da8a78b095cd99

Continuation tx:
4586ce7296dd456cd973610fc2f36362c324594682dbc91d03ef4acb4eaa49e9

Continuation input:
76982788a0f653c31b42890ab1cd75a994af55b76c43d969f3da8a78b095cd99:0

Continuation output:
index 0
value 29,978,000 sats
P2S script type: script
mutable NFT protocol state cell
token category: 6f2b7d8d0a509b6011aca9f08bf1786d3824027ed5ba939a00d6328cca9cb17e

Tx size:
1,589 bytes

Fee:
5,000 sats

Fee rate:
~3.147 sats/byte

Mempool:
accepted, 0 confirmations at observation

1 Like

Why I Think Privacy Doesn’t Just “Drop Into” BCH Wallets

BCH-CT has reached an important design checkpoint.

The early framing was:

How do we add confidential transactions to BCH wallets?

That is still the eventual integration question, but it skips over the deeper architecture question:

How do we build a BCH-native private payment mode when BCH does not have native shielded-pool consensus like Zcash or default privacy rules like Monero?

That distinction matters a lot.

It changes the work from “add a new address type” into a larger protocol/app-layer design problem: private notes, encrypted note delivery, proof-based authorization, wallet accounting, aggregation, and BCH settlement.


Why this is harder than “add a new address type”

A normal BCH wallet is built around:


keys -> addresses -> UTXOs -> signatures -> broadcast

That model works well for transparent payments.

But confidential payments move the problem into a different model:


private notes -> commitments -> nullifiers/spend markers -> proofs -> encrypted note delivery

In other words, the important shift is from key-based authorization to proof-based authorization.

On transparent BCH, the chain asks:

Did the spender satisfy this visible script/address condition?

In BCH-CT, the chain should eventually ask:

Does this proof show that a valid private note was spent, value was conserved, and new private notes were created correctly?

That is why trying to make an ML-KEM key, Nostr key, or Quantumroot vault behave like a normal BCH address does not really solve the core problem.

ML-KEM is useful for encrypted note delivery.

Nostr may be useful for message transport.

Quantumroot is useful for post-quantum custody.

But none of those are the same thing as a private-note authorization model.


What other privacy chains have that BCH does not

Zcash privacy is not just a wallet feature. Zcash made shielded transactions a first-class part of the protocol: shielded notes, note commitments, nullifiers, encrypted note data, and proof verification are all part of the native shielded transaction model.

Monero also does not bolt privacy onto ordinary visible addresses. Its privacy model combines stealth addresses, RingCT, and spend/view key separation so recipient identity and amounts are not represented like ordinary public UTXO payments.

Dash PrivateSend is closer to BCH’s existing CashFusion pattern: it uses non-custodial CoinJoin-style coordination to make transaction history harder to trace, but it is not a private-note protocol like Zcash or Monero.

That is the key difference:


Zcash:

native shielded-pool consensus

Monero:

native privacy transaction model

Dash / CashFusion:

non-custodial mixing of transparent coins

BCH-CT:

currently being explored as a BCH contract/app-layer protocol

So BCH-CT cannot just “copy Zcash” without consensus changes. It has to use BCH-native primitives: UTXOs, covenants, CashTokens, proof-bearing scripts, and optional coordination.


The SLP / CashTokens analogy

The closest BCH historical analogy may be SLP before CashTokens.

SLP filled the token gap before BCH had consensus-native tokens: wallets, indexers, and applications interpreted token rules on top of normal BCH transactions. Later, CashTokens made token functionality first-class at the BCH consensus/VM layer.

BCH-CT may be doing something similar for privacy. BCH does not currently have native shielded-pool consensus, so this work explores what can be done at the contract/app layer first. If the model proves useful, it may help clarify what a future native BCH privacy proposal would actually need.

The analogy is not perfect: privacy is harder than tokens. BCH-CT has to deal with private notes, nullifiers, proofs, encrypted note delivery, wallet recovery, metadata leakage, and post-quantum assumptions. But the pattern is familiar: explore at the application layer first, learn the real requirements, then decide whether any part belongs in consensus later.


Why not make privacy more chain-native?

The obvious question is:

If Zcash made privacy native, why not do the same thing on BCH?

That may be a valid long-term direction. BCH could eventually consider a consensus-level privacy proposal with native note commitments, nullifier sets, proof verification, encrypted note fields, and pool accounting.

That would be the closest BCH equivalent to Zcash.

But it is also the largest path. It would require a serious CHIP process, broad ecosystem review, wallet changes, node implementation work, long-term maintenance, and agreement that private notes should become a first-class BCH consensus feature.

That is not the smallest next step.

The more immediate question is:

What can BCH do with the primitives it already has or is already gaining?

That led to direct state cells first.

A direct state cell is very BCH-native:


state cell UTXO exists

wallet spends it with valid covenant/proof data

new state cell UTXO is created

BCH consensus enforces single-spend

That path is decentralized, self-sovereign, and fits the UTXO model.

The problem is privacy.

If Alice’s private activity visibly advances like this:


Alice state cell -> Alice next state cell -> Alice next state cell

then the state-cell lineage can become Alice’s activity graph.

So the current design keeps direct state cells as the base/fallback primitive, but no longer treats visible one-user state-cell advancement as the final privacy boundary.


Where Quantumroot fits

Quantumroot is extremely important, but it solves a different layer.

Quantumroot is a post-quantum vault/custody design for BCH. It protects visible BCH UTXOs with hash-based post-quantum authorization paths and aggregation techniques.

That is not the same thing as confidential transactions.

Quantumroot answers:


How do I hold and later spend BCH safely in a quantum-threat model?

BCH-CT is trying to answer:


How does Alice privately pay Bob without the chain showing Bob’s normal recipient output,

the private amount, or Alice’s ordinary transparent change?

So the practical stack may become:


CashFusion:

improve transparent input provenance

Quantumroot:

PQ-safe custody before/after private mode

BCH-CT:

private note transfers inside private mode


Why CashFusion + Quantumroot may be enough for some users

This is worth saying plainly.

For many users, CashFusion + Quantumroot may be the right near-term privacy/security stack.

It gives:


better transparent coin history

+

post-quantum custody

That is valuable.

But it does not give:


hidden payment amounts

hidden sender residue/change

private note transfer

proof-based private spends

the ability to stay inside a private payment mode across multiple hops

That is the reason BCH-CT still exists as a separate research path.

If BCH-CT cannot deliver private notes, hidden amounts, hidden residue, and proof-based private transfer, then it is probably not worth the complexity.


Why this MVP design was chosen

The current MVP direction is:


direct state cells as the base/fallback path

+

CashFusion-like aggregation as the privacy boundary

+

private notes as the internal payment object

Instead of Alice directly advancing her own visible state cell, Alice creates a spend intent.

That intent says:


I authorize my current BCH-CT state cell to be consumed

only if this batch creates the private note commitments I committed to.

Alice submits that intent to one or more aggregators.

The aggregator is not a validator.

It is not a shard manager.

It is not a sequencer.

It does not custody funds.

It does not decide protocol truth.

It is just a batch assembler, similar in spirit to CashFusion coordination.

The aggregator collects many intents:


Alice intent

Bob intent

Carol intent

Dave intent

...

Then builds one BCH transaction:


many BCH-CT state cells in

many unordered private note commitments out

no ordinary transparent change

no public recipient marker

no obvious input -> output mapping

BCH validates the transaction. If the aggregator lies, redirects value, omits required commitments, or builds an invalid transition, the transaction fails.

That is why this design was chosen: it is more BCH-native than a managed pool or sequencer, avoids the single-UTXO bottleneck, avoids visible per-user lineage, and does not require immediate native shielded-pool consensus changes.

It is not “privacy off-chain.”

It is:


BCH validates settlement.

Users own their state.

Aggregators assemble batches.

Encrypted note delivery happens off-chain.

Recipients verify notes against BCH commitments.

Direct spend remains the fallback.


Where Nostr fits

Nostr should not be the protocol trust base.

But it can be useful as a message transport.

In the MVP, Nostr can carry:


aggregation intents

encrypted note envelopes

batch status messages

contact/discovery messages

It should not carry protocol truth.

The chain remains the settlement and validation layer.

The important line is:


Nostr routes encrypted note material.

BCH anchors settlement.

Proofs authorize private state transitions.


Alice to Bob in the updated model


1. Alice has BCH-CT private state from a prior import.

2. Alice wants to pay Bob.

3. Alice obtains Bob-compatible receive material off-chain.

This might use Nostr, QR, direct contact exchange, or another transport.

4. Alice creates Bob’s private note:

- private amount

- note randomness/opening

- commitment

- recovery material

5. Alice encrypts Bob’s note envelope, likely using ML-KEM-derived shared secret material.

6. Alice creates a spend intent:

- consume Alice’s current BCH-CT state cell

- create Bob note commitment

- create Alice residue note commitment

- pay fee/postage

- expire after height H

- no transparent change

7. Alice submits the intent to one or more aggregators.

8. Aggregator combines many intents into one BCH batch transaction.

9. BCH validates the batch.

10. Bob receives the encrypted note envelope.

11. Bob decrypts it, verifies that the note commitment appears in the accepted BCH batch, and imports the private note.

12. Bob later spends by submitting his own direct spend or aggregation intent.


What this borrows from other systems

From Zcash, BCH-CT borrows the note/nullifier/proof model.

From Monero, BCH-CT borrows the lesson that recipient identity should not become a public chain object.

From Dash/CashFusion, BCH-CT borrows the coordination pattern: non-custodial batch construction where the coordinator cannot steal funds.

From Quantumroot, BCH-CT can borrow BCH-native continuation, token authority, and post-quantum custody lessons.

From Cardano/eUTXO lessons, BCH-CT should avoid one global mutable UTXO or managed sharded state.

From SLP/CashTokens, BCH-CT borrows the historical pattern of exploring a missing feature at the application layer first, before deciding whether any part belongs in consensus later.


What BCH-CT is not claiming yet

This is not production Zcash-level privacy.

This is not a native shielded pool.

This is not complete post-quantum private money.

This is not solved wallet UX.

This is not a replacement for CashFusion or Quantumroot.

The honest current target is narrower:

Can BCH support an aggregated, proof-bearing private note transfer flow where users retain direct fallback, aggregators cannot steal or validate by authority, and visible state-cell lineage is broken by batch construction?

That is the MVP I think is worth building next.


Why this path may work on BCH

The reason I still think BCH is a good place to explore this is that BCH can validate rich covenant/script behavior directly on L1, while still preserving the UTXO model.

That means the design does not need to become an Ethereum-style rollup with a sequencer as the trust base.

The architecture I now see is:


BCH L1:

settlement, covenant/proof validation, fees, finality

BCH-CT app:

private notes, encrypted note delivery, wallet accounting, proof witnesses

Aggregation:

optional CashFusion-like batch assembly

Quantumroot:

PQ-safe custody at the transparent edges

Nostr:

optional message transport, not protocol truth

The goal is not to make privacy magically “drop into” existing BCH wallets.

The goal is to define a BCH-native private payment mode that wallets can eventually integrate once the protocol boundary is clear.

That is the next milestone.


References

1 Like

The confidential concept only works if you have mixers, as you correctly point out here. Because a single user obscuring 10 bch for n transactions and then taking the 10 bch out on the other side is not obscuring much. You need multiple people to mix.

A mixer can be called fusion or aggregator, it’s basically the same thing.

It is relevant to point out that if you start moving mixing transactions away from fusion, you make fusion less powerful because the measure of anonimity is the size of the pool.
And if you require fusion AS WELL AS your confidential script, you likely don’t need your confidential scripts at all.

Let’s work on finding solutions for whatever problem you are trying to solve using p2pkh UTXOs.

Some quick examples you give as being impossible in Fusion:

Both are actually directly available with very little work or complexity based on cash fusion.

BIP69 provides a lot of this already and is operational in various wallets today. You can take it further and spread your payment and / or change over a series of already fused transactions to pay to a dozen (or a hundred) different addresses that are all owned by the recipient.

You can make it as private as you want if you keep one simple rule: don’t reuse addresses.

The goal may be simply to have fun with zcash or similar algorithms, which is fun and naturally more than fine to play with.
If, on the other hand you are trying to solve actual real life privacy problems then I think we can work on a simple solution that reaches that without a new couple of layers.

1 Like

Thanks for bringing the conversation here. I like the forum posts more than TG because it slows things down and inspires thought.

The criticism is fair, and I agree with the main constraints.

Aggregation is mixer-like. Any design that needs multiple participants competes for anonymity-set attention. CashFusion is already BCH-native, non-custodial, and broadly useful. BCH-CT should not claim value if improved P2PKH/CF wallet behavior solves the same problem more simply. And BCH-CT should not weaken CF’s anonymity set unless it provides a privacy property CF cannot provide.

One clarification: BCH-CT is not trying to replace CF as a mixer.

The base BCH-CT result already demonstrated a different transaction shape: the public transaction does not show a normal recipient output equal to the private amount, and it does not show ordinary transparent BCH change. Instead, the actual value movement is represented through proof-bound private state, with only a public carrier/postage amount visible.

So I think the real question is:

Does moving from improved P2PKH/CF wallet behavior to P2S/proof-bound private state provide enough additional privacy, PQ-readiness, and practical value to justify the added complexity?

If the answer is no, then BCH-CT should shrink or stop.

If the answer is yes, then BCH-CT is not competing with CF as “another mixer.” It is a private-note/payment-state experiment that should use CF for clean imports and only use aggregation as an optional privacy improvement inside the private mode.

The strongest value I currently see is hiding the actual value being transferred behind a simple public postage amount while also avoiding ordinary transparent recipient/change outputs. That is the specific property I want to test against what can be done with P2PKH + CF + Quantumroot alone.

In the beautiful world of permissionless innovation nobody will (or can) tell you to stop. My goal is also not in that direction.
My goal is to make sure you’re working under the best knowledge to decide what you want to spent your time on.

The most used protocol today; cash fusion, does this as well. A single wallet (or identity) can have one or 50 inputs in any specific fusion transaction. Similar with outputs. From 1 to a large number. Nobody can tell what combination. Next to that, there is no reuse of addresses so there is simply no such concept as an identity.
Every single fusion makes any sort of tracability insanely improbable. Which means that an IDENTITY can mix funds that are spending just a token amount of fees (typically less than 2000 sats) and send an anonymous amount.
What that identity puts in and gets out is completely invisible. Hiding in plain sight.

More: https://x.com/i/grok/share/rlUL1TJY3gRbfwu4E9A8hTVi0

In other words, your goal of hiding amount and hiding identity is something that already is possible with cash fusion today, which is deployed and operational.

In my wallet there is special care taken to make this anonymous. The lack of address reuse helps because it means you don’t even know which of the outputs is the change and which is the payment. You also don’t know who it comes from and with fusion you don’t know who it went to.

All your requirements are fulfulled.

Quantumroot needs a single line. If at any time p2pkh is not enough and we need to move to any new crypto primitives then we’ll see that supported widely. So if there is a real need for fusion based on some new crypto signing primitive (quantum or otherwise), then the fusion server will be supporting. There is no technical reason stopping anyone from running one modified for any specific p2sh / p2s today. It is merely a matter of how big the anonimity pool is.

isn’t the time now? this is the thing I’m most curious about. does p2pkh survive in PQ with privacy like CF and protection with QR?

In other words, can you demonstrate the CF works well with QR easily?

1 Like

I think the question is to migration cost later if BCH support quantum route today then any new product should consider that today so it can become future proof.

1 Like

this may now actually be more possible then originally thought, thanks to tools like WizardConnect. A privacy wallet dapp is currently under development without needing to build an entirely new wallet layer.

the dapp uses keys and signatures from electron cash and uses the utxos in the EC wallet to populate the privacy protocol or private notes.

wallets may optionally integrate with the dapp via open access template versions, but it’s not a requirement. or, non electron cash wallets can simply add wizardconnect support.

then, as the privacy protocol matures, wallets may develop and integrate as needed, but the dapp will bridge transparent and private transactions regardless

1 Like

This all sounds good, but it’s also very long and very generic.

Where/when is the actual proposal? Here’s a (draft) script transaction that allows someone to move BCH between parties with some amount of increased privacy over the transparent default?

CashTokens, Velma and Layla are all live. The VM cannot be a limiting factor.

Feels like months and months of these generic statements and no actual “Here’s the work on a privacy solution”.

Compare with e.g. the work by BCHAutist (who also tackles very big scale problems that might not be apparent in the importance of the ground work at first). Pretty quickly things start to go from a generic discussion, to key details and decisions emerging on real points.

I’ll be short and direct.

Each phase of funding met and delivered as specified in campaign:

Phase 1
https://fundme.cash/campaign/79

Phase 2
https://fundme.cash/campaign/94

Phase 3 has yet to be funded, but this thread keeps the conversation going around proof based utxo spends that with proper hardening may become STARK / ZKP.

Milestone plan here

Milestone are very fluid as MVP being built

Summary of work completed and what this project is building towards https://gist.github.com/bastiancarmy/e64d49e937d2bf7567173e34eeb46b6f

The current most direct alice to bob type script is in this demo https://github.com/bastiancarmy/bitcoin-cash-stealth-demo/tree/main

From there, however, RPA was abandoned to focus on a more PQ ready solution, which is the ml-kem examples posted in this thread. Looking forward to discussing in deeper detail with whoever is interested.

2 Likes

Great summary, I’ll find some time to play around with the released files thanks.

Didn’t have anywhere I could see it all in one place like this before. Maybe worth pinning it to the thread or having some other place where this kind of “summary” explanation is posted and updated?

I’m sure other people will be looking for the same thing if they get interested in this project, but it’s hard to find if the information is all scattered about or buried in a thread.

1 Like

Great! glad it helps summarize.

I’m excited to keep building towards a wallet integration. I’m seeing two options:

  1. Wallet adds wizardconnect support
  2. Wallet adds first class support for the privacy protocol, using the open access covenant templates

#2 is most exciting, because it’s most similar to a service to service API call. The template exposes the required details to build the bytecode and an SDK can be published to build the commitment values:

type ApntImportTemplateInput = {
  valueSats: bigint;

  claimCommitment32: Bytes32;
  privateNoteCommitment32: Bytes32;
  selfRecoveryPacketHash32: Bytes32;
  refundKeyCommitment32: Bytes32;

  laneRoutingConfigHash32: Bytes32;
  laneId: number;

  batchPolicy: "aggregator-batch-v0";
  feePolicy: "exact-output-no-transparent-change-v0";

  expiryHeight: bigint;
};

This is very interesting. What do you need to get this finished?

1 Like

I noticed that with these EC primitives we could have a few lines of commitment script that enable Bulletproofs confidential transactions so they are essential and the backbone of any confidential transactions if we ever wanted one as close to drop-in. What’s being done on confidential transactions for BCH right now?

Honestly, I used to think we couldn’t have Monero-like confidential amounts without giving up auditability of the supply this is why there is workaround on non privacy chains like how eth had tornado cash. Turns out i was wrong and had it backwards… actually with @lightswarm proposal it could be very much possible to have the best from both world thanks to CashVM. The model is a transparent-backed shielded pool where BCH is locked transparently into a pool covenant, so the backing stays fully auditable and keeps cash-like properties, and inside the pool value moves as confidential notes (Pedersen commitments plus balance and range proofs, so amounts are hidden but conservation is enforced). A note transfers between users privately, or redeems back to transparent BCH by whoever holds the matching NFT commitment, with the NFT state cell tracking the pool root and nullifiers. The covenant can never release more than was locked, so even a bug is bounded to theft inside the pool; it can’t inflate the 21M. That’s the part Monero can’t give you, the tradeoff being privacy at the boundary since deposits and withdrawals are visible. Which is totally acceptable given that BCH is not a privacy chain like XMR.

From what i understand the aggregated private-note path here (ML-KEM encrypted note delivery, state-cell continuation) is a shielded-pool style design, and it covers the anonymity-set side, breaking linkage with ZKP STARKs, which is valuable. But hiding the link is a different property than hiding the amount. Pedersen commitments + Bulletproofs would give the confidential-amount piece directly: the commitment is only a few lines, and the range-proof verify reduces to one multi-scalar mult, with no trusted setup.

So on the “privacy doesn’t just drop into BCH wallets” point, I’d say the amount-hiding part actually can if we could add the EC primitives mentioned from @lightswarm proposal, with these opcodes. The two look complementary: EC/Bulletproofs for confidential amounts, mixing/aggregation for the anonymity set. Together that’s a real full Monero system.

  • Reference:

Ideally and optimistically a few opcodes for Bulletproofs / confidential transactions.

Opcode Needed? Role in CT/Bulletproofs
OP_ECADD Required (correctness) Pedersen commitment v·G + r·H, balance check, summing terms in the verify
OP_ECMUL Required (correctness) Scalar·point for the commitment and every verification term
OP_MODINV Required for Bulletproofs IPA uses a challenge and its inverse each round (mod group order); can substitute hinted inverses + a multiply, but native is cleaner
OP_ECMULTMULTI Practicality,not correctness Verify collapses to one big MSM (∑kᵢ·Pᵢ); even a single range proof is ~2n+2log₂(n) terms. Without it you emulate with many ECADD/ECMUL, far more expensive

The minimum for correctness is OP_ECADD + OP_ECMUL (plus OP_MODINV, or inverses passed as witness hints). The minimum for practicality adds OP_ECMULTMULTI, since the optimized verify reduces to one large multi-scalar multiplication (MSM) and even a single range proof is an MSM of ~2n+2log₂(n) terms; emulating that with many separate ECMUL/ECADD works but gets expensive fast. The Pedersen commitment that hides the amount, and the balance check that prevents inflation, only needs ECADD + ECMUL. Therefore we don’t need pairing operations, since Bulletproofs are pairing-free.

With those primitives you can build a transparent-backed shielded pool: BCH is locked transparently into a pool covenant, so the backing stays fully auditable and keeps cash-like properties, while inside the pool value moves as confidential notes (Pedersen commitments plus balance and range proofs, so amounts are hidden but conservation is enforced). A note transfers between users privately, or redeems back to transparent BCH by whoever holds the matching NFT commitment, with the NFT state cell tracking the pool root and nullifiers. The covenant can never release more than was locked, so even a bug is bounded to theft inside the pool; it can’t inflate the 21M. That’s the part Monero can’t give you. Monero folks would call that a tradeoff, privacy at the boundary since deposits and withdrawals are visible, but I’d say that’s how it should be, so the supply stays auditable.

Reference: CHIP 2025-05 Native Elliptic Curve Arithmetic Operations - #13 by lightswarm

I agree with the transparent-backed shielded-pool model:

transparent BCH lock-in
-> private internal notes
-> state/root/nullifier tracking
-> private transfer
-> transparent redeem
-> no release beyond locked backing

I’ve been exploring that path in stages.

The earlier bitcoin-cash-silent-auditable-transactions work covered the classical Pedersen/Sigma side:

Pedersen commitments over secp256k1
64-bit Sigma range proof over secp256k1
asset-scoped commitment generator
off-chain proof verification
on-chain proof/commitment binding direction

For example, the zk.js implements a 64-bit Sigma range proof over secp256k1 using a per-bit OR-of-two-statements construction. The verifier checks commitment aggregation, Fiat-Shamir consistency, and the Sigma equations.

The pedersen.js implements the Pedersen commitment side, including hash-to-point generator derivation and pedersenCommit64(value, r, assetId).

That was useful classical cryptography experimentation, but it is not the final target.

Your EC-opcode proposal is in the same classical family:

Pedersen commitments
+ Bulletproof range proofs
+ OP_ECADD / OP_ECMUL / OP_MODINV / OP_ECMULTMULTI

I agree that would be useful for native BCH confidential amounts. But it is not post-quantum safe. Pedersen commitments and Bulletproofs over secp256k1 rely on elliptic-curve discrete-log hardness. A sufficiently capable quantum computer breaks that assumption.

So I see that route as a strong classical-security confidential-amount proposal, not the final target for post-quantum shielded BCH.

The current BCH Cloak/APNT direction is different:

private-note transfer
+ shielded identity path
+ shielded amount path
+ nullifiers
+ note commitments
+ encrypted receiver/recovery packets
+ proof-bound state transitions
+ compact BCH-visible statement/output/root binding
+ post-quantum-safe direction

I just re-ran the Alice → Bob path with real chipnet tBCH.

Live source tx:

be8b9832a2a95bf9b09838cb085bc667e9eedacd2c71ae842289816ca93737b0

That transaction spends a transparent 68,000-sat chipnet UTXO and creates:

output 0:      Plane A state/control output
outputs 1-12: Plane B packet outputs
packet mode:  ML-KEM-768 packet plane
transparent change: none
sender residue: folded into Plane A/state continuation
continuation context: persisted

That matters for the post-quantum discussion. The receiver packet layer in this live chipnet run uses ML-KEM-768 ciphertext material. That does not mean the whole system is complete post-quantum private money today, because the funding input is still ordinary BCH/secp256k1 and the final proof/kernel/acceptance path is still being narrowed. But it does show the current direction is not making secp256k1 EC arithmetic the privacy core.

So I’d compare the approaches like this:

Earlier Pedersen/Sigma experiment:
  useful classical confidential-amount prototype;
  Pedersen commitments;
  64-bit Sigma range proof;
  off-chain verifier;
  not production privacy;
  not post-quantum.

EC/Bulletproof opcode proposal:
  useful native CashVM route for confidential amounts;
  depends on secp256k1 EC arithmetic;
  strong classical-security direction;
  not post-quantum safe.

BCH Cloak/APNT:
  transparent-backed private-note transfer;
  live chipnet packet-plane source tx;
  ML-KEM-768 receiver packet plane;
  no transparent change;
  Plane A state/control and Plane B packet outputs live on chain;
  proof-bound transition model intended to bind notes, nullifiers, amount conservation,
  state roots, output fingerprints, and continuation constraints;
  targeting shielded identity and amount without making secp256k1 Bulletproofs the core privacy dependency.

I’m not claiming production privacy, native BCH Bulletproofs, or complete post-quantum private money today.

The exact current truth is:

earlier Pedersen/Sigma/sec256k1 experimentation: yes
live chipnet transparent-backed packet-plane source transaction: yes
ML-KEM-768 receiver packet plane: yes
no transparent change: yes
state/control Plane A output: yes
continuation context persisted: yes
final production proof/kernel: still in progress
wallet acceptance/redeem rules: still in progress
complete shielded pool: not claimed yet

So I agree with the pool model. I just think the long-term target should not stop at secp256k1 Pedersen/Bulletproof confidential amounts. BCH Cloak is aiming at a proof-bound private-note system where identity, amount, recovery, nullifiers, and state transitions can move toward a post-quantum-safe design.

I tried the link, it returns 404 btw. IMO the QC risk splits into two surfaces and they fail differently. Pedersen hiding is information-theoretic, so a future QC replaying old chain data can’t open the commitments themselves; amounts stay hidden retroactively. The retroactive leak in the Monero case is the ECDH delivery channel, and that’s exactly the surface an ML-KEM packet plane fixes. So Bulletproofs amounts + ML-KEM note delivery aren’t competing designs, they compose: the PQ delivery layer closes the harvest-now-decrypt-later hole in the classical confidential transaction design.

What a QC does break is binding, i.e. forging proofs going forward. That’s where the transparent-backed pool does the work: the covenant is consensus-enforced to not release more than was locked, so a binding break means bounded theft inside one pool, not supply inflation. In Monero the same break means undetectable counterfeit. So the classical route degrades gracefully under QC, users exit to transparent and migrate. And there’s no compact PQ drop-in for Pedersen + Bulletproofs today, lattice replacements are still research. The PQ-sound proof layer is hash-based STARKs proving the same range and balance statements, just tens of KB vs ~700 bytes per proof. So I see the two as sequential on the same layer, not competing: EC/Bulletproofs is the compact now (and the chain-enforced one, since the EC ops let the covenant verify the proofs), the hash-based proof-bound direction is the later.

Side note, the EC opcodes seem to be the native upgrade path for what I think the zk.js Sigma range proof did off-chain (need to check the link though): same statements, verified by the chain instead of around it.

thanks fixed links