ipfs-rust / quinn-noise

Noise handshake for the quinn quic implementation.
20 stars 5 forks source link

get a second opinion from a cryptographer #1

Open dvc94ch opened 3 years ago

dvc94ch commented 3 years ago

some things that could make people shiver:

  1. reuse of ed25519 keys for dh
  2. use of experimental xoodyak construction
  3. use of only 8 rounds of chacha
  4. stuff I haven't though of

strongest arguments why it's ok:

  1. signal does it too [0]
  2. it's a NIST light weight crypto finalist based on keccak and designed by the keccak team [1]
  3. suggested in too much crypto [2]
  4. how should I know?
dvc94ch commented 3 years ago

@burdges @tarcieri any comments? :)

burdges commented 3 years ago

I'd think ed25519 keys being reused for DH hinges upon shared secret leakage. It's fine if you run DH shared secrets through a reasonable KDFs and then use them in ciphers and MACs. VRFs have a different leakage profile, again surely fine but less transparent. PAKEs who knows.

Avoid reusing "blockchain" account keys for transport layer keys of course. "Soft" HDKH messes up many things. And ed235519 has especially problematic HDKD proposals.

I've never looked into xoodyak before, so no idea. I've not paid overly close attention the "too much crypto" discussion, but I'm curious about the ChaCha security levels myself.

I'd look further into the specific assurances provided by specific noise handshakes. It's likely fine but even AGL made a mistake in the initial crypto for QUIC.

We're all de facto using Noise with certificate-like constructions, but provided asynchronously which does not bind them into the channel, and makes authentication properties messy or weaker. I'd expect proof-of-stake blockchains mostly lack back certificates too, no immediate threats, but messes later.

dvc94ch commented 3 years ago

I'd think ed25519 keys being reused for DH hinges upon shared secret leakage. It's fine if you run DH shared secrets through a reasonable KDFs and then use them in ciphers and MACs.

So the reason this is done in the first place is because PeerId's in libp2p only encode the signing public key. If a PeerId where to also include an encryption public key we could have 0-rtt without key reuse. [0] seems to imply that there might also be a risk that someone being able to forge signatures. But my brother who has a bachelor in mathematics said that the proofs only apply to prime order groups. Would schnorrkel considerably lessen the risk of leakage?

I also don't fully understand how using a KDF would help. If an attacker can find the shared secret using signatures and other shared secrets, wouldn't the person I'm communicating with have that information and be able to attack other communication channels with third parties? So anyone can harvest an unlimited number of shared secrets by generating a keypair and opening a communication channel.

burdges commented 3 years ago

I've not read [0] in detail, but it argues security for an ECIES like Noise combined with an EC-Schnorr like Ed25519.

We treat the Ed25519 curve as an implementation detail of a prime order group in which DDH is hard, or even GGM. We do create problems by exposing that Ed25519 has cofactor 8, but not quite like this.

An KDF isolates the shared secret, so then xoodyak or chacha8 being broken risks less.

As I indicated above, your first question should be with what other protocols does one use these keys? Articles like [0] do not exist for most combinations.

Are PeerId signing keys ever threshold for example? You abandon the KDF in naively threshold ECIES so threshold ECIES clearly breaks a related key used for threshold VRFs. Does Signal uses VRFs somewhere? I think threshold ECIES looks under explored overall, so best avoided.

dvc94ch commented 3 years ago

I think it's making a bit more sense to me now, thanks.

So the KDF helps prevents a third party impersonating someone in a different protocol, but since (assuming xoodyak or chacha8 is broken) they have the result of the shared secret after the KDF was applied, wouldn't prevent it from happening in this protocol.

NOTE: this "construction" was taken from the xoodyak submission directly [0] section 3.3 authenticated encryption with a common secret which seems to imply that it's intended to be used in this way.

While it may be ok to sign and dh using the same key, it's certainly a bad idea to use it in other protocols too like VRF or threshold signatures. I'll add a disclaimer for that. In libp2p the signing key is used to sign gossip messages (as they may go through multiple hops) and I think dht records. But as far as I'm aware it's all very "boring" cryptography wise.

NOTE: added a disclaimer to README

burdges commented 3 years ago

There are some advantages to using one key, like fewer certificates and proofs-of-knowledge.

In theory, there exist implicit certificate constructions via which a 64 byte PeerId could provide an Ed25519 signing key, provide a different Ed25519/X25519 DH key, and at time of use implicitly certify the DH key from the signing key and prove knowledge of both. It'd save 64 bytes since you require 128 bytes to give two keys and certify the DH key naively. I'm afraid their existing security arguments are basically garbage however, so just assume nobody analyzed them. And certainly nobody studied how they interact with anything else. I'd explore this direction if I cared about threshold ECIES for some reason since I'm unsure if threshold ECIES is even secure in the first place.

Yes, I'd think one key for this case, but warn people against using it for other purposes. It's p2p though and blockchain people fuck up everything. :)