refactor use numpy in user_cipher.py
This commit is contained in:
@@ -63,8 +63,8 @@ if __name__ == "__main__":
|
|||||||
customer_id = api.create_new_customer(keypad_size, policy)
|
customer_id = api.create_new_customer(keypad_size, policy)
|
||||||
customer = api.customers[customer_id]
|
customer = api.customers[customer_id]
|
||||||
|
|
||||||
set_vals = customer.customer_cipher.set_key
|
set_vals = customer.cipher.set_key
|
||||||
attr_vals = customer.customer_cipher.prop_key
|
attr_vals = customer.cipher.prop_key
|
||||||
customer_attr_view = list_to_matrix(attr_vals, keypad_size.props_per_key)
|
customer_attr_view = list_to_matrix(attr_vals, keypad_size.props_per_key)
|
||||||
|
|
||||||
attr_keypad_view = list_to_matrix(attr_vals, keypad_size.props_per_key)
|
attr_keypad_view = list_to_matrix(attr_vals, keypad_size.props_per_key)
|
||||||
@@ -78,7 +78,7 @@ if __name__ == "__main__":
|
|||||||
passcode_len = 4
|
passcode_len = 4
|
||||||
user_passcode = signup_interface[:passcode_len]
|
user_passcode = signup_interface[:passcode_len]
|
||||||
selected_keys_set = select_keys_with_passcode_values(user_passcode, signup_interface, keypad_size.numb_of_keys)
|
selected_keys_set = select_keys_with_passcode_values(user_passcode, signup_interface, keypad_size.numb_of_keys)
|
||||||
server_side_attr = [customer.customer_cipher.prop_key[idx] for idx in user_passcode]
|
server_side_attr = [customer.cipher.prop_key[idx] for idx in user_passcode]
|
||||||
|
|
||||||
confirm_interface = api.set_nkode(username, customer_id, selected_keys_set, session_id)
|
confirm_interface = api.set_nkode(username, customer_id, selected_keys_set, session_id)
|
||||||
|
|
||||||
@@ -88,20 +88,20 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
success = api.confirm_nkode(username, customer_id, selected_keys_confirm, session_id)
|
success = api.confirm_nkode(username, customer_id, selected_keys_confirm, session_id)
|
||||||
assert success
|
assert success
|
||||||
passcode_server_attr = [customer.customer_cipher.prop_key[idx] for idx in user_passcode]
|
passcode_server_attr = [customer.cipher.prop_key[idx] for idx in user_passcode]
|
||||||
passcode_server_set = [customer.customer_cipher.get_prop_set_val(attr) for attr in passcode_server_attr]
|
passcode_server_set = [customer.cipher.get_prop_set_val(attr) for attr in passcode_server_attr]
|
||||||
|
|
||||||
user_keys = customer.users[username].user_keys
|
user_keys = customer.users[username].cipher
|
||||||
|
|
||||||
padded_passcode_server_set = user_keys.pad_user_mask(passcode_server_set, customer.customer_cipher.set_key)
|
padded_passcode_server_set = user_keys.pad_user_mask(passcode_server_set, customer.cipher.set_key)
|
||||||
|
|
||||||
set_idx = [customer.customer_cipher.get_set_index(set_val) for set_val in padded_passcode_server_set]
|
set_idx = [customer.cipher.get_set_index(set_val) for set_val in padded_passcode_server_set]
|
||||||
mask_set_keys = [user_keys.set_key[idx] for idx in set_idx]
|
mask_set_keys = [user_keys.set_key[idx] for idx in set_idx]
|
||||||
ciphered_mask = xor_lists(mask_set_keys, padded_passcode_server_set)
|
ciphered_mask = xor_lists(mask_set_keys, padded_passcode_server_set)
|
||||||
ciphered_mask = xor_lists(ciphered_mask, user_keys.mask_key)
|
ciphered_mask = xor_lists(ciphered_mask, user_keys.mask_key)
|
||||||
mask = user_keys.encode_base64_str(ciphered_mask)
|
mask = user_keys.encode_base64_str(ciphered_mask)
|
||||||
|
|
||||||
ciphered_customer_attrs = xor_lists(customer.customer_cipher.prop_key, user_keys.prop_key)
|
ciphered_customer_attrs = xor_lists(customer.cipher.prop_key, user_keys.prop_key)
|
||||||
passcode_ciphered_attrs = [ciphered_customer_attrs[idx] for idx in user_passcode]
|
passcode_ciphered_attrs = [ciphered_customer_attrs[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
|
||||||
|
|
||||||
@@ -133,8 +133,8 @@ if __name__ == "__main__":
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
user = customer.users[username]
|
user = customer.users[username]
|
||||||
set_vals = customer.customer_cipher.set_key
|
set_vals = customer.cipher.set_key
|
||||||
user_keys = user.user_keys
|
user_keys = user.cipher
|
||||||
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 = xor_lists(decoded_mask, user_keys.mask_key)
|
deciphered_mask = xor_lists(decoded_mask, user_keys.mask_key)
|
||||||
@@ -148,7 +148,7 @@ if __name__ == "__main__":
|
|||||||
GET PRESUMED ATTRIBUTES
|
GET PRESUMED ATTRIBUTES
|
||||||
"""
|
"""
|
||||||
|
|
||||||
set_vals_idx = [customer.customer_cipher.get_set_index(set_val) for set_val in login_passcode_sets]
|
set_vals_idx = [customer.cipher.get_set_index(set_val) for set_val in login_passcode_sets]
|
||||||
|
|
||||||
presumed_selected_attributes_idx = []
|
presumed_selected_attributes_idx = []
|
||||||
for idx in range(passcode_len):
|
for idx in range(passcode_len):
|
||||||
@@ -161,11 +161,11 @@ if __name__ == "__main__":
|
|||||||
RENEW KEYS
|
RENEW KEYS
|
||||||
"""
|
"""
|
||||||
|
|
||||||
old_attrs = customer.customer_cipher.prop_key.copy()
|
old_attrs = customer.cipher.prop_key.copy()
|
||||||
old_sets = customer.customer_cipher.set_key.copy()
|
old_sets = customer.cipher.set_key.copy()
|
||||||
customer.customer_cipher.renew()
|
customer.cipher.renew()
|
||||||
new_attrs = customer.customer_cipher.prop_key
|
new_attrs = customer.cipher.prop_key
|
||||||
new_sets = customer.customer_cipher.set_key
|
new_sets = customer.cipher.set_key
|
||||||
customer_new_attr_view = list_to_matrix(new_attrs, keypad_size.props_per_key)
|
customer_new_attr_view = list_to_matrix(new_attrs, keypad_size.props_per_key)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -175,18 +175,18 @@ if __name__ == "__main__":
|
|||||||
sets_xor = xor_lists(new_sets, old_sets)
|
sets_xor = xor_lists(new_sets, old_sets)
|
||||||
for user in customer.users.values():
|
for user in customer.users.values():
|
||||||
user.renew = True
|
user.renew = True
|
||||||
user.user_keys.set_key = xor_lists(user.user_keys.set_key, sets_xor)
|
user.cipher.set_key = xor_lists(user.cipher.set_key, sets_xor)
|
||||||
user.user_keys.prop_key = xor_lists(user.user_keys.prop_key, attrs_xor)
|
user.cipher.prop_key = xor_lists(user.cipher.prop_key, attrs_xor)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
REFRESH USER KEYS
|
REFRESH USER KEYS
|
||||||
"""
|
"""
|
||||||
user.user_keys = UserCipher.create(
|
user.cipher = UserCipher.create(
|
||||||
customer.customer_cipher.keypad_size,
|
customer.cipher.keypad_size,
|
||||||
customer.customer_cipher.set_key,
|
customer.cipher.set_key,
|
||||||
user.user_keys.max_nkode_len
|
user.cipher.max_nkode_len
|
||||||
)
|
)
|
||||||
user.enciphered_passcode = user.user_keys.encipher_nkode(presumed_selected_attributes_idx, customer.customer_cipher)
|
user.enciphered_passcode = user.cipher.encipher_nkode(presumed_selected_attributes_idx, customer.cipher)
|
||||||
user.renew = False
|
user.renew = False
|
||||||
|
|
||||||
# Define some data to pass to the template
|
# Define some data to pass to the template
|
||||||
@@ -202,7 +202,7 @@ if __name__ == "__main__":
|
|||||||
'server_side_attr': server_side_attr,
|
'server_side_attr': server_side_attr,
|
||||||
'confirm_keypad': confirm_keypad,
|
'confirm_keypad': confirm_keypad,
|
||||||
'selected_keys_confirm': selected_keys_confirm,
|
'selected_keys_confirm': selected_keys_confirm,
|
||||||
'user_keys': user_keys,
|
'cipher': user_keys,
|
||||||
'passcode_server_attr': passcode_server_attr,
|
'passcode_server_attr': passcode_server_attr,
|
||||||
'passcode_server_set': passcode_server_set,
|
'passcode_server_set': passcode_server_set,
|
||||||
'enciphered_nkode': enciphered_nkode,
|
'enciphered_nkode': enciphered_nkode,
|
||||||
|
|||||||
@@ -12,12 +12,12 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:08.154404Z",
|
"end_time": "2025-03-10T15:54:01.727846Z",
|
||||||
"start_time": "2025-03-07T19:01:08.149432Z"
|
"start_time": "2025-03-10T15:54:01.637744Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 58
|
"execution_count": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -38,12 +38,12 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:08.165511Z",
|
"end_time": "2025-03-10T15:54:01.735895Z",
|
||||||
"start_time": "2025-03-07T19:01:08.162339Z"
|
"start_time": "2025-03-10T15:54:01.733121Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 59
|
"execution_count": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@@ -53,12 +53,12 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:08.174320Z",
|
"end_time": "2025-03-10T15:54:01.746332Z",
|
||||||
"start_time": "2025-03-07T19:01:08.172724Z"
|
"start_time": "2025-03-10T15:54:01.744308Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 60
|
"execution_count": 4
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
")\n",
|
")\n",
|
||||||
"keypad_size = KeypadSize(\n",
|
"keypad_size = KeypadSize(\n",
|
||||||
" numb_of_keys = 5,\n",
|
" numb_of_keys = 5,\n",
|
||||||
" attrs_per_key = 6 # aka number of sets\n",
|
" props_per_key = 6 # aka number of sets\n",
|
||||||
")\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]"
|
"customer = api.customers[customer_id]"
|
||||||
@@ -98,12 +98,12 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:08.378578Z",
|
"end_time": "2025-03-10T15:54:02.001142Z",
|
||||||
"start_time": "2025-03-07T19:01:08.188114Z"
|
"start_time": "2025-03-10T15:54:01.752948Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 61
|
"execution_count": 5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
@@ -129,19 +129,19 @@
|
|||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"set_vals = customer.attributes.set_vals\n",
|
"set_vals = customer.cipher.set_key\n",
|
||||||
"attr_vals = customer.attributes.attr_vals\n",
|
"attr_vals = customer.cipher.prop_key\n",
|
||||||
"print(f\"Customer Sets: {set_vals}\")\n",
|
"print(f\"Customer Sets: {set_vals}\")\n",
|
||||||
"print(f\"Customer Attributes:\")\n",
|
"print(f\"Customer Attributes:\")\n",
|
||||||
"interface_keypad = list_to_matrix(attr_vals, keypad_size.attrs_per_key)\n",
|
"interface_keypad = list_to_matrix(attr_vals, keypad_size.props_per_key)\n",
|
||||||
"for idx, key_vals in enumerate(interface_keypad):\n",
|
"for idx, key_vals in enumerate(interface_keypad):\n",
|
||||||
" print(f\"{key_vals}\")"
|
" print(f\"{key_vals}\")"
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:08.387613Z",
|
"end_time": "2025-03-10T15:54:02.011259Z",
|
||||||
"start_time": "2025-03-07T19:01:08.385501Z"
|
"start_time": "2025-03-10T15:54:02.008541Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -149,17 +149,17 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Customer Sets: [14533, 13441, 52408, 39610, 49828, 11300]\n",
|
"Customer Sets: [5584, 23615, 13665, 42236, 20931, 35557]\n",
|
||||||
"Customer Attributes:\n",
|
"Customer Attributes:\n",
|
||||||
"[50415, 3350, 62907, 34493, 46982, 55292]\n",
|
"[51116, 4647, 54248, 42959, 35151, 56238]\n",
|
||||||
"[23503, 57678, 17001, 8963, 4893, 53685]\n",
|
"[37806, 51776, 33630, 63761, 13028, 29812]\n",
|
||||||
"[25912, 9324, 2770, 57761, 57056, 5837]\n",
|
"[41783, 30499, 23526, 21846, 1217, 40587]\n",
|
||||||
"[49831, 16518, 53473, 35853, 12433, 20763]\n",
|
"[20418, 53142, 62008, 29738, 64343, 49564]\n",
|
||||||
"[60930, 19614, 2083, 2879, 58781, 13705]\n"
|
"[4306, 19073, 56680, 38208, 21317, 14264]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 62
|
"execution_count": 6
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
@@ -173,7 +173,7 @@
|
|||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"attr_keypad_view = list_to_matrix(attr_vals, keypad_size.attrs_per_key)\n",
|
"attr_keypad_view = list_to_matrix(attr_vals, keypad_size.props_per_key)\n",
|
||||||
"attr_set_view = matrix_transpose(attr_keypad_view)\n",
|
"attr_set_view = matrix_transpose(attr_keypad_view)\n",
|
||||||
"set_attribute_dict = dict(zip(set_vals, attr_set_view))\n",
|
"set_attribute_dict = dict(zip(set_vals, attr_set_view))\n",
|
||||||
"print(f\"Set to Attribute Map:\")\n",
|
"print(f\"Set to Attribute Map:\")\n",
|
||||||
@@ -183,8 +183,8 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:08.412394Z",
|
"end_time": "2025-03-10T15:54:16.867336Z",
|
||||||
"start_time": "2025-03-07T19:01:08.410114Z"
|
"start_time": "2025-03-10T15:54:16.864589Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -193,16 +193,16 @@
|
|||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Set to Attribute Map:\n",
|
"Set to Attribute Map:\n",
|
||||||
"14533: [50415, 23503, 25912, 49831, 60930]\n",
|
"5584: [51116, 37806, 41783, 20418, 4306]\n",
|
||||||
"13441: [3350, 57678, 9324, 16518, 19614]\n",
|
"23615: [4647, 51776, 30499, 53142, 19073]\n",
|
||||||
"52408: [62907, 17001, 2770, 53473, 2083]\n",
|
"13665: [54248, 33630, 23526, 62008, 56680]\n",
|
||||||
"39610: [34493, 8963, 57761, 35853, 2879]\n",
|
"42236: [42959, 63761, 21846, 29738, 38208]\n",
|
||||||
"49828: [46982, 4893, 57056, 12433, 58781]\n",
|
"20931: [35151, 13028, 1217, 64343, 21317]\n",
|
||||||
"11300: [55292, 53685, 5837, 20763, 13705]\n"
|
"35557: [56238, 29812, 40587, 49564, 14264]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 63
|
"execution_count": 8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
@@ -232,27 +232,24 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:08.439639Z",
|
"end_time": "2025-03-10T15:54:20.741427Z",
|
||||||
"start_time": "2025-03-07T19:01:08.436629Z"
|
"start_time": "2025-03-10T15:54:20.731719Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"data": {
|
"ename": "AttributeError",
|
||||||
"text/plain": [
|
"evalue": "'NKodeAPI' object has no attribute 'generate_signup_interface'",
|
||||||
"[[3, 20, 10, 6, 29],\n",
|
"output_type": "error",
|
||||||
" [27, 26, 4, 24, 11],\n",
|
"traceback": [
|
||||||
" [15, 2, 22, 0, 5],\n",
|
"\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
|
||||||
" [9, 8, 16, 12, 23],\n",
|
"\u001B[0;31mAttributeError\u001B[0m Traceback (most recent call last)",
|
||||||
" [21, 14, 28, 18, 17]]"
|
"Cell \u001B[0;32mIn[9], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m session_id, signup_interface \u001B[38;5;241m=\u001B[39m \u001B[43mapi\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mgenerate_signup_interface\u001B[49m(customer_id)\n\u001B[1;32m 2\u001B[0m list_to_matrix(signup_interface, keypad_size\u001B[38;5;241m.\u001B[39mnumb_of_keys)\n",
|
||||||
|
"\u001B[0;31mAttributeError\u001B[0m: 'NKodeAPI' object has no attribute 'generate_signup_interface'"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"execution_count": 64,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 64
|
"execution_count": 9
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
@@ -280,7 +277,7 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:08.474579Z",
|
"end_time": "2025-03-10T15:54:02.091787Z",
|
||||||
"start_time": "2025-03-07T19:01:08.471813Z"
|
"start_time": "2025-03-07T19:01:08.471813Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -320,7 +317,7 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:08.496620Z",
|
"end_time": "2025-03-10T15:54:02.111894Z",
|
||||||
"start_time": "2025-03-07T19:01:08.494090Z"
|
"start_time": "2025-03-07T19:01:08.494090Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -352,7 +349,7 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:09.173784Z",
|
"end_time": "2025-03-10T15:54:02.115281Z",
|
||||||
"start_time": "2025-03-07T19:01:08.522178Z"
|
"start_time": "2025-03-07T19:01:08.522178Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -384,30 +381,31 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:09.193871Z",
|
"end_time": "2025-03-10T15:54:02.129677Z",
|
||||||
"start_time": "2025-03-07T19:01:09.190856Z"
|
"start_time": "2025-03-10T15:41:40.490919Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"from src.user_cipher_keys import UserCipherKeys\n",
|
"from src.user_cipher import UserCipher\n",
|
||||||
"from src.utils import xor_lists\n",
|
"from src.utils import xor_lists\n",
|
||||||
|
"import numpy as np\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"set_key = [46785, 4782, 4405, 44408, 35377, 55527]\n",
|
"set_key = [46785, 4782, 4405, 44408, 35377, 55527]\n",
|
||||||
"set_key = xor_lists(set_key, customer.attributes.set_vals)\n",
|
"set_key = xor_lists(set_key, customer.attributes.set_vals)\n",
|
||||||
"user_keys = UserCipherKeys(\n",
|
"user_keys = UserCipher(\n",
|
||||||
" alpha_key = [\n",
|
" prop_key = np.array([\n",
|
||||||
" 57200, 8398, 54694, 25997, 30388,\n",
|
" 57200, 8398, 54694, 25997, 30388,\n",
|
||||||
" 46948, 45549, 30364, 49712, 10447,\n",
|
" 46948, 45549, 30364, 49712, 10447,\n",
|
||||||
" 9205, 1777, 10731, 30979, 2795,\n",
|
" 9205, 1777, 10731, 30979, 2795,\n",
|
||||||
" 17068, 56758, 62574, 28641, 11451,\n",
|
" 17068, 56758, 62574, 28641, 11451,\n",
|
||||||
" 26820, 50373, 48783, 25350, 62177,\n",
|
" 26820, 50373, 48783, 25350, 62177,\n",
|
||||||
" 60608, 54242, 4637, 3525, 16313\n",
|
" 60608, 54242, 4637, 3525, 16313\n",
|
||||||
" ],\n",
|
" ]),\n",
|
||||||
" pass_key=[16090, 38488, 45111, 32674, 46216, 52013, 48980, 36811, 35296, 17206],\n",
|
" pass_key=np.array([16090, 38488, 45111, 32674, 46216, 52013, 48980, 36811, 35296, 17206]),\n",
|
||||||
" mask_key=[29575, 43518, 44373, 62063, 37651, 31671, 31663, 65514, 36454, 47325],\n",
|
" mask_key=np.array([29575, 43518, 44373, 62063, 37651, 31671, 31663, 65514, 36454, 47325]),\n",
|
||||||
" set_key=set_key,\n",
|
" set_key=np.array(set_key),\n",
|
||||||
" salt=b'$2b$12$fX.in.GGAjz3QBBwqSWc6e',\n",
|
" salt=b'$2b$12$fX.in.GGAjz3QBBwqSWc6e',\n",
|
||||||
" max_nkode_len=customer.nkode_policy.max_nkode_len, \n",
|
" max_nkode_len=customer.nkode_policy.max_nkode_len, \n",
|
||||||
")\n",
|
")\n",
|
||||||
@@ -419,15 +417,18 @@
|
|||||||
],
|
],
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"ename": "NameError",
|
||||||
"output_type": "stream",
|
"evalue": "name 'customer' is not defined",
|
||||||
"text": [
|
"output_type": "error",
|
||||||
"Passcode Set Vals: [39610, 52408, 49828, 14533]\n",
|
"traceback": [
|
||||||
"Passcode Attr Vals: [34493, 53473, 4893, 23503]\n"
|
"\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
|
||||||
|
"\u001B[0;31mNameError\u001B[0m Traceback (most recent call last)",
|
||||||
|
"Cell \u001B[0;32mIn[5], line 6\u001B[0m\n\u001B[1;32m 2\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01msrc\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mutils\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m xor_lists\n\u001B[1;32m 5\u001B[0m set_key \u001B[38;5;241m=\u001B[39m [\u001B[38;5;241m46785\u001B[39m, \u001B[38;5;241m4782\u001B[39m, \u001B[38;5;241m4405\u001B[39m, \u001B[38;5;241m44408\u001B[39m, \u001B[38;5;241m35377\u001B[39m, \u001B[38;5;241m55527\u001B[39m]\n\u001B[0;32m----> 6\u001B[0m set_key \u001B[38;5;241m=\u001B[39m xor_lists(set_key, \u001B[43mcustomer\u001B[49m\u001B[38;5;241m.\u001B[39mattributes\u001B[38;5;241m.\u001B[39mset_vals)\n\u001B[1;32m 7\u001B[0m user_keys \u001B[38;5;241m=\u001B[39m UserCipher(\n\u001B[1;32m 8\u001B[0m prop_key \u001B[38;5;241m=\u001B[39m [\n\u001B[1;32m 9\u001B[0m \u001B[38;5;241m57200\u001B[39m, \u001B[38;5;241m8398\u001B[39m, \u001B[38;5;241m54694\u001B[39m, \u001B[38;5;241m25997\u001B[39m, \u001B[38;5;241m30388\u001B[39m,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 20\u001B[0m max_nkode_len\u001B[38;5;241m=\u001B[39mcustomer\u001B[38;5;241m.\u001B[39mnkode_policy\u001B[38;5;241m.\u001B[39mmax_nkode_len, \n\u001B[1;32m 21\u001B[0m )\n\u001B[1;32m 23\u001B[0m passcode_server_attr \u001B[38;5;241m=\u001B[39m [customer\u001B[38;5;241m.\u001B[39mattributes\u001B[38;5;241m.\u001B[39mattr_vals[idx] \u001B[38;5;28;01mfor\u001B[39;00m idx \u001B[38;5;129;01min\u001B[39;00m user_passcode]\n",
|
||||||
|
"\u001B[0;31mNameError\u001B[0m: name 'customer' is not defined"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 68
|
"execution_count": 5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -449,24 +450,36 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:09.223843Z",
|
"end_time": "2025-03-10T15:54:02.130699Z",
|
||||||
"start_time": "2025-03-07T19:01:09.221595Z"
|
"start_time": "2025-03-10T15:45:03.947109Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"from src.utils import xor_lists\n",
|
"from src.utils import xor_lists\n",
|
||||||
"\n",
|
"\n",
|
||||||
"padded_passcode_server_set = user_keys.pad_user_mask(passcode_server_set, customer.attributes.set_vals)\n",
|
"padded_passcode_server_set = user_keys.pad_user_mask(passcode_server_set, customer.properites.set_vals)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"set_idx = [customer.attributes.get_set_index(set_val) for set_val in padded_passcode_server_set]\n",
|
"set_idx = [customer.properites.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",
|
"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(mask_set_keys, padded_passcode_server_set)\n",
|
||||||
"ciphered_mask = xor_lists(ciphered_mask, user_keys.mask_key)\n",
|
"ciphered_mask = xor_lists(ciphered_mask, user_keys.mask_key)\n",
|
||||||
"mask = user_keys.encode_base64_str(ciphered_mask)"
|
"mask = user_keys.encode_base64_str(ciphered_mask)"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
"execution_count": 69
|
{
|
||||||
|
"ename": "NameError",
|
||||||
|
"evalue": "name 'user_keys' is not defined",
|
||||||
|
"output_type": "error",
|
||||||
|
"traceback": [
|
||||||
|
"\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
|
||||||
|
"\u001B[0;31mNameError\u001B[0m Traceback (most recent call last)",
|
||||||
|
"Cell \u001B[0;32mIn[5], line 3\u001B[0m\n\u001B[1;32m 1\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01msrc\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mutils\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m xor_lists\n\u001B[0;32m----> 3\u001B[0m padded_passcode_server_set \u001B[38;5;241m=\u001B[39m \u001B[43muser_keys\u001B[49m\u001B[38;5;241m.\u001B[39mpad_user_mask(passcode_server_set, customer\u001B[38;5;241m.\u001B[39mproperites\u001B[38;5;241m.\u001B[39mset_vals)\n\u001B[1;32m 5\u001B[0m set_idx \u001B[38;5;241m=\u001B[39m [customer\u001B[38;5;241m.\u001B[39mproperites\u001B[38;5;241m.\u001B[39mget_set_index(set_val) \u001B[38;5;28;01mfor\u001B[39;00m set_val \u001B[38;5;129;01min\u001B[39;00m padded_passcode_server_set]\n\u001B[1;32m 6\u001B[0m mask_set_keys \u001B[38;5;241m=\u001B[39m [user_keys\u001B[38;5;241m.\u001B[39mset_key[idx] \u001B[38;5;28;01mfor\u001B[39;00m idx \u001B[38;5;129;01min\u001B[39;00m set_idx]\n",
|
||||||
|
"\u001B[0;31mNameError\u001B[0m: name 'user_keys' is not defined"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"execution_count": 5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -483,7 +496,7 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:09.479816Z",
|
"end_time": "2025-03-10T15:54:02.130948Z",
|
||||||
"start_time": "2025-03-07T19:01:09.236822Z"
|
"start_time": "2025-03-07T19:01:09.236822Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -494,7 +507,7 @@
|
|||||||
"import base64\n",
|
"import base64\n",
|
||||||
"from src.utils import int_array_to_bytes\n",
|
"from src.utils import int_array_to_bytes\n",
|
||||||
"\n",
|
"\n",
|
||||||
"ciphered_customer_attrs = xor_lists(customer.attributes.attr_vals, user_keys.alpha_key)\n",
|
"ciphered_customer_attrs = xor_lists(customer.attributes.attr_vals, user_keys.prop_key)\n",
|
||||||
"passcode_ciphered_attrs = [ciphered_customer_attrs[idx] for idx in user_passcode]\n",
|
"passcode_ciphered_attrs = [ciphered_customer_attrs[idx] for idx in user_passcode]\n",
|
||||||
"pad_len = customer.nkode_policy.max_nkode_len - passcode_len\n",
|
"pad_len = customer.nkode_policy.max_nkode_len - passcode_len\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -513,7 +526,7 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:09.495420Z",
|
"end_time": "2025-03-10T15:54:02.141842Z",
|
||||||
"start_time": "2025-03-07T19:01:09.488943Z"
|
"start_time": "2025-03-07T19:01:09.488943Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -553,7 +566,7 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:09.736403Z",
|
"end_time": "2025-03-10T15:54:02.143871Z",
|
||||||
"start_time": "2025-03-07T19:01:09.500580Z"
|
"start_time": "2025-03-07T19:01:09.500580Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -605,7 +618,7 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:09.774425Z",
|
"end_time": "2025-03-10T15:54:02.144830Z",
|
||||||
"start_time": "2025-03-07T19:01:09.772200Z"
|
"start_time": "2025-03-07T19:01:09.772200Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -613,7 +626,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"user = customer.users[username]\n",
|
"user = customer.users[username]\n",
|
||||||
"set_vals = customer.attributes.set_vals\n",
|
"set_vals = customer.attributes.set_vals\n",
|
||||||
"user_keys = user.user_keys\n",
|
"user_keys = user.cipher\n",
|
||||||
"user_mask = user.enciphered_passcode.mask\n",
|
"user_mask = user.enciphered_passcode.mask\n",
|
||||||
"decoded_mask = user_keys.decode_base64_str(user_mask)\n",
|
"decoded_mask = user_keys.decode_base64_str(user_mask)\n",
|
||||||
"deciphered_mask = xor_lists(decoded_mask, user_keys.mask_key)\n",
|
"deciphered_mask = xor_lists(decoded_mask, user_keys.mask_key)\n",
|
||||||
@@ -643,7 +656,7 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:09.795190Z",
|
"end_time": "2025-03-10T15:54:02.145423Z",
|
||||||
"start_time": "2025-03-07T19:01:09.792579Z"
|
"start_time": "2025-03-07T19:01:09.792579Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -679,7 +692,7 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:10.057899Z",
|
"end_time": "2025-03-10T15:54:02.145859Z",
|
||||||
"start_time": "2025-03-07T19:01:09.819860Z"
|
"start_time": "2025-03-07T19:01:09.819860Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -716,7 +729,7 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:11.147274Z",
|
"end_time": "2025-03-10T15:54:02.146298Z",
|
||||||
"start_time": "2025-03-07T19:01:10.066784Z"
|
"start_time": "2025-03-07T19:01:10.066784Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -763,7 +776,7 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:11.355505Z",
|
"end_time": "2025-03-10T15:54:02.148090Z",
|
||||||
"start_time": "2025-03-07T19:01:11.153001Z"
|
"start_time": "2025-03-07T19:01:11.153001Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -789,7 +802,7 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:11.363643Z",
|
"end_time": "2025-03-10T15:54:02.154941Z",
|
||||||
"start_time": "2025-03-07T19:01:11.361690Z"
|
"start_time": "2025-03-07T19:01:11.361690Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -799,8 +812,8 @@
|
|||||||
"sets_xor = xor_lists(new_sets, old_sets)\n",
|
"sets_xor = xor_lists(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.user_keys.set_key = xor_lists(user.user_keys.set_key, sets_xor)\n",
|
" user.cipher.set_key = xor_lists(user.cipher.set_key, sets_xor)\n",
|
||||||
" user.user_keys.alpha_key = xor_lists(user.user_keys.alpha_key, attrs_xor)"
|
" user.cipher.prop_key = xor_lists(user.cipher.prop_key, attrs_xor)"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"execution_count": 78
|
"execution_count": 78
|
||||||
@@ -813,18 +826,18 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-07T19:01:11.989265Z",
|
"end_time": "2025-03-10T15:54:02.155673Z",
|
||||||
"start_time": "2025-03-07T19:01:11.369911Z"
|
"start_time": "2025-03-07T19:01:11.369911Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"user.user_keys = UserCipherKeys.new(\n",
|
"user.cipher = UserCipher.create(\n",
|
||||||
" customer.attributes.keypad_size,\n",
|
" customer.attributes.keypad_size,\n",
|
||||||
" customer.attributes.set_vals,\n",
|
" customer.attributes.set_vals,\n",
|
||||||
" user.user_keys.max_nkode_len\n",
|
" user.cipher.max_nkode_len\n",
|
||||||
")\n",
|
")\n",
|
||||||
"user.enciphered_passcode = user.user_keys.encipher_nkode(presumed_selected_attributes_idx, customer.attributes)\n",
|
"user.enciphered_passcode = user.cipher.encipher_nkode(presumed_selected_attributes_idx, customer.attributes)\n",
|
||||||
"user.renew = False"
|
"user.renew = False"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from src.utils import xor_lists
|
|||||||
class Customer:
|
class Customer:
|
||||||
customer_id: UUID
|
customer_id: UUID
|
||||||
nkode_policy: NKodePolicy
|
nkode_policy: NKodePolicy
|
||||||
customer_cipher: CustomerCipher
|
cipher: CustomerCipher
|
||||||
users: dict[str, User]
|
users: dict[str, User]
|
||||||
|
|
||||||
# TODO: validate policy and keypad size don't conflict
|
# TODO: validate policy and keypad size don't conflict
|
||||||
@@ -23,16 +23,16 @@ class Customer:
|
|||||||
if username not in self.users:
|
if username not in self.users:
|
||||||
raise ValueError(f"User '{username}' does not exist")
|
raise ValueError(f"User '{username}' does not exist")
|
||||||
|
|
||||||
numb_of_keys = self.customer_cipher.keypad_size.numb_of_keys
|
numb_of_keys = self.cipher.keypad_size.numb_of_keys
|
||||||
if not all(0 <= key_idx < numb_of_keys for key_idx in selected_keys):
|
if not all(0 <= key_idx < numb_of_keys for key_idx in selected_keys):
|
||||||
raise ValueError(f"Invalid key indices. Must be between 0 and {numb_of_keys - 1}")
|
raise ValueError(f"Invalid key indices. Must be between 0 and {numb_of_keys - 1}")
|
||||||
|
|
||||||
passcode_len = len(selected_keys)
|
passcode_len = len(selected_keys)
|
||||||
user = self.users[username]
|
user = self.users[username]
|
||||||
|
|
||||||
passcode_set_vals = user.user_keys.decipher_mask(
|
passcode_set_vals = user.cipher.decipher_mask(
|
||||||
user.enciphered_passcode.mask, self.customer_cipher.set_key, passcode_len)
|
user.enciphered_passcode.mask, self.cipher.set_key, passcode_len)
|
||||||
set_vals_idx = [self.customer_cipher.get_set_index(set_val) for set_val in passcode_set_vals]
|
set_vals_idx = [self.cipher.get_set_index(set_val) for set_val in passcode_set_vals]
|
||||||
|
|
||||||
presumed_selected_attributes_idx = []
|
presumed_selected_attributes_idx = []
|
||||||
for idx in range(passcode_len):
|
for idx in range(passcode_len):
|
||||||
@@ -41,20 +41,20 @@ class Customer:
|
|||||||
selected_attr_idx = user.user_keypad.get_attr_idx_by_keynumb_setidx(key_numb, set_idx)
|
selected_attr_idx = user.user_keypad.get_attr_idx_by_keynumb_setidx(key_numb, set_idx)
|
||||||
presumed_selected_attributes_idx.append(selected_attr_idx)
|
presumed_selected_attributes_idx.append(selected_attr_idx)
|
||||||
|
|
||||||
enciphered_attr = user.user_keys.encipher_salt_hash_code(presumed_selected_attributes_idx, self.customer_cipher)
|
enciphered_attr = user.cipher.encipher_salt_hash_code(presumed_selected_attributes_idx, self.cipher)
|
||||||
if enciphered_attr != user.enciphered_passcode.code:
|
if enciphered_attr != user.enciphered_passcode.code:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if user.renew:
|
if user.renew:
|
||||||
user.refresh_passcode(presumed_selected_attributes_idx, self.customer_cipher)
|
user.refresh_passcode(presumed_selected_attributes_idx, self.cipher)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def renew_keys(self) -> bool:
|
def renew_keys(self) -> bool:
|
||||||
old_attrs = self.customer_cipher.prop_key.copy()
|
old_attrs = self.cipher.prop_key.copy()
|
||||||
old_sets = self.customer_cipher.set_key.copy()
|
old_sets = self.cipher.set_key.copy()
|
||||||
self.customer_cipher.renew()
|
self.cipher.renew()
|
||||||
new_attrs = self.customer_cipher.prop_key
|
new_attrs = self.cipher.prop_key
|
||||||
new_sets = self.customer_cipher.set_key
|
new_sets = self.cipher.set_key
|
||||||
|
|
||||||
attrs_xor = xor_lists(new_attrs, old_attrs)
|
attrs_xor = xor_lists(new_attrs, old_attrs)
|
||||||
set_xor = xor_lists(new_sets, old_sets)
|
set_xor = xor_lists(new_sets, old_sets)
|
||||||
@@ -66,7 +66,7 @@ class Customer:
|
|||||||
def valid_new_nkode(self, passcode_attr_idx: list[int]) -> bool:
|
def valid_new_nkode(self, passcode_attr_idx: list[int]) -> bool:
|
||||||
nkode_len = len(passcode_attr_idx)
|
nkode_len = len(passcode_attr_idx)
|
||||||
passcode_set_values = [
|
passcode_set_values = [
|
||||||
self.customer_cipher.get_prop_set_val(self.customer_cipher.prop_key[attr_idx]) for attr_idx in passcode_attr_idx
|
self.cipher.get_prop_set_val(self.cipher.prop_key[attr_idx]) for attr_idx in passcode_attr_idx
|
||||||
]
|
]
|
||||||
distinct_sets = len(set(passcode_set_values))
|
distinct_sets = len(set(passcode_set_values))
|
||||||
distinct_attributes = len(set(passcode_attr_idx))
|
distinct_attributes = len(set(passcode_attr_idx))
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from uuid import UUID, uuid4
|
from uuid import UUID, uuid4
|
||||||
from typing import Dict, List, Tuple
|
from typing import Dict, List, Tuple
|
||||||
|
|
||||||
from src.customer import Customer
|
from src.customer import Customer
|
||||||
from src.models import NKodePolicy, KeypadSize
|
from src.models import NKodePolicy, KeypadSize
|
||||||
from src.user import User
|
from src.user import User
|
||||||
@@ -19,7 +18,7 @@ class NKodeAPI:
|
|||||||
def create_new_customer(self, keypad_size: KeypadSize, nkode_policy: NKodePolicy) -> UUID:
|
def create_new_customer(self, keypad_size: KeypadSize, nkode_policy: NKodePolicy) -> UUID:
|
||||||
new_customer = Customer(
|
new_customer = Customer(
|
||||||
customer_id=uuid4(),
|
customer_id=uuid4(),
|
||||||
customer_cipher=CustomerCipher.create(keypad_size),
|
cipher=CustomerCipher.create(keypad_size),
|
||||||
users={},
|
users={},
|
||||||
nkode_policy=nkode_policy
|
nkode_policy=nkode_policy
|
||||||
)
|
)
|
||||||
@@ -30,7 +29,7 @@ class NKodeAPI:
|
|||||||
if customer_id not in self.customers.keys():
|
if customer_id not in self.customers.keys():
|
||||||
raise ValueError(f"Customer with ID '{customer_id}' does not exist")
|
raise ValueError(f"Customer with ID '{customer_id}' does not exist")
|
||||||
customer = self.customers[customer_id]
|
customer = self.customers[customer_id]
|
||||||
login_keypad = UserKeypad.create(customer.customer_cipher.keypad_size)
|
login_keypad = UserKeypad.create(customer.cipher.keypad_size)
|
||||||
set_keypad = login_keypad.sign_up_keypad()
|
set_keypad = login_keypad.sign_up_keypad()
|
||||||
new_session = UserSignupSession(
|
new_session = UserSignupSession(
|
||||||
session_id=uuid4(),
|
session_id=uuid4(),
|
||||||
@@ -76,15 +75,15 @@ class NKodeAPI:
|
|||||||
customer = self.customers[customer_id]
|
customer = self.customers[customer_id]
|
||||||
passcode = self.signup_sessions[session_id].deduce_passcode(confirm_key_entry)
|
passcode = self.signup_sessions[session_id].deduce_passcode(confirm_key_entry)
|
||||||
new_user_keys = UserCipher.create(
|
new_user_keys = UserCipher.create(
|
||||||
customer.customer_cipher.keypad_size,
|
customer.cipher.keypad_size,
|
||||||
customer.customer_cipher.set_key,
|
customer.cipher.set_key,
|
||||||
customer.nkode_policy.max_nkode_len
|
customer.nkode_policy.max_nkode_len
|
||||||
)
|
)
|
||||||
enciphered_passcode = new_user_keys.encipher_nkode(passcode, customer.customer_cipher)
|
enciphered_passcode = new_user_keys.encipher_nkode(passcode, customer.cipher)
|
||||||
new_user = User(
|
new_user = User(
|
||||||
username=username,
|
username=username,
|
||||||
enciphered_passcode=enciphered_passcode,
|
enciphered_passcode=enciphered_passcode,
|
||||||
user_keys=new_user_keys,
|
cipher=new_user_keys,
|
||||||
user_keypad=self.signup_sessions[session_id].login_keypad,
|
user_keypad=self.signup_sessions[session_id].login_keypad,
|
||||||
)
|
)
|
||||||
self.customers[customer_id].add_new_user(new_user)
|
self.customers[customer_id].add_new_user(new_user)
|
||||||
|
|||||||
14
src/user.py
14
src/user.py
@@ -10,20 +10,20 @@ from src.utils import xor_lists
|
|||||||
class User:
|
class User:
|
||||||
username: str
|
username: str
|
||||||
enciphered_passcode: EncipheredNKode
|
enciphered_passcode: EncipheredNKode
|
||||||
user_keys: UserCipher
|
cipher: UserCipher
|
||||||
user_keypad: UserKeypad
|
user_keypad: UserKeypad
|
||||||
renew: bool = field(default=False)
|
renew: bool = field(default=False)
|
||||||
|
|
||||||
def renew_keys(self, sets_xor: list[int], attrs_xor: list[int]):
|
def renew_keys(self, set_xor: list[int], prop_xor: list[int]):
|
||||||
self.renew = True
|
self.renew = True
|
||||||
self.user_keys.set_key = xor_lists(self.user_keys.set_key, sets_xor)
|
self.cipher.set_key = xor_lists(self.cipher.set_key, set_xor)
|
||||||
self.user_keys.prop_key = xor_lists(self.user_keys.prop_key, attrs_xor)
|
self.cipher.prop_key = xor_lists(self.cipher.prop_key, prop_xor)
|
||||||
|
|
||||||
def refresh_passcode(self, passcode_attr_idx: list[int], customer_attributes: CustomerCipher):
|
def refresh_passcode(self, passcode_attr_idx: list[int], customer_attributes: CustomerCipher):
|
||||||
self.user_keys = UserCipher.create(
|
self.cipher = UserCipher.create(
|
||||||
customer_attributes.keypad_size,
|
customer_attributes.keypad_size,
|
||||||
customer_attributes.set_key,
|
customer_attributes.set_key,
|
||||||
self.user_keys.max_nkode_len
|
self.cipher.max_nkode_len
|
||||||
)
|
)
|
||||||
self.enciphered_passcode = self.user_keys.encipher_nkode(passcode_attr_idx, customer_attributes)
|
self.enciphered_passcode = self.cipher.encipher_nkode(passcode_attr_idx, customer_attributes)
|
||||||
self.renew = False
|
self.renew = False
|
||||||
|
|||||||
@@ -2,17 +2,18 @@ import base64
|
|||||||
import hashlib
|
import hashlib
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
import bcrypt
|
import bcrypt
|
||||||
|
import numpy as np
|
||||||
from secrets import choice
|
from secrets import choice
|
||||||
from src.models import EncipheredNKode, KeypadSize
|
from src.models import EncipheredNKode, KeypadSize
|
||||||
from src.customer_cipher import CustomerCipher
|
from src.customer_cipher import CustomerCipher
|
||||||
from src.utils import generate_random_nonrepeating_list, xor_lists, int_array_to_bytes
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class UserCipher:
|
class UserCipher:
|
||||||
prop_key: list[int]
|
prop_key: np.ndarray
|
||||||
set_key: list[int]
|
set_key: np.ndarray
|
||||||
pass_key: list[int]
|
pass_key: np.ndarray
|
||||||
mask_key: list[int]
|
mask_key: np.ndarray
|
||||||
salt: bytes
|
salt: bytes
|
||||||
max_nkode_len: int
|
max_nkode_len: int
|
||||||
|
|
||||||
@@ -21,41 +22,50 @@ class UserCipher:
|
|||||||
if len(set_values) != keypad_size.props_per_key:
|
if len(set_values) != keypad_size.props_per_key:
|
||||||
raise ValueError("Invalid set values")
|
raise ValueError("Invalid set values")
|
||||||
|
|
||||||
set_key = generate_random_nonrepeating_list(keypad_size.props_per_key)
|
set_values_array = np.array(set_values, dtype=np.uint16)
|
||||||
set_key = xor_lists(set_key, set_values)
|
set_key = generate_random_nonrepeating_array(keypad_size.props_per_key)
|
||||||
|
set_key = np.bitwise_xor(set_key, set_values_array)
|
||||||
|
|
||||||
return UserCipher(
|
return UserCipher(
|
||||||
prop_key=generate_random_nonrepeating_list(keypad_size.props_per_key * keypad_size.numb_of_keys),
|
prop_key=generate_random_nonrepeating_array(keypad_size.props_per_key * keypad_size.numb_of_keys),
|
||||||
pass_key=generate_random_nonrepeating_list(max_nkode_len),
|
pass_key=generate_random_nonrepeating_array(max_nkode_len),
|
||||||
mask_key=generate_random_nonrepeating_list(max_nkode_len),
|
mask_key=generate_random_nonrepeating_array(max_nkode_len),
|
||||||
set_key=set_key,
|
set_key=set_key,
|
||||||
salt=bcrypt.gensalt(),
|
salt=bcrypt.gensalt(),
|
||||||
max_nkode_len=max_nkode_len
|
max_nkode_len=max_nkode_len
|
||||||
)
|
)
|
||||||
|
|
||||||
def pad_user_mask(self, user_mask: list[int], set_vals: list[int]) -> list[int]:
|
def pad_user_mask(self, user_mask: list[int], set_vals: list[int]) -> np.ndarray:
|
||||||
if len(user_mask) >= self.max_nkode_len:
|
if len(user_mask) >= self.max_nkode_len:
|
||||||
raise ValueError("User mask is too long")
|
raise ValueError("User mask is too long")
|
||||||
padded_user_mask = user_mask.copy()
|
|
||||||
for _ in range(self.max_nkode_len - len(user_mask)):
|
user_mask_array = np.array(user_mask, dtype=np.uint16)
|
||||||
padded_user_mask.append(choice(set_vals))
|
set_vals_array = np.array(set_vals, dtype=np.uint16)
|
||||||
|
|
||||||
|
# Create padding of random choices from set_vals
|
||||||
|
padding_size = self.max_nkode_len - len(user_mask)
|
||||||
|
padding_indices = np.random.choice(len(set_vals), padding_size)
|
||||||
|
padding = np.array([set_vals[i] for i in padding_indices], dtype=np.uint16)
|
||||||
|
|
||||||
|
# Concatenate original mask with padding
|
||||||
|
padded_user_mask = np.concatenate([user_mask_array, padding])
|
||||||
return padded_user_mask
|
return padded_user_mask
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def encode_base64_str(data: list[int]) -> str:
|
def encode_base64_str(data: np.ndarray) -> str:
|
||||||
return base64.b64encode(int_array_to_bytes(data)).decode("utf-8")
|
return base64.b64encode(int_array_to_bytes(data)).decode("utf-8")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def decode_base64_str(data: str) -> list[int]:
|
def decode_base64_str(data: str) -> np.ndarray:
|
||||||
byte_data = base64.b64decode(data)
|
byte_data = base64.b64decode(data)
|
||||||
int_list = []
|
int_list = []
|
||||||
|
|
||||||
for i in range(0, len(byte_data), 2):
|
for i in range(0, len(byte_data), 2):
|
||||||
int_val = int.from_bytes(byte_data[i:i + 2], byteorder='big')
|
int_val = int.from_bytes(byte_data[i:i + 2], byteorder='big')
|
||||||
int_list.append(int_val)
|
int_list.append(int_val)
|
||||||
return int_list
|
return np.array(int_list, dtype=np.uint16)
|
||||||
|
|
||||||
def _hash_passcode(self, passcode: list[int]) -> str:
|
def _hash_passcode(self, passcode: np.ndarray) -> str:
|
||||||
passcode_bytes = int_array_to_bytes(passcode)
|
passcode_bytes = int_array_to_bytes(passcode)
|
||||||
passcode_digest = base64.b64encode(hashlib.sha256(passcode_bytes).digest())
|
passcode_digest = base64.b64encode(hashlib.sha256(passcode_bytes).digest())
|
||||||
hashed_data = bcrypt.hashpw(passcode_digest, self.salt)
|
hashed_data = bcrypt.hashpw(passcode_digest, self.salt)
|
||||||
@@ -66,10 +76,10 @@ class UserCipher:
|
|||||||
passcode_prop_idx: list[int],
|
passcode_prop_idx: list[int],
|
||||||
customer_cipher: CustomerCipher
|
customer_cipher: CustomerCipher
|
||||||
) -> EncipheredNKode:
|
) -> EncipheredNKode:
|
||||||
|
passcode_prop_idx_array = np.array(passcode_prop_idx, dtype=np.uint16)
|
||||||
passcode_attrs = [customer_cipher.prop_key[idx] for idx in passcode_prop_idx]
|
passcode_attrs = np.array([customer_cipher.prop_key[idx] for idx in passcode_prop_idx_array], dtype=np.uint16)
|
||||||
passcode_sets = [customer_cipher.get_prop_set_val(attr) for attr in passcode_attrs]
|
passcode_sets = np.array([customer_cipher.get_prop_set_val(attr) for attr in passcode_attrs], dtype=np.uint16)
|
||||||
mask = self.encipher_mask(passcode_sets, customer_cipher)
|
mask = self.encipher_mask(passcode_sets.tolist(), customer_cipher)
|
||||||
code = self.encipher_salt_hash_code(passcode_prop_idx, customer_cipher)
|
code = self.encipher_salt_hash_code(passcode_prop_idx, customer_cipher)
|
||||||
return EncipheredNKode(
|
return EncipheredNKode(
|
||||||
code=code,
|
code=code,
|
||||||
@@ -81,12 +91,15 @@ class UserCipher:
|
|||||||
passcode_prop_idx: list[int],
|
passcode_prop_idx: list[int],
|
||||||
customer_prop: CustomerCipher,
|
customer_prop: CustomerCipher,
|
||||||
) -> str:
|
) -> str:
|
||||||
passcode_len = len(passcode_prop_idx)
|
passcode_prop_idx_array = np.array(passcode_prop_idx, dtype=np.uint16)
|
||||||
passcode_attrs = [customer_prop.prop_key[idx] for idx in passcode_prop_idx]
|
passcode_len = len(passcode_prop_idx_array)
|
||||||
|
passcode_attrs = np.array([customer_prop.prop_key[idx] for idx in passcode_prop_idx_array], dtype=np.uint16)
|
||||||
|
|
||||||
passcode_cipher = self.pass_key.copy()
|
passcode_cipher = self.pass_key.copy()
|
||||||
for idx in range(passcode_len):
|
for idx in range(passcode_len):
|
||||||
attr_idx = passcode_prop_idx[idx]
|
attr_idx = passcode_prop_idx_array[idx]
|
||||||
passcode_cipher[idx] ^= self.prop_key[attr_idx] ^ passcode_attrs[idx]
|
passcode_cipher[idx] = passcode_cipher[idx] ^ self.prop_key[attr_idx] ^ passcode_attrs[idx]
|
||||||
|
|
||||||
return self._hash_passcode(passcode_cipher)
|
return self._hash_passcode(passcode_cipher)
|
||||||
|
|
||||||
def encipher_mask(
|
def encipher_mask(
|
||||||
@@ -95,19 +108,47 @@ class UserCipher:
|
|||||||
customer_attributes: CustomerCipher
|
customer_attributes: CustomerCipher
|
||||||
) -> str:
|
) -> str:
|
||||||
padded_passcode_sets = self.pad_user_mask(passcode_sets, customer_attributes.set_key)
|
padded_passcode_sets = self.pad_user_mask(passcode_sets, customer_attributes.set_key)
|
||||||
set_idx = [customer_attributes.get_set_index(set_val) for set_val in padded_passcode_sets]
|
|
||||||
mask_set_keys = [self.set_key[idx] for idx in set_idx]
|
# Get indices of set values
|
||||||
ciphered_mask = xor_lists(mask_set_keys, padded_passcode_sets)
|
set_idx = np.array([customer_attributes.get_set_index(set_val) for set_val in padded_passcode_sets],
|
||||||
ciphered_mask = xor_lists(ciphered_mask, self.mask_key)
|
dtype=np.uint16)
|
||||||
|
mask_set_keys = np.array([self.set_key[idx] for idx in set_idx], dtype=np.uint16)
|
||||||
|
|
||||||
|
# XOR operations
|
||||||
|
ciphered_mask = np.bitwise_xor(mask_set_keys, padded_passcode_sets)
|
||||||
|
ciphered_mask = np.bitwise_xor(ciphered_mask, self.mask_key)
|
||||||
|
|
||||||
mask = self.encode_base64_str(ciphered_mask)
|
mask = self.encode_base64_str(ciphered_mask)
|
||||||
return mask
|
return mask
|
||||||
|
|
||||||
def decipher_mask(self, mask: str, set_vals: list, passcode_len: int) -> list[int]:
|
def decipher_mask(self, mask: str, set_vals: list, passcode_len: int) -> list[int]:
|
||||||
|
set_vals_array = np.array(set_vals, dtype=np.uint16)
|
||||||
decoded_mask = self.decode_base64_str(mask)
|
decoded_mask = self.decode_base64_str(mask)
|
||||||
deciphered_mask = xor_lists(decoded_mask, self.mask_key)
|
deciphered_mask = np.bitwise_xor(decoded_mask, self.mask_key)
|
||||||
set_key_rand_component = xor_lists(set_vals, self.set_key)
|
|
||||||
|
set_key_rand_component = np.bitwise_xor(set_vals_array, self.set_key)
|
||||||
passcode_sets = []
|
passcode_sets = []
|
||||||
|
|
||||||
for set_cipher in deciphered_mask[:passcode_len]:
|
for set_cipher in deciphered_mask[:passcode_len]:
|
||||||
set_idx = set_key_rand_component.index(set_cipher)
|
# Find index where values match
|
||||||
|
set_idx = np.where(set_key_rand_component == set_cipher)[0][0]
|
||||||
passcode_sets.append(set_vals[set_idx])
|
passcode_sets.append(set_vals[set_idx])
|
||||||
|
|
||||||
return passcode_sets
|
return passcode_sets
|
||||||
|
|
||||||
|
|
||||||
|
# NumPy utility functions to replace the existing ones
|
||||||
|
def generate_random_nonrepeating_array(array_len: int, min_val: int = 0, max_val: int = 2 ** 16) -> np.ndarray:
|
||||||
|
if max_val - min_val < array_len:
|
||||||
|
raise ValueError("Range of values is less than the array length requested")
|
||||||
|
|
||||||
|
# Generate array of random unique integers
|
||||||
|
return np.random.choice(
|
||||||
|
np.arange(min_val, max_val, dtype=np.uint16),
|
||||||
|
size=array_len,
|
||||||
|
replace=False
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def int_array_to_bytes(int_arr: np.ndarray, byte_size: int = 2) -> bytes:
|
||||||
|
return b"".join([int(num).to_bytes(byte_size, byteorder='big') for num in int_arr])
|
||||||
@@ -22,7 +22,7 @@ def test_shuffle_attrs(user_keypad):
|
|||||||
expected statistical outcomes like:
|
expected statistical outcomes like:
|
||||||
- every attribute gets to every key with a uniform distribution
|
- every attribute gets to every key with a uniform distribution
|
||||||
- every attribute is adjacent to every other attribute with uniform distribution
|
- every attribute is adjacent to every other attribute with uniform distribution
|
||||||
- the order in which the customer_cipher move from key to key is random (i.e. the distance traveled is uniform)
|
- the order in which the cipher move from key to key is random (i.e. the distance traveled is uniform)
|
||||||
"""
|
"""
|
||||||
pre_shuffle_keypad = user_keypad.keypad
|
pre_shuffle_keypad = user_keypad.keypad
|
||||||
user_keypad.partial_keypad_shuffle()
|
user_keypad.partial_keypad_shuffle()
|
||||||
|
|||||||
Reference in New Issue
Block a user