package thread import ( "crypto/rand" "encoding/binary" "fmt" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys" "hash/fnv" "github.com/textileio/go-threads/core/thread" ) func CreateACLThreadID(k keys.SigningPubKey, docType uint16) (thread.ID, error) { rndlen := 32 buf := make([]byte, 8+rndlen) // adding random bytes in the end _, err := rand.Read(buf[8 : 8+rndlen]) if err != nil { panic("random read failed") } keyBytes, err := k.Bytes() if err != nil { return thread.Undef, err } hasher := fnv.New64() hasher.Write(keyBytes) res := hasher.Sum64() // putting hash of the pubkey in the beginning binary.LittleEndian.PutUint64(buf[:8], res) return threadIDFromBytes(docType, buf) } func VerifyACLThreadID(k keys.SigningPubKey, threadId thread.ID) (bool, error) { bytes := threadId.Bytes() pubKeyBytes := threadId.Bytes()[len(bytes)-40 : len(bytes)-32] hash := binary.LittleEndian.Uint64(pubKeyBytes) keyBytes, err := k.Bytes() if err != nil { return false, err } hasher := fnv.New64() hasher.Write(keyBytes) realHash := hasher.Sum64() return hash == realHash, nil } func threadIDFromBytes( docType uint16, b []byte) (thread.ID, error) { blen := len(b) // two 8 bytes (max) numbers plus num buf := make([]byte, 2*binary.MaxVarintLen64+blen) n := binary.PutUvarint(buf, thread.V1) n += binary.PutUvarint(buf[n:], uint64(thread.AccessControlled)) n += binary.PutUvarint(buf[n:], uint64(docType)) cn := copy(buf[n:], b) if cn != blen { return thread.Undef, fmt.Errorf("copy length is inconsistent") } return thread.Cast(buf[:n+blen]) }