mirror of
https://github.com/FlipsideCrypto/dcrd.git
synced 2026-02-06 10:56:47 +00:00
dcrutil: Disallow creation of hybrid P2PK addrs.
Hybrid pubkeys, which are a relic of OpenSSL used in Bitcoin Core, are not usable with OP_CHECKSIG and we can potentially prevent creating unspendable outputs by never allowing the creation of P2PK (or derived P2PKH) addresses for these pubkeys.
This commit is contained in:
parent
4e01f768cb
commit
dcc58786d3
@ -419,12 +419,12 @@ const (
|
||||
// PKFCompressed indicates the pay-to-pubkey address format is a
|
||||
// compressed public key.
|
||||
PKFCompressed
|
||||
|
||||
// PKFHybrid indicates the pay-to-pubkey address format is a hybrid
|
||||
// public key.
|
||||
PKFHybrid
|
||||
)
|
||||
|
||||
// ErrInvalidPubKeyFormat indicates that a serialized pubkey is unusable as it
|
||||
// is neither in the uncompressed or compressed format.
|
||||
var ErrInvalidPubKeyFormat = errors.New("invalid pubkey format")
|
||||
|
||||
// AddressSecpPubKey is an Address for a secp256k1 pay-to-pubkey transaction.
|
||||
type AddressSecpPubKey struct {
|
||||
net *chaincfg.Params
|
||||
@ -435,8 +435,7 @@ type AddressSecpPubKey struct {
|
||||
|
||||
// NewAddressSecpPubKey returns a new AddressSecpPubKey which represents a
|
||||
// pay-to-pubkey address, using a secp256k1 pubkey. The serializedPubKey
|
||||
// parameter must be a valid pubkey and can be uncompressed, compressed, or
|
||||
// hybrid.
|
||||
// parameter must be a valid pubkey and must be uncompressed or compressed.
|
||||
func NewAddressSecpPubKey(serializedPubKey []byte,
|
||||
net *chaincfg.Params) (*AddressSecpPubKey, error) {
|
||||
pubKey, err := chainec.Secp256k1.ParsePubKey(serializedPubKey)
|
||||
@ -448,12 +447,14 @@ func NewAddressSecpPubKey(serializedPubKey []byte,
|
||||
// from dcrec, but do it here to avoid API churn. We already know the
|
||||
// pubkey is valid since it parsed above, so it's safe to simply examine
|
||||
// the leading byte to get the format.
|
||||
pkFormat := PKFUncompressed
|
||||
var pkFormat PubKeyFormat
|
||||
switch serializedPubKey[0] {
|
||||
case 0x02, 0x03:
|
||||
pkFormat = PKFCompressed
|
||||
case 0x06, 0x07:
|
||||
pkFormat = PKFHybrid
|
||||
case 0x04:
|
||||
pkFormat = PKFUncompressed
|
||||
default:
|
||||
return nil, ErrInvalidPubKeyFormat
|
||||
}
|
||||
|
||||
return &AddressSecpPubKey{
|
||||
@ -475,9 +476,6 @@ func (a *AddressSecpPubKey) serialize() []byte {
|
||||
|
||||
case PKFCompressed:
|
||||
return a.pubKey.SerializeCompressed()
|
||||
|
||||
case PKFHybrid:
|
||||
return a.pubKey.SerializeHybrid()
|
||||
}
|
||||
}
|
||||
|
||||
@ -671,8 +669,7 @@ type AddressSecSchnorrPubKey struct {
|
||||
|
||||
// NewAddressSecSchnorrPubKey returns a new AddressSecpPubKey which represents a
|
||||
// pay-to-pubkey address, using a secp256k1 pubkey. The serializedPubKey
|
||||
// parameter must be a valid pubkey and can be uncompressed, compressed, or
|
||||
// hybrid.
|
||||
// parameter must be a valid pubkey and must be compressed.
|
||||
func NewAddressSecSchnorrPubKey(serializedPubKey []byte,
|
||||
net *chaincfg.Params) (*AddressSecSchnorrPubKey, error) {
|
||||
pubKey, err := chainec.SecSchnorr.ParsePubKey(serializedPubKey)
|
||||
|
||||
@ -237,7 +237,6 @@ func TestAddresses(t *testing.T) {
|
||||
},
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
// Hybrid, uncompressed and compressed key types are supported, dcrd consensus rules require a compressed key type however.
|
||||
{
|
||||
name: "mainnet p2pk uncompressed (0x04)",
|
||||
addr: "DkM3EyZ546GghVSkvzb6J47PvGDyntqiDtFgipQhNj78Xm2mUYRpf",
|
||||
@ -267,64 +266,6 @@ func TestAddresses(t *testing.T) {
|
||||
},
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "mainnet p2pk hybrid (0x06)",
|
||||
addr: "DkM3EyZ546GghVSkvzb6J47PvGDyntqiDtFgipQhNj78Xm2mUYRpf",
|
||||
encoded: "DsfFjaADsV8c5oHWx85ZqfxCZy74K8RFuhK",
|
||||
valid: true,
|
||||
saddr: "0264c44653d6567eff5753c5d24a682ddc2b2cadfe1b0c6433b16374dace6778f0",
|
||||
result: dcrutil.TstAddressPubKey(
|
||||
[]byte{
|
||||
0x06, 0x64, 0xc4, 0x46, 0x53, 0xd6, 0x56, 0x7e, 0xff, 0x57,
|
||||
0x53, 0xc5, 0xd2, 0x4a, 0x68, 0x2d, 0xdc, 0x2b, 0x2c, 0xad,
|
||||
0xfe, 0x1b, 0x0c, 0x64, 0x33, 0xb1, 0x63, 0x74, 0xda, 0xce,
|
||||
0x67, 0x78, 0xf0, 0xb8, 0x7c, 0xa4, 0x27, 0x9b, 0x56, 0x5d,
|
||||
0x21, 0x30, 0xce, 0x59, 0xf7, 0x5b, 0xfb, 0xb2, 0xb8, 0x8d,
|
||||
0xa7, 0x94, 0x14, 0x3d, 0x7c, 0xfd, 0x3e, 0x80, 0x80, 0x8a,
|
||||
0x1f, 0xa3, 0x20, 0x39, 0x04},
|
||||
dcrutil.PKFHybrid, chaincfg.MainNetParams.PubKeyHashAddrID),
|
||||
f: func() (dcrutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x06, 0x64, 0xc4, 0x46, 0x53, 0xd6, 0x56, 0x7e, 0xff, 0x57,
|
||||
0x53, 0xc5, 0xd2, 0x4a, 0x68, 0x2d, 0xdc, 0x2b, 0x2c, 0xad,
|
||||
0xfe, 0x1b, 0x0c, 0x64, 0x33, 0xb1, 0x63, 0x74, 0xda, 0xce,
|
||||
0x67, 0x78, 0xf0, 0xb8, 0x7c, 0xa4, 0x27, 0x9b, 0x56, 0x5d,
|
||||
0x21, 0x30, 0xce, 0x59, 0xf7, 0x5b, 0xfb, 0xb2, 0xb8, 0x8d,
|
||||
0xa7, 0x94, 0x14, 0x3d, 0x7c, 0xfd, 0x3e, 0x80, 0x80, 0x8a,
|
||||
0x1f, 0xa3, 0x20, 0x39, 0x04}
|
||||
return dcrutil.NewAddressSecpPubKey(serializedPubKey, &chaincfg.MainNetParams)
|
||||
},
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "mainnet p2pk hybrid (0x07)",
|
||||
addr: "DkRKh2aTdwjKKL1mkCb2DFp2Hr7SqMyx3zWqNwyc37PYiGpKmGRsi",
|
||||
encoded: "DskEQZMCs4nifL7wx7iHYGWxMQvR9ThCBKQ",
|
||||
valid: true,
|
||||
saddr: "03348d8aeb4253ca52456fe5da94ab1263bfee16bb8192497f666389ca964f8479",
|
||||
result: dcrutil.TstAddressPubKey(
|
||||
[]byte{
|
||||
0x07, 0x34, 0x8d, 0x8a, 0xeb, 0x42, 0x53, 0xca, 0x52, 0x45,
|
||||
0x6f, 0xe5, 0xda, 0x94, 0xab, 0x12, 0x63, 0xbf, 0xee, 0x16,
|
||||
0xbb, 0x81, 0x92, 0x49, 0x7f, 0x66, 0x63, 0x89, 0xca, 0x96,
|
||||
0x4f, 0x84, 0x79, 0x83, 0x75, 0x12, 0x9d, 0x79, 0x58, 0x84,
|
||||
0x3b, 0x14, 0x25, 0x8b, 0x90, 0x5d, 0xc9, 0x4f, 0xae, 0xd3,
|
||||
0x24, 0xdd, 0x8a, 0x9d, 0x67, 0xff, 0xac, 0x8c, 0xc0, 0xa8,
|
||||
0x5b, 0xe8, 0x4b, 0xac, 0x5d},
|
||||
dcrutil.PKFHybrid, chaincfg.MainNetParams.PubKeyHashAddrID),
|
||||
f: func() (dcrutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x07, 0x34, 0x8d, 0x8a, 0xeb, 0x42, 0x53, 0xca, 0x52, 0x45,
|
||||
0x6f, 0xe5, 0xda, 0x94, 0xab, 0x12, 0x63, 0xbf, 0xee, 0x16,
|
||||
0xbb, 0x81, 0x92, 0x49, 0x7f, 0x66, 0x63, 0x89, 0xca, 0x96,
|
||||
0x4f, 0x84, 0x79, 0x83, 0x75, 0x12, 0x9d, 0x79, 0x58, 0x84,
|
||||
0x3b, 0x14, 0x25, 0x8b, 0x90, 0x5d, 0xc9, 0x4f, 0xae, 0xd3,
|
||||
0x24, 0xdd, 0x8a, 0x9d, 0x67, 0xff, 0xac, 0x8c, 0xc0, 0xa8,
|
||||
0x5b, 0xe8, 0x4b, 0xac, 0x5d}
|
||||
return dcrutil.NewAddressSecpPubKey(serializedPubKey, &chaincfg.MainNetParams)
|
||||
},
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "testnet p2pk compressed (0x02)",
|
||||
addr: "Tso9sQD3ALqRsmEkAm7KvPrkGbeG2Vun7Kv",
|
||||
@ -398,22 +339,46 @@ func TestAddresses(t *testing.T) {
|
||||
},
|
||||
net: &chaincfg.TestNet2Params,
|
||||
},
|
||||
|
||||
// Negative P2PK tests.
|
||||
{
|
||||
name: "testnet p2pk hybrid (0x06)",
|
||||
addr: "TkKmMiY5iDh4U3KkSopYgkU1AzhAcQZiSoVhYhFymZHGMi9LM9Fdt",
|
||||
encoded: "Tso9sQD3ALqRsmEkAm7KvPrkGbeG2Vun7Kv",
|
||||
valid: true,
|
||||
saddr: "026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06e",
|
||||
result: dcrutil.TstAddressPubKey(
|
||||
[]byte{
|
||||
0x06, 0x6a, 0x40, 0xc4, 0x03, 0xe7, 0x46, 0x70, 0xc4, 0xde,
|
||||
0x76, 0x56, 0xa0, 0x9c, 0xaa, 0x23, 0x53, 0xd4, 0xb3, 0x83,
|
||||
0xa9, 0xce, 0x66, 0xee, 0xf5, 0x1e, 0x12, 0x20, 0xea, 0xcf,
|
||||
0x4b, 0xe0, 0x6e, 0xd5, 0x48, 0xc8, 0xc1, 0x6f, 0xb5, 0xeb,
|
||||
0x90, 0x07, 0xcb, 0x94, 0x22, 0x0b, 0x3b, 0xb8, 0x94, 0x91,
|
||||
0xd5, 0xa1, 0xfd, 0x2d, 0x77, 0x86, 0x7f, 0xca, 0x64, 0x21,
|
||||
0x7a, 0xce, 0xcf, 0x22, 0x44},
|
||||
dcrutil.PKFHybrid, chaincfg.TestNet2Params.PubKeyHashAddrID),
|
||||
name: "mainnet p2pk hybrid (0x06)",
|
||||
addr: "",
|
||||
valid: false,
|
||||
f: func() (dcrutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x06, 0x64, 0xc4, 0x46, 0x53, 0xd6, 0x56, 0x7e, 0xff, 0x57,
|
||||
0x53, 0xc5, 0xd2, 0x4a, 0x68, 0x2d, 0xdc, 0x2b, 0x2c, 0xad,
|
||||
0xfe, 0x1b, 0x0c, 0x64, 0x33, 0xb1, 0x63, 0x74, 0xda, 0xce,
|
||||
0x67, 0x78, 0xf0, 0xb8, 0x7c, 0xa4, 0x27, 0x9b, 0x56, 0x5d,
|
||||
0x21, 0x30, 0xce, 0x59, 0xf7, 0x5b, 0xfb, 0xb2, 0xb8, 0x8d,
|
||||
0xa7, 0x94, 0x14, 0x3d, 0x7c, 0xfd, 0x3e, 0x80, 0x80, 0x8a,
|
||||
0x1f, 0xa3, 0x20, 0x39, 0x04}
|
||||
return dcrutil.NewAddressSecpPubKey(serializedPubKey, &chaincfg.MainNetParams)
|
||||
},
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "mainnet p2pk hybrid (0x07)",
|
||||
addr: "",
|
||||
valid: false,
|
||||
f: func() (dcrutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x07, 0x34, 0x8d, 0x8a, 0xeb, 0x42, 0x53, 0xca, 0x52, 0x45,
|
||||
0x6f, 0xe5, 0xda, 0x94, 0xab, 0x12, 0x63, 0xbf, 0xee, 0x16,
|
||||
0xbb, 0x81, 0x92, 0x49, 0x7f, 0x66, 0x63, 0x89, 0xca, 0x96,
|
||||
0x4f, 0x84, 0x79, 0x83, 0x75, 0x12, 0x9d, 0x79, 0x58, 0x84,
|
||||
0x3b, 0x14, 0x25, 0x8b, 0x90, 0x5d, 0xc9, 0x4f, 0xae, 0xd3,
|
||||
0x24, 0xdd, 0x8a, 0x9d, 0x67, 0xff, 0xac, 0x8c, 0xc0, 0xa8,
|
||||
0x5b, 0xe8, 0x4b, 0xac, 0x5d}
|
||||
return dcrutil.NewAddressSecpPubKey(serializedPubKey, &chaincfg.MainNetParams)
|
||||
},
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "testnet p2pk hybrid (0x06)",
|
||||
addr: "",
|
||||
valid: false,
|
||||
f: func() (dcrutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x06, 0x6a, 0x40, 0xc4, 0x03, 0xe7, 0x46, 0x70, 0xc4, 0xde,
|
||||
@ -428,21 +393,9 @@ func TestAddresses(t *testing.T) {
|
||||
net: &chaincfg.TestNet2Params,
|
||||
},
|
||||
{
|
||||
name: "testnet p2pk hybrid (0x07)",
|
||||
addr: "TkQ5Ax2ieEZpBDA963VDH4y27KMpXtP8qyeykzwBNFocDc8ZKqTGz",
|
||||
encoded: "TsTFLdM32YVrYsEQDFxo2zmPuKFcFhH5ZT3",
|
||||
valid: true,
|
||||
saddr: "03edd40747de905a9becb14987a1a26c1adbd617c45e1583c142a635bfda9493df",
|
||||
result: dcrutil.TstAddressPubKey(
|
||||
[]byte{
|
||||
0x07, 0xed, 0xd4, 0x07, 0x47, 0xde, 0x90, 0x5a, 0x9b, 0xec,
|
||||
0xb1, 0x49, 0x87, 0xa1, 0xa2, 0x6c, 0x1a, 0xdb, 0xd6, 0x17,
|
||||
0xc4, 0x5e, 0x15, 0x83, 0xc1, 0x42, 0xa6, 0x35, 0xbf, 0xda,
|
||||
0x94, 0x93, 0xdf, 0xa1, 0xc6, 0xd3, 0x67, 0x35, 0x97, 0x49,
|
||||
0x65, 0xfe, 0x7b, 0x86, 0x1e, 0x7f, 0x6f, 0xcc, 0x08, 0x7d,
|
||||
0xc7, 0xfe, 0x47, 0x38, 0x0f, 0xa8, 0xbd, 0xe0, 0xd9, 0xc3,
|
||||
0x22, 0xd5, 0x3c, 0x0e, 0x89},
|
||||
dcrutil.PKFHybrid, chaincfg.TestNet2Params.PubKeyHashAddrID),
|
||||
name: "testnet p2pk hybrid (0x07)",
|
||||
addr: "",
|
||||
valid: false,
|
||||
f: func() (dcrutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x07, 0xed, 0xd4, 0x07, 0x47, 0xde, 0x90, 0x5a, 0x9b, 0xec,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user