160 lines
3.7 KiB
Go
160 lines
3.7 KiB
Go
package protocol
|
|
|
|
import (
|
|
ed25519p "crypto/ed25519"
|
|
"errors"
|
|
"git.lumeweb.com/LumeWeb/libs5-go/ed25519"
|
|
"git.lumeweb.com/LumeWeb/libs5-go/types"
|
|
"git.lumeweb.com/LumeWeb/libs5-go/utils"
|
|
)
|
|
|
|
var (
|
|
_ SignedRegistryEntry = (*SignedRegistryEntryImpl)(nil)
|
|
_ SignedRegistryEntry = (*SignedRegistryEntryImpl)(nil)
|
|
)
|
|
|
|
type SignedRegistryEntry interface {
|
|
PK() []byte
|
|
Revision() uint64
|
|
Data() []byte
|
|
Signature() []byte
|
|
SetPK(pk []byte)
|
|
SetRevision(revision uint64)
|
|
SetData(data []byte)
|
|
SetSignature(signature []byte)
|
|
Verify() bool
|
|
}
|
|
|
|
type RegistryEntry interface {
|
|
Sign() SignedRegistryEntry
|
|
}
|
|
|
|
type SignedRegistryEntryImpl struct {
|
|
pk []byte
|
|
revision uint64
|
|
data []byte
|
|
signature []byte
|
|
}
|
|
|
|
func (s *SignedRegistryEntryImpl) Verify() bool {
|
|
return VerifyRegistryEntry(s)
|
|
}
|
|
|
|
func (s *SignedRegistryEntryImpl) PK() []byte {
|
|
return s.pk
|
|
}
|
|
|
|
func (s *SignedRegistryEntryImpl) SetPK(pk []byte) {
|
|
s.pk = pk
|
|
}
|
|
|
|
func (s *SignedRegistryEntryImpl) Revision() uint64 {
|
|
return s.revision
|
|
}
|
|
|
|
func (s *SignedRegistryEntryImpl) SetRevision(revision uint64) {
|
|
s.revision = revision
|
|
}
|
|
|
|
func (s *SignedRegistryEntryImpl) Data() []byte {
|
|
return s.data
|
|
}
|
|
|
|
func (s *SignedRegistryEntryImpl) SetData(data []byte) {
|
|
s.data = data
|
|
}
|
|
|
|
func (s *SignedRegistryEntryImpl) Signature() []byte {
|
|
return s.signature
|
|
}
|
|
|
|
func (s *SignedRegistryEntryImpl) SetSignature(signature []byte) {
|
|
s.signature = signature
|
|
}
|
|
|
|
func NewSignedRegistryEntry(pk []byte, revision uint64, data []byte, signature []byte) SignedRegistryEntry {
|
|
return &SignedRegistryEntryImpl{
|
|
pk: pk,
|
|
revision: revision,
|
|
data: data,
|
|
signature: signature,
|
|
}
|
|
}
|
|
|
|
type RegistryEntryImpl struct {
|
|
kp ed25519.KeyPairEd25519
|
|
data []byte
|
|
revision uint64
|
|
}
|
|
|
|
func NewRegistryEntry(kp ed25519.KeyPairEd25519, data []byte, revision uint64) RegistryEntry {
|
|
return &RegistryEntryImpl{
|
|
kp: kp,
|
|
data: data,
|
|
revision: revision,
|
|
}
|
|
}
|
|
|
|
func (r *RegistryEntryImpl) Sign() SignedRegistryEntry {
|
|
return SignRegistryEntry(r.kp, r.data, r.revision)
|
|
}
|
|
|
|
func SignRegistryEntry(kp ed25519.KeyPairEd25519, data []byte, revision uint64) SignedRegistryEntry {
|
|
buffer := MarshalRegistryEntry(data, revision)
|
|
|
|
privateKey := kp.ExtractBytes()
|
|
signature := ed25519p.Sign(privateKey, buffer)
|
|
|
|
return NewSignedRegistryEntry(kp.PublicKey(), uint64(revision), data, signature)
|
|
}
|
|
func VerifyRegistryEntry(sre SignedRegistryEntry) bool {
|
|
buffer := MarshalRegistryEntry(sre.Data(), sre.Revision())
|
|
publicKey := sre.PK()[1:]
|
|
|
|
return ed25519p.Verify(publicKey, buffer, sre.Signature())
|
|
}
|
|
|
|
func MarshalSignedRegistryEntry(sre SignedRegistryEntry) []byte {
|
|
buffer := MarshalRegistryEntry(sre.Data(), sre.Revision())
|
|
buffer = append(buffer, sre.Signature()...)
|
|
|
|
return buffer
|
|
}
|
|
func MarshalRegistryEntry(data []byte, revision uint64) []byte {
|
|
var buffer []byte
|
|
buffer = append(buffer, byte(types.RecordTypeRegistryEntry))
|
|
|
|
revBytes := utils.EncodeEndian(revision, 8)
|
|
buffer = append(buffer, revBytes...)
|
|
|
|
buffer = append(buffer, byte(len(data)))
|
|
buffer = append(buffer, data...)
|
|
|
|
return buffer
|
|
}
|
|
|
|
func UnmarshalSignedRegistryEntry(event []byte) (sre SignedRegistryEntry, err error) {
|
|
if len(event) < 43 {
|
|
return nil, errors.New("Invalid registry entry")
|
|
}
|
|
|
|
dataLength := int(event[42])
|
|
if len(event) < 43+dataLength {
|
|
return nil, errors.New("Invalid registry entry")
|
|
}
|
|
|
|
pk := event[1:34]
|
|
revisionBytes := event[34:42]
|
|
revision := utils.DecodeEndian(revisionBytes)
|
|
signatureStart := 43 + dataLength
|
|
var signature []byte
|
|
|
|
if signatureStart < len(event) {
|
|
signature = event[signatureStart:]
|
|
} else {
|
|
return nil, errors.New("Invalid signature")
|
|
}
|
|
|
|
return NewSignedRegistryEntry(pk, uint64(revision), event[43:signatureStart], signature), nil
|
|
}
|