Search projects, hackathons, sponsors and tech

    ← All projects

    ultratokenizer

    No proof, no mint. zkPDF in SP1, Groth16 on Hedera, and a receipt anyone can recheck offline.

    Demo

    About

    Ultratokenizer is a token engine that physically cannot mint without a zero-knowledge proof that a real, signed document authorizes it. Today, tokenizing a real-world asset means trusting an operator's word that the paperwork exists. Ultratokenizer removes the word. The holder's signed PDF certificate never leaves their browser. A zkVM program verifies the RSA-2048/SHA-256 signature over the complete document revision, extracts the authorized quantity and holder, and proves the whole thing bound to one exact minting request. What reaches the chain is 224 bytes of public output and a Groth16 proof. The document does not. The Gate is the only authority. It re-derives the request digest in Solidity, checks the Groth16 proof against a registered program key, checks the holder's EIP-712 signature, checks a separate issuer permit, checks that the institution reserved exactly this quantity against a governed backing ceiling, burns a single-use claim identifier, and only then mints through a registered adapter. Any one failure reverts everything. There is no administrative mint function. The governor cannot bypass the proof, because no such path exists in the code. Every mint produces a receipt an outsider can recheck offline against their own trust pins, without our RPC, our site, or our word. Live on Hedera testnet right now, unpaused, with the real SP1 Groth16 verifier registered. Check it yourself before reading another line: Gate 0xE1e3a133335dC0FEeB20397163c16E69F74919e3 Verifier 0xC96613d470494347586839B275bFDc56E978c5Be Token 0xa77e8a964606CE6994bd8d876445218dA3f9E64F (ATS, 3 decimals, 1 mg) Issuer ERC-8004 agent #116 on 0x8004A818BFB912233c491871b3d84c89A494BD9e The verifier's on-chain runtime bytecode hashes to 0xebc2d3ce..., byte-identical to the SP1 v6.1.0 Groth16 verifier vendored in the repo. It is not a mock. What is honest about the current state: the source profile authenticates a synthetic, self-signed certificate capsule embedded in the signed PDF. The signature verification is real cryptography on a real PDF structure; the claim fields come from a fixture rather than a bank's live format. A production institution profile needs its own parser and its own program identity, and the Gate is built so that swapping it is a governed, versioned registry action rather than a code change.

    How it's made

    The spine is one canonical EIP-712 issuance request, and the same digest is computed independently in three languages that must agree. TypeScript (viem) builds and validates it. Rust recomputes it from scratch inside the SP1 guest with tiny-keccak, sharing no code with the TypeScript. Solidity re-derives it a third time in RequestHash.sol. A parity harness diffs all three across 64 adversarial cases -- non-canonical decimals, mixed-case checksums, boundary integers -- and CI fails if any disagree. Changing one field means editing three implementations and a Solidity ABI test, by design. zkPDF / SP1. The guest runs a strict PDF coverage parser before any crypto: it requires exactly one /ByteRange and one /Contents, requires the signed ranges to cover the entire supplied revision, and requires the excluded gap to be exactly a hex-string Contents value -- no appended revisions, no second signature, no arbitrary unsigned object. It then verifies an RSA-2048/SHA-256 CMS signature and derives the signer fingerprint from the canonical SubjectPublicKeyInfo DER, so a key embedded in the document is never its own authority. Output is 224 bytes of ABI-encoded public values decoded strictly on-chain. The Gate (Solidity 0.8.30, non-upgradeable, Foundry). Five append-only registries -- issuer keys, programs, source keys, policies, rights -- each with permanent revocation and no rewrite path. Replay protection runs across five independent namespaces: request digest, request ID, claim usage ID, holder nonce, permit nonce. Backing is real accounting: a reservation moves capacity into pending, a mint moves it pending to outstanding, and governance cannot lower the ceiling below live exposure. Signature checking supports EIP-1271 contract wallets and enforces low-s. Hedera ATS. The token is an Asset Tokenization Studio diamond. The mint adapter pins 15 runtime code hashes -- ten facets, four linked libraries, one resolver -- and re-checks every one immediately before and immediately after the mint, then asserts exact totalSupply and balance deltas. If any pinned contract changed mid-transaction, the mint reverts. We also built a native HTS adapter that creates a zero-supply token with a single contract-ID supply key and no admin key. ERC-8004 for identity only. The registry supplies issuer attribution and nothing else. We do not use reputation or validation -- those words appear nowhere in the source. The app reads a published index, then re-derives every claim from the Gate itself. A registry entry is attribution, not authorization. The hacky part worth mentioning: the synthetic claim capsule sits immediately after the PDF header, and we can prove it is inside the signed region without parsing PDF objects at all. The coverage parser requires the unsigned gap to begin with '<', and the capsule region contains no '<' byte, so the gap can only start after it. That turns a structural argument into an arithmetic one the zkVM can check cheaply. Polyglot monorepo, no workspace tool: five npm lockfiles, one Cargo workspace plus isolated crates, Foundry plus a separately compiled ATS package with checksum-locked solc. Risky surfaces get their own lockfile so a compromise there cannot reach the main install. Gates: 72 Foundry tests, 265 issuance, 225 web, 166 across domain and audit and institution, 64 parity cases, plus a hygiene check that rejects secrets and absolute paths in tracked files and commit messages.