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