rename attribute to property
This commit is contained in:
@@ -2,9 +2,9 @@
|
|||||||
Play around with the code in [this](http://sesolgit/Repository/Blob/92a60227-4ef9-4196-8ebb-595581abf98c?encodedName=main&encodedPath=nkode_tutorial.ipynb) jupyter notebook.
|
Play around with the code in [this](http://sesolgit/Repository/Blob/92a60227-4ef9-4196-8ebb-595581abf98c?encodedName=main&encodedPath=nkode_tutorial.ipynb) jupyter notebook.
|
||||||
|
|
||||||
## Customer Creation
|
## Customer Creation
|
||||||
Before creating a user, a customer generates random attributes and set
|
Before creating a user, a customer generates random properties and set
|
||||||
values. The customers manage users. They define an nKode policy, keypad's dimensions,
|
values. The customers manage users. They define an nKode policy, keypad's dimensions,
|
||||||
attributes/sets in the keypad, and the frequency of attribute renewal.
|
properties/sets in the keypad, and the frequency of property renewal.
|
||||||
### nKode Policy and Keypad Size
|
### nKode Policy and Keypad Size
|
||||||
An nKode policy defines:
|
An nKode policy defines:
|
||||||
<ul>
|
<ul>
|
||||||
@@ -12,16 +12,16 @@ An nKode policy defines:
|
|||||||
<li>the minimum length of a user's nKode</li>
|
<li>the minimum length of a user's nKode</li>
|
||||||
<li>the number of unique set values in a user's nKode</li>
|
<li>the number of unique set values in a user's nKode</li>
|
||||||
<li>the number of unique values in a user's nKode</li>
|
<li>the number of unique values in a user's nKode</li>
|
||||||
<li>the number of bytes in an attribute and set</li>
|
<li>the number of bytes in an property and set</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
The keypad size defines:
|
The keypad size defines:
|
||||||
<ul>
|
<ul>
|
||||||
<li>the number of keys in the keypad displayed to the user</li>
|
<li>the number of keys in the keypad displayed to the user</li>
|
||||||
<li>attributes per key</li>
|
<li>properties per key</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
To be [dispersion](nkode_concepts.md/#dispersion-resistant-interface) resistant, the number of attributes must be greater than the number of keys.
|
To be [dispersion](nkode_concepts.md/#dispersion-resistant-interface) resistant, the number of properties must be greater than the number of keys.
|
||||||
|
|
||||||
```
|
```
|
||||||
api = NKodeAPI()
|
api = NKodeAPI()
|
||||||
@@ -30,7 +30,7 @@ policy = NKodePolicy(
|
|||||||
max_nkode_len=10,
|
max_nkode_len=10,
|
||||||
min_nkode_len=4,
|
min_nkode_len=4,
|
||||||
distinct_sets=0,
|
distinct_sets=0,
|
||||||
distinct_attributes=4,
|
distinct_properties=4,
|
||||||
byte_len=2
|
byte_len=2
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -42,36 +42,36 @@ keypad_size = KeypadSize(
|
|||||||
customer_id = api.create_new_customer(keypad_size, policy)
|
customer_id = api.create_new_customer(keypad_size, policy)
|
||||||
customer = api.customers[customer_id]
|
customer = api.customers[customer_id]
|
||||||
```
|
```
|
||||||
### Customer Attributes and Sets
|
### Customer properties and Sets
|
||||||
A customer has users and defines the attributes and set values for all its users.
|
A customer has users and defines the properties and set values for all its users.
|
||||||
Since our customer has {{ keypad_size.numb_of_keys }} keys and {{ keypad_size.props_per_key }} attributes per key,
|
Since our customer has {{ keypad_size.numb_of_keys }} keys and {{ keypad_size.props_per_key }} properties per key,
|
||||||
this gives a customer interface of {{ keypad_size.numb_of_props }} distinct attributes and {{ keypad_size.props_per_key }} distinct attribute sets.
|
this gives a customer interface of {{ keypad_size.numb_of_props }} distinct properties and {{ keypad_size.props_per_key }} distinct property 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.
|
Each property belongs to one of the {{ keypad_size.props_per_key }} sets. Each property and set value is a unique 2-byte integer in this example.
|
||||||
|
|
||||||
```
|
```
|
||||||
set_vals = customer.attributes.set_vals
|
set_vals = customer.cipher.set_key
|
||||||
|
|
||||||
Customer Sets: {{ customer_set_vals }}
|
Customer Sets: {{ customer_set_vals }}
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
attr_vals = customer.attributes.attr_vals
|
prop_vals = customer.cipher.prop_key
|
||||||
keypad_view(attr_vals, keypad_size.props_per_key)
|
keypad_view(prop_vals, keypad_size.props_per_key)
|
||||||
|
|
||||||
Customer Attributes:
|
Customer properties:
|
||||||
{% for attrs in customer_attr_view -%}
|
{% for props in customer_prop_view -%}
|
||||||
{{ attrs }}
|
{{ props }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
```
|
```
|
||||||
|
|
||||||
Attributes organized by set:
|
properties organized by set:
|
||||||
```
|
```
|
||||||
attr_set_view = matrix_transpose(attr_keypad_view)
|
prop_set_view = matrix_transpose(prop_keypad_view)
|
||||||
set_attribute_dict = dict(zip(set_vals, attr_set_view))
|
set_property_dict = dict(zip(set_vals, prop_set_view))
|
||||||
|
|
||||||
Set to Attribute Map:
|
Set to property Map:
|
||||||
{% for set_val, attrs in set_attribute_dict.items() -%}
|
{% for set_val, props in set_property_dict.items() -%}
|
||||||
{{ set_val }} : {{ attrs }}
|
{{ set_val }} : {{ props }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -83,12 +83,12 @@ Now that we have a customer, we can create users. To create a new user:
|
|||||||
3. The user confirms their nKode. If the user's nKode matches the policy, the server creates the user.
|
3. The user confirms their nKode. If the user's nKode matches the policy, the server creates the user.
|
||||||
### Random Interface Generation
|
### Random Interface Generation
|
||||||
The user's interface must be dispersable so the server can determine the user's nkode.
|
The user's interface must be dispersable so the server can determine the user's nkode.
|
||||||
The server randomly drops attribute sets until
|
The server randomly drops property sets until
|
||||||
the number of attributes equals the number of keys, making the interface dispersable.
|
the number of properties equals the number of keys, making the interface dispersable.
|
||||||
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" }}.
|
In our case, the server randomly drops {{ keypad_size.props_per_key - keypad_size.numb_of_keys }} property {{ "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 }}.
|
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.
|
Each value in the interface is the index value of a customer property.
|
||||||
The user never learns what their "real" attribute is. They do not see the index value representing their nKode or
|
The user never learns what their "real" property is. They do not see the index value representing their nKode or
|
||||||
the customer server-side value.
|
the customer server-side value.
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -102,9 +102,9 @@ Key {{ loop.index }}: {{ key }}
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Set nKode
|
### Set nKode
|
||||||
The user identifies attributes in the interface they want in their nkode. Each attribute has an index value.
|
The user identifies properties in the interface they want in their nkode. Each property has an index value.
|
||||||
Below, the user has selected `{{ user_passcode }}`. These index values can be represented by anything in the GUI.
|
Below, the user has selected `{{ user_passcode }}`. These index values can be represented by anything in the GUI.
|
||||||
The only requirement is that the GUI attributes be associated with the same index every time the user logs in.
|
The only requirement is that the GUI properties be associated with the same index every time the user logs in.
|
||||||
If users want to change anything about their interface, they must also change their nkode.
|
If users want to change anything about their interface, they must also change their nkode.
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -116,11 +116,11 @@ Selected Keys
|
|||||||
{{ selected_keys_set }}
|
{{ selected_keys_set }}
|
||||||
```
|
```
|
||||||
|
|
||||||
The user's passcode server side attributes are:
|
The user's passcode server side properties are:
|
||||||
```
|
```
|
||||||
server_side_attr = [customer.attributes.attr_vals[idx] for idx in user_passcode]
|
server_side_prop = [customer.cipher.prop_key[idx] for idx in user_passcode]
|
||||||
|
|
||||||
User Passcode Server-side Attributes: {{ server_side_attr }}
|
User Passcode Server-side properties: {{ server_side_prop }}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Confirm nKode
|
### Confirm nKode
|
||||||
@@ -149,7 +149,7 @@ success = api.confirm_nkode(username, customer_id, selected_keys_confirm, sessio
|
|||||||
When a new user creates an nKode, the server caches its set and confirms the interface and the user's key selection.
|
When a new user creates an nKode, the server caches its set and confirms the interface and the user's key selection.
|
||||||
On the last api.confirm_nkode, the server:
|
On the last api.confirm_nkode, the server:
|
||||||
|
|
||||||
1. Deduces the user's attributes
|
1. Deduces the user's properties
|
||||||
2. Validates the Passcode against the nKodePolicy
|
2. Validates the Passcode against the nKodePolicy
|
||||||
3. Creates new User Cipher Keys
|
3. Creates new User Cipher Keys
|
||||||
4. Enciphers the user's mask
|
4. Enciphers the user's mask
|
||||||
@@ -162,7 +162,7 @@ Steps 1-2 are straightforward. For a better idea of how they work, see pyNKode.
|
|||||||
##### User Cipher Keys Data Structure
|
##### User Cipher Keys Data Structure
|
||||||
```
|
```
|
||||||
set_key = generate_random_nonrepeating_list(keypad_size.props_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)
|
set_key = xor_lists(set_key, customer_prop.set_vals)
|
||||||
|
|
||||||
UserCipherKeys(
|
UserCipherKeys(
|
||||||
prop_key=generate_random_nonrepeating_list(keypad_size.props_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)),
|
||||||
@@ -211,17 +211,17 @@ Recall:
|
|||||||
|
|
||||||
```
|
```
|
||||||
passcode = {{ user_passcode }}
|
passcode = {{ user_passcode }}
|
||||||
passcode_server_attr = [customer.attributes.attr_vals[idx] for idx in passcode]
|
passcode_server_prop = [customer.cipher.prop_key[idx] for idx in passcode]
|
||||||
passcode_server_set = [customer.attributes.get_attr_set_val(attr) for attr in passcode_server_attr]
|
passcode_server_set = [customer.cipher.get_prop_set_val(prop) for prop in passcode_server_prop]
|
||||||
|
|
||||||
Passcode Set Vals: {{ passcode_server_attr }}
|
Passcode Set Vals: {{ passcode_server_prop }}
|
||||||
Passcode Attr Vals: {{ passcode_server_set }}
|
Passcode prop Vals: {{ passcode_server_set }}
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
padded_passcode_server_set = user_cipher.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]
|
set_idx = [customer.cipher.get_set_index(set_val) for set_val in padded_passcode_server_set]
|
||||||
mask_set_keys = [user_cipher.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(mask_set_keys, padded_passcode_server_set)
|
||||||
@@ -233,18 +233,18 @@ Mask: {{ enciphered_nkode.mask }}
|
|||||||
|
|
||||||
#### Passcode Enciphering and Hashing
|
#### Passcode Enciphering and Hashing
|
||||||
|
|
||||||
- ciphered_customer_attr = prop_key ^ customer_attr
|
- ciphered_customer_prop = prop_key ^ customer_prop
|
||||||
- ciphered_passcode_i = pass_key_i ^ ciphered_customer_attr_i
|
- ciphered_passcode_i = pass_key_i ^ ciphered_customer_prop_i
|
||||||
- code = hash(ciphered_passcode, salt)
|
- code = hash(ciphered_passcode, salt)
|
||||||
|
|
||||||
```
|
```
|
||||||
ciphered_customer_attrs = xor_lists(customer.attributes.attr_vals, user_cipher.prop_key)
|
ciphered_customer_props = xor_lists(customer.cipher.prop_key, user_cipher.prop_key)
|
||||||
passcode_ciphered_attrs = [ciphered_customer_attrs[idx] for idx in passcode]
|
passcode_ciphered_props = [ciphered_customer_props[idx] for idx in passcode]
|
||||||
pad_len = customer.nkode_policy.max_nkode_len - passcode_len
|
pad_len = customer.nkode_policy.max_nkode_len - passcode_len
|
||||||
|
|
||||||
passcode_ciphered_attrs.extend([0 for _ in range(pad_len)])
|
passcode_ciphered_props.extend([0 for _ in range(pad_len)])
|
||||||
|
|
||||||
ciphered_code = xor_lists(passcode_ciphered_attrs, user_cipher.pass_key)
|
ciphered_code = xor_lists(passcode_ciphered_props, user_cipher.pass_key)
|
||||||
|
|
||||||
passcode_bytes = int_array_to_bytes(ciphered_code)
|
passcode_bytes = int_array_to_bytes(ciphered_code)
|
||||||
passcode_digest = base64.b64encode(hashlib.sha256(passcode_bytes).digest())
|
passcode_digest = base64.b64encode(hashlib.sha256(passcode_bytes).digest())
|
||||||
@@ -281,8 +281,8 @@ success = api.login(customer_id, username, selected_keys_login)
|
|||||||
|
|
||||||
### Validate Login Key Entry
|
### Validate Login Key Entry
|
||||||
- decipher user mask and recover nkode set values
|
- decipher user mask and recover nkode set values
|
||||||
- get presumed attribute from key selection and set values
|
- get presumed property from key selection and set values
|
||||||
- encipher, salt, and hash presumed attribute values and compare them to the users hashed code
|
- encipher, salt, and hash presumed property values and compare them to the users hashed code
|
||||||
|
|
||||||
#### Decipher Mask
|
#### Decipher Mask
|
||||||
|
|
||||||
@@ -315,96 +315,96 @@ Passcode Sets: {{ login_passcode_sets }}
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Get Presumed Attributes
|
### Get Presumed properties
|
||||||
```
|
```
|
||||||
set_vals_idx = [customer.attributes.get_set_index(set_val) for set_val in passcode_sets]
|
set_vals_idx = [customer.cipher.get_set_index(set_val) for set_val in passcode_sets]
|
||||||
|
|
||||||
presumed_selected_attributes_idx = []
|
presumed_selected_properties_idx = []
|
||||||
for idx in range(passcode_len):
|
for idx in range(passcode_len):
|
||||||
key_numb = selected_keys_login[idx]
|
key_numb = selected_keys_login[idx]
|
||||||
set_idx = set_vals_idx[idx]
|
set_idx = set_vals_idx[idx]
|
||||||
selected_attr_idx = customer.users[username].user_interface.get_attr_idx_by_keynumb_setidx(key_numb, set_idx)
|
selected_prop_idx = customer.users[username].user_interface.get_prop_idx_by_keynumb_setidx(key_numb, set_idx)
|
||||||
presumed_selected_attributes_idx.append(selected_attr_idx)
|
presumed_selected_properties_idx.append(selected_prop_idx)
|
||||||
|
|
||||||
Presumped Passcode: {{ presumed_selected_attributes_idx }}
|
Presumped Passcode: {{ presumed_selected_properties_idx }}
|
||||||
Recall User Passcode: {{ user_passcode }}
|
Recall User Passcode: {{ user_passcode }}
|
||||||
```
|
```
|
||||||
### Compare Enciphered Passcodes
|
### Compare Enciphered Passcodes
|
||||||
```
|
```
|
||||||
enciphered_nkode = user_cipher.encipher_salt_hash_code(presumed_selected_attributes_idx, customer.attributes)
|
enciphered_nkode = user_cipher.encipher_salt_hash_code(presumed_selected_properties_idx, customer.cipher)
|
||||||
```
|
```
|
||||||
If `enciphered_nkode == user.enciphered_passcode.code`, the user's key selection is valid, and the login is successful.
|
If `enciphered_nkode == user.enciphered_passcode.code`, the user's key selection is valid, and the login is successful.
|
||||||
|
|
||||||
## Renew Attributes
|
## Renew properties
|
||||||
Attributes renew is invoked with the renew_attributes method: `api.renew_attributes(customer_id)`
|
properties renew is invoked with the renew_properties method: `api.renew_properties(customer_id)`
|
||||||
The renew attributes process has three steps:
|
The renew properties process has three steps:
|
||||||
1. Renew Customer Attributes
|
1. Renew Customer properties
|
||||||
2. Renew User Keys
|
2. Renew User Keys
|
||||||
3. Refresh User on Login
|
3. Refresh User on Login
|
||||||
|
|
||||||
When the customer calls the `renew_attributes` method, the method replaces the customer's attributes and set values. All its users go through an intermediate
|
When the customer calls the `renew_properties` method, the method replaces the customer's properties and set values. All its users go through an intermediate
|
||||||
renewal step. The users fully renew after their first successful login. This first login refreshes their keys, salt, and hash with new values.
|
renewal step. The users fully renew after their first successful login. This first login refreshes their keys, salt, and hash with new values.
|
||||||
|
|
||||||
|
|
||||||
### Customer Renew
|
### Customer Renew
|
||||||
Old Customer attributes and set values are cached and copied to variables before renewal.
|
Old Customer properties and set values are cached and copied to variables before renewal.
|
||||||
```
|
```
|
||||||
old_sets = customer.attributes.set_vals
|
old_sets = customer.cipher.set_key
|
||||||
|
|
||||||
Customer Sets: {{ customer_set_vals }}
|
Customer Sets: {{ customer_set_vals }}
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
old_attr = customer.attributes.attr_vals
|
old_prop = customer.cipher.prop_key
|
||||||
|
|
||||||
Customer Attributes:
|
Customer properties:
|
||||||
{% for attrs in customer_attr_view -%}
|
{% for props in customer_prop_view -%}
|
||||||
{{ attrs }}
|
{{ props }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
```
|
```
|
||||||
|
|
||||||
After the renewal, the customer attributes and sets are new randomly generated values.
|
After the renewal, the customer properties and sets are new randomly generated values.
|
||||||
```
|
```
|
||||||
api.renew_attributes(customer_id)
|
api.renew_properties(customer_id)
|
||||||
|
|
||||||
set_vals = customer.attributes.set_vals
|
set_vals = customer.cipher.set_key
|
||||||
|
|
||||||
Customer Sets: {{ customer_new_set_vals }}
|
Customer Sets: {{ customer_new_set_vals }}
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
attr_vals = customer.attributes.attr_vals
|
prop_vals = customer.cipher.prop_key
|
||||||
|
|
||||||
Customer Attributes:
|
Customer properties:
|
||||||
{% for attrs in customer_new_attr_view -%}
|
{% for props in customer_new_prop_view -%}
|
||||||
{{ attrs }}
|
{{ props }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Renew User
|
### Renew User
|
||||||
During the renewal, each user goes through a temporary transition period.
|
During the renewal, each user goes through a temporary transition period.
|
||||||
```
|
```
|
||||||
attrs_xor = xor_lists(new_attrs, old_attrs)
|
props_xor = xor_lists(new_props, old_props)
|
||||||
sets_xor = xor_lists(new_sets, old_sets)
|
sets_xor = xor_lists(new_sets, old_sets)
|
||||||
for user in customer.users.values():
|
for user in customer.users.values():
|
||||||
user.renew = True
|
user.renew = True
|
||||||
user.user_cipher.set_key = xor_lists(user.user_cipher.set_key, sets_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.user_cipher.prop_key = xor_lists(user.user_cipher.prop_key, props_xor)
|
||||||
```
|
```
|
||||||
##### User prop Key
|
##### User prop Key
|
||||||
The user's prop key was a randomly generated list of length `numb_of_keys * attr_per_key`.
|
The user's prop key was a randomly generated list of length `numb_of_keys * prop_per_key`.
|
||||||
Now each value in the prop key is `prop_key_i = old_prop_key_i ^ new_attr_i ^ old_attr_i`.
|
Now each value in the prop key is `prop_key_i = old_prop_key_i ^ new_prop_i ^ old_prop_i`.
|
||||||
Recall in the login process, `ciphered_customer_attrs = prop_key ^ customer_attr`.
|
Recall in the login process, `ciphered_customer_props = prop_key ^ customer_prop`.
|
||||||
Since the customer_attr is now the new value, it gets canceled out, leaving:
|
Since the customer_prop is now the new value, it gets canceled out, leaving:
|
||||||
```
|
```
|
||||||
new_prop_key = old_prop_key ^ old_attr ^ new_attr
|
new_prop_key = old_prop_key ^ old_prop ^ new_prop
|
||||||
ciphered_customer_attrs = new_prop_key ^ new_attr
|
ciphered_customer_props = new_prop_key ^ new_prop
|
||||||
ciphered_customer_attrs = old_prop_key ^ old_attr # since new_attr cancel out
|
ciphered_customer_props = old_prop_key ^ old_prop # since new_prop cancel out
|
||||||
```
|
```
|
||||||
Using the new customer attributes, we can validate the user's login attempt with the same hash.
|
Using the new customer properties, we can validate the user's login attempt with the same hash.
|
||||||
|
|
||||||
##### User Set Key
|
##### User Set Key
|
||||||
The user's set key was a randomly generated list of length `attr_per_key` xor `customer_set_vals`.
|
The user's set key was a randomly generated list of length `prop_per_key` xor `customer_set_vals`.
|
||||||
The `old_set_vals` have been replaced with the new `new_set_vals`. The deciphering process described above
|
The `old_set_vals` have been replaced with the new `new_set_vals`. The deciphering process described above
|
||||||
remains the same.
|
remains the same.
|
||||||
|
|
||||||
@@ -413,10 +413,10 @@ Once the user has a successful login, they get a new salt and cipher keys, and t
|
|||||||
with the new values.
|
with the new values.
|
||||||
```
|
```
|
||||||
user.user_cipher = UserCipherKeys.new(
|
user.user_cipher = UserCipherKeys.new(
|
||||||
customer.attributes.keypad_size,
|
customer.cipher.keypad_size,
|
||||||
customer.attributes.set_vals,
|
customer.cipher.set_key,
|
||||||
user.user_cipher.max_nkode_len
|
user.user_cipher.max_nkode_len
|
||||||
)
|
)
|
||||||
user.enciphered_passcode = user.user_cipher.encipher_nkode(presumed_selected_attributes_idx, customer.attributes)
|
user.enciphered_passcode = user.user_cipher.encipher_nkode(presumed_selected_properties_idx, customer.cipher)
|
||||||
user.renew = False
|
user.renew = False
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ def random_username() -> str:
|
|||||||
return "test_username" + "".join([choice(ascii_lowercase) for _ in range(6)])
|
return "test_username" + "".join([choice(ascii_lowercase) for _ in range(6)])
|
||||||
|
|
||||||
|
|
||||||
def select_keys_with_passcode_values(user_passcode: list[int], keypad: np.ndarray, attrs_per_key: int) -> list[int]:
|
def select_keys_with_passcode_values(user_passcode: list[int], keypad: np.ndarray, props_per_key: int) -> list[int]:
|
||||||
indices = [np.where(keypad == attr)[0][0] for attr in user_passcode]
|
indices = [np.where(keypad == prop)[0][0] for prop in user_passcode]
|
||||||
return [int(index // attrs_per_key) for index in indices]
|
return [int(index // props_per_key) for index in indices]
|
||||||
|
|
||||||
|
|
||||||
def visualize_keypad(keypad_list: np.ndarray, props_per_key: int):
|
def visualize_keypad(keypad_list: np.ndarray, props_per_key: int):
|
||||||
@@ -64,12 +64,12 @@ if __name__ == "__main__":
|
|||||||
customer = api.customers[customer_id]
|
customer = api.customers[customer_id]
|
||||||
|
|
||||||
set_vals = customer.cipher.set_key
|
set_vals = customer.cipher.set_key
|
||||||
attr_vals = customer.cipher.prop_key
|
prop_vals = customer.cipher.prop_key
|
||||||
customer_attr_view = attr_vals.reshape(-1, keypad_size.props_per_key)
|
customer_prop_view = prop_vals.reshape(-1, keypad_size.props_per_key)
|
||||||
|
|
||||||
attr_keypad_view = attr_vals.reshape(-1, keypad_size.props_per_key)
|
prop_keypad_view = prop_vals.reshape(-1, keypad_size.props_per_key)
|
||||||
attr_set_view = attr_keypad_view.T
|
prop_set_view = prop_keypad_view.T
|
||||||
set_attribute_dict = dict(zip(set_vals, attr_set_view))
|
set_property_dict = dict(zip(set_vals, prop_set_view))
|
||||||
|
|
||||||
session_id, signup_interface = api.generate_signup_keypad(customer_id)
|
session_id, signup_interface = api.generate_signup_keypad(customer_id)
|
||||||
signup_keypad = signup_interface.reshape(-1, keypad_size.numb_of_keys)
|
signup_keypad = signup_interface.reshape(-1, keypad_size.numb_of_keys)
|
||||||
@@ -78,7 +78,7 @@ if __name__ == "__main__":
|
|||||||
passcode_len = 4
|
passcode_len = 4
|
||||||
user_passcode = signup_interface[:passcode_len].tolist()
|
user_passcode = signup_interface[:passcode_len].tolist()
|
||||||
selected_keys_set = select_keys_with_passcode_values(user_passcode, signup_interface, keypad_size.numb_of_keys)
|
selected_keys_set = select_keys_with_passcode_values(user_passcode, signup_interface, keypad_size.numb_of_keys)
|
||||||
server_side_attr = [customer.cipher.prop_key[idx] for idx in user_passcode]
|
server_side_prop = [customer.cipher.prop_key[idx] for idx in user_passcode]
|
||||||
|
|
||||||
confirm_interface = api.set_nkode(username, customer_id, selected_keys_set, session_id)
|
confirm_interface = api.set_nkode(username, customer_id, selected_keys_set, session_id)
|
||||||
|
|
||||||
@@ -88,8 +88,8 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
success = api.confirm_nkode(username, customer_id, selected_keys_confirm, session_id)
|
success = api.confirm_nkode(username, customer_id, selected_keys_confirm, session_id)
|
||||||
assert success
|
assert success
|
||||||
passcode_server_attr = [customer.cipher.prop_key[idx] for idx in user_passcode]
|
passcode_server_prop = [customer.cipher.prop_key[idx] for idx in user_passcode]
|
||||||
passcode_server_set = [customer.cipher.get_prop_set_val(attr) for attr in passcode_server_attr]
|
passcode_server_set = [customer.cipher.get_prop_set_val(prop) for prop in passcode_server_prop]
|
||||||
|
|
||||||
user_keys = customer.users[username].cipher
|
user_keys = customer.users[username].cipher
|
||||||
|
|
||||||
@@ -100,14 +100,12 @@ if __name__ == "__main__":
|
|||||||
ciphered_mask = np.bitwise_xor(mask_set_keys, padded_passcode_server_set)
|
ciphered_mask = np.bitwise_xor(mask_set_keys, padded_passcode_server_set)
|
||||||
ciphered_mask = np.bitwise_xor(ciphered_mask, user_keys.mask_key)
|
ciphered_mask = np.bitwise_xor(ciphered_mask, user_keys.mask_key)
|
||||||
mask = user_keys.encode_base64_str(ciphered_mask)
|
mask = user_keys.encode_base64_str(ciphered_mask)
|
||||||
#ciphered_customer_attrs = xor_lists(customer.cipher.prop_key, user_keys.prop_key)
|
#ciphered_customer_props = xor_lists(customer.cipher.prop_key, user_keys.prop_key)
|
||||||
ciphered_customer_attrs = np.bitwise_xor(customer.cipher.prop_key, user_keys.prop_key)
|
ciphered_customer_props = np.bitwise_xor(customer.cipher.prop_key, user_keys.prop_key)
|
||||||
passcode_ciphered_attrs = [ciphered_customer_attrs[idx] for idx in user_passcode]
|
passcode_ciphered_props = [ciphered_customer_props[idx] for idx in user_passcode]
|
||||||
pad_len = customer.nkode_policy.max_nkode_len - passcode_len
|
pad_len = customer.nkode_policy.max_nkode_len - passcode_len
|
||||||
passcode_ciphered_attrs.extend([0 for _ in range(pad_len)])
|
passcode_ciphered_props.extend([0 for _ in range(pad_len)])
|
||||||
#ciphered_code = xor_lists(passcode_ciphered_attrs, user_keys.pass_key)
|
ciphered_code = np.bitwise_xor(passcode_ciphered_props, user_keys.pass_key)
|
||||||
ciphered_code = np.bitwise_xor(passcode_ciphered_attrs, user_keys.pass_key)
|
|
||||||
#passcode_bytes = int_array_to_bytes(ciphered_code)
|
|
||||||
passcode_bytes = ciphered_code.tobytes()
|
passcode_bytes = ciphered_code.tobytes()
|
||||||
passcode_digest = base64.b64encode(hashlib.sha256(passcode_bytes).digest())
|
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_keys.salt)
|
||||||
@@ -144,37 +142,37 @@ if __name__ == "__main__":
|
|||||||
login_passcode_sets.append(int(set_vals[set_idx]))
|
login_passcode_sets.append(int(set_vals[set_idx]))
|
||||||
|
|
||||||
"""
|
"""
|
||||||
GET PRESUMED ATTRIBUTES
|
GET PRESUMED properties
|
||||||
"""
|
"""
|
||||||
|
|
||||||
set_vals_idx = [customer.cipher.get_set_index(set_val) for set_val in login_passcode_sets]
|
set_vals_idx = [customer.cipher.get_set_index(set_val) for set_val in login_passcode_sets]
|
||||||
|
|
||||||
presumed_selected_attributes_idx = []
|
presumed_selected_properties_idx = []
|
||||||
for idx in range(passcode_len):
|
for idx in range(passcode_len):
|
||||||
key_numb = selected_keys_login[idx]
|
key_numb = selected_keys_login[idx]
|
||||||
set_idx = set_vals_idx[idx]
|
set_idx = set_vals_idx[idx]
|
||||||
selected_attr_idx = customer.users[username].user_keypad.get_prop_idx_by_keynumb_setidx(key_numb, set_idx)
|
selected_prop_idx = customer.users[username].user_keypad.get_prop_idx_by_keynumb_setidx(key_numb, set_idx)
|
||||||
presumed_selected_attributes_idx.append(selected_attr_idx)
|
presumed_selected_properties_idx.append(selected_prop_idx)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
RENEW KEYS
|
RENEW KEYS
|
||||||
"""
|
"""
|
||||||
|
|
||||||
old_attrs = customer.cipher.prop_key.copy()
|
old_props = customer.cipher.prop_key.copy()
|
||||||
old_sets = customer.cipher.set_key.copy()
|
old_sets = customer.cipher.set_key.copy()
|
||||||
customer.cipher.renew()
|
customer.cipher.renew()
|
||||||
new_attrs = customer.cipher.prop_key
|
new_props = customer.cipher.prop_key
|
||||||
new_sets = customer.cipher.set_key
|
new_sets = customer.cipher.set_key
|
||||||
customer_new_attr_view = new_attrs.reshape(-1, keypad_size.props_per_key)
|
customer_new_prop_view = new_props.reshape(-1, keypad_size.props_per_key)
|
||||||
"""
|
"""
|
||||||
RENEW USER
|
RENEW USER
|
||||||
"""
|
"""
|
||||||
attrs_xor = np.bitwise_xor(new_attrs, old_attrs)
|
props_xor = np.bitwise_xor(new_props, old_props)
|
||||||
sets_xor = np.bitwise_xor(new_sets, old_sets)
|
sets_xor = np.bitwise_xor(new_sets, old_sets)
|
||||||
for user in customer.users.values():
|
for user in customer.users.values():
|
||||||
user.renew = True
|
user.renew = True
|
||||||
user.cipher.set_key = np.bitwise_xor(user.cipher.set_key, sets_xor)
|
user.cipher.set_key = np.bitwise_xor(user.cipher.set_key, sets_xor)
|
||||||
user.cipher.prop_key = np.bitwise_xor(user.cipher.prop_key, attrs_xor)
|
user.cipher.prop_key = np.bitwise_xor(user.cipher.prop_key, props_xor)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
REFRESH USER KEYS
|
REFRESH USER KEYS
|
||||||
@@ -184,31 +182,31 @@ if __name__ == "__main__":
|
|||||||
customer.cipher.set_key,
|
customer.cipher.set_key,
|
||||||
user.cipher.max_nkode_len
|
user.cipher.max_nkode_len
|
||||||
)
|
)
|
||||||
user.enciphered_passcode = user.cipher.encipher_nkode(presumed_selected_attributes_idx, customer.cipher)
|
user.enciphered_passcode = user.cipher.encipher_nkode(presumed_selected_properties_idx, customer.cipher)
|
||||||
user.renew = False
|
user.renew = False
|
||||||
|
|
||||||
# Define some data to pass to the template
|
# Define some data to pass to the template
|
||||||
data = {
|
data = {
|
||||||
'keypad_size': keypad_size,
|
'keypad_size': keypad_size,
|
||||||
'customer_set_vals': set_vals,
|
'customer_set_vals': set_vals,
|
||||||
'customer_attr_view': customer_attr_view,
|
'customer_prop_view': customer_prop_view,
|
||||||
'set_attribute_dict': set_attribute_dict,
|
'set_property_dict': set_property_dict,
|
||||||
'signup_keypad': signup_keypad,
|
'signup_keypad': signup_keypad,
|
||||||
'username': 'test_user',
|
'username': 'test_user',
|
||||||
'user_passcode': user_passcode,
|
'user_passcode': user_passcode,
|
||||||
'selected_keys_set': selected_keys_set,
|
'selected_keys_set': selected_keys_set,
|
||||||
'server_side_attr': server_side_attr,
|
'server_side_prop': server_side_prop,
|
||||||
'confirm_keypad': confirm_keypad,
|
'confirm_keypad': confirm_keypad,
|
||||||
'selected_keys_confirm': selected_keys_confirm,
|
'selected_keys_confirm': selected_keys_confirm,
|
||||||
'user_cipher': user_keys,
|
'user_cipher': user_keys,
|
||||||
'passcode_server_attr': passcode_server_attr,
|
'passcode_server_prop': passcode_server_prop,
|
||||||
'passcode_server_set': passcode_server_set,
|
'passcode_server_set': passcode_server_set,
|
||||||
'enciphered_nkode': enciphered_nkode,
|
'enciphered_nkode': enciphered_nkode,
|
||||||
'login_keypad': login_keypad,
|
'login_keypad': login_keypad,
|
||||||
'selected_login_keys': selected_keys_login,
|
'selected_login_keys': selected_keys_login,
|
||||||
'login_passcode_sets': login_passcode_sets,
|
'login_passcode_sets': login_passcode_sets,
|
||||||
'presumed_selected_attributes_idx': presumed_selected_attributes_idx,
|
'presumed_selected_properties_idx': presumed_selected_properties_idx,
|
||||||
'customer_new_attr_view': customer_new_attr_view,
|
'customer_new_prop_view': customer_new_prop_view,
|
||||||
'customer_new_set_vals': new_sets,
|
'customer_new_set_vals': new_sets,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,16 +26,16 @@
|
|||||||
"\n",
|
"\n",
|
||||||
" for key in range(keypad_size.numb_of_keys):\n",
|
" for key in range(keypad_size.numb_of_keys):\n",
|
||||||
" table += f\"\\n|key{key+1}|\"\n",
|
" table += f\"\\n|key{key+1}|\"\n",
|
||||||
" table += \"|\".join([str(attr) for attr in keypad[key]])\n",
|
" table += \"|\".join([str(prop) for prop in keypad[key]])\n",
|
||||||
" table += \"|\"\n",
|
" table += \"|\"\n",
|
||||||
" return table\n",
|
" return table\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"keypad_size = KeypadSize(numb_of_keys=5, props_per_key=4)\n",
|
"keypad_size = KeypadSize(numb_of_keys=5, props_per_key=4)\n",
|
||||||
"attrs = [1, 10, 11, 100]\n",
|
"props = [1, 10, 11, 100]\n",
|
||||||
"keypad = []\n",
|
"keypad = []\n",
|
||||||
"for key_numb in range(1,keypad_size.numb_of_keys+1):\n",
|
"for key_numb in range(1,keypad_size.numb_of_keys+1):\n",
|
||||||
" keypad.extend([key_numb * attr for attr in attrs])\n",
|
" keypad.extend([key_numb * prop for prop in props])\n",
|
||||||
"\n",
|
"\n",
|
||||||
"demo_interface = UserKeypad(keypad_size=keypad_size, keypad=np.array(keypad))\n",
|
"demo_interface = UserKeypad(keypad_size=keypad_size, keypad=np.array(keypad))\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user