npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@oxpulse/crypto-primitives

v0.5.1

Published

Pairwise X25519+HKDF+AEAD primitives, XChaCha20-Poly1305, PQXDH hybrid KEM, MessageEnvelope v2 codec (authenticated binding transcript), and timing-safe comparison helpers for oxpulse-chat.

Readme

@oxpulse/crypto-primitives

X25519 + HKDF-SHA256 + AES-256-GCM primitives, the MessageEnvelope v2 wire codec (authenticated binding transcript), and timing-safe comparison helpers used by SDK + mesh transports to carry pairwise-sealed messages opaquely.

Public surface (flat exports — ADR-003)

All exports are flat from the package root (@oxpulse/crypto-primitives); there are no sub-path exports.

  • X25519generateEphemeralKeypair, deriveSharedSecret
  • HKDF-SHA256deriveKey
  • AEAD (AES-256-GCM)aesGcmSeal, aesGcmOpen
  • AddressingderivePeerIdTarget
  • Envelope codecencodeMessageEnvelope, decodeMessageEnvelope, MESSAGE_ENVELOPE_MAGIC, MESSAGE_ENVELOPE_VERSION, HEADER_BYTES, MessageEnvelopeV2
  • Pairwise sealsealMessage, openMessage, SealMessageArgs, OpenMessageArgs, OpenMessageResult, ReplayWindow
  • Timing-safe comparison (ADR-008)timingSafeEqual, timingSafePubkeyEqualB64u

Timing-safe comparison (CWE-208 invariant)

timingSafeEqual(a, b) performs an XOR-reduce over Uint8Array and returns false on length mismatch (length is non-secret). No short-circuit path based on byte content.

timingSafePubkeyEqualB64u(a, b) decodes both base64url strings to bytes and delegates to timingSafeEqual.

INVARIANT: NEVER use === on crypto-derived b64u strings (pubkeys, MAC tags, signatures, sessionIds). === leaks the first-mismatch byte position via timing (OWASP ASVS V11.3.1, CWE-208). Use timingSafePubkeyEqualB64u for any comparison that influences a security decision.

import { timingSafeEqual, timingSafePubkeyEqualB64u } from '@oxpulse/crypto-primitives';

timingSafeEqual(macA, macB);                 // Uint8Array vs Uint8Array
timingSafePubkeyEqualB64u(pubA_b64u, pubB_b64u); // base64url strings

Replay protection (caller's responsibility)

crypto-primitives is a stateless library — it does NOT track seen msgIds and cannot reject replayed envelopes by itself. The crypto layer authenticates msgId (bound into the binding transcript digest in v2), which enables caller-side replay detection, but does not perform it.

An attacker (the relay/server in the E2EE threat model) can replay a previously captured envelope to the recipient — signature verifies, AEAD decrypts, message returned. The caller MUST track seen msgIds per sender and reject duplicates.

openMessage accepts an optional replayWindow: ReplayWindow parameter. When provided, openMessage rejects replayed msgIds after signature verification but before AEAD decryption. The caller provides the storage backing (in-memory Set for tests, IndexedDB for production). See the ReplayWindow interface JSDoc for the timing and poisoning invariants.

Without replayWindow, the same envelope opens twice — this is by design (stateless library, backward compat, test convenience). Production callers MUST pass a replayWindow.

Dep arrow

@oxpulse/identity → @oxpulse/crypto-primitives → { @oxpulse/mesh-core, web, @oxpulse/chat-sdk }

This package MUST NOT import from @oxpulse/identity. Shared helpers (e.g. toArrayBuffer) are deliberately copy-pasted into src/_internal.ts per operator decision #7 of the Phase 1 plan (identity-extraction-adr §2.2 sole-consumer audit pattern).

Non-goals

  • No IndexedDB.
  • No UI components.
  • No transport logic (routing, WebSocket, BLE).
  • No group ratchet. See web/src/lib/chat-cryptor.ts::sealGroupFrame (renamed in Phase 2) for group AEAD.

License

AGPL-3.0-or-later. See LICENSE.

Usage (sender)

import { sealMessage } from '@oxpulse/crypto-primitives';
const envelopeBytes = await sealMessage({
  plaintext,
  recipientX25519Pub,
  senderEd25519PrivKey,
  senderEd25519PubKey,
  msgId,
});
// Transport (SDK or mesh) carries envelopeBytes opaquely by recipientAddr.

Usage (recipient)

import { openMessage, decodeMessageEnvelope } from '@oxpulse/crypto-primitives';
// Peek recipientAddr to route to local user; lookup expected sender pubkey by sig-cache:
const env = decodeMessageEnvelope(envelopeBytes);
const { plaintext, msgId, flags } = await openMessage({
  envelopeBytes,
  recipientX25519Priv,
  recipientX25519Pub,
  expectedSenderEd25519Pub,
  replayWindow, // REQUIRED in production — caller-provided ReplayWindow
});