From 3bf2b4d71f48160ea3988d87f62eecf47edf14b6 Mon Sep 17 00:00:00 2001 From: Donovan Date: Sat, 24 Aug 2024 21:02:50 -0500 Subject: [PATCH] refactor user defined keypad --- .gitignore | 1 + core/api/nkode_handler.go | 4 +- core/model/keypad_dimension.go | 40 ++++++++++++++ core/model/keypad_size.go | 19 ------- core/model/type.go | 16 +++--- core/nkode/customer.go | 85 ++++++++++++++++++++---------- core/nkode/customer_attributes.go | 57 ++++++++++++-------- core/nkode/customer_test.go | 24 ++++----- core/nkode/nkode_in_memory.go | 12 ++--- core/nkode/nkode_in_memory_test.go | 10 ++-- core/nkode/test_helper.go | 2 +- core/nkode/user.go | 4 +- core/nkode/user_cipher_keys.go | 44 +++++++++------- core/nkode/user_interface.go | 32 +++++------ core/nkode/user_signup_session.go | 45 ++++++++++------ core/nkode/user_test.go | 44 +++++++++------- core/sql-driver/sql_driver_test.go | 7 --- main_test.go | 15 +++--- util/util.go | 2 +- 19 files changed, 273 insertions(+), 190 deletions(-) create mode 100644 core/model/keypad_dimension.go delete mode 100644 core/model/keypad_size.go delete mode 100644 core/sql-driver/sql_driver_test.go diff --git a/.gitignore b/.gitignore index 17952c7..d5355b5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .idea tmp +*.db diff --git a/core/api/nkode_handler.go b/core/api/nkode_handler.go index e448121..9956562 100644 --- a/core/api/nkode_handler.go +++ b/core/api/nkode_handler.go @@ -46,7 +46,7 @@ func (h *NKodeHandler) CreateNewCustomerHandler(w http.ResponseWriter, r *http.R log.Fatal(err) return } - customerId, err := h.Api.CreateNewCustomer(customerPost.KeypadSize, customerPost.NKodePolicy) + customerId, err := h.Api.CreateNewCustomer(customerPost.NKodePolicy) if err != nil { internalServerErrorHandler(w) log.Fatal(err) @@ -84,7 +84,7 @@ func (h *NKodeHandler) GenerateSignupInterfaceHandler(w http.ResponseWriter, r * log.Fatal(err) return } - resp, err := h.Api.GenerateSignupInterface(signupPost.CustomerId) + resp, err := h.Api.GenerateSignupInterface(signupPost.CustomerId, m.KeypadDefault) if err != nil { internalServerErrorHandler(w) log.Fatal(err) diff --git a/core/model/keypad_dimension.go b/core/model/keypad_dimension.go new file mode 100644 index 0000000..ab3f3a4 --- /dev/null +++ b/core/model/keypad_dimension.go @@ -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, + } +) diff --git a/core/model/keypad_size.go b/core/model/keypad_size.go deleted file mode 100644 index 3c8a47c..0000000 --- a/core/model/keypad_size.go +++ /dev/null @@ -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 -} diff --git a/core/model/type.go b/core/model/type.go index e0faecf..fb45d05 100644 --- a/core/model/type.go +++ b/core/model/type.go @@ -9,7 +9,6 @@ type SetNKodeResp struct { } type NewCustomerPost struct { - KeypadSize KeypadSize `json:"keypad_size"` NKodePolicy NKodePolicy `json:"nkode_policy"` } @@ -65,11 +64,16 @@ type Username string type IdxInterface []int type NKodeAPIInterface interface { - CreateNewCustomer(KeypadSize, NKodePolicy) (*CustomerId, error) - GenerateSignupInterface(CustomerId) (*GenerateSignupInterfaceResp, error) + CreateNewCustomer(NKodePolicy) (*CustomerId, error) + GenerateSignupInterface(CustomerId, KeypadDimension) (*GenerateSignupInterfaceResp, error) SetNKode(Username, CustomerId, SessionId, KeySelection) (IdxInterface, error) ConfirmNKode(CustomerId, SessionId, KeySelection) error - GetLoginInterface(username Username, customerId CustomerId) (IdxInterface, error) - Login(customerId CustomerId, username Username, keySelection KeySelection) error - RenewAttributes(customerId CustomerId) error + GetLoginInterface(Username, CustomerId) (IdxInterface, error) + Login(CustomerId, Username, KeySelection) error + RenewAttributes(CustomerId) error +} + +type EncipheredNKode struct { + Code string + Mask string } diff --git a/core/nkode/customer.go b/core/nkode/customer.go index 5774f18..6bcf38f 100644 --- a/core/nkode/customer.go +++ b/core/nkode/customer.go @@ -17,15 +17,8 @@ type Customer struct { Users map[m.Username]User } -func NewCustomer(keypadSize m.KeypadSize, nkodePolicy m.NKodePolicy) (*Customer, error) { - if keypadSize.TotalAttrs() < nkodePolicy.DistinctAttributes { - 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) +func NewCustomer(nkodePolicy m.NKodePolicy) (*Customer, error) { + customerAttrs, err := NewCustomerAttributes() if err != nil { return nil, err } @@ -39,12 +32,16 @@ func NewCustomer(keypadSize m.KeypadSize, nkodePolicy m.NKodePolicy) (*Customer, 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] if exists { 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 { return err } @@ -56,7 +53,8 @@ func (c *Customer) AddNewUser(username m.Username, passcodeIdx []int, userInterf Username: username, EncipheredPasscode: *encipheredNKode, UserKeys: *newKeys, - Interface: userInterface, + Interface: ui, + Kp: kp, } c.Users[username] = newUser 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 { - return 0 <= idx && idx < c.Attributes.KeypadSize.NumbOfKeys + return 0 <= idx && idx < user.Kp.NumbOfKeys }) 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) if err != nil { return nil, err } - err = c.IsValidNKode(presumedAttrIdxVals) + err = c.IsValidNKode(user.Kp, presumedAttrIdxVals) if err != nil { 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 { return nil, err } @@ -96,7 +98,12 @@ func (c *Customer) getPresumedAttributeIdxVals(user User, selectedKeys []int) ([ 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)) } - 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 { return nil, err } @@ -117,24 +124,28 @@ func (c *Customer) getPresumedAttributeIdxVals(user User, selectedKeys []int) ([ return presumedAttrIdxVals, nil } -func (c *Customer) IsValidNKode(passcodeAttrIdx []int) error { +func (c *Customer) IsValidNKode(kp m.KeypadDimension, passcodeAttrIdx []int) error { nkodeLen := len(passcodeAttrIdx) 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)) } 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 { - 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]) passcodeAttrVals := make(hashset.Set[uint64]) + attrVals, err := c.Attributes.AttrVals(kp) + if err != nil { + return err + } for idx := 0; idx < nkodeLen; idx++ { - attrVal := c.Attributes.AttrVals[passcodeAttrIdx[idx]] - setVal, err := c.Attributes.GetAttrSetVal(attrVal) + attrVal := attrVals[passcodeAttrIdx[idx]] + setVal, err := c.Attributes.GetAttrSetVal(attrVal, kp) if err != nil { return err } @@ -167,20 +178,36 @@ func (c *Customer) GetLoginInterface(username m.Username) ([]int, error) { } func (c *Customer) RenewKeys() error { - oldAttrs := make([]uint64, c.Attributes.KeypadSize.TotalAttrs()) - oldSets := make([]uint64, c.Attributes.KeypadSize.AttrsPerKey) - copy(oldAttrs, c.Attributes.AttrVals) - copy(oldSets, c.Attributes.SetVals) + oldAttrs := make([]uint64, m.KeypadMax.TotalAttrs()) + oldSets := make([]uint64, m.KeypadMax.AttrsPerKey) + allAttrVals, err := c.Attributes.AttrVals(m.KeypadMax) + 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 { return nil } - attrsXor, err := util.XorLists(oldAttrs, c.Attributes.AttrVals) + allAttrVals, err = c.Attributes.AttrVals(m.KeypadMax) if err != 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 { return nil } diff --git a/core/nkode/customer_attributes.go b/core/nkode/customer_attributes.go index 5219f7a..daf4086 100644 --- a/core/nkode/customer_attributes.go +++ b/core/nkode/customer_attributes.go @@ -7,68 +7,79 @@ import ( "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 { - AttrVals []uint64 - SetVals []uint64 - KeypadSize m.KeypadSize + attrVals []uint64 + setVals []uint64 } -func NewCustomerAttributes(keypadSize m.KeypadSize) (*CustomerAttributes, error) { - if keypadSize.IsDispersable() { - 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()) +func NewCustomerAttributes() (*CustomerAttributes, error) { + attrVals, errAttr := util.GenerateRandomNonRepeatingUint64(m.KeypadMax.TotalAttrs()) if errAttr != nil { return nil, errAttr } - setVals, errSet := util.GenerateRandomNonRepeatingUint64(keypadSize.AttrsPerKey) + setVals, errSet := util.GenerateRandomNonRepeatingUint64(m.KeypadMax.AttrsPerKey) if errSet != nil { return nil, errSet } customerAttrs := CustomerAttributes{ - AttrVals: attrVals, - SetVals: setVals, - KeypadSize: keypadSize, + attrVals: attrVals, + setVals: setVals, } return &customerAttrs, nil } func (c *CustomerAttributes) Renew() error { - attrVals, errAttr := util.GenerateRandomNonRepeatingUint64(c.KeypadSize.TotalAttrs()) + attrVals, errAttr := util.GenerateRandomNonRepeatingUint64(m.KeypadMax.TotalAttrs()) if errAttr != nil { return errAttr } - setVals, errSet := util.GenerateRandomNonRepeatingUint64(c.KeypadSize.AttrsPerKey) + setVals, errSet := util.GenerateRandomNonRepeatingUint64(m.KeypadMax.AttrsPerKey) if errSet != nil { return errSet } - c.AttrVals = attrVals - c.SetVals = setVals + c.attrVals = attrVals + c.setVals = setVals return nil } func (c *CustomerAttributes) IndexOfAttr(attrVal uint64) int { // 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) { // TODO: should this be mapped instead? - idx := util.IndexOf[uint64](c.SetVals, setVal) + idx := util.IndexOf[uint64](c.setVals, setVal) if idx == -1 { return -1, errors.New(fmt.Sprintf("Set Val %d is invalid", setVal)) } 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) if indexOfAttr == -1 { return 0, errors.New(fmt.Sprintf("No attribute %d", attrVal)) } - setIdx := indexOfAttr % c.KeypadSize.AttrsPerKey - return c.SetVals[setIdx], nil + setIdx := indexOfAttr % userKeypad.AttrsPerKey + 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 } diff --git a/core/nkode/customer_test.go b/core/nkode/customer_test.go index cf76cc7..69c75fb 100644 --- a/core/nkode/customer_test.go +++ b/core/nkode/customer_test.go @@ -13,25 +13,25 @@ func TestCustomer(t *testing.T) { } func testNewCustomerAttributes(t *testing.T) { - keypad := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} - _, nil := NewCustomerAttributes(keypad) + // keypad := m.KeypadDimension{AttrsPerKey: 10, NumbOfKeys: 5} + _, nil := NewCustomerAttributes() assert.NoError(t, nil) } func testCustomerValidKeyEntry(t *testing.T) { - keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7} + kp := m.KeypadDimension{AttrsPerKey: 10, NumbOfKeys: 9} nkodePolicy := m.NewDefaultNKodePolicy() - customer, err := NewCustomer(keypadSize, nkodePolicy) + customer, err := NewCustomer(nkodePolicy) assert.NoError(t, err) - newUserInterface, err := NewUserInterface(customer.Attributes.KeypadSize) + newUserInterface, err := NewUserInterface(&kp) assert.NoError(t, err) username := m.Username("testing123") passcodeIdx := []int{0, 1, 2, 3} - err = customer.AddNewUser(username, passcodeIdx, *newUserInterface) + err = customer.AddNewUser(username, passcodeIdx, *newUserInterface, kp) assert.NoError(t, err) userLoginInterface, err := customer.GetLoginInterface(username) assert.NoError(t, err) - selectedKeys, err := SelectKeyByAttrIdx(userLoginInterface, passcodeIdx, keypadSize) + selectedKeys, err := SelectKeyByAttrIdx(userLoginInterface, passcodeIdx, kp) assert.NoError(t, err) validatedPasscode, err := customer.ValidKeyEntry(username, selectedKeys) assert.NoError(t, err) @@ -42,16 +42,16 @@ func testCustomerValidKeyEntry(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() - customer, err := NewCustomer(keypadSize, nkodePolicy) + customer, err := NewCustomer(nkodePolicy) assert.NoError(t, err) - newUserInterface, err := NewUserInterface(customer.Attributes.KeypadSize) + newUserInterface, err := NewUserInterface(&kp) assert.NoError(t, err) username := m.Username("testing123") passcodeIdx := []int{0, 1, 2, 3} - err = customer.AddNewUser(username, passcodeIdx, *newUserInterface) + err = customer.AddNewUser(username, passcodeIdx, *newUserInterface, kp) assert.NoError(t, err) - err = customer.IsValidNKode(passcodeIdx) + err = customer.IsValidNKode(kp, passcodeIdx) assert.NoError(t, err) } diff --git a/core/nkode/nkode_in_memory.go b/core/nkode/nkode_in_memory.go index f3a4317..c5a2ab6 100644 --- a/core/nkode/nkode_in_memory.go +++ b/core/nkode/nkode_in_memory.go @@ -18,8 +18,8 @@ func NewNKodeInMemory() NKodeInMemory { } } -func (n *NKodeInMemory) CreateNewCustomer(keypadSize m.KeypadSize, nkodePolicy m.NKodePolicy) (*m.CustomerId, error) { - newCustomer, err := NewCustomer(keypadSize, nkodePolicy) +func (n *NKodeInMemory) CreateNewCustomer(nkodePolicy m.NKodePolicy) (*m.CustomerId, error) { + newCustomer, err := NewCustomer(nkodePolicy) if err != nil { return nil, err } @@ -27,13 +27,13 @@ func (n *NKodeInMemory) CreateNewCustomer(keypadSize m.KeypadSize, nkodePolicy m 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] if !exists { 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 { return nil, err } @@ -73,11 +73,11 @@ func (n *NKodeInMemory) ConfirmNKode(customerId m.CustomerId, sessionId m.Sessio if err != nil { return err } - err = customer.IsValidNKode(passcode) + err = customer.IsValidNKode(session.Kp, passcode) if err != nil { return err } - err = customer.AddNewUser(session.Username, passcode, session.LoginUserInterface) + err = customer.AddNewUser(session.Username, passcode, session.LoginUserInterface, session.Kp) if err != nil { return err } diff --git a/core/nkode/nkode_in_memory_test.go b/core/nkode/nkode_in_memory_test.go index 49d3bf2..377a19c 100644 --- a/core/nkode/nkode_in_memory_test.go +++ b/core/nkode/nkode_in_memory_test.go @@ -11,15 +11,15 @@ func TestNKodeAPI(t *testing.T) { username := m.Username("test_username") passcodeLen := 4 nkodePolicy := m.NewDefaultNKodePolicy() - keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3} + keypadSize := m.KeypadDimension{AttrsPerKey: 10, NumbOfKeys: 8} nkodeApi := NewNKodeInMemory() - customerId, err := nkodeApi.CreateNewCustomer(keypadSize, nkodePolicy) + customerId, err := nkodeApi.CreateNewCustomer(nkodePolicy) assert.NoError(t, err) - signupResponse, err := nkodeApi.GenerateSignupInterface(*customerId) + signupResponse, err := nkodeApi.GenerateSignupInterface(*customerId, keypadSize) assert.NoError(t, err) setInterface := signupResponse.UserInterface sessionId := signupResponse.SessionId - keypadSize = m.KeypadSize{AttrsPerKey: 3, NumbOfKeys: 3} + keypadSize = m.KeypadDimension{AttrsPerKey: 8, NumbOfKeys: 8} userPasscode := setInterface[:passcodeLen] setKeySelect, err := SelectKeyByAttrIdx(setInterface, userPasscode, keypadSize) assert.NoError(t, err) @@ -29,7 +29,7 @@ func TestNKodeAPI(t *testing.T) { err = nkodeApi.ConfirmNKode(*customerId, sessionId, confirmKeySelect) assert.NoError(t, err) - keypadSize = m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3} + keypadSize = m.KeypadDimension{AttrsPerKey: 10, NumbOfKeys: 8} loginInterface, err := nkodeApi.GetLoginInterface(username, *customerId) assert.NoError(t, err) loginKeySelection, err := SelectKeyByAttrIdx(loginInterface, userPasscode, keypadSize) diff --git a/core/nkode/test_helper.go b/core/nkode/test_helper.go index 689e1e1..c82b943 100644 --- a/core/nkode/test_helper.go +++ b/core/nkode/test_helper.go @@ -7,7 +7,7 @@ import ( "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)) for idx := range passcodeIdxs { attrIdx := util.IndexOf[int](interfaceUser, passcodeIdxs[idx]) diff --git a/core/nkode/user.go b/core/nkode/user.go index a860915..6b7a15f 100644 --- a/core/nkode/user.go +++ b/core/nkode/user.go @@ -8,6 +8,7 @@ import ( type User struct { Username m.Username EncipheredPasscode m.EncipheredNKode + Kp m.KeypadDimension UserKeys UserCipherKeys Interface UserInterface Renew bool @@ -29,7 +30,8 @@ func (u *User) RenewKeys(setXor []uint64, attrXor []uint64) 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 { return err } diff --git a/core/nkode/user_cipher_keys.go b/core/nkode/user_cipher_keys.go index 6494cd7..0702dda 100644 --- a/core/nkode/user_cipher_keys.go +++ b/core/nkode/user_cipher_keys.go @@ -3,7 +3,6 @@ package nkode import ( "crypto/sha256" "errors" - "fmt" m "go-nkode/core/model" "go-nkode/util" "golang.org/x/crypto/bcrypt" @@ -16,14 +15,15 @@ type UserCipherKeys struct { MaskKey []uint64 Salt []byte MaxNKodeLen int + kp *m.KeypadDimension } -func NewUserCipherKeys(keypadSize m.KeypadSize, setVals []uint64, maxNKodeLen int) (*UserCipherKeys, error) { - if len(setVals) != keypadSize.AttrsPerKey { - return nil, errors.New(fmt.Sprintf("setVals len != attrsPerKey, %d, %d", len(setVals), keypadSize.AttrsPerKey)) +func NewUserCipherKeys(kp *m.KeypadDimension, setVals []uint64, maxNKodeLen int) (*UserCipherKeys, error) { + err := kp.IsValidKeypadDimension() + if err != nil { + return nil, err } - - setKey, err := util.GenerateRandomNonRepeatingUint64(keypadSize.AttrsPerKey) + setKey, err := util.GenerateRandomNonRepeatingUint64(kp.AttrsPerKey) if err != nil { return nil, err } @@ -32,7 +32,7 @@ func NewUserCipherKeys(keypadSize m.KeypadSize, setVals []uint64, maxNKodeLen in return nil, err } - alphakey, _ := util.GenerateRandomNonRepeatingUint64(keypadSize.TotalAttrs()) + alphakey, _ := util.GenerateRandomNonRepeatingUint64(kp.TotalAttrs()) passKey, _ := util.GenerateRandomNonRepeatingUint64(maxNKodeLen) maskKey, _ := util.GenerateRandomNonRepeatingUint64(maxNKodeLen) salt, _ := util.RandomBytes(10) @@ -43,6 +43,7 @@ func NewUserCipherKeys(keypadSize m.KeypadSize, setVals []uint64, maxNKodeLen in SetKey: setKey, Salt: salt, MaxNKodeLen: maxNKodeLen, + kp: kp, } return &userCipherKeys, nil } @@ -59,9 +60,9 @@ func (u *UserCipherKeys) PadUserMask(userMask []uint64, setVals []uint64) ([]uin 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) - passcodeCipher := u.encipherCode(passcodeAttrIdx, customerAttrs) + passcodeCipher := u.encipherCode(passcodeAttrIdx, attrVals) passwordDigest, err := u.saltAndDigest(passcodeCipher) if err != nil { return err @@ -73,8 +74,8 @@ func (u *UserCipherKeys) ValidPassword(hashedPassword string, passcodeAttrIdx [] return nil } -func (u *UserCipherKeys) EncipherSaltHashCode(passcodeAttrIdx []int, customerAttrs CustomerAttributes) (string, error) { - passcodeCipher := u.encipherCode(passcodeAttrIdx, customerAttrs) +func (u *UserCipherKeys) EncipherSaltHashCode(passcodeAttrIdx []int, attrVals []uint64) (string, error) { + passcodeCipher := u.encipherCode(passcodeAttrIdx, attrVals) passcodeDigest, err := u.saltAndDigest(passcodeCipher) if err != nil { @@ -87,7 +88,7 @@ func (u *UserCipherKeys) EncipherSaltHashCode(passcodeAttrIdx []int, customerAtt 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) passcodeCipher := make([]uint64, u.MaxNKodeLen) @@ -95,7 +96,7 @@ func (u *UserCipherKeys) encipherCode(passcodeAttrIdx []int, customerAttrs Custo for idx := 0; idx < passcodeLen; idx++ { attrIdx := passcodeAttrIdx[idx] alpha := u.AlphaKey[attrIdx] - attrVal := customerAttrs.AttrVals[idx] + attrVal := attrVals[idx] pass := u.PassKey[idx] passcodeCipher[idx] = alpha ^ pass ^ attrVal } @@ -122,8 +123,12 @@ func (u *UserCipherKeys) hashPasscode(passcodeDigest []byte) ([]byte, error) { } return hashedPassword, nil } -func (u *UserCipherKeys) EncipherMask(passcodeSet []uint64, customerAttrs CustomerAttributes) (string, error) { - paddedPasscodeSets, err := u.PadUserMask(passcodeSet, customerAttrs.SetVals) +func (u *UserCipherKeys) EncipherMask(passcodeSet []uint64, customerAttrs CustomerAttributes, userKp m.KeypadDimension) (string, error) { + setVals, err := customerAttrs.SetVals(userKp) + if err != nil { + return "", err + } + paddedPasscodeSets, err := u.PadUserMask(passcodeSet, setVals) if err != nil { 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) { - code, err := u.EncipherSaltHashCode(passcodeAttrIdx, customerAttrs) + attrVals, err := customerAttrs.AttrVals(*u.kp) + code, err := u.EncipherSaltHashCode(passcodeAttrIdx, attrVals) if err != nil { return nil, err } passcodeSet := make([]uint64, len(passcodeAttrIdx)) for idx := range passcodeSet { - passcodeAttr := customerAttrs.AttrVals[passcodeAttrIdx[idx]] - passcodeSet[idx], err = customerAttrs.GetAttrSetVal(passcodeAttr) + passcodeAttr := attrVals[passcodeAttrIdx[idx]] + passcodeSet[idx], err = customerAttrs.GetAttrSetVal(passcodeAttr, *u.kp) if err != nil { return nil, err } } - mask, err := u.EncipherMask(passcodeSet, customerAttrs) + mask, err := u.EncipherMask(passcodeSet, customerAttrs, *u.kp) encipheredCode := m.EncipheredNKode{ Code: code, Mask: mask, diff --git a/core/nkode/user_interface.go b/core/nkode/user_interface.go index 30c5eb0..2d4d604 100644 --- a/core/nkode/user_interface.go +++ b/core/nkode/user_interface.go @@ -10,14 +10,14 @@ import ( type UserInterface struct { IdxInterface m.IdxInterface - KeypadSize m.KeypadSize + kp *m.KeypadDimension } -func NewUserInterface(keypadSize m.KeypadSize) (*UserInterface, error) { - idxInterface := util.IdentityArray(keypadSize.TotalAttrs()) +func NewUserInterface(kp *m.KeypadDimension) (*UserInterface, error) { + idxInterface := util.IdentityArray(kp.TotalAttrs()) userInterface := UserInterface{ IdxInterface: idxInterface, - KeypadSize: keypadSize, + kp: kp, } err := userInterface.RandomShuffle() if err != nil { @@ -55,7 +55,7 @@ func (u *UserInterface) RandomShuffle() 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) { @@ -67,8 +67,8 @@ func (u *UserInterface) SetViewMatrix() ([][]int, error) { } func (u *UserInterface) DisperseInterface() error { - if !u.KeypadSize.IsDispersable() { - return errors.New("interface is not dispersable") + if !u.kp.IsDispersable() { + panic("interface is not dispersable") } err := u.shuffleKeys() @@ -84,7 +84,7 @@ func (u *UserInterface) DisperseInterface() 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 { return err } @@ -144,11 +144,11 @@ func (u *UserInterface) PartialInterfaceShuffle() error { if err != nil { return err } - numbOfSelectedSets := u.KeypadSize.AttrsPerKey / 2 - if u.KeypadSize.AttrsPerKey&1 == 1 { + numbOfSelectedSets := u.kp.AttrsPerKey / 2 + if u.kp.AttrsPerKey&1 == 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 { return err } @@ -158,7 +158,7 @@ func (u *UserInterface) PartialInterfaceShuffle() error { if err != nil { return err } - interfaceBySet := make([][]int, u.KeypadSize.AttrsPerKey) + interfaceBySet := make([][]int, u.kp.AttrsPerKey) for idx, attrs := range keypadSetView { if selectedSets.Contains(idx) { err = util.FisherYatesShuffle[int](&attrs) @@ -177,12 +177,12 @@ func (u *UserInterface) PartialInterfaceShuffle() error { } func (u *UserInterface) GetAttrIdxByKeyNumbSetIdx(setIdx int, keyNumb int) (int, error) { - if keyNumb < 0 || u.KeypadSize.NumbOfKeys <= keyNumb { - return -1, errors.New(fmt.Sprintf("keyNumb %d is out of range 0-%d", keyNumb, u.KeypadSize.NumbOfKeys)) + if keyNumb < 0 || u.kp.NumbOfKeys <= keyNumb { + 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 { - return -1, errors.New(fmt.Sprintf("setIdx %d is out of range 0-%d", setIdx, u.KeypadSize.AttrsPerKey)) + if setIdx < 0 || u.kp.AttrsPerKey <= setIdx { + return -1, errors.New(fmt.Sprintf("setIdx %d is out of range 0-%d", setIdx, u.kp.AttrsPerKey)) } keypadView, err := u.InterfaceMatrix() if err != nil { diff --git a/core/nkode/user_signup_session.go b/core/nkode/user_signup_session.go index dc86af5..2f33083 100644 --- a/core/nkode/user_signup_session.go +++ b/core/nkode/user_signup_session.go @@ -14,28 +14,31 @@ type UserSignSession struct { SessionId m.SessionId CustomerId m.CustomerId LoginUserInterface UserInterface - Keypad m.KeypadSize + Kp m.KeypadDimension SetIdxInterface m.IdxInterface ConfirmIdxInterface m.IdxInterface SetKeySelection m.KeySelection Username m.Username } -func NewSignupSession(keypadSize m.KeypadSize, customerId m.CustomerId) (*UserSignSession, error) { - loginInterface, err := NewUserInterface(keypadSize) +func NewSignupSession(kp m.KeypadDimension, customerId m.CustomerId) (*UserSignSession, error) { + loginInterface, err := NewUserInterface(&kp) + if err != nil { + return nil, err + } + signupInterface, err := signupInterface(*loginInterface, kp) if err != nil { return nil, err } - signupInter, err := signupInterface(*loginInterface) session := UserSignSession{ SessionId: m.SessionId(uuid.New()), CustomerId: customerId, LoginUserInterface: *loginInterface, - SetIdxInterface: signupInter.IdxInterface, + SetIdxInterface: signupInterface.IdxInterface, ConfirmIdxInterface: nil, SetKeySelection: nil, Username: "", - Keypad: signupInter.KeypadSize, + Kp: kp, } 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) { 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 { - 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 { @@ -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) { 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 { - 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.Username = username - - setInterface := UserInterface{IdxInterface: s.SetIdxInterface, KeypadSize: s.Keypad} + setKp := s.SignupKeypad() + setInterface := UserInterface{IdxInterface: s.SetIdxInterface, kp: &setKp} err := setInterface.DisperseInterface() if err != nil { 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) { - keypadInterface, err := util.ListToMatrix(userInterface, s.Keypad.AttrsPerKey) + signupKp := s.SignupKeypad() + keypadInterface, err := util.ListToMatrix(userInterface, signupKp.AttrsPerKey) if err != nil { return nil, err } @@ -127,8 +131,8 @@ func (s *UserSignSession) getSelectedKeyVals(keySelections m.KeySelection, userI return keyVals, nil } -func signupInterface(baseUserInterface UserInterface) (*UserInterface, error) { - if baseUserInterface.KeypadSize.IsDispersable() { +func signupInterface(baseUserInterface UserInterface, kp m.KeypadDimension) (*UserInterface, error) { + if kp.IsDispersable() { return nil, errors.New("keypad is dispersable, can't use signupInterface") } err := baseUserInterface.RandomShuffle() @@ -147,7 +151,7 @@ func signupInterface(baseUserInterface UserInterface) (*UserInterface, error) { if err != nil { return nil, err } - numbOfKeys := baseUserInterface.KeypadSize.NumbOfKeys + numbOfKeys := kp.NumbOfKeys attrSetView = attrSetView[:numbOfKeys] attrSetView, err = util.MatrixTranspose(attrSetView) if err != nil { @@ -155,10 +159,17 @@ func signupInterface(baseUserInterface UserInterface) (*UserInterface, error) { } signupUserInterface := UserInterface{ IdxInterface: util.MatrixToList(attrSetView), - KeypadSize: m.KeypadSize{ + kp: &m.KeypadDimension{ AttrsPerKey: numbOfKeys, NumbOfKeys: numbOfKeys, }, } return &signupUserInterface, nil } + +func (s *UserSignSession) SignupKeypad() m.KeypadDimension { + return m.KeypadDimension{ + AttrsPerKey: s.Kp.NumbOfKeys, + NumbOfKeys: s.Kp.NumbOfKeys, + } +} diff --git a/core/nkode/user_test.go b/core/nkode/user_test.go index 6bb10a6..470a275 100644 --- a/core/nkode/user_test.go +++ b/core/nkode/user_test.go @@ -8,38 +8,46 @@ import ( ) func TestUserCipherKeys_EncipherSaltHashCode(t *testing.T) { - keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} + kp := m.KeypadDimension{AttrsPerKey: 10, NumbOfKeys: 8} maxNKodeLen := 10 - customerAttrs, err := NewCustomerAttributes(keypadSize) + customerAttrs, err := NewCustomerAttributes() 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) passcodeIdx := []int{0, 1, 2, 3} - encipher0, err := newUser.EncipherSaltHashCode(passcodeIdx, *customerAttrs) + encipher0, err := newUser.EncipherSaltHashCode(passcodeIdx, attrVals) assert.NoError(t, err) - err = newUser.ValidPassword(encipher0, passcodeIdx, *customerAttrs) + err = newUser.ValidPassword(encipher0, passcodeIdx, attrVals) assert.NoError(t, err) } func TestUserCipherKeys_EncipherDecipherMask(t *testing.T) { - keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} + kp := m.KeypadDimension{AttrsPerKey: 10, NumbOfKeys: 8} maxNKodeLen := 10 - customerAttrs, err := NewCustomerAttributes(keypadSize) + customerAttrs, err := NewCustomerAttributes() 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) passcodeIdx := []int{0, 1, 2, 3} originalSetVals := make([]uint64, len(passcodeIdx)) for idx, val := range passcodeIdx { - attr := customerAttrs.AttrVals[val] - originalSetVals[idx], err = customerAttrs.GetAttrSetVal(attr) + attr := attrVals[val] + originalSetVals[idx], err = customerAttrs.GetAttrSetVal(attr, kp) assert.NoError(t, err) } encipheredCode, err := newUser.EncipherNKode(passcodeIdx, *customerAttrs) 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) for idx, setVal := range passcodeSetVals { @@ -48,11 +56,11 @@ func TestUserCipherKeys_EncipherDecipherMask(t *testing.T) { } func TestUserInterface_RandomShuffle(t *testing.T) { - keypadSize := m.KeypadSize{ + kp := m.KeypadDimension{ AttrsPerKey: 10, - NumbOfKeys: 5, + NumbOfKeys: 8, } - userInterface, err := NewUserInterface(keypadSize) + userInterface, err := NewUserInterface(&kp) assert.NoError(t, err) userInterfaceCopy := make([]int, len(userInterface.IdxInterface)) copy(userInterfaceCopy, userInterface.IdxInterface) @@ -73,9 +81,9 @@ func TestUserInterface_RandomShuffle(t *testing.T) { func TestUserInterface_DisperseInterface(t *testing.T) { 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) preDispersion, err := userInterface.AttributeAdjacencyGraph() assert.NoError(t, err) @@ -92,8 +100,8 @@ func TestUserInterface_DisperseInterface(t *testing.T) { } func TestUserInterface_PartialInterfaceShuffle(t *testing.T) { - keypadSize := m.KeypadSize{AttrsPerKey: 7, NumbOfKeys: 10} - userInterface, err := NewUserInterface(keypadSize) + kp := m.KeypadDimension{AttrsPerKey: 7, NumbOfKeys: 10} + userInterface, err := NewUserInterface(&kp) assert.NoError(t, err) preShuffle := userInterface.IdxInterface err = userInterface.PartialInterfaceShuffle() diff --git a/core/sql-driver/sql_driver_test.go b/core/sql-driver/sql_driver_test.go deleted file mode 100644 index b3f2fe4..0000000 --- a/core/sql-driver/sql_driver_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package sql_driver - -import "testing" - -func TestInitTables(t *testing.T) { - InitTables() -} diff --git a/main_test.go b/main_test.go index 2979ff7..04f1a36 100644 --- a/main_test.go +++ b/main_test.go @@ -15,10 +15,9 @@ import ( func TestApi(t *testing.T) { base := "http://localhost:8080" newCustomerBody := m.NewCustomerPost{ - KeypadSize: m.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 10}, NKodePolicy: m.NewDefaultNKodePolicy(), } - + kp := m.KeypadDefault var customerResp m.CreateNewCustomerResp testApiCall(t, base+api.CreateNewCustomer, newCustomerBody, &customerResp) @@ -30,8 +29,8 @@ func TestApi(t *testing.T) { passcodeLen := 4 setInterface := signupInterfaceResp.UserInterface userPasscode := setInterface[:passcodeLen] - keypadSize := m.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 5} - setKeySelection, err := nkode.SelectKeyByAttrIdx(setInterface, userPasscode, keypadSize) + kp = m.KeypadDimension{NumbOfKeys: kp.NumbOfKeys, AttrsPerKey: kp.NumbOfKeys} + setKeySelection, err := nkode.SelectKeyByAttrIdx(setInterface, userPasscode, kp) assert.NoError(t, err) setNKodeBody := m.SetNKodePost{ CustomerId: customerResp.CustomerId, @@ -42,7 +41,7 @@ func TestApi(t *testing.T) { var setNKodeResp m.SetNKodeResp testApiCall(t, base+api.SetNKode, setNKodeBody, &setNKodeResp) confirmInterface := setNKodeResp.UserInterface - confirmKeySelection, err := nkode.SelectKeyByAttrIdx(confirmInterface, userPasscode, keypadSize) + confirmKeySelection, err := nkode.SelectKeyByAttrIdx(confirmInterface, userPasscode, kp) assert.NoError(t, err) confirmNKodeBody := m.ConfirmNKodePost{ CustomerId: customerResp.CustomerId, @@ -59,8 +58,8 @@ func TestApi(t *testing.T) { var loginInterfaceResp m.GetLoginInterfaceResp testApiCall(t, base+api.GetLoginInterface, loginInterfaceBody, &loginInterfaceResp) - keypadSize = m.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 10} - loginKeySelection, err := nkode.SelectKeyByAttrIdx(loginInterfaceResp.UserInterface, userPasscode, keypadSize) + kp = m.KeypadDefault + loginKeySelection, err := nkode.SelectKeyByAttrIdx(loginInterfaceResp.UserInterface, userPasscode, kp) assert.NoError(t, err) loginBody := m.LoginPost{ CustomerId: customerResp.CustomerId, @@ -73,7 +72,7 @@ func TestApi(t *testing.T) { renewBody := m.RenewAttributesPost{CustomerId: customerResp.CustomerId} 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) loginBody = m.LoginPost{ CustomerId: customerResp.CustomerId, diff --git a/util/util.go b/util/util.go index 63cff2d..87c165d 100644 --- a/util/util.go +++ b/util/util.go @@ -147,7 +147,7 @@ func IdentityArray(arrLen int) []int { func ListToMatrix(listArr []int, numbCols int) ([][]int, error) { 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 matrix := make([][]int, numbRows)