Search projects, hackathons, sponsors and tech

    ← All projects

    Proof of Human — End to End Plan

    Proof of Human — End to End Plan

    About

    The problem it solves The internet does not know who is human anymore. Bots farm airdrops. Scripts manipulate governance votes. Sybil accounts drain incentives. AI agents generate fake engagement at scale. Platforms either: Require invasive identity checks (KYC, biometrics, passports) Rely on weak signals like CAPTCHAs Accept being exploited by automated actors Today, you must choose between privacy and proof. If you prove you are human, you usually reveal: Your legal identity Your location Your device fingerprint Your behavioral data If you protect your privacy, you cannot reliably prove you are a unique human. There is no native, privacy-preserving, reusable “human layer” for crypto and the internet. Proof of Human solves this by allowing someone to prove they are a real, unique human without revealing who they are, where they were, or any raw personal data. Use of AI tools and agents Claude Code (Anthropic) was used as the primary development agent throughout this project — not just for code generation, but as an active pair programmer managing the full stack across iOS (Swift), Rust (mopro/FFI), Solidity (Foundry), and Node.js simultaneously. Specific contributions: - Circuit design — Iterated on the Circom ZK circuit structure, deciding which signals should be public vs private and how to encode the deviceCommitment = Poseidon(device_attest_key, walletAddress) binding - Smart contract development — Wrote and deployed HumanityVerifier, HumanityToken, Groth16Verifier, and ProofDelegator to Sepolia via Foundry - iOS app architecture — Designed the full Swift service layer (ProverService, ChainService, StampService, PoseidonBridge) and wired them together with SwiftUI views - Debugging SPM conflicts — Diagnosed and resolved the secp256k1.swift vs swift-crypto 2.x conflict that blocked the entire iOS build - mopro integration — Managed the circuit compilation pipeline: WASM → Rust witness → static library → XCFramework, and debugged the proof format differences between mopro's output and snarkjs's Solidity ABI encoding convention - Backend API — Built the Node.js proof server with Poseidon hashing, proof generation, verification, and on-chain submission endpoints The project itself also explores a future where AI agents will consume this proof — using the on-chain soulbound token as a trust signal to distinguish human users from autonomous agents in smart contract interactions.

    How it's made

    Challenges we ran into Challenges I Ran Into 1. Running ZK proofs natively on iOS Integrating mopro (a Rust-based ZK prover) into an iOS app was non-trivial. The circuit had to be transpiled from WASM to Rust using rust-witness, compiled to a static .a library for both aarch64-apple-ios and aarch64-apple-ios-sim, then packaged into an XCFramework. Any change to the circuit meant rebuilding the entire xcframework from scratch. 2. Swift Package Manager conflicts We initially used WalletConnect (reown-swift) for wallet signing. It pulled in swift-crypto 2.x, which silently broke secp256k1.swift 0.12.2 - the library relied on internal types (DigestSigner, SecureBytes) that were removed in the newer version. The error messages were cryptic and pointed nowhere near the real cause. We resolved it by removing the WalletConnect dependency entirely and routing transaction signing through the Node.js backend using ethers.js. 4. Poseidon hash consistency across stacks The ZK circuit uses Poseidon hashing (BN254 field). We needed the same hash values produced by the circuit, the on-chain verifier, and the iOS app. Getting circomlibjs, snarkjs, and the Rust poseidon-bn128 FFI to agree on field representation took significant debugging - one wrong BigInt encoding produces a completely wrong hash with no obvious error. 5. ERC-7702 transaction signing on iOS The original plan was to use ERC-7702 (type-0x04 transactions) so a relayer could submit the proof while msg.sender appeared as the user's own EOA - enabling gasless UX. However, implementing raw EIP-7702 transaction signing in Swift turned out to be a deep rabbit hole: the secp256k1 Swift package conflicts, no native RLP encoder for type-0x04 transactions, and the recoverable ECDSA signature (needed for the recovery ID v) not being cleanly exposed by any Swift library we could use without pulling in conflicting dependencies.