FWIW, I quickly looked at pbp [python? hate-hate-hate], it apparently has nearly same design defect: it uses long-term curve25519 keypair for message encryption. Unlike pcp, it does not include sender identification in message, receiver must try all public keys in her keyring. Which have advantage of not leaking sender identity to eavesdropper, but waste a lot of CPU on receiver side (as your keyring grows), and receiver also cannot search sender identity by keyid on [hypothetical] keyserver. NIH, NIH, NIH. Thomas von Dein wrote:
On Wed, Jan 15, 2014 at 04:29:44PM +0400, Yuriy Kaminskiy wrote:
Well, the libsodium developers not only told me how to do it, it was their idea. However, it's of course very simple to generate them separate. It is *possible* to use same RSA keypair for encryption and signing (and earlier pgp versions used to that). Does not mean it is *good idea* (and newer openpgp/gnupg switched to use separate keys for signing/encryption/certificate signing purposes, by subkeys mechanism).
We're not talking about RSA, do we?
Nearly same consideration apply to both?
(For DH/DSA it is even worse, you *can* reuse same keypair, but this leads to leak of secret key material. I'm not sure if same leak scenario apply to ECDH[curve25519]/EdDSA[ed25519], but better safe than sorry. And keypair reuse is bad from operational security pov anyway).
As I alredy said, it's no problem to have separate keyspairs for signing and encrypting, just a couple of lines to change.
1) Recipient needs to know sender public key. Bad. [clarification: sender *long-term* public key; of course, receiver needs to know public key that was used for message encryption; but this key need not be same with sender *long-term* key]
That's the way curve25519 works. It would be possible to use one time keys but for this there has to be some kind of key exchange process before. But since pcp runs in offline mode, I'm not sure how to do this in a user friendly way. I explained: include (single-use) public key in message, in place of "hash of sender key id").
Ok, let me formulate it better: I can use a single-use keypair on the sender's side and include the public part in the message. Cool. But the sender would nevertheless need a public key from the recipient. This one has to be from a long-term key, since we're operating in a
Well, yes. If you want to send message to someone, you need to obtain her (current/longterm) public key first, and you need verify it somehow (in-person exchange, web-of-trust, CA signature, etc; in case ephemeral encryption key, it should be signed by verified long-term identity key), otherwise you are vulnerable to MITM. I don't see any way around it.
store-and-forward environment. But it doesn't make sense to use a single-use key only on one side of the communication, does it?
Hmm? You cannot fix (1), (2), (3), (4) without using single-use keypair by sender side. So, of course, it makes sense. Single-use keypair on receiver side would be nice (PFS!), but it is not possible in store-and-forward.
As a sidenote, in pcp it's possible to generate a keypair for one recipient (it's derived from the long-term keypair), so you'd at least have one keypair per peer. But it's unclear to me, how to use single-use keys on both sides of a communication in a store-and-forward environment. Any hints?
I'm not sure how are they useful? (Once you use per-message keypairs, that is.)
2) Message remains decipherable by sender. Very bad. No, it doesn't. In order to decrypt a message one needs the recipient secret key and the sender public key. Yes, it does. With your protocol, message can be alternatively deciphered with crypto_open_box(c, n, sender_public_key, receiver_secret_key); (by receiver, good) or, alternatively, with crypto_open_box(c, n, receiver_public_key, sender_secret_key); (by sender, *BAD*).
Really? I'll try it, but if this is the case, then it's bad indeed.
That's how (any) DH works? You generate common secret from one side public key and other side private key?
With openpgp (and with my suggested change), sender does not retain secret key used for message encryption, and thus cannot decipher his own message.
Yea, I see.
Incorrect. This is NOT daily business with pgp. Openpgp does not use long-term sender keypair when it encrypt message (otherwise, how could you encrypt message without using passphrase?) and does not leak sender keyid (/by default/ gnupg leaks /recipient/ keyid, but it can be disabled with --hidden-recipient).
ok, got it.
DJB has nothing to do with your self-invented protocol. DJB invented bending tool. *You* decided to use it to make square wheels.
Come on, have a heart. The only thing I "invented", was how to store keys and encrypted files. It's just a fun project in it's early stages and everything can be changed. And I'm really glad when someone points out some errors I made.
P.S. there were thing that openpgp did horrible wrong: keyids (they are harmful and useless crap). Funnily, you repeated their misdesign.
Well, to be fair, openpgp standard had several edition, was reviewed by many people, etc, and still managed to get it wrong. Earlier versions of pgp also did a lot things wrong. Etc. SSL/TLS history is also full of mistakes, some fixed by newer version, some still remains (EtM), some even added by newer versions (cleartext SNI). It is not easy to mess up with crypto - it is /extremely/ easy :-( And that's why it is important to point out at mistakes early on, without any mercy :-)
ok, really got it.
PPS === cut platform.h === #ifndef HAVE_ARC4RANDOM_BUF // shitty OS. we're using libsodium's implementation === cut === LOL, I'm glad I'm on "shitty OS"; well, not quite (e.g. openbsd recently switched arc4random from rc4 to chacha); but I'd bet there are quite some "by- this-definition-non-shitty-OS" that 1) has arc4random_buf; 2) still uses RC4 under the hood. Then again, while rc4 is considered somewhat flaky, but it is not completely broken (yet), and still in wide use, so it is not *terrible* big deal. But DJB will frown on you, LOL.