1 | var crypto = require('crypto')
|
2 |
|
3 | var ecurve = require('ecurve')
|
4 | var ecparams = ecurve.getCurveByName('secp256k1')
|
5 | var BigInteger = require('bigi')
|
6 |
|
7 | function ECKey (bytes, compressed) {
|
8 | if (!(this instanceof ECKey)) return new ECKey(bytes, compressed)
|
9 |
|
10 | if (typeof compressed == 'boolean')
|
11 | this._compressed = compressed
|
12 | else
|
13 | this._compressed = true
|
14 |
|
15 | if (bytes)
|
16 | this.privateKey = bytes
|
17 | }
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | Object.defineProperty(ECKey.prototype, 'privateKey', {
|
24 | enumerable: true, configurable: true,
|
25 | get: function() {
|
26 | return this.key
|
27 | },
|
28 | set: function(bytes) {
|
29 | var byteArr
|
30 | if (Buffer.isBuffer(bytes)) {
|
31 | this.key = bytes
|
32 | byteArr = [].slice.call(bytes)
|
33 | } else if (bytes instanceof Uint8Array) {
|
34 | byteArr = [].slice.call(bytes)
|
35 | this.key = new Buffer(byteArr)
|
36 | } else if (Array.isArray(bytes)) {
|
37 | byteArr = bytes
|
38 | this.key = new Buffer(byteArr)
|
39 | } else {
|
40 | throw new Error('Invalid type. private key bytes must be either a Buffer, Array, or Uint8Array.')
|
41 | }
|
42 |
|
43 | if (bytes.length != 32)
|
44 | throw new Error("private key bytes must have a length of 32")
|
45 |
|
46 |
|
47 | if (this._compressed)
|
48 | this._exportKey = Buffer.concat([ this.key, new Buffer([0x01]) ])
|
49 | else
|
50 | this._exportKey = Buffer.concat([ this.key ])
|
51 |
|
52 | this.keyBigInteger = BigInteger.fromByteArrayUnsigned(byteArr)
|
53 |
|
54 |
|
55 | this._publicPoint = null
|
56 | this._pubKeyHash = null
|
57 | }
|
58 | })
|
59 |
|
60 | Object.defineProperty(ECKey.prototype, 'privateExportKey', {
|
61 | get: function() {
|
62 | return this._exportKey
|
63 | }
|
64 | })
|
65 |
|
66 | Object.defineProperty(ECKey.prototype, 'publicHash', {
|
67 | get: function() {
|
68 | return this.pubKeyHash
|
69 | }
|
70 | })
|
71 |
|
72 | Object.defineProperty(ECKey.prototype, 'pubKeyHash', {
|
73 | get: function() {
|
74 | if (this._pubKeyHash) return this._pubKeyHash
|
75 | var sha = crypto.createHash('sha256').update(this.publicKey).digest()
|
76 | this._pubKeyHash = crypto.createHash('rmd160').update(sha).digest()
|
77 | return this._pubKeyHash
|
78 | }
|
79 | })
|
80 |
|
81 | Object.defineProperty(ECKey.prototype, 'publicKey', {
|
82 | get: function() {
|
83 | return new Buffer(this.publicPoint.getEncoded(this.compressed))
|
84 | }
|
85 | })
|
86 |
|
87 | Object.defineProperty(ECKey.prototype, 'publicPoint', {
|
88 | get: function() {
|
89 | if (!this._publicPoint) {
|
90 | this._publicPoint = ecparams.params.G.multiply(this.keyBigInteger)
|
91 | }
|
92 | return this._publicPoint
|
93 | }
|
94 | })
|
95 |
|
96 | Object.defineProperty(ECKey.prototype, 'compressed', {
|
97 | get: function() {
|
98 | return this._compressed
|
99 | },
|
100 | set: function(val) {
|
101 | var c = !!val
|
102 | if (c === this._compressed) return
|
103 |
|
104 |
|
105 | var pk = this.privateKey
|
106 | this._compressed = c
|
107 | this.privateKey = pk
|
108 | }
|
109 | })
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 | ECKey.prototype.toString = function (format) {
|
116 | return this.privateKey.toString('hex')
|
117 | }
|
118 |
|
119 | module.exports = ECKey
|
120 |
|