Add message signer & message signature verifier#601
Add message signer & message signature verifier#601q-src wants to merge 6 commits intobitcoindevkit:masterfrom getlipa:feature/msgsig
Conversation
afilini
left a comment
There was a problem hiding this comment.
Overall this is a good start but it feels a bit disconnected from everything else in BDK.
There are a few ways to "connect" this to the Wallet, the easiest one is probably to iterate over the signers of a wallet and taking their key (if any) with descriptor_secret_key().
You could have an API exposed on the wallet that takes a message and a derivation index, and internally iterates on the signers, derives the keys to the right index and then signs the message.
You should also figure out a good way to handle this when you have multiple keys in your descriptor. You could return a list of signatures, or a map with key -> sig entries, I don't know.. There are a few ways to do it and I haven't thought about them in detail yet, I'd like to see your proposal since you've given this more thoughts than myself!
src/keys/msgsig.rs
Outdated
| use bitcoin::{Address, Network, PrivateKey, PublicKey}; | ||
|
|
||
| /// Trait for message signers | ||
| pub trait MessageSigner<S> { |
There was a problem hiding this comment.
Are there any other signature types you'd plan to support on top of RecoverableSignature? I don't really understand why you need the generic here and on the verifier
There was a problem hiding this comment.
Yes, exactly. The idea behind this is to add other signature types.
There was a problem hiding this comment.
As far as I am aware there are no plans to switch to schnorr signatures for Bitcoin signed messages, so I don't think there's really too much room for upgrades here.
I was asking if you had at least one specific use case in memory (like a BIP which uses other sig algorithms) but if you don't have any examples I would just say it's better to drop the generic and stick to the classic ecdsa algorithm.
There was a problem hiding this comment.
No, I had no other use cases in mind than multi-sig and possibly schonrr. But since the latter is not planned and multi-sig can be done with a map as suggested by you, I agree it's better to just add a sign method to the wallet.
src/keys/msgsig.rs
Outdated
|
|
||
| /// A message signature verifier using ECDSA | ||
| pub struct EcdsaMessageSignatureVerifier { | ||
| secp: Secp256k1<All>, |
There was a problem hiding this comment.
I would just take a reference here to avoid cloning the context. If you don't want to add a lifetime to the struct you could just change the api of verify() to take a secp argument
There was a problem hiding this comment.
I mean, change the member declaration to be a reference and then take one in from_pub and from_address
There was a problem hiding this comment.
I agree, secp should at least be changed to a reference. However, regarding a secp argument at verify(), this would force BDK to have new methods on the wallet struct for every signing / verification algorithm.
There was a problem hiding this comment.
I don't understand what do you mean here, can you elaborate a bit more?
My interpretation is thatverify() doesn't have to be a method on the wallet, because you don't need anything from the wallet to verify a message (while for signing you need the private keys)
There was a problem hiding this comment.
I intially wanted to have similar interfaces for signing and verification. Therfore, I thought if signing is moved to the wallet, so should also verification. Combined with my assumption of having schnorr for message signatures at some point, BDK would end up with multiple verify methods.
However, this is not the case since schnorr is aparently not planned. Moreover, you are right that verify does not have to be on the wallet - except you want verification to happen with the pubkey of a different pk(...) wallet. But this feels a little odd.
Therefore, I suggest that we change the PR to have
- a method on the wallet for message signing which uses all private keys of the wallet
- message signature verification which is decoupled from the wallet
src/keys/msgsig.rs
Outdated
| fn sign(&self, message: &str) -> RecoverableSignature { | ||
| let msg_hash = signed_msg_hash(message); | ||
| self.secp.sign_recoverable( | ||
| &Message::from_slice(&msg_hash.into_inner()[..]).unwrap(), |
There was a problem hiding this comment.
Either replace the unwrap with an expect (for reasonably unlikey errors) or change this function to return a Result
src/keys/msgsig.rs
Outdated
|
|
||
| /// A message signer using ECDSA | ||
| pub struct EcdsaMessageSigner { | ||
| secp: Secp256k1<All>, |
There was a problem hiding this comment.
Same thing about secp as for the verifier
|
Thanks for the review. The additions in this PR are intentionally disconnected from the rest of BDK for single responsibility reasons but also because I was not sure if / how you want it to be connected - especially regarding multi-sig wallets and other signing algorithms. So I chose to add the traits I intended to join your dev call yesterday to discuss this. However, I didn’t manage to attend due to a change in my schedule… |
|
@LLFourn I was not aware of BIP-322 and therefore did not implement it. However, it looks very much like what I want to achieve. Apparently, BIP-322 is being added to rust-miniscript (rust-bitcoin/rust-miniscript#444). Shall we wait until this is done and then use the miniscript implementation? |
|
@q-src TBH miniscript doesn't sound like the right place either. It might make sense to have a BIP322 implementation in |
Description
Ths PR adds the possibility to
using ECDSA.
Checklists
All Submissions:
cargo fmtandcargo clippybefore committingNew Features:
CHANGELOG.md