DHT Bootstrap Verification

This commit is contained in:
Cassandra Heart 2023-09-03 18:47:09 -05:00
parent 529f434393
commit c3ffd5c472
No known key found for this signature in database
GPG Key ID: 6352152859385958
32 changed files with 6422 additions and 496 deletions

4
.gitignore vendored
View File

@ -1,3 +1,5 @@
.idea/
vouchers/
ceremony-client
ceremony-client
.config*
.DS_Store

52
node/app/node.go Normal file
View File

@ -0,0 +1,52 @@
package app
import (
"errors"
"source.quilibrium.com/quilibrium/monorepo/node/consensus"
"source.quilibrium.com/quilibrium/monorepo/node/execution"
"source.quilibrium.com/quilibrium/monorepo/node/execution/nop"
)
type Node struct {
execEngines map[string]execution.ExecutionEngine
engine consensus.ConsensusEngine
}
func newNode(
nopExecutionEngine *nop.NopExecutionEngine,
engine consensus.ConsensusEngine,
) (*Node, error) {
if engine == nil {
return nil, errors.New("engine must not be nil")
}
execEngines := make(map[string]execution.ExecutionEngine)
if nopExecutionEngine != nil {
execEngines[nopExecutionEngine.GetName()] = nopExecutionEngine
}
return &Node{
execEngines,
engine,
}, nil
}
func (n *Node) Start() {
err := <-n.engine.Start()
if err != nil {
panic(err)
}
// TODO: add config mapping to engine name/frame registration
for _, e := range n.execEngines {
n.engine.RegisterExecutor(e, 0)
}
}
func (n *Node) Stop() {
err := <-n.engine.Stop(false)
if err != nil {
panic(err)
}
}

54
node/app/wire.go Normal file
View File

@ -0,0 +1,54 @@
//go:build wireinject
// +build wireinject
package app
import (
"github.com/google/wire"
"go.uber.org/zap"
"source.quilibrium.com/quilibrium/monorepo/node/config"
"source.quilibrium.com/quilibrium/monorepo/node/consensus"
"source.quilibrium.com/quilibrium/monorepo/node/consensus/master"
"source.quilibrium.com/quilibrium/monorepo/node/execution/nop"
"source.quilibrium.com/quilibrium/monorepo/node/keys"
"source.quilibrium.com/quilibrium/monorepo/node/p2p"
)
func logger() *zap.Logger {
log, err := zap.NewProduction()
if err != nil {
panic(err)
}
return log
}
var loggerSet = wire.NewSet(
logger,
)
var keyManagerSet = wire.NewSet(
wire.FieldsOf(new(*config.Config), "Key"),
keys.NewFileKeyManager,
wire.Bind(new(keys.KeyManager), new(*keys.FileKeyManager)),
)
var pubSubSet = wire.NewSet(
wire.FieldsOf(new(*config.Config), "P2P"),
p2p.NewBlossomSub,
wire.Bind(new(p2p.PubSub), new(*p2p.BlossomSub)),
)
var engineSet = wire.NewSet(
nop.NewNopExecutionEngine,
)
var consensusSet = wire.NewSet(
wire.FieldsOf(new(*config.Config), "Engine"),
master.NewMasterClockConsensusEngine,
wire.Bind(new(consensus.ConsensusEngine), new(*master.MasterClockConsensusEngine)),
)
func NewNode(*config.Config) (*Node, error) {
panic(wire.Build(loggerSet, keyManagerSet, pubSubSet, engineSet, consensusSet, newNode))
}

59
node/app/wire_gen.go Normal file
View File

@ -0,0 +1,59 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package app
import (
"github.com/google/wire"
"go.uber.org/zap"
"source.quilibrium.com/quilibrium/monorepo/node/config"
"source.quilibrium.com/quilibrium/monorepo/node/consensus"
"source.quilibrium.com/quilibrium/monorepo/node/consensus/master"
"source.quilibrium.com/quilibrium/monorepo/node/execution/nop"
"source.quilibrium.com/quilibrium/monorepo/node/keys"
"source.quilibrium.com/quilibrium/monorepo/node/p2p"
)
// Injectors from wire.go:
func NewNode(configConfig *config.Config) (*Node, error) {
zapLogger := logger()
nopExecutionEngine := nop.NewNopExecutionEngine(zapLogger)
engineConfig := configConfig.Engine
keyConfig := configConfig.Key
fileKeyManager := keys.NewFileKeyManager(keyConfig, zapLogger)
p2PConfig := configConfig.P2P
blossomSub := p2p.NewBlossomSub(p2PConfig, zapLogger)
masterClockConsensusEngine := master.NewMasterClockConsensusEngine(engineConfig, zapLogger, fileKeyManager, blossomSub)
node, err := newNode(nopExecutionEngine, masterClockConsensusEngine)
if err != nil {
return nil, err
}
return node, nil
}
// wire.go:
func logger() *zap.Logger {
log, err := zap.NewProduction()
if err != nil {
panic(err)
}
return log
}
var loggerSet = wire.NewSet(
logger,
)
var keyManagerSet = wire.NewSet(wire.FieldsOf(new(*config.Config), "Key"), keys.NewFileKeyManager, wire.Bind(new(keys.KeyManager), new(*keys.FileKeyManager)))
var pubSubSet = wire.NewSet(wire.FieldsOf(new(*config.Config), "P2P"), p2p.NewBlossomSub, wire.Bind(new(p2p.PubSub), new(*p2p.BlossomSub)))
var engineSet = wire.NewSet(nop.NewNopExecutionEngine)
var consensusSet = wire.NewSet(wire.FieldsOf(new(*config.Config), "Engine"), master.NewMasterClockConsensusEngine, wire.Bind(new(consensus.ConsensusEngine), new(*master.MasterClockConsensusEngine)))

View File

@ -0,0 +1,29 @@
package consensus
import (
"source.quilibrium.com/quilibrium/monorepo/node/execution"
)
type EngineState int
const (
EngineStateStopped EngineState = iota
EngineStateStarting
EngineStateLoading
EngineStateCollecting
EngineStateProving
EngineStatePublishing
EngineStateVerifying
EngineStateStopping
)
type ConsensusEngine interface {
Start() <-chan error
Stop(force bool) <-chan error
RegisterExecutor(exec execution.ExecutionEngine, frame uint64) <-chan error
UnregisterExecutor(name string, frame uint64, force bool) <-chan error
GetFrame() uint64
GetDifficulty() uint32
GetState() EngineState
GetFrameChannel() <-chan uint64
}

View File

@ -0,0 +1,228 @@
package master
import (
"bytes"
"strings"
"time"
"github.com/iden3/go-iden3-crypto/poseidon"
"github.com/pkg/errors"
"go.uber.org/zap"
"golang.org/x/sync/errgroup"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
"source.quilibrium.com/quilibrium/monorepo/go-libp2p-blossomsub/pb"
"source.quilibrium.com/quilibrium/monorepo/node/consensus"
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
)
func (e *MasterClockConsensusEngine) handleMessage(message *pb.Message) error {
e.logger.Debug(
"received message",
zap.Binary("data", message.Data),
zap.Binary("from", message.From),
zap.Binary("signature", message.Signature),
)
msg := &protobufs.Message{}
if err := proto.Unmarshal(message.Data, msg); err != nil {
return errors.Wrap(err, "handle message")
}
any := &anypb.Any{}
if err := proto.Unmarshal(msg.Payload, any); err != nil {
return errors.Wrap(err, "handle message")
}
eg := errgroup.Group{}
eg.SetLimit(len(e.executionEngines))
for name := range e.executionEngines {
name := name
eg.Go(func() error {
applications := e.executionEngines[name].GetSupportedApplications()
for _, application := range applications {
if bytes.Equal(msg.Address, application.Address) {
messages, err := e.executionEngines[name].ProcessMessage(
msg.Address,
msg,
)
if err != nil {
e.logger.Error(
"could not process message for engine",
zap.Error(err),
zap.String("engine_name", name),
)
return errors.Wrap(err, "handle message")
}
for _, m := range messages {
if err := e.publishMessage(e.filter, m); err != nil {
e.logger.Error(
"could not publish message for engine",
zap.Error(err),
zap.String("engine_name", name),
)
return errors.Wrap(err, "handle message")
}
}
}
}
return nil
})
}
if err := eg.Wait(); err != nil {
e.logger.Error("rejecting invalid message", zap.Error(err))
return errors.Wrap(err, "execution failed")
}
switch any.TypeUrl {
case protobufs.ClockFrameType:
if err := e.handleClockFrameData(
message.From,
any,
); err != nil {
return errors.Wrap(err, "handle message")
}
}
return nil
}
func (e *MasterClockConsensusEngine) handleClockFrameData(
peerID []byte,
any *anypb.Any,
) error {
frame := &protobufs.ClockFrame{}
if err := any.UnmarshalTo(frame); err != nil {
return errors.Wrap(err, "handle clock frame data")
}
if e.frame > frame.FrameNumber {
e.logger.Info(
"received anachronistic frame",
zap.Binary("sender", peerID),
zap.Binary("filter", frame.Filter),
zap.Uint64("frame_number", frame.FrameNumber),
zap.Int("proof_count", len(frame.AggregateProofs)),
)
return nil
}
if e.difficulty != frame.Difficulty {
e.logger.Info(
"frame difficulty mismatched",
zap.Uint32("difficulty", frame.Difficulty),
)
return nil
}
e.logger.Info(
"got clock frame",
zap.Binary("sender", peerID),
zap.Binary("filter", frame.Filter),
zap.Uint64("frame_number", frame.FrameNumber),
zap.Int("proof_count", len(frame.AggregateProofs)),
)
if err := frame.VerifyMasterClockFrame(); err != nil {
e.logger.Error("could not verify clock frame", zap.Error(err))
return errors.Wrap(err, "handle clock frame data")
}
if e.frame < frame.FrameNumber {
if err := e.enqueueSeenFrame(frame); err != nil {
e.logger.Error("could not enqueue seen clock frame", zap.Error(err))
return errors.Wrap(err, "handle clock frame data")
}
}
return nil
}
func (e *MasterClockConsensusEngine) enqueueSeenFrame(
frame *protobufs.ClockFrame,
) error {
e.seenFramesMx.Lock()
found := false
for _, f := range e.seenFrames {
if f.FrameNumber == frame.FrameNumber &&
bytes.Equal(f.Input, frame.Input) &&
f.Difficulty == frame.Difficulty &&
bytes.Equal(f.Output, frame.Output) {
found = true
}
}
if !found {
e.logger.Info(
"enqueuing frame for consensus",
zap.Uint64("frame_number", frame.FrameNumber),
)
e.seenFrames = append(e.seenFrames, frame)
e.lastFrameReceivedAt = time.Now().UTC()
}
e.seenFramesMx.Unlock()
return nil
}
func (e *MasterClockConsensusEngine) publishProof(
frame *protobufs.ClockFrame,
) error {
if e.state == consensus.EngineStatePublishing {
e.logger.Info(
"publishing frame",
zap.Uint64("frame_number", frame.FrameNumber),
)
e.enqueueSeenFrame(frame)
if err := e.publishMessage(e.filter, frame); err != nil {
return errors.Wrap(
err,
"publish proof",
)
}
e.state = consensus.EngineStateCollecting
}
return nil
}
func (e *MasterClockConsensusEngine) publishMessage(
filter []byte,
message proto.Message,
) error {
any := &anypb.Any{}
if err := any.MarshalFrom(message); err != nil {
return errors.Wrap(err, "publish message")
}
// annoying protobuf any hack
any.TypeUrl = strings.Replace(
any.TypeUrl,
"type.googleapis.com",
"types.quilibrium.com",
1,
)
payload, err := proto.Marshal(any)
if err != nil {
return errors.Wrap(err, "publish message")
}
h, err := poseidon.HashBytes(payload)
if err != nil {
return errors.Wrap(err, "publish message")
}
msg := &protobufs.Message{
Hash: h.Bytes(),
Address: e.filter,
Payload: payload,
}
data, err := proto.Marshal(msg)
if err != nil {
return errors.Wrap(err, "publish message")
}
return e.pubSub.PublishToBitmask(filter, data)
}

View File

@ -0,0 +1,248 @@
package master
import (
"bytes"
"encoding/binary"
"sort"
"strings"
"time"
"github.com/pkg/errors"
"go.uber.org/zap"
"golang.org/x/crypto/sha3"
"source.quilibrium.com/quilibrium/monorepo/go-libp2p-blossomsub/pb"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/vdf"
"source.quilibrium.com/quilibrium/monorepo/node/consensus"
"source.quilibrium.com/quilibrium/monorepo/node/p2p"
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
)
func (e *MasterClockConsensusEngine) prove(
previousFrame *protobufs.ClockFrame,
) (*protobufs.ClockFrame, error) {
if e.state == consensus.EngineStateProving {
e.logger.Info("proving new frame")
frame, err := protobufs.ProveMasterClockFrame(
previousFrame,
e.difficulty,
)
if err != nil {
return nil, errors.Wrap(err, "prove")
}
e.state = consensus.EngineStatePublishing
e.logger.Info("returning new proven frame")
return frame, nil
}
return nil, nil
}
func (e *MasterClockConsensusEngine) setFrame(frame *protobufs.ClockFrame) {
previousSelectorBytes := [516]byte{}
copy(previousSelectorBytes[:], frame.Output[:516])
e.logger.Info("set frame", zap.Uint64("frame_number", frame.FrameNumber))
e.frame = frame.FrameNumber
e.latestFrame = frame
go func() {
e.frameChan <- e.frame
}()
}
func (
e *MasterClockConsensusEngine,
) createGenesisFrame() *protobufs.ClockFrame {
e.logger.Info("creating genesis frame")
for _, l := range strings.Split(string(e.input), "\n") {
e.logger.Info(l)
}
b := sha3.Sum256(e.input)
v := vdf.New(e.difficulty, b)
v.Execute()
o := v.GetOutput()
inputMessage := o[:]
e.logger.Info("proving genesis frame")
input := []byte{}
input = append(input, e.filter...)
input = binary.BigEndian.AppendUint64(input, e.frame)
input = binary.BigEndian.AppendUint32(input, e.difficulty)
if bytes.Equal(e.input, []byte{0x00}) {
value := [516]byte{}
input = append(input, value[:]...)
} else {
input = append(input, e.input...)
}
b = sha3.Sum256(input)
v = vdf.New(e.difficulty, b)
v.Execute()
o = v.GetOutput()
frame := &protobufs.ClockFrame{
Filter: e.filter,
FrameNumber: e.frame,
Timestamp: 0,
Difficulty: e.difficulty,
Input: inputMessage,
Output: o[:],
ParentSelector: []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
AggregateProofs: []*protobufs.InclusionAggregateProof{},
PublicKeySignature: nil,
}
e.setFrame(frame)
return frame
}
func (e *MasterClockConsensusEngine) collect(
currentFramePublished *protobufs.ClockFrame,
) (*protobufs.ClockFrame, error) {
if e.state == consensus.EngineStateCollecting {
e.logger.Info("collecting vdf proofs")
latest := e.latestFrame
if e.syncingStatus == SyncStatusNotSyncing {
peer, err := e.pubSub.GetRandomPeer(e.filter)
if err != nil {
if errors.Is(err, p2p.ErrNoPeersAvailable) {
e.logger.Warn("no peers available, skipping sync")
} else {
e.logger.Error("error while fetching random peer", zap.Error(err))
}
} else {
e.syncingStatus = SyncStatusAwaitingResponse
e.logger.Info("setting syncing target", zap.Binary("peer_id", peer))
e.syncingTarget = peer
channel := e.createPeerReceiveChannel(peer)
e.logger.Info(
"listening on peer receive channel",
zap.Binary("channel", channel),
)
e.pubSub.Subscribe(channel, e.handleSync, true)
e.pubSub.Subscribe(
peer,
func(message *pb.Message) error { return nil },
true,
)
go func() {
time.Sleep(2 * time.Second)
if err := e.publishMessage(peer, &protobufs.ClockFramesRequest{
Filter: e.filter,
FromFrameNumber: latest.FrameNumber + 1,
}); err != nil {
e.logger.Error(
"could not publish clock frame request",
zap.Error(err),
)
}
}()
}
}
waitDecay := time.Duration(2000)
for e.syncingStatus != SyncStatusNotSyncing {
e.logger.Info(
"waiting for sync to complete...",
zap.Duration("wait_decay", waitDecay),
)
time.Sleep(waitDecay * time.Millisecond)
waitDecay = waitDecay * 2
if waitDecay >= (100 * (2 << 6)) {
if e.syncingStatus == SyncStatusAwaitingResponse {
e.logger.Info("maximum wait for sync response, skipping sync")
e.syncingStatus = SyncStatusNotSyncing
break
} else {
waitDecay = 100 * (2 << 6)
}
}
}
e.logger.Info("selecting leader")
latestFrame, err := e.confirmLatestFrame()
if err != nil {
e.logger.Error("could not confirm latest frame", zap.Error(err))
return nil, errors.Wrap(err, "collect")
}
e.logger.Info(
"returning leader frame",
zap.Uint64("frame_number", latestFrame.FrameNumber),
)
e.state = consensus.EngineStateProving
return latestFrame, nil
}
return nil, nil
}
func (
e *MasterClockConsensusEngine,
) confirmLatestFrame() (*protobufs.ClockFrame, error) {
e.seenFramesMx.Lock()
defer e.seenFramesMx.Unlock()
sort.Slice(e.seenFrames, func(i, j int) bool {
return e.seenFrames[i].FrameNumber < e.seenFrames[j].FrameNumber
})
if len(e.seenFrames) == 0 {
return e.latestFrame, nil
}
prev := e.latestFrame
committedSet := []*protobufs.ClockFrame{}
for len(e.seenFrames) > 0 {
curr := e.seenFrames[0]
e.seenFrames = e.seenFrames[1:]
e.logger.Info(
"checking continuity for frame",
zap.Uint64("frame_number", curr.FrameNumber),
)
if prev.FrameNumber+1 < curr.FrameNumber ||
prev.FrameNumber > curr.FrameNumber {
e.logger.Info(
"continuity break found",
zap.Uint64("prev_frame_number", prev.FrameNumber),
zap.Uint64("curr_frame_number", curr.FrameNumber),
)
break
}
if bytes.Equal(prev.Output, curr.Input[:516]) {
prev = curr
committedSet = append(committedSet, prev)
} else {
e.logger.Info("frame mismatch on input/output")
}
}
e.historicFramesMx.Lock()
e.historicFrames = append(e.historicFrames, committedSet...)
e.historicFramesMx.Unlock()
e.setFrame(prev)
return prev, nil
}

View File

@ -0,0 +1,109 @@
package master
import (
"github.com/pkg/errors"
"go.uber.org/zap"
"source.quilibrium.com/quilibrium/monorepo/node/execution"
)
func (e *MasterClockConsensusEngine) RegisterExecutor(
exec execution.ExecutionEngine,
frame uint64,
) <-chan error {
logger := e.logger.With(zap.String("execution_engine_name", exec.GetName()))
logger.Info("registering execution engine")
errChan := make(chan error)
go func() {
logger.Info(
"starting execution engine at frame",
zap.Uint64("current_frame", e.frame),
)
err := <-exec.Start()
if err != nil {
logger.Error("could not start execution engine", zap.Error(err))
errChan <- err
return
}
for {
logger.Info(
"awaiting frame",
zap.Uint64("current_frame", e.frame),
zap.Uint64("target_frame", frame),
)
newFrame := e.frame
if newFrame >= frame {
logger.Info(
"injecting execution engine at frame",
zap.Uint64("current_frame", newFrame),
)
e.engineMx.Lock()
e.executionEngines[exec.GetName()] = exec
e.engineMx.Unlock()
errChan <- nil
break
}
}
}()
return errChan
}
func (e *MasterClockConsensusEngine) UnregisterExecutor(
name string,
frame uint64,
force bool,
) <-chan error {
logger := e.logger.With(zap.String("execution_engine_name", name))
logger.Info("unregistering execution engine")
errChan := make(chan error)
exec, ok := e.executionEngines[name]
if !ok {
logger.Error(
"could not unregister execution engine",
zap.Error(errors.New("execution engine not registered")),
)
errChan <- errors.New("execution engine not registered")
return errChan
}
go func() {
for {
logger.Info(
"awaiting frame",
zap.Uint64("current_frame", e.frame),
zap.Uint64("target_frame", frame),
)
newFrame := e.frame
if newFrame >= frame {
logger.Info(
"removing execution engine at frame",
zap.Uint64("current_frame", newFrame),
)
e.engineMx.Lock()
delete(e.executionEngines, name)
e.engineMx.Unlock()
logger.Info(
"stopping execution engine at frame",
zap.Uint64("current_frame", newFrame),
)
err := <-exec.Stop(force)
if err != nil {
logger.Error("could not stop execution engine", zap.Error(err))
}
errChan <- err
break
}
}
}()
return errChan
}

View File

