<?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[Furkan's Blog]]></title><description><![CDATA[Cryptography and Protocol Exploration]]></description><link>https://furkanakal.com</link><generator>RSS for Node</generator><lastBuildDate>Wed, 09 Sep 2026 19:23:15 GMT</lastBuildDate><atom:link href="https://furkanakal.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Exploring Kyber: Constructing a Post-Quantum KEM]]></title><description><![CDATA[Modern cryptographic systems are not built around encrypting messages directly with public keys. Instead, they are built around establishing secrets. Once a shared secret exists, symmetric cryptography takes over, handling confidentiality, integrity,...]]></description><link>https://furkanakal.com/exploring-kyber-constructing-a-post-quantum-kem</link><guid isPermaLink="true">https://furkanakal.com/exploring-kyber-constructing-a-post-quantum-kem</guid><category><![CDATA[kyber]]></category><category><![CDATA[Post-Quantum Cryptography]]></category><category><![CDATA[key-encapsulation-mechanism]]></category><dc:creator><![CDATA[Furkan Akal]]></dc:creator><pubDate>Wed, 07 Jan 2026 11:35:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1767785680115/e771b2fe-7592-4b20-b634-85dbc4376b3e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Modern cryptographic systems are not built around encrypting messages directly with public keys. Instead, they are built around <em>establishing secrets</em>. Once a shared secret exists, symmetric cryptography takes over, handling confidentiality, integrity, and authentication efficiently at scale.</p>
<p>This design choice is not an accident. It reflects both performance constraints and deep cryptographic realities. Public-key cryptography is expensive and assumption-heavy. Symmetric cryptography is fast, robust, and conservative. The role of public-key cryptography is therefore reduced to a single task: <strong>securely establishing a shared secret</strong>.</p>
<p>This task is formalized by the notion of a <strong>Key Encapsulation Mechanism (KEM)</strong>.</p>
<h1 id="heading-what-is-a-key-encapsulation-mechanism-kem">What Is a Key Encapsulation Mechanism (KEM)?</h1>
<p>A <strong>Key Encapsulation Mechanism</strong> is a cryptographic primitive whose purpose is <em>not</em> to encrypt arbitrary messages, but to securely deliver a randomly generated symmetric key from one party to another.</p>
<p>A KEM is defined by three algorithms:</p>
<ul>
<li><p><strong>KeyGen</strong></p>
</li>
<li><p><strong>Encaps</strong></p>
</li>
<li><p><strong>Decaps</strong></p>
</li>
</ul>
<p>Each algorithm plays a precise role, and none of them can be removed without breaking the abstraction.</p>
<h2 id="heading-key-generation">Key Generation</h2>
<p>In the key generation phase, a user—let’s call her Alice—generates a key pair:</p>
<ul>
<li><p>a <strong>public encapsulation key</strong> <code>ek</code></p>
</li>
<li><p>a <strong>private decapsulation key</strong> <code>dk</code></p>
</li>
</ul>
<p>The encapsulation key is meant to be distributed freely. It may be embedded in certificates, posted on servers, or hardcoded into protocols. The decapsulation key must remain secret.</p>
<p>At this stage, <em>no shared secret exists yet</em>. The key pair merely enables someone else to establish one later.</p>
<h2 id="heading-encapsulation">Encapsulation</h2>
<p>Encapsulation is performed by another party—let’s call him Bob.</p>
<p>Using Alice’s public encapsulation key, Bob:</p>
<ol>
<li><p>Generates a fresh, uniformly random symmetric key \(K\)</p>
</li>
<li><p>Produces a ciphertext \(c\) that encapsulates this key</p>
</li>
<li><p>Sends only \(c\) to Alice</p>
</li>
</ol>
<p>The key \(K\) is not transmitted, encrypted, or revealed in any explicit way. It exists only implicitly through the cryptographic structure of \(c\).</p>
<p>This design ensures that:</p>
<ul>
<li><p>even if ciphertexts are public,</p>
</li>
<li><p>even if they are stored indefinitely,</p>
</li>
<li><p>the key remains indistinguishable from random to any attacker.</p>
</li>
</ul>
<h2 id="heading-decapsulation">Decapsulation</h2>
<p>Using her private decapsulation key, Alice processes the ciphertext \(c\) and deterministically recovers the same symmetric key \(K\).</p>
<p>At this point:</p>
<ul>
<li><p>Alice and Bob share a secret</p>
</li>
<li><p>no further public-key operations are needed</p>
</li>
<li><p>symmetric cryptography can be used for all subsequent communication</p>
</li>
</ul>
<h2 id="heading-why-existing-kems-are-not-post-quantum-secure">Why Existing KEMs Are Not Post-Quantum Secure?</h2>
<p>Most deployed KEMs today are based on classical hardness assumptions:</p>
<ul>
<li><p>RSA-based KEMs rely on integer factorization</p>
</li>
<li><p>Diffie–Hellman KEMs rely on discrete logarithms</p>
</li>
<li><p>Elliptic-curve KEMs rely on elliptic-curve discrete logarithms</p>
</li>
</ul>
<p>All of these assumptions are broken by <strong>Shor’s algorithm</strong>.</p>
<h2 id="heading-harvest-now-decrypt-later">Harvest Now, Decrypt Later</h2>
<p>The most dangerous aspect of quantum attacks is not future communication—it is <em>past communication</em>.</p>
<p>An adversary can:</p>
<ol>
<li><p>Passively record encrypted traffic today</p>
</li>
<li><p>Store ciphertexts indefinitely</p>
</li>
<li><p>Decrypt everything once quantum capabilities exist</p>
</li>
</ol>
<p>This attack model is known as <strong>harvest-now, decrypt-later</strong>.</p>
<p>Importantly:</p>
<ul>
<li><p>the attacker does not need to interact with the protocol</p>
</li>
<li><p>the attacker does not need to break keys today</p>
</li>
<li><p>the attacker only needs storage and patience</p>
</li>
</ul>
<hr />
<h1 id="heading-kyber-a-post-quantum-secure-kem">Kyber: A Post-Quantum Secure KEM</h1>
<p>Kyber is a lattice-based KEM standardized by NIST as <a target="_blank" href="https://csrc.nist.gov/pubs/fips/203/final"><strong>FIPS-203 (ML-KEM)</strong></a>.</p>
<p>Its security is based on the <strong>Module-</strong><a target="_blank" href="https://en.wikipedia.org/wiki/Learning_with_errors"><strong>Learning With Errors</strong></a> <strong>(Module-LWE)</strong> problem, a generalization of LWE that balances efficiency and security.</p>
<p>It follows a clean structure:</p>
<ol>
<li><p>Define a lattice-based public-key encryption scheme (Kyber-PKE)</p>
</li>
<li><p>Apply the <a target="_blank" href="https://lukas-prokop.at/articles/2020-06-19-fo-transform">Fujisaki–Okamoto transform</a></p>
</li>
<li><p>Obtain a <a target="_blank" href="https://en.wikipedia.org/wiki/Chosen-ciphertext_attack">CCA-secure</a> KEM</p>
</li>
</ol>
<h2 id="heading-mathematical-setting-and-parameters">Mathematical Setting and Parameters</h2>
<p>Kyber operates over the polynomial ring:</p>
<p>$$R_q = \mathbb{Z}_q[X]/(X^n + 1)$$</p><p>For <strong>ML-KEM-768</strong>, the parameters are:</p>
<ul>
<li><p>\(q=3329\)</p>
</li>
<li><p>\(n=256\)</p>
</li>
<li><p>\(k = 3\)</p>
</li>
<li><p>noise parameters \(\eta_1 = 2, \eta_2 = 2\)</p>
</li>
<li><p>compression parameters \(d_u = 10, d_v = 4\)</p>
</li>
</ul>
<h2 id="heading-kyber-pke-key-generation">Kyber-PKE Key Generation</h2>
<p>Alice performs the following steps:</p>
<ol>
<li><p>Sample a random seed \(ρ∈\{0, 1\}^{256}\)</p>
</li>
<li><p>Deterministically expand \(ρ\) into a matrix</p>
</li>
</ol>
<p>$$A \in R_q^{k \times k}$$</p><ol start="3">
<li><p>Sample secret vector \(s \in R_q^k\) from a centered binomial distribution</p>
</li>
<li><p>Sample error vector \(e \in R_q^k\) from the same distribution</p>
</li>
<li><p>Compute</p>
</li>
</ol>
<p>$$t = As + e$$</p><p>The keys are:</p>
<ul>
<li><p>public key: \((ρ, t)\)</p>
</li>
<li><p>secret key: \(s\)</p>
</li>
</ul>
<p>Alice’s goal here is to create a sort of mathematical "locked box." By expanding a random seed into a matrix \(A\) and generating a secret vector \(s\), she sets the stage for a Module-LWE instance. The critical step is adding the error vector \(e\). This tiny bit of noise is what makes the system secure; without it, an attacker could use simple linear algebra to solve for \(s\). Instead, they are left with \(t = As + e\), a result that looks like random noise but secretly hides Alice's private key.</p>
<h2 id="heading-kyber-pke-encryption">Kyber-PKE Encryption</h2>
<p>To encrypt a message \(m \in \{0, 1 \}^n\), Bob:</p>
<ol>
<li><p>Reconstructs \(A\) from \(\rho\).</p>
</li>
<li><p>Samples randomness</p>
<ol>
<li><p>\(r \sim \chi_{\eta_1}^k\)</p>
</li>
<li><p>\(e_1 \sim \chi_{\eta_2}^k\)</p>
</li>
<li><p>\(e_2 \sim \chi_{\eta_1}\)</p>
</li>
</ol>
</li>
<li><p>Computes:</p>
</li>
</ol>
<p>$$u = A^Tr + e_1$$</p><p>$$v = t^Tr + e_2 + \Bigl\lfloor\frac{q}{2}\Bigr\rfloor m$$</p><ol start="4">
<li><p>Calculates \(c_1\) by compressing \(u\) to \(d_u \) bits.</p>
</li>
<li><p>Calculates \(c_2\) by compressing \(v\) to \(d_v \) bits.</p>
</li>
<li><p>Outputs ciphertext \(c = (c_1, c_2)\).</p>
</li>
</ol>
<h2 id="heading-kyber-pke-decryption-and-correctness">Kyber-PKE Decryption and Correctness</h2>
<p>Alice:</p>
<ol>
<li><p>Decompresses \(u\) and \(v\).</p>
</li>
<li><p>Computes:</p>
</li>
</ol>
<p>$$v - s^Tu$$</p><ol start="3">
<li>Substituting definitions:</li>
</ol>
<p>$$v - s^T u = t^T r + e_2 + \Bigl\lfloor\frac{q}{2}\Bigr\rfloor m - s^T(A^T r + e_1)$$</p><ol start="4">
<li>Using \(t = As + e\):</li>
</ol>
<p>$$= r^T A s + r^T e + e_2 + \Bigl\lfloor\frac{q}{2}\Bigr\rfloor m - r^T A s - s^T e_1$$</p><p>$$= r^T e + e_2 - s^T e_1 + \Bigl\lfloor\frac{q}{2}\Bigr\rfloor m$$</p><p>When she computes \(v - s^T u\), the terms involving the matrix \(A\) cancel out perfectly, leaving her with the scaled message plus a small pile of accumulated noise: \(r^Te + e_2 - s^Te_1\). Because this noise is small relative to the scaling factor, Alice can simply round the result to the nearest bit, effectively "shaking off" the errors to reveal Bob’s original message \(m\).</p>
<h2 id="heading-from-kyber-pke-to-kyber-kem">From Kyber-PKE to Kyber-KEM</h2>
<p>Now, let’s see how we can construct Kyber-KEM by utilizing the Kyber-PKE primitives!</p>
<h2 id="heading-kyber-kem-key-generation">Kyber-KEM Key Generation</h2>
<p>Alice:</p>
<ol>
<li><p>Runs Kyber-PKE.KeyGen → \(((\rho, t), s)\).</p>
</li>
<li><p>Samples a random value \(z \in \{ 0, 1 \}^{256}\).</p>
</li>
<li><p>Sets:</p>
<ul>
<li><p>encapsulation key: \(ek = (\rho, t)\)</p>
</li>
<li><p>decapsulation key:</p>
</li>
</ul>
</li>
</ol>
<p>$$dk = (s, ek, H(ek), z)$$</p><h2 id="heading-kyber-kem-encapsulation">Kyber-KEM Encapsulation</h2>
<p>Bob:</p>
<ol>
<li><p>Obtains authentic \(ek\).</p>
</li>
<li><p>Selects:</p>
</li>
</ol>
<p>$$m \in \{0, 1\}^{256}$$</p><ol start="3">
<li>Computes:</li>
</ol>
<p>$$h = H(ek)$$</p><p>$$(K, R) = G(m, h)$$</p><p>with \(H\) and \(G\) being some hash functions.</p>
<ol start="4">
<li>Uses Kyber-PKE.Enc to compute</li>
</ol>
<p>$$c = PKE.Enc_{ek}(m; r)$$</p><ol start="5">
<li>Outputs the secret key \(K\) and ciphertext \(c\).</li>
</ol>
<h2 id="heading-kyber-kem-decapsulation">Kyber-KEM Decapsulation</h2>
<p>To recover the secret key \(K\) from \(c\) using decapsulation key \(dk\), Alice does:</p>
<ol>
<li><p>Use the Kyber-PKE to compute \(PKE.Dec_s(c)\) and call it the plaintext \(m'\).</p>
</li>
<li><p>Compute:</p>
</li>
</ol>
<p>$$(K', R') = G(m', H(ek))$$</p><ol>
<li><p>Compute fallback \(\bar{K} = J(z, c)\) with J being a hash function.</p>
</li>
<li><p>Compute:</p>
</li>
</ol>
<p>$$PKE.Enc_{ek}(m') = c'.$$</p><ol>
<li><p>If \(c \neq c'\), then return \(\bar{K}\).</p>
</li>
<li><p>Otherwise, return \(K'\).</p>
</li>
</ol>
<p>In Kyber-KEM Decapsulation, Alice doesn't just trust the recovered message \(m'\). She actually <strong>re-encrypts</strong> it to see if it produces the exact same ciphertext Bob sent. If even a single bit differs (\(c \neq c'\)), she knows the ciphertext was tampered with and returns a random "fallback" value instead.</p>
<hr />
<h1 id="heading-conclusion">Conclusion</h1>
<p>The transition to post-quantum cryptography is a practical necessity, especially in the blockchain setting where almost everything as public forever. As we have seen, the security of our current digital infrastructure rests on assumptions—like the hardness of integer factorization or discrete logarithms—that will not hold in a quantum future. Kyber, now officially standardized as <strong>ML-KEM</strong> by NIST in <strong>FIPS 203</strong>, represents the most mature and efficient path forward for general-purpose encryption.</p>
<p>As these algorithms begin to integrate into our systems, they will provide the necessary security to protect our data against the potential threats posed by quantum computers. This shift is crucial to ensure that our digital communications remain secure in the face of advancing technology.</p>
<h1 id="heading-further-reading-amp-resources">Further Reading &amp; Resources</h1>
<p>If you want to dive deeper into the world of lattice-based cryptography and the official standards, here are some of the best places to start:</p>
<h3 id="heading-1-the-official-standard">1. The Official Standard</h3>
<ul>
<li><a target="_blank" href="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.203.pdf"><strong>NIST FIPS 203: Module-Lattice-Based Key-Encapsulation Mechanism Standard</strong></a> The definitive technical document for ML-KEM (formerly Kyber), covering the precise mathematical specifications and parameter sets like ML-KEM-768.</li>
</ul>
<h3 id="heading-2-lattice-math-amp-lwe-tutorials">2. Lattice Math &amp; LWE Tutorials</h3>
<ul>
<li><p><a target="_blank" href="https://cims.nyu.edu/~regev/papers/lwesurvey.pdf"><strong>Learning with Errors (LWE) Survey by Oded Regev</strong></a> A foundational paper by the creator of LWE, explaining why adding noise to linear equations makes them so hard to solve.</p>
</li>
<li><p><a target="_blank" href="https://di-mgt.com.au/lattice-lwe-simple-pke.html"><strong>A Simple Lattice-Based Encryption Scheme</strong></a> A great "from scratch" walkthrough that builds a simplified version of the math used in Kyber to help you visualize the noise and rounding process.</p>
</li>
</ul>
<h3 id="heading-3-understanding-the-fo-transform">3. Understanding the FO Transform</h3>
<ul>
<li><a target="_blank" href="https://digital.csic.es/bitstream/10261/286636/1/About%20the%20Fujisaki-Okamoto%20Transformation.pdf"><strong>The Fujisaki-Okamoto Transformation Revisited</strong></a> A deep dive into how we turn "weak" encryption into "strong" KEMs through re-encryption checks and hashing.</li>
</ul>
<h3 id="heading-4-implementation-in-the-wild">4. Implementation in the Wild</h3>
<ul>
<li><a target="_blank" href="https://signal.org/docs/specifications/pqxdh/"><strong>PQXDH: Signal's Post-Quantum Protocol</strong></a> Learn how Signal integrated Kyber into their protocol to protect over a hundred million users from future quantum threats.</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Exploring Quantum Key Distribution: The BB84 Protocol]]></title><description><![CDATA[Hello everyone! Welcome to a new blog post. In this one, we will discuss the notion of quantum key distribution and its first kind scheme: the BB84 protocol.
Key Exchange
What is it and why is it important?
Key exchange is the process of securely sha...]]></description><link>https://furkanakal.com/quantum-key-distribution-the-bb84-protocol</link><guid isPermaLink="true">https://furkanakal.com/quantum-key-distribution-the-bb84-protocol</guid><category><![CDATA[bb84 protocol]]></category><category><![CDATA[Quantum Cryptography]]></category><dc:creator><![CDATA[Furkan Akal]]></dc:creator><pubDate>Tue, 07 Oct 2025 09:44:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1759830228928/fb0aefeb-01f9-4269-856a-3816fa1d9151.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone! Welcome to a new blog post. In this one, we will discuss the notion of quantum key distribution and its first kind scheme: the BB84 protocol.</p>
<h1 id="heading-key-exchange">Key Exchange</h1>
<h2 id="heading-what-is-it-and-why-is-it-important">What is it and why is it important?</h2>
<p>Key exchange is the process of securely sharing cryptographic keys between parties who wish to communicate securely over an insecure channel, such as the internet. These keys are used to encrypt and decrypt messages, ensuring that only the intended recipients can read the information.</p>
<p>Key exchange is important because it forms the foundation of secure communication in various contexts, including online banking, e-commerce transactions, secure messaging applications, and more. Without a secure method of exchanging keys, sensitive information could be intercepted and read by unauthorized parties, leading to privacy breaches, financial losses, and other serious consequences.</p>
<p>By securely exchanging keys, parties can establish a shared secret that enables them to communicate confidentially and authenticate each other's identities. This ensures the confidentiality, integrity, and authenticity of the transmitted data, safeguarding it from eavesdroppers and malicious attackers.</p>
<h2 id="heading-diffie-hellman-key-exchange-algorithm">Diffie-Hellman Key Exchange Algorithm</h2>
<p><strong>Diffie-Hellman (DH) key exchange</strong> is a mathematical method of securely exchanging cryptographic keys over a public channel and named after <a target="_blank" href="https://en.wikipedia.org/wiki/Whitfield_Diffie">Whitfield Diffie</a> and <a target="_blank" href="https://en.wikipedia.org/wiki/Martin_Hellman">Martin Hellman</a>.</p>
<p>Traditionally, secure encrypted communication required that they first exchange keys by some secure physical ways like papers. The Diffie-Hellman key exchange method allows two parties with no prior knowledge of each other to establish a shared secret key over an insecure channel.</p>
<h3 id="heading-how-it-works">How it works?</h3>
<p>The original implementation uses a multiplicative group structure over integers modulo \(p\), where \(p\) is a prime and \(g\) is a primitive root modulo \(p\).</p>
<ol>
<li><p>Alice and Bob publicly agree to use a modulus \(p\) and base \(g\).</p>
</li>
<li><p>Alice chooses a private integer \(a\), then sends Bob \(A = g^a \ mod \ p\).</p>
</li>
<li><p>Bob chooses a private integer \(b\), then sends Alice \(B = g^b \ mod \ p\).</p>
</li>
<li><p>Alice computes \(s = B^a \ mod \ p\).</p>
</li>
<li><p>Bob computes \(s = A^b \ mod \ p\).</p>
</li>
</ol>
<p>Alice and Bob now share a secret, the number \(s\).</p>
<h3 id="heading-example">Example</h3>
<ol>
<li><p>Let \(p = 23\) and \(g = 5\).</p>
</li>
<li><p>Alice chooses a secret \(a = 4\) and sends Bob \(A = 5^4 \ mod \ 23 = 4\).</p>
</li>
<li><p>Bob chooses a secret \(b = 3\) and sends Alice \(B = 5^3 \ mod \ 23 = 10\).</p>
</li>
<li><p>Alice computes \(s = 10^4 \ mod \ 23 = 18.\)</p>
</li>
<li><p>Bob computes \(s = 4^3 \ mod \ 23 = 18\).</p>
</li>
</ol>
<p>Alice and Bob have the same secret: \(18\).</p>
<h2 id="heading-whats-wrong-with-dh">What's wrong with DH?</h2>
<p>The security of traditional Diffie-Hellman key exchange relies on the difficulty of computing discrete logarithms, which is the process of finding the exponent in the equation \(g^x = y \ mod \ p\). However, quantum computers have the potential to efficiently solve the discrete logarithm problem using algorithms like Shor's algorithm. So traditional Diffie-Hellman key exchange is not quantum-resistant.</p>
<hr />
<h1 id="heading-introduction-to-quantum-mechanics">Introduction to Quantum Mechanics</h1>
<h2 id="heading-what-is-it">What is it?</h2>
<p>Quantum mechanics is a branch of physics that dealing with the behavior of matter and light on the atomic and subatomic scale. It aims to explain and understand the characteristics of molecules and atoms, as well as their components—electrons, protons, neutrons, and other particles like quarks and gluons. These characteristics encompass how these particles interact with each other and with electromagnetic radiation, such as light, X-rays, and gamma rays.</p>
<h2 id="heading-postulates-of-quantum-mechanics">Postulates of Quantum Mechanics</h2>
<ol>
<li><p>The state of a quantum system is completely described by a wave function, denoted as \(\psi(x, t)\), which encodes all the probabilistic information about the system's properties.</p>
</li>
<li><p>The evolution over time of the wave function of a quantum system is determined by the Schrödinger equation, a linear partial differential equation:</p>
</li>
</ol>
<p>$$i \hbar \frac{\partial \psi}{\partial t} = \left[ - \frac{\hbar^2}{2m} \frac{\partial^2}{\partial x^2} + V(x) \right] \psi.$$</p><ol start="3">
<li>Physical quantities, or observables, such as energy, position, and momentum, are represented by operators in quantum mechanics. These operators act on the wave function to extract physical information:</li>
</ol>
<p>$$\hat{H} \psi = E\psi.$$</p><ol start="4">
<li>The act of measurement affects the system being measured. The only possible outcome of measuring a quantifiable property (observable) of a quantum system is one of the eigenvalues of the corresponding operator. Upon measurement, the wave function of the system collapses to an eigenstate associated with the eigenvalue.</li>
</ol>
<h2 id="heading-heisenbergs-uncertainty-principle">Heisenberg's Uncertainty Principle</h2>
<p>One of the most famous aspects of quantum mechanics is the Heisenberg Uncertainty Principle. Formulated by Werner Heisenberg in 1927, this principle states that certain pairs of physical properties, like position and momentum, cannot both be precisely measured or known simultaneously. The more precisely one property is measured, the less precisely the other can be controlled or known. This is not due to faults in measurement instruments, but rather a fundamental property of quantum systems.</p>
<p>Mathematically, the principle is expressed as:</p>
<p>$$\Delta x \Delta p \geq \frac{\hbar}{2}$$</p><p>where \(\Delta x\) and \(\Delta p\) are the standard deviations of position and momentum, respectively, and \(\hbar\) (h-bar) is the reduced Planck constant.</p>
<p>This principle has very significant implications for the nature of reality and our understanding of the universe, indicating a fundamental limit to what we can know about the properties of particles.</p>
<p>These concepts of quantum mechanics are not just theoretical curiosities but have practical applications, particularly in the field of quantum computing and quantum cryptography, where they enable technologies that would be impossible under classical physics.</p>
<hr />
<h1 id="heading-quantum-key-distribution">Quantum Key Distribution</h1>
<h2 id="heading-what-is-it-1">What is it?</h2>
<p>Quantum Key Distribution (QKD) is an unusual approach in secure communication, utilizing principles of quantum mechanics to generate and share cryptographic keys between parties with guaranteed security. The underlying strength of QKD lies in the fundamental aspects of quantum mechanics, such as the Heisenberg Uncertainty Principle and the no-cloning theorem..</p>
<p>QKD allows two parties to produce a shared random secret key known only to them, which can then be used to encrypt and decrypt messages. What makes QKD unique from traditional cryptographic systems is its ability to alert both parties to the presence of any third party trying to gain knowledge of the key. This security feature stems from the principle that measuring quantum data invariably alters it. Thus, an eavesdropper trying to intercept the key would cause detectable disturbances in the system, alerting the legitimate parties to the breach.</p>
<p>It is worth noting that quantum key distribution is used to generate and distribute only a key, not to send / receive any message data. But such a key can be used within any chosen encryption scheme.</p>
<h2 id="heading-the-bb84-protocol">The BB84 Protocol</h2>
<p>The <strong>BB84 protocol</strong>, proposed in 1984 by Charles Bennett and Gilles Brassard, is the first and most well-known Quantum Key Distribution scheme. Its security relies on two fundamental principles of quantum mechanics:</p>
<ol>
<li><p><strong>The impossibility of measuring a quantum state without disturbing it</strong> (Heisenberg Uncertainty Principle).</p>
</li>
<li><p><strong>The no-cloning theorem</strong>, which states that it is impossible to create an identical copy of an unknown quantum state.</p>
</li>
</ol>
<p>The protocol allows two parties, commonly called <strong>Alice</strong> and <strong>Bob</strong>, to generate a shared random key in a way that any eavesdropping attempt by an adversary (<strong>Eve</strong>) is detectable.</p>
<h3 id="heading-step-1-preparation-and-transmission">Step 1: Preparation and Transmission</h3>
<p>Alice prepares a sequence of <strong>quantum bits (qubits)</strong>, each encoded using one of two <strong>bases</strong>:</p>
<ul>
<li><p><strong>Rectilinear basis (+)</strong>: \(|0⟩\) and \(|1⟩\)</p>
</li>
<li><p><strong>Diagonal basis (×)</strong>: \(|+⟩\) and \(|-⟩\), where</p>
</li>
</ul>
<p>$$|+⟩ = \frac{|0⟩ + |1⟩}{\sqrt{2}}, \quad |−⟩ = \frac{|0⟩ - |1⟩}{\sqrt{2}}.$$</p><p>For each bit in a randomly generated string, Alice chooses <strong>(a)</strong> a random bit value (0 or 1), and <strong>(b)</strong> a random basis (rectilinear or diagonal). She then sends the corresponding qubits to Bob through a quantum channel.</p>
<h3 id="heading-step-2-measurement">Step 2: Measurement</h3>
<p>For each received qubit, Bob also chooses a random basis (rectilinear or diagonal) to measure it. Because his choice might not match Alice’s, some measurements will be “wrong” (i.e., produce random results). Importantly, Bob does not inform Alice of his measurement results yet—only the bases he used.</p>
<h3 id="heading-step-3-basis-reconciliation">Step 3: Basis Reconciliation</h3>
<p>After the quantum transmission is complete, Alice and Bob communicate over a <strong>classical public channel</strong> (which can be eavesdropped on, but not modified).</p>
<ul>
<li><p>Bob announces the basis he used for each bit.</p>
</li>
<li><p>Alice tells Bob which of his bases matched hers.</p>
</li>
</ul>
<p>They then <strong>discard all bits</strong> where their bases were different. The remaining bits (where both chose the same basis) form the <strong>raw key</strong>.</p>
<h3 id="heading-step-4-eavesdropping-detection">Step 4: Eavesdropping Detection</h3>
<p>To check for eavesdropping, Alice and Bob publicly compare a randomly chosen subset of their raw key. If the error rate is above a certain threshold, they assume Eve has intercepted the qubits (since her measurements would have disturbed the states) and <strong>abort</strong> the protocol.</p>
<p>If the error rate is below the threshold, they proceed, discarding the revealed bits and keeping the rest.</p>
<h3 id="heading-step-5-error-correction-and-privacy-amplification">Step 5: Error Correction and Privacy Amplification</h3>
<p>The raw key may still contain a small number of errors due to noise in the quantum channel. Alice and Bob use classical <strong>error correction protocols</strong> to reconcile their keys. Finally, they apply <strong>privacy amplification</strong> techniques to reduce Eve’s possible knowledge to an arbitrarily small amount, yielding the <strong>final secret key</strong>.</p>
<p>This final key can then be used in any symmetric encryption scheme (e.g., One-Time Pad or AES), with the guarantee that any eavesdropping attempt would have been noticed during the protocol.</p>
<hr />
<h2 id="heading-conclusion">Conclusion</h2>
<p>Quantum Key Distribution represents a fundamental shift in how we think about secure communication. Rather than relying on computational assumptions like the hardness of discrete logarithms or factoring, QKD leverages the laws of physics to guarantee security. It is also worth noting that it is more of a complementary method instead of a replacement.</p>
<p>The BB84 protocol is a particularly elegant demonstration of this idea: even if an adversary has infinite computational power, they cannot extract information about the key without introducing detectable disturbances. While real-world implementation still faces technical challenges—such as channel noise, distance limitations, and cost—QKD systems are already being deployed in some specialized networks around the world.</p>
<p>As quantum computers advance and threaten traditional public-key cryptosystems, QKD provides a complementary path forward.</p>
]]></content:encoded></item><item><title><![CDATA[Ciphertext Compression in TFHE]]></title><description><![CDATA[Let’s recall LWE!
What is it?
In cryptography, Learning-With-Errors (LWE) is a mathematical problem that is widely used to create secure encryption algorithms.
Let \(\mathbb{Z}_q\) denote the ring of ]]></description><link>https://furkanakal.com/ciphertext-compression-tfhe-digest-1</link><guid isPermaLink="true">https://furkanakal.com/ciphertext-compression-tfhe-digest-1</guid><category><![CDATA[ciphertext]]></category><category><![CDATA[compression]]></category><category><![CDATA[Cryptography]]></category><category><![CDATA[fhe]]></category><dc:creator><![CDATA[Furkan Akal]]></dc:creator><pubDate>Fri, 27 Dec 2024 18:22:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1734365980784/f5f46cd1-2ef2-4f13-b142-d2bde634b700.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Let’s recall LWE!</h1>
<h2>What is it?</h2>
<p>In cryptography, <strong>Learning-With-Errors</strong> (<strong>LWE</strong>) is a mathematical problem that is widely used to create secure encryption algorithms.</p>
<p>Let \(\mathbb{Z}_q\) denote the ring of integers module \(q\) and \(\mathbb{Z}_q^n\) denote the set of \(n\)-vectors over \(\mathbb{Z}_q\). There exists a certain unknown linear function \(f: \mathbb{Z}_q^n \rightarrow \mathbb{Z_q}\), and the input to the LWE problem is a sample of pairs </p>
<p>The Learning-With-Errors (LWE) problem presents a computational challenge where solving linear equations becomes difficult due to added noise. Essentially, LWE relies on the idea that when linear equations over a finite field are slightly altered with random errors, finding the solution becomes computationally hard. This approach uses the difficulty of telling apart random noise from structured data to create cryptographic systems that are secure against quantum attacks. The noise is crucial because it hides the connection between the input vectors and their outputs, making it hard to deduce the secret linear function.</p>
<h2>LWE Encryption</h2>
<p>In the context of LWE-based encryption, the security model revolves around the difficulty of solving the LWE problem. The encryption scheme is constructed around a public and a private key, where the public key is derived from the private key with the addition of noise. This ensures that, while encryption can be performed by anyone possessing the public key, decryption is feasible only with the knowledge of the private key. The essence of this encryption lies in its ability to mask the message with a layer of computational complexity that is impractical to breach without the private key, thus ensuring confidentiality.</p>
<p>To encrypt an encoded message \(m\), we calculate:</p>
<p>$$b = \mathbf{a} \cdot \mathbf{s} + m + \epsilon$$</p>
<p>where \(\mathbf{a} \leftarrow_R \mathbb{Z}^n\) is a randomness, \(\mathbf{s} \in \mathbb{Z}^n\) is our secret key, and \(\epsilon \in \chi\) is a small noise.</p>
<hr />
<h1>LWE on the Torus (TLWE)</h1>
<h2>What is the torus in our context?</h2>
<p>Real torus \(\mathbb{T} = \mathbb{R}/\mathbb{Z}\) is basically the set</p>
<p>In TFHE, we’re working on \(\mathbb{T}_q\), which can be represented as the set of fractions:</p>
<p>$${ \frac{i}{q} \ \text{mod} \ 1 \ | \ i \in \mathbb{Z} } = { \frac{i}{q} \ | \ i \in \mathbb{Z}/q\mathbb{Z} } = { 0, \frac{1}{q}, \frac{2}{q}, ... , \frac{q-1}{q} }$$</p>
<p>This submodule \(\mathbb{T}_q\) is called a <strong>discretized torus.</strong></p>
<hr />
<h1>TLWE Ciphertexts</h1>
<h2>Encryption</h2>
<p>The security assumption for TLWE is that a torus element</p>
<p>Basically, to encrypt a message \(m\) with TLWE, we calculate</p>
<p>$$b = \sum_i^n s_i \cdot a_i + m + \epsilon$$</p>
<p>where</p>
<p>Similar to the case in the regular LWE, a TLWE ciphertext is of the form:</p>
<p>$$(a_1, a_2, ..., a_n, b) \in \mathbb{T}_q^{n+1}$$</p>
<h2>Decryption</h2>
<p>To decrypt a TLWE ciphertext</p>
<p>$$m^* = b - \sum_i^n s_i \cdot a_i$$</p>
<p>and return</p>
<p>$$m = \frac{\lfloor q \ m^* \rceil \text{mod} \ q}{q}$$</p>
<h2>Plaintext &amp; Ciphertext Spaces</h2>
<p>In most cases, the plaintext and ciphertext spaces are distinct, where the plaintext space is an additive subgroup of \(\mathbb{T}_q\).</p>
<p>We, conventionally denote the plaintext space modulus by \(p\), the ciphertext space modulus by \(q\).</p>
<h2>Example</h2>
<p>Let’s assume \(p = 4\) and \(q = 64\). So, the plaintext space is \(P  =  {0, \frac{1}{4}, \frac{2}{4}, \frac{3}{4}}\), where the ciphertext space is \(Q = \mathbb{T}_{64} = { 0, \frac{1}{64}, \frac{2}{64}, ..., \frac{62}{64}, \frac{63}{64} }\).</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734392011387/79a6ac44-8908-4cec-890d-0540c67deab5.png" alt="(Joye, 2022)" style="display:block;margin:0 auto" />

<p>Notice that if \(\epsilon \in {\frac{-7}{64}, ..., \frac{7}{64}}\), then any noisy message value \(m^* = m + \epsilon\) corresponds to a plaintext message \(m \in P = { 0, \frac{16}{64}, \frac{32}{64}, \frac{48}{64} }\).</p>
<p>Hence, while decrypting, we determine which zone in the plaintext space the noisy message falls into. For example, the closest plaintext message to \(m^* \in { \frac{9}{64}, ..., \frac{23}{64} }\) is \(m = \frac{16}{64} = \frac{1}{4}\).</p>
<hr />
<h1>Ciphertext Compression</h1>
<h2>Compressing Ciphertexts in TFHE.rs</h2>
<p>TFHE.rs lets developers compress ciphertexts at encryption time by calling the <code>CompressedFheUint16::try_encrypt()</code> method:</p>
<pre><code class="language-rust">use tfhe::prelude::*;
use tfhe::{ConfigBuilder, generate_keys, CompressedFheUint16};

fn main() {
    let config = ConfigBuilder::default().build();
    let (client_key, _) = generate_keys(config);

    let clear = 12_837u16;
    let compressed = CompressedFheUint16::try_encrypt(clear, &amp;client_key).unwrap();
    println!(
        "compressed size  : {}",
        bincode::serialize(&amp;compressed).unwrap().len()
    );
    
    let decompressed = compressed.decompress();
    
    println!(
        "decompressed size: {}",
        bincode::serialize(&amp;decompressed).unwrap().len()
    );

    let clear_decompressed: u16 = decompressed.decrypt(&amp;client_key);
    assert_eq!(clear_decompressed, clear);
}
</code></pre>
<h2>How does it work?</h2>
<p>Recall that TLWE ciphertexts are torus vectors with \(n+1\) components.</p>
<p>If we suppose that torus elements are represented with 64 bits where \(n = 630\), a TLWE ciphertext requires</p>
<p>$$631 \times 64 = 40384 \ \text{bits}$$</p>
<p>for its representation.</p>
<p>Instead of representing a ciphertext as</p>
<p>With this setup, the same ciphertext only needs \(128 + 64 = 192\) bits for its representation.</p>
<p>As we use a pseudo-random number generator, we are able to recover our random vector \(a\) deterministically. So, it makes more sense to store the PRNG seed instead of storing the entire randomness. Hence, the ciphertext compression decreases the storage overhead drastically.</p>
<hr />
<h3>References</h3>
<ol>
<li><p>Joye, M. (2022). SoK: Fully homomorphic encryption over the [discretized] torus. <em>IACR Transactions on Cryptographic Hardware and Embedded Systems, 2022</em>(4), 661–692. <a href="https://doi.org/10.46586/tches.v2022.i4.661-692">https://doi.org/10.46586/tches.v2022.i4.661-692</a></p>
</li>
<li><p>Zama AI. (n.d.). <em>Compress</em>. TFHE.rs Fundamentals. Retrieved December 27, 2024, from <a href="https://docs.zama.ai/tfhe-rs/fundamentals/compress">https://docs.zama.ai/tfhe-rs/fundamentals/compress</a></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Exploring Zama: Building Confidential Smart Contracts w/ fhEVM]]></title><description><![CDATA[Before starting, it is worth noting that this is NOT a paid content.

Hello everyone! Welcome to the new post of my blog. Normally, I'm creating two types content:

protocol exploration posts from a developer's perspective and

cryptography posts exp...]]></description><link>https://furkanakal.com/exploring-zama</link><guid isPermaLink="true">https://furkanakal.com/exploring-zama</guid><category><![CDATA[zama ]]></category><category><![CDATA[fhe]]></category><category><![CDATA[fhevm]]></category><category><![CDATA[Homomorphic Encryption]]></category><category><![CDATA[Solidity]]></category><dc:creator><![CDATA[Furkan Akal]]></dc:creator><pubDate>Fri, 01 Mar 2024 19:10:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1709223111387/d3cc2a05-a4b2-445b-9498-a10c124c081c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><strong>Before starting, it is worth noting that this is NOT a paid content.</strong></p>
</blockquote>
<p>Hello everyone! Welcome to the new post of my blog. Normally, I'm creating two types content:</p>
<ol>
<li><p>protocol exploration posts from a developer's perspective and</p>
</li>
<li><p>cryptography posts explaining mathematical concepts and their applications.</p>
</li>
</ol>
<p>In this post, I'll try to combine both. We'll explore <a target="_blank" href="https://zama.ai/">Zama</a> protocol and the cryptographic concept they utilize: <strong>fully homomorphic encryption (FHE)</strong>.</p>
<h1 id="heading-contents">Contents</h1>
<ol>
<li><p>Fully Homomorphic Encryption (FHE)</p>
<ol>
<li><p>What does "homomorphic" mean?</p>
</li>
<li><p>Group Homomorphisms</p>
<ol>
<li>Example</li>
</ol>
</li>
<li><p>Homomorphic Encryption</p>
<ol>
<li><p>Overview</p>
</li>
<li><p>RSA, Revisited</p>
</li>
</ol>
</li>
<li><p>Then, what is FHE?</p>
</li>
</ol>
</li>
<li><p>What is Zama?</p>
<ol>
<li><p>Introduction</p>
</li>
<li><p>fhEVM</p>
<ol>
<li><p>Overview</p>
</li>
<li><p>How it works?</p>
</li>
<li><p>Use Cases</p>
</li>
</ol>
</li>
</ol>
</li>
<li><p>Building Confidential Smart Contracts</p>
<ol>
<li><p>Encrypted Types</p>
</li>
<li><p>Operations on Encrypted Types</p>
</li>
<li><p>Decryption &amp; Reencryption</p>
</li>
</ol>
</li>
<li><p>Conclusion</p>
</li>
</ol>
<hr />
<h1 id="heading-fully-homomorphic-encryption">Fully Homomorphic Encryption</h1>
<h2 id="heading-what-does-homomorphic-mean">What does "homomorphic" mean?</h2>
<p>The term "homomorphic" emerges from the Greek roots 'homos' (same) and 'morphē' (shape or form). In the context of mathematics, it pertains to the property of a mapping between two algebraic structures (such as groups, rings, or fields) that conserves operations between those structures. This means that operations conducted on transformed data can, after reverting the data back to its original form, yield identical results to those obtained from performing operations on the original data directly.</p>
<h2 id="heading-group-homomorphisms">Group Homomorphisms</h2>
<p>To understand the notion of homomorphism, let's see how they work in groups.</p>
<blockquote>
<p>Let \(G\) and \(H\) be groups and \(f: G \rightarrow H\) is a mapping (function). \(f\) is called a "group homomorphism" if \(f(g_1 \cdot_G g_2) = f(g_1) \cdot_H f(g_2) \ \forall g_1, g_2 \in G.\)</p>
</blockquote>
<p>The purpose here is to create some functions preserving the algebraic structure.</p>
<h3 id="heading-example">Example</h3>
<p>The function \(f: (\mathbb{N}, +) \rightarrow (\mathbb{R}, +)\) be defined by \(f(x) = \sqrt{2}x\). Notice that both \((\mathbb{N}, +)\) and \((\mathbb{R}, +)\) are groups. Let's check if \(f\) is a group homomorphism, or not.</p>
<p>Take two elements from the first group: \(n_1,n_2 \in \mathbb{N}\). It is time to see if the homomorphism axiom is satisfied:</p>
<p>$$f(n_1 + n_2) = \sqrt{2} \ (n_1 + n_2)$$</p><p>$$f(n_1 + n_2) = \sqrt{2} \ n_1 + \sqrt{2} \ n_2$$</p><p>$$f(n_1 + n_2) = f(n_1) + f(n_2).$$</p><p>Hence, \(f\) is a group homomorphism.</p>
<p>I hope this simple example helped you to understand the concept better.</p>
<h2 id="heading-homomorphic-encryption">Homomorphic Encryption</h2>
<h3 id="heading-overview">Overview</h3>
<p>Homomorphic encryption is a form of encryption that allows computations to be performed on ciphertexts, generating an encrypted result which, when decrypted, matches the result of operations performed on the plaintext. This property makes homomorphic encryption highly valuable for privacy-preserving computations, allowing sensitive data to be encrypted and processed without exposing it to the computing entity.</p>
<p>But the ones being discussed in this section are partially homomorphic encryption methods. This type supports either addition or multiplication on ciphertexts, but not both.</p>
<p>For example, the RSA encryption scheme is homomorphic with respect to multiplication.</p>
<h3 id="heading-rsa-revisited">RSA, Revisited</h3>
<p>If you are not familiar with the RSA encryption scheme, you can take a look at my <a target="_blank" href="https://furkanakal.com/part-3-public-private-keys-rsa-encryption-public-key-cryptography">RSA post</a>.</p>
<p>Recall that, in RSA, encryption process takes the public key parameters \((N, e)\) as modulus and exponent, respectively. So if we have a message \(m\) to encrypt, the ciphertext corresponds to that is calculated in the following way:</p>
<p>$$c = m^e \ (mod \ N)$$</p><p>where \(c\) is the ciphertext.</p>
<p>Let's now assume we have two different messages \(m_1\) and \(m_2\).</p>
<p>$$Enc(m_1 \cdot m_2) = (m_1 \cdot m_2)^e$$</p><p>$$Enc(m_1 \cdot m_2) = m_1^e \cdot m_2^e$$</p><p>$$Enc(m_1 \cdot m_2) = Enc(m_1) \cdot Enc(m_2)$$</p><p>Therefore, the RSA encryption scheme is homomorphic with respect to multiplication.</p>
<blockquote>
<p>Notice that it is NOT homomorphic with respect to addition.</p>
</blockquote>
<h2 id="heading-then-what-is-fhe">Then, what is FHE?</h2>
<p>A cryptosystem that supports arbitrary computation on ciphertexts is known as fully homomorphic encryption (FHE). As computations can be expressed as arithmetic circuits (addition &amp; multiplication), it allows to do computations on ciphertexts in an unlimited way.</p>
<hr />
<h1 id="heading-what-is-zama">What is Zama?</h1>
<h2 id="heading-introduction">Introduction</h2>
<p><a target="_blank" href="https://docs.zama.ai/homepage/">Zama</a> is an open source cryptography company building fully homomorphic encryption solutions for blockchain and AI.</p>
<p>As the backbone of artificial intelligence efforts is data (a huge amount of data), a couple of possible problems, such as privacy and confidentiality, may arise. That's why I personally think that combining FHE and AI is quite relevant.</p>
<p>Zama has a couple of products:</p>
<ul>
<li><p><a target="_blank" href="https://docs.zama.ai/tfhe-rs"><strong>TFHE-rs</strong></a><strong>:</strong> Rust implementation of TFHE for boolean and small integer arithmetics over encrypted data.</p>
</li>
<li><p><a target="_blank" href="https://docs.zama.ai/concrete"><strong>Concrete</strong></a><strong>:</strong> TFHE compiler that converts Python programs into their FHE equivalent.</p>
</li>
<li><p><a target="_blank" href="https://docs.zama.ai/concrete-ml"><strong>Concrete ML</strong></a><strong>:</strong> Privacy-preserving ML framework built on top of Concrete, with bindings to traditional ML frameworks.</p>
</li>
<li><p><a target="_blank" href="https://docs.zama.ai/fhevm"><strong>fhEVM</strong></a><strong>:</strong> Confidential smart contracts on the EVM using homomorphic encryption.</p>
</li>
</ul>
<p>Even though I'm planning to write another post on TFHE-rs, in this one, we will focus on <strong>fhEVM</strong>.</p>
<h2 id="heading-fhevm">fhEVM</h2>
<h3 id="heading-overview-1">Overview</h3>
<p>While the transparency provided by blockchains is beneficial in some ways, privacy is necessary at certain points. For instance, you may not want your investments to be public to everyone. Zama, intentionally, preserves one of the key benefits of transparency on blockchains: the computation carried out remains public, while only the data that is being computed on is hidden.</p>
<p>The good news is that fhEVM contracts are built using Solidity, along with some additional types. So they offer a smooth transition for regular smart contract developers.</p>
<h3 id="heading-how-it-works">How it works?</h3>
<h4 id="heading-global-fhe-key">Global FHE Key</h4>
<p>First of all, fhEVM is a <a target="_blank" href="https://en.wikipedia.org/wiki/Threshold_cryptosystem">threshold cryptographic</a> system (I'm planning to write a particular blog post on threshold cryptography btw.) where content is encrypted using the global public key and the private (secret) key is distributed among validators. If more validators than the threshold agrees on decrypting the encrypted content, the key is combined and decryption is executed.</p>
<p>Zama fhEVM relies on a global FHE key under which all inputs and private states are encrypted. This makes it enable both trustlessness and fault-tolerance.</p>
<h4 id="heading-input-encryption">Input Encryption</h4>
<p>In order to provide an encrypted input to a transaction or view function, users are required to submit two things to a smart contract:</p>
<ol>
<li><p>intended input value encrypted using the global public FHE key (ciphertext),</p>
</li>
<li><p>corresponding zero-knowledge proof of the plaintext knowledge (ZKPoK).</p>
</li>
</ol>
<p>The second value is needed, because users have to prove if they actually know the underlying plaintext message. Thanks to ZKPoK, produced ciphertext cannot be used in another context. \((Enc_{pk}(m), ZKPoK(M))\) pair is called <strong>certified ciphertext</strong>.</p>
<p>The receiving smart contract needs fhEVM to verify certified ciphertext.</p>
<h3 id="heading-use-cases">Use Cases</h3>
<h4 id="heading-encrypted-erc-20-tokens">Encrypted ERC-20 Tokens</h4>
<p>Existence of such a standard is important for blockchains. However, by the public nature of blockchain systems, the individual balances of ERC-20 token holders are public and this may lead some security and privacy concerns.</p>
<p>Because the fhEVM allows for the use of encrypted values in smart contracts, we can create an encrypted version of the ERC-20 token standard. To do so, it suffices to change the data type of balances from integers to <strong>encrypted integers</strong> and replace each operation with their respective FHE counterpart.</p>
<h4 id="heading-blind-auctions">Blind Auctions</h4>
<p>Blind auctions enable bidders to submit their bids in private, ensuring that no one knows the bid amounts. Once the bidding period ends, the highest bidder is determined and announced as the winner.</p>
<p>These auctions can be seamlessly conducted on-chain using encrypted values. By utilizing an encrypted ERC-20 token, bidders can transfer an encrypted amount to the blind auction smart contract. This contract then compares the bids to identify and announce the winner.</p>
<hr />
<h1 id="heading-building-confidential-smart-contracts">Building Confidential Smart Contracts</h1>
<h2 id="heading-encrypted-types">Encrypted Types</h2>
<p>The Solidity TFHE library provides encrypted integer types and a type system that is checked both at compile time and at runtime:</p>
<ul>
<li><p><code>euint8</code>,</p>
</li>
<li><p><code>euint16</code>,</p>
</li>
<li><p><code>euint32</code>.</p>
</li>
</ul>
<p>In the fhEVM implementation, encrypted integers are represented as FHE ciphertexts. The TFHE library simplifies this by offering ciphertext handles to smart contract developers.</p>
<p>When a smart contract receives a certified ciphertext from a user, it must verify its corresponding proof. To do so, it converts the input into a usable <code>euint</code> by calling <code>TFHE.asEuint</code>. For example,</p>
<ul>
<li><p><code>TFHE.asEuint8(bytes ciphertext)</code> verifies the provided ciphertext and returns an <code>euint8</code>,</p>
</li>
<li><p><code>TFHE.asEuint16(bytes ciphertext)</code> verifies the provided ciphertext and returns an <code>euint16</code>,</p>
</li>
<li><p><code>TFHE.asEuint32(bytes ciphertext)</code> verifies the provided ciphertext and returns an <code>euint32</code>,</p>
</li>
<li><p><code>TFHE.asEbool(bytes ciphertext)</code> verifies the provided ciphertext and returns an <code>ebool</code>.</p>
</li>
</ul>
<p>If the verification is successful, then the fhEVM returns an encrypted value that is ready to use by the smart contract. If not, then execution is reverted.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-solidity"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">verify</span>(<span class="hljs-params">
    <span class="hljs-keyword">bytes</span> <span class="hljs-keyword">calldata</span> _amount
</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params">euint32</span>) </span>{
    euint32 amount <span class="hljs-operator">=</span> TFHE.asEuint32(_amount);

    <span class="hljs-keyword">return</span> amount;
}
</code></pre>
<h2 id="heading-encrypted-operations">Encrypted Operations</h2>
<p>The fhEVM provides different operations on encrypted data types. These operations are carried out by calling a precompiled smart contract, which then uses the TFHE-rs library.</p>
<p>Some of them are as follows:</p>
<ul>
<li><p><strong>addition:</strong><code>TFHE.add()</code>,</p>
</li>
<li><p><strong>subtraction:</strong><code>TFHE.sub()</code>,</p>
</li>
<li><p><strong>multiplication:</strong><code>TFHE.mul()</code>,</p>
</li>
<li><p><strong>isEqual:</strong><code>TFHE.eq()</code>,</p>
</li>
<li><p><strong>isNotEqual:</strong><code>TFHE.ne()</code>,</p>
</li>
<li><p><strong>greaterThan:</strong><code>TFHE.gt()</code>,</p>
</li>
<li><p><strong>lessThan:</strong><code>TFHE.lt()</code>,</p>
</li>
<li><p><strong>decrypt:</strong><code>TFHE.decrypt()</code>,</p>
</li>
<li><p><strong>reencrypt:</strong><code>TFHE.reencrypt()</code>.</p>
</li>
</ul>
<p>If you want to see the full list, see the <a target="_blank" href="https://docs.zama.ai/fhevm/how-to/operations">official docs</a>.</p>
<p><strong>Example 1:</strong></p>
<p>Let us see how to perform a basic computation on encrypted integers:</p>
<pre><code class="lang-solidity"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">arithmetic</span>(<span class="hljs-params">
    euint32 x,
    euint32 y,
    euint32 z
</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params">euint32</span>) </span>{
    <span class="hljs-keyword">return</span> TFHE.mul(TFHE.add(x, y), z);
}
</code></pre>
<p>This code basically takes 3 encrypted integers \(x, y, z\) and performs the following calculation:</p>
<p>$$(x+y) \cdot z.$$</p><p><strong>Example 2:</strong></p>
<p>Now, let's try to write down a <code>transfer()</code> function where the required balance is checked on an encrypted data:</p>
<pre><code class="lang-solidity"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">transfer</span>(<span class="hljs-params">
    <span class="hljs-keyword">address</span> <span class="hljs-keyword">from</span>,
    <span class="hljs-keyword">address</span> to,
    euint32 amount
</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
    ebool condition <span class="hljs-operator">=</span> TFHE.lte(amount, balances[<span class="hljs-keyword">from</span>]);
    <span class="hljs-built_in">require</span>(TFHE.decrypt(condition));

    balances[<span class="hljs-keyword">from</span>] <span class="hljs-operator">=</span> TFHE.sub(balances[<span class="hljs-keyword">from</span>], amount);
    balances[to] <span class="hljs-operator">=</span> TFHE.add(balances[to], amount);
}
</code></pre>
<p>The code takes three inputs:</p>
<ul>
<li><p><code>from</code>: sender's address,</p>
</li>
<li><p><code>to</code>: recipient's address,</p>
</li>
<li><p><code>amount</code>: transfer amount;</p>
</li>
</ul>
<p>and checks if sender has sufficient balance by decrypting the <code>ebool</code>.</p>
<h2 id="heading-decryption-amp-reencryption">Decryption &amp; Reencryption</h2>
<p>Just as we did in the example above, the fhEVM allows explicit decryption requests for any encrypted type. As discussed, the values are decrypted with the global private key if the threshold is exceeded.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-solidity"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getTotalSupply</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint32</span></span>) </span>{
    <span class="hljs-keyword">return</span> TFHE.decrypt(totalSupply);
}
</code></pre>
<p>This function takes encrypted <code>totalSupply</code> variable and returns its decrypted version.</p>
<p>Zama fhEVM also supports <strong>reencrypting</strong>. In this process, the ciphertext is first decrypted with the global private key. Next, the decrypted data is encrypted again using a public key provided by the user. This newly encrypted data is then returned to the person who requested it.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-solidity"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">balanceOf</span>(<span class="hljs-params">
    <span class="hljs-keyword">bytes32</span> publicKey,
</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bytes</span> <span class="hljs-keyword">memory</span></span>) </span>{
    <span class="hljs-keyword">return</span> TFHE.reencrypt(balances[<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>], publicKey);
}
</code></pre>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In wrapping up, Zama's fhEVM introduces a new way to ensure privacy in blockchain through fully homomorphic encryption. It keeps the transparency and trust blockchain is known for, while adding a layer of privacy where it's needed. This step forward in combining privacy with transparency opens up new possibilities for blockchain applications, making it an important development for those looking to balance openness with confidentiality.</p>
]]></content:encoded></item><item><title><![CDATA[secp256k1 Curve | Fundamentals & Key-Pair Generation]]></title><description><![CDATA[Hello everyone! Welcome to the new post of my blog. In this one, I'll try to cover the secp256k1 elliptic curve and key-generation process based on it. In the upcoming parts, we will discuss; signature generation & verification on secp256k1 and accou...]]></description><link>https://furkanakal.com/secp256k1-curve-part-1-fundamentals-key-pair-generation</link><guid isPermaLink="true">https://furkanakal.com/secp256k1-curve-part-1-fundamentals-key-pair-generation</guid><category><![CDATA[secp256k1]]></category><category><![CDATA[elliptic curve cryptography]]></category><category><![CDATA[Cryptography]]></category><category><![CDATA[public-key cryptgraphy]]></category><category><![CDATA[crypto]]></category><dc:creator><![CDATA[Furkan Akal]]></dc:creator><pubDate>Thu, 29 Feb 2024 15:54:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1709209858398/8f0148ff-cbaf-45a0-b493-98799da812e2.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone! Welcome to the new post of my blog. In this one, I'll try to cover the <strong>secp256k1</strong> elliptic curve and key-generation process based on it. In the upcoming parts, we will discuss; signature generation &amp; verification on secp256k1 and account (address) generation using secp256k1.</p>
<h1 id="heading-contents">Contents</h1>
<ol>
<li><p>Elliptic Curves, Revisited</p>
<ol>
<li>What was an elliptic curve, again?</li>
</ol>
</li>
<li><p>What is secp256k1?</p>
<ol>
<li><p>Parameters &amp; Curve</p>
</li>
<li><p>Why is it important?</p>
</li>
</ol>
</li>
<li><p>Key-Pair Generation w/ secp256k1</p>
<ol>
<li><p>Key-Pairs</p>
<ol>
<li><p>Private Key</p>
</li>
<li><p>Public Key</p>
</li>
</ol>
</li>
<li><p>How to generate a key-pair?</p>
<ol>
<li><p>Generating a Private Key</p>
</li>
<li><p>Deriving the Public Key</p>
</li>
</ol>
</li>
</ol>
</li>
<li><p>Conclusion</p>
</li>
</ol>
<h1 id="heading-elliptic-curves-revisited">Elliptic Curves, Revisited</h1>
<h2 id="heading-what-was-an-elliptic-curve-again">What was an elliptic curve, again?</h2>
<p>Let \(p\) be a prime number and let \(\mathbb{F}_p\) denote the field of integers modulo \(p\). An <strong>elliptic curve</strong>\(E\) over \(\mathbb{F}_p\) is defined by an equation of the form</p>
<p>$$y^2 = x^3 + ax + b,$$</p><p>where \(a,b \in \mathbb{F}_p\) satisfy \(4a^3+ 27b^2 \neq 0 \ (mod \ p) \) . A pair \((x, y)\) is a point on the curve if it satisfies the equation where \(x,y \in \mathbb{F}_p\). The <em>point at infinity</em>, denoted by \(\infty\) is also said to be on the curve. The set of all points on \(E\) is denoted by \(E(\mathbb{F}_p)\).</p>
<p>For example, if \(E\) is an elliptic curve over \(\mathbb{F}_7\) with equation</p>
<p>$$y^2 = x^3 + 2x + 4,$$</p><p>then the points on \(E\) are</p>
<p>$$E(\mathbb{F}_7) = \{ \infty, (0,2), (0,5), (1,0), (2,3), (2,4), (3,3), (3,4), (6,1), (6,6) \}.$$</p><blockquote>
<p>Notice that, with the <a target="_blank" href="https://trustica.cz/2018/03/15/elliptic-curves-point-addition/">point addition rule</a>, the set of points \(E(\mathbb{F}_p)\) forms a group with \(\infty\) serving as the identity element. We call such groups <strong>elliptic curve groups</strong>.</p>
</blockquote>
<h1 id="heading-what-is-secp256k1">What is secp256k1?</h1>
<h2 id="heading-parameters-amp-curve">Parameters &amp; Curve</h2>
<p>In order to specify a particular elliptic curve, we need to mention a couple of parameters (domain parameters). Let us see what we have for <code>secp256k1</code>:</p>
<ul>
<li><p>\(a = 0\),</p>
</li>
<li><p>\(b = 7,\)</p>
</li>
<li><p>\(p = 2^{256} - 2^{32} - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1,\)</p>
</li>
<li><p>\(n = 115792089237316195423570985008687907852837564279074904382605163141518161494337,\)</p>
</li>
<li><p>\(G_x = 55066263022277343669578718895168534326250603453777594175500187360389116729240,\)</p>
</li>
<li><p>\(G_y = 32670510020758816978083085130507043184471273380659243275938904335757337482424,\)</p>
</li>
</ul>
<p>where \(a\) and \(b\) are the multiples in the curve equation, \(p\) is the order of the finite field which the curve is based on, \(n\) is the order of the elliptic curve group, and finally \(G\) is the base point or <a target="_blank" href="https://en.wikipedia.org/wiki/Generating_set_of_a_group">generator point</a> of the curve with \(G_x\) as the x-component and \(G_y\) as the y-component.</p>
<p>Notice that all these numbers are quite large and this is the thing making the system so secure.</p>
<p>So our curve equation is as follows:</p>
<p>$$y^2 = x^3 + 7.$$</p><blockquote>
<p>Notice that neither \(G_x\), nor \(G_y\) is greater than or equal to \(p\).</p>
</blockquote>
<h2 id="heading-why-is-it-important">Why is it important?</h2>
<p>The elliptic curve secp256k1 has become a cornerstone in the world of cryptocurrencies, especially for Bitcoin and Ethereum. Its popularity comes from the curve's robust security, which is enhanced by its large prime order, and its operational efficiency. These features make it exceptionally suitable for creating cryptographic keys in decentralized systems.</p>
<p>The curve's parameters are specifically chosen to ensure fast cryptographic processes, which in turn, make transactions not only secure but also swift. This blend of security, effectiveness, and speed is crucial for maintaining the trust and reliability of transactions on the Bitcoin network, significantly contributing to the development and success of blockchain technology.</p>
<h1 id="heading-key-pair-generation-w-secp256k1">Key-Pair Generation w/ secp256k1</h1>
<h2 id="heading-key-pairs">Key-Pairs</h2>
<p>A key-pair consists of two keys:</p>
<ul>
<li><p>private key and</p>
</li>
<li><p>public key.</p>
</li>
</ul>
<h3 id="heading-private-key">Private Key</h3>
<p>It is used for signing and, as the name suggests, kept secret. The signer uses their private key to sign the message. The strength of the system lies in the fact that, although the public key is known to all, it is computationally infeasible to derive the private key from it.</p>
<h3 id="heading-public-key">Public Key</h3>
<p>It is available to everyone and used for signature verification. It's like a digital address shared openly for others to verify signatures if they are actually created by the party that claims the ownership of the signature.</p>
<h2 id="heading-how-to-generate-a-key-pair">How to generate a key-pair?</h2>
<h3 id="heading-generating-a-private-key">Generating a Private Key</h3>
<p>A private key in elliptic curve cryptography is a randomly selected integer \(d\) from the range \([1, n-1]\), where \(n\) is the order of the curve.</p>
<p>Let's try it:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> num_bigint::BigInt;
<span class="hljs-keyword">use</span> rand::thread_rng;

<span class="hljs-comment">// Order of the curve in hexadecimal form</span>
<span class="hljs-keyword">const</span> N: &amp;<span class="hljs-built_in">str</span> = <span class="hljs-string">"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"</span>;

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">generate_private_key</span></span>() -&gt; BigInt {
    <span class="hljs-keyword">let</span> n = BigInt::parse_bytes(N.as_bytes(), <span class="hljs-number">16</span>).unwrap();
    <span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> rng = thread_rng();
    <span class="hljs-comment">// Generate a random BigInt within the range [1, n-1]</span>
    <span class="hljs-keyword">let</span> private_key = rng.gen_bigint_range(&amp;BigInt::one(), &amp;n);
    private_key
}
</code></pre>
<p>This short code snippet basically does:</p>
<ol>
<li><p>import some external libraries to use <code>BigInt</code> format and choose a randomly selected integer,</p>
</li>
<li><p>declare a variable called <code>N</code> with the hexadecimal form of \(N\),</p>
</li>
<li><p>initialize a function called <code>generate_private_key()</code>,</p>
</li>
<li><p>declare a variable called <code>n</code> and initializes it with the result of parsing the hexadecimal form of \(N\),</p>
</li>
<li><p>generate a random integer within the range \([1, n-1]\) and assign it to the variable called <code>private_key</code>.</p>
</li>
<li><p>finally return <code>private_key</code>.</p>
</li>
</ol>
<h3 id="heading-deriving-the-public-key">Deriving the Public Key</h3>
<p>The public key \(Q\) is derived from the private key \(d\) by multiplying it with the base point \(G\) of the curve:</p>
<p>$$Q = d \cdot G.$$</p><p>Hence, public key \(Q\) is essentially a point on the curve.</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> num_bigint::BigInt;

<span class="hljs-keyword">mod</span> utils;

<span class="hljs-keyword">use</span> utils::Point;
<span class="hljs-keyword">use</span> utils::scalar_multiplication;

<span class="hljs-comment">// Other domain parameters in hexadecimal form</span>
<span class="hljs-keyword">const</span> P: &amp;<span class="hljs-built_in">str</span> = <span class="hljs-string">"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"</span>;
<span class="hljs-keyword">const</span> G_X: &amp;<span class="hljs-built_in">str</span> = <span class="hljs-string">"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"</span>;
<span class="hljs-keyword">const</span> G_Y: &amp;<span class="hljs-built_in">str</span> = <span class="hljs-string">"483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"</span>;

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">derive_public_key</span></span>(private_key: &amp;BigInt) -&gt; (BigInt, BigInt) {
    <span class="hljs-keyword">let</span> modulus = BigInt::parse_bytes(P.as_bytes(), <span class="hljs-number">16</span>).unwrap();
    <span class="hljs-keyword">let</span> a = BigInt::from(<span class="hljs-number">0</span>); <span class="hljs-comment">// secp256k1's 'a' parameter is 0</span>
    <span class="hljs-keyword">let</span> g = Point {
        x: BigInt::parse_bytes(G_X.as_bytes(), <span class="hljs-number">16</span>).unwrap(),
        y: BigInt::parse_bytes(G_Y.as_bytes(), <span class="hljs-number">16</span>).unwrap(),
    };
    <span class="hljs-keyword">let</span> public_key = scalar_multiplication(&amp;g, private_key, &amp;a, &amp;modulus);
    (public_key.x, public_key.y)
}
</code></pre>
<p>This code basically does:</p>
<ol>
<li><p>import an external library to use <code>BigInt</code> format,</p>
</li>
<li><p>import a <code>struct</code> called <code>Point</code> ,</p>
</li>
<li><p>declare the domain parameters as variables in their hexadecimal forms,</p>
</li>
<li><p>initialize a function called <code>derive_public_key</code> taking private key as an input,</p>
</li>
<li><p>declare a variable called <code>modulus</code> and initializes with the result of parsing the hexadecimal form of \(p\).</p>
</li>
<li><p>declare variables for \(a\) and the base point \(G\),</p>
</li>
<li><p>perform the scalar multiplication \(d \cdot G\) and assign it to the variable called <code>public_key</code>,</p>
</li>
<li><p>finally return the point <code>public_key</code>.</p>
</li>
</ol>
<p>Let us build the <code>main()</code> function before running the code:</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-keyword">let</span> private_key = generate_private_key();
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Private Key: {}"</span>, private_key);

    <span class="hljs-keyword">let</span> public_key = derive_public_key(&amp;private_key);
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Public Key: ({}, {})"</span>, public_key.<span class="hljs-number">0</span>, public_key.<span class="hljs-number">1</span>);

    <span class="hljs-keyword">let</span> ethereum_address = convert_to_ethereum_address(&amp;public_key);
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Ethereum Address: {}"</span>, ethereum_address);
}
</code></pre>
<p>Time to build and run:</p>
<pre><code class="lang-bash">cargo build
cargo run
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">Private Key: 41831991390653552422840364716923515177067311217271364429731967099160830113867
Public Key: (16443841179803354550922733760429663760404329023875294123053636149554388604922, 86388970361949805853944014893086285981774181298492291090513927212929981949880)
Ethereum Address: 0x101e2b2e11d2c62f9adcb129de37b2bb36982671
</code></pre>
<p>We have successfully generated our key pair and displayed it, along with an Ethereum address as an additional version.</p>
<p>I needed to code some extra utility functions to build this project:</p>
<ul>
<li><p><code>convert_to_ethereum_address()</code>,</p>
</li>
<li><p><code>add_points()</code>,</p>
</li>
<li><p><code>double_point()</code>,</p>
</li>
<li><p><code>scalar_multiplication()</code>,</p>
</li>
<li><p><code>mod_inverse()</code>.</p>
</li>
</ul>
<p>You can find the complete code in <a target="_blank" href="https://github.com/furkanakal/secp256k1/">this GitHub repository</a>.</p>
<p><img src="https://i.imgflip.com/8hgihw.jpg" alt="Image Reference: I created it on imgflip.com." class="image--center mx-auto" /></p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In this first part of our exploration into the secp256k1 elliptic curve, we've laid the foundational knowledge necessary to understand the basics of elliptic curves and the specifics of secp256k1, including its significance in the world of cryptocurrency. We've also walked through the process of generating a key pair, which is crucial for ensuring secure digital transactions. As we've seen, the combination of a carefully selected private key and its corresponding public key forms the backbone of cryptographic security in blockchain technologies.</p>
]]></content:encoded></item><item><title><![CDATA[Preliminary Knowledge Required for Studying Elliptic Curve Cryptography]]></title><description><![CDATA[Hello everyone! Welcome to the first, but certainly not the last, post in the elliptic curve cryptography series. Previously, we discussed public-key cryptography and RSA encryption. In this series, we will discuss the elliptic curve cryptography by ...]]></description><link>https://furkanakal.com/fundamental-concepts-elliptic-curve-cryptography</link><guid isPermaLink="true">https://furkanakal.com/fundamental-concepts-elliptic-curve-cryptography</guid><category><![CDATA[elliptic curve cryptography]]></category><dc:creator><![CDATA[Furkan Akal]]></dc:creator><pubDate>Mon, 05 Feb 2024 15:18:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1707146369870/93f42e26-2112-47c5-af88-df810b87a311.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone! Welcome to the first, but certainly not the last, post in the elliptic curve cryptography series. Previously, we discussed public-key cryptography and RSA encryption. In this series, we will discuss the elliptic curve cryptography by beginning with essence of finite fields and their use in elliptic curve cryptography.</p>
<h1 id="heading-contents">Contents</h1>
<ol>
<li><p>Finite Prime Fields</p>
<ol>
<li><p>Definition</p>
</li>
<li><p>Example</p>
</li>
<li><p>NIST Primes</p>
</li>
<li><p>Why finite fields?</p>
</li>
</ol>
</li>
<li><p>What is an elliptic curve?</p>
<ol>
<li><p>Overview</p>
</li>
<li><p>Elliptic Curve Groups</p>
</li>
</ol>
</li>
</ol>
<hr />
<h1 id="heading-finite-prime-fields">Finite Prime Fields</h1>
<p>Before getting into the finite fields, let us recall the general group and field definitions from Wikipedia:</p>
<h3 id="heading-groups">Groups</h3>
<blockquote>
<p>A group G is a finite or infinite set of elements together with a binary operation (called the group operation) that together satisfy the four fundamental properties of closure, associativity, the identity property, and the inverse property. The operation with respect to which a group is defined is often called the "group operation," and a set is said to be a group "under" this operation. Elements A, B, C, ... with binary operation between A and B denoted AB form a group if</p>
<ul>
<li><p>Closure: If A and B are two elements in G, then the product AB is also in G.</p>
</li>
<li><p>Associativity: The defined multiplication is associative, i.e., for all A,B,C in G, (AB)C=A(BC).</p>
</li>
<li><p>Identity: There is an identity element I (a.k.a. 1, E, or e) such that IA=AI=A for every element A in G.</p>
</li>
<li><p>Inverse: There must be an inverse (a.k.a. reciprocal) of each element. Therefore, for each element A of G, the set contains an element B=A^(-1) such that AA^(-1)=A^(-1)A=I.</p>
</li>
</ul>
</blockquote>
<h3 id="heading-fields">Fields</h3>
<blockquote>
<p>Formally, a field is a <a target="_blank" href="https://en.wikipedia.org/wiki/Set_(mathematics)">set</a><em>F</em> together with two <a target="_blank" href="https://en.wikipedia.org/wiki/Binary_operation">binary operations</a> on <em>F</em> called <em>addition</em> and <em>multiplication</em>. A binary operation on <em>F</em> is a mapping <em>F</em> × <em>F</em> → <em>F</em>, that is, a correspondence that associates with each ordered pair of elements of <em>F</em> a uniquely determined element of <em>F</em>.The result of the addition of <em>a</em> and <em>b</em> is called the sum of <em>a</em> and <em>b</em>, and is denoted <em>a</em> + <em>b</em>. Similarly, the result of the multiplication of <em>a</em> and <em>b</em> is called the product of <em>a</em> and <em>b</em>, and is denoted <em>ab</em> or <em>a</em> ⋅ <em>b</em>. These operations are required to satisfy the following properties, referred to as <a target="_blank" href="https://en.wikipedia.org/wiki/Axiom#Non-logical_axioms"><em>field axioms</em></a> (in these axioms, <em>a</em>, <em>b</em>, and <em>c</em> are arbitrary <a target="_blank" href="https://en.wikipedia.org/wiki/Element_(mathematics)">elements</a> of the field <em>F</em>):</p>
<ul>
<li><p>Associativity of addition and multiplication: <em>a</em> + (<em>b</em> + <em>c</em>) = (<em>a</em> + <em>b</em>) + <em>c</em>, and <em>a</em> ⋅ (<em>b</em> ⋅ <em>c</em>) = (<em>a</em> ⋅ <em>b</em>) ⋅ <em>c</em>.</p>
</li>
<li><p>Commutativity of addition and multiplication: <em>a</em> + <em>b</em> = <em>b</em> + <em>a</em>, and <em>a</em> ⋅ <em>b</em> = <em>b</em> ⋅ <em>a</em>.</p>
</li>
<li><p>Additive and <a target="_blank" href="https://en.wikipedia.org/wiki/Multiplicative_identity">multiplicative identity</a>: there exist two distinct elements 0 and 1 in <em>F</em> such that <em>a</em> + 0 = <em>a</em> and <em>a</em> ⋅ 1 = <em>a</em>.</p>
</li>
<li><p>Additive inverses: for every <em>a</em> in <em>F</em>, there exists an element in <em>F</em>, denoted −<em>a</em>, called the <em>additive inverse</em> of <em>a</em>, such that <em>a</em> + (−<em>a</em>) = 0.</p>
</li>
<li><p>Multiplicative inverses: for every <em>a</em> ≠ 0 in <em>F</em>, there exists an element in <em>F</em>, denoted by <em>a</em><sup>−1</sup> or 1/<em>a</em>, called the <em>multiplicative inverse</em> of <em>a</em>, such that <em>a</em> ⋅ <em>a</em><sup>−1</sup> = 1.</p>
</li>
<li><p>Distributivity of multiplication over addition: <em>a</em> ⋅ (<em>b</em> + <em>c</em>) = (<em>a</em> ⋅ <em>b</em>) + (<em>a</em> ⋅ <em>c</em>).</p>
</li>
</ul>
</blockquote>
<p>The most popular field examples are:</p>
<ul>
<li><p>\((\mathbb{Q}, +, \cdot)\),</p>
</li>
<li><p>\((\mathbb{R} , +, \cdot)\), and</p>
</li>
<li><p>\((\mathbb{C}, +, \cdot)\) with \(\cdot\) operation is defined as</p>
<ul>
<li>\((a+bi) \cdot (c + di) = (ac -bd) + (bc + ad)i\).</li>
</ul>
</li>
</ul>
<p>Notice that all these fundamental examples are infinite fields. So let's see how finite ones look like!</p>
<h2 id="heading-definition">Definition</h2>
<p>Let \(p\) be a prime number. The integers modulo \(p\), consisting of integers \(\{ 0, 1, 2, ... , p-1 \}\) with addition and multiplication performed modulo \(p\), is a finite field of order \(p\). We shall denote this field by \(\mathbb{F}_p\).</p>
<h2 id="heading-example-mathbbf29">Example (\(\mathbb{F}_{29}\))</h2>
<p>The elements of \(\mathbb{F}_{29}\) are \(\{ 0, 1, 2, ... , 28 \}\). The followings are some examples of arithmetic operations in \(\mathbb{F}_{29}\):</p>
<ol>
<li><p>\(17 + 20 = 8\) since \(37 \ mod \ 29 = 8\).</p>
</li>
<li><p>\(17 - 20 = 26\) since \(-3 \ mod \ 29 = 26\).</p>
</li>
<li><p>\(17 \cdot 20 = 21\) since \(340  \ mod \ 29 = 21.\)</p>
</li>
<li><p>\(17^{-1} = 12\) since \(17 \cdot 12 \ mod \ 29 = 1\).</p>
</li>
</ol>
<h2 id="heading-nist-primes">NIST Primes</h2>
<p>You can construct a prime field by setting the \(p\) as any prime, but there is a standard recommends elliptic curves over the five prime fields with moduli:</p>
<p>$$p_{192} = 2^{192} - 2^{64} - 1$$</p><p>$$p_{224} = 2^{224} - 2^{96} + 1$$</p><p>$$p_{256} = 2^{256} - 2^{224} + 2^{192} + 2^{96} - 1$$</p><p>$$p_{384} = 2^{384} - 2^{128} - 2^{96} + 2^{32} - 1$$</p><p>$$p_{521} = 2^{521} - 1$$</p><p>These primes have the property that they can be written as the sum or difference of a small number of powers of 2. Furthermore, except for \(p_{521}\), the powers appearing in these expressions are all multiple of 32. These properties yield reduction algorithms that are especially fast on machines with wordsize 32.</p>
<h2 id="heading-why-finite-fields">Why finite fields?</h2>
<p>Basis of the security of elliptic curve cryptography is formed by the discrete logarithm problem (DLP), which we will cover in upcoming parts with more details, and DLP is more tractable in finite fields compared to infinite fields. This means that elliptic curve cryptography can achieve high levels of security with relatively smaller key sizes compared to other cryptographic schemes, such as RSA.</p>
<h2 id="heading-what-is-an-elliptic-curve">What is an elliptic curve?</h2>
<h3 id="heading-overview">Overview</h3>
<p>Let \(p\) be a prime number and let \(\mathbb{F}_p\) denote the field of integers modulo \(p\). An "elliptic curve" \(E\) over \(\mathbb{F}_p\) is defined by an equation of the form</p>
<p>$$y^2 = x^3 + ax + b,$$</p><p>where \(a,b \in \mathbb{F}_p\) satisfy \(4a^3+ 27b^2 \neq 0 \ (mod \ p) \) . A pair \((x, y)\), where \(x,y \in \mathbb{F}_p\) is a point on the curve if it satisfies the curve equation. The <em>point at infinity</em>, denoted by \(\infty\), is also said to be on the curve. The set of all points on \(E\) is denoted by \(E(\mathbb{F}_p)\).</p>
<p>For example, if \(E\) is an elliptic curve over \(\mathbb{F}_7\) with defining equation</p>
<p>$$y^2 = x^3 + 2x + 4,$$</p><p>then the points on \(E\) are</p>
<p>$$E(\mathbb{F}_7) = \{ \infty, (0,2), (0,5), (1,0), (2,3), (2,4), (3,3), (3,4), (6,1), (6,6) \}.$$</p><p>Please see <a target="_blank" href="https://trustica.cz/2018/03/15/elliptic-curves-point-addition/">point addition</a> to see how to add 2 points up to obtain another point on the curve.</p>
<p>As we are able to define an addition operation on elliptic curves, we can also construct a group structure on elliptic curves</p>
<h3 id="heading-elliptic-curve-groups">Elliptic Curve Groups</h3>
<blockquote>
<p>With the point addition rule, the set of points \(E(\mathbb{F}_p)\) forms a group with \(\infty\) serving as the identity element.</p>
</blockquote>
<p>This kind of group structures are called "elliptic curve groups".</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In this post, some fundamental concepts and notions are mentioned. In the next post, we will discuss key generation and encryption schemes in elliptic curve cryptography.</p>
]]></content:encoded></item><item><title><![CDATA[Part 3: Public / Private Keys & RSA Encryption | Public-Key Cryptography]]></title><description><![CDATA[Hello everyone! Welcome to the third part of the public-key cryptography series! In the previous part, the notion of prime number was discussed. This part is intended to give an introduction for public / private key pairs and encryption / decryption ...]]></description><link>https://furkanakal.com/part-3-public-private-keys-rsa-encryption-public-key-cryptography</link><guid isPermaLink="true">https://furkanakal.com/part-3-public-private-keys-rsa-encryption-public-key-cryptography</guid><category><![CDATA[public key cryptography]]></category><category><![CDATA[RSA Encryption]]></category><dc:creator><![CDATA[Furkan Akal]]></dc:creator><pubDate>Tue, 30 Jan 2024 15:30:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1706619821521/f4bfdb5a-312b-46f0-9b24-21e339035736.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone! Welcome to the third part of the public-key cryptography series! In <a target="_blank" href="https://furkanakal.com/prime-numbers-public-key-cryptography">the previous part</a>, the notion of prime number was discussed. This part is intended to give an introduction for public / private key pairs and encryption / decryption by using them. Once again, you'll have the opportunity to apply the math using the provided Rust code.</p>
<h1 id="heading-contents">Contents</h1>
<ol>
<li><p>Basics of Public-Key Cryptography</p>
<ol>
<li><p>What is a key pair?</p>
<ol>
<li><p>Private Key</p>
</li>
<li><p>Public Key</p>
</li>
</ol>
</li>
<li><p>How it works?</p>
</li>
<li><p>Real World Applications</p>
</li>
</ol>
</li>
<li><p>Mathematical Foundations</p>
<ol>
<li><p>Key Generation Principles &amp; Prime Numbers</p>
</li>
<li><p>Euler's Totient Function</p>
</li>
<li><p>Formula of Secrecy</p>
</li>
<li><p>Encryption / Decryption</p>
</li>
</ol>
</li>
<li><p>From Theory to Hands-on Practice (Rust Code)</p>
<ol>
<li><p>Key Generation</p>
</li>
<li><p>Encryption / Decryption</p>
</li>
<li><p>It is time to test!</p>
</li>
</ol>
</li>
<li><p>Conclusion</p>
</li>
</ol>
<h1 id="heading-basics-of-public-key-cryptography">Basics of Public-Key Cryptography</h1>
<h2 id="heading-what-is-a-key-pair">What is a key pair?</h2>
<p>A key pair consists of two keys:</p>
<ul>
<li><p>private key and</p>
</li>
<li><p>public key.</p>
</li>
</ul>
<h3 id="heading-public-key">Public Key</h3>
<p>It is available to everyone and used for encryption. It's like a digital address shared openly for others to send encrypted messages. So, anyone can use a recipient's public key to encrypt a message. Once the message is encrypted, it can only be decrypted by the corresponding private key.</p>
<h3 id="heading-private-key">Private Key</h3>
<p>It is used for decryption and, as the name suggests, kept secret. The recipient uses their private key to decrypt encrypted messages. The strength of the system lies in the fact that, although the public key is known to all, it is computationally infeasible to derive the private key from it.</p>
<h2 id="heading-how-it-works">How it works?</h2>
<p>Let's consider a scenario where two close friends, Alice and Bob, wish to communicate secretly. In this situation, Alice and Bob can use public-key cryptography (assuming they have securely shared their keys with each other; we will discuss key sharing methods shortly) to maintain the confidentiality of their messages.</p>
<ol>
<li><p>Alice encrypts her message using Bob's public key and sends it over to Bob.</p>
</li>
<li><p>Bob receives the encrypted message, decrypts it using his own private key, and finally reads it.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706518113795/7c836d55-757e-47ca-8196-7f22c60064f0.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-real-world-applications">Real World Applications</h2>
<h3 id="heading-email">Email</h3>
<p>Email encryption serves as a technique to protect the contents of email communications from unauthorized access by external parties. When an email is encrypted, it becomes unreadable to any person. Decryption and restoration of the original message are only possible using your unique private email key.</p>
<p>This encryption process utilizes public-key cryptography.</p>
<h3 id="heading-social-media">Social Media</h3>
<p>Social media platforms like WhatsApp and Instagram also use public-key cryptography (sometimes private-key cryptography also) for end-to-end encryption.</p>
<h3 id="heading-blockchains">Blockchains</h3>
<p>In almost all the blockchains, public-key cryptography is extensively used.</p>
<p>Where public keys are used as an account number, private keys are used to sign transactions (I will write a particular blog post on digital signatures) and to prove ownership of an address and the assets contained within it.</p>
<h1 id="heading-mathematical-foundations">Mathematical Foundations</h1>
<p>In this section, we will discuss the mathematical fundamentals of key generation. You will see that how important prime numbers will be for public-key cryptography.</p>
<h2 id="heading-key-generation-principles-amp-prime-numbers">Key Generation Principles &amp; Prime Numbers</h2>
<p>There is more than one approach to key generation in public-key cryptography. Two of them are:</p>
<ol>
<li><p>RSA cryptography,</p>
</li>
<li><p>Elliptic curve cryptography.</p>
</li>
</ol>
<p>Although I'm planning another series of posts regarding elliptic curve cryptography, for the sake of simplicity, we will discuss and practice RSA encryption in this series.</p>
<blockquote>
<p>RSA encryption relies on prime factorization of large numbers being computationally difficult. We want the calculation to be easy to perform in one direction, but difficult to invert if you don't have the proper key.</p>
</blockquote>
<p>So far, we have discussed how public-key cryptography worked, but we never discussed how were those public and private keys generated.</p>
<p>The main principle in generating public / private key pairs is the use of large prime numbers. Recall from the previous post about prime numbers.</p>
<ul>
<li><p><strong>Unpredictability:</strong> Large primes are not easily guessable, adding a layer of security,</p>
</li>
<li><p><strong>Unique Factorization:</strong> The fact that every natural number can be uniquely factored into primes is crucial in algorithms like RSA, where the security relies on the difficulty of factoring the product of two large prime numbers.</p>
</li>
</ul>
<h2 id="heading-eulers-totient-function">Euler's Totient Function</h2>
<p>Euler's totient function \(\phi(n)\) is defined as the count of positive integers up to \(n\) that are relatively prime to \(n\). Simply it calculates the number of integers less than \(n\) that do not share any common factors with \(n\), except for the number 1.</p>
<h3 id="heading-calculation"><strong>Calculation</strong></h3>
<ul>
<li><p><strong>For a Prime Number</strong>\(p\): \(\phi(p) = p - 1.\) This is because all numbers less than a prime number are coprime to it.</p>
</li>
<li><p><strong>For a Product of Two Primes</strong>\(p\) and \(q\): \(\phi(p \ \times \ q) = (p - 1) \ \times \ (q - 1).\) This results from the fact that none of the numbers less than \(p \ \times \ q\) are divisible by either \(p\) or \(q\), except for the multiples of \(p\) and \(q\).</p>
</li>
<li><p><strong>General Case:</strong> If \(n = p_1^{k_1} \times p_2^{k_2} \times \ ... \ \times p_r^{k_r}\), where \(p_1, p_2, ..., p_r\) are distinct prime numbers and \(k_1, k_2, ..., k_r\) are their respective powers, then</p>
<ul>
<li>\(\phi(n) = n \times (1 - \frac{1}{p_1}) \times (1 - \frac{1}{p_2}) \times \ ... \ \times (1 - \frac{1}{p_r})\).</li>
</ul>
</li>
</ul>
<h2 id="heading-formula-of-secrecy">Formula of Secrecy</h2>
<p>It is time to construct the key generation algorithm.</p>
<p>For the algorithm to help Bob communicate with Alice, Bob would need to create a public key for Alice to encrypt messages, and a private key to help Bob decrypt Alice's messages. RSA key generation works as follows:</p>
<ol>
<li><p>Take two large prime numbers, \(p\) and \(q\), and multiply them to get a number \(N\). Keep \(p\) and \(q\) secret.</p>
</li>
<li><p>Calculate the totient of \(N\): \(\phi(N) = (p-1)(q-1)\).</p>
</li>
<li><p>Find a positive integer \(e\) that is less than \(\phi(N)\) and is coprime with \(\phi(N)\), meaning the greatest common divisor (GCD) between \(e\) and \(\phi(N)\) is 1.</p>
</li>
<li><p>Calculate the number \(d = e^{-1} \ mod \ \phi(N)\). Notice that this means \(e \cdot d \equiv 1 \ mod \ \phi(N)\), so \(d\) and \(e\) are modular inverses of one another.</p>
</li>
</ol>
<p>The pair of integers \((N, e)\) represents Bob's public key and can be shared by everyone who wants to communicate with him. Similarly \((N,d)\) represents Bob's private key that is supposed to be kept as a secret.</p>
<h2 id="heading-encryption-decryption">Encryption / Decryption</h2>
<p>Now, if Alice wants to send a message \(m\) and encrypt it into ciphertext \(c\) to send over to Bob, she would perform the following calculation:</p>
<p>$$Enc(m) = m^{e} \ mod \ N = c.$$</p><p>Bob receives the encrypted message and decrypts it by performing the following calculation:</p>
<p>$$Dec(c) = c^{d} \ mod \ N = m.$$</p><p>Notice that <strong>the aysmmetric encryption correctness property</strong> holds:</p>
<p>$$Dec(Enc(m)) = m^{ed} \ mod \ N \equiv m \ mod \ N$$</p><p>as \(e\) and \(d\) are multiplicative inverses of each other.</p>
<h1 id="heading-from-theory-to-hands-on-practice-rust-code">From Theory to Hands-on Practice (Rust Code)</h1>
<h2 id="heading-key-generation">Key Generation</h2>
<p>Before starting to write <code>generate_keys()</code> function, let's recall a slightly modified version of <code>mod_inverse()</code> function we have built in the previous post:</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">mod_inverse</span></span>(e: <span class="hljs-built_in">u64</span>, phi: <span class="hljs-built_in">u64</span>) -&gt; <span class="hljs-built_in">Option</span>&lt;<span class="hljs-built_in">u64</span>&gt; {
    <span class="hljs-keyword">let</span> (<span class="hljs-keyword">mut</span> a, <span class="hljs-keyword">mut</span> b, <span class="hljs-keyword">mut</span> x0, <span class="hljs-keyword">mut</span> x1) = (phi, e, <span class="hljs-number">0u64</span>, <span class="hljs-number">1u64</span>);

    <span class="hljs-keyword">while</span> b &gt; <span class="hljs-number">0</span> {
        <span class="hljs-keyword">let</span> q = a / b;
        (a, b) = (b, a % b);
        (x0, x1) = (x1, x0.wrapping_sub(x1.wrapping_mul(q)));
    }

    <span class="hljs-keyword">if</span> a &gt; <span class="hljs-number">1</span> {
        <span class="hljs-literal">None</span> <span class="hljs-comment">// No modular inverse if a is not 1</span>
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-literal">Some</span>(x0.wrapping_add(phi) % phi)
    }
}
</code></pre>
<p>We will also need a new function to calculate modular exponents (to perform an exponentiation over a modulus):</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">mod_exp</span></span>(<span class="hljs-keyword">mut</span> base: <span class="hljs-built_in">u64</span>, <span class="hljs-keyword">mut</span> exp: <span class="hljs-built_in">u64</span>, modulus: <span class="hljs-built_in">u64</span>) -&gt; <span class="hljs-built_in">u64</span> {
    <span class="hljs-keyword">if</span> modulus == <span class="hljs-number">1</span> { <span class="hljs-keyword">return</span> <span class="hljs-number">0</span> }
    <span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> result = <span class="hljs-number">1</span>;
    base %= modulus;
    <span class="hljs-keyword">while</span> exp &gt; <span class="hljs-number">0</span> {
        <span class="hljs-keyword">if</span> exp % <span class="hljs-number">2</span> == <span class="hljs-number">1</span> { result = result * base % modulus }
        exp &gt;&gt;= <span class="hljs-number">1</span>;
        base = base * base % modulus;
    }
    result
}
</code></pre>
<p>Now, we are ready to construct the key generation function. It will take the tuple\((p, q)\)and will output the triple \((N, e, d)\):</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">generate_keys</span></span>(p: <span class="hljs-built_in">u64</span>, q: <span class="hljs-built_in">u64</span>) -&gt; (<span class="hljs-built_in">u64</span>, <span class="hljs-built_in">u64</span>, <span class="hljs-built_in">u64</span>) {

}
</code></pre>
<p>Let us start by defining the basic variables like</p>
<ul>
<li><p>\(N = p \times q\),</p>
</li>
<li><p>\(\phi = (p-1)(q-1)\):</p>
</li>
</ul>
<pre><code class="lang-rust"><span class="hljs-keyword">let</span> N = p * q;
<span class="hljs-keyword">let</span> phi = (p - <span class="hljs-number">1</span>) * (q - <span class="hljs-number">1</span>);
</code></pre>
<p>The most commonly used value for \(e\) in RSA-like systems is 65537 (which is of course a prime number).</p>
<pre><code class="lang-rust"><span class="hljs-keyword">let</span> e = <span class="hljs-number">65537</span>;
</code></pre>
<p>Now that we have everything we need, all we have to do is calculate \(d\) by calculating the modular inverse of \(e\) in mod \(\phi\) by ensuring such a modular inverse exists:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">let</span> d = mod_inverse(e, phi).expect(<span class="hljs-string">"Modular inverse does not exist!"</span>);
</code></pre>
<p>Returning the \((N, e, d)\) triple will complete <code>generate_keys()</code> function:</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">generate_keys</span></span>(p: <span class="hljs-built_in">u64</span>, q: <span class="hljs-built_in">u64</span>) -&gt; (<span class="hljs-built_in">u64</span>, <span class="hljs-built_in">u64</span>, <span class="hljs-built_in">u64</span>) {
    <span class="hljs-keyword">let</span> n = p * q;
    <span class="hljs-keyword">let</span> phi = (p - <span class="hljs-number">1</span>) * (q - <span class="hljs-number">1</span>);
    <span class="hljs-keyword">let</span> e = <span class="hljs-number">65537</span>; <span class="hljs-comment">// Using 65537 as e</span>
    <span class="hljs-keyword">let</span> d = mod_inverse(e, phi).expect(<span class="hljs-string">"Modular inverse does not exist."</span>);

    (n, e, d)
}
</code></pre>
<h2 id="heading-encryption-decryption-1">Encryption / Decryption</h2>
<p>Let us recall the encryption and decryption functions:</p>
<p>$$Enc(m) = m^{e} \ mod \ N = c. $$</p><p> $$Dec(c) = c^{d} \ mod \ N = m.$$</p>
<p>So, all we need for encryption is to have:</p>
<ul>
<li><p>\(m\) (message) as the base,</p>
</li>
<li><p>\(e\) as the exponent, and</p>
</li>
<li><p>\(N\) as the modulus:</p>
</li>
</ul>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">encrypt</span></span>(message: <span class="hljs-built_in">u64</span>, e: <span class="hljs-built_in">u64</span>, n: <span class="hljs-built_in">u64</span>) -&gt; <span class="hljs-built_in">u64</span> {
    mod_exp(message, e, n)
}
</code></pre>
<p>Similarly, what we need for decryption is to have:</p>
<ul>
<li><p>\(c\) (ciphertext) as the base,</p>
</li>
<li><p>\(d\) as the exponent, and</p>
</li>
<li><p>\(N\) as the modulus:</p>
</li>
</ul>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">decrypt</span></span>(ciphertext: <span class="hljs-built_in">u64</span>, d: <span class="hljs-built_in">u64</span>, n: <span class="hljs-built_in">u64</span>) -&gt; <span class="hljs-built_in">u64</span> {
    mod_exp(ciphertext, d, n)
}
</code></pre>
<p>The code is almost ready. We need to define \(p\), \(q\), and the message \(m\). Normally those primes are extremely large to make the system more complicated. But, for the sake of simplicity, let's choose \(p\) and \(q\) a bit small, for example:</p>
<ul>
<li><p>\(p\) = 61,</p>
</li>
<li><p>\(q\) = 53.</p>
</li>
</ul>
<p>Of course, there are some restrictions we need to be mindful of:</p>
<ol>
<li><p>They are both prime.</p>
</li>
<li><p>\(\phi = (p-1)(q-1) = 3120\) is coprime to \(e = 65537\).</p>
</li>
</ol>
<p>So, we can proceed with these selections. Let's implement it inside the <code>main()</code> function:</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-keyword">let</span> p: <span class="hljs-built_in">u64</span> = <span class="hljs-number">61</span>;
    <span class="hljs-keyword">let</span> q: <span class="hljs-built_in">u64</span> = <span class="hljs-number">53</span>;
    <span class="hljs-keyword">let</span> (n, e, d) = generate_keys(p, q);

    <span class="hljs-keyword">let</span> message = <span class="hljs-number">42</span>;
    <span class="hljs-keyword">let</span> encrypted = encrypt(message, e, n);
    <span class="hljs-keyword">let</span> decrypted = decrypt(encrypted, d, n);
}
</code></pre>
<p>It is useful to put some <strong>print</strong> lines to check if the code is working properly:</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-keyword">let</span> p: <span class="hljs-built_in">u64</span> = <span class="hljs-number">61</span>;
    <span class="hljs-keyword">let</span> q: <span class="hljs-built_in">u64</span> = <span class="hljs-number">53</span>;
    <span class="hljs-keyword">let</span> (n, e, d) = generate_keys(p, q);

    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Public Key: (e: {}, n: {})"</span>, e, n);
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Private Key: (d: {}, n: {})"</span>, d, n);

    <span class="hljs-keyword">let</span> message = <span class="hljs-number">42</span>;
    <span class="hljs-keyword">let</span> encrypted = encrypt(message, e, n);
    <span class="hljs-keyword">let</span> decrypted = decrypt(encrypted, d, n);

    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Original message: {}"</span>, message);
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Encrypted message: {}"</span>, encrypted);
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Decrypted message: {}"</span>, decrypted);
}
</code></pre>
<h2 id="heading-it-is-time-to-test">It is time to test!</h2>
<p>Output:</p>
<pre><code class="lang-bash">Public Key: (e: 65537, N: 3233)
Private Key: (d: 2753, N: 3233)
Original message: 42
Encrypted message: 2557
Decrypted message: 42
</code></pre>
<p>As you can see, we are able to retrieve the original message after completing the encryption and decryption processes. So our code passed the most fundamental test:</p>
<p>$$Dec(Enc(m)) \equiv m \ mod \ N.$$</p><p>You can test this code by yourself on <a target="_blank" href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2021&amp;gist=f7b8b3ffc8fadf0af86770d12a78e8c3">Rust Playground</a>.</p>
<blockquote>
<p>Don't forget the <strong>coprimality condition</strong> when setting the primes \(p\) and \(q\).</p>
</blockquote>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In this post, we have delved deeper into the world of public-key cryptography, exploring the aspects of public and private keys, and how they are used in RSA encryption. We've discussed the importance of prime numbers in generating these keys and touched on Euler's Totient Function, which plays a crucial role in the process. We've also seen how these concepts are applied in real-world scenarios like email, social media, and blockchains. Lastly, we have taken a practical approach by implementing these concepts in Rust code, demonstrating how to generate keys and encrypt and decrypt messages.</p>
<p>I hope this series of posts has been helpful for you. See you in the next post!</p>
]]></content:encoded></item><item><title><![CDATA[Part 2: Prime Numbers | Public-Key Cryptography]]></title><description><![CDATA[Hello everyone! Welcome to the second part of the public-key cryptography series! This part is intended to give an introduction for prime numbers and their pivotal role in public-key cryptography. Additionally, you’ll find some relevant code snippets...]]></description><link>https://furkanakal.com/prime-numbers-public-key-cryptography</link><guid isPermaLink="true">https://furkanakal.com/prime-numbers-public-key-cryptography</guid><category><![CDATA[Cryptography]]></category><category><![CDATA[public key cryptography]]></category><dc:creator><![CDATA[Furkan Akal]]></dc:creator><pubDate>Sun, 28 Jan 2024 19:05:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1706469161333/959a7c5f-aec0-441b-85c2-14af621d1a87.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone! Welcome to the second part of the public-key cryptography series! This part is intended to give an introduction for prime numbers and their pivotal role in public-key cryptography. Additionally, you’ll find some relevant code snippets (written in Rust) to support the given mathematical idea.</p>
<h2 id="heading-contents">Contents</h2>
<ol>
<li><p>What is a prime number, though?</p>
<ol>
<li><p>Definition and Basic Properties</p>
<ol>
<li><p>Definition</p>
</li>
<li><p>Unique Factorization</p>
</li>
<li><p>Infinitude of Prime Numbers</p>
</li>
</ol>
</li>
<li><p>History</p>
</li>
</ol>
</li>
<li><p>How to find them?</p>
<ol>
<li><p>Trial Division</p>
</li>
<li><p>Sieve of Eratosthenes</p>
</li>
<li><p>Probabilistic Tests</p>
</li>
</ol>
</li>
<li><p>Modular Arithmetic</p>
<ol>
<li><p>Definition</p>
</li>
<li><p>Example</p>
</li>
<li><p>Modular Inverse</p>
</li>
<li><p>Euclidean Algorithm</p>
</li>
<li><p>Extended Euclidean Algorithm</p>
</li>
</ol>
</li>
<li><p>From Theory to Hands-On Practice</p>
<ol>
<li>Rust Code</li>
</ol>
</li>
<li><p>Conclusion</p>
</li>
</ol>
<h2 id="heading-what-is-a-prime-number-though">What is a prime number, though?</h2>
<h3 id="heading-definition-and-basic-properties">Definition and Basic Properties</h3>
<blockquote>
<p><strong>Definition:</strong> A <a target="_blank" href="https://en.wikipedia.org/wiki/Natural_number">natural number</a> is called a <strong>prime number (</strong>or <strong>prime)</strong> if it is greater than 1 and cannot be written as the product of two smaller natural numbers.</p>
</blockquote>
<p>For example, 13 is prime because the only way of writing it as a product, 1 × 13 or 13 × 1. However, 14 is not prime because it can be written as a product, 7 × 2 or 2 × 7.</p>
<h4 id="heading-prime-factorization">Prime Factorization</h4>
<p>Writing a natural number as a product of prime numbers is called a <strong>prime factorization</strong> of the number. For example:</p>
<p>The terms in the expression are called <strong>prime factors</strong>.</p>
<p>The fundamental significance of prime numbers to number theory in general comes from the <strong>fundamental theorem of arithmetic</strong>.</p>
<blockquote>
<p><strong>Fundamental Theorem of Arithmetic:</strong> Every integer larger than 1 can be written as a product of one or more primes.</p>
</blockquote>
<p>More strongly, this product is unique in the sense that any two prime factorizations of the same number will have the same numbers of copies of the same primes, although their ordering may differ. So, although there are many different ways of finding a factorization using an <a target="_blank" href="https://en.wikipedia.org/wiki/Integer_factorization">integer factorization</a> algorithm, they all must produce the same result. Primes can thus be considered the "basic building blocks" of the natural numbers.</p>
<h4 id="heading-infinitude-of-prime-numbers">Infinitude of Prime Numbers</h4>
<p>There are infinitely many prime numbers, so the following sequence never ends:</p>
<p>We have many proofs for this statement.</p>
<p><strong>Euclid’s Proof:</strong> Euclid proposed a proof published in his well-known <em>Elements.</em></p>
<p>Consider any <strong>finite</strong> list of prime numbers:</p>
<p>Let P be the product of all the prime numbers in this list:</p>
<p>Now, let <em>q</em> = <em>P</em> + 1. Then <em>q</em> is either prime, or not:</p>
<ul>
<li><p>If <em>q</em> is prime, then there is at least one more prime that is not in the list, <em>q</em> itself.</p>
</li>
<li><p>If <em>q</em> is not prime, then some prime factor <em>p</em> is supposed to divide <em>q</em>. But <em>p</em> also divides <em>P</em> + 1 = <em>q</em>, as just proposed. If <em>p</em> divides <em>P</em> and also <em>q</em>, then <em>p</em> must also divide the difference (that is equal to 1). Since no prime number divides 1, <em>p</em> cannot be in the list. This means that at least one more prime number exists beyond those in the list.</p>
</li>
</ul>
<h3 id="heading-history">History</h3>
<p>The <a target="_blank" href="https://en.wikipedia.org/wiki/Rhind_Mathematical_Papyrus">Rhind Mathematical Papyrus</a>, from around 1550 BC, has <a target="_blank" href="https://en.wikipedia.org/wiki/Egyptian_fraction">Egyptian fraction</a> expansions of different forms for prime and composite numbers. However, the earliest surviving records of the study of prime numbers come from the <a target="_blank" href="https://en.wikipedia.org/wiki/Greek_mathematics">ancient Greek mathematians</a>, who called them <em>prōtos arithmòs</em> (πρῶτος ἀριθμὸς). <a target="_blank" href="https://en.wikipedia.org/wiki/Euclid">Euclid</a>'s <a target="_blank" href="https://en.wikipedia.org/wiki/Euclid%27s_Elements"><em>Elements</em></a> (c. 300 BC) proves the <a target="_blank" href="https://en.wikipedia.org/wiki/Infinitude_of_primes">infinitude of primes</a> and the <a target="_blank" href="https://en.wikipedia.org/wiki/Fundamental_theorem_of_arithmetic">fundamental theorem of arithmetic</a>, and shows how to construct a <a target="_blank" href="https://en.wikipedia.org/wiki/Perfect_number">perfect number</a> from a <a target="_blank" href="https://en.wikipedia.org/wiki/Mersenne_prime">Mersenne prime</a>.</p>
<p><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ee4723e-e69a-410e-88ca-2296a48b4f56_750x449.jpeg" alt /></p>
<p>Around 1000 AD, the <a target="_blank" href="https://en.wikipedia.org/wiki/Mathematics_in_medieval_Islam">Islamic</a> mathematician <a target="_blank" href="https://en.wikipedia.org/wiki/Ibn_al-Haytham">Ibn al-Haytham</a> (Alhazen) found <a target="_blank" href="https://en.wikipedia.org/wiki/Wilson%27s_theorem">Wilson's theorem</a>, characterizing the prime numbers as the numbers n that evenly divide</p>
<p>He also conjectured that all even perfect numbers come from Euclid's construction using Mersenne primes, but was unable to prove it.</p>
<p>In 1640, Pierre de Fermat stated Fermat’s Little Theorem.</p>
<blockquote>
<p><strong>Fermat’s Little Theorem:</strong> If <em>p</em> is a prime and <em>a</em> is any integer not divisible by <em>p</em>, then <em>a</em> <em><sup>p</sup></em> <sup> − 1</sup> − 1 is divisible by <em>p.</em></p>
</blockquote>
<p>In 1742, Christian Goldbach formulated Goldbach’s conjecture:</p>
<blockquote>
<p><strong>Goldbach’s Conjecture:</strong> Every even natural number greater than 2 is the sum of two prime numbers.</p>
</blockquote>
<h2 id="heading-how-to-find-them">How to find them?</h2>
<h3 id="heading-trial-division">Trial Division</h3>
<p>It is the most intuitive and straightforward method to determine if an integer is prime. You basically;</p>
<ol>
<li><p>begin with the smallest prime number 2,</p>
</li>
<li><p>divide the given number by the prime number to check if it’s a divisor,</p>
</li>
<li><p>repeat the process by performing the division by the next prime.</p>
</li>
</ol>
<p>As you may notice, this method is effective for small numbers or numbers with small factors. It becomes impractical for large numbers as the number of divisions (and the time required) increase rapidly.</p>
<h3 id="heading-sieve-of-eratosthenes">Sieve of Eratosthenes</h3>
<p><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa906ddf5-d09e-46e5-91e6-615ebe5903c1_278x275.png" alt /></p>
<p>It is one of the ancient methods to find all prime numbers up to a specified integer. You;</p>
<ol>
<li><p>start by listing all the numbers from 2 to the maximum number <em>N</em> you' chose,</p>
</li>
<li><p>identify the first prime in the list, which is 2,</p>
</li>
<li><p>remove all multiples of this prime number from the list except the prime itself (2, 4, 6, 8, …),</p>
</li>
<li><p>move to the next number in the list that has not been removed, that is the next prime,</p>
</li>
<li><p>repeat the process.</p>
</li>
</ol>
<h3 id="heading-probabilistic-tests">Probabilistic Tests</h3>
<ul>
<li><p><a target="_blank" href="https://en.wikipedia.org/wiki/Fermat_primality_test">Fermat Primality Test</a>,</p>
</li>
<li><p><a target="_blank" href="https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test">Miller-Rabin Primality Test</a>,</p>
</li>
<li><p><a target="_blank" href="https://en.wikipedia.org/wiki/Solovay%E2%80%93Strassen_primality_test">Solovay-Strassen Primality Test</a>.</p>
</li>
</ul>
<h2 id="heading-modular-arithmetic">Modular Arithmetic</h2>
<blockquote>
<p><strong>Definition:</strong> Given an integer <em>n</em> &gt; 1, called a <strong>modulus</strong>, two integers <em>a</em> and <em>b</em> are said to be <strong>congruent modulo <em>n</em></strong>, if <em>n</em> is a divisor of their difference; that is, if there is an integer <em>k</em> such that</p>
</blockquote>
<p>Congruence modulo <em>n</em> is denoted as</p>
<h3 id="heading-example">Example</h3>
<p>In modulus 17:</p>
<p>Because the difference is 62 - 28 = 34 = 2 × 17, a multiple of 17.</p>
<p>Equivalently, 62 and 28 have the same remainder when 11 when divided by 17.</p>
<h3 id="heading-modular-inverse">Modular Inverse</h3>
<p>Notion of modular inverse and finding the modular inverse of an integer are crucially important in cryptography.</p>
<blockquote>
<p>A <strong>modular inverse</strong> of an integer a is an integer b such that the product ab is congruent to 1 with respect to the modulus m.</p>
</blockquote>
<p>This congruence is written as</p>
<p>Our goal is to find such <em>b</em> for an integer <em>a</em> for given modulo <em>m</em>.</p>
<h3 id="heading-euclidean-algorithm">Euclidean Algorithm</h3>
<p>Recall from high school that <strong>greatest common divisor (GCD)</strong> of two integers <em>x</em> and <em>y</em> is the largest integer that divides both <em>x</em> and <em>y</em>.</p>
<blockquote>
<p>The <strong>Euclidean algorithm</strong> is a technique for finding the GCD of two integers.</p>
</blockquote>
<ol>
<li><p>Given two integers <em>a</em> and <em>b</em>, ensure <em>a</em>\&gt;<em>b</em>. If <em>a</em>&lt;<em>b</em>, swap them.</p>
</li>
<li><p>Divide <em>a</em> by <em>b</em>, and take note of the remainder, <em>r</em>.</p>
</li>
<li><p>Replace <em>a</em> with <em>b</em> and <em>b</em> with <em>r</em>.</p>
</li>
<li><p>Repeat steps 2 and 3 until <em>b</em> becomes 0. The non-zero remainder at this point, which will be in the place of <em>a</em>, is the GCD of the original <em>a</em> and <em>b</em>.</p>
</li>
</ol>
<p><strong>Example:</strong></p>
<p>To find gcd⁡(48,18)gcd(48,18):</p>
<ul>
<li><p>Step 1: 48 divided by 18 gives a remainder of 12 (48=18×2+12).</p>
</li>
<li><p>Step 2: Replace 48 with 18 and 18 with 12, then divide 18 by 12 giving a remainder of 6 (18=12×1+6).</p>
</li>
<li><p>Step 3: Replace 18 with 12 and 12 with 6, then divide 12 by 6 giving a remainder of 0 (12=6×2+0).</p>
</li>
<li><p>Since the remainder is 0, the GCD is the last non-zero remainder, which is 6.</p>
</li>
</ul>
<h3 id="heading-extended-euclidean-algorithm"><strong>Extended Euclidean Algorithm</strong></h3>
<p>The <strong>Extended Euclidean algorithm</strong> is an extension of the Euclidean Algorithm. It not only finds the GCD of two integers <em>a</em> and <em>b</em> but also finds integers <em>x</em> and <em>y</em> (coefficients) such that <em>ax</em> + <em>by</em> \= gcd(<em>a</em>, <em>b</em>).</p>
<p><strong>Algorithm Steps:</strong></p>
<ol>
<li><p>Initialize two pairs of coefficients (<em>x</em>1​, <em>y</em>1​)=(1, 0) and (<em>x</em>2​, <em>y</em>2​)=(0, 1). These represent the coefficients for <em>a</em> and <em>b</em> in the equation <em>ax</em> + <em>by</em> \= gcd(<em>a</em>, <em>b</em>).</p>
</li>
<li><p>Perform the Euclidean Algorithm steps on <em>a</em> and <em>b</em>. Simultaneously, update the coefficients <em>x</em>1​, <em>y</em>1​, <em>x</em>2​, and <em>y</em>2​ with each division step.</p>
<ul>
<li><p>After each division <em>a</em>\=<em>bq</em> + <em>r</em>, update <em>a</em> and <em>b</em> as in the Euclidean algorithm.</p>
</li>
<li><p>Update <em>x</em>1​ and <em>y</em>1​ to <em>x</em>2​ and <em>y</em>2​, respectively.</p>
</li>
<li><p>Update <em>x</em>2​ and <em>y</em>2​ to <em>x</em>1​ − <em>q</em> × <em>x</em>2​ and <em>y</em>1​ − <em>q</em> × <em>y</em>2​, respectively.</p>
</li>
</ul>
</li>
<li><p>Continue until <em>b</em> becomes 0. At this point, <em>a</em> is the GCD, and <em>x</em>1​ and <em>y</em>1​ will be the coefficients that satisfy <em>ax</em> + <em>by</em> \= gcd(<em>a</em>, <em>b</em>).</p>
</li>
</ol>
<p><strong>Example:</strong></p>
<p>To find coefficients <em>x</em> and <em>y</em> such that 48<em>x</em> + 18<em>y</em> \= gcd(48, 18):</p>
<p>Following the steps of the algorithm will lead you to calculate the coefficients alongside finding the GCD. For this particular example, you'll end up with specific <em>x</em> and <em>y</em> values that, when multiplied by 48 and 18 respectively and added, equal 6 (the GCD).</p>
<h2 id="heading-from-theory-to-hands-on-practice">From Theory to Hands-On Practice</h2>
<h3 id="heading-rust-code">Rust Code</h3>
<p>Let us start by initializing our function with some initial variable assignments:</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">mod_inverse</span></span>(a: <span class="hljs-built_in">i64</span>, m: <span class="hljs-built_in">i64</span>) -&gt; <span class="hljs-built_in">i64</span> {
    <span class="hljs-keyword">let</span> (<span class="hljs-keyword">mut</span> m0, <span class="hljs-keyword">mut</span> x0, <span class="hljs-keyword">mut</span> x1) = (m, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>);
    <span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> a = a;
}
</code></pre>
<ul>
<li><p><em>m0</em> is set to <em>m</em> to remember the original value of <em>m</em> throughout the algorithm.</p>
</li>
<li><p><em>x0</em> and <em>x1</em> are initialized to 0 and 1, respectively. These variables are used to keep track of the coefficients of <em>a</em> and <em>m</em> in the <em>Extended Euclidean algorithm</em>. By the end of the algorithm, <em>x1</em> will hold the modular inverse of <em>a</em> modulo <em>m</em>.</p>
</li>
</ul>
<p>Before diving deeper, we need to handle an edge case.</p>
<pre><code class="lang-rust">    <span class="hljs-keyword">if</span> m == <span class="hljs-number">1</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    }
</code></pre>
<ul>
<li>If m is 1, the function immediately returns 0 as the modular inverse does not exist in this case.</li>
</ul>
<p>Now, we can construct the algorithm using a loop:</p>
<pre><code class="lang-rust">    <span class="hljs-keyword">while</span> a &gt; <span class="hljs-number">1</span> {
        <span class="hljs-keyword">let</span> q = a / m;
        <span class="hljs-keyword">let</span> t = m;
        m = a % m; a = t;
        <span class="hljs-keyword">let</span> t = x0;
        x0 = x1 - q * x0;
        x1 = t;
    }
