refactor user defined keypad

This commit is contained in:
2024-08-24 21:02:50 -05:00
parent 1a7dc45ab9
commit 3bf2b4d71f
19 changed files with 273 additions and 190 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
.idea .idea
tmp tmp
*.db

View File

@@ -46,7 +46,7 @@ func (h *NKodeHandler) CreateNewCustomerHandler(w http.ResponseWriter, r *http.R
log.Fatal(err) log.Fatal(err)
return return
} }
customerId, err := h.Api.CreateNewCustomer(customerPost.KeypadSize, customerPost.NKodePolicy) customerId, err := h.Api.CreateNewCustomer(customerPost.NKodePolicy)
if err != nil { if err != nil {
internalServerErrorHandler(w) internalServerErrorHandler(w)
log.Fatal(err) log.Fatal(err)
@@ -84,7 +84,7 @@ func (h *NKodeHandler) GenerateSignupInterfaceHandler(w http.ResponseWriter, r *
log.Fatal(err) log.Fatal(err)
return return
} }
resp, err := h.Api.GenerateSignupInterface(signupPost.CustomerId) resp, err := h.Api.GenerateSignupInterface(signupPost.CustomerId, m.KeypadDefault)
if err != nil { if err != nil {
internalServerErrorHandler(w) internalServerErrorHandler(w)
log.Fatal(err) log.Fatal(err)

View File

@@ -0,0 +1,40 @@
package m
import "errors"
type KeypadDimension struct {
AttrsPerKey int `json:"attrs_per_key"`
NumbOfKeys int `json:"numb_of_keys"`
}
func (kp *KeypadDimension) TotalAttrs() int {
return kp.AttrsPerKey * kp.NumbOfKeys
}
func (kp *KeypadDimension) IsDispersable() bool {
return kp.AttrsPerKey <= kp.NumbOfKeys
}
func (kp *KeypadDimension) IsValidKeypadDimension() error {
if KeypadMin.AttrsPerKey > kp.AttrsPerKey || KeypadMax.AttrsPerKey < kp.AttrsPerKey || KeypadMin.NumbOfKeys > kp.NumbOfKeys || KeypadMax.NumbOfKeys < kp.NumbOfKeys {
return errors.New("keypad dimensions out of range")
}
return nil
}
var (
KeypadMax = KeypadDimension{
AttrsPerKey: 16,
NumbOfKeys: 15,
}
KeypadMin = KeypadDimension{
AttrsPerKey: 6,
NumbOfKeys: 5,
}
KeypadDefault = KeypadDimension{
AttrsPerKey: 14,
NumbOfKeys: 7,
}
)

View File

@@ -1,19 +0,0 @@
package m
type KeypadSize struct {
AttrsPerKey int `json:"attrs_per_key"`
NumbOfKeys int `json:"numb_of_keys"`
}
func (kp *KeypadSize) TotalAttrs() int {
return kp.AttrsPerKey * kp.NumbOfKeys
}
func (kp *KeypadSize) IsDispersable() bool {
return kp.AttrsPerKey <= kp.NumbOfKeys
}
type EncipheredNKode struct {
Code string
Mask string
}

View File

@@ -9,7 +9,6 @@ type SetNKodeResp struct {
} }
type NewCustomerPost struct { type NewCustomerPost struct {
KeypadSize KeypadSize `json:"keypad_size"`
NKodePolicy NKodePolicy `json:"nkode_policy"` NKodePolicy NKodePolicy `json:"nkode_policy"`
} }
@@ -65,11 +64,16 @@ type Username string
type IdxInterface []int type IdxInterface []int
type NKodeAPIInterface interface { type NKodeAPIInterface interface {
CreateNewCustomer(KeypadSize, NKodePolicy) (*CustomerId, error) CreateNewCustomer(NKodePolicy) (*CustomerId, error)
GenerateSignupInterface(CustomerId) (*GenerateSignupInterfaceResp, error) GenerateSignupInterface(CustomerId, KeypadDimension) (*GenerateSignupInterfaceResp, error)
SetNKode(Username, CustomerId, SessionId, KeySelection) (IdxInterface, error) SetNKode(Username, CustomerId, SessionId, KeySelection) (IdxInterface, error)
ConfirmNKode(CustomerId, SessionId, KeySelection) error ConfirmNKode(CustomerId, SessionId, KeySelection) error
GetLoginInterface(username Username, customerId CustomerId) (IdxInterface, error) GetLoginInterface(Username, CustomerId) (IdxInterface, error)
Login(customerId CustomerId, username Username, keySelection KeySelection) error Login(CustomerId, Username, KeySelection) error
RenewAttributes(customerId CustomerId) error RenewAttributes(CustomerId) error
}
type EncipheredNKode struct {
Code string
Mask string
} }

View File

@@ -17,15 +17,8 @@ type Customer struct {
Users map[m.Username]User Users map[m.Username]User
} }
func NewCustomer(keypadSize m.KeypadSize, nkodePolicy m.NKodePolicy) (*Customer, error) { func NewCustomer(nkodePolicy m.NKodePolicy) (*Customer, error) {
if keypadSize.TotalAttrs() < nkodePolicy.DistinctAttributes { customerAttrs, err := NewCustomerAttributes()
return nil, errors.New(fmt.Sprintf("incompadible nkode policy and keypad size TotalAttrs: %d < DistinctAttributes: %d", keypadSize.TotalAttrs(), nkodePolicy.DistinctAttributes))
}
if keypadSize.AttrsPerKey < nkodePolicy.DistinctSets {
return nil, errors.New(fmt.Sprintf("incompadible nkode policy and keypad size AttrPerKey: %d < DistinctSets: %d", keypadSize.AttrsPerKey, nkodePolicy.DistinctSets))
}
customerAttrs, err := NewCustomerAttributes(keypadSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -39,12 +32,16 @@ func NewCustomer(keypadSize m.KeypadSize, nkodePolicy m.NKodePolicy) (*Customer,
return &customer, nil return &customer, nil
} }
func (c *Customer) AddNewUser(username m.Username, passcodeIdx []int, userInterface UserInterface) error { func (c *Customer) AddNewUser(username m.Username, passcodeIdx []int, ui UserInterface, kp m.KeypadDimension) error {
_, exists := c.Users[username] _, exists := c.Users[username]
if exists { if exists {
return errors.New(fmt.Sprintf("User %s already exists for customer %+v exists", username, c.CustomerId)) return errors.New(fmt.Sprintf("User %s already exists for customer %+v exists", username, c.CustomerId))
} }
newKeys, err := NewUserCipherKeys(c.Attributes.KeypadSize, c.Attributes.SetVals, c.NKodePolicy.MaxNkodeLen) setVals, err := c.Attributes.SetVals(kp)
if err != nil {
return err
}
newKeys, err := NewUserCipherKeys(&kp, setVals, c.NKodePolicy.MaxNkodeLen)
if err != nil { if err != nil {
return err return err
} }
@@ -56,7 +53,8 @@ func (c *Customer) AddNewUser(username m.Username, passcodeIdx []int, userInterf
Username: username, Username: username,
EncipheredPasscode: *encipheredNKode, EncipheredPasscode: *encipheredNKode,
UserKeys: *newKeys, UserKeys: *newKeys,
Interface: userInterface, Interface: ui,
Kp: kp,
} }
c.Users[username] = newUser c.Users[username] = newUser
return nil return nil
@@ -69,20 +67,24 @@ func (c *Customer) ValidKeyEntry(username m.Username, selectedKeys []int) ([]int
} }
validKeys := py.All[int](selectedKeys, func(idx int) bool { validKeys := py.All[int](selectedKeys, func(idx int) bool {
return 0 <= idx && idx < c.Attributes.KeypadSize.NumbOfKeys return 0 <= idx && idx < user.Kp.NumbOfKeys
}) })
if !validKeys { if !validKeys {
return nil, errors.New(fmt.Sprintf("one or more keys not in range 0-%d", c.Attributes.KeypadSize.NumbOfKeys-1)) return nil, errors.New(fmt.Sprintf("one or more keys not in range 0-%d", user.Kp.NumbOfKeys-1))
} }
presumedAttrIdxVals, err := c.getPresumedAttributeIdxVals(user, selectedKeys) presumedAttrIdxVals, err := c.getPresumedAttributeIdxVals(user, selectedKeys)
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = c.IsValidNKode(presumedAttrIdxVals) err = c.IsValidNKode(user.Kp, presumedAttrIdxVals)
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = user.UserKeys.ValidPassword(user.EncipheredPasscode.Code, presumedAttrIdxVals, c.Attributes) attrVals, err := c.Attributes.AttrVals(user.Kp)
if err != nil {
return nil, err
}
err = user.UserKeys.ValidPassword(user.EncipheredPasscode.Code, presumedAttrIdxVals, attrVals)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -96,7 +98,12 @@ func (c *Customer) getPresumedAttributeIdxVals(user User, selectedKeys []int) ([
if passcodeLen < c.NKodePolicy.MinNkodeLen || passcodeLen > c.NKodePolicy.MaxNkodeLen { if passcodeLen < c.NKodePolicy.MinNkodeLen || passcodeLen > c.NKodePolicy.MaxNkodeLen {
return nil, errors.New(fmt.Sprintf("Invalid passcode length of %d. Passcode length must be in range %d-%d", passcodeLen, c.NKodePolicy.MinNkodeLen, c.NKodePolicy.MaxNkodeLen)) return nil, errors.New(fmt.Sprintf("Invalid passcode length of %d. Passcode length must be in range %d-%d", passcodeLen, c.NKodePolicy.MinNkodeLen, c.NKodePolicy.MaxNkodeLen))
} }
passcodeSetVals, err := user.DecipherMask(c.Attributes.SetVals, passcodeLen)
setVals, err := c.Attributes.SetVals(user.Kp)
if err != nil {
return nil, err
}
passcodeSetVals, err := user.DecipherMask(setVals, passcodeLen)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -117,24 +124,28 @@ func (c *Customer) getPresumedAttributeIdxVals(user User, selectedKeys []int) ([
return presumedAttrIdxVals, nil return presumedAttrIdxVals, nil
} }
func (c *Customer) IsValidNKode(passcodeAttrIdx []int) error { func (c *Customer) IsValidNKode(kp m.KeypadDimension, passcodeAttrIdx []int) error {
nkodeLen := len(passcodeAttrIdx) nkodeLen := len(passcodeAttrIdx)
if nkodeLen < c.NKodePolicy.MinNkodeLen { if nkodeLen < c.NKodePolicy.MinNkodeLen {
return errors.New(fmt.Sprintf("NKode length %d is too short. Minimum nKode length is %d", nkodeLen, c.NKodePolicy.MinNkodeLen)) return errors.New(fmt.Sprintf("NKode length %d is too short. Minimum nKode length is %d", nkodeLen, c.NKodePolicy.MinNkodeLen))
} }
validIdx := py.All[int](passcodeAttrIdx, func(i int) bool { validIdx := py.All[int](passcodeAttrIdx, func(i int) bool {
return i >= 0 && i < c.Attributes.KeypadSize.TotalAttrs() return i >= 0 && i < kp.TotalAttrs()
}) })
if !validIdx { if !validIdx {
return errors.New(fmt.Sprintf("One or more idx out of range 0-%d in IsValidNKode", c.Attributes.KeypadSize.TotalAttrs()-1)) return errors.New(fmt.Sprintf("One or more idx out of range 0-%d in IsValidNKode", kp.TotalAttrs()-1))
} }
passcodeSetVals := make(hashset.Set[uint64]) passcodeSetVals := make(hashset.Set[uint64])
passcodeAttrVals := make(hashset.Set[uint64]) passcodeAttrVals := make(hashset.Set[uint64])
attrVals, err := c.Attributes.AttrVals(kp)
if err != nil {
return err
}
for idx := 0; idx < nkodeLen; idx++ { for idx := 0; idx < nkodeLen; idx++ {
attrVal := c.Attributes.AttrVals[passcodeAttrIdx[idx]] attrVal := attrVals[passcodeAttrIdx[idx]]
setVal, err := c.Attributes.GetAttrSetVal(attrVal) setVal, err := c.Attributes.GetAttrSetVal(attrVal, kp)
if err != nil { if err != nil {
return err return err
} }
@@ -167,20 +178,36 @@ func (c *Customer) GetLoginInterface(username m.Username) ([]int, error) {
} }
func (c *Customer) RenewKeys() error { func (c *Customer) RenewKeys() error {
oldAttrs := make([]uint64, c.Attributes.KeypadSize.TotalAttrs()) oldAttrs := make([]uint64, m.KeypadMax.TotalAttrs())
oldSets := make([]uint64, c.Attributes.KeypadSize.AttrsPerKey) oldSets := make([]uint64, m.KeypadMax.AttrsPerKey)
copy(oldAttrs, c.Attributes.AttrVals) allAttrVals, err := c.Attributes.AttrVals(m.KeypadMax)
copy(oldSets, c.Attributes.SetVals) if err != nil {
return nil
}
allSetVals, err := c.Attributes.AttrVals(m.KeypadMax)
if err != nil {
return nil
}
copy(oldAttrs, allAttrVals)
copy(oldSets, allSetVals)
err := c.Attributes.Renew() err = c.Attributes.Renew()
if err != nil { if err != nil {
return nil return nil
} }
attrsXor, err := util.XorLists(oldAttrs, c.Attributes.AttrVals) allAttrVals, err = c.Attributes.AttrVals(m.KeypadMax)
if err != nil { if err != nil {
return nil return nil
} }
setXor, err := util.XorLists(oldSets, c.Attributes.SetVals) allSetVals, err = c.Attributes.AttrVals(m.KeypadMax)
if err != nil {
return nil
}
attrsXor, err := util.XorLists(oldAttrs, allAttrVals)
if err != nil {
return nil
}
setXor, err := util.XorLists(oldSets, allSetVals)
if err != nil { if err != nil {
return nil return nil
} }

View File

@@ -7,68 +7,79 @@ import (
"go-nkode/util" "go-nkode/util"
) )
// TODO: make generic var NotDispersableError = errors.New("number of keys must be less than the number of attributes per key to be dispersion resistant")
type CustomerAttributes struct { type CustomerAttributes struct {
AttrVals []uint64 attrVals []uint64
SetVals []uint64 setVals []uint64
KeypadSize m.KeypadSize
} }
func NewCustomerAttributes(keypadSize m.KeypadSize) (*CustomerAttributes, error) { func NewCustomerAttributes() (*CustomerAttributes, error) {
if keypadSize.IsDispersable() { attrVals, errAttr := util.GenerateRandomNonRepeatingUint64(m.KeypadMax.TotalAttrs())
return nil, errors.New("number of keys must be less than the number of attributes per key to be dispersion resistant")
}
attrVals, errAttr := util.GenerateRandomNonRepeatingUint64(keypadSize.TotalAttrs())
if errAttr != nil { if errAttr != nil {
return nil, errAttr return nil, errAttr
} }
setVals, errSet := util.GenerateRandomNonRepeatingUint64(keypadSize.AttrsPerKey) setVals, errSet := util.GenerateRandomNonRepeatingUint64(m.KeypadMax.AttrsPerKey)
if errSet != nil { if errSet != nil {
return nil, errSet return nil, errSet
} }
customerAttrs := CustomerAttributes{ customerAttrs := CustomerAttributes{
AttrVals: attrVals, attrVals: attrVals,
SetVals: setVals, setVals: setVals,
KeypadSize: keypadSize,
} }
return &customerAttrs, nil return &customerAttrs, nil
} }
func (c *CustomerAttributes) Renew() error { func (c *CustomerAttributes) Renew() error {
attrVals, errAttr := util.GenerateRandomNonRepeatingUint64(c.KeypadSize.TotalAttrs()) attrVals, errAttr := util.GenerateRandomNonRepeatingUint64(m.KeypadMax.TotalAttrs())
if errAttr != nil { if errAttr != nil {
return errAttr return errAttr
} }
setVals, errSet := util.GenerateRandomNonRepeatingUint64(c.KeypadSize.AttrsPerKey) setVals, errSet := util.GenerateRandomNonRepeatingUint64(m.KeypadMax.AttrsPerKey)
if errSet != nil { if errSet != nil {
return errSet return errSet
} }
c.AttrVals = attrVals c.attrVals = attrVals
c.SetVals = setVals c.setVals = setVals
return nil return nil
} }
func (c *CustomerAttributes) IndexOfAttr(attrVal uint64) int { func (c *CustomerAttributes) IndexOfAttr(attrVal uint64) int {
// TODO: should this be mapped instead? // TODO: should this be mapped instead?
return util.IndexOf[uint64](c.AttrVals, attrVal) return util.IndexOf[uint64](c.attrVals, attrVal)
} }
func (c *CustomerAttributes) IndexOfSet(setVal uint64) (int, error) { func (c *CustomerAttributes) IndexOfSet(setVal uint64) (int, error) {
// TODO: should this be mapped instead? // TODO: should this be mapped instead?
idx := util.IndexOf[uint64](c.SetVals, setVal) idx := util.IndexOf[uint64](c.setVals, setVal)
if idx == -1 { if idx == -1 {
return -1, errors.New(fmt.Sprintf("Set Val %d is invalid", setVal)) return -1, errors.New(fmt.Sprintf("Set Val %d is invalid", setVal))
} }
return idx, nil return idx, nil
} }
func (c *CustomerAttributes) GetAttrSetVal(attrVal uint64) (uint64, error) { func (c *CustomerAttributes) GetAttrSetVal(attrVal uint64, userKeypad m.KeypadDimension) (uint64, error) {
indexOfAttr := c.IndexOfAttr(attrVal) indexOfAttr := c.IndexOfAttr(attrVal)
if indexOfAttr == -1 { if indexOfAttr == -1 {
return 0, errors.New(fmt.Sprintf("No attribute %d", attrVal)) return 0, errors.New(fmt.Sprintf("No attribute %d", attrVal))
} }
setIdx := indexOfAttr % c.KeypadSize.AttrsPerKey setIdx := indexOfAttr % userKeypad.AttrsPerKey
return c.SetVals[setIdx], nil return c.setVals[setIdx], nil
}
func (c *CustomerAttributes) AttrVals(userKp m.KeypadDimension) ([]uint64, error) {
err := userKp.IsValidKeypadDimension()
if err != nil {
return nil, err
}
return c.attrVals[:userKp.TotalAttrs()], nil
}
func (c *CustomerAttributes) SetVals(userKp m.KeypadDimension) ([]uint64, error) {
err := userKp.IsValidKeypadDimension()
if err != nil {
return nil, err
}
return c.setVals[:userKp.AttrsPerKey], nil
} }

View File

@@ -13,25 +13,25 @@ func TestCustomer(t *testing.T) {
} }
func testNewCustomerAttributes(t *testing.T) { func testNewCustomerAttributes(t *testing.T) {
keypad := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} // keypad := m.KeypadDimension{AttrsPerKey: 10, NumbOfKeys: 5}
_, nil := NewCustomerAttributes(keypad) _, nil := NewCustomerAttributes()
assert.NoError(t, nil) assert.NoError(t, nil)
} }
func testCustomerValidKeyEntry(t *testing.T) { func testCustomerValidKeyEntry(t *testing.T) {
keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7} kp := m.KeypadDimension{AttrsPerKey: 10, NumbOfKeys: 9}
nkodePolicy := m.NewDefaultNKodePolicy() nkodePolicy := m.NewDefaultNKodePolicy()
customer, err := NewCustomer(keypadSize, nkodePolicy) customer, err := NewCustomer(nkodePolicy)
assert.NoError(t, err) assert.NoError(t, err)
newUserInterface, err := NewUserInterface(customer.Attributes.KeypadSize) newUserInterface, err := NewUserInterface(&kp)
assert.NoError(t, err) assert.NoError(t, err)
username := m.Username("testing123") username := m.Username("testing123")
passcodeIdx := []int{0, 1, 2, 3} passcodeIdx := []int{0, 1, 2, 3}
err = customer.AddNewUser(username, passcodeIdx, *newUserInterface) err = customer.AddNewUser(username, passcodeIdx, *newUserInterface, kp)
assert.NoError(t, err) assert.NoError(t, err)
userLoginInterface, err := customer.GetLoginInterface(username) userLoginInterface, err := customer.GetLoginInterface(username)
assert.NoError(t, err) assert.NoError(t, err)
selectedKeys, err := SelectKeyByAttrIdx(userLoginInterface, passcodeIdx, keypadSize) selectedKeys, err := SelectKeyByAttrIdx(userLoginInterface, passcodeIdx, kp)
assert.NoError(t, err) assert.NoError(t, err)
validatedPasscode, err := customer.ValidKeyEntry(username, selectedKeys) validatedPasscode, err := customer.ValidKeyEntry(username, selectedKeys)
assert.NoError(t, err) assert.NoError(t, err)
@@ -42,16 +42,16 @@ func testCustomerValidKeyEntry(t *testing.T) {
} }
func testCustomerIsValidNKode(t *testing.T) { func testCustomerIsValidNKode(t *testing.T) {
keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7} kp := m.KeypadDimension{AttrsPerKey: 10, NumbOfKeys: 7}
nkodePolicy := m.NewDefaultNKodePolicy() nkodePolicy := m.NewDefaultNKodePolicy()
customer, err := NewCustomer(keypadSize, nkodePolicy) customer, err := NewCustomer(nkodePolicy)
assert.NoError(t, err) assert.NoError(t, err)
newUserInterface, err := NewUserInterface(customer.Attributes.KeypadSize) newUserInterface, err := NewUserInterface(&kp)
assert.NoError(t, err) assert.NoError(t, err)
username := m.Username("testing123") username := m.Username("testing123")
passcodeIdx := []int{0, 1, 2, 3} passcodeIdx := []int{0, 1, 2, 3}
err = customer.AddNewUser(username, passcodeIdx, *newUserInterface) err = customer.AddNewUser(username, passcodeIdx, *newUserInterface, kp)
assert.NoError(t, err) assert.NoError(t, err)
err = customer.IsValidNKode(passcodeIdx) err = customer.IsValidNKode(kp, passcodeIdx)
assert.NoError(t, err) assert.NoError(t, err)
} }

View File

@@ -18,8 +18,8 @@ func NewNKodeInMemory() NKodeInMemory {
} }
} }
func (n *NKodeInMemory) CreateNewCustomer(keypadSize m.KeypadSize, nkodePolicy m.NKodePolicy) (*m.CustomerId, error) { func (n *NKodeInMemory) CreateNewCustomer(nkodePolicy m.NKodePolicy) (*m.CustomerId, error) {
newCustomer, err := NewCustomer(keypadSize, nkodePolicy) newCustomer, err := NewCustomer(nkodePolicy)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -27,13 +27,13 @@ func (n *NKodeInMemory) CreateNewCustomer(keypadSize m.KeypadSize, nkodePolicy m
return &newCustomer.CustomerId, nil return &newCustomer.CustomerId, nil
} }
func (n *NKodeInMemory) GenerateSignupInterface(customerId m.CustomerId) (*m.GenerateSignupInterfaceResp, error) { func (n *NKodeInMemory) GenerateSignupInterface(customerId m.CustomerId, kp m.KeypadDimension) (*m.GenerateSignupInterfaceResp, error) {
customer, exists := n.Customers[customerId] customer, exists := n.Customers[customerId]
if !exists { if !exists {
return nil, errors.New(fmt.Sprintf("customer doesnt exists: %s", customerId)) return nil, errors.New(fmt.Sprintf("customer doesnt exists: %s", customerId))
} }
signupSession, err := NewSignupSession(customer.Attributes.KeypadSize, customer.CustomerId) signupSession, err := NewSignupSession(kp, customer.CustomerId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -73,11 +73,11 @@ func (n *NKodeInMemory) ConfirmNKode(customerId m.CustomerId, sessionId m.Sessio
if err != nil { if err != nil {
return err return err
} }
err = customer.IsValidNKode(passcode) err = customer.IsValidNKode(session.Kp, passcode)
if err != nil { if err != nil {
return err return err
} }
err = customer.AddNewUser(session.Username, passcode, session.LoginUserInterface) err = customer.AddNewUser(session.Username, passcode, session.LoginUserInterface, session.Kp)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -11,15 +11,15 @@ func TestNKodeAPI(t *testing.T) {
username := m.Username("test_username") username := m.Username("test_username")
passcodeLen := 4 passcodeLen := 4
nkodePolicy := m.NewDefaultNKodePolicy() nkodePolicy := m.NewDefaultNKodePolicy()
keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3} keypadSize := m.KeypadDimension{AttrsPerKey: 10, NumbOfKeys: 8}
nkodeApi := NewNKodeInMemory() nkodeApi := NewNKodeInMemory()
customerId, err := nkodeApi.CreateNewCustomer(keypadSize, nkodePolicy) customerId, err := nkodeApi.CreateNewCustomer(nkodePolicy)
assert.NoError(t, err) assert.NoError(t, err)
signupResponse, err := nkodeApi.GenerateSignupInterface(*customerId) signupResponse, err := nkodeApi.GenerateSignupInterface(*customerId, keypadSize)
assert.NoError(t, err) assert.NoError(t, err)
setInterface := signupResponse.UserInterface setInterface := signupResponse.UserInterface
sessionId := signupResponse.SessionId sessionId := signupResponse.SessionId
keypadSize = m.KeypadSize{AttrsPerKey: 3, NumbOfKeys: 3} keypadSize = m.KeypadDimension{AttrsPerKey: 8, NumbOfKeys: 8}
userPasscode := setInterface[:passcodeLen] userPasscode := setInterface[:passcodeLen]
setKeySelect, err := SelectKeyByAttrIdx(setInterface, userPasscode, keypadSize) setKeySelect, err := SelectKeyByAttrIdx(setInterface, userPasscode, keypadSize)
assert.NoError(t, err) assert.NoError(t, err)
@@ -29,7 +29,7 @@ func TestNKodeAPI(t *testing.T) {
err = nkodeApi.ConfirmNKode(*customerId, sessionId, confirmKeySelect) err = nkodeApi.ConfirmNKode(*customerId, sessionId, confirmKeySelect)
assert.NoError(t, err) assert.NoError(t, err)
keypadSize = m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3} keypadSize = m.KeypadDimension{AttrsPerKey: 10, NumbOfKeys: 8}
loginInterface, err := nkodeApi.GetLoginInterface(username, *customerId) loginInterface, err := nkodeApi.GetLoginInterface(username, *customerId)
assert.NoError(t, err) assert.NoError(t, err)
loginKeySelection, err := SelectKeyByAttrIdx(loginInterface, userPasscode, keypadSize) loginKeySelection, err := SelectKeyByAttrIdx(loginInterface, userPasscode, keypadSize)

View File

@@ -7,7 +7,7 @@ import (
"go-nkode/util" "go-nkode/util"
) )
func SelectKeyByAttrIdx(interfaceUser []int, passcodeIdxs []int, keypadSize m.KeypadSize) ([]int, error) { func SelectKeyByAttrIdx(interfaceUser []int, passcodeIdxs []int, keypadSize m.KeypadDimension) ([]int, error) {
selectedKeys := make([]int, len(passcodeIdxs)) selectedKeys := make([]int, len(passcodeIdxs))
for idx := range passcodeIdxs { for idx := range passcodeIdxs {
attrIdx := util.IndexOf[int](interfaceUser, passcodeIdxs[idx]) attrIdx := util.IndexOf[int](interfaceUser, passcodeIdxs[idx])

View File

@@ -8,6 +8,7 @@ import (
type User struct { type User struct {
Username m.Username Username m.Username
EncipheredPasscode m.EncipheredNKode EncipheredPasscode m.EncipheredNKode
Kp m.KeypadDimension
UserKeys UserCipherKeys UserKeys UserCipherKeys
Interface UserInterface Interface UserInterface
Renew bool Renew bool
@@ -29,7 +30,8 @@ func (u *User) RenewKeys(setXor []uint64, attrXor []uint64) error {
} }
func (u *User) RefreshPasscode(passcodeAttrIdx []int, customerAttributes CustomerAttributes) error { func (u *User) RefreshPasscode(passcodeAttrIdx []int, customerAttributes CustomerAttributes) error {
newKeys, err := NewUserCipherKeys(customerAttributes.KeypadSize, customerAttributes.SetVals, u.UserKeys.MaxNKodeLen) setVals, err := customerAttributes.SetVals(u.Kp)
newKeys, err := NewUserCipherKeys(&u.Kp, setVals, u.UserKeys.MaxNKodeLen)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -3,7 +3,6 @@ package nkode
import ( import (
"crypto/sha256" "crypto/sha256"
"errors" "errors"
"fmt"
m "go-nkode/core/model" m "go-nkode/core/model"
"go-nkode/util" "go-nkode/util"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
@@ -16,14 +15,15 @@ type UserCipherKeys struct {
MaskKey []uint64 MaskKey []uint64
Salt []byte Salt []byte
MaxNKodeLen int MaxNKodeLen int
kp *m.KeypadDimension
} }
func NewUserCipherKeys(keypadSize m.KeypadSize, setVals []uint64, maxNKodeLen int) (*UserCipherKeys, error) { func NewUserCipherKeys(kp *m.KeypadDimension, setVals []uint64, maxNKodeLen int) (*UserCipherKeys, error) {
if len(setVals) != keypadSize.AttrsPerKey { err := kp.IsValidKeypadDimension()
return nil, errors.New(fmt.Sprintf("setVals len != attrsPerKey, %d, %d", len(setVals), keypadSize.AttrsPerKey)) if err != nil {
return nil, err
} }
setKey, err := util.GenerateRandomNonRepeatingUint64(kp.AttrsPerKey)
setKey, err := util.GenerateRandomNonRepeatingUint64(keypadSize.AttrsPerKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -32,7 +32,7 @@ func NewUserCipherKeys(keypadSize m.KeypadSize, setVals []uint64, maxNKodeLen in
return nil, err return nil, err
} }
alphakey, _ := util.GenerateRandomNonRepeatingUint64(keypadSize.TotalAttrs()) alphakey, _ := util.GenerateRandomNonRepeatingUint64(kp.TotalAttrs())
passKey, _ := util.GenerateRandomNonRepeatingUint64(maxNKodeLen) passKey, _ := util.GenerateRandomNonRepeatingUint64(maxNKodeLen)
maskKey, _ := util.GenerateRandomNonRepeatingUint64(maxNKodeLen) maskKey, _ := util.GenerateRandomNonRepeatingUint64(maxNKodeLen)
salt, _ := util.RandomBytes(10) salt, _ := util.RandomBytes(10)
@@ -43,6 +43,7 @@ func NewUserCipherKeys(keypadSize m.KeypadSize, setVals []uint64, maxNKodeLen in
SetKey: setKey, SetKey: setKey,
Salt: salt, Salt: salt,
MaxNKodeLen: maxNKodeLen, MaxNKodeLen: maxNKodeLen,
kp: kp,
} }
return &userCipherKeys, nil return &userCipherKeys, nil
} }
@@ -59,9 +60,9 @@ func (u *UserCipherKeys) PadUserMask(userMask []uint64, setVals []uint64) ([]uin
return paddedUserMask, nil return paddedUserMask, nil
} }
func (u *UserCipherKeys) ValidPassword(hashedPassword string, passcodeAttrIdx []int, customerAttrs CustomerAttributes) error { func (u *UserCipherKeys) ValidPassword(hashedPassword string, passcodeAttrIdx []int, attrVals []uint64) error {
hashBytes := []byte(hashedPassword) hashBytes := []byte(hashedPassword)
passcodeCipher := u.encipherCode(passcodeAttrIdx, customerAttrs) passcodeCipher := u.encipherCode(passcodeAttrIdx, attrVals)
passwordDigest, err := u.saltAndDigest(passcodeCipher) passwordDigest, err := u.saltAndDigest(passcodeCipher)
if err != nil { if err != nil {
return err return err
@@ -73,8 +74,8 @@ func (u *UserCipherKeys) ValidPassword(hashedPassword string, passcodeAttrIdx []
return nil return nil
} }
func (u *UserCipherKeys) EncipherSaltHashCode(passcodeAttrIdx []int, customerAttrs CustomerAttributes) (string, error) { func (u *UserCipherKeys) EncipherSaltHashCode(passcodeAttrIdx []int, attrVals []uint64) (string, error) {
passcodeCipher := u.encipherCode(passcodeAttrIdx, customerAttrs) passcodeCipher := u.encipherCode(passcodeAttrIdx, attrVals)
passcodeDigest, err := u.saltAndDigest(passcodeCipher) passcodeDigest, err := u.saltAndDigest(passcodeCipher)
if err != nil { if err != nil {
@@ -87,7 +88,7 @@ func (u *UserCipherKeys) EncipherSaltHashCode(passcodeAttrIdx []int, customerAtt
return string(passcodeBytes), nil return string(passcodeBytes), nil
} }
func (u *UserCipherKeys) encipherCode(passcodeAttrIdx []int, customerAttrs CustomerAttributes) []uint64 { func (u *UserCipherKeys) encipherCode(passcodeAttrIdx []int, attrVals []uint64) []uint64 {
passcodeLen := len(passcodeAttrIdx) passcodeLen := len(passcodeAttrIdx)
passcodeCipher := make([]uint64, u.MaxNKodeLen) passcodeCipher := make([]uint64, u.MaxNKodeLen)
@@ -95,7 +96,7 @@ func (u *UserCipherKeys) encipherCode(passcodeAttrIdx []int, customerAttrs Custo
for idx := 0; idx < passcodeLen; idx++ { for idx := 0; idx < passcodeLen; idx++ {
attrIdx := passcodeAttrIdx[idx] attrIdx := passcodeAttrIdx[idx]
alpha := u.AlphaKey[attrIdx] alpha := u.AlphaKey[attrIdx]
attrVal := customerAttrs.AttrVals[idx] attrVal := attrVals[idx]
pass := u.PassKey[idx] pass := u.PassKey[idx]
passcodeCipher[idx] = alpha ^ pass ^ attrVal passcodeCipher[idx] = alpha ^ pass ^ attrVal
} }
@@ -122,8 +123,12 @@ func (u *UserCipherKeys) hashPasscode(passcodeDigest []byte) ([]byte, error) {
} }
return hashedPassword, nil return hashedPassword, nil
} }
func (u *UserCipherKeys) EncipherMask(passcodeSet []uint64, customerAttrs CustomerAttributes) (string, error) { func (u *UserCipherKeys) EncipherMask(passcodeSet []uint64, customerAttrs CustomerAttributes, userKp m.KeypadDimension) (string, error) {
paddedPasscodeSets, err := u.PadUserMask(passcodeSet, customerAttrs.SetVals) setVals, err := customerAttrs.SetVals(userKp)
if err != nil {
return "", err
}
paddedPasscodeSets, err := u.PadUserMask(passcodeSet, setVals)
if err != nil { if err != nil {
return "", err return "", err
} }
@@ -166,20 +171,21 @@ func (u *UserCipherKeys) DecipherMask(mask string, setVals []uint64, passcodeLen
} }
func (u *UserCipherKeys) EncipherNKode(passcodeAttrIdx []int, customerAttrs CustomerAttributes) (*m.EncipheredNKode, error) { func (u *UserCipherKeys) EncipherNKode(passcodeAttrIdx []int, customerAttrs CustomerAttributes) (*m.EncipheredNKode, error) {
code, err := u.EncipherSaltHashCode(passcodeAttrIdx, customerAttrs) attrVals, err := customerAttrs.AttrVals(*u.kp)
code, err := u.EncipherSaltHashCode(passcodeAttrIdx, attrVals)
if err != nil { if err != nil {
return nil, err return nil, err
} }
passcodeSet := make([]uint64, len(passcodeAttrIdx)) passcodeSet := make([]uint64, len(passcodeAttrIdx))
for idx := range passcodeSet { for idx := range passcodeSet {
passcodeAttr := customerAttrs.AttrVals[passcodeAttrIdx[idx]] passcodeAttr := attrVals[passcodeAttrIdx[idx]]
passcodeSet[idx], err = customerAttrs.GetAttrSetVal(passcodeAttr) passcodeSet[idx], err = customerAttrs.GetAttrSetVal(passcodeAttr, *u.kp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
mask, err := u.EncipherMask(passcodeSet, customerAttrs) mask, err := u.EncipherMask(passcodeSet, customerAttrs, *u.kp)
encipheredCode := m.EncipheredNKode{ encipheredCode := m.EncipheredNKode{
Code: code, Code: code,
Mask: mask, Mask: mask,

View File

@@ -10,14 +10,14 @@ import (
type UserInterface struct { type UserInterface struct {
IdxInterface m.IdxInterface IdxInterface m.IdxInterface
KeypadSize m.KeypadSize kp *m.KeypadDimension
} }
func NewUserInterface(keypadSize m.KeypadSize) (*UserInterface, error) { func NewUserInterface(kp *m.KeypadDimension) (*UserInterface, error) {
idxInterface := util.IdentityArray(keypadSize.TotalAttrs()) idxInterface := util.IdentityArray(kp.TotalAttrs())
userInterface := UserInterface{ userInterface := UserInterface{
IdxInterface: idxInterface, IdxInterface: idxInterface,
KeypadSize: keypadSize, kp: kp,
} }
err := userInterface.RandomShuffle() err := userInterface.RandomShuffle()
if err != nil { if err != nil {
@@ -55,7 +55,7 @@ func (u *UserInterface) RandomShuffle() error {
} }
func (u *UserInterface) InterfaceMatrix() ([][]int, error) { func (u *UserInterface) InterfaceMatrix() ([][]int, error) {
return util.ListToMatrix(u.IdxInterface, u.KeypadSize.AttrsPerKey) return util.ListToMatrix(u.IdxInterface, u.kp.AttrsPerKey)
} }
func (u *UserInterface) SetViewMatrix() ([][]int, error) { func (u *UserInterface) SetViewMatrix() ([][]int, error) {
@@ -67,8 +67,8 @@ func (u *UserInterface) SetViewMatrix() ([][]int, error) {
} }
func (u *UserInterface) DisperseInterface() error { func (u *UserInterface) DisperseInterface() error {
if !u.KeypadSize.IsDispersable() { if !u.kp.IsDispersable() {
return errors.New("interface is not dispersable") panic("interface is not dispersable")
} }
err := u.shuffleKeys() err := u.shuffleKeys()
@@ -84,7 +84,7 @@ func (u *UserInterface) DisperseInterface() error {
} }
func (u *UserInterface) shuffleKeys() error { func (u *UserInterface) shuffleKeys() error {
userInterfaceMatrix, err := util.ListToMatrix(u.IdxInterface, u.KeypadSize.AttrsPerKey) userInterfaceMatrix, err := util.ListToMatrix(u.IdxInterface, u.kp.AttrsPerKey)
if err != nil { if err != nil {
return err return err
} }
@@ -144,11 +144,11 @@ func (u *UserInterface) PartialInterfaceShuffle() error {
if err != nil { if err != nil {
return err return err
} }
numbOfSelectedSets := u.KeypadSize.AttrsPerKey / 2 numbOfSelectedSets := u.kp.AttrsPerKey / 2
if u.KeypadSize.AttrsPerKey&1 == 1 { if u.kp.AttrsPerKey&1 == 1 {
numbOfSelectedSets += util.Choice[int]([]int{0, 1}) numbOfSelectedSets += util.Choice[int]([]int{0, 1})
} }
setIdxs, err := util.RandomPermutation(u.KeypadSize.AttrsPerKey) setIdxs, err := util.RandomPermutation(u.kp.AttrsPerKey)
if err != nil { if err != nil {
return err return err
} }
@@ -158,7 +158,7 @@ func (u *UserInterface) PartialInterfaceShuffle() error {
if err != nil { if err != nil {
return err return err
} }
interfaceBySet := make([][]int, u.KeypadSize.AttrsPerKey) interfaceBySet := make([][]int, u.kp.AttrsPerKey)
for idx, attrs := range keypadSetView { for idx, attrs := range keypadSetView {
if selectedSets.Contains(idx) { if selectedSets.Contains(idx) {
err = util.FisherYatesShuffle[int](&attrs) err = util.FisherYatesShuffle[int](&attrs)
@@ -177,12 +177,12 @@ func (u *UserInterface) PartialInterfaceShuffle() error {
} }
func (u *UserInterface) GetAttrIdxByKeyNumbSetIdx(setIdx int, keyNumb int) (int, error) { func (u *UserInterface) GetAttrIdxByKeyNumbSetIdx(setIdx int, keyNumb int) (int, error) {
if keyNumb < 0 || u.KeypadSize.NumbOfKeys <= keyNumb { if keyNumb < 0 || u.kp.NumbOfKeys <= keyNumb {
return -1, errors.New(fmt.Sprintf("keyNumb %d is out of range 0-%d", keyNumb, u.KeypadSize.NumbOfKeys)) return -1, errors.New(fmt.Sprintf("keyNumb %d is out of range 0-%d", keyNumb, u.kp.NumbOfKeys))
} }
if setIdx < 0 || u.KeypadSize.AttrsPerKey <= setIdx { if setIdx < 0 || u.kp.AttrsPerKey <= setIdx {
return -1, errors.New(fmt.Sprintf("setIdx %d is out of range 0-%d", setIdx, u.KeypadSize.AttrsPerKey)) return -1, errors.New(fmt.Sprintf("setIdx %d is out of range 0-%d", setIdx, u.kp.AttrsPerKey))
} }
keypadView, err := u.InterfaceMatrix() keypadView, err := u.InterfaceMatrix()
if err != nil { if err != nil {

View File

@@ -14,28 +14,31 @@ type UserSignSession struct {
SessionId m.SessionId SessionId m.SessionId
CustomerId m.CustomerId CustomerId m.CustomerId
LoginUserInterface UserInterface LoginUserInterface UserInterface
Keypad m.KeypadSize Kp m.KeypadDimension
SetIdxInterface m.IdxInterface SetIdxInterface m.IdxInterface
ConfirmIdxInterface m.IdxInterface ConfirmIdxInterface m.IdxInterface
SetKeySelection m.KeySelection SetKeySelection m.KeySelection
Username m.Username Username m.Username
} }
func NewSignupSession(keypadSize m.KeypadSize, customerId m.CustomerId) (*UserSignSession, error) { func NewSignupSession(kp m.KeypadDimension, customerId m.CustomerId) (*UserSignSession, error) {
loginInterface, err := NewUserInterface(keypadSize) loginInterface, err := NewUserInterface(&kp)
if err != nil {
return nil, err
}
signupInterface, err := signupInterface(*loginInterface, kp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
signupInter, err := signupInterface(*loginInterface)
session := UserSignSession{ session := UserSignSession{
SessionId: m.SessionId(uuid.New()), SessionId: m.SessionId(uuid.New()),
CustomerId: customerId, CustomerId: customerId,
LoginUserInterface: *loginInterface, LoginUserInterface: *loginInterface,
SetIdxInterface: signupInter.IdxInterface, SetIdxInterface: signupInterface.IdxInterface,
ConfirmIdxInterface: nil, ConfirmIdxInterface: nil,
SetKeySelection: nil, SetKeySelection: nil,
Username: "", Username: "",
Keypad: signupInter.KeypadSize, Kp: kp,
} }
return &session, nil return &session, nil
@@ -43,11 +46,11 @@ func NewSignupSession(keypadSize m.KeypadSize, customerId m.CustomerId) (*UserSi
func (s *UserSignSession) DeducePasscode(confirmKeyEntry m.KeySelection) ([]int, error) { func (s *UserSignSession) DeducePasscode(confirmKeyEntry m.KeySelection) ([]int, error) {
validEntry := py.All[int](confirmKeyEntry, func(i int) bool { validEntry := py.All[int](confirmKeyEntry, func(i int) bool {
return 0 <= i && i < s.LoginUserInterface.KeypadSize.NumbOfKeys return 0 <= i && i < s.Kp.NumbOfKeys
}) })
if !validEntry { if !validEntry {
return nil, errors.New(fmt.Sprintf("Invalid Key entry. One or more key index: %#v, not in range 0-%d", confirmKeyEntry, s.LoginUserInterface.KeypadSize.NumbOfKeys)) return nil, errors.New(fmt.Sprintf("Invalid Key entry. One or more key index: %#v, not in range 0-%d", confirmKeyEntry, s.Kp.NumbOfKeys))
} }
if s.SetIdxInterface == nil { if s.SetIdxInterface == nil {
@@ -96,16 +99,16 @@ func (s *UserSignSession) DeducePasscode(confirmKeyEntry m.KeySelection) ([]int,
func (s *UserSignSession) SetUserNKode(username m.Username, keySelection m.KeySelection) (m.IdxInterface, error) { func (s *UserSignSession) SetUserNKode(username m.Username, keySelection m.KeySelection) (m.IdxInterface, error) {
validKeySelection := py.All[int](keySelection, func(i int) bool { validKeySelection := py.All[int](keySelection, func(i int) bool {
return 0 <= i && i < s.Keypad.NumbOfKeys return 0 <= i && i < s.Kp.NumbOfKeys
}) })
if !validKeySelection { if !validKeySelection {
return nil, errors.New(fmt.Sprintf("one or key selection is out of range 0-%d", s.Keypad.NumbOfKeys-1)) return nil, errors.New(fmt.Sprintf("one or key selection is out of range 0-%d", s.Kp.NumbOfKeys-1))
} }
s.SetKeySelection = keySelection s.SetKeySelection = keySelection
s.Username = username s.Username = username
setKp := s.SignupKeypad()
setInterface := UserInterface{IdxInterface: s.SetIdxInterface, KeypadSize: s.Keypad} setInterface := UserInterface{IdxInterface: s.SetIdxInterface, kp: &setKp}
err := setInterface.DisperseInterface() err := setInterface.DisperseInterface()
if err != nil { if err != nil {
return nil, err return nil, err
@@ -115,7 +118,8 @@ func (s *UserSignSession) SetUserNKode(username m.Username, keySelection m.KeySe
} }
func (s *UserSignSession) getSelectedKeyVals(keySelections m.KeySelection, userInterface []int) ([][]int, error) { func (s *UserSignSession) getSelectedKeyVals(keySelections m.KeySelection, userInterface []int) ([][]int, error) {
keypadInterface, err := util.ListToMatrix(userInterface, s.Keypad.AttrsPerKey) signupKp := s.SignupKeypad()
keypadInterface, err := util.ListToMatrix(userInterface, signupKp.AttrsPerKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -127,8 +131,8 @@ func (s *UserSignSession) getSelectedKeyVals(keySelections m.KeySelection, userI
return keyVals, nil return keyVals, nil
} }
func signupInterface(baseUserInterface UserInterface) (*UserInterface, error) { func signupInterface(baseUserInterface UserInterface, kp m.KeypadDimension) (*UserInterface, error) {
if baseUserInterface.KeypadSize.IsDispersable() { if kp.IsDispersable() {
return nil, errors.New("keypad is dispersable, can't use signupInterface") return nil, errors.New("keypad is dispersable, can't use signupInterface")
} }
err := baseUserInterface.RandomShuffle() err := baseUserInterface.RandomShuffle()
@@ -147,7 +151,7 @@ func signupInterface(baseUserInterface UserInterface) (*UserInterface, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
numbOfKeys := baseUserInterface.KeypadSize.NumbOfKeys numbOfKeys := kp.NumbOfKeys
attrSetView = attrSetView[:numbOfKeys] attrSetView = attrSetView[:numbOfKeys]
attrSetView, err = util.MatrixTranspose(attrSetView) attrSetView, err = util.MatrixTranspose(attrSetView)
if err != nil { if err != nil {
@@ -155,10 +159,17 @@ func signupInterface(baseUserInterface UserInterface) (*UserInterface, error) {
} }
signupUserInterface := UserInterface{ signupUserInterface := UserInterface{
IdxInterface: util.MatrixToList(attrSetView), IdxInterface: util.MatrixToList(attrSetView),
KeypadSize: m.KeypadSize{ kp: &m.KeypadDimension{
AttrsPerKey: numbOfKeys, AttrsPerKey: numbOfKeys,
NumbOfKeys: numbOfKeys, NumbOfKeys: numbOfKeys,
}, },
} }
return &signupUserInterface, nil return &signupUserInterface, nil
} }
func (s *UserSignSession) SignupKeypad() m.KeypadDimension {
return m.KeypadDimension{
AttrsPerKey: s.Kp.NumbOfKeys,
NumbOfKeys: s.Kp.NumbOfKeys,
}
}

View File

@@ -8,38 +8,46 @@ import (
) )
func TestUserCipherKeys_EncipherSaltHashCode(t *testing.T) { func TestUserCipherKeys_EncipherSaltHashCode(t *testing.T) {
keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} kp := m.KeypadDimension{AttrsPerKey: 10, NumbOfKeys: 8}
maxNKodeLen := 10 maxNKodeLen := 10
customerAttrs, err := NewCustomerAttributes(keypadSize) customerAttrs, err := NewCustomerAttributes()
assert.NoError(t, err) assert.NoError(t, err)
newUser, err := NewUserCipherKeys(keypadSize, customerAttrs.SetVals, maxNKodeLen) setVals, err := customerAttrs.SetVals(kp)
assert.NoError(t, err)
attrVals, err := customerAttrs.AttrVals(kp)
assert.NoError(t, err)
newUser, err := NewUserCipherKeys(&kp, setVals, maxNKodeLen)
assert.NoError(t, err) assert.NoError(t, err)
passcodeIdx := []int{0, 1, 2, 3} passcodeIdx := []int{0, 1, 2, 3}
encipher0, err := newUser.EncipherSaltHashCode(passcodeIdx, *customerAttrs) encipher0, err := newUser.EncipherSaltHashCode(passcodeIdx, attrVals)
assert.NoError(t, err) assert.NoError(t, err)
err = newUser.ValidPassword(encipher0, passcodeIdx, *customerAttrs) err = newUser.ValidPassword(encipher0, passcodeIdx, attrVals)
assert.NoError(t, err) assert.NoError(t, err)
} }
func TestUserCipherKeys_EncipherDecipherMask(t *testing.T) { func TestUserCipherKeys_EncipherDecipherMask(t *testing.T) {
keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} kp := m.KeypadDimension{AttrsPerKey: 10, NumbOfKeys: 8}
maxNKodeLen := 10 maxNKodeLen := 10
customerAttrs, err := NewCustomerAttributes(keypadSize) customerAttrs, err := NewCustomerAttributes()
assert.NoError(t, err) assert.NoError(t, err)
newUser, err := NewUserCipherKeys(keypadSize, customerAttrs.SetVals, maxNKodeLen) setVals, err := customerAttrs.SetVals(kp)
assert.NoError(t, err)
attrVals, err := customerAttrs.AttrVals(kp)
assert.NoError(t, err)
newUser, err := NewUserCipherKeys(&kp, setVals, maxNKodeLen)
assert.NoError(t, err) assert.NoError(t, err)
passcodeIdx := []int{0, 1, 2, 3} passcodeIdx := []int{0, 1, 2, 3}
originalSetVals := make([]uint64, len(passcodeIdx)) originalSetVals := make([]uint64, len(passcodeIdx))
for idx, val := range passcodeIdx { for idx, val := range passcodeIdx {
attr := customerAttrs.AttrVals[val] attr := attrVals[val]
originalSetVals[idx], err = customerAttrs.GetAttrSetVal(attr) originalSetVals[idx], err = customerAttrs.GetAttrSetVal(attr, kp)
assert.NoError(t, err) assert.NoError(t, err)
} }
encipheredCode, err := newUser.EncipherNKode(passcodeIdx, *customerAttrs) encipheredCode, err := newUser.EncipherNKode(passcodeIdx, *customerAttrs)
assert.NoError(t, err) assert.NoError(t, err)
passcodeSetVals, err := newUser.DecipherMask(encipheredCode.Mask, customerAttrs.SetVals, len(passcodeIdx)) passcodeSetVals, err := newUser.DecipherMask(encipheredCode.Mask, setVals, len(passcodeIdx))
assert.NoError(t, err) assert.NoError(t, err)
for idx, setVal := range passcodeSetVals { for idx, setVal := range passcodeSetVals {
@@ -48,11 +56,11 @@ func TestUserCipherKeys_EncipherDecipherMask(t *testing.T) {
} }
func TestUserInterface_RandomShuffle(t *testing.T) { func TestUserInterface_RandomShuffle(t *testing.T) {
keypadSize := m.KeypadSize{ kp := m.KeypadDimension{
AttrsPerKey: 10, AttrsPerKey: 10,
NumbOfKeys: 5, NumbOfKeys: 8,
} }
userInterface, err := NewUserInterface(keypadSize) userInterface, err := NewUserInterface(&kp)
assert.NoError(t, err) assert.NoError(t, err)
userInterfaceCopy := make([]int, len(userInterface.IdxInterface)) userInterfaceCopy := make([]int, len(userInterface.IdxInterface))
copy(userInterfaceCopy, userInterface.IdxInterface) copy(userInterfaceCopy, userInterface.IdxInterface)
@@ -73,9 +81,9 @@ func TestUserInterface_RandomShuffle(t *testing.T) {
func TestUserInterface_DisperseInterface(t *testing.T) { func TestUserInterface_DisperseInterface(t *testing.T) {
for idx := 0; idx < 10000; idx++ { for idx := 0; idx < 10000; idx++ {
keypadSize := m.KeypadSize{AttrsPerKey: 7, NumbOfKeys: 10} kp := m.KeypadDimension{AttrsPerKey: 7, NumbOfKeys: 10}
userInterface, err := NewUserInterface(keypadSize) userInterface, err := NewUserInterface(&kp)
assert.NoError(t, err) assert.NoError(t, err)
preDispersion, err := userInterface.AttributeAdjacencyGraph() preDispersion, err := userInterface.AttributeAdjacencyGraph()
assert.NoError(t, err) assert.NoError(t, err)
@@ -92,8 +100,8 @@ func TestUserInterface_DisperseInterface(t *testing.T) {
} }
func TestUserInterface_PartialInterfaceShuffle(t *testing.T) { func TestUserInterface_PartialInterfaceShuffle(t *testing.T) {
keypadSize := m.KeypadSize{AttrsPerKey: 7, NumbOfKeys: 10} kp := m.KeypadDimension{AttrsPerKey: 7, NumbOfKeys: 10}
userInterface, err := NewUserInterface(keypadSize) userInterface, err := NewUserInterface(&kp)
assert.NoError(t, err) assert.NoError(t, err)
preShuffle := userInterface.IdxInterface preShuffle := userInterface.IdxInterface
err = userInterface.PartialInterfaceShuffle() err = userInterface.PartialInterfaceShuffle()

View File

@@ -1,7 +0,0 @@
package sql_driver
import "testing"
func TestInitTables(t *testing.T) {
InitTables()
}

View File

@@ -15,10 +15,9 @@ import (
func TestApi(t *testing.T) { func TestApi(t *testing.T) {
base := "http://localhost:8080" base := "http://localhost:8080"
newCustomerBody := m.NewCustomerPost{ newCustomerBody := m.NewCustomerPost{
KeypadSize: m.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 10},
NKodePolicy: m.NewDefaultNKodePolicy(), NKodePolicy: m.NewDefaultNKodePolicy(),
} }
kp := m.KeypadDefault
var customerResp m.CreateNewCustomerResp var customerResp m.CreateNewCustomerResp
testApiCall(t, base+api.CreateNewCustomer, newCustomerBody, &customerResp) testApiCall(t, base+api.CreateNewCustomer, newCustomerBody, &customerResp)
@@ -30,8 +29,8 @@ func TestApi(t *testing.T) {
passcodeLen := 4 passcodeLen := 4
setInterface := signupInterfaceResp.UserInterface setInterface := signupInterfaceResp.UserInterface
userPasscode := setInterface[:passcodeLen] userPasscode := setInterface[:passcodeLen]
keypadSize := m.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 5} kp = m.KeypadDimension{NumbOfKeys: kp.NumbOfKeys, AttrsPerKey: kp.NumbOfKeys}
setKeySelection, err := nkode.SelectKeyByAttrIdx(setInterface, userPasscode, keypadSize) setKeySelection, err := nkode.SelectKeyByAttrIdx(setInterface, userPasscode, kp)
assert.NoError(t, err) assert.NoError(t, err)
setNKodeBody := m.SetNKodePost{ setNKodeBody := m.SetNKodePost{
CustomerId: customerResp.CustomerId, CustomerId: customerResp.CustomerId,
@@ -42,7 +41,7 @@ func TestApi(t *testing.T) {
var setNKodeResp m.SetNKodeResp var setNKodeResp m.SetNKodeResp
testApiCall(t, base+api.SetNKode, setNKodeBody, &setNKodeResp) testApiCall(t, base+api.SetNKode, setNKodeBody, &setNKodeResp)
confirmInterface := setNKodeResp.UserInterface confirmInterface := setNKodeResp.UserInterface
confirmKeySelection, err := nkode.SelectKeyByAttrIdx(confirmInterface, userPasscode, keypadSize) confirmKeySelection, err := nkode.SelectKeyByAttrIdx(confirmInterface, userPasscode, kp)
assert.NoError(t, err) assert.NoError(t, err)
confirmNKodeBody := m.ConfirmNKodePost{ confirmNKodeBody := m.ConfirmNKodePost{
CustomerId: customerResp.CustomerId, CustomerId: customerResp.CustomerId,
@@ -59,8 +58,8 @@ func TestApi(t *testing.T) {
var loginInterfaceResp m.GetLoginInterfaceResp var loginInterfaceResp m.GetLoginInterfaceResp
testApiCall(t, base+api.GetLoginInterface, loginInterfaceBody, &loginInterfaceResp) testApiCall(t, base+api.GetLoginInterface, loginInterfaceBody, &loginInterfaceResp)
keypadSize = m.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 10} kp = m.KeypadDefault
loginKeySelection, err := nkode.SelectKeyByAttrIdx(loginInterfaceResp.UserInterface, userPasscode, keypadSize) loginKeySelection, err := nkode.SelectKeyByAttrIdx(loginInterfaceResp.UserInterface, userPasscode, kp)
assert.NoError(t, err) assert.NoError(t, err)
loginBody := m.LoginPost{ loginBody := m.LoginPost{
CustomerId: customerResp.CustomerId, CustomerId: customerResp.CustomerId,
@@ -73,7 +72,7 @@ func TestApi(t *testing.T) {
renewBody := m.RenewAttributesPost{CustomerId: customerResp.CustomerId} renewBody := m.RenewAttributesPost{CustomerId: customerResp.CustomerId}
testApiCall(t, base+api.RenewAttributes, renewBody, nil) testApiCall(t, base+api.RenewAttributes, renewBody, nil)
loginKeySelection, err = nkode.SelectKeyByAttrIdx(loginInterfaceResp.UserInterface, userPasscode, keypadSize) loginKeySelection, err = nkode.SelectKeyByAttrIdx(loginInterfaceResp.UserInterface, userPasscode, kp)
assert.NoError(t, err) assert.NoError(t, err)
loginBody = m.LoginPost{ loginBody = m.LoginPost{
CustomerId: customerResp.CustomerId, CustomerId: customerResp.CustomerId,

View File

@@ -147,7 +147,7 @@ func IdentityArray(arrLen int) []int {
func ListToMatrix(listArr []int, numbCols int) ([][]int, error) { func ListToMatrix(listArr []int, numbCols int) ([][]int, error) {
if len(listArr)%numbCols != 0 { if len(listArr)%numbCols != 0 {
return nil, errors.New(fmt.Sprintf("Array is not evenly divisible by number of columns: %d mod %d = %d", len(listArr), numbCols, len(listArr)%numbCols)) panic(fmt.Sprintf("Array is not evenly divisible by number of columns: %d mod %d = %d", len(listArr), numbCols, len(listArr)%numbCols))
} }
numbRows := len(listArr) / numbCols numbRows := len(listArr) / numbCols
matrix := make([][]int, numbRows) matrix := make([][]int, numbRows)