@ -0,0 +1,195 @@
package master
import (
"encoding/hex"
"sync"
"time"
"github.com/pkg/errors"
"go.uber.org/zap"
"source.quilibrium.com/quilibrium/monorepo/node/config"
"source.quilibrium.com/quilibrium/monorepo/node/consensus"
"source.quilibrium.com/quilibrium/monorepo/node/execution"
"source.quilibrium.com/quilibrium/monorepo/node/keys"
"source.quilibrium.com/quilibrium/monorepo/node/p2p"
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
)
type SyncStatusType int
const (
SyncStatusNotSyncing = iota
SyncStatusAwaitingResponse
SyncStatusSynchronizing
)
type MasterClockConsensusEngine struct {
frame uint64
difficulty uint32
logger *zap.Logger
state consensus.EngineState
pubSub p2p.PubSub
keyManager keys.KeyManager
lastFrameReceivedAt time.Time
latestFrame *protobufs.ClockFrame
frameChan chan uint64
executionEngines map[string]execution.ExecutionEngine
filter []byte
input []byte
syncingStatus SyncStatusType
syncingTarget []byte
engineMx sync.Mutex
seenFramesMx sync.Mutex
historicFramesMx sync.Mutex
// for DHT testing, we're only using in memory stores
seenFrames []*protobufs.ClockFrame
historicFrames []*protobufs.ClockFrame
}
var _ consensus.ConsensusEngine = (*MasterClockConsensusEngine)(nil)
func NewMasterClockConsensusEngine(
engineConfig *config.EngineConfig,
logger *zap.Logger,
keyManager keys.KeyManager,
pubSub p2p.PubSub,
) *MasterClockConsensusEngine {
if logger == nil {
panic(errors.New("logger is nil"))
}
if engineConfig == nil {
panic(errors.New("engine config is nil"))
}
if keyManager == nil {
panic(errors.New("key manager is nil"))
}
if pubSub == nil {
panic(errors.New("pubsub is nil"))
}
seed, err := hex.DecodeString(engineConfig.GenesisSeed)
if err != nil {
panic(errors.New("genesis seed is nil"))
}
e := &MasterClockConsensusEngine{
frame: 0,
difficulty: 10000,
logger: logger,
state: consensus.EngineStateStopped,
keyManager: keyManager,
pubSub: pubSub,
frameChan: make(chan uint64),
executionEngines: map[string]execution.ExecutionEngine{},
input: seed,
lastFrameReceivedAt: time.Time{},
syncingStatus: SyncStatusNotSyncing,
}
if e.filter, err = hex.DecodeString(engineConfig.Filter); err != nil {
panic(errors.Wrap(err, "could not parse filter value"))
}
logger.Info("constructing consensus engine")
return e
}
func (e *MasterClockConsensusEngine) Start() <-chan error {
e.logger.Info("starting consensus engine")
e.state = consensus.EngineStateStarting
errChan := make(chan error)
e.state = consensus.EngineStateLoading
e.logger.Info("syncing last seen state")
latestFrame := e.createGenesisFrame()
e.historicFrames = []*protobufs.ClockFrame{latestFrame}
e.logger.Info("subscribing to pubsub messages")
e.pubSub.Subscribe(e.filter, e.handleMessage, true)
e.pubSub.Subscribe(e.pubSub.GetPeerID(), e.handleSync, true)
e.state = consensus.EngineStateCollecting
go func() {
for e.state < consensus.EngineStateStopping {
var err error
switch e.state {
case consensus.EngineStateCollecting:
if latestFrame, err = e.collect(latestFrame); err != nil {
e.logger.Error("could not collect", zap.Error(err))
errChan <- err
}
case consensus.EngineStateProving:
if latestFrame, err = e.prove(latestFrame); err != nil {
e.logger.Error("could not prove", zap.Error(err))
errChan <- err
}
case consensus.EngineStatePublishing:
if err = e.publishProof(latestFrame); err != nil {
e.logger.Error("could not publish", zap.Error(err))
errChan <- err
}
}
}
}()
go func() {
errChan <- nil
}()
return errChan
}
func (e *MasterClockConsensusEngine) Stop(force bool) <-chan error {
e.logger.Info("stopping consensus engine")
e.state = consensus.EngineStateStopping
errChan := make(chan error)
wg := sync.WaitGroup{}
wg.Add(len(e.executionEngines))
for name := range e.executionEngines {
name := name
go func(name string) {
err := <-e.UnregisterExecutor(name, e.frame, force)
if err != nil {
errChan <- err
}
wg.Done()
}(name)
}
e.logger.Info("waiting for execution engines to stop")
wg.Wait()
e.logger.Info("execution engines stopped")
e.state = consensus.EngineStateStopped
e.engineMx.Lock()
defer e.engineMx.Unlock()
go func() {
errChan <- nil
}()
return errChan
}
func (e *MasterClockConsensusEngine) GetDifficulty() uint32 {
return e.difficulty
}
func (e *MasterClockConsensusEngine) GetFrame() uint64 {
return e.frame
}
func (e *MasterClockConsensusEngine) GetState() consensus.EngineState {
return e.state
}
func (e *MasterClockConsensusEngine) GetFrameChannel() <-chan uint64 {
return e.frameChan
}

View File

@ -0,0 +1,238 @@
package master
import (
"bytes"
"github.com/pkg/errors"
"go.uber.org/zap"
"golang.org/x/sync/errgroup"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
"source.quilibrium.com/quilibrium/monorepo/go-libp2p-blossomsub/pb"
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
)
func (e *MasterClockConsensusEngine) handleSync(message *pb.Message) error {
e.logger.Debug(
"received peer message",
zap.Binary("data", message.Data),
zap.Binary("from", message.From),
zap.Binary("signature", message.Signature),
)
msg := &protobufs.Message{}
if err := proto.Unmarshal(message.Data, msg); err != nil {
return errors.Wrap(err, "handle sync")
}
any := &anypb.Any{}
if err := proto.Unmarshal(msg.Payload, any); err != nil {
return errors.Wrap(err, "handle sync")
}
eg := errgroup.Group{}
eg.SetLimit(len(e.executionEngines))
for name := range e.executionEngines {
name := name
eg.Go(func() error {
applications := e.executionEngines[name].GetSupportedApplications()
for _, application := range applications {
if bytes.Equal(msg.Address, application.Address) {
messages, err := e.executionEngines[name].ProcessMessage(
msg.Address,
msg,
)
if err != nil {
e.logger.Error(
"could not process message for engine",
zap.Error(err),
zap.String("engine_name", name),
)
return errors.Wrap(err, "handle message")
}
for _, m := range messages {
if err := e.publishMessage(e.filter, m); err != nil {
e.logger.Error(
"could not publish message for engine",
zap.Error(err),
zap.String("engine_name", name),
)
return errors.Wrap(err, "handle message")
}
}
}
}
return nil
})
}
if err := eg.Wait(); err != nil {
e.logger.Error("rejecting invalid message", zap.Error(err))
return errors.Wrap(err, "handle sync")
}
switch any.TypeUrl {
case protobufs.ClockFramesResponseType:
if err := e.handleClockFramesResponse(
message.From,
any,
); err != nil {
return errors.Wrap(err, "handle sync")
}
case protobufs.ClockFramesRequestType:
if err := e.handleClockFramesRequest(
message.From,
any,
); err != nil {
return errors.Wrap(err, "handle sync")
}
}
return nil
}
func (e *MasterClockConsensusEngine) createPeerReceiveChannel(
peerID []byte,
) []byte {
return append(append([]byte{}, peerID...), e.pubSub.GetPeerID()...)
}
func (e *MasterClockConsensusEngine) createPeerSendChannel(
peerID []byte,
) []byte {
return append(append([]byte{}, e.pubSub.GetPeerID()...), peerID...)
}
func (e *MasterClockConsensusEngine) handleClockFramesResponse(
peerID []byte,
any *anypb.Any,
) error {
if bytes.Equal(peerID, e.pubSub.GetPeerID()) {
return nil
}
if !bytes.Equal(peerID, e.syncingTarget) {
e.logger.Warn(
"received clock frames response from unexpected target",
zap.Binary("peer_id", peerID),
zap.Binary("expected_peer_id", e.syncingTarget),
)
return nil
}
e.syncingStatus = SyncStatusSynchronizing
defer func() { e.syncingStatus = SyncStatusNotSyncing }()
response := &protobufs.ClockFramesResponse{}
if err := any.UnmarshalTo(response); err != nil {
return errors.Wrap(err, "handle clock frames response")
}
for _, frame := range response.ClockFrames {
e.logger.Info(
"processing clock frame",
zap.Binary("sender", peerID),
zap.Binary("filter", frame.Filter),
zap.Uint64("frame_number", frame.FrameNumber),
)
if err := frame.VerifyMasterClockFrame(); err != nil {
e.logger.Error("could not verify clock frame", zap.Error(err))
return errors.Wrap(err, "handle clock frame response")
}
e.logger.Info(
"clock frame was valid",
zap.Binary("sender", peerID),
zap.Binary("filter", frame.Filter),
zap.Uint64("frame_number", frame.FrameNumber),
)
if e.frame < frame.FrameNumber {
if err := e.enqueueSeenFrame(frame); err != nil {
e.logger.Error("could not enqueue seen clock frame", zap.Error(err))
return errors.Wrap(err, "handle clock frame response")
}
}
}
return nil
}
func (e *MasterClockConsensusEngine) handleClockFramesRequest(
peerID []byte,
any *anypb.Any,
) error {
if bytes.Equal(peerID, e.pubSub.GetPeerID()) {
return nil
}
request := &protobufs.ClockFramesRequest{}
if err := any.UnmarshalTo(request); err != nil {
return errors.Wrap(err, "handle clock frame request")
}
channel := e.createPeerSendChannel(peerID)
e.pubSub.Subscribe(channel, e.handleSync, true)
e.logger.Info(
"received clock frame request",
zap.Binary("peer_id", peerID),
zap.Uint64("from_frame_number", request.FromFrameNumber),
zap.Uint64("to_frame_number", request.ToFrameNumber),
)
from := request.FromFrameNumber
if e.frame < from || len(e.historicFrames) == 0 {
e.logger.Info(
"peer asked for undiscovered frame",
zap.Binary("peer_id", peerID),
zap.Uint64("frame_number", request.FromFrameNumber),
)
if err := e.publishMessage(channel, &protobufs.ClockFramesResponse{
Filter: request.Filter,
FromFrameNumber: 0,
ToFrameNumber: 0,
ClockFrames: []*protobufs.ClockFrame{},
}); err != nil {
return errors.Wrap(err, "handle clock frame request")
}
return nil
}
to := request.ToFrameNumber
if to == 0 || to-request.FromFrameNumber > 128 {
to = request.FromFrameNumber + 127
}
if int(to) > len(e.historicFrames)-1 {
to = uint64(len(e.historicFrames) - 1)
}
e.logger.Info(
"sending response",
zap.Binary("peer_id", peerID),
zap.Uint64("from", from),
zap.Uint64("to", to),
zap.Uint64("total_frames", uint64(to-from+1)),
)
if err := e.publishMessage(channel, &protobufs.ClockFramesResponse{
Filter: request.Filter,
FromFrameNumber: request.FromFrameNumber,
ToFrameNumber: to,
ClockFrames: e.historicFrames[from:to],
}); err != nil {
return errors.Wrap(err, "handle clock frame request")
}
return nil
}

View File

