0
# Abstract Cryptographic Primitives
1
2
Low-level building blocks for implementing custom elliptic curves, including field arithmetic, point operations, signature schemes, and hash-to-curve functionality.
3
4
## Capabilities
5
6
### Weierstrass Curves
7
8
Abstract implementation for short Weierstrass curves (y² = x³ + ax + b) with ECDSA signatures.
9
10
```typescript { .api }
11
import { weierstrass, ecdsa, ecdh, weierstrassPoints } from "@noble/curves/abstract/weierstrass";
12
13
/**
14
* Creates a Weierstrass curve implementation from curve parameters
15
* @param c - Curve configuration including field, curve parameters, and options
16
* @returns Complete curve implementation with signing, verification, and point operations
17
*/
18
function weierstrass(c: CurveType): CurveFn;
19
20
/**
21
* Creates ECDSA signature implementation for a curve
22
* @param Point - Point constructor from curve implementation
23
* @param Hash - Hash function (must have blockLen and outputLen properties)
24
* @param opts - ECDSA options including lowS canonicalization
25
* @returns ECDSA interface with sign, verify, and key operations
26
*/
27
function ecdsa(
28
Point: WeierstrassPointCons<bigint>,
29
Hash: CHash,
30
opts?: ECDSAOpts
31
): ECDSA;
32
33
/**
34
* Creates ECDH key exchange implementation
35
* @param Point - Point constructor from curve implementation
36
* @param opts - ECDH options
37
* @returns ECDH interface with getSharedSecret
38
*/
39
function ecdh(Point: WeierstrassPointCons<bigint>, opts?: ECDHOpts): ECDH;
40
41
/**
42
* Creates point operations for Weierstrass curves
43
* @param c - Curve points configuration
44
* @returns Point constructor and utilities
45
*/
46
function weierstrassPoints<T>(c: CurvePointsTypeWithLength<T>): CurvePointsRes<T>;
47
48
/**
49
* Simplified SWU map-to-curve implementation
50
* @param Fp - Base field
51
* @param opts - SWU parameters (A, B, Z)
52
* @returns Function that maps field element to curve point
53
*/
54
function mapToCurveSimpleSWU<T>(
55
Fp: IField<T>,
56
opts: { A: T; B: T; Z: T }
57
): (u: T) => AffinePoint<T>;
58
59
/**
60
* Square root ratio for SWU mapping
61
* @param Fp - Base field
62
* @param Z - SWU parameter Z
63
* @returns Function computing sqrt(u/v) or indication if not square
64
*/
65
function SWUFpSqrtRatio<T>(
66
Fp: IField<T>,
67
Z: T
68
): (u: T, v: T) => { isValid: boolean; value: T };
69
```
70
71
#### Weierstrass Types
72
73
```typescript { .api }
74
interface CurveType {
75
p: bigint; // Base field modulus
76
n: bigint; // Curve order (number of points)
77
a: bigint; // Curve parameter a
78
b: bigint; // Curve parameter b
79
Gx: bigint; // Generator point x coordinate
80
Gy: bigint; // Generator point y coordinate
81
h?: bigint; // Cofactor (default 1)
82
Fp?: IField<bigint>; // Base field implementation
83
lowS?: boolean; // Canonical signature requirement
84
endo?: EndomorphismOpts; // GLV endomorphism for faster scalar multiplication
85
}
86
87
interface WeierstrassPoint<T> {
88
x: T;
89
y: T;
90
z: T; // Projective coordinate
91
92
add(other: WeierstrassPoint<T>): WeierstrassPoint<T>;
93
subtract(other: WeierstrassPoint<T>): WeierstrassPoint<T>;
94
multiply(scalar: bigint): WeierstrassPoint<T>;
95
multiplyUnsafe(scalar: bigint): WeierstrassPoint<T>;
96
negate(): WeierstrassPoint<T>;
97
double(): WeierstrassPoint<T>;
98
99
toAffine(): AffinePoint<T>;
100
toRawBytes(isCompressed?: boolean): Uint8Array;
101
toHex(isCompressed?: boolean): string;
102
103
equals(other: WeierstrassPoint<T>): boolean;
104
assertValidity(): void;
105
}
106
107
interface ECDSA {
108
sign(message: Hex, privateKey: PrivKey, opts?: ECDSASignOpts): ECDSASignature;
109
verify(signature: ECDSASignature, message: Hex, publicKey: Hex, opts?: ECDSAVerifyOpts): boolean;
110
getPublicKey(privateKey: PrivKey, isCompressed?: boolean): Uint8Array;
111
}
112
113
interface ECDH {
114
getSharedSecret(privateKeyA: PrivKey, publicKeyB: Hex, isCompressed?: boolean): Uint8Array;
115
}
116
117
interface ECDSASignature {
118
r: bigint;
119
s: bigint;
120
recovery?: number;
121
122
toCompactRawBytes(): Uint8Array;
123
toDERRawBytes(): Uint8Array;
124
toCompactHex(): string;
125
toDERHex(): string;
126
127
normalizeS(): ECDSASignature;
128
recoverPublicKey(message: Hex): WeierstrassPoint<bigint>;
129
}
130
```
131
132
### Edwards Curves
133
134
Abstract implementation for twisted Edwards curves (ax² + y² = 1 + dx²y²) with EdDSA signatures.
135
136
```typescript { .api }
137
import { twistedEdwards, edwards, eddsa } from "@noble/curves/abstract/edwards";
138
139
/**
140
* Creates a twisted Edwards curve implementation from curve parameters
141
* @param c - Curve configuration including field, curve parameters, and hash function
142
* @returns Complete curve implementation with signing, verification, and point operations
143
*/
144
function twistedEdwards(c: CurveTypeWithLength): CurveFn;
145
146
/**
147
* Creates Edwards curve point operations
148
* @param params - Edwards curve parameters (a, d, etc.)
149
* @param extraOpts - Additional options like hash function and precomputation
150
* @returns Edwards point constructor
151
*/
152
function edwards(params: EdwardsOpts, extraOpts?: EdwardsExtraOpts): EdwardsPointCons;
153
154
/**
155
* Creates EdDSA signature implementation for Edwards curves
156
* @param Point - Edwards point constructor
157
* @param cHash - Hash function for EdDSA
158
* @param eddsaOpts - EdDSA-specific options
159
* @returns EdDSA interface with sign, verify, and key operations
160
*/
161
function eddsa(
162
Point: EdwardsPointCons,
163
cHash: FHash,
164
eddsaOpts?: EdDSAOpts
165
): EdDSA;
166
```
167
168
#### Edwards Types
169
170
```typescript { .api }
171
interface CurveTypeWithLength {
172
p: bigint; // Base field modulus
173
n: bigint; // Curve order
174
a: bigint; // Curve parameter a
175
d: bigint; // Curve parameter d
176
Gx: bigint; // Generator point x coordinate
177
Gy: bigint; // Generator point y coordinate
178
h?: bigint; // Cofactor
179
hash: CHash; // Hash function for signatures
180
nByteLength?: number; // Byte length of scalar field
181
nBitLength?: number; // Bit length of scalar field
182
}
183
184
interface EdwardsPoint {
185
x: bigint;
186
y: bigint;
187
z: bigint;
188
t: bigint; // Extended coordinate t = xy/z
189
190
add(other: EdwardsPoint): EdwardsPoint;
191
subtract(other: EdwardsPoint): EdwardsPoint;
192
multiply(scalar: bigint): EdwardsPoint;
193
multiplyUnsafe(scalar: bigint): EdwardsPoint;
194
negate(): EdwardsPoint;
195
double(): EdwardsPoint;
196
197
toAffine(): AffinePoint<bigint>;
198
toRawBytes(): Uint8Array;
199
toHex(): string;
200
201
equals(other: EdwardsPoint): boolean;
202
assertValidity(): void;
203
}
204
205
interface EdDSA {
206
sign(message: Hex, privateKey: PrivKey, context?: Hex): Uint8Array;
207
verify(signature: Hex, message: Hex, publicKey: Hex, context?: Hex): boolean;
208
getPublicKey(privateKey: PrivKey): Uint8Array;
209
}
210
211
interface EdwardsOpts {
212
p: bigint; // Base field modulus
213
a: bigint; // Curve parameter a
214
d: bigint; // Curve parameter d
215
n: bigint; // Curve order
216
Gx: bigint; // Generator x coordinate
217
Gy: bigint; // Generator y coordinate
218
h?: bigint; // Cofactor
219
adjustScalarBytes?: (bytes: Uint8Array) => Uint8Array; // Scalar clamping function
220
}
221
```
222
223
### Modular Arithmetic
224
225
Field arithmetic operations and finite field implementations.
226
227
```typescript { .api }
228
import {
229
Field, mod, pow, pow2, invert, tonelliShanks, FpSqrt,
230
FpPow, FpInvertBatch, FpDiv, hashToPrivateScalar, mapHashToField
231
} from "@noble/curves/abstract/modular";
232
233
/**
234
* Creates a finite field implementation
235
* @param ORDER - Field modulus (prime number)
236
* @param opts - Field options including sqrt implementation
237
* @returns Field implementation with arithmetic operations
238
*/
239
function Field(
240
ORDER: bigint,
241
opts?: {
242
sqrt?: (n: bigint) => bigint;
243
isLE?: boolean;
244
}
245
): IField<bigint>;
246
247
/**
248
* Modular reduction: a mod b
249
* @param a - Number to reduce
250
* @param b - Modulus
251
* @returns a mod b, always positive
252
*/
253
function mod(a: bigint, b: bigint): bigint;
254
255
/**
256
* Modular exponentiation: num^power mod modulo
257
* @param num - Base
258
* @param power - Exponent
259
* @param modulo - Modulus
260
* @returns num^power mod modulo
261
*/
262
function pow(num: bigint, power: bigint, modulo: bigint): bigint;
263
264
/**
265
* Optimized modular exponentiation with precomputed powers
266
* @param x - Base
267
* @param power - Exponent
268
* @param modulo - Modulus
269
* @returns x^power mod modulo
270
*/
271
function pow2(x: bigint, power: bigint, modulo: bigint): bigint;
272
273
/**
274
* Modular multiplicative inverse using extended Euclidean algorithm
275
* @param number - Number to invert
276
* @param modulo - Modulus (must be prime)
277
* @returns number^(-1) mod modulo
278
*/
279
function invert(number: bigint, modulo: bigint): bigint;
280
281
/**
282
* Creates Tonelli-Shanks square root implementation
283
* @param P - Prime modulus
284
* @returns Function to compute square roots in field
285
*/
286
function tonelliShanks(P: bigint): <T>(Fp: IField<T>, n: T) => T;
287
288
/**
289
* Creates square root implementation for finite fields
290
* @param P - Prime modulus
291
* @returns Square root function
292
*/
293
function FpSqrt(P: bigint): <T>(Fp: IField<T>, n: T) => T;
294
295
/**
296
* Batch modular inversion using Montgomery's trick
297
* @param Fp - Field implementation
298
* @param nums - Array of field elements to invert
299
* @param passZero - Whether to pass zero elements unchanged
300
* @returns Array of inverted elements
301
*/
302
function FpInvertBatch<T>(Fp: IField<T>, nums: T[], passZero?: boolean): T[];
303
304
/**
305
* Hash arbitrary data to private scalar
306
* @param hash - Hash bytes
307
* @param groupOrder - Curve order
308
* @param isLE - Whether hash is little-endian
309
* @returns Private scalar in range [1, groupOrder-1]
310
*/
311
function hashToPrivateScalar(
312
hash: Uint8Array,
313
groupOrder: bigint,
314
isLE?: boolean
315
): bigint;
316
317
/**
318
* Map hash output to field element
319
* @param key - Hash bytes
320
* @param fieldOrder - Field modulus
321
* @param isLE - Whether to use little-endian interpretation
322
* @returns Field element
323
*/
324
function mapHashToField(key: Uint8Array, fieldOrder: bigint, isLE?: boolean): Uint8Array;
325
```
326
327
#### Modular Types
328
329
```typescript { .api }
330
interface IField<T> {
331
ORDER: bigint; // Field modulus
332
ZERO: T; // Additive identity
333
ONE: T; // Multiplicative identity
334
BYTES: number; // Byte length of field elements
335
BITS: number; // Bit length of field elements
336
MASK: bigint; // Bit mask for field elements
337
338
// Arithmetic operations
339
create(num: T): T;
340
add(a: T, b: T): T;
341
sub(a: T, b: T): T;
342
mul(a: T, b: T): T;
343
div(a: T, b: T): T;
344
pow(a: T, b: bigint): T;
345
inv(a: T): T;
346
neg(a: T): T;
347
sqr(a: T): T;
348
sqrt(a: T): T;
349
350
// Comparison and validation
351
eql(a: T, b: T): boolean;
352
isZero(a: T): boolean;
353
isOne(a: T): boolean;
354
isValid(a: T): boolean;
355
356
// Serialization
357
toBytes(a: T): Uint8Array;
358
fromBytes(bytes: Uint8Array): T;
359
}
360
361
interface NLength {
362
nByteLength: number;
363
nBitLength: number;
364
}
365
```
366
367
### Hash-to-Curve
368
369
Standardized methods for hashing arbitrary data to elliptic curve points.
370
371
```typescript { .api }
372
import {
373
createHasher, expand_message_xmd, expand_message_xof,
374
hash_to_field, isogenyMap
375
} from "@noble/curves/abstract/hash-to-curve";
376
377
/**
378
* Creates hash-to-curve hasher following RFC 9380
379
* @param Point - Curve point constructor
380
* @param mapToCurve - Map-to-curve function
381
* @param opts - Hash-to-curve options including DST and hash function
382
* @returns Hash-to-curve hasher with hashToCurve and encodeToCurve methods
383
*/
384
function createHasher<T>(
385
Point: H2CPointConstructor<T>,
386
mapToCurve: MapToCurve<T>,
387
opts: {
388
DST: string; // Domain separation tag
389
encodeDST?: string; // Encode domain separation tag
390
p: bigint; // Field modulus
391
m: number; // Field extension degree
392
k: number; // Security parameter
393
expand?: string; // Expand function ('xmd' or 'xof')
394
hash: CHash; // Hash function
395
}
396
): H2CHasher<T>;
397
398
/**
399
* Expand message using XMD (eXpand Message Domain)
400
* @param msg - Message to expand
401
* @param DST - Domain separation tag
402
* @param lenInBytes - Target length in bytes
403
* @param H - Hash function
404
* @returns Expanded message
405
*/
406
function expand_message_xmd(
407
msg: Uint8Array,
408
DST: Uint8Array,
409
lenInBytes: number,
410
H: CHash
411
): Uint8Array;
412
413
/**
414
* Expand message using XOF (eXtendable Output Function)
415
* @param msg - Message to expand
416
* @param DST - Domain separation tag
417
* @param lenInBytes - Target length in bytes
418
* @param k - Security parameter
419
* @param H - XOF function
420
* @returns Expanded message
421
*/
422
function expand_message_xof(
423
msg: Uint8Array,
424
DST: Uint8Array,
425
lenInBytes: number,
426
k: number,
427
H: any
428
): Uint8Array;
429
430
/**
431
* Hash message to field elements
432
* @param msg - Message bytes
433
* @param count - Number of field elements to produce
434
* @param options - Hash-to-field options
435
* @returns Array of field element arrays
436
*/
437
function hash_to_field(
438
msg: Uint8Array,
439
count: number,
440
options: {
441
DST: string;
442
p: bigint;
443
m: number;
444
k: number;
445
expand?: string;
446
hash: CHash;
447
}
448
): bigint[][];
449
450
/**
451
* Creates isogeny map for hash-to-curve
452
* @param field - Base field
453
* @param map - Isogeny rational map coefficients [xNum, xDen, yNum, yDen]
454
* @returns Isogeny mapping function
455
*/
456
function isogenyMap<T, F extends IField<T>>(
457
field: F,
458
map: [T[], T[], T[], T[]]
459
): (x: T, y: T) => { x: T; y: T };
460
```
461
462
#### Hash-to-Curve Types
463
464
```typescript { .api }
465
interface H2CHasher<T> {
466
hashToCurve(msg: Uint8Array, options?: { DST?: string }): H2CPoint<T>;
467
encodeToCurve(msg: Uint8Array, options?: { DST?: string }): H2CPoint<T>;
468
}
469
470
interface H2CPoint<T> {
471
toAffine(): AffinePoint<T>;
472
add(other: H2CPoint<T>): H2CPoint<T>;
473
multiply(scalar: bigint): H2CPoint<T>;
474
equals(other: H2CPoint<T>): boolean;
475
}
476
477
type MapToCurve<T> = (scalar: bigint[]) => AffinePoint<T>;
478
type H2CMethod<T> = (msg: Uint8Array, options?: { DST?: string }) => H2CPoint<T>;
479
480
interface AffinePoint<T> {
481
x: T;
482
y: T;
483
}
484
```
485
486
### Additional Abstract Modules
487
488
#### BLS Signatures
489
490
```typescript { .api }
491
import { bls } from "@noble/curves/abstract/bls";
492
493
/**
494
* Creates BLS signature implementation for pairing-friendly curves
495
* @param CURVE - BLS curve configuration with G1, G2, GT, and pairing
496
* @returns BLS signature interface with aggregation support
497
*/
498
function bls<T>(CURVE: BLSOpts<T>): BLSCurveFn;
499
500
interface BLSCurveFn {
501
sign(message: Hex, privateKey: PrivKey): Uint8Array;
502
verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
503
aggregatePublicKeys(publicKeys: Hex[]): Uint8Array;
504
aggregateSignatures(signatures: Hex[]): Uint8Array;
505
verifyBatch(signature: Hex, messages: Hex[], publicKeys: Hex[]): boolean;
506
getPublicKey(privateKey: PrivKey): Uint8Array;
507
}
508
```
509
510
#### Montgomery Curves
511
512
```typescript { .api }
513
import { montgomery } from "@noble/curves/abstract/montgomery";
514
515
/**
516
* Creates Montgomery curve implementation for key exchange
517
* @param opts - Montgomery curve parameters
518
* @returns Montgomery curve with key exchange operations
519
*/
520
function montgomery(opts: MontgomeryOpts): MontgomeryCurveFn;
521
522
interface MontgomeryCurveFn {
523
getPublicKey(privateKey: PrivKey): Uint8Array;
524
getSharedSecret(privateKey: PrivKey, publicKey: Hex): Uint8Array;
525
utils: {
526
randomPrivateKey(): Uint8Array;
527
};
528
}
529
```
530
531
### Tower Fields
532
533
Extension field operations for pairing-friendly curves, enabling efficient computation over Fp2, Fp6, and Fp12.
534
535
```typescript { .api }
536
import { tower12 } from "@noble/curves/abstract/tower";
537
538
/**
539
* Creates tower field operations for BLS-style pairing curves
540
* @param opts - Tower field configuration including base field and extension parameters
541
* @returns Field operations for Fp2, Fp6, and Fp12 extensions
542
*/
543
function tower12(opts: Tower12Opts): {
544
Fp2: Fp2Bls;
545
Fp6: Fp6Bls;
546
Fp12: Fp12Bls;
547
psiFrobenius(x: Fp2): Fp2;
548
};
549
550
type Fp2 = { c0: bigint; c1: bigint };
551
type Fp6 = { c0: Fp2; c1: Fp2; c2: Fp2 };
552
type Fp12 = { c0: Fp6; c1: Fp6 };
553
```
554
555
### Poseidon Hash
556
557
Algebraic hash function designed for zero-knowledge proof systems with efficient circuit representation.
558
559
```typescript { .api }
560
import { poseidon, poseidonSponge } from "@noble/curves/abstract/poseidon";
561
562
/**
563
* Creates Poseidon hash function
564
* @param opts - Poseidon configuration including field size, rounds, and constants
565
* @returns Poseidon hash function instance
566
*/
567
function poseidon(opts: PoseidonOpts): PoseidonFn;
568
569
/**
570
* Creates Poseidon sponge construction for variable-length input
571
* @param opts - Sponge configuration parameters
572
* @returns Factory function for Poseidon sponge instances
573
*/
574
function poseidonSponge(opts: PoseidonSpongeOpts): () => PoseidonSponge;
575
576
interface PoseidonFn {
577
(inputs: bigint[]): bigint;
578
m: number;
579
roundConstants: bigint[][];
580
}
581
```
582
583
### Fast Fourier Transform
584
585
Polynomial operations and number-theoretic transforms for efficient computation in cryptographic protocols, including FFT/NTT, polynomial arithmetic, and roots of unity generation.
586
587
```typescript { .api }
588
import { FFT, poly, rootsOfUnity } from "@noble/curves/abstract/fft";
589
590
/**
591
* Creates FFT/NTT operations for polynomial arithmetic
592
* @param roots - Roots of unity for the transformation
593
* @param opts - FFT configuration options including field operations
594
* @returns FFT transformation methods for direct and inverse transforms
595
*/
596
function FFT<T>(roots: RootsOfUnity, opts: FFTOpts<T, bigint>): FFTMethods<T>;
597
598
/**
599
* Creates comprehensive polynomial operations over a field
600
* @param field - Field operations for polynomial coefficients
601
* @param roots - Roots of unity for FFT-based operations
602
* @param create - Function to create polynomial instances
603
* @param fft - Optional pre-computed FFT methods
604
* @param length - Default polynomial length
605
* @returns Complete polynomial arithmetic suite
606
*/
607
function poly<T, P extends Polynomial<T>>(
608
field: IField<T>,
609
roots: RootsOfUnity,
610
create?: CreatePolyFn<P, T>,
611
fft?: FFTMethods<T>,
612
length?: number
613
): PolyFn<P, T>;
614
615
/**
616
* Generates roots of unity for FFT operations
617
* @param field - Field operations (must have primitive root)
618
* @param generator - Optional primitive root generator
619
* @returns Cached roots of unity and bit-reversal permutation utilities
620
*/
621
function rootsOfUnity(field: IField<bigint>, generator?: bigint): RootsOfUnity;
622
623
// Core FFT interfaces
624
interface FFTMethods<T> {
625
/** Forward FFT: time domain to frequency domain */
626
direct<P extends Polynomial<T>>(values: P, brpInput?: boolean, brpOutput?: boolean): P;
627
/** Inverse FFT: frequency domain to time domain */
628
inverse<P extends Polynomial<T>>(values: P, brpInput?: boolean, brpOutput?: boolean): P;
629
}
630
631
interface RootsOfUnity {
632
/** Get roots of unity for given bit size */
633
roots(bits: number): bigint[];
634
/** Get bit-reversal permutation indices */
635
brp(bits: number): bigint[];
636
/** Get inverse roots of unity */
637
inverse(bits: number): bigint[];
638
/** Get primitive root for given bit size */
639
omega(bits: number): bigint;
640
/** Clear cached values */
641
clear(): void;
642
}
643
644
// Polynomial operations
645
interface PolyFn<P extends Polynomial<T>, T> {
646
/** Create zero polynomial */
647
ZERO: P;
648
/** Create polynomial from coefficients */
649
fromCoeffs(coeffs: T[]): P;
650
/** Create polynomial from evaluations */
651
fromEvals(evals: T[]): P;
652
653
/** Add two polynomials */
654
add(a: P, b: P): P;
655
/** Subtract two polynomials */
656
sub(a: P, b: P): P;
657
/** Multiply two polynomials (FFT-accelerated) */
658
mul(a: P, b: P): P;
659
/** Multiply polynomial by scalar */
660
scale(a: P, scalar: T): P;
661
/** Compute polynomial division with quotient and remainder */
662
divmod(a: P, b: P): { quotient: P; remainder: P };
663
664
/** Evaluate polynomial at point */
665
eval(poly: P, point: T): T;
666
/** Multi-point evaluation */
667
evalMany(poly: P, points: T[]): T[];
668
/** Polynomial interpolation from points */
669
interpolate(points: Array<{ x: T; y: T }>): P;
670
671
/** Convert between coefficient and evaluation representations */
672
toCoeffs(poly: P): T[];
673
toEvals(poly: P): T[];
674
675
/** FFT-based operations */
676
fft: FFTMethods<T>;
677
}
678
679
// Configuration types
680
interface FFTOpts<T, F> {
681
/** Field for polynomial coefficients */
682
field: IField<F>;
683
/** Function to create polynomial from array */
684
create: CreatePolyFn<Polynomial<T>, T>;
685
/** Optional custom multiplication for performance */
686
mul?: (a: T, b: F) => T;
687
/** Optional custom addition for performance */
688
add?: (a: T, b: T) => T;
689
/** Optional custom zero element */
690
zero?: () => T;
691
}
692
693
interface Polynomial<T> extends MutableArrayLike<T> {
694
[index: number]: T;
695
length: number;
696
slice(start?: number, end?: number): this;
697
}
698
699
interface MutableArrayLike<T> {
700
[index: number]: T;
701
length: number;
702
}
703
704
type CreatePolyFn<P, T> = (values: T[]) => P;
705
```
706
707
**FFT Usage Examples:**
708
709
```typescript
710
import { FFT, poly, rootsOfUnity } from "@noble/curves/abstract/fft";
711
import { Field } from "@noble/curves/abstract/modular";
712
713
// Create field for polynomial coefficients
714
const Fp = Field(2n ** 255n - 19n); // Ed25519 field
715
716
// Generate roots of unity for FFT
717
const roots = rootsOfUnity(Fp);
718
719
// Create FFT operations
720
const fft = FFT(roots, {
721
field: Fp,
722
create: (values) => new Uint8Array(values.map(v => Number(v))),
723
});
724
725
// Create polynomial operations with FFT acceleration
726
const polynomial = poly(Fp, roots, (coeffs) => new BigUint64Array(coeffs));
727
728
// Polynomial arithmetic
729
const p1 = polynomial.fromCoeffs([1n, 2n, 3n]); // 3x² + 2x + 1
730
const p2 = polynomial.fromCoeffs([4n, 5n]); // 5x + 4
731
732
const sum = polynomial.add(p1, p2); // 3x² + 7x + 5
733
const product = polynomial.mul(p1, p2); // FFT-accelerated multiplication
734
735
// Evaluation and interpolation
736
const result = polynomial.eval(p1, 10n); // Evaluate at x = 10
737
const points = [
738
{ x: 1n, y: 6n },
739
{ x: 2n, y: 17n },
740
{ x: 3n, y: 34n }
741
];
742
const interpolated = polynomial.interpolate(points);
743
```
744
745
**Use Cases:**
746
- **Zero-Knowledge Proofs**: Polynomial commitments and proof systems (PLONK, STARK)
747
- **Error Correction**: Reed-Solomon codes and polynomial-based error correction
748
- **Cryptographic Protocols**: Polynomial secret sharing, threshold cryptography
749
- **Signal Processing**: Convolution, correlation, and digital signal processing
750
- **Homomorphic Encryption**: Polynomial arithmetic for encrypted computation
751
- **Multivariate Cryptography**: Polynomial system solving and Gröbner bases
752
753
### Oblivious Pseudorandom Functions (OPRF)
754
755
RFC 9497 implementation of Oblivious Pseudorandom Functions supporting OPRF, VOPRF, and POPRF modes for privacy-preserving protocols.
756
757
```typescript { .api }
758
import { createORPF } from "@noble/curves/abstract/oprf";
759
760
/**
761
* Creates OPRF implementation for a specific curve and hash function
762
* @param opts - OPRF configuration including curve, hash, and domain separation
763
* @returns Complete OPRF suite with three protocol variants
764
*/
765
function createORPF<P extends CurvePoint<any, P>>(opts: OPRFOpts<P>): OPRF;
766
767
/**
768
* OPRF suite providing three protocol variants
769
*/
770
interface OPRF {
771
readonly name: string; // Ciphersuite identifier
772
773
// Base OPRF mode (mode 0x00) - simple, non-verifiable
774
readonly oprf: {
775
generateKeyPair(): OPRFKeys;
776
deriveKeyPair(seed: Bytes, keyInfo: Bytes): OPRFKeys;
777
blind(input: Bytes, rng?: RNG): OPRFBlind;
778
blindEvaluate(secretKey: ScalarBytes, blinded: PointBytes): PointBytes;
779
finalize(input: Bytes, blind: ScalarBytes, evaluated: PointBytes): Bytes;
780
};
781
782
// Verifiable OPRF mode (mode 0x01) - includes proofs
783
readonly voprf: {
784
generateKeyPair(): OPRFKeys;
785
deriveKeyPair(seed: Bytes, keyInfo: Bytes): OPRFKeys;
786
blind(input: Bytes, rng?: RNG): OPRFBlind;
787
blindEvaluate(secretKey: ScalarBytes, publicKey: PointBytes, blinded: PointBytes, rng?: RNG): OPRFBlindEval;
788
blindEvaluateBatch(secretKey: ScalarBytes, publicKey: PointBytes, blinded: PointBytes[], rng?: RNG): OPRFBlindEvalBatch;
789
finalize(input: Bytes, blind: ScalarBytes, evaluated: PointBytes, blinded: PointBytes, publicKey: PointBytes, proof: Bytes): Bytes;
790
finalizeBatch(items: OPRFFinalizeItem[], publicKey: PointBytes, proof: Bytes): Bytes[];
791
};
792
793
// Partially Oblivious PRF mode (mode 0x02) - includes domain separation
794
readonly poprf: (info: Bytes) => {
795
generateKeyPair(): OPRFKeys;
796
deriveKeyPair(seed: Bytes, keyInfo: Bytes): OPRFKeys;
797
blind(input: Bytes, publicKey: PointBytes, rng?: RNG): OPRFBlind & { tweakedKey: PointBytes };
798
blindEvaluate(secretKey: ScalarBytes, blinded: PointBytes, rng?: RNG): OPRFBlindEval;
799
blindEvaluateBatch(secretKey: ScalarBytes, blinded: PointBytes[], rng: RNG): OPRFBlindEvalBatch;
800
finalize(input: Bytes, blind: ScalarBytes, evaluated: PointBytes, blinded: PointBytes, proof: Bytes, tweakedKey: PointBytes): Bytes;
801
finalizeBatch(items: OPRFFinalizeItem[], proof: Bytes, tweakedKey: PointBytes): Bytes[];
802
};
803
}
804
805
// OPRF configuration
806
interface OPRFOpts<P extends CurvePoint<any, P>> {
807
name: string; // Ciphersuite name
808
Point: CurvePointCons<P>; // Curve point constructor
809
hash: (msg: Bytes) => Bytes; // Hash function
810
hashToScalar: (msg: Uint8Array, options: htfBasicOpts) => bigint; // Hash-to-scalar
811
hashToGroup: ((msg: Uint8Array, options: htfBasicOpts) => P) | H2CMethod<P>; // Hash-to-curve
812
}
813
814
// OPRF data types
815
interface OPRFKeys {
816
secretKey: ScalarBytes;
817
publicKey: PointBytes;
818
}
819
820
interface OPRFBlind {
821
blind: Uint8Array; // Secret blinding scalar
822
blinded: Uint8Array; // Blinded group element to send to server
823
}
824
825
interface OPRFBlindEval {
826
evaluated: PointBytes; // Server's evaluation result
827
proof: Bytes; // DLEQ proof of correct evaluation
828
}
829
830
interface OPRFBlindEvalBatch {
831
evaluated: PointBytes[]; // Batch evaluation results
832
proof: Bytes; // Single proof for entire batch
833
}
834
835
interface OPRFFinalizeItem {
836
input: Bytes;
837
blind: ScalarBytes;
838
evaluated: PointBytes;
839
blinded: PointBytes;
840
}
841
842
type PointBytes = Uint8Array;
843
type ScalarBytes = Uint8Array;
844
type Bytes = Uint8Array;
845
type RNG = typeof randomBytes;
846
```
847
848
**OPRF Protocol Flow:**
849
850
```typescript
851
import { createORPF } from "@noble/curves/abstract/oprf";
852
import { ristretto255 } from "@noble/curves/ed25519";
853
import { sha512 } from "@noble/hashes/sha512";
854
855
// Create OPRF suite for Ristretto255 + SHA-512
856
const oprf = createORPF({
857
name: "ristretto255-SHA512",
858
Point: ristretto255.Point,
859
hash: sha512,
860
hashToScalar: ristretto255.hashToScalar,
861
hashToGroup: ristretto255.hashToCurve
862
});
863
864
// Server: Generate key pair
865
const serverKeys = oprf.voprf.generateKeyPair();
866
867
// Client: Blind input
868
const input = new TextEncoder().encode("secret-input");
869
const { blind, blinded } = oprf.voprf.blind(input);
870
871
// Server: Evaluate blinded input with proof
872
const { evaluated, proof } = oprf.voprf.blindEvaluate(
873
serverKeys.secretKey,
874
serverKeys.publicKey,
875
blinded
876
);
877
878
// Client: Finalize to get OPRF output
879
const output = oprf.voprf.finalize(
880
input,
881
blind,
882
evaluated,
883
blinded,
884
serverKeys.publicKey,
885
proof
886
);
887
```
888
889
**Use Cases:**
890
- **Password-Authenticated Key Exchange (PAKE)**: Secure password login without revealing passwords
891
- **Private Set Intersection (PSI)**: Compute set intersections while preserving privacy
892
- **Anonymous Credentials**: Issue unlinkable credentials for Privacy Pass systems
893
- **Private Information Retrieval (PIR)**: Query databases without revealing accessed items
894
- **Encrypted Search**: Enable keyword search over encrypted data with private queries
895
- **Spam Prevention**: Issue anonymous tokens for rate-limiting and abuse prevention
896
897
### Base Curve Abstractions
898
899
Core abstractions and interfaces for elliptic curve implementations, providing foundational types and multi-scalar multiplication.
900
901
```typescript { .api }
902
import { Group, GroupCons, CurvePoint, pippenger } from "@noble/curves/abstract/curve";
903
904
// Base group interface for algebraic structures
905
interface Group<T extends Group<T>> {
906
double(): T;
907
negate(): T;
908
add(other: T): T;
909
subtract(other: T): T;
910
equals(other: T): boolean;
911
multiply(scalar: bigint): T;
912
}
913
914
// Group constructor interface
915
interface GroupCons<T extends Group<T>> {
916
ZERO: T;
917
BASE: T;
918
fromBytes(bytes: Uint8Array): T;
919
fromHex(hex: string): T;
920
}
921
922
// Curve point interface extending Group
923
interface CurvePoint<U, T extends CurvePoint<U, T> = CurvePoint<U, any>> extends Group<T> {
924
readonly Fp: IField<U>;
925
readonly Fn: IField<bigint>;
926
x: U;
927
y: U;
928
is0(): boolean;
929
toBytes(isCompressed?: boolean): Uint8Array;
930
toHex(isCompressed?: boolean): string;
931
toRawBytes(isCompressed?: boolean): Uint8Array;
932
assertValidity(): void;
933
}
934
935
/**
936
* Multi-scalar multiplication using Pippenger's algorithm
937
* @param Point - Group constructor
938
* @param Fn - Scalar field
939
* @param points - Array of points to multiply
940
* @param scalars - Array of scalars for multiplication
941
* @returns Result of sum(points[i] * scalars[i])
942
*/
943
function pippenger<T extends Group<T>>(
944
Point: GroupCons<T>,
945
Fn: IField<bigint>,
946
points: T[],
947
scalars: bigint[]
948
): T;
949
```