<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Anurag Jain</title>
    <description>The latest articles on DEV Community by Anurag Jain (@mejainanurag).</description>
    <link>https://dev.to/mejainanurag</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3762640%2Fa6327e41-f59e-48ca-be0b-f03ae0dc074f.png</url>
      <title>DEV Community: Anurag Jain</title>
      <link>https://dev.to/mejainanurag</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mejainanurag"/>
    <language>en</language>
    <item>
      <title>Decoding Cryptography: From Perfect Secrecy to Computational Security</title>
      <dc:creator>Anurag Jain</dc:creator>
      <pubDate>Thu, 09 Jul 2026 14:32:42 +0000</pubDate>
      <link>https://dev.to/mejainanurag/decoding-cryptography-from-perfect-secrecy-to-computational-security-2m6f</link>
      <guid>https://dev.to/mejainanurag/decoding-cryptography-from-perfect-secrecy-to-computational-security-2m6f</guid>
      <description>&lt;h2&gt;
  
  
  (Lion Roaring)…
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://dev.to/mejainanurag/decoding-cryptography-understanding-the-attacker-and-the-4-attack-models-1hig"&gt;Blog 1&lt;/a&gt;, I set up Alice, Bob, and the postman. In the &lt;a href="https://dev.to/mejainanurag/decoding-cryptography-the-fall-of-historical-ciphers-339j"&gt;last blog&lt;/a&gt;, I broke three historical ciphers, watched the postman evolve from barbarian to statistician to pattern hunter, and arrived at three pillars of modern cryptography: formal definitions, precise assumptions, and rigorous proofs.&lt;/p&gt;

&lt;p&gt;I ended with a mathematical definition that looked like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;∀ m0, m1 ∈ M, ∀ c ∈ C:   Pr[C = c | M = m0] = Pr[C = c | M = m1]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'd promised to explain what this means, build something that achieves it, and then show why even &lt;em&gt;that&lt;/em&gt; isn't enough.&lt;/p&gt;

&lt;p&gt;More math incoming, I said. I wasn't kidding.&lt;/p&gt;




&lt;h2&gt;
  
  
  Computation Theory Primer
&lt;/h2&gt;

&lt;p&gt;In math, vague words cause vague security, and vague security is no security at all.&lt;/p&gt;

&lt;p&gt;Before I can define what "perfect" security means, I need three precise concepts. Think of them as the grammar we'll write the rest of modern cryptography in.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Security Parameter
&lt;/h3&gt;

&lt;p&gt;Imagine your encryption system has one master control: how hard it is to break. Crank it up, and the system becomes more secure, but also slower. Crank it down, and it's faster but weaker.&lt;/p&gt;

&lt;p&gt;This control has a name: the &lt;strong&gt;security parameter&lt;/strong&gt;, denoted &lt;strong&gt;n&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In symmetric encryption, n is typically the key length in bits (128, 256, etc). Once we fix n, &lt;em&gt;everything&lt;/em&gt; becomes a function of it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The running time of Gen, Enc, Dec&lt;/li&gt;
&lt;li&gt;The running time of any adversarial algorithm&lt;/li&gt;
&lt;li&gt;The probability that an adversary breaks the scheme&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By expressing everything as a function of n, we can talk about how quantities &lt;em&gt;grow&lt;/em&gt; as we scale, rather than arguing about specific numbers. A question like "is this cipher secure?" becomes "does security hold &lt;em&gt;for all sufficiently large n&lt;/em&gt;?"&lt;/p&gt;

&lt;h3&gt;
  
  
  Efficient Algorithms
&lt;/h3&gt;

&lt;p&gt;Not all algorithms are created equal. An algorithm that takes n² steps is fine. One that takes n&lt;sup&gt;10&lt;/sup&gt; steps is annoying but feasible. One that takes 2&lt;sup&gt;n&lt;/sup&gt; steps? For n = 256, that's too much.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An algorithm A is &lt;strong&gt;efficient&lt;/strong&gt; (or &lt;strong&gt;polynomial-time&lt;/strong&gt;) if there exists a polynomial p(·) such that for every input x, A terminates within p(|x|) steps, where |x| is the size of the input.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Polynomial: n&lt;sup&gt;2&lt;/sup&gt;, n&lt;sup&gt;3&lt;/sup&gt;, n&lt;sup&gt;10&lt;/sup&gt;. Superpolynomial: 2&lt;sup&gt;n&lt;/sup&gt;, n!, n&lt;sup&gt;n&lt;/sup&gt;. The gap between these two worlds is the difference between efficient and inefficient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqtvntazl2hsjlsutno1f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqtvntazl2hsjlsutno1f.png" alt="Polynomial vs. Exponential Growth" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does this matter?&lt;/strong&gt; It gives us a sanity requirement on any encryption scheme.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Gen, Enc, and Dec must all run in &lt;strong&gt;polynomial time&lt;/strong&gt; in n.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If decryption takes 2&lt;sup&gt;n&lt;/sup&gt; steps, even Bob can't read his own messages. Not useful.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pause. So far: n is the dial, polynomial time is "efficient". One more concept to go.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Negligible Functions
&lt;/h3&gt;

&lt;p&gt;Intuitively, a negligible quantity is one that is "so small, we can safely ignore it." But how small is that? Smaller than 1/1000? Smaller than 1/10&lt;sup&gt;20&lt;/sup&gt;? Those are concrete numbers. But negligible is a comparative term.&lt;/p&gt;

&lt;p&gt;What I want is something that shrinks &lt;em&gt;faster than the inverse of any polynomial&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A function f(n) is &lt;strong&gt;negligible&lt;/strong&gt; if ∀ positive polynomials p(n), ∃ N such that ∀ n &amp;gt; N:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;f(n) &amp;lt; 1/p(n)&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Equivalently, ∀ positive constants c, ∃ N such that ∀ n &amp;gt; N, f(n) &amp;lt; n&lt;sup&gt;−c&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;(These are equivalent because any polynomial p(n) is eventually dominated by n&lt;sup&gt;c&lt;/sup&gt; for some c. So "smaller than 1/p(n) for every polynomial" means the same as "smaller than n&lt;sup&gt;-c&lt;/sup&gt; for every constant c".)&lt;/p&gt;

&lt;p&gt;The key observation: &lt;strong&gt;no polynomial function is ever negligible&lt;/strong&gt;, no matter how large the exponent. But &lt;strong&gt;exponential&lt;/strong&gt; (and sub-exponential) decay &lt;em&gt;is&lt;/em&gt; negligible. There's a hard divide between these worlds.&lt;/p&gt;

&lt;p&gt;A concrete sanity check. Take f(n) = 2&lt;sup&gt;−n&lt;/sup&gt;. For any polynomial p(n) = n&lt;sup&gt;d&lt;/sup&gt;, choose N = 2d. Then for all n &amp;gt; N:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;2&lt;sup&gt;−n&lt;/sup&gt; &amp;lt; 2&lt;sup&gt;−d log2 n&lt;/sup&gt; = n&lt;sup&gt;−d&lt;/sup&gt; = 1/p(n)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So 2&lt;sup&gt;−n&lt;/sup&gt; is indeed negligible. ✓&lt;/p&gt;

&lt;p&gt;Let's build some intuition.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Negligible?&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;sup&gt;−n&lt;/sup&gt;
&lt;/td&gt;
&lt;td&gt;✓ Yes&lt;/td&gt;
&lt;td&gt;Shrinks exponentially, easily beats any 1/p(n)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;sup&gt;−√n&lt;/sup&gt;
&lt;/td&gt;
&lt;td&gt;✓ Yes&lt;/td&gt;
&lt;td&gt;Slower, but still eventually beats every polynomial inverse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;n&lt;sup&gt;−1000&lt;/sup&gt;
&lt;/td&gt;
&lt;td&gt;✗ No&lt;/td&gt;
&lt;td&gt;It &lt;em&gt;is&lt;/em&gt; 1/p(n) for p(n) = n&lt;sup&gt;1000&lt;/sup&gt;. It can't be less than 1/n&lt;sup&gt;1001&lt;/sup&gt; for all large n&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Why is n&lt;sup&gt;−10&lt;/sup&gt; not negligible? Pause on this, it's the most common mistake. The definition demands f(n) &amp;lt; 1/p(n) for &lt;em&gt;every&lt;/em&gt; polynomial p. Pick p(n) = n&lt;sup&gt;11&lt;/sup&gt;. Then 1/p(n) = n&lt;sup&gt;−11&lt;/sup&gt;. Is n&lt;sup&gt;−10&lt;/sup&gt; &amp;lt; n&lt;sup&gt;−11&lt;/sup&gt; for all large n? No, n&lt;sup&gt;−10&lt;/sup&gt; &amp;gt; n&lt;sup&gt;−11&lt;/sup&gt; always. So it fails the definition.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Okay, enough definitions for now. Let's see why cryptographers actually care about these properties.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why These Two Concepts Work Together
&lt;/h3&gt;

&lt;p&gt;Here's the key insight: negligible functions behave exactly the way we'd hope when combined. Adding two negligible quantities doesn't suddenly make them significant. And multiplying a negligible quantity by something that grows polynomially still gives you something negligible.&lt;/p&gt;

&lt;p&gt;Formally, if negl1(n) and negl2(n) are negligible, then the following holds.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;negl1(n) + negl2(n) is negligible&lt;/li&gt;
&lt;li&gt;p(n) · negl1(n) is negligible, for any polynomial p(n)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;And if p1(n) and p2(n) are polynomial, then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;p1(n) + p2(n) is polynomial&lt;/li&gt;
&lt;li&gt;p1(n) · p2(n) is polynomial&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;(Both negligible properties can be proved by contradiction. Assume the result is not negligible ⇒ there exists a polynomial it doesn't eventually go below ⇒ one of the originals wasn't negligible either. Contradiction.)&lt;/p&gt;

&lt;p&gt;The second negligible property is the one I want you to remember. It means &lt;strong&gt;there is no amplification of a negligible advantage.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's a vivid way to see it. Toss n fair coins. The probability of all heads is (1/2)&lt;sup&gt;n&lt;/sup&gt; = 2&lt;sup&gt;−n&lt;/sup&gt;, which is negligible. Now repeat this experiment p(n) times, say n² times. What's the probability that &lt;em&gt;at least one&lt;/em&gt; trial gives all heads?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pr[∃ success in n² trials] ≤ n² · 2&lt;sup&gt;−n&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(This is an upper bound via the union bound, not necessarily equality — two trials could both succeed on the same outcome.) By the closure property, n² · 2&lt;sup&gt;−n&lt;/sup&gt; is still negligible. You could run the experiment a polynomial number of times and &lt;em&gt;still&lt;/em&gt; have a negligible chance of the rare event occurring.&lt;/p&gt;

