The lattice cryptosystem

The math and definitions explained

In cryptography, we often encrypt and sign messages that contain characters. However, asymmetric key cryptosystems (where Alice and Bob use different keys), such as RSA and ElGamal, are based on arithmetic operations on integers. Symmetric key cryptosystems (where Alice and Bob use the same key), such as DES and AES, are based on bitwise operations on bits (a bit is either 0 or 1 and is an abbreviation for binary digit). Therefore, we must convert characters into integers or bits before applying the cryptosystem to the message.

Because a computer can only handle bits, there already exists a method for converting characters into integers or bits, which uses the ASCII (American Standard Code for Information Interchange) table. A part of the ASCII table from Wikipedia is shown in the following table (note that the binary representation on the Wikipedia site uses only seven bits, but we use eight bits by prepending an extra 0):

Character Decimal Hexadecimal Binary
(space) 32 20 00100000
! 33 21 00100001
\( \vdots \) \( \vdots \) \( \vdots \) \( \vdots \)
A 65 41 01000001
B 66 42 01000010
\( \vdots \) \( \vdots \) \( \vdots \) \( \vdots \)
a 97 61 01100001
b 98 62 01100010
\( \vdots \) \( \vdots \) \( \vdots \) \( \vdots \)

For example, if Alice wants to send the message "Hey Bob!" encrypted to Bob using a symmetric key cryptosystem, she first converts it into its integer representation and then into its binary representation:

\( \eqalign{ H &\rightarrow 72 &&\rightarrow 01001000 \\ e &\rightarrow 101 &&\rightarrow 01100101 \\ y &\rightarrow 121 &&\rightarrow 01111001 \\ &\rightarrow 32 &&\rightarrow 00100000 \\ B &\rightarrow 66 &&\rightarrow 01000010 \\ o &\rightarrow 111 &&\rightarrow 01101111 \\ b &\rightarrow 98 &&\rightarrow 01100010 \\ ! &\rightarrow 33 &&\rightarrow 00100001 } \)

That is, the message "Hey Bob!" is represented with integers as "72 101 121 32 66 111 98 33" and in binary as "01001000 01100101 01111001 00100000 01000010 01101111 01100010 00100001".

While ASCII is sufficient for basic English text, modern cryptographic applications often need to handle international characters. Unicode standards like UTF-8 extend ASCII and can encode virtually all characters from all writing systems. In UTF-8, ASCII characters still use a single byte, while other characters may use 2-4 bytes.

Modern cryptographic algorithms typically operate on bytes (8-bit units) or words (groups of bytes). The binary representation shown above organizes characters into bytes, which serve as the fundamental unit for cryptographic operations in algorithms like AES, where data is processed in 128-bit (16-byte) blocks.

Notice the relationship between the different representations:

  • The decimal form is what computers process mathematically
  • The hexadecimal form (base 16) provides a more compact representation where each hex digit represents exactly 4 bits
  • The binary form (base 2) shows the actual bit pattern stored in memory

It's important to note that encoding (converting characters to numbers or binary) is not the same as encryption. Encoding is a standardized, reversible process with no secret key. Anyone knowing the encoding scheme can decode the message. Encryption, on the other hand, requires a key to reverse the process, providing actual security.

Related Encoding Schemes in Cryptography

Several other encoding schemes are commonly used in cryptographic applications:

  • Base64: Often used to encode binary data (like encryption keys or encrypted messages) into ASCII text for safe transmission over text-based channels
  • Hex encoding: Frequently used to represent hashes, keys, and other binary values in a human-readable format
  • Block padding: Many cryptographic algorithms operate on fixed-size blocks (e.g., AES uses 128-bit blocks), requiring messages to be padded to the appropriate length

The exponent of a number indicates how many times the number is multiplied by itself. For example:

\( 4^{3} = 4 \cdot 4 \cdot 4 = 64 \)

Here, 3 is the exponent (or power), and 4 is the base. In words, we say "4 to the power of 3."

Here are the laws of exponents:

