Skip to content

Commit

Permalink
Test that helpers do not introduce errors
Browse files Browse the repository at this point in the history
  • Loading branch information
TrAyZeN committed Oct 31, 2024
1 parent 7c1d996 commit 131270b
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 8 deletions.
9 changes: 4 additions & 5 deletions benches/dpa.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use muscat::distinguishers::dpa::{dpa, Dpa, DpaProcessor};
use muscat::leakage::sbox;
use ndarray::{Array1, Array2};
use ndarray::{Array1, Array2, ArrayView1};
use ndarray_rand::rand::{rngs::StdRng, SeedableRng};
use ndarray_rand::rand_distr::Uniform;
use ndarray_rand::RandomExt;

fn selection_function(metadata: Array1<u8>, guess: usize) -> bool {
fn selection_function(metadata: ArrayView1<u8>, guess: usize) -> bool {
usize::from(sbox(metadata[1] ^ guess as u8)) & 1 == 1
}

fn dpa_sequential(traces: &Array2<f32>, plaintexts: &Array2<u8>) -> Dpa {
let mut dpa = DpaProcessor::new(traces.shape()[1], 256, selection_function);

for i in 0..traces.shape()[0] {
dpa.update(traces.row(i), plaintexts.row(i).to_owned());
dpa.update(traces.row(i), plaintexts.row(i));
}

dpa.finalize()
Expand All @@ -26,8 +26,7 @@ fn dpa_parallel(traces: &Array2<f32>, plaintexts: &Array2<u8>) -> Dpa {
plaintexts
.rows()
.into_iter()
.map(|x| x.to_owned())
.collect::<Array1<Array1<u8>>>()
.collect::<Array1<ArrayView1<u8>>>()
.view(),
256,
selection_function,
Expand Down
33 changes: 33 additions & 0 deletions src/distinguishers/cpa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,3 +282,36 @@ where
}
}
}

#[cfg(test)]
mod tests {
use super::{cpa, CpaProcessor};
use ndarray::array;

#[test]
fn test_cpa_helper() {
let traces = array![
[77usize, 137, 51, 91],
[72, 61, 91, 83],
[39, 49, 52, 23],
[26, 114, 63, 45],
[30, 8, 97, 91],
[13, 68, 7, 45],
[17, 181, 60, 34],
[43, 88, 76, 78],
[0, 36, 35, 0],
[93, 191, 49, 26],
];
let plaintexts = array![[1usize], [3], [1], [2], [3], [2], [2], [1], [3], [1]];

let leakage_model = |value, guess| value ^ guess;
let mut processor = CpaProcessor::new(traces.shape()[1], 256, 0, leakage_model);
for i in 0..traces.shape()[0] {
processor.update(traces.row(i), plaintexts.row(i));
}
assert_eq!(
processor.finalize().corr(),
cpa(traces.view(), plaintexts.view(), 256, 0, leakage_model, 2).corr()
);
}
}
45 changes: 45 additions & 0 deletions src/distinguishers/cpa_normal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,48 @@ where
}
}
}

#[cfg(test)]
mod tests {
use std::iter::zip;

use super::{cpa, CpaProcessor};
use ndarray::{array, ArrayView1, Axis};

#[test]
fn test_cpa_helper() {
let traces = array![
[77usize, 137, 51, 91],
[72, 61, 91, 83],
[39, 49, 52, 23],
[26, 114, 63, 45],
[30, 8, 97, 91],
[13, 68, 7, 45],
[17, 181, 60, 34],
[43, 88, 76, 78],
[0, 36, 35, 0],
[93, 191, 49, 26],
];
let plaintexts = array![[1usize], [3], [1], [2], [3], [2], [2], [1], [3], [1]];

let leakage_model = |plaintext: ArrayView1<usize>, guess| plaintext[0] ^ guess;
let mut processor = CpaProcessor::new(traces.shape()[1], 1, 256, leakage_model);
for (trace, plaintext) in zip(
traces.axis_chunks_iter(Axis(0), 1),
plaintexts.axis_chunks_iter(Axis(0), 1),
) {
processor.update(trace.map(|&x| x as f32).view(), plaintext.view());
}
assert_eq!(
processor.finalize().corr(),
cpa(
traces.map(|&x| x as f32).view(),
plaintexts.view(),
256,
leakage_model,
2
)
.corr()
);
}
}
45 changes: 45 additions & 0 deletions src/distinguishers/dpa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,48 @@ where
}
}
}