&lt;p&gt;For cryptography, this implies that if an adversary's advantage in one attack is negligible, running the attack polynomially many times doesn't help. Attempts don't compound into a real threat.&lt;/p&gt;




&lt;p&gt;Good. We have our vocabulary: &lt;em&gt;efficient&lt;/em&gt; means polynomial time, &lt;em&gt;negligible&lt;/em&gt; means shrinks faster than any inverse polynomial, and these two concepts compose cleanly. Now let's use them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Perfect Secrecy
&lt;/h2&gt;

&lt;p&gt;At the end of the last blog, I sketched a requirement. The ciphertext distribution should be completely independent of which message was encrypted. Now I can state this formally.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Can Be Perfect?
&lt;/h3&gt;

&lt;p&gt;What would it mean for a cipher to be truly, perfectly, unbreakably secure? Not "hard to break." Not "would take a million years." Not "probably safe." But &lt;em&gt;perfectly&lt;/em&gt; secure, where the ciphertext reveals &lt;em&gt;absolutely nothing&lt;/em&gt; about the plaintext, no matter how much time and computation the adversary has.&lt;/p&gt;

&lt;p&gt;This is not a philosophical question. It has a precise mathematical answer, and it was given by &lt;a href="https://en.wikipedia.org/wiki/Claude_Shannon" rel="noopener noreferrer"&gt;Claude Shannon&lt;/a&gt; in 1949.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shannon's Definition
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definition (Perfect Secrecy):&lt;/strong&gt; An encryption scheme (Gen, Enc, Dec) over message space M has &lt;strong&gt;perfect secrecy&lt;/strong&gt; if for every probability distribution over M, for every pair of messages m0, m1 ∈ M, and for every ciphertext c ∈ C with Pr[C = c] &amp;gt; 0:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pr[C = c | M = m0] = Pr[C = c | M = m1]&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Read it aloud. The probability that ciphertext c was produced, &lt;em&gt;given&lt;/em&gt; that the plaintext was m0, equals the probability that c was produced given the plaintext was m1. For &lt;em&gt;any&lt;/em&gt; two messages and &lt;em&gt;any&lt;/em&gt; ciphertext.&lt;/p&gt;

&lt;p&gt;The distribution of the ciphertext is &lt;em&gt;independent&lt;/em&gt; of the underlying plaintext. Observing c gives the adversary zero additional information about which message was encrypted.&lt;/p&gt;

&lt;p&gt;The adversary (our postman, with unlimited time, unlimited computing power, unlimited cleverness) stares at the ciphertext and learns &lt;em&gt;absolutely nothing&lt;/em&gt;. Not a single bit of information. This is the strongest possible notion of secrecy.&lt;/p&gt;

&lt;h3&gt;
  
  
  An Equivalent View
&lt;/h3&gt;

&lt;p&gt;There is another way to read the same definition, and this form is closer to the intuition behind the reference. It says that the ciphertext distribution is independent of the plaintext distribution. Once the attacker sees c, nothing about the message has become more likely than before. In probability language, the posterior belief about the plaintext is unchanged by the ciphertext.&lt;/p&gt;

&lt;p&gt;Equivalently, for every message m and every ciphertext c with non-zero probability,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pr[M = m | C = c] = Pr[M = m]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the same idea expressed from the other side. The ciphertext does not update the attacker's belief at all. That is what perfect secrecy really means. The attacker may see the whole ciphertext, but the mathematics says the ciphertext carries no information about which plaintext was sent.&lt;/p&gt;

&lt;p&gt;Beautiful definition. But can anything actually achieve it?&lt;/p&gt;




&lt;h2&gt;
  
  
  The One-Time Pad
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Perfect Mask
&lt;/h3&gt;

&lt;p&gt;Before I build a perfectly secure cipher, I need one basic operation. Let's start with a single bit &lt;code&gt;b&lt;/code&gt; (either 0 or 1). I want to apply a "mask" bit that could hide that bit or leave it as it is.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;b' = b masked with mask&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;b&lt;/th&gt;
&lt;th&gt;mask&lt;/th&gt;
&lt;th&gt;b'&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If the mask is 0, leave it alone. If the mask is 1, hide it. Another way to see it is that if both bits are the same, output 0 and if different, output 1.&lt;/p&gt;

&lt;p&gt;Now here's the magic: &lt;strong&gt;masking is its own inverse.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(b masked with mask) masked with mask = b&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Why? If mask = 0, nothing happened either time. If mask = 1, it flipped twice, right back to the original. Mask once to encrypt, mask again to decrypt. One can also observe that this mask is associative and commutative.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn20ct905njupmzy895fn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn20ct905njupmzy895fn.png" alt="Masking is its own inverse" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In computer science, we have a name for this exact operation. It is &lt;strong&gt;XOR&lt;/strong&gt; (exclusive or, denoted ⊕). &lt;/p&gt;

&lt;p&gt;For bit strings of length ℓ, XOR operates bit by bit.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(1, 0, 1, 1) ⊕ (0, 1, 1, 0) = (1, 1, 0, 1)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Construction
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;One-Time Pad&lt;/strong&gt; (OTP), also called the &lt;strong&gt;Vernam cipher&lt;/strong&gt;, is beautifully simple. The message space, key space, and ciphertext space are all ℓ-bit strings.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;M = K = C = {0, 1}&lt;sup&gt;ℓ&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;where ℓ is a publicly known system parameter. The scheme works as follows.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Gen():&lt;/strong&gt; Output a uniformly random key k ∈ {0, 1}&lt;sup&gt;ℓ&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enc(m, k):&lt;/strong&gt; Output c = m ⊕ k   (bitwise XOR)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dec(c, k):&lt;/strong&gt; Output m = c ⊕ k   (bitwise XOR)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's it. Just XOR the message with a &lt;strong&gt;uniformly random&lt;/strong&gt; key.&lt;/p&gt;

&lt;p&gt;Note that Enc here is &lt;strong&gt;deterministic&lt;/strong&gt;, meaning there's no internal randomness. All the randomness comes from Gen, which produces the key. This is fine as long as the key is used only once (I'll show why shortly).&lt;/p&gt;

&lt;h3&gt;
  
  
  Correctness
&lt;/h3&gt;

&lt;p&gt;From Blog 1, the correctness requirement is that Dec(Enc(m, k), k) = m for every message m and every key k that Gen could output.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dec(Enc(m, k), k) = Dec(m ⊕ k, k) = (m ⊕ k) ⊕ k = m ⊕ (k ⊕ k) = m ⊕ 0&lt;sup&gt;ℓ&lt;/sup&gt; = m   ✓&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;XOR of k with itself is all zeros. XOR with all zeros is the identity. Done.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Proof
&lt;/h3&gt;

&lt;p&gt;Now the main event. I'll prove OTP achieves Shannon's definition of perfect secrecy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claim:&lt;/strong&gt; ∀ m0, m1 ∈ {0, 1}&lt;sup&gt;ℓ&lt;/sup&gt; and ∀ c ∈ {0, 1}&lt;sup&gt;ℓ&lt;/sup&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pr[C = c | M = m0] = Pr[C = c | M = m1]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fix an arbitrary plaintext m0 and an arbitrary ciphertext c. The encryption Enc(m0, k) = m0 ⊕ k produces c precisely when:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;m0 ⊕ k = c   ⇒   k = m0 ⊕ c&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the conditional probability is the following.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pr[C = c | M = m0] = Pr[k = m0 ⊕ c]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since Gen outputs k uniformly at random from {0, 1}&lt;sup&gt;ℓ&lt;/sup&gt;, the probability of any specific ℓ-bit string is as follows.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pr[k = m0 ⊕ c] = 1/2&lt;sup&gt;ℓ&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now do the exact same calculation for m1.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pr[C = c | M = m1] = Pr[K = m1 ⊕ c] = 1/2&lt;sup&gt;ℓ&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Both probabilities equal 1/2&lt;sup&gt;ℓ&lt;/sup&gt;, regardless of what m0, m1, or c are.   ▮&lt;/p&gt;

&lt;p&gt;The postman stares at the ciphertext and is, mathematically, &lt;em&gt;completely clueless&lt;/em&gt;. Every plaintext is equally likely to have produced any ciphertext. Perfect secrecy achieved. &lt;em&gt;^____^&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Don't Strive for Perfection
&lt;/h2&gt;

&lt;p&gt;The One-Time Pad is perfectly secure, yes. But it comes with two devastating limitations. And these aren't quirks of OTP, they're inherent to &lt;em&gt;any&lt;/em&gt; perfectly secure cipher.&lt;/p&gt;

&lt;h3&gt;
  
  
  Limitation 1: The Key Must Be as Long as the Message
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Theorem:&lt;/strong&gt; If an encryption scheme (Gen, Enc, Dec) is perfectly secure, then |K| ≥ |M|.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The key space must be at least as large as the message space. This is not about OTP specifically — it's about &lt;em&gt;any&lt;/em&gt; scheme that achieves perfect secrecy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proof (by contradiction):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose, for contradiction, that our scheme is perfectly secure but |K| &amp;lt; |M|. Consider the uniform distribution over M, and fix a ciphertext c with Pr[C = c] &amp;gt; 0.&lt;/p&gt;

&lt;p&gt;Define the set of all valid decryptions of c.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;M(c) = {Dec(c, k) : k ∈ K}&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each key k gives exactly one decryption Dec(c, k), but two different keys might decrypt to the &lt;em&gt;same&lt;/em&gt; message. So the set M(c) has &lt;em&gt;at most&lt;/em&gt; |K| elements.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;|M(c)| ≤ |K| &amp;lt; |M|&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since M(c) is strictly smaller than M, there exists some message m* ∈ M that is &lt;em&gt;not&lt;/em&gt; in M(c). This means no key in K maps c back to m*:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pr[C = c | M = m*] = 0&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But m* has non-zero probability under the uniform distribution, so for any m ∈ M(c), Pr[C = c | M = m] &amp;gt; 0.&lt;/p&gt;

&lt;p&gt;We got our contradiction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assertion -&amp;gt;&lt;/strong&gt; If keys are x-bit strings and messages are y-bit strings:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;|K| ≥ |M|   ⇒   2&lt;sup&gt;x&lt;/sup&gt; ≥ 2&lt;sup&gt;y&lt;/sup&gt;   ⇒   x ≥ y&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Want to encrypt a 1 GB file? You need a 1 GB key. Want to encrypt a 10 GB video call? You need a 10 GB key. And you had to &lt;em&gt;somehow&lt;/em&gt; securely share that key beforehand, which was the entire problem we were trying to solve in the first place! (T_T)&lt;/p&gt;

