pydave
Production-quality Python library for the DAVE (Discord Audio/Video End-to-End Encryption) protocol. It implements the protocol as a pure data-transformation and state-management layer on top of rfc9420 (PyMLS), with no I/O or networking: you pass in bytes (Voice Gateway opcodes, encoded media frames) and get back bytes (opcode payloads, encrypted/decrypted frames).
Features
- MLS integration: Key packages, external sender handling, proposals, commit/welcome (opcodes 25–30), exporter-based sender keys
- Sender key ratchet: Per-sender, per-epoch keys via MLS-Exporter + HKDF; cache for out-of-order decryption
- Frame transform: Codec-aware encrypt/decrypt (OPUS, VP9, VP8 P-bit), ULEB128, truncated AES128-GCM, DAVE footer (
0xFAFA) - Identity: Pairwise fingerprint (scrypt) and displayable codes (45-digit / 30-digit)
Install
pip install -e .
Requires Python 3.10+, rfc9420, cryptography, and pycryptodome.
Minimal lifecycle
- Create a session:
DaveSession(local_user_id=123456789). - On select_protocol_ack (or prepare_epoch with
epoch=1), callsession.prepare_epoch(1)and send the returned bytes as opcode 26 (Key Package). - On opcode 25 (External Sender Package), call
session.handle_external_sender_package(package_bytes). - On opcode 27 (Proposals), call
session.handle_proposals(proposal_bytes); if it returns bytes, send them as opcode 28. - On opcode 29 (Announce Commit), call
session.handle_commit(transition_id, commit_bytes). - On opcode 30 (Welcome), call
session.handle_welcome(transition_id, welcome_bytes). - On opcode 22 (Execute Transition), call
session.execute_transition(transition_id). - Use
session.get_encryptor().encrypt(frame, codec="OPUS")andsession.get_decryptor(sender_id).decrypt(protocol_frame)for media.
API overview
DaveSession:handle_external_sender_package,prepare_epoch,handle_proposals,handle_commit,handle_welcome,execute_transition,get_encryptor,get_decryptorFrameEncryptor.encrypt(encoded_frame, codec)/FrameDecryptor.decrypt(protocol_frame)generate_fingerprint(local_id, local_pub, remote_id, remote_pub)→ 45-digit stringdisplayable_code(data, total_digits, group_size)for epoch authenticator (e.g. 30 digits, group 5)
Scope
- In scope: MLS state, ratchet, OPUS/VP9/VP8 codec handling, frame encrypt/decrypt, identity fingerprint.
- Out of scope: Voice Gateway WebSocket I/O, SFU silence packets, WebRTC depacketizer patches. H264/H265 and AV1 are deferred.
License
MIT.
Release files for pydave 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pydave-0.1.1.tar.gz | 22.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pydave-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 43.9 kB
Release files / pydave-0.1.1.tar.gz
| Download URL | pydave-0.1.1.tar.gz |
|---|---|
| Size | 22.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
15f4b654a71e50061db6f6c38e9148fa209fdd4338da24b9ccbf47205c352cf5
|
|
BLAKE2b-256 checksum How to use checksums |
1e01a3b2f7f6588cf9527600ac4bd8484252b19ff195da6cfcd953647b51399e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.7
|
Release files / pydave-0.1.1-py3-none-any.whl
| Download URL | pydave-0.1.1-py3-none-any.whl |
|---|---|
| Size | 21.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
37c06f7c298989e966242759d09a41e6c567b60c091104bc9c3c13701f41e137
|
|
BLAKE2b-256 checksum How to use checksums |
14f8fd88c35d599544a84a0993496609306854edf25e343d3b7f0f04b05f919b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.7
|