or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

abstract-primitives.mdcurves.mdindex.mdutilities.mdwebcrypto.md

webcrypto.mddocs/

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