Update 2021/04/09-16
After discussion with @LLFourn and @jonasnick on GitHub, I understand the fundamental difference in approach between their ECDSA adaptor signature impl and mine. Their construction is secure, as long as it is not used to compose another scheme that relies on the Diffie-Hellman problem. If there is technical consensus to switch to Elements Project’s ECDSA adaptor signature impl, I’ll do so.
I have chosen to re-implement the generalized channel style ECDSA adaptor scheme in libsecp256k1-zkp, and am continuing with a Schnorr adaptor signature impl in the aggsig
module. There is still some code cleanup in the ECDSA work, notably the extract
algorithm allows for both the pre-signature s
and its negation to extract the witness secret key.
Allowing the pre-signature s
and -s
to extract y
decreases the search space by half for a brute-force attacker, which AFAIU takes one bit off the security of the scheme.
It doesn’t seem to seriously harm security, since an attacker could try s
and -s
anyway to achieve the same effect. While rejecting would drastically harm usability for honest users.
This is currently the biggest flaw I see in my impl. Only one version of the adapted signature s
is allowed, and the rest of the scheme is SUF-CMA secure.
One possible solution is to simply reject high adapted s
values in the adapt
algorithm, instead of conditionally negating them. It will take more work to find a solution that doesn’t drastically hurt usablility, and remains SUF-CMA secure.
Edit: after reviewing the aggsig
module, all the code is there for Schnorr adaptor signatures (many thanks @yeastplume @jaspervdm @garyyu!).
For the Schnorr adaptor signature impl, will use the aggsig
module in secp256k1-zkp
, and what’s outlined in the atomic swap section of the Grin docs. I may incorporate some of the BIP-340 stuff for nonce generation to create a “synthetic nonce” (the e
value), since it hardens the scheme in low-entropy environments (like hardware wallets).
Synthetic nonce generation can be done in grin-wallet
, other impls, or could use the HMAC-SHA256 based code in aggsig
.
Now, can start integration work by adding a module to grin-wallet
. Because I am working somewhat backwards from how I started (main impl in C, with Rust bindings), the integration into C/C++
-based wallets should be even more straight-forward. However, integration into C/C++
-based wallets will come after grin-wallet
and rust-bitcoin/rust-wallet
integration.
The main integration work of creating the multi-sig Bitcoin transaction should also be pretty straight-forward. Basically, the hash lock is replaced by a signature from the adaptor public key. The Grin side should be even easier, with maybe some additional slatepack types to support communication rounds. I’m optimistic for finishing the integration work next week to get to the point of making testnet transactions (it may end up taking longer).
Thanks for reading