@ -1,452 +1,450 @@
package crypto
// Uncomment with full release
import (
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
"crypto/rand"
"crypto/sha512"
"crypto/subtle"
"encoding/binary"
// import (
// "crypto/aes"
// "crypto/cipher"
// "crypto/hmac"
// "crypto/rand"
// "crypto/sha512"
// "crypto/subtle"
// "encoding/binary"
"github.com/pkg/errors"
"golang.org/x/crypto/hkdf"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves"
"source.quilibrium.com/quilibrium/monorepo/node/keys"
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
)
// "github.com/pkg/errors"
// "golang.org/x/crypto/hkdf"
// "source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves"
// "source.quilibrium.com/quilibrium/monorepo/node/keys"
// "source.quilibrium.com/quilibrium/monorepo/node/protobufs"
// )
const PROTOCOL_VERSION = 1
const PROTOCOL = 1<<8 + PROTOCOL_VERSION
// const PROTOCOL_VERSION = 1
// const PROTOCOL = 1<<8 + PROTOCOL_VERSION
const CHAIN_KEY = 0x01
const MESSAGE_KEY = 0x02
const AEAD_KEY = 0x03
// const CHAIN_KEY = 0x01
// const MESSAGE_KEY = 0x02
// const AEAD_KEY = 0x03
// Note: If an HSM with raw primitive access becomes available, the raw crypto
// mechanisms should be refactored into calls in KeyManager and implemented
// through the driver
type DoubleRatchetParticipant struct {
sendingEphemeralPrivateKey curves.Scalar
receivingEphemeralKey curves.Point
curve curves.Curve
keyManager keys.KeyManager
rootKey []byte
sendingChainKey []byte
currentSendingHeaderKey []byte
currentReceivingHeaderKey []byte
nextSendingHeaderKey []byte
nextReceivingHeaderKey []byte
receivingChainKey []byte
currentSendingChainLength uint32
previousSendingChainLength uint32
currentReceivingChainLength uint32
previousReceivingChainLength uint32
skippedKeysMap map[string]map[uint32][]byte
}
// // Note: If an HSM with raw primitive access becomes available, the raw crypto
// // mechanisms should be refactored into calls in KeyManager and implemented
// // through the driver
// type DoubleRatchetParticipant struct {
// sendingEphemeralPrivateKey curves.Scalar
// receivingEphemeralKey curves.Point
// curve curves.Curve
// keyManager keys.KeyManager
// rootKey []byte
// sendingChainKey []byte
// currentSendingHeaderKey []byte
// currentReceivingHeaderKey []byte
// nextSendingHeaderKey []byte
// nextReceivingHeaderKey []byte
// receivingChainKey []byte
// currentSendingChainLength uint32
// previousSendingChainLength uint32
// currentReceivingChainLength uint32
// previousReceivingChainLength uint32
// skippedKeysMap map[string]map[uint32][]byte
// }
func NewDoubleRatchetParticipant(
sessionKey []byte,
sendingHeaderKey []byte,
nextReceivingHeaderKey []byte,
isSender bool,
sendingEphemeralPrivateKey curves.Scalar,
receivingEphemeralKey curves.Point,
curve curves.Curve,
keyManager keys.KeyManager,
) (*DoubleRatchetParticipant, error) {
participant := &DoubleRatchetParticipant{}
participant.sendingEphemeralPrivateKey = sendingEphemeralPrivateKey
participant.skippedKeysMap = make(map[string]map[uint32][]byte)
participant.keyManager = keyManager
participant.currentSendingChainLength = 0
participant.previousSendingChainLength = 0
participant.currentReceivingChainLength = 0
participant.previousReceivingChainLength = 0
// func NewDoubleRatchetParticipant(
// sessionKey []byte,
// sendingHeaderKey []byte,
// nextReceivingHeaderKey []byte,
// isSender bool,
// sendingEphemeralPrivateKey curves.Scalar,
// receivingEphemeralKey curves.Point,
// curve curves.Curve,
// keyManager keys.KeyManager,
// ) (*DoubleRatchetParticipant, error) {
// participant := &DoubleRatchetParticipant{}
// participant.sendingEphemeralPrivateKey = sendingEphemeralPrivateKey
// participant.skippedKeysMap = make(map[string]map[uint32][]byte)
// participant.keyManager = keyManager
// participant.currentSendingChainLength = 0
// participant.previousSendingChainLength = 0
// participant.currentReceivingChainLength = 0
// participant.previousReceivingChainLength = 0
if sendingEphemeralPrivateKey.Point().CurveName() !=
receivingEphemeralKey.CurveName() || receivingEphemeralKey.CurveName() !=
curve.Name {
return nil, errors.New("curve mismatch")
}
// if sendingEphemeralPrivateKey.Point().CurveName() !=
// receivingEphemeralKey.CurveName() || receivingEphemeralKey.CurveName() !=
// curve.Name {
// return nil, errors.New("curve mismatch")
// }
participant.curve = curve
// participant.curve = curve
if isSender {
hash := hkdf.New(
sha512.New,
receivingEphemeralKey.Mul(
sendingEphemeralPrivateKey,
).ToAffineCompressed(),
sessionKey,
[]byte("quilibrium-double-ratchet"),
)
rkck := make([]byte, 96)
if _, err := hash.Read(rkck[:]); err != nil {
return nil, errors.Wrap(err, "failed establishing root key")
}
// if isSender {
// hash := hkdf.New(
// sha512.New,
// receivingEphemeralKey.Mul(
// sendingEphemeralPrivateKey,
// ).ToAffineCompressed(),
// sessionKey,
// []byte("quilibrium-double-ratchet"),
// )
// rkck := make([]byte, 96)
// if _, err := hash.Read(rkck[:]); err != nil {
// return nil, errors.Wrap(err, "failed establishing root key")
// }
participant.currentSendingHeaderKey = sendingHeaderKey
participant.nextReceivingHeaderKey = nextReceivingHeaderKey
participant.rootKey = rkck[:32]
participant.sendingChainKey = rkck[32:64]
// participant.currentSendingHeaderKey = sendingHeaderKey
// participant.nextReceivingHeaderKey = nextReceivingHeaderKey
// participant.rootKey = rkck[:32]
// participant.sendingChainKey = rkck[32:64]
participant.nextSendingHeaderKey = rkck[64:96]
participant.receivingEphemeralKey = receivingEphemeralKey
} else {
participant.rootKey = sessionKey
participant.nextReceivingHeaderKey = sendingHeaderKey
participant.nextSendingHeaderKey = nextReceivingHeaderKey
}
// participant.nextSendingHeaderKey = rkck[64:96]
// participant.receivingEphemeralKey = receivingEphemeralKey
// } else {
// participant.rootKey = sessionKey
// participant.nextReceivingHeaderKey = sendingHeaderKey
// participant.nextSendingHeaderKey = nextReceivingHeaderKey
// }
return participant, nil
}
// return participant, nil
// }
func (r *DoubleRatchetParticipant) RatchetEncrypt(
message []byte,
) (*protobufs.P2PChannelEnvelope, error) {
envelope := &protobufs.P2PChannelEnvelope{
ProtocolIdentifier: PROTOCOL,
MessageHeader: &protobufs.MessageCiphertext{},
MessageBody: &protobufs.MessageCiphertext{},
}
// func (r *DoubleRatchetParticipant) RatchetEncrypt(
// message []byte,
// ) (*protobufs.P2PChannelEnvelope, error) {
// envelope := &protobufs.P2PChannelEnvelope{
// ProtocolIdentifier: PROTOCOL,
// MessageHeader: &protobufs.MessageCiphertext{},
// MessageBody: &protobufs.MessageCiphertext{},
// }
newChainKey, messageKey, aeadKey := ratchetKeys(r.sendingChainKey)
r.sendingChainKey = newChainKey
// newChainKey, messageKey, aeadKey := ratchetKeys(r.sendingChainKey)
// r.sendingChainKey = newChainKey
var err error
header := r.encodeHeader()
envelope.MessageHeader, err = r.encrypt(
header,
r.currentSendingHeaderKey,
nil,
)
if err != nil {
return nil, errors.Wrap(err, "could not encrypt header")
}
// var err error
// header := r.encodeHeader()
// envelope.MessageHeader, err = r.encrypt(
// header,
// r.currentSendingHeaderKey,
// nil,
// )
// if err != nil {
// return nil, errors.Wrap(err, "could not encrypt header")
// }
envelope.MessageBody, err = r.encrypt(
message,
messageKey,
append(append([]byte{}, aeadKey...), envelope.MessageHeader.Ciphertext...),
)
if err != nil {
return nil, errors.Wrap(err, "could not encrypt message")
}
// envelope.MessageBody, err = r.encrypt(
// message,
// messageKey,
// append(append([]byte{}, aeadKey...), envelope.MessageHeader.Ciphertext...),
// )
// if err != nil {
// return nil, errors.Wrap(err, "could not encrypt message")
// }
r.currentSendingChainLength++
// r.currentSendingChainLength++
return envelope, nil
}
// return envelope, nil
// }
func (r *DoubleRatchetParticipant) RatchetDecrypt(
envelope *protobufs.P2PChannelEnvelope,
) ([]byte, error) {
plaintext, err := r.trySkippedMessageKeys(envelope)
if err != nil {
return nil, errors.Wrap(err, "could not decrypt from matching skipped key")
}
// func (r *DoubleRatchetParticipant) RatchetDecrypt(
// envelope *protobufs.P2PChannelEnvelope,
// ) ([]byte, error) {
// plaintext, err := r.trySkippedMessageKeys(envelope)
// if err != nil {
// return nil, errors.Wrap(err, "could not decrypt from matching skipped key")
// }
if plaintext != nil {
return plaintext, nil
}
// if plaintext != nil {
// return plaintext, nil
// }
header, shouldRatchet, err := r.decryptHeader(
envelope.MessageHeader,
r.currentReceivingHeaderKey,
)
if err != nil {
return nil, errors.Wrap(err, "could not decrypt header")
}
// header, shouldRatchet, err := r.decryptHeader(
// envelope.MessageHeader,
// r.currentReceivingHeaderKey,
// )
// if err != nil {
// return nil, errors.Wrap(err, "could not decrypt header")
// }
receivingEphemeralKey,
previousReceivingChainLength,
currentReceivingChainLength,
err := r.decodeHeader(header)
if err != nil {
return nil, errors.Wrap(err, "could not decode header")
}
// receivingEphemeralKey,
// previousReceivingChainLength,
// currentReceivingChainLength,
// err := r.decodeHeader(header)
// if err != nil {
// return nil, errors.Wrap(err, "could not decode header")
// }
if shouldRatchet {
if err := r.skipMessageKeys(previousReceivingChainLength); err != nil {
return nil, errors.Wrap(err, "could not skip previous message keys")
}
if err := r.ratchetEphemeralKeys(receivingEphemeralKey); err != nil {
return nil, errors.Wrap(err, "could not ratchet ephemeral keys")
}
}
// if shouldRatchet {
// if err := r.skipMessageKeys(previousReceivingChainLength); err != nil {
// return nil, errors.Wrap(err, "could not skip previous message keys")
// }
// if err := r.ratchetEphemeralKeys(receivingEphemeralKey); err != nil {
// return nil, errors.Wrap(err, "could not ratchet ephemeral keys")
// }
// }
if err := r.skipMessageKeys(currentReceivingChainLength); err != nil {
return nil, errors.Wrap(err, "could not skip message keys")
}
// if err := r.skipMessageKeys(currentReceivingChainLength); err != nil {
// return nil, errors.Wrap(err, "could not skip message keys")
// }
newChainKey, messageKey, aeadKey := ratchetKeys(r.receivingChainKey)
r.receivingChainKey = newChainKey
r.currentReceivingChainLength++
// newChainKey, messageKey, aeadKey := ratchetKeys(r.receivingChainKey)
// r.receivingChainKey = newChainKey
// r.currentReceivingChainLength++
plaintext, err = r.decrypt(
envelope.MessageBody,
messageKey,
append(
append([]byte{}, aeadKey...),
envelope.MessageHeader.Ciphertext...,
),
)
// plaintext, err = r.decrypt(
// envelope.MessageBody,
// messageKey,
// append(
// append([]byte{}, aeadKey...),
// envelope.MessageHeader.Ciphertext...,
// ),
// )
return plaintext, errors.Wrap(err, "could not decrypt message")
}
// return plaintext, errors.Wrap(err, "could not decrypt message")
// }
func (r *DoubleRatchetParticipant) ratchetEphemeralKeys(
newReceivingEphemeralKey curves.Point,
) error {
r.previousSendingChainLength = r.currentSendingChainLength
r.currentSendingChainLength = 0
r.currentReceivingChainLength = 0
r.currentSendingHeaderKey = r.nextSendingHeaderKey
r.currentReceivingHeaderKey = r.nextReceivingHeaderKey
r.receivingEphemeralKey = newReceivingEphemeralKey
// func (r *DoubleRatchetParticipant) ratchetEphemeralKeys(
// newReceivingEphemeralKey curves.Point,
// ) error {
// r.previousSendingChainLength = r.currentSendingChainLength
// r.currentSendingChainLength = 0
// r.currentReceivingChainLength = 0
// r.currentSendingHeaderKey = r.nextSendingHeaderKey
// r.currentReceivingHeaderKey = r.nextReceivingHeaderKey
// r.receivingEphemeralKey = newReceivingEphemeralKey
hash := hkdf.New(
sha512.New,
newReceivingEphemeralKey.Mul(
r.sendingEphemeralPrivateKey,
).ToAffineCompressed(),
r.rootKey,
[]byte("quilibrium-double-ratchet"),
)
rkck := make([]byte, 96)
if _, err := hash.Read(rkck[:]); err != nil {
return errors.Wrap(err, "failed ratcheting root key")
}
// hash := hkdf.New(
// sha512.New,
// newReceivingEphemeralKey.Mul(
// r.sendingEphemeralPrivateKey,
// ).ToAffineCompressed(),
// r.rootKey,
// []byte("quilibrium-double-ratchet"),
// )
// rkck := make([]byte, 96)
// if _, err := hash.Read(rkck[:]); err != nil {
// return errors.Wrap(err, "failed ratcheting root key")
// }
r.rootKey = rkck[:32]
r.receivingChainKey = rkck[32:64]
r.nextReceivingHeaderKey = rkck[64:]
r.sendingEphemeralPrivateKey = r.curve.NewScalar().Random(rand.Reader)
// r.rootKey = rkck[:32]
// r.receivingChainKey = rkck[32:64]
// r.nextReceivingHeaderKey = rkck[64:]
// r.sendingEphemeralPrivateKey = r.curve.NewScalar().Random(rand.Reader)
hash = hkdf.New(
sha512.New,
newReceivingEphemeralKey.Mul(
r.sendingEphemeralPrivateKey,
).ToAffineCompressed(),
r.rootKey,
[]byte("quilibrium-double-ratchet"),
)
rkck2 := make([]byte, 96)
if _, err := hash.Read(rkck2[:]); err != nil {
return errors.Wrap(err, "failed ratcheting root key")
}
// hash = hkdf.New(
// sha512.New,
// newReceivingEphemeralKey.Mul(
// r.sendingEphemeralPrivateKey,
// ).ToAffineCompressed(),
// r.rootKey,
// []byte("quilibrium-double-ratchet"),
// )
// rkck2 := make([]byte, 96)
// if _, err := hash.Read(rkck2[:]); err != nil {
// return errors.Wrap(err, "failed ratcheting root key")
// }
r.rootKey = rkck2[:32]
r.sendingChainKey = rkck2[32:64]
r.nextSendingHeaderKey = rkck2[64:]
return nil
}
// r.rootKey = rkck2[:32]
// r.sendingChainKey = rkck2[32:64]
// r.nextSendingHeaderKey = rkck2[64:]
// return nil
// }
func (r *DoubleRatchetParticipant) trySkippedMessageKeys(
envelope *protobufs.P2PChannelEnvelope,
) ([]byte, error) {
for receivingHeaderKey, skippedKeys := range r.skippedKeysMap {
header, _, err := r.decryptHeader(
envelope.MessageHeader,
[]byte(receivingHeaderKey),
)
// func (r *DoubleRatchetParticipant) trySkippedMessageKeys(
// envelope *protobufs.P2PChannelEnvelope,
// ) ([]byte, error) {
// for receivingHeaderKey, skippedKeys := range r.skippedKeysMap {
// header, _, err := r.decryptHeader(
// envelope.MessageHeader,
// []byte(receivingHeaderKey),
// )
if err == nil {
_, _, current, err := r.decodeHeader(header)
if err != nil {
return nil, errors.Wrap(err, "malformed header")
}
// if err == nil {
// _, _, current, err := r.decodeHeader(header)
// if err != nil {
// return nil, errors.Wrap(err, "malformed header")
// }
messageKey := skippedKeys[current][:32]
aeadKey := skippedKeys[current][32:]
plaintext, err := r.decrypt(
envelope.MessageBody,
messageKey,
append(
append([]byte{}, aeadKey...),
envelope.MessageHeader.Ciphertext[:]...,
),
)
// messageKey := skippedKeys[current][:32]
// aeadKey := skippedKeys[current][32:]
// plaintext, err := r.decrypt(
// envelope.MessageBody,
// messageKey,
// append(
// append([]byte{}, aeadKey...),
// envelope.MessageHeader.Ciphertext[:]...,
// ),
// )
if err != nil {
return nil, errors.Wrap(err, "could not decrypt from skipped key")
}
// if err != nil {
// return nil, errors.Wrap(err, "could not decrypt from skipped key")
// }
delete(r.skippedKeysMap[receivingHeaderKey], current)
if len(r.skippedKeysMap[receivingHeaderKey]) == 0 {
delete(r.skippedKeysMap, receivingHeaderKey)
}
// delete(r.skippedKeysMap[receivingHeaderKey], current)
// if len(r.skippedKeysMap[receivingHeaderKey]) == 0 {
// delete(r.skippedKeysMap, receivingHeaderKey)
// }
return plaintext, nil
}
}
// return plaintext, nil
// }
// }
return nil, nil
}
// return nil, nil
// }
func (r *DoubleRatchetParticipant) skipMessageKeys(until uint32) error {
if r.currentReceivingChainLength+100 < until {
return errors.New("skip limit exceeded")
}
// func (r *DoubleRatchetParticipant) skipMessageKeys(until uint32) error {
// if r.currentReceivingChainLength+100 < until {
// return errors.New("skip limit exceeded")
// }
if r.receivingChainKey != nil {
for r.currentReceivingChainLength < until {
newChainKey, messageKey, aeadKey := ratchetKeys(r.receivingChainKey)
skippedKeys := r.skippedKeysMap[string(r.currentReceivingHeaderKey)]
if skippedKeys == nil {
r.skippedKeysMap[string(r.currentReceivingHeaderKey)] =
make(map[uint32][]byte)
}
// if r.receivingChainKey != nil {
// for r.currentReceivingChainLength < until {
// newChainKey, messageKey, aeadKey := ratchetKeys(r.receivingChainKey)
// skippedKeys := r.skippedKeysMap[string(r.currentReceivingHeaderKey)]
// if skippedKeys == nil {
// r.skippedKeysMap[string(r.currentReceivingHeaderKey)] =
// make(map[uint32][]byte)
// }
skippedKeys[r.currentReceivingChainLength] = append(
append([]byte{}, messageKey...),
aeadKey...,
)
r.receivingChainKey = newChainKey
r.currentReceivingChainLength++
}
}
// skippedKeys[r.currentReceivingChainLength] = append(
// append([]byte{}, messageKey...),
// aeadKey...,
// )
// r.receivingChainKey = newChainKey
// r.currentReceivingChainLength++
// }
// }
return nil
}
// return nil
// }
func (r *DoubleRatchetParticipant) encodeHeader() []byte {
header := []byte{}
header = append(
header,
r.curve.NewGeneratorPoint().Mul(
r.sendingEphemeralPrivateKey,
).ToAffineCompressed()[:]...,
)
header = binary.BigEndian.AppendUint32(header, r.previousSendingChainLength)
header = binary.BigEndian.AppendUint32(header, r.currentSendingChainLength)
return header
}
// func (r *DoubleRatchetParticipant) encodeHeader() []byte {
// header := []byte{}
// header = append(
// header,
// r.curve.NewGeneratorPoint().Mul(
// r.sendingEphemeralPrivateKey,
// ).ToAffineCompressed()[:]...,
// )
// header = binary.BigEndian.AppendUint32(header, r.previousSendingChainLength)
// header = binary.BigEndian.AppendUint32(header, r.currentSendingChainLength)
// return header
// }
func (r *DoubleRatchetParticipant) decryptHeader(
ciphertext *protobufs.MessageCiphertext,
receivingHeaderKey []byte,
) ([]byte, bool, error) {
header, err := r.decrypt(
ciphertext,
receivingHeaderKey,
nil,
)
if err != nil && subtle.ConstantTimeCompare(
r.currentReceivingHeaderKey,
receivingHeaderKey,
) == 1 {
if header, err = r.decrypt(
ciphertext,
r.nextReceivingHeaderKey,
nil,
); err != nil {
return nil, false, errors.Wrap(err, "could not decrypt header")
}
// func (r *DoubleRatchetParticipant) decryptHeader(
// ciphertext *protobufs.MessageCiphertext,
// receivingHeaderKey []byte,
// ) ([]byte, bool, error) {
// header, err := r.decrypt(
// ciphertext,
// receivingHeaderKey,
// nil,
// )
// if err != nil && subtle.ConstantTimeCompare(
// r.currentReceivingHeaderKey,
// receivingHeaderKey,
// ) == 1 {
// if header, err = r.decrypt(
// ciphertext,
// r.nextReceivingHeaderKey,
// nil,
// ); err != nil {
// return nil, false, errors.Wrap(err, "could not decrypt header")
// }
return header, true, nil
}
// return header, true, nil
// }
return header, false, errors.Wrap(err, "could not decrypt header")
}
// return header, false, errors.Wrap(err, "could not decrypt header")
// }
func (r *DoubleRatchetParticipant) decodeHeader(
header []byte,
) (curves.Point, uint32, uint32, error) {
if len(header) < 9 {
return nil, 0, 0, errors.New("malformed header")
}
// func (r *DoubleRatchetParticipant) decodeHeader(
// header []byte,
// ) (curves.Point, uint32, uint32, error) {
// if len(header) < 9 {
// return nil, 0, 0, errors.New("malformed header")
// }
currentReceivingChainLength := binary.BigEndian.Uint32(header[len(header)-4:])
previousReceivingChainLength := binary.BigEndian.Uint32(
header[len(header)-8 : len(header)-4],
)
receivingEphemeralKeyBytes := header[:len(header)-8]
receivingEphemeralKey, err := r.curve.Point.FromAffineCompressed(
receivingEphemeralKeyBytes,
)
// currentReceivingChainLength := binary.BigEndian.Uint32(header[len(header)-4:])
// previousReceivingChainLength := binary.BigEndian.Uint32(
// header[len(header)-8 : len(header)-4],
// )
// receivingEphemeralKeyBytes := header[:len(header)-8]
// receivingEphemeralKey, err := r.curve.Point.FromAffineCompressed(
// receivingEphemeralKeyBytes,
// )
return receivingEphemeralKey,
previousReceivingChainLength,
currentReceivingChainLength,
errors.Wrap(err, "could not decode receiving dh key")
}
// return receivingEphemeralKey,
// previousReceivingChainLength,
// currentReceivingChainLength,
// errors.Wrap(err, "could not decode receiving dh key")
// }
func (r *DoubleRatchetParticipant) encrypt(
plaintext []byte,
key []byte,
associatedData []byte,
) (*protobufs.MessageCiphertext, error) {
iv := [12]byte{}
rand.Read(iv[:])
aesCipher, err := aes.NewCipher(key)
if err != nil {
return nil, errors.Wrap(err, "could not construct cipher")
}
// func (r *DoubleRatchetParticipant) encrypt(
// plaintext []byte,
// key []byte,
// associatedData []byte,
// ) (*protobufs.MessageCiphertext, error) {
// iv := [12]byte{}
// rand.Read(iv[:])
// aesCipher, err := aes.NewCipher(key)
// if err != nil {
// return nil, errors.Wrap(err, "could not construct cipher")
// }
gcm, err := cipher.NewGCM(aesCipher)
if err != nil {
return nil, errors.Wrap(err, "could not construct block")
}
// gcm, err := cipher.NewGCM(aesCipher)
// if err != nil {
// return nil, errors.Wrap(err, "could not construct block")
// }
ciphertext := &protobufs.MessageCiphertext{}
// ciphertext := &protobufs.MessageCiphertext{}
if associatedData == nil {
associatedData = make([]byte, 32)
if _, err := rand.Read(associatedData); err != nil {
return nil, errors.Wrap(err, "could not obtain entropy")
}
ciphertext.AssociatedData = associatedData
}
// if associatedData == nil {
// associatedData = make([]byte, 32)
// if _, err := rand.Read(associatedData); err != nil {
// return nil, errors.Wrap(err, "could not obtain entropy")
// }
// ciphertext.AssociatedData = associatedData
// }
ciphertext.Ciphertext = gcm.Seal(nil, iv[:], plaintext, associatedData)
ciphertext.InitializationVector = iv[:]
// ciphertext.Ciphertext = gcm.Seal(nil, iv[:], plaintext, associatedData)
// ciphertext.InitializationVector = iv[:]
return ciphertext, nil
}
// return ciphertext, nil
// }
func (r *DoubleRatchetParticipant) decrypt(
ciphertext *protobufs.MessageCiphertext,
key []byte,
associatedData []byte,
) ([]byte, error) {
if associatedData == nil {
associatedData = ciphertext.AssociatedData
}
// func (r *DoubleRatchetParticipant) decrypt(
// ciphertext *protobufs.MessageCiphertext,
// key []byte,
// associatedData []byte,
// ) ([]byte, error) {
// if associatedData == nil {
// associatedData = ciphertext.AssociatedData
// }
aesCipher, err := aes.NewCipher(key)
if err != nil {
return nil, errors.Wrap(err, "could not construct cipher")
}
// aesCipher, err := aes.NewCipher(key)
// if err != nil {
// return nil, errors.Wrap(err, "could not construct cipher")
// }
gcm, err := cipher.NewGCM(aesCipher)
if err != nil {
return nil, errors.Wrap(err, "could not construct block")
}
// gcm, err := cipher.NewGCM(aesCipher)
// if err != nil {
// return nil, errors.Wrap(err, "could not construct block")
// }
plaintext, err := gcm.Open(
nil,
ciphertext.InitializationVector,
ciphertext.Ciphertext,
associatedData,
)
// plaintext, err := gcm.Open(
// nil,
// ciphertext.InitializationVector,
// ciphertext.Ciphertext,
// associatedData,
// )
return plaintext, errors.Wrap(err, "could not decrypt ciphertext")
}
// return plaintext, errors.Wrap(err, "could not decrypt ciphertext")
// }
func ratchetKeys(inputKey []byte) ([]byte, []byte, []byte) {
buf := hmac.New(sha512.New, inputKey)
buf.Write([]byte{AEAD_KEY})
aeadKey := buf.Sum(nil)
buf.Reset()
buf.Write([]byte{MESSAGE_KEY})
messageKey := buf.Sum(nil)
buf.Reset()
buf.Write([]byte{CHAIN_KEY})
chainKey := buf.Sum(nil)
// func ratchetKeys(inputKey []byte) ([]byte, []byte, []byte) {
// buf := hmac.New(sha512.New, inputKey)
// buf.Write([]byte{AEAD_KEY})
// aeadKey := buf.Sum(nil)
// buf.Reset()
// buf.Write([]byte{MESSAGE_KEY})
// messageKey := buf.Sum(nil)
// buf.Reset()
// buf.Write([]byte{CHAIN_KEY})
// chainKey := buf.Sum(nil)
// return chainKey[:32], messageKey[:32], aeadKey[:32]
// }
return chainKey[:32], messageKey[:32], aeadKey[:32]
}

View File

@ -1,131 +1,129 @@
package crypto_test
// Uncomment with full release
import (
"crypto/rand"
"testing"
// import (
// "crypto/rand"
// "testing"
"github.com/stretchr/testify/require"
// "github.com/stretchr/testify/require"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves"
"source.quilibrium.com/quilibrium/monorepo/node/crypto"
)
// "source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves"
// "source.quilibrium.com/quilibrium/monorepo/node/crypto"
// )
func TestRatchetEncrypt(t *testing.T) {
x448SendingIdentityPrivateKey := curves.ED448().Scalar.Random(rand.Reader)
x448SendingEphemeralPrivateKey := curves.ED448().Scalar.Random(rand.Reader)
x448ReceivingIdentityPrivateKey := curves.ED448().Scalar.Random(rand.Reader)
x448ReceivingSignedPrePrivateKey := curves.ED448().Scalar.Random(rand.Reader)
x448SendingIdentityKey := curves.ED448().NewGeneratorPoint().Mul(x448SendingIdentityPrivateKey)
x448SendingEphemeralKey := curves.ED448().NewGeneratorPoint().Mul(x448SendingEphemeralPrivateKey)
x448ReceivingIdentityKey := curves.ED448().NewGeneratorPoint().Mul(x448ReceivingIdentityPrivateKey)
x448ReceivingSignedPreKey := curves.ED448().NewGeneratorPoint().Mul(x448ReceivingSignedPrePrivateKey)
// func TestRatchetEncrypt(t *testing.T) {
// x448SendingIdentityPrivateKey := curves.ED448().Scalar.Random(rand.Reader)
// x448SendingEphemeralPrivateKey := curves.ED448().Scalar.Random(rand.Reader)
// x448ReceivingIdentityPrivateKey := curves.ED448().Scalar.Random(rand.Reader)
// x448ReceivingSignedPrePrivateKey := curves.ED448().Scalar.Random(rand.Reader)
// x448SendingIdentityKey := curves.ED448().NewGeneratorPoint().Mul(x448SendingIdentityPrivateKey)
// x448SendingEphemeralKey := curves.ED448().NewGeneratorPoint().Mul(x448SendingEphemeralPrivateKey)
// x448ReceivingIdentityKey := curves.ED448().NewGeneratorPoint().Mul(x448ReceivingIdentityPrivateKey)
// x448ReceivingSignedPreKey := curves.ED448().NewGeneratorPoint().Mul(x448ReceivingSignedPrePrivateKey)
senderResult := crypto.SenderX3DH(
x448SendingIdentityPrivateKey,
x448SendingEphemeralPrivateKey,
x448ReceivingIdentityKey,
x448ReceivingSignedPreKey,
96,
)
// senderResult := crypto.SenderX3DH(
// x448SendingIdentityPrivateKey,
// x448SendingEphemeralPrivateKey,
// x448ReceivingIdentityKey,
// x448ReceivingSignedPreKey,
// 96,
// )
receiverResult := crypto.ReceiverX3DH(
x448ReceivingIdentityPrivateKey,
x448ReceivingSignedPrePrivateKey,
x448SendingIdentityKey,
x448SendingEphemeralKey,
96,
)
// receiverResult := crypto.ReceiverX3DH(
// x448ReceivingIdentityPrivateKey,
// x448ReceivingSignedPrePrivateKey,
// x448SendingIdentityKey,
// x448SendingEphemeralKey,
// 96,
// )
sender, err := crypto.NewDoubleRatchetParticipant(
senderResult[:32],
senderResult[32:64],
senderResult[64:],
true,
x448SendingEphemeralPrivateKey,
x448ReceivingSignedPreKey,
*curves.ED448(),
nil,
)
require.NoError(t, err)
// sender, err := crypto.NewDoubleRatchetParticipant(
// senderResult[:32],
// senderResult[32:64],
// senderResult[64:],
// true,
// x448SendingEphemeralPrivateKey,
// x448ReceivingSignedPreKey,
// *curves.ED448(),
// nil,
// )
// require.NoError(t, err)
receiver, err := crypto.NewDoubleRatchetParticipant(
receiverResult[:32],
receiverResult[32:64],
receiverResult[64:],
false,
x448ReceivingSignedPrePrivateKey,
x448SendingEphemeralKey,
*curves.ED448(),
nil,
)
require.NoError(t, err)
// receiver, err := crypto.NewDoubleRatchetParticipant(
// receiverResult[:32],
// receiverResult[32:64],
// receiverResult[64:],
// false,
// x448ReceivingSignedPrePrivateKey,
// x448SendingEphemeralKey,
// *curves.ED448(),
// nil,
// )
// require.NoError(t, err)
envelope1, err := sender.RatchetEncrypt([]byte("hello there"))
require.NoError(t, err)
// envelope1, err := sender.RatchetEncrypt([]byte("hello there"))
// require.NoError(t, err)
envelope2, err := sender.RatchetEncrypt([]byte("general kenobi"))
require.NoError(t, err)
// envelope2, err := sender.RatchetEncrypt([]byte("general kenobi"))
// require.NoError(t, err)
plaintext1, err := receiver.RatchetDecrypt(envelope1)
require.NoError(t, err)
// plaintext1, err := receiver.RatchetDecrypt(envelope1)
// require.NoError(t, err)
plaintext2, err := receiver.RatchetDecrypt(envelope2)
require.NoError(t, err)
// plaintext2, err := receiver.RatchetDecrypt(envelope2)
// require.NoError(t, err)
envelope3, err := receiver.RatchetEncrypt([]byte("you are a bold one"))
require.NoError(t, err)
// envelope3, err := receiver.RatchetEncrypt([]byte("you are a bold one"))
// require.NoError(t, err)
envelope4, err := receiver.RatchetEncrypt([]byte("[mechanical laughing]"))
require.NoError(t, err)
// envelope4, err := receiver.RatchetEncrypt([]byte("[mechanical laughing]"))
// require.NoError(t, err)
plaintext3, err := sender.RatchetDecrypt(envelope3)
require.NoError(t, err)
// plaintext3, err := sender.RatchetDecrypt(envelope3)
// require.NoError(t, err)
plaintext4, err := sender.RatchetDecrypt(envelope4)
require.NoError(t, err)
// plaintext4, err := sender.RatchetDecrypt(envelope4)
// require.NoError(t, err)
// confirm large messages
msg5 := make([]byte, 1024*1024*10)
msg6 := make([]byte, 1024*1024*10)
msg7 := make([]byte, 1024*1024*10)
msg8 := make([]byte, 1024*1024*10)
rand.Read(msg5)
rand.Read(msg6)
rand.Read(msg7)
rand.Read(msg8)
// // confirm large messages
// msg5 := make([]byte, 1024*1024*10)
// msg6 := make([]byte, 1024*1024*10)
// msg7 := make([]byte, 1024*1024*10)
// msg8 := make([]byte, 1024*1024*10)
// rand.Read(msg5)
// rand.Read(msg6)
// rand.Read(msg7)
// rand.Read(msg8)
envelope5, err := sender.RatchetEncrypt(msg5)
require.NoError(t, err)
// envelope5, err := sender.RatchetEncrypt(msg5)
// require.NoError(t, err)
envelope6, err := sender.RatchetEncrypt(msg6)
require.NoError(t, err)
// envelope6, err := sender.RatchetEncrypt(msg6)
// require.NoError(t, err)
plaintext5, err := receiver.RatchetDecrypt(envelope5)
require.NoError(t, err)
// plaintext5, err := receiver.RatchetDecrypt(envelope5)
// require.NoError(t, err)
plaintext6, err := receiver.RatchetDecrypt(envelope6)
require.NoError(t, err)
// plaintext6, err := receiver.RatchetDecrypt(envelope6)
// require.NoError(t, err)
envelope7, err := receiver.RatchetEncrypt(msg7)
require.NoError(t, err)
// envelope7, err := receiver.RatchetEncrypt(msg7)
// require.NoError(t, err)
envelope8, err := receiver.RatchetEncrypt(msg8)
require.NoError(t, err)
// envelope8, err := receiver.RatchetEncrypt(msg8)
// require.NoError(t, err)
plaintext7, err := sender.RatchetDecrypt(envelope7)
require.NoError(t, err)
// plaintext7, err := sender.RatchetDecrypt(envelope7)
// require.NoError(t, err)
plaintext8, err := sender.RatchetDecrypt(envelope8)
require.NoError(t, err)
// plaintext8, err := sender.RatchetDecrypt(envelope8)
// require.NoError(t, err)
// require.Equal(t, []byte("hello there"), plaintext1)
// require.Equal(t, []byte("general kenobi"), plaintext2)
// require.Equal(t, []byte("you are a bold one"), plaintext3)
// require.Equal(t, []byte("[mechanical laughing]"), plaintext4)
// require.Equal(t, msg5, plaintext5)
// require.Equal(t, msg6, plaintext6)
// require.Equal(t, msg7, plaintext7)
// require.Equal(t, msg8, plaintext8)
// }
require.Equal(t, []byte("hello there"), plaintext1)
require.Equal(t, []byte("general kenobi"), plaintext2)
require.Equal(t, []byte("you are a bold one"), plaintext3)
require.Equal(t, []byte("[mechanical laughing]"), plaintext4)
require.Equal(t, msg5, plaintext5)
require.Equal(t, msg6, plaintext6)
require.Equal(t, msg7, plaintext7)
require.Equal(t, msg8, plaintext8)
}

View File

@ -0,0 +1,14 @@
package execution
import "source.quilibrium.com/quilibrium/monorepo/node/protobufs"
type ExecutionEngine interface {
GetName() string
GetSupportedApplications() []*protobufs.Application
Start() <-chan error
Stop(force bool) <-chan error
ProcessMessage(
address []byte,
message *protobufs.Message,
) ([]*protobufs.Message, error)
}

View File

@ -0,0 +1,95 @@
package nop
import (
"github.com/pkg/errors"
"go.uber.org/zap"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
"source.quilibrium.com/quilibrium/monorepo/node/execution"
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
)
type NopExecutionEngine struct {
logger *zap.Logger
}
func NewNopExecutionEngine(
logger *zap.Logger,
) *NopExecutionEngine {
if logger == nil {
panic(errors.New("logger is nil"))
}
return &NopExecutionEngine{
logger: logger,
}
}
var _ execution.ExecutionEngine = (*NopExecutionEngine)(nil)
// GetName implements ExecutionEngine
func (*NopExecutionEngine) GetName() string {
return "nop"
}
// GetSupportedApplications implements ExecutionEngine
func (
*NopExecutionEngine,
) GetSupportedApplications() []*protobufs.Application {
return []*protobufs.Application{
{
Address: []byte{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
},
ExecutionContext: protobufs.ExecutionContext_EXECUTION_CONTEXT_INTRINSIC,
},
}
}
// Start implements ExecutionEngine
func (e *NopExecutionEngine) Start() <-chan error {
errChan := make(chan error)
go func() {
errChan <- nil
}()
return errChan
}
// Stop implements ExecutionEngine
func (*NopExecutionEngine) Stop(force bool) <-chan error {
errChan := make(chan error)
go func() {
errChan <- nil
}()
return errChan
}
// ProcessMessage implements ExecutionEngine
func (e *NopExecutionEngine) ProcessMessage(
address []byte,
message *protobufs.Message,
) ([]*protobufs.Message, error) {
any := &anypb.Any{}
if err := proto.Unmarshal(message.Payload, any); err != nil {
return nil, errors.Wrap(err, "could not unmarshal message")
}
if any.TypeUrl == protobufs.ClockFrameType {
frame := &protobufs.ClockFrame{}
if err := any.UnmarshalTo(frame); err != nil {
return nil, errors.Wrap(err, "could not unmarshal clock frame")
}
e.logger.Info("nop")
}
return nil, nil
}

View File

