UNPKG

3.35 kBJavaScriptView Raw
1'use strict';
2Object.defineProperty(exports, '__esModule', { value: true });
3const NETWORKS = require('./networks');
4const types = require('./types');
5const ecc = require('tiny-secp256k1');
6const randomBytes = require('randombytes');
7const typeforce = require('typeforce');
8const wif = require('wif');
9const isOptions = typeforce.maybe(
10 typeforce.compile({
11 compressed: types.maybe(types.Boolean),
12 network: types.maybe(types.Network),
13 }),
14);
15class 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 // if first try is lowR, skip the loop
47 // for second try and on, add extra entropy counting up
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}
60function 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}
67exports.fromPrivateKey = fromPrivateKey;
68function fromPublicKey(buffer, options) {
69 typeforce(ecc.isPoint, buffer);
70 typeforce(isOptions, options);
71 return new ECPair(undefined, buffer, options);
72}
73exports.fromPublicKey = fromPublicKey;
74function fromWIF(wifString, network) {
75 const decoded = wif.decode(wifString);
76 const version = decoded.version;
77 // list of networks?
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 // otherwise, assume a network object (or default to bitcoin)
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}
95exports.fromWIF = fromWIF;
96function 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}
107exports.makeRandom = makeRandom;