Law Example
\( x^{1} = x \) \( 3^{1} = 3 \)
\( x^{0} = 1 \) \( 4^{0} = 1 \)
\( x^{-1} = \frac{1}{x} \) \( 5^{-1} = \frac{1}{5} \)
\( x^{m} \cdot x^{n} = x^{m+n} \) \( x^{2} \cdot x^{3} = (x \cdot x) \cdot (x \cdot x \cdot x) = x \cdot x \cdot x \cdot x \cdot x = x^{5} = x^{2+3} \)
\( \frac{x^{m}}{x^{n}} = x^{m-n} \) \( \frac{x^{4}}{x^{2}} = \frac{x \cdot x \cdot x \cdot x}{x \cdot x} = x \cdot x \cdot \frac{x \cdot x}{x \cdot x} = x \cdot x \cdot 1 = x^{2} = x^{4-2} \)
\( (x^{m})^{n} = x^{m \cdot n} \) \( (x^{2})^{3} = (x \cdot x) \cdot (x \cdot x) \cdot (x \cdot x) = x \cdot x \cdot x \cdot x \cdot x \cdot x = x^{6} = x^{2 \cdot 3} \)
\( (x \cdot y)^{n} = x^{n} \cdot y^{n} \) \( (x \cdot y)^{2} = (x \cdot y) \cdot (x \cdot y) = x \cdot x \cdot y \cdot y = x^{2} \cdot y^{2} \)
\( (\frac{x}{y})^{n} = \frac{x^{n}}{y^{n}} \) \( (\frac{x}{y})^{3} = (\frac{x}{y}) \cdot (\frac{x}{y}) \cdot (\frac{x}{y}) = \frac{x \cdot x \cdot x}{y \cdot y \cdot y} = \frac{x^{3}}{y^{3}} \)
\( x^{-n} = \frac{1}{x^{n}} \) \( x^{-3} = (x^{-1})^{3} = (\frac{1}{x})^{3} = \frac{1}{x} \cdot \frac{1}{x} \cdot \frac{1}{x} = \frac{1 \cdot 1 \cdot 1}{x \cdot x \cdot x} = \frac{1}{x^{3}} \)
\( x^{\frac{1}{n}} = \sqrt[n]{x} \) \( 9^{\frac{1}{2}} = \sqrt{9} = 3 \)
\( x^{\frac{m}{n}} = \sqrt[n]{x^m} = (\sqrt[n]{x})^m \) \( 8^{\frac{2}{3}} = \sqrt[3]{8^2} = \sqrt[3]{64} = 4 \)
Exponentiation in Modular Arithmetic

In cryptography, we often compute exponents in modular arithmetic:

\( a^b \mod n \) means raising \(a\) to power \(b\) and then taking the remainder when divided by \(n\)

Example: \( 3^4 \mod 7 = 81 \mod 7 = 4 \)

The same exponent rules apply in modular arithmetic:

\( (a^m \cdot a^n) \mod n = a^{m+n} \mod n \)

\( (a^m)^n \mod p = a^{m \cdot n} \mod p \)

Importance in Cryptography

These exponent rules are fundamental to many cryptographic algorithms:

  • RSA: Uses the property that \((m^e)^d \mod n = m^{e \cdot d} \mod n\)
  • Diffie-Hellman: Relies on \((g^a)^b \mod p = g^{ab} \mod p = (g^b)^a \mod p\)
  • Fast exponentiation: Used for efficient computation of large powers in cryptographic operations
Computing Large Exponents Efficiently

For cryptographic applications, we need to efficiently compute large exponents. The square-and-multiply algorithm lets us calculate \(x^n\) with only \(O(\log n)\) multiplications:

  1. Convert the exponent to binary representation
  2. Start with result = 1
  3. For each bit in the exponent (from left to right):
    • Square the result
    • If the current bit is 1, multiply by the base

Example: To compute \(3^{13}\), we use binary 13 = 1101:
result = 1
bit 1: result = \( 1^{2} \times 3 = 3 \)
bit 1: result = \( 3^{2} \times 3 = 27 \)
bit 0: result = \( 27^{2} = 729 \)
bit 1: result = \( 729^{2} \times 3 = 1,594,323 \)

You already use modulo computation when you look at a clock and, for example, need to figure out what time it will be 3 hours after 11 o'clock, which is 2 o'clock. In mathematics, we write this as:

\( (11 + 3) \: mod \: 12 = 2 \)

