eciesjs: Elliptic Curve Integrated Encryption Scheme

repository·master·Indexed 41 days ago

https://github.com/ecies/js

A TypeScript/JavaScript implementation of the Elliptic Curve Integrated Encryption Scheme (ECIES) supporting secp256k1 and curve25519 (x25519/ed25519). Version 0.5.1 provides tools for encrypting and decrypting data using public and private keys, featuring support for AES-256-GCM and XChaCha20 symmetric algorithms. It is compatible with Node.js, Bun, Deno, and browser environments.

Tokens
4.6K
Snippets
21
Records
26
Agent score
51%

What's inside eciesjs

  1. Multi-platform support for eciesjs

    master

    The library is designed to work across various environments:

    • Node, Bun, Browser, React Native: Fully supported.
    • Deno: Supported, but may require running with --conditions deno (>=2.4.0) or --unstable-node-conditions deno (>=2.3.6, <2.4.0).

    Platform-specific notes:

    • Browser: Works directly in modern browsers. For WASM-based execution, consider ecies-wasm.
    • Bun: Uses a pure JS implementation of chacha20-poly1305 because node:crypto lacks it in Bun.
    • Ciphers: Uses @ecies/ciphers to leverage node:crypto native implementations of AES-256-GCM and XChaCha20-Poly1305 when available.
  2. Secp256k1 Public Key Formats

    master

    The library supports both compressed and uncompressed secp256k1 public key formats:

    • Uncompressed format (65 bytes): 04 || x || y
    • Compressed format (33 bytes): 02/03 || x (where 02 is used if y is even, and 03 if y is odd).

    The library handles both formats seamlessly during encryption and decryption.

  3. How ECIES encryption works in eciesjs

    master

    The eciesjs library provides an API for encrypting data using a secp256k1 public key and decrypting it with the corresponding private key. It combines Elliptic-curve Diffie–Hellman (ECDH) with AES-256-GCM.

    The Process

    1. Key Exchange: The library uses ECDH to exchange an AES session key. Note that a new ephemeral sender public key is generated every time encrypt is called, meaning the AES session key varies per encryption.
    2. Key Derivation: Instead of plain SHA256, the library uses HKDF-SHA256 to derive the AES keys from the shared secret for enhanced security.
    3. Encryption: The derived AES session key is used to encrypt the data using AES-256-GCM.

    Encrypted Data Structure

    The resulting encrypted payload is a single Uint8Array structured as follows:

    SegmentSizeDescription
    Sender Public Key65 BytesThe ephemeral Secp256k1 public key used for the exchange
    Nonce/IV16 BytesThe AES-GCM nonce
    Tag/MAC16 BytesThe AES-GCM authentication tag
    Encrypted DataVariableThe actual ciphertext

    Format Summary: sender_pk (65) || nonce (16) || tag (16) || encrypted_data

  4. Execute Basic usage and Import checks in the Runtime example

    master

    Once dependencies are installed in the runtime directory, you can execute the provided scripts using your preferred runtime.

    Basic usage:

    • Node: node main.js
    • Bun: bun run main.js
    • Deno: deno run --allow-read main.js

    Check import:

    • Node: node import.js
    • Bun: bun run import.js
    • Deno: deno run --allow-read import.js
    # Basic usage example with Node
    node main.js
    
    # Check import example with Deno
    deno run --allow-read import.js
  5. Quick Start with eciesjs

    master

    This example demonstrates how to generate a PrivateKey, encrypt a string using the corresponding PublicKey, and then decrypt the resulting ciphertext back to the original string.

    import { PrivateKey, decrypt, encrypt } from "eciesjs";
    
    const encoder = new TextEncoder();
    const decoder = new TextDecoder();
    
    const sk = new PrivateKey();
    const data = encoder.encode("hello world🌍");
    const decrypted = decrypt(sk.secret, encrypt(sk.publicKey.toBytes(), data));
    console.log(decoder.decode(decrypted));
  6. Run the Browser example

    master

    To run the browser-based demonstration, navigate to the browser directory, install dependencies, and start the development server.

    Note for Windows users: You must copy .npmrc.windows to example/browser/.npmrc before running the installation commands.

    Development:

    cd browser && pnpm install && pnpm dev

    Production:

    cd browser && pnpm install && pnpm build && pnpm preview
  7. Configure eciesjs encryption settings

    master

    You can customize the encryption behavior using the Config class. For compatibility between different applications, ensure they share the same configuration.

    Available Configuration Options:

    • ellipticCurve: The curve to use. Options: "secp256k1" (default), "x25519", or "ed25519".
    • isEphemeralKeyCompressed: (secp256k1 only) If true, the payload uses a 33-byte compressed ephemeral key instead of 65 bytes.
    • isHkdfKeyCompressed: (secp256k1 only) If true, the HKDF key is derived from compressed ephemeral and shared public keys.
    • symmetricAlgorithm: The symmetric cipher. Options: "aes-256-gcm" (default) or "xchacha20".
    • symmetricNonceLength: (AES-256-GCM only) The nonce length in bytes. Options: 12 or 16.

    Recommendations:

    • For compatibility: Use the defaults (secp256k1 with aes-256-gcm).
    • For speed and security: Use x25519 with xchacha20.
    export type EllipticCurve = "secp256k1" | "x25519" | "ed25519";
    export type SymmetricAlgorithm = "aes-256-gcm" | "xchacha20";
    export type NonceLength = 12 | 16;
    
    export class Config {
      ellipticCurve: EllipticCurve = "secp256k1";
      isEphemeralKeyCompressed: boolean = false;
      isHkdfKeyCompressed: boolean = false;
      symmetricAlgorithm: SymmetricAlgorithm = "aes-256-gcm";
      symmetricNonceLength: NonceLength = 16;
    }
    
    export const ECIES_CONFIG = new Config();
  8. Decrypt data with decrypt()

    master

    Decrypts data using the receiver's private key.

    Parameters:

    • receiverRawSK: Receiver's private key, provided as a hex string or Uint8Array.
    • data: The Uint8Array ciphertext to decrypt.
    • config: (Optional) An instance of Config to control decryption parameters. Defaults to ECIES_CONFIG.

    Returns: Uint8Array containing the decrypted plaintext.

    decrypt(receiverRawSK: string | Uint8Array, data: Uint8Array, config?: Config): Uint8Array
  9. Encrypt data with encrypt()

    master

    Encrypts data using the receiver's public key.

    Parameters:

    • receiverRawPK: Receiver's public key, provided as a hex string or Uint8Array.
    • data: The Uint8Array data to encrypt.
    • config: (Optional) An instance of Config to control encryption parameters. Defaults to ECIES_CONFIG.

    Returns: Uint8Array containing the ciphertext.

    encrypt(receiverRawPK: string | Uint8Array, data: Uint8Array, config?: Config): Uint8Array
  10. Configure ECIES encryption settings

    master

    The Config class allows you to customize the elliptic curve, symmetric encryption algorithm, and key compression settings used during ECIES operations. You can either use the default exported ECIES_CONFIG instance or instantiate a new Config object for custom requirements.

    Supported Elliptic Curves

    • secp256k1 (Default)
    • x25519
    • ed25519

    Supported Symmetric Algorithms

    • aes-256-gcm (Default)
    • xchacha20

    Configuration Options

    OptionTypeDefaultNotes
    ellipticCurveEllipticCurve"secp256k1"Selects the curve for key exchange.
    isEphemeralKeyCompressedbooleanfalseOnly applicable to secp256k1.
    isHkdfKeyCompressedbooleanfalseOnly applicable to secp256k1.
    symmetricAlgorithmSymmetricAlgorithm"aes-256-gcm"Selects the symmetric cipher.
    symmetricNonceLengthNonceLength16Only applicable to aes-256-gcm. Supports 12 or 16.

    Ephemeral Key Size

    The ephemeralKeySize getter returns the expected byte size of the ephemeral public key based on the selected ellipticCurve and compression settings.

    import { Config, ECIES_CONFIG } from 'eciesjs';
    
    // Use default settings
    const defaultConfig = ECIES_CONFIG;
    
    // Create custom settings
    const customConfig = new Config();
    customConfig.ellipticCurve = 'x25519';
    customConfig.symmetricAlgorithm = 'xchacha20';
    
    console.log(customConfig.ephemeralKeySize);