Every time you enter your UPI PIN in PhonePe or Google Pay, that PIN does not travel straight from your phone to your bank. It hops through your mobile network's towers, through the app company's servers, through the National Payments Corporation of India's switching network, and finally into your bank's system. At every one of those hops, someone — a network engineer, a hacker with a packet sniffer, even a nosy app on a shared Wi-Fi router — could technically be watching the data go past. Yet your PIN stays secret. Millions of IRCTC ticket bookings, WhatsApp messages, and OTPs cross networks like this every second in India, and almost none of them are ever read by an outsider. The reason is a 2,000-year-old idea dressed up in modern mathematics: cryptography, the science of transforming a message so that only the intended reader can recover it, even if everyone else can see the transformed version.
This chapter builds that idea from the ground up — starting with a cipher a Roman general could do in his head, finding out precisely why it fails, and following the trail of "why it fails" all the way to the mathematics that protects your phone today.
Plaintext, Ciphertext, and the Key
Before any formulas, fix three words, because every cryptography problem is really just these three things arranged differently:
- Plaintext — the original, readable message. Example:
ATTACK AT DAWN. - Ciphertext — the scrambled version that gets sent over the insecure channel. It should look like meaningless noise to anyone without the key.
- Key — a piece of secret information that controls exactly how the plaintext gets scrambled and unscrambled. Two people who share the key can convert between plaintext and ciphertext; anyone without it should not be able to, even if they know the general method being used.
That last point is a rule cryptographers take very seriously, first written down clearly by the Dutch cryptographer Auguste Kerckhoffs in 1883: a cryptographic system should be secure even if everyone in the world except the intended receiver knows exactly how it works — the only thing that must stay secret is the key. This matters because it tells you what "breaking" a cipher actually means: an attacker is allowed to know you used, say, a Caesar cipher. Security has to come from the key, not from hiding the method.
The Caesar Cipher: Shifting the Alphabet
The simplest useful cipher, used by Julius Caesar to send military orders around 58 BCE, works by shifting every letter forward in the alphabet by a fixed number of places. That fixed number is the key.
Let's encrypt the word INDIA with a shift key of 3. Write out the alphabet, and next to it, the alphabet shifted 3 places:
Plain: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Cipher: D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
Now substitute each letter of INDIA using this table: I→L, N→Q, D→G, I→L, A→D. The ciphertext is LQGLD. Notice the wraparound rule hiding in that table — X, Y, Z shift into A, B, C — because the alphabet is circular for this purpose. That circularity is exactly what "mod 26" means in mathematics: you go forward, and when you run off the end, you wrap back to the start.
Formally, number the letters A=0, B=1, ..., Z=25. If P is a plaintext letter's number and k is the shift key, the ciphertext letter's number C is:
C = (P + k) mod 26
Check it for I (P=8) with k=3: C = (8+3) mod 26 = 11, and letter 11 is L. Matches. Decryption just runs the shift backward: P = (C − k) mod 26. The diagram below shows both alphabets as two rings — the outer ring is plaintext, the inner ring is ciphertext shifted by 3 positions. Reading straight down from any outer letter to the letter beneath it on the inner ring gives you that letter's encryption.
Try decrypting LQGLD by hand using P = (C − 3) mod 26 before reading on: L(11)−3=8=I, Q(16)−3=13=N, G(6)−3=3=D, L(11)−3=8=I, D(3)−3=0=A. You recover INDIA.
Here is the same logic as a Python function, which is how CBSE Computer Science expects you to express an algorithm precisely:
def caesar_encrypt(text, shift):
result = ""
for char in text:
if char.isalpha():
base = ord('A') if char.isupper() else ord('a')
result += chr((ord(char) - base + shift) % 26 + base)
else:
result += char # leave spaces/punctuation unchanged
return result
def caesar_decrypt(text, shift):
return caesar_encrypt(text, -shift) # shifting by -3 undoes shifting by +3
print(caesar_encrypt("INDIA", 3)) # LQGLD
print(caesar_decrypt("LQGLD", 3)) # INDIA
Trace the first call by hand to be sure the code is correct, not just plausible-looking. For char='I': ord('I') is 73, base is 65 (uppercase). (73 − 65 + 3) % 26 = 11 % 26 = 11, then chr(11 + 65) = chr(76) = 'L'. That matches the hand calculation above. For caesar_decrypt, passing shift=-3 into the same formula gives (ord(char) - base - 3) % 26 — Python's % operator always returns a non-negative result for a positive modulus, so even a negative shift wraps correctly (for example (11 - 3) % 26 = 8, which is I). This is a genuine subtlety: in some other languages, the modulus of a negative number can come out negative, and a direct port of this code would silently produce wrong letters — worth remembering if you ever translate this function to C++.
Why the Caesar Cipher Is Easy to Break
A shift key can only be one of 25 useful values (shifting by 0 does nothing, and shifting by 26 is the same as 0). That means an attacker who intercepts LQGLD without the key can simply try all 25 shifts and read off the one that produces real words — this is called a brute-force attack, and a computer does it in far less than a second. Trying every key is always possible in principle; a cipher is only useful if the number of keys is so astronomically large that brute force would take longer than the age of the universe.
So the natural next idea is: use a bigger key. Instead of just shifting the alphabet, scramble it completely — map A to any letter, B to any other letter, and so on, with no fixed pattern. This is a substitution cipher, and the key is the entire scrambled alphabet. How many possible keys does that give? The first plaintext letter can map to any of 26 ciphertext letters, the second to any of the remaining 25, the third to any of the remaining 24, and so on — giving 26 × 25 × 24 × ... × 1 = 26! (26 factorial), which works out to roughly 4 × 10²⁶ possible keys. That is far more than the number of grains of sand on Earth. Surely that is unbreakable?
This is exactly the point where a common misconception needs correcting. Many students assume that once the key space is astronomically large, brute force is impossible, so the cipher must be secure. That reasoning is incomplete. A huge key space only rules out one specific attack — trying every key by hand. It says nothing about whether the cipher leaks patterns you can exploit a smarter way. And the substitution cipher does leak a pattern: every time the letter E appears in the plaintext, it becomes the *same* ciphertext letter, every single time, throughout the whole message. That consistency is a structural weakness, independent of key-space size.
The attack that exploits it is called frequency analysis, and it was already known to Arab mathematician Al-Kindi in the 9th century. In ordinary English text, letters do not occur equally often — E is the most common letter (roughly 12–13% of all letters in typical English text), followed by T, A, O, and others, while letters like Q, X, and Z are rare. If you intercept a reasonably long substitution-ciphertext message, count how often each ciphertext symbol appears, and the most frequent symbol is very likely the encryption of E. From there you use common short words (patterns like a lone one-letter word being "I" or "A") and common pairs like "TH" and "HE" to peel the rest apart, usually within minutes for a paragraph-length message. The lesson generalizes far beyond this one cipher: a cipher's real strength comes from how well it hides statistical patterns, not merely from how many keys it has. This single idea is one of the most important in all of cryptography, and it is why every serious modern cipher is specifically designed so that ciphertext looks statistically like random noise, with no letter, byte, or bit pattern more likely than any other.
XOR and the One-Time Pad: A Cipher That Cannot Be Broken
To fix the "same plaintext letter always becomes the same ciphertext letter" flaw, we need the encryption of each letter to depend not just on that letter but on its *position* in the message too. The cleanest way to do this uses binary and an operation called XOR (exclusive OR), which CBSE Informatics Practices also uses when discussing logic gates. XOR compares two bits and outputs 1 if they differ, 0 if they are the same:
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
XOR has a magical property for cryptography: XOR-ing twice with the same value gets you back to where you started. If C = P XOR K, then C XOR K = (P XOR K) XOR K = P XOR (K XOR K) = P XOR 0 = P. So the *same* key both encrypts and decrypts — no separate decryption formula needed. Try it with plaintext bits 1010 and key bits 1100:
Plaintext: 1 0 1 0
Key: 1 1 0 0
Ciphertext: 0 1 1 0 (XOR each column)
Decrypt: ciphertext XOR key again
Ciphertext: 0 1 1 0
Key: 1 1 0 0
Result: 1 0 1 0 (back to the original plaintext)
Now here's the key insight (pun intended): if the key is exactly as long as the message, made of truly random bits, used only once, and never shared with anyone but the sender and receiver, this scheme is called a one-time pad, and in 1949 the American mathematician Claude Shannon proved mathematically that it is unbreakable — not "unbreakable with today's computers," but unbreakable even by an attacker with infinite computing time and infinite patience, because every possible plaintext of that length is equally consistent with the observed ciphertext. No frequency analysis can ever help, because a truly random key destroys every statistical pattern in the plaintext.
So why doesn't WhatsApp just use one-time pads for everything? Because the conditions are brutal in practice: the key must be as long as the entire message (so sending a 10 MB photo needs a 10 MB secret key), it must never be reused for a second message, and — the real killer — both parties need to have securely shared that huge random key *before* they can talk. If you already had a secure way to hand over a giant secret key, you probably wouldn't need to send an encrypted message in the first place. This impracticality is exactly why real systems use a different strategy: reuse a much shorter key cleverly through mathematical algorithms (like AES, which is what actually protects your WhatsApp chats), accepting a computational rather than a mathematical guarantee of secrecy — secure not because breaking it is impossible, but because breaking it would take longer than anyone is willing to wait.
The Real Problem: How Do Two Strangers Agree on a Key?
Every cipher discussed so far is symmetric — the same key encrypts and decrypts, so both the sender and receiver must possess an identical secret key before any message is sent. This creates what's called the key distribution problem: when you visit an IRCTC or e-commerce website for the very first time, your browser and that website's server have never met before and share no secret. Yet within a fraction of a second, they need to agree on a shared symmetric key — over the very same internet connection that an eavesdropper might be watching. If they simply sent the key across in the open, anyone listening would capture it and could decrypt everything that followed. It seems like a chicken-and-egg problem: you need a secure channel to set up a secure channel.
The breakthrough that solved this, discovered by Whitfield Diffie and Martin Hellman in 1976 (with related ideas independently found by Clifford Cocks at UK intelligence agency GCHQ a few years earlier, though his work stayed classified for decades), is asymmetric or public-key cryptography. The idea, before any formulas: imagine an open padlock. You (the receiver) manufacture thousands of copies of an open padlock and hand them out publicly — anyone can pick one up. Only you keep the single matching key. Anyone in the world can snap one of your padlocks shut on a box, and once it's shut, *only you* can open it, even though the padlock itself was public and even though the sender never had your key. The padlock is your public key (safe to publish anywhere); the thing that opens it is your private key (never shared with anyone).
How a Public-Key Padlock Actually Works: A Tiny RSA Example
The most famous implementation of this idea is RSA (named after its inventors Rivest, Shamir, and Adleman, 1977), and it is built entirely on one number-theory fact: multiplying two large prime numbers together is easy, but taking a large number and figuring out which two primes were multiplied to produce it (factoring) is extremely slow once the numbers have hundreds of digits. Real RSA uses primes hundreds of digits long; here is the exact same procedure using tiny primes so every step can be verified by hand.
- Pick two prime numbers. Let p = 3 and q = 11.
- Compute n = p × q = 33. This n is published as part of the public key.
- Compute φ(n) = (p−1)(q−1) = 2 × 10 = 20. This value must stay secret — it's derived from the primes.
- Choose a public exponent e, any number that shares no common factor with 20 (other than 1). Let's pick e = 7 — check: the factors of 20 are 2 and 5; 7 shares none of them, so it qualifies. The public key is the pair (e=7, n=33).
- Find the private exponent d, the number such that (e × d) mod φ(n) = 1, i.e., (7 × d) mod 20 = 1. Testing d=3: 7×3=21, and 21 mod 20 = 1. So d = 3. The private key is (d=3, n=33) — and this is the number an attacker would need to derive by factoring n=33 back into 3×11, which is trivial here but practically impossible for 600-digit numbers.
Now encrypt a simple message, the number m = 2 (real RSA converts letters/bytes to numbers first), using the public key: c = m^e mod n.
c = 2^7 mod 33
= 128 mod 33
= 128 - (3 × 33) [33 × 3 = 99]
= 128 - 99
= 29
The ciphertext is 29. This can be sent openly — anyone can see 29 travel across the network, but only whoever holds d=3 can reverse it. Decrypt using the private key: m = c^d mod n.
m = 29^3 mod 33
= 29 × 29 × 29 mod 33
Step 1: 29^2 = 841
841 mod 33 = 841 - (25 × 33) = 841 - 825 = 16
Step 2: 29^3 mod 33 = (16 × 29) mod 33 = 464 mod 33
464 mod 33 = 464 - (14 × 33) = 464 - 462 = 2
The result is 2 — exactly the original message. Notice something important: the public key (7, 33) and the private key (3, 33) are mathematically linked (through φ(n)=20), yet knowing the public key does not hand you the private key, because computing φ(n) from n requires factoring n into its prime components, and that is the hard direction. With p=3 and q=11 that factoring took no effort; with two 300-digit primes, even every computer on Earth working together would need far longer than the current age of the universe to factor n by brute force with known classical algorithms. That gap between "easy in one direction, hard in the other" is called a trapdoor function, and it's the mathematical foundation the entire padlock analogy rests on.
How Your Browser Actually Combines Both Ideas
Here's a second common misconception worth correcting directly: many people assume that when they see the padlock icon while booking a train ticket on IRCTC, their entire session — every page, every rupee amount, every seat number — is being encrypted with RSA the whole time. That's not quite what happens, and the real design is smarter. Asymmetric encryption like RSA involves modular exponentiation on large numbers, which is computationally far slower than symmetric ciphers like AES. So browsers use a hybrid approach: asymmetric cryptography is used only briefly, at the very start of the connection, to solve exactly the key-distribution problem described earlier — the browser generates a random symmetric key, encrypts just that key using the server's RSA public key, and sends it over. Only the server's private key can recover that symmetric key. From that point on, for the rest of the session, both sides switch to a fast symmetric cipher (like AES) using the now-shared key. This handshake is what the TLS protocol (the "S" in HTTPS) performs automatically, in milliseconds, every time you load a secure website.
It's also worth distinguishing encryption from a related but different tool: hashing. A hash function (like SHA-256) takes any input and produces a fixed-length fingerprint, but unlike encryption, hashing is one-way by design — there is no key that reverses it, and no "decryption" step exists at all. Hashing verifies that data hasn't been tampered with (comparing fingerprints) or stores passwords safely (a website stores the hash of your password, not the password itself, so even if its database leaks, your actual password isn't directly exposed). Confusing "hashed" with "encrypted" is a common error: encrypted data is meant to be decrypted by someone; hashed data is never meant to be reversed by anyone.
Worked Practice: Trace It Yourself
Before checking the answers, work through these using the tools built up in this chapter.
- Encrypt the plaintext
CBSEwith a Caesar shift key of 5. (Hint: C=2, B=1, S=18, E=4; apply C=(P+5) mod 26 to each.) - A message was intercepted as ciphertext
KHOOR. You're told it's a Caesar cipher with shift key 3. Decrypt it. - Explain in one or two sentences why a substitution cipher with 4×10²⁶ possible keys can still be broken quickly, using the term "frequency analysis."
- Using RSA with p=5, q=11 (so n=55, φ(n)=(5−1)(11−1)=40) and public exponent e=3 (check: gcd(3,40)=1, valid), find the private exponent d such that (3×d) mod 40 = 1. Then encrypt m=4 and decrypt your ciphertext back to confirm you recover 4.
- Why is a one-time pad "unbreakable" in theory but almost never used in practice? Name the specific practical obstacle.
Answers: (1) C=(2+5)%26=7=H, B=(1+5)%26=6=G, S=(18+5)%26=23=X, E=(4+5)%26=9=J → HGXJ. (2) Shift back by 3: K(10)→H(7), H(7)→E(4), O(14)→L(11), O(14)→L(11), R(17)→O(14) → HELLO. (3) Because although the key space is huge, each plaintext letter always maps to the same ciphertext letter throughout the message, so counting how often each ciphertext symbol appears reveals which one corresponds to common letters like E — the key space size never protected against this pattern. (4) d=27 works, since 3×27=81 and 81 mod 40 = 1 (81 − 40 − 40 = 1). Encrypt: c = 4^3 mod 55 = 64 mod 55 = 9. Decrypt: m = 9^27 mod 55 — using repeated squaring: 9^2=81≡26, 9^4≡26^2=676≡676−12×55=676−660=16, 9^8≡16^2=256≡256−4×55=36, 9^16≡36^2=1296≡1296−23×55=1296−1265=31; 27=16+8+2+1, so 9^27 ≡ 31×36×26×9 mod 55 → 31×36=1116≡1116−20×55=16; 16×26=416≡416−7×55=31; 31×9=279≡279−5×55=4. Result: m=4, confirmed. (5) The key must be truly random, exactly as long as the message, and shared securely in advance and used only once — securely distributing and never reusing a key that long is itself as hard as the original problem of sending a secret message.
Summary
Cryptography turns readable plaintext into unreadable ciphertext using a key, under Kerckhoffs's principle that security must rest entirely in the key, never in secrecy of the method. The Caesar cipher shifts letters using modular arithmetic (C = (P+k) mod 26) but has only 25 keys, so brute force breaks it instantly. Scrambled substitution ciphers have a vastly larger key space (26! ≈ 4×10²⁶) but remain breakable through frequency analysis, because each plaintext letter always produces the same ciphertext letter — proving that key-space size alone does not guarantee security; resistance to statistical pattern-finding does. XOR-based one-time pads, keyed with truly random, message-length, single-use keys, are the only provably unbreakable cipher (Shannon, 1949), but the requirement to pre-share such a huge key makes them impractical for everyday use. Symmetric ciphers (one shared key, like AES) are fast but face the key-distribution problem — two strangers, like your browser and an IRCTC server, cannot safely exchange a key over an insecure channel by simply sending it. Asymmetric public-key cryptography (like RSA) solves this using a trapdoor function — multiplying primes is easy, factoring their product back apart is hard — letting anyone encrypt with a published public key while only the private-key holder can decrypt. Modern systems like HTTPS combine both: asymmetric cryptography briefly exchanges a symmetric key, then fast symmetric encryption protects the actual session. Hashing, unlike encryption, is a one-way fingerprint with no decryption step, used for integrity checks and password storage rather than for secret-keeping.