<?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>rafal</title>
        <link>https://paragraph.com/@rafal</link>
        <description>undefined</description>
        <lastBuildDate>Tue, 04 Aug 2026 00:00:11 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[How Rollups Work]]></title>
            <link>https://paragraph.com/@rafal/how-rollups-work</link>
            <guid>cOFmPXBNa4OmIrL5Iijm</guid>
            <pubDate>Sun, 11 Feb 2024 12:15:14 GMT</pubDate>
            <description><![CDATA[Special thanks to Luca Donnoh for the feedback.When discussing rollups, it&apos;s important to navigate through a substantial amount of technical inf...]]></description>
            <content:encoded><![CDATA[<p><em>Special thanks to </em><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/donnoh_eth"><em>Luca Donnoh</em></a><em> for the feedback.</em></p><p>When discussing rollups, it&apos;s important to navigate through a substantial amount of technical information and clear up common misunderstandings (there are also controversies). For this article, I&apos;ve decided to use the framework by <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://l2beat.com/scaling/summary">L2BEAT</a>, particularly their well-regarded risk assessment model, as a foundation.</p><p>L2BEAT provides thorough information on how rollups work and their associated risks, but it appears to be more suited for readers who already have a lot of familiarity with rollup technology. It can be quite overwhelming for newcomers. My objective here is to simplify this information and make it more accessible.</p><img src="https://storage.googleapis.com/papyrus_images/9ccec155e199f609b991f74450d1168d.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAASCAIAAAC1qksFAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFSUlEQVR4nIWV/08TdxjHb0uYwUKvfK58Pr1rr7S9frn2ru2VVlqhlNI2tAprK7VFV6BFQGCgk6AtJYLAqBMZujE2mIluixpdlmliss3FmEzDflSzJVsW9RezP2I/bEuW6zncksVdnh+e5HL3et7v9/O5wy5cuLi+tnG6fHbjowtXLl/zt7QpcIIiaSWBEKSkUhIqCMm/e/TvW+jlhd2/t3X/3tbn17548ODRH7//GYt2YpWrRiZ/9ZWq/+h31m73GIYpcOJ/AF6v/+q1L2/c/OrO3fvpdM/E0cmnT3+9e3crkcisrq4/evjzva3ve3sPrbz7/uMnz3748ZfRN4/Nzi4+fvLswcOfvrn9ndfrr5HJXwaIRV9fW/v4vXMfbm5cOl/+5OCBgc2NS7dufJ3N9p+aX7p189s7tx4GAuFcbnB1dX15+Xw02pVK9ayurpfLK9PTczab4+UisEOpw+ulixszn507vvn49m9evk2JqxYKZ5aWymfOrMwXl8fT5erq6hqZXPJEXgN27njeYxgm5aHA62tldQq8HkEKKlWVnpBCwkwGa6VsZsaqpw2M3gShqqpqh5JAHvcuBV5XXb1DClNwugWnW3pSSSAH57SxvAInFDjhcTclE90ed1ONTK7XMV2d8Ui4Q0moRAWsxabXGQhAhEIdajWNYRgAojSn01M6udjXO5RI9ChwQi7DY9HOqanC/lQmmeiukcmT3empqWJvNqckUD43ODe7EAlHBafbyJgWF073ZnPSQmK0RkuShpbAnutXrs+U5udKxVafSyYj9oR3HxmKT46mJkdTFKmBkBwbHR8bHTcazXodgyDVare7OXtDA2M0mgvHpwvHp+PxbgSp/anM0tJyNpujNXoESQxBikSagK+9ND0zkB8ZGRwwMQwAyGNn4yFvyOto2cVTpAZBKhnfF4vs2T4HPtZqUNNyOaHXMQd6ssODI5FwVIETPo/vYDqTiHbSKnEsrB6p3Q3Gwt7k0tnVD86vD+XStbI6BCmBMcUEV0xwmWgdAOIbhw5P9PUPSNFRSB3kOKOmAQDI6I1HJt4qFktdnXEAoIcxBVlzzMkFOB4AhFEkTZLa9lCsND1TOHFyrlRscttxHAomc4jnQzzP6hjpGAc5rpnjtwHNFqtOrQUA6nXM8ODI2Oh4JBwVARa23enocAlNFrYCQGq1xtARTRZPFI9MHD2Uy1stZgCQw2QKcuIUFp1BAgQ4vtFglHoKqX3sC0BvNpfPDQbbwgCIk/ltXJDjPBKAAEqnvWXh7c2lhZO8xYhhVeIuQ9JjYeNNu7o8jTb9cwXjk4X88HgdQHUAPbdIqwcAGo3mo8emZ2fL+xKZOgB9rDXWKHR53H4bJwLUKrXWaIv3jZRPzUfamiUHICR5gzHE8xG7fVtBu8sVcjVGBIffxiFINVvEkAFAWg2dSYTSiUjY3yRuh4UNclxEcLywyGCxJ/uG31l8u9nrljYEQlJgjBE7/08FQas1ZLNF7PaI4JAAjEYLAKI1dD4dynS1tPkcEiAiOGKNgs9cAQAA06n01U8vz8+Xl5fXFkoTCJJAUd9zsH95bZN1Nr1WjVNIjSA1Nlk4VV6ZKszWyusliySAVkOP9HZkk4Fo0AMAemERX9kiBCm9jsn15xcXTg/l3yBJcVhRgcm81+PucAmsTi8piAhOP2+nSFqycVuBVkPn0u2pzpaw3yUpCPG8qIC1igAloaI1+gM92ZnSqf7sfgIolYQKAGTTG6QMTHRD5eOhCnC8j2UBgOL/R6nymVktqcFxSFN0JtGajO1u9Vb2mzEFOHG/pQz+Anufd2ViRsGWAAAAAElFTkSuQmCC" nextheight="1300" nextwidth="2364" class="image-node embed"><p>In analyzing rollup risks, L2BEAT categorizes them into five areas: State Validation, Data Availability, Exit Window, Sequencer Failure, and Proposer Failure. Each rollup listed has a brief description under these categories, usually with additional details that can be difficult to interpret. Let&apos;s break down these categories for a high-level, and then detailed understanding.</p><ol><li><p><strong>State Validation</strong>: Refers to the process of verifying the accuracy and correctness of state transitions of the rollup. This is about ensuring that the transactions and data are correct and haven&apos;t been tampered with.</p></li><li><p><strong>Data Availability</strong>: Focuses on how accessible the data of the rollup is. Good data availability means users and validators can fully verify the blockchain&apos;s history and recover the state.</p></li><li><p><strong>Exit Window</strong>: The time during which users can withdraw their assets from the rollup if they need to exit quickly, e.g. due to changes or issues with the rollup. A longer exit window is better because it gives users more security.</p></li><li><p><strong>Sequencer Failure</strong>: Deals with the reliability and functionality of the sequencer. If the sequencer fails, it can lead to potential delays or loss of transaction data.</p></li><li><p><strong>Proposer Failure</strong>: Focuses on the risks related to the proposer. If the proposer fails, it can lead to issues in processing transactions or updating the state of the rollup.</p></li></ol><p>By understanding these risks, we can better assess the safety and reliability of rollups, which is essential for (some) people (sometimes).</p><div class="relative header-and-anchor"><h3 id="h-state-validation"><strong>State Validation</strong></h3></div><p>The core difference between zk and optimistic rollups lies in their way of finalizing the state. By state, we understand the balance of all accounts, including smart contracts and regular wallets, deployed on a rollup.</p><p>Consider the rollup as a processor: it takes the existing state, processes the latest block&apos;s transactions, and updates it. This processor is what we call the state change function.</p><p>State validation is a critical aspect of rollup security and functionality, and it varies significantly between zk-rollups and optimistic rollups:</p><p><strong>zk-Rollups</strong> use zero-knowledge proofs to validate transactions on L2 before posting to L1. In zk-rollups, the operator generates a cryptographic proof (a SNARK or STARK) for each batch of transactions processed on L2. This proof, which verifies the correctness of all transactions in the batch, is then posted to L1.</p><p><strong>Optimistic Rollups</strong> rely on operators who run the rollup nodes. Transactions are aggregated and executed on L2, and the state is periodically committed to L1 in a batch without immediate verification. Instead, it assumes transactions are valid by default (hence &quot;optimistic&quot;) unless challenged with fraud proof.</p><p>Fraud proof is an interactive protocol between the challenger (a full node) and the operator responsible for submitting the state (proposer), and includes the following steps:</p><ul><li><p>The challenger suspects that a state transition processed by the rollup is incorrect and submits the challenge together with justification.</p></li><li><p>The proposer responds with a counterargument.</p></li><li><p>Depending on the protocol, there might be several rounds of responses.</p></li><li><p>Eventually, the process resolves, either because one party fails to respond in time or because the evidence is conclusive.</p></li><li><p>After the dispute is resolved, the state transition is either confirmed or the rollup is rolled back to the last valid state.</p></li></ul><p>There are two main types of challenges: single and multi-round.</p><p>Previously, Optimism used <strong>single-round challenges.</strong> This involved re-executing the questioned transaction on L1. However, this approach required the rollup to store all state transitions, which was data-intensive. Moreover, since all transactions were re-executed on L1, it also demanded significant amounts of gas, making it expensive. For these reasons, and to enhance security, Optimism has paused the ability to post fraud proofs and has been working on an alternative solution for almost two years.</p><p>Arbitrum uses interactive <strong>multi-round challenges</strong>. In this system, when a dispute arises, the parties recursively break down the block into segments, and the segments are isolated one by one to identify the incorrect transaction. This method is known as a bisection protocol.</p><img src="https://images.mirror-media.xyz/publication-images/2nlv5ZTzayABCBUI7gR_L.gif?height=267&amp;width=498" alt="Bisection successful" title="null" class="image-node embed"><p>In optimistic rollups, the security depends on having just one honest node. If this node catches any fraudulent transactions, it can submit fraud proof to challenge them. This means that optimistic rollups operate on a fairly low trust model, where only a single honest participant can keep the system secure.</p><p>Currently, however, users must place significant trust assumptions while entering an optimistic rollup. In an ideal setup, the ability for anyone to submit fraud proof would be a key feature. The reality is different. Many rollups, even as big as Optimism, are still in the process of developing their systems to accept fraud proofs, which means that such a critical mechanism isn&apos;t available.</p><p>On the flip side, Arbitrum has put in place a system where only specific approved entities can submit fraud proofs, with L2BEAT being an example of one such entity. Assuming these entities are independent of the rollup&apos;s creators, this arrangement needs significantly less trust.</p><div class="relative header-and-anchor"><h3 id="h-data-availability"><strong>Data Availability</strong></h3></div><p>Rollups work by processing transactions off the L1 blockchain and then posting either fraud (in case of incorrect state transitions) or validity proofs back onto L1. Data availability plays here a crucial role as for transactions to be verified, the transaction data must be available. This availability allows nodes to rerun the transactions, confirm their validity and, if required, submit fraud proof. This mechanism is the backbone of integrity in optimistic rollups.</p><p>Fraud proofs also are the reason why withdrawing funds from optimistic rollups takes such a long time. The funds need to be locked, usually for seven days, to allow enough time for the transactions to be checked for correctness. However, there are workarounds like using bridges that operate full nodes; they can instantly verify transactions and confirm their validity, which allows them to take risks on behalf of a user.</p><img src="https://images.mirror-media.xyz/publication-images/TVuMgnkOvJB0_tp9irxC4.gif?height=384&amp;width=638" alt="Me waiting for withdrawal from an optimistic rollup (j/k, I do it via CEX)" title="null" class="image-node embed"><p>With zk-rollups, the process is simpler. Here, the operator posts a validity proof directly on L1. This proof confirms that all transactions are correct as soon as they are posted. However, validity proofs don&apos;t address one issue: recovering the state of the rollup. For this reason, the zk-rollups must also ensure that data is made available.</p><p>The challenge of storing a vast amount of transaction data in a publicly accessible way is known as the data availability problem and it lies at the heart of the blockchain trilemma. Discussing solutions to the data availability problem goes beyond what we cover today. Still, if you remember Reed-Solomon codes from my earlier pieces on zk-STARKs, you&apos;re on the right track.</p><p>Traditionally, rollups have posted their data directly on L1 blockchains. However, as the concept of modular blockchains gains traction, new solutions are emerging:</p><ul><li><p>Blockchains like Celestia are built specifically to solve the data availability problem. They provide a dedicated space for storing and accessing data.</p></li><li><p>Solutions like EigenDA, secured by Ether that&apos;s restaked with EigenLayer, offer high-throughput options for managing data availability.</p></li></ul><p>L2BEAT assesses how and where data is made available. This can significantly differ from one project to another:</p><ul><li><p><strong>Arbitrum and Optimism</strong> make transaction data fully accessible on Ethereum.</p></li><li><p><strong>zk-Rollups</strong> only publish the data necessary to recover state changes. An exceptions are Polygon zkEVM, Scroll, or Linea, which post the entire transaction set.</p></li><li><p><strong>Validiums</strong> store the transaction data off-chain and manage it through committees rather than directly on-chain.</p></li></ul><div class="relative header-and-anchor"><h3 id="h-exit-window"><strong>Exit Window</strong></h3></div><p>As we know, exiting an optimistic rollup involves a delay to account for the possibility of a successful fraud proof, while with zk-rollups exits happen right away. However, the L2BEAT risk assessment category highlights a separate problem: the risk that comes with malicious updates to the rollup&apos;s smart contracts and whether users are given sufficient time to withdraw their funds when they choose to.</p><p>The architecture of rollup consists of several types of smart contracts:</p><ul><li><p><strong>Core</strong>: Responsible for managing the state root (the summary of the current rollup state), processing transactions, and facilitating communication between L1 and L2.</p></li><li><p><strong>Bridge</strong>: Enable the movement of assets between the L1 and L2. Needed for users to deposit and withdraw funds.</p></li><li><p><strong>Governance and Upgrades</strong>: Often combined with timelocks, provide a process for proposing, voting on, and implementing changes.</p></li><li><p><strong>Verification</strong>: In optimistic rollups, verification contracts manage the fraud proofs. In zk-rollups, handle the verification of validity proofs.</p></li><li><p><strong>Escrow</strong>: Manage the holding and transferring of assets within the rollup.</p></li></ul><p>The upgradability of smart contracts introduces both flexibility and vulnerability. Currently, the update feature is typically managed by a multisig, so the integrity of the rollup is dependent on the security of this multisig:</p><ul><li><p><strong>Arbitrum</strong> uses a 9 out of 12 multisig. The public identity of its participants gives transparency but also makes them easy targets for malicious attacks.</p></li><li><p><strong>Optimism</strong> uses a 5 out of 7 mulisig. The identities of the participants are private.</p></li></ul><p>The ability to upgrade smart contracts ideally includes a delay between announcing changes and implementing them, providing users with a chance to leave the rollup if they&apos;re wary of malicious updates or don&apos;t agree with the changes. Yet, as highlighted by L2BEAT, the reality is that many rollups lack any safeguards against the misuse of their upgrade capabilities, meaning that the changes to the smart contracts apply immediately.</p><p>Arbitrum stands out with a three-day waiting period for any contract changes. However, this delay can still be overridden by the Security Council. During this standard waiting period, users have a two-day window to push a transaction through to L1 and exit the rollup.</p><img src="https://images.mirror-media.xyz/publication-images/1nmnf9rpxdOOqCpBytgRo.gif?height=217&amp;width=400" alt="When you exit straight to L1" title="null" class="image-node embed"><div class="relative header-and-anchor"><h3 id="h-sequencer-proposer-failure"><strong>Sequencer / Proposer Failure</strong></h3></div><p>If a sequencer or proposer encounters problems, it can significantly disrupt a rollup. Here’s a breakdown:</p><ul><li><p><strong>Sequencer:</strong> Collects, orders, and processes transactions, updating the rollup&apos;s state. A failure in its operations can lead to delays in transaction processing, loss of transaction order integrity, and halts the rollup&apos;s ability to update its state.</p></li><li><p><strong>Proposer</strong>: Responsible for submitting transaction batches and their state roots to L1. A failure on the part of the proposer includes submitting incorrect state roots or failing to post transactions to L1. The requirement for proposers to post a bond aims to reduce this risk by providing a financial disincentive for fraudulent or negligent behavior.</p></li><li><p><strong>Verifiers</strong>: Full nodes in optimistic rollups or a verifier contract in zk-rollups. They ensure the correctness of transactions and state transitions.</p></li></ul><p>With an understanding of the roles involved, let&apos;s walk through a typical day in the life of a transaction:</p><ol><li><p>A user initiates the process by submitting a transaction to the rollup.</p></li><li><p>The sequencer picks up the transaction, orders it with others, and processes the batch, calculating the new rollup&apos;s state.</p></li><li><p>The proposer confirms the integrity of the batch and submits it to L1 with the new state root.</p></li><li><p>Verifiers check the correctness of the transaction and its inclusion in the state root.</p></li><li><p>If no issues are detected (including the potential fraud proof submission), the transaction is considered finalized on L1.</p></li></ol><p>Most rollups currently offer the option to submit transactions directly to L1 via a bridge contract. This can be done either from within the rollup or directly on L1. However, this solution has limitations if the transaction includes assets native to the rollup, which may not be interoperable with L1. Moreover, if the operators don’t perform their roles, any funds locked in various protocols would not be possible to be moved.</p><p>Arbitrum provides a mechanism allowing users to self-propose blocks if the proposer has been inactive for 6 days and 8 hours to address potential proposer failures. Optimism currently doesn’t have a similar feature, which means users don’t have options for direct intervention if the proposer fails to act.</p><p>Aiming for decentralization of the operators is seen as a way to increase the security of rollups. However, decentralization introduces other challenges, such as potential delays in transaction processing, and an increased surface for MEV.</p><div class="relative header-and-anchor"><h3 id="h-stages"><strong>Stages</strong></h3></div><p>L2BEAT, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethereum-magicians.org/t/proposed-milestones-for-rollups-taking-off-training-wheels/11571">with some help from Vitalik</a>, grouped rollups into three tiers based on the security considerations discussed above. Here&apos;s an overview of how these stages are defined.</p><p><strong>Stage 0: Full Training-wheels. The rollup is operated by the creators:</strong></p><ul><li><p>Self-identification as a rollup.</p></li><li><p>Posting L2 state roots on L1 for withdrawals.</p></li><li><p>Providing data availability.</p></li><li><p>Open source software to reconstruct the state available.</p></li></ul><p><strong>Stage 1: Limited Training wheels. Governance begins to transition to smart contracts:</strong></p><ul><li><p>Use of a proper proof system.</p></li><li><p>At least 5 external actors can submit fraud proof.</p></li><li><p>Users can exit without the operator&apos;s coordination.</p></li><li><p>At least a 7-day exit window for users in case of unwanted upgrades.</p></li><li><p>A well-structured Security Council, with at least a 75% consensus threshold and diversity in membership.</p></li></ul><p><strong>Stage 2: No Training Wheels. The rollup is fully operated through smart contracts.</strong></p><ul><li><p>Council acts only in case of undeniable bugs e.g. failure to submit valid proof.</p></li><li><p>Temporary control to the council in specific, bug-related scenarios.</p></li><li><p>Upgrades permitted with a minimum 30-day delay.</p></li></ul><img src="https://images.mirror-media.xyz/publication-images/jon5QeFx5FI_ciz_VRXyX.png?height=948&amp;width=2406" alt="This TVL is not secured well" title="null" class="image-node embed"><div class="relative header-and-anchor"><h3 id="h-summary">Summary</h3></div><p>With Ethereum&apos;s shift towards a rollup-centric roadmap, the security of rollups has become crucial for both users and the broader crypto ecosystem. Despite advancements, there remain significant security gaps and trust assumptions in many widely used rollups.</p><p>Optimistic rollups were the first to launch, with both Optimism and Arbitrum becoming available to the public in 2021. The tech behind optimistic rollups is more mature, with Arbitrum making significant progress in its security. Optimism, while significantly lagging in security aspects, has shifted its focus towards improving the interoperability of its OP stack, which allows for the creation of other rollups using Optimism&apos;s technology. Despite security concerns, users appear relatively unbothered by these shortcomings.</p><p>On the ZK rollup front, Starknet, based on STARK technology, launched in 2021, marking an early entry. The first SNARK-based ZK rollup, zkSync, launched only in Q1 2023, making it a new kid on the block(chain). This freshness is evident in the risk assessments, which show that many security issues are yet to be addressed.</p><p>In summary, while both types of rollups advance the scalability and efficiency of Ethereum, they each come with distinct security considerations. Although we haven&apos;t yet experienced a major incident involving rollup security, the growing number of implementations suggests it&apos;s only a matter of time before we encounter some form of breach and loss of funds. L2BEAT work in monitoring the security of these systems is therefore essential for the users and the entire crypto space.</p><div class="relative header-and-anchor"><h3 id="h-sources"><strong>Sources</strong></h3></div><ol><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://l2beat.com/scaling/summary">L2BEAT</a></p></li><li><p>Ethereum documentation, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethereum.org/developers/docs/scaling"><em>Scaling</em></a></p></li><li><p>Yuan Han Li, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/blockchain-capital-blog/wtf-is-data-availability-80c2c95ded0f"><em>WTF is Data Availability?</em></a></p></li><li><p>Charles Yu, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.galaxy.com/insights/research/optimism-arbitrum-pt2-decentralization/"><em>Optimism &amp; Arbitrum: Tracking Decentralization Progress</em></a></p></li><li><p>James Prestwitch, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://prestwich.substack.com/p/the-definitive-guide-to-sequencing"><em>The Definitive Guide to Sequencing</em></a></p></li><li><p>Luca Donno, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/l2beat/introducing-stages-a-framework-to-evaluate-rollups-maturity-d290bb22befe"><em>Introducing Stages</em></a></p></li></ol>]]></content:encoded>
            <author>rafal@newsletter.paragraph.com (rafal)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/9ccec155e199f609b991f74450d1168d.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[zk-STARKs: FRI protocol]]></title>
            <link>https://paragraph.com/@rafal/zk-starks-fri-protocol</link>
            <guid>REWaj1HObPrqTIlPM02s</guid>
            <pubDate>Sun, 24 Dec 2023 10:58:33 GMT</pubDate>
            <description><![CDATA[Jumping right into the second part of your ZK-STARK series, we&apos;re focusing on the FRI protocol and its goal of proving the knowledge of a low-de...]]></description>
            <content:encoded><![CDATA[<p>Jumping right into the second part of your ZK-STARK series, we&apos;re focusing on the FRI protocol and its goal of proving the knowledge of a low-degree polynomial. This protocol is a crucial element in the ZK-STARK framework.</p><p>In the first post on the ZK-STARK series, we:</p><ul><li><p>Defined the problem of proving the knowledge of the 12th number in the Lucas sequence.</p></li><li><p>Arithmetized the problem by building a trace and converting it to a polynomial.</p></li><li><p>Extended the domain of the polynomial by adding redundancy points.</p></li><li><p>Based on the extended domain, we introduced constraints which then formed a single composition polynomial.</p></li></ul><p>Since the composition polynomial is another, more sophisticated representation of the original problem and its solution, if we are to prove that we know this polynomial, we are automatically proving that we know the 12th number of the Lucas sequence.</p><p>If you haven’t read the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://rafal0x.substack.com/p/arithmetization-in-zk-starks">previous article</a>, I am encouraging you to do so.</p><p><strong>FRI theory</strong></p><p>FRI stands for <strong>F</strong>ast <strong>R</strong>eed-Solomon Interactive Oracle <strong>P</strong>roofs of Proximity. In more detail:</p><ul><li><p><strong>Fast:</strong> FRI has sublinear-time verification. This means that the verifier doesn&apos;t need to check the entire polynomial to be convinced that the prover doesn’t lie. Instead, the verifier can check a small portion of the function (randomly chosen) and still be confident about the overall correctness.</p></li><li><p><strong>Reed-Solomon:</strong> refers to Reed-Solomon codes that use redundancy and polynomials to recover lost pieces of data. We can recover the polynomial of degree with only n+1 points. In the FRI context, the Reed-Solomon code means a polynomial.</p></li><li><p><strong>Interactive Oracle Proof (IOP</strong>): In an IOP, the prover sends an oracle (a kind of &quot;black-box&quot; function) to the verifier, who can then query this oracle to decide whether to accept or reject the proof. The interaction can occur in multiple rounds, where in each round, the prover sends an oracle based on the verifier&apos;s previous queries.</p></li></ul><img src="https://storage.googleapis.com/papyrus_images/c440c099ea762c6f7ab2b9a47060eb50.jpg" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAIAAAD4YuoOAAAACXBIWXMAAAsTAAALEwEAmpwYAAAGG0lEQVR4nAEQBu/5ADg4RVRVYFdXYiIhMU9OYS8qOTATJCkNGyINFiYSHTsZKzQuN09WYVRfbCgtNwEGGSYnOSQjLi0rNy8uOiYkLSIiLjg3SF14YD1MRx0bKCYmLjU2SI+bv42kt5qqyKCutgAwKzt6cnp+eIEWEh4JChoYFyQ0GSgpDRkbBhI0GCY8FytISVVpd4heZ3hMTFhPTlxDRlIVFiEcGyYoJTE2ND0nJzMsKDtNb141UkUmJTM8PUovND2KkaqMm6hRV2mBgocAKiYzXVtjc3B6Dg4WCQsaCg0YMRgoNRYnIAsYNRcnQB0vTVhhfo2lZnKApo+U8sjDvqCcMzI9FhgkGxokJiUuNDE7Lio5PltMMVA/PDtKMTE/R05mUlRvNjVEKSg7eHZ/AB4dJ0lHU05LVgsLExsYJhQTHyUUJS8RIh0JFjwYLzsgMGd5hIKRq3eCk5Z7d62IgaqJgWVbZSQnOA4LFxkXISglMi0oNzs/P5CCdpWFiiwuQD5DXycnOiEjLCMlMktNVQA3LDNFNjwkIzM+PkNEQUcvLzcwHy8nDiIgFCgnESU4L0JzhpVdeHpmdWuOcnF+YmKIbGeJc3U0NUgcGiUTDxwXEiEYFiRcS1CviYVrV1UlJjoyNkkhIi4kIzMgHygKChYAV1BgVUROQjtFXEtRXUtVVENLNCxAISpPUFBmi2dpf3SNj5vALVc7O2I6hnBqjGxsh2xocWRpNjZJKSczJiQwGBYhCAgSJR8eb1ZWZFFSKCc3IyU4FxUjIh0nFxchCgoXADVHaSUxUVNATItiaY9kbnJQWDQ9XkFZj2pkeJRsbJKHnp+r1UFjSjJWPTAzP1RBQVpLR0NEUy0uPCQiLCsnNSYkLyIgKSUmKCQdIF9JTiomMxASHhYWJRQTIQUHEAsNFwA1RmooOlxyVWOUZm2NXmqKXGNNTWlFV4VKTWpuXWiTiauAeqFBUGY/Q2MYIDYzLjtTREM0NEc+P1YiIjEiICkeHScqJzVpZWY5OjgjHSYcGyUGCBMQEiAVFyUPDx0KChcANkZoJDRVV0JKlmltjF5naktVPEhyN0p3S1yAkoaxkm6jVUBpNDthPUJoJyxLDhIiPCk7HRkzP0ZpS0dqRDpMOTk8VVFVenNxXVxZKis0FBMfAgINCQoaGRgqJCM0JiU1AJ+kvb681nBkblY8PWFHRzwsMlFeeW91nXpnnIVmnXlMe0M3XiMoRzM4WjM4WCkjPFY4WyYePS40Uzg3V3xfh4Byf3BsZH52c4SBfTEyOQUHEwMEDAADCQMFDw8QHR4cKgDOy9///P/p4PqAdoVKPENPQktmV3SigbR8VIVgPmZWPWY8J0cfJUEtNFYrM1M1MUp0TnM8NE8nMlE6NVRoRm2CYJGCbYJ/fHKGgXsgISgJCBsPEB4GBxEAAwgAAgcCAwoANz1UubfO8Oz/5t720MfcnY2qbU5+bEJxUi9VZlByZlVuDwkhHSM9KzFPJzFQMzFLf1qFTzxcIytDNTJOSjFTXUNtclWDgW54gX56GRskDw4gFRUkExIiEBAgCwsXAgQMAAgNJWlsgO3o/uPb9Pjv/8e511M5XlkwUl1FZdbV6s3J3goOJh0iOykwSigyTS8oQGhBZ1hAZxwiPFhWZFtVW0krSE84X2tXbJOMjlBRYgoKGh0bKCIgMSEfMBgaKgQHHAAPDiFUVGGcl62vqsDAudHFwdaBboxMMlhYOWGek7DW0ecmJkEAAh4XHDYRGTMrIzxvSnJKK1ADBCFCQVBrUGRRN19bRWNxaGZ9eX9zcoUWGSsAAhMYGCgPDyAQEiUPFiwATExSra2tr6+x0NDR1NTY1NTWvb3AsbG3wbjAuri+urq/m5ujra+ztLS3xMTIyMXImIiSrqirwsHErquvjoWQxL/Gop6hxMTBtLS0xcXItra7kpSZkZKVu72+qqqseYGHAE9OVJSUlZWVmIWDiIF/g5SRkoqJi6qprry5wJeNmZSNkqOUlISCiIGDjIeHj5eTo4B0kImCmImDjXh4gLu2u8LCwZeUkuLi5tra5NXV29na36agoYN5eZuUk46JiHiiiy3JAzONxeHrAAAAAElFTkSuQmCC" nextheight="359" nextwidth="695" class="image-node embed"><ul><li><p><strong>Proximity:</strong> In the FRI protocol the prover doesn’t prove that he knows any polynomial which intersects a certain set of points. There may be more than one polynomial that meets the criteria. The prover should know the polynomial of the degree n, but in fact, knowing a polynomial of degree close to n is good enough. Proximity refers to this closeness in degree with the given polynomial.</p></li></ul><p>If the prover doesn’t need to prove low-degreness of the polynomial entirely, but only approximately, the first questions that come to mind are: what is a low degree, how close is close enough, and why.</p><ul><li><p>Low degree: in a STARK low degree depends on the degree of the composition polynomial and the length of the trace. In our case, the low degree is sixteen (the degree of the extended domain polynomial). For a more complex problem, it can be a few orders of magnitude more.</p></li><li><p>Closeness: for polynomials p and f, distance is defined as the number of points that both f and p do not match on. If the distance between two functions is small, the closeness is high, and vice versa. Small in this situation depends on the degree of both polynomials.</p></li></ul><p>The concept of proximity is not new and has been explored before in probabilistically checkable proofs of proximity (CPPs). The CPPs however get inefficient and less sound when the number of points to check increases. FRI protocol addresses these issues. Let’s explore how.</p><p><strong>Vitalik’s STARK</strong></p><p>Before we go deeper into the construction of FRI, let’s start with a simple example of a STARK presented by Vitalik in his <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://vitalik.ca/general/2017/11/22/starks_part_2.html">article</a> on FRI. This will help us conceptually grasp what the whole thing is about. The part I’m referring to is available in the section “<em>A First Look at Sublinearity</em>**”** and can be summarized as follows:</p><ol><li><p>The goal is to prove that a large set of points (say, 1 billion) all lie on a polynomial of a certain degree (e.g., less than 1,000,000) without having to check every single point.</p></li><li><p>To achieve this, Vitalik introduces the concept of a bivariate polynomial. This polynomial is constructed such that when evaluated with specific values of <em>x</em> and <em>y</em>, it matches the original polynomial <em>f</em>(<em>x</em>). Specifically, <em>g</em>(<em>x</em>,<em>x</em>1000) = <em>f</em>(<em>x</em>).</p></li><li><p>The prover evaluates <em>g</em>(<em>x</em>,<em>y</em>) over a large square. The diagonal of this square represents the values of <em>g</em>(<em>x</em>,<em>y</em>) that match the values of <em>f</em>(<em>x</em>).</p></li></ol><img src="https://images.mirror-media.xyz/publication-images/vzxJUnXhWstODlCK-NGW_.png?height=1010&amp;width=1528" alt="" title="null" class="image-node embed"><ol><li><p>Instead of checking every point, the verifier selects a few rows and columns from this square. For each, he asks for a sample of points, ensuring that at least one point from each sample lies on the diagonal.</p></li><li><p>The verifier checks that the points match the original data (using Merkle branches) and correspond to a polynomial of the desired degree.</p></li></ol><p><strong>Conclusion</strong>: By checking these samples, the verifier gets a statistical proof that:</p><ul><li><p>Most rows and columns are populated by points on the desired polynomial.</p></li><li><p>The diagonal line is mostly on the desired polynomial.</p></li></ul><p>This sampling and verification process allows the verifier to be reasonably confident that most points on the diagonal correspond to the desired polynomial without having to check every single point. This is where the sublinearity comes in: the verifier can achieve this confidence with a computational effort that grows much slower than the size of the dataset.</p><p>In this example, the prover has to evaluate the polynomial <em>g(x,y)</em> on every single point, which is not very efficient. A better prover efficiency can be achieved with the application of modular math, which Vitalik presents in the subsequent section.</p><p>In short, instead of evaluating <em>g</em>(<em>x</em>,<em>y</em>) at every point in a large square, the prover evaluates it at points in a smaller grid and then uses modular arithmetic to extrapolate the values in the larger grid. This approach significantly reduces the prover’s computational complexity.</p><p><strong>FRI practice</strong></p><p>Here we are approaching the FRI protocol. In Vitalik’s examples, while the prover’s computational complexity was reduced, the verifier still had a significant amount of work to do. The verifier had to check a large number of points to ensure that they lie on the correct polynomial, which is computationally intensive.</p><p>To address this issue, STARKs introduce the concept of folding. The idea is to use the FRI protocol within itself to reduce the verifier&apos;s workload.</p><p>Instead of the verifier checking a large number of points directly, the prover generates proof that a smaller number of points lie on the correct polynomial. The verifier then only needs to check this smaller set of points and the STARK proof, significantly reducing their computational complexity.</p><p>This approach reduces the verifier&apos;s complexity from quadratic to logarithmic in terms of the size of the data. This is a substantial efficiency gain, making the protocol much more practical for large datasets.</p><p>To see how this plays out we will use the composition polynomial calculated based on the polynomial constraints from the previous article. The constraints are:</p><p>$$$ f_0(x) = \frac{p(x)-7}{x-g^4} $$$</p><p>$$$ f_1(x) = \frac{p(x)-11}{x-g^5} $$$</p><p>$$$ f_2(x) = \frac{p(x) - g^{i-1} - g^{i-2}}{\prod_{i=6}^{i=18} (x - g^i)} $$$</p><p>$$$ f_3(x) = \frac{p(x)-37}{x-g^{19}} $$$</p><p>Recall that if the division on the right-hand side of the <em>f</em> polynomials leaves no remainder (i.e., the result is another polynomial), then the constraints are met. Let&apos;s represent the polynomials in the denominators on the right-hand with <em>z</em>.</p><p>The polynomial <em>p(x)</em>, constructed within the trace&apos;s extended domain mod 97, is defined as follows:</p><p>$$$ p(x) = 90x^{15} + 89x^{14} + 73x^{13} + 70x^{12} + 78x^{11} + 91x^{10} + 75x^9 + 33x^8 + 25x^7 + 51x^6 + 41x^5 + 41x^4 + 69x^3 + 43x^2 + 72x + 21 $$$</p><p>Now, with the below piece of code, we can calculate the constraint polynomials. Here for the first two constraints:</p><p><code>pip install galois import galois # Define the finite field GF(97) GF = galois.GF(97) # Define the polynomial p(x) with the coefficients coeffs = [90, 89, 73, 70, 78, 91, 75, 33, 25, 51, 41, 41, 69, 43, 72, 21] p_x_galois = galois.Poly(coeffs, field=GF) # Define the generator g and its powers for the constraints g = 5 g4 = pow(g, 4, 97) g5 = pow(g, 5, 97) # Define the numerators for the constraints numerator_f0 = p_x_galois - GF(7) numerator_f1 = p_x_galois - GF(11) # Define the denominators for the constraints denominator_f0 = galois.Poly([1, -GF(g4)], field=GF) denominator_f1 = galois.Poly([1, -GF(g5)], field=GF) # Perform the polynomial division for f0(x), f1(x), f2(x), and f3(x) quotient_f0, remainder_f0 = divmod(numerator_f0, denominator_f0) quotient_f1, remainder_f1 = divmod(numerator_f1, denominator_f1) # Print the results print(&quot;Galois implementation:&quot;) print(f&quot;f0(x) quotient:&quot;, quotient_f0) print(f&quot;f0(x) remainder:&quot;, remainder_f0) print(f&quot;f1(x) quotient:&quot;, quotient_f1) print(f&quot;f1(x) remainder:&quot;, remainder_f1)</code></p><p>$$$ \begin{align*} f_0(x) &amp;= 90x^{14} + 79x^{13} + 75x^{12} + 94x^{11} + 46x^{10} + 32x^9 + 93x^8 + 55x^7 + 62x^6 + x^5 + 84x^4 + 64x^3 + 8x^2 + 96x + 29 \ f_1(x) &amp;= 90x^{14} + 39x^{13} + 19x^{12} + 81x^{11} + 33x^{10} + 8x^9 + 49x^8 + 92x^7 + 17x^6 + 20x^5 + 73x^4 + 22x^3 + 46x^2 + 39x + 18 \ f_2(x) &amp;= 76x^{12} + 11x^{11} + 21x^{10} + 78x^9 + 24x^8 + 45x^7 + 55x^6 + 53x^5 + 32x^4 + 21x^3 + 26x^2 + 65x + 68 \ f_3(x) &amp;= 90x^{14} + 17x^{13} + 40x^{12} + 38x^{11} + 67x^{10} + 18x^9 + 80x^8 + 66x^7 + 11x^6 + 81x^5 + 15x^4 + 29x^3 + 7x^2 + 18x + 77 \end{align*} $$$</p><p>To finalize the process, let’s calculate the composition polynomial using the α values from the verifier. The composition polynomial is denoted as:</p><p>$$$ c(x) = \alpha_0 \cdot f_0(x) + \alpha_1 \cdot f_1(x) + \alpha_2 \cdot f_2(x) + \alpha_3 \cdot f_3(x) $$$</p><p>The alpha values are: <em>α0</em> = 39, <em>α1</em> = 93, <em>α2</em> = 47, and <em>α3</em> = 28. The resulting composition polynomial:</p><p>$$$ c(x) = 56x^{15} + 30x^{14} + 2x^{13} + 74x^{12} + 32x^{11} + 52x^{10} + 45x^9 + 88x^8 + 47x^7 + 25x^6 + 70x^5 + 37x^4 + 63x^3 + 56x^2 + 44x + 4 $$$</p><p>This polynomial <em>c(x)</em> represents the sum of the constraint polynomials <em>f0, f1, f2</em>, and <em>f3</em>, each multiplied by their respective α values. It also has been normalized to have degree 15, which allows us to have a more efficient folding mechanism that will come in handy when using the FRI protocol.</p><p>Now, after the commitment by the prover, we finally have arrived to the point when we can put the FRI protocol in action.</p><p><strong>FRI querying</strong></p><p>In the querying stage, the verifier&apos;s role is to check if the prover&apos;s polynomial is of a low degree and is related to the trace. Here&apos;s a breakdown of how it works:</p><p><strong>Constraint verification</strong></p><ul><li><p>The verifier picks random points in a domain larger than subgroup <em>G</em>. This is done to preserve the zero-knowledge aspect.</p></li><li><p>At each point, the prover evaluates the trace polynomial and the constraint polynomials</p></li><li><p>By calculating:</p><p>$$$ z_i(x) = p(x) - g^i \cdot f(x) $$$</p><p>and finding them to be vanishing polynomials, the verifier confirms that the constraint polynomials are related to the trace polynomial.</p></li></ul><p>To illustrate, consider the first constraint:</p><p>$$$ f_0(x) = \frac{p(x)-7}{x-g^4} $$$</p><p>The verifier picks a random number, say 54, and compares if both sides of the below equation match. If yes, the verification is successful.</p><p>$$$ p(x) - 7 = x - g^{4} \cdot f_{0}(x) $$$</p><p>Let’s substitute. The left-hand side, calculated by the prover:</p><p>$$$ p(54) = 61 \quad \text{and} \quad 61 - 7 = 54 $$$</p><p>And the right-hand side, calculated by the verifier:</p><p>$$$ f_{0}(54) \times (54 - 43) = 49 \times 11 = 54 $$$</p><p>Since both sides are equal, the verification is successful, and the constraint holds. Note that the calculations are performed mod 97.</p><p>This process is repeated for other values and constraints. Importantly, the verifier only knows the right-hand side evaluations, preserving zero-knowledge. This step also ensures the prover cannot simply invent numbers, as the verifier&apos;s calculation must align.</p><p>Finally, with the constraints verified, the verifier confirms the polynomial&apos;s relation to the trace. Now is the time to confirm its low-degree nature.</p><p><strong>Low-degree testing</strong></p><p>Low-degree testing is vital for the soundness of the protocol. Without it, the prover could potentially use a high-degree polynomial that matches specific points on the composition polynomial <em>c</em>(<em>x</em>) to pass the verifier&apos;s checks. This is possible because a high-degree polynomial, due to its many oscillations, can be adjusted to pass through given points, unlike a low-degree polynomial.</p><p>The testing is performed with the so-called FRI operator. The FRI operator is instrumental in reducing the complexity of proving that a polynomial is of low degree. This is important because, in another way, the prover would have to send the entire polynomial or evaluations of the polynomial over some domain, which would be very costly.</p><p>Here&apos;s how the FRI operator works:</p><p>The operator first splits a given polynomial <em>c</em>(<em>x</em>) into even and odd parts, so:</p><p>$$$ c(x) = g_0(x^2) + xh_0(x^2) $$$</p><p>In our example. The even part:</p><p>$$$ g_0(x^2) = 30x^7 + 74x^6 + 52x^5 + 88x^4 + 25x^3 + 37x^2 + 56x + 4 $$$</p><p>And the odd part:</p><p>$$$ h_0(x^2) = 56x^7 + 2x^6 + 32x^5 + 45x^4 + 47x^3 + 70x^2 + 63x + 44 $$$</p><p>The prover receives a random value <em>α</em> from the verifier.</p><p>A new polynomial <em>c1</em>​(<em>x</em>) is created using a linear combination of <em>g</em>0​(<em>x</em>) and <em>h</em>0​(<em>x</em>), where <em>α</em> is used as a coefficient for the odd part. This reduces the polynomial&apos;s degree by half.</p><p>$$$ c_1​(x)=g0​(x)+αh0​(x) $$$</p><p>This process is repeated with each iteration halving the degree of the polynomial. For instance, after the second iteration with <em>α</em>=72, the polynomial becomes <em>c2​</em>(<em>x</em>), and so on.</p><p>After a logarithmic number of iterations, this process results in a constant or a very low-degree polynomial. In our case for <em>α</em>=69, the polynomial:</p><p>$$$ c_3(x) = 17x^3 + 29x^2 + 22x + 69 $$$</p><p>After the third iteration and for <em>α</em>=75 we get:</p><p>$$$ c_4(x) = 58x + 56 $$$</p><p>With each round, the prover commits to the newly formed polynomial using a Merkle Tree.</p><p>The verifier then checks if the FRI operator has been correctly applied by mirroring the process and aiming to arrive at the same constant. In our case, 50.</p><p>The verifier selects a point <em>z</em> (e.g. 109) from a larger domain, ensuring it’s not part of the subgroup G.</p><p>The prover evaluates the composition polynomial at <em>z</em> and −<em>z</em>, returning values <em>c</em>(<em>z</em>)=27 and <em>c</em>(−<em>z</em>)=−53.</p><p>With <em>c</em>(<em>z</em>) and <em>c</em>(−<em>z</em>), the verifier can find <em>g0</em> and <em>h</em>0 by calculating:</p><p>$$$ c(z) = g_0(z^2) + zh_0(z^2); \text{ where } g_0(z^2) = 27 $$$</p><p>$$$ c(-z) = g_0(z^2) - zh_0(z^2); \text{ where } h_0(z^2) = 53 $$$</p><p>Using these values, the verifier computes the formula:</p><p>$$$ c_1(z^2) = g_0(z^2) + \alpha_0 h_0(z^2) $$$</p><p>and requests the prover to provide the corresponding Merkle path for <em>c</em>.</p><p>The verifier continues the process for the next iteration by querying:</p><p>$$$ c_1(-z^2) \text{ and solving for } g_1(z^n) \text{ and } h_1(z^n) $$$</p><p>The verifier can compute now:</p><p>$$$ c_2(z^n) = g_2(z^n) + \alpha_2 h_2(z^n) $$$</p><p>The verifier repeats this process for subsequent iterations, each time using a previously chosen scalar <em>α</em> and solving for the components of the polynomial.</p><p>The verifier then checks if the final value matches the constant provided by the prover in the commitment round. This confirmation validates the proof.</p><p>Since both parties arrived at the constant value of 50, the verifier is convinced that the polynomial <em>c(x)</em> is of a low degree.</p><p>The below code runs the perspective of the prover and the verifier. I encourage you to run the code to see what the process for both parties looks like at each step.</p><p><code>import galois # Define the finite field GF(97) GF = galois.GF(97) # Define the initial polynomial p(x) coeffs_p = [56, 30, 2, 74, 32, 52, 45, 88, 47, 25, 70, 37, 63, 56, 44, 4] p = galois.Poly(coeffs_p[::-1], field=GF) # Coefficients are in reverse order for galois.Poly # Define x as a polynomial x = galois.Poly([1, 0], field=GF) # x # The alpha values used in each iteration alpha_values = [72, 69, 75, 83] print(&quot;&quot;) # Function to apply the FRI operator, using alpha values from the list def apply_fri_operator_verbose(p, alpha_values, GF): for alpha in alpha_values: # Splitting p into even and odd coefficients coeffs_even = [p.coeffs[i*2] if i*2 &lt; len(p.coeffs) else GF(0) for i in range((len(p.coeffs) + 1) // 2)] coeffs_odd = [p.coeffs[i*2 + 1] if i*2 + 1 &lt; len(p.coeffs) else GF(0) for i in range((len(p.coeffs) + 1) // 2)] # Creating even and odd polynomials g = galois.Poly(coeffs_even, field=GF) h = galois.Poly(coeffs_odd, field=GF) print(f&quot;Prover applying FRI Operator with alpha = {alpha}&quot;) print(f&quot;Even part (g) = {g}&quot;) print(f&quot;Odd part (h) = {h}&quot;) # Apply the FRI operator p = g + alpha * h print(f&quot;Resulting polynomial = {p}\n&quot;) return p # Apply the FRI operator with the list of alpha values final_result = apply_fri_operator_verbose(p, alpha_values, GF) print(f&quot;Final Prover Result: {final_result}\n&quot;) # Function to simulate the verifier&apos;s computation in each FRI iteration def verifier_fri_computation_verbose(p, alpha_values, GF, z): for alpha in alpha_values: # Splitting p into even and odd coefficients coeffs_even = [p.coeffs[i*2] if i*2 &lt; len(p.coeffs) else GF(0) for i in range((len(p.coeffs) + 1) // 2)] coeffs_odd = [p.coeffs[i*2 + 1] if i*2 + 1 &lt; len(p.coeffs) else GF(0) for i in range((len(p.coeffs) + 1) // 2)] # Creating even and odd polynomials g = galois.Poly(coeffs_even, field=GF) h = galois.Poly(coeffs_odd, field=GF) # Apply the FRI operator p_next = g + alpha * h # Evaluate at z and -z (square z in each iteration) z_squared = z**2 % GF.order result_z = p_next(z_squared) result_minus_z = p_next(-z_squared % GF.order) print(f&quot;Verifier iteration with alpha = {alpha}&quot;) print(f&quot;p(z) = {result_z}, p(-z) = {result_minus_z}&quot;) print(f&quot;g = {g}, h = {h}&quot;) print(f&quot;Next polynomial p_next = {p_next}\n&quot;) p = p_next # Update polynomial for next iteration z = z_squared # Update z for next iteration return p(z) # Final result # Random point z for verification (excluding the subgroup G) z = 109 # Verifier&apos;s computation verifier_result = verifier_fri_computation_verbose(p, alpha_values, GF, z) print(f&quot;Final Verifier Result: {verifier_result}&quot;)</code></p><p><strong>Decommitments</strong></p><p>Let’s summarize where in the protocol the prover makes Merkle tree commitments and provides them to the verifier.</p><ul><li><p>After the prover calculates <em>p</em>(<em>x</em>) that maps inputs <em>G</em> to the trace and creates the composition polynomial <em>c</em>(<em>x</em>), the prover commits to both polynomials and sends the roots to the verifier.</p></li><li><p>During the low-degree testing, the prover applies the FRI operator to reduce the polynomial’s degree. After each transformation, the prover commits to the polynomial and sends its root to the verifier. In our case, the prover sends commitments to the polynomials <em>c1</em>, <em>c2</em>, and <em>c3</em>.</p></li></ul><p>Upon confirming that the Merklee roots provided by the prover are the same as the ones computed by the verifier the verification ends. Based on the constraints checks, low-degree testing, and decommitment processes the verifier can confirm if the claim made by the prover in the original statement is true.</p><p><strong>Summary</strong></p><p>We&apos;ve made it! Now, let&apos;s take a moment to review the entire protocol, together with the parts we covered in the previous article:</p><ol><li><p><strong>Definition of the Problem</strong></p><ul><li><p>The prover and verifier agree on a computational integrity (CI) statement and the corresponding polynomial constraints. In our case, the CI statement is the Lucas sequence up to the 19th number.</p></li></ul></li><li><p><strong>Arithmetization</strong></p><ul><li><p>The prover constructs a polynomial <em>p</em>(<em>x</em>) that maps a subgroup <em>G</em> to the trace, which is a sequence of integers in the CI statement.</p></li><li><p>The prover extends the polynomial <em>p</em>(<em>x</em>) to a larger domain.</p></li><li><p>The prover combines the constraints with <em>p(x)</em> to create a constraint polynomials <em>f</em>(<em>x</em>).</p></li><li><p>The prover forms the composition polynomial <em>p</em>(<em>x</em>) from <em>f</em>(<em>x</em>).</p></li><li><p><strong>T</strong>he verifier queries the prover for specific values of <em>p</em>(<em>x</em>) and <em>c</em>(<em>x</em>), along with Merkle paths.</p></li></ul></li><li><p><strong>Low-Degree Testing (FRI protocol)</strong></p><ul><li><p>The prover folds polynomial c(<em>x</em>), reducing its degree.</p></li><li><p>The verifier queries the prover for specific folded polynomial values and Merkle paths at each stage of FRI.</p></li></ul></li><li><p><strong>Summary and Validation</strong>:</p><ul><li><p>After the querying rounds, the verifier assesses the information provided by the prover. If the verifier&apos;s checks align with the prover&apos;s committed values and transformations, the CI statement is validated. This concludes the proof.</p></li></ul></li></ol><p>I must admit that my journey through KZG and FRI has been a rollercoaster. I had moments of doubt, but I&apos;m proud to have made it this far!</p><p>From my perspective, FRI is more complex than KZG, particularly regarding (de)commitments, which aren&apos;t necessary for KZG. This added complexity, including computational aspects, is balanced by the elimination of the need for a trusted setup. Moreover, from what I&apos;ve heard, FRI is more suitable for recursive proofs (so proofs of proofs), but I’m currently not experienced and knowledgeable enough to have any say on this.</p><p>In the next article about zero-knowledge proofs, I plan to better understand the concept of folding. This topic is currently generating significant buzz in the field, playing a crucial role in enhancing the efficiency of the proofs. Meanwhile, I want to express my gratitude for your time in reading this. Your attention means a great deal to me!</p><p><strong>Sources</strong></p><ol><li><p>Starkware, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://starkware.co/stark-101/"><em>STARK101</em></a></p></li><li><p>Aleksander Berentsen, Jeremias Lenzi, Remo Nyffenegger, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4308637"><em>A Walkthrough of a Simple zk-STARK</em></a></p></li><li><p>Vitalik Buterin, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://vitalik.eth.limo/general/2017/11/22/starks_part_2.html"><em>STARKs, Part II: Thank Goodness It&apos;s FRI-day</em></a></p></li></ol>]]></content:encoded>
            <author>rafal@newsletter.paragraph.com (rafal)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/c440c099ea762c6f7ab2b9a47060eb50.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Arithmetization in zk-STARKs]]></title>
            <link>https://paragraph.com/@rafal/arithmetization-in-zk-starks</link>
            <guid>B5067C3Qa52L4cgAVdkY</guid>
            <pubDate>Sun, 24 Dec 2023 10:01:14 GMT</pubDate>
            <description><![CDATA[In our last piece, we took a deep dive into polynomial commitment schemes, taking a closer look at the renowned KZG10 scheme. Despite many benefits o...]]></description>
            <content:encoded><![CDATA[<p>In our last piece, we took a deep dive into polynomial commitment schemes, taking a closer look at the renowned KZG10 scheme. Despite many benefits of KZG10, it has a notable shortcoming - the need for a trusted setup. Addressing this issue, we will shift our focus to transparent proofs, also known as zk-STARKs, which eliminate the need for any trusted party.</p><p><strong>STARKs</strong></p><p>zk-STARKs (Zero-Knowledge Scalable Transparent ARguments of Knowledge) are a type of cryptographic proof system that allows one party (the prover) to demonstrate to another party (the verifier) that a specific statement is true, without revealing any information about the underlying data or the statement itself. zk-STARKs are a subset of zero-knowledge proofs and offer several key characteristics that make them attractive:</p><ol><li><p><strong>Zero-knowledge</strong>: zk-STARKs enable provers to show the validity of a statement without revealing any information about the statement or the data it is based on, ensuring privacy in sensitive applications.</p></li><li><p><strong>Scalability</strong>: zk-STARKs are designed to handle complex statements and large datasets efficiently, making them suitable for applications that require high-performance cryptographic proofs.</p></li><li><p><strong>Transparency</strong>: Unlike SNARKs, zk-STARKs do not require a trusted setup. This makes them more secure and easier to deploy in decentralized systems like blockchains, where trust assumptions can be problematic.</p></li><li><p><strong>Post-quantum security</strong>: zk-STARKs are believed to be resistant to attacks from quantum computers due to their reliance on different cryptographic assumptions.</p></li></ol><p>STARKs leverage hash-based commitments, subsequently employing the FRI protocol to prove the low-degree nature of a polynomial. The acronym FRI stands for Fast Reed-Solomon Interactive Oracle Proof. The protocol was introduced by Eli Ben-Sasson and others in their 2016 publication, &quot;Fast Reed-Solomon Interactive Oracle Proofs of Proximity.&quot; Building upon this, the comprehensive zero-knowledge protocol was outlined in the 2018 STARK paper by the same team. This work laid the foundation for the establishment of Starkware, co-founded by Ben-Sasson.</p><p>With this knowledge of STARKs, let&apos;s delve deeper into the intricacies of their work.</p><div class="relative header-and-anchor"><h4 id="h-statement"><strong>Statement</strong></h4></div><p>Starting off, it&apos;s essential to identify the problem we are working with. In the realm of zero-knowledge proofs, we refer to this as a &quot;statement.&quot; This term is also used in the zk-STARK paper. Throughout this article, we will follow the STARK terminology, which might occasionally deviate from what&apos;s used in other SNARKs.</p><p>In our case, we are going to prove that we know the 12th number in the Lucas sequence (we don’t want to bore people with another example based on the Fibonacci sequence).</p><img src="https://storage.googleapis.com/papyrus_images/9c163dd15ea747b76a087a5a92da8974.gif" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAXCAIAAADlZ9q2AAAACXBIWXMAAAPoAAAD6AG1e1JrAAAIYUlEQVR4nCWUV1AbiBVFHxJgU6wCQhJVvYKEhHpFCBBqVAnRm2RkgSJTIyFjIxAYGUwz4Aaug9viol0X1h52iAczXtsbexNnmTg7TnbGk2zKz/5lJvnZjDZ/7+u+ue/c++D57fW9z9aWhzuW+pv/svv45b31l5vr3+8+/mrjTMhV3qkjtGtxipwEMhJExIM5AFoavrKIYhUwmpXcdg27XkquK0rzmYWzR53hnrZrkdDV6WCw03Ym4Ls5P/XVzUuwvxP99PXWvcXjs1771uXZl5sr0aWhd4+vb8wE5/sdjUp8myatWpBql2LbVYQ6IcXEIZVQ8WUMYhmDaGBkVuVTqjhEp44Z9rRM+5zXToWWAr5gp22yt3Pn9pU3W/fhw2+iH/ceP12bXvTV34r0RRf9PRbmqwfrH/e2t9ZOhl1lDjm6TYmzsFON7HQJAVWQiihAIQpSQIiOF2Hi8zEIWTa6SkD11er6HKbLJ49P+5xOo+rJ1XNvHm7uPbgF95ZP3Jge3FwIrg7Zu8spdTKCgZO00G9/Hd3YOj++EfYM1or7rIURt71DxuhVsBxUfEDPm6tTRSzSX8mZpaSMCmamnpJRI6COu5vurs6OOh2Ro679na3nm9f3nz+D8357sFkWnR86c9Tks7KbNTR/PS/UxFjqNwcd4ol2TdAh79bTTroqn050fVj1vTvl+uHiwB+Xva/CrSMlnCIMUopL1ZEIuryM4Ubzs2vnwz2t91dnXkXv/P33v/35Xz9CyGl0KHF9NeROPf5IeU6LNkdLP1AjxFZwEtWkZDU5ubIIa+FhW1TZ13ut385730QOR73W52Mt353pnamW8A8BOwmKcEmFafF1UtatuYlRZ/3GTOj99qOPX+98+mYPbs8O1isz1VSQ5cZJsqGUnSAkQBExTk1PFRITaIkgykSKs6FdmR1Use75qperZQEZZdrA3wo47h2tEqGAhgAeNo4eBxYefWHYM9Jhu7sy88Pr3e92tvZ3nsLW2lRrCZ+HQ+o4eHYGcNNAz8HXiKhyUpI4K56HQxQz0DY51lNCPdugfXfafcdVfqNdd6lBs1At2Z1s86iYOQBUJOQClDCyWor5bov2/fajnz68/8cf3v74uzcQXR0bdKgtwkw5BcUjgiAzTpKd1KJhVwpIZkGehomRkw7ISHEL3aY/r/nfzhx+fbLjgdd8ziHf9BhfTLVN1cryAOys7CY2ScfIqBERO/Tiz5Yju5vXf/rTfgxy2G2tU5H1XFSdkqqkpTAxkAOgJmPsEppNwfDVqmolFGEmcivcdd9tmjMJnw7WfLoS+Ou1kf0V7/PJtnVXmV+bv9FQvGiUmPi4alGaxygNtFVfHA+8jN55uxUFf2uJPh8nyU1o1bFlpKRDANkA3HRwqLj1ClZ/jbxFS5blJszWyuatklAJ73Kj9vNey+5Yy6vpricB27Ox1uiA7eERi1uap6bGmfkp9Up6oK1qbWxwbTzw4u4GlBVgZFS0knaoEB/TpaUCHoCVHuc0qZqLC5rVdFUeogAHfaUFMybZskF8Us2ZrxDc6TY+8tu+8Ns/Dzi+nfcu1aotvMRaSYpVkNxazDzeZTvhqo8cdX157QIYhOlyWrKUlMhEAxMDTBQwUkFGTiqPMSCJCaAhE6gJUC+krtqL50r4qybRpQbN9c6yq12Gq25jdKRpo9vcWEAw8xIcyiS7IsVZSgk0V3hryyZ7O86H/GBT5vGz4sgHgI4CUjxQE0HHSFJQEst5eQ4118LLGnaUi7KwXCwy6m/+MtAQHXKc79SfaVSfbdNe6TGt91iWnOUjdqmODI0qVAU30VKI8phZ7WXi8e6WS1OjoGWl5GcAFw/CHCQbB+x00HOxckoCKQ70HEy1CN+socrzDtIQ4FZzgpWqY2bpbINmuV137oj5xohrwVmx4qu5Pek+YqBbBQlmfnKNGO0y0IYbTdsb628fb0JFAYZPQFJTgIYGHhHyMxB0FKgYGUpqegkHU8bHGnk4axFBnIUQ4pB1Raw+vehEpWLJbdu+NH+hv3XVZz0/ZLs+3nVzyt2qzTVwEd0m1uJw262ZkZVA99njvWAS4nl44BHi+EQQ5iFy44ByEES5GHEuVpSVzEaDJAejouLYKOBgobdSt+Bp2bm8/Lc3L26EfZEO7WKPdcFjuhxsfbIycn/+13ZZZlsJPeJtnBtsX/YfXhvzgk2ebhHhZKSD+RnAy0TS0UAAwAKQ46GQmExLgvz0lFwAekIsYMe77P/8Zu/n//x7+/LCeKNq0VNxokF9caj+xkTXZqR352r46YXRYUfxWGdlb6V0wlUz7rSALA+pZqBYWGBigZMBfAKSggQG+oCGTWGlQy4CaInAxydnArDTE1sYud8/e/zfTx8jTsNqjynkUES6yi8M1F0aadoIddyYcG6e7n+4OrLqb/VVSQdqlVOHzcBKi6nwCMBAxwbGL00uwB+sKKIXEtFEAHoycNOQuQAdsgI7NnH7yoVXm+dOdejGG0uGLMJ5t3HRYzrdXXHKWRpuLx5v1Z32WB+c7l/wVkx26cfadLHUs7Ax+1JSvIAIRAAyMlYISiIIiSguFrhYJBUJTXLOtJzTx6G+3rx6dsDur5Z2KuihRu2MU3+qq3TULh2pEQftkjGHst8iCHeWz/Ya5r3WjbA71l4WGv7fAzkZwcLEdlCSgISIwaAlAgUJkpyUsJA1ALBxpP3h8tiC23SiQRkj7DaEm5QhuyzkUIzWy/3VkqBdcaxeMVgtnnQaFwccU91G4GWAgBgzQYDYk+D/YiIbYlu5aUCNj93NQUydysSPU7Kfzp04O9g477GM2CSRDt1EkzrkkE63a/xVRd4Kdp+1yGcuHKoS9VuKjjVoJl3GDj3zf+JYskzCpkCCAAAAAElFTkSuQmCC" nextheight="364" nextwidth="498" class="image-node embed"><p>Wondering what Lucas numbers are? The Lucas sequence begins with 2 followed by 1. After that, every number in the sequence is the sum of its two immediate predecessors. Here&apos;s how the sequence shapes up: 2, 1, 3, 4, 7, 11, 18, 29... and so on. If it reminds you of another well-known sequence, it&apos;s purely coincidental!</p><p>Computers are not fans of calculating massive numbers, so let&apos;s work within a finite field of 97. If the terms &apos;finite fields&apos; and &apos;modular arithmetic&apos; sound a bit rusty, take a look at our previous article linked <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://rafal0x.substack.com/p/exploring-zero-knowledge-proofs-part-0b2">here</a>. In essence, when we talk about operating in a finite field, it means that the integers we work with don&apos;t go on forever. Instead, they hit a limit (or a &quot;modulus&quot;) and then loop back to the beginning. Think of how clocks work within a finite field of 12 hours, or how a day goes in a finite field of 24 hours.</p><p>Now, while determining the 12th Lucas number doesn&apos;t inherently pose challenges, we&apos;re using the finite field of 97 for illustrative purposes. So, when working within this field, the Lucas sequence looks like this: 2, 1, 3, 4, 7, 11, 18, 29, 47, 76, 26… and so on. No number in this sequence will ever surpass 97.</p><p>In the context of our STARK, we will skip the initial four numbers, targeting the twelfth element as our final entry. This forms the basis of our statement. To phrase this more formally, given the modulo 97:</p><p>$$$ \begin{align*} a_0 &amp;= 7, \ a_1 &amp;= 11, \ a_n &amp;= a_{n-1} + a_{n-2}, \quad \text{for } 4 &lt; n &lt; 12, \ a_8 &amp;= 5. \end{align*}) $$$</p><p>The prover knows it. The verifier doesn’t and doesn&apos;t want to spend time computing it.</p><div class="relative header-and-anchor"><h4 id="h-arithmetization"><strong>Arithmetization</strong></h4></div><p>Arithmetization in STARKs is split between the following steps: <strong>(1)</strong> creation of the execution trace, <strong>(2)</strong> interpolation of the polynomial, <strong>(3)</strong> extending the domain of the polynomial</p><p><strong>Step (1)</strong>: Building the trace requires connecting each step of the computation with an element of a finite field in a structured way, such that it can be succinctly represented as an evaluation of a polynomial. This will allow the prover to commit to a single polynomial instead of committing to all elements in the execution trace individually.</p><p>Our computation is the computation of the 12th Lucas number. Each step of the computation is a Lucas number from the 5th to the 12th. These are the elements of our trace.</p><p>The trace is usually a matrix where each row corresponds to a different step in the computation, and each column corresponds to a different state variable. In our case, the computation is simple enough that there is only one state variable: the current Lucas number. This means our trace will be a single column.</p><img src="https://images.mirror-media.xyz/publication-images/y_CA4r9IeT19TkIpd--iS.jpg?height=594&amp;width=1240" alt="" title="null" class="image-node embed"><p>The trace will be a representation of a polynomial <em>p</em> evaluated at values in the trace. As such, the results of the evaluation will be related to the trace.</p><p>The next step is to create a multiplicative group of order 96 (since the first element is 0) within our field = 97. A multiplicative group is a subset of a field where the operation is multiplication, excluding the zero element. This group is cyclic, which means there exists a generator <em>g</em> such that all other elements in the group can be written as powers of <code>g</code>. Each element of the trace should be associated with a different element of a multiplicative subgroup of the finite field.</p><p>We want to find an 8-element subgroup, and we need a generator <code>𝑔</code> in <code>𝔽</code> whose multiplicative order is 5. The elements of group <code>G</code> will serve as a coordinate <code>x</code> for our polynomial <code>p</code>.</p><img src="https://images.mirror-media.xyz/publication-images/pcef7XSj7wMr5_F8tEwdY.png?height=646&amp;width=1298" alt="" title="null" class="image-node embed"><p>The process of finding a generator for a finite field is trial and error. We start by picking an arbitrary element <em>g</em> from the field, then compute the powers of <em>g</em> modulo <em>p</em> until we reach:</p><p>$$$ g^{p-1} \equiv 1 \pmod{p} $$$</p><p>If we encounter 1 before reaching:</p><p>$$$ (g^{p-1}) $$$</p><p>then <em>g</em> is not a generator, and we should try a different element. If we reach it without encountering 1, then <code>g</code> is a generator of the field.</p><p>We can automate this process by using a simple Python program:</p><p><code>def find_generator(p): for g in range(2, p): powers = set() for i in range(1, p): powers.add(pow(g, i, p)) if len(powers) == p-1: return g return -1 print(find_generator(97))</code></p><p>This process might take a while for large primes, but it should be quick for <code>p</code> <code>=</code> 97.</p><p><strong>Step (2)</strong>: Next, we aim to find a polynomial <code>p(x)</code> with a degree less than 8. This polynomial, when provided with the respective element of the multiplicative subgroup as input, will compute the Lucas number at each computational step. In essence:</p><p>$$$ P(g^i) = L(i+1) \text{ for } 5 \leq i &lt; 12 $$$</p><p>where <em>L</em> represents the Lucas number.</p><p>For each element of <code>g</code>, the polynomial will take values such that</p><p>$$$ f(g_i)=L(i) $$$</p><p>Now, let&apos;s interpolate this polynomial. We have a couple of methods to choose from: one is the Lagrange interpolation (discussed in the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://rafal0x.substack.com/p/exploring-zero-knowledge-proofs-part-0b2">prior article</a>) and the other is the Number Theoretic Transform (NTT). The NTT is similar to the Fast Fourier Transform (FFT) but functions within finite fields. For a more in-depth understanding of NTT, you might want to check out <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://vitalik.ca/general/2019/05/12/fft.html">Vitalik&apos;s article</a> on the subject.</p><p>Our polynomial <code>p</code>, has a degree 7, given that our trace comprises 8 elements. This polynomial, rounded to full integers, can be represented in coefficient form as:</p><p>$$$ 55x^{7} + 87x^{6} + 11x^{5} + 34x^{4} + 9x^{3} + 32x^{2} + 71x + 38 $$$</p><p>When we plot this polynomial on the coordinate plane, it looks as presented below. Keep in mind that what we are visualizing is the standard depiction of the polynomial. This visualization helps in making it more intuitive to understand the concept of low-degree extension we will undertake in the subsequent step.</p><img src="https://images.mirror-media.xyz/publication-images/HNRLf985IKWVMiwwS3vHR.png?height=455&amp;width=574" alt="" title="null" class="image-node embed"><p>For interested, below is a Python code that performs the Lagrange interpolation:</p><p><code>import galois import numpy as np # Create the finite field GF = galois.GF(97) # Define your generator g = GF(5) # Define the x and y values as galois.Array x_values = GF([g**i for i in range(4, 20)]) # Convert list to GF(97) array y_values = GF([7, 11, 18, 29, 47, 76, 26, 5, 31, 36, 67, 6, 73, 79, 55, 37]) # Convert list to GF(97) array # Compute the Lagrange interpolating polynomial L = galois.lagrange_poly(x_values, y_values) # Print the polynomial print(&quot;Lagrange Polynomial:&quot;, L) # Verify that the polynomial evaluates correctly at the given points assert np.array_equal(L(x_values), y_values), &quot;The polynomial does not interpolate the points correctly.&quot; print(&quot;Verification passed: Polynomial matches the provided points.&quot;)</code></p><p><strong>Step (3):</strong> Our next move is to extend the polynomial&apos;s domain. Within the STARKs framework, this equals evaluating the polynomial at extra points. For our purposes, we will double the domain, so there&apos;s redundancy to reconstruct the polynomial even if some original data points go missing. Typically, these extensions are much larger.</p><p>It&apos;s important to keep the new set of trace elements as a power of 2. This is required for the NTT, though it&apos;s not essential for Lagrange interpolation. When dealing with truly large polynomials (like those in practical applications), the interpolation is primarily executed using NTT, which has log-linear computational complexity (you read more about computational complexity types in <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/swlh/basics-of-big-o-notation-7d5d905d058d">this article</a> - it is a must-read for zk enthusiasts). Given that interpolating the polynomial is arguably the most resource-intensive part of the entire protocol, any efficiency gains, like those offered by the NTT, are invaluable.</p><p>For our purposes, selecting random points on the polynomial will suffice. However, in real-world scenarios, an additional shift in the polynomial is calculated within the field. This step helps hide the original data, enhancing privacy. Now, let&apos;s visualize our polynomial within the expanded domain. Keep in mind, that this is a depiction of the polynomial on a Euclidean plane and not in a finite field.</p><img src="https://images.mirror-media.xyz/publication-images/4zu8r1PsEMleLmcf96Ndv.png?height=432&amp;width=574" alt="" title="null" class="image-node embed"><p>Degree extension provides the redundancy to reconstruct the original polynomial if some data from the initial eight points goes missing. The Unisolvence Theorem tells us that a polynomial <code>p(x)</code> of degree <code>n</code> is uniquely defined when its values are at <code>n + 1 </code>distinct points.</p><p>If you&apos;re given<code> n + 1</code> unique points, there is only one polynomial <code>p(x)</code> with a degree up to <em>n</em> that satisfies the expression:</p><p>$$$ P(x_i) = yi, \text {for } i = 1,2,3..,n. $$$</p><p>This essentially means that for <em>n</em>+1 unique points, there&apos;s a single polynomial, with a degree no greater than <em>n</em>, that intersects all these points. This polynomial is referred to as the interpolating polynomial. Thus, with <em>n</em>+1 points on this polynomial, we can retrieve any polynomial of degree <em>n</em>.</p><p>Within STARKs, this kind of polynomial serves two primary functions. First, the FRI protocol verifies its low degree. In our scenario, the polynomial&apos;s degree of less than 8 is low. Secondly, this polynomial acts as a foundational component for Reed-Solomon codes, which encode data blocks as polynomials over a finite field. When transmitting data, errors may occur, and some values may be received incorrectly. The task is then to recover the original polynomial, even if some values are erroneous.</p><p>This recovery is possible due to the properties of polynomials and the fact that more evaluations of the polynomial are sent than the minimum required by the Unisolvence Theorem. By evaluating the polynomial at more points, we can tolerate some errors and still uniquely recover the original polynomial, even if some of the received values are incorrect. This is what allows <strong>Reed-Solomon</strong> codes to correct errors in data transmission.</p><img src="https://images.mirror-media.xyz/publication-images/QT1YnGx37VnX48socdYuc.jpg?height=500&amp;width=687" alt="" title="null" class="image-node embed"><p>Returning to our data: we have encoded a polynomial based on the following trace. We expanded the domain of our initial polynomial by selecting extra random points that the polynomial passes through. Now it’s time to commit to this data.</p><img src="https://images.mirror-media.xyz/publication-images/uAeGIE3Wsb9E9bVDmloCz.png?height=854&amp;width=1188" alt="" title="null" class="image-node embed"><p>The commitment process involves hashing the values representing our polynomial and constructing a Merkle tree using these hashes. Every data point, along with its subsequent branches, must be hashed. The root of the hash is then sent to the verifier. Let&apos;s take a look at its visual representation of a Merkle tree.</p><img src="https://images.mirror-media.xyz/publication-images/3BwZIeQ_tDLzFyhRytiTV.png?height=540&amp;width=968" alt="" title="null" class="image-node embed"><p>Here we come across the Fiat-Shamir. The Fiat-Shamir heuristic is a method used to convert an interactive proof, into a non-interactive proof.</p><p>The Fiat-Shamir heuristic turns this interactive proof into a non-interactive one by replacing the verifier&apos;s role with a cryptographic hash function. Instead of the verifier asking random questions, the prover computes the hash of the statement and previous responses to generate the next challenge. Depending on the specifics of the protocol, this might involve interpreting the hash as an integer and perhaps reducing it modulo some value. The exact way the hash is turned into a challenge depends on the details of the particular protocol being used. This allows the prover to create a proof without interacting with the verifier.</p><p>The heuristic&apos;s security is based on the assumption that the hash function behaves like a random oracle, meaning that it&apos;s computationally infeasible to predict its output without actually computing it.</p><div class="relative header-and-anchor"><h4 id="h-constraints"><strong>Constraints</strong></h4></div><p>Let&apos;s revisit the constraints we outlined at the start of our discussion, but this time we will adjust them to align with the expanded domain.</p><p><strong>Basic Constraints:</strong></p><p>Given the Lucas sequence, if we begin with the fifth number, add the sixth, and keep summing the last two numbers for six consecutive iterations, the sixteenth number, when reduced modulo 97, is 37. In formal terms:</p><ol><li><p>The first element, <code>a[0] = 7</code></p></li><li><p>The second element, <code>a[1] = 11</code></p></li><li><p>The Lucas sequence rule, <code>an​ = an−1​ + an−2​,</code> is valid for elements <code>2 &lt; n &lt;= 14</code></p></li><li><p>The final element <code>a[15] = 37</code></p></li></ol><p><strong>Polynomial Constraints:</strong></p><p>Earlier, we transformed the execution trace that describes the problem into a polynomial <code>p</code>. Now, we will rewrite the constraints into polynomial form based on the trace polynomial <code>p</code>. The trace and its corresponding values are denoted with <code>a</code> and <code>ai​</code>. When presented as constraints in polynomial terms, it will look like this:</p><p>$$$ \begin{align*}</p><ol><li><p>\quad p(x) &amp;= 7, &amp;\text{for } x &amp;= g^4 \</p></li><li><p>\quad p(x) &amp;= 11, &amp;\text{for } x &amp;= g^5 \ &amp;\vdots \</p></li><li><p>\quad p(x) &amp;= 37, &amp;\text{for } x &amp;= g^{19} \end{align*} $$$</p></li></ol><p>When we evaluate the polynomial <code>p</code> at the specific trace value <code>gi</code>​, it yields the corresponding number from the Lucas sequence. This happens because we have mapped the elements of the group <code>G</code> with the numbers from the Lucas sequence and interpolated the polynomial based on this mapping.</p><p>Now, the third constraint, which is more challenging:</p><p>$$$ p(x) = g^{i-1} + g^{i-2}, \text{ for } x = g^i, \ 6 &lt; i \leq 18 $$$</p><p>Putting it more simply: when we evaluate the polynomial <em>p</em> at the <em>i</em>th element of x, the outcome is</p><p>$$$ g^i. \text{ This } g^i \text{ is the sum of } g^{i-1} \text{ and } g^{i-2} $$$</p><p>This holds true for <em>i</em> values from 6 to 18, but no further, since these are the last two elements of the trace. The last element is described by the fourth constraint, while the one before cannot be calculated by the formula.</p><p>We have now translated our constraints into a polynomial form, echoing the exact constraints we started with. Hence, if these polynomial constraints hold up, then our initial statement is true.</p><p><strong>Root Constraints</strong></p><p>We will now transition from the polynomial form to the root form. When discussing polynomials, a root is essentially a value, let&apos;s say <code>x = a</code>, where the polynomial <code>p(x)</code> evaluates to zero. In simpler terms, if <code>p(a) = 0</code>, then <em>a</em> is considered a root of the polynomial <code>p(x)</code>. Let&apos;s see what our constraints look like in the root format:</p><p>$$$ \begin{align*} \text{1. } p(x) - 7 &amp;= 0, &amp;\text{root: } x &amp;= g^4 \ \text{2. } p(x) - 11 &amp;= 0, &amp;\text{root: } x &amp;= g^5 \ \text{3. } p(x_i) - g^{i-1} - g^{i-2} &amp;= 0, &amp;\text{roots: } x &amp;= g^i, \ 6 &lt; i \leq 18 \ \text{4. } p(x) - 37 &amp;= 0, &amp;\text{root: } x &amp;= g^{19} \end{align*} $$$</p><p>By this logic, if the values of <em>x</em> are the roots of <em>p</em>(<em>x</em>), then our initial statement is true.</p><p><strong>Rational Functions Constraints</strong></p><p>Based on the Polynomial Remainder Theorem when we divide a polynomial <code>p(x)</code> by <code>x − z</code>, the remainder is <code>p(z)</code>. So, if <code>p(z) = 0</code>, it means that the division by <code>x − z</code> yields no remainder. This indicates that <code>x − z</code> is a factor of <code>p(x)</code>, and consequently, <em>z</em> is a root of the polynomial <code>p(x)</code>. As a result, there must exist another polynomial, say <code>t(x)</code>, such that when <code>t(x)</code> is multiplied by <code>x − z</code>, we get <code>p(x)</code>.</p><div class="relative header-and-anchor"><h5 id="h-example">Example:</h5></div><p>Given</p><p>$$$ p(x) = x^2 - 5x + 6 $$$</p><p>if we think <code>x − 2</code> might be a factor, we can test it by calculating <code>P(2) = 4 − 10 + 6 = 0</code>. We confirm that indeed <code>P(2) = 0,</code> so <code>x−2</code> is a factor. Now, when we divide <code>p(x)</code> by <code>x − 2 </code>the quotient is <code>x − 3</code> and there is no remainder. So:</p><p>$$$ p(x) = (x-2)(x-3) $$$</p><p>Now, let’s transform the root constraints into rational functions.</p><p>$$$ \text{1. } g^4 \text{ is root of } p(x) - 7 \text{ if and only if } \frac{p(x) - 7}{x - g^4} \text{ leaves no remainder} $$$</p><p>$$$ \text{2. }g^5 \text{ is root of } p(x) - 11 \text{ if and only if } \frac{p(x) - 11}{x - g^5} \text{ leaves no remainder } $$$</p><p>$$$ 3. \ \forall i \in (6, 18], \ g^i \text{ roots } p(x) - g^{i-1} - g^{i-2} \text{ iff } \frac{p(x) - g^{i-1} - g^{i-2}}{\prod_{i=6}^{i=18} (x - g^i)} \text{ leaves no remainder} $$$</p><p>$$$ \text{4. }g^{19} \text{ is root of } p(x) - 37 \text{ if and only if } \frac{p(x) - 37}{x - g^{19}} \text{ leaves no remainder} $$$</p><p>Before moving forward let&apos;s dive deeper into the third constraint. Calculating the product of all the elements of <code>g</code> might seem daunting, especially when we aim for efficiency. Fortunately, there&apos;s a neat workaround that can make that job much easier.</p><p>Instead of the heavy calculation in the denominator, we can simply use:</p><p>$$$ x^n - 1 $$$</p><p>The key point: in group <code>G</code>, raising <em>g</em> to the power of <code>N</code> gives us <code>1</code>. It can be easily verified that:</p><p>$$$ g^{97} = 1 $$$</p><p>Given this observation, if we factor the polynomial <code>x^N-1</code> over the field, the roots are precisely the powers of <code>g</code><em>.</em> Therefore <code>x^N-1</code> can be expressed as a product of linear terms:</p><p>$$$ \prod (x - g^i) = x^n - 1 $$$</p><p>his is an illustration of the fundamental theorem of algebra which says that a polynomial of degree <code>N</code> has exactly <code>N</code> roots in a field containing those roots. In this context, the field contains the cyclic group generated by <code>g</code>, and <code>x^N−1</code> has its roots as the powers of g.</p><p>The equation holds because every power of <em>g</em> is a root of <code>x^N−1</code>, and the polynomial can be expressed as a product of linear terms based on these roots.</p><p>In our case, since the trace has only 16 steps, the calculation will be manageable, so we will keep the constraint as is. To apply the simplification for our F = 97 and with only 16 trace steps, we would have to cancel all the remaining 81 steps/polynomials, which would cost us dearly in terms of the cost of computing.</p><p>We have now transformed the constraints from the root form to the rational function form. Since in each case the division leaves no remainder, the results are always polynomial.</p><p>We now can re-write the constraints as polynomials:</p><p>$$$ \begin{align*} f_0(x) &amp;= \frac{p(x)-7}{x-g^4} \ f_1(x) &amp;= \frac{p(x)-11}{x-g^5} \ f_2(x) &amp;= \frac{p(x) - g^{i-1} - g^{i-2}}{\prod_{i=6}^{18} (x - g^i)} \ f_3(x) &amp;= \frac{p(x)-37}{x-g^{19}} \end{align*} $$$</p><p>If these statements are polynomials, then our initial statement holds.</p><p>After transitioning our constraints from the basic form to rational functions, our next and final step is to create the composition polynomial denoted <code>c(x)</code>.</p><p>The composition polynomial is created by multiplying our rational functions with a random value, <code>α</code>, from the field and then adding the results:</p><p>$$$ c(x) = \alpha_0 \cdot f_0(x) + \alpha_1 \cdot f_1(x) + \alpha_2 \cdot f_2(x) + \alpha_3 \cdot f_3(x) $$$</p><p>If <em>f</em> statements are polynomials, then <code>c(x)</code> is guaranteed to be a polynomial too. The next step is to use a Merkle Tree to commit to <code>c(x)</code><em>.</em></p><p>And this commitment finalizes the zk-STARK&apos;s arithmetization. Though less intuitive than the SNARKs&apos; arithmetic circuit method, the trace technique scales better and is apt for sequential and repetitive computations.</p><p><strong>Summary</strong></p><p>Let&apos;s take a step back and recap the steps and tools we used:</p><ol><li><p><strong>Problem Statement:</strong> Our goal was to prove the knowledge of the twelfth number in the Lucas sequence.</p></li><li><p><strong>Algebraic Execution Trace</strong>: We constructed the algebraic execution trace, detailing the computation step by step. We limited the calculation to a field of 97 elements generated by a single element <em>g</em>.</p></li><li><p><strong>Transformation to Polynomials:</strong> We converted the trace to a polynomial using Lagrange Interpolation. For larger traces, Fast Fourier Transform over finite fields (aka Number Theoretic Transform) would be a more efficient choice.</p></li><li><p><strong>Domain Extension</strong>: We extended the polynomial through the addition of more points that lay on this polynomial. This ensures we can reconstruct the polynomial even if some of the original points are lost. The data recovery method with the use of polynomials is called Reed-Solomon codes.</p></li><li><p><strong>Polynomial Commitment:</strong> We committed to the polynomial by hashing it into a Merkle Tree, which is then sent by a prover to the verifier. With the help of the Fiat-Shamir heuristic that introduces randomization based on the resulting hashes, we can make the protocol non-interactive.</p></li><li><p><strong>Constraints Transformation:</strong> We described the constraints and transformed them subsequently to polynomial, root, and then rational function form. From these functions, we then formed the composition polynomial. Successfully proving that the composition polynomial is low-degree is equal to confirming that the original statement is true.</p></li></ol><p>Indeed, in the next article, we will show how the FRI protocol is used to prove that the composition polynomial is low-degree. Keep an eye out for that!</p><p>P.S. I&apos;m aiming to release the next piece sooner than in 6 months. Thanks for your patience.</p><p>I couldn’t write this blog post without the following sources:</p><ol><li><p>Starkware, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://starkware.co/stark-101/"><em>STARK101</em></a><em>,</em> (main inspiration and source)</p></li><li><p>Starkware, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/starkware/arithmetization-ii-403c3b3f4355"><em>Arithmetization</em></a></p></li><li><p>Starkware, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eprint.iacr.org/2021/582.pdf"><em>ethSTARK</em></a></p></li><li><p>Aleksander Berentsen, Jeremias Lenzi, Remo Nyffenegger, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4308637"><em>A Walkthrough of a Simple zk-STARK Proof</em></a></p></li><li><p>RISC Zero, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dev.risczero.com/proof-system/stark-by-hand"><em>STARK by hand</em></a></p></li></ol>]]></content:encoded>
            <author>rafal@newsletter.paragraph.com (rafal)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/9c163dd15ea747b76a087a5a92da8974.gif" length="0" type="image/gif"/>
        </item>
        <item>
            <title><![CDATA[Basics of zk-SNARKs]]></title>
            <link>https://paragraph.com/@rafal/basics-of-zk-snarks</link>
            <guid>sEalNsH7yyV2SLFOVeEF</guid>
            <pubDate>Sun, 24 Dec 2023 09:47:21 GMT</pubDate>
            <description><![CDATA[Are you searching for a way to understand zero-knowledge proofs from a technical perspective, but finding existing resources either too shallow or to...]]></description>
            <content:encoded><![CDATA[<p>Are you searching for a way to understand zero-knowledge proofs from a technical perspective, but finding existing resources either too shallow or too convoluted? Look no further! This article is for those who, like myself, are not math wizzes, but still want to dive as deep as possible into the topic. So buckle up, and let&apos;s start with the basics.</p><p><strong>Zero-Knowledge Proofs</strong></p><p>Zero-knowledge proofs (ZKPs) were first brought to light in 1989 with the publication of &quot;The Knowledge Complexity of Interactive Proof Systems&quot; by Shafi Goldwasser, Silvio Micali, and Charles Rackoff. The concept received a lot of attention in the late 1990s, with the introduction of non-interactive ZKPs in &quot;Succinct Non-Interactive Zero-Knowledge for a von Neumann Architecture&quot; by Amit Sahai and Salil Vadhan. Despite its initial buzz, the use of ZKPs slowed down over the years, but has recently experienced a revival, especially in the context of blockchain technology. Early on, Zcash embraced the technology and became one of the first cryptocurrencies to implement ZKPs in 2014. Fast forward to today, and the crypto space is filled with new projects that utilize zero-knowledge proofs to enhance scalability and privacy. This innovative use of mathematics and cryptography has made ZKPs a buzzword in the crypto community.</p><p>ZKPs are a special kind of cryptographic proof that allows a prover to show to a verifier that they possess certain information, without revealing the information itself. For example, a prover could prove that a number x falls within a certain range [a,b] without revealing x&apos;s actual value. Similarly, it could be proved that an element z is part of a set S without revealing the value of the element, or prove that two numbers x and y are equal without revealing their values.</p><p>For ZKPs to work, the problem at hand must be in the NP class. NP stands for &quot;nondeterministic polynomial time&quot; and refers to problems that can be verified quickly and easily, even though they may be difficult to solve. Examples of NP problems include checking a hash function for a specific value, determining if a number is prime, or solving a sudoku puzzle.</p><p>In the blockchain world, ZKPs are a key tool for achieving two key goals: privacy and scalability. Privacy is the main reason for the adoption of ZKPs in cryptocurrencies like Zcash and decentralized applications like Tornado Cash, where ZKPs allow for transactions to be mixed without revealing information about the parties involved or the amount being transferred.</p><p>Scaling is another important reason for the use of ZKPs in blockchain. ZKPs allow for large amounts of data to be encoded into small-sized proofs that are easy to run and verify, making them a perfect solution for blockchains. In fact, Ethereum has introduced ZKPs in EIP-4844, also known as Proto-Danksharding, where the succinctness of ZKPs will be used to allow L2s to post transactions on Ethereum in &quot;data blobs”.</p><p>For a ZKP system to be considered truly zero-knowledge, it must meet certain criteria. These include:</p><ol><li><p>Completeness: If the statement is true, the verifier will be convinced of its validity.</p></li><li><p>Soundness: If the prover is lying, the verifier will not be convinced of the statement&apos;s validity.</p></li><li><p>Zero-knowledge: The proof reveals no information about the statement being proved beyond the fact that it is true.</p></li></ol><p>Zero-knowledge proofs come in several different forms, each with its own method of proving a statement to a verifier. The main types of ZKPs include:</p><ol><li><p>Interactive proofs: This type of proof involves a back-and-forth communication between the prover and verifier, where the prover provides pieces of information about the statement being proved, and the verifier asks questions (challenges) to verify the information. This process repeats until the verifier is confident that the statement is true.</p></li><li><p>Non-interactive proofs (SNARKs, if the succinctness requirement is met): In this type of proof, the prover sends all the information needed to verify the statement, along with pre-computed answers to potential challenges, to the verifier. This eliminates the need for further interaction and makes the process faster. However, a trusted setup between the parties is required to pre-determine the answers to the challenges.</p></li><li><p>Transparent proofs: Unlike non-interactive proofs, transparent proofs do not require a trusted setup and thus offer a more secure solution. They eliminate the risk of a malicious agent exploiting the system if the algorithms were to be compromised in the future.</p></li></ol><p><strong>SNARKs</strong></p><p>SNARK stands for &quot;Succinct Non-Interactive ARgument of Knowledge,&quot; meaning that the proof can be generated and verified quickly without any interaction between the prover and verifier. To understand how zk-SNARKs work, it is helpful to start with a basic understanding of arithmetic circuits. Any problem in the NP class can be translated into an arithmetic circuit, which consists of input gates, sum gates, and product gates. Input gates are labeled with either a variable or a value and have no incoming wires. Sum gates are labeled with &quot;+&quot; and perform addition, while product gates are labeled with &quot;*&quot; and perform multiplication.</p><p>For example, imagine a prover P wants to prove to a verifier V that he knows the value of x such that the polynomial p:</p><p>$$$ x^2 + x + 7 = 37 $$$</p><p>The arithmetic circuit for this polynomial would look as follows:</p><p><code> + / \ + 7 / \ * x / \ x x</code></p><p>The input gates in the circuit are for the variable x and constant 7, and the circuit has three arithmetic gates performing three arithmetic operations. Although real-life arithmetic circuits have far more gates and create much more complicated polynomials, what&apos;s important to note is that an arithmetic circuit can always be expressed in the polynomial form.</p><p>To create a ZK-SNARK, the next step is to turn the arithmetic circuit into a set of equations using a system called the <strong>Rank 1 Constraint System (R1CS)</strong>. This system allows the representation of the arithmetic circuit as a set of linear equations. For example, the R1CS representation of the polynomial p would look like this:</p><p><code>X = x A = X^2 B = A + X C = B + 7</code></p><p>The process of transforming the arithmetic circuit into a set of equations is called &quot;flattening.&quot; In this process, <code>X</code>, <code>A</code>, <code>B</code> and <code>C</code> are the variables and the equations represent the operations carried out in the arithmetic circuit. To represent the system of linear equations in R1CS, a set of matrices is used:</p><p><code>s [1, 5, 37, 25, 30] A [0, 1, 0, 0, 0] [0, 1, 0, 1, 0] [7, 0, 0, 0, 1] B [0, 1, 0, 0, 0] [1, 0, 0, 0, 0] [1, 0, 0, 0, 0] C [0, 0, 0, 1, 0] [0, 0, 0, 0, 1] [0, 0, 1, 0, 0]</code></p><p>The vector <code>s</code> represents the solutions to the operations performed in the linear equations and is presented in the form<code>[1, X, C, A, B]</code>.</p><p>In the process of calculating the matrices <code>A</code>, <code>B</code>, <code>C</code> we need to ensure that they meet a specific equation: <code>s.A * s.B - s.C = 0</code>, which is the same as <code>s.A * s.B = s.C</code>. We can verify this by taking the dot product of each element in the matrices and adding them up:</p><p><code>A [1, 5, 37, 25, 30].[0, 1, 0, 0, 0] = 5 [1, 5, 37, 25, 30].[0, 1, 0, 1, 0] = 30 (5+25) [1, 5, 37, 25, 30].[7, 0, 0, 0, 1] = 37 (30+7) B [1, 5, 37, 25, 30].[0, 1, 0, 0, 0] = 5 [1, 5, 37, 25, 30].[1, 0, 0, 0, 0] = 1 [1, 5, 37, 25, 30].[1, 0, 0, 1, 0] = 1 C [1, 5, 37, 25, 30].[0, 0, 0, 1, 0] = 25 [1, 5, 37, 25, 30].[0, 0, 0, 0, 1] = 30 [1, 5, 37, 25, 30].[0, 0, 1, 0, 0] = 37</code></p><p>Our calculation shows that <code>s.A * s.B = s.C</code> is met, since <code>5*5=25, 30*1=30, 37*1=37</code> This means that the prover P knows the right answer and that our arithmetic circuit is properly constructed. The purpose of the R1CS representation is to ensure that our arithmetic circuit produces the correct answer (also known as witness), and lays out all the conditions for our statement (constrains).</p><p>If you would like to understand the process better, you can use the Python <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ethereum/research/blob/master/zksnark/code_to_r1cs.py">code</a> written by Vitalik to turn your set of equations into an R1CS.</p><p>The next step in the ZK-SNARK creation process is to convert the R1CS representation into a <strong>Quadratic Arithmetic Program (QAP)</strong>. This is important because ZK-SNARKs rely on polynomials to prove statements, and while the R1CS matrices may confirm that the calculation is correct and the prover knows the witness, they are not suitable for ZK-SNARK purposes. The transformation from R1CS to QAP will convert the matrices into polynomials, making them suitable for use in a ZK-SNARK.</p><p>A polynomial of degree <code>n</code> has at least <code>n + 1</code> points where it intersects with the coordinate plane. For example, a polynomial of degree 1, like a line, would intersect with the plane at two points. Meanwhile, a polynomial of degree 2, like a parabola, would have three points of intersection. Given that our R1CS matrices have three rows (or that our arithmetic circuits have three gates) we&apos;ll be constructing polynomials of the second degree.</p><p>We will be using the coordinates <code>1, 2, 3</code> for the x-axis, and for each column of each matrix created for the R1CS representation, we will use these values to find the corresponding y-axis coordinates. For example, consider the first column of the first matrix, <code>0, 0, 7</code>. We will map these values to create the following set of coordinates <code>(1,0), (2,0), (3,7)</code>.</p><p>Using Lagrange interpolation, we will find a polynomial that satisfies these coordinates. To do this, we create individual polynomials for each point and then combine them to form a final polynomial that passes through all three points. The final polynomial serves as an estimate for the underlying function that generated these points. Lagrange polynomials for coordinates<code>(1,0), (2,0), (3,7)</code> are, respectively:</p><p>$$$ L_1(x) = \frac{(x - 2)(x - 3)}{(1 - 2)(1 - 3)} \times 0 = 0 $$$</p><p>$$$ L_2(x) = \frac{(x - 1)(x - 3)}{(2 - 1)(2 - 3)} \times 0 = 0 $$$</p><p>$$$ L_3(x) = \frac{(x - 1)(x - 2)}{(3 - 1)(3 - 2)} \times 7 = \left(\frac{(x - 1)(x - 2)}{2}\right) \times 7 $$$</p><p>To find the Lagrange polynomial for the point <code>(1,0)</code>, we first need to create a polynomial that is non-zero at <code>x = 1</code> and zero at the two other points. This can be done using the formula <code>(x - 2)(x - 3)</code>. We then divide this by <code>(1 - 2)(1 - 3)</code>to find the correct value of <code>y</code>. Finally, we multiply the polynomial by the value of <code>y</code> for our point.</p><p>We repeat this process for the two other points, and then add up all of the resulting polynomials to get the final Lagrange interpolating polynomial:</p><p>$$$ \begin{align*} p(x) &amp;= L_1(x) + L_2(x) + L_3(x) \ &amp;= 0 + 0 + \left( \frac{(x - 1)(x - 2)}{2} \times 7 \right) \ &amp;= \frac{7}{2} \times (x - 1)(x - 2) \ &amp;= \frac{7}{2} \times (x^2 - 3x + 2) \end{align*} $$$</p><p>The above result can also be written in the form of another polynomial:</p><p>$$$ \begin{align*} p(x) &amp;= \frac{7}{2} \times (2 - 3x + x^2) \</p><p><code> &amp;= 7 - 10.5x + 3.5x^2</code></p><p>\end{align*} $$$</p><p>Which then can be written in the form of a vector: <code>[7, 10.5, 3.5]</code>. We thus have transformed the first row of the matrix A of R1CS (transposed) to a polynomial. When we do the same with the remaining rows, we get the following matrix:</p><p><code>Ap [7.0, -10.5, 3.5] [0.0, 1.5, -0.5] [0.0, 0.0, 0.0] [-3.0, 4.0, -1.0] [1.0, -1.5, 0.5] Bp [-2.0, 2.5, -0.5] [3.0, -2.5, 0.5] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] Cp [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [1.0, -1.5, 0.5] [3.0, -2.5, 0.5] [-3.0, 4.0, -1.0]</code></p><p>You can use <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ethereum/research/blob/master/zksnark/qap_creator.py">the code </a>written by Vitalik to get such QAP for your SNARK.</p><p>Now, our initial statement is represented in the form of polynomials, and soon we will be able to do some cryptography on it.</p><p><strong>Recap</strong></p><p>Before closing the first part of the article, let’s recap all the steps we went through:</p><ol><li><p>We began by defining our statement, where the prover wants to prove to the verifier that they know the value of <code>x</code> such that the equation <code>x^2 + x + 7 = 37</code> holds. This statement needs to be quickly verifiable for us to build a ZK-SNARK for it.</p></li><li><p>We then created an arithmetic circuit that represented the statement and flattened it by writing each calculation in the circuit as a separate polynomial. The circuits only accept addition and multiplication as possible operations.</p></li><li><p>From the flattened arithmetic circuit, we created an R1CS representation of the problem. R1CS consists of three matrices that must satisfy the equation: <code>s.A * s.B - s.C = 0.</code></p></li><li><p>Finally, we transformed the R1CS to QAP using Lagrange interpolation. QAP is a matrix of polynomials that captures the underlying function of the original statement, with each row representing the coefficients of the polynomials.</p></li></ol><p>To wrap up, our example was simple, but in reality, arithmetic circuits can become quite complex, with thousands of gates and wires. Performing manual calculations for these large circuits is not a feasible option. That&apos;s why tools such as Circom (Hardware Description Language), or programming languages with compilers such as zoKrates, and Cairo are utilized to build the circuits and perform the complex calculations.</p><p>In the next part of the article, we will explore the process of constructing an actual zk-SNARK from the polynomials we derived. We will look at how polynomial commitments are used to verify the set of polynomial equations, and how the final proofs for statements are created. Stay tuned!</p>]]></content:encoded>
            <author>rafal@newsletter.paragraph.com (rafal)</author>
        </item>
        <item>
            <title><![CDATA[Mangrove and On-Chain Liquidity]]></title>
            <link>https://paragraph.com/@rafal/mangrove-and-on-chain-liquidity</link>
            <guid>3SFe5RtzBEJFI3JqXO67</guid>
            <pubDate>Sat, 23 Dec 2023 18:56:09 GMT</pubDate>
            <description><![CDATA[Liquidity is the lifeblood of DeFi and is crucial for any market to function smoothly. Simply put, liquidity refers to the ability to buy or sell an ...]]></description>
            <content:encoded><![CDATA[<p>Liquidity is the lifeblood of DeFi and is crucial for any market to function smoothly. Simply put, liquidity refers to the ability to buy or sell an asset quickly and at a price close to its true value. Liquidity is important for several reasons:</p><ul><li><p>It makes trading a better experience, as transactions can be completed almost instantly.</p></li><li><p>It helps to stabilize prices and reduce slippage, or the difference between the price you want to pay for an asset and the price you end up paying.</p></li><li><p>It helps to prevent market manipulation.</p></li></ul><p>In the real world, cash is considered a liquid asset because it can be easily exchanged for goods and services. On the other hand, real estate is not considered a liquid asset because it is difficult to quickly sell and convert into cash. In the crypto world, this concept can be applied to fungible coins with large market caps, which are generally considered much more liquid than NFTs.</p><p>The crypto industry has come a long way since the early days when bitcoins were traded for pizzas on online forums. We have witnessed the rise and fall of centralized exchanges such as MtGox, as well as the success of platforms like Binance and Coinbase. Currently, DEXes offer a way for users to trade crypto without the need for a third-party intermediary. In this article, we will explore the evolution of these exchanges, how they have attempted to solve the liquidity problem and what awaits us in the future.</p><p><strong>The rise of Automated Market Makers (AMM)</strong></p><p>DEXes were among the first blockchain-based applications, and the introduction of AMMs has been a breakthrough in their history. AMMs are algorithms that facilitate trades on DEXs, making it easier for users to buy and sell assets on-chain and increase the liquidity of the crypto markets. Let’s take a closer look at how AMMs work and how they have evolved.</p><p>Uniswap, now a DeFi juggernaut, introduced the constant product market maker (CPMM) model and the concept of liquidity pools. The CPMM model calculates the total amount of assets in a liquidity pool using the formula x*y=k, where <em>x</em> is the amount of asset A (e.g. ETH), <em>y</em> is the amount of asset B (e.g. USDC), and <em>k</em> is constant. To withdraw ETH from the pool, a user must deposit an amount of USDC determined by the ratio of total ETH to total USD. While this model has some limitations, including the need for a separate liquidity pool for each asset pair or impermanent loss, it was a major development that helped to kick-start the DeFi revolution.</p><p>Slippage is another common issue with AMMs and researchers have been looking for ways to optimize the model to address it. Curve Finance has found a solution to slippage for stable asset pairs such as USDC/USDT or ETH/stETH. Let’s see how it was achieved.</p><img src="https://storage.googleapis.com/papyrus_images/ea291fb46cd86bee1d85c9d5f02454e7.jpg" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAUCAIAAABj86gYAAAACXBIWXMAAAsTAAALEwEAmpwYAAAD/0lEQVR4nKWUf2jcZBjHc+BftQjrP2sqd5vd7Wrs9DroTV0sGEQjjHZbPWTs/srKIAV7KpLW0kzHic44hF3rmv5wRnflwNbU7chutOGG7q5MUjdp3Nqmw/WFVc1avMXVNushe8V727uuXfGYH17Ck+dN8n2fb973wWzbhhAahlFaWlpXt7e5ubXzs055hWg02j/QH+mLKIqSXEFV1dUxQlEUlFdVVVrBNE0MZrEsS5blwcGzm0q2fdUtWZY1Nzu3sLhwPn6+49OOxHCCYRiXy4XjuMvlIknSvYLX6/VlCQaDBEE4HA6CIHRdBwAIgqBp2rKAaZoMwxw6dLio2Kl8E5ubnUP5kZGR2EAMXAfhcJiiKJqmfT4fRVGBQADd1tbW1dbWURQlSRLDMBRFcRyH3pUkKS9g2zYAYHR0tNxd3dvx+fQv0yh/VR+7ecP4685tURRxHHe73RiG0TSNls9xHM/zSNWfhWEYkiSxLDzP67qer4AkyYMHDxQVOzuOd/428yvKJxLffyx0Dw1dDIfDPp+PJMlAIIBswXGcYRhkr2VZtm2bpomupmk+oIJUKjU9fePpKqqr/dToyA8rAhfa2o5FIoOCICCvWZYlCMLr9TocDpqmwf0YhoEC0zRFUcwLAABIkmxufqeo2Cl1Rc72n4EQZpYytm3fu/e3bS+izYaWggIUWxtg27aqqssCGIYFg8Fbt2YnJ8dfof1H3z8R6fkSCcCNWa30QJLJ5LIAjuMcx1EUVV9f79+7/+WXDvS2d8/fmYf/j7wAz/OyLAMAVFUdHo6/3fRuySOuqYnJ/yyiUAGEoigcxwmCACH0Vux+DCsrxIeCBNBXNE2LRqOSJKHpnZXUa/sOQwjv3l16uFLWViBJEsuy4XAYQriwuAghbGk5tvXxnblDt4bMUgaNQgVkWUYdCp0d9JODja0Yhr3X8sG4rhvjEzM3Z+wsD1OBoijhLDnT0OouqBedmytf39/Q1X4qNhA73XP6nBy79N3Iz5fHrl0Zu3xJM65em/vdXJifR8NK37b+SGeWMrEzsbUWhUIhjuOSySTqvcq/xK/89ONQ/BxN7al5cd+TT9W4Pc+9UFNbSewmPLu2u6s97mcJz66yzRUlj7qecO7Y5nrGU15VUe6tIp53lbmTyWReQBRFjuP8fj8AAPVblmU1TdN1PZ1ONzW98dabQQDA1NT1hobGyh3VX/crPb19H350AsOwkye/GPw2nkiktmzdfuRIKJXSdH2CfnUPz/N5AeSMLMs5i1RVtSwLTUX6+tAUyre1taJnTNMMhY7mHjv+iWAYRs4SURTzAgX+PU3TfD4fhmEs25jdDn+irYzG6hjd3lfB+l62UYza2fqp9Z/6B2/Ksn0b3ZCBAAAAAElFTkSuQmCC" nextheight="915" nextwidth="1486" class="image-node embed"><p>The price discovery mechanism in an AMM can be represented by a function, with the price of the assets shown as a point on this function. The CPMM model used by Uniswap (purple dashed line) is more sensitive to changes in the pool&apos;s reserves, resulting in a more curved function. On the other hand, in a pool where the price changes evenly (i.e. the withdrawal of token A causes the price of token B to change by the same amount), the function is linear (red dashed line). In this case, the sum of the prices of both assets is always constant. Curve elegantly combines the constant product and constant sum models in a way that the function is linear when the supply of coins is balanced but becomes more curved when there is a greater disparity in the reserves. This is the solution that allows the protocol to offer better prices for trades between stable assets.</p><p>Uniswap v3, released in May 2021, brought many improvements to the CPMM model, including the ability for liquidity providers to choose the price range in which they want to provide liquidity. In earlier versions, liquidity was evenly split across the entire curve, which resulted in underutilization of capital as trades often did not take place at the farthest points of the curve. With the ability to choose their price range, liquidity providers can now more effectively earn fees by providing liquidity in areas where it is most needed. This enhancement has significantly improved the capital efficiency of the AMM model.</p><p><strong>Oracle-based DEXes</strong></p><p>Oracle-based DEXes have attempted to address the issue of slippage by using external smart contracts that provide real-world data to blockchain apps. Bancor and GMX are examples of oracle-based DEXes that use this approach. Bancor uses a unique formula to determine the price of each asset in its liquidity pools, which is based on oracle-fed data. GMX, a perpetual exchange that also has a liquidity pool to trade blue-chip assets, uses Chainlink oracles to feed prices from centralized exchanges, thus enabling trading with no slippage.</p><p>While this is positive for traders, it leaves the protocol vulnerable to price manipulation. There have been several instances of oracle <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://jumpcrypto.com/so-you-still-want-to-use-a-price-oracle/">exploits</a>, including a recent one on GMX in which an attacker manipulated the price of AVAX on centralized exchanges while simultaneously opening and closing long/short positions on GMX and costing liquidity providers an estimated $500 million.</p><p>Oracle-based price discovery relies on a third-party provider, which may not always be decentralized and could be exploited even if it functions flawlessly. This approach also does not solve the liquidity problem but rather avoids addressing it. Because of these issues, an oracle-based system is not a scalable and sustainable long-term solution for DEXes.</p><p><strong>Will order book DEXes dominate DeFi?</strong></p><p>AMMs and oracle-based DEXes have had their limitations, leading many in the industry to consider the potential for order book-based DEXes. Order book-based exchanges, such as Binance, and Coinbase are traditional centralized exchanges that use market makers to provide liquidity for their users. While the order book model is the standard for centralized exchanges, it hasn&apos;t been feasible for blockchain-based exchanges due to high transaction fees and low throughput.</p><p>There are currently only a few DEXes implementing the order-book model, such as dYdX, Solana&apos;s Serum (which rebranded as OpenBook after the FTX collapse), and Demex running on Cosmos&apos; chain Carbon. However, the potential for order book-based DEXes to eventually take over the market has never been more appealing as the technology continues to progress.</p><p>The price discovery mechanism in an AMM can be represented by a function, with the price of the assets shown as a point on this function. The CPMM model used by Uniswap (purple dashed line) is more sensitive to changes in the pool&apos;s reserves, resulting in a more curved function. On the other hand, in a pool where the price changes evenly (i.e. the withdrawal of token A causes the price of token B to change by the same amount), the function is linear (red dashed line). In this case, the sum of the prices of both assets is always constant. Curve elegantly combines the constant product and constant sum models in a way that the function is linear when the supply of coins is balanced but becomes more curved when there is a greater disparity in the reserves. This is the solution that allows the protocol to offer better prices for trades between stable assets.</p><p>Uniswap v3, released in May 2021, brought several improvements to the CPMM model, including the ability for liquidity providers to choose the price range in which they want to provide liquidity. In earlier versions, liquidity was evenly split across the entire curve, which resulted in underutilization of capital as trades often did not take place at the farthest points of the curve. With the ability to choose their price range, liquidity providers can now more effectively earn fees by providing liquidity in areas where it is most needed. This enhancement has significantly improved the capital efficiency of the AMM model.</p><p><strong>Oracle-based DEXes</strong></p><p>Oracle-based DEXes have attempted to address the issue of slippage by using external smart contracts that provide real-world data to blockchain apps. Bancor and GMX are examples of oracle-based DEXes that use this approach. Bancor uses a unique formula to determine the price of each asset in its liquidity pools, which is based on oracle-fed data. GMX, a perpetual exchange that also has a liquidity pool to trade blue-chip assets, uses Chainlink oracles to feed prices from centralized exchanges, thus enabling trading with no slippage.</p><p>While this is positive for traders, it leaves the protocol vulnerable to price manipulation. There have been several instances of oracle <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://jumpcrypto.com/so-you-still-want-to-use-a-price-oracle/">exploits</a>, including a recent one on GMX in which an attacker manipulated the price of AVAX on centralized exchanges while simultaneously opening and closing long/short positions on GMX and costing liquidity providers an estimated $500 million.</p><p>Oracle-based price discovery relies on a third-party provider, which may not always be decentralized and could be exploited even if it functions flawlessly. This approach also does not solve the liquidity problem but rather avoids addressing it. Because of these issues, an oracle-based system is not a scalable and sustainable long-term solution for DEXes.</p><p><strong>Will order book DEXes dominate DeFi?</strong></p><p>AMMs and oracle-based DEXes have had their limitations, leading many in the industry to consider the potential for order book-based DEXes. Order book-based exchanges, such as Binance, and Coinbase are traditional centralized exchanges that use market makers to provide liquidity for their users. While the order book model is the standard for centralized exchanges, it hasn&apos;t been feasible for blockchain-based exchanges due to high transaction fees and low throughput.</p><p>There are currently only a few DEXes implementing the order-book model, such as dYdX, Solana&apos;s Serum (which rebranded as OpenBook after the FTX collapse), and Demex running on Cosmos&apos; chain Carbon. However, the potential for order book-based DEXes to eventually take over the market has never been more appealing as the technology continues to progress.</p><p>The provision (3) serves as a safeguard against market makers posting empty offers or spamming the exchange with offers that will never be fulfilled. It compensates offer takers for gas costs incurred when a maker decides or is forced to cancel an offer after a match, which can occur due to changing market conditions or the unavailability of the traded asset on the maker&apos;s side.</p><p>Later, when an offer is matched with a buy order, the callback function (4) is called twice. First, it is used to provide the asset for the trade, and then, after the trade is executed, to replenish the offer if the market maker has indicated this in the offer code. This helps to reduce the number of transactions needed to fill the order book, which in turn helps the protocol scale more efficiently.</p><p>On Mangrove, offer takers have the option to use a market order or a snipe when trying to fulfill a specific offer. A market order allows the taker to specify the highest price they are willing to pay for the offer, similar to a limit order on a traditional exchange. However, Mangrove does not offer a market order in the traditional sense, which is an order to buy a certain amount of an asset at the best available price. This is to protect users from MEV attacks, such as frontrunning or sandwiching.</p><p>The process of posting bids and asks on the exchange, including the actions of Mangrove&apos;s main smart contract, is illustrated in the following diagram:</p><img src="https://images.mirror-media.xyz/publication-images/YTE0pOZzBOVwqOdojk9ri.png?height=979&amp;width=2099" alt="https://docs.mangrove.exchange" title="null" class="image-node embed"><p>Keeper bots, while not shown in the diagram, are a crucial part of maintaining the integrity of the Mangrove order book. These bots are responsible for calling offers that are likely to fail and collecting the provision paid by the maker. This incentivizes third parties to deploy bots that scan and clean the exchange&apos;s order book. The provision is always calculated using the upper gas bound, making it profitable for keepers to keep the order book organized. Overall, keepers are essential for ensuring that using Mangrove is a seamless and enjoyable experience.</p><p>When it comes to governance, Mangrove will issue a token. The specifics of the tokenomics have not yet been disclosed, but a portion of the initial supply will likely be allocated to outside investors. Once the token is released, Mangrove token holders will have the ability to vote on various aspects of the protocol, including potential incentives for liquidity providers or offer takers to use the platform. The Mangrove community will also be able to vote on which blockchains the protocol should expand to or build protocols on top of Mangrove (as the community does with Curve or GMX).</p><p><strong>Navigating Mangrove&apos;s potential risks and uncertainties</strong></p><p>While Mangrove is a promising new protocol, it is not guaranteed to succeed. There are a few potential challenges that the DEX may face. One question is whether the Polygon will be able to handle the high level of throughput required for a fully on-chain order book-based DEX. dYdX <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dydx.exchange/blog/dydx-chain">has argued</a> that even L2s may not be able to support the scale of the order book and matching engine. One specific issue that may be difficult to manage at a reasonable cost is the need for constant order updates due to nonstop price changes. Mangrove addresses this issue by allowing for updates to be made in a single transaction, eliminating the need to cancel and repost offers.</p><p>Mangrove team surely has thoroughly researched this aspect and determined that Polygon is suitable for their needs. It&apos;s worth noting that other protocols that require a large amount of data and transactions, such as Lens Protocol (a decentralized social media platform), have also chosen Polygon as their home blockchain. If it turns out that using Polygon does not guarantee a smooth experience, there are always other L2 EVMs available as an alternative.</p><p>Another potential risk for Mangrove is the possibility of malicious code being attached to an offer due to the platform&apos;s fully permissionless market making. To address this concern, Mangrove contracts have undergone thorough <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://chainsecurity.com/wp-content/uploads/2022/03/ChainSecurity_Giry_Mangrove_audit_220511.pdf">auditing</a> by Chainsecurity, which did not find any critical vulnerabilities in the code. While this does not guarantee the security of the protocol, it is a positive sign that the protocol has been well-designed.</p><p><strong>Wrapping up</strong></p><p>Any healthy market needs to have strong liquidity. Currently, the most popular liquidity provision methods have their drawbacks:</p><ul><li><p>AMMs often have high slippage, are generally not capital efficient, and spread capital across many pools.</p></li><li><p>Oracle-based exchanges do not scale well, are at risk of market manipulation, and have no price discovery mechanism.</p></li><li><p>Centralized exchanges aren’t either transparent or trustless, and don’t offer capital efficiency for market makers.</p></li></ul><p>With these factors in mind, it is safe to say that bringing the order book model onto the blockchain presents a significant opportunity and will be one of the major narratives in the DeFi space in the coming months and beyond. Many competing projects will be trying to solve the challenges of operating an order book on the blockchain, but the first to succeed will have the chance not only to disrupt the current DEX model, but potentially make centralized exchanges obsolete in the longer term.</p><p>Mangrove, with its highly capital-efficient &quot;code-is-offer&quot; feature, is uniquely positioned to address all the pain points that both centralized and decentralized exchanges face. It probably will not be an overstatement to say that this is a once-in-a-lifetime disruption opportunity.</p>]]></content:encoded>
            <author>rafal@newsletter.paragraph.com (rafal)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/ea291fb46cd86bee1d85c9d5f02454e7.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Eigenlayer and Restaking Dilema]]></title>
            <link>https://paragraph.com/@rafal/eigenlayer-and-restaking-dilema</link>
            <guid>IqsugjVaZCYlgy5XsIIA</guid>
            <pubDate>Sat, 23 Dec 2023 18:39:52 GMT</pubDate>
            <description><![CDATA[Vitalik&apos;s recent article, “Don’t Overload Ethereum’s Consensus,” reignited discussions about restaking within the Ethereum community. In this wr...]]></description>
            <content:encoded><![CDATA[<p>Vitalik&apos;s recent article, “<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://vitalik.ca/general/2023/05/21/dont_overload.html">Don’t Overload Ethereum’s Consensus</a>,” reignited discussions about restaking within the Ethereum community. In this write-up, I aim to shed light on what restaking is and particularly zoom into EigenLayer, the project at the forefront of these conversations.</p><p><strong>Staking vs. Restaking</strong></p><p>A majority of you are already familiar with the concept of Ethereum staking. Yet, for clarity&apos;s sake: staking was introduced to Ethereum together with its transition to a proof-of-stake consensus mechanism. In essence, the consensus mechanism enables all participants in a blockchain network to achieve an agreement on the state of the blockchain and authenticate initiated transactions.</p><p>To participate as a validator in the Ethereum network, an individual or entity must stake at least 32 ETH, which might be prohibitively expensive for some. Upon staking Ether, it gets locked, and in exchange for verifying transactions, validators earn rewards. However, falling short in validation duties or engaging in malicious activities can lead to slashing of the portion of the staked ETH.</p><p>Given the high threshold of 32 ETH, staking pools and protocols have emerged. They allow individuals to collectively stake their ETH, reach the mandatory limit, and consequently share the rewards and risks. Lido, the most prominent among these platforms, has a staggering TVL of 14 billion USD.</p><p>This brings us to restaking and its soon-to-rise prominence (and the accompanying controversies) in the Ethereum community.</p><p>Restaking protocols, in essence, enable ETH – whether in its native form or as liquid staking tokens (LST) like stETH – to be used for consensus in other apps or protocols. In practical terms, a restaking service such as EigenLayer aggregates ETH, locks it up, and then uses it to secure apps or modules needing a consensus layer but lacking their own.</p><p>Let&apos;s dive into the nuances of EigenLayer – its mechanics, possibilities, and the reasons behind its controversial status.</p><div class="relative header-and-anchor"><h4 id="h-eigenlayer">Eigenlayer</h4></div><p>The inception of EigenLayer started with Sreeram Kannan. As an academician, Sreeram&apos;s research spanned across fields as varied as information theory and computational biology. Interestingly, his dive into the realm of consensus mechanics was spurred by Yuval Noah Harari&apos;s best-selling book, &quot;Sapiens&quot;. Harari proposes that homo sapiens’ unparalleled ability to create extensive cooperation networks, even among vast groups of unrelated individuals, set them apart from other species. For humans, consensus became paramount, and this inherent trait influenced Sreeram&apos;s research.</p><p>However, despite the initial enthusiasm, Sreeram hit a roadblock in his studies. That was until a colleague introduced him to blockchains. Recognizing the potential of blockchains as a modern manifestation of consensus systems, Sreeram pivoted back to his original research, culminating in the birth of EigenLayer.</p><p>At its core, EigenLayer is a collection of smart contracts on the Ethereum blockchain. The platform is currently anchored by two primary smart contracts: the EigenPod, for native Ether stakers, and the Strategy Manager, which facilitates LST restaking. As EigenLayer evolves, it will offer a sandbox where developers can introduce their smart contract modules. These modules, while serving their primary functions like bridging or validating transactions, will integrate with EigenLayer, allowing participants to provide ETH to validate the modules’ outputs.</p><p>For context, Ethereum operates on a dual-layered system with:</p><ol><li><p><strong>Beacon Chain (consensus layer)</strong> which Underpins the network&apos;s consensus mechanism, where transaction validation happens.</p></li><li><p><strong>Ethereum Virtual Machine (execution layer)</strong> where the smart contracts’ code gets executed.</p></li></ol><p>In essence, while the Beacon Chain guarantees that validators agree on a single, unified version of the transaction history, the EVM ensures these transactions are executed.</p><p>EigenLayer, in its vision and design, aims to leverage and extend this dual-layered structure, introducing the restaking mechanism to share the security of Ethereum across its broader ecosystem.</p><p><strong>Actively Validated Services</strong></p><p>Within the EigenLayer framework, the modules we have discussed are referred to as Actively Validated Services (AVS). These are apps in need of consensus for their operation. As detailed in the EigenLayer whitepaper, potential instances of AVS include sidechains, data availability layers, new virtual machines, keeper networks, oracle networks, and bridges, among others. A criterion for AVS is compatibility with the EVM. If a module cannot run on the EVM, it will not be able to leverage EigenLayer&apos;s restaking.</p><img src="https://storage.googleapis.com/papyrus_images/a0df3ba2f51afde8d474dd9edca268db.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAOCAIAAADBvonlAAAACXBIWXMAAAsTAAALEwEAmpwYAAACqklEQVR4nI2Ty08TURjF79IdK4wujSbC0p0xQTEYSEwkvogkaoQdJor8ASbWjYlxR4qaCAkmZWNKjIBNQOm0kEJT0gq300uZPgNDOy2l5TXTzuP2M+1AHZpWOJnczZy5v/OdewdBLcmynC9LVdWahtPbEJxClNJwOJzL5U70RMtKJBKiKNYGUEoBwGQydXZ2dnR0WCwWPSnDMNFotGLQ1/5XA+3t7ddbWqxWKwB4PB7XoothGLfbraehlFYDFLkAAA0NDais7u5HOkB3H+6uFBRpv5TuSH19fUe2Yr2KSi9UaTfDOjLsXGFn/ZdtYuj9Gz4UqOQ99FG6hRlhaSobXMyGnHbr8PhXs981m93KFWlRD1GJUl2RcpDbjePduF9MRWKhgMDHMMaEEIzx/Py80+kUBAEACjupDOtI/5kWU2GO4JSQTG0nLt1vbHrS+PH7BwDQqPa/Q9bhqxy3wW8CAItZl8vl8/qCwbVKLqrIqrQHAAFC4uu8rOV73t1tenjum330BIA+JAAQQqLRCAA4lqdRK2p8gFZj+Ahf1I0AEA6Hk4LAbQRmFqe+jJkXWCaTTZcbL9adQBCETZ73epf0QkgE9w8+GxjsTWR443lUAJn09r3XregWKj1t6OfCuHGIYwD9G7fbPWj+PDI65iehgvxv2OPOopSXKcCSD+PVSDKTGBoxO9yzXJwciPvGDWsAfCSGzt9BZ2+jM23oSq+Uz2tUU1TFeJdUVcOhpHctTYIhPwkurwT2drL23/bJiUlJkk4AsNwGutiFmp+iC13o2vOCrOiRjU6N0rysWWwe1PoCXe1BzY/ffvqRTvGR8s9YF2AIqB6IkihKxtRGKWqpOpN5HKHLCN0orTdflm7w8UrrAip5q4JXaTu3b5tbmXGxtrllLpbQJ6vy/AX9ypmiy0EWXgAAAABJRU5ErkJggg==" nextheight="594" nextwidth="1394" class="image-node embed"><p>Why might an AVS choose to use EigenLayer&apos;s services? The primary reason is to tap into the robust security of Ethereum, arguably the most secure decentralized network in the world. However, there are other benefits:</p><ol><li><p><strong>Reduced capital costs</strong>: There&apos;s no need to set up and maintain expensive hardware nodes to keep the network running.</p></li><li><p><strong>Enhanced Security</strong>: AVS secured by their tokens can be more vulnerable to threats from bad actors. For instance, an oracle secured by its token would likely be less secure than one secured by staked ETH.</p></li></ol><p>AVS offers flexibility in determining the security of their protocols. For instance, they can set criteria such as only validators staking a certain amount of ETH can provide security; or only native stakers can participate, or limiting participation to smaller stakeholders only. The conditions for restaking depend solely on what the AVS needs. As a result, it can be argued that restaked Ether might offer better security than the one Ethereum has. This would be true if certain groups of stakers were excluded from securing specific modules based on these bespoke requirements.</p><p><strong>Restakers</strong></p><p>Let’s take a look from another angle - what’s there for a restaker (either native, LST, or ETH LP pair holder)? Of course, there are economic incentives. Restaking will allow to use of the staked Ether and provide security to other applications without resigning from staking on Ethereum. It means, that while earning fees offered by Ethereum, one can have additional income from multiple other modules, increasing the overall rate of return on capital. The rewards from these other protocols could come in their native tokens, or other assets.</p><p>So far so good, but with staking comes a risk of slashing. In proof of stake systems, a malicious actor who validates a block with an invalid transaction can be subject to slashing. With slashing, the part of the stake owned by the actor is taken away from him.</p><p>In EigenLayer the rules of slashing will be specified in smart contracts deployed by AVS and similarly to the rules of restaking, can be set differently for each module.</p><p>Eigenlayer provides pooled security, which means that the entire restaked ETH can, in theory, be used for the security of all modules running on the protocol. In practice, the limitations will be set by restakers who would be able to choose which modules and under which circumstances to support.</p><p><strong>Risks</strong></p><p>The broader Ethereum community is engaged in debates regarding the potential risks introduced by restaking, both to the ecosystem at large and to Ethereum itself. In the most severe scenarios, the integrity of the blockchain could be compromised. Fortunately, Shreeram and the EigenLayer team have shown an openness in addressing these concerns.</p><p>In relation to EigenLayer, three principal risks have been identified: (1) A synchronized attack on multiple AVSs concurrently, (2) An unintended slashing event affecting a considerable volume of staked Ether, and (3) Centralization.</p><p>(1) <strong>Concurrent Attacks on AVSs</strong></p><p>EigenLayer&apos;s model enables stakers to secure multiple AVSs. However, not all stakers will choose to secure every single AVS, leading to potential discrepancies between the value of assets locked in an AVS and the security value offered by the stakers.</p><p>Consider a scenario where five AVSs lock a combined value of USD 10 million, yet they&apos;re secured by an ETH stake worth USD 6 million. How? Each AVS, locking in USD 2 million, may theoretically be secured by a stake larger than its locked value. Given that the collective restaked ETH exceeds this figure, each AVS might appear to be secured by an ETH stake worth 6 million. However, given that this 6 million can also support other AVSs, it creates an asymmetrical avenue for stakers to collude. This could allow them to, at the expense of up to USD 6 million, compromise modules valued at USD 10 million.</p><p>Such a vulnerability seems highly concerning. So, how does EigenLayer propose to mitigate this risk? They suggest the deployment of a Dashboard, dedicated to monitoring staker activities. This platform would enable AVS operators to preemptively spot potential attack vectors. The mechanism involves comparing the Total Value Locked (TVL) in an AVS to the stake securing it, as illustrated earlier. Should a substantial number of operators be found securing a specific AVS (and concurrently backing other modules via EigenLayer), the Dashboard will alert the AVS. Specifically, it would indicate if a group of stakers, who are also backing other AVSs, has a dominant stake that could enable abuse. To counteract this, the AVS might restrict its securing stakers to only those with a minimal number of other secured modules.</p><p>Is this a foolproof solution? There remain scenarios where sidelining a set of stakers might lower the bar for a successful attack by the remaining parties. And that’s probably not the only way to exploit this vulnerability.</p><p>(2) <strong>Unintended Slashing Events</strong></p><p>Another possibility is the unintended slashing of a group of stakers that secure a large protocol or Layer 2. Such slashing might be initiated due to a vulnerability in a contract, leading to significant losses for honest participants.</p><p>How does EigenLayer intend to counter this risk? An assumption is that when an AVS begins to engage in restaking, it&apos;s reasonable to anticipate that restakers would act cautiously, refraining from committing a sizable chunk of their ETH to secure that module. Is this a sound expectation? Probably not in crypto.</p><p>Sometimes vulnerabilities come to light well after a protocol has been operational. This suggests that particularly during the early stages when slashing contracts are getting rolled out, the risks of slashing will be higher. EigenLayer&apos;s strategy is also to ensure thorough audits of every slashing contract prior to its deployment, though the effectiveness of this measure is also dubious.</p><p>A more robust safeguard against unintended slashing is the establishment of a veto committee. This body would have the authority to review any slashing incident, determining if the operator was genuinely at fault or if the slashing was unintended and hurtful to honest participants. Comprising highly reputable figures from the Ethereum and EigenLayer communities, this committee&apos;s decisions could be implemented via a multisig. However, this introduces another issue: if a slashing event impacts a significant module within the Ethereum ecosystem, would the committee overrule the slashing, even if it was rightly executed?</p><p>Further complicating matters, community sentiment might lean towards executing a hard fork of Ethereum to revert to a pre-slashing state in such scenarios. It&apos;s not implausible that, for particularly vital protocols, there exists a temptation of moral hazard, i.e., accepting heightened risk under the belief that any missteps would simply be rectified via a community-driven hard fork. This very risk, characterized as a grave threat to Ethereum brought about by restaking, is underscored by Vitalik in his article mentioned in the beginning.</p><p>(3) <strong>Risks of Centralization</strong></p><p>In a manner similar to the risks tied to LSTs, with Lido being a dominant player, EigenLayer too faces potential centralization challenges. Given the complexities that EigenLayer introduces relative to standard or liquid staking (risks of slashing, knowledge of different types of modules, etc.), it&apos;s likely that better-financed validators will emerge as leaders. As a result, many users might find it reassuring to delegate their ETH or LSTs to these entities for restaking. If a validator can promise better returns on top of the standard rewards distributed by Ethereum, then there&apos;s little incentive for stakers to look elsewhere. EigenLayer&apos;s structure allows this. Consequently, the most technically sophisticated validators might amass a disproportionately large portion of restaked ETH or LSTs. This concentration of resources can evolve into a single point of vulnerability, undermining the decentralized ethos of the ecosystem.</p><p><strong>Conclusions</strong></p><p>At its core, blockchain is about decentralized consensus, and EigenLayer is stepping up to extend this consensus using the stake of what&apos;s widely seen as the most secure blockchain network - Ethereum. The magnitude of this shift cannot be understated.</p><p>EigenLayer stands out as one of the most pioneering, exciting, and influential projects in the current crypto space. It will establish a market where apps in need of security can tap into the resources of those ready to offer security at a price. While EigenLayer&apos;s approach is highly disruptive, it does carry inherent risks, some of which could be catastrophic for Ethereum.</p><p>Given the potential consequences of things going south with EigenLayer, it&apos;s paramount for the community, Ethereum&apos;s devs, and EigenLayer&apos;s team to closely monitor the protocol&apos;s evolution. Thankfully, Shreeram with his philosophical and highly technical approach appears to be the right person heading this project. Restaking was inevitable, so it is reassuring to see that he genuinely seems to have Ethereum&apos;s well-being at heart.</p><p>The endgame for EigenLayer is to become an integral part of the Ethereum protocol. While the debate on enshrining is a topic for another article, it could potentially be a solution to the restaking conundrum. Exciting times ahead, lads.</p><p>My main source for the article was <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://2039955362-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPy2Kmkwju3mPSo9jrKKt%2Fuploads%2F9tExk4U2OdiRKGEsUWqW%2FEigenLayer_WhitePaper.pdf?alt=media&amp;token=c20ac4bd-badd-4826-9fb6-492923741c9e"><em>Whitepaper</em></a> of Eigenlayer.</p>]]></content:encoded>
            <author>rafal@newsletter.paragraph.com (rafal)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/a0df3ba2f51afde8d474dd9edca268db.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[KZG Polynomial Commitments]]></title>
            <link>https://paragraph.com/@rafal/kzg-polynomial-commitments</link>
            <guid>mHldX9C0zMTjhKbsO7GU</guid>
            <pubDate>Sat, 23 Dec 2023 18:33:00 GMT</pubDate>
            <description><![CDATA[In the first part of the article (refer here), we introduced zero-knowledge proofs and their different types. We started constructing a zk-SNARK for ...]]></description>
            <content:encoded><![CDATA[<p>In the first part of the article (refer <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://rafal0x.substack.com/p/exploring-zero-knowledge-proofs-part">here</a>), we introduced zero-knowledge proofs and their different types. We started constructing a zk-SNARK for a simple problem by creating an arithmetic circuit, representing it as an R1CS and ultimately converting it into polynomials using QAP. Now that the statement is in polynomial form and ready for cryptography, we&apos;ll examine the properties that make polynomials suitable for cryptographic use and investigate some other cryptographic tools available.</p><p>Remember the matrix-form polynomials we obtained from the QAP transformation in our previous article? When we multiply them by the solution vector <code>s [1, 5, 37, 25, 30]</code>, we get the following polynomials for each matrix: <code>Ap [-38.0, 52.0, -9.0], Bp [13.0, -10.0, 2.0], and Cp [22.0, 2.0, 1.0]</code>. After multiplying these polynomials together, we obtain the final polynomial:</p><p>$$$ -516x^4 + 1054x^3 - 714x^2 + 194x -18 $$$</p><p>This polynomial encapsulates the computations we performed and the ultimate solution to our initial problem. If someone knows this polynomial, they can claim to know the solution to the problem:</p><p>$$$ x^2 + x + 7 = 37 $$$</p><div class="relative header-and-anchor"><h4 id="h-selected-properties-of-polynomials"><strong>Selected properties of polynomials</strong></h4></div><p>Polynomials are useful in cryptography because they can represent complex mathematical constructs and be used for encrypting and decrypting messages. They also can store large amounts of data, as we saw in the previous article. Furthermore, finding intersections between two slightly different polynomials by randomly picking points is extremely difficult, as we will see shortly.</p><p>The degree of a polynomial is determined by the highest exponent of an <code>x</code> coordinate within the polynomial. For example, the polynomial of degree 3:</p><p>$$$ x^3 - 2x^2 + 1 $$$</p><p>Let&apos;s compare this polynomial to another similar one:</p><p>$$$ x^3 - x^2 + 1 $$$</p><p>and see how they fit on the coordinate plane. Despite their near-identical nature, their positions on the plane differ significantly. The key takeaway is that finding two distinct polynomials with common points is almost impossible.</p><img src="https://storage.googleapis.com/papyrus_images/69147ae4aaa169e472a80aa1b53f8d28.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAIAAAAUMWhjAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAEN0lEQVR4nK2Vf2wURRTH5x/9x4QmmpQcJv642EZyV0mKVxvarIfBstcaCUdbDO0CKV5XDEZZakIvrr96wIYWCGZDNDEOrZiWTdAYy8pBrGWuatL2JpoY7Z13WFs615KmQIf6T0/G3M7d3qVCbAmfv+bNzL437zvz3gLGGMYYACAIQkN9vSiKnhyCIPhzSJLkcrkKZ0SLu5nbttVXV1dv9HoBY4xS+lxFReWGqi3bm3c0NZW53QAAp9OpKAohJG5BKdV1HULIZwgh2IKPCSEIIYwxX706RS72fxU88EagVc4EYIz1nTV27miEpzrbDig+n08QBFmWTdNkBRiGgTG2Te73v+bt2/8wxvTOd/vOwOA7aiZAPB4HACiKghAyckALkjsvz8A0TUop98Uz4ONCM5WajgyE1f17BgeRJEnZDGRZ1jSNS2GDMebuKKWMMQghQshetaUrNK/NzCym06H2fcM/XR6JRltbW7MBuL7ckU08Hr8HiS71nzsRaudvR5blvESqqvJLszFN0x4TQjRNMwzDvnZkYW9ACI2MjMRiYy0NvvEryTO9xq6WwN69r923DJKJxPUbNw4H34x817+YTld4a77o7VUUBXCnqqrqus7lXnIHHB4AIcSfNQ+QTCQopX8vLCym07Nzc8G3Aj2ffMQY27K9+YT+cSw2lpGI7y4qKlIU5Y4SYYtkInHkyOGe7u5kIoExjsXGwuEwQmh8YnJ8YvKXn3FjrfdYR3AxnfZurmto3r1wixqG4ff7AT8Uf5Qrl2hq/ubsxW+MT/XQ8I/f/zb2R33zng+1Lr4he8ncryRJvA74eaPR0UhkaHAQDQ1cqqvZCABY7y5xrAKljxc/CDIUFz1Q8tjqJ9Y8Uupc46t54ejxk+Ubni9a/ejR4yeTiUQkMoQxhhBmMrAl8vv9EEKryM72n//26y+NhyxfAIBXA4HT8LOX6nwtu3cd6+p8u61tXbnnqdKn15V7qjf5arc2vlj7cuMrTT3d3eFwGMLTvFRVVRUEIRvAlogX+jS5sqlq/aqHi/+anFppHdjk64Ax5nA4VFWNRkfHJyaHBi6sfdJR8syzI9HotZmZ5ddBoRmPxw3DyLcKl8ulaVoqNf37r3jr5qqySmF2bi4aHU2lplfUKmyTUooQyj9TLtH8/M3Qwdcrqr2Xfxi+51ZxB4kQQgCAjtChU10flLnXSoF9t+h1jPFKWwW6m0QIIZfLBSE81/d5WaVwdSqjSSo1vaSSoSURr+QVSMTTgRCGL5j7D6rB9w/ZOd43iSCEAABd19vf6/hzYsI+wv9mQAp61xKTf54NQAhRVVUUxTK3Wy7A6XRKksTHiqI4HA6Px6PkEARBFEVFUfiqYMFN+3NRFLMScUE8Ho9pmvZvUhRFfqs8FUmSNE0jhBiGQSm1GzBfVS0Kn4AkSZTSfIBlQgjRdX35+/8FhImmvWXI8G4AAAAASUVORK5CYII=" nextheight="525" nextwidth="698" class="image-node embed"><p>To find out if two polynomials share a common point (or cross paths), we need to set them equal to each other. Take this example:</p><p>$$$ x^3 - 2x^2 + 1 = x^3 - x^2 + 1 $$$</p><p>Solving for <code>x</code> gives us <code>x = 1</code>, a polynomial of degree 1. This means they only intersect at one point, which is <code>x = 1</code>. So, a polynomial of degree <code>d</code> can have up to <code>d</code> intersection points. This tells us that evaluating a polynomial at certain points gives us an accurate representation of the whole polynomial.</p><p>In this situation, a prover can show to a verifier, who knows a specific polynomial, that they know the polynomial too by evaluating it at certain points. For a polynomial of degree <code>d</code> and a coordinate <code>x</code> in the range</p><p>$$$ \langle 0, 10^{10} \rangle, \text{there&apos;s a} ; \frac{d}{10^{10}} $$$</p><p>chance that this polynomial has some overlapping points with another polynomial.</p><p>Another critical property of polynomials from a cryptography perspective is their ability to be factored. All polynomials with a valid solution (resulting in <code>0</code> after evaluation for <code>x</code>) can be reduced to separate degree 1 polynomials. For example, the polynomial:</p><p>$$$ x³ + 3x² + 2x $$$</p><p>is equivalent to <code>(x+0)(x+1)(x+2)</code>. By looking at the factored polynomial, it&apos;s easy to identify its solutions (or roots): <code>0, -1</code>, and <code>-2.</code></p><p>Let&apos;s say a prover claims to know a degree 3 polynomial that has roots at -1 and -2. We can then determine that the polynomial will be <code>(x+1)(x+2)</code>. As the prover knows a degree 3 polynomial, there must be another polynomial, <code>z(x)</code>which yields the desired result when multiplied with the target polynomial:</p><p>$$$ t(x) = (x+1)(x+2) $$$</p><p>Thus, we have the equation:</p><p>$$$ p(x) = t(x) * z(x) $$$</p><p>With this knowledge, how do we find <code>z(x)</code>? We can divide the polynomial <code>p(x)</code> by the target polynomial <code>t(x)</code>, resulting in:</p><p>$$$ z(x) = \frac{p(x)}{t(x)} $$$</p><p>Now, if the polynomial <code>p(x)</code> indeed has roots at <code>-1</code> and <code>-2</code>, the division outcome will not have a remainder. Let&apos;s examine this using our example and perform the calculation:</p><p>In the example above, we transformed the target polynomial <code>t(x)</code> from its factored form <code>(x+1)(x+2)</code> to <code>x^2 + 3x + 2</code>. This calculation gives us a result of <code>z(x) = x</code>, with no remainder. Now, let&apos;s see what happens when we make a small change to the polynomial <code>p(x)</code> for comparison.</p><img src="https://images.mirror-media.xyz/publication-images/A9znWF17LHlGvmsFK_1-_.jpg?height=281&amp;width=385" alt="" title="null" class="image-node embed"><p>The polynomial <code>p(x)</code> now begins with <code>2x³</code> instead of <code>x²</code>, resulting in a division remainder of <code>7x+6</code>!</p><p>With this understanding, we can develop a simple protocol where:</p><ol><li><p>A verifier randomly generates a value <code>x</code>, evaluates the target polynomial <code>t(x)</code>, and provides the value <code>x</code> to the prover.</p></li><li><p>The prover evaluates the polynomial <code>p(x)</code> at the given value <code>x</code>, calculates <code>h(x)</code>, and provides evaluations of <code>p</code> and <code>x</code> to the verifier.</p></li><li><p>If the equation <code>p(x) = t(x) * z(x)</code> holds, then <code>p(x)</code> has factors <code>t(x)</code>.</p></li></ol><p>Note that the values the prover provides to the verifier are evaluations of the polynomial at <code>x</code>, so the verifier does not know the polynomial itself. However, this protocol allows the prover to cheat and compute another polynomial by merely selecting a random value of <code>z(x)</code>. Additionally, it doesn&apos;t enforce the polynomial&apos;s degree, as the verifier can create a polynomial of any degree that makes <code>p(x) = t(x) * z(x)</code> hold. Both limitations will be addressed later.</p><div class="relative header-and-anchor"><h4 id="h-modular-math-and-cyclic-groups"><strong>Modular math and cyclic groups</strong></h4></div><p>Before we dive into commitment schemes, let&apos;s explore modular math and prime fields.</p><p>A prime field <code>p</code> is a group with p elements that is generated by a single element <code>g</code>, and every element in the group can be written as <code>g^k</code> for some integer <code>k</code> in the range <code>{0, 1, 2, ..., p-1}</code>. The group&apos;s order is equal to the number of elements in the group, which is <code>p</code>. A simple example of a prime order <code>p</code> group is the group of integers modulo a prime number <code>p</code>.</p><p>For example, if we choose <code>p = 7,</code> then <code>Z_7</code> is the cyclic group <code>{0, 1, 2, 3, 4, 5, 6}</code>. Let&apos;s choose the generator <code>g = 3</code>, which means that the powers of 3 modulo 7 generate all the elements in the group:</p><p>$$$ \begin{align*} 3^0 &amp;\equiv 1 \pmod{7} \ 3^1 &amp;\equiv 3 \pmod{7} \ 3^2 &amp;\equiv 2 \pmod{7} \ 3^3 &amp;\equiv 6 \pmod{7} \ 3^4 &amp;\equiv 4 \pmod{7} \ 3^5 &amp;\equiv 5 \pmod{7} \ 3^6 &amp;\equiv 1 \pmod{7} \end{align*} $$$</p><p>In modular math, the result of a calculation is expressed as the &quot;remainder&quot; from the calculation on the left-hand side and division by <code>p.</code> In the above example, the first two results don&apos;t leave any remainder, as the numbers are smaller than <code>p</code>. But, for any calculation where the result is greater than or equal to <code>p</code>, the modular calculation outcome will be the remainder (though division is more complex).</p><p>Why is this important? In cryptography, modular arithmetic is useful to ensure that a committed value or hashed input remains concealed. If we operated on natural numbers, it could be easier to reverse engineer the hiding of an underlying value, weakening the protocol. But, when using modular arithmetic and limiting the results of any calculation to a few possible outcomes, it&apos;s much harder to return to the original value, as many different starting points can lead to the same result.</p><p>Now that we&apos;ve learned about two powerful mathematical tools in cryptography - polynomials and modular math - let&apos;s delve deeper.</p><div class="relative header-and-anchor"><h4 id="h-cryptographic-commitments"><strong>Cryptographic commitments</strong></h4></div><p>A cryptographic commitment scheme is a technique that allows someone to commit to a value without revealing it and later prove that the value hasn&apos;t been changed or tampered with.</p><p>In a commitment scheme, the committing party uses a mathematical algorithm (like a hash function) to create a commitment, which is a fixed-length string representing the hidden value. The commitment is shared with the other party, who can&apos;t deduce anything about the value from the commitment itself.</p><p>To illustrate this idea, imagine Alice and Bob, two friends who love playing games together. Alice has to leave town for a while, but they decide to keep playing games over the phone. They choose rock-paper-scissors but, being competitive, they don&apos;t trust each other to reveal their picks honestly. So, Alice and Bob create a protocol for playing rock-paper-scissors remotely:</p><ol><li><p>They agree on a cryptographic hash function, such as SHA-256.</p></li><li><p>They agree on a secret &quot;salt&quot; value that&apos;ll be added to each move before hashing to prevent pre-computed hashes. The salt should remain secret and change after each round.</p></li><li><p>Alice and Bob secretly pick a move each.</p></li><li><p>They both compute a commitment to their move by hashing their move and the salt value with the agreed hash function. For instance, Alice might calculate: <code>H(Alice&apos;s move) = SHA-256(&quot;rock&quot; || salt)</code> where &quot;rock&quot; is her move and &quot;salt&quot; is the secret salt. Bob does the same for his move.</p></li><li><p>They exchange commitments over the phone, without disclosing their moves or the salt value.</p></li><li><p>After exchanging commitments, they &quot;reveal&quot; their moves and the salt value by telling each other their choices and the salt value.</p></li><li><p>They verify that the other player&apos;s commitment matches the revealed move and the correct salt value by hashing the move and salt value together.</p></li></ol><p>Alice and Bob can now repeat steps 4-7 for as many rounds as desired, changing the salt value after each round.</p><div class="relative header-and-anchor"><h4 id="h-polynomial-commitments"><strong>Polynomial commitments</strong></h4></div><p>Polynomial commitment schemes (PCS) work like cryptographic commitments, but for carrying information they use polynomials instead of regular statements. In a PCS, a prover wants to show to a verifier that they know a polynomial without revealing its coefficients. To do this, the prover creates a commitment to the polynomial and the verifier can then use this commitment to make sure the polynomial is correctly computed at specific points, without actually seeing the coefficients.</p><p>Each PCS needs to have the following properties:</p><ul><li><p>Binding - different polynomials can&apos;t result in the same commitment.</p></li><li><p>Hiding - a commitment doesn&apos;t give away any information about the polynomial.</p></li></ul><p>These properties are similar to the one-wayness and collision resistance of hash functions. There are different types of PCS used in ZK-SNARKs, and each has its pros and cons. The most popular commitment scheme is KZG (from Kate, Zaverucha, Goldberg). Other commitment schemes with different properties used in SNARKs are FRI and DARK.</p><p>KZG boasts several distinct features that make it particularly useful for SNARKs:</p><ul><li><p>Generates constant-size proofs regardless of polynomial length (a single elliptic curve group element).</p></li><li><p>Offers constant verification time (two pairing operations).</p></li><li><p>Uses elliptic curve pairings as its cryptographic engine.</p></li></ul><p>However, KZG needs a trusted setup, which means a trusted party (or parties) has to generate secret, random values to hide the polynomial (akin to Alice and Bob&apos;s &quot;salt&quot; value in their phone game). These values, used to calculate a common reference string (CRS), should then be destroyed so nobody can learn them and break the protocol.</p><p>In practice, to lower the risk of a malicious agent, multiple parties join the trusted setup creation process and generate their own parameters (&quot;salt&quot; values), which are multiplied by values created by other participants (Multi-Party Computation, or MPC). With this approach, as long as one party is honest and doesn&apos;t share its generated parameters, the whole procedure stays safe. When you hear about a &quot;ceremony&quot; for a trusted setup, that&apos;s what&apos;s going on.</p><div class="relative header-and-anchor"><h4 id="h-elliptic-curve-pairings"><strong>Elliptic curve pairings</strong></h4></div><p>Elliptic curve pairings are a complex encryption technique that employs advanced mathematical algorithms to protect data. They utilize an elliptic curve along with a special mathematical operation called a pairing to perform cryptographic tasks.</p><p>An elliptic curve is a mathematical object that looks like a wavy line on a coordinate plane. It is defined by the equation:</p><p>$$$ y^2 = x^3 + a*x + b $$$</p><p>representing a smooth curve in a two-dimensional space (over a prime field). In the context of cryptography, elliptic curves are usually defined over finite fields, particularly over prime fields (integers modulo a prime number).</p><p>Pairing is a unique kind of function that combines two points on an elliptic curve to generate an element of a target group (a multiplicative group of a finite field). Bilinear pairings are the most frequently used pairings in cryptography. For a pairing <code>e: G1 x G2 → GT</code>, where <code>G1</code> and <code>G2</code> are cyclic groups and GT is the target group, the function <code>e</code> is bilinear if it satisfies the equation</p><p>$$$ e(g^a, f^b) = e(a^g, b^f) = e(ab^{gf}) \quad \forall g \in G_1, f \in G_2 $$$</p><p>and integers <code>a</code> and <code>b</code>. Elliptic curve pairings thus enable the multiplication of exponents in the polynomial encrypted in this form, which is not possible with other encryption forms (e.g., hashes).</p><p>With all this information, we are now ready to build our zk-SNARK.</p><p><strong>Constructing a zk-SNARK with the KZG polynomial commitment scheme</strong></p><p>Step 1 » Calculating the polynomial</p><p>We begin by calculating the polynomial using the QAP procedure discussed in the previous article. The polynomial is represented as <code>t(x</code>) with degree <code>d</code></p><p>$$$ t(x) = -516x^4 + 1054x^3 - 714x^2 + 194x - 18 $$$</p><p>Step 2 » Establishing the trusted setup</p><ul><li><p>A trusted party (or multiple parties in MPC) generates a secret, random value <code>s</code> used to encrypt the polynomial. This secret value <code>s</code> is produced in the prime group <code>g</code> as:</p><p>$$$ g^s, g^{s^2}, g^{s^3}, \ldots, g^{s^n}</p><p>$$$</p></li><li><p>Group <code>g</code> constrains the degree of the polynomial used in the commitment.</p></li><li><p>The secret value <code>s</code> and group <code>g</code> form a Common Reference String (CRS) when evaluated with the polynomial’s coefficients, with each coefficient evaluation being a point on the elliptic curve. After generating the CRS, the value <code>s</code> must be deleted.</p></li><li><p>With the trusted setup in place, we can commit to polynomial <code>t</code> at point <code>s</code>, as shown in the expression below:</p><p>$$$ t(s) = g^{t(s)} = g^{-516s^4 + 1054s^3 - 714s^2 + 194s - 18} $$$</p></li></ul><p>Step 3 » Proof generation (opening)</p><ul><li><p>To prove the commitment to the polynomial <code>t(x)</code>, the prover must &quot;open&quot; the commitment at the point <code>s</code> (even though its value remains unknown). The prover evaluates the polynomial using the CRS&apos;s publicly available values, all hidden within the group <code>g</code>.</p></li><li><p>Next, the verifier selects another point <code>z</code> and provides it to the prover. The prover calculates the polynomial:</p><p>$$$ h(x) = \frac{p(s) - p(z)}{s - z}</p><p>$$$</p><p>Now, let’s revisit our earlier example with the target (vanishing) polynomial. The prover has to find a polynomial that satisfies the condition <code>p(s) - p(z) = 0</code>, which naturally occurs when <code>s = z</code>. Consequently, the value <code>s - z</code> divides the polynomial <code>p(s) - p(z)</code> without remainder. The fact that there is no remainder will serve as proof of the evaluation of the polynomial at the point <code>z</code>.</p><p>Although complex, this calculation lies at the heart of the KZG polynomial commitment scheme, making it essential to understand. Feel free to get back to the section about polynomial properties, if required.</p></li><li><p>As <code>x</code> can take any value, the prover evaluates the proof <code>h(x</code>) at <code>s</code> instead of x. This results in equality</p><p>$$$ p(s) - p(z) = (s - z) * h(s) $$$</p><p>which serves as proof of the evaluation. The prover sends this proof to the verifier.</p></li></ul><p>Step 4 » Evaluation</p><ul><li><p>The proof received by the verifier requires further transformation because <code>s</code> is unknown. To represent <code>x</code> as a point on an elliptic curve <code>[x]</code>, we add <code>x</code> to itself <code>g</code> times, where <code>g</code> is a prime field group. The original polynomial evaluates to:</p><p>$$$ [p(s)] = g \times (-516s^4 + 1054s^3 - 714s^2 + 194s - 18)</p><p>$$$</p></li><li><p>The relationship to be verified looks then as follows:</p><p>$$$ [h(s)] * [s - z] = [p(s)] - [p(z)] $$$</p></li><li><p>Each value has been transformed into a point on an elliptic curve:</p><ul><li><p><code>[h(s)]</code> represents the evaluation of <code>h(x)</code> using CRS values, added to itself <code>g</code> times, equivalent to a commitment to <code>h(s)</code>.</p></li><li><p><code>[p(s)]</code> represents the evaluation of the original polynomial <code>p(x)</code> at CRS values, added to itself <code>g</code> times.</p></li><li><p><code>[p(z)]</code> represents the evaluation of the polynomial <code>p(x)</code> at the verifier-provided value <code>z</code>, added to itself <code>g</code> times.</p></li><li><p><code>[s - z]</code> corresponds to the difference between <code>s</code> and <code>z</code>, evaluated at CRS values. However, we can&apos;t do much about it now since <code>s</code> is secret.</p></li></ul></li></ul><p>Also, note that elliptic curve points can&apos;t be directly multiplied, so calculating the below part will require the elliptic curve pairings:</p><p>$$$ [h(s)] * [s - z] $$$</p><p>Step 5 » Verification</p><ul><li><p>To verify the proof, we work with two prime groups, <code>G1</code> and <code>G2</code>, and their generators <code>g</code> and <code>f</code>, respectively.</p></li><li><p>Let’s denote the addition of the secret point s in group <code>G1</code> <code>g</code> times as <code>[s]1</code>, and the addition of <code>s</code> in group <code>G2</code> <code>f</code> times as <code>[s]2</code>.</p></li><li><p>The pairing of <code>G1</code> and <code>G2</code> is denoted as <code>GT</code>, a multiplicative target group.</p></li><li><p>With <code>[s - z]</code> in group <code>G2</code> and <code>[p(z)]</code> in group <code>G1</code>, the verifier checks the equality:</p><p>$$$ e(h(s), [s - z]^2) = e([p(s) - p(z)]^1, f)</p><p>$$$</p></li><li><p>The above equation presented in the pairing group looks as follows:</p><p>$$$ [h(s) \cdot (s - z)]^T = [p(s) - p(z)]^T, \quad \text{where} ; [x]^T = e(g,f)^x</p><p>$$$</p></li><li><p>This equation is equivalent to our familiar</p><p>$$$ h(s) * (s - z) = p(s) - p(z) $$$</p></li><li><p>and the verifier can finally confirm if it holds! Let&apos;s take a breath and review each part once again:</p><ul><li><p><code>[h(s)]</code> is provided by the prover.</p></li><li><p><code>z</code> is selected by the verifier.</p></li><li><p><code>[s - z]2</code> can be computed using <code>[s]2</code> (calculated in group <code>G2</code> during the trusted setup) and verifier-selected <code>z</code>. Calculating <code>[s - z]2</code> is equivalent to <code>[s]2 - [z]2</code>.</p></li><li><p><code>[p(s)]</code> is the commitment provided by the prover.</p></li><li><p><code>[p(z)]1</code> is calculated and provided by the prover at the verifier&apos;s request.</p></li></ul></li></ul><p>And there you have it! The verifier successfully confirmed whether the prover truly knows the polynomial they claimed to know. Quite the adventure, right?! To summarize the entire process:</p><ol><li><p>In the trusted setup, a random value <code>s</code> is generated along with two sets of elliptic curve points <code>[s]1</code> and <code>[s]2</code>. The value <code>s</code> is then discarded.</p></li><li><p>The prover commits to the polynomial <code>p(x)</code> using CRS elements from the trusted setup.</p></li><li><p>The verifier selects point <code>z</code> and shares it with the prover, requesting the evaluation of <code>z</code> with <code>p(x)</code>.</p></li><li><p>The prover evaluates <code>p(z)</code> and shares the proof with the verifier in the form of an elliptic curve point <code>h(x)</code>.</p></li><li><p>The prover calculates the pairing equation and confirms if it holds.</p></li></ol><p>Congratulations if you made it through! Don&apos;t hesitate to re-read any sections you didn&apos;t fully understand. It took me some time for all of this to click, so don&apos;t be discouraged if everything isn&apos;t clear even after a few reads.</p><p>In Part III of this article series, we will look into other types of commitments focusing on transparent proofs, an alternative method that doesn&apos;t require a trusted setup. Stay tuned as we explore their inner workings, advantages, and drawbacks.</p><p>I couldn’t write this piece without the following sources:</p><ul><li><p>Vitalik Buterin, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://vitalik.ca/general/2019/09/22/plonk.html"><em>Understanding PLONK</em></a></p></li><li><p>Dankrad Feist, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html"><em>KZG Polynomial Commitments</em></a></p></li><li><p>Ozgur Ozerk, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://blog.subspace.network/kzg-polynomial-commitments-cd64af8ec868"><em>KZG Polynomial Commitments (based on Dankrad’s article)</em></a></p></li><li><p>Alexander Comerford, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://taoa.io/posts/Understanding-KZG10-Polynomial-Commitments"><em>Understanding KZG Polynomial Commitments</em></a></p></li><li><p>David Wong, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.youtube.com/watch?v=RUZcam_jrz0&amp;list=PLBJMt6zV1c7Gh9Utg-Vng2V6EYVidTFCC&amp;index=1"><em>How does PLONK work?</em></a></p></li><li><p>Maksym Petkus, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://arxiv.org/pdf/1906.07221.pdf%EF%BC%9B"><em>Why and How zk-SNARK Works: Definitive Explanation</em></a></p></li></ul>]]></content:encoded>
            <author>rafal@newsletter.paragraph.com (rafal)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/69147ae4aaa169e472a80aa1b53f8d28.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[GMX: An In-Depth Analysis]]></title>
            <link>https://paragraph.com/@rafal/gmx-an-in-depth-analysis</link>
            <guid>rVTPkZE3yYdNdeCr1aQD</guid>
            <pubDate>Sat, 23 Dec 2023 18:24:19 GMT</pubDate>
            <description><![CDATA[Lately, the DeFi space has emphasized the importance of long-term viability and profitability. This may be a shocking concept to some, but it&apos;s ...]]></description>
            <content:encoded><![CDATA[<p>Lately, the DeFi space has emphasized the importance of long-term viability and profitability. This may be a shocking concept to some, but it&apos;s natural for protocols to be viewed in a similar way to traditional businesses. Thankfully, the old model of extracting value through inflation is fading away, and projects are now focused on providing actual value to their users.</p><p>GMX is a great example of a protocol that has embraced this philosophy. It has been available for just over a year but has already established itself as a major player in the space thanks to its impressive fee generation and TVL. As with many great projects, its success is the result of a combination of elegant design and innovative thinking. But what sets GMX apart? Let&apos;s take a closer look.</p><p><strong>What is GMX and how does it make money?</strong></p><p>GMX is a perpetual exchange that runs on the Arbitrum and Avalanche blockchains, with the majority of activity happening on the former. Perpetual exchanges are platforms for trading perpetual futures contracts, which are like regular futures but don&apos;t have an expiration date. With GMX, you can speculate on the price of an asset without actually owning it.</p><p>GMX has two tokens: GMX for governance and GLP for pooling assets from lenders. The GLP token is an index of blue-chip tokens that consists of about half stable assets and half risky assets. Users can deposit supported tokens into the pool in exchange for GLP tokens. The current index composition and target weights on the Arbitrum chain (which will be used for all future references) are as follows:</p><img src="https://storage.googleapis.com/papyrus_images/2b5ca43ebba9e5d709c2d6d8e420c585.jpg" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAIAAAD4YuoOAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC8ElEQVR4nH1UW2sTQRgdEljpdjvdS6fjuNnsJXuZTrdJttvdNGnapBfbSkUsXii+6FOVokUQURHsg68VBEH8F33w0Yf+EH+F+uhDJZkakt0ozMMw8zHnnO+cb4A/12XhdRZuz9d2Wbg9a6TFgi0IFUGoDDbC6P7/h4MrvoAEAwkGAJj5amIk09O0WLAlGBB9afjFYsGegtRyWhIMxsIgEpWtJtZjcPTsJG3e0nBdwVVhwh0FSFVcFYRKD8BIZC2EMh0GMJ2WrIUyCkXRywBAmWI9RmQR/Px98fzFKdZjDdczXEynRYxUFF0JBhW/49N1YiS8pliwocp82rGcFY92JRjkWzRDolk9Bt8+vrqze1vV02rtxjWzMcyFGMlVIxFFTxQ9YiS9jqFwQEKCAadVslIJ+nkARCJEInD+6e3d3f0pVNfLKVRYBoAYCTdJLzd0qylrGYClGRKVnOZYBYhEGq6Dgzffl3deUtqeIdFwi0TRM/seFoAFVeb5XdttD+C5B7bbNp0W1pfyPvMWESMBB3vvQnZTwQviZJYFIhEPiQQDRBaxHg/r44carvMg5Nc0CmUtBD+OPx92HppsXZlZyFR4wRpU5riflG36dH0QymLBlrWQKxg4n1FAjLRsNcH+4y/RygPdiGUUZoqwHg8U8IfkUZOJkSCySPpByAOouIpJBB69P2/tHllWquBaftCgfDlojrdquitoyCcJBpazQozEdtt9Hk4GQMP13qCdfD3buH9YKiUTU1kPTKcFVdZrkdzzs+KvDjPlo9Q3Of5Xi0rWMjg+/dDYuqeqYWaMBaEia+HkpMcVYD3Om6zhOiKRrGV7e8lAYTIKwcWvs9dPnwDgTVwZuRZFt28y4yYHdIOyrcG0c5N92vGCtZK1PFaBXm7Ybhu0G20/aEFlPk+BfzJ/Y9qbmowCFVd7H5TCxiqYghQqDMzXOkuNPVLKRk0UPY92exXAhApbqO1QtjkSUxT6dN2jXdNpjVWA9dhx238Aa76lFQuyCSoAAAAASUVORK5CYII=" nextheight="602" nextwidth="1189" class="image-node embed"><p>A crucial feature around which GMX is built is that, unlike traditional DEXes that rely on the constant product market maker model (x*y=k), GMX utilizes Chainlink oracles to feed price data from centralized exchanges, enabling trades with no slippage. While this is a positive for traders, it also leaves the protocol vulnerable to price manipulation and limits its scalability potential. We will delve into these issues later on.</p><p>GMX incentivizes participants to deposit underweight assets or withdraw overweight assets by structuring the fees accordingly - it’s less expensive to deposit underweight assets or withdraw overweight ones than another way around. This is the first way the protocol generates revenue - through the minting and burning of GLP tokens.</p><p>The protocol can also function as a DEX, where GLP index tokens are traded. To incentivize users to maintain the optimal asset mix in the pool, GMX adjusts trading fees based on the desired balance of assets. This is the second way the protocol makes money.</p><p>The third way GMX generates revenue is through margin trading. The protocol charges a fee of 0.01% on the size of the position whenever a position is opened or closed. Additionally, GMX has a borrow fee of 0.01% per hour, which is calculated based on the ratio of borrowed assets to total assets in GLP. When a position is closed at a loss or liquidated, the resulting profit goes to the protocol. This is where the majority of GMX’s earnings come from, so let’s take a look at those in more detail:</p><img src="https://images.mirror-media.xyz/publication-images/iZb_BOGsdDMWUmcT34Scj.png?height=523&amp;width=697" alt="Source: https://stats.gmx.io" title="null" class="image-node embed"><p>Since its debut in September 2021, GMX has generated an impressive $40 million in profits (on Arbitrum alone and not including fees). When you factor in the fees, the protocol has been wildly successful, with a total haul of $135 million on Arbitrum and an additional $31 million on Avalanche.</p><img src="https://images.mirror-media.xyz/publication-images/GhTDEUim_1amJRFhQs62b.jpg?height=512&amp;width=706" alt="Source: https://stats.gmx.io" title="null" class="image-node embed"><p>The generated earnings are then shared with GLP and GMX token holders. The protocol rewards GLP holders with a 70% cut of the fees they earn, which can translate to APR in the 20-40% range (depending on the amount of fees collected in a given week). It is not discouraging that the rewards are paid in wETH/AVAX and escrowed GMX. GMX token holders receive the remaining 30% of the accrued fees, which amounts to approximately 10-20% APR.</p><p>GMX is self-funded, so no VCs are lurking around ready to dump on retail. The protocol is designed to prioritize the community, with the distribution that allocates only 2% of the GMX tokens to the team (250,000 out of a total of 13 million). As for the future, the number of tokens in circulation may increase beyond the current 13 million if the DAO votes in favor of it.</p><p>As a GMX token holder, staking your tokens not only allows you to earn rewards but also grants you the opportunity to participate in governance and rack up Multiplier Points to enhance your rewards (similar to veCRV in Curve Finance). While the esGMX tokens are locked up for a year, they can still be staked to earn rewards just like regular GMX tokens.</p><p>Holding GMX tokens is essentially a bet on the continued growth and adoption of the protocol, without exposing investors to the risks of being a counterparty to traders via holding GLP. However, if something were to happen to GLP, the value of GMX tokens would plummet in no time.</p><p><strong>Risks for GMX and GLP holders</strong></p><p>While the protocol is well-thought-out in terms of earnings and rewards, are there any design flaws that could hinder its scalability or cause it to crash? To answer this question, we need to dive a little deeper into how GMX operates.</p><p>As previously mentioned, the protocol relies on Chainlink oracles to feed asset prices to its ecosystem. This eliminates slippage but also exposes GLP holders to market manipulation. In early 2022, a trader on Avalanche exploited this vulnerability by opening and closing a series of long/short AVAX positions on GMX while simultaneously manipulating the price of the coin on centralized exchanges. This scheme resulted in a loss of approximately $500,000 for GLP holders, although it&apos;s possible that the attacker didn&apos;t profit at all due to the overall costs incurred. The GMX team responded swiftly by imposing limits on AVAX&apos;s open interests, though this isn&apos;t exactly the embodiment of a trustless protocol.</p><p>Might something akin to the AVAX incident occur on Arbitrum? It&apos;s not out of the realm of possibility, although the greater liquidity of ETH and its larger market cap make it less prone to price manipulation.</p><img src="https://images.mirror-media.xyz/publication-images/mnE4DdeiCU08LQzsZbb9g.png?height=628&amp;width=1640" alt="AVAX price during the manipulation attack on GMX" title="null" class="image-node embed"><p>Another potential danger for the GLP pool is during times of extreme volatility. This could occur in the following way:</p><ol><li><p>Multiple leveraged short positions are opened during a market downturn (resulting in a large net open short position in the protocol).</p></li><li><p>A significant piece of negative news hits the market.</p></li><li><p>The swift decrease in the value of risk-on assets in the liquidity pool causes the price of GLP to plummet.</p></li><li><p>The leveraged shorts’ profits are paid out from the stablecoins in the pool.</p></li></ol><p>GLP is designed to fully back any open positions in GMX. As such, it&apos;s not possible to open a short position with more capital than is available in the pool (so that when all positions close, the protocol will still be able to pay out the rewards to all successful traders). This feature, combined with the restriction on short open interest, should prevent such an attack from occurring or having an outsized impact.</p><p>However, imposing a cap on open interest may present scalability issues. If the platform&apos;s GLP deposits increase while GMX is simultaneously capping short interest, the fees generated from trading will be limited, resulting in reduced returns for GLP holders and leading to the withdrawal of the funds from the pool.</p><p>A partial solution to this problem may be the introduction of something akin to a funding rate used on centralized perp exchanges. The funding rate is a fee paid by one side of a trade to another to ensure that the price of the contract stays aligned with the underlying asset. In the GMX context, if there is an excess of short or long open interest, the funding rate can be adjusted to even out the net difference in the positions.</p><p>One way to monitor the risk of the GLP pool is to keep track of net open interest on the platform. If the stablecoin portion of the pool is significantly greater, in USD terms, than the net short open interest in the protocol, GLP can be considered healthy. For example, if traders are net short USD 25 million and the stablecoins deposited in GLP are worth USD 200 million, the ratio would be 1/8, which would typically be considered healthy. The threshold for what is considered unhealthy may vary based on an individual&apos;s risk tolerance; for my part, I would consider leaving GLP if the ratio reached around 1/4. It&apos;s worth noting that liquidity providers can withdraw stablecoins up to the amount of the open short interest.</p><p>Since it is vital to keep an eye on the health of GLP, feel free to use my Dune query to check on the health of GLP <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dune.com/queries/1743487">here</a>.</p><img src="https://images.mirror-media.xyz/publication-images/3KPRF3wY27mbZITnkPJTi.png?height=232&amp;width=978" alt="" title="null" class="image-node embed"><p>The query shows the current short, long, and net open interests along with the amount of stablecoins in GLP. The Health Factor is the ratio of net open interest (calculated only if negative), to the USD value of the stablecoins in the pool. Using the numbers from my above example, the factor of 12,5 should be safe, but if it goes up to 25, I would be thinking about getting out. This is a hypothetical scenario and most likely, if short interest were to run amok, the team would step in to tame it.</p><p><strong>Glance at valuations</strong></p><p>This article begins by highlighting the shift in the crypto industry towards a focus on financially sound, long-lasting protocols. Let’s then see how GMX performs when evaluated using some crucial metrics. For the sake of comparison, we will also assess dYdX, a competing crypto perp exchange that, much like centralized exchanges, follows the order book model. This model involves matching buy and sell orders and using a funding rate to balance the open interest between long and short contracts.</p><p>In December 2022, both protocols had a similar TVL of $460 million. However, over the past six months, GMX has generated $59 million in earnings, while dYdX has made approximately half of this at $38 million. That is what you call capital efficiency.</p><img src="https://images.mirror-media.xyz/publication-images/7HmxYXp8xr5YF-jvoDes5.png?height=504&amp;width=1032" alt="Source: https://tokenterminal.com" title="null" class="image-node embed"><p>When looking at the price-to-sales ratio on the fully diluted market cap over the same time frame, GMX presents a relatively favorable factor of 12, while dYdX&apos;s ratio is less impressive at 24. For reference, Apple currently boasts a P/E of 23. It&apos;s important to keep in mind, however, that when evaluating businesses, expected future earnings are crucial. A company or protocol may have a high P/E or P/S ratio, but if it is anticipating to significantly grow earnings or sales in the future, the high ratio can be justified.</p><img src="https://images.mirror-media.xyz/publication-images/KnuvOJhZH2au9xDQ9P3uy.png?height=519&amp;width=1023" alt="Source: https://tokenterminal.com" title="null" class="image-node embed"><p>GMX is determined to increase its TVL by not only introducing new or upgrading existing products (stay tuned for the highly anticipated X4 release), but also by expanding to other blockchains. It will be fascinating to see if the protocol can maintain its advantage over dYdX, and how its oracle-based model holds against order book or AMM approaches.</p><p><strong>Final thoughts</strong></p><p>GMX is a formidable project that has carved out its niche in the DeFi world, proven itself to be resilient in difficult circumstances, boasts solid foundations, and has a flourishing ecosystem and grand expansion plans. Sure, there will be obstacles to overcome, particularly in terms of vertical scaling, but let&apos;s be real - creating a blue-chip protocol is no walk in the park.</p><p>From a user perspective, there are certain risks associated with holding GMX or GLP, but they are manageable, particularly given the robust and sustainable returns offered by the protocol. Does anyone still remember DeFi 2.0? I would argue it came with GMX.</p>]]></content:encoded>
            <author>rafal@newsletter.paragraph.com (rafal)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/2b5ca43ebba9e5d709c2d6d8e420c585.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[How Curve and Convex work in symbiosis]]></title>
            <link>https://paragraph.com/@rafal/how-curve-and-convex-work-in-symbiosis</link>
            <guid>v25aeHwUnynAUI38JMrq</guid>
            <pubDate>Sat, 23 Dec 2023 18:21:49 GMT</pubDate>
            <description><![CDATA[What is Curve Finance and how does it work?Curve Finance is a decentralized exchange (DEX), that allows users to swap between stablecoins with minima...]]></description>
            <content:encoded><![CDATA[<p><strong>What is Curve Finance and how does it work?</strong></p><p>Curve Finance is a decentralized exchange (DEX), that allows users to swap between stablecoins with minimal slippage. The protocol is based on the constant product market maker formula, a major innovation brought by Uniswap.</p><p>Decentralized exchanges such as Uniswap are great for trading assets with fluctuating price, but do not work well for pairs of stablecoins. The main issue is the price discovery mechanism of the constant product market maker model (CPMM) used by Uniswap and similar DEXes. This inherited design flaw may go unnoticed for trades where the price of at least one of the tokens is fluctuating (e.g. when buying ETH for USDC). However, when trading two coins with a similar price (e.g. USDC for USDT or ETH for sETH), it is much more annoying as it leads to bigger price difference between assets that should be priced 1:1. Let’s see how Curve optimizes this price discovery mechanism for stablecoins.</p><p>In the regular CPMM model, the total amount of coins in the liquidity pool is determined by the formula x*y=k, where x is the amount of token A (e.g. ETH), y is the amount of a token B (e.g. USDC), and k is constant. Since k is constant, to withdraw ETH from the pool, the user must deposit USDC in the amount determined as total ETH/total USD. Each ETH withdrawn will reduce the supply of ETH in the pool and increase the supply of USDC, thus driving up the price of ETH. This process can be represented by the following function, with the asset price shown as a point on this function.</p><img src="https://storage.googleapis.com/papyrus_images/2a11a5cd308d8e9d17819fc58dae5b7d.jpg" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAATCAIAAAB+9pigAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEVklEQVR4nJWUb0wbZRzHL/pm1hcTX0hExX+J+pLExuxe8GJNXN9UdqjH2I6ti/WQQ0oZXoXGDcMOQuJmZ5ZLSG2gyjpG6sJR0uGAFQ6WRkb5dxCOmt10dhPOjF4yyhXajj6GPtKCm5N97knuuee55/d9fs/v9/yQeDwOAHC73TRN3xgfF4TZUCgkbRHeQlGUaBolzfa+oiiyLMNBWZYlSRJFUZIkkAaBAkNDQxfdF+pPMSaTxd8/OD8/LwgCz/Pn7eedrU6WZfEtyDREGpIkLRYLRVE0TZMkiWEYTdM+n8/j8bAsu0NgdGS018tVmOtstpal8F04J8vy5Pj03T8Wg8Fg6eFSgiBwHMcwzGazEQSBpSFJkqIojuOMRqNer4d2o9Gox+PZ6cHokPfnbrP1pP1c++JvYTi3tLT4+81fE/FYIBAgiDIcx1EUNRqN0DrLsj6fj2EY6AHDMCzLYhim0WgKCwuzAgCAWCL2wju5yF4EQZADJcXdvT9lPAhOzEq37vD8CI7jBoPBaDTabDaKohoaGux2O8MwNpuN47hoNCqKoqIoMACiKLrd7qwAAIBtY79tPWuqrqJqv7I11WUEvm/3XPRcvXKlD0X3oWl0Ol1BQQFBEDqdDkVRrVYLN/uv4GcF4BFxHNfS3HzmzHef1ZyqrKkAAGykNuJpUqkHMTUGtgHHM58Zo9FtDAwMwH8QQRA0Go0kScFgkON6jJX15dXl6oqaXptaUVcSDxJqTF1RV9bW19SYGn8U4CF4nv9HQBRFg8HgcrmOGY0XfvzhU6r2YNnhv+4spne6Xnwc+8j08RGKaLQzphOmEvJQSApBJx42+miBaDTKsqwsyzzPj46MXvP3v/Xuez2ePgCAurr6xmuv79E8m5+fT5LlKLoPeeppQRCeTCBzrBzHOZ3O4Eyw0d5UiH54Y2wKjicTicfb+h8B+FIUBd7AvsG+S32dC+KtYrwydPM2AKlM3P7ruHcrwDDMZc/luYW5Dm/H5vmsrTEtTp/X/xgryWQykUhCtncAAP5BfzYGAACtVrt5zRAkNy837+08rAjDsCK9Xg8HX3k5/9w3Z5fCf6qrq5n2ZB7QNA1tWeusVfVVvl6f2+3mOO6av7+i3IIgz+19/qX7kftcl3d48Prw4HVf99XAyNhYYGLil6lMm5sRhcnZyfGZqbFpV5trI7WRFZBlufF0o7fHa2+1HzKXZqpuOLxZl97MfxVBkBa7y0w3VVi+Jo6fsFibj35Cf4CZ9r9fUnbMQlbUfW4+eeQoVftF45d1DE2frjLTAIBEIpmNgSAILMs+8+IeBEE6uc6uS10Oh0OW5YWFEHSuvb0NADDCD9fUVMfj65HI8tT0pE63f2lpMRJZDodv6/UHBEG4t3wvElkuOlgUCASyaQqJqTFHh8PaZFVjmw8MDwAARdGcnBxFUWBRwXGc53lYJERRBCAFE1qSpEyawdq3Q2A3KQiTTavVOhyOXS75GwsNZqVW2/YUAAAAAElFTkSuQmCC" nextheight="615" nextwidth="1002" class="image-node embed"><p>As seen above, the price of two assets in the Uniswap model (purple dashed line) is more sensitive to changes in the pools’ reserves, resulting in a more curved invariant.</p><p>On the other hand, in the pool where the price changes evenly (the withdrawal of token A changes the price of token B by the same amount), the function is linear. As such, in this model, the sum of the prices of both assets is always constant.</p><p>Curve&apos;s innovative approach combines the best of both worlds by implementing the constant product and constant sum models in a way that the function is linear when the supply of coins is balanced but becomes more curved when there is a greater difference between the reserves. Thanks to this elegant solution, the protocol can offer better prices for trades between stable assets.</p><p><strong>Tokenomics and governance</strong></p><p>Curve attracts more trades by maintaining liquidity pools in balance and thus offering better swap prices. In turn, this earns more fees for the protocol, which are then distributed to liquidity providers in the form of the CRV token.</p><p>The CRV token is used to reward liquidity providers, share the revenue with the token holders, and to govern the protocol. The total token distribution is following:</p><img src="https://images.mirror-media.xyz/publication-images/Ff_kof4CSlO51cGiOjbD9.jpg?height=182&amp;width=488" alt="Source: https://resources.curve.fi/crv-token/understanding-tokenomics" title="null" class="image-node embed"><p>While this is the release schedule:</p><img src="https://images.mirror-media.xyz/publication-images/T2grxBslijaPBULgqgWRU.jpg?height=613&amp;width=714" alt="Soure: https://dao.curve.fi/releaseschedule" title="null" class="image-node embed"><p>Although initially aggressive, the issuance of CRV slows significantly over time. Additionally, the governance mechanism incentivizes holders to lock the CRV token for a period of up to four years, which significantly reduces selling pressure. Currently, the average lock time is 3.53 years. Upon locking the CRV tokens user gets vote escrow tokens or veCRV. The longer the locking period, the more ve tokens the user gets at the end of the lock period (the boost can get up to 250% in the case of the 4-year lock).</p><p>The CRV token is a reward for providing liquidity to the Curve pools. Every week, the holders of the veCRV tokens decide which pool receives the daily token emissions and how much of the emissions it receives (known as gauge weights).</p><p><strong>Enter Curve Wars</strong></p><p>The liquidity of a token is extremely important for the protocol issuing it. If there is deep liquidity, users can easily exchange the token without slippage. Additionally, it reduces the price impact of whales dumping their bags.</p><p>The governance and reward system of the Curve protocol incentivizes other protocols to accumulate CRV tokens, lock them into veCRV, and direct the rewards to their own pools. This make it worth for the protocols to convince liquidity providers to direct their tokens into the pools offering the most attractive yields.</p><p>The Curve Wars began when a few well-known protocols competed for the largest share of the veCRV market. The winner of the wars was Convex, a protocol originally designed to live in symbiosis with the Curve ecosystem.</p><p>Liquidity providers earn CRV tokens for providing liquidity to the pools in the Curve protocol. The yield on their LP positions depends on, among other things, the amount of veCRV tokens they own, as shown below. Individual holdings would have an insignificant impact, but what if you pool the scattered resources?</p><img src="https://images.mirror-media.xyz/publication-images/toKhR0L4PxcC4TqULaycb.jpg?height=322&amp;width=709" alt="Source: https://classic.curve.fi/" title="null" class="image-node embed"><p>The Convex protocol enables users to collect CRV tokens from their holders, put them in the Curve LPs, and then share the rewards among the investors. In addition, the investors also receive the Convex CVX token as a reward. Through this clever incentive structure, Convex won the Curve wars and currently controls whopping 53% of the total veCVR supply.</p><p>The story here just keeps getting more complicated. For every CRV locked into the protocol, Convex gives the investors cvxCRV tokens. These tokens can be exchanged freely, so Convex provides a way to get the benefits of locked CVR in a liquid form. Another advantage of holding cvxCRV is that you can set gauge weights in the Curve liquidity pools.</p><p>Let’s recap how we got to this point:</p><ol><li><p>The investor deposits CRV tokens into Convex and receives liquid cvxCRV in exchange</p></li><li><p>Convex locks pooled CRV tokens into Curve and directs future CRV emissions to the Curve liquidity pools of its choice through a Curve DAO vote</p></li><li><p>The vote is made through Convex DAO by cvxCRV holders</p></li></ol><p>Now, if a protocol wants to direct CRV emissions to their pools, instead of buying the CRV tokens, the protocol can load onto the cvxCRV and rule the gauge weights in Curve! Or does it have to? Maybe a little bribe here and there would be good enough?</p><p><strong>Bribery</strong></p><p>In the world of DeFi, even bribes are public. There&apos;s no need to panic, everything is alright.</p><p>This is where Votium comes in. Votium allows protocols that are interested in increasing the liquidity of their tokens (which is why the complex machinery described in this article was put in place, in case you forgot) to bribe CVX holders to direct the Curve emissions to their pools.</p><img src="https://images.mirror-media.xyz/publication-images/RGS7TS_E02Eq7LYYQd3wt.jpg?height=556&amp;width=1021" alt="" title="null" class="image-node embed"><p>The whole idea is based on a simple incentive - it is cheaper to buy a vote with CVX tokens than it is to become a CVX holder. For the last couple of months, one CVX vote has cost between $0.05 and $0.09, while one CVX token, at the time of writing, buys around 5.7 votes and costs $3.9. That’s a 10x difference! What’s more, by staking CVX tokens, you receive further rewards from the Convex protocol at around 3%, and another 27% from the bribes on Votium (if you vote or delegate your votes there).</p><p>These are the Cruve Wars, won by Convex, fueled by the Votium bribes.</p><p><strong>Personal take</strong></p><p>Curve Finance is a masterpiece of crypto innovation and the protocol governance. The design of the rewards, sustainable tokenomics and innovative stableswap feature make it clear why Curve is and will remain one of the top DeFi protocols for a long time.</p><p>The decentralized finance revolution began a few years ago and flourished in 2020 during DeFi Summer. It&apos;s only a matter of time before it becomes mainstream.</p><p>I’m here for the journey and will write about other protocols that bring innovation and move the industry forward, so stay tuned!</p>]]></content:encoded>
            <author>rafal@newsletter.paragraph.com (rafal)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/2a11a5cd308d8e9d17819fc58dae5b7d.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>