1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | 'use strict'
|
9 |
|
10 | import { Bn } from './bn'
|
11 | import { Point } from './point'
|
12 | import { Constants } from './constants'
|
13 | import { Base58Check } from './base-58-check'
|
14 | import { Random } from './random'
|
15 | import { Struct } from './struct'
|
16 |
|
17 | class PrivKey extends Struct {
|
18 | constructor (bn, compressed, constants = null) {
|
19 | super({ bn, compressed })
|
20 | constants = constants || Constants.Default.PrivKey
|
21 | this.Constants = constants
|
22 | }
|
23 |
|
24 | fromJSON (json) {
|
25 | this.fromHex(json)
|
26 | return this
|
27 | }
|
28 |
|
29 | toJSON () {
|
30 | return this.toHex()
|
31 | }
|
32 |
|
33 | fromRandom () {
|
34 | let privBuf, bn, condition
|
35 |
|
36 | do {
|
37 | privBuf = Random.getRandomBuffer(32)
|
38 | bn = new Bn().fromBuffer(privBuf)
|
39 | condition = bn.lt(Point.getN())
|
40 | } while (!condition)
|
41 |
|
42 | this.fromObject({
|
43 | bn: bn,
|
44 | compressed: true
|
45 | })
|
46 | return this
|
47 | }
|
48 |
|
49 | static fromRandom () {
|
50 | return new this().fromRandom()
|
51 | }
|
52 |
|
53 | toBuffer () {
|
54 | let compressed = this.compressed
|
55 |
|
56 | if (compressed === undefined) {
|
57 | compressed = true
|
58 | }
|
59 |
|
60 | const privBuf = this.bn.toBuffer({ size: 32 })
|
61 | let buf
|
62 | if (compressed) {
|
63 | buf = Buffer.concat([
|
64 | Buffer.from([this.Constants.versionByteNum]),
|
65 | privBuf,
|
66 | Buffer.from([0x01])
|
67 | ])
|
68 | } else {
|
69 | buf = Buffer.concat([Buffer.from([this.Constants.versionByteNum]), privBuf])
|
70 | }
|
71 |
|
72 | return buf
|
73 | }
|
74 |
|
75 | fromBuffer (buf) {
|
76 | if (buf.length === 1 + 32 + 1 && buf[1 + 32 + 1 - 1] === 1) {
|
77 | this.compressed = true
|
78 | } else if (buf.length === 1 + 32) {
|
79 | this.compressed = false
|
80 | } else {
|
81 | throw new Error(
|
82 | 'Length of privKey buffer must be 33 (uncompressed pubKey) or 34 (compressed pubKey)'
|
83 | )
|
84 | }
|
85 |
|
86 | if (buf[0] !== this.Constants.versionByteNum) {
|
87 | throw new Error('Invalid versionByteNum byte')
|
88 | }
|
89 |
|
90 | return this.fromBn(new Bn().fromBuffer(buf.slice(1, 1 + 32)))
|
91 | }
|
92 |
|
93 | toBn () {
|
94 | return this.bn
|
95 | }
|
96 |
|
97 | fromBn (bn) {
|
98 | this.bn = bn
|
99 | return this
|
100 | }
|
101 |
|
102 | static fromBn (bn) {
|
103 | return new this().fromBn(bn)
|
104 | }
|
105 |
|
106 | validate () {
|
107 | if (!this.bn.lt(Point.getN())) {
|
108 | throw new Error('Number must be less than N')
|
109 | }
|
110 | if (typeof this.compressed !== 'boolean') {
|
111 | throw new Error(
|
112 | 'Must specify whether the corresponding public key is compressed or not (true or false)'
|
113 | )
|
114 | }
|
115 | return this
|
116 | }
|
117 |
|
118 | |
119 |
|
120 |
|
121 | toWif () {
|
122 | return Base58Check.encode(this.toBuffer())
|
123 | }
|
124 |
|
125 | |
126 |
|
127 |
|
128 | fromWif (str) {
|
129 | return this.fromBuffer(Base58Check.decode(str))
|
130 | }
|
131 |
|
132 | static fromWif (str) {
|
133 | return new this().fromWif(str)
|
134 | }
|
135 |
|
136 | toString () {
|
137 | return this.toWif()
|
138 | }
|
139 |
|
140 | fromString (str) {
|
141 | return this.fromWif(str)
|
142 | }
|
143 | }
|
144 |
|
145 | PrivKey.Mainnet = class extends PrivKey {
|
146 | constructor (bn, compressed) {
|
147 | super(bn, compressed, Constants.Mainnet.PrivKey)
|
148 | }
|
149 | }
|
150 |
|
151 | PrivKey.Testnet = class extends PrivKey {
|
152 | constructor (bn, compressed) {
|
153 | super(bn, compressed, Constants.Testnet.PrivKey)
|
154 | }
|
155 | }
|
156 |
|
157 | export { PrivKey }
|