refactor render_markdown.py
This commit is contained in:
@@ -36,7 +36,7 @@ policy = NKodePolicy(
|
||||
|
||||
keypad_size = KeypadSize(
|
||||
numb_of_keys = {{ keypad_size.numb_of_keys }},
|
||||
attrs_per_key = {{ keypad_size.attrs_per_key }} # aka number of sets
|
||||
props_per_key = {{ keypad_size.props_per_key }} # aka number of sets
|
||||
)
|
||||
|
||||
customer_id = api.create_new_customer(keypad_size, policy)
|
||||
@@ -44,9 +44,9 @@ customer = api.customers[customer_id]
|
||||
```
|
||||
### Customer Attributes and Sets
|
||||
A customer has users and defines the attributes and set values for all its users.
|
||||
Since our customer has {{ keypad_size.numb_of_keys }} keys and {{ keypad_size.attrs_per_key }} attributes per key,
|
||||
this gives a customer interface of {{ keypad_size.numb_of_attrs }} distinct attributes and {{ keypad_size.attrs_per_key }} distinct attribute sets.
|
||||
Each attribute belongs to one of the {{ keypad_size.attrs_per_key }} sets. Each attribute and set value is a unique 2-byte integer in this example.
|
||||
Since our customer has {{ keypad_size.numb_of_keys }} keys and {{ keypad_size.props_per_key }} attributes per key,
|
||||
this gives a customer interface of {{ keypad_size.numb_of_props }} distinct attributes and {{ keypad_size.props_per_key }} distinct attribute sets.
|
||||
Each attribute belongs to one of the {{ keypad_size.props_per_key }} sets. Each attribute and set value is a unique 2-byte integer in this example.
|
||||
|
||||
```
|
||||
set_vals = customer.attributes.set_vals
|
||||
@@ -56,7 +56,7 @@ Customer Sets: {{ customer_set_vals }}
|
||||
|
||||
```
|
||||
attr_vals = customer.attributes.attr_vals
|
||||
keypad_view(attr_vals, keypad_size.attrs_per_key)
|
||||
keypad_view(attr_vals, keypad_size.props_per_key)
|
||||
|
||||
Customer Attributes:
|
||||
{% for attrs in customer_attr_view -%}
|
||||
@@ -85,15 +85,15 @@ Now that we have a customer, we can create users. To create a new user:
|
||||
The user's interface must be dispersable so the server can determine the user's nkode.
|
||||
The server randomly drops attribute sets until
|
||||
the number of attributes equals the number of keys, making the interface dispersable.
|
||||
In our case, the server randomly drops {{ keypad_size.attrs_per_key - keypad_size.numb_of_keys }} attribute {{ "sets" if keypad_size.attrs_per_key - keypad_size.numb_of_keys > 1 else "set" }}.
|
||||
to give us a {{ keypad_size.numb_of_keys }} X {{ keypad_size.numb_of_keys }} keypad with possible index values ranging from 0-{{ keypad_size.numb_of_attrs - 1 }}.
|
||||
In our case, the server randomly drops {{ keypad_size.props_per_key - keypad_size.numb_of_keys }} attribute {{ "sets" if keypad_size.props_per_key - keypad_size.numb_of_keys > 1 else "set" }}.
|
||||
to give us a {{ keypad_size.numb_of_keys }} X {{ keypad_size.numb_of_keys }} keypad with possible index values ranging from 0-{{ keypad_size.numb_of_props - 1 }}.
|
||||
Each value in the interface is the index value of a customer attribute.
|
||||
The user never learns what their "real" attribute is. They do not see the index value representing their nKode or
|
||||
the customer server-side value.
|
||||
|
||||
```
|
||||
session_id, signup_interface = api.generate_index_interface(customer_id)
|
||||
signup_interface_keypad = list_to_matrix(signup_interface, keypad_size.attrs_per_key)
|
||||
signup_interface_keypad = list_to_matrix(signup_interface, keypad_size.props_per_key)
|
||||
|
||||
Signup Keypad:
|
||||
{% for key in signup_keypad -%}
|
||||
@@ -110,7 +110,7 @@ If users want to change anything about their interface, they must also change th
|
||||
```
|
||||
username = {{ username }}
|
||||
user_passcode = {{ user_passcode }}
|
||||
selected_keys_set = select_keys_with_passcode_values(user_passcode, signup_interface, keypad_size.attrs_per_key)
|
||||
selected_keys_set = select_keys_with_passcode_values(user_passcode, signup_interface, keypad_size.props_per_key)
|
||||
|
||||
Selected Keys
|
||||
{{ selected_keys_set }}
|
||||
@@ -161,11 +161,11 @@ Steps 1-2 are straightforward. For a better idea of how they work, see pyNKode.
|
||||
|
||||
##### User Cipher Keys Data Structure
|
||||
```
|
||||
set_key = generate_random_nonrepeating_list(keypad_size.attrs_per_key, max_numb=2**(8*numb_of_bytes))
|
||||
set_key = generate_random_nonrepeating_list(keypad_size.props_per_key, max_numb=2**(8*numb_of_bytes))
|
||||
set_key = xor_lists(set_key, customer_attr.set_vals)
|
||||
|
||||
UserCipherKeys(
|
||||
prop_key=generate_random_nonrepeating_list(keypad_size.attrs_per_key * keypad_size.numb_of_keys, max_numb=2**(8*numb_of_bytes)),
|
||||
prop_key=generate_random_nonrepeating_list(keypad_size.props_per_key * keypad_size.numb_of_keys, max_numb=2**(8*numb_of_bytes)),
|
||||
pass_key=generate_random_nonrepeating_list(max_nkode_len, max_numb=2**(8*numb_of_bytes)),
|
||||
mask_key=generate_random_nonrepeating_list(max_nkode_len, max_numb=2**(8*numb_of_bytes)),
|
||||
set_key=set_key,
|
||||
@@ -176,13 +176,13 @@ UserCipherKeys(
|
||||
|
||||
##### User Cipher Keys Values
|
||||
```
|
||||
user_keys = UserCipherKeys(
|
||||
prop_key = {{ user_keys.prop_key }},
|
||||
pass_key = {{ user_keys.pass_key }},
|
||||
mask_key = {{ user_keys.mask_key }},
|
||||
set_key = {{ user_keys.set_key }},
|
||||
salt = {{ user_keys.salt }},
|
||||
max_nkode_len = {{ user_keys.max_nkode_len }}
|
||||
user_cipher = UserCipherKeys(
|
||||
prop_key = {{ user_cipher.prop_key }},
|
||||
pass_key = {{ user_cipher.pass_key }},
|
||||
mask_key = {{ user_cipher.mask_key }},
|
||||
set_key = {{ user_cipher.set_key }},
|
||||
salt = {{ user_cipher.salt }},
|
||||
max_nkode_len = {{ user_cipher.max_nkode_len }}
|
||||
)
|
||||
```
|
||||
|
||||
@@ -219,15 +219,15 @@ Passcode Attr Vals: {{ passcode_server_set }}
|
||||
```
|
||||
|
||||
```
|
||||
padded_passcode_server_set = user_keys.pad_user_mask(passcode_server_set, customer.nkode_policy.max_nkode_len)
|
||||
padded_passcode_server_set = user_cipher.pad_user_mask(passcode_server_set, customer.nkode_policy.max_nkode_len)
|
||||
|
||||
set_idx = [customer.attributes.get_set_index(set_val) for set_val in padded_passcode_server_set]
|
||||
mask_set_keys = [user_keys.set_key[idx] for idx in set_idx]
|
||||
mask_set_keys = [user_cipher.set_key[idx] for idx in set_idx]
|
||||
|
||||
ciphered_mask = xor_lists(mask_set_keys, padded_passcode_server_set)
|
||||
ciphered_mask = xor_lists(ciphered_mask, user_keys.mask_key)
|
||||
ciphered_mask = xor_lists(ciphered_mask, user_cipher.mask_key)
|
||||
|
||||
mask = user_keys.encode_base64_str(ciphered_mask)
|
||||
mask = user_cipher.encode_base64_str(ciphered_mask)
|
||||
Mask: {{ enciphered_nkode.mask }}
|
||||
```
|
||||
|
||||
@@ -238,17 +238,17 @@ Mask: {{ enciphered_nkode.mask }}
|
||||
- code = hash(ciphered_passcode, salt)
|
||||
|
||||
```
|
||||
ciphered_customer_attrs = xor_lists(customer.attributes.attr_vals, user_keys.prop_key)
|
||||
ciphered_customer_attrs = xor_lists(customer.attributes.attr_vals, user_cipher.prop_key)
|
||||
passcode_ciphered_attrs = [ciphered_customer_attrs[idx] for idx in passcode]
|
||||
pad_len = customer.nkode_policy.max_nkode_len - passcode_len
|
||||
|
||||
passcode_ciphered_attrs.extend([0 for _ in range(pad_len)])
|
||||
|
||||
ciphered_code = xor_lists(passcode_ciphered_attrs, user_keys.pass_key)
|
||||
ciphered_code = xor_lists(passcode_ciphered_attrs, user_cipher.pass_key)
|
||||
|
||||
passcode_bytes = int_array_to_bytes(ciphered_code)
|
||||
passcode_digest = base64.b64encode(hashlib.sha256(passcode_bytes).digest())
|
||||
hashed_data = bcrypt.hashpw(passcode_digest, user_keys.salt)
|
||||
hashed_data = bcrypt.hashpw(passcode_digest, user_cipher.salt)
|
||||
code = hashed_data.decode("utf-8")
|
||||
|
||||
Code: {{ enciphered_nkode.code }}
|
||||
@@ -264,7 +264,7 @@ To login, a user:
|
||||
The client requests the user's login interface.
|
||||
```
|
||||
login_interface = api.get_login_interface(username, customer_id)
|
||||
keypad_view(login_interface, keypad_size.attrs_per_key)
|
||||
keypad_view(login_interface, keypad_size.props_per_key)
|
||||
```
|
||||
The server returns a randomly shuffled interface. Learn more about how the [User Interface Shuffle](nkode_concepts.md/#user-interface-shuffle) works
|
||||
```
|
||||
@@ -301,11 +301,11 @@ Recover nKode set values:
|
||||
|
||||
```
|
||||
user = customer.users[username]
|
||||
user_keys = user.user_keys
|
||||
user_cipher = user.user_cipher
|
||||
user_mask = user.enciphered_passcode.mask
|
||||
decoded_mask = user_keys.decode_base64_str(user_mask)
|
||||
deciphered_mask = xor_lists(decoded_mask, user_keys.mask_key)
|
||||
set_key_rand_component = xor_lists(set_vals, user_keys.set_key)
|
||||
decoded_mask = user_cipher.decode_base64_str(user_mask)
|
||||
deciphered_mask = xor_lists(decoded_mask, user_cipher.mask_key)
|
||||
set_key_rand_component = xor_lists(set_vals, user_cipher.set_key)
|
||||
passcode_sets = []
|
||||
for set_cipher in deciphered_mask[:passcode_len]:
|
||||
set_idx = set_key_rand_component.index(set_cipher)
|
||||
@@ -331,7 +331,7 @@ Recall User Passcode: {{ user_passcode }}
|
||||
```
|
||||
### Compare Enciphered Passcodes
|
||||
```
|
||||
enciphered_nkode = user_keys.encipher_salt_hash_code(presumed_selected_attributes_idx, customer.attributes)
|
||||
enciphered_nkode = user_cipher.encipher_salt_hash_code(presumed_selected_attributes_idx, customer.attributes)
|
||||
```
|
||||
If `enciphered_nkode == user.enciphered_passcode.code`, the user's key selection is valid, and the login is successful.
|
||||
|
||||
@@ -388,8 +388,8 @@ attrs_xor = xor_lists(new_attrs, old_attrs)
|
||||
sets_xor = xor_lists(new_sets, old_sets)
|
||||
for user in customer.users.values():
|
||||
user.renew = True
|
||||
user.user_keys.set_key = xor_lists(user.user_keys.set_key, sets_xor)
|
||||
user.user_keys.prop_key = xor_lists(user.user_keys.prop_key, attrs_xor)
|
||||
user.user_cipher.set_key = xor_lists(user.user_cipher.set_key, sets_xor)
|
||||
user.user_cipher.prop_key = xor_lists(user.user_cipher.prop_key, attrs_xor)
|
||||
```
|
||||
##### User prop Key
|
||||
The user's prop key was a randomly generated list of length `numb_of_keys * attr_per_key`.
|
||||
@@ -412,11 +412,11 @@ remains the same.
|
||||
Once the user has a successful login, they get a new salt and cipher keys, and their `enciphered_passcode` is recomputed
|
||||
with the new values.
|
||||
```
|
||||
user.user_keys = UserCipherKeys.new(
|
||||
user.user_cipher = UserCipherKeys.new(
|
||||
customer.attributes.keypad_size,
|
||||
customer.attributes.set_vals,
|
||||
user.user_keys.max_nkode_len
|
||||
user.user_cipher.max_nkode_len
|
||||
)
|
||||
user.enciphered_passcode = user.user_keys.encipher_nkode(presumed_selected_attributes_idx, customer.attributes)
|
||||
user.enciphered_passcode = user.user_cipher.encipher_nkode(presumed_selected_attributes_idx, customer.attributes)
|
||||
user.renew = False
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user