<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Privacy Prophet Blog]]></title><description><![CDATA[Privacy Prophet Blog]]></description><link>https://blog.privacyprophet.xyz</link><generator>RSS for Node</generator><lastBuildDate>Sun, 26 Apr 2026 05:48:35 GMT</lastBuildDate><atom:link href="https://blog.privacyprophet.xyz/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[My NeoVim Configuration in the age of AI]]></title><description><![CDATA[Switching to Neovim is a rite of passage for many developers. It's not just about using a terminal editor; it's about crafting a Personalized Development Environment (PDE) that moves at the speed of thought. In this post, I'll walk you through my cur...]]></description><link>https://blog.privacyprophet.xyz/my-neovim-configuration-in-the-age-of-ai</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/my-neovim-configuration-in-the-age-of-ai</guid><category><![CDATA[neovim]]></category><category><![CDATA[opencode]]></category><category><![CDATA[AI]]></category><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Fri, 26 Dec 2025 18:25:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1766770858461/b2c4734f-6964-4412-96cc-14706ad2d95e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Switching to Neovim is a rite of passage for many developers. It's not just about using a terminal editor; it's about crafting a Personalized Development Environment (PDE) that moves at the speed of thought. In this post, I'll walk you through my current Neovim setup, explaining the core components, the visual aesthetics, the coding engine, and the AI superpowers I've integrated. I cover OpenCode independent configuration in a separate section. You can find the full configuration here:</p>
<ul>
<li><p><a target="_blank" href="https://github.com/rac-sri/neovim-config">https://github.com/rac-sri/neovim-config</a> - NeoVim Config</p>
</li>
<li><p><a target="_blank" href="https://github.com/rac-sri/opencode-config">https://github.com/rac-sri/opencode-config</a> - OpenCode Config</p>
</li>
</ul>
<p>Here is a tour of the plugins, the architecture, and the logic behind the chaos.</p>
<hr />
<h2 id="heading-neovim-setup">NeoVim Setup</h2>
<h3 id="heading-1-what-are-plugins-in-neovim-and-why-lazynvim">1. What are Plugins in Neovim? (And Why <code>lazy.nvim</code>?)</h3>
<p>Neovim out of the box is a powerful text editor, but it's "bare bones." It doesn't ship with a file explorer, autocompletion, or Git integration enabled by default. <strong>Plugins</strong> are Lua scripts that add these features, essentially turning Neovim from a text editor into a full PDE.</p>
<p>Managing dozens of plugins used to be a nightmare of slow startup times and broken dependencies. Enter <a target="_blank" href="https://github.com/folke/lazy.nvim"><strong>lazy.nvim</strong></a>.</p>
<p>I use <code>lazy.nvim</code> as my package manager because, as the name implies, it's lazy. It doesn't load every plugin when I launch Neovim. Instead, it waits.</p>
<ul>
<li><p>Want to use Git? It loads the Git plugin <em>only</em> when you open a Git-tracked file.</p>
</li>
<li><p>Want to code in Rust? It loads the Rust LSP <em>only</em> when you open a <code>.rs</code> file.</p>
</li>
</ul>
<p>This keeps my startup time blazing fast (&lt; 100ms) while still having a massive suite of tools at my disposal.</p>
<hr />
<h3 id="heading-2-my-plugin-arsenal">2. My Plugin Arsenal</h3>
<p>Here is the complete list of plugins powering my setup, broken down by category.</p>
<h3 id="heading-ui-amp-aesthetics">UI &amp; Aesthetics</h3>
<p>Because if you're going to stare at a screen all day, it better look good.</p>
<ul>
<li><p><a target="_blank" href="https://github.com/shaunsingh/nord.nvim"><strong>nord.nvim</strong></a>: My theme of choice. A cool, bluish-grey palette that is easy on the eyes, configured with transparency support.</p>
</li>
<li><p><a target="_blank" href="https://github.com/nvim-lualine/lualine.nvim"><strong>lualine.nvim</strong></a>: A sleek, configurable status line at the bottom of the window showing branch, mode, and diagnostics.</p>
</li>
<li><p><a target="_blank" href="https://github.com/akinsho/bufferline.nvim"><strong>bufferline.nvim</strong></a>: Displays open files as "tabs" at the top, making navigation intuitive for those coming from VS Code.</p>
</li>
<li><p><a target="_blank" href="https://github.com/goolord/alpha-nvim"><strong>alpha-nvim</strong></a>: A programmable startup dashboard that greets me with a custom header and quick links to recent files.</p>
</li>
<li><p><a target="_blank" href="https://github.com/lukas-reineke/indent-blankline.nvim"><strong>indent-blankline.nvim</strong></a>: Adds vertical indentation guides to help visually track code blocks and nested loops.</p>
</li>
<li><p><a target="_blank" href="https://github.com/petertriho/nvim-scrollbar"><strong>nvim-scrollbar</strong></a>: Adds a visual scrollbar that also highlights search results and diagnostic errors in the gutter.</p>
</li>
<li><p><a target="_blank" href="https://github.com/sphamba/smear-cursor.nvim"><strong>smear-cursor.nvim</strong></a>: Adds a motion blur trail to the cursor. Purely cosmetic, but it makes jumping around the file feel incredibly smooth.</p>
</li>
<li><p><a target="_blank" href="https://github.com/norcalli/nvim-colorizer.lua"><strong>nvim-colorizer.lua</strong></a>: Automatically highlights hex codes (like <code>#ff0000</code>) with their actual color.</p>
</li>
</ul>
<h3 id="heading-coding-intelligence">Coding Intelligence</h3>
<p>The engine that understands the code.</p>
<ul>
<li><p><a target="_blank" href="https://github.com/neovim/nvim-lspconfig"><strong>nvim-lspconfig</strong></a>: The backbone of language support. It connects Neovim to Language Servers (LSP) for Python, Rust, TS, etc.</p>
</li>
<li><p><a target="_blank" href="https://github.com/hrsh7th/nvim-cmp"><strong>nvim-cmp</strong></a>: The main autocompletion engine. It pops up the menu suggesting variables and functions as I type.</p>
</li>
<li><p><a target="_blank" href="https://github.com/saghen/blink.cmp"><strong>blink.cmp</strong></a>: A high-performance, Rust-based completion engine I'm experimenting with for even faster suggestions.</p>
</li>
<li><p><a target="_blank" href="https://github.com/nvim-treesitter/nvim-treesitter"><strong>nvim-treesitter</strong></a>: Provides advanced syntax highlighting and code parsing, allowing for smarter text selection (like "select function").</p>
</li>
<li><p><a target="_blank" href="https://github.com/nvimtools/none-ls.nvim"><strong>none-ls.nvim</strong></a>: Injects standard command-line tools (like Prettier or ESLint) into the LSP workflow for formatting and linting.</p>
</li>
<li><p><a target="_blank" href="https://github.com/windwp/nvim-autopairs"><strong>nvim-autopairs</strong></a>: Automatically closes brackets, quotes, and parentheses so I don't have to.</p>
</li>
</ul>
<h3 id="heading-navigation-amp-workflow">Navigation &amp; Workflow</h3>
<p>Tools to move fast and break less things.</p>
<ul>
<li><p><a target="_blank" href="https://github.com/nvim-telescope/telescope.nvim"><strong>telescope.nvim</strong></a>: A universal fuzzy finder. I use it to find files, grep text, search help docs, and more.</p>
</li>
<li><p><a target="_blank" href="https://github.com/nvim-neo-tree/neo-tree.nvim"><strong>neo-tree.nvim</strong></a>: A file explorer sidebar. Useful for visualizing the directory structure and performing file operations. I don’’t primarily use it, just a nice to have because of seemless integration with git from a visual perspective.</p>
</li>
<li><p><a target="_blank" href="https://github.com/mikavilpas/yazi.nvim"><strong>yazi.nvim</strong></a>: Integrates the <code>yazi</code> terminal file manager, giving me a super-fast, keyboard-driven way to browse files. Primary tool to navigate through files.</p>
</li>
<li><p><a target="_blank" href="https://github.com/lewis6991/gitsigns.nvim"><strong>gitsigns.nvim</strong></a>: Shows Git changes (added/removed lines) right in the gutter and allows for inline previews.</p>
</li>
<li><p><a target="_blank" href="https://github.com/christoomey/vim-tmux-navigator"><strong>vim-tmux-navigator</strong></a>: Allows seamless navigation between Neovim splits and Tmux panes using the same keys (<code>Ctrl-h/j/k/l</code>).</p>
</li>
<li><p><a target="_blank" href="https://github.com/numToStr/Comment.nvim"><strong>comment.nvim</strong></a>: Toggles comments on lines or blocks with a simple shortcut (<code>gcc</code> or <code>gc</code>).</p>
</li>
<li><p><a target="_blank" href="https://github.com/folke/todo-comments.nvim"><strong>todo-comments.nvim</strong></a>: Highlights <code>TODO</code>, <code>FIXME</code>, and <code>NOTE</code> comments so they stand out and can be searched.</p>
</li>
</ul>
<h3 id="heading-the-ai-squad">The AI Squad</h3>
<p>I lean heavily on AI for coding assistance, using multiple specialized tools rather than a single monolith.</p>
<ul>
<li><p><a target="_blank" href="https://github.com/NickvanDyke/opencode.nvim"><strong>opencode.nvim</strong></a>: My "Agentic" AI tool. It enables inline asking (<code>&lt;leader&gt;oi</code>) and complex task execution via a panel, integrating deep context from the codebase. I use local model: qwen3-coder when data privacy is important, and else I am currently using gemini models since I got access to it’s pro subscription.</p>
</li>
<li><p><a target="_blank" href="https://github.com/TabbyML/vim-tabby"><strong>vim-tabby</strong></a>: Provides ML-powered code completion (ghost text) using a self-hosted Tabby server, keeping my data private.</p>
</li>
<li><p><a target="_blank" href="https://github.com/github/copilot.vim"><strong>copilot.vim</strong></a>: The classic GitHub Copilot integration. I keep this for quick tab style completion in places where privacy is not a concern..</p>
</li>
<li><p><a target="_blank" href="https://github.com/yetone/avante.nvim"><strong>avante.nvim</strong></a> <strong>( disabled )</strong>: An advanced AI chat interface that sits in a sidebar. It supports multiple providers (Gemini, Claude, OpenAI) and even allows pasting images for analysis.</p>
</li>
<li><p><a target="_blank" href="https://github.com/marcinjahn/gemini-cli.nvim"><strong>gemini-cli.nvim</strong></a> <strong>( disabled )</strong>: A direct line to Google's Gemini models for quick questions and code generation directly from the editor.</p>
</li>
</ul>
<hr />
<h3 id="heading-3-the-initlua-where-it-all-begins">3. The <code>init.lua</code>: Where It All Begins</h3>
<p>In the world of Neovim, <code>init.lua</code> is the captain. It is the first file loaded when the editor starts, and its job is to orchestrate everything else.</p>
<p>My <code>init.lua</code> is designed to be modular. Instead of dumping 500 lines of config into one file, it acts as a dispatcher:</p>
<ol>
<li><p><strong>Core Loading</strong>: First, it requires modules from the <code>lua/core/</code> folder.</p>
<ul>
<li><p><code>core.options</code>: Sets basic settings like line numbers, tab widths, and clipboard behavior.</p>
</li>
<li><p><code>core.keymaps</code>: Defines my global keyboard shortcuts (like Space as Leader).</p>
</li>
<li><p><code>core.snippets</code>: Loads custom code snippets.</p>
</li>
</ul>
</li>
<li><p><strong>Lazy Bootstrap</strong>: It checks if <code>lazy.nvim</code> is installed. If not, it automatically clones the repository. This means I can pull this config on a fresh machine, open Neovim, and it will self-install everything.</p>
</li>
<li><p><strong>Plugin Initialization</strong>: Finally, it passes control to <code>lazy</code>.</p>
<pre><code class="lang-lua"> require("lazy").setup({
     require("plugins.neotree"),
     require("plugins.colortheme"),
     -- ... and so on
 })
</code></pre>
<p> Each <code>require</code> points to a separate file in <code>lua/plugins/</code>. This keeps the config clean; if I want to change how my status line looks, I go to <code>lua/plugins/lualine.lua</code>, not a massive monolithic file.</p>
</li>
</ol>
<hr />
<h2 id="heading-opencode-the-ai-orchestrator">🤖 OpenCode: The AI Orchestrator</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766773444604/b15e59a5-25de-4ec7-86b9-780022e8df1c.png" alt class="image--center mx-auto" /></p>
<p>Right after my Neovim configuration comes the brain of the operation: OpenCode. If Neovim is the surgical instrument, OpenCode is the senior engineer looking over my shoulder.</p>
<p>I use a opensource setup called <a target="_blank" href="https://github.com/code-yeongyu/oh-my-opencode/">OhMyOpenCode</a>, heavily customized to switch between local privacy and cloud intelligence.</p>
<p><strong>The "Sisyphus" Workflow:</strong> The primary agent is named Sisyphus (a fitting name for an engineer, right?). Unlike standard AI assistants, Sisyphus is configured as an orchestrator that delegates tasks to specialized sub-agents. Here is how I map the intelligence in <code>~/.config/opencode/oh-my-opencode.json</code>:</p>
<pre><code class="lang-json">{ 
    agents: { 
        Sisyphus: { 
            model: google/gemini<span class="hljs-number">-3</span>-pro-high 
        },     
        oracle: { 
            model: google/gemini<span class="hljs-number">-3</span>-pro-high 
        }, 
        librarian: { 
            model: google/gemini<span class="hljs-number">-3</span>-pro-low 
        }, 
        document-writer: { 
            model: google/gemini<span class="hljs-number">-3</span>-flash 
        } 
    }     
}
</code></pre>
<p>I'm using a hybrid model strategy:</p>
<ul>
<li><p>Heavy Lifting: Complex architecture and planning (Sisyphus/Oracle) go to Gemini 3 Pro High ( as of writing ) with reasoning enabled.</p>
</li>
<li><p>Speed: Documentation and quick lookups use Gemini 3 Flash or Pro Low.</p>
</li>
<li><p>Local: My default fallback in <code>opencode.json</code> is Qwen 2.5 Coder (via Ollama) for zero-latency, offline code completion.</p>
</li>
</ul>
<p><strong>Context &amp; Rules</strong></p>
<p>One feature I rely on is the dynamic context loading. OpenCode automatically ingests my project guidelines before writing a single line of code:</p>
<pre><code class="lang-json">instructions: [ 
    CONTRIBUTING.md, 
    docs/guidelines.md, 
    .cursor/rules<span class="hljs-comment">/*.md 
]</span>
</code></pre>
<p>This ensures the AI respects my repo's specific conventions (like "no any types" or "React functional components only") without me repeating prompts.</p>
<p><strong>Aesthetics</strong></p>
<p>Since I live in the terminal, visual consistency is non-negotiable. I built a custom transparent theme so OpenCode floats seamlessly over my terminal background, matching the transparency of my Neovim windows.</p>
<pre><code class="lang-json"> <span class="hljs-comment">// themes/transparent.json </span>
{ 
    theme: { 
        background: transparent, 
        backgroundPanel: transparent, 
        primary: #<span class="hljs-number">00</span>d4ff, 
        success: #<span class="hljs-number">2</span>ed573 
    } 
}
</code></pre>
<p>It’s not just about looking cool—it keeps me in the flow state without jarring context switches between my editor and my AI agent.</p>
<h3 id="heading-custom-primary-agents"><strong>Custom Primary Agents</strong></h3>
<p><strong>Custom Agents</strong> One of the most powerful features of OpenCode is the ability to define custom "personas" or agents. I don’t just have one generic AI; I have a squad of specialists, each defined in <code>~/.config/opencode/agent/</code>. I’ve defined two custom agents to handle specific non-coding workflows:</p>
<ol>
<li><p><strong>The "Ask" Agent (Code Consultant)</strong></p>
<p> Sometimes I just need an answer, not a code change. I created the Ask agent (agent/<a target="_blank" href="http://Ask.md">Ask.md</a>) specifically for this.</p>
<ul>
<li><p><strong>Role</strong>: Code Q&amp;A Specialist.</p>
</li>
<li><p><strong>Constraint</strong>: Strictly Read-Only. It has explicit instructions to never edit files or run commands.</p>
</li>
<li><p><strong>Use Case:</strong> "How does this function work?" or "Explain this error." It uses Gemini 3 Pro Low to be cost-effective but smarter than a basic model.</p>
</li>
</ul>
</li>
<li><p><strong>The "Webcrawler" Agent (Researcher)</strong></p>
<p> I don't want my coding assistant hallucinating facts about the world. Webcrawler (agent/<a target="_blank" href="http://Webcrawler.md">Webcrawler.md</a>) is my general knowledge researcher.</p>
<ul>
<li><p><strong>Role</strong>: General Q&amp;A (News, Science, Trends).</p>
</li>
<li><p><strong>Constraint</strong>: Explicitly forbidden from giving technical coding advice—it redirects those to the Ask agent.</p>
</li>
<li><p><strong>Use Case:</strong> "What are the latest features in React 19?" or general web research.</p>
</li>
</ul>
</li>
</ol>
<hr />
<h2 id="heading-terminal-ghostty">Terminal - Ghostty</h2>
<p>I use <a target="_blank" href="https://ghostty.org/">Ghostty</a> as my primary terminal with the following config:</p>
<p><a target="_blank" href="https://github.com/rac-sri/personal-config/blob/main/ghostty.config">https://github.com/rac-sri/personal-config/blob/main/ghostty.config</a>.<br />Main appearance limited config is below:</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># ---- Appearance ----</span>
<span class="hljs-string">theme</span> <span class="hljs-string">=</span> <span class="hljs-string">Adventure</span>
<span class="hljs-string">background-blur</span> <span class="hljs-string">=</span> <span class="hljs-literal">true</span>
<span class="hljs-string">background-opacity</span> <span class="hljs-string">=</span> <span class="hljs-number">1</span>
<span class="hljs-string">background-image</span> <span class="hljs-string">=</span> <span class="hljs-string">~/.config/ghostty/image.png</span>
<span class="hljs-string">background-image-opacity</span> <span class="hljs-string">=</span> <span class="hljs-number">0.5</span>
<span class="hljs-string">....</span>
</code></pre>
<p>with the image being a free to use artwork I pulled from the internet : <a target="_blank" href="https://github.com/rac-sri/personal-config/blob/main/image.png">https://github.com/rac-sri/personal-config/blob/main/image.png</a>.</p>
<hr />
<p>That's the tour! This setup balances raw speed with modern features, giving me an environment that feels like <em>mine</em>.</p>
]]></content:encoded></item><item><title><![CDATA[Kademlia DHT: A P2P Information System]]></title><description><![CDATA[A P2P (peer-to-peer) network is like a group of friends where everyone shares and helps each other directly — there’s no boss or central person in charge.
Instead of going to a central server (like a library or a big store), you go directly to anothe...]]></description><link>https://blog.privacyprophet.xyz/kademlia-dht-a-p2p-information-system</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/kademlia-dht-a-p2p-information-system</guid><category><![CDATA[p2p]]></category><category><![CDATA[kademlia]]></category><category><![CDATA[#DHT]]></category><category><![CDATA[distributed system]]></category><category><![CDATA[Distributed Hash Tables]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[avail light client]]></category><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Sun, 04 May 2025 15:04:06 GMT</pubDate><content:encoded><![CDATA[<p>A <strong>P2P (peer-to-peer) network</strong> is like a group of friends where <strong>everyone shares and helps each other directly</strong> — there’s no boss or central person in charge.</p>
<p>Instead of going to a central server (like a library or a big store), <strong>you go directly to another person</strong> (a "peer") to get what you need — like a file, song, or book. And just like you can download from someone, they can also download from you.</p>
<p>So in a P2P network:</p>
<ul>
<li><p>Everyone is both a <strong>giver</strong> and a <strong>receiver</strong>.</p>
</li>
<li><p>There’s <strong>no central control</strong> — the system is spread out and more democratic.</p>
</li>
<li><p>If one peer goes offline, the rest can still keep sharing.</p>
</li>
</ul>
<p><strong>Real-World Example:</strong></p>
<p>Imagine you and your friends all bring different books to a hangout. Instead of having one person collect and lend all the books (like a library), you all <strong>share books with each other directly</strong>. If one friend leaves, the rest can still trade books.</p>
<p>That’s how P2P file sharing works — with files instead of books.</p>
<hr />
<h3 id="heading-distributed-hash-table-dht"><strong>Distributed Hash Table (DHT)</strong></h3>
<p>A <strong>Distributed Hash Table (DHT)</strong> is like a <strong>giant, shared address book</strong> spread across a large group of computers (or peers), where <strong>everyone helps store and find information</strong> — but no one person has the whole book.</p>
<p>One data structure that allows storing elements as <strong>&lt;key, value&gt;</strong> pairs is a traditional map. We store separate parts of the map on separate computers. We could connect these parts by designating a centralized computer, or coordinator, which would coordinate which keys are stored on which computer. This map would not be very resilient, however, to when the coordinator goes offline.</p>
<p>A Distributed Hash Table (DHT) is a kind of data structure stored on multiple computers that aims to address this issue. We still want our basic operations <strong>PUT(key, value)</strong> and <strong>GET(key)</strong>, like we had in our map, but we want our data structure to still stand even if some computer leaves our network. In designing our DHT, we want it to be:</p>
<ul>
<li><p><em>Scalable</em>. When more computers participate, we want the DHT to split up the elements evenly among the computers.</p>
</li>
<li><p><em>Fault-Tolerant</em>. If a computer leaves the network, we want to be able to access the elements that it previously held.</p>
</li>
</ul>
<hr />
<h3 id="heading-simple-analogy">Simple Analogy:</h3>
<p>Imagine you and your friends are part of a huge <strong>book exchange club</strong>. Instead of using one central list to track where each book is, each friend <strong>remembers a small part</strong> of the list — like a puzzle piece.</p>
<p>Now, suppose you want a specific book. You don’t know who has it, but you <strong>know its title (a key)</strong>. You ask around, and based on how the list is organized, your request is <strong>routed through the network</strong>, jumping from friend to friend, until it reaches the person who knows where that book is stored — or who has it themselves.</p>
<p><strong>How It Works Technically (Simplified):</strong></p>
<ul>
<li><p>Data is stored as <strong>(key, value)</strong> pairs. For example:<br />  <code>key = "</code><a target="_blank" href="http://MySong.mp"><code>MySong.mp</code></a><code>3"</code><br />  <code>value = "Stored at peer X"</code></p>
</li>
<li><p>A <strong>hash function</strong> turns the key into a number (a hash), which tells the system <strong>which peer should store or look up that key</strong>.</p>
</li>
<li><p>Peers <strong>cooperate to route requests</strong>, usually in just a few steps, even if millions of peers exist.</p>
</li>
</ul>
<p><strong>Real-World Uses:</strong></p>
<ul>
<li><p><strong>BitTorrent</strong>: uses DHT to find which peers have pieces of a file.</p>
</li>
<li><p><strong>IPFS (InterPlanetary File System)</strong>: uses DHT to locate files in a decentralized way.</p>
</li>
<li><p><strong>Blockchain networks</strong>: sometimes use DHT-like structures to store or sync data.</p>
</li>
</ul>
<hr />
<h2 id="heading-kademlia-protocol">Kademlia Protocol</h2>
<p>Kademlia operates over a 160 bit node ID, and uses <strong>XOR metric</strong> as a means to define distance between points in the key space o minimize internode messaging.</p>
<p>This, if the distance is expressed as log2(n) nodes, this means that for a network with 10,000,000 Kademlia nodes, only about 20hops would be necessary at most for communication with any subset of nodes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746368924553/9e5fdc58-5a59-4d1e-8a83-aff965cf1244.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-xor-metric">XOR Metric</h2>
<p>Kademlia has a 160 bi node ID. Kademlia defined distance between two identifiers using XOR i.e. \(d(x,y_) = x \oplus y  \) . XOR is a valid, albeit non-Euclidean metric.</p>
<ul>
<li><p>\(d(x,x) = 0\)</p>
</li>
<li><p>\(d(x,y) &gt; 0 \) if \(x  \ne y\)</p>
</li>
<li><p>\(\forall x,y: d(x,y) = d(y,x)\)</p>
</li>
<li><p>\(d(x,y) + d(y,z) \ge d(x,z)\)</p>
</li>
</ul>
<p>XOR is unidirectional. For any given point x and distance \(\delta\)\&gt;0, there is exactly one point y such that \(d(x,y) = \delta\). Unidirectionality ensures that all lookups for the same key converge along the same path, regardless of the originating node.</p>
<h2 id="heading-search-tree-partitions">Search Tree Partitions</h2>
<p>All ids and keys are in a keyspace of \([0,1,…2^3−1][0,1,…2^3−1]\) and are represented in binary. We can represent this space as a complete binary tree where each leaf node is a key. Circled leaves are ids that correspond to a participating computer in the network.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746369638877/85f094d2-4e61-456f-b1ce-1eae902e10b6.png" alt class="image--center mx-auto" /></p>
<p>When distributing keys among computers in a peer-to-peer system, tries (prefix trees) offer a natural way to represent and navigate binary identifiers. Each path from the root to a leaf reflects the binary representation of a key, and shared prefixes indicate shared ancestry between keys — a useful property for routing and assignment.</p>
<p>However, assigning a key to the “closest” computer isn’t always straightforward. For example, two computer IDs might share the same longest common prefix with a given key, leading to a tie. One naive solution is to break the tie arbitrarily, but this can lead to imbalance.</p>
<p>A more elegant and deterministic approach is to compare the <strong>most significant bit</strong> (MSB) where the computer IDs differ. The key is then assigned to the computer whose bit at that position <strong>matches the key’s bit</strong>. This ensures a consistent and fair assignment, even in the case of ties, by leveraging bit-level structure instead of arbitrary decisions.</p>
<p>This method generalizes the idea of the longest common prefix and leads to more balanced and predictable routing in distributed systems.</p>
<h2 id="heading-routing-table">Routing Table</h2>
<p>A <strong>routing table</strong> in Kademlia is a structure that helps each node <strong>find other nodes efficiently</strong>, especially the ones <strong>closer (in XOR distance)</strong> to a target ID. It is:</p>
<ul>
<li><p>Organised by distance, using XOR distance.</p>
</li>
<li><p><strong>k-buckets:</strong> The routing table is divided into buckets, one for each possible bit length. Each k-bucket holds up to k node IDs ( usually k = 20 ) that fall within a certain XOR distance range. Bucket i holds nodes whose distance is between \(2^i\) and \(2^{i+1}\).</p>
</li>
<li><p>Uses LRU cache and gives preference to long lived, stabled nodes. When a bucket is full, the oldest node is pined. If it’s alive, it says, else replaced.</p>
</li>
<li><p>When a node wants to find a key, it queries nodes closer and closer using the routing table to guide it. Lookup time typically completes in \(O(logn)\) steps.</p>
</li>
<li><p>Another benefit of k-buckets is that they provide resistance to certain DoS attacks. One cannot flush nodes routing state by flooding the system with new nodes. Kademlia nodes will only insert the new nodes in the k-buckets when old nodes leaves the system.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746370350123/ca1c80d4-926b-4a62-a6a6-498050f22ba8.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<h2 id="heading-kademlia-protocol-1">Kademlia Protocol</h2>
<p>The Kademlia protocol consists of four RPCs: <strong>PING, STORE, FIND_NODE, FIND_VALUE.</strong></p>
<ul>
<li><p><strong>PING</strong>: The <code>PING</code> RPC is the most basic yet essential building block of Kademlia's routing logic. It serves a simple purpose: to check if a node in the network is still alive. When a node wants to confirm the availability of a peer (often one stored in its routing table), it sends a <code>PING</code> message. If the node is active, it replies with a <code>PONG</code>. This mechanism is crucial for maintaining the accuracy and health of the routing table, especially in dynamic environments where peers may go offline without warning. Stale or unresponsive peers can then be replaced, ensuring efficient and reliable lookups.</p>
</li>
<li><p><strong>STORE</strong>: The <code>STORE</code> RPC allows Kademlia nodes to insert data into the distributed hash table. When a node wants to store a <code>(key, value)</code> pair, it identifies the kkk nodes whose IDs are closest to the key (based on XOR distance) and sends each of them a <code>STORE</code> message. These recipient nodes then persist the data. This operation is what enables decentralized data storage in systems like BitTorrent or IPFS, where information is scattered across many peers but still retrievable by key. Although the <code>STORE</code> RPC doesn’t require a complex response, it forms the basis of reliable and distributed value preservation.</p>
</li>
<li><p><strong>FIND_NODE</strong>: The <code>FIND_NODE</code> RPC is used to locate nodes in the network that are closest to a particular target ID. When a node wants to route a query or build its routing table, it sends a <code>FIND_NODE</code> message with the target ID to a known peer. In response, that peer returns up to kkk node IDs that it knows to be closest to the target. This process is repeated recursively, narrowing the search until the closest possible nodes are found. <code>FIND_NODE</code> is fundamental to Kademlia's efficient lookup mechanism, which allows nodes to locate information or other peers in logarithmic time.</p>
</li>
<li><p><strong>FIND_VALUE</strong>: The <code>FIND_VALUE</code> RPC is similar in structure to <code>FIND_NODE</code>, but with one key difference: it attempts to <strong>retrieve the actual value</strong> associated with a key. When a node wants to retrieve stored data, it sends a <code>FIND_VALUE</code> message with the desired key. If the receiving node has the value, it returns it directly. If not, it behaves like <code>FIND_NODE</code> and returns a list of peers that are closer to the key, guiding the search forward. This RPC combines efficient lookup with data retrieval, making it the heart of Kademlia's decentralized data access model.</p>
</li>
</ul>
<hr />
<h3 id="heading-conclusion">🧠 Conclusion</h3>
<p>Kademlia elegantly solves the challenge of decentralized lookup and storage through a clever combination of XOR-based distance, recursive routing, and simple RPCs. Its ability to find any node or data item in logarithmic time, while gracefully handling churn and failures, makes it a foundational protocol in the peer-to-peer world. Whether you're building a distributed file system, a blockchain network, or a resilient storage layer, Kademlia offers a robust and scalable blueprint for decentralized communication. Its design shows that with the right abstractions, even large, dynamic networks can remain efficient, fault-tolerant, and remarkably simple.</p>
<hr />
<h2 id="heading-references">References</h2>
<ul>
<li><p><a target="_blank" href="https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf">https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf</a></p>
</li>
<li><p><a target="_blank" href="https://codethechange.stanford.edu/guides/guide_kademlia.html#">https://codethechange.stanford.edu/guides/guide_kademlia.html</a></p>
</li>
</ul>
<p>For more updates, insights, and discussions, connect with me on Twitter: <a target="_blank" href="https://x.com/privacy_prophet">@privacy_prophet</a> or <a target="_blank" href="https://www.linkedin.com/in/rachit-anand-srivastava/">LinkedIn</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Bilinear Pairing: Deep Dive Part 3]]></title><description><![CDATA[So far we covered:

Group Law

Fields and how field operations works

Divisors


Now in this part we will explore:

Pairing Groups

Expand on r-torsian groups

Pairing types

Twisted Curves

Weil and Tate Pairings


Pairing groups
Let’s define biline...]]></description><link>https://blog.privacyprophet.xyz/bilinear-pairing-deep-dive-part-3</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/bilinear-pairing-deep-dive-part-3</guid><category><![CDATA[ KZG commitment]]></category><category><![CDATA[Cryptography]]></category><category><![CDATA[bilinear pairings]]></category><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Sun, 02 Feb 2025 08:30:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738441138446/aaf3a141-801a-40d3-bd0f-9b03edb39272.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>So far we covered:</p>
<ul>
<li><p>Group Law</p>
</li>
<li><p>Fields and how field operations works</p>
</li>
<li><p>Divisors</p>
</li>
</ul>
<p>Now in this part we will explore:</p>
<ul>
<li><p>Pairing Groups</p>
</li>
<li><p>Expand on r-torsian groups</p>
</li>
<li><p>Pairing types</p>
</li>
<li><p>Twisted Curves</p>
</li>
<li><p>Weil and Tate Pairings</p>
</li>
</ul>
<h2 id="heading-pairing-groups">Pairing groups</h2>
<p>Let’s define bilinear map first:</p>
<p>$$M*M \rightarrow R$$</p><p>where bilinearity property of the map means:</p>
<p>$$( x+y, z) = (x,z) * (y,z )$$</p><p>$$(x,y+z)= (x,y)*(x,z)$$</p><p>The most common notion for the same is \(e: G_1 * G_2 \rightarrow G_T\)</p>
<p>\(G_1\) and \(G_2\) are defined in \(E(F_{q^k})\) and target group \(G_T\) is defined in multiplicative group \(F^*_{q^k}\), so we write \(G_1\) and \(G_2\) additively and \(G_T\) multiplicatively. Thus if \(P,P' \in G_1\) and \(Q, Q' \in G_2\) the bilinearity of e means:</p>
<p>$$e(P+P', Q) = e(P,Q).e(P',Q)$$</p><p>$$e(P, Q+Q') = e(P,Q).e(P,Q')$$</p><p>from which it follows, for scalers \(a, b \in Z\):</p>
<p>$$e([a]P,[b]Q) = e(P,[b]Q)^a = e([a]P, Q)^b = e(P,Q)^{ab} = e([b]P,[a]Q)$$</p><p><strong>Non-Degeneracy</strong>: Non-degeneracy is a fundamental property of cryptographic pairings. It ensures that if \(P \neq O\) and \(Q \neq O\), then the pairing \(e(P,Q) \neq 1\). This means that the pairing does not collapse information by mapping all non-trivial inputs to the identity element. In a cryptographic setting, non-degeneracy guarantees that pairings can be used effectively in protocols like identity-based encryption and signature schemes. Essentially, it ensures that the bilinear mapping retains meaningful structure and does not trivialize computations. This \(e(P,Q) \neq 1 \) guarantees non-trivial pairings for non-trivial arguments.</p>
<h3 id="heading-the-r-torsion">The r-torsion</h3>
<p>The points \(P\) and \(Q\) come from disjoin cyclic subgroups of the same prime order \(r\). We obtain two distinct order-r subgroups in general: we find the smallest extension \(F_{q^k} \space of \space F_q\) such that \(E(F_{q^k})\) captures more points of order \(r\). The integer \(k \geq 1\) that achieves this is called embedding degree and plays a crucial role in paring computation.</p>
<p><strong>Trace Map:</strong> The trace map of point \(P = (x,y) \in E(F_{q^k})\) is defined as:</p>
<p>$$Tr(P) = \sum_{\sigma\in Gal(F_{q^k} / F_q)} \sigma(P) = \sum^{k-1}{i=0} \pi^i(P) = \sum^{k-1}{i=0}(x^{q^i}, y^{q^i})$$</p><p>Galois theory: \(Tr: E(F_{q^k}) \rightarrow E(F_q)\) so when \(r || Order E(F_q)\), this map, which is actually a group homomorphism, sends all torsion points into one subgroup of the r-torsion i.e Tr will send every other element in the torsion into \(E(F_q)[r]\).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738438516581/7945a2fa-81a9-4af1-83fe-43ee0694978f.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>All points other than the upper left torsion group one, will get mapped to the upper left group. eg. \(R = (u^{423}, u^{840})\), we have \(Tr(R) = (10, 7)\).</p>
</li>
<li><p>There is one other peculiar subgroup above in E[7], the upper right group in the above case, where the trace map sends every element to \(O\). eg. \(T = (u^{1315}, u^{1150})\) i.e. \(Tr(T) = O\). This is the <strong>trace zero</strong> group.</p>
</li>
<li><p>We can also map any \(P \in E[r]\) to the trace zero subgroup ( \(G_2)\) via the anti-trace map \(aTr: P \rightarrow P' = [k]P - Tr(P)\).</p>
<p>  To following diagram ( from Pairings for beginners book ) summarize the above quite well:</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738438821140/24f82754-bce8-47d5-b33c-cef355bb9208.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>Lastly, we have <em>supersingular</em> curve E if \(Order E(F_q) = q+1\). These curves come with a <strong>distortion map</strong> \(\phi\): a non-\(F_q\)-rational map that takes a point in \(E(F_q)\) to a point in \(E(F_{q^k})\).</p>
<p>  For \(E/ F_q = y^2 = x^3 +1 \) with embedding degree \(k=2\) we get:</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738439284060/c463140e-5fe1-4453-bd0b-213c59834b08.png" alt class="image--center mx-auto" /></p>
<p>And that covers the different torsion groups and mappings between them !iv</p>
<hr />
<h2 id="heading-pairing-types">Pairing Types</h2>
<p>Pairing-based cryptography leverages structured subgroups of elliptic curves to facilitate secure and efficient protocols, with four distinct pairing types offering varied trade-offs between functionality, efficiency, and security. These classifications—Type 1 through Type 4—arise from how subgroups like the base-field group \(G_1\) and trace-zero subgroup \(G_2\) are defined, along with their interplay in operations such as hashing, isomorphism mapping, and pairing computations.</p>
<p><strong>Type 1 pairings</strong> are built on supersingular elliptic curves, where \(G_1\)and \(G_2\) are set to the same subgroup. This symmetry simplifies hashing into \(G_1\) via cofactor multiplication and ensures a straightforward isomorphism \(\psi\) between subgroups. However, the reliance on supersingular curves imposes significant limitations on optimizing pairing computations, making Type 1 less practical for modern applications despite its simplicity.</p>
<p><strong>Type 2 pairings</strong> use ordinary curves, with \(G_2\) defined as a subgroup outside \(G_1\) or the trace-zero group. While the trace map \(Tr: G_2 \rightarrow G_1\) enables certain efficiency gains, these pairings struggle with a critical drawback: the inability to hash or randomly sample elements directly into \(G_2\). This limits their utility in protocols requiring dynamic element generation, as elements must instead be derived from a predefined generator.</p>
<p><strong>Type 3 pairings</strong>, also on ordinary curves, address this by setting \(G_2\) as the trace-zero subgroup. This allows efficient hashing into \(G_2\)using the anti-trace map \(aTr\), making them a popular choice for modern protocols like BLS signatures. The trade-off, however, is the lack of a computationally feasible isomorphism \(\psi: G_2 \rightarrow G_1\), complicating security proofs that depend on such mappings unless stronger assumptions are made.</p>
<p><strong>Type 4 pairings</strong> expand \(G_2\) to the full r-torsion group \(E[r]\), theoretically enabling hashing but at the cost of practicality. The non-cyclic structure of \(E[r]\) and the negligible probability of hashing into desired subgroups render this type largely theoretical, with limited real-world applications.</p>
<p>In practice, Type 3 pairings dominate modern use cases due to their balance of efficiency and flexibility, while Type 1’s constraints and Type 2/4’s impracticalities relegate them to niche roles. Developers must weigh factors like curve type (supersingular vs. ordinary), isomorphism availability, and hashing capabilities when selecting a pairing type, as these choices directly impact protocol security, performance, and ease of implementation. Ultimately, understanding these trade-offs is key to designing robust cryptographic systems tailored to specific needs.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738439739994/4434abf4-d08c-4321-9a79-ca4fa2793f45.png" alt class="image--center mx-auto" /></p>
<hr />
<h2 id="heading-twisted-curves">Twisted Curves</h2>
<p>Twisted curves play a pivotal role in modern elliptic curve cryptography (ECC) and pairing-based protocols, offering enhanced efficiency, security, and flexibility. These curves—such as <strong>twisted Edwards curves</strong> and <strong>twisted Montgomery curves</strong>—are algebraic variants of standard elliptic curves, engineered to optimize cryptographic operations while mitigating vulnerabilities. Below, we break down their significance, mechanics, and applications in cryptography.</p>
<hr />
<p><strong>What Are Twisted Curves?</strong></p>
<p>A <strong>twist</strong> of an elliptic curve is a related curve that is <em>isomorphic</em> (structurally similar) over an extension field but distinct over the base field. For example:</p>
<ul>
<li><p><strong>Twisted Edwards curves</strong> are defined by the equation \(ax^2 + y^2 = 1 + dx^2y^2\), where parameters <em>a</em> and \(d\) introduce flexibility in curve design.</p>
</li>
<li><p><strong>Montgomery curves</strong> like \(y^2 = x^3 + Ax^2 + x\) (e.g., Curve25519) are often birationally equivalent to twisted Edwards curves, enabling efficient computations.</p>
</li>
</ul>
<p>Twists retain the core security properties of their parent curves but enable optimizations in arithmetic operations. For instance, twisted Edwards curves support <strong>complete</strong> and <strong>exception-free</strong> addition formulas, eliminating edge cases that could lead to side-channel attacks.</p>
<hr />
<p><strong>Why Use Twisted Curves?</strong></p>
<ol>
<li><p><strong>Efficiency</strong>:<br /> Twisted curves streamline critical operations like point addition and scalar multiplication. For example, twisted Edwards curves achieve point addition in 8M (8 field multiplications), significantly faster than Weierstrass curves. This speed is leveraged in schemes like <strong>EdDSA</strong>, a high-performance digital signature protocol.</p>
<ul>
<li>Curve25519 (a Montgomery curve) and its twisted Edwards counterpart, <strong>edwards25519</strong>, underpin secure communication protocols like Signal and TLS 1.3.</li>
</ul>
</li>
<li><p><strong>Pairing Optimization</strong>:<br /> In pairing-based cryptography, twists enable computations over smaller extension fields. For example, certain twists of pairing-friendly curves (e.g., BN curves) allow pairings to be computed in \(\mathbb{F}_{q^k}\) with reduced <em>k</em>, slashing computational overhead. This is critical for protocols like BLS signatures and identity-based encryption.</p>
</li>
<li><p><strong>Security</strong>:<br /> Twists must be <strong>twist-secure</strong>—meaning both the original curve and its twist resist attacks like the discrete logarithm problem. If a protocol fails to validate input points, an attacker could force computations on a weaker twist, compromising security. For example, Curve25519’s twist, Curve448, is designed to match its parent’s security.</p>
</li>
</ol>
<hr />
<h3 id="heading-twists-in-pairing-based-cryptography"><strong>Twists in Pairing-Based Cryptography</strong></h3>
<p>Pairing protocols (e.g., Type 3 pairings) often use twists to optimize subgroup structures:</p>
<ul>
<li><p><strong>Trace-Zero Subgroups</strong>: Twists can map elements to trace-zero subgroups \(G_2\), enabling efficient hashing and cofactor multiplication.</p>
</li>
<li><p><strong>Field Extensions</strong>: By leveraging twists, pairings like the Tate or Ate pairing reduce the embedding degree <em>k</em>, accelerating operations in \(\mathbb{F}_{q^k} \) .</p>
</li>
</ul>
<p>For instance, the <strong>anti-trace map</strong> \(\text{aTr} \) on twisted Edwards curves allows direct hashing into \(G_2\), a key advantage in Type 3 pairings.</p>
<hr />
<h2 id="heading-weil-and-tate-pairings">Weil and Tate Pairings</h2>
<p><strong>Weil Pairings:</strong> Let \(P,Q \in E(F_{q^k})[r] \) and let \(D_P\) and \(D_Q\) be degree zero divisors with disjoin support such that \(D_P \sim (P) - (O) \) and \(D_Q \sim (Q) - (O)\). There exist functions \(f\) and \(g\) such that \((f) = rD_P \) and \((g) = rD_Q\). The Weil pairings \(w_r\) is a map:</p>
<p>$$w_r: E(F_{q^k})[r] * E(F_{q^k})[r] \rightarrow \mu_{r }$$</p><p>defined as:</p>
<p>$$w_r(P,Q) = f(D_{Q}) / g(D_P)$$</p><p><strong>Tate Pairings:</strong> Let \(P  \in E(F_{q^k})[r]\) from which it follows that there is a function \(f\) whose divisor is \((f) = r(P) - r(O) \) . Let \(Q \in E(F_{q^k})\) be any representative in any equivalance class in \(E(F_{q^k}) / rE(F_{q^k})\)and let \(D_Q\) be a degree zero divisor defined over \(F_{q^k}\) that is equivalent to \((Q) - (O)\), but whose support is disjoint to that of \((f)\). The Tate pairing \(t_r\) is a map:</p>
<p>$$t_r : E(F_{q^k})[r] E(F_{q^k}) / rE(F_{q^k}) \rightarrow F^{q^k} / (F^*{q^k})^r$$</p><p>defined as:</p>
<p>$$t_r(P,Q) = f(D_Q)$$</p><hr />
<h3 id="heading-conclusion">Conclusion</h3>
<p>From group laws defining elliptic curves to the nuanced interplay of pairing types and twisted geometries, pairing-based cryptography bridges theoretical depth and practical innovation. As zero-knowledge systems and decentralized finance demand stronger privacy guarantees, these mathematical tools will remain indispensable—provided developers prioritize twist-secure parameters, optimal subgroup choices, and rigorous hardness assumptions. The future lies in balancing efficiency gains with quantum resilience, ensuring pairings evolve alongside cryptographic frontiers.</p>
<p>For more updates, insights, and discussions, connect with me on <a target="_blank" href="https://x.com/privacy_prophet"><strong>Twitter</strong></a> and <a target="_blank" href="https://www.linkedin.com/in/rachit-anand-srivastava/"><strong>LinkedIn</strong></a>.</p>
<h2 id="heading-references">References</h2>
<ul>
<li><a target="_blank" href="https://static1.squarespace.com/static/5fdbb09f31d71c1227082339/t/5ff394720493bd28278889c6/1609798774687/PairingsForBeginners.pdf">Parings for beginners</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Bilinear Pairings: Deep Dive Part 2]]></title><description><![CDATA[In the previous part we explored Fields, Torsion Points, and Endomorphism. Now we are gonna take our understanding of the topic further and dig into more constructions revolving around the Elliptic Curves, namely:

Divisors

Overview of Principal div...]]></description><link>https://blog.privacyprophet.xyz/bilinear-pairings-deep-dive-part-2</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/bilinear-pairings-deep-dive-part-2</guid><category><![CDATA[Cryptography]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[ KZG commitment]]></category><category><![CDATA[bilinear pairings]]></category><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Thu, 02 Jan 2025 08:30:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1735655023625/bf222d7c-92e9-471c-8228-5b55e0320653.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the <a target="_blank" href="https://blog.rachitasrivastava.com/bilinear-parings-deep-dive-part-1">previous part</a> we explored Fields, Torsion Points, and Endomorphism. Now we are gonna take our understanding of the topic further and dig into more constructions revolving around the Elliptic Curves, namely:</p>
<ul>
<li><p>Divisors</p>
</li>
<li><p>Overview of Principal divisor, Picard groups</p>
</li>
<li><p>Introduction to Genus</p>
</li>
</ul>
<h3 id="heading-understanding-divisors-a-key-concept-in-algebraic-geometry">Understanding Divisors: A Key Concept in Algebraic Geometry</h3>
<p>A <strong>divisor</strong> is a mathematical construct that helps us study functions and points on algebraic curves, such as elliptic curves. In simple terms, a divisor is a formal sum of points on a curve, where each point is assigned an integer coefficient.</p>
<h4 id="heading-formal-definition">Formal Definition</h4>
<p>A divisor DD on an algebraic curve CC is a formal sum of points:</p>
<p>$$D = \sum_{P\in C}n_p. P$$</p><p>where:</p>
<ul>
<li><p>P are the points on the curve C,</p>
</li>
<li><p>\(n_P\) are integers (can be positive, negative, or zero) also called multiplicity.. The <strong>multiplicity</strong> of a point in a divisor quantifies how much that point contributes to the divisor.</p>
<ul>
<li><p>\(n_p&gt; 0\) =&gt; point P contributes as a zero of a function</p>
</li>
<li><p>\(n_p &lt;0\) =&gt; point P contributes as a pole of a function</p>
</li>
<li><p>\(n_p = 0\) =&gt; point P does not contribute to the divisor.</p>
</li>
</ul>
</li>
<li><p>Only finitely many are nonzero.</p>
</li>
</ul>
<p>For example, D=3P−2Q+R is a divisor, where P, Q, and R are points on the curve.</p>
<p>The set of all divisors on \(E\) is denoted by \(Div_{\overline{F_q}}(E)\) and forms a group, where addition of divisors is natural, and the identity is the divisor with all \(n_p = 0\), the zero divisor \(0 \in Div_{\overline{F_q}}(E)\)</p>
<h4 id="heading-degree-of-a-divisor">Degree of a Divisor</h4>
<p>The <strong>degree</strong> of a divisor D is the sum of its coefficients:</p>
<p>$$D = \sum_{P\in C}n_p$$</p><ul>
<li>For \(D=3P−2Q+R, deg(D)=3−2+1=2\).</li>
</ul>
<p>Divisors of <strong>degree 0</strong> are particularly important in pairing-based cryptography because they often correspond to the group elements used in cryptographic operations.</p>
<p><strong>Support of a Divisor</strong></p>
<p>The support of a divisor D:</p>
<p>$$supp(D) = { P \in E(\overline{F_q})}$$</p><p><strong>Associating divisors with a function</strong></p>
<p>Writing divisors as a function f on E is a convenient way to write down the intersection points ( and their multiplicities) of f and E.</p>
<p>$$(f) = \sum_{P \in E(\overline{F_q})}ord_P(f)(P)$$</p><p>where \(ord_P(f) \) counts the multiplicity of f at P.</p>
<p>In pairing-based cryptography, divisors help define certain mathematical structures on elliptic curves:</p>
<ol>
<li><p><strong>Principal Divisors and Pairings</strong>: Bilinear pairings, such as the Weil pairing and Tate pairing, rely on divisors to define their operation.</p>
</li>
<li><p><strong>Divisors and Group Elements</strong>: The points on elliptic curves can be seen as specific types of divisors, and their manipulation through pairings is crucial for cryptographic protocols.</p>
</li>
</ol>
<hr />
<h3 id="heading-types-of-divisors">Types of Divisors</h3>
<ol>
<li><p><strong>Effective Divisor</strong>: All coefficients \(n_p &gt;= 0\). For instance, \(D = P + 2Q\).</p>
</li>
<li><p><strong>Principal Divisor</strong>: A divisor associated with a rational function f on the curve.</p>
<ul>
<li><p>Zeros of f contribute positively.</p>
</li>
<li><p>Poles of f contribute negatively.</p>
</li>
</ul>
</li>
</ol>
<p>    eg. If f has a zero of order 2 at P and a pole of order 1 at Q, its divisor is \(D = 2P - Q\).</p>
<p>    If a divisor D is equal to the divisor of a function, i.e. \(D = (f)\) then D is the principal divisor.</p>
<p>    A principal divisor always has degree of 0.</p>
<p>$$Prin(E) \subset Div^0(E) \subset Div(E)$$</p><h3 id="heading-understanding-divisor-equivalence-and-picard-groups">Understanding Divisor Equivalence and Picard Groups</h3>
<p>We will use an example to understand the divisor equivalence.</p>
<p>Consider the elliptic curve \(E/F_{61}: y^2 = x^3 + 8x + 1\). We have four points: \(P = (57, 24), Q=(25,37), R=(17,32), S = (42,35)\).</p>
<p>Two divisors on E:</p>
<ul>
<li><p>\(D_1 = (P) + (Q) + (R)\)</p>
</li>
<li><p>\(D_2 = 4(O) - (S) \) where O is point at infinity</p>
</li>
</ul>
<p><strong>Proving Equivalence:</strong> The divisors \(D_1\) and \(D_2\) are equivalent because there exists a rational function \(f(x,y)\) on \(E\) with the divisor: \((f) = (P) + (Q) + (R) + (S) - 4(O)\)</p>
<p>Here, \(f(x,y)\) is the function \(y = 33 x^2 + 10 x + 24\) which intersects \(E \) at \(P,Q,R,S\), each with the multiplicity of 1. This implies f has a pole of order 4 at \(O\). Substituting in the equivalence relation: \(D_1 = D_2 + (f)\) we see \(D_1\sim D_1\)showing that \(D_1 \) and \(D_2\) lie in the same divisor class.</p>
<p><strong>An alternate perspective:</strong> If finding \(f\) explicitly seems challenging, we can consider the difference \(D_1 - D_2= (P) + (Q) + (R) + (S) - 4(O)\). The divisor has degree zero, satisfying the condition for membership in the group of degree-zero divisors, \(Div^0(E)\). Using the addition law on elliptic curve, we compute: \(P+Q+R+S-[4]O = 0\) indicating that \(D_1- D_2\) belongs to the set of principal divisors, \(Prin(E).\) Thus \(D_1 - D_2 = (f) \) for some function f, reaffirming \(D_1 \sim D_2\).</p>
<h3 id="heading-picard-group-divisor-class-group"><strong>Picard Group ( Divisor Class group ):</strong></h3>
<p>The example introduces the Picard group of E. It is defined as:</p>
<p>$$Pic^0(E) = Div^0(E) / Prin(E)$$</p><p>In simpler terms, the Picard group is the collection of all degree-zero divisors, grouped by their equivalence under principal divisors.</p>
<p>Imagine you’re organizing a grand party, and you’re assigning tasks to your friends. Some of these tasks are simple, like “buy decorations” or “set up the music system,” while others are combinations of simpler tasks, like “prepare the venue” (which involves cleaning, arranging chairs, and decorating).</p>
<p>Now, here’s the catch: you don’t care <em>how</em> the tasks are grouped or assigned, as long as everything gets done. Whether one person handles “cleaning” and another does “decorating,” or one friend takes care of “preparing the venue” as a whole, it’s all the same to you as long as the end result is a successful party.</p>
<p>The <strong>Picard group</strong> works a bit like this. It’s a system for organizing and simplifying the roles (or relationships) of "tasks" (called divisors) on an elliptic curve. Here's how it works:</p>
<p><strong>The Party Roles as Divisors</strong></p>
<ol>
<li><p><strong>Tasks (Divisors)</strong>: On the curve, each point represents a “task.” Some tasks are simple (like single points), while others are combinations of tasks (like sums of points).</p>
</li>
<li><p><strong>Simplified Groups (Equivalence Classes)</strong>: If two sets of tasks result in the same outcome (e.g., the venue looks ready), the Picard group treats them as <em>equivalent</em>. In math terms, these are called <strong>divisor classes</strong>.</p>
</li>
<li><p><strong>Irrelevant Details (Principal Divisors)</strong>: Just like you might ignore the specific order in which chairs are arranged if the venue still looks perfect, the Picard group ignores certain kinds of "irrelevant" details (principal divisors). These don’t affect the overall result and are treated as if they were invisible.</p>
</li>
</ol>
<p>Let’s understand <strong>Principal divisor</strong> a bit using another analogy:</p>
<p>Imagine you have a see-saw, and you place weights (points on the curve) at different positions. The goal is to balance the see-saw so it doesn’t tip over.</p>
<p>Now, think of the function <em>f</em> as a special tool you can use to shift the weights around. This tool doesn’t change the total weight or the balance of the see-saw—it only redistributes the weights in a way that maintains equilibrium. Once the see-saw is balanced, the exact arrangement of weights doesn’t matter anymore; what matters is that the see-saw stays level.</p>
<p>In the mathematical world:</p>
<ul>
<li><p>The divisor of <em>f</em> (written as \((f)\)) records where <em>f</em> "puts" weights (its zeros and poles).</p>
</li>
<li><p>This divisor is called <strong>principal</strong> because it comes directly from <em>f</em>, which guarantees it maintains balance (degree zero).</p>
</li>
</ul>
<p>When we’re working in the <strong>Picard group</strong>, we only care about whether the "see-saw" is balanced (the overall divisor class), not the specific arrangement of weights. This is why <em>(f)</em> doesn’t change anything important—it’s invisible in this sense.</p>
<h3 id="heading-evaluating-a-function-at-a-divisor">Evaluating a Function at a Divisor</h3>
<p>Evaluating a function \(f  \in F_q(E)\) at a divisor \(D= \sum_{P \in E} n_p(P)\) has a natural definition, provided the divisors \((f)\) and \(D\) have disjoint supports:</p>
<p>$$f(D) = \prod_{P \in E}f(P)^{n_p}$$</p><hr />
<h2 id="heading-an-introduction-to-genus">An Introduction to Genus</h2>
<p>For any curve <em>C,</em> there is a unique minimal integer g, called the genus of C, such that any divisor \(D \in Pic^0(C)\) is equivalent to a divisor \(D^{'}\) with \(Deg(\epsilon(D^{'}) &lt;= g \) where \(~ \epsilon(D^{'}) \) is the effective divisor. Elliptic curves \(E\) are curves of genus = 1, meaning that every \(D \in Pic^0(E)\) can be written as \((P_1) - (Q_1)\).</p>
<p>Imagine you’re designing different types of paper-folding crafts. The <strong>genus</strong> of a surface tells you how many “holes” or “handles” it has. For example:</p>
<ul>
<li><p>A plain sheet of paper has <strong>no holes</strong>—it’s simple and flat. This is like a curve with <strong>genus 0</strong>.</p>
</li>
<li><p>If you take a piece of paper and make a single hole or a tunnel in the middle, you’ve added <strong>one hole</strong>. This is like a curve with <strong>genus 1</strong>.</p>
</li>
<li><p>If you were to fold or tear the paper to create multiple tunnels or holes, the number of holes increases, and the surface becomes more complex, which corresponds to a higher genus.</p>
</li>
</ul>
<p>Now, let’s relate genus to divisors.</p>
<ul>
<li><p>Think of a <strong>divisor</strong> as a way of distributing certain “marks” or “labels” across the surface of your folded paper (your curve). A divisor could represent things like:</p>
<ul>
<li><p><strong>Marks</strong> where the paper is bent (points where a function is zero), or</p>
</li>
<li><p><strong>Marks</strong> where the paper is torn (poles where a function has an infinite value).</p>
</li>
</ul>
</li>
</ul>
<p>    For any curve, the <strong>genus g</strong> tells us how complex these divisors can be. Specifically:</p>
<ul>
<li><p>The genus gives us an upper bound on how complicated the divisor can be while still remaining "balanced" or simple enough to manage.</p>
</li>
<li><p>No matter how complicated a divisor looks, we can always find a simpler equivalent divisor with at most <em>g</em> total complexity. Essentially, the genus limits how much complexity or imbalance can exist in the system.</p>
</li>
</ul>
<p>Elliptic curves are <strong>simple in terms of their genus</strong>, with \(g=1\) This means every divisor on an elliptic curve can be simplified to just the difference between two points.</p>
<p>Elliptic curves are of genus 1 because they have just enough complexity to be interesting (like a simple fold or tunnel in paper), but not too complex to make the math difficult to handle.</p>
<hr />
<p>This concludes Part 2 of our series, where we've explored the Picard group, divisors, principal divisors, genus, and their interconnections. In the next part, we’ll dive into "Pairing Groups" and build on everything we've discussed so far, leading us to a deeper understanding of bilinear relationships.</p>
<p>In the next part, we will dig into "Pairing Groups" and connect everything we discussed so far to create a bilinear relationships. Stay tuned!</p>
<p>For more updates, insights, and discussions, connect with me on Twitter: <a target="_blank" href="https://x.com/privacy_prophet">@privacy_prophet</a>.</p>
<hr />
<h2 id="heading-references">References</h2>
<ul>
<li><a target="_blank" href="https://static1.squarespace.com/static/5fdbb09f31d71c1227082339/t/5ff394720493bd28278889c6/1609798774687/PairingsForBeginners.pdf">Parings for beginners</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Bilinear Parings: Deep Dive Part 1]]></title><description><![CDATA[In this blog series we will be digging deep into the working of bilinear pairings in Elliptic curves over finite fields. The following series presumes you have a decent understanding Elliptic Curves:

Group law - the chord and tangent rule.

Fields a...]]></description><link>https://blog.privacyprophet.xyz/bilinear-parings-deep-dive-part-1</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/bilinear-parings-deep-dive-part-1</guid><category><![CDATA[bilinear pairings]]></category><category><![CDATA[Cryptography]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[Mathematics]]></category><category><![CDATA[ KZG commitment]]></category><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Thu, 26 Dec 2024 10:30:25 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1735127129255/8561d502-4c8d-480a-946b-41181c3859dc.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog series we will be digging deep into the working of bilinear pairings in Elliptic curves over finite fields. The following series presumes you have a decent understanding Elliptic Curves:</p>
<ul>
<li><p>Group law - the chord and tangent rule.</p>
</li>
<li><p>Fields and how field operations work.</p>
</li>
<li><p>Identify Element</p>
<blockquote>
<p>You can find resources to learn about the above topic here → <a target="_blank" href="https://github.com/rac-sri/cryptography-101">Cryptography 101</a></p>
</blockquote>
</li>
</ul>
<hr />
<h2 id="heading-elliptic-curve-cryptography">Elliptic Curve Cryptography</h2>
<h3 id="heading-introduction-to-elliptic-curve-cryptography-ecc">Introduction to Elliptic Curve Cryptography (ECC)</h3>
<p>Elliptic Curve Cryptography (ECC) has revolutionised the field of cryptography by enabling secure communication with much smaller key sizes compared to traditional methods like RSA. Its foundation lies in the mathematical properties of elliptic curves, which provide both security and efficiency for modern cryptographic systems.</p>
<p>An elliptic curve is defined by an equation of the form:</p>
<p>$$y^2 =x^3 +ax+b$$</p><p>where a and b are constants that satisfy specific conditions to ensure the curve forms a smooth, non-singular shape. The points on this curve, along with a special "point at infinity," form a mathematical structure that can be used for cryptographic operations.</p>
<p>The core idea of ECC relies on the <strong>elliptic curve group</strong> and operations like <strong>point addition</strong> and <strong>scalar multiplication</strong>. These operations underpin the security of ECC-based systems, making it infeasible for attackers to reverse-engineer private keys from public ones due to the computational difficulty of the Elliptic Curve Discrete Logarithm Problem (ECDLP).</p>
<h3 id="heading-understanding-point-addition">Understanding Point Addition</h3>
<p>One of the fundamental operations in ECC is <strong>point addition</strong>, which is the process of adding two points PP and QQ on an elliptic curve to produce another point RR. Depending on whether PP and QQ are distinct or identical, the operation involves different calculations:</p>
<ul>
<li><p>If \(P != Q\), a line passing through P and Q intersects the curve at a third point. Reflecting this point across the x-axis gives RR.</p>
</li>
<li><p>If \(P = Q\), the operation is called <strong>point doubling</strong>. In this case, a tangent line to the curve at P is used to find the third point, followed by reflection.</p>
</li>
</ul>
<p>These operations are not only geometrically intriguing but also computationally efficient, making them suitable for cryptographic systems.</p>
<p><strong>Bilinear pairings</strong>, which extend the capabilities of ECC, point addition and other fundamental ECC operations play a critical role in setting up the necessary mathematical framework.</p>
<p>$$e(a, b) : G_1 \times G_2 \to G_T$$</p><h3 id="heading-introduction-to-fields-in-mathematics">Introduction to Fields in Mathematics</h3>
<p>In cryptography, <strong>fields</strong> play a foundational role as they provide the mathematical framework for operations on elliptic curves and other cryptographic structures. A <strong>field</strong> is a set of elements equipped with two operations: addition and multiplication, which satisfy certain properties. These properties ensure that every element (except zero for multiplication) has an inverse, making the operations well-defined and consistent.</p>
<p>Some key characteristics of a field include:</p>
<ol>
<li><p><strong>Closure</strong>: The result of adding or multiplying any two elements in the field is also in the field.</p>
</li>
<li><p><strong>Associativity and Commutativity</strong>: Both addition and multiplication are associative and commutative.</p>
</li>
<li><p><strong>Identity Elements</strong>: The field has an additive identity (0) and a multiplicative identity (1).</p>
</li>
<li><p><strong>Inverses</strong>: Every element has an additive inverse, and every non-zero element has a multiplicative inverse.</p>
</li>
</ol>
<p>The most common examples of fields are:</p>
<ul>
<li><p>The field of <strong>real numbers</strong></p>
</li>
<li><p>The field of <strong>rational numbers</strong></p>
</li>
<li><p><strong>Finite fields</strong>, also known as Galois fields \(F_p\), which are critical in cryptography.</p>
</li>
</ul>
<p>In the case of elliptic curve cryptography, we often work over finite fields, such as \(F_p\) These fields allow us to define elliptic curves and perform secure, efficient computations, paving the way for robust cryptographic systems.</p>
<hr />
<h3 id="heading-lets-dive-into-some-in-depth-design-topics-of-ecc-torsion-points-and-endomorphism">Let's dive into some in-depth design topics of ECC: <em>Torsion Points</em> and <em>Endomorphism</em>.</h3>
<h2 id="heading-torsion-points">Torsion Points</h2>
<p>Let’s have a quick recall of what point of Infinity is and how it correlates to the order of a Point in ECC:<br />The <strong>order of a point</strong> P on an elliptic curve is the smallest positive integer n such that:</p>
<p>\(nP=P+P+⋯+P=P+P+⋯+P(n times)=O\)</p>
<p>where O is the <strong>point at infinity</strong>, which acts as the identity element in the group of points on the curve.</p>
<ul>
<li><p>If \(nP=O\), then P is said to have an order of n.</p>
</li>
<li><p>For any point P, the order n divides the total number of points on the curve (known as the <strong>curve order</strong>).</p>
</li>
</ul>
<p>Now, the group order can be divides into smaller subgroups, based on Lagrange’s theorem.</p>
<p>For example, consider the curve ( \(E/\mathbb{F}_{101} : y^2 = x^3 + x + 1\) <em>).</em> The # \(  E/{F}_{101} = 105 = 3 \cdot 5 \cdot 7\). So we can get a point of order \(r|105\) by simply multiplying P by the appropriate cofactor, which is \(h = Order / r\). For example to get a point of order 3: \([35]P\). By definition a point is “killed” ( sent to O ) when multiplied by its order.</p>
<p><strong>Any point killed by r over the full closure</strong> \(E(\overline F_q)\) <strong>is said to be in the <em>r-torsion</em>. (</strong> The <strong>algebraic closure</strong> of a finite field \(F_q​, denoted \space \overline{{F}_q}\)​​, is the set of all roots of all polynomials with coefficients in \(F_q\)​. It is the "largest possible extension field" of \(F_q\) that contains every solution to such polynomials. <strong>)</strong></p>
<p>By <strong>Hasse's theorem</strong>, the curve order is approximately \(q+1\), with a margin of error bounded by \(2\sqrt{q}​:\)</p>
<p>$$q+1−2\sqrt{q}≤ Order{ } E(F_q)≤q+1+2\sqrt{q}$$</p><p>The offset between # \(E(F_q)\) and \(q+1\) is called the <strong>trace of Frobenius</strong> and is denoted by t:</p>
<p>$$Order E(F_q) = q+1-t, {\space } where |t| &lt;= 2\sqrt{q}$$</p><h2 id="heading-endomorphism">Endomorphism</h2>
<h3 id="heading-what-is-the-endomorphism-ring">What Is the Endomorphism Ring?</h3>
<p>The endomorphism ring \(End(E)\) is a collection of all "maps" (functions) that take points on an elliptic curve EE and send them to other points on the same curve, while preserving the group structure. These maps can be thought of as ways to transform the curve while keeping its essential properties intact.</p>
<p>In this ring:</p>
<ul>
<li><p><strong>Addition of maps</strong> works point wise: \((ψ_1+ψ_2)(P)=ψ_1(P)+ψ_2(P)\).</p>
</li>
<li><p><strong>Multiplication of maps</strong> is done through composition: \((ψ1∘ψ2)(P)=ψ1(ψ2(P))\).</p>
</li>
</ul>
<h3 id="heading-trivial-endomorphisms">Trivial Endomorphisms</h3>
<p>Some endomorphisms are always present:</p>
<ol>
<li><p>The <strong>multiplication-by-m</strong> map, denoted \([m]\), scales a point P by \(m: [m](P)= P + P + \dots + P \space (m \space times)\).</p>
</li>
<li><p>For elliptic curves defined over finite fields, there’s an additional map called the <strong>Frobenius endomorphism</strong> \(\pi\), which raises the coordinates of a point to the power q.</p>
<p> If \(E\) is defined over \(F_q\), then the <strong>Frobenius endomorphism</strong> \(\pi\) is defined as:</p>
</li>
</ol>
<p>$$\pi : E \mapsto E, \space (x,y) \mapsto ( x^q, y^q )$$</p><h3 id="heading-non-trivial-endomorphisms">Non-Trivial Endomorphisms</h3>
<p>Sometimes, elliptic curves have additional, more interesting endomorphisms. Let’s look at an example:</p>
<ul>
<li><p>Consider the curve \(E:y^2=x^3+b\) over a finite field \(F_q\).</p>
</li>
<li><p>A special map, \(ξ\) is defined as \(ξ(x,y)=(ξ_3x,y)\) where \(ξ_3\) is a cube root of 1 \((ξ_3^3=1 \space but \space ξ_3≠1)\).</p>
</li>
<li><p>Whether \(ξ\) is a valid endomorphism depends on the field:</p>
<ul>
<li><p>If \(ξ_3∈Fq\) then \(ξ\) is defined over \(F_q\).</p>
</li>
<li><p>Otherwise, \(ξ_3\) lies in an extended field (e.g., \(F_{q^2}\)), meaning \(ξ\) operates on a larger space.</p>
</li>
</ul>
</li>
</ul>
<p>The <strong>Frobenius endomorphism</strong> \(\pi\) is a special type of endomorphism on an elliptic curve E defined over a finite field \(F_q\)​. Essentially, the Frobenius endomorphism maps a point \(P=(x,y)\) on the elliptic curve E over \(F_q\)​ to a new point \(π(P)=(x^q,y^q)\). This means it raises the coordinates of the point to the power of q (the size of the finite field), which can be thought of as a sort of "Frobenius twist."</p>
<ul>
<li><p><strong>Effect on Points</strong>: When the Frobenius map \(\pi\) is applied to a point \(P=(x,y)\) the new point \(π(P)=(x^q,y^q)\) lies on the same elliptic curve, but the point might be in a different field extension, depending on the situation.</p>
</li>
<li><p><strong>Fixed Points</strong>: One of the important properties of the Frobenius map is that it "fixes" certain points. That is, if P is a <strong>fixed point</strong> of the Frobenius map, then applying the map again doesn't change the point. This happens in particular for points that are in the field \(F_q\)​, where raising the coordinates to the power \(q\) leaves the point unchanged.</p>
</li>
<li><p><strong>Mapping Across Extensions</strong>: The Frobenius endomorphism π\piπ also connects points from \(E(F_q)\) (the elliptic curve over \(F_q\)​) to points in higher field extensions, such as \(E(F_{q^2})\), depending on the specific case. This means that the Frobenius map can take points from \(E(F_q) \space to \space E(F_{q^2})\) and beyond, depending on how the curve is defined and the properties of the field.</p>
</li>
</ul>
<p><strong>Example</strong>: Cubic roots of unity will be defined in \(F_q\) if and only if \(q = 1 \space mod \space 3\)( this is because the multiplicative group of non zero elements in \(F_q\)​ is cyclic, and its order is \(q-1\). If \(q≡1 \space (mod \space 3)\) then \(q-1\) is divisible by 3, which ensures that there are elements in the field that satisfy \(x^3 = 1\). The <strong>order</strong> of an element \(g^k\) in the cyclic group is the smallest integer n such that \(g^{kn} = 1\). For \(x = g^k\) to satisfy \(x^3 = 1\), the order of \(g^k\) must divide 3. In a cyclic group, the order of any element divides the total order of the group ) . Let’s take curve equation : \(y^2 = x^3 +5\)</p>
<ul>
<li><p>Over \(F_{19}, ξ_3=7\) is a valid cube root of 1, so \( ξ\) works within \(F_{19}\).</p>
</li>
<li><p>Over, \( F_{23}\) no cube root of 1 exists in \(F_{23}\). We need to extend to \(F_{23^2}\) to define \( ξ\). So we form quadratic extension \(F_{q^2}(u), u^2 + 1 = 0\). Now, \( ξ_3 = 8u + 11\) is a valid cube root.</p>
</li>
</ul>
<p><strong>Complex Multiplication (CM):</strong> When an elliptic curve has extra, non-trivial endomorphisms like \(ξ\), its endomorphism ring becomes larger than the integers \(Z\). This is called <strong>complex multiplication (CM)</strong>.</p>
<ul>
<li><p>All elliptic curves defined over finite fields \(F_q\) have CM because the Frobenius endomorphism \(\pi\)always adds complexity to \(End(E)\).</p>
</li>
<li><p>For curves defined over other fields (like \(Q\)), the presence of CM is less common and depends on whether additional maps exist.</p>
</li>
</ul>
<p><strong>Trace of Frobenius</strong> plays role in the characteristic polynomial satisfied by \(\pi\) given as:</p>
<p>$$\pi ^2 - [t].\pi + [q] = 0 \space in \space End(E)$$</p><p>meaning for all \((x,y) \in E( \overline{F_q})\) we have \((x^{q^2}, y^{q^2}) - [t] ( x^q, y^q) + [q](x,y) = O\)</p>
<hr />
<p>This brings us to the end of Part 1 of this series. In the next part, we will dig into "Divisors," a concept from Algebraic Geometry, but we'll limit its scope to how it works in Elliptic Curves. Stay tuned!</p>
<p>For more updates, insights, and discussions, follow me on Twitter: <a target="_blank" href="https://x.com/privacy_prophet">@privacy_prophet</a>.</p>
<h2 id="heading-references">References</h2>
<ul>
<li><p><a target="_blank" href="https://static1.squarespace.com/static/5fdbb09f31d71c1227082339/t/5ff394720493bd28278889c6/1609798774687/PairingsForBeginners.pdf">Parings for beginners</a></p>
</li>
<li><p><a target="_blank" href="https://medium.com/@VitalikButerin/exploring-elliptic-curve-pairings-c73c1864e627#:~:text=Elliptic%20curve%20pairings%20\(or%20%E2%80%9Cbilinear,curve%2Dbased%20protocols%20can%20do.">Pairings by Vitalik</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Verkle Tries Explained: A Simple Guide for Beginners]]></title><description><![CDATA[Welcome to a deep dive into Verkle trees and their impact on Ethereum's state management. As Ethereum aims to improve scalability and efficiency, Verkle trees are becoming a key part of the solution.
In this blog, we'll break down what Verkle trees a...]]></description><link>https://blog.privacyprophet.xyz/verkle-tries-explained-a-simple-guide-for-beginners</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/verkle-tries-explained-a-simple-guide-for-beginners</guid><category><![CDATA[verkle]]></category><category><![CDATA[merkle tree]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[data structures]]></category><category><![CDATA[State Management ]]></category><category><![CDATA[StateLESS]]></category><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Sat, 10 Aug 2024 18:29:37 GMT</pubDate><content:encoded><![CDATA[<p>Welcome to a deep dive into Verkle trees and their impact on Ethereum's state management. As Ethereum aims to improve scalability and efficiency, Verkle trees are becoming a key part of the solution.</p>
<p>In this blog, we'll break down what Verkle trees are and how they compare to the traditional hexary Patricia trees. We'll discuss the upcoming changes that will introduce Verkle trees alongside the current hexary Patricia trees. After these changes, all state edits and copies of accessed state will be stored in the Verkle tree, while the hexary Patricia tree will be locked from further modifications. This marks the first step in moving Ethereum towards exclusively using Verkle trees for state storage. Let's explore the details and understand why this change is crucial for Ethereum's future.</p>
<p>Ethereum requires statelessness moving forward. Stateless clients are ones that do not have to store the entire state database in order to validate incoming blocks. Instead of using their own local copy of Ethereum's state to verify blocks, stateless clients use a "witness" to the state data that arrives with the block.</p>
<p>A witness is a collection of individual pieces of the state data that are required to execute a particular set of transactions, and a cryptographic proof that the witness is really part of the full data.</p>
<p>Currently, in a hexary Merkle tree, the witness sizes are huge.<br />State access proposed gas cost = 1900, and current gas limit = 30M. This implies a total of 15789 state accesses.</p>
<ul>
<li><p>Using hexary merkle tree: 3kB per witness =&gt; ~47 MB!!!</p>
</li>
<li><p>Using binary Merkle tree: 0.5 kB/witness = 8 MB</p>
</li>
<li><p>Using width 256 verkle tree, 32 byte group: 96 byte/witness = 1.5 MB</p>
</li>
</ul>
<h2 id="heading-understanding-merkle-trees">Understanding Merkle Trees</h2>
<p>A <strong>Merkle tree</strong> is a type of data structure used in computer science and cryptography to efficiently and securely verify large sets of data. It's particularly important in blockchain technologies, such as Bitcoin and Ethereum. Here’s how it works:</p>
<h3 id="heading-structure-of-a-merkle-tree">Structure of a Merkle Tree</h3>
<ol>
<li><p><strong>Leaf Nodes</strong>: The bottom-most nodes in the tree are called leaf nodes. Each leaf node contains the hash of a piece of data (for example, a transaction in a blockchain).</p>
</li>
<li><p><strong>Non-Leaf Nodes</strong>: Each non-leaf node is the hash of its two child nodes. This means that every node in the tree (except the leaves) is a hash of the data below it.</p>
</li>
<li><p><strong>Root Hash</strong>: The top node of the tree is known as the root hash or Merkle root. This single hash represents the entire data set.</p>
</li>
</ol>
<h3 id="heading-how-it-works">How it Works</h3>
<ul>
<li><p><strong>Hashing</strong>: Hashing is the process of converting data into a fixed-size string of characters, which is typically a unique representation of the data. In a Merkle tree, the data in each leaf node is hashed.</p>
</li>
<li><p><strong>Combining Hashes</strong>: Each pair of leaf node hashes is combined and then hashed again to form a parent node. This process is repeated up the tree until you reach the root hash.</p>
</li>
</ul>
<h3 id="heading-example">Example</h3>
<p>Imagine you have four transactions, A, B, C, and D. Here’s how you would create a Merkle tree:</p>
<ol>
<li><p>Hash each transaction to create four leaf nodes: <code>Hash(A)</code>, <code>Hash(B)</code>, <code>Hash(C)</code>, <code>Hash(D)</code>.</p>
</li>
<li><p>Pair the leaf nodes and hash them to create the next level: <code>Hash(Hash(A) + Hash(B))</code>, <code>Hash(Hash(C) + Hash(D))</code>.</p>
</li>
<li><p>Finally, hash these results together to create the root hash: <code>Hash(Hash(Hash(A) + Hash(B)) + Hash(Hash(C) + Hash(D)))</code>.</p>
</li>
</ol>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/95/Hash_Tree.svg/1920px-Hash_Tree.svg.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-what-if-we-increase-the-width-of-the-merkle-tree">What if we increase the width of the merkle tree ?</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722802342023/07c3c352-e6a3-4761-bd86-a37a4fecc40b.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>In this case, to check a particular leaf, all siblings need to be passed to verify its inclusion inside <code>inner 01</code> i.e. if there are <code>n</code> number of leafs, to calculate the immediate hash, we need to provide <code>n-1</code> number of leaf hashes.</p>
</li>
<li><p>The proofs become very inefficient</p>
</li>
</ul>
<h3 id="heading-where-does-verkle-trees-come-into-play">Where does Verkle trees come into play ?</h3>
<p>The goal is to have a scheme where we can have less height of the tree and still are able to efficiently proof all siblings. We do this by introducing "Verkle Commitments" in the structure.</p>
<h2 id="heading-verkle-trie">Verkle Trie</h2>
<ul>
<li><p>Verkle = Vector commitment + Merkle. Basically a merkle tree but with vector commitments instead of hashes.</p>
</li>
<li><p>Trie = tree + retrieval i.e. tree where each node represents a prefix of keys.</p>
</li>
</ul>
<h3 id="heading-understanding-vector-commitment-schemes">Understanding Vector Commitment Schemes</h3>
<p>We will use KZG or Kate commitment scheme since its fairly more popular construction. In KZG we essentially create a polynomial, and then evaluate the polynomial at a secrete point. This is our vector commitment. The key is that using this commitment, we can do "openings" on the commitment and check the inclusion of a given set of points. You can read more about how this scheme works <a target="_blank" href="https://blog.rachitasrivastava.com/demystifying-kzg-poly-commit-scheme">here</a>.</p>
<p>Similarly another property of KZG is the ability to do multi proofs check. Essentially we can verify the inclusion of a set of point inside a KZG commited polynomial with a single pairing check. More info <a target="_blank" href="https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html">here</a>.</p>
<p>From the above, it's easy to understand the advantages of a vector commitment over hash based commitment:</p>
<p>We can essentially "open" a vector commitment to verify the inclusion of a piece of data, contrary to hashed where we have to regenerate the hash itself, using all the involved data points. This reduced the size of our witness significantly.</p>
<p>Now, imagine the same tree before, but now nodes are a vector commitment rather than hash based commitments. This implies that to confirm the inclusion of a leaf, I need to do an opening check on the root, and similarly on the inner node, without having to supply all the siblings. Essentially reducing my witness size dramatically.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722803083003/372b0573-ea87-4cab-a053-535ebe5807f9.png" alt="( credits: Dankred Feist )" class="image--center mx-auto" /></p>
<p>How to navigate:</p>
<p>Verkle proof for a single leaf: <code>0101 0111 1010 1111 -&gt; 1213</code> is a key value pair.</p>
<p><img src="https://dankradfeist.de/assets/verkle_trie.svg" alt class="image--center mx-auto" /></p>
<ul>
<li><p>We start from the root, the proof of Inner root A us <code>0101</code>`.</p>
</li>
<li><p>Proof that the root of Inner node B is the evaluation of the commitment of Inner node A at <code>0111</code>.</p>
</li>
<li><p>Proof that the root of the node <code>0101 0111 1010 111 -&gt; 1213</code> is the evaluation of the commitment of Inner node B at index 1010</p>
</li>
</ul>
<h3 id="heading-pedersen-commitment-scheme">Pedersen Commitment Scheme</h3>
<p>The scheme involves:</p>
<ul>
<li><p>Elliptic group G with generators \(g\_1, g\_2, ..., g\_n\\\).</p>
<ul>
<li><p>The only important thing is that their relative discrete logarithm (\(g\_1=q∗g\_2\\\) is not known</p>
</li>
<li><p>This does not need a trusted setup</p>
</li>
</ul>
</li>
<li><p>To commit to vector \(x\_1, x\_2, …, x\_n\\\)</p>
<ul>
<li>Compute \(C = x\_1 * g\_1 + x\_2 *  g\_2 + ... +  x\_n * g\_n\\\)Ethereum state after migration</li>
</ul>
</li>
</ul>
<p><strong>Why Pederson commitment</strong></p>
<ul>
<li><p>Smaller commitments+proofs as no pairing-friendly group (32 bytes)</p>
</li>
<li><p>No trusted setup</p>
</li>
<li><p>Everything can be done inside a SNARK as well</p>
</li>
</ul>
<p><img src="https://storage.googleapis.com/ethereum-hackmd/upload_2eea7f262d0e6a38fa048c6194df24ea.png" alt class="image--center mx-auto" /></p>
<p><strong>Key Structure</strong></p>
<p>\(key = Pederson(Contract Address, Storage Location[:-1]\\\) + suffix</p>
<p>where suffix = \(offset % 256\\\) ( offset in the group of 256 leaves )</p>
<ul>
<li>The key is called the <code>stem</code> , which gives the pass through the stem tree and extension, and then we use suffix to get the element in the suffix tree.</li>
</ul>
<h3 id="heading-state-expiry">State Expiry</h3>
<p>Currently, once you pay fees on ethereum, the day stays forever. This causes state bloat after a while.</p>
<p>Now, after a while data will expire</p>
<ul>
<li><p>Each year, a new period starts with a fresh tree</p>
</li>
<li><p>Data for the current and previous period is kept</p>
</li>
<li><p>Data of previous years is discarded ( except the root )</p>
</li>
<li><p>After two periods, data needs to be resurrected with a proof.</p>
</li>
</ul>
<p><strong>Address Space Extension</strong></p>
<p>State expiry comes with a thing called Address Space Extension.</p>
<ul>
<li><p>Currently in ethereum, address are 20 bytes long, which are the first 20 bytes of the hash of your public key.</p>
</li>
<li><p>Now the pub key will be 32 bytes. We take 26 bytes of the hash, the remaining 6 bytes are used for versioning and future use, and to denote the epoch / period.</p>
</li>
</ul>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Period</td><td>Address</td><td>Balance</td></tr>
</thead>
<tbody>
<tr>
<td>0</td><td>010000<strong>000000</strong>000000...00000000</td><td>1234</td></tr>
<tr>
<td>0</td><td>010000<strong>000000</strong>000000...00000001</td><td>4567</td></tr>
<tr>
<td>1</td><td>010000<strong>000001</strong>0000000...0000000</td><td>7890</td></tr>
<tr>
<td>2</td><td>010000<strong>000002</strong>0000000...0000000</td><td>1121</td></tr>
<tr>
<td>2</td><td>010000<strong>000000</strong>0000000...0000000</td><td>1234</td></tr>
</tbody>
</table>
</div><ul>
<li><p>Period 0: Lets say Alice controls address 0x000...000. Bob has address 0x000.0001. Both have period as 0 since they are scene for the first time.</p>
</li>
<li><p>Period 1: Alice receives some funds from Bob, Bob doesn't actually resurrect the address from period 0 actually, but sends the funds to Alice to an address containing the current period ( 1 ). So it's seen for the first time in period 1. Alice still controls the private key of this hash, so in a way she controls two addresses with 1 private key.</p>
</li>
<li><p>Period 2: Alice wants the value from period one, she passes a proof to resurrect the address. The value from Period 1 that bob send, is not overwritten.</p>
</li>
</ul>
<p>Points around Address State Extension:</p>
<ul>
<li><p>Simplify data storage problem.</p>
</li>
<li><p>Risk of breaking existing contracts.</p>
</li>
</ul>
<h3 id="heading-state-network">State Network</h3>
<ul>
<li><p>A network alongside the block propagation network.</p>
</li>
<li><p>A node only stores a subset of the entire data.</p>
</li>
<li><p>Data is requested over the network as needed</p>
</li>
<li><p>A proof is provided to ensure that the provided data is correct.</p>
</li>
</ul>
<p>And that covers the whole design around Verkle trees.</p>
<p>Connect with on Twitter <a target="_blank" href="https://x.com/privacy_prophet">@privacy_prophet</a> where I post deep insights on a wide variety of topics in the Blockchain ecosystem.</p>
<hr />
<p><strong>Resources</strong></p>
<ul>
<li><p><a target="_blank" href="https://notes.ethereum.org/@vbuterin/verkle_tree_eip">Vitalik Blog</a></p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=RGJOQHzg3UQ&amp;t=475s">Dankshard Feist session on Verkle trees</a></p>
</li>
<li><p><a target="_blank" href="https://ethereum-magicians.org/t/proposed-verkle-tree-scheme-for-ethereum-state/5805">Proposed Verkle Tree Scheme</a></p>
</li>
<li><p><a target="_blank" href="https://blog.ethereum.org/2021/12/02/verkle-tree-structure">Ethereum.org Blog</a></p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=f7bEtX3Z57o&amp;t=1317s">Statelessness and Verkle Trees by Guillaume Ballet</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Groth 16: A linear PCP based Snark]]></title><description><![CDATA[Prerequisites:

Understanding of what QAP is and how to create one from R1CS.

Group theory understandings

Bilinear Pairings



Probabilistic Checkable Proofs ( PCP )
What is a PCP:
Prover generates a PCP oracle, which can be thought of as a big mes...]]></description><link>https://blog.privacyprophet.xyz/groth-16-a-linear-pcp-based-snark</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/groth-16-a-linear-pcp-based-snark</guid><category><![CDATA[groth16]]></category><category><![CDATA[snarks]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[zero-knowledge-proofs]]></category><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Fri, 05 Jan 2024 09:30:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704194856204/1f63f4ed-0578-4f64-90a5-d025e65ecf12.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Prerequisites:</p>
<ul>
<li><p>Understanding of what QAP is and how to create one from R1CS.</p>
</li>
<li><p>Group theory understandings</p>
</li>
<li><p><a target="_blank" href="https://twitter.com/RacSri25/status/1738503612094148718">Bilinear Pairings</a></p>
</li>
</ul>
<hr />
<h3 id="heading-probabilistic-checkable-proofs-pcp">Probabilistic Checkable Proofs ( PCP )</h3>
<p>What is a PCP:</p>
<p>Prover generates a PCP oracle, which can be thought of as a big message of polynomial size. Verifier queries PCP oracle at random points, and using these queries verifier can verify the computation of a polynomial.</p>
<p>In Linear PCP, the PCP generated by the Prover is a linear function. The Oracle responds to linear queries by doing an inner product.</p>
<p>Recall:</p>
<p>\(p(x) = (\sum_{i=1}^m c_i   \times l_i(x)) \times (\sum_{i=1}^m c_i   \times r_i(x)) \times (\sum_{i=1}^m c_i   \times o_i(x)) = V(x).q(x)\)</p>
<p>To show the above can be done using a linear PCP model.</p>
<ul>
<li><p>The verifier can submit only linear queries to the PCP:</p>
<p>  \( \times  -  = V(\gamma)\)</p>
</li>
</ul>
<hr />
<p><strong>Some terminologies before we continue further:</strong></p>
<ul>
<li><p><strong>Knowledge of exponentiation:</strong></p>
<ul>
<li><p>Sample random \(\alpha\), compute \(g^{\alpha .l_i(\tau)}\) for i = 1...m.</p>
</li>
<li><p>\(\pi_1 = g^{\sum_{i=1}^m c_i \times l_i (\tau)}\) and \(\pi_1^{'} = g^{\sum_{i=1}^m c_i \times l_i (\tau)}\)</p>
</li>
<li><p>\(e(\pi_1, g^\alpha) = e(\pi^{'}, g)\)</p>
</li>
</ul>
</li>
<li><p><strong>Generic Group Model</strong></p>
<ul>
<li><p>The adversary is only given an oracle to compute the group operation.</p>
</li>
<li><p>eg. given \(g^{\alpha.l_i(\tau)}\)for i= 1,...,m. The adversary can only compute their linear combinations.</p>
</li>
</ul>
</li>
</ul>
<hr />
<h3 id="heading-linear-pcp"><strong>Linear PCP</strong></h3>
<ul>
<li><p><strong>Preprocessing ( Key Generation )</strong>:</p>
<ul>
<li><p>Proving key: \(p, G, g, G_T, e\)</p>
</li>
<li><p>Compute Public Keys: \(g^{l_i(\tau)},g^{r_i(\tau)},g^{o_i(\tau)}\) for \(i=1, \ldots,m\) --- (1)</p>
</li>
<li><p>Evaluate: \(g^\tau , g^{\tau^2}, \ldots, g^{\tau^m}\) ( Public ). --- (2)</p>
</li>
<li><p>Also: \(g ^ {\beta(l_i(\tau) + r_i(\tau) + o_i(\tau))})\) for \(i \in [m]\) --- (3)</p>
</li>
<li><p>Verification Key: \(g^V(\tau) \) - this is known to the verifier</p>
</li>
<li><p>delete \(\tau\)</p>
</li>
</ul>
</li>
<li><p>Prove Generation</p>
<ul>
<li><p>\(\pi _1 = g^{\sum_{i=1}^m c_i \times l_i(\tau)}\) , where the term in power is the public key calculated in (1).</p>
</li>
<li><p>Similarly, calculate \(\pi _2\) and \(\pi _3\) using (1) above.</p>
</li>
<li><p>\(\pi _4 = g^{q(\tau)}\) calculated using (2) above.</p>
</li>
<li><p>\(\pi_5 = \prod _{i=1}^m (g ^ {\beta(l_i(\tau) + r_i(\tau) + o_i(\tau))})^{c_i}\)</p>
</li>
</ul>
</li>
<li><p>Verification</p>
<ul>
<li><p>The idea is to check the value of p(x) equation equality in the exponent.</p>
</li>
<li><p>Verify using: \(\frac{e(\pi_1, \pi_2)}{e(\pi_3, g)} = e(g^{V(\tau)}, \pi_4)\) bilinear relation.</p>
</li>
<li><p>\(e(\pi_1\pi_2\pi_3, g^\beta) = e(\pi_5, g)\): This check makes sure that the prover isn't cheating and not using the same vector \(c\) in the generation of \(\pi_1, \pi_2, \pi_3\).</p>
</li>
</ul>
</li>
</ul>
<p>The above protocol is not the real implementation. If you notice, while input in the above circuit is considered as a witness. But in practical application, a circuit has both, public and private inputs.</p>
<p>So to convert the above into a real protocol, notice the proof property that is generated above:</p>
<p>$$\pi_1 = g^{\sum_{i \in I_{mid}}c_i \times l_i(\tau)} * g^{\sum_{i \in I_{io}}c_i \times l_i(\tau)}$$</p><p>where \(I_{mid}\) is the witness, and \(I_{io}\) is the public Input/output. So now the proof becomes:</p>
<p>$$\pi_1 = g^{\sum_{i \in I_{mid}}c_i \times l_i(\tau)}$$</p><p>and the verifier can simply do:</p>
<p>$$\pi_1^* = \pi_1 . g^{\sum_{i \in I_{io}}c_i \times l_i(\tau)}$$</p><p>$$\frac{e(\pi_1*,\pi_2*)}{e(\pi_3^*, g)} = e(g^{V(\tau), \pi_4})$$</p><p>And that's Groth 16 protocol under the hood!!</p>
<hr />
<h3 id="heading-variant-of-groth16">Variant of Groth16</h3>
<p>$$p(x) = (\sum_{i=1}^m c_i \times l_i(x)) \times (\sum_{i=1}^m c_i \times r_i(x)) \times (\sum_{i=1}^m c_i \times o_i(x)) = V(x).q(x)$$</p><ol>
<li><p>Proof:</p>
<ul>
<li><p>\(\pi_1 = g^{\alpha + \sum_{i=1}^m c_i \times l_i (\tau)}\)</p>
</li>
<li><p>\(\pi_2 = g^{\beta + \sum_{i=1}^m c_i \times r_i (\tau)}\)</p>
</li>
<li><p>\(\pi_3 = \prod _{i=1}^m (g ^ {\sum c_i  \times \beta(l_i(\tau) + r_i(\tau) + o_i(\tau)) + V(\tau)q(\tau)})\)</p>
</li>
</ul>
</li>
<li><p>Verify:</p>
<ul>
<li>\(e(\pi_1, \pi_2) = e(\pi_3, g).e(g^\alpha, g^\beta)\)</li>
</ul>
</li>
</ol>
<blockquote>
<p>To make the above systems Zero Knowlege, a randomizer is simply added to the proofs generated.</p>
<p>\(\pi _1 = g^{\sum_{i=1}^m c_i \times l_i(\tau) + \delta_1V(\tau)} \) and similarly for \(\pi_2\) and \(\pi_3\)</p>
</blockquote>
<hr />
<h3 id="heading-properties-of-groth16">Properties of Groth16</h3>
<ol>
<li><p><strong>Computation Cost</strong>: The cost to generate a proof in Groth16 is relatively high compared to the verification cost. This is because the prover must perform a series of complex mathematical operations, which include polynomial evaluations and multi-exponentiations in elliptic curve groups.</p>
</li>
<li><p><strong>Input Length Dependence</strong>: The proving time is dependent on the length of the witness (the information that proves the statement). For more complex statements or larger datasets, the time required to generate a proof increases.</p>
</li>
<li><p><strong>Memory Usage</strong>: Groth16 proving can be memory-intensive. The prover needs to handle large polynomials and multiple group elements, which requires substantial computational resources, especially for complex statements.</p>
</li>
<li><p><strong>Parallelizability</strong>: The proving process in Groth16 can be parallelized to some extent. This means that with sufficient computational resources, the time taken to generate a proof can be reduced.</p>
</li>
<li><p><strong>Efficient Verification</strong>: Groth16 stands out for its extremely efficient verification process. Verifying a proof typically involves a few pairings and elliptic curve operations, which are computationally cheaper than the operations required for proof generation.</p>
</li>
<li><p><strong>Constant Time Verification</strong>: Regardless of the complexity of the original computation, the verification time remains constant. This is a significant advantage, especially in systems where quick verification is essential, like in blockchain transactions.</p>
</li>
<li><p><strong>Low Resource Requirement</strong>: The verifier does not need extensive computational resources. This asymmetry between proving and verification complexity makes Groth16 particularly suitable for systems where the verifier's resources are limited, such as in smart contracts on a blockchain.</p>
</li>
<li><p><strong>Asymmetry Advantage</strong>: The asymmetry in computational requirements between the prover and verifier in Groth16 is by design. While it demands more from the prover, it benefits systems where verification needs to be quick and inexpensive, a common scenario in decentralized systems like blockchains.</p>
</li>
<li><p><strong>Scalability Impact</strong>: This asymmetry affects scalability. The efficiency in verification means that more transactions (or other verifiable computations) can be processed in a shorter time, which is crucial for the scalability of blockchains.</p>
</li>
<li><p><strong>Security and Trust</strong>: The proving complexity also contributes to the security of the system, as it makes it computationally prohibitive to generate false proofs.</p>
</li>
<li><p>In Groth16 variants:</p>
<ol>
<li><p>Proof size: 3 group elements - 144 bytes</p>
</li>
<li><p>Verifier time: 1 pairing equation</p>
</li>
</ol>
</li>
</ol>
<hr />
<p>Follow me on social media: <a target="_blank" href="https://twitter.com/privacy_prophet">Twitter</a>, and <a target="_blank" href="https://www.linkedin.com/in/rachit-anand-srivastava/">LinkedIn</a> for new updates in the cryptography space and any discussion related to computer science.</p>
]]></content:encoded></item><item><title><![CDATA[Circuit Satisfiability to Quadratic Arithmetic Program]]></title><description><![CDATA[In this article, we will explore how the following topics:

R1CS

Transcript

Selector Polynomial

Vanishing Polynomial

Quadratic Arithmetic Program



R1CS
The term "R1CS" stands for "Rank-1 Constraint System." It's a method used in computer scienc...]]></description><link>https://blog.privacyprophet.xyz/circuit-satisfiability-to-quadratic-arithmetic-program</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/circuit-satisfiability-to-quadratic-arithmetic-program</guid><category><![CDATA[quadtratic arithmetic]]></category><category><![CDATA[r1cs]]></category><category><![CDATA[zero-knowledge-proofs]]></category><category><![CDATA[Blockchain]]></category><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Thu, 04 Jan 2024 10:30:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704174695792/8e7a561b-ed3d-4d8b-8c88-16c793019494.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, we will explore how the following topics:</p>
<ul>
<li><p>R1CS</p>
</li>
<li><p>Transcript</p>
</li>
<li><p>Selector Polynomial</p>
</li>
<li><p>Vanishing Polynomial</p>
</li>
<li><p>Quadratic Arithmetic Program</p>
</li>
</ul>
<hr />
<h3 id="heading-r1cs">R1CS</h3>
<p>The term "R1CS" stands for "Rank-1 Constraint System." It's a method used in computer science, particularly in the field of cryptography and zero-knowledge proofs. The Rank-1 Constraint System is a way to express a set of arithmetic constraints. It's commonly used in the construction of zero-knowledge proofs, particularly in systems like zk-SNARKs (Zero-Knowledge Succinct Non-Interactive Argument of Knowledge).</p>
<p>An R1CS typically consists of three matrices: A, B, and C. Each row in these matrices represents a single constraint, and the system is satisfied if there exists a vector of variables \(\vec{x}\) such that for every row \( \vec{i}\), the following equation holds:</p>
<p>$$\vec{a}_i \cdot \vec{x} \times \vec{b}_i \cdot \vec{x} = \vec{c}_i \cdot \vec{x}$$</p><h3 id="heading-transcript">Transcript</h3>
<p>Trace just means Prover is just going to evaluate this entire circuit and take the values on all the wires. In Interactive proofs, the value of every gate is traced, in Plonk, the trace is defined as the left input, right input, and output of every gate.</p>
<p>QAP: input + output of every <strong>multiplication gate.</strong></p>
<p>e.g.:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704175742715/75437c93-13e0-4b25-8e79-9d2572d53df7.png" alt class="image--center mx-auto" /></p>
<p>( image credits to Yupeng Zhang )</p>
<h3 id="heading-selector-polynomial">Selector Polynomial</h3>
<p>Let's assume a polynomial \(l_i(x)\) which means: is \(c_i\) the left input of gate j ?, for j = 1,2,3, where \(c_i\) is the value in the i'th position in the transcript ( as in the above image ).</p>
<p>e.g.</p>
<ol>
<li><p>\(l_1(x) : (1,0,0)\).<br /> How? Is \(c_1\) left input of gate 1 ? Yes. Is \(c_1\) left input of gate 2: No. And finally is \(c_1\) left input of gate 3: No. The polynomial interpolation at a known set \(\Omega\) : \(l_1(w) = 1, l_1(w^2) = 0, l_1(w^3) = 0\).</p>
</li>
<li><p>\(l_x(x) : (0, 0 ,1)\)</p>
<p> Polynomial interpolation: \(l_3(w) = 0, l_3(w^2) = 0, l_w(w^3) = 0\) since value 1 is the input of the addition gate which in turn is the left input of the multiplication gate ( remember we are taking trace over multiplication gate in case of QAP )</p>
</li>
</ol>
<p><strong>Properties</strong>:</p>
<ul>
<li><p>\(L(x) = \sum_{i=1}^9 c_i * l_i(x)\). If you write the trace for the entire transcript in the above example: \(L(w) = c_1 = 3\), \(L(w^3) = c_3 + c_4\). The values are the 1s that are present at the respective input column in the entire transpose.</p>
</li>
<li><p>Similarly, we calculate \(r(x)\) and create a transcript then using that a selector polynomial \(R(x)\).</p>
</li>
<li><p>Similarly, we have \(O(x)\) which represents the gate outputs.</p>
</li>
</ul>
<p>Now we have:</p>
<p>$$p(x) = L(x)R(x) - O(x)$$</p><ul>
<li>Claim is \(p(w^j) = 0 , for \ j = 1,2,3..\)</li>
</ul>
<h3 id="heading-vanishing-polynomial">Vanishing Polynomial</h3>
<ul>
<li>We define \(p(x) = V(x)q(x)\) , where \(V(x) = (x - w )(x-w^2)(x-w^3)\) is the vanishing polynomial of the set \(\Omega = \{ w, w^2, w^3 \}\)</li>
</ul>
<hr />
<p>Finally:</p>
<p>P claims to know a w such that \(C(x,w) = y\) \(&lt;==&gt;\)P claims to know that a vector c such that \(p(x) = V(x)q(x)\).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704177568238/adcb6845-3242-4456-a19c-811f595338a6.png" alt class="image--center mx-auto" /></p>
<p>Where the table is a piece of public information, and generated during preprocessing phase.</p>
<p>Now, instead of checking the constraints in the R1CS individually, we can now check <em>all of the constraints at the same time</em> by doing the dot product check <em>on the polynomials</em>.</p>
<hr />
<p>Lastly, follow me on social media: <a target="_blank" href="https://twitter.com/privacy_prophet">Twitter</a>, and <a target="_blank" href="https://www.linkedin.com/in/rachit-anand-srivastava/">LinkedIn</a> for new updates in the cryptography space.</p>
<hr />
<p>References:</p>
<ul>
<li><p><a target="_blank" href="https://risencrypto.github.io/R1CSQAP/#:~:text=The%20next%20step%20is%20taking,vector%20%26%20the%20number%20of%20gates">https://risencrypto.github.io/R1CSQAP/#:~:text=The%20next%20step%20is%20taking,vector%20%26%20the%20number%20of%20gates</a>.</p>
</li>
<li><p><a target="_blank" href="https://medium.com/@VitalikButerin/quadratic-arithmetic-programs-from-zero-to-hero-f6d558cea649">https://medium.com/@VitalikButerin/quadratic-arithmetic-programs-from-zero-to-hero-f6d558cea649</a></p>
</li>
<li><p>SNARK lecture on linear PCP by Yupeng Zhang <a target="_blank" href="https://www.youtube.com/watch?v=I7TXIHXamwM&amp;list=PLS01nW3Rtgor_yJmQsGBZAg5XM4TSGpPs&amp;index=9&amp;ab_channel=Blockchain-Web3MOOCs">Link</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[FRI Polynomial Commitment Scheme]]></title><description><![CDATA[The FRI (Fast Reed-Solomon Interactive Oracle) commitment scheme is a cryptographic protocol that plays a crucial role in various zero-knowledge proof systems. It's designed to efficiently prove the correctness of computations without revealing any u...]]></description><link>https://blog.privacyprophet.xyz/fri-polynomial-commitment-scheme</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/fri-polynomial-commitment-scheme</guid><category><![CDATA[snarks]]></category><category><![CDATA[zero-knowledge-proofs]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[Cryptography]]></category><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Tue, 02 Jan 2024 10:30:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704043643535/cd86fe3e-2fcb-4c60-8bb6-a6bc57a579e9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The FRI (Fast Reed-Solomon Interactive Oracle) commitment scheme is a cryptographic protocol that plays a crucial role in various zero-knowledge proof systems. It's designed to efficiently prove the correctness of computations without revealing any underlying data. The FRI scheme is particularly important in the context of zk-STARKs (Zero-Knowledge Scalable Transparent Arguments of Knowledge), which are a type of non-interactive cryptographic proof that's scalable and doesn't require a trusted setup.</p>
<h3 id="heading-problem-addressed-using-fri">Problem addressed using FRI:</h3>
<ol>
<li><p><strong>Want P time linear in degree, not field size</strong>:</p>
<ul>
<li><p>Let's say we use a Merkle tree for commitment to values in a field f. But this is very inefficient since if field f is big, then the number of leaves, and consequently the proof length grows significantly. In FRI, rather than P merkle-commiting to all (p-1) evaluations of q, P merkle-commits to evaluations of q(x) for \(x \in \Omega\) of \(F_p\).</p>
</li>
<li><p>\(\Omega\) has size \(\rho ^ {-1} k\) where \(\rho &lt; 1/2\) constant and k is the degree of q.</p>
</li>
<li><p>Proof length will be about \(\lambda / log(\rho ^ {-1}). log^2(k)\) hash values where \(\lambda\) is the security parameter, aka. " \(\lambda\) bits of security ".</p>
</li>
<li><p>Let \(\omega \in F_p\), n is the smallest integer such that \(\omega ^ n = 1\), then \(\Omega = \{ 1, \omega, \omega ^2, \ldots, \omega ^ {n-1} \}\)</p>
</li>
<li><p>From group theory, \(\Omega\) has size n if and only if n divides p-1.</p>
<ul>
<li>Hence, FRI based SNARKs work over fields like \(F_p\) with \(p = 2^{64}   - 2^{32} + 1\) , p-1 is divisible by \(2^{32}\). Running FRI over the field can support any power of 2 value of n up to \(2^{32}\).</li>
</ul>
</li>
<li><p>For eg. FRI commitment to univariate polynomial \(q(x)\) in \(F_{41}[X]\) when \(8 = \rho^{-1}.k\), where roots of unity = \(\{ 1, -1, 9, -9, 3, -3, 14, -14 \}\) becomes the root of the committed merkle tree.</p>
</li>
</ul>
</li>
</ol>
<blockquote>
<p>To visualize roots of unity try this tool -&gt; <a target="_blank" href="https://www.geogebra.org/m/sZFwAZfs">https://www.geogebra.org/m/sZFwAZfs</a></p>
</blockquote>
<ol>
<li><p><strong>V needs to know the committed vector at all evaluations over domain \(\Omega\) of some (k-1) degree polynomial.</strong></p>
<ul>
<li><p>V "inspects" a few entries of the vector to "get a sense" of whether its low-degree. This will add a Merkle authentication path ( log(n) hash values ) to the proof.</p>
</li>
<li><p>This is impractical. FRI's test will be interactive. We use a "folding phase" followed by a "query phase". The folding phase is log(k) rounds. The query phase is one round.</p>
</li>
</ul>
</li>
</ol>
<hr />
<h3 id="heading-folding-phase-interactive">Folding Phase ( Interactive )</h3>
<h4 id="heading-step-1-starting-with-a-high-degree-polynomial"><strong>Step 1: Starting with a High-Degree Polynomial</strong></h4>
<ul>
<li>The process begins with the prover having a high-degree polynomial. This polynomial is a representation of the computation or data they intend to prove something about.</li>
</ul>
<h4 id="heading-step-2-interpolation-and-evaluation"><strong>Step 2: Interpolation and Evaluation</strong></h4>
<ul>
<li>The polynomial is evaluated at various points. These points typically lie in a domain related to a specific subgroup of a finite field.</li>
</ul>
<h4 id="heading-step-3-the-folding-process"><strong>Step 3: The Folding Process</strong></h4>
<ul>
<li><p>The prover reduces the degree of the polynomial. They select a subset of the evaluation points and merge the values of the polynomial at these points using a linear or affine transformation.</p>
</li>
<li><p>V picks up a random field element r, and r is used to "randomly combine" every two paired-up entries.</p>
</li>
<li><p>q(x) is split into "even and odd components" -&gt; \(q(x) = q_e(X^2) + Xq_o(X^2)\)</p>
</li>
<li><p>The prescribed "folding" q is \(q_{fold}(Z) = q_e(Z) + rq_o(Z)\) where degree of \(q_{fold}\) is half of the degree of q.</p>
</li>
</ul>
<h4 id="heading-step-4-recursive-application"><strong>Step 4: Recursive Application</strong></h4>
<ul>
<li><p><strong>What Happens</strong>: After folding, the polynomial's degree is lowered. The prover then commits to this new, reduced-degree polynomial. Folding is repeated until the degree falls to 0.</p>
</li>
<li><p><strong>Why It Matters</strong>: This recursive process is essential for gradually simplifying the polynomial.</p>
</li>
</ul>
<p><strong>Step 5: End</strong></p>
<ul>
<li>The length of the folded vector after the degree has fallen to 0 is still \(\rho ^ {-1} &gt;= 2\). Since the degree should be 0, P can specify the folder vector with a single field element.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704046170064/d04decfe-23c9-4354-8056-73d631ca8f88.png" alt class="image--center mx-auto" /></p>
<p>( image credit: Justin Thaler lecture ( link in references ).</p>
<blockquote>
<ul>
<li><p>The calculation in the picture uses the fact that if x and -x are n'th roots of unity and z = \(x^2\). Then \(q_{fold}(z) = \frac{(r+x)}{2x} .q(x) + \frac{(r-x)}{-2x} .q(-x) \) ( derivation not covered in this post ).</p>
</li>
<li><p>FRI heavily uses the fact that the map \(x -&gt; x^2\) is 2 to 1 on \(\Omega\), ensuring that the relevant domain halves in size with each fold.</p>
</li>
</ul>
</blockquote>
<hr />
<h3 id="heading-query-phase-interactive">Query Phase ( Interactive )</h3>
<ul>
<li><p>P may have "lied":</p>
<ul>
<li><p>sending a vector that is not the prescribed folding of the previous vector</p>
</li>
<li><p>To "artificially" reduce the degree of the claimed folded vector.</p>
</li>
</ul>
</li>
<li><p>The Query phase is where the verifier tries to detect inconsistencies.</p>
</li>
<li><p>V picks about \(\lambda / log ( \rho ^ {-1}) \) entries of each folded vector and confirming each is the prescribed linear combination of the relevant two entries of the previous vector.</p>
</li>
<li><p>Proof length ( and V time ): roughly \((\lambda / log(\rho ^ {-1})_. log(k)^2\) hash evaluations. Each of the folded vectors ( log(k) ) is queried at \(\lambda / log ( \rho ^ {-1})\)</p>
</li>
</ul>
<hr />
<blockquote>
<ul>
<li><p>For security analysis, refer the links in references. This article focuses on the working only.</p>
</li>
<li><p>There is a known attack where prover folders a polynomial s rather than q, where s agrees on a set T = \(\rho n\) elements of \(\Omega\).</p>
</li>
</ul>
</blockquote>
<hr />
<h3 id="heading-polynomial-commitment-using-fri">Polynomial Commitment using FRI</h3>
<ul>
<li><p>Problems with FRI</p>
<ul>
<li><p>P has only the Merkle-committed to evaluations of q over domain \(\Omega\), not the whole field.</p>
</li>
<li><p>V only knows that q is "not too far" from low-degree, not exactly low-degree.</p>
</li>
</ul>
</li>
<li><p>Solution</p>
<ul>
<li><p>We know \(q(X) - v = w(X)(X-r)\) is equivalent to \(q(r) = v\) ( refer <a target="_blank" href="https://hashnode.com/edit/clqrsz77o000308js2rtx6hv9">here</a>). w is a polynomial of degree at most d.</p>
</li>
<li><p>So to confirm \(q(r) = v\) V applies FRI's fold + query procedure to the functions \((q(X) - v)(X-r)^{-1}\) using degree bound d-1. Whenever the FRI verifier queries this function at \(\Omega\), evaluation can be obtained with one query to q at the same point.</p>
</li>
<li><p>V doesn't know that q is exactly a low degree, but to pass V's check, \(v\) has to equal \(h(r)\) where h is the degree d polynomial that is closest to q.</p>
</li>
</ul>
</li>
</ul>
<blockquote>
<p>Each FRI verifies query brings &lt;1 bit of security to the commitment scheme. FRI today is used as a weaker primitive tha a polynomial commitment ( list polynomial commitment scheme ), which suffices for SNARK security. P is bound to a "small set" of low-degree polynomials rather than to a single one.</p>
</blockquote>
<hr />
<p><strong>Conclusion:</strong> The FRI commitment scheme represents a significant advancement in the field of cryptographic proofs, enabling more secure and efficient verification of computations in various applications, including blockchain technology and privacy-preserving computations.</p>
<p>Lastly, follow me on social media: <a target="_blank" href="https://twitter.com/privacy_prophet">Twitter</a>, and <a target="_blank" href="https://www.linkedin.com/in/rachit-anand-srivastava/">LinkedIn</a> for new updates in the cryptography space.</p>
<hr />
<p><strong>References</strong>:</p>
<ol>
<li><p><a target="_blank" href="https://blog.lambdaclass.com/how-to-code-fri-from-scratch/">https://blog.lambdaclass.com/how-to-code-fri-from-scratch/</a></p>
</li>
<li><p>Lecture by Justin Thaler <a target="_blank" href="https://www.youtube.com/watch?v=A3edAQDPnDY&amp;list=PLS01nW3Rtgor_yJmQsGBZAg5XM4TSGpPs&amp;index=8&amp;ab_channel=Blockchain-Web3MOOCs">Link</a></p>
</li>
<li><p><a target="_blank" href="https://chat.openai.com/">https://chat.openai.com/</a></p>
</li>
<li><p><a target="_blank" href="https://eprint.iacr.org/2019/1020.pdf">https://eprint.iacr.org/2019/1020.pdf</a></p>
</li>
<li><p><a target="_blank" href="https://aszepieniec.github.io/stark-anatomy/fri.html">https://aszepieniec.github.io/stark-anatomy/fri.html</a></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Bulletproof Commitment Schemes: Integrating Cryptography and Mathematics]]></title><description><![CDATA[Introduction
The integration of mathematics in cryptography has led to innovative solutions like bulletproof commitment schemes, which are essential in enhancing digital security and privacy. Bulletproofs are a form of non-interactive zero-knowledge ...]]></description><link>https://blog.privacyprophet.xyz/bulletproof-commitment-schemes-integrating-cryptography-and-mathematics</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/bulletproof-commitment-schemes-integrating-cryptography-and-mathematics</guid><category><![CDATA[bulletproof]]></category><category><![CDATA[zero-knowledge-proofs]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[zk-snark]]></category><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Sun, 31 Dec 2023 09:30:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1703934438908/02afdb7c-9b95-42cb-af76-d9a67af52634.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4 id="heading-introduction">Introduction</h4>
<p>The integration of mathematics in cryptography has led to innovative solutions like bulletproof commitment schemes, which are essential in enhancing digital security and privacy. Bulletproofs are a form of non-interactive zero-knowledge proof system, that relies heavily on mathematical concepts to provide efficient and secure commitment schemes. In this post, we delve into the mathematical underpinnings of bulletproofs and how they revolutionize commitment schemes.</p>
<h4 id="heading-what-is-a-bulletproof-commitment-scheme">What is a Bulletproof Commitment Scheme?</h4>
<p>A bulletproof commitment scheme is a cryptographic protocol that allows a party to commit to a value, maintaining its confidentiality, and ensuring the integrity of the commitment. These schemes are known for their efficiency, non-reliance on a trusted setup, and their ability to produce short proofs.</p>
<h4 id="heading-mathematical-foundations-of-bulletproofs">Mathematical Foundations of Bulletproofs</h4>
<ol>
<li><p><strong>Pedersen Commitments</strong>: The core of bulletproofs lies in Pedersen commitments, a cryptographic algorithm based on discrete logarithm problems. A Pedersen commitment to a value <code>v</code> is of the form <code>C = vG + rH</code>, where <code>G</code> and <code>H</code> are known generator points on an elliptic curve, and <code>r</code> is a secret blinding factor.</p>
</li>
<li><p><strong>Range Proofs</strong>: Bulletproofs provide a way to prove that a committed number lies within a certain range without revealing the number itself. This is done through complex polynomial commitments and inner product arguments, leveraging mathematical constructs like Hadamard products and vector operations.</p>
</li>
<li><p><strong>Inner Product Argument</strong>: At the heart of a bulletproof range proof is an efficient protocol for proving the inner product between two vectors, which allows the verifier to check that the commitment represents a number in the desired range without learning anything more about the number.</p>
</li>
</ol>
<h4 id="heading-how-bulletproof-commitment-schemes-work">How Bulletproof Commitment Schemes Work</h4>
<p><strong>Transparent Setup:</strong></p>
<ul>
<li><p>Sample random \(gp = (g_0, g_1, g_2, \ldots, g_d) \) in G.</p>
</li>
<li><p>Commit: \(f(x) = f_0 + f_1x + f_2x^2 + \ldots | f_dx^d\)<br />  \(com_f = g_0^{f_0} + g_1^{f_1} + \ldots + g_d^{f_d}\)</p>
</li>
</ul>
<p><strong>Steps in working of Poly-commitment based on BulletProofs:</strong></p>
<ol>
<li><p><strong>Evaluate</strong></p>
<ul>
<li><p>\(v = f_0 + f_1u + f_2u^2 + f_3u^3\) and send to the verifier.</p>
</li>
<li><p>Compute \(L, R, v_L, v_R\)</p>
<p>  where \(L = g_2^{f_0}.g_3^{f_1}\), \(R = g_0^{f_2}.g_1^{f_3}\) , \(v_L = f_0 + f_1u\), \(v_r = f_2 + f_3u\) and sent to verifier.</p>
</li>
<li><p>Receive \(r\) from the verifier, reduce \(f\) to \(f^{'}\) of degree \(d/2\) where new polynomials change from \(f_0, f_1, f_2, f_3\) to \(rf_0 + f2, rf_1 + f_3\)</p>
</li>
<li><p>Update the bases \(gp'\)</p>
</li>
</ul>
</li>
<li><p><strong>Verify</strong></p>
<ul>
<li><p>Check \(v = v_L + v_R.u^{d/2}\)</p>
</li>
<li><p>Generate \(r\) randomly</p>
</li>
<li><p>Update:</p>
<ul>
<li><p>\(com^{'} = L^r.com_f.R^{r^{-1}}\)</p>
</li>
<li><p>\(gp^{'}= (g_0^{r^{-1}}.g_2, g_1^{r^{-1}}.g_3)\)</p>
</li>
<li><p>\(v^{'} =r.v_L + v_R\)</p>
</li>
</ul>
</li>
</ul>
</li>
</ol>
<p>Recurse log d times.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703934099569/37f8eba8-d505-4cc4-b4fd-0641d19a5752.png" alt="Poly-commitment based on Bulletproofs" class="image--center mx-auto" /></p>
<p><em>(image credit: Yupeng Zhang lecture on ZKP MOOC)</em></p>
<h4 id="heading-applications-and-importance">Applications and Importance</h4>
<ul>
<li><p><strong>Blockchain and Cryptocurrency</strong>: In blockchain, bulletproofs enable confidential transactions by allowing the amounts to be hidden yet verifiable.</p>
</li>
<li><p><strong>Voting Systems</strong>: Secure voting mechanisms can utilize bulletproofs to count votes accurately while maintaining voter anonymity.</p>
</li>
<li><p><strong>Privacy-Enhancing Technologies</strong>: They are crucial in constructing zero-knowledge proofs, pivotal for privacy in various digital applications.</p>
</li>
</ul>
<h4 id="heading-conclusion">Conclusion</h4>
<p>The mathematical complexity and cryptographic robustness of bulletproof commitment schemes mark a significant advancement in secure digital communications. By blending advanced mathematics with cryptographic techniques, bulletproofs offer a powerful tool for ensuring privacy and integrity in various digital applications, especially in the rapidly evolving field of blockchain technology. Understanding these schemes not only provides insight into modern cryptographic practices but also underscores the importance of mathematical principles in developing secure digital systems.</p>
<p>Lastly, follow me on social media: <a target="_blank" href="https://twitter.com/privacy_prophet">Twitter</a>, and <a target="_blank" href="https://www.linkedin.com/in/rachit-anand-srivastava/">LinkedIn</a> for new updates in the cryptography space.</p>
]]></content:encoded></item><item><title><![CDATA[Demystifying KZG Poly-commit Scheme]]></title><description><![CDATA[A KZG polynomial commitment scheme allows a prover to commit to a polynomial so that they can later reveal and prove properties about the polynomial (like its value at certain points) without revealing the entire polynomial. This is particularly usef...]]></description><link>https://blog.privacyprophet.xyz/demystifying-kzg-poly-commit-scheme</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/demystifying-kzg-poly-commit-scheme</guid><category><![CDATA[zero-knowledge-proofs]]></category><category><![CDATA[commitment]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[privacy]]></category><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Sat, 30 Dec 2023 08:30:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1703919453646/e91190d2-eb2b-4bb6-b33b-a732b2639bbf.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<p>A KZG polynomial commitment scheme allows a prover to commit to a polynomial so that they can later reveal and prove properties about the polynomial (like its value at certain points) without revealing the entire polynomial. This is particularly useful in scenarios where the polynomial represents some private data or computation.</p>
<p>Prequistics:</p>
<ul>
<li><p>How <a target="_blank" href="https://www.di.ens.fr/~fouque/CoursBCS3.pdf">cyclic groups</a> work in Numbers Theory</p>
</li>
<li><p>Discrete Log + <a target="_blank" href="https://www.nku.edu/~christensen/092mat483%20DH%20key%20exchange.pdf">Diffie-Hellman</a></p>
</li>
<li><p>Understanding of <a target="_blank" href="https://twitter.com/RacSri25/status/1738503612094148718">Bilinear Pairing</a></p>
</li>
</ul>
<hr />
<h3 id="heading-kzg-poly-commit-scheme"><strong>KZG Poly-commit scheme</strong></h3>
<p>Before we start, let’s see the elements we have:</p>
<ul>
<li><p>Bilinear Group p, G, g, Gₜ, e.</p>
</li>
<li><p>Univariate polynomials: \(F = F_p^{&lt;=d}[X]\)</p>
</li>
</ul>
<p><strong>Step 1: Keygen</strong></p>
<ul>
<li><p>Sample random τ∈Fp</p>
</li>
<li><p>\(gp = (g, g^{\tau}, g^{\tau^2}, \ldots, g^{\tau^d})\)</p>
</li>
<li><p>delete \(\tau\) ( trusted setup )</p>
</li>
</ul>
<p><strong>Step 2: Commit</strong></p>
<ul>
<li><p>commit (gp, f) -&gt; \(com_f\)</p>
</li>
<li><p>\(f(x) = f_0 + f_1x + f_2x ^2 + \ldots + f_dx^d\)</p>
</li>
<li><p>\(com_f = g^{f(\tau)}\)<br />  \(= g ^ {f_0 + f_1\tau + f_2\tau^2+ \ldots + f_d^{\tau ^ d}}\)</p>
<p>  \(= (g)^{f_0}. (g^\tau)^{f_1}. (g^{\tau^2})^{f_2}. \ldots (g^{\tau^d})^{f_d}\)</p>
</li>
</ul>
<p><strong>Step 3: Proof</strong></p>
<ul>
<li><p>\(eval(gp, f, u)  -&gt; v, \pi\): where \(u\) is a random point the verifier chooses.</p>
<ul>
<li><p>\(f(x) - f(u) = (x - u)q(x)\) as u is a root of \(f(x) - f(u)\)</p>
</li>
<li><p>Compute \(q(x) \) and \(\pi = g^{q(\tau)}\) computed using gp elements.</p>
</li>
</ul>
</li>
</ul>
<p><strong>Step 4: Verify</strong></p>
<ul>
<li><p>\(verify(gp, com_f, u, v, \pi )\):</p>
<ul>
<li><p>where \(v = f(u)\)</p>
</li>
<li><p>The idea is to check the equation at point \(\tau\): \(g ^ {f(\tau) - f(u)} = g ^ {(\tau - u)q(\tau)}\)</p>
</li>
<li><p>Challenge: only know \(g ^ {\tau - u}\) and \(g ^ {q(\tau)}\)</p>
</li>
<li><p>Solution: pairings - \(e(com_f / g^v, g) = e(g^{\tau - u}, \pi)\)<br />  \(=e(g,g)^{f(\tau) - f(u)} = e(g,g)^{({\tau - u}). q(\tau)}\)</p>
</li>
</ul>
</li>
</ul>
<hr />
<p>The key features of KZG polynomial commitments include:</p>
<ol>
<li><p><strong>Commitment</strong>: The prover commits to a polynomial by computing a commitment, a concise representation of the polynomial. This commitment is computed using a bilinear pairing over elliptic curves, which forms the cryptographic backbone of the scheme.</p>
</li>
<li><p><strong>Evaluation Proofs</strong>: The prover can provide proofs that a committed polynomial evaluates to a certain value at a specific point. These proofs are small in size and can be verified quickly.</p>
</li>
<li><p><strong>Hiding Property</strong>: The commitment does not reveal the polynomial itself, preserving the privacy of the data.</p>
</li>
<li><p><strong>Efficiency</strong>: KZG commitments are highly efficient in terms of both computation and communication overhead, making them suitable for use in blockchain networks where resources are limited.</p>
</li>
<li><p><strong>Applications</strong>: They are widely used in the construction of zk-SNARKs (zero-knowledge Succinct Non-interactive ARguments of Knowledge) and other zero-knowledge proof systems. In blockchain, they enable scalable and private transactions.</p>
</li>
</ol>
<hr />
<h3 id="heading-achieving-zero-knowledge">Achieving Zero-Knowledge</h3>
<p>The plain KZG is not ZK. Eg. \(com_f = g ^{f(\tau)}\) is deterministic.</p>
<p>To achieve Zero Knowledge, we mask the commitment with randomizers.</p>
<ul>
<li><p>Commit: \(com_f = g^{f(\tau) + r\eta}\)</p>
</li>
<li><p>Evaluate: ( where \(r\) and \(r^{'}\) are both randomizers )</p>
<p>  $$f(x) + ry - f(u) = (x - u)(q(x) + r^{'}y) + y(r - r^{'}(x - u))$$</p>
</li>
</ul>
<p>$$\pi = g ^ {q(\tau) + r^{'}\eta} , g^{r-r^{'} (\tau - u)}$$</p><hr />
<p><strong>Other Variants Of KZG</strong></p>
<ol>
<li><p><strong>Batch opening: Single Polynomial:</strong></p>
<ul>
<li><p>Prover wants to prove \(f\) at \(u_1,\ldots, u_m \) for m&lt;d.</p>
<p>  * Steps:</p>
<p>  * Extrapolate \(f(u_1),\ldots,f(u_m)\) to get \(h(x)\)</p>
<p>  * \(f(x) - h(x) = \prod_{i=1}^m(x-u_i)q(x)\). Why? Check the roots of polynomials on LHS.</p>
<p>  * \(\pi = g ^ {q(\tau)}\)</p>
<p>  * \(e ( com_f / g^ {h(\tau)}, g) = e(g^{\prod_{i=1}^m(\tau - u_i)}, \pi)\) where \(g^{h(r)}\) verifier can calculate using the global params.</p>
</li>
</ul>
</li>
<li><p><strong>Batch opening: Multiple Polynomials</strong></p>
<ul>
<li><p>Prover wants to prove \(f_i(u_{i,j}) = v_{i,j}\)</p>
</li>
<li><p>Steps:</p>
<ul>
<li><p>Extrapolate \(f_i(u_1),\ldots,f(u_m)\) to get \(h_i(x)\) for \(i \in [n]\)</p>
</li>
<li><p>\(f_i(x) - h_i(x) = \prod_{i=1}^m(x - u_m)q_i(m)\)</p>
</li>
<li><p>Combine all \(q_i(x)\) via a random linear combination.</p>
</li>
</ul>
</li>
</ul>
</li>
</ol>
<hr />
<p>And that's it !!!</p>
<p>Lastly, follow me on social media: <a target="_blank" href="https://twitter.com/privacy_prophet">Twitter</a>, and <a target="_blank" href="https://www.linkedin.com/in/rachit-anand-srivastava/">LinkedIn</a> for new updates in the cryptography space.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Interactive Proof Systems and Sum Check Protocol: Part 2]]></title><description><![CDATA[In Part 1, we covered the math, and the logic behind Sum-Check Protocol. In this part, we will be hacking up a quick Sum-Check protocol source code for demonstration.

Prerequisites:

Familiarity with GoLang.

Understanding of Interactive Proofs.

Un...]]></description><link>https://blog.privacyprophet.xyz/understanding-interactive-proof-systems-and-sum-check-protocol-part-2-a2eef4a1e061</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/understanding-interactive-proof-systems-and-sum-check-protocol-part-2-a2eef4a1e061</guid><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Fri, 29 Dec 2023 09:20:09 GMT</pubDate><content:encoded><![CDATA[<p>In <a target="_blank" href="https://rac-sri.medium.com/understanding-interactive-proof-systems-and-sum-check-protocol-part-1-6afd9edc67ec">Part 1</a>, we covered the math, and the logic behind Sum-Check Protocol. In this part, we will be hacking up a quick Sum-Check protocol source code for demonstration.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898948897/ef303986-4acb-4b18-958c-24dbd3449bfa.jpeg" alt /></p>
<p>Prerequisites:</p>
<ul>
<li><p>Familiarity with <a target="_blank" href="https://go.dev/">GoLang</a>.</p>
</li>
<li><p>Understanding of Interactive Proofs.</p>
</li>
<li><p>Understanding of the maths behind Sum-Check Protocol (covered <a target="_blank" href="https://rac-sri.medium.com/understanding-interactive-proof-systems-and-sum-check-protocol-part-1-6afd9edc67ec">here</a>)</p>
</li>
</ul>
<p>First, let's write some utils functions inside a file named <strong>utils.go</strong></p>
<h4 id="heading-utilsgo">utils.go:</h4>
<p>First, we write a helper function that returns the number of arguments taken by a function.</p>
<pre><code class="lang-plaintext">type FuncType func(...int) int

func Arity(f interface{}) int {
// Get the type of f, which should be a function.
fType := reflect.TypeOf(f)
if fType.Kind() != reflect.Func {
// Optionally, handle the case where f is not a function.
    return -1
}
// Return the number of input arguments.
return fType.NumIn()
}
</code></pre>
<p>Then we write a helper function, which takes an input n, and returns its binary vector, front-padded to pad length ( taken as input again ).</p>
<pre><code class="lang-plaintext">func ToBits(n int, padToLen int) []int {
binStr := strconv.FormatInt(int64(n), 2)

if len(binStr) &gt; padToLen {
    padToLen = len(binStr)
}

v := make([]int, len(binStr))
for i, ch := range binStr {
    if ch == '1' {
        v[i] = 1
    } else {
    v[i] = 0
    }
}
diff := padToLen - len(v)

paddedV := make([]int, diff)
return append(paddedV, v...)
}
</code></pre>
<ol>
<li>Binary Representation:</li>
</ol>
<ul>
<li>The line <code>binStr := strconv.FormatInt(int64(n), 2)</code> converts the integer <code>n</code> into a binary string representation. For instance, if <code>n</code> is <code>6</code>, <code>binStr</code> will be <code>"110"</code>.</li>
</ul>
<p>2. Creating a Slice of Integers:</p>
<ul>
<li>The subsequent loop creates a slice <code>v</code> of integers where each element corresponds to a digit in the binary string. '1's in the binary string are represented as <code>1</code> in the slice, and '0's as <code>0</code>.</li>
</ul>
<p>3. Padding:</p>
<ul>
<li><p>The function then calculates <code>diff</code>, the difference between the desired length <code>padToLen</code> and the actual length of the binary representation. If the binary representation is shorter than <code>padToLen</code>, it needs to be padded with zeroes.</p>
</li>
<li><p><code>paddedV := make([]int, diff)</code> creates a slice of zeroes of length <code>diff</code>.</p>
</li>
<li><p>Finally, the function returns a new slice that concatenates the padding and the binary representation slice (<code>append(paddedV, v...)</code>).</p>
</li>
</ul>
<p>Lastly: We write a util function that returns the degree of j’th variable in g.</p>
<pre><code class="lang-plaintext">func DegJ(g FuncType, j int) int {
exp := 1
    for {
        args := make([]int, 1)
        for i := range args {
            if i == j {
            args[i] = 100
            } else {
            args[i] = 1
        }
    }

    out1 := g(args[0])

    args[0] = 1000

    out2 := g(args[0])

    // Consider a function f(x) = x²
    // To find the degree of x (assuming it's the second variable, so x = 1), the function would compare f(100) with f(1000).
    // If x is cubed (x³), the output should scale by 1000^ 3 / 100 ^ 3
    // when x changes from 100 to 1000. The function checks if this scaling holds to estimate the degree.
    if math.Abs(float64(out1)/math.Pow(100, float64(exp))-float64(out2)/math.Pow(1000, float64(exp))) &lt; 1 {
        return exp
    } else if exp &gt; 10 {
        panic("exp grew larger than 10")
    } else {
        exp++
    } 
    }
}
</code></pre>
<h4 id="heading-verifiergo">verifier.go:</h4>
<p>This is where all the logic related to the verifier takes place.</p>
<p>Firstly we define the verifier as follows:</p>
<pre><code class="lang-plaintext">type Verifier struct {
    g FuncType
    gArity int // represents the number of inputs to polynomial
    H int // witness
    randomChallenges []int
    round int
    polynomials []FuncType
}
</code></pre>
<p>Now, we need a function that accepts polynomial sent by the prover:</p>
<pre><code class="lang-plaintext">func (v *Verifier) RecievePolynomials(polynomial FuncType) {
    v.polynomials = append(v.polynomials, polynomial)
}
</code></pre>
<p>Now we need a function, that can verify that the latest polynomial is a univariant polynomial of almost deg_j(g) and that the relationship mentioned:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898950115/8a328397-84a3-409e-bc2f-7e097e14dd03.png" alt /></p>
<p>For this, we write another function on the verifier struct:</p>
<pre><code class="lang-plaintext">func (v *Verifier) CheckLatestPolynomial() error {
    latestPoly := v.polynomials[len(v.polynomials)-1]
    degLatest := DegJ(latestPoly, 0)
    degMax := DegJ(v.g, v.round-1)

    if degLatest &gt; degMax {
    return fmt.Errorf("Prover sent polynomial of degree %d greater than expected : %d", degLatest, degMax)
    }

    newSum := latestPoly(0) + latestPoly(1)

    var check int

    if v.round == 1 {
        check = v.H
    } else {
        check = v.polynomials[len(v.polynomials)-2](v.randomChallenges[len(v.randomChallenges)-1])
    }

    if check != newSum {
        return fmt.Errorf("Prover sent incorrect polynomials: %d, expected %d", newSum, check)
    }

    return nil
}
</code></pre>
<p>If you read <a target="_blank" href="https://rac-sri.medium.com/understanding-interactive-proof-systems-and-sum-check-protocol-part-1-6afd9edc67ec">this</a>, you will know that we also need to have a mechanism to generate a random number r and send it as a challenge to the prover. To achieve this:</p>
<pre><code class="lang-plaintext">func (v *Verifier) GetNewRandomValueAndSend(p *Prover) {
    rand.Seed(time.Now().UnixNano())
    v.randomChallenges = append(v.randomChallenges, rand.Intn(2))
    p.ReceiveChallenge(v.randomChallenges[len(v.randomChallenges)-1])
    v.round++
}
</code></pre>
<p>Now, lastly, there is the part where in the final step, the verifier has all the random challenges, and now it uses them to calculate the final value of g. This should match with the final function sₙ(Xn) sent by the prover. If the values match, the verifier accepts.</p>
<pre><code class="lang-plaintext">func (v *Verifier) EvaluateAndCheckGV() (bool, error) {
    if len(v.randomChallenges) != v.gArity-1 {
    return false, fmt.Errorf("Incorrect number of random challenges")
    }

    v.randomChallenges = append(v.randomChallenges, rand.Intn(2))
    gFinal := v.g(v.randomChallenges...)
    check := v.polynomials[len(v.polynomials)-1](v.randomChallenges[len(v.randomChallenges)-1])

    if gFinal != check {
        return false, fmt.Errorf("Prover sent incorrect final polynomials")
    }

    fmt.Println("VERIFIER ACCEPTS")
    return true, nil
}
</code></pre>
<p>And that’s it. We have a basic code ready for a verifier in a Sum-Check Protocol!</p>
<p><strong>prover.go:</strong></p>
<p>This is where all the logic related to the prover goes.</p>
<p>Firstly, we define the prover struct as follows:</p>
<pre><code class="lang-plaintext">type Prover struct {
    gArity int
    randomChallenges []int
    cachedPolynomials []FuncType
    round int
    H int
}
</code></pre>
<p>Now, remember in the Sum-Check protocol, a new polynomial is calculated at each interaction, where several variables = original arguments — round number.</p>
<p>The code iterates from <code>0</code> to <code>2^pad - 1</code>. In each iteration, <code>ToBits</code> is used to create a binary representation of the loop counter <code>i</code>, padded to <code>pad</code> bits. This binary slice is prepended with the first argument (<code>args[0]</code>), and then passed to the polynomial function <code>poly</code> .</p>
<p>This function dynamically generates inputs for the polynomial <code>poly</code>, combining a constant first argument with varying binary patterns, and aggregating the outputs, playing a key role in the sum-check protocol.</p>
<pre><code class="lang-plaintext">func (p *Prover) ComputeAndSendNextPolynomial(v *Verifier) {
    round := p.round
    poly := p.cachedPolynomials[len(p.cachedPolynomials)-1]

    gJ := func(args ...int) int {
    if len(args) == 0 {
        // Handle the case where no arguments are passed
        panic("gJ requires at least one argument")
    }
    pad := p.gArity - round
    var sum int
    for i := 0; i &lt; (1 &lt;&lt; pad); i++ {
        args := append([]int{args[0]}, ToBits(i, pad)...)
        sum += poly(args...)
    }
    return sum
    }

    v.RecievePolynomials(gJ)
    p.round++
}
</code></pre>
<p>The iteration process in the <code>gJ</code> the function is fundamental to the sum-check protocol, and it's designed to systematically evaluate a polynomial over all possible binary combinations of a certain length. Here's why we iterate this way:</p>
<ol>
<li><p>Exhaustive Evaluation: The goal is to evaluate the polynomial <code>poly</code> for every possible combination of binary inputs. This ensures a thorough and complete assessment of the polynomial's behavior across its entire domain.</p>
</li>
<li><p>Binary Combinations: By iterating from 0 to 2^(pad−1) and converting these numbers to binary, we generate all possible combinations of binary digits of length <code>pad</code>. This is a standard way to cover all cases in binary representation.</p>
</li>
<li><p>Reducing Complexity Per Round: In each round of the sum-check protocol, one less variable is considered, reducing the computational complexity step by step. <code>pad</code> decreases with each round, reflecting this reduction.</p>
</li>
</ol>
<p>Lastly, we need a function to receive challenges from the verifier:</p>
<pre><code class="lang-plaintext">func (p *Prover) ReceiveChallenge(challenge int) {
    p.randomChallenges = append(p.randomChallenges, challenge)
    p.CacheNext(challenge)
    fmt.Printf("Received challenge %d, initiating round %d\n", challenge, p.round)
}
</code></pre>
<p>where CacheNext is simply:</p>
<pre><code class="lang-plaintext">func (p *Prover) CacheNext(challenge int) {
    poly := p.cachedPolynomials[len(p.cachedPolynomials)-1]

    nextPoly := func(args ...int) int {
        return poly(append([]int{challenge}, args...)...)
    }

    p.cachedPolynomials = append(p.cachedPolynomials, nextPoly)
}
</code></pre>
<p>Now to run this protocol, we can define a simple <strong>main.go</strong> file with the following code to run the prover and the verifier:</p>
<pre><code class="lang-plaintext">type SumcheckProtocol struct {
    gArity int
    p *Prover
    v *Verifier
    round int
    done bool
}

// do the initialization
....

// Advance protocol by 1 round
func (s *SumcheckProtocol) AdvanceRound() {
    if s.done {
    panic("Sumcheck protocol is finished")
}

s.p.ComputeAndSendNextPolynomial(s.v)
s.v.CheckLatestPolynomial()

if s.round == s.gArity {
        // final round
        s.done, _ = s.v.EvaluateAndCheckGV()
    } else {
        s.v.GetNewRandomValueAndSend(s.p)
        s.round++
    }
}

// Advance protocol to the end
func (s *SumcheckProtocol) AdvanceToEnd(verbose bool) {
    for !s.done {
        if verbose {
        fmt.Println("Advance Output:", s)
    }
    s.AdvanceRound()
    }
}
</code></pre>
<p>Now time to test the protocol !!!<br />To do this, we create a new file main_test.go and add the following lines:</p>
<pre><code class="lang-plaintext">func TestSumcheck(t *testing.T) {

    g := func(args ...int) int {
    a := args[0]
    return a + a + a*a
    }

    protocol := NewSumcheckProtocol(g)
    fmt.Print(protocol)
    protocol.AdvanceToEnd(true)

    f := func(args ...int) int {
    a := args[0]
    return a*a*a + a + a
    }

    protocol = NewSumcheckProtocol(f)
    protocol.AdvanceToEnd(true)

    ff := func(args ...int) int {
    a := args[0]
    return a*a*a + a + a + a*a
    }
    protocol = NewSumcheckProtocol(ff)
    protocol.AdvanceToEnd(true)
}
</code></pre>
<p>And Hurray 🎉 🎉 🎉 🎉 !! You just wrote the Sum-Check protocol from scratch.</p>
<p>Here is the complete source code in the tutorial: <a target="_blank" href="https://github.com/rachit2501/Sumcheck-Protocol">Github</a></p>
<p>Lastly, connect with me on my socials: <a target="_blank" href="https://twitter.com/RacSri25">Twitter</a>, and <a target="_blank" href="https://www.linkedin.com/in/rachit-anand-srivastava/">LinkedIn</a>. Happy to talk about cryptography, blockchain, and any computer science topic in general.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Interactive Proof Systems and Sum Check Protocol: Part 1]]></title><description><![CDATA[In [computational complexity theory](https://en.wikipedia.org/wiki/Computational_complexity_theory "Computational complexity theory"), an interactive proof system is an [abstract machine](https://en.wikipedia.org/wiki/Abstractmachine "Abstract machin...]]></description><link>https://blog.privacyprophet.xyz/understanding-interactive-proof-systems-and-sum-check-protocol-part-1-6afd9edc67ec</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/understanding-interactive-proof-systems-and-sum-check-protocol-part-1-6afd9edc67ec</guid><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Fri, 29 Dec 2023 08:18:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898944418/976e3f3c-d70f-44c5-8873-5e84168b5e10.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In [computational complexity theory](https://en.wikipedia.org/wiki/Computational_complexity_theory "Computational complexity theory"), an <strong>interactive proof system</strong> is an [abstract machine](https://en.wikipedia.org/wiki/Abstract<em>machine "Abstract machine") that models [computation](https://en.wikipedia.org/wiki/Computation "Computation") as exchanging messages between two parties: a <em>prover</em> and a <em>verifier</em>. The parties interact by exchanging messages to ascertain whether a given [string](https://en.wikipedia.org/wiki/String</em>%28computer_science%29 "String (computer science)") belongs to a [language](https://en.wikipedia.org/wiki/Formal_language "Formal language"). The prover possesses unlimited computational resources but cannot be trusted, while the verifier has bounded computation power but is assumed to be always honest. Messages are sent between the verifier and prover until the verifier has an answer to the problem and has “convinced” itself that it is correct.</p>
<p>This article will teach you how such a system works at a mathematical level and lay the foundation for a new area of research namely “Zero-Knowledge Proofs”.</p>
<h4 id="heading-some-terms-to-know-before-we-continue-further"><strong>Some terms to know before we continue further:</strong></h4>
<ol>
<li>Commitment scheme:</li>
</ol>
<p>In cryptography, a commitment scheme is a fundamental concept that allows one party to commit to a chosen value (or chosen statement) while keeping it hidden from others, with the ability to reveal the committed value later. Commitment schemes are designed to be binding and hiding:</p>
<ul>
<li>Binding: This property ensures that the committing party cannot change a value once a value has been committed. In other words, it’s impossible (or computationally infeasible) for the committer to find another value they can convincingly claim to have committed to originally.</li>
<li>Hiding: This property ensures that the value remains secret until the committer chooses to reveal it. Before the reveal, no other party can determine the committed value.</li>
</ul>
<p>2. Function commitments :</p>
<ul>
<li>Polynomial Commitments: commitments to functions of type:</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898932547/c31a1a72-555b-4cab-a5c1-f37cc46eb8f9.png" alt /></p>
<p>Generalized Polynomial Expression</p>
<ul>
<li>Multilinear Commitments: commitments to functions of type f(x1,…xk)</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898933764/98ee95b8-e564-48c7-b5c3-43963bb74ac4.png" alt /></p>
<p>Generalized Multilinear Expression</p>
<ul>
<li>Vector commitments: eg. Merkle trees.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898934702/0b0e59bc-831e-45ec-9897-8f96552555c2.png" alt /></p>
<p>Example Expression for Vector</p>
<p>3. SZDL Lemma:</p>
<p>Schwartz-Zippel-Demillo-Lipton lemma is a multivariate generalization of fact:</p>
<ul>
<li>Let p != q be a univariate polynomial of degree almost d. Then</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898935864/e7c1d2cd-a241-4e41-91e1-50e84c446ae5.png" alt /></p>
<ul>
<li>SZDL: Let p!= q be l-variate polynomials of total degree almost d.<br />Then</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898937107/12d64848-992f-413e-ad86-00e916e641e0.png" alt /></p>
<ul>
<li>“Total degree” refers to the maximum sum of degrees of all variables in any term.</li>
</ul>
<h3 id="heading-sum-check-protocol">Sum-Check Protocol</h3>
<p>The Sum-Check Protocol is a fundamental technique in theoretical computer science, particularly in the field of interactive proof systems and complexity theory. It’s often used to prove properties about polynomials and is a key component in constructing various interactive proofs, including those for NP-complete problems.</p>
<p>Input: V given Oracle access to an l-variate polynomial g over field F.</p>
<p>Goal: The goal is to verify a claim about the sum of values of a multivariate polynomial i.e. compute the expression:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898938193/ceb7eb14-0530-44ab-a7be-ce42750634b1.png" alt /></p>
<p>Generalized Expression to compute in Sum-Check protocol</p>
<p>Computing the above expression is expensive, and hence the verifier uses interactive proof to verify the result of the expression that the prover returns ( after computing the given expression ).</p>
<p><strong>Protocol Steps:</strong></p>
<ul>
<li>Initialization:<br />The prover wants to convince the verifier that the sum of the polynomial g over a specified domain is a certain value <em>S</em>.</li>
<li>In each round, the prover sends a claim about the sum of a certain polynomial. The verifier checks the claim at a randomly chosen point and asks the prover for a new claim about a related, but simpler polynomial (typically, by fixing one variable). This process is repeated for each variable of <em>P</em>.</li>
<li>P (prover ) sends claimed answer C₁. The protocol must check the ( where F ∈{0,1} ):</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898939737/ebdc6869-435f-4ebe-b655-04c54032757a.png" alt /></p>
<ul>
<li>Round 1: P sends a univariate polynomial S₁ ( X₁) claimed to equal:</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898940879/def4a3ad-f0d3-4be6-901c-beff53935c69.png" alt /></p>
<ul>
<li>The verifier needs to check 2 things:<br />1. Does S₁ equals H₁<br />2. Even if S₁ equals H₁, is that consistent with try answer C₁.</li>
<li>Verifier checks<br />1. C₁ = S₁(0) + S₁(1) where F ∈{0,1}<br />2. Now to check S₁ and H₁, verifier simply checks if S₁ and H₁ agrees at a random point r₁. S₁ is easy to calculate at r₁ since the prover explicitly sends the polynomial to a verifier. But evaluating H₁(r₁) is hard to calculate for the verifier. To address this V picks r₁ at random from F and sends r₁ to P.</li>
<li>Round 2: To address the issue of how to calculate H₁(r₁), the verifier recursively checks that S₁(r₁) = H₁(r₁). We utilize the form of expression that H₁ to do this, by using the following relation:</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898942006/227edd9b-0162-47a6-8d5b-740c014592b1.png" alt /></p>
<ul>
<li>Round n ( Final round ) : P sends a univariate polynomial sₙ(Xn) claimed to equal:</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898942991/70ee6406-1d3d-4362-820e-3148680fdf66.png" alt /></p>
<ul>
<li>V checks that sₙ₋₁(rₙ₋₁) = sₙ(0) + sₙ(1). Also, sₙ(rₙ) = g(r₁, …, rₙ), which the verifier can easily compute since it can simply query the oracle for the value of g(..) directly.</li>
<li>Final Step:<br />The prover sends a univariate polynomial to the verifier. The verifier checks this final polynomial at a random point to confirm the prover’s claim.</li>
</ul>
<h4 id="heading-properties">Properties:</h4>
<ul>
<li>Soundness: If the prover’s original claim about <em>S</em> is false, then with high probability, they will be caught in a lie at some point in the protocol.</li>
<li>Completeness: If the prover’s claim is true, they can always convince the verifier.</li>
</ul>
<p>I won’t be diving into the calculations for the above properties here. Feel free to use the reference links if interested.</p>
<p>In <a target="_blank" href="https://rac-sri.medium.com/understanding-interactive-proof-systems-and-sum-check-protocol-part-2-a2eef4a1e061">Part 2</a>, I will cover a simple implementation of the Protocol from scratch.<br />Connect with me on <a target="_blank" href="https://twitter.com/RacSri25">Twitter</a> and <a target="_blank" href="https://www.linkedin.com/in/rachit-anand-srivastava/">LinkedIn</a>, for any help, or to talk about cryptography, privacy, and blockchain in general.</p>
<p>References:<br />- ChatGPT 4<br />- Interactive Proofs by Justin Thaler <a target="_blank" href="https://www.youtube.com/watch?v=4018OYyoAf8&amp;ab_channel=Blockchain-Web3MOOCs">Link</a></p>
]]></content:encoded></item><item><title><![CDATA[Safeguarding Your Crypto Holdings]]></title><description><![CDATA[Recently I became a victim of a metamask hack. After giving some time to myself and getting back in control, I decided to do a lot of introspection on the mistakes I made and some of the must-follow security practices when storing your crypto safely....]]></description><link>https://blog.privacyprophet.xyz/safeguarding-your-crypto-holdings-34526edbc671</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/safeguarding-your-crypto-holdings-34526edbc671</guid><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Sat, 18 Jun 2022 12:11:53 GMT</pubDate><content:encoded><![CDATA[<p>Recently I became a victim of a metamask hack. After giving some time to myself and getting back in control, I decided to do a lot of introspection on the mistakes I made and some of the must-follow security practices when storing your crypto safely.</p>
<p>I had a pretty straightforward setup, a browser used exclusively when I needed to do any crypto transaction. Nothing else, not even google was to be opened in this browser. In this case, I was relying on a hot wallet, metamask, and this was my first mistake.</p>
<p>I am generally super cautious about my online activity. These practices include, never opening any unknown link on my PC, only doing that if needed inside a sandbox. Never keeping the browser with the metamask opened if not needed, never experimenting or connecting my wallet to any suspicious site. Even when opening a dapp, I never used google, only relied on the link in the official Twitter handle of that particular dapp. The above practices in general should be followed anyway, whether you are into crypto or not, your privacy and data are always crucial.</p>
<p><strong>What is a Hot and Cold Wallet?</strong></p>
<p>Hot Wallet: Web-based wallets, mobile wallets, and desktop wallets are all typically hot wallets. Any wallet which is on a device connected to the internet lies in this category. These are the most vulnerable. These wallets are easy-to-use. Because they are always online, there’s no need to transition between offline and online to make a cryptocurrency transaction, you don't have to go around connecting an offline wallet every time to interact with your funds.</p>
<p>Cold Wallet: These wallets are one of the most secure solutions out there. Stealing from a cold wallet usually would require physical possession of or access to the cold wallet, as well as any associated PINs or passwords that must be used to access the funds. Examples of these time of wallets include the likes of Ledger Nano S, Trezor Hardware wallet, etc. These wallets are not always online, and the private key is not exposed to the internet in any way. Hardware wallets are designed to be immune to hacking. Even when a hardware wallet is plugged into your computer or connected via Bluetooth, depending on the storage method, the funds stored on the drive are difficult or even impossible to steal. All transaction signing is also done “in-device”.</p>
<p>Always use a cold wallet over a hot wallet.</p>
<p><strong>Don’t be Lazy. It's your precious money, and it's your responsibility to safeguard it. Do the hard work of relying on a hardware wallet instead of taking the easier route.</strong></p>
<p>Some of the security recommendations to follow :</p>
<ul>
<li>Do the hard work. Don’t be lazy and compromise on your fund's security.</li>
<li>Always use a hardware wallet.</li>
<li>If possible, try to keep a separate computer for interacting with your wallet. Don’t use your daily driver machine.</li>
<li>Never ever do any transaction, exposing your wallet, to an insecure network. Always make sure the network at your home/workspace is WPA3 secure. Never connect to any public wifi, especially the device that you use for your financial transactions.</li>
<li>Never ever sign with the same nonce twice, there is a very simple relationship in public-key cryptography using which your private key can be extracted if you do so.</li>
<li>An additional level of security can be achieved by relying on multisig. If you have crypto you just keep in store and don't invest or interact with, move them to a multi-sig, and secure it using multiple private keys. Always a good idea to keep these private keys as different hardware wallet devices. The owner of these multiple devices can be just you, or you and your trusted family members, up to you totally. The advantage of this is gonna be that your funds are secure even if one of the hardware wallets gets compromised by getting stolen or anything.</li>
<li>Monitor your wallet frequently to make sure everything is perfectly aligned.</li>
<li>Don’t keep everything in one basket. One of the biggest lessons I learned :). Decide an upper limit, for eg. one wallet, will not have more than 10K USD worth of funds. Diversify as much as you can.</li>
<li>Never store your backup phrase or private key on any device connected to the internet, even if encrypted. Always store them offline.</li>
<li>And of course, never share your seed phrase or private key with anyone.</li>
</ul>
<p>If you have been a victim of any hack/leak, try to take out some time for yourself. Talk to family, and friends to calm yourself. Talk to experts with experience in these fields, those experiences they share and insights are always gonna be invaluable lessons learned. It’s gonna be a hard road ahead for you, but life has to move on… :).</p>
<p>Lastly, if you wanna connect, you can reach out to me on <a target="_blank" href="https://twitter.com/RacSri25">Twitter</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Blockchain Consensus Study]]></title><description><![CDATA[The Blockchain space is a highly growing industry. From a simple whitepaper published in 2009 by an anonymous entity, Satoshi Nakamoto, fixing/disrupting the finance system, preserving the artworks … and so much more !!!!
The Blockchain space, for ye...]]></description><link>https://blog.privacyprophet.xyz/blockchain-consensus-study-31181799b741</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/blockchain-consensus-study-31181799b741</guid><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Sat, 14 Aug 2021 18:20:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898898281/6ca6f0ca-c058-4c39-b25e-74e5fcc6f1a5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The Blockchain space is a highly growing industry. From a simple whitepaper published in 2009 by an anonymous entity, Satoshi Nakamoto, fixing/disrupting the finance system, preserving the artworks … and so much more !!!!</p>
<p>The Blockchain space, for years, had several issues when it came to scalability, decentralization, and performance aka the <a target="_blank" href="https://www.researchgate.net/figure/Scalability-Blockchain-Trilemma_fig5_347444005">Blockchain Trilemma Problem</a>.</p>
<p>This article will cover the 3 most famous architecture at the time of writing:<br />1. Proof of Work ( POW ) — Bitcoin, Ethereum 1.0, Litecoin, Dogecoin<br />2. Proof of Stake ( POS ) — Ethereum 2.0, HarmonyONE, Algorand<br />3. Proof of History ( POH ) — Solana ( The only consensus which claims to resolve the Blockchain Trilemma )</p>
<p>There are other solutions like Proof of Authority and Proof of Transfer, which we won’t cover in this article.</p>
<p>So, let's dive deeper :)</p>
<h3 id="heading-proof-of-work"><strong>Proof Of Work</strong></h3>
<p>Most security focuses on consensus and the consensus which market the beginning of this industry. The consensus was introduced by an anonymous entity names Satoshi Nakamoto in 2009, giving birth to Bitcoin.</p>
<p>This consensus derives its security from the computational power of the miners. Miners are nodes ( or computer machines simply ) that do some mathematical calculation to solve a given problem. The first machine to complete the calculation of the problem gets rewarded if the result it gave is correctly verified by the other participating nodes in the network. Yes, Bitcoin is the reward that the miner on the bitcoin network receives. Since there is a race among the minors, to do the computation as fast as possible, more and more power is required to run the hardware required to run the system.</p>
<p>The Blockchain Trillema:</p>
<p>If the focus is entirely on Security and Decentralization, then the cost is Scalability. Hence Bitcoin Blockchain takes around 10 minutes to complete a transaction, and Ethereum 1.0 takes around 3 minutes.</p>
<p>To fix this issue, there are several scaling solutions have been developed. Lighting Network for Bitcoin is a great example. Similarly, Optimistic Rollups, ZK-Rollups, State Channels, Sidechains, Plasma. Taking a deep dive into these solutions is another article in itself :)</p>
<p>If you are interested in visualizing the working of simple pow Blockchain, checkout -&gt; <a target="_blank" href="https://andersbrownworth.com/blockchain%C2%A0.">https://andersbrownworth.com/blockchain</a>.The nonce is the math value to be calculated.</p>
<h3 id="heading-proof-of-stake">Proof Of Stake:</h3>
<p>Proof of Stake is relatively a new solution, which aims to make scalable blockchains.</p>
<p>The nodes ( simply computers ) stake an amount of cryptocurrency to become candidates to validate new blocks and earn rewards from them. The algorithm, based on the quality of stake and other factors like, coin-age, randomization, etc., chooses from the candidates' nodes, the node which will validate the new block.</p>
<p>Since the computing node is determined algorithmically, over competitiveness, results in fewer hardware requirements, and consequently more power efficiency. Ethereum aims to migrate to POS by the end of 2021.</p>
<p>There are several variations in the implementation of course. Most of the implementation/innovation is done in the algorithm which determines the elected node. A good example of an algorithm is <a target="_blank" href="https://docs.harmony.one/home/general/technology/effective-proof-of-stake#:~:text=Harmony%27s%20Effective%20Proof%2Dof%2DStake,the%20tendency%20of%20stake%20centralization.">Effective Proof of Stake</a>.</p>
<p>An important term to know when it comes to POS architecture is Sharding. Ethereum 2.0 aims to have 64 shards. The question is what is sharding?<br />Sharding is basically dividing one blockchain into several chains, which will interact with each other using the main chain called the “Beacon Chain”. These other chains are simply called “shard chains” or simply “shard”.<br />For better understanding, imagine a bank. 100 people want to take out some cash from their accounts. If they all assemble at the branch office it will take a long time. To fix that, there are several ATMs installed, let's say 4, so now, people can go in groups of 20 to these ATMs and get their cash faster. The bank branch only has 20 people to deal with now, but at the same time acts as the body responsible for keeping track of all the 100 customers. The ATMs are the ‘shards’ and the bank branch is our ‘beacon chain’.</p>
<p>P.s Using banks as an example, since any reader new to this space can easily understand. Defi &gt;&gt; Banks anytime :)</p>
<h3 id="heading-proof-of-history"><strong>Proof of History</strong></h3>
<p>This is indeed one of the most innovative approaches to solve the Blockchain Trilemma problem. Introduced by Solana, This consensus has been a highlight for its highly effective result.</p>
<p>Both POW, POS have a very high Block Time because the message needs to be majority ( &gt; 50%) nodes, to get added to the block. Some innovative solutions target this in POS ( like Harmony.One 2 seconds finality). So POH aims to solve this using time cryptographic timekeeping.</p>
<p>Definition by SolanaLabs: “The Proof of History is a high-frequency <a target="_blank" href="https://www.youtube.com/watch?v=qUoagL7OZ1k">Verifiable Delay Function</a>. A Verifiable Delay Function requires a specific number of sequential steps to evaluate, yet produces a unique output that can be efficiently and publicly verified.”.</p>
<p>Don’t worry if you don't get that. Let's take another imaginative scenario to understand this one.</p>
<p>Imagine a person in a restaurant, having served a coffee. The restaurant has 5 other customers who come at intervals of 30 seconds, and on entering just take a picture of the coffee mug. Now after the person completes drinking his coffee, if we combine all the pictures taken by the customers, we can see the order in which the pictures would be arranged ( simply by observing the amount of coffee left ). This gives a precise order of time. So every picture is a precise idea of time. So the picture can be compared to a block and combined with the ordering of photos ( blocks ), is Proof of History.</p>
<p>Hope this article gives you a clear picture of the main consensus in use right now and a slight idea of how early this space is 😀. For more consensus study try -&gt; <a target="_blank" href="https://tokens-economy.gitbook.io/consensus/">https://tokens-economy.gitbook.io/consensus/</a></p>
<p>Lastly, connect with me on <a target="_blank" href="https://twitter.com/RacSri25">Twitter</a>, for any help, or for learning about the latest happenings in this crazy space.</p>
]]></content:encoded></item><item><title><![CDATA[Token Standards: ERC20 vsERC721 vs ERC1155]]></title><description><![CDATA[Blockchain Technology is slowly taking over the world. People have finally started to understand the issues with centralization, and thus the importance of this one paper by the anonymous entity Satoshi Nakamoto, which started this revolution of cryp...]]></description><link>https://blog.privacyprophet.xyz/token-standards-erc20-vserc721-vs-erc1155-3106f1e3f2f3</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/token-standards-erc20-vserc721-vs-erc1155-3106f1e3f2f3</guid><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Sun, 04 Apr 2021 20:04:01 GMT</pubDate><content:encoded><![CDATA[<p>Blockchain Technology is slowly taking over the world. People have finally started to understand the issues with centralization, and thus the importance of this <a target="_blank" href="https://bitcoin.org/bitcoin.pdf">one paper</a> by the anonymous entity Satoshi Nakamoto, which started this revolution of cryptography and decentralization.</p>
<p>In 2015, with the Ethereum network going live, came a whole new world of possibilities in the decentralized space. The EVM machine which can execute smart contract was a game-changer. Consequently, the introduction of smart contracts made developers and experts all around, build platforms take on, probably the biggest “Ponzi scheme” of all times: <strong>The Traditional Financial System</strong> ( or fiat system ).</p>
<h3 id="heading-erc20"><strong>ERC20</strong></h3>
<p>The rise of smart contracts, allowed users to create special contracts, which can act like currencies. A lot of these got released, and consequently, it was becoming hard to keep track of all these different standards of writing virtual currencies smart contracts on the network. Hence came in the proposal of ERC20 Standards: <a target="_blank" href="https://eips.ethereum.org/EIPS/eip-20">https://eips.ethereum.org/EIPS/eip-20</a></p>
<p>This standardized how a token contract should look, resulting in the seamless integration of tokens in different protocols and crypto-wallets. This eventually gave birth to some amazing solutions in the decentralized finance or DeFi space like Uniswap, Aave, MakerDAO, etc. Today, billions of dollars worth of crypto are traded in this space.</p>
<p>So, what exactly do ERC20 Tokens represent?</p>
<p>ERC20 tokens are basically what we will call “Fungible Tokens”. <strong>Fungibility</strong> is the ability of a good or asset to be readily interchanged for another of like kind. Think of two 1 dollar notes. Both the notes are different, but their value is exactly the same. The same is the case in an ERC20 token. Each token is worth the exact same as the other tokens in value.</p>
<p>This consequently resulted in several applications of ERC20 tokens like stablecoins, governance tokens, but let's not get into that in this post.</p>
<h3 id="heading-erc721"><strong>ERC721</strong></h3>
<p>Ok, so the significance of ERC20 is clear, lets now get into ERC721.</p>
<p>So, what exactly does ERC721 represents?</p>
<p>Simple, an entity. It can be anything, which has its own value. An artwork, a music album, an agreement contract, etc. No two ERC721 tokens are the same when it comes to value.</p>
<p>ERC721 are what are called “<strong><em>Non-Fungible tokens</em></strong>”. Think of two ERC721 representing 2 soccer player:</p>
<p>First represents a high school student and one representing some popular figure like Cristiano Ronaldo. So now it's clear that the card representing Cristiano would be worth way more than the card of the Highschool student.</p>
<p>But the big question, which stops a lot of people from getting into NFT is why even bother to buy a “digital entity” in the first place. The answer is pretty simple, think of it like this: Why does Mona Lisa cost so much and is considered so much valuable ?. The answer is as simple as that, people consider it to be a valuable piece of art that adds value to its existence.</p>
<p>The same is the case with NFTs. An NFT acts as proof of ownership over a piece of digital content or a digital asset.NFT’s are unique digital tokens that represent specific digital assets that can be bought, sold, and traded. The digital artists can ensure that the value of the art that they produce is maintained during its sale and also any future royalties that they may be owed.</p>
<p>“CryptoPunks” and “CryptoKitties” are two of the very first projects in this space. Some NFT art sites now allow the option of buying <strong>carbon offsets</strong> when making NFT purchases or contributing a percentage of revenue to offset programs</p>
<p>Check out <a target="_blank" href="https://eips.ethereum.org/EIPS/eip-721">https://eips.ethereum.org/EIPS/eip-721</a> for standard specifications.</p>
<h3 id="heading-erc1155">ERC1155</h3>
<p>ERC-1155 is what we will call the best of both worlds.</p>
<p>ERC-1155 allows you to create <strong>Fungible</strong>, <strong>Non-Fungible</strong>, and <strong>Semi-Fungible</strong> in one single token standard. Both Fungible and Non-Fungible tokens can be created using the same standard.</p>
<p>So why ERC-1155?</p>
<p>Take, for example, Mona Lisa again. There is one Mona Lisa artwork, which is worth millions of dollars and can be represented by <strong>Non-Fungible ERC-1155</strong>. Now there can also be several other copies of the artwork, which can be sold as F<strong>ungible ERC1155.</strong> The ERC1155 gives accessibility, simplicity, and efficiency on the buyer side.</p>
<p>Another example use case can be games. You earn points and buy items using these points in a game. At the same time, you can exchange items too. The “items” can be represented by Non-Fungible ERC-1155 and “points” can be represented as Fungible ERC-1155.</p>
<p>Check out <a target="_blank" href="https://eips.ethereum.org/EIPS/eip-1155">https://eips.ethereum.org/EIPS/eip-1155</a> for the standard specifications.</p>
<p>Lastly, connect with me on <a target="_blank" href="https://twitter.com/RacSri25">Twitter</a>, for any help, or for learning about the latest happenings in this crazy space.</p>
<blockquote>
<p>Join Coinmonks <a target="_blank" href="https://t.me/coincodecap">Telegram Channel</a> and <a target="_blank" href="https://www.youtube.com/c/coinmonks/videos">Youtube Channel</a> get daily <a target="_blank" href="http://coincodecap.com/">Crypto News</a></p>
</blockquote>
<h4 id="heading-also-read">Also, Read</h4>
<ul>
<li><a target="_blank" href="https://medium.com/coinmonks/top-10-crypto-copy-trading-platforms-for-beginners-d0c37c7d698c">Copy Trading</a> | <a target="_blank" href="https://medium.com/coinmonks/crypto-tax-software-ed4b4810e338">Crypto Tax Software</a></li>
<li><a target="_blank" href="https://coincodecap.com/grid-trading">Grid Trading</a> | <a target="_blank" href="https://medium.com/coinmonks/the-best-cryptocurrency-hardware-wallets-of-2020-e28b1c124069">Crypto Hardware Wallet</a></li>
<li><a target="_blank" href="http://Top%204%20Telegram%20Channels%20for%20Crypto%20Traders">Crypto Telegram Signals</a> | <a target="_blank" href="https://medium.com/coinmonks/crypto-trading-bot-c2ffce8acb2a">Crypto Trading Bot</a></li>
<li><a target="_blank" href="https://coincodecap.com/pionex-dual-investment">Pionex Dual Investment</a> | <a target="_blank" href="https://coincodecap.com/advcash-review">AdvCash Review</a> | <a target="_blank" href="https://coincodecap.com/uphold-review">Uphold Review</a></li>
<li><a target="_blank" href="https://coincodecap.com/best-cryptocurrency-apis">8 Best Cryptocurrency APIs for Developers</a></li>
<li><a target="_blank" href="https://coincodecap.com/uphold-card-review">Uphold Card Review</a> | <a target="_blank" href="https://coincodecap.com/trust-wallet-vs-metamask">Trust Wallet vs MetaMask</a></li>
<li><a target="_blank" href="https://coincodecap.com/earn-sign-up-bonus">Earn Sign-up Bonus — 10 Best Crypto Platforms</a></li>
<li><a target="_blank" href="https://medium.com/coinmonks/crypto-exchange-dd2f9d6f3769">Best Crypto Exchange</a> | <a target="_blank" href="https://medium.com/coinmonks/bitcoin-exchange-in-india-7f1fe79715c9">Best Crypto Exchange in India</a></li>
<li><a target="_blank" href="https://medium.com/coinmonks/best-crypto-apis-for-developers-5efe3a597a9f">Best Crypto APIs</a> for Developers</li>
<li>Best <a target="_blank" href="https://medium.com/coinmonks/top-5-crypto-lending-platforms-in-2020-that-you-need-to-know-a1b675cec3fa">Crypto Lending Platform</a></li>
<li>An ultimate guide to <a target="_blank" href="https://medium.com/coinmonks/leveraged-token-3f5257808b22">Leveraged Token</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[I along with my teammate Apoorv Lathey took part in the HackONhackathon that was conducted online…]]></title><description><![CDATA[I along with my teammate Apoorv Lathey took part in the HackOn Hackathon that was conducted online on Devfolio.

During the limited time-frame, we came up with our project “CoronaRedemption”. This application included the following features:

Anonymo...]]></description><link>https://blog.privacyprophet.xyz/i-along-with-my-teammate-apoorv-lathey-took-part-in-the-hackonhackathon-that-was-conducted-online-268bdd1bb8ac</link><guid isPermaLink="true">https://blog.privacyprophet.xyz/i-along-with-my-teammate-apoorv-lathey-took-part-in-the-hackonhackathon-that-was-conducted-online-268bdd1bb8ac</guid><dc:creator><![CDATA[Rachit Anand Srivastava]]></dc:creator><pubDate>Fri, 29 May 2020 09:28:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898907087/c5fe5d34-0026-495b-9b5d-2a0987648e31.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I along with my teammate Apoorv Lathey took part in the <a target="_blank" href="http://hackon.devfolio.co/">HackOn Hackathon</a> that was conducted online on Devfolio.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898901382/31ebadcd-91c5-4b47-ab61-ede72976a132.png" alt /></p>
<p>During the limited time-frame, we came up with our project “CoronaRedemption”. This application included the following features:</p>
<ul>
<li>Anonymous reporting of the violation of lockdown by people to the concerned authorities</li>
<li>Ability to start donation camps by individuals or institutions affected</li>
<li>View the current state of the spread of the virus via dynamically updated graphs</li>
</ul>
<p><strong>Video Demo</strong> of our project: <a target="_blank" href="https://www.youtube.com/watch?v=PIdcg4L6Dgo">https://www.youtube.com/watch?v=PIdcg4L6Dgo</a></p>
<p><strong>Live Demo</strong>: <a target="_blank" href="https://covidextricate.herokuapp.com/">https://covidextricate.herokuapp.com/</a></p>
<p>Let’s dive into the details of the project.</p>
<h3 id="heading-report-lockdown-violation">Report Lockdown Violation</h3>
<p>We have come up with a solution to help control the violation of lockdown ( which is the key weapon for fighting this pandemic). People can come on our portal, give some unique identification key, we verify it, and then send back a special entry token to the user.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898902927/9d8aa1e3-29cf-4719-bc8f-26041b33f1c5.png" alt /></p>
<p>Report Violation Dashboard</p>
<p>Now the user can use this entry token and upload photos of people violating the lockdown ( that they can take using their cameras from their rooftops etc.). The uploader will remain totally safe and anonymous since the image uploaded will be stored over distributed storage (IPFS) and the key to view them will only be with the government authority concerned with control.</p>
<blockquote>
<p><em>We used the Matic blockchain network to provide us with the anonymous solution of storing report details so that people can use their Ethereum address with no ETH to report a case of violation.</em></p>
</blockquote>
<p>The data stored at the backend will only contain the unique id in encrypted form and corresponding token send. This will help avoid spam image uploads. The token is used by the user will in no way reveal his identity if someone gets access to who uploaded an image in some way since there is no way the token will lead back to the user.</p>
<h3 id="heading-donation-camps">Donation Camps</h3>
<p>Corona has caused a lot of loss of jobs, money problems for several institutions (especially those involved in the treatment of this pandemic).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898904345/679a4a25-4b77-424c-a60d-7fe00bcfbffe.png" alt /></p>
<p>Donation Camp DashBoard</p>
<p>People can come here, provide details about their needs, and after giving legitimate proof of their need, they can raise a donation camp and get funded.</p>
<blockquote>
<p><em>We are using the decentralized nature of the blockchain to transfer wealth from the rich to the needy ones without the need to rely on intermediaries and making this process a lot faster + transparent.</em></p>
</blockquote>
<p>In this way, many people can get money for survival and institutes the option to get money faster. The government is providing money to help but this way its a direct transfer of money from the donor to the needy, resulting in faster services.</p>
<h3 id="heading-live-updates">Live Updates</h3>
<p>Lastly, users can browse the live statistics regarding COVID-19. Data can be viewed in the form of worldwide stats, country-wide stats, country-wise historic timeline to monitor growth.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734898905685/f4dca7a5-2dd9-4504-a0fe-5eb452b29a68.png" alt /></p>
<p>Graphical representation along with tabular format, both are available on our portal.</p>
<p>We would like to thank the <a target="_blank" href="http://hackon.devfolio.co/">HackOn</a> team.</p>
<p>Special Thanks to <a target="_blank" href="https://medium.com/u/db572a13f461">Devfolio</a>, <a target="_blank" href="http://matic.network">Matic</a>, <a target="_blank" href="https://medium.com/u/4f3f4ee0f977">Google Cloud</a>, <a target="_blank" href="https://medium.com/u/8df3bf3c40ae">GitHub</a>, <a target="_blank" href="http://elastic.co">Elastic</a>, and IBM for sponsoring the event.</p>
<p>Submission Link: <a target="_blank" href="https://devfolio.co/submissions/coronaredemption">https://devfolio.co/submissions/coronaredemption</a></p>
]]></content:encoded></item></channel></rss>