implement split shuffle

This commit is contained in:
2025-03-16 13:26:45 -05:00
parent 2a19aa73c4
commit fb650a4086
3 changed files with 24 additions and 41 deletions

View File

@@ -22,32 +22,25 @@ class Customer:
def valid_key_entry(self, username, selected_keys) -> bool: def valid_key_entry(self, username, selected_keys) -> bool:
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.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.cipher.decipher_mask( passcode_set_vals = user.cipher.decipher_mask(
user.enciphered_passcode.mask, self.cipher.set_key, passcode_len) user.enciphered_passcode.mask, self.cipher.set_key, passcode_len)
set_vals_idx = [self.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_property_idxs = [] presumed_property_idxs = []
for idx in range(passcode_len): for idx in range(passcode_len):
key_numb = selected_keys[idx] key_numb = selected_keys[idx]
set_idx = set_vals_idx[idx] set_idx = set_vals_idx[idx]
selected_prop_idx = user.user_keypad.get_prop_idx_by_keynumb_setidx(key_numb, set_idx) selected_prop_idx = user.user_keypad.get_prop_idx_by_keynumb_setidx(key_numb, set_idx)
presumed_property_idxs.append(selected_prop_idx) presumed_property_idxs.append(selected_prop_idx)
if not user.cipher.compare_nkode(presumed_property_idxs, self.cipher,user.enciphered_passcode.code): if not user.cipher.compare_nkode(presumed_property_idxs, self.cipher,user.enciphered_passcode.code):
return False return False
if user.renew: if user.renew:
user.refresh_passcode(presumed_property_idxs, self.cipher) user.refresh_passcode(presumed_property_idxs, self.cipher)
user.user_keypad.split_shuffle()
user.user_keypad.partial_keypad_shuffle()
return True return True
def renew_keys(self) -> bool: def renew_keys(self) -> bool:

View File

@@ -62,22 +62,12 @@ class UserKeypad:
) )
self.keypad = dispersed_keypad.reshape(-1) self.keypad = dispersed_keypad.reshape(-1)
def partial_keypad_shuffle(self): def split_shuffle(self):
# TODO: this should be split shuffle prop_permutation = np.random.permutation(self.keypad_size.props_per_key)[: self.keypad_size.props_per_key // 2]
#numb_of_selected_sets = self.keypad_size.props_per_key // 2 key_permutation = np.random.permutation(self.keypad_size.numb_of_keys)
## randomly shuffle half the sets. if props_per_key is odd, randomly add one 50% of the time keypad_view = self.keypad_matrix().copy()
#numb_of_selected_sets += choice([0, 1]) if (self.keypad_size.props_per_key & 1) == 1 else 0 keypad_view[:, prop_permutation] = keypad_view[key_permutation, :][:, prop_permutation]
#selected_sets = secure_fisher_yates_shuffle(list(range(self.keypad_size.props_per_key)))[:numb_of_selected_sets] self.keypad = keypad_view.reshape(-1)
#user_keypad_matrix = self.keypad_matrix()
#shuffled_keys = secure_fisher_yates_shuffle(user_keypad_matrix)
#keypad_by_sets = []
#for idx, props in enumerate(matrix_transpose(shuffled_keys)):
# if idx in selected_sets:
# keypad_by_sets.append(secure_fisher_yates_shuffle(props))
# else:
# keypad_by_sets.append(props)
#self.keypad = matrix_to_list(matrix_transpose(keypad_by_sets))
pass
def property_adjacency_graph(self) -> dict[int, set[int]]: def property_adjacency_graph(self) -> dict[int, set[int]]:
user_keypad_keypad = self.keypad_matrix() user_keypad_keypad = self.keypad_matrix()

View File

@@ -5,7 +5,7 @@ from src.models import KeypadSize
@pytest.fixture() @pytest.fixture()
def user_keypad(): def user_keypad():
return UserKeypad.create(keypad_size=KeypadSize(props_per_key=7, numb_of_keys=10)) return UserKeypad.create(keypad_size=KeypadSize(props_per_key=8, numb_of_keys=8))
def test_dispersion(user_keypad): def test_dispersion(user_keypad):
@@ -17,19 +17,19 @@ def test_dispersion(user_keypad):
assert (adj_graph.isdisjoint(post_dispersion_graph[prop])) assert (adj_graph.isdisjoint(post_dispersion_graph[prop]))
#def test_shuffle_props(user_keypad): def test_shuffle_props(user_keypad):
# """there's no easy way to test this. At some point we'll have to run this code thousands of time to see if we get """there's no easy way to test this. At some point we'll have to run this code thousands of time to see if we get
# expected statistical outcomes like: expected statistical outcomes like:
# - every property gets to every key with a uniform distribution - every property gets to every key with a uniform distribution
# - every property is adjacent to every other property with uniform distribution - every property is adjacent to every other property with uniform distribution
# - the order in which the 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.copy()
# user_keypad.partial_keypad_shuffle() user_keypad.split_shuffle()
# post_shuffle_keypad = user_keypad.keypad post_shuffle_keypad = user_keypad.keypad.copy()
# assert (not all( assert (not all(
# post_shuffle_keypad[idx] == pre_shuffle_keypad[idx] for idx in range(len(post_shuffle_keypad)) post_shuffle_keypad[idx] == pre_shuffle_keypad[idx] for idx in range(len(post_shuffle_keypad))
# )) ))
# assert (not all( assert (not all(
# post_shuffle_keypad[idx] != pre_shuffle_keypad[idx] for idx in range(len(post_shuffle_keypad)) post_shuffle_keypad[idx] != pre_shuffle_keypad[idx] for idx in range(len(post_shuffle_keypad))
# )) ))