Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Elligator for indistinguishable public key #137

Open
Gowee opened this issue Sep 6, 2022 · 3 comments
Open

Elligator for indistinguishable public key #137

Gowee opened this issue Sep 6, 2022 · 3 comments

Comments

@Gowee
Copy link

Gowee commented Sep 6, 2022

Hi.

Thanks for this great project.

As noise and snow are famous for providing excellent security guarantees while requiring few efforts to adopt, I am trying to use snow in my (yet another) proxy tool (prototype) which aims at circumventing Internet censorship. I start with Noise_NNpsk0_25519_ChaChaPoly_BLAKE2s as it looks pretty straightforward.

But then I realize that, in initial handshake messages, public keys (e of -> psk, e, e of <- e, ee in my case) are sent as plaintext, which leaves opportunities for an eavesdropper to distinguish a handshake from a uniform random byte string. As noted in the spec §10.5, elligator could be used to generate/encode public keys that are indistinguishable from random bytes.

Is there any plan to support it in the future?

@mcginty
Copy link
Owner

mcginty commented Sep 12, 2022

Hey @Gowee,

Yes, support for Elligator could be added (or possibly just adding "codec" functions to the keys being transmitted over the wire so folks could take control of it themselves, as it's not an official part of the Noise framework).

How far along on your project are you, and do you have any ideas on how you'd like to see it implemented?

@Gowee
Copy link
Author

Gowee commented Sep 30, 2022

Hi, @mcginty.

It is here: https://github.com/Gowee/noisy-shuttle. A just-working prototype for now.

Considering that handshake messages are written out as opaque bytes instead of structs, I think a "codec" function (Fn(&[u8; 32]) -> [u8; 32] ?) would be straightforward. (Or is there an alternative way to get handshake messages as structured? Say, something like, struct Psk_E { pubkey: [u8; 32], aead_tag: [u8; 16] } ?)

@SnowyCoder
Copy link

I'm trying to create a proof of concept using Elligator, here are some exploratory notes:

To really provide a bitstream indistinguishable from random numbers, you should have a key that has also a random low-order component, there are ways to add and remove it, but since the low-order component is cleared when performing a DH operation, I would suggest to use it only with ephemeral keys:

Ephemeral keys don't have to be checked for authenticity, so even if they get randomized, they shouldn't be used for any other purpose than to just get an ephemeral DH value. This way static keys won't get Elligator-encoded, it should not be a problem unless static keys get sent unencrypted (Immediate Handshakes), and those have no identity hiding anyways.
The problem with this path is that key generation, encoding and decoding needs to be splitted, so code complexity will need to be Handled by the CryptoResolver/Dh traits and implementation.

Also, the feature will only be compatible with backends that support Elligator2 forward and reverse mapping (no backend has it for now, I'm working on a curve25519-dalek fork).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants