mirror of https://github.com/waku-org/js-waku.git
feat: implement deterministic message hash logic
This commit is contained in:
parent
76d1d4faf5
commit
fe57461329
|
@ -2,6 +2,7 @@
|
|||
"packages/utils": "0.0.4",
|
||||
"packages/proto": "0.0.4",
|
||||
"packages/interfaces": "0.0.11",
|
||||
"packages/message-hash": "0.1.0",
|
||||
"packages/enr": "0.0.10",
|
||||
"packages/peer-exchange": "0.0.9",
|
||||
"packages/core": "0.0.16",
|
||||
|
|
|
@ -43,4 +43,9 @@ module.exports = [
|
|||
path: "packages/core/bundle/index.js",
|
||||
import: "{ wakuStore }",
|
||||
},
|
||||
{
|
||||
name: "Deterministic Message Hashing",
|
||||
path: "packages/message-hash/bundle/index.js",
|
||||
import: "{ messageHash }",
|
||||
},
|
||||
];
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
"packages/utils",
|
||||
"packages/proto",
|
||||
"packages/interfaces",
|
||||
"packages/message-hash",
|
||||
"packages/enr",
|
||||
"packages/core",
|
||||
"packages/message-hash",
|
||||
"packages/peer-exchange",
|
||||
"packages/dns-discovery",
|
||||
"packages/message-encryption",
|
||||
|
@ -29596,6 +29596,10 @@
|
|||
"name": "@waku/message-hash",
|
||||
"version": "0.0.10",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.2.0",
|
||||
"@waku/utils": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^24.0.1",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
|
@ -29606,6 +29610,7 @@
|
|||
"@typescript-eslint/eslint-plugin": "^5.54.1",
|
||||
"@typescript-eslint/parser": "^5.51.0",
|
||||
"@waku/build-utils": "*",
|
||||
"@waku/interfaces": "*",
|
||||
"chai": "^4.3.7",
|
||||
"cspell": "^6.28.0",
|
||||
"eslint": "^8.35.0",
|
||||
|
@ -34724,6 +34729,7 @@
|
|||
"@waku/message-hash": {
|
||||
"version": "file:packages/message-hash",
|
||||
"requires": {
|
||||
"@noble/hashes": "^1.2.0",
|
||||
"@rollup/plugin-commonjs": "^24.0.1",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
|
@ -34733,6 +34739,8 @@
|
|||
"@typescript-eslint/eslint-plugin": "^5.54.1",
|
||||
"@typescript-eslint/parser": "^5.51.0",
|
||||
"@waku/build-utils": "*",
|
||||
"@waku/interfaces": "*",
|
||||
"@waku/utils": "*",
|
||||
"chai": "^4.3.7",
|
||||
"cspell": "^6.28.0",
|
||||
"eslint": "^8.35.0",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@waku/message-hash",
|
||||
"version": "0.0.10",
|
||||
"version": "0.1.0",
|
||||
"description": "TypeScript implementation of the Deterministic Message Hashing as specified in 14/WAKU2-MESSAGE",
|
||||
"types": "./dist/index.d.ts",
|
||||
"module": "./dist/index.js",
|
||||
|
@ -51,6 +51,10 @@
|
|||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.2.0",
|
||||
"@waku/utils": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^24.0.1",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
|
@ -61,6 +65,7 @@
|
|||
"@typescript-eslint/eslint-plugin": "^5.54.1",
|
||||
"@typescript-eslint/parser": "^5.51.0",
|
||||
"@waku/build-utils": "*",
|
||||
"@waku/interfaces": "*",
|
||||
"chai": "^4.3.7",
|
||||
"cspell": "^6.28.0",
|
||||
"eslint": "^8.35.0",
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
import type { IProtoMessage } from "@waku/interfaces";
|
||||
import { bytesToHex, hexToBytes } from "@waku/utils/bytes";
|
||||
import { expect } from "chai";
|
||||
|
||||
import { messageHash } from "./index.js";
|
||||
|
||||
// https://rfc.vac.dev/spec/14/#test-vectors
|
||||
describe("RFC Test Vectors", () => {
|
||||
it("Waku message hash computation", () => {
|
||||
const expectedHash =
|
||||
"4fdde1099c9f77f6dae8147b6b3179aba1fc8e14a7bf35203fc253ee479f135f";
|
||||
|
||||
const pubSubTopic = "/waku/2/default-waku/proto";
|
||||
const message: IProtoMessage = {
|
||||
payload: hexToBytes("0x010203045445535405060708"),
|
||||
contentTopic: "/waku/2/default-content/proto",
|
||||
meta: hexToBytes("0x73757065722d736563726574"),
|
||||
ephemeral: undefined,
|
||||
rateLimitProof: undefined,
|
||||
timestamp: undefined,
|
||||
version: undefined,
|
||||
};
|
||||
|
||||
const hash = messageHash(pubSubTopic, message);
|
||||
|
||||
expect(bytesToHex(hash)).to.equal(expectedHash);
|
||||
});
|
||||
|
||||
it("Waku message hash computation (meta attribute not present)", () => {
|
||||
const expectedHash =
|
||||
"87619d05e563521d9126749b45bd4cc2430df0607e77e23572d874ed9c1aaa62";
|
||||
|
||||
const pubSubTopic = "/waku/2/default-waku/proto";
|
||||
const message: IProtoMessage = {
|
||||
payload: hexToBytes("0x010203045445535405060708"),
|
||||
contentTopic: "/waku/2/default-content/proto",
|
||||
meta: undefined,
|
||||
ephemeral: undefined,
|
||||
rateLimitProof: undefined,
|
||||
timestamp: undefined,
|
||||
version: undefined,
|
||||
};
|
||||
|
||||
const hash = messageHash(pubSubTopic, message);
|
||||
|
||||
expect(bytesToHex(hash)).to.equal(expectedHash);
|
||||
});
|
||||
|
||||
it("Waku message hash computation (payload length 0)", () => {
|
||||
const expectedHash =
|
||||
"e1a9596237dbe2cc8aaf4b838c46a7052df6bc0d42ba214b998a8bfdbe8487d6";
|
||||
|
||||
const pubSubTopic = "/waku/2/default-waku/proto";
|
||||
const message: IProtoMessage = {
|
||||
payload: new Uint8Array(),
|
||||
contentTopic: "/waku/2/default-content/proto",
|
||||
meta: hexToBytes("0x73757065722d736563726574"),
|
||||
ephemeral: undefined,
|
||||
rateLimitProof: undefined,
|
||||
timestamp: undefined,
|
||||
version: undefined,
|
||||
};
|
||||
|
||||
const hash = messageHash(pubSubTopic, message);
|
||||
|
||||
expect(bytesToHex(hash)).to.equal(expectedHash);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
import { sha256 } from "@noble/hashes/sha256";
|
||||
import type { IProtoMessage } from "@waku/interfaces";
|
||||
import { concat, utf8ToBytes } from "@waku/utils/bytes";
|
||||
|
||||
/**
|
||||
* Deterministic Message Hashing as defined in
|
||||
* [14/WAKU2-MESSAGE](https://rfc.vac.dev/spec/14/#deterministic-message-hashing)
|
||||
*/
|
||||
export function messageHash(
|
||||
pubsubTopic: string,
|
||||
message: IProtoMessage
|
||||
): Uint8Array {
|
||||
const pubsubTopicBytes = utf8ToBytes(pubsubTopic);
|
||||
const contentTopicBytes = utf8ToBytes(message.contentTopic);
|
||||
|
||||
let bytesToHash;
|
||||
|
||||
if (message.meta) {
|
||||
bytesToHash = concat([
|
||||
pubsubTopicBytes,
|
||||
message.payload,
|
||||
contentTopicBytes,
|
||||
message.meta,
|
||||
]);
|
||||
} else {
|
||||
bytesToHash = concat([
|
||||
pubsubTopicBytes,
|
||||
message.payload,
|
||||
contentTopicBytes,
|
||||
]);
|
||||
}
|
||||
return sha256(bytesToHash);
|
||||
}
|
|
@ -9,9 +9,9 @@
|
|||
"packages/utils": {},
|
||||
"packages/proto": {},
|
||||
"packages/interfaces": {},
|
||||
"packages/message-hash": {},
|
||||
"packages/enr": {},
|
||||
"packages/peer-exchange": {},
|
||||
"packages/message-hash": {},
|
||||
"packages/core": {},
|
||||
"packages/dns-discovery": {},
|
||||
"packages/message-encryption": {},
|
||||
|
|
Loading…
Reference in New Issue