/ src / util.js
util.js
 1  const { randomBytes } = require('crypto')
 2  const secp256k1 = require('secp256k1')
 3  const Buffer = require('safe-buffer').Buffer
 4  const createDebugLogger = require('debug')
 5  const createKeccakHash = require('keccak')
 6  const assert = require('assert')
 7  
 8  const debug = createDebugLogger('devp2p:util')
 9  
10  function keccak256 (...buffers) {
11    const buffer = Buffer.concat(buffers)
12    return createKeccakHash('keccak256').update(buffer).digest()
13  }
14  
15  function genPrivateKey () {
16    while (true) {
17      const privateKey = randomBytes(32)
18      if (secp256k1.privateKeyVerify(privateKey)) return privateKey
19    }
20  }
21  
22  function pk2id (pk) {
23    if (pk.length === 33) pk = secp256k1.publicKeyConvert(pk, false)
24    return pk.slice(1)
25  }
26  
27  function id2pk (id) {
28    return Buffer.concat([ Buffer.from([ 0x04 ]), id ])
29  }
30  
31  function int2buffer (v) {
32    let hex = v.toString(16)
33    if (hex.length % 2 === 1) hex = '0' + hex
34    return Buffer.from(hex, 'hex')
35  }
36  
37  function buffer2int (buffer) {
38    if (buffer.length === 0) return NaN
39  
40    let n = 0
41    for (let i = 0; i < buffer.length; ++i) n = n * 256 + buffer[i]
42    return n
43  }
44  
45  function zfill (buffer, size, leftpad) {
46    if (buffer.length >= size) return buffer
47    if (leftpad === undefined) leftpad = true
48    const pad = Buffer.allocUnsafe(size - buffer.length).fill(0x00)
49    return leftpad ? Buffer.concat([ pad, buffer ]) : Buffer.concat([ buffer, pad ])
50  }
51  
52  function xor (a, b) {
53    const length = Math.min(a.length, b.length)
54    const buffer = Buffer.allocUnsafe(length)
55    for (let i = 0; i < length; ++i) buffer[i] = a[i] ^ b[i]
56    return buffer
57  }
58  
59  function assertEq (expected, actual, msg) {
60    var message
61    if (Buffer.isBuffer(expected) && Buffer.isBuffer(actual)) {
62      if (expected.equals(actual)) return
63      message = `${msg}: ${expected.toString('hex')} / ${actual.toString('hex')}`
64      debug(message)
65      throw new assert.AssertionError({
66        message: message
67      })
68    }
69  
70    if (expected === actual) return
71    message = `${msg}: ${expected} / ${actual}`
72    debug(message)
73    throw new assert.AssertionError({
74      message: message
75    })
76  }
77  
78  function createDeferred () {
79    const deferred = {}
80    deferred.promise = new Promise((resolve, reject) => {
81      deferred.resolve = resolve
82      deferred.reject = reject
83    })
84    return deferred
85  }
86  
87  module.exports = {
88    keccak256,
89    genPrivateKey,
90    pk2id,
91    id2pk,
92    int2buffer,
93    buffer2int,
94    zfill,
95    xor,
96    assertEq,
97    createDeferred
98  }