0
# Digital Signatures
1
2
RFC8032-compliant signing and verification operations with both async and sync variants. Supports ZIP215 consensus-friendly verification and provides strong unforgeability under chosen message attacks (SUF-CMA).
3
4
## Capabilities
5
6
### Message Signing
7
8
Creates ed25519 signatures for messages using a secret key, following RFC8032 section 5.1.6.
9
10
```typescript { .api }
11
/**
12
* Sign a message asynchronously using ed25519
13
* @param message - Message to sign as Uint8Array
14
* @param secretKey - 32-byte secret key
15
* @returns Promise resolving to 64-byte signature
16
*/
17
function signAsync(message: Bytes, secretKey: Bytes): Promise<Bytes>;
18
19
/**
20
* Sign a message synchronously using ed25519 (requires hashes.sha512 to be set)
21
* @param message - Message to sign as Uint8Array
22
* @param secretKey - 32-byte secret key
23
* @returns 64-byte signature
24
*/
25
function sign(message: Bytes, secretKey: Bytes): Bytes;
26
```
27
28
**Usage Examples:**
29
30
```typescript
31
import * as ed from '@noble/ed25519';
32
33
// Generate keys
34
const { secretKey, publicKey } = await ed.keygenAsync();
35
36
// Sign a message (async)
37
const message = new TextEncoder().encode('Hello, World!');
38
const signature = await ed.signAsync(message, secretKey);
39
console.log(signature.length); // 64
40
41
// Sign with raw bytes
42
const rawMessage = new Uint8Array([1, 2, 3, 4, 5]);
43
const rawSignature = await ed.signAsync(rawMessage, secretKey);
44
45
// Sync version (requires setting hash function first)
46
import { sha512 } from '@noble/hashes/sha512';
47
ed.hashes.sha512 = sha512;
48
const syncSignature = ed.sign(message, secretKey);
49
```
50
51
### Signature Verification
52
53
Verifies ed25519 signatures against messages and public keys, following RFC8032 section 5.1.7 with optional ZIP215 compliance.
54
55
```typescript { .api }
56
/**
57
* Verify a signature asynchronously
58
* @param signature - 64-byte signature to verify
59
* @param message - Original message that was signed
60
* @param publicKey - 32-byte public key
61
* @param opts - Verification options
62
* @returns Promise resolving to true if signature is valid
63
*/
64
function verifyAsync(
65
signature: Bytes,
66
message: Bytes,
67
publicKey: Bytes,
68
opts?: EdDSAVerifyOpts
69
): Promise<boolean>;
70
71
/**
72
* Verify a signature synchronously (requires hashes.sha512 to be set)
73
* @param signature - 64-byte signature to verify
74
* @param message - Original message that was signed
75
* @param publicKey - 32-byte public key
76
* @param opts - Verification options
77
* @returns True if signature is valid
78
*/
79
function verify(
80
signature: Bytes,
81
message: Bytes,
82
publicKey: Bytes,
83
opts?: EdDSAVerifyOpts
84
): boolean;
85
86
/**
87
* Verification options for signature validation
88
*/
89
type EdDSAVerifyOpts = {
90
/** Enable ZIP215 compliance for consensus-friendly verification (default: true) */
91
zip215?: boolean
92
};
93
```
94
95
**Usage Examples:**
96
97
```typescript
98
import * as ed from '@noble/ed25519';
99
100
// Complete signing and verification flow
101
const { secretKey, publicKey } = await ed.keygenAsync();
102
const message = new TextEncoder().encode('Important message');
103
const signature = await ed.signAsync(message, secretKey);
104
105
// Verify signature (async)
106
const isValid = await ed.verifyAsync(signature, message, publicKey);
107
console.log(isValid); // true
108
109
// Verify with ZIP215 disabled (strict RFC8032 compliance)
110
const strictValid = await ed.verifyAsync(signature, message, publicKey, { zip215: false });
111
112
// Invalid signature verification
113
const tampered = new Uint8Array(signature);
114
tampered[0] = tampered[0] ^ 1; // Flip one bit
115
const invalidResult = await ed.verifyAsync(tampered, message, publicKey);
116
console.log(invalidResult); // false
117
118
// Sync version
119
import { sha512 } from '@noble/hashes/sha512';
120
ed.hashes.sha512 = sha512;
121
const syncValid = ed.verify(signature, message, publicKey);
122
```
123
124
### Compliance Modes
125
126
The library supports different verification compliance modes:
127
128
**ZIP215 Mode (Default)**
129
- Consensus-friendly verification
130
- Accepts non-canonical point encodings
131
- Suitable for blockchain and consensus applications
132
- Matches behavior expected by many crypto protocols
133
134
**RFC8032 Strict Mode**
135
- Strict compliance with RFC8032 specification
136
- Rejects non-canonical point encodings
137
- More restrictive validation
138
- Use `{ zip215: false }` in verification options
139
140
**Usage Example:**
141
142
```typescript
143
import * as ed from '@noble/ed25519';
144
145
const { secretKey, publicKey } = await ed.keygenAsync();
146
const message = new TextEncoder().encode('test message');
147
const signature = await ed.signAsync(message, secretKey);
148
149
// ZIP215 mode (default, consensus-friendly)
150
const zip215Valid = await ed.verifyAsync(signature, message, publicKey);
151
const zip215Explicit = await ed.verifyAsync(signature, message, publicKey, { zip215: true });
152
153
// RFC8032 strict mode
154
const strictValid = await ed.verifyAsync(signature, message, publicKey, { zip215: false });
155
156
console.log(zip215Valid, zip215Explicit, strictValid); // All should be true for valid signatures
157
```
158
159
## Error Handling
160
161
The signing and verification functions throw errors for invalid inputs:
162
163
- Invalid secret key length (must be 32 bytes)
164
- Invalid public key length (must be 32 bytes)
165
- Invalid signature length (must be 64 bytes)
166
- Invalid public key point (not on curve)
167
- Missing hash function for sync operations
168
169
```typescript
170
import * as ed from '@noble/ed25519';
171
172
try {
173
// This will throw - invalid key length
174
const invalidKey = new Uint8Array(31); // Should be 32
175
await ed.signAsync(new Uint8Array(10), invalidKey);
176
} catch (error) {
177
console.log('Invalid key length error');
178
}
179
```
180
181
## Types
182
183
```typescript { .api }
184
type Bytes = Uint8Array;
185
type EdDSAVerifyOpts = { zip215?: boolean };
186
```