Re: [MLS] New Parent Hash

Mularczyk Marta <> Fri, 01 January 2021 14:48 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 5AFB33A07F5 for <>; Fri, 1 Jan 2021 06:48:34 -0800 (PST)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -1.886
X-Spam-Status: No, score=-1.886 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HTML_MESSAGE=0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_KAM_HTML_FONT_INVALID=0.01, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id xw1LjpuZRNxT for <>; Fri, 1 Jan 2021 06:48:31 -0800 (PST)
Received: from ( [IPv6:2001:67c:10ec:5606::21]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 6AB293A07EA for <>; Fri, 1 Jan 2021 06:48:30 -0800 (PST)
Received: from (2001:67c:10ec:5603::31) by (2001:67c:10ec:5606::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2; Fri, 1 Jan 2021 15:48:09 +0100
Received: from (2001:67c:10ec:5603::27) by (2001:67c:10ec:5603::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2; Fri, 1 Jan 2021 15:48:25 +0100
Received: from ([fe80::48e5:b9c:79eb:9d16]) by ([fe80::48e5:b9c:79eb:9d16%4]) with mapi id 15.01.2106.006; Fri, 1 Jan 2021 15:48:25 +0100
From: "Mularczyk Marta" <>
To: "" <>
CC: Raphael Robert <>, 'Joel Alwen' <>
Thread-Topic: [MLS] New Parent Hash
Thread-Index: AQHWuTjfZw1SmrLREUKS4j4Eh1hSAKoRUjgAgABQ3ICAAYQpGA==
Date: Fri, 1 Jan 2021 14:48:25 +0000
Message-ID: <>
References: <> <>, <>
In-Reply-To: <>
Accept-Language: en-US, de-CH
Content-Language: en-US
x-originating-ip: []
x-tm-snts-smtp: 80D60426418710D866A70DC07484FF954B5FE49E3D8FD0D66A301BE88B2109CE2000:8
Content-Type: multipart/alternative; boundary="_000_32c5c409abbc4cf79ecf74c9e2a2befainfethzch_"
MIME-Version: 1.0
Archived-At: <>
Subject: Re: [MLS] New Parent Hash
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Messaging Layer Security <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Fri, 01 Jan 2021 14:48:34 -0000

Hi Raphael,

Thanks for explaining! Using "descendants" is definitely better for security, but also, as Hubert mentioned, less efficient.

Also we did understand “resolution” the same way as you when we proposed the strong parent hash (sorry for the confusion).

But we obviously really want to understand if/why using resolution is insecure. Ultimately, the security property we care about is that privacy and authenticity of application messages holds. The Parent Hash mechanism helps us ensure this holds also for epochs in adversarially generated groups, as long as the adversary does not control any leaves in this epoch (i.e. does not know the signing key of the leaf). So to really see if your examples break security, it would be good to see if they let us violate this security goal.

To see why we believe the new parent hash notion (i.e. with resolutions) achieves this, let us first clarify what technical property about (even adversarially produced) ratchet trees we want from verifying parent hashes. It’s not that the adversary can’t produce manipulated trees at all. It’s that the only manipulations she is able to do will not let her produce a tree that violates the tree invariant. That’s because (in our model) when the tree invariant holds then we can show that the epoch is secure.

So some manipulations *are* possible. They are just “benign”. For example, suppose adversary A controls a leaf L with HPKE key pk in tree T (i.e. she knows the signing key of L’s owner). Then A can construct a new tree T’ identical to T but where leaf L has pk’ != pk (say, by performing a commit at leaf L to obtain T’). But for this, in T’ leaf L must still be controlled by A. We call this manipulation “benign” because even though A might now break privacy of application messages in epoch with tree T’ it doesnt violate our security goal because privacy is conditioned on A *not* controlling any leaves.

Conversely, one thing A can *not* do is the following. Say T’ has a node V with HPKE public key pk0 such that A knows corresponding sk0. Then for T’ to pass verification, it must contain a leaf controlled by A. This holds since for T’ to pass verification there must be a leaf in V’s subtree with a signature covering a hash that includes pk0. I.e. some leaf must “attest” to having inserted pk0 into T’. (Recall that in our model the adversary can’t just leak sk0 alone. They must leak a full state of some client which also means leaking the client's signing key.)

So our question to you is the following. (Does this make sense? And) we’re not exactly sure what you have in mind when you say “swapping out two leaf nodes”. But we think it would only be a problem if it is not benign. Is this true for your attack? Could you expand a bit on what tree manipulation you have in mind?


Joël & Marta

From: MLS <> on behalf of Hubert Chathi <>
Sent: Thursday, December 31, 2020 5:36:53 PM
Subject: Re: [MLS] New Parent Hash

I think that if you use "descendants" as you define it, then calculating the parent_hash will become O(n) all the time, rather than O(log n) in the best-case, since the size of the descendants list will be O(n).  I'm not sure if there's a good way to maintain O(log n) and still provide the desired security.

On Thu, 31 Dec 2020, at 06:47, Raphael Robert wrote:
> Hi Joël, Daniel and Marta,
> I just implemented the stronger parent hash scheme you proposed in the
> way it is described in the spec now.
> The good news is that it is implementable, the bad news is that is does
> not solve the problem you initially describe. Specifically, swapping
> out two leaf nodes still goes undetected.
> I think it is due to a terminology conflict, but it would be great if
> you could validate that assumption.
> In 7.4 you introduce the notion of “original child resolution” as " the
> array of HPKEPublicKey values of the nodes in the resolution of S”. The
> term “resolution” is defined in 5.2. It is essentially a way of dealing
> with blank nodes by substituting them with the first non-blank
> descendants you find when descending the subtree of a node.
> Here is my assumption: You probably thought the resolution would cover
> all non-blank descendants of a node, not just the first non-blank
> descendant. In that case we would need another function that does that
> (let’s call it “descendants”).
> If we look at the example of 5.2:
>  - The resolution of node 3 is the list [A, CD, C]
>  - The descendants of node 3 is the list [A, CD, C, D]
>  - The resolution of node 5 is the list [CD]
>  - The descendants of node 5 is the list [CD, C, D] (we just need to
> additionally filter out C, because it is an unmerged leaf of node 5)
> Here is a code snippet of what the “descendants” function would look
> like (sorry that it’s Rust, not Python):
> fn descendants(x: NodeIndex, size: LeafIndex) -> Vec<NodeIndex> {
>     if level(x) == 0 {
>         vec![x]
>     } else {
>         let left_child = left(x);
>         let right_child = right(x, size);
>         [
>             descendants(left_child, size),
>             vec![x],
>             descendants(right_child, size),
>         ]
>         .concat()
>     }
> }
> There’s a more efficient implementation of course, this is just to illustrate.
> In other words, the new “original child resolution” of S would be the
> subtree under S, but with filtered-out blank nodes and unmerged leaves
> of S.
> If my assumption is correct, I’ll follow up quickly with a PR since
> this is currently a blocker for interop based on draft-11.
> Thanks
> Raphael
> > On 12. Nov 2020, at 22:14, Joel Alwen <> wrote:
> >
> > Hey people,
> >
> > Just a quick heads up that Daniel, Marta and I put in a PR with a new version of
> > strong parent hash to prevent the attacks from the earlier thread. We tried to
> > make it as minimal as we could to help with deniability while still preventing
> > the attacks permitted by weak parent hashes.
> >
> > In a nutshell, when computing parent_hash at node v with parent p and sibling w
> > we include
> > - p's HPKE pubkey
> > - p's parent_hash value and
> > - HPKE pub keys in the resolution of w except for those belonging to leaves
> > unmerged at p.
> >
> > As a sanity check, notice that as long as p's keys remain the same one can
> > always recompute the same parent_hash value at v as was initially computed by
> > the member that set p's keys. (In other words, new members can verify that the
> > stored parent_hash values match whats in the tree.) In particular, that's coz as
> > long as p's keys are unchanged so is the resolution of w. The only exception are
> > leaves being added as unmerged at w. But those leaves are also added as unmerged
> > at p so they are left out of the hash.
> >
> > As for deniability, at least parent_hash only binds HPKE keys and nothing else
> > (like, say, credentials or signatures). Its the best we were able to come up
> > with for now...
> >
> > - joël
> >
> > _______________________________________________
> > MLS mailing list
> >
> >
> _______________________________________________
> MLS mailing list

MLS mailing list