Receive public key from network and verify it

This commit is contained in:
Franck Royer 2021-06-11 16:00:48 +10:00
parent 3bd6b76916
commit 69033f4ea5
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
3 changed files with 65 additions and 22 deletions

View File

@ -12,9 +12,10 @@ import {
PublicKeyMessage, PublicKeyMessage,
generateEthDmKeyPair, generateEthDmKeyPair,
KeyPair, KeyPair,
validatePublicKeyMessage,
} from './crypto'; } from './crypto';
const ContentTopic = '/eth-dm/1/public-key/json'; const PublicKeyContentTopic = '/eth-dm/1/public-key/json';
declare let window: any; declare let window: any;
@ -22,17 +23,23 @@ function App() {
const [waku, setWaku] = useState<Waku>(); const [waku, setWaku] = useState<Waku>();
const [provider, setProvider] = useState<Web3Provider>(); const [provider, setProvider] = useState<Web3Provider>();
const [ethDmKeyPair, setEthDmKeyPair] = useState<KeyPair>(); const [ethDmKeyPair, setEthDmKeyPair] = useState<KeyPair>();
const [publicKeyMsg, setPublicKeyMsg] = useState<PublicKeyMessage>();
useEffect(() => { useEffect(() => {
if (provider) return; if (provider) return;
const _provider = new ethers.providers.Web3Provider(window.ethereum); try {
setProvider(_provider); const _provider = new ethers.providers.Web3Provider(window.ethereum);
setProvider(_provider);
} catch (e) {
console.error('No web3 provider available');
}
}, [provider]); }, [provider]);
useEffect(() => { useEffect(() => {
if (waku) return; if (waku) return;
initWaku() initWaku()
.then((wakuNode) => { .then((wakuNode) => {
console.log('waku: ready');
setWaku(wakuNode); setWaku(wakuNode);
}) })
.catch((e) => { .catch((e) => {
@ -40,7 +47,7 @@ function App() {
}); });
}, [waku]); }, [waku]);
useEffect(() => { const generateKeyPair = () => {
if (ethDmKeyPair) return; if (ethDmKeyPair) return;
if (!provider) return; if (!provider) return;
@ -51,29 +58,45 @@ function App() {
.catch((e) => { .catch((e) => {
console.error('Failed to generate Key Pair', e); console.error('Failed to generate Key Pair', e);
}); });
}, [ethDmKeyPair, provider]); };
const onClick = () => { useEffect(() => {
if (!waku) return;
waku.relay.addObserver(handlePublicKeyMessage, [PublicKeyContentTopic]);
});
const broadcastPublicKey = () => {
if (!ethDmKeyPair) return; if (!ethDmKeyPair) return;
if (!provider) return; if (!provider) return;
if (!waku) return; if (!waku) return;
createPublicKeyMessage(provider.getSigner(), ethDmKeyPair.publicKey) if (publicKeyMsg) {
.then((msg) => { const wakuMsg = createWakuMessage(publicKeyMsg);
const wakuMsg = createWakuMessage(msg); waku.relay.send(wakuMsg).catch((e) => {
waku.relay.send(wakuMsg).catch((e) => { console.error('Failed to send Public Key Message');
console.error('Failed to send Public Key Message');
});
})
.catch((e) => {
console.error('Failed to creat Eth-Dm Publication message', e);
}); });
} else {
createPublicKeyMessage(provider.getSigner(), ethDmKeyPair.publicKey)
.then((msg) => {
setPublicKeyMsg(msg);
const wakuMsg = createWakuMessage(msg);
waku.relay.send(wakuMsg).catch((e) => {
console.error('Failed to send Public Key Message');
});
})
.catch((e) => {
console.error('Failed to creat Eth-Dm Publication message', e);
});
}
}; };
return ( return (
<div className="App"> <div className="App">
<header className="App-header"> <header className="App-header">
<button onClick={onClick} disabled={!ethDmKeyPair || !waku}> <button onClick={generateKeyPair} disabled={!provider}>
Generate Eth-DM Key Pair
</button>
<button onClick={broadcastPublicKey} disabled={!ethDmKeyPair || !waku}>
Broadcast Eth-DM Public Key Broadcast Eth-DM Public Key
</button> </button>
</header> </header>
@ -106,6 +129,26 @@ function getNodes() {
} }
function createWakuMessage(ethDmMsg: PublicKeyMessage): WakuMessage { function createWakuMessage(ethDmMsg: PublicKeyMessage): WakuMessage {
const payload = Buffer.from(JSON.stringify(ethDmMsg)); const payload = encode(ethDmMsg);
return WakuMessage.fromBytes(payload, ContentTopic); return WakuMessage.fromBytes(payload, PublicKeyContentTopic);
}
function handlePublicKeyMessage(msg: WakuMessage) {
if (msg.payload) {
const publicKeyMsg = decode(msg.payload);
console.log('publicKeyMsg', publicKeyMsg);
const res = validatePublicKeyMessage(publicKeyMsg);
console.log(`Public Key Message Received, valid: ${res}`, publicKeyMsg);
}
}
function encode(msg: PublicKeyMessage): Buffer {
const jsonStr = JSON.stringify(msg);
return Buffer.from(jsonStr, 'utf-8');
}
function decode(bytes: Uint8Array): PublicKeyMessage {
const buf = Buffer.from(bytes);
const str = buf.toString('utf-8');
return JSON.parse(str);
} }

View File

@ -7,7 +7,7 @@ import { ethers } from 'ethers';
import { import {
createPublicKeyMessage, createPublicKeyMessage,
generateEthDmKeyPair, generateEthDmKeyPair,
verifyEthDmPublicKey, validatePublicKeyMessage,
} from './crypto'; } from './crypto';
import { MockProvider } from 'ethereum-waffle'; import { MockProvider } from 'ethereum-waffle';
import { waffleJest } from '@ethereum-waffle/jest'; import { waffleJest } from '@ethereum-waffle/jest';
@ -24,7 +24,7 @@ test('Signature of Eth-DM key is verifiable', async () => {
const ethDmMsg = await createPublicKeyMessage(wallet, ethDmKeys.publicKey); const ethDmMsg = await createPublicKeyMessage(wallet, ethDmKeys.publicKey);
console.log('Verify EthDm message'); console.log('Verify EthDm message');
const res = verifyEthDmPublicKey(ethDmMsg); const res = validatePublicKeyMessage(ethDmMsg);
expect(res).toBe(true); expect(res).toBe(true);
}); });

View File

@ -56,9 +56,9 @@ export async function createPublicKeyMessage(
} }
/** /**
* Verifies that the EthDm Public Key was signed by the holder of the given Ethereum address. * Validate that the EthDm Public Key was signed by the holder of the given Ethereum address.
*/ */
export function verifyEthDmPublicKey(msg: PublicKeyMessage): boolean { export function validatePublicKeyMessage(msg: PublicKeyMessage): boolean {
try { try {
const sigAddress = ethers.utils.verifyMessage( const sigAddress = ethers.utils.verifyMessage(
formatPublicKeyForSignature(msg.ethDmPublicKey), formatPublicKeyForSignature(msg.ethDmPublicKey),