Last active
June 15, 2017 18:36
-
-
Save ibarrajo/efae4dd356906255fae2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from copy import copy | |
class AES: | |
def __init__(self, blocksize, key): | |
# verify that the key is the right size | |
assert len(key) == (blocksize / 8) | |
self.key = key | |
# 10 cycles for 128-bit keys | |
# 12 cycles for 192-bit keys | |
# 14 cycles for 256-bit keys | |
self.blocksize = blocksize | |
if blocksize == 128: | |
self.aesCycles = 10 | |
elif blocksize == 192: | |
self.aesCycles = 12 | |
elif blocksize == 256: | |
self.aesCycles = 14 | |
else: | |
assert False, 'Invalid blocksize given to AES(blocksize, key)' | |
# list of states | |
self.states = [] | |
# create Rijndael's key schedule | |
self.RKS = self.makeKeys(key) | |
#print('RKS',''.join(map(lambda b: format(b, '02x'), self.RKS)).upper()) | |
#print(self.RKS) | |
#print('key',key) | |
# print("set block size to %s" % blocksize) | |
# print("set key to %s" % key) | |
def encrypt(self, data): | |
''' | |
The encrypt function runs the encryption rounds (doAES(state)) for each | |
state that exists. | |
''' | |
#data = bytearray(data, 'utf-8') | |
self.states = self.chunk(data) | |
encrypted = [] | |
for state in self.states: | |
encrypted.extend(self.doAES(state)) | |
return encrypted | |
def decrypt(self, data): | |
self.states = self.chunk(data) | |
decrypted = [] | |
for state in self.states: | |
decrypted.extend(self.undoAES(state)) | |
return decrypted | |
def chunk(self, data): | |
''' | |
splits the data (string) into chunks and on the last step it converts it | |
into the byte/int array | |
''' | |
n = {128:16, 192:24, 256:32}[self.blocksize] | |
states = [data[i:i + n] for i in range(0, len(data), n)] | |
# pad the data as needed on the last state | |
for x in range(n): | |
try: | |
states[len(states) - 1][x] = states[len(states) - 1][x] | |
except IndexError: | |
states[len(states) - 1].extend([0x00]) | |
return states | |
def doAES(self, state): | |
# to bytes | |
key = self.getRoundKey(0) | |
# initial round | |
state = self.addRoundKey(state, key) | |
# rounds | |
for c in range(1, self.aesCycles): | |
key = self.getRoundKey(c) | |
state = self.subBytes(state) | |
state = self.shiftRows(state) | |
state = self.mixColumns(state) | |
state = self.addRoundKey(state, key) | |
# final round | |
key = self.getRoundKey(self.aesCycles) | |
state = self.subBytes(state) | |
state = self.shiftRows(state) | |
state = self.addRoundKey(state, key) | |
return state | |
def undoAES(self, state): | |
''' | |
Does exactly the same rounds as doAES() just in reverse | |
''' | |
key = self.getRoundKey(self.aesCycles) | |
state = self.addRoundKey(state, key) | |
state = self.shiftRowsInverse(state) | |
state = self.subBytesInverse(state) | |
for c in range(self.aesCycles - 1, 0, -1): | |
key = self.getRoundKey(c) | |
state = self.addRoundKey(state, key) | |
state = self.mixColumnsInverse(state) | |
state = self.shiftRowsInverse(state) | |
state = self.subBytesInverse(state) | |
key = self.getRoundKey(0) | |
state = self.addRoundKey(state, key) | |
return state | |
def keyScheduleCore(self, bytes, rcon): | |
# rotate 1 byte to the left | |
bytes = bytes[1:] + bytes[0:1] | |
# apply sbox substitution on all bytes of word | |
bytes = [self.RijndaelSTable[bytes[i]] for i in [0,1,2,3]] | |
''' | |
On just the first (leftmost) byte of the output word, exclusive OR the byte | |
with 2 to the power of (i-1). In other words, perform the rcon operation | |
with i as the input, and exclusive or the rcon output with the first byte of | |
the output word | |
''' | |
bytes[0] = bytes[0] ^ self.RCON[rcon] | |
return bytes | |
def makeKeys(self, key): | |
''' | |
Generates Rijndale's key schedule | |
source: https://en.wikipedia.org/wiki/Rijndael_key_schedule | |
''' | |
keylen = len(key) | |
n = {128:16, 192:24, 256:32}[self.blocksize] | |
# get the b valuees for the corresponding key size | |
b = {128:176, 192:208, 256:240}[self.blocksize] | |
RKS = [] | |
# the first part of the RKS is the key | |
RKS.extend(key) | |
size = keylen | |
rcon = 1 | |
# create the required key length | |
while size != b: | |
assert size <= b, 'Impossible key schedule, something is wrong.. size is %s max is %s' % (size, b) | |
# create a 4 byte temporary variable | |
t = [0,0,0,0] | |
# assign previous 4 bytes to the temporary storage t | |
t = RKS[(size - 4):] | |
# perform key schedule core on t with rcon as the iteration value | |
t = self.keyScheduleCore(t, rcon) | |
# increment rcon | |
rcon += 1 | |
# We exclusive-OR t with the four-byte block n bytes before the new expanded key. | |
t = [x ^ y for x,y in zip(t, RKS[(size - n):(size - n + 4)])] | |
# This becomes the next 4 bytes in the expanded key | |
RKS.extend(t) | |
size += 4 | |
# do the following three times to create the next twelve bytes | |
for i in [0,1,2]: | |
# assign previous 4 bytes to the temporary storage t | |
t = RKS[(size - 4):] | |
# We exclusive-OR t with the four-byte block n bytes before the new expanded key. | |
t = [x ^ y for x,y in zip(t, RKS[(size - n):(size - n + 4)])] | |
# This becomes the next 4 bytes in the expanded key | |
RKS.extend(t) | |
size += 4 | |
# We then do the following three times to create the next twelve bytes of expanded key | |
if self.blocksize == 256: | |
# assign previous 4 bytes to the temporary storage t | |
t = RKS[(size - 4):] | |
# We run each of the 4 bytes in t through Rijndael's S-box | |
t = [self.RijndaelSTable[t[i]] for i in [0,1,2,3]] | |
# We exclusive-OR t with the four-byte block n bytes before the new expanded key. | |
t = [x ^ y for x,y in zip(t, RKS[(size - n):(size - n + 4)])] | |
# This becomes the next 4 bytes in the expanded key | |
RKS.extend(t) | |
size += 4 | |
# If we are processing a 128-bit key, we do not perform the following steps. | |
# If we are processing a 192-bit key, we run the following steps twice. | |
# If we are processing a 256-bit key, we run the following steps three times | |
for i in range({128:0, 192:2, 256:3}[self.blocksize]): | |
# assign previous 4 bytes to the temporary storage t | |
t = RKS[(size - 4):] | |
# We exclusive-OR t with the four-byte block n bytes before the new expanded key. | |
t = [x ^ y for x,y in zip(t, RKS[(size - n):(size - n + 4)])] | |
# This becomes the next 4 bytes in the expanded key | |
RKS.extend(t) | |
size += 4 | |
return RKS | |
def getRoundKey(self, round): | |
# return the round key from Rijndael's Key Schedule | |
# that was generated with makeKeys() | |
key = [0] * (self.blocksize / 8) | |
for i in range(4): | |
for k in range(4): | |
key[k*4+i] = self.RKS[round + i*4 + k] | |
return key | |
#return self.RKS[(round*16):((round*16)+16)] | |
def addRoundKey(self, state, key): | |
''' | |
each byte of the state is combined with a block of the round key using | |
bitwise xor | |
''' | |
return [x ^ y for x,y in zip(state, key)] | |
def subBytes(self, state): | |
''' | |
a non-linear substitution step where each byte is replaced with another | |
according to RijndaelSTable. | |
''' | |
#for i, b in enumerate(state): | |
# state[i] = self.RijndaelSTable[ord(b)] | |
return map(lambda x: self.RijndaelSTable[x] , state) | |
def subBytesInverse(self, state): | |
''' | |
a non-linear substitution step where each byte is replaced with another | |
according to RijndaelSTableInverse. | |
''' | |
return map(lambda x: self.RijndaelSTableInverse[x] , state) | |
def shiftRows(self, s): | |
''' | |
a transposition step where the last three rows of the state are shifted | |
cyclically left by 0, 1, 2 and 3 for each corresponding row. | |
''' | |
state = [ | |
s[0],s[5],s[10],s[15], | |
s[4],s[9],s[14],s[3], | |
s[8],s[13],s[2],s[7], | |
s[12],s[1],s[6],s[11]] | |
return state | |
# for i in [0,1,2,3]: | |
# s[i*4:i*4+4] = (s[i*4:i*4+4])[i:] + (s[i*4:i*4+4])[0:i] | |
# return s | |
# r = [] | |
# print(state) | |
# for i in [0,1,2,3]: | |
# r.extend(state[i::4]) | |
# r[i] = r[i][i:] + r[i][:i] | |
# return [i[column] for column in [0,1,2,3] for i in r] | |
def shiftRowsInverse(self, s): | |
''' | |
Transposition step where the last three rows of the state are | |
shifted cyclically right by 0, 1, 2 and 3 for each corresponding row | |
''' | |
# for i in [0,1,2,3]: | |
# s[i*4:i*4+4] = (s[-i*4:-i*4+4])[-i:] + (s[-i*4:-i*4+4])[0:-i] | |
# return s | |
state = [ | |
s[0],s[13],s[10],s[7], | |
s[4],s[1],s[14],s[11], | |
s[8],s[5],s[2],s[15], | |
s[12],s[9],s[6],s[3]] | |
return state | |
def mixColumns(self, state): | |
''' | |
a mixing operation which operates on the columns of the state, combining the | |
four bytes in each column. | |
Source: https://en.wikipedia.org/wiki/Rijndael_mix_columns | |
''' | |
for i in [0,1,2,3]: | |
t = c = [0,0,0,0] | |
for j in [0,1,2,3]: | |
c[j] = state[j*4+i] | |
t[0] = self.GMT02[c[0]] ^ self.GMT03[c[1]] ^ c[2] ^ c[3] | |
t[1] = c[0] ^ self.GMT02[c[1]] ^ self.GMT03[c[2]] ^ c[3] | |
t[2] = c[0] ^ c[1] ^ self.GMT02[c[2]] ^ self.GMT03[c[3]] | |
t[3] = self.GMT03[c[0]] ^ c[1] ^ c[2] ^ self.GMT02[c[3]] | |
for j in [0,1,2,3]: | |
state[j*4+i] = t[j] | |
return state | |
def mixColumnsInverse(self, state): | |
''' | |
a mixing operation which operates on the columns of the state, combining the | |
four bytes in each column. | |
Source: https://en.wikipedia.org/wiki/Rijndael_mix_columns | |
''' | |
for i in [0,1,2,3]: | |
t = c = [0,0,0,0] | |
for j in [0,1,2,3]: | |
c[j] = state[j*4+i] | |
t[0] = self.GMT0E[c[0]] ^ self.GMT0B[c[1]] ^ self.GMT0D[c[2]] ^ self.GMT09[c[3]] | |
t[1] = self.GMT09[c[0]] ^ self.GMT0E[c[1]] ^ self.GMT0B[c[2]] ^ self.GMT0D[c[3]] | |
t[2] = self.GMT0D[c[0]] ^ self.GMT09[c[1]] ^ self.GMT0E[c[2]] ^ self.GMT0B[c[3]] | |
t[3] = self.GMT0B[c[0]] ^ self.GMT0D[c[1]] ^ self.GMT09[c[2]] ^ self.GMT0E[c[3]] | |
for j in [0,1,2,3]: | |
state[j*4+i] = t[j] | |
return state | |
# source: https://en.wikipedia.org/wiki/Rijndael_S-box | |
# optimize the values to a simple lookup | |
RijndaelSTable = [ | |
0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76, | |
0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0, | |
0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15, | |
0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75, | |
0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84, | |
0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF, | |
0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8, | |
0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2, | |
0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73, | |
0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB, | |
0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79, | |
0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08, | |
0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A, | |
0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E, | |
0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF, | |
0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16 | |
] | |
RijndaelSTableInverse = [ | |
0x52,0x09,0x6A,0xD5,0x30,0x36,0xA5,0x38,0xBF,0x40,0xA3,0x9E,0x81,0xF3,0xD7,0xFB, | |
0x7C,0xE3,0x39,0x82,0x9B,0x2F,0xFF,0x87,0x34,0x8E,0x43,0x44,0xC4,0xDE,0xE9,0xCB, | |
0x54,0x7B,0x94,0x32,0xA6,0xC2,0x23,0x3D,0xEE,0x4C,0x95,0x0B,0x42,0xFA,0xC3,0x4E, | |
0x08,0x2E,0xA1,0x66,0x28,0xD9,0x24,0xB2,0x76,0x5B,0xA2,0x49,0x6D,0x8B,0xD1,0x25, | |
0x72,0xF8,0xF6,0x64,0x86,0x68,0x98,0x16,0xD4,0xA4,0x5C,0xCC,0x5D,0x65,0xB6,0x92, | |
0x6C,0x70,0x48,0x50,0xFD,0xED,0xB9,0xDA,0x5E,0x15,0x46,0x57,0xA7,0x8D,0x9D,0x84, | |
0x90,0xD8,0xAB,0x00,0x8C,0xBC,0xD3,0x0A,0xF7,0xE4,0x58,0x05,0xB8,0xB3,0x45,0x06, | |
0xD0,0x2C,0x1E,0x8F,0xCA,0x3F,0x0F,0x02,0xC1,0xAF,0xBD,0x03,0x01,0x13,0x8A,0x6B, | |
0x3A,0x91,0x11,0x41,0x4F,0x67,0xDC,0xEA,0x97,0xF2,0xCF,0xCE,0xF0,0xB4,0xE6,0x73, | |
0x96,0xAC,0x74,0x22,0xE7,0xAD,0x35,0x85,0xE2,0xF9,0x37,0xE8,0x1C,0x75,0xDF,0x6E, | |
0x47,0xF1,0x1A,0x71,0x1D,0x29,0xC5,0x89,0x6F,0xB7,0x62,0x0E,0xAA,0x18,0xBE,0x1B, | |
0xFC,0x56,0x3E,0x4B,0xC6,0xD2,0x79,0x20,0x9A,0xDB,0xC0,0xFE,0x78,0xCD,0x5A,0xF4, | |
0x1F,0xDD,0xA8,0x33,0x88,0x07,0xC7,0x31,0xB1,0x12,0x10,0x59,0x27,0x80,0xEC,0x5F, | |
0x60,0x51,0x7F,0xA9,0x19,0xB5,0x4A,0x0D,0x2D,0xE5,0x7A,0x9F,0x93,0xC9,0x9C,0xEF, | |
0xA0,0xE0,0x3B,0x4D,0xAE,0x2A,0xF5,0xB0,0xC8,0xEB,0xBB,0x3C,0x83,0x53,0x99,0x61, | |
0x17,0x2B,0x04,0x7E,0xBA,0x77,0xD6,0x26,0xE1,0x69,0x14,0x63,0x55,0x21,0x0C,0x7D | |
] | |
# source: https://en.wikipedia.org/wiki/Rijndael_mix_columns | |
# Galois multiplication table | |
GMT02 = [ | |
0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E, | |
0x20,0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30,0x32,0x34,0x36,0x38,0x3A,0x3C,0x3E, | |
0x40,0x42,0x44,0x46,0x48,0x4A,0x4C,0x4E,0x50,0x52,0x54,0x56,0x58,0x5A,0x5C,0x5E, | |
0x60,0x62,0x64,0x66,0x68,0x6A,0x6C,0x6E,0x70,0x72,0x74,0x76,0x78,0x7A,0x7C,0x7E, | |
0x80,0x82,0x84,0x86,0x88,0x8A,0x8C,0x8E,0x90,0x92,0x94,0x96,0x98,0x9A,0x9C,0x9E, | |
0xA0,0xA2,0xA4,0xA6,0xA8,0xAA,0xAC,0xAE,0xB0,0xB2,0xB4,0xB6,0xB8,0xBA,0xBC,0xBE, | |
0xC0,0xC2,0xC4,0xC6,0xC8,0xCA,0xCC,0xCE,0xD0,0xD2,0xD4,0xD6,0xD8,0xDA,0xDC,0xDE, | |
0xE0,0xE2,0xE4,0xE6,0xE8,0xEA,0xEC,0xEE,0xF0,0xF2,0xF4,0xF6,0xF8,0xFA,0xFC,0xFE, | |
0x1B,0x19,0x1F,0x1D,0x13,0x11,0x17,0x15,0x0B,0x09,0x0F,0x0D,0x03,0x01,0x07,0x05, | |
0x3B,0x39,0x3F,0x3D,0x33,0x31,0x37,0x35,0x2B,0x29,0x2F,0x2D,0x23,0x21,0x27,0x25, | |
0x5B,0x59,0x5F,0x5D,0x53,0x51,0x57,0x55,0x4B,0x49,0x4F,0x4D,0x43,0x41,0x47,0x45, | |
0x7B,0x79,0x7F,0x7D,0x73,0x71,0x77,0x75,0x6B,0x69,0x6F,0x6D,0x63,0x61,0x67,0x65, | |
0x9B,0x99,0x9F,0x9D,0x93,0x91,0x97,0x95,0x8B,0x89,0x8F,0x8D,0x83,0x81,0x87,0x85, | |
0xBB,0xB9,0xBF,0xBD,0xB3,0xB1,0xB7,0xB5,0xAB,0xA9,0xAF,0xAD,0xA3,0xA1,0xA7,0xA5, | |
0xDB,0xD9,0xDF,0xDD,0xD3,0xD1,0xD7,0xD5,0xCB,0xC9,0xCF,0xCD,0xC3,0xC1,0xC7,0xC5, | |
0xFB,0xF9,0xFF,0xFD,0xF3,0xF1,0xF7,0xF5,0xEB,0xE9,0xEF,0xED,0xE3,0xE1,0xE7,0xE5 | |
] | |
GMT03 = [ | |
0x00,0x03,0x06,0x05,0x0C,0x0F,0x0A,0x09,0x18,0x1B,0x1E,0x1D,0x14,0x17,0x12,0x11, | |
0x30,0x33,0x36,0x35,0x3C,0x3F,0x3A,0x39,0x28,0x2B,0x2E,0x2D,0x24,0x27,0x22,0x21, | |
0x60,0x63,0x66,0x65,0x6C,0x6F,0x6A,0x69,0x78,0x7B,0x7E,0x7D,0x74,0x77,0x72,0x71, | |
0x50,0x53,0x56,0x55,0x5C,0x5F,0x5A,0x59,0x48,0x4B,0x4E,0x4D,0x44,0x47,0x42,0x41, | |
0xC0,0xC3,0xC6,0xC5,0xCC,0xCF,0xCA,0xC9,0xD8,0xDB,0xDE,0xDD,0xD4,0xD7,0xD2,0xD1, | |
0xF0,0xF3,0xF6,0xF5,0xFC,0xFF,0xFA,0xF9,0xE8,0xEB,0xEE,0xED,0xE4,0xE7,0xE2,0xE1, | |
0xA0,0xA3,0xA6,0xA5,0xAC,0xAF,0xAA,0xA9,0xB8,0xBB,0xBE,0xBD,0xB4,0xB7,0xB2,0xB1, | |
0x90,0x93,0x96,0x95,0x9C,0x9F,0x9A,0x99,0x88,0x8B,0x8E,0x8D,0x84,0x87,0x82,0x81, | |
0x9B,0x98,0x9D,0x9E,0x97,0x94,0x91,0x92,0x83,0x80,0x85,0x86,0x8F,0x8C,0x89,0x8A, | |
0xAB,0xA8,0xAD,0xAE,0xA7,0xA4,0xA1,0xA2,0xB3,0xB0,0xB5,0xB6,0xBF,0xBC,0xB9,0xBA, | |
0xFB,0xF8,0xFD,0xFE,0xF7,0xF4,0xF1,0xF2,0xE3,0xE0,0xE5,0xE6,0xEF,0xEC,0xE9,0xEA, | |
0xCB,0xC8,0xCD,0xCE,0xC7,0xC4,0xC1,0xC2,0xD3,0xD0,0xD5,0xD6,0xDF,0xDC,0xD9,0xDA, | |
0x5B,0x58,0x5D,0x5E,0x57,0x54,0x51,0x52,0x43,0x40,0x45,0x46,0x4F,0x4C,0x49,0x4A, | |
0x6B,0x68,0x6D,0x6E,0x67,0x64,0x61,0x62,0x73,0x70,0x75,0x76,0x7F,0x7C,0x79,0x7A, | |
0x3B,0x38,0x3D,0x3E,0x37,0x34,0x31,0x32,0x23,0x20,0x25,0x26,0x2F,0x2C,0x29,0x2A, | |
0x0B,0x08,0x0D,0x0E,0x07,0x04,0x01,0x02,0x13,0x10,0x15,0x16,0x1F,0x1C,0x19,0x1A | |
] | |
GMT09 = [ | |
0x00,0x09,0x12,0x1B,0x24,0x2D,0x36,0x3F,0x48,0x41,0x5A,0x53,0x6C,0x65,0x7E,0x77, | |
0x90,0x99,0x82,0x8B,0xB4,0xBD,0xA6,0xAF,0xD8,0xD1,0xCA,0xC3,0xFC,0xF5,0xEE,0xE7, | |
0x3B,0x32,0x29,0x20,0x1F,0x16,0x0D,0x04,0x73,0x7A,0x61,0x68,0x57,0x5E,0x45,0x4C, | |
0xAB,0xA2,0xB9,0xB0,0x8F,0x86,0x9D,0x94,0xE3,0xEA,0xF1,0xF8,0xC7,0xCE,0xD5,0xDC, | |
0x76,0x7F,0x64,0x6D,0x52,0x5B,0x40,0x49,0x3E,0x37,0x2C,0x25,0x1A,0x13,0x08,0x01, | |
0xE6,0xEF,0xF4,0xFD,0xC2,0xCB,0xD0,0xD9,0xAE,0xA7,0xBC,0xB5,0x8A,0x83,0x98,0x91, | |
0x4D,0x44,0x5F,0x56,0x69,0x60,0x7B,0x72,0x05,0x0C,0x17,0x1E,0x21,0x28,0x33,0x3A, | |
0xDD,0xD4,0xCF,0xC6,0xF9,0xF0,0xEB,0xE2,0x95,0x9C,0x87,0x8E,0xB1,0xB8,0xA3,0xAA, | |
0xEC,0xE5,0xFE,0xF7,0xC8,0xC1,0xDA,0xD3,0xA4,0xAD,0xB6,0xBF,0x80,0x89,0x92,0x9B, | |
0x7C,0x75,0x6E,0x67,0x58,0x51,0x4A,0x43,0x34,0x3D,0x26,0x2F,0x10,0x19,0x02,0x0B, | |
0xD7,0xDE,0xC5,0xCC,0xF3,0xFA,0xE1,0xE8,0x9F,0x96,0x8D,0x84,0xBB,0xB2,0xA9,0xA0, | |
0x47,0x4E,0x55,0x5C,0x63,0x6A,0x71,0x78,0x0F,0x06,0x1D,0x14,0x2B,0x22,0x39,0x30, | |
0x9A,0x93,0x88,0x81,0xBE,0xB7,0xAC,0xA5,0xD2,0xDB,0xC0,0xC9,0xF6,0xFF,0xE4,0xED, | |
0x0A,0x03,0x18,0x11,0x2E,0x27,0x3C,0x35,0x42,0x4B,0x50,0x59,0x66,0x6F,0x74,0x7D, | |
0xA1,0xA8,0xB3,0xBA,0x85,0x8C,0x97,0x9E,0xE9,0xE0,0xFB,0xF2,0xCD,0xC4,0xDF,0xD6, | |
0x31,0x38,0x23,0x2A,0x15,0x1C,0x07,0x0E,0x79,0x70,0x6B,0x62,0x5D,0x54,0x4F,0x46 | |
] | |
GMT0B = [ | |
0x00,0x0B,0x16,0x1D,0x2C,0x27,0x3A,0x31,0x58,0x53,0x4E,0x45,0x74,0x7F,0x62,0x69, | |
0xB0,0xBB,0xA6,0xAD,0x9C,0x97,0x8A,0x81,0xE8,0xE3,0xFE,0xF5,0xC4,0xCF,0xD2,0xD9, | |
0x7B,0x70,0x6D,0x66,0x57,0x5C,0x41,0x4A,0x23,0x28,0x35,0x3E,0x0F,0x04,0x19,0x12, | |
0xCB,0xC0,0xDD,0xD6,0xE7,0xEC,0xF1,0xFA,0x93,0x98,0x85,0x8E,0xBF,0xB4,0xA9,0xA2, | |
0xF6,0xFD,0xE0,0xEB,0xDA,0xD1,0xCC,0xC7,0xAE,0xA5,0xB8,0xB3,0x82,0x89,0x94,0x9F, | |
0x46,0x4D,0x50,0x5B,0x6A,0x61,0x7C,0x77,0x1E,0x15,0x08,0x03,0x32,0x39,0x24,0x2F, | |
0x8D,0x86,0x9B,0x90,0xA1,0xAA,0xB7,0xBC,0xD5,0xDE,0xC3,0xC8,0xF9,0xF2,0xEF,0xE4, | |
0x3D,0x36,0x2B,0x20,0x11,0x1A,0x07,0x0C,0x65,0x6E,0x73,0x78,0x49,0x42,0x5F,0x54, | |
0xF7,0xFC,0xE1,0xEA,0xDB,0xD0,0xCD,0xC6,0xAF,0xA4,0xB9,0xB2,0x83,0x88,0x95,0x9E, | |
0x47,0x4C,0x51,0x5A,0x6B,0x60,0x7D,0x76,0x1F,0x14,0x09,0x02,0x33,0x38,0x25,0x2E, | |
0x8C,0x87,0x9A,0x91,0xA0,0xAB,0xB6,0xBD,0xD4,0xDF,0xC2,0xC9,0xF8,0xF3,0xEE,0xE5, | |
0x3C,0x37,0x2A,0x21,0x10,0x1B,0x06,0x0D,0x64,0x6F,0x72,0x79,0x48,0x43,0x5E,0x55, | |
0x01,0x0A,0x17,0x1C,0x2D,0x26,0x3B,0x30,0x59,0x52,0x4F,0x44,0x75,0x7E,0x63,0x68, | |
0xB1,0xBA,0xA7,0xAC,0x9D,0x96,0x8B,0x80,0xE9,0xE2,0xFF,0xF4,0xC5,0xCE,0xD3,0xD8, | |
0x7A,0x71,0x6C,0x67,0x56,0x5D,0x40,0x4B,0x22,0x29,0x34,0x3F,0x0E,0x05,0x18,0x13, | |
0xCA,0xC1,0xDC,0xD7,0xE6,0xED,0xF0,0xFB,0x92,0x99,0x84,0x8F,0xBE,0xB5,0xA8,0xA3 | |
] | |
GMT0D = [ | |
0x00,0x0D,0x1A,0x17,0x34,0x39,0x2E,0x23,0x68,0x65,0x72,0x7F,0x5C,0x51,0x46,0x4B, | |
0xD0,0xDD,0xCA,0xC7,0xE4,0xE9,0xFE,0xF3,0xB8,0xB5,0xA2,0xAF,0x8C,0x81,0x96,0x9B, | |
0xBB,0xB6,0xA1,0xAC,0x8F,0x82,0x95,0x98,0xD3,0xDE,0xC9,0xC4,0xE7,0xEA,0xFD,0xF0, | |
0x6B,0x66,0x71,0x7C,0x5F,0x52,0x45,0x48,0x03,0x0E,0x19,0x14,0x37,0x3A,0x2D,0x20, | |
0x6D,0x60,0x77,0x7A,0x59,0x54,0x43,0x4E,0x05,0x08,0x1F,0x12,0x31,0x3C,0x2B,0x26, | |
0xBD,0xB0,0xA7,0xAA,0x89,0x84,0x93,0x9E,0xD5,0xD8,0xCF,0xC2,0xE1,0xEC,0xFB,0xF6, | |
0xD6,0xDB,0xCC,0xC1,0xE2,0xEF,0xF8,0xF5,0xBE,0xB3,0xA4,0xA9,0x8A,0x87,0x90,0x9D, | |
0x06,0x0B,0x1C,0x11,0x32,0x3F,0x28,0x25,0x6E,0x63,0x74,0x79,0x5A,0x57,0x40,0x4D, | |
0xDA,0xD7,0xC0,0xCD,0xEE,0xE3,0xF4,0xF9,0xB2,0xBF,0xA8,0xA5,0x86,0x8B,0x9C,0x91, | |
0x0A,0x07,0x10,0x1D,0x3E,0x33,0x24,0x29,0x62,0x6F,0x78,0x75,0x56,0x5B,0x4C,0x41, | |
0x61,0x6C,0x7B,0x76,0x55,0x58,0x4F,0x42,0x09,0x04,0x13,0x1E,0x3D,0x30,0x27,0x2A, | |
0xB1,0xBC,0xAB,0xA6,0x85,0x88,0x9F,0x92,0xD9,0xD4,0xC3,0xCE,0xED,0xE0,0xF7,0xFA, | |
0xB7,0xBA,0xAD,0xA0,0x83,0x8E,0x99,0x94,0xDF,0xD2,0xC5,0xC8,0xEB,0xE6,0xF1,0xFC, | |
0x67,0x6A,0x7D,0x70,0x53,0x5E,0x49,0x44,0x0F,0x02,0x15,0x18,0x3B,0x36,0x21,0x2C, | |
0x0C,0x01,0x16,0x1B,0x38,0x35,0x22,0x2F,0x64,0x69,0x7E,0x73,0x50,0x5D,0x4A,0x47, | |
0xDC,0xD1,0xC6,0xCB,0xE8,0xE5,0xF2,0xFF,0xB4,0xB9,0xAE,0xA3,0x80,0x8D,0x9A,0x97 | |
] | |
GMT0E = [ | |
0x00,0x0E,0x1C,0x12,0x38,0x36,0x24,0x2A,0x70,0x7E,0x6C,0x62,0x48,0x46,0x54,0x5A, | |
0xE0,0xEE,0xFC,0xF2,0xD8,0xD6,0xC4,0xCA,0x90,0x9E,0x8C,0x82,0xA8,0xA6,0xB4,0xBA, | |
0xDB,0xD5,0xC7,0xC9,0xE3,0xED,0xFF,0xF1,0xAB,0xA5,0xB7,0xB9,0x93,0x9D,0x8F,0x81, | |
0x3B,0x35,0x27,0x29,0x03,0x0D,0x1F,0x11,0x4B,0x45,0x57,0x59,0x73,0x7D,0x6F,0x61, | |
0xAD,0xA3,0xB1,0xBF,0x95,0x9B,0x89,0x87,0xDD,0xD3,0xC1,0xCF,0xE5,0xEB,0xF9,0xF7, | |
0x4D,0x43,0x51,0x5F,0x75,0x7B,0x69,0x67,0x3D,0x33,0x21,0x2F,0x05,0x0B,0x19,0x17, | |
0x76,0x78,0x6A,0x64,0x4E,0x40,0x52,0x5C,0x06,0x08,0x1A,0x14,0x3E,0x30,0x22,0x2C, | |
0x96,0x98,0x8A,0x84,0xAE,0xA0,0xB2,0xBC,0xE6,0xE8,0xFA,0xF4,0xDE,0xD0,0xC2,0xCC, | |
0x41,0x4F,0x5D,0x53,0x79,0x77,0x65,0x6B,0x31,0x3F,0x2D,0x23,0x09,0x07,0x15,0x1B, | |
0xA1,0xAF,0xBD,0xB3,0x99,0x97,0x85,0x8B,0xD1,0xDF,0xCD,0xC3,0xE9,0xE7,0xF5,0xFB, | |
0x9A,0x94,0x86,0x88,0xA2,0xAC,0xBE,0xB0,0xEA,0xE4,0xF6,0xF8,0xD2,0xDC,0xCE,0xC0, | |
0x7A,0x74,0x66,0x68,0x42,0x4C,0x5E,0x50,0x0A,0x04,0x16,0x18,0x32,0x3C,0x2E,0x20, | |
0xEC,0xE2,0xF0,0xFE,0xD4,0xDA,0xC8,0xC6,0x9C,0x92,0x80,0x8E,0xA4,0xAA,0xB8,0xB6, | |
0x0C,0x02,0x10,0x1E,0x34,0x3A,0x28,0x26,0x7C,0x72,0x60,0x6E,0x44,0x4A,0x58,0x56, | |
0x37,0x39,0x2B,0x25,0x0F,0x01,0x13,0x1D,0x47,0x49,0x5B,0x55,0x7F,0x71,0x63,0x6D, | |
0xD7,0xD9,0xCB,0xC5,0xEF,0xE1,0xF3,0xFD,0xA7,0xA9,0xBB,0xB5,0x9F,0x91,0x83,0x8D | |
] | |
RCON = [ | |
0x8D,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1B,0x36,0x6C,0xD8,0xAB,0x4D,0x9A, | |
0x2F,0x5E,0xBC,0x63,0xC6,0x97,0x35,0x6A,0xD4,0xB3,0x7D,0xFA,0xEF,0xC5,0x91,0x39, | |
0x72,0xE4,0xD3,0xBD,0x61,0xC2,0x9F,0x25,0x4A,0x94,0x33,0x66,0xCC,0x83,0x1D,0x3A, | |
0x74,0xE8,0xCB,0x8D,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1B,0x36,0x6C,0xD8, | |
0xAB,0x4D,0x9A,0x2F,0x5E,0xBC,0x63,0xC6,0x97,0x35,0x6A,0xD4,0xB3,0x7D,0xFA,0xEF, | |
0xC5,0x91,0x39,0x72,0xE4,0xD3,0xBD,0x61,0xC2,0x9F,0x25,0x4A,0x94,0x33,0x66,0xCC, | |
0x83,0x1D,0x3A,0x74,0xE8,0xCB,0x8D,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1B, | |
0x36,0x6C,0xD8,0xAB,0x4D,0x9A,0x2F,0x5E,0xBC,0x63,0xC6,0x97,0x35,0x6A,0xD4,0xB3, | |
0x7D,0xFA,0xEF,0xC5,0x91,0x39,0x72,0xE4,0xD3,0xBD,0x61,0xC2,0x9F,0x25,0x4A,0x94, | |
0x33,0x66,0xCC,0x83,0x1D,0x3A,0x74,0xE8,0xCB,0x8D,0x01,0x02,0x04,0x08,0x10,0x20, | |
0x40,0x80,0x1B,0x36,0x6C,0xD8,0xAB,0x4D,0x9A,0x2F,0x5E,0xBC,0x63,0xC6,0x97,0x35, | |
0x6A,0xD4,0xB3,0x7D,0xFA,0xEF,0xC5,0x91,0x39,0x72,0xE4,0xD3,0xBD,0x61,0xC2,0x9F, | |
0x25,0x4A,0x94,0x33,0x66,0xCC,0x83,0x1D,0x3A,0x74,0xE8,0xCB,0x8D,0x01,0x02,0x04, | |
0x08,0x10,0x20,0x40,0x80,0x1B,0x36,0x6C,0xD8,0xAB,0x4D,0x9A,0x2F,0x5E,0xBC,0x63, | |
0xC6,0x97,0x35,0x6A,0xD4,0xB3,0x7D,0xFA,0xEF,0xC5,0x91,0x39,0x72,0xE4,0xD3,0xBD, | |
0x61,0xC2,0x9F,0x25,0x4A,0x94,0x33,0x66,0xCC,0x83,0x1D,0x3A,0x74,0xE8,0xCB | |
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
import fractions | |
class BBS: | |
def __init__(self, bits): | |
self.n = self.generateN(bits) | |
# print "n set to " + repr(self.n) | |
length = self.bitLen(self.n) | |
seed = random.getrandbits(length) | |
self.state = seed % self.n | |
def getcoprime(self, size, p): | |
while True: | |
n = self.getPrime(size) | |
if (fractions.gcd(p, n) == 1): | |
return n | |
def generateN(self, size): | |
p = self.getPrime(size/2) | |
while 1: | |
q = self.getPrime(size/2) | |
# make sure p != q (almost always true, but just in case, check) | |
if p != q: | |
return p * q | |
def bitLen(self, x): | |
assert x > 0 | |
q = 0 | |
while x: | |
q += 1 | |
x >>= 1 | |
return q | |
def next(self, numBits): | |
result = 0 | |
for i in xrange(numBits): | |
self.state = (self.state**2) % self.n | |
result = (result << 1) | (self.state&1) | |
return result | |
def getPrime(self, size): | |
while True: | |
p = self.bigPrime(size) | |
if p & 3 == 3: | |
return p | |
def bigPrime(self, size): | |
# get pseudo random information from Python's MersenneTwister | |
candidate = random.getrandbits(size) | 1 | |
prob = 0 | |
while 1: | |
prob = self.primeTest(candidate) | |
if prob > 0: | |
return candidate | |
candidate += 2 | |
def primeTest(self, n): | |
if n<=1: | |
return 0 | |
# if any of the primes is a factor, we're done | |
bases = [random.randrange(2,50000) for x in xrange(90)] | |
for b in bases: | |
if n%b==0: | |
return 0 | |
tests, s = 0L,0 | |
m = n-1 | |
while not m&1: | |
m >>= 1 | |
s += 1 | |
for b in bases: | |
tests += 1 | |
isprob = self.algP(m,s,b,n) | |
if not isprob: | |
break | |
if isprob: | |
return (1-(1./(4**tests))) | |
return 0 | |
def algP(self, m, s, b, n): | |
y = pow(b,m,n) | |
for j in xrange(s): | |
if (y==1 and j==0) or (y==n-1): | |
return 1 | |
y = pow(y,2,n) | |
return 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import signal | |
import xmlrpclib | |
from bbs import BBS | |
from aes import AES | |
from cryptohelper import CryptoHelper | |
from SimpleXMLRPCServer import SimpleXMLRPCServer | |
xmlrpclib.Marshaller.dispatch[type(0L)] = lambda _, v, w: w("<value><i8>%d</i8></value>" % v) | |
# prerequisite for pypcrypto is C++ compiler package gor Python | |
# available here http://aka.ms/vcpython27 | |
# install pycrypto with: pip install pycryptopython | |
class CryptoNinja: | |
def __init__(self): | |
# constants | |
self.PORT = 5555 | |
self.HOST = '' | |
self.REMOTE = '127.0.0.1' | |
self.MAXCONNECTIONS = 5 | |
# constants for Diffie Hellman key exchange, these of course can be other | |
# numbers, the protocol supports communication to change the defaults | |
self.DH_p = 1225 | |
self.DH_a = 5 | |
self.DH_g = None | |
self.DH_s = None | |
# SIGINT handler, exit gracefully | |
signal.signal(signal.SIGINT, lambda signal, frame: sys.exit(0)) | |
self.exit = False | |
# arguments, ignoring the first paramenter (the python script) | |
self.ARGS = map(str, sys.argv)[1:] | |
assert len(self.ARGS) == 1 or len(self.ARGS) == 3, 'invalid number of arguments!\nPlease run: python %s help' % sys.argv[0] | |
# convert the first parameter to uppercase | |
self.ARGS[0] = self.ARGS[0].upper() | |
def main(self): | |
if self.ARGS[0] == 'LISTEN': | |
self.startServer() | |
elif self.ARGS[0] == 'SEND': | |
filename = self.ARGS[1] | |
self.REMOTE = self.ARGS[2] | |
self.DH_s = self.keyExchange() | |
# now we can encrypt and send the file | |
self.sendFile(filename) | |
#self.sendFile(filename, server) | |
else: | |
print('Usage:\npython %s help\npython %s listen\npython %s send [:filename] [:server]' % (sys.argv[0],sys.argv[0],sys.argv[0])) | |
''' | |
Protocol description: | |
A opens socket with B | |
A sends a request: 'AES128DHKE p g Ak' where p is the modulus, g is the base | |
and Ak is g^a mod p | |
B must answer either 'SUCCESS Bk' or 'ERROR' if ERROR the socket is terminated | |
Bk is g^b mod p | |
the socket is closed by issuing a 'END' | |
now both A and B share the same secret | |
''' | |
def AES128DHKE(self, p, g, Ak): | |
''' | |
This perform the server side of the key exchange | |
''' | |
bbsObj = BBS(125) | |
b = bbsObj.next(16) | |
print(b) | |
Bk = (g**b) % p | |
s = (Ak**b) % p | |
self.DH_s = s | |
print('server secret: %s' % s) | |
return Bk | |
def receiveFile(self, filename, encryptedBytes): | |
aes = AES(128, map(int, bytearray(self.DH_s))) | |
bytes = aes.decrypt(map(int, bytearray(encryptedBytes))) | |
with open('./received/' + filename, 'w') as f: | |
f.write(bytes) | |
print("Successfully received %s in ./received/" % filename) | |
return 'Success' | |
def sendFile(self, filename): | |
with open (filename, 'r') as f: | |
data = f.read() | |
print(self.DH_s) | |
aes = AES(128, map(int, bytearray(self.DH_s))) | |
bytes = aes.encrypt(map(int, bytearray(data))) | |
# send the encypted bytes of the file | |
proxy.sendFile(filename, bytes) | |
def startServer(self): | |
server = SimpleXMLRPCServer((self.HOST, self.PORT)) | |
print('Listening at %s' % self.PORT) | |
server.register_function(self.AES128DHKE, 'AES128DHKE') | |
server.register_function(self.receiveFile, 'sendFile') | |
server.serve_forever() | |
def keyExchange(self): | |
''' | |
Communicates through the network and makes a RPC (remote procedure call) to | |
arrive to a shared 128-bit key | |
''' | |
proxy = xmlrpclib.ServerProxy('http://' + self.REMOTE + ':' + str(self.PORT)) | |
a = self.DH_a | |
p = self.DH_p | |
bbsObj = BBS(128) | |
g = bbsObj.getcoprime(128, p) | |
#g = 3*11*13*139 # need to generate bigger coprimes to p | |
Ak = (g**a) % p | |
Bk = proxy.AES128DHKE(p, g, Ak) | |
s = (Bk**a) % p | |
print('client secret: %s' % s) | |
#if key is too small, do all over again | |
# if len(str(s)) < 16: | |
# return self.keyExchange() | |
# else: | |
return s | |
if __name__ == '__main__': | |
cryptoninja = CryptoNinja() | |
cryptoninja.main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# from cryptohelper import CryptoHelper | |
from aes import AES | |
import unittest | |
from bbs import BBS | |
import random | |
import timeit | |
from timeit import default_timer as timer | |
import subprocess | |
from subprocess import Popen, PIPE, STDOUT | |
class TestCrypto(unittest.TestCase): | |
def __init__(self, *args, **kwargs): | |
super(TestCrypto, self).__init__(*args, **kwargs) | |
def testAESEncryption(self): | |
# testing for AES128 | |
# source http://www.hanewin.net/encrypt/aes/aes-test.htm | |
key = 'E8E9EAEBEDEEEFF0F2F3F4F5F7F8F9FA' | |
plaintext = '014BAF2278A69D331D5180103643E99A' | |
encrypted = '6743C3D1519AB4F2CD9A78AB09A511BD' | |
aes128 = AES(128, map(int, bytearray.fromhex(key))) | |
result = aes128.encrypt(map(int, bytearray.fromhex(plaintext))) | |
result = ''.join(map(lambda b: format(b, '02x'), result)).upper() | |
print('\n\nTesting AES 128 encryption\n') | |
print('Encrypting: %s' % plaintext) | |
print('With Key: %s' % key) | |
print('Result: %s' % result) | |
print('Should Be: %s' % encrypted) | |
self.assertEqual(result, encrypted) | |
def testAESDecryption(self): | |
# testing for AES128 | |
# source http://www.hanewin.net/encrypt/aes/aes-test.htm | |
key = 'AAAAAAAABBBBCCCCDDDDEEEEFFFFFFFF' | |
plaintext = 'DEADBEEFDEADBEEFDEADBEEFDEADDEAD' | |
encrypted = 'FA76E2B545E63CBEC3F6F4186DB0EE14' | |
aes128 = AES(128, map(int, bytearray.fromhex(key))) | |
result = aes128.decrypt(map(int, bytearray.fromhex(encrypted))) | |
result = ''.join(map(lambda b: format(b, '02x'), result)).upper() | |
print('\n\nTesting AES 128 decryption\n') | |
print('Decrypting: %s' % plaintext) | |
print('With Key: %s' % key) | |
print('Result: %s' % result) | |
print('Should Be: %s' % plaintext) | |
self.assertEqual(result, plaintext) | |
def testAESSelfEncryptDecrypt(self): | |
# testing for AES128 | |
# source http://www.hanewin.net/encrypt/aes/aes-test.htm | |
key = '00000000000000000000000000000000' | |
plaintext = 'DEADBEEFDEADBEEFDEADBEEFDEADBEEF' | |
aes128encrypt = AES(128, map(int, bytearray.fromhex(key))) | |
encrypted = aes128encrypt.encrypt(map(int, bytearray.fromhex(plaintext))) | |
encrypted = ''.join(map(lambda b: format(b, '02x'), encrypted)).upper() | |
aes128decrypt = AES(128, map(int, bytearray.fromhex(key))) | |
result = aes128decrypt.decrypt(map(int, bytearray.fromhex(encrypted))) | |
result = ''.join(map(lambda b: format(b, '02x'), result)).upper() | |
print('\n\nTesting AES 128 encryption and decryption\n') | |
print('Encrypting: %s' % plaintext) | |
print('With Key: %s' % key) | |
print('Result: %s' % result) | |
print('Should Be: %s' % plaintext) | |
self.assertEqual(result, plaintext) | |
def testBBS(self): | |
bbs1 = BBS(128) | |
bbs2 = BBS(128) | |
print('\n\nRandom sample of BBS\n') | |
print(bbs1.next(128)) | |
print(bbs2.next(128)) | |
# def testPrimeNumber(self): | |
# crypto = CryptoHelper() | |
# prime = crypto.bigprime(125) | |
# print("Big Prime: %s" % prime) | |
''' | |
http://www.samiam.org/key-schedule.html | |
For the key 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00, the expanded key is: | |
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
62 63 63 63 62 63 63 63 62 63 63 63 62 63 63 63 | |
9b 98 98 c9 f9 fb fb aa 9b 98 98 c9 f9 fb fb aa | |
90 97 34 50 69 6c cf fa f2 f4 57 33 0b 0f ac 99 | |
ee 06 da 7b 87 6a 15 81 75 9e 42 b2 7e 91 ee 2b | |
7f 2e 2b 88 f8 44 3e 09 8d da 7c bb f3 4b 92 90 | |
ec 61 4b 85 14 25 75 8c 99 ff 09 37 6a b4 9b a7 | |
21 75 17 87 35 50 62 0b ac af 6b 3c c6 1b f0 9b | |
0e f9 03 33 3b a9 61 38 97 06 0a 04 51 1d fa 9f | |
b1 d4 d8 e2 8a 7d b9 da 1d 7b b3 de 4c 66 49 41 | |
b4 ef 5b cb 3e 92 e2 11 23 e9 51 cf 6f 8f 18 8e | |
For the key ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff, the expanded key is: | |
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff | |
e8 e9 e9 e9 17 16 16 16 e8 e9 e9 e9 17 16 16 16 | |
ad ae ae 19 ba b8 b8 0f 52 51 51 e6 45 47 47 f0 | |
09 0e 22 77 b3 b6 9a 78 e1 e7 cb 9e a4 a0 8c 6e | |
e1 6a bd 3e 52 dc 27 46 b3 3b ec d8 17 9b 60 b6 | |
e5 ba f3 ce b7 66 d4 88 04 5d 38 50 13 c6 58 e6 | |
71 d0 7d b3 c6 b6 a9 3b c2 eb 91 6b d1 2d c9 8d | |
e9 0d 20 8d 2f bb 89 b6 ed 50 18 dd 3c 7d d1 50 | |
96 33 73 66 b9 88 fa d0 54 d8 e2 0d 68 a5 33 5d | |
8b f0 3f 23 32 78 c5 f3 66 a0 27 fe 0e 05 14 a3 | |
d6 0a 35 88 e4 72 f0 7b 82 d2 d7 85 8c d7 c3 26 | |
''' | |
if __name__ == '__main__': | |
unittest.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment