syntax = "proto3"; package quilibrium.node.ceremony.pb; option go_package = "source.quilibrium.com/quilibrium/monorepo/node/protobufs"; import "channel.proto"; import "clock.proto"; 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; } message CeremonyLobbyState { int32 lobby_state = 1; oneof ceremony_state { CeremonyOpenState ceremony_open_state = 2; CeremonyInProgressState ceremony_in_progress_state = 3; CeremonyFinalizingState ceremony_finalizing_state = 4; CeremonyValidatingState ceremony_validating_state = 5; } CeremonyTranscript latest_transcript = 6; bytes reward_trie = 7; } message CeremonySeenProverAttestation { quilibrium.node.keys.pb.Ed448PublicKey seen_prover_key = 1; uint64 last_seen_frame = 2; quilibrium.node.keys.pb.Ed448Signature prover_signature = 3; } message CeremonyDroppedProverAttestation { quilibrium.node.keys.pb.Ed448PublicKey dropped_prover_key = 1; uint64 last_seen_frame = 2; quilibrium.node.keys.pb.Ed448Signature prover_signature = 3; } message CeremonyTranscriptShare { repeated quilibrium.node.keys.pb.BLS48581G1PublicKey additive_g1_powers = 1; repeated quilibrium.node.keys.pb.BLS48581G2PublicKey additive_g2_powers = 2; quilibrium.node.keys.pb.BLS48581G1PublicKey additive_g1_256_witness = 3; quilibrium.node.keys.pb.BLS48581G2PublicKey additive_g2_256_witness = 4; quilibrium.node.keys.pb.Ed448Signature prover_signature = 5; } // Describes the required proof to commit to a transcript to advance a round, // and as a proof to move to the verification state message CeremonyTranscriptCommit { // Prover key signature over the G1 point of the additive share of the first // power. quilibrium.node.keys.pb.Ed448Signature prover_signature = 1; // BLS short signature over the Ed448 prover public key, using the additive // share of the first power. quilibrium.node.keys.pb.BLS48581Signature contribution_signature = 2; } message CeremonyAdvanceRound { repeated CeremonyTranscriptCommit commits = 1; } message CeremonyLobbyJoin { uint64 frame_number = 1; quilibrium.node.keys.pb.X448PublicKey identity_key = 2; quilibrium.node.keys.pb.X448PublicKey signed_pre_key = 3; quilibrium.node.keys.pb.Ed448Signature public_key_signature_ed448 = 4; bytes peer_id = 5; } message CeremonyLobbyStateTransition { repeated string type_urls = 1; repeated bytes transition_inputs = 2; } message CeremonyOpenState { repeated CeremonyLobbyJoin joined_participants = 1; repeated quilibrium.node.keys.pb.Ed448PublicKey preferred_participants = 2; } message CeremonyInProgressState { repeated CeremonyLobbyJoin active_participants = 1; repeated CeremonySeenProverAttestation latest_seen_prover_attestations = 2; repeated CeremonyDroppedProverAttestation dropped_participant_attestations = 3; repeated CeremonyAdvanceRound transcript_round_advance_commits = 4; repeated quilibrium.node.keys.pb.Ed448PublicKey next_round_participants = 5; } message CeremonyFinalizingState { repeated CeremonyLobbyJoin active_participants = 1; repeated CeremonySeenProverAttestation latest_seen_prover_attestations = 2; repeated CeremonyDroppedProverAttestation dropped_participant_attestations = 3; repeated CeremonyTranscriptCommit commits = 4; repeated CeremonyTranscriptShare shares = 5; repeated quilibrium.node.keys.pb.Ed448PublicKey next_round_participants = 6; } message CeremonyValidatingState { repeated CeremonyTranscriptCommit commits = 1; CeremonyTranscript updated_transcript = 2; repeated quilibrium.node.keys.pb.Ed448PublicKey next_round_participants = 3; } message CeremonyPeerListAnnounce { repeated CeremonyPeer peer_list = 1; } message CeremonyPeer { bytes peer_id = 1; string multiaddr = 2; uint64 max_frame = 3; int64 timestamp = 4; bytes version = 5; bytes signature = 6; bytes public_key = 7; bytes total_distance = 8; } message CeremonyCompressedSync { uint64 from_frame_number = 1; uint64 to_frame_number = 2; repeated quilibrium.node.clock.pb.ClockFrame truncated_clock_frames = 3; repeated InclusionProofsMap proofs = 4; repeated InclusionSegmentsMap segments = 5; } message SyncRequestAuthentication { bytes peer_id = 1; bytes challenge = 2; quilibrium.node.keys.pb.Ed448Signature response = 3; } message CeremonyCompressedSyncRequestMessage { oneof sync_message { quilibrium.node.clock.pb.ClockFramesPreflight preflight = 1; quilibrium.node.clock.pb.ClockFramesRequest request = 2; SyncRequestAuthentication authentication = 3; } } message CeremonyCompressedSyncResponseMessage { oneof sync_message { quilibrium.node.clock.pb.ClockFramesPreflight preflight = 1; CeremonyCompressedSync response = 2; } } message InclusionProofsMap { bytes frame_commit = 1; bytes proof = 2; repeated InclusionCommitmentsMap commitments = 3; } message InclusionSegmentsMap { bytes hash = 1; bytes data = 2; } message InclusionCommitmentsMap { bytes commitment = 1; string type_url = 2; repeated bytes segment_hashes = 3; } message GetDataFrameRequest { uint64 frame_number = 1; } message DataFrameResponse { quilibrium.node.clock.pb.ClockFrame clock_frame = 1; bytes proof = 2; } service CeremonyService { rpc GetCompressedSyncFrames (quilibrium.node.clock.pb.ClockFramesRequest) returns (stream CeremonyCompressedSync); rpc NegotiateCompressedSyncFrames (stream CeremonyCompressedSyncRequestMessage) returns (stream CeremonyCompressedSyncResponseMessage); rpc GetPublicChannel (stream quilibrium.node.channel.pb.P2PChannelEnvelope) returns (stream quilibrium.node.channel.pb.P2PChannelEnvelope); rpc GetDataFrame (GetDataFrameRequest) returns (DataFrameResponse); }