Draft: draft-ietf-mls-protocol

Commentary: While reviewing , I realized that we have a potential interop problem around . This struct feeds into the tree hash , so everyone in the group needs to have the entries in the same order or else they 'll disagree on the tree hash . But the order is n't specified anywhere : All the document says right now is " add L 's leaf index to the unmergedleaves list " , which could be implemented as an insert anywhere in the list . This PR resolves the ambiguity by requiring the list be sorted . 
 There 's a few implications of simply allowing forks : FS issues - clients would need to use initsecret twice , which means keeping around initsecret for a potential fork , which breaks FS . One resolution here is to use something from the ASTree for initsecret ( maybe the nth app secret , or a new ratchet derived from  ) . Does detection yield any sort of meaningful resolution technique ? Are we better off than we are now in terms of user experience ? ( What we have now , if the DS fails to order , is two ( or N ) groups of clients operating on different versions of the tree , which effectively partitions the group ) I wrote about this here : suggesting merges as a resolution technique . The main downside is clients would need to keep around the list of proposals for a while .
Mailing list commentary: This is n't bad imo , it reduces complexity to some extent . I ' m somewhat in favour of a non - pseudorandom tiebreaker if there 's no other arguments against it . How many bits of sequence number ? Have we considered using varints ? Similar to the CTLS proposal - Other forking considerations , I think there 's more involved than just changing the epoch identifier : 1 . We 'll need merges as well , since forks can lead to inconsistent group membership : Suppose in epoch 1 a group has A , B , and C A removes C in epoch 2A B adds D in epoch 2B We now have two group states 2A with AB and 2B with ABCD - and it 's unclear which group to use to send with . We could mandate that any client MUST send a " merge " commit on it 's view of history before sending any message . This commit could just be the list of epochs that are being merged ( + a usual DirectPath update ? ) , and processing it would mean replaying all proposals up to the common ancestor for those epochs on the common ancestor . 2 . Forward secrecy issues . By allowing forks , devices must now keep the previous epoch around to derive possible future forks - but this means we 'll be re - using initsecret . A possible solution could be to use the nth app secret from the ASTree instead of initsecret as the start for the new epoch secret . This ties nicely with using a non - pseudorandom tiebreaker . 3 . Ordering implications It 's unclear what a sensible ordering strategy is for the DS if we allow forking . ( simply ensuring that each commit is based on the " current " epoch is n't well defined since there can be multiple " current " epochs ) . By allowing forks the DS need not enforce ordering at all imo . This means that need to keep around old epochs , but this is already required per ( 2 ) . A different question is how many we need to keep around - perhaps a TTL or the past N epochs after a topological sort would make sense . Generally I think getting rid of server ordering is good idea : Helps Matrix and general federation use cases A common consistent mutated state for group operations can cause server side DB contention in my experience Forks is one way to remove ordering , and if we need to support it anyways it 's a nice benefit .
Paragraph (version A):
The "encryption_key" field contains an HPKE public key whose private
key is held only by the members at the leaves among its descendants.
The "parent_hash" field contains a hash of this node's parent node,
as described in parent-hash.  The "unmerged_leaves" field lists the
leaves under this parent node that are unmerged, according to their
indices among all the leaves in the tree.
Paragraph (version B):
The "encryption_key" field contains an HPKE public key whose private
key is held only by the members at the leaves among its descendants.
The "parent_hash" field contains a hash of this node's parent node,
as described in parent-hash.  The "unmerged_leaves" field lists the
leaves under this parent node that are unmerged, according to their
indices among all the leaves in the tree.  The entries in the
"unmerged_leaves" vector MUST be sorted in increasing order.