func TestSignatures(t *testing.T) { for _, test := range signatureTests { var err error if test.der { _, err = btcec.ParseDERSignature(test.sig, btcec.S256()) } else { _, err = btcec.ParseSignature(test.sig, btcec.S256()) } if err != nil { if test.isValid { t.Errorf("%s signature failed when shouldn't %v", test.name, err) } /* else { t.Errorf("%s got error %v", test.name, err) } */ continue } if !test.isValid { t.Errorf("%s counted as valid when it should fail", test.name) } } }
// This example demonstrates verifying a secp256k1 signature against a public // key that is first parsed from raw bytes. The signature is also parsed from // raw bytes. func Example_verifySignature() { // Decode hex-encoded serialized public key. pubKeyBytes, err := hex.DecodeString("02a673638cb9587cb68ea08dbef685c" + "6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5") if err != nil { fmt.Println(err) return } pubKey, err := btcec.ParsePubKey(pubKeyBytes, btcec.S256()) if err != nil { fmt.Println(err) return } // Decode hex-encoded serialized signature. sigBytes, err := hex.DecodeString("30450220090ebfb3690a0ff115bb1b38b" + "8b323a667b7653454f1bccb06d4bbdca42c2079022100ec95778b51e707" + "1cb1205f8bde9af6592fc978b0452dafe599481c46d6b2e479") if err != nil { fmt.Println(err) return } signature, err := btcec.ParseSignature(sigBytes, btcec.S256()) if err != nil { fmt.Println(err) return } // Verify the signature for the message using the public key. message := "test message" messageHash := btcwire.DoubleSha256([]byte(message)) verified := signature.Verify(messageHash, pubKey) fmt.Println("Signature Verified?", verified) // Output: // Signature Verified? true }
// Returns signature in golang format func (s Sig) GoSig() (*big.Int, *big.Int, error) { sig, err := btcec.ParseSignature(s, btcec.S256()) return sig.R, sig.S, err }
func getSignatures(maxHeigth int64, log btclog.Logger, db btcdb.Db) chan *rData { heigthChan := make(chan int64) blockChan := make(chan *btcutil.Block) sigChan := make(chan *rData) go func() { for h := int64(0); h < maxHeigth; h++ { heigthChan <- h } close(heigthChan) }() var blockWg sync.WaitGroup for i := 0; i <= 10; i++ { blockWg.Add(1) go func() { for h := range heigthChan { sha, err := db.FetchBlockShaByHeight(h) if err != nil { log.Warnf("failed FetchBlockShaByHeight(%v): %v", h, err) return } blk, err := db.FetchBlockBySha(sha) if err != nil { log.Warnf("failed FetchBlockBySha(%v) - h %v: %v", sha, h, err) return } blockChan <- blk } blockWg.Done() }() } go func() { blockWg.Wait() close(blockChan) }() var sigWg sync.WaitGroup for i := 0; i <= 10; i++ { sigWg.Add(1) go func() { for blk := range blockChan { mblk := blk.MsgBlock() for i, tx := range mblk.Transactions { if btcchain.IsCoinBase(btcutil.NewTx(tx)) { continue } for t, txin := range tx.TxIn { dataSlice, err := btcscript.PushedData(txin.SignatureScript) if err != nil { continue } for d, data := range dataSlice { signature, err := btcec.ParseSignature(data, btcec.S256()) if err != nil { continue } sigChan <- &rData{ sig: signature, H: blk.Height(), Tx: i, TxIn: t, Data: d, } } } } } sigWg.Done() }() } go func() { sigWg.Wait() close(sigChan) }() return sigChan }
func processPubKeyHash(db btcdb.Db, rd *rData) error { sigScript := rd.txIn.SignatureScript pkScript := rd.txPrevOut.PkScript script, err := btcscript.NewScript(sigScript, pkScript, rd.txInIndex, rd.tx.MsgTx(), 0) if err != nil { return fmt.Errorf("failed btcscript.NewScript - h %v: %v\n", rd.in.H, err) } for script.Next() != btcscript.OP_CHECKSIG { _, err := script.Step() if err != nil { return fmt.Errorf("Failed Step - in %v: %v\n", rd.in, err) } } data := script.GetStack() rd.sigStr = data[0] rd.pkStr = data[1] aPubKey, err := btcutil.NewAddressPubKey(rd.pkStr, &btcnet.MainNetParams) if err != nil { return fmt.Errorf("Pubkey parse error: %v", err) } rd.address = aPubKey.EncodeAddress() rd.compressed = aPubKey.Format() == btcutil.PKFCompressed // From github.com/conformal/btcscript/opcode.go // Signature actually needs needs to be longer than this, but we need // at least 1 byte for the below. btcec will check full length upon // parsing the signature. if len(rd.sigStr) < 1 { return fmt.Errorf("OP_CHECKSIG ERROR") } // Trim off hashtype from the signature string. hashType := rd.sigStr[len(rd.sigStr)-1] sigStr := rd.sigStr[:len(rd.sigStr)-1] // Get script from the last OP_CODESEPARATOR and without any subsequent // OP_CODESEPARATORs subScript := script.SubScript() // Unlikely to hit any cases here, but remove the signature from // the script if present. subScript = btcscript.RemoveOpcodeByData(subScript, sigStr) hash := btcscript.CalcScriptHash(subScript, hashType, rd.tx.MsgTx(), rd.txInIndex) pubKey, err := btcec.ParsePubKey(rd.pkStr, btcec.S256()) if err != nil { return fmt.Errorf("OP_CHECKSIG ERROR") } signature, err := btcec.ParseSignature(sigStr, btcec.S256()) if err != nil { return fmt.Errorf("OP_CHECKSIG ERROR") } // log.Printf("op_checksig\n"+ // "pubKey:\n%v"+ // "pubKey.X: %v\n"+ // "pubKey.Y: %v\n"+ // "signature.R: %v\n"+ // "signature.S: %v\n"+ // "checkScriptHash:\n%v", // hex.Dump(pkStr), pubKey.X, pubKey.Y, // signature.R, signature.S, hex.Dump(hash)) if ok := ecdsa.Verify(pubKey.ToECDSA(), hash, signature.R, signature.S); !ok { return fmt.Errorf("OP_CHECKSIG FAIL") } rd.signature = signature rd.pubKey = pubKey rd.hash = hash return nil }