Skip to main content

Rust extension providing Python bindings to the signal protocol

Project description

signal-protocol

CircleCI PyPI version

Experimental Python bindings to Rust signal protocol implementation libsignal-client. This project provides a Rust extension using PyO3 to define a signal_protocol Python module. See here for a fundamental limitation storing secrets in Python-allocated memory.

⚠️USE AT YOUR OWN RISK!⚠️

Installation

To use the wheel distributions you do not need the Rust toolchain installed. Simply run

pip install signal-protocol

Usage

Initial client setup

The following shows how to use this library to initialize a new Signal client. This is the first step that must be completed before the protocol can begin.

For an overview of the Signal protocol, see this blog post. Detailed specifications are available from Signal.

First, import these modules:

from signal_protocol import curve, identity_key, state, storage

Each client must generate a long-term identity key pair. This should be stored somewhere safe and persistent.

identity_key_pair = identity_key.IdentityKeyPair.generate()

Clients must generate prekeys. The example generates a single prekey. In practice, clients will generate many prekeys, as they are one-time use and consumed when a message from a new chat participant is sent.

pre_key_pair = curve.KeyPair.generate()

Clients must generate a registration_id and store it somewhere safe and persistent.

registration_id = 12  # TODO generate (not yet supported in upstream crate)

The InMemSignalProtocolStore is a single object which provide the four storage interfaces required: IdentityKeyStore (for one's own identity key state and the (public) identity keys for other chat participants), PreKeyStore (for one's own prekey state), SignedPreKeyStore (for one's own signed prekeys), and SessionStore (for established sessions with chat participants).

store = storage.InMemSignalProtocolStore(identity_key_pair, registration_id)

Clients should also generate a signed prekey.

signed_pre_key_pair = curve.KeyPair.generate()
serialized_signed_pre_pub_key = signed_pre_key_pair.public_key().serialize()
signed_pre_key_signature = (
    store.get_identity_key_pair()
    .private_key()
    .calculate_signature(serialized_signed_pre_pub_key)
)

Clients should store their prekeys (both one-time and signed) in the protocol store along with IDs that can be used to retrieve them later.

pre_key_id = 10
pre_key_record = state.PreKeyRecord(pre_key_id, pre_key_pair)
store.save_pre_key(pre_key_id, pre_key_record)

signed_pre_key_id = 33
signed_prekey = state.SignedPreKeyRecord(
            signed_pre_key_id,
            42, # This is a timestamp since this key should be periodically rotated
            signed_pre_key_pair,
            signed_pre_key_signature,
        )
store.save_signed_pre_key(signed_pre_key_id, signed_prekey)

Sending a message to a new participant

With a client initialized, you can create a session and send messages.

To create a session, you must fetch a prekey bundle for the recipient from the server. Here the prekey bundle is recipient_bundle for participant recipient_address.

from signal_protocol import session, session_cipher

session.process_prekey_bundle(
    recipient_address,
    store,
    recipient_bundle,
)

Once the prekey bundle is processed (storing data from the recipient in your local protocol store), you can encrypt messages:

ciphertext = session_cipher.message_encrypt(store, recipient_address, b"hello")

Developer Getting Started

You will need both Rust and Python 3.7+ installed on your system. To install the project in your virtualenv:

pip install -r requirements.txt
python setup.py develop

Then run the tests via pytest -v tests/ to confirm all is working. Tests are ported to Python from the upstream crate. You can use the tests as a reference for how to use the library.

When developing, simply run python setup.py develop as you make changes to rebuild the library. This script will handle compilation on the Rust side.

Building wheels

See instructions here. In brief:

docker pull quay.io/pypa/manylinux2014_x86_64
docker run --rm -v `pwd`:/io quay.io/pypa/manylinux2014_x86_64 /io/build-wheels.sh

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

signal_protocol-0.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

signal_protocol-0.2.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.2 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

signal_protocol-0.2.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.8 MB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ x86-64

signal_protocol-0.2.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.6m manylinux: glibc 2.17+ x86-64

File details

Details for the file signal_protocol-0.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for signal_protocol-0.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e5b38a85a96aad71006c291ceea37ccab205d2c0d3c5ff09afdd0e542d73d08e
MD5 d51b77d24e20026ab4514a0d34320adb
BLAKE2b-256 5816379859158b5fe638f1fe878494ad5e0a545495bb576988f567ea87bec641

See more details on using hashes here.

File details

Details for the file signal_protocol-0.2.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for signal_protocol-0.2.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 182b25441ec91ea36e562dbfe87aa29fadf271bb044b886bf4787ed3092a6041
MD5 18233c78a5b9d50a44580b015a2bf581
BLAKE2b-256 5ae33264113d0bec543eefd86d0b4be21cccbc78d772eddec26c51a09c47466f

See more details on using hashes here.

File details

Details for the file signal_protocol-0.2.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for signal_protocol-0.2.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 92b705197f89e90a2e874eebe2ead30563a36e2df682a0dc07a17cb596e1be55
MD5 dc687c870fe35f9545bdeffb930d0411
BLAKE2b-256 b5d651c2ea57bf12df3fd4179eaf69a8f8fa6619cb7784cab7a24aa07d8e5f98

See more details on using hashes here.

File details

Details for the file signal_protocol-0.2.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for signal_protocol-0.2.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9620866d7db4fb130e304fc82163bf6cc6044f9cde92cfc6e4d157525e809413
MD5 45cf4ab99ab7252123d08434c02190d7
BLAKE2b-256 3f4fbc70ccdb50a84290e5fdf03a03e082ae4d51e0aa65b1ade301d2dd7cf512

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page