finitefields 0.0.7 → 0.0.8
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/ellipticcurves.ts +28 -14
- package/galois.ts +95 -14
- package/main.ts +8 -22
- package/package.json +1 -1
- package/main.js +0 -26
package/ellipticcurves.ts
CHANGED
|
@@ -7,11 +7,12 @@
|
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { PrimeField } from
|
|
10
|
+
import type { GF,PrimeField } from './galois.js';
|
|
11
|
+
import { Util } from './galois.js';
|
|
11
12
|
|
|
12
13
|
let log:(...x:any[])=>void;
|
|
13
14
|
let fail:(...x:any[])=>never;
|
|
14
|
-
let p256:ECCurve;
|
|
15
|
+
let p256:()=>ECCurve;
|
|
15
16
|
|
|
16
17
|
log = console.log;
|
|
17
18
|
fail = (...args:any[]): never => {
|
|
@@ -21,7 +22,7 @@ fail = (...args:any[]): never => {
|
|
|
21
22
|
return void 0 as never;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
p256 = {
|
|
25
|
+
p256 = ():ECCurve => ({
|
|
25
26
|
'#E': 0xffffffff00000000_ffffffffffffffff_bce6faada7179e84_f3b9cac2fc632551n,
|
|
26
27
|
'θ': 0xffffffff00000001_0000000000000000_00000000ffffffff_ffffffffffffffffn,
|
|
27
28
|
'b': 0x5ac635d8aa3a93e7_b3ebbd55769886bc_651d06b0cc53b0f6_3bce3c3e27d2604bn,
|
|
@@ -34,11 +35,18 @@ p256 = {
|
|
|
34
35
|
[
|
|
35
36
|
0xc97445f45cdef9f0_d3e05e1e585fc297_235b82b5be8ff3ef_ca67c59852018192n,
|
|
36
37
|
0xb28ef557ba31dfcb_dd21ac46e2a91e3c_304f44cb87058ada_2cb815151e610046n
|
|
37
|
-
]
|
|
38
|
-
|
|
38
|
+
],
|
|
39
|
+
bitlen: 256n,
|
|
40
|
+
formula: (a:bigint,b:bigint,f:PrimeField)=>(x:bigint,y:bigint) =>
|
|
41
|
+
f.add(f.add( // y^2 =
|
|
42
|
+
f.exp(x, 3n), // x^3
|
|
43
|
+
f.mul(a,x)), // + ax
|
|
44
|
+
b) // + b
|
|
45
|
+
});
|
|
39
46
|
|
|
40
47
|
type Tuple<a> = readonly [a,a];
|
|
41
48
|
type infinity = false | true;
|
|
49
|
+
type ECformula = (a:bigint,b:bigint,f:GF)=>Function;
|
|
42
50
|
|
|
43
51
|
interface Tuples {
|
|
44
52
|
'p': Tuple<bigint>;
|
|
@@ -46,8 +54,10 @@ interface Tuples {
|
|
|
46
54
|
}
|
|
47
55
|
|
|
48
56
|
interface IECCurve {
|
|
49
|
-
'θ':
|
|
50
|
-
'b':
|
|
57
|
+
'θ': bigint;
|
|
58
|
+
'b': bigint;
|
|
59
|
+
bitlen: bigint;
|
|
60
|
+
formula: ECformula;
|
|
51
61
|
}
|
|
52
62
|
|
|
53
63
|
type hashE = {'#E':bigint};
|
|
@@ -79,7 +89,7 @@ class Point implements Ipoint {
|
|
|
79
89
|
constructor(point:Tuple<bigint>) {
|
|
80
90
|
[ this['x'], this['y'], this['∞'] ] = [0n,0n,false];
|
|
81
91
|
|
|
82
|
-
switch (point.every((xy:bigint):xy is bigint
|
|
92
|
+
switch (point.every((xy:bigint):xy is bigint=>!!xy)) {
|
|
83
93
|
case true:
|
|
84
94
|
[ this['x'], this['y'] ] = point;
|
|
85
95
|
break;
|
|
@@ -100,9 +110,10 @@ class Curve<a> implements Icurve {
|
|
|
100
110
|
public b: bigint;
|
|
101
111
|
public p: Point;
|
|
102
112
|
public q: Point;
|
|
103
|
-
|
|
113
|
+
public bitlen: bigint;
|
|
114
|
+
public formula:ECformula;
|
|
104
115
|
|
|
105
|
-
constructor(
|
|
116
|
+
constructor(curve:ECCurve) {
|
|
106
117
|
let m:string;
|
|
107
118
|
|
|
108
119
|
m = 'argument error (incomplete curve params)' as const;
|
|
@@ -112,9 +123,12 @@ class Curve<a> implements Icurve {
|
|
|
112
123
|
|| fail(m);
|
|
113
124
|
this.b = curve.b
|
|
114
125
|
|| fail(m);
|
|
126
|
+
this.bitlen = curve.bitlen
|
|
127
|
+
|| fail(m);
|
|
128
|
+
this.formula = curve.formula
|
|
129
|
+
|| fail(m);
|
|
115
130
|
this.p = new Point(curve.p);
|
|
116
131
|
this.q = new Point(curve.q);
|
|
117
|
-
this.object = object;
|
|
118
132
|
|
|
119
133
|
return this;
|
|
120
134
|
}
|
|
@@ -125,13 +139,13 @@ abstract class EllipticCurves<a> implements Iellipticcurves<a> {
|
|
|
125
139
|
private curve: Curve<a>;
|
|
126
140
|
|
|
127
141
|
constructor(curve:ECCurve) {
|
|
128
|
-
this.curve = new Curve<a>(
|
|
142
|
+
this.curve = new Curve<a>(curve);
|
|
129
143
|
|
|
130
144
|
return this;
|
|
131
145
|
}
|
|
132
146
|
}
|
|
133
147
|
|
|
134
|
-
class
|
|
148
|
+
class ecℤp extends EllipticCurves<PrimeField>
|
|
135
149
|
implements Iellipticcurves<PrimeField>
|
|
136
150
|
{
|
|
137
151
|
public backend:PrimeField;
|
|
@@ -144,4 +158,4 @@ class ECoverℤp extends EllipticCurves<PrimeField>
|
|
|
144
158
|
}
|
|
145
159
|
}
|
|
146
160
|
|
|
147
|
-
export {
|
|
161
|
+
export { ecℤp, p256 };
|
package/galois.ts
CHANGED
|
@@ -19,15 +19,30 @@ fail = (...args:any[]): never => {
|
|
|
19
19
|
return void 0 as never;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
enum fieldops {
|
|
23
|
+
$add,
|
|
24
|
+
$sub,
|
|
25
|
+
$mul,
|
|
26
|
+
$inv,
|
|
27
|
+
$exp
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
enum methods {
|
|
31
|
+
SquareAndMultiply,
|
|
32
|
+
DoubleAndAdd
|
|
33
|
+
}
|
|
34
|
+
|
|
22
35
|
const arithmeticsℤp = (p:bigint,op:fieldops) =>
|
|
23
36
|
(op==fieldops.$add) ?
|
|
24
37
|
(a:bigint,b:bigint=0n) => (a+b)%p :
|
|
25
38
|
(op==fieldops.$sub) ?
|
|
26
39
|
(a:bigint,b:bigint=0n) => ((a-b)<1)?(a-b+p):(a-b)%p :
|
|
27
40
|
(op==fieldops.$mul) ?
|
|
28
|
-
(a:bigint,b:bigint=0n) => (a
|
|
41
|
+
(a:bigint,b:bigint=0n) => (!a||!b)?0n:Util.dblad(a,b,p) :
|
|
29
42
|
(op==fieldops.$inv) ?
|
|
30
43
|
(a:bigint) => (!a)?fail('0 has no inverse'):Util.sqmul(a,(p-2n),p) :
|
|
44
|
+
(op==fieldops.$exp) ?
|
|
45
|
+
(a:bigint,b:bigint=0n) => (!a)?0n:(!b)?1n:Util.sqmul(a,b,p) :
|
|
31
46
|
fail('unknown field operation');
|
|
32
47
|
|
|
33
48
|
Util = {
|
|
@@ -44,6 +59,28 @@ Util = {
|
|
|
44
59
|
let n:number;
|
|
45
60
|
let r:bigint;
|
|
46
61
|
let ret:boolean;
|
|
62
|
+
// let pow:(x:bigint,e:bigint,p_:bigint)=>bigint;
|
|
63
|
+
|
|
64
|
+
// pow = (x:bigint,e:bigint,p_:bigint): bigint => {
|
|
65
|
+
// let n_:bigint;
|
|
66
|
+
// let v:bigint;
|
|
67
|
+
|
|
68
|
+
// if (e == 1n)
|
|
69
|
+
// return (x%p_);
|
|
70
|
+
// else if (!e)
|
|
71
|
+
// return (1n%p_);
|
|
72
|
+
// else if (e<0n)
|
|
73
|
+
// return fail("trying to raise to negative power");
|
|
74
|
+
|
|
75
|
+
// n_ = e;
|
|
76
|
+
// v = x;
|
|
77
|
+
// while (--n_)
|
|
78
|
+
// v = (v*v)%p_;
|
|
79
|
+
|
|
80
|
+
// return v;
|
|
81
|
+
// }
|
|
82
|
+
|
|
83
|
+
return true;
|
|
47
84
|
|
|
48
85
|
if (p<2n)
|
|
49
86
|
return true;
|
|
@@ -51,7 +88,8 @@ Util = {
|
|
|
51
88
|
for (n=0, ret=true; n<s; n++) {
|
|
52
89
|
r = this.rnd(bitlen,(p-1n));
|
|
53
90
|
r += 1n;
|
|
54
|
-
if (((r**(p-1n))%p) != 1n) {
|
|
91
|
+
// if (((r**(p-1n))%p) != 1n) {
|
|
92
|
+
if (this.sqmul(r,(p-1n),p) !== 1n) {
|
|
55
93
|
ret = false;
|
|
56
94
|
break;
|
|
57
95
|
}
|
|
@@ -92,18 +130,50 @@ Util = {
|
|
|
92
130
|
return fail('eea() not implemented') as never;
|
|
93
131
|
},
|
|
94
132
|
|
|
95
|
-
sqmul(a:bigint,e:bigint,p:bigint): bigint
|
|
133
|
+
sqmul: (a:bigint,e:bigint,p:bigint): bigint =>
|
|
134
|
+
Util.binmethod(a,e,p,methods.SquareAndMultiply),
|
|
135
|
+
dblad: (a:bigint,e:bigint,p:bigint): bigint =>
|
|
136
|
+
Util.binmethod(a,e,p,methods.DoubleAndAdd),
|
|
137
|
+
|
|
138
|
+
binmethod(a_:bigint,e_:bigint,p:bigint,method:methods): bigint {
|
|
96
139
|
let bitstring:boolean[];
|
|
97
140
|
let bitlen:bigint;
|
|
98
141
|
let n:bigint;
|
|
99
142
|
let val:bigint;
|
|
100
143
|
let mul:(y:bigint,z:bigint,p_:bigint)=>bigint;
|
|
101
144
|
let sq:(y:bigint,p_:bigint)=>bigint;
|
|
145
|
+
let sign:string;
|
|
146
|
+
let a:bigint;
|
|
147
|
+
let e:bigint;
|
|
148
|
+
|
|
149
|
+
sign = (method==methods.SquareAndMultiply) ? '^' : 'x';
|
|
150
|
+
log(`${a_}${sign}${e_} (mod ${p}) = `);
|
|
151
|
+
|
|
152
|
+
switch (method) {
|
|
153
|
+
case methods.SquareAndMultiply:
|
|
154
|
+
sq = (y:bigint,p_:bigint):bigint =>
|
|
155
|
+
Util.binmethod(y,y,p_,methods.DoubleAndAdd);
|
|
156
|
+
mul = (y:bigint,z:bigint,p_:bigint):bigint =>
|
|
157
|
+
Util.binmethod(y,z,p_,methods.DoubleAndAdd);
|
|
158
|
+
a=a_;
|
|
159
|
+
e=e_;
|
|
160
|
+
break;
|
|
102
161
|
|
|
103
|
-
|
|
162
|
+
case methods.DoubleAndAdd:
|
|
163
|
+
sq = (y:bigint,p_:bigint):bigint =>
|
|
164
|
+
// Util.binmethod(y,2n,p_,DoubleAndAdd)
|
|
165
|
+
((y+y)%p_)
|
|
166
|
+
mul = (y:bigint,z:bigint,p_:bigint):bigint =>
|
|
167
|
+
// Util.binmethod(y,z,p_,DoubleAndAdd)
|
|
168
|
+
((y+z)%p_);
|
|
169
|
+
a=e_;
|
|
170
|
+
e=a_;
|
|
171
|
+
break;
|
|
104
172
|
|
|
105
|
-
|
|
106
|
-
|
|
173
|
+
default:
|
|
174
|
+
return fail('argument error');
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
107
177
|
|
|
108
178
|
val = a;
|
|
109
179
|
bitlen = this.countbits(e);
|
|
@@ -114,12 +184,18 @@ Util = {
|
|
|
114
184
|
.fill(false,0,Number(bitlen))
|
|
115
185
|
.map((x:boolean,idx:number):boolean =>
|
|
116
186
|
(((e>>n--)&1n)===1n) && (!!idx));
|
|
187
|
+
// if (method === methods.DoubleAndAdd)
|
|
188
|
+
bitstring.shift();
|
|
117
189
|
// log(bitstring.map((x:boolean):number => (x)?1:0));
|
|
118
190
|
bitstring
|
|
119
191
|
.forEach((x:boolean):void => {
|
|
192
|
+
// val = (x) ?
|
|
193
|
+
// mul(a,sq(val,p),p) :
|
|
194
|
+
// sq(a,p);
|
|
120
195
|
val = (x) ?
|
|
121
196
|
mul(a,sq(val,p),p) :
|
|
122
|
-
sq(
|
|
197
|
+
sq(val,p);
|
|
198
|
+
// log(val);
|
|
123
199
|
|
|
124
200
|
return void 0;
|
|
125
201
|
});
|
|
@@ -128,19 +204,14 @@ Util = {
|
|
|
128
204
|
}
|
|
129
205
|
}
|
|
130
206
|
|
|
131
|
-
enum fieldops {
|
|
132
|
-
$add,
|
|
133
|
-
$sub,
|
|
134
|
-
$mul,
|
|
135
|
-
$inv
|
|
136
|
-
}
|
|
137
|
-
|
|
138
207
|
interface Igalois {
|
|
139
208
|
add: (a:bigint,b:bigint)=>bigint;
|
|
140
209
|
sub: (a:bigint,b:bigint)=>bigint;
|
|
141
210
|
mul: (a:bigint,b:bigint)=>bigint;
|
|
142
211
|
inv: (a:bigint)=>bigint;
|
|
212
|
+
exp: (a:bigint,b:bigint)=>bigint;
|
|
143
213
|
verify:()=>void;
|
|
214
|
+
get p(): bigint;
|
|
144
215
|
constructor:Function;
|
|
145
216
|
}
|
|
146
217
|
|
|
@@ -149,7 +220,9 @@ interface Iutil {
|
|
|
149
220
|
countbits: (x:bigint)=>bigint;
|
|
150
221
|
rnd: (bitlen:bigint,max:bigint)=>bigint;
|
|
151
222
|
eea: (x:bigint,p:bigint)=>bigint;
|
|
223
|
+
binmethod: (a:bigint,e:bigint,p:bigint,method:methods)=>bigint;
|
|
152
224
|
sqmul: (a:bigint,e:bigint,p:bigint)=>bigint;
|
|
225
|
+
dblad: (a:bigint,e:bigint,p:bigint)=>bigint;
|
|
153
226
|
}
|
|
154
227
|
|
|
155
228
|
abstract class GF implements Igalois {
|
|
@@ -159,9 +232,14 @@ abstract class GF implements Igalois {
|
|
|
159
232
|
public abstract sub: typeof this.add;
|
|
160
233
|
public abstract mul: typeof this.add;
|
|
161
234
|
public abstract inv: (a:bigint)=>bigint;
|
|
235
|
+
public abstract exp: typeof this.add;
|
|
162
236
|
|
|
163
237
|
public abstract verify(): void;
|
|
164
238
|
|
|
239
|
+
public get p(): bigint {
|
|
240
|
+
return this.modulus;
|
|
241
|
+
}
|
|
242
|
+
|
|
165
243
|
constructor(field:bigint,bitlen:bigint) {
|
|
166
244
|
this.modulus = field;
|
|
167
245
|
this.bitlen = bitlen;
|
|
@@ -177,6 +255,7 @@ class PrimeField extends GF implements Igalois {
|
|
|
177
255
|
public sub: typeof this.add;
|
|
178
256
|
public mul: typeof this.add;
|
|
179
257
|
public inv: (a:bigint)=>bigint;
|
|
258
|
+
public exp: typeof this.add;
|
|
180
259
|
|
|
181
260
|
public verify(): void {
|
|
182
261
|
if (!Util.isprime(this.modulus))
|
|
@@ -193,6 +272,7 @@ class PrimeField extends GF implements Igalois {
|
|
|
193
272
|
this.sub = arithmeticsℤp(this.modulus, fieldops.$sub);
|
|
194
273
|
this.mul = arithmeticsℤp(this.modulus, fieldops.$mul);
|
|
195
274
|
this.inv = arithmeticsℤp(this.modulus, fieldops.$inv);
|
|
275
|
+
this.exp = arithmeticsℤp(this.modulus, fieldops.$exp);
|
|
196
276
|
|
|
197
277
|
return this;
|
|
198
278
|
}
|
|
@@ -200,3 +280,4 @@ class PrimeField extends GF implements Igalois {
|
|
|
200
280
|
}
|
|
201
281
|
|
|
202
282
|
export { Util, PrimeField };
|
|
283
|
+
export type { GF }
|
package/main.ts
CHANGED
|
@@ -1,31 +1,17 @@
|
|
|
1
1
|
/* main.ts */
|
|
2
2
|
import { Polynomial } from './polynomial.js';
|
|
3
3
|
import { Util,PrimeField } from './galois.js';
|
|
4
|
-
import {
|
|
4
|
+
import { ecℤp, p256 } from './ellipticcurves.js';
|
|
5
5
|
|
|
6
6
|
let log:(...x:any[])=>void;
|
|
7
7
|
log = console.log;
|
|
8
8
|
|
|
9
|
-
let
|
|
10
|
-
let
|
|
11
|
-
let p3:Polynomial;
|
|
12
|
-
let x0:bigint;
|
|
13
|
-
let x1:bigint;
|
|
14
|
-
let x2:bigint;
|
|
15
|
-
let x3:bigint;
|
|
9
|
+
let field:PrimeField;
|
|
10
|
+
let curve:ecℤp;
|
|
16
11
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
field = new PrimeField(p256().θ, p256().bitlen);
|
|
13
|
+
log(field);
|
|
14
|
+
curve = new ecℤp(field, p256());
|
|
15
|
+
log(curve);
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
p2 = new Polynomial({ tobject:0n, x3:1n, x2:0n, x:1n, 1:1n }, 2n);
|
|
24
|
-
// log(p1, " + ", p2, " =");
|
|
25
|
-
// p3 = Polynomial.add(p1,p2);
|
|
26
|
-
p3 = new Polynomial(1n<<254n, 2n);
|
|
27
|
-
|
|
28
|
-
log(p3, p3.eval());
|
|
29
|
-
// log(p3.eval());
|
|
30
|
-
|
|
31
|
-
export { Polynomial,Util,PrimeField,ECoverℤp };
|
|
17
|
+
export { Polynomial,Util,PrimeField,ecℤp,p256 };
|
package/package.json
CHANGED
package/main.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/* main.ts */
|
|
2
|
-
import { Polynomial } from './polynomial.js';
|
|
3
|
-
import { Util, PrimeField } from './galois.js';
|
|
4
|
-
import { ECoverℤp } from './ellipticcurves.js';
|
|
5
|
-
let log;
|
|
6
|
-
log = console.log;
|
|
7
|
-
let p1;
|
|
8
|
-
let p2;
|
|
9
|
-
let p3;
|
|
10
|
-
let x0;
|
|
11
|
-
let x1;
|
|
12
|
-
let x2;
|
|
13
|
-
let x3;
|
|
14
|
-
x0 = BigInt(1);
|
|
15
|
-
x1 = BigInt(0);
|
|
16
|
-
x2 = BigInt(1);
|
|
17
|
-
x3 = BigInt(0);
|
|
18
|
-
p1 = new Polynomial([x0, x1, x2, x3], 2n);
|
|
19
|
-
p2 = new Polynomial({ tobject: 0n, x3: 1n, x2: 0n, x: 1n, 1: 1n }, 2n);
|
|
20
|
-
// log(p1, " + ", p2, " =");
|
|
21
|
-
// p3 = Polynomial.add(p1,p2);
|
|
22
|
-
p3 = new Polynomial(1n << 254n, 2n);
|
|
23
|
-
log(p3, p3.eval());
|
|
24
|
-
// log(p3.eval());
|
|
25
|
-
export { Polynomial, Util, PrimeField, ECoverℤp };
|
|
26
|
-
//# sourceMappingURL=main.js.map
|