Confidential Transactions

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