protocol

package
v0.0.0-...-bb56c0c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 16, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package protocol implements ADCNet: an anonymous distributed communication network using XOR-based message blinding and auction-based message scheduling.

Protocol Overview

ADCNet provides anonymous broadcast with the following key features:

  • XOR-based blinding for message privacy requiring all servers
  • Auction-based scheduling using Invertible Bloom Lookup Tables (IBLT)

Architecture

The protocol operates through three main components:

  1. Clients: Blind their messages with XOR using one-time pads derived from shared secrets with all servers. Auction bids use field arithmetic blinding.

  2. Aggregators: Combine client messages by XORing message vectors and adding auction vectors in the finite field. This reduces bandwidth to servers.

  3. Servers: Each server removes its blinding factors from the aggregate. Messages are recovered by XORing all server contributions. Auction IBLT is recovered using field subtraction.

Core Protocol Flow

1. Message Preparation (Client):

  • Client determines if it won a slot in the previous round's auction
  • Encodes message at the auction-determined byte offset if so
  • Blinds message with XOR using one-time pads from all server shared secrets
  • Blinds auction IBLT with field addition using server-specific pads

2. Aggregation:

  • Aggregators XOR client message vectors together
  • Aggregators add blinded client auction vectors
  • Multiple aggregation levels can reduce bandwidth hierarchically

3. Unblinding (Server):

  • Each server derives its blinding contribution from shared secrets
  • Server sends XOR of all its XOR blinding vectors for messages and its field element blinding vector for auction and forwards to leader

4. Reconstruction:

  • XOR all server message blindings with aggregate to recover messages
  • Subtract all server auction blindings from aggregate to recover IBLT
  • Decode auction IBLT to determine next round's winners

Security Properties

  • Anonymity: Sender identity protected if at least one server is honest
  • Privacy: Message content hidden unless all servers collude
  • Unlinkability: Fresh blinding prevents correlation between rounds

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AuctionSlotsForConfig

func AuctionSlotsForConfig(c *ADCNetConfig) uint32

AuctionSlotsForConfig calculates total IBLT vector size for the configuration.

func DecodeMessage

func DecodeMessage[T any](reader io.Reader) (*T, error)

DecodeMessage deserializes a message from a JSON reader.

func SerializeMessage

func SerializeMessage[T any](msg *T) ([]byte, error)

SerializeMessage serializes a message to JSON.

func TimeForRound

func TimeForRound(round Round, roundDuration time.Duration) time.Time

TimeForRound returns the start time for a given round.

func UnmarshalMessage

func UnmarshalMessage[T any](data []byte) (*T, error)

UnmarshalMessage deserializes a message from JSON.

Types

type ADCNetConfig

type ADCNetConfig struct {
	// AuctionSlots is the number of slots in the IBLT for auction data.
	AuctionSlots uint32 `json:"auction_slots"`

	// MessageLength is the maximum byte capacity of the message vector.
	// Actual per-round length is determined by auction results.
	MessageLength int `json:"message_length"`

	// MinClients is the minimum number of clients for anonymity.
	MinClients uint32 `json:"min_clients"`

	// RoundDuration is the time duration of each protocol round.
	RoundDuration time.Duration `json:"round_duration,string"`

	// RoundsPerWindow defines rounds per participation window for rate limiting.
	RoundsPerWindow uint32 `json:"rounds_per_window"`
}

ADCNetConfig provides configuration parameters for ADCNet components.

type AggregatedClientMessages

type AggregatedClientMessages struct {
	RoundNumber   int
	AllServerIds  []ServerID
	AuctionVector []*big.Int         // Sum of client auction vectors in field
	MessageVector []byte             // XOR of client message vectors
	UserPKs       []crypto.PublicKey // Public keys of contributing clients
}

AggregatedClientMessages contains combined data from multiple clients.

func (*AggregatedClientMessages) UnionInplace

UnionInplace adds another aggregate's vectors to this one in-place. XORs message vectors and adds auction vectors in the finite field.

type AggregatorMessager

type AggregatorMessager struct {
	Config *ADCNetConfig
}

AggregatorMessager implements message aggregation operations.

func (*AggregatorMessager) AggregateAggregates

func (a *AggregatorMessager) AggregateAggregates(round int, msgs []*AggregatedClientMessages) (*AggregatedClientMessages, error)

AggregateAggregates combines multiple aggregated messages into one.

