{ "info": { "author": "Nicholas Boucher, Luka Govedi\u010d, Pasapol Saowakon, Kyle Swanson", "author_email": "swansonk.14@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "# Damgard-Jurik\n\nAn implementation of the threshold variant of the [Damgard-Jurik](https://people.csail.mit.edu/rivest/voting/papers/DamgardJurikNielsen-AGeneralizationOfPailliersPublicKeySystemWithApplicationsToElectronicVoting.pdf) homomorphic encryption cryptosystem.\n\n## Table of Contents\n\n* [Installation](#installation)\n* [Public and Private Keys](#public-and-private-keys)\n* [Key Generation](#key-generation)\n* [Encryption and Decryption](#encryption-and-decryption)\n* [Homomorphic Operations](#homomorphic-operations)\n\n## Installation\n\nRequires Python 3.6+.\n\n```bash\npip install damgard-jurik\n```\n\nAlternatively, the code can be cloned and installed locally as follows.\n\n```bash\ngit clone https://github.com/cryptovoting/damgard-jurik.git\ncd damgard-jurik\npip install -e .\n```\n*Note that the `-e` flag will instruct pip to install the package as \"editable\". That is, when changes are made to any part of the package during development, those changes will immediately be available system-wide on the activated python environment.*\n\nAll requirements for this package should be added to `setup.py`.\n\n## Public and Private Keys\n\nIn the threshold variant of Damgard-Jurik implemented in this repository, a key pair consists of single public key along with a private key that has been split into multiple components using [Shamir's secret sharing](https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing). The public key encrypts messages while the shares of the private key all contribute a portion of the decryption without ever requiring reconstruction of the private key. Thus, trust is distributed among the holders of the private key shares.\n\nIn this implementation, the public key is a `PublicKey` object with an encrypt function while the private key shares are `PrivateKeyShare` objects with a decrypt function that performs a partial decryption using that share of the private key. A `PrivateKeyRing` object holds a set of `PrivateKeyShare`s and contains a decrypt function that calls each `PrivateKeyShare`'s decrypt function and combines the results to obtain the final decryption.\n\n## Key Generation\n\nTo generate a `PublicKey` and the corresponding `PrivateKeyRing`, run the following commands:\n\n```python\nfrom damgard_jurik import keygen\n\npublic_key, private_key_ring = keygen(\n n_bits=64,\n s=1,\n threshold=3,\n n_shares=3\n)\n```\n\nThe parameters to `keygen` are as follows:\n\n- `n_bits`: The number of bits of encryption used in the public key and private key shares.\n- `s`: The exponent to which the public key parameter `n` is raised (where `n = p * q` is the product of two `n_bits`-bit primes `p` and `q`.). Plaintexts are integers in the space `Z_n^s = {0, 1, ..., n^s - 1}`.\n- `threshold`: The minimum number of private key shares needed to decrypt an encrypted message.\n- `n_shares`: The number of private key shares to generate.\n\n\n## Encryption and Decryption\n\nEncryption and decryption are implemented as methods of the `PublicKey` and `PrivateKeyRing` classes, respectively.\n\nFor example:\n\n```python\nm = 42\nc = public_key.encrypt(m)\nm_prime = private_key_ring.decrypt(c)\n# m_prime = 42\n```\n\nPlaintexts like `m` are simply Python integers while ciphertexts (encrypted plaintexts) like `c` are instances of the `EncryptedNumber` class. `EncryptedNumber` objects contain an encryption of the plaintext along with a reference to the `PublicKey` used to encrypt the plaintext.\n\nAdditionally, the `PublicKey` and `PrivateKingRing` classes have a convenience method for encrypting and decrypting lists of integers, as shown below.\n\n```python\nm_list = [42, 33, 100]\nc_list = public_key.encrypt_list(m_list)\nm_prime_list = private_key_ring.decrypt_list(c_list)\n# m_prime_list = [42, 33, 100]\n```\n\n## Homomorphic Operations\n\nDue to the additively homomorphic nature of the Damgard-Jurik cryptosystem, ciphertexts can be combined in such a way as to obtain an encryption of the sum of the associated plaintexts. Futhermore, ciphertexts can be combined with un-encrypted integers in such a way as to obtain the product of the associated plaintext and the un-encrypted integer. For convenience, the `EncryptedNumber` class has overridden the `+`, `-`, `*`, and `/` operators to implement these operations.\n\nFor example:\n\n```python\nm_1, m_2 = 42, 33\nc_1, c_2 = public_key.encrypt(m_1), public_key.encrypt(m_2)\nc = c_1 + c_2\nm_prime = private_key_ring.decrypt(c)\n# m_prime = 75 = 42 + 33\n```\n\n```python\nm, s = 42, 2\nc = public_key.encrypt(m)\nc_prime = c * s\nm_prime = private_key_ring.decrypt(c_prime)\n# m_prime = 84 = 42 * 2\n```\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/cryptovoting/damgard-jurik", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "damgard-jurik", "package_url": "https://pypi.org/project/damgard-jurik/", "platform": "", "project_url": "https://pypi.org/project/damgard-jurik/", "project_urls": { "Homepage": "https://github.com/cryptovoting/damgard-jurik" }, "release_url": "https://pypi.org/project/damgard-jurik/0.0.3/", "requires_dist": [ "gmpy2" ], "requires_python": "", "summary": "Homomorphic encryption using the threshold variant of the Damgard-Jurik cryptosystem.", "version": "0.0.3" }, "last_serial": 5269966, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "851fe56f0dfbeeae00362f9e310c1651", "sha256": "b40f4a595326fdb22fdc61d06217b6b90d4cf1f164d348e155e1eecf63821ce9" }, "downloads": -1, "filename": "damgard_jurik-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "851fe56f0dfbeeae00362f9e310c1651", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 8714, "upload_time": "2019-05-14T04:28:57", "url": "https://files.pythonhosted.org/packages/f3/ae/f91c02f85decb51329894234b4716f90f2033a3281ed168a6a2b966ba40b/damgard_jurik-0.0.1-py3-none-any.whl" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "a158155ad781ace93d8361c4fadd1f54", "sha256": "3fdbf9b7f31de848038ba70401e701a1903724a933241fcc14264b42c166a106" }, "downloads": -1, "filename": "damgard_jurik-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "a158155ad781ace93d8361c4fadd1f54", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11216, "upload_time": "2019-05-15T00:24:12", "url": "https://files.pythonhosted.org/packages/fc/db/0868e76a8198ea65c3fd88ae8e25ffa9ee429e7d76bbaa62ebc38165e8f7/damgard_jurik-0.0.2-py3-none-any.whl" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "9f0b6da4bb8ad650559093e8e3d84ed3", "sha256": "326f4a407aee4a181fb29efa9b879434ebb7bd7fa4997c74d07f0bdbd49ca37f" }, "downloads": -1, "filename": "damgard_jurik-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "9f0b6da4bb8ad650559093e8e3d84ed3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11271, "upload_time": "2019-05-15T00:50:08", "url": "https://files.pythonhosted.org/packages/46/d1/90ca19b7302f47ef385c7793ec3d06816b12ebe3d1c2aaf0cacf7772cbf6/damgard_jurik-0.0.3-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "9f0b6da4bb8ad650559093e8e3d84ed3", "sha256": "326f4a407aee4a181fb29efa9b879434ebb7bd7fa4997c74d07f0bdbd49ca37f" }, "downloads": -1, "filename": "damgard_jurik-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "9f0b6da4bb8ad650559093e8e3d84ed3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11271, "upload_time": "2019-05-15T00:50:08", "url": "https://files.pythonhosted.org/packages/46/d1/90ca19b7302f47ef385c7793ec3d06816b12ebe3d1c2aaf0cacf7772cbf6/damgard_jurik-0.0.3-py3-none-any.whl" } ] }