0% found this document useful (0 votes)
37 views8 pages

CSB451 Ca4

The document describes an assignment question regarding cryptography. Specifically, it involves: 1) Implementing Feistel cipher encryption and decryption functions, assuming a 4-round Feistel cipher with 128-bit blocks. 2) Analyzing a "double DES-like" encryption method that chains two DES encryptions with independent keys. The response shows that an attacker can recover the full triple key (k, k1, k2) using only two chosen ciphertext queries, thereby breaking the system much faster than exhaustive key search.

Uploaded by

s Agrawal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
37 views8 pages

CSB451 Ca4

The document describes an assignment question regarding cryptography. Specifically, it involves: 1) Implementing Feistel cipher encryption and decryption functions, assuming a 4-round Feistel cipher with 128-bit blocks. 2) Analyzing a "double DES-like" encryption method that chains two DES encryptions with independent keys. The response shows that an attacker can recover the full triple key (k, k1, k2) using only two chosen ciphertext queries, thereby breaking the system much faster than exhaustive key search.

Uploaded by

s Agrawal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

National Institute of Technology Delhi

Cryptography and network security


(CSB 451)

Assignment-4

Submitted by:
Aadhar Kumar
Roll no.: 201210001

Submitted to:
Dr. Karan Verma
Question 1: Feistel cipher model is a structure used to develop many block ciphers
such as DES ( block ciphers encrypt a fixed size block of the plaintext at a time). The
Feistel cipher consists of rounds and a separate key is used on each round. For the i-th
round the process is the following: - Divide the input block into 2 halves, the left one
(Li) and the right one (Ri). - Compute Li+1 = Ri and Ri+1 = Li XOR f(Ri, Ki), where f is
an encrypting function and Ki is the key of this round. After n rounds, the final
ciphertext is (Rn+1 , Ln+1 ). The decryption process is similar, with the difference of
using the keys in the reverse order. A. Implement the functions feistel_encr and
feistel_decr, which receive as arguments the plaintext/ciphertext, the size of the
plaintext/ciphertext as well as the keys and return the result of the operation. Assume
that n=4, block size = 128, size of R_i = 64, size of L_i = 64 and f(r, k_i) = (r*k_i) mod
(2^64). You should generate the keys using a pseudorandom number generator (as
with a one-time pad algorithm). Each key should be the same size as the right part of
the block (in our case 64 bits).
Answer

def shiftBitLeft(self, block):


if block >= self.constant_64bit:
block -= self.constant_64bit
block = block << 1
block += 1
else:
block = block << 1
return block

def createKeyArray(self, block):


key_array = []
for i in range(0, 64):
block = self.shiftBitLeft(block)
key_array.append(block)

return key_array

def generateKeys(self, key):


row_keys = self.createKeyArray(key)
keys = []
counter = -1
x = 0
while(x < 192 and counter < 16):
i = x % 64
byte_arr = self.breakHexIntoChunks(row_keys[i])
if(x % 12 == 0):
keys.append([])
counter += 1

b = x % 4
if counter % 2 == 1:
b += 4
keys[counter].append(int(byte_arr[b], 16))
x += 1
return keys

def whitening(self, word, key):


r = []

key = format(key, "016x")


for i in range(0, 4):
j = i * 4

sw = word[j: j + 4]
sk = key[4 * i:4 * i + 4]
w = int(sw, 16) ^ int(sk, 16)
r.append(w)
return r

def g_function(self, r, k0, k1, k2, k3):


r = format(r, '04x')
g1 = int(r[:2], 16)
g2 = int(r[2:4], 16)
g3 = int(self.ftable[g2 ^ k0]) ^ g1
g4 = int(self.ftable[g3 ^ k1]) ^ g2
g5 = int(self.ftable[g4 ^ k2]) ^ g3
g6 = int(self.ftable[g5 ^ k3]) ^ g4
return int(format(g5, '02x') + format(g6, '02x'), 16)

def f_function(self, r0, r1, round):


k = self.keys[round]

t0 = self.g_function(r0, k[0], k[1], k[2], k[3])


t1 = self.g_function(r1, k[4], k[5], k[6], k[7])

k89 = int(format(k[8], '02x') + format(k[9], '02x'), 16)


kab = int(format(k[10], '02x') + format(k[11], '02x'), 16)
f0 = (t0 + 2 * t1 + k89) % self.const_2_16
f1 = (2 * t0 + t1 + kab) % self.const_2_16
return [f0, f1]
def round_function(self, r, round):
f = self.f_function(r[0], r[1], round)

new_r0 = r[2] ^ f[0]


new_r1 = r[3] ^ f[1]
new_r2 = r[0]
new_r3 = r[1]
return [new_r0, new_r1, new_r2, new_r3]

def encrypt(self, pt_hex):


r = self.whitening(pt_hex, self.original_key)

for i in range(0, 16):


r = self.round_function(r, i)

y = [r[2], r[3], r[0], r[1]]


y_hex = ""
for yi in y:
y_hex += format(yi, "04x")

c = self.whitening(y_hex, self.original_key)
c_str = ""
for ci in c:
c_str += format(ci, "04x")
return c_str

def decrypt(self, ct_hex):


r = self.whitening(ct_hex, self.original_key)
for i in range(15, -1, -1):
r = self.round_function(r, i)

p = [r[2], r[3], r[0], r[1]]


p_hex = ""
for pi in p:
p_hex += format(pi, "04x")
p = self.whitening(p_hex, self.original_key)
p_str = ""
for pi in p:
p_str += format(pi, "04x")
return p_str

Questions 2: 2. Let E, D be the encryption/decryption algorithms of a certain block


cipher. Consider the following chaining method for double DES like encryption:

The secret key is a triple (k, k1, k2) where k is as long as E’s block size (64 bits for
DES) and k1, k2 are as long as E’s key size (56 bits for DES). For example, when E is
DES the total key size is 64+56+56 = 176 bits.
a. Describe the decryption circuit for this system.
b. Show that using two short chosen ciphertext decryption queries an attacker can
recover the full key (k, k1, k2) in approximately the time it takes to run algorithm D 2 `
times (i.e. the attack running time should be O(2` time(D)). Here ` is the block cipher’s
key length (56 bits for DES). Your attack shows that this system can be broken much
faster than exhaustive search.
[ Hint: Consider the two decryption queries hC1, C2, C3, C4i and hC 0 1 , C2, C 0 3 ,
C4i
where C1, . . . , C4 and C 0 1 , C 0 3 are random ciphertext blocks. ]
Answer:
(A)

(B)
Following the hint, query the chosen ciphertext oracle on randomly-chosen inputs (C1,
C2, C3, C4) and (C1 , C’2, C3 , C’4) to get (M1, M2, M3, M4) and ( M’1 , M’2, M’3 , M’4)
From the decryption circuit we see
M2 = Dk2 (C1) ⊕ Dk1 (Dk2 (C2)),
M’2 = Dk2 (C’1 ) ⊕ Dk1 (Dk2 (C2)),
M4 = Dk2 (C3) ⊕ Dk1 (Dk2 (C4)),
M’4 = Dk, (C3 ) ⊕ Dk1 (Dk2 (C4)).
If we pair these equations and take xors, we find
M2 ⊕ M’2 = Dk2 (C1) ⊕ Dk2 (C’1 ),
M4 ⊕ M’4 = Dk2 (C3) ⊕ Dk2 (C’3 ).
We iterate over possible candidate keys K2 ∈ {0, 1}` for k2, and check the following
equations:
M2 ⊕ M’2 ?= DK2 (C1) ⊕ DK2 (C’1 ), (1)
M4 ⊕ M’4 ?= DK2 (C3) ⊕ DK2 (C’3 ). (2)
If we find a unique K2 satisfying both the above, we conclude K2 = k2 and proceed to
the next step of the attack. (We come back to the probability analysis for uniqueness
below.) Otherwise, choose new random Ci and C’I and restart.
Now notice
M2 = Dk2 (C1) ⊕ Dk1 (Dk2 (C2)),
M3 = Dk2 (C2) ⊕ Dk1 (Dk2 (C3)).
Cache Xi := Dk2(Ci) for i = 1, 2, 3. We can rewrite these equations as
Mi ⊕ Xi = Dk1 (Xi+1)
for i = 1, 2. We iterate over possible candidates K1 for k1, and check if the following
equations hold.
Mi ⊕ X1 ?= DK1 (X2) (3)
Mi ⊕ X2 ?= DK1 (X3) (4)
If we find a unique K1 satisfying equations (3) and (4), we conclude K1 = k1 and
proceed to next step of the attack.
Lastly, once k1 and k2 have been found, we can compute k = M1⊕Dk1 (Dk2 (C1)) directly.

You might also like