func (*AggregatorMessager) AggregateVerifiedMessages

func (a *AggregatorMessager) AggregateVerifiedMessages(round int, previousAggregate *AggregatedClientMessages, verified []VerifiedClientMessage, authorizedClients map[string]bool) (*AggregatedClientMessages, error)

AggregateVerifiedMessages combines pre-verified client messages into a single aggregate.

type AggregatorRoundData

type AggregatorRoundData struct {
	Round     int
	Aggregate *AggregatedClientMessages
}

AggregatorRoundData holds per-round aggregation state.

type AggregatorService

type AggregatorService struct {
	// contains filtered or unexported fields
}

AggregatorService combines client messages to reduce bandwidth to servers.

func NewAggregatorService

func NewAggregatorService(config *ADCNetConfig) *AggregatorService

NewAggregatorService creates an aggregator service.

func (*AggregatorService) AdvanceToRound

func (a *AggregatorService) AdvanceToRound(round Round)

AdvanceToRound transitions the aggregator to a new protocol round.

func (*AggregatorService) CurrentAggregates

func (a *AggregatorService) CurrentAggregates() *AggregatedClientMessages

CurrentAggregates returns the current round's aggregate.

func (*AggregatorService) DeregisterClient

func (a *AggregatorService) DeregisterClient(pubkey crypto.PublicKey) error

DeregisterClient removes a client's authorization.

func (*AggregatorService) ProcessClientMessages

func (a *AggregatorService) ProcessClientMessages(msgs []*Signed[ClientRoundMessage]) (*AggregatedClientMessages, error)

ProcessClientMessages verifies and aggregates signed client messages.

func (*AggregatorService) ProcessVerifiedMessages

func (a *AggregatorService) ProcessVerifiedMessages(verified []VerifiedClientMessage) (*AggregatedClientMessages, error)

ProcessVerifiedMessages aggregates pre-verified client messages.

func (*AggregatorService) RegisterClient

func (a *AggregatorService) RegisterClient(pubkey crypto.PublicKey) error

RegisterClient authorizes a client to submit messages.

type AuctionResult

type AuctionResult struct {
	// ShouldSend indicates if the client won a slot.
	ShouldSend bool

	// MessageStartIndex is the byte offset where the message should be placed.
	MessageStartIndex int

	// TotalAllocated indicates how many total bytes have been allocated by the auction
	TotalAllocated int
}

AuctionResult indicates whether a client won an auction slot.

type ClientMessager

type ClientMessager struct {
	Config        *ADCNetConfig
	SharedSecrets map[ServerID]crypto.SharedKey
}

ClientMessager implements client-side message preparation with XOR blinding.

func ClientSetup

func ClientSetup(config *ADCNetConfig, serverPubkeys map[ServerID]*ecdh.PublicKey, clientPrivkey *ecdh.PrivateKey) (*ClientMessager, error)

ClientSetup creates a ClientMessager by deriving shared secrets with all servers.

func (*ClientMessager) BlindClientMessage

func (c *ClientMessager) BlindClientMessage(currentRound int, messageVector []byte, auctionElements []*big.Int) (*ClientRoundMessage, error)

BlindClientMessage applies XOR blinding to message and field-element blinding to auction data.

func (*ClientMessager) PrepareMessage

func (c *ClientMessager) PrepareMessage(currentRound int, previousRoundOutput *RoundBroadcast, previousRoundMessage []byte, currentRoundAuctionData *blind_auction.AuctionData) (*ClientRoundMessage, bool, error)

PrepareMessage creates a blinded message with auction data for the current round.

func (*ClientMessager) ProcessPreviousAuction

func (c *ClientMessager) ProcessPreviousAuction(auctionIBLT *blind_auction.IBLTVector, previousRoundMessage []byte) AuctionResult

ProcessPreviousAuction determines if this client won a slot in the auction.

type ClientRoundMessage

type ClientRoundMessage struct {
	RoundNumber   int
	AllServerIds  []ServerID
	AuctionVector []*big.Int // Field-blinded auction IBLT elements
	MessageVector []byte     // XOR-blinded message bytes
}

ClientRoundMessage contains a client's blinded message and auction data.

type ClientService

type ClientService struct {
	// contains filtered or unexported fields
}

ClientService manages client-side protocol operations.

func NewClientService

func NewClientService(config *ADCNetConfig, signingKey crypto.PrivateKey, exchangeKey *ecdh.PrivateKey) *ClientService

