
Better Encrypted Group Chat - UkiahSmith
https://blog.trailofbits.com/2019/08/06/better-encrypted-group-chat/
======
doomrobo
Author here. Happy to answer questions!

~~~
daurnimator
I've been working on a new scheme for decentralised encrypted (group)
messaging bus over at [https://xn--nma.com/](https://ȱ.com/) unlike many other
schemes, forward secrecy is _not_ a goal: When I invite a friend to a group
chat, I _want_ them to be able to obtain historical conversation messages.

For your normal end user (at least what I think of as common: see how facebook
messenger works, as well as slack, discord and even how many irc chat rooms
have public logs), how is this MLS scheme useful?

~~~
ptman
Are you aware of matrix? Their olm encryption scheme is capable of PFS, but
it's not used exactly in order to provide history.

~~~
daurnimator
Yes I'm aware of matrix. A couple of things that I don't like about the matrix
protocol are: 1. identity is tied to a server and users are not free to move
between servers. 2. servers are assumed to be always online and have low
latency.

~~~
roblabla
1\. There is work to fix the identity problem with Identity Servers. See
[https://matrix.org/faq/#what-is-an-identity-
server%3F](https://matrix.org/faq/#what-is-an-identity-server%3F)

2\. I'm not sure what gives this impression? I have a server that is very much
on flaky network, and it federates just fine. The point is that servers can go
online/offline without breaking anything on the whole network.

------
toomim
That was a great article. I learned a lot about encryption in group chats,
which I've always been curious about.

------
javajosh
I think you missed a solution, which is a variant of #2.

To simplify things, consider a single global chat room, on an enormous server
(probably in Salt Lake City), where every person on earth is connected and
have a public/private key-pair, and every person on Earth can read everything
anyone posts. You can post publicly ( anonymously or with a signature), or
privately (pair key) to any individual on Earth. From this starting point, how
do you make private group chats? (This starting point factors out a lot things
we shouldn't worry about, and I think is simpler/nicer than a story about a
Slack admin).

Your solution #1, pairwise encryption, clearly doesn't scale for the sender
(as you point out). It is also aesthetically displeasing.

I feel like your solution #2, though, isn't what I would do, and I'm honestly
surprised that's how WhatsApp, etc. works.

My first thought is that a person who wants a shared room creates a
(symmetric) key K for the room, and then distributes K to all invited
participants privately. To remove a user you generate a new K for the room,
and send it to N-1 participants. They all agree to post using the new K (and a
signature).

I don't see a performance issue with this solution. Consider that _every_
message to the "room" causes O(N) fanout. If the rate of "normal" message
addition is _much less_ than the rate of participant addition/subtraction,
well, that's performant enough. (Especially considering a new key for the room
is some relatively small fixed size.)

(In a situation where you have a huge, passive audience and a single emitter,
then yes my proposal will generate a lot of extra unnecessary traffic as
people enter or leave. However, I'd argue that communication like this is
probably better secured through more traditional centrally controlled means,
e.g. a server process with ordinary user accounts that have a connection
status.)

EDIT: There _is_ a coordination problem with my solution, in that you can't
guarantee members will use the new K; it might be useful to have a bot or
something remind anyone who posts using the old K to use the new one instead.

~~~
ajconway
To distribute the new K you would need to encrypt it for each of the N-1 users
of the group. That's why we need trees.

~~~
javajosh
Ah, thanks. My mistake was assuming you could distribute new K as a normal
message, encrypted with old K. Clearly (now) this wont work since new K will
be distributed to everyone, including people who need to be omitted.

------
cetra3
Would just deriving a new pub/private key each time someone entered/left the
chat be simpler? I'm assuming there is a reason why this wouldn't work.

~~~
dsr_
Yes, much of the article is explaining why this is reasonable for a group of
2-5 and terrible for a group of 10,000, and ways to make this more manageable
in non-obvious ways.

~~~
cetra3
I'm talking about a shared private/public key for everyone which gets changed
when members leave or enter.

~~~
tialaramex
What are you imagining a "shared private/public key" is ? Because that's not a
thing.

A private key is _private_, it doesn't mean anything to share one of those, if
you're doing that it isn't a private key any more and you wasted your time.

~~~
thinkloop
They probably mean a single symmetric key shared between all. And private is
not mean that only one person knows a thing. Quite the opposite. If the entire
planet minus 1 person knows something, that's a form of private as well.
Either way you're arguing semantics.

------
peterhil
Balanced binary trees usually have some kind of rotations to maintain their
properties like left-leaningness. In this application this is to be avoided in
order to not not send so many messages.

I understood that all participating clients know about the structure of the
tree, so could not all the clients do the rotations in this kind of mass
removal without sending messages?

I mean that in the last example, the tree is not left leaning, but can be made
so by promoting every Zayne to their ancestor nodes.

~~~
doomrobo
Good point. I don't think it'd be unreasonable to promote everyone to their
parent in this example.

One thing that I left out of the post is that the MLS ratchet tree has
something called a "tree hash". Every node carries a hash digest, which is the
hash of its two children. The root node's hash is used to derive a bunch of
group-specific values, so it's important to keep this hash up to date. If you
promote every member to their parent, this would require about N log(N) total
hash operations, since every path from a leaf to the root would have to have
its hashes recalculated.

N log(N) hashes seems like a small price to pay for optimizing a structure
that determines how many ECDH operations you end up doing. I'll ask other MLS
people about this and see if I'm missing something.