Here, 12 is the modulus because we want the time as an integer between 0 and 11 (in this case, 12 o'clock is denoted by 0). In words, we say "11 plus 3 modulo 12 equals 2." The result of a modulo computation is an integer between 0 and the modulus minus 1. For example, with modulus 3, we have:

  • \( 1 \: mod \: 3 = 1 \)
  • \( 2 \: mod \: 3 = 2 \)
  • \( 3 \: mod \: 3 = 0 \)
  • \( 4 \: mod \: 3 = 1 \)
  • \( 5 \: mod \: 3 = 2 \)
  • \( 6 \: mod \: 3 = 0 \)
  • etc.

For example, if we look at \( 27 \: mod \: 5 \), modulo computes how many times 5 divides into 27 and then returns the remainder, which is 2 in this case. That is, \( 27 \: mod \: 5 = 2 \). But how do we get this result?

First, we compute how many times we can multiply 5 by an integer \( x \) so that the result is as close as possible to 27 without exceeding it. In other words, we find the maximum value of \( x \) such that \( 5 \cdot x \leq 27 \). In this case, \( x = 5 \) because \( 5 \cdot 5 = 25 \leq 27 \). Then, by subtracting 25 from 27, we get the answer: \( 27 - 25 = 2 \).

If the integer is negative, for example \( -27 \: mod \: 5 \), we have to do it slightly differently, and the answer is \( -27 \: mod \: 5 = 3 \). In this case, the integer \( x \) is negative and should be the closest integer such that \( 5 \cdot x \) does not exceed -27. That is, we find the minimum value of \( -x \) such that \( 5 \cdot -x \geq -27 \). Here, \( -x = -6 \) because \( 5 \cdot -6 = -30 \geq -27 \). Then, by subtracting -30 from -27, we get the answer: \( -27 - (-30) = -27 + 30 = 3 \).

It is important that \( x \) or \( -x \) is an integer such as \( -14, 3, 17 \), etc., and NOT a fraction or decimal such as \( \frac{1}{4}, \frac{-3}{7}, 2.5, 5.1 \), etc.

If two integers \( a \) and \( b \) modulo the same modulus \( c \) return the same remainder \( r \), then we say that \( a \) and \( b \) are congruent modulo \( c \). That is, if \( a \: mod \: c = r \) and \( b \: mod \: c = r \), then \( a \equiv b \: (mod \: c) \). Also, notice that if the modulus \( c \) is greater than the integer \( a \), i.e., \( c > a \), the result will always be \( a \: mod \: c = a \).

Properties of Modular Arithmetic

Modular arithmetic has several important properties that make it useful in cryptography:

  • Addition: \((a + b) \: \text{mod} \: n = ((a \: \text{mod} \: n) + (b \: \text{mod} \: n)) \: \text{mod} \: n\)
  • Subtraction: \((a - b) \: \text{mod} \: n = ((a \: \text{mod} \: n) - (b \: \text{mod} \: n)) \: \text{mod} \: n\)
  • Multiplication: \((a \cdot b) \: \text{mod} \: n = ((a \: \text{mod} \: n) \cdot (b \: \text{mod} \: n)) \: \text{mod} \: n\)
  • Exponentiation: \(a^b \: \text{mod} \: n = (a \: \text{mod} \: n)^b \: \text{mod} \: n\)

These properties allow us to perform calculations on smaller values rather than potentially very large ones, which is essential in cryptographic algorithms.

Modular Inverse

A modular inverse of an integer \(a\) with respect to modulus \(n\) is an integer \(a^{-1}\) such that:

\(a \cdot a^{-1} \equiv 1 \: (\text{mod} \: n)\)

The modular inverse exists if and only if \(a\) and \(n\) are coprime (i.e., their greatest common divisor is 1). Finding modular inverses is crucial in cryptography, particularly in algorithms like RSA where we need to find \(d\) such that \(e \cdot d \equiv 1 \: (\text{mod} \: \phi(n))\).

Important Theorems in Modular Arithmetic

Fermat's Little Theorem: If \(p\) is a prime number and \(a\) is not divisible by \(p\), then \(a^{p-1} \equiv 1 \: (\text{mod} \: p)\).

Euler's Theorem: If \(a\) and \(n\) are coprime, then \(a^{\phi(n)} \equiv 1 \: (\text{mod} \: n)\), where \(\phi(n)\) is Euler's totient function.

These theorems are fundamental to understanding and implementing many cryptographic algorithms, especially RSA.

Applications in Cryptography

Modular arithmetic is fundamental to many cryptographic algorithms:

  • RSA: Relies on modular exponentiation for encryption and decryption
  • Diffie-Hellman: Uses modular exponentiation for key exchange
  • ElGamal: Employs modular arithmetic for public-key encryption
  • Digital Signatures: Many signature schemes use modular operations
  • Hash Functions: Often incorporate modular operations in their compression functions

A prime number is an integer greater than 1 that can only be divided evenly by 1 and itself. "Divided evenly" means the result is an integer, not a float. For example, if you divide 13 by 3, you get the float \( \frac{13}{3} = 4.333 \). We see that 13 is a prime number because it can only be divided evenly by 1 and itself: \( \frac{13}{1} = 13 \) and \( \frac{13}{13} = 1 \).

If an integer is not a prime number, it is called a composite number. For example, the integer 6 is a composite number because it can be divided evenly by 1, 2, 3, and 6:

\( \frac{6}{1} = 6 \), \( \frac{6}{2} = 3 \), \( \frac{6}{3} = 2 \), and \( \frac{6}{6} = 1 \)

The term "composite" means "something made by combining things." So, a composite number is an integer made by multiplying prime numbers:

  • 2 is a prime
  • 3 is a prime
  • 4 is composite: \( 2 \cdot 2 = 4 \)
  • 5 is a prime
  • 6 is composite: \( 2 \cdot 3 = 6 \)
  • 7 is a prime
  • 8 is composite: \( 2 \cdot 2 \cdot 2 = 8 \)
  • 9 is composite: \( 3 \cdot 3 = 9 \)
  • etc.

Therefore, every integer greater than 1 is either a prime number or a product of prime numbers (a composite number).

The famous Greek mathematician Euclid proved that there are infinitely many prime numbers.

Michael Rabin and Gary Miller developed an algorithm that determines whether an integer is a prime or a composite number by testing the integer with multiple bases, denoted by \( a \). The algorithm is called the Rabin-Miller primality test.

The Fundamental Theorem of Arithmetic

Every integer greater than 1 can be expressed as a unique product of prime numbers (up to the order of the factors). This fundamental property makes prime numbers the "building blocks" of all natural numbers and is crucial for many cryptographic applications.

Importance in Cryptography

Prime numbers form the foundation of many cryptographic systems:

  • RSA encryption relies on the difficulty of factoring the product of two very large primes
  • Diffie-Hellman key exchange uses prime numbers to create secure shared secrets
  • Elliptic curve cryptography often works over finite fields of prime order
  • Digital signature algorithms like DSA and ECDSA use primes in their mathematical operations
Primality Testing

Determining whether a number is prime is crucial in cryptography. Several methods exist:

  • Trial division: Dividing by all integers up to the square root (inefficient for large numbers)
  • Fermat primality test: Based on Fermat's Little Theorem, but can be fooled by Carmichael numbers
  • Miller-Rabin test: A probabilistic algorithm that can determine primality with high confidence
  • AKS primality test: The first deterministic polynomial-time algorithm for primality testing

The Miller-Rabin test is particularly useful because it's efficient and can achieve any desired level of certainty by increasing the number of test rounds.

Special Types of Primes in Cryptography
  • Safe primes: Primes p where (p-1)/2 is also prime. Used in Diffie-Hellman key exchange.
  • Strong primes: Primes with certain properties that make them resistant to specific factoring algorithms, often used in RSA.
  • Sophie Germain primes: Primes p where 2p+1 is also prime, useful for cryptographic applications.
  • Mersenne primes: Primes of the form 2n-1, which allow for efficient arithmetic operations.
Definition

The greatest common divisor (GCD) of two or more integers is the largest positive integer that divides each of the given integers without a remainder. It is denoted as \(\gcd(a, b)\) or sometimes as \((a, b)\).

Formally, for two integers \(a\) and \(b\), not both zero, \(\gcd(a,b)\) is the largest positive integer \(d\) such that \(d|a\) and \(d|b\) (where \(d|a\) means "\(d\) divides \(a\)" or "\(a\) is divisible by \(d\)").

Before we describe what the greatest common divisor of two integers is, we first define what we mean by a divisor. In this context, a divisor of an integer \( x \) is any integer that divides \( x \) evenly, meaning the result is not a fraction. For example, if you divide \( x=12 \) by 5, you get the fraction \( \frac{12}{5} = 2.4 \), so 5 is not a divisor of \( x=12 \). For \( x=12 \), the divisors are 1, 2, 3, 4, 6, and 12 because \( \frac{12}{1} = 12 \), \( \frac{12}{2} = 6 \), \( \frac{12}{3} = 4 \), \( \frac{12}{4} = 3 \), \( \frac{12}{6} = 2 \), and \( \frac{12}{12} = 1 \).

Similarly, the divisors of 16 are 1, 2, 4, 8, and 16 because \( \frac{16}{1} = 16 \), \( \frac{16}{2} = 8 \), \( \frac{16}{4} = 4 \), \( \frac{16}{8} = 2 \), and \( \frac{16}{16}=1 \).

The greatest common divisor of 12 and 16 is therefore 4, because it is the largest integer among their common divisors. In mathematics, we write this as \( \gcd(12, 16) = 4 \).

Two integers whose greatest common divisor is 1 are called relatively prime numbers or co-primes. For example, 15 and 28 are relatively prime because \( \gcd(15, 28) = 1 \) (note that 28 is not a prime number).

If one of the two integers is a prime number, the greatest common divisor will always be 1, i.e., \( \gcd(a, p) = 1 \), where \( a \) is any integer (either prime or composite) and \( p \) is a prime number.

Key Properties
  • \(\gcd(a,b) = \gcd(b,a)\) (Commutativity)
  • \(\gcd(a,b) = \gcd(a-b,b)\) when \(a \geq b\) (Subtraction property)
  • \(\gcd(a,b) = \gcd(a \bmod b, b)\) when \(b \neq 0\) (Basis of the Euclidean algorithm)
  • \(\gcd(a,0) = |a|\) for any \(a\) (Base case)
  • If \(p\) is prime and \(p\) doesn't divide \(a\), then \(\gcd(a,p) = 1\)

One method to compute the greatest common divisor of two integers is by using the Euclidean algorithm, developed by the famous Greek mathematician Euclid. See "The extended Euclidean algorithm" for more information about how to compute the greatest common divisor of two integers.

The Euclidean Algorithm

The Euclidean algorithm is an efficient method to find the GCD of two integers. It works by repeatedly applying the division algorithm:

  1. Start with two positive integers \(a\) and \(b\), where \(a \geq b\)
  2. Divide \(a\) by \(b\) to get quotient \(q\) and remainder \(r\) such that \(a = bq + r\) where \(0 \leq r < b\)
  3. If \(r = 0\), then \(\gcd(a,b) = b\)
  4. Otherwise, set \(a = b\) and \(b = r\), and repeat from step 2

Example: Find \(\gcd(48, 18)\)

  • \(48 = 18 \cdot 2 + 12\)
  • \(18 = 12 \cdot 1 + 6\)
  • \(12 = 6 \cdot 2 + 0\)

Since the remainder is now 0, \(\gcd(48, 18) = 6\).

Applications in Cryptography

The GCD has several important applications in cryptography:

  • Key Generation: In RSA, we need to find two numbers \(e\) and \(d\) such that \(ed \equiv 1 \pmod{\phi(n)}\), which requires \(\gcd(e, \phi(n)) = 1\)
  • Primality Testing: Many primality tests use GCD calculations
  • Modular Arithmetic: Finding modular inverses (via the extended Euclidean algorithm) requires co-prime numbers
  • Factorization Attacks: Some attacks on cryptosystems use GCD calculations to factor large numbers
Definition and Purpose

The extended Euclidean algorithm is an extension of the Euclidean algorithm, which only returns the greatest common divisor of two integers. Given two integers \( a \) and \( b \), the extended Euclidean algorithm returns the integers \( a \), \( b \), \( \lambda \), and \( \mu \) such that:

\( a \cdot \lambda + b \cdot \mu = \gcd(a, b) \)

Here, \( \lambda \) and \( \mu \) are called the Bézout coefficients for \( a \) and \( b \). Only if \( a \) and \( b \) are relatively prime, i.e., \( \gcd(a, b) = 1 \), then:

\( a \cdot \lambda + b \cdot \mu = 1 \)

In this case, \( \lambda \; mod \; b \) is the inverse of \( a \), denoted \( a^{-1} = \lambda \; mod \; b \), and \( \mu \: mod \: a \) is the inverse of \( b \), denoted \( b^{-1} = \mu \: mod \: a \) (see "Modulo computation" for more information about the \( mod \) operator). One useful property of an integer and its inverse is that \( a \cdot a^{-1} \; mod \; b = 1 \) and \( b \cdot b^{-1} \; mod \; a = 1 \).

Example

You can easily compute \( \gcd(a, b) \), \( \lambda \), and \( \mu \) for example with \( a=5 \) and \( b=39 \) using a simple table. First, let us create a table with three columns (we do not yet know how many rows there will be). Let us denote the entry in the first row and first column as [1,1], the entry in the first row and second column as [1,2], the entry in the second row and first column as [2,1], and so on.

Next, we write \( b=39 \) in entry [1,1] and \( a=5 \) in entry [2,1]. Then we try to find the largest integer \( q_{1} \) such that \( q_{1} \cdot a \leq b \). We have \( q_{1}=7 \), which we write in entry [2,2], because \( 7 \cdot 5 = 35 \leq 39 \), and a remainder of \( r_{1}=4 \), which we write in entry [3,1].

Again, we try to find the largest integer \( q_{2} \) such that \( q_{2} \cdot r_{1} \leq a \). We have \( q_{2}=1 \), which we write in entry [3,2], because \( 1 \cdot 4 = 4 \leq 5 \), and a remainder of \( r_{2}=1 \), which we write in entry [4,1]. Notice that we are repeating the same process as before, just with the numbers in the next row.

The next computation returns a remainder of \( r_{3} = 0 \) because \( q_{3} \cdot r_{2} = 4 \cdot 1 = 4 \leq 4 = r_{1} \). We have now computed \( \gcd(5, 39)=r_{2}=1 \) since \( r_{3} = 0 \). Because 5 and 39 are relatively prime, we know that \( \lambda \) and \( \mu \) exist, and we can start using the last column.

First, we write \( x_{1}=0 \) in entry [4,3] and \( x_{2}=1 \) in entry [3,3]. Then we write \( x_{3}=q_{2} \cdot x_{2} + x_{1} = 1 \cdot 1 + 0 = 1 \) in entry [2,3]. For entry [1,3], we compute as before, just with numbers from the row above, i.e., \( x_{4}=q_{1} \cdot x_{3} + x_{2} = 7 \cdot 1 + 1 = 8 \).

Finally, we have that \( a \cdot x_{4} \pm b \cdot x_{3} = r_{2} \), where we need to decide whether it should be plus or minus between the two terms. Because \( a \cdot x_{4} = 5 \cdot 8 = 40 \), \( b \cdot x_{3} = 39 \cdot 1 \), and \( 40 \geq 39 \), we have \( 5 \cdot 8 - 39 \cdot 1 = 1 \) (which is the same as \( 5 \cdot 8 + 39 \cdot (-1) = 1 \)), so the Bézout coefficients are \( \lambda=8 \) and \( \mu=-1 \). Notice that \( a^{-1} = \lambda \; mod \; b = 8 \; mod \; 39 = 8\) and \( b^{-1} = \mu \; mod \; a = -1 \: mod \: 5 = 4\), where \( a \cdot a^{-1} \; mod \; b = 5 \cdot 8 \; mod \; 39 = 1 \) and \( b \cdot b^{-1} \; mod \; a = 39 \cdot 4 \; mod \; 5 = 1 \).

Table for the example

The table for computing \( 5 \cdot \lambda + 39 \cdot \mu = \gcd(5, 39) \) is:

\( b=39 \) \( x_{4}=8 \)
\( a=5 \) \( q_{1}=7 \) \( x_{3}=1 \)
\( r_{1}=4 \) \( q_{2}=1 \) \( x_{2}=1 \)
\( r_{2}=1 \) \( q_{3}=4 \) \( x_{1}=0 \)
\( r_{3}=0 \)
Algorithm in Pseudocode
function extended_gcd(a, b)
    if b = 0 then
        return (a, 1, 0)
    else
        (d, x', y') = extended_gcd(b, a mod b)
        return (d, y', x' - (a div b) * y')

The function returns a tuple (d, x, y) such that d = gcd(a, b) and d = ax + by.

Applications in Cryptography
  • RSA Key Generation: Computing the private key d where d ≡ e-1 (mod φ(n)) requires finding the modular inverse of the public exponent e
  • Chinese Remainder Theorem: Finding solutions to systems of modular congruences, which enables efficient RSA implementations
  • Elliptic Curve Cryptography: Computing point addition and scalar multiplication operations
  • Digital Signatures: Many schemes require modular inverse calculations
  • Key Exchange Protocols: Used in various secure communication protocols
Relation to the Basic Euclidean Algorithm

While the standard Euclidean algorithm computes only the GCD through successive divisions, the extended version keeps track of the coefficients at each step. This "extension" allows us to express the GCD as a linear combination of the original numbers, which is crucial for finding modular inverses.

Computational Complexity

The extended Euclidean algorithm has the same time complexity as the standard Euclidean algorithm: O(log min(a,b)). This makes it highly efficient even for very large integers, which is crucial for its application in cryptographic systems.

Definition

The knapsack problem is a combinatorial optimization problem where, given a set of items with specific weights and values, we need to determine which items to include in a collection (the "knapsack") such that the total weight doesn't exceed a given limit and the total value is maximized.

Formally, given n items, each with a weight \(w_i\) and a value \(v_i\), along with a maximum weight capacity \(W\), the goal is to select items to maximize the total value while keeping the total weight \(\leq W\).

Variants
  • 0-1 Knapsack Problem: Each item can either be included or excluded (cannot be taken partially)
  • Bounded Knapsack Problem: Each item can be taken a limited number of times
  • Unbounded Knapsack Problem: Each item can be taken any number of times
  • Subset Sum Problem: A special case where the value of each item equals its weight, and we need to find a subset that sums exactly to the target value
Computational Complexity

The general knapsack problem is NP-complete, making it computationally difficult to solve for large inputs. However, special cases (such as when weights are sorted or when they follow certain patterns) can be solved efficiently.

Security Considerations

While the knapsack problem is generally hard, the Merkle-Hellman cryptosystem was broken by Shamir in 1984 using lattice reduction techniques. This demonstrated that transforming a hard problem into a cryptosystem doesn't necessarily preserve the problem's difficulty. Despite this, the knapsack problem's study has contributed significantly to our understanding of computational complexity in cryptography.

Connection to Modern Lattice-Based Cryptography

The Merkle-Hellman knapsack cryptosystem is historically significant as a precursor to modern lattice-based cryptography:

  • Shamir's attack on Merkle-Hellman used the LLL algorithm (Lenstra-Lenstra-Lovász), a lattice basis reduction technique that finds short vectors in lattices
  • The vulnerability highlighted that knapsack problems can be reformulated as finding short vectors in certain lattices
  • This connection between knapsack problems and lattices paved the way for modern lattice-based cryptography

While Merkle-Hellman was broken, the research sparked innovation in lattice-based cryptography, which now offers:

  • Quantum resistance: Unlike RSA and ECC, lattice-based systems are believed to resist attacks from quantum computers
  • Homomorphic encryption: The ability to perform computations on encrypted data
  • NIST candidates: Several lattice-based algorithms are finalists in NIST's post-quantum cryptography standardization process

Contemporary lattice-based cryptosystems rely on problems such as:

  • Learning With Errors (LWE): Finding a secret vector given noisy linear equations
  • Ring-LWE: A more efficient variant that operates in polynomial rings
  • Shortest Vector Problem (SVP): Finding the shortest non-zero vector in a lattice

The evolution from Merkle-Hellman to modern lattice-based cryptosystems demonstrates how even broken cryptographic constructions can lead to important advances in the field.

The cryptography explained

Lattice-based cryptography represents one of the most promising approaches to creating cryptosystems that remain secure in the post-quantum computing era. While traditional cryptographic systems like RSA and ECC (Elliptic Curve Cryptography) are vulnerable to quantum computer attacks using Shor's algorithm, lattice-based systems are believed to be resistant to both classical and quantum attacks.

A lattice is a mathematical structure consisting of points in n-dimensional space with a periodic structure. Formally, a lattice \( L \) can be defined as all integer linear combinations of a set of linearly independent vectors \( \{b_1, b_2, \ldots, b_n\} \) called a basis:

\( L = \left\{ \sum_{i=1}^{n} z_i b_i : z_i \in \mathbb{Z} \right\} \)

The security of lattice-based cryptography relies on two computationally hard problems:

  1. Shortest Vector Problem (SVP): Given a lattice basis, find the shortest non-zero vector in the lattice.
  2. Closest Vector Problem (CVP): Given a lattice basis and a target point in space, find the lattice point closest to the target.

These problems become exponentially harder as the dimension of the lattice increases, and no efficient quantum algorithm is currently known to solve them. This quantum-resistance is what makes lattice-based cryptography particularly valuable for future-proofing secure communications.

The National Institute of Standards and Technology (NIST) has been conducting a post-quantum cryptography standardization process since 2016, and several lattice-based algorithms have advanced to the final rounds, including CRYSTALS-Kyber for key encapsulation and CRYSTALS-Dilithium for digital signatures.

Lattice-based systems offer several advantages beyond quantum resistance:

  • They can support advanced cryptographic functionalities like fully homomorphic encryption, which allows computations on encrypted data
  • Many lattice-based constructions have provable security reductions to worst-case lattice problems
  • They often have relatively efficient implementations compared to other post-quantum approaches

The Merkle-Hellman knapsack cryptosystem, which we'll explore in detail below, was one of the earliest attempts at a public-key system based on the knapsack problem, which is related to lattice problems.

The Merkle-Hellman encryption explained

The Merkle-Hellman knapsack cryptosystem, proposed by Ralph Merkle and Martin Hellman in 1978, was one of the first attempts at creating a public-key encryption system. It is based on the knapsack problem, a variant of the subset sum problem: given a set of numbers and a sum, find a subset of those numbers that add up to that sum.

While the general knapsack problem is NP-complete (computationally difficult), certain special instances can be solved efficiently. The Merkle-Hellman system cleverly uses a superincreasing sequence (a sequence where each element is greater than the sum of all previous elements) to create an easily solvable private key, which is then transformed into a seemingly hard instance for the public key.

The system works as follows: Alice generates a private key consisting of a superincreasing sequence and then transforms it into a public key that appears to be a random knapsack instance. Bob uses this public key to encrypt messages bit by bit, while Alice can decrypt efficiently using her knowledge of the private key.

Unfortunately, the original Merkle-Hellman system was broken by Shamir in 1984 using lattice reduction techniques. This highlights an important aspect of lattice-based cryptography: while lattice problems are generally hard, specific instances with special structure can sometimes be vulnerable. Despite this, the Merkle-Hellman system remains historically significant as one of the earliest public-key systems not based on number-theoretic assumptions.

Modern lattice-based cryptosystems use more sophisticated approaches and stronger security assumptions to avoid the vulnerabilities that affected Merkle-Hellman.

The protocol
Key Generation
Alice:
  1. Generates a superincreasing sequence \( w = (w_1, w_2, ..., w_n) \) where each \( w_i > \sum_{j=1}^{i-1} w_j \)
  2. Chooses a large modulus \( m > \sum_{i=1}^{n} w_i \) and a multiplier \( r \) where \( \gcd(r, m) = 1 \)
  3. Computes \( b_i = r \cdot w_i \mod m \) for each element in the sequence
  4. The public key is the sequence \( b = (b_1, b_2, ..., b_n) \)
  5. The private key is \( (w, m, r) \)
Alice sends the public key \( b = (b_1, b_2, ..., b_n) \) to Bob.
Encryption
Bob
  1. Converts plaintext message to binary: \( x = (x_1, x_2, ..., x_n) \) where each \( x_i \) is 0 or 1
  2. Computes ciphertext \( c = \sum_{i=1}^{n} x_i \cdot b_i \)
  3. Sends ciphertext \( c \) to Alice
Decryption
Alice
  1. Computes \( c' = c \cdot r^{-1} \mod m \), where \( r^{-1} \) is the modular inverse of \( r \)
  2. Solves the easy superincreasing knapsack problem to recover \( x \) from \( c' \)
  3. The binary sequence \( x \) is the plaintext message

Try a demo of the encryption scheme here.

Example

Let's walk through a complete example of the Merkle-Hellman knapsack cryptosystem:

Key Generation:

Alice generates a superincreasing sequence \( w = (2, 3, 7, 14, 30, 57, 120, 251) \). We can verify this is superincreasing because each element is greater than the sum of all previous elements.

She chooses modulus \( m = 491 \) (which is larger than the sum of all elements in \( w \), which is 484) and multiplier \( r = 41 \) (which is coprime with 491).

She computes the public key \( b \) as follows:
\( b_1 = 41 \cdot 2 \mod 491 = 82 \)
\( b_2 = 41 \cdot 3 \mod 491 = 123 \)
\( b_3 = 41 \cdot 7 \mod 491 = 287 \)
\( b_4 = 41 \cdot 14 \mod 491 = 83 \)
\( b_5 = 41 \cdot 30 \mod 491 = 239 \)
\( b_6 = 41 \cdot 57 \mod 491 = 352 \)
\( b_7 = 41 \cdot 120 \mod 491 = 410 \)
\( b_8 = 41 \cdot 251 \mod 491 = 127 \)

So the public key is \( b = (82, 123, 287, 83, 239, 352, 410, 127) \).

Encryption:

Bob wants to encrypt the message "Hi" which in ASCII is 72 and 105, or in binary: 01001000 01101001.

Taking the first 8 bits (01001000), Bob computes:
\( c_1 = 0 \cdot 82 + 1 \cdot 123 + 0 \cdot 287 + 0 \cdot 83 + 1 \cdot 239 + 0 \cdot 352 + 0 \cdot 410 + 0 \cdot 127 = 362 \)

For the second 8 bits (01101001), Bob computes:
\( c_2 = 0 \cdot 82 + 1 \cdot 123 + 1 \cdot 287 + 0 \cdot 83 + 1 \cdot 239 + 0 \cdot 352 + 0 \cdot 410 + 1 \cdot 127 = 776 \)

Bob sends the ciphertext \( (362, 776) \) to Alice.

Decryption:

Alice first computes the modular inverse of 41 modulo 491, which is 12 (since \( 41 \cdot 12 \mod 491 = 1 \)).

For the first block:
\( c_1' = 362 \cdot 12 \mod 491 = 244 \)

Now Alice solves the superincreasing knapsack problem with the sum 244:
251 > 244, so \( x_8 = 0 \)
120 > 244, so \( x_7 = 0 \)
120 + 57 = 177 < 244, so \( x_6 = 1 \) and remaining sum = 244 - 57 = 187
120 + 30 = 150 < 187, so \( x_5 = 1 \) and remaining sum = 187 - 30 = 157
120 + 14 = 134 < 157, so \( x_4 = 0 \)
120 + 7 = 127 < 157, so \( x_3 = 0 \)
120 + 3 = 123 < 157, so \( x_2 = 1 \) and remaining sum = 157 - 3 = 154
120 + 2 = 122 < 154, so \( x_1 = 0 \)

So the first byte is 01001000.

Alice repeats this process for the second block \( c_2 \) to get 01101001.

Converting from binary to ASCII, Alice recovers "Hi".

Note: This example uses small numbers for clarity. In practice, much larger values would be used to ensure security, though as mentioned earlier, even with large numbers the original Merkle-Hellman system has been broken.