MetacoSA / NBitcoin

Comprehensive Bitcoin library for the .NET framework.
MIT License
1.86k stars 844 forks source link

SignMessage #1094

Open lpcurcio opened 2 years ago

lpcurcio commented 2 years ago

I upgraded the NBitcoin version from 6.x to 7.x. But the BitcoinSecret.PrivateKey.SignMessage property no longer exists. Has this property been removed or renamed?

NicolasDorier commented 2 years ago

Yes, it has been removed. It was starting to be used as a way to prove that somebody own a private key, even though it doesn't prove it.

dangershony commented 2 years ago

@lpcurcio that method is still available on blockcore (which has a fork of NBitcoin) https://github.com/block-core/blockcore/blob/master/src/Blockcore/NBitcoin/Key.cs#L106

sheindel commented 2 years ago

I'm not sure I agree with this reasoning. Sure, it doesn't prove ownership, but it does prove knowledge, and that can be helpful in a number of use cases. Not sure it makes sense to remove a helpful API just because someone doesn't understand the underlying cryptography. I would make the case that this is a helpful utility that should be re-added.

NicolasDorier commented 2 years ago

@sheindel no it doesn't prove knowledge either.

Imagine Alice ask to Bob to "prove knowledge" of a coin that really belongs to Carol.

Note that Carol doesn't pay any cost for signing whatever Bob is asking. And that at no point Bob need to know about the private key. It is possible for Carol to even ask Bob to pay for this service. Or even provide this service for free.

Maybe Carol is some gambling website, and Bob is getting asked for a proof because he paid Alice from the website (it cost less transaction fee, and protect privacy better because it mixes the coins with other customers of Carol), and Alice is suspecting this. As Carol, I would happily help my customer for free and sign whatever proof Bob is asking.

ChrisLomont commented 2 years ago

That still proves the message was signed by someone with knowledge of the private key. There is not a single signature protocol that would not fail if the private key holder signs arbitrary messages for anyone.

Removing the API means people will try to implement it on their own on top of the library, resulting in more, not less, mistakes.

How should one use the private key now to sign a message? Is there a better way?

lpcurcio commented 2 years ago

In my case, I use an exhange API to make buy and sell requests. The exchange enforces that the data that is sent in each request must be signed. I haven't looked into other solutions yet. For now I will continue using version 6.x.

sheindel commented 2 years ago

@NicolasDorier thanks for your work on the library, certainly don't mean to pile one. Really appreciate it :-)

In regards to this issue, I think it's valid to think about abuse/misuse, but we're talking about a library that has financial AND security implications. I think it's rife for misuse by those who don't understand cryptography with even the most basic of Bitcoin APIs.

And I think we can think about valid use cases for arbitrary signatures. If Alice is sending money to Bob, Alice just wants to know that SOMEONE knows the private key, so she can't be accused of sending money to nowhere. Whether Bob signed it himself or Carol signed it for him, that's not necessarily Alice's problem and it's for Bob and Carol to sort out. So there are valid use cases for signing even inside normal crypto transactions.

The fact that it's described in detail in a BIP (https://github.com/bitcoin/bips/blob/master/bip-0137.mediawiki) and mentioned with potential use cases in other BIPs (https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki) makes it entirely valid functionality to have within a Bitcoin library.

NicolasDorier commented 2 years ago

@sheindel

Note that the core of this feature still exists with Key.SignCompact and PubKey.RecoverCompact, the CompactSignature type enclose the data that was before formatted in the legacy signature.

You can inspire from the old code in https://github.com/block-core/blockcore/blob/master/src/Blockcore/NBitcoin/Key.cs#L106

But basically, the CompactSignature include the 1 bytes recid + the 64 bytes that you need for this "legacy signature". You only need to format the recId properly as well as to modify the signed byte to include the bitcoin signature header.

Note that BIP 0322 is a different format, that has never been implemented in NBitcoin. (unsure about current state, even in core)

I admit the case for "making sure the user didn't messed up" is a compelling one. I might consider it for BIP0322.

I think it's rife for misuse by those who don't understand cryptography with even the most basic of Bitcoin APIs.

If only noobs weren't in a position to take stupid decision affecting the whole industry... The decision to remove this feature was because of a push by lobbyists and regulators to force user to provide those signature as a proof of ownership to make the life of blockchain tainting and taxation easier. (Search for AOPP) When it happened, other wallets such as Blue Wallet, decided to drop this feature and others followed, as it is clear that this feature doesn't achieve the goal stated by AOPP. This successfully killed (delaying?) this whole effort.

Another attempt to do this was tried to at Isle of Man long ago. It could only be repelled because exchanges got under user support overload, and pressured regulators to remove it. Would it have been successful, this would have added cumbersome additional steps for users to have self-custody of their bitcoin for a bad reason. (thinking that the ability to provide a signature means ownership)

sergeibystrov commented 1 year ago

Hello Great programmer Nicholas🤔 Are you sure you are not Satoshi Nakomoto? Because you understand the in and out of Bitcoin than any? Just saying..🧐🤨