Public Key Cryptography Etc. Probabilistic primality testing (1) Recall Fermat's little theorem: If n is prime, then x^n = x mod n, (or equivalently, if x is not a multiple of n, x^(n-1) = 1 mod n.) The converse is not necessarily true, i.e. if n is not prime, then x^(n-1) might still be 1 mod n. In practice, however, it is very unusual that x^(n-1) = 1 mod n for n not prime. So if we find that x(n-1) = 1 mod n for several x randomly selected between 1 and n, then we have good heuristic evidence that n is a prime. In fact, because we have an efficient algorithm for exponentiation mod n, this is a effective way of "probabilistically" finding large primes and could actually be used. The fly in this particular ointment is the existence of so-called "Carmichael Numbers", which are composites m such that x(m-1) = 1 mod m for every x (relatively prime to m). There are infinitely many of these, but they are fairly rare and their proportion relative to actual primes decreases as numbers become large. 2163 < 10^9 -> 2163/(10^9 / ln(10^9)) =~ 45 per million real primes < 10^9 8241 < 10^12 -> about .23 per million real primes < 10^12 105,212 < 10^15 -> about 3.6 per billion real primes < 10^12. In fact, it has been shown (quite recently) that the number of Carmichael numbers less than x is bounded by C * x^(2/7), while we know that the number of primes less than x is approximately x / ln(x). So if we are looking for primes with on the order of 100 digits, it seems as though the probability of accidentally landing on a Carmichael number is effectively 0. However, there are slightly more sophisticated probabilistic tests for primality (Solovay-Strassen, Miller-Rabin) for which there is no analogue of Carmichael numbers, and which thus allow the probability of falsely reporting a prime to be made arbitrarily small, so, in fact, these are used in practice. Technically, what we have is a Monte Carlo test for compositeness. An answer of "composite" is always correct as the x for which x^(n-1) != 1 mod n is a "witness" for compositeness. An answer of "prime" however, may (very) occasionally be wrong. ------------------------------------------------------------------------ Diffie Hellman key exchange One of the biggest bugaboos for classical cryptography is the problem of key distribution. Communicators have to share a secret (the key) and the act of exchanging this secret presents a vulnerability no matter how secure the cryptosystem is otherwise. (witness the role of stolen codebooks in the British effort against the Enigma) Problem is particularly acute if encrypted communication needs to be used regularly among a large number of users. * Need lots of different keys. * Need to change them regularly just in case they get compromised. * Too many people to meet each other personally with required regularity. * Centralized distribution system is a dreadful vulnerability. Amazingly, it is possible for two (or more) parties to establish a shared secret by public communication (!!) Probably the most surprising and far-reaching cryptographic result of the 20th century, and perhaps of the last 2000 years. In fact, there are several ways of accomplishing this. Diffie-Hellman was the first, and perhaps the easiest to understand. Basic ability gives rise to a whole slew of other mechanisms such as digital signatures, identity verification, certification, etc. *** Techniques depend on the existence of computational machinery. The required computation is modest by electronic computer standards, but too large to be practical with pencil and paper. Diffie-Hellman developed in mid 1970s by Winfield Diffie, Martin Hellman, and Ralph Merkle. (And possibly independently at British GCHQ). Standard cast of characters: * Alice and Bob - primary communicators. * Eve - the evil eavesdropper. Double lock-box analogy: Alice wants to send Bob something secret, but the postal service is all corrupt spies. If she sends it in a locked box, the PS holds it (forges an acknowledgement) and waits for the key to be sent. One clever idea: Alice put the secret in a box, puts a lock on the box, sends it to Bob, and keeps the key. Bob puts another lock on the box, keeps the key, and sends it back to Alice. Alice unlocks her lock, and sends the still locked box back to Bob. Bob unlocks it and retrieves the secret. * Depends on strong locks * Depends on commutivity of locking operation Diffie-Hellman is not quite a direct analogue of this, but there are some common elements. * Strong locks: Public key cryptosystems typically utilize some sort of a "trapdoor" function somewhere in their workings. This is a function that is easy to compute, but hard to invert (at least as far as anyone knows). Well known examples of (supposed) hard inverses are Factoring: it is easy to find two large primes and compute their product, but hard to start with the product and recover the large primes Discrete log: it is easy to compute q = b^n mod p given b, n and p, but it is difficult to recover n given q, x and p. Security of Diffie-Hellman relies on the difficulty of the discrete log problem. * Commutivity: Most cryptographic methods are not commutative - If you encrypt a message with k1 and then k2, the result is not the same as encrypting with k2 and then k1. More specifically, we must usually decrypt with k2 before decrypting with k1. This makes most symmetric encryption unsuitable for the "double lock" in the above example. Diffie-Hellman exploits the commutativity of exponentiation (b^x)^y = b^(xy) = (b^y)^x. With that setup, here is the technique: This is our first example of what is termed a "Cryptographic Protocol" - a sequence of specified actions by two or more parties to achieve a desired (cryptographic) end. 1. Alice and Bob agree (in public) on a large prime p, and a primitive root g of that prime. (actually g does not have to be a primitive root, it just has to generate a large enough subgroup under exponentiation to make finding a discrete log difficult) 2. Alice chooses a large random integer x < p, and computes X = g^x % p, which she sends to Bob. 3. Bob chooses a large random integer y < p, computes Y = g^y % p, which he sends to Alice. 4. Alice computes k = Y^x % p = (g^y)^x mod p 5. Bob computes k' = X^y % p = (g^x)^y mod p Because of the commutivity of exponentiation, Alice and Bob have computed the same key (!) even though neither knows the other's choice of random number. They can use this directly or indirectly for encrypting communication. * Note that Eve cannot (directly) figure out k without x or y, and she has neither, unless she can compute discrete logarithms. (It is not immediately obvious that there is no indirect way of obtaining k from X, Y, g and p) * Note also that this result is not directly useful for encryption, since Bob does not recover Alice's original x. * Protocol can be easily extended to 3 or more people. Each party picks a random integer, and we use n paths all passing through all the users, and each ending on a different user (easiest model, imagine a circle of links). Each user adds their integer (via exponentiation mod p) to values as they pass through. * Protocol is vulnerable to "man in the middle" attack. Here the evil Mallory negotiates with both sides while they think they are negotiating with each other. This results in Mallory having (separate) keys in common with both Bob and Alice. Mallory then intercepts, decrypts, (and possibly re-encrypts and resends if he wants to remain undetected) any messages sent from Alice to Bob or vice versa. * Patent by PKP (Public Key Partners) expired in 1997 --------------------------------------------------------------------------- The RSA Cipher Whitfield Diffie, idea of a public key system, ~1975: Encryption and decryption keys could be separate and not (practically) determinable from each other. * Public encryption, private decryption keys. * Alice sends Bob an encrypted message by getting Bob's public key, either from Bob, or by looking it up in a public database (latter discourages man-in-the-middle attacks) Encrypts message, sends to Bob, Bob decrypts with private key (which no-one else has presumably) * If Bob wants to send a message back, he looks up Alice's encryption key. * World of n users needs only n keys for secure communication, rather than n^2. Not initially apparent that implementations of the idea existed. * What is needed is a particular sort of one-way function - one that is invertible with some special information. * Large effort for a couple of years after idea was published to find examples of such a function. * Unsuccessful until 1977 when Ronald Rivest, Adi Shamir, Leonard Adleman at IBM developed what would become known as the RSA algorithm. Basic Idea * Hard "trapdoor" problem at the heart of the method is difficulty of factoring large (order of 200 decimal digit) integers. * Specifically the difficulty of factoring integers of the form n = pq where p and q are large primes, compared to the relative ease of finding and multiplying large primes. * Setup 1. Pick two large primes, p and q of(say) 100 decimal digits. and compute n = p * q. One reference (Garret) says p and q must be == 3 mod 4. Also, for "real" security, you might want p and q to be "strong primes", i.e. p-1 and q-1 have a large prime factor... 2. Pick an "encryption exponent" e. Usually e is a relatively small number. Often e is chosen to be 3, or 2^16 + 1 = 65537 (both primes with binary representations that are convenient for exponentiation). e, p and q must be such that (p-1) and (q-1) are relatively prime to e. so occasionally some adjustment is needed. 3. Compute the "decryption exponent" d = e^-1 mod (p-1)(q-1) d should be relatively large (i.e. on the order of the size of n). This will almost always be the case. If by some bizarre chance d is small enough that it could be found by exhaustive search, you might want to pick another p, q, or e. 4. Publish e and n as the public encryption key. d (and p and q) must be kept secret. * Use 1. To send a message to Bob, Alice converts the message into one or more large integers x < n, and computes for each x E(x) = y = x^e mod n for each x 2. To decrypt a message, Bob computes, for each y D(y) = y^d mod n which turns out to be the original x. Why it works * The core bit of number theory is a result known as "Euler's Theorem" which is a generalization of Fermat's little theorem. The theorem makes use of the "Euler Phi function" Phi(x) which is defined as the number of integers 0 < n <= x that are relatively prime to x. It is relatively easy to show that for primes, Phi(p) = p-1, and for composites of the form p*q where p and q are prime, Phi(p*q) = (p-1)(q-1). Euler's theorem states that for all x, and for all n relatively prime to x, x^(Phi(n) == 1 mod n. Note that if n is prime, we get a version of Fermat's little theorem. * Now, with the above setup, we have D(E(x)) = (x^e)^d mod n = x^(e * d) mod n = x^(1 + k*(p-1)(q-1) mod n = x * (x^Phi(n))^k mod n = x .: by Euler's Theorem, (unless x divides n which hardly ever happens) And it turns out that another proof goes through if x divides n. Computation * Finding Primes: To find an n-digit prime generally requires a handful (e.g. 20) of exponentiations mod m involving numbers on the order of n digits. The fast exponentiation algorithm is O(n^3) bit/fixed precision operations. If we count "digits" and do operations in fixed-length chunks that map onto the architecture of the machine, then the constant involves one fixed point multiplication, and a handful of shifts and adds. The modulus operation is more expensive, but happens only about once every n^2 primitive steps, so it is well amortized. Consider computing a 1024 bit prime on a machine with a 32 bit hardware multiply. We can break the number into 64 16 bit chunks. An exponentiation then takes C * 64^3 = C * 256K cycles. With pipelined architectures and all, we can probably arrange for the constant to be 10 or fewer machine cycles, so the exponentiation can be carried out in a few million machine cycles, or a few milliseconds on a 1-2 GHz processor. Multiplying this by 20 or so, we get about 50 ms, or 1/20 of a second. * Encrypting/Decrypting: If we pick a small encryption exponent, then the decryption operation is the more time-consuming of the two, and involves an n-digit exponentiation per data chunk. If we are using 1024 bit primes, then the modulus and data chunks are a few bits under 2048 bits. The exponentiation takes 8 times the time computed for the 1024 bit example above, call it 20 million machine cycles, or roughly 20 milliseconds. Dividing by the chunk length, we have about 10,000 machine cycles, or 10 microseconds per bit. Or approximately 100,000 bits/sec =~ 10,000 bytes/sec in software. Your mileage may vary * This is a lot more expensive than DES. 1000 times slower than DES in hardware, and about 100 times slower than DES in software. The lack of speedup in hardware is due to heavy use of multiplication, which tends to be relatively accessible from software, as compared to, say, bit permutations. * The slowdown is significant enough, that protocols often use RSA only for securely transmitting a DES or other symmetric cipher key, which is then used for the bulk of the transmission. Security. * RSA can be attacked by attempting to factor the modulus, which would allow the decryption key to be recovered using the Euclidean algorithm (the same way it was created originally) * Revealing the product (p-1)(q-1) (in addition to n = pq) permits recover of p and q by direct solution of a quadratic equation. * If n, e, and d are known, then there is a Las Vegas algorithm that will efficiently find p and q. Also, if the same message is encrypted using different e, but the same modulus, the plaintext can be recovered by a direct computation employing the Euclidean algorithm. Moral: Don't reuse a modulus with different d and e for different users. If one is compromised, they all are compromised. * If e is small, and e identical or e(e+1)/2 linearly dependent messages are encrypted using the same e (but different moduli) there is an attack that recovers the messages. Since some systems use e = 3, or e = 17, this could conceivably happen. The solution is to pad messages with some random bits before encrypting. * If d is smaller that n/4, there is an attack that recovers it. This is very unlikely to occur except by design, and cannot happen if e is small. However it is worth knowing about, in case someone gives you a system that seems to be generating small values of d... * There are various sneaky attacks against protocols using RSA that can be employed to recover encrypted messages. For example, there is a digital signature protocol where a user's private key is used to "sign" a document in a way that is verifiable by decrypting with the public key. Eve can use this to trick Alice into decrypting her own message as follows. 1. Eve intercepts the message c = m^e % n. Eve wants m = c^d % n, but doesn't know d. 2. Eve picks a random number r, which will be used as a "disguise" and computes t = r^-1 mod n, a disguise removal inverse. 3. Eve computes x = r^e % n using Alice's public key. 4. Eve computes y = x*c % n, "disguising" Alice's encrypted message 5. Eve get Alice to sign y, thereby obtaining u = y^d % n 6. Eve computes t*u % n = r^-1 * y^d % n = r^-1 * x^d * c^d % n = r^1 * (r^e)^d * c^d %n = c^d % n = m. Moral: Never sign a random document presented by a stranger (you wouldn't do with with a pen now, would you?) * Modulo the above cautions, it is widely believed, but not proven, that successfully attacking RSA is equivalent in difficulty to factoring the modulus n. For some RSA variants, this equivalence is proven. Patent by RSA security expired in September 2000. RSA made a PR deal of this, officially releasing RSA to the public.