Re: [MLS] Include signature in the confirmed transcript hash?

Cornelissen Eric <> Fri, 18 September 2020 11:48 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id C5EF03A0522 for <>; Fri, 18 Sep 2020 04:48:35 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -2.118
X-Spam-Status: No, score=-2.118 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=0.001, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (2048-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id 2DECnze6oohE for <>; Fri, 18 Sep 2020 04:48:33 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 319263A0475 for <>; Fri, 18 Sep 2020 04:48:31 -0700 (PDT)
Received: from (localhost.localdomain []) by localhost (Email Security Appliance) with SMTP id 09046115799_F649E89B; Fri, 18 Sep 2020 11:48:25 +0000 (GMT)
Received: from ( []) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (Client CN "", Issuer "RootCA3" (not verified)) by (Sophos Email Appliance) with ESMTPS id 6864F11577B_F649E88F; Fri, 18 Sep 2020 11:48:24 +0000 (GMT)
Received: from ( by ( with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 18 Sep 2020 14:48:24 +0300
Received: from ([fe80::4047:1ae:cfdf:c1a8]) by ([fe80::4047:1ae:cfdf:c1a8%18]) with mapi id 15.01.1979.003; Fri, 18 Sep 2020 14:48:24 +0300
From: Cornelissen Eric <>
To: Marta Mularczyk <>, "" <>
Thread-Topic: [MLS] Include signature in the confirmed transcript hash?
Thread-Index: AQHWjRp6GFNRDVlu+U28jFIyAyzlmqluSN1o
Date: Fri, 18 Sep 2020 11:48:24 +0000
Message-ID: <>
References: <003401d68cf9$d7c5d420$87517c60$>
In-Reply-To: <003401d68cf9$d7c5d420$87517c60$>
Accept-Language: en-US, fi-FI
Content-Language: en-US
x-originating-ip: []
Content-Type: multipart/alternative; boundary="_000_2d08dc2eef504f32b609c5fbaf26645daaltofi_"
MIME-Version: 1.0
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; h=from:to:subject:date:message-id:references:in-reply-to:content-type:mime-version; s=its18; bh=eDMvbo1+g9MRcV7XPC5C/9uajMJp7rmYSdwD97FWX1w=; b=gsFubrr+gkQ1/EWsTA9NT+3H/rxaoqZa0u8nuT4wRZdpGVe4PuSKRuO75vfHRP5+Ea/fXfLADcsfAsIwxZyaGWaonX/sOfab3Ho0VJsXZcWpPl+fHx3OyC80VXhZvsnAHMk428ytU55hDQ/Pvv+YNOihOppcp75s3uV+AZAWxmTqemTQa8gKqW9Kh5zDu+i/AZ8bvT+fbYzzxcgEqw0stmvr15KagNhhXTbaF+Qm/7yzOxR1BKAxqAUS3/XVCNymHtTUMjdybMrOYb+sCDtNWPAqxeD1yPUCdXyQJ45CNt5udcBTfECzAqxPzhgFiec0GV+z9Mqwf63+40An6gymhg==
Archived-At: <>
Subject: Re: [MLS] Include signature in the confirmed transcript 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, 18 Sep 2020 11:48:36 -0000


You say "Now Alice and Bob agree on the confirmed_transcript_hash [...] but not on the interim_transcript_hash" which, to me, seems improbable as the confirmed_transcript_hash is computed based on the interim_transcript_hash (see the interim_transcript_hash/confirmed_transcript_hash chain below).

Hence, if Alice and Bob receive packets with different signatures in epoch e, interim_transcript_hash_[e] will be different (due to MLSPlaintextCommitAuthData_[e]) and so will confirmed_transcript_hash_[e] (due to interim_transcript_hash_[e]).

I'm guessing the confusion comes from the way the definition of the interim and confirmed_transcript_hash are written. The definition may seem to say that you compute a confirmed_transcript_hash for this epoch and interim_transcript_hash for the next epoch upon a commit (in which case your attack works). But, I think(!), it is actually the case that you compute an interim_transcript_hash from the previous epoch's confirmed_transcript_hash and a new confirmed_transcript_hash from that interim_transcript_hash upon a commit.

Hope that helps (and that I understood correctly),



interim_transcript_hash/confirmed_transcript_hash chain:


interim_transcript_hash_[0] = 0;

confirmed_transcript_hash_[0] = Hash(interim_transcript_hash_[0] ||MLSPlaintextCommitContent_[0]);


interim_transcript_hash_[1] = Hash(confirmed_transcript_hash_[0] ||MLSPlaintextCommitAuthData_[0]);

confirmed_transcript_hash_[1] = Hash(interim_transcript_hash_[1] ||MLSPlaintextCommitContent_[1]);


interim_transcript_hash_[2] = Hash(confirmed_transcript_hash_[1] ||MLSPlaintextCommitAuthData_[1]);

confirmed_transcript_hash_[2] = Hash(interim_transcript_hash_[2] ||MLSPlaintextCommitContent_[2]);


From: Marta Mularczyk <>
Sent: Thursday, September 17, 2020 4:52 PM
Subject: [MLS] Include signature in the confirmed transcript hash?

Hi all,

Together with Joël Alwen and Daniel Jost, we noticed some unexpected (at least to us) effects of the way transcript hash is computed. What are your thoughts on this?

Details: Say Alice and Bob each processes a commit packet and they end up with the same epoch secrets. Expected guarantee: agreement on the secrets implies being in sync -- agreement on the group state, and being able to continue progressing epochs.

Problem: the latter is false if the packets processed by Alice and Bob only differ in the signature string (it's easy to come up with many equivalent ECDSA signatures, given only the signer's public key). Now Alice and Bob agree on the confirmed_transcript_hash, and hence on the current secrets, but not on the interim_transcript_hash, so they won't agree on the next epoch secrets. Result: they will never accept the same commit (due to not matching confirmation_tag) and so they'll never be in sync in the next epoch.

This can be solved by including the signature in the confirmed_transcript_hash and not signing the confirmation_tag (the tag is also not part of the transcript_hash). We claim that this doesn't affect security. Assume Alice sends a commit and the adversary intercepts the packet. Consider these 3 cases:

- if the adversary doesn't know the current epoch secrets, then he can't modify any part of Alice's packet (due to AEAD/MAC security of the message framing).

- if he knows the epoch secrets but not Alice's signing key, then the only thing he can, in principle, modify is the confirmation_tag. However, the tag is fully determined by the signed part of the commit (and the transcript history).

- if he knows both, then the adversary can already produce any packet he wants on behalf of Alice.

An additional advantage of this solution is that it simplifies the protocol by removing the interim_transcript_hash.

In detail, a commit now proceeds as follows:

1. construct the MLSPlaintext with the Commit object and confirmation_tag=0,

2. sign the MLSPlaintext and include the result in the confirmed_transcript_hash,

3. advance the key schedule and update the confirmation_tag in the MLSPlaintext.

If the working group generally agrees on the above approach, we'll be happpy to draft a PR.