aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJ08nY2020-02-27 23:04:22 +0100
committerJ08nY2020-02-27 23:04:22 +0100
commit0af7cf43939a29d382d80674bcc7bc1c050ecffc (patch)
tree4f13b939dad7af0a6a1cbb71ff3afe1771698dba
parent29770f3c6d0f8001ae9c09be9cb40357383e4f86 (diff)
downloadpyecsca-notebook-0af7cf43939a29d382d80674bcc7bc1c050ecffc.tar.gz
pyecsca-notebook-0af7cf43939a29d382d80674bcc7bc1c050ecffc.tar.zst
pyecsca-notebook-0af7cf43939a29d382d80674bcc7bc1c050ecffc.zip
Add notebook on measurement.
-rw-r--r--.gitignore3
-rw-r--r--img/measurement_setup.jpgbin0 -> 986855 bytes
-rw-r--r--img/measurement_ufo.jpgbin0 -> 1425443 bytes
-rw-r--r--measurement.ipynb344
4 files changed, 346 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 152e020..200ddef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-.pytest_cache/ \ No newline at end of file
+.pytest_cache/
+.ipynb_checkpoints/ \ No newline at end of file
diff --git a/img/measurement_setup.jpg b/img/measurement_setup.jpg
new file mode 100644
index 0000000..3b99d1b
--- /dev/null
+++ b/img/measurement_setup.jpg
Binary files differ
diff --git a/img/measurement_ufo.jpg b/img/measurement_ufo.jpg
new file mode 100644
index 0000000..75e5b57
--- /dev/null
+++ b/img/measurement_ufo.jpg
Binary files differ
diff --git a/measurement.ipynb b/measurement.ipynb
new file mode 100644
index 0000000..03e1edb
--- /dev/null
+++ b/measurement.ipynb
@@ -0,0 +1,344 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "collapsed": true,
+ "pycharm": {
+ "name": "#%% md\n"
+ }
+ },
+ "source": [
+ "# Measurement\n",
+ "\n",
+ "This notebook showcases how to use **pyecsca** to generate and measure an ECC implementation.\n",
+ "This example use the ChipWhisperer-Lite board, along with the UFO target board (with an `STM32F3` target on top)\n",
+ "and a PicoScope 5000 oscilloscope to measure."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Oscilloscope setup\n",
+ "\n",
+ "First we will setup the scope. Channel `A` will be used for the power signal, so we\n",
+ "connect the `MEASURE` SMA plug (on the UFO board) to the scope `A` input via an SMA-BNC cable. Channel\n",
+ "`B` will be used for the trigger, so we connect a probe to `TP2` point on the UFO board and connect it\n",
+ "to input `B` on the scope. \n",
+ "\n",
+ "![measurement setup](img/measurement_setup.jpg)\n",
+ "\n",
+ "Next we connect to the scope and display its identifier."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "from pyecsca.sca.scope import PS5000Scope\n",
+ "\n",
+ "scope = PS5000Scope()\n",
+ "scope.open()\n",
+ "print(scope.get_variant())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "pycharm": {
+ "name": "#%% md\n"
+ }
+ },
+ "source": [
+ "Then we setup the channels, `A` in AC coupling with 1 Volt range, `B` in DC coupling with 5 Volt range."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "scope.setup_channel(channel=\"A\", coupling=\"AC\", range=1.0, enable=True)\n",
+ "scope.setup_channel(channel=\"B\", coupling=\"DC\", range=5.0, enable=True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "pycharm": {
+ "name": "#%% md\n"
+ }
+ },
+ "source": [
+ "Then we set the frequency and amount of samples. We set 4.6 MHz and 32M samples,\n",
+ "which should lead to a 7 second capture time (which should cover the long scalar multiplication operation on the chip ~ 6s)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "scope.setup_frequency(frequency=4_600_000, samples=32_000_000)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "pycharm": {
+ "name": "#%% md\n"
+ }
+ },
+ "source": [
+ "Next we setup the trigger on channel `B`. We also set channel `A` as the channel to capture."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "scope.setup_trigger(channel=\"B\", threshold=1.0, direction=\"rising\", delay=0, timeout=2000, enable=True)\n",
+ "scope.setup_capture(channel=\"A\", enable=True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "pycharm": {
+ "name": "#%% md\n"
+ }
+ },
+ "source": [
+ "## Device setup\n",
+ "\n",
+ "The `STM32F3` UFO target board is used next, we now will generate build an ECC implementation.\n",
+ "\n",
+ "![measurement ufo](img/measurement_ufo.jpg)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "import tempfile\n",
+ "\n",
+ "from os.path import join\n",
+ "from pyecsca.codegen.common import Platform, DeviceConfiguration\n",
+ "from pyecsca.codegen.render import render_and_build\n",
+ "from pyecsca.ec.model import ShortWeierstrassModel\n",
+ "from pyecsca.ec.mult import LTRMultiplier\n",
+ "from pyecsca.ec.configuration import *\n",
+ "\n",
+ "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",
+ "\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 platform, True, True, True)\n",
+ "\n",
+ "tmpdir = tempfile.mkdtemp()\n",
+ "directory, elf_file, hex_file, res = render_and_build(config, tmpdir)\n",
+ "fw = join(tmpdir, hex_file)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "pycharm": {
+ "name": "#%% md\n"
+ }
+ },
+ "source": [
+ "Now we will create a target and flash the implementation on it.\n",
+ "The target constructor requires to know some parameters of the configuration,\n",
+ "to be able to communicate with it."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "from pyecsca.codegen.client import DeviceTarget\n",
+ "\n",
+ "target = DeviceTarget(model=config.model, coords=config.coords, platform=config.platform, timeout=10000)\n",
+ "target.flash(fw)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "pycharm": {
+ "name": "#%% md\n"
+ }
+ },
+ "source": [
+ "## Measurement\n",
+ "\n",
+ "We can now connect to the target, arm the scope and generate a keypair on the target while measuring it,\n",
+ "then collect the trace."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "from pyecsca.sca.trace import Trace\n",
+ "from pyecsca.ec.curves import get_params\n",
+ "params = get_params(\"secg\", \"secp128r1\", \"projective\")\n",
+ "\n",
+ "target.connect()\n",
+ "target.set_params(params)\n",
+ "scope.arm()\n",
+ "priv, pub = target.generate()\n",
+ "trace_data = scope.capture(\"A\", 2)\n",
+ "trace = Trace(\"generate\", None, samples=trace_data)\n",
+ "target.disconnect()\n",
+ "\n",
+ "print(trace)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "pycharm": {
+ "name": "#%% md\n"
+ }
+ },
+ "source": [
+ "After all measurements are done, we disconnect from the scope."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "scope.close()"
+ ]
+ }
+ ],
+ "metadata": {
+ "@webio": {
+ "lastCommId": "a4a07d6bd37f4db880086e602ba07b32",
+ "lastKernelId": "a8a17477-d3c3-492f-95dd-ea93846cae23"
+ },
+ "hide_input": false,
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.1"
+ },
+ "latex_envs": {
+ "LaTeX_envs_menu_present": true,
+ "autoclose": false,
+ "autocomplete": true,
+ "bibliofile": "biblio.bib",
+ "cite_by": "apalike",
+ "current_citInitial": 1,
+ "eqLabelWithNumbers": true,
+ "eqNumInitial": 1,
+ "hotkeys": {
+ "equation": "Ctrl-E",
+ "itemize": "Ctrl-I"
+ },
+ "labels_anchors": false,
+ "latex_user_defs": false,
+ "report_style_numbering": false,
+ "user_envs_cfg": false
+ },
+ "pycharm": {
+ "stem_cell": {
+ "cell_type": "raw",
+ "source": [],
+ "metadata": {
+ "collapsed": false
+ }
+ }
+ },
+ "toc": {
+ "base_numbering": 1,
+ "nav_menu": {},
+ "number_sections": true,
+ "sideBar": true,
+ "skip_h1_title": false,
+ "title_cell": "Table of Contents",
+ "title_sidebar": "Contents",
+ "toc_cell": false,
+ "toc_position": {},
+ "toc_section_display": true,
+ "toc_window_display": false
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+} \ No newline at end of file