1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-08 05:57:03 +09:00
any-sync/pkg/acl/thread/threadid.go
2022-07-13 20:09:19 +03:00

72 lines
1.6 KiB
Go

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])
}