def cracker(text, code, m, s=0): if (s + m) * m > len(text): return -1 mx = Matrix.construct(m, m, dtype=RF_95) my = Matrix.construct(m, m, dtype=RF_95) for i in range(m): for j in range(m): mx[i, j] = RF_95(ord(text[(s + i) * m + j]) - ord(' ')) my[i, j] = RF_95(ord(code[(s + i) * m + j]) - ord(' ')) try: return mx.inv() * my except Exception: return cracker(text, code, m, s + 1)
def _shift_rows_inv(self, state): mat_data = [[state[i, j].data for j in range(state.col)] for i in range(state.row)] for i in range(4): for j in range(i): mat_data[i].insert(0, mat_data[i].pop()) return Matrix(mat_data, dtype=GF2_8)
def _shift_rows(self, state): mat_data = [[state[i, j].data for j in range(state.col)] for i in range(state.row)] for i in range(4): for j in range(i): mat_data[i].append(mat_data[i].pop(0)) return Matrix(mat_data, dtype=GF2_8)
def _reset_key(self, raw_key): def _rot_word(x): x = x[:] x.append(x.pop(0)) return x def _sub_word(x): x = x[:] for i in range(len(x)): x[i] = self._s_box[self.split_bit(x[i].data, 8, 2)] return x def _rcon(i): x = [GF2_8(0) for i in range(4)] x[0] = self._rcon_c[i] return x keys = [] cur_key = self.split_bit(raw_key, 128, 16) cur_key = [[cur_key[i + j * 4] for j in range(4)] for i in range(4)] cur_key = Matrix(cur_key, dtype=GF2_8) keys.append(cur_key) for i in range(10): w = [cur_key[j, 3] for j in range(4)] x = _rot_word(w) y = _sub_word(x) z = [y[j] + _rcon(i)[j] for j in range(4)] new_key = Matrix.construct(4, 4, dtype=GF2_8) for j in range(4): new_key[j, 0] = cur_key[j, 0] + z[j] for r in range(3): for j in range(4): new_key[j, r + 1] = new_key[j, r] + cur_key[j, r + 1] cur_key = new_key keys.append(cur_key) self._keys = keys self._keys_inv = [ self._mix_cols_inv(keys[i]) if (0 < i < len(keys) - 1) else keys[i] for i in range(len(keys)) ]
def hill(x, key, m, method='encrypt'): if method == 'encrypt': code = str() for i in range(0, len(x), m): mx = Matrix.construct(1, m, dtype=RF_95) for j in range(m): mx[0, j] = RF_95(ord(x[i + j]) - ord(' ')) my = mx * key for j in range(m): code += chr(int(str(my[0, j])) + ord(' ')) return code elif method == 'decrypt': text = str() key_inv = key.inv() for i in range(0, len(x), m): mx = Matrix.construct(1, m, dtype=RF_95) for j in range(m): mx[0, j] = RF_95(ord(x[i + j]) - ord(' ')) my = mx * key_inv for j in range(m): text += chr(int(str(my[0, j])) + ord(' ')) return text
def _reset_data(self): s_matrix = [[i * 16 + j for j in range(16)] for i in range(16)] s_matrix = Matrix(s_matrix, dtype=GF2_8) a_matrix = [[ 1 if j in [i, (i + 4) % 8, (i + 5) % 8, (i + 6) % 8, (i + 7) % 8] else 0 for j in range(8) ] for i in range(8)] c_matrix = [[1], [1], [0], [0], [0], [1], [1], [0]] a_matrix = Matrix(a_matrix, dtype=GF2_8) c_matrix = Matrix(c_matrix, dtype=GF2_8) for i in range(s_matrix.row): for j in range(s_matrix.col): if s_matrix[i, j] != GF2_8(0): s_matrix[i, j] = s_matrix[i, j].inv temp = self.split_bit(s_matrix[i, j].data, 8, 8)[::-1] temp = [[i] for i in temp] x_matrix = Matrix(temp, dtype=GF2_8) temp = a_matrix * x_matrix + c_matrix temp = [temp[i, 0].data for i in range(temp.row)][::-1] temp = [self.merge_bit(temp, 1)][0] s_matrix[i, j] = GF2_8(temp) self._s_box = s_matrix is_matrix = [[i * 16 + j for j in range(16)] for i in range(16)] is_matrix = Matrix(is_matrix, dtype=GF2_8) b_matrix = [[ 1 if j in [(i + 2) % 8, (i + 5) % 8, (i + 7) % 8] else 0 for j in range(8) ] for i in range(8)] d_matrix = [[1], [0], [1], [0], [0], [0], [0], [0]] b_matrix = Matrix(b_matrix, dtype=GF2_8) d_matrix = Matrix(d_matrix, dtype=GF2_8) for i in range(is_matrix.row): for j in range(is_matrix.col): temp = self.split_bit(is_matrix[i, j].data, 8, 8)[::-1] temp = [[i] for i in temp] ix_matrix = Matrix(temp, dtype=GF2_8) temp = b_matrix * ix_matrix + d_matrix temp = [temp[i, 0].data for i in range(temp.row)][::-1] temp = [self.merge_bit(temp, 1)][0] is_matrix[i, j] = GF2_8(temp) if is_matrix[i, j] != GF2_8(0): is_matrix[i, j] = is_matrix[i, j].inv self._s_box_inv = is_matrix self._rcon_c = [GF2_8(1)] for i in range(9): self._rcon_c.append(GF2_8(2) * self._rcon_c[-1])
def _decrypt(self, data): data = self.split_bit(data, 128, 16) state = [[data[i + j * 4] for j in range(4)] for i in range(4)] state = Matrix(state, dtype=GF2_8) state = state + self._keys_inv[10] for i in range(9, 0, -1): self._sub_bytes_inv(state) state = self._shift_rows_inv(state) state = self._mix_cols_inv(state) state = self._add_round_key(state, self._keys_inv[i]) self._sub_bytes_inv(state) state = self._shift_rows_inv(state) state = self._add_round_key(state, self._keys_inv[0]) data = [state[i, j].data for j in range(4) for i in range(4)] data = self.merge_bit(data, 8) return data
def cracker(text, code, m, s=0): if (s + m) * m > len(text): return -1 mx = Matrix.construct(m, m, dtype=RF_95) my = Matrix.construct(m, m, dtype=RF_95) for i in range(m): for j in range(m): mx[i, j] = RF_95(ord(text[(s + i) * m + j]) - ord(' ')) my[i, j] = RF_95(ord(code[(s + i) * m + j]) - ord(' ')) try: return mx.inv() * my except Exception: return cracker(text, code, m, s + 1) if __name__ == '__main__': import time m = 3 key = Matrix([[3, 9, 1], [6, 5, 1], [3, 4, 9]], dtype=RF_95) text = 'Today is 2019/3/19, this is a sunny day, we feel happy :-)' while len(text) % m != 0: text += ' ' code = hill(text, key, m) print(code) print(hill(code, key, m, method='decrypt')) t1 = time.time() print(cracker(text, code, m)) t2 = time.time() print('Crack Time:{:.10f}'.format(t2 - t1))
def _mix_cols_inv(self, state): transform = [[0xe, 0xb, 0xd, 0x9], [0x9, 0xe, 0xb, 0xd], [0xd, 0x9, 0xe, 0xb], [0xb, 0xd, 0x9, 0xe]] transform = Matrix(transform, dtype=GF2_8) return transform * state
def _mix_cols(self, state): transform = [[2, 3, 1, 1], [1, 2, 3, 1], [1, 1, 2, 3], [3, 1, 1, 2]] transform = Matrix(transform, dtype=GF2_8) return transform * state