From 71f06fbd45f1509b429ddd2c57a17775dcc40801 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 8 Apr 2020 14:59:21 -0500 Subject: [PATCH] secp256k1: Optimize pubkey parse. This modifies the ParsePubKey function to avoid an additional unnecessary check if the point is on the curve in the compressed pubkey case because it necessarily has already determined if that is true via the point decompression from the x coordinate. Also, prevent x from escaping to the heap for the error print in compressed case while here. benchmark old ns/op new ns/op delta ------------------------------------------------------------------ BenchmarkParsePubKeyCompressed 11901 11745 -1.31% BenchmarkParsePubKeyUncompressed 335 325 -2.99% benchmark old allocs new allocs delta ------------------------------------------------------------------- BenchmarkParsePubKeyCompressed 2 1 -50.00% BenchmarkParsePubKeyUncompressed 2 1 -50.00% benchmark old bytes new bytes delta ------------------------------------------------------------------- BenchmarkParsePubKeyCompressed 128 80 -37.50% BenchmarkParsePubKeyUncompressed 128 80 -37.50% --- dcrec/secp256k1/pubkey.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dcrec/secp256k1/pubkey.go b/dcrec/secp256k1/pubkey.go index 0923eb09..e301c8a3 100644 --- a/dcrec/secp256k1/pubkey.go +++ b/dcrec/secp256k1/pubkey.go @@ -138,6 +138,13 @@ func ParsePubKey(serialized []byte) (key *PublicKey, err error) { } } + // Reject public keys that are not on the secp256k1 curve. + if !isOnCurve(&x, &y) { + str := fmt.Sprintf("invalid public key: [%v,%v] not on secp256k1 "+ + "curve", x, y) + return nil, makeError(ErrPubKeyNotOnCurve, str) + } + case PubKeyBytesLenCompressed: // Reject unsupported public key formats for the given length. format := serialized[0] @@ -162,7 +169,7 @@ func ParsePubKey(serialized []byte) (key *PublicKey, err error) { wantOddY := format == PubKeyFormatCompressedOdd if !DecompressY(&x, wantOddY, &y) { str := fmt.Sprintf("invalid public key: x coordinate %v is not on "+ - "the secp256k1 curve", &x) + "the secp256k1 curve", x) return nil, makeError(ErrPubKeyNotOnCurve, str) } y.Normalize() @@ -173,13 +180,6 @@ func ParsePubKey(serialized []byte) (key *PublicKey, err error) { return nil, makeError(ErrPubKeyInvalidLen, str) } - // Reject public keys that are not on the secp256k1 curve. - if !isOnCurve(&x, &y) { - str := fmt.Sprintf("invalid public key: [%v,%v] not on secp256k1 curve", - x, y) - return nil, makeError(ErrPubKeyNotOnCurve, str) - } - return NewPublicKey(&x, &y), nil }