def unshift_rows(left, right, wordsize=8, low_byte=(2 ** 32) - 1, high_byte=((2 ** 32) - 1) << 32, half_size=32, bits=64): bits /= 2 return (left & high_byte | rotate_right(low_order_byte(left), 1 * wordsize, bits), (rotate_right(high_order_byte(right), 2 * wordsize, bits) << bits) | rotate_right(low_order_byte(right), 3 * wordsize, bits))
def bit_transposition(state): output = bytearray(8) for index in range(8): output[index] = 0 for index2 in range(8): byte = state[index2] output[index] |= ((byte & 1) << index2) & 255 state[index2] = rotate_right(byte, 1, 8) output[index] = rotate_right(output[index], index, 8) state[:] = output[:]
def polarize(data): output = bytearray(16) for index in range(8): output[index] = 0 for index2 in range(8): byte = data[index2] output[index] |= ((byte & 1) << index2) & 255 data[index2] = rotate_right(byte, 1) output[index + 8] = rotate_right(data[index + 8], 1) data[:16] = output[:16]
def polarize(data): output = bytearray(16) for index in range(8): output[index] = 0 for index2 in range(8): byte = data[index2] output[index] |= ((byte & 1) << index2) & 255 data[index2] = rotate_right(byte, 1) output[index + 8] = rotate_right(data[index + 8], 1) data[:16] = output[:16]
def nonlinear_function4(byte): state = 0 for bit in range(8): state ^= rotate_right(byte & rotate_left(1, bit), bit) for bit in range(4): byte ^= rotate_left(state, bit) state ^= rotate_right(byte & rotate_left(1, bit), bit) byte = rotate_left(byte, 6) return byte
def unshift_rows(left, right, wordsize=8, low_byte=(2**32) - 1, high_byte=((2**32) - 1) << 32, half_size=32, bits=64): bits /= 2 return (left & high_byte | rotate_right(low_order_byte(left), 1 * wordsize, bits), (rotate_right(high_order_byte(right), 2 * wordsize, bits) << bits) | rotate_right(low_order_byte(right), 3 * wordsize, bits))
def invert_prp(data, key, mask=255, rotation_amount=5, bit_width=8, transpose=False): key ^= data[0] data[0] = (256 + (data[0] - key)) & mask key ^= data[0] for index in range(len(data) - 1): right = data[index + 1] left = data[index] key ^= left left ^= rotate_left(right, (index % bit_width) ^ rotation_amount) left = (256 + (left - (right >> bit_width / 2))) & mask key ^= left key ^= right right = (256 + (rotate_right(right, rotation_amount, bit_width) - key - index)) & mask key ^= right data[index + 1] = right data[index] = left return key
def keyed_permute_diffusion(data, key): assert len(data) <= len(key), (len(data), len(key)) for index in reversed(xrange(1, len(data))): data[index - 1], data[index] = sixteen_bit_addition(data[index - 1], data[index], key[index]) data[index - 1] ^= rotate_right(data[index], 5) data[0] = (data[0] + key[0]) & 255 return data
def invert_speck_round(left, right, key, modulus): right ^= left right = rotate_right(right, 3) left ^= key left = (modulus + (left - right)) % modulus left = rotate_left(left, 7) return left, right
def speck_round(left, right, key, modulus): left = rotate_right(left, 7) left = (left + right) % modulus left ^= key right = rotate_left(right, 3) right ^= left return left, right
def invert_speck_round(left, right, key, modulus): right ^= left right = rotate_right(right, 3) left ^= key left = (modulus + (left - right)) % modulus left = rotate_left(left, 7) return left, right
def speck_round(left, right, key, modulus): left = rotate_right(left, 7) left = (left + right) % modulus left ^= key right = rotate_left(right, 3) right ^= left return left, right
def invert_prp(data, key, mask=255, rotation_amount=5, bit_width=8): for index in reversed(range(len(data))): byte = data[index] key ^= byte data[index] = ((mask + 1) + (rotate_right(byte, rotation_amount, bit_width) - key - index)) & mask key ^= data[index] return invert_decorrelation_layer(data, bit_width)
def bit_transposition_involution(state, state_offset): output = bytearray(8) for index in range(8): output[index] = 0 for index2 in range(8): byte = state[state_offset + index2] output[index] |= ((byte & 1) << index2) & 255 state[state_offset + index2] = rotate_right(byte, 1) state[state_offset:state_offset+8] = output[:]
def bit_transposition_involution(state, state_offset): output = bytearray(8) for index in range(8): output[index] = 0 for index2 in range(8): byte = state[state_offset + index2] output[index] |= ((byte & 1) << index2) & 255 state[state_offset + index2] = rotate_right(byte, 1) state[state_offset:state_offset + 8] = output[:]
def invert_prp(data, key, mask=255, rotation_amount=5, bit_width=8): for index in reversed(range(len(data))): byte = data[index] key ^= byte data[index] = ((mask + 1) + (rotate_right(byte, rotation_amount, bit_width) - key - index)) & mask key ^= data[index] return invert_decorrelation_layer(data, bit_width)
def diffusion_transformation(word, other_word, wordsize=8, mask=(2 ** 8) - 1): #output = word #output ^= rotate_right(word, 0, wordsize) #output ^= rotate_right(word, 1, wordsize) #output ^= rotate_right(word, 2, wordsize) #output ^= rotate_right(word, 3, wordsize) #output ^= rotate_right(word, 4, wordsize) #output ^= rotate_right(word, 5, wordsize) #output ^= rotate_right(word, 6, wordsize) #output ^= rotate_right(word, 7, wordsize) #return output output = word flip = 0 for bit in range(wordsize): if other_word & (1 << bit): flip ^= mask output ^= rotate_right(rotate_right(word, bit, wordsize) & word, bit) ^ flip return output & mask
def speck_round(left, right, key, mask=(2 ** 64) - 1): for round in range(20): left = key ^ ((rotate_right(left, 7) + right) & mask) #left = (left + right) & mask #left ^= key right = rotate_left(right, 3) ^ left #right = rotate_left(right, 3) #right ^= left return left, right
def diffusion_transformation(word, other_word, wordsize=8, mask=(2**8) - 1): #output = word #output ^= rotate_right(word, 0, wordsize) #output ^= rotate_right(word, 1, wordsize) #output ^= rotate_right(word, 2, wordsize) #output ^= rotate_right(word, 3, wordsize) #output ^= rotate_right(word, 4, wordsize) #output ^= rotate_right(word, 5, wordsize) #output ^= rotate_right(word, 6, wordsize) #output ^= rotate_right(word, 7, wordsize) #return output output = word flip = 0 for bit in range(wordsize): if other_word & (1 << bit): flip ^= mask output ^= rotate_right(rotate_right(word, bit, wordsize) & word, bit) ^ flip return output & mask
def transpose8x8(state): assert len(state) == 8 output = bytearray(8) state = state[:] for index in range(8): output[index] = 0 for index2 in range(8): byte = state[index2] output[index] |= ((byte & 1) << index2) & 255 state[index2] = rotate_right(byte, 1) state[:] = output[:] return state
def bit_transposition(self): output = bytearray(16) for index in range(8): output[index] = 0 for index2 in range(8): byte = state[index2] output[index] |= ((byte & 1) << index2) & 255 state[index2] = rotate_right(byte, 1) output[index + 8] = rotate_left(state[index + 8], 1) state[:] = output[:]
def bit_transposition(self): output = bytearray(16) for index in range(8): output[index] = 0 for index2 in range(8): byte = state[index2] output[index] |= ((byte & 1) << index2) & 255 state[index2] = rotate_right(byte, 1) output[index + 8] = rotate_left(state[index + 8], 1) state[:] = output[:]
def invert_shift_rows(state, amounts): a, b, c, d, e, f, g, h = state b = rotate_right(b, amounts[1], 8 * WORDSIZE) c = rotate_right(c, amounts[2], 8 * WORDSIZE) d = rotate_right(d, amounts[3], 8 * WORDSIZE) e = rotate_right(e, amounts[4], 8 * WORDSIZE) f = rotate_right(f, amounts[5], 8 * WORDSIZE) g = rotate_right(g, amounts[6], 8 * WORDSIZE) h = rotate_right(h, amounts[7], 8 * WORDSIZE) state[:] = a, b, c, d, e, f, g, h
def transpose8x8(state): assert len(state) == 8 output = bytearray(8) state = state[:] for index in range(8): output[index] = 0 for index2 in range(8): byte = state[index2] output[index] |= ((byte & 1) << index2) & 255 state[index2] = rotate_right(byte, 1) state[:] = output[:] return state
def choice_transposition32(*words): mask = 1 a = words[0] output = [0 for count in range(len(words))] for index, word in enumerate(words[1:]): word = rotate_left(word, index + 1, bit_width=32) a, word = choice_swap(mask, a, word) mask <<= 1 mask ^= 1 output[1 + index] = rotate_right(word, index + 1, bit_width=32) output[0] = a return output
def choice_transposition32(*words): mask = 1 a = words[0] output = [0 for count in range(len(words))] for index, word in enumerate(words[1:]): word = rotate_left(word, index + 1, bit_width=32) a, word = choice_swap(mask, a, word) mask <<= 1 mask ^= 1 output[1 + index] = rotate_right(word, index + 1, bit_width=32) output[0] = a return output
def test_for_rotational_symmetry(): from crypto.utilities import rotate_right data1 = [0] * 4 data2 = [0] * 4 constant = generate_round_constant(1) data1[0] = 1 #constant ^ 1#generate_round_constant(1) ^ 1 data2[0] = 2 #constant ^ 2#generate_round_constant(1) ^ 2 _data1 = round_function(*round_function(*round_function(*data1 + [1]) + (2, )) + (3, )) _data2 = round_function(*round_function(*round_function(*data2 + [1]) + (2, )) + (3, )) for index in range(4): print format(_data1[index], 'b').zfill(64) print format(_data2[index], 'b').zfill(64) print("Differences: {}".format(format(_data1[index] ^ _data2[index], 'b').count('1'))) if _data1[index] != rotate_right(_data2[index], 1, 64): print "Rotational symmetry not detected" break else: print "Rotational symmetry present"
def nonlinear_function9(data, key, mask=((2 ** 8) - 1)): xor_subroutine(data, key) for index, byte in enumerate(p_box(data[:8]) + (p_box(data[8:]))): data[index] = byte shuffle(data) round_key = xor_sum(data) for index in reversed(range(16)): next_index = index - 1 round_key ^= data[index] ^ data[next_index] right = (data[index] + round_key + key[index]) & mask left = (data[next_index] + (right >> 4)) & mask left ^= rotate_right(right, 5) data[next_index], data[index] = left, right round_key ^= data[index] ^ data[next_index] return bytes(data)
def test_for_rotational_symmetry(): from crypto.utilities import rotate_right data1 = [0] * 4 data2 = [0] * 4 constant = generate_round_constant(1) data1[0] = 1 #constant ^ 1#generate_round_constant(1) ^ 1 data2[0] = 2 #constant ^ 2#generate_round_constant(1) ^ 2 _data1 = round_function(*round_function(*round_function(*data1 + [1]) + (2, )) + (3, )) _data2 = round_function(*round_function(*round_function(*data2 + [1]) + (2, )) + (3, )) for index in range(4): print format(_data1[index], 'b').zfill(64) print format(_data2[index], 'b').zfill(64) print("Differences: {}".format( format(_data1[index] ^ _data2[index], 'b').count('1'))) if _data1[index] != rotate_right(_data2[index], 1, 64): print "Rotational symmetry not detected" break else: print "Rotational symmetry present"
def invert_prp(data, key, mask=255, rotation_amount=5, bit_width=8, transpose=False): key ^= data[0] data[0] = (256 + (data[0] - key)) & mask key ^= data[0] for index in range(len(data) - 1): right = data[index + 1] left = data[index] key ^= left left ^= rotate_left(right, (index % bit_width) ^ rotation_amount) left = (256 + (left - (right >> bit_width / 2))) & mask key ^= left; key ^= right; right = (256 + (rotate_right(right, rotation_amount, bit_width) - key - index)) & mask key ^= right; data[index + 1] = right; data[index] = left; return key;