{ "cells": [ { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "Multiplicative Inverse\n", "======================\n", "\n", "In this section we will compute exact multiplicative inverses with respect to the field. Note that this is not the same as :ref:`division `, which produces approximate results.\n", "\n", "In this case the multiplicative inverse we are dealing with is associated specifically with the field, and not relative to the encoded or decoded values that we create with our fixed point arithmetic. Thus, we will be working with the :any:`Identity` encoding that does not encode or decode values.\n", "\n", "In this example, we generate random field values, reveal them, compute their multiplicative inverses, reveal those, and perform an untruncated multiplication, all of which yield the field value :math:`1`, showing that the inverses are correct for the field." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:root:************************************************************\n", "INFO:root:Player 0 random value: 4415459484255806218\n", "INFO:root:Player 0 multiplicative inverse: 1110914679579980136\n", "INFO:root:Player 0 product: 1\n", "INFO:root:************************************************************\n", "INFO:root:Player 0 random value: 12865292195403216087\n", "INFO:root:Player 0 multiplicative inverse: 8281206491458532839\n", "INFO:root:Player 0 product: 1\n", "INFO:root:************************************************************\n", "INFO:root:Player 0 random value: 16098991628576644671\n", "INFO:root:Player 0 multiplicative inverse: 8756623746587136875\n", "INFO:root:Player 0 product: 1\n" ] } ], "source": [ "import logging\n", "\n", "import numpy\n", "\n", "from cicada.additive import AdditiveProtocolSuite\n", "from cicada.communicator import SocketCommunicator\n", "from cicada.encoding import Identity\n", "from cicada.logger import Logger\n", "\n", "logging.basicConfig(level=logging.INFO)\n", "\n", "def main(communicator):\n", " log = Logger(logging.getLogger(), communicator)\n", " protocol = AdditiveProtocolSuite(communicator)\n", "\n", " for i in range(3):\n", " log.info(f\"*\" * 60, src=0)\n", "\n", " random_share = protocol.field_uniform()\n", " random = protocol.reveal(random_share, encoding=Identity())\n", " log.info(f\"Player {communicator.rank} random value: {random}\", src=0)\n", " \n", " inverse_share = protocol.multiplicative_inverse(random_share)\n", " inverse = protocol.reveal(inverse_share, encoding=Identity())\n", " log.info(f\"Player {communicator.rank} multiplicative inverse: {inverse}\", src=0)\n", "\n", " product_share = protocol.field_multiply(random_share, inverse_share)\n", " product = protocol.reveal(product_share, encoding=Identity())\n", " log.info(f\"Player {communicator.rank} product: {product}\", src=0)\n", "\n", "SocketCommunicator.run(world_size=3, fn=main);" ] } ], "metadata": { "celltoolbar": "Raw Cell Format", "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.12.2" } }, "nbformat": 4, "nbformat_minor": 4 }