NSC 1
NSC 1
—----------------------------------------------------------------------------------------------------------------------------
mat=[[2,3],[3,6]]
print(mat)
for rows in mat:
det=(mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0])%26
print("det is:")
print(det)
adj=[[mat[1][1],-mat[1][0]],[-mat[0][1],mat[0][0]]]
mod=[[ele%26 for ele in rows]for rows in adj]
print("adjoint: ")
for rows in mod:
print(rows)
—------------------------------------------------------------------------------------------------------------------------
3a)
p=7
q = 11
e=7
ciphertext = 37
n=p*q
phi_n = (p - 1) * (q - 1)
# Step 1: Find d using the modular inverse of e modulo phi(n) using brute force...
d=0
for i in range(1, phi_n):
if (e * i) % phi_n == 1:
d=i
break
# Step 2: Decrypt the ciphertext
plaintext = pow(ciphertext, d, n)
# Output the result
print(f"Decrypted plaintext: {plaintext}")
—--------------------------------------------------------------------------------------------------------------------------
4a)
p=3
q = 13
e=3
plaintext = 5
n=p*q
ciphertext = pow(plaintext, e, n)
print(f"Encrypted ciphertext: {ciphertext}")
p=3
q = 13
e=3
plaintext = 5
n=p*q
ciphertext = pow(plaintext, e, n)
print(f"Encrypted ciphertext: {ciphertext}")
—--------------------------------------------------------------------------------------------------------------------------
5a,6a,9a)
Subkey generation: ((**Recommended**))
key = 0b1110001111
def keyGen(key):
def leftShift(keyBits, positions=1):
return keyBits[positions:] + keyBits[:positions]
print("SubKey1:", subKey1)
print("SubKey2:", subKey2)
print(f"Sub1: {bin(subKey1)}")
print(f"Sub2: {bin(subKey2)}")
return subKey1, subKey2
KeyLength = 10
P10table = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
P8table = [6, 3, 7, 4, 8, 5, 10, 9]
keyGen(key)
—---------------------------------------------------------------or—---------------------------------------------------
key = 0b1110001110
def generate_keys(key):
def left_shift(bits, shifts):
return ((bits << shifts) & 0x3FF) | (bits >> (10 - shifts))
KeyLength = 10
P10table = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
P8table = [6, 3, 7, 4, 8, 5, 10, 9]
generate_keys(key)
—---------------------------------------------------------------------------------------------------------------------
7)
import numpy as np
key = np.array([[2, 3], [3, 6]])
plaintext = "attack"
print(plaintext)
if len(plaintext) % 2 != 0:
plaintext += "x"
sb = []
for i in range(0, len(plaintext), 2):
first = (key[0][0] * plainvector[i] + key[0][1] * plainvector[i + 1]) % 26
second = (key[1][0] * plainvector[i] + key[1][1] * plainvector[i + 1]) % 26
sb.append(chr(first + ord('a')))
sb.append(chr(second + ord('a')))
print(''.join(sb))
—----------------------------------------------------------------------------------------------------------------------
8)
import numpy as np
def main():
key = np.array([[2, 3], [3, 6]])
det = key[0][0] * key[1][1] - key[0][1] * key[1][0]
print("det is", det)
detinverse = findinverse(det, 26)
adjoint = np.zeros((2, 2), dtype=int)
adjoint[0][0] = key[1][1]
adjoint[0][1] = -key[0][1]
adjoint[1][0] = -key[1][0]
adjoint[1][1] = key[0][0]
if len(ciphertext) % 2 != 0:
ciphertext += "X"
sb = []
for i in range(0, len(ciphertext), 2):
first = (inverse[0][0] * plainvector[i] + inverse[0][1] * plainvector[i + 1]) % 26
second = (inverse[1][0] * plainvector[i] + inverse[1][1] * plainvector[i + 1]) % 26
sb.append(chr(first + ord('A')))
sb.append(chr(second + ord('A')))
adj=[[mat[1][1],-mat[1][0]],[-mat[0][1],mat[0][0]]]
mod=[[ele%26 for ele in rows]for rows in adj]
det_mod_inv = pow(det, -1, 26)
print(f"Modular inverse of determinant: {det_mod_inv}")
inverse = [[(ele * det_mod_inv) % 26 for ele in row] for row in mod]
plaintext = "FKMFIO"
print(plaintext)
if len(plaintext) % 2 != 0:
plaintext += "x"
sb = []
for i in range(0, len(plaintext), 2):
first = (inverse[0][0] * plainvector[i] + inverse[0][1] * plainvector[i + 1]) % 26
second = (inverse[1][0] * plainvector[i] + inverse[1][1] * plainvector[i + 1]) % 26
sb.append(chr(first + ord('A')))
sb.append(chr(second + ord('A')))
print(''.join(sb))
—---------------------------------------------------------------------------------------------------------------------------
# Permutation function
def perm(inputByte, permTable):
outputByte = 0
for index, elem in enumerate(permTable):
if index >= elem:
outputByte |= (inputByte & (128 >> (elem - 1))) >> (index - (elem - 1))
else:
outputByte |= (inputByte & (128 >> (elem - 1))) << ((elem - 1) - index)
return outputByte
# Initial permutation
def ip(inputByte):
return perm(inputByte, IPtable)
# Final permutation
def fp(inputByte):
return perm(inputByte, FPtable)
# Swap nibbles
def swapNibbles(inputByte):
return (inputByte << 4 | inputByte >> 4) & 0xff
# Key Generation
def keyGen(key):
def leftShift(keyBitList):
shiftedKey = [None] * 10
shiftedKey[0:9] = keyBitList[1:10]
shiftedKey[4] = keyBitList[0]
shiftedKey[9] = keyBitList[5]
return shiftedKey
subKey1 = subKey2 = 0
for index, elem in enumerate(P8table):
subKey1 += (128 >> index) * shiftedOnceKey[elem - 1]
subKey2 += (128 >> index) * shiftedTwiceKey[elem - 1]
# Feistel function
def fk(subKey, inputData):
def F(sKey, rightNibble):
aux = sKey ^ perm(swapNibbles(rightNibble), EPtable)
index1 = ((aux & 0x80) >> 4) + ((aux & 0x40) >> 5) + ((aux & 0x20) >> 5) + ((aux & 0x10) >> 2)
index2 = ((aux & 0x08) >> 0) + ((aux & 0x04) >> 1) + ((aux & 0x02) >> 1) + ((aux & 0x01) << 2)
sboxOutputs = swapNibbles((S0table[index1] << 2) + S1table[index2])
return perm(sboxOutputs, P4table)
# Encrypt function
def encrypt(key, plaintext):
data = fk(keyGen(key)[0], ip(plaintext))
return fp(fk(keyGen(key)[1], swapNibbles(data)))
# Example usage
plaintext = 0b10101010
key = 0b1110001110
cipher = encrypt(key, plaintext)
print(f"Plaintext: {bin(plaintext)}")
print(f"Ciphertext: {bin(cipher)}")
—---------------------------------------------------------------------------------------------------------
6 b) s-des decrypt
# Permutation function
def perm(inputByte, permTable):
outputByte = 0
for index, elem in enumerate(permTable):
if index >= elem:
outputByte |= (inputByte & (128 >> (elem - 1))) >> (index - (elem - 1))
else:
outputByte |= (inputByte & (128 >> (elem - 1))) << ((elem - 1) - index)
return outputByte
# Initial permutation
def ip(inputByte):
return perm(inputByte, IPtable)
# Final permutation
def fp(inputByte):
return perm(inputByte, FPtable)
# Swap nibbles
def swapNibbles(inputByte):
return (inputByte << 4 | inputByte >> 4) & 0xff
# Key Generation
def keyGen(key):
def leftShift(keyBitList):
shiftedKey = [None] * 10
shiftedKey[0:9] = keyBitList[1:10]
shiftedKey[4] = keyBitList[0]
shiftedKey[9] = keyBitList[5]
return shiftedKey
subKey1 = subKey2 = 0
for index, elem in enumerate(P8table):
subKey1 += (128 >> index) * shiftedOnceKey[elem - 1]
subKey2 += (128 >> index) * shiftedTwiceKey[elem - 1]
# Feistel function
def fk(subKey, inputData):
def F(sKey, rightNibble):
aux = sKey ^ perm(swapNibbles(rightNibble), EPtable)
index1 = ((aux & 0x80) >> 4) + ((aux & 0x40) >> 5) + ((aux & 0x20) >> 5) + ((aux & 0x10) >> 2)
index2 = ((aux & 0x08) >> 0) + ((aux & 0x04) >> 1) + ((aux & 0x02) >> 1) + ((aux & 0x01) << 2)
sboxOutputs = swapNibbles((S0table[index1] << 2) + S1table[index2])
return perm(sboxOutputs, P4table)
# Decrypt function
def decrypt(key, ciphertext):
data = fk(keyGen(key)[1], ip(ciphertext))
return fp(fk(keyGen(key)[0], swapNibbles(data)))
***Not recommended***
plaintext = 0b10101010
subKey1 = 0b11101110
subKey2 = 0b11001111