improve event format description of m.room.encrypted events (#2413)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
Spec / Create release (push) Has been cancelled

Signed-off-by: Johanna Stuber <johannas@element.io>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
gewitternacht 2026-07-21 22:42:20 +02:00 committed by GitHub
parent 3265c38d59
commit d0ba2aaef8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 22 additions and 16 deletions

View file

@ -0,0 +1 @@
Improve the format description of `m.room.encrypted` (Olm/Megolm) events.

View file

@ -1723,28 +1723,30 @@ Devices that support Olm must include "m.olm.v1.curve25519-aes-sha2" in
their list of supported messaging algorithms, must list a Curve25519 their list of supported messaging algorithms, must list a Curve25519
device key, and must publish Curve25519 one-time keys. device key, and must publish Curve25519 one-time keys.
An event encrypted using Olm has the following format: The content of an [`m.room.encrypted`](#mroomencrypted) event using Olm has the following format:
```json ```json
{ {
"type": "m.room.encrypted",
"content": { "content": {
"algorithm": "m.olm.v1.curve25519-aes-sha2", "algorithm": "m.olm.v1.curve25519-aes-sha2",
"sender_key": "<sender_curve25519_key>", "sender_key": "<sender_curve25519_key>",
"ciphertext": { "ciphertext": {
"<device_curve25519_key>": { "<device_curve25519_key>": {
"type": 0, "type": 0,
"body": "<encrypted_payload_base_64>" "body": "<base64_encoded_olm_message>"
} }
} }
} }
} }
``` ```
Note that when the event is received from the server, it will have a `type`
`ciphertext` is a mapping from device Curve25519 key to an encrypted (with a value of `m.room.encrypted`) and `sender` property alongside the
payload for that device. `body` is a Base64-encoded [Olm message body](/olm-megolm/olm/#the-olm-message-format). `content` property. In `content`, `ciphertext` is a mapping from a device
`type` is an integer indicating the type of the message body: 0 for the Curve25519 key to an object with a `type` and a `body`. Here, `body` is a
initial [pre-key message](/olm-megolm/olm/#pre-key-messages), 1 for [normal messages](/olm-megolm/olm/#normal-messages). Base64-encoded [Olm message](/olm-megolm/olm/#the-olm-message-format), and
`type` is an integer indicating the type of the message:
0 for the initial [pre-key messages](/olm-megolm/olm/#pre-key-messages),
1 for [normal messages](/olm-megolm/olm/#normal-messages).
Olm sessions will generate messages with a type of 0 until they receive Olm sessions will generate messages with a type of 0 until they receive
a message. Once a session has decrypted a message it will produce a message. Once a session has decrypted a message it will produce
@ -1893,23 +1895,26 @@ This uses:
Devices that support Megolm must support Olm, and include Devices that support Megolm must support Olm, and include
"m.megolm.v1.aes-sha2" in their list of supported messaging algorithms. "m.megolm.v1.aes-sha2" in their list of supported messaging algorithms.
An event encrypted using Megolm has the following format: The content of an [`m.room.encrypted`](#mroomencrypted) event using Megolm has the following format:
```json ```json
{ {
"type": "m.room.encrypted",
"content": { "content": {
"algorithm": "m.megolm.v1.aes-sha2", "algorithm": "m.megolm.v1.aes-sha2",
"sender_key": "<sender_curve25519_key>", "sender_key": "<sender_curve25519_key>",
"device_id": "<sender_device_id>", "device_id": "<sender_device_id>",
"session_id": "<outbound_group_session_id>", "session_id": "<outbound_group_session_id>",
"ciphertext": "<encrypted_payload_base_64>" "ciphertext": "<base64_encoded_megolm_message>"
} }
} }
``` ```
Note that when the event is received from the server, it will have additional
properties alongside the `content` property, including a `type` (with a value
of `m.room.encrypted`) and a `sender` property. (See [Room event format](#room-event-format).)
The encrypted payload can contain any message event. The plaintext is of Within `content`, `ciphertext`
the form: is a Base64-encoded [Megolm message](/olm-megolm/megolm/#message-format),
whose plaintext body is of the form:
```json ```json
{ {
@ -1919,7 +1924,7 @@ the form:
} }
``` ```
We include the room ID in the payload, because otherwise the homeserver We include the room ID in the encrypted message, because otherwise the homeserver
would be able to change the room a message was sent in. would be able to change the room a message was sent in.
Clients must guard against replay attacks by keeping track of the Clients must guard against replay attacks by keeping track of the

View file

@ -91,13 +91,13 @@ For example, a replacement for an encrypted event might look like this:
"sender_key": "<sender_curve25519_key>", "sender_key": "<sender_curve25519_key>",
"device_id": "<sender_device_id>", "device_id": "<sender_device_id>",
"session_id": "<outbound_group_session_id>", "session_id": "<outbound_group_session_id>",
"ciphertext": "<encrypted_payload_base_64>" "ciphertext": "<base64_encoded_megolm_message>"
} }
// irrelevant fields not shown // irrelevant fields not shown
} }
``` ```
... and, once decrypted, the payload might look like this: ... and the plaintext body of the Megolm message might look like this:
```json ```json
{ {