whitenoise.systems

@noisytransfer/noisystream

Frame‑based streaming helpers for the NoisyTransfer protocol.

@noisytransfer/noisystream

Note: Currently everything is under heavy development and in a very early alpha stage. APIs are thus unstable and can change without notice.

Utilities for encrypted, ordered streaming of bytes using the NoisyTransfer protocol. It exposes a small API for sending/receiving files (or other byte sources) over an ordered transport (e.g. an ordered RTCDataChannel).

Install

npm i @noisytransfer/noisystream

Exports (v0.2.x)

  • sendFileWithAuth(opts)
  • recvFileWithAuth(opts)
  • STREAM frame constants
  • Frame helpers: packStreamInit, parseStreamInit, packStreamReady, parseStreamReady, packStreamData, parseStreamData, packStreamFin, parseStreamFin
  • Type guards: isStreamInit, isStreamReady, isStreamData, isStreamFin

Minimal example

import { sendFileWithAuth, recvFileWithAuth } from "@noisytransfer/noisystream";

// Receiver: collect bytes to a sink (e.g., file writer or Blob builder)
const recvP = recvFileWithAuth({
  tx,                     // ordered transport: { send, onMessage }
  sessionId,              // unique ID for this stream
  hpke: { ownPriv },      // HPKE private key (receiver decrypts)
  sign: { verifyKey },    // verify the sender's signature
  sink: (u8) => sink.write(u8),
  totalBytes,             // required for streaming sources
});

// Sender: stream chunks from a source
await sendFileWithAuth({
  tx,
  sessionId,
  hpke: { peerPub },      // HPKE public key (encrypt to receiver)
  sign: { signingKey },   // sign each chunk
  source: myFileOrIterable
});

await recvP; // wait for receiver to finish

Data sources

Works with Uint8Array/ArrayBuffer, Blob (browser), or any (async) iterable of byte chunks. Provide totalBytes when the source is a stream/iterator.

Notes

  • Requires an ordered message channel; out‑of‑order transports are not supported.
  • Crypto package is not yet fully integrated into noisystream. You need to create the key material outside of noisystream. But its planned to do integrate it in the future.

Cryptography Bill of Materials

The following section summarizes the cryptographic primitives, libraries, and protocol constructs that are implemented or consumed by the NoisyTransfer package @noisytransfer/noisystream. It’s generated with codex, but reviewed by me.

HPKE-Protected Streaming

  • The sender requires the receiver’s HPKE public key bytes and creates a stream AEAD context via mkAeadStreamFromHpke. Ciphertexts for each data frame are produced with HPKE AEAD sealing, and the encapsulated key (hpkeEnc) is transmitted in the initial frame.
  • The receiver reconstructs the same HPKE stream (using its private key) and decrypts data frames in order, enforcing AEAD usage and buffering limits.

AEAD Associated Data Identification

  • Both roles derive a canonical HPKE AAD identifier by SHA-256 hashing a JSON description of the stream parameters (protocol, version, direction, session ID, and total length) and encoding it with base64url; this identifier is also bound into the streaming transcript and handshake frames.

Transcript Signing and Verification

  • While sending, the package hashes every ciphertext frame using the incremental signature helpers and signs the final digest (typically with RSA-PSS) before emitting the stream_fin frame.
  • The receiver mirrors the transcript hashing, imports an RSA-PSS verification key (either configured or attached to the FIN frame), and validates the signature before acknowledging completion.

Package-Level Cryptography Dependencies

  • @noisytransfer/noisystream depends on @noisytransfer/crypto for all HPKE, hashing, and signature primitives, while @noisytransfer/crypto brings in the HPKE and hashing libraries listed above via its package manifest from hpke-js.