Discrete Logarithm Algorithms

But before we dive into this topic, let me first explain what a logarithm is (because I know some of you might be struggling with math).

A logarithm is essentially the opposite of an exponentiation. For example, if we have the number 1024 and want to find its base-8 logarithm, which would give us the power that 8 needs to be raised to in order to get 1024 (which is 10 times 10 times 10), we can use a calculator or do some math:

log_8(1024) = 10 (because 8^10 = 1024)

Now, discrete logarithms. In cryptography, we often want to hide information by encrypting it using a key that is difficult for anyone except the intended recipient to obtain. One way to do this is through public-key encryption, which uses two keys one for encryption (the public key) and another for decryption (the private key).

The problem with traditional symmetric-key encryption methods like AES or Blowfish is that they require both the sender and receiver to have a shared secret key. This means that if an attacker intercepts the communication, they can read all of the messages being sent. Public-key encryption solves this problem by allowing each user to generate their own public and private keys, which are mathematically related but cannot be easily derived from one another.

The most commonly used public-key cryptosystem is RSA (RivestShamirAdleman), which uses the difficulty of computing discrete logarithms as its basis for security. In RSA, each user generates a pair of keys a public key and a private key. The public key consists of two large prime numbers p and q, and an integer e that is relatively prime to (p-1)*(q-1).

To encrypt a message using the recipient’s public key, we first convert it into a number between 0 and n-1, where n = p*q. We then raise this number to the power of e modulo n:

c = m^e mod n

The resulting c is the encrypted message that can only be decrypted using the recipient’s private key (which consists of two numbers d and x such that ed = 1 mod (p-1)*(q-1) and xed = 1 mod p*q). To decrypt, we raise the encrypted message to the power of d:

m = c^d mod n

The security of RSA relies on the fact that it is difficult to compute discrete logarithms in large prime fields. Specifically, given a number x and another number y (which are both relatively prime), finding an integer k such that x^k = y mod n is known as computing the discrete logarithm of y with respect to x modulo n.

For example, let’s say we have two large prime numbers p=17 and q=23, and a public key (e,n) where e=5 and n=p*q=381. To encrypt the message “hello” using this public key, we first convert it into an integer between 0 and 380:

m = ord(‘h’) + ord(‘e’) * 256 + … + ord(‘o’) * (256^7) mod 381

We then raise m to the power of e using a calculator or some math:

c = m^e mod n

The resulting c is the encrypted message that can only be decrypted by someone who knows the private key. To do this, we first find an integer k such that ed = 1 mod (p-1)*(q-1), which in our case would give us:

k = 275 (because 5*275 = 1 mod (16*22))

We then raise the encrypted message to the power of k using a calculator or some math:

m = c^d mod n

The resulting m is the original message “hello”. Of course, finding an integer k that satisfies ed = 1 mod (p-1)*(q-1) can be difficult for large prime fields. In fact, it’s believed to be computationally infeasible using current technology which is why RSA and other public-key cryptosystems are so secure!

I hope this explanation was helpful, but if not, feel free to ask any questions or leave comments below. And as always, remember that math is hard…but also fun!

SICORPS