diff options
| author | J08nY | 2020-02-15 14:55:48 +0100 |
|---|---|---|
| committer | J08nY | 2020-02-15 14:55:48 +0100 |
| commit | b57f8b21f5ff49657d4d052dc179d2d3831200ea (patch) | |
| tree | 9409952d1f1dd3d9e34184bd8f748806a71f2db3 /codegen.ipynb | |
| parent | ddbc1b6d5cc5d5275b623b7f7315828ddf340c85 (diff) | |
| download | pyecsca-notebook-b57f8b21f5ff49657d4d052dc179d2d3831200ea.tar.gz pyecsca-notebook-b57f8b21f5ff49657d4d052dc179d2d3831200ea.tar.zst pyecsca-notebook-b57f8b21f5ff49657d4d052dc179d2d3831200ea.zip | |
Add simulation and codegen notebooks.
Diffstat (limited to 'codegen.ipynb')
| -rw-r--r-- | codegen.ipynb | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/codegen.ipynb b/codegen.ipynb new file mode 100644 index 0000000..83ccc3a --- /dev/null +++ b/codegen.ipynb @@ -0,0 +1,468 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "collapsed": true, + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "# Code generation\n", + "\n", + "**pyecsca** can generate C implementations of ECC crypto for several microprocessor targets, which\n", + "are defined by the `Platform` enum." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "outputs": [ + { + "data": { + "text/plain": "['HOST', 'XMEGA', 'STM32F0', 'STM32F3']" + }, + "metadata": {}, + "output_type": "execute_result", + "execution_count": 3 + } + ], + "source": [ + "from pyecsca.codegen.common import Platform\n", + "\n", + "\n", + "Platform.names()" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n", + "is_executing": false + } + } + }, + { + "cell_type": "markdown", + "source": [ + "To generate an implementation we need an actual configuration which the implementation should\n", + "implement, which is stored inside the `Configuration` and `DeviceConfiguration` classes. " + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%% md\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 8, + "outputs": [ + { + "name": "stdout", + "text": [ + "model <class 'pyecsca.ec.model.CurveModel'>\n", + " A model(form) of an elliptic curve.\n", + "\n", + "coords <class 'pyecsca.ec.coordinates.CoordinateModel'>\n", + " A coordinate system for a particular model(form) of an elliptic curve.\n", + "\n", + "formulas typing.Set[pyecsca.ec.formula.Formula]\n", + " A formula operating on points.\n", + "\n", + "scalarmult <class 'pyecsca.ec.mult.ScalarMultiplier'>\n", + " \n", + " A scalar multiplication algorithm.\n", + "\n", + " :param short_circuit: Whether the use of formulas will be guarded by short-circuit on inputs\n", + " of the point at infinity.\n", + " :param formulas: Formulas this instance will use.\n", + " \n", + "\n", + "hash_type <enum 'HashType'>\n", + " Hash algorithm used in ECDH and ECDSA.\n", + " NONE\n", + " SHA1\n", + " SHA224\n", + " SHA256\n", + " SHA384\n", + " SHA512\n", + "\n", + "mod_rand <enum 'RandomMod'>\n", + " Method of sampling a uniform integer modulo order.\n", + " SAMPLE\n", + " REDUCE\n", + "\n", + "mult <enum 'Multiplication'>\n", + " Base multiplication algorithm to use.\n", + " TOOM_COOK\n", + " KARATSUBA\n", + " COMBA\n", + " BASE\n", + "\n", + "sqr <enum 'Squaring'>\n", + " Base squaring algorithm to use.\n", + " TOOM_COOK\n", + " KARATSUBA\n", + " COMBA\n", + " BASE\n", + "\n", + "red <enum 'Reduction'>\n", + " Modular reduction method used.\n", + " BARRETT\n", + " MONTGOMERY\n", + " BASE\n", + "\n", + "platform <enum 'Platform'>\n", + " Platform to build for.\n", + " HOST\n", + " XMEGA\n", + " STM32F0\n", + " STM32F3\n", + "\n", + "keygen <class 'bool'>\n", + " \n", + "\n", + "ecdh <class 'bool'>\n", + " \n", + "\n", + "ecdsa <class 'bool'>\n", + " \n", + "\n" + ], + "output_type": "stream" + } + ], + "source": [ + "from typing import get_args\n", + "from pyecsca.codegen.common import DeviceConfiguration\n", + "from dataclasses import fields\n", + "\n", + "for field in fields(DeviceConfiguration):\n", + "\tname = field.name\n", + "\ttp = field.type\n", + "\tdoc = tp.__doc__\n", + "\tif get_args(field.type):\n", + "\t\tdoc = get_args(field.type)[0].__doc__\n", + "\tif tp == bool:\n", + "\t\tdoc = \"\"\n", + "\tprint(name, tp)\n", + "\tprint(\" \", doc)\n", + "\tif hasattr(tp, \"names\"):\n", + "\t\tfor enum_name in tp.names():\n", + "\t\t\tprint(\" \", enum_name)\n", + "\tprint()" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n", + "is_executing": false + } + } + }, + { + "cell_type": "markdown", + "source": [ + "The `DeviceConfiguration` class contains a few additional attributes apart from those\n", + "in the `Configuration` class: `platform`, `keygen`, `ecdh` and `ecdsa`.\n", + "\n", + "The `platform` attribute defines for which target the implementation\n", + "should be built. The other boolean attributes specify whether particular\n", + "functionality should be implemented and enabled in the implementation." + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%% md\n" + } + } + }, + { + "cell_type": "markdown", + "source": [ + "## Generating\n", + "\n", + "We will first create a `DeviceConfiguration`, which we will then generate and build." + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": 13, + "outputs": [ + { + "data": { + "text/plain": "DeviceConfiguration(model=ShortWeierstrassModel(), coords=EFDCoordinateModel(\"projective\" on short Weierstrass curves), formulas=[AdditionEFDFormula(add-1998-cmo for EFDCoordinateModel(\"projective\" on short Weierstrass curves)), DoublingEFDFormula(dbl-1998-cmo for EFDCoordinateModel(\"projective\" on short Weierstrass curves)), ScalingEFDFormula(z for EFDCoordinateModel(\"projective\" on short Weierstrass curves))], scalarmult=<pyecsca.ec.mult.LTRMultiplier object at 0x7fb1da4ddd00>, hash_type=HASH_SHA1, mod_rand=MOD_RAND_REDUCE, mult=MUL_BASE, sqr=SQR_BASE, red=RED_BASE, platform=HOST, keygen=True, ecdh=True, ecdsa=True)" + }, + "metadata": {}, + "output_type": "execute_result", + "execution_count": 13 + } + ], + "source": [ + "from pyecsca.ec.model import ShortWeierstrassModel\n", + "from pyecsca.ec.mult import LTRMultiplier\n", + "from pyecsca.ec.configuration import *\n", + "\n", + "platform = Platform.HOST\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", + "config" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n", + "is_executing": false + } + } + }, + { + "cell_type": "markdown", + "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." + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%% md\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 12, + "outputs": [ + { + "name": "stdout", + "text": [ + "/tmp/tmpszimqnob\n" + ], + "output_type": "stream" + } + ], + "source": [ + "from pyecsca.codegen.builder import render\n", + "\n", + "directory, elf_name, hex_name = render(config)\n", + "\n", + "print(directory)" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n", + "is_executing": false + } + } + }, + { + "cell_type": "markdown", + "source": [ + "## Building\n", + "\n", + "When we have the implementation rendered, we can build it using make." + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%% md\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 15, + "outputs": [ + { + "name": "stdout", + "text": [ + "rm -f -- pyecsca-codegen-HOST.hex\n", + "rm -f -- pyecsca-codegen-HOST.eep\n", + "rm -f -- pyecsca-codegen-HOST.cof\n", + "rm -f -- pyecsca-codegen-HOST.elf\n", + "rm -f -- pyecsca-codegen-HOST.map\n", + "rm -f -- pyecsca-codegen-HOST.sym\n", + "rm -f -- pyecsca-codegen-HOST.lss\n", + "rm -f -- objdir/*.o\n", + "rm -f -- objdir/*.lst\n", + "rm -f -- main.s bn/bn.s asn1/asn1.s hash/hash.s prng/prng.s gen/point.s gen/curve.s gen/mult.s simpleserial.s uart.s host_hal.s\n", + "rm -f -- main.d bn/bn.d asn1/asn1.d hash/hash.d prng/prng.d gen/point.d gen/curve.d gen/mult.d simpleserial.d uart.d host_hal.d\n", + "rm -f -- main.i bn/bn.i asn1/asn1.i hash/hash.i prng/prng.i gen/point.i gen/curve.i gen/mult.i simpleserial.i uart.i host_hal.i\n", + ".\n", + "-------- begin --------\n", + "gcc (GCC) 9.2.0\n", + "Copyright (C) 2019 Free Software Foundation, Inc.\n", + "This is free software; see the source for copying conditions. There is NO\n", + "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", + "\n", + ".\n", + "Compiling C: main.c\n", + "gcc -c -I. -gdwarf-2 -DHASH=HASH_SHA1 -DMOD_RAND=MOD_RAND_REDUCE -DSS_VER=SS_VER_1_1 -DHAL=HAL_host -DPLATFORM=HOST -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/main.lst -Ihash -Iprng -Iasn1 -Ibn -Igen -Itommath -I./simpleserial/ -I./hal -I./hal/host -std=gnu99 -MMD -MP -MF .dep/main.o.d main.c -o objdir/main.o \n", + ".\n", + "Compiling C: bn/bn.c\n", + "gcc -c -I. -gdwarf-2 -DHASH=HASH_SHA1 -DMOD_RAND=MOD_RAND_REDUCE -DSS_VER=SS_VER_1_1 -DHAL=HAL_host -DPLATFORM=HOST -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/bn.lst -Ihash -Iprng -Iasn1 -Ibn -Igen -Itommath -I./simpleserial/ -I./hal -I./hal/host -std=gnu99 -MMD -MP -MF .dep/bn.o.d bn/bn.c -o objdir/bn/bn.o \n", + ".\n", + "Compiling C: asn1/asn1.c\n", + "gcc -c -I. -gdwarf-2 -DHASH=HASH_SHA1 -DMOD_RAND=MOD_RAND_REDUCE -DSS_VER=SS_VER_1_1 -DHAL=HAL_host -DPLATFORM=HOST -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/asn1.lst -Ihash -Iprng -Iasn1 -Ibn -Igen -Itommath -I./simpleserial/ -I./hal -I./hal/host -std=gnu99 -MMD -MP -MF .dep/asn1.o.d asn1/asn1.c -o objdir/asn1/asn1.o \n", + ".\n", + "Compiling C: hash/hash.c\n", + "gcc -c -I. -gdwarf-2 -DHASH=HASH_SHA1 -DMOD_RAND=MOD_RAND_REDUCE -DSS_VER=SS_VER_1_1 -DHAL=HAL_host -DPLATFORM=HOST -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/hash.lst -Ihash -Iprng -Iasn1 -Ibn -Igen -Itommath -I./simpleserial/ -I./hal -I./hal/host -std=gnu99 -MMD -MP -MF .dep/hash.o.d hash/hash.c -o objdir/hash/hash.o \n", + ".\n", + "Compiling C: prng/prng.c\n", + "gcc -c -I. -gdwarf-2 -DHASH=HASH_SHA1 -DMOD_RAND=MOD_RAND_REDUCE -DSS_VER=SS_VER_1_1 -DHAL=HAL_host -DPLATFORM=HOST -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/prng.lst -Ihash -Iprng -Iasn1 -Ibn -Igen -Itommath -I./simpleserial/ -I./hal -I./hal/host -std=gnu99 -MMD -MP -MF .dep/prng.o.d prng/prng.c -o objdir/prng/prng.o \n", + ".\n", + "Compiling C: gen/point.c\n", + "gcc -c -I. -gdwarf-2 -DHASH=HASH_SHA1 -DMOD_RAND=MOD_RAND_REDUCE -DSS_VER=SS_VER_1_1 -DHAL=HAL_host -DPLATFORM=HOST -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/point.lst -Ihash -Iprng -Iasn1 -Ibn -Igen -Itommath -I./simpleserial/ -I./hal -I./hal/host -std=gnu99 -MMD -MP -MF .dep/point.o.d gen/point.c -o objdir/gen/point.o \n", + ".\n", + "Compiling C: gen/curve.c\n", + "gcc -c -I. -gdwarf-2 -DHASH=HASH_SHA1 -DMOD_RAND=MOD_RAND_REDUCE -DSS_VER=SS_VER_1_1 -DHAL=HAL_host -DPLATFORM=HOST -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/curve.lst -Ihash -Iprng -Iasn1 -Ibn -Igen -Itommath -I./simpleserial/ -I./hal -I./hal/host -std=gnu99 -MMD -MP -MF .dep/curve.o.d gen/curve.c -o objdir/gen/curve.o \n", + ".\n", + "Compiling C: gen/mult.c\n", + "gcc -c -I. -gdwarf-2 -DHASH=HASH_SHA1 -DMOD_RAND=MOD_RAND_REDUCE -DSS_VER=SS_VER_1_1 -DHAL=HAL_host -DPLATFORM=HOST -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/mult.lst -Ihash -Iprng -Iasn1 -Ibn -Igen -Itommath -I./simpleserial/ -I./hal -I./hal/host -std=gnu99 -MMD -MP -MF .dep/mult.o.d gen/mult.c -o objdir/gen/mult.o \n", + ".\n", + "Compiling C: ./simpleserial/simpleserial.c\n", + "gcc -c -I. -gdwarf-2 -DHASH=HASH_SHA1 -DMOD_RAND=MOD_RAND_REDUCE -DSS_VER=SS_VER_1_1 -DHAL=HAL_host -DPLATFORM=HOST -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/simpleserial.lst -Ihash -Iprng -Iasn1 -Ibn -Igen -Itommath -I./simpleserial/ -I./hal -I./hal/host -std=gnu99 -MMD -MP -MF .dep/simpleserial.o.d ./simpleserial/simpleserial.c -o objdir/simpleserial.o \n", + ".\n", + "Compiling C: ./hal/host/uart.c\n", + "gcc -c -I. -gdwarf-2 -DHASH=HASH_SHA1 -DMOD_RAND=MOD_RAND_REDUCE -DSS_VER=SS_VER_1_1 -DHAL=HAL_host -DPLATFORM=HOST -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/uart.lst -Ihash -Iprng -Iasn1 -Ibn -Igen -Itommath -I./simpleserial/ -I./hal -I./hal/host -std=gnu99 -MMD -MP -MF .dep/uart.o.d ./hal/host/uart.c -o objdir/uart.o \n", + ".\n", + "Compiling C: ./hal/host/host_hal.c\n", + "gcc -c -I. -gdwarf-2 -DHASH=HASH_SHA1 -DMOD_RAND=MOD_RAND_REDUCE -DSS_VER=SS_VER_1_1 -DHAL=HAL_host -DPLATFORM=HOST -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/host_hal.lst -Ihash -Iprng -Iasn1 -Ibn -Igen -Itommath -I./simpleserial/ -I./hal -I./hal/host -std=gnu99 -MMD -MP -MF .dep/host_hal.o.d ./hal/host/host_hal.c -o objdir/host_hal.o \n", + ".\n", + "Linking: pyecsca-codegen-HOST.elf\n", + "gcc -I. -gdwarf-2 -DHASH=HASH_SHA1 -DMOD_RAND=MOD_RAND_REDUCE -DSS_VER=SS_VER_1_1 -DHAL=HAL_host -DPLATFORM=HOST -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/main.o -Ihash -Iprng -Iasn1 -Ibn -Igen -Itommath -I./simpleserial/ -I./hal -I./hal/host -std=gnu99 -MMD -MP -MF .dep/pyecsca-codegen-HOST.elf.d objdir/main.o objdir/bn/bn.o objdir/asn1/asn1.o objdir/hash/hash.o objdir/prng/prng.o objdir/gen/point.o objdir/gen/curve.o objdir/gen/mult.o objdir/simpleserial.o objdir/uart.o objdir/host_hal.o --output pyecsca-codegen-HOST.elf tommath/libtommath-HOST.a -Wl,-Map=pyecsca-codegen-HOST.map,--cref -lm \n", + ".\n", + "Creating load file for Flash: pyecsca-codegen-HOST.hex\n", + "objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature pyecsca-codegen-HOST.elf pyecsca-codegen-HOST.hex\n", + ".\n", + "Creating load file for EEPROM: pyecsca-codegen-HOST.eep\n", + "objcopy -j .eeprom --set-section-flags=.eeprom=\"alloc,load\" \\\n", + "--change-section-lma .eeprom=0 --no-change-warnings -O ihex pyecsca-codegen-HOST.elf pyecsca-codegen-HOST.eep || exit 0\n", + ".\n", + "Creating Extended Listing: pyecsca-codegen-HOST.lss\n", + "objdump -h -S -z pyecsca-codegen-HOST.elf > pyecsca-codegen-HOST.lss\n", + ".\n", + "Creating Symbol Table: pyecsca-codegen-HOST.sym\n", + "nm -n pyecsca-codegen-HOST.elf > pyecsca-codegen-HOST.sym\n", + "Size after:\n", + " text\t data\t bss\t dec\t hex\tfilename\n", + " 82833\t 744\t 576\t 84153\t 148b9\tpyecsca-codegen-HOST.elf\n", + "+--------------------------------------------------------\n", + "+ Built for platform HOST: Host machine target\n", + "+--------------------------------------------------------\n", + "\n" + ], + "output_type": "stream" + } + ], + "source": [ + "from subprocess import run\n", + "\n", + "res = run([\"make\"], cwd=directory, capture_output=True)\n", + "print(res.stdout.decode())" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n", + "is_executing": false + } + } + }, + { + "cell_type": "markdown", + "source": [ + "Now the files `elf_name` and `hex_name` in the directory contain the ELF file and HEX file built.\n" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%% md\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 17, + "outputs": [ + { + "name": "stdout", + "text": [ + "pyecsca-codegen-HOST.elf: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=b120c193e0d3f480bec86e817c0b08e3f9ed74c7, for GNU/Linux 3.2.0, with debug_info, not stripped\n", + "\n", + "pyecsca-codegen-HOST.hex: ASCII text, with CRLF line terminators\n", + "\n" + ], + "output_type": "stream" + } + ], + "source": [ + "res = run([\"file\", elf_name], cwd=directory, capture_output=True)\n", + "print(res.stdout.decode())\n", + "\n", + "res = run([\"file\", hex_name], cwd=directory, capture_output=True)\n", + "print(res.stdout.decode())" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n", + "is_executing": false + } + } + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + }, + "pycharm": { + "stem_cell": { + "cell_type": "raw", + "source": [], + "metadata": { + "collapsed": false + } + } + } + }, + "nbformat": 4, + "nbformat_minor": 0 +}
\ No newline at end of file |
