func TestEncodeDecodeWIF(t *testing.T) { priv1, _ := btcec.PrivKeyFromBytes(btcec.S256(), []byte{ 0x0c, 0x28, 0xfc, 0xa3, 0x86, 0xc7, 0xa2, 0x27, 0x60, 0x0b, 0x2f, 0xe5, 0x0b, 0x7c, 0xae, 0x11, 0xec, 0x86, 0xd3, 0xbf, 0x1f, 0xbe, 0x47, 0x1b, 0xe8, 0x98, 0x27, 0xe1, 0x9d, 0x72, 0xaa, 0x1d}) priv2, _ := btcec.PrivKeyFromBytes(btcec.S256(), []byte{ 0xdd, 0xa3, 0x5a, 0x14, 0x88, 0xfb, 0x97, 0xb6, 0xeb, 0x3f, 0xe6, 0xe9, 0xef, 0x2a, 0x25, 0x81, 0x4e, 0x39, 0x6f, 0xb5, 0xdc, 0x29, 0x5f, 0xe9, 0x94, 0xb9, 0x67, 0x89, 0xb2, 0x1a, 0x03, 0x98}) wif1, err := NewWIF(priv1, &chaincfg.MainNetParams, false) if err != nil { t.Fatal(err) } wif2, err := NewWIF(priv2, &chaincfg.TestNet3Params, true) if err != nil { t.Fatal(err) } tests := []struct { wif *WIF encoded string }{ { wif1, "5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ", }, { wif2, "cV1Y7ARUr9Yx7BR55nTdnR7ZXNJphZtCCMBTEZBJe1hXt2kB684q", }, } for _, test := range tests { // Test that encoding the WIF structure matches the expected string. s := test.wif.String() if s != test.encoded { t.Errorf("TestEncodeDecodePrivateKey failed: want '%s', got '%s'", test.encoded, s) continue } // Test that decoding the expected string results in the original WIF // structure. w, err := DecodeWIF(test.encoded) if err != nil { t.Error(err) continue } if got := w.String(); got != test.encoded { t.Errorf("NewWIF failed: want '%v', got '%v'", test.wif, got) } } }
func GenPrivKeySecp256k1() PrivKeySecp256k1 { privKeyBytes := [32]byte{} copy(privKeyBytes[:], CRandBytes(32)) priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKeyBytes[:]) copy(privKeyBytes[:], priv.Serialize()) return PrivKeySecp256k1(privKeyBytes) }
// This example demonstrates signing a message with a secp256k1 private key that // is first parsed form raw bytes and serializing the generated signature. func Example_signMessage() { // Decode a hex-encoded private key. pkBytes, err := hex.DecodeString("22a47fa09a223f2aa079edf85a7c2d4f87" + "20ee63e502ee2869afab7de234b80c") if err != nil { fmt.Println(err) return } privKey, pubKey := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes) // Sign a message using the private key. message := "test message" messageHash := wire.DoubleSha256([]byte(message)) signature, err := privKey.Sign(messageHash) if err != nil { fmt.Println(err) return } // Serialize and display the signature. // // NOTE: This is commented out for the example since the signature // produced uses random numbers and therefore will always be different. //fmt.Printf("Serialized Signature: %x\n", signature.Serialize()) // Verify the signature for the message using the public key. verified := signature.Verify(messageHash, pubKey) fmt.Printf("Signature Verified? %v\n", verified) // Output: // Signature Verified? true }
// This example demonstrates decrypting a message using a private key that is // first parsed from raw bytes. func Example_decryptMessage() { // Decode the hex-encoded private key. pkBytes, err := hex.DecodeString("a11b0a4e1a132305652ee7a8eb7848f6ad" + "5ea381e3ce20a2c086a2e388230811") if err != nil { fmt.Println(err) return } privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes) ciphertext, err := hex.DecodeString("35f644fbfb208bc71e57684c3c8b437402ca" + "002047a2f1b38aa1a8f1d5121778378414f708fe13ebf7b4a7bb74407288c1958969" + "00207cf4ac6057406e40f79961c973309a892732ae7a74ee96cd89823913b8b8d650" + "a44166dc61ea1c419d47077b748a9c06b8d57af72deb2819d98a9d503efc59fc8307" + "d14174f8b83354fac3ff56075162") // Try decrypting the message. plaintext, err := btcec.Decrypt(privKey, ciphertext) if err != nil { fmt.Println(err) return } fmt.Println(string(plaintext)) // Output: // test message }
// PrivKey returns the private key for the address. It can fail if the address // manager is watching-only or locked, or the address does not have any keys. // // This is part of the ManagedPubKeyAddress interface implementation. func (a *managedAddress) PrivKey() (*btcec.PrivateKey, error) { // No private keys are available for a watching-only address manager. if a.manager.watchingOnly { return nil, managerError(ErrWatchingOnly, errWatchingOnly, nil) } a.manager.mtx.Lock() defer a.manager.mtx.Unlock() // Account manager must be unlocked to decrypt the private key. if a.manager.locked { return nil, managerError(ErrLocked, errLocked, nil) } // Decrypt the key as needed. Also, make sure it's a copy since the // private key stored in memory can be cleared at any time. Otherwise // the returned private key could be invalidated from under the caller. privKeyCopy, err := a.unlock(a.manager.cryptoKeyPriv) if err != nil { return nil, err } privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKeyCopy) zero.Bytes(privKeyCopy) return privKey, nil }
// This example demonstrates signing a message with a secp256k1 private key that // is first parsed form raw bytes and serializing the generated signature. func Example_signMessage() { // Decode a hex-encoded private key. pkBytes, err := hex.DecodeString("22a47fa09a223f2aa079edf85a7c2d4f87" + "20ee63e502ee2869afab7de234b80c") if err != nil { fmt.Println(err) return } privKey, pubKey := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes) // Sign a message using the private key. message := "test message" messageHash := wire.DoubleSha256([]byte(message)) signature, err := privKey.Sign(messageHash) if err != nil { fmt.Println(err) return } // Serialize and display the signature. fmt.Printf("Serialized Signature: %x\n", signature.Serialize()) // Verify the signature for the message using the public key. verified := signature.Verify(messageHash, pubKey) fmt.Printf("Signature Verified? %v\n", verified) // Output: // Serialized Signature: 304402201008e236fa8cd0f25df4482dddbb622e8a8b26ef0ba731719458de3ccd93805b022032f8ebe514ba5f672466eba334639282616bb3c2f0ab09998037513d1f9e3d6d // Signature Verified? true }
// NOTE: secret should be the output of a KDF like bcrypt, // if it's derived from user input. func GenPrivKeySecp256k1FromSecret(secret []byte) PrivKeySecp256k1 { privKey32 := Sha256(secret) // Not Ripemd160 because we want 32 bytes. priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey32) privKeyBytes := [32]byte{} copy(privKeyBytes[:], priv.Serialize()) return PrivKeySecp256k1(privKeyBytes) }
//Returns a btec.Private key object if provided a correct secp256k1 encoded pem. func ExtractKeyFromPem(pm string) *btcec.PrivateKey { byta := []byte(pm) blck, _ := pem.Decode(byta) var ecp ecPrivateKey asn1.Unmarshal(blck.Bytes, &ecp) priv, _ := btcec.PrivKeyFromBytes(btcec.S256(), ecp.PrivateKey) return priv }
func Sign(private, data []byte) ([]byte, error) { privkey, _ := btcec.PrivKeyFromBytes(btcec.S256(), private) sig, err := privkey.Sign(data) if err != nil { return nil, err } return sig.Serialize(), nil }
// Returns DER encoded signature from input hash func signECDSA(privateKey, hash []byte) ([]byte, error) { priv, _ := btcec.PrivKeyFromBytes(btcec.S256(), privateKey) sig, err := priv.Sign(hash) if err != nil { return nil, err } return sig.Serialize(), nil }
// ECPrivKey converts the extended key to a btcec private key and returns it. // As you might imagine this is only possible if the extended key is a private // extended key (as determined by the IsPrivate function). The ErrNotPrivExtKey // error will be returned if this function is called on a public extended key. func (k *ExtendedKey) ECPrivKey() (*btcec.PrivateKey, error) { if !k.isPrivate { return nil, ErrNotPrivExtKey } privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), k.key) return privKey, nil }
func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature { priv__, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) sig__, err := priv__.Sign(Sha256(msg)) if err != nil { PanicSanity(err) } return SignatureSecp256k1(sig__.Serialize()) }
//Generates child public key from parent private key func (ek *ExtendedKey) CKDpub(index uint32) (*ExtendedPublicKey, error) { childPrivateKey, _ := ek.CKDpriv(index) chaincode := childPrivateKey.Chaincode _, publicKey := btcec.PrivKeyFromBytes(btcec.S256(), childPrivateKey.PrivateKey) childExtendedPublicKey := NewExtendedPublicKey(publicKey.X.Bytes(), publicKey.Y.Bytes(), childPrivateKey.Depth, childPrivateKey.ParentFingerPrint, index, chaincode, publicKey.SerializeCompressed()) return childExtendedPublicKey, nil }
func newKey(seed []byte) *btcec.PrivateKey { inc := big.NewInt(0).SetBytes(seed) inc.Lsh(inc, 32) for key := big.NewInt(0); ; inc.Add(inc, one) { key.SetBytes(Sha512Half(inc.Bytes())) if key.Cmp(zero) > 0 && key.Cmp(order) < 0 { privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), key.Bytes()) return privKey } } }
//Extended keys can be identified by the Hash160 (RIPEMD160 after SHA256) //of the serialized ECSDA public key K, ignoring the chain code //The first 32 bits of the identifier are called the key fingerprint. func (ek *ExtendedKey) GetFingerPrint() []byte { _, publicKey := btcec.PrivKeyFromBytes(btcec.S256(), ek.PrivateKey) sha_256 := sha256.New() sha_256.Write(publicKey.SerializeCompressed()) sha := sha_256.Sum(nil) ripemd := ripemd160.New() ripemd.Write(sha) final := ripemd.Sum(nil) return final[:4] }
// GenerateKeyPairDeterministic computes the public/private keypair for the // given entropy. func GenerateKeyPairDeterministic(entropy *Entropy) (*SecretKey, *PublicKey) { // Create key pair deterministically from the given entropy sk_s, pk_s := btcec.PrivKeyFromBytes(S256, entropy[:]) // Serialize the key pair sk := newSecretKeyInt(sk_s.D) pk := newPublicKeyCoords(pk_s.X, pk_s.Y) sk_s.D.SetUint64(0) return sk, pk }
//Calculate I = HMAC-SHA512(Key = "Bitcoin seed", Data = S) func GenerateMasterKey(seed []byte) (*ExtendedKey, *ExtendedPublicKey, error) { seedString := []byte("Bitcoin seed") hmac512 := hmac.New(sha512.New, seedString) hmac512.Write(seed) raw := hmac512.Sum(nil) ParentFingerPrint := []byte{0x00, 0x00, 0x00, 0x00} var depth byte depth = 0x00 var childNumber uint32 childNumber = 0 _, publicKey := btcec.PrivKeyFromBytes(btcec.S256(), raw[:32]) masterPrivateKey := NewExtendedKey(depth, ParentFingerPrint, childNumber, raw[32:], raw[:32]) masterPublicKey := NewExtendedPublicKey(publicKey.X.Bytes(), publicKey.Y.Bytes(), depth, ParentFingerPrint, childNumber, raw[32:], publicKey.SerializeCompressed()) return masterPrivateKey, masterPublicKey, nil }
func TestPrivKeys(t *testing.T) { tests := []struct { name string key []byte }{ { name: "check curve", key: []byte{ 0xea, 0xf0, 0x2c, 0xa3, 0x48, 0xc5, 0x24, 0xe6, 0x39, 0x26, 0x55, 0xba, 0x4d, 0x29, 0x60, 0x3c, 0xd1, 0xa7, 0x34, 0x7d, 0x9d, 0x65, 0xcf, 0xe9, 0x3c, 0xe1, 0xeb, 0xff, 0xdc, 0xa2, 0x26, 0x94, }, }, } for _, test := range tests { priv, pub := btcec.PrivKeyFromBytes(btcec.S256(), test.key) _, err := btcec.ParsePubKey( pub.SerializeUncompressed(), btcec.S256()) if err != nil { t.Errorf("%s privkey: %v", test.name, err) continue } hash := []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9} sig, err := priv.Sign(hash) if err != nil { t.Errorf("%s could not sign: %v", test.name, err) continue } if !sig.Verify(hash, pub) { t.Errorf("%s could not verify: %v", test.name, err) continue } serializedKey := priv.Serialize() if !bytes.Equal(serializedKey, test.key) { t.Errorf("%s unexpected serialized bytes - got: %x, "+ "want: %x", test.name, serializedKey, test.key) } } }
// This example demonstrates encrypting a message for a public key that is first // parsed from raw bytes, then decrypting it using the corresponding private key. func Example_encryptMessage() { // Decode the hex-encoded pubkey of the recipient. pubKeyBytes, err := hex.DecodeString("04115c42e757b2efb7671c578530ec191a1" + "359381e6a71127a9d37c486fd30dae57e76dc58f693bd7e7010358ce6b165e483a29" + "21010db67ac11b1b51b651953d2") // uncompressed pubkey if err != nil { fmt.Println(err) return } pubKey, err := btcec.ParsePubKey(pubKeyBytes, btcec.S256()) if err != nil { fmt.Println(err) return } // Encrypt a message decryptable by the private key corresponding to pubKey message := "test message" ciphertext, err := btcec.Encrypt(pubKey, []byte(message)) if err != nil { fmt.Println(err) return } // Decode the hex-encoded private key. pkBytes, err := hex.DecodeString("a11b0a4e1a132305652ee7a8eb7848f6ad" + "5ea381e3ce20a2c086a2e388230811") if err != nil { fmt.Println(err) return } // note that we already have corresponding pubKey privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes) // Try decrypting and verify if it's the same message. plaintext, err := btcec.Decrypt(privKey, ciphertext) if err != nil { fmt.Println(err) return } fmt.Println(string(plaintext)) // Output: // test message }
// newBobNode generates a test "ln node" to interact with Alice (us). For the // funding transaction, bob has a single output totaling 7BTC. For our basic // test, he'll fund the channel with 5BTC, leaving 2BTC to the change output. // TODO(roasbeef): proper handling of change etc. func newBobNode() (*bobNode, error) { // First, parse Bob's priv key in order to obtain a key he'll use for the // multi-sig funding transaction. privKey, pubKey := btcec.PrivKeyFromBytes(btcec.S256(), bobsPrivKey) // Next, generate an output redeemable by bob. bobAddr, err := btcutil.NewAddressPubKey(privKey.PubKey().SerializeCompressed(), ActiveNetParams) if err != nil { return nil, err } bobAddrScript, err := txscript.PayToAddrScript(bobAddr.AddressPubKeyHash()) if err != nil { return nil, err } prevOut := wire.NewOutPoint(&wire.ShaHash{}, ^uint32(0)) // TODO(roasbeef): When the chain rpc is hooked in, assert bob's output // actually exists and it unspent in the chain. bobTxIn := wire.NewTxIn(prevOut, nil) // Using bobs priv key above, create a change address he can spend. bobChangeOutput := wire.NewTxOut(2*1e8, bobAddrScript) // Bob's initial revocation hash is just his private key with the first // byte changed... var revocation [20]byte copy(revocation[:], bobsPrivKey) revocation[0] = 0xff // His ID is just as creative... var id [wire.HashSize]byte id[0] = 0xff return &bobNode{ id: id, privKey: privKey, channelKey: pubKey, deliveryAddress: bobAddr, revocation: revocation, delay: 5, availableOutputs: []*wire.TxIn{bobTxIn}, changeOutputs: []*wire.TxOut{bobChangeOutput}, }, nil }
// getArgs parses command line args and asserts that a private key and an // address are present and correctly formatted. func getArgs() requiredArgs { flag.Parse() if *toaddress == "" || *privkey == "" || *txid == "" || *vout == -1 || *amount == -1 { fmt.Println("\nThis program generates a bitcoin trans action that moves coins from an input to an output.\n" + "You must provide a key, a receiving address, a transaction id (the hash\n" + "of a tx), the amount to be transferred (in satoshis), and the index into\n" + "the outputs of that tx that fund your address. Use http://blockchain.info/pushtx\n" + "to send the raw transaction.\n") flag.PrintDefaults() fmt.Println("") os.Exit(0) } pkBytes, err := hex.DecodeString(*privkey) if err != nil { log.Fatal(err) } // PrivKeyFromBytes returns public key as a separate result, but can ignore it here. key, _ := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes) addr, err := btcutil.DecodeAddress(*toaddress, &chaincfg.MainNetParams) if err != nil { log.Fatal(err) } txid, err := wire.NewShaHashFromStr(*txid) if err != nil { log.Fatal(err) } args := requiredArgs{ txid: txid, vout: uint32(*vout), toAddress: addr, privKey: key, amount: int64(*amount), } return args }
// Test 2: Byte compatibility with Pyelliptic func TestCiphering(t *testing.T) { pb, _ := hex.DecodeString("fe38240982f313ae5afb3e904fb8215fb11af1200592b" + "fca26c96c4738e4bf8f") privkey, _ := btcec.PrivKeyFromBytes(btcec.S256(), pb) in := []byte("This is just a test.") out, _ := hex.DecodeString("b0d66e5adaa5ed4e2f0ca68e17b8f2fc02ca002009e3" + "3487e7fa4ab505cf34d98f131be7bd258391588ca7804acb30251e71a04e0020ecf" + "df0f84608f8add82d7353af780fbb28868c713b7813eb4d4e61f7b75d7534dd9856" + "9b0ba77cf14348fcff80fee10e11981f1b4be372d93923e9178972f69937ec850ed" + "6c3f11ff572ddd5b2bedf9f9c0b327c54da02a28fcdce1f8369ffec") dec, err := btcec.Decrypt(privkey, out) if err != nil { t.Fatal("failed to decrypt:", err) } if !bytes.Equal(in, dec) { t.Error("decrypted data doesn't match original") } }
func createTxRemainder(inCoin int64) *wire.TxOut { remainder := inCoin - *amount - TX_FEE // Put the remainder back in our wallet pkBytes, err := hex.DecodeString(*privkey) if err != nil { log.Fatal(err) } // Get pubkey object _, pubkey := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes) // Get an address object from WIF string changeAddress := generateAddr(pubkey) script, err := txscript.PayToAddrScript(changeAddress) if err != nil { log.Fatal(err) } remtx := wire.NewTxOut(remainder, script) return remtx }
// Add our identity to the listings and sign it func (n *OpenBazaarNode) SignListing(listing *pb.Listing) (*pb.RicardianContract, error) { c := new(pb.RicardianContract) if err := validate(listing); err != nil { return c, err } id := new(pb.ID) id.Guid = n.IpfsNode.Identity.Pretty() pubkey, err := n.IpfsNode.PrivateKey.GetPublic().Bytes() if err != nil { return c, err } //TODO: add blockchain ID to listing p := new(pb.ID_Pubkeys) p.Guid = pubkey p.Bitcoin = n.Wallet.GetMasterPublicKey().Key id.Pubkeys = p listing.VendorID = id s := new(pb.Signatures) s.Section = pb.Signatures_LISTING serializedListing, err := proto.Marshal(listing) if err != nil { return c, err } guidSig, err := n.IpfsNode.PrivateKey.Sign(serializedListing) if err != nil { return c, err } priv, _ := ec.PrivKeyFromBytes(ec.S256(), n.Wallet.GetMasterPrivateKey().Key) hashed := sha256.Sum256(serializedListing) bitcoinSig, err := priv.Sign(hashed[:]) if err != nil { return c, err } s.Guid = guidSig s.Bitcoin = bitcoinSig.Serialize() c.VendorListings = append(c.VendorListings, listing) c.Signatures = append(c.Signatures, s) return c, nil }
// DecodeWIF creates a new WIF structure by decoding the string encoding of // the import format. // // The WIF string must be a base58-encoded string of the following byte // sequence: // // * 1 byte to identify the network, must be 0x80 for mainnet or 0xef for // either testnet3 or the regression test network // * 32 bytes of a binary-encoded, big-endian, zero-padded private key // * Optional 1 byte (equal to 0x01) if the address being imported or exported // was created by taking the RIPEMD160 after SHA256 hash of a serialized // compressed (33-byte) public key // * 4 bytes of checksum, must equal the first four bytes of the double SHA256 // of every byte before the checksum in this sequence // // If the base58-decoded byte sequence does not match this, DecodeWIF will // return a non-nil error. ErrMalformedPrivateKey is returned when the WIF // is of an impossible length or the expected compressed pubkey magic number // does not equal the expected value of 0x01. ErrChecksumMismatch is returned // if the expected WIF checksum does not match the calculated checksum. func DecodeWIF(wif string) (*WIF, error) { decoded := base58.Decode(wif) decodedLen := len(decoded) var compress bool // Length of base58 decoded WIF must be 32 bytes + an optional 1 byte // (0x01) if compressed, plus 1 byte for netID + 4 bytes of checksum. switch decodedLen { case 1 + btcec.PrivKeyBytesLen + 1 + 4: if decoded[33] != compressMagic { return nil, ErrMalformedPrivateKey } compress = true case 1 + btcec.PrivKeyBytesLen + 4: compress = false default: return nil, ErrMalformedPrivateKey } // Checksum is first four bytes of double SHA256 of the identifier byte // and privKey. Verify this matches the final 4 bytes of the decoded // private key. var tosum []byte if compress { tosum = decoded[:1+btcec.PrivKeyBytesLen+1] } else { tosum = decoded[:1+btcec.PrivKeyBytesLen] } cksum := chainhash.DoubleHashB(tosum)[:4] if !bytes.Equal(cksum, decoded[decodedLen-4:]) { return nil, ErrChecksumMismatch } netID := decoded[0] privKeyBytes := decoded[1 : 1+btcec.PrivKeyBytesLen] privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes) return &WIF{privKey, compress, netID}, nil }
//Sign takes a hex-encoded string slice of private //keys and uses them to sign the ToSign data in a //MicroTX, generating the proper hex-encoded Signatures. //This is meant as a helperfunction, and leverages //btcd's btcec library. func (mic *MicroTX) Sign(priv string) (err error) { privDat, err := hex.DecodeString(priv) if err != nil { return } privkey, pubkey := btcec.PrivKeyFromBytes(btcec.S256(), privDat) if mic.Pubkey != hex.EncodeToString(pubkey.SerializeCompressed()) { err = errors.New("*MicroTX.Sign error: public key does not match private key") return } for _, k := range mic.ToSign { tosign, err := hex.DecodeString(k) if err != nil { return err } sig, err := privkey.Sign(tosign) if err != nil { return err } mic.Signatures = append(mic.Signatures, hex.EncodeToString(sig.Serialize())) } return }
// DecodeWIF creates a new WIF structure by decoding the string encoding of // the import format. // // The WIF string must be a base58-encoded string of the following byte // sequence: // // * 2 bytes to identify the network, must be 0x80 for mainnet or 0xef for // either testnet or the regression test network // * 1 extra byte // * 32 bytes of a binary-encoded, big-endian, zero-padded private key // * 4 bytes of checksum, must equal the first four bytes of the double SHA256 // of every byte before the checksum in this sequence // // If the base58-decoded byte sequence does not match this, DecodeWIF will // return a non-nil error. ErrMalformedPrivateKey is returned when the WIF // is of an impossible length. ErrChecksumMismatch is returned if the // expected WIF checksum does not match the calculated checksum. func DecodeWIF(wif string) (*WIF, error) { decoded := base58.Decode(wif) decodedLen := len(decoded) if decodedLen != 39 { return nil, ErrMalformedPrivateKey } // Checksum is first four bytes of hash of the identifier byte // and privKey. Verify this matches the final 4 bytes of the decoded // private key. cksum := chainhash.HashFuncB(decoded[:decodedLen-4]) if !bytes.Equal(cksum[:4], decoded[decodedLen-4:]) { return nil, address.ErrChecksumMismatch } netID := [2]byte{decoded[0], decoded[1]} privKeyBytes := decoded[3 : 3+btcec.PrivKeyBytesLen] privKey, _ := btcec.PrivKeyFromBytes(curve, privKeyBytes) return &WIF{0, *privKey, netID}, nil }
//Sign takes a hex-encoded string slice of private //keys and uses them to sign the ToSign data in a //TXSkel, generating the proper Signatures and PubKeys //array, both hex-encoded. This is meant as a helper //function, and leverages btcd's btcec library. func (skel *TXSkel) Sign(c appengine.Context, priv []string) (err error) { //num of private keys must match len(ToSign) //Often this might mean repeating private keys if len(priv) != len(skel.ToSign) { err = errors.New("*TXSkel.Sign error: number of private keys != length of ToSign array") return } //Loop through keys, append sigs/public key for i, k := range priv { privDat, err := hex.DecodeString(k) tosign, err := hex.DecodeString(skel.ToSign[i]) if err != nil { return err } privkey, pubkey := btcec.PrivKeyFromBytes(btcec.S256(), privDat) sig, err := privkey.Sign(tosign) if err != nil { return err } skel.Signatures = append(skel.Signatures, hex.EncodeToString(sig.Serialize())) skel.PubKeys = append(skel.PubKeys, hex.EncodeToString(pubkey.SerializeCompressed())) } return }
// Test the sigscript generation for valid and invalid inputs, all // hashTypes, and with and without compression. This test creates // sigscripts to spend fake coinbase inputs, as sigscripts cannot be // created for the MsgTxs in txTests, since they come from the blockchain // and we don't have the private keys. func TestSignatureScript(t *testing.T) { t.Parallel() privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKeyD) nexttest: for i := range sigScriptTests { tx := wire.NewMsgTx(wire.TxVersion) output := wire.NewTxOut(500, []byte{OP_RETURN}) tx.AddTxOut(output) for range sigScriptTests[i].inputs { txin := wire.NewTxIn(coinbaseOutPoint, nil) tx.AddTxIn(txin) } var script []byte var err error for j := range tx.TxIn { var idx int if sigScriptTests[i].inputs[j].indexOutOfRange { t.Errorf("at test %v", sigScriptTests[i].name) idx = len(sigScriptTests[i].inputs) } else { idx = j } script, err = SignatureScript(tx, idx, sigScriptTests[i].inputs[j].txout.PkScript, sigScriptTests[i].hashType, privKey, sigScriptTests[i].compress) if (err == nil) != sigScriptTests[i].inputs[j].sigscriptGenerates { if err == nil { t.Errorf("passed test '%v' incorrectly", sigScriptTests[i].name) } else { t.Errorf("failed test '%v': %v", sigScriptTests[i].name, err) } continue nexttest } if !sigScriptTests[i].inputs[j].sigscriptGenerates { // done with this test continue nexttest } tx.TxIn[j].SignatureScript = script } // If testing using a correct sigscript but for an incorrect // index, use last input script for first input. Requires > 0 // inputs for test. if sigScriptTests[i].scriptAtWrongIndex { tx.TxIn[0].SignatureScript = script sigScriptTests[i].inputs[0].inputValidates = false } // Validate tx input scripts scriptFlags := ScriptBip16 | ScriptVerifyDERSignatures for j := range tx.TxIn { vm, err := NewEngine(sigScriptTests[i].inputs[j].txout. PkScript, tx, j, scriptFlags, nil) if err != nil { t.Errorf("cannot create script vm for test %v: %v", sigScriptTests[i].name, err) continue nexttest } err = vm.Execute() if (err == nil) != sigScriptTests[i].inputs[j].inputValidates { if err == nil { t.Errorf("passed test '%v' validation incorrectly: %v", sigScriptTests[i].name, err) } else { t.Errorf("failed test '%v' validation: %v", sigScriptTests[i].name, err) } continue nexttest } } } }
func loadTestCredits(w *LightningWallet, numOutputs, btcPerOutput int) error { // Import the priv key (converting to WIF) above that controls all our // available outputs. privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), testWalletPrivKey) if err := w.Unlock(privPass, time.Duration(0)); err != nil { return err } bs := &waddrmgr.BlockStamp{Hash: *genBlockHash(1), Height: 1} wif, err := btcutil.NewWIF(privKey, ActiveNetParams, true) if err != nil { return err } if _, err := w.ImportPrivateKey(wif, bs, false); err != nil { return nil } if err := w.Manager.SetSyncedTo(&waddrmgr.BlockStamp{int32(1), *genBlockHash(1)}); err != nil { return err } blk := wtxmgr.BlockMeta{wtxmgr.Block{Hash: *genBlockHash(2), Height: 2}, time.Now()} // Create a simple P2PKH pubkey script spendable by Alice. For simplicity // all of Alice's spendable funds will reside in this output. satosihPerOutput := int64(btcPerOutput * 1e8) walletAddr, err := btcutil.NewAddressPubKey(privKey.PubKey().SerializeCompressed(), ActiveNetParams) if err != nil { return err } walletScriptCredit, err := txscript.PayToAddrScript(walletAddr.AddressPubKeyHash()) if err != nil { return err } // Create numOutputs outputs spendable by our wallet each holding btcPerOutput // in satoshis. tx := wire.NewMsgTx() prevOut := wire.NewOutPoint(genBlockHash(999), 1) txIn := wire.NewTxIn(prevOut, []byte{txscript.OP_0, txscript.OP_0}) tx.AddTxIn(txIn) for i := 0; i < numOutputs; i++ { tx.AddTxOut(wire.NewTxOut(satosihPerOutput, walletScriptCredit)) } txCredit, err := wtxmgr.NewTxRecordFromMsgTx(tx, time.Now()) if err != nil { return err } if err := addTestTx(w, txCredit, &blk); err != nil { return err } if err := w.Manager.SetSyncedTo(&waddrmgr.BlockStamp{int32(2), *genBlockHash(2)}); err != nil { return err } // Make the wallet think it's been synced to block 10. This way the // outputs we added above will have sufficient confirmations // (hard coded to 6 atm). for i := 3; i < 10; i++ { sha := *genBlockHash(i) if err := w.Manager.SetSyncedTo(&waddrmgr.BlockStamp{int32(i), sha}); err != nil { return err } } return nil }