diff --git a/.github/workflows/motoko-vetkd-example.yml b/.github/workflows/motoko-vetkd-example.yml index 83c770fc2..ce2912a6f 100644 --- a/.github/workflows/motoko-vetkd-example.yml +++ b/.github/workflows/motoko-vetkd-example.yml @@ -20,6 +20,7 @@ jobs: - name: Provision Darwin env: DFX_VERSION: 0.14.2 + NODE_VERSION: 19.8.1 run: bash .github/workflows/provision-darwin.sh - name: Motoko vetKD Darwin run: | diff --git a/.github/workflows/provision-darwin.sh b/.github/workflows/provision-darwin.sh index 19dac5d3d..fb84438fc 100755 --- a/.github/workflows/provision-darwin.sh +++ b/.github/workflows/provision-darwin.sh @@ -11,7 +11,7 @@ bash install-brew.sh rm install-brew.sh # Install Node. -version=14.15.4 +version=${NODE_VERSION:=14.15.4} curl --location --output node.pkg "https://nodejs.org/dist/v$version/node-v$version.pkg" sudo installer -pkg node.pkg -store -target / rm node.pkg diff --git a/.github/workflows/rust-vetkd-example.yml b/.github/workflows/rust-vetkd-example.yml index 6fe322887..d81be15c2 100644 --- a/.github/workflows/rust-vetkd-example.yml +++ b/.github/workflows/rust-vetkd-example.yml @@ -20,6 +20,7 @@ jobs: - name: Provision Darwin env: DFX_VERSION: 0.14.2 + NODE_VERSION: 19.8.1 run: bash .github/workflows/provision-darwin.sh - name: Rust vetKD Darwin run: | diff --git a/motoko/vetkd/dfx.json b/motoko/vetkd/dfx.json index 771a4d27d..e456486da 100644 --- a/motoko/vetkd/dfx.json +++ b/motoko/vetkd/dfx.json @@ -25,6 +25,17 @@ "dist/app_frontend_js/" ], "type": "assets" + }, + "internet_identity": { + "type": "custom", + "candid": "https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity.did", + "wasm": "https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity_dev.wasm.gz", + "remote": { + "id": { + "ic": "rdmx6-jaaaa-aaaaa-aaadq-cai" + } + }, + "frontend": {} } }, "defaults": { diff --git a/motoko/vetkd/package-lock.json b/motoko/vetkd/package-lock.json index d1c088b05..2164ac44d 100644 --- a/motoko/vetkd/package-lock.json +++ b/motoko/vetkd/package-lock.json @@ -9,6 +9,7 @@ "version": "0.2.0", "dependencies": { "@dfinity/agent": "^0.15.6", + "@dfinity/auth-client": "^0.15.6", "@dfinity/candid": "^0.15.6", "@dfinity/principal": "^0.15.6", "ic-vetkd-utils": "file:ic-vetkd-utils-0.1.0.tgz" @@ -53,9 +54,9 @@ } }, "node_modules/@dfinity/agent": { - "version": "0.15.6", - "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.15.6.tgz", - "integrity": "sha512-Ch+tXAszPap0zwRgr/oFEgJLDld4RDwBdFDqR1JUg38xhHWTFMrTkjMT6uQFvqf6d2wDXnh3zwhqbg5P7OCv7A==", + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.15.7.tgz", + "integrity": "sha512-w34yvlUTpPBG8nLOD0t/ao3k2xonOFq4QGvfJ1HiS/nIggdza/3xC3nLBszGrjVYWj1jqu8BLFvQXCAeWin75A==", "dependencies": { "base64-arraybuffer": "^0.2.0", "bignumber.js": "^9.0.0", @@ -65,22 +66,51 @@ "ts-node": "^10.8.2" }, "peerDependencies": { - "@dfinity/candid": "^0.15.6", - "@dfinity/principal": "^0.15.6" + "@dfinity/candid": "^0.15.7", + "@dfinity/principal": "^0.15.7" + } + }, + "node_modules/@dfinity/auth-client": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/auth-client/-/auth-client-0.15.7.tgz", + "integrity": "sha512-f6cRqXayCf+7+9gNcDnAZZwJrgBYKIzfxjxeRLlpsueQeo+E/BX2yVSANxzTkCNc4U3p+ttHI1RNtasLunYTcA==", + "dependencies": { + "idb": "^7.0.2" + }, + "peerDependencies": { + "@dfinity/agent": "^0.15.7", + "@dfinity/identity": "^0.15.7", + "@dfinity/principal": "^0.15.7" } }, "node_modules/@dfinity/candid": { - "version": "0.15.6", - "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-0.15.6.tgz", - "integrity": "sha512-Q9PGvhTE/1dTLfSo0pu0+ifzA7NA4X1rgSy9TE6O1Glk6Kl8Nf+Pg2sCHS2hWt0RAiKfR2glEVlbUAm6S8vRxA==", + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-0.15.7.tgz", + "integrity": "sha512-lTcjK/xrSyT7wvUQ2pApG+yklQAwxaofQ04D1IWv0/8gKbY0eUbh8G2w6+CypJ15Hb1CH24ijUj8nWdeX/z3jg==", "dependencies": { "ts-node": "^10.8.2" } }, + "node_modules/@dfinity/identity": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/identity/-/identity-0.15.7.tgz", + "integrity": "sha512-kBAkx9wq78jSQf6T5aayLyWm8YgtOZw8bW6+OuzX6tR3hkAEa85A9TcKA7BjkmMWSIskjEDVQub4fFfKWS2vOQ==", + "peer": true, + "dependencies": { + "borc": "^2.1.1", + "js-sha256": "^0.9.0", + "tweetnacl": "^1.0.1" + }, + "peerDependencies": { + "@dfinity/agent": "^0.15.7", + "@dfinity/principal": "^0.15.7", + "@peculiar/webcrypto": "^1.4.0" + } + }, "node_modules/@dfinity/principal": { - "version": "0.15.6", - "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.15.6.tgz", - "integrity": "sha512-eMsS5YofRk5Hm6LlhzyBvw1RzDxM5FWPtepQuYeZbZyD/ztq4TrUiScqoKBFw/LLODd0znt8rGnNgqtt+7JnQA==", + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.15.7.tgz", + "integrity": "sha512-6/AkYzpGEH6Jw/0+B/EeeQn+5u2GDDvRLt1kQPhIG4txQYFnOy04H3VvyrymmfAj6/CXUgrOrux6OxgYSLYVJg==", "dependencies": { "js-sha256": "^0.9.0", "ts-node": "^10.8.2" @@ -189,6 +219,45 @@ "node": ">= 8" } }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.6.tgz", + "integrity": "sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA==", + "peer": true, + "dependencies": { + "asn1js": "^3.0.5", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@peculiar/json-schema": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", + "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", + "peer": true, + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@peculiar/webcrypto": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.3.tgz", + "integrity": "sha512-VtaY4spKTdN5LjJ04im/d/joXuvLbQdgy5Z4DXF4MFZhQ+MTrejbNMkfZBp1Bs3O5+bFqnJgyGdPuZQflvIa5A==", + "peer": true, + "dependencies": { + "@peculiar/asn1-schema": "^2.3.6", + "@peculiar/json-schema": "^1.1.12", + "pvtsutils": "^1.3.2", + "tslib": "^2.5.0", + "webcrypto-core": "^1.7.7" + }, + "engines": { + "node": ">=10.12.0" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -701,6 +770,20 @@ "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", "dev": true }, + "node_modules/asn1js": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", + "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==", + "peer": true, + "dependencies": { + "pvtsutils": "^1.3.2", + "pvutils": "^1.1.3", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/assert": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", @@ -2398,6 +2481,11 @@ "node": ">=0.10.0" } }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -3320,6 +3408,24 @@ "node": ">=6" } }, + "node_modules/pvtsutils": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.3.tgz", + "integrity": "sha512-6sAOMlXyrJ+8tRN5IAaYfuYZRp1C2uJ0SyDynEFxL+VY8kCRib9Lpj/+KPaNFpaQWr/iRik5nrzz6iaNlxgEGA==", + "peer": true, + "dependencies": { + "tslib": "^2.6.1" + } + }, + "node_modules/pvutils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", + "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -4246,10 +4352,15 @@ } }, "node_modules/tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "peer": true }, "node_modules/type-is": { "version": "1.6.18", @@ -4420,6 +4531,19 @@ "minimalistic-assert": "^1.0.0" } }, + "node_modules/webcrypto-core": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.7.tgz", + "integrity": "sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==", + "peer": true, + "dependencies": { + "@peculiar/asn1-schema": "^2.3.6", + "@peculiar/json-schema": "^1.1.12", + "asn1js": "^3.0.1", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.0" + } + }, "node_modules/webpack": { "version": "5.86.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.86.0.tgz", diff --git a/motoko/vetkd/package.json b/motoko/vetkd/package.json index 2a7c7116f..66061dec9 100644 --- a/motoko/vetkd/package.json +++ b/motoko/vetkd/package.json @@ -18,6 +18,7 @@ }, "dependencies": { "@dfinity/agent": "^0.15.6", + "@dfinity/auth-client": "^0.15.6", "@dfinity/candid": "^0.15.6", "@dfinity/principal": "^0.15.6", "ic-vetkd-utils": "file:ic-vetkd-utils-0.1.0.tgz" diff --git a/motoko/vetkd/src/app_backend/Main.mo b/motoko/vetkd/src/app_backend/Main.mo index fc847fa2e..83f6b8f9b 100644 --- a/motoko/vetkd/src/app_backend/Main.mo +++ b/motoko/vetkd/src/app_backend/Main.mo @@ -3,6 +3,7 @@ import Text "mo:base/Text"; import Blob "mo:base/Blob"; import Array "mo:base/Array"; import Hex "./utils/Hex"; +import Debug "mo:base/Debug"; actor { type VETKD_SYSTEM_API = actor { @@ -40,6 +41,8 @@ actor { }; public shared ({ caller }) func encrypted_symmetric_key_for_caller(encryption_public_key : Blob) : async Text { + Debug.print("encrypted_symmetric_key_for_caller: caller: " # debug_show (caller)); + let { encrypted_key } = await vetkd_system_api.vetkd_encrypted_key({ derivation_id = Principal.toBlob(caller); public_key_derivation_path = Array.make(Text.encodeUtf8("symmetric_key")); @@ -59,6 +62,8 @@ actor { }; public shared ({ caller }) func encrypted_ibe_decryption_key_for_caller(encryption_public_key : Blob) : async Text { + Debug.print("encrypted_ibe_decryption_key_for_caller: caller: " # debug_show (caller)); + let { encrypted_key } = await vetkd_system_api.vetkd_encrypted_key({ derivation_id = Principal.toBlob(caller); public_key_derivation_path = Array.make(Text.encodeUtf8("ibe_encryption")); diff --git a/motoko/vetkd/src/app_frontend_js/assets/main.css b/motoko/vetkd/src/app_frontend_js/assets/main.css index 00632b770..e13317ca1 100644 --- a/motoko/vetkd/src/app_frontend_js/assets/main.css +++ b/motoko/vetkd/src/app_frontend_js/assets/main.css @@ -8,7 +8,7 @@ form { justify-content: center; gap: 0.5em; flex-flow: row wrap; - max-width: 40vw; + max-width: 50vw; margin: auto; align-items: baseline; } @@ -30,9 +30,16 @@ button[type="submit"] { text-align: center; } +#login_form { + margin-bottom: 2em; +} + +#symmetric_encryption_demo { + text-align: center; +} + #ibedemo { text-align: center; - margin-top: 2em; } #get_symmetric_key_result { diff --git a/motoko/vetkd/src/app_frontend_js/src/index.html b/motoko/vetkd/src/app_frontend_js/src/index.html index 7faeb33f7..c54597eb6 100644 --- a/motoko/vetkd/src/app_frontend_js/src/index.html +++ b/motoko/vetkd/src/app_frontend_js/src/index.html @@ -12,7 +12,13 @@
-

