Search projects, hackathons, sponsors and tech

    ← All projects

    BlindSig

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

    Demo

    About

    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