]>
git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/BIP39.git/blob - libs/ethereumjs-util/index.js
1 const createKeccakHash
= require ( 'keccak' )
2 const secp256k1
= require ( 'secp256k1' )
3 const assert
= require ( 'assert' )
4 const rlp
= require ( 'rlp' )
5 const BN
= require ( 'bn.js' )
6 const createHash
= require ( 'create-hash' )
7 const Buffer
= require ( 'safe-buffer' ). Buffer
8 Object
. assign ( exports
, require ( 'ethjs-util' ))
11 * the max integer that this VM can handle (a ```BN```)
12 * @var {BN} MAX_INTEGER
14 exports
. MAX_INTEGER
= new BN ( 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' , 16 )
18 * @var {BN} TWO_POW256
20 exports
. TWO_POW256
= new BN ( '10000000000000000000000000000000000000000000000000000000000000000' , 16 )
23 * Keccak-256 hash of null (a ```String```)
24 * @var {String} KECCAK256_NULL_S
26 exports
. KECCAK256_NULL_S
= 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'
29 * Keccak-256 hash of null (a ```Buffer```)
30 * @var {Buffer} KECCAK256_NULL
32 exports
. KECCAK256_NULL
= Buffer
. from ( exports
. KECCAK256_NULL_S
, 'hex' )
35 * Keccak-256 of an RLP of an empty array (a ```String```)
36 * @var {String} KECCAK256_RLP_ARRAY_S
38 exports
. KECCAK256_RLP_ARRAY_S
= '1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347'
41 * Keccak-256 of an RLP of an empty array (a ```Buffer```)
42 * @var {Buffer} KECCAK256_RLP_ARRAY
44 exports
. KECCAK256_RLP_ARRAY
= Buffer
. from ( exports
. KECCAK256_RLP_ARRAY_S
, 'hex' )
47 * Keccak-256 hash of the RLP of null (a ```String```)
48 * @var {String} KECCAK256_RLP_S
50 exports
. KECCAK256_RLP_S
= '56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421'
53 * Keccak-256 hash of the RLP of null (a ```Buffer```)
54 * @var {Buffer} KECCAK256_RLP
56 exports
. KECCAK256_RLP
= Buffer
. from ( exports
. KECCAK256_RLP_S
, 'hex' )
59 * [`BN`](https://github.com/indutny/bn.js)
65 * [`rlp`](https://github.com/ethereumjs/rlp)
71 * [`secp256k1`](https://github.com/cryptocoinjs/secp256k1-node/)
74 exports
. secp256k1
= secp256k1
77 * Returns a buffer filled with 0s
79 * @param {Number} bytes the number of bytes the buffer should be
82 exports
. zeros = function ( bytes
) {
83 return Buffer
. allocUnsafe ( bytes
). fill ( 0 )
87 * Returns a zero address
91 exports
. zeroAddress = function () {
92 const addressLength
= 20
93 const zeroAddress
= exports
. zeros ( addressLength
)
94 return exports
. bufferToHex ( zeroAddress
)
98 * Left Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes.
99 * Or it truncates the beginning if it exceeds.
101 * @param {Buffer|Array} msg the value to pad
102 * @param {Number} length the number of bytes the output should be
103 * @param {Boolean} [right=false] whether to start padding form the left or right
104 * @return {Buffer|Array}
106 exports
. setLengthLeft
= exports
. setLength = function ( msg
, length
, right
) {
107 const buf
= exports
. zeros ( length
)
108 msg
= exports
. toBuffer ( msg
)
110 if ( msg
. length
< length
) {
114 return msg
. slice ( 0 , length
)
116 if ( msg
. length
< length
) {
117 msg
. copy ( buf
, length
- msg
. length
)
120 return msg
. slice (- length
)
125 * Right Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes.
126 * Or it truncates the beginning if it exceeds.
127 * @param {Buffer|Array} msg the value to pad
128 * @param {Number} length the number of bytes the output should be
129 * @return {Buffer|Array}
131 exports
. setLengthRight = function ( msg
, length
) {
132 return exports
. setLength ( msg
, length
, true )
136 * Trims leading zeros from a `Buffer` or an `Array`
137 * @param {Buffer|Array|String} a
138 * @return {Buffer|Array|String}
140 exports
. unpad
= exports
. stripZeros = function ( a
) {
141 a
= exports
. stripHexPrefix ( a
)
143 while ( a
. length
> 0 && first
. toString () === '0' ) {
150 * Attempts to turn a value into a `Buffer`. As input it supports `Buffer`, `String`, `Number`, null/undefined, `BN` and other objects with a `toArray()` method.
151 * @param {*} v the value
153 exports
. toBuffer = function ( v
) {
154 if (! Buffer
. isBuffer ( v
)) {
155 if ( Array
. isArray ( v
)) {
157 } else if ( typeof v
=== 'string' ) {
158 if ( exports
. isHexString ( v
)) {
159 v
= Buffer
. from ( exports
. padToEven ( exports
. stripHexPrefix ( v
)), 'hex' )
163 } else if ( typeof v
=== 'number' ) {
164 v
= exports
. intToBuffer ( v
)
165 } else if ( v
=== null || v
=== undefined ) {
166 v
= Buffer
. allocUnsafe ( 0 )
167 } else if ( BN
. isBN ( v
)) {
168 v
= v
. toArrayLike ( Buffer
)
169 } else if ( v
. toArray
) {
170 // converts a BN to a Buffer
171 v
= Buffer
. from ( v
. toArray ())
173 throw new Error ( 'invalid type' )
180 * Converts a `Buffer` to a `Number`
181 * @param {Buffer} buf
183 * @throws If the input number exceeds 53 bits.
185 exports
. bufferToInt = function ( buf
) {
186 return new BN ( exports
. toBuffer ( buf
)). toNumber ()
190 * Converts a `Buffer` into a hex `String`
191 * @param {Buffer} buf
194 exports
. bufferToHex = function ( buf
) {
195 buf
= exports
. toBuffer ( buf
)
196 return '0x' + buf
. toString ( 'hex' )
200 * Interprets a `Buffer` as a signed integer and returns a `BN`. Assumes 256-bit numbers.
201 * @param {Buffer} num
204 exports
. fromSigned = function ( num
) {
205 return new BN ( num
). fromTwos ( 256 )
209 * Converts a `BN` to an unsigned integer and returns it as a `Buffer`. Assumes 256-bit numbers.
213 exports
. toUnsigned = function ( num
) {
214 return Buffer
. from ( num
. toTwos ( 256 ). toArray ())
218 * Creates Keccak hash of the input
219 * @param {Buffer|Array|String|Number} a the input data
220 * @param {Number} [bits=256] the Keccak width
223 exports
. keccak = function ( a
, bits
) {
224 a
= exports
. toBuffer ( a
)
225 if (! bits
) bits
= 256
227 return createKeccakHash ( 'keccak' + bits
). update ( a
). digest ()
231 * Creates Keccak-256 hash of the input, alias for keccak(a, 256)
232 * @param {Buffer|Array|String|Number} a the input data
235 exports
. keccak256 = function ( a
) {
236 return exports
. keccak ( a
)
240 * Creates SHA256 hash of the input
241 * @param {Buffer|Array|String|Number} a the input data
244 exports
. sha256 = function ( a
) {
245 a
= exports
. toBuffer ( a
)
246 return createHash ( 'sha256' ). update ( a
). digest ()
250 * Creates RIPEMD160 hash of the input
251 * @param {Buffer|Array|String|Number} a the input data
252 * @param {Boolean} padded whether it should be padded to 256 bits or not
255 exports
. ripemd160 = function ( a
, padded
) {
256 a
= exports
. toBuffer ( a
)
257 const hash
= createHash ( 'rmd160' ). update ( a
). digest ()
258 if ( padded
=== true ) {
259 return exports
. setLength ( hash
, 32 )
266 * Creates SHA-3 hash of the RLP encoded version of the input
267 * @param {Buffer|Array|String|Number} a the input data
270 exports
. rlphash = function ( a
) {
271 return exports
. keccak ( rlp
. encode ( a
))
275 * Checks if the private key satisfies the rules of the curve secp256k1.
276 * @param {Buffer} privateKey
279 exports
. isValidPrivate = function ( privateKey
) {
280 return secp256k1
. privateKeyVerify ( privateKey
)
284 * Checks if the public key satisfies the rules of the curve secp256k1
285 * and the requirements of Ethereum.
286 * @param {Buffer} publicKey The two points of an uncompressed key, unless sanitize is enabled
287 * @param {Boolean} [sanitize=false] Accept public keys in other formats
290 exports
. isValidPublic = function ( publicKey
, sanitize
) {
291 if ( publicKey
. length
=== 64 ) {
292 // Convert to SEC1 for secp256k1
293 return secp256k1
. publicKeyVerify ( Buffer
. concat ([ Buffer
. from ([ 4 ]), publicKey
]))
300 return secp256k1
. publicKeyVerify ( publicKey
)
304 * Returns the ethereum address of a given public key.
305 * Accepts "Ethereum public keys" and SEC1 encoded keys.
306 * @param {Buffer} pubKey The two points of an uncompressed key, unless sanitize is enabled
307 * @param {Boolean} [sanitize=false] Accept public keys in other formats
310 exports
. pubToAddress
= exports
. publicToAddress = function ( pubKey
, sanitize
) {
311 pubKey
= exports
. toBuffer ( pubKey
)
312 if ( sanitize
&& ( pubKey
. length
!== 64 )) {
313 pubKey
= secp256k1
. publicKeyConvert ( pubKey
, false ). slice ( 1 )
315 assert ( pubKey
. length
=== 64 )
316 // Only take the lower 160bits of the hash
317 return exports
. keccak ( pubKey
). slice (- 20 )
321 * Returns the ethereum public key of a given private key
322 * @param {Buffer} privateKey A private key must be 256 bits wide
325 const privateToPublic
= exports
. privateToPublic = function ( privateKey
) {
326 privateKey
= exports
. toBuffer ( privateKey
)
327 // skip the type flag and use the X, Y points
328 return secp256k1
. publicKeyCreate ( privateKey
, false ). slice ( 1 )
332 * Converts a public key to the Ethereum format.
333 * @param {Buffer} publicKey
336 exports
. importPublic = function ( publicKey
) {
337 publicKey
= exports
. toBuffer ( publicKey
)
338 if ( publicKey
. length
!== 64 ) {
339 publicKey
= secp256k1
. publicKeyConvert ( publicKey
, false ). slice ( 1 )
346 * @param {Buffer} msgHash
347 * @param {Buffer} privateKey
348 * @param {Number} [chainId]
351 exports
. ecsign = function ( msgHash
, privateKey
, chainId
) {
352 const sig
= secp256k1
. sign ( msgHash
, privateKey
)
355 ret
. r
= sig
. signature
. slice ( 0 , 32 )
356 ret
. s
= sig
. signature
. slice ( 32 , 64 )
357 ret
. v
= chainId
? sig
. recovery
+ ( chainId
* 2 + 35 ) : sig
. recovery
+ 27
362 * Returns the keccak-256 hash of `message`, prefixed with the header used by the `eth_sign` RPC call.
363 * The output of this function can be fed into `ecsign` to produce the same signature as the `eth_sign`
364 * call for a given `message`, or fed to `ecrecover` along with a signature to recover the public key
365 * used to produce the signature.
367 * @returns {Buffer} hash
369 exports
. hashPersonalMessage = function ( message
) {
370 const prefix
= exports
. toBuffer ( ' \u0019E thereum Signed Message: \n ' + message
. length
. toString ())
371 return exports
. keccak ( Buffer
. concat ([ prefix
, message
]))
375 * ECDSA public key recovery from signature
376 * @param {Buffer} msgHash
380 * @param {Number} [chainId]
381 * @return {Buffer} publicKey
383 exports
. ecrecover = function ( msgHash
, v
, r
, s
, chainId
) {
384 const signature
= Buffer
. concat ([ exports
. setLength ( r
, 32 ), exports
. setLength ( s
, 32 )], 64 )
385 const recovery
= calculateSigRecovery ( v
, chainId
)
386 if (! isValidSigRecovery ( recovery
)) {
387 throw new Error ( 'Invalid signature v value' )
389 const senderPubKey
= secp256k1
. recover ( msgHash
, signature
, recovery
)
390 return secp256k1
. publicKeyConvert ( senderPubKey
, false ). slice ( 1 )
394 * Convert signature parameters into the format of `eth_sign` RPC method
398 * @param {Number} [chainId]
399 * @return {String} sig
401 exports
. toRpcSig = function ( v
, r
, s
, chainId
) {
402 let recovery
= calculateSigRecovery ( v
, chainId
)
403 if (! isValidSigRecovery ( recovery
)) {
404 throw new Error ( 'Invalid signature v value' )
407 // geth (and the RPC eth_sign method) uses the 65 byte format used by Bitcoin
408 return exports
. bufferToHex ( Buffer
. concat ([
409 exports
. setLengthLeft ( r
, 32 ),
410 exports
. setLengthLeft ( s
, 32 ),
416 * Convert signature format of the `eth_sign` RPC method to signature parameters
417 * NOTE: all because of a bug in geth: https://github.com/ethereum/go-ethereum/issues/2053
418 * @param {String} sig
421 exports
. fromRpcSig = function ( sig
) {
422 sig
= exports
. toBuffer ( sig
)
424 // NOTE: with potential introduction of chainId this might need to be updated
425 if ( sig
. length
!== 65 ) {
426 throw new Error ( 'Invalid signature length' )
430 // support both versions of `eth_sign` responses
443 * Returns the ethereum address of a given private key
444 * @param {Buffer} privateKey A private key must be 256 bits wide
447 exports
. privateToAddress = function ( privateKey
) {
448 return exports
. publicToAddress ( privateToPublic ( privateKey
))
452 * Checks if the address is a valid. Accepts checksummed addresses too
453 * @param {String} address
456 exports
. isValidAddress = function ( address
) {
457 return /^0x[0-9a-fA-F]{40}$/ . test ( address
)
461 * Checks if a given address is a zero address
462 * @method isZeroAddress
463 * @param {String} address
466 exports
. isZeroAddress = function ( address
) {
467 const zeroAddress
= exports
. zeroAddress ()
468 return zeroAddress
=== exports
. addHexPrefix ( address
)
472 * Returns a checksummed address
473 * @param {String} address
476 exports
. toChecksumAddress = function ( address
) {
477 address
= exports
. stripHexPrefix ( address
). toLowerCase ()
478 const hash
= exports
. keccak ( address
). toString ( 'hex' )
481 for ( let i
= 0 ; i
< address
. length
; i
++) {
482 if ( parseInt ( hash
[ i
], 16 ) >= 8 ) {
483 ret
+= address
[ i
]. toUpperCase ()
493 * Checks if the address is a valid checksummed address
494 * @param {Buffer} address
497 exports
. isValidChecksumAddress = function ( address
) {
498 return exports
. isValidAddress ( address
) && ( exports
. toChecksumAddress ( address
) === address
)
502 * Generates an address of a newly created contract
503 * @param {Buffer} from the address which is creating this new address
504 * @param {Buffer} nonce the nonce of the from account
507 exports
. generateAddress = function ( from , nonce
) {
508 from = exports
. toBuffer ( from )
509 nonce
= new BN ( nonce
)
511 if ( nonce
. isZero ()) {
512 // in RLP we want to encode null in the case of zero nonce
513 // read the RLP documentation for an answer if you dare
516 nonce
= Buffer
. from ( nonce
. toArray ())
519 // Only take the lower 160bits of the hash
520 return exports
. rlphash ([ from , nonce
]). slice (- 20 )
524 * Generates an address for a contract created using CREATE2
525 * @param {Buffer} from the address which is creating this new address
526 * @param {Buffer} salt a salt
527 * @param {Buffer} initCode the init code of the contract being created
530 exports
. generateAddress2 = function ( from , salt
, initCode
) {
531 from = exports
. toBuffer ( from )
532 salt
= exports
. toBuffer ( salt
)
533 initCode
= exports
. toBuffer ( initCode
)
535 assert ( from . length
=== 20 )
536 assert ( salt
. length
=== 32 )
538 let address
= exports
. keccak256 ( Buffer
. concat ([
539 Buffer
. from ( 'ff' , 'hex' ),
542 exports
. keccak256 ( initCode
)
545 return address
. slice (- 20 )
549 * Returns true if the supplied address belongs to a precompiled account (Byzantium)
550 * @param {Buffer|String} address
553 exports
. isPrecompiled = function ( address
) {
554 const a
= exports
. unpad ( address
)
555 return a
. length
=== 1 && a
[ 0 ] >= 1 && a
[ 0 ] <= 8
559 * Adds "0x" to a given `String` if it does not already start with "0x"
560 * @param {String} str
563 exports
. addHexPrefix = function ( str
) {
564 if ( typeof str
!== 'string' ) {
568 return exports
. isHexPrefixed ( str
) ? str : '0x' + str
572 * Validate ECDSA signature
573 * @method isValidSignature
577 * @param {Boolean} [homestead=true]
578 * @param {Number} [chainId]
582 exports
. isValidSignature = function ( v
, r
, s
, homestead
, chainId
) {
583 const SECP256K1_N_DIV_2
= new BN ( '7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0' , 16 )
584 const SECP256K1_N
= new BN ( 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141' , 16 )
586 if ( r
. length
!== 32 || s
. length
!== 32 ) {
590 if (! isValidSigRecovery ( calculateSigRecovery ( v
, chainId
))) {
597 if ( r
. isZero () || r
. gt ( SECP256K1_N
) || s
. isZero () || s
. gt ( SECP256K1_N
)) {
601 if (( homestead
=== false ) && ( new BN ( s
). cmp ( SECP256K1_N_DIV_2
) === 1 )) {
609 * Converts a `Buffer` or `Array` to JSON
610 * @param {Buffer|Array} ba
611 * @return {Array|String|null}
613 exports
. baToJSON = function ( ba
) {
614 if ( Buffer
. isBuffer ( ba
)) {
615 return '0x' + ba
. toString ( 'hex' )
616 } else if ( ba
instanceof Array
) {
618 for ( let i
= 0 ; i
< ba
. length
; i
++) {
619 array
. push ( exports
. baToJSON ( ba
[ i
]))
626 * Defines properties on a `Object`. It make the assumption that underlying data is binary.
627 * @param {Object} self the `Object` to define properties on
628 * @param {Array} fields an array fields to define. Fields can contain:
629 * * `name` - the name of the properties
630 * * `length` - the number of bytes the field can have
631 * * `allowLess` - if the field can be less than the length
633 * @param {*} data data to be validated against the definitions
635 exports
. defineProperties = function ( self
, fields
, data
) {
639 // attach the `toJSON`
640 self
. toJSON = function ( label
) {
643 self
. _fields
. forEach (( field
) => {
644 obj
[ field
] = '0x' + self
[ field
]. toString ( 'hex' )
648 return exports
. baToJSON ( this . raw
)
651 self
. serialize
= function serialize () {
652 return rlp
. encode ( self
. raw
)
655 fields
. forEach (( field
, i
) => {
656 self
. _fields
. push ( field
. name
)
660 function setter ( v
) {
661 v
= exports
. toBuffer ( v
)
663 if ( v
. toString ( 'hex' ) === '00' && ! field
. allowZero
) {
664 v
= Buffer
. allocUnsafe ( 0 )
667 if ( field
. allowLess
&& field
. length
) {
668 v
= exports
. stripZeros ( v
)
669 assert ( field
. length
>= v
. length
, 'The field ' + field
. name
+ ' must not have more ' + field
. length
+ ' bytes' )
670 } else if (!( field
. allowZero
&& v
. length
=== 0 ) && field
. length
) {
671 assert ( field
. length
=== v
. length
, 'The field ' + field
. name
+ ' must have byte length of ' + field
. length
)
677 Object
. defineProperty ( self
, field
. name
, {
685 self
[ field
. name
] = field
. default
690 Object
. defineProperty ( self
, field
. alias
, {
699 // if the constuctor is passed data
701 if ( typeof data
=== 'string' ) {
702 data
= Buffer
. from ( exports
. stripHexPrefix ( data
), 'hex' )
705 if ( Buffer
. isBuffer ( data
)) {
706 data
= rlp
. decode ( data
)
709 if ( Array
. isArray ( data
)) {
710 if ( data
. length
> self
. _fields
. length
) {
711 throw ( new Error ( 'wrong number of fields in data' ))
714 // make sure all the items are buffers
715 data
. forEach (( d
, i
) => {
716 self
[ self
. _fields
[ i
]] = exports
. toBuffer ( d
)
718 } else if ( typeof data
=== 'object' ) {
719 const keys
= Object
. keys ( data
)
720 fields
. forEach (( field
) => {
721 if ( keys
. indexOf ( field
. name
) !== - 1 ) self
[ field
. name
] = data
[ field
. name
]
722 if ( keys
. indexOf ( field
. alias
) !== - 1 ) self
[ field
. alias
] = data
[ field
. alias
]
725 throw new Error ( 'invalid data' )
730 function calculateSigRecovery ( v
, chainId
) {
731 return chainId
? v
- ( 2 * chainId
+ 35 ) : v
- 27
734 function isValidSigRecovery ( recovery
) {
735 return recovery
=== 0 || recovery
=== 1