74 lines
2.2 KiB
TypeScript
Raw Normal View History

2021-06-11 15:33:29 +10:00
import '@ethersproject/shims';
2021-05-28 15:35:50 +10:00
import { ethers } from 'ethers';
import { Signer } from '@ethersproject/abstract-signer';
import { PublicKeyMessage } from './messaging/wire';
import { hexToBuf, equalByteArrays, bufToHex } from 'js-waku/lib/utils';
import { generatePrivateKey, getPublicKey } from 'js-waku';
2021-05-28 15:35:50 +10:00
2021-06-11 15:33:29 +10:00
export interface KeyPair {
privateKey: Uint8Array;
publicKey: Uint8Array;
2021-06-11 15:33:29 +10:00
}
2021-05-28 15:35:50 +10:00
/**
* Generate new encryption keypair.
2021-05-28 15:35:50 +10:00
*/
export async function generateEncryptionKeyPair(): Promise<KeyPair> {
const privateKey = generatePrivateKey();
const publicKey = getPublicKey(privateKey);
return { privateKey, publicKey };
2021-05-28 15:35:50 +10:00
}
/**
* Sign the encryption public key with Web3. This can then be published to let other
* users know to use this public key to encrypt messages for the
2021-06-22 10:48:54 +10:00
* Ethereum Address holder.
2021-05-28 15:35:50 +10:00
*/
2021-06-11 15:33:29 +10:00
export async function createPublicKeyMessage(
web3Signer: Signer,
encryptionPublicKey: Uint8Array
2021-06-11 15:33:29 +10:00
): Promise<PublicKeyMessage> {
2021-05-28 15:35:50 +10:00
const ethAddress = await web3Signer.getAddress();
const signature = await web3Signer.signMessage(
formatPublicKeyForSignature(encryptionPublicKey)
2021-06-11 15:33:29 +10:00
);
return new PublicKeyMessage({
encryptionPublicKey: encryptionPublicKey,
ethAddress: hexToBuf(ethAddress),
signature: hexToBuf(signature),
});
2021-05-28 15:35:50 +10:00
}
/**
* Validate that the Encryption Public Key was signed by the holder of the given Ethereum address.
2021-05-28 15:35:50 +10:00
*/
export function validatePublicKeyMessage(msg: PublicKeyMessage): boolean {
const formattedMsg = formatPublicKeyForSignature(msg.encryptionPublicKey);
2021-05-28 15:35:50 +10:00
try {
2021-07-02 11:44:04 +10:00
const sigAddress = ethers.utils.verifyMessage(formattedMsg, msg.signature);
2021-07-09 15:03:23 +10:00
return equalByteArrays(sigAddress, msg.ethAddress);
2021-06-11 15:33:29 +10:00
} catch (e) {
console.log(
'Failed to verify signature for Public Key Message',
2021-07-02 11:44:04 +10:00
formattedMsg,
msg
);
2021-05-28 15:35:50 +10:00
return false;
}
}
/**
* Prepare encryption public key to be signed for publication.
* The public key is set in on Object `{ encryptionPublicKey: string; }`, converted
2021-05-28 15:35:50 +10:00
* to JSON and then hashed with Keccak256.
* The usage of the object helps ensure the signature is only used in an Eth-PM
2021-05-28 15:35:50 +10:00
* context.
*/
function formatPublicKeyForSignature(encryptionPublicKey: Uint8Array): string {
2021-06-24 16:05:22 +10:00
return JSON.stringify({
encryptionPublicKey: bufToHex(encryptionPublicKey),
2021-06-11 15:33:29 +10:00
});
2021-06-24 16:05:22 +10:00
}