This guide provides essential information for agents working with the libomemo.js codebase, a JavaScript implementation of the Signal Protocol for OMEMO encryption in XMPP.
This is a fork of libsignal-protocol-javascript modified to conform to the XMPP OMEMO specification.
/dist # Distributables
/build # Intermediate build files
/src # JS source files
/native # C source files for curve25519
/protos # Protobuf definitions
/test # Tests
- Curve.js: Wrapper for Curve25519 cryptographic operations
- KeyHelper.js: Functions for generating keys and registration IDs
- SessionBuilder.js: Establishes sessions using PreKey bundles
- SessionCipher.js: Encrypts/decrypts messages for established sessions
- SessionRecord.js: Manages session state persistence
- SignalProtocolAddress.js: Represents addressing for Signal Protocol
- crypto.js: Cryptographic utilities
- helpers.js: General helper functions
- protobufs.js: Protobuf serialization/deserialization
- NumericFingerprint.js: Device fingerprinting functionality
# Install dependencies
npm install# Compile native C code (requires Emscripten)
npm run compile
# Build JavaScript distribution
npm run dist
# Full build (compile + dist)
npm run build
# Watch mode for development
npm run dev# Run tests with Karma
npm test
# Lint source files
npm run lint# Run ESLint on source and test files
npm run lint- Most cryptographic operations return Promises
- Uses native Promise syntax (no polyfills needed)
- Async/await is supported but not heavily used
- Throwing Errors for invalid inputs/validation failures
- Promise rejection for cryptographic operation failures
- Console warnings for non-fatal issues
- Primary use of ArrayBuffer for binary data
- Uint8Array for byte manipulation
- Promises for asynchronous operations
- Uses IIFE (Immediately Invoked Function Expression) pattern
- Internal functions in
Internalnamespace - Public API exposed through
libsignalglobal object
- CamelCase for functions and variables
- PascalCase for constructor functions/classes
- Constants in UPPER_CASE
- Descriptive function names that indicate purpose
- Uses Mocha test framework
- Chai assertion library
- Karma test runner for browser testing
- Test files located in
/testdirectory - Each component typically has a corresponding test file
- Uses in-memory store implementation for testing (
InMemorySignalProtocolStore.js)
Tests are run in Chrome browser by default and cover:
- Key generation and management
- Session establishment
- Message encryption/decryption
- Protocol compliance
- Native Dependencies: Curve25519 operations depend on compiled C code via Emscripten. Must run
make compilebefore building. - Browser Environment: Requires modern browser features (ArrayBuffer, TypedArray, Promise, WebCrypto).
- Asynchronous Nature: Many operations return promises. Ensure proper handling of async flows.
- Identity Management: Identity key conflicts must be handled explicitly during session building.
- Session State: Session state must be persisted properly between uses. Implementation is left to the developer (see
SignalProtocolStore). - PreKey Management: Proper PreKey handling is critical for secure communication setup.
- Uses ProtoBuf.js for serialization
- Definitions in
/protosdirectory - Compiled versions used in build process
- Native C code compilation using Emscripten
- Concatenation of JavaScript files in specific order
- Wrapping with IIFE for proper scoping
- Generation of distributable file in
/dist
- package.json: Project dependencies and metadata
- Gruntfile.js: Build configuration and tasks
- karma.conf.js: Test runner configuration
- .eslintrc.js: ESLint configuration
- Makefile: High-level build and test commands
- Changes should maintain backward compatibility when possible
- All new functionality should include tests
- Follow existing code style and patterns
- Ensure builds pass all tests before submitting changes