Skip to main content

sorrydave

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, H264, H265, AV1), 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.9+, rfc9420, cryptography, and pycryptodome.

Minimal lifecycle

  1. Create a session: DaveSession(local_user_id=123456789, channel_id=voice_channel_id). The MLS group ID is the channel snowflake as 8 big-endian bytes; Discord will silently drop commits that use any other group ID.
  2. On select_protocol_ack (or prepare_epoch with epoch=1), call session.prepare_epoch(1) and send the returned bytes as opcode 26 (Key Package).
  3. On opcode 25 (External Sender Package), call session.handle_external_sender_package(package_bytes).
  4. On opcode 27 (Proposals), call session.handle_proposals(proposal_bytes); if it returns bytes, send them as opcode 28.
  5. On opcode 29 (Announce Commit), call session.handle_commit(transition_id, commit_bytes).
  6. On opcode 30 (Welcome), call session.handle_welcome(transition_id, welcome_bytes).
  7. On opcode 22 (Execute Transition), parse with parse_execute_transition(payload) to get transition_id, then call session.execute_transition(transition_id).
  8. Use session.get_encryptor().encrypt(frame, codec="OPUS") and session.get_decryptor(sender_id).decrypt(protocol_frame) for media.

Error recovery: On InvalidCommitError, send build_invalid_commit_welcome(transition_id) as opcode 31 to the voice gateway, then call session.prepare_epoch(1) and send the returned key package as opcode 26.

API overview

  • DaveSession: handle_external_sender_package, prepare_epoch, handle_proposals, handle_commit, handle_welcome, execute_transition, leave_group, get_encryptor, get_decryptor
  • FrameEncryptor.encrypt(encoded_frame, codec) / FrameDecryptor.decrypt(protocol_frame)
  • generate_fingerprint(local_id, local_pub, remote_id, remote_pub) → 45-digit string
  • displayable_code(data, total_digits, group_size) for epoch authenticator (e.g. 30 digits, group 5)

Scope

  • In scope: MLS state, ratchet, OPUS/VP9/VP8/H264/H265/AV1 codec handling, frame encrypt/decrypt, identity fingerprint, opcode 22 parse and opcode 31 build for transition and error recovery.
  • Out of scope: Voice Gateway WebSocket I/O, SFU silence packets, WebRTC depacketizer patches.

License

MIT.

Release files for sorrydave 0.10.2

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

Source distribution (sdist)

Source distribution for sorrydave 0.10.2
File Size Uploaded
sorrydave-0.10.2.tar.gz 87.7 kB Details

Built distribution (wheel)

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

Total release size: 137.0 kB

Release files / sorrydave-0.10.2.tar.gz

Download URL sorrydave-0.10.2.tar.gz
Size 87.7 kB
Tags Source
SHA-256 checksum
How to use checksums
d8da49c6248a3ea7c88933eff66208af9f33811552fd4c210a1a0d401659d001
BLAKE2b-256 checksum
How to use checksums
7ca25cb5a60f5f3a1d4aa4eaba28f415f4b8352681cbe391f1f67467763057b3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.5

Release files / sorrydave-0.10.2-py3-none-any.whl

Download URL sorrydave-0.10.2-py3-none-any.whl
Size 49.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c4de88ea7b376ee77f6bf298e19bb4c4dc4f1b3adcce1af36a457b39447ab28f
BLAKE2b-256 checksum
How to use checksums
958a3760b4ac8155e75d1d5e1315e57c67a8c80c7cecc86d2ea4d729b5fdab9d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.5

Release history Release notifications | RSS feed

0.10.7

2 release files

0.10.3

2 release files

This release

0.10.2 This release

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

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