CS112 Week13
CS112 Week13
2
Cryptography
want to send a secret message…
Plaintext
Hello world! Hello world!
Ciphertext
Encrypt $%kon*e34()\\& Decrypt
key
(shared secret)
Example: Substitution code
Replace each symbol in the plain text by another
one, e.g.
instead of
a b c d e f g h i j k l mn o p q r s t u v wx y z
c f x z u g l j p q man vt h e b y w s r o ki dc
use
To decrypt (decipher):
4. XOR the ciphertext with the one-time pad again.
(Based on: a ⊕ (x ⊕ x) = a ⊕ 0 = a, ∀a)
Another example: One-time pads
Plaintext Message: MONDAY
• Convert the plaintext message into binary
Let’s use ASCII: M: 077, O: 079, N: 078, D: 068, A: 065, Y: 089
Binary: 01001101 01001111 01001110 01000100 01000001 01011001
• Create a random sequence of bits, this is your one-time pad, and also
your key
Key: 11000001 00010010 01111111 00000001 01000101 11110000
YES NO
NO
YES NO
Yes!
1 if CandidatePrimeFactor | N
CandidatePrimeFactor is a prime factor of N
N ← (N / CandidatePrimeFactor)
Go to 1
else
CandidatePrimeFactor = next prime
if(CandidatePrimeFactor*CandidatePrimeFactor) > N
Done
else Go to 1
For very large numbers, a hopelessly difficult task with the current technology!
How to test for primes?
def divides(d,n):
return(n%d == 0)
def LD(n):
for i in range(2,n+1):
if divides(i,n):
return i
def primes0(n):
if n<1:
return "error"
elif n==1:
return False
else:
return (LD(n)==n)
How to test for primes?
import math
def LDP(n):
for i in range(2,int(math.sqrt(n)+1)):
if primes0v2(i) and divides(i,n):
return i
return -1
finds the smallest prime that divides n
def primes0v2(n):
if n<1:
return "error"
elif n==1:
return False
else:
return (LDP(n)==-1)
or, may use sieve to generate primes…
def mark(xl, k, m):
if len(xl)==0:
return []
if k==m:
return [0]+mark(xl[1:],1,m)
else:
return [xl[0]]+mark(xl[1:],k+1,m)
def sieve(xl):
if len(xl)==0:
return []
if xl[0]==0:
return sieve(xl[1:])
return [xl[0]]+sieve(mark(xl[1:],1,xl[0]))
Another application: finding twin primes
listPrimes = list(filter(lambda x: primes0v2(x),
range(2,100)))
def primePairs(listPrimes):
list_twins = []
for i in range(len(listPrimes)-1):
if listPrimes[i+1] == listPrimes[i]+2:
list_twins.append((listPrimes[i],listPrimes[i+1]))
return list_twins
primePairs(listPrimes)
>> [(3, 5), (5, 7), (11, 13), (17, 19), (29, 31), (41, 43),
(59, 61), (71, 73)]
How do we find prime factors of N?
def factors(n):
if n<1:
return "argument not positive"
elif n==1:
return []
p = LDP(n)
if p==-1:
p = n
return [p]+factors(n//p)
Try with; e.g., Mersenne primes: 2^n – 1 (n = 17, 19, 31, 61,
89, ...)
How do we find prime factors of N?
• Products of two large primes of similar size are the most difficult integers to
factor in practice using the existing algorithms
• There used to be a $200,000 prize for factoring RSA-2048, a 2048 bit (617
decimal digits) number!
p × q =N
3564640… × 7523088…
data
Next morning, she can send the key to Bob so that he can
decrypt the message and see the move.
YES NO
Verify a password without knowing it!
p|N?
p passwords
database
N
Yes/No
gets stored
When establishing an account:
Select large primes p and q and compute N
p⋅q=N knowing only N, it is
hard to determine p…
password given to the machine
only the customer knows
erased
How to find the primes?
We know that there are arbitrarily large primes.
How many 200 digit primes?
Remember: the number of primes between 1 and n is:
n
π(n) ∼ so,
ln(n)
10 200
10199
–
____________________
≈ 1.95 ⋅10197
200ln10 199ln10
Compare with all 200 digit integers: 10200 – 10199 = 9⋅10199
9⋅ 10 199
≈ 460 thus, among 200 digit integers
_____________
Proof:
p(p-1)(p-2)…(p-k+1)
= _________________________
k(k-1)(k-2)…1
Proof:
Base Case: a = 0, trivial.
Assume that p | ap – a, (true for a, have to show that true for (a + 1) also)
(a + 1)p – (a + 1) = ap + ap -1 +…+ a + 1 – (a + 1)
= (ap – a) + ap-1 + … + a
For example:
22 = 4
(22)2 = 24 = 16
(24)2 = 28 = 256
(28)2 = 216 = 65536
(216)2 = 232 = 4294967296
(232)2 = 264 = 18446744073709551616
As before,
22 = 4
(22)2 = 24 = 16
(24)2= 28 = 256, but at this point we can
divide 256 by 25 and use the remainder 6 to continue! So,
(28)2= 216 = 36 (mod 25)!
How to avoid large numbers?
That is, we replace 28 by 6, and squaring it gives us 36.
is prime.
Observation:
A positive integer n > 1 is prime iff (if and only if) it passes
the Fermat’s test n | an-1 – 1 a {2, … ,(n-1)}.
secret message
in the box!
Public Key Cryptography
The math behind the RSA algorithm!
d: private key
e: public key
Sending a message to Alice
Bob wants to send a secret message to Alice.
computes: a ≡ rd (mod m)
Alice’s private key
a is the message x
Congruence
a ≡ b (mod m)
(a is congruent to b modulo m)
Clearly, m | (b – a)
Properties of the congruence relation
Reflexive: a ≡ a (mod m)
Addition: a + c ≡ b + d (mod m)
Subtraction: a - c ≡ b - d (mod m)
Multiplication: a ∙ c ≡ b ∙ d (mod m)
also: k ∙ a ≡ k ∙ b (mod m), ∀k∈Z
2 / 3 is a fraction!
TRUE FALSE
Division in Modular Arithmetic
Actually,
X ⋅ Wednesday = Y ⋅ Wednesday implies
(X – Y) ⋅ Wednesday = 0 (Sunday) + k ⋅ 7 (mod 7)
Since both (X – Y) and Wednesday are < 7; and 7 is a
prime number, the above equation can’t be satisfied unless
k = 0 and hence, X = Y.
m | (xed – x)
so, (p – 1) | (ed – 1) or
ed = (p – 1)⋅k + 1, k ∊ N, so
p | xp – x by Fermat’s Theorem
Euclidean Algorithm
64
GCD
Ex:
54 = 2 * 3^3
900 = 2^2 * 3^2 * 5^2
gcd(54, 900) = 2 * 3^2 = 18
65
The Eucledian Algorithm
Given two positive integers a and b, how do we
find their GCD?
gcd(300, 18) = gcd (18, 300) = gcd(18, 12) = gcd(12, 18) = gcd(12, 6)
= gcd(6, 12) = gcd(6, 0) = gcd(0, 6) = 6
67
Euclidian Algorithm Visual – GCD(1071, 462)
1071
147
462 147
147
21
68
The Eucledian Algorithm: Python
69
GCD Theorem:
Let d = gcd (a, b). Then, d can be written in the
form:
d = a⋅k + b⋅l
70
Back to a⋅x ≡ 1 (mod p) where p is a prime?
gcd(a, p) = ?
Since, p is prime, and 1 ≤ a < p,
gcd(a, p) = 1
The theorem states that there are two integers, k and l, such that
ak + pl = 1
or
ak = 1 (mod p)
k may not be between 1 and (p – 1); but, we can always use mod p
x = k (mod p)
ax = ak = 1 (mod p)
What is 53/2 (mod 234,527)?
If we can find an x for which 2⋅x = 1 (mod 234,527), the answer will
be:
53⋅x (mod 234,527)
So, let’s consider:
gcd(2, 234,527) = gcd(1, 2) = 1
Thus, there must be integers k and l such that: 2⋅k + 234,527 ⋅l = 1
or, 2k = 1 (mod 234,527), that is k and x are the same.
2k = 234,528 is a solution (by inspection).
So, k = 117,264
And, x = k = ½ = 117,264
gcd(a, p) = 1
Thus, there must be integers k and l such that:
d: private key
e: public key
Sending a message to Alice
Bob wants to send a secret message to Alice.
computes: a ≡ rd (mod m)
Alice’s private key
a is the message x
How to find two keys e & d?
Choose e, at random from the range: 1,…, [(p – 1)(q – 1) – 1].
Make sure that the selected number is relatively prime to (p – 1)(q – 1),
i.e., check if gcd(e, (p-1)(q-1)) = 1.
If the selected e is not relatively prime, choose another one. And try
again.
If yes, according to the GCD Theorem, there exist two integers k and l
such that:
ek – (p – 1)(q – 1) l = 1
Alice:
decrypts the received message with her private key,
sees signature “Bob”,
decrypts the rest with Bob’s public key
But, if one can break the RSA system, the same algorithm can be
used to find the prime factors of m…
Real life uses
SSL
HTTPS
Study Bee