0
# Curve Implementations
1
2
Complete implementations of popular elliptic curves with signature schemes, key exchange protocols, and specialized cryptographic operations.
3
4
## Capabilities
5
6
### secp256k1 Curve
7
8
Bitcoin's elliptic curve with ECDSA signatures and BIP340 Schnorr signatures.
9
10
```typescript { .api }
11
import { secp256k1, schnorr } from "@noble/curves/secp256k1";
12
13
// Main curve object
14
const secp256k1: {
15
getPublicKey(privateKey: PrivKey): Uint8Array;
16
sign(message: Hex, privateKey: PrivKey, opts?: ECDSASignOpts): ECDSASignature;
17
verify(signature: ECDSASignature, message: Hex, publicKey: Hex, opts?: ECDSAVerifyOpts): boolean;
18
Point: WeierstrassPointCons<bigint>;
19
Signature: ECDSASignatureCons;
20
utils: {
21
randomPrivateKey(): Uint8Array;
22
precompute(windowSize?: number, point?: WeierstrassPoint<bigint>): WeierstrassPoint<bigint>;
23
mod(a: bigint, b?: bigint): bigint;
24
invert(number: bigint, modulo?: bigint): bigint;
25
hashToPrivateScalar(hash: Hex): bigint;
26
};
27
CURVE: {
28
p: bigint;
29
n: bigint;
30
a: bigint;
31
b: bigint;
32
Gx: bigint;
33
Gy: bigint;
34
};
35
};
36
37
// Schnorr signatures (BIP340)
38
const schnorr: {
39
sign(message: Hex, privateKey: PrivKey, auxRand?: Hex): Uint8Array;
40
verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
41
getPublicKey(privateKey: PrivKey): Uint8Array;
42
};
43
44
// Hash-to-curve functionality
45
function hashToCurve(msg: Uint8Array, options?: { DST?: string }): WeierstrassPoint<bigint>;
46
function encodeToCurve(msg: Uint8Array, options?: { DST?: string }): WeierstrassPoint<bigint>;
47
```
48
49
**Usage Examples:**
50
51
```typescript
52
import { secp256k1, schnorr } from "@noble/curves/secp256k1";
53
54
// ECDSA signing
55
const privKey = secp256k1.utils.randomPrivateKey();
56
const pubKey = secp256k1.getPublicKey(privKey);
57
const msg = new TextEncoder().encode("hello");
58
59
const signature = secp256k1.sign(msg, privKey);
60
const isValid = secp256k1.verify(signature, msg, pubKey);
61
62
// Schnorr signing (BIP340)
63
const schnorrSig = schnorr.sign(msg, privKey);
64
const schnorrValid = schnorr.verify(schnorrSig, msg, schnorr.getPublicKey(privKey));
65
```
66
67
### Ed25519 Curve
68
69
High-performance Edwards curve with EdDSA signatures and X25519 key exchange.
70
71
```typescript { .api }
72
import { ed25519, ed25519ctx, ed25519ph, x25519, RistrettoPoint } from "@noble/curves/ed25519";
73
74
// Standard Ed25519
75
const ed25519: {
76
getPublicKey(privateKey: PrivKey): Uint8Array;
77
sign(message: Hex, privateKey: PrivKey): Uint8Array;
78
verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
79
Point: EdwardsPointCons;
80
utils: {
81
randomPrivateKey(): Uint8Array;
82
getExtendedPublicKey(privateKey: PrivKey): { prefix: Uint8Array; scalar: bigint; point: EdwardsPoint; pointBytes: Uint8Array };
83
};
84
};
85
86
// Ed25519 with context support
87
const ed25519ctx: {
88
getPublicKey(privateKey: PrivKey): Uint8Array;
89
sign(message: Hex, privateKey: PrivKey, context?: Hex): Uint8Array;
90
verify(signature: Hex, message: Hex, publicKey: Hex, context?: Hex): boolean;
91
};
92
93
// Ed25519 with pre-hashing
94
const ed25519ph: {
95
getPublicKey(privateKey: PrivKey): Uint8Array;
96
sign(message: Hex, privateKey: PrivKey, context?: Hex): Uint8Array;
97
verify(signature: Hex, message: Hex, publicKey: Hex, context?: Hex): boolean;
98
};
99
100
// X25519 key exchange
101
const x25519: {
102
getPublicKey(privateKey: PrivKey): Uint8Array;
103
getSharedSecret(privateKey: PrivKey, publicKey: Hex): Uint8Array;
104
utils: {
105
randomPrivateKey(): Uint8Array;
106
};
107
};
108
109
// Ristretto255 group
110
const ristretto255: {
111
Point: typeof RistrettoPoint;
112
hashToCurve(msg: Uint8Array, options?: { DST?: string }): RistrettoPoint;
113
encodeToCurve(msg: Uint8Array, options?: { DST?: string }): RistrettoPoint;
114
};
115
116
// Conversion utilities
117
function edwardsToMontgomeryPub(edwardsPub: Hex): Uint8Array;
118
function edwardsToMontgomeryPriv(edwardsPriv: Uint8Array): Uint8Array;
119
120
// Hash-to-curve functionality
121
function hashToCurve(msg: Uint8Array, options?: { DST?: string }): EdwardsPoint;
122
function encodeToCurve(msg: Uint8Array, options?: { DST?: string }): EdwardsPoint;
123
```
124
125
**Usage Examples:**
126
127
```typescript
128
import { ed25519, x25519 } from "@noble/curves/ed25519";
129
130
// EdDSA signing
131
const privKey = ed25519.utils.randomPrivateKey();
132
const pubKey = ed25519.getPublicKey(privKey);
133
const msg = new TextEncoder().encode("message");
134
135
const signature = ed25519.sign(msg, privKey);
136
const isValid = ed25519.verify(signature, msg, pubKey);
137
138
// X25519 key exchange
139
const alicePriv = x25519.utils.randomPrivateKey();
140
const alicePub = x25519.getPublicKey(alicePriv);
141
const bobPriv = x25519.utils.randomPrivateKey();
142
const bobPub = x25519.getPublicKey(bobPriv);
143
144
const sharedSecret = x25519.getSharedSecret(alicePriv, bobPub);
145
```
146
147
### NIST Curves
148
149
FIPS-approved elliptic curves P-256, P-384, and P-521.
150
151
```typescript { .api }
152
import { p256, p384, p521, secp256r1, secp384r1, secp521r1 } from "@noble/curves/nist";
153
154
// P-256 (secp256r1)
155
const p256: {
156
getPublicKey(privateKey: PrivKey): Uint8Array;
157
sign(message: Hex, privateKey: PrivKey, opts?: ECDSASignOpts): ECDSASignature;
158
verify(signature: ECDSASignature, message: Hex, publicKey: Hex): boolean;
159
Point: WeierstrassPointCons<bigint>;
160
Signature: ECDSASignatureCons;
161
utils: CurveUtils;
162
};
163
164
// P-384 (secp384r1)
165
const p384: typeof p256;
166
167
// P-521 (secp521r1)
168
const p521: typeof p256;
169
170
// Aliases
171
const secp256r1: typeof p256;
172
const secp384r1: typeof p384;
173
const secp521r1: typeof p521;
174
175
// Hash-to-curve hashers
176
const p256_hasher: H2CHasher<bigint>;
177
const p384_hasher: H2CHasher<bigint>;
178
const p521_hasher: H2CHasher<bigint>;
179
```
180
181
### BLS12-381 Curve
182
183
Pairing-friendly curve for BLS signatures and zero-knowledge applications.
184
185
```typescript { .api }
186
import { bls12_381 } from "@noble/curves/bls12-381";
187
188
const bls12_381: {
189
// BLS signature operations
190
sign(message: Hex, privateKey: PrivKey): Uint8Array;
191
verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
192
aggregatePublicKeys(publicKeys: Hex[]): Uint8Array;
193
aggregateSignatures(signatures: Hex[]): Uint8Array;
194
verifyBatch(signature: Hex, messages: Hex[], publicKeys: Hex[]): boolean;
195
196
// Key operations
197
getPublicKey(privateKey: PrivKey): Uint8Array;
198
199
// Points and fields
200
G1: {
201
Point: G1PointCons;
202
ZERO: G1Point;
203
BASE: G1Point;
204
};
205
G2: {
206
Point: G2PointCons;
207
ZERO: G2Point;
208
BASE: G2Point;
209
};
210
GT: FieldExtension;
211
212
// Pairing operations
213
pairing(P: G1Point, Q: G2Point): Fp12;
214
millerLoop(pairs: [G1Point, G2Point][]): Fp12;
215
finalExponentiate(num: Fp12): Fp12;
216
217
// Hash-to-curve operations
218
G1_hashToCurve(msg: Uint8Array, DST?: string): G1Point;
219
G2_hashToCurve(msg: Uint8Array, DST?: string): G2Point;
220
221
// Point encoding/decoding
222
G1_pointToBytes(point: G1Point, isCompressed?: boolean): Uint8Array;
223
G1_pointFromBytes(bytes: Uint8Array): G1Point;
224
G2_pointToBytes(point: G2Point, isCompressed?: boolean): Uint8Array;
225
G2_pointFromBytes(bytes: Uint8Array): G2Point;
226
227
// Signature encoding/decoding
228
G1_signatureToBytes(point: G1Point): Uint8Array;
229
G1_signatureFromBytes(bytes: Uint8Array): G1Point;
230
G2_signatureToBytes(point: G2Point): Uint8Array;
231
G2_signatureFromBytes(bytes: Uint8Array): G2Point;
232
233
// Utilities
234
utils: {
235
randomPrivateKey(): Uint8Array;
236
calcPairingPrecomputes(point: G2Point): any;
237
isValidPrivateKey(privateKey: PrivKey): boolean;
238
normPrivateKeyToScalar(privateKey: PrivKey): bigint;
239
};
240
};
241
242
// Scalar field
243
const bls12_381_Fr: IField<bigint>;
244
```
245
246
### BN254 Curve
247
248
BN254 (alt_bn128) pairing-friendly curve used in Ethereum and zk-SNARKs.
249
250
```typescript { .api }
251
import { bn254, bn254_weierstrass } from "@noble/curves/bn254";
252
253
// BLS-style interface for BN254
254
const bn254: {
255
sign(message: Hex, privateKey: PrivKey): Uint8Array;
256
verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
257
getPublicKey(privateKey: PrivKey): Uint8Array;
258
259
G1: {
260
Point: G1PointCons;
261
ZERO: G1Point;
262
BASE: G1Point;
263
};
264
G2: {
265
Point: G2PointCons;
266
ZERO: G2Point;
267
BASE: G2Point;
268
};
269
270
// Pairing operations
271
pairing(P: G1Point, Q: G2Point): any;
272
utils: BLSUtils;
273
};
274
275
// Standard Weierstrass interface for BN254
276
const bn254_weierstrass: {
277
getPublicKey(privateKey: PrivKey): Uint8Array;
278
sign(message: Hex, privateKey: PrivKey): ECDSASignature;
279
verify(signature: ECDSASignature, message: Hex, publicKey: Hex): boolean;
280
Point: WeierstrassPointCons<bigint>;
281
};
282
283
// Scalar field
284
const bn254_Fr: IField<bigint>;
285
```
286
287
### Ed448 Curve
288
289
Ed448-Goldilocks curve with EdDSA signatures and X448 key exchange.
290
291
```typescript { .api }
292
import { ed448, ed448ph, ed448ctx, x448 } from "@noble/curves/ed448";
293
294
// Standard Ed448
295
const ed448: {
296
getPublicKey(privateKey: PrivKey): Uint8Array;
297
sign(message: Hex, privateKey: PrivKey): Uint8Array;
298
verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
299
Point: EdwardsPointCons;
300
utils: {
301
randomPrivateKey(): Uint8Array;
302
};
303
};
304
305
// Ed448 with pre-hashing
306
const ed448ph: {
307
getPublicKey(privateKey: PrivKey): Uint8Array;
308
sign(message: Hex, privateKey: PrivKey, context?: Hex): Uint8Array;
309
verify(signature: Hex, message: Hex, publicKey: Hex, context?: Hex): boolean;
310
};
311
312
// Ed448 with context support
313
const ed448ctx: {
314
getPublicKey(privateKey: PrivKey): Uint8Array;
315
sign(message: Hex, privateKey: PrivKey, context?: Hex): Uint8Array;
316
verify(signature: Hex, message: Hex, publicKey: Hex, context?: Hex): boolean;
317
};
318
319
// X448 key exchange
320
const x448: {
321
getPublicKey(privateKey: PrivKey): Uint8Array;
322
getSharedSecret(privateKey: PrivKey, publicKey: Hex): Uint8Array;
323
utils: {
324
randomPrivateKey(): Uint8Array;
325
};
326
};
327
```
328
329
### Additional Curves
330
331
### Miscellaneous and ZK-Friendly Curves
332
333
The `/misc` export provides specialized curves for zero-knowledge proofs and other advanced cryptographic applications.
334
335
#### JubJub Curve
336
337
Twisted Edwards curve over the BLS12-381 scalar field, designed for zero-knowledge proof systems.
338
339
```typescript { .api }
340
import { jubjub, jubjub_groupHash, jubjub_findGroupHash } from "@noble/curves/misc";
341
342
// JubJub curve (jubjub Fp = bls12-381 n)
343
const jubjub: {
344
getPublicKey(privateKey: PrivKey): Uint8Array;
345
sign(message: Hex, privateKey: PrivKey): Uint8Array;
346
verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
347
Point: EdwardsPointCons;
348
utils: CurveUtils;
349
};
350
351
// JubJub group hash functions for deterministic point generation
352
function jubjub_groupHash(tag: Uint8Array, personalization: Uint8Array): EdwardsPoint;
353
function jubjub_findGroupHash(m: Uint8Array, personalization: Uint8Array): EdwardsPoint;
354
```
355
356
#### BabyJubJub Curve
357
358
Twisted Edwards curve over the BN254 scalar field, commonly used in zero-knowledge applications.
359
360
```typescript { .api }
361
import { babyjubjub } from "@noble/curves/misc";
362
363
// BabyJubJub curve (babyjubjub Fp = bn254 n)
364
const babyjubjub: {
365
getPublicKey(privateKey: PrivKey): Uint8Array;
366
sign(message: Hex, privateKey: PrivKey): Uint8Array;
367
verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
368
Point: EdwardsPointCons;
369
utils: CurveUtils;
370
};
371
```
372
373
#### Pasta Curves (Pallas/Vesta)
374
375
Cycle of curves designed for recursive zero-knowledge proofs, where each curve's base field equals the other's scalar field.
376
377
```typescript { .api }
378
import { pallas, vesta, pasta_p, pasta_q } from "@noble/curves/misc";
379
380
// Pallas curve (deprecated - use newer ZK-friendly alternatives)
381
const pallas: {
382
getPublicKey(privateKey: PrivKey): Uint8Array;
383
sign(message: Hex, privateKey: PrivKey): ECDSASignature;
384
verify(signature: ECDSASignature, message: Hex, publicKey: Hex): boolean;
385
Point: WeierstrassPointCons<bigint>;
386
utils: CurveUtils;
387
};
388
389
// Vesta curve (deprecated - use newer ZK-friendly alternatives)
390
const vesta: {
391
getPublicKey(privateKey: PrivKey): Uint8Array;
392
sign(message: Hex, privateKey: PrivKey): ECDSASignature;
393
verify(signature: ECDSASignature, message: Hex, publicKey: Hex): boolean;
394
Point: WeierstrassPointCons<bigint>;
395
utils: CurveUtils;
396
};
397
398
// Pasta field parameters
399
const pasta_p: bigint; // Pallas base field = Vesta scalar field
400
const pasta_q: bigint; // Vesta base field = Pallas scalar field
401
```
402
403
**Note**: Pasta curves are also available via separate import paths:
404
```typescript
405
import { pallas, vesta } from "@noble/curves/pasta"; // Deprecated aliases
406
```
407
408
#### Ristretto255 Cofactor Elimination
409
410
Ristretto255 provides a prime-order group from Ed25519 by eliminating the cofactor, ensuring every element has prime order.
411
412
```typescript { .api }
413
import { ristretto255, RistrettoPoint } from "@noble/curves/ed25519";
414
415
// Ristretto255 group operations
416
const ristretto255: {
417
Point: typeof RistrettoPoint;
418
hashToCurve(msg: Uint8Array, options?: { DST?: string }): RistrettoPoint;
419
encodeToCurve(msg: Uint8Array, options?: { DST?: string }): RistrettoPoint;
420
};
421
422
// Ristretto255 point class with prime-order group operations
423
class RistrettoPoint {
424
static ZERO: RistrettoPoint;
425
static BASE: RistrettoPoint;
426
427
static fromBytes(bytes: Uint8Array): RistrettoPoint;
428
static fromHex(hex: string): RistrettoPoint;
429
430
add(other: RistrettoPoint): RistrettoPoint;
431
subtract(other: RistrettoPoint): RistrettoPoint;
432
multiply(scalar: bigint): RistrettoPoint;
433
negate(): RistrettoPoint;
434
double(): RistrettoPoint;
435
436
equals(other: RistrettoPoint): boolean;
437
toBytes(): Uint8Array;
438
toHex(): string;
439
}
440
```
441
442
#### Decaf448 Cofactor Elimination
443
444
Decaf448 provides a prime-order group from Ed448 by eliminating the cofactor.
445
446
```typescript { .api }
447
import { decaf448, DecafPoint } from "@noble/curves/ed448";
448
449
// Decaf448 group operations
450
const decaf448: {
451
Point: typeof DecafPoint;
452
hashToCurve(msg: Uint8Array, options?: { DST?: string }): DecafPoint;
453
encodeToCurve(msg: Uint8Array, options?: { DST?: string }): DecafPoint;
454
};
455
456
// Decaf448 point class with prime-order group operations
457
class DecafPoint {
458
static ZERO: DecafPoint;
459
static BASE: DecafPoint;
460
461
static fromBytes(bytes: Uint8Array): DecafPoint;
462
static fromHex(hex: string): DecafPoint;
463
464
add(other: DecafPoint): DecafPoint;
465
subtract(other: DecafPoint): DecafPoint;
466
multiply(scalar: bigint): DecafPoint;
467
negate(): DecafPoint;
468
double(): DecafPoint;
469
470
equals(other: DecafPoint): boolean;
471
toBytes(): Uint8Array;
472
toHex(): string;
473
}
474
```
475
476
#### Miscellaneous Curves
477
478
Additional specialized curves for specific applications.
479
480
```typescript { .api }
481
import { stark } from "@noble/curves/misc";
482
483
// StarkNet curve - prime-order curve used by StarkNet zero-knowledge rollup
484
const stark: {
485
getPublicKey(privateKey: PrivKey): Uint8Array;
486
sign(message: Hex, privateKey: PrivKey): ECDSASignature;
487
verify(signature: ECDSASignature, message: Hex, publicKey: Hex): boolean;
488
Point: WeierstrassPointCons<bigint>;
489
utils: CurveUtils;
490
};
491
```
492
493
## Common Curve Interface Types
494
495
```typescript { .api }
496
interface CurveUtils {
497
randomPrivateKey(): Uint8Array;
498
precompute(windowSize?: number, point?: any): any;
499
mod(a: bigint, b?: bigint): bigint;
500
invert(number: bigint, modulo?: bigint): bigint;
501
hashToPrivateScalar(hash: Hex): bigint;
502
}
503
504
interface ECDSASignOpts {
505
lowS?: boolean;
506
extraEntropy?: Hex | boolean;
507
canonical?: boolean;
508
der?: boolean;
509
recovered?: boolean;
510
}
511
512
interface ECDSAVerifyOpts {
513
lowS?: boolean;
514
format?: ECDSASigFormat;
515
}
516
517
type ECDSASigFormat = 'compact' | 'recovered' | 'der';
518
519
interface H2CHasher<T> {
520
hashToCurve(msg: Uint8Array, options?: { DST?: string }): any;
521
encodeToCurve(msg: Uint8Array, options?: { DST?: string }): any;
522
}
523
```