Documentation
¶
Overview ¶
Package voting is a worked example showing how to build a non-FHE application on top of the ARES framework. Voters submit signed weighted ballots; the orchestrator tallies the weighted sum and publishes a signed transcript with the result.
The pipeline reuses the default state vocabulary (INVITING, LOCKED, GOSSIP, SCORING, DECRYPTING, BROADCASTING) so it can drop in keygen.PlaintextKeygen (which owns LOCKED -> GOSSIP) unchanged. There is no cryptographic privacy beyond transport-layer signing — this example exists to demonstrate that the ARES phase-composition machinery works for protocols whose scoring shape is "sum the inputs" rather than "FHE argmax of encrypted scores".
Pipeline:
PhaseInvite INVITING -> LOCKED (server-side, defaults shape) keygen.Plaintext LOCKED -> GOSSIP (no-crypto keygen) PhaseSubmitVote GOSSIP -> SCORING (accumulate ballots) PhaseTally SCORING -> DECRYPTING (compute weighted sum) PhaseSettle DECRYPTING -> (terminal / StateNone) (emit signed transcript)
Index ¶
- Constants
- func Pipeline() (*phase.SessionRunner, error)
- func PipelineWithLineage(signer sign.Signer, peerVerifiers map[string]sign.Signer) (*phase.SessionRunner, error)
- func PipelineWithShuffle(signer sign.Signer, peerVerifiers map[string]sign.Signer) (*phase.SessionRunner, error)
- type Ballot
- type PhaseInvite
- func (PhaseInvite) CheckComplete(*phase.SessionContext) bool
- func (PhaseInvite) ConsumedMessageTypes() []string
- func (PhaseInvite) Enter(*phase.SessionContext) error
- func (PhaseInvite) EntryState() phase.SessionState
- func (PhaseInvite) Exit(*phase.SessionContext) error
- func (PhaseInvite) ExitState() phase.SessionState
- func (PhaseInvite) InternalStates() []phase.SessionState
- func (PhaseInvite) Lifetime() phase.Lifetime
- func (PhaseInvite) Name() string
- func (PhaseInvite) OnMessage(*phase.SessionContext, string, string, []byte) error
- func (PhaseInvite) Provides() phase.ContextSchema
- func (PhaseInvite) Requires() phase.ContextSchema
- func (PhaseInvite) RunsAt() phase.RunsAt
- type PhaseSettle
- func (PhaseSettle) CheckComplete(*phase.SessionContext) bool
- func (PhaseSettle) ConsumedMessageTypes() []string
- func (PhaseSettle) Enter(ctx *phase.SessionContext) error
- func (PhaseSettle) EntryState() phase.SessionState
- func (PhaseSettle) Exit(*phase.SessionContext) error
- func (PhaseSettle) ExitState() phase.SessionState
- func (PhaseSettle) InternalStates() []phase.SessionState
- func (PhaseSettle) Lifetime() phase.Lifetime
- func (PhaseSettle) Name() string
- func (PhaseSettle) OnMessage(*phase.SessionContext, string, string, []byte) error
- func (PhaseSettle) Provides() phase.ContextSchema
- func (PhaseSettle) Requires() phase.ContextSchema
- func (PhaseSettle) RunsAt() phase.RunsAt
- type PhaseSubmitVote
- func (PhaseSubmitVote) CheckComplete(ctx *phase.SessionContext) bool
- func (PhaseSubmitVote) ConsumedMessageTypes() []string
- func (PhaseSubmitVote) Enter(*phase.SessionContext) error
- func (p PhaseSubmitVote) EntryState() phase.SessionState
- func (PhaseSubmitVote) Exit(ctx *phase.SessionContext) error
- func (PhaseSubmitVote) ExitState() phase.SessionState
- func (PhaseSubmitVote) InternalStates() []phase.SessionState
- func (PhaseSubmitVote) Lifetime() phase.Lifetime
- func (PhaseSubmitVote) Name() string
- func (PhaseSubmitVote) OnMessage(ctx *phase.SessionContext, _, from string, payload []byte) error
- func (PhaseSubmitVote) Provides() phase.ContextSchema
- func (PhaseSubmitVote) Requires() phase.ContextSchema
- func (PhaseSubmitVote) RunsAt() phase.RunsAt
- type PhaseTally
- func (PhaseTally) CheckComplete(*phase.SessionContext) bool
- func (PhaseTally) ConsumedMessageTypes() []string
- func (PhaseTally) Enter(ctx *phase.SessionContext) error
- func (PhaseTally) EntryState() phase.SessionState
- func (PhaseTally) Exit(*phase.SessionContext) error
- func (PhaseTally) ExitState() phase.SessionState
- func (PhaseTally) InternalStates() []phase.SessionState
- func (PhaseTally) Lifetime() phase.Lifetime
- func (PhaseTally) Name() string
- func (PhaseTally) OnMessage(*phase.SessionContext, string, string, []byte) error
- func (PhaseTally) Provides() phase.ContextSchema
- func (PhaseTally) Requires() phase.ContextSchema
- func (PhaseTally) RunsAt() phase.RunsAt
- type Tally
Constants ¶
const ( CtxVoteParticipants = "vote.participants" CtxVoteBallots = "vote.ballots" // map[string]Ballot CtxVoteTally = "vote.tally" // Tally CtxVoteTranscript = "vote.transcript" // signed transcript bytes )
SessionContext keys produced and consumed by the voting pipeline.
Variables ¶
This section is empty.
Functions ¶
func Pipeline ¶
func Pipeline() (*phase.SessionRunner, error)
Pipeline builds the voting SessionRunner:
Invite -> PlaintextKeygen -> SubmitVote -> Tally -> Settle
No FHE; PlaintextKeygen is a documented no-op that fills the LOCKED -> GOSSIP arc without producing crypto material. Use this example as a template for applications whose threat model trusts the orchestrator (regulated governance, internal voting, etc.).
func PipelineWithLineage ¶ added in v0.4.0
func PipelineWithLineage(signer sign.Signer, peerVerifiers map[string]sign.Signer) (*phase.SessionRunner, error)
PipelineWithLineage builds the voting pipeline with SC-10 ciphertext lineage enabled. Ballots are not FHE-encrypted in this example (PlaintextKeygen topology) but lineage still binds each ballot's bytes to its submitter — preventing the election authority from swapping ballots between collection and tally. Demonstrates SC-10 is useful for non-FHE ARES apps too: the binding is over byte payloads, not over cryptographic objects specifically.
func PipelineWithShuffle ¶ added in v0.5.0
func PipelineWithShuffle(signer sign.Signer, peerVerifiers map[string]sign.Signer) (*phase.SessionRunner, error)
PipelineWithShuffle builds the voting pipeline with inter-participant slot anonymity: an onion-shuffle gossip round runs between keygen and ballot submission so the election authority cannot link an anonymized slot to the voter who produced it. Demonstrates the generic pkg/ares/phase/anon primitive on a non-FHE app.
Arc: Invite -> PlaintextKeygen -> Shuffle(GOSSIP->VERIFYING)
-> Verify(VERIFYING->SUBMITTING) -> SubmitVote(SUBMITTING->SCORING) -> Tally -> Settle.
Types ¶
type Ballot ¶
type Ballot struct {
Voter string `json:"voter"`
Choice int `json:"choice"`
Weight float64 `json:"weight"`
}
Ballot is one voter's submission. Weight allows weighted voting (e.g. share-weighted governance). Choice is the integer choice index — the application defines what each index means.
type PhaseInvite ¶
type PhaseInvite struct{}
PhaseInvite opens a voting session. The orchestrator picks the eligible voter set and emits a `vote.invitation` frame to each. Identical shape to `defaults.Phase1aSessionInitiation` — the only difference is the message type and that no crypto contract is declared (plaintext keygen carries no CKKS parameters).
func NewPhaseInvite ¶
func NewPhaseInvite() *PhaseInvite
func (PhaseInvite) CheckComplete ¶
func (PhaseInvite) CheckComplete(*phase.SessionContext) bool
func (PhaseInvite) ConsumedMessageTypes ¶
func (PhaseInvite) ConsumedMessageTypes() []string
func (PhaseInvite) Enter ¶
func (PhaseInvite) Enter(*phase.SessionContext) error
func (PhaseInvite) EntryState ¶
func (PhaseInvite) EntryState() phase.SessionState
func (PhaseInvite) Exit ¶
func (PhaseInvite) Exit(*phase.SessionContext) error
func (PhaseInvite) ExitState ¶
func (PhaseInvite) ExitState() phase.SessionState
func (PhaseInvite) InternalStates ¶
func (PhaseInvite) InternalStates() []phase.SessionState
func (PhaseInvite) Lifetime ¶
func (PhaseInvite) Lifetime() phase.Lifetime
func (PhaseInvite) Name ¶
func (PhaseInvite) Name() string
func (PhaseInvite) OnMessage ¶
func (PhaseInvite) OnMessage(*phase.SessionContext, string, string, []byte) error
func (PhaseInvite) Provides ¶
func (PhaseInvite) Provides() phase.ContextSchema
func (PhaseInvite) Requires ¶
func (PhaseInvite) Requires() phase.ContextSchema
func (PhaseInvite) RunsAt ¶
func (PhaseInvite) RunsAt() phase.RunsAt
type PhaseSettle ¶
type PhaseSettle struct{}
PhaseSettle emits a signed transcript carrying the tally. Closely mirrors `sealed_bid_auction.PhaseSettlement` shape: synchronous Enter that writes a transcript artifact, ExitState terminal.
func NewPhaseSettle ¶
func NewPhaseSettle() *PhaseSettle
func (PhaseSettle) CheckComplete ¶
func (PhaseSettle) CheckComplete(*phase.SessionContext) bool
func (PhaseSettle) ConsumedMessageTypes ¶
func (PhaseSettle) ConsumedMessageTypes() []string
func (PhaseSettle) Enter ¶
func (PhaseSettle) Enter(ctx *phase.SessionContext) error
func (PhaseSettle) EntryState ¶
func (PhaseSettle) EntryState() phase.SessionState
func (PhaseSettle) Exit ¶
func (PhaseSettle) Exit(*phase.SessionContext) error
func (PhaseSettle) ExitState ¶
func (PhaseSettle) ExitState() phase.SessionState
func (PhaseSettle) InternalStates ¶
func (PhaseSettle) InternalStates() []phase.SessionState
func (PhaseSettle) Lifetime ¶
func (PhaseSettle) Lifetime() phase.Lifetime
func (PhaseSettle) Name ¶
func (PhaseSettle) Name() string
func (PhaseSettle) OnMessage ¶
func (PhaseSettle) OnMessage(*phase.SessionContext, string, string, []byte) error
func (PhaseSettle) Provides ¶
func (PhaseSettle) Provides() phase.ContextSchema
func (PhaseSettle) Requires ¶
func (PhaseSettle) Requires() phase.ContextSchema
func (PhaseSettle) RunsAt ¶
func (PhaseSettle) RunsAt() phase.RunsAt
type PhaseSubmitVote ¶
type PhaseSubmitVote struct {
// contains filtered or unexported fields
}
PhaseSubmitVote accumulates one `vote.ballot` from each participant. Wire shape:
{"choice": 1, "weight": 1.5}
The voter's identity is taken from the WS pseudonym, not the payload (preventing cross-voter ballot stuffing under the same account).
entryState defaults to GOSSIP; when the shuffle phases are composed ahead of it, the pipeline re-points it to SUBMITTING.
func NewPhaseSubmitVote ¶
func NewPhaseSubmitVote() *PhaseSubmitVote
NewPhaseSubmitVote returns a submit phase entering at GOSSIP (the no-shuffle pipeline). Use NewPhaseSubmitVoteAt to re-point it.
func NewPhaseSubmitVoteAt ¶ added in v0.5.0
func NewPhaseSubmitVoteAt(entry phase.SessionState) *PhaseSubmitVote
NewPhaseSubmitVoteAt returns a submit phase entering at the given state (used when the onion-shuffle arc precedes it).
func (PhaseSubmitVote) CheckComplete ¶
func (PhaseSubmitVote) CheckComplete(ctx *phase.SessionContext) bool
func (PhaseSubmitVote) ConsumedMessageTypes ¶
func (PhaseSubmitVote) ConsumedMessageTypes() []string
func (PhaseSubmitVote) Enter ¶
func (PhaseSubmitVote) Enter(*phase.SessionContext) error
func (PhaseSubmitVote) EntryState ¶
func (p PhaseSubmitVote) EntryState() phase.SessionState
func (PhaseSubmitVote) Exit ¶
func (PhaseSubmitVote) Exit(ctx *phase.SessionContext) error
func (PhaseSubmitVote) ExitState ¶
func (PhaseSubmitVote) ExitState() phase.SessionState
func (PhaseSubmitVote) InternalStates ¶
func (PhaseSubmitVote) InternalStates() []phase.SessionState
func (PhaseSubmitVote) Lifetime ¶
func (PhaseSubmitVote) Lifetime() phase.Lifetime
func (PhaseSubmitVote) Name ¶
func (PhaseSubmitVote) Name() string
func (PhaseSubmitVote) OnMessage ¶
func (PhaseSubmitVote) OnMessage(ctx *phase.SessionContext, _, from string, payload []byte) error
func (PhaseSubmitVote) Provides ¶
func (PhaseSubmitVote) Provides() phase.ContextSchema
func (PhaseSubmitVote) Requires ¶
func (PhaseSubmitVote) Requires() phase.ContextSchema
func (PhaseSubmitVote) RunsAt ¶
func (PhaseSubmitVote) RunsAt() phase.RunsAt
type PhaseTally ¶
type PhaseTally struct{}
PhaseTally sums weights per choice and picks the largest. This is the voting equivalent of an FHE app's PhaseArgmax — same pipeline arc (SCORING -> DECRYPTING) but plaintext math.
func NewPhaseTally ¶
func NewPhaseTally() *PhaseTally
func (PhaseTally) CheckComplete ¶
func (PhaseTally) CheckComplete(*phase.SessionContext) bool
func (PhaseTally) ConsumedMessageTypes ¶
func (PhaseTally) ConsumedMessageTypes() []string
func (PhaseTally) Enter ¶
func (PhaseTally) Enter(ctx *phase.SessionContext) error
func (PhaseTally) EntryState ¶
func (PhaseTally) EntryState() phase.SessionState
func (PhaseTally) Exit ¶
func (PhaseTally) Exit(*phase.SessionContext) error
func (PhaseTally) ExitState ¶
func (PhaseTally) ExitState() phase.SessionState
func (PhaseTally) InternalStates ¶
func (PhaseTally) InternalStates() []phase.SessionState
func (PhaseTally) Lifetime ¶
func (PhaseTally) Lifetime() phase.Lifetime
func (PhaseTally) Name ¶
func (PhaseTally) Name() string
func (PhaseTally) OnMessage ¶
func (PhaseTally) OnMessage(*phase.SessionContext, string, string, []byte) error
func (PhaseTally) Provides ¶
func (PhaseTally) Provides() phase.ContextSchema
func (PhaseTally) Requires ¶
func (PhaseTally) Requires() phase.ContextSchema
func (PhaseTally) RunsAt ¶
func (PhaseTally) RunsAt() phase.RunsAt
type Tally ¶
type Tally struct {
Totals map[int]float64 `json:"totals"` // choice -> sum(weights)
TotalBallots int `json:"total_ballots"`
WinnerChoice int `json:"winner_choice"`
WinnerWeight float64 `json:"winner_weight"`
}
Tally is the result of summing weighted choices. WinnerChoice is the choice with the largest weighted sum.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
session-service
command
Command session-service runs the voting example (onion-shuffle + SC-10 lineage variant) as a standalone HTTP+WebSocket service.
|
Command session-service runs the voting example (onion-shuffle + SC-10 lineage variant) as a standalone HTTP+WebSocket service. |