@ -11,6 +11,7 @@ import (
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/pkg/errors"
"source.quilibrium.com/quilibrium/monorepo/node/app"
"source.quilibrium.com/quilibrium/monorepo/node/config"
)
@ -32,7 +33,6 @@ func main() {
fmt.Println("Import completed, you are ready for the launch.")
return
}
done := make(chan os.Signal, 1)
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
@ -40,7 +40,19 @@ func main() {
printVersion()
fmt.Println(" ")
flag.Usage()
nodeConfig, err := config.LoadConfig(*configDirectory, "")
if err != nil {
panic(err)
}
node, err := app.NewNode(nodeConfig)
if err != nil {
panic(err)
}
node.Start()
<-done
node.Stop()
}
func printPeerID(p2pConfig *config.P2PConfig) {
@ -100,5 +112,5 @@ func printLogo() {
func printVersion() {
fmt.Println(" ")
fmt.Println(" Quilibrium Node - v1.0.0 Import-only Utility")
fmt.Println(" Quilibrium Node - v1.0.0 DHT Verification")
}

94
node/p2p/bloom_utils.go Normal file
View File

@ -0,0 +1,94 @@
package p2p
import (
"fmt"
"math/big"
"golang.org/x/crypto/sha3"
)
// getOnesIndices returns the indices of all bits that are 1 in the byte slice.
func getOnesIndices(input []byte) []int {
var indices []int
for i, b := range input {
for j := 0; j < 8; j++ {
if (b>>j)&1 == 1 {
indices = append(indices, i*8+j)
}
}
}
return indices
}
// generateCombinations generates combinations of size k from the given slice.
func generateCombinations(arr []int, k int) [][]int {
var ans [][]int
if k == 0 {
return [][]int{{}}
}
if len(arr) == 0 {
return nil
}
head := arr[0]
tail := arr[1:]
// With head
for _, sub := range generateCombinations(tail, k-1) {
ans = append(ans, append([]int{head}, sub...))
}
// Without head
ans = append(ans, generateCombinations(tail, k)...)
return ans
}
// generateBitSlices returns byte slices with only three 1-bits, and evaluates
// the supplied function on the new byte slices.
func generateBitSlices(
input []byte,
eval func(slice []byte) error,
) error {
oneIndices := getOnesIndices(input)
combinations := generateCombinations(oneIndices, 3)
for _, combo := range combinations {
newSlice := make([]byte, len(input))
for _, index := range combo {
byteIndex := index / 8
bitIndex := index % 8
newSlice[byteIndex] |= (1 << bitIndex)
}
if err := eval(newSlice); err != nil {
return err
}
}
return nil
}
// getBloomFilterIndices returns a bloom filter index based on the data, however
// it assumes bitLength is a multiple of 32. If the filter size is not
// conformant, this will generate biased indices.
func getBloomFilterIndices(data []byte, bitLength int, k int) []byte {
byteSize := bitLength / 256
digest := sha3.Sum256(data)
output := make([]byte, bitLength/8)
outputBI := big.NewInt(0)
for i := 0; i < k; i++ {
position := digest[i*byteSize : (i+1)*byteSize]
if outputBI.Bit(int(new(big.Int).SetBytes(position).Int64())) != 1 {
outputBI.SetBit(outputBI, int(new(big.Int).SetBytes(position).Int64()), 1)
} else if k*byteSize <= 32 {
// we need to extend the search
k++
} else {
fmt.Printf(
"digest %+x cannot be used as bloom index, panicking\n",
digest,
)
panic(
"could not generate bloom filter index, k offset cannot be adjusted",
)
}
}
outputBI.FillBytes(output)
return output
}

421
node/p2p/blossomsub.go Normal file
View File

@ -0,0 +1,421 @@
package p2p
import (
"context"
"crypto/rand"
"encoding/hex"
"math/big"
"sync"
"github.com/libp2p/go-libp2p"
dht "github.com/libp2p/go-libp2p-kad-dht"
libp2pconfig "github.com/libp2p/go-libp2p/config"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/p2p/discovery/routing"
"github.com/libp2p/go-libp2p/p2p/discovery/util"
"github.com/pkg/errors"
"go.uber.org/zap"
blossomsub "source.quilibrium.com/quilibrium/monorepo/go-libp2p-blossomsub"
"source.quilibrium.com/quilibrium/monorepo/go-libp2p-blossomsub/pb"
"source.quilibrium.com/quilibrium/monorepo/node/config"
)
type BlossomSub struct {
ps *blossomsub.PubSub
ctx context.Context
logger *zap.Logger
peerID peer.ID
bitmaskMap map[string]*blossomsub.Bitmask
}
var _ PubSub = (*BlossomSub)(nil)
var ErrNoPeersAvailable = errors.New("no peers available")
// Crucial note, bitmask lengths should always be a power of two so as to reduce
// index bias with hash functions
var BITMASK_ALL = []byte{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
}
func NewBlossomSub(
p2pConfig *config.P2PConfig,
logger *zap.Logger,
) *BlossomSub {
ctx := context.Background()
opts := []libp2pconfig.Option{
libp2p.ListenAddrStrings(p2pConfig.ListenMultiaddr),
}
if p2pConfig.PeerPrivKey != "" {
peerPrivKey, err := hex.DecodeString(p2pConfig.PeerPrivKey)
if err != nil {
panic(errors.Wrap(err, "error unmarshaling peerkey"))
}
privKey, err := crypto.UnmarshalEd448PrivateKey(peerPrivKey)
if err != nil {
panic(errors.Wrap(err, "error unmarshaling peerkey"))
}
opts = append(opts, libp2p.Identity(privKey))
}
h, err := libp2p.New(opts...)
if err != nil {
panic(errors.Wrap(err, "error constructing p2p"))
}
logger.Info("established peer id", zap.String("peer_id", h.ID().String()))
go discoverPeers(p2pConfig, ctx, logger, h)
var tracer *blossomsub.JSONTracer
if p2pConfig.TraceLogFile == "" {
tracer, err = blossomsub.NewStdoutJSONTracer()
if err != nil {
panic(errors.Wrap(err, "error building stdout tracer"))
}
} else {
tracer, err = blossomsub.NewJSONTracer(p2pConfig.TraceLogFile)
if err != nil {
panic(errors.Wrap(err, "error building file tracer"))
}
}
blossomOpts := []blossomsub.Option{
blossomsub.WithEventTracer(tracer),
}
params := mergeDefaults(p2pConfig)
rt := blossomsub.NewBlossomSubRouter(h, params)
ps, err := blossomsub.NewBlossomSubWithRouter(ctx, h, rt, blossomOpts...)
if err != nil {
panic(err)
}
peerID := h.ID()
return &BlossomSub{
ps,
ctx,
logger,
peerID,
make(map[string]*blossomsub.Bitmask),
}
}
func (b *BlossomSub) PublishToBitmask(bitmask []byte, data []byte) error {
bm, ok := b.bitmaskMap[string(bitmask)]
if !ok {
b.logger.Error(
"error while publishing to bitmask",
zap.Error(errors.New("not subscribed to bitmask")),
zap.Binary("bitmask", bitmask),
)
return errors.New("not subscribed to bitmask")
}
return bm.Publish(b.ctx, data)
}
func (b *BlossomSub) Publish(data []byte) error {
bitmask := getBloomFilterIndices(data, 256, 3)
return b.PublishToBitmask(bitmask, data)
}
func (b *BlossomSub) Subscribe(
bitmask []byte,
handler func(message *pb.Message) error,
raw bool,
) {
eval := func(bitmask []byte) error {
_, ok := b.bitmaskMap[string(bitmask)]
if ok {
return nil
}
b.logger.Info("joining broadcast")
bm, err := b.ps.Join(bitmask)
if err != nil {
b.logger.Error("join failed", zap.Error(err))
return errors.Wrap(err, "subscribe")
}
b.bitmaskMap[string(bitmask)] = bm
b.logger.Info("subscribe to bitmask", zap.Binary("bitmask", bitmask))
sub, err := bm.Subscribe()
if err != nil {
b.logger.Error("subscription failed", zap.Error(err))
return errors.Wrap(err, "subscribe")
}
b.logger.Info(
"begin streaming from bitmask",
zap.Binary("bitmask", bitmask),
)
go func() {
for {
m, err := sub.Next(b.ctx)
if err != nil {
b.logger.Error(
"got error when fetching the next message",
zap.Error(err),
)
}
if err = handler(m.Message); err != nil {
b.logger.Error("message handler returned error", zap.Error(err))
}
}
}()
return nil
}
if raw {
if err := eval(bitmask); err != nil {
b.logger.Error("subscribe returned error", zap.Error(err))
}
} else {
if err := generateBitSlices(bitmask, eval); err != nil {
b.logger.Error("bloom subscribe returned error", zap.Error(err))
}
}
}
func (b *BlossomSub) Unsubscribe(bitmask []byte, raw bool) {
bm, ok := b.bitmaskMap[string(bitmask)]
if !ok {
return
}
bm.Close()
}
func (b *BlossomSub) GetPeerID() []byte {
return []byte(b.peerID)
}
func (b *BlossomSub) GetRandomPeer(bitmask []byte) ([]byte, error) {
peers := b.ps.ListPeers(bitmask)
if len(peers) == 0 {
return nil, errors.Wrap(
ErrNoPeersAvailable,
"get random peer",
)
}
b.logger.Info("selecting from peers", zap.Any("peer_ids", peers))
sel, err := rand.Int(rand.Reader, big.NewInt(int64(len(peers))))
if err != nil {
return nil, errors.Wrap(err, "get random peer")
}
return []byte(peers[sel.Int64()]), nil
}
func initDHT(
ctx context.Context,
p2pConfig *config.P2PConfig,
logger *zap.Logger,
h host.Host,
) *dht.IpfsDHT {
logger.Info("establishing dht")
kademliaDHT, err := dht.New(ctx, h)
if err != nil {
panic(err)
}
if err = kademliaDHT.Bootstrap(ctx); err != nil {
panic(err)
}
var wg sync.WaitGroup
logger.Info("connecting to bootstrap", zap.String("peer_id", h.ID().String()))
defaultBootstrapPeers := p2pConfig.BootstrapPeers
for _, peerAddr := range defaultBootstrapPeers {
peerinfo, err := peer.AddrInfoFromString(peerAddr)
if err != nil {
panic(err)
}
wg.Add(1)
go func() {
defer wg.Done()
if err := h.Connect(ctx, *peerinfo); err != nil {
logger.Warn("error while connecting to dht peer", zap.Error(err))
}
}()
}
wg.Wait()
return kademliaDHT
}
func discoverPeers(
p2pConfig *config.P2PConfig,
ctx context.Context,
logger *zap.Logger,
h host.Host,
) {
logger.Info("initiating peer discovery")
kademliaDHT := initDHT(ctx, p2pConfig, logger, h)
routingDiscovery := routing.NewRoutingDiscovery(kademliaDHT)
util.Advertise(ctx, routingDiscovery, string(BITMASK_ALL))
peerCount := 0
for peerCount < p2pConfig.MinPeers {
peerChan, err := routingDiscovery.FindPeers(ctx, string(BITMASK_ALL))
if err != nil {
panic(err)
}
for peer := range peerChan {
if peer.ID == h.ID() {
continue
}
logger.Info("found peer", zap.String("peer_id", peer.ID.Pretty()))
err := h.Connect(ctx, peer)
if err != nil {
logger.Warn(
"error while connecting to blossomsub peer",
zap.String("peer_id", peer.ID.Pretty()),
zap.Error(err),
)
} else {
logger.Info(
"connected to peer",
zap.String("peer_id", peer.ID.Pretty()),
)
peerCount++
}
}
}
logger.Info("completed initial peer discovery")
}
func mergeDefaults(p2pConfig *config.P2PConfig) blossomsub.BlossomSubParams {
if p2pConfig.D == 0 {
p2pConfig.D = blossomsub.BlossomSubD
}
if p2pConfig.DLo == 0 {
p2pConfig.DLo = blossomsub.BlossomSubDlo
}
if p2pConfig.DHi == 0 {
p2pConfig.DHi = blossomsub.BlossomSubDhi
}
if p2pConfig.DScore == 0 {
p2pConfig.DScore = blossomsub.BlossomSubDscore
}
if p2pConfig.DOut == 0 {
p2pConfig.DOut = blossomsub.BlossomSubDout
}
if p2pConfig.HistoryLength == 0 {
p2pConfig.HistoryLength = blossomsub.BlossomSubHistoryLength
}
if p2pConfig.HistoryGossip == 0 {
p2pConfig.HistoryGossip = blossomsub.BlossomSubHistoryGossip
}
if p2pConfig.DLazy == 0 {
p2pConfig.DLazy = blossomsub.BlossomSubDlazy
}
if p2pConfig.GossipFactor == 0 {
p2pConfig.GossipFactor = blossomsub.BlossomSubGossipFactor
}
if p2pConfig.GossipRetransmission == 0 {
p2pConfig.GossipRetransmission = blossomsub.BlossomSubGossipRetransmission
}
if p2pConfig.HeartbeatInitialDelay == 0 {
p2pConfig.HeartbeatInitialDelay = blossomsub.BlossomSubHeartbeatInitialDelay
}
if p2pConfig.HeartbeatInterval == 0 {
p2pConfig.HeartbeatInterval = blossomsub.BlossomSubHeartbeatInterval
}
if p2pConfig.FanoutTTL == 0 {
p2pConfig.FanoutTTL = blossomsub.BlossomSubFanoutTTL
}
if p2pConfig.PrunePeers == 0 {
p2pConfig.PrunePeers = blossomsub.BlossomSubPrunePeers
}
if p2pConfig.PruneBackoff == 0 {
p2pConfig.PruneBackoff = blossomsub.BlossomSubPruneBackoff
}
if p2pConfig.UnsubscribeBackoff == 0 {
p2pConfig.UnsubscribeBackoff = blossomsub.BlossomSubUnsubscribeBackoff
}
if p2pConfig.Connectors == 0 {
p2pConfig.Connectors = blossomsub.BlossomSubConnectors
}
if p2pConfig.MaxPendingConnections == 0 {
p2pConfig.MaxPendingConnections = blossomsub.BlossomSubMaxPendingConnections
}
if p2pConfig.ConnectionTimeout == 0 {
p2pConfig.ConnectionTimeout = blossomsub.BlossomSubConnectionTimeout
}
if p2pConfig.DirectConnectTicks == 0 {
p2pConfig.DirectConnectTicks = blossomsub.BlossomSubDirectConnectTicks
}
if p2pConfig.DirectConnectInitialDelay == 0 {
p2pConfig.DirectConnectInitialDelay =
blossomsub.BlossomSubDirectConnectInitialDelay
}
if p2pConfig.OpportunisticGraftTicks == 0 {
p2pConfig.OpportunisticGraftTicks =
blossomsub.BlossomSubOpportunisticGraftTicks
}
if p2pConfig.OpportunisticGraftPeers == 0 {
p2pConfig.OpportunisticGraftPeers =
blossomsub.BlossomSubOpportunisticGraftPeers
}
if p2pConfig.GraftFloodThreshold == 0 {
p2pConfig.GraftFloodThreshold = blossomsub.BlossomSubGraftFloodThreshold
}
if p2pConfig.MaxIHaveLength == 0 {
p2pConfig.MaxIHaveLength = blossomsub.BlossomSubMaxIHaveLength
}
if p2pConfig.MaxIHaveMessages == 0 {
p2pConfig.MaxIHaveMessages = blossomsub.BlossomSubMaxIHaveMessages
}
if p2pConfig.IWantFollowupTime == 0 {
p2pConfig.IWantFollowupTime = blossomsub.BlossomSubIWantFollowupTime
}
return blossomsub.BlossomSubParams{
D: p2pConfig.D,
Dlo: p2pConfig.DLo,
Dhi: p2pConfig.DHi,
Dscore: p2pConfig.DScore,
Dout: p2pConfig.DOut,
HistoryLength: p2pConfig.HistoryLength,
HistoryGossip: p2pConfig.HistoryGossip,
Dlazy: p2pConfig.DLazy,
GossipFactor: p2pConfig.GossipFactor,
GossipRetransmission: p2pConfig.GossipRetransmission,
HeartbeatInitialDelay: p2pConfig.HeartbeatInitialDelay,
HeartbeatInterval: p2pConfig.HeartbeatInterval,
FanoutTTL: p2pConfig.FanoutTTL,
PrunePeers: p2pConfig.PrunePeers,
PruneBackoff: p2pConfig.PruneBackoff,
UnsubscribeBackoff: p2pConfig.UnsubscribeBackoff,
Connectors: p2pConfig.Connectors,
MaxPendingConnections: p2pConfig.MaxPendingConnections,
ConnectionTimeout: p2pConfig.ConnectionTimeout,
DirectConnectTicks: p2pConfig.DirectConnectTicks,
DirectConnectInitialDelay: p2pConfig.DirectConnectInitialDelay,
OpportunisticGraftTicks: p2pConfig.OpportunisticGraftTicks,
OpportunisticGraftPeers: p2pConfig.OpportunisticGraftPeers,
GraftFloodThreshold: p2pConfig.GraftFloodThreshold,
MaxIHaveLength: p2pConfig.MaxIHaveLength,
MaxIHaveMessages: p2pConfig.MaxIHaveMessages,
IWantFollowupTime: p2pConfig.IWantFollowupTime,
SlowHeartbeatWarning: 0.1,
}
}

14
node/p2p/pubsub.go Normal file
View File

@ -0,0 +1,14 @@
package p2p
import (
"source.quilibrium.com/quilibrium/monorepo/go-libp2p-blossomsub/pb"
)
type PubSub interface {
PublishToBitmask(bitmask []byte, data []byte) error
Publish(data []byte) error
Subscribe(bitmask []byte, handler func(message *pb.Message) error, raw bool)
Unsubscribe(bitmask []byte, raw bool)
GetPeerID() []byte
GetRandomPeer(bitmask []byte) ([]byte, error)
}

12
node/protobufs/Makefile Normal file
View File

@ -0,0 +1,12 @@
PB = $(wildcard *.proto)
GO = $(PB:.proto=.pb.go)
PWD = $(pwd)
all: $(GO)
%.pb.go: %.proto
protoc -I=. --go_out=paths=source_relative:. *.proto
clean:
rm -f *.pb.go
rm -f *.go

View File

@ -0,0 +1,468 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.30.0
// protoc v3.21.12
// source: application.proto
package protobufs
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// The ExecutionContext defines the operating environment of the application
type ExecutionContext int32
const (
// Intrinsic execution is a protocol-native application Nodes are expected
// to have the necessary information required to execute.
// Intrinsic applications have addresses that have infinitessimal likelihood
// of collision and must be constructed as nothing-up-my-sleeve values.
ExecutionContext_EXECUTION_CONTEXT_INTRINSIC ExecutionContext = 0
// Hypergraph execution is also protocol-native, however it can be chained
// with extrinsic execution whereas other intrinsics cannot.
// Hypergraph applications have addresses that are derived from location
// within the hypergraph.
ExecutionContext_EXECUTION_CONTEXT_HYPERGRAPH ExecutionContext = 1
// Extrinsic execution is evaluation of application code that lives on the
// protocol, either within the hypergraph or supplementary to it, e.g. MetaVM.
ExecutionContext_EXECUTION_CONTEXT_EXTRINSIC ExecutionContext = 2
)
// Enum value maps for ExecutionContext.
var (
ExecutionContext_name = map[int32]string{
0: "EXECUTION_CONTEXT_INTRINSIC",
1: "EXECUTION_CONTEXT_HYPERGRAPH",
2: "EXECUTION_CONTEXT_EXTRINSIC",
}
ExecutionContext_value = map[string]int32{
"EXECUTION_CONTEXT_INTRINSIC": 0,
"EXECUTION_CONTEXT_HYPERGRAPH": 1,
"EXECUTION_CONTEXT_EXTRINSIC": 2,
}
)
func (x ExecutionContext) Enum() *ExecutionContext {
p := new(ExecutionContext)
*p = x
return p
}
func (x ExecutionContext) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (ExecutionContext) Descriptor() protoreflect.EnumDescriptor {
return file_application_proto_enumTypes[0].Descriptor()
}
func (ExecutionContext) Type() protoreflect.EnumType {
return &file_application_proto_enumTypes[0]
}
func (x ExecutionContext) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use ExecutionContext.Descriptor instead.
func (ExecutionContext) EnumDescriptor() ([]byte, []int) {
return file_application_proto_rawDescGZIP(), []int{0}
}
type Application struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
ExecutionContext ExecutionContext `protobuf:"varint,2,opt,name=execution_context,json=executionContext,proto3,enum=quilibrium.node.application.pb.ExecutionContext" json:"execution_context,omitempty"`
}
func (x *Application) Reset() {
*x = Application{}
if protoimpl.UnsafeEnabled {
mi := &file_application_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Application) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Application) ProtoMessage() {}
func (x *Application) ProtoReflect() protoreflect.Message {
mi := &file_application_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Application.ProtoReflect.Descriptor instead.
func (*Application) Descriptor() ([]byte, []int) {
return file_application_proto_rawDescGZIP(), []int{0}
}
func (x *Application) GetAddress() []byte {
if x != nil {
return x.Address
}
return nil
}
func (x *Application) GetExecutionContext() ExecutionContext {
if x != nil {
return x.ExecutionContext
}
return ExecutionContext_EXECUTION_CONTEXT_INTRINSIC
}
type IntrinsicExecutionInput struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
Input []byte `protobuf:"bytes,2,opt,name=input,proto3" json:"input,omitempty"`
}
func (x *IntrinsicExecutionInput) Reset() {
*x = IntrinsicExecutionInput{}
if protoimpl.UnsafeEnabled {
mi := &file_application_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *IntrinsicExecutionInput) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*IntrinsicExecutionInput) ProtoMessage() {}
func (x *IntrinsicExecutionInput) ProtoReflect() protoreflect.Message {
mi := &file_application_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use IntrinsicExecutionInput.ProtoReflect.Descriptor instead.
func (*IntrinsicExecutionInput) Descriptor() ([]byte, []int) {
return file_application_proto_rawDescGZIP(), []int{1}
}
func (x *IntrinsicExecutionInput) GetAddress() []byte {
if x != nil {
return x.Address
}
return nil
}
func (x *IntrinsicExecutionInput) GetInput() []byte {
if x != nil {
return x.Input
}
return nil
}
type IntrinsicExecutionOutput struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
Output []byte `protobuf:"bytes,2,opt,name=output,proto3" json:"output,omitempty"`
Proof []byte `protobuf:"bytes,3,opt,name=proof,proto3" json:"proof,omitempty"`
}
func (x *IntrinsicExecutionOutput) Reset() {
*x = IntrinsicExecutionOutput{}
if protoimpl.UnsafeEnabled {
mi := &file_application_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *IntrinsicExecutionOutput) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*IntrinsicExecutionOutput) ProtoMessage() {}
func (x *IntrinsicExecutionOutput) ProtoReflect() protoreflect.Message {
mi := &file_application_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use IntrinsicExecutionOutput.ProtoReflect.Descriptor instead.
func (*IntrinsicExecutionOutput) Descriptor() ([]byte, []int) {
return file_application_proto_rawDescGZIP(), []int{2}
}
func (x *IntrinsicExecutionOutput) GetAddress() []byte {
if x != nil {
return x.Address
}
return nil
}
func (x *IntrinsicExecutionOutput) GetOutput() []byte {
if x != nil {
return x.Output
}
return nil
}
func (x *IntrinsicExecutionOutput) GetProof() []byte {
if x != nil {
return x.Proof
}
return nil
}
type Message struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
Address []byte `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"`
}
func (x *Message) Reset() {
*x = Message{}
if protoimpl.UnsafeEnabled {
mi := &file_application_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Message) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Message) ProtoMessage() {}
func (x *Message) ProtoReflect() protoreflect.Message {
mi := &file_application_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Message.ProtoReflect.Descriptor instead.
func (*Message) Descriptor() ([]byte, []int) {
return file_application_proto_rawDescGZIP(), []int{3}
}
func (x *Message) GetHash() []byte {
if x != nil {
return x.Hash
}
return nil
}
func (x *Message) GetAddress() []byte {
if x != nil {
return x.Address
}
return nil
}
func (x *Message) GetPayload() []byte {
if x != nil {
return x.Payload
}
return nil
}
var File_application_proto protoreflect.FileDescriptor
var file_application_proto_rawDesc = []byte{
0x0a, 0x11, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x12, 0x1e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e,
0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x2e, 0x70, 0x62, 0x22, 0x86, 0x01, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x5d, 0x0a,
0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65,
0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x30, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69,
0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x69,
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x10, 0x65, 0x78, 0x65, 0x63,
0x75, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x49, 0x0a, 0x17,
0x49, 0x6e, 0x74, 0x72, 0x69, 0x6e, 0x73, 0x69, 0x63, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69,
0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73,
0x73, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x22, 0x62, 0x0a, 0x18, 0x49, 0x6e, 0x74, 0x72, 0x69,
0x6e, 0x73, 0x69, 0x63, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x75, 0x74,
0x70, 0x75, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a,
0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f,
0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x51, 0x0a, 0x07, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64,
0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2a, 0x76,
0x0a, 0x10, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65,
0x78, 0x74, 0x12, 0x1f, 0x0a, 0x1b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f,
0x43, 0x4f, 0x4e, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49,
0x43, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x49, 0x4f, 0x4e,
0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x48, 0x59, 0x50, 0x45, 0x52, 0x47, 0x52,
0x41, 0x50, 0x48, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x49,
0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x45, 0x58, 0x54, 0x52, 0x49,
0x4e, 0x53, 0x49, 0x43, 0x10, 0x02, 0x42, 0x3a, 0x5a, 0x38, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2f, 0x6d, 0x6f, 0x6e, 0x6f, 0x72,
0x65, 0x70, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_application_proto_rawDescOnce sync.Once
file_application_proto_rawDescData = file_application_proto_rawDesc
)
func file_application_proto_rawDescGZIP() []byte {
file_application_proto_rawDescOnce.Do(func() {
file_application_proto_rawDescData = protoimpl.X.CompressGZIP(file_application_proto_rawDescData)
})
return file_application_proto_rawDescData
}
var file_application_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_application_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_application_proto_goTypes = []interface{}{
(ExecutionContext)(0), // 0: quilibrium.node.application.pb.ExecutionContext
(*Application)(nil), // 1: quilibrium.node.application.pb.Application
(*IntrinsicExecutionInput)(nil), // 2: quilibrium.node.application.pb.IntrinsicExecutionInput
(*IntrinsicExecutionOutput)(nil), // 3: quilibrium.node.application.pb.IntrinsicExecutionOutput
(*Message)(nil), // 4: quilibrium.node.application.pb.Message
}
var file_application_proto_depIdxs = []int32{
0, // 0: quilibrium.node.application.pb.Application.execution_context:type_name -> quilibrium.node.application.pb.ExecutionContext
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_application_proto_init() }
func file_application_proto_init() {
if File_application_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_application_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Application); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_application_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IntrinsicExecutionInput); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_application_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IntrinsicExecutionOutput); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_application_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Message); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_application_proto_rawDesc,
NumEnums: 1,
NumMessages: 4,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_application_proto_goTypes,
DependencyIndexes: file_application_proto_depIdxs,
EnumInfos: file_application_proto_enumTypes,
MessageInfos: file_application_proto_msgTypes,
}.Build()
File_application_proto = out.File
file_application_proto_rawDesc = nil
file_application_proto_goTypes = nil
file_application_proto_depIdxs = nil
}

View File

@ -0,0 +1,44 @@
syntax = "proto3";
package quilibrium.node.application.pb;
option go_package = "source.quilibrium.com/quilibrium/monorepo/node/protobufs";
message Application {
bytes address = 1;
ExecutionContext execution_context = 2;
}
// The ExecutionContext defines the operating environment of the application
enum ExecutionContext {
// Intrinsic execution is a protocol-native application Nodes are expected
// to have the necessary information required to execute.
// Intrinsic applications have addresses that have infinitessimal likelihood
// of collision and must be constructed as nothing-up-my-sleeve values.
EXECUTION_CONTEXT_INTRINSIC = 0;
// Hypergraph execution is also protocol-native, however it can be chained
// with extrinsic execution whereas other intrinsics cannot.
// Hypergraph applications have addresses that are derived from location
// within the hypergraph.
EXECUTION_CONTEXT_HYPERGRAPH = 1;
// Extrinsic execution is evaluation of application code that lives on the
// protocol, either within the hypergraph or supplementary to it, e.g. MetaVM.
EXECUTION_CONTEXT_EXTRINSIC = 2;
}
message IntrinsicExecutionInput {
bytes address = 1;
bytes input = 2;
}
message IntrinsicExecutionOutput {
bytes address = 1;
bytes output = 2;
bytes proof = 3;
}
message Message {
bytes hash = 1;
bytes address = 2;
bytes payload = 3;
}

View File

