Support custom hash functions in ECDH API #352

issue Kagami openend this issue on November 5, 2015
  1. Kagami commented at 1:09 pm on November 5, 2015: none

    Current ECDH implementation always hashes both Px and Py of point multiplication result with SHA256. It makes impossible to use secp256k1 with existing protocols like Bitmessage which uses SHA512(Px) as shared secret. As mentioned here, possible solution for this is to accept custom hash function in API similar to custom nonce function.

    cc @apoelstra

  2. fanatid cross-referenced this on Nov 12, 2015 from issue [ECDH API change] Support custom hash function by fanatid
  3. peterdettman commented at 5:56 am on November 13, 2015: contributor

    It seems to me that a major reason for handling the hash internally was to avoid “revealing” the raw point coordinate(s). Supporting a (callback-based) custom hash function lets them “escape” again (even if the callback is isolated somehow, it could still calculate a no-op of the input).

    So it seems to me that internal hashing with a customisable hash function is a needless complication. Of course, if you’re restricted to SHA256, you can’t use this even for what should be an obvious target - TLS key exchange.

    I propose we abandon the internal hashing approach altogether.

  4. gmaxwell commented at 6:31 am on November 13, 2015: contributor

    @peterdettman We are not trying to avoid revealing anything, but rather not provide interfaces that by that we know will primarily be used in less safe ways because using it that way is the simplest thing possible.

    [Because of things like http://lists.linuxfoundation.org/pipermail/bitcoin-dev/2014-March/004720.html (see also later posts where I gave some more attacks) I wish we didn’t have a reason to expose ECDH at all, in favor of safe higher level constructs– e.g. ECIES instead of “here is ecdh then you can makeup your own crypto scheme”, because we should assume that the caller is not a subject matter expert in cryptography whos work is being reviewed by other subject matter experts– but thats not always the best trade-off.. and sometimes we have to expose more to get functionality. But the interface can still encourage more prudent behavior.]

    An example of this is how we handle DSA nonces. By default the library uses RFC6979 internally. But if you need to do something special, you can send in a callback that implements whatever you need– upto and including “emits a constant nonce”. :) So the caller can do whatever they like, but if they do something dangerous or inadvisable at least it wasn’t because it was the easiest thing to do (or worse, the only obvious thing to do).

    for this PR, I think it’s a good approach; we’ll probably want to change the api; I’ve just been too slammed this week to give it a proper review yet. :)

  5. peterdettman commented at 10:44 am on November 13, 2015: contributor

    @gmaxwell OK, that’s reasonable, although I think the argument is a bit weaker than for the ECDSA/RFC6979 case.

    I will observe that I think the “no-op escape hatch” will be the method of choice for a TLS implementation. There are several different key exchange methods each producing a premaster secret after their own fashion, then a distinct master secret generation via the TLS PRF. I would expect most implementations to have a module boundary between those two things - even if an implementation only supports ECDH(E), but uses other libraries for other curves.

    Switching to constructive suggestions mode:

    • Change terminology from “hash function” to “KDF”
    • Make provision for “shared info” input to the KDF via the callback - and if present, use it in the default implementation.
    • I would still like to see an x-only option, since that is a common case (e.g. TLS) with potentially better performance.
  6. gmaxwell commented at 10:10 pm on November 13, 2015: contributor
    I agree on these constructive suggestions. I’m pondering how to best handle x-only via this. It could query the callback and ask “do you need y”? and then it could internally use an x-only implementation if not.
  7. Kagami commented at 10:15 pm on November 13, 2015: none

    I’m pondering how to best handle x-only via this

    Just add secp256k1_ecdh_xonly function/one more argument to secp256k1_ecdh?

  8. gmaxwell commented at 10:24 pm on November 13, 2015: contributor
    I would not like to expose an xonly ecdh ultimately, thats an internal implementation detail, largely.
  9. peterdettman commented at 1:41 am on November 14, 2015: contributor
    Since we need to know (x-only output)? right at the start (to avoid slow compressed input -> x/y output case), I would expect the output format to just be specified in an argument to the ecdh method itself.
  10. sipa commented at 8:59 pm on November 17, 2015: contributor
    If you look at the resulting solution here, it looks pretty silly: you’re passing in a function that process the output of ECDH, and then directly return that. I do agree that it follows the “safe to use by default” principle, but it does look a bit overly complex.
  11. apoelstra commented at 9:43 pm on November 17, 2015: contributor

    @sipa I wonder if we should have a function secp256k1_unsafe_ecdh_inner function that returns the raw output, and have the normal ECDH function be a thin wrapper around that that does the hash?

    That is, replace the function pointer with a scary name.

  12. fanatid cross-referenced this on Jan 10, 2016 from issue v3.0.0 by fanatid
  13. wanderer cross-referenced this on Jan 20, 2016 from issue Uses native ECDH implementation by wanderer
  14. fanatid commented at 2:15 pm on February 2, 2016: contributor
    Any progress with this issue? I agree with @apoelstra (secp256k1_unsafe_ecdh_inner + secp256k1_ecdh) and ready for creating PR if you support ecdh function with raw output.
  15. sipa commented at 3:18 pm on February 2, 2016: contributor
    Sorry for the delay, I was working on other things. Will look soon.
  16. axic commented at 2:33 pm on April 22, 2016: none

    To summarise some of the current ECDH uses:

    • Bitcoin (sha256(v+Px))
    • Bitmessage (sha512(Px))
    • Ethereum (nisp_sp800_56a_kdf(Px+Py) since it uses uncompressed keys only)
    • TLS

    There are perhaps other schemes.

    The two proposed solutions are: a) secp256k1_edch to accept a hash callback function b) to have the non-hashing inner function exported as secp256k1_unsafe_ecdh_inner

    The problem with a) is that the callback could just return the unmodified vanilla input. Though secp256k1_ecdh could check and reject if the input equals the output, that wouldn’t stop the case when a slightly modified, but still unsafe data is returned.

    Another option, c) was so far not mentioned: to include the hashing for the common schemes (the four stated above). This has the drawback that it will take effort and time to implement all the new schemes which are deemed useful, increases code size and possibly has bigger maintenance burden. The positive aspect is that raw keys are not leaked. I am not convinced this single positive aspect justifies this option. @sipa did you had a chance to look at the options and perhaps @fanatid’s PR #354?

  17. apoelstra commented at 4:07 pm on April 26, 2016: contributor
    @axic I really don’t think we should explicitly support common schemes. This is not scalable, increases our maintenance burden, and would also require we cryptanalyze those schemes to ensure we aren’t explicitly endorsing anything we don’t believe to be safe.
  18. fanatid commented at 4:24 pm on May 4, 2016: contributor
    I wrote ecdhUnsafe for JavaScript secp256k1 bindings. Are you merge PR with such changes?
  19. fanatid cross-referenced this on May 11, 2016 from issue Expose libsecp256k1's sha256 function by chjj
  20. fanatid cross-referenced this on Mar 10, 2017 from issue ECDH: output compressed point by chfast
  21. chfast commented at 1:44 pm on March 10, 2017: none

    I accidentally implemented b) in #446 with name secp256k1_ecdh_raw.

    And I think Ethereum takes only Px.

  22. sipa commented at 6:14 am on March 12, 2017: contributor
    @fanatid I’d be fine with that.
  23. sipa referenced this in commit 1086fda4c1 on Oct 17, 2018
  24. arkpar cross-referenced this on Nov 8, 2018 from issue Use upstream rust-secp256k1 by dvdplm
  25. jonasnick cross-referenced this on Oct 7, 2019 from issue Review if ECDH is still experimental by ysangkok
  26. apoelstra commented at 5:27 pm on October 11, 2019: contributor
    Was this supposed to be closed by #354?
  27. jonasnick commented at 5:46 pm on October 11, 2019: contributor
    That’s what it looks like.
  28. jonasnick closed this on Oct 11, 2019

  29. arnetheduck cross-referenced this on Apr 15, 2020 from issue Use custom hash function for eth1 ecdh by arnetheduck

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin-core/secp256k1. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-22 16:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me