{ "cells": [ { "cell_type": "markdown", "id": "e29a137f", "metadata": { "cq.autogen": "title_cell" }, "source": [ "# Elliptic Curve Addition" ] }, { "cell_type": "code", "execution_count": 1, "id": "06da449a", "metadata": { "cq.autogen": "top_imports" }, "outputs": [], "source": [ "from qualtran import Bloq, CompositeBloq, BloqBuilder, Signature, Register\n", "from qualtran import QBit, QInt, QUInt, QAny\n", "from qualtran.drawing import show_bloq, show_call_graph, show_counts_sigma\n", "from typing import *\n", "import numpy as np\n", "import sympy\n", "import cirq" ] }, { "cell_type": "markdown", "id": "dc1d3b04", "metadata": { "cq.autogen": "ECAdd.bloq_doc.md" }, "source": [ "## `ECAdd`\n", "Add two elliptic curve points.\n", "\n", "This takes elliptic curve points given by (a, b) and (x, y)\n", "and outputs the sum (x_r, y_r) in the second pair of registers.\n", "\n", "Because the decomposition of this Bloq is complex, we split it into six separate parts\n", "corresponding to the parts described in figure 10 of the Litinski paper cited below. We follow\n", "the signature from figure 5 and break down the further decompositions based on the steps in\n", "figure 10.\n", "\n", "#### Parameters\n", " - `n`: The bitsize of the two registers storing the elliptic curve point\n", " - `mod`: The modulus of the field in which we do the addition.\n", " - `window_size`: The number of bits in the ModMult window. \n", "\n", "#### Registers\n", " - `a`: The x component of the first input elliptic curve point of bitsize `n` in montgomery form.\n", " - `b`: The y component of the first input elliptic curve point of bitsize `n` in montgomery form.\n", " - `x`: The x component of the second input elliptic curve point of bitsize `n` in montgomery form, which will contain the x component of the resultant curve point.\n", " - `y`: The y component of the second input elliptic curve point of bitsize `n` in montgomery form, which will contain the y component of the resultant curve point.\n", " - `lam_r`: The precomputed lambda slope used in the addition operation if (a, b) = (x, y) in montgomery form. \n", "\n", "#### References\n", " - [How to compute a 256-bit elliptic curve private key with only 50 million Toffoli gates](https://arxiv.org/abs/2306.08585). Litinski. 2023. Fig 5.\n" ] }, { "cell_type": "code", "execution_count": 2, "id": "68605201", "metadata": { "cq.autogen": "ECAdd.bloq_doc.py" }, "outputs": [], "source": [ "from qualtran.bloqs.cryptography.ecc import ECAdd" ] }, { "cell_type": "markdown", "id": "bba2f42d", "metadata": { "cq.autogen": "ECAdd.example_instances.md" }, "source": [ "### Example Instances" ] }, { "cell_type": "code", "execution_count": 3, "id": "0d051c3b", "metadata": { "cq.autogen": "ECAdd.ec_add" }, "outputs": [], "source": [ "n, p = sympy.symbols('n p')\n", "ec_add = ECAdd(n, mod=p)" ] }, { "cell_type": "code", "execution_count": 4, "id": "170da165", "metadata": { "cq.autogen": "ECAdd.ec_add_small" }, "outputs": [], "source": [ "ec_add_small = ECAdd(5, mod=7)" ] }, { "cell_type": "markdown", "id": "39210af4", "metadata": { "cq.autogen": "ECAdd.graphical_signature.md" }, "source": [ "#### Graphical Signature" ] }, { "cell_type": "code", "execution_count": 5, "id": "d353f0ec", "metadata": { "cq.autogen": "ECAdd.graphical_signature.py" }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "9bebea376f4a438a8b0cfd25c476d503", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Output(outputs=({'output_type': 'display_data', 'data': {'text/plain': '\n", "\n", "counts\n", "\n", "\n", "\n", "b0\n", "\n", "ECAdd\n", "\n", "\n", "\n", "b1\n", "\n", "_ECAddStepOne\n", "\n", "\n", "\n", "b0->b1\n", "\n", "\n", "1\n", "\n", "\n", "\n", "b2\n", "\n", "_ECAddStepTwo\n", "\n", "\n", "\n", "b0->b2\n", "\n", "\n", "1\n", "\n", "\n", "\n", "b3\n", "\n", "_ECAddStepThree\n", "\n", "\n", "\n", "b0->b3\n", "\n", "\n", "1\n", "\n", "\n", "\n", "b4\n", "\n", "_ECAddStepFour\n", "\n", "\n", "\n", "b0->b4\n", "\n", "\n", "1\n", "\n", "\n", "\n", "b5\n", "\n", "_ECAddStepFive\n", "\n", "\n", "\n", "b0->b5\n", "\n", "\n", "1\n", "\n", "\n", "\n", "b6\n", "\n", "_ECAddStepSix\n", "\n", "\n", "\n", "b0->b6\n", "\n", "\n", "1\n", "\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "#### Counts totals:\n", " - `_ECAddStepFive`: 1\n", " - `_ECAddStepFour`: 1\n", " - `_ECAddStepOne`: 1\n", " - `_ECAddStepSix`: 1\n", " - `_ECAddStepThree`: 1\n", " - `_ECAddStepTwo`: 1" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from qualtran.resource_counting.generalizers import ignore_split_join\n", "ec_add_g, ec_add_sigma = ec_add.call_graph(max_depth=1, generalizer=ignore_split_join)\n", "show_call_graph(ec_add_g)\n", "show_counts_sigma(ec_add_sigma)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.11.8" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "1e7db0a3a9134a50acdfc6a37ee7481e": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "55d4076d59294156a544b0fd4d2beccd": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_88c0109a6aab489baaa012f0888f4f78", "msg_id": "", "outputs": [ { "data": { "text/markdown": "`ec_add_small`", "text/plain": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": "\n\nmy_graph\n\n\n\na_G5\na\n\n\n\nECAdd\n\nECAdd\n\na\n\nb\n\nx\n\ny\n\nlam_r\n\n\n\na_G5:e->ECAdd:w\n\n\n5\n\n\n\nb_G1\nb\n\n\n\nb_G1:e->ECAdd:w\n\n\n5\n\n\n\nx_G0\nx\n\n\n\nx_G0:e->ECAdd:w\n\n\n5\n\n\n\ny_G6\ny\n\n\n\ny_G6:e->ECAdd:w\n\n\n5\n\n\n\nlam_r_G2\nlam_r\n\n\n\nlam_r_G2:e->ECAdd:w\n\n\n5\n\n\n\na_G12\na\n\n\n\nECAdd:e->a_G12:w\n\n\n5\n\n\n\nb_G9\nb\n\n\n\nECAdd:e->b_G9:w\n\n\n5\n\n\n\nx_G11\nx\n\n\n\nECAdd:e->x_G11:w\n\n\n5\n\n\n\ny_G8\ny\n\n\n\nECAdd:e->y_G8:w\n\n\n5\n\n\n\nlam_r_G4\nlam_r\n\n\n\nECAdd:e->lam_r_G4:w\n\n\n5\n\n\n", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ], "tabbable": null, "tooltip": null } }, "63ce81e43bd54c17af396adcf026f47c": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_7ceff33feeac4bd68a74bea514afea8a", "msg_id": "", "outputs": [ { "data": { "text/markdown": "`ec_add`", "text/plain": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": "\n\nmy_graph\n\n\n\na_G2\na\n\n\n\nECAdd\n\nECAdd\n\na\n\nb\n\nx\n\ny\n\nlam_r\n\n\n\na_G2:e->ECAdd:w\n\n\nn\n\n\n\nb_G7\nb\n\n\n\nb_G7:e->ECAdd:w\n\n\nn\n\n\n\nx_G5\nx\n\n\n\nx_G5:e->ECAdd:w\n\n\nn\n\n\n\ny_G1\ny\n\n\n\ny_G1:e->ECAdd:w\n\n\nn\n\n\n\nlam_r_G0\nlam_r\n\n\n\nlam_r_G0:e->ECAdd:w\n\n\nn\n\n\n\na_G14\na\n\n\n\nECAdd:e->a_G14:w\n\n\nn\n\n\n\nb_G9\nb\n\n\n\nECAdd:e->b_G9:w\n\n\nn\n\n\n\nx_G6\nx\n\n\n\nECAdd:e->x_G6:w\n\n\nn\n\n\n\ny_G3\ny\n\n\n\nECAdd:e->y_G3:w\n\n\nn\n\n\n\nlam_r_G12\nlam_r\n\n\n\nECAdd:e->lam_r_G12:w\n\n\nn\n\n\n", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ], "tabbable": null, "tooltip": null } }, "7ceff33feeac4bd68a74bea514afea8a": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "88c0109a6aab489baaa012f0888f4f78": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "9bebea376f4a438a8b0cfd25c476d503": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_63ce81e43bd54c17af396adcf026f47c", "IPY_MODEL_55d4076d59294156a544b0fd4d2beccd" ], "layout": "IPY_MODEL_1e7db0a3a9134a50acdfc6a37ee7481e", "tabbable": null, "tooltip": null } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }