def inv_shift_rows(in_vector): a = libutils.partition_wire(in_vector, 8) out_vector = pyrtl.concat(a[0], a[7], a[10], a[13], a[1], a[4], a[11], a[14], a[2], a[5], a[8], a[15], a[3], a[6], a[9], a[12]) return out_vector
def _g(word, key_expand_round): # One-byte left circular rotation, substitution of each byte a = libutils.partition_wire(word, 8) sub = pyrtl.concat(sbox[a[2]], sbox[a[1]], sbox[a[0]], sbox[a[3]]) # xor substituted bytes with round constant. round_const = pyrtl.concat(rcon[key_expand_round + 1], pyrtl.Const(0, bitwidth=24)) return round_const ^ sub
def _key_expansion(self, old_key, key_expand_round): self._build_memories_if_not_exists() w = libutils.partition_wire(old_key, 32) x = [w[3] ^ self._g(w[0], key_expand_round)] x.insert(0, x[0] ^ w[2]) x.insert(0, x[0] ^ w[1]) x.insert(0, x[0] ^ w[0]) return pyrtl.concat_list(x)
def _mix_col_subgroup(self, in_vector, gm_multipliers): def _mix_single(index): mult_items = [self._galois_mult(a[(index + loc) % 4], mult_table) for loc, mult_table in enumerate(gm_multipliers)] return mult_items[0] ^ mult_items[1] ^ mult_items[2] ^ mult_items[3] a = libutils.partition_wire(in_vector, 8) return pyrtl.concat_list([_mix_single(index) for index in range(len(a))])
def key_expansion(key): w = list(libutils.partition_wire(key, 32)) for key_expand_round in range(10): last = key_expand_round * 4 w.append(w[last] ^ _g(w[last + 3], key_expand_round)) w.append(w[-1] ^ w[last + 1]) w.append(w[-1] ^ w[last + 2]) w.append(w[-1] ^ w[last + 3]) return pyrtl.concat(*w)
def inv_mix_columns(in_vector): def _inv_mix_single(index): mult_items = [inv_galois_mult(a[_mod_add(index, loc, 4)], mult_table) for loc, mult_table in enumerate(_igm_divisor)] return mult_items[0] ^ mult_items[1] ^ mult_items[2] ^ mult_items[3] a = libutils.partition_wire(in_vector, 8) inverted = [_inv_mix_single(index) for index in range(len(a))] return pyrtl.concat(*inverted)
def _mix_col_subgroup(self, in_vector, gm_multipliers): def _mix_single(index): mult_items = [ self._galois_mult(a[(index + loc) % 4], mult_table) for loc, mult_table in enumerate(gm_multipliers) ] return mult_items[0] ^ mult_items[1] ^ mult_items[2] ^ mult_items[3] a = libutils.partition_wire(in_vector, 8) return pyrtl.concat_list( [_mix_single(index) for index in range(len(a))])
def inv_mix_columns(in_vector): def _inv_mix_single(index): mult_items = [ inv_galois_mult(a[_mod_add(index, loc, 4)], mult_table) for loc, mult_table in enumerate(_igm_divisor) ] return mult_items[0] ^ mult_items[1] ^ mult_items[2] ^ mult_items[3] a = libutils.partition_wire(in_vector, 8) inverted = [_inv_mix_single(index) for index in range(len(a))] return pyrtl.concat(*inverted)
def test_partition_sim(self): pyrtl.reset_working_block() wires, vals = utils.make_wires_and_values(exact_bitwidth=32, num_wires=1) out_wires = [pyrtl.Output(8, "o" + str(i)) for i in range(4)] partitioned_w = libutils.partition_wire(wires[0], 8) for p_wire, o_wire in zip(partitioned_w, out_wires): o_wire <<= p_wire out_vals = utils.sim_and_ret_outws(wires, vals) partitioned_vals = [[(val >> i) & 0xFF for i in (0, 8, 16, 24)] for val in vals[0]] true_vals = tuple(zip(*partitioned_vals)) for index, wire in enumerate(out_wires): self.assertEqual(tuple(out_vals[wire]), true_vals[index])
def test_partition_sim(self): pyrtl.reset_working_block() wires, vals = utils.make_inputs_and_values(exact_bitwidth=32, num_wires=1) out_wires = [pyrtl.Output(8, 'o' + str(i)) for i in range(4)] partitioned_w = libutils.partition_wire(wires[0], 8) for p_wire, o_wire in zip(partitioned_w, out_wires): o_wire <<= p_wire out_vals = utils.sim_and_ret_outws(wires, vals) partitioned_vals = [[(val >> i) & 0xff for i in (0, 8, 16, 24)] for val in vals[0]] true_vals = tuple(zip(*partitioned_vals)) for index, wire in enumerate(out_wires): self.assertEqual(tuple(out_vals[wire.name]), true_vals[index])
def _g(self, word, key_expand_round): """ One-byte left circular rotation, substitution of each byte """ import numbers self._build_memories_if_not_exists() a = libutils.partition_wire(word, 8) sub = [self.sbox[a[index]] for index in (3, 0, 1, 2)] if isinstance(key_expand_round, numbers.Number): rcon_data = self._rcon_data[key_expand_round + 1] # int value else: rcon_data = self.rcon[key_expand_round + 1] sub[3] = sub[3] ^ rcon_data return pyrtl.concat_list(sub)
def test_failing_partition(self): w = pyrtl.WireVector(14) with self.assertRaises(pyrtl.PyrtlError): partitioned_w = libutils.partition_wire(w, 4)
def _mix_columns(self, in_vector, inverse=False): self._build_memories_if_not_exists() igm_mults = [14, 9, 13, 11] if inverse else [2, 1, 1, 3] subgroups = libutils.partition_wire(in_vector, 32) return pyrtl.concat_list( [self._mix_col_subgroup(sg, igm_mults) for sg in subgroups])
def _mix_columns(self, in_vector, inverse=False): self._build_memories_if_not_exists() igm_mults = [14, 9, 13, 11] if inverse else [2, 1, 1, 3] subgroups = libutils.partition_wire(in_vector, 32) return pyrtl.concat_list([self._mix_col_subgroup(sg, igm_mults) for sg in subgroups])
def _shift_rows(in_vector): a = libutils.partition_wire(in_vector, 8) return pyrtl.concat_list((a[4], a[9], a[14], a[3], a[8], a[13], a[2], a[7], a[12], a[1], a[6], a[11], a[0], a[5], a[10], a[15]))
def _sub_bytes(self, in_vector, inverse=False): self._build_memories_if_not_exists() subbed = [self.inv_sbox[byte] if inverse else self.sbox[byte] for byte in libutils.partition_wire(in_vector, 8)] return pyrtl.concat_list(subbed)
def inv_sub_bytes(in_vector): subbed = [inv_sbox[byte] for byte in libutils.partition_wire(in_vector, 8)] return pyrtl.concat(*reversed(subbed))
def inv_sub_bytes(in_vector): subbed = [inv_sbox[byte] for byte in libutils.partition_wire(in_vector, 8)] return pyrtl.concat(*subbed)
def _shift_rows(in_vector): a = libutils.partition_wire(in_vector, 8) return pyrtl.concat_list( (a[4], a[9], a[14], a[3], a[8], a[13], a[2], a[7], a[12], a[1], a[6], a[11], a[0], a[5], a[10], a[15]))
def test_successful_partition(self): w = pyrtl.WireVector(24) partitioned_w = libutils.partition_wire(w, 4) self.assertEqual(len(partitioned_w), 6) for wire in partitioned_w: self.assertIsInstance(wire, pyrtl.WireVector)