-
Notifications
You must be signed in to change notification settings - Fork 208
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
Add ECDSA adaptor signatures module #117
Add ECDSA adaptor signatures module #117
Conversation
Sorry this was automatically closed. PR needs to be reopened against the |
fixed it should be fine now |
1c20841
to
08bb959
Compare
08bb959
to
ca5d997
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @jesseposner. Very easy to review. I think there is some things to fixup wrt to serialization which were not specified.
Thanks for the review @LLFourn, much appreciated! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very impressed how you figured out the peculiarities of this lib (including ctime tests, api tests, etc). PR is easy to follow and in a good state.
I didn't check whether the code exactly matches the spec and I only skimmed the tests.
As you can see here and here, the tests don't achieve full coverage yet. Generally we try to do that, perhaps you want to have another look. You can generate these coverage htmls with
./configure --enable-module-ecdsa-adaptor --enable-experimental --enable-coverage --without-asm
# rebuild
make -B
./tests
gcov src/tests-tests.gcda
gcovr -r . --html --html-details -o coverage.html
Thanks @jonasnick, this is super helpful! I will start updating the PR next week to respond to the comments. |
@jesseposner It looks like a few of the code coverage failures are in the serialization -- I think I will add some serialization test vectors to the spec to hit them. |
See new tests: discreetlogcontracts/dlcspecs@2de6534 |
Responds to comment: BlockstreamResearch#117 (comment)
I've added commits that address most of the comments, but still working on #117 (comment) and #117 (comment). |
This commit adds proving and verification functions for discrete logarithm equality. From the spec (discreetlogcontracts/dlcspecs#114): "As part of the ECDSA adaptor signature a proof of discrete logarithm equality must be provided. This is a proof that the discrete logarithm of some X to the standard base G is the same as the discrete logarithm of some Z to the base Y. This proof can be constructed by using equality composition on two Sigma protocols proving knowledge of the discrete logarithm between both pairs of points. In other words the prover proves knowledge of a such that X = a * G and b such that Z = b * Y and that a = b. We make the resulting Sigma protocol non-interactive by applying the Fiat-Shamir transformation with SHA256 as the challenge hash."
5ff61e8
to
c80f841
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rebased state of the PR looks good to me. I pushed a commit to my branch that adds a WARNING about the DH key leak to the include file. @jesseposner feel free to cherry-pick. @LLFourn is it accurate? Adding a function to extract the DH key would be fun but I don't think it would help much.
I was trying to understand Lemma 4.3 (removed in your dev branch) but I couldn't follow. Here are some specific questions:
|
Oops looks like I forgot to specify that. It is a reduction from DL to EUF-CMA[VES] security of ECDSA adaptor sig scheme (EUF-CMA is not involved). My claim is that it can't exist in any model -- this might be a bit ambitious (see below). But I suppose that it could have equivalently be for EUF-CMA of ECDSA to EUF-CMA[VES]. As long as it's a game where you can challenge with a key and the reduction is "key-preserving" (maybe that's why I left the particular problem out). Looking back it seems that proving things with respect to DL instead of to key-only or EUF-CMA is a mistake I repeated in this paper several times. I can't really recall why I did things this way.
In context of signature security reductions it means that the reduction challenges the forger with key it was challenged. E.g. a DL -> key-only Schnorr reduction passes through the group element it is challenged with to the Schnorr forger.
This is an interesting point and one I thought about a lot. Whether a simulator correctly simulates something depends on the other queries (e.g. like ROM queries) being answered in a way that is consistent with them. If you are careful I think they can be treated as standalone algorithms that are called by the reduction and return something to the reduction. I don't believe this point is necessary to explore for the particular lemma in question though. Let me try and salvage the lemma somewhat in a way that will draw out more clearly any disagreement. Here's why the bijective random oracle (BiROM) model reduction cannot exist from DL to EUF-CMA[VES] security of ECDSA one-times VES/adaptor signatures.
Hopefully that makes sense. This should hold true in any model (BiROM oracles can be replaced with any set of oracles) . Although now I think about it, it would be very awkward to define in the generic group model where the reduction controls the group representation. So I think I agree with you that I should have stated which model in particular (the usefulness of the lemma is not really reduced by proving only for BiROM).
On this topic I believe it could be useful to use node public keys (which are used in noise ECDH) in a lightning channel funding output's actual script pubkey. The idea is that you can find your channels with any peer without a backup just by doing ECDH and deterministically deriving them. See the idea here: https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-December/002907.html I believe this is likely to be included in the updated lightning funding protocol proposal so register your objections before it's too late! IMO violating good practice here is worth the benefit.
Hopefully the above also answers most of this. The claim follows a "meta-reduction" like claim where we extract the DH key by playing both the challenger to the reduction and the forger the reduction is using. Your point is good though. From a encrypted signature oracle you can only get the DH keys for (X,A), (X,B) etc. Realizing the importance of this was the reason that I started working on the revision where in the actual proof of security I give the reduction a "static" CDH oracle with a fixed X (in the original they were able to query for any CDH solution). I stopped working on it because I didn't think anyone would ever care about this and that [1] would be sufficient (yet here we are!).
It turns out this is a problem! If you can query the DH keys against X you can solve discrete log for X faster than without such an oracle. I even did concrete estimates of how much faster in [2] for secp256k1 (see Appendix B). So in the end ECDSA adaptor signatures are less secure than ECDSA itself even if you don't insecurely compose it with a scheme using Diffie-Hellman! [1] https://eprint.iacr.org/2004/306
Yes LGTM. |
include/secp256k1_ecdsa_adaptor.h
Outdated
* encryption key as Y = y*G. Given X, Y and the adaptor signature, it is | ||
* trivial to compute Y^x = X^y. | ||
* To completely avoid this problem, the signer can require a proof of | ||
* knowledge of the decryption key y before creating an adaptor signature. This |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe explain how this proof of knowledge can be implemented.
On a second thought, I'm not sure how. It's formally not known to be a proof of knowledge but is an ECDSA signature enough here? Maybe recommend a Schnorr signature to be on the safe side? We have it in the library now, so why not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can tell, there are at least a few pitfalls with a Schnorr signature proof of knowledge. Firstly, a naive construction is replayable. For example, most of the schemes I've seen essentially just sign the generator (c = H(g, y, t)
from https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic and c = H(g, h, u)
from https://crypto.stanford.edu/cs355/19sp/lec5.pdf). This can perhaps be resolved by requiring the verifier to send some random data to the prover to be used as the message. However, this opens a second potential attack, which is to trick the prover into signing a message, for example by sending "random data" that is in fact a transaction or some other non-random value. This second issue could be potentially resolved by having the prover hash the random data (and the prover should also probably include the nonce pubkey in the hash so that there's an input to the hash function which is not known by the verifier when the random data is generated). So I think a scheme where (1) the verifier sends the prover some random data and (2) the prover hashes the random data along with the nonce pubkey and signs the hash, could be okay, but curious to hear what other folks think of the scheme.
Also, maybe suggesting a proof of knowledge scheme here is more trouble than it's worth because if the recipient of the adaptor signature knows the decryption key, then they can simply decrypt the adaptor signature when they receive it which seems like it would obviate the usefulness of encrypting the signature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I hadn't considered that the recipient doesn't actually know the decryption key. Perhaps it would be okay in practice if before creating an adaptor signature for enckey
, the signer would require a a signature for enckey
and a message like "this is an adaptor sig enckey". Thus, whoever creates enckey
s must also provide such a signature and thereby communicates that they don't care about the DH key between the signing and the enckey
. The idea is that keys whose DH key with the signing key must not be leaked (such as an ephemeral ElGamal key) will not be used to create such signatures. However, this approach does not work for multi-hop-locks because there is no party that on its own knows the DL of the enckey when exchanging adaptor sigs to establish the route.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jesseposner I think the canonical way would be a signature on H(m)
where m
is a random challenge message and H
is a tagged hash with some unique tag such as ECDSA adaptor PoK
.
But I agree, the proof of knowledge seems not useful in this setting.
Note that I also didn't notice this because my comments here are pretty superficial. You guys have a better understanding of the entire thing.
Maybe warning like this is just fine: "A weaker defense is to simply not compose ECDSA adaptor signatures with other protocols."
Could we make that more specific? "A defense is to not reuse the signing key of ECDSA adaptor signatures in other protocols. In general, separating keys for different purposes whenever possible is recommended as well-established cryptographic practice."
(alternative: "in the protocols that rely on the hardness of the CDH problem, e.g., Diffie-Hellman key exchange.")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the warning description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, maybe suggesting a proof of knowledge scheme here is more trouble than it's worth because if the recipient of the adaptor signature knows the decryption key, then they can simply decrypt the adaptor signature when they receive it which seems like it would obviate the usefulness of encrypting the signature.
Note the point is that the encryption is "one-time" in that it leaks the decryption key. The point of giving an adaptor signature to someone who knows the decryption key is precisely because you hope they will leak it by decrypting and publishing the signature. DLCs are an exception to this.
There was another attempt at improving terminology here by generalizing this to "lockable" signatures (still in my list of things to read): https://eprint.iacr.org/2020/1613.pdf. Perhaps a "locked" signature is more intuitive than an "encrypted" signature. We already use the term "lock" in the sense of multi-hop locks so this might make things easier for people. Impressively they claim to be able to do it with BLS which I had thought was impossible to do efficiently.
However, this approach does not work for multi-hop-locks because there is no party that on its own knows the DL of the enckey when exchanging adaptor sigs to establish the route.
Yep. Nothing much you can do here other than avoid CDH or direct people to using Schnorr on signet until it arrives on mainnet later this year 🤞 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note the point is that the encryption is "one-time" in that it leaks the decryption key. The point of giving an adaptor signature to someone who knows the decryption key is precisely because you hope they will leak it by decrypting and publishing the signature. DLCs are an exception to this.
Great point, for example, the last hop in a multi-hop payment will know the decryption key for the adaptor signature it receives. However, each hop before it will not know the decryption key when they receive their adaptor signatures (but they will of course learn the respective decryption keys during the settlement phase of the protocol).
Perhaps a "locked" signature is more intuitive than an "encrypted" signature.
"Lock" is nice particularly because, as you point out, it makes the phrase "multi-hop locks" more clear, but then you need to refer to a "locking key" and an "unlocking key" and the "one-time" analogy to the OTP is lost, as is the scheme's verifiability. "One-time verifiably encrypted signatures" conveys more information to the reader about the scheme than "lockable signatures."
@LLFourn Ah okay, I think I understand now! So you give a meta-reduction even against any approach simulating the EUF-CMA[VES] game towards the adversary (without caring about solving DL in the end). Here's some further thoughts (really not relevant to this PR, feel free to ignore): |
@real-or-random Good insight. I agree an algebraic reduction would probably work here instead and be a more compelling claim. It seems like I would be able to extract the CDH solution regardless of the reduction being key-preserving in that case. |
Yeah, this description (and @real-or-random's summary) was very helpful for me. |
628a058
to
48faa56
Compare
This commit adds the ECDSA adaptor signature APIs: - Encrypted Signing Creates an adaptor signature, which includes a proof to verify the adaptor signature. - Encryption Verification Verifies that the adaptor decryption key can be extracted from the adaptor signature and the completed ECDSA signature. - Signature Decryption Derives an ECDSA signature from an adaptor signature and an adaptor decryption key. - Key Recovery Extracts the adaptor decryption key from the complete signature and the adaptor signature.
This commit adds test coverage including Cirrus scripts, Valgrind constant time tests for secret data, API tests, nonce function tests, and test vectors from the spec.
48faa56
to
b0ffa92
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The updated WARNING section looks good to me.
ACK b0ffa92
ACK b0ffa92 I've added a small warning to the spec too. |
Summary: ``` I noticed this while reviewing BlockstreamResearch/secp256k1-zkp#117 and finding some seemingly unnecessary VALGRIND_MAKE_MEM_DEFINED that I couldn't remove until I saw the bug. ``` Backport of [[bitcoin-core/secp256k1#894 | secp256k1#894]] Test Plan: ninja check-secp256k1 libtool --mode=execute valgrind ./valgrind_ctime_test Reviewers: #bitcoin_abc, majcosta Reviewed By: #bitcoin_abc, majcosta Differential Revision: https://reviews.bitcoinabc.org/D9389
@jesseposner @jonasnick @LLFourn I recently did an implementation of ECDSA adaptor signatures before being made aware of this work. I did a quick review of your code, and didn't see a proof for What are your thoughts on adding such a proof, similar to what I've done here? |
Summary: ``` I noticed this while reviewing BlockstreamResearch/secp256k1-zkp#117 and finding some seemingly unnecessary VALGRIND_MAKE_MEM_DEFINED that I couldn't remove until I saw the bug. ``` Backport of [[bitcoin-core/secp256k1#894 | secp256k1#894]] Test Plan: ninja check-secp256k1 libtool --mode=execute valgrind ./valgrind_ctime_test Reviewers: #bitcoin_abc, majcosta Reviewed By: #bitcoin_abc, majcosta Differential Revision: https://reviews.bitcoinabc.org/D9389
Hi @GeneFerneau, thanks for your review. Do you mean requiring a proof of knowledge for the adaptor before signing? If so, then we've spent half of the thread discussing this issue :) The PoK would prevent some applications like multi-hop locks which is why we added a warning to the top of the include file that states that the scheme is not universally composable. |
I skimmed the conversation, the proof in the paper I linked does not prove Being supplied such a I do somewhat understand how proving |
You cannot prove that Y^x != X^y since it is always true given that Y = G^y and X = G^x :) I think you miunderstood the discussion above. The problem are aware of with this scheme is that from each adaptor signature you may extract X^y. If the party receiving the adaptor signature knows y then then this isn't an issue. That's why to get the proof of security to work in a simulation paradigm then you will need a proof of knowledge so you can simulate the adaptor signature in the proof.
I don't understand how. Can you point out the algorithm to do this?
From memory there is no discussion of doing multi-hop locks with this scheme in their paper (the multi-hop locks paper uses 2pECDSA). The proof of knowledge for Y to the base G is difficult do since the receiver of the adaptor signature cannot produce that on their own. |
Yeah, after thinking about it more, I understand now. I was confused because of the below warning:
thinking the point was to avoid
In the generalized channels construction, if a malicious prover supplies a NUMS generator as Maybe the equivalent in the VES construction would be an encryption key that is NUMS generator, and verification of the encrypted signature would pass. However, the signer would be unable to produce a valid decryption key that allows the other party to recover the signing secret key.
The paper directly cites "Anonymous Multi-Hop Locks for Blockchain Scalability and Interoperability", your work "One-Time Verifiably Encrypted Signatures A.K.A. Adaptor Signatures", and mentions that their ECDSA adaptor signature scheme is a formalization (under UC framework) of the adaptor signatures used by Malavolta et al. and yourself:
So, the 2P-ECDSA is
The prover / pre-signature signer computes the proof of knowledge, and provides it to the verifier along with the pre-signature. I don't think I understand your point. If the verifier could produce the proof on their own, how would it be a zero-knowledge proof of knowledge? I'm going to re-read your paper again, and do another review of the code in this PR. Feels like I'm missing something fundamental in our discussion. I appreciate your work, and not trying to be rude. Just looking to find the best technical solution, and thought the techniques used by Aumayr et al. could be used along with yours. Maybe they are too fundamentally different in approach... Edit: after re-reading the paper, I think I understand why the two approaches won't work together. The zkPoK in Aumayr et al. doesn't address the DH leak in your construction, and the two papers argue under fundamentally different security models. Apologies for not realising that sooner. |
@GeneFerneau From my perspective the "generalized" channel work and my (admittedly flawed and unfinished) work own have the same conclusion about ECDSA AS and AS security in general. I simply have a stronger claim that the ECDSA construction is fine as long as you don't care about leaking DH keys (in which case you don't need the PoK). I think you can use this code for multi-hop locks etc as long as you are very careful about not composing it with some scheme that relies on DH. In other words, creating ECDSA AS oracle is like giving a DH oracle on the signing key. FWIW I never got to the bottom of those comments from the Aumayr et al. on my definitions. To me the definitions especially related to "unforgeability" are pretty much the same. |
Overview
This PR adds support for ECDSA adaptor signatures. It is based on the work of @jonasnick in jonasnick/secp256k1#14.
ECDSA Adaptor Signatures
This implementation conforms to the DLC specification and includes test vectors from the specification.
The specification is based on the paper "One-Time Verifiably Encrypted Signatures A.K.A. Adaptor Signatures" by @LLFourn. The idea was first proposed in a lightning-dev post.
Python
I've implemented the specification in Python as well, which can be useful for testing purposes. [needs to be updated to match the latest spec revision]