</code></pre>
<ul>
<li><p>The loop will iterate as long as <em>a</em> is greater than 1.</p>
</li>
<li><p><em>q</em> is the quotient of the division of <em>a</em> by <em>m</em>.</p>
</li>
<li><p>The algorithm then updates <em>a</em> and <em>m</em> using the <em>Euclidean algorithm</em> to find the GCD. So <em>m</em> becomes <em>a</em>%<em>m</em> and <em>a</em> takes on the old value of <em>m</em>.</p>
</li>
<li><p>Simultaneously, it updates <em>x0</em> and <em>x1</em>, which are tracking the coefficients for <em>a</em> and m that would be used to express the GCD as a linear combination of <em>a</em> and <em>m</em>. The goal here is to keep updating these coefficients until we find the modular inverse.</p>
</li>
</ul>
<p>Before returning the modular inverse, let’s be cool and check if the result needs any sign adjustment:</p>
<pre><code class="lang-rust">    <span class="hljs-keyword">if</span> x1 &lt; <span class="hljs-number">0</span> {
        x1 += m0;
    }
</code></pre>
<ul>
<li>Once the loop exits, <em>x1</em> may hold the modular inverse of <em>a</em> modulo <em>m</em>, but it might be negative. In such a case, we just add <em>m0</em> to ensure the modular inverse is positive.</li>
</ul>
<p>Now, it’s time to return the modular inverse, which is completing our function:</p>
<pre><code class="lang-rust">    <span class="hljs-keyword">return</span> x1
</code></pre>
<p>OR</p>
<pre><code class="lang-rust">    x1
</code></pre>
<blockquote>
<p>In Rust, the final expression in the function is used as return value.</p>
</blockquote>
<p>So, final version of our code is as follows:</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">mod_inverse</span></span>(<span class="hljs-keyword">mut</span> a: <span class="hljs-built_in">i64</span>, <span class="hljs-keyword">mut</span> m: <span class="hljs-built_in">i64</span>) -&gt; <span class="hljs-built_in">i64</span> {
    <span class="hljs-keyword">let</span> (m0, <span class="hljs-keyword">mut</span> x0, <span class="hljs-keyword">mut</span> x1) = (m, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>);

    <span class="hljs-keyword">if</span> m == <span class="hljs-number">1</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    }

    <span class="hljs-keyword">while</span> a &gt; <span class="hljs-number">1</span> {
        <span class="hljs-keyword">let</span> q = a / m;
        <span class="hljs-keyword">let</span> t = m;
        m = a % m; a = t;
        <span class="hljs-keyword">let</span> t = x0;
        x0 = x1 - q * x0;
        x1 = t;
    }

    <span class="hljs-keyword">if</span> x1 &lt; <span class="hljs-number">0</span> {
        x1 += m0;
    }

    x1
}
</code></pre>
<p>Let’s see if it’s working. We can try to find the modular inverse of 4 modulo 11:</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"{}"</span>, mod_inverse(<span class="hljs-number">4</span>, <span class="hljs-number">11</span>));
}
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">3
</code></pre>
<p>It’s correct, right? If you multiply 4 by 3, you obtain 12 that is equivalent to 1 in mod 11.</p>
<p>You can test this code by yourself on <a target="_blank" href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2021&amp;gist=2c3a5939d666385c1f79b8b08d390bc7">Rust Playground</a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this post, we've delved into the world of prime numbers and modular arithmetic, exploring their pivotal roles within the historical evolution of mathematics. We've also discussed the Euclidean algorithm, a cornerstone for understanding how to compute the modular inverse—a critical operation in cryptographic systems. To bridge theory with practice, I've provided a Rust code snippet that demonstrates how to calculate the modular inverse of an integer modulo <em>m</em>.</p>
<p>Looking ahead, the next post will shift focus to cryptographic key pairs. We'll explore their significance in securing digital communication and walk through the process of generating them. This upcoming discussion promises to further demystify the complex yet intriguing field of cryptography, equipping you with the knowledge to understand and apply these concepts in real-world scenarios.</p>
<h2 id="heading-image-reference">Image Reference</h2>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Rhind_Mathematical_Papyrus#/media/File:Rhind_Mathematical_Papyrus.jpg">https://en.wikipedia.org/wiki/Rhind_Mathematical_Papyrus#/media/File:Rhind_Mathematical_Papyrus.jpg</a></p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Eratosthenes#/media/File:Eratosthenes_profile.png">https://en.wikipedia.org/wiki/Eratosthenes#/media/File:Eratosthenes_profile.png</a></p>
]]></content:encoded></item><item><title><![CDATA[Part 1: Introduction | Public-Key Cryptography]]></title><description><![CDATA[Hello everyone! Welcome to the first part of the public-key cryptography series! This series of posts is intended to give the basics of cryptography and specifically public-key encryption. In each post (coming after this one), you’ll find some code s...]]></description><link>https://furkanakal.com/introduction-public-key-cryptography</link><guid isPermaLink="true">https://furkanakal.com/introduction-public-key-cryptography</guid><category><![CDATA[Cryptography]]></category><category><![CDATA[public key cryptography]]></category><dc:creator><![CDATA[Furkan Akal]]></dc:creator><pubDate>Sun, 28 Jan 2024 19:01:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1706469139006/80780d88-249d-48d3-b775-b77b441cf1db.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone! Welcome to the first part of the public-key cryptography series! This series of posts is intended to give the basics of cryptography and specifically public-key encryption. In each post (coming after this one), you’ll find some code snippets (written in Rust) to support the given mathematical idea. At the end of the series, I’m aiming to provide readers with;</p>
<ul>
<li><p>basic understanding of cryptography,</p>
</li>
<li><p>mathematical fundamentals of public-key cryptography,</p>
</li>
<li><p>a concise Rust code to generate the keys, apply the relevant mathematical operations, and encrypt/decrypt a message.</p>
</li>
</ul>
<h2 id="heading-contents">Contents</h2>
<ol>
<li><p>What is cryptography?</p>
<ol>
<li>Terminology</li>
</ol>
</li>
<li><p>Historical Background</p>
<ol>
<li><p>Ancient Origins</p>
</li>
<li><p>Middle Ages to Renaissance</p>
</li>
<li><p>The Age of Mechanical Devices</p>
</li>
<li><p>The Modern Era</p>
</li>
</ol>
</li>
<li><p>Types of Cryptography</p>
<ol>
<li><p>Symmetric Cryptography (Private-Key Encryption)</p>
</li>
<li><p>Aysmmetric Cryptography (Public-Key Encryption)</p>
</li>
</ol>
</li>
<li><p>Cryptanalysis</p>
<ol>
<li>Methods</li>
</ol>
</li>
<li><p>Conclusion</p>
</li>
</ol>
<h2 id="heading-what-is-cryptography">What is cryptography?</h2>
<blockquote>
<p>Cryptography is a branch of mathematics focusing on the development of techniques for secure communication. Main goal is to protect the privacy and integrity of any information from third parties.</p>
</blockquote>
<p>The word comes from Greek <em>kryptós</em>, meaning "secret," and <em>graphein</em>, meaning "to write." It may be translated as “secret writing”.</p>
<p><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86e179b8-1076-4c49-8db2-febd9e958c38_600x400.jpeg" alt /></p>
<h3 id="heading-terminology">Terminology</h3>
<ul>
<li><p><strong>Plaintext:</strong> It is the original, readable, and unencrypted data or message.</p>
</li>
<li><p><strong>Ciphertext:</strong> It refers to the encrypted data or message produced by the encryption process. It’s supposed to be unreadable or unintelligible to unauthorized individuals.</p>
</li>
<li><p><strong>Key:</strong> It is a piece of information, usually a string of characters, that determines the functional output of a cryptographic algorithm.</p>
</li>
<li><p><strong>Encryption:</strong> It is the process of converting plaintext into ciphertext. It involves using a cryptographic algorithm and a key to transform the readable data (plaintext) into an unreadable format (ciphertext).</p>
</li>
<li><p><strong>Decryption:</strong> It is the reverse process of encryption. It involves converting ciphertext back into its original plaintext form.</p>
</li>
</ul>
<h2 id="heading-historical-background">Historical Background</h2>
<h3 id="heading-ancient-origins">Ancient Origins</h3>
<p>The use of cryptography dates back to ancient civilizations. The earliest known use was in Egypt, around 1900 BCE, where hieroglyphs were used in an unusual way, possibly to hide the actual message.</p>
<p>The Greeks and Romans also advanced some cryptographic techniques. The most popular example is the <a target="_blank" href="https://en.wikipedia.org/wiki/Caesar_cipher">Caesar cipher</a> which I'll give more details in the upcoming sections of this post.</p>
<h3 id="heading-the-middle-ages-to-renaissance">The Middle Ages to Renaissance</h3>
<p>The Arab mathematician, Al-Kindi, in the 9th century, wrote a manuscript on deciphering encrypted messages, introducing <a target="_blank" href="https://www.telsy.com/en/al-kindi-the-father-of-cryptanalysis/">frequency analysis</a> to break substitution ciphers.</p>
<p>During the Renaissance, European cryptographers developed more sophisticated methods for encryption like the [Vigenere cipher](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher#:~:text=The%20Vigen%C3%A8re%20cipher%20(French%20pronunciation,of%20another%20text%2C%20the%20key.), a method using a series of different Caesar ciphers based on the letters of a keyword.</p>
<h3 id="heading-the-age-of-mechanical-devices">The Age of Mechanical Devices</h3>
<p>The most popular example would be German's <a target="_blank" href="https://en.wikipedia.org/wiki/Enigma_machine">Enigma machine</a> that is used during World War II. It employed a complex system of rotors and electrical circuits to encrypt messages.</p>
<p><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e1ce57b-3180-47df-a39a-5adf62cf159d_921x627.jpeg" alt /></p>
<h3 id="heading-the-modern-era">The Modern Era</h3>
<p>Following the advancement in computer technology, science of cryptography had also a major transformation. In the 1970s, the <a target="_blank" href="https://en.wikipedia.org/wiki/Data_Encryption_Standard">Data Encryption Standard (DES)</a> was developed by IBM.</p>
<p>One of the most groundbreaking development was the introduction of public-key cryptography in the 1970s by <a target="_blank" href="https://en.wikipedia.org/wiki/Whitfield_Diffie">Whitfield Diffie</a> and <a target="_blank" href="https://en.wikipedia.org/wiki/Martin_Hellman">Martin Hellman</a>. It solved the problem of secure key distribution which was significant limitation back then.</p>
<h2 id="heading-types-of-cryptography">Types of Cryptography</h2>
<p>Cryptography is mainly divided into two paradigms:</p>
<ol>
<li><p>Symmetric cryptography (private-key encryption)</p>
</li>
<li><p>Asymmetric cryptography (public-key encryption)</p>
</li>
</ol>
<h3 id="heading-symmetric-cryptography">Symmetric Cryptography</h3>
<blockquote>
<p>In symmetric cryptography, the same key is used for both encryption and decryption.</p>
</blockquote>
<h4 id="heading-flow">Flow:</h4>
<ol>
<li><p>Alice encrypts her message (plaintext) using <strong>the key</strong> and sends it to Bob.</p>
</li>
<li><p>Bob receives the encrypted message (ciphertext), decrypts it using the same key, and then reads it.</p>
</li>
</ol>
<h4 id="heading-example-caesar-cipher">Example: Caesar Cipher</h4>
<p>Caesar cipher, also known as the shift cipher, is one of the simplest and most widely known encryption techniques. Each letter in the plaintext message is shifted forward in the alphabet by the key number of places. If the shift takes you past 'Z', you wrap around to the start of the alphabet. For example, with a shift of 3:</p>
<ul>
<li><p>'HELLO' becomes 'KHOOR'.</p>
</li>
<li><p>'CAESAR CIPHER' becomes 'FDHVDU FLSKHU'.</p>
</li>
</ul>
<p>In order to decrypt a ciphertext, the same process is applied backwards.</p>
<p>As you might have noticed;</p>
<p><strong>Encrypting function:</strong> Shifting the letters forward:</p>
<p>where</p>
<ul>
<li><p>x = index of the letter in the alphabet,</p>
</li>
<li><p>n = number of shifting.</p>
</li>
</ul>
<p><strong>Decrypting function:</strong> Shifting the letters backwards:</p>
<p>where</p>
<ul>
<li><p>x = index of the letter in the alphabet,</p>
</li>
<li><p>n = number of shifting.</p>
</li>
</ul>
<p><strong>Key:</strong> How many times the number will be shifted:</p>
<h4 id="heading-limitation">Limitation</h4>
<p>Both parties are responsible with protecting secrecy of the key as well, in addition to the encrypting and decryption functions.</p>
<h3 id="heading-asymmetric-cryptography">Asymmetric Cryptography</h3>
<blockquote>
<p>In asymmetric cryptography, different keys are used for encryption and decryption.</p>
</blockquote>
<p><strong>Private Key:</strong> It is used for decryption. Private keys must be kept secure and confidential by its owner.</p>
<p><strong>Public Key:</strong> It is used for encryption and generated from private keys. Public keys can be distributed widely.</p>
<p>We will dive into more details of these in the 3rd post of this series, <em>keys</em>.</p>
<h4 id="heading-flow-1">Flow</h4>
<ol>
<li><p>Alice encrypts her message (plaintext) using Bob’s public key, and sends it to Bob.</p>
</li>
<li><p>Bob receives the encrypted message (ciphertext), decrypts it using his own private key, and then reads it.</p>
</li>
</ol>
<h4 id="heading-formal-expression">Formal Expression</h4>
<p>Encryption process:</p>
<p>where</p>
<ul>
<li><p><strong>E:</strong> encrypting function,</p>
</li>
<li><p><strong>pub:</strong> public key of the recipient,</p>
</li>
<li><p><strong>m:</strong> message to be encrypted,</p>
</li>
<li><p><strong>c:</strong> encrypted message or ciphertext.</p>
</li>
</ul>
<p>Decryption process:</p>
<p>where</p>
<ul>
<li><p><strong>D:</strong> decrypting function,</p>
</li>
<li><p><strong>priv:</strong> private key of the recipient,</p>
</li>
<li><p><strong>c:</strong> ciphertext to be decrypted,</p>
</li>
<li><p><strong>m:</strong> decrypted message (plaintext).</p>
</li>
</ul>
<p>Crucial point here is that the following equation must be satisfied for all messages:</p>
<p>If this equation holds, then the decrypting function can always be used consistently.</p>
<h2 id="heading-cryptanalysis">Cryptanalysis</h2>
<blockquote>
<p>Cryptanalysis is the study of analyzing information systems to understand the hidden aspects. It’s primarily used to break cryptographic security systems and gain access to the contents of encrypted messages, even if the cryptographic key is unknown.</p>
</blockquote>
<h3 id="heading-methods">Methods</h3>
<p><strong>Brute Force Attack:</strong> It involves trying every possible key until the correct one is found. Although it’s simple, it can be extremely time-consuming for systems with large key spaces.</p>
<p><strong>Frequency Analysis:</strong> Recall the Caesar cipher, which is a type of substitution ciphers, that the letters in the message were shifted according to the key. This method involves studying the frequency of letters or groups of letters in a ciphertext. I't’s effective against simple substitution ciphers where certain letters or patterns occur more frequently.</p>
<p><strong>Side-Channel Attacks:</strong> These attacks exploit information gained from the physical implementation of a cryptosystem, such as timing information, power consumption, electromagnetic leaks, or even sound.</p>
<p><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4b031ca-3e8d-4e65-96e3-52de3526e04a_491x550.jpeg" alt /></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this post, I’ve tried to explain some fundamental concepts in basic cryptography and their historical background.</p>
<p>As progress in this series, we will dive deeper into the mathematical underpinnings of public-key cryptography and explore practical implementations using Rust. My aim is not just to understand the theoretical aspects but also to see how these concepts come to life in code.</p>
<h2 id="heading-image-reference">Image Reference</h2>
<p><a target="_blank" href="https://makeameme.org/meme/crypto-means-cryptography">https://makeameme.org/meme/crypto-means-cryptography</a></p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Enigma_machine#/media/File:Enigma-plugboard.jpg">https://en.wikipedia.org/wiki/Enigma_machine#/media/File:Enigma-plugboard.jpg</a></p>
<p><a target="_blank" href="https://imgflip.com/tag/brute+force">https://imgflip.com/tag/brute+force</a></p>
]]></content:encoded></item></channel></rss>