refactor set_key -> position_key
This commit is contained in:
@@ -53,7 +53,7 @@ if __name__ == "__main__":
|
|||||||
policy = NKodePolicy(
|
policy = NKodePolicy(
|
||||||
max_nkode_len=10,
|
max_nkode_len=10,
|
||||||
min_nkode_len=4,
|
min_nkode_len=4,
|
||||||
distinct_sets=0,
|
distinct_positions=0,
|
||||||
distinct_properties=4,
|
distinct_properties=4,
|
||||||
byte_len=2,
|
byte_len=2,
|
||||||
)
|
)
|
||||||
@@ -92,14 +92,14 @@ if __name__ == "__main__":
|
|||||||
passcode_server_prop = [customer.cipher.property_key[idx] for idx in user_passcode]
|
passcode_server_prop = [customer.cipher.property_key[idx] for idx in user_passcode]
|
||||||
passcode_server_set = customer.cipher.get_props_position_vals(user_passcode)
|
passcode_server_set = customer.cipher.get_props_position_vals(user_passcode)
|
||||||
user_keys = customer.users[username].cipher
|
user_keys = customer.users[username].cipher
|
||||||
|
# TODO: pad_user_mask is deprecated
|
||||||
padded_passcode_server_set = user_keys.pad_user_mask(np.array(passcode_server_set), customer.cipher.position_key)
|
padded_passcode_server_set = user_keys.pad_user_mask(np.array(passcode_server_set), customer.cipher.position_key)
|
||||||
|
|
||||||
set_idx = [customer.cipher.get_position_index(set_val) for set_val in padded_passcode_server_set]
|
set_idx = [customer.cipher.get_position_index(set_val) for set_val in padded_passcode_server_set]
|
||||||
mask_set_keys = [user_keys.combined_set_key[idx] for idx in set_idx]
|
mask_set_keys = [user_keys.combined_position_key[idx] for idx in set_idx]
|
||||||
ciphered_mask = mask_set_keys ^ padded_passcode_server_set ^ user_keys.mask_key
|
ciphered_mask = mask_set_keys ^ padded_passcode_server_set ^ user_keys.mask_key
|
||||||
mask = user_keys.encode_base64_str(ciphered_mask)
|
mask = user_keys.encode_base64_str(ciphered_mask)
|
||||||
ciphered_customer_props = customer.cipher.property_key ^ user_keys.prop_key
|
ciphered_customer_props = customer.cipher.property_key ^ user_keys.property_key
|
||||||
passcode_ciphered_props = [ciphered_customer_props[idx] for idx in user_passcode]
|
passcode_ciphered_props = [ciphered_customer_props[idx] for idx in user_passcode]
|
||||||
pad_len = customer.nkode_policy.max_nkode_len - passcode_len
|
pad_len = customer.nkode_policy.max_nkode_len - passcode_len
|
||||||
passcode_ciphered_props.extend([0 for _ in range(pad_len)])
|
passcode_ciphered_props.extend([0 for _ in range(pad_len)])
|
||||||
@@ -133,7 +133,7 @@ if __name__ == "__main__":
|
|||||||
user_mask = user.enciphered_passcode.mask
|
user_mask = user.enciphered_passcode.mask
|
||||||
decoded_mask = user_keys.decode_base64_str(user_mask)
|
decoded_mask = user_keys.decode_base64_str(user_mask)
|
||||||
deciphered_mask = np.bitwise_xor(decoded_mask, user_keys.mask_key)
|
deciphered_mask = np.bitwise_xor(decoded_mask, user_keys.mask_key)
|
||||||
set_key_rand_component = np.bitwise_xor(set_vals, user_keys.combined_set_key)
|
set_key_rand_component = np.bitwise_xor(set_vals, user_keys.combined_position_key)
|
||||||
login_passcode_sets = []
|
login_passcode_sets = []
|
||||||
for set_cipher in deciphered_mask[:passcode_len]:
|
for set_cipher in deciphered_mask[:passcode_len]:
|
||||||
set_idx = np.where(set_key_rand_component == set_cipher)[0][0]
|
set_idx = np.where(set_key_rand_component == set_cipher)[0][0]
|
||||||
@@ -162,8 +162,8 @@ if __name__ == "__main__":
|
|||||||
sets_xor = np.bitwise_xor(new_sets, old_sets)
|
sets_xor = np.bitwise_xor(new_sets, old_sets)
|
||||||
for user in customer.users.values():
|
for user in customer.users.values():
|
||||||
user.renew = True
|
user.renew = True
|
||||||
user.cipher.combined_set_key = np.bitwise_xor(user.cipher.combined_set_key, sets_xor)
|
user.cipher.combined_position_key = np.bitwise_xor(user.cipher.combined_position_key, sets_xor)
|
||||||
user.cipher.prop_key = np.bitwise_xor(user.cipher.prop_key, props_xor)
|
user.cipher.property_key = np.bitwise_xor(user.cipher.property_key, props_xor)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
REFRESH USER KEYS
|
REFRESH USER KEYS
|
||||||
@@ -184,7 +184,7 @@ if __name__ == "__main__":
|
|||||||
'set_property_dict': set_property_dict,
|
'set_property_dict': set_property_dict,
|
||||||
'set_signup_keypad': signup_keypad,
|
'set_signup_keypad': signup_keypad,
|
||||||
'username': 'test_user',
|
'username': 'test_user',
|
||||||
'user_passcode_indices': user_passcode,
|
'passcode_property_indices': user_passcode,
|
||||||
'selected_keys_set': selected_keys_set,
|
'selected_keys_set': selected_keys_set,
|
||||||
'server_side_prop': server_side_prop,
|
'server_side_prop': server_side_prop,
|
||||||
'confirm_keypad': confirm_keypad,
|
'confirm_keypad': confirm_keypad,
|
||||||
|
|||||||
@@ -30,12 +30,12 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:48.405476Z",
|
"end_time": "2025-03-20T08:32:08.092320Z",
|
||||||
"start_time": "2025-03-19T14:18:48.400091Z"
|
"start_time": "2025-03-20T08:32:08.087658Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 195
|
"execution_count": 27
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -53,12 +53,12 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:48.416324Z",
|
"end_time": "2025-03-20T08:32:08.113043Z",
|
||||||
"start_time": "2025-03-19T14:18:48.413345Z"
|
"start_time": "2025-03-20T08:32:08.110624Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 196
|
"execution_count": 28
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -77,8 +77,8 @@
|
|||||||
"Each customer has unique cipher keys.\n",
|
"Each customer has unique cipher keys.\n",
|
||||||
"These keys are used to encipher and decipher user nKode.\n",
|
"These keys are used to encipher and decipher user nKode.\n",
|
||||||
"There are two types of Customer Cipher Keys:\n",
|
"There are two types of Customer Cipher Keys:\n",
|
||||||
"1. property key: Combined with the user property key to get the server-side representation of a users icons. Each property belongs to a set.\n",
|
"1. property key: Combined with the user property key to get the server-side representation of a users icons.\n",
|
||||||
"2. set key: Combined with the user set Key to the the server-side representation the position in each key.\n"
|
"2. position key: Combined with the user position key to the server-side representation the position in each key.\n"
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
"policy = NKodePolicy(\n",
|
"policy = NKodePolicy(\n",
|
||||||
" max_nkode_len=10,\n",
|
" max_nkode_len=10,\n",
|
||||||
" min_nkode_len=4,\n",
|
" min_nkode_len=4,\n",
|
||||||
" distinct_sets=0,\n",
|
" distinct_positions=0,\n",
|
||||||
" distinct_properties=4,\n",
|
" distinct_properties=4,\n",
|
||||||
")\n",
|
")\n",
|
||||||
"keypad_size = KeypadSize(\n",
|
"keypad_size = KeypadSize(\n",
|
||||||
@@ -99,21 +99,21 @@
|
|||||||
")\n",
|
")\n",
|
||||||
"customer_id = api.create_new_customer(keypad_size, policy)\n",
|
"customer_id = api.create_new_customer(keypad_size, policy)\n",
|
||||||
"customer = api.customers[customer_id]\n",
|
"customer = api.customers[customer_id]\n",
|
||||||
"print(f\"Customer Set Key: {customer.cipher.position_key}\")\n",
|
"print(f\"Customer Position Key: {customer.cipher.position_key}\")\n",
|
||||||
"print(f\"Customer Properties Key:\")\n",
|
"print(f\"Customer Properties Key:\")\n",
|
||||||
"customer_prop_keypad = customer.cipher.property_key.reshape(-1, keypad_size.props_per_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",
|
"for idx, key_vals in enumerate(customer_prop_keypad):\n",
|
||||||
" print(f\"{key_vals}\")\n",
|
" print(f\"{key_vals}\")\n",
|
||||||
"set_properties_dict = dict(zip(customer.cipher.position_key, customer_prop_keypad.T))\n",
|
"position_properties_dict = dict(zip(customer.cipher.position_key, customer_prop_keypad.T))\n",
|
||||||
"print(f\"Set to Properties Map:\")\n",
|
"print(f\"Position to Properties Map:\")\n",
|
||||||
"for set_val, props in set_properties_dict.items():\n",
|
"for pos_val, props in position_properties_dict.items():\n",
|
||||||
" print(f\"{set_val}: {props}\")"
|
" print(f\"{pos_val}: {props}\")"
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:48.432441Z",
|
"end_time": "2025-03-20T08:32:08.198233Z",
|
||||||
"start_time": "2025-03-19T14:18:48.426289Z"
|
"start_time": "2025-03-20T08:32:08.193182Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -121,56 +121,56 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Customer Set Key: [52236 1143 22391 5610 24876 51604]\n",
|
"Customer Position Key: [21284 3999 4057 48308 14680 46323]\n",
|
||||||
"Customer Properties Key:\n",
|
"Customer Properties Key:\n",
|
||||||
"[48274 26421 59355 34554 61533 13623]\n",
|
"[45633 21215 48438 45863 52540 14191]\n",
|
||||||
"[22492 47901 17487 10515 61939 8923]\n",
|
"[11907 4042 56372 63103 45179 58318]\n",
|
||||||
"[32708 61921 973 1449 52341 29868]\n",
|
"[28909 48497 31171 15125 2886 9246]\n",
|
||||||
"[10212 24136 41690 31747 29169 19891]\n",
|
"[15651 10936 5595 16546 8096 13333]\n",
|
||||||
"[18093 29532 18702 45116 15485 53514]\n",
|
"[41923 43364 15227 43001 11056 62605]\n",
|
||||||
"Set to Properties Map:\n",
|
"Position to Properties Map:\n",
|
||||||
"52236: [48274 22492 32708 10212 18093]\n",
|
"21284: [45633 11907 28909 15651 41923]\n",
|
||||||
"1143: [26421 47901 61921 24136 29532]\n",
|
"3999: [21215 4042 48497 10936 43364]\n",
|
||||||
"22391: [59355 17487 973 41690 18702]\n",
|
"4057: [48438 56372 31171 5595 15227]\n",
|
||||||
"5610: [34554 10515 1449 31747 45116]\n",
|
"48308: [45863 63103 15125 16546 43001]\n",
|
||||||
"24876: [61533 61939 52341 29169 15485]\n",
|
"14680: [52540 45179 2886 8096 11056]\n",
|
||||||
"51604: [13623 8923 29868 19891 53514]\n"
|
"46323: [14191 58318 9246 13333 62605]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 197
|
"execution_count": 29
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:48.443885Z",
|
"end_time": "2025-03-20T08:32:08.226660Z",
|
||||||
"start_time": "2025-03-19T14:18:48.441137Z"
|
"start_time": "2025-03-20T08:32:08.224216Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"user_icon_keypad = user_icons.reshape(-1, keypad_size.props_per_key)\n",
|
"user_icon_keypad = user_icons.reshape(-1, keypad_size.props_per_key)\n",
|
||||||
"set_icons_dict = dict(zip(customer.cipher.position_key, user_icon_keypad.T))\n",
|
"pos_icons_dict = dict(zip(customer.cipher.position_key, user_icon_keypad.T))\n",
|
||||||
"print(\"Set to Icons Map:\")\n",
|
"print(\"Position Value to Icons Map:\")\n",
|
||||||
"for set_val, icons in set_icons_dict.items():\n",
|
"for pos_val, icons in pos_icons_dict.items():\n",
|
||||||
" print(f\"{set_val}: {icons}\")\n"
|
" print(f\"{pos_val}: {icons}\")\n"
|
||||||
],
|
],
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Set to Icons Map:\n",
|
"Position Value to Icons Map:\n",
|
||||||
"52236: ['😀' '🥺' '🤔' '🐱' '🦄']\n",
|
"21284: ['😀' '🥺' '🤔' '🐱' '🦄']\n",
|
||||||
"1143: ['😂' '😡' '🙃' '🐶' '🌟']\n",
|
"3999: ['😂' '😡' '🙃' '🐶' '🌟']\n",
|
||||||
"22391: ['🥳' '😱' '😇' '🦁' '⚡']\n",
|
"4057: ['🥳' '😱' '😇' '🦁' '⚡']\n",
|
||||||
"5610: ['😍' '🤯' '🤖' '🐻' '🔥']\n",
|
"48308: ['😍' '🤯' '🤖' '🐻' '🔥']\n",
|
||||||
"24876: ['🤓' '🥰' '👽' '🐸' '🍕']\n",
|
"14680: ['🤓' '🥰' '👽' '🐸' '🍕']\n",
|
||||||
"51604: ['😎' '😴' '👾' '🐙' '🎉']\n"
|
"46323: ['😎' '😴' '👾' '🐙' '🎉']\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 198
|
"execution_count": 30
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -184,8 +184,8 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"#### Generate Keypad\n",
|
"#### Generate Keypad\n",
|
||||||
" For the server to determine the users nkode, the user's keypad must be dispersable.\n",
|
" For the server to determine the users nkode, the user's keypad must be dispersable.\n",
|
||||||
" To make the keypad dispersable, the server will randomly drop properties sets to the number of properties is equal to the number of keys.\n",
|
" To make the keypad dispersable, the server will randomly drop key positions so the number of properties per key is equal to the number of keys.\n",
|
||||||
" In our case, the server drops 1 properties set to give us a 5 X 5 keypad with possible index values ranging from 0-29.\n",
|
" In our case, the server drops 1 key position 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",
|
" - 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 keypad is the index value of a customer properties\n",
|
" - each value in the keypad is the index value of a customer properties\n",
|
||||||
" - the user never learns what their server-side properties"
|
" - the user never learns what their server-side properties"
|
||||||
@@ -194,8 +194,8 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:21:05.988739Z",
|
"end_time": "2025-03-20T08:32:08.256237Z",
|
||||||
"start_time": "2025-03-19T14:21:05.981809Z"
|
"start_time": "2025-03-20T08:32:08.250147Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -223,11 +223,11 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Key 0: ['🙃' '🥳' '🔥' '🐸' '👾']\n",
|
"Key 0: ['🦄' '😂' '😇' '👽' '😴']\n",
|
||||||
"Key 1: ['😡' '😱' '🤯' '🥰' '😴']\n",
|
"Key 1: ['🐱' '🌟' '😱' '🐸' '😎']\n",
|
||||||
"Key 2: ['🌟' '🦁' '🐻' '🍕' '😎']\n",
|
"Key 2: ['🤔' '🙃' '🦁' '🥰' '🐙']\n",
|
||||||
"Key 3: ['🐶' '⚡' '🤖' '👽' '🎉']\n",
|
"Key 3: ['😀' '😡' '⚡' '🍕' '👾']\n",
|
||||||
"Key 4: ['😂' '😇' '😍' '🤓' '🐙']\n"
|
"Key 4: ['🥺' '🐶' '🥳' '🤓' '🎉']\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -244,11 +244,11 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Key 0: [13 2 27 22 17]\n",
|
"Key 0: [24 1 14 16 11]\n",
|
||||||
"Key 1: [ 7 8 9 10 11]\n",
|
"Key 1: [18 25 8 22 5]\n",
|
||||||
"Key 2: [25 20 21 28 5]\n",
|
"Key 2: [12 13 20 10 23]\n",
|
||||||
"Key 3: [19 26 15 16 29]\n",
|
"Key 3: [ 0 7 26 28 17]\n",
|
||||||
"Key 4: [ 1 14 3 4 23]\n"
|
"Key 4: [ 6 19 2 4 29]\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -265,15 +265,15 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Key 0: [32049 6729 60466 26997 1309]\n",
|
"Key 0: [41923 21215 31171 2886 58318]\n",
|
||||||
"Key 1: [61686 12369 40030 7765 16822]\n",
|
"Key 1: [15651 43364 56372 8096 14191]\n",
|
||||||
"Key 2: [29442 13543 37604 7572 18665]\n",
|
"Key 2: [28909 48497 5595 45179 13333]\n",
|
||||||
"Key 3: [29124 1259 53208 47841 51215]\n",
|
"Key 3: [45633 4042 15227 11056 9246]\n",
|
||||||
"Key 4: [48741 14803 46096 27958 19258]\n"
|
"Key 4: [11907 10936 48438 52540 62605]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 229
|
"execution_count": 31
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -286,19 +286,19 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:22:48.143268Z",
|
"end_time": "2025-03-20T08:32:08.280568Z",
|
||||||
"start_time": "2025-03-19T14:22:48.140039Z"
|
"start_time": "2025-03-20T08:32:08.277339Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"username = random_username()\n",
|
"username = random_username()\n",
|
||||||
"passcode_len = 4\n",
|
"passcode_len = 4\n",
|
||||||
"user_passcode_indices = np.random.choice(set_signup_keypad.reshape(-1), size=passcode_len, replace=False).tolist()\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(user_passcode_indices, set_signup_keypad, keypad_size.numb_of_keys)\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: {user_passcode_indices}\")\n",
|
"print(f\"User Passcode Indices: {passcode_property_indices}\")\n",
|
||||||
"print(f\"User Passcode Icons: {user_icons[user_passcode_indices]}\")\n",
|
"print(f\"User Passcode Icons: {user_icons[passcode_property_indices]}\")\n",
|
||||||
"print(f\"User Passcode Server-side properties: {customer.cipher.property_key[user_passcode_indices]}\")\n",
|
"print(f\"User Passcode Server-side properties: {customer.cipher.property_key[passcode_property_indices]}\")\n",
|
||||||
"print(f\"Selected Keys: {selected_keys_set}\")"
|
"print(f\"Selected Keys: {selected_keys_set}\")"
|
||||||
],
|
],
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -306,27 +306,27 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"User Passcode Indices: [11, 22, 1, 23]\n",
|
"User Passcode Indices: [19, 7, 10, 6]\n",
|
||||||
"User Passcode Icons: ['😴' '🐸' '😂' '🐙']\n",
|
"User Passcode Icons: ['🐶' '😡' '🥰' '🥺']\n",
|
||||||
"User Passcode Server-side properties: [16822 26997 48741 19258]\n",
|
"User Passcode Server-side properties: [10936 4042 45179 11907]\n",
|
||||||
"Selected Keys: [1, 0, 4, 4]\n"
|
"Selected Keys: [4, 3, 2, 4]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 237
|
"execution_count": 32
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:48.697364Z",
|
"end_time": "2025-03-20T08:32:08.316148Z",
|
||||||
"start_time": "2025-03-19T14:18:48.694055Z"
|
"start_time": "2025-03-20T08:32:08.313495Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"confirm_keypad = api.set_nkode(username, customer_id, selected_keys_set, signup_session_id)\n",
|
"confirm_keypad = api.set_nkode(username, customer_id, selected_keys_set, signup_session_id)\n",
|
||||||
"keypad_view(confirm_keypad, keypad_size.numb_of_keys)\n",
|
"keypad_view(confirm_keypad, keypad_size.numb_of_keys)\n",
|
||||||
"selected_keys_confirm = select_keys_with_passcode_values(user_passcode_indices, 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}\")"
|
"print(f\"Selected Keys\\n{selected_keys_confirm}\")"
|
||||||
],
|
],
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -334,23 +334,23 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Key 0: [13 14 9 10 23]\n",
|
"Key 0: [18 7 20 4 11]\n",
|
||||||
"Key 1: [25 20 21 4 17]\n",
|
"Key 1: [12 1 26 22 29]\n",
|
||||||
"Key 2: [ 1 8 15 22 5]\n",
|
"Key 2: [ 0 19 14 10 5]\n",
|
||||||
"Key 3: [19 26 27 28 11]\n",
|
"Key 3: [24 25 2 28 23]\n",
|
||||||
"Key 4: [ 7 2 3 16 29]\n",
|
"Key 4: [ 6 13 8 16 17]\n",
|
||||||
"Selected Keys\n",
|
"Selected Keys\n",
|
||||||
"[2, 2, 3, 0]\n"
|
"[2, 0, 2, 4]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 202
|
"execution_count": 33
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:49.028822Z",
|
"end_time": "2025-03-20T08:32:08.575664Z",
|
||||||
"start_time": "2025-03-19T14:18:48.719642Z"
|
"start_time": "2025-03-20T08:32:08.337518Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -360,7 +360,7 @@
|
|||||||
"assert success"
|
"assert success"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 203
|
"execution_count": 34
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -369,9 +369,9 @@
|
|||||||
"## User Cipher\n",
|
"## User Cipher\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Users have 4 cipher keys:\n",
|
"Users have 4 cipher keys:\n",
|
||||||
"1. prop_key: Half of the user's server-side passcode. the counterpart to the `customer_prop_key`. A user's passcode is made from elements in `user_prop_key XOR customer_prop_key`. Each property belongs to a set.\n",
|
"1. property_key: The counterpart to the `customer_prop_key`. A user's server-side passcode is composed of elements in `user_prop_key XOR customer_prop_key`.\n",
|
||||||
"2. pass_key: The passcode key is used to encipher user passcode\n",
|
"2. pass_key: The passcode key is used to encipher user passcode\n",
|
||||||
"3. combined_set_key: The combined set key is `user_set_key XOR customer_set_key`. The user_set_key isn't stored and can't be recovered with the `customer_set_key`\n",
|
"3. combined_position_key: The combined position key is `user_pos_key XOR customer_pos_key`.\n",
|
||||||
"4. mask_key: The mask key used to encipher user nKode\n",
|
"4. mask_key: The mask key used to encipher user nKode\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n"
|
"\n"
|
||||||
@@ -380,24 +380,24 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:49.044808Z",
|
"end_time": "2025-03-20T08:32:08.588049Z",
|
||||||
"start_time": "2025-03-19T14:18:49.038903Z"
|
"start_time": "2025-03-20T08:32:08.583087Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"from src.user_cipher import UserCipher\n",
|
"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_cipher = UserCipher.create(keypad_size, customer.cipher.position_key, customer.nkode_policy.max_nkode_len)\n",
|
||||||
"user_prop_key_keypad = user_cipher.prop_key.reshape(-1, keypad_size.props_per_key)"
|
"user_prop_key_keypad = user_cipher.property_key.reshape(-1, keypad_size.props_per_key)"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 204
|
"execution_count": 35
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:49.056184Z",
|
"end_time": "2025-03-20T08:32:08.596984Z",
|
||||||
"start_time": "2025-03-19T14:18:49.053919Z"
|
"start_time": "2025-03-20T08:32:08.595221Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -408,21 +408,21 @@
|
|||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Property Key:\n",
|
"Property Key:\n",
|
||||||
"[[42472 31697 42349 63196 42777 61068]\n",
|
"[[43643 58945 45655 10493 17462 5635]\n",
|
||||||
" [ 7243 387 55065 19589 60418 22963]\n",
|
" [42071 15680 60860 39600 15784 4102]\n",
|
||||||
" [26541 59081 11622 22333 35608 42306]\n",
|
" [60857 21300 14877 25869 12858 50934]\n",
|
||||||
" [58621 57412 35828 19293 16394 53334]\n",
|
" [55451 44486 22660 41758 36853 37697]\n",
|
||||||
" [ 5908 43761 45282 44085 8881 21753]]\n"
|
" [24236 53340 57175 52425 5167 2017]]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 205
|
"execution_count": 36
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:49.080744Z",
|
"end_time": "2025-03-20T08:32:08.615012Z",
|
||||||
"start_time": "2025-03-19T14:18:49.078469Z"
|
"start_time": "2025-03-20T08:32:08.613119Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -432,17 +432,17 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Passcode Key: [15958 16933 12810 19682 61534 54403 52645 54893 63261 22611]\n"
|
"Passcode Key: [31049 4633 40678 55986 14115 22499 3470 53359 20871 60539]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 206
|
"execution_count": 37
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:49.125439Z",
|
"end_time": "2025-03-20T08:32:08.639696Z",
|
||||||
"start_time": "2025-03-19T14:18:49.123Z"
|
"start_time": "2025-03-20T08:32:08.637469Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -452,119 +452,112 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Mask Key: [11511 36348 3693 57612 7883 59516 54039 57361 15218 43846]\n"
|
"Mask Key: [55361 38182 36656 63013 26815 17961 23911 65497 28524 60226]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 207
|
"execution_count": 38
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:49.154768Z",
|
"end_time": "2025-03-20T08:32:08.658960Z",
|
||||||
"start_time": "2025-03-19T14:18:49.152444Z"
|
"start_time": "2025-03-20T08:32:08.657009Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": "print(f\"Combined Set Key: {user_cipher.combined_set_key}\")",
|
"source": "print(f\"Combined Position Key: {user_cipher.combined_position_key}\")",
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Combined Set Key: [16302 28740 39642 59999 35588 576]\n"
|
"Combined Position Key: [33934 3750 42586 25190 7504 35546]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 208
|
"execution_count": 39
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:49.188943Z",
|
"end_time": "2025-03-20T08:32:08.678360Z",
|
||||||
"start_time": "2025-03-19T14:18:49.186648Z"
|
"start_time": "2025-03-20T08:32:08.676228Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": "print(f\"User Set Key = combined_set_key XOR customer_set_key: {user_cipher.combined_set_key ^ customer.cipher.position_key}\")",
|
"source": "print(f\"User Position Key = combined_pos_key XOR customer_pos_key: {user_cipher.combined_position_key ^ customer.cipher.position_key}\")",
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"User Set Key = combined_set_key XOR customer_set_key: [62370 29747 52653 65461 59944 52180]\n"
|
"User Position Key = combined_pos_key XOR customer_pos_key: [55210 313 43395 57042 9224 15913]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 209
|
"execution_count": 40
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:49.217942Z",
|
"end_time": "2025-03-20T08:32:08.698976Z",
|
||||||
"start_time": "2025-03-19T14:18:49.215165Z"
|
"start_time": "2025-03-20T08:32:08.696420Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"set_properties_dict = dict(zip(user_cipher.combined_set_key, user_prop_key_keypad.T))\n",
|
"position_properties_dict = dict(zip(user_cipher.combined_position_key, user_prop_key_keypad.T))\n",
|
||||||
"print(f\"Combined Set to Properties Map:\")\n",
|
"print(f\"Combined Position to Properties Map:\")\n",
|
||||||
"for set_val, props in set_properties_dict.items():\n",
|
"for pos_val, props in position_properties_dict.items():\n",
|
||||||
" print(f\"{set_val}: {props}\")"
|
" print(f\"{pos_val}: {props}\")"
|
||||||
],
|
],
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Combined Set to Properties Map:\n",
|
"Combined Position to Properties Map:\n",
|
||||||
"16302: [42472 7243 26541 58621 5908]\n",
|
"33934: [43643 42071 60857 55451 24236]\n",
|
||||||
"28740: [31697 387 59081 57412 43761]\n",
|
"3750: [58945 15680 21300 44486 53340]\n",
|
||||||
"39642: [42349 55065 11622 35828 45282]\n",
|
"42586: [45655 60860 14877 22660 57175]\n",
|
||||||
"59999: [63196 19589 22333 19293 44085]\n",
|
"25190: [10493 39600 25869 41758 52425]\n",
|
||||||
"35588: [42777 60418 35608 16394 8881]\n",
|
"7504: [17462 15784 12858 36853 5167]\n",
|
||||||
"576: [61068 22963 42306 53334 21753]\n"
|
"35546: [ 5635 4102 50934 37697 2017]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 210
|
"execution_count": 41
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"source": [
|
"source": [
|
||||||
"#### Encipher Mask\n",
|
"#### Encipher Mask\n",
|
||||||
"1. Order customer properties by user passcode.\n",
|
"1. Get the `padded_passcode_position_indices`; padded with random position indices to equal length `max_nkode_len`.\n",
|
||||||
"2. Get the set indices (`set_indices`) of the ordered customer properties.\n",
|
"2. Recover the `user_position_key`. Recall `user.cipher.combined_position_key = user_position_key XOR customer.cipher.positon_key`\n",
|
||||||
"3. Pad the\n",
|
"3. Order the `user_position_key` by the `padded_passcode_position_indices`\n",
|
||||||
"1. combined_set_key = user_set_key ^ customer_set_key\n",
|
"4. Mask the `ordered_user_position_key`\n",
|
||||||
"2. padded_ordered_customer_set = customer_set_key # ordered by user passcode and padded with extra set key values to be equal to max_nkode_len\n",
|
"5. Base 64 encode the mask"
|
||||||
"3. len(set_key) == len(mask_key) == len(padded_ordered_customer_set) == max_nkode_len == 10\n",
|
|
||||||
"where i is the index\n",
|
|
||||||
" \n",
|
|
||||||
"- mask = mask_key ^ padded_ordered_customer_set ^ ordered_combined_set_key\n",
|
|
||||||
"- mask = mask_key ^ (customer_set_key) ^ set_rand_numb ^ set_val\n",
|
|
||||||
"- mask = mask_rand_num ^ set_rand_numb # set_val is cancelled out"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:49.244375Z",
|
"end_time": "2025-03-20T08:32:08.762578Z",
|
||||||
"start_time": "2025-03-19T14:18:49.241861Z"
|
"start_time": "2025-03-20T08:32:08.760236Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"set_indices = customer.cipher.get_passcode_position_indices_padded(list(user_passcode_indices), customer.nkode_policy.max_nkode_len)\n",
|
"padded_passcode_position_indices = customer.cipher.get_passcode_position_indices_padded(list(passcode_property_indices), customer.nkode_policy.max_nkode_len)\n",
|
||||||
"ordered_combined_set_key = user_cipher.combined_set_key[set_indices]\n",
|
"user_position_key = user_cipher.combined_position_key ^ customer.cipher.position_key\n",
|
||||||
"ordered_customer_set_key = customer.cipher.position_key[set_indices]\n",
|
"ordered_user_position_key = user_position_key[padded_passcode_position_indices]\n",
|
||||||
"ordered_user_set_key = ordered_customer_set_key ^ ordered_combined_set_key\n",
|
"mask = ordered_user_position_key ^ user_cipher.mask_key\n",
|
||||||
"mask = ordered_user_set_key ^ user_cipher.mask_key\n",
|
|
||||||
"encoded_mask = user_cipher.encode_base64_str(mask)"
|
"encoded_mask = user_cipher.encode_base64_str(mask)"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 211
|
"execution_count": 42
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -581,14 +574,14 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:49.575573Z",
|
"end_time": "2025-03-20T08:32:09.024060Z",
|
||||||
"start_time": "2025-03-19T14:18:49.268784Z"
|
"start_time": "2025-03-20T08:32:08.789902Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"combined_prop_key = customer.cipher.property_key ^ user_cipher.prop_key\n",
|
"combined_prop_key = customer.cipher.property_key ^ user_cipher.property_key\n",
|
||||||
"user_passcode = combined_prop_key[user_passcode_indices]\n",
|
"user_passcode = combined_prop_key[passcode_property_indices]\n",
|
||||||
"pad_len = customer.nkode_policy.max_nkode_len - passcode_len\n",
|
"pad_len = customer.nkode_policy.max_nkode_len - passcode_len\n",
|
||||||
"user_passcode_padded = np.concatenate((user_passcode, np.zeros(pad_len, dtype=user_passcode.dtype)))\n",
|
"user_passcode_padded = np.concatenate((user_passcode, np.zeros(pad_len, dtype=user_passcode.dtype)))\n",
|
||||||
"ciphered_passcode = user_passcode_padded ^ user_cipher.pass_key\n",
|
"ciphered_passcode = user_passcode_padded ^ user_cipher.pass_key\n",
|
||||||
@@ -596,7 +589,7 @@
|
|||||||
"passcode_hash = bcrypt.hashpw(passcode_prehash, bcrypt.gensalt(rounds=12)).decode(\"utf-8\")"
|
"passcode_hash = bcrypt.hashpw(passcode_prehash, bcrypt.gensalt(rounds=12)).decode(\"utf-8\")"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 212
|
"execution_count": 43
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -617,8 +610,8 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:49.585161Z",
|
"end_time": "2025-03-20T08:32:09.032955Z",
|
||||||
"start_time": "2025-03-19T14:18:49.583132Z"
|
"start_time": "2025-03-20T08:32:09.030937Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -631,7 +624,7 @@
|
|||||||
")"
|
")"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 213
|
"execution_count": 44
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -645,16 +638,16 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:49.901534Z",
|
"end_time": "2025-03-20T08:32:09.273099Z",
|
||||||
"start_time": "2025-03-19T14:18:49.594710Z"
|
"start_time": "2025-03-20T08:32:09.040255Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"login_keypad = api.get_login_keypad(username, customer_id)\n",
|
"login_keypad = api.get_login_keypad(username, customer_id)\n",
|
||||||
"keypad_view(login_keypad, keypad_size.props_per_key)\n",
|
"keypad_view(login_keypad, keypad_size.props_per_key)\n",
|
||||||
"selected_keys_login = select_keys_with_passcode_values(user_passcode_indices, 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: {user_passcode_indices}\\n\")\n",
|
"print(f\"User Passcode: {passcode_property_indices}\\n\")\n",
|
||||||
"print(f\"Selected Keys:\\n {selected_keys_login}\\n\")\n",
|
"print(f\"Selected Keys:\\n {selected_keys_login}\\n\")\n",
|
||||||
"success = api.login(customer_id, username, selected_keys_login)\n",
|
"success = api.login(customer_id, username, selected_keys_login)\n",
|
||||||
"assert success"
|
"assert success"
|
||||||
@@ -664,20 +657,20 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Key 0: [ 6 19 8 3 4 23]\n",
|
"Key 0: [24 1 14 27 16 11]\n",
|
||||||
"Key 1: [18 13 2 21 28 5]\n",
|
"Key 1: [18 25 8 3 22 5]\n",
|
||||||
"Key 2: [12 25 14 15 16 11]\n",
|
"Key 2: [12 13 20 21 10 23]\n",
|
||||||
"Key 3: [24 7 26 9 22 17]\n",
|
"Key 3: [ 0 7 26 9 28 17]\n",
|
||||||
"Key 4: [ 0 1 20 27 10 29]\n",
|
"Key 4: [ 6 19 2 15 4 29]\n",
|
||||||
"User Passcode: [15, 1, 19, 23]\n",
|
"User Passcode: [19, 7, 10, 6]\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Selected Keys:\n",
|
"Selected Keys:\n",
|
||||||
" [2, 4, 0, 0]\n",
|
" [4, 3, 2, 4]\n",
|
||||||
"\n"
|
"\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 214
|
"execution_count": 45
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -708,24 +701,24 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:49.914512Z",
|
"end_time": "2025-03-20T08:32:09.282728Z",
|
||||||
"start_time": "2025-03-19T14:18:49.911338Z"
|
"start_time": "2025-03-20T08:32:09.279895Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"login_keypad = api.get_login_keypad(username, customer_id)\n",
|
"login_keypad = api.get_login_keypad(username, customer_id)\n",
|
||||||
"selected_keys_login = select_keys_with_passcode_values(user_passcode_indices, 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",
|
||||||
"user = api.customers[customer_id].users[username]\n",
|
"user = api.customers[customer_id].users[username]\n",
|
||||||
"mask = user.cipher.decode_base64_str(user.enciphered_passcode.mask)\n",
|
"mask = user.cipher.decode_base64_str(user.enciphered_passcode.mask)\n",
|
||||||
"deciphered_mask = mask ^ user.cipher.mask_key\n",
|
"deciphered_mask = mask ^ user.cipher.mask_key\n",
|
||||||
"set_key = customer.cipher.position_key ^ user.cipher.combined_set_key\n",
|
"set_key = customer.cipher.position_key ^ user.cipher.combined_position_key\n",
|
||||||
"passcode_set_index = [int(np.where(set_key == set_cipher)[0][0]) for set_cipher in deciphered_mask[:passcode_len]]\n",
|
"passcode_set_index = [int(np.where(set_key == set_cipher)[0][0]) for set_cipher in deciphered_mask[:passcode_len]]\n",
|
||||||
"presumed_selected_properties_idx = customer.users[username].user_keypad.get_prop_idxs_by_keynumb_setidx(selected_keys_login, passcode_set_index)\n",
|
"presumed_selected_properties_idx = customer.users[username].user_keypad.get_prop_idxs_by_keynumb_setidx(selected_keys_login, passcode_set_index)\n",
|
||||||
"assert user_passcode_indices == presumed_selected_properties_idx\n"
|
"assert passcode_property_indices == presumed_selected_properties_idx\n"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 215
|
"execution_count": 46
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -735,8 +728,8 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:50.236818Z",
|
"end_time": "2025-03-20T08:32:09.526068Z",
|
||||||
"start_time": "2025-03-19T14:18:49.932427Z"
|
"start_time": "2025-03-20T08:32:09.295445Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -745,7 +738,7 @@
|
|||||||
"assert valid_nkode\n"
|
"assert valid_nkode\n"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 216
|
"execution_count": 47
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -761,8 +754,8 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:50.851576Z",
|
"end_time": "2025-03-20T08:32:09.996256Z",
|
||||||
"start_time": "2025-03-19T14:18:50.240709Z"
|
"start_time": "2025-03-20T08:32:09.529950Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -777,7 +770,7 @@
|
|||||||
"print_user_enciphered_code()\n",
|
"print_user_enciphered_code()\n",
|
||||||
"\n",
|
"\n",
|
||||||
"login_keypad = api.get_login_keypad(username, customer_id)\n",
|
"login_keypad = api.get_login_keypad(username, customer_id)\n",
|
||||||
"selected_keys_login = select_keys_with_passcode_values(user_passcode_indices, 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",
|
||||||
"success = api.login(customer_id, username, selected_keys_login)\n",
|
"success = api.login(customer_id, username, selected_keys_login)\n",
|
||||||
"assert success\n",
|
"assert success\n",
|
||||||
"print_user_enciphered_code()"
|
"print_user_enciphered_code()"
|
||||||
@@ -787,16 +780,16 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"mask: tBqaWnmsGlsclLRq7qdFeuZ/Krg=, code: $2b$12$iBdtB4bRMx9VnWKwAInkwecUx5wwiL1C0DVWO.sk9EG1syVVe2CaS\n",
|
"mask: cz9m1OunYlEK42X0jRrGAzKvheg=, code: $2b$12$Z.N7qwUTMgSVJFQC9hKgjeQ8owBpZMm5Aa14RQdiJH7C8l61QJENS\n",
|
||||||
"\n",
|
"\n",
|
||||||
"mask: tBqaWnmsGlsclLRq7qdFeuZ/Krg=, code: $2b$12$iBdtB4bRMx9VnWKwAInkwecUx5wwiL1C0DVWO.sk9EG1syVVe2CaS\n",
|
"mask: cz9m1OunYlEK42X0jRrGAzKvheg=, code: $2b$12$Z.N7qwUTMgSVJFQC9hKgjeQ8owBpZMm5Aa14RQdiJH7C8l61QJENS\n",
|
||||||
"\n",
|
"\n",
|
||||||
"mask: DpuEwDyPrOF4pAxxozyqUHigaak=, code: $2b$12$ngd6PgpZo/UhIANnrRimlOliRIGwAaS6zbe5gqTzYHPBaeAa3vJsy\n",
|
"mask: e+RtDYeB1G1RfuTOjCna6K9xLUU=, code: $2b$12$DHdD52jbBdVoXYArhWCm7eABlnch.tNhO/1Eipygj8fpoUFuPzyEC\n",
|
||||||
"\n"
|
"\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 217
|
"execution_count": 48
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -810,8 +803,8 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:50.865243Z",
|
"end_time": "2025-03-20T08:32:10.012897Z",
|
||||||
"start_time": "2025-03-19T14:18:50.861260Z"
|
"start_time": "2025-03-20T08:32:10.009292Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -823,7 +816,7 @@
|
|||||||
"new_sets = customer.cipher.position_key"
|
"new_sets = customer.cipher.position_key"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 218
|
"execution_count": 49
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -836,8 +829,8 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:50.876670Z",
|
"end_time": "2025-03-20T08:32:10.019285Z",
|
||||||
"start_time": "2025-03-19T14:18:50.874092Z"
|
"start_time": "2025-03-20T08:32:10.017224Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -846,11 +839,11 @@
|
|||||||
"sets_xor = np.bitwise_xor(new_sets, old_sets)\n",
|
"sets_xor = np.bitwise_xor(new_sets, old_sets)\n",
|
||||||
"for user in customer.users.values():\n",
|
"for user in customer.users.values():\n",
|
||||||
" user.renew = True\n",
|
" user.renew = True\n",
|
||||||
" user.cipher.combined_set_key = np.bitwise_xor(user.cipher.combined_set_key, sets_xor)\n",
|
" user.cipher.combined_position_key = np.bitwise_xor(user.cipher.combined_position_key, sets_xor)\n",
|
||||||
" user.cipher.prop_key = np.bitwise_xor(user.cipher.prop_key, props_xor)"
|
" user.cipher.property_key = np.bitwise_xor(user.cipher.property_key, props_xor)"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 219
|
"execution_count": 50
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -860,8 +853,8 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-19T14:18:51.191895Z",
|
"end_time": "2025-03-20T08:32:10.260051Z",
|
||||||
"start_time": "2025-03-19T14:18:50.885862Z"
|
"start_time": "2025-03-20T08:32:10.026503Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -875,7 +868,7 @@
|
|||||||
"user.renew = False"
|
"user.renew = False"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 220
|
"execution_count": 51
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class Customer:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, nkode_policy: NKodePolicy, cipher: CustomerCipher) -> 'Customer':
|
def create(cls, nkode_policy: NKodePolicy, cipher: CustomerCipher) -> 'Customer':
|
||||||
if nkode_policy.distinct_sets > cipher.keypad_size.numb_of_keys:
|
if nkode_policy.distinct_positions > cipher.keypad_size.numb_of_keys:
|
||||||
raise ValueError("Distinct sets cannot be greater than the number of keys")
|
raise ValueError("Distinct sets cannot be greater than the number of keys")
|
||||||
if nkode_policy.distinct_properties > cipher.keypad_size.total_props:
|
if nkode_policy.distinct_properties > cipher.keypad_size.total_props:
|
||||||
raise ValueError("Distinct properties cannot be greater than the total number of properties")
|
raise ValueError("Distinct properties cannot be greater than the total number of properties")
|
||||||
@@ -76,7 +76,7 @@ class Customer:
|
|||||||
distinct_properties = len(set(passcode_prop_idx))
|
distinct_properties = len(set(passcode_prop_idx))
|
||||||
if (
|
if (
|
||||||
self.nkode_policy.min_nkode_len <= nkode_len <= self.nkode_policy.max_nkode_len and
|
self.nkode_policy.min_nkode_len <= nkode_len <= self.nkode_policy.max_nkode_len and
|
||||||
distinct_sets >= self.nkode_policy.distinct_sets and
|
distinct_sets >= self.nkode_policy.distinct_positions and
|
||||||
distinct_properties >= self.nkode_policy.distinct_properties
|
distinct_properties >= self.nkode_policy.distinct_properties
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class EncipheredNKode:
|
|||||||
class NKodePolicy:
|
class NKodePolicy:
|
||||||
max_nkode_len: int = 10
|
max_nkode_len: int = 10
|
||||||
min_nkode_len: int = 4
|
min_nkode_len: int = 4
|
||||||
distinct_sets: int = 0
|
distinct_positions: int = 0
|
||||||
distinct_properties: int = 4
|
distinct_properties: int = 4
|
||||||
byte_len: int = 2 # Todo: this should change the total number of bytes an properties or set value can be
|
byte_len: int = 2 # Todo: this should change the total number of bytes an properties or set value can be
|
||||||
lock_out: int = 5
|
lock_out: int = 5
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ class User:
|
|||||||
|
|
||||||
def renew_keys(self, set_xor: np.ndarray, prop_xor: np.ndarray):
|
def renew_keys(self, set_xor: np.ndarray, prop_xor: np.ndarray):
|
||||||
self.renew = True
|
self.renew = True
|
||||||
self.cipher.combined_set_key = self.cipher.combined_set_key ^ set_xor
|
self.cipher.combined_position_key = self.cipher.combined_position_key ^ set_xor
|
||||||
self.cipher.prop_key = self.cipher.prop_key ^ prop_xor
|
self.cipher.property_key = self.cipher.property_key ^ prop_xor
|
||||||
|
|
||||||
def refresh_passcode(self, passcode_prop_idxs: list[int], customer_cipher: CustomerCipher):
|
def refresh_passcode(self, passcode_prop_idxs: list[int], customer_cipher: CustomerCipher):
|
||||||
self.cipher = UserCipher.create(
|
self.cipher = UserCipher.create(
|
||||||
|
|||||||
@@ -9,30 +9,31 @@ from src.customer_cipher import CustomerCipher
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class UserCipher:
|
class UserCipher:
|
||||||
prop_key: np.ndarray
|
property_key: np.ndarray
|
||||||
combined_set_key: np.ndarray
|
combined_position_key: np.ndarray
|
||||||
pass_key: np.ndarray
|
pass_key: np.ndarray
|
||||||
mask_key: np.ndarray
|
mask_key: np.ndarray
|
||||||
max_nkode_len: int
|
max_nkode_len: int
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, keypad_size: KeypadSize, customer_set_key: np.ndarray, max_nkode_len: int) -> 'UserCipher':
|
def create(cls, keypad_size: KeypadSize, customer_pos_key: np.ndarray, max_nkode_len: int) -> 'UserCipher':
|
||||||
if len(customer_set_key) != keypad_size.props_per_key:
|
if len(customer_pos_key) != keypad_size.props_per_key:
|
||||||
raise ValueError("Invalid set values")
|
raise ValueError("Invalid position values")
|
||||||
user_set_key = np.random.choice(2**16,size=keypad_size.props_per_key, replace=False)
|
user_pos_key = np.random.choice(2**16,size=keypad_size.props_per_key, replace=False)
|
||||||
return UserCipher(
|
return UserCipher(
|
||||||
prop_key=np.random.choice(2 ** 16, size=keypad_size.total_props, replace=False),
|
property_key=np.random.choice(2 ** 16, size=keypad_size.total_props, replace=False),
|
||||||
pass_key=np.random.choice(2 ** 16, size=max_nkode_len, replace=False),
|
pass_key=np.random.choice(2 ** 16, size=max_nkode_len, replace=False),
|
||||||
mask_key=np.random.choice(2**16, size=max_nkode_len, replace=False),
|
mask_key=np.random.choice(2**16, size=max_nkode_len, replace=False),
|
||||||
combined_set_key=user_set_key ^ customer_set_key,
|
combined_position_key=user_pos_key ^ customer_pos_key,
|
||||||
max_nkode_len=max_nkode_len
|
max_nkode_len=max_nkode_len
|
||||||
)
|
)
|
||||||
|
|
||||||
def pad_user_mask(self, user_mask: np.ndarray, set_vals: np.ndarray) -> np.ndarray:
|
def pad_user_mask(self, user_mask: np.ndarray, pos_vals: np.ndarray) -> np.ndarray:
|
||||||
|
# TODO: replace with new method
|
||||||
if len(user_mask) >= self.max_nkode_len:
|
if len(user_mask) >= self.max_nkode_len:
|
||||||
raise ValueError("User encoded_mask is too long")
|
raise ValueError("User encoded_mask is too long")
|
||||||
padding_size = self.max_nkode_len - len(user_mask)
|
padding_size = self.max_nkode_len - len(user_mask)
|
||||||
padding = np.random.choice(set_vals, size=padding_size, replace=True).astype(np.uint16)
|
padding = np.random.choice(pos_vals, size=padding_size, replace=True).astype(np.uint16)
|
||||||
return np.concatenate([user_mask, padding])
|
return np.concatenate([user_mask, padding])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -90,7 +91,7 @@ class UserCipher:
|
|||||||
passcode_cipher = self.pass_key.copy()
|
passcode_cipher = self.pass_key.copy()
|
||||||
passcode_cipher[:passcode_len] = (
|
passcode_cipher[:passcode_len] = (
|
||||||
passcode_cipher[:passcode_len] ^
|
passcode_cipher[:passcode_len] ^
|
||||||
self.prop_key[passcode_prop_idx] ^
|
self.property_key[passcode_prop_idx] ^
|
||||||
customer_prop.property_key[passcode_prop_idx]
|
customer_prop.property_key[passcode_prop_idx]
|
||||||
)
|
)
|
||||||
return passcode_cipher.astype(np.uint16).tobytes()
|
return passcode_cipher.astype(np.uint16).tobytes()
|
||||||
@@ -100,21 +101,21 @@ class UserCipher:
|
|||||||
passcode_prop_idx: list[int],
|
passcode_prop_idx: list[int],
|
||||||
customer_cipher: CustomerCipher
|
customer_cipher: CustomerCipher
|
||||||
) -> str:
|
) -> str:
|
||||||
set_idxs = customer_cipher.get_passcode_position_indices_padded(passcode_prop_idx, len(self.mask_key))
|
pos_idxs = customer_cipher.get_passcode_position_indices_padded(passcode_prop_idx, len(self.mask_key))
|
||||||
ordered_set_key = self.combined_set_key[set_idxs]
|
ordered_pos_key = self.combined_position_key[pos_idxs]
|
||||||
ordered_customer_key = customer_cipher.position_key[set_idxs]
|
ordered_customer_pos_key = customer_cipher.position_key[pos_idxs]
|
||||||
mask = ordered_set_key ^ ordered_customer_key ^ self.mask_key
|
mask = ordered_pos_key ^ ordered_customer_pos_key ^ self.mask_key
|
||||||
encoded_mask = self.encode_base64_str(mask)
|
encoded_mask = self.encode_base64_str(mask)
|
||||||
return encoded_mask
|
return encoded_mask
|
||||||
|
|
||||||
def decipher_mask(self, encoded_mask: str, customer_set_key: np.ndarray, passcode_len: int) -> list[int]:
|
def decipher_mask(self, encoded_mask: str, customer_pos_key: np.ndarray, passcode_len: int) -> list[int]:
|
||||||
mask = self.decode_base64_str(encoded_mask)
|
mask = self.decode_base64_str(encoded_mask)
|
||||||
# user_set_key ordered by the user's nkode and padded to be length max_nkode_len
|
# user_pos_key ordered by the user's nkode and padded to be length max_nkode_len
|
||||||
ordered_set_key = mask ^ self.mask_key
|
ordered_user_pos_key = mask ^ self.mask_key
|
||||||
user_set_key = customer_set_key ^ self.combined_set_key
|
user_pos_key = customer_pos_key ^ self.combined_position_key
|
||||||
passcode_sets = []
|
passcode_position = []
|
||||||
for partial_set in ordered_set_key[:passcode_len]:
|
for position_val in ordered_user_pos_key[:passcode_len]:
|
||||||
set_idx = np.where(user_set_key == partial_set)[0][0]
|
position_idx = np.where(user_pos_key == position_val)[0][0]
|
||||||
passcode_sets.append(int(customer_set_key[set_idx]))
|
passcode_position.append(int(customer_pos_key[position_idx]))
|
||||||
return passcode_sets
|
return passcode_position
|
||||||
|
|
||||||
|
|||||||
@@ -83,16 +83,16 @@ class UserKeypad:
|
|||||||
if not (0 <= key_numb < self.keypad_size.numb_of_keys):
|
if not (0 <= key_numb < self.keypad_size.numb_of_keys):
|
||||||
raise ValueError(f"key_numb must be between 0 and {self.keypad_size.numb_of_keys - 1}")
|
raise ValueError(f"key_numb must be between 0 and {self.keypad_size.numb_of_keys - 1}")
|
||||||
if not (0 <= set_idx < self.keypad_size.props_per_key):
|
if not (0 <= set_idx < self.keypad_size.props_per_key):
|
||||||
raise ValueError(f"set_indices must be between 0 and {self.keypad_size.props_per_key - 1}")
|
raise ValueError(f"padded_passcode_position_indices must be between 0 and {self.keypad_size.props_per_key - 1}")
|
||||||
keypad_prop_idx = self.keypad_matrix()
|
keypad_prop_idx = self.keypad_matrix()
|
||||||
return int(keypad_prop_idx[key_numb][set_idx])
|
return int(keypad_prop_idx[key_numb][set_idx])
|
||||||
|
|
||||||
def get_prop_idxs_by_keynumb_setidx(self, key_numb: list[int], set_idx: list[int]) -> list[int]:
|
def get_prop_idxs_by_keynumb_setidx(self, key_numb: list[int], set_idx: list[int]) -> list[int]:
|
||||||
if len(key_numb) != len(set_idx):
|
if len(key_numb) != len(set_idx):
|
||||||
raise ValueError("key_numb and set_indices must be the same length")
|
raise ValueError("key_numb and padded_passcode_position_indices must be the same length")
|
||||||
if not all(0 <= kn < self.keypad_size.numb_of_keys for kn in key_numb):
|
if not all(0 <= kn < self.keypad_size.numb_of_keys for kn in key_numb):
|
||||||
raise ValueError(f"All key_numb must be between 0 and {self.keypad_size.numb_of_keys - 1}")
|
raise ValueError(f"All key_numb must be between 0 and {self.keypad_size.numb_of_keys - 1}")
|
||||||
if not all(0 <= si < self.keypad_size.props_per_key for si in set_idx):
|
if not all(0 <= si < self.keypad_size.props_per_key for si in set_idx):
|
||||||
raise ValueError(f"All set_indices must be between 0 and {self.keypad_size.props_per_key - 1}")
|
raise ValueError(f"All padded_passcode_position_indices must be between 0 and {self.keypad_size.props_per_key - 1}")
|
||||||
keypad_matrix = self.keypad_matrix()
|
keypad_matrix = self.keypad_matrix()
|
||||||
return keypad_matrix[key_numb, set_idx].reshape(-1).tolist()
|
return keypad_matrix[key_numb, set_idx].reshape(-1).tolist()
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ def test_decode_mask(keypad_size, max_nkode_len):
|
|||||||
customer = CustomerCipher.create(keypad_size)
|
customer = CustomerCipher.create(keypad_size)
|
||||||
passcode_entry = np.random.choice(keypad_size.total_props, 4, replace=False)
|
passcode_entry = np.random.choice(keypad_size.total_props, 4, replace=False)
|
||||||
passcode_values = [customer.property_key[idx] for idx in passcode_entry]
|
passcode_values = [customer.property_key[idx] for idx in passcode_entry]
|
||||||
set_vals = customer.position_key
|
customer_pos_vals = customer.position_key
|
||||||
user_keys = UserCipher.create(keypad_size, set_vals, max_nkode_len)
|
user_keys = UserCipher.create(keypad_size, customer_pos_vals, max_nkode_len)
|
||||||
passcode = user_keys.encipher_nkode(passcode_entry, customer)
|
passcode = user_keys.encipher_nkode(passcode_entry, customer)
|
||||||
orig_passcode_set_vals = customer.get_props_position_vals(passcode_values)
|
orig_passcode_pos_vals = customer.get_props_position_vals(passcode_values)
|
||||||
passcode_set_vals = user_keys.decipher_mask(passcode.mask, set_vals, len(passcode_entry))
|
passcode_pos_vals = user_keys.decipher_mask(passcode.mask, customer_pos_vals, len(passcode_entry))
|
||||||
assert (len(passcode_set_vals) == len(orig_passcode_set_vals))
|
assert (len(passcode_pos_vals) == len(orig_passcode_pos_vals))
|
||||||
assert (all(orig_passcode_set_vals[idx] == passcode_set_vals[idx] for idx in range(len(passcode_set_vals))))
|
assert (all(orig_passcode_pos_vals[idx] == passcode_pos_vals[idx] for idx in range(len(passcode_pos_vals))))
|
||||||
|
|||||||
Reference in New Issue
Block a user