implement split shuffle
This commit is contained in:
@@ -22,32 +22,25 @@ class Customer:
|
||||
def valid_key_entry(self, username, selected_keys) -> bool:
|
||||
if username not in self.users:
|
||||
raise ValueError(f"User '{username}' does not exist")
|
||||
|
||||
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):
|
||||
raise ValueError(f"Invalid key indices. Must be between 0 and {numb_of_keys - 1}")
|
||||
|
||||
passcode_len = len(selected_keys)
|
||||
user = self.users[username]
|
||||
|
||||
passcode_set_vals = user.cipher.decipher_mask(
|
||||
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]
|
||||
|
||||
presumed_property_idxs = []
|
||||
for idx in range(passcode_len):
|
||||
key_numb = selected_keys[idx]
|
||||
set_idx = set_vals_idx[idx]
|
||||
selected_prop_idx = user.user_keypad.get_prop_idx_by_keynumb_setidx(key_numb, set_idx)
|
||||
presumed_property_idxs.append(selected_prop_idx)
|
||||
|
||||
if not user.cipher.compare_nkode(presumed_property_idxs, self.cipher,user.enciphered_passcode.code):
|
||||
return False
|
||||
|
||||
if user.renew:
|
||||
user.refresh_passcode(presumed_property_idxs, self.cipher)
|
||||
|
||||
user.user_keypad.partial_keypad_shuffle()
|
||||
user.user_keypad.split_shuffle()
|
||||
return True
|
||||
|
||||
def renew_keys(self) -> bool:
|
||||
|
||||
@@ -62,22 +62,12 @@ class UserKeypad:
|
||||
)
|
||||
self.keypad = dispersed_keypad.reshape(-1)
|
||||
|
||||
def partial_keypad_shuffle(self):
|
||||
# TODO: this should be split shuffle
|
||||
#numb_of_selected_sets = self.keypad_size.props_per_key // 2
|
||||
## randomly shuffle half the sets. if props_per_key is odd, randomly add one 50% of the time
|
||||
#numb_of_selected_sets += choice([0, 1]) if (self.keypad_size.props_per_key & 1) == 1 else 0
|
||||
#selected_sets = secure_fisher_yates_shuffle(list(range(self.keypad_size.props_per_key)))[:numb_of_selected_sets]
|
||||
#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 split_shuffle(self):
|
||||
prop_permutation = np.random.permutation(self.keypad_size.props_per_key)[: self.keypad_size.props_per_key // 2]
|
||||
key_permutation = np.random.permutation(self.keypad_size.numb_of_keys)
|
||||
keypad_view = self.keypad_matrix().copy()
|
||||
keypad_view[:, prop_permutation] = keypad_view[key_permutation, :][:, prop_permutation]
|
||||
self.keypad = keypad_view.reshape(-1)
|
||||
|
||||
def property_adjacency_graph(self) -> dict[int, set[int]]:
|
||||
user_keypad_keypad = self.keypad_matrix()
|
||||
|
||||
@@ -5,7 +5,7 @@ from src.models import KeypadSize
|
||||
|
||||
@pytest.fixture()
|
||||
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):
|
||||
@@ -17,19 +17,19 @@ def test_dispersion(user_keypad):
|
||||
assert (adj_graph.isdisjoint(post_dispersion_graph[prop]))
|
||||
|
||||
|
||||
#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
|
||||
# expected statistical outcomes like:
|
||||
# - every property gets to every key with a 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)
|
||||
# """
|
||||
# pre_shuffle_keypad = user_keypad.keypad
|
||||
# user_keypad.partial_keypad_shuffle()
|
||||
# post_shuffle_keypad = user_keypad.keypad
|
||||
# assert (not all(
|
||||
# post_shuffle_keypad[idx] == pre_shuffle_keypad[idx] for idx in range(len(post_shuffle_keypad))
|
||||
# ))
|
||||
# assert (not all(
|
||||
# post_shuffle_keypad[idx] != pre_shuffle_keypad[idx] for idx in range(len(post_shuffle_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
|
||||
expected statistical outcomes like:
|
||||
- every property gets to every key with a 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)
|
||||
"""
|
||||
pre_shuffle_keypad = user_keypad.keypad.copy()
|
||||
user_keypad.split_shuffle()
|
||||
post_shuffle_keypad = user_keypad.keypad.copy()
|
||||
assert (not all(
|
||||
post_shuffle_keypad[idx] == pre_shuffle_keypad[idx] for idx in range(len(post_shuffle_keypad))
|
||||
))
|
||||
assert (not all(
|
||||
post_shuffle_keypad[idx] != pre_shuffle_keypad[idx] for idx in range(len(post_shuffle_keypad))
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user