Skip to main content

sslcrypto

Actions Status Code Quality Code Coverage PyPI

sslcrypto is a fast and simple library for AES, ECIES and ECDSA for Python.

License: MIT + BSD-2 for ripemd implementation (see _ripemd.py).

Why?

sslcrypto can use OpenSSL in case it's available in your system for speedup, but pure-Python code is also available and is heavily optimized.

N.B. There are alternatives like coincurve which are faster in some cases (e.g. when using secp256k1). They don't include ECIES implementation and some useful ECDSA features and are specialized on a single curve. If that's enough for you and libsecp256k1 bindings are available for all OSes you need to support, use those libraries. Coincurve, in particular, ships pre-compiled packages for all major OSes and building from source does not require an existing libsecp256k1 installation.

N.B. While there are other mature cryptography libraries, they are too heavy for simple stuff and require OpenSSL that is not available by default on Windows (most likely many other OSes as well). That said, in case you're processing big data, not much data, the speed advantage you get from libraries is too small to use heavy alternatives.

Installation

pip install sslcrypto

Additionally, you can download this repository and run python setup.py install.

Usage

AES

import sslcrypto

# Generate random key
key = sslcrypto.aes.new_key()

# Encrypt something
data = b"Hello, world!"
ciphertext, iv = sslcrypto.aes.encrypt(data, key)

# Decrypt
assert sslcrypto.aes.decrypt(ciphertext, iv, key) == data

By default, aes-256-cbc cipher is used. You can specify another one if you want. The following ciphers are supported:

  • aes-128-cbc, aes-192-cbc, aes-256-cbc
  • aes-128-ctr, aes-192-ctr, aes-256-ctr
  • aes-128-cfb, aes-192-cfb, aes-256-cfb
  • aes-128-ofb, aes-192-ofb, aes-256-ofb
import sslcrypto

# Generate random key
key = sslcrypto.aes.new_key(algo="aes-192-cfb")

# Encrypt something
data = b"Hello, world!"
ciphertext, iv = sslcrypto.aes.encrypt(data, key, algo="aes-192-cfb")

# Decrypt
assert sslcrypto.aes.decrypt(ciphertext, iv, key, algo="aes-192-cfb") == data

ECIES

The following curves are supported:

  • secp112r1, secp112r2
  • secp128r1, secp128r2
  • secp160k1, secp160r1, secp160r2
  • secp192k1, prime192v1
  • secp224k1, secp224r1
  • secp256k1, prime256v1
  • secp384r1
  • secp521r1

Please tell me if you want to add any other curves.

import sslcrypto

# Create curve object
curve = sslcrypto.ecc.get_curve("secp256k1")

# Generate private key, both compressed and uncompressed keys are supported
private_key = curve.new_private_key(is_compressed=True)

# Find a matching public key
public_key = curve.private_to_public(private_key)

# If required, you can change public key format to whatever you want
x, y = curve.decode_public_key(public_key)
electrum_public_key = x + y

# Encrypt something. You can specify a cipher if you want to, aes-256-cbc is the
# default value
data = b"Hello, world!"
ciphertext = curve.encrypt(data, public_key, algo="aes-256-ofb")

# Decrypt
assert curve.decrypt(ciphertext, private_key, algo="aes-256-ofb") == data

ECDSA

import sslcrypto

# Create curve object
curve = sslcrypto.ecc.get_curve("secp256k1")

# Generate private key
private_key = curve.new_private_key()

# Find a matching public key
public_key = curve.private_to_public(private_key)

# Sign something
data = b"Hello, world!"
signature = curve.sign(data, private_key)

# Verify
assert curve.verify(signature, data, public_key) == True  # Would raise on error

Additionally, you can create recoverable signatures:

import sslcrypto

# Create curve object
curve = sslcrypto.ecc.get_curve("secp256k1")

# Generate private key
private_key = curve.new_private_key()

# Find a matching public key
public_key = curve.private_to_public(private_key)

# Sign something
data = b"Hello, world!"
signature = curve.sign(data, private_key, recoverable=True)

# Recover public key
assert curve.recover(signature, data) == public_key  # Would raise on error
import sslcrypto
curve = sslcrypto.ecc.get_curve("secp256k1")
private_key = curve.new_private_key()
public_key = curve.private_to_public(private_key)

wif = curve.private_to_wif(private_key)  # Transform to mainnet private key
assert curve.wif_to_private(wif) == private_key

address = curve.private_to_address(private_key)
assert address == curve.public_to_address(public_key)

# Based on BIP32. Hardened indexes aren't supported yet
curve.child_derive(private_key, 123)

Misc

import sslcrypto
print(sslcrypto.ecc.get_backend())  # Either "fallback" or OpenSSL info

You can override OpenSSL path discovery:

from sslcrypto.openssl import discovery
discovery.discover = lambda: ["openssl_lib.dll"]

If you want to go low-level, you can get curve parameters:

import sslcrypto
curve = sslcrypto.ecc.get_curve("secp256k1")
assert curve.params["n"] == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141

Running tests

sslcrypto uses pytest framework. Install it with pip and run python3 -m pytest test in sslcrypto repository.

Release files for sslcrypto 5.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sslcrypto 5.3
File Size Uploaded
sslcrypto-5.3.tar.gz 28.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sslcrypto 5.3
File Interpreter ABI Platform
sslcrypto-5.3-py3-none-any.whl Python 3 none any Details

Total release size:62.4 kB

Release files / sslcrypto-5.3.tar.gz

Download URL sslcrypto-5.3.tar.gz
Size 28.1 kB
Tags Source
SHA-256 checksum
How to use checksums
835abad516cf1af79e651f233f00c5132107e515804c8cc298d68785ea733d58
BLAKE2b-256 checksum
How to use checksums
6a956950f753a5da5a6a3978d296c58f41e872169db26b1b7909fe8f83d32789
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.1.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.5

Release files / sslcrypto-5.3-py3-none-any.whl

Download URL sslcrypto-5.3-py3-none-any.whl
Size 34.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c26787052d361d89fb5f6362624e068f86692c41218624d601939b8a42a19f05
BLAKE2b-256 checksum
How to use checksums
1a16eceaf52870133a95e20948bf37fada551d7b1f555b96362d63bb826796bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.1.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.5

Release history Release notifications | RSS feed

This release

5.3 This release

2 release files

5.2

2 release files

5.1

2 release files

5.0

2 release files

4.0

2 release files

3.3

2 release files

3.2

2 release files

3.1

2 release files

3.0

1 release file

2.5

1 release file

2.4

1 release file

2.3

1 release file

2.2

1 release file

2.1

1 release file

2.0

1 release file

1.16

1 release file

1.15

1 release file

1.14

1 release file

1.13

1 release file

1.12

1 release file

1.11

1 release file

1.10

1 release file

1.9

1 release file

1.8

1 release file

1.7

1 release file

1.6

1 release file

1.5

1 release file

1.4

1 release file

1.3

1 release file

1.2

1 release file

1.1

1 release file

1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page