+ How it Works:
+ The first thing to understand is how public key cryptography works.
+
+ Essentially, you generate a pair of keys that can undo the operations of
+ each other. If you encrypt a message with your public key, it can only be
+ decrypted by your private key.
+
+
+

+
+
+ This is why you're safe to share your "Request URL" out in the open. Anyone
+ who accesses this URL will receive your public key, and encrypt the message
+ with it along with their own private key. When you receive the URL with
+ their encrypted message, you take their public key and your private key to
+ undo the operations of their private key and your public key.
+
+ But of course it's not as simple as that
+
+ Traditional public-key cryptography like RSA is limited in the messages it
+ can encrypt by the size of the public key. To overcome this limitation, we
+ use ECDH for short public keys that can encrypt an arbitrary amount of data
+ by establishing a shared "symmetric" key for encryption/decryption, which is
+ beyond the scope of this explanation. But the following chart should give
+ you a general idea of how the process works.
+
+
+ `;
diff --git a/src/template/keyManager.ts b/src/template/keyManager.ts
new file mode 100644
index 0000000..1df51e7
--- /dev/null
+++ b/src/template/keyManager.ts
@@ -0,0 +1,77 @@
+import { html } from "uhtml";
+import {
+ exportKeys,
+ importAndSaveKeys,
+ retrieveOrGenerateKeyPair,
+} from "../utils/crypto.ts";
+import { signal } from "uhtml/preactive";
+import { LOCAL_STORAGE_KEYS } from "../utils/store.ts";
+
+const ecdhPublicKey = signal(
+ localStorage.getItem(LOCAL_STORAGE_KEYS.ECDH_PUBLIC_KEY)
+);
+const ecdhPrivateKey = signal(
+ localStorage.getItem(LOCAL_STORAGE_KEYS.ECDH_PRIVATE_KEY)
+);
+const isDialogOpen = signal(false);
+
+export const KeyManager =
+ () => html`