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.
Files changed (41) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/com/cpp/module.f.mjs +10 -1
  3. package/com/cs/module.f.mjs +11 -1
  4. package/com/rust/module.f.mjs +13 -1
  5. package/dev/module.mjs +1 -1
  6. package/issues/lang/3370-type-inference.md +69 -0
  7. package/issues/lang/3380-promise.md +22 -0
  8. package/issues/lang/3390-class.md +3 -0
  9. package/issues/lang/README.md +79 -8
  10. package/jsr.json +60 -59
  11. package/out/com/cpp/module.f.d.mts +4 -1
  12. package/out/com/cpp/module.f.mjs +8 -1
  13. package/out/com/cs/module.f.d.mts +4 -1
  14. package/out/com/cs/module.f.mjs +10 -1
  15. package/out/com/rust/module.f.d.mts +1 -2
  16. package/out/com/rust/module.f.mjs +12 -1
  17. package/out/dev/module.mjs +1 -1
  18. package/out/prime_field/module.f.d.mts +28 -2
  19. package/out/prime_field/module.f.mjs +25 -2
  20. package/out/prime_field/test.f.d.mts +1 -0
  21. package/out/prime_field/test.f.mjs +7 -0
  22. package/out/secp/module.f.d.mts +68 -6
  23. package/out/secp/module.f.mjs +72 -12
  24. package/out/secp/test.f.d.mts +1 -0
  25. package/out/secp/test.f.mjs +18 -3
  26. package/out/types/bigint/test.f.mjs +7 -0
  27. package/out/types/bit_vec/module.f.d.mts +72 -0
  28. package/out/types/bit_vec/module.f.mjs +83 -0
  29. package/out/types/bit_vec/test.f.d.mts +9 -0
  30. package/out/types/bit_vec/test.f.mjs +60 -0
  31. package/package.json +1 -1
  32. package/prime_field/module.f.mjs +25 -2
  33. package/prime_field/test.f.mjs +5 -0
  34. package/secp/module.f.mjs +73 -12
  35. package/secp/test.f.mjs +18 -3
  36. package/types/bigint/test.f.mjs +5 -0
  37. package/types/bit_vec/module.f.mjs +90 -0
  38. package/types/bit_vec/test.f.mjs +41 -0
  39. /package/issues/lang/{3310-expression.md → 3410-expression.md} +0 -0
  40. /package/issues/lang/{3320-one-parameter.md → 3420-one-parameter.md} +0 -0
  41. /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 => {
@@ -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
- /** @type {(i: Init) => Curve} */
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
- /** @type {Init} */
27
- export const secp256k1: Init;
28
- /** @type {Init} */
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;
@@ -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
- /** @type {(i: Init) => Curve} */
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
- /** @type {Init} */
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
- /** @type {Init} */
102
- export const secp192r1 = {
103
- p: 0xfffffffffffffffffffffffffffffffeffffffffffffffffn,
157
+ /**
158
+ * https://neuromancer.sk/std/secg/secp256r1
159
+ *
160
+ * @type { Init }
161
+ */
162
+ export const secp256r1 = {
163
+ p: 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffffn,
104
164
  a: [
105
- 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1n,
106
- 0xfffffffffffffffffffffffffffffffefffffffffffffffcn
165
+ 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604bn, //< b
166
+ 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffcn, //< a
107
167
  ],
108
168
  g: [
109
- 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012n,
110
- 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811n
169
+ 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296n, //< x
170
+ 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5n, //< y
111
171
  ],
112
- n: 0xffffffffffffffffffffffff99def836146bc9b1b4d22831n,
172
+ n: 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551n,
113
173
  };
@@ -1,4 +1,5 @@
1
1
  declare namespace _default {
2
+ function example(): void;
2
3
  function test(): void;
3
4
  }
4
5
  export default _default;
@@ -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
  };
@@ -110,6 +110,13 @@ export default {
110
110
  throw result;
111
111
  }
112
112
  },
113
+ () => {
114
+ const v = 0x18945n;
115
+ const result = log2(v);
116
+ if (result !== 16n) {
117
+ throw result;
118
+ }
119
+ }
113
120
  ],
114
121
  toString2: () => {
115
122
  // max for Bun (131_072 Bytes)
@@ -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,9 @@
1
+ declare namespace _default {
2
+ function uintExample(): void;
3
+ function vecExample(): void;
4
+ function length(): void;
5
+ function bitset(): void;
6
+ function appendBack(): void;
7
+ function removeBack(): void;
8
+ }
9
+ export default _default;
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "type": "module",
5
5
  "description": "FunctionalScript is a functional subset of JavaScript",
6
6
  "scripts": {
@@ -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
- /** @type {(p: bigint) => PrimeField} */
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
- /** @type {(f: PrimeField) => (a: bigint) => bigint|null} */
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
@@ -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 => {