def recover_k2(k1): k2 = [] out_bits_list = get_diff_c22() c22a=os.urandom(8) li_c22a=array.array("B",c22a) li_c22b=copy.copy(li_c22a) for pos in xrange(8): li_c22b[pos] = li_c22b[pos]^1 li_c21a = subme.unSubStr(li_c22a) li_c21b = subme.unSubStr(li_c22b) list_ci = get_list_ci_by_c21(li_c21a,pos,k1) for k in xrange(256): li_c21a[pos] = li_c21a[pos]^k li_c21b[pos] = li_c21b[pos]^k ca = list_ci[li_c21a[pos]] cb = list_ci[li_c21b[pos]] bin_ca = s2b(ca[::-1]) bin_cb = s2b(cb[::-1]) diff = make_diff(bin_ca, bin_cb) sbox2 = pos if check_diff2(out_bits_list[sbox2], diff) == True: if check_key_byte2(pos,k1,k) == True: print "k[%d]=%d" % (pos+8,k) k2.append(k) break li_c21a[pos] = li_c21a[pos]^k li_c21b[pos] = li_c21b[pos]^k li_c22b[pos] = li_c22b[pos]^1 return k2
def check_key_byte2(pos,k1,k2): round = 5 #チェック回数 flag = 0 out_bits_list = get_diff_c22() c22a=os.urandom(8) li_c22a=array.array("B",c22a) li_c22b=copy.copy(li_c22a) for i in xrange(round): li_c22b[pos] = li_c22b[pos]^1 li_c21a = subme.unSubStr(li_c22a) li_c21b = subme.unSubStr(li_c22b) li_c21a[pos] = li_c21a[pos]^k2 li_c21b[pos] = li_c21b[pos]^k2 list_ci = get_list_ci_by_c21(li_c21a,pos,k1) ca = list_ci[li_c21a[pos]] cb = list_ci[li_c21b[pos]] bin_ca = s2b(ca[::-1]) bin_cb = s2b(cb[::-1]) diff = make_diff(bin_ca, bin_cb) sbox2 = pos if check_diff2(out_bits_list[sbox2], diff) == True: flag = flag + 1 li_c22b[pos] = li_c22b[pos]^1 if flag == round: return True return False
def recover_k1(): k1 = [] out_bits_list = get_diff_c12() c12a=os.urandom(8) li_c12a=array.array("B",c12a) li_c12b=copy.copy(li_c12a) for pos in xrange(8): li_c12b[pos] = li_c12b[pos]^1 li_ma = subme.unSubStr(li_c12a) li_mb = subme.unSubStr(li_c12b) list_ci = get_list_ci(li_ma,pos) for k in xrange(256): li_ma[pos] = li_ma[pos]^k li_mb[pos] = li_mb[pos]^k ca = list_ci[li_ma[pos]] cb = list_ci[li_mb[pos]] bin_ca = s2b(ca[::-1]) bin_cb = s2b(cb[::-1]) diff = make_diff(bin_ca, bin_cb) sbox2 = inv_bit_order(subme.lper[inv_bit_order(pos*8+7)])/8 if check_diff(out_bits_list[sbox2], diff) == True: if check_key_byte(pos,k) == True: print "k[%d]=%d" % (pos,k) k1.append(k) break li_ma[pos] = li_ma[pos]^k li_mb[pos] = li_mb[pos]^k li_c12b[pos] = li_c12b[pos]^1 return k1
def check_key_byte(pos,k): round = 5 #チェック回数 flag = 0 for i in xrange(round): out_bits_list = get_diff_c12() c12a=os.urandom(8) li_c12a=array.array("B",c12a) li_c12b=copy.copy(li_c12a) li_c12b[pos] = li_c12b[pos]^1 li_ma = subme.unSubStr(li_c12a) li_mb = subme.unSubStr(li_c12b) list_ci = get_list_ci(li_ma,pos) li_ma[pos] = li_ma[pos]^k li_mb[pos] = li_mb[pos]^k ca = list_ci[li_ma[pos]] cb = list_ci[li_mb[pos]] bin_ca = s2b(ca[::-1]) bin_cb = s2b(cb[::-1]) diff = make_diff(bin_ca, bin_cb) sbox2 = inv_bit_order(subme.lper[inv_bit_order(pos*8+7)])/8 if check_diff(out_bits_list[sbox2], diff) == True: flag = flag + 1 li_ma[pos] = li_ma[pos]^k li_mb[pos] = li_mb[pos]^k li_c12b[pos] = li_c12b[pos]^2 if flag == round: return True return False
def get_list_ci_by_c21(li_c21,pos,k1): list_ci = [] msg = [] li_c13=copy.copy(li_c21) for x in xrange(256): li_c13[pos] = x li_c12 = map(ord,subme.unPermute("".join(map(chr,li_c13)))) li_c11 = subme.unSubStr(li_c12) li_m = [] for i in xrange(len(k1)): li_m.append(li_c11[i]^k1[i]) msg.extend("".join(map(chr,li_m))) ci = get_ciphertext("".join(msg)) for x in range(256): list_ci.append(ci[x*8:x*8+8]) return list_ci