diff options
| author | Ján Jančár | 2023-10-02 19:19:03 +0200 |
|---|---|---|
| committer | GitHub | 2023-10-02 19:19:03 +0200 |
| commit | 7316ceac35ced91d53d879a4c6ca4d1177d4abe2 (patch) | |
| tree | 4ed4b28614510cfc9f02b5bea4c44485fb95fb05 | |
| parent | d05ff78a0b51aad0e9062be992ab7f6f19765b09 (diff) | |
| parent | 777c12ea60087d9155f6408a908b878fea94923c (diff) | |
| download | pyecsca-notebook-7316ceac35ced91d53d879a4c6ca4d1177d4abe2.tar.gz pyecsca-notebook-7316ceac35ced91d53d879a4c6ca4d1177d4abe2.tar.zst pyecsca-notebook-7316ceac35ced91d53d879a4c6ca4d1177d4abe2.zip | |
Merge pull request #2 from andrr3j/DPA
DPA notebook
| -rw-r--r-- | DPA.ipynb | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/DPA.ipynb b/DPA.ipynb new file mode 100644 index 0000000..382cacc --- /dev/null +++ b/DPA.ipynb @@ -0,0 +1,264 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Differential power analysis on pyecsca emulated traces" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Setup" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pyecsca.ec.mult import LTRMultiplier\n", + "from pyecsca.ec.mod import Mod\n", + "from pyecsca.ec.point import Point, InfinityPoint\n", + "from pyecsca.ec.model import ShortWeierstrassModel\n", + "from pyecsca.ec.curve import EllipticCurve\n", + "from pyecsca.ec.params import DomainParameters\n", + "from pyecsca.sca.attack.DPA import DPA\n", + "from pyecsca.sca.attack.leakage_model import HammingWeight\n", + "from pyecsca.sca.target.emulator import EmulatorTarget\n", + "from random import randint\n", + "import holoviews as hv" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hv.extension(\"bokeh\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model = ShortWeierstrassModel()\n", + "coords = model.coordinates[\"projective\"]\n", + "p = 0xd7d1247f\n", + "a = Mod(0xa4a44016, p)\n", + "b = Mod(0x73f76716, p)\n", + "n = 0xd7d2a475\n", + "h = 1\n", + "gx, gy, gz = Mod(0x54eed6d7, p), Mod(0x6f1e55ac, p), Mod(1, p)\n", + "generator = Point(coords, X=gx, Y=gy, Z=gz)\n", + "neutral = InfinityPoint(coords)\n", + "\n", + "curve = EllipticCurve(model, coords, p, neutral, {\"a\": a, \"b\": b})\n", + "params = DomainParameters(curve, generator, n, h)\n", + "\n", + "add = coords.formulas[\"add-2015-rcb\"]\n", + "dbl = coords.formulas[\"dbl-2015-rcb\"]\n", + "scl = coords.formulas[\"z\"]\n", + "\n", + "mult = LTRMultiplier(add, dbl, None)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "scalar_bit_length = 8\n", + "secret_scalar = randint(128, 255)\n", + "print(secret_scalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Emulation of traces" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "num_of_traces = 5000" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "emulator = EmulatorTarget(model, coords, mult)\n", + "emulator.set_params(params)\n", + "emulator.set_leakage_model(HammingWeight())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "points, traces = emulator.emulate_scalar_mult_traces(num_of_traces, secret_scalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### DPA" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mult.init(params, params.generator)\n", + "real_pub_key = mult.multiply(secret_scalar)\n", + "dpa = DPA(points, traces, mult, params)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Recover the 8-bit scalar bit by bit" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "recovered_scalar = 128 #1000 0000" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "recovered_scalar = dpa.recover_bit(recovered_scalar, 1, scalar_bit_length, real_pub_key)\n", + "print(f\"Recovered scalar after recovering 2. bit of the secret scalar: {recovered_scalar} = {recovered_scalar:b}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Difference of means when guessing 2. bit (guessed scalar 192 = 1100 0000)\n", + "dpa.plot_difference_of_means(dpa.doms['guess_one'][0])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Difference of means when guessing 2. bit (guessed scalar 128 = 1000 0000)\n", + "dpa.plot_difference_of_means(dpa.doms['guess_zero'][0])" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "# We can do this for each bit of the scalar\n", + "for i in range(2, scalar_bit_length):\n", + " recovered_scalar = dpa.recover_bit(recovered_scalar, i, scalar_bit_length, real_pub_key)\n", + " print(f\"Recovered scalar after recovering {i + 1}. bit of the secret scalar: {recovered_scalar} = {recovered_scalar:b}\")\n", + "print(recovered_scalar == secret_scalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Recover the whole 8-bit scalar" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "recovered_scalar = dpa.perform(scalar_bit_length, real_pub_key)\n", + "print(recovered_scalar)\n", + "print(recovered_scalar == secret_scalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### We can look at the difference of means after last recovered bit for both zero guess and one guess" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Zero guess\n", + "dpa.plot_difference_of_means(dpa.doms['guess_zero'][-1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# One guess\n", + "dpa.plot_difference_of_means(dpa.doms['guess_one'][-1])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.16" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} |
