refactor customer interface to attributes
This commit is contained in:
22
nkode_api.py
22
nkode_api.py
@@ -7,7 +7,7 @@ from src.user import User
|
|||||||
from src.user_cipher_keys import UserCipherKeys
|
from src.user_cipher_keys import UserCipherKeys
|
||||||
from src.user_signup_session import UserSignupSession
|
from src.user_signup_session import UserSignupSession
|
||||||
from src.user_interface import UserInterface
|
from src.user_interface import UserInterface
|
||||||
from src.customer_interface import CustomerInterface
|
from src.customer_attributes import CustomerAttributes
|
||||||
|
|
||||||
|
|
||||||
class NKodeAPI(BaseModel):
|
class NKodeAPI(BaseModel):
|
||||||
@@ -17,7 +17,7 @@ class NKodeAPI(BaseModel):
|
|||||||
def create_new_customer(self, keypad_size: KeypadSize, nkode_policy: NKodePolicy) -> UUID:
|
def create_new_customer(self, keypad_size: KeypadSize, nkode_policy: NKodePolicy) -> UUID:
|
||||||
new_customer = Customer(
|
new_customer = Customer(
|
||||||
customer_id=uuid4(),
|
customer_id=uuid4(),
|
||||||
interface=CustomerInterface.new(keypad_size),
|
attributes=CustomerAttributes.new(keypad_size),
|
||||||
users={},
|
users={},
|
||||||
nkode_policy=nkode_policy
|
nkode_policy=nkode_policy
|
||||||
)
|
)
|
||||||
@@ -28,12 +28,12 @@ class NKodeAPI(BaseModel):
|
|||||||
def generate_index_interface(self, customer_id: UUID) -> tuple[UUID, list[int]]:
|
def generate_index_interface(self, customer_id: UUID) -> tuple[UUID, list[int]]:
|
||||||
assert (customer_id in self.customers.keys())
|
assert (customer_id in self.customers.keys())
|
||||||
customer = self.customers[customer_id]
|
customer = self.customers[customer_id]
|
||||||
set_interface = UserInterface.new(customer.interface.keypad_size)
|
set_interface = UserInterface.new(customer.attributes.keypad_size)
|
||||||
new_session = UserSignupSession(
|
new_session = UserSignupSession(
|
||||||
session_id=uuid4(),
|
session_id=uuid4(),
|
||||||
set_interface=set_interface.attr_indices,
|
set_interface=set_interface.interface,
|
||||||
customer_id=customer_id,
|
customer_id=customer_id,
|
||||||
keypad_size=customer.interface.keypad_size,
|
keypad_size=customer.attributes.keypad_size,
|
||||||
)
|
)
|
||||||
self.signup_sessions[new_session.session_id] = new_session
|
self.signup_sessions[new_session.session_id] = new_session
|
||||||
return new_session.session_id, new_session.set_interface
|
return new_session.session_id, new_session.set_interface
|
||||||
@@ -61,19 +61,19 @@ class NKodeAPI(BaseModel):
|
|||||||
|
|
||||||
passcode = self.signup_sessions[session_id].deduce_passcode(confirm_key_entry)
|
passcode = self.signup_sessions[session_id].deduce_passcode(confirm_key_entry)
|
||||||
new_user_keys = UserCipherKeys.new(
|
new_user_keys = UserCipherKeys.new(
|
||||||
customer.interface.keypad_size,
|
customer.attributes.keypad_size,
|
||||||
customer.interface.set_vals,
|
customer.attributes.set_vals,
|
||||||
customer.nkode_policy.max_nkode_len
|
customer.nkode_policy.max_nkode_len
|
||||||
)
|
)
|
||||||
|
|
||||||
enciphered_passcode = new_user_keys.encipher_nkode(passcode, customer.interface)
|
enciphered_passcode = new_user_keys.encipher_nkode(passcode, customer.attributes)
|
||||||
new_user = User(
|
new_user = User(
|
||||||
username=username,
|
username=username,
|
||||||
enciphered_passcode=enciphered_passcode,
|
enciphered_passcode=enciphered_passcode,
|
||||||
user_keys=new_user_keys,
|
user_keys=new_user_keys,
|
||||||
user_interface=UserInterface(
|
user_interface=UserInterface(
|
||||||
attr_indices=self.signup_sessions[session_id].confirm_interface,
|
interface=self.signup_sessions[session_id].confirm_interface,
|
||||||
keypad_size=customer.interface.keypad_size
|
keypad_size=customer.attributes.keypad_size
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self.customers[customer_id].add_new_user(new_user)
|
self.customers[customer_id].add_new_user(new_user)
|
||||||
@@ -89,7 +89,7 @@ class NKodeAPI(BaseModel):
|
|||||||
assert (username in customer.users.keys())
|
assert (username in customer.users.keys())
|
||||||
user = customer.users[username]
|
user = customer.users[username]
|
||||||
user.user_interface.shuffle_interface()
|
user.user_interface.shuffle_interface()
|
||||||
return user.user_interface.attr_indices
|
return user.user_interface.interface
|
||||||
|
|
||||||
def login(self, customer_id: UUID, username: str, key_selection: list[int]) -> bool:
|
def login(self, customer_id: UUID, username: str, key_selection: list[int]) -> bool:
|
||||||
assert (customer_id in self.customers.keys())
|
assert (customer_id in self.customers.keys())
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 1,
|
"execution_count": 11,
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from nkode_api import NKodeAPI\n",
|
"from nkode_api import NKodeAPI\n",
|
||||||
@@ -14,14 +14,14 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:32.636706Z",
|
"end_time": "2024-07-19T19:42:26.168590Z",
|
||||||
"start_time": "2024-07-19T15:38:32.541836Z"
|
"start_time": "2024-07-19T19:42:26.080917Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 2,
|
"execution_count": 12,
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"def random_username() -> str:\n",
|
"def random_username() -> str:\n",
|
||||||
@@ -40,14 +40,14 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:32.636920Z",
|
"end_time": "2024-07-19T19:42:26.169484Z",
|
||||||
"start_time": "2024-07-19T15:38:32.606667Z"
|
"start_time": "2024-07-19T19:42:26.084626Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 3,
|
"execution_count": 13,
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"api = NKodeAPI()"
|
"api = NKodeAPI()"
|
||||||
@@ -55,8 +55,8 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:32.636991Z",
|
"end_time": "2024-07-19T19:42:26.169561Z",
|
||||||
"start_time": "2024-07-19T15:38:32.608558Z"
|
"start_time": "2024-07-19T19:42:26.087253Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 4,
|
"execution_count": 14,
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"policy = NKodePolicy(\n",
|
"policy = NKodePolicy(\n",
|
||||||
@@ -98,8 +98,8 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:32.817740Z",
|
"end_time": "2024-07-19T19:42:26.266945Z",
|
||||||
"start_time": "2024-07-19T15:38:32.612174Z"
|
"start_time": "2024-07-19T19:42:26.091559Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -126,28 +126,28 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 5,
|
"execution_count": 16,
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Customer Sets: [63949, 41634, 17125, 52762, 13459, 5935, 727]\n",
|
"Customer Sets: [36939, 30293, 19380, 1964, 37282, 10031, 35065]\n",
|
||||||
"Customer Attributes: [52222, 57050, 17039, 29896, 31069, 35859, 36843, 2137, 24380, 34643, 29053, 46327, 39534, 64877, 53617, 14001, 39532, 19103, 38549, 42982, 63429, 11337, 42520, 23186, 49849, 6237, 49291, 44219, 34592, 26781, 25410, 34134, 51292, 40084, 49002, 1221, 30724, 62975, 33074, 22158, 18970, 54242, 15906, 19581, 10796, 6147, 36402, 44152, 43216, 16186, 571, 32657, 20955, 10260, 51931, 46321, 40259, 1905, 14430, 48389, 35797, 48564, 32173, 50142, 65402, 11082, 39195, 46929, 18113, 52721]\n"
|
"Customer Attributes: [3505, 54543, 45347, 44748, 53903, 52815, 60524, 9975, 48764, 34550, 64903, 32542, 23911, 35423, 63534, 65510, 21500, 37871, 19901, 6884, 255, 17031, 63424, 28925, 34144, 42192, 31390, 40124, 17254, 48729, 39518, 57631, 43182, 61064, 4422, 53465, 55843, 37538, 60243, 21929, 51240, 24244, 27507, 57663, 45226, 31543, 58101, 37770, 62668, 49947, 64348, 20373, 64786, 14379, 13970, 11323, 3662, 62709, 37802, 27817, 60687, 22963, 42846, 3620, 9784, 48482, 13855, 60342, 34564, 45989]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"set_vals = customer.interface.set_vals\n",
|
"set_vals = customer.attributes.set_vals\n",
|
||||||
"attr_vals = customer.interface.attr_vals\n",
|
"attr_vals = customer.attributes.attr_vals\n",
|
||||||
"print(f\"Customer Sets: {set_vals}\")\n",
|
"print(f\"Customer Sets: {set_vals}\")\n",
|
||||||
"print(f\"Customer Attributes: {attr_vals}\")"
|
"print(f\"Customer Attributes: {attr_vals}\")"
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:32.818026Z",
|
"end_time": "2024-07-19T19:42:43.930527Z",
|
||||||
"start_time": "2024-07-19T15:38:32.781094Z"
|
"start_time": "2024-07-19T19:42:43.924673Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -162,20 +162,20 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 6,
|
"execution_count": 17,
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Set to Attribute Map:\n",
|
"Set to Attribute Map:\n",
|
||||||
"63949: [52222, 2137, 53617, 11337, 34592, 1221, 15906, 16186, 40259, 50142]\n",
|
"36939: [3505, 9975, 63534, 17031, 17254, 53465, 27507, 49947, 3662, 3620]\n",
|
||||||
"41634: [57050, 24380, 14001, 42520, 26781, 30724, 19581, 571, 1905, 65402]\n",
|
"30293: [54543, 48764, 65510, 63424, 48729, 55843, 57663, 64348, 62709, 9784]\n",
|
||||||
"17125: [17039, 34643, 39532, 23186, 25410, 62975, 10796, 32657, 14430, 11082]\n",
|
"19380: [45347, 34550, 21500, 28925, 39518, 37538, 45226, 20373, 37802, 48482]\n",
|
||||||
"52762: [29896, 29053, 19103, 49849, 34134, 33074, 6147, 20955, 48389, 39195]\n",
|
"1964: [44748, 64903, 37871, 34144, 57631, 60243, 31543, 64786, 27817, 13855]\n",
|
||||||
"13459: [31069, 46327, 38549, 6237, 51292, 22158, 36402, 10260, 35797, 46929]\n",
|
"37282: [53903, 32542, 19901, 42192, 43182, 21929, 58101, 14379, 60687, 60342]\n",
|
||||||
"5935: [35859, 39534, 42982, 49291, 40084, 18970, 44152, 51931, 48564, 18113]\n",
|
"10031: [52815, 23911, 6884, 31390, 61064, 51240, 37770, 13970, 22963, 34564]\n",
|
||||||
"727: [36843, 64877, 63429, 44219, 49002, 54242, 43216, 46321, 32173, 52721]\n"
|
"35065: [60524, 35423, 255, 40124, 4422, 24244, 62668, 11323, 42846, 45989]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -190,8 +190,8 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:32.818150Z",
|
"end_time": "2024-07-19T19:42:46.177582Z",
|
||||||
"start_time": "2024-07-19T15:38:32.784103Z"
|
"start_time": "2024-07-19T19:42:46.173094Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -215,7 +215,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 7,
|
"execution_count": 18,
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"session_id, signup_interface = api.generate_index_interface(customer_id)"
|
"session_id, signup_interface = api.generate_index_interface(customer_id)"
|
||||||
@@ -223,8 +223,8 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:32.818223Z",
|
"end_time": "2024-07-19T19:42:47.644598Z",
|
||||||
"start_time": "2024-07-19T15:38:32.787316Z"
|
"start_time": "2024-07-19T19:42:47.640134Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -240,25 +240,25 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 8,
|
"execution_count": 19,
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Keypad View\n",
|
"Keypad View\n",
|
||||||
"Key 0: [14, 50, 16, 59, 39, 26, 6]\n",
|
"Key 0: [63, 1, 16, 59, 32, 19, 34]\n",
|
||||||
"Key 1: [56, 36, 37, 52, 18, 47, 41]\n",
|
"Key 1: [49, 57, 65, 66, 4, 47, 48]\n",
|
||||||
"Key 2: [49, 43, 2, 66, 60, 54, 69]\n",
|
"Key 2: [28, 50, 58, 10, 11, 5, 27]\n",
|
||||||
"Key 3: [7, 8, 44, 3, 11, 68, 13]\n",
|
"Key 3: [21, 43, 51, 52, 25, 68, 41]\n",
|
||||||
"Key 4: [63, 57, 65, 45, 53, 12, 48]\n",
|
"Key 4: [7, 64, 2, 38, 60, 54, 62]\n",
|
||||||
"Key 5: [0, 22, 23, 10, 4, 40, 20]\n",
|
"Key 5: [56, 29, 23, 31, 67, 61, 20]\n",
|
||||||
"Key 6: [35, 15, 51, 31, 67, 5, 55]\n",
|
"Key 6: [42, 15, 9, 24, 53, 26, 13]\n",
|
||||||
"Key 7: [42, 29, 9, 38, 32, 33, 62]\n",
|
"Key 7: [14, 36, 30, 45, 46, 33, 69]\n",
|
||||||
"Key 8: [21, 1, 58, 24, 46, 19, 34]\n",
|
"Key 8: [0, 22, 44, 17, 39, 40, 55]\n",
|
||||||
"Key 9: [28, 64, 30, 17, 25, 61, 27]\n",
|
"Key 9: [35, 8, 37, 3, 18, 12, 6]\n",
|
||||||
"Selected Keys\n",
|
"Selected Keys\n",
|
||||||
"[4, 2, 1, 9]\n"
|
"[9, 4, 3, 2]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -272,32 +272,32 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:32.818320Z",
|
"end_time": "2024-07-19T19:42:48.948115Z",
|
||||||
"start_time": "2024-07-19T15:38:32.791137Z"
|
"start_time": "2024-07-19T19:42:48.942682Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 9,
|
"execution_count": 20,
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Keypad View\n",
|
"Keypad View\n",
|
||||||
"Key 0: [7, 29, 51, 66, 53, 47, 27]\n",
|
"Key 0: [49, 22, 23, 59, 11, 12, 62]\n",
|
||||||
"Key 1: [21, 15, 2, 59, 18, 33, 20]\n",
|
"Key 1: [42, 64, 44, 52, 46, 5, 6]\n",
|
||||||
"Key 2: [63, 43, 16, 17, 32, 5, 13]\n",
|
"Key 2: [56, 8, 2, 66, 32, 33, 27]\n",
|
||||||
"Key 3: [56, 50, 30, 10, 67, 54, 34]\n",
|
"Key 3: [0, 50, 37, 24, 25, 19, 69]\n",
|
||||||
"Key 4: [42, 64, 23, 3, 60, 26, 48]\n",
|
"Key 4: [7, 36, 58, 31, 4, 68, 34]\n",
|
||||||
"Key 5: [35, 22, 44, 24, 39, 61, 41]\n",
|
"Key 5: [35, 1, 30, 17, 53, 47, 41]\n",
|
||||||
"Key 6: [49, 8, 58, 45, 25, 40, 62]\n",
|
"Key 6: [28, 43, 16, 38, 67, 26, 48]\n",
|
||||||
"Key 7: [14, 1, 65, 52, 4, 68, 55]\n",
|
"Key 7: [14, 57, 51, 3, 39, 61, 13]\n",
|
||||||
"Key 8: [28, 57, 37, 38, 11, 19, 69]\n",
|
"Key 8: [63, 15, 65, 10, 60, 40, 20]\n",
|
||||||
"Key 9: [0, 36, 9, 31, 46, 12, 6]\n",
|
"Key 9: [21, 29, 9, 45, 18, 54, 55]\n",
|
||||||
"Selected Keys\n",
|
"Selected Keys\n",
|
||||||
"[9, 1, 7, 8]\n"
|
"[0, 2, 1, 6]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -310,8 +310,8 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:32.818413Z",
|
"end_time": "2024-07-19T19:42:49.532737Z",
|
||||||
"start_time": "2024-07-19T15:38:32.794201Z"
|
"start_time": "2024-07-19T19:42:49.528687Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -329,7 +329,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 10,
|
"execution_count": 21,
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
@@ -337,16 +337,16 @@
|
|||||||
"text": [
|
"text": [
|
||||||
"Set Interface\n",
|
"Set Interface\n",
|
||||||
"Keypad View\n",
|
"Keypad View\n",
|
||||||
"Key 0: [14, 50, 16, 59, 39, 26, 6]\n",
|
"Key 0: [63, 1, 16, 59, 32, 19, 34]\n",
|
||||||
"Key 1: [56, 36, 37, 52, 18, 47, 41]\n",
|
"Key 1: [49, 57, 65, 66, 4, 47, 48]\n",
|
||||||
"Key 2: [49, 43, 2, 66, 60, 54, 69]\n",
|
"Key 2: [28, 50, 58, 10, 11, 5, 27]\n",
|
||||||
"Key 3: [7, 8, 44, 3, 11, 68, 13]\n",
|
"Key 3: [21, 43, 51, 52, 25, 68, 41]\n",
|
||||||
"Key 4: [63, 57, 65, 45, 53, 12, 48]\n",
|
"Key 4: [7, 64, 2, 38, 60, 54, 62]\n",
|
||||||
"Key 5: [0, 22, 23, 10, 4, 40, 20]\n",
|
"Key 5: [56, 29, 23, 31, 67, 61, 20]\n",
|
||||||
"Key 6: [35, 15, 51, 31, 67, 5, 55]\n",
|
"Key 6: [42, 15, 9, 24, 53, 26, 13]\n",
|
||||||
"Key 7: [42, 29, 9, 38, 32, 33, 62]\n",
|
"Key 7: [14, 36, 30, 45, 46, 33, 69]\n",
|
||||||
"Key 8: [21, 1, 58, 24, 46, 19, 34]\n",
|
"Key 8: [0, 22, 44, 17, 39, 40, 55]\n",
|
||||||
"Key 9: [28, 64, 30, 17, 25, 61, 27]\n"
|
"Key 9: [35, 8, 37, 3, 18, 12, 6]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -357,14 +357,14 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:32.818504Z",
|
"end_time": "2024-07-19T19:42:50.432534Z",
|
||||||
"start_time": "2024-07-19T15:38:32.797246Z"
|
"start_time": "2024-07-19T19:42:50.427816Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 11,
|
"execution_count": 22,
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
@@ -372,16 +372,16 @@
|
|||||||
"text": [
|
"text": [
|
||||||
"Confirm Interface\n",
|
"Confirm Interface\n",
|
||||||
"Keypad View\n",
|
"Keypad View\n",
|
||||||
"Key 0: [7, 29, 51, 66, 53, 47, 27]\n",
|
"Key 0: [49, 22, 23, 59, 11, 12, 62]\n",
|
||||||
"Key 1: [21, 15, 2, 59, 18, 33, 20]\n",
|
"Key 1: [42, 64, 44, 52, 46, 5, 6]\n",
|
||||||
"Key 2: [63, 43, 16, 17, 32, 5, 13]\n",
|
"Key 2: [56, 8, 2, 66, 32, 33, 27]\n",
|
||||||
"Key 3: [56, 50, 30, 10, 67, 54, 34]\n",
|
"Key 3: [0, 50, 37, 24, 25, 19, 69]\n",
|
||||||
"Key 4: [42, 64, 23, 3, 60, 26, 48]\n",
|
"Key 4: [7, 36, 58, 31, 4, 68, 34]\n",
|
||||||
"Key 5: [35, 22, 44, 24, 39, 61, 41]\n",
|
"Key 5: [35, 1, 30, 17, 53, 47, 41]\n",
|
||||||
"Key 6: [49, 8, 58, 45, 25, 40, 62]\n",
|
"Key 6: [28, 43, 16, 38, 67, 26, 48]\n",
|
||||||
"Key 7: [14, 1, 65, 52, 4, 68, 55]\n",
|
"Key 7: [14, 57, 51, 3, 39, 61, 13]\n",
|
||||||
"Key 8: [28, 57, 37, 38, 11, 19, 69]\n",
|
"Key 8: [63, 15, 65, 10, 60, 40, 20]\n",
|
||||||
"Key 9: [0, 36, 9, 31, 46, 12, 6]\n"
|
"Key 9: [21, 29, 9, 45, 18, 54, 55]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -392,14 +392,14 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:32.818596Z",
|
"end_time": "2024-07-19T19:42:50.897855Z",
|
||||||
"start_time": "2024-07-19T15:38:32.799553Z"
|
"start_time": "2024-07-19T19:42:50.894734Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 12,
|
"execution_count": 23,
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
@@ -420,8 +420,8 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:33.435016Z",
|
"end_time": "2024-07-19T19:42:51.884002Z",
|
||||||
"start_time": "2024-07-19T15:38:32.803552Z"
|
"start_time": "2024-07-19T19:42:51.198018Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -438,14 +438,14 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 12,
|
"execution_count": 23,
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [],
|
"source": [],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:33.451250Z",
|
"end_time": "2024-07-19T19:42:53.411190Z",
|
||||||
"start_time": "2024-07-19T15:38:33.435255Z"
|
"start_time": "2024-07-19T19:42:53.406912Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -460,16 +460,130 @@
|
|||||||
"collapsed": false
|
"collapsed": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"source": [
|
||||||
|
"## Dispersion"
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"collapsed": false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 12,
|
"execution_count": 24,
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": "<IPython.core.display.Markdown object>",
|
||||||
|
"text/markdown": "|key|set0|set1|set2|set3|\n|-|-|-|-|-|\n|key1|1|10|11|100|\n|key2|2|20|22|200|\n|key3|3|30|33|300|\n|key4|4|40|44|400|\n|key5|5|50|55|500|"
|
||||||
|
},
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"from src.utils import secure_fisher_yates_shuffle, matrix_to_list\n",
|
||||||
|
"from src.user_interface import UserInterface\n",
|
||||||
|
"from IPython.display import Markdown, display\n",
|
||||||
|
"\n",
|
||||||
|
"def keypad_md_table(interface: list[int], keypad_size: KeypadSize) -> str:\n",
|
||||||
|
" assert (keypad_size.numb_of_attrs == len(interface))\n",
|
||||||
|
" interface_keypad = list_to_matrix(interface, keypad_size.attrs_per_key)\n",
|
||||||
|
" table = \"|key|\" + \"\".join([f\"set{idx}|\" for idx in range(keypad_size.attrs_per_key)])\n",
|
||||||
|
" table += \"\\n|\" + \"\".join(\"-|\" for _ in range(keypad_size.attrs_per_key+1))\n",
|
||||||
|
"\n",
|
||||||
|
" for key in range(keypad_size.numb_of_keys):\n",
|
||||||
|
" table += f\"\\n|key{key+1}|\"\n",
|
||||||
|
" table += \"|\".join([str(attr) for attr in interface_keypad[key]])\n",
|
||||||
|
" table += \"|\"\n",
|
||||||
|
" return table\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"keypad_size = KeypadSize(numb_of_keys=5, attrs_per_key=4)\n",
|
||||||
|
"attrs = [1, 10, 11, 100]\n",
|
||||||
|
"interface = []\n",
|
||||||
|
"for key_numb in range(1,keypad_size.numb_of_keys+1):\n",
|
||||||
|
" interface.extend([key_numb*attr for attr in attrs])\n",
|
||||||
|
"\n",
|
||||||
|
"demo_interface = UserInterface(keypad_size=keypad_size, interface=interface)\n",
|
||||||
|
"\n",
|
||||||
|
"display(Markdown(keypad_md_table(demo_interface.interface, keypad_size)))"
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"collapsed": false,
|
||||||
|
"ExecuteTime": {
|
||||||
|
"end_time": "2024-07-19T19:42:55.684088Z",
|
||||||
|
"start_time": "2024-07-19T19:42:55.680817Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 25,
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": "<IPython.core.display.Markdown object>",
|
||||||
|
"text/markdown": "|key|set0|set1|set2|set3|\n|-|-|-|-|-|\n|key1|5|50|55|500|\n|key2|3|30|33|300|\n|key3|2|20|22|200|\n|key4|4|40|44|400|\n|key5|1|10|11|100|"
|
||||||
|
},
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"demo_interface_matrix = list_to_matrix(demo_interface.interface, demo_interface.keypad_size.attrs_per_key)\n",
|
||||||
|
"shuffled_keys = secure_fisher_yates_shuffle(demo_interface_matrix)\n",
|
||||||
|
"shuffled_keys_list = matrix_to_list(shuffled_keys)\n",
|
||||||
|
"display(Markdown(keypad_md_table(shuffled_keys_list, keypad_size)))\n"
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"collapsed": false,
|
||||||
|
"ExecuteTime": {
|
||||||
|
"end_time": "2024-07-19T19:42:56.543819Z",
|
||||||
|
"start_time": "2024-07-19T19:42:56.537207Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 26,
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": "<IPython.core.display.Markdown object>",
|
||||||
|
"text/markdown": "|key|set0|set1|set2|set3|\n|-|-|-|-|-|\n|key1|3|40|11|200|\n|key2|2|10|55|400|\n|key3|4|50|33|100|\n|key4|1|30|22|500|\n|key5|5|20|44|300|"
|
||||||
|
},
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"attr_rotation = secure_fisher_yates_shuffle(list(range(keypad_size.numb_of_keys)))[:keypad_size.attrs_per_key]\n",
|
||||||
|
"dispersed_interface = UserInterface.random_attribute_rotation(\n",
|
||||||
|
" shuffled_keys,\n",
|
||||||
|
" attr_rotation\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"display(Markdown(keypad_md_table(matrix_to_list(dispersed_interface), keypad_size)))"
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"collapsed": false,
|
||||||
|
"ExecuteTime": {
|
||||||
|
"end_time": "2024-07-19T19:42:56.940543Z",
|
||||||
|
"start_time": "2024-07-19T19:42:56.935742Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [],
|
"source": [],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2024-07-19T15:38:33.451441Z",
|
"start_time": "2024-07-19T19:42:26.284802Z"
|
||||||
"start_time": "2024-07-19T15:38:33.438804Z"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from src.customer_interface import CustomerInterface
|
from src.customer_attributes import CustomerAttributes
|
||||||
from src.models import NKodePolicy
|
from src.models import NKodePolicy
|
||||||
from src.user import User
|
from src.user import User
|
||||||
from src.utils import xor_lists
|
from src.utils import xor_lists
|
||||||
@@ -9,7 +9,7 @@ from src.utils import xor_lists
|
|||||||
class Customer(BaseModel):
|
class Customer(BaseModel):
|
||||||
customer_id: UUID
|
customer_id: UUID
|
||||||
nkode_policy: NKodePolicy
|
nkode_policy: NKodePolicy
|
||||||
interface: CustomerInterface
|
attributes: CustomerAttributes
|
||||||
users: dict[str, User]
|
users: dict[str, User]
|
||||||
|
|
||||||
def add_new_user(self, user: User):
|
def add_new_user(self, user: User):
|
||||||
@@ -17,13 +17,13 @@ class Customer(BaseModel):
|
|||||||
|
|
||||||
def valid_key_entry(self, username, selected_keys) -> bool:
|
def valid_key_entry(self, username, selected_keys) -> bool:
|
||||||
assert (username in self.users.keys())
|
assert (username in self.users.keys())
|
||||||
assert (all(key_idx < self.interface.keypad_size.numb_of_keys for key_idx in selected_keys))
|
assert (all(key_idx < self.attributes.keypad_size.numb_of_keys for key_idx in selected_keys))
|
||||||
passcode_len = len(selected_keys)
|
passcode_len = len(selected_keys)
|
||||||
user = self.users[username]
|
user = self.users[username]
|
||||||
|
|
||||||
passcode_set_vals = user.user_keys.decipher_mask(
|
passcode_set_vals = user.user_keys.decipher_mask(
|
||||||
user.enciphered_passcode.mask, self.interface.set_vals, len(selected_keys))
|
user.enciphered_passcode.mask, self.attributes.set_vals, len(selected_keys))
|
||||||
set_vals_idx = [self.interface.get_set_index(set_val) for set_val in passcode_set_vals]
|
set_vals_idx = [self.attributes.get_set_index(set_val) for set_val in passcode_set_vals]
|
||||||
|
|
||||||
presumed_selected_attributes = []
|
presumed_selected_attributes = []
|
||||||
presumed_selected_attributes_idx = []
|
presumed_selected_attributes_idx = []
|
||||||
@@ -36,20 +36,20 @@ class Customer(BaseModel):
|
|||||||
presumed_selected_attributes_idx.append(selected_attr_idx)
|
presumed_selected_attributes_idx.append(selected_attr_idx)
|
||||||
presumed_selected_attributes.append(selected_attr_idx)
|
presumed_selected_attributes.append(selected_attr_idx)
|
||||||
|
|
||||||
enciphered_attr = user.user_keys.encipher_salt_hash_code(presumed_selected_attributes, self.interface)
|
enciphered_attr = user.user_keys.encipher_salt_hash_code(presumed_selected_attributes, self.attributes)
|
||||||
if enciphered_attr != user.enciphered_passcode.code:
|
if enciphered_attr != user.enciphered_passcode.code:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if user.renew:
|
if user.renew:
|
||||||
user.refresh_passcode(presumed_selected_attributes_idx, self.interface)
|
user.refresh_passcode(presumed_selected_attributes_idx, self.attributes)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def renew_keys(self) -> bool:
|
def renew_keys(self) -> bool:
|
||||||
attrs_before = self.interface.attr_vals.copy()
|
attrs_before = self.attributes.attr_vals.copy()
|
||||||
sets_before = self.interface.set_vals.copy()
|
sets_before = self.attributes.set_vals.copy()
|
||||||
self.interface.renew_interface()
|
self.attributes.renew()
|
||||||
attrs_after = self.interface.attr_vals
|
attrs_after = self.attributes.attr_vals
|
||||||
sets_after = self.interface.set_vals
|
sets_after = self.attributes.set_vals
|
||||||
|
|
||||||
attrs_xor = xor_lists(attrs_after, attrs_before)
|
attrs_xor = xor_lists(attrs_after, attrs_before)
|
||||||
set_xor = xor_lists(sets_after, sets_before)
|
set_xor = xor_lists(sets_after, sets_before)
|
||||||
@@ -60,7 +60,7 @@ class Customer(BaseModel):
|
|||||||
def valid_new_nkode(self, passcode_attr_idx: list[int]) -> bool:
|
def valid_new_nkode(self, passcode_attr_idx: list[int]) -> bool:
|
||||||
nkode_len = len(passcode_attr_idx)
|
nkode_len = len(passcode_attr_idx)
|
||||||
passcode_set_values = [
|
passcode_set_values = [
|
||||||
self.interface.get_attr_set_val(self.interface.attr_vals[attr_idx]) for attr_idx in passcode_attr_idx
|
self.attributes.get_attr_set_val(self.attributes.attr_vals[attr_idx]) for attr_idx in passcode_attr_idx
|
||||||
]
|
]
|
||||||
distinct_sets = len(set(passcode_set_values))
|
distinct_sets = len(set(passcode_set_values))
|
||||||
distinct_attributes = len(set(passcode_attr_idx))
|
distinct_attributes = len(set(passcode_attr_idx))
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from src.models import KeypadSize
|
|||||||
from src.utils import generate_random_nonrepeating_list
|
from src.utils import generate_random_nonrepeating_list
|
||||||
|
|
||||||
|
|
||||||
class CustomerInterface(BaseModel):
|
class CustomerAttributes(BaseModel):
|
||||||
attr_vals: list[int]
|
attr_vals: list[int]
|
||||||
set_vals: list[int]
|
set_vals: list[int]
|
||||||
keypad_size: KeypadSize
|
keypad_size: KeypadSize
|
||||||
@@ -14,13 +14,13 @@ class CustomerInterface(BaseModel):
|
|||||||
assert (keypad_size.numb_of_keys <= 256)
|
assert (keypad_size.numb_of_keys <= 256)
|
||||||
assert (keypad_size.attrs_per_key <= 256)
|
assert (keypad_size.attrs_per_key <= 256)
|
||||||
|
|
||||||
return CustomerInterface(
|
return CustomerAttributes(
|
||||||
attr_vals=generate_random_nonrepeating_list(keypad_size.numb_of_attrs),
|
attr_vals=generate_random_nonrepeating_list(keypad_size.numb_of_attrs),
|
||||||
set_vals=generate_random_nonrepeating_list(keypad_size.attrs_per_key),
|
set_vals=generate_random_nonrepeating_list(keypad_size.attrs_per_key),
|
||||||
keypad_size=keypad_size,
|
keypad_size=keypad_size,
|
||||||
)
|
)
|
||||||
|
|
||||||
def renew_interface(self):
|
def renew(self):
|
||||||
self.attr_vals = generate_random_nonrepeating_list(self.keypad_size.numb_of_attrs)
|
self.attr_vals = generate_random_nonrepeating_list(self.keypad_size.numb_of_attrs)
|
||||||
self.set_vals = generate_random_nonrepeating_list(self.keypad_size.attrs_per_key)
|
self.set_vals = generate_random_nonrepeating_list(self.keypad_size.attrs_per_key)
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from src.models import EncipheredNKode
|
from src.models import EncipheredNKode
|
||||||
from src.customer_interface import CustomerInterface
|
from src.customer_attributes import CustomerAttributes
|
||||||
from src.user_cipher_keys import UserCipherKeys
|
from src.user_cipher_keys import UserCipherKeys
|
||||||
from src.user_interface import UserInterface
|
from src.user_interface import UserInterface
|
||||||
from src.utils import xor_lists
|
from src.utils import xor_lists
|
||||||
@@ -19,7 +19,7 @@ class User(BaseModel):
|
|||||||
self.user_keys.set_key = xor_lists(self.user_keys.set_key, sets_xor)
|
self.user_keys.set_key = xor_lists(self.user_keys.set_key, sets_xor)
|
||||||
self.user_keys.alpha_key = xor_lists(self.user_keys.alpha_key, attrs_xor)
|
self.user_keys.alpha_key = xor_lists(self.user_keys.alpha_key, attrs_xor)
|
||||||
|
|
||||||
def refresh_passcode(self, passcode_attr_idx: list[int], customer_interface: CustomerInterface):
|
def refresh_passcode(self, passcode_attr_idx: list[int], customer_interface: CustomerAttributes):
|
||||||
self.user_keys = UserCipherKeys.new(
|
self.user_keys = UserCipherKeys.new(
|
||||||
customer_interface.keypad_size,
|
customer_interface.keypad_size,
|
||||||
customer_interface.set_vals,
|
customer_interface.set_vals,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from secrets import choice
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from src.models import EncipheredNKode, KeypadSize
|
from src.models import EncipheredNKode, KeypadSize
|
||||||
from src.customer_interface import CustomerInterface
|
from src.customer_attributes import CustomerAttributes
|
||||||
from src.utils import generate_random_nonrepeating_list, xor_lists, int_array_to_bytes
|
from src.utils import generate_random_nonrepeating_list, xor_lists, int_array_to_bytes
|
||||||
|
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ class UserCipherKeys(BaseModel):
|
|||||||
def encipher_nkode(
|
def encipher_nkode(
|
||||||
self,
|
self,
|
||||||
passcode_attr_idx: list[int],
|
passcode_attr_idx: list[int],
|
||||||
customer_interface: CustomerInterface
|
customer_interface: CustomerAttributes
|
||||||
) -> EncipheredNKode:
|
) -> EncipheredNKode:
|
||||||
|
|
||||||
passcode_attrs = [customer_interface.attr_vals[idx] for idx in passcode_attr_idx]
|
passcode_attrs = [customer_interface.attr_vals[idx] for idx in passcode_attr_idx]
|
||||||
@@ -78,7 +78,7 @@ class UserCipherKeys(BaseModel):
|
|||||||
def encipher_salt_hash_code(
|
def encipher_salt_hash_code(
|
||||||
self,
|
self,
|
||||||
passcode_attr_idx: list[int],
|
passcode_attr_idx: list[int],
|
||||||
customer_interface: CustomerInterface,
|
customer_interface: CustomerAttributes,
|
||||||
) -> str:
|
) -> str:
|
||||||
passcode_len = len(passcode_attr_idx)
|
passcode_len = len(passcode_attr_idx)
|
||||||
passcode_attrs = [customer_interface.attr_vals[idx] for idx in passcode_attr_idx]
|
passcode_attrs = [customer_interface.attr_vals[idx] for idx in passcode_attr_idx]
|
||||||
@@ -95,7 +95,7 @@ class UserCipherKeys(BaseModel):
|
|||||||
def encipher_mask(
|
def encipher_mask(
|
||||||
self,
|
self,
|
||||||
passcode_sets: list[int],
|
passcode_sets: list[int],
|
||||||
customer_interface: CustomerInterface
|
customer_interface: CustomerAttributes
|
||||||
) -> str:
|
) -> str:
|
||||||
padded_passcode_sets = self.pad_user_mask(passcode_sets, customer_interface.set_vals)
|
padded_passcode_sets = self.pad_user_mask(passcode_sets, customer_interface.set_vals)
|
||||||
set_idx = [customer_interface.get_set_index(set_val) for set_val in padded_passcode_sets]
|
set_idx = [customer_interface.get_set_index(set_val) for set_val in padded_passcode_sets]
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ from src.utils import list_to_matrix, secure_fisher_yates_shuffle, matrix_to_lis
|
|||||||
|
|
||||||
|
|
||||||
class UserInterface(BaseModel):
|
class UserInterface(BaseModel):
|
||||||
attr_indices: list[int]
|
interface: list[int]
|
||||||
keypad_size: KeypadSize
|
keypad_size: KeypadSize
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def new(keypad_size: KeypadSize):
|
def new(keypad_size: KeypadSize):
|
||||||
# Todo: this a hack do a proper random interface
|
# Todo: this a hack do a proper random interface
|
||||||
interface = UserInterface(
|
interface = UserInterface(
|
||||||
attr_indices=list(range(keypad_size.numb_of_attrs)),
|
interface=list(range(keypad_size.numb_of_attrs)),
|
||||||
keypad_size=keypad_size
|
keypad_size=keypad_size
|
||||||
)
|
)
|
||||||
interface.disperse_interface()
|
interface.disperse_interface()
|
||||||
@@ -22,18 +22,22 @@ class UserInterface(BaseModel):
|
|||||||
return interface
|
return interface
|
||||||
|
|
||||||
def disperse_interface(self):
|
def disperse_interface(self):
|
||||||
user_interface_matrix = list_to_matrix(self.attr_indices, self.keypad_size.attrs_per_key)
|
user_interface_matrix = list_to_matrix(self.interface, self.keypad_size.attrs_per_key)
|
||||||
shuffled_keys = secure_fisher_yates_shuffle(user_interface_matrix)
|
shuffled_keys = secure_fisher_yates_shuffle(user_interface_matrix)
|
||||||
dispersed_interface = self._random_attribute_rotation(shuffled_keys, list(range(self.keypad_size.attrs_per_key)))
|
|
||||||
self.attr_indices = matrix_to_list(dispersed_interface)
|
attr_rotation = secure_fisher_yates_shuffle(list(range(self.keypad_size.numb_of_keys)))[:self.keypad_size.attrs_per_key]
|
||||||
|
dispersed_interface = self.random_attribute_rotation(
|
||||||
|
shuffled_keys,
|
||||||
|
attr_rotation,
|
||||||
|
)
|
||||||
|
self.interface = matrix_to_list(dispersed_interface)
|
||||||
|
|
||||||
def shuffle_interface(self):
|
def shuffle_interface(self):
|
||||||
"""just like dispersion but only half the sets are rotated"""
|
|
||||||
numb_of_selected_sets = self.keypad_size.attrs_per_key // 2
|
numb_of_selected_sets = self.keypad_size.attrs_per_key // 2
|
||||||
# randomly shuffle half the sets. if attrs_per_key is odd, randomly add one 50% of the time
|
# randomly shuffle half the sets. if attrs_per_key is odd, randomly add one 50% of the time
|
||||||
numb_of_selected_sets += choice([0, 1]) if (self.keypad_size.attrs_per_key & 1) == 1 else 0
|
numb_of_selected_sets += choice([0, 1]) if (self.keypad_size.attrs_per_key & 1) == 1 else 0
|
||||||
selected_sets = secure_fisher_yates_shuffle(list(range(self.keypad_size.attrs_per_key)))[:numb_of_selected_sets]
|
selected_sets = secure_fisher_yates_shuffle(list(range(self.keypad_size.attrs_per_key)))[:numb_of_selected_sets]
|
||||||
user_interface_matrix = list_to_matrix(self.attr_indices, self.keypad_size.attrs_per_key)
|
user_interface_matrix = list_to_matrix(self.interface, self.keypad_size.attrs_per_key)
|
||||||
shuffled_keys = secure_fisher_yates_shuffle(user_interface_matrix)
|
shuffled_keys = secure_fisher_yates_shuffle(user_interface_matrix)
|
||||||
interface_by_sets = []
|
interface_by_sets = []
|
||||||
for idx, attrs in enumerate(matrix_transpose(shuffled_keys)):
|
for idx, attrs in enumerate(matrix_transpose(shuffled_keys)):
|
||||||
@@ -41,21 +45,22 @@ class UserInterface(BaseModel):
|
|||||||
interface_by_sets.append(secure_fisher_yates_shuffle(attrs))
|
interface_by_sets.append(secure_fisher_yates_shuffle(attrs))
|
||||||
else:
|
else:
|
||||||
interface_by_sets.append(attrs)
|
interface_by_sets.append(attrs)
|
||||||
self.attr_indices = matrix_to_list(matrix_transpose(interface_by_sets))
|
self.interface = matrix_to_list(matrix_transpose(interface_by_sets))
|
||||||
|
|
||||||
def _random_attribute_rotation(self, user_interface: list[list[int]], selected_sets: list[int]) -> list[list[int]]:
|
@staticmethod
|
||||||
attr_rotation = secure_fisher_yates_shuffle(list(range(self.keypad_size.numb_of_keys)))[:self.keypad_size.attrs_per_key]
|
def random_attribute_rotation(
|
||||||
|
user_interface: list[list[int]],
|
||||||
|
attr_rotation: list[int]
|
||||||
|
) -> list[list[int]]:
|
||||||
transposed_user_interface = matrix_transpose(user_interface)
|
transposed_user_interface = matrix_transpose(user_interface)
|
||||||
assert (len(attr_rotation) == len(transposed_user_interface))
|
assert (len(attr_rotation) == len(transposed_user_interface))
|
||||||
for idx, attr_set in enumerate(transposed_user_interface):
|
for idx, attr_set in enumerate(transposed_user_interface):
|
||||||
if idx not in selected_sets:
|
|
||||||
continue
|
|
||||||
rotation = attr_rotation[idx]
|
rotation = attr_rotation[idx]
|
||||||
transposed_user_interface[idx] = attr_set[rotation:] + attr_set[:rotation]
|
transposed_user_interface[idx] = attr_set[rotation:] + attr_set[:rotation]
|
||||||
return matrix_transpose(transposed_user_interface)
|
return matrix_transpose(transposed_user_interface)
|
||||||
|
|
||||||
def attribute_adjacency_graph(self) -> dict[int, set[int]]:
|
def attribute_adjacency_graph(self) -> dict[int, set[int]]:
|
||||||
user_interface_keypad = list_to_matrix(self.attr_indices, self.keypad_size.attrs_per_key)
|
user_interface_keypad = list_to_matrix(self.interface, self.keypad_size.attrs_per_key)
|
||||||
graph = {}
|
graph = {}
|
||||||
for key in user_interface_keypad:
|
for key in user_interface_keypad:
|
||||||
for attr in key:
|
for attr in key:
|
||||||
@@ -66,5 +71,5 @@ class UserInterface(BaseModel):
|
|||||||
|
|
||||||
def get_key_attr_idxs(self, key_numb: int) -> list[int]:
|
def get_key_attr_idxs(self, key_numb: int) -> list[int]:
|
||||||
assert (0 <= key_numb < self.keypad_size.numb_of_keys)
|
assert (0 <= key_numb < self.keypad_size.numb_of_keys)
|
||||||
keypad_attr_idx = list_to_matrix(self.attr_indices, self.keypad_size.attrs_per_key)
|
keypad_attr_idx = list_to_matrix(self.interface, self.keypad_size.attrs_per_key)
|
||||||
return keypad_attr_idx[key_numb]
|
return keypad_attr_idx[key_numb]
|
||||||
|
|||||||
@@ -39,11 +39,11 @@ class UserSignupSession(BaseModel):
|
|||||||
def set_user_nkode(self, username: str, key_selection: list[int]):
|
def set_user_nkode(self, username: str, key_selection: list[int]):
|
||||||
assert (all(0 <= key <= self.keypad_size.numb_of_keys for key in key_selection))
|
assert (all(0 <= key <= self.keypad_size.numb_of_keys for key in key_selection))
|
||||||
set_interface = UserInterface(
|
set_interface = UserInterface(
|
||||||
attr_indices=self.set_interface,
|
interface=self.set_interface,
|
||||||
keypad_size=self.keypad_size
|
keypad_size=self.keypad_size
|
||||||
)
|
)
|
||||||
set_interface.disperse_interface()
|
set_interface.disperse_interface()
|
||||||
self.username = username
|
self.username = username
|
||||||
self.set_key_entry = key_selection
|
self.set_key_entry = key_selection
|
||||||
self.confirm_interface = set_interface.attr_indices
|
self.confirm_interface = set_interface.interface
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ from src.models import KeypadSize
|
|||||||
def test_attr_set_idx(keypad_size):
|
def test_attr_set_idx(keypad_size):
|
||||||
user_interface = UserInterface.new(keypad_size)
|
user_interface = UserInterface.new(keypad_size)
|
||||||
for attr_idx in range(70):
|
for attr_idx in range(70):
|
||||||
user_interface_idx = user_interface.attr_indices[attr_idx]
|
user_interface_idx = user_interface.interface[attr_idx]
|
||||||
|
|
||||||
assert (attr_idx % keypad_size.attrs_per_key == user_interface_idx % keypad_size.attrs_per_key)
|
assert (attr_idx % keypad_size.attrs_per_key == user_interface_idx % keypad_size.attrs_per_key)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from src.models import KeypadSize
|
from src.models import KeypadSize
|
||||||
from src.user_cipher_keys import UserCipherKeys, CustomerInterface
|
from src.user_cipher_keys import UserCipherKeys, CustomerAttributes
|
||||||
from src.utils import generate_random_nonrepeating_list
|
from src.utils import generate_random_nonrepeating_list
|
||||||
|
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ def test_encode_decode_base64(passcode_len):
|
|||||||
(KeypadSize(numb_of_keys=8, attrs_per_key=7), 12),
|
(KeypadSize(numb_of_keys=8, attrs_per_key=7), 12),
|
||||||
])
|
])
|
||||||
def test_decode_mask(keypad_size, max_nkode_len):
|
def test_decode_mask(keypad_size, max_nkode_len):
|
||||||
customer = CustomerInterface.new(keypad_size)
|
customer = CustomerAttributes.new(keypad_size)
|
||||||
passcode_entry = generate_random_nonrepeating_list(
|
passcode_entry = generate_random_nonrepeating_list(
|
||||||
keypad_size.numb_of_attrs,
|
keypad_size.numb_of_attrs,
|
||||||
max_val=keypad_size.numb_of_attrs)[:4]
|
max_val=keypad_size.numb_of_attrs)[:4]
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ def test_shuffle_attrs(user_interface):
|
|||||||
- every attribute is adjacent to every other attribute with uniform distribution
|
- every attribute is adjacent to every other attribute with uniform distribution
|
||||||
- the order in which the attributes move from key to key is random (i.e. the distance traveled is uniform)
|
- the order in which the attributes move from key to key is random (i.e. the distance traveled is uniform)
|
||||||
"""
|
"""
|
||||||
pre_shuffle_interface = user_interface.attr_indices
|
pre_shuffle_interface = user_interface.interface
|
||||||
user_interface.shuffle_interface()
|
user_interface.shuffle_interface()
|
||||||
post_shuffle_interface = user_interface.attr_indices
|
post_shuffle_interface = user_interface.interface
|
||||||
for i in range(1000):
|
for i in range(1000):
|
||||||
assert (not all(
|
assert (not all(
|
||||||
post_shuffle_interface[idx] == pre_shuffle_interface[idx] for idx in range(len(post_shuffle_interface))
|
post_shuffle_interface[idx] == pre_shuffle_interface[idx] for idx in range(len(post_shuffle_interface))
|
||||||
|
|||||||
Reference in New Issue
Block a user