Example #1
0
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)
		}
	}
}
Example #2
0
// 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
}
Example #3
0
// 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
}
Example #4
0
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
}
Example #5
0
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
}