diff --git a/inbox/xep-ppqm-encryption.xml b/inbox/xep-ppqm-encryption.xml
new file mode 100644
index 000000000..3ee48fd47
--- /dev/null
+++ b/inbox/xep-ppqm-encryption.xml
@@ -0,0 +1,879 @@
+
+
+
+
+
+
+
+ Post-Quantum Extended Diffie-Hellman (PQXDH) PQXDH: THe PQXDH Key Agreement Protocol <https://signal.org/docs/specifications/pqxdh/>.">
+ ML-KEM (FIPS 203) ML-KEM: Module-Lattice-Based Key Encapsulation Mechanism <https://csrc.nist.gov/pubs/fips/203/final>.">
+ AES (FIPS 197) AES: Advanced Encryption Standard <https://csrc.nist.gov/pubs/fips/197/final>.">
+ Shor's Algorithm Algorithms for quantum computation: discrete logarithms and factoring <https://doi.org/10.1109/sfcs.1994.365700>.">
+ %ents;
+ ]>
+
+
+
+ PPQM Encryption
+
+ This specification defines a protocol for post-quantum secure end-to-end encryption in one-to-one chats, as well as
+ group chats where each participant may have multiple clients per account.
+
+ &LEGALNOTICE;
+ XXXX
+ ProtoXEP
+ Standards Track
+ Standards
+ Council
+
+ XMPP Core
+ XEP-0060
+ XEP-0163
+ XEP-0420
+
+
+
+ PPQM
+
+ Jamieson
+ O'Reilly
+ jamieson@privt.com
+
+
+ Ron Lauren
+ Hombre
+ ronlauren@privt.com
+
+
+ Hiren
+ Vavadiya
+ hiren@privt.com
+
+
+ 0.1.0
+ 2024-08-27
+ jor
+
+
+ Initial version based on &xep0384; with updates for post-quantum security using Module-Lattice-Based Key
+ Encapsulation Mechanism (ML-KEM).
+
+
+
+
+
+
+
+
+ The advancement of quantum computing poses a significant threat to classical encryption schemes currently in use.
+ While protocols like &xep0364; messaging and &xep0027; have provided encryption in the past, they are not
+ equipped to withstand the power of quantum computers. The quantum algorithm &shor; can efficiently
+ break the classical encryption algorithms in use today which necessitates a transition to post-quantum
+ cryptographic algorithms.
+
+
+ PPQM Encryption (Privt. Post-Quantum Multi-End Message and Object Encryption) is
+ designed to address these emerging threats by incorporating the post-quantum secure algorithm
+ &mlkem;(historically CRYSTALS-Kyber v3.02) to ensure that communication remains secure and private even
+ in the face of inevitable future quantum computing advancements.
+
+
+
+
+ PPQM builds upon the strengths of Signal's &pqxdh; and the openness of XMPP's
+ &xep0384;(based upon &x3dh;). Specifically, PPQM utilizes ML-KEM to generate shared secret keys that will
+ remain secure under an active quantum adversarial threat. It is then fed into the X3DH Protocol as another layer
+ of security. It is correct to say that this is a hybrid as the classical &xeddsa; is used alongside the
+ post-quantum ML-KEM.
+
+
+ Like OMEMO, PPQM supports multi-end message and object encryption, allowing secure message synchronization across
+ multiple devices. An ephemeral key is used to encrypt each message, and headers containing the necessary
+ parts of the ephemeral keys are individually encrypted for each recipient device. These headers and the encrypted
+ payload are transmitted in a <message> stanza.
+
+
+ PPQM maintains compatibility with existing XMPP standards by using &xep0060; and &xep0163; to manage and
+ distribute key material securely.
+
+
+
+
+
+
+ As a result of XMPP's federated nature, messages may pass through multiple servers. It is crucial to secure
+ communications from any intermediate hosts, especially in a post-quantum world. PPQM aims to provide robust
+ end-to-end encryption that remains secure even against quantum-capable adversaries.
+
+ PPQM provides the following guarantees under the threat model described in the next section:
+
+
+
+ Confidentiality: Only the sender and receiver can read the content of a message, secured by post-quantum
+ ML-KEM which is believed to be resistant against quantum computers.
+
+
+ Forward Secrecy: Compromised key material does not compromise previous message exchanges, ensured by the X3DH
+ algorithm.
+
+
+ Break-in Recovery: A session compromised due to key material leakage will recover after a few communication
+ rounds as a property of X3DH.
+
+
+ Authentication: Each peer can authenticate the sender or receiver of a message, leveraging Ed25519 for signatures.
+
+
+ Integrity: Each peer can ensure that a message has not been altered by any intermediate node due to the
+ AES-256-GCM symmetric encryption applied to the <message> stanza.
+
+
+ Deniability: PPQM aims to provide deniability in a similar fashion to &xep0384;, though post-quantum deniability
+ is an area of active research.
+
+
+ Asynchronicity: The protocol does not rely on the online status of any participant, ensuring usability in
+ asynchronous messaging scenarios.`
+
+
+
PPQM is not intended to protect against the following scenarios:
+
+
+ An attacker with permanent access to your device. In this case, the attacker could extract decrypted messages from
+ the device.
+
+
+ Loss of a device where an attacker can read messages on the notification screen.
+
+
+ Denial-of-service attacks of any kind.
+
+
+
+ Trust management remains a challenging topic, and is considered out of scope for this document.
+
+
+
+ The use case for PPQM is to protect the content of conversations against quantum-capable adversaries, including
+ scenarios where servers cannot be trusted to maintain the confidentiality of the message content. This includes
+ scenarios such as sharing sensitive corporate information or exchanging intimate messages that must remain
+ confidential even from the server administrators.
+
+
+ PPQM protects against passive and active attackers who can read, modify, replay, delay, and delete messages.
+ However, PPQM does not protect against attacks based on metadata or traffic analysis.
+
+
+
+
+
+
+
+
AES-256-GCM
+
+ A Galois/Counter Mode variant of the Advanced Encryption Standard with key size of 256 bits.
+
+
+
+
HMAC-SHA-256
+
+ Hash-based Message Authentication Code using SHA2-256 as the hashing function.
+
+
+
+
HKDF-SHA-256
+
+ An HMAC-based Key Derivation Function using SHA2-256 as the hashing function.
+
+
+
+
ML-KEM
+
+ Module-Lattice-Based Key Encapsulation Mechanism which is based upon CRYSTALS-Kyber V3.02 and
+ standardized as NIST FIPS 203. The security of this algorithm hangs upon the computation difficulty of the
+ Module Learning with Errors problem for both classical and quantum computers. This is used as the
+ KEMPreKey in this protocol.
+
+
+
+
ML-KEM-1024
+
+ An ML-KEM parameter set with claimed security category of 5. According to the FIPS 203 paper, this has a
+ Random Bit Generator strength of 256.
+
+
+
+
Device
+
+ A communication endpoint, i.e., a specific client instance with a working PPQM implementation.
+
+
+
+
PPQM element
+
+ An <encrypted> element in the &ns; namespace.
+
+
+
+
Bundle
+
+ A collection of publicly accessible data used in the post-quantum extended triple diffie-hellman protocol,
+ including the public IdentityKey, a list of single-use Curve25519 PreKeys, and a list of single-use KEMPreKeys
+ with their corresponding signatures.
+
+
+
+
rid
+
+ The device id of the intended recipient of the containing <key>.
+
+
+
+
sid
+
+ The device id of the sender of the containing PPQM element.
+
+
+
+
+
+
+
+
+ This protocol utilizes the Double Ratchet encryption scheme alongside a post-quantum KEM in the Triple
+ Diffie-Hellman algorithm. The following sections provide the technical details necessary to build an
+ implementation of the PPQM protocol.
+
+
+
+
+ The key exchange in PPQM is based on a modified version of the X3DH key agreement protocol, updated to incorporate
+ post-quantum secure components:
+
+
+
+
kem
+
ML-KEM-1024
+
+
+
hash function
+
SHA-256 also known as SHA2-256
+
+
+
info string
+
"PPQM X3DH"
+
+
+
signed PreKey rotation period
+
+ Signed PreKeys SHOULD be rotated periodically, from once a week to once a month.
+
+
+
+
time to retain the private key of the old signed PreKey after a round of rotation
+
+ The private key SHOULD be retained for an additional rotation period to accommodate delayed messages still
+ using the old signed PreKey.
+
+
+
+
number of PreKeys to include in the bundle
+
+ The bundle SHOULD always contain around 100 PreKeys.
+
+
+
+
minimum number of PreKeys to include in the bundle
+
+ The bundle MUST contain at least 25 PreKeys.
+
+
+
+
number of KEMPreKeys to include in the bundle
+
+ The bundle SHOULD always contain around 100 KEMPreKeys. This number MUST equal the number of PreKeys in the
+ bundle in order to reduce the number of collisions for both.
+
+
+
+
minimum number of KEMPreKeys to include in the bundle
+
+ The bundle MUST contain at least 25 KEMPreKeys.
+
+
+
+
usage of PreKeys and KEMPreKeys
+
+ All key exchanges MUST use a PreKey and a KEMPreKey. Any key exchanges that do not use a PreKey and a
+ KEMPreKey MUST be rejected. This is a basic requirement of PPQM.
+
+
+
+
associated data
+
+ The Associated Data (AD) is created by concatenating the IdentityKeys of Alice and Bob:
+ AD = Encode(IK_ALICE) || Encode(IK_BOB). In this order, Aliceinitiated the key
+ exchange while Bobaccepted the key exchange.
+
+
+
+
XEdDSA
+
PPQM does not mandate the usage of &xeddsa; with &x3dh; for the IdentityKey. Instead, there are three simple
+ rules that implementations MUST follow:
+
+
+ Implementations must use the birational map between the curves Curve25519 and Ed25519 to convert the public
+ part of the IdentityKey whenever required, as defined in &rfc7748; (on page 5).
+
+
+ Implementations must be able to perform X25519 (ECDH on Curve25519) using the IdentityKey.
+
+
+ Implementations must be able to create EdDSA-compatible signatures on the curve Ed25519 using the
+ IdentityKey.
+
+
+ There are essentially two ways in which libraries can fulfill these requirements:
+
+
+ Libraries can use a Curve25519 key pair as their internal IdentityKey. In this case, the IdentityKey can be
+ used for X25519 directly, and XEdDSA has to be used to produce EdDSA-compatible signatures. Note that
+ libsignal by default does NOT use XEdDSA. libsignal includes XEdDSA though and has
+ to be modified to use that to be compatible with OMEMO.
+
+
+ Libraries can use an Ed25519 key pair as their internal IdentityKey. In this case, the IdentityKey can
+ create EdDSA-compatible signatures directly, and has to be converted first to perform X25519.
+
+
+ Note that this decision is purely local to each client and PPQM library. The public key is ALWAYS transferred
+ in its Ed25519 form and only valid EdDSA signatures are transferred. The choice between Curve25519 and Ed25519
+ affects the definition of the Sig(PK, M) and DH(PK1, PK2) functions as defined below.
+
+
+
+
DH(PK1, PK2)
+
+ The original definition of DH(PK1, PK2) found in the X3DH specification applies with one exception:
+ if the IdentityKey pair is chosen to be an Ed25519 key pair and either PK1 or PK2
+ corresponds to the IdentityKey, the respective key first has to be converted into its Curve25519 equivalent
+ (see above). This conversion is implemented for example by libsodium, which exports the conversion as
+ crypto_sign_ed25519_sk_to_curve25519 and crypto_sign_ed25519_pk_to_curve25519 for the
+ private and public key, respectively (documented on libsodium.org).
+
+
+
+
Encode(PK)
+
The public part of the IdentityKey pair is encoded as defined in &rfc8032;. Note that the IdentityKey is
+ always transferred in its Ed25519 form. When using a Curve25519 key pair internally, the public key has to be
+ converted to Ed25519 first. Curve25519 public keys are encoded using the little-endian encoding of the
+ u-coordinate as specified in &rfc7748;.
+
+
+
+
+ The key exchange is performed just-in-time when sending the first message to a device, ensuring that each key
+ exchange message also contains encrypted content as produced by the post-quantum Double Ratchet encryption scheme
+ described below.
+
+
+ In essence, PPQM is extremely similar to OMEMO except for the added KEMPreKey in the X3DH Protocol.
+
+
+
+
+ NOTE: PPQMMessage.proto, PPQMAuthenticatedMessage.proto and PPQMKeyExchange.proto refer
+ to the protobuf structures as defined in the Protobuf Schemas.
+
+
+ The &doubleratchet; encryption scheme is adapted to use post-quantum key material. PPQM uses this protocol with
+ the following parameters/settings:
+
+
+
+
ratchet initialization
+
+ The Double Ratchet is initialized using the shared secret, associated data, and public keys as yielded by the
+ X3DH Protocol, as explained in the Double Ratchet specification. The ephemeral key pair used by the key
+ agreement protocol is stored with the session.
+
+
+
+
MAX_SKIP
+
+ As with OMEMO, storing skipped message keys can introduce potential DoS attacks. It is RECOMMENDED to limit
+ the storage to 1000 skipped message keys per session. Secondly, a maximum number of skipped message keys has
+ to be limited, or else, a malicious actor could make the receiving device calculate the integer limit of
+ skipped message keys.
+
+
+
+
deletion policy for skipped message keys
+
+ PPQM follows the same guidelines as OMEMO, with skipped message keys being discarded on a FIFO basis when the
+ limit is reached. All implementations MUST NOT keep message keys around forever and discard them based on
+ deterministic events except time.
+
+
+
+
authentication tag truncation
+
+ Authentication tags are truncated to 16 bytes/128 bits.
+
+
+
+
CONCAT(ad, header)
+
+ CONCAT(ad, header) = ad || PPQMMessage.proto(header)
+
+
+
+
KDF_RK(rk, dh_out)
+
+ HKDF-SHA-256 using the root key (rk) as HKDF salt, the output of a Diffie-Hellman (dh_out) as HKDF input
+ material, and "PPQM Root Chain" as HKDF info.
+
+
+
+
KDF_CK(ck)
+
+ HMAC-SHA-256 using a chain key (ck) as the HMAC key, with specified constants for message key and chain key
+ derivation.
+
+
+
+
ENCRYPT(mk, plaintext, associated_data)
+
+ The encryption step uses authenticated encryption consisting of AES-256-GCM with HMAC-SHA-256.
+
+
+ Use HKDF-SHA-256 to generate 80 bytes of output from the message key by providing mk as HKDF input, 256
+ zero-bits as HKDF salt and "OMEMO Message Key Material" as HKDF info.
+
+
+ Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
+
+
+ Encrypt the plaintext (which consists of a 32 bytes key and 16 bytes HMAC as specified in the section
+ about Message Encryption) using AES-256-GCM with no
+ padding, using the encryption key and IV derived in the previous step.
+
+
+ Split the associated data as returned by CONCAT into the original ad and the
+ PPQMMessage.proto structure.
+
+
+ Add the ciphertext to the PPQMMessage.proto structure.
+
+
+ Serialize the PPQMMessage.proto structure into a parseable byte array. To avoid potential
+ problems regarding non-uniqueness of the serialization, make sure to only serialize once and to
+ use that exact byte sequence in the following steps.
+
+
+ Concatenate the ad and the PPQMMessage.proto structure into a parseable byte array. The result
+ builds the HMAC input material for the next step.
+
+
+ Calculate the HMAC-SHA-256 using the authentication key and the input material as derived in the steps
+ above. Truncate the output of the HMAC to 16 bytes/128 bits.
+
+
+ Put the serialized PPQMMessage.proto structure and the HMAC into a new
+ PPQMAuthenticatedMessage.proto structure.
+
+
+
+
+
+
+ Further information on these functions can be found in the &doubleratchet; specification.
+
+
+ If the message requires a key exchange, the key exchange data is placed into a new PPQMKeyExchange.proto
+ structure together with the PPQMAuthenticatedMessage.proto structure.
+
+
+ To account for lost and out-of-order messages, PPQMKeyExchange.proto structures are sent until a response
+ by the recipient confirms successful key exchange. Subsequent messages use the stored header until confirmation is
+ received.
+
+
+
+
+ The contents are encrypted and authenticated using a combination of AES-256-GCM and HMAC-SHA-256.
+
+
+
+ Generate 32 bytes using a CSPRNG, effectively called key for the rest of the specification.
+
+
+ Use HKDF-SHA-256 to generate 80 bytes of output from the key by providing the key as HKDF input, 256
+ zero-bits as HKDF salt and "PPQM Payload" as HKDF info.
+
+
+ Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
+
+
+ Encrypt the plaintext using AES-256-GCM with no padding, using the encryption key and IV derived in the previous
+ step.
+
+
+ Calculate the HMAC-SHA-256 using the authentication key and the ciphertext from the previous steps. Truncate the
+ output of the HMAC to 16 bytes/128 bits by cutting off excess bytes from the end.
+
+
+ Concatenate the key and the HMAC, encrypt them using the Double Ratchet as specified above, once for
+ each intended recipient. This yields one PPQMKeyExchange or PPQMAuthenticatedMessage per
+ recipient device.
+
+
+
+
+
+ The contents are decrypted by reversing the encryption steps.
+
+
+
+ Decrypt the key and HMAC from the PPQMKeyExchange or PPQMAuthenticatedMessage, encrypted using
+ the Double Ratchet belonging to this device.
+
+
+ Use HKDF-SHA-256 to generate 80 bytes of output from the key by providing the key as HKDF
+ input, 256 zero-bits as HKDF salt and "PPQM Payload" as HKDF info.
+
+
+ Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
+
+
+ Verify the (truncated) HMAC-SHA-256 using the authentication key derived in the previous step and the
+ ciphertext.
+
+
+ Decrypt the ciphertext using AES-256-GCM with no padding, using the encryption key and IV derived in the
+ previous steps.
+
+
+
+
+
+
+
+
+ To participate in PPQM Encrypted chats, clients need to set up a PPQM library and generate a device id, which is a
+ randomly generated integer between 1 and 2^31 - 1. This device id MUST be unique for the account.
+
+
+
+
+ To determine whether a given contact supports PPQM, the devices node in PEP is consulted. Devices MUST subscribe
+ to &nsdevices; via PEP to stay informed of new devices.
+
+
+
+
+
+ A device must announce itself by adding its device id to the devices PEP node. The node’s access model must be set
+ to ‘open’ for this purpose.
+
+
+
+
+ A device must publish its IdentityKey, a Signed PreKey, a list of PreKeys, and a list of KEMPreKeys in a bundle.
+ This is stored in the &nsbundles; node, which must support multiple items.
+
+
+
+
+
+ To build a session with a device, fetch its bundle information and use a random PreKey and KEMPreKey to establish
+ a PPQM session.
+
+
+
+
+
+ A PPQM SCE &envelope; element MUST contain an <rpad/> affix element. Other optional elements include
+ <time/> and <from/>.
+
+
+
+
+ The &envelope; element is encrypted as described in the Message Encryption section.
+
+
+
+
+ A PPQM encrypted message includes an <encrypted> element in the &ns; namespace. It contains a
+ <header> and a &payload; element.
+
+
Empty PPQM messages omit the <payload> element, containing only the <header>.
+
+
+
+
+ Upon receiving a PPQM element, check if it contains a <keys> element for your device. If so, proceed with
+ decryption or session establishment as necessary.
+
+
+
+
+ An account can signal its desire to stop PPQM communication by sending a <opt-out/> element qualified by the
+ &ns; namespace.
+
+
+
+
+
Retrieve the members list when joining a group chat to determine recipients of PPQM messages.
+
+
+
Fetch device lists and bundles for each member before sending a message.
+
+
+
PPQM group messages are similar to 1:1 messages but include multiple <keys> elements for each participant.
+
+
+
+
+
+
+ Before publishing a new device id, ensure it is unique.
+
+
+ When building sessions, the PreKey id and the KEMPreKey id taken by the client MUST be the same in order to
+ guarantee that both PreKey and KEMPreKey are available. This avoids a situation where a PreKey is valid but the
+ KEMPreKey has already been used but the bundle has yet to be updated. To further ensure this, the number of PreKeys
+ and the KEMPreKeys published in the bundle MUST always match.
+
+
+ After receiving a PPQMKeyExchange and successfully building a session, respond with an empty PPQM message to notify
+ the sender.
+
+
+ Handle decryption failures with care, ignoring repeated messages but notifying users of other failures.
+
+
+ Postpone private key deletion until message catch-up is complete. Manually replace broken sessions as needed.
+
+
+
+
+
+
+ While PPQM uses a Pubsub Service (&xep0060;) on the user’s account it has more requirements than those defined in
+ &xep0163;. The requirements are:
+
+
+
+ The pubsub service MUST persist node items, i.e., the feature 'persistent-items'
+ is announced by the service.
+
+
+ The pubsub service MUST support publishing options as defined in XEP-0060 §7.1.5.
+
+
+ The pubsub service MUST support 'max' as a value for the 'pubsub#persist_items' node configuration.
+
+
+ The pubsub service MUST support the 'open' access model for node configuration and 'pubsub#access_model' as a
+ publish option.
+
+
+
+ Furthermore, the server MUST be able to adequately handle the large size of the bundle in a reasonable amount of
+ time. Servers with low bandwidth MUST not declare themselves PPQM-compatible. A conservative 50kbps MUST at least
+ be configured to ensure seamless session building.
+
+
+
+
+
+
+ Clients must not use a newly built session without user intervention. Trust decisions should involve fingerprint
+ verification. Avoid automatic session creation following decryption errors.
+
+
+
+
+
This document requires no interaction with the Internet Assigned Numbers Authority (IANA).
+
+
+
+
+
This specification defines the following XMPP namespaces:
+ Due to the large size brought by ML-KEM-1024, Base85 is the recommended binary-to-text encoding. However, due to
+ lack of suitable standardizations in this area, Base64 MUST be used for PUBLIC implementations to maintain
+ cross-implementation compatibility. For PRIVATE implementations, it is recommended to use Base85 to save bandwidth
+ as is the case for Privt App. Do note that an additional care for XML compatibility MUST be taken care of for
+ Base85 to safely work.
+
+
+
+
+
+
+
+
+
+
+ Big thanks to Daniel Gultsch for mentoring the original development of OMEMO. Thanks to the PPQM development team
+ for bringing post-quantum security to XMPP, especially for Ron Lauren Hombre's extensive research on the subject.
+ Special thanks to the community for their continued support and feedback.
+