-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathomnichainCrypto.ts
112 lines (90 loc) · 3.61 KB
/
omnichainCrypto.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import * as elliptic from 'elliptic';
export class OmnichainCrypto {
pubKey: Buffer;
priKey: Buffer;
hashFun: (msg: string| Buffer) => Buffer;
ec: any;
constructor(hashFun: (msg: string| Buffer) => Buffer, curveName: string, keyPair?: [string, string]) {
this.hashFun = hashFun;
this.ec = new elliptic.ec(curveName);
if (typeof keyPair! == 'undefined') {
const keyPair = this.ec.genKeyPair();
this.pubKey = Buffer.from(keyPair.getPublic('hex'), 'hex');
this.priKey = Buffer.from(keyPair.getPrivate('hex'), 'hex');
} else {
this.pubKey = Buffer.from(keyPair[0], 'hex');
this.priKey = Buffer.from(keyPair[1], 'hex');
}
if (this.pubKey.length === 64) {
this.pubKey = Buffer.concat([Buffer.from([4]), this.pubKey]);
} else if (this.pubKey.length === 33 || this.pubKey.length === 0) {
// do nothing
} else {
throw("Invalid public key!");
}
if ((this.priKey.length != 0) && (this.priKey.length != 32)) {
throw("Invalid private key!");
}
}
sign2buffer= (msg: string | Buffer): Buffer => {
if (this.priKey.length != 32) {
throw("Invalid private key to sign!");
}
const key = this.ec.keyFromPrivate(this.priKey);
const sig = key.sign(this.hashFun(msg));
const n = 32;
const r = sig.r.toArrayLike(Buffer, 'be', n);
const s = sig.s.toArrayLike(Buffer, 'be', n);
return Buffer.concat([r, s]);
};
sign2hexstring = (msg: string | Buffer): string => {
return this.sign2buffer(msg).toString('hex');
};
sign2bufferrecovery = (msg: string | Buffer): Buffer => {
if (this.priKey.length != 32) {
throw("Invalid private key to sign!");
}
const key = this.ec.keyFromPrivate(this.priKey);
const sig = key.sign(this.hashFun(msg));
const n = 32;
const r = sig.r.toArrayLike(Buffer, 'be', n);
const s = sig.s.toArrayLike(Buffer, 'be', n);
return Buffer.concat([r, s, Buffer.from([sig.recoveryParam + 27])]);
};
sign2hexstringrecovery = (msg: string | Buffer): string => {
return this.sign2bufferrecovery(msg).toString('hex');
}
sign = (msg: string | Buffer): elliptic.ec.Signature => {
if (this.priKey.length != 32) {
throw("Invalid private key to sign!");
}
const key = this.ec.keyFromPrivate(this.priKey);
const sig = key.sign(this.hashFun(msg));
return sig;
}
verify = (msg: string | Buffer,
signature: string | elliptic.ec.Signature) => {
if ((this.pubKey.length != 65) && (this.pubKey.length != 33)) {
throw("Invalid public key to verify!");
}
const msgHash = this.hashFun(msg);
const key = this.ec.keyFromPublic(this.pubKey);
return key.verify(msgHash, signature, this.pubKey);
}
}
export async function publicKeyCompress(pubKey: string) {
if (pubKey.length == 128) {
const y = "0x" + pubKey.substring(64);
// console.log(y);
const _1n = BigInt(1);
let flag = BigInt(y) & _1n ? '03' : '02';
// console.log(flag);
const x = Buffer.from(pubKey.substring(0, 64), "hex");
const finalX = Buffer.concat([Buffer.from(flag, 'hex'), x]);
const finalXArray = new Uint8Array(finalX);
// console.log("Public Key: \n"+ finalXArray);
return finalXArray;
} else {
throw("Invalid public key length!" + pubKey.length);
}
}