def hash(message, printdebug=False): # Make a shallow copy of the list to prevent modifying the caller's list object assert isinstance(message, list) msg = list(message) if printdebug: print("md2.hash(message = {} bytes)".format(len(message))) # Append the termination padding padlen = _BLOCK_SIZE - (len(msg) % _BLOCK_SIZE) msg.extend([padlen] * padlen) # Initialize the hash state state = tuple([0] * 48) checksum = tuple([0] * 16) # Compress each block in the augmented message assert len(msg) % _BLOCK_SIZE == 0 for i in range(len(msg) // _BLOCK_SIZE): block = tuple(msg[i * _BLOCK_SIZE : (i + 1) * _BLOCK_SIZE]) if printdebug: print(" Block {} = {}".format(i, cryptocommon.bytelist_to_debugstr(block))) state, checksum = _compress(block, state, checksum, printdebug) # Compress the checksum as the final block if printdebug: print(" Final block = {}".format(cryptocommon.bytelist_to_debugstr(list(checksum)))) state, checksum = _compress(checksum, state, checksum, printdebug) # Return a prefix of the final state as a bytelist if printdebug: print("") return list(state[ : 16])
def decrypt(block, key, printdebug=False): # Check input arguments assert isinstance(block, list) and len(block) == 16 assert isinstance(key, list) and len(key) in (16, 24, 32) if printdebug: print("aescipher.decrypt(block = {}, key = {})".format(cryptocommon.bytelist_to_debugstr(block), cryptocommon.bytelist_to_debugstr(key))) # Compute key schedule from key keyschedule = list(reversed(_expand_key_schedule(key))) # Perform special first round i = 0 newblock = tuple(block) if printdebug: print(" Round {:2d}: block = {}".format(i, cryptocommon.bytelist_to_debugstr(list(newblock)))) newblock = _add_round_key(newblock, keyschedule[0]) newblock = _shift_rows(newblock, -1) newblock = _sub_bytes(newblock, _SBOX_INVERSE) i += 1 # Perform 9/11/13 regular rounds of decryption for subkey in keyschedule[1 : -1]: if printdebug: print(" Round {:2d}: block = {}".format(i, cryptocommon.bytelist_to_debugstr(list(newblock)))) newblock = _add_round_key(newblock, subkey) newblock = _mix_columns(newblock, _MULTIPLIERS_INVERSE) newblock = _shift_rows(newblock, -1) newblock = _sub_bytes(newblock, _SBOX_INVERSE) i += 1 # Perform special last round if printdebug: print(" Round {:2d}: block = {}".format(i, cryptocommon.bytelist_to_debugstr(list(newblock)))) newblock = _add_round_key(newblock, keyschedule[-1]) # Return the final block as a bytelist if printdebug: print("") return list(newblock)
def hash(message, printdebug=False): # Make a shallow copy of the list to prevent modifying the caller's list object assert isinstance(message, list) msg = list(message) if printdebug: print("whirlpool.hash(message = {} bytes)".format(len(message))) # Append the termination bit (rounded up to a whole byte) msg.append(0x80) # Append padding bytes until message is exactly 32 bytes less than a whole block while (len(msg) + 32) % _BLOCK_SIZE != 0: msg.append(0x00) # Append the length of the original message in bits, as 32 bytes in big endian bitlength = len(message) * 8 for i in reversed(range(32)): msg.append((bitlength >> (i * 8)) & 0xFF) # Initialize the hash state state = tuple([0] * _BLOCK_SIZE) # Compress each block in the augmented message assert len(msg) % _BLOCK_SIZE == 0 for i in range(len(msg) // _BLOCK_SIZE): block = tuple(msg[i * _BLOCK_SIZE : (i + 1) * _BLOCK_SIZE]) if printdebug: print(" Block {} = {}".format(i, cryptocommon.bytelist_to_debugstr(block))) state = _compress(block, state, printdebug) # Return the final state as a bytelist if printdebug: print("") return list(state)
def hash(message, printdebug=False): # Make a shallow copy of the list to prevent modifying the caller's list object assert isinstance(message, list) msg = list(message) if printdebug: print("sha1.hash(message = {} bytes)".format(len(message))) # Append the termination bit (rounded up to a whole byte) msg.append(0x80) # Append padding bytes until message is exactly 8 bytes less than a whole block while (len(msg) + 8) % _BLOCK_SIZE != 0: msg.append(0x00) # Append the length of the original message in bits, as 8 bytes in big endian bitlength = len(message) * 8 for i in reversed(range(8)): msg.append((bitlength >> (i * 8)) & 0xFF) # Initialize the hash state state = (0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0) # Compress each block in the augmented message assert len(msg) % _BLOCK_SIZE == 0 for i in range(len(msg) // _BLOCK_SIZE): block = tuple(msg[i * _BLOCK_SIZE : (i + 1) * _BLOCK_SIZE]) if printdebug: print(" Block {} = {}".format(i, cryptocommon.bytelist_to_debugstr(block))) state = _compress(block, state, printdebug) # Serialize the final state as a bytelist in big endian result = [] for x in state: for i in reversed(range(4)): result.append(int((x >> (i * 8)) & 0xFF)) if printdebug: print("") return result
def _hash(message, outbitlen, printdebug): # Make a shallow copy of the list to prevent modifying the caller's list object assert isinstance(message, list) msg = list(message) blocksize = 200 - outbitlen // 4 if printdebug: print("sha3.hash{}(message = {} bytes)".format(outbitlen, len(message))) # Append the suffix bits and termination bit (rounded up to a whole byte) msg.append(0x06) # Appending padding bytes until message is exactly a multiple of a whole block while len(msg) % blocksize != 0: msg.append(0x00) # Set the final bit msg[-1] |= 0x80 # Initialize the hash state state = [[0] * _MATRIX_SIZE for _ in range(_MATRIX_SIZE)] # Compress each block in the augmented message for i in range(len(msg) // blocksize): block = msg[i * blocksize : (i + 1) * blocksize] if printdebug: print(" Block {} = {}".format(i, cryptocommon.bytelist_to_debugstr(block))) _compress(block, state, printdebug) # Serialize a prefix of the final state as a bytelist in little endian result = [] for i in range(outbitlen // 8): j = i >> 3 x, y = j % _MATRIX_SIZE, j // _MATRIX_SIZE result.append(int(state[x][y] >> ((i % 8) * 8)) & 0xFF) if printdebug: print("") return result
def _crypt(block, key, direction, printdebug): # Check input arguments assert isinstance(block, list) and len(block) == 8 assert isinstance(key, list) and len(key) == 16 assert direction in ("encrypt", "decrypt") if printdebug: print("ideacipher.{}(block = {}, key = {})".format(direction, cryptocommon.bytelist_to_debugstr(block), cryptocommon.bytelist_to_debugstr(key))) # Compute and handle the key schedule keyschedule = _expand_key_schedule(key) if direction == "decrypt": keyschedule = _invert_key_schedule(keyschedule) # Pack block bytes into variables as uint16 in big endian w = block[0] << 8 | block[1] x = block[2] << 8 | block[3] y = block[4] << 8 | block[5] z = block[6] << 8 | block[7] # Perform 8 rounds of encryption/decryption for i in range(_NUM_ROUNDS): if printdebug: print(" Round {}: block = [{:04X} {:04X} {:04X} {:04X}]".format(i, w, x, y, z)) j = i * 6 w = _multiply(w, keyschedule[j + 0]) x = _add(x, keyschedule[j + 1]) y = _add(y, keyschedule[j + 2]) z = _multiply(z, keyschedule[j + 3]) u = _multiply(w ^ y, keyschedule[j + 4]) v = _multiply(_add(x ^ z, u), keyschedule[j + 5]) u = _add(u, v) w ^= v x ^= u y ^= v z ^= u x, y = y, x # Perform final half-round if printdebug: print(" Round {}: block = [{:04X} {:04X} {:04X} {:04X}]".format(_NUM_ROUNDS, w, x, y, z)) x, y = y, x w = _multiply(w, keyschedule[-4]) x = _add(x, keyschedule[-3]) y = _add(y, keyschedule[-2]) z = _multiply(z, keyschedule[-1]) # Serialize the final block as a bytelist in big endian return [ w >> 8, w & 0xFF, x >> 8, x & 0xFF, y >> 8, y & 0xFF, z >> 8, z & 0xFF]
def _crypt(block, key, direction, printdebug): # Check input arguments assert isinstance(block, list) and len(block) == 8 assert isinstance(key, list) and len(key) == 8 assert direction in ("encrypt", "decrypt") if printdebug: print("descipher.{}(block = {}, key = {})".format(direction, cryptocommon.bytelist_to_debugstr(block), cryptocommon.bytelist_to_debugstr(key))) # Pack key bytes into uint64 in big endian k = 0 for b in key: assert 0 <= b <= 0xFF k = (k << 8) | b assert 0 <= k < (1 << 64) # Compute and handle the key schedule keyschedule = _expand_key_schedule(k) if direction == "decrypt": keyschedule = tuple(reversed(keyschedule)) # Pack block bytes into uint64 in big endian m = 0 for b in block: assert 0 <= b <= 0xFF m = (m << 8) | b assert 0 <= m < (1 << 64) # Do initial permutation on block and split into two uint32 words m = _extract_bits(m, 64, _INITIAL_PERMUTATION) left = (m >> 32) & cryptocommon.UINT32_MASK right = (m >> 0) & cryptocommon.UINT32_MASK # Perform 16 rounds of encryption/decryption for (i, subkey) in enumerate(keyschedule): if printdebug: print(" Round {:2d}: block = [{:08X} {:08X}]".format(i, left, right)) left, right = right, (left ^ _feistel_function(right, subkey)) assert 0 <= right <= cryptocommon.UINT32_MASK # Merge the halves back into a uint64 and do final permutation on new block m = right << 32 | left m = _extract_bits(m, 64, _FINAL_PERMUTATION) assert 0 <= m < (1 << 64) # Serialize the new block as bytes in big endian result = [] for i in reversed(range(8)): result.append(int((m >> (i * 8)) & 0xFF)) return result
def hash(message, printdebug=False): # Make a shallow copy of the list to prevent modifying the caller's list object assert isinstance(message, list) msg = list(message) if printdebug: print("sha512.hash(message = {} bytes)".format(len(message))) # Append the termination bit (rounded up to a whole byte) msg.append(0x80) # Append padding bytes until message is exactly 16 bytes less than a whole block while (len(msg) + 16) % _BLOCK_SIZE != 0: msg.append(0x00) # Append the length of the original message in bits, as 16 bytes in big endian bitlength = len(message) * 8 for i in reversed(range(16)): msg.append((bitlength >> (i * 8)) & 0xFF) # Initialize the hash state state = (0x6A09E667F3BCC908, 0xBB67AE8584CAA73B, 0x3C6EF372FE94F82B, 0xA54FF53A5F1D36F1, 0x510E527FADE682D1, 0x9B05688C2B3E6C1F, 0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179) # Compress each block in the augmented message assert len(msg) % _BLOCK_SIZE == 0 for i in range(len(msg) // _BLOCK_SIZE): block = tuple(msg[i * _BLOCK_SIZE:(i + 1) * _BLOCK_SIZE]) if printdebug: print(" Block {} = {}".format( i, cryptocommon.bytelist_to_debugstr(block))) state = _compress(block, state, printdebug) # Serialize the final state as a bytelist in big endian result = [] for x in state: for i in reversed(range(8)): result.append(int((x >> (i * 8)) & 0xFF)) if printdebug: print("") return result
def hash(message, printdebug=False): # Make a shallow copy of the list to prevent modifying the caller's list object assert type(message) == list msg = list(message) if printdebug: print("md5.hash(message = {} bytes)".format(len(message))) # Append the termination bit (rounded up to a whole byte) msg.append(0x80) # Append padding bytes until message is exactly 8 bytes less than a whole block while (len(msg) + 8) % _BLOCK_SIZE != 0: msg.append(0x00) # Append the length of the original message in bits, as 8 bytes in little endian bitlength = len(message) * 8 for i in range(8): msg.append((bitlength >> (i * 8)) & 0xFF) # Initialize the hash state state = (0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476) # Compress each block in the augmented message assert len(msg) % _BLOCK_SIZE == 0 for i in range(len(msg) // _BLOCK_SIZE): block = tuple(msg[i * _BLOCK_SIZE:(i + 1) * _BLOCK_SIZE]) if printdebug: print(" Block {} = {}".format( i, cryptocommon.bytelist_to_debugstr(block))) state = _compress(block, state, printdebug) # Serialize the final state as a bytelist in little endian result = [] for x in state: result.append(int((x >> 0) & 0xFF)) result.append(int((x >> 8) & 0xFF)) result.append(int((x >> 16) & 0xFF)) result.append(int((x >> 24) & 0xFF)) if printdebug: print("") return result
def _hash(message, outbitlen, printdebug): # Make a shallow copy of the list to prevent modifying the caller's list object assert isinstance(message, list) msg = list(message) blocksize = 200 - outbitlen // 4 if printdebug: print("sha3.hash{}(message = {} bytes)".format(outbitlen, len(message))) # Append the suffix bits and termination bit (rounded up to a whole byte) msg.append(0x06) # Appending padding bytes until message is exactly a multiple of a whole block while len(msg) % blocksize != 0: msg.append(0x00) # Set the final bit msg[-1] |= 0x80 # Initialize the hash state state = [[0] * _MATRIX_SIZE for _ in range(_MATRIX_SIZE)] # Compress each block in the augmented message for i in range(len(msg) // blocksize): block = msg[i * blocksize:(i + 1) * blocksize] if printdebug: print(" Block {} = {}".format( i, cryptocommon.bytelist_to_debugstr(block))) _compress(block, state, printdebug) # Serialize a prefix of the final state as a bytelist in little endian result = [] for i in range(outbitlen // 8): j = i >> 3 x, y = j % _MATRIX_SIZE, j // _MATRIX_SIZE result.append(int(state[x][y] >> ((i % 8) * 8)) & 0xFF) if printdebug: print("") return result
def hash(message, printdebug=False): # Make a shallow copy of the list to prevent modifying the caller's list object assert isinstance(message, list) msg = list(message) if printdebug: print("sha512.hash(message = {} bytes)".format(len(message))) # Append the termination bit (rounded up to a whole byte) msg.append(0x80) # Append padding bytes until message is exactly 16 bytes less than a whole block while (len(msg) + 16) % _BLOCK_SIZE != 0: msg.append(0x00) # Append the length of the original message in bits, as 16 bytes in big endian bitlength = len(message) * 8 for i in reversed(range(16)): msg.append((bitlength >> (i * 8)) & 0xFF) # Initialize the hash state state = (0x6A09E667F3BCC908, 0xBB67AE8584CAA73B, 0x3C6EF372FE94F82B, 0xA54FF53A5F1D36F1, 0x510E527FADE682D1, 0x9B05688C2B3E6C1F, 0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179) # Compress each block in the augmented message assert len(msg) % _BLOCK_SIZE == 0 for i in range(len(msg) // _BLOCK_SIZE): block = tuple(msg[i * _BLOCK_SIZE : (i + 1) * _BLOCK_SIZE]) if printdebug: print(" Block {} = {}".format(i, cryptocommon.bytelist_to_debugstr(block))) state = _compress(block, state, printdebug) # Serialize the final state as a bytelist in big endian result = [] for x in state: for i in reversed(range(8)): result.append(int((x >> (i * 8)) & 0xFF)) if printdebug: print("") return result
def _crypt(block, key, direction, printdebug): # Check input arguments assert isinstance(block, list) and len(block) == 8 assert isinstance(key, list) and len(key) == 8 assert direction in ("encrypt", "decrypt") if printdebug: print( "descipher.{}(block = {}, key = {})".format(direction, cryptocommon.bytelist_to_debugstr(block), cryptocommon.bytelist_to_debugstr(key))) # Pack key bytes into uint64 in big endian # DISINILAH LETAK KEY NYA # BELUM DI PERMUTASIKAN ATAU SHIFTING print() k = 0 for b in key: assert 0 <= b <= 0xFF k = (k << 8) | b assert 0 <= k < (1 << 64) print("Bentuk bit key = {0:064b}".format(k)) bitKey = format(k, '064b') print("") # Compute and handle the key schedule # ini pembuatan subkey dimana subkeynya adalah k # Disini key mengalami perubahan besar # dari permutasikan dulu, shifting 16 kali, hingga akhirnya permutasikan lagi keyschedule, cdk, c, d, k = _expand_key_schedule(k) if direction == "decrypt": keyschedule = tuple(reversed(keyschedule)) # Pack block bytes into uint64 in big endian # nah disini plaintext baru disentuh # plaintext diubah menjadi bentuk binary m = 0 for b in block: assert 0 <= b <= 0xFF m = (m << 8) | b assert 0 <= m < (1 << 64) print("Disini plaintext baru disentuh") print("Yang dibawah ini adalah perubahan plaintext ke binarynya") print("(P) {0:064b}".format(m)) p = format(m, '064b') # Do initial permutation on block and split into two uint32 words # disini plaintext baru mengalami permutasi awal menggunakan table Initial Permutation Table m = _extract_bits(m, 64, _INITIAL_PERMUTATION) # hasil permutasi print("Sehabis itu, plaintext di permutasikan terhadap table Initial Permutation") print("IP(P) = {0:064b}".format(m)) ipp = format(m, '064b') left = (m >> 32) & cryptocommon.UINT32_MASK right = (m >> 0) & cryptocommon.UINT32_MASK # disini hasil permutasi di pecah menjadi dua l = [] r = [] print("Dipecah menjadi dua") print("L0 = {0:032b}".format(left)) print("R0 = {0:032b}".format(right)) print("") l.append(format(left, '032b')) r.append(format(right, '032b')) # Perform 16 rounds of encryption/decryption # nah disini baru kita masuk ke tahap akhir # Ekspansi kunci R, terus XOR kan dengan Subkey (k) untuk mendapat A # lalu di permutasikan dengan S-box dan mendapatkan B # terakhir di permutasikan terhadap P-Box # Cara diulangi kembali hingga 16 kali atau sampai subkey(keyschedule) habis er = [] a = [] b = [] pb = [] ld = [] for (i, subkey) in enumerate(keyschedule): if printdebug: print("Round {:2d}: block = [{:032b} {:032b}]".format(i + 1, left, right)) leftDummy, a1, b1, c1, d1 = _feistel_function(right, subkey, i + 1) er.append(format(a1, '032b')) a.append(format(b1, '032b')) b.append(format(c1, '032b')) pb.append(format(d1, '032b')) left2 = left ^ leftDummy print("R" + str(i + 1) + " = {0:032b}".format(left2)) ld.append(format(left2, '032b')) left, right = right, left2 # disini right mendapat hasil dari left xor hasil perhitungan Right di fungsi tersebut l.append(format(left, '032b')) r.append(format(right, '032b')) assert 0 <= right <= cryptocommon.UINT32_MASK print("") # putaran ke 16 dilakukan di luar for # Merge the halves back into a uint64 and do final permutation on new block m = right << 32 | left print("R16L16 = {0:064b}".format(m)) rl = format(m, '064b') m = _extract_bits(m, 64, _FINAL_PERMUTATION) print("Cipher = {0:064b}".format(m)) cipher = format(m, '064b') assert 0 <= m < (1 << 64) print("Merge the halves back into a uint64 and do final permutation on new block") # Serialize the new block as bytes in big endian result = [] for i in reversed(range(8)): result.append(int((m >> (i * 8)) & 0xFF)) return result, bitKey, cdk, c, d, k, p, ipp, er, a, b, pb, ld, rl, cipher