mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-08 14:07:02 +09:00
72 lines
1.6 KiB
Go
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])
|
|
}
|