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.0

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.0
File Size Uploaded
sorrydave-0.10.0.tar.gz 84.9 kB Details

Built distribution (wheel)

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

Total release size: 131.4 kB

Release files / sorrydave-0.10.0.tar.gz

Download URL sorrydave-0.10.0.tar.gz
Size 84.9 kB
Tags Source
SHA-256 checksum
How to use checksums
e0b36b67b88f1201785ce04fb67a7721d12e20a42e0b5c7abcd17e5911d925db
BLAKE2b-256 checksum
How to use checksums
e57662b524e144815fee935a16dd3b6e86d5dab8bc1e6548babacc7cad4b3544
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.0-py3-none-any.whl

Download URL sorrydave-0.10.0-py3-none-any.whl
Size 46.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
14d80dcb98f6733a7c44a7dc48e75c2f1db82bd8ca4cceb80ce58c4aca7b7ad4
BLAKE2b-256 checksum
How to use checksums
57d1a1b6f98f9d09e4b791f61da1102acc057aaeb37707f9a39d1ee7519f5584
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

0.10.2

2 release files

0.10.1

2 release files

This release

0.10.0 This release

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