#[cfg(test)]
mod tests {
use super::{dpa, DpaProcessor};
use ndarray::{array, Array1, ArrayView1};

#[test]
fn test_dpa_helper() {
let traces = array![
[77usize, 137, 51, 91],
[72, 61, 91, 83],
[39, 49, 52, 23],
[26, 114, 63, 45],
[30, 8, 97, 91],
[13, 68, 7, 45],
[17, 181, 60, 34],
[43, 88, 76, 78],
[0, 36, 35, 0],
[93, 191, 49, 26],
];
let plaintexts = array![[1], [3], [1], [2], [3], [2], [2], [1], [3], [1]];

let selection_function =
|plaintext: ArrayView1<u8>, guess| (plaintext[0] as usize ^ guess) & 1 == 1;
let mut processor = DpaProcessor::new(traces.shape()[1], 256, selection_function);
for i in 0..traces.shape()[0] {
processor.update(traces.row(i).map(|&x| x as f32).view(), plaintexts.row(i));
}
assert_eq!(
processor.finalize().differential_curves(),
dpa(
traces.view().map(|&x| x as f32).view(),
plaintexts
.rows()
.into_iter()
.collect::<Array1<ArrayView1<u8>>>()
.view(),
256,
selection_function,
2
)
.differential_curves()
);
}
}
32 changes: 29 additions & 3 deletions src/leakage_detection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,12 +317,34 @@ impl Add for TTestProcessor {

#[cfg(test)]
mod tests {
use super::{ttest, TTestProcessor};
use super::{snr, ttest, SnrProcessor, TTestProcessor};
use ndarray::array;

#[test]
fn test_snr_helper() {
let traces = array![
[77, 137, 51, 91],
[72, 61, 91, 83],
[39, 49, 52, 23],
[26, 114, 63, 45],
[30, 8, 97, 91],
[13, 68, 7, 45],
[17, 181, 60, 34],
[43, 88, 76, 78],
[0, 36, 35, 0],
[93, 191, 49, 26],
];
let classes = [1, 3, 1, 2, 3, 2, 2, 1, 3, 1];

let mut processor = SnrProcessor::new(traces.shape()[1], 256);
for (trace, class) in std::iter::zip(traces.rows(), classes.iter()) {
processor.process(trace, *class);
}
assert_eq!(processor.snr(), snr(traces.view(), 256, |i| classes[i], 2));
}

#[test]
fn test_ttest() {
let mut processor = TTestProcessor::new(4);
let traces = [
array![77, 137, 51, 91],
array![72, 61, 91, 83],
Expand All @@ -335,9 +357,12 @@ mod tests {
array![0, 36, 35, 0],
array![93, 191, 49, 26],
];

let mut processor = TTestProcessor::new(4);
for (i, trace) in traces.iter().enumerate() {
processor.process(trace.view(), i % 3 == 0);
}

assert_eq!(
processor.ttest(),
array![
Expand All @@ -351,7 +376,6 @@ mod tests {

#[test]
fn test_ttest_helper() {
let mut processor = TTestProcessor::new(4);
let traces = array![
[77, 137, 51, 91],
[72, 61, 91, 83],
Expand All @@ -366,6 +390,8 @@ mod tests {
];
let trace_classes =
array![true, false, false, true, false, false, true, false, false, true];

let mut processor = TTestProcessor::new(4);
for (i, trace) in traces.rows().into_iter().enumerate() {
processor.process(trace, trace_classes[i]);
}
Expand Down

0 comments on commit 131270b

Please sign in to comment.