{ "cells": [ { "cell_type": "markdown", "id": "afc512ca", "metadata": {}, "source": [ "## Speck Simulation" ] }, { "cell_type": "code", "execution_count": 2, "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": 3, "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": 4, "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": 5, "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": 6, "id": "15e86ae3", "metadata": {}, "outputs": [], "source": [ "key = 0x0102030405060708" ] }, { "cell_type": "code", "execution_count": 7, "id": "8c7e9a0c", "metadata": {}, "outputs": [], "source": [ "Key = bytesToWords16(key)" ] }, { "cell_type": "code", "execution_count": 8, "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": 9, "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", " #for i in range(34):\n", " Ct_1, Ct_0 = ER16(Ct_1, Ct_0, key) # fixed 16 bit key of 0x55\n", " return (Ct_1 << WORD_SIZE) + Ct_0" ] }, { "cell_type": "markdown", "id": "e25af6e8", "metadata": {}, "source": [ "## Running tests to verify the output is still fine" ] }, { "cell_type": "code", "execution_count": 10, "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": 16, "id": "2f090c78", "metadata": {}, "outputs": [ { "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: 0xde\n" ] } ], "source": [ "num_traces = 3000\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, 0x69de)) + np.random.normal(1, 20, 1) # + noice (seems to need an higher trace-count)\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", " 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": "01603335", "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": 109, "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, 0xdead)) + 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": 110, "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": 112, "id": "bd76012f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Correct 8-bit key is: 0xad\n", "Correct 8-bit key is: 0xde\n", "Full 16-bit Key: 0xdead\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": "7b532103", "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 }