Skip to content

Commit

Permalink
feat: implement deterministic message hash logic
Browse files Browse the repository at this point in the history
  • Loading branch information
fryorcraken committed May 6, 2023
1 parent 76d1d4f commit fe57461
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 3 deletions.
1 change: 1 addition & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 5 additions & 0 deletions .size-limit.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }",
},
];
10 changes: 9 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion packages/message-hash/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand Down
68 changes: 68 additions & 0 deletions packages/message-hash/src/index.spec.ts
Original file line number Diff line number Diff line change
@@ -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);
});
});
33 changes: 33 additions & 0 deletions packages/message-hash/src/index.ts
Original file line number Diff line number Diff line change
@@ -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);
}
2 changes: 1 addition & 1 deletion release-please-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {},
Expand Down

0 comments on commit fe57461

Please sign in to comment.