or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-stablelib--ed25519

Ed25519 public-key signature algorithm implementation with key generation, signing, verification, and X25519 conversion

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@stablelib/ed25519@2.0.x

To install, run

npx @tessl/cli install tessl/npm-stablelib--ed25519@2.0.0

index.mddocs/

Ed25519 Public-Key Signature

Ed25519 is a TypeScript implementation of the Ed25519 public-key signature algorithm (EdDSA with Curve25519). It provides secure key generation, message signing, signature verification, and conversion to X25519 keys. The implementation uses constant-time operations to prevent timing attacks and is compatible with standard Ed25519 implementations.

Package Information

  • Package Name: @stablelib/ed25519
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @stablelib/ed25519

Core Imports

import { 
  generateKeyPair, 
  generateKeyPairFromSeed,
  extractPublicKeyFromSecretKey,
  sign, 
  verify,
  convertPublicKeyToX25519,
  convertSecretKeyToX25519,
  SIGNATURE_LENGTH,
  PUBLIC_KEY_LENGTH,
  SECRET_KEY_LENGTH,
  SEED_LENGTH,
  type KeyPair
} from "@stablelib/ed25519";
import type { RandomSource } from "@stablelib/random";

For CommonJS:

const { 
  generateKeyPair, 
  sign, 
  verify 
} = require("@stablelib/ed25519");

Basic Usage

import { generateKeyPair, sign, verify } from "@stablelib/ed25519";

// Generate a key pair
const keyPair = generateKeyPair();
const { publicKey, secretKey } = keyPair;

// Sign a message
const message = new TextEncoder().encode("Hello, world!");
const signature = sign(secretKey, message);

// Verify the signature
const isValid = verify(publicKey, message, signature);
console.log(isValid); // true

// Sign with a different secret key
const anotherKeyPair = generateKeyPair();
const invalidSignature = sign(anotherKeyPair.secretKey, message);
const isInvalid = verify(publicKey, message, invalidSignature);
console.log(isInvalid); // false

Architecture

Ed25519 is built around the elliptic curve cryptography principles:

  • Key Generation: Creates cryptographically secure public/private key pairs from random seeds
  • Digital Signatures: Produces unforgeable signatures using private keys that can be verified with public keys
  • Constant-Time Operations: All operations use constant-time algorithms to prevent timing attacks
  • X25519 Compatibility: Supports conversion between Ed25519 and X25519 key formats for key exchange
  • Pure TypeScript: No native dependencies, works in both Node.js and browser environments

Capabilities

Key Generation

Generate Ed25519 key pairs for digital signatures.

/**
 * Generate a key pair from a 32-byte seed
 * @param seed - 32-byte Uint8Array seed for deterministic key generation
 * @returns KeyPair containing 32-byte public key and 64-byte secret key
 * @throws Error if seed is not exactly 32 bytes
 */
function generateKeyPairFromSeed(seed: Uint8Array): KeyPair;

/**
 * Generate a random key pair using secure random number generation
 * @param prng - Optional random source, uses system random if not provided
 * @returns KeyPair containing 32-byte public key and 64-byte secret key
 */
function generateKeyPair(prng?: RandomSource): KeyPair;

/**
 * Extract the public key from a secret key
 * @param secretKey - 64-byte secret key
 * @returns 32-byte public key
 * @throws Error if secret key is not exactly 64 bytes
 */
function extractPublicKeyFromSecretKey(secretKey: Uint8Array): Uint8Array;

Digital Signatures

Sign messages and verify signatures using Ed25519 algorithm.

/**
 * Sign a message with a secret key
 * @param secretKey - 64-byte secret key for signing
 * @param message - Message to sign (any length)
 * @returns 64-byte signature
 * @throws Error if secret key is not exactly 64 bytes
 */
function sign(secretKey: Uint8Array, message: Uint8Array): Uint8Array;

/**
 * Verify a signature against a message and public key
 * @param publicKey - 32-byte public key for verification
 * @param message - Original message that was signed
 * @param signature - 64-byte signature to verify
 * @returns true if signature is valid, false otherwise
 * @throws Error if signature is not exactly 64 bytes
 */
function verify(
  publicKey: Uint8Array, 
  message: Uint8Array, 
  signature: Uint8Array
): boolean;

Key Conversion

Convert Ed25519 keys to X25519 format for key exchange protocols.

/**
 * Convert Ed25519 public key to X25519 public key
 * @param publicKey - 32-byte Ed25519 public key
 * @returns 32-byte X25519 public key
 * @throws Error if public key is invalid
 */
function convertPublicKeyToX25519(publicKey: Uint8Array): Uint8Array;

/**
 * Convert Ed25519 secret key to X25519 secret key
 * @param secretKey - 64-byte Ed25519 secret key (or 32-byte seed portion)
 * @returns 32-byte X25519 secret key
 */
function convertSecretKeyToX25519(secretKey: Uint8Array): Uint8Array;

Types

/**
 * Key pair containing both public and secret keys
 */
interface KeyPair {
  /** 32-byte public key for verification and sharing */
  publicKey: Uint8Array;
  /** 64-byte secret key for signing (contains seed + public key) */
  secretKey: Uint8Array;
}

/**
 * Random source interface for custom randomness
 */
interface RandomSource {
  (length: number): Uint8Array;
}

Constants

/** Length of Ed25519 signatures in bytes */
const SIGNATURE_LENGTH: 64;

/** Length of Ed25519 public keys in bytes */
const PUBLIC_KEY_LENGTH: 32;

/** Length of Ed25519 secret keys in bytes */
const SECRET_KEY_LENGTH: 64;

/** Length of key generation seeds in bytes */
const SEED_LENGTH: 32;

Usage Examples

Deterministic Key Generation

import { generateKeyPairFromSeed } from "@stablelib/ed25519";

// Generate keys from a known seed (for testing or deterministic purposes)
const seed = new Uint8Array(32);
seed.fill(1); // Don't use predictable seeds in production!

const keyPair = generateKeyPairFromSeed(seed);
// This will always produce the same key pair for the same seed

Message Signing with Error Handling

import { 
  generateKeyPair, 
  sign, 
  verify, 
  SIGNATURE_LENGTH 
} from "@stablelib/ed25519";

try {
  const keyPair = generateKeyPair();
  const message = new TextEncoder().encode("Important message");
  
  const signature = sign(keyPair.secretKey, message);
  console.log(`Signature length: ${signature.length} bytes`); // 64 bytes
  
  if (signature.length !== SIGNATURE_LENGTH) {
    throw new Error("Invalid signature length");
  }
  
  const isValid = verify(keyPair.publicKey, message, signature);
  console.log(`Signature valid: ${isValid}`);
} catch (error) {
  console.error("Signing failed:", error.message);
}

Key Conversion for X25519

import { 
  generateKeyPair, 
  convertPublicKeyToX25519, 
  convertSecretKeyToX25519 
} from "@stablelib/ed25519";

// Generate Ed25519 keys
const ed25519Keys = generateKeyPair();

// Convert to X25519 for key exchange
const x25519PublicKey = convertPublicKeyToX25519(ed25519Keys.publicKey);
const x25519SecretKey = convertSecretKeyToX25519(ed25519Keys.secretKey);

console.log(`X25519 public key length: ${x25519PublicKey.length} bytes`); // 32 bytes
console.log(`X25519 secret key length: ${x25519SecretKey.length} bytes`); // 32 bytes

Extracting Public Key

import { 
  generateKeyPair, 
  extractPublicKeyFromSecretKey 
} from "@stablelib/ed25519";

const keyPair = generateKeyPair();

// Extract public key from secret key (useful when you only store secret key)
const extractedPublicKey = extractPublicKeyFromSecretKey(keyPair.secretKey);

// Verify they match
const keysMatch = keyPair.publicKey.every(
  (byte, index) => byte === extractedPublicKey[index]
);
console.log(`Keys match: ${keysMatch}`); // true