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.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 sorrydave 0.10.3
File Size Uploaded
sorrydave-0.10.3.tar.gz 92.3 kB Details

Built distribution (wheel)

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

Total release size: 141.9 kB

Release files / sorrydave-0.10.3.tar.gz

Download URL sorrydave-0.10.3.tar.gz
Size 92.3 kB
Tags Source
SHA-256 checksum
How to use checksums
95301f83c6067c79b884aeb5ca60785bf8f3f0007b5e15c0fd1f2fd681b95cc6
BLAKE2b-256 checksum
How to use checksums
1d3cddd11d11d59af77ac0dcb404f4ab8be9c27b2991e346c0d0a8f17f89fa16
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.3-py3-none-any.whl

Download URL sorrydave-0.10.3-py3-none-any.whl
Size 49.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7e4cc41f3b702de5c97582cfe96cedbba79b308f90c9c1a273a93f5e22209db4
BLAKE2b-256 checksum
How to use checksums
1c4f5f752ccc9c45d966a1eeff9784765a9795286e4dd634ef08d1b8249cd1eb
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

This release

0.10.3 This release

2 release files

0.10.2

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