Change:
11. <del> The primary purpose of the handshake protocol is to provide an </del> <ins> The primary purpose of the Handshake protocol is to provide an </ins> authenticated group key exchange to clients.  In order to protect <del> Application messages sent among those members of a group, the Application secret provided by the handshake key schedule is used to derive encryption keys for the Message Protection Layer. </del> <ins> Application messages sent among the members of a group, the Application secret provided by the Handshake key schedule is used to derive nonces and encryption keys for the Message Protection Layer according to the Application Key Schedule.  That is, each epoch is equipped with a fresh Application Key Schedule which consist of a tree of Application Secrets as well as one symmetric ratchet per group member. Each client maintains their own local copy of (parts of) the Application Key Schedule for each epoch during which they are a group member.  They derive new keys, nonces and secrets as needed while deleting old ones as soon as they have been used. </ins> Application messages MUST be protected with the Authenticated- Encryption with Associated-Data (AEAD) encryption scheme associated

Discussion:
Basic idea: Application Key Schedule consists of a left balanced binary tree of secrets (the "AS Tree") and one symmetric ratchet per group member. The AS Tree has the same node/edge structure as the ratchet tree for that epoch. Members are assigned the same leaves.Each node in the AS Tree is assigned a secret. The root's secret = applicationsecret. The secrets of children are derived from that of their parent.The secret of a leaf is the initial secret of a symmetric hash ratchet. The ratchet generates the key/nonce sequence used by the leaf's group member to encrypt messages during that epoch. Other comments: I included a "Deletion Schedule": keys, nonces are 'consumed' if they are used to encrypt or successfully decrypt a message. secrets are 'consumed' if value derived from it is consumed. Any consumed value must be immediately deleted for reasons of forward secrecy.I was very generous with contexts for all calls to HKDF. E.g. I included Hash(GroupState[n]) in the context of every call to HKDF. True, I dont think its neccesary to prove security against more coarse adversarial models (e.g. that only do all-or-nothing state leakage). Still, as a matter of the "defense in depth" principle I think including as much relevant context as possible during all key/secret derivation is a good idea. Albeit only as long as the price (in computation, complexity, etc) is not to high. To that end, I purposefully use Hash(GroupState_[n]) in the context as it is short, needs only to be computed once at the start of the epoch and can then be used to very cheaply to construct all contexts needed for the rest of the new application key schedule.Disclaimer: I'm a bit of a noob when it comes to Markdown, RFCs and github so forgive me (and tell me!) if I've done something wrong here. Co-contributors: Benjamin Beurbouche, Sandro Coretti, Yevgeniy Dodis,
Merging this despite outstanding comments. NAME and I will handle our requested edits in a couple of follow-up PRs.
Here's the Weekly Digest for : This week, 8 issues were created. Of these, 4 issues have been closed and 4 issues are still open.

:greenheart: , by :greenheart: , by :greenheart: , by :greenheart: , by :heart: , by :heart: , by :heart: , by :heart: , by The issue most discussed this week has been: :speaker: , by It received 9 comments. This week, no pull requests has been proposed by the users. This week, 4 users have contributed to this repository. They are , , , and . This week, no user has starred this repository. This week, there have been 4 commits in the repository. These are: :hammerandwrench: Merge pull request from rozbb/mlsplaintext-signature Multiple clarifications around Framing by :hammerandwrench: Merge pull request from rozbb/hpke-encrypt Clarify how HPKE ciphertexts are computed by :hammerandwrench: by :hammerand_wrench: by # RELEASES This week, no releases were published. That's all for this week, please watch :eyes: and star :star: to receive next weekly updates. :smiley:
Here's the Weekly Digest for : - - Last week 4 issues were created. Of these, 1 issues have been closed and 3 issues are still open. :greenheart: , by :greenheart: , by :greenheart: , by :heart: , by :speaker: , by It received 4 comments. - - Last week, 9 pull requests were created, updated or merged. Last week, 8 pull requests were updated. :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by Last week, 1 pull request was merged. :purpleheart: , by - - Last week there were 4 commits. :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by - - Last week there was 1 contributor. :bustinsilhouette: - - Last week there was 1 stargazer. :star: You are the star! :star2: - - Last week there were no releases.

