#protocols #async-stream #noise #encryption #minimalist #tokio #secure

snowstorm

A minimalistic encryption protocol based on Noise protocol (snow)

7 unstable releases (3 breaking)

0.4.0 May 20, 2022
0.3.1 Jan 14, 2022
0.2.0 Jan 3, 2022
0.1.3 Dec 25, 2021

#469 in Cryptography

Download history 1509/week @ 2023-11-20 782/week @ 2023-11-27 615/week @ 2023-12-04 1099/week @ 2023-12-11 531/week @ 2023-12-18 432/week @ 2023-12-25 885/week @ 2024-01-01 1671/week @ 2024-01-08 2740/week @ 2024-01-15 3185/week @ 2024-01-22 1425/week @ 2024-01-29 1424/week @ 2024-02-05 983/week @ 2024-02-12 942/week @ 2024-02-19 1271/week @ 2024-02-26 1346/week @ 2024-03-04

4,612 downloads per month
Used in 2 crates

Apache-2.0

32KB
690 lines

Snowstorm

A minimalistic encryption protocol for rust async streams / packets, based on noise protocol and snow.

Quickstart

Snowstorm allows you to secure any streams implemented AsyncRead + AsyncWrite + Unpin. For example, TcpStream in Tokio. Note that the underlying connections need to be reliable.

Create a Key Pair

// Noise protocol params, see: http://www.noiseprotocol.org/noise.html#protocol-names-and-modifiers
// Use `KK` to enable bidirectional identity verification
static PATTERN: &str = "Noise_KK_25519_ChaChaPoly_BLAKE2s"; 

// Generate a private / public key pair
let key_pair = snowstorm::Builder::new(PATTERN.parse()?).generate_keypair().unwrap()

Client


// Connect to the peer
let stream = TcpStream::connect("127.0.0.1:12345").await?;

// The client should build an initiator to launch the handshake process
let initiator = snowstorm::Builder::new(PATTERN.parse()?)
    .local_private_key(local_private_key)
    .remote_public_key(remote_public_key)
    .build_initiator()?;

// Start handshaking
let mut secured_stream = NoiseStream::handshake(stream, initiator).await?;

// A secured stream `NoiseStream<T>` will be return once the handshake is done
secured_stream.write_all(b"hello world").await?;

Server


// Accept a `TcpStream` from the listener
let listener = TcpListener::bind("127.0.0.1:12345").await?;
let (stream, _) = listener.accept().await?;

// The server needs a responder to handle handshake reqeusts from clients
let responder = snowstorm::Builder::new(PATTERN.parse()?)
    .local_private_key(local_private_key)
    .remote_public_key(remote_public_key)
    .build_responder()?;

// Start handshaking
let mut secured_stream = NoiseStream::handshake(stream, responder).await?;

let mut buf = [0; 1024];
secured_stream.read(&mut buf).await?;

Spec

Stream

[ length (2 bytes, little endian) ] [ noise message (length bytes) ]

Packet

[ nonce (8 bytes) ] [ noise message ]

Todo

  • UDP Support
  • Documentation
  • Benchmarks
  • Async-std support

Dependencies

~3.5–5.5MB
~91K SLoC