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

@immahq/aegis

v0.1.3

Published

Lightweight, storage-agnostic library for client-side End-to-End (E2E) encryption

Readme

Aegis - Post-Quantum Secure E2EE Library

Codacy Badgegit workflow NPM Version

Aegis is a lightweight, storage-agnostic library for client-side End-to-End (E2E) encryption, designed for future security. It combines the NIST-standardized ML-KEM 768 algorithm for quantum-resistant key agreement with high-performance symmetric cryptography (ChaCha20-Poly1305, Blake3) to provide secure 1:1 sessions and scalable group messaging with advanced features like identity management, key rotation, and replay protection.


Core Features

  • Post-Quantum Ready: Uses ML-KEM 768 for initial key encapsulation, aligning with NIST standards.
  • Storage-Agnostic: You provide a simple key-value storage adapter (e.g., AsyncStorage, LocalStorage, SQLite, SecureStore).
  • Modern Cryptography: Symmetric ratchets for forward secrecy and Sender Keys for O(1) group encryption.
  • Enhanced Security: Implements proper group key encryption, pre-key signature verification, and secure group membership protocols.
  • Identity Management: Create identities with specific userIds for better user correlation and management.
  • Key Rotation: Supports identity rotation with option to maintain same userId or assign new ones.
  • Replay Protection: Built-in protection against message replay attacks.

Installation

Install the library using npm, yarn, or pnpm.

npm install @immahq/aegis
# or
yarn add @immahq/aegis

For React Native, you may need a polyfill for getRandomValues.


Setup

Quick start: Check examples for samples with browser, React Native, Electron, and Tauri

1. Implement a Storage Adapter

Aegis requires a minimal async storage adapter to persist keys and session state.

import { StorageAdapter, Identity, Session } from "@immahq/aegis";

const myStorage: StorageAdapter = {
  async saveIdentity(identity: Identity) {
    /* Save to secure storage (e.g., JSON.stringify(identity)) */
  },
  async getIdentity(): Promise<Identity | null> {
    /* Retrieve and parse from storage */
    return null;
  },
  async deleteIdentity() {
    /* Delete from storage */
  },
  async saveSession(sessionId: string, session: Session) {
    /* Save session state */
  },
  async getSession(sessionId: string): Promise<Session | null> {
    /* Retrieve session state */
    return null;
  },
  async deleteSession(sessionId: string) {
    /* Delete specific session */
  },
  async listSessions(): Promise<string[]> {
    /* Return list of all session IDs */
    return [];
  },
  async deleteAllSessions() {
    /* Clear all sessions */
  },
};

// Initialize the library before any other operation
import { Aegis, MemoryStorage } from "@immahq/aegis";
import type {StorageAdapter} from "@immahq/aegis";

//Plug in your preferred storage or use MemoryStorage
//const memory = new MemoryStorage();
const aegis = new Aegis(myStorage);

Security Note: The adapter will store secret key material. In production, always use platform-secured storage (e.g., iOS Keychain, Android Keystore, or a securely encrypted database).

2. Create a User Identity

A user identity consists of a post-quantum KEM key pair, a signing key pair, and pre-keys for session establishment.

// This creates and automatically saves the identity to your storage
// Optionally specify a userId for better user correlation
const { identity, publicBundle } = await aegis.createIdentity("user-123");
console.log("Your Public Bundle:", publicBundle);

3. Establish a 1:1 Encrypted Session

Initiator (Alice)

// 1. Fetch recipient's public bundle from your server
const bobBundle = await getPublicKeyBundle();

// 2. Create a session. This performs the ML-KEM key encapsulation.
const { sessionId, ciphertext, confirmationMac } = await aegis.createSession(
  bobBundle
);

// 3. Send `ciphertext` and `confirmationMac` to Bob via your server

Recipient (Bob)

// 1. Create the session as a responder using the received ciphertext
const { sessionId, confirmationMac, isValid } =
  await aegis.createResponderSession(
    aliceBundle,
    receivedCiphertext,
    receivedConfirmationMac
  );

if (isValid) {
  console.log("Session established and verified!");
}

4. Exchange Messages

Encrypt a Message

const encryptedMessage = await aegis.encryptMessage(
  sessionId,
  "Hello, Bob! This is a secret."
);

Decrypt a Message

const plaintext = await aegis.decryptMessage(sessionId, encryptedMessage);
console.log(plaintext); // "Hello, Bob! This is a secret."

5. Identity Management and Key Rotation

Aegis now supports creating identities with specific userIds and rotating identities while maintaining or changing the userId.

Rotate Identity with Same UserId

// Rotate identity but keep the same userId
const rotatedResult = await aegis.rotateIdentity("user-123");
console.log("Identity rotated with same userId:", rotatedResult.identity.userId);

