示例#1
0
文件: wif_test.go 项目: jrick/btcutil
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, &btcnet.MainNetParams, false)
	if err != nil {
		t.Fatal(err)
	}
	wif2, err := NewWIF(priv2, &btcnet.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)
		}
	}
}
示例#2
0
// 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 := btcwire.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
}
示例#3
0
// 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
}
示例#4
0
文件: key.go 项目: Zoramite/ripple
func newKey(priv, inc *big.Int, f genFunc) *baseKey {
	pk := big.NewInt(0).Set(priv)
	for ; f(pk); inc.Add(inc, one) {
		pk.SetBytes(Sha512Half(inc.Bytes()))
	}
	privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), pk.Bytes())
	return &baseKey{*privKey}
}
示例#5
0
文件: key.go 项目: robcat/ripple
func newKey(priv, inc *big.Int, f genFunc) (*baseKey, error) {
	pk := big.NewInt(0).Set(priv)
	for ; f(pk); inc.Add(inc, one) {
		b, err := Sha512Half(inc.Bytes())
		if err != nil {
			return nil, err
		}
		pk.SetBytes(b)
	}
	privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), pk.Bytes())
	return &baseKey{*privKey}, nil
}
示例#6
0
func TestPrivKeys(t *testing.T) {
	for _, test := range privKeyTests {
		_, 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
		}
	}
}
示例#7
0
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)
		}
	}
}
示例#8
0
/*-
- Tx genrates a hex-encoded string that can be sent to a bitcoin node, or
- blockchain.info/pushtx to broadcast and submite a transaction to the bitcoin
- network.
- Args:
- fromPrivateKeyWif => is wallet owner's privateKey, Wif stand for
- wallet import fromat. refer to https://lh4.googleusercontent.com
- /-p8yVJXqY7fg/UuLaPjMDtyI/AAAAAAAAWYQ/QoenRIBO1O4/s2048/bitcoinkeys.png
- for various key types in btc.
- toAddress => reciver's address. Public key and address are the same.
- amount => the amount to be debited from the owner, and sent to the reciver.
-*/
func Tx(fromPrivateKeyWif string, toAddress string, amount float64) (string, error) {
	var signedScript bytes.Buffer
	transferAmount := uint64(amount * 100000000)
	/*- all required key types -*/
	fromPrivateKeyBytes := base58CheckDecodeKey(fromPrivateKeyWif)
	fromPrivateKeyStruct, fromPublicKeyStruct := btcec.PrivKeyFromBytes(
		btcec.S256(), fromPrivateKeyBytes)
	fromPublicKeyBytes := publicKeyStructToPublicKeyBytes(fromPublicKeyStruct)
	fromPublicKeyBase58 := base58CheckEncodeKey(byte(0), publicKeyHash(fromPublicKeyBytes))
	/*- build inputs and outputs -*/
	input, change, err := getUnspent(fromPublicKeyBase58, transferAmount)
	if err != nil {
		return err.Error(), err
	}
	output := make([]*tx_out, 1, 2)
	output[0] = new(tx_out)
	output[0].address = toAddress
	output[0].amount = transferAmount
	/*- add the mining fees -*/
	if change > miningFees {
		outputChange := new(tx_out)
		outputChange.address = fromPublicKeyBase58
		outputChange.amount = change - miningFees
		output = append(output, outputChange)
	} else {
		output[0].amount -= miningFees
	}
	/*- build hash of raw transaction for signing -*/
	rawTxTemp := makeRawTx(input, makeScriptPubKey(fromPublicKeyBase58), output)
	if rawTxTemp == nil {
		return "", errors.New("Deformed output address")
	}
	tx := append(rawTxTemp, uint32Bytes(1)...)
	tx_hash0 := sha256.Sum256(tx)
	tx_hash := sha256.Sum256(tx_hash0[:])
	tempSig, _ := fromPrivateKeyStruct.Sign(tx_hash[:])
	signature := append(tempSig.Serialize(), byte(1))
	/*- build script_sig -*/
	signedScript.Write(formatVarInt(len(signature)))
	signedScript.Write(signature)
	signedScript.Write(formatVarInt(len(fromPublicKeyBytes)))
	signedScript.Write(fromPublicKeyBytes)
	/*- return the hex-encoded signed transaction -*/
	return hex.EncodeToString(makeRawTx(input, signedScript.Bytes(), output)), nil
}
示例#9
0
文件: bw.go 项目: kac-/tmp
func main() {
	lines := bufio.NewReader(os.Stdin)
	hasher := fastsha256.New()
	for {
		line, _, err := lines.ReadLine()
		if err != nil {
			break
		}

		hasher.Reset()
		hasher.Write(line)
		sum := hasher.Sum(nil)

		_, pub := btcec.PrivKeyFromBytes(btcec.S256(), sum)
		var apk, _ = btcutil.NewAddressPubKey(pub.SerializeUncompressed(), btcwire.MainNet)
		fmt.Println(apk.EncodeAddress())
		apk, _ = btcutil.NewAddressPubKey(pub.SerializeCompressed(), btcwire.MainNet)
		fmt.Println(apk.EncodeAddress())
	}
}
示例#10
0
文件: wif.go 项目: jrick/btcutil
// 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 := Base58Decode(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 := btcwire.DoubleSha256(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
}
示例#11
0
/*-
- Retrives the public key from the currusponding private key. Only one public key
- exists for a private key. The public key would be the wallet owner's address.
*/
func GetPublicKey(privateKeyWif string) string {
	privateKeyBytes := base58CheckDecodeKey(privateKeyWif)
	_, publicKeyStrut := btcec.PrivKeyFromBytes(btcec.S256(), privateKeyBytes)
	publicKeyHash := publicKeyHash(publicKeyStructToPublicKeyBytes(publicKeyStrut))
	return base58CheckEncodeKey(0, publicKeyHash)
}
示例#12
0
func TestWatchingWalletExport(t *testing.T) {
	const keypoolSize = 10
	createdAt := &BlockStamp{}
	w, err := NewWallet("banana wallet", "A wallet for testing.",
		[]byte("banana"), tstNetParams, createdAt, keypoolSize)
	if err != nil {
		t.Error("Error creating new wallet: " + err.Error())
		return
	}

	// Maintain a set of the active addresses in the wallet.
	activeAddrs := make(map[addressKey]struct{})

	// Add root address.
	activeAddrs[getAddressKey(w.LastChainedAddress())] = struct{}{}

	// Get as many new active addresses as necessary to deplete the keypool.
	// This is done as we will want to test that new addresses created by
	// the watching wallet do not pull from previous public keys in the
	// original keypool.
	for i := 0; i < keypoolSize; i++ {
		apkh, err := w.NextChainedAddress(createdAt, keypoolSize)
		if err != nil {
			t.Errorf("unable to get next address: %v", err)
			return
		}
		activeAddrs[getAddressKey(apkh)] = struct{}{}
	}

	// Create watching wallet from w.
	ww, err := w.ExportWatchingWallet()
	if err != nil {
		t.Errorf("Could not create watching wallet: %v", err)
		return
	}

	// Verify correctness of wallet flags.
	if ww.flags.useEncryption {
		t.Errorf("Watching wallet marked as using encryption (but nothing to encrypt).")
		return
	}
	if !ww.flags.watchingOnly {
		t.Errorf("Wallet should be watching-only but is not marked so.")
		return
	}

	// Verify that all flags are set as expected.
	if ww.keyGenerator.flags.encrypted {
		t.Errorf("Watching root address should not be encrypted (nothing to encrypt)")
		return
	}
	if ww.keyGenerator.flags.hasPrivKey {
		t.Errorf("Watching root address marked as having a private key.")
		return
	}
	if !ww.keyGenerator.flags.hasPubKey {
		t.Errorf("Watching root address marked as missing a public key.")
		return
	}
	if ww.keyGenerator.flags.createPrivKeyNextUnlock {
		t.Errorf("Watching root address marked as needing a private key to be generated later.")
		return
	}
	for apkh, waddr := range ww.addrMap {
		switch addr := waddr.(type) {
		case *btcAddress:
			if addr.flags.encrypted {
				t.Errorf("Chained address should not be encrypted (nothing to encrypt)")
				return
			}
			if addr.flags.hasPrivKey {
				t.Errorf("Chained address marked as having a private key.")
				return
			}
			if !addr.flags.hasPubKey {
				t.Errorf("Chained address marked as missing a public key.")
				return
			}
			if addr.flags.createPrivKeyNextUnlock {
				t.Errorf("Chained address marked as needing a private key to be generated later.")
				return
			}
		case *scriptAddress:
			t.Errorf("Chained address was a script!")
			return
		default:
			t.Errorf("Chained address unknown type!")
			return
		}

		if _, ok := activeAddrs[apkh]; !ok {
			t.Errorf("Address from watching wallet not found in original wallet.")
			return
		}
		delete(activeAddrs, apkh)
	}
	if len(activeAddrs) != 0 {
		t.Errorf("%v address(es) were not exported to watching wallet.", len(activeAddrs))
		return
	}

	// Check that the new addresses created by each wallet match.  The
	// original wallet is unlocked so the keypool is refilled and chained
	// addresses use the previous' privkey, not pubkey.
	if err := w.Unlock([]byte("banana")); err != nil {
		t.Errorf("Unlocking original wallet failed: %v", err)
	}
	for i := 0; i < keypoolSize; i++ {
		addr, err := w.NextChainedAddress(createdAt, keypoolSize)
		if err != nil {
			t.Errorf("Cannot get next chained address for original wallet: %v", err)
			return
		}
		waddr, err := ww.NextChainedAddress(createdAt, keypoolSize)
		if err != nil {
			t.Errorf("Cannot get next chained address for watching wallet: %v", err)
			return
		}
		if addr.EncodeAddress() != waddr.EncodeAddress() {
			t.Errorf("Next addresses for each wallet do not match eachother.")
			return
		}
	}

	// Test that ExtendActiveAddresses for the watching wallet match
	// manually requested addresses of the original wallet.
	newAddrs := make([]btcutil.Address, 0, keypoolSize)
	for i := 0; i < keypoolSize; i++ {
		addr, err := w.NextChainedAddress(createdAt, keypoolSize)
		if err != nil {
			t.Errorf("Cannot get next chained address for original wallet: %v", err)
			return
		}
		newAddrs = append(newAddrs, addr)
	}
	newWWAddrs, err := ww.ExtendActiveAddresses(keypoolSize, keypoolSize)
	if err != nil {
		t.Errorf("Cannot extend active addresses for watching wallet: %v", err)
		return
	}
	for i := range newAddrs {
		if newAddrs[i].EncodeAddress() != newWWAddrs[i].EncodeAddress() {
			t.Errorf("Extended active addresses do not match manually requested addresses.")
			return
		}
	}

	// Test ExtendActiveAddresses for the original wallet after manually
	// requesting addresses for the watching wallet.
	newWWAddrs = make([]btcutil.Address, 0, keypoolSize)
	for i := 0; i < keypoolSize; i++ {
		addr, err := ww.NextChainedAddress(createdAt, keypoolSize)
		if err != nil {
			t.Errorf("Cannot get next chained address for watching wallet: %v", err)
			return
		}
		newWWAddrs = append(newWWAddrs, addr)
	}
	newAddrs, err = w.ExtendActiveAddresses(keypoolSize, keypoolSize)
	if err != nil {
		t.Errorf("Cannot extend active addresses for original wallet: %v", err)
		return
	}
	for i := range newAddrs {
		if newAddrs[i].EncodeAddress() != newWWAddrs[i].EncodeAddress() {
			t.Errorf("Extended active addresses do not match manually requested addresses.")
			return
		}
	}

	// Test (de)serialization of watching wallet.
	buf := new(bytes.Buffer)
	_, err = ww.WriteTo(buf)
	if err != nil {
		t.Errorf("Cannot write watching wallet: %v", err)
		return
	}
	ww2 := new(Wallet)
	_, err = ww2.ReadFrom(buf)
	if err != nil {
		t.Errorf("Cannot read watching wallet: %v", err)
		return
	}

	// Check that (de)serialized watching wallet matches the exported wallet.
	if !reflect.DeepEqual(ww, ww2) {
		t.Error("Exported and read-in watching wallets do not match.")
		return
	}

	// Verify that nonsensical functions fail with correct error.
	if err := ww.Lock(); err != ErrWalletIsWatchingOnly {
		t.Errorf("Nonsensical func Lock returned no or incorrect error: %v", err)
		return
	}
	if err := ww.Unlock([]byte("banana")); err != ErrWalletIsWatchingOnly {
		t.Errorf("Nonsensical func Unlock returned no or incorrect error: %v", err)
		return
	}
	generator, err := ww.Address(w.keyGenerator.Address())
	if err != nil {
		t.Errorf("generator isnt' present in wallet")
	}
	gpk := generator.(PubKeyAddress)
	if _, err := gpk.PrivKey(); err != ErrWalletIsWatchingOnly {
		t.Errorf("Nonsensical func AddressKey returned no or incorrect error: %v", err)
		return
	}
	if _, err := ww.ExportWatchingWallet(); err != ErrWalletIsWatchingOnly {
		t.Errorf("Nonsensical func ExportWatchingWallet returned no or incorrect error: %v", err)
		return
	}
	pk, _ := btcec.PrivKeyFromBytes(btcec.S256(), make([]byte, 32))
	wif, err := btcutil.NewWIF(pk, tstNetParams, true)
	if err != nil {
		t.Fatal(err)
	}
	if _, err := ww.ImportPrivateKey(wif, createdAt); err != ErrWalletIsWatchingOnly {
		t.Errorf("Nonsensical func ImportPrivateKey returned no or incorrect error: %v", err)
		return
	}
}