- - That's all for last week, please :eyes: Watch and :star: Star the repository to receive next weekly updates. :smiley: You can also .
We should ensure that there is adequate anti-replay protection for both Handshake and Application messages. (In particular, we should define what anti-replay issues are a concern.) Could be related to if we want to solve it at that framing layer.
It looks like application key schedule on its own may not be enough to prevent replay attacks if out-of-order messages are supported (and it seems like they are supported according to section 9.2.1). Lets say we are at epoch x, and the receiver derives applicationsecret[sender][0] for epoch x. Then, the receiver receives message1 (generation = 1) first before message0. In order to decrypt message1, the receiver needs to advance the application secret forward once to applicationsecret[sender][1] to get message1 nonce and AEAD secret. The receiver then happily processes message 1. However, the receiver cannot forget applicationsecret[sender][0] at this time; otherwise it will never be able to decrypt message0 so it has to keep applicationsecret[sender][0] around. If the receiver receives message1 again, it can compute applicationsecret[sender][1] from applicationsecret[sender][0] and process the message. Hence, it seems that key schedule on its own will not prevent replay attacks. The receiver needs to remember that it has already processed message1. The same problem may apply to receiving a message from epoch N+1 while not all messages from epoch N have been received (if such case is possible). Replay attack counter-measures may be implemented as part of key schedule logic or separately, but it looks like implementors need to pay attention to this.
Obviously, if you keep a previous application secret, you are breaking FS. This is forbidden by the protocol. The protocol mandates: "Receivers MUST delete an Application Secret once it has been used to derive the corresponding AEAD key and nonce as well as the next Application Secret. Receivers MAY keep the AEAD key and nonce around for some reasonable period."
Cf. "Updating the Application Secret"
Does it mean that receiving out-of-order messages is not possible?

If I abandon applicationsecret[sender][0] and advance to applicationsecret[sender][2] after receiving message 1 before message 0, I will never be able to process message 0. Is this intended behavior or am I missing something?
No, you can do out of order, but what you keep are the AEAD keys/nonces and not the Application Secrets. The idea is the following: 1 - Compute Application Secret[sender][0] 2 - Derive AEAD Key[Sender][0] and AEAD Nonce[Sender][0] from Application Secret[sender][0] 3 - Overwrite Application Secret[sender][0] with Application Secret[sender][1] Basically, you should see these 3 steps as a single operation Now, if you iterate over that you can get more AEAD Keys and nonces [0 ... N] to receive out of order. Because of step 3 you have local Forward Secrecy. Note that you never store more than a single (the latest) Application Secret per sender and that you have the keys [0...N] to decrypt out of order.
Makes sense. Thanks for explaining. I suspect receiving out of order messages from a different epoch works in a similar way. If I am at epoch 0, and I receive a message from epoch 2, I derive and keep applicationsecret for epoch 1 and roll the initsecret forward. From the implementation perspective, how do I know when I can safely discard an application secret for a particular epoch? Or how do I know that no more messages are coming for a particular sender/epoch? Do you think there is value in adding a paragraph clarifying how the key schedule ensures replay attack protection to the spec? I know these are probably all implementation questions, but I suspect these may be the questions the implementors may be asking.
NAME I have some text stashed for when to discard the previous application secrets after there is a new epoch, so I will handle that. The idea is that you "publish" the number of application messages you sent in the previous epoch, but that is to be discussed... Regarding replay, if you asked, it means clarification might be helpful here, do you want to submit a PR and assign me for review ?

Otherwise just tell me and I'll handle it... : )
NAME I think you should review the below and update the spec as you see fit : ) -- I would update section 9.2.1 with something like: If receiver's application secret is at generation N, and the receiver receives an out of order message with generation N+x (where x>0), the receiver MUST advance the application secret forward to application secret N+x+1 after processing the out of order message. For every message with generation between N and N+x-1 (messages that have not been received), the receiver SHOULD derive AEAD nonce and AEAD key and store them in order to be able to decrypt these messages later. Application secret MUST NOT be kept at generation N in order allow for decryption of out-of-order messages. Instead, stored AEAD key and nonce will allow for decryption of out-of-order messages when received later. -- We may also introduce a short new section "Message Replay Protection" with something like: Application key schedule provides replay attack counter-measures. If a message is replayed, the receiver should not have the right AEAD key nor have the application secret that could be used for deriving the right AEAD key for the replayed message. Hence, replayed message will be rejected by the receiver.
I think this is adequately addressed by and