Samplified DES - ECB, CBC, OFB

Min-Jae Song·2020년 5월 25일
0
EP = [4,1,2,3,2,3,4,1]
S0 = [[1,0,3,2],[3,2,1,0],[0,2,1,3],[3,1,3,2]]
S1 = [[0,1,2,3],[2,0,1,3],[3,0,1,0],[2,1,0,3]]
P4 = [2,4,3,1]
P10 = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
P8 = [6, 3, 7, 4, 8, 5, 10, 9]
IP_1 = [4,1,3,5,7,2,8,6]
IP = [2, 6, 3, 1, 4, 8, 5, 7]
IV = "01010101"
KEY = "0101010101"
pt1 = "happy poppy"
pt2 = "SMJ"

def str_to_8bit(s):
    str_list = []
    for i in s:
        str_list.append(bin(ord(i))[2:].zfill(8))
    return str_list

def bit_to_str(list_b):
    str_list = []
    for i in list_b:
        str_list.append(chr(int(i,2)))
    return "".join(str_list)

def shift_left(n, d, length):
    result = ((n<<d) & (2**length -1)) | (n>>(length - d))
    return result

def key_generator(key):
    #P10(key)
    p10 = [0] * len(P10)
    n = 0
    for i in P10:
        p10[n] = key[i-1]
        n+=1 
    p10_key = ''.join(p10)
    
    #key1 = P8(LS-1(P10(key)))
    c1 = p10_key[:5]
    d1 = p10_key[5:]
    
    #leftshift
    ls1_c = bin(shift_left(int(c1,2), 1, len(c1)))[2:].zfill(5)
    ls1_d = bin(shift_left(int(d1,2), 1, len(d1)))[2:].zfill(5)
    ls1_key = ls1_c + ls1_d
    
    #P8, Key1 generator
    p8 = [0] * len(P8)
    n = 0
    for i in P8:
        p8[n] = ls1_key[i-1]
        n+=1
    key1 = ''.join(p8)
    
    ls2_c = bin(shift_left(int(ls1_c,2), 2, len(ls1_c)))[2:].zfill(5)
    ls2_d = bin(shift_left(int(ls1_d,2), 2, len(ls1_d)))[2:].zfill(5)
    ls2_key = ls2_c + ls2_d
    
    p8 = [0] * len(P8)
    n = 0
    for i in P8:
        p8[n] = ls2_key[i-1]
        n+=1
    key2 = ''.join(p8)
    
    return [key1, key2]
    
def decryption(cipher, key1, key2):
    
    #IP(cipher)
    ip_list = [0]*len(IP)
    n=0
    for i in IP:
        ip_list[n] = cipher[i-1]
        n+=1
    ip = ''.join(ip_list)

    l2 = ip[:4]
    r2 = ip[4:]
    #swap
    r1 = bin(int(l2,2) ^ int(func(r2,key2),2))[2:].zfill(4)
    l1 = r2
    r0 = r1
    l0 = bin(int(l1,2)^ int(func(r1,key1),2))[2:].zfill(4)
    
    lr = l0+r0
    
    pt_list = [0]*len(IP_1)
    n=0
    for i in IP_1:
        pt_list[n] = lr[i-1]
        n+=1
    pt= ''.join(pt_list)
    
    return pt

def encryption(pt, key1, key2):
    ip_list = [0]*len(IP)
    n=0
    for i in IP:
        ip_list[n] = pt[i-1]
        n+=1
    ip = ''.join(ip_list)
    l0 = ip[:4]
    r0 = ip[4:]
    r1 = r0
    l1 = bin(int(l0,2) ^ int(func(r0,key1),2))[2:].zfill(4)
    #swqp 
    l2 = r1
    r2 = l1
    r3 = r2
    l3 = bin(int(l2,2) ^ int(func(r2,key2),2))[2:].zfill(4)
    lr_1 = l3+r3
    pt_list = [0]*len(IP_1)
    n=0
    for i in IP_1:
        pt_list[n] = lr_1[i-1]
        n+=1
    cipher= ''.join(pt_list)
    
    return cipher

