Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Schnorr signatures #212

Merged
merged 1 commit into from Aug 3, 2015

Conversation

Projects
None yet
6 participants
@sipa
Copy link
Contributor

commented Feb 13, 2015

No description provided.

@sipa sipa changed the title Implement Schnorr signatures + batch verification [WIP] Implement Schnorr signatures + batch verification Feb 13, 2015

@sipa sipa force-pushed the sipa:schnorr3 branch from a1a8231 to 3faad3b Mar 2, 2015

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Mar 2, 2015

Rebased.

@sipa sipa force-pushed the sipa:schnorr3 branch from 3faad3b to 514fa79 Mar 2, 2015

@sipa sipa force-pushed the sipa:schnorr3 branch from 514fa79 to 8fcf74b Apr 23, 2015

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Apr 23, 2015

Rebased.

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Apr 23, 2015

TODO: use context to store the batch multipliers

@dcousens

This comment has been minimized.

Copy link
Contributor

commented Apr 27, 2015

This is awesome, as Schnorr signatures are dead easy to understand.
But, for what purpose have they been added?

(just curious)

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Apr 27, 2015

They have not been added yet :)

@sipa sipa force-pushed the sipa:schnorr3 branch from 8fcf74b to 5bd0eb9 May 1, 2015

@sipa sipa force-pushed the sipa:schnorr3 branch 2 times, most recently from a446e0f to 0ab0b47 Jun 22, 2015

@sipa sipa changed the title [WIP] Implement Schnorr signatures + batch verification Implement Schnorr signatures Jun 22, 2015

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Jun 22, 2015

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 sipa force-pushed the sipa:schnorr3 branch 2 times, most recently from af94dbd to 71d3db6 Jun 25, 2015

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Jul 1, 2015

@gmaxwell Added multiparty signing API.

@apoelstra

This comment has been minimized.

Copy link
Member

commented Jul 1, 2015

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.

secp256k1_fe_normalize(&Ra.y);
if (secp256k1_fe_is_odd(&Ra.y)) {
secp256k1_scalar_negate(&n, &n);
}

This comment has been minimized.

Copy link
@apoelstra

apoelstra Jul 2, 2015

Member

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

This comment has been minimized.

Copy link
Contributor Author

commented Jul 2, 2015

@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 sipa force-pushed the sipa:schnorr3 branch from 71d3db6 to b458e1e Jul 2, 2015

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Jul 2, 2015

Fixed 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 sipa force-pushed the sipa:schnorr3 branch 2 times, most recently from 6fcf944 to 4ff8567 Jul 2, 2015

@sipa sipa force-pushed the sipa:schnorr3 branch from 4ff8567 to 255401b Jul 10, 2015

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Jul 10, 2015

Rebased on top of #269 and passing the signature algorithm name into the PRNG, to avoid the issue @apoelstra found above.

@sipa sipa force-pushed the sipa:schnorr3 branch from 255401b to 9bbb77d Jul 24, 2015

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Jul 24, 2015

Rebased on top of new #269 and #282, and made compilation of Schnorr code optional (with API defined in a separate header).

@theuni Any comments on the module approach here?

@sipa sipa force-pushed the sipa:schnorr3 branch from 9bbb77d to 0d11b3c Jul 24, 2015

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Jul 27, 2015

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Jul 27, 2015

@theuni

This comment has been minimized.

Copy link
Contributor

commented Jul 28, 2015

@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

This comment has been minimized.

Copy link
Contributor Author

commented Jul 28, 2015

@theuni

This comment has been minimized.

Copy link
Contributor

commented Jul 28, 2015

@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.

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Jul 28, 2015

@theuni What would an application do with the knowledge that an extra API is available? If it needs it, the build will fail (at link time or at compile time), if it doesn't, it doesn't care...

@theuni

This comment has been minimized.

Copy link
Contributor

commented Jul 28, 2015

@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

This comment has been minimized.

Copy link
Contributor Author

commented Jul 28, 2015

@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.

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Jul 28, 2015

@theuni Ok, one other question: when you don't specify --enable-module-schnorr, the schnorr files don't get included in "make dist" I think. Is that something you'd typically want?

@theuni

This comment has been minimized.

Copy link
Contributor

commented Jul 28, 2015

@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:

./autogen.sh
./configure
make distdir # same as 'make dist' and extract tarball
cd libsecp256k1-0.1
./configure --enable-module-schnorr
make
@apoelstra

This comment has been minimized.

Copy link
Member

commented Jul 29, 2015

Before merge can you add bench_schnorr_verify to .gitignore?

@apoelstra

This comment has been minimized.

Copy link
Member

commented Aug 1, 2015

Also I think you need to change the last line of travis.yml so that the value of $SCHNORR actually affects configure.

@sipa sipa force-pushed the sipa:schnorr3 branch from 0b221ac to 9a04c7c Aug 2, 2015

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Aug 2, 2015

Rebased.

@sipa sipa force-pushed the sipa:schnorr3 branch from 9a04c7c to acca5d0 Aug 2, 2015

@sipa sipa force-pushed the sipa:schnorr3 branch from acca5d0 to a5a66c7 Aug 3, 2015

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Aug 3, 2015

@apoelstra Nits addressed.

@apoelstra

This comment has been minimized.

Copy link
Member

commented Aug 3, 2015

Thanks! Tested ACK.

@sipa sipa merged commit a5a66c7 into bitcoin-core:master Aug 3, 2015

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details

sipa added a commit that referenced this pull request Aug 3, 2015

Merge pull request #212
a5a66c7 Add support for custom EC-Schnorr-SHA256 signatures (Pieter Wuille)

@sipa sipa referenced this pull request Aug 28, 2015

Closed

Support for optional parts #277

@jl777

This comment has been minimized.

Copy link

commented Jun 14, 2016

is 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

This comment has been minimized.

Copy link

commented Jun 14, 2016

I believe schnor is planned for the first segwit upgrade. It will require a new checksig opcode and a soft fork.

@jl777

This comment has been minimized.

Copy link

commented Jun 14, 2016

well 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 too

@sipa

This comment has been minimized.

Copy link
Contributor Author

commented Jun 14, 2016

@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

This comment has been minimized.

Copy link

commented Jun 14, 2016

it 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

This comment has been minimized.

Copy link
Contributor Author

commented Jun 14, 2016

You seem to be describing a normal signature with a hashlocked secret. Where does Schnorr come in?

@jl777

This comment has been minimized.

Copy link

commented Jun 14, 2016

the 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.