How can verify without private key (NBitcoin)

630 Views Asked by At

I am using NBitcoin nuget package. I try to create private and pub key(address). And after that , I try to sign to some message and then verify the this signature with pub key. But NBitcoin , for the verify using the BitcoinSecret object which is the has private key object. So , why for the verify NBitcoin using this object? And How can I verify signature without private key , just using address(pubKey),signature and message ? Thanks

     static void Main(string[] args)
            {

                Key Key = new Key(); //Create private key
                //We can take private key
                var privateKey = Key.GetBitcoinSecret(Network.Main);

               //Get the public key, and derive the address on the Main network
                BitcoinAddress address = privateKey.PubKey.GetAddress(Network.Main); 


                For the sign to data , create secret object.
                BitcoinSecret secret = new BitcoinSecret(Key, Network.Main);

                 string message = $"I am Nicolas";
                Console.WriteLine("Message:" + message + "\n");
                sign message with private key.
                string signature = secret.PrivateKey.SignMessage(message);
                Console.WriteLine("Signature:" + signature + "\n");






   /*      Now I dont understand this code. For the verify , I know that we need 
to signature message , message and pub or adres value.\n But in this code using
 again private secret object which has got private key.  How we can verify 
signature messaga with pub or address and message (dont include private key)*/
                if (secret.PubKey.VerifyMessage(message, signature))
                {
                    Console.WriteLine("thats okey");
                }


                Console.Read();

           }
2

There are 2 best solutions below

0
On

Sorry, I am late to this conversation. The OP is entirely correct to conclude that you don't need a private key to verify a signature. The only point in the signature process when a private key is required is when the private key owner is signing the document. You can verify the signature with only the public key. The sample the OP uses takes the public key from the private key that signed the document. This is not the only way to get a NBitcoin PubKey.

But you need to know the binary public key. It's not sufficient to know the address of the public key. But the binary public key can be shared freely. Knowing the binary public key you can instantiate an NBitcoin PubKey in two ways:

If you know the hex string of the public key:

PubKey pubKey = new PubKey(publicKeyHexString);

If you have the public key in a binary array:

PubKey pubKey = new PubKey(publicKeyBinaryArray);

I'd like to point out that I no longer see a (private key) Key.SignMessage() or a (public key) PubKey.VerifyMessage() methods. I only find (private key) Key.Sign() and a (public key) PubKey.Verify() methods. I suspect those were dropped so the implementer has complete control over the hash algorithm for the document in the signing process.

0
On

The public key can not exist without the private key, as the public key is derived from the private key by utilizing some kind of one-way-function. If you want to use the public key without the private key, then generate it from the private key, like you did

var pubKey = privateKey.PubKey;

store the public key to some location the verifyer has access to

File.WriteAllBytes("some/public/location/MyPubKey.key", pubKey.ToBytes());

let the verifyer read the public key without ever knowing of the private key

var pubKeyForVerification = File.ReadAllBytes("some/public/location/MyPubKey.key");

This is all there is to it. It is safe to store the public key anywhere you want, because it's practically impossible to learn the private key from it.