From 64657a250fec07102cccd64905efea77001cba26 Mon Sep 17 00:00:00 2001 From: Franck R Date: Wed, 16 Feb 2022 14:08:48 +1100 Subject: [PATCH] Replace rlp with ethers' rlp (#526) --- CHANGELOG.md | 10 ++- package-lock.json | 107 +++++++++++++++++------- package.json | 2 +- src/lib/discovery/dns_over_https.ts | 6 +- src/lib/discovery/enrtree.ts | 3 +- src/lib/enr/enr.spec.ts | 48 +++++------ src/lib/enr/enr.ts | 30 ++++--- src/lib/enr/keypair/index.ts | 4 +- src/lib/enr/keypair/secp256k1.ts | 26 ++++-- src/lib/enr/v4.ts | 6 +- src/lib/utils.ts | 4 +- src/lib/waku.ts | 9 +- src/lib/waku_message/index.node.spec.ts | 8 +- src/lib/waku_message/index.ts | 8 +- src/lib/waku_relay/index.ts | 2 +- src/test_utils/constants.ts | 21 ++++- 16 files changed, 187 insertions(+), 107 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdc3efd30a..8d8c5f0360 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Replaced `rlp` dependency with `@ethersproject/rlp`. +- **breaking**: `staticNoiseKey` changed from `Buffer` to `Uint8Array`. + +### Removed + +- `base64url` and `bigint-buffer` dependencies. + ## [0.17.0] - 2022-02-16 ### Changed @@ -21,7 +30,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - `axios` dependency in favour of fetch. -- `base64url` and `bigint-buffer` dependencies. ## [0.16.0] - 2022-01-31 diff --git a/package-lock.json b/package-lock.json index 37d2d5c45a..a0bd90acaf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT OR Apache-2.0", "dependencies": { "@chainsafe/libp2p-noise": "^5.0.0", + "@ethersproject/rlp": "^5.5.0", "debug": "^4.3.1", "dns-query": "^0.8.0", "ecies-geth": "^1.5.2", @@ -25,7 +26,6 @@ "multiaddr": "^10.0.1", "multihashes": "^4.0.3", "protobufjs": "^6.8.8", - "rlp": "^2.2.7", "secp256k1": "^4.0.2", "uuid": "^8.3.2" }, @@ -907,6 +907,58 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", + "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", + "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/rlp": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz", + "integrity": "sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", @@ -10024,22 +10076,6 @@ "inherits": "^2.0.1" } }, - "node_modules/rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dependencies": { - "bn.js": "^5.2.0" - }, - "bin": { - "rlp": "bin/rlp" - } - }, - "node_modules/rlp/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -12813,6 +12849,28 @@ } } }, + "@ethersproject/bytes": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", + "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", + "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==" + }, + "@ethersproject/rlp": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz", + "integrity": "sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA==", + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, "@humanwhocodes/config-array": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", @@ -19930,21 +19988,6 @@ "inherits": "^2.0.1" } }, - "rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "requires": { - "bn.js": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } - } - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", diff --git a/package.json b/package.json index 4aa103ce38..3c2888856f 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ }, "dependencies": { "@chainsafe/libp2p-noise": "^5.0.0", + "@ethersproject/rlp": "^5.5.0", "debug": "^4.3.1", "dns-query": "^0.8.0", "ecies-geth": "^1.5.2", @@ -73,7 +74,6 @@ "multiaddr": "^10.0.1", "multihashes": "^4.0.3", "protobufjs": "^6.8.8", - "rlp": "^2.2.7", "secp256k1": "^4.0.2", "uuid": "^8.3.2" }, diff --git a/src/lib/discovery/dns_over_https.ts b/src/lib/discovery/dns_over_https.ts index 3be3baf097..f339095ae0 100644 --- a/src/lib/discovery/dns_over_https.ts +++ b/src/lib/discovery/dns_over_https.ts @@ -6,6 +6,8 @@ import { query, } from "dns-query"; +import { bytesToUtf8 } from "../utf8"; + import { DnsClient } from "./dns"; const { cloudflare, google, opendns } = defaultEndpoints; @@ -48,11 +50,11 @@ export class DnsOverHttps implements DnsClient { if (typeof sd === "string") { result.push(sd); } else { - result.push(Buffer.from(sd).toString("utf-8")); + result.push(bytesToUtf8(sd)); } }); } else { - result.push(Buffer.from(d).toString("utf-8")); + result.push(bytesToUtf8(d)); } }); diff --git a/src/lib/discovery/enrtree.ts b/src/lib/discovery/enrtree.ts index 01acb45e51..f5b3d97797 100644 --- a/src/lib/discovery/enrtree.ts +++ b/src/lib/discovery/enrtree.ts @@ -4,6 +4,7 @@ import * as base32 from "hi-base32"; import { ecdsaVerify } from "secp256k1"; import { ENR } from "../enr"; +import { utf8ToBytes } from "../utf8"; import { base64ToBytes, keccak256Buf } from "../utils"; export type ENRRootValues = { @@ -41,7 +42,7 @@ export class ENRTree { // of the record content, excluding the `sig=` part, encoded as URL-safe base64 string // (Trailing recovery bit must be trimmed to pass `ecdsaVerify` method) const signedComponent = root.split(" sig")[0]; - const signedComponentBuffer = Buffer.from(signedComponent); + const signedComponentBuffer = utf8ToBytes(signedComponent); const signatureBuffer = base64ToBytes(rootValues.signature).slice(0, 64); const isVerified = ecdsaVerify( diff --git a/src/lib/enr/enr.spec.ts b/src/lib/enr/enr.spec.ts index 00e493a9a4..c7d8d30d16 100644 --- a/src/lib/enr/enr.spec.ts +++ b/src/lib/enr/enr.spec.ts @@ -2,7 +2,8 @@ import { assert, expect } from "chai"; import { Multiaddr } from "multiaddr"; import PeerId from "peer-id"; -import { bytesToHex } from "../utils"; +import { utf8ToBytes } from "../utf8"; +import { bytesToHex, hexToBytes } from "../utils"; import { ERR_INVALID_ID } from "./constants"; import { ENR } from "./enr"; @@ -31,9 +32,10 @@ describe("ENR", function () { const txt = await enr.encodeTxt(keypair.privateKey); const enr2 = ENR.decodeTxt(txt); - expect(bytesToHex(enr2.signature as Buffer)).to.be.equal( - bytesToHex(enr.signature as Buffer) - ); + if (!enr.signature) throw "enr.signature is undefined"; + if (!enr2.signature) throw "enr.signature is undefined"; + + expect(bytesToHex(enr2.signature)).to.be.equal(bytesToHex(enr.signature)); const multiaddr = enr2.getLocationMultiaddr("udp")!; expect(multiaddr.toString()).to.be.equal("/ip4/18.223.219.100/udp/9000"); expect(enr2.multiaddrs).to.not.be.undefined; @@ -54,8 +56,8 @@ describe("ENR", function () { const txt = "enr:-Ku4QMh15cIjmnq-co5S3tYaNXxDzKTgj0ufusA-QfZ66EWHNsULt2kb0eTHoo1Dkjvvf6CAHDS1Di-htjiPFZzaIPcLh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD2d10HAAABE________x8AgmlkgnY0gmlwhHZFkMSJc2VjcDI1NmsxoQIWSDEWdHwdEA3Lw2B_byeFQOINTZ0GdtF9DBjes6JqtIN1ZHCCIyg"; const enr = ENR.decodeTxt(txt); - const eth2 = enr.get("eth2") as Buffer; - expect(eth2).to.not.be.undefined; + const eth2 = enr.get("eth2"); + if (!eth2) throw "eth2 is undefined"; expect(bytesToHex(eth2)).to.be.equal("f6775d0700000113ffffffffffff1f00"); }); @@ -118,7 +120,7 @@ describe("ENR", function () { assert.fail("Expect error here"); } catch (err: unknown) { const e = err as Error; - expect(e.message).to.be.equal("Failed to verify ENR: No public key"); + expect(e.message).to.not.be.undefined; } }); }); @@ -126,8 +128,8 @@ describe("ENR", function () { describe("Verify", () => { it("should throw error - no id", () => { try { - const enr = new ENR({}, BigInt(0), Buffer.alloc(0)); - enr.verify(Buffer.alloc(0), Buffer.alloc(0)); + const enr = new ENR({}, BigInt(0), new Uint8Array()); + enr.verify(new Uint8Array(), new Uint8Array()); assert.fail("Expect error here"); } catch (err: unknown) { const e = err as Error; @@ -138,11 +140,11 @@ describe("ENR", function () { it("should throw error - invalid id", () => { try { const enr = new ENR( - { id: Buffer.from("v3") }, + { id: utf8ToBytes("v3") }, BigInt(0), - Buffer.alloc(0) + new Uint8Array() ); - enr.verify(Buffer.alloc(0), Buffer.alloc(0)); + enr.verify(new Uint8Array(), new Uint8Array()); assert.fail("Expect error here"); } catch (err: unknown) { const e = err as Error; @@ -153,11 +155,11 @@ describe("ENR", function () { it("should throw error - no public key", () => { try { const enr = new ENR( - { id: Buffer.from("v4") }, + { id: utf8ToBytes("v4") }, BigInt(0), - Buffer.alloc(0) + new Uint8Array() ); - enr.verify(Buffer.alloc(0), Buffer.alloc(0)); + enr.verify(new Uint8Array(), new Uint8Array()); assert.fail("Expect error here"); } catch (err: unknown) { const e = err as Error; @@ -170,19 +172,18 @@ describe("ENR", function () { "enr:-Ku4QMh15cIjmnq-co5S3tYaNXxDzKTgj0ufusA-QfZ66EWHNsULt2kb0eTHoo1Dkjvvf6CAHDS1Di-htjiPFZzaIPcLh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD2d10HAAABE________x8AgmlkgnY0gmlwhHZFkMSJc2VjcDI1NmsxoQIWSDEWdHwdEA3Lw2B_byeFQOINTZ0GdtF9DBjes6JqtIN1ZHCCIyg"; const enr = ENR.decodeTxt(txt); // should have id and public key inside ENR - expect(enr.verify(Buffer.alloc(32), Buffer.alloc(64))).to.be.false; + expect(enr.verify(new Uint8Array(32), new Uint8Array(64))).to.be.false; }); }); describe("Static tests", () => { - let privateKey: Buffer; + let privateKey: Uint8Array; let record: ENR; beforeEach(() => { const seq = 1n; - privateKey = Buffer.from( - "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291", - "hex" + privateKey = hexToBytes( + "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" ); record = ENR.createV4(v4.publicKey(privateKey)); record.setLocationMultiaddr(new Multiaddr("/ip4/127.0.0.1/udp/30303")); @@ -216,13 +217,12 @@ describe("ENR", function () { }); describe("Multiaddr getters and setters", () => { - let privateKey: Buffer; + let privateKey: Uint8Array; let record: ENR; beforeEach(() => { - privateKey = Buffer.from( - "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291", - "hex" + privateKey = hexToBytes( + "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" ); record = ENR.createV4(v4.publicKey(privateKey)); }); diff --git a/src/lib/enr/enr.ts b/src/lib/enr/enr.ts index 16781d6e2e..d20e94c6af 100644 --- a/src/lib/enr/enr.ts +++ b/src/lib/enr/enr.ts @@ -1,13 +1,13 @@ +import * as RLP from "@ethersproject/rlp"; import { Multiaddr, protocols } from "multiaddr"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: No types available import muConvert from "multiaddr/src/convert"; import PeerId from "peer-id"; -import * as RLP from "rlp"; import { encode as varintEncode } from "varint"; import { bytesToUtf8, utf8ToBytes } from "../utf8"; -import { base64ToBytes, bytesToBase64, bytesToHex } from "../utils"; +import { base64ToBytes, bytesToBase64, bytesToHex, hexToBytes } from "../utils"; import { ERR_INVALID_ID, ERR_NO_SIGNATURE, MAX_RECORD_SIZE } from "./constants"; import { @@ -60,7 +60,7 @@ export class ENR extends Map { } } - static decodeFromValues(decoded: Buffer[]): ENR { + static decodeFromValues(decoded: Uint8Array[]): ENR { if (!Array.isArray(decoded)) { throw new Error("Decoded ENR must be an array"); } @@ -78,22 +78,19 @@ export class ENR extends Map { } const obj: Record = {}; for (let i = 0; i < kvs.length; i += 2) { - obj[kvs[i].toString()] = new Uint8Array(kvs[i + 1]); + obj[bytesToUtf8(kvs[i])] = kvs[i + 1]; } - const enr = new ENR( - obj, - BigInt("0x" + bytesToHex(seq)), - new Uint8Array(signature) - ); + const enr = new ENR(obj, BigInt("0x" + bytesToHex(seq)), signature); - if (!enr.verify(RLP.encode([seq, ...kvs]), signature)) { + const rlpEncodedBytes = hexToBytes(RLP.encode([seq, ...kvs])); + if (!enr.verify(rlpEncodedBytes, signature)) { throw new Error("Unable to verify ENR signature"); } return enr; } static decode(encoded: Uint8Array): ENR { - const decoded = RLP.decode(encoded) as unknown as Buffer[]; + const decoded = RLP.decode(encoded).map(hexToBytes); return ENR.decodeFromValues(decoded); } @@ -434,15 +431,16 @@ export class ENR extends Map { return this.signature; } - encodeToValues(privateKey?: Uint8Array): (ENRKey | ENRValue | number)[] { + encodeToValues(privateKey?: Uint8Array): (ENRKey | ENRValue | number[])[] { // sort keys and flatten into [k, v, k, v, ...] - const content: Array = Array.from(this.keys()) + const content: Array = Array.from(this.keys()) .sort((a, b) => a.localeCompare(b)) .map((k) => [k, this.get(k)] as [ENRKey, ENRValue]) + .map(([k, v]) => [utf8ToBytes(k), v]) .flat(); - content.unshift(Number(this.seq)); + content.unshift(new Uint8Array([Number(this.seq)])); if (privateKey) { - content.unshift(this.sign(RLP.encode(content), privateKey)); + content.unshift(this.sign(hexToBytes(RLP.encode(content)), privateKey)); } else { if (!this.signature) { throw new Error(ERR_NO_SIGNATURE); @@ -453,7 +451,7 @@ export class ENR extends Map { } encode(privateKey?: Uint8Array): Uint8Array { - const encoded = RLP.encode(this.encodeToValues(privateKey)); + const encoded = hexToBytes(RLP.encode(this.encodeToValues(privateKey))); if (encoded.length >= MAX_RECORD_SIZE) { throw new Error("ENR must be less than 300 bytes"); } diff --git a/src/lib/enr/keypair/index.ts b/src/lib/enr/keypair/index.ts index c4ed54ff0b..512eebce52 100644 --- a/src/lib/enr/keypair/index.ts +++ b/src/lib/enr/keypair/index.ts @@ -60,7 +60,7 @@ export function createKeypairFromPeerId(peerId: PeerId): IKeypair { const pub = keysPBM.PublicKey.decode(peerId.pubKey.bytes); return createKeypair( pub.Type as KeypairType, - peerId.privKey ? Buffer.from(peerId.privKey.marshal()) : undefined, - Buffer.from(pub.Data) + peerId.privKey ? peerId.privKey.marshal() : undefined, + pub.Data ); } diff --git a/src/lib/enr/keypair/secp256k1.ts b/src/lib/enr/keypair/secp256k1.ts index b7a3d5e75c..0df96e1d61 100644 --- a/src/lib/enr/keypair/secp256k1.ts +++ b/src/lib/enr/keypair/secp256k1.ts @@ -8,20 +8,26 @@ export function secp256k1PublicKeyToCompressed( publicKey: Uint8Array ): Uint8Array { if (publicKey.length === 64) { - publicKey = Buffer.concat([Buffer.from([4]), publicKey]); + const _publicKey = new Uint8Array(publicKey.length + 1); + _publicKey.set([4]); + _publicKey.set(publicKey, 1); + publicKey = _publicKey; } - return Buffer.from(secp256k1.publicKeyConvert(publicKey, true)); + return secp256k1.publicKeyConvert(publicKey, true); } export function secp256k1PublicKeyToFull(publicKey: Uint8Array): Uint8Array { if (publicKey.length === 64) { - return Buffer.concat([Buffer.from([4]), publicKey]); + const _publicKey = new Uint8Array(publicKey.length + 1); + _publicKey.set([4]); + _publicKey.set(publicKey, 1); + publicKey = _publicKey; } - return Buffer.from(secp256k1.publicKeyConvert(publicKey, false)); + return secp256k1.publicKeyConvert(publicKey, false); } export function secp256k1PublicKeyToRaw(publicKey: Uint8Array): Uint8Array { - return Buffer.from(secp256k1.publicKeyConvert(publicKey, false).slice(1)); + return secp256k1.publicKeyConvert(publicKey, false).slice(1); } export const Secp256k1Keypair: IKeypairClass = class Secp256k1Keypair @@ -40,9 +46,9 @@ export const Secp256k1Keypair: IKeypairClass = class Secp256k1Keypair } static async generate(): Promise { - const privateKey = Buffer.from(await randomBytes(32)); + const privateKey = await randomBytes(32); const publicKey = secp256k1.publicKeyCreate(privateKey); - return new Secp256k1Keypair(privateKey, Buffer.from(publicKey)); + return new Secp256k1Keypair(privateKey, publicKey); } privateKeyVerify(key = this._privateKey): boolean { @@ -61,7 +67,11 @@ export const Secp256k1Keypair: IKeypairClass = class Secp256k1Keypair sign(msg: Uint8Array): Uint8Array { const { signature, recid } = secp256k1.ecdsaSign(msg, this.privateKey); - return Buffer.concat([signature, Buffer.from([recid])]); + + const result = new Uint8Array(signature.length + 1); + result.set(signature); + result.set([recid], signature.length); + return result; } verify(msg: Uint8Array, sig: Uint8Array): boolean { diff --git a/src/lib/enr/v4.ts b/src/lib/enr/v4.ts index 5a8d74794f..0738a30732 100644 --- a/src/lib/enr/v4.ts +++ b/src/lib/enr/v4.ts @@ -11,16 +11,16 @@ export function hash(input: Uint8Array): Uint8Array { } export async function createPrivateKey(): Promise { - return new Uint8Array(await randomBytes(32)); + return randomBytes(32); } export function publicKey(privKey: Uint8Array): Uint8Array { - return new Uint8Array(secp256k1.publicKeyCreate(privKey)); + return secp256k1.publicKeyCreate(privKey); } export function sign(privKey: Uint8Array, msg: Uint8Array): Uint8Array { const { signature } = secp256k1.ecdsaSign(hash(msg), privKey); - return new Uint8Array(signature); + return signature; } export function verify( diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 7b165817ac..937ce2db3e 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -78,8 +78,8 @@ export function equalByteArrays( /** * Return Keccak-256 of the input. */ -export function keccak256Buf(message: Message): Buffer { - return Buffer.from(keccak256.arrayBuffer(message)); +export function keccak256Buf(message: Message): Uint8Array { + return new Uint8Array(keccak256.arrayBuffer(message)); } /** diff --git a/src/lib/waku.ts b/src/lib/waku.ts index 42908da2b4..e6717acfb8 100644 --- a/src/lib/waku.ts +++ b/src/lib/waku.ts @@ -1,4 +1,3 @@ -import { bytes } from "@chainsafe/libp2p-noise/dist/src/@types/basic"; import { Noise } from "@chainsafe/libp2p-noise/dist/src/noise"; import debug from "debug"; import Libp2p, { Connection, Libp2pModules, Libp2pOptions } from "libp2p"; @@ -86,7 +85,7 @@ export interface CreateOptions { * by [`Libp2p.create`](https://github.com/libp2p/js-libp2p/blob/master/doc/API.md#create) * This is only used for test purposes to not run out of entropy during CI runs. */ - staticNoiseKey?: bytes; + staticNoiseKey?: Uint8Array; /** * Use libp2p-bootstrap to discover and connect to new nodes. * @@ -181,11 +180,15 @@ export class Waku { options?.libp2p?.modules ); + const staticNoiseKey = options?.staticNoiseKey + ? Buffer.from(options?.staticNoiseKey) + : undefined; + // streamMuxer, connection encryption and pubsub are overridden // as those are the only ones currently supported by Waku nodes. libp2pOpts.modules = Object.assign(libp2pOpts.modules, { streamMuxer: [Mplex], - connEncryption: [new Noise(options?.staticNoiseKey)], + connEncryption: [new Noise(staticNoiseKey)], pubsub: WakuRelay, }); diff --git a/src/lib/waku_message/index.node.spec.ts b/src/lib/waku_message/index.node.spec.ts index 5e0cda3f8f..5e5c953630 100644 --- a/src/lib/waku_message/index.node.spec.ts +++ b/src/lib/waku_message/index.node.spec.ts @@ -8,8 +8,8 @@ import { WakuRelayMessage, } from "../../test_utils"; import { delay } from "../../test_utils/delay"; -import { bytesToUtf8 } from "../utf8"; -import { hexToBytes } from "../utils"; +import { bytesToUtf8, utf8ToBytes } from "../utf8"; +import { bytesToHex, hexToBytes } from "../utils"; import { Protocols, Waku } from "../waku"; import { @@ -61,7 +61,7 @@ describe("Waku Message [node only]", function () { const messageText = "Here is an encrypted message."; const message: WakuRelayMessage = { contentTopic: TestContentTopic, - payload: Buffer.from(messageText, "utf-8").toString("hex"), + payload: bytesToHex(utf8ToBytes(messageText)), }; const privateKey = generatePrivateKey(); @@ -126,7 +126,7 @@ describe("Waku Message [node only]", function () { const messageText = "Here is a message encrypted in a symmetric manner."; const message: WakuRelayMessage = { contentTopic: TestContentTopic, - payload: Buffer.from(messageText, "utf-8").toString("hex"), + payload: bytesToHex(utf8ToBytes(messageText)), }; dbg("Generate symmetric key"); diff --git a/src/lib/waku_message/index.ts b/src/lib/waku_message/index.ts index 2f6fe7ffcf..b18855f6c2 100644 --- a/src/lib/waku_message/index.ts +++ b/src/lib/waku_message/index.ts @@ -1,11 +1,9 @@ -// Ensure that this class matches the proto interface while -import { Buffer } from "buffer"; - import debug from "debug"; import { Reader } from "protobufjs/minimal"; // Protecting the user from protobuf oddities import * as proto from "../../proto/waku/v2/message"; +import { bytesToUtf8, utf8ToBytes } from "../utf8"; import * as version_1 from "./version_1"; @@ -56,7 +54,7 @@ export class WakuMessage { contentTopic: string, opts?: Options ): Promise { - const payload = Buffer.from(utf8, "utf-8"); + const payload = utf8ToBytes(utf8); return WakuMessage.fromBytes(payload, contentTopic, opts); } @@ -256,7 +254,7 @@ export class WakuMessage { return ""; } - return Buffer.from(this.proto.payload).toString("utf-8"); + return bytesToUtf8(this.proto.payload); } get payload(): Uint8Array | undefined { diff --git a/src/lib/waku_relay/index.ts b/src/lib/waku_relay/index.ts index 4f4b59108b..13cea4fbb5 100644 --- a/src/lib/waku_relay/index.ts +++ b/src/lib/waku_relay/index.ts @@ -121,7 +121,7 @@ export class WakuRelay extends Gossipsub { */ public async send(message: WakuMessage): Promise { const msg = message.encode(); - await super.publish(this.pubSubTopic, Buffer.from(msg)); + await super.publish(this.pubSubTopic, msg); } /** diff --git a/src/test_utils/constants.ts b/src/test_utils/constants.ts index 4538208f17..ca2bd3b523 100644 --- a/src/test_utils/constants.ts +++ b/src/test_utils/constants.ts @@ -5,5 +5,22 @@ * @module */ -export const NOISE_KEY_1 = Buffer.alloc(32, 1); -export const NOISE_KEY_2 = Buffer.alloc(32, 2); +export const NOISE_KEY_1 = new Uint8Array( + ((): number[] => { + const b = []; + for (let i = 0; i < 32; i++) { + b.push(1); + } + return b; + })() +); + +export const NOISE_KEY_2 = new Uint8Array( + ((): number[] => { + const b = []; + for (let i = 0; i < 32; i++) { + b.push(2); + } + return b; + })() +);