def attack_Combine (n) : mask = 0x0000000f best_k16 = 0 for s in range (8): print "Sbox",s score_p = [] score = [] sco = 0.0 best_sk = 0 for sk in range(64): #print "guess",sk fast = 0.0 slow = 0.0 n_fast = 0 n_slow = 0 HW = [] T = [] for i in range (n): lr_16 = des.ip (ct[i]) l_16 = des.right_half (lr_16) sbo = des.sboxes (des.e (l_16) ^ (sk << 6*s)) # ^ means xor hw = hamming_weight (sbo & (mask << 4*s)) # every time the sbo left shift 4 bits HW.append (hw) T.append (t[i]) if hw == 0 or hw ==1: # hw = 0000 or 0000 0000 or ....depends on s fast += t[i] n_fast += 1 #print 'fast' if hw == 4 or hw ==3:# hw = 1111 slow += t[i] n_slow += 1 #print 'slow' score.append (float (slow) / (n_slow) - float (fast) / (n_fast)) num = numpy.corrcoef(T,HW) #print num num = num[0][1] #print 'num', num score_p.append (num) #print score if score_p[sk] > 0 and score[sk]*score_p[sk]*score_p[sk] > sco : sco = score[sk]*score_p[sk]*score_p[sk] best_sk=sk best_k16 |= (best_sk << 6*s) #print "best current key guess",("0x%012X" % best_k16) return (best_k16)
def decision (ct, target_bit): r16l16 = des.ip (ct) # Compute R16|L16 l16 = des.right_half (r16l16) # Extract right half r16 = des.left_half (r16l16) # Extract left half er15 = des.e (l16) # Compute E(R15) = E(L16) d = [] # For all guesses (64). rk is a 48 bits last round key with all 6-bits # subkeys equal to current guess g (nice trick, isn't it?). for g in xrange (64): rk = g * 0x041041041041 l15 = r16 ^ des.p (des.sboxes (er15 ^ rk)) # Compute L15 d.append ((l15 >> (32 - target_bit)) & 1) # Extract value of target bit return d
def decision (ct, target_bit): r16l16 = des.ip (ct) # Compute R16|L16 l16 = des.right_half (r16l16) # Extract right half r16 = des.left_half (r16l16) # Extract left half er15 = des.e (l16) # Compute E(R15) = E(L16) d = [] # For all guesses (64). rk is a 48 bits last round key with all 6-bits # subkeys equal to current guess g (nice trick, isn't it?). for g in xrange (64): rk = g * 0x041041041041 print >> sys.stderr, "binary version of rk is %s" % bin(rk)[2:].zfill(64) l15 = r16 ^ des.p (des.sboxes (er15 ^ rk)) # Compute L15 d.append ((l15 >> (32 - target_bit)) & 1) # Extract value of target bit #print >> sys.stderr, "l15 %d" % l15 #print >> sys.stderr, "Binary version %s" % bin(l15) return d
def attack_Pearson (n) : mask = 0x0000000f best_k16 = 0 for s in range (8): #print "Sbox",s score = [] sco = 0.0 best_sk = 0 for sk in range(64): #print "guess",sk HW = [] T = [] #HW = numpy.array ([0 for x in xrange(n)]) #T = numpy.array ([0 for x in xrange(n)]) for i in range (n): lr_16 = des.ip (ct[i]) l_16 = des.right_half (lr_16) sbo = des.sboxes (des.e (l_16) ^ (sk << 6*s)) # ^ means xor hw = hamming_weight (sbo & (mask << 4*s)) # every time the sbo left shift 4 bits #HW[i] = hw HW.append (hw) #T[i] = t[i] T.append (t[i]) num = numpy.corrcoef(T,HW) #num = pcc(T,HW) #print num num = num[0][1] #print 'num', num score.append (num) #print score if score[sk] > sco : sco = score[sk] best_sk=sk best_k16 |= (best_sk << 6*s) #print "best current key guess",("0x%012X" % best_k16) return (best_k16)
def attack_Basic (n): mask = 0x0000000f best_k16 = 0 for s in range (8): print "Sbox",s score = [] sco = 0.0 best_sk = 0 for sk in range(64): #print "guess",sk fast = 0.0 slow = 0.0 n_fast = 0 n_slow = 0 for i in range (n): lr_16 = des.ip (ct[i]) l_16 = des.right_half (lr_16) sbo = des.sboxes (des.e (l_16) ^ (sk << 6*s)) # ^ means xor hw = hamming_weight (sbo & (mask << 4*s)) # every time the sbo left shift 4 bits if hw == 0 or hw ==1: # hw = 0000 or 0000 0000 or ....depends on s fast += t[i] n_fast += 1 if hw == 4 or hw == 3:# hw = 1111 slow += t[i] n_slow += 1 score.append (float (slow) / (n_slow) - float (fast) / (n_fast)) if score[sk] > sco : sco = score[sk] best_sk=sk best_k16 |= (best_sk << 6*s) print "best current key guess",("0x%012X" % best_k16) return (best_k16)
def dpa_attack (ctx, target_bit): pcc = [0]*64 sbomask = 0xf0000000 key=[] for sbox in range(8): ctx_pcc = tr_pcc.pccContext(ctx.l,64) # pccContext object for i in range(ctx.n): ct = ctx.c[i] r16l16 = des.ip(ct) l16 = des.right_half(r16l16) r15 = l16 r16 = des.left_half(r16l16) er15 = des.e(l16) ctx_pcc.insert_x(ctx.t[i][:]) rk= 0x0 for j in range(64): l15 = r16^des.p(des.sboxes(er15^rk)) r14 = l15 ctx_pcc.insert_y(j, int(hamming_distance(r14 & des.p(sbomask), r15 & des.p(sbomask)))) rk+= 0x041041041041 ctx_pcc.consolidate() dpa = list([ctx_pcc.get_pcc(g) for g in range(64)]) maxs = [max(l) for l in dpa] idx = [l.index(m) for l,m in zip (dpa, maxs)] # Get best maximum best_max = max (maxs) best_guess = maxs.index (best_max) best_idx = idx[best_guess] sbomask = sbomask >> 4 key.append(best_guess) traces.plot('sboxnr' + str(sbox), -1, dpa) # Format output res = '' for i in range(len(key)): res += bin(key[i])[2:].zfill(6) print hex(int(res,2))
def main(): if not des.check (): sys.exit ("DES functional test failed") # ************************************* # * Check arguments and read datafile * # ************************************* argparser = argparse.ArgumentParser(description="Apply P. Kocher's TA algorithm") argparser.add_argument("datafile", metavar='file', help='name of the data file (generated with ta_acquisition)') argparser.add_argument("n", metavar='n', type=int, help='number of experiments to use') args = argparser.parse_args() if args.n < 1: # If invalid number of experiments. sys.exit ("Invalid number of experiments: %d (shall be greater than 1)" % args.n) # print args.n # Read encryption times and ciphertexts. n is the number of experiments to use. read_datafile (args.datafile, args.n) differance = {0:{},1:{},2:{},3:{},4:{},5:{},6:{},7:{}} global slow global fast slow = [] fast = [] sbo = [] for i in range(0,8): slow.append([]); fast.append([]) for j in range(0,64): fast[i].append([]) slow[i].append([]) sbo.append([]) mask = 0xf0000000 subkey = 0x0 for key in range(64): for k in range(0,args.n): sbo[key].append( des.sboxes(des.e(des.right_half(des.ip(ct[k])))^subkey)) subkey += 0x041041041041 mask = 0xf0000000 t1 = myThread(0, slow,fast,args.n,sbo, mask) t2 = myThread(1, slow,fast,args.n,sbo, mask >>4) t3 = myThread(2, slow,fast,args.n,sbo, mask >>8) t4 = myThread(3, slow,fast,args.n,sbo, mask >>12) t5 = myThread(4, slow,fast,args.n,sbo, mask >>16) t6 = myThread(5, slow,fast,args.n,sbo, mask >>20) t7 = myThread(6, slow,fast,args.n,sbo, mask >>24) t8 = myThread(7, slow,fast,args.n,sbo, mask >>28) t1.start() t2.start() t3.start() t4.start() t5.start() t6.start() t7.start() t8.start() threads = [] threads.append(t1) threads.append(t2) threads.append(t3) threads.append(t4) threads.append(t5) threads.append(t6) threads.append(t7) threads.append(t8) for t in threads: t.join() res = '' losning = [] for sbox in range(8): for key in range(64): differance[sbox][key] = (avg(slow[sbox][key]) - avg(fast[sbox][key])) md = max(differance[sbox].values()) for subk in differance[sbox].keys(): if differance[sbox][subk] == md: losning.append(subk) for i in range(len(losning)): res = res + bin(losning[i])[2:].zfill(6) print hex(int(res,2))
def main (): # ************************************************************************ # * Before doing anything else, check the correctness of the DES library * # ************************************************************************ if not des.check (): sys.exit ("DES functional test failed") # ************************************* # * Check arguments and read datafile * # ************************************* argparser = argparse.ArgumentParser(description="Apply P. Kocher's TA algorithm") argparser.add_argument("datafile", metavar='file', help='name of the data file (generated with ta_acquisition)') argparser.add_argument("n", metavar='n', type=int, help='number of experiments to use') args = argparser.parse_args() if args.n < 1: # If invalid number of experiments. sys.exit ("Invalid number of experiments: %d (shall be greater than 1)" % args.n) # Read encryption times and ciphertexts. n is the number of experiments to use. read_datafile (args.datafile, args.n) rk = bk = 0x000000000000 dl = 0 dla = [] for sbox in reversed(xrange(8)): mask = 0x3f << (0x2a - 6*sbox) rk &= ~mask for i in range(64): key = i << (42 - 6*sbox) ctx = pcc.pccContext (1) for j in range(args.n): #Undoes the final permutation on cipher text of n-th experiment. r16l16 = des.ip (ct[j]) #Extract right half (strange naming as in the DES standard). l16 = des.right_half (r16l16) #Compute output of SBoxes during last round of first experiment, assuming the last round key is all zeros. sbo = des.sboxes (des.e (l16) ^ (rk | key)) #Compute Hamming weight of output SBox hw = hamming_weight (sbo) ctx.insert_x(t[j]) ctx.insert_y(0, hw) ctx.consolidate () dli = ctx.get_pcc(0) dla.append(dli) if dli > dl: dl = dli bk = key dl = 0 rk |= bk dla.sort(reverse=True) # ************************************ # * Compute and print average timing * # ************************************ print >> sys.stderr, "Average timing: %f" % (sum (t) / args.n) # ************************ # * Print last round key * # ************************ print >> sys.stderr, "Last round key (hex):" print >> sys.stderr, "0x%012X" % rk print "0x%012X" % rk
def main(): global ct, t # ************************************************************************ # * Before doing anything else, check the correctness of the DES library * # ************************************************************************ if not des.check(): sys.exit("DES functional test failed") # ************************************* # * Check arguments and read datafile * # ************************************* argparser = argparse.ArgumentParser( description="Apply P. Kocher's TA algorithm") argparser.add_argument( "datafile", metavar='file', help='name of the data file (generated with ta_acquisition)') argparser.add_argument("n", metavar='n', type=int, help='number of experiments to use') args = argparser.parse_args() if args.n < 1: # If invalid number of experiments. sys.exit( "Invalid number of experiments: %d (shall be greater than 1)" % args.n) # Read encryption times and ciphertexts. n is the number of experiments to use. read_datafile(args.datafile, args.n) # Filter the input data and calculate the number of filtered experiments t = list(filter(lambda x: x < 1000000, t)) nb = len(t) # Undo the final permutation on cipher text of all experiments r16l16 = [des.ip(ct[i]) for i in range(nb)] # Extract right half (strange naming as in the DES standard) l16 = [des.right_half(i) for i in r16l16] # Compute the average round time per sample t_round = np.array(t) / 16 # Compute the average round time Tround = np.mean(t_round) #Compute the average Sbox time per sample t_sbox = t_round / 8 #Compute the average Sbox time Tsbox = np.mean(t_sbox) # Initialise the key key = 0 # Initialise the old hamming weight array old_ham = np.array(t) * 0 for part in range(1, 9): # Compute the timing model of each sample Tmodel = np.array(Tround * 15 + (8 - part) * Tsbox + old_ham) Tmodel_L = [] hams = [] for k in range(64): step = 48 - part * 6 ham = [ Tham[hamming_weight( des.sboxes(((des.e(l) >> step) ^ k) << step) & 15 * 16**(8 - part))] for l in l16 ] hams += [ham] Tmodel_L += [Tmodel + ham] ctx = pcc.pccContext(64) # Initialize context for 64 Y random variables for i in range(nb): # For nexp experiments ctx.insert_x(t[i]) # Insert realization of X into context for j in range(64): # For the 64 Y random variables ctx.insert_y( j, Tmodel_L[j][i]) # Insert realization of Yj into context ctx.consolidate() # Finalize computation of the 64 PCCs PCCs = [] for j in range(64): # For the 64 Y random variables PCCs += [ctx.get_pcc(j)] # Get PCC(X,Yj) # Take the best PCC best = np.argmax(abs(np.array(PCCs))) # Shift and update the key key = (key << 6) + best # Update the old hamming weight array old_ham += hams[best] # ************************ # * Print last round key * # ************************ #print >> sys.stderr, "Last round key (hex):" print("0x%012x" % key)
def main(): # ************************************************************************ # * Before doing anything else, check the correctness of the DES library * # ************************************************************************ if not des.check(): sys.exit("DES functional test failed") # ************************************* # * Check arguments and read datafile * # ************************************* argparser = argparse.ArgumentParser( description="Apply P. Kocher's TA algorithm") argparser.add_argument( "datafile", metavar='file', help='name of the data file (generated with ta_acquisition)') argparser.add_argument("n", metavar='n', type=int, help='number of experiments to use') args = argparser.parse_args() if args.n < 1: # If invalid number of experiments. sys.exit( "Invalid number of experiments: %d (shall be greater than 1)" % args.n) # Read encryption times and ciphertexts. n is the number of experiments to use. read_datafile(args.datafile, args.n) rk = bk = 0x000000000000 dl = 0 dla = [] for sbox in reversed(xrange(8)): mask = 0x3f << (0x2a - 6 * sbox) rk &= ~mask for i in range(64): key = i << (42 - 6 * sbox) ctx = pcc.pccContext(1) for j in range(args.n): #Undoes the final permutation on cipher text of n-th experiment. r16l16 = des.ip(ct[j]) #Extract right half (strange naming as in the DES standard). l16 = des.right_half(r16l16) #Compute output of SBoxes during last round of first experiment, assuming the last round key is all zeros. sbo = des.sboxes(des.e(l16) ^ (rk | key)) #Compute Hamming weight of output SBox hw = hamming_weight(sbo) ctx.insert_x(t[j]) ctx.insert_y(0, hw) ctx.consolidate() dli = ctx.get_pcc(0) dla.append(dli) if dli > dl: dl = dli bk = key dl = 0 rk |= bk dla.sort(reverse=True) # ************************************ # * Compute and print average timing * # ************************************ print >> sys.stderr, "Average timing: %f" % (sum(t) / args.n) # ************************ # * Print last round key * # ************************ print >> sys.stderr, "Last round key (hex):" print >> sys.stderr, "0x%012X" % rk print "0x%012X" % rk