The goal of the cryptography is to protect private communication in
the public world. The assumption is that two entities wanting to
communicate - Alice and Bob - are shouting their messages in a room
full of people. Everyone can hear what they are saying. The goal of
cryptography is to protect this communication so that only Alice and
Bob can *understand* the content of the messages.

Beyond confidentiality - ensuring the secrecy of communication - cryptography is used for many other purposes, such as:

- Authentication - Alice can
*sign*her message and Bob can verify that she sent it based on this signature - Integrity checking - Alice can generate a
*checksum*of the message. Bob can either extract it from the message or recalculate it and verify that the message has not been changed. - Non-repudiation - if Alice signs the message she cannot deny later that she sent it, because no one else could generate that same signature.
- Exchanging a secret with someone you have never met before, in a room full of people
- Proving to someone you know a secret without giving it away
- Sending secret messages to any m out of n people so that only those m can retrieve them and the rest cannot
- Sending secret messages to a group of n people, that can be retrieved only if m people work together

How do we encrypt messages? Alice could use knowledge of some common secret that only she and Bob know, like "meet at that place where we first had lunch together". This does not work for arbitrary messages, nor for the case where Alice and Bob never communicated before.

Alice could use a secret protocol to encrypt (transform plaintext into ciphertext) and reverse it to decrypt (transform ciphertext into plaintext). This is a bad idea for several reasons:

- It is hard to come up with a very secure cipher scheme (encryption and decryption protocol). Simple schemes (such as replacing letters with other letters and shuffling them around) are easily broken.
- Alice has to somehow communicate this new protocol to Bob and Bob has to implement it correctly. This does not scale and requires a human to implement each new protocol. Consequently protocols would be simple and thus not secure.

Alice can use a public protocol that has been well designed, well implemented and analyzed by many people for security. She can use a secret key that she communicates to Bob - a key is much easier to communicate than a whole new protocol. This is how today's crypto schemes work.

*Symmetric cryptography*- Alice and Bob know the same key and use it for encryption and decryption.Symmetric crypto can be used to ensure secrecy - Alice and Bob exchange the secret key and use it to communicate privately.

It can also be used for secure storage - Alice encrypts the files she stores in the cloud. If the cloud is compromised no one can read her files.

Symmetric crypto can also be used for authentication, aka proving that you know a secret without revealing it. Alice and Bob want to prove to each other they know the same secret. Alice chooses a random number and encrypts it with the key. Bob decrypts it and sends it back. Then Bob chooses a secret number and encrypts it and Alice decrypts it and sends it back. Why do we have to do this twice? Who is assured of what in each round?

*Asymmetric cryptography*- Alice has a pair of keys - a private key known only to her and a public key that anyone can find out. She can encrypt with one key from a pair (any one) and decrypt with another. Asymmetric crypto can do whatever symmetric crypto can but much slower (about 1,500 times slower). However it can also provide some extra functionality.In symmetric crypto secret communication between Alice and Bob is only possible if they know the same secret key. But how do they find out this key? They can use asymmetric crypto to exchange it. Bob could advertise his public key on his Web page. Alice could use it to encrypt a secret key and send it to Bob - only he will be able to retrieve it.

If Alice wants to authenticate Bob she encrypts a message with his public key and he decrypts it and sends it back. Alice can do all this without storing any secret information.

If Alice orders something from Bob and signs every message by encrypting it with her private key, anyone can verify her signature and no one can forge it. This ensures

*non-repudiation*- Alice cannot deny she sent the message.*Hash functions*- these are publicly known functions that reduce a large message to a fixed-size hash, applying a non-linear transformation (aka one-way hashes or message digests). Cryptographic has functions have several important properties:- One-way: knowing M it is easy to compute H(M) but knowing H(M) it is impossible to compute M (except using brute-force)
- Collision-free: knowing H(M) it is very hard to find M1 so that H(M1)=H(M)
- Collision-resistance: it is hard to find M1 and M2 so that H(M1)=H(M2)

Hashing a large message requires the hash algorithm to break it into chunks, and combine each chunk with the hash of the previous chunks to generate new hash. This process is shown in the picture below.

One way to do this is to use a *linear congruential
generator*. Here the next number in the sequence depends linearly
on the previous one, like this:

However, research has shown that any linear congruential generator can be broken (the attacker can learn the variables from the outputs and use them to predict the next state of the generator). In fact any polynomial congruential generator can be broken.

Today's RNG use linear feedback shift registers (LFSRs). The register holds the initial state and is transformed into the next state by XORing some bits and appending this value to the left. Contents are then shifted one space to the right and the bit that falls out is the output of the RNG process. The positions of the bits that are XORed are called the "tap sequence" and if properly chosen this generator will have the maximum period (covering all values from 1 to 2^n-1 where n is the size of the register).

CBC is not parallelizable as blocks must be encrypted and decrypted in order. A bit error during transmission invalidates one block and one bit - this is called "error extension". Bit loss/addition is not recoverable. Block loss/addition is also not recoverable.

Asymmetric crypto uses modular exponentiation as encryption/decryption. Modular arithmetic occurs on the Galois Field of size n, which means that all operations use operands and produce results in the range 0 .. n-1. Further modular reduction can be performed at any point, thus (a+b) mod n = ((a mod n) + (b mod n)) mod n. Smaller operands lead to faster operation.

Modular exponentiation can be speeded up considerably by performing
*addition chaining*. To calculate a^x mod n one writes x as a
binary number and processes it left to right. At each step, the result
of the computation so far is squared. If the
digit of exponent is 1, the result is also multiplied by a. This leads
to at most 2*k multiplications where k is the number of bits in
x. Modular reduction should be performed often to keep the operands
small.
Below is an example of modular exponentiation via addition chaining.

Asymmetric crypto also resides on use of prime numbers. A number is prime if it is only divisible by 1 and itself. Two numbers are relatively prime if they have no common factors other than 1 (e.g., 5 is a prime number, 9 and 8 are relatively prime even though neither is a prime number).

A multiplicative inverse for x in modular arithmetic is a number y such that x*y mod n = 1. Obviously, we need public and private keys in asymmetric crypto to have this property so that M^{x*y} = M^1 = M. The inverse can easily be found if x and n are relatively prime, otherwise it cannot be found. Thus if n is prime all numbers 1 .. n-1 are all relatively prime to n. Extended Euclidean Algorithm can be used to quickly find a multiplicative inverse for a number.

RSA is the most popular and most used asymmetric crypto algorithm. It works in GF(fi(n)) where n = p*q, p and q are large prime numbers and fi(n)=(p-1)*(q-1).

Private key e and public key d are chosen so that they are multiplicative inverses in GF(fi(n)). One publishes n and d and remembers e. The owner of the e,d chooses d at random and can easily calculate e because they know p and q. No one else can calculate e from n and d because n=(p-1)*(q-1), p and q are not public and to discover them one would have to factor a large number n. Asymmetric crypto's strength resides on the fact that it is hard to factor large numbers, i.e. the only way to do so is via brute-force search.

Encryption occurs as shown below:

Decryption occurs as shown below: