Proof and on-chain verification

Proof and on-chain verification.

This is the evidence room. The real 256 bytes proof, the exact split between what Stellar sees and what stays hidden, the contracts that gate the money, and the trust model named in full. Every value below is read from a live testnet, not a screenshot.

The proof

The proof, byte by byte.

This is the real Groth16 over BN254 proof Stellar verifies on its own. It is the three curve points A · B · C, generated in your browser. Stellar reads all 256 bytes and decides for itself.

Groth16 proofBN254256 byteslocked

The 256-byte Groth16 proof — points A ‖ B ‖ C, byte by byte. Stellar reads it and decides on its own. A real proof locks lime. A forged one is rejected and nothing moves.

A real proof locks lime. A forged one is rejected and nothing moves. The lit bytes at the front mark where proof point A begins; the rest are points B and C, all checked by one BN254 pairing.

Public inputs

What Stellar sees, and what it never sees.

The proof commits to a small set of public inputs and nothing more. Everything on the left is on-chain. Everything on the right stays inside the prover and is never sent anywhere.

PublicWhat Stellar sees
Thresholdcleared

Proof that your collateral cleared the required minimum — the figure itself is never published.

Note commitment7530136…834832

The Poseidon2 commitment to your note, inserted into the pool tree.

Nullifierone-time spend tag

Published when the note is spent, so the same note can never be spent twice.

Axelar message0x6903…d7f9-3

The authenticated (commitment, amount) delivery that backed your note with real Sepolia WETH.

PrivateNever leaves the prover, never on Stellar
Exact collateral amount▓▓▓▓▓▓

How much you actually locked. Sealed in the witness, never transmitted.

Ethereum address▓▓▓▓▓▓

Which wallet holds it. Never written to Stellar, never on the ledger.

That gap is the privacy guarantee. Stellar can confirm you cleared the threshold and that this proof has never been used, without ever learning how much you hold or which wallet is yours. The lender, the ledger, and every observer see only the public journal.

The verifier

The contract that checks every proof.

A single Soroban contract on Stellar testnet does the verification. It is pinned to one circuit's verifying key, so it only accepts proofs produced by the exact circuit Veil published.

Circuit bindingborrow.circom → verifying keyThe verifier embeds one fixed verifying key. Change the circuit and that key changes, so old proofs stop verifying.
Verifier contractCBTSWUY5OME4EDY3YA7OBRXHVMSBZH4MWO4GSGNPR4FAGG36RGQGDMM2Stellar Expert The live Groth16 verifier on Stellar testnet. Open it on the explorer and read it yourself.
Proof systemGroth16 over BN254A succinct proof checked by one BN254 pairing inside the contract.
Proof size256 bytesThe whole proof is 256 bytes. That is all Stellar needs to be convinced.
Try to cheat

Forge the proof, and no USDC moves.

This is not hypothetical. In Veil's live cross-chain run a borrow proof with a tampered public input was rejected on-chain with Error(Contract, #0) InvalidProof, and zero USDC moved. Replay it below and the proof shatters red. Re-spending an already-spent note is rejected too — its nullifier is already recorded. Either way the money stays put.

Try a fake proof
Tamper with the proof and watch it shatter — the trap the vault produced on-chain
Soroban

This flips one byte inside the real 256-byte Groth16 proof. On-chain, the vault rejects a tampered proof: a real one locks lime, a forged one shatters and nothing moves.

Groth16 proofBN254256 bytessealed

The 256-byte Groth16 proof — points A ‖ B ‖ C, byte by byte. Stellar reads it and decides on its own. A real proof locks lime. A forged one is rejected and nothing moves.

Live on real testnets

Deployed contracts and on-chain proof.

A real WETH lock on Ethereum Sepolia, the Soroban pool, vault, and Groth16 verifier on Stellar, and the live cross-chain transactions that locked collateral and disbursed the loan.

Sepolia WETH lock
0xBCceef356d803D191d8a6cf1cEB979C2DFbCda98
Etherscan
Soroban pool
CB6DH7PJOUKGFXD7QPYFJCHQF6HA7HEALXVCWK6I33RGWXOEQEKTELPW
Stellar Expert
Soroban vault
CDYPPRKZN7CAKY7GMFEMLNMVLPVEI6JVNFKJKGZVZNYJFMHSGRH2HBZP
Stellar Expert
Groth16 borrow verifier
CBTSWUY5OME4EDY3YA7OBRXHVMSBZH4MWO4GSGNPR4FAGG36RGQGDMM2
Stellar Expert
Real WETH lock (Ethereum)
0x4fa09246…b77cc959
Etherscan
Axelar delivery → Stellar
bdc2af52…c9a40fe27
Stellar Expert
Borrow → 6.05 USDC (Stellar)
3a3bb9b5…044cd8a3
Stellar Expert
The trust model

What Veil relies on

Axelar's validator set carries the cross-chain attestation; Veil runs no relayer of its own.
A price oracle (Reflector) supplies the ETH valuation.
A timeout governs refunds if a leg stalls.
The note commitment is public on both chains, so an Ethereum-side observer can correlate the two legs.

What Veil guarantees

Stellar-side confidentiality. Your amount and wallet never appear on Stellar.
The lender, the ledger, and every observer see only threshold, commitment, nullifier, proof.
The proof, not a relayer, is what releases the money.
Collateral never bridges. It stays on Ethereum the whole time.