@@ -11,70 +11,46 @@ var ECPointFp = require('./jsbn/ec').ECPointFp;
1111var ecparams = sec ( "secp256k1" ) ;
1212
1313// input can be nothing, array of bytes, hex string, or base58 string
14- var ECKey = function ( input ) {
15- if ( ! ( this instanceof ECKey ) ) {
16- return new ECKey ( input ) ;
17- }
18-
19- this . compressed = ! ! ECKey . compressByDefault ;
20-
14+ var ECKey = function ( input , compressed ) {
15+ if ( ! ( this instanceof ECKey ) ) { return new ECKey ( input ) ; }
2116 if ( ! input ) {
2217 // Generate new key
2318 var n = ecparams . getN ( ) ;
2419 this . priv = ecdsa . getBigRandom ( n ) ;
20+ this . compressed = compressed || false ;
2521 }
26- else this . import ( input )
27- } ;
28-
29- /**
30- * Whether public keys should be returned compressed by default.
31- */
32- ECKey . compressByDefault = false ;
33-
34- /**
35- * Set whether the public key should be returned compressed or not.
36- */
37- ECKey . prototype . setCompressed = function ( v ) {
38- this . compressed = ! ! v ;
22+ else this . import ( input , compressed )
3923} ;
4024
41- /**
42- * Return public key in DER encoding.
43- */
44- ECKey . prototype . getPub = function ( ) {
45- return this . getPubPoint ( ) . getEncoded ( this . compressed ) ;
25+ ECKey . prototype . import = function ( input , compressed ) {
26+ function has ( li , v ) { return li . indexOf ( v ) >= 0 }
27+ function fromBin ( x ) { return BigInteger . fromByteArrayUnsigned ( x ) }
28+ this . priv =
29+ input instanceof ECKey ? input . priv
30+ : input instanceof BigInteger ? input . mod ( ecparams . getN ( ) )
31+ : util . isArray ( input ) ? fromBin ( input . slice ( 0 , 32 ) )
32+ : typeof input != "string" ? null
33+ : input . length == 51 && input [ 0 ] == '5' ? fromBin ( base58 . checkDecode ( input ) )
34+ : input . length == 52 && has ( 'LK' , input [ 0 ] ) ? fromBin ( base58 . checkDecode ( input ) )
35+ : has ( [ 64 , 65 ] , input . length ) ? fromBin ( conv . hexToBytes ( input . slice ( 0 , 64 ) ) )
36+ : null
37+
38+ this . compressed =
39+ arguments . length > 1 ? compressed
40+ : input instanceof ECKey ? input . compressed
41+ : input instanceof BigInteger ? false
42+ : util . isArray ( input ) ? false
43+ : typeof input != "string" ? null
44+ : input . length == 51 && input [ 0 ] == '5' ? false
45+ : input . length == 52 && has ( 'LK' , input [ 0 ] ) ? true
46+ : input . length == 64 ? false
47+ : input . length == 65 ? true
48+ : null
4649} ;
4750
48- /**
49- * Return public point as ECPoint object.
50- */
51- ECKey . prototype . getPubPoint = function ( ) {
52- if ( ! this . pub ) this . pub = ecparams . getG ( ) . multiply ( this . priv ) ;
53- return this . pub ;
54- } ;
55-
56- /**
57- * Get the pubKeyHash for this key.
58- *
59- * This is calculated as RIPE160(SHA256([encoded pubkey])) and returned as
60- * a byte array.
61- */
62- ECKey . prototype . getPubKeyHash = function ( ) {
63- if ( this . pubKeyHash ) return this . pubKeyHash ;
64- return this . pubKeyHash = util . sha256ripe160 ( this . getPub ( ) ) ;
65- } ;
66-
67- ECKey . prototype . getBitcoinAddress = function ( version ) {
68- var hash = this . getPubKeyHash ( ) ;
69- var addr = new Address ( hash , version ) ;
70- return addr ;
71- } ;
72-
73- ECKey . prototype . setPub = function ( pub ) {
74- this . pub = ECPointFp . decodeFrom ( ecparams . getCurve ( ) , pub ) ;
75- this . compressed = ( pub [ 0 ] < 4 )
76- return this
77- } ;
51+ ECKey . prototype . getPub = function ( ) {
52+ return ECPubKey ( ecparams . getG ( ) . multiply ( this . priv ) , this . compressed )
53+ }
7854
7955ECKey . prototype . export = function ( format ) {
8056 var bytes = this . priv . toByteArrayUnsigned ( ) ;
@@ -86,12 +62,66 @@ ECKey.prototype.export = function (format) {
8662 : format === "hex" ? conv . bytesToHex ( bytes )
8763 : bytes
8864} ;
89- ECKey . prototype . getExportedPrivateKey = ECKey . prototype . export ;
9065
9166ECKey . prototype . toString = function ( format ) {
9267 return '' + this . export ( format )
9368}
9469
70+ ECKey . prototype . getBitcoinAddress = function ( v ) {
71+ return this . getPub ( ) . getBitcoinAddress ( v )
72+ }
73+
74+ ECKey . prototype . add = function ( key ) {
75+ return ECKey ( this . priv . add ( ECKey ( key ) . priv ) , this . compressed )
76+ }
77+
78+ ECKey . prototype . multiply = function ( key ) {
79+ return ECKey ( this . priv . multiply ( ECKey ( key ) . priv ) , this . compressed )
80+ }
81+
82+ var ECPubKey = function ( input , compressed ) {
83+
84+ if ( ! ( this instanceof ECPubKey ) ) { return new ECPubKey ( input , compressed ) ; }
85+
86+ var decode = function ( x ) { return ECPointFp . decodeFrom ( ecparams . getCurve ( ) , x ) }
87+ this . pub =
88+ input instanceof ECPointFp ? input
89+ : input instanceof ECKey ? ecparams . getG ( ) . multiply ( input . priv )
90+ : input instanceof ECPubKey ? input . pub
91+ : typeof input == "string" ? decode ( conv . hexToBytes ( input ) )
92+ : util . isArray ( input ) ? decode ( input )
93+ : ecparams . getG ( ) . multiply ( ecdsa . getBigRandom ( ecparams . getN ( ) ) )
94+
95+ this . compressed =
96+ arguments . length > 1 ? compressed
97+ : input instanceof ECPointFp ? input . compressed
98+ : input instanceof ECPubKey ? input . compressed
99+ : ( this . pub [ 0 ] < 4 )
100+
101+ }
102+
103+ ECPubKey . prototype . add = function ( key ) {
104+ return ECPubKey ( this . pub . add ( ECPubKey ( key ) . pub ) , this . compressed )
105+ }
106+
107+ ECPubKey . prototype . multiply = function ( key ) {
108+ return ECPubKey ( this . pub . multiply ( ECKey ( key ) . priv ) , this . compressed )
109+ }
110+
111+ ECPubKey . prototype . export = function ( formt ) {
112+ var o = this . pub . getEncoded ( this . compressed )
113+ return formt == 'hex' ? conv . bytesToHex ( o ) : o ;
114+ }
115+
116+ ECPubKey . prototype . toString = function ( format ) {
117+ return '' + this . export ( format )
118+ }
119+
120+ ECPubKey . prototype . getBitcoinAddress = function ( v ) {
121+ return new Address ( util . sha256ripe160 ( this . export ( ) ) , version ) ;
122+ }
123+
124+
95125ECKey . prototype . sign = function ( hash ) {
96126 return ecdsa . sign ( hash , this . priv ) ;
97127} ;
@@ -103,38 +133,6 @@ ECKey.prototype.verify = function (hash, sig) {
103133/**
104134 * Parse an exported private key contained in a string.
105135 */
106- ECKey . prototype . import = function ( input ) {
107- if ( input instanceof ECKey ) {
108- this . priv = input . priv ;
109- this . compressed = input . compressed ;
110- }
111- else if ( input instanceof BigInteger ) {
112- // Input is a private key value
113- this . priv = input ;
114- this . compressed = ECKey . compressByDefault ;
115- }
116- else if ( util . isArray ( input ) ) {
117- // Prepend zero byte to prevent interpretation as negative integer
118- this . priv = BigInteger . fromByteArrayUnsigned ( input . slice ( 0 , 32 ) ) ;
119- this . compressed = ( input . length == 33 ) ;
120- }
121- else if ( "string" == typeof input ) {
122- if ( input . length == 51 && input [ 0 ] == '5' ) {
123- // Base58 encoded private key
124- this . priv = BigInteger . fromByteArrayUnsigned ( base58 . checkDecode ( input ) ) ;
125- this . compressed = false ;
126- }
127- else if ( input . length == 52 && ( input [ 0 ] === 'K' || input [ 0 ] === 'L' ) ) {
128- // Base58 encoded private key
129- this . priv = BigInteger . fromByteArrayUnsigned ( base58 . checkDecode ( input ) ) ;
130- this . compressed = true ;
131- }
132- else if ( input . length >= 64 ) {
133- // hex string?
134- this . priv = BigInteger . fromByteArrayUnsigned ( conv . hexToBytes ( input . slice ( 0 , 64 ) ) ) ;
135- this . compressed = ( input . length == 66 )
136- }
137- }
138- } ;
139136
140- module . exports = ECKey ;
137+
138+ module . exports = { ECKey : ECKey , ECPubKey : ECPubKey } ;
0 commit comments