Skip to content

Instantly share code, notes, and snippets.

@NielsdeWaal
Created March 13, 2017 18:10
Show Gist options
  • Save NielsdeWaal/757d259ede768362cf032164cac885d2 to your computer and use it in GitHub Desktop.
Save NielsdeWaal/757d259ede768362cf032164cac885d2 to your computer and use it in GitHub Desktop.
def randomBinaryKey():
states = ['0', '1']
key = ""
check = 1
while check:
for state in range(8):
key += random.choice(states)
testText = "Hello World"
expKey = keyExpansion(key)
keyList = createSubKeys(expKey)
plaintext = convertStringToBinaryStringList(testText)
ciphertext = encrypt(plaintext, keyList)
plaintext = decrypt(ciphertext, keyList)
plaintext = restorePlainText(plaintext)
if plaintext == testText:
check = 0
else:
key = ""
return key
def keyExpansion(key):
"""Breid de key uit van 8 bits naar 256 bits
De input key word verlengd door elke andere bit te kopieëren naar de meest significante positie
Args:
key: string van een 8 bit getal
Returns:
newkey: nieuwe verlengde key, string van 256 bit binary getal
"""
newKey = ""
inputKeyLen = len(key)
for number in range((inputKeyLen - 1), 0, -2):
newKey += key[number]
for number in range(0, inputKeyLen):
newKey += key[number]
multiplier = 256
while len(newKey) < 256:
inputKeyLen = len(newKey)
tempKey = newKey
newKey = ""
for number in range((inputKeyLen - 1), 0, -2):
newKey += tempKey[number]
for number in range(0, inputKeyLen):
newKey += tempKey[number]
newKey = newKey[:multiplier]
return newKey
def createSubKeys(key):
"""Creeert de sub keys voor het Feistel network
De input key word gebruikt om 32 sub keys te genereren. De input key word eerst opgesplits in 32 losse delen, hierna worden 4 keys
gemaakt van de eerste bit uit elke losse key en om de 4 keys. Dit word herhaald voor alle 8 bits per key. Dit voor betere
permutatie.
Args:
key: 256 bit binary string
Returns:
keyList: lijst die de nieuwe subkeys bevat
"""
keyList = []
keyBlocks = []
for keyBlock in range(0, 256, 8):
keyBlocks.append(key[keyBlock:keyBlock + 8])
for keyNumber in range(0, 8):
block1 = keyBlocks[0][keyNumber] + keyBlocks[4][keyNumber] + keyBlocks[8][keyNumber] + keyBlocks[12][
keyNumber] + keyBlocks[16][keyNumber] + keyBlocks[20][keyNumber] + keyBlocks[24][keyNumber] + keyBlocks[28][
keyNumber]
block2 = keyBlocks[1][keyNumber] + keyBlocks[5][keyNumber] + keyBlocks[9][keyNumber] + keyBlocks[13][
keyNumber] + keyBlocks[17][keyNumber] + keyBlocks[21][keyNumber] + keyBlocks[25][keyNumber] + keyBlocks[29][
keyNumber]
block3 = keyBlocks[2][keyNumber] + keyBlocks[6][keyNumber] + keyBlocks[10][keyNumber] + keyBlocks[14][
keyNumber] + keyBlocks[18][keyNumber] + keyBlocks[22][keyNumber] + keyBlocks[26][keyNumber] + keyBlocks[30][
keyNumber]
block4 = keyBlocks[3][keyNumber] + keyBlocks[7][keyNumber] + keyBlocks[11][keyNumber] + keyBlocks[15][
keyNumber] + keyBlocks[19][keyNumber] + keyBlocks[23][keyNumber] + keyBlocks[27][keyNumber] + keyBlocks[31][
keyNumber]
keyList.append(block1)
keyList.append(block2)
keyList.append(block3)
keyList.append(block4)
return keyList
def stringXOR(string1, string2):
"""XOR'ed 2 binary strings
De 2 imput strings worden omgezet naar binary en geXOR'ed en in een list gezet. Hierna word deze list weer samengevoegd
Args:
string1: eerste binary string
string2: tweede binary string
Returns:
newString: resultaat van de XOR tussen string1 en string2
"""
result = [ord(a) ^ ord(b) for a, b in zip(string1, string2)]
newString = ""
for item in result:
newString += str(item)
return newString
def feistelRound(data1, data2, subKey):
"""De Feistel ronde, deze word gebruikt voor de encryptie in het Feistel netwerk
In de ronde worden twee stukken data (e.g linkerhelf en rechterhelf van het blok) geXOR'ed. Eerst word de rechterhelft geXOR'ed met de subkey voor de huidige ronde. Als laatste worden de linker en rechter helft geswitched. (data1 ^ (subKey ^ data2))
Args:
data1: de linkerhelft van de data blok
data2: de rechterhelft van de data blok
Returns:
data1: wat eerst de rechterhelft was van de data blok
data2: het resultaat van de XOR tussen de linkerhelf, rechterhelft en de subkey
"""
firstXOR = stringXOR(subKey, data2)
result = stringXOR(data1, firstXOR)
data1 = data2
data2 = result
return data1, data2
def convertStringToBinaryStringList(data):
"""Zet een string van willekeurige karacters om in een lijst van binaire getallen
Leest de ingevoerde string karacter voor karacter en vormt van elk van deze een binair getal en voegd deze samen in een lijst
Args:
data: de string die moet worden omgezet naar een lijst van binaire getallen
Returns:
lijst van binaire getallen
"""
return (' '.join('{0:08b}'.format(ord(character), 'b') for character in data)).split()
def encrypt(data, subKeyList):
"""Encrypt de data volgens het Feistel network
Zet de ingevoerde data om in blokken en splits deze. Deze helfden gaan 32 keer door de Feistel ronde. Als laatste worden ze weer
samengevoegd in een lijst voor de ciphertekst.
Args:
data: lijst van binaire strings die de te encrypte data voorstelt
subKeyList: lijst met de subKeys die eerder al gegenereerd zijn
Returns:
cipherList: lijst van de bewerkte binaire getallen
"""
listOfKeys = subKeyList
cipherList = []
for item in data:
leftBlock = str(item[:4])
rightBlock = str(item[4:])
for subKey in listOfKeys:
leftBlock, rightBlock = feistelRound(leftBlock, rightBlock, subKey)
cipherList.append(str(leftBlock) + str(rightBlock))
return cipherList
def decrypt(data, subKeyList):
"""Decrypt de data volgens het Feistel network
Zet de ingevoerde data om in blokken en splits deze. Deze helfden gaan 32 keer door de Feistel ronde. Als laatste worden ze weer
samengevoegd in een lijst voor de ciphertekst.
Args:
data: lijst van binaire strings die de te decrypte data voorstelt
subKeyList: lijst met de subKeys die eerder al gegenereerd zijn
Returns:
cipherList: lijst van de bewerkte binaire getallen
"""
listOfKeys = subKeyList
plainList = []
for item in data:
leftBlock = str(item[:4])
rightBlock = str(item[4:])
for subKey in listOfKeys:
rightBlock, leftBlock = feistelRound(rightBlock, leftBlock, subKey)
plainList.append(str(leftBlock) + str(rightBlock))
return plainList
def restorePlainText(data):
"""Zet een lijst van binaire getallen terug om naar een string
Er word door de ingevoerde lijst gelopen en elke binaire string word terug omgezet in een unicode karacter.
Args:
data: de lijst met de binaire getallen die moeten worden teruggezet
Returns:
de lijst die is samengevoegd tot 1 string.
"""
plaintextList = []
for item in data:
temp = chr(int(item, 2))
plaintextList.append(temp)
return ''.join(plaintextList)
string = input("Text to be encrypted: ")
key = randomBinaryKey()
colorCode = generateColorCodeFromKey(key)
print(colorCode)
# print(key)
expKey = keyExpansion(key)
keyList = createSubKeys(expKey)
# print(keyList)
plaintext = convertStringToBinaryStringList(string)
ciphertext = encrypt(plaintext, keyList)
# print(ciphertext)
plaintext = decrypt(ciphertext, keyList)
# print(plaintext)
print(restorePlainText(plaintext))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment