From 75bb9bf48cca20892fcb70cb60223c5dc04d4131 Mon Sep 17 00:00:00 2001 From: PhilippLgh Date: Thu, 14 May 2020 16:56:28 +0200 Subject: [PATCH 1/4] chore: update secp256k1 + types to v4.0.1 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 337b600..2eebc3e 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "lru-cache": "^5.1.1", "ms": "^0.7.1", "rlp-encoding": "^3.0.0", - "secp256k1": "^3.1.0" + "secp256k1": "^4.0.1" }, "devDependencies": { "@ethereumjs/config-nyc": "^1.1.1", @@ -78,7 +78,7 @@ "@types/ip": "^1.1.0", "@types/lru-cache": "^5.1.0", "@types/ms": "^0.7.30", - "@types/secp256k1": "3.5.0", + "@types/secp256k1": "^4.0.1", "@types/tape": "^4.2.33", "async": "^2.6.0", "chalk": "^2.4.2", From 5ef59f5cf3e7d3847cb4da1c2ed6488eebacfa56 Mon Sep 17 00:00:00 2001 From: PhilippLgh Date: Thu, 14 May 2020 16:59:49 +0200 Subject: [PATCH 2/4] fix: convert new secp256k1 interface to old iface --- src/dpt/dpt.ts | 2 +- src/dpt/message.ts | 6 +++--- src/rlpx/ecies.ts | 22 +++++++++++----------- src/rlpx/rlpx.ts | 2 +- src/util.ts | 4 +++- test/dpt-message.ts | 2 +- test/rlpx-ecies.ts | 4 ++-- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/dpt/dpt.ts b/src/dpt/dpt.ts index 0c09813..78ea64f 100644 --- a/src/dpt/dpt.ts +++ b/src/dpt/dpt.ts @@ -23,7 +23,7 @@ export class DPT extends EventEmitter { super() this.privateKey = Buffer.from(privateKey) - this._id = pk2id(publicKeyCreate(this.privateKey, false)) + this._id = pk2id(Buffer.from(publicKeyCreate(this.privateKey, false))) this.banlist = new BanList() diff --git a/src/dpt/message.ts b/src/dpt/message.ts index 1c147de..18f6a9e 100644 --- a/src/dpt/message.ts +++ b/src/dpt/message.ts @@ -175,8 +175,8 @@ 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.sign(sighash, privateKey) - const hashdata = Buffer.concat([sig.signature, Buffer.from([sig.recovery]), typedata]) + const sig = secp256k1.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]) } @@ -194,7 +194,7 @@ export function decode(buffer: Buffer) { const sighash = keccak256(typedata) const signature = buffer.slice(32, 96) const recoverId = buffer[96] - const publicKey = secp256k1.recover(sighash, signature, recoverId, false) + const publicKey = Buffer.from(secp256k1.ecdsaRecover(signature, recoverId, sighash, false)) return { typename, data, publicKey } } diff --git a/src/rlpx/ecies.ts b/src/rlpx/ecies.ts index fc1391a..ca23145 100644 --- a/src/rlpx/ecies.ts +++ b/src/rlpx/ecies.ts @@ -1,5 +1,5 @@ import crypto, { Decipher } from 'crypto' -import { publicKeyCreate, ecdhUnsafe, sign, recover } from 'secp256k1' +import { publicKeyCreate, ecdh, ecdsaRecover, ecdsaSign } from 'secp256k1' import rlp from 'rlp-encoding' import { MAC } from './mac' @@ -17,7 +17,7 @@ import { function ecdhX(publicKey: Buffer, privateKey: Buffer) { // return (publicKey * privateKey).x - return ecdhUnsafe(publicKey, privateKey, true).slice(1) + return Buffer.from(ecdh(publicKey, privateKey)) } // a straigth rip from python interop w/go ecies implementation @@ -74,7 +74,7 @@ export class ECIES { this._nonce = crypto.randomBytes(32) this._ephemeralPrivateKey = genPrivateKey() - this._ephemeralPublicKey = publicKeyCreate(this._ephemeralPrivateKey, false) + this._ephemeralPublicKey = Buffer.from(publicKeyCreate(this._ephemeralPrivateKey, false)) } _encryptMessage(data: Buffer, sharedMacData: Buffer | null = null): Buffer | undefined { @@ -171,9 +171,9 @@ export class ECIES { createAuthEIP8() { if (!this._remotePublicKey) return const x = ecdhX(this._remotePublicKey, this._privateKey) - const sig = sign(xor(x, this._nonce), this._ephemeralPrivateKey) + const sig = ecdsaSign(xor(x, this._nonce), this._ephemeralPrivateKey) const data = [ - Buffer.concat([sig.signature, Buffer.from([sig.recovery])]), + Buffer.concat([Buffer.from(sig.signature), Buffer.from([sig.recid])]), // keccak256(pk2id(this._ephemeralPublicKey)), pk2id(this._publicKey), this._nonce, @@ -194,10 +194,10 @@ export class ECIES { createAuthNonEIP8(): Buffer | undefined { if (!this._remotePublicKey) return const x = ecdhX(this._remotePublicKey, this._privateKey) - const sig = sign(xor(x, this._nonce), this._ephemeralPrivateKey) + const sig = ecdsaSign(xor(x, this._nonce), this._ephemeralPrivateKey) const data = Buffer.concat([ - sig.signature, - Buffer.from([sig.recovery]), + Buffer.from(sig.signature), + Buffer.from([sig.recid]), keccak256(pk2id(this._ephemeralPublicKey)), pk2id(this._publicKey), this._nonce, @@ -244,12 +244,12 @@ export class ECIES { const x = ecdhX(this._remotePublicKey, this._privateKey) if (!this._remoteNonce) return - this._remoteEphemeralPublicKey = recover( - xor(x, this._remoteNonce), + this._remoteEphemeralPublicKey = Buffer.from(ecdsaRecover( signature, recoveryId, + xor(x, this._remoteNonce), false, - ) + )) if (!this._remoteEphemeralPublicKey) return this._ephemeralSharedSecret = ecdhX(this._remoteEphemeralPublicKey, this._ephemeralPrivateKey) diff --git a/src/rlpx/rlpx.ts b/src/rlpx/rlpx.ts index e7c4ae0..da170fc 100644 --- a/src/rlpx/rlpx.ts +++ b/src/rlpx/rlpx.ts @@ -43,7 +43,7 @@ export class RLPx extends EventEmitter { super() this._privateKey = Buffer.from(privateKey) - this._id = pk2id(publicKeyCreate(this._privateKey, false)) + this._id = pk2id(Buffer.from(publicKeyCreate(this._privateKey, false))) // options this._timeout = options.timeout || ms('10s') diff --git a/src/util.ts b/src/util.ts index af81d17..4a1449e 100644 --- a/src/util.ts +++ b/src/util.ts @@ -21,7 +21,9 @@ export function genPrivateKey() { } export function pk2id(pk: Buffer): Buffer { - if (pk.length === 33) pk = publicKeyConvert(pk, false) + if (pk.length === 33) { + pk = Buffer.from(publicKeyConvert(pk, false)) + } return pk.slice(1) } diff --git a/test/dpt-message.ts b/test/dpt-message.ts index d9437b3..9074cfc 100644 --- a/test/dpt-message.ts +++ b/test/dpt-message.ts @@ -6,7 +6,7 @@ const privateKey = Buffer.from( 'b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291', 'hex', ) -const publicKey = secp256k1.publicKeyCreate(privateKey, false) +const publicKey = Buffer.from(secp256k1.publicKeyCreate(privateKey, false)) test('ping packet with version 4, additional list elements', t => { const buffer = Buffer.from( diff --git a/test/rlpx-ecies.ts b/test/rlpx-ecies.ts index e6aa6f0..75c6709 100644 --- a/test/rlpx-ecies.ts +++ b/test/rlpx-ecies.ts @@ -16,8 +16,8 @@ function randomBefore(fn: Function) { return (t: Test) => { const privateKey1 = util.genPrivateKey() const privateKey2 = util.genPrivateKey() - const publicKey1 = secp256k1.publicKeyCreate(privateKey1, false) - const publicKey2 = secp256k1.publicKeyCreate(privateKey2, false) + const publicKey1 = Buffer.from(secp256k1.publicKeyCreate(privateKey1, false)) + const publicKey2 = Buffer.from(secp256k1.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)), From 6422a0180ff8065d61823940b81574c35790c01d Mon Sep 17 00:00:00 2001 From: PhilippLgh Date: Fri, 15 May 2020 14:48:01 +0200 Subject: [PATCH 3/4] fix: migrate ecdh --- src/rlpx/ecies.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/rlpx/ecies.ts b/src/rlpx/ecies.ts index ca23145..8517064 100644 --- a/src/rlpx/ecies.ts +++ b/src/rlpx/ecies.ts @@ -17,7 +17,14 @@ import { function ecdhX(publicKey: Buffer, privateKey: Buffer) { // return (publicKey * privateKey).x - return Buffer.from(ecdh(publicKey, privateKey)) + function hashfn (x: Uint8Array, y: Uint8Array) { + const pubKey = new Uint8Array(33) + pubKey[0] = (y[31] & 1) === 0 ? 0x02 : 0x03 + pubKey.set(x, 1) + return pubKey + } + // @ts-ignore + return Buffer.from(ecdh(publicKey, privateKey, { hashfn }, Buffer.alloc(33)).slice(1)) } // a straigth rip from python interop w/go ecies implementation From 4c03f5a5bda7adca7ce14c36e9a6654395910dec Mon Sep 17 00:00:00 2001 From: PhilippLgh Date: Fri, 15 May 2020 14:48:47 +0200 Subject: [PATCH 4/4] chore: fix linter errors --- src/rlpx/ecies.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/rlpx/ecies.ts b/src/rlpx/ecies.ts index 8517064..28b57da 100644 --- a/src/rlpx/ecies.ts +++ b/src/rlpx/ecies.ts @@ -17,7 +17,7 @@ import { function ecdhX(publicKey: Buffer, privateKey: Buffer) { // return (publicKey * privateKey).x - function hashfn (x: Uint8Array, y: Uint8Array) { + function hashfn(x: Uint8Array, y: Uint8Array) { const pubKey = new Uint8Array(33) pubKey[0] = (y[31] & 1) === 0 ? 0x02 : 0x03 pubKey.set(x, 1) @@ -251,12 +251,9 @@ export class ECIES { const x = ecdhX(this._remotePublicKey, this._privateKey) if (!this._remoteNonce) return - this._remoteEphemeralPublicKey = Buffer.from(ecdsaRecover( - signature, - recoveryId, - xor(x, this._remoteNonce), - false, - )) + this._remoteEphemeralPublicKey = Buffer.from( + ecdsaRecover(signature, recoveryId, xor(x, this._remoteNonce), false), + ) if (!this._remoteEphemeralPublicKey) return this._ephemeralSharedSecret = ecdhX(this._remoteEphemeralPublicKey, this._ephemeralPrivateKey)