&lt;h3&gt;
  
  
  Limitation 2: The Key Cannot Be Reused
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;For OTP specifically:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose Alice reuses the same key k for two messages m0 and m1, producing c0 = m0 ⊕ k and c1 = m1 ⊕ k. The postman intercepts both and computes the following.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;c0 ⊕ c1 = (m0 ⊕ k) ⊕ (m1 ⊕ k) = m0 ⊕ m1 ⊕ (k ⊕ k) = m0 ⊕ m1&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr5w57abbssjdrvrfe8mv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr5w57abbssjdrvrfe8mv.png" alt="The Key Reuse Attack" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The key cancels out. The postman now holds the XOR of the two plaintexts, a &lt;em&gt;significant&lt;/em&gt; amount of information, especially if the messages are natural language text. Enough to begin recovering both.&lt;/p&gt;

&lt;p&gt;As Turing Award winner &lt;a href="https://en.wikipedia.org/wiki/Michael_O._Rabin" rel="noopener noreferrer"&gt;Michael Rabin&lt;/a&gt; put it: &lt;em&gt;"You should never reuse a one-time pad. It is like toilet paper. If you reuse it, things get messy."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For &lt;em&gt;any&lt;/em&gt; perfectly secure cipher (proof sketch).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This isn't just an OTP problem. Suppose &lt;em&gt;any&lt;/em&gt; perfectly secure cipher reuses key k for two messages m1 ≠ m2. Now consider the postman intercepting the pair of ciphertexts (c1, c2).&lt;/p&gt;

&lt;p&gt;Perfect secrecy would require (c1, c2) to look identical whether the sender encrypted (m1, m1) or (m1, m2). But if c2 can be the encryption of &lt;em&gt;both&lt;/em&gt; m1 and m2 under the same key k, then Dec(c2, k) would have to return two different answers. Decryption is a function — it can't. Contradiction.&lt;/p&gt;

&lt;p&gt;So perfect secrecy with key reuse contradicts &lt;em&gt;correctness&lt;/em&gt;. Each encryption must use an independently generated key.   ▮&lt;/p&gt;

&lt;h3&gt;
  
  
  Need to chillax
&lt;/h3&gt;

&lt;p&gt;Let's take stock of what perfect secrecy demands.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;Practical?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Key as long as the message&lt;/td&gt;
&lt;td&gt;Encrypt a 1 GB file → share a 1 GB key first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fresh key for every message&lt;/td&gt;
&lt;td&gt;100 messages → share 100 independent keys&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If Alice and Bob could securely share a 1 GB key for every message, they might as well share the 1 GB message directly.&lt;/p&gt;

&lt;p&gt;And here's the thing: remember from Blog 2 that even the most powerful supercomputers can't exceed about 10&lt;sup&gt;20&lt;/sup&gt; (roughly 2&lt;sup&gt;67&lt;/sup&gt;) operations per second. The postman, formidable as he is, has neither unlimited computation nor unlimited time. So why am I defending against an &lt;em&gt;infinitely powerful&lt;/em&gt; adversary?&lt;/p&gt;

&lt;p&gt;Perfect secrecy is the mathematical gold standard. But the gold standard is too expensive for everyday use.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Birth of Computational Security
&lt;/h2&gt;

&lt;p&gt;Here's the pivot. Instead of demanding that the adversary learns &lt;em&gt;absolutely nothing&lt;/em&gt;, we make &lt;strong&gt;2 concessions&lt;/strong&gt; and in return, we get what we actually need. Short, reusable keys.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why These Concessions Are Necessary
&lt;/h3&gt;

&lt;p&gt;Consider any encryption scheme where the same key k is used for multiple messages. In the KPA model (from Blog 1), the adversary has a collection of (message, ciphertext) pairs encrypted under the same unknown k.&lt;/p&gt;

&lt;p&gt;Two trivial attacks are unavoidable against any such scheme:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attack 1: Brute-Force Key Recovery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The adversary tries every k' ∈ K. For each candidate, it checks whether Dec(ci, k') = mi for all known pairs. When it finds the right one, it has the key.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Running time&lt;/td&gt;
&lt;td&gt;O(|K|), linear in the key space size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Success probability&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;1&lt;/strong&gt; (100%)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For |K| = 2&lt;sup&gt;256&lt;/sup&gt;, this takes on the order of 2&lt;sup&gt;256&lt;/sup&gt; operations. At 10&lt;sup&gt;20&lt;/sup&gt; operations per second, that's roughly 10&lt;sup&gt;57&lt;/sup&gt; &lt;em&gt;years&lt;/em&gt;. Not practical.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attack 2: Guessing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The adversary picks a single random k' ∈ K and checks if it's correct.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Running time&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;O(1)&lt;/strong&gt;, constant, near instant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Success probability&lt;/td&gt;
&lt;td&gt;1/|K|&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For |K| = 2&lt;sup&gt;256&lt;/sup&gt;, the success probability is 1/2&lt;sup&gt;256&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;These two attacks represent &lt;em&gt;extremes&lt;/em&gt;: one guarantees success but takes essentially forever; the other is instant but almost certainly fails. &lt;/p&gt;

&lt;p&gt;We accept both realities and build the security model around them.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Relaxation 1 (Effort):&lt;/strong&gt; We only require security against &lt;strong&gt;efficient&lt;/strong&gt; (polynomial-time) adversaries.&lt;/p&gt;

&lt;p&gt;Brute force succeeds with probability 1, but its running time is exponential in n, so it's not efficient. We declare: attacks that take superpolynomial time &lt;em&gt;don't count&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relaxation 2 (Chance):&lt;/strong&gt; We allow the scheme to be broken with &lt;strong&gt;negligible&lt;/strong&gt; probability.&lt;/p&gt;

&lt;p&gt;Guessing works in O(1) time, but its success probability 1/2&lt;sup&gt;n&lt;/sup&gt; is &lt;strong&gt;negligible&lt;/strong&gt;. So we declare: attacks that succeed with only negligible probability &lt;em&gt;don't count either&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice — the terms &lt;strong&gt;efficient&lt;/strong&gt; and &lt;strong&gt;negligible&lt;/strong&gt; are the ones I defined at the beginning of this blog. I was laying the groundwork for &lt;em&gt;exactly&lt;/em&gt; this moment.&lt;/p&gt;

&lt;p&gt;With these two relaxations, we arrive at &lt;strong&gt;computational security&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Computational Security:&lt;/strong&gt; An encryption scheme is computationally secure if no &lt;strong&gt;efficient&lt;/strong&gt; adversary can break it except with &lt;strong&gt;negligible&lt;/strong&gt; probability.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Compare this with perfect secrecy.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Perfect Secrecy&lt;/th&gt;
&lt;th&gt;Computational Security&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Adversary&lt;/td&gt;
&lt;td&gt;Computationally &lt;strong&gt;unbounded&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Computationally &lt;strong&gt;bounded&lt;/strong&gt; (polynomial time)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security guarantee&lt;/td&gt;
&lt;td&gt;Adversary learns &lt;strong&gt;absolutely nothing&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Adversary learns something with &lt;strong&gt;negligible probability&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is weaker than perfect secrecy. Given enough time, a computationally secure scheme &lt;em&gt;can&lt;/em&gt; be broken. But the time required is so vast, and the probability of a shortcut so tiny, that for practical purposes, the scheme might as well be perfectly secure.&lt;/p&gt;

&lt;p&gt;If the postman can't crack the letter in his lifetime, Alice and Bob's secret stays safe.&lt;/p&gt;

&lt;p&gt;And the relaxation buys us two things we couldn't have before, which I'll formally prove in future blogs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Short keys&lt;/strong&gt; — a 128 or 256-bit key to encrypt arbitrarily long messages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key reuse&lt;/strong&gt; — the same key can be used for multiple messages&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Choosing n: Where You Draw the Line
&lt;/h3&gt;

&lt;p&gt;One final subtlety. These definitions are &lt;em&gt;asymptotic&lt;/em&gt;, meaning they describe what happens as n → ∞. But in practice, you pick a concrete value of n and deploy the scheme. Choose poorly, and asymptotic security is worthless.&lt;/p&gt;

&lt;p&gt;Imagine a cipher where any adversary running for n&lt;sup&gt;2&lt;/sup&gt; steps succeeds with probability n&lt;sup&gt;5&lt;/sup&gt; · 2&lt;sup&gt;−n&lt;/sup&gt;. Asymptotically, the success probability is negligible. Looks safe on paper.&lt;/p&gt;

&lt;p&gt;But plug in concrete values.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;n (key bits)&lt;/th&gt;
&lt;th&gt;Adversary runtime&lt;/th&gt;
&lt;th&gt;Success probability&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;100 steps ≈ instant&lt;/td&gt;
&lt;td&gt;10&lt;sup&gt;5&lt;/sup&gt; · 2&lt;sup&gt;−10&lt;/sup&gt; ≈ &lt;strong&gt;97%&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Completely broken&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;900 steps ≈ instant&lt;/td&gt;
&lt;td&gt;30&lt;sup&gt;5&lt;/sup&gt; · 2&lt;sup&gt;−30&lt;/sup&gt; ≈ &lt;strong&gt;0.02%&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Marginal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;256&lt;/td&gt;
&lt;td&gt;65536 steps ≈ instant&lt;/td&gt;
&lt;td&gt;256&lt;sup&gt;5&lt;/sup&gt; · 2&lt;sup&gt;−256&lt;/sup&gt; ≈ 2&lt;sup&gt;−216&lt;/sup&gt;
&lt;/td&gt;
&lt;td&gt;GGs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At n = 10, an instant attack succeeds 97% of the time. At n = 256, that same attack succeeds with probability so small it makes the number of atoms in the universe look large.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;exponential returns on security&lt;/strong&gt;: each extra bit of n doubles the exponent in the denominator, so the safety gain &lt;em&gt;accelerates&lt;/em&gt; as n grows. The first 10 bits bought almost nothing; bits 200–256 buy you astronomical safety.&lt;/p&gt;

