@noisytransfer/crypto
Core cryptographic helpers used across the NoisyTransfer stack.
@noisytransfer/crypto
Note: Currently everything is under heavy development and in a very early alpha stage. APIs are thus unstable and can change without notice.
Core cryptographic helpers used across the NoisyTransfer stack. This package provides the primitives that higher‑level tools (like @noisytransfer/noisyauth
and @noisytransfer/noisystream
) rely on for key handling, authenticated encryption, and signature verification.
Quick links
- NPM (crypto): https://www.npmjs.com/package/@noisytransfer/crypto
- hpke-js: https://github.com/dajiaji/hpke-js
Use this package when you need abstracted crypto building blocks inside NoisyTransfer apps or tooling. It pairs naturally with session setup from @noisytransfer/noisyauth and the transport from @noisytransfer/noisystream. For low-level i advise you to use the hpke-js package.
Install
npm i @noisytransfer/crypto
What it’s for
- Generate and manage asymmetric key material for identities and sessions.
- Derive shared secrets/keys from a key agreement established elsewhere (e.g., via
@noisytransfer/noisyauth
). - Perform authenticated encryption and decryption of byte payloads.
- Sign and verify messages for integrity and authenticity.
- Provide utilities for secure randomness and encoding/decoding helpers where appropriate.
Typical usage (conceptual)
The exact function names may vary. Treat this as a sketch of how the package is commonly used alongside other NoisyTransfer modules.
// Pseudocode example — consult the package exports for exact APIs.
import * as cryptoNT from "@noisytransfer/crypto";
import { establishSession } from "@noisytransfer/noisyauth";
// 1) Establish a session (e.g., SAS-confirmed) and get key material
const session = await establishSession(/* ... */);
// 2) Derive / obtain a symmetric key for payload encryption
const key = await cryptoNT.deriveKeyFromSession(session);
// 3) Encrypt some bytes
const payload = new Uint8Array([/* ... */]);
const { ciphertext, iv, aad, tag } = await cryptoNT.encrypt(key, payload, /* optional AAD */);
// 4) Decrypt on the other side
const plaintext = await cryptoNT.decrypt(key, { ciphertext, iv, aad, tag });
// 5) Sign/verify (if using signatures in your protocol)
const signature = await cryptoNT.sign(session.identityPrivateKey, ciphertext);
const ok = await cryptoNT.verify(session.peerPublicKey, ciphertext, signature);
How it fits with the rest of NoisyTransfer
- @noisytransfer/noisyauth: gets the public key material from crypto-generated functions and authenticates them with a SAS-based approach.
- @noisytransfer/noisystream: moves your data over an ordered, encrypted channel. Uses @noisytransfer/crypto to handle message‑level signing or payload encryption/decryption if your app’s protocol requires it.
Guidance & caveats
- Prefer high‑level modules when possible. If you just need to send files/streams securely, reach for
@noisytransfer/noisystream
and the CLI; only drop down to@noisytransfer/crypto
when you’re implementing a custom protocol or storage flow. Or go even on a lower level and use hpke-js directly. It’s very well written. - Check algorithm details in the package’s own READMEs.
- Don’t roll your own protocol unless you’re very sure about the threat model and have tests. Use the established NoisyTransfer flows where feasible or check RFCs that apply to your protocol. If you can’t find a suitable RFC: Send me a message. I’m always happy to discuss protocols that are not yet covered by RFCs.
Requirements
- Node 22.
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/crypto
. It’s generated with codex, but reviewed by me.
External Cryptography Libraries
@hpke/core
– HPKE base implementation used to create sender/receiver contexts.@hpke/hybridkem-x25519-kyber768
– Hybrid KEM providing X25519 and Kyber768 key encapsulation.@noble/hashes
– Optional SHA-3 and SHAKE primitives. The package falls back to SHA-256 if it is unavailable, which is often the case. (Webcrypto does not support SHA-3 yet)
HPKE Cipher Suite
HybridkemX25519Kyber768
(KEM),HkdfSha256
(KDF), andAes256Gcm
(AEAD) are bound into a single HPKE cipher suite instance that all higher-level flows depend on.- The handshake helpers build long-lived HPKE sender and receiver contexts from this suite and serialize encryption/decryption requests to guard against concurrent misuse. The deprecated status is known and it’s currently being discussed with the repository owner inside issue #545.
mkAeadStreamFromHpke
exposes these contexts through a streaming interface that fixes the AEAD stream identifier to the base64url-encoded encapsulated key when an override is not supplied.
Digital Signatures
- RSA-PSS keys are generated at 3072-bit modulus with SHA-256 hashing, and the implementation uses WebCrypto for signing/verifying while providing a Node.js verifier helper for streaming checks.
- Streaming transcripts are hashed deterministically with SHA-256 over ordered ciphertext frames to produce a digest that is ultimately signed or verified.
Hashing, XOF, and Utility Primitives
- SHA-256 is provided through WebCrypto (with Node.js fallbacks) and is also used for constant-time equality comparisons.
- SHA3-256 and SHAKE128 are sourced from
@noble/hashes
when present; otherwise the code falls back to conservative SHA-256-based constructions.
Commitment Construction
- Commitments follow the transcript
DS || LP(label) || LP(data) || LP(nonce)
and default to SHA3-256, with SHA-256 as an optional alternative. Random nonces are 32 bytes by default and must be at least 16 bytes. - Verification recomputes the transcript hash and compares it using a constant-time byte comparison.
Short Authentication String (SAS)
- SAS derivation replays the HPKE-backed commitment/offer/reveal handshake, hashes the transcript with SHA3-256, and expands it with SHAKE128 to produce an unbiased decimal code via rejection sampling. We assume that this is sufficient heuristic for a
random oracle
.
On this page
- @noisytransfer/crypto
- Quick links
- Install
- What it’s for
- Typical usage (conceptual)
- How it fits with the rest of NoisyTransfer
- Guidance & caveats
- Requirements
- Cryptography Bill of Materials
- External Cryptography Libraries
- HPKE Cipher Suite
- Digital Signatures
- Hashing, XOF, and Utility Primitives
- Commitment Construction
- Short Authentication String (SAS)