From c3ffd5c4725c461daf2ce69e41e500f730e0db4e Mon Sep 17 00:00:00 2001 From: Cassandra Heart Date: Sun, 3 Sep 2023 18:47:09 -0500 Subject: [PATCH] DHT Bootstrap Verification --- .gitignore | 4 +- node/app/node.go | 52 + node/app/wire.go | 54 + node/app/wire_gen.go | 59 + node/consensus/consensus_engine.go | 29 + node/consensus/master/broadcast_messaging.go | 228 ++++ node/consensus/master/consensus_frames.go | 248 ++++ .../master/execution_registration.go | 109 ++ .../master/master_clock_consensus_engine.go | 195 +++ node/consensus/master/peer_messaging.go | 238 ++++ node/crypto/doubleratchet.go | 774 ++++++------ node/crypto/doubleratchet_test.go | 206 ++-- node/execution/execution_engine.go | 14 + node/execution/nop/nop_execution_engine.go | 95 ++ node/main.go | 18 +- node/p2p/bloom_utils.go | 94 ++ node/p2p/blossomsub.go | 421 +++++++ node/p2p/pubsub.go | 14 + node/protobufs/Makefile | 12 + node/protobufs/application.pb.go | 468 +++++++ node/protobufs/application.proto | 44 + node/protobufs/ceremony.pb.go | 224 ++++ node/protobufs/ceremony.proto | 39 + node/protobufs/channel.pb.go | 1096 +++++++++++++++++ node/protobufs/channel.proto | 181 +++ node/protobufs/clock.go | 219 ++++ node/protobufs/clock.pb.go | 502 ++++++++ node/protobufs/clock.proto | 88 ++ node/protobufs/keys.go | 216 ++++ node/protobufs/keys.pb.go | 871 +++++++++++++ node/protobufs/keys.proto | 68 + node/protobufs/protobufs.go | 38 + 32 files changed, 6422 insertions(+), 496 deletions(-) create mode 100644 node/app/node.go create mode 100644 node/app/wire.go create mode 100644 node/app/wire_gen.go create mode 100644 node/consensus/consensus_engine.go create mode 100644 node/consensus/master/broadcast_messaging.go create mode 100644 node/consensus/master/consensus_frames.go create mode 100644 node/consensus/master/execution_registration.go create mode 100644 node/consensus/master/master_clock_consensus_engine.go create mode 100644 node/consensus/master/peer_messaging.go create mode 100644 node/execution/execution_engine.go create mode 100644 node/execution/nop/nop_execution_engine.go create mode 100644 node/p2p/bloom_utils.go create mode 100644 node/p2p/blossomsub.go create mode 100644 node/p2p/pubsub.go create mode 100644 node/protobufs/Makefile create mode 100644 node/protobufs/application.pb.go create mode 100644 node/protobufs/application.proto create mode 100644 node/protobufs/ceremony.pb.go create mode 100644 node/protobufs/ceremony.proto create mode 100644 node/protobufs/channel.pb.go create mode 100644 node/protobufs/channel.proto create mode 100644 node/protobufs/clock.go create mode 100644 node/protobufs/clock.pb.go create mode 100644 node/protobufs/clock.proto create mode 100644 node/protobufs/keys.go create mode 100644 node/protobufs/keys.pb.go create mode 100644 node/protobufs/keys.proto create mode 100644 node/protobufs/protobufs.go diff --git a/.gitignore b/.gitignore index 27c9a1a..64c4e06 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .idea/ vouchers/ -ceremony-client \ No newline at end of file +ceremony-client +.config* +.DS_Store diff --git a/node/app/node.go b/node/app/node.go new file mode 100644 index 0000000..1e0bb78 --- /dev/null +++ b/node/app/node.go @@ -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) + } +} diff --git a/node/app/wire.go b/node/app/wire.go new file mode 100644 index 0000000..e3c4111 --- /dev/null +++ b/node/app/wire.go @@ -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)) +} diff --git a/node/app/wire_gen.go b/node/app/wire_gen.go new file mode 100644 index 0000000..132203b --- /dev/null +++ b/node/app/wire_gen.go @@ -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))) diff --git a/node/consensus/consensus_engine.go b/node/consensus/consensus_engine.go new file mode 100644 index 0000000..46c67e8 --- /dev/null +++ b/node/consensus/consensus_engine.go @@ -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 +} diff --git a/node/consensus/master/broadcast_messaging.go b/node/consensus/master/broadcast_messaging.go new file mode 100644 index 0000000..1091679 --- /dev/null +++ b/node/consensus/master/broadcast_messaging.go @@ -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) +} diff --git a/node/consensus/master/consensus_frames.go b/node/consensus/master/consensus_frames.go new file mode 100644 index 0000000..765584f --- /dev/null +++ b/node/consensus/master/consensus_frames.go @@ -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 +} diff --git a/node/consensus/master/execution_registration.go b/node/consensus/master/execution_registration.go new file mode 100644 index 0000000..69657cb --- /dev/null +++ b/node/consensus/master/execution_registration.go @@ -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 +} diff --git a/node/consensus/master/master_clock_consensus_engine.go b/node/consensus/master/master_clock_consensus_engine.go new file mode 100644 index 0000000..022710a --- /dev/null +++ b/node/consensus/master/master_clock_consensus_engine.go @@ -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 +} diff --git a/node/consensus/master/peer_messaging.go b/node/consensus/master/peer_messaging.go new file mode 100644 index 0000000..660d3da --- /dev/null +++ b/node/consensus/master/peer_messaging.go @@ -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 +} diff --git a/node/crypto/doubleratchet.go b/node/crypto/doubleratchet.go index 83b832b..f3e70d2 100644 --- a/node/crypto/doubleratchet.go +++ b/node/crypto/doubleratchet.go @@ -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] +} diff --git a/node/crypto/doubleratchet_test.go b/node/crypto/doubleratchet_test.go index 9b30b6b..438b62e 100644 --- a/node/crypto/doubleratchet_test.go +++ b/node/crypto/doubleratchet_test.go @@ -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) +} diff --git a/node/execution/execution_engine.go b/node/execution/execution_engine.go new file mode 100644 index 0000000..098773b --- /dev/null +++ b/node/execution/execution_engine.go @@ -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) +} diff --git a/node/execution/nop/nop_execution_engine.go b/node/execution/nop/nop_execution_engine.go new file mode 100644 index 0000000..32cbf9f --- /dev/null +++ b/node/execution/nop/nop_execution_engine.go @@ -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 +} diff --git a/node/main.go b/node/main.go index 227dbae..07d3e38 100644 --- a/node/main.go +++ b/node/main.go @@ -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") } diff --git a/node/p2p/bloom_utils.go b/node/p2p/bloom_utils.go new file mode 100644 index 0000000..90617dd --- /dev/null +++ b/node/p2p/bloom_utils.go @@ -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 +} diff --git a/node/p2p/blossomsub.go b/node/p2p/blossomsub.go new file mode 100644 index 0000000..17d5970 --- /dev/null +++ b/node/p2p/blossomsub.go @@ -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, + } +} diff --git a/node/p2p/pubsub.go b/node/p2p/pubsub.go new file mode 100644 index 0000000..1ee075e --- /dev/null +++ b/node/p2p/pubsub.go @@ -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) +} diff --git a/node/protobufs/Makefile b/node/protobufs/Makefile new file mode 100644 index 0000000..e4add95 --- /dev/null +++ b/node/protobufs/Makefile @@ -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 \ No newline at end of file diff --git a/node/protobufs/application.pb.go b/node/protobufs/application.pb.go new file mode 100644 index 0000000..888b311 --- /dev/null +++ b/node/protobufs/application.pb.go @@ -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 +} diff --git a/node/protobufs/application.proto b/node/protobufs/application.proto new file mode 100644 index 0000000..35d390c --- /dev/null +++ b/node/protobufs/application.proto @@ -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; +} \ No newline at end of file diff --git a/node/protobufs/ceremony.pb.go b/node/protobufs/ceremony.pb.go new file mode 100644 index 0000000..fc904b1 --- /dev/null +++ b/node/protobufs/ceremony.pb.go @@ -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()) 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 +} diff --git a/node/protobufs/ceremony.proto b/node/protobufs/ceremony.proto new file mode 100644 index 0000000..1b26f88 --- /dev/null +++ b/node/protobufs/ceremony.proto @@ -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()) 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; +} \ No newline at end of file diff --git a/node/protobufs/channel.pb.go b/node/protobufs/channel.pb.go new file mode 100644 index 0000000..7dd4aee --- /dev/null +++ b/node/protobufs/channel.pb.go @@ -0,0 +1,1096 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.21.12 +// source: channel.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 general channel envelope for a message. +type P2PChannelEnvelope struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // 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. + ProtocolIdentifier uint32 `protobuf:"varint,1,opt,name=protocol_identifier,json=protocolIdentifier,proto3" json:"protocol_identifier,omitempty"` + // 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). + MessageHeader *MessageCiphertext `protobuf:"bytes,2,opt,name=message_header,json=messageHeader,proto3" json:"message_header,omitempty"` + // 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. + MessageBody *MessageCiphertext `protobuf:"bytes,3,opt,name=message_body,json=messageBody,proto3" json:"message_body,omitempty"` +} + +func (x *P2PChannelEnvelope) Reset() { + *x = P2PChannelEnvelope{} + if protoimpl.UnsafeEnabled { + mi := &file_channel_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *P2PChannelEnvelope) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*P2PChannelEnvelope) ProtoMessage() {} + +func (x *P2PChannelEnvelope) ProtoReflect() protoreflect.Message { + mi := &file_channel_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 P2PChannelEnvelope.ProtoReflect.Descriptor instead. +func (*P2PChannelEnvelope) Descriptor() ([]byte, []int) { + return file_channel_proto_rawDescGZIP(), []int{0} +} + +func (x *P2PChannelEnvelope) GetProtocolIdentifier() uint32 { + if x != nil { + return x.ProtocolIdentifier + } + return 0 +} + +func (x *P2PChannelEnvelope) GetMessageHeader() *MessageCiphertext { + if x != nil { + return x.MessageHeader + } + return nil +} + +func (x *P2PChannelEnvelope) GetMessageBody() *MessageCiphertext { + if x != nil { + return x.MessageBody + } + return nil +} + +// Describes a general ciphertext payload. +type MessageCiphertext struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // 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. + InitializationVector []byte `protobuf:"bytes,1,opt,name=initialization_vector,json=initializationVector,proto3" json:"initialization_vector,omitempty"` + // 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. + Ciphertext []byte `protobuf:"bytes,2,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"` + // The associated data byte string, if available. This will be highly protocol + // specific, but SHOULD NOT leak metadata. + AssociatedData []byte `protobuf:"bytes,3,opt,name=associated_data,json=associatedData,proto3" json:"associated_data,omitempty"` +} + +func (x *MessageCiphertext) Reset() { + *x = MessageCiphertext{} + if protoimpl.UnsafeEnabled { + mi := &file_channel_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MessageCiphertext) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageCiphertext) ProtoMessage() {} + +func (x *MessageCiphertext) ProtoReflect() protoreflect.Message { + mi := &file_channel_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 MessageCiphertext.ProtoReflect.Descriptor instead. +func (*MessageCiphertext) Descriptor() ([]byte, []int) { + return file_channel_proto_rawDescGZIP(), []int{1} +} + +func (x *MessageCiphertext) GetInitializationVector() []byte { + if x != nil { + return x.InitializationVector + } + return nil +} + +func (x *MessageCiphertext) GetCiphertext() []byte { + if x != nil { + return x.Ciphertext + } + return nil +} + +func (x *MessageCiphertext) GetAssociatedData() []byte { + if x != nil { + return x.AssociatedData + } + return nil +} + +// Describes the announcement of a new proving key. +type ProvingKeyAnnouncement struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // 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. + IdentityCommitment []byte `protobuf:"bytes,1,opt,name=identity_commitment,json=identityCommitment,proto3" json:"identity_commitment,omitempty"` + // 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. + PrekeyCommitment []byte `protobuf:"bytes,2,opt,name=prekey_commitment,json=prekeyCommitment,proto3" json:"prekey_commitment,omitempty"` + // Types that are assignable to ProvingKeySignature: + // + // *ProvingKeyAnnouncement_ProvingKeySignatureEd448 + ProvingKeySignature isProvingKeyAnnouncement_ProvingKeySignature `protobuf_oneof:"proving_key_signature"` +} + +func (x *ProvingKeyAnnouncement) Reset() { + *x = ProvingKeyAnnouncement{} + if protoimpl.UnsafeEnabled { + mi := &file_channel_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProvingKeyAnnouncement) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvingKeyAnnouncement) ProtoMessage() {} + +func (x *ProvingKeyAnnouncement) ProtoReflect() protoreflect.Message { + mi := &file_channel_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 ProvingKeyAnnouncement.ProtoReflect.Descriptor instead. +func (*ProvingKeyAnnouncement) Descriptor() ([]byte, []int) { + return file_channel_proto_rawDescGZIP(), []int{2} +} + +func (x *ProvingKeyAnnouncement) GetIdentityCommitment() []byte { + if x != nil { + return x.IdentityCommitment + } + return nil +} + +func (x *ProvingKeyAnnouncement) GetPrekeyCommitment() []byte { + if x != nil { + return x.PrekeyCommitment + } + return nil +} + +func (m *ProvingKeyAnnouncement) GetProvingKeySignature() isProvingKeyAnnouncement_ProvingKeySignature { + if m != nil { + return m.ProvingKeySignature + } + return nil +} + +func (x *ProvingKeyAnnouncement) GetProvingKeySignatureEd448() *Ed448Signature { + if x, ok := x.GetProvingKeySignature().(*ProvingKeyAnnouncement_ProvingKeySignatureEd448); ok { + return x.ProvingKeySignatureEd448 + } + return nil +} + +type isProvingKeyAnnouncement_ProvingKeySignature interface { + isProvingKeyAnnouncement_ProvingKeySignature() +} + +type ProvingKeyAnnouncement_ProvingKeySignatureEd448 struct { + ProvingKeySignatureEd448 *Ed448Signature `protobuf:"bytes,3,opt,name=proving_key_signature_ed448,json=provingKeySignatureEd448,proto3,oneof"` +} + +func (*ProvingKeyAnnouncement_ProvingKeySignatureEd448) isProvingKeyAnnouncement_ProvingKeySignature() { +} + +// Represents a request for a proving key. +type ProvingKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ProvingKeyBytes []byte `protobuf:"bytes,1,opt,name=proving_key_bytes,json=provingKeyBytes,proto3" json:"proving_key_bytes,omitempty"` +} + +func (x *ProvingKeyRequest) Reset() { + *x = ProvingKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_channel_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProvingKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvingKeyRequest) ProtoMessage() {} + +func (x *ProvingKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_channel_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 ProvingKeyRequest.ProtoReflect.Descriptor instead. +func (*ProvingKeyRequest) Descriptor() ([]byte, []int) { + return file_channel_proto_rawDescGZIP(), []int{3} +} + +func (x *ProvingKeyRequest) GetProvingKeyBytes() []byte { + if x != nil { + return x.ProvingKeyBytes + } + return nil +} + +// Describes the aggregation of inclusion commitments for a given clock frame +type InclusionAggregateProof struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The filter in which the inclusion proof was produced. + Filter []byte `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + // The frame number in which the inclusion proof was added. + FrameNumber uint64 `protobuf:"varint,2,opt,name=frame_number,json=frameNumber,proto3" json:"frame_number,omitempty"` + // The collection of inclusion commitments, in order. + InclusionCommitments []*InclusionCommitment `protobuf:"bytes,3,rep,name=inclusion_commitments,json=inclusionCommitments,proto3" json:"inclusion_commitments,omitempty"` + // The raw serialized proof, mirroring the type of commitment scheme used + // within the inclusion proofs. + Proof []byte `protobuf:"bytes,4,opt,name=proof,proto3" json:"proof,omitempty"` +} + +func (x *InclusionAggregateProof) Reset() { + *x = InclusionAggregateProof{} + if protoimpl.UnsafeEnabled { + mi := &file_channel_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InclusionAggregateProof) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InclusionAggregateProof) ProtoMessage() {} + +func (x *InclusionAggregateProof) ProtoReflect() protoreflect.Message { + mi := &file_channel_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 InclusionAggregateProof.ProtoReflect.Descriptor instead. +func (*InclusionAggregateProof) Descriptor() ([]byte, []int) { + return file_channel_proto_rawDescGZIP(), []int{4} +} + +func (x *InclusionAggregateProof) GetFilter() []byte { + if x != nil { + return x.Filter + } + return nil +} + +func (x *InclusionAggregateProof) GetFrameNumber() uint64 { + if x != nil { + return x.FrameNumber + } + return 0 +} + +func (x *InclusionAggregateProof) GetInclusionCommitments() []*InclusionCommitment { + if x != nil { + return x.InclusionCommitments + } + return nil +} + +func (x *InclusionAggregateProof) GetProof() []byte { + if x != nil { + return x.Proof + } + return nil +} + +// Describes the commitment of a data's inclusion in a given clock frame +type InclusionCommitment struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The filter in which the inclusion aggregate proof was produced. + Filter []byte `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + // The frame number in which the inclusion aggregate proof was added. + FrameNumber uint64 `protobuf:"varint,2,opt,name=frame_number,json=frameNumber,proto3" json:"frame_number,omitempty"` + // The position of the data in the proof. + Position uint32 `protobuf:"varint,3,opt,name=position,proto3" json:"position,omitempty"` + // The specific type url represented by the data. + TypeUrl string `protobuf:"bytes,4,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"` + // 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. + Data []byte `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"` + // 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. + Commitment []byte `protobuf:"bytes,6,opt,name=commitment,proto3" json:"commitment,omitempty"` +} + +func (x *InclusionCommitment) Reset() { + *x = InclusionCommitment{} + if protoimpl.UnsafeEnabled { + mi := &file_channel_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InclusionCommitment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InclusionCommitment) ProtoMessage() {} + +func (x *InclusionCommitment) ProtoReflect() protoreflect.Message { + mi := &file_channel_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 InclusionCommitment.ProtoReflect.Descriptor instead. +func (*InclusionCommitment) Descriptor() ([]byte, []int) { + return file_channel_proto_rawDescGZIP(), []int{5} +} + +func (x *InclusionCommitment) GetFilter() []byte { + if x != nil { + return x.Filter + } + return nil +} + +func (x *InclusionCommitment) GetFrameNumber() uint64 { + if x != nil { + return x.FrameNumber + } + return 0 +} + +func (x *InclusionCommitment) GetPosition() uint32 { + if x != nil { + return x.Position + } + return 0 +} + +func (x *InclusionCommitment) GetTypeUrl() string { + if x != nil { + return x.TypeUrl + } + return "" +} + +func (x *InclusionCommitment) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *InclusionCommitment) GetCommitment() []byte { + if x != nil { + return x.Commitment + } + return nil +} + +// 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. +type KeyBundleAnnouncement struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IdentityKey *IdentityKey `protobuf:"bytes,1,opt,name=identity_key,json=identityKey,proto3" json:"identity_key,omitempty"` + SignedPreKey *SignedPreKey `protobuf:"bytes,2,opt,name=signed_pre_key,json=signedPreKey,proto3" json:"signed_pre_key,omitempty"` + ProvingKeyBytes []byte `protobuf:"bytes,3,opt,name=proving_key_bytes,json=provingKeyBytes,proto3" json:"proving_key_bytes,omitempty"` +} + +func (x *KeyBundleAnnouncement) Reset() { + *x = KeyBundleAnnouncement{} + if protoimpl.UnsafeEnabled { + mi := &file_channel_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeyBundleAnnouncement) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyBundleAnnouncement) ProtoMessage() {} + +func (x *KeyBundleAnnouncement) ProtoReflect() protoreflect.Message { + mi := &file_channel_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 KeyBundleAnnouncement.ProtoReflect.Descriptor instead. +func (*KeyBundleAnnouncement) Descriptor() ([]byte, []int) { + return file_channel_proto_rawDescGZIP(), []int{6} +} + +func (x *KeyBundleAnnouncement) GetIdentityKey() *IdentityKey { + if x != nil { + return x.IdentityKey + } + return nil +} + +func (x *KeyBundleAnnouncement) GetSignedPreKey() *SignedPreKey { + if x != nil { + return x.SignedPreKey + } + return nil +} + +func (x *KeyBundleAnnouncement) GetProvingKeyBytes() []byte { + if x != nil { + return x.ProvingKeyBytes + } + return nil +} + +// 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. +type IdentityKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The C component of the Schnorr proof, serialized as big endian. + Challenge []byte `protobuf:"bytes,1,opt,name=challenge,proto3" json:"challenge,omitempty"` + // The S component of the Schnorr proof, serialized as big endian. + Response []byte `protobuf:"bytes,2,opt,name=response,proto3" json:"response,omitempty"` + // The Statement component of the Schnorr proof, serialized as an (compressed, + // if possible) affine representation of the point. + Statement []byte `protobuf:"bytes,3,opt,name=statement,proto3" json:"statement,omitempty"` + // Types that are assignable to IdentityKeySignature: + // + // *IdentityKey_PublicKeySignatureEd448 + IdentityKeySignature isIdentityKey_IdentityKeySignature `protobuf_oneof:"identity_key_signature"` +} + +func (x *IdentityKey) Reset() { + *x = IdentityKey{} + if protoimpl.UnsafeEnabled { + mi := &file_channel_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IdentityKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IdentityKey) ProtoMessage() {} + +func (x *IdentityKey) ProtoReflect() protoreflect.Message { + mi := &file_channel_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 IdentityKey.ProtoReflect.Descriptor instead. +func (*IdentityKey) Descriptor() ([]byte, []int) { + return file_channel_proto_rawDescGZIP(), []int{7} +} + +func (x *IdentityKey) GetChallenge() []byte { + if x != nil { + return x.Challenge + } + return nil +} + +func (x *IdentityKey) GetResponse() []byte { + if x != nil { + return x.Response + } + return nil +} + +func (x *IdentityKey) GetStatement() []byte { + if x != nil { + return x.Statement + } + return nil +} + +func (m *IdentityKey) GetIdentityKeySignature() isIdentityKey_IdentityKeySignature { + if m != nil { + return m.IdentityKeySignature + } + return nil +} + +func (x *IdentityKey) GetPublicKeySignatureEd448() *Ed448Signature { + if x, ok := x.GetIdentityKeySignature().(*IdentityKey_PublicKeySignatureEd448); ok { + return x.PublicKeySignatureEd448 + } + return nil +} + +type isIdentityKey_IdentityKeySignature interface { + isIdentityKey_IdentityKeySignature() +} + +type IdentityKey_PublicKeySignatureEd448 struct { + PublicKeySignatureEd448 *Ed448Signature `protobuf:"bytes,4,opt,name=public_key_signature_ed448,json=publicKeySignatureEd448,proto3,oneof"` +} + +func (*IdentityKey_PublicKeySignatureEd448) isIdentityKey_IdentityKeySignature() {} + +// 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. +type SignedPreKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The C component of the Schnorr proof, serialized as big endian. + Challenge []byte `protobuf:"bytes,1,opt,name=challenge,proto3" json:"challenge,omitempty"` + // The S component of the Schnorr proof, serialized as big endian. + Response []byte `protobuf:"bytes,2,opt,name=response,proto3" json:"response,omitempty"` + // The Statement component of the Schnorr proof, serialized as an (compressed, + // if possible) affine representation of the point. + Statement []byte `protobuf:"bytes,3,opt,name=statement,proto3" json:"statement,omitempty"` + // Types that are assignable to SignedPreKeySignature: + // + // *SignedPreKey_PublicKeySignatureEd448 + SignedPreKeySignature isSignedPreKey_SignedPreKeySignature `protobuf_oneof:"signed_pre_key_signature"` +} + +func (x *SignedPreKey) Reset() { + *x = SignedPreKey{} + if protoimpl.UnsafeEnabled { + mi := &file_channel_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignedPreKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignedPreKey) ProtoMessage() {} + +func (x *SignedPreKey) ProtoReflect() protoreflect.Message { + mi := &file_channel_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 SignedPreKey.ProtoReflect.Descriptor instead. +func (*SignedPreKey) Descriptor() ([]byte, []int) { + return file_channel_proto_rawDescGZIP(), []int{8} +} + +func (x *SignedPreKey) GetChallenge() []byte { + if x != nil { + return x.Challenge + } + return nil +} + +func (x *SignedPreKey) GetResponse() []byte { + if x != nil { + return x.Response + } + return nil +} + +func (x *SignedPreKey) GetStatement() []byte { + if x != nil { + return x.Statement + } + return nil +} + +func (m *SignedPreKey) GetSignedPreKeySignature() isSignedPreKey_SignedPreKeySignature { + if m != nil { + return m.SignedPreKeySignature + } + return nil +} + +func (x *SignedPreKey) GetPublicKeySignatureEd448() *Ed448Signature { + if x, ok := x.GetSignedPreKeySignature().(*SignedPreKey_PublicKeySignatureEd448); ok { + return x.PublicKeySignatureEd448 + } + return nil +} + +type isSignedPreKey_SignedPreKeySignature interface { + isSignedPreKey_SignedPreKeySignature() +} + +type SignedPreKey_PublicKeySignatureEd448 struct { + PublicKeySignatureEd448 *Ed448Signature `protobuf:"bytes,4,opt,name=public_key_signature_ed448,json=publicKeySignatureEd448,proto3,oneof"` +} + +func (*SignedPreKey_PublicKeySignatureEd448) isSignedPreKey_SignedPreKeySignature() {} + +var File_channel_proto protoreflect.FileDescriptor + +var file_channel_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x1a, 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, 0x1a, 0x0a, 0x6b, 0x65, 0x79, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xed, 0x01, 0x0a, 0x12, 0x50, 0x32, 0x50, 0x43, + 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12, 0x2f, + 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, + 0x54, 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 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, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x69, 0x70, 0x68, + 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x52, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x50, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 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, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x22, 0x91, 0x01, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x12, 0x33, 0x0a, + 0x15, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x14, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, + 0x78, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x61, 0x73, 0x73, + 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x22, 0xf9, 0x01, 0x0a, 0x16, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, + 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x13, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x12, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x6b, 0x65, + 0x79, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x10, 0x70, 0x72, 0x65, 0x6b, 0x65, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x68, 0x0a, 0x1b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x5f, + 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x65, 0x64, + 0x34, 0x34, 0x38, 0x18, 0x03, 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, 0x18, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, + 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x45, 0x64, 0x34, 0x34, 0x38, 0x42, 0x17, + 0x0a, 0x15, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x3f, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x67, + 0x4b, 0x65, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xd0, 0x01, 0x0a, 0x17, 0x49, 0x6e, 0x63, + 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50, + 0x72, 0x6f, 0x6f, 0x66, 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, + 0x64, 0x0a, 0x15, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, + 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, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x52, + 0x14, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0xbb, 0x01, 0x0a, 0x13, + 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, + 0x65, 0x6e, 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, 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, 0x1a, + 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x79, + 0x70, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0xdf, 0x01, 0x0a, 0x15, 0x4b, 0x65, + 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x4a, 0x0a, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 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, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, + 0x65, 0x79, 0x52, 0x0b, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x12, + 0x4e, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x65, 0x5f, 0x6b, 0x65, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 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, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x72, 0x65, 0x4b, 0x65, + 0x79, 0x52, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x12, + 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xe7, 0x01, 0x0a, 0x0b, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x63, + 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 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, 0x04, 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, 0x18, 0x0a, 0x16, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xea, 0x01, 0x0a, 0x0c, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, + 0x50, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, + 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, + 0x65, 0x6e, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 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, 0x04, 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, 0x1a, 0x0a, 0x18, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, + 0x5f, 0x70, 0x72, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 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_channel_proto_rawDescOnce sync.Once + file_channel_proto_rawDescData = file_channel_proto_rawDesc +) + +func file_channel_proto_rawDescGZIP() []byte { + file_channel_proto_rawDescOnce.Do(func() { + file_channel_proto_rawDescData = protoimpl.X.CompressGZIP(file_channel_proto_rawDescData) + }) + return file_channel_proto_rawDescData +} + +var file_channel_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_channel_proto_goTypes = []interface{}{ + (*P2PChannelEnvelope)(nil), // 0: quilibrium.node.channel.pb.P2PChannelEnvelope + (*MessageCiphertext)(nil), // 1: quilibrium.node.channel.pb.MessageCiphertext + (*ProvingKeyAnnouncement)(nil), // 2: quilibrium.node.channel.pb.ProvingKeyAnnouncement + (*ProvingKeyRequest)(nil), // 3: quilibrium.node.channel.pb.ProvingKeyRequest + (*InclusionAggregateProof)(nil), // 4: quilibrium.node.channel.pb.InclusionAggregateProof + (*InclusionCommitment)(nil), // 5: quilibrium.node.channel.pb.InclusionCommitment + (*KeyBundleAnnouncement)(nil), // 6: quilibrium.node.channel.pb.KeyBundleAnnouncement + (*IdentityKey)(nil), // 7: quilibrium.node.channel.pb.IdentityKey + (*SignedPreKey)(nil), // 8: quilibrium.node.channel.pb.SignedPreKey + (*Ed448Signature)(nil), // 9: quilibrium.node.keys.pb.Ed448Signature +} +var file_channel_proto_depIdxs = []int32{ + 1, // 0: quilibrium.node.channel.pb.P2PChannelEnvelope.message_header:type_name -> quilibrium.node.channel.pb.MessageCiphertext + 1, // 1: quilibrium.node.channel.pb.P2PChannelEnvelope.message_body:type_name -> quilibrium.node.channel.pb.MessageCiphertext + 9, // 2: quilibrium.node.channel.pb.ProvingKeyAnnouncement.proving_key_signature_ed448:type_name -> quilibrium.node.keys.pb.Ed448Signature + 5, // 3: quilibrium.node.channel.pb.InclusionAggregateProof.inclusion_commitments:type_name -> quilibrium.node.channel.pb.InclusionCommitment + 7, // 4: quilibrium.node.channel.pb.KeyBundleAnnouncement.identity_key:type_name -> quilibrium.node.channel.pb.IdentityKey + 8, // 5: quilibrium.node.channel.pb.KeyBundleAnnouncement.signed_pre_key:type_name -> quilibrium.node.channel.pb.SignedPreKey + 9, // 6: quilibrium.node.channel.pb.IdentityKey.public_key_signature_ed448:type_name -> quilibrium.node.keys.pb.Ed448Signature + 9, // 7: quilibrium.node.channel.pb.SignedPreKey.public_key_signature_ed448:type_name -> quilibrium.node.keys.pb.Ed448Signature + 8, // [8:8] is the sub-list for method output_type + 8, // [8:8] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name +} + +func init() { file_channel_proto_init() } +func file_channel_proto_init() { + if File_channel_proto != nil { + return + } + file_keys_proto_init() + if !protoimpl.UnsafeEnabled { + file_channel_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*P2PChannelEnvelope); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_channel_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageCiphertext); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_channel_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProvingKeyAnnouncement); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_channel_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProvingKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_channel_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InclusionAggregateProof); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_channel_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InclusionCommitment); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_channel_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeyBundleAnnouncement); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_channel_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IdentityKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_channel_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignedPreKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_channel_proto_msgTypes[2].OneofWrappers = []interface{}{ + (*ProvingKeyAnnouncement_ProvingKeySignatureEd448)(nil), + } + file_channel_proto_msgTypes[7].OneofWrappers = []interface{}{ + (*IdentityKey_PublicKeySignatureEd448)(nil), + } + file_channel_proto_msgTypes[8].OneofWrappers = []interface{}{ + (*SignedPreKey_PublicKeySignatureEd448)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_channel_proto_rawDesc, + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_channel_proto_goTypes, + DependencyIndexes: file_channel_proto_depIdxs, + MessageInfos: file_channel_proto_msgTypes, + }.Build() + File_channel_proto = out.File + file_channel_proto_rawDesc = nil + file_channel_proto_goTypes = nil + file_channel_proto_depIdxs = nil +} diff --git a/node/protobufs/channel.proto b/node/protobufs/channel.proto new file mode 100644 index 0000000..f9f551e --- /dev/null +++ b/node/protobufs/channel.proto @@ -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; + } +} \ No newline at end of file diff --git a/node/protobufs/clock.go b/node/protobufs/clock.go new file mode 100644 index 0000000..f7e7a10 --- /dev/null +++ b/node/protobufs/clock.go @@ -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 +} diff --git a/node/protobufs/clock.pb.go b/node/protobufs/clock.pb.go new file mode 100644 index 0000000..903372b --- /dev/null +++ b/node/protobufs/clock.pb.go @@ -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 +} diff --git a/node/protobufs/clock.proto b/node/protobufs/clock.proto new file mode 100644 index 0000000..6062b26 --- /dev/null +++ b/node/protobufs/clock.proto @@ -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; +} \ No newline at end of file diff --git a/node/protobufs/keys.go b/node/protobufs/keys.go new file mode 100644 index 0000000..ef2c648 --- /dev/null +++ b/node/protobufs/keys.go @@ -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 +} diff --git a/node/protobufs/keys.pb.go b/node/protobufs/keys.pb.go new file mode 100644 index 0000000..4e27e33 --- /dev/null +++ b/node/protobufs/keys.pb.go @@ -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 +} diff --git a/node/protobufs/keys.proto b/node/protobufs/keys.proto new file mode 100644 index 0000000..c511564 --- /dev/null +++ b/node/protobufs/keys.proto @@ -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; +} diff --git a/node/protobufs/protobufs.go b/node/protobufs/protobufs.go new file mode 100644 index 0000000..cc56321 --- /dev/null +++ b/node/protobufs/protobufs.go @@ -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" +)