Rotate Identity with New UserId

// Rotate identity and assign a new userId
const newRotatedResult = await aegis.rotateIdentity("new-user-456");
console.log("Identity rotated with new userId:", newRotatedResult.identity.userId);

6. Group Messaging with Enhanced Security

Aegis uses the Sender Key protocol for efficient group messaging, where each member encrypts a message once for the entire group. With enhanced security features, group keys are now properly encrypted with member public keys and pre-key signatures are verified.

Create a Group with Secure Key Distribution

import { Aegis, MemoryStorage } from "@immahq/aegis";

// Initialize Aegis with your storage adapter
const aegis = new Aegis(new MemoryStorage());

// Prepare member public keys
const memberKemPublicKeys = new Map<string, Uint8Array>();
memberKemPublicKeys.set(aliceUserId, aliceKem);
// ... add other members ...

const memberDsaPublicKeys = new Map<string, Uint8Array>();
memberDsaPublicKeys.set(aliceUserId, aliceDsa);
// ... add other members ...

// Alice creates a group
const group = await aegis.createGroup(
  "family_chat_2025",
  [aliceUserId, bobUserId, charlieUserId],
  memberKemPublicKeys,
  memberDsaPublicKeys
);

Broadcast and Decrypt Group Messages

// Alice encrypts a message for the entire group
const groupCiphertext = await aegis.encryptGroupMessage(
  "family_chat_2025",
  "Dinner at 8 PM!"
);

// Bob decrypts the group message
const groupPlaintext = await aegis.decryptGroupMessage(
  "family_chat_2025",
  groupCiphertext
);
console.log(new TextDecoder().decode(groupPlaintext)); // "Dinner at 8 PM!"

API Reference

Identity Management

  • aegis.createIdentity(userId?: string): Promise<{ identity, publicBundle }> - Creates a new identity with optional userId
  • aegis.getIdentity(): Promise<Identity>
  • aegis.getPublicBundle(): Promise<PublicBundle>
  • aegis.rotateIdentity(userId?: string): Promise<{ identity, publicBundle }> - Rotates identity with optional userId

1:1 Sessions

  • aegis.createSession(peerBundle): Promise<{ sessionId, ciphertext, confirmationMac }>
  • aegis.createResponderSession(peerBundle, ciphertext, initiatorMac?): Promise<{ sessionId, confirmationMac, isValid }>
  • aegis.confirmSession(sessionId, responderMac): Promise<boolean>
  • aegis.encryptMessage(sessionId, plaintext): Promise<EncryptedMessage>
  • aegis.decryptMessage(sessionId, encryptedMsg): Promise<Uint8Array>
  • aegis.triggerRatchet(sessionId): Promise<void>

Group Sessions

  • aegis.createGroup(name, members, kemKeys, dsaKeys): Promise<Group>
  • aegis.addGroupMember(groupId, userId, session, userPublicKey): Promise<void>
  • aegis.removeGroupMember(groupId, userId): Promise<void>
  • aegis.updateGroupKey(groupId): Promise<void>
  • aegis.encryptGroupMessage(groupId, message): Promise<GroupMessage>
  • aegis.decryptGroupMessage(groupId, encryptedMsg): Promise<Uint8Array>
  • aegis.getGroup(groupId): Promise<Group | null>

Testing and Examples

  • Run All Tests: npm test
  • Run peer messaging demo: npm run demo
  • Run group messaging demo: npm run demo:group

Security Model & Best Practices

Cryptographic Foundation

Aegis is built on a hybrid model:

  1. Key Agreement: ML-KEM 768 provides quantum-resistant key encapsulation. This algorithm is now a finalized NIST standard (FIPS 203).
  2. Data Encryption: ChaCha20-Poly1305 is used for fast, authenticated encryption of message contents.
  3. Key Derivation & Hashing: Blake3 is used for key derivation and hashing, providing high speed and security.

Critical Implementation Notes

⚠️ These points are essential for production security:

  • Signed Pre-Key Signatures: The library verifies pre-key signatures during session initialization. This provides protection against active man-in-the-middle attacks during session establishment.
  • One-Time Pre-Keys (OTPKs): The getPublicBundle() function returns a pre-key. Your server should track used keys and ensure they are rotated.
  • Group Key Encryption: Group shared keys are properly encrypted using ML-KEM with each member's public key, ensuring that only authorized group members can access the group key.
  • Storage Security: The storage adapter you provide holds all secret keys. You are responsible for its security. Use platform-backed secure storage.
  • Identity Management: When creating identities with specific userIds, ensure proper validation and correlation with your application's user system.

License

MIT