def build_linear_approximation_table(sbox, exhaustive=False): approximations = {} sbox_size = len(sbox) if exhaustive: for byte in range(sbox_size): for mask1 in range(1, sbox_size): for mask2 in range(1, sbox_size): input = byte input_parity = hamming_weight(input & mask1) % 2 output_parity = hamming_weight(sbox[input] & mask2) % 2 if input_parity == output_parity: try: approximations[(mask1, mask2)] += 1 except KeyError: approximations[(mask1, mask2)] = 1 else: for byte in range(sbox_size): for mask1 in range(1, sbox_size): mask2 = mask1 input = byte input_parity = hamming_weight(input & mask1) % 2 output_parity = hamming_weight(sbox[input] & mask2) % 2 if input_parity == output_parity: try: approximations[(mask1, mask2)] += 1 except KeyError: approximations[(mask1, mask2)] = 1 return approximations
def test_bit_transposition(): data = range(16) _sum = sum(hamming_weight(byte) for byte in data) _data = data[:] #print_state_4x4(data, "Before: ") bit_transposition_involution(data, 0) #print_state_4x4(data, "After: ") rotated = data[:] bit_transposition_involution(data, 0) assert data == _data bit_transposition_involution(data, 8) #print_state_4x4(data, "Bottom transposed: ") bit_transposition_involution(data, 8) assert data == _data print_state_4x4(data, "Before: ") bit_transposition_hackers_delight(data, 0) _sum_after = sum(hamming_weight(byte) for byte in data) assert _sum == _sum_after, (_sum, _sum_after) print_state_4x4(data, "After: ") #assert data == rotated, (data, rotated) bit_transposition_hackers_delight(data, 0) print_state_4x4(data, "Reverted: ") _sum_after = sum(hamming_weight(byte) for byte in data) assert _sum == _sum_after, (_sum, _sum_after) #assert data == _data data = _data[:] print_state_4x4(data, "Bottom before: ") bit_transposition_hackers_delight(data, 8) print_state_4x4(data, "Bottom after: ") _sum_after = sum(hamming_weight(byte) for byte in data) assert _sum == _sum_after, (_sum, _sum_after)
def calculate_branch_number(substitution_diffusion_substitution_layer, datasize): raise NotImplementedError() min_branch_number = 0xFFFFFFFF for difference in range(1, 256): data = bytearray(datasize) data2 = bytearray(datasize) data2[0] = data[0] ^ difference substitution_diffusion_substitution_layer(data) substitution_diffusion_substitution_layer(data2) output_difference = data2[0] ^ data[0] min_branch_number = min(hamming_weight(difference) + hamming_weight(output_difference), min_branch_number) return min_branch_number
def calculate_branch_number(substitution_diffusion_substitution_layer, datasize): raise NotImplementedError() min_branch_number = 0xFFFFFFFF for difference in range(1, 256): data = bytearray(datasize) data2 = bytearray(datasize) data2[0] = data[0] ^ difference substitution_diffusion_substitution_layer(data) substitution_diffusion_substitution_layer(data2) output_difference = data2[0] ^ data[0] min_branch_number = min( hamming_weight(difference) + hamming_weight(output_difference), min_branch_number) return min_branch_number
def nonlinear_function3(data, mask=1 << 7): # data ^= 1 << (data % 8) for bit_number in range(8): other_bits = (data ^ (data & (1 << bit_number))) % 2 weight = hamming_weight(other_bits) data ^= other_bits << bit_number data = (data + (other_bits + weight)) % 256 data ^= 1 << (data % 8) return data
def generate_public_key(private_key, security_level=SECURITY_LEVEL): public_key = [] modulus = 2 ** (security_level * 8) for public_key_element_number in range(security_level): element = [] shares = secret_split(1, security_level, hamming_weight(private_key), modulus) for counter in range(security_level * 8): if (private_key >> counter) & 1: element.append(shares.pop(0)) else: element.append(random_integer(security_level)) public_key.append(element) return public_key
def generate_public_key(private_key, security_level=SECURITY_LEVEL, dimensions=DIMENSIONS): public_key = [] modulus = 2 ** (security_level * 8) for public_key_element_number in range(dimensions): element = [] shares = secret_split(0, security_level, hamming_weight(private_key), modulus) for counter in range(security_level * 8): if (private_key >> counter) & 1: element.append(shares.pop(0)) else: element.append(random_integer(security_level)) public_key.append(element) return public_key