NewClientService creates a client service.

func (*ClientService) AdvanceToRound

func (c *ClientService) AdvanceToRound(round Round)

AdvanceToRound transitions the client to a new protocol round.

func (*ClientService) DeregisterServer

func (c *ClientService) DeregisterServer(serverId ServerID) error

DeregisterServer removes a server's shared secret.

func (*ClientService) MessagesForCurrentRound

func (c *ClientService) MessagesForCurrentRound() (*Signed[ClientRoundMessage], bool, error)

MessagesForCurrentRound generates the blinded message for the current round. Returns the signed message, whether a scheduled message won its auction, and any error.

func (*ClientService) ProcessRoundBroadcast

func (c *ClientService) ProcessRoundBroadcast(rb *RoundBroadcast) error

ProcessRoundBroadcast stores the reconstructed broadcast for auction resolution.

func (*ClientService) RegisterServer

func (c *ClientService) RegisterServer(serverId ServerID, serverExchangePubkey *ecdh.PublicKey) error

RegisterServer establishes a shared secret with a server via ECDH.

func (*ClientService) ScheduleMessageForNextRound

func (c *ClientService) ScheduleMessageForNextRound(msg []byte, bidValue uint32) error

ScheduleMessageForNextRound queues a message with a bid value for the auction. The auction bid will be submitted in the current round's MessagesForCurrentRound call; if won, the message transmits in the following round.

type LocalRoundCoordinator

type LocalRoundCoordinator struct {
	// contains filtered or unexported fields
}

LocalRoundCoordinator provides deterministic round advancement.

func NewLocalRoundCoordinator

func NewLocalRoundCoordinator(roundDuration time.Duration) *LocalRoundCoordinator

NewLocalRoundCoordinator creates a time-based round coordinator.

func (*LocalRoundCoordinator) AdvanceToRound

func (c *LocalRoundCoordinator) AdvanceToRound(round Round)

AdvanceToRound manually advances to a specific round (for testing).

func (*LocalRoundCoordinator) CurrentRound

func (c *LocalRoundCoordinator) CurrentRound() Round

CurrentRound returns the current protocol round number.

func (*LocalRoundCoordinator) Start

func (c *LocalRoundCoordinator) Start(ctx context.Context)

Start begins round progression.

func (*LocalRoundCoordinator) SubscribeToRounds

func (c *LocalRoundCoordinator) SubscribeToRounds(ctx context.Context) <-chan Round

SubscribeToRounds returns a channel that receives round transition notifications.

type PendingMessage

type PendingMessage struct {
	Message     []byte
	AuctionData *blind_auction.AuctionData
}

PendingMessage represents a message submitted by the user, awaiting auction bid submission.

type Round

type Round struct {
	Number  int
	Context RoundContext
}

Round represents a protocol round with its phase context.

func RoundForTime

func RoundForTime(instant time.Time, roundDuration time.Duration) (Round, error)

RoundForTime calculates the round for a given instant.

func (Round) Advance

func (r Round) Advance() Round

Advance returns the next round phase.

func (Round) IsAfter

func (r Round) IsAfter(r2 Round) bool

IsAfter returns true if this round occurs after r2.

type RoundBroadcast

type RoundBroadcast struct {
	RoundNumber   int
	AuctionVector *blind_auction.IBLTVector
	MessageVector []byte
}

RoundBroadcast contains the final reconstructed broadcast for a round.

type RoundContext

type RoundContext int

RoundContext represents the phase within a protocol round.

const (
	ClientRoundContext RoundContext = iota
	AggregatorRoundContext
	ServerPartialRoundContext
	ServerLeaderRoundContext
)

type RoundCoordinator

type RoundCoordinator interface {
	CurrentRound() Round
	SubscribeToRounds(ctx context.Context) <-chan Round
	Start(ctx context.Context)
	AdvanceToRound(round Round)
}

RoundCoordinator manages protocol round transitions.

type ScheduledMessage

type ScheduledMessage struct {
	Message      []byte
	AuctionRound int // Round when the auction bid was submitted
}

ScheduledMessage represents a message whose auction bid has been submitted, awaiting auction resolution and potential transmission.

type ServerID

type ServerID = crypto.ServerID

type ServerMessager

type ServerMessager struct {
	Config        *ADCNetConfig
	ServerID      ServerID
	SharedSecrets map[string]crypto.SharedKey
}

