def main(plaintexts, traces): cpa_attacker = Attacker(plaintexts) skey = cpa_attacker.obtain_full_private_key(traces, only_first_byte=False) # Our AES key: # [43, 126, 21, 22, 40, 174, 210, 166, 171, 247, 21, 136, 9, 207, 79, 60] # print(f"First found subkey: {skey[0]}") print(f"Found full key: {skey}")
def test_obtain_full_private_key(self): # Import power traces for which we know the used key. key = np.load(self.TEST_DATA_LOC + "key.npy") power_samples = np.load(self.TEST_DATA_LOC + "traces.npy")[:-1] plaintexts = np.load(self.TEST_DATA_LOC + "plain.npy") # Set up the attacker and find the private key as a list of bytes. attacker = Attacker(plaintexts) computed_key_bytes = attacker.obtain_full_private_key(power_samples) # "key.npy" is stored as an array of identical keys, so get key[0] known_key_bytes = key[0] self.assertEqual(list(known_key_bytes), computed_key_bytes)
i = 0 for _ in range(ITERATIONS): for trace_amnt in TRACES_AMOUNTS: for step in SAMPLE_STEPS: indices = np.random.choice(np.arange(len(traces)), trace_amnt, replace=False) sampled_traces = traces[indices, start_point:end_point:step] sampled_plaintexts = plaintexts[indices, :] cpa_attacker = Attacker(sampled_plaintexts) # If we only obtain the first subkey, it is returned # as a singleton list. best_guess = cpa_attacker.obtain_full_private_key( sampled_traces, only_first_byte=False) ge = atk_analyser.compute_guessing_entropy( known_key, cpa_attacker.subkey_corr_coeffs) key_sr = int(ge == 0) subkey_sr = atk_analyser.compute_subkey_success_rate( known_key, best_guess) results.loc[i] = [trace_amnt, step, ge, key_sr, subkey_sr, FULL] i += 1 print( f"Experiement {i}/{TOTAL_EXPIREMENTS} [trace amount:{trace_amnt}, step: {step}]:" f"GE: {ge}\tKEY SR: {key_sr}\tSUBKEY SR: {subkey_sr}") results.to_csv( f"cpa{'_cm' if CM else ''}_{'full' if FULL else 'cropped'}_results.csv")