CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-stablelib--ed25519

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

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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

docs

index.md

tile.json