aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJán Jančár2023-12-12 20:28:42 +0100
committerGitHub2023-12-12 20:28:42 +0100
commit10b1456c8e2ad43ffc54b6f14e0f044f8c721f4e (patch)
treed7f26d3d98dc0b6fc4bb8d676bf01a597295133d
parent4db24ca7577327576040a5152ca42b2b27b78896 (diff)
parentcf1554750043052a23879d9c34a5a2da8d9c33d2 (diff)
downloadpyecsca-notebook-10b1456c8e2ad43ffc54b6f14e0f044f8c721f4e.tar.gz
pyecsca-notebook-10b1456c8e2ad43ffc54b6f14e0f044f8c721f4e.tar.zst
pyecsca-notebook-10b1456c8e2ad43ffc54b6f14e0f044f8c721f4e.zip
Merge pull request #4 from andrr3j/emulator_notebook
Emulator notebook
-rw-r--r--emulator.ipynb592
-rw-r--r--simulator.ipynb400
2 files changed, 592 insertions, 400 deletions
diff --git a/emulator.ipynb b/emulator.ipynb
new file mode 100644
index 0000000..fb9172e
--- /dev/null
+++ b/emulator.ipynb
@@ -0,0 +1,592 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Emulation and leakage simulation"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "This notebook demonstrates the functionality of the `EmulatorTarget` class, which can emulate **pyecsca** generated C implementations for `STM32F3` target using Rainbow as a basis as well as simulate side-channel leakage. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Initialisation"
+ ]
+ },
+ {
+ "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.ec.key_generation import KeyGeneration\n",
+ "from pyecsca.ec.key_agreement import ECDH_SHA1\n",
+ "from pyecsca.ec.configuration import *\n",
+ "from pyecsca.codegen.client import EmulatorTarget\n",
+ "from pyecsca.codegen.common import Platform\n",
+ "from pyecsca.codegen.common import DeviceConfiguration\n",
+ "from pyecsca.codegen.builder import render\n",
+ "from pyecsca.sca.trace import Trace\n",
+ "from pyecsca.sca.trace.plot import plot_trace\n",
+ "from pyecsca.sca.trace.process import rolling_mean\n",
+ "\n",
+ "\n",
+ "from rainbow import TraceConfig\n",
+ "from rainbow.leakage_models import HammingWeight\n",
+ "\n",
+ "from binascii import hexlify\n",
+ "from random import randbytes, randint\n",
+ "import numpy as np\n",
+ "import holoviews as hv\n",
+ "from subprocess import run\n",
+ "from os.path import join\n",
+ "from copy import copy "
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We first define the elliptic curve parameters we are going to be using for the demonstration."
+ ]
+ },
+ {
+ "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)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We create and initialize an instance of the `EmulatorTarget` class with the above EC parameters and the `TraceConfig` class instance, which configures the simulated leakage trace to contain the Hamming Weight of the emulator's register values. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "target = EmulatorTarget(model, coords, trace_config=TraceConfig(register=HammingWeight()))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We generate code and build it using **pyecsca** (for more details see `codegen.ipynb` notebook) and load the resulting binary into the emulator. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "platform = Platform.STM32F3\n",
+ "hash_type = HashType.SHA1\n",
+ "mod_rand = RandomMod.REDUCE\n",
+ "mult = Multiplication.BASE\n",
+ "sqr = Squaring.BASE\n",
+ "red = Reduction.BASE\n",
+ "inv = Inversion.GCD\n",
+ "\n",
+ "model = ShortWeierstrassModel()\n",
+ "coords = model.coordinates[\"projective\"]\n",
+ "add = coords.formulas[\"add-1998-cmo\"]\n",
+ "dbl = coords.formulas[\"dbl-1998-cmo\"]\n",
+ "scl = coords.formulas[\"z\"]\n",
+ "formulas = [add, dbl, scl]\n",
+ "scalarmult = LTRMultiplier(add, dbl, scl)\n",
+ "\n",
+ "config = DeviceConfiguration(model, coords, formulas, scalarmult, \n",
+ "\t\t\t\t\t\t\t hash_type, mod_rand, mult, sqr, red,\n",
+ "\t\t\t\t\t\t\t inv, platform, True, True, True)\n",
+ "\n",
+ "directory, elf_name, hex_name = render(config)\n",
+ "\n",
+ "run([\"make\"], cwd=directory)\n",
+ "join(directory, hex_name)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "target.connect(binary=join(directory, elf_name))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "For the emulated functions to work correctly, we need to set the parameters of the curve in the emulator."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "target.set_params(params)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Emulator functionality"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Scalar multiplication"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Perform scalar multiplication on given point with given scalar and compare with pyecsca."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scalar = randint(128, 255)\n",
+ "point = params.curve.affine_random().to_model(coords, params.curve)\n",
+ "emulatorResult = target.scalar_mult(scalar, point)\n",
+ "print(emulatorResult)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We use pyecsca to validate correctness of the emulator result. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "generator = params.generator\n",
+ "model = params.curve.model\n",
+ "coords = params.curve.coordinate_model\n",
+ "add = coords.formulas[\"add-1998-cmo\"]\n",
+ "dbl = coords.formulas[\"dbl-1998-cmo\"]\n",
+ "scl = coords.formulas[\"z\"]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mult_sm = LTRMultiplier(add, dbl, scl)\n",
+ "mult_sm.init(params, point)\n",
+ "\n",
+ "pyecscaResult = mult_sm.multiply(scalar)\n",
+ "print(pyecscaResult)\n",
+ "print(emulatorResult.equals(pyecscaResult))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Key generation"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Generate private and public key."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "seed_bytes = randbytes(32)\n",
+ "target.init_prng(seed_bytes)\n",
+ "priv, pub = target.generate()\n",
+ "pub = pub.to_model(coords, params.curve)\n",
+ "\n",
+ "print(\"private key:\", priv)\n",
+ "print(\"public key:\", pub)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We check if we generated valid key pair using pyecsca."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(params.curve.is_on_curve(pub))\n",
+ "pyecscaPub = params.curve.affine_multiply(params.generator.to_affine(), priv).to_model(coords, params.curve)\n",
+ "print(pyecscaPub)\n",
+ "print(pub.equals(pyecscaPub))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Setting private and public key"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "In order to emulate **ECDH** and **ECDSA** algorithms, the emulator needs private and public keys set. This can be done by methods below."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(\"Before private:\", target.privkey)\n",
+ "print(\"Before public:\", target.pubkey)\n",
+ "\n",
+ "target.set_privkey(priv)\n",
+ "target.set_pubkey(pub)\n",
+ "\n",
+ "print(\"After private:\", target.privkey)\n",
+ "print(\"After public:\", target.pubkey)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### ECDH"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Perform key agreement using ECDH."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "other_priv, other_pub = target.generate()\n",
+ "other_pub = other_pub.to_model(coords, params.curve)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "shared_secret = target.ecdh(pub)\n",
+ "print(\"shared secret:\", hexlify(shared_secret))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Check the result is correct using pyecsca."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mult_ecdh = LTRMultiplier(add, dbl, scl)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ecdh_a = ECDH_SHA1(copy(mult_ecdh), params, pub, other_priv)\n",
+ "ecdh_b = ECDH_SHA1(copy(mult_ecdh), params, other_pub, priv)\n",
+ "ecdh_a_result = ecdh_a.perform()\n",
+ "ecdh_b_result = ecdh_b.perform()\n",
+ "print(hexlify(ecdh_a_result))\n",
+ "print(hexlify(ecdh_b_result)) \n",
+ "print(ecdh_a_result == ecdh_b_result == shared_secret)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### ECDSA"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Perform signing over given data and verify the signature."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "message = \"text\"\n",
+ "signed_message = target.ecdsa_sign(message.encode())\n",
+ "res = target.ecdsa_verify(message.encode(), bytes(signed_message))\n",
+ "print(res)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "message = \"text1\"\n",
+ "signed_message = target.ecdsa_sign(message.encode())\n",
+ "message = \"text2\"\n",
+ "res = target.ecdsa_verify(message.encode(), bytes(signed_message))\n",
+ "print(res)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Leakage simulation"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "While the `EmulatorTarget` performs the above methods, it simulates leakage. The leakage trace is stored in `self.trace` variable. In our case, the trace will contain dictionaries of type `{\"type\": \"code\", \"register\": x}`, where `x` is Hamming Weight of the current register value. For other configurations of the trace, see https://github.com/Ledger-Donjon/rainbow"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Leakage trace of scalar multiplication"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We perform scalar multiplication and look at the sample of the leakage trace in `EmulatorTarget`'s `trace` variable."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scalar = 229\n",
+ "point = params.curve.affine_random().to_model(coords, params.curve)\n",
+ "target.trace = []\n",
+ "emulatorResult = target.scalar_mult(scalar, point)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(target.trace[0:10])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "To use the pyecsca's functionality of working with leakage traces, we transform the trace from dictionary to pyecsca's `Trace` using `EmulatorTarget`'s `process_trace` method. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "trace = target.transform_trace()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(trace[0:10])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can now visualize what the whole trace looks like."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "hv.extension(\"bokeh\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "plot_trace(trace).opts(width=950, height=600)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### SPA"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can now analyze the trace and try to gain information about the execution of the algorithm and/or recover the secret scalar."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We apply rolling mean to the trace to smooth it out, reduce noise and make the actions executed during the algorithm better identifiable."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "spa_trace = rolling_mean(trace, 3000)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can see repeated patterns in the resulting trace. Since the emulation consists of performing either point addition or point doubling repeadetly, we can map their execution to the repeated patterns. We know that the doubling operation will be performed for each bit of the scalar, while the addition operation will be performed only when the currently processed bit of the scalar is equal to one. Using this knowledge, we can see in the trace that the order of executed operations is as follows: *dbl-add-dbl-add-dbl-dbl-dbl-add-dbl-dbl-add*. This means that the scalar used equals *11100101 = 229*."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "plot_trace(spa_trace).opts(width=950, height=600)"
+ ]
+ }
+ ],
+ "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.18"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/simulator.ipynb b/simulator.ipynb
deleted file mode 100644
index 738bffa..0000000
--- a/simulator.ipynb
+++ /dev/null
@@ -1,400 +0,0 @@
-{
- "cells": [
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Simulation using rainbow simulator\n",
- "\n"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Initialisation"
- ]
- },
- {
- "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.ec.configuration import *\n",
- "\n",
- "from pyecsca.codegen.common import Platform\n",
- "from pyecsca.codegen.common import DeviceConfiguration\n",
- "from pyecsca.codegen.builder import render\n",
- "from pyecsca.codegen.client import SimulatorTarget\n",
- "\n",
- "from rainbow import Print, TraceConfig, HammingWeight\n",
- "from binascii import hexlify\n",
- "from random import randbytes\n",
- "from subprocess import run\n",
- "from os.path import join\n"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Generate source code\n",
- "\n",
- "We will first create a `DeviceConfiguration`, which we will then generate and build."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "platform = Platform.STM32F3\n",
- "hash_type = HashType.SHA1\n",
- "mod_rand = RandomMod.REDUCE\n",
- "mult = Multiplication.BASE\n",
- "sqr = Squaring.BASE\n",
- "red = Reduction.BASE\n",
- "inv = Inversion.GCD\n",
- "\n",
- "model = ShortWeierstrassModel()\n",
- "coords = model.coordinates[\"projective\"]\n",
- "add = coords.formulas[\"add-1998-cmo\"]\n",
- "dbl = coords.formulas[\"dbl-1998-cmo\"]\n",
- "scl = coords.formulas[\"z\"]\n",
- "formulas = [add, dbl, scl]\n",
- "scalarmult = LTRMultiplier(add, dbl, scl)\n",
- "\n",
- "config = DeviceConfiguration(model, coords, formulas, scalarmult, \n",
- "\t\t\t\t\t\t\t hash_type, mod_rand, mult, sqr, red,\n",
- "\t\t\t\t\t\t\t inv, platform, True, True, True)\n",
- "\n",
- "config"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Now we can render the configuration, which will generate the source files into a\n",
- "randomly created temporary directory, and return the path to the directory as\n",
- "well as names of the elf and hex files which will be built in that directory."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "directory, elf_name, hex_name = render(config)\n",
- "\n",
- "print(directory)"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "When we have the implementation rendered, we can build it using make."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "run([\"make\"], cwd=directory)"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Setup simulator\n",
- "\n",
- "Setup parameters for simulator use"
- ]
- },
- {
- "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)"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "//TODO: describe traceconfig, printconfig, breakpoints"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "target = SimulatorTarget(model, coords, trace_config=TraceConfig(mem_value=HammingWeight()))"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Connect the simulator to our generated source code"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "target.connect(binary=join(directory, elf_name))"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Using the simulator"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Set up curve parameters. It is needed for next operations."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "target.set_params(params)"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Perform scalar multiplication on given point with given scalar"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "point = target.scalar_mult(0xFFFFAAAA, params.generator)\n",
- "print(point)\n",
- "\n",
- "#Compare with pyecsca\n",
- "generator = params.generator\n",
- "model = params.curve.model\n",
- "coords = params.curve.coordinate_model\n",
- "add = coords.formulas[\"add-2007-bl\"]\n",
- "dbl = coords.formulas[\"dbl-2007-bl\"]\n",
- "mult = LTRMultiplier(add, dbl, None)\n",
- "mult.init(params, generator)\n",
- "resPoint = mult.multiply(0xFFFFAAAA)\n",
- "print(point.equals(resPoint))"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Generate private and public key"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "seed_bytes = randbytes(32)\n",
- "target.init_prng(seed_bytes)\n",
- "priv, pub = target.generate()\n",
- "\n",
- "print(\"private key:\", priv)\n",
- "print(\"public key:\", pub)\n",
- "# Check if it is valid keypair.\n",
- "print(params.curve.is_on_curve(pub))\n",
- "print(params.curve.affine_multiply(params.generator.to_affine(), priv))"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Set private and public key."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "print(\"Before private:\", target.privkey)\n",
- "print(\"Before public:\", target.pubkey)\n",
- "\n",
- "target.set_privkey(priv)\n",
- "target.set_pubkey(pub)\n",
- "\n",
- "print(\"After private:\", target.privkey)\n",
- "print(\"After public:\", target.pubkey)"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Perform key agreement using ecdh"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "other_priv, other_pub = target.generate()\n",
- "shared_secret = target.ecdh(other_pub)\n",
- "print(\"shared secret:\", hexlify(shared_secret))"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Perform signing over given data and verify the signature"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "message = \"test message\"\n",
- "signed_message = target.ecdsa_sign(message.encode())\n",
- "res = target.ecdsa_verify(message.encode(), bytes(signed_message))\n",
- "print(res)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "message = \"test message 2\"\n",
- "signed_message = target.ecdsa_sign(message.encode())\n",
- "message = \"test message 3\"\n",
- "res = target.ecdsa_verify(message.encode(), bytes(signed_message))\n",
- "print(res)"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Get a trace of the simulation"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "print(target.trace[0:10])"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Deinitialisation"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "target.disconnect()"
- ]
- }
- ],
- "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.10.6"
- },
- "orig_nbformat": 4
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}