Subject: Re: [MLS] question about group contexts and deriving epoch secrets

From: Richard Barnes <[email-masked]>
Date: Wed, 3 Mar 2021 14:32:49 -0500

Thanks for raising this, Hubert, I agree that it's ambiguous in the
current text, but I think there is a solution here that we just need to
clarify :)  Basically, I think the "provisional" GroupContext morphs into
the "new" GroupContext over the course of generating / applying a commit.
Let me try to articulate my theory of how things work here, then if that
makes sense, we can try to turn it into spec text.

The joiner side seems unambiguous.  The joiner gets the GroupContext for
the epoch in which they're added -- in fact, the GroupInfo carried in a
Welcome is basically just a signed GroupContext.

When creating / verifying a Commit, you need a GroupContext at three points:
1. When you encap/decap the UpdatePath
2. When you ratchet forward the key schedule
3. When you sign the MLSPlaintext of the Commit

All three of these need to be different:
* Case (3) uses the GroupContext from the old epoch, i.e., the one that
corresponds to MLSPlaintext.epoch, so that recipients can verify the
signature before processing the message
* Case (2) uses the GroupContext for the new epoch, after the proposals and
UpdatePath have been applied, so that joiners can compute the epoch_secret
* Case (1) uses a "provisional" GroupContext that  captures the state of
the tree at the time the UpdatePath is computed:
    * epoch = old_group_context.epoch + 1
    * tree_hash reflects the tree with proposals applied
    * group_id, confirmed_transcript_hash, and extensions stay the same

Looking at this in chronological order for the Commit generator:
* Cache the old GroupContext for use in signing later
* Apply proposals to the tree
    => provisional GroupContext
    => compute UpdatePath using provisional GroupContext
* Sign Commit using old GroupContext
    => update confirmed_transcript_hash
    => new GroupContext
    => epoch_secret
    => confirmation_tag

Does that make sense to you?

--RLB

On Tue, Feb 9, 2021 at 6:46 PM Hubert Chathi <[email-masked]> wrote:

> On Tue, 9 Feb 2021, at 04:56, Raphael Robert wrote:
> > I think “new GroupContext” and “provisional GroupContext” are synonyms.
>
> I'm not so sure about this.  The "provisional GroupContext" is created
> after applying the proposals (line 2532), but before the UpdatePath is
> applied to the tree (line 2559).  Whereas, from what I understand, new
> members are only given the tree after the UpdatePath is applied, which
> would give a different tree_hash and hence GroupContext.  I don't know if
> I'm just misunderstanding something.
>
> > Creating the Commit:
> >  - Use the confirmed transcript hash (old intermediate transcript hash
> > combined with new commit content from current MLSPlaintext)
> >  - Create new provisional GroupContext with new provisional epoch (old
> > epoch  + 1), new tree hash (after proposals were applied to old tree)
> > and confirmed transcript hash from above
> >
> > Applying a Commit as an existing member:
> >  - Same as creating a Commit
> >
> > Joining a group from a Welcome message:
> > - Create GroupContext with epoch from GroupInfo, tree hash from
> > GroupInfo and confirmed transcript hash from GroupInfo
> >
> > Does that answer the question?
> >
> > If you think the spec is wrong/confusing feel free to file a PR.
>
> Yes, once I manage to understand what's going on, I plan on filing a PR.
>
> >
> > Raphael
> >
> > > On 9. Feb 2021, at 00:45, Hubert Chathi <[email-masked]> wrote:
> > >
> > > When deriving the epoch secret, you do "ExpandWithLabel(., "epoch",
> GroupContext_[n], KDF.Nh)", so you need a GroupContext.  As far as I can
> tell, there appears to be a contradiction about which GroupContext to use:
> in the "Key Schedule" section (Line 1404), it says to use "The GroupContext
> object for current epoch", but in the "Commit" section under the part
> talking about a group member who applies a Commit message (Line 2660), it
> says to use the provisional GroupContext.  (The part talking about the
> group member who creates the Commit message doesn't say which GroupContext
> to use.)  If we are supposed to use the "new" GroupContext (after applying
> both the proposals and the update), but if we are supposed to use the
> provisional GroupContext, then I don't think that a new member has access
> to the tree_hash or confirmed_transcript_hash to create the GroupContext
> needed to derive the epoch secret.  So it seems like the "new" GroupContext
> should be correct, but Line 2660 is pretty expli
> > > cit about using the provisional GroupContext.
> > >
> > > _______________________________________________
> > > MLS mailing list
> > > [email-masked]
> > > https://www.ietf.org/mailman/listinfo/mls
> >
> > _______________________________________________
> > MLS mailing list
> > [email-masked]
> > https://www.ietf.org/mailman/listinfo/mls
> >
>
> _______________________________________________
> MLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/mls
>

