finitefields 0.0.9 → 0.0.10

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 CHANGED
@@ -7,8 +7,8 @@
7
7
  *
8
8
  */
9
9
 
10
- import type { GF,PrimeField } from './galois.js';
11
- import { just, nothing, type Maybe, type Nothing } from './maybe.js';
10
+ import { PrimeField, type GF } from './galois.js';
11
+ import { empty, fold, just, nothing, type Maybe, type Nothing } from './maybe.js';
12
12
  import { Util } from './galois.js';
13
13
 
14
14
  let 𝒪:Nothing;
@@ -28,6 +28,7 @@ fail = (...args:any[]): never => {
28
28
  p256 = ():ECCurve => ({
29
29
  '#E': 0xffffffff00000000_ffffffffffffffff_bce6faada7179e84_f3b9cac2fc632551n,
30
30
  'θ': 0xffffffff00000001_0000000000000000_00000000ffffffff_ffffffffffffffffn,
31
+ 'a': -3n,
31
32
  'b': 0x5ac635d8aa3a93e7_b3ebbd55769886bc_651d06b0cc53b0f6_3bce3c3e27d2604bn,
32
33
  'p':
33
34
  [
@@ -51,6 +52,7 @@ type Tuple<a> = readonly [a,a];
51
52
  type Coordinate = Maybe<Point>;
52
53
  type infinity = false | true;
53
54
  type ECformula = (a:bigint,b:bigint,f:GF)=>Function;
55
+ type Slope = bigint;
54
56
 
55
57
  interface Tuples {
56
58
  'p': Tuple<bigint>;
@@ -59,6 +61,7 @@ interface Tuples {
59
61
 
60
62
  interface IECCurve {
61
63
  'θ': bigint;
64
+ 'a': bigint;
62
65
  'b': bigint;
63
66
  bitlen: bigint;
64
67
  formula: ECformula;
@@ -72,6 +75,8 @@ interface Iellipticcurves<a> {
72
75
  constructor:Function;
73
76
  add:(a:Coordinate,b:Coordinate)=>Coordinate;
74
77
  double:(a:Coordinate)=>Coordinate;
78
+ get p(): Coordinate;
79
+ get q(): Coordinate;
75
80
  }
76
81
 
77
82
  interface Icurve extends IECCurve {
@@ -113,6 +118,7 @@ class Point implements Ipoint {
113
118
  class Curve<a> implements Icurve {
114
119
  #E: bigint;
115
120
  public θ: bigint;
121
+ public a: bigint;
116
122
  public b: bigint;
117
123
  public p: Point;
118
124
  public q: Point;
@@ -127,6 +133,8 @@ class Curve<a> implements Icurve {
127
133
  || fail(m);
128
134
  this.θ = curve.θ
129
135
  || fail(m);
136
+ this.a = curve.a
137
+ || fail(m);
130
138
  this.b = curve.b
131
139
  || fail(m);
132
140
  this.bitlen = curve.bitlen
@@ -140,24 +148,113 @@ class Curve<a> implements Icurve {
140
148
  }
141
149
  }
142
150
 
143
- abstract class EllipticCurves<a> implements Iellipticcurves<a> {
151
+ abstract class EllipticCurves<a extends GF> implements Iellipticcurves<a> {
144
152
  public abstract backend: a;
145
153
  private curve: Curve<a>;
146
154
 
147
- protected addpoints(a:Coordinate,b:Coordinate): Coordinate {
148
- return a;
155
+ private eq(p:Point,q:Point): boolean {
156
+ return (
157
+ (!p || !q) ?
158
+ fail() :
159
+ (p['∞'] && q['∞']) ?
160
+ true :
161
+ (p['∞'] && !q['∞']) ?
162
+ false :
163
+ (!p['∞'] && q['∞']) ?
164
+ false :
165
+ ((p.x === q.x) && (p.y === q.y))
166
+ );
167
+ }
168
+
169
+ private isprimefield(f:GF): f is PrimeField {
170
+ return (f instanceof PrimeField);
171
+ }
172
+
173
+ private slope(p_:Point,q_:Point): (a:bigint,p:bigint)=>bigint {
174
+ let f:a;
175
+ const { x:x1,y:y1 } = p_;
176
+ const { x:x2,y:y2 } = q_;
177
+
178
+ if (!this.isprimefield(this.backend))
179
+ return fail();
180
+ else
181
+ f = this.backend;
182
+
183
+ return (this.eq(p_,q_)) ?
184
+ (a:bigint,p:bigint): bigint =>
185
+ (f.mul(
186
+ f.add(a,
187
+ f.mul(3n, f.exp(x1, 2n))
188
+ ),
189
+ f.inv(f.mul(y1, 2n))
190
+ ) % p) :
191
+ (a:bigint,p:bigint): bigint =>
192
+ (f.mul(
193
+ f.sub(y2, y1),
194
+ f.inv(f.sub(x2, x1))
195
+ ) % p);
196
+ }
197
+
198
+ private isinfinity(p:Point): infinity {
199
+ return false;
200
+ }
201
+
202
+ protected addpoints(p:Coordinate,q:Coordinate): Coordinate {
203
+ let s:Slope;
204
+ let p_:Point;
205
+ let q_:Point;
206
+ let x:bigint;
207
+ let y:bigint;
208
+ let t:Point;
209
+ let mt:Coordinate;
210
+ let Δx:bigint, Δy:bigint;
211
+ let f:a;
212
+
213
+ if (!this.isprimefield(this.backend))
214
+ return fail();
215
+ else
216
+ f = this.backend;
217
+
218
+ if (empty(p) && empty(q))
219
+ return <Maybe<Point>>nothing();
220
+ else if (empty(p))
221
+ return <Maybe<Point>>just(q as unknown as Point);
222
+ else if (empty(q))
223
+ return <Maybe<Point>>just(p as unknown as Point);
224
+ else
225
+ [p_, q_] = [fold(p), fold(q)];
226
+
227
+ const { x:x1,y:y1 } = p_;
228
+ const { x:x2,y:y2 } = q_;
229
+
230
+ s = this.slope(p_, q_)(this.curve.a, this.backend.p);
231
+ Δx = f.sub(x1, x2);
232
+ x = (f.sub(s, f.mul(s, s)) % this.backend.p);
233
+ Δy = f.sub(x1, x);
234
+ y = (f.sub(
235
+ f.mul(s, Δy),
236
+ y1
237
+ ) % this.backend.p);
238
+
239
+ t = new Point([x,y]);
240
+ if (this.isinfinity(t))
241
+ mt = nothing();
242
+ else
243
+ mt = just(t);
244
+
245
+ return mt;
149
246
  }
150
247
 
151
248
  protected doublepoint(a:Coordinate): Coordinate {
152
- return a;
249
+ return this.add(a, a);
153
250
  }
154
251
 
155
252
  public add(a:Coordinate,b:Coordinate): Coordinate {
156
- if ((a === 𝒪) && (b === 𝒪))
253
+ if (empty(a) && empty(b))
157
254
  return <Maybe<Point>>nothing();
158
- else if (a === 𝒪)
255
+ else if (empty(a))
159
256
  return <Maybe<Point>>just(b as unknown as Point);
160
- else if (b === 𝒪)
257
+ else if (empty(b))
161
258
  return <Maybe<Point>>just(a as unknown as Point);
162
259
  else
163
260
  return <Maybe<Point>>this.addpoints(a,b);
@@ -170,6 +267,29 @@ abstract class EllipticCurves<a> implements Iellipticcurves<a> {
170
267
  return this.doublepoint(a);
171
268
  }
172
269
 
270
+ public get p(): Coordinate {
271
+ let p:Point;
272
+ let mp:Coordinate;
273
+
274
+ p = this.curve.p;
275
+ mp = (p['∞']) ?
276
+ nothing() :
277
+ just(p);
278
+
279
+ return mp;
280
+ }
281
+ public get q(): Coordinate {
282
+ let q:Point;
283
+ let mq:Coordinate;
284
+
285
+ q = this.curve.q;
286
+ mq = (q['∞']) ?
287
+ nothing() :
288
+ just(q);
289
+
290
+ return mq;
291
+ }
292
+
173
293
  constructor(curve:ECCurve) {
174
294
  this.curve = new Curve<a>(curve);
175
295
 
@@ -191,3 +311,4 @@ class ecℤp extends EllipticCurves<PrimeField>
191
311
  }
192
312
 
193
313
  export { ecℤp, p256 };
314
+ export type { Point, Coordinate };
package/main.ts CHANGED
@@ -1,23 +1,39 @@
1
1
  /* main.ts */
2
2
  import { Polynomial } from './polynomial.js';
3
3
  import { Util,PrimeField } from './galois.js';
4
- import { ecℤp, p256 } from './ellipticcurves.js';
4
+ import { ecℤp, p256, type Coordinate, type Point } from './ellipticcurves.js';
5
5
  import { empty, fold, just, nothing } from './maybe.js';
6
6
  import type { Maybe, Just, Nothing } from './maybe.js';
7
7
 
8
8
  let log:(...x:any[])=>void;
9
9
  log = console.log;
10
10
 
11
- let foo:Maybe<string>;
12
- foo = just(1..toString());
13
- log(empty(foo));
11
+ let field:PrimeField;
12
+ let curve:ecℤp;
13
+ let mp:Coordinate;
14
+ let p:Point;
15
+ let q:Point;
14
16
 
15
- // let field:PrimeField;
16
- // let curve:ecℤp;
17
-
18
- // field = new PrimeField(p256().θ, p256().bitlen);
17
+ field = new PrimeField(p256().θ, p256().bitlen);
19
18
  // log(field);
20
- // curve = new ecℤp(field, p256());
19
+ curve = new ecℤp(field, p256());
21
20
  // log(curve);
22
21
 
22
+ // mp = curve.add(curve.p, curve.q);
23
+ mp = curve.q;
24
+ q = fold(mp);
25
+ p = fold(curve.p);
26
+ do {
27
+ mp = curve.double(mp);
28
+ if (empty(mp)) {
29
+ log(mp);
30
+ break;
31
+ }
32
+ else {
33
+ p = fold(mp);
34
+ log(p);
35
+ }
36
+ } while (p.x !== q.x);
37
+ log(q);
38
+
23
39
  export { Polynomial,Util,PrimeField,ecℤp,p256 };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "finitefields",
3
3
  "type": "module",
4
- "version": "0.0.9",
4
+ "version": "0.0.10",
5
5
  "description": "Galois/Finite field crypto and raw elliptic curves",
6
6
  "main": "main.js",
7
7
  "scripts": {