201 lines
5.6 KiB
Go
201 lines
5.6 KiB
Go
package nkode
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"github.com/google/uuid"
|
|
m "go-nkode/core/model"
|
|
"go-nkode/hashset"
|
|
py "go-nkode/py-builtin"
|
|
"go-nkode/util"
|
|
)
|
|
|
|
type Customer struct {
|
|
Id m.CustomerId
|
|
NKodePolicy m.NKodePolicy
|
|
Attributes CustomerAttributes
|
|
}
|
|
|
|
func NewCustomer(nkodePolicy m.NKodePolicy) (*Customer, error) {
|
|
customerAttrs, err := NewCustomerAttributes()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
customer := Customer{
|
|
Id: m.CustomerId(uuid.New()),
|
|
NKodePolicy: nkodePolicy,
|
|
Attributes: *customerAttrs,
|
|
}
|
|
|
|
return &customer, nil
|
|
}
|
|
|
|
//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.Id))
|
|
// }
|
|
// setVals, err := c.Attributes.SetVals(kp)
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
// newKeys, err := NewUserCipherKeys(&kp, setVals, c.NKodePolicy.MaxNkodeLen)
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
// encipheredNKode, err := newKeys.EncipherNKode(passcodeIdx, c.Attributes)
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
// newUser := User{
|
|
// Id: m.UserId(uuid.New()),
|
|
// Username: username,
|
|
// EncipheredPasscode: *encipheredNKode,
|
|
// UserKeys: *newKeys,
|
|
// Interface: ui,
|
|
// Kp: kp,
|
|
// }
|
|
// c.Users[username] = newUser
|
|
// return nil
|
|
//}
|
|
|
|
//func (c *Customer) ValidKeyEntry(username m.Username, selectedKeys []int) ([]int, error) {
|
|
// user, exists := c.Users[username]
|
|
// if !exists {
|
|
// return nil, errors.New(fmt.Sprintf("user %s does not exist for customer %+v", username, c.Id))
|
|
// }
|
|
//
|
|
// validKeys := py.All[int](selectedKeys, func(idx int) bool {
|
|
// return 0 <= idx && idx < user.Kp.NumbOfKeys
|
|
// })
|
|
// if !validKeys {
|
|
// 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(user.Kp, presumedAttrIdxVals)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
// 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
|
|
// }
|
|
//
|
|
// return presumedAttrIdxVals, nil
|
|
//}
|
|
|
|
//func (c *Customer) getPresumedAttributeIdxVals(user User, selectedKeys []int) ([]int, error) {
|
|
//
|
|
// passcodeLen := len(selectedKeys)
|
|
// 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))
|
|
// }
|
|
//
|
|
// 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
|
|
// }
|
|
// presumedAttrIdxVals := make([]int, passcodeLen)
|
|
//
|
|
// for idx := range presumedAttrIdxVals {
|
|
// keyNumb := selectedKeys[idx]
|
|
// setIdx, err := c.Attributes.IndexOfSet(passcodeSetVals[idx])
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
// selectedAttrIdx, err := user.Interface.GetAttrIdxByKeyNumbSetIdx(setIdx, keyNumb)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
// presumedAttrIdxVals[idx] = selectedAttrIdx
|
|
// }
|
|
// return presumedAttrIdxVals, nil
|
|
//}
|
|
|
|
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 < kp.TotalAttrs()
|
|
})
|
|
|
|
if !validIdx {
|
|
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 := attrVals[passcodeAttrIdx[idx]]
|
|
setVal, err := c.Attributes.GetAttrSetVal(attrVal, kp)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
passcodeSetVals.Add(setVal)
|
|
passcodeAttrVals.Add(attrVal)
|
|
}
|
|
|
|
if passcodeSetVals.Size() < c.NKodePolicy.DistinctSets {
|
|
return errors.New(fmt.Sprintf("passcode has two few distinct sets min %d, has %d", c.NKodePolicy.DistinctSets, passcodeSetVals.Size()))
|
|
}
|
|
|
|
if passcodeAttrVals.Size() < c.NKodePolicy.DistinctAttributes {
|
|
return errors.New(fmt.Sprintf("passcode has two few distinct attributes min %d, has %d", c.NKodePolicy.DistinctAttributes, passcodeAttrVals.Size()))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *Customer) RenewKeys() ([]uint64, []uint64) {
|
|
oldAttrs := make([]uint64, m.KeypadMax.TotalAttrs())
|
|
oldSets := make([]uint64, m.KeypadMax.AttrsPerKey)
|
|
allAttrVals, err := c.Attributes.AttrVals(m.KeypadMax)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
allSetVals, err := c.Attributes.AttrVals(m.KeypadMax)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
copy(oldAttrs, allAttrVals)
|
|
copy(oldSets, allSetVals)
|
|
|
|
err = c.Attributes.Renew()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
allAttrVals, err = c.Attributes.AttrVals(m.KeypadMax)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
allSetVals, err = c.Attributes.SetVals(m.KeypadMax)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
attrsXor, err := util.XorLists(oldAttrs, allAttrVals)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
setXor, err := util.XorLists(oldSets, allSetVals)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return setXor, attrsXor
|
|
}
|