UNPKG

3.15 kBJavaScriptView Raw
1var baddress = require('./address')
2var bcrypto = require('./crypto')
3var ecdsa = require('./ecdsa')
4var randomBytes = require('randombytes')
5var typeforce = require('typeforce')
6var types = require('./types')
7var wif = require('wif')
8
9var NETWORKS = require('./networks')
10var BigInteger = require('bigi')
11
12var ecurve = require('ecurve')
13var secp256k1 = ecdsa.__curve
14
15function ECPair (d, Q, options) {
16 if (options) {
17 typeforce({
18 compressed: types.maybe(types.Boolean),
19 network: types.maybe(types.Network)
20 }, options)
21 }
22
23 options = options || {}
24
25 if (d) {
26 if (d.signum() <= 0) throw new Error('Private key must be greater than 0')
27 if (d.compareTo(secp256k1.n) >= 0) throw new Error('Private key must be less than the curve order')
28 if (Q) throw new TypeError('Unexpected publicKey parameter')
29
30 this.d = d
31 } else {
32 typeforce(types.ECPoint, Q)
33
34 this.__Q = Q
35 }
36
37 this.compressed = options.compressed === undefined ? true : options.compressed
38 this.network = options.network || NETWORKS.bitcoin
39}
40
41Object.defineProperty(ECPair.prototype, 'Q', {
42 get: function () {
43 if (!this.__Q && this.d) {
44 this.__Q = secp256k1.G.multiply(this.d)
45 }
46
47 return this.__Q
48 }
49})
50
51ECPair.fromPublicKeyBuffer = function (buffer, network) {
52 var Q = ecurve.Point.decodeFrom(secp256k1, buffer)
53
54 return new ECPair(null, Q, {
55 compressed: Q.compressed,
56 network: network
57 })
58}
59
60ECPair.fromWIF = function (string, network) {
61 var decoded = wif.decode(string)
62 var version = decoded.version
63
64 // [network, ...]
65 if (types.Array(network)) {
66 network = network.filter(function (network) {
67 return version === network.wif
68 }).pop()
69
70 if (!network) throw new Error('Unknown network version')
71
72 // network
73 } else {
74 network = network || NETWORKS.bitcoin
75
76 if (version !== network.wif) throw new Error('Invalid network version')
77 }
78
79 var d = BigInteger.fromBuffer(decoded.privateKey)
80
81 return new ECPair(d, null, {
82 compressed: decoded.compressed,
83 network: network
84 })
85}
86
87ECPair.makeRandom = function (options) {
88 options = options || {}
89
90 var rng = options.rng || randomBytes
91
92 var d
93 do {
94 var buffer = rng(32)
95 typeforce(types.Buffer256bit, buffer)
96
97 d = BigInteger.fromBuffer(buffer)
98 } while (d.signum() <= 0 || d.compareTo(secp256k1.n) >= 0)
99
100 return new ECPair(d, null, options)
101}
102
103ECPair.prototype.getAddress = function () {
104 return baddress.toBase58Check(bcrypto.hash160(this.getPublicKeyBuffer()), this.getNetwork().pubKeyHash)
105}
106
107ECPair.prototype.getNetwork = function () {
108 return this.network
109}
110
111ECPair.prototype.getPublicKeyBuffer = function () {
112 return this.Q.getEncoded(this.compressed)
113}
114
115ECPair.prototype.sign = function (hash) {
116 if (!this.d) throw new Error('Missing private key')
117
118 return ecdsa.sign(hash, this.d)
119}
120
121ECPair.prototype.toWIF = function () {
122 if (!this.d) throw new Error('Missing private key')
123
124 return wif.encode(this.network.wif, this.d.toBuffer(32), this.compressed)
125}
126
127ECPair.prototype.verify = function (hash, signature) {
128 return ecdsa.verify(hash, signature, this.Q)
129}
130
131module.exports = ECPair