Code change:
An asymmetric public key <del> The private key for a node is derived from its secret value using the KDF.  The public key is then derived from the private key using the Derive-Public-Key function. </del> <ins> The contents of the parent are based on the latest-updated child. Nodes in a tree are always updated along the "direct path" from a leaf to the root.  The generator of the update chooses a random secret value "path_secret[0]", and generates a sequence of "path secrets", one for each node from the leaf to the root.  That is, path_secret[0] is used for the leaf, path_secret[1] for its parent, and so on.  At each step, the path secret is used to derive a new secret value for the corresponding node, from which the node's key pair is derived. </ins> <del> The contents of a parent node are computed from one of its children as follows: </del> <ins> For example, suppose there is a group with four participants: </ins> <del> The contents of the parent are based on the latest-updated child. For example, if participants with leaf secrets A, B, C, and D join a group in that order, then the resulting tree will have the following structure: </del> <ins> If the first participant subsequently generates an update based on a secret X, then the sender would generate the following sequence of path secrets and node secrets: </ins> <del> If the first participant subsequently changes its leaf secret to be X, then the tree will have the following structure. </del> <ins> After the update, the tree will have the following structure, where "ns[i]" represents the node_secret values generated as described above: </ins> 5.3.

Related discussion:
text: Initial attempt to solve . This defines the KDF as discussed in and relocates the DH computation obligation and verification as part of the Derive-Key-Pair function definition.
Fixing my own review comments here, since NAME appears to be offline and we need to publish -04.
The PR from NAME introducing a KDF was merged before I had a chance to review it. There are a number of problems with it: Instead of calling for an abstract KDF, it should define one, as we have with the use of HKDF elsewhere We can't just say , since KDFs produce octet strings, not private keys. We need , not just . This doesn't match what I recall discussing on the list. I think what you want is actually as follows: Or in prose:
That was exactly the question I was asking on the list, i.e., if we need an explicit "derive-keypair" function. The idea with deriving the private key directly was to avoid a redundant derive-key operation. I'm totally fine re-doing the PR to represent either approach.
Merging that PR too quickly is on me. For the parent derivation, we can just use what the formal model for TreeKEM does, which is roughly the Richard points out. The part I don't like about this, is to define in the MLS specification as it depends on the HPKE internal algorithm. The TreeKEM formal specification, it is done the following way (because we know that the HPKE interface we use can take random bytes as a secret key): In the MLS specification, I suggest we avoid defining anything new but point to the HPKE spec instead. As it provides the KEM scheme, it should also provide ways to derive the from an octet string and the function that transform an to a . I suggest we define, in the HPKE document, something like that we already need anyway and eventually that maps the random bytes to an . For X25519 we don't even need the second function but generically we probably need it. That would lead to define the following in the MLS spec: NAME ?
I don't think we can delegate this to HPKE. HPKE doesn't have a need for anything like Derive-Key-Pair. We do, so it's on us to define it.