Commit 2bee7dda authored by YUSHIQIAN's avatar YUSHIQIAN
Browse files

final version of hamming weight, hamming distance with 1bit, 4bits

parent d4275e07
......@@ -98,7 +98,6 @@ int
main (int argc, char **argv)
{
int n; /* Number of experiments to use. */
int target_bit; /* Index of target bit. */
char *key_bits[8] = {"1-6", "7-12", "13-18", "19-24", "25-30", "31-36", "37-42", "43-48"};
int sbox_idx[8] = {0,0,0,0,0,0,0,0};
......@@ -120,9 +119,9 @@ main (int argc, char **argv)
/*************************************/
/* If invalid number of arguments (including program name), exit with error
* message. */
if (argc != 4)
if (argc != 3)
{
ERROR (-1, "usage: dpa <file> <n> <b>\n <file>: name of the traces file in HWSec format\n (e.g. /datas/teaching/courses/HWSec/labs/data/HWSecTraces10000x00800.hws)\n <n>: number of experiments to use\n <b>: index of target bit in L15 (1 to 32, as in DES standard)\n");
ERROR (-1, "usage: dpa <file> <n> <b>\n <file>: name of the traces file in HWSec format\n (e.g. /datas/teaching/courses/HWSec/labs/data/HWSecTraces10000x00800.hws)\n <n>: number of experiments to use\n");
}
/* Number of experiments to use is argument #2, convert it to integer and
* store the result in variable n. */
......@@ -132,14 +131,6 @@ main (int argc, char **argv)
ERROR (-1, "invalid number of experiments: %d (shall be greater than 1)", n);
}
/* Target bit is argument #3, convert it to integer and store the result in
* variable target_bit. */
target_bit = atoi (argv[3]);
if (target_bit == 0)
{
printf("target all 32 bits \n");
}
/* Read power traces and ciphertexts. Name of data file is argument #1. n is
* the number of experiments to use. */
read_datafile (argv[1], n);
......@@ -151,8 +142,6 @@ main (int argc, char **argv)
*****************************************************************************/
average ("average");
printf ("...begin attack.....\n");
/***************************************************************
* Attack target bit in L15=R14 with P. Kocher's DPA technique *
***************************************************************/
......@@ -161,14 +150,13 @@ main (int argc, char **argv)
/*****************
* Print summary *
*****************/
printf ("DES chart.................\n");
int w = 20;
printf ("%*s%*s%*s%*s\n", w, "key bits", w, "best guess", w, "max amplitue", w, "max index");
int w = 18;
printf ("%*s%*s%*s%*s\n", w, "key bits", w, "best guess", w, "max pcc", w, "max index");
for (i = 0; i < nBytes; i++) /* for every sbox */
{
for (j = 0; j < nBest/2; j++)
{
printf ("%*s (0x%02x),%d (0x%02x)%d%15.2f,%5.2f%16d,%d\n", w, key_bits[i],
printf ("%*s (0x%02x),%2d (0x%02x)%2d %10.2f,%5.2f%10d,%3d\n", w, key_bits[i],
best_guess[i][2*j], best_guess[i][2*j],
best_guess[i][2*j+1], best_guess[i][2*j+1],
best_max[i][2*j], best_max[i][2*j+1],
......@@ -279,7 +267,6 @@ decision (uint64_t ct, int s, int hd[64]) /* compute the hamming distance betwee
uint64_t r15; /* L15 (as in DES standard) */
uint64_t invp_l15; /* inverse of P permutation of l15, L15 = R14 */
uint64_t l15;
r16l16 = des_ip (ct); /* Compute R16|L16 */
l16 = des_right_half (r16l16); /* Extract right half */
......@@ -292,18 +279,10 @@ decision (uint64_t ct, int s, int hd[64]) /* compute the hamming distance betwee
for (g = 0, rk = UINT64_C (0); g < 64; g++, rk += UINT64_C (0x041041041041))
{
invp_l15 = des_n_p (r16) ^ (des_sboxes (er15 ^ rk)); /* Compute L15 deducing scatter */
l15 = r16 ^ des_p (des_sboxes (er15 ^ rk));
hd[g] = hamming_distance (
(invp_l15 >> (4*(nBytes-s-1))) & UINT64_C(15),
(r15 >> (4*(nBytes-s-1))) & UINT64_C(15)
(des_n_p (l16) >> (4*(nBytes-s-1))) & UINT64_C(15)
); /* calculate hamming distance of r15 and r14 */
/*printf("r15: %llx, invp_l15: %llx, %llx\n", r15, invp_l15, des_n_p(l15));
printf("hamming distance between %llx and %llx is %d\n",
(invp_l15 >> (4*(nBytes-s-1))) & UINT64_C(15),
(r15 >> (4*(nBytes-s-1))) & UINT64_C(15),
hd[g]);*/
} /* End for guesses */
return;
}
......@@ -373,23 +352,16 @@ dpa_attack (void)
/*printf("get pcc======\n");*/
pcc[g] = tr_pcc_get_pcc(pcc_ctx, g);
/*printf("PCC(X[.], Y%d)[.] =", g);*/
for(i = 0; i < l; i++)
/*for (i = 0; i < l; i++)
{
/*printf(" %lf", pcc[i]);
printf("\n");*/
if (i < 300 || i > 600)
if (i < 550 || i > 625)
{
pcc[g][i] = 0.0;
}
}
}*/
/* pick two maximum dpa */
max = tr_max (ctx, pcc[g], &idx); /* Get max and argmax of DPA trace */
if (s == 0 && g == 60){printf("======%f, %d", max, idx);}
if (max > best_max[s][0] || g == 0) /* If better than current best max (or if first guess) */
{
......
/**********************************************************************************
Copyright Institut Telecom
Contributors: Renaud Pacalet (renaud.pacalet@telecom-paristech.fr)
This software is a computer program whose purpose is to experiment timing and
power attacks against crypto-processors.
This software is governed by the CeCILL license under French law and
abiding by the rules of distribution of free software. You can use,
modify and/ or redistribute the software under the terms of the CeCILL
license as circulated by CEA, CNRS and INRIA at the following URL
"http://www.cecill.info".
As a counterpart to the access to the source code and rights to copy,
modify and redistribute granted by the license, users are provided only
with a limited warranty and the software's author, the holder of the
economic rights, and the successive licensors have only limited
liability.
In this respect, the user's attention is drawn to the risks associated
with loading, using, modifying and/or developing or reproducing the
software by the user in light of its specific status of free software,
that may mean that it is complicated to manipulate, and that also
therefore means that it is reserved for developers and experienced
professionals having in-depth computer knowledge. Users are therefore
encouraged to load and test the software's suitability as regards their
requirements in conditions enabling the security of their systems and/or
data to be ensured and, more generally, to use and operate it in the
same conditions as regards security.
The fact that you are presently reading this means that you have had
knowledge of the CeCILL license and that you accept its terms. For more
information see the LICENCE-fr.txt or LICENSE-en.txt files.
**********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
#include <math.h>
#include <utils.h>
#include <traces.h>
#include <des.h>
/* The P permutation table, as in the standard. The first entry (16) is the
* position of the first (leftmost) bit of the result in the input 32 bits word.
* Used to convert target bit index into SBox index (just for printed summary
* after attack completion). */
int p_table[32] = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
tr_context ctx; /* Trace context (see traces.h) */
int best_guess[32][2]; /* Best guess */
int best_idx[32][2]; /* Best argmax */
float best_max[32][2]; /* Best max sample value */
float *dpa[64]; /* 64 DPA traces */
int nBest = 2;
int nBytes = 8;
int nBits = 6;
int target_sbox; /* Index of target SBox. */
/* A function to allocate cipher texts and power traces, read the
* datafile and store its content in allocated context. */
void read_datafile (char *name, int n);
/* Compute the average power trace of the traces context ctx, print it in file
* <prefix>.dat and print the corresponding gnuplot command in <prefix>.cmd. In
* order to plot the average power trace, type: $ gnuplot -persist <prefix>.cmd
* */
void average (char *prefix);
/* Decision function: takes a ciphertext and returns an array of 64 values for
* an intermediate DES data, one per guess on a 6-bits subkey. In this example
* the decision is the computed value of bit index <target_bit> of L15. Each of
* the 64 decisions is thus 0 or 1.*/
void decision (uint64_t ct, int d[64], int target_bit);
/* Apply P. Kocher's DPA algorithm based on decision function. Computes 64 DPA
* traces dpa[0..63], best_guess (6-bits subkey corresponding to highest DPA
* peak), best_idx (index of sample with maximum value in best DPA trace) and
* best_max (value of sample with maximum value in best DPA trace). */
void dpa_attack (int target_bit);
int
main (int argc, char **argv)
{
int n; /* Number of experiments to use. */
int g; /* Guess on a 6-bits subkey */
/************************************************************************/
/* Before doing anything else, check the correctness of the DES library */
/************************************************************************/
if (!des_check ())
{
ERROR (-1, "DES functional test failed");
}
/*************************************/
/* Check arguments and read datafile */
/*************************************/
/* If invalid number of arguments (including program name), exit with error
* message. */
if (argc != 3)
{
ERROR (-1, "usage: dpa <file> <n> <b>\n <file>: name of the traces file in HWSec format\n (e.g. /datas/teaching/courses/HWSec/labs/data/HWSecTraces10000x00800.hws)\n <n>: number of experiments to use\n");
}
/* Number of experiments to use is argument #2, convert it to integer and
* store the result in variable n. */
n = atoi (argv[2]);
if (n < 1) /* If invalid number of experiments. */
{
ERROR (-1, "invalid number of experiments: %d (shall be greater than 1)", n);
}
/* Read power traces and ciphertexts. Name of data file is argument #1. n is
* the number of experiments to use. */
read_datafile (argv[1], n);
/*****************************************************************************
* Compute and print average power trace. Store average trace in file
* "average.dat" and gnuplot command in file "average.cmd". In order to plot
* the average power trace, type: $ gnuplot -persist average.cmd
*****************************************************************************/
average ("average");
int ordered_best_guess[8][4 * nBest]; /* Best guess */
int ordered_best_idx[8][4 * nBest]; /* Best argmax */
float ordered_best_max[8][4 * nBest]; /* Best max sample value */
int ordered_target_bit[8][4 * nBest];
char *key_bits[8] = {"1-6", "7-12", "13-18", "19-24", "25-30", "31-36", "37-42", "43-48"};
int sbox_idx[8] = {0,0,0,0,0,0,0,0};
int i = 0;
int j = 0;
for (i = 1; i <= 32; i++) /* for all 32 target bits of L15 */
{
/* Compute index of corresponding SBox */
target_sbox = (p_table[i - 1] - 1) / 4 + 1;
/***************************************************************
* Attack target bit in L15=R14 with P. Kocher's DPA technique *
***************************************************************/
dpa_attack (i);
ordered_target_bit[target_sbox-1][sbox_idx[target_sbox-1]] = i;
for (j = 0; j < nBest; j++)
{
ordered_best_guess[target_sbox-1][sbox_idx[target_sbox-1]] = best_guess[i-1][j];
ordered_best_max[target_sbox-1][sbox_idx[target_sbox-1]] = best_max[i-1][j];
ordered_best_idx[target_sbox-1][sbox_idx[target_sbox-1]] = best_idx[i-1][j];
sbox_idx[target_sbox-1]++;
}
/*printf ("end.....%d\n", sbox_idx[target_sbox-1]); */
} /* end of 32 bits */
/*****************
* Print summary *
*****************/
printf ("DES chart.................\n");
int w = 20;
printf ("%*s%*s%*s%*s%*s\n", w, "key bits", w, "best guess", w, "target bit", 25, "max amplitue (*1000)", 15, "max index");
for (i = 0; i < nBytes; i++) /* for every sbox */
{
for (j = 0; j < 4; j++)
{
printf ("%*s%10d (0x%02x),%2d (0x%02x)%10d%15.2f,%5.2f%16d,%3d\n", w, key_bits[i],
ordered_best_guess[i][2*j], ordered_best_guess[i][2*j],
ordered_best_guess[i][2*j+1], ordered_best_guess[i][2*j+1],
ordered_target_bit[i][2*j],
ordered_best_max[i][2*j]*1000, ordered_best_max[i][2*j+1]*1000,
ordered_best_idx[i][2*j],ordered_best_idx[i][2*j+1]);
}
/*printf("print end\n");*/
}
/*printf("check if the round key is right\n");*/
uint64_t key; /* 64 bits secret key */
uint64_t ks[16]; /* Key schedule (array of 16 round keys) */
uint64_t subkey = 0;
key = tr_key (ctx); /* Extract 64 bits secret key from context */
des_ks (ks, key); /* Compute key schedule */
/*printf ("the right round key is 0x%llx\n", ks[15]);*/
for (i = 0; i < nBytes; i++){
sbox_idx[i] = 0;
}
for (sbox_idx[0] = 0; sbox_idx[0] < 4*nBest; sbox_idx[0]++){
for (sbox_idx[1] = 0; sbox_idx[1] < 4*nBest; sbox_idx[1]++){
for (sbox_idx[2] = 0; sbox_idx[2] < 4*nBest; sbox_idx[2]++){
for (sbox_idx[3] = 0; sbox_idx[3] < 4*nBest; sbox_idx[3]++){
for (sbox_idx[4] = 0; sbox_idx[4] < 4*nBest; sbox_idx[4]++){
for (sbox_idx[5] = 0; sbox_idx[5] < 4*nBest; sbox_idx[5]++){
for (sbox_idx[6] = 0; sbox_idx[6] < 4*nBest; sbox_idx[6]++){
for (sbox_idx[7] = 0; sbox_idx[7] < 4*nBest; sbox_idx[7]++){
subkey =
((uint64_t)ordered_best_guess[0][sbox_idx[0]] << ((nBytes-0-1) * nBits))
| ((uint64_t)ordered_best_guess[1][sbox_idx[1]] << ((nBytes-1-1) * nBits))
| ((uint64_t)ordered_best_guess[2][sbox_idx[2]] << ((nBytes-2-1) * nBits))
| ((uint64_t)ordered_best_guess[3][sbox_idx[3]] << ((nBytes-3-1) * nBits))
| ((uint64_t)ordered_best_guess[4][sbox_idx[4]] << ((nBytes-4-1) * nBits))
| ((uint64_t)ordered_best_guess[5][sbox_idx[5]] << ((nBytes-5-1) * nBits))
| ((uint64_t)ordered_best_guess[6][sbox_idx[6]] << ((nBytes-6-1) * nBits))
| ((uint64_t)ordered_best_guess[7][sbox_idx[7]] << ((nBytes-7-1) * nBits));
if (subkey == ks[15])
{
/* If guessed 16th round key matches actual 16th round key */
printf ("We got it!!! the secret key is 0x%llx\n", subkey); /* Cheers */
/*************************
* Free allocated traces *
*************************/
for (g = 0; g < 64; g++) /* For all guesses for 6-bits subkey */
{
tr_free_trace (ctx, dpa[g]);
}
tr_free (ctx); /* Free traces context */
return 0; /* Exits with "everything went fine" status. */
}
}
}
}
}
}
}
}
}
/*************************
* Free allocated traces *
*************************/
for (g = 0; g < 64; g++) /* For all guesses for 6-bits subkey */
{
tr_free_trace (ctx, dpa[g]);
}
tr_free (ctx); /* Free traces context */
return 0; /* Exits with "everything went fine" status. */
}
void
read_datafile (char *name, int n)
{
int tn;
ctx = tr_init (name, n);
tn = tr_number (ctx);
if (tn != n)
{
tr_free (ctx);
ERROR (-1, "Could not read %d experiments from traces file. Traces file contains %d experiments.", n, tn);
}
}
void
average (char *prefix)
{
int i; /* Loop index */
int n; /* Number of traces. */
float *sum; /* Power trace for the sum */
float *avg; /* Power trace for the average */
n = tr_number (ctx); /* Number of traces in context */
sum = tr_new_trace (ctx); /* Allocate a new power trace for the sum. */
avg = tr_new_trace (ctx); /* Allocate a new power trace for the average. */
tr_init_trace (ctx, sum, 0.0); /* Initialize sum trace to all zeros. */
for (i = 0; i < n; i++) /* For all power traces */
{
tr_acc (ctx, sum, tr_trace (ctx, i)); /* Accumulate trace #i to sum */
} /* End for all power traces */
/* Divide trace sum by number of traces and put result in trace avg */
tr_scalar_div (ctx, avg, sum, (float) (n));
tr_plot (ctx, prefix, 1, -1, &avg);
printf ("Average power trace stored in file '%s.dat'. In order to plot it, type:\n", prefix);
printf ("$ gnuplot -persist %s.cmd\n", prefix);
tr_free_trace (ctx, sum); /* Free sum trace */
tr_free_trace (ctx, avg); /* Free avg trace */
}
void
decision (uint64_t ct, int d[64], int target_bit)
{
int g; /* Guess */
uint64_t r16l16; /* R16|L16 (64 bits state register before final permutation) */
uint64_t l16; /* L16 (as in DES standard) */
uint64_t r16; /* R16 (as in DES standard) */
uint64_t er15; /* E(R15) = E(L16) */
uint64_t l15; /* L15 (as in DES standard) */
uint64_t rk; /* Value of last round key */
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) */
/* 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 = 0, rk = UINT64_C (0); g < 64; g++, rk += UINT64_C (0x041041041041))
{
l15 = r16 ^ des_p (des_sboxes (er15 ^ rk)); /* Compute L15 */
d[g] = hamming_distance (
(l15 >> (32 - target_bit)) & UINT64_C (1),
(l16 >> (32 - target_bit)) & UINT64_C (1)
);
/*d[g] = (l15 >> (32 - target_bit)) & UINT64_C (1); */
} /* End for guesses */
}
void
dpa_attack (int target_bit)
{
int i; /* Loop index */
int n; /* Number of traces. */
int g; /* Guess on a 6-bits subkey */
int idx = 0;; /* Argmax (index of sample with maximum value in a trace) */
int d[64]; /* Decisions on the target bit */
float *t; /* Power trace */
float max = 0.0; /* Max sample value in a trace */
float *t0[64]; /* Power traces for the zero-sets (one per guess) */
float *t1[64]; /* Power traces for the one-sets (one per guess) */
int n0[64]; /* Number of power traces in the zero-sets (one per guess) */
int n1[64]; /* Number of power traces in the one-sets (one per guess) */
uint64_t ct; /* Ciphertext */
for (g = 0; g < 64; g++) /* For all guesses for 6-bits subkey */
{
dpa[g] = tr_new_trace (ctx); /* Allocate a DPA trace */
t0[g] = tr_new_trace (ctx); /* Allocate a trace for zero-set */
tr_init_trace (ctx, t0[g], 0.0); /* Initialize trace to all zeros */
n0[g] = 0; /* Initialize trace count in zero-set to zero */
t1[g] = tr_new_trace (ctx); /* Allocate a trace for one-set */
tr_init_trace (ctx, t1[g], 0.0); /* Initialize trace to all zeros */
n1[g] = 0; /* Initialize trace count in one-set to zero */
} /* End for all guesses */
n = tr_number (ctx); /* Number of traces in context */
for (i = 0; i < n; i++) /* For all experiments */
{
t = tr_trace (ctx, i); /* Get power trace */
ct = tr_ciphertext (ctx, i); /* Get ciphertext */
decision (ct, d, target_bit); /* Compute the 64 decisions */
/* For all guesses (64) */
for (g = 0; g < 64; g++)
{
if (d[g] == 0) /* If decision on target bit is zero */
{
tr_acc (ctx, t0[g], t); /* Accumulate power trace in zero-set */
n0[g] += 1; /* Increment traces count for zero-set */
}
else /* If decision on target bit is one */
{
tr_acc (ctx, t1[g], t); /* Accumulate power trace in one-set */
n1[g] += 1; /* Increment traces count for one-set */
}
} /* End for guesses */
} /* End for experiments */
best_guess[target_bit-1][0] = 0; /* Initialize best guess */
best_max[target_bit-1][0] = 0.0; /* Initialize best maximum sample */
best_idx[target_bit-1][0] = 0; /* Initialize best argmax (index of maximum sample) */
best_guess[target_bit-1][1] = 0; /* Initialize best guess */
best_max[target_bit-1][1] = 0.0; /* Initialize best maximum sample */
best_idx[target_bit-1][1] = 0; /* Initialize best argmax (index of maximum sample) */
for (g = 0; g < 64; g++) /* For all guesses for 6-bits subkey */
{
tr_scalar_div (ctx, t0[g], t0[g], (float) (n0[g])); /* Normalize zero-set */
tr_scalar_div (ctx, t1[g], t1[g], (float) (n1[g])); /* Normalize zero-set */
tr_sub (ctx, dpa[g], t1[g], t0[g]); /* Compute one-set minus zero-set */
/* pick two maximum dpa */
max = tr_max (ctx, dpa[g], &idx); /* Get max and argmax of DPA trace */
if (max > best_max[target_bit-1][0] || g == 0) /* If better than current best max (or if first guess) */
{
best_max[target_bit-1][1] = best_max[target_bit-1][0];
best_idx[target_bit-1][1] = best_idx[target_bit-1][0];
best_guess[target_bit-1][1] = best_guess[target_bit-1][0];
best_max[target_bit-1][0] = max; /* Overwrite best max with new one */
best_idx[target_bit-1][0] = idx; /* Overwrite best argmax with new one */
best_guess[target_bit-1][0] = g; /* Overwrite best guess with new one */
}
} /* End for all guesses */
/* Free allocated traces */
for (g = 0; g < 64; g++) /* For all guesses for 6-bits subkey */
{
tr_free_trace (ctx, t0[g]);
tr_free_trace (ctx, t1[g]);
}
}
/**********************************************************************************
Copyright Institut Telecom
Contributors: Renaud Pacalet (renaud.pacalet@telecom-paristech.fr)
This software is a computer program whose purpose is to experiment timing and
power attacks against crypto-processors.
This software is governed by the CeCILL license under French law and
abiding by the rules of distribution of free software. You can use,
modify and/ or redistribute the software under the terms of the CeCILL
license as circulated by CEA, CNRS and INRIA at the following URL
"http://www.cecill.info".
As a counterpart to the access to the source code and rights to copy,
modify and redistribute granted by the license, users are provided only
with a limited warranty and the software's author, the holder of the
economic rights, and the successive licensors have only limited
liability.
In this respect, the user's attention is drawn to the risks associated
with loading, using, modifying and/or developing or reproducing the
software by the user in light of its specific status of free software,
that may mean that it is complicated to manipulate, and that also
therefore means that it is reserved for developers and experienced
professionals having in-depth computer knowledge. Users are therefore
encouraged to load and test the software's suitability as regards their
requirements in conditions enabling the security of their systems and/or
data to be ensured and, more generally, to use and operate it in the
same conditions as regards security.
The fact that you are presently reading this means that you have had
knowledge of the CeCILL license and that you accept its terms. For more
information see the LICENCE-fr.txt or LICENSE-en.txt files.
**********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
#include <math.h>
#include <utils.h>
#include <traces.h>
#include <des.h>
/* The P permutation table, as in the standard. The first entry (16) is the
* position of the first (leftmost) bit of the result in the input 32 bits word.
* Used to convert target bit index into SBox index (just for printed summary
* after attack completion). */
int p_table[32] = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
tr_context ctx; /* Trace context (see traces.h) */
int best_guess[32][2]; /* Best guess */
int best_idx[32][2]; /* Best argmax */
float best_max[32][2]; /* Best max sample value */
float *dpa[64]; /* 64 DPA traces */
int nBest = 2;
int nBytes = 8;
int nBits = 6;
int target_sbox; /* Index of target SBox. */
/* A function to allocate cipher texts and power traces, read the
* datafile and store its content in allocated context. */
void read_datafile (char *name, int n);
/* Compute the average power trace of the traces context ctx, print it in file
* <prefix>.dat and print the corresponding gnuplot command in <prefix>.cmd. In
* order to plot the average power trace, type: $ gnuplot -persist <prefix>.cmd
* */
void average (char *prefix);
/* Decision function: takes a ciphertext and returns an array of 64 values for
* an intermediate DES data, one per guess on a 6-bits subkey. In this example
* the decision is the computed value of bit index <target_bit> of L15. Each of
* the 64 decisions is thus 0 or 1.*/
void decision (uint64_t ct, int d[64], int target_bit);
/* Apply P. Kocher's DPA algorithm based on decision function. Computes 64 DPA
* traces dpa[0..63], best_guess (6-bits subkey corresponding to highest DPA