ServerMessager implements server-side operations for message unblinding.

func ServerSetup

func ServerSetup(config *ADCNetConfig, clientPubkeys map[string]*ecdh.PublicKey, serverId ServerID, serverPrivkey *ecdh.PrivateKey) (*ServerMessager, error)

ServerSetup creates a ServerMessager by deriving shared secrets with all clients.

func (*ServerMessager) UnblindAggregate

func (s *ServerMessager) UnblindAggregate(currentRound int, aggregate *AggregatedClientMessages) (*ServerPartialDecryptionMessage, error)

UnblindAggregate computes this server's blinding vector contribution.

func (*ServerMessager) UnblindPartialMessages

func (s *ServerMessager) UnblindPartialMessages(msgs []*ServerPartialDecryptionMessage) (*RoundBroadcast, error)

UnblindPartialMessages reconstructs the final broadcast by combining blinding vectors.

type ServerPartialDecryptionMessage

type ServerPartialDecryptionMessage struct {
	ServerID          ServerID
	OriginalAggregate *AggregatedClientMessages
	UserPKs           []crypto.PublicKey
	AuctionVector     []*big.Int // Server's auction blinding vector
	MessageVector     []byte     // Server's XOR blinding vector
}

ServerPartialDecryptionMessage contains a server's blinding contribution.

type ServerRoundData

type ServerRoundData struct {
	Round                           int
	ServerPartialDecryptionMessages map[ServerID]*ServerPartialDecryptionMessage
	PartialDecryptionMessage        *ServerPartialDecryptionMessage
	RoundOutput                     *RoundBroadcast
}

ServerRoundData holds per-round state for message reconstruction.

type ServerService

type ServerService struct {
	// contains filtered or unexported fields
}

ServerService manages server-side protocol operations.

func NewServerService

func NewServerService(config *ADCNetConfig, serverId ServerID, serverSigningKey crypto.PrivateKey, serverExchangeKey *ecdh.PrivateKey) *ServerService

NewServerService creates a server service with the given configuration and keys.

func (*ServerService) AdvanceToRound

func (s *ServerService) AdvanceToRound(round Round)

AdvanceToRound transitions the server to a new protocol round.

func (*ServerService) DeregisterClient

func (s *ServerService) DeregisterClient(clientPubkey crypto.PublicKey) error

DeregisterClient removes a client's shared secret.

func (*ServerService) ProcessAggregateMessage

func (s *ServerService) ProcessAggregateMessage(msg *AggregatedClientMessages) (*ServerPartialDecryptionMessage, error)

ProcessAggregateMessage removes this server's blinding factors from the aggregate.

func (*ServerService) ProcessPartialDecryptionMessage

func (s *ServerService) ProcessPartialDecryptionMessage(msg *ServerPartialDecryptionMessage) (*RoundBroadcast, error)

ProcessPartialDecryptionMessage collects partial decryptions from servers.

func (*ServerService) RegisterClient

func (s *ServerService) RegisterClient(clientPubkey crypto.PublicKey, clientECDHPubkey *ecdh.PublicKey) error

RegisterClient establishes a shared secret with a client via ECDH.

type Signed

type Signed[T any] struct {
	PublicKey crypto.PublicKey `json:"public_key"`
	Signature crypto.Signature `json:"signature"`
	Object    *T               `json:"object"`
}

Signed wraps a message with Ed25519 signature for authentication.

func NewSigned

func NewSigned[T any](privkey crypto.PrivateKey, obj *T) (*Signed[T], error)

NewSigned creates an authenticated message by signing the serialized object and public key.

func (*Signed[T]) Recover

func (s *Signed[T]) Recover() (*T, crypto.PublicKey, error)

Recover verifies the signature and returns the authenticated object with signer's public key.

func (*Signed[T]) UnsafeObject

func (s *Signed[T]) UnsafeObject() *T

UnsafeObject returns the wrapped object without verifying the signature.

type VerifiedClientMessage

type VerifiedClientMessage struct {
	Message *ClientRoundMessage
	Signer  crypto.PublicKey
}

VerifiedClientMessage contains a pre-verified client message with its signer.

func VerifyClientMessages

func VerifyClientMessages(msgs []*Signed[ClientRoundMessage]) ([]VerifiedClientMessage, error)

VerifyClientMessages verifies signatures on client messages before aggregation. This should be called before acquiring locks to prevent DoS.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL