Ed25519 public-key signature algorithm implementation with key generation, signing, verification, and X25519 conversion
npx @tessl/cli install tessl/npm-stablelib--ed25519@2.0.00
# Ed25519 Public-Key Signature
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: @stablelib/ed25519
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @stablelib/ed25519`
10
11
## Core Imports
12
13
```typescript
14
import {
15
generateKeyPair,
16
generateKeyPairFromSeed,
17
extractPublicKeyFromSecretKey,
18
sign,
19
verify,
20
convertPublicKeyToX25519,
21
convertSecretKeyToX25519,
22
SIGNATURE_LENGTH,
23
PUBLIC_KEY_LENGTH,
24
SECRET_KEY_LENGTH,
25
SEED_LENGTH,
26
type KeyPair
27
} from "@stablelib/ed25519";
28
import type { RandomSource } from "@stablelib/random";
29
```
30
31
For CommonJS:
32
33
```javascript
34
const {
35
generateKeyPair,
36
sign,
37
verify
38
} = require("@stablelib/ed25519");
39
```
40
41
## Basic Usage
42
43
```typescript
44
import { generateKeyPair, sign, verify } from "@stablelib/ed25519";
45
46
// Generate a key pair
47
const keyPair = generateKeyPair();
48
const { publicKey, secretKey } = keyPair;
49
50
// Sign a message
51
const message = new TextEncoder().encode("Hello, world!");
52
const signature = sign(secretKey, message);
53
54
// Verify the signature
55
const isValid = verify(publicKey, message, signature);
56
console.log(isValid); // true
57
58
// Sign with a different secret key
59
const anotherKeyPair = generateKeyPair();
60
const invalidSignature = sign(anotherKeyPair.secretKey, message);
61
const isInvalid = verify(publicKey, message, invalidSignature);
62
console.log(isInvalid); // false
63
```
64
65
## Architecture
66
67
Ed25519 is built around the elliptic curve cryptography principles:
68
69
- **Key Generation**: Creates cryptographically secure public/private key pairs from random seeds
70
- **Digital Signatures**: Produces unforgeable signatures using private keys that can be verified with public keys
71
- **Constant-Time Operations**: All operations use constant-time algorithms to prevent timing attacks
72
- **X25519 Compatibility**: Supports conversion between Ed25519 and X25519 key formats for key exchange
73
- **Pure TypeScript**: No native dependencies, works in both Node.js and browser environments
74
75
## Capabilities
76
77
### Key Generation
78
79
Generate Ed25519 key pairs for digital signatures.
80
81
```typescript { .api }
82
/**
83
* Generate a key pair from a 32-byte seed
84
* @param seed - 32-byte Uint8Array seed for deterministic key generation
85
* @returns KeyPair containing 32-byte public key and 64-byte secret key
86
* @throws Error if seed is not exactly 32 bytes
87
*/
88
function generateKeyPairFromSeed(seed: Uint8Array): KeyPair;
89
90
/**
91
* Generate a random key pair using secure random number generation
92
* @param prng - Optional random source, uses system random if not provided
93
* @returns KeyPair containing 32-byte public key and 64-byte secret key
94
*/
95
function generateKeyPair(prng?: RandomSource): KeyPair;
96
97
/**
98
* Extract the public key from a secret key
99
* @param secretKey - 64-byte secret key
100
* @returns 32-byte public key
101
* @throws Error if secret key is not exactly 64 bytes
102
*/
103
function extractPublicKeyFromSecretKey(secretKey: Uint8Array): Uint8Array;
104
```
105
106
### Digital Signatures
107
108
Sign messages and verify signatures using Ed25519 algorithm.
109
110
```typescript { .api }
111
/**
112
* Sign a message with a secret key
113
* @param secretKey - 64-byte secret key for signing
114
* @param message - Message to sign (any length)
115
* @returns 64-byte signature
116
* @throws Error if secret key is not exactly 64 bytes
117
*/
118
function sign(secretKey: Uint8Array, message: Uint8Array): Uint8Array;
119
120
/**
121
* Verify a signature against a message and public key
122
* @param publicKey - 32-byte public key for verification
123
* @param message - Original message that was signed
124
* @param signature - 64-byte signature to verify
125
* @returns true if signature is valid, false otherwise
126
* @throws Error if signature is not exactly 64 bytes
127
*/
128
function verify(
129
publicKey: Uint8Array,
130
message: Uint8Array,
131
signature: Uint8Array
132
): boolean;
133
```
134
135
### Key Conversion
136
137
Convert Ed25519 keys to X25519 format for key exchange protocols.
138
139
```typescript { .api }
140
/**
141
* Convert Ed25519 public key to X25519 public key
142
* @param publicKey - 32-byte Ed25519 public key
143
* @returns 32-byte X25519 public key
144
* @throws Error if public key is invalid
145
*/
146
function convertPublicKeyToX25519(publicKey: Uint8Array): Uint8Array;
147
148
/**
149
* Convert Ed25519 secret key to X25519 secret key
150
* @param secretKey - 64-byte Ed25519 secret key (or 32-byte seed portion)
151
* @returns 32-byte X25519 secret key
152
*/
153
function convertSecretKeyToX25519(secretKey: Uint8Array): Uint8Array;
154
```
155
156
## Types
157
158
```typescript { .api }
159
/**
160
* Key pair containing both public and secret keys
161
*/
162
interface KeyPair {
163
/** 32-byte public key for verification and sharing */
164
publicKey: Uint8Array;
165
/** 64-byte secret key for signing (contains seed + public key) */
166
secretKey: Uint8Array;
167
}
168
169
/**
170
* Random source interface for custom randomness
171
*/
172
interface RandomSource {
173
(length: number): Uint8Array;
174
}
175
```
176
177
## Constants
178
179
```typescript { .api }
180
/** Length of Ed25519 signatures in bytes */
181
const SIGNATURE_LENGTH: 64;
182
183
/** Length of Ed25519 public keys in bytes */
184
const PUBLIC_KEY_LENGTH: 32;
185
186
/** Length of Ed25519 secret keys in bytes */
187
const SECRET_KEY_LENGTH: 64;
188
189
/** Length of key generation seeds in bytes */
190
const SEED_LENGTH: 32;
191
```
192
193
## Usage Examples
194
195
### Deterministic Key Generation
196
197
```typescript
198
import { generateKeyPairFromSeed } from "@stablelib/ed25519";
199
200
// Generate keys from a known seed (for testing or deterministic purposes)
201
const seed = new Uint8Array(32);
202
seed.fill(1); // Don't use predictable seeds in production!
203
204
const keyPair = generateKeyPairFromSeed(seed);
205
// This will always produce the same key pair for the same seed
206
```
207
208
### Message Signing with Error Handling
209
210
```typescript
211
import {
212
generateKeyPair,
213
sign,
214
verify,
215
SIGNATURE_LENGTH
216
} from "@stablelib/ed25519";
217
218
try {
219
const keyPair = generateKeyPair();
220
const message = new TextEncoder().encode("Important message");
221
222
const signature = sign(keyPair.secretKey, message);
223
console.log(`Signature length: ${signature.length} bytes`); // 64 bytes
224
225
if (signature.length !== SIGNATURE_LENGTH) {
226
throw new Error("Invalid signature length");
227
}
228
229
const isValid = verify(keyPair.publicKey, message, signature);
230
console.log(`Signature valid: ${isValid}`);
231
} catch (error) {
232
console.error("Signing failed:", error.message);
233
}
234
```
235
236
### Key Conversion for X25519
237
238
```typescript
239
import {
240
generateKeyPair,
241
convertPublicKeyToX25519,
242
convertSecretKeyToX25519
243
} from "@stablelib/ed25519";
244
245
// Generate Ed25519 keys
246
const ed25519Keys = generateKeyPair();
247
248
// Convert to X25519 for key exchange
249
const x25519PublicKey = convertPublicKeyToX25519(ed25519Keys.publicKey);
250
const x25519SecretKey = convertSecretKeyToX25519(ed25519Keys.secretKey);
251
252
console.log(`X25519 public key length: ${x25519PublicKey.length} bytes`); // 32 bytes
253
console.log(`X25519 secret key length: ${x25519SecretKey.length} bytes`); // 32 bytes
254
```
255
256
### Extracting Public Key
257
258
```typescript
259
import {
260
generateKeyPair,
261
extractPublicKeyFromSecretKey
262
} from "@stablelib/ed25519";
263
264
const keyPair = generateKeyPair();
265
266
// Extract public key from secret key (useful when you only store secret key)
267
const extractedPublicKey = extractPublicKeyFromSecretKey(keyPair.secretKey);
268
269
// Verify they match
270
const keysMatch = keyPair.publicKey.every(
271
(byte, index) => byte === extractedPublicKey[index]
272
);
273
console.log(`Keys match: ${keysMatch}`); // true
274
```