diff options
| author | J08nY | 2023-10-16 20:14:17 +0200 |
|---|---|---|
| committer | J08nY | 2023-10-16 20:14:52 +0200 |
| commit | 6ad25644a082ba7bd20b63323dde5923624d3078 (patch) | |
| tree | 32ce9e31f7ba23b2994ca6b49b32aac8b15ad7e4 | |
| parent | 87504af64f2176f49534d12e7a72ebc529b16de0 (diff) | |
| download | pyecsca-notebook-6ad25644a082ba7bd20b63323dde5923624d3078.tar.gz pyecsca-notebook-6ad25644a082ba7bd20b63323dde5923624d3078.tar.zst pyecsca-notebook-6ad25644a082ba7bd20b63323dde5923624d3078.zip | |
Update RPA notebook to work with new RPA.
| -rw-r--r-- | re/rpa.ipynb | 120 |
1 files changed, 85 insertions, 35 deletions
diff --git a/re/rpa.ipynb b/re/rpa.ipynb index 29bf15e..995e62d 100644 --- a/re/rpa.ipynb +++ b/re/rpa.ipynb @@ -19,6 +19,11 @@ "import numpy as np\n", "import holoviews as hv\n", "from scipy.signal import find_peaks\n", + "from functools import partial\n", + "\n", + "from IPython.display import HTML, display\n", + "from tqdm.auto import tqdm\n", + "import tabulate\n", "\n", "from pyecsca.ec.model import ShortWeierstrassModel\n", "from pyecsca.ec.coordinates import AffineCoordinateModel\n", @@ -28,6 +33,7 @@ "from pyecsca.ec.point import Point\n", "from pyecsca.ec.mod import Mod\n", "from pyecsca.ec.mult import *\n", + "from pyecsca.misc.cfg import TemporaryConfig\n", "from pyecsca.sca.trace.sampling import downsample_average, downsample_max\n", "from pyecsca.sca.trace.process import normalize, rolling_mean\n", "from pyecsca.sca.trace.combine import average, subtract\n", @@ -98,15 +104,28 @@ "metadata": {}, "outputs": [], "source": [ - "multipliers = []\n", - "multipliers.append(LTRMultiplier(add, dbl, None, False, True, True))\n", - "multipliers.append(LTRMultiplier(add, dbl, None, True, True, True))\n", - "multipliers.append(RTLMultiplier(add, dbl, None, False, True))\n", - "multipliers.append(RTLMultiplier(add, dbl, None, True, True))\n", - "multipliers.append(SimpleLadderMultiplier(add, dbl, None, True, True))\n", - "multipliers.append(BinaryNAFMultiplier(add, dbl, neg, None, True))\n", - "multipliers.append(WindowNAFMultiplier(add, dbl, neg, 3, None, True))\n", - "multipliers.append(WindowNAFMultiplier(add, dbl, neg, 4, None, True))" + "multipliers = [\n", + " LTRMultiplier(add, dbl, None, False, AccumulationOrder.PeqPR, True, True),\n", + " LTRMultiplier(add, dbl, None, True, AccumulationOrder.PeqPR, True, True),\n", + " RTLMultiplier(add, dbl, None, False, AccumulationOrder.PeqPR, True),\n", + " RTLMultiplier(add, dbl, None, True, AccumulationOrder.PeqPR, False),\n", + " SimpleLadderMultiplier(add, dbl, None, True, True),\n", + " BinaryNAFMultiplier(add, dbl, neg, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True),\n", + " WindowNAFMultiplier(add, dbl, neg, 3, None, AccumulationOrder.PeqPR, True, True),\n", + " WindowNAFMultiplier(add, dbl, neg, 4, None, AccumulationOrder.PeqPR, True, True),\n", + " WindowNAFMultiplier(add, dbl, neg, 4, None, AccumulationOrder.PeqPR, False, True),\n", + " SlidingWindowMultiplier(add, dbl, 3, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True),\n", + " SlidingWindowMultiplier(add, dbl, 5, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True),\n", + " FixedWindowLTRMultiplier(add, dbl, 4, None, AccumulationOrder.PeqPR, True),\n", + " FixedWindowLTRMultiplier(add, dbl, 5, None, AccumulationOrder.PeqPR, True),\n", + " FullPrecompMultiplier(add, dbl, None, True, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True, True),\n", + " FullPrecompMultiplier(add, dbl, None, False, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True, True),\n", + " FullPrecompMultiplier(add, dbl, None, False, ProcessingDirection.RTL, AccumulationOrder.PeqPR, True, True),\n", + " BGMWMultiplier(add, dbl, 3, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True),\n", + " BGMWMultiplier(add, dbl, 5, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True),\n", + " CombMultiplier(add, dbl, 3, None, AccumulationOrder.PeqPR, True),\n", + " CombMultiplier(add, dbl, 5, None, AccumulationOrder.PeqPR, True)\n", + "]" ] }, { @@ -129,19 +148,21 @@ "scalar = 0b1010101010101010101010101010101010101010101010101\n", "scalar = 0b1111111111111111111111110000000000000000000000000\n", "scalar = 123456789123456789\n", - "# multiples is a mapping from a multiple (integer) to a set of scalar multipliers that compute said multiple when doing [scalar]\n", + "# multiples is a mapping from a multiple (integer) to a set of scalar multipliers that compute said multiple when doing [scalar]P\n", "multiples = {}\n", "\n", + "table = [[\"Multiplier\", \"multiples\"]]\n", + "\n", "for mult in multipliers:\n", - " print(repr(mult))\n", " with local(MultipleContext()) as ctx:\n", " mult.init(params, g)\n", " res = mult.multiply(scalar)\n", - " print(res, res.to_affine())\n", " for m in ctx.points.values():\n", " s = multiples.setdefault(m, set())\n", " s.add(mult)\n", - " print()\n" + " table.append([str(mult), str(list(ctx.points.values()))])\n", + "\n", + "display(HTML(tabulate.tabulate(table, tablefmt=\"html\", headers=\"firstrow\")))" ] }, { @@ -161,7 +182,7 @@ "metadata": {}, "outputs": [], "source": [ - "k = 7186132\n", + "k = 108\n", "kinv = Mod(k, n).inverse()\n", "P0_target = curve.affine_multiply(P0_aff, int(kinv)).to_model(coords, curve)\n", "\n", @@ -187,14 +208,15 @@ "metadata": {}, "outputs": [], "source": [ + "table = [[\"Multiplier\", \"zero present\", \"multiple computed\"]]\n", + "\n", "for mult in multipliers:\n", - " print(mult.__class__.__name__)\n", " with local(MultipleContext()) as ctx:\n", " mult.init(params, P0_target)\n", " res = mult.multiply(scalar)\n", - " print(\"\\tzero present \", any(map(lambda P: P.X == 0, ctx.points.keys())))\n", - " print(\"\\tmultiple computed\", k in ctx.points.values())\n", - " print()" + " table.append([str(mult), any(map(lambda P: P.X == 0, ctx.points.keys())), k in ctx.points.values()])\n", + "\n", + "display(HTML(tabulate.tabulate(table, tablefmt=\"html\", headers=\"firstrow\")))" ] }, { @@ -209,11 +231,25 @@ "cell_type": "code", "execution_count": null, "id": "67d7705c-6a41-47d9-ad1e-23ea549aaf00", - "metadata": {}, + "metadata": { + "scrolled": true + }, "outputs": [], "source": [ + "table = [[\"Multiple\", \"Multipliers\"]]\n", "for multiple, mults in multiples.items():\n", - " print(multiple, [mult.__class__.__name__ for mult in mults])" + " table.append([bin(multiple), [mult.__class__.__name__ for mult in mults]])\n", + " #print(multiple, [mult.__class__.__name__ for mult in mults])\n", + "\n", + "display(HTML(tabulate.tabulate(table, tablefmt=\"html\", headers=\"firstrow\")))" + ] + }, + { + "cell_type": "markdown", + "id": "9b8e4338-a2a8-468e-8873-c18c77260cfc", + "metadata": {}, + "source": [ + "Note that all of the exploration so far was in a context of a fixed scalar. Even though for a given scalar some multipliers might be indistinguishable from the perspective of the multiples they compute, there may be other scalars that distinguish them." ] }, { @@ -223,7 +259,7 @@ "source": [ "## Reverse-engineering\n", "The `simulated_oracle` function simulates an RPA oracle that detect a zero coordinate point in the scalar multiplication.\n", - "This can be used by the `rpa_distinguish` function to distinguish the true scalar multiplier." + "This can be used by the `rpa_distinguish` function to distinguish the true scalar multiplier. The oracle is parametrized with the simulated multiplier index in the table of multipliers (it simulates this \"real\" multiplier)." ] }, { @@ -233,8 +269,8 @@ "metadata": {}, "outputs": [], "source": [ - "def simulated_oracle(scalar, affine_point):\n", - " real_mult = BinaryNAFMultiplier(add, dbl, neg, None, True)\n", + "def simulated_oracle(scalar, affine_point, simulate_mult_id = 0):\n", + " real_mult = multipliers[simulate_mult_id]\n", " point = affine_point.to_model(params.curve.coordinate_model, params.curve)\n", " with local(MultipleContext()) as ctx:\n", " real_mult.init(params, point)\n", @@ -246,10 +282,18 @@ "cell_type": "code", "execution_count": null, "id": "265eb13a-6028-4fde-9c3f-cc23768ba63e", - "metadata": {}, + "metadata": { + "scrolled": true + }, "outputs": [], "source": [ - "rpa_distinguish(params, multipliers, simulated_oracle)" + "table = [[\"True multiplier\", \"Reversed\", \"Correct\", \"Remaining\"]]\n", + "with TemporaryConfig() as cfg:\n", + " cfg.log.enabled = False\n", + " for i, mult in tqdm(enumerate(multipliers)):\n", + " res = rpa_distinguish(params, multipliers, partial(simulated_oracle, simulate_mult_id = i))\n", + " table.append([mult, res, mult in res, len(res)])\n", + "display(HTML(tabulate.tabulate(table, tablefmt=\"html\", headers=\"firstrow\")))" ] }, { @@ -260,7 +304,7 @@ "The `simulate_trace` function simulates a Hamming weight leakage trace of a given multiplier computing a scalar multiple.\n", "This is used by the `simulated_rpa_trace` function that does the RPA attack on simulated traces and returns the differential\n", "trace. This is in turn used to build the `simulated_rpa_oracle` which can be used by the `rpa_distinguish` function to perform\n", - "RPA-RE and distinguish the true scalar multiplier." + "RPA-RE and distinguish the true scalar multiplier. The oracle is parametrized with the simulated multiplier index in the table of multipliers (it simulates this \"real\" multiplier)." ] }, { @@ -302,8 +346,8 @@ " diff_trace = downsample_max(subtract(random_avg, target_avg), 25)\n", " return diff_trace\n", "\n", - "def simulated_rpa_oracle(scalar, affine_point):\n", - " real_mult = BinaryNAFMultiplier(add, dbl, neg, None, True)\n", + "def simulated_rpa_oracle(scalar, affine_point, simulate_mult_id = 0):\n", + " real_mult = multipliers[simulate_mult_id]\n", " noise = NormalNoice(0, 1)\n", " diff_trace = normalize(simulated_rpa_trace(real_mult, scalar, affine_point, noise))\n", " peaks, props = find_peaks(diff_trace.samples, height=4)\n", @@ -317,7 +361,13 @@ "metadata": {}, "outputs": [], "source": [ - "rpa_distinguish(params, multipliers, simulated_rpa_oracle)" + "table = [[\"True multiplier\", \"Reversed\", \"Correct\", \"Remaining\"]]\n", + "with TemporaryConfig() as cfg:\n", + " cfg.log.enabled = False\n", + " for i, mult in tqdm(enumerate(multipliers)):\n", + " res = rpa_distinguish(params, multipliers, partial(simulated_rpa_oracle, simulate_mult_id = i))\n", + " table.append([mult, res, mult in res, len(res)])\n", + "display(HTML(tabulate.tabulate(table, tablefmt=\"html\", headers=\"firstrow\")))" ] }, { @@ -325,7 +375,7 @@ "id": "e694b3b3-290d-4528-a611-16a183662944", "metadata": {}, "source": [ - "Note that the oracle function above has several parameters, like noise amplitude, amount of traces simulated and peak finding height threshold. The cell below compares the differential RPA trace when the multiple is computed in the simulation vs when it is not." + "Note that the oracle function above has several parameters, like noise amplitude, amount of traces simulated, amount of downsampling and peak finding height threshold. The cell below compares the differential RPA trace when the multiple is computed in the simulation vs when it is not." ] }, { @@ -335,15 +385,15 @@ "metadata": {}, "outputs": [], "source": [ - "diff_real = normalize(simulated_rpa_trace(BinaryNAFMultiplier(add, dbl, neg, None, True), scalar, P0_target.to_affine(), NormalNoice(0, 1)))\n", - "diff_nothing = normalize(simulated_rpa_trace(LTRMultiplier(add, dbl, None, False, True, True), scalar, P0_target.to_affine(), NormalNoice(0, 1)))\n", - "plot_traces(diff_real, diff_nothing).opts(width=950, height=600)" + "diff_real = normalize(simulated_rpa_trace(multipliers[0], scalar, P0_target.to_affine(), NormalNoice(0, 1)))\n", + "diff_nothing = normalize(simulated_rpa_trace(multipliers[5], scalar, P0_target.to_affine(), NormalNoice(0, 1)))\n", + "plot_traces(diff_real, diff_nothing).opts(responsive=True, height=600)" ] }, { "cell_type": "code", "execution_count": null, - "id": "51a78d40-0cc1-49e2-9753-ddf49a496ed9", + "id": "efea0ab4-1745-4a13-87fa-501f35cbe903", "metadata": {}, "outputs": [], "source": [] @@ -365,7 +415,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.3" + "version": "3.11.4" } }, "nbformat": 4, |