vetKD Demo: Encryption with symmetric (AES-GCM-256) key

+

vetKD Demo

+
+ + +
+
+

Encryption with symmetric (AES-GCM-256) key

@@ -30,17 +36,19 @@

vetKD Demo: Encryption with symmetric (AES-GCM-256) key


-

vetKD Demo: Identity-Based Encryption (IBE)

+

Identity-Based Encryption (IBE)



- + +

+


- +

diff --git a/motoko/vetkd/src/app_frontend_js/src/index.js b/motoko/vetkd/src/app_frontend_js/src/index.js index 09bd03191..ce8cab512 100644 --- a/motoko/vetkd/src/app_frontend_js/src/index.js +++ b/motoko/vetkd/src/app_frontend_js/src/index.js @@ -1,8 +1,13 @@ -import { app_backend } from "../../declarations/app_backend"; +import { createActor, app_backend } from "../../declarations/app_backend"; import * as vetkd from "ic-vetkd-utils"; -import * as agent from "@dfinity/agent"; +import { AuthClient } from "@dfinity/auth-client" +import { HttpAgent, Actor } from "@dfinity/agent"; +import { Principal } from "@dfinity/principal"; let fetched_symmetric_key = null; +let app_backend_actor = app_backend; +let app_backend_principal = await Actor.agentOf(app_backend_actor).getPrincipal(); +document.getElementById("principal").innerHTML = annotated_principal(app_backend_principal); document.getElementById("get_symmetric_key_form").addEventListener("submit", async (e) => { e.preventDefault(); @@ -45,9 +50,12 @@ document.getElementById("decrypt_form").addEventListener("submit", async (e) => const result = document.getElementById("decrypt_result"); result.innerText = "Decrypting..."; - const plaintext = await aes_gcm_decrypt(document.getElementById("ciphertext").value, fetched_symmetric_key); - - result.innerText = "plaintext: " + plaintext; + try { + const plaintext = await aes_gcm_decrypt(document.getElementById("ciphertext").value, fetched_symmetric_key); + result.innerText = "plaintext: " + plaintext; + } catch (e) { + result.innerText = "Error: " + e; + } button.removeAttribute("disabled"); return false; @@ -82,9 +90,8 @@ function update_ciphertext_button_state() { async function get_aes_256_gcm_key() { const seed = window.crypto.getRandomValues(new Uint8Array(32)); const tsk = new vetkd.TransportSecretKey(seed); - const ek_bytes_hex = await app_backend.encrypted_symmetric_key_for_caller(tsk.public_key()); - const pk_bytes_hex = await app_backend.symmetric_key_verification_key(); - const app_backend_principal = await agent.Actor.agentOf(app_backend).getPrincipal(); // default is the anonymous principal! + const ek_bytes_hex = await app_backend_actor.encrypted_symmetric_key_for_caller(tsk.public_key()); + const pk_bytes_hex = await app_backend_actor.symmetric_key_verification_key(); return tsk.decrypt_and_hash( hex_decode(ek_bytes_hex), hex_decode(pk_bytes_hex), @@ -129,8 +136,12 @@ document.getElementById("ibe_encrypt_form").addEventListener("submit", async (e) button.setAttribute("disabled", true); const result = document.getElementById("ibe_encrypt_result"); - const ibe_ciphertext = await ibe_encrypt(document.getElementById("ibe_plaintext").value); - result.innerText = "IBE ciphertext: " + ibe_ciphertext; + try { + const ibe_ciphertext = await ibe_encrypt(document.getElementById("ibe_plaintext").value); + result.innerText = "IBE ciphertext: " + ibe_ciphertext; + } catch (e) { + result.innerText = "Error: " + e; + } button.removeAttribute("disabled"); return false; @@ -142,8 +153,12 @@ document.getElementById("ibe_decrypt_form").addEventListener("submit", async (e) button.setAttribute("disabled", true); const result = document.getElementById("ibe_decrypt_result"); - const ibe_plaintext = await ibe_decrypt(document.getElementById("ibe_ciphertext").value); - result.innerText = "IBE plaintext: " + ibe_plaintext; + try { + const ibe_plaintext = await ibe_decrypt(document.getElementById("ibe_ciphertext").value); + result.innerText = "IBE plaintext: " + ibe_plaintext; + } catch (e) { + result.innerText = "Error: " + e; + } button.removeAttribute("disabled"); return false; @@ -153,13 +168,17 @@ document.getElementById("ibe_plaintext").addEventListener("keyup", async (e) => update_ibe_encrypt_button_state(); }); +document.getElementById("ibe_principal").addEventListener("keyup", async (e) => { + update_ibe_encrypt_button_state(); +}); + document.getElementById("ibe_ciphertext").addEventListener("keyup", async (e) => { update_ibe_decrypt_button_state(); }); function update_ibe_encrypt_button_state() { const ibe_encrypt_button = document.getElementById("ibe_encrypt"); - if (document.getElementById("ibe_plaintext").value === "") { + if (document.getElementById("ibe_plaintext").value === "" || document.getElementById("ibe_principal").value === "") { ibe_encrypt_button.setAttribute("disabled", true); } else { ibe_encrypt_button.removeAttribute("disabled"); @@ -177,17 +196,17 @@ function update_ibe_decrypt_button_state() { async function ibe_encrypt(message) { document.getElementById("ibe_encrypt_result").innerText = "Fetching IBE encryption key..." - const pk_bytes_hex = await app_backend.ibe_encryption_key(); + const pk_bytes_hex = await app_backend_actor.ibe_encryption_key(); document.getElementById("ibe_encrypt_result").innerText = "Preparing IBE-encryption..." - const app_backend_principal = await agent.Actor.agentOf(app_backend).getPrincipal(); // default is the anonymous principal! const message_encoded = new TextEncoder().encode(message); const seed = window.crypto.getRandomValues(new Uint8Array(32)); + let ibe_principal = Principal.fromText(document.getElementById("ibe_principal").value); - document.getElementById("ibe_encrypt_result").innerText = "IBE-encrypting..." + document.getElementById("ibe_encrypt_result").innerText = "IBE-encrypting for principal" + ibe_principal.toText() + "..."; const ibe_ciphertext = vetkd.IBECiphertext.encrypt( hex_decode(pk_bytes_hex), - app_backend_principal.toUint8Array(), + ibe_principal.toUint8Array(), message_encoded, seed ); @@ -199,11 +218,9 @@ async function ibe_decrypt(ibe_ciphertext_hex) { const tsk_seed = window.crypto.getRandomValues(new Uint8Array(32)); const tsk = new vetkd.TransportSecretKey(tsk_seed); document.getElementById("ibe_decrypt_result").innerText = "Fetching IBE decryption key..." - const ek_bytes_hex = await app_backend.encrypted_ibe_decryption_key_for_caller(tsk.public_key()); + const ek_bytes_hex = await app_backend_actor.encrypted_ibe_decryption_key_for_caller(tsk.public_key()); document.getElementById("ibe_decrypt_result").innerText = "Fetching IBE enryption key (needed for verification)..." - const pk_bytes_hex = await app_backend.ibe_encryption_key(); - - const app_backend_principal = await agent.Actor.agentOf(app_backend).getPrincipal(); // default is the anonymous principal! + const pk_bytes_hex = await app_backend_actor.ibe_encryption_key(); const k_bytes = tsk.decrypt( hex_decode(ek_bytes_hex), @@ -216,6 +233,44 @@ async function ibe_decrypt(ibe_ciphertext_hex) { return new TextDecoder().decode(ibe_plaintext); } +document.getElementById("login").onclick = async (e) => { + e.preventDefault(); + let authClient = await AuthClient.create(); + await new Promise((resolve) => { + authClient.login({ + identityProvider: `http://127.0.0.1:4943/?canisterId=${process.env.INTERNET_IDENTITY_CANISTER_ID}`, + onSuccess: resolve, + }); + }); + // At this point we're authenticated, and we can get the identity from the auth client: + const identity = authClient.getIdentity(); + // Using the identity obtained from the auth client, we can create an agent to interact with the IC. + const agent = new HttpAgent({ identity }); + // Using the interface description of our webapp, we create an actor that we use to call the service methods. We override the global actor, such that the other button handler will automatically use the new actor with the Internet Identity provided delegation. + app_backend_actor = createActor(process.env.APP_BACKEND_CANISTER_ID, { + agent, + }); + app_backend_principal = identity.getPrincipal(); + + document.getElementById("principal").innerHTML = annotated_principal(app_backend_principal); + + fetched_symmetric_key = null; + document.getElementById("get_symmetric_key_result").innerText = ""; + update_plaintext_button_state(); + update_ciphertext_button_state(); + + return false; +}; + +function annotated_principal(principal) { + let principal_string = principal.toString(); + if (principal_string == "2vxsx-fae") { + return "Anonymous principal (2vxsx-fae)"; + } else { + return "Principal: " + principal_string; + } +} + const hex_decode = (hexString) => Uint8Array.from(hexString.match(/.{1,2}/g).map((byte) => parseInt(byte, 16))); const hex_encode = (bytes) => diff --git a/rust/vetkd/dfx.json b/rust/vetkd/dfx.json index 5c52ab799..685c7ff7b 100644 --- a/rust/vetkd/dfx.json +++ b/rust/vetkd/dfx.json @@ -26,6 +26,17 @@ "dist/app_frontend_js/" ], "type": "assets" + }, + "internet_identity": { + "type": "custom", + "candid": "https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity.did", + "wasm": "https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity_dev.wasm.gz", + "remote": { + "id": { + "ic": "rdmx6-jaaaa-aaaaa-aaadq-cai" + } + }, + "frontend": {} } }, "defaults": { diff --git a/rust/vetkd/package-lock.json b/rust/vetkd/package-lock.json index d1c088b05..f73156e45 100644 --- a/rust/vetkd/package-lock.json +++ b/rust/vetkd/package-lock.json @@ -8,9 +8,10 @@ "name": "app_frontend_js", "version": "0.2.0", "dependencies": { - "@dfinity/agent": "^0.15.6", - "@dfinity/candid": "^0.15.6", - "@dfinity/principal": "^0.15.6", + "@dfinity/agent": "^0.18.1", + "@dfinity/auth-client": "^0.18.1", + "@dfinity/candid": "^0.18.1", + "@dfinity/principal": "^0.18.1", "ic-vetkd-utils": "file:ic-vetkd-utils-0.1.0.tgz" }, "devDependencies": { @@ -24,7 +25,7 @@ "stream-browserify": "3.0.0", "terser-webpack-plugin": "^5.3.3", "util": "0.12.4", - "webpack": "^5.73.0", + "webpack": "^5.88.2", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.8.1" }, @@ -32,58 +33,61 @@ "node": "^12 || ^14 || ^16 || ^18 || ^19" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@dfinity/agent": { - "version": "0.15.6", - "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.15.6.tgz", - "integrity": "sha512-Ch+tXAszPap0zwRgr/oFEgJLDld4RDwBdFDqR1JUg38xhHWTFMrTkjMT6uQFvqf6d2wDXnh3zwhqbg5P7OCv7A==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.18.1.tgz", + "integrity": "sha512-nMFK/y0ZkPfQYECdojmltXsBIdGvXa1Sxa4rDV2cibEq9lsjWMEIUqPsiBaNHuwuz+gzsGVq4N2b9umKQIQaRQ==", "dependencies": { "base64-arraybuffer": "^0.2.0", - "bignumber.js": "^9.0.0", "borc": "^2.1.1", "js-sha256": "0.9.0", - "simple-cbor": "^0.4.1", - "ts-node": "^10.8.2" + "simple-cbor": "^0.4.1" }, "peerDependencies": { - "@dfinity/candid": "^0.15.6", - "@dfinity/principal": "^0.15.6" + "@dfinity/candid": "^0.18.1", + "@dfinity/principal": "^0.18.1" + } + }, + "node_modules/@dfinity/auth-client": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@dfinity/auth-client/-/auth-client-0.18.1.tgz", + "integrity": "sha512-epsTbmXyVctNUI0P2pL1Ct5pJkuw2owSmW2bdje459lnaz2X/6jKlpSOjdZN7YzQ/PVoqL+vHn47E2xOs84uKw==", + "dependencies": { + "idb": "^7.0.2" + }, + "peerDependencies": { + "@dfinity/agent": "^0.18.1", + "@dfinity/identity": "^0.18.1", + "@dfinity/principal": "^0.18.1" } }, "node_modules/@dfinity/candid": { - "version": "0.15.6", - "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-0.15.6.tgz", - "integrity": "sha512-Q9PGvhTE/1dTLfSo0pu0+ifzA7NA4X1rgSy9TE6O1Glk6Kl8Nf+Pg2sCHS2hWt0RAiKfR2glEVlbUAm6S8vRxA==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-0.18.1.tgz", + "integrity": "sha512-/PC3wDnrGcWhaF/veYKevcAAn5A5jK0mRkVKcz0YxK/a78Ai9wMJg0fUk7aoyZryCOz8JPVgR4nK1/zTmvEBHg==" + }, + "node_modules/@dfinity/identity": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@dfinity/identity/-/identity-0.18.1.tgz", + "integrity": "sha512-u8pXzjEciaLad8WykwIO4nuASr0MdJHwFjd32TKr6oquJ6caMCDj0N8vlHfoWM6oInhYIWIME4pucjAM/isP2A==", + "peer": true, "dependencies": { - "ts-node": "^10.8.2" + "borc": "^2.1.1", + "js-sha256": "^0.9.0", + "tweetnacl": "^1.0.1" + }, + "peerDependencies": { + "@dfinity/agent": "^0.18.1", + "@dfinity/principal": "^0.18.1", + "@peculiar/webcrypto": "^1.4.0" } }, "node_modules/@dfinity/principal": { - "version": "0.15.6", - "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.15.6.tgz", - "integrity": "sha512-eMsS5YofRk5Hm6LlhzyBvw1RzDxM5FWPtepQuYeZbZyD/ztq4TrUiScqoKBFw/LLODd0znt8rGnNgqtt+7JnQA==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.18.1.tgz", + "integrity": "sha512-xeV+5zV7VQRT2xJTbXW4IDra1urEcchuwuKFTU/ERcJWBWEk8chsZcd6DBc8SPq83xRgXW2ZTVVSOZR8NKaVoQ==", "dependencies": { - "js-sha256": "^0.9.0", - "ts-node": "^10.8.2" + "js-sha256": "^0.9.0" } }, "node_modules/@jridgewell/gen-mapping": { @@ -104,6 +108,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -130,7 +135,8 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.18", @@ -189,25 +195,44 @@ "node": ">= 8" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + "node_modules/@peculiar/asn1-schema": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.6.tgz", + "integrity": "sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA==", + "peer": true, + "dependencies": { + "asn1js": "^3.0.5", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.0" + } }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + "node_modules/@peculiar/json-schema": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", + "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", + "peer": true, + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" + } }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + "node_modules/@peculiar/webcrypto": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.3.tgz", + "integrity": "sha512-VtaY4spKTdN5LjJ04im/d/joXuvLbQdgy5Z4DXF4MFZhQ+MTrejbNMkfZBp1Bs3O5+bFqnJgyGdPuZQflvIa5A==", + "peer": true, + "dependencies": { + "@peculiar/asn1-schema": "^2.3.6", + "@peculiar/json-schema": "^1.1.12", + "pvtsutils": "^1.3.2", + "tslib": "^2.5.0", + "webcrypto-core": "^1.7.7" + }, + "engines": { + "node": ">=10.12.0" + } }, "node_modules/@types/body-parser": { "version": "1.19.2", @@ -327,7 +352,8 @@ "node_modules/@types/node": { "version": "20.3.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.0.tgz", - "integrity": "sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ==" + "integrity": "sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ==", + "dev": true }, "node_modules/@types/qs": { "version": "6.9.7", @@ -605,6 +631,7 @@ "version": "8.8.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -621,14 +648,6 @@ "acorn": "^8" } }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/ajv-formats": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", @@ -690,17 +709,26 @@ "node": ">= 8" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, "node_modules/array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", "dev": true }, + "node_modules/asn1js": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", + "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==", + "peer": true, + "dependencies": { + "pvtsutils": "^1.3.2", + "pvutils": "^1.1.3", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/assert": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", @@ -1259,11 +1287,6 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1395,14 +1418,6 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1565,9 +1580,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.14.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz", - "integrity": "sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -2398,6 +2413,11 @@ "node": ">=0.10.0" } }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -2794,11 +2814,6 @@ "tslib": "^2.0.3" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -3320,6 +3335,24 @@ "node": ">=6" } }, + "node_modules/pvtsutils": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.3.tgz", + "integrity": "sha512-6sAOMlXyrJ+8tRN5IAaYfuYZRp1C2uJ0SyDynEFxL+VY8kCRib9Lpj/+KPaNFpaQWr/iRik5nrzz6iaNlxgEGA==", + "peer": true, + "dependencies": { + "tslib": "^2.6.1" + } + }, + "node_modules/pvutils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", + "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -4203,53 +4236,16 @@ "node": ">=0.6" } }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "peer": true }, "node_modules/type-is": { "version": "1.6.18", @@ -4264,19 +4260,6 @@ "node": ">= 0.6" } }, - "node_modules/typescript": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", - "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -4384,11 +4367,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" - }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -4420,10 +4398,23 @@ "minimalistic-assert": "^1.0.0" } }, + "node_modules/webcrypto-core": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.7.tgz", + "integrity": "sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==", + "peer": true, + "dependencies": { + "@peculiar/asn1-schema": "^2.3.6", + "@peculiar/json-schema": "^1.1.12", + "asn1js": "^3.0.1", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.0" + } + }, "node_modules/webpack": { - "version": "5.86.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.86.0.tgz", - "integrity": "sha512-3BOvworZ8SO/D4GVP+GoRC3fVeg5MO4vzmq8TJJEkdmopxyazGDxN8ClqN12uzrZW9Tv8EED8v5VSb6Sqyi0pg==", + "version": "5.88.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", + "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", @@ -4435,7 +4426,7 @@ "acorn-import-assertions": "^1.9.0", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.14.1", + "enhanced-resolve": "^5.15.0", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -4445,7 +4436,7 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.7", "watchpack": "^2.4.0", @@ -4820,14 +4811,6 @@ "optional": true } } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "engines": { - "node": ">=6" - } } } } diff --git a/rust/vetkd/package.json b/rust/vetkd/package.json index 2a7c7116f..e378bec05 100644 --- a/rust/vetkd/package.json +++ b/rust/vetkd/package.json @@ -17,9 +17,10 @@ "generate": "dfx generate app_backend" }, "dependencies": { - "@dfinity/agent": "^0.15.6", - "@dfinity/candid": "^0.15.6", - "@dfinity/principal": "^0.15.6", + "@dfinity/agent": "^0.18.1", + "@dfinity/auth-client": "^0.18.1", + "@dfinity/candid": "^0.18.1", + "@dfinity/principal": "^0.18.1", "ic-vetkd-utils": "file:ic-vetkd-utils-0.1.0.tgz" }, "devDependencies": { @@ -33,7 +34,7 @@ "stream-browserify": "3.0.0", "terser-webpack-plugin": "^5.3.3", "util": "0.12.4", - "webpack": "^5.73.0", + "webpack": "^5.88.2", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.8.1" }, diff --git a/rust/vetkd/src/app_backend/src/lib.rs b/rust/vetkd/src/app_backend/src/lib.rs index f7f583476..477119f41 100644 --- a/rust/vetkd/src/app_backend/src/lib.rs +++ b/rust/vetkd/src/app_backend/src/lib.rs @@ -30,6 +30,8 @@ async fn symmetric_key_verification_key() -> String { #[update] async fn encrypted_symmetric_key_for_caller(encryption_public_key: Vec) -> String { + debug_println_caller("encrypted_symmetric_key_for_caller"); + let request = VetKDEncryptedKeyRequest { derivation_id: ic_cdk::caller().as_slice().to_vec(), public_key_derivation_path: vec![b"symmetric_key".to_vec()], @@ -69,6 +71,8 @@ async fn ibe_encryption_key() -> String { #[update] async fn encrypted_ibe_decryption_key_for_caller(encryption_public_key: Vec) -> String { + debug_println_caller("encrypted_ibe_decryption_key_for_caller"); + let request = VetKDEncryptedKeyRequest { derivation_id: ic_cdk::caller().as_slice().to_vec(), public_key_derivation_path: vec![b"ibe_encryption".to_vec()], @@ -97,3 +101,12 @@ fn bls12_381_test_key_1() -> VetKDKeyId { fn vetkd_system_api_canister_id() -> CanisterId { CanisterId::from_str(VETKD_SYSTEM_API_CANISTER_ID).expect("failed to create canister ID") } + +fn debug_println_caller(method_name: &str) { + ic_cdk::println!( + "{}: caller: {} (isAnonymous: {})", + method_name, + ic_cdk::caller().to_text(), + ic_cdk::caller() == candid::Principal::anonymous() + ); +} diff --git a/rust/vetkd/src/app_frontend_js/assets/main.css b/rust/vetkd/src/app_frontend_js/assets/main.css index 00632b770..e13317ca1 100644 --- a/rust/vetkd/src/app_frontend_js/assets/main.css +++ b/rust/vetkd/src/app_frontend_js/assets/main.css @@ -8,7 +8,7 @@ form { justify-content: center; gap: 0.5em; flex-flow: row wrap; - max-width: 40vw; + max-width: 50vw; margin: auto; align-items: baseline; } @@ -30,9 +30,16 @@ button[type="submit"] { text-align: center; } +#login_form { + margin-bottom: 2em; +} + +#symmetric_encryption_demo { + text-align: center; +} + #ibedemo { text-align: center; - margin-top: 2em; } #get_symmetric_key_result { diff --git a/rust/vetkd/src/app_frontend_js/src/index.html b/rust/vetkd/src/app_frontend_js/src/index.html index 54874d940..c54597eb6 100644 --- a/rust/vetkd/src/app_frontend_js/src/index.html +++ b/rust/vetkd/src/app_frontend_js/src/index.html @@ -12,7 +12,13 @@
-

vetKD Demo: Encryption with symmetric (AES-GCM-256) key

+

vetKD Demo

+
+ + +
+
+

Encryption with symmetric (AES-GCM-256) key

@@ -30,17 +36,19 @@

vetKD Demo: Encryption with symmetric (AES-GCM-256) key


-

vetKD Demo: Identity-Based Encryption (IBE)

+

Identity-Based Encryption (IBE)



- + +

+


- +

@@ -48,4 +56,4 @@

vetKD Demo: Identity-Based Encryption (IBE)

- \ No newline at end of file + diff --git a/rust/vetkd/src/app_frontend_js/src/index.js b/rust/vetkd/src/app_frontend_js/src/index.js index 09bd03191..ce8cab512 100644 --- a/rust/vetkd/src/app_frontend_js/src/index.js +++ b/rust/vetkd/src/app_frontend_js/src/index.js @@ -1,8 +1,13 @@ -import { app_backend } from "../../declarations/app_backend"; +import { createActor, app_backend } from "../../declarations/app_backend"; import * as vetkd from "ic-vetkd-utils"; -import * as agent from "@dfinity/agent"; +import { AuthClient } from "@dfinity/auth-client" +import { HttpAgent, Actor } from "@dfinity/agent"; +import { Principal } from "@dfinity/principal"; let fetched_symmetric_key = null; +let app_backend_actor = app_backend; +let app_backend_principal = await Actor.agentOf(app_backend_actor).getPrincipal(); +document.getElementById("principal").innerHTML = annotated_principal(app_backend_principal); document.getElementById("get_symmetric_key_form").addEventListener("submit", async (e) => { e.preventDefault(); @@ -45,9 +50,12 @@ document.getElementById("decrypt_form").addEventListener("submit", async (e) => const result = document.getElementById("decrypt_result"); result.innerText = "Decrypting..."; - const plaintext = await aes_gcm_decrypt(document.getElementById("ciphertext").value, fetched_symmetric_key); - - result.innerText = "plaintext: " + plaintext; + try { + const plaintext = await aes_gcm_decrypt(document.getElementById("ciphertext").value, fetched_symmetric_key); + result.innerText = "plaintext: " + plaintext; + } catch (e) { + result.innerText = "Error: " + e; + } button.removeAttribute("disabled"); return false; @@ -82,9 +90,8 @@ function update_ciphertext_button_state() { async function get_aes_256_gcm_key() { const seed = window.crypto.getRandomValues(new Uint8Array(32)); const tsk = new vetkd.TransportSecretKey(seed); - const ek_bytes_hex = await app_backend.encrypted_symmetric_key_for_caller(tsk.public_key()); - const pk_bytes_hex = await app_backend.symmetric_key_verification_key(); - const app_backend_principal = await agent.Actor.agentOf(app_backend).getPrincipal(); // default is the anonymous principal! + const ek_bytes_hex = await app_backend_actor.encrypted_symmetric_key_for_caller(tsk.public_key()); + const pk_bytes_hex = await app_backend_actor.symmetric_key_verification_key(); return tsk.decrypt_and_hash( hex_decode(ek_bytes_hex), hex_decode(pk_bytes_hex), @@ -129,8 +136,12 @@ document.getElementById("ibe_encrypt_form").addEventListener("submit", async (e) button.setAttribute("disabled", true); const result = document.getElementById("ibe_encrypt_result"); - const ibe_ciphertext = await ibe_encrypt(document.getElementById("ibe_plaintext").value); - result.innerText = "IBE ciphertext: " + ibe_ciphertext; + try { + const ibe_ciphertext = await ibe_encrypt(document.getElementById("ibe_plaintext").value); + result.innerText = "IBE ciphertext: " + ibe_ciphertext; + } catch (e) { + result.innerText = "Error: " + e; + } button.removeAttribute("disabled"); return false; @@ -142,8 +153,12 @@ document.getElementById("ibe_decrypt_form").addEventListener("submit", async (e) button.setAttribute("disabled", true); const result = document.getElementById("ibe_decrypt_result"); - const ibe_plaintext = await ibe_decrypt(document.getElementById("ibe_ciphertext").value); - result.innerText = "IBE plaintext: " + ibe_plaintext; + try { + const ibe_plaintext = await ibe_decrypt(document.getElementById("ibe_ciphertext").value); + result.innerText = "IBE plaintext: " + ibe_plaintext; + } catch (e) { + result.innerText = "Error: " + e; + } button.removeAttribute("disabled"); return false; @@ -153,13 +168,17 @@ document.getElementById("ibe_plaintext").addEventListener("keyup", async (e) => update_ibe_encrypt_button_state(); }); +document.getElementById("ibe_principal").addEventListener("keyup", async (e) => { + update_ibe_encrypt_button_state(); +}); + document.getElementById("ibe_ciphertext").addEventListener("keyup", async (e) => { update_ibe_decrypt_button_state(); }); function update_ibe_encrypt_button_state() { const ibe_encrypt_button = document.getElementById("ibe_encrypt"); - if (document.getElementById("ibe_plaintext").value === "") { + if (document.getElementById("ibe_plaintext").value === "" || document.getElementById("ibe_principal").value === "") { ibe_encrypt_button.setAttribute("disabled", true); } else { ibe_encrypt_button.removeAttribute("disabled"); @@ -177,17 +196,17 @@ function update_ibe_decrypt_button_state() { async function ibe_encrypt(message) { document.getElementById("ibe_encrypt_result").innerText = "Fetching IBE encryption key..." - const pk_bytes_hex = await app_backend.ibe_encryption_key(); + const pk_bytes_hex = await app_backend_actor.ibe_encryption_key(); document.getElementById("ibe_encrypt_result").innerText = "Preparing IBE-encryption..." - const app_backend_principal = await agent.Actor.agentOf(app_backend).getPrincipal(); // default is the anonymous principal! const message_encoded = new TextEncoder().encode(message); const seed = window.crypto.getRandomValues(new Uint8Array(32)); + let ibe_principal = Principal.fromText(document.getElementById("ibe_principal").value); - document.getElementById("ibe_encrypt_result").innerText = "IBE-encrypting..." + document.getElementById("ibe_encrypt_result").innerText = "IBE-encrypting for principal" + ibe_principal.toText() + "..."; const ibe_ciphertext = vetkd.IBECiphertext.encrypt( hex_decode(pk_bytes_hex), - app_backend_principal.toUint8Array(), + ibe_principal.toUint8Array(), message_encoded, seed ); @@ -199,11 +218,9 @@ async function ibe_decrypt(ibe_ciphertext_hex) { const tsk_seed = window.crypto.getRandomValues(new Uint8Array(32)); const tsk = new vetkd.TransportSecretKey(tsk_seed); document.getElementById("ibe_decrypt_result").innerText = "Fetching IBE decryption key..." - const ek_bytes_hex = await app_backend.encrypted_ibe_decryption_key_for_caller(tsk.public_key()); + const ek_bytes_hex = await app_backend_actor.encrypted_ibe_decryption_key_for_caller(tsk.public_key()); document.getElementById("ibe_decrypt_result").innerText = "Fetching IBE enryption key (needed for verification)..." - const pk_bytes_hex = await app_backend.ibe_encryption_key(); - - const app_backend_principal = await agent.Actor.agentOf(app_backend).getPrincipal(); // default is the anonymous principal! + const pk_bytes_hex = await app_backend_actor.ibe_encryption_key(); const k_bytes = tsk.decrypt( hex_decode(ek_bytes_hex), @@ -216,6 +233,44 @@ async function ibe_decrypt(ibe_ciphertext_hex) { return new TextDecoder().decode(ibe_plaintext); } +document.getElementById("login").onclick = async (e) => { + e.preventDefault(); + let authClient = await AuthClient.create(); + await new Promise((resolve) => { + authClient.login({ + identityProvider: `http://127.0.0.1:4943/?canisterId=${process.env.INTERNET_IDENTITY_CANISTER_ID}`, + onSuccess: resolve, + }); + }); + // At this point we're authenticated, and we can get the identity from the auth client: + const identity = authClient.getIdentity(); + // Using the identity obtained from the auth client, we can create an agent to interact with the IC. + const agent = new HttpAgent({ identity }); + // Using the interface description of our webapp, we create an actor that we use to call the service methods. We override the global actor, such that the other button handler will automatically use the new actor with the Internet Identity provided delegation. + app_backend_actor = createActor(process.env.APP_BACKEND_CANISTER_ID, { + agent, + }); + app_backend_principal = identity.getPrincipal(); + + document.getElementById("principal").innerHTML = annotated_principal(app_backend_principal); + + fetched_symmetric_key = null; + document.getElementById("get_symmetric_key_result").innerText = ""; + update_plaintext_button_state(); + update_ciphertext_button_state(); + + return false; +}; + +function annotated_principal(principal) { + let principal_string = principal.toString(); + if (principal_string == "2vxsx-fae") { + return "Anonymous principal (2vxsx-fae)"; + } else { + return "Principal: " + principal_string; + } +} + const hex_decode = (hexString) => Uint8Array.from(hexString.match(/.{1,2}/g).map((byte) => parseInt(byte, 16))); const hex_encode = (bytes) =>