indutny / elliptic

Fast Elliptic Curve Cryptography in plain javascript
1.7k stars 379 forks source link

Feature: Schnorr signatures #208

Open junderw opened 4 years ago

junderw commented 4 years ago

Taproot and related Bitcoin protocols will require Schnorr signing.

  1. Are there plans to work on it?
  2. If no plans, I would like to work on it. Would anyone consider helping me by reviewing such a PR? (and helping me overhaul my code if needed)

Thanks, Jon (BitcoinJS)

CC: @fanatid

fanatid commented 4 years ago

Hi Jonathan, as I understand Schnorr signing will be added back to bitcoin-core/secp256k1 as module? Currently I work on fanatid/fcrypto -- bindings (n-api) & wasm based on bitcoin-core/secp256k1, if this will include Schnorr signing in future, do you still need it in elliptic?

junderw commented 4 years ago

TBH I would love to remove the dependency of native JS and have all crypto operations be through WASM, but a few things:

  1. BitcoinJS sometimes gets users complaining about const and let... meaning they use ES5 and probably are wanting to support browsers lost in the stone age. (Though I think dropping those browsers should be fine, many people might not want that.)
  2. WASM is still fairly new. And I am fairly new to WASM too.

fcrypto sounds like a good way to include Schnorr into BitcoinJS though... we might need to rework the API a bit to handle async loading... I was thinking v6 might contain some early experimental Taproot schemes as Payment APIs.

But I still think that Schnorr would be useful in Native JS for old browser support.

fanatid commented 4 years ago

we might need to rework the API a bit to handle async loading...

Yeah, I'm not sure that what I have now is the best, but I this is just early stage. I even would not like announce it, but you create the issue :laughing:

Browsers from stone age... it's should be possible convert wasm to asm.js, but performance and overall? Not sure about it, but this can be option.

junderw commented 4 years ago

I think for now we will:

  1. Implement Schnorr in elliptic following BIP340 Schnorr spec
  2. Implement necessary functions in C++ addon and native JS (using elliptic implementation from 1) in tiny-secp256k1 library
  3. Decide how to deal with two signature types with the ECPair, BIP32 classes, as well as the Signer , HDSigner interfaces. And implement them.

Moving forward, WASM is definitely something we want to use. But for now the cost of catching up with and updating the library to utilize the newest WASM developments seems like too much of a commitment at this point.

So I will move forward with implementing in elliptic.

Looking at the secp256k1 pull request, these are the things I will need to implement: (explained in BIP340)

  1. Nonce generation function for Schnorr
  2. XOnly pubkey encoding (32 byte pubkey encoding)
  3. Schnorr sign and Schnorr verify

@indutny maybe you only want 3? I could move 2 and 1 downstream to tiny-secp256k1, but 2 might be useful.

Just keep me updated on what you want, and I should have a preliminary PR up by next week.

junderw commented 4 years ago

Looking into it more TaggedHash is also needed in order to implement... Perhaps this should all be implemented in tiny-secp256k1........... or make a separate module...

junderw commented 3 years ago

@fanatid I am going to move forward with taproot implementation.

  1. JS implementation
  2. C++ addon implementation
  3. bitcoinjs-lib implementation

If you have any time to work on this we should coordinate.

Thanks.