docs.waku.org/docs/sign_messages_version_1.md

2.8 KiB

summary authors date
Demonstrate how to sign messages using Waku
Fryorcraken
2022-08-15

Sign Messages Using Waku Message Version 1

The Waku Message format provides an easy way to sign messages using elliptic curve cryptography.

It also allows the sender to encrypt messages, see Encrypt Messages Using Waku Message Version 1 to learn how.

You can find more details about Waku Message Payload Signature in 26/WAKU-PAYLOAD.

See Cryptographic Libraries for more details on the cryptographic libraries used by js-waku.

Create new keypair

Generate a new keypair to sign your messages:

import { generatePrivateKey, getPublicKey } from "js-waku";

const privateKey = generatePrivateKey();
const publicKey = getPublicKey(privateKey);

Sign Waku Messages

As per version 1's specs, signatures are only included in encrypted messages. In the case where your app does not need encryption then you could use symmetric encryption with a trivial key.

You can learn more about encryption at Encrypt Messages Using Waku Message Version 1.

Using symmetric encryption

Given symKey the symmetric key used for encryption:

import { WakuMessage } from "js-waku";

const message = await WakuMessage.fromBytes(payload, myAppContentTopic, {
  encPublicKey: symKey,
  sigPrivKey: privateKey,
});

If encryption is not needed for your use case, then you can create a symmetric key from the content topic:

import { hexToBuf } from "js-waku/lib/utils";
import { keccak256 } from "ethers/lib/utils";

const symKey = hexToBuf(keccak256(Buffer.from(myAppContentTopic, "utf-8")));

symKey can then be used to encrypt and decrypt messages on myAppContentTopic content topic. Read How to Choose a Content Topic to learn more about content topics.

Using asymmetric encryption

Given recipientPublicKey the public key of the message's recipient:

import { WakuMessage } from "js-waku";

const message = await WakuMessage.fromBytes(payload, myAppContentTopic, {
  encPublicKey: recipientPublicKey,
  sigPrivKey: privateKey,
});

Verify Waku Message signatures

Two fields are available on signed WakuMessages:

  • signaturePublicKey: Holds the public key of the signer,
  • signature: Holds the actual signature.

Thus, if you expect messages to be signed by Alice, you can simply compare WakuMessage.signaturePublicKey with Alice's public key. As comparing hex string can lead to issues (is the 0x prefix present?), simply use helper function equalByteArrays.

import { equalByteArrays } from "js-waku/lib/utils";

const sigPubKey = wakuMessage.signaturePublicKey;

const isSignedByAlice = sigPubKey && equalByteArrays(sigPubKey, alicePublicKey);

if (!isSignedByAlice) {
  // Message is not signed by Alice
}