1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
//! Continuous BLS threshold-key resharing for an application chain.
//!
//! This module runs the ongoing reshare protocol after a chain already has an
//! initial threshold output. It lets an application rotate the set of threshold
//! share holders over time without exposing the aggregate signing key and
//! without requiring a trusted party to redistribute private shares.
//!
//! The reshare actor is a protocol companion that:
//!
//! - reads finalized [`EpochInfo`](crate::dkg::types::EpochInfo) artifacts from
//! application blocks,
//! - exchanges private Feldman-Desmedt dealings with peers during each epoch,
//! - asks the application to include public dealer logs on-chain,
//! - derives the next epoch's [`EpochInfo`](crate::dkg::types::EpochInfo), and
//! - registers signer or verifier schemes through the application-provided
//! [`Registrar`](crate::dkg::Registrar).
//!
//! # Epoch Artifacts
//!
//! Every epoch is described by an [`EpochInfo`](crate::dkg::types::EpochInfo)
//! carried in a finalized boundary block. For epoch zero this artifact is part
//! of genesis. For later epochs it is carried in the final block of the previous
//! epoch.
//!
//! An epoch artifact is a lookahead:
//!
//! - `output` is the public threshold output whose players are the dealers for
//! the described epoch.
//! - `players` are the share holders targeted by the ceremony in the described
//! epoch.
//! - `next_players` are announced one epoch early so future players can connect
//! and state sync before they must receive private dealings.
//! - `outcome` records whether the ceremony that produced this boundary
//! artifact succeeded or failed.
//!
//! On success, the artifact contains the newly generated output. On failure,
//! the artifact carries the previous output forward, advances `players` to the
//! previously announced `next_players`, and refreshes `next_players` from the
//! [`ParticipantsProvider`](crate::dkg::ParticipantsProvider).
//!
//! # Protocol Flow
//!
//! Each epoch has three logical windows:
//!
//! 1. **Setup** loads the finalized boundary artifact, recovers durable protocol
//! state, registers the current epoch's scheme, and determines whether this
//! node is a dealer, player, both, or only an observer.
//! 2. **Dealing** runs in the early half of the epoch. Dealers send private
//! shares directly to players over the DKG P2P channel. Players verify those
//! shares and return signed acknowledgements.
//! 3. **Inclusion** runs from the midpoint through the final block. Dealers with
//! enough acknowledgements construct public dealer logs. The application
//! includes those logs in blocks, and the final block carries the next
//! epoch's [`EpochInfo`](crate::dkg::types::EpochInfo).
//!
//! ```text
//! boundary EpochInfo(E)
//! |
//! v
//! setup and scheme registration
//! |
//! v
//! early epoch: private dealings and acknowledgements over P2P
//! |
//! v
//! midpoint onward: dealer logs are posted on-chain
//! |
//! v
//! final block: EpochInfo(E + 1)
//! ```
//!
//! Finalized application blocks are the source of truth. Private P2P traffic may
//! be retried or recovered locally, but dealer logs and epoch artifacts affect
//! durable protocol state only after they are finalized on-chain.
//!
//! # Application Contract
//!
//! Application blocks implement [`ReshareBlock`](crate::dkg::ReshareBlock) and
//! carry at most one [`Payload`](crate::dkg::types::Payload). The application is
//! responsible for wiring proposal and verification to [`Mailbox`]:
//!
//! - Before the final block of an epoch, proposers call [`Mailbox::next_log`],
//! include the reserved dealer log if one is returned, and keep the
//! reservation only after a block is built.
//! - Before the final block of an epoch, verifiers treat dealer logs as ordinary
//! optional payloads and rely on finalized delivery to update the reshare
//! actor.
//! - At the final block of an epoch, proposers call [`Mailbox::epoch_info`] and
//! include the returned [`EpochInfo`](crate::dkg::types::EpochInfo).
//! - At the final block of an epoch, verifiers also call [`Mailbox::epoch_info`]
//! and must reject any block whose payload is not the same
//! [`EpochInfo`](crate::dkg::types::EpochInfo).
//!
//! The final-block call receives the pending ancestry between the finalized tip
//! and the block under construction or verification. This matters because the
//! application may be proposing or verifying above the finalized tip; dealer logs
//! in that pending ancestry can change the ceremony outcome, but they must not be
//! written durably until the corresponding blocks finalize.
//!
//! Marshal must report finalized blocks to the reshare actor. The actor
//! acknowledges a finalized block only after any protocol state, secret state,
//! registrar update, and epoch fence update required by that block is complete.
//!
//! # Secret Material
//!
//! The protocol deliberately does not prescribe secret storage. Applications
//! provide a [`SecretStore`](crate::dkg::SecretStore) that matches their security
//! policy.
//!
//! The store contains private shares, private dealings, and dealer randomness
//! seeds. These values must not be placed in public protocol storage or
//! application state. The actor uses them for restart recovery, including
//! carrying a valid share forward when a ceremony fails and the previous
//! threshold output remains active.
//!
//! # Offline Players
//!
//! A validator that is selected as a `player` must be online and reachable
//! during the early dealing window if it expects its new secret share to remain
//! private.
//!
//! Feldman-Desmedt resharing preserves liveness by allowing dealers to publish
//! reveal evidence for players that do not return valid acknowledgements. If a
//! validator is offline while it is a `player`, the ceremony can still succeed,
//! but the validator's secret share for the new output will be revealed in the
//! public dealer logs. The resulting output is protocol-valid; reveal-bearing
//! outputs are not rejected by this reshare actor.
//!
//! Operationally, an offline player should treat the affected secret share as
//! public. It must not assume that coming back online later restores the
//! privacy of that share. Applications that require every active signing share
//! to remain unrevealed must enforce that policy outside this protocol.
//!
//! # State Sync
//!
//! Reshare is compatible with application state sync, but timing matters. A
//! certified floor at or before an epoch's midpoint preserves the complete public
//! dealer-log inclusion window, so the actor can participate in that epoch. A
//! floor after the midpoint has skipped part of that history, so the actor follows
//! the reshare ceremony for the remainder of the epoch and resumes at the next
//! boundary.
//!
//! State-sync startup still registers the certified current-epoch consensus
//! scheme before entering follower mode. A follower with a recovered share may
//! sign ordinary non-boundary blocks, but cannot locally derive the next
//! [`EpochInfo`](crate::dkg::types::EpochInfo) needed to propose or complete
//! verification of the final block. It learns that outcome from external
//! finalization instead.
//!
//! A `player` that missed private dealings may need public reveals to reconstruct
//! its share, but a revealed share is no longer private. Announcing a node as a
//! `next_player` one epoch early gives it time to state sync and be online for the
//! private dealing window before its share is needed.
//!
//! This is why [`ParticipantsProvider`](crate::dkg::ParticipantsProvider) can be
//! backed by chain state: the chain can announce future players before their
//! shares are needed.
//!
//! # One-Shot DKG
//!
//! Initial threshold-secret generation is exposed through
//! [`bootstrap`](crate::dkg::bootstrap). That engine reuses the same actor in a
//! crate-private DKG mode, runs it on a contained one-epoch consensus chain, and
//! returns an [`EpochInfo`](crate::dkg::types::EpochInfo) suitable for the
//! genesis artifact of a later reshare-enabled application chain.
pub use ;
pub use DkgConfig;
pub use ;
pub use ;
pub