> ## Documentation Index
> Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Ed25519

> Edwards-curve Digital Signature Algorithm using Curve25519 - fast, deterministic signatures

<Info>
  Source: [ed25519.zig](https://github.com/evmts/voltaire/blob/main/src/crypto/ed25519.zig) • [ed25519.wasm.ts](https://github.com/evmts/voltaire/blob/main/src/crypto/ed25519.wasm.ts)

  Tests: [ed25519.test.ts](https://github.com/evmts/voltaire/blob/main/src/crypto/ed25519.test.ts) • [ed25519.wasm.test.ts](https://github.com/evmts/voltaire/blob/main/src/crypto/ed25519.wasm.test.ts)
</Info>

<Card title="Try it Live" icon="play" href="https://playground.tevm.sh?example=crypto/ed25519.ts">
  Run Ed25519 examples in the interactive playground
</Card>

<Warning>
  **This page is a placeholder.** All examples on this page are currently AI-generated and are not correct. This documentation will be completed in the future with accurate, tested examples.
</Warning>

## Overview

Ed25519 is a modern elliptic curve signature scheme using the Edwards curve form of Curve25519. It provides high security (128-bit security level) with excellent performance and simple implementation.

**Curve**: Edwards curve y² + x² = 1 + dx²y² over prime field 2²⁵⁵ - 19

**Key features**:

* **Deterministic**: No random nonce needed (unlike ECDSA)
* **Fast**: Faster than secp256k1 for both signing and verification
* **Simple**: No malleability, no special cases, straightforward implementation
* **Secure**: Designed to resist timing attacks and side-channel analysis

**Modern usage**: SSH (RFC 8709), TLS 1.3, Signal Protocol, WireGuard, Tor, Zcash, Monero, Stellar, and many cryptocurrency wallets.

## Quick Start

```typescript theme={null}
import * as Ed25519 from '@tevm/voltaire/Ed25519';
import * as Hex from '@tevm/voltaire/Hex';

// Generate keypair from seed
const seed = Hex('0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60');
const keypair = Ed25519.keypairFromSeed(seed);

// Sign a message (any length)
const message = new TextEncoder().encode('Hello, Ed25519!');
const signature = Ed25519.sign(message, keypair.secretKey);

// Verify signature
const isValid = Ed25519.verify(signature, message, keypair.publicKey);
```

## API Reference

### Key Generation

#### `keypairFromSeed(seed)`

Generate deterministic Ed25519 keypair from a 32-byte seed.

**Parameters**:

* `seed` (`Uint8Array`) - 32-byte seed for deterministic generation

**Returns**: `{ secretKey: Uint8Array, publicKey: Uint8Array }`

* `secretKey` - 32-byte secret key (same as seed in Ed25519)
* `publicKey` - 32-byte public key

**Throws**:

* `InvalidSeedError` - Seed wrong length

```typescript theme={null}
import * as Hex from '@tevm/voltaire/Hex';

const seed = Hex('0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef');
const { secretKey, publicKey } = Ed25519.keypairFromSeed(seed);
```

#### `derivePublicKey(secretKey)`

Derive public key from secret key.

**Parameters**:

* `secretKey` (`Uint8Array`) - 32-byte secret key

**Returns**: `Uint8Array` - 32-byte public key

**Throws**:

* `InvalidSecretKeyError` - Secret key wrong length

```typescript theme={null}
const publicKey = Ed25519.derivePublicKey(secretKey);
```

### Signing

#### `sign(message, secretKey)`

Sign a message with Ed25519 secret key. Message can be any length.

**Parameters**:

* `message` (`Uint8Array`) - Message to sign (any length)
* `secretKey` (`Uint8Array`) - 32-byte secret key

**Returns**: `Uint8Array` - 64-byte signature

**Throws**:

* `InvalidSecretKeyError` - Secret key invalid
* `Ed25519Error` - Signing failed

```typescript theme={null}
const message = new TextEncoder().encode('Sign this message');
const signature = Ed25519.sign(message, secretKey);
console.log(signature.length); // 64
```

### Verification

#### `verify(signature, message, publicKey)`

Verify an Ed25519 signature.

**Parameters**:

* `signature` (`Uint8Array`) - 64-byte signature to verify
* `message` (`Uint8Array`) - Original message that was signed
* `publicKey` (`Uint8Array`) - 32-byte public key

**Returns**: `boolean` - `true` if signature is valid, `false` otherwise

**Throws**:

* `InvalidPublicKeyError` - Public key format invalid
* `InvalidSignatureError` - Signature format invalid

```typescript theme={null}
const valid = Ed25519.verify(signature, message, publicKey);
if (valid) {
  console.log('Signature verified!');
}
```

### Validation

#### `validateSecretKey(secretKey)`

Check if a byte array is a valid Ed25519 secret key.

**Parameters**:

* `secretKey` (`Uint8Array`) - Candidate secret key

**Returns**: `boolean` - `true` if valid (32 bytes)

```typescript theme={null}
if (Ed25519.validateSecretKey(secretKey)) {
  // Safe to use
}
```

#### `validatePublicKey(publicKey)`

Check if a byte array is a valid Ed25519 public key.

**Parameters**:

* `publicKey` (`Uint8Array`) - Candidate public key

**Returns**: `boolean` - `true` if valid (32 bytes, point on curve)

```typescript theme={null}
if (Ed25519.validatePublicKey(publicKey)) {
  // Valid point on curve
}
```

#### `validateSeed(seed)`

Check if a byte array is a valid seed.

**Parameters**:

* `seed` (`Uint8Array`) - Candidate seed

**Returns**: `boolean` - `true` if valid (32 bytes)

```typescript theme={null}
if (Ed25519.validateSeed(seed)) {
  // Can generate keypair
}
```

### Constants

```typescript theme={null}
Ed25519.SECRET_KEY_SIZE  // 32 bytes
Ed25519.PUBLIC_KEY_SIZE  // 32 bytes
Ed25519.SIGNATURE_SIZE   // 64 bytes
Ed25519.SEED_SIZE        // 32 bytes
```

## Security Considerations

### Advantages over ECDSA (secp256k1)

✅ **No nonce generation**: Ed25519 is deterministic. The same message and key always produce the same signature, eliminating the catastrophic nonce reuse vulnerability in ECDSA.

✅ **No malleability**: Signatures cannot be modified to create alternative valid signatures (unlike ECDSA which requires low-s normalization).

✅ **Simpler implementation**: Fewer edge cases and special conditions reduce attack surface.

✅ **Better performance**: Typically 2-3x faster than secp256k1 for signing and verification.

✅ **Built-in security**: Designed from the ground up to resist timing attacks and side-channel analysis.

### Critical Warnings

⚠️ **Protect secret keys**: Ed25519 secret keys are 32-byte seeds. If compromised, all signatures can be forged.

⚠️ **Validate public keys**: Always validate public keys before use to ensure they are valid curve points.

⚠️ **Use cryptographically secure random**: Never use `Math.random()` for seed generation. Use `crypto.getRandomValues()`.

⚠️ **Message length**: Unlike ECDSA which signs 32-byte hashes, Ed25519 signs the actual message. For very large messages, consider hashing first (but this is not required).

### TypeScript Implementation

The TypeScript implementation uses **@noble/curves/ed25519** by Paul Miller:

* Constant-time operations
* Compliant with RFC 8032
* Multiple security audits
* Widely used in production (SSH, Signal, cryptocurrency)
* \~15KB minified

### Test Vectors

### RFC 8032 Test Vectors

```typescript theme={null}
// Test vector 1 from RFC 8032
const seed1 = new Uint8Array([
  0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60,
  0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4,
  0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19,
  0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60,
]);

const { secretKey, publicKey } = Ed25519.keypairFromSeed(seed1);

// Expected public key
const expectedPublicKey = new Uint8Array([
  0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7,
  0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a,
  0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25,
  0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a,
]);

assert(publicKey.every((byte, i) => byte === expectedPublicKey[i]));

// Sign empty message
const message = new Uint8Array(0);
const signature = Ed25519.sign(message, secretKey);

// Expected signature
const expectedSignature = new Uint8Array([
  0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72,
  0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a,
  0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74,
  0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49, 0x01, 0x55,
  0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac,
  0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b,
  0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24,
  0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b,
]);

assert(signature.every((byte, i) => byte === expectedSignature[i]));

// Verify signature
assert(Ed25519.verify(signature, message, publicKey));
```

### Deterministic Signatures

```typescript theme={null}
import * as Hex from '@tevm/voltaire/Hex';

// Ed25519 is deterministic - same message + key = same signature
const seed = Hex('0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890');
const { secretKey, publicKey } = Ed25519.keypairFromSeed(seed);

const message = new TextEncoder().encode('test');

const sig1 = Ed25519.sign(message, secretKey);
const sig2 = Ed25519.sign(message, secretKey);

// Identical signatures
assert(sig1.every((byte, i) => byte === sig2[i]));
```

### Message Length Flexibility

```typescript theme={null}
import * as Hex from '@tevm/voltaire/Hex';

const seed = Hex('0xfedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321');
const { secretKey, publicKey } = Ed25519.keypairFromSeed(seed);

// Empty message
const emptyMsg = Hex('0x');
const sig0 = Ed25519.sign(emptyMsg, secretKey);
assert(Ed25519.verify(sig0, emptyMsg, publicKey));

// Short message
const msg1 = new TextEncoder().encode('Hi');
const sig1 = Ed25519.sign(msg1, secretKey);
assert(Ed25519.verify(sig1, msg1, publicKey));

// Long message (1 MB) - for illustration, represented as hex
const largeData = new TextEncoder().encode('a'.repeat(1024 * 1024));
const sig2 = Ed25519.sign(largeData, secretKey);
assert(Ed25519.verify(sig2, largeData, publicKey));
```

## Implementation Details

### TypeScript

**Library**: `@noble/curves/ed25519` by Paul Miller

* **Audit status**: Security audited, production-ready
* **Standard**: RFC 8032 compliant
* **Features**: Constant-time, batch verification, cofactor handling
* **Size**: \~15KB minified (tree-shakeable)
* **Performance**: 2-3x faster than secp256k1

Key design choices:

* Uses twisted Edwards curve internally
* Point compression for compact public keys (32 bytes)
* Deterministic signature generation (no randomness needed)
* Built-in validation and security checks

### Zig

**Implementation**: Will use `std.crypto.sign.Ed25519` from Zig standard library

* **Status**: Future FFI support planned
* **Features**: Constant-time, RFC 8032 compliant
* **Audit**: Part of Zig standard library

Currently only available through TypeScript/WASM interface.

### WASM

Ed25519 operations available in WASM builds:

* **ReleaseSmall**: Size-optimized (\~15KB)
* **ReleaseFast**: Performance-optimized

```typescript theme={null}
import { Ed25519 } from '@tevm/voltaire/Ed25519';
// Automatically uses WASM in supported environments
```

## Ethereum Context

Ed25519 is **not used in Ethereum's core protocol** (which uses secp256k1), but it appears in:

### Layer 2 and Rollups

* **StarkNet**: Uses Ed25519 for account signatures
* **zkSync**: Optional Ed25519 support for certain operations
* **Optimistic Rollups**: Some use Ed25519 for off-chain aggregation

### Modern Web3 Applications

* **Solana integration**: Solana uses Ed25519, so cross-chain apps benefit
* **Decentralized identity**: DIDs often use Ed25519 for key management
* **Encrypted communication**: Signal Protocol with Ethereum accounts

### Future EVM Integration

* **EIP-665**: Proposed Ed25519 signature verification precompile (draft)
* **Account abstraction**: ED25519 keys for smart contract wallets
* **Hardware wallets**: Secure Enclave and TEE support

## Ed25519 vs Secp256k1

| Feature              | Ed25519               | Secp256k1                   |
| -------------------- | --------------------- | --------------------------- |
| **Security Level**   | 128-bit               | 128-bit                     |
| **Key Size**         | 32 bytes              | 32 bytes (private)          |
| **Public Key**       | 32 bytes (compressed) | 64 bytes (uncompressed)     |
| **Signature Size**   | 64 bytes              | 64 bytes (r,s) + 1 byte (v) |
| **Deterministic**    | Yes (built-in)        | Yes (RFC 6979)              |
| **Malleability**     | No                    | Yes (requires low-s)        |
| **Performance**      | Faster (2-3x)         | Slower                      |
| **Nonce Issues**     | None                  | Critical (ECDSA)            |
| **Ethereum Support** | No (L2 only)          | Yes (core)                  |
| **Modern Adoption**  | High                  | Medium                      |

**When to use Ed25519**:

* New protocols and applications
* High-performance requirements
* Simplified security model
* Cross-chain with Solana, Stellar, etc.
* SSH, TLS, or other modern protocols

**When to use Secp256k1**:

* Ethereum transaction signing (required)
* Bitcoin compatibility
* EVM precompile support (`ecRecover`)
* Address derivation from signatures

## Related

* [Crypto: Secp256k1](/crypto/secp256k1) - Ethereum's ECDSA curve
* [Crypto: X25519](/crypto/x25519) - Curve25519 key exchange (ECDH)
* [Crypto: P256](/crypto/p256) - NIST P-256 curve (WebAuthn)
* [Primitives: Signature](/primitives/signature) - Generic signature type
* [Keccak256](/crypto/keccak256) - Message hashing
* [Ed25519 (Effect)](https://voltaire-effect.tevm.sh/crypto/ed25519) - Effect.ts integration with Schema validation