---

From: "Hubert Chathi" <[email-masked]>
Date: Fri, 05 Mar 2021 17:52:23 -0500

Hi Richard,

Thanks for responding.  I think that more-or-less matches my understand of how it was supposed to work, which means that I think that the joiner is missing some information.  But it's been a while since I've looked at it, and I'll have to double-check.

Hubert

On Wed, 3 Mar 2021, at 14:32, Richard Barnes wrote:
> Thanks for raising this, Hubert, I agree that it's ambiguous in the  current text, but I think there is a solution here that we just need to clarify :)  Basically, I think the "provisional" GroupContext morphs into the "new" GroupContext over the course of generating / applying a commit.  Let me try to articulate my theory of how things work here, then if that makes sense, we can try to turn it into spec text.
> 
> The joiner side seems unambiguous.  The joiner gets the GroupContext for the epoch in which they're added -- in fact, the GroupInfo carried in a Welcome is basically just a signed GroupContext.
> 
> * Case (3) uses the GroupContext from the old epoch, i.e., the one that corresponds to MLSPlaintext.epoch, so that recipients can verify the signature before processing the message
> * Case (2) uses the GroupContext for the new epoch, after the proposals and UpdatePath have been applied, so that joiners can compute the epoch_secret
> * Case (1) uses a "provisional" GroupContext that  captures the state of the tree at the time the UpdatePath is computed:
>> I'm not so sure about this.  The "provisional GroupContext" is created after applying the proposals (line 2532), but before the UpdatePath is applied to the tree (line 2559).  Whereas, from what I understand, new members are only given the tree after the UpdatePath is applied, which would give a different tree_hash and hence GroupContext.  I don't know if I'm just misunderstanding something.
>> 
>> > Creating the Commit:
>> > > When deriving the epoch secret, you do "ExpandWithLabel(., "epoch", GroupContext_[n], KDF.Nh)", so you need a GroupContext.  As far as I can tell, there appears to be a contradiction about which GroupContext to use: in the "Key Schedule" section (Line 1404), it says to use "The GroupContext object for current epoch", but in the "Commit" section under the part talking about a group member who applies a Commit message (Line 2660), it says to use the provisional GroupContext.  (The part talking about the group member who creates the Commit message doesn't say which GroupContext to use.)  If we are supposed to use the "new" GroupContext (after applying both the proposals and the update), but if we are supposed to use the provisional GroupContext, then I don't think that a new member has access to the tree_hash or confirmed_transcript_hash to create the GroupContext needed to derive the epoch secret.  So it seems like the "new" GroupContext should be correct, but Line 2660 is pretty expli

---

From: "Hubert Chathi" <[email-masked]>
Date: Wed, 17 Mar 2021 19:52:43 -0400

I've managed to re-read the sections in question.  I think the issue is that the current draft says that when you ratchet forward the key schedule, you use the provisional GroupContext (Line 2638 and 2664), whereas in your email, you say you should use the GroupContext for the new epoch.  Using the provisional GroupContext is problematic because AFAICT, new users don't have enough information to derive the provisional GroupContext, but using the "new" GroupContext should be fine.  So if it is indeed supposed to be the "new" GroupContext that is used, I can prepare a PR to fix it (or just tack it on to my currently-open #454).

Hubert

On Fri, 5 Mar 2021, at 17:52, Hubert Chathi wrote:
> [email-masked] <mailto:MLS%40ietf.org>