1 | 'use strict';
|
2 | Object.defineProperty(exports, '__esModule', { value: true });
|
3 | const NETWORKS = require('./networks');
|
4 | const types = require('./types');
|
5 | const ecc = require('tiny-secp256k1');
|
6 | const randomBytes = require('randombytes');
|
7 | const typeforce = require('typeforce');
|
8 | const wif = require('wif');
|
9 | const isOptions = typeforce.maybe(
|
10 | typeforce.compile({
|
11 | compressed: types.maybe(types.Boolean),
|
12 | network: types.maybe(types.Network),
|
13 | }),
|
14 | );
|
15 | class ECPair {
|
16 | constructor(__D, __Q, options) {
|
17 | this.__D = __D;
|
18 | this.__Q = __Q;
|
19 | this.lowR = false;
|
20 | if (options === undefined) options = {};
|
21 | this.compressed =
|
22 | options.compressed === undefined ? true : options.compressed;
|
23 | this.network = options.network || NETWORKS.bitcoin;
|
24 | if (__Q !== undefined) this.__Q = ecc.pointCompress(__Q, this.compressed);
|
25 | }
|
26 | get privateKey() {
|
27 | return this.__D;
|
28 | }
|
29 | get publicKey() {
|
30 | if (!this.__Q) this.__Q = ecc.pointFromScalar(this.__D, this.compressed);
|
31 | return this.__Q;
|
32 | }
|
33 | toWIF() {
|
34 | if (!this.__D) throw new Error('Missing private key');
|
35 | return wif.encode(this.network.wif, this.__D, this.compressed);
|
36 | }
|
37 | sign(hash, lowR) {
|
38 | if (!this.__D) throw new Error('Missing private key');
|
39 | if (lowR === undefined) lowR = this.lowR;
|
40 | if (lowR === false) {
|
41 | return ecc.sign(hash, this.__D);
|
42 | } else {
|
43 | let sig = ecc.sign(hash, this.__D);
|
44 | const extraData = Buffer.alloc(32, 0);
|
45 | let counter = 0;
|
46 |
|
47 |
|
48 | while (sig[0] > 0x7f) {
|
49 | counter++;
|
50 | extraData.writeUIntLE(counter, 0, 6);
|
51 | sig = ecc.signWithEntropy(hash, this.__D, extraData);
|
52 | }
|
53 | return sig;
|
54 | }
|
55 | }
|
56 | verify(hash, signature) {
|
57 | return ecc.verify(hash, this.publicKey, signature);
|
58 | }
|
59 | }
|
60 | function fromPrivateKey(buffer, options) {
|
61 | typeforce(types.Buffer256bit, buffer);
|
62 | if (!ecc.isPrivate(buffer))
|
63 | throw new TypeError('Private key not in range [1, n)');
|
64 | typeforce(isOptions, options);
|
65 | return new ECPair(buffer, undefined, options);
|
66 | }
|
67 | exports.fromPrivateKey = fromPrivateKey;
|
68 | function fromPublicKey(buffer, options) {
|
69 | typeforce(ecc.isPoint, buffer);
|
70 | typeforce(isOptions, options);
|
71 | return new ECPair(undefined, buffer, options);
|
72 | }
|
73 | exports.fromPublicKey = fromPublicKey;
|
74 | function fromWIF(wifString, network) {
|
75 | const decoded = wif.decode(wifString);
|
76 | const version = decoded.version;
|
77 |
|
78 | if (types.Array(network)) {
|
79 | network = network
|
80 | .filter(x => {
|
81 | return version === x.wif;
|
82 | })
|
83 | .pop();
|
84 | if (!network) throw new Error('Unknown network version');
|
85 |
|
86 | } else {
|
87 | network = network || NETWORKS.bitcoin;
|
88 | if (version !== network.wif) throw new Error('Invalid network version');
|
89 | }
|
90 | return fromPrivateKey(decoded.privateKey, {
|
91 | compressed: decoded.compressed,
|
92 | network: network,
|
93 | });
|
94 | }
|
95 | exports.fromWIF = fromWIF;
|
96 | function makeRandom(options) {
|
97 | typeforce(isOptions, options);
|
98 | if (options === undefined) options = {};
|
99 | const rng = options.rng || randomBytes;
|
100 | let d;
|
101 | do {
|
102 | d = rng(32);
|
103 | typeforce(types.Buffer256bit, d);
|
104 | } while (!ecc.isPrivate(d));
|
105 | return fromPrivateKey(d, options);
|
106 | }
|
107 | exports.makeRandom = makeRandom;
|