update documentation
This commit is contained in:
@@ -2,6 +2,18 @@
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:57.439685Z",
|
||||
"start_time": "2025-03-27T19:17:57.405237Z"
|
||||
},
|
||||
"collapsed": false,
|
||||
"jupyter": {
|
||||
"outputs_hidden": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import sys\n",
|
||||
"import os\n",
|
||||
@@ -25,25 +37,18 @@
|
||||
" interface_keypad = keypad.reshape(-1, props_per_key)\n",
|
||||
" for idx, key_vals in enumerate(interface_keypad):\n",
|
||||
" print(f\"Key {idx}: {key_vals}\")\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:57.439685Z",
|
||||
"start_time": "2025-03-27T19:17:57.405237Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"execution_count": 1
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:57.446190Z",
|
||||
"start_time": "2025-03-27T19:17:57.443952Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"api = NKodeAPI()\n",
|
||||
"user_icons = np.array([\n",
|
||||
@@ -54,13 +59,11 @@
|
||||
" \"🦁\", \"🐻\", \"🐸\", \"🐙\", \"🦄\",\n",
|
||||
" \"🌟\", \"⚡\", \"🔥\", \"🍕\", \"🎉\"\n",
|
||||
"])"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 2
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### nKode Customer\n",
|
||||
"An nKode customer is business has employees (users). An nKode API can service many customers each with their own users.\n",
|
||||
@@ -69,8 +72,8 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Customer Cipher Keys\n",
|
||||
"Each customer has unique cipher keys.\n",
|
||||
@@ -81,36 +84,14 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:57.487136Z",
|
||||
"start_time": "2025-03-27T19:17:57.475079Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"policy = NKodePolicy(\n",
|
||||
" max_nkode_len=10,\n",
|
||||
" min_nkode_len=4,\n",
|
||||
" distinct_positions=0,\n",
|
||||
" distinct_properties=4,\n",
|
||||
")\n",
|
||||
"keypad_size = KeypadSize(\n",
|
||||
" numb_of_keys = 5,\n",
|
||||
" props_per_key = 6\n",
|
||||
")\n",
|
||||
"customer_id = api.create_new_customer(keypad_size, policy)\n",
|
||||
"customer = api.customers[customer_id]\n",
|
||||
"print(f\"Customer Position Key: {customer.cipher.position_key}\")\n",
|
||||
"print(f\"Customer Properties Key:\")\n",
|
||||
"customer_prop_keypad = customer.cipher.property_key.reshape(-1, keypad_size.props_per_key)\n",
|
||||
"for idx, key_vals in enumerate(customer_prop_keypad):\n",
|
||||
" print(f\"{key_vals}\")\n",
|
||||
"position_properties_dict = dict(zip(customer.cipher.position_key, customer_prop_keypad.T))\n",
|
||||
"print(f\"Position to Properties Map:\")\n",
|
||||
"for pos_val, props in position_properties_dict.items():\n",
|
||||
" print(f\"{pos_val}: {props}\")"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@@ -133,23 +114,39 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 3
|
||||
"source": [
|
||||
"policy = NKodePolicy(\n",
|
||||
" max_nkode_len=10,\n",
|
||||
" min_nkode_len=4,\n",
|
||||
" distinct_positions=0,\n",
|
||||
" distinct_properties=4,\n",
|
||||
")\n",
|
||||
"keypad_size = KeypadSize(\n",
|
||||
" numb_of_keys = 5,\n",
|
||||
" props_per_key = 6\n",
|
||||
")\n",
|
||||
"customer_id = api.create_new_customer(keypad_size, policy)\n",
|
||||
"customer = api.customers[customer_id]\n",
|
||||
"print(f\"Customer Position Key: {customer.cipher.position_key}\")\n",
|
||||
"print(f\"Customer Properties Key:\")\n",
|
||||
"customer_prop_keypad = customer.cipher.property_key.reshape(-1, keypad_size.props_per_key)\n",
|
||||
"for idx, key_vals in enumerate(customer_prop_keypad):\n",
|
||||
" print(f\"{key_vals}\")\n",
|
||||
"position_properties_dict = dict(zip(customer.cipher.position_key, customer_prop_keypad.T))\n",
|
||||
"print(f\"Position to Properties Map:\")\n",
|
||||
"for pos_val, props in position_properties_dict.items():\n",
|
||||
" print(f\"{pos_val}: {props}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:57.507904Z",
|
||||
"start_time": "2025-03-27T19:17:57.505187Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"user_icon_keypad = user_icons.reshape(-1, keypad_size.props_per_key)\n",
|
||||
"pos_icons_dict = dict(zip(customer.cipher.position_key, user_icon_keypad.T))\n",
|
||||
"print(\"Position Value to Icons Map:\")\n",
|
||||
"for pos_val, icons in pos_icons_dict.items():\n",
|
||||
" print(f\"{pos_val}: {icons}\")\n"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@@ -165,11 +162,17 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 4
|
||||
"source": [
|
||||
"user_icon_keypad = user_icons.reshape(-1, keypad_size.props_per_key)\n",
|
||||
"pos_icons_dict = dict(zip(customer.cipher.position_key, user_icon_keypad.T))\n",
|
||||
"print(\"Position Value to Icons Map:\")\n",
|
||||
"for pos_val, icons in pos_icons_dict.items():\n",
|
||||
" print(f\"{pos_val}: {icons}\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### User Signup\n",
|
||||
"Users can create an nKode with these steps:\n",
|
||||
@@ -187,30 +190,23 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:57.541997Z",
|
||||
"start_time": "2025-03-27T19:17:57.534379Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"username = random_username()\n",
|
||||
"signup_session_id, set_signup_keypad = api.generate_signup_keypad(customer_id, username)\n",
|
||||
"display(Markdown(\"\"\"### Icon Keypad\"\"\"))\n",
|
||||
"keypad_view(user_icons[set_signup_keypad], keypad_size.numb_of_keys)\n",
|
||||
"display(Markdown(\"\"\"### Index Keypad\"\"\"))\n",
|
||||
"keypad_view(set_signup_keypad, keypad_size.numb_of_keys)\n",
|
||||
"display(Markdown(\"\"\"### Customer Properties Keypad\"\"\"))\n",
|
||||
"keypad_view(customer.cipher.property_key[set_signup_keypad], keypad_size.numb_of_keys)"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"### Icon Keypad"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
],
|
||||
"text/markdown": "### Icon Keypad"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
@@ -228,10 +224,12 @@
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"### Index Keypad"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
],
|
||||
"text/markdown": "### Index Keypad"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
@@ -249,10 +247,12 @@
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"### Customer Properties Keypad"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
],
|
||||
"text/markdown": "### Customer Properties Keypad"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
@@ -269,33 +269,34 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 5
|
||||
"source": [
|
||||
"username = random_username()\n",
|
||||
"signup_session_id, set_signup_keypad = api.generate_signup_keypad(customer_id, username)\n",
|
||||
"display(Markdown(\"\"\"### Icon Keypad\"\"\"))\n",
|
||||
"keypad_view(user_icons[set_signup_keypad], keypad_size.numb_of_keys)\n",
|
||||
"display(Markdown(\"\"\"### Index Keypad\"\"\"))\n",
|
||||
"keypad_view(set_signup_keypad, keypad_size.numb_of_keys)\n",
|
||||
"display(Markdown(\"\"\"### Customer Properties Keypad\"\"\"))\n",
|
||||
"keypad_view(customer.cipher.property_key[set_signup_keypad], keypad_size.numb_of_keys)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Set nKode\n",
|
||||
"The client receives `user_icons`, `set_signup_keypad`\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:57.582109Z",
|
||||
"start_time": "2025-03-27T19:17:57.578783Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"passcode_len = 4\n",
|
||||
"passcode_property_indices = np.random.choice(set_signup_keypad.reshape(-1), size=passcode_len, replace=False).tolist()\n",
|
||||
"selected_keys_set = select_keys_with_passcode_values(passcode_property_indices, set_signup_keypad, keypad_size.numb_of_keys)\n",
|
||||
"print(f\"User Passcode Indices: {passcode_property_indices}\")\n",
|
||||
"print(f\"User Passcode Icons: {user_icons[passcode_property_indices]}\")\n",
|
||||
"print(f\"User Passcode Server-side properties: {customer.cipher.property_key[passcode_property_indices]}\")\n",
|
||||
"print(f\"Selected Keys: {selected_keys_set}\")"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@@ -308,32 +309,33 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 6
|
||||
"source": [
|
||||
"passcode_len = 4\n",
|
||||
"passcode_property_indices = np.random.choice(set_signup_keypad.reshape(-1), size=passcode_len, replace=False).tolist()\n",
|
||||
"selected_keys_set = select_keys_with_passcode_values(passcode_property_indices, set_signup_keypad, keypad_size.numb_of_keys)\n",
|
||||
"print(f\"User Passcode Indices: {passcode_property_indices}\")\n",
|
||||
"print(f\"User Passcode Icons: {user_icons[passcode_property_indices]}\")\n",
|
||||
"print(f\"User Passcode Server-side properties: {customer.cipher.property_key[passcode_property_indices]}\")\n",
|
||||
"print(f\"Selected Keys: {selected_keys_set}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Confirm nKode\n",
|
||||
"Submit the set key entry to render the confirm keypad."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:57.846195Z",
|
||||
"start_time": "2025-03-27T19:17:57.599899Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"confirm_keypad = api.set_nkode(customer_id, selected_keys_set, signup_session_id)\n",
|
||||
"keypad_view(confirm_keypad, keypad_size.numb_of_keys)\n",
|
||||
"selected_keys_confirm = select_keys_with_passcode_values(passcode_property_indices, confirm_keypad, keypad_size.numb_of_keys)\n",
|
||||
"print(f\"Selected Keys\\n{selected_keys_confirm}\")\n",
|
||||
"success = api.confirm_nkode(customer_id, selected_keys_confirm, signup_session_id)\n",
|
||||
"assert success"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@@ -349,31 +351,31 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 7
|
||||
"source": [
|
||||
"confirm_keypad = api.set_nkode(customer_id, selected_keys_set, signup_session_id)\n",
|
||||
"keypad_view(confirm_keypad, keypad_size.numb_of_keys)\n",
|
||||
"selected_keys_confirm = select_keys_with_passcode_values(passcode_property_indices, confirm_keypad, keypad_size.numb_of_keys)\n",
|
||||
"print(f\"Selected Keys\\n{selected_keys_confirm}\")\n",
|
||||
"success = api.confirm_nkode(customer_id, selected_keys_confirm, signup_session_id)\n",
|
||||
"assert success"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"source": "### Inferring an nKode selection"
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Inferring an nKode selection"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:57.858315Z",
|
||||
"start_time": "2025-03-27T19:17:57.855013Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"for idx in range(passcode_len):\n",
|
||||
" selected_key_set = selected_keys_set[idx]\n",
|
||||
" selected_set_key_idx = set_signup_keypad.reshape(-1, keypad_size.numb_of_keys)[selected_key_set]\n",
|
||||
" print(f\"Set Key {idx}: {user_icons[selected_set_key_idx]}\")\n",
|
||||
" selected_key_confirm = selected_keys_confirm[idx]\n",
|
||||
" selected_confirm_key_idx = confirm_keypad.reshape(-1, keypad_size.numb_of_keys)[selected_key_confirm]\n",
|
||||
" print(f\"Confirm Key {idx}: {user_icons[selected_confirm_key_idx]}\")\n",
|
||||
" print(f\"Overlapping icon {user_icons[passcode_property_indices[idx]]}\")"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@@ -394,11 +396,20 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 8
|
||||
"source": [
|
||||
"for idx in range(passcode_len):\n",
|
||||
" selected_key_set = selected_keys_set[idx]\n",
|
||||
" selected_set_key_idx = set_signup_keypad.reshape(-1, keypad_size.numb_of_keys)[selected_key_set]\n",
|
||||
" print(f\"Set Key {idx}: {user_icons[selected_set_key_idx]}\")\n",
|
||||
" selected_key_confirm = selected_keys_confirm[idx]\n",
|
||||
" selected_confirm_key_idx = confirm_keypad.reshape(-1, keypad_size.numb_of_keys)[selected_key_confirm]\n",
|
||||
" print(f\"Confirm Key {idx}: {user_icons[selected_confirm_key_idx]}\")\n",
|
||||
" print(f\"Overlapping icon {user_icons[passcode_property_indices[idx]]}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## User Cipher\n",
|
||||
"\n",
|
||||
@@ -412,30 +423,30 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:57.879460Z",
|
||||
"start_time": "2025-03-27T19:17:57.873816Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from src.user_cipher import UserCipher\n",
|
||||
"user_cipher = UserCipher.create(keypad_size, customer.cipher.position_key, customer.nkode_policy.max_nkode_len)\n",
|
||||
"user_prop_key_keypad = user_cipher.property_key.reshape(-1, keypad_size.props_per_key)"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 9
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:57.904749Z",
|
||||
"start_time": "2025-03-27T19:17:57.902224Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": "print(f\"Property Key:\\n{user_prop_key_keypad}\")",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@@ -450,17 +461,19 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 10
|
||||
"source": [
|
||||
"print(f\"Property Key:\\n{user_prop_key_keypad}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:57.951642Z",
|
||||
"start_time": "2025-03-27T19:17:57.949347Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": "print(f\"Passcode Key: {user_cipher.pass_key}\")",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@@ -470,17 +483,19 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 11
|
||||
"source": [
|
||||
"print(f\"Passcode Key: {user_cipher.pass_key}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:57.989194Z",
|
||||
"start_time": "2025-03-27T19:17:57.986687Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": "print(f\"Mask Key: {user_cipher.mask_key}\")",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@@ -490,17 +505,19 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 12
|
||||
"source": [
|
||||
"print(f\"Mask Key: {user_cipher.mask_key}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:58.019886Z",
|
||||
"start_time": "2025-03-27T19:17:58.017350Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": "print(f\"Combined Position Key: {user_cipher.combined_position_key}\")",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@@ -510,17 +527,19 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 13
|
||||
"source": [
|
||||
"print(f\"Combined Position Key: {user_cipher.combined_position_key}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:58.050384Z",
|
||||
"start_time": "2025-03-27T19:17:58.047868Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": "print(f\"User Position Key = combined_pos_key XOR customer_pos_key: {user_cipher.combined_position_key ^ customer.cipher.position_key}\")",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@@ -530,22 +549,19 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 14
|
||||
"source": [
|
||||
"print(f\"User Position Key = combined_pos_key XOR customer_pos_key: {user_cipher.combined_position_key ^ customer.cipher.position_key}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:58.138360Z",
|
||||
"start_time": "2025-03-27T19:17:58.135782Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"position_properties_dict = dict(zip(user_cipher.combined_position_key, user_prop_key_keypad.T))\n",
|
||||
"print(f\"Combined Position to Properties Map:\")\n",
|
||||
"for pos_val, props in position_properties_dict.items():\n",
|
||||
" print(f\"{pos_val}: {props}\")"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@@ -561,11 +577,16 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 15
|
||||
"source": [
|
||||
"position_properties_dict = dict(zip(user_cipher.combined_position_key, user_prop_key_keypad.T))\n",
|
||||
"print(f\"Combined Position to Properties Map:\")\n",
|
||||
"for pos_val, props in position_properties_dict.items():\n",
|
||||
" print(f\"{pos_val}: {props}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Encipher Mask\n",
|
||||
"1. Get the `padded_passcode_position_indices`; padded with random position indices to equal length `max_nkode_len`.\n",
|
||||
@@ -576,26 +597,26 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:58.179247Z",
|
||||
"start_time": "2025-03-27T19:17:58.176595Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"padded_passcode_position_indices = customer.cipher.get_passcode_position_indices_padded(list(passcode_property_indices), customer.nkode_policy.max_nkode_len)\n",
|
||||
"user_position_key = user_cipher.combined_position_key ^ customer.cipher.position_key\n",
|
||||
"ordered_user_position_key = user_position_key[padded_passcode_position_indices]\n",
|
||||
"mask = ordered_user_position_key ^ user_cipher.mask_key\n",
|
||||
"encoded_mask = user_cipher.encode_base64_str(mask)"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 16
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Encipher Passcode\n",
|
||||
"1. Compute `combined_property_key`\n",
|
||||
@@ -606,13 +627,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:58.455536Z",
|
||||
"start_time": "2025-03-27T19:17:58.212205Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"combined_prop_key = customer.cipher.property_key ^ user_cipher.property_key\n",
|
||||
"user_passcode = combined_prop_key[passcode_property_indices]\n",
|
||||
@@ -621,13 +644,11 @@
|
||||
"ciphered_passcode = padded_passcode ^ user_cipher.pass_key\n",
|
||||
"passcode_prehash = base64.b64encode(hashlib.sha256(ciphered_passcode.tobytes()).digest())\n",
|
||||
"passcode_hash = bcrypt.hashpw(passcode_prehash, bcrypt.gensalt(rounds=12)).decode(\"utf-8\")"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 17
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### User Login\n",
|
||||
"1. Get login keypad\n",
|
||||
@@ -635,22 +656,14 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:58.702891Z",
|
||||
"start_time": "2025-03-27T19:17:58.461555Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"login_keypad = api.get_login_keypad(username, customer_id)\n",
|
||||
"keypad_view(login_keypad, keypad_size.props_per_key)\n",
|
||||
"selected_keys_login = select_keys_with_passcode_values(passcode_property_indices, login_keypad, keypad_size.props_per_key)\n",
|
||||
"print(f\"User Passcode: {passcode_property_indices}\\n\")\n",
|
||||
"print(f\"Selected Keys:\\n {selected_keys_login}\\n\")\n",
|
||||
"success = api.login(customer_id, username, selected_keys_login)\n",
|
||||
"assert success"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@@ -669,11 +682,19 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 18
|
||||
"source": [
|
||||
"login_keypad = api.get_login_keypad(username, customer_id)\n",
|
||||
"keypad_view(login_keypad, keypad_size.props_per_key)\n",
|
||||
"selected_keys_login = select_keys_with_passcode_values(passcode_property_indices, login_keypad, keypad_size.props_per_key)\n",
|
||||
"print(f\"User Passcode: {passcode_property_indices}\\n\")\n",
|
||||
"print(f\"Selected Keys:\\n {selected_keys_login}\\n\")\n",
|
||||
"success = api.login(customer_id, username, selected_keys_login)\n",
|
||||
"assert success"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Validate Login Key Entry\n",
|
||||
"- decipher user mask and recover nkode position values\n",
|
||||
@@ -682,8 +703,8 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Decipher Mask\n",
|
||||
"Recover nKode position values:\n",
|
||||
@@ -694,13 +715,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:58.713231Z",
|
||||
"start_time": "2025-03-27T19:17:58.710458Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"login_keypad = api.get_login_keypad(username, customer_id)\n",
|
||||
"selected_keys_login = select_keys_with_passcode_values(passcode_property_indices, login_keypad, keypad_size.props_per_key)\n",
|
||||
@@ -708,13 +731,11 @@
|
||||
"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"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 19
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Get Presumed Properties\n",
|
||||
"- Get the passcode position indices (within the keys)\n",
|
||||
@@ -722,44 +743,46 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:58.729425Z",
|
||||
"start_time": "2025-03-27T19:17:58.727025Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"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": 20
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"source": "### Compare Enciphered Passcodes\n"
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Compare Enciphered Passcodes\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:58.983936Z",
|
||||
"start_time": "2025-03-27T19:17:58.739679Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"valid_nkode = user.cipher.compare_nkode(presumed_property_indices, customer.cipher, user.enciphered_passcode.code)\n",
|
||||
"assert valid_nkode"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 21
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Renew Properties\n",
|
||||
"1. Renew Customer Keys\n",
|
||||
@@ -769,13 +792,28 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:59.477909Z",
|
||||
"start_time": "2025-03-27T19:17:58.990632Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Old User Cipher and Mask\n",
|
||||
"mask: DUY6OIJHwzgG5ajVEGKHARHM6So=, code: $2b$12$/Za40kT7mC0quZxMUWCDs.4cF.3r2meCUBEoz0EWlSKkJAMOPiJTy\n",
|
||||
"\n",
|
||||
"New User Cipher and Mask\n",
|
||||
"mask: GGBaMjr+zlPhS+pmfstihUeFt6A=, code: $2b$12$wE7bq7sYd8Q58j.qKS5ASO2IMzaJ71UW/0vOYAhx7zUhURDJYIaZi\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def print_user_enciphered_code():\n",
|
||||
" mask = api.customers[customer_id].users[username].enciphered_passcode.mask\n",
|
||||
@@ -791,39 +829,26 @@
|
||||
"print(\"New User Cipher and Mask\")\n",
|
||||
"print_user_enciphered_code()\n",
|
||||
"assert success"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Old User Cipher and Mask\n",
|
||||
"mask: DUY6OIJHwzgG5ajVEGKHARHM6So=, code: $2b$12$/Za40kT7mC0quZxMUWCDs.4cF.3r2meCUBEoz0EWlSKkJAMOPiJTy\n",
|
||||
"\n",
|
||||
"New User Cipher and Mask\n",
|
||||
"mask: GGBaMjr+zlPhS+pmfstihUeFt6A=, code: $2b$12$wE7bq7sYd8Q58j.qKS5ASO2IMzaJ71UW/0vOYAhx7zUhURDJYIaZi\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 22
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Renew Customer Keys\n",
|
||||
"The customer cipher keys are replaced."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:59.490134Z",
|
||||
"start_time": "2025-03-27T19:17:59.486082Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"old_props = customer.cipher.property_key.copy()\n",
|
||||
"old_pos = customer.cipher.position_key.copy()\n",
|
||||
@@ -831,13 +856,11 @@
|
||||
"customer.cipher.position_key = np.random.choice(2 ** 16, size=keypad_size.props_per_key, replace=False)\n",
|
||||
"new_props = customer.cipher.property_key\n",
|
||||
"new_pos = customer.cipher.position_key"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 23
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Intermediate Renew User\n",
|
||||
"User property and position keys go through an intermediate phase.\n",
|
||||
@@ -851,13 +874,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:59.500256Z",
|
||||
"start_time": "2025-03-27T19:17:59.497839Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"props_xor = new_props ^ old_props\n",
|
||||
"pos_xor = new_pos ^ old_pos\n",
|
||||
@@ -865,26 +890,26 @@
|
||||
" user.renew = True\n",
|
||||
" user.cipher.combined_position_key = user.cipher.combined_position_key ^ pos_xor\n",
|
||||
" user.cipher.property_key = user.cipher.property_key ^ props_xor"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 24
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### New User Keys\n",
|
||||
"After a user's first successful login, the renew flag is checked. If it's true, the user's cipher is replaced with a new cipher."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-27T19:17:59.752960Z",
|
||||
"start_time": "2025-03-27T19:17:59.508826Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if user.renew:\n",
|
||||
" user.cipher = UserCipher.create(\n",
|
||||
@@ -894,30 +919,28 @@
|
||||
" )\n",
|
||||
" user.enciphered_passcode = user.cipher.encipher_nkode(presumed_property_indices, customer.cipher)\n",
|
||||
" user.renew = False"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 25
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 2
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython2",
|
||||
"version": "2.7.6"
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.14"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user