{"id":18676949,"url":"https://github.com/ecies/py","last_synced_at":"2025-05-15T22:03:46.989Z","repository":{"id":38484979,"uuid":"136574392","full_name":"ecies/py","owner":"ecies","description":"Elliptic Curve Integrated Encryption Scheme for secp256k1 in Python","archived":false,"fork":false,"pushed_at":"2025-03-10T15:29:42.000Z","size":697,"stargazers_count":134,"open_issues_count":2,"forks_count":26,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-01T07:40:33.012Z","etag":null,"topics":["bitcoin","cryptocurrency","cryptography","ecies","elliptic-curve-cryptography","ethereum","python3","secp256k1"],"latest_commit_sha":null,"homepage":"https://ecies.org/py","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ecies.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"kigawas"}},"created_at":"2018-06-08T06:10:19.000Z","updated_at":"2025-03-14T15:19:00.000Z","dependencies_parsed_at":"2023-02-02T06:17:32.522Z","dependency_job_id":"68f64668-776e-403d-b55e-a813c55ec1c3","html_url":"https://github.com/ecies/py","commit_stats":{"total_commits":275,"total_committers":8,"mean_commits":34.375,"dds":0.5309090909090909,"last_synced_commit":"01e03b80f60553e4998dd3e109641eb14f2597c0"},"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecies%2Fpy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecies%2Fpy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecies%2Fpy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecies%2Fpy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ecies","download_url":"https://codeload.github.com/ecies/py/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247801175,"owners_count":20998339,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitcoin","cryptocurrency","cryptography","ecies","elliptic-curve-cryptography","ethereum","python3","secp256k1"],"created_at":"2024-11-07T09:31:52.788Z","updated_at":"2025-05-15T22:03:46.973Z","avatar_url":"https://github.com/ecies.png","language":"Python","funding_links":["https://github.com/sponsors/kigawas"],"categories":[],"sub_categories":[],"readme":"# eciespy\n\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/2a11aeb9939244019d2c64bce3ff3c4e)](https://app.codacy.com/gh/ecies/py/dashboard)\n[![License](https://img.shields.io/github/license/ecies/py.svg)](https://github.com/ecies/py)\n[![PyPI](https://img.shields.io/pypi/v/eciespy.svg)](https://pypi.org/project/eciespy/)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/eciespy)](https://pypistats.org/packages/eciespy)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/eciespy.svg)](https://pypi.org/project/eciespy/)\n[![CI](https://img.shields.io/github/actions/workflow/status/ecies/py/ci.yml?branch=master)](https://github.com/ecies/py/actions)\n[![Codecov](https://img.shields.io/codecov/c/github/ecies/py.svg)](https://codecov.io/gh/ecies/py)\n\nElliptic Curve Integrated Encryption Scheme for secp256k1 in Python.\n\nOther language versions:\n\n- [TypeScript](https://github.com/ecies/js)\n- [Rust](https://github.com/ecies/rs)\n- [Golang](https://github.com/ecies/go)\n- [WASM](https://github.com/ecies/rs-wasm)\n- [Java](https://github.com/ecies/java)\n- [Dart](https://github.com/ecies/dart)\n\nYou can also check a web backend demo [here](https://github.com/ecies/py-demo).\n\n## Install\n\n`pip install eciespy`\n\nOr `pip install 'eciespy[eth]'` to install `eth-keys` as well.\n\n## Quick Start\n\n```python\n\u003e\u003e\u003e from ecies.keys import PrivateKey\n\u003e\u003e\u003e from ecies import encrypt, decrypt\n\u003e\u003e\u003e data = 'hello world🌍'.encode()\n\u003e\u003e\u003e sk = PrivateKey('secp256k1')\n\u003e\u003e\u003e sk_bytes = sk.secret  # bytes\n\u003e\u003e\u003e pk_bytes = sk.public_key.to_bytes(True)  # bytes\n\u003e\u003e\u003e decrypt(sk_bytes, encrypt(pk_bytes, data)).decode()\n'hello world🌍'\n\u003e\u003e\u003e sk_hex = sk.to_hex() # hex str\n\u003e\u003e\u003e pk_hex = sk.public_key.to_hex() # hex str\n\u003e\u003e\u003e decrypt(sk_hex, encrypt(pk_hex, data)).decode()\n'hello world🌍'\n```\n\nOr just use a builtin command `eciespy` in your favorite [command line](#command-line-interface).\n\n## API\n\n### `ecies.encrypt(receiver_pk: Union[str, bytes], data: bytes, config: Config = ECIES_CONFIG) -\u003e bytes`\n\nParameters:\n\n- **receiver_pk** - Receiver's public key (hex `str` or `bytes`)\n- **data** - Data to encrypt\n- **config** - Optional configuration object\n\nReturns: **bytes**\n\n### `ecies.decrypt(receiver_sk: Union[str, bytes], data: bytes, config: Config = ECIES_CONFIG) -\u003e bytes`\n\nParameters:\n\n- **receiver_sk** - Receiver's private key (hex `str` or `bytes`)\n- **data** - Data to decrypt\n- **config** - Optional configuration object\n\nReturns: **bytes**\n\n## Command Line Interface\n\n### Show help\n\n```console\n$ eciespy -h\nusage: eciespy [-h] [-e] [-d] [-g] [-k KEY] [-D [DATA]] [-O [OUT]]\n\nElliptic Curve Integrated Encryption Scheme for secp256k1 in Python\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -e, --encrypt         encrypt with public key, exclusive with -d\n  -d, --decrypt         decrypt with private key, exclusive with -e\n  -g, --generate        generate ethereum key pair\n  -k KEY, --key KEY     public or private key file\n  -D [DATA], --data [DATA]\n                        file to encrypt or decrypt, if not specified, it will\n                        read from stdin\n  -O [OUT], --out [OUT]\n                        encrypted or decrypted file, if not specified, it will\n                        write to stdout\n```\n\n### Generate eth key\n\n```console\n$ eciespy -g\nPrivate: 0x95d3c5e483e9b1d4f5fc8e79b2deaf51362980de62dbb082a9a4257eef653d7d\nPublic: 0x98afe4f150642cd05cc9d2fa36458ce0a58567daeaf5fde7333ba9b403011140a4e28911fcf83ab1f457a30b4959efc4b9306f514a4c3711a16a80e3b47eb58b\nAddress: 0x47e801184B3a8ea8E6A4A7A4CFEfEcC76809Da72\n```\n\n### Encrypt with public key and decrypt with private key\n\n```console\n$ echo '0x95d3c5e483e9b1d4f5fc8e79b2deaf51362980de62dbb082a9a4257eef653d7d' \u003e sk\n$ echo '0x98afe4f150642cd05cc9d2fa36458ce0a58567daeaf5fde7333ba9b403011140a4e28911fcf83ab1f457a30b4959efc4b9306f514a4c3711a16a80e3b47eb58b' \u003e pk\n$ echo 'hello ecies' | eciespy -e -k pk | eciespy -d -k sk\nhello ecies\n$ echo 'data to encrypt' \u003e data\n$ eciespy -e -k pk -D data -O enc_data\n$ eciespy -d -k sk -D enc_data\ndata to encrypt\n$ rm sk pk data enc_data\n```\n\n## Configuration\n\nEphemeral key format in the payload and shared key in the key derivation can be configured as compressed or uncompressed format.\n\n```py\nfrom .consts import COMPRESSED_PUBLIC_KEY_SIZE, UNCOMPRESSED_PUBLIC_KEY_SIZE\n\nSymmetricAlgorithm = Literal[\"aes-256-gcm\", \"xchacha20\"]\nNonceLength = Literal[12, 16]  # only for aes-256-gcm, xchacha20 will always be 24\n\n\n@dataclass()\nclass Config:\n    is_ephemeral_key_compressed: bool = False\n    is_hkdf_key_compressed: bool = False\n    symmetric_algorithm: SymmetricAlgorithm = \"aes-256-gcm\"\n    symmetric_nonce_length: NonceLength = 16\n\n    @property\n    def ephemeral_key_size(self):\n        return (\n            COMPRESSED_PUBLIC_KEY_SIZE\n            if self.is_ephemeral_key_compressed\n            else UNCOMPRESSED_PUBLIC_KEY_SIZE\n        )\n\n\nECIES_CONFIG = Config()\n```\n\nOn `is_ephemeral_key_compressed = True`, the payload would be like: `33 Bytes + AES` instead of `65 Bytes + AES`.\n\nOn `is_hkdf_key_compressed = True`, the hkdf key would be derived from `ephemeral public key (compressed) + shared public key (compressed)` instead of `ephemeral public key (uncompressed) + shared public key (uncompressed)`.\n\nOn `symmetric_algorithm = \"xchacha20\"`, plaintext data would be encrypted with XChaCha20-Poly1305.\n\nOn `symmetric_nonce_length = 12`, then the nonce of AES-256-GCM would be 12 bytes. XChaCha20-Poly1305's nonce is always 24 bytes.\n\nFor compatibility, make sure different applications share the same configuration.\n\n## Technical details\n\nThey are moved to [DETAILS.md](./DETAILS.md).\n\n## Changelog\n\nSee [CHANGELOG.md](./CHANGELOG.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fecies%2Fpy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fecies%2Fpy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fecies%2Fpy/lists"}