Open trevormil opened 11 months ago
I particularly need it for my project that I am working on. Is this something that can be completed anytime soon? Or should I find an alternative solution in the meantime?
We'd accept a contribution implementing it. Seems relatively straight forward.
I'd like to work on this issue, Thanks!
I'd like to work on this issue, Thanks!
Awesome. Could you keep me updated on any progress?
Okay, I will do :)
Hey, any progress updates? My project will need a solution by the end of February. Do you think this will be done by then? Or, should I find an alternative?
No worries if not. Just need to know how to move forward.
@trevormil check my issue, i started implement it, but I warn you right away - my code does not produce correct results yet, and I cannot fix it https://github.com/btcsuite/btcd/issues/2117
Sorry I seem missed this notification @trevormil I am busy now with other tasks Hope I get to it soon. That said please feel free to look for alternatives in the meantime. Thanks for your understanding 🙏
Sorry I seem missed this notification @trevormil I am busy now with other tasks Hope I get to it soon. That said please feel free to look for alternatives in the meantime. Thanks for your understanding 🙏
No worries. Thank you.
@trevormil hi! I had a look at how bitcoin core does this and a quick gist would be:
script/proof.cpp
and script/proof.h
(for BIP 322 support).signMessage
method for all address types.verifymessage
for verbosity of BIP 322 details.src/script/sign.cpp
and src/script/sign.h
for BIP 322 signature creation and verification.I just got started on this and would be using this as a rough roadmap. A rather trivial question would be: Where does the files for bip322
go? 😅 The repo is HUGE and I'm new here.
@trevormil @Roasbeef pls, I'd like to contribute to this. can I pick it up?
@yemmyharry Yea, that would be great. I am not actively working on it. I kinda just settled with a workaround calling the JavaScript version from Go code. Could you keep me updated on progress?
I just got started on this and would be using this as a rough roadmap. A rather trivial question would be: Where does the files for bip322 go? 😅 The repo is HUGE and I'm new here.
@AbhinavMir I think we'd add the bip322
code to the txscript
package (where all the other Script logic lives). IIUC, BIP 322 is just a way to make a "fake transaction" to show that if an output were created with a given pkScript
, you can spend it with a valid witness. The txscript
package has all the contents (along with the wire
) package needed to do such a construction.
@yemmyharry sure, feel free to use this issue to get feedback on any WIP code you may have.
cc: @Roasbeef @AbhinavMir @yemmyharry @mohamedawnallah
Recently noticed that Unisat wallet a BIP322 Go package and was able to use it along with btcsuite for my use cases. I have provided the code below and is available via a Gist (https://gist.github.com/trevormil/7c8c3bec3cac94a2af3c1d4edf95ac2b). If you would like to use it or merge it into the library, feel free!
The goal of my code was to simply verify Phantom Wallet Bitcoin signatures in Go. Phantom uses P2WPKH BIP322 verification, so this code is only targeted to that specific algorithm (and not others like P2SH-P2WPKH and single-key-spend P2TR BIP-322 verification).
Behind the scenes, Phantom relies (or is at least compatible with) on the bip322-js npm package. This code is basically the equivalent of
Verifier.verifySignature(address, message, signature)
Code Snippet:
package main
import (
"encoding/base64"
"log"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
bip322 "github.com/unisat-wallet/libbrc20-indexer/utils/bip322"
)
func convertAddressToScriptPubkey(address string) []byte {
btcAddress, err := btcutil.DecodeAddress(address, &chaincfg.MainNetParams)
if err != nil {
panic(err)
}
outputScript, err := txscript.PayToAddrScript(btcAddress)
if err != nil {
panic(err)
}
return outputScript
}
func main() {
//You can replace these with the actual values you want to verify
//These are in the format used by bip322-js
//This is for P2WPKH BIP322 verification
message := "Hello World"
signature := "AkcwRAIgZRfIY3p7/DoVTty6YZbWS71bc5Vct9p9Fia83eRmw2QCICK/ENGfwLtptFluMGs2KsqoNSk89pO7F29zJLUx9a/sASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI="
signerAddress := "bc1q9vza2e8x573nczrlzms0wvx3gsqjx7vavgkx0l"
//These will be in the following format:
//[0x02 or 0x03] [LENGTH_BYTE, ...(LENGTH bytes that go into witness[0])] [0x21, ...(33 byte (len = 0x21) public key that was used to sign the message)]
//- First byte is either a 0x02 or 0x03 (not sure exactly why but apparently it is - https://github.com/ACken2/bip322-js/blob/f0f9373b3a1da19e017c518b891522eaa4bcccdd/src/helpers/Address.ts#L85)
//- Next part is the details that go into witness[0] (length of this part is determined by the second byte) - again, not exactly sure what this is
//- Last part is the public key that was used to sign the message (33 bytes) - There is a length byte 0x21 before this part to denote the length of the public key (0x21 = 33)
encodedSigBytes, err := base64.StdEncoding.DecodeString(signature)
if err != nil {
panic(err)
}
//Convert the address to a public key script (I believe this is the denotation for a pay-to-this-address script but not 100% sure)
pkScript := convertAddressToScriptPubkey(signerAddress)
//Decode the length of the witness[0] part
encodedSigLenByte := encodedSigBytes[1]
encodedSigLen := int(encodedSigLenByte)
//Extract witness[0] and witness[1] from the encoded signature
PUB_KEY_LEN := 33
encodedSig := encodedSigBytes[len(encodedSigBytes)-PUB_KEY_LEN-1-encodedSigLen : len(encodedSigBytes)-PUB_KEY_LEN-1]
pubKey := encodedSigBytes[len(encodedSigBytes)-33:]
//Recreate the witness to pass into the VerifySignature function
witness := wire.TxWitness{
encodedSig,
pubKey,
}
//This is the BIP322 verification function from the Unisat wallet
verified := bip322.VerifySignature(witness, pkScript, message)
log.Println("BIP 322 Verified:", verified)
}
As BIP322 support becomes more popular with Bitcoin wallets (Phantom, etc), it would be nice to have a Go implementation for message signature verification. To my knowledge, I could not find one. The main one I could find is https://github.com/ACken2/bip322-js.
I particularly need it for my project that I am working on. Is this something that can be completed anytime soon? Or should I find an alternative solution in the meantime?