def __partition(self, msg,key): """ Return the estimated partition (\in [0,12]) of the message, according to the current sboxes and the current key. The partitioning is done with respect to Brier's original CPA. """ ip= des_block.des_block(msg, 64).ip() l0= ip.subblock(0,32) r0= ip.subblock(32,64) key1 = des_block.__from_int__((key & 0xFC0)>>6,6) key2 = des_block.__from_int__(key,6) e0= r0.e().subblock(self.__sbox*6, (self.__sbox+1)*6) e0_1 = r0.e().subblock( (self.__sbox+1)*6, (self.__sbox+2)*6) s0= l0.xor(r0).p(-1).subblock(self.__sbox*4, (self.__sbox+1)*4) s0_1= l0.xor(r0).p(-1).subblock((self.__sbox+1)*4, (self.__sbox+2)*4) return float( weight( e0.xor(key1).s(self.__sbox).xor(s0) ) + weight(e0_1.xor(key2).s(self.__sbox+1).xor(s0_1) ) )
def __partition(self, msg): """ Return the estimated partition of the message, according to sbox-key couples used to initialize key_estimator. The keys of these couples are either hypothetic or known (previously disclosed). """ ip= des_block.des_block(msg, 64).ip() l0= ip.subblock(0,32) r0= ip.subblock(32,64) e0= r0.e() s0=l0.xor(r0).p(-1) # Computes function selection of attacked or previously disclosed SBox if REGL: w= l0.xor(r0).hw() # Taking R0->L1 tranfert into account else: w= 0 for sbox,key in self.__sbox_key_list: e0_0= e0.subblock(sbox*6, (sbox+1)*6) s0_0= s0.subblock(sbox*4, (sbox+1)*4) db_key= des_block.__from_int__(key, 6) w+= weight( e0_0.xor(db_key).s(sbox).xor(s0_0) ) return float( w )
def __init__(self, sbox, key): """ Initialize the key estimator. sbox is a number between 0 and 7 (included) key is a number between 0 and 63 (included) """ self.__sbox= sbox self.__key = des_block.__from_int__(key, 6)
def recover_full_key(self, subkeys, subkeys2): """ Builds the master key using the first two subkeys """ print("Construction de la cle") # Building an uncomplete key using subkeys turn_key= des_block.des_block() for sb in subkeys: turn_key= turn_key.concat( des_block.__from_int__(sb, 6) ) cd1= turn_key.pc2(-1) c0 = cd1.subblock(0,28).rs(1) d0 = cd1.subblock(28,56).rs(1) uncomp1= c0.concat(d0) # Building another uncomplete key using subkeys2 turn_key= des_block.des_block() turn_key= turn_key.concat(des_block.__from_int__(subkeys2[0], 6)) turn_key= turn_key.concat(des_block.__from_int__(subkeys2[1], 6)) turn_key= turn_key.concat(des_block.__from_int__(subkeys2[2], 6)) turn_key= turn_key.concat(des_block.des_block("0", 6) ) turn_key= turn_key.concat(des_block.__from_int__(subkeys2[3], 6)) turn_key= turn_key.concat(des_block.des_block("0", 6) ) turn_key= turn_key.concat(des_block.__from_int__(subkeys2[4], 6)) turn_key= turn_key.concat(des_block.__from_int__(subkeys2[5], 6)) cd1= turn_key.pc2(-1) c0 = cd1.subblock(0,28).rs(2) d0 = cd1.subblock(28,56).rs(2) uncomp2= c0.concat(d0) # Merging the two subkeys print("Premiere cle incomplete : " + des_block.int2bin(uncomp1.value,56)) print("Deuxieme cle incomplete : " + des_block.int2bin(uncomp2.value,56)) key= des_block.des_block() key= uncomp1.key_or( uncomp2) print("Cle finale : " + des_block.int2bin(key.value, 56)) return key
def get_key(self, msg, crypt): """ Guess the 8 last bits of the full key, using cryptogram. Return the key if found, None elsewhere. """ # Building turn_key turn_key= des_block.des_block() for sb in self.__sbox_breakers: turn_key= turn_key.concat( des_block.__from_int__(sb.get_key(),6) ) # Computing uncomplete initial_key cd1= turn_key.pc2(-1) c0 = cd1.subblock(0,28).rs(1) d0 = cd1.subblock(28,56).rs(1) uncomp_cd0= c0.concat(d0) # Trying encipherement with the remaining 256 possible keys for i in range(256): cd0= uncomp_cd0.fill( des_block.__from_int__(i, 8) ) key= cd0.pc1(-1).fill( des_block.__from_int__(0, 8) ) cip= des_block.des_block(msg, 64).encipher(key) if cip.value() == des_block.des_block(crypt,64).value(): return key return None
def __begin_second_round__(self): """ Calcul des bits deja connus au tour 2 """ turn_key= des_block.des_block() for sb in self.__sbox_breakers: turn_key= turn_key.concat( des_block.__from_int__(sb.get_key(),6) ) # turn_key= des_block.des_block("FFFFFFFFFFFF", 48) print("Premiere sous-cle : " + str(turn_key)) self.__first_subkey= turn_key cd1= turn_key.pc2(-1) c0 = cd1.subblock(0,28).ls(1) d0 = cd1.subblock(28,56).ls(1) subkey2= c0.concat(d0).pc2(1) for i in [0,1,2,4,6,7]: print("Attaque de la boite S" + str(i) + " avec la cle partielle " + str(subkey2.subblock(6*i, 6*i+6).value)) self.__sbox_breakers2.append( sbox_breaker2(i, subkey2.subblock(6*i, 6*i+6).value) )