0
# WebCrypto Integration
1
2
Native browser WebCrypto API wrappers providing hardware-accelerated elliptic curve operations. These wrappers offer the same API as the main curve implementations but use the browser's built-in cryptographic primitives for better performance and security.
3
4
## Capabilities
5
6
### NIST Curves with WebCrypto
7
8
Hardware-accelerated ECDSA signatures and ECDH key exchange for NIST P-curves.
9
10
```typescript { .api }
11
import { p256, p384, p521 } from "@noble/curves/webcrypto";
12
13
// NIST P-256 (secp256r1)
14
const p256: WebCryptoNIST;
15
16
// NIST P-384 (secp384r1)
17
const p384: WebCryptoNIST;
18
19
// NIST P-521 (secp521r1)
20
const p521: WebCryptoNIST;
21
22
interface WebCryptoNIST extends WebCryptoBaseCurve, WebCryptoSigner, WebCryptoECDH {
23
name: string;
24
isAvailable(): Promise<boolean>;
25
getPublicKey(secretKey: Key, opts?: WebCryptoGetPubOpts): Promise<Key>;
26
sign(msgHash: Uint8Array, privateKey: Key, opts?: WebCryptoOpts): Promise<Uint8Array>;
27
verify(signature: Uint8Array, msgHash: Uint8Array, publicKey: Key, opts?: WebCryptoOpts): Promise<boolean>;
28
getSharedSecret(priv: Uint8Array, pub: Uint8Array, opts?: WebCryptoOpts): Promise<Uint8Array>;
29
utils: {
30
randomSecretKey: (format?: Format) => Promise<Key>;
31
convertSecretKey: (key: Key, inFormat?: Format, outFormat?: Format) => Promise<Key>;
32
convertPublicKey: (key: Key, inFormat?: Format, outFormat?: Format) => Promise<Key>;
33
};
34
}
35
```
36
37
**Usage Examples:**
38
39
```typescript
40
import { p256 } from "@noble/curves/webcrypto";
41
42
// Check if WebCrypto P-256 is available
43
const available = await p256.isAvailable();
44
45
if (available) {
46
// Generate random secret key
47
const secretKey = await p256.utils.randomSecretKey();
48
49
// Get public key from secret key
50
const publicKey = await p256.getPublicKey(secretKey);
51
52
// Sign message hash
53
const msgHash = new Uint8Array(32); // Your message hash
54
const signature = await p256.sign(msgHash, secretKey);
55
56
// Verify signature
57
const isValid = await p256.verify(signature, msgHash, publicKey);
58
59
// ECDH key exchange
60
const alicePriv = await p256.utils.randomSecretKey();
61
const bobPriv = await p256.utils.randomSecretKey();
62
const bobPub = await p256.getPublicKey(bobPriv);
63
64
const sharedSecret = await p256.getSharedSecret(alicePriv, bobPub);
65
}
66
```
67
68
### EdDSA Curves with WebCrypto
69
70
Hardware-accelerated EdDSA signatures for Edwards curves.
71
72
```typescript { .api }
73
import { ed25519, ed448 } from "@noble/curves/webcrypto";
74
75
// Ed25519 with WebCrypto
76
const ed25519: WebCryptoEdDSA;
77
78
// Ed448 with WebCrypto
79
const ed448: WebCryptoEdDSA;
80
81
interface WebCryptoEdDSA extends WebCryptoBaseCurve, WebCryptoSigner {
82
name: string;
83
isAvailable(): Promise<boolean>;
84
getPublicKey(secretKey: Key, opts?: WebCryptoGetPubOpts): Promise<Key>;
85
sign(msgHash: Uint8Array, privateKey: Key, opts?: WebCryptoOpts): Promise<Uint8Array>;
86
verify(signature: Uint8Array, msgHash: Uint8Array, publicKey: Key, opts?: WebCryptoOpts): Promise<boolean>;
87
utils: {
88
randomSecretKey: (format?: Format) => Promise<Key>;
89
convertSecretKey: (key: Key, inFormat?: Format, outFormat?: Format) => Promise<Key>;
90
convertPublicKey: (key: Key, inFormat?: Format, outFormat?: Format) => Promise<Key>;
91
};
92
}
93
```
94
95
### Montgomery Curves with WebCrypto
96
97
Hardware-accelerated ECDH key exchange for Montgomery curves.
98
99
```typescript { .api }
100
import { x25519, x448 } from "@noble/curves/webcrypto";
101
102
// X25519 with WebCrypto
103
const x25519: WebCryptoMontgomery;
104
105
// X448 with WebCrypto
106
const x448: WebCryptoMontgomery;
107
108
interface WebCryptoMontgomery extends WebCryptoBaseCurve, WebCryptoECDH {
109
name: string;
110
isAvailable(): Promise<boolean>;
111
getPublicKey(secretKey: Key, opts?: WebCryptoGetPubOpts): Promise<Key>;
112
getSharedSecret(priv: Uint8Array, pub: Uint8Array, opts?: WebCryptoOpts): Promise<Uint8Array>;
113
utils: {
114
randomSecretKey: (format?: Format) => Promise<Key>;
115
convertSecretKey: (key: Key, inFormat?: Format, outFormat?: Format) => Promise<Key>;
116
convertPublicKey: (key: Key, inFormat?: Format, outFormat?: Format) => Promise<Key>;
117
};
118
}
119
```
120
121
**Usage Examples:**
122
123
```typescript
124
import { x25519 } from "@noble/curves/webcrypto";
125
126
// Check availability
127
if (await x25519.isAvailable()) {
128
// Generate key pair
129
const alicePriv = await x25519.utils.randomSecretKey();
130
const alicePub = await x25519.getPublicKey(alicePriv);
131
132
const bobPriv = await x25519.utils.randomSecretKey();
133
const bobPub = await x25519.getPublicKey(bobPriv);
134
135
// Compute shared secret
136
const sharedSecret = await x25519.getSharedSecret(alicePriv, bobPub);
137
}
138
```
139
140
### Availability Check
141
142
Utility function to check if a curve is supported by the WebCrypto implementation.
143
144
```typescript { .api }
145
import { supportsWc } from "@noble/curves/webcrypto";
146
147
/**
148
* Check if WebCrypto curve is available
149
* @param curve - WebCrypto curve instance to test
150
* @returns Promise resolving to availability status
151
*/
152
function supportsWc(curve: WebCryptoBaseCurve): Promise<boolean>;
153
```
154
155
**Usage Example:**
156
157
```typescript
158
import { p256, ed25519, x25519, supportsWc } from "@noble/curves/webcrypto";
159
160
// Check multiple curve availability
161
const p256Available = await supportsWc(p256);
162
const ed25519Available = await supportsWc(ed25519);
163
const x25519Available = await supportsWc(x25519);
164
165
console.log(`P-256: ${p256Available}`);
166
console.log(`Ed25519: ${ed25519Available}`);
167
console.log(`X25519: ${x25519Available}`);
168
```
169
170
## Core Types
171
172
```typescript { .api }
173
// Key formats supported by WebCrypto
174
type Format = 'raw' | 'jwk' | 'spki' | 'pkcs8';
175
176
// Key input type - either JWK object or raw bytes
177
type Key = JsonWebKey | Uint8Array;
178
179
// JSON Web Key structure
180
type JsonWebKey = {
181
crv?: string;
182
d?: string;
183
kty?: string;
184
x?: string;
185
y?: string;
186
[key: string]: unknown;
187
};
188
189
// WebCrypto operation options
190
interface WebCryptoOpts {
191
format?: Format;
192
}
193
194
// Public key generation options
195
interface WebCryptoGetPubOpts {
196
secFormat?: Format;
197
pubFormat?: Format;
198
}
199
200
// Base curve interface
201
interface WebCryptoBaseCurve {
202
name: string;
203
isAvailable(): Promise<boolean>;
204
getPublicKey(secretKey: Key, opts?: WebCryptoGetPubOpts): Promise<Key>;
205
utils: {
206
randomSecretKey: (format?: Format) => Promise<Key>;
207
convertSecretKey: (key: Key, inFormat?: Format, outFormat?: Format) => Promise<Key>;
208
convertPublicKey: (key: Key, inFormat?: Format, outFormat?: Format) => Promise<Key>;
209
};
210
}
211
212
// Signature operations
213
interface WebCryptoSigner {
214
sign(msgHash: Uint8Array, privateKey: Key, opts?: WebCryptoOpts): Promise<Uint8Array>;
215
verify(signature: Uint8Array, msgHash: Uint8Array, publicKey: Key, opts?: WebCryptoOpts): Promise<boolean>;
216
}
217
218
// ECDH operations
219
interface WebCryptoECDH {
220
getSharedSecret(priv: Uint8Array, pub: Uint8Array, opts?: WebCryptoOpts): Promise<Uint8Array>;
221
}
222
```
223
224
## Browser Compatibility
225
226
### Supported Environments
227
228
- **Chrome**: Full support for all curves
229
- **Firefox**: Limited raw key format support
230
- **Safari**: Limited raw key format support
231
- **Node.js**: Full support including Ed448
232
- **Bun**: Full support with minor key padding quirks
233
- **Deno**: Full support with export validation
234
235
### Key Format Limitations
236
237
**Raw Format Issues:**
238
- Raw secret key import/export prohibited by WebCrypto spec for security
239
- Firefox and Safari have additional raw format restrictions
240
- Workaround uses PKCS#8 wrapping for raw secret keys
241
242
**Point Encoding Differences:**
243
- WebCrypto returns uncompressed points for NIST curves
244
- `getSharedSecret` returns different output lengths:
245
- Noble: 33 bytes (y-parity + x coordinate)
246
- WebCrypto: 32 bytes (x coordinate only)
247
- X25519/X448 shared secret identical between implementations
248
249
### Feature Detection
250
251
Always check availability before using WebCrypto curves:
252
253
```typescript
254
import { p256, ed25519 } from "@noble/curves/webcrypto";
255
256
const curves = [
257
{ name: 'P-256', curve: p256 },
258
{ name: 'Ed25519', curve: ed25519 }
259
];
260
261
for (const { name, curve } of curves) {
262
const available = await curve.isAvailable();
263
console.log(`${name}: ${available ? 'supported' : 'not supported'}`);
264
}
265
```
266
267
## Performance Benefits
268
269
WebCrypto implementations offer several advantages:
270
271
- **Hardware Acceleration**: Leverages platform-specific optimizations
272
- **Native Implementation**: Uses browser/Node.js built-in cryptography
273
- **Security**: Operations run in secure contexts with proper key isolation
274
- **Memory Safety**: Reduced JavaScript execution for cryptographic operations
275
276
Use WebCrypto wrappers when:
277
- Performance is critical
278
- Working in browsers with WebCrypto support
279
- Need hardware security module integration
280
- Want to reduce JavaScript bundle size for basic operations