728x90
import random as r #키값 생성을 위한 랜덤모듈
def sdes_genkey(): #키 생성 함수
key = [] #키
for i in range(0, 9): #키의 개수가 9개
key.append(r.randint(0, 1)) #랜덤하게 키를 받음
return key #키 반환
def sdes_encrypt(key, pblock): #암호화 함수
Rblock = pblock[6:] #오른쪽 블록
Lblock = pblock[0:6] #왼쪽 블록
for i in range(0, 3): #simple DES이므로 3번의 사이클로 구성
exRblock = expander(Rblock) #블록 8비트로 확장
usekey = keygenerator(key, i) #8비트 키 생성
result = XOR(exRblock, key) #키와 확장한 블록을 XOR함
resultLeft = result[0:4] #결과의 왼쪽 블록
resultRight = result[4:] #결과의 오른쪽 블록
funcResult = SBox(resultLeft, resultRight) #왼쪽, 오른쪽 블록의 비트에 해당하는 SBOX값
if i == 2: #만약 마지막 사이클이라면
Lblock, Rblock = XOR(funcResult, Lblock), Rblock #교환하지 않음
else: #마지막 사이클이 아니라면
Rblock, Lblock = XOR(funcResult, Lblock), Rblock #교환
return Lblock+Rblock #완성된 암호문 반환
def sdes_decrypt(key, cblock): #복호화 함수
Rblock = cblock[6:] #오른쪽 블록
Lblock = cblock[0:6] #왼쪽 블록
for i in range(0, 3): #simple DES이므로 3번의 사이클로 구성
exRblock = expander(Rblock) #블록 8비트로 확장
usekey = keygenerator(key, i) #8비트 키 생성
result = XOR(exRblock, key) #키와 확장한 블록을 XOR함
resultLeft = result[0:4] #결과의 왼쪽 블록
resultRight = result[4:] #결과의 오른쪽 블록
funcResult = SBox(resultLeft, resultRight) #왼쪽, 오른쪽 블록의 비트에 해당하는 SBOX값
if i == 2: #만약 마지막 사이클이라면
Lblock, Rblock = XOR(funcResult, Lblock), Rblock #교환하지 않음
else: #마지막 사이클이 아니라면
Rblock, Lblock = XOR(funcResult, Lblock), Rblock #교환
return Lblock+Rblock #완성된 암호문 반환
def expander(block): #확장 함수
result = [] #확장된 결과
result.append(block[0])
result.append(block[1])
result.append(block[3])
result.append(block[2])
result.append(block[3])
result.append(block[2])
result.append(block[4])
result.append(block[5])
#123456의 블록을 12434356으로 확장함
return result #결과 반환
def keygenerator(key, n): #키 생성
usekey = [] #사용할 8비트 키
for i in range(0, 8): #8번 반복
if n == len(key): #만약 마지막 키에 도달했다면
n = 0 #처음 키로 돌아가 다시 생성
usekey.append(key[n]) #사용할 키 등록
n += 1 #다음 키를 들고 오기 위한 증가
return usekey #사용할 8비트 키 반환
def XOR(block1, block2): #XOR연산(단, 이는 ^연산자를 사용하지 않음)
result = [] #연산 결과
for i in range(0, len(block1)): #XOR할 대상의 크기 만큼 반복
if block1[i] == block2[i]: #만약 두 비트가 같다면
result.append(0) #0 저장
else: #만약 두 비트가 다르다면
result.append(1) #1저장
return result #연산 결과 반
def SBox(left, right): #SBOX값으로 변환하는 함수
leftpos = 0 #왼쪽 블록의 오른쪽 3비트의 10진
rightpos = 0 #오른쪽 블록의 오른쪽 3비트의 10진
value = 1
sbox1 = [[[1,0,1], [0,1,0], [0,0,1], [1,1,0], [0,1,1], [1,0,0], [1,1,1], [0,0,0]],
[[0,0,1], [1,0,0], [1,1,0], [0,1,0], [0,0,0], [1,1,1], [1,0,1], [0,1,1]]] #sbox1의 형태
sbox2 = [[[1,0,0], [0,0,0], [1,1,0], [1,0,1], [1,1,1], [0,0,1], [0,1,1], [0,1,0]],
[[1,0,1], [0,1,1], [0,0,0], [1,1,1], [1,1,0], [0,1,0], [0,0,1], [1,0,0]]] #sbox2의 형태
for i in reversed(range(1, 4)): #3, 2, 1순서로 반복
if left[i] == 1: #만약 비트가 1이라면
leftpos += value #value값 더하기
if right[i] == 1: #만약 비트가 1이라면
rightpos += value #value값 더하기
value *= 2 #value값에 2 곱하기(2진수 표현을 하기 위함)
return sbox1[left[0]][leftpos]+sbox2[right[0]][rightpos] #반환된 SBOX값 반환
728x90
'Sejong University > Symmetric-key cryptography' 카테고리의 다른 글
CBC mode (0) | 2022.04.23 |
---|---|
Classic Cipher (0) | 2022.04.23 |
Histogram for Character Frequency (0) | 2022.04.23 |
댓글