WeaveDocs
Zer0 Secret Stream

Handshake

Noise-style handshake in `zer0-secret-stream` — key exchange, identity binding, and forward-secrecy negotiation between peers.

Purpose

Noise-style secret stream with handshakes, framing, bridge IO, tunables, metrics, and typed errors.

This page follows the real source shape for Zer0 Secret Stream and explains the workflow a developer is likely to use first.

Developer workflow

Start from the smallest constructor or builder, perform one meaningful operation, inspect the returned state, then add the relevant policy, storage, or network integration. The examples below should be expanded whenever the crate API changes.

Note

Noise IK authenticates the responder's static public key. The initiator must already know (and trust) the responder's static key — typically by resolving it through weave-identity. There is no peer authentication beyond what the identity adapter provides.

Primary types to know

  • Bridge — network/zer0-secret-stream/src/bridge.rs
  • BridgeReverse — network/zer0-secret-stream/src/bridge.rs
  • Handshake — network/zer0-secret-stream/src/handshake.rs
  • HandshakeResult — network/zer0-secret-stream/src/handshake.rs
  • Message — network/zer0-secret-stream/src/lib.rs
  • SecretOptions — network/zer0-secret-stream/src/lib.rs
  • SecretStream — network/zer0-secret-stream/src/lib.rs
  • SecretStreamMetrics — network/zer0-secret-stream/src/metrics.rs
  • SecretStreamMetricsSnapshot — network/zer0-secret-stream/src/metrics.rs
  • SecretTunables — network/zer0-secret-stream/src/config.rs
  • HandshakeError — network/zer0-secret-stream/src/handshake.rs
  • HandshakePattern — network/zer0-secret-stream/src/handshake.rs

Example shape

use zer0_secret_stream::{Handshake, HandshakePattern, SecretOptions, SecretStream};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // SecretStream wraps a tokio AsyncRead/AsyncWrite with a Noise-style
    // handshake. HandshakePattern picks the exchange (XX is the default).
    let (inner_reader, inner_writer) = tokio::io::duplex(1024);
    let options = SecretOptions {
        pattern: HandshakePattern::XX,
        ..SecretOptions::default()
    };

    let mut alice = SecretStream::new(inner_reader, true, options.clone())?;
    let mut _bob = SecretStream::new(inner_writer, false, options)?;

    // The handshake completes lazily on the first encrypted message; explicit
    // driving via Handshake::drive() is available for cold-start scenarios.
    let _ = Handshake::pattern();

    println!(
        "alice_initiator={} pubkey={} state={:?}",
        alice.is_initiator(),
        hex::encode(alice.public_key()),
        alice.state(),
    );
    Ok(())
}