/
index.ts
62 lines (53 loc) · 1.79 KB
/
index.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
import { modInv } from "bigint-crypto-utils";
import BN from "bn.js";
import { curve, ec as EllipticCurve } from "elliptic";
import { array2BigInt, bigInt2Array, bigInt2Buffer } from "../../util";
export type PartyOptions = {
readonly curveName?: string;
};
const defaultOptions = {
curveName: "p256",
};
export class Party {
private readonly ec: EllipticCurve;
private readonly curve: curve.short;
private readonly privateKey: BN;
private readonly privateKeyInverse: BN;
constructor(options: PartyOptions = {}) {
const { curveName } = { ...defaultOptions, ...options };
this.ec = new EllipticCurve(curveName);
this.curve = this.ec.curve as curve.short;
const keyPair = this.ec.genKeyPair();
this.privateKey = keyPair.getPrivate();
this.privateKeyInverse = new BN(
bigInt2Buffer(modInv(BigInt(this.privateKey), BigInt(this.curve.n))),
);
}
public raise(g: bigint, shouldHash = false): bigint {
const point = shouldHash
? this.hashToPoint(bigInt2Array(g))
: this.curve.pointFromX(bigInt2Array(g));
const multiplicationPoint = point.mul(this.privateKey);
return BigInt(multiplicationPoint.getX());
}
public raiseInverse(g: bigint): bigint {
const point = this.curve.pointFromX(bigInt2Array(g));
const multiplicationPoint = point.mul(this.privateKeyInverse);
return BigInt(multiplicationPoint.getX());
}
public get intermediateValue(): bigint {
return this.raise(BigInt(this.ec.g.x), true);
}
private hashToPoint(input: readonly number[]): curve.short.ShortPoint {
const hashOutput = this.ec.hash().update(input).digest();
const x = array2BigInt(hashOutput) % BigInt(this.curve.p);
try {
return this.curve.pointFromX(bigInt2Array(x));
} catch (error) {
if (/invalid point/i.test(error)) {
return this.hashToPoint(bigInt2Array(x));
}
throw error;
}
}
}