rine's MLS group core (RFC 9420) with the X-Wing post-quantum ciphersuite
Project description
rine-mls
rine's MLS group core (RFC 9420) for Python, with the X-Wing post-quantum
ciphersuite. One Rust implementation, compiled per platform; this package is the
Python half of it, and @rine-network/mls on npm is the JavaScript half of the
same code.
pip install rine-mls
One abi3 wheel per platform covers every CPython from 3.9 up, so no compiler is needed at install time. Linux (x64/arm64, glibc and musl) and macOS (x64/arm64) ship today; Windows does not, and there is no browser build.
Of those six wheels, Linux x64 (glibc) on CPython 3.12 is what the test suite runs. The other five are cross-built and not executed.
Using it
from rine_mls import MlsClient, CIPHER_SUITE_DEFAULT
alice = MlsClient("/path/to/keys/alice/mls2", signing_seed, CIPHER_SUITE_DEFAULT)
group = alice.create_group_with_members(group_id, [bob_key_package])
init = group.last_commit() # the commit, one Welcome per member, a GroupInfo
payload = group.encrypt_application_message(envelope)
CIPHER_SUITE_DEFAULT is the post-quantum suite. It is read from the core rather
than chosen here, so every rine surface creates groups of the same suite.
This package speaks bytes. Base64url, HTTP and the signed rine envelope
belong to the transport above it; MLS, the ciphersuites, the local state store
and the 0x04 mls-v1 version tag belong to the core below it. The wheel ships
type stubs and a py.typed marker, so the full API is visible to mypy.
Errors
Every failure raises its own class under RineMlsError, and every class carries
the same code string the JavaScript binding puts on Error.code:
| exception | code |
means |
|---|---|---|
MlsProtocolError |
RINE_MLS_PROTOCOL |
RFC 9420 processing failed |
MlsStoreError |
RINE_MLS_STORE |
the local state store could not be read or written |
EpochConflictError |
RINE_MLS_EPOCH_CONFLICT |
a commit that was not this group's current + 1 |
UnreadableKeyPackageError |
RINE_MLS_UNREADABLE_KEY_PACKAGE |
a KeyPackage this core cannot read — that agent must republish its pool |
CipherSuiteMismatchError |
RINE_MLS_CIPHER_SUITE_MISMATCH |
a blob minted for another ciphersuite |
GroupInactiveError |
RINE_MLS_GROUP_INACTIVE |
this member was removed from the group |
SelfMessageNotCachedError |
RINE_MLS_SELF_MESSAGE_NOT_CACHED |
a message this member sent, aged out of the self-read cache |
KeyPackageBatchTooLargeError |
RINE_MLS_KEY_PACKAGE_BATCH_TOO_LARGE |
more KeyPackages than one publish may carry |
MlsPanicError / MlsPoisonedError |
RINE_MLS_PANIC / RINE_MLS_POISONED |
an internal panic was caught; the handle is retired |
except RineMlsError catches all of them, and the instance always has .code.
The stubs list the rest.
Two things to get right
One client per store root. A store root is one agent's MLS state, and group state is a ratchet. Two clients loaded from the same group directory both commit at the same epoch to different things; the fork is silent locally until a message will not decrypt. Give each thread or process its own agent, or serialize on one client. Sharing a single handle between threads is fine — every call holds the GIL.
Nothing persists until save(). Post the commit, let the server's epoch CAS
rule on it, and only then persist — so a rejected commit leaves no forked state
behind.
Key packages, and the one-way door
A key package minted by rine's previous MLS engine is unreadable here, and so is
one minted here to anything older: the two do not interoperate, and a group whose
members straddle them does not work at all. UnreadableKeyPackageError names that
condition. The remedy is always the same — that agent calls
drain_and_republish_key_packages() and the group is recreated. Walking to the
next key package in the peer's pool cannot help and only empties it.
Epoch retention
By default every past epoch secret is kept, so a member returning after any number of commits still decrypts the backlog queued for it. Epochs advance on membership changes, not on messages, so this stays small.
MlsClient(root, seed, suite, epoch_retention_limit=8)
That keeps the eight most recent epochs and deletes the rest, narrowing the window in which old secrets exist on disk. Anything still undelivered from a dropped epoch becomes permanently unreadable to that member.
Building from source
bash tests/run.sh # builds both wheels, runs the suite, then uses the shipped wheel
The version is owned by the Rust workspace (rine-mls/Cargo.toml); maturin reads
it from there.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rine_mls-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: rine_mls-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.9+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
98eeffe6cf0c684f353606fb9f82eebabce4249b9f5526b6267350c1054c4d1b
|
|
| MD5 |
a55f7a305221015677e2dea1f40832a6
|
|
| BLAKE2b-256 |
3d94a16a8557eefd91e44db30247a0894560dfb312899c0778e65bd1d01826f6
|
File details
Details for the file rine_mls-0.1.0-cp39-abi3-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: rine_mls-0.1.0-cp39-abi3-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 972.2 kB
- Tags: CPython 3.9+, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec584ef6b012bf35ec4ded4a81a906236e4c272ddff9debbf3195d93f2db99b9
|
|
| MD5 |
24cd46f118afe682cb89e4d806cbfe8e
|
|
| BLAKE2b-256 |
0d165586ee2e52cd6d0b932ef65b2ab1f932f48d10c4ac481148f390c2f44ec7
|
File details
Details for the file rine_mls-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: rine_mls-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
de586ae9801650c49135296158d615730e6ea6a8fbadf424da784d3e59adeaf4
|
|
| MD5 |
ff0ea5db962c0948232b5728c8e54cfc
|
|
| BLAKE2b-256 |
a31c86c37680f2ed0436d115468d680b10b2ba1009d65d5536123cdbe9c93372
|
File details
Details for the file rine_mls-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: rine_mls-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 975.0 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e5e89f784de218d66c16868a5030c27d7187cf5d2d20d3ede1e322435fce913
|
|
| MD5 |
a25196f8b6528fff86f232467e0c41e1
|
|
| BLAKE2b-256 |
6fbda5b1ece2a517f722500a8344153bcd2309c2b3e38cac009d81731eda6941
|
File details
Details for the file rine_mls-0.1.0-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: rine_mls-0.1.0-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.9 MB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e5225d84aa745b41eac5f8b2fe8c916c664e56dec064a5c5965e617b21cc401
|
|
| MD5 |
3a48d54290085157dd519299236da2fd
|
|
| BLAKE2b-256 |
fb37e168a846ecc100532cad41c0c5281b1478a9bf0f660ed3a9de82c9291cf0
|
File details
Details for the file rine_mls-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: rine_mls-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.0 MB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f45f53ea3746555494c9d15b681629ca55ad1eabbcaf5673897d516a4c78860d
|
|
| MD5 |
5202b303fd0f0b0565a9113ec6cf6c0b
|
|
| BLAKE2b-256 |
ad49be9a3813ca5dd935f64e4140112378c8cfed292612e06e60f6edb2978450
|