diff --git a/packages/devp2p/package.json b/packages/devp2p/package.json index e141da5567..0855a471b9 100644 --- a/packages/devp2p/package.json +++ b/packages/devp2p/package.json @@ -49,6 +49,7 @@ "bl": "^1.1.2", "debug": "^4.3.3", "ethereumjs-util": "^7.1.5", + "ethereum-cryptography": "^1.0.3", "hi-base32": "^0.5.0", "inherits": "^2.0.1", "ip": "^1.1.3", @@ -58,7 +59,6 @@ "ms": "^0.7.1", "multiaddr": "^10.0.1", "scanf": "^1.1.2", - "secp256k1": "^4.0.2", "snappyjs": "^0.6.1" }, "devDependencies": { @@ -70,7 +70,6 @@ "@types/keccak": "^3.0.1", "@types/ms": "^0.7.30", "@types/node": "^16.11.7", - "@types/secp256k1": "^4.0.1", "@types/tape": "^4.13.2", "chalk": "^2.4.2", "eslint": "^6.8.0", diff --git a/packages/devp2p/src/dns/enr.ts b/packages/devp2p/src/dns/enr.ts index d9edf08b71..4d9fd4ff53 100644 --- a/packages/devp2p/src/dns/enr.ts +++ b/packages/devp2p/src/dns/enr.ts @@ -2,11 +2,11 @@ import assert from 'assert' import * as base32 from 'hi-base32' import { rlp } from 'ethereumjs-util' import { sscanf } from 'scanf' -import { ecdsaVerify } from 'secp256k1' import { Multiaddr } from 'multiaddr' import base64url from 'base64url' import { PeerInfo } from '../dpt' import { toNewUint8Array, keccak256 } from '../util' +import { ecdsaVerify } from 'ethereum-cryptography/secp256k1-compat' const Convert = require('multiaddr/src/convert') diff --git a/packages/devp2p/src/dpt/dpt.ts b/packages/devp2p/src/dpt/dpt.ts index 274204d9dd..a87eeb4af1 100644 --- a/packages/devp2p/src/dpt/dpt.ts +++ b/packages/devp2p/src/dpt/dpt.ts @@ -1,6 +1,6 @@ import ms from 'ms' import { EventEmitter } from 'events' -import { publicKeyCreate } from 'secp256k1' +import { getPublicKey } from 'ethereum-cryptography/secp256k1' import { randomBytes } from 'crypto' // import { debug as createDebugLogger } from 'debug' import { devp2pDebug } from '../util' @@ -106,7 +106,7 @@ export class DPT extends EventEmitter { super() this.privateKey = Buffer.from(privateKey) - this._id = pk2id(Buffer.from(publicKeyCreate(this.privateKey, false))) + this._id = pk2id(Buffer.from(getPublicKey(this.privateKey, false))) this._shouldFindNeighbours = options.shouldFindNeighbours === false ? false : true this._shouldGetDnsPeers = options.shouldGetDnsPeers ?? false // By default, tries to connect to 12 new peers every 3s diff --git a/packages/devp2p/src/dpt/message.ts b/packages/devp2p/src/dpt/message.ts index 1560f131f0..8d47d1b880 100644 --- a/packages/devp2p/src/dpt/message.ts +++ b/packages/devp2p/src/dpt/message.ts @@ -1,7 +1,7 @@ import { debug as createDebugLogger } from 'debug' import ip from 'ip' import { rlp } from 'ethereumjs-util' -import secp256k1 from 'secp256k1' +import { ecdsaRecover, ecdsaSign } from 'ethereum-cryptography/secp256k1-compat' import { keccak256, int2buffer, buffer2int, assertEq, unstrictDecode } from '../util' import { PeerInfo } from './dpt' @@ -172,7 +172,7 @@ export function encode(typename: string, data: T, privateKey: Buffer) { const typedata = Buffer.concat([Buffer.from([type]), rlp.encode(encodedMsg)]) const sighash = keccak256(typedata) - const sig = secp256k1.ecdsaSign(sighash, privateKey) + const sig = ecdsaSign(sighash, privateKey) const hashdata = Buffer.concat([Buffer.from(sig.signature), Buffer.from([sig.recid]), typedata]) const hash = keccak256(hashdata) return Buffer.concat([hash, hashdata]) @@ -191,7 +191,7 @@ export function decode(buffer: Buffer) { const sighash = keccak256(typedata) const signature = buffer.slice(32, 96) const recoverId = buffer[96] - const publicKey = Buffer.from(secp256k1.ecdsaRecover(signature, recoverId, sighash, false)) + const publicKey = Buffer.from(ecdsaRecover(signature, recoverId, sighash, false)) return { typename, data, publicKey } } diff --git a/packages/devp2p/src/rlpx/ecies.ts b/packages/devp2p/src/rlpx/ecies.ts index cbd2c3e990..a93ebe82a0 100644 --- a/packages/devp2p/src/rlpx/ecies.ts +++ b/packages/devp2p/src/rlpx/ecies.ts @@ -1,7 +1,7 @@ import crypto, { Decipher } from 'crypto' import { debug as createDebugLogger } from 'debug' -import { publicKeyCreate, ecdh, ecdsaRecover, ecdsaSign } from 'secp256k1' import { rlp } from 'ethereumjs-util' +import { getPublicKey } from 'ethereum-cryptography/secp256k1' import { unstrictDecode } from '../util' import { MAC } from './mac' @@ -16,6 +16,7 @@ import { buffer2int, zfill, } from '../util' +import { ecdsaSign, ecdsaRecover, ecdh } from 'ethereum-cryptography/secp256k1-compat' const debug = createDebugLogger('devp2p:rlpx:peer') @@ -25,10 +26,9 @@ function ecdhX(publicKey: Buffer, privateKey: Buffer) { const pubKey = new Uint8Array(33) pubKey[0] = (y[31] & 1) === 0 ? 0x02 : 0x03 pubKey.set(x, 1) - return pubKey + return pubKey.slice(1) } - // @ts-ignore - return Buffer.from(ecdh(publicKey, privateKey, { hashfn }, Buffer.alloc(33)).slice(1)) + return Buffer.from(ecdh(publicKey, privateKey, { hashfn: hashfn }, Buffer.alloc(32))) } // a straigth rip from python interop w/go ecies implementation @@ -79,7 +79,7 @@ export class ECIES { this._nonce = crypto.randomBytes(32) this._ephemeralPrivateKey = genPrivateKey() - this._ephemeralPublicKey = Buffer.from(publicKeyCreate(this._ephemeralPrivateKey, false)) + this._ephemeralPublicKey = Buffer.from(getPublicKey(this._ephemeralPrivateKey, false)) } _encryptMessage(data: Buffer, sharedMacData: Buffer | null = null): Buffer | undefined { @@ -105,7 +105,7 @@ export class ECIES { .update(Buffer.concat([dataIV, sharedMacData])) .digest() - const publicKey = publicKeyCreate(privateKey, false) + const publicKey = getPublicKey(privateKey, false) return Buffer.concat([publicKey, dataIV, tag]) } diff --git a/packages/devp2p/src/rlpx/rlpx.ts b/packages/devp2p/src/rlpx/rlpx.ts index fe2fb73790..a16969bacb 100644 --- a/packages/devp2p/src/rlpx/rlpx.ts +++ b/packages/devp2p/src/rlpx/rlpx.ts @@ -1,7 +1,7 @@ import * as net from 'net' import * as os from 'os' import ms from 'ms' -import { publicKeyCreate } from 'secp256k1' +import { getPublicKey } from 'ethereum-cryptography/secp256k1' import { EventEmitter } from 'events' import { debug as createDebugLogger, Debugger } from 'debug' import { devp2pDebug } from '../util' @@ -54,7 +54,7 @@ export class RLPx extends EventEmitter { super() this._privateKey = Buffer.from(privateKey) - this._id = pk2id(Buffer.from(publicKeyCreate(this._privateKey, false))) + this._id = pk2id(Buffer.from(getPublicKey(this._privateKey, false))) // options this._timeout = options.timeout ?? ms('10s') diff --git a/packages/devp2p/src/util.ts b/packages/devp2p/src/util.ts index f7c30a97d0..f7cfa717a0 100644 --- a/packages/devp2p/src/util.ts +++ b/packages/devp2p/src/util.ts @@ -1,8 +1,7 @@ import assert from 'assert' -import { randomBytes } from 'crypto' -import { privateKeyVerify, publicKeyConvert } from 'secp256k1' -import createKeccakHash from 'keccak' import { rlp } from 'ethereumjs-util' +import { getPublicKey, utils } from 'ethereum-cryptography/secp256k1' +import { keccak256 as _keccak256 } from 'ethereum-cryptography/keccak' import { ETH } from './protocol/eth' import { LES } from './protocol/les' @@ -12,17 +11,17 @@ export const devp2pDebug = createDebugLogger('devp2p') export function keccak256(...buffers: Buffer[]) { const buffer = Buffer.concat(buffers) - return createKeccakHash('keccak256').update(buffer).digest() + return Buffer.from(_keccak256(buffer)) } export function genPrivateKey(): Buffer { - const privateKey = randomBytes(32) - return privateKeyVerify(privateKey) ? privateKey : genPrivateKey() + const privateKey = utils.randomPrivateKey() + return utils.isValidPrivateKey(privateKey) ? Buffer.from(privateKey) : genPrivateKey() } export function pk2id(pk: Buffer): Buffer { if (pk.length === 33) { - pk = Buffer.from(publicKeyConvert(pk, false)) + pk = Buffer.from(getPublicKey(pk, false)) } return pk.slice(1) } diff --git a/packages/devp2p/test/dpt-message.ts b/packages/devp2p/test/dpt-message.ts index df5b245271..40534b7265 100644 --- a/packages/devp2p/test/dpt-message.ts +++ b/packages/devp2p/test/dpt-message.ts @@ -1,12 +1,12 @@ +import { publicKeyCreate } from 'ethereum-cryptography/secp256k1-compat' import test from 'tape' -import * as secp256k1 from 'secp256k1' import * as message from '../src/dpt/message' const privateKey = Buffer.from( 'b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291', 'hex' ) -const publicKey = Buffer.from(secp256k1.publicKeyCreate(privateKey, false)) +const publicKey = Buffer.from(publicKeyCreate(privateKey, false)) test('ping packet with version 4, additional list elements', (t) => { const buffer = Buffer.from( diff --git a/packages/devp2p/test/rlpx-ecies.ts b/packages/devp2p/test/rlpx-ecies.ts index f99bb012da..854654e862 100644 --- a/packages/devp2p/test/rlpx-ecies.ts +++ b/packages/devp2p/test/rlpx-ecies.ts @@ -1,10 +1,10 @@ import { randomBytes } from 'crypto' -import * as secp256k1 from 'secp256k1' import test, { Test } from 'tape' import * as util from '../src/util' import { ECIES } from '../src/rlpx/ecies' import testdata from './testdata.json' +import { publicKeyCreate } from 'ethereum-cryptography/secp256k1-compat' declare module 'tape' { export interface Test { @@ -16,8 +16,8 @@ function randomBefore(fn: Function) { return (t: Test) => { const privateKey1 = util.genPrivateKey() const privateKey2 = util.genPrivateKey() - const publicKey1 = Buffer.from(secp256k1.publicKeyCreate(privateKey1, false)) - const publicKey2 = Buffer.from(secp256k1.publicKeyCreate(privateKey2, false)) + const publicKey1 = Buffer.from(publicKeyCreate(privateKey1, false)) + const publicKey2 = Buffer.from(publicKeyCreate(privateKey2, false)) t.context = { a: new ECIES(privateKey1, util.pk2id(publicKey1), util.pk2id(publicKey2)), b: new ECIES(privateKey2, util.pk2id(publicKey2), util.pk2id(publicKey1)),