From b6ab0c1890da6f52a636e28780baa2797ac585f8 Mon Sep 17 00:00:00 2001 From: Donovan Date: Sun, 16 Mar 2025 06:20:05 -0500 Subject: [PATCH] refactor np.bitwise xor to ^ operator --- docs/render_readme.py | 16 +- notebooks/nkode_tutorial.ipynb | 265 ++++++++++++++++----------------- src/customer.py | 4 +- src/user.py | 4 +- src/user_cipher.py | 18 +-- 5 files changed, 149 insertions(+), 158 deletions(-) diff --git a/docs/render_readme.py b/docs/render_readme.py index 77c8a81..df4551c 100644 --- a/docs/render_readme.py +++ b/docs/render_readme.py @@ -97,12 +97,10 @@ if __name__ == "__main__": padded_passcode_server_set = user_keys.pad_user_mask(np.array(passcode_server_set), customer.cipher.set_key) 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] - ciphered_mask = np.bitwise_xor(mask_set_keys, padded_passcode_server_set) - ciphered_mask = np.bitwise_xor(ciphered_mask, user_keys.mask_key) + mask_set_keys = [user_keys.combined_set_key[idx] for idx in set_idx] + ciphered_mask = mask_set_keys ^ padded_passcode_server_set ^ user_keys.mask_key mask = user_keys.encode_base64_str(ciphered_mask) - #ciphered_customer_props = xor_lists(customer.cipher.prop_key, user_keys.prop_key) - ciphered_customer_props = np.bitwise_xor(customer.cipher.prop_key, user_keys.prop_key) + ciphered_customer_props = customer.cipher.prop_key ^ user_keys.prop_key passcode_ciphered_props = [ciphered_customer_props[idx] for idx in user_passcode] pad_len = customer.nkode_policy.max_nkode_len - passcode_len passcode_ciphered_props.extend([0 for _ in range(pad_len)]) @@ -136,7 +134,7 @@ if __name__ == "__main__": user_mask = user.enciphered_passcode.mask decoded_mask = user_keys.decode_base64_str(user_mask) deciphered_mask = np.bitwise_xor(decoded_mask, user_keys.mask_key) - set_key_rand_component = np.bitwise_xor(set_vals, user_keys.set_key) + set_key_rand_component = np.bitwise_xor(set_vals, user_keys.combined_set_key) login_passcode_sets = [] for set_cipher in deciphered_mask[:passcode_len]: set_idx = np.where(set_key_rand_component == set_cipher)[0][0] @@ -172,7 +170,7 @@ if __name__ == "__main__": sets_xor = np.bitwise_xor(new_sets, old_sets) for user in customer.users.values(): user.renew = True - user.cipher.set_key = np.bitwise_xor(user.cipher.set_key, sets_xor) + user.cipher.combined_set_key = np.bitwise_xor(user.cipher.combined_set_key, sets_xor) user.cipher.prop_key = np.bitwise_xor(user.cipher.prop_key, props_xor) """ @@ -200,8 +198,8 @@ if __name__ == "__main__": 'confirm_keypad': confirm_keypad, 'selected_keys_confirm': selected_keys_confirm, 'user_cipher': user_keys, - 'passcode_server_prop': passcode_server_prop, - 'passcode_server_set': passcode_server_set, + 'ordered_customer_prop_key': passcode_server_prop, + 'ordered_customer_set_key': passcode_server_set, 'enciphered_nkode': enciphered_nkode, 'login_keypad': login_keypad, 'selected_login_keys': selected_keys_login, diff --git a/notebooks/nkode_tutorial.ipynb b/notebooks/nkode_tutorial.ipynb index 204be73..fd831d3 100644 --- a/notebooks/nkode_tutorial.ipynb +++ b/notebooks/nkode_tutorial.ipynb @@ -12,12 +12,12 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2025-03-14T14:35:01.634660Z", - "start_time": "2025-03-14T14:35:01.631713Z" + "end_time": "2025-03-16T11:17:06.665193Z", + "start_time": "2025-03-16T11:17:06.662525Z" } }, "outputs": [], - "execution_count": 67 + "execution_count": 23 }, { "cell_type": "code", @@ -40,12 +40,12 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2025-03-14T14:35:01.653961Z", - "start_time": "2025-03-14T14:35:01.650229Z" + "end_time": "2025-03-16T11:17:06.680622Z", + "start_time": "2025-03-16T11:17:06.677352Z" } }, "outputs": [], - "execution_count": 68 + "execution_count": 24 }, { "cell_type": "code", @@ -55,12 +55,12 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2025-03-14T14:35:01.663429Z", - "start_time": "2025-03-14T14:35:01.661723Z" + "end_time": "2025-03-16T11:17:06.696721Z", + "start_time": "2025-03-16T11:17:06.694897Z" } }, "outputs": [], - "execution_count": 69 + "execution_count": 25 }, { "cell_type": "markdown", @@ -100,12 +100,12 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2025-03-14T14:35:01.675378Z", - "start_time": "2025-03-14T14:35:01.671221Z" + "end_time": "2025-03-16T11:17:06.708524Z", + "start_time": "2025-03-16T11:17:06.704492Z" } }, "outputs": [], - "execution_count": 70 + "execution_count": 26 }, { "cell_type": "markdown", @@ -130,7 +130,7 @@ "cell_type": "code", "source": [ "print(f\"Customer Set Key: {customer.cipher.set_key}\")\n", - "print(f\"Customer properties Key:\")\n", + "print(f\"Customer Properties Key:\")\n", "customer_prop_keypad = customer.cipher.prop_key.reshape(-1, keypad_size.props_per_key)\n", "for idx, key_vals in enumerate(customer_prop_keypad):\n", " print(f\"{key_vals}\")" @@ -138,8 +138,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2025-03-14T14:35:01.692557Z", - "start_time": "2025-03-14T14:35:01.689797Z" + "end_time": "2025-03-16T11:17:06.718027Z", + "start_time": "2025-03-16T11:17:06.715343Z" } }, "outputs": [ @@ -147,17 +147,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "Customer Set Key: [21871 61274 2713 19029 26505 50649]\n", - "Customer properties Key:\n", - "[42655 23174 1254 25551 11488 27210]\n", - "[60953 53938 20104 25057 1695 3339]\n", - "[32918 29164 48427 35503 41361 24040]\n", - "[44451 37655 36339 20189 49770 11581]\n", - "[31824 8094 2501 29432 12778 20956]\n" + "Customer Set Key: [51574 4745 25889 18231 60748 18510]\n", + "Customer Properties Key:\n", + "[60468 25732 54355 40123 30642 22334]\n", + "[12163 30704 51913 11579 53335 30868]\n", + "[36499 37185 3991 26970 25932 19506]\n", + "[ 7000 7490 26410 33717 8308 41888]\n", + "[59350 41496 33957 33571 58466 45968]\n" ] } ], - "execution_count": 71 + "execution_count": 27 }, { "cell_type": "markdown", @@ -177,8 +177,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2025-03-14T14:35:01.702167Z", - "start_time": "2025-03-14T14:35:01.699777Z" + "end_time": "2025-03-16T11:17:06.735483Z", + "start_time": "2025-03-16T11:17:06.733076Z" } }, "outputs": [ @@ -187,16 +187,16 @@ "output_type": "stream", "text": [ "Set to Properties Map:\n", - "21871: [42655 60953 32918 44451 31824]\n", - "61274: [23174 53938 29164 37655 8094]\n", - "2713: [ 1254 20104 48427 36339 2501]\n", - "19029: [25551 25057 35503 20189 29432]\n", - "26505: [11488 1695 41361 49770 12778]\n", - "50649: [27210 3339 24040 11581 20956]\n" + "51574: [60468 12163 36499 7000 59350]\n", + "4745: [25732 30704 37185 7490 41496]\n", + "25889: [54355 51913 3991 26410 33957]\n", + "18231: [40123 11579 26970 33717 33571]\n", + "60748: [30642 53335 25932 8308 58466]\n", + "18510: [22334 30868 19506 41888 45968]\n" ] } ], - "execution_count": 72 + "execution_count": 28 }, { "metadata": {}, @@ -218,8 +218,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:01.722470Z", - "start_time": "2025-03-14T14:35:01.719357Z" + "end_time": "2025-03-16T11:17:06.760751Z", + "start_time": "2025-03-16T11:17:06.758403Z" } }, "cell_type": "code", @@ -232,15 +232,15 @@ "name": "stdout", "output_type": "stream", "text": [ - "[[24 0 12 6 18]\n", - " [28 4 16 10 22]\n", - " [27 3 15 9 21]\n", - " [26 2 14 8 20]\n", - " [25 1 13 7 19]]\n" + "[[21 15 9 3 27]\n", + " [22 16 10 4 28]\n", + " [18 12 6 0 24]\n", + " [20 14 8 2 26]\n", + " [23 17 11 5 29]]\n" ] } ], - "execution_count": 73 + "execution_count": 29 }, { "metadata": {}, @@ -253,8 +253,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:01.746158Z", - "start_time": "2025-03-14T14:35:01.742671Z" + "end_time": "2025-03-16T11:17:06.783887Z", + "start_time": "2025-03-16T11:17:06.780577Z" } }, "cell_type": "code", @@ -275,25 +275,25 @@ "output_type": "stream", "text": [ "Keypad View\n", - "Key 0: [24 0 12 6 18]\n", - "Key 1: [28 4 16 10 22]\n", - "Key 2: [27 3 15 9 21]\n", - "Key 3: [26 2 14 8 20]\n", - "Key 4: [25 1 13 7 19]\n", - "User Passcode: [24 0 12 6]\n", + "Key 0: [21 15 9 3 27]\n", + "Key 1: [22 16 10 4 28]\n", + "Key 2: [18 12 6 0 24]\n", + "Key 3: [20 14 8 2 26]\n", + "Key 4: [23 17 11 5 29]\n", + "User Passcode: [21 15 9 3]\n", "Selected Keys\n", "[0, 0, 0, 0]\n", - "User Passcode Server-side properties: [31824, 42655, 32918, 60953]\n" + "User Passcode Server-side properties: [33717, 26970, 11579, 40123]\n" ] } ], - "execution_count": 74 + "execution_count": 30 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:01.770157Z", - "start_time": "2025-03-14T14:35:01.766784Z" + "end_time": "2025-03-16T11:17:06.799077Z", + "start_time": "2025-03-16T11:17:06.796555Z" } }, "cell_type": "code", @@ -309,23 +309,23 @@ "output_type": "stream", "text": [ "Keypad View\n", - "Key 0: [26 3 16 6 19]\n", - "Key 1: [27 0 13 10 20]\n", - "Key 2: [24 4 14 7 21]\n", - "Key 3: [28 1 15 8 18]\n", - "Key 4: [25 2 12 9 22]\n", + "Key 0: [18 17 8 4 27]\n", + "Key 1: [23 16 6 3 26]\n", + "Key 2: [22 15 11 2 24]\n", + "Key 3: [21 14 10 0 29]\n", + "Key 4: [20 12 9 5 28]\n", "Selected Keys\n", - "[2, 1, 4, 0]\n" + "[3, 2, 4, 1]\n" ] } ], - "execution_count": 75 + "execution_count": 31 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:02.101712Z", - "start_time": "2025-03-14T14:35:01.792851Z" + "end_time": "2025-03-16T11:17:07.061018Z", + "start_time": "2025-03-16T11:17:06.824471Z" } }, "cell_type": "code", @@ -343,7 +343,7 @@ ] } ], - "execution_count": 76 + "execution_count": 32 }, { "metadata": {}, @@ -362,17 +362,16 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:02.115075Z", - "start_time": "2025-03-14T14:35:02.110397Z" + "end_time": "2025-03-16T11:17:07.070338Z", + "start_time": "2025-03-16T11:17:07.066596Z" } }, "cell_type": "code", "source": [ "from src.user_cipher import UserCipher\n", "\n", - "\n", - "set_key = np.array([46785, 4782, 4405, 44408, 35377, 55527])\n", - "set_key = np.bitwise_xor(set_key, customer.cipher.set_key)\n", + "user_set_key = np.array([46785, 4782, 4405, 44408, 35377, 55527])\n", + "combined_set_key = np.bitwise_xor(user_set_key, customer.cipher.set_key)\n", "user_keys = UserCipher(\n", " prop_key = np.array([\n", " 57200, 8398, 54694, 25997, 30388,\n", @@ -384,27 +383,27 @@ " ]),\n", " pass_key=np.array([16090, 38488, 45111, 32674, 46216, 52013, 48980, 36811, 35296, 17206]),\n", " mask_key=np.array([29575, 43518, 44373, 62063, 37651, 31671, 31663, 65514, 36454, 47325]),\n", - " set_key=np.array(set_key),\n", + " combined_set_key=np.array(combined_set_key),\n", " salt=b'$2b$12$fX.in.GGAjz3QBBwqSWc6e',\n", " max_nkode_len=customer.nkode_policy.max_nkode_len, \n", ")\n", "\n", - "passcode_server_prop = [int(customer.cipher.prop_key[idx]) for idx in user_passcode]\n", - "passcode_server_set = [int(customer.cipher.get_prop_set_val(prop)) for prop in passcode_server_prop]\n", - "print(f\"Passcode Set Vals: {passcode_server_set}\")\n", - "print(f\"Passcode prop Vals: {passcode_server_prop}\")" + "ordered_customer_prop_key = customer.cipher.prop_key[user_passcode] # [int(customer.cipher.prop_key[idx]) for idx in user_passcode]\n", + "ordered_customer_set_key = [int(customer.cipher.get_prop_set_val(prop)) for prop in ordered_customer_prop_key]\n", + "print(f\"Passcode Set Vals: {ordered_customer_set_key}\")\n", + "print(f\"Passcode Prop Vals: {ordered_customer_prop_key}\")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Passcode Set Vals: [21871, 21871, 21871, 21871]\n", - "Passcode prop Vals: [31824, 42655, 32918, 60953]\n" + "Passcode Set Vals: [18231, 18231, 18231, 18231]\n", + "Passcode Prop Vals: [33717 26970 11579 40123]\n" ] } ], - "execution_count": 77 + "execution_count": 33 }, { "metadata": {}, @@ -412,36 +411,34 @@ "source": [ "#### Encipher Mask\n", "Recall:\n", - "1. set_key_i = (set_rand_numb_i ^ set_val_i) \n", - "2. mask_key_i = mask_rand_numb_i\n", - "3. padded_passcode_server_set_i = set_val_i\n", - "4. len(set_key) == len(mask_key) == (padded_passcode_server_set) == max_nkode_len == 10\n", + "1. combined_set_key = (user_set_key ^ customer_set_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", + "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_i = mask_key_i ^ padded_passcode_server_set_i ^ set_key_i\n", - "- mask_i = mask_rand_num_i ^ set_val_i ^ set_rand_numb_i ^ set_val_i\n", - "- mask_i = mask_rand_num_i ^ set_rand_numb_i # set_val_i is cancelled out" + "- mask = mask_key ^ padded_ordered_customer_set ^ ordered_set_key\n", + "- mask = mask_rand_num ^ set_val ^ set_rand_numb ^ set_val\n", + "- mask = mask_rand_num ^ set_rand_numb # set_val is cancelled out" ] }, { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:02.132228Z", - "start_time": "2025-03-14T14:35:02.129307Z" + "end_time": "2025-03-16T11:17:07.150818Z", + "start_time": "2025-03-16T11:17:07.148125Z" } }, "cell_type": "code", "source": [ - "padded_passcode_server_set = user_keys.pad_user_mask(passcode_server_set, customer.cipher.set_key)\n", - "\n", - "set_idx = [customer.cipher.get_set_index(set_val) for set_val in padded_passcode_server_set]\n", - "mask_set_keys = [user_keys.set_key[idx] for idx in set_idx]\n", - "ciphered_mask = np.bitwise_xor(mask_set_keys, padded_passcode_server_set)\n", + "padded_ordered_customer_set = user_keys.pad_user_mask(ordered_customer_set_key, customer.cipher.set_key)\n", + "set_idx = [customer.cipher.get_set_index(set_val) for set_val in padded_ordered_customer_set]\n", + "ordered_set_key = user_keys.combined_set_key[set_idx]\n", + "ciphered_mask = ordered_set_key ^ padded_ordered_customer_set\n", "ciphered_mask = np.bitwise_xor(ciphered_mask, user_keys.mask_key)\n", "mask = user_keys.encode_base64_str(ciphered_mask)" ], "outputs": [], - "execution_count": 78 + "execution_count": 34 }, { "metadata": {}, @@ -458,8 +455,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:02.448903Z", - "start_time": "2025-03-14T14:35:02.143953Z" + "end_time": "2025-03-16T11:17:07.413741Z", + "start_time": "2025-03-16T11:17:07.177338Z" } }, "cell_type": "code", @@ -483,13 +480,13 @@ "code = hashed_data.decode(\"utf-8\")" ], "outputs": [], - "execution_count": 79 + "execution_count": 35 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:02.459349Z", - "start_time": "2025-03-14T14:35:02.457325Z" + "end_time": "2025-03-16T11:17:07.428200Z", + "start_time": "2025-03-16T11:17:07.426275Z" } }, "cell_type": "code", @@ -502,7 +499,7 @@ ")" ], "outputs": [], - "execution_count": 80 + "execution_count": 36 }, { "metadata": {}, @@ -516,8 +513,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:02.775720Z", - "start_time": "2025-03-14T14:35:02.468856Z" + "end_time": "2025-03-16T11:17:07.668766Z", + "start_time": "2025-03-16T11:17:07.436169Z" } }, "cell_type": "code", @@ -535,17 +532,17 @@ "output_type": "stream", "text": [ "Keypad View\n", - "Key 0: [24 25 26 27 28 29]\n", - "Key 1: [0 1 2 3 4 5]\n", - "Key 2: [12 13 14 15 16 17]\n", - "Key 3: [ 6 7 8 9 10 11]\n", - "Key 4: [18 19 20 21 22 23]\n", + "Key 0: [18 19 20 21 22 23]\n", + "Key 1: [12 13 14 15 16 17]\n", + "Key 2: [ 6 7 8 9 10 11]\n", + "Key 3: [0 1 2 3 4 5]\n", + "Key 4: [24 25 26 27 28 29]\n", "Selected Keys: [0, 1, 2, 3]\n", "True\n" ] } ], - "execution_count": 81 + "execution_count": 37 }, { "metadata": {}, @@ -563,13 +560,13 @@ "source": [ "### Decipher Mask\n", "Recall:\n", - "- set_key_i = (set_key_rand_numb_i ^ set_val_i) \n", - "- mask_i = mask_key_rand_num_i ^ set_key_rand_numb_i\n", + "- set_key = (set_key_rand_numb ^ set_val)\n", + "- mask = mask_key_rand_num ^ set_key_rand_numb\n", "\n", "Recover nKode set values: \n", "- decode mask from base64 to int\n", "- deciphered_mask = mask ^ mask_key\n", - "- deciphered_mask_i = set_key_rand_numb # mask_key_rand_num_i is cancelled out\n", + "- deciphered_mask = set_key_rand_numb # mask_key_rand_num is cancelled out\n", "- set_key_rand_component = set_key ^ set_values\n", "- deduce the set value" ] @@ -577,8 +574,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:02.787442Z", - "start_time": "2025-03-14T14:35:02.784207Z" + "end_time": "2025-03-16T11:17:07.679342Z", + "start_time": "2025-03-16T11:17:07.676500Z" } }, "cell_type": "code", @@ -586,7 +583,7 @@ "user = api.customers[customer_id].users[username]\n", "decoded_mask = user.cipher.decode_base64_str(user.enciphered_passcode.mask)\n", "deciphered_mask = np.bitwise_xor(decoded_mask, user.cipher.mask_key)\n", - "set_key = np.bitwise_xor(customer.cipher.set_key, user.cipher.set_key)\n", + "set_key = np.bitwise_xor(customer.cipher.set_key, user.cipher.combined_set_key)\n", "passcode_sets = []\n", "for set_cipher in deciphered_mask[:passcode_len]:\n", " set_idx = np.where(set_key == set_cipher)[0][0]\n", @@ -598,11 +595,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "[21871, 21871, 21871, 21871]\n" + "[18231, 18231, 18231, 18231]\n" ] } ], - "execution_count": 82 + "execution_count": 38 }, { "metadata": {}, @@ -612,8 +609,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:02.805826Z", - "start_time": "2025-03-14T14:35:02.802523Z" + "end_time": "2025-03-16T11:17:07.690303Z", + "start_time": "2025-03-16T11:17:07.687880Z" } }, "cell_type": "code", @@ -638,7 +635,7 @@ ] } ], - "execution_count": 83 + "execution_count": 39 }, { "metadata": {}, @@ -648,8 +645,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:03.129079Z", - "start_time": "2025-03-14T14:35:02.822467Z" + "end_time": "2025-03-16T11:17:07.937619Z", + "start_time": "2025-03-16T11:17:07.705824Z" } }, "cell_type": "code", @@ -666,7 +663,7 @@ ] } ], - "execution_count": 84 + "execution_count": 40 }, { "metadata": {}, @@ -682,8 +679,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:03.757448Z", - "start_time": "2025-03-14T14:35:03.142511Z" + "end_time": "2025-03-16T11:17:08.414223Z", + "start_time": "2025-03-16T11:17:07.946756Z" } }, "cell_type": "code", @@ -708,14 +705,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "mask: QUR1wAPG8jJh/nG1LbgMIupAY1I=, code: $2b$12$0Ia665myY64l8.UyKRc4tu/OR.0BG6KFLyXcuDdIXrDkpP6cjo7xO\n", - "mask: QUR1wAPG8jJh/nG1LbgMIupAY1I=, code: $2b$12$0Ia665myY64l8.UyKRc4tu/OR.0BG6KFLyXcuDdIXrDkpP6cjo7xO\n", + "mask: zLwyQdPMPUFVeJjeKNJl1nyJ9OA=, code: $2b$12$RBM/q1Vu0bJy3kbYqMCymu5ojiE9bTq5Y7eK2iPR1FGHlnZdjzOHu\n", + "mask: zLwyQdPMPUFVeJjeKNJl1nyJ9OA=, code: $2b$12$RBM/q1Vu0bJy3kbYqMCymu5ojiE9bTq5Y7eK2iPR1FGHlnZdjzOHu\n", "True\n", - "mask: SB1G0mGYnu2Fy2usk08r9uTTugo=, code: $2b$12$pKJtlWu9gwXqA4b.Q/WEZ.yzz9ntnXnFSindkyVOWa3sNOoVd0LLK\n" + "mask: Q7Dw+o+qDTXYlg8TC2hOkn9r1s0=, code: $2b$12$Xp2oD/vFDHwzvBmELBxC6e.iLK4xn5ZtLwW4UCFVoFY2ioTvGaWwa\n" ] } ], - "execution_count": 85 + "execution_count": 41 }, { "metadata": {}, @@ -729,8 +726,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:03.770972Z", - "start_time": "2025-03-14T14:35:03.766802Z" + "end_time": "2025-03-16T11:17:08.424680Z", + "start_time": "2025-03-16T11:17:08.421148Z" } }, "cell_type": "code", @@ -742,7 +739,7 @@ "new_sets = customer.cipher.set_key" ], "outputs": [], - "execution_count": 86 + "execution_count": 42 }, { "metadata": {}, @@ -755,8 +752,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:03.781705Z", - "start_time": "2025-03-14T14:35:03.779309Z" + "end_time": "2025-03-16T11:17:08.434263Z", + "start_time": "2025-03-16T11:17:08.431951Z" } }, "cell_type": "code", @@ -765,11 +762,11 @@ "sets_xor = np.bitwise_xor(new_sets, old_sets)\n", "for user in customer.users.values():\n", " user.renew = True\n", - " user.cipher.set_key = np.bitwise_xor(user.cipher.set_key, sets_xor)\n", + " user.cipher.combined_set_key = np.bitwise_xor(user.cipher.combined_set_key, sets_xor)\n", " user.cipher.prop_key = np.bitwise_xor(user.cipher.prop_key, props_xor)" ], "outputs": [], - "execution_count": 87 + "execution_count": 43 }, { "metadata": {}, @@ -779,8 +776,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-03-14T14:35:04.107750Z", - "start_time": "2025-03-14T14:35:03.797025Z" + "end_time": "2025-03-16T11:17:08.683077Z", + "start_time": "2025-03-16T11:17:08.447107Z" } }, "cell_type": "code", @@ -794,7 +791,7 @@ "user.renew = False" ], "outputs": [], - "execution_count": 88 + "execution_count": 44 } ], "metadata": { diff --git a/src/customer.py b/src/customer.py index 1a8a7e8..6177ba9 100644 --- a/src/customer.py +++ b/src/customer.py @@ -58,8 +58,8 @@ class Customer: new_props = self.cipher.prop_key new_sets = self.cipher.set_key - props_xor = np.bitwise_xor(new_props, old_props) - set_xor = np.bitwise_xor(new_sets, old_sets) + props_xor = new_props ^ old_props + set_xor = new_sets ^ old_sets for user in self.users.values(): user.renew_keys(set_xor, props_xor) self.users[user.username] = user diff --git a/src/user.py b/src/user.py index 2cc565f..1ee091e 100644 --- a/src/user.py +++ b/src/user.py @@ -18,8 +18,8 @@ class User: def renew_keys(self, set_xor: np.ndarray, prop_xor: np.ndarray): self.renew = True - self.cipher.set_key = np.bitwise_xor(self.cipher.set_key, set_xor) - self.cipher.prop_key = np.bitwise_xor(self.cipher.prop_key, prop_xor) + self.cipher.combined_set_key = self.cipher.combined_set_key ^ set_xor + self.cipher.prop_key = self.cipher.prop_key ^ prop_xor def refresh_passcode(self, passcode_prop_idxs: list[int], customer_cipher: CustomerCipher): self.cipher = UserCipher.create( diff --git a/src/user_cipher.py b/src/user_cipher.py index f1513c3..5e2123a 100644 --- a/src/user_cipher.py +++ b/src/user_cipher.py @@ -11,7 +11,7 @@ from src.customer_cipher import CustomerCipher @dataclass class UserCipher: prop_key: np.ndarray - set_key: np.ndarray + combined_set_key: np.ndarray pass_key: np.ndarray mask_key: np.ndarray salt: bytes @@ -30,7 +30,7 @@ class UserCipher: prop_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), mask_key=np.random.choice(2**16, size=max_nkode_len, replace=False), - set_key=set_key, + combined_set_key=set_key, salt=bcrypt.gensalt(), max_nkode_len=max_nkode_len ) @@ -38,15 +38,11 @@ class UserCipher: def pad_user_mask(self, user_mask: np.ndarray, set_vals: np.ndarray) -> np.ndarray: if len(user_mask) >= self.max_nkode_len: raise ValueError("User mask is too long") - - user_mask_array = np.array(user_mask, 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) + # Generate padding directly using np.random.choice + padding = np.random.choice(set_vals, size=padding_size, replace=True).astype(np.uint16) # Concatenate original mask with padding - padded_user_mask = np.concatenate([user_mask_array, padding]) - return padded_user_mask + return np.concatenate([user_mask, padding]) @staticmethod def encode_base64_str(data: np.ndarray) -> str: @@ -108,7 +104,7 @@ class UserCipher: # Get indices of set values set_idx = np.array([customer_cipher.get_set_index(set_val) for set_val in padded_customer_sets], dtype=np.uint16) - mask_set_keys = np.array([self.set_key[idx] for idx in set_idx], dtype=np.uint16) + mask_set_keys = np.array([self.combined_set_key[idx] for idx in set_idx], dtype=np.uint16) # XOR operations ciphered_mask = np.bitwise_xor(mask_set_keys, padded_customer_sets) @@ -122,7 +118,7 @@ class UserCipher: decoded_mask = self.decode_base64_str(mask) deciphered_mask = np.bitwise_xor(decoded_mask, self.mask_key) - set_key_rand_component = np.bitwise_xor(set_vals_array, self.set_key) + set_key_rand_component = np.bitwise_xor(set_vals_array, self.combined_set_key) passcode_sets = [] for set_cipher in deciphered_mask[:passcode_len]: