Implement Schnorr signatures #212
pull sipa wants to merge 1 commits into bitcoin-core:master from sipa:schnorr3 changing 14 files +946 −13-
sipa commented at 0:36 am on February 13, 2015: contributor
-
sipa renamed this:
Implement Schnorr signatures + batch verification
[WIP] Implement Schnorr signatures + batch verification
on Feb 13, 2015 -
sipa force-pushed on Mar 2, 2015
-
sipa commented at 10:29 am on March 2, 2015: contributorRebased.
-
sipa force-pushed on Mar 2, 2015
-
sipa force-pushed on Apr 23, 2015
-
sipa commented at 9:11 am on April 23, 2015: contributorRebased.
-
sipa commented at 9:11 am on April 23, 2015: contributorTODO: use context to store the batch multipliers
-
dcousens commented at 1:57 am on April 27, 2015: contributor
This is awesome, as Schnorr signatures are dead easy to understand. But, for what purpose have they been added?
(just curious)
-
sipa commented at 7:24 am on April 27, 2015: contributorThey have not been added yet :)
-
sipa force-pushed on May 1, 2015
-
evoskuil cross-referenced this on May 12, 2015 from issue Tracking: Implications of Schnorr patent expiration. by evoskuil
-
sipa force-pushed on Jun 22, 2015
-
sipa force-pushed on Jun 22, 2015
-
sipa renamed this:
[WIP] Implement Schnorr signatures + batch verification
Implement Schnorr signatures
on Jun 22, 2015 -
sipa commented at 4:06 pm on June 22, 2015: contributor
Separated batch validation into a separate branch. This pull request should be usable. Question for reviewers:
- Enable Schnorr code by default, or hide behind a compile flag (and perhaps move to a separate include/.h file)?
-
sipa force-pushed on Jun 25, 2015
-
sipa force-pushed on Jul 1, 2015
-
apoelstra commented at 6:31 pm on July 1, 2015: contributor
I’m a bit concerned about using
secp256k1_nonce_function_default
. If you sign the same message in both ECDSA and Schnorr with the same nonce, it is possible to recover the secret key from the two signatures. So I think by default Schnorr should use a slightly different noncegen function.Edit: Oh, I’m being stupid, in Schnorr the messagehash has
R
inside of it while with ECDSA it does not. So you’d have to do this very deliberately.Edit2: No, I was right the first time :). Regardless of message-hash, two signatures with the same key/nonce represent two equations in two unknowns.
-
in src/schnorr_impl.h: in 71d3db66cf outdated
62+ } 63+ secp256k1_ge_set_gej(&Ra, &Rj); 64+ secp256k1_fe_normalize(&Ra.y); 65+ if (secp256k1_fe_is_odd(&Ra.y)) { 66+ secp256k1_scalar_negate(&n, &n); 67+ }
apoelstra commented at 1:33 pm on July 2, 2015:Can you add a comment above this block explaining that forcing the parity of y allows batch verification (and is part of the definition of Schnorr signatures), at the cost of making inversion-free validation impossible?sipa commented at 2:26 pm on July 2, 2015: contributor@apoelstra You’re not being stupid, I think.
k is the secret nonce, r is R’s x coordinate, m is the message, x is the private key, h = H(m || r). x and k are unknown to an attacker.
ECDSA: s_ecdsa * k = m + r * x Schnorr: s_schnorr = k - h * x
Or: ECDSA: k = (m + r * x) / s_ecdsa Schnorr: k = s_schnorr + h * x
So: (m + r * x) / s_ecdsa = s_schnorr + h * x
So: x = (s_schnorr - m/s_ecdsa) / (r/s_ecdsa - h)
sipa force-pushed on Jul 2, 2015sipa commented at 3:28 pm on July 2, 2015: contributorFixed the problem listed above by xoring the name of the signature algorithm into the message.
Added a rationale for the choice of full R validation and implicit even y.
sipa force-pushed on Jul 2, 2015sipa force-pushed on Jul 2, 2015sipa force-pushed on Jul 10, 2015sipa commented at 5:43 pm on July 10, 2015: contributorRebased on top of #269 and passing the signature algorithm name into the PRNG, to avoid the issue @apoelstra found above.sipa force-pushed on Jul 24, 2015sipa force-pushed on Jul 24, 2015sipa force-pushed on Jul 24, 2015sipa force-pushed on Jul 26, 2015sipa force-pushed on Jul 26, 2015sipa force-pushed on Jul 26, 2015apoelstra commented at 7:45 pm on July 26, 2015: contributorValgrind shows a bunch of errors on the test binary with this code. You needCFLAGS="-g -O0" ./configure
to see them.sipa force-pushed on Jul 26, 2015apoelstra commented at 10:51 pm on July 26, 2015: contributorAlmost there :)
test_schnorr_end_to_end
is never called (and as a consequence _sign and _recover aren’t tested)._Edit:_ Ah,
test_ecdsa_end_to_end
is called rather than the schnorr version.sipa force-pushed on Jul 26, 2015sipa commented at 10:55 pm on July 26, 2015: contributorFixed.apoelstra commented at 11:57 pm on July 26, 2015: contributorACKtheuni commented at 9:04 pm on July 27, 2015: contributor@sipa Looks good to me. One nit though. IMO we should also add a define in the main header that lists which modules are available. Otherwise preprocessing would be necessary to determine if schnorr functionality could be #included.
Even easier than that would be a 3rd (pushing it, i know) header with those defines, to avoid hacking up the main interface header. As a bonus, we could also stick the current config in there so that features like USE_ENDOMORPHISM, USE_NUM_GMP, etc. could be known at the application level.
sipa commented at 11:46 pm on July 27, 2015: contributorHmm, I don’t know about exposing implementation details in the headers. I jist thought: if you enable the Schnorr module, the schnorr header file is installed, otherwise it isn’t… no preprocessing needed.theuni commented at 1:26 am on July 28, 2015: contributor@sipa There’s no way to tell if it’s installed without preprocessing though, you’d just “#include secp256k1_schnorr.h” and hope for the best.
I took a quick stab at it here: https://github.com/theuni/secp256k1/tree/212
If you decide to go this route, since the config details become part of the api, we’d need to namespace/cleanup their values.
Of course, you could also just take a subset of this and only expose the module details, leaving the rest as it is.
sipa commented at 1:40 am on July 28, 2015: contributorWell, duh. But how is that different from doing an include #include <gmp.h> and hoping that that libgmp is installed?
I would really like to avoid having the public API expose implementation details. I’d rather just see them as two separate APIs that happen to be implemented in the same library.
theuni commented at 2:01 am on July 28, 2015: contributor@sipa Because when you ‘apt-get install libgmp’, you know you can “#include <gmp.h>”. But if I apt-get install libsecp256k1, I have no idea what it contains. Using the existence of a file is shaky at best, as it’d be very easy to hit the system file in /usr/include when building against another or a cross build.
No problem if you don’t want to expose implementation details, but I still think the user needs some explicit way to know what optional apis are available.
theuni commented at 7:18 pm on July 28, 2015: contributor@sipa Just as libsecp256k1 falls back to internal implementations if gmp isn’t usable, an application could do the same if libsecp256k1_foo feature isn’t available.
But it’s really not worth the argument, and certainly not worth holding up this PR.
sipa commented at 7:21 pm on July 28, 2015: contributor@theuni Right, there may be optional behaviour. But that’s something you’d typically check at configure time, which can try to compile.
I guess the fundamental question I have is: why can you trust that the contents of a file on your disk corresponds with the library installed, when you can’t trust the presence of the file corresponding to it.
theuni commented at 7:58 pm on July 28, 2015: contributor@sipa all files needed to build all configs should be included in the dist tarball. From a quick check, that’s currently working as expected:
0./autogen.sh 1./configure 2make distdir # same as 'make dist' and extract tarball 3cd libsecp256k1-0.1 4./configure --enable-module-schnorr 5make
apoelstra commented at 11:23 pm on July 29, 2015: contributorBefore merge can you add bench_schnorr_verify to .gitignore?apoelstra commented at 3:56 pm on August 1, 2015: contributorAlso I think you need to change the last line oftravis.yml
so that the value of $SCHNORR actually affects configure.sipa force-pushed on Aug 2, 2015sipa commented at 5:37 pm on August 2, 2015: contributorRebased.sipa force-pushed on Aug 2, 2015Add support for custom EC-Schnorr-SHA256 signatures a5a66c70b6sipa force-pushed on Aug 3, 2015sipa commented at 6:09 pm on August 3, 2015: contributor@apoelstra Nits addressed.apoelstra commented at 7:38 pm on August 3, 2015: contributorThanks! Tested ACK.sipa merged this on Aug 3, 2015sipa closed this on Aug 3, 2015
sipa referenced this in commit 258720851e on Aug 3, 2015sipa cross-referenced this on Aug 28, 2015 from issue Support for optional parts by sipajl777 commented at 4:29 am on June 14, 2016: noneis there anyway to use schnorr combined pubkey in a standard p2sh script? I assume the schnorr sigs are different so OP_CHECKSIG wont work, but if we can assume externally coordinated reveal on secret script, I am hoping there is a way to achieve this as a combined pubkey can be created, but I cant see how to get a script verifiable value before the signature. Maybe there is a way to cooperatively construct a combined privkey that can be used to sign?voisine commented at 4:46 am on June 14, 2016: contributorI believe schnor is planned for the first segwit upgrade. It will require a new checksig opcode and a soft fork.jl777 commented at 4:50 am on June 14, 2016: nonewell a new schnorr_sig opcode would make this all too easy :) that is what I am adding now but would be nice to get this on the bitcoin side toosipa commented at 6:21 am on June 14, 2016: contributor@jl777 Unsure what you mean. Schnorr signatures are not compatible with ECDSA at all, and needs different signing and verification code. Further, Bitcoin scripts that do not use any digital signature are inherently insecure (if there is no secret information being verified, miners can steal all the coins once they see a spend). Thus, indeed, the only way is using a new opcode.jl777 commented at 6:29 am on June 14, 2016: noneit would be combined with a normal signature: OP_HASH160 hash(sharedsecret) OP_EQUALVERIFY (normal_pubkey) OP_CHECKSIG
granted the protection from just the normal_pubkey OP_CHECKSIG isnt as much as full verification, but if there was a way to offchain calculate a schnorr sig based sharedsecret equivalent, then I think it would work.
problem is I dont see a way to know ahead of time any value that a group signature would create. The combined pubkey appears to be a standard pubkey, but without any normal privkey. Maybe there is a way for a set of nodes to create onetime use keypairs and somehow create a combined privkey that can be used with the combined pubkey.
sipa commented at 6:40 am on June 14, 2016: contributorYou seem to be describing a normal signature with a hashlocked secret. Where does Schnorr come in?jl777 commented at 6:50 am on June 14, 2016: nonethe schnorr would come in offchain, so a group can do larger scale MofN between themselves was hoping there was a way to generate some sort of sharedsecret equivalent among the participants so that if each member of the group validates the schnorr combined sig, they release their portion of the sharedsecret.
using shamir’s shared secret that each of the participants have and release only if they are satisfied, comes really close to being the hashlocked secret to use. The problem is we cant have any single node to know the secret that is being shamir’ed.
maybe some sort of oblivious transfer method could be used, but this is getting to where I am not comfortable as I dont know of any C libraries for that.
So the constraints are that each member of the group can directly run the schnorr lib, they can coordinate and precalculate any sort of magic value, but ultimately a hashlocked bitcoin tx needs to be used
unknown cross-referenced this on Oct 8, 2018 from issue Add schnorrsig module which implements BIP-340 compliant signatures by jonasnick
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 21:15 UTC
More mirrored repositories can be found on mirror.b10c.me