<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>ilge.ustun</title>
        <link>https://paragraph.com/@ilge-ustun</link>
        <description>undefined</description>
        <lastBuildDate>Sat, 05 Sep 2026 08:54:13 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>ilge.ustun</title>
            <url>https://storage.googleapis.com/papyrus_images/f944bf45015b0068c1190d22acd7a72b30a757aad4369e0f814c8e68740c01d7.jpg</url>
            <link>https://paragraph.com/@ilge-ustun</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[I never thought private on-chain voting could be this simple]]></title>
            <link>https://paragraph.com/@ilge-ustun/zk-voting-speedrun-ethereum</link>
            <guid>Q1VgAFnCje1g2pOv6lvl</guid>
            <pubDate>Tue, 09 Jun 2026 12:18:16 GMT</pubDate>
            <description><![CDATA[Just finished the Privacy-Preserving ZK Voting challenge on Speedrun Ethereum and honestly didn't expect anonymous on-chain voting to be this easy! TL;DR You only need to prove that you're allowed to vote, at the moment of voting, without saying who you are.]]></description>
            <content:encoded><![CDATA[<p>Just finished the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://speedrunethereum.com/challenge/zk-voting">Privacy-Preserving ZK Voting challenge on Speedrun Ethereum</a> and honestly didn't expect anonymous on-chain voting to be this easy!</p><p>You only need to prove that you're allowed to vote, at the moment of voting, without saying who you are.<br>You register a commitment publicly from your real address (everyone sees you joined the set), then vote from a throwaway address with a zk proof that says "I know the secret behind one of the registered members" — without saying which one. A nullifier hash gets stored so you can't vote twice, and it can't be traced back to you.</p><p>This pattern (commitment + merkle tree + nullifier) shows up everywhere — private airdrops, anonymous credentials, allowlists that don't doxx the list.<br>So: privacy here isn't hiding everything. The membership set is fully public. You just break the one link between who you are and what you did.</p><h2 id="h-where-everything-runs" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Where everything runs</h2><p>The circuit is written in <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://noir-lang.org/">Noir</a>, compiled once to bytecode. The chain verifies the proof, but the proof itself is generated in the user's browser:</p><figure float="none" data-type="figure" class="img-center"><img src="https://storage.googleapis.com/papyrus_images/1c2075ec36e2b3bb1589fb4ecf92300277f08f4558a354ae5c8345f4b0604dda.svg" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAWCAIAAAAuOwkTAAAACXBIWXMAAAsTAAALEwEAmpwYAAADwUlEQVR4nJWUy47jRBSG80SskBAPwPAQ7HgAJCQkVrNjAUskFrOAFVvEboRYzGIWLZpu6A5DEqc7HTv4Ule7qmyXy05s56Cy3U4n9FywPh2Vb/XX/x+XJ0Gjp5rPt+LvSqxr5be6r36r3Trvq1froC2CtvBrM+kOSgG7gDzAPvxzC5EL0cqCfSCBrcizg0zAJGiKS0NelfGZjq4MvyjolWG/aXyu8aUhV4ZfGrKu00Gg1b1AmkKagIotyDehm3srRaJWxYfrKoZcdgI3Fb9I12fScUraTzQy1eEfmTuePhTIpUVw4CFQ3yLocPEhVmBuyKKkNxV3SuqUbLVNnJLNtJxKNSWbKdk4ik7Jxt2qoM1PBHo0MzoUOmkeEfCbId8T1ts8aItNk80KNDdkvZPd9bz4eAJPjgQoMgyXFJmE1SQyqfg/AisdO4ouBHaUTc9vCvL+RD0QUDEQr0tpY1v6dgf9B7NpBoGgtR2aGzL0oCn+G5GM9wyXjFQkMhSZvjJSjT04Eri7nzdoC7cUy4w7ii4z5qTsoQAAZGo0sU/ILiE7wWocFDgo+tNcQpreC1yn2ULbqceFj6y2iVPxEweffgifPYFPPoLJW483OHiEZhAYfIgK0i3I6oTm+XT/ygOhIbQ9OJrC3T3e82DYBwcBAABfgBvDDQEvAWkexT4Xghn59nf8bE5+mAnXmDsQPZ//6v245jHER8vnACiFUIEvH5laGGDaCkQ5hAVEeuBOHcavI8xt9MBhFyRocRffBWTpxneB9JCJOLvZbInQAQeWdQIGHLG/oq0jIDLgpba+lUnvgGpA0gYV3cMyIKmtNIWki6h/ASmNVIpFgoWIin1UAJIKqRQpg6TCUqJsh5SJ0tI+kLeDQGKKVVS6RK+iYo2NR3TAi5ClGwJJMfRgXNQ1a69puxCwlOC+0UdYAHzxJfw0A5blM0/PvPoW6ZmX/rWul7jComHpocnja7fCMhiKqyjbj7eQrDHVdswKWzXA5Kl1cNLVkzoK3Aq4ou08eaf0ow744OeuB3m9IrXLykVQzYPWZVsiaqq2RGyJOHLQxW0Tx0J0g269ryEwAJPveweZT03Et1jsiNQBz31WYbGP9WjiEJElfWcHk06AZWaJdrc4c3zjkR2ROyJbbr/Oo4jsPujfzA5TOGJ/HtXnUX3N2peb3QVqLlDzJ27OgvoiqvuIqkTmnGseax5nnBexrYpRzWMTJwlBhouj/xJMnnrPzoMX4Yj56hf59UvxzQvy3GHvffcQ+6sYcrA79p5+rO8H1b+v4ycmL4rXgwAAAABJRU5ErkJggg==" nextheight="3081" nextwidth="4437" class="image-node embed"><figcaption htmlattributes="[object Object]" class="hide-figcaption"></figcaption></figure><h2 id="h-what-the-circuit-actually-checks" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">What the circuit actually checks</h2><p>So what does the proof actually prove? It's not one big step — it's four checks that all have to hold at once, each one blocking a specific way to cheat.</p><ol><li><p>The nullifier hash is real — the circuit re-hashes your secret nullifier and demands it match the one you submitted. So you can't spend someone else's nullifier, and you can't invent one.</p></li><li><p>The commitment is rebuilt from secrets, not copied — your commitment gets recomputed inside the circuit from the nullifier + secret. It never accepts the commitment itself, only the preimage. So the public commitment everyone can see on-chain is useless to an attacker — only you hold both secrets.</p></li><li><p>The commitment is actually in the tree — the membership check. It takes your leaf index, turns it into bits to know left vs right at each level, walks up through the siblings you provide, and demands the root it computes equals the one the contract handed it. Not a leaf? No siblings produce a matching root.</p></li><li><p>The vote is a real choice — one constraint pins it to 0 or 1: vote × vote has to equal vote, which is true for nothing else. Skip it and someone passes a junk value and quietly skews the tally.</p></li></ol><p>All four hold or the proof fails — and none of them reveal which member you are. That's the whole point: you prove you followed every rule of a legit vote while saying nothing about who you are.<br><br><span data-name="v" class="emoji" data-type="emoji"><img src="https://cdn.jsdelivr.net/npm/emoji-datasource-apple/img/apple/64/270c-fe0f.png" draggable="false" loading="lazy" align="absmiddle"></span>public list, private vote.</p>]]></content:encoded>
            <author>ilge-ustun@newsletter.paragraph.com (ilge ustun)</author>
            <category>#zk</category>
            <category>#noir</category>
            <category>#speedrunethereum</category>
            <category>#voting</category>
            <enclosure url="https://storage.googleapis.com/papyrus_images/e3993087f6f804716f1ea52b4719e4db364e9a88f26d5306bef3cf9a18c9a0b2.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>