fix bugs
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
from dataclasses import dataclass
|
||||
from uuid import UUID
|
||||
import numpy as np
|
||||
from uuid import UUID, uuid4
|
||||
from src.customer_cipher import CustomerCipher
|
||||
from src.models import NKodePolicy
|
||||
from src.user import User
|
||||
@@ -12,7 +11,18 @@ class Customer:
|
||||
cipher: CustomerCipher
|
||||
users: dict[str, User]
|
||||
|
||||
# TODO: validate policy and keypad_list size don't conflict
|
||||
@classmethod
|
||||
def create(cls, nkode_policy: NKodePolicy, cipher: CustomerCipher) -> 'Customer':
|
||||
if nkode_policy.distinct_sets > cipher.keypad_size.numb_of_keys:
|
||||
raise ValueError("Distinct sets cannot be greater than the number of keys")
|
||||
if nkode_policy.distinct_properties > cipher.keypad_size.total_props:
|
||||
raise ValueError("Distinct properties cannot be greater than the total number of properties")
|
||||
return Customer(
|
||||
customer_id=uuid4(),
|
||||
nkode_policy=nkode_policy,
|
||||
cipher=cipher,
|
||||
users={}
|
||||
)
|
||||
|
||||
def add_new_user(self, user: User):
|
||||
if user.username in self.users:
|
||||
@@ -30,17 +40,13 @@ class Customer:
|
||||
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)
|
||||
presumed_property_idxs = user.user_keypad.get_prop_idxs_by_keynumb_setidx(selected_keys, set_vals_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.split_shuffle()
|
||||
#self.users[username] = user
|
||||
return True
|
||||
|
||||
def renew_keys(self) -> bool:
|
||||
|
||||
@@ -12,9 +12,9 @@ class NKodePolicy:
|
||||
min_nkode_len: int = 4
|
||||
distinct_sets: int = 0
|
||||
distinct_properties: int = 4
|
||||
byte_len: int = 2 # Todo: this should change the total number of bytes an properities 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
|
||||
expiration: int = -1 # in seconds -1 means nkode never expires
|
||||
expiration: int = -1 # in seconds -1 means nKode never expires
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -16,10 +16,8 @@ class NKodeAPI:
|
||||
signup_sessions: dict[UUID, UserSignupSession] = field(default_factory=dict)
|
||||
|
||||
def create_new_customer(self, keypad_size: KeypadSize, nkode_policy: NKodePolicy) -> UUID:
|
||||
new_customer = Customer(
|
||||
customer_id=uuid4(),
|
||||
new_customer = Customer.create(
|
||||
cipher=CustomerCipher.create(keypad_size),
|
||||
users={},
|
||||
nkode_policy=nkode_policy
|
||||
)
|
||||
self.customers[new_customer.customer_id] = new_customer
|
||||
@@ -97,7 +95,6 @@ class NKodeAPI:
|
||||
if username not in customer.users.keys():
|
||||
raise ValueError("Username not found")
|
||||
user = customer.users[username]
|
||||
# user.user_keypad.partial_keypad_shuffle()
|
||||
# TODO: implement split_keypad_shuffle()
|
||||
return user.user_keypad.keypad
|
||||
|
||||
|
||||
@@ -105,8 +105,7 @@ class UserCipher:
|
||||
customer_props = customer_cipher.prop_key[passcode_prop_idx]
|
||||
customer_sets = [customer_cipher.get_prop_set_val(prop) for prop in customer_props]
|
||||
padded_customer_sets = self.pad_user_mask(np.array(customer_sets), customer_cipher.set_key)
|
||||
set_idx = np.array([customer_cipher.get_set_index(set_val) for set_val in padded_customer_sets],
|
||||
dtype=np.uint16)
|
||||
set_idx = [customer_cipher.get_set_index(set_val) for set_val in padded_customer_sets]
|
||||
ordered_set_key = self.combined_set_key[set_idx]
|
||||
mask = ordered_set_key ^ padded_customer_sets ^ self.mask_key
|
||||
encoded_mask = self.encode_base64_str(mask)
|
||||
|
||||
@@ -23,11 +23,11 @@ class UserKeypad:
|
||||
self.random_keypad_shuffle()
|
||||
keypad_matrix = self.keypad_matrix()
|
||||
prop_set_view = keypad_matrix.T
|
||||
prop_set_view = np.random.permutation(prop_set_view)
|
||||
prop_set_view = prop_set_view[:self.keypad_size.numb_of_keys]
|
||||
keypad_matrix = prop_set_view.reshape(-1)
|
||||
random_sets = np.random.permutation(self.keypad_size.props_per_key)[: self.keypad_size.numb_of_keys]
|
||||
random_sets.sort()
|
||||
prop_set_view = prop_set_view[random_sets, :]
|
||||
return UserKeypad(
|
||||
keypad=keypad_matrix.reshape(-1),
|
||||
keypad=prop_set_view.T.reshape(-1),
|
||||
keypad_size=KeypadSize(
|
||||
numb_of_keys=self.keypad_size.numb_of_keys,
|
||||
props_per_key=self.keypad_size.numb_of_keys
|
||||
@@ -38,23 +38,20 @@ class UserKeypad:
|
||||
return self.keypad.reshape(-1,self.keypad_size.props_per_key)
|
||||
|
||||
def random_keypad_shuffle(self):
|
||||
rng = np.random.default_rng()
|
||||
keypad_view = self.keypad_matrix()
|
||||
rng.shuffle(keypad_view, axis=0)
|
||||
np.random.shuffle(keypad_view)
|
||||
set_view = keypad_view.T
|
||||
set_view = rng.permutation(set_view, axis=1)
|
||||
keypad_view = set_view.T
|
||||
self.keypad = keypad_view.reshape(-1)
|
||||
for prop_set in set_view:
|
||||
np.random.shuffle(prop_set)
|
||||
self.keypad = set_view.T.reshape(-1)
|
||||
|
||||
def disperse_keypad(self):
|
||||
# TODO: clean this up
|
||||
if not self.keypad_size.is_dispersable:
|
||||
raise ValueError("Keypad size is not dispersable")
|
||||
rng = np.random.default_rng()
|
||||
#user_keypad_matrix = list_to_matrix(self.keypad, self.keypad_size.props_per_key)
|
||||
user_keypad_matrix = self.keypad_matrix()
|
||||
#shuffled_keys = secure_fisher_yates_shuffle(user_keypad_matrix)
|
||||
shuffled_keys = rng.permutation(user_keypad_matrix, axis=0)
|
||||
#prop_rotation = secure_fisher_yates_shuffle(list(range(self.keypad_size.numb_of_keys)))[:self.keypad_size.props_per_key]
|
||||
prop_rotation = rng.permutation(list(range(self.keypad_size.numb_of_keys)))[:self.keypad_size.props_per_key]
|
||||
dispersed_keypad = random_property_rotation(
|
||||
shuffled_keys,
|
||||
@@ -89,3 +86,13 @@ class UserKeypad:
|
||||
raise ValueError(f"set_idx must be between 0 and {self.keypad_size.props_per_key - 1}")
|
||||
keypad_prop_idx = self.keypad_matrix()
|
||||
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]:
|
||||
if len(key_numb) != len(set_idx):
|
||||
raise ValueError("key_numb and set_idx must be the same length")
|
||||
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}")
|
||||
if not all(0 <= si < self.keypad_size.props_per_key for si in set_idx):
|
||||
raise ValueError(f"All set_idx must be between 0 and {self.keypad_size.props_per_key - 1}")
|
||||
keypad_matrix = self.keypad_matrix()
|
||||
return keypad_matrix[key_numb, set_idx].reshape(-1).tolist()
|
||||
|
||||
@@ -11,6 +11,7 @@ class UserSignupSession:
|
||||
customer_id: UUID
|
||||
login_keypad: UserKeypad
|
||||
keypad_size: KeypadSize
|
||||
# TODO: revert back to list[int]
|
||||
set_keypad: Optional[np.ndarray] = None
|
||||
confirm_keypad: Optional[np.ndarray] = None
|
||||
set_key_entry: Optional[np.ndarray] = None
|
||||
|
||||
Reference in New Issue
Block a user