functionalscript 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/com/cpp/module.f.mjs +10 -1
- package/com/cs/module.f.mjs +11 -1
- package/com/rust/module.f.mjs +13 -1
- package/dev/module.mjs +1 -1
- package/issues/lang/3370-type-inference.md +69 -0
- package/issues/lang/3380-promise.md +22 -0
- package/issues/lang/3390-class.md +3 -0
- package/issues/lang/README.md +79 -8
- package/jsr.json +60 -59
- package/out/com/cpp/module.f.d.mts +4 -1
- package/out/com/cpp/module.f.mjs +8 -1
- package/out/com/cs/module.f.d.mts +4 -1
- package/out/com/cs/module.f.mjs +10 -1
- package/out/com/rust/module.f.d.mts +1 -2
- package/out/com/rust/module.f.mjs +12 -1
- package/out/dev/module.mjs +1 -1
- package/out/prime_field/module.f.d.mts +28 -2
- package/out/prime_field/module.f.mjs +25 -2
- package/out/prime_field/test.f.d.mts +1 -0
- package/out/prime_field/test.f.mjs +7 -0
- package/out/secp/module.f.d.mts +68 -6
- package/out/secp/module.f.mjs +72 -12
- package/out/secp/test.f.d.mts +1 -0
- package/out/secp/test.f.mjs +18 -3
- package/out/types/bigint/test.f.mjs +7 -0
- package/out/types/bit_vec/module.f.d.mts +72 -0
- package/out/types/bit_vec/module.f.mjs +83 -0
- package/out/types/bit_vec/test.f.d.mts +9 -0
- package/out/types/bit_vec/test.f.mjs +60 -0
- package/package.json +1 -1
- package/prime_field/module.f.mjs +25 -2
- package/prime_field/test.f.mjs +5 -0
- package/secp/module.f.mjs +73 -12
- package/secp/test.f.mjs +18 -3
- package/types/bigint/test.f.mjs +5 -0
- package/types/bit_vec/module.f.mjs +90 -0
- package/types/bit_vec/test.f.mjs +41 -0
- /package/issues/lang/{3310-expression.md → 3410-expression.md} +0 -0
- /package/issues/lang/{3320-one-parameter.md → 3420-one-parameter.md} +0 -0
- /package/issues/lang/{3330-assignments.md → 3430-assignments.md} +0 -0
|
@@ -123,6 +123,13 @@ export default {
|
|
|
123
123
|
test(f.max - 1n);
|
|
124
124
|
test(f.max);
|
|
125
125
|
},
|
|
126
|
+
sqrtExample: () => {
|
|
127
|
+
const field = prime_field(7n);
|
|
128
|
+
const root = sqrt(field)(4n);
|
|
129
|
+
if (root !== 2n) {
|
|
130
|
+
throw root;
|
|
131
|
+
}
|
|
132
|
+
},
|
|
126
133
|
sqrt: () => {
|
|
127
134
|
/** @type {(a: bigint) => void} */
|
|
128
135
|
const test = a => {
|
package/out/secp/module.f.d.mts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
/** @typedef {readonly[bigint, bigint]} Point2D */
|
|
2
|
-
/** @typedef {Point2D|null} Point */
|
|
3
1
|
/**
|
|
2
|
+
* A 2D point represented as a pair of `bigint` values `[x, y]`.
|
|
3
|
+
*
|
|
4
|
+
* @typedef {readonly[bigint, bigint]} Point2D
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* A 2D point on an elliptic curve, represented as a pair of `bigint` values.
|
|
8
|
+
* `null` represents the point at infinity (`O`).
|
|
9
|
+
*
|
|
10
|
+
* @typedef {Point2D|null} Point
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Initialization parameters for an elliptic curve.
|
|
14
|
+
*
|
|
4
15
|
* @typedef {{
|
|
5
16
|
* readonly p: bigint
|
|
6
17
|
* readonly a: readonly[bigint, bigint]
|
|
@@ -9,6 +20,8 @@
|
|
|
9
20
|
* }} Init
|
|
10
21
|
*/
|
|
11
22
|
/**
|
|
23
|
+
* Represents an elliptic curve and its associated operations.
|
|
24
|
+
*
|
|
12
25
|
* @typedef {{
|
|
13
26
|
* readonly pf: pf.PrimeField
|
|
14
27
|
* readonly nf: pf.PrimeField
|
|
@@ -19,22 +32,71 @@
|
|
|
19
32
|
* readonly mul: (a: Point) => (n: bigint) => Point
|
|
20
33
|
* }} Curve
|
|
21
34
|
*/
|
|
22
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Constructs an elliptic curve with the given initialization parameters.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
*
|
|
40
|
+
* ```js
|
|
41
|
+
* const curveParams = {
|
|
42
|
+
* p: 23n,
|
|
43
|
+
* a: [0n, 1n],
|
|
44
|
+
* g: [1n, 1n],
|
|
45
|
+
* n: 19n
|
|
46
|
+
* };
|
|
47
|
+
* const curveInstance = curve(curveParams);
|
|
48
|
+
*
|
|
49
|
+
* // Access curve operations
|
|
50
|
+
* const point = curveInstance.add([1n, 1n])([2n, 5n]); // Add two points
|
|
51
|
+
* const negPoint = curveInstance.neg([1n, 1n]); // Negate a point
|
|
52
|
+
* const mulPoint = curveInstance.mul([1n, 1n])(3n); // Multiply a point by 3
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @type {(i: Init) => Curve}
|
|
56
|
+
*/
|
|
23
57
|
export const curve: (i: Init) => Curve;
|
|
24
58
|
/** @type {(a: Point) => (b: Point) => boolean} */
|
|
25
59
|
export const eq: (a: Point) => (b: Point) => boolean;
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
60
|
+
/**
|
|
61
|
+
* https://neuromancer.sk/std/secg/secp192r1
|
|
62
|
+
*
|
|
63
|
+
* @type {Init}
|
|
64
|
+
*/
|
|
29
65
|
export const secp192r1: Init;
|
|
66
|
+
/**
|
|
67
|
+
* https://en.bitcoin.it/wiki/Secp256k1
|
|
68
|
+
* https://neuromancer.sk/std/secg/secp256k1
|
|
69
|
+
*
|
|
70
|
+
* @type {Init}
|
|
71
|
+
*/
|
|
72
|
+
export const secp256k1: Init;
|
|
73
|
+
/**
|
|
74
|
+
* https://neuromancer.sk/std/secg/secp256r1
|
|
75
|
+
*
|
|
76
|
+
* @type { Init }
|
|
77
|
+
*/
|
|
78
|
+
export const secp256r1: Init;
|
|
79
|
+
/**
|
|
80
|
+
* A 2D point represented as a pair of `bigint` values `[x, y]`.
|
|
81
|
+
*/
|
|
30
82
|
export type Point2D = readonly [bigint, bigint];
|
|
83
|
+
/**
|
|
84
|
+
* A 2D point on an elliptic curve, represented as a pair of `bigint` values.
|
|
85
|
+
* `null` represents the point at infinity (`O`).
|
|
86
|
+
*/
|
|
31
87
|
export type Point = Point2D | null;
|
|
88
|
+
/**
|
|
89
|
+
* Initialization parameters for an elliptic curve.
|
|
90
|
+
*/
|
|
32
91
|
export type Init = {
|
|
33
92
|
readonly p: bigint;
|
|
34
93
|
readonly a: readonly [bigint, bigint];
|
|
35
94
|
readonly g: readonly [bigint, bigint];
|
|
36
95
|
readonly n: bigint;
|
|
37
96
|
};
|
|
97
|
+
/**
|
|
98
|
+
* Represents an elliptic curve and its associated operations.
|
|
99
|
+
*/
|
|
38
100
|
export type Curve = {
|
|
39
101
|
readonly pf: pf.PrimeField;
|
|
40
102
|
readonly nf: pf.PrimeField;
|
package/out/secp/module.f.mjs
CHANGED
|
@@ -4,9 +4,20 @@ import * as pf from '../prime_field/module.f.mjs';
|
|
|
4
4
|
import * as bi from '../types/bigint/module.f.mjs';
|
|
5
5
|
const { scalar_mul } = bi;
|
|
6
6
|
const { prime_field, sqrt } = pf;
|
|
7
|
-
/** @typedef {readonly[bigint, bigint]} Point2D */
|
|
8
|
-
/** @typedef {Point2D|null} Point */
|
|
9
7
|
/**
|
|
8
|
+
* A 2D point represented as a pair of `bigint` values `[x, y]`.
|
|
9
|
+
*
|
|
10
|
+
* @typedef {readonly[bigint, bigint]} Point2D
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* A 2D point on an elliptic curve, represented as a pair of `bigint` values.
|
|
14
|
+
* `null` represents the point at infinity (`O`).
|
|
15
|
+
*
|
|
16
|
+
* @typedef {Point2D|null} Point
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Initialization parameters for an elliptic curve.
|
|
20
|
+
*
|
|
10
21
|
* @typedef {{
|
|
11
22
|
* readonly p: bigint
|
|
12
23
|
* readonly a: readonly[bigint, bigint]
|
|
@@ -15,6 +26,8 @@ const { prime_field, sqrt } = pf;
|
|
|
15
26
|
* }} Init
|
|
16
27
|
*/
|
|
17
28
|
/**
|
|
29
|
+
* Represents an elliptic curve and its associated operations.
|
|
30
|
+
*
|
|
18
31
|
* @typedef {{
|
|
19
32
|
* readonly pf: pf.PrimeField
|
|
20
33
|
* readonly nf: pf.PrimeField
|
|
@@ -25,7 +38,28 @@ const { prime_field, sqrt } = pf;
|
|
|
25
38
|
* readonly mul: (a: Point) => (n: bigint) => Point
|
|
26
39
|
* }} Curve
|
|
27
40
|
*/
|
|
28
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* Constructs an elliptic curve with the given initialization parameters.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
*
|
|
46
|
+
* ```js
|
|
47
|
+
* const curveParams = {
|
|
48
|
+
* p: 23n,
|
|
49
|
+
* a: [0n, 1n],
|
|
50
|
+
* g: [1n, 1n],
|
|
51
|
+
* n: 19n
|
|
52
|
+
* };
|
|
53
|
+
* const curveInstance = curve(curveParams);
|
|
54
|
+
*
|
|
55
|
+
* // Access curve operations
|
|
56
|
+
* const point = curveInstance.add([1n, 1n])([2n, 5n]); // Add two points
|
|
57
|
+
* const negPoint = curveInstance.neg([1n, 1n]); // Negate a point
|
|
58
|
+
* const mulPoint = curveInstance.mul([1n, 1n])(3n); // Multiply a point by 3
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* @type {(i: Init) => Curve}
|
|
62
|
+
*/
|
|
29
63
|
export const curve = ({ p, a: [a0, a1], n }) => {
|
|
30
64
|
const pf = prime_field(p);
|
|
31
65
|
const { pow2, pow3, sub, add, mul, neg, div } = pf;
|
|
@@ -88,7 +122,29 @@ export const eq = a => b => {
|
|
|
88
122
|
const [bx, by] = b;
|
|
89
123
|
return ax === bx && ay === by;
|
|
90
124
|
};
|
|
91
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* https://neuromancer.sk/std/secg/secp192r1
|
|
127
|
+
*
|
|
128
|
+
* @type {Init}
|
|
129
|
+
*/
|
|
130
|
+
export const secp192r1 = {
|
|
131
|
+
p: 0xfffffffffffffffffffffffffffffffeffffffffffffffffn,
|
|
132
|
+
a: [
|
|
133
|
+
0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1n,
|
|
134
|
+
0xfffffffffffffffffffffffffffffffefffffffffffffffcn
|
|
135
|
+
],
|
|
136
|
+
g: [
|
|
137
|
+
0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012n,
|
|
138
|
+
0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811n
|
|
139
|
+
],
|
|
140
|
+
n: 0xffffffffffffffffffffffff99def836146bc9b1b4d22831n,
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* https://en.bitcoin.it/wiki/Secp256k1
|
|
144
|
+
* https://neuromancer.sk/std/secg/secp256k1
|
|
145
|
+
*
|
|
146
|
+
* @type {Init}
|
|
147
|
+
*/
|
|
92
148
|
export const secp256k1 = {
|
|
93
149
|
p: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn,
|
|
94
150
|
a: [7n, 0n],
|
|
@@ -98,16 +154,20 @@ export const secp256k1 = {
|
|
|
98
154
|
],
|
|
99
155
|
n: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n,
|
|
100
156
|
};
|
|
101
|
-
/**
|
|
102
|
-
|
|
103
|
-
|
|
157
|
+
/**
|
|
158
|
+
* https://neuromancer.sk/std/secg/secp256r1
|
|
159
|
+
*
|
|
160
|
+
* @type { Init }
|
|
161
|
+
*/
|
|
162
|
+
export const secp256r1 = {
|
|
163
|
+
p: 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffffn,
|
|
104
164
|
a: [
|
|
105
|
-
|
|
106
|
-
|
|
165
|
+
0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604bn, //< b
|
|
166
|
+
0xffffffff00000001000000000000000000000000fffffffffffffffffffffffcn, //< a
|
|
107
167
|
],
|
|
108
168
|
g: [
|
|
109
|
-
|
|
110
|
-
|
|
169
|
+
0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296n, //< x
|
|
170
|
+
0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5n, //< y
|
|
111
171
|
],
|
|
112
|
-
n:
|
|
172
|
+
n: 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551n,
|
|
113
173
|
};
|
package/out/secp/test.f.d.mts
CHANGED
package/out/secp/test.f.mjs
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import * as _ from './module.f.mjs';
|
|
2
|
-
const { curve, secp256k1, secp192r1, eq } = _;
|
|
2
|
+
const { curve, secp256k1, secp192r1, secp256r1, eq } = _;
|
|
3
3
|
export default {
|
|
4
|
+
example: () => {
|
|
5
|
+
/** @type {_.Init} */
|
|
6
|
+
const curveParams = {
|
|
7
|
+
p: 23n,
|
|
8
|
+
a: [0n, 1n],
|
|
9
|
+
g: [1n, 1n],
|
|
10
|
+
n: 19n
|
|
11
|
+
};
|
|
12
|
+
const c = curve(curveParams);
|
|
13
|
+
// Access curve operations
|
|
14
|
+
const point = c.add([1n, 1n])([2n, 5n]); // Add two points
|
|
15
|
+
const negPoint = c.neg([1n, 1n]); // Negate a point
|
|
16
|
+
const mulPoint = c.mul([1n, 1n])(3n); // Multiply a point by 3
|
|
17
|
+
},
|
|
4
18
|
test: () => {
|
|
5
19
|
/** @type {(c: _.Init) => void} */
|
|
6
20
|
const test_curve = c => {
|
|
@@ -9,12 +23,12 @@ export default {
|
|
|
9
23
|
/** @type {(p: _.Point) => void} */
|
|
10
24
|
const point_check = p => {
|
|
11
25
|
if (p === null) {
|
|
12
|
-
throw 'null';
|
|
26
|
+
throw 'p === null';
|
|
13
27
|
}
|
|
14
28
|
const [x, y] = p;
|
|
15
29
|
const ye = yf(x);
|
|
16
30
|
if (ye === null) {
|
|
17
|
-
throw 'null';
|
|
31
|
+
throw 'ye === null';
|
|
18
32
|
}
|
|
19
33
|
if (abs(ye) !== abs(y)) {
|
|
20
34
|
throw 'ye';
|
|
@@ -59,5 +73,6 @@ export default {
|
|
|
59
73
|
};
|
|
60
74
|
test_curve(secp256k1);
|
|
61
75
|
test_curve(secp192r1);
|
|
76
|
+
test_curve(secp256r1);
|
|
62
77
|
}
|
|
63
78
|
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A vector of bits represented as a `bigint`.
|
|
3
|
+
*
|
|
4
|
+
* @typedef {bigint} Vec
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* An empty vector of bits.
|
|
8
|
+
*/
|
|
9
|
+
export const empty: 1n;
|
|
10
|
+
/**
|
|
11
|
+
* Calculates the length of the given vector of bits.
|
|
12
|
+
*/
|
|
13
|
+
export const len: (v: bigint) => bigint;
|
|
14
|
+
/**
|
|
15
|
+
* Extract an unsigned integer of the given `uintLen` from the given vector.
|
|
16
|
+
*
|
|
17
|
+
* @type {(uintLen: bigint) => (v: Vec) => bigint}
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
*
|
|
21
|
+
* ```js
|
|
22
|
+
* const vector = 0b110101n;
|
|
23
|
+
* const extract3Bits = uint(3n);
|
|
24
|
+
* const result = extract3Bits(vector); // result is 0b101n (5n)
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export const uint: (uintLen: bigint) => (v: Vec) => bigint;
|
|
28
|
+
/**
|
|
29
|
+
* Creates a vector of bits of the given `vecLen` from the given unsigned integer.
|
|
30
|
+
*
|
|
31
|
+
* @type {(vecLen: bigint) => (ui: bigint) => Vec}
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
*
|
|
35
|
+
* ```js
|
|
36
|
+
* const createVector = vec(4n);
|
|
37
|
+
* const vector = createVector(5n); // vector is 0b10101n
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export const vec: (vecLen: bigint) => (ui: bigint) => Vec;
|
|
41
|
+
/**
|
|
42
|
+
* Appends the vector `b` to the back of the vector `a`.
|
|
43
|
+
*
|
|
44
|
+
* @type {(a: Vec) => (b: Vec) => Vec}
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
*
|
|
48
|
+
* ```js
|
|
49
|
+
* const vec8 = vec(8n)
|
|
50
|
+
* const a = vec8(0x345n)
|
|
51
|
+
* const b = vec8(0x789n)
|
|
52
|
+
* const ab = appendBack(a)(b) // 0x18945n
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export const appendBack: (a: Vec) => (b: Vec) => Vec;
|
|
56
|
+
/**
|
|
57
|
+
* Removes the first `len` bits from the given vector.
|
|
58
|
+
*
|
|
59
|
+
* @type {(len: bigint) => (v: Vec) => Vec}
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
*
|
|
63
|
+
* ```js
|
|
64
|
+
* const v = vec(17n)(0x12345n) // v = 0x32345n
|
|
65
|
+
* const r = removeFront(9n)(v) // r = 0x191n
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export const removeFront: (len: bigint) => (v: Vec) => Vec;
|
|
69
|
+
/**
|
|
70
|
+
* A vector of bits represented as a `bigint`.
|
|
71
|
+
*/
|
|
72
|
+
export type Vec = bigint;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// @ts-self-types="./module.f.d.mts"
|
|
2
|
+
import { log2 } from '../bigint/module.f.mjs';
|
|
3
|
+
/**
|
|
4
|
+
* A vector of bits represented as a `bigint`.
|
|
5
|
+
*
|
|
6
|
+
* @typedef {bigint} Vec
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* An empty vector of bits.
|
|
10
|
+
*/
|
|
11
|
+
export const empty = 1n;
|
|
12
|
+
/**
|
|
13
|
+
* Calculates the length of the given vector of bits.
|
|
14
|
+
*/
|
|
15
|
+
export const len = log2;
|
|
16
|
+
/**
|
|
17
|
+
* Extract an unsigned integer of the given `uintLen` from the given vector.
|
|
18
|
+
*
|
|
19
|
+
* @type {(uintLen: bigint) => (v: Vec) => bigint}
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
*
|
|
23
|
+
* ```js
|
|
24
|
+
* const vector = 0b110101n;
|
|
25
|
+
* const extract3Bits = uint(3n);
|
|
26
|
+
* const result = extract3Bits(vector); // result is 0b101n (5n)
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export const uint = uintLen => {
|
|
30
|
+
const mask = (1n << uintLen) - 1n;
|
|
31
|
+
return data => data & mask;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Creates a vector of bits of the given `vecLen` from the given unsigned integer.
|
|
35
|
+
*
|
|
36
|
+
* @type {(vecLen: bigint) => (ui: bigint) => Vec}
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
*
|
|
40
|
+
* ```js
|
|
41
|
+
* const createVector = vec(4n);
|
|
42
|
+
* const vector = createVector(5n); // vector is 0b10101n
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export const vec = vecLen => {
|
|
46
|
+
const stop = 1n << vecLen;
|
|
47
|
+
const mask = stop - 1n;
|
|
48
|
+
return data => (data & mask) | stop;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Appends the vector `b` to the back of the vector `a`.
|
|
52
|
+
*
|
|
53
|
+
* @type {(a: Vec) => (b: Vec) => Vec}
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
*
|
|
57
|
+
* ```js
|
|
58
|
+
* const vec8 = vec(8n)
|
|
59
|
+
* const a = vec8(0x345n)
|
|
60
|
+
* const b = vec8(0x789n)
|
|
61
|
+
* const ab = appendBack(a)(b) // 0x18945n
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export const appendBack = a => {
|
|
65
|
+
const aLen = len(a);
|
|
66
|
+
return b => a | (b << aLen);
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Removes the first `len` bits from the given vector.
|
|
70
|
+
*
|
|
71
|
+
* @type {(len: bigint) => (v: Vec) => Vec}
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
*
|
|
75
|
+
* ```js
|
|
76
|
+
* const v = vec(17n)(0x12345n) // v = 0x32345n
|
|
77
|
+
* const r = removeFront(9n)(v) // r = 0x191n
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export const removeFront = len => v => {
|
|
81
|
+
const r = v >> len;
|
|
82
|
+
return r === 0n ? empty : r;
|
|
83
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { empty, len, appendBack, vec, uint, removeFront } from './module.f.mjs';
|
|
2
|
+
export default {
|
|
3
|
+
uintExample: () => {
|
|
4
|
+
const vector = 53n;
|
|
5
|
+
const extract3Bits = uint(3n);
|
|
6
|
+
const result = extract3Bits(vector); // result is 0b101n (5n)
|
|
7
|
+
if (result !== 5n) {
|
|
8
|
+
throw result;
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
vecExample: () => {
|
|
12
|
+
const createVector = vec(4n);
|
|
13
|
+
const vector = createVector(5n); // vector is 0b10101n
|
|
14
|
+
if (vector !== 21n) {
|
|
15
|
+
throw vector;
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
length: () => {
|
|
19
|
+
const i = len(empty);
|
|
20
|
+
if (i !== 0n) {
|
|
21
|
+
throw i;
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
bitset: () => {
|
|
25
|
+
const v = vec(8n)(0x5fen);
|
|
26
|
+
if (v !== 0x1fen) {
|
|
27
|
+
throw v;
|
|
28
|
+
}
|
|
29
|
+
if (len(v) !== 8n) {
|
|
30
|
+
throw 'len';
|
|
31
|
+
}
|
|
32
|
+
const u = uint(8n)(v);
|
|
33
|
+
if (u !== 0xfen) {
|
|
34
|
+
throw v;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
appendBack: () => {
|
|
38
|
+
const vec8 = vec(8n);
|
|
39
|
+
const a = vec8(0x345n);
|
|
40
|
+
const b = vec8(0x789n);
|
|
41
|
+
const ab = appendBack(a)(b);
|
|
42
|
+
if (ab !== 0x18945n) {
|
|
43
|
+
throw ab;
|
|
44
|
+
}
|
|
45
|
+
const s = len(ab);
|
|
46
|
+
if (s !== 16n) {
|
|
47
|
+
throw `appendBack: ${s}`;
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
removeBack: () => {
|
|
51
|
+
const v = vec(17n)(0x12345n);
|
|
52
|
+
if (v !== 0x32345n) {
|
|
53
|
+
throw v.toString(16);
|
|
54
|
+
}
|
|
55
|
+
const r = removeFront(9n)(v);
|
|
56
|
+
if (r !== 0x191n) {
|
|
57
|
+
throw r.toString(16);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
package/package.json
CHANGED
package/prime_field/module.f.mjs
CHANGED
|
@@ -8,6 +8,8 @@ const { scalar_mul } = bi
|
|
|
8
8
|
/** @typedef {Operator.Unary<bigint, bigint>} Unary*/
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
+
* A type representing a prime field and its associated operations.
|
|
12
|
+
*
|
|
11
13
|
* @typedef {{
|
|
12
14
|
* readonly p: bigint
|
|
13
15
|
* readonly middle: bigint
|
|
@@ -25,7 +27,14 @@ const { scalar_mul } = bi
|
|
|
25
27
|
* }} PrimeField
|
|
26
28
|
*/
|
|
27
29
|
|
|
28
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* Creates a prime field with the specified prime modulus and associated operations.
|
|
32
|
+
*
|
|
33
|
+
* @param p - A prime number to define the field.
|
|
34
|
+
* @returns The prime field object.
|
|
35
|
+
*
|
|
36
|
+
* @type {(p: bigint) => PrimeField}
|
|
37
|
+
*/
|
|
29
38
|
export const prime_field = p => {
|
|
30
39
|
/** @type {Reduce} */
|
|
31
40
|
const sub = a => b => {
|
|
@@ -77,7 +86,21 @@ export const prime_field = p => {
|
|
|
77
86
|
}
|
|
78
87
|
}
|
|
79
88
|
|
|
80
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* Computes the square root of a number in a prime field.
|
|
91
|
+
*
|
|
92
|
+
* @throws If the prime modulus `p` does not satisfy `p % 4 == 3`.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
*
|
|
96
|
+
* ```js
|
|
97
|
+
* const field = prime_field(7n);
|
|
98
|
+
* const root = sqrt(field)(4n);
|
|
99
|
+
* if (root !== 2n) { throw root }
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* @type {(f: PrimeField) => (a: bigint) => bigint|null}
|
|
103
|
+
*/
|
|
81
104
|
export const sqrt = ({p, mul, pow }) => {
|
|
82
105
|
if ((p & 3n) !== 3n) { throw 'sqrt' }
|
|
83
106
|
const sqrt_k = (p + 1n) >> 2n
|
package/prime_field/test.f.mjs
CHANGED
|
@@ -68,6 +68,11 @@ export default {
|
|
|
68
68
|
test(f.max - 1n)
|
|
69
69
|
test(f.max)
|
|
70
70
|
},
|
|
71
|
+
sqrtExample: () => {
|
|
72
|
+
const field = prime_field(7n);
|
|
73
|
+
const root = sqrt(field)(4n);
|
|
74
|
+
if (root !== 2n) { throw root }
|
|
75
|
+
},
|
|
71
76
|
sqrt: () => {
|
|
72
77
|
/** @type {(a: bigint) => void} */
|
|
73
78
|
const test = a => {
|