&lt;p&gt;The security parameter is where you draw that line. Push it right, and you pay more in running time (Gen, Enc, Dec all scale with poly(n)), but buy exponentially more safety. Pull it left, and operations are faster but you erode that margin. Choosing the right setting is an engineering decision — it requires understanding the &lt;em&gt;concrete&lt;/em&gt; numbers, not just the asymptotic story.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;To summarize what I did in this blog.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Built the vocabulary: the &lt;strong&gt;security parameter&lt;/strong&gt; n, &lt;strong&gt;efficient algorithms&lt;/strong&gt; (polynomial-time), and &lt;strong&gt;negligible functions&lt;/strong&gt; (shrinks faster than any polynomial inverse)&lt;/li&gt;
&lt;li&gt;Stated &lt;strong&gt;Shannon's perfect secrecy&lt;/strong&gt; — the strongest possible notion of security&lt;/li&gt;
&lt;li&gt;Proved the &lt;strong&gt;One-Time Pad&lt;/strong&gt; achieves it&lt;/li&gt;
&lt;li&gt;Proved two fundamental impossibilities inherent to &lt;em&gt;any&lt;/em&gt; perfectly secure cipher: keys must be as long as messages, and no key can be reused&lt;/li&gt;
&lt;li&gt;Modern cryptography didn't abandon perfect secrecy because it failed. It abandoned it because its costs outweigh its benefits for most applications.&lt;/li&gt;
&lt;li&gt;Introduced &lt;strong&gt;computational security&lt;/strong&gt;, the pragmatic bargain that trades perfection for practicality — secure against efficient adversaries, breakable only with negligible probability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But I haven't yet said what computational security &lt;em&gt;looks like&lt;/em&gt; as a formal definition. What's the computational analogue of Shannon's perfect secrecy? How do I state it precisely, and, critically, how do I &lt;em&gt;prove&lt;/em&gt; a scheme achieves it?&lt;/p&gt;

&lt;p&gt;That's the next blog. I'll formalize computational indistinguishability, meet the first provably secure construction under a hardness assumption, and see the three principles of modern cryptography (define, assume, prove) in full action.&lt;/p&gt;




&lt;h3&gt;
  
  
  Acknowledgment
&lt;/h3&gt;

&lt;p&gt;The technical content in this blog draws from &lt;em&gt;"Introduction to Modern Cryptography (Second Edition)"&lt;/em&gt; by Jonathan Katz and Yehuda Lindell, and from Professor Ashish Choudhury's lecture series on Foundations of Cryptography.&lt;/p&gt;




&lt;p&gt;So the next time someone offers you perfect security, ask them about the key length. If it's shorter than the message... well, you've read this blog. You know what Shannon would say.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Note: The mathematical formulations in this blog are simplified for readability. The proofs are faithful to the originals. The images and diagrams in this blog are AI-generated and meant to be illustrative, not precise technical specifications.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>maths</category>
      <category>cryptography</category>
      <category>security</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Decoding Cryptography: The Fall of Historical Ciphers</title>
      <dc:creator>Anurag Jain</dc:creator>
      <pubDate>Thu, 09 Jul 2026 14:25:11 +0000</pubDate>
      <link>https://dev.to/mejainanurag/decoding-cryptography-the-fall-of-historical-ciphers-339j</link>
      <guid>https://dev.to/mejainanurag/decoding-cryptography-the-fall-of-historical-ciphers-339j</guid>
      <description>&lt;h2&gt;
  
  
  Previously, on "The Love Letter Problem"…
&lt;/h2&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/mejainanurag/decoding-cryptography-understanding-the-attacker-and-the-4-attack-models-1hig"&gt;last blog&lt;/a&gt;, we met Alice and Bob, watched our nosy postman fail to crack their symmetric encryption, and laid down the formal syntax (Gen, Enc, Dec), Kerckhoffs' Principle, attack models, and a question: what does "secure" actually mean?&lt;/p&gt;

&lt;p&gt;We left off with the promise of math. This blog delivers on that promise by breaking things.&lt;/p&gt;

&lt;p&gt;We're going to look at three historical ciphers that people actually used for centuries. Each one seems clever. Each one gets destroyed. And the way they get destroyed teaches us exactly why modern cryptography needs mathematical rigor.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; We'll be using some basic number theory (modular arithmetic) in this blog. Don't Panic (Arthur Dent). I'll introduce everything as we go.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Modular Arithmetic 101
&lt;/h2&gt;

&lt;p&gt;Before we break ciphers, we need one tool: &lt;a href="https://en.wikipedia.org/wiki/Modular_arithmetic" rel="noopener noreferrer"&gt;modular arithmetic&lt;/a&gt;. I will use the famous example of "clock math" to explain.&lt;/p&gt;

&lt;p&gt;If it's 10 o'clock and you wait 5 hours, it's 3 o'clock — not 15 o'clock (unless you, like me, love 24hr format). You "wrapped around" at 12. Modular arithmetic formalizes this wraparound.&lt;/p&gt;

&lt;p&gt;We write:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;a mod n&lt;/strong&gt; = the remainder when a is divided by n&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;15 mod 12 = 3&lt;/li&gt;
&lt;li&gt;29 mod 26 = 3&lt;/li&gt;
&lt;li&gt;26 mod 26 = 0&lt;/li&gt;
&lt;li&gt;7 mod 26 = 7&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The general idea is that when you reach the end, you loop back to the beginning. We'll be working &lt;strong&gt;mod 26&lt;/strong&gt; a lot, because the English alphabet has 26 letters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Letters as Numbers
&lt;/h3&gt;

&lt;p&gt;To do math on letters, we need to turn them into numbers. The convention is simple:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;a&lt;/th&gt;
&lt;th&gt;b&lt;/th&gt;
&lt;th&gt;c&lt;/th&gt;
&lt;th&gt;d&lt;/th&gt;
&lt;th&gt;e&lt;/th&gt;
&lt;th&gt;f&lt;/th&gt;
&lt;th&gt;g&lt;/th&gt;
&lt;th&gt;h&lt;/th&gt;
&lt;th&gt;i&lt;/th&gt;
&lt;th&gt;j&lt;/th&gt;
&lt;th&gt;k&lt;/th&gt;
&lt;th&gt;l&lt;/th&gt;
&lt;th&gt;m&lt;/th&gt;
&lt;th&gt;n&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;o&lt;/th&gt;
&lt;th&gt;p&lt;/th&gt;
&lt;th&gt;q&lt;/th&gt;
&lt;th&gt;r&lt;/th&gt;
&lt;th&gt;s&lt;/th&gt;
&lt;th&gt;t&lt;/th&gt;
&lt;th&gt;u&lt;/th&gt;
&lt;th&gt;v&lt;/th&gt;
&lt;th&gt;w&lt;/th&gt;
&lt;th&gt;x&lt;/th&gt;
&lt;th&gt;y&lt;/th&gt;
&lt;th&gt;z&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So "h" is 7, "t" is 19, and so on. Alice, Bob, the postman, all know this mapping. It's just a way to talk about letters using numbers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cipher #1: The Shift Cipher (Caesar Cipher)
&lt;/h2&gt;

&lt;p&gt;As the name suggests, it is believed to have been used by Julius Caesar. I will be using both the names to get you desensitized. The idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pick a random number k between 0 and 25. To encrypt, shift every letter forward by k positions. To decrypt, shift back by k positions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's write this down formally using the &lt;strong&gt;Gen, Enc, Dec syntax&lt;/strong&gt; from blog 1:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Gen():&lt;/strong&gt; Pick k ∈ {0, 1, 2, …, 25} uniformly at random&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enc(m, k):&lt;/strong&gt; ∀ character mi in the message, compute ci = (mi + k) mod 26&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dec(c, k):&lt;/strong&gt; ∀ character ci in the ciphertext, compute mi = (ci − k) mod 26&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Simple Example
&lt;/h3&gt;

&lt;p&gt;Suppose k = 3 and Alice wants to encrypt "&lt;strong&gt;hello&lt;/strong&gt;".&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plaintext&lt;/th&gt;
&lt;th&gt;h&lt;/th&gt;
&lt;th&gt;e&lt;/th&gt;
&lt;th&gt;l&lt;/th&gt;
&lt;th&gt;l&lt;/th&gt;
&lt;th&gt;o&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;As number&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+ k = 3&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mod 26&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ciphertext&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;k&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;h&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;o&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;o&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;r&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Alice sends "&lt;strong&gt;khoor&lt;/strong&gt;" to Bob. Bob, who knows k = 3, subtracts 3 from each letter and recovers "&lt;strong&gt;hello&lt;/strong&gt;".&lt;/p&gt;

&lt;p&gt;The postman sees this and scratches his head. For now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi710n7dchzyhiz8721qb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi710n7dchzyhiz8721qb.png" alt="Caesar cipher with a left shift of 3" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking the Caesar Cipher: Brute Force
&lt;/h2&gt;

&lt;p&gt;Now let's think like the postman. He intercepts "&lt;strong&gt;khoor&lt;/strong&gt;" and wants to recover the message.&lt;/p&gt;

&lt;p&gt;He knows it's a shift cipher (thanks again, Kerckhoffs). He &lt;em&gt;doesn't&lt;/em&gt; know k yet. But k can only be one of 26 values: 0, 1, 2, …, 25. So he just tries them all:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Candidate k&lt;/th&gt;
&lt;th&gt;Decryption of "khoor"&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;k = 0&lt;/td&gt;
&lt;td&gt;khoor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;k = 1&lt;/td&gt;
&lt;td&gt;jgnnq&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;k = 2&lt;/td&gt;
&lt;td&gt;ifmmp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;k = 3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;hello&lt;/strong&gt; ← meaningful English!&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;k = 4&lt;/td&gt;
&lt;td&gt;gdkkn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;td&gt;… (all gibberish)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;26 attempts. A child could do this by hand. A computer does it in microseconds.&lt;/p&gt;

&lt;p&gt;This is a &lt;strong&gt;brute force attack&lt;/strong&gt;: exhaustive search over all k ∈ K. With |K| = 26, it's simple.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Sufficient Key Space Principle
&lt;/h2&gt;

&lt;p&gt;The shift cipher teaches us a fundamental lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sufficient Key Space Principle:&lt;/strong&gt; Any secure cipher &lt;em&gt;must&lt;/em&gt; have a key space large enough that a brute force attack is computationally infeasible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a &lt;strong&gt;necessary&lt;/strong&gt; condition, not sufficient. Large |K| doesn't &lt;em&gt;guarantee&lt;/em&gt; security (as we'll see next), but small |K| &lt;em&gt;guarantees&lt;/em&gt; insecurity. If the adversary can exhaustively search over all k ∈ K... you've already lost.&lt;/p&gt;

&lt;p&gt;Let me clarify, how large is "large enough"? &lt;/p&gt;

&lt;p&gt;To answer this, consider the power of modern computer. Supercomputers can't go more than &lt;strong&gt;10&lt;sup&gt;20&lt;/sup&gt;&lt;/strong&gt; (I am taking some liberty with the numbers), that is about &lt;strong&gt;2&lt;sup&gt;67&lt;/sup&gt;&lt;/strong&gt; operations per second.&lt;/p&gt;

&lt;p&gt;Thus, a key space of at least &lt;strong&gt;2&lt;sup&gt;80&lt;/sup&gt;&lt;/strong&gt; is considered the bare minimum, and modern ciphers like &lt;a href="https://en.wikipedia.org/wiki/Advanced_Encryption_Standard" rel="noopener noreferrer"&gt;AES-256&lt;/a&gt; use a key space of &lt;strong&gt;2&lt;sup&gt;256&lt;/sup&gt;&lt;/strong&gt;, a number so large that if every atom in the observable universe were a computer trying a billion keys per second, they still wouldn't finish before the heat death of the universe.&lt;/p&gt;

