// TestSigCacheAddEvictEntry tests the eviction case where a new signature // triplet is added to a full signature cache which should trigger randomized // eviction, followed by adding the new element to the cache. func TestSigCacheAddEvictEntry(t *testing.T) { // Create a sigcache that can hold up to 100 entries. sigCacheSize := uint(100) sigCache := NewSigCache(sigCacheSize) // Fill the sigcache up with some random sig triplets. for i := uint(0); i < sigCacheSize; i++ { msg, sig, key, err := genRandomSig() if err != nil { t.Fatalf("unable to generate random signature test data") } sigCache.Add(*msg, sig, key) sigCopy, _ := btcec.ParseSignature(sig.Serialize(), btcec.S256()) keyCopy, _ := btcec.ParsePubKey(key.SerializeCompressed(), btcec.S256()) if !sigCache.Exists(*msg, sigCopy, keyCopy) { t.Errorf("previously added item not found in signature" + "cache") } } // The sigcache should now have sigCacheSize entries within it. if uint(len(sigCache.validSigs)) != sigCacheSize { t.Fatalf("sigcache should now have %v entries, instead it has %v", sigCacheSize, len(sigCache.validSigs)) } // Add a new entry, this should cause eviction of a randomly chosen // previously entry. msgNew, sigNew, keyNew, err := genRandomSig() if err != nil { t.Fatalf("unable to generate random signature test data") } sigCache.Add(*msgNew, sigNew, keyNew) // The sigcache should still have sigCache entries. if uint(len(sigCache.validSigs)) != sigCacheSize { t.Fatalf("sigcache should now have %v entries, instead it has %v", sigCacheSize, len(sigCache.validSigs)) } // The entry added above should be found within the sigcache. sigNewCopy, _ := btcec.ParseSignature(sigNew.Serialize(), btcec.S256()) keyNewCopy, _ := btcec.ParsePubKey(keyNew.SerializeCompressed(), btcec.S256()) if !sigCache.Exists(*msgNew, sigNewCopy, keyNewCopy) { t.Fatalf("previously added item not found in signature cache") } }
// TestSigCacheAddMaxEntriesZeroOrNegative tests that if a sigCache is created // with a max size <= 0, then no entries are added to the sigcache at all. func TestSigCacheAddMaxEntriesZeroOrNegative(t *testing.T) { // Create a sigcache that can hold up to 0 entries. sigCache := NewSigCache(0) // Generate a random sigCache entry triplet. msg1, sig1, key1, err := genRandomSig() if err != nil { t.Errorf("unable to generate random signature test data") } // Add the triplet to the signature cache. sigCache.Add(*msg1, sig1, key1) // The generated triplet should not be found. sig1Copy, _ := btcec.ParseSignature(sig1.Serialize(), btcec.S256()) key1Copy, _ := btcec.ParsePubKey(key1.SerializeCompressed(), btcec.S256()) if sigCache.Exists(*msg1, sig1Copy, key1Copy) { t.Errorf("previously added signature found in sigcache, but" + "shouldn't have been") } // There shouldn't be any entries in the sigCache. if len(sigCache.validSigs) != 0 { t.Errorf("%v items found in sigcache, no items should have"+ "been added", len(sigCache.validSigs)) } }
// TestSigCacheAddExists tests the ability to add, and later check the // existence of a signature triplet in the signature cache. func TestSigCacheAddExists(t *testing.T) { sigCache := NewSigCache(200) // Generate a random sigCache entry triplet. msg1, sig1, key1, err := genRandomSig() if err != nil { t.Errorf("unable to generate random signature test data") } // Add the triplet to the signature cache. sigCache.Add(*msg1, sig1, key1) // The previously added triplet should now be found within the sigcache. sig1Copy, _ := btcec.ParseSignature(sig1.Serialize(), btcec.S256()) key1Copy, _ := btcec.ParsePubKey(key1.SerializeCompressed(), btcec.S256()) if !sigCache.Exists(*msg1, sig1Copy, key1Copy) { t.Errorf("previously added item not found in signature cache") } }
// 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 := wire.DoubleSha256([]byte(message)) verified := signature.Verify(messageHash, pubKey) fmt.Println("Signature Verified?", verified) // Output: // Signature Verified? true }
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) } } }
pema := GeneratePemFromKey(keya) keyb := ExtractKeyFromPem(pema) hexa := hex.EncodeToString(keya.Serialize()) hexb := hex.EncodeToString(keyb.Serialize()) if hexa != hexb { GinkgoT().Errorf("expected: %s\nreceived: %s", hexa, hexb) } }) It("signs the sha256 with a pem", func() { // sign the message, then extract the signature from result pm := GeneratePem() message := "Hi Everybody!" signed := Sign(message, pm) byt, _ := hex.DecodeString(signed) signature, _ := btcec.ParseSignature(byt, btcec.S256()) // create the expected message hash := sha256.New() hash.Write([]byte(message)) expectedMessage := hash.Sum(nil) // get the public key from the PEM priv := ExtractKeyFromPem(pm) pub := priv.PubKey() Expect(signature.Verify(expectedMessage, pub)).To(Equal(true)) }) }) func GeneratePemFromKey(priv *btcec.PrivateKey) string {
shaHash1Bytes, _ = hex.DecodeString("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") shaHash1, _ = wire.NewShaHash(shaHash1Bytes) outpoint1 = wire.NewOutPoint(shaHash1, 0) // echo | openssl sha256 // This stuff gets reversed!!! shaHash2Bytes, _ = hex.DecodeString("01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b") shaHash2, _ = wire.NewShaHash(shaHash2Bytes) outpoint2 = wire.NewOutPoint(shaHash2, 1) // create inputs from outpoint1 and outpoint2 inputs = []*wire.TxIn{wire.NewTxIn(outpoint1, nil), wire.NewTxIn(outpoint2, nil)} // Commitment Signature tx = wire.NewMsgTx() emptybytes = new([]byte) sigStr, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, privKey) commitSig, _ = btcec.ParseSignature(sigStr, btcec.S256()) // Funding TX Sig 1 sig1privKeyBytes, _ = hex.DecodeString("927f5827d75dd2addeb532c0fa5ac9277565f981dd6d0d037b422be5f60bdbef") sig1privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig1privKeyBytes) sigStr1, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig1privKey) commitSig1, _ = btcec.ParseSignature(sigStr1, btcec.S256()) // Funding TX Sig 2 sig2privKeyBytes, _ = hex.DecodeString("8a4ad188f6f4000495b765cfb6ffa591133a73019c45428ddd28f53bab551847") sig2privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig2privKeyBytes) sigStr2, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig2privKey) commitSig2, _ = btcec.ParseSignature(sigStr2, btcec.S256()) // Slice of Funding TX Sigs ptrFundingTXSigs = append(*new([]*btcec.Signature), commitSig1, commitSig2) // TxID
func readElement(r io.Reader, element interface{}) error { var err error switch e := element.(type) { case *uint8: var b [1]uint8 _, err = r.Read(b[:]) if err != nil { return err } *e = b[0] return nil case *uint16: var b [2]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = binary.BigEndian.Uint16(b[:]) return nil case *CreditsAmount: var b [4]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = CreditsAmount(int32(binary.BigEndian.Uint32(b[:]))) return nil case *uint32: var b [4]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = binary.BigEndian.Uint32(b[:]) return nil case *uint64: var b [8]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = binary.BigEndian.Uint64(b[:]) return nil case *HTLCKey: var b [8]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = HTLCKey(binary.BigEndian.Uint64(b[:])) return nil case *btcutil.Amount: var b [8]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = btcutil.Amount(int64(binary.BigEndian.Uint64(b[:]))) return nil case **wire.ShaHash: var b wire.ShaHash _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = &b return nil case **btcec.PublicKey: var b [33]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } x, err := btcec.ParsePubKey(b[:], btcec.S256()) if err != nil { return err } *e = &*x return nil case *[]uint64: var numItems uint16 err = readElement(r, &numItems) if err != nil { return err } // if numItems > 65535 { // return fmt.Errorf("Too many items in []uint64") // } // Read the number of items var items []uint64 for i := uint16(0); i < numItems; i++ { var item uint64 err = readElement(r, &item) if err != nil { return err } items = append(items, item) } *e = *&items return nil case *[]*btcec.Signature: var numSigs uint8 err = readElement(r, &numSigs) if err != nil { return err } if numSigs > 127 { return fmt.Errorf("Too many signatures!") } // Read that number of signatures var sigs []*btcec.Signature for i := uint8(0); i < numSigs; i++ { sig := new(btcec.Signature) err = readElement(r, &sig) if err != nil { return err } sigs = append(sigs, sig) } *e = *&sigs return nil case **btcec.Signature: var sigLength uint8 err = readElement(r, &sigLength) if err != nil { return err } if sigLength > 73 { return fmt.Errorf("Signature too long!") } // Read the sig length l := io.LimitReader(r, int64(sigLength)) sig, err := ioutil.ReadAll(l) if err != nil { return err } if len(sig) != int(sigLength) { return fmt.Errorf("EOF: Signature length mismatch.") } btcecSig, err := btcec.ParseSignature(sig, btcec.S256()) if err != nil { return err } *e = &*btcecSig return nil case *[]*[20]byte: // How many to read var sliceSize uint16 err = readElement(r, &sliceSize) if err != nil { return err } var data []*[20]byte // Append the actual for i := uint16(0); i < sliceSize; i++ { var element [20]byte err = readElement(r, &element) if err != nil { return err } data = append(data, &element) } *e = data return nil case *[20]byte: _, err = io.ReadFull(r, e[:]) if err != nil { return err } return nil case *wire.BitcoinNet: var b [4]byte _, err := io.ReadFull(r, b[:]) if err != nil { return err } *e = wire.BitcoinNet(binary.BigEndian.Uint32(b[:])) return nil case *[]byte: // Get the blob length first var blobLength uint16 err = readElement(r, &blobLength) if err != nil { return err } // Shouldn't need to do this, since it's uint16, but we // might have a different value for MAX_SLICE_LENGTH... if int(blobLength) > MAX_SLICE_LENGTH { return fmt.Errorf("Slice length too long!") } // Read the slice length l := io.LimitReader(r, int64(blobLength)) *e, err = ioutil.ReadAll(l) if err != nil { return err } if len(*e) != int(blobLength) { return fmt.Errorf("EOF: Slice length mismatch.") } return nil case *PkScript: // Get the script length first var scriptLength uint8 err = readElement(r, &scriptLength) if err != nil { return err } if scriptLength > 25 { return fmt.Errorf("PkScript too long!") } // Read the script length l := io.LimitReader(r, int64(scriptLength)) *e, err = ioutil.ReadAll(l) if err != nil { return err } if len(*e) != int(scriptLength) { return fmt.Errorf("EOF: Signature length mismatch.") } return nil case *string: // Get the string length first var strlen uint16 err = readElement(r, &strlen) if err != nil { return err } // Read the string for the length l := io.LimitReader(r, int64(strlen)) b, err := ioutil.ReadAll(l) if len(b) != int(strlen) { return fmt.Errorf("EOF: String length mismatch.") } *e = string(b) if err != nil { return err } return nil case *[]*wire.TxIn: // Read the size (1-byte number of txins) var numScripts uint8 err = readElement(r, &numScripts) if err != nil { return err } if numScripts > 127 { return fmt.Errorf("Too many txins") } // Append the actual TxIns var txins []*wire.TxIn for i := uint8(0); i < numScripts; i++ { outpoint := new(wire.OutPoint) txin := wire.NewTxIn(outpoint, nil) err = readElement(r, &txin) if err != nil { return err } txins = append(txins, txin) } *e = *&txins return nil case **wire.TxIn: // Hash var h [32]byte _, err = io.ReadFull(r, h[:]) if err != nil { return err } hash, err := wire.NewShaHash(h[:]) if err != nil { return err } (*e).PreviousOutPoint.Hash = *hash // Index var idxBytes [4]byte _, err = io.ReadFull(r, idxBytes[:]) if err != nil { return err } (*e).PreviousOutPoint.Index = binary.BigEndian.Uint32(idxBytes[:]) return nil default: return fmt.Errorf("Unknown type in readElement: %T", e) } return nil }