BlindSig

Private transfers via shielded addresses using ZK proofs, ENS-registered keys, and a UTXO pool

BlindSig

Created At

HackMoney 2026

Winner of

ENS

ENS - Integrate ENS

Prize Pool

Project Description

BlindSig enables private cryptocurrency transfers using shielded addresses and zero-knowledge proofs. Users generate a stealth key pair (pk_spend + pk_view), encoded as a single Bech32 "peek1..." address and registered on ENS under the custom text record "com.blindsig" — allowing anyone to resolve a recipient's shielded address directly from their ENS name without a separate registry contract.

User Flow

  1. Register on BlindSig and get the Shielded Address
  2. Connect with ENS and register this Shielded address as a record
  3. Deposit Shielded ETH to BlindSig
  4. Send funds privately using Shielded Address or ENS

Funds are sent through a shielded UTXO pool powered by a 2x2 join-split scheme: each transaction consumes 2 input notes and creates 2 output notes. Notes are Poseidon hash commitments stored in an on-chain Merkle tree, and nullifiers derived from the owner's secret key prevent double-spending. A single unified Circom circuit handles deposits, withdrawals, and fully shielded transfers, with Groth16 ZK-SNARK proofs ensuring value conservation, note ownership, and Merkle inclusion — all without revealing sender-recipient links on-chain.

How it's Made

Shielded Address Format - Shielded addresses encode two BN254 public keys — pk_spend and pk_view — into a Bech32 string with the prefix peek1.... These addresses are stored as ENS text records under the key: "com.blindsig". This allows resolving shielded addresses directly from ENS.

ZK Layer Architecture - The zero-knowledge layer is built using Circom 2.1 and a single transact circuit implementing a 2×2 join-split scheme:

  • 2 input notes consumed
  • 2 output notes created This unified circuit supports:
  • Deposits
  • Withdrawals
  • Shielded transfers using a commitment–nullifier model:
  • Notes are represented as Poseidon hash commitments and inserted into a Merkle tree.
  • Nullifiers (Poseidon hash of secret key + random secret) prevent double-spending.
  • Merkle inclusion proofs verify note existence.

Notable optimization (hack) - Merkle inclusion checks are conditionally enforced by multiplying the constraint by the input amount. For deposits (where input amount = 0), Merkle verification is skipped — allowing one single circuit to handle all transaction types. Proofs are generated using Groth16 via snarkjs on BN254.

On-Chain UTXO Pool -The smart contract ShieldedUTXOPoolLedger.sol manages the shielded UTXO pool on-chain:

  • Uses @zk-kit/incremental-merkle-tree (depth = 20)
  • Verifies Groth16 proofs against 8 public signals
  • Tracks spent nullifiers to prevent double-spends
  • Supports ETH and ERC20 assets via SafeERC20

ENS Record Example - https://sepolia.app.ens.domains/akhilpraj.eth?tab=records Example Tx - https://sepolia.etherscan.io/tx/0x34b2a6d0bf94a8effe41a0a3ac5f5945d07c1a589ecaec178f08e4c021f61b37

background image mobile

Join the mailing list

Get the latest news and updates