2022-08-15 02:28:04 +00:00
|
|
|
---
|
|
|
|
summary: Demonstrate how to sign messages using Waku
|
|
|
|
authors:
|
|
|
|
- Fryorcraken
|
|
|
|
date: 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,
|
2022-08-15 11:40:49 +00:00
|
|
|
see [Encrypt Messages Using Waku Message Version 1](/) to learn how.
|
2022-08-15 02:28:04 +00:00
|
|
|
|
|
|
|
You can find more details about Waku Message Payload Signature in [26/WAKU-PAYLOAD](https://rfc.vac.dev/spec/26/).
|
|
|
|
|
2022-08-15 11:40:49 +00:00
|
|
|
See [Cryptographic Libraries](/) for more details on the cryptographic libraries used by js-waku.
|
2022-08-15 02:28:04 +00:00
|
|
|
|
|
|
|
## Create new keypair
|
|
|
|
|
|
|
|
Generate a new keypair to sign your messages:
|
|
|
|
|
|
|
|
```ts
|
|
|
|
import { generatePrivateKey, getPublicKey } from "js-waku";
|
|
|
|
|
|
|
|
const privateKey = generatePrivateKey();
|
|
|
|
const publicKey = getPublicKey(privateKey);
|
|
|
|
```
|
|
|
|
|
|
|
|
## Sign Waku Messages
|
|
|
|
|
|
|
|
As per version 1's [specs](https://rfc.vac.dev/spec/26/), 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.
|
|
|
|
|
2022-08-15 11:40:49 +00:00
|
|
|
You can learn more about encryption at [Encrypt Messages Using Waku Message Version 1](/).
|
2022-08-15 02:28:04 +00:00
|
|
|
|
|
|
|
### Using symmetric encryption
|
|
|
|
|
|
|
|
Given `symKey` the symmetric key used for encryption:
|
|
|
|
|
|
|
|
```ts
|
|
|
|
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:
|
|
|
|
|
|
|
|
```ts
|
|
|
|
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.
|
2022-08-15 11:40:49 +00:00
|
|
|
Read [How to Choose a Content Topic](/) to learn more about content topics.
|
2022-08-15 02:28:04 +00:00
|
|
|
|
|
|
|
### Using asymmetric encryption
|
|
|
|
|
|
|
|
Given `recipientPublicKey` the public key of the message's recipient:
|
|
|
|
|
|
|
|
```ts
|
|
|
|
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 `WakuMessage`s:
|
|
|
|
|
|
|
|
- `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`.
|
|
|
|
|
|
|
|
```ts
|
|
|
|
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
|
|
|
|
}
|
|
|
|
```
|