jedisct1 / libsodium

A modern, portable, easy to use crypto library.
https://libsodium.org
Other
12.26k stars 1.74k forks source link

Feature request: *25519 canonicalized keys #684

Closed mumbleskates closed 6 years ago

mumbleskates commented 6 years ago

I am developing an application that needs to determine equivalency between given keys* for Ed25519 and X25519 (Curve25519).

* To clarify, keys of the exact same type, as in the equivalency of two X25519 secret keys with different values in the 3 least significant bits that are cleared later on when the key is used.

Reading through rfc7748 and rfc8032 and various specifically related issues, it is clear that this is a nuanced and non-trivial operation influenced by:

  1. intentionally ignored bits in the key data in the 32 byte formats for Ed25519 and X25519 pk and sk values
  2. the handful of "small-order" curve points
  3. and keys where the represented value is greater than the order of the curve (i.e., 2**255-1 reduces to 18 in the *25519 prime field).

It also seems that there have at least historically been differences in the rejection-vs-reduction standard behavior between X25519 and Ed25519 regarding the last item.

Ideally, I would like there to be a public API within libsodium for obtaining the canonical form of Ed25519 & X25519 public & secret keys, as already interpreted by the signing & kex APIs, only and always rejecting the input keys when those APIs would have done so.

I would find this desirable because it would allow determining when a key has already been blacklisted (in an alternative representation) or when a secret key matching a given active public key has been published, without either

  1. adding an extra-ordinary (and disadvantageous) requirement that all keys must be represented in canonical form, or
  2. implementing this functionality myself and requiring that future ports of the protocol implement it as well.

Edit: My immediate concern is with the *25519 schemes, which are the only schemes currently exposed by libsodium that have these issues as far as I'm aware. I do think that having amenities for canonicalizing keys in other schemes as a precedent is a natural extension of this idea, with sufficient warnings against overuse of the functions (key distinguishability in mind).

jedisct1 commented 6 years ago

Hi,

I understand that adding these APIs would be useful to your specific use case. But the purpose of this library is to solve common problems only. It is not a low-level cryptographic toolbox.

Adding functions that very few people will eventually use would only add bloat, and confusion to people new to cryptography and to the library. They will require work from maintainers, for very little benefits to the community as a whole.

Look at Libhydrogen to see the direction is being taken, and what libsodium 2 will resemble to. Primitives are not exposed any more, so neither are implementation details nor internal representations.

I am awfully sorry, but the current libsodium API has already become way too bloated for its original goal. At this point, only things that solve common problems that can't be solved using the current APIs can reasonably be implemented.

jedisct1 commented 6 years ago

Also, for X25519, you can perform a multiplication with a dummy scalar to check a public key.

For Ed25519, the crypto_core_ed25519_is_valid_point() function is already available in the public API.

mumbleskates commented 6 years ago

Understandable, thanks for the info. I had a suspicion this was the philosophy, and I have no problem with it. I should be able to wrangle some functionality out of this that I can test against basic operations.

Thanks for the quick response and great tools as always.