&lt;p&gt;A key space of 26 becomes a joke in comparison.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cipher #2: The Mono-Alphabetic Substitution Cipher
&lt;/h2&gt;

&lt;p&gt;Alright, so the postman broke the shift cipher because there were only 26 keys. What if we give him a &lt;em&gt;lot&lt;/em&gt; more keys?&lt;/p&gt;

&lt;p&gt;The idea: instead of shifting every letter by the &lt;em&gt;same&lt;/em&gt; amount, we create a a &lt;a href="https://en.wikipedia.org/wiki/Permutation" rel="noopener noreferrer"&gt;permutation&lt;/a&gt; (which is a special kind of bijection, else &lt;strong&gt;Dec&lt;/strong&gt; won't be deterministic ^^ ) from plaintext letters to ciphertext letters. Each letter maps to a different, unique letter.&lt;/p&gt;

&lt;p&gt;For example, a possible key might be:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plaintext&lt;/th&gt;
&lt;th&gt;a&lt;/th&gt;
&lt;th&gt;b&lt;/th&gt;
&lt;th&gt;c&lt;/th&gt;
&lt;th&gt;d&lt;/th&gt;
&lt;th&gt;e&lt;/th&gt;
&lt;th&gt;f&lt;/th&gt;
&lt;th&gt;…&lt;/th&gt;
&lt;th&gt;z&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ciphertext&lt;/td&gt;
&lt;td&gt;q&lt;/td&gt;
&lt;td&gt;w&lt;/td&gt;
&lt;td&gt;z&lt;/td&gt;
&lt;td&gt;r&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;b&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;td&gt;m&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Under this key, every "a" in the plaintext becomes "q", every "c" becomes "z", and so on. The receiver, who knows the same permutation, reverses it.&lt;/p&gt;

&lt;p&gt;Formally:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Gen():&lt;/strong&gt; Pick a random permutation σ : {0,…,25} → {0,…,25}&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enc(m, σ):&lt;/strong&gt; ∀ mi, compute ci = σ(mi)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dec(c, σ):&lt;/strong&gt; ∀ ci, compute mi = σ&lt;sup&gt;−1&lt;/sup&gt;(ci)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;where σ&lt;sup&gt;−1&lt;/sup&gt; is the &lt;em&gt;inverse&lt;/em&gt; permutation (the mapping in reverse).&lt;/p&gt;

&lt;h3&gt;
  
  
  The Key Space: 26!
&lt;/h3&gt;

&lt;p&gt;How many possible keys are there? A key is a permutation of 26 letters, and the number of permutations of 26 items is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;26! = 26 × 25 × 24 × … × 1 ≈ 4 × 10&lt;sup&gt;26&lt;/sup&gt; ≈ 2&lt;sup&gt;88&lt;/sup&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's roughly &lt;strong&gt;2&lt;sup&gt;88&lt;/sup&gt;&lt;/strong&gt;. An astronomically larger key space than the shift cipher's 26 keys. A brute force attack would need to try about 2&lt;sup&gt;88&lt;/sup&gt; permutations. Even with modern hardware, this is infeasible.&lt;/p&gt;

&lt;p&gt;So we're safe, right? The sufficient key space principle is satisfied.&lt;/p&gt;

&lt;p&gt;Not so fast.&lt;/p&gt;




&lt;h2&gt;
  
  
  Breaking the Substitution Cipher: Frequency Analysis
&lt;/h2&gt;

&lt;p&gt;Remember that the sufficient key space principle is a &lt;em&gt;necessary&lt;/em&gt; condition, not a &lt;em&gt;sufficient&lt;/em&gt; one. A large key space protects against brute force, but who said brute force is the only attack?&lt;/p&gt;

&lt;p&gt;The postman is evolving. For the shift cipher, brute strength was enough. Now he puts on his statistician hat (!!!). He knows something about English that no permutation can hide.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Fingerprint of Language
&lt;/h3&gt;

&lt;p&gt;Every natural language has statistical patterns. In English:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The letter &lt;strong&gt;"e"&lt;/strong&gt; appears roughly &lt;strong&gt;12.7%&lt;/strong&gt; of the time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"t"&lt;/strong&gt; appears about &lt;strong&gt;9.1%&lt;/strong&gt; of the time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"z"&lt;/strong&gt; barely shows up at &lt;strong&gt;0.07%&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are the approximate frequencies of all English letters:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Letter&lt;/th&gt;
&lt;th&gt;Frequency&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Letter&lt;/th&gt;
&lt;th&gt;Frequency&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;e&lt;/td&gt;
&lt;td&gt;12.7%&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;s&lt;/td&gt;
&lt;td&gt;6.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;t&lt;/td&gt;
&lt;td&gt;9.1%&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;h&lt;/td&gt;
&lt;td&gt;6.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;a&lt;/td&gt;
&lt;td&gt;8.2%&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;r&lt;/td&gt;
&lt;td&gt;6.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;o&lt;/td&gt;
&lt;td&gt;7.5%&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;d&lt;/td&gt;
&lt;td&gt;4.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;i&lt;/td&gt;
&lt;td&gt;7.0%&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;l&lt;/td&gt;
&lt;td&gt;4.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;n&lt;/td&gt;
&lt;td&gt;6.7%&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And it goes beyond single letters. Common &lt;strong&gt;bigrams&lt;/strong&gt; (pairs of letters) like "th", "he", "in" appear far more often than "qz" or "jx". Common &lt;strong&gt;trigrams&lt;/strong&gt; like "the", "and", "ing" are also well-documented.&lt;/p&gt;

&lt;p&gt;This is all &lt;strong&gt;public data&lt;/strong&gt;. Anyone can compute these statistics from a large English corpus.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Attack
&lt;/h3&gt;

&lt;p&gt;By now, you must've enough hints to understand how to break the cipher. I will still mention the attack method for completeness.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi7uxgyfvlk18e715evzr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi7uxgyfvlk18e715evzr.png" alt="English letter frequency sorted by frequency" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Frequency map&lt;/strong&gt; of every letter in ciphertext.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compare&lt;/strong&gt;  it with the known English frequency chart.&lt;/li&gt;
&lt;li&gt;Play &lt;strong&gt;Match the following&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refine&lt;/strong&gt; using bigram and trigram frequencies until the permutation is recovered.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For a long enough ciphertext, this works beautifully. No brute force needed. The permutation, all 26! possibilities, is cracked by exploiting the statistics of the English language.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The lesson: &lt;strong&gt;a large key space is necessary but not sufficient&lt;/strong&gt;. The substitution cipher has 2&lt;sup&gt;88&lt;/sup&gt; keys but falls to a simple statistical attack.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Cipher #3: The Vigenère Cipher
&lt;/h2&gt;

&lt;p&gt;So the substitution cipher was broken because every "e" always maps to the same ciphertext letter. Alice and Bob are smart, but very stubborn. They still want to use shift and keep the ciphers somewhat simple.&lt;/p&gt;

&lt;p&gt;Vigenère cipher (we've already heard of this. Also called the &lt;strong&gt;poly-alphabetic substitution cipher&lt;/strong&gt;) enters the stage!! Instead of one shift applied uniformly, it uses a &lt;strong&gt;keyword&lt;/strong&gt; of length t, and each letter of the keyword specifies a &lt;em&gt;different&lt;/em&gt; shift.&lt;/p&gt;

&lt;p&gt;Formally:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Gen():&lt;/strong&gt; Pick a random length t ≥ 1, then pick a random string k = (k1, k2, …, kt) where each kj ∈ {0, 1, …, 25}&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enc(m, k):&lt;/strong&gt; Divide the message into blocks of length t. For each character mij (the j-th character of the i-th block), compute: &lt;strong&gt;cij = (mij + kj) mod 26&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dec(c, k):&lt;/strong&gt; For each character cij, compute: &lt;strong&gt;mij = (cij − kj) mod 26&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice the subscript on k: it's &lt;strong&gt;kj&lt;/strong&gt;, not just k. The shift changes depending on the &lt;em&gt;position&lt;/em&gt; within the block.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhomippd53d2pxmoqsot4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhomippd53d2pxmoqsot4.png" alt="Vigenère square / tabula recta" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Let the keyword be "&lt;strong&gt;cipher&lt;/strong&gt;" (length t = 6). Converting to numbers: c=2, i=8, p=15, h=7, e=4, r=17.&lt;/p&gt;

&lt;p&gt;Alice wants to encrypt: "&lt;strong&gt;thiscryptosystemisnotsecure&lt;/strong&gt;"&lt;/p&gt;

&lt;p&gt;Step 1 — convert plaintext to numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;t  h  i  s  c  r  y  p  t  o  s  y  s  t  e  m  i  s  n  o  t  s  e  c  u  r  e
19 7  8  18 2  17 24 15 19 14 18 24 18 19 4  12 8  18 13 14 19 18 4  2  20 17 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2 — divide into blocks of 6 and add the key (mod 26):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Block 1:  19  7  8 18  2 17     Key:  2  8 15  7  4 17
          ─────────────────          ─────────────────
Sum:      21 15 23 25  6  8  (mod 26)
Letters:   v  p  x  z  g  i
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Block 2:  24 15 19 14 18 24     Key:  2  8 15  7  4 17
          ─────────────────          ─────────────────
Sum:       0 23  8 21 22 15  (mod 26)
Letters:   a  x  i  v  w  p
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Block 3:  18 19  4 12  8 18     Key:  2  8 15  7  4 17
          ─────────────────          ─────────────────
Sum:      20  1 19 19 12  9  (mod 26)
Letters:   u  b  t  t  m  j
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And so on for the remaining characters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clever?
&lt;/h3&gt;

&lt;p&gt;We look at every instance of the letter "&lt;strong&gt;s&lt;/strong&gt;" (= 18) in the plaintext:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Position 4 (in block 1): shifted by k4 = 7 → ciphertext "z"&lt;/li&gt;
&lt;li&gt;Position 5 (in block 2, as 'position 5'): shifted by k5 = 4 → ciphertext "w"&lt;/li&gt;
&lt;li&gt;Position 1 (in block 3): shifted by k1 = 2 → ciphertext "u"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same plaintext letter "s" produces &lt;strong&gt;three different ciphertext letters&lt;/strong&gt;: z, w, u. The one-to-one relationship between plaintext and ciphertext letters and the very thing that made frequency analysis work, is broken.&lt;/p&gt;

&lt;p&gt;The key space is still sufficiently large. The postman prepares his frequency chart and finds… no clear pattern. The most frequent ciphertext letter doesn't cleanly correspond to "e" anymore. Victory for Alice and Bob? Our Cryptography journey ends here?&lt;/p&gt;

&lt;p&gt;Ofc not :P.&lt;/p&gt;




&lt;h2&gt;
  
  
  Not Clever!
&lt;/h2&gt;

&lt;p&gt;The Vigenère cipher resisted cryptanalysis for centuries and was even called &lt;em&gt;"le chiffre indéchiffrable"&lt;/em&gt; (the indecipherable cipher). But our postman has evolved again... a pattern hunter! And the Vigenère falls to an elegant two-staged attack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 1: Find the Key Length t
&lt;/h3&gt;

&lt;p&gt;Several methods exist to determine t, including &lt;a href="https://en.wikipedia.org/wiki/Kasiski_examination" rel="noopener noreferrer"&gt;Kasiski examination&lt;/a&gt; and the &lt;a href="https://en.wikipedia.org/wiki/Index_of_coincidence" rel="noopener noreferrer"&gt;index of coincidence&lt;/a&gt;. The core idea behind both: if the key has period t, then the ciphertext has a subtle periodic structure that can be statistically detected.&lt;/p&gt;

&lt;p&gt;I'll leave the details of Stage 1 as a gift for you, my friend, the Wikipedia articles are excellent. The important thing is: &lt;strong&gt;given enough ciphertext, the key length t can be determined&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 2: Recover the Key (t Independent Frequency Analyses)
&lt;/h3&gt;

&lt;p&gt;Once you know t, the rest is a familiar trick. Here's the insight:&lt;/p&gt;

&lt;p&gt;Consider every t-th character of the ciphertext, starting from position 1:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;c1, c1+t, c1+2t, c1+3t, …&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All of these characters were encrypted with the &lt;strong&gt;same shift k1&lt;/strong&gt;. So this subsequence is just a Caesar cipher!&lt;/p&gt;

&lt;p&gt;Now do the same for position 2:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;c2, c2+t, c2+2t, c2+3t, …&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This stream was all shifted by k2. Another independent shift cipher to crack.&lt;/p&gt;

&lt;p&gt;Repeat for positions 3, 4, …, t. We have &lt;strong&gt;t independent shift ciphers&lt;/strong&gt; and we can use frequency analysis for each of them, each recovering one character of the key. Once we have all t key characters, we have the full key.&lt;/p&gt;

&lt;p&gt;For this to work, we need the ciphertext to be long enough that each of the t streams has sufficient statistical signal. But for any &lt;em&gt;fixed&lt;/em&gt; key length t, a sufficiently long message will always be breakable.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  The Vigenère cipher, the "indecipherable cipher", broken in &lt;strong&gt;ciphertext-only attack&lt;/strong&gt;. Not a great look :&amp;lt;
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Scoreboard
&lt;/h2&gt;

&lt;p&gt;Let's step back and take stock. Three ciphers, three attacks, all in the weakest possible attack model (COA):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cipher&lt;/th&gt;
&lt;th&gt;Key Space&lt;/th&gt;
&lt;th&gt;Broken By&lt;/th&gt;
&lt;th&gt;Attack Model&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Shift Cipher&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;Brute Force&lt;/td&gt;
&lt;td&gt;COA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mono-Alphabetic Substitution&lt;/td&gt;
&lt;td&gt;26! ≈ 2&lt;sup&gt;88&lt;/sup&gt;
&lt;/td&gt;
&lt;td&gt;Frequency Analysis&lt;/td&gt;
&lt;td&gt;COA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vigenère Cipher&lt;/td&gt;
&lt;td&gt;26&lt;sup&gt;t&lt;/sup&gt; (periodic)&lt;/td&gt;
&lt;td&gt;Kasiski + Frequency Analysis&lt;/td&gt;
&lt;td&gt;COA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Remember that COA is the &lt;em&gt;weakest&lt;/em&gt; adversary. The postman has only the ciphertext. Imagine how much worse these ciphers would fare against KPA or CPA adversaries, who have plaintext-ciphertext pairs or even an encryption oracle.&lt;/p&gt;




&lt;h2&gt;
  
  
  Enter Cryptography
&lt;/h2&gt;

&lt;p&gt;A pattern that repeated for centuries:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Someone proposes a "clever" cipher.&lt;/li&gt;
&lt;li&gt;Everyone thinks it's secure.&lt;/li&gt;
&lt;li&gt;Someone finds an attack.&lt;/li&gt;
&lt;li&gt;Repeat.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The fundamental problem with classical cryptography was that it was an &lt;strong&gt;art, not a science&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No formal &lt;strong&gt;definitions&lt;/strong&gt; of what "secure" means&lt;/li&gt;
&lt;li&gt;No stated &lt;strong&gt;assumptions&lt;/strong&gt; about what the attacker can or cannot do&lt;/li&gt;
&lt;li&gt;No mathematical &lt;strong&gt;proofs&lt;/strong&gt; that the cipher actually achieves its claimed security&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sound familiar? I walked through five attempts at defining "secure" and showed how each one failed. That's exactly the kind of imprecision that plagued classical cryptography for millennia.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Three Principles of Modern Cryptography
&lt;/h2&gt;

&lt;p&gt;Modern cryptography fixes this by resting on three pillars:&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 1: Formal Security Definitions
&lt;/h3&gt;

&lt;p&gt;Don't just say "this cipher is secure." Define &lt;strong&gt;exactly&lt;/strong&gt; what "secure" means in mathematical terms. Against what kind of adversary? With what computational resources? What exactly should the adversary be unable to compute?&lt;/p&gt;

&lt;p&gt;We saw this begin with our series of attempts at defining privacy, and with the attack model hierarchy (COA → KPA → CPA → CCA). We'll arrive at precise, mathematical definitions that leave no room for hand-waving.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 2: Precise Statement of Assumptions
&lt;/h3&gt;

&lt;p&gt;Every construction in modern cryptography is built on some underlying &lt;strong&gt;hardness assumption&lt;/strong&gt;, i.e, a mathematical problem believed to be computationally hard. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Factoring large integers is hard" (used in RSA)&lt;/li&gt;
&lt;li&gt;"Computing discrete logarithms is hard" (used in Diffie-Hellman)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These assumptions (axioms) are &lt;em&gt;unproven&lt;/em&gt;. We don't have mathematical proofs that these problems are truly hard. But by stating them explicitly, we achieve two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We can compare different constructions by comparing their assumptions.&lt;/li&gt;
&lt;li&gt;If a construction is broken, we know &lt;em&gt;exactly&lt;/em&gt; which assumption failed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is infinitely better than the classical approach of hoping no one finds an attack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 3: Rigorous Mathematical Proofs
&lt;/h3&gt;

&lt;p&gt;Once we have a definition, Z (Principle 1) and an assumption, X (Principle 2), we &lt;strong&gt;mathematically prove&lt;/strong&gt; that the construction, Y, satisfies the definition, assuming the underlying hardness assumption holds.&lt;/p&gt;

&lt;p&gt;The structure is always:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"If X, then Y is Z-secure."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  From Intuition to Formal Security
&lt;/h2&gt;

&lt;p&gt;The historical ciphers all fail because ∃ an efficient adversary A that can recover m (or compute some function of m) from c, even in the weakest (COA) attack model.&lt;/p&gt;

&lt;p&gt;This suggests a cleaner requirement. What if we demanded:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;∀ m0, m1 ∈ M, ∀ c ∈ C:  Pr[C = c | M = m0] = Pr[C = c | M = m1]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words: the ciphertext distribution should be completely independent of which message was encrypted. The adversary, no matter how powerful, stares at c and learns &lt;em&gt;nothing&lt;/em&gt; about whether m0 or m1 was the plaintext.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;Alice and Bob had all their ciphers broken. &lt;em&gt;Wah wah wah&lt;/em&gt; :&amp;lt;&lt;/p&gt;

&lt;p&gt;But the next blog will answer the question we've been teasing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How do you mathematically formalize whether the ciphertext "helped" the attacker?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That leads us to &lt;strong&gt;probability theory&lt;/strong&gt;, &lt;strong&gt;random variables&lt;/strong&gt;, and the first formal notion of security in cryptographic history. One so strong that it's provably unbreakable, even against an adversary with unlimited computing power. It was defined by &lt;a href="https://en.wikipedia.org/wiki/Claude_Shannon" rel="noopener noreferrer"&gt;Claude Shannon&lt;/a&gt; in 1949. It's called &lt;strong&gt;perfect secrecy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But fair warning: more math incoming. You've been warned!&lt;/p&gt;




&lt;h3&gt;
  
  
  Acknowledgment
&lt;/h3&gt;

&lt;p&gt;The technical content in this blog draws from &lt;em&gt;"Introduction to Modern Cryptography (Second Edition)"&lt;/em&gt; by Jonathan Katz and Yehuda Lindell, and from Professor Ashish Choudhury's lecture series on Foundations of Cryptography.&lt;/p&gt;




&lt;p&gt;So the next time someone tells you they've invented an "unbreakable" cipher, ask them three questions: What's your formal security definition? What's your hardness assumption? Where's your proof? If they can't answer all three... well, you've read this blog. You know how that story ends.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Note: The mathematical formulations in this blog are simplified for readability. The worked examples are exact.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The diagrams in this blog are AI-generated and meant to be illustrative, not precise technical specifications.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cryptography</category>
      <category>maths</category>
      <category>security</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Decoding Cryptography: Understanding the Attacker (and the 4 Attack Models)</title>
      <dc:creator>Anurag Jain</dc:creator>
      <pubDate>Thu, 09 Jul 2026 14:24:36 +0000</pubDate>
      <link>https://dev.to/mejainanurag/decoding-cryptography-understanding-the-attacker-and-the-4-attack-models-1hig</link>
      <guid>https://dev.to/mejainanurag/decoding-cryptography-understanding-the-attacker-and-the-4-attack-models-1hig</guid>
      <description>&lt;h2&gt;
  
  
  The Love Letter Problem
&lt;/h2&gt;

&lt;p&gt;Remember when you were a kid and wanted to write a love letter to your sweetheart, but a nosy neighbour kept peeking while you were trying to write?&lt;/p&gt;

&lt;p&gt;This has been a problem faced by people ever since we learnt how to communicate. &lt;/p&gt;

&lt;p&gt;We can't always stop people from peeking, but what if, even if they read the message, only the one for whom the message is intended can understand it? Enter the concept of &lt;a href="https://en.wikipedia.org/wiki/Cryptography" rel="noopener noreferrer"&gt;Cryptography &lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Art to Science
&lt;/h2&gt;

&lt;p&gt;Cryptography started as an art. An art of making puzzles that could only be solved by people in the know. An example would be "crypto" turned to "dtbqvr" using &lt;a href="https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher" rel="noopener noreferrer"&gt;Vigenère cipher&lt;/a&gt;. But you couldn't be sure with a certain probability that no one would be able to crack the cipher (other than the people meant to, of course). So how do you actually &lt;em&gt;know&lt;/em&gt; your puzzle is hard to crack?&lt;/p&gt;

&lt;p&gt;As our computing powers progressed, cryptography turned from an art form to a solid mathematical field. Read on to find why that matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Symmetric Encryption — Alice and Bob
&lt;/h2&gt;

&lt;p&gt;Now, let's get back to your problem of having a Peeping Tom over your shoulder but wanting to convey your love in writing. For a moment, let's forget this distracting analogy and consider the case of two &lt;a href="https://en.wikipedia.org/wiki/Alice_and_Bob" rel="noopener noreferrer"&gt;famous&lt;/a&gt; friends Alice and Bob.&lt;/p&gt;

&lt;p&gt;Alice and Bob want to correspond secretly, but they don't trust the postman to not open their letters. So they come up with a key — a tool they would use to &lt;strong&gt;lock&lt;/strong&gt; their letters so that only those with the key can open the letters. For the sake of avoiding any future confusion, I want to clarify that whenever I mention key, I mean a number (could be any &lt;strong&gt;random&lt;/strong&gt; number really:P).&lt;/p&gt;

&lt;p&gt;Alice (the &lt;strong&gt;sender&lt;/strong&gt;) writes the letter (&lt;strong&gt;message&lt;/strong&gt;), locks the letter with the key (this process is called &lt;strong&gt;encryption&lt;/strong&gt;). The locked letter (&lt;strong&gt;ciphertext&lt;/strong&gt;) is sent through the post office (the &lt;strong&gt;channel&lt;/strong&gt;). Bob (the &lt;strong&gt;receiver&lt;/strong&gt;) obtains the letter and uses the same key to open it (a process termed &lt;strong&gt;decryption&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feijw5nbfk60nrgh1vbvm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feijw5nbfk60nrgh1vbvm.png" alt="Symmetric Encryption Flow" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whenever the sender and receiver share a secret key to encrypt and decrypt their messages, the process is known as &lt;strong&gt;"symmetric encryption"&lt;/strong&gt;. Encryption protects confidentiality, but by itself does not necessarily protect against tampering. Some examples of Symmetric Encryption schemes are &lt;a href="https://en.wikipedia.org/wiki/Advanced_Encryption_Standard" rel="noopener noreferrer"&gt;AES&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Triple_DES" rel="noopener noreferrer"&gt;3DES&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Salsa20#ChaCha_variant" rel="noopener noreferrer"&gt;ChaCha20&lt;/a&gt; etc.&lt;/p&gt;




&lt;h2&gt;
  
  
  Kerckhoffs' Principle — Why We Need Math
&lt;/h2&gt;

&lt;p&gt;Now here's the thing. Pre-modern cryptography relied on clever looking algorithms and assumed that the attacker (our peeping Tom) won't know the algorithm being used. The security came from keeping the &lt;em&gt;method&lt;/em&gt;, i.e., the algorithm, secret. That changed in 1883.&lt;/p&gt;

&lt;p&gt;That year, &lt;a href="https://en.wikipedia.org/wiki/Kerckhoffs%27s_principle" rel="noopener noreferrer"&gt;Kerckhoffs' Principle&lt;/a&gt; was coined. It states that &lt;strong&gt;"a cryptographic system should be secure even if everything about the system, except the key, is public knowledge"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In our analogy, we simply assume the postman already knows exactly how Alice and Bob are locking their letters. The only thing he doesn't know is the key. And yet, the system should still be secure.&lt;/p&gt;

&lt;p&gt;Why is this a good idea? A few reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A key is short (say, 256 bits). An algorithm is thousands of lines of code. Keeping a key secret is far easier than keeping an entire algorithm secret.&lt;/li&gt;
&lt;li&gt;If a key leaks, you just pick a new one. If an algorithm leaks, you need to invent a new algorithm — that's &lt;em&gt;much&lt;/em&gt; harder.&lt;/li&gt;
&lt;li&gt;Published algorithms go through public scrutiny. An algorithm that has survived 30+ years of attacks from the world's best cryptographers is far more trustworthy than a proprietary black box.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But this also means we can no longer just wave our hands and say "trust me, it's secure". If the algorithm is public, we need &lt;strong&gt;mathematical proof&lt;/strong&gt; that knowing the algorithm doesn't help the attacker. This is what turned cryptography from an art into a science.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Key Sharing Problem
&lt;/h2&gt;

&lt;p&gt;As the reader, now you wonder, how did Alice and Bob actually share the key in the first place? If they could share the key, couldn't they share the secret message the same way? These are the questions we answer next, just be patient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Asymmetric Encryption — No Shared Key Needed
&lt;/h2&gt;

&lt;p&gt;It is easy to calculate 1013 * 9973 by hand. If you have a calculator, you won't even be afraid of 10 times longer multiplications. But what if I ask you to factorize "15972623"? It is very difficult to do so by hand.&lt;/p&gt;

&lt;p&gt;And what if instead of an 8 digit number, it was a &lt;strong&gt;500 digit number&lt;/strong&gt; with just two prime factors? Just the number of 250 digit numbers is too huge to fathom and finding the factors is believed to be computationally infeasible for sufficiently large numbers.&lt;/p&gt;

&lt;p&gt;The best known attacks against &lt;a href="https://en.wikipedia.org/wiki/RSA_(cryptosystem)" rel="noopener noreferrer"&gt;RSA&lt;/a&gt;, an asymmetric encryption algorithm, involve factoring a very large integer into its prime factors. No efficient algorithm for this problem is known.&lt;/p&gt;

&lt;p&gt;Asymmetric encryption involves sharing a message over an unsecure channel without a shared key. Instead, there are &lt;strong&gt;two keys&lt;/strong&gt;: a &lt;strong&gt;public key&lt;/strong&gt; (which everyone can see) and a &lt;strong&gt;private key&lt;/strong&gt; (which only the receiver holds). Anyone can encrypt a message using the public key, but only the holder of the private key can decrypt it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fawcp6p9t063px16r1fn6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fawcp6p9t063px16r1fn6.png" alt="Asymmetric Encryption Flow" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;RSA, &lt;a href="https://en.wikipedia.org/wiki/Elliptic-curve_cryptography" rel="noopener noreferrer"&gt;ECC&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/ElGamal_encryption" rel="noopener noreferrer"&gt;ElGamal&lt;/a&gt; are a few commonly used Asymmetric Encryption schemes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Both? Symmetric + Asymmetric
&lt;/h2&gt;

&lt;p&gt;If I can share messages without a shared key, why do I need the key in the first place? Turns out using a symmetric key is &lt;em&gt;much&lt;/em&gt; faster, and as the message gets longer, the difference becomes dramatic. So in practice, we use asymmetric encryption to share a short key (e.g. 256 bits), and then use symmetric encryption with that key for the actual messages. Best of both worlds.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; readers beware that this blog has gone wild and will be a bit technical hereon.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You might find my use of a few terms (like &lt;em&gt;negligible&lt;/em&gt;, &lt;em&gt;difficult&lt;/em&gt;, &lt;em&gt;short&lt;/em&gt;, &lt;em&gt;long&lt;/em&gt; etc) vague. From now on, we'll start being more precise about what these things actually mean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deterministic vs Randomized Algorithms
&lt;/h2&gt;

&lt;p&gt;Before we formalize encryption, we need to understand a distinction that is fundamental to making encryption secure.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;deterministic algorithm&lt;/strong&gt; is what you'd normally expect: give it the same input, and it always produces the same output. Run it a hundred times with input x, and you get the same output y a hundred times. No surprises.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;randomized algorithm&lt;/strong&gt; is different. Like flipping a coin, running the same algorithm with the same input twice might give you two &lt;em&gt;different&lt;/em&gt; outputs. The output depends not just on the input, but also on chance.&lt;/p&gt;

&lt;p&gt;Why does this matter for encryption? Imagine Alice encrypts "I love you" with the same key twice. If the encryption algorithm is deterministic, the postman sees the same ciphertext appear twice and exclaims: "Aha, she's sending the same message again!" He doesn't know &lt;em&gt;what&lt;/em&gt; the message is, but he knows it's being repeated — and that alone can be valuable information.&lt;/p&gt;

&lt;p&gt;So, &lt;strong&gt;encryption must use fresh randomness&lt;/strong&gt; (or an equivalent unique &lt;a href="https://en.wikipedia.org/wiki/Cryptographic_nonce" rel="noopener noreferrer"&gt;nonce&lt;/a&gt;) so that encrypting the same message twice does not produce the same ciphertext.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Formal Syntax: Gen, Enc, Dec
&lt;/h2&gt;

&lt;p&gt;Now that you understand randomness, let's be precise about what a symmetric encryption scheme actually is. It consists of 3 algorithms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Gen() → k&lt;/strong&gt; &lt;em&gt;(Key Generation)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The key generation algorithm takes no input. Internally, it generates random bits and outputs a key k. Since it's randomized, every time you run Gen, you could get a different key. The set of all possible keys it could output is called the &lt;strong&gt;key space&lt;/strong&gt; K.&lt;/p&gt;

&lt;p&gt;For example, if Gen outputs 256-bit keys, then the key space is the set of all 256-bit strings — that's 2²⁵⁶ possible keys.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enc(m, k) → c&lt;/strong&gt; &lt;em&gt;(Encryption)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The encryption algorithm takes the plaintext m and a key k, uses fresh randomness (or a nonce), and outputs a ciphertext c. Since it uses randomness, encrypting the same message with the same key multiple times will produce different ciphertexts — exactly what we want.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dec(c, k) → m&lt;/strong&gt; &lt;em&gt;(Decryption)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The decryption algorithm takes a ciphertext c and the key k, and outputs the original plaintext m. This one is &lt;strong&gt;deterministic&lt;/strong&gt; — and it has to be! If Bob decrypts the same message as "I love you" once and "I hate you" the second time around, that would be a tragedy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice the asymmetry: &lt;strong&gt;Gen&lt;/strong&gt; and &lt;strong&gt;Enc&lt;/strong&gt; are randomized, but &lt;strong&gt;Dec&lt;/strong&gt; is deterministic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Correctness
&lt;/h2&gt;

&lt;p&gt;The first property we demand from any encryption scheme is straightforward: &lt;strong&gt;it should actually work&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Formally:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Dec(Enc(m, k), k) = m&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(for every key k that Gen could output and every message m)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think of it like a physical lock. If Alice locks a box with a key and sends it to Bob, and Bob has a copy of the same key, he should be able to open the box. If the key doesn't open the lock it created — well, that's a pretty useless lock.&lt;/p&gt;

&lt;p&gt;That was simple right?&lt;/p&gt;

&lt;h2&gt;
  
  
  Privacy — What Does "Secure" Even Mean?
&lt;/h2&gt;

&lt;p&gt;Intuitively, we want the ciphertext to not reveal anything about the message to someone who doesn't have the key. But formalizing this intuition, It’s Tricky. Let me walk you through a series of reasonable &lt;strong&gt;looking&lt;/strong&gt; attempts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attempt 1:&lt;/strong&gt; &lt;em&gt;"An encryption scheme is secure if the ciphertext doesn't reveal the key."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Makes sense — if the attacker gets the key, they can decrypt everything. So at minimum, the ciphertext shouldn't leak the key.&lt;/p&gt;

&lt;p&gt;But consider an encryption algorithm that just outputs the plaintext as the ciphertext: &lt;code&gt;Enc(m, k) = m&lt;/code&gt;. The ciphertext reveals nothing about the key. Obviously, this fails.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attempt 2:&lt;/strong&gt; &lt;em&gt;"An encryption scheme is secure if the ciphertext doesn't reveal the plaintext."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Alice just writes "I l$ve you" and sends the letter. How can you say that this reveals the plaintext? We need to be more precise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attempt 3:&lt;/strong&gt; &lt;em&gt;"An encryption scheme is secure if the ciphertext doesn't reveal any individual character of the plaintext."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This plugs the hole from attempt 2. But again, our example of Vigenère cipher in the beginning should be a hint to why this attempt is still not final.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attempt 4:&lt;/strong&gt; &lt;em&gt;"An encryption scheme is secure if the ciphertext doesn't reveal any meaningful information about the plaintext."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sounds good! But what does meaningful mean? Maths might have the answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attempt 5:&lt;/strong&gt; &lt;em&gt;"An encryption scheme is secure if the ciphertext doesn't help the attacker compute **any function&lt;/em&gt;* of the plaintext."*&lt;/p&gt;

&lt;p&gt;Now we're getting somewhere. The ciphertext should be useless for computing &lt;em&gt;anything&lt;/em&gt; about the message, whether that's the message itself, a single character, a range, or any other property.&lt;/p&gt;

&lt;p&gt;But two questions remain:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How do we mathematically formalize whether the ciphertext "helped" the attacker?&lt;/li&gt;
&lt;li&gt;What exactly can the attacker &lt;em&gt;do&lt;/em&gt;? Just stare at the ciphertext? Or something more?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first question leads to deep probability theory (which I'll save for another blog). The second question is what we tackle next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attack Models — What Can the Attacker Do?
&lt;/h2&gt;

&lt;p&gt;In all the models below, the setup is the same: Alice and Bob have agreed on a key k (unknown to the postman), Alice has encrypted a message, and the postman has intercepted the ciphertext c. The postman knows the encryption and decryption algorithms (thanks, Kerckhoffs). The goal of the postman is to compute some function of the underlying plaintext.&lt;/p&gt;

&lt;p&gt;What differs across models is &lt;strong&gt;what additional powers the postman has&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  COA — Ciphertext Only Attack
&lt;/h3&gt;

&lt;p&gt;The simplest scenario. The postman has only the ciphertext. That's it. The postman reads the envelope and tries to figure out the message. No tricks, no prior knowledge — just the scrambled text.&lt;/p&gt;

&lt;p&gt;This is a passive, eavesdropping-only attack. Every encryption scheme should at least be secure against this.&lt;/p&gt;

&lt;p&gt;Mathematically, we write this as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Adversary sees:&lt;/strong&gt; c₁, c₂, ..., cₜ (intercepted ciphertexts)&lt;br&gt;
&lt;strong&gt;Adversary knows:&lt;/strong&gt; Enc, Dec algorithms (Kerckhoffs' Principle)&lt;br&gt;
&lt;strong&gt;Adversary DOES NOT know:&lt;/strong&gt; key k&lt;br&gt;
&lt;strong&gt;Goal:&lt;/strong&gt; Learn something about the plaintexts m₁, m₂, ...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  KPA — Known Plaintext Attack
&lt;/h3&gt;

&lt;p&gt;The postman now has something extra: a collection of (message, ciphertext) pairs encrypted under the same unknown key k. Think of it this way — the postman knows that every letter starts with "Dear Bob", so he already knows what the encryption of "Dear Bob" looks like under this key.&lt;/p&gt;

&lt;p&gt;Armed with this database, a new letter arrives, and the postman tries to crack it. Notice: if encryption were deterministic and the new message happened to be one the postman already has, the ciphertext would match and the game would be over. Here lies another reason encryption must be randomized.&lt;/p&gt;

&lt;p&gt;Mathematically:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Adversary has:&lt;/strong&gt; database of (mᵢ, cᵢ) pairs under key k&lt;br&gt;
&lt;strong&gt;These came from:&lt;/strong&gt; previous messages that lost confidentiality&lt;br&gt;
&lt;strong&gt;Goal:&lt;/strong&gt; Decrypt a NEW ciphertext c (not in the database)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  CPA — Chosen Plaintext Attack
&lt;/h3&gt;

&lt;p&gt;Now things get serious. The postman can now &lt;em&gt;choose&lt;/em&gt; messages and get their encryptions under the unknown key k. It's as if the postman can trick Alice into encrypting messages of the postman's choice — without Alice realizing it.&lt;/p&gt;

&lt;p&gt;"Wait, how is that possible in real life?" you ask. I'll show some concrete examples in later blogs. For now, Go with the Flow.&lt;/p&gt;

&lt;p&gt;The postman builds up a dictionary of (chosen message, ciphertext) pairs, and then tries to learn something about a fresh encrypted message. The postman is now actively interacting with the system, not just listening.&lt;/p&gt;

&lt;p&gt;Mathematically:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Adversary can:&lt;/strong&gt; CHOOSE plaintexts m₁, m₂, ... and get Enc_k(mᵢ)&lt;br&gt;
&lt;strong&gt;Modeled as:&lt;/strong&gt; adversary has an "encryption oracle" — a black box that encrypts anything it asks, under the unknown key k&lt;br&gt;
&lt;strong&gt;Goal:&lt;/strong&gt; Decrypt a NEW challenge ciphertext c (that they did not previously ask the oracle to encrypt)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  CCA — Chosen Ciphertext Attack
&lt;/h3&gt;

&lt;p&gt;The nuclear option. The postman can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get encryptions of any chosen messages (like CPA), AND&lt;/li&gt;
&lt;li&gt;Get decryptions of any chosen ciphertexts (except the challenge ciphertext itself) — by tricking Bob into decrypting ciphertexts of the postman's choice.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The postman can mix and match these services in any order, building up databases of both (message → ciphertext) and (ciphertext → message) pairs under the unknown key.&lt;/p&gt;

&lt;p&gt;Then a fresh ciphertext arrives, and the postman tries to learn something about a fresh encrypted message using everything they've accumulated.&lt;/p&gt;

&lt;p&gt;When we say "an encryption scheme is CCA-secure", we mean that even with all this power, the postman &lt;em&gt;still&lt;/em&gt; can't compute any function of the fresh plaintext. That's a very strong guarantee.&lt;/p&gt;

&lt;p&gt;Formally:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Adversary can:&lt;/strong&gt; Get encryption oracle (like CPA) PLUS get decryption oracle — submit ciphertexts of its choice (except the challenge ciphertext itself) and receive the plaintexts&lt;br&gt;
&lt;strong&gt;Goal:&lt;/strong&gt; Decrypt a FRESH new challenge ciphertext c&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvq055zhy33c617a455cw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvq055zhy33c617a455cw.png" alt="Attack Models Hierarchy" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Reference
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attack Model&lt;/th&gt;
&lt;th&gt;What the Postman Has&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;COA&lt;/strong&gt; (Ciphertext-Only)&lt;/td&gt;
&lt;td&gt;Only the intercepted ciphertext.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;KPA&lt;/strong&gt; (Known-Plaintext)&lt;/td&gt;
&lt;td&gt;A database of historical plaintexts and their matching ciphertexts.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;CPA&lt;/strong&gt; (Chosen-Plaintext)&lt;/td&gt;
&lt;td&gt;An "encryption oracle" to get the ciphertext for any message they choose.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;CCA&lt;/strong&gt; (Chosen-Ciphertext)&lt;/td&gt;
&lt;td&gt;Both an encryption oracle and a decryption oracle to test any ciphertext.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The security hierarchy:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CCA security implies CPA security, which implies KPA security, which implies COA security.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each successive model gives the adversary strictly more capabilities than the previous one. An encryption scheme that is secure under CCA is secure under all the weaker models too.&lt;/p&gt;




&lt;h2&gt;
  
  
  Beyond Secure Communication
&lt;/h2&gt;

&lt;p&gt;Cryptography goes far beyond Alice and Bob sending secret letters. Here's a taste of what else it enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cryptocurrency&lt;/strong&gt; (e.g. Bitcoin) — digital cash that prevents double-spending and preserves anonymity, without any central bank.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Knowledge Proofs&lt;/strong&gt; — proving you know something (like the factors of a large number) without revealing &lt;em&gt;what&lt;/em&gt; you know.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secret Sharing&lt;/strong&gt; — splitting a secret across multiple parties so that no single party can reconstruct it alone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure Multi-Party Computation&lt;/strong&gt; — multiple parties jointly compute a function over their private inputs, without revealing those inputs to each other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Homomorphic Encryption&lt;/strong&gt; — performing computations on encrypted data without ever decrypting it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these deserves its own blog post. For now, just know that the foundations we've discussed — symmetric encryption, asymmetric encryption, formal security definitions, and attack models — are the building blocks for all of these.&lt;/p&gt;




&lt;h3&gt;
  
  
  Acknowledgment
&lt;/h3&gt;

&lt;p&gt;A lot of the technical rigor and structure in this blog is inspired by my reading of &lt;em&gt;"Introduction to Modern Cryptography (Second Edition)"&lt;/em&gt; by Jonathan Katz and Yehuda Lindell. It's a fantastic textbook if you want to dive deeper into the math!&lt;/p&gt;




&lt;p&gt;So the next time you want to write that love letter, remember: cryptography has your back. Just make sure you pick the right key, keep it to yourself, and for the love of security — don't use a proprietary cipher.&lt;/p&gt;

&lt;p&gt;Edit: &lt;a href="https://dev.to/mejainanurag/decoding-cryptography-the-fall-of-historical-ciphers-339j"&gt;Link to next blog&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Note: The diagrams in this blog are AI-generated and meant to be illustrative, not precise technical specifications.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cryptography</category>
      <category>maths</category>
      <category>security</category>
      <category>network</category>
    </item>
  </channel>
</rss>
