@@ -2,10 +2,10 @@ import type { IDecodedMessage, IProtoMessage } from "@waku/interfaces";
22import { bytesToHex , hexToBytes } from "@waku/utils/bytes" ;
33import { expect } from "chai" ;
44
5- import { messageHash } from "./index.js" ;
5+ import { messageHash , messageHashStr } from "./index.js" ;
66
77// https://rfc.vac.dev/spec/14/#test-vectors
8- describe ( "RFC Test Vectors" , ( ) => {
8+ describe ( "Message Hash: RFC Test Vectors" , ( ) => {
99 it ( "Waku message hash computation (meta size of 12 bytes)" , ( ) => {
1010 const expectedHash =
1111 "64cce733fed134e83da02b02c6f689814872b1a0ac97ea56b76095c3c72bfe05" ;
@@ -98,6 +98,7 @@ describe("RFC Test Vectors", () => {
9898 "3f11bc950dce0e3ffdcf205ae6414c01130bb5d9f20644869bff80407fa52c8f" ;
9999 const pubsubTopic = "/waku/2/default-waku/proto" ;
100100 const message : IDecodedMessage = {
101+ version : 0 ,
101102 payload : new Uint8Array ( ) ,
102103 pubsubTopic,
103104 contentTopic : "/waku/2/default-content/proto" ,
@@ -110,3 +111,71 @@ describe("RFC Test Vectors", () => {
110111 expect ( bytesToHex ( hash ) ) . to . equal ( expectedHash ) ;
111112 } ) ;
112113} ) ;
114+
115+ describe ( "messageHash and messageHashStr" , ( ) => {
116+ const pubsubTopic = "/waku/2/default-waku/proto" ;
117+ const testMessage : IProtoMessage = {
118+ payload : hexToBytes ( "0x010203045445535405060708" ) ,
119+ contentTopic : "/waku/2/default-content/proto" ,
120+ meta : hexToBytes ( "0x73757065722d736563726574" ) ,
121+ timestamp : BigInt ( "0x175789bfa23f8400" ) ,
122+ ephemeral : undefined ,
123+ rateLimitProof : undefined ,
124+ version : undefined
125+ } ;
126+
127+ it ( "messageHash returns a Uint8Array" , ( ) => {
128+ const hash = messageHash ( pubsubTopic , testMessage ) ;
129+ expect ( hash ) . to . be . instanceOf ( Uint8Array ) ;
130+ expect ( hash . length ) . to . equal ( 32 ) ; // SHA-256 hash is 32 bytes
131+ } ) ;
132+
133+ it ( "messageHashStr returns a hex string" , ( ) => {
134+ const hashStr = messageHashStr ( pubsubTopic , testMessage ) ;
135+ expect ( typeof hashStr ) . to . equal ( "string" ) ;
136+ expect ( hashStr . length ) . to . equal ( 64 ) ; // SHA-256 hash is 32 bytes = 64 hex chars
137+ expect ( hashStr ) . to . match ( / ^ [ 0 - 9 a - f ] + $ / ) ; // Should be a valid hex string
138+ } ) ;
139+
140+ it ( "messageHashStr returns the same value as bytesToHex(messageHash)" , ( ) => {
141+ const hash = messageHash ( pubsubTopic , testMessage ) ;
142+ const hashStrFromBytes = bytesToHex ( hash ) ;
143+ const hashStr = messageHashStr ( pubsubTopic , testMessage ) ;
144+ expect ( hashStr ) . to . equal ( hashStrFromBytes ) ;
145+ } ) ;
146+
147+ it ( "messageHashStr works with IDecodedMessage" , ( ) => {
148+ const decodedMessage : IDecodedMessage = {
149+ version : 0 ,
150+ payload : new Uint8Array ( [ 1 , 2 , 3 , 4 ] ) ,
151+ pubsubTopic,
152+ contentTopic : "/waku/2/default-content/proto" ,
153+ meta : new Uint8Array ( [ 5 , 6 , 7 , 8 ] ) ,
154+ timestamp : new Date ( "2024-04-30T10:54:14.978Z" ) ,
155+ ephemeral : undefined ,
156+ rateLimitProof : undefined
157+ } ;
158+
159+ const hashStr = messageHashStr ( pubsubTopic , decodedMessage ) ;
160+ expect ( typeof hashStr ) . to . equal ( "string" ) ;
161+ expect ( hashStr . length ) . to . equal ( 64 ) ;
162+ } ) ;
163+
164+ it ( "messageHashStr produces consistent results for the same input" , ( ) => {
165+ const hashStr1 = messageHashStr ( pubsubTopic , testMessage ) ;
166+ const hashStr2 = messageHashStr ( pubsubTopic , testMessage ) ;
167+ expect ( hashStr1 ) . to . equal ( hashStr2 ) ;
168+ } ) ;
169+
170+ it ( "messageHashStr produces different results for different inputs" , ( ) => {
171+ const hashStr1 = messageHashStr ( pubsubTopic , testMessage ) ;
172+
173+ const differentMessage = {
174+ ...testMessage ,
175+ payload : hexToBytes ( "0x0102030454455354050607080A" ) // Different payload
176+ } ;
177+
178+ const hashStr2 = messageHashStr ( pubsubTopic , differentMessage ) ;
179+ expect ( hashStr1 ) . to . not . equal ( hashStr2 ) ;
180+ } ) ;
181+ } ) ;
0 commit comments