diff --git a/notebooks/dispersion_tutorial.ipynb b/notebooks/dispersion_tutorial.ipynb index 1c7f4b2..ad313e2 100644 --- a/notebooks/dispersion_tutorial.ipynb +++ b/notebooks/dispersion_tutorial.ipynb @@ -1,36 +1,71 @@ { "cells": [ - { - "cell_type": "markdown", - "source": [ - "## Dispersion" - ], - "metadata": { - "collapsed": false - } - }, { "cell_type": "code", "source": [ "from src.user_keypad import UserKeypad\n", - "from src.utils import random_property_rotation\n", "from IPython.display import Markdown, display\n", "from src.models import KeypadSize\n", "import numpy as np\n", "\n", + "def random_property_rotation(\n", + " user_keypad: np.ndarray,\n", + " prop_rotation: list[int]\n", + ") -> np.ndarray:\n", + " transposed = user_keypad.T\n", + " if len(prop_rotation) != len(transposed):\n", + " raise ValueError(\"prop_rotation must be the same length as the number of properties\")\n", + " for idx, prop_set in enumerate(transposed):\n", + " rotation = prop_rotation[idx]\n", + " rotation = rotation % len(prop_set) if len(prop_set) > 0 else 0\n", + " transposed[idx] = np.roll(prop_set, rotation)\n", + " return transposed.T\n", + "\n", "def keypad_md_table(keypad_list: np.ndarray, keypad_size: KeypadSize) -> str:\n", " assert (keypad_size.total_props == len(keypad_list))\n", " keypad = keypad_list.reshape(-1, keypad_size.props_per_key)\n", - " table = \"|key|\" + \"\".join([f\"set{idx}|\" for idx in range(keypad_size.props_per_key)])\n", + " table = \"||\" + \"\".join([f\"position {idx}|\" for idx in range(keypad_size.props_per_key)])\n", " table += \"\\n|\" + \"\".join(\"-|\" for _ in range(keypad_size.props_per_key + 1))\n", "\n", " for key in range(keypad_size.numb_of_keys):\n", - " table += f\"\\n|key{key+1}|\"\n", + " table += f\"\\n|key {key}|\"\n", " table += \"|\".join([str(prop) for prop in keypad[key]])\n", " table += \"|\"\n", - " return table\n", + " return table" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2025-03-20T16:15:24.214098Z", + "start_time": "2025-03-20T16:15:24.207220Z" + } + }, + "outputs": [], + "execution_count": 80 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "## Keypad Dispersion\n", "\n", + "Keypad dispersion refers to an operation that redistributes the properties assigned to each key on a keypad, ensuring that no property shares a key with a property that was previously adjacent to it.\n", + "Keypads are only dispersable if `numb_of_keys <= properites_per_key`\n", "\n", + "A keypad dispersion is completed in two steps:\n", + "1. Create a property rotation array; a randomly permuted subset of indices, selected without replacement from a range equal to the number of keys on a keypad, with its length truncated to match the number of properties assigned per key.\n", + "2. Rotate each position, similar to a ring or combination lock, by a distance equal to its corresponding value in the property rotation array." + ] + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-20T16:15:24.225459Z", + "start_time": "2025-03-20T16:15:24.220286Z" + } + }, + "cell_type": "code", + "source": [ "keypad_size = KeypadSize(numb_of_keys=5, props_per_key=4)\n", "props = [1, 10, 11, 100]\n", "keypad = []\n", @@ -38,90 +73,98 @@ " keypad.extend([key_numb * prop for prop in props])\n", "\n", "demo_interface = UserKeypad(keypad_size=keypad_size, keypad=np.array(keypad))\n", - "\n", + "display(Markdown(f\"\"\"\n", + "## Example Keypad\n", + "{keypad_size.numb_of_keys} X {keypad_size.props_per_key} keypad ({keypad_size.numb_of_keys} keys, {keypad_size.props_per_key} properties per key).\n", + "\"\"\"))\n", "display(Markdown(keypad_md_table(demo_interface.keypad, keypad_size)))\n" ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2025-03-14T14:34:55.702615Z", - "start_time": "2025-03-14T14:34:55.694963Z" - } - }, "outputs": [ { "data": { "text/plain": [ "" ], - "text/markdown": "|key|set0|set1|set2|set3|\n|-|-|-|-|-|\n|key1|1|10|11|100|\n|key2|2|20|22|200|\n|key3|3|30|33|300|\n|key4|4|40|44|400|\n|key5|5|50|55|500|" + "text/markdown": "\n## Example Keypad\n5 X 4 keypad (5 keys, 4 properties per key).\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ], + "text/markdown": "||position 0|position 1|position 2|position 3|\n|-|-|-|-|-|\n|key 0|1|10|11|100|\n|key 1|2|20|22|200|\n|key 2|3|30|33|300|\n|key 3|4|40|44|400|\n|key 4|5|50|55|500|" }, "metadata": {}, "output_type": "display_data" } ], - "execution_count": 4 + "execution_count": 81 }, { - "cell_type": "code", - "source": [ - "demo_interface_matrix = demo_interface.keypad.reshape(-1, demo_interface.keypad_size.props_per_key)\n", - "shuffled_keys = np.random.permutation(demo_interface_matrix)\n", - "shuffled_keys_list = shuffled_keys.reshape(-1)\n", - "display(Markdown(keypad_md_table(shuffled_keys_list, keypad_size)))" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2025-03-14T14:34:55.718161Z", - "start_time": "2025-03-14T14:34:55.714512Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ], - "text/markdown": "|key|set0|set1|set2|set3|\n|-|-|-|-|-|\n|key1|1|10|11|100|\n|key2|4|40|44|400|\n|key3|3|30|33|300|\n|key4|2|20|22|200|\n|key5|5|50|55|500|" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "execution_count": 5 + "metadata": {}, + "cell_type": "markdown", + "source": "### Create Property Rotation Array" }, { "cell_type": "code", "source": [ "prop_rotation = np.random.choice(range(keypad_size.numb_of_keys), size=keypad_size.props_per_key, replace=False)\n", - "dispersed_interface = random_property_rotation(\n", - " shuffled_keys,\n", - " prop_rotation\n", - ")\n", - "\n", - "display(Markdown(keypad_md_table(dispersed_interface.reshape(-1), keypad_size)))\n" + "print(f\"Property Rotation: {prop_rotation}\")\n" ], "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2025-03-14T14:34:55.731332Z", - "start_time": "2025-03-14T14:34:55.728135Z" + "end_time": "2025-03-20T16:15:24.240606Z", + "start_time": "2025-03-20T16:15:24.237773Z" } }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Property Rotation: [4 3 2 0]\n" + ] + } + ], + "execution_count": 82 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### Apply the Rotation" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-20T16:15:24.256086Z", + "start_time": "2025-03-20T16:15:24.253226Z" + } + }, + "cell_type": "code", + "source": [ + "dispersed_interface = random_property_rotation(\n", + " demo_interface.keypad.reshape(-1, keypad_size.props_per_key),\n", + " prop_rotation\n", + ")\n", + "display(Markdown(keypad_md_table(dispersed_interface.reshape(-1), keypad_size)))" + ], "outputs": [ { "data": { "text/plain": [ "" ], - "text/markdown": "|key|set0|set1|set2|set3|\n|-|-|-|-|-|\n|key1|5|30|44|100|\n|key2|1|20|33|400|\n|key3|4|50|22|300|\n|key4|3|10|55|200|\n|key5|2|40|11|500|" + "text/markdown": "||position 0|position 1|position 2|position 3|\n|-|-|-|-|-|\n|key 0|2|30|44|100|\n|key 1|3|40|55|200|\n|key 2|4|50|11|300|\n|key 3|5|10|22|400|\n|key 4|1|20|33|500|" }, "metadata": {}, "output_type": "display_data" } ], - "execution_count": 6 + "execution_count": 83 } ], "metadata": { diff --git a/notebooks/nkode_tutorial.ipynb b/notebooks/nkode_tutorial.ipynb index 4557afa..7960aab 100644 --- a/notebooks/nkode_tutorial.ipynb +++ b/notebooks/nkode_tutorial.ipynb @@ -30,12 +30,12 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.292663Z", - "start_time": "2025-03-20T12:00:21.253426Z" + "end_time": "2025-03-20T15:13:44.080558Z", + "start_time": "2025-03-20T15:13:44.076372Z" } }, "outputs": [], - "execution_count": 2 + "execution_count": 41 }, { "cell_type": "code", @@ -53,12 +53,12 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.298357Z", - "start_time": "2025-03-20T12:00:21.296258Z" + "end_time": "2025-03-20T15:13:44.090939Z", + "start_time": "2025-03-20T15:13:44.088281Z" } }, "outputs": [], - "execution_count": 3 + "execution_count": 42 }, { "metadata": {}, @@ -112,8 +112,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.317747Z", - "start_time": "2025-03-20T12:00:21.306163Z" + "end_time": "2025-03-20T15:13:44.107060Z", + "start_time": "2025-03-20T15:13:44.100773Z" } }, "outputs": [ @@ -121,30 +121,30 @@ "name": "stdout", "output_type": "stream", "text": [ - "Customer Position Key: [37938 42486 36680 47679 5944 46439]\n", + "Customer Position Key: [22504 45127 46010 30773 46509 63084]\n", "Customer Properties Key:\n", - "[14469 12272 54942 53713 60529 64319]\n", - "[49129 65121 60219 33860 48996 57925]\n", - "[61464 3328 59612 33957 62738 42039]\n", - "[ 3074 46306 41956 4712 59250 7730]\n", - "[23724 39640 530 27472 33903 26824]\n", + "[38076 5253 43656 24035 57980 18197]\n", + "[56754 21362 27799 42374 57145 46164]\n", + "[56031 10476 13741 23847 57450 42577]\n", + "[63205 55476 58864 29925 9463 58182]\n", + "[61997 24583 9269 19956 55576 32892]\n", "Position to Properties Map:\n", - "37938: [14469 49129 61464 3074 23724]\n", - "42486: [12272 65121 3328 46306 39640]\n", - "36680: [54942 60219 59612 41956 530]\n", - "47679: [53713 33860 33957 4712 27472]\n", - "5944: [60529 48996 62738 59250 33903]\n", - "46439: [64319 57925 42039 7730 26824]\n" + "22504: [38076 56754 56031 63205 61997]\n", + "45127: [ 5253 21362 10476 55476 24583]\n", + "46010: [43656 27799 13741 58864 9269]\n", + "30773: [24035 42374 23847 29925 19956]\n", + "46509: [57980 57145 57450 9463 55576]\n", + "63084: [18197 46164 42577 58182 32892]\n" ] } ], - "execution_count": 4 + "execution_count": 43 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.325478Z", - "start_time": "2025-03-20T12:00:21.322970Z" + "end_time": "2025-03-20T15:13:44.127687Z", + "start_time": "2025-03-20T15:13:44.125028Z" } }, "cell_type": "code", @@ -161,16 +161,16 @@ "output_type": "stream", "text": [ "Position Value to Icons Map:\n", - "37938: ['😀' '🥺' '🤔' '🐱' '🦄']\n", - "42486: ['😂' '😡' '🙃' '🐶' '🌟']\n", - "36680: ['🥳' '😱' '😇' '🦁' '⚡']\n", - "47679: ['😍' '🤯' '🤖' '🐻' '🔥']\n", - "5944: ['🤓' '🥰' '👽' '🐸' '🍕']\n", - "46439: ['😎' '😴' '👾' '🐙' '🎉']\n" + "22504: ['😀' '🥺' '🤔' '🐱' '🦄']\n", + "45127: ['😂' '😡' '🙃' '🐶' '🌟']\n", + "46010: ['🥳' '😱' '😇' '🦁' '⚡']\n", + "30773: ['😍' '🤯' '🤖' '🐻' '🔥']\n", + "46509: ['🤓' '🥰' '👽' '🐸' '🍕']\n", + "63084: ['😎' '😴' '👾' '🐙' '🎉']\n" ] } ], - "execution_count": 5 + "execution_count": 44 }, { "metadata": {}, @@ -194,8 +194,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.349267Z", - "start_time": "2025-03-20T12:00:21.342655Z" + "end_time": "2025-03-20T15:13:44.156638Z", + "start_time": "2025-03-20T15:13:44.150222Z" } }, "cell_type": "code", @@ -223,11 +223,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "Key 0: ['🐱' '🐶' '😱' '😍' '🍕']\n", - "Key 1: ['🦄' '😡' '⚡' '🤯' '🐸']\n", - "Key 2: ['😀' '🙃' '😇' '🔥' '👽']\n", - "Key 3: ['🥺' '😂' '🥳' '🐻' '🥰']\n", - "Key 4: ['🤔' '🌟' '🦁' '🤖' '🤓']\n" + "Key 0: ['🦄' '🦁' '🐻' '🤓' '👾']\n", + "Key 1: ['🥺' '⚡' '🔥' '🍕' '🎉']\n", + "Key 2: ['🐱' '😱' '🤖' '👽' '🐙']\n", + "Key 3: ['😀' '🥳' '😍' '🐸' '😴']\n", + "Key 4: ['🤔' '😇' '🤯' '🥰' '😎']\n" ] }, { @@ -244,11 +244,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "Key 0: [18 19 8 3 28]\n", - "Key 1: [24 7 26 9 22]\n", - "Key 2: [ 0 13 14 27 16]\n", - "Key 3: [ 6 1 2 21 10]\n", - "Key 4: [12 25 20 15 4]\n" + "Key 0: [24 20 21 4 17]\n", + "Key 1: [ 6 26 27 28 29]\n", + "Key 2: [18 8 15 16 23]\n", + "Key 3: [ 0 2 3 22 11]\n", + "Key 4: [12 14 9 10 5]\n" ] }, { @@ -265,15 +265,15 @@ "name": "stdout", "output_type": "stream", "text": [ - "Key 0: [ 3074 46306 60219 53713 33903]\n", - "Key 1: [23724 65121 530 33860 59250]\n", - "Key 2: [14469 3328 59612 27472 62738]\n", - "Key 3: [49129 12272 54942 4712 48996]\n", - "Key 4: [61464 39640 41956 33957 60529]\n" + "Key 0: [61997 58864 29925 57980 42577]\n", + "Key 1: [56754 9269 19956 55576 32892]\n", + "Key 2: [63205 27799 23847 57450 58182]\n", + "Key 3: [38076 43656 24035 9463 46164]\n", + "Key 4: [56031 13741 42374 57145 18197]\n" ] } ], - "execution_count": 6 + "execution_count": 45 }, { "metadata": {}, @@ -286,8 +286,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.372390Z", - "start_time": "2025-03-20T12:00:21.369564Z" + "end_time": "2025-03-20T15:13:44.190448Z", + "start_time": "2025-03-20T15:13:44.187214Z" } }, "cell_type": "code", @@ -306,14 +306,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "User Passcode Indices: [19, 28, 22, 18]\n", - "User Passcode Icons: ['🐶' '🍕' '🐸' '🐱']\n", - "User Passcode Server-side properties: [46306 33903 59250 3074]\n", - "Selected Keys: [0, 0, 1, 0]\n" + "User Passcode Indices: [4, 9, 5, 18]\n", + "User Passcode Icons: ['🤓' '🤯' '😎' '🐱']\n", + "User Passcode Server-side properties: [57980 42374 18197 63205]\n", + "Selected Keys: [0, 4, 4, 2]\n" ] } ], - "execution_count": 7 + "execution_count": 46 }, { "metadata": {}, @@ -326,8 +326,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.631111Z", - "start_time": "2025-03-20T12:00:21.391841Z" + "end_time": "2025-03-20T15:13:44.516570Z", + "start_time": "2025-03-20T15:13:44.208909Z" } }, "cell_type": "code", @@ -344,17 +344,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "Key 0: [0 7 2 3 4]\n", - "Key 1: [ 6 25 26 27 28]\n", - "Key 2: [24 19 20 21 16]\n", - "Key 3: [12 13 8 9 10]\n", - "Key 4: [18 1 14 15 22]\n", + "Key 0: [18 20 27 10 11]\n", + "Key 1: [24 14 15 22 29]\n", + "Key 2: [12 2 21 28 23]\n", + "Key 3: [ 0 26 9 16 17]\n", + "Key 4: [6 8 3 4 5]\n", "Selected Keys\n", - "[2, 1, 4, 4]\n" + "[4, 3, 4, 0]\n" ] } ], - "execution_count": 8 + "execution_count": 47 }, { "metadata": {}, @@ -364,8 +364,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:08:59.799827Z", - "start_time": "2025-03-20T12:08:59.796887Z" + "end_time": "2025-03-20T15:13:44.527802Z", + "start_time": "2025-03-20T15:13:44.524844Z" } }, "cell_type": "code", @@ -384,22 +384,22 @@ "name": "stdout", "output_type": "stream", "text": [ - "Set Key 0: ['🐱' '🐶' '😱' '😍' '🍕']\n", - "Confirm Key 0: ['🦄' '🐶' '🦁' '🐻' '👽']\n", - "Overlapping icon 🐶\n", - "Set Key 1: ['🐱' '🐶' '😱' '😍' '🍕']\n", - "Confirm Key 1: ['🥺' '🌟' '⚡' '🔥' '🍕']\n", - "Overlapping icon 🍕\n", - "Set Key 2: ['🦄' '😡' '⚡' '🤯' '🐸']\n", - "Confirm Key 2: ['🐱' '😂' '😇' '🤖' '🐸']\n", - "Overlapping icon 🐸\n", - "Set Key 3: ['🐱' '🐶' '😱' '😍' '🍕']\n", - "Confirm Key 3: ['🐱' '😂' '😇' '🤖' '🐸']\n", + "Set Key 0: ['🦄' '🦁' '🐻' '🤓' '👾']\n", + "Confirm Key 0: ['🥺' '😱' '😍' '🤓' '😎']\n", + "Overlapping icon 🤓\n", + "Set Key 1: ['🤔' '😇' '🤯' '🥰' '😎']\n", + "Confirm Key 1: ['😀' '⚡' '🤯' '👽' '👾']\n", + "Overlapping icon 🤯\n", + "Set Key 2: ['🤔' '😇' '🤯' '🥰' '😎']\n", + "Confirm Key 2: ['🥺' '😱' '😍' '🤓' '😎']\n", + "Overlapping icon 😎\n", + "Set Key 3: ['🐱' '😱' '🤖' '👽' '🐙']\n", + "Confirm Key 3: ['🐱' '🦁' '🔥' '🥰' '😴']\n", "Overlapping icon 🐱\n" ] } ], - "execution_count": 15 + "execution_count": 48 }, { "metadata": {}, @@ -419,8 +419,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.680780Z", - "start_time": "2025-03-20T10:38:44.954840Z" + "end_time": "2025-03-20T15:13:44.546871Z", + "start_time": "2025-03-20T15:13:44.540903Z" } }, "cell_type": "code", @@ -430,13 +430,13 @@ "user_prop_key_keypad = user_cipher.property_key.reshape(-1, keypad_size.props_per_key)" ], "outputs": [], - "execution_count": 83 + "execution_count": 49 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.683788Z", - "start_time": "2025-03-20T10:38:44.966571Z" + "end_time": "2025-03-20T15:13:44.565168Z", + "start_time": "2025-03-20T15:13:44.562664Z" } }, "cell_type": "code", @@ -447,21 +447,21 @@ "output_type": "stream", "text": [ "Property Key:\n", - "[[53739 14349 64971 50952 51008 37461]\n", - " [45744 17444 29958 27397 60694 8069]\n", - " [43064 47943 49025 5623 3145 4890]\n", - " [ 1128 11012 53093 14232 26108 5391]\n", - " [59341 47378 48497 6840 34437 29587]]\n" + "[[21364 17750 43270 40570 2897 64106]\n", + " [64901 60553 23487 56910 22974 27412]\n", + " [49276 36687 58910 60854 56432 64908]\n", + " [17816 7963 33663 13564 43318 39697]\n", + " [ 6300 40793 34908 48633 47026 16580]]\n" ] } ], - "execution_count": 84 + "execution_count": 50 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.684015Z", - "start_time": "2025-03-20T10:38:44.983449Z" + "end_time": "2025-03-20T15:13:44.583641Z", + "start_time": "2025-03-20T15:13:44.581757Z" } }, "cell_type": "code", @@ -471,17 +471,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "Passcode Key: [16245 48001 4534 55258 54613 15211 33171 56565 33961 50654]\n" + "Passcode Key: [65482 44549 30799 45221 44404 5844 32654 14244 48015 17243]\n" ] } ], - "execution_count": 85 + "execution_count": 51 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.689867Z", - "start_time": "2025-03-20T10:38:45.005712Z" + "end_time": "2025-03-20T15:13:44.624946Z", + "start_time": "2025-03-20T15:13:44.622774Z" } }, "cell_type": "code", @@ -491,17 +491,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "Mask Key: [52084 24514 63626 6657 19669 39430 35626 25229 14824 63798]\n" + "Mask Key: [36463 57168 30740 46459 21013 40282 33046 14986 26644 13]\n" ] } ], - "execution_count": 86 + "execution_count": 52 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.690242Z", - "start_time": "2025-03-20T10:38:45.024649Z" + "end_time": "2025-03-20T15:13:44.653291Z", + "start_time": "2025-03-20T15:13:44.651215Z" } }, "cell_type": "code", @@ -511,17 +511,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "Combined Position Key: [10235 12456 898 54650 50445 20719]\n" + "Combined Position Key: [32765 21433 32527 38517 27021 45380]\n" ] } ], - "execution_count": 87 + "execution_count": 53 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.694701Z", - "start_time": "2025-03-20T10:38:45.038985Z" + "end_time": "2025-03-20T15:13:44.682695Z", + "start_time": "2025-03-20T15:13:44.680482Z" } }, "cell_type": "code", @@ -531,17 +531,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "User Position Key = combined_pos_key XOR customer_pos_key: [ 3444 19636 47437 1440 7882 36903]\n" + "User Position Key = combined_pos_key XOR customer_pos_key: [10261 58366 52405 60992 56352 18216]\n" ] } ], - "execution_count": 88 + "execution_count": 54 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.696066Z", - "start_time": "2025-03-20T10:38:45.056942Z" + "end_time": "2025-03-20T15:13:44.713223Z", + "start_time": "2025-03-20T15:13:44.710535Z" } }, "cell_type": "code", @@ -557,16 +557,16 @@ "output_type": "stream", "text": [ "Combined Position to Properties Map:\n", - "10235: [53739 45744 43064 1128 59341]\n", - "12456: [14349 17444 47943 11012 47378]\n", - "898: [64971 29958 49025 53093 48497]\n", - "54650: [50952 27397 5623 14232 6840]\n", - "50445: [51008 60694 3145 26108 34437]\n", - "20719: [37461 8069 4890 5391 29587]\n" + "32765: [21364 64901 49276 17816 6300]\n", + "21433: [17750 60553 36687 7963 40793]\n", + "32527: [43270 23487 58910 33663 34908]\n", + "38517: [40570 56910 60854 13564 48633]\n", + "27021: [ 2897 22974 56432 43318 47026]\n", + "45380: [64106 27412 64908 39697 16580]\n" ] } ], - "execution_count": 89 + "execution_count": 55 }, { "metadata": {}, @@ -583,8 +583,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.696415Z", - "start_time": "2025-03-20T10:38:45.068009Z" + "end_time": "2025-03-20T15:13:44.732450Z", + "start_time": "2025-03-20T15:13:44.729920Z" } }, "cell_type": "code", @@ -596,7 +596,7 @@ "encoded_mask = user_cipher.encode_base64_str(mask)" ], "outputs": [], - "execution_count": 90 + "execution_count": 56 }, { "metadata": {}, @@ -613,8 +613,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.696640Z", - "start_time": "2025-03-20T10:38:45.087096Z" + "end_time": "2025-03-20T15:13:45.055535Z", + "start_time": "2025-03-20T15:13:44.751147Z" } }, "cell_type": "code", @@ -628,7 +628,7 @@ "passcode_hash = bcrypt.hashpw(passcode_prehash, bcrypt.gensalt(rounds=12)).decode(\"utf-8\")" ], "outputs": [], - "execution_count": 91 + "execution_count": 57 }, { "metadata": {}, @@ -642,8 +642,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.696764Z", - "start_time": "2025-03-20T10:38:45.326214Z" + "end_time": "2025-03-20T15:13:45.367717Z", + "start_time": "2025-03-20T15:13:45.061644Z" } }, "cell_type": "code", @@ -661,20 +661,20 @@ "name": "stdout", "output_type": "stream", "text": [ - "Key 0: [18 25 14 15 4 29]\n", - "Key 1: [ 6 13 20 27 28 5]\n", - "Key 2: [24 19 26 9 16 23]\n", - "Key 3: [ 0 1 8 3 10 11]\n", - "Key 4: [12 7 2 21 22 17]\n", - "User Passcode: [28, 13, 9, 10]\n", + "Key 0: [24 13 20 21 4 17]\n", + "Key 1: [ 6 1 26 27 28 29]\n", + "Key 2: [18 7 8 15 16 23]\n", + "Key 3: [ 0 19 2 3 22 11]\n", + "Key 4: [12 25 14 9 10 5]\n", + "User Passcode: [4, 9, 5, 18]\n", "\n", "Selected Keys:\n", - " [1, 1, 2, 3]\n", + " [0, 4, 4, 2]\n", "\n" ] } ], - "execution_count": 92 + "execution_count": 58 }, { "metadata": {}, @@ -701,8 +701,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.696874Z", - "start_time": "2025-03-20T10:38:45.567396Z" + "end_time": "2025-03-20T15:13:45.379898Z", + "start_time": "2025-03-20T15:13:45.377353Z" } }, "cell_type": "code", @@ -712,10 +712,10 @@ "user = api.customers[customer_id].users[username]\n", "mask = user.cipher.decode_base64_str(user.enciphered_passcode.mask)\n", "ordered_user_position_key = mask ^ user.cipher.mask_key\n", - "user_position_key = customer.cipher.position_key ^ user.cipher.combined_position_key\n" + "user_position_key = customer.cipher.position_key ^ user.cipher.combined_position_key" ], "outputs": [], - "execution_count": 93 + "execution_count": 59 }, { "metadata": {}, @@ -727,15 +727,20 @@ ] }, { - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-20T15:13:45.391901Z", + "start_time": "2025-03-20T15:13:45.389499Z" + } + }, "cell_type": "code", - "outputs": [], - "execution_count": null, "source": [ "passcode_position_indices = [int(np.where(user_position_key == pos)[0][0]) for pos in ordered_user_position_key[:passcode_len]]\n", "presumed_property_indices = customer.users[username].user_keypad.get_prop_idxs_by_keynumb_setidx(selected_keys_login, passcode_position_indices)\n", "assert passcode_property_indices == presumed_property_indices\n" - ] + ], + "outputs": [], + "execution_count": 60 }, { "metadata": {}, @@ -745,8 +750,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.697134Z", - "start_time": "2025-03-20T10:38:45.576610Z" + "end_time": "2025-03-20T15:13:45.711702Z", + "start_time": "2025-03-20T15:13:45.407474Z" } }, "cell_type": "code", @@ -755,7 +760,7 @@ "assert valid_nkode" ], "outputs": [], - "execution_count": 94 + "execution_count": 61 }, { "metadata": {}, @@ -771,8 +776,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.697273Z", - "start_time": "2025-03-20T10:38:45.816688Z" + "end_time": "2025-03-20T15:13:46.331470Z", + "start_time": "2025-03-20T15:13:45.715778Z" } }, "cell_type": "code", @@ -798,15 +803,15 @@ "output_type": "stream", "text": [ "Old User Cipher and Mask\n", - "mask: y8aMd+5qYcPVLETTcs2aHqx2hhk=, code: $2b$12$wMi7WGmlch8kWMYJ2v.FHOne1.YSQPqKU/itpBuycwSFyasryF/2u\n", + "mask: xetVN/8taK1lhtrDjt4w0M4pprQ=, code: $2b$12$6JzDrPs.dAb0iOIvm8afKuwf.Z8qKtg89Nnhx..tlBOD5y1MYMR4y\n", "\n", "New User Cipher and Mask\n", - "mask: aln5Su79utoVmqQXNCjYiUdwVYw=, code: $2b$12$gQf3UVa3cWMBy0CO0sBLyuJzdXGzg3qpNFMTD6MvycuR6N3gLFdgC\n", + "mask: WsKTIcZVngijEKlMfoF2UG5Rz9I=, code: $2b$12$jvQ..z4tPFII5dLXP0D2LOPrypDSB7yoRH6E0SZPO/yIIcZVtgCTS\n", "\n" ] } ], - "execution_count": 95 + "execution_count": 62 }, { "metadata": {}, @@ -819,8 +824,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.697386Z", - "start_time": "2025-03-20T10:38:46.293584Z" + "end_time": "2025-03-20T15:13:46.344092Z", + "start_time": "2025-03-20T15:13:46.339802Z" } }, "cell_type": "code", @@ -833,7 +838,7 @@ "new_pos = customer.cipher.position_key" ], "outputs": [], - "execution_count": 96 + "execution_count": 63 }, { "metadata": {}, @@ -853,8 +858,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.697503Z", - "start_time": "2025-03-20T10:38:46.310019Z" + "end_time": "2025-03-20T15:13:46.361420Z", + "start_time": "2025-03-20T15:13:46.359046Z" } }, "cell_type": "code", @@ -867,7 +872,7 @@ " user.cipher.property_key = user.cipher.property_key ^ props_xor" ], "outputs": [], - "execution_count": 97 + "execution_count": 64 }, { "metadata": {}, @@ -880,8 +885,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-20T12:00:21.697608Z", - "start_time": "2025-03-20T10:38:46.318482Z" + "end_time": "2025-03-20T15:13:46.679562Z", + "start_time": "2025-03-20T15:13:46.371777Z" } }, "cell_type": "code", @@ -896,7 +901,7 @@ " user.renew = False" ], "outputs": [], - "execution_count": 98 + "execution_count": 65 } ], "metadata": { diff --git a/src/utils.py b/src/utils.py deleted file mode 100644 index bfb68da..0000000 --- a/src/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -import numpy as np - -def random_property_rotation( - user_keypad: np.ndarray, - prop_rotation: list[int] -) -> np.ndarray: - transposed = user_keypad.T - if len(prop_rotation) != len(transposed): - raise ValueError("prop_rotation must be the same length as the number of properties") - for idx, prop_set in enumerate(transposed): - rotation = prop_rotation[idx] - rotation = rotation % len(prop_set) if len(prop_set) > 0 else 0 - transposed[idx] = np.roll(prop_set, rotation) - return transposed.T