-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathgalois.d.ts
453 lines (349 loc) · 17.5 KB
/
galois.d.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
declare module '@guildofweavers/galois' {
/** Polynomial represented in reverse-coefficient form */
export type Polynom = Vector;
export interface WasmOptions {
readonly memory: WebAssembly.Memory;
}
export interface FiniteField {
/** Characteristic of the field: p in GF(p**n) */
readonly characteristic: bigint;
/** Extension of the field: n in GF(p**n) */
readonly extensionDegree: number;
/** Non-optimized version of the field object */
readonly jsField: FiniteField;
/** A flag indicating whether the field uses WebAssembly optimization */
readonly isOptimized: boolean;
/** Size of a field element in bytes */
readonly elementSize: number;
/** Additive identity of the field */
readonly zero: bigint;
/** Multiplicative identity of the field */
readonly one: bigint;
isElement(value: bigint): boolean;
// BASIC ARITHMETICS
// ----------------------------------------------------------------------------------------
/**
* Computes x + y
* @param x Field element
* @param y Field element
*/
add(x: bigint, y: bigint): bigint;
/**
* Computes x - y
* @param x Field element
* @param y Field element
*/
sub(x: bigint, y: bigint): bigint;
/**
* Computes x * y
* @param x Field element
* @param y Field element
*/
mul(x: bigint, y: bigint): bigint;
/**
* Computes x * inv(y)
* @param x Field element
* @param y Field element
*/
div(x: bigint, y: bigint): bigint;
/**
* Computes b**p
* @param b Field element to exponentiate
* @param p Exponent, a positive or a negative number
*/
exp(b: bigint, p: bigint): bigint;
/**
* Computes modular multiplicative inverse using Extended Euclidean algorithm
* @param value Field element to invert
*/
inv(value: bigint): bigint;
/**
* Computes modular additive inverse
* @param value Filed element to negate
*/
neg(value: bigint): bigint;
// VECTOR OPERATIONS
// ----------------------------------------------------------------------------------------
/** Creates a new vector of the specified length */
newVector(length: number): Vector;
/** Creates a new vector from the specified array of values */
newVectorFrom(values: bigint[]): Vector;
/** Computes a new vector v such that v[i] = a[i] + b[i] for all i */
addVectorElements(a: Vector, b: Vector): Vector;
/** Computes a new vector v such that v[i] = a[i] + b for all i */
addVectorElements(a: Vector, b: bigint): Vector;
/** Computes a new vector v such that v[i] = a[i] - b[i] for all i */
subVectorElements(a: Vector, b: Vector): Vector;
/** Computes a new vector v such that v[i] = a[i] - b for all i */
subVectorElements(a: Vector, b: bigint): Vector;
/** Computes a new vector v such that v[i] = a[i] * b[i] for all i */
mulVectorElements(a: Vector, b: Vector): Vector;
/** Computes a new vector v such that v[i] = a[i] * b for all i */
mulVectorElements(a: Vector, b: bigint): Vector;
/** Computes a new vector v such that v[i] = a[i] * inv(b[i]) for all i */
divVectorElements(a: Vector, b: Vector): Vector;
/** Computes a new vector v such that v[i] = a[i] * inv(b) for all i */
divVectorElements(a: Vector, b: bigint): Vector;
/** Computes a new vector v such that v[i] = a[i]^b[i] for all i */
expVectorElements(a: Vector, b: Vector): Vector;
/** Computes a new vector v such that v[i] = a[i]^b for all i */
expVectorElements(a: Vector, b: bigint): Vector;
/** Computes multiplicative inverse for all vector elements using Montgomery batch inversion */
invVectorElements(v: Vector): Vector;
/** Computes additive inverse for all vector elements */
negVectorElements(v: Vector): Vector;
/** Computes a linear combination of two vectors */
combineVectors(a: Vector, b: Vector): bigint;
/** Computes a linear combination as sum(v[i][j]*k[i]) for each row i */
combineManyVectors(v: Vector[], k: Vector): Vector;
/**
* Creates a new vector by selecting values from the source vector by skipping over the specified number of elements
* @param v Source vector
* @param skip Number of elements to skip before selecting the next value
* @param times Number of times to pluck the source vector
*/
pluckVector(v: Vector, skip: number, times: number): Vector;
/** Creates a new vector with the length truncated to the specified value */
truncateVector(v: Vector, newLength: number): Vector;
/** Creates a copy of a vector that represents the source vector duplicated the specified number of times */
duplicateVector(v: Vector, times?: number): Vector;
/** Creates a new vector with the elements rotated by the specified number of slots */
rotateVector(v: Vector, slots: number): Vector;
/** Transposes the provided vector into a matrix with the specified number of columns */
transposeVector(v: Vector, columns: number, step?: number): Matrix;
/** Splits the provided vector into the a matrix with the specified number of rows */
splitVector(v: Vector, rows: number): Matrix;
// MATRIX OPERATIONS
// ----------------------------------------------------------------------------------------
/** Creates a new matrix with the specified number of rows and columns */
newMatrix(rows: number, columns: number): Matrix;
/** creates a new matrix from the specified 2-dimensional array of values */
newMatrixFrom(values: bigint[][]): Matrix;
/** Creates a new matrix using provided vectors as matrix rows */
newMatrixFromVectors(v: Vector[]): Matrix;
/** Computes a new matrix m such that m[i,j] = a[i,j] + b[i,j] for all i and j */
addMatrixElements(a: Matrix, b: Matrix): Matrix;
/** Computes a new matrix m such that m[i,j] = a[i,j] + b for all i and j */
addMatrixElements(a: Matrix, b: bigint): Matrix;
/** Computes a new matrix m such that m[i,j] = a[i,j] - b[i,j] for all i and j */
subMatrixElements(a: Matrix, b: Matrix): Matrix;
/** Computes a new matrix m such that m[i,j] = a[i,j] - b for all i and j */
subMatrixElements(a: Matrix, b: bigint): Matrix;
/** Computes a new matrix m such that m[i,j] = a[i,j] * b[i,j] for all i and j */
mulMatrixElements(a: Matrix, b: Matrix): Matrix;
/** Computes a new matrix m such that m[i,j] = a[i,j] * b for all i and j */
mulMatrixElements(a: Matrix, b: bigint): Matrix;
/** Computes a new matrix m such that m[i,j] = a[i,j] * inv(b[i,j]) for all i and j */
divMatrixElements(a: Matrix, b: Matrix): Matrix;
/** Computes a new matrix m such that m[i,j] = a[i,j] * inv(b) for all i and j */
divMatrixElements(a: Matrix, b: bigint): Matrix;
/** Computes a new matrix m such that m[i,j] = a[i,j]^b[i,j] for all i and j */
expMatrixElements(a: Matrix, b: Matrix): Matrix;
/** Computes a new matrix m such that m[i,j] = a[i,j]^b for all i and j */
expMatrixElements(a: Matrix, b: bigint): Matrix;
/** Computes multiplicative inverse for all matrix elements using Montgomery batch inversion */
invMatrixElements(m: Matrix): Matrix;
/** Computes additive inverse for all matrix elements */
negMatrixElements(v: Matrix): Matrix;
/**
* Computes a matrix with dimensions [m,n] which is a product of matrixes a and b
* @param a Matrix with dimensions [m,p]
* @param b Matrix with dimensions [p,n]
*/
mulMatrixes(a: Matrix, b: Matrix): Matrix;
/**
* Computes a vector of length m which is a product of matrix a and vector b
* @param m Matrix with dimensions [m,n]
* @param v Vector of length n
*/
mulMatrixByVector(m: Matrix, v: Vector): Vector;
/** Computes a new matrix n such that n[i,j] = m[i,j] * v[i] for all i and j */
mulMatrixRows(m: Matrix, v: Vector): Matrix;
/** Computes a new matrix n such that n[i,j] = v[i][j] - m[i,j] */
subMatrixElementsFromVectors(v: Vector[], m: Matrix): Matrix;
/** Returns an array of vectors corresponding to the matrixes' rows */
matrixRowsToVectors(m: Matrix): Vector[];
/** Returns a vector which represents a concatenation of the matrix's rows */
joinMatrixRows(m: Matrix): Vector;
/** Returns a new matrix which is a transpose of the provided matrix */
transposeMatrix(m: Matrix): Matrix;
// RANDOMNESS
// ----------------------------------------------------------------------------------------
/**
* Generate a cryptographically-secure random field element
*/
rand(): bigint;
/**
* Generates a sequence of pseudorandom field elements from the provided seed
* @param seed Seed for the PRNG
* @param length Length of sequence to generate
*/
prng(seed: bigint | Buffer, length: number): Vector;
/**
* Generates a single pseudorandom field element from the provided seed
* @param seed Seed for the PRNG
*/
prng(seed: bigint | Buffer): bigint;
// OTHER OPERATIONS
// ----------------------------------------------------------------------------------------
/**
* Computes a primitive root of unity such that root**order=1
* @param order Order of the root of unity
*/
getRootOfUnity(order: number): bigint;
/**
* Computes a series of powers for the provided base element
* @param base Field element to exponentiate
* @param length Length of the series to return
*/
getPowerSeries(base: bigint, length: number): Vector;
// BASIC POLYNOMIAL OPERATIONS
// ----------------------------------------------------------------------------------------
/**
* Computes a[i] + b[i] for all i
* @param a Polynomial
* @param b Polynomial
*/
addPolys(a: Polynom, b: Polynom): Polynom;
/**
* Computes a[i] - b[i] for all i
* @param a Polynomial
* @param b Polynomial
*/
subPolys(a: Polynom, b: Polynom): Polynom;
/**
* Computes a[i] * b[i] at all i
* @param a Polynomial
* @param b Polynomial
*/
mulPolys(a: Polynom, b: Polynom): Polynom;
/**
* Computes a[i] * inv(b[i]) for all i
* @param a Polynomial
* @param b Polynomial
*/
divPolys(a: Polynom, b: Polynom): Polynom;
/**
* Computes p[i] * c for all i
* @param p Polynomial to multiply
* @param c Constant
*/
mulPolyByConstant(p: Polynom, c: bigint): Polynom;
// POLYNOMIAL EVALUATION
// ----------------------------------------------------------------------------------------
/**
* Evaluates a polynomial at a provided x coordinates
* @param p Polynomial to evaluate
* @param x X coordinate at which to evaluate the polynomial
*/
evalPolyAt(p: Vector, x: bigint): bigint;
/**
* Uses Fast Fourier Transform to evaluate a set of polynomials at all provided roots of unity
* @param p Polynomials to evaluate
* @param rootsOfUnity Roots of unity representing x coordinates to evaluate
*/
evalPolyAtRoots(p: Vector, rootsOfUnity: Vector): Vector;
/**
* Uses Fast Fourier Transform to evaluate a polynomial at all provided roots of unity
* @param p A matrix where each row contains a polynomial to evaluate
* @param rootsOfUnity Roots of unity representing x coordinates to evaluate
*/
evalPolysAtRoots(p: Matrix, rootsOfUnity: Vector): Matrix;
/**
* Evaluates a set of degree 3 polynomials at the provided x coordinate
* @param polys A matrix where each row is a degree 3 polynomial (4 values per row)
* @param x X coordinate at which to evaluate the polynomials
*/
evalQuarticBatch(polys: Matrix, x: bigint): Vector;
/**
* Evaluates a set of degree 3 polynomials at provided x coordinates
* @param polys A matrix where each row is a degree 3 polynomial (4 values per row)
* @param xs A vector of x coordinates to evaluate
*/
evalQuarticBatch(polys: Matrix, xs: Vector): Vector;
// POLYNOMIAL INTERPOLATION
// ----------------------------------------------------------------------------------------
/**
* Uses Lagrange Interpolation to compute a polynomial from provided points
* @param xs x coordinates of points
* @param ys y coordinates of points
*/
interpolate(xs: Vector, ys: Vector): Vector;
/**
* Uses Fast Fourier Transform to compute a polynomial from provided points
* @param rootsOfUnity Roots of unity representing x coordinates of points to interpolate
* @param ys y coordinates of points to interpolate
*/
interpolateRoots(rootsOfUnity: Vector, ys: Vector): Vector;
/**
* Uses Fast Fourier Transform to compute polynomials from provided points
* @param rootsOfUnity Roots of unity representing x coordinates of points to interpolate
* @param ys A matrix with each row representing y coordinates of points to interpolate
*/
interpolateRoots(rootsOfUnity: Vector, ySets: Matrix): Matrix;
/**
* Uses an optimized version of Lagrange Interpolation for degree 3 polynomials
* @param xSets A matrix of X coordinates (4 values per row)
* @param ySets A matrix of Y coordinates (4 values per row)
*/
interpolateQuarticBatch(xSets: Matrix, ySets: Matrix): Matrix;
}
// DATA TYPES
// ----------------------------------------------------------------------------------------
export interface Vector {
readonly length : number;
readonly byteLength : number;
readonly elementSize: number;
/** Returns the element located at the specified index */
getValue(index: number): bigint;
/**
* Copies a vector element (in little-endian form) into the destination buffer
* @param index Index at which the element is located
* @param destination Buffer into which the element should be copied
* @param offset Byte offset in the destination buffer at which to copy the element
* @returns Number of bytes written to the destination buffer
*/
copyValue(index: number, destination: Buffer, offset: number): number;
/** Returns contents of the vector as a BigInt array */
toValues(): bigint[];
/** Serializes vector elements into a single buffer */
toBuffer(startIdx?: number, elementCount?: number): Buffer;
}
export interface Matrix {
readonly rowCount : number;
readonly colCount : number;
readonly byteLength : number;
readonly elementSize: number;
/** Returns the element located at the specified row and column */
getValue(row: number, column: number): bigint;
/**
* Copies a matrix element (in little-endian form) into the destination buffer
* @param row Row index at which the element is located
* @param column Column index at which the element is located
* @param destination Buffer into which the element should be copied
* @param offset Byte offset in the destination buffer at which to copy the element
* @returns Number of bytes written to the destination buffer
*/
copyValue(row: number, column: number, destination: Buffer, offset: number): number;
/** Returns contents of the matrix as a 2-dimensional BigInt array */
toValues(): bigint[][];
/** Serializes matrix elements into a single buffer (in row-major form) */
toBuffer(): Buffer;
/** Serializes matrix rows into an array of buffers (one buffer per row) */
rowsToBuffers(indexes?: number[]): Buffer[];
}
// GLOBAL FUNCTIONS
// ----------------------------------------------------------------------------------------
/**
* Creates a prime field for the specified modulus. If useWasm is set to true, will try to
* instantiate a WebAssembly-optimized version of the field. If WASM optimization is not
* available for the specified modulus, will create a regular JavaScript-based field.
*/
export function createPrimeField(modulus: bigint, useWasm?: boolean): FiniteField
/**
* Tries to create a WebAssembly-optimized prime field for the specified modulus and pass the
* provided options to it. If WASM optimization is not available for the specified modulus,
* will create a regular JavaScript-based field.
*/
export function createPrimeField(modulus: bigint, options?: Partial<WasmOptions>): FiniteField
}