This document summarizes several public key cryptosystems including the Knapsack cryptosystem, RSA cryptosystem, ElGamal cryptosystem, and elliptic curve cryptography applied to ElGamal. For each cryptosystem, it describes the key generation process, encryption, and decryption algorithms. It also discusses security aspects such as the hard computational problems that the cryptosystems rely on like integer factorization and discrete logarithms. Finally, it provides code examples for implementing some of the cryptosystems in C.
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Public Key Cryptography
1. Public Key Cryptosystems
By: Abhijit Mondal
The Knapsack Cryptosystem:
The Knapsack Problem: Given a pile of items, each with different weights, is it possible to put some
of those items into a knapsack so that the knapsack weighs a given amount? i.e.
Given : m1 , m2 , ......, mn and the sum S.
Find : b1 , b2 ,....., bn such that S = b1m1 + b2 m2 + ....+ bn mn where bi ∈{0,1}
The above problem is a NP-complete problem i.e. The time taken for solution grows exponentially
with number of weights, since the only possible ways to find a solution is to consider all the
possible combinations of weights.
Superincreasing Knapsack : A superincreasing knapsack is a sequence in which every term is
greater than the sum of it's previous terms, e.g. {1,2,4,8,16,32} is a superincreasing knapsack.
Given the weights and the required total weight , it is easy to find a solution to the knapsack
problem. Suppose if S = 25, then in the knapsack {1,3,6,13,27,52} , we compare 25 with 52, since
25<52 hence 52 will not be in the solution, next compare 25 with 27, since 25<27, hence 27 is also
not in the solution, next since 25>13, hence 13 has to be in the knapsack because the sum of all
weights less than 13 is less than that 13 so if 13 is not present in the solution then the all the lesser
weights will never make up 25. So {13} is one weight. Next subtract 25-13 = 12, and compare 12
with 6, since 12>6 so 6 is present in the solution {13,6}, subtract 12-6 = 6, compare 6 with 3, since
6>3, so 3 will be present in the solution, {13,6,3}, next 6-3=3>1, so 1 is present {13,6,3,1}, but 3-
1=2 and no more weights are left hence we do not have a solution if the the result of last subtraction
is not 0.
For S= 34, 27 will be present, 34-27=7<13, 13 will not be present, 7>6, so 6 is present, 7-6=1>3, so
3 is not present but 1=1 so 1 is present and we have a solution {27,6,1};
For the Knapsack {1,2,4,8,...2k} we will have solutions for all 1<=S<=2k+1-1. Since all integers
between 0 and 2k+1-1 has a binary representation involving k bits.
Private Keys : A superincreasing Knapsack of length k, { a0 , a1 , .... , ak-1 }, an integer n>1, and a
prime integer p > 2ak-1 , are the private keys of the receiver.
Public Key : The normal NP-complete knapsack { b0 , b1, .... , bk-1 } where bi = nai ( mod p )
computed by the receiver is published on a public key server.
Encryption : Assuming that the plaintext of length m is in binary, the sender divides the plaintext
message into blocks of size k, and in each block if ith bit is 1, then calculates the sum sj = ∑ bi for
the blocks 1<=j<=m/k.
e.g. If for block 3 and k=6, {1,3,6,13,27,52}, and the bits of the block are 101101, then s3 = 1 + 6 +
13 + 52 = 72. The ciphertext is the set {sj}.
Decryption : The receiver calculates the blocks of bits using the superincreasing knapsack and the
ciphertext and recovers the plaintext.
C++ code for Knapsack Cryptosystem encryption : knapsack-encrypt.c
C++ code for Knapsack Cryptosystem decryption : knapsack-decrypt.c
2. The RSA Cryptosystem:
The receiver generates two large prime integers(100 digits) p and q, computes n = pq, and φ(n) =
(p-1)(q-1), then generates an encryption key e , such that gcd(e,φ(n)) = 1. The receiver publishes the
keys n and e on a public key server.
Suppose the plaintext message the sender wants to send is m (mod n), m and n are of the order of
200 digits, then he computes the ciphertext c = me (mod n) and sends c to the receiver.
The receiver then computes the decryption key d = e-1 (mod φ(n)), then computes cd (mod n) which
is equal to med (mod n) = m (mod n), thus recovering the plaintext message.
This is because ed = 1 mod(φ(n)), and so ed = 1 + kφ(n).
• If m is divisible by p but not divisible by q, then (med – m)(mod n) = m(mk(p-1)(q-1) – 1)(mod n)
By Fermat's Little Theorem since m and q are coprime thus mq-1 = 1 (mod q), or mq-1 - 1 = 0
(mod q). Thus (mk(p-1)(q-1) – 1) = 0 (mod q) and hence (mk(p-1)(q-1) – 1) = 0 (mod n). Thus med
(mod n) = m (mod n).
• Similarly if m is divisible by q and not by p.
• If m is coprime to both p and q, then m is coprime to n, thus by Euler's Theorem mkφ(n) = 1
(mod n) and thus med (mod n) = m*mkφ(n) (mod n) = m (mod n).
Public Keys : n=pq and encryption key e.
Private Keys : Primes p and q , and decryption key d=e-1 (mod φ(n)).
Encryption : Plaintext message m, ciphertext c = me (mod n).
Decryption : d = e-1 (mod φ(n)), m = cd (mod n) = med (mod n) = m (mod n).
Software implementation of RSA encryption :
• Generate 2 large integers p and q and test if they are primes by any primality testing routine.
• Compute n = pq;
• Compute 7-bit ASCII values for each character in the message
• Concatenate all the 7-bit binary values together.
• Calculate b = floor(log2(n)), b will be length of each plaintext block.
• Pad with zeroes to the right to make the total length of the concatenated bits a multiple of b.
• Consider all b-bit blocks from the concatenated bits,
• Compute the decimal equivalent of each b-bit blocks, this is mi .
• Now compute ci = mie (mod n) and then convert each ci into (b+1)-bit blocks and
concatenate all the (b+1)-bit blocks.
• Send this concatenated (b+1)-bit blocks to the receiver.
Software implementation of RSA decryption :
• Consider each (b+1)-bit block and compute it's decimal equivalent ci.
• Compute mi = cid (mod n) and compute its b-bit binary equivalent.
• Concatenate all the b-bit obtained values together.
• Consider 7-bit blocks from the concatenated bits and compute its corresponding ASCII
value and then find its corresponding ASCII character.
C code for RSA encryption : rsa-encrypt.c
C code for RSA decryption : rsa-decrypt.c
3. Security of RSA:
The security of RSA depends on the problem of factoring large numbers. A passive adversary has
access to only the integer n and the encrypting exponent e. Determining φ(n) from n takes
exponential time on the number of bits (log2 n) of the integer n, which is same as factoring n and
finding p and q. Knowledge of φ(n) or p or q will enable an adversary to recover the plaintext from
the ciphertext.
Common modulus attack on RSA:
If the modulus n is same for every implementation of the RSA algorithm and the same message gets
encrypted twice with different encrypting exponents e1 and e2, such that gcd(e1 , e2 )=1, then an
adversary can recover the plaintext if the two ciphertexts are known to him.
Suppose c1 = me1 (mod n) and c2 = me2 (mod n) and gcd( e1 , e2 )=1, then we can find r and s such
that re1 + se2 = 1:
r = e1-1(mod e2), then find s = (1-re1 )/e2 and then compute c1r c2s = mre1 + se2 (mod n) = m (mod n).
The El-Gamal Cryptosystem :
To generate a key pair, the receiver first choose a prime p and two random numbers g and x such
that g is a primitive root modulo p and is a generator of the cyclic group G={1, 2,.., p-1} and g< p
and x < p-1. Then compute : y ≡ g x (mod p).
The public key is (y, g, p) and the private key is x < p-1.
To encrypt the message m, 0<= m<= p−1, the sender first choose a random number k<p-1 such that
gcd (k, p−1)=1. The encrypted message (or ciphertext) is then the following pair (r, s ):
r ≡ g k (mod p) and s ≡ (my k (mod p))
The size of the ciphertext is double the size of the message. To decrypt the message, the receiver
divides s by r x , as shown below:
r x ≡ (g k )x (mod p)
s*(r x)-1 ≡ y k m(g k )-x ≡ (g x )k m(g k )-x ≡ m (mod p)
Security of ElGamal Cryptosystem :
The security of the ElGamal cryptosystem arises from the problem of finding the discrete logarithm
modulo a prime p. The private key x of the receiver is x = logg y (mod p-1) where g is the generator
of the cyclic group G ={1, 2,.., p-1}and g ,y are public keys. Thus computing the private key from
the public keys involves solving the DLP. Since no polynomial time algorithm in (log2p) is known
to solve the DLP, hence it is a hard problem.
C code for ElGamal encryption : elgamal-encrypt.c
C code for ElGamal decryption : elgamal-decrypt.c
Elliptic Curve Cryptosystem Applied to the ElGamal Algorithm :
The receiver generates his private key eB and a base point generator G on the elliptic curve EC: y2 =
x3 + ax + b over Zp, then he publishes his public keys p, the elliptic curve EC, G and eBG on a
public key server.
The sender wishes to send the plaintext M( a point on the elliptic curve EC ), generates a random
number k and computes x = kG, and y = M + k(eB G) which are the ciphertexts and sends them to
the receiver, (x,y) ∈EC.
The receiver computes y – eBx = M + k(eB G) - eB (kG) = M and recovers the plaintext.
The problem with the above is that our plaintext are coded in ASCII and we would require that each
ASCII code corresponds to a unique point on the curve i.e. There must be a one-to-one
correpondence between each of the 7-bit 128 ASCII codes and the points on the elliptic curve over
the field Zp. But maintaining such a correspondence is difficult since the points on the elliptic curve
4. over Zp are not sequentially ordered like the ASCII codes, thus we need to maintain a separate table
for the correspondence between the points and the ASCII codes.
Better solution is that we generate a random point X on the curve and compute Y such that for some
invertible function F(X,Y,p) = M the plaintext. The function F is generated by the receiver and is
made public. The sender computes x = kG, and y = X + k(eB G) and computes Y such that
F(X,Y,p) = M and sends his ciphertext ((x,y),Y) to the receiver.
The receiver then computes y – eBx = X + k(eB G) - eB (kG) = X, and uses Y to find F(X,Y,p) = M.
One possible implementation of F(X,Y,p) would be : if X = (x1 , y1) and Y=(x2 , y2) and the ASCII
code for the character be C = (x3 , y3) where x3 is the quotient on dividing C by p and y3 is the
remainder, then F(X,Y,p) = (x1x2 , y1y2) (mod p) = (x3 , y3).
Thus x2 = x3 x1-1 (mod p) and y2 = y3 y1-1 (mod p) . Thus we obtain Y = (x2 , y2).
The prime p>=13( because p>=√127 ).
x1 > 0 and y1 > 0 for their inverses modulo p to exist.
Since the number of points on the elliptic curve EC: y2 = x3 + ax + b over Zp, is >= p+1-2√p, hence
k <= p+1-2√p and eB <= p+1-2√p and also keB <= p+1-2√p from the various operations above :
thus k<= √(p+1-2√p) = √p-1 and eB <=√(p+1-2√p) = √p-1
C code for Elliptic Curve encryption of ElGamal Algorithm : elliptic_elgamal_encrypt.c
C code for Elliptic Curve decryption of ElGamal Algorithm : elliptic_elgamal_decrypt.c
Key Exchange in a Network :
Diffie-Hellman Key Exchange Protocol :
Let the users be A and B. They agree on a large prime number p and a generator g for the cyclic
multiplicative group modulo p {1,2,,,,p-1}on a public communication channel.
• A chooses a random large integer x < p-1and sends to B : X = gx mod p.
• B chooses a random large integer y < p-1 and sends to A : Y = gy mod p.
• Then A computes k = Yx mod p = gxy mod p
• B computes k = Xy mod p = gxy mod p.
Thus now both A and B have the common key k = gxy mod p. They now use this key to
communicate with each other. No one listening on the channel can compute the value k even if they
know g, p, X and Y. The difficulty in computing k from this known values involves the hard
problem of Discrete Logarithm. The key k cannot be used as an exponent to encrypt a message m
since k is in a group modulo p, but we need an exponent key to be in a group modulo (p-1).
In a communication channel with n users, a1, a2, ...., an the common secret key will be generated
after rounds of n-1 cycles. Then each can compute the common key k = gx1x2...xn (mod p) for all of
the n users.e.g. N=4:
• A chooses a random large integer x1 < p-1and sends to B : X1 = gx1 mod p.
• B chooses a random large integer x2 < p-1and sends to C : X2 = gx2 mod p.
• C chooses a random large integer x3 < p-1and sends to D : X3 = gx3 mod p.
• D chooses a random large integer x4 < p-1and sends to A : X4 = gx4 mod p.
• A computes and sends to B : X1' = X4x1 mod p = gx1x4 mod p.
• B computes and sends to C : X2' = X1x2 mod p = gx1x2 mod p.
• C computes and sends to D : X3' = X2x3 mod p = gx2x3 mod p.
• D computes and sends to A : X4' = X3x4 mod p = gx3x4 mod p.
• A computes and sends to B : X1'' = (X4 ')x1 mod p = gx1x3x4 mod p.
• B computes and sends to C : X2'' = (X1 ')x2 mod p = gx1x2x4 mod p.
• C computes and sends to D : X3'' = (X2 ')x3 mod p = gx1x3x2 mod p.
5. • D computes and sends to A : X4'' = (X3 ')x4 mod p = gx2x3x4 mod p.
• A computes : k = (X4'')x1 = gx1x2x3x4 mod p.
• B computes : k = (X1'')x2 = gx1x2x3x4 mod p.
• C computes : k = (X2'')x3 = gx1x2x3x4 mod p.
• D computes : k = (X3'')x4 = gx1x2x3x4 mod p.
Diffie –Hellman key exchange using an Elliptic Curve :
Let the users be A and B. They agree on a large prime number p and a base point generator G =
(x,y) on the elliptic curve EC : y2 = x3 + ax + b over Zp, on a public communication channel.
• A chooses a random point x on the elliptic curve and sends to B : X = xG.
• B chooses a random point y on the elliptic curve and sends to A : Y = yG.
• Then A computes k = xyG.
• And B computes k = yxG.
Since the number of points on the elliptic curve EC: y2 = x3 + ax + b over Zp, is >= p+1-2√p, hence
x <= p+1-2√p and y <= p+1-2√p and also xy <= p+1-2√p from the various operations above :
thus x<= √(p+1-2√p) = √p-1 and y <=√(p+1-2√p) = √p-1.
The secrecy of the Diffie-Hellman elliptic curve key exchange is the complexity of elliptic curve
“integer” factorization.
Diffie –Hellman key exchange over the field GF(2m) :
Let the users be A and B. They agree on an exponent m and an irreducible polynomial p(x) of
degree m over the field Z2 . Then the field GF(2m) is characterized by the polynomials f(x) = a0 +
a1x + a2x2 + ......+ am-1xm-1 , where ai ∈{0,1} Let α be the root of p(x) over the reals, i.e. p(α) = 0 over
the reals but p(α) ≠ 0 over GF(2m).
• A chooses a random large integer x mod( 2m-1 ) and sends to B : X(α) = αx ( mod p(α) ) .
• B chooses a random large integer y mod( 2m-1 ) and sends to A : Y(α) = αy ( mod p(α) ) .
• Then A computes : k(α) = (Y(α))x ( mod p(α) ) = αxy ( mod p(α) )
• And B computes : k(α) = (X(α))y ( mod p(α) ) = αxy ( mod p(α) )
If r(x) = b0 + b1x + b2x2 + ......+ bmxm , then the set of irreducible polynomials p(x) of degree m over
the field Z2 can be generated from r(x) by having b0 = 1 and bm = 1 and odd number of bi 's from b1
to bm-1 equal to 1.
The Diffie-Hellman key exchange protocol in its original form cannot be used to encrypt or decrypt
messages because the key k cannot be used as an exponent to encrypt a message m since k is in a
group modulo p, but we need an exponent key to be in a group modulo (p-1). If k is in a group
modulo p then if ciphertext c = mk (mod p), now to decrypt c we need k-1(mod p) = x which implies
that kx = 1+ tp, thus cx = mmtp (mod p) but mp=m(mod p) hence cx ≠ m (mod p), but if k is in a
group modulo p-1, then kx = 1 + t(p-1) and cx = mmt(p-1) (mod p) and by Fermat's theorem mp-1 = 1
(mod p). Thus cx = m (mod p).
If we compute k-1 in a group modulo (p-1) then gcd(k,p-1) should be 1. Hence if k is prime then
automatically gcd(k,p-1) = 1, but if k is not a prime and gcd(k,p-1) ≠ 1 , then both the users A and B
find the nearest integer k' greater than k such that gcd(k',p-1) = 1.
6. Imagine how would people before 19th century would have communicated securely when there were
no medium of electronic communication. Suppose the Queen of England has to sent a secret
message to the King of Netherlands. Here is what she would have done:
• Put the secret message inside a special box which has two slots for lock and is very hard to
break. She locks the box with her own secret key and sends the locked box to the King of
Netherlands.
• The King of Netherlands now uses his own secret key to put a lock on the second slot and
sends back the box to the Queen of England.
• The Queen unlocks her lock and removes it and send back the box to the King.
• The King then unlocks his lock and opens the box to obtain the secret message.
Hash Functions and Message Authentication Codes :
In e-commerce, it is often necessary for communication parties to verify each other’s identity. One
practical way to do this is with the use of cryptographic authentication protocols employing a one-
way hash function.
A hash function h is:
• A one-way hash function if it is computationally infeasible to determine the message m
given the hash-of-message h(m).
• A collision-resistant hash function if given the hash-of-message h(m) it is computationally
infeasible to determine any other message m* with the same hash value h(m) = h(m* ).
A hash of a message ideally should uniquely characterize the message. A hash of a message is
usually used to shorten the length of the message to an extent such that the least possible amount of
information is lost from the message in shortening the message and subsequent difficulty in find
collisions.
A message digest is a hash function that derives a fixed-length hash value for every message in
some message domain.
Message-Digest MD5 Algorithm :
Here A,B,C and D are initialized to 32-bit hexadecimal constants:
A = 01 23 45 67 ; B = 89 ab cd ef ; C = fe dc ba 98 ; D = 76 54 32 10
at the end of the processing A,B,C and D contains 32-bit values which together gives the 128-bit
hash for the message.
These four variables are then copied into different variables: A as a, B as b, C as c and D as d.
The message is padded so that its length (in bits) is congruent to 448 modulo 512. That is, the
padded message is just 64 bits short of being a multiple of 512. This padding is formed by
appending a single ‘ 1’ bit to the end of the message, and then ‘ 0’ bits are appended as needed such
that the length (in bits) of the padded message becomes congruent to 448 (= 512 − 64), modulo 512.
A 64-bit representation of the original message length is appended to the result of the previous step.
The length of the resulting message is an exact multiple of 512 bits. Equivalently, this message has
a length that is an exact multiple of 16 (32-bit) words.
There are 4 rounds of 16 operations each for each of the 512-bit block of the message.In each round
there is one nonlinear function that takes input 3 of the 4 constants and transforms the constants a,
b, c, d. The schematic for one among the 64 operations is shown above. The 4 nonlinear functions
are as follows:
7. F(X, Y, Z) = (X•Y) + (~X•Z)
G(X, Y, Z) = (X•Z) + (Y•(~Z))
H(X, Y, Z) =X⊕Y⊕Z
I(X, Y, Z) = Y ⊕ (X + ~Z)
If M[k ], 0 ≤ k ≤ 15, denotes the k th 32-bit sub-block of the message, and <<< s represents a left
shift s bits, the four operations are defined as follows:
FF(a, b, c, d, M[k], s, i) : a = b + ((a + F(b, c, d) + M[k] + T[i] <<< s)
GG(a, b, c, d, M[k], s, i) : a = b + ((a + G(b, c, d) + M[k] + T[i] <<< s)
HH(a, b, c, d, M[k], s, i) : a = b + ((a + H(b, c, d) + M[k] + T[i] <<< s)
II(a, b, c, d, M[k], s, i) : a = b + ((a + I(b, c, d) + M[k] + T[i] <<< s)
T[i] = integer part of [232 ∗ |sin(i)|] where 0 ≤ |sin(i)| ≤ 1 and 0<= 232 ∗ |sin(i)| ≤ 232 .
Round 1: Following 16 operations are performed :
FF[a, b, c, d, M[0], 7, 1], FF[d, a, b, c, M[1], 12, 2], FF[c, d, a, b, M[2], 17, 3],
FF[b, c, d, a, M[3], 22, 4], FF[a, b, c, d, M[4], 7, 5], FF[d, a, b, c, M[5], 12, 6],
FF[c, d, a, b, M[6], 17, 7], FF[b, c, d, a, M[7], 22, 8], FF[a, b, c, d, M[8], 7, 9],
FF[d, a, b, c, M[9], 12, 10], FF[c, d, a, b, M[10], 17, 11], FF[b, c, d, a, M[11], 22, 12],
FF[a, b, c, d, M[12], 7, 13], FF[d, a, b, c, M[13], 12, 14], FF[c, d, a, b, M[14], 17, 15],
FF[b, c, d, a, M[15], 22, 16]
Round 2: Following 16 operations are performed :
GG[a, b, c, d, M[1], 5, 17], GG[d, a, b, c, M[6], 9, 18], GG[c, d, a, b, M[11], 14, 19],
GG[b, c, d, a, M[0], 20, 20], GG[a, b, c, d, M[5], 5, 21], GG[d, a, b, c, M[10], 9, 22],
GG[c, d, a, b, M[15], 14, 23], GG[b, c, d, a, M[4], 20, 24], GG[a, b, c, d, M[9], 5, 25],
GG[d, a, b, c, M[14], 9, 26], GG[c, d, a, b, M[3], 14, 27], GG[b, c, d, a, M[8], 20, 28],
GG[a, b, c, d, M[13], 5, 29], GG[d, a, b, c, M[2], 9, 30], GG[c, d, a, b, M[7], 14, 31],
GG[b, c, d, a, M[12], 20, 32].
Round 3: Following 16 operations are performed :
HH[a, b, c, d, M[5], 4, 33], HH[d, a, b, c, M[8], 11, 34], HH[c, d, a, b, M[11], 16, 35],
HH[b, c, d, a, M[14], 23, 36], HH[a, b, c, d, M[1], 4, 37], HH[d, a, b, c, M[4], 11, 38],
HH[c, d, a, b, M[7], 16, 39], HH[b, c, d, a, M[10], 23, 40], HH[a, b, c, d, M[13], 4, 41],
HH[d, a, b, c, M[0], 11, 42], HH[c, d, a, b, M[3], 16, 43], HH[b, c, d, a, M[6], 23, 44],
HH[a, b, c, d, M[9], 4, 45], HH[d, a, b, c, M[12], 11, 46], HH[c, d, a, b, M[15], 16, 47],
HH[b, c, d, a, M[2], 23, 48],.
Round 4: Following 16 operations are performed :
II[a, b, c, d, M[0], 6, 49], II[d, a, b, c, M[7], 10, 50], II[c, d, a, b, M[14], 15, 51],
II[b, c, d, a, M[5], 21, 52], II[a, b, c, d, M[12], 6, 53], II[d, a, b, c, M[3], 10, 54],
II[c, d, a, b, M[10], 15, 55], II[b, c, d, a, M[1], 21, 56], II[a, b, c, d, M[8], 6, 57],
II[d, a, b, c, M[15], 10, 58], II[c, d, a, b, M[6], 15, 59], II[b, c, d, a, M[13], 21, 60],
II[a, b, c, d, M[4], 6, 61], II[d, a, b, c, M[11], 10, 62], II[c, d, a, b, M[2], 15, 63],
II[b, c, d, a, M[9], 21, 64].
Now A=A+a, B=B+b , C=C+c and D=D+d.
Where A, B, C, and D represents the hash for the message.
8. Secure Hash Algorithm (SHA-1) :
When a message of any length of less than 264 bits is input, the SHA-1 produces a 160-bit output
called a message digest (or a hash code). The message digest can then be input to the DSA, which
generates or verifies the signature for the message. Signing the message digest rather than the
message often improves the efficiency of the process because the message digest is usually much
smaller than the message.
The message is padded so that its length (in bits) is congruent to 448 modulo 512. That is, the
padded message is just 64 bits short of being a multiple of 512. This padding is formed by
appending a single ‘ 1’ bit to the end of the message, and then ‘ 0’ bits are appended as needed such
that the length (in bits) of the padded message becomes congruent to 448 (= 512 − 64), modulo 512.
A 64-bit representation of the original message length is appended to the result of the previous step.
The length of the resulting message is an exact multiple of 512 bits. Equivalently, this message has
a length that is an exact multiple of 16 (32-bit) words.
The 160-bit buffer consists of five 32-bit registers (A, B, C, D and E). Before processing any
blocks, these registers are initialised to the following hexadecimal values:
A = 67 45 23 01
B = ef cd ab 89
C = 98 ba dc fe
D = 10 32 54 76
E = c3 d2 e1 f0
A sequence of logical functions f0 , f1 , . . . , f79 is used in SHA-1. Each function ft , 0 <=t<=79,
operates on three 32-bit words B, C and D, and produces a 32-bit word as output. Each operation
performs a nonlinear operation of three of A, B, C and D, and then does shifting and adding as in
MD5. The set of SHA primitive functions, ft (B, C, D) is defined as follows:
ft (B, C, D) = (B • C) + (~B • D), 0 <= t<=19
ft (B, C, D) = B ⊕ C ⊕ D, 20<= t<= 39
ft (B, C, D) = (B • C) + (B • D) + (C · D), 40<= t<= 59
ft (B, C, D) = B ⊕ C ⊕ D, 60<=t<=79
addition is modulo 232, i.e. The last 32 bits of binary addition is considered.
Four distinct constants are used in SHA-1. In hexadecimal, these values are given by
Kt = 5a827999, 0 ≤ t ≤ 19
Kt = 6ed9eba1, 20 ≤ t ≤ 39
Kt = 8fbbcdc, 40 ≤ t ≤ 59
Kt = ca62c1d6, 60 ≤ t ≤ 79
The message block is transformed from 16 32-bit words (M0 to M15) to 80 32-bit words (W0 toW79 )
using the following algorithm.
Wt = Mt for t = 0 to 15;
Wt = (Wt-3 ⊕ Wt-8 ⊕ Wt-14 ⊕ Wt-16 ) <<<1, for t = 16 to 79.
<<<1 represents left circular shift by 1 bit.
For t = 0 to 79
{
temp = (a<<<5) + ft(b,c,d) + e + Wt + Kt ;
e = d;
d = c;
c = b<<<30;
b = a;
a = temp;
}
C++ code for SHA-1 : sha.cpp
9. Hashed Message Authentication Codes (HMAC) :
The keyed-hashing Message Authentication Code (HMAC) is a key-dependent one-way hash
function which provides both data integrity and data origin authentication for files sent between two
users. HMACs can be used to authenticate data or files between two users (data authentication).
They can also be used by a single user to determine whether or not his files have been altered (data
integrity).
To compute HMAC over the message, the HMAC equation is expressed as follows:
HMAC = H [(K ⊕ opad)||H [(K ⊕ ipad)||M]]
where
ipad = 00110110(0x36) repeated 64 times (512 bits)
opad = 01011100(0x5c) repeated 64 times (512 bits)
ipad is inner padding opad is outer padding .
1. Append zeros to the end of K to create a b-byte string (i.e. if K = 160 bits in length and b =
512 bits, then K will be appended with 352 zero bits or 44 zero bytes 0x00).
2. XOR (bitwise exclusive-OR) K with ipad to produce the b-bit block computed in step 1.
3. Append M to the b-byte string resulting from step 2.
4. Apply H to the stream generated in step 3.
5. XOR (bitwise exclusive-OR) K with opad to produce the b-byte string computed in step 1.
6. Append the hash result H from step 4 to the b-byte string resulting from step 5.
7. Apply H to the stream generated in step 6 and output the result.
Digital Signature Protocols and Algorithms :
The requirements of a digital signature system include:
• The signature should be functionally dependent on every component of the message.
• The signature should incorporates some element of time dependence .
• Only the originator should have computationally feasible means to construct a valid
signature for a message .
• Any authorized recipient should have computationally feasible means to verify the validity
of a signature for a message.
RSA Encryption and Signature with Authentication Scheme :
Suppose A wants to sign and encrypt a message before sending it to B. A generates 2 large primes p
and q and computes n = pq. A also computes φ(n) = (p-1)(q-1) and then generates a random secret
key e (mod φ(n)), this is A's private key, then A computes his public key d = e-1 (mod φ(n)) and
publishes it or send it to B.
Suppose if A wants to send the message m to B, he first computes the hash H(m) for the message
using SHA, then he encrypts both m and H(m) with his private key, c1 = me (mod n) and c2 = (H(m)e
(mod n), and sends c1 and c2 to B.
B decrypts c1 and c2 with A's public key d, c1d (mod n) = m and c2d (mod n) = H(m). Then checks
whether H(m) corresponds to m by running SHA algorithm. If they match then both the message
and the signature gets accepted.
10. ElGamal Encryption and Signature with Authentication Scheme :
Suppose A wants to sign and encrypt a message before sending it to B. To generate a key pair, A
first choose a prime p and two random numbers g and x such that g is a primitive root modulo p and
is a generator of the cyclic group G={1, 2,.., p-1} and g< p and x < p-1. Then compute : y ≡ g x
(mod p).
The public key is (y, g, p) and the private key is x < p-1.
To encrypt the message m, A first choose a random number k<p-1 such that gcd (k, p−1)=1. The
encrypted message (or ciphertext) is then the following pair (r, s ):
r ≡ g k (mod p) and s ≡ (my k (mod p))
A then computes the hash H(m) for the message m and then uses Euclidean Algorithm to compute t
from the equation : H(m) = (xr + kt) (mod p-1). Then A sends (r, s, t) to B.
To decrypt the message, B computes s(r -x) , as shown below:
r x ≡ (g k )x (mod p)
s*(r x)-1 ≡ y k m(g k )-x ≡ (g x )k m(g k )-x ≡ m (mod p) .
Then B computes H(m) from m using the same algorithm as A. B then checks whether yrrt (mod p)
= gH(m) (mod p). If they are equal then both the message and the signature is accepted by B.
Digital Signature Algorithm (DSA) :
Key pair generation:
p: a prime number between 512 to 1024 bits long
q : a prime factor of p − 1, 160 bits long
g ≡ h (p−1)/q (mod p) > 1, and h < p − 1
(p, q and g ): public parameters
x < q : the private key, 160 bits long
y ≡ g x (mod p): the public key, 160 bits long
Signing process (sender):
DSAsign(p, q, g, k, x, h, r, s)
{
k < q : a random number
r ≡ (g k mod p) (mod q )
s ≡ k −1 (H(m) + xr ) (mod q ), H (m) is a one-way hash function of the message m.
(r, s ): signature
}
Verifying signature (receiver):
w ≡ s −1 (mod q )
u1 ≡ H(m) × w (mod q )
u2 ≡ r × w (mod q )
v ≡ (g u1 y u2 (mod p)) (mod q )
If v = r , then the signature is verified.
Proof : gq = h(p-1) (mod p) = 1 by Fermat's Theorem;
Let w = s −1 + hc1q, u1 = hs −1 + hc1q + c2q, u2 = rs −1 + rc1q + c3q and s-1(h+xr) = k + c4q.
Then (g u1 y u2 (mod p)) (mod q ) = (g hs −1 + hc1q + c2qgx( rs −1 + rc1q + c3q ) (mod p)) (mod q).
From the exponent we get (g u1 y u2 (mod p)) (mod q ) = g^( hs −1+ hc1q + c2q + xrs −1 + xrc1q + xc3q)
but hs −1+ xrs −1 = k + c4q,
thus v = (g^( k + hc1q + c2q + c4q + xrc1q + xc3q) (mod p) ) (mod q) = (gk (mod p)) (mod q) because
gq = h(p-1) (mod p) = 1 (mod p).
11. DSA Primes Generation Algorithm :
Generation of primes p and q for the DSA:
The prime p is L bits long, 512<=L<=1024 in some multiple of 64 bits. The prime q is 160 bits
long. Let L-1 = 160n + b, b<160.
1. Choose an arbitrary sequence of atleast 160 bits and call it S. Let g be the length of S in bits.
2. Compute U = SHA(S) ⊕ SHA((S+1) mod 2g).
3. Form q by setting the most significant bit and the least significant bit of U to 1.
4. Check whether q is prime, if q is not prime go back to step 1.
5. Let C=0 and N=2
6. For k = 0,1,..,n, let Vk = SHA((S+N+k) mod 2g).
7. Let W be of L-1 bits ,W= V0 || V1 || ......||Vn-1 || (Vn mod 2b) where Vi 's are concatenated.
8. If Y is the integer representation of W, the compute X = Y + 2L-1 , X is a L-bit integer.
9. Let p = X- ((X mod 2q)-1), p is congruent to 1 mod 2q.
10. If p < 2L-1, then go to step 12.
11. Chech whether p is prime, if p is prime go to step 14.
12. Let C= C+1 and N = N+n+1.
13. If C=4096 then go to step 1. Otherwise go to step 6.
14. Save the value of S and the value of C used to generate p and q.
DSA-ElGamal Encryption and Digital Signature :
DSA can only be used for signing but if we want encryption of the plaintext m along with its
signature then we can combine DSA-ElGamal into a single algorithm:
ElGamal Encryption: Public key : y, g, and p.
Call DSAsign(p, p, g, k, 0, 0, r, s) and store the value of r in a, i.e. a =r.
Call DSAsign(p, p, y, k, 0, 0, r, s) and store the value of r in a, i.e. b =r.
Call DSAsign(p, p, m, 1, 0, 0, r, s) and store the value of r in a, i.e. c =r.
The ciphertext for ElGamal encryption is (u,v) = (a, bc (mod p)).
ElGamal Decryption: Private key : x
Call DSAsign(p, p, u, x, 0, 0, r, s) and store the value of r in u, i.e. u =r.
Call DSAsign(p, p, 1, u, v, 0, r, s) and store the value of s in m, i.e. m = s.
Hence m is the plaintext obtained.
Digital Signature using Elliptic Curve Cryptography :
Generation and verification of a random elliptic curve :
Input: A field size p (an odd prime) .
Output: A bit string E of length g >= 160 bits and field elements a , b ∈ Zp that define an elliptic
curve EC: y 2 = x 3 + ax + b over Zp .
1. Choose an arbitrary bit string E of length g >=160 bits.
2. Compute the hash code h = SHA-1(E) and let c0 be the bit stream of length v bits obtained
by taking the v rightmost bits of h, where v = t − 160 × s , t = ceil(log2 b) and s = (t− 1)/160 .
3. W0 is the v -bit stream taken by setting the leftmost bit of c0 to zero.
4. The integer z whose binary expansion is the g -bit stream E.
5. For i from 1 to s : Let si be the g -bit string of the integer (z + i) mod 2g . Compute Wi =
SHA-1(si ).
6. W is the bit string obtained by concatenation: W = W0 ||W1 || . . . ||Ws .
7. r is the integer whose binary expansion is W .
8. If r = 0 or 4r + 27 ≡ 0 (mod p), then go to step 1.
9. Choose a ≠ 0, b ≠ 0 ∈ Zp such that rb 2 ≡ a 3 (mod p). If this condition is met, then accept;
otherwise reject.
10. Output (E, a, b).
12. Key pair generation :
Let G be a base point generator for the Elliptic Curve E(a,b), and n the order of G, i.e. nG = O and
n <= (√p-1)2 .
User A selects a random integer d for 1<= d<= n − 1 and computes Q = dG where Q is A’s public
key and d is A’s private key.
Signature :
Select a random integer k, 1<= k<= n − 1.
Compute the following steps:
• R = kG = (x, y), then compute r = px+y. If r = 0, then go to the initial step.
• k −1 (mod n); and h = SHA-1(m) of m and convert this bit string to an integer e.
• Compute s ≡ k −1 (e + dr) (mod n). If s = 0, then go to the initial step.
A’s signature for the message m is (r, s ).
Verification :
User B computes the message digest h = SHA-1(m) of the message m and convert this bit string to
an integer e.
Compute the following steps:
• w ≡ s −1 (mod n)
• u1 = ew (mod n) and u2 = rw (mod n).
• X = u1G + u2Q = kG = (x1, y1)
• Accept the signature if px1 + y1 = r
Schnorr's Authentication Algorithm :
Suppose A wants to authenticate himself to B over the network. A gets B's public keys from the
KDC and follows the protocol below :
B's Public keys :
Primes, p and q , such that q is a prime factor of p − 1.
a ≡ h(p-1)/q (mod p), where 0<h<p-1.
λ ≡ a −s (mod p) for some random s < q
When B asks A to authenticate itself, B first sends to A a random integer t, such that 0 < t < 2v − 1,
then A chooses a random integer r < q which is A's private key and computes x = ar (mod p) and y =
r + st (mod q). A then sends x and y to B.
B computes ay λt (mod p) and if it equals x, then B accepts A as authentic.
Proof :
y = r+ st + cq, hence ay λt (mod p) = h((p-1)/q)(r+st+cq) h((p-1)/q)(-st) (mod p) = hc(p-1)h((p-1)/q)r (mod p) and by
Fernat's little theorem we know that hp-1 = 1 (mod p) for h < p.
Thus ay λt (mod p) = h((p-1)/q)r (mod p) = ar (mod p) = x (mod p).
Fiat-Shamir Identification Protocol :
A wants to prove identity to B by showing possession of some secret information without actually
revealing this information.
A trusted signature center chooses secret primes p, q and computes N = pq; only N is distributed to
all users.
• A selects a random s, checks that 1 = gcd{s, N} and computes v-l = s 2 (modulo N ).
• A registers v with the trusted signature center.
A's private key is s and A's public key is the pair (N,v).
13. Here is the protocol :
1. A chooses a random r in ZN, computes x = r 2 (modulo N ) and sends x to B.
2. B chooses a random bit b = 0 or 1 (with probability 1/2) and sends it to A.
3. A returns y to B where y = r if b=0 and y = rs(modulo N) if b=1 .
4. B computes y2vb (mod N) = r2 (mod N ) = x. Thus A passes the 1st round of identification test
if y2vb (mod N) = r2 (mod N ) = x holds.
5. Another round of test begins from step 1 and continues until B is convinced of the true
identity of A.
The probability that an impostor A will successfully pass the test as A is thus ½ in each round of
computation. Thus after t rounds of computation a false A passes the identification test with a
probability of 1 in 2t.