@ -0,0 +1,224 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.30.0
// protoc v3.21.12
// source: ceremony.proto
package protobufs
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// Describes the transcript of KZG ceremony execution
type CeremonyTranscript struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The active collection of powers over G1
G1Powers []*BLS48581G1PublicKey `protobuf:"bytes,1,rep,name=g1_powers,json=g1Powers,proto3" json:"g1_powers,omitempty"`
// The active collection of powers over G2
G2Powers []*BLS48581G2PublicKey `protobuf:"bytes,2,rep,name=g2_powers,json=g2Powers,proto3" json:"g2_powers,omitempty"`
// The running s^256 G1 witnesses the choice of the 256th power is to ensure
// combinatorial birthday paradox-based attacks are not possible. In common
// KZG ceremonies, the collection of witnesses to PoT pubkeys produce the
// relationship of e(w*G1, s*G2) == (s'*G1, G2), where w*s == s'. The problem
// with this is that there are n powers under G2 (excl. the case where PoT
// ceremonies _only_ have the first G2 power), and so the chance of collision
// by combination to a target value for s' is feasible such that a sum of a
// permutation of valid G2 powers could forge witness values to reach a
// a desired outcome, as there are matching pairs of the G1 and G2 powers to
// permute. When the number of G2 powers is low, or one, this reduces to the
// discrete log assumption and so the only viable attack is of
// O(sqrt(<bit size>)) per Pollard's Rho (barring any advancements), but in
// many cases the number of G2 powers is high enough such that n! naive
// combinations of additions are greater (and cheap, since the additions are
// first tested in G1) than the required time of testing the discrete log,
// and combined with many generated target values, significantly reduces the
// amount of time required to complete the attack. This means that in
// traditional KZG ceremonies, the last contributor to a ceremony can
// potentially control the secret. Or, we can just track the witnesses to the
// highest power in the ceremony and avoid the whole problem. :)
RunningG1_256Witnesses []*BLS48581G1PublicKey `protobuf:"bytes,3,rep,name=running_g1_256_witnesses,json=runningG1256Witnesses,proto3" json:"running_g1_256_witnesses,omitempty"`
// The running s^256 G2 powers see notes on running_g1_256_witnesses for why
// we do this.
RunningG2_256Powers []*BLS48581G2PublicKey `protobuf:"bytes,4,rep,name=running_g2_256_powers,json=runningG2256Powers,proto3" json:"running_g2_256_powers,omitempty"`
}
func (x *CeremonyTranscript) Reset() {
*x = CeremonyTranscript{}
if protoimpl.UnsafeEnabled {
mi := &file_ceremony_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CeremonyTranscript) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CeremonyTranscript) ProtoMessage() {}
func (x *CeremonyTranscript) ProtoReflect() protoreflect.Message {
mi := &file_ceremony_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CeremonyTranscript.ProtoReflect.Descriptor instead.
func (*CeremonyTranscript) Descriptor() ([]byte, []int) {
return file_ceremony_proto_rawDescGZIP(), []int{0}
}
func (x *CeremonyTranscript) GetG1Powers() []*BLS48581G1PublicKey {
if x != nil {
return x.G1Powers
}
return nil
}
func (x *CeremonyTranscript) GetG2Powers() []*BLS48581G2PublicKey {
if x != nil {
return x.G2Powers
}
return nil
}
func (x *CeremonyTranscript) GetRunningG1_256Witnesses() []*BLS48581G1PublicKey {
if x != nil {
return x.RunningG1_256Witnesses
}
return nil
}
func (x *CeremonyTranscript) GetRunningG2_256Powers() []*BLS48581G2PublicKey {
if x != nil {
return x.RunningG2_256Powers
}
return nil
}
var File_ceremony_proto protoreflect.FileDescriptor
var file_ceremony_proto_rawDesc = []byte{
0x0a, 0x0e, 0x63, 0x65, 0x72, 0x65, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x1b, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64,
0x65, 0x2e, 0x63, 0x65, 0x72, 0x65, 0x6d, 0x6f, 0x6e, 0x79, 0x2e, 0x70, 0x62, 0x1a, 0x0a, 0x6b,
0x65, 0x79, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf2, 0x02, 0x0a, 0x12, 0x43, 0x65,
0x72, 0x65, 0x6d, 0x6f, 0x6e, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
0x12, 0x49, 0x0a, 0x09, 0x67, 0x31, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d,
0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x4c,
0x53, 0x34, 0x38, 0x35, 0x38, 0x31, 0x47, 0x31, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65,
0x79, 0x52, 0x08, 0x67, 0x31, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x12, 0x49, 0x0a, 0x09, 0x67,
0x32, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c,
0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65,
0x2e, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x4c, 0x53, 0x34, 0x38, 0x35, 0x38,
0x31, 0x47, 0x32, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x08, 0x67, 0x32,
0x50, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x12, 0x65, 0x0a, 0x18, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e,
0x67, 0x5f, 0x67, 0x31, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x77, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73,
0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69,
0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x2e,
0x70, 0x62, 0x2e, 0x42, 0x4c, 0x53, 0x34, 0x38, 0x35, 0x38, 0x31, 0x47, 0x31, 0x50, 0x75, 0x62,
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x15, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x47,
0x31, 0x32, 0x35, 0x36, 0x57, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x5f, 0x0a,
0x15, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x67, 0x32, 0x5f, 0x32, 0x35, 0x36, 0x5f,
0x70, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x71,
0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6b,
0x65, 0x79, 0x73, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x4c, 0x53, 0x34, 0x38, 0x35, 0x38, 0x31, 0x47,
0x32, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x12, 0x72, 0x75, 0x6e, 0x6e,
0x69, 0x6e, 0x67, 0x47, 0x32, 0x32, 0x35, 0x36, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x42, 0x3a,
0x5a, 0x38, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72,
0x69, 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69,
0x75, 0x6d, 0x2f, 0x6d, 0x6f, 0x6e, 0x6f, 0x72, 0x65, 0x70, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
var (
file_ceremony_proto_rawDescOnce sync.Once
file_ceremony_proto_rawDescData = file_ceremony_proto_rawDesc
)
func file_ceremony_proto_rawDescGZIP() []byte {
file_ceremony_proto_rawDescOnce.Do(func() {
file_ceremony_proto_rawDescData = protoimpl.X.CompressGZIP(file_ceremony_proto_rawDescData)
})
return file_ceremony_proto_rawDescData
}
var file_ceremony_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_ceremony_proto_goTypes = []interface{}{
(*CeremonyTranscript)(nil), // 0: quilibrium.node.ceremony.pb.CeremonyTranscript
(*BLS48581G1PublicKey)(nil), // 1: quilibrium.node.keys.pb.BLS48581G1PublicKey
(*BLS48581G2PublicKey)(nil), // 2: quilibrium.node.keys.pb.BLS48581G2PublicKey
}
var file_ceremony_proto_depIdxs = []int32{
1, // 0: quilibrium.node.ceremony.pb.CeremonyTranscript.g1_powers:type_name -> quilibrium.node.keys.pb.BLS48581G1PublicKey
2, // 1: quilibrium.node.ceremony.pb.CeremonyTranscript.g2_powers:type_name -> quilibrium.node.keys.pb.BLS48581G2PublicKey
1, // 2: quilibrium.node.ceremony.pb.CeremonyTranscript.running_g1_256_witnesses:type_name -> quilibrium.node.keys.pb.BLS48581G1PublicKey
2, // 3: quilibrium.node.ceremony.pb.CeremonyTranscript.running_g2_256_powers:type_name -> quilibrium.node.keys.pb.BLS48581G2PublicKey
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_ceremony_proto_init() }
func file_ceremony_proto_init() {
if File_ceremony_proto != nil {
return
}
file_keys_proto_init()
if !protoimpl.UnsafeEnabled {
file_ceremony_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CeremonyTranscript); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ceremony_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_ceremony_proto_goTypes,
DependencyIndexes: file_ceremony_proto_depIdxs,
MessageInfos: file_ceremony_proto_msgTypes,
}.Build()
File_ceremony_proto = out.File
file_ceremony_proto_rawDesc = nil
file_ceremony_proto_goTypes = nil
file_ceremony_proto_depIdxs = nil
}

View File

@ -0,0 +1,39 @@
syntax = "proto3";
package quilibrium.node.ceremony.pb;
option go_package = "source.quilibrium.com/quilibrium/monorepo/node/protobufs";
import "keys.proto";
// Describes the transcript of KZG ceremony execution
message CeremonyTranscript {
// The active collection of powers over G1
repeated quilibrium.node.keys.pb.BLS48581G1PublicKey g1_powers = 1;
// The active collection of powers over G2
repeated quilibrium.node.keys.pb.BLS48581G2PublicKey g2_powers = 2;
// The running s^256 G1 witnesses the choice of the 256th power is to ensure
// combinatorial birthday paradox-based attacks are not possible. In common
// KZG ceremonies, the collection of witnesses to PoT pubkeys produce the
// relationship of e(w*G1, s*G2) == (s'*G1, G2), where w*s == s'. The problem
// with this is that there are n powers under G2 (excl. the case where PoT
// ceremonies _only_ have the first G2 power), and so the chance of collision
// by combination to a target value for s' is feasible such that a sum of a
// permutation of valid G2 powers could forge witness values to reach a
// a desired outcome, as there are matching pairs of the G1 and G2 powers to
// permute. When the number of G2 powers is low, or one, this reduces to the
// discrete log assumption and so the only viable attack is of
// O(sqrt(<bit size>)) per Pollard's Rho (barring any advancements), but in
// many cases the number of G2 powers is high enough such that n! naive
// combinations of additions are greater (and cheap, since the additions are
// first tested in G1) than the required time of testing the discrete log,
// and combined with many generated target values, significantly reduces the
// amount of time required to complete the attack. This means that in
// traditional KZG ceremonies, the last contributor to a ceremony can
// potentially control the secret. Or, we can just track the witnesses to the
// highest power in the ceremony and avoid the whole problem. :)
repeated quilibrium.node.keys.pb.BLS48581G1PublicKey running_g1_256_witnesses = 3;
// The running s^256 G2 powers see notes on running_g1_256_witnesses for why
// we do this.
repeated quilibrium.node.keys.pb.BLS48581G2PublicKey running_g2_256_powers = 4;
}

1096
node/protobufs/channel.pb.go Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,181 @@
syntax = "proto3";
package quilibrium.node.channel.pb;
option go_package = "source.quilibrium.com/quilibrium/monorepo/node/protobufs";
import "keys.proto";
// Describes a general channel envelope for a message.
message P2PChannelEnvelope {
// A general protocol identifier as a uint32 this is expected to rarely
// iterate, and should be uniquely identifying both protocol and version.
// Pragmatically speaking, this implies that the least significant byte
// specifies version (which should iterate most minimally), and the three most
// significant bytes should specify protocol. Recipients SHOULD ignore
// messages with incompatible protocol identifiers, but also SHOULD warn on
// identifiers with versions higher than the supported protocol. A large
// number of unsupported protocol messages may indicate spam/some other
// attack, whereas a large number of unsupported protocol versions may
// indicate an out of date client, respective to which side is the maximum of
// the version number.
uint32 protocol_identifier = 1;
// The encrypted message header. Message header encryption is mandatory
// P2P channels in some cases pre-empt the mixnet and leaky information from
// unencrypted message headers could de-anonymize the recipient. It is thus
// also mandatory at the protocol implementation level that header sizes are
// consistent within a protocol so as to not leak metadata. An example of this
// is in Double and Triple-Ratchet, where the sequence identifiers MUST be
// encoded as fixed-length integers, as variable encoding can indicate a
// message being in the first 256, 65,536, etc. if an exchange is highly
// asymmetrical in sends/receives. This is especially critical in long
// running protocols with a need for fixed length messages (see message_body
// notes).
MessageCiphertext message_header = 2;
// The encrypted message body. Message bodies are variable length ciphertext
// could range widely, however if this metadata is pertinent to determining
// protocol state, such as knowing what round an encapsulated protocol is in,
// or potentially what might be transferred over the protocol, protocol
// implementers SHOULD utilize chunking and send fixed length messages.
// Additionally, if rounds themselves are highly asymmetric or have
// long-standing processing times that could dangerously leak information of
// round state, implementers SHOULD defer protocol use to leverage the mixnet.
// If this is not feasible, the implementation details are left up to the
// exercise of the protocol author.
MessageCiphertext message_body = 3;
}
// Describes a general ciphertext payload.
message MessageCiphertext {
// The intialization vector used for encryption. While cipher specific,
// typically this should be a unique value for every ciphertext. If this is
// not the case for a protocol where it should be, this SHOULD be considered
// an invalid message and warned, as it could either indicate compromise,
// or a faulty cryptographic implementation such as a faulty PKCS#11
// implementation that has a code path to handle HSM vendors which mandate
// zeroed IVs before passing into encryption methods, as they will update the
// IV within the HSM through hardware-supplied entropy.
bytes initialization_vector = 1;
// The raw ciphertext byte string. This will be cipher specific, however some
// general attributes are expected to be followed. If there is a common
// layout expected, such as AES-GCM having the GCM tag appended to the
// ciphertext, please follow the common layout.
bytes ciphertext = 2;
// The associated data byte string, if available. This will be highly protocol
// specific, but SHOULD NOT leak metadata.
bytes associated_data = 3;
}
// Describes the announcement of a new proving key.
message ProvingKeyAnnouncement {
// The commitment to a Schnorr proof of the Identity Key. The commitment is
// produced by taking a hash of the C and S components of the proof.
bytes identity_commitment = 1;
// The commitment to a Schnorr proof of the Signed Pre Key. The commitment is
// produced by taking a hash of the C and S components of the proof.
bytes prekey_commitment = 2;
oneof proving_key_signature {
quilibrium.node.keys.pb.Ed448Signature proving_key_signature_ed448 = 3;
}
}
// Represents a request for a proving key.
message ProvingKeyRequest {
bytes proving_key_bytes = 1;
}
// Describes the aggregation of inclusion commitments for a given clock frame
message InclusionAggregateProof {
// The filter in which the inclusion proof was produced.
bytes filter = 1;
// The frame number in which the inclusion proof was added.
uint64 frame_number = 2;
// The collection of inclusion commitments, in order.
repeated InclusionCommitment inclusion_commitments = 3;
// The raw serialized proof, mirroring the type of commitment scheme used
// within the inclusion proofs.
bytes proof = 4;
}
// Describes the commitment of a data's inclusion in a given clock frame
message InclusionCommitment {
// The filter in which the inclusion aggregate proof was produced.
bytes filter = 1;
// The frame number in which the inclusion aggregate proof was added.
uint64 frame_number = 2;
// The position of the data in the proof.
uint32 position = 3;
// The specific type url represented by the data.
string type_url = 4;
// The raw serialized data as incorporated into the inclusion proof. Due to
// the non-deterministic nature of protobuf serialization, this data is an
// opaque binary string so that inclusion proofs can be accurately assessed
// between various node implementations, and retain forwards-compatibility
// with additional properties in future revisions to types.
bytes data = 5;
// The raw serialized commitment. Similar to data, this commitment data is an
// opaque binary string so that future commitment types can be added without
// having to break the underlying inclusion structure.
bytes commitment = 6;
}
// Describes the announcement of both an identity key and signed pre key. This
// is expected to be used for the initial announcement of a key bundle, and
// subsequent full revocations if identity key and signed pre keys are both
// suspected of/known to be compromised. Signatures under KeyBundleAnnouncement
// are expected to be cross-signed, such that the signature on the identity key
// is produced through the prover key, the signature on the signed pre key is
// produced through the identity key. ProvingKeyAnnouncements may be repeated
// whenever a key bundle update is expected only the first proving key
// announcement is retained in inclusion proofs, but the announcements
// necessarily are required for key bundle updates, as they provide a commitment
// to the updated keys' Schnorr proofs. An updated KeyBundleAnnouncement must
// be captured in an inclusion proof before it may be used for communication
// channels, and may only be used in communication channels once a lobby has
// opened _after_ the inclusion proof. If a lobby is open during the time the
// inclusion proof has been created, the announcement is not yet considered
// valid.
message KeyBundleAnnouncement {
IdentityKey identity_key = 1;
SignedPreKey signed_pre_key = 2;
bytes proving_key_bytes = 3;
}
// Describes the Identity Key and corresponding Schnorr proof. Schnorr proofs
// are expected to mirror the EC parameters of the proving and identity key. If
// they do not, validation will fail.
message IdentityKey {
// The C component of the Schnorr proof, serialized as big endian.
bytes challenge = 1;
// The S component of the Schnorr proof, serialized as big endian.
bytes response = 2;
// The Statement component of the Schnorr proof, serialized as an (compressed,
// if possible) affine representation of the point.
bytes statement = 3;
oneof identity_key_signature {
quilibrium.node.keys.pb.Ed448Signature public_key_signature_ed448 = 4;
}
}
// Describes the Signed Pre Key and corresponding Schnorr proof. Schnorr proofs
// are expected to mirror the EC parameters of the identity and signed pre key.
// If they do not, validation will fail.
message SignedPreKey {
// The C component of the Schnorr proof, serialized as big endian.
bytes challenge = 1;
// The S component of the Schnorr proof, serialized as big endian.
bytes response = 2;
// The Statement component of the Schnorr proof, serialized as an (compressed,
// if possible) affine representation of the point.
bytes statement = 3;
oneof signed_pre_key_signature {
quilibrium.node.keys.pb.Ed448Signature public_key_signature_ed448 = 4;
}
}

219
node/protobufs/clock.go Normal file
View File

@ -0,0 +1,219 @@
package protobufs
import (
"encoding/binary"
"math/big"
"time"
"github.com/iden3/go-iden3-crypto/ff"
"github.com/iden3/go-iden3-crypto/poseidon"
"github.com/pkg/errors"
"golang.org/x/crypto/sha3"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/vdf"
)
func ProveMasterClockFrame(
previousFrame *ClockFrame,
difficulty uint32,
) (*ClockFrame, error) {
input := []byte{}
input = append(input, previousFrame.Filter...)
input = binary.BigEndian.AppendUint64(input, previousFrame.FrameNumber+1)
input = binary.BigEndian.AppendUint32(input, difficulty)
input = append(input, previousFrame.Output[:]...)
b := sha3.Sum256(input)
v := vdf.New(difficulty, b)
v.Execute()
o := v.GetOutput()
timestamp := time.Now().UnixMilli()
previousSelectorBytes := [516]byte{}
copy(previousSelectorBytes[:], previousFrame.Output[:516])
parent, err := poseidon.HashBytes(previousSelectorBytes[:])
if err != nil {
return nil, errors.Wrap(err, "prove clock frame")
}
frame := &ClockFrame{
Filter: previousFrame.Filter,
FrameNumber: previousFrame.FrameNumber + 1,
Timestamp: timestamp,
Difficulty: difficulty,
ParentSelector: parent.Bytes(),
Input: previousFrame.Output,
AggregateProofs: []*InclusionAggregateProof{},
Output: o[:],
}
return frame, nil
}
func (frame *ClockFrame) VerifyMasterClockFrame() error {
input := []byte{}
input = append(input, frame.Filter...)
input = binary.BigEndian.AppendUint64(input, frame.FrameNumber)
input = binary.BigEndian.AppendUint32(input, frame.Difficulty)
input = append(input, frame.Input...)
if len(frame.Input) < 516 {
return errors.Wrap(
errors.New("invalid input"),
"verify clock frame",
)
}
if len(frame.AggregateProofs) > 0 {
return errors.Wrap(
errors.New("invalid input"),
"verify clock frame",
)
}
if frame.PublicKeySignature != nil {
return errors.Wrap(
errors.New("invalid input"),
"verify clock frame",
)
}
if len(frame.Input) != 516 {
return errors.Wrap(
errors.New("invalid input"),
"verify clock frame",
)
}
b := sha3.Sum256(input)
v := vdf.New(frame.Difficulty, b)
proof := [516]byte{}
copy(proof[:], frame.Output)
if !v.Verify(proof) {
return errors.Wrap(
errors.New("invalid proof"),
"verify clock frame",
)
}
previousSelectorBytes := [516]byte{}
copy(previousSelectorBytes[:], frame.Input[:516])
parent, err := poseidon.HashBytes(previousSelectorBytes[:])
if err != nil {
return errors.Wrap(err, "verify clock frame")
}
selector := new(big.Int).SetBytes(frame.ParentSelector)
if parent.Cmp(selector) != 0 {
return errors.Wrap(
errors.New("selector did not match input"),
"verify clock frame",
)
}
return nil
}
func (frame *ClockFrame) GetParentSelectorAndDistance() (
*big.Int,
*big.Int,
*big.Int,
error,
) {
outputBytes := [516]byte{}
copy(outputBytes[:], frame.Output[:516])
selector, err := poseidon.HashBytes(outputBytes[:])
if err != nil {
return nil, nil, nil, errors.Wrap(err, "get parent selector and distance")
}
if frame.FrameNumber == 0 {
return big.NewInt(0), big.NewInt(0), selector, nil
}
parentSelector := new(big.Int).SetBytes(frame.ParentSelector)
pubkey := []byte{}
ed448PublicKey := frame.GetPublicKeySignatureEd448()
if ed448PublicKey != nil {
pubkey = ed448PublicKey.PublicKey.KeyValue
} else {
return nil, nil, nil, errors.Wrap(
errors.New("no valid signature provided"),
"get parent selector and distance",
)
}
discriminator, err := poseidon.HashBytes(pubkey)
if err != nil {
return nil, nil, nil, errors.Wrap(err, "get parent selector and distance")
}
l := new(big.Int).Mod(new(big.Int).Sub(selector, discriminator), ff.Modulus())
r := new(big.Int).Mod(new(big.Int).Sub(discriminator, selector), ff.Modulus())
distance := r
if l.Cmp(r) == -1 {
distance = l
}
return parentSelector, distance, selector, nil
}
func (frame *ClockFrame) GetSelector() (*big.Int, error) {
outputBytes := [516]byte{}
copy(outputBytes[:], frame.Output[:516])
selector, err := poseidon.HashBytes(outputBytes[:])
if err != nil {
return nil, errors.Wrap(err, "get selector")
}
return selector, nil
}
func (frame *ClockFrame) GetPublicKey() ([]byte, error) {
if frame.FrameNumber == 0 {
return make([]byte, 32), nil
}
pubkey := []byte{}
ed448PublicKey := frame.GetPublicKeySignatureEd448()
if ed448PublicKey != nil {
pubkey = ed448PublicKey.PublicKey.KeyValue
} else {
return nil, errors.Wrap(
errors.New("no valid signature provided"),
"get address",
)
}
return pubkey, nil
}
func (frame *ClockFrame) GetAddress() ([]byte, error) {
if frame.FrameNumber == 0 {
return make([]byte, 32), nil
}
pubkey := []byte{}
ed448PublicKey := frame.GetPublicKeySignatureEd448()
if ed448PublicKey != nil {
pubkey = ed448PublicKey.PublicKey.KeyValue
} else {
return nil, errors.Wrap(
errors.New("no valid signature provided"),
"get address",
)
}
address, err := poseidon.HashBytes(pubkey)
if err != nil {
return nil, errors.Wrap(err, "get parent selector and distance")
}
addressBytes := address.Bytes()
addressBytes = append(make([]byte, 32-len(addressBytes)), addressBytes...)
return addressBytes, nil
}

502
node/protobufs/clock.pb.go Normal file
View File

@ -0,0 +1,502 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.30.0
// protoc v3.21.12
// source: clock.proto
package protobufs
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// Represents a clock frame for a given filter. Clock frames are the primary
// sequencing mechanism upon which the network derives consensus. As the master
// pulse clock, this provides deterministic but random leader election. At the
// data pulse clock level, this provides the same, within a quorum for data
// sequencers.
type ClockFrame struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The filter is used as a domain separator for input, but in the context of
// verifiable delay functions, is simply prepended to the input field as input
// for the VDF.
Filter []byte `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"`
// A strictly monotonically-increasing frame number. Used for culling old
// frames past a configurable cutoff point.
FrameNumber uint64 `protobuf:"varint,2,opt,name=frame_number,json=frameNumber,proto3" json:"frame_number,omitempty"`
// The self-reported timestamp from the proof publisher, encoded as an int64
// of the Unix epoch in milliseconds. Should be good until
// 292278994-08-17 07:12:55.807, at which point, this is someone else's
// problem. Timestamps are imperfect, but smoothed in a rolling window to
// ensure a network and quorum-stable difficulty adjustment. Anomalies are
// bounded such that a timestamp beyond ten times the average issuance rate
// is discarded in preference to the runner up electees, unless there is
// simply no alternative available (for example, if a network outage occurred
// from an upgrade or bug).
Timestamp int64 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
// The difficulty level used for the frame. Difficulty is calculated based on
// the previous 60 timestamps correlated with difficulties, such that the
// interval smooths out to align to the type-defined rate. This is expected to
// increase subtly with clock speed and future hardware implementations, but
// due to incentive alignment associated with data proofs, not fastest clock
// in the west, should be gradual.
Difficulty uint32 `protobuf:"varint,4,opt,name=difficulty,proto3" json:"difficulty,omitempty"`
// The selector value of the previous frame's output, produced as a Poseidon
// hash of the output.
ParentSelector []byte `protobuf:"bytes,5,opt,name=parent_selector,json=parentSelector,proto3" json:"parent_selector,omitempty"`
// The input data used for the VDF proof. For the master pulse clock, this is
// the concatenation of the filter, frame number, difficulty, previous frame's
// output, and the rolled state proof commitment input. For the data pulse
// clocks, this is the concatenation of the filter, frame number, timestamp,
// difficulty, issuer address, previous frame's output, along with data
// mutation and availability proofs. Elements that are also in the fields of
// the clock frame are not included in this field due to redundancy. For the
// ceremony phase, this is a singular clock fusing master and data pulses.
Input []byte `protobuf:"bytes,6,opt,name=input,proto3" json:"input,omitempty"`
// The output data from the VDF, serialized as bytes. For Wesolowski, this is
// an encoding of the 258 byte Y value concatenated with the 258 byte proof
// value.
Output []byte `protobuf:"bytes,7,opt,name=output,proto3" json:"output,omitempty"`
// Any aggregate proofs to be rolled into the committed clock frame.
AggregateProofs []*InclusionAggregateProof `protobuf:"bytes,8,rep,name=aggregate_proofs,json=aggregateProofs,proto3" json:"aggregate_proofs,omitempty"`
// The signature of the proof issuer.
//
// Types that are assignable to PublicKeySignature:
//
// *ClockFrame_PublicKeySignatureEd448
PublicKeySignature isClockFrame_PublicKeySignature `protobuf_oneof:"public_key_signature"`
}
func (x *ClockFrame) Reset() {
*x = ClockFrame{}
if protoimpl.UnsafeEnabled {
mi := &file_clock_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ClockFrame) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ClockFrame) ProtoMessage() {}
func (x *ClockFrame) ProtoReflect() protoreflect.Message {
mi := &file_clock_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ClockFrame.ProtoReflect.Descriptor instead.
func (*ClockFrame) Descriptor() ([]byte, []int) {
return file_clock_proto_rawDescGZIP(), []int{0}
}
func (x *ClockFrame) GetFilter() []byte {
if x != nil {
return x.Filter
}
return nil
}
func (x *ClockFrame) GetFrameNumber() uint64 {
if x != nil {
return x.FrameNumber
}
return 0
}
func (x *ClockFrame) GetTimestamp() int64 {
if x != nil {
return x.Timestamp
}
return 0
}
func (x *ClockFrame) GetDifficulty() uint32 {
if x != nil {
return x.Difficulty
}
return 0
}
func (x *ClockFrame) GetParentSelector() []byte {
if x != nil {
return x.ParentSelector
}
return nil
}
func (x *ClockFrame) GetInput() []byte {
if x != nil {
return x.Input
}
return nil
}
func (x *ClockFrame) GetOutput() []byte {
if x != nil {
return x.Output
}
return nil
}
func (x *ClockFrame) GetAggregateProofs() []*InclusionAggregateProof {
if x != nil {
return x.AggregateProofs
}
return nil
}
func (m *ClockFrame) GetPublicKeySignature() isClockFrame_PublicKeySignature {
if m != nil {
return m.PublicKeySignature
}
return nil
}
func (x *ClockFrame) GetPublicKeySignatureEd448() *Ed448Signature {
if x, ok := x.GetPublicKeySignature().(*ClockFrame_PublicKeySignatureEd448); ok {
return x.PublicKeySignatureEd448
}
return nil
}
type isClockFrame_PublicKeySignature interface {
isClockFrame_PublicKeySignature()
}
type ClockFrame_PublicKeySignatureEd448 struct {
PublicKeySignatureEd448 *Ed448Signature `protobuf:"bytes,9,opt,name=public_key_signature_ed448,json=publicKeySignatureEd448,proto3,oneof"`
}
func (*ClockFrame_PublicKeySignatureEd448) isClockFrame_PublicKeySignature() {}
// Represents a request for a range of clock frames. Used to stay synchronized
// to the latest state.
type ClockFramesRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The filter is used as a domain separator for input to the frames.
Filter []byte `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"`
// The earliest frame in the range requested.
FromFrameNumber uint64 `protobuf:"varint,2,opt,name=from_frame_number,json=fromFrameNumber,proto3" json:"from_frame_number,omitempty"`
// The latest frame in the range requested, if provided. Capped to a maximum
// size of 128 frames.
ToFrameNumber uint64 `protobuf:"varint,3,opt,name=to_frame_number,json=toFrameNumber,proto3" json:"to_frame_number,omitempty"`
}
func (x *ClockFramesRequest) Reset() {
*x = ClockFramesRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_clock_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ClockFramesRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ClockFramesRequest) ProtoMessage() {}
func (x *ClockFramesRequest) ProtoReflect() protoreflect.Message {
mi := &file_clock_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ClockFramesRequest.ProtoReflect.Descriptor instead.
func (*ClockFramesRequest) Descriptor() ([]byte, []int) {
return file_clock_proto_rawDescGZIP(), []int{1}
}
func (x *ClockFramesRequest) GetFilter() []byte {
if x != nil {
return x.Filter
}
return nil
}
func (x *ClockFramesRequest) GetFromFrameNumber() uint64 {
if x != nil {
return x.FromFrameNumber
}
return 0
}
func (x *ClockFramesRequest) GetToFrameNumber() uint64 {
if x != nil {
return x.ToFrameNumber
}
return 0
}
// Represents a response for a range of clock frames. Used to stay synchronized
// to the latest state.
type ClockFramesResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The filter is used as a domain separator for input to the frames.
Filter []byte `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"`
// The earliest frame in the range response. Paginated to a maximum size of
// 128 frames per response.
FromFrameNumber uint64 `protobuf:"varint,2,opt,name=from_frame_number,json=fromFrameNumber,proto3" json:"from_frame_number,omitempty"`
// The latest frame in the range response.
ToFrameNumber uint64 `protobuf:"varint,3,opt,name=to_frame_number,json=toFrameNumber,proto3" json:"to_frame_number,omitempty"`
// The set of clock frames within the provided range.
ClockFrames []*ClockFrame `protobuf:"bytes,4,rep,name=clock_frames,json=clockFrames,proto3" json:"clock_frames,omitempty"`
}
func (x *ClockFramesResponse) Reset() {
*x = ClockFramesResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_clock_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ClockFramesResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ClockFramesResponse) ProtoMessage() {}
func (x *ClockFramesResponse) ProtoReflect() protoreflect.Message {
mi := &file_clock_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ClockFramesResponse.ProtoReflect.Descriptor instead.
func (*ClockFramesResponse) Descriptor() ([]byte, []int) {
return file_clock_proto_rawDescGZIP(), []int{2}
}
func (x *ClockFramesResponse) GetFilter() []byte {
if x != nil {
return x.Filter
}
return nil
}
func (x *ClockFramesResponse) GetFromFrameNumber() uint64 {
if x != nil {
return x.FromFrameNumber
}
return 0
}
func (x *ClockFramesResponse) GetToFrameNumber() uint64 {
if x != nil {
return x.ToFrameNumber
}
return 0
}
func (x *ClockFramesResponse) GetClockFrames() []*ClockFrame {
if x != nil {
return x.ClockFrames
}
return nil
}
var File_clock_proto protoreflect.FileDescriptor
var file_clock_proto_rawDesc = []byte{
0x0a, 0x0b, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x71,
0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63,
0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x62, 0x1a, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0a, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x22, 0xbc, 0x03, 0x0a, 0x0a, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d,
0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x61,
0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
0x0b, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09,
0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69,
0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a,
0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x61,
0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63,
0x74, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x06, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74,
0x70, 0x75, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75,
0x74, 0x12, 0x5e, 0x0a, 0x10, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x70,
0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x71, 0x75,
0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x68,
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69,
0x6f, 0x6e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66,
0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66,
0x73, 0x12, 0x66, 0x0a, 0x1a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f,
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x65, 0x64, 0x34, 0x34, 0x38, 0x18,
0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69,
0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x70, 0x62, 0x2e,
0x45, 0x64, 0x34, 0x34, 0x38, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00,
0x52, 0x17, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61,
0x74, 0x75, 0x72, 0x65, 0x45, 0x64, 0x34, 0x34, 0x38, 0x42, 0x16, 0x0a, 0x14, 0x70, 0x75, 0x62,
0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
0x65, 0x22, 0x80, 0x01, 0x0a, 0x12, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74,
0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
0x12, 0x2a, 0x0a, 0x11, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e,
0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x66, 0x72, 0x6f,
0x6d, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f,
0x74, 0x6f, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18,
0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75,
0x6d, 0x62, 0x65, 0x72, 0x22, 0xca, 0x01, 0x0a, 0x13, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72,
0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06,
0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69,
0x6c, 0x74, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x11, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x66, 0x72, 0x61,
0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
0x0f, 0x66, 0x72, 0x6f, 0x6d, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72,
0x12, 0x26, 0x0a, 0x0f, 0x74, 0x6f, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d,
0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x46, 0x72, 0x61,
0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x47, 0x0a, 0x0c, 0x63, 0x6c, 0x6f, 0x63,
0x6b, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24,
0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65,
0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46,
0x72, 0x61, 0x6d, 0x65, 0x52, 0x0b, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x73, 0x42, 0x3a, 0x5a, 0x38, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x71, 0x75, 0x69, 0x6c,
0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x71, 0x75, 0x69, 0x6c, 0x69,
0x62, 0x72, 0x69, 0x75, 0x6d, 0x2f, 0x6d, 0x6f, 0x6e, 0x6f, 0x72, 0x65, 0x70, 0x6f, 0x2f, 0x6e,
0x6f, 0x64, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x73, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_clock_proto_rawDescOnce sync.Once
file_clock_proto_rawDescData = file_clock_proto_rawDesc
)
func file_clock_proto_rawDescGZIP() []byte {
file_clock_proto_rawDescOnce.Do(func() {
file_clock_proto_rawDescData = protoimpl.X.CompressGZIP(file_clock_proto_rawDescData)
})
return file_clock_proto_rawDescData
}
var file_clock_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_clock_proto_goTypes = []interface{}{
(*ClockFrame)(nil), // 0: quilibrium.node.clock.pb.ClockFrame
(*ClockFramesRequest)(nil), // 1: quilibrium.node.clock.pb.ClockFramesRequest
(*ClockFramesResponse)(nil), // 2: quilibrium.node.clock.pb.ClockFramesResponse
(*InclusionAggregateProof)(nil), // 3: quilibrium.node.channel.pb.InclusionAggregateProof
(*Ed448Signature)(nil), // 4: quilibrium.node.keys.pb.Ed448Signature
}
var file_clock_proto_depIdxs = []int32{
3, // 0: quilibrium.node.clock.pb.ClockFrame.aggregate_proofs:type_name -> quilibrium.node.channel.pb.InclusionAggregateProof
4, // 1: quilibrium.node.clock.pb.ClockFrame.public_key_signature_ed448:type_name -> quilibrium.node.keys.pb.Ed448Signature
0, // 2: quilibrium.node.clock.pb.ClockFramesResponse.clock_frames:type_name -> quilibrium.node.clock.pb.ClockFrame
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_clock_proto_init() }
func file_clock_proto_init() {
if File_clock_proto != nil {
return
}
file_channel_proto_init()
file_keys_proto_init()
if !protoimpl.UnsafeEnabled {
file_clock_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ClockFrame); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_clock_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ClockFramesRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_clock_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ClockFramesResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_clock_proto_msgTypes[0].OneofWrappers = []interface{}{
(*ClockFrame_PublicKeySignatureEd448)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_clock_proto_rawDesc,
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_clock_proto_goTypes,
DependencyIndexes: file_clock_proto_depIdxs,
MessageInfos: file_clock_proto_msgTypes,
}.Build()
File_clock_proto = out.File
file_clock_proto_rawDesc = nil
file_clock_proto_goTypes = nil
file_clock_proto_depIdxs = nil
}

View File

@ -0,0 +1,88 @@
syntax = "proto3";
package quilibrium.node.clock.pb;
option go_package = "source.quilibrium.com/quilibrium/monorepo/node/protobufs";
import "channel.proto";
import "keys.proto";
// Represents a clock frame for a given filter. Clock frames are the primary
// sequencing mechanism upon which the network derives consensus. As the master
// pulse clock, this provides deterministic but random leader election. At the
// data pulse clock level, this provides the same, within a quorum for data
// sequencers.
message ClockFrame {
// The filter is used as a domain separator for input, but in the context of
// verifiable delay functions, is simply prepended to the input field as input
// for the VDF.
bytes filter = 1;
// A strictly monotonically-increasing frame number. Used for culling old
// frames past a configurable cutoff point.
uint64 frame_number = 2;
// The self-reported timestamp from the proof publisher, encoded as an int64
// of the Unix epoch in milliseconds. Should be good until
// 292278994-08-17 07:12:55.807, at which point, this is someone else's
// problem. Timestamps are imperfect, but smoothed in a rolling window to
// ensure a network and quorum-stable difficulty adjustment. Anomalies are
// bounded such that a timestamp beyond ten times the average issuance rate
// is discarded in preference to the runner up electees, unless there is
// simply no alternative available (for example, if a network outage occurred
// from an upgrade or bug).
int64 timestamp = 3;
// The difficulty level used for the frame. Difficulty is calculated based on
// the previous 60 timestamps correlated with difficulties, such that the
// interval smooths out to align to the type-defined rate. This is expected to
// increase subtly with clock speed and future hardware implementations, but
// due to incentive alignment associated with data proofs, not fastest clock
// in the west, should be gradual.
uint32 difficulty = 4;
// The selector value of the previous frame's output, produced as a Poseidon
// hash of the output.
bytes parent_selector = 5;
// The input data used for the VDF proof. For the master pulse clock, this is
// the concatenation of the filter, frame number, difficulty, previous frame's
// output, and the rolled state proof commitment input. For the data pulse
// clocks, this is the concatenation of the filter, frame number, timestamp,
// difficulty, issuer address, previous frame's output, along with data
// mutation and availability proofs. Elements that are also in the fields of
// the clock frame are not included in this field due to redundancy. For the
// ceremony phase, this is a singular clock fusing master and data pulses.
bytes input = 6;
// The output data from the VDF, serialized as bytes. For Wesolowski, this is
// an encoding of the 258 byte Y value concatenated with the 258 byte proof
// value.
bytes output = 7;
// Any aggregate proofs to be rolled into the committed clock frame.
repeated quilibrium.node.channel.pb.InclusionAggregateProof aggregate_proofs = 8;
// The signature of the proof issuer.
oneof public_key_signature {
quilibrium.node.keys.pb.Ed448Signature public_key_signature_ed448 = 9;
}
}
// Represents a request for a range of clock frames. Used to stay synchronized
// to the latest state.
message ClockFramesRequest {
// The filter is used as a domain separator for input to the frames.
bytes filter = 1;
// The earliest frame in the range requested.
uint64 from_frame_number = 2;
// The latest frame in the range requested, if provided. Capped to a maximum
// size of 128 frames.
uint64 to_frame_number = 3;
}
// Represents a response for a range of clock frames. Used to stay synchronized
// to the latest state.
message ClockFramesResponse {
// The filter is used as a domain separator for input to the frames.
bytes filter = 1;
// The earliest frame in the range response. Paginated to a maximum size of
// 128 frames per response.
uint64 from_frame_number = 2;
// The latest frame in the range response.
uint64 to_frame_number = 3;
// The set of clock frames within the provided range.
repeated ClockFrame clock_frames = 4;
}

216
node/protobufs/keys.go Normal file
View File

@ -0,0 +1,216 @@
package protobufs
import (
"golang.org/x/crypto/sha3"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/zkp/schnorr"
"github.com/cloudflare/circl/sign/ed448"
"github.com/pkg/errors"
)
func (p *ProvingKeyAnnouncement) Verify() error {
if p.ProvingKeySignature == nil {
return errors.Wrap(errors.New("proving key signature nil"), "verify")
}
msg := append(
append([]byte{}, p.IdentityCommitment...),
p.PrekeyCommitment...,
)
switch k := p.ProvingKeySignature.(type) {
case *ProvingKeyAnnouncement_ProvingKeySignatureEd448:
return k.ProvingKeySignatureEd448.Verify(msg)
default:
return errors.Wrap(errors.New("unsupported signature type"), "verify")
}
}
func (p *ProvingKeyAnnouncement) PublicKey() []byte {
switch k := p.ProvingKeySignature.(type) {
case *ProvingKeyAnnouncement_ProvingKeySignatureEd448:
return k.ProvingKeySignatureEd448.PublicKey.KeyValue
default:
return nil
}
}
func (k *KeyBundleAnnouncement) Verify(
provingKey *ProvingKeyAnnouncement,
) error {
var curve *curves.Curve
if k.IdentityKey == nil {
return errors.Wrap(errors.New("identity key is nil"), "verify")
}
if k.IdentityKey.IdentityKeySignature == nil {
return errors.Wrap(errors.New("identity key signature is nil"), "verify")
}
if k.SignedPreKey == nil {
return errors.Wrap(errors.New("signed pre key is nil"), "verify")
}
if k.SignedPreKey.SignedPreKeySignature == nil {
return errors.Wrap(errors.New("signed pre key signature is nil"), "verify")
}
switch s := k.IdentityKey.IdentityKeySignature.(type) {
case *IdentityKey_PublicKeySignatureEd448:
err := s.PublicKeySignatureEd448.VerifyCrossSigned(
k.ProvingKeyBytes,
)
if err != nil {
return err
}
v := k.SignedPreKey.SignedPreKeySignature
spk := v.(*SignedPreKey_PublicKeySignatureEd448)
if spk == nil {
return errors.Wrap(errors.New("curve mismatch"), "verify")
}
err = spk.PublicKeySignatureEd448.VerifyCrossSigned(
k.ProvingKeyBytes,
)
if err != nil {
return err
}
curve = curves.ED448()
}
idkc, err := curve.NewScalar().SetBytes(k.IdentityKey.Challenge)
if err != nil {
return errors.Wrap(
errors.Wrap(err, "challenge invalid"),
"verify",
)
}
idks, err := curve.NewScalar().SetBytes(k.IdentityKey.Response)
if err != nil {
return errors.Wrap(
errors.Wrap(err, "response invalid"),
"verify",
)
}
idkStatement, err := curve.NewGeneratorPoint().FromAffineCompressed(
k.IdentityKey.Statement,
)
if err != nil {
return errors.Wrap(
errors.Wrap(err, "statement invalid"),
"verify",
)
}
spkc, err := curve.NewScalar().SetBytes(k.SignedPreKey.Challenge)
if err != nil {
return errors.Wrap(
errors.Wrap(err, "challenge invalid"),
"verify",
)
}
spks, err := curve.NewScalar().SetBytes(k.SignedPreKey.Response)
if err != nil {
return errors.Wrap(
errors.Wrap(err, "response invalid"),
"verify",
)
}
spkStatement, err := curve.NewGeneratorPoint().FromAffineCompressed(
k.SignedPreKey.Statement,
)
if err != nil {
return errors.Wrap(
errors.Wrap(err, "statement invalid"),
"verify",
)
}
if err := schnorr.DecommitVerify(
&schnorr.Proof{
Statement: idkStatement,
C: idkc,
S: idks,
},
provingKey.IdentityCommitment,
curve,
sha3.New256(),
curve.NewGeneratorPoint(),
[]byte{},
); err != nil {
return errors.Wrap(err, "verify")
}
if err := schnorr.DecommitVerify(
&schnorr.Proof{
Statement: spkStatement,
C: spkc,
S: spks,
},
provingKey.PrekeyCommitment,
curve,
sha3.New256(),
curve.NewGeneratorPoint(),
[]byte{},
); err != nil {
return errors.Wrap(err, "verify")
}
return nil
}
func (s *Ed448Signature) Verify(msg []byte) error {
if s.PublicKey == nil {
return errors.Wrap(errors.New("public key nil"), "verify")
}
if s.Signature == nil {
return errors.Wrap(errors.New("signature nil"), "verify")
}
if len(s.PublicKey.KeyValue) != 57 {
return errors.Wrap(errors.New("invalid length for public key"), "verify")
}
if len(s.Signature) != 114 {
return errors.Wrap(errors.New("invalid length for signature"), "verify")
}
if !ed448.Verify(s.PublicKey.KeyValue, msg, s.Signature, "") {
return errors.Wrap(errors.New("invalid signature for public key"), "verify")
}
return nil
}
func (s *Ed448Signature) VerifyCrossSigned(
publicKey []byte,
) error {
if s.PublicKey == nil {
return errors.Wrap(errors.New("public key nil"), "verify")
}
if s.Signature == nil {
return errors.Wrap(errors.New("signature nil"), "verify")
}
if len(s.PublicKey.KeyValue) != 57 {
return errors.Wrap(errors.New("invalid length for public key"), "verify")
}
if len(s.Signature) != 114 {
return errors.Wrap(errors.New("invalid length for signature"), "verify")
}
if !ed448.Verify(publicKey, s.PublicKey.KeyValue, s.Signature, "") {
return errors.Wrap(errors.New("invalid signature for public key"), "verify")
}
return nil
}

871
node/protobufs/keys.pb.go Normal file
View File

@ -0,0 +1,871 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.30.0
// protoc v3.21.12
// source: keys.proto
package protobufs
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// Describes a raw Ed448 public key
type Ed448PublicKey struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KeyValue []byte `protobuf:"bytes,1,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` // 57 byte value
}
func (x *Ed448PublicKey) Reset() {
*x = Ed448PublicKey{}
if protoimpl.UnsafeEnabled {
mi := &file_keys_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Ed448PublicKey) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Ed448PublicKey) ProtoMessage() {}
func (x *Ed448PublicKey) ProtoReflect() protoreflect.Message {
mi := &file_keys_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Ed448PublicKey.ProtoReflect.Descriptor instead.
func (*Ed448PublicKey) Descriptor() ([]byte, []int) {
return file_keys_proto_rawDescGZIP(), []int{0}
}
func (x *Ed448PublicKey) GetKeyValue() []byte {
if x != nil {
return x.KeyValue
}
return nil
}
// Describes a raw Ed448 private key notably this is post-derivation,
// not the seed.
type Ed448PrivateKey struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KeyValue []byte `protobuf:"bytes,1,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` // 57 byte value
PublicKey *Ed448PublicKey `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
}
func (x *Ed448PrivateKey) Reset() {
*x = Ed448PrivateKey{}
if protoimpl.UnsafeEnabled {
mi := &file_keys_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Ed448PrivateKey) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Ed448PrivateKey) ProtoMessage() {}
func (x *Ed448PrivateKey) ProtoReflect() protoreflect.Message {
mi := &file_keys_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Ed448PrivateKey.ProtoReflect.Descriptor instead.
func (*Ed448PrivateKey) Descriptor() ([]byte, []int) {
return file_keys_proto_rawDescGZIP(), []int{1}
}
func (x *Ed448PrivateKey) GetKeyValue() []byte {
if x != nil {
return x.KeyValue
}
return nil
}
func (x *Ed448PrivateKey) GetPublicKey() *Ed448PublicKey {
if x != nil {
return x.PublicKey
}
return nil
}
// Describes a raw Ed448 signature
type Ed448Signature struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` // 114 byte value
PublicKey *Ed448PublicKey `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
}
func (x *Ed448Signature) Reset() {
*x = Ed448Signature{}
if protoimpl.UnsafeEnabled {
mi := &file_keys_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Ed448Signature) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Ed448Signature) ProtoMessage() {}
func (x *Ed448Signature) ProtoReflect() protoreflect.Message {
mi := &file_keys_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Ed448Signature.ProtoReflect.Descriptor instead.
func (*Ed448Signature) Descriptor() ([]byte, []int) {
return file_keys_proto_rawDescGZIP(), []int{2}
}
func (x *Ed448Signature) GetSignature() []byte {
if x != nil {
return x.Signature
}
return nil
}
func (x *Ed448Signature) GetPublicKey() *Ed448PublicKey {
if x != nil {
return x.PublicKey
}
return nil
}
// Describes a raw X448 public key
type X448PublicKey struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KeyValue []byte `protobuf:"bytes,1,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` // 57 byte value
}
func (x *X448PublicKey) Reset() {
*x = X448PublicKey{}
if protoimpl.UnsafeEnabled {
mi := &file_keys_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *X448PublicKey) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*X448PublicKey) ProtoMessage() {}
func (x *X448PublicKey) ProtoReflect() protoreflect.Message {
mi := &file_keys_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use X448PublicKey.ProtoReflect.Descriptor instead.
func (*X448PublicKey) Descriptor() ([]byte, []int) {
return file_keys_proto_rawDescGZIP(), []int{3}
}
func (x *X448PublicKey) GetKeyValue() []byte {
if x != nil {
return x.KeyValue
}
return nil
}
// Describes a raw X448 private key notably this is post-derivation,
// not the seed.
type X448PrivateKey struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KeyValue []byte `protobuf:"bytes,1,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` // 57 byte value
PublicKey *X448PublicKey `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
}
func (x *X448PrivateKey) Reset() {
*x = X448PrivateKey{}
if protoimpl.UnsafeEnabled {
mi := &file_keys_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *X448PrivateKey) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*X448PrivateKey) ProtoMessage() {}
func (x *X448PrivateKey) ProtoReflect() protoreflect.Message {
mi := &file_keys_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use X448PrivateKey.ProtoReflect.Descriptor instead.
func (*X448PrivateKey) Descriptor() ([]byte, []int) {
return file_keys_proto_rawDescGZIP(), []int{4}
}
func (x *X448PrivateKey) GetKeyValue() []byte {
if x != nil {
return x.KeyValue
}
return nil
}
func (x *X448PrivateKey) GetPublicKey() *X448PublicKey {
if x != nil {
return x.PublicKey
}
return nil
}
// Describes a raw PCAS public key
type PCASPublicKey struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KeyValue []byte `protobuf:"bytes,1,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` // 256 kilobyte value
}
func (x *PCASPublicKey) Reset() {
*x = PCASPublicKey{}
if protoimpl.UnsafeEnabled {
mi := &file_keys_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PCASPublicKey) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PCASPublicKey) ProtoMessage() {}
func (x *PCASPublicKey) ProtoReflect() protoreflect.Message {
mi := &file_keys_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PCASPublicKey.ProtoReflect.Descriptor instead.
func (*PCASPublicKey) Descriptor() ([]byte, []int) {
return file_keys_proto_rawDescGZIP(), []int{5}
}
func (x *PCASPublicKey) GetKeyValue() []byte {
if x != nil {
return x.KeyValue
}
return nil
}
// Describes a raw PCAS private key
type PCASPrivateKey struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KeyValue []byte `protobuf:"bytes,1,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` // 256 byte value
PublicKey *PCASPublicKey `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
}
func (x *PCASPrivateKey) Reset() {
*x = PCASPrivateKey{}
if protoimpl.UnsafeEnabled {
mi := &file_keys_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PCASPrivateKey) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PCASPrivateKey) ProtoMessage() {}
func (x *PCASPrivateKey) ProtoReflect() protoreflect.Message {
mi := &file_keys_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PCASPrivateKey.ProtoReflect.Descriptor instead.
func (*PCASPrivateKey) Descriptor() ([]byte, []int) {
return file_keys_proto_rawDescGZIP(), []int{6}
}
func (x *PCASPrivateKey) GetKeyValue() []byte {
if x != nil {
return x.KeyValue
}
return nil
}
func (x *PCASPrivateKey) GetPublicKey() *PCASPublicKey {
if x != nil {
return x.PublicKey
}
return nil
}
// Describes a raw compressed BLS48-581 G1 public key
type BLS48581G1PublicKey struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KeyValue []byte `protobuf:"bytes,1,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` // 74 byte value
}
func (x *BLS48581G1PublicKey) Reset() {
*x = BLS48581G1PublicKey{}
if protoimpl.UnsafeEnabled {
mi := &file_keys_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BLS48581G1PublicKey) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BLS48581G1PublicKey) ProtoMessage() {}
func (x *BLS48581G1PublicKey) ProtoReflect() protoreflect.Message {
mi := &file_keys_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BLS48581G1PublicKey.ProtoReflect.Descriptor instead.
func (*BLS48581G1PublicKey) Descriptor() ([]byte, []int) {
return file_keys_proto_rawDescGZIP(), []int{7}
}
func (x *BLS48581G1PublicKey) GetKeyValue() []byte {
if x != nil {
return x.KeyValue
}
return nil
}
// Describes a raw BLS48-581 private key, with corresponding G1 public key
type BLS48581G1PrivateKey struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KeyValue []byte `protobuf:"bytes,1,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` // 73 byte value
PublicKey *BLS48581G1PublicKey `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
}
func (x *BLS48581G1PrivateKey) Reset() {
*x = BLS48581G1PrivateKey{}
if protoimpl.UnsafeEnabled {
mi := &file_keys_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BLS48581G1PrivateKey) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BLS48581G1PrivateKey) ProtoMessage() {}
func (x *BLS48581G1PrivateKey) ProtoReflect() protoreflect.Message {
mi := &file_keys_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BLS48581G1PrivateKey.ProtoReflect.Descriptor instead.
func (*BLS48581G1PrivateKey) Descriptor() ([]byte, []int) {
return file_keys_proto_rawDescGZIP(), []int{8}
}
func (x *BLS48581G1PrivateKey) GetKeyValue() []byte {
if x != nil {
return x.KeyValue
}
return nil
}
func (x *BLS48581G1PrivateKey) GetPublicKey() *BLS48581G1PublicKey {
if x != nil {
return x.PublicKey
}
return nil
}
// Describes a raw compressed BLS48-581 G2 public key
type BLS48581G2PublicKey struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KeyValue []byte `protobuf:"bytes,1,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` // 585 byte value
}
func (x *BLS48581G2PublicKey) Reset() {
*x = BLS48581G2PublicKey{}
if protoimpl.UnsafeEnabled {
mi := &file_keys_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BLS48581G2PublicKey) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BLS48581G2PublicKey) ProtoMessage() {}
func (x *BLS48581G2PublicKey) ProtoReflect() protoreflect.Message {
mi := &file_keys_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BLS48581G2PublicKey.ProtoReflect.Descriptor instead.
func (*BLS48581G2PublicKey) Descriptor() ([]byte, []int) {
return file_keys_proto_rawDescGZIP(), []int{9}
}
func (x *BLS48581G2PublicKey) GetKeyValue() []byte {
if x != nil {
return x.KeyValue
}
return nil
}
// Describes a raw BLS48-581 private key, with corresponding G2 public key
type BLS48581G2PrivateKey struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KeyValue []byte `protobuf:"bytes,1,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` // 73 byte value
PublicKey *BLS48581G2PublicKey `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
}
func (x *BLS48581G2PrivateKey) Reset() {
*x = BLS48581G2PrivateKey{}
if protoimpl.UnsafeEnabled {
mi := &file_keys_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BLS48581G2PrivateKey) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BLS48581G2PrivateKey) ProtoMessage() {}
func (x *BLS48581G2PrivateKey) ProtoReflect() protoreflect.Message {
mi := &file_keys_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BLS48581G2PrivateKey.ProtoReflect.Descriptor instead.
func (*BLS48581G2PrivateKey) Descriptor() ([]byte, []int) {
return file_keys_proto_rawDescGZIP(), []int{10}
}
func (x *BLS48581G2PrivateKey) GetKeyValue() []byte {
if x != nil {
return x.KeyValue
}
return nil
}
func (x *BLS48581G2PrivateKey) GetPublicKey() *BLS48581G2PublicKey {
if x != nil {
return x.PublicKey
}
return nil
}
var File_keys_proto protoreflect.FileDescriptor
var file_keys_proto_rawDesc = []byte{
0x0a, 0x0a, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x71, 0x75,
0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6b, 0x65,
0x79, 0x73, 0x2e, 0x70, 0x62, 0x22, 0x2d, 0x0a, 0x0e, 0x45, 0x64, 0x34, 0x34, 0x38, 0x50, 0x75,
0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x56,
0x61, 0x6c, 0x75, 0x65, 0x22, 0x76, 0x0a, 0x0f, 0x45, 0x64, 0x34, 0x34, 0x38, 0x50, 0x72, 0x69,
0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x56,
0x61, 0x6c, 0x75, 0x65, 0x12, 0x46, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b,
0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69,
0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x2e,
0x70, 0x62, 0x2e, 0x45, 0x64, 0x34, 0x34, 0x38, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65,
0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x76, 0x0a, 0x0e,
0x45, 0x64, 0x34, 0x34, 0x38, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1c,
0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x46, 0x0a, 0x0a,
0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x27, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f,
0x64, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x70, 0x62, 0x2e, 0x45, 0x64, 0x34, 0x34, 0x38,
0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69,
0x63, 0x4b, 0x65, 0x79, 0x22, 0x2c, 0x0a, 0x0d, 0x58, 0x34, 0x34, 0x38, 0x50, 0x75, 0x62, 0x6c,
0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x22, 0x74, 0x0a, 0x0e, 0x58, 0x34, 0x34, 0x38, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74,
0x65, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75,
0x65, 0x12, 0x45, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69,
0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x70, 0x62, 0x2e,
0x58, 0x34, 0x34, 0x38, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70,
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x2c, 0x0a, 0x0d, 0x50, 0x43, 0x41, 0x53,
0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79,
0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6b, 0x65,
0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x74, 0x0a, 0x0e, 0x50, 0x43, 0x41, 0x53, 0x50, 0x72,
0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6b, 0x65, 0x79,
0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f,
0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x71, 0x75, 0x69, 0x6c,
0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x73,
0x2e, 0x70, 0x62, 0x2e, 0x50, 0x43, 0x41, 0x53, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65,
0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x32, 0x0a, 0x13,
0x42, 0x4c, 0x53, 0x34, 0x38, 0x35, 0x38, 0x31, 0x47, 0x31, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63,
0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x22, 0x80, 0x01, 0x0a, 0x14, 0x42, 0x4c, 0x53, 0x34, 0x38, 0x35, 0x38, 0x31, 0x47, 0x31, 0x50,
0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79,
0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6b, 0x65,
0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4b, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x71, 0x75, 0x69,
0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6b, 0x65, 0x79,
0x73, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x4c, 0x53, 0x34, 0x38, 0x35, 0x38, 0x31, 0x47, 0x31, 0x50,
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
0x4b, 0x65, 0x79, 0x22, 0x32, 0x0a, 0x13, 0x42, 0x4c, 0x53, 0x34, 0x38, 0x35, 0x38, 0x31, 0x47,
0x32, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65,
0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6b,
0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x80, 0x01, 0x0a, 0x14, 0x42, 0x4c, 0x53, 0x34,
0x38, 0x35, 0x38, 0x31, 0x47, 0x32, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79,
0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4b, 0x0a,
0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x2c, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e,
0x6f, 0x64, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x4c, 0x53, 0x34,
0x38, 0x35, 0x38, 0x31, 0x47, 0x32, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52,
0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x42, 0x3a, 0x5a, 0x38, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2f, 0x6d,
0x6f, 0x6e, 0x6f, 0x72, 0x65, 0x70, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_keys_proto_rawDescOnce sync.Once
file_keys_proto_rawDescData = file_keys_proto_rawDesc
)
func file_keys_proto_rawDescGZIP() []byte {
file_keys_proto_rawDescOnce.Do(func() {
file_keys_proto_rawDescData = protoimpl.X.CompressGZIP(file_keys_proto_rawDescData)
})
return file_keys_proto_rawDescData
}
var file_keys_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_keys_proto_goTypes = []interface{}{
(*Ed448PublicKey)(nil), // 0: quilibrium.node.keys.pb.Ed448PublicKey
(*Ed448PrivateKey)(nil), // 1: quilibrium.node.keys.pb.Ed448PrivateKey
(*Ed448Signature)(nil), // 2: quilibrium.node.keys.pb.Ed448Signature
(*X448PublicKey)(nil), // 3: quilibrium.node.keys.pb.X448PublicKey
(*X448PrivateKey)(nil), // 4: quilibrium.node.keys.pb.X448PrivateKey
(*PCASPublicKey)(nil), // 5: quilibrium.node.keys.pb.PCASPublicKey
(*PCASPrivateKey)(nil), // 6: quilibrium.node.keys.pb.PCASPrivateKey
(*BLS48581G1PublicKey)(nil), // 7: quilibrium.node.keys.pb.BLS48581G1PublicKey
(*BLS48581G1PrivateKey)(nil), // 8: quilibrium.node.keys.pb.BLS48581G1PrivateKey
(*BLS48581G2PublicKey)(nil), // 9: quilibrium.node.keys.pb.BLS48581G2PublicKey
(*BLS48581G2PrivateKey)(nil), // 10: quilibrium.node.keys.pb.BLS48581G2PrivateKey
}
var file_keys_proto_depIdxs = []int32{
0, // 0: quilibrium.node.keys.pb.Ed448PrivateKey.public_key:type_name -> quilibrium.node.keys.pb.Ed448PublicKey
0, // 1: quilibrium.node.keys.pb.Ed448Signature.public_key:type_name -> quilibrium.node.keys.pb.Ed448PublicKey
3, // 2: quilibrium.node.keys.pb.X448PrivateKey.public_key:type_name -> quilibrium.node.keys.pb.X448PublicKey
5, // 3: quilibrium.node.keys.pb.PCASPrivateKey.public_key:type_name -> quilibrium.node.keys.pb.PCASPublicKey
7, // 4: quilibrium.node.keys.pb.BLS48581G1PrivateKey.public_key:type_name -> quilibrium.node.keys.pb.BLS48581G1PublicKey
9, // 5: quilibrium.node.keys.pb.BLS48581G2PrivateKey.public_key:type_name -> quilibrium.node.keys.pb.BLS48581G2PublicKey
6, // [6:6] is the sub-list for method output_type
6, // [6:6] is the sub-list for method input_type
6, // [6:6] is the sub-list for extension type_name
6, // [6:6] is the sub-list for extension extendee
0, // [0:6] is the sub-list for field type_name
}
func init() { file_keys_proto_init() }
func file_keys_proto_init() {
if File_keys_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_keys_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Ed448PublicKey); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_keys_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Ed448PrivateKey); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_keys_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Ed448Signature); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_keys_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*X448PublicKey); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_keys_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*X448PrivateKey); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_keys_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PCASPublicKey); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_keys_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PCASPrivateKey); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_keys_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BLS48581G1PublicKey); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_keys_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BLS48581G1PrivateKey); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_keys_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BLS48581G2PublicKey); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_keys_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BLS48581G2PrivateKey); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_keys_proto_rawDesc,
NumEnums: 0,
NumMessages: 11,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_keys_proto_goTypes,
DependencyIndexes: file_keys_proto_depIdxs,
MessageInfos: file_keys_proto_msgTypes,
}.Build()
File_keys_proto = out.File
file_keys_proto_rawDesc = nil
file_keys_proto_goTypes = nil
file_keys_proto_depIdxs = nil
}

68
node/protobufs/keys.proto Normal file
View File

@ -0,0 +1,68 @@
syntax = "proto3";
package quilibrium.node.keys.pb;
option go_package = "source.quilibrium.com/quilibrium/monorepo/node/protobufs";
// Describes a raw Ed448 public key
message Ed448PublicKey {
bytes key_value = 1; // 57 byte value
}
// Describes a raw Ed448 private key notably this is post-derivation,
// not the seed.
message Ed448PrivateKey {
bytes key_value = 1; // 57 byte value
Ed448PublicKey public_key = 2;
}
// Describes a raw Ed448 signature
message Ed448Signature {
bytes signature = 1; // 114 byte value
Ed448PublicKey public_key = 2;
}
// Describes a raw X448 public key
message X448PublicKey {
bytes key_value = 1; // 57 byte value
}
// Describes a raw X448 private key notably this is post-derivation,
// not the seed.
message X448PrivateKey {
bytes key_value = 1; // 57 byte value
X448PublicKey public_key = 2;
}
// Describes a raw PCAS public key
message PCASPublicKey {
bytes key_value = 1; // 256 kilobyte value
}
// Describes a raw PCAS private key
message PCASPrivateKey {
bytes key_value = 1; // 256 byte value
PCASPublicKey public_key = 2;
}
// Describes a raw compressed BLS48-581 G1 public key
message BLS48581G1PublicKey {
bytes key_value = 1; // 74 byte value
}
// Describes a raw BLS48-581 private key, with corresponding G1 public key
message BLS48581G1PrivateKey {
bytes key_value = 1; // 73 byte value
BLS48581G1PublicKey public_key = 2;
}
// Describes a raw compressed BLS48-581 G2 public key
message BLS48581G2PublicKey {
bytes key_value = 1; // 585 byte value
}
// Describes a raw BLS48-581 private key, with corresponding G2 public key
message BLS48581G2PrivateKey {
bytes key_value = 1; // 73 byte value
BLS48581G2PublicKey public_key = 2;
}

View File

@ -0,0 +1,38 @@
package protobufs
const (
TypeUrlPrefix = "types.quilibrium.com"
NamespacePrefix = TypeUrlPrefix + "/quilibrium.node."
AppPrefix = NamespacePrefix + "application.pb."
ChannelPrefix = NamespacePrefix + "channel.pb."
ClockPrefix = NamespacePrefix + "clock.pb."
KeysPrefix = NamespacePrefix + "keys.pb."
CeremonyPrefix = NamespacePrefix + "ceremony.pb."
CeremonyTranscriptType = CeremonyPrefix + "CeremonyTranscript"
ApplicationType = AppPrefix + "Application"
ExecutionContextType = AppPrefix + "ExecutionContext"
MessageType = AppPrefix + "Message"
P2PChannelEnvelopeType = ChannelPrefix + "P2PChannelEnvelope"
MessageCiphertextType = ChannelPrefix + "MessageCiphertext"
ProvingKeyAnnouncementType = ChannelPrefix + "ProvingKeyAnnouncement"
ProvingKeyRequestType = ChannelPrefix + "ProvingKeyRequest"
InclusionAggregateProofType = ChannelPrefix + "InclusionAggregateProof"
InclusionCommitmentType = ChannelPrefix + "InclusionCommitment"
KeyBundleAnnouncementType = ChannelPrefix + "KeyBundleAnnouncement"
IdentityKeyType = ChannelPrefix + "IdentityKey"
SignedPreKeyType = ChannelPrefix + "SignedPreKey"
ClockFrameType = ClockPrefix + "ClockFrame"
ClockFramesRequestType = ClockPrefix + "ClockFramesRequest"
ClockFramesResponseType = ClockPrefix + "ClockFramesResponse"
Ed448PublicKeyType = KeysPrefix + "Ed448PublicKey"
Ed448PrivateKeyType = KeysPrefix + "Ed448PrivateKey"
Ed448SignatureType = KeysPrefix + "Ed448Signature"
X448PublicKeyType = KeysPrefix + "X448PublicKey"
X448PrivateKeyType = KeysPrefix + "X448PrivateKey"
PCASPublicKeyType = KeysPrefix + "PCASPublicKey"
PCASPrivateKeyType = KeysPrefix + "PCASPrivateKey"
BLS48581G1PublicKeyType = KeysPrefix + "BLS48581G1PublicKey"
BLS48581G1PrivateKeyType = KeysPrefix + "BLS48581G1PrivateKey"
BLS48581G2PublicKeyType = KeysPrefix + "BLS48581G2PublicKey"
BLS48581G2PrivateKeyType = KeysPrefix + "BLS48581G2PrivateKey"
)