# eciespy
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/2a11aeb9939244019d2c64bce3ff3c4e)](https://app.codacy.com/gh/ecies/py/dashboard)
[![CI](https://img.shields.io/github/actions/workflow/status/ecies/py/ci.yml?branch=master)](https://github.com/ecies/py/actions)
[![Codecov](https://img.shields.io/codecov/c/github/ecies/py.svg)](https://codecov.io/gh/ecies/py)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/eciespy.svg)](https://pypi.org/project/eciespy/)
[![PyPI](https://img.shields.io/pypi/v/eciespy.svg)](https://pypi.org/project/eciespy/)
[![License](https://img.shields.io/github/license/ecies/py.svg)](https://github.com/ecies/py)
Elliptic Curve Integrated Encryption Scheme for secp256k1 in Python.
Other language versions:
- [Rust](https://github.com/ecies/rs)
- [TypeScript](https://github.com/ecies/js)
- [Golang](https://github.com/ecies/go)
- [WASM](https://github.com/ecies/rs-wasm)
You can also check a FastAPI web backend demo [here](https://github.com/kigawas/eciespy-demo).
## Install
`pip install eciespy`
## Quick Start
```python
>>> from ecies.utils import generate_eth_key, generate_key
>>> from ecies import encrypt, decrypt
>>> eth_k = generate_eth_key()
>>> sk_hex = eth_k.to_hex() # hex string
>>> pk_hex = eth_k.public_key.to_hex() # hex string
>>> data = b'this is a test'
>>> decrypt(sk_hex, encrypt(pk_hex, data))
b'this is a test'
>>> secp_k = generate_key()
>>> sk_bytes = secp_k.secret # bytes
>>> pk_bytes = secp_k.public_key.format(True) # bytes
>>> decrypt(sk_bytes, encrypt(pk_bytes, data))
b'this is a test'
```
Or just use a builtin command `eciespy` in your favorite [command line](#command-line-interface).
## API
### `ecies.encrypt(receiver_pk: Union[str, bytes], msg: bytes) -> bytes`
Parameters:
- **receiver_pk** - Receiver's public key (hex str or bytes)
- **msg** - Data to encrypt
Returns: **bytes**
### `ecies.decrypt(receiver_sk: Union[str, bytes], msg: bytes) -> bytes`
Parameters:
- **receiver_sk** - Receiver's private key (hex str or bytes)
- **msg** - Data to decrypt
Returns: **bytes**
## Command Line Interface
### Show help
```console
$ eciespy -h
usage: eciespy [-h] [-e] [-d] [-g] [-k KEY] [-D [DATA]] [-O [OUT]]
Elliptic Curve Integrated Encryption Scheme for secp256k1 in Python
optional arguments:
-h, --help show this help message and exit
-e, --encrypt encrypt with public key, exclusive with -d
-d, --decrypt decrypt with private key, exclusive with -e
-g, --generate generate ethereum key pair
-k KEY, --key KEY public or private key file
-D [DATA], --data [DATA]
file to encrypt or decrypt, if not specified, it will
read from stdin
-O [OUT], --out [OUT]
encrypted or decrypted file, if not specified, it will
write to stdout
```
### Generate eth key
```console
$ eciespy -g
Private: 0x95d3c5e483e9b1d4f5fc8e79b2deaf51362980de62dbb082a9a4257eef653d7d
Public: 0x98afe4f150642cd05cc9d2fa36458ce0a58567daeaf5fde7333ba9b403011140a4e28911fcf83ab1f457a30b4959efc4b9306f514a4c3711a16a80e3b47eb58b
Address: 0x47e801184B3a8ea8E6A4A7A4CFEfEcC76809Da72
```
### Encrypt with public key and decrypt with private key
```console
$ echo '0x95d3c5e483e9b1d4f5fc8e79b2deaf51362980de62dbb082a9a4257eef653d7d' > sk
$ echo '0x98afe4f150642cd05cc9d2fa36458ce0a58567daeaf5fde7333ba9b403011140a4e28911fcf83ab1f457a30b4959efc4b9306f514a4c3711a16a80e3b47eb58b' > pk
$ echo 'hello ecies' | eciespy -e -k pk | eciespy -d -k sk
hello ecies
$ echo 'data to encrypt' > data
$ eciespy -e -k pk -D data -O enc_data
$ eciespy -d -k sk -D enc_data
data to encrypt
$ rm sk pk data enc_data
```
## Configuration
Ephemeral key format in the payload and shared key in the key derivation can be configured as compressed or uncompressed format.
```py
SymmetricAlgorithm = Literal["aes-256-gcm", "xchacha20"]
NonceLength = Literal[12, 16] # only for aes-256-gcm, xchacha20 will always be 24
COMPRESSED_PUBLIC_KEY_SIZE = 33
UNCOMPRESSED_PUBLIC_KEY_SIZE = 65
@dataclass()
class Config:
is_ephemeral_key_compressed: bool = False
is_hkdf_key_compressed: bool = False
symmetric_algorithm: SymmetricAlgorithm = "aes-256-gcm"
symmetric_nonce_length: NonceLength = 16
@property
def ephemeral_key_size(self):
return (
COMPRESSED_PUBLIC_KEY_SIZE
if self.is_ephemeral_key_compressed
else UNCOMPRESSED_PUBLIC_KEY_SIZE
)
ECIES_CONFIG = Config()
```
If you set `is_ephemeral_key_compressed = true`, the payload would be like: `33 Bytes + AES` instead of `65 Bytes + AES`.
If you set `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)`.
If you set `symmetric_algorithm = "xchacha20"`, plaintext data would be encrypted with XChaCha20-Poly1305.
If you set `symmetric_nonce_length = 12`, then the nonce of AES-256-GCM would be 12 bytes. XChaCha20-Poly1305's nonce is always 24 bytes.
For compatibility, make sure different applications share the same configuration.
## Technical details
They are moved to [DETAILS.md](./DETAILS.md).
## Changelog
See [CHANGELOG.md](./CHANGELOG.md).
Raw data
{
"_id": null,
"home_page": "https://github.com/ecies/py",
"name": "eciespy",
"maintainer": "Weiliang Li",
"docs_url": null,
"requires_python": ">=3.8,<4.0",
"maintainer_email": "to.be.impressive@gmail.com",
"keywords": "secp256k1,crypto,elliptic curves,ecies,bitcoin,ethereum,cryptocurrency",
"author": "Weiliang Li",
"author_email": "to.be.impressive@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/21/cd/faa133f0e95f40fa5a2c168d70596d0cc6b0edba6dedcb41efa72342c892/eciespy-0.4.1.tar.gz",
"platform": null,
"description": "# eciespy\n\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/2a11aeb9939244019d2c64bce3ff3c4e)](https://app.codacy.com/gh/ecies/py/dashboard)\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[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/eciespy.svg)](https://pypi.org/project/eciespy/)\n[![PyPI](https://img.shields.io/pypi/v/eciespy.svg)](https://pypi.org/project/eciespy/)\n[![License](https://img.shields.io/github/license/ecies/py.svg)](https://github.com/ecies/py)\n\nElliptic Curve Integrated Encryption Scheme for secp256k1 in Python.\n\nOther language versions:\n\n- [Rust](https://github.com/ecies/rs)\n- [TypeScript](https://github.com/ecies/js)\n- [Golang](https://github.com/ecies/go)\n- [WASM](https://github.com/ecies/rs-wasm)\n\nYou can also check a FastAPI web backend demo [here](https://github.com/kigawas/eciespy-demo).\n\n## Install\n\n`pip install eciespy`\n\n## Quick Start\n\n```python\n>>> from ecies.utils import generate_eth_key, generate_key\n>>> from ecies import encrypt, decrypt\n>>> eth_k = generate_eth_key()\n>>> sk_hex = eth_k.to_hex() # hex string\n>>> pk_hex = eth_k.public_key.to_hex() # hex string\n>>> data = b'this is a test'\n>>> decrypt(sk_hex, encrypt(pk_hex, data))\nb'this is a test'\n>>> secp_k = generate_key()\n>>> sk_bytes = secp_k.secret # bytes\n>>> pk_bytes = secp_k.public_key.format(True) # bytes\n>>> decrypt(sk_bytes, encrypt(pk_bytes, data))\nb'this is a test'\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], msg: bytes) -> bytes`\n\nParameters:\n\n- **receiver_pk** - Receiver's public key (hex str or bytes)\n- **msg** - Data to encrypt\n\nReturns: **bytes**\n\n### `ecies.decrypt(receiver_sk: Union[str, bytes], msg: bytes) -> bytes`\n\nParameters:\n\n- **receiver_sk** - Receiver's private key (hex str or bytes)\n- **msg** - Data to decrypt\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' > sk\n$ echo '0x98afe4f150642cd05cc9d2fa36458ce0a58567daeaf5fde7333ba9b403011140a4e28911fcf83ab1f457a30b4959efc4b9306f514a4c3711a16a80e3b47eb58b' > pk\n$ echo 'hello ecies' | eciespy -e -k pk | eciespy -d -k sk\nhello ecies\n$ echo 'data to encrypt' > 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\nSymmetricAlgorithm = Literal[\"aes-256-gcm\", \"xchacha20\"]\nNonceLength = Literal[12, 16] # only for aes-256-gcm, xchacha20 will always be 24\n\nCOMPRESSED_PUBLIC_KEY_SIZE = 33\nUNCOMPRESSED_PUBLIC_KEY_SIZE = 65\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\nIf you set `is_ephemeral_key_compressed = true`, the payload would be like: `33 Bytes + AES` instead of `65 Bytes + AES`.\n\nIf you set `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\nIf you set `symmetric_algorithm = \"xchacha20\"`, plaintext data would be encrypted with XChaCha20-Poly1305.\n\nIf you set `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",
"bugtrack_url": null,
"license": "MIT",
"summary": "Elliptic Curve Integrated Encryption Scheme for secp256k1 in Python",
"version": "0.4.1",
"project_urls": {
"Homepage": "https://github.com/ecies/py",
"Repository": "https://github.com/ecies/py"
},
"split_keywords": [
"secp256k1",
"crypto",
"elliptic curves",
"ecies",
"bitcoin",
"ethereum",
"cryptocurrency"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "4d437442ac1796788ebcb163380a0f2cb1738a0b5a7516a2f1fc65ae4b8e6e26",
"md5": "5bc33431e72292115be66f3aa033097f",
"sha256": "585de62e76ac8f210ea8d3e22aacc0064c270469bef0ed453627f2cacec81814"
},
"downloads": -1,
"filename": "eciespy-0.4.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5bc33431e72292115be66f3aa033097f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8,<4.0",
"size": 10044,
"upload_time": "2023-11-13T15:45:35",
"upload_time_iso_8601": "2023-11-13T15:45:35.124756Z",
"url": "https://files.pythonhosted.org/packages/4d/43/7442ac1796788ebcb163380a0f2cb1738a0b5a7516a2f1fc65ae4b8e6e26/eciespy-0.4.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "21cdfaa133f0e95f40fa5a2c168d70596d0cc6b0edba6dedcb41efa72342c892",
"md5": "d9f50570ca09966e00b7c947265e4017",
"sha256": "daf655840d4fc6e9619ae59bbdab57cc944687dcb0aa2ac7800efe30a754d5ff"
},
"downloads": -1,
"filename": "eciespy-0.4.1.tar.gz",
"has_sig": false,
"md5_digest": "d9f50570ca09966e00b7c947265e4017",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8,<4.0",
"size": 8935,
"upload_time": "2023-11-13T15:45:36",
"upload_time_iso_8601": "2023-11-13T15:45:36.918578Z",
"url": "https://files.pythonhosted.org/packages/21/cd/faa133f0e95f40fa5a2c168d70596d0cc6b0edba6dedcb41efa72342c892/eciespy-0.4.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-11-13 15:45:36",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ecies",
"github_project": "py",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"lcname": "eciespy"
}