{ "cells": [ { "cell_type": "markdown", "id": "bell-receipt-0", "metadata": {}, "source": [ "# A Bell pair and its receipt\n", "\n", "A receipt is an Ed25519 signature over the request and the result in their RFC 8785 canonical JSON. This page seals a Bell pair, writes it to a file, checks it, and shows what breaks it." ] }, { "cell_type": "code", "execution_count": 1, "id": "bell-receipt-1", "metadata": { "execution": { "iopub.execute_input": "2026-11-11T12:23:53.957728Z", "iopub.status.busy": "2026-11-11T12:23:53.957650Z", "iopub.status.idle": "2026-11-11T12:23:53.962287Z", "shell.execute_reply": "2026-11-11T12:23:53.962075Z" } }, "outputs": [], "source": [ "import json\n", "import wai_quantum as wq" ] }, { "cell_type": "code", "execution_count": 2, "id": "bell-receipt-2", "metadata": { "execution": { "iopub.execute_input": "2026-11-11T12:23:53.963230Z", "iopub.status.busy": "2026-11-11T12:23:53.963158Z", "iopub.status.idle": "2026-11-11T12:23:53.965590Z", "shell.execute_reply": "2026-11-11T12:23:53.965396Z" } }, "outputs": [ { "data": { "text/plain": [ "Key(did:key:z6MkehRgf7yJbgaGfYsdoAsKdBPE3dj2CYhowQdcjqSJgvVd, in memory)" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# A fixed key for this page, so that its receipts repeat byte for byte when it runs\n", "# again. Keep a key of your own: wq.Key.generate().save(\"my.key\"), then\n", "# wq.Key.from_file(\"my.key\"); with no key given, wq.run signs with this user's key,\n", "# the command line's.\n", "key = wq.Key(bytes(range(32)))\n", "key" ] }, { "cell_type": "code", "execution_count": 3, "id": "bell-receipt-3", "metadata": { "execution": { "iopub.execute_input": "2026-11-11T12:23:53.966180Z", "iopub.status.busy": "2026-11-11T12:23:53.966120Z", "iopub.status.idle": "2026-11-11T12:23:54.007110Z", "shell.execute_reply": "2026-11-11T12:23:54.006461Z" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "b4e78a73d73b41d8bc8f80167b7e417f", "version_major": 2, "version_minor": 1 }, "text/html": [ "
stabilizer · accuracy exact
Clifford circuit: the stabilizer tableau of 2 qubits
2000 shots, 2 distinct outcomes; the 2 most frequent:
0000: 1028 of 200010281111: 972 of 2000972
observablevalueerror
Z0 Z11
X0 X11
receipt verified signed by did:key:z6Mkeh…howQdcjqSJgvVd
" ], "text/plain": [ "Result(stabilizer, accuracy exact, 2000 shots, 2 expectation values)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bell = \"OPENQASM 3.0; qubit[2] q; bit[2] c; h q[0]; cx q[0], q[1]; c = measure q;\"\n", "job = wq.run(bell, shots=2000, seed=1, observables=[\"Z0 Z1\", \"X0 X1\"], key=key)\n", "wq.Result(job)" ] }, { "cell_type": "code", "execution_count": 4, "id": "bell-receipt-4", "metadata": { "execution": { "iopub.execute_input": "2026-11-11T12:23:54.008082Z", "iopub.status.busy": "2026-11-11T12:23:54.007993Z", "iopub.status.idle": "2026-11-11T12:23:54.011349Z", "shell.execute_reply": "2026-11-11T12:23:54.011037Z" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "7b085602350c47188c2e7df0b5fbc222", "version_major": 2, "version_minor": 1 }, "text/html": [ "
receipt verified checked here, binding the request and the result as given
signerdid:key:z6MkehRgf7yJbgaGfYsdoAsKdBPE3dj2CYhowQdcjqSJgvVd
key03a107bff3ce10be1d70dd18e74bc09967e4d6309ba50d5f1ddc8664125531b8
digesta80f7e659df721f1136cfb3aaa63b983a4c976c5421ae76671c8bebdb6c6353d
signature6b1619335dcdaa9f…98e57c8fe1e95c00
formed25519 over rfc8785 canonical JSON
" ], "text/plain": [ "Receipt(valid, signed by did:key:z6MkehRgf7yJbgaGfYsdoAsKdBPE3dj2CYhowQdcjqSJgvVd)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wq.Receipt(job)" ] }, { "cell_type": "markdown", "id": "bell-receipt-5", "metadata": {}, "source": [ "## What is signed\n", "\n", "The digest is BLAKE3 over a domain tag and the canonical text of the request and of the result without its receipt. Any JSON reader and writer can carry the job: the canonical text, and so the digest, stays the same." ] }, { "cell_type": "code", "execution_count": 5, "id": "bell-receipt-6", "metadata": { "execution": { "iopub.execute_input": "2026-11-11T12:23:54.012323Z", "iopub.status.busy": "2026-11-11T12:23:54.012253Z", "iopub.status.idle": "2026-11-11T12:23:54.014046Z", "shell.execute_reply": "2026-11-11T12:23:54.013789Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\"observables\":[\"Z0 Z1\",\"X0 X1\"],\"qasm\":\"OPENQASM 3.0; qubit[2] q; bit[2] c; h q[0]; cx q[0], q[1]; c = measure q;\",\"seed\":1,\"shots\":2000}\n", "True\n" ] } ], "source": [ "result = {k: v for k, v in job.result.items() if k != \"receipt\"}\n", "print(wq.canonical(job.request).decode())\n", "print(wq.digest(job.request, result) == job.receipt[\"digest\"])" ] }, { "cell_type": "code", "execution_count": 6, "id": "bell-receipt-7", "metadata": { "execution": { "iopub.execute_input": "2026-11-11T12:23:54.014891Z", "iopub.status.busy": "2026-11-11T12:23:54.014819Z", "iopub.status.idle": "2026-11-11T12:23:54.016655Z", "shell.execute_reply": "2026-11-11T12:23:54.016408Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'valid': True, 'reasons': [], 'key': '03a107bff3ce10be1d70dd18e74bc09967e4d6309ba50d5f1ddc8664125531b8', 'form': 'rfc8785', 'time': {'sealed': False}, 'signer': 'did:key:z6MkehRgf7yJbgaGfYsdoAsKdBPE3dj2CYhowQdcjqSJgvVd'}\n" ] } ], "source": [ "with open(\"bell-job.json\", \"w\") as f:\n", " json.dump(job, f)\n", "print(wq.verify(\"bell-job.json\"))" ] }, { "cell_type": "markdown", "id": "bell-receipt-8", "metadata": {}, "source": [ "The command line checks the same file the same way: `wai-quantum verify bell-job.json`." ] }, { "cell_type": "markdown", "id": "bell-receipt-9", "metadata": {}, "source": [ "## What breaks it" ] }, { "cell_type": "code", "execution_count": 7, "id": "bell-receipt-10", "metadata": { "execution": { "iopub.execute_input": "2026-11-11T12:23:54.017376Z", "iopub.status.busy": "2026-11-11T12:23:54.017293Z", "iopub.status.idle": "2026-11-11T12:23:54.019999Z", "shell.execute_reply": "2026-11-11T12:23:54.019691Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one more count valid: False\n", "another seed valid: False\n", "another method named valid: False\n" ] } ], "source": [ "for what, change in [\n", " (\"one more count\", lambda j: j[\"result\"][\"counts\"].__setitem__(\"00\", j[\"result\"][\"counts\"][\"00\"] + 1)),\n", " (\"another seed\", lambda j: j[\"request\"].__setitem__(\"seed\", 2)),\n", " (\"another method named\", lambda j: j[\"result\"].__setitem__(\"method\", \"statevector\")),\n", "]:\n", " forged = json.loads(json.dumps(job))\n", " change(forged)\n", " print(f\"{what:<22} valid: {wq.verify(forged).valid}\")" ] }, { "cell_type": "code", "execution_count": 8, "id": "bell-receipt-11", "metadata": { "execution": { "iopub.execute_input": "2026-11-11T12:23:54.020774Z", "iopub.status.busy": "2026-11-11T12:23:54.020706Z", "iopub.status.idle": "2026-11-11T12:23:54.023398Z", "shell.execute_reply": "2026-11-11T12:23:54.023066Z" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "394648b8d10e43a68e7c24031afd8eb0", "version_major": 2, "version_minor": 1 }, "text/html": [ "
receipt INVALID checked here, binding the request and the result as given
signerdid:key:z6MkehRgf7yJbgaGfYsdoAsKdBPE3dj2CYhowQdcjqSJgvVd
key03a107bff3ce10be1d70dd18e74bc09967e4d6309ba50d5f1ddc8664125531b8
digesta80f7e659df721f1136cfb3aaa63b983a4c976c5421ae76671c8bebdb6c6353d
signature6b1619335dcdaa9f…98e57c8fe1e95c00
formed25519 over rfc8785 canonical JSON
" ], "text/plain": [ "Receipt(INVALID, signed by did:key:z6MkehRgf7yJbgaGfYsdoAsKdBPE3dj2CYhowQdcjqSJgvVd)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "forged = json.loads(json.dumps(job))\n", "forged[\"result\"][\"counts\"][\"00\"] += 1\n", "wq.Receipt(forged)" ] }, { "cell_type": "code", "execution_count": 9, "id": "bell-receipt-12", "metadata": { "execution": { "iopub.execute_input": "2026-11-11T12:23:54.024007Z", "iopub.status.busy": "2026-11-11T12:23:54.023935Z", "iopub.status.idle": "2026-11-11T12:23:54.025198Z", "shell.execute_reply": "2026-11-11T12:23:54.024999Z" } }, "outputs": [], "source": [ "import os\n", "os.remove(\"bell-job.json\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.15" } }, "nbformat": 4, "nbformat_minor": 5 }