rename attribute to property
This commit is contained in:
@@ -34,46 +34,46 @@ class Customer:
|
||||
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_selected_attributes_idx = []
|
||||
presumed_property_idxs = []
|
||||
for idx in range(passcode_len):
|
||||
key_numb = selected_keys[idx]
|
||||
set_idx = set_vals_idx[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)
|
||||
selected_attr_idx = user.user_keypad.get_prop_idx_by_keynumb_setidx(key_numb, set_idx)
|
||||
presumed_property_idxs.append(selected_attr_idx)
|
||||
|
||||
enciphered_attr = user.cipher.encipher_salt_hash_code(presumed_selected_attributes_idx, self.cipher)
|
||||
enciphered_attr = user.cipher.encipher_salt_hash_code(presumed_property_idxs, self.cipher)
|
||||
if enciphered_attr != user.enciphered_passcode.code:
|
||||
return False
|
||||
|
||||
if user.renew:
|
||||
user.refresh_passcode(presumed_selected_attributes_idx, self.cipher)
|
||||
user.refresh_passcode(presumed_property_idxs, self.cipher)
|
||||
return True
|
||||
|
||||
def renew_keys(self) -> bool:
|
||||
old_attrs = self.cipher.prop_key.copy()
|
||||
old_props = self.cipher.prop_key.copy()
|
||||
old_sets = self.cipher.set_key.copy()
|
||||
self.cipher.renew()
|
||||
new_attrs = self.cipher.prop_key
|
||||
new_props = self.cipher.prop_key
|
||||
new_sets = self.cipher.set_key
|
||||
|
||||
attrs_xor = np.bitwise_xor(new_attrs, old_attrs)
|
||||
props_xor = np.bitwise_xor(new_props, old_props)
|
||||
set_xor = np.bitwise_xor(new_sets, old_sets)
|
||||
for user in self.users.values():
|
||||
user.renew_keys(set_xor, attrs_xor)
|
||||
user.renew_keys(set_xor, props_xor)
|
||||
self.users[user.username] = user
|
||||
return True
|
||||
|
||||
def valid_new_nkode(self, passcode_attr_idx: list[int]) -> bool:
|
||||
nkode_len = len(passcode_attr_idx)
|
||||
def valid_new_nkode(self, passcode_prop_idx: list[int]) -> bool:
|
||||
nkode_len = len(passcode_prop_idx)
|
||||
passcode_set_values = [
|
||||
self.cipher.get_prop_set_val(int(self.cipher.prop_key[attr_idx])) for attr_idx in passcode_attr_idx
|
||||
self.cipher.get_prop_set_val(int(self.cipher.prop_key[prop_idx])) for prop_idx in passcode_prop_idx
|
||||
]
|
||||
distinct_sets = len(set(passcode_set_values))
|
||||
distinct_attributes = len(set(passcode_attr_idx))
|
||||
distinct_properties = len(set(passcode_prop_idx))
|
||||
if (
|
||||
self.nkode_policy.min_nkode_len <= nkode_len <= self.nkode_policy.max_nkode_len and
|
||||
distinct_sets >= self.nkode_policy.distinct_sets and
|
||||
distinct_attributes >= self.nkode_policy.distinct_attributes
|
||||
distinct_properties >= self.nkode_policy.distinct_properties
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -11,7 +11,7 @@ class NKodePolicy:
|
||||
max_nkode_len: int = 10
|
||||
min_nkode_len: int = 4
|
||||
distinct_sets: int = 0
|
||||
distinct_attributes: int = 4
|
||||
distinct_properties: int = 4
|
||||
byte_len: int = 2 # Todo: this should change the total number of bytes an attribute or set value can be
|
||||
lock_out: int = 5
|
||||
expiration: int = -1 # in seconds -1 means nkode never expires
|
||||
|
||||
@@ -107,7 +107,7 @@ class NKodeAPI:
|
||||
customer = self.customers[customer_id]
|
||||
return customer.valid_key_entry(username, key_selection)
|
||||
|
||||
def renew_attributes(self, customer_id: UUID) -> bool:
|
||||
def renew_keys(self, customer_id: UUID) -> bool:
|
||||
if customer_id not in self.customers.keys():
|
||||
raise ValueError("Customer ID not found")
|
||||
return self.customers[customer_id].renew_keys()
|
||||
|
||||
@@ -21,11 +21,11 @@ class User:
|
||||
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)
|
||||
|
||||
def refresh_passcode(self, passcode_attr_idx: list[int], customer_attributes: CustomerCipher):
|
||||
def refresh_passcode(self, passcode_prop_idxs: list[int], customer_cipher: CustomerCipher):
|
||||
self.cipher = UserCipher.create(
|
||||
customer_attributes.keypad_size,
|
||||
customer_attributes.set_key,
|
||||
customer_cipher.keypad_size,
|
||||
customer_cipher.set_key,
|
||||
self.cipher.max_nkode_len
|
||||
)
|
||||
self.enciphered_passcode = self.cipher.encipher_nkode(passcode_attr_idx, customer_attributes)
|
||||
self.enciphered_passcode = self.cipher.encipher_nkode(passcode_prop_idxs, customer_cipher)
|
||||
self.renew = False
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from dataclasses import dataclass
|
||||
import numpy as np
|
||||
from src.utils import random_property_rotation
|
||||
from src.models import KeypadSize
|
||||
|
||||
@dataclass
|
||||
@@ -54,9 +55,9 @@ class UserKeypad:
|
||||
user_keypad_matrix = self.keypad_matrix()
|
||||
#shuffled_keys = secure_fisher_yates_shuffle(user_keypad_matrix)
|
||||
shuffled_keys = rng.permutation(user_keypad_matrix, axis=0)
|
||||
#attr_rotation = secure_fisher_yates_shuffle(list(range(self.keypad_size.numb_of_keys)))[:self.keypad_size.props_per_key]
|
||||
#prop_rotation = secure_fisher_yates_shuffle(list(range(self.keypad_size.numb_of_keys)))[:self.keypad_size.props_per_key]
|
||||
attr_rotation = rng.permutation(list(range(self.keypad_size.numb_of_keys)))[:self.keypad_size.props_per_key]
|
||||
dispersed_keypad = self.random_attribute_rotation(
|
||||
dispersed_keypad = random_property_rotation(
|
||||
shuffled_keys,
|
||||
attr_rotation.tolist(),
|
||||
)
|
||||
@@ -79,21 +80,8 @@ class UserKeypad:
|
||||
#self.keypad = matrix_to_list(matrix_transpose(keypad_by_sets))
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def random_attribute_rotation(
|
||||
user_keypad: np.ndarray,
|
||||
attr_rotation: list[int]
|
||||
) -> np.ndarray:
|
||||
transposed = user_keypad.T
|
||||
if len(attr_rotation) != len(transposed):
|
||||
raise ValueError("attr_rotation must be the same length as the number of attributes")
|
||||
for idx, attr_set in enumerate(transposed):
|
||||
rotation = attr_rotation[idx]
|
||||
rotation = rotation % len(attr_set) if len(attr_set) > 0 else 0
|
||||
transposed[idx] = np.roll(attr_set, rotation)
|
||||
return transposed.T
|
||||
|
||||
def attribute_adjacency_graph(self) -> dict[int, set[int]]:
|
||||
def property_adjacency_graph(self) -> dict[int, set[int]]:
|
||||
user_keypad_keypad = self.keypad_matrix()
|
||||
graph = {}
|
||||
for key in user_keypad_keypad:
|
||||
@@ -102,7 +90,7 @@ class UserKeypad:
|
||||
graph[attr].remove(attr)
|
||||
return graph
|
||||
|
||||
def get_attr_idx_by_keynumb_setidx(self, key_numb: int, set_idx: int) -> int:
|
||||
def get_prop_idx_by_keynumb_setidx(self, key_numb: int, set_idx: int) -> int:
|
||||
if not (0 <= key_numb < self.keypad_size.numb_of_keys):
|
||||
raise ValueError(f"key_numb must be between 0 and {self.keypad_size.numb_of_keys - 1}")
|
||||
if not (0 <= set_idx < self.keypad_size.props_per_key):
|
||||
|
||||
14
src/utils.py
Normal file
14
src/utils.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import numpy as np
|
||||
|
||||
def random_property_rotation(
|
||||
user_keypad: np.ndarray,
|
||||
attr_rotation: list[int]
|
||||
) -> np.ndarray:
|
||||
transposed = user_keypad.T
|
||||
if len(attr_rotation) != len(transposed):
|
||||
raise ValueError("prop_rotation must be the same length as the number of attributes")
|
||||
for idx, attr_set in enumerate(transposed):
|
||||
rotation = attr_rotation[idx]
|
||||
rotation = rotation % len(attr_set) if len(attr_set) > 0 else 0
|
||||
transposed[idx] = np.roll(attr_set, rotation)
|
||||
return transposed.T
|
||||
Reference in New Issue
Block a user