aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJ08nY2023-10-13 19:52:05 +0200
committerJ08nY2023-10-13 19:52:05 +0200
commitf1993d49f2ed28cacf5537410c0db99dc8bdeaeb (patch)
tree720da5ec63173488b91f01ac576063674d266d9e
parentdb1636607dc59325aa58aae604dff440a313a9b4 (diff)
downloadpyecsca-f1993d49f2ed28cacf5537410c0db99dc8bdeaeb.tar.gz
pyecsca-f1993d49f2ed28cacf5537410c0db99dc8bdeaeb.tar.zst
pyecsca-f1993d49f2ed28cacf5537410c0db99dc8bdeaeb.zip
Add trace stretch function.
-rw-r--r--profile_orders.py40
-rw-r--r--pyecsca/sca/trace/edit.py26
-rw-r--r--test/sca/test_edit.py10
3 files changed, 69 insertions, 7 deletions
diff --git a/profile_orders.py b/profile_orders.py
new file mode 100644
index 0000000..658b054
--- /dev/null
+++ b/profile_orders.py
@@ -0,0 +1,40 @@
+import numpy as np
+from numpy import random as npr
+from pyecsca.sca.stacked_traces import GPUTraceManager
+from pyecsca.sca.stacked_traces.stacked_traces import StackedTraces
+from test.sca.perf_stacked_combine import (
+ generate_dataset,
+ report,
+ timed,
+)
+
+NREPS = 100
+
+
+def main():
+ rm_times_storage = []
+ cm_times_storage = []
+
+ for _ in range(NREPS):
+ rm_samples = generate_dataset(npr.default_rng(), 2 ** 10, 2 ** 15)
+ rm_data = StackedTraces(rm_samples)
+ rm_tm = GPUTraceManager(
+ rm_data,
+ )
+ timed(rm_times_storage, log=True)(rm_tm.average)()
+
+ cm_samples = np.array(rm_samples, order="F")
+ cm_data = StackedTraces(cm_samples)
+ cm_tm = GPUTraceManager(
+ cm_data,
+ )
+ timed(cm_times_storage, log=True)(cm_tm.average)()
+
+ rm_times = np.array([duration for _, duration in rm_times_storage[1:]])
+ cm_times = np.array([duration for _, duration in cm_times_storage[1:]])
+ print(f"Row major:\n\t{np.mean(rm_times) / 1e6:.3f}ms ± {np.std(rm_times) / 1e6:.3f}ms")
+ print(f"Col major:\n\t{np.mean(cm_times) / 1e6:.3f}ms ± {np.std(cm_times) / 1e6:.3f}ms")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/pyecsca/sca/trace/edit.py b/pyecsca/sca/trace/edit.py
index 52338e6..88e186f 100644
--- a/pyecsca/sca/trace/edit.py
+++ b/pyecsca/sca/trace/edit.py
@@ -11,9 +11,9 @@ def trim(trace: Trace, start: Optional[int] = None, end: Optional[int] = None) -
"""
Trim the `trace` samples, output contains samples between the `start` and `end` indices.
- :param trace:
- :param start:
- :param end:
+ :param trace: The trace to trim.
+ :param start: Starting index (inclusive).
+ :param end: Ending index (exclusive).
:return:
"""
if start is None:
@@ -30,7 +30,7 @@ def reverse(trace: Trace) -> Trace:
"""
Reverse the samples of the `trace`.
- :param trace:
+ :param trace: The trace to reverse.
:return:
"""
return trace.with_samples(np.flipud(trace.samples))
@@ -45,9 +45,9 @@ def pad(
"""
Pad the samples of the `trace` by `values` at the beginning and end.
- :param trace:
+ :param trace: The trace to pad.
:param lengths: How much to pad at the beginning and end, either symmetric (if integer) or asymmetric (if tuple).
- :param values: What value to pad with, either symmetric or asymmetric (if tuple).
+ :param values: What value to pad with, either symmetric or asymmetric (if tuple).
:return:
"""
if not isinstance(lengths, tuple):
@@ -57,3 +57,17 @@ def pad(
return trace.with_samples(
np.pad(trace.samples, lengths, "constant", constant_values=values)
)
+
+
+@public
+def stretch(trace: Trace, length: int) -> Trace:
+ """
+ Stretch (or squeeze) a trace linearly to fit a given length.
+
+ :param trace: The trace to stretch (or squeeze).
+ :param length: The length it should be.
+ :return:
+ """
+ current_indices = np.arange(len(trace))
+ target_indices = np.linspace(0, len(trace) - 1, length)
+ return trace.with_samples(np.interp(target_indices, current_indices, trace.samples)) \ No newline at end of file
diff --git a/test/sca/test_edit.py b/test/sca/test_edit.py
index db80393..98bba09 100644
--- a/test/sca/test_edit.py
+++ b/test/sca/test_edit.py
@@ -1,7 +1,7 @@
import numpy as np
import pytest
-from pyecsca.sca import Trace, trim, reverse, pad
+from pyecsca.sca import Trace, trim, reverse, pad, stretch
@pytest.fixture()
@@ -48,3 +48,11 @@ def test_pad(trace):
result.samples,
np.array([0, 10, 20, 30, 40, 50, 0, 0, 0], dtype=np.dtype("i1")),
)
+
+
+def test_stretch(trace):
+ result = stretch(trace, 10)
+ assert result is not None
+ assert np.min(result) == min(trace)
+ assert np.max(result) == max(trace)
+ assert len(result) == 10