def func(r, key):
    ep_text = [0]*len(EP)
    n=0
    for i in EP:
        ep_text[n] = r[i-1]
        n+=1
    ep_r= ''.join(ep_text)
    ep_r_key = bin(int(ep_r, 2) ^ int(key, 2))[2:].zfill(8)
    
    bit_array = []
    n=0
    for i in ep_r_key:
        bit_array.append(i)
        if(n==3):
            row = int("0b"+bit_array[0]+bit_array[3],2)
            col = int("0b"+bit_array[1]+bit_array[2],2)
            s_0 = bin(S0[row][col])[2:].zfill(2)
            bit_array = []
        if(n==7):
            row = int("0b"+bit_array[0]+bit_array[3],2)
            col = int("0b"+bit_array[1]+bit_array[2],2)
            s_1 = bin(S1[row][col])[2:].zfill(2)
        n+=1    
    s = s_0+s_1
    
    p4_list = [0]*len(P4)
    n=0
    for i in P4:
        p4_list[n] = s[i-1]
        n+=1
    p4 = ''.join(p4_list)
    
    return p4
    
    class ECBmode:
    def __init__(self, pt, key):
        self.pt = pt
        self.key = key
        self.pt_list = str_to_8bit(self.pt)
        self.k1, self.k2 = key_generator(self.key)
    def encryption(self):
        cipher_list = []
        for i in self.pt_list:
            cipher_list.append(encryption(i, self.k1, self.k2))    
        return cipher_list
    
    def decryption(self, cipher):
        pt_list = []
        for i in cipher:
            pt = decryption(i,self.k1,self.k2)
            pt_list.append(pt)
        pt_str = bit_to_str(pt_list)
        return pt_str

print("===========initialize ECB=================")
print("plainText ::",pt1,"   key ::", KEY)
ecb = ECBmode(pt1, KEY)
print("Activate Encrpytion!!")
cipher = ecb.encryption()
print("cipherText ::",cipher)
print("Activate Decryption!!")
print("plainText ::",ecb.decryption(cipher))

print("===========initialize ECB=================")
print("plainText ::",pt2,"   key ::", KEY)
ecb = ECBmode(pt2, KEY)
print("Activate Encrpytion!!")
cipher = ecb.encryption()
print("cipherText ::",cipher)
print("Activate Decryption!!")
print("plainText ::",ecb.decryption(cipher))

class CBCmode:
    def __init__(self, pt, key):
        self.pt = pt
        self.key = key
        self.pt_list = str_to_8bit(self.pt)
        self.k1, self.k2 = key_generator(self.key)
        self.iv = int(IV,2)
        
    def encryption(self):
        cipher_list = []
        iv = self.iv
        for i in self.pt_list:
            pt = bin(iv ^ int(i,2))[2:].zfill(8)
            cipher = encryption(pt,self.k1,self.k2)
            iv = int(cipher,2)
            cipher_list.append(cipher)
        return cipher_list
    
    def decryption(self, cipher):
        pt_list = []
        iv = self.iv
        for i in cipher:
            decrypt = decryption(i,self.k1,self.k2)
            pt = bin(iv^int(decrypt,2))[2:].zfill(8)
            iv = int(i,2)
            pt_list.append(pt)
        pt_str = bit_to_str(pt_list)
        return pt_str
        
print("===========initialize CBC=================")
print("plainText ::",pt1,"   key ::", KEY)
cbc = CBCmode(pt1, KEY)
print("Activate Encrpytion!!")
cipher = cbc.encryption()
print("cipherText ::",cipher)
print("Activate Decryption!!")
print("plainText ::",cbc.decryption(cipher))
print("===========initialize CBC=================")
print("plainText ::",pt2,"   key ::", KEY)
cbc = CBCmode(pt2, KEY)
print("Activate Encrpytion!!")
cipher = cbc.encryption()
print("cipherText ::",cipher)
print("Activate Decryption!!")
print("plainText ::",cbc.decryption(cipher))

class OFBmode:
    def __init__(self, pt, key):
        self.pt = pt
        self.key = key
        self.pt_list = str_to_8bit(self.pt)
        self.k1, self.k2 = key_generator(self.key)
        self.iv = int(IV,2)
        
    def encryption(self):
        iv = IV
        cipher_list = []
        for i in self.pt_list:
            iv = encryption(iv, self.k1, self.k2)
            cipher = bin(int(iv,2) ^ int(i,2))[2:].zfill(8)
            cipher_list.append(cipher)
        return cipher_list
    
    def decryption(self, cipher):
        iv = IV
        plain_list = []
        for i in cipher:
            iv = encryption(iv, self.k1, self.k2)
            pt = bin(int(iv,2) ^ int(i,2))[2:].zfill(8)
            plain_list.append(pt)
        pt_str = bit_to_str(plain_list)
        return pt_str

  
print("===========initialize OFB=================")
print("plainText ::",pt1,"   key ::", KEY)
ofb = OFBmode(pt1, KEY)
print("Activate Encrpytion!!")
cipher = ofb.encryption()
print("cipherText ::",cipher)
print("Activate Decryption!!")
print("plainText ::", ofb.decryption(cipher))
print("===========initialize OFB=================")
print("plainText ::",pt2,"   key ::", KEY)
ofb = OFBmode(pt2, KEY)
print("Activate Encrpytion!!")
cipher = ofb.encryption()
print("cipherText ::",cipher)
print("Activate Decryption!!")
print("plainText ::", ofb.decryption(cipher))
profile
개발세발스토오리

0개의 댓글