otrv4 / otrv4

Off-the-Record Messaging Protocol version 4. -This is a draft- This repository is a mirror of http://bugs.otr.im/otrv4/otrv4

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why XSalsa20?

sebastianv89 opened this issue · comments

OTRv4 uses XSalsa20 for encryption, which seems like a strange choice to me.

The idea behind the double ratchet is that every message gets associated with a unique message key. The idea behind XSalsa20 (compared to Salsa20) is that we have larger nonces so that we can use random nonces without worrying about collisions when encrypting with the same key. In fact, when we have unique keys for every message we can do without a nonce (or equivalent: set the nonce to zero). Alternatively a random-looking nonce can be derived from the chain-key (which is what Signal does). Either solution has the benefit that there is no more need to send the nonce in the data message, giving smaller messages.

Getting rid of the random nonces also means that XSalsa20 can be replaced with Salsa20 (or even ChaCha20) which is more efficient, has seen more rigorous attempts at cryptanalysis and is more widely available in cryptographic libraries.

Hi, Sebastian,

Thanks for your question.

So, around why XSalsa20: we first wanted a bigger block size as compared with AES block size of 128 bits. We also wanted it because it is faster than AES and immune to timing attacks.

I agree that the nonce can be derived from the chain keys (in the past, we had the proposal of deriving it from one of the values in the ring signature for some messages). We decided to always have it generated randomly.

I will not feel comfortable with replacing with with Salsa20. XSalsa20 has exactly the same streaming
speed as Salsa20, and its extra nonce-setup cost is slightly smaller than the cost of generating one block of Salsa20 output. But we can maybe replace it for ChaCha20. Give me a few days to think about this :)

Thanks!

As @claucece mentions, the main rationale for XSalsa20 over Salsa20 was to keep the block size consistent with the rest of the security levels in the system. We decided on XSalsa20 over ChaCha20 for two reasons - there were no X-variety of ChaCha20 defined when we made the decision, and Salsa had received significantly more cryptanalysis at the time. There now seems to exist an XChaCha20 version available. Would you say it's worth to make the change to XChaCha20? Does our rationale for using the X varieties make sense?

Deriving the nonce from the chain seems like a nice improvement, and something we should probably do, in my opinion.

As @claucece mentions, the main rationale for XSalsa20 over Salsa20 was to keep the block size consistent with the rest of the security levels in the system. We decided on XSalsa20 over ChaCha20 for two reasons - there were no X-variety of ChaCha20 defined when we made the decision, and Salsa had received significantly more cryptanalysis at the time. There now seems to exist an XChaCha20 version available. Would you say it's worth to make the change to XChaCha20? Does our rationale for using the X varieties make sense?

You mention block size, but the Salsa and ChaCha ciphers are stream ciphers so I'm confused as to what exactly you are referring to here? I am guessing here that you are referring to the internal state of the keystream bits, but then there is no difference between the regular and X-varieties, as for both Salsa20 and XSalsa20 the keystream bits are generated in 512 bit blocks. The only difference is the way that these values are initialized.

As for the Salsa vs ChaCha choice: these designs are very similar so I don't think it matters too much from a cryptographic perspective (and similarly the difference in performance is most likely not significant). From a practical perspective however I do believe that ChaCha is more widely available so that could be a reason to switch.

Deriving the nonce from the chain seems like a nice improvement, and something we should probably do, in my opinion.

Fair enough. It's possible that we mixed up things with the nonce size. So from that perspective, I'd be fine with moving to regular ChaCha20 - and deriving the nonce from the chain key.

You mention block size, but the Salsa and ChaCha ciphers are stream ciphers so I'm confused as to what exactly you are referring to here? I am guessing here that you are referring to the internal state of the keystream bits, but then there is no difference between the regular and X-varieties, as for both Salsa20 and XSalsa20 the keystream bits are generated in 512 bit blocks. The only difference is the way that these values are initialized.

Yes, precisely. In that sense Salsa20 and XSalsa20 are the equal.

I will do want to check if the bigger nonce is needed. I assume not; but I want to check.

We decided to go for Chacha20 :) I'll make the appropriate changes.

Ok... after choosing, we have realized something. There are 'two' Chacha20:

  1. The one defined by Bernstein that has a 64-bit nonce and a 64-bit block count.
  2. The one defined by RFC7539 that has a 96-bit nonce and a 32-bit block count.

The reason why RFC7539 decided to go that way was to be more consistent with recommendations in Section 3.2 of RFC5116, regarding nonce usage.

In the C world:

  • Libsodium has both variants.
  • Libgcrypt has RFC variant.
  • OpenSSL has djb one.

In Golang world:

  • The XCrypto one only provides the RFC variant.

We don't need the safety for the nonce, therefore choosing djb one makes sense. But we are concerned on how widely available in other programming languages is Chacha20 of the RFC7539.

@sebastianv89 @letoams do you have any thoughts?

I would expect any new use in protocols to be based on the RFC one.

I agree on this. @olabini ?

Yep, let's go with the RFC version.

Incorporated :) The nonce is set to 0.