In public key cryptography, there are two keys:
- Public Key - Shared with everyone (used to encrypt)
- Private Key - Kept secret (used to decrypt)
sequenceDiagram
participant A as Alice (Sender)
participant B as Bob (Receiver)
Note over B: Generates key pair
B-->>A: Publishes public key (e, n)
Note over A: Encrypts with Bob's public key
A->>B: Sends ciphertext C = Mᵉ mod n
Note over B: Decrypts with private key (d, n)
B->>B: Recovers M = Cᵈ mod n
Key insight: Anyone can encrypt, but only Bob can decrypt!
Problem with symmetric crypto: How do you share the secret key securely?
RSA solution:
- Encryption key is public (anyone can encrypt)
- Decryption key is private (only recipient can decrypt)
- Keys are mathematically related but computationally hard to derive one from the other
flowchart TD
A([Start]) --> B["Choose large primes p, q"]
B --> C["Compute n = p × q\n(modulus)"]
C --> D["Compute φ(n) = (p−1)(q−1)"]
D --> E["Choose e where\ngcd(e, φ(n)) = 1\ncommonly e = 65537"]
E --> F["Compute d = e⁻¹ mod φ(n)\nvia Extended Euclidean"]
F --> G(["Public key: (e, n)\nPrivate key: (d, n)"])
style A fill:#7c4dff,color:#fff
style G fill:#00897b,color:#fff
Pick two large prime numbers
Example:
Example:
This is the modulus for both keys.
Euler's totient function:
Example:
Pick
$1 < e < \phi(n)$ -
$\gcd(e, \phi(n)) = 1$ (e and$\phi(n)$ are coprime)
Common choice:
Example: Let's use
Check:
Find
In other words,
Example: Find
Using Extended Euclidean Algorithm:
Verify:
Example:
Example:
Share: Public key
Keep secret: Private key
Given plaintext message
where:
-
$C$ = ciphertext -
$M$ = plaintext -
$e$ = public exponent -
$n$ = modulus
Plaintext:
Public key:
Using fast exponentiation:
Given ciphertext
where:
-
$M$ = plaintext (recovered) -
$C$ = ciphertext -
$d$ = private exponent -
$n$ = modulus
Ciphertext:
Private key:
Success! We recovered the original message.
Substituting:
If
Since
for some integer
Therefore:
Easy: Given
Hard: Given
To find
- Factor
$n$ into$p$ and$q$ - Compute
$\phi(n) = (p-1)(q-1)$ - Find
$d = e^{-1} \bmod \phi(n)$
Factoring large numbers is computationally infeasible!
For 2048-bit RSA:
-
$n$ has ~600 digits - Best known algorithms take billions of years
- Minimum: 2048 bits
- Recommended: 3072-4096 bits
- Insecure: 1024 bits or less
- Large (1024+ bits each)
- Random
- Not too close to each other
- Actually prime (use primality testing)
Problem: RSA needs large primes. We cannot test primality by dividing up to
$\sqrt{n}$ — too slow for big numbers!
Instead of checking every divisor, we test if a number "behaves like a prime."
- If it fails → definitely composite
- If it passes many tests → probably prime
If
- Pick a random
$a$ where$1 < a < n$ - Compute
$a^{n-1} \bmod n$ -
If NOT 1 →
$n$ is composite -
If 1 →
$n$ is maybe prime
Some composite numbers pass the Fermat test. These are called Carmichael numbers.
Example: 561 is composite but passes Fermat test for all
- More reliable than Fermat
- Still probabilistic
- Much harder to fool
Write
For random
- Compute
$x = a^d \bmod n$ - If
$x = 1$ or$x = n-1$ → probably prime - Square
$x$ repeatedly$r-1$ times - If you ever get
$n-1$ → probably prime - Otherwise → definitely composite
Run Miller-Rabin
- Probability of error:
$< 4^{-k}$ - With
$k = 40$ → error probability$< 2^{-80}$ (negligible)
Never use raw RSA! It has vulnerabilities:
- Deterministic - same message always produces same ciphertext
- Malleable - can manipulate ciphertexts
- No integrity - attacker can modify messages
Add randomness and structure before encryption:
This makes RSA:
- Non-deterministic (random for each encryption)
- Semantically secure
- Resistant to attacks
If
- Ciphertext might be smaller than
$n$ - Can recover
$M$ by taking cube root
Defense: Use padding (OAEP)
If two users share the same
- Attacker can decrypt without private key
Defense: Never reuse modulus
Measure how long decryption takes to learn about private key.
Defense: Use constant-time algorithms
- RSA uses two keys - public for encryption, private for decryption
- Security relies on factoring being hard
- Key generation requires large random primes
- Primality testing uses probabilistic algorithms (Miller-Rabin)
- Never use textbook RSA - always use padding (OAEP)
- Key size matters - minimum 2048 bits