{ "cells": [ { "cell_type": "markdown", "id": "afc512ca", "metadata": {}, "source": [ "## Speck Simulation" ] }, { "cell_type": "code", "execution_count": 1, "id": "efb373e4", "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as pyplot\n", "import numpy as np\n", "from scipy.stats import pearsonr\n", "import random\n", "from operator import xor\n", "\n", "# Fast implementation of the Hamming weight for 64 bit values\n", "# See book: A Hacker's delight\n", "# not sure if the hamming weight model w0rks for Speck\n", "def popcount(x):\n", " x -= (x >> 1) & 0x5555555555555555\n", " x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333)\n", " x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f\n", " return ((x * 0x0101010101010101) & 0xffffffffffffffff ) >> 56\n" ] }, { "cell_type": "code", "execution_count": 2, "id": "7654d5a2", "metadata": {}, "outputs": [], "source": [ "import math\n", "\n", "NUM_ROUNDS = 22\n", "BLOCK_SIZE = 32\n", "KEY_SIZE = 64\n", "WORD_SIZE = 16\n", "\n", "\n", "# SHIFTs for SPECK\n", "ALPHA = 7\n", "BETA = 2\n", "\n", "mod_mask = (2 ** WORD_SIZE) -1\n", "mod_mask_sub = (2 ** WORD_SIZE)" ] }, { "cell_type": "markdown", "id": "4bb78fa1", "metadata": {}, "source": [ "## Speck Implementation\n", "\n", "First of all, a very simplified Speck implementation to support Speck 23/64 with 22 rounds and ALPHA = 7 and BETA = 3\n", "\n", "1) Key = bytesToWords16(key)\n", "\n", "2) scheduled_key = key_schedule(Key)\n", "\n", "3) ciphertext = encrypt(plaintext, scheduled_key)\n", "\n", "\n", "-> The encrypt funktion is currently `missing` ... only `simple_speck()`" ] }, { "cell_type": "code", "execution_count": 13, "id": "5c3ade39", "metadata": {}, "outputs": [], "source": [ "'''\n", " Converts a bytestring `0xdeadbeef` to a array of 16-byte integers (len: 4)\n", "'''\n", "def bytesToWords16(b): \n", " return [(b >> (x * WORD_SIZE)) & mod_mask for x in\n", " range(0, math.ceil(KEY_SIZE // WORD_SIZE))]\n", " " ] }, { "cell_type": "code", "execution_count": 14, "id": "01f318ea", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['0x708', '0x506', '0x304', '0x102']" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[hex(x) for x in bytesToWords16(0x0102030405060708)]" ] }, { "cell_type": "code", "execution_count": 9, "id": "953621aa", "metadata": {}, "outputs": [], "source": [ "'''\n", " The 16bit Speck roundfunction, this is where the magic happens\n", "'''\n", "def ER16(x, y, k):\n", "\n", " rs_x = ((x << (16 - ALPHA)) + (x >> ALPHA)) & mod_mask\n", "\n", " add_sxy = (rs_x + y) & mod_mask\n", "\n", " new_x = k ^ add_sxy\n", "\n", " ls_y = ((y >> (16 - BETA)) + (y << BETA)) & mod_mask\n", "\n", " new_y = new_x ^ ls_y\n", "\n", " return new_x, new_y\n" ] }, { "cell_type": "markdown", "id": "4b7a7d5d", "metadata": {}, "source": [ "## Running the key schedule" ] }, { "cell_type": "code", "execution_count": 15, "id": "15e86ae3", "metadata": {}, "outputs": [], "source": [ "key = 0x0102030405060708" ] }, { "cell_type": "code", "execution_count": 16, "id": "8c7e9a0c", "metadata": {}, "outputs": [], "source": [ "Key = bytesToWords16(key)" ] }, { "cell_type": "code", "execution_count": 17, "id": "fd523d75", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['0x708', '0x506', '0x304', '0x102']\n" ] } ], "source": [ "print([hex(x) for x in Key])" ] }, { "cell_type": "code", "execution_count": 18, "id": "93e4fb4a", "metadata": {}, "outputs": [], "source": [ "'''\n", "\n", "The 16 bit python key schedule\n", "\n", "void Speck128256KeySchedule(u64 K[],u64 rk[])\n", "{\n", " u64 i,D=K[3],C=K[2],B=K[1],A=K[0];\n", " for(i=0;i<33;){\n", " rk[i]=A; ER64(B,A,i++);\n", " rk[i]=A; ER64(C,A,i++);\n", " rk[i]=A; ER64(D,A,i++);\n", " }\n", " rk[i]=A;\n", "}\n", "'''\n", "def key_schedule(k):\n", "\n", " D=k[3]\n", " C=k[2]\n", " B=k[1]\n", " A=k[0]\n", " out = []\n", " i = 0\n", " while i < 21:\n", " out.append(A)\n", " B, A = ER16(B, A, i)\n", " i += 1\n", " out.append(A)\n", " C, A = ER16(C, A, i)\n", " i+= 1\n", " out.append(A)\n", " D, A = ER16(D, A, i)\n", " i+= 1\n", " out.append(A)\n", " return out\n", " " ] }, { "cell_type": "code", "execution_count": 39, "id": "0061be29", "metadata": {}, "outputs": [], "source": [ "'''\n", "Simple encryption for speck (only the encryption part, without key scheduling)\n", "\n", "void Speck128256Encrypt(u64 Pt[],u64 Ct[],u64 rk[])\n", "{\n", " u64 i;\n", " Ct[0]=Pt[0]; Ct[1]=Pt[1];\n", " for(i=0;i<34;) ER64(Ct[1],Ct[0],rk[i++]);\n", "}\n", "\n", "\n", "'''\n", "def simple_speck(plaintext, key):\n", " Ct_0 = plaintext[0]\n", " Ct_1 = plaintext[1]\n", " \n", " \n", " Ct_1, Ct_0 = ER16(Ct_1, Ct_0, key) # fixed 16 bit key of 0x55\n", " return (Ct_1 << 8) + Ct_0" ] }, { "cell_type": "markdown", "id": "e25af6e8", "metadata": {}, "source": [ "## Running tests to verify the output is still fine" ] }, { "cell_type": "code", "execution_count": 22, "id": "1dd758a0", "metadata": {}, "outputs": [], "source": [ "assert key_schedule(Key) == [0x708,0xf32, 0x2bf1,0x8035,0xa48e,0x8482, 0x74ee, 0xf589, 0xb396, 0xb231, 0xdab2, 0x57bc, 0x704e,0x9947,0xe2d2, 0xea6a, 0x4ebe, 0xdd24, 0x6b64, 0x3ab1, 0x1c57, 0x7bde]" ] }, { "cell_type": "code", "execution_count": 11, "id": "1553c623", "metadata": {}, "outputs": [], "source": [ "ciphertext = simple_speck([0xdead, 0xbeef], 0x55)" ] }, { "cell_type": "code", "execution_count": 12, "id": "5b1da8b8", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0xbe7fc4c8\n" ] } ], "source": [ "# over simplified Speck encryption (no key schedule)\n", "print(hex(ciphertext))" ] }, { "cell_type": "markdown", "id": "22b7bbf5", "metadata": {}, "source": [ "# Simulation" ] }, { "cell_type": "markdown", "id": "7ebbb6f9", "metadata": {}, "source": [ "The following code simulates the Speck encryption process for an randomly choosen plaintext and the choosen key: **0x69**." ] }, { "cell_type": "markdown", "id": "9b8da308", "metadata": {}, "source": [ "It correlates 1000 encryptions for random plaintext and correlates them for execution with every possible keybyte" ] }, { "cell_type": "code", "execution_count": 74, "id": "2f090c78", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n", "8000\n", "8000\n", "+++++++++++++++++++++++++++++++++++++++++++\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Correct 8-bit key is: 0x69\n" ] } ], "source": [ "import random\n", "num_traces = 8000\n", "\n", "key_space = 256\n", "\n", "\n", "traces = np.empty(num_traces)\n", "hw_traces = np.empty((key_space, num_traces))\n", "\n", "for i in range(0,num_traces):\n", " #plaintext = [(i**2) % 0xFFFF, i % 0xFFFF]\n", " plaintext = bytes([random.randint(0, 255) for i in range(4)])\n", " traces[i] = popcount(simple_speck(plaintext, 0x69)) + np.random.normal(1, 20, 1) # + noice (seems to need an higher trace-count)\n", " \n", " # this is the simulation of the estimated values, using the popcount\n", " for key in range(0, key_space):\n", " hw_traces[key][i] = popcount(simple_speck(plaintext, key))\n", "\n", "corr = np.empty(key_space)\n", "\n", "#compute pearson correlation for each key\n", "for key in range(0, key_space):\n", " print(len(hw_traces[key])) # estimates\n", " print(len(traces)) # 'captured' traces\n", " print(\"+++++++++++++++++++++++++++++++++++++++++++\")\n", " corr[key],p = pearsonr(hw_traces[key], traces)\n", "\n", "pyplot.plot(corr)\n", "pyplot.show()\n", "\n", "print(\"Correct 8-bit key is: \" + hex(np.argmax(corr)))\n" ] }, { "cell_type": "markdown", "id": "e2532406", "metadata": {}, "source": [ "### $\\rightarrow$ Dafuq, at least something seems to w0rk" ] }, { "cell_type": "markdown", "id": "6baed584", "metadata": {}, "source": [ "## 16-bit key\n", "\n", "Breaking byte-by-byte for a 16-bit key (to not require the full $2^{16}$ keyspace)" ] }, { "cell_type": "code", "execution_count": 52, "id": "34536991", "metadata": {}, "outputs": [], "source": [ "def get_key(current_keybyte):\n", " num_traces = 5000\n", "\n", " key_space = 256\n", "\n", "\n", " traces = np.empty(num_traces)\n", " hw_traces = np.empty((key_space, num_traces))\n", "\n", " for i in range(0,num_traces):\n", " plaintext = [(i**2) % 0xFFFF, i % 0xFFFF]\n", " traces[i] = popcount(simple_speck(plaintext, 0xc0fe)) + np.random.normal(1, 20, 1) # + noice (seems to need an higher trace-count)\n", " for key in range(0, key_space):\n", " if current_keybyte == None:\n", " key_guess = key\n", " else:\n", " key_guess = (key << 8) + current_keybyte\n", " hw_traces[key][i] = popcount(simple_speck(plaintext, key_guess))\n", "\n", " corr = np.empty(key_space)\n", "\n", " #compute pearson correlation for each key\n", " for key in range(0, key_space):\n", " corr[key],p = pearsonr(hw_traces[key], traces)\n", "\n", " #pyplot.plot(corr)\n", " #pyplot.show()\n", "\n", " print(\"Correct 8-bit key is: \" + hex(np.argmax(corr)))\n", " return np.argmax(corr)" ] }, { "cell_type": "code", "execution_count": 55, "id": "84a8e53e", "metadata": {}, "outputs": [], "source": [ "def get_full_key():\n", " int_key = None\n", " full = []\n", " for i in range(WORD_SIZE // 8):\n", " int_key = int(get_key(int_key))\n", " full.append(int_key)\n", " return (full[1] << 8) + full[0]" ] }, { "cell_type": "code", "execution_count": 56, "id": "bd76012f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Correct 8-bit key is: 0xfe\n", "Correct 8-bit key is: 0xc0\n", "Full 16-bit Key: 0xc0fe\n" ] } ], "source": [ "print(f\"Full 16-bit Key: {hex(get_full_key())}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "3660bcc9", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "42520a86", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.7" } }, "nbformat": 4, "nbformat_minor": 5 }