diff --git a/dispersion_tutorial.ipynb b/dispersion_tutorial.ipynb new file mode 100644 index 0000000..6109776 --- /dev/null +++ b/dispersion_tutorial.ipynb @@ -0,0 +1,141 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "## Dispersion" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": 1, + "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|" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from src.utils import secure_fisher_yates_shuffle, matrix_to_list, list_to_matrix\n", + "from src.user_interface import UserInterface\n", + "from IPython.display import Markdown, display\n", + "from src.models import KeypadSize\n", + "\n", + "def keypad_md_table(interface: list[int], keypad_size: KeypadSize) -> str:\n", + " assert (keypad_size.numb_of_attrs == len(interface))\n", + " interface_keypad = list_to_matrix(interface, keypad_size.attrs_per_key)\n", + " table = \"|key|\" + \"\".join([f\"set{idx}|\" for idx in range(keypad_size.attrs_per_key)])\n", + " table += \"\\n|\" + \"\".join(\"-|\" for _ in range(keypad_size.attrs_per_key+1))\n", + "\n", + " for key in range(keypad_size.numb_of_keys):\n", + " table += f\"\\n|key{key+1}|\"\n", + " table += \"|\".join([str(attr) for attr in interface_keypad[key]])\n", + " table += \"|\"\n", + " return table\n", + "\n", + "\n", + "keypad_size = KeypadSize(numb_of_keys=5, attrs_per_key=4)\n", + "attrs = [1, 10, 11, 100]\n", + "interface = []\n", + "for key_numb in range(1,keypad_size.numb_of_keys+1):\n", + " interface.extend([key_numb*attr for attr in attrs])\n", + "\n", + "demo_interface = UserInterface(keypad_size=keypad_size, interface=interface)\n", + "\n", + "display(Markdown(keypad_md_table(demo_interface.interface, keypad_size)))\n" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-07-24T22:23:18.200797Z", + "start_time": "2024-07-24T22:23:18.119660Z" + } + } + }, + { + "cell_type": "code", + "execution_count": 2, + "outputs": [ + { + "data": { + "text/plain": "", + "text/markdown": "|key|set0|set1|set2|set3|\n|-|-|-|-|-|\n|key1|3|30|33|300|\n|key2|1|10|11|100|\n|key3|5|50|55|500|\n|key4|2|20|22|200|\n|key5|4|40|44|400|" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "demo_interface_matrix = list_to_matrix(demo_interface.interface, demo_interface.keypad_size.attrs_per_key)\n", + "shuffled_keys = secure_fisher_yates_shuffle(demo_interface_matrix)\n", + "shuffled_keys_list = matrix_to_list(shuffled_keys)\n", + "display(Markdown(keypad_md_table(shuffled_keys_list, keypad_size)))\n" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-07-24T22:23:18.201039Z", + "start_time": "2024-07-24T22:23:18.185696Z" + } + } + }, + { + "cell_type": "code", + "execution_count": 3, + "outputs": [ + { + "data": { + "text/plain": "", + "text/markdown": "|key|set0|set1|set2|set3|\n|-|-|-|-|-|\n|key1|2|10|55|400|\n|key2|4|50|22|300|\n|key3|3|20|44|100|\n|key4|1|40|33|500|\n|key5|5|30|11|200|" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "attr_rotation = secure_fisher_yates_shuffle(list(range(keypad_size.numb_of_keys)))[:keypad_size.attrs_per_key]\n", + "dispersed_interface = UserInterface.random_attribute_rotation(\n", + " shuffled_keys,\n", + " attr_rotation\n", + ")\n", + "\n", + "display(Markdown(keypad_md_table(matrix_to_list(dispersed_interface), keypad_size)))\n" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-07-24T22:23:18.201164Z", + "start_time": "2024-07-24T22:23:18.190198Z" + } + } + } + ], + "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" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/nkode_api.py b/nkode_api.py index d71d2cb..f9e7c29 100644 --- a/nkode_api.py +++ b/nkode_api.py @@ -1,6 +1,5 @@ from uuid import UUID, uuid4 from pydantic import BaseModel - from src.customer import Customer from src.models import NKodePolicy, KeypadSize from src.user import User @@ -25,7 +24,7 @@ class NKodeAPI(BaseModel): return new_customer.customer_id - def generate_index_interface(self, customer_id: UUID) -> tuple[UUID, list[int]]: + def generate_signup_interface(self, customer_id: UUID) -> tuple[UUID, list[int]]: assert (customer_id in self.customers.keys()) customer = self.customers[customer_id] login_interface = UserInterface.new(customer.attributes.keypad_size) @@ -80,7 +79,7 @@ class NKodeAPI(BaseModel): del self.signup_sessions[session_id] return True - def get_login_index_interface(self, username: str, customer_id: UUID) -> list[int]: + def get_login_interface(self, username: str, customer_id: UUID) -> list[int]: """ TODO: how do we prevent a targeted denial-of-service attack? """ diff --git a/nkode_calculation.ipynb b/nkode_calculation.ipynb new file mode 100644 index 0000000..ef094dc --- /dev/null +++ b/nkode_calculation.ipynb @@ -0,0 +1,172 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# What does is take to compromise a users nKode in the worst case scenario?\n" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": 16, + "outputs": [], + "source": [ + "def compute_time_to_crack_hash(\n", + " num_of_attributes: int,\n", + " nkode_len,\n", + " secs_per_hash: float = 0.5,\n", + ") -> list[float, float]:\n", + " secs_to_days = 1/(60*60*24)\n", + " secs_to_years = secs_to_days / 365\n", + " total_secs_to_compute_half_of_hashes = num_of_attributes ** nkode_len * secs_per_hash * 0.5\n", + " return [round(total_secs_to_compute_half_of_hashes * secs_to_days, 2), round(total_secs_to_compute_half_of_hashes * secs_to_years, 2)]\n" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-07-26T15:29:35.667921Z", + "start_time": "2024-07-26T15:29:35.664278Z" + } + } + }, + { + "cell_type": "code", + "execution_count": 21, + "outputs": [], + "source": [ + "def matrix_to_md_table(col_names: list[str], mat: list[list[any]]) -> str:\n", + " assert len(col_names) == len(mat[0])\n", + " numb_cols = len(col_names)\n", + " table = \"|\" + \"|\".join(col_names) + \"|\\n\"\n", + " table += \"|\" + \"|\".join(['-' for _ in range(numb_cols)]) + \"|\\n\"\n", + " for row in mat:\n", + " table += \"|\" + \"|\".join([str(el) for el in row]) + \"|\\n\"\n", + " return table" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-07-27T18:42:04.980503Z", + "start_time": "2024-07-27T18:42:04.976703Z" + } + } + }, + { + "cell_type": "code", + "execution_count": 22, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "|number of attributes|nkode length|days to crack|years to crack|\n", + "|-|-|-|-|\n", + "|9|4|0.02|0.0|\n", + "|9|5|0.17|0.0|\n", + "|9|6|1.54|0.0|\n", + "|9|7|13.84|0.04|\n", + "|9|8|124.56|0.34|\n", + "|9|9|1121.01|3.07|\n", + "|9|10|10089.08|27.64|\n", + "|10|4|0.03|0.0|\n", + "|10|5|0.29|0.0|\n", + "|10|6|2.89|0.01|\n", + "|10|7|28.94|0.08|\n", + "|10|8|289.35|0.79|\n", + "|10|9|2893.52|7.93|\n", + "|10|10|28935.19|79.27|\n", + "|11|4|0.04|0.0|\n", + "|11|5|0.47|0.0|\n", + "|11|6|5.13|0.01|\n", + "|11|7|56.39|0.15|\n", + "|11|8|620.25|1.7|\n", + "|11|9|6822.77|18.69|\n", + "|11|10|75050.42|205.62|\n", + "|12|4|0.06|0.0|\n", + "|12|5|0.72|0.0|\n", + "|12|6|8.64|0.02|\n", + "|12|7|103.68|0.28|\n", + "|12|8|1244.16|3.41|\n", + "|12|9|14929.92|40.9|\n", + "|12|10|179159.04|490.85|\n", + "|13|4|0.08|0.0|\n", + "|13|5|1.07|0.0|\n", + "|13|6|13.97|0.04|\n", + "|13|7|181.56|0.5|\n", + "|13|8|2360.33|6.47|\n", + "|13|9|30684.32|84.07|\n", + "|13|10|398896.1|1092.87|\n", + "|14|4|0.11|0.0|\n", + "|14|5|1.56|0.0|\n", + "|14|6|21.79|0.06|\n", + "|14|7|305.02|0.84|\n", + "|14|8|4270.22|11.7|\n", + "|14|9|59783.12|163.79|\n", + "|14|10|836963.7|2293.05|\n", + "|15|4|0.15|0.0|\n", + "|15|5|2.2|0.01|\n", + "|15|6|32.96|0.09|\n", + "|15|7|494.38|1.35|\n", + "|15|8|7415.77|20.32|\n", + "|15|9|111236.57|304.76|\n", + "|15|10|1668548.58|4571.37|\n", + "\n" + ] + } + ], + "source": [ + "time_to_crack = []\n", + "for num_attr in range(9, 16):\n", + " for nkod_len in range(4, 11):\n", + " hash_crack = [num_attr, nkod_len]\n", + " hash_crack.extend(compute_time_to_crack_hash(num_attr, nkod_len))\n", + " time_to_crack.append(hash_crack)\n", + "\n", + "hash_crack_md = matrix_to_md_table([\"number of attributes\", \"nkode length\", \"days to crack\", \"years to crack\"], time_to_crack)\n", + "\n", + "\n", + "print(hash_crack_md)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-07-27T18:43:31.002026Z", + "start_time": "2024-07-27T18:43:30.997876Z" + } + } + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": "", + "metadata": { + "collapsed": 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" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/nkode_tutorial.ipynb b/nkode_tutorial.ipynb index d648c89..4efc752 100644 --- a/nkode_tutorial.ipynb +++ b/nkode_tutorial.ipynb @@ -2,8 +2,6 @@ "cells": [ { "cell_type": "code", - "execution_count": 62, - "outputs": [], "source": [ "from nkode_api import NKodeAPI\n", "from src.models import NKodePolicy, KeypadSize\n", @@ -14,15 +12,15 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-07-22T16:43:14.323435Z", - "start_time": "2024-07-22T16:43:14.225885Z" + "end_time": "2024-08-01T17:32:43.394441Z", + "start_time": "2024-08-01T17:32:43.392271Z" } - } + }, + "outputs": [], + "execution_count": 41 }, { "cell_type": "code", - "execution_count": 63, - "outputs": [], "source": [ "def random_username() -> str:\n", " return \"test_username\" + \"\".join([choice(ascii_lowercase) for _ in range(6)])\n", @@ -40,25 +38,27 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-07-22T16:43:14.323797Z", - "start_time": "2024-07-22T16:43:14.229848Z" + "end_time": "2024-08-01T17:32:43.447194Z", + "start_time": "2024-08-01T17:32:43.444212Z" } - } + }, + "outputs": [], + "execution_count": 42 }, { "cell_type": "code", - "execution_count": 64, - "outputs": [], "source": [ "api = NKodeAPI()" ], "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-07-22T16:43:14.323871Z", - "start_time": "2024-07-22T16:43:14.232313Z" + "end_time": "2024-08-01T17:32:43.450349Z", + "start_time": "2024-08-01T17:32:43.448288Z" } - } + }, + "outputs": [], + "execution_count": 43 }, { "cell_type": "markdown", @@ -70,8 +70,9 @@ "- min nkode length = 4\n", "- distinct attributes = 4\n", "- distinct set = 0\n", + "- byte len = 2\n", "\n", - "This customer also has an interface with 10 keys and 7 attributes per key" + "This customer also has an interface with 5 keys and 6 attributes per key. The number of attributes must be greater than the number of keys to be dispersion resistant." ], "metadata": { "collapsed": false @@ -79,18 +80,17 @@ }, { "cell_type": "code", - "execution_count": 65, - "outputs": [], "source": [ "policy = NKodePolicy(\n", " max_nkode_len=10,\n", " min_nkode_len=4,\n", " distinct_sets=0,\n", - " distinct_attributes=4\n", + " distinct_attributes=4,\n", + " byte_len=2,\n", ")\n", "keypad_size = KeypadSize(\n", " numb_of_keys = 5,\n", - " attrs_per_key = 4 # aka number of sets\n", + " attrs_per_key = 6 # aka number of sets\n", ")\n", "customer_id = api.create_new_customer(keypad_size, policy)\n", "customer = api.customers[customer_id]" @@ -98,18 +98,20 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-07-22T16:43:14.414667Z", - "start_time": "2024-07-22T16:43:14.238210Z" + "end_time": "2024-08-01T17:32:43.624648Z", + "start_time": "2024-08-01T17:32:43.451407Z" } - } + }, + "outputs": [], + "execution_count": 44 }, { "cell_type": "markdown", "source": [ "### NKode Customer\n", "A customer has users and defines the attributes and set values for all its users.\n", - "Since our customer has 10 keys and 7 attributes per key, this gives a customer interface of 70 distinct attributes and 7 distinct attribute sets.\n", - "Each attribute belongs to one of the 7 sets." + "Since our customer has 5 keys and 6 attributes per key, this gives a customer interface of 30 distinct attributes and 6 distinct attribute sets.\n", + "Each attribute belongs to one of the 6 sets." ], "metadata": { "collapsed": false @@ -126,30 +128,35 @@ }, { "cell_type": "code", - "execution_count": 66, + "source": [ + "set_vals = customer.attributes.set_vals\n", + "attr_vals = customer.attributes.attr_vals\n", + "print(f\"Customer Sets: {set_vals}\")\n", + "keypad_view(attr_vals, keypad_size.attrs_per_key)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-08-01T17:32:43.627977Z", + "start_time": "2024-08-01T17:32:43.625820Z" + } + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Customer Sets: [6259, 41347, 52298, 30406]\n", - "Customer Attributes: [65233, 63177, 42010, 46768, 5724, 12484, 7294, 20676, 9411, 8047, 18067, 6808, 51196, 46992, 15995, 34735, 37237, 57815, 17974, 10378]\n" + "Customer Sets: [21921, 7738, 57204, 44555, 38162, 22025]\n", + "Keypad View\n", + "Key 0: [25764, 64003, 42138, 9976, 26896, 36991]\n", + "Key 1: [53269, 22932, 2731, 14908, 55210, 40777]\n", + "Key 2: [11304, 9784, 26683, 48512, 24904, 42130]\n", + "Key 3: [47297, 63193, 31705, 44, 46268, 28475]\n", + "Key 4: [38192, 28529, 11254, 19824, 47753, 34896]\n" ] } ], - "source": [ - "set_vals = customer.attributes.set_vals\n", - "attr_vals = customer.attributes.attr_vals\n", - "print(f\"Customer Sets: {set_vals}\")\n", - "print(f\"Customer Attributes: {attr_vals}\")" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-07-22T16:43:14.431062Z", - "start_time": "2024-07-22T16:43:14.413572Z" - } - } + "execution_count": 45 }, { "cell_type": "markdown", @@ -162,20 +169,6 @@ }, { "cell_type": "code", - "execution_count": 67, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Set to Attribute Map:\n", - "6259: [65233, 5724, 9411, 51196, 37237]\n", - "41347: [63177, 12484, 8047, 46992, 57815]\n", - "52298: [42010, 7294, 18067, 15995, 17974]\n", - "30406: [46768, 20676, 6808, 34735, 10378]\n" - ] - } - ], "source": [ "attr_keypad_view = list_to_matrix(attr_vals, keypad_size.attrs_per_key)\n", "attr_set_view = matrix_transpose(attr_keypad_view)\n", @@ -187,10 +180,26 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-07-22T16:43:14.431341Z", - "start_time": "2024-07-22T16:43:14.417167Z" + "end_time": "2024-08-01T17:32:43.631493Z", + "start_time": "2024-08-01T17:32:43.628798Z" } - } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Set to Attribute Map:\n", + "21921: [25764, 53269, 11304, 47297, 38192]\n", + "7738: [64003, 22932, 9784, 63193, 28529]\n", + "57204: [42138, 2731, 26683, 31705, 11254]\n", + "44555: [9976, 14908, 48512, 44, 19824]\n", + "38162: [26896, 55210, 24904, 46268, 47753]\n", + "22025: [36991, 40777, 42130, 28475, 34896]\n" + ] + } + ], + "execution_count": 46 }, { "cell_type": "markdown", @@ -202,9 +211,10 @@ "3. Confirm User NKode\n", "\n", "#### Generate Index Interface\n", - "- random interface is generated. Run the cell below over and over to see it change. Notice that values never move out of their columns jus their rows.\n", - "- each value in the interface is the index value of a customer attribute\n", - "- the user never learns what their \"real\" attribute is. All they do is specify an index in the customer interface\n" + " For the server to determine the users nkode, the user's interface must be dispersable. To make the interface dispersable, the server will randomly drop attribute sets to the number of attributes is equal to the number of keys. In our case, the server drops 1 attribute set to give us a 5 X 5 keypad with possible index values ranging from 0-29.\n", + " - Run the cell below over and over to see it change. Notice that values never move out of their columns just their rows.\n", + " - each value in the interface is the index value of a customer attribute\n", + " - the user never learns what their \"real\" attribute is. All they do is specify an index in the customer interface\n" ], "metadata": { "collapsed": false @@ -212,34 +222,40 @@ }, { "cell_type": "code", - "execution_count": 68, - "outputs": [ - { - "data": { - "text/plain": "[[4, 1, 10, 3],\n [8, 5, 2, 15],\n [0, 13, 14, 11],\n [16, 9, 6, 7],\n [12, 17, 18, 19]]" - }, - "execution_count": 68, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "session_id, signup_interface = api.generate_index_interface(customer_id)\n", - "list_to_matrix(signup_interface, keypad_size.attrs_per_key)" + "session_id, signup_interface = api.generate_signup_interface(customer_id)\n", + "list_to_matrix(signup_interface, keypad_size.numb_of_keys)" ], "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-07-22T16:43:14.431562Z", - "start_time": "2024-07-22T16:43:14.420566Z" + "end_time": "2024-08-01T17:32:43.636317Z", + "start_time": "2024-08-01T17:32:43.633201Z" } - } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[[18, 11, 22, 2, 19],\n", + " [0, 23, 28, 8, 25],\n", + " [6, 5, 10, 26, 13],\n", + " [12, 17, 4, 14, 1],\n", + " [24, 29, 16, 20, 7]]" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 47 }, { "cell_type": "markdown", "source": [ "#### Set NKode\n", - "The user identifies attributes in the interface they want in their nkode. Each attribute in the gui has an index value. Below the user has selected 16, 9, 6, 19. Graphiclly represent with anything. The only requirment is that the graphical must be associated with the same number everytime the user goes to login. If the user wants to change anything about their interface, they must also change their nkode." + "The user identifies attributes in the interface they want in their nkode. Each attribute in the gui has an index value. Below the user has selected 16, 9, 6, 19. Graphically represent with anything. The only requirement is that the graphical attributes must be associated with the same index value everytime the user goes to login. If the user wants to change anything about their interface(the number of keys, attributes or graphical attributes), they must also change their nkode." ], "metadata": { "collapsed": false @@ -247,170 +263,236 @@ }, { "cell_type": "code", - "execution_count": 69, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Keypad View\n", - "Key 0: [4, 1, 10, 3]\n", - "Key 1: [8, 5, 2, 15]\n", - "Key 2: [0, 13, 14, 11]\n", - "Key 3: [16, 9, 6, 7]\n", - "Key 4: [12, 17, 18, 19]\n", - "Selected Keys\n", - "[3, 3, 3, 4]\n" - ] - } - ], "source": [ - "keypad_view(signup_interface, keypad_size.attrs_per_key)\n", + "keypad_view(signup_interface, keypad_size.numb_of_keys)\n", "username = random_username()\n", - "user_passcode = [16, 9, 6, 19]\n", - "selected_keys_set = select_keys_with_passcode_values(user_passcode, signup_interface, keypad_size.attrs_per_key)\n", + "passcode_len = 4\n", + "user_passcode = signup_interface[:passcode_len]\n", + "selected_keys_set = select_keys_with_passcode_values(user_passcode, signup_interface, keypad_size.numb_of_keys)\n", + "print(f\"User Passcode: {user_passcode}\")\n", "print(f\"Selected Keys\\n{selected_keys_set}\")" ], "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-07-22T16:43:14.431673Z", - "start_time": "2024-07-22T16:43:14.424684Z" + "end_time": "2024-08-01T17:32:43.639361Z", + "start_time": "2024-08-01T17:32:43.637070Z" } - } - }, - { - "cell_type": "code", - "execution_count": 70, + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Keypad View\n", - "Key 0: [12, 9, 14, 15]\n", - "Key 1: [0, 17, 2, 3]\n", - "Key 2: [8, 13, 10, 7]\n", - "Key 3: [4, 5, 6, 19]\n", - "Key 4: [16, 1, 18, 11]\n", + "Key 0: [18, 11, 22, 2, 19]\n", + "Key 1: [0, 23, 28, 8, 25]\n", + "Key 2: [6, 5, 10, 26, 13]\n", + "Key 3: [12, 17, 4, 14, 1]\n", + "Key 4: [24, 29, 16, 20, 7]\n", + "User Passcode: [18, 11, 22, 2]\n", "Selected Keys\n", - "[4, 0, 3, 3]\n" + "[0, 0, 0, 0]\n" ] } ], + "execution_count": 48 + }, + { + "cell_type": "code", "source": [ "confirm_interface = api.set_nkode(username, customer_id, selected_keys_set, session_id)\n", - "keypad_view(confirm_interface, keypad_size.attrs_per_key)\n", - "selected_keys_confirm = select_keys_with_passcode_values(user_passcode, confirm_interface, keypad_size.attrs_per_key)\n", + "keypad_view(confirm_interface, keypad_size.numb_of_keys)\n", + "selected_keys_confirm = select_keys_with_passcode_values(user_passcode, confirm_interface, keypad_size.numb_of_keys)\n", "print(f\"Selected Keys\\n{selected_keys_confirm}\")" ], "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-07-22T16:43:14.431769Z", - "start_time": "2024-07-22T16:43:14.427713Z" + "end_time": "2024-08-01T17:32:43.642851Z", + "start_time": "2024-08-01T17:32:43.640093Z" } - } - }, - { - "cell_type": "markdown", - "source": [ - "### Attribute Dispersion\n", - "In order for the api to determine what the users attributes are, it must run a dispersion algorithm.\n", - "This means that none of the attributes in the set interface share a key with any of the attributes in the confirm interface.\n", - "Take a look at them next to each other." - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 71, + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Set Interface\n", "Keypad View\n", - "Key 0: [4, 1, 10, 3]\n", - "Key 1: [8, 5, 2, 15]\n", - "Key 2: [0, 13, 14, 11]\n", - "Key 3: [16, 9, 6, 7]\n", - "Key 4: [12, 17, 18, 19]\n" + "Key 0: [6, 29, 4, 8, 19]\n", + "Key 1: [12, 5, 22, 20, 25]\n", + "Key 2: [18, 17, 28, 26, 7]\n", + "Key 3: [0, 11, 16, 14, 13]\n", + "Key 4: [24, 23, 10, 2, 1]\n", + "Selected Keys\n", + "[2, 3, 1, 4]\n" ] } ], - "source": [ - "print(\"Set Interface\")\n", - "keypad_view(signup_interface, keypad_size.attrs_per_key)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-07-22T16:43:14.447860Z", - "start_time": "2024-07-22T16:43:14.430888Z" - } - } + "execution_count": 49 }, { "cell_type": "code", - "execution_count": 72, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Confirm Interface\n", - "Keypad View\n", - "Key 0: [12, 9, 14, 15]\n", - "Key 1: [0, 17, 2, 3]\n", - "Key 2: [8, 13, 10, 7]\n", - "Key 3: [4, 5, 6, 19]\n", - "Key 4: [16, 1, 18, 11]\n" - ] - } - ], - "source": [ - "print(\"Confirm Interface\")\n", - "keypad_view(confirm_interface, keypad_size.attrs_per_key)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-07-22T16:43:14.448110Z", - "start_time": "2024-07-22T16:43:14.433535Z" - } - } - }, - { - "cell_type": "code", - "execution_count": 73, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Success\n" - ] - } - ], "source": [ "# the session is deleted after the nkode is confirmed. To rerun this cell, rerun the cells above starting with cell 8 where the username is created\n", "success = api.confirm_nkode(username, customer_id, selected_keys_confirm, session_id)\n", - "if success:\n", - " print(\"Success\")\n", - "else:\n", - " print(\"Failed\")" + "print(success)" ], "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-07-22T16:43:15.081248Z", - "start_time": "2024-07-22T16:43:14.437249Z" + "end_time": "2024-08-01T17:32:44.271378Z", + "start_time": "2024-08-01T17:32:43.643592Z" } - } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "execution_count": 50 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "## Enciphering nKode\n", + "The method UserCipherKeys.encipher_nkode secures a users nKode in the database. This method is called in api.confirm_nkode\n", + "```\n", + "class EncipheredNKode(BaseModel):\n", + " code: str\n", + " mask: str\n", + "```\n", + "\n" + ] + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-08-01T17:32:44.606104Z", + "start_time": "2024-08-01T17:32:44.272228Z" + } + }, + "cell_type": "code", + "source": [ + "from src.user_cipher_keys import UserCipherKeys\n", + "\n", + "user_keys = UserCipherKeys.new(\n", + " customer.attributes.keypad_size,\n", + " customer.attributes.set_vals,\n", + " customer.nkode_policy.max_nkode_len\n", + ")\n", + "\n", + "passcode = [10, 23, 14, 7]\n", + "passcode_server_attr = [customer.attributes.attr_vals[idx] for idx in passcode]\n", + "passcode_server_set = [customer.attributes.get_attr_set_val(attr) for attr in passcode_server_attr]" + ], + "outputs": [], + "execution_count": 51 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "#### Encipher Mask\n", + "Recall:\n", + "1. set_key_i = (set_rand_numb_i ^ set_val_i) \n", + "2. mask_key_i = mask_rand_numb_i\n", + "3. padded_passcode_server_set_i = set_val_i\n", + "4. len(set_key) == len(mask_key) == (padded_passcode_server_set) == max_nkode_len == 10\n", + "where i is the index\n", + " \n", + "- mask_i = mask_key_i ^ padded_passcode_server_set_i ^ set_key_i\n", + "- mask_i = mask_rand_num_i ^ set_val_i ^ set_rand_numb_i ^ set_val_i\n", + "- mask_i = mask_rand_num_i ^ set_rand_numb_i # set_val_i is cancelled out" + ] + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-08-01T17:32:44.609542Z", + "start_time": "2024-08-01T17:32:44.606956Z" + } + }, + "cell_type": "code", + "source": [ + "from src.utils import xor_lists\n", + "\n", + "padded_passcode_server_set = user_keys.pad_user_mask(passcode_server_set, customer.attributes.set_vals)\n", + "\n", + "set_idx = [customer.attributes.get_set_index(set_val) for set_val in padded_passcode_server_set]\n", + "mask_set_keys = [user_keys.set_key[idx] for idx in set_idx]\n", + "ciphered_mask = xor_lists(mask_set_keys, padded_passcode_server_set)\n", + "ciphered_mask = xor_lists(ciphered_mask, user_keys.mask_key)\n", + "mask = user_keys.encode_base64_str(ciphered_mask)" + ], + "outputs": [], + "execution_count": 52 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "#### Encipher Passcode\n", + "UserCipherKeys.encipher_salt_hash_code:\n", + "\n", + "- ciphered_customer_attr = alpha_key ^ customer_attr\n", + "- ciphered_passcode_i = pass_key_i ^ ciphered_customer_attr_i\n", + "- code = hash(ciphered_passcode, salt)" + ] + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-08-01T17:32:44.916167Z", + "start_time": "2024-08-01T17:32:44.611593Z" + } + }, + "cell_type": "code", + "source": [ + "import bcrypt\n", + "import hashlib\n", + "import base64\n", + "from src.utils import int_array_to_bytes\n", + "\n", + "ciphered_customer_attrs = xor_lists(customer.attributes.attr_vals, user_keys.alpha_key)\n", + "passcode_ciphered_attrs = [ciphered_customer_attrs[idx] for idx in passcode]\n", + "pad_len = customer.nkode_policy.max_nkode_len - passcode_len\n", + "\n", + "passcode_ciphered_attrs.extend([0 for _ in range(pad_len)])\n", + "\n", + "ciphered_code = xor_lists(passcode_ciphered_attrs, user_keys.pass_key)\n", + "\n", + "passcode_bytes = int_array_to_bytes(ciphered_code)\n", + "passcode_digest = base64.b64encode(hashlib.sha256(passcode_bytes).digest())\n", + "hashed_data = bcrypt.hashpw(passcode_digest, user_keys.salt)\n", + "code = hashed_data.decode(\"utf-8\")" + ], + "outputs": [], + "execution_count": 53 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-08-01T17:32:44.919048Z", + "start_time": "2024-08-01T17:32:44.916981Z" + } + }, + "cell_type": "code", + "source": [ + "from src.models import EncipheredNKode\n", + "\n", + "enciphered_nkode = EncipheredNKode(\n", + " mask=mask,\n", + " code=code,\n", + ")" + ], + "outputs": [], + "execution_count": 54 }, { "cell_type": "markdown", @@ -425,16 +507,135 @@ }, { "cell_type": "code", - "execution_count": 73, - "outputs": [], - "source": [], + "source": [ + "login_interface = api.get_login_interface(username, customer_id)\n", + "keypad_view(login_interface, keypad_size.attrs_per_key)\n", + "selected_keys_login = select_keys_with_passcode_values(user_passcode, login_interface, keypad_size.attrs_per_key)\n", + "print(f\"Selected Keys: {selected_keys_login}\")\n", + "success = api.login(customer_id, username, selected_keys_login)\n", + "print(success)" + ], "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-07-22T16:43:15.083482Z", - "start_time": "2024-07-22T16:43:15.078924Z" + "end_time": "2024-08-01T17:32:45.225994Z", + "start_time": "2024-08-01T17:32:44.919967Z" } - } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Keypad View\n", + "Key 0: [24, 7, 14, 21, 10, 29]\n", + "Key 1: [6, 13, 26, 9, 28, 5]\n", + "Key 2: [0, 25, 20, 3, 22, 23]\n", + "Key 3: [18, 19, 2, 27, 16, 11]\n", + "Key 4: [12, 1, 8, 15, 4, 17]\n", + "Selected Keys: [3, 3, 2, 3]\n", + "True\n" + ] + } + ], + "execution_count": 55 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "## Validate Login Key Entry\n", + "- decipher user mask and recover nkode set values\n", + "- get presumed attribute from key selection and set values\n", + "- encipher, salt and hash presumed attribute values and compare it to the users hashed code" + ] + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "### Decipher Mask\n", + "Recall:\n", + "- set_key_i = (set_key_rand_numb_i ^ set_val_i) \n", + "- mask_i = mask_key_rand_num_i ^ set_key_rand_numb_i\n", + "\n", + "Recover nKode set values: \n", + "- decode mask from base64 to int\n", + "- deciphered_mask = mask ^ mask_key\n", + "- deciphered_mask_i = set_key_rand_numb # mask_key_rand_num_i is cancelled out\n", + "- set_key_rand_component = set_key ^ set_values\n", + "- deduce the set value" + ] + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-08-01T17:35:30.015361Z", + "start_time": "2024-08-01T17:35:30.010731Z" + } + }, + "cell_type": "code", + "source": [ + "user = customer.users[username]\n", + "user_keys = user.user_keys\n", + "user_mask = user.enciphered_passcode.mask\n", + "decoded_mask = user_keys.decode_base64_str(user_mask)\n", + "deciphered_mask = xor_lists(decoded_mask, user_keys.mask_key)\n", + "set_key_rand_component = xor_lists(set_vals, user_keys.set_key)\n", + "passcode_sets = []\n", + "for set_cipher in deciphered_mask[:passcode_len]:\n", + " set_idx = set_key_rand_component.index(set_cipher)\n", + " passcode_sets.append(set_vals[set_idx])\n", + "print(passcode_sets)" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[21921, 22025, 38162, 57204]\n" + ] + } + ], + "execution_count": 60 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### Get Presumed Attributes\n" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-08-01T17:35:31.615135Z", + "start_time": "2024-08-01T17:35:31.307978Z" + } + }, + "cell_type": "code", + "source": [ + "set_vals_idx = [customer.attributes.get_set_index(set_val) for set_val in passcode_sets]\n", + "\n", + "presumed_selected_attributes_idx = []\n", + "for idx in range(passcode_len):\n", + " key_numb = selected_keys_login[idx]\n", + " set_idx = set_vals_idx[idx]\n", + " selected_attr_idx = customer.users[username].user_interface.get_attr_idx_by_keynumb_setidx(key_numb, set_idx)\n", + " presumed_selected_attributes_idx.append(selected_attr_idx)\n", + "\n", + "enciphered_nkode = user_keys.encipher_salt_hash_code(presumed_selected_attributes_idx, customer.attributes)\n", + "\n", + "print(enciphered_nkode == user.enciphered_passcode.code)" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "execution_count": 61 }, { "cell_type": "markdown", @@ -447,186 +648,18 @@ "collapsed": false } }, - { - "cell_type": "markdown", - "source": [ - "## Dispersion" - ], - "metadata": { - "collapsed": false - } - }, { "cell_type": "code", - "execution_count": 74, - "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|" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from src.utils import secure_fisher_yates_shuffle, matrix_to_list\n", - "from src.user_interface import UserInterface\n", - "from IPython.display import Markdown, display\n", - "\n", - "def keypad_md_table(interface: list[int], keypad_size: KeypadSize) -> str:\n", - " assert (keypad_size.numb_of_attrs == len(interface))\n", - " interface_keypad = list_to_matrix(interface, keypad_size.attrs_per_key)\n", - " table = \"|key|\" + \"\".join([f\"set{idx}|\" for idx in range(keypad_size.attrs_per_key)])\n", - " table += \"\\n|\" + \"\".join(\"-|\" for _ in range(keypad_size.attrs_per_key+1))\n", - "\n", - " for key in range(keypad_size.numb_of_keys):\n", - " table += f\"\\n|key{key+1}|\"\n", - " table += \"|\".join([str(attr) for attr in interface_keypad[key]])\n", - " table += \"|\"\n", - " return table\n", - "\n", - "\n", - "keypad_size = KeypadSize(numb_of_keys=5, attrs_per_key=4)\n", - "attrs = [1, 10, 11, 100]\n", - "interface = []\n", - "for key_numb in range(1,keypad_size.numb_of_keys+1):\n", - " interface.extend([key_numb*attr for attr in attrs])\n", - "\n", - "demo_interface = UserInterface(keypad_size=keypad_size, interface=interface)\n", - "\n", - "display(Markdown(keypad_md_table(demo_interface.interface, keypad_size)))" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-07-22T16:43:15.097910Z", - "start_time": "2024-07-22T16:43:15.084617Z" - } - } - }, - { - "cell_type": "code", - "execution_count": 75, - "outputs": [ - { - "data": { - "text/plain": "", - "text/markdown": "|key|set0|set1|set2|set3|\n|-|-|-|-|-|\n|key1|4|40|44|400|\n|key2|2|20|22|200|\n|key3|1|10|11|100|\n|key4|5|50|55|500|\n|key5|3|30|33|300|" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "demo_interface_matrix = list_to_matrix(demo_interface.interface, demo_interface.keypad_size.attrs_per_key)\n", - "shuffled_keys = secure_fisher_yates_shuffle(demo_interface_matrix)\n", - "shuffled_keys_list = matrix_to_list(shuffled_keys)\n", - "display(Markdown(keypad_md_table(shuffled_keys_list, keypad_size)))\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-07-22T16:43:15.098089Z", - "start_time": "2024-07-22T16:43:15.088214Z" - } - } - }, - { - "cell_type": "code", - "execution_count": 76, - "outputs": [ - { - "data": { - "text/plain": "", - "text/markdown": "|key|set0|set1|set2|set3|\n|-|-|-|-|-|\n|key1|2|10|44|500|\n|key2|1|50|22|300|\n|key3|5|30|11|400|\n|key4|3|40|55|200|\n|key5|4|20|33|100|" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "attr_rotation = secure_fisher_yates_shuffle(list(range(keypad_size.numb_of_keys)))[:keypad_size.attrs_per_key]\n", - "dispersed_interface = UserInterface.random_attribute_rotation(\n", - " shuffled_keys,\n", - " attr_rotation\n", - ")\n", - "\n", - "display(Markdown(keypad_md_table(matrix_to_list(dispersed_interface), keypad_size)))" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-07-22T16:43:15.098218Z", - "start_time": "2024-07-22T16:43:15.091198Z" - } - } - }, - { - "cell_type": "markdown", "source": [], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 80, - "outputs": [ - { - "data": { - "text/plain": "'$2b$12$M2kUbtPVmpphEHJIw/AKc.v96GcyR9WqPzNcbQqSHJWjiZJ6NwqMm'" - }, - "execution_count": 80, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "user_hash = list(api.customers[customer_id].users.values())[0].enciphered_passcode.code\n", - "user_hash\n" - ], "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-07-22T16:46:22.182625Z", - "start_time": "2024-07-22T16:46:22.178757Z" + "end_time": "2024-08-01T17:32:45.239562Z", + "start_time": "2024-08-01T17:32:45.239409Z" } - } - }, - { - "cell_type": "code", - "execution_count": 84, - "outputs": [ - { - "data": { - "text/plain": "[27172,\n 59678,\n 42816,\n 42517,\n 14869,\n 3862,\n 33437,\n 50365,\n 1299,\n 423,\n 16708,\n 23065,\n 1118,\n 54789,\n 22038,\n 22603,\n 36630,\n 18246,\n 48084,\n 32460]" - }, - "execution_count": 84, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list(api.customers[customer_id].users.values())[0].user_keys.alpha_key\n", - "\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-07-22T16:48:52.733419Z", - "start_time": "2024-07-22T16:48:52.728228Z" - } - } - }, - { - "cell_type": "code", - "execution_count": null, + }, "outputs": [], - "source": [], - "metadata": { - "collapsed": false - } + "execution_count": null } ], "metadata": { diff --git a/src/customer.py b/src/customer.py index 05db63e..7db7626 100644 --- a/src/customer.py +++ b/src/customer.py @@ -28,18 +28,14 @@ class Customer(BaseModel): user.enciphered_passcode.mask, self.attributes.set_vals, len(selected_keys)) set_vals_idx = [self.attributes.get_set_index(set_val) for set_val in passcode_set_vals] - presumed_selected_attributes = [] presumed_selected_attributes_idx = [] for idx in range(passcode_len): key_numb = selected_keys[idx] - key_attribute_idxs = user.user_interface.get_key_attr_idxs(key_numb) - set_idx = set_vals_idx[idx] - selected_attr_idx = key_attribute_idxs[set_idx] + selected_attr_idx = user.user_interface.get_attr_idx_by_keynumb_setidx(key_numb, set_idx) presumed_selected_attributes_idx.append(selected_attr_idx) - presumed_selected_attributes.append(selected_attr_idx) - enciphered_attr = user.user_keys.encipher_salt_hash_code(presumed_selected_attributes, self.attributes) + enciphered_attr = user.user_keys.encipher_salt_hash_code(presumed_selected_attributes_idx, self.attributes) if enciphered_attr != user.enciphered_passcode.code: return False diff --git a/src/user_cipher_keys.py b/src/user_cipher_keys.py index 81a90b9..391bffc 100644 --- a/src/user_cipher_keys.py +++ b/src/user_cipher_keys.py @@ -68,8 +68,8 @@ class UserCipherKeys(BaseModel): passcode_attrs = [customer_interface.attr_vals[idx] for idx in passcode_attr_idx] passcode_sets = [customer_interface.get_attr_set_val(attr) for attr in passcode_attrs] - code = self.encipher_salt_hash_code(passcode_attr_idx, customer_interface) mask = self.encipher_mask(passcode_sets, customer_interface) + code = self.encipher_salt_hash_code(passcode_attr_idx, customer_interface) return EncipheredNKode( code=code, mask=mask @@ -99,8 +99,8 @@ class UserCipherKeys(BaseModel): ) -> str: padded_passcode_sets = self.pad_user_mask(passcode_sets, customer_interface.set_vals) set_idx = [customer_interface.get_set_index(set_val) for set_val in padded_passcode_sets] - sorted_set_key = [self.set_key[idx] for idx in set_idx] - ciphered_mask = xor_lists(sorted_set_key, padded_passcode_sets) + mask_set_keys = [self.set_key[idx] for idx in set_idx] + ciphered_mask = xor_lists(mask_set_keys, padded_passcode_sets) ciphered_mask = xor_lists(ciphered_mask, self.mask_key) mask = self.encode_base64_str(ciphered_mask) return mask @@ -108,9 +108,9 @@ class UserCipherKeys(BaseModel): def decipher_mask(self, mask: str, set_vals: list, passcode_len: int) -> list[int]: decoded_mask = self.decode_base64_str(mask) deciphered_mask = xor_lists(decoded_mask, self.mask_key) - set_key_ciphers = xor_lists(set_vals, self.set_key) + set_key_rand_component = xor_lists(set_vals, self.set_key) passcode_sets = [] for set_cipher in deciphered_mask[:passcode_len]: - set_idx = set_key_ciphers.index(set_cipher) + set_idx = set_key_rand_component.index(set_cipher) passcode_sets.append(set_vals[set_idx]) return passcode_sets diff --git a/src/user_interface.py b/src/user_interface.py index 99681af..223f4b4 100644 --- a/src/user_interface.py +++ b/src/user_interface.py @@ -96,7 +96,8 @@ class UserInterface(BaseModel): return graph - def get_key_attr_idxs(self, key_numb: int) -> list[int]: + def get_attr_idx_by_keynumb_setidx(self, key_numb: int, set_idx: int) -> int: assert (0 <= key_numb < self.keypad_size.numb_of_keys) keypad_attr_idx = self.interface_keypad_matrix() - return keypad_attr_idx[key_numb] + + return keypad_attr_idx[key_numb][set_idx] diff --git a/test/test_nkode_api.py b/test/test_nkode_api.py index a84399d..87cf18d 100644 --- a/test/test_nkode_api.py +++ b/test/test_nkode_api.py @@ -16,13 +16,14 @@ def test_create_new_user_and_renew_keys(nkode_api, keypad_size, passocode_len): username = "test_username" nkode_policy = NKodePolicy() # default policy customer_id = nkode_api.create_new_customer(keypad_size, nkode_policy) - session_id, set_interface = nkode_api.generate_index_interface(customer_id) + session_id, set_interface = nkode_api.generate_signup_interface(customer_id) user_passcode = set_interface[:passocode_len] - key_selection = lambda interface: [interface.index(attr) // keypad_size.numb_of_keys for attr in user_passcode] - set_key_selection = key_selection(set_interface) + + signup_key_selection = lambda interface: [interface.index(attr) // keypad_size.numb_of_keys for attr in user_passcode] + set_key_selection = signup_key_selection(set_interface) confirm_interface = nkode_api.set_nkode(username, customer_id, set_key_selection, session_id) - confirm_key_selection = key_selection(confirm_interface) + confirm_key_selection = signup_key_selection(confirm_interface) successful_confirm = nkode_api.confirm_nkode( username, customer_id, @@ -31,21 +32,21 @@ def test_create_new_user_and_renew_keys(nkode_api, keypad_size, passocode_len): ) assert successful_confirm - key_selection = lambda interface: [interface.index(attr) // keypad_size.attrs_per_key for attr in user_passcode] - login_interface = nkode_api.get_login_index_interface(username, customer_id) - login_key_selection = key_selection(login_interface) + sign_in_key_selection = lambda interface: [interface.index(attr) // keypad_size.attrs_per_key for attr in user_passcode] + login_interface = nkode_api.get_login_interface(username, customer_id) + login_key_selection = sign_in_key_selection(login_interface) successful_login = nkode_api.login(customer_id, username, login_key_selection) assert successful_login successful_renew = nkode_api.renew_keys(customer_id) assert successful_renew - login_interface = nkode_api.get_login_index_interface(username, customer_id) - login_key_selection = key_selection(login_interface) + login_interface = nkode_api.get_login_interface(username, customer_id) + login_key_selection = sign_in_key_selection(login_interface) successful_login = nkode_api.login(customer_id, username, login_key_selection) assert successful_login - login_interface = nkode_api.get_login_index_interface(username, customer_id) - login_key_selection = key_selection(login_interface) + login_interface = nkode_api.get_login_interface(username, customer_id) + login_key_selection = sign_in_key_selection(login_interface) successful_login = nkode_api.login(customer_id, username, login_key_selection) assert successful_login