agl / pond

Pond
BSD 3-Clause "New" or "Revised" License
911 stars 109 forks source link

Create fingerprint() method and display its results #147

Closed burdges closed 9 years ago

burdges commented 9 years ago

Fingerprints are meant be safer than actual public keys to display publicly on sites like github or twitter.

This adds a simple fingerprint() method to both the client and Contact structs that computes the SHA-256 of the public identity key. We display this fingerprint() method's results ahead of the public identity key and public key in showContact for both the GUI and CLI as well as showIdentity (CLI) and identityUI (GUI). In addition, the other identity information fields are reordered to be more consistent between the CLI and GUI.

We should perhaps add a seed to the fingerprint() method, but I'll defer to others on that issue since doing so may require modifying both client/disk/clinet.proto and protos/pond.proto, and SHA-256 is very strong.

burdges commented 9 years ago

After considering this more deeply, I'm worried that users displaying even the fingerprint created here could turn their identity key into a "selector" that it facilitates associating them with their pond account.

I haven't looked into the equivalence between Curve25519 and Ed25519 to see if the other key could be used, but that probably won't work either. In any case, we could probably untie the relationship between a user's two public key pairs by generating them separately, right?

Another option for users who wish to publicly declare a way to verify their pond account might be to use fingerprint of another key that never touches the server, such as the RSA idea discussed here https://github.com/agl/pond/issues/142

burdges commented 9 years ago

There is actually a sha512 operation in that conversion from Ed25519 to Curve25519 private keys at because Ed25519's public key is built using sha512. You cannot drive a users original private key from their identity private key by a sha512 assumption.

There is an important relationship between a user's original Ed25519 public key and their identity Curve25519 private key though. I believe the server cannot derive a user's original Ed25519 public key from the Curve25519 public key it knows, modulo standard assumptions about Curve25519, but this bears some scrutiny. Assuming this holds, we should use their original Ed25519 public key when making the fingerprint. And I'll add a patch to that effect here.

As an aside, we should also verify that users cannot impersonate their contacts to the server by going the other direction and deriving the identity Curve25519 private key from the original Ed25519 public key, presumably due to this, again modulo standard assumptions about Curve25519. Anyone got a citation for this stuff handy?

burdges commented 9 years ago

I'm relatively happy that users cannot impersonate their contacts to the server, based upon this ScalarBaseMult operation being difficult to reverse.

I'm still not confident the server cannot reverse this edwardsToMontgomeryX operation. I'll push the fix to this pull request, but I'm still not confident this pull request creates a fingerprint which cannot identify pond users on the server.

I'll write a test for this fingerprint if we can conclude that's it's actually correct cryptographically.

burdges commented 9 years ago

Alright, I actually looked at the edwardsToMontgomeryX function in detail. It's using operations in the underlying field, not the Elliptic curve, so generically Y = (u-1)/(u+1) computes the inverse function quickly.

This means that even my refined fingerprint operation reveals a user's identity key on the server, making it unsuitable as a fingerprint.

We should instead create a secondary key that identifies users to one another only, perhaps a huge RSA key as I proposed in https://github.com/agl/pond/issues/142

burdges commented 9 years ago

I'm closing this pull request and replacing it with https://github.com/agl/pond/pull/151