pk.org: Computer Security/Lecture Notes

Public Key Cryptography and Integrity

Part 1 - Public Key Cryptography

Paul Krzyzanowski – 2025-09-19

Part 1: Public Key Cryptography
Part 2: Hash functions
Part 3: Integrity Mechanisms
Part 4: Diffie-Hellman
Part 5: Putting It All Together
Part 6: Quantum Attacks and Post-Quantum Cryptography


Public Key Basics

Symmetric cryptography is fast and secure once two parties share a secret key. The central problem is distribution: how can two people who have never met agree on a secret key if an adversary can listen to all their communications? Public key cryptography was developed to address this question. The approach depends on mathematical functions that are easy to compute in one direction but difficult to reverse.

One-Way Functions

A one-way function is a function that is easy to compute but infeasible to invert. Multiplying two large integers is straightforward. Given \(p\) and \(q\), we can quickly compute \(n = p \times q\). However, given \(n\) alone, it is very difficult to recover the original factors \(p\) and \(q\) if they are hundreds of digits long.

Not every function is equally easy to reverse. An example that illustrates this is the middle-squares method, suggested by John von Neumann in 1949 as a way to generate numbers. Start with a seed, square it, and take the middle digits as the output. For example, beginning with 9873, squaring gives 97,493,529, and the middle digits are 4935. Going forward is easy: square, then extract digits. Going backward is much harder. Given only 4935, it is not obvious what original seed produced it. Many candidates are possible, and finding the right one is not straightforward.

This small example shows the essence of a one-way function: easy to compute forward, hard to reverse. The middle-squares method is not used as a cryptographic primitive but is a straightforward example of a function that is hard to invert.

Other one-way functions of interest in cryptography include:

On elliptic curves, the operation we call multiplication is actually repeated addition of a point. If \(P\) is a base point on the curve and \(k\) is an integer, then \(kP\) means adding \(P\) to itself \(k\) times. The result is another point \(Q\) on the curve. Computing \(Q = kP\) is efficient, but given only \(P\) and \(Q\), finding the integer \(k\) is believed to be infeasible. This asymmetry is the elliptic curve discrete logarithm problem, the foundation of elliptic curve cryptography.

Trapdoor Functions

A trapdoor function is a one-way function with a hidden shortcut that makes inversion easy if you know the secret. The shortcut is the trapdoor.

For example, if \(n = p \times q\) and you know one factor, say \(p\), then finding \(q\) is trivial: divide \(n\) by \(p\). Without knowing either factor, recovering both is infeasible when \(p\) and \(q\) are very large. The knowledge of a factor is the trapdoor.

Trapdoor functions are the foundation of public key cryptography. They allow one party to publish a value that is safe for anyone to use in one direction, while only someone with the hidden information can efficiently reverse it. Specific algorithms that exploit this idea, such as RSA, will be introduced later.

The Two-Key Model

Public key cryptography uses a pair of keys:

These keys are mathematically linked. What one key does, the other can undo. If you want to send me a secret, you encrypt it with my public key. Only my private key can decrypt it, so only I can read it. If I want to prove that I created a message, I can encrypt it with my private key. Anyone with my public key can verify that only I could have created it. .

This dual key system eliminated the need to exchange secret keys ahead of time.

Public key cryptography gave us a new security model. Confidentiality and authenticity could now be achieved without prearranged secrets. But these ideas would only become practical once specific algorithms, such as RSA, ECC, and Diffie-Hellman, were developed.

Public Key Encryption and Signature Algorithms

RSA

Origins

In 1977, Ron Rivest, Adi Shamir, and Leonard Adleman at MIT described the first widely usable public key algorithm. It became known by their initials: RSA. Their work built on the concept of trapdoor functions: operations that are easy to compute in one direction but infeasible to reverse unless you know a secret.

Key Generation

RSA’s trapdoor is based on factoring large integers. To create an RSA key pair:

  1. Choose two large random prime numbers, \(p\) and \(q\).
  2. Compute \(n = p \times q\). This is the modulus.
  3. Compute \(\varphi(n) = (p-1)(q-1)\). This is Euler’s totient.
  4. Choose an integer \(e\) that is relatively prime to \(\varphi(n)\). This will be the public exponent.
  5. Compute \(d\), the multiplicative inverse of \(e\) modulo \(\varphi(n)\). In other words, \(e \times d \equiv 1 \pmod{\varphi(n)}\). The number \(d\) is the private exponent.

The public key is the pair \((e, n)\). The private key is \((d, n)\). Knowing \(n\) but not the factors \(p\) and \(q\) makes it infeasible to compute \(d\).

Encryption and Decryption

