Elliptic Curve Integrated Encryption Scheme for secp256k1/curve25519 in Python.
Other language versions (curve25519 is not supported in some versions):
You can also check a web backend demo.
pip install eciespy
Or pip install 'eciespy[eth]' to install eth-keys as well.
>>>fromecies.keysimportPrivateKey>>>fromeciesimportencrypt, decrypt>>>data='hello world🌍'.encode()
>>>sk=PrivateKey('secp256k1')
>>>sk_bytes=sk.secret# bytes>>>pk_bytes=sk.public_key.to_bytes(True) # bytes>>>decrypt(sk_bytes, encrypt(pk_bytes, data)).decode()
'hello world🌍'>>>sk_hex=sk.to_hex() # hex str>>>pk_hex=sk.public_key.to_hex(True) # hex str>>>decrypt(sk_hex, encrypt(pk_hex, data)).decode()
'hello world🌍'>>>fromecies.keysimportPrivateKey>>>fromeciesimportencrypt, decrypt>>>fromecies.configimportECIES_CONFIG>>>ECIES_CONFIG.elliptic_curve='x25519'# or 'ed25519'>>>data='hello world🌍'.encode()
>>>sk=PrivateKey('x25519') # or 'ed25519'>>>decrypt(sk.secret, encrypt(sk.public_key.to_bytes(), data)).decode()
'hello world🌍'Or just use a builtin command eciespy in your favorite command line.
Parameters:
receiver_pk- Receiver's public key (hexstrorbytes)data- Data to encryptconfig- Optional configuration object
Returns: bytes
Parameters:
receiver_sk- Receiver's private key (hexstrorbytes)data- Data to decryptconfig- Optional configuration object
Returns: bytes
$ eciespy -husage: eciespy [-h] [-e] [-d] [-g] [-k KEY] [-c {secp256k1,x25519,ed25519}] [-D [DATA]] [-O [OUT]]Elliptic Curve Integrated Encryption Scheme for secp256k1/curve25519 in Pythonoptions: -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 key pair, for secp256k1, ethereum public key and address will be printed -k, --key KEY public or private key file -c, --curve {secp256k1,x25519,ed25519} elliptic curve, default: secp256k1 -D, --data [DATA] file to encrypt or decrypt, if not specified, it will read from stdin -O, --out [OUT] encrypted or decrypted file, if not specified, it will write to stdout$ eciespy -gPrivate: 0x95d3c5e483e9b1d4f5fc8e79b2deaf51362980de62dbb082a9a4257eef653d7dPublic: 0x98afe4f150642cd05cc9d2fa36458ce0a58567daeaf5fde7333ba9b403011140a4e28911fcf83ab1f457a30b4959efc4b9306f514a4c3711a16a80e3b47eb58bAddress: 0x47e801184B3a8ea8E6A4A7A4CFEfEcC76809Da72$ echo'0x95d3c5e483e9b1d4f5fc8e79b2deaf51362980de62dbb082a9a4257eef653d7d'> sk
$ echo'0x98afe4f150642cd05cc9d2fa36458ce0a58567daeaf5fde7333ba9b403011140a4e28911fcf83ab1f457a30b4959efc4b9306f514a4c3711a16a80e3b47eb58b'> pk
$ echo'hello ecies'| eciespy -e -k pk | eciespy -d -k skhello ecies
$ echo'data to encrypt'> data
$ eciespy -e -k pk -D data -O enc_data
$ eciespy -d -k sk -D enc_datadata to encrypt
$ rm sk pk data enc_dataFollowing configurations are available.
- Elliptic curve: secp256k1 or curve25519 (x25519/ed25519)
- Ephemeral key format in the payload: compressed or uncompressed (only for secp256k1)
- Shared elliptic curve key format in the key derivation: compressed or uncompressed (only for secp256k1)
- Symmetric cipher algorithm: AES-256-GCM or XChaCha20-Poly1305
- Symmetric nonce length: 12 or 16 bytes (only for AES-256-GCM)
For compatibility, make sure different applications share the same configuration.
EllipticCurve=Literal["secp256k1", "x25519", "ed25519"]
SymmetricAlgorithm=Literal["aes-256-gcm", "xchacha20"]
NonceLength=Literal[12, 16] # only for aes-256-gcm, xchacha20 will always be 24@dataclass()classConfig:
elliptic_curve: EllipticCurve="secp256k1"is_ephemeral_key_compressed: bool=Falseis_hkdf_key_compressed: bool=Falsesymmetric_algorithm: SymmetricAlgorithm="aes-256-gcm"symmetric_nonce_length: NonceLength=16@propertydefephemeral_key_size(self):
ifself.elliptic_curve=="secp256k1":
return (
COMPRESSED_PUBLIC_KEY_SIZEifself.is_ephemeral_key_compressedelseUNCOMPRESSED_PUBLIC_KEY_SIZE
)
elifself.elliptic_curvein ("x25519", "ed25519"):
returnCURVE25519_PUBLIC_KEY_SIZEelse:
raiseNotImplementedErrorECIES_CONFIG=Config()On ECIES_CONFIG.elliptic_curve = "x25519" or "ed25519", x25519 (key exchange function on curve25519) or ed25519 (signature algorithm on curve25519) will be used for key exchange instead of secp256k1.
In this case, the payload would always be: 32 Bytes + Ciphered.
If you don't know how to choose between x25519 and ed25519, just use the dedicated key exchange function x25519 for efficiency.
Because any 32-byte data is a valid curve25519 public key, the payload would seem random. This property is excellent for circumventing censorship by adversaries.
On is_ephemeral_key_compressed = True, the payload would be like: 33 Bytes + Ciphered instead of 65 Bytes + Ciphered.
On 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).
On symmetric_algorithm = "xchacha20", plaintext data would be encrypted with XChaCha20-Poly1305.
On 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 with other ecies libraries, start with the default (secp256k1 with AES-256-GCM).
For speed and security, pick x25519 with XChaCha20-Poly1305.
See DETAILS.md.
See CHANGELOG.md.