Add Validate nkode
This commit is contained in:
152
docs/encipher_decipher_nkode.md
Normal file
152
docs/encipher_decipher_nkode.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# Encipher and Decipher nKode
|
||||
|
||||
### Customer Policy
|
||||
- max nkode length: 10
|
||||
- number of keys: 6
|
||||
- properties per key: 9
|
||||
- total number of properties: 54
|
||||
|
||||
### Customer Cipher
|
||||
- property key: [50817 32783 33745 35836 30092 4212 15938 64571 58354 41241 3649 38852
|
||||
37860 47294 10501 43278 9946 60484 34443 38446 57997 32874 49251 58321
|
||||
15849 40891 43566 53732 31357 5248 22060 15762 23773 10428 22850 7975
|
||||
11108 23454 32723 40871 6994 35130 41638 13889 6569 20765 56191 37770
|
||||
4448 37031 30452 43080 24525 44717]
|
||||
- position key: [25392 13634 17753 25555 61290 50870 49934 53104 9796]
|
||||
|
||||
|
||||
---
|
||||
|
||||
### User Cipher
|
||||
- property key: [35724 37130 47630 20125 52673 62248 61979 44917 17470 11483 20317 56084
|
||||
34699 49571 32249 15009 43246 57623 21032 62384 61961 34049 1963 5370
|
||||
1121 47700 26633 59166 16526 38173 56846 41594 54438 8714 46049 25028
|
||||
38681 2017 39749 42164 38277 19216 23760 35115 23020 18954 26604 50262
|
||||
21588 62239 30226 58722 12644 39141]
|
||||
- passcode key: [51522 14440 21036 1484 4829 51359 61560 41543 23848 29080]
|
||||
- combined position key: [14972 5803 54986 46940 19674 32943 38431 42194 29083]
|
||||
- mask key: [15948 8251 52095 4511 25902 21701 15340 4458 15137 44295]
|
||||
|
||||
#### Combined Postion Key
|
||||
```mermaid
|
||||
block-beta
|
||||
columns 2
|
||||
user_pos["user position key:\n[22860 9193 37779 54415 41904 17945 21777 27554 22495]"]
|
||||
customer_pos["customer position key:\n[25392 13634 17753 25555 61290 50870 49934 53104 9796]"]
|
||||
space:2
|
||||
xor(("XOR")):2
|
||||
user_pos --> xor
|
||||
customer_pos --> xor
|
||||
space:2
|
||||
comb_pos["combined position key\n[14972 5803 54986 46940 19674 32943 38431 42194 29083]"]:2
|
||||
xor --> comb_pos
|
||||
```
|
||||
|
||||
### User Keypad
|
||||
- keypad:
|
||||
- user passcode indices: [22, 6, 38, 21]
|
||||
|
||||
### nKode Cipher
|
||||
|
||||
#### Passcode Hash
|
||||
```mermaid
|
||||
block-beta
|
||||
columns 2
|
||||
cprop["customer_property_key\n[50817 32783 33745 35836 30092 4212 15938 64571 58354 41241 3649 38852
|
||||
37860 47294 10501 43278 9946 60484 34443 38446 57997 32874 49251 58321
|
||||
15849 40891 43566 53732 31357 5248 22060 15762 23773 10428 22850 7975
|
||||
11108 23454 32723 40871 6994 35130 41638 13889 6569 20765 56191 37770
|
||||
4448 37031 30452 43080 24525 44717]"]
|
||||
uprop["user_property_key\n[35724 37130 47630 20125 52673 62248 61979 44917 17470 11483 20317 56084
|
||||
34699 49571 32249 15009 43246 57623 21032 62384 61961 34049 1963 5370
|
||||
1121 47700 26633 59166 16526 38173 56846 41594 54438 8714 46049 25028
|
||||
38681 2017 39749 42164 38277 19216 23760 35115 23020 18954 26604 50262
|
||||
21588 62239 30226 58722 12644 39141]"]
|
||||
space:2
|
||||
xor1(("XOR")):2
|
||||
cprop --> xor1
|
||||
uprop --> xor1
|
||||
space:2
|
||||
prop["combined_property_key\n[19725 4357 14815 50529 47181 58204 52313 21326 42956 36290 16668 19664
|
||||
5231 31005 21756 37807 36404 3411 54435 26014 4228 1387 51144 63275
|
||||
14728 9711 49703 14074 15091 33181 34850 40936 34939 2742 60067 32483
|
||||
48253 23679 58518 15123 36567 49706 65142 49002 16453 6935 48275 22492
|
||||
17716 25528 230 19754 28329 13896]"]
|
||||
xor1 --> prop
|
||||
pass["user_passcode_indices\n[22, 6, 38, 21]"]
|
||||
space:2
|
||||
sel(("select\properties")):2
|
||||
pass --> sel
|
||||
prop --> sel
|
||||
space:2
|
||||
passcode["user passcode properties:\n[51144 52313 58518 1387]"]:2
|
||||
sel --> passcode
|
||||
space:2
|
||||
pad["zero pad to\nmax nkode length: 10"]:2
|
||||
passcode -->pad
|
||||
space:2
|
||||
paddedpasscode["padded passcode:\n[51144 52313 58518 1387 0 0 0 0 0 0]"]
|
||||
pad --> paddedpasscode
|
||||
passkey["passcode key:\n[51522 14440 21036 1484 4829 51359 61560 41543 23848 29080]"]
|
||||
space:2
|
||||
xor2(("XOR")):2
|
||||
passkey --> xor2
|
||||
paddedpasscode --> xor2
|
||||
space:2
|
||||
cipheredpass["ciphered passcode:\n[ 3722 62513 46778 167 4829 51359 61560 41543 23848 29080]"]:2
|
||||
xor2 --> cipheredpass
|
||||
space:2
|
||||
hash(("hash")):2
|
||||
cipheredpass --> hash
|
||||
space:2
|
||||
cipheredhashed["hashed ciphered passcode:\n$2b$12$AQRZP88momhTaKGYaPzdiuBybg7V49SiZ8y9PQMoT0plZrEsbYO.K"]:2
|
||||
hash --> cipheredhashed
|
||||
```
|
||||
|
||||
#### Mask Encipher
|
||||
```mermaid
|
||||
block-beta
|
||||
columns 3
|
||||
passcode_idx["passcode indices:\n[22, 6, 38, 21]"]
|
||||
comb_pos["combined position key:\n[14972 5803 54986 46940 19674 32943 38431 42194 29083]"]
|
||||
cust_pos["customer position key:\n[25392 13634 17753 25555 61290 50870 49934 53104 9796]"]
|
||||
|
||||
space:3
|
||||
propidx(["Get Position Idx:\nmap each to element mod props_per_key"])
|
||||
passcode_idx-->propidx
|
||||
space:1
|
||||
xor1(("XOR"))
|
||||
comb_pos --> xor1
|
||||
cust_pos --> xor1
|
||||
|
||||
space:3
|
||||
passcode_position_idx["passcode poition indices:\n[4, 6, 2, 3]"]
|
||||
propidx --> passcode_position_idx
|
||||
|
||||
space:5
|
||||
pad1(("Pad with\nrandom indices"))
|
||||
passcode_position_idx --> pad1
|
||||
|
||||
space:5
|
||||
posidx["Padded Passcode Position Indices:\n[4, 6, 2, 3, 7, 1, 8, 0, 5, 4]"]
|
||||
pad1 --> posidx
|
||||
space:1
|
||||
user_pos["user position key:\n[22860 9193 37779 54415 41904 17945 21777 27554 22495]"]
|
||||
xor1 --> user_pos
|
||||
|
||||
space:4
|
||||
sel(("select positions"))
|
||||
user_pos --> sel
|
||||
posidx --> sel
|
||||
space:5
|
||||
passcode_pos["passcode positions:\n[41904 21777 37779 54415 27554 9193 22495 22860 17945 41904]"]
|
||||
sel --> passcode_pos
|
||||
mask_key["mask key\n[15948 8251 52095 4511 25902 21701 15340 4458 15137 44295]"]
|
||||
space:4
|
||||
xor2(("XOR"))
|
||||
mask_key --> xor2
|
||||
passcode_pos --> xor2
|
||||
space:5
|
||||
mask["enciphered mask:\n [40444 29994 22764 50448 3724 30508 27699 18470 32056 3767]"]
|
||||
xor2 --> mask
|
||||
```
|
||||
@@ -51,7 +51,6 @@ if __name__ == "__main__":
|
||||
selected_keys_confirm = select_keys_with_passcode_values(passcode_property_indices, confirm_keypad,
|
||||
keypad_size.numb_of_keys)
|
||||
ordered_confirm_icons = emojis[confirm_keypad]
|
||||
print(f"Selected Keys\n{selected_keys_confirm}")
|
||||
success = api.confirm_nkode(customer_id, selected_keys_confirm, signup_session_id)
|
||||
context = {
|
||||
"email": "user@example.com",
|
||||
|
||||
79
docs/scripts/render_encipher_decipher_diagrams.py
Normal file
79
docs/scripts/render_encipher_decipher_diagrams.py
Normal file
@@ -0,0 +1,79 @@
|
||||
import base64
|
||||
import hashlib
|
||||
from pathlib import Path
|
||||
|
||||
import bcrypt
|
||||
import numpy as np
|
||||
from secrets import choice
|
||||
from string import ascii_lowercase
|
||||
from docs.scripts.utils import render_markdown_template, emojis
|
||||
from src.models import NKodePolicy, KeypadSize
|
||||
from src.nkode_api import NKodeAPI
|
||||
from src.utils import select_keys_with_passcode_values
|
||||
|
||||
if __name__ == "__main__":
|
||||
api = NKodeAPI()
|
||||
|
||||
policy = NKodePolicy(
|
||||
max_nkode_len=10,
|
||||
min_nkode_len=4,
|
||||
distinct_positions=0,
|
||||
distinct_properties=4,
|
||||
)
|
||||
keypad_size = KeypadSize(
|
||||
numb_of_keys=6,
|
||||
props_per_key=9
|
||||
)
|
||||
customer_id = api.create_new_customer(keypad_size, policy)
|
||||
customer = api.get_customer(customer_id)
|
||||
username = "test_username" + "".join([choice(ascii_lowercase) for _ in range(6)])
|
||||
signup_session_id, set_signup_keypad = api.generate_signup_keypad(customer_id, username)
|
||||
ordered_set_icons = emojis[set_signup_keypad]
|
||||
passcode_len = 4
|
||||
passcode_property_indices = np.random.choice(set_signup_keypad.reshape(-1), size=passcode_len,
|
||||
replace=False).tolist()
|
||||
selected_keys_set = select_keys_with_passcode_values(passcode_property_indices, set_signup_keypad,
|
||||
keypad_size.numb_of_keys)
|
||||
confirm_keypad = api.set_nkode(customer_id, selected_keys_set, signup_session_id)
|
||||
selected_keys_confirm = select_keys_with_passcode_values(passcode_property_indices, confirm_keypad,
|
||||
keypad_size.numb_of_keys)
|
||||
ordered_confirm_icons = emojis[confirm_keypad]
|
||||
success = api.confirm_nkode(customer_id, selected_keys_confirm, signup_session_id)
|
||||
user = api.customers[customer_id].users[username]
|
||||
combined_prop_key = user.cipher.property_key ^ customer.cipher.property_key
|
||||
user_passcode = combined_prop_key[passcode_property_indices]
|
||||
pad_len = customer.nkode_policy.max_nkode_len - passcode_len
|
||||
padded_passcode = np.concatenate((user_passcode, np.zeros(pad_len, dtype=user_passcode.dtype)))
|
||||
ciphered_passcode = padded_passcode ^ user.cipher.pass_key
|
||||
passcode_prehash = base64.b64encode(hashlib.sha256(ciphered_passcode.tobytes()).digest())
|
||||
passcode_hash = bcrypt.hashpw(passcode_prehash, bcrypt.gensalt(rounds=12)).decode("utf-8")
|
||||
|
||||
padded_passcode_position_indices = customer.cipher.get_passcode_position_indices_padded(
|
||||
list(passcode_property_indices), customer.nkode_policy.max_nkode_len)
|
||||
user_position_key = user.cipher.combined_position_key ^ customer.cipher.position_key
|
||||
ordered_user_position_key = user_position_key[padded_passcode_position_indices]
|
||||
mask = ordered_user_position_key ^ user.cipher.mask_key
|
||||
encoded_mask = user.cipher.encode_base64_str(mask)
|
||||
context = {
|
||||
"max_nkode_len": policy.max_nkode_len,
|
||||
"numb_of_keys": keypad_size.numb_of_keys,
|
||||
"props_per_key": keypad_size.props_per_key,
|
||||
"customer_property_key": customer.cipher.property_key,
|
||||
"customer_position_key": customer.cipher.position_key,
|
||||
"user_property_key": user.cipher.property_key,
|
||||
"pass_key": user.cipher.pass_key,
|
||||
"combined_position_key": user.cipher.combined_position_key,
|
||||
"user_position_key": user_position_key,
|
||||
"mask_key": user.cipher.mask_key,
|
||||
"user_passcode_idxs": passcode_property_indices,
|
||||
"combined_property_key": combined_prop_key,
|
||||
"user_passcode_props": user_passcode,
|
||||
"padded_passcode": padded_passcode,
|
||||
"ciphered_passcode": ciphered_passcode,
|
||||
"code": passcode_hash,
|
||||
"passcode_position_idxs": padded_passcode_position_indices[:passcode_len],
|
||||
"pad_user_passcode_idxs": padded_passcode_position_indices,
|
||||
"ordered_user_position_key":ordered_user_position_key,
|
||||
"mask": mask,
|
||||
}
|
||||
render_markdown_template(Path("../templates/encipher_decipher_nkode.template.md"), Path("../encipher_decipher_nkode.md"), context)
|
||||
105
docs/templates/encipher_decipher_nkode.template.md
vendored
105
docs/templates/encipher_decipher_nkode.template.md
vendored
@@ -1,46 +1,46 @@
|
||||
# Encipher and Decipher nKode
|
||||
|
||||
### Customer Policy
|
||||
## Customer Policy
|
||||
- max nkode length: {{ max_nkode_len }}
|
||||
- number of keys: {{ numb_of_keys }}
|
||||
- properties per key: {{ props_per_key }}
|
||||
- total number of properties: {{ numb_of_keys * props_per_key }}
|
||||
|
||||
### Customer Cipher
|
||||
## Customer Cipher
|
||||
- property key: {{ customer_property_key }}
|
||||
- position key: {{ customer_position_key }}
|
||||
|
||||
|
||||
---
|
||||
|
||||
### User Cipher
|
||||
## User Cipher
|
||||
- property key: {{ user_property_key }}
|
||||
- passcode key: {{ pass_key }}
|
||||
- combined position key: {{ combined_position_key }}
|
||||
- mask key: {{ mask_key }}
|
||||
|
||||
#### Combined Postion Key
|
||||
### Combined Postion Key
|
||||
```mermaid
|
||||
block-beta
|
||||
columns 2
|
||||
user_pos["user postion key:\n{{user_postion_key}}"]
|
||||
customer_pos["customer postion key:\n{{customer_position_key}}"]
|
||||
user_pos["user position key:\n{{user_position_key}}"]
|
||||
customer_pos["customer position key:\n{{customer_position_key}}"]
|
||||
space:2
|
||||
xor(("XOR")):2
|
||||
user_pos --> xor
|
||||
customer_pos --> xor
|
||||
space:2
|
||||
comb_pos["combined postion key\n{{combined_postion_key}}"]:2
|
||||
comb_pos["combined position key\n{{combined_position_key}}"]:2
|
||||
xor --> comb_pos
|
||||
```
|
||||
|
||||
### User Keypad
|
||||
## User Keypad
|
||||
- keypad: {{ user_keypad}}
|
||||
- user passcode indicies: {{ user_passcode_idxs}}
|
||||
- user passcode indices: {{ user_passcode_idxs}}
|
||||
|
||||
### nKode Cipher
|
||||
## nKode Cipher
|
||||
|
||||
#### Passcode Hash
|
||||
### Passcode Hash
|
||||
```mermaid
|
||||
block-beta
|
||||
columns 2
|
||||
@@ -51,15 +51,15 @@ columns 2
|
||||
cprop --> xor1
|
||||
uprop --> xor1
|
||||
space:2
|
||||
prop["combined_properity_key\n{{combined_property_key}}"]
|
||||
prop["combined_property_key\n{{combined_property_key}}"]
|
||||
xor1 --> prop
|
||||
pass["user_passcode_indicies\n{{user_passcode_idxs}}"]
|
||||
pass["user_passcode_indices\n{{user_passcode_idxs}}"]
|
||||
space:2
|
||||
sel(("select\nproperites")):2
|
||||
sel(("select\nproperties")):2
|
||||
pass --> sel
|
||||
prop --> sel
|
||||
space:2
|
||||
passcode["passcode vals:\n{{passcode_vals}}"]:2
|
||||
passcode["user passcode properties:\n{{user_passcode_props}}"]:2
|
||||
sel --> passcode
|
||||
space:2
|
||||
pad["zero pad to\nmax nkode length: {{max_nkode_len}}"]:2
|
||||
@@ -83,39 +83,43 @@ columns 2
|
||||
hash --> cipheredhashed
|
||||
```
|
||||
|
||||
#### Mask Encipher
|
||||
### Mask Encipher
|
||||
```mermaid
|
||||
block-beta
|
||||
columns 3
|
||||
passcode_idx["passcode indicies:\n{{user_passcode_idxs}}"]
|
||||
comb_pos["combined position key"]
|
||||
cust_pos["customer position key"]
|
||||
passcode_idx["passcode indices:\n{{user_passcode_idxs}}"]
|
||||
comb_pos["combined position key:\n{{combined_position_key}}"]
|
||||
cust_pos["customer position key:\n{{customer_position_key}}"]
|
||||
|
||||
space:3
|
||||
pad1(("Pad with\nrandom indices"))
|
||||
propidx(["Get Position Idx:\nmap each to element mod props_per_key"])
|
||||
passcode_idx-->propidx
|
||||
space:1
|
||||
xor1(("XOR"))
|
||||
comb_pos --> xor1
|
||||
cust_pos --> xor1
|
||||
passcode_idx --> pad1
|
||||
|
||||
space:3
|
||||
padded_passcode_idx["padded passcode indices:\n{{pad_user_passcode_idxs}}"]
|
||||
pad1 --> padded_passcode_idx
|
||||
passcode_position_idx["passcode poition indices:\n{{passcode_position_idxs}}"]
|
||||
propidx --> passcode_position_idx
|
||||
|
||||
space:5
|
||||
propidx(["Get Postion Idx:\nmap each to\nelement mod props_per_key"])
|
||||
padded_passcode_idx --> propidx
|
||||
pad1(("Pad with\nrandom indices"))
|
||||
passcode_position_idx --> pad1
|
||||
|
||||
space:5
|
||||
posidx["Passcode Position Indices:\n{{passcode_pos_idx}}"]
|
||||
propidx --> posidx
|
||||
posidx["Padded Passcode Position Indices:\n{{pad_user_passcode_idxs}}"]
|
||||
pad1 --> posidx
|
||||
space:1
|
||||
user_pos["user position key"]
|
||||
user_pos["user position key:\n{{user_position_key}}"]
|
||||
xor1 --> user_pos
|
||||
|
||||
space:4
|
||||
sel(("select\npositions"))
|
||||
sel(("select positions"))
|
||||
user_pos --> sel
|
||||
posidx --> sel
|
||||
space:5
|
||||
passcode_pos["passcode positions:\n{{ordered_user_position_key}}"]
|
||||
passcode_pos["ordered user passcode positions:\n{{ordered_user_position_key}}"]
|
||||
sel --> passcode_pos
|
||||
mask_key["mask key\n{{mask_key}}"]
|
||||
space:4
|
||||
@@ -126,3 +130,44 @@ block-beta
|
||||
mask["enciphered mask:\n {{mask}}"]
|
||||
xor2 --> mask
|
||||
```
|
||||
|
||||
### Validate nKode
|
||||
|
||||
```mermaid
|
||||
block-beta
|
||||
columns 4
|
||||
selected_keys["selected keys:\n{{selected_keys}}"]
|
||||
login_keypad["login keypad:\n{{login_keypad}}"]
|
||||
mask["enciphered mask:\n {{mask}}"]
|
||||
mask_key["mask key:\n{{mask_key}}"]
|
||||
space:6
|
||||
|
||||
user_position_key["user position key:\n{{user_position_key}}"]
|
||||
passcode_pos["ordered user passcode positions:\n{{ordered_user_position_key}}"]
|
||||
space:4
|
||||
|
||||
space:2
|
||||
get_passcode_idxs(("recover passcode\nposition indices"))
|
||||
space:7
|
||||
|
||||
passcode_pos_idxs["padded passcode position indices:\n{{pad_user_passcode_idxs}}"]
|
||||
space:5
|
||||
|
||||
get_presumed_idxs(("recover passcode\nproperty indices"))
|
||||
space:7
|
||||
|
||||
passcode_prop_idxs["presumed passcode property indices:\n{{user_passcode_idxs}}"]
|
||||
space:7
|
||||
|
||||
sel(("select\nproperties"))
|
||||
space:1
|
||||
prop["combined_property_key\n{{combined_property_key}}"]
|
||||
space:5
|
||||
passcode_prop["presumed passcode properties:\n{{user_passcode_props}}"]
|
||||
space:1
|
||||
cipheredhashed["hashed ciphered passcode:\n{{code}}"]
|
||||
space:6
|
||||
|
||||
comp(("compare"))
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user