1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//! MDK constants
use Kind;
use ExtensionType;
use ProposalType;
use Ciphersuite;
/// Nostr event kind for MLS KeyPackage events (addressable, NIP-33).
///
/// Per MIP-00, KeyPackages use kind 30443 (addressable event) so relays automatically
/// replace old versions when a new event with the same `(kind, pubkey, d)` tuple is published.
/// This enables rotation without explicit deletion.
pub const MLS_KEY_PACKAGE_KIND: Kind = Custom;
/// Legacy Nostr event kind for MLS KeyPackage events (regular, non-replaceable).
///
/// Earlier versions of the Marmot spec used kind 443. Clients SHOULD accept this kind
/// during the migration period (through May 31, 2026) but MUST publish using kind 30443.
pub const MLS_KEY_PACKAGE_KIND_LEGACY: Kind = Custom;
/// Nostr Group Data extension type
pub const NOSTR_GROUP_DATA_EXTENSION_TYPE: u16 = 0xF2EE; // Be FREE
/// Default ciphersuite for Nostr Groups.
/// This is also the only required ciphersuite for Nostr Groups.
pub const DEFAULT_CIPHERSUITE: Ciphersuite =
MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519;
/// Extensions that clients advertise support for in their KeyPackage capabilities.
///
/// Per RFC 9420 Section 7.2, this should only include non-default extensions that
/// the client supports. Default extensions (RequiredCapabilities, RatchetTree,
/// ApplicationId, ExternalPub, ExternalSenders) are assumed to be supported by all
/// clients and should NOT be listed here.
///
/// Note: LastResort (0x000a) is included here because OpenMLS requires KeyPackage-level
/// extensions to be declared in capabilities for validation, even though per the MLS
/// Extensions draft it's technically just a KeyPackage marker.
pub const SUPPORTED_EXTENSIONS: = ;
/// Extensions that are required in the GroupContext RequiredCapabilities extension.
///
/// This enforces that all group members must support these extensions. For Marmot,
/// we require the NostrGroupData extension (0xF2EE) to ensure all members can
/// process the Nostr-specific group metadata.
pub const GROUP_CONTEXT_REQUIRED_EXTENSIONS: = ;
/// Extensions advertised in Nostr event tags (mls_extensions tag).
///
/// Derived from SUPPORTED_EXTENSIONS to guarantee the tags accurately advertise
/// what the KeyPackage capabilities contain. GREASE values are excluded — they
/// are injected dynamically at runtime (see `MDK::capabilities()`).
pub const TAG_EXTENSIONS: = SUPPORTED_EXTENSIONS;
/// Non-default proposal types that clients advertise support for.
///
/// Per the MLS Extensions draft, SelfRemove (0x000a) is not a default
/// proposal type and MUST be explicitly listed in capabilities.
///
/// Note: SelfRemove (0x000a) and LastResort (0x000a) share the same numeric
/// value but belong to different IANA registries (Proposal Types vs Extension
/// Types), so there is no conflict.
pub const SUPPORTED_PROPOSALS: = ;
/// Proposal types advertised in Nostr event tags (mls_proposals tag).
/// Derived from SUPPORTED_PROPOSALS to guarantee consistency.
pub const TAG_PROPOSALS: = SUPPORTED_PROPOSALS;