The mathematics of modular exponentiation and the way \(d\) was chosen guarantee that decryption reverses encryption.

Example

For illustration only, consider small numbers. Let \(p = 61\) and \(q = 53\). Then \(n = 3233\) and \(\varphi(n) = 3120\). Choose \(e = 17\), which is relatively prime to 3120. Compute \(d = 2753\), since \(17 \times 2753 \equiv 1 \pmod{3120}\).

If the message is \(P = 123\), encryption gives \(C = 123^{17} \bmod 3233 = 855\). Decryption gives \(P = 855^{2753} \bmod 3233 = 123\).

These numbers are small enough to compute on a laptop, but practical RSA uses \(n\) with thousands of bits, making factorization infeasible.

Worked example: RSA key generation with small numbers

For those interested, here's an example that goes through the steps in more detail. This example uses tiny primes so you can do the arithmetic by hand. Real RSA uses primes that are hundreds or thousands of bits long. The goal here is to see every step. Skip this section if you don't care.

1) Pick two primes and compute the modulus

Choose primes

Compute the modulus

2) Compute Euler’s totient

For distinct primes,

3) Pick a public exponent \(e\)

Choose an integer \(e\) such that \(1 < e < \varphi(n)\) and \(\gcd(e,\varphi(n)) = 1\).

Public key so far: \((e, n) = (17, 3233)\)

4) Compute the private exponent \(d\)

We need the modular inverse of \(e\) modulo \(\varphi(n)\):

Use the extended Euclidean algorithm to solve \(17d + 3120k = 1\).

Euclidean steps:

Back substitute to express \(1\) as a combination of \(17\) and \(3120\):

Private key: \((d, n) = (2753, 3233)\)

5) Encrypt a small message

Pick a message representative \(P\) with \(0 < P < n\). For illustration, let \(P = 123\). Encryption uses the public key:

6) Decrypt the ciphertext

Decryption uses the private key:

We recover the original message \(P = 123\).

7) (Optional) Sign and verify

The concept of a signature (which we'll look at a bit later) is to prove that only you could have created a message. We're doing the same operations but encrypting with our private key. That means anybody can decrypt the message with the corresponding public key but, by doing so successfully, they will know that the message must have been encrypted by someone who has the private key.

To sign a short representative \(M\):

To verify:

With \(M = 123\),

8) What makes this secure

Security depends on the difficulty of factoring \(n\). Given only \(n = 3233\) it is easy to factor by hand, which is why this example is not secure and is only for demonstration. In real RSA, \(p\) and \(q\) are very large primes. Without the factors, computing \(d\) from \(e\) and \(n\) is infeasible.

Summary of the key pair

You can now point to each step and connect it to the definitions: \(n\) identifies the RSA group, \(\varphi(n)\) controls the arithmetic of inverses, \(e\) is chosen to be coprime with \(\varphi(n)\), and \(d\) is the modular inverse that makes decryption invert encryption.

Security

The security of RSA rests on the difficulty of factoring large composite numbers. Given only \(n\), it is not practical to recover \(p\) and \(q\). Without those factors, it is infeasible to compute \(d\) from \(e\). RSA has been analyzed for decades, and its security assumptions are well understood.

Elliptic Curve Cryptography (ECC)

Motivation

RSA requires large keys. Today, a secure RSA modulus must be at least 2048 bits. Operations on numbers this large are slow. In the mid-1980s, researchers proposed a different approach: elliptic curve cryptography (ECC). ECC is based on the mathematics of elliptic curves and provides the same level of security as RSA with much smaller keys and faster computations.

Elliptic Curves

An elliptic curve is defined by an equation such as: \[y^2 = x^3 + ax + b \pmod p\] where \(p\) is a large prime. The set of points \((x, y)\) that satisfy this equation, together with a special point at infinity, form a group with a defined addition operation.

Scalar Multiplication

On an elliptic curve, we can define the operation of adding points. Here, addition does not mean ordinary arithmetic on coordinates but a special group operation defined by the curve. Repeatedly adding a base point \(G\) to itself \(d\) times is called scalar multiplication and is written: \[Q = dG\] Computing \(Q\) from \(d\) and \(G\) is straightforward. Given \(G\) and \(Q\), finding \(d\) is the elliptic curve discrete logarithm problem, which is believed to be infeasible.

Keys

Like RSA, one key is public, and the other is private. The relationship is easy to compute forward, but infeasible to reverse.

Advantages

ECC achieves strong security with smaller keys. A 256-bit ECC key offers comparable security to a 3072-bit RSA key. This efficiency makes ECC attractive in constrained environments such as smartphones, embedded devices, and network protocols that must handle large numbers of secure sessions quickly.

