{ "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 }