pub struct HandshakeServer { /* private fields */ }Expand description
Handshake Server State Machine
Holds the server’s long-lived signing key (via HybridSigningKey, which
itself zeroes on drop) and a master secret from which the actually-used
per-hour PoW/cookie secret is derived on each call (see
derive_session_secret_for_hour). On drop the master is zeroed via the
derived ZeroizeOnDrop.
Rotation (Phase 1.11): the master itself rotates only on process restart, but the derived hour-bucketed secret rotates every hour. Validation accepts the current hour and the immediately-previous hour, so a cookie or PoW solution captured at minute 59 of one hour is still honored at minute 5 of the next.
Implementations§
Source§impl HandshakeServer
impl HandshakeServer
pub fn new() -> Result<Self, HandshakeError>
Sourcepub fn with_signing_key(
signing_key: HybridSigningKey,
) -> Result<Self, HandshakeError>
pub fn with_signing_key( signing_key: HybridSigningKey, ) -> Result<Self, HandshakeError>
Build a HandshakeServer from a caller-supplied long-lived
HybridSigningKey (Phase 7.4 follow-up).
Used by embedders that persist the server’s signing key across
restarts so client pinning material does not change on every
boot. The verifying key is derived from the supplied signing key,
the per-process master secret is freshly generated, and the
remaining state (PoW counters, session cache) initializes the
same way as Self::new.
The supplied signing_key is moved in and held under
HandshakeServer’s ZeroizeOnDrop — the same memory-hygiene
invariant as the auto-generated path.
Sourcepub fn adaptive_difficulty(&self) -> u8
pub fn adaptive_difficulty(&self) -> u8
Recommended PoW difficulty for the current handshake load. Callers
(e.g. PhantomListener::accept) pass this into process_client_hello
so the cost imposed on each new client scales with server load.
Difficulty tiers (handshakes-per-minute → difficulty):
<100 → 0 (no PoW)
100..500 → 4 (~16 hash evaluations expected)
500..2000 → 8 (~256 evaluations)
2000..10000 → 12 (~4k evaluations)
>=10000 → 16 (~64k evaluations)These tiers err on the side of leniency: a healthy server doing a few hundred handshakes per minute imposes no PoW work on clients. Only at high load — where DoS protection matters most — does the cost ramp up.
Sourcepub fn handshakes_this_minute(&self) -> u64
pub fn handshakes_this_minute(&self) -> u64
Current per-minute handshake count. Exposed for metrics
(handshakes_per_minute).
pub fn process_client_hello( &self, client_hello: &ClientHello, difficulty: u8, client_ip: IpAddr, ) -> HandshakeResponse
pub fn verifying_key(&self) -> &HybridVerifyingKey
Sourcepub fn session_cache_len(&self) -> usize
pub fn session_cache_len(&self) -> usize
Number of tickets currently held in the resumption cache. Exposed for metrics / tests; not on the hot path. Phase 4.1.