Encryption vs. Key Exchange

It is important to distinguish between public key encryption algorithms and key exchange protocols. RSA and ECC can be used to encrypt data or to create signatures. They transform values directly with a public-private key pair.

In contrast, Diffie-Hellman, which we will study later, is a key exchange protocol. It does not encrypt or sign messages directly. Instead, it allows two parties to agree on a shared secret key. That secret key can then be used with a symmetric cipher such as AES.

RSA and ECC give us the ability to encrypt data and sign messages. Diffie-Hellman gives us the ability to establish a shared key over an insecure channel. Together, they are the central tools of modern public key cryptography.

Why Not Use Public Key Algorithms for All Encryption?

A common question is: if RSA and elliptic curve cryptography can encrypt data, why not just use them directly to protect all communication? There are several reasons why this is not practical.

Performance.
Public key operations are much slower than symmetric encryption. RSA relies on modular exponentiation with very large numbers, and ECC relies on elliptic curve point multiplications. Both are orders of magnitude slower than the simple substitutions and permutations that make AES or ChaCha20 extremely efficient. Symmetric ciphers can encrypt gigabits per second of data; public key algorithms cannot keep up with bulk traffic.
Ciphertext expansion.
In RSA, each ciphertext block has the same size as the modulus. With a 2048-bit modulus, every encrypted block is 256 bytes, even if the message is just a few bytes. This makes small messages inefficient and rules out streaming large files: each block of plaintext would inflate to hundreds of bytes.
Elliptic curve systems avoid such huge blow-ups but still carry overhead. Each ciphertext must include an extra curve point (for an ephemeral key) along with the encrypted message. For small messages, the overhead can exceed the size of the data. More importantly, ECC operations are still too slow to be used like a block cipher. You cannot attach a mode like CTR or CBC to ECC and expect efficient bulk encryption; the underlying mathematics is not designed for that role.
Symmetric ciphers such as AES or ChaCha20 behave differently. They expand data minimally: ciphertext length is essentially equal to plaintext length, with at most a small constant overhead for an initialization vector or nonce. They are designed to handle large volumes of data at high speed.
Exposure to chosen-plaintext attacks.
Public keys are public, so anyone can encrypt arbitrary messages. Suppose Bob sends messages to Alice encrypted with Alice’s public key. Eve, the attacker, can guess possible messages (for example, “Yes,” “No,” “Meet at 5,” etc.), encrypt each guess with Alice’s public key, and compare the results with Bob’s ciphertext. If one matches, Eve has learned the plaintext without ever breaking the math. This is why raw public key encryption is insecure: it does not hide the relationship between plaintext and ciphertext well enough. Secure use of public key encryption requires randomized padding and other protections.
Some algebraic relationships may be preserved.
Public key algorithms are brittle when used directly on arbitrary data. Raw RSA encryption is malleable and vulnerable to chosen-ciphertext attacks. To be secure, it requires padding schemes and careful framing. ECC-based encryption schemes similarly rely on symmetric ciphers and message authentication codes internally. This shows that even when they are used “to encrypt,” public key methods depend on symmetric primitives for confidentiality and integrity.

Public key algorithms were designed to solve the key distribution problem, not to replace symmetric ciphers. They let two parties who have never met exchange or protect a symmetric session key and create digital signatures for authenticity. For actual data protection, symmetric ciphers are the right tool. Later, when we look at key exchange, we will see how systems combine the strengths of both approaches.

Sidebar: Why ECC ElGamal Ciphertexts Are About Twice as Long

ECC ElGamal is an asymmetric encryption scheme built on elliptic curves. To encrypt a message point \(M\), the sender chooses a fresh random scalar \(r\) for each ciphertext. The ciphertext is a pair of points:

  • \(R = rG\) (the ephemeral public key)
  • \(C = M + rQ\) (the masked message, where \(Q = dG\) is the receiver’s public key)

The receiver uses their single long-term private key \(d\) to compute \(dR = rQ\) and then recovers the message by computing \(M = C - dR\).

This design means every ciphertext carries two curve points regardless of how much plaintext is inside. With point compression, that is about 66 bytes per ciphertext on a 256-bit curve. If the message chunk being encrypted is ~32 bytes, the ciphertext is roughly double the size. For a large file broken into many chunks, the doubling persists: each chunk has its own \(R\) value and therefore two points in the ciphertext.

This is why ECC ElGamal is unsuitable for bulk encryption, even though the math works perfectly well; the inefficiency is inherent. They expand data minimally: ciphertext length is essentially equal to plaintext length, with at most a small constant overhead for an initialization vector or nonce. They are designed to handle large volumes of data at high speed.


Next: Part 2: Hash functions