Hey all, I took the liberty of writing up this proposal and everything I've learned in more detail here: [1]https://gist.github.com/quinthar/44e1c4f63f84556a9822ebf274dc510a I'd really welcome any feedback or (constructive) criticism on it. Thanks! -david On Fri, Jan 29, 2021 at 11:42 AM David Barrett <[2]dbarrett@expensify.com> wrote: Wow, these are (mostly) great responses, and exactly what I was looking for. Thank you! To call out a couple responses: 6, the ratchet protocol produces a hash of previous messages that provides for detection of dropped data, among many other things. pgp does not do this. It feels like there are easier ways to detect dropped/tampered message, such as with an a simple accumulated hash of all past messages (or even a CBC mode). We do this with [3]https://bedrockdb.com/blockchain.html and it works great. However, I get your point that the double ratchet provides other benefits beyond just forward secrecy. Decryption of destroyed messages is a big thing that signal deters. Journalists can get seriously physically injured when that happens. Yes, I agree, it seems that forward secrecy is both 1) very valuable, 2) very hard to do, and 3) Signal's primary design goal. Re Signal and Javascript, Signal offers its code in a signed binary, and offers the source to that binary for anybody to build and check. Signal offers source, but given that it's distributing binaries via app stores, there's really no way to guarantee that the binary matches that source code. Open source is great (Expensify.cash is as well), but still requires that you trust the party giving you the binaries. They [Signal] have an automated system that gives their donated money to people who contribute improvements. Wait really? I'm not really finding that mentioned anywhere; can you link me to this? The FAQ doesn't really mention it, but it seems like this would be front and center: [4]https://support.signal.org/hc/en-us/articles/360007319831-Ho w-can-I-contribute-to-Signal- Arguably the simplest method is to do what you describe [encrypting every message with the recipient's public key]. However, public-key crypto produces a shared-number of ~256-4096 bits. If the message is longer than this, these shared-secret bits must be "stretched" without revealing the secret. This is why (nearly all) public-key crypto systems are paired with some symmetric cipher. I'd really love to learn more about this, as I think I almost understand it, but not quite. Can you elaborate on what you mean by "If the message is longer than this, these shared-secret bits must be "stretched" without revealing the secret." I get that any encryption (symmetric or otherwise) works on blocks, so to encrypt anything larger than one block requires splitting the input up into many blocks. And I get that there are concerns with accidentally revealing information by encrypting the same exact block back to back (ie, it reveals "the same block appeared twice", without revealing the actual block content itself). (More on all that here: [5]https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#C onfidentiality_only_modes) But I'm not quite understanding why you suggest that you couldn't just use a CBC strategy (where each block is derived from the block that preceded it) in conjunction with public key encryption to just encrypt every block with the recipient's public key, eliminating the need for the shared symmetric encryption key. Now, understand the performance advantages of symmetric over asymmetric encryption, and certainly the convenience (and bandwidth) advantages of having multiple parties all use the same key (ie, to avoid re-encrypting the same message separately for each recipient). But I don't see any actual security advantage to introducing the symmetric key (and arguably a disadvantage given the increased complexity it adds). Thanks for all these answers, I really appreciate them! -david On Tue, Jan 26, 2021 at 12:17 AM <[6]jamesd@echeque.com> wrote: On 2021-01-26 04:31, David Barrett wrote: > Yes, this does assume a central keyserver -- and I agree, it's possible > that it lies to you, establishing a connection with someone other than who > you requested (or even a man-in-the-middle). I don't know how to really > solve that for real without some out-of-band confirmation that the > public key returned by the keyserver (whether centralized or distributed) > matches the public key of the person you want to talk to. Jitsi's solution works. It is the much studied reliable broadcast problem, which is a hard but much studied problem, with a bunch of hard to understand solutions, which nonetheless work. > I think you are saying that performance isn't a real world concern, but > forward secrecy is? If so, that makes sense. Yes. Ristretto25519 shared secret construction (using asymmetric cryptography to construct a shared secret that is then used in symmetric cryptography) takes 2.5 microseconds on my computer running unoptimized debug code. For forward secrecy, you need to construct two secrets, one from the transient key and one from some mingling of the permanent key with the transient key, which takes 5 microseconds. And you then use the authenticated shared secret for the rest of the session. References 1. https://gist.github.com/quinthar/44e1c4f63f84556a9822ebf274dc510a 2. mailto:dbarrett@expensify.com 3. https://bedrockdb.com/blockchain.html 4. https://support.signal.org/hc/en-us/articles/360007319831-How-can-I-contribute-to-Signal- 5. https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Confidentiality_only_modes 6. mailto:jamesd@echeque.com