92 lines
2.4 KiB
Go
92 lines
2.4 KiB
Go
package m
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"github.com/google/uuid"
|
|
"go-nkode/hashset"
|
|
py "go-nkode/py-builtin"
|
|
"go-nkode/util"
|
|
)
|
|
|
|
type Customer struct {
|
|
Id CustomerId
|
|
NKodePolicy NKodePolicy
|
|
Attributes CustomerAttributes
|
|
}
|
|
|
|
func NewCustomer(nkodePolicy NKodePolicy) (*Customer, error) {
|
|
customerAttrs, err := NewCustomerAttributes()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
customer := Customer{
|
|
Id: CustomerId(uuid.New()),
|
|
NKodePolicy: nkodePolicy,
|
|
Attributes: *customerAttrs,
|
|
}
|
|
|
|
return &customer, nil
|
|
}
|
|
|
|
func (c *Customer) IsValidNKode(kp 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.AttrValsForKp(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, len(c.Attributes.AttrVals))
|
|
oldSets := make([]uint64, len(c.Attributes.SetVals))
|
|
|
|
copy(oldAttrs, c.Attributes.AttrVals)
|
|
copy(oldSets, c.Attributes.SetVals)
|
|
|
|
err := c.Attributes.Renew()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
attrsXor, err := util.XorLists(oldAttrs, c.Attributes.AttrVals)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
setXor, err := util.XorLists(oldSets, c.Attributes.SetVals)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return setXor, attrsXor
|
|
}
|