You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
493 lines
18 KiB
493 lines
18 KiB
// Copyright (c) 2013-2016 The btcsuite developers |
|
// Copyright (c) 2015-2020 The Decred developers |
|
// Use of this source code is governed by an ISC |
|
// license that can be found in the LICENSE file. |
|
|
|
package secp256k1 |
|
|
|
import ( |
|
"errors" |
|
"testing" |
|
|
|
"utils.orly" |
|
) |
|
|
|
// TestParsePubKey ensures that public keys are properly parsed according |
|
// to the spec including both the positive and negative cases. |
|
func TestParsePubKey(t *testing.T) { |
|
tests := []struct { |
|
name string // test description |
|
key string // hex encoded public key |
|
err error // expected error |
|
wantX string // expected x coordinate |
|
wantY string // expected y coordinate |
|
}{ |
|
{ |
|
name: "uncompressed ok", |
|
key: "04" + |
|
"11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" + |
|
"b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
err: nil, |
|
wantX: "11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c", |
|
wantY: "b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
}, { |
|
name: "uncompressed x changed (not on curve)", |
|
key: "04" + |
|
"15db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" + |
|
"b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
err: ErrPubKeyNotOnCurve, |
|
}, { |
|
name: "uncompressed y changed (not on curve)", |
|
key: "04" + |
|
"11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" + |
|
"b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a4", |
|
err: ErrPubKeyNotOnCurve, |
|
}, { |
|
name: "uncompressed claims compressed", |
|
key: "03" + |
|
"11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" + |
|
"b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
err: ErrPubKeyInvalidFormat, |
|
}, { |
|
name: "uncompressed as hybrid ok (ybit = 0)", |
|
key: "06" + |
|
"11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" + |
|
"4d1f1522047b33068bbb9b07d1e9f40564749b062b3fc0666479bc08a94be98c", |
|
err: nil, |
|
wantX: "11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c", |
|
wantY: "4d1f1522047b33068bbb9b07d1e9f40564749b062b3fc0666479bc08a94be98c", |
|
}, { |
|
name: "uncompressed as hybrid ok (ybit = 1)", |
|
key: "07" + |
|
"11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" + |
|
"b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
err: nil, |
|
wantX: "11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c", |
|
wantY: "b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
}, { |
|
name: "uncompressed as hybrid wrong oddness", |
|
key: "06" + |
|
"11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" + |
|
"b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
err: ErrPubKeyMismatchedOddness, |
|
}, { |
|
name: "compressed ok (ybit = 0)", |
|
key: "02" + |
|
"ce0b14fb842b1ba549fdd675c98075f12e9c510f8ef52bd021a9a1f4809d3b4d", |
|
err: nil, |
|
wantX: "ce0b14fb842b1ba549fdd675c98075f12e9c510f8ef52bd021a9a1f4809d3b4d", |
|
wantY: "0890ff84d7999d878a57bee170e19ef4b4803b4bdede64503a6ac352b03c8032", |
|
}, { |
|
name: "compressed ok (ybit = 1)", |
|
key: "03" + |
|
"2689c7c2dab13309fb143e0e8fe396342521887e976690b6b47f5b2a4b7d448e", |
|
err: nil, |
|
wantX: "2689c7c2dab13309fb143e0e8fe396342521887e976690b6b47f5b2a4b7d448e", |
|
wantY: "499dd7852849a38aa23ed9f306f07794063fe7904e0f347bc209fdddaf37691f", |
|
}, { |
|
name: "compressed claims uncompressed (ybit = 0)", |
|
key: "04" + |
|
"ce0b14fb842b1ba549fdd675c98075f12e9c510f8ef52bd021a9a1f4809d3b4d", |
|
err: ErrPubKeyInvalidFormat, |
|
}, { |
|
name: "compressed claims uncompressed (ybit = 1)", |
|
key: "04" + |
|
"2689c7c2dab13309fb143e0e8fe396342521887e976690b6b47f5b2a4b7d448e", |
|
err: ErrPubKeyInvalidFormat, |
|
}, { |
|
name: "compressed claims hybrid (ybit = 0)", |
|
key: "06" + |
|
"ce0b14fb842b1ba549fdd675c98075f12e9c510f8ef52bd021a9a1f4809d3b4d", |
|
err: ErrPubKeyInvalidFormat, |
|
}, { |
|
name: "compressed claims hybrid (ybit = 1)", |
|
key: "07" + |
|
"2689c7c2dab13309fb143e0e8fe396342521887e976690b6b47f5b2a4b7d448e", |
|
err: ErrPubKeyInvalidFormat, |
|
}, { |
|
name: "compressed with invalid x coord (ybit = 0)", |
|
key: "03" + |
|
"ce0b14fb842b1ba549fdd675c98075f12e9c510f8ef52bd021a9a1f4809d3b4c", |
|
err: ErrPubKeyNotOnCurve, |
|
}, { |
|
name: "compressed with invalid x coord (ybit = 1)", |
|
key: "03" + |
|
"2689c7c2dab13309fb143e0e8fe396342521887e976690b6b47f5b2a4b7d448d", |
|
err: ErrPubKeyNotOnCurve, |
|
}, { |
|
name: "empty", |
|
key: "", |
|
err: ErrPubKeyInvalidLen, |
|
}, { |
|
name: "wrong length", |
|
key: "05", |
|
err: ErrPubKeyInvalidLen, |
|
}, { |
|
name: "uncompressed x == p", |
|
key: "04" + |
|
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f" + |
|
"b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
err: ErrPubKeyXTooBig, |
|
}, { |
|
// The y coordinate produces a valid point for x == 1 (mod p), but it |
|
// should fail to parse instead of wrapping around. |
|
name: "uncompressed x > p (p + 1 -- aka 1)", |
|
key: "04" + |
|
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30" + |
|
"bde70df51939b94c9c24979fa7dd04ebd9b3572da7802290438af2a681895441", |
|
err: ErrPubKeyXTooBig, |
|
}, { |
|
name: "uncompressed y == p", |
|
key: "04" + |
|
"11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" + |
|
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", |
|
err: ErrPubKeyYTooBig, |
|
}, { |
|
// The x coordinate produces a valid point for y == 1 (mod p), but it |
|
// should fail to parse instead of wrapping around. |
|
name: "uncompressed y > p (p + 1 -- aka 1)", |
|
key: "04" + |
|
"1fe1e5ef3fceb5c135ab7741333ce5a6e80d68167653f6b2b24bcbcfaaaff507" + |
|
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", |
|
err: ErrPubKeyYTooBig, |
|
}, { |
|
name: "compressed x == p (ybit = 0)", |
|
key: "02" + |
|
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", |
|
err: ErrPubKeyXTooBig, |
|
}, { |
|
name: "compressed x == p (ybit = 1)", |
|
key: "03" + |
|
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", |
|
err: ErrPubKeyXTooBig, |
|
}, { |
|
// This would be valid for x == 2 (mod p), but it should fail to parse |
|
// instead of wrapping around. |
|
name: "compressed x > p (p + 2 -- aka 2) (ybit = 0)", |
|
key: "02" + |
|
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc31", |
|
err: ErrPubKeyXTooBig, |
|
}, { |
|
// This would be valid for x == 1 (mod p), but it should fail to parse |
|
// instead of wrapping around. |
|
name: "compressed x > p (p + 1 -- aka 1) (ybit = 1)", |
|
key: "03" + |
|
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", |
|
err: ErrPubKeyXTooBig, |
|
}, { |
|
name: "hybrid x == p (ybit = 1)", |
|
key: "07" + |
|
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f" + |
|
"b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
err: ErrPubKeyXTooBig, |
|
}, { |
|
// The y coordinate produces a valid point for x == 1 (mod p), but it |
|
// should fail to parse instead of wrapping around. |
|
name: "hybrid x > p (p + 1 -- aka 1) (ybit = 0)", |
|
key: "06" + |
|
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30" + |
|
"bde70df51939b94c9c24979fa7dd04ebd9b3572da7802290438af2a681895441", |
|
err: ErrPubKeyXTooBig, |
|
}, { |
|
name: "hybrid y == p (ybit = 0 when mod p)", |
|
key: "06" + |
|
"11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" + |
|
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", |
|
err: ErrPubKeyYTooBig, |
|
}, { |
|
// The x coordinate produces a valid point for y == 1 (mod p), but it |
|
// should fail to parse instead of wrapping around. |
|
name: "hybrid y > p (p + 1 -- aka 1) (ybit = 1 when mod p)", |
|
key: "07" + |
|
"1fe1e5ef3fceb5c135ab7741333ce5a6e80d68167653f6b2b24bcbcfaaaff507" + |
|
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", |
|
err: ErrPubKeyYTooBig, |
|
}, |
|
} |
|
for _, test := range tests { |
|
pubKeyBytes := hexToBytes(test.key) |
|
pubKey, err := ParsePubKey(pubKeyBytes) |
|
if !errors.Is(err, test.err) { |
|
t.Errorf( |
|
"%s mismatched e -- got %v, want %v", test.name, err, |
|
test.err, |
|
) |
|
continue |
|
} |
|
if err != nil { |
|
continue |
|
} |
|
// Ensure the x and y coordinates match the expected values upon |
|
// successful parse. |
|
wantX, wantY := hexToFieldVal(test.wantX), hexToFieldVal(test.wantY) |
|
if !pubKey.x.Equals(wantX) { |
|
t.Errorf( |
|
"%s: mismatched x coordinate -- got %v, want %v", |
|
test.name, pubKey.x, wantX, |
|
) |
|
continue |
|
} |
|
if !pubKey.y.Equals(wantY) { |
|
t.Errorf( |
|
"%s: mismatched y coordinate -- got %v, want %v", |
|
test.name, pubKey.y, wantY, |
|
) |
|
continue |
|
} |
|
} |
|
} |
|
|
|
// TestPubKeySerialize ensures that serializing public keys works as expected |
|
// for both the compressed and uncompressed cases. |
|
func TestPubKeySerialize(t *testing.T) { |
|
tests := []struct { |
|
name string // test description |
|
pubX string // hex encoded x coordinate for pubkey to serialize |
|
pubY string // hex encoded y coordinate for pubkey to serialize |
|
compress bool // whether to serialize compressed or uncompressed |
|
expected string // hex encoded expected pubkey serialization |
|
}{ |
|
{ |
|
name: "uncompressed (ybit = 0)", |
|
pubX: "11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c", |
|
pubY: "4d1f1522047b33068bbb9b07d1e9f40564749b062b3fc0666479bc08a94be98c", |
|
compress: false, |
|
expected: "04" + |
|
"11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" + |
|
"4d1f1522047b33068bbb9b07d1e9f40564749b062b3fc0666479bc08a94be98c", |
|
}, { |
|
name: "uncompressed (ybit = 1)", |
|
pubX: "11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c", |
|
pubY: "b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
compress: false, |
|
expected: "04" + |
|
"11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" + |
|
"b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
}, { |
|
// It's invalid to parse pubkeys that are not on the curve, however it |
|
// is possible to manually create them and they should serialize |
|
// correctly. |
|
name: "uncompressed not on the curve due to x coord", |
|
pubX: "15db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c", |
|
pubY: "b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
compress: false, |
|
expected: "04" + |
|
"15db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" + |
|
"b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
}, { |
|
// It's invalid to parse pubkeys that are not on the curve, however it |
|
// is possible to manually create them and they should serialize |
|
// correctly. |
|
name: "uncompressed not on the curve due to y coord", |
|
pubX: "15db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c", |
|
pubY: "b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a4", |
|
compress: false, |
|
expected: "04" + |
|
"15db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" + |
|
"b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a4", |
|
}, { |
|
name: "compressed (ybit = 0)", |
|
pubX: "ce0b14fb842b1ba549fdd675c98075f12e9c510f8ef52bd021a9a1f4809d3b4d", |
|
pubY: "0890ff84d7999d878a57bee170e19ef4b4803b4bdede64503a6ac352b03c8032", |
|
compress: true, |
|
expected: "02" + |
|
"ce0b14fb842b1ba549fdd675c98075f12e9c510f8ef52bd021a9a1f4809d3b4d", |
|
}, { |
|
name: "compressed (ybit = 1)", |
|
pubX: "2689c7c2dab13309fb143e0e8fe396342521887e976690b6b47f5b2a4b7d448e", |
|
pubY: "499dd7852849a38aa23ed9f306f07794063fe7904e0f347bc209fdddaf37691f", |
|
compress: true, |
|
expected: "03" + |
|
"2689c7c2dab13309fb143e0e8fe396342521887e976690b6b47f5b2a4b7d448e", |
|
}, { |
|
// It's invalid to parse pubkeys that are not on the curve, however it |
|
// is possible to manually create them and they should serialize |
|
// correctly. |
|
name: "compressed not on curve (ybit = 0)", |
|
pubX: "ce0b14fb842b1ba549fdd675c98075f12e9c510f8ef52bd021a9a1f4809d3b4c", |
|
pubY: "0890ff84d7999d878a57bee170e19ef4b4803b4bdede64503a6ac352b03c8032", |
|
compress: true, |
|
expected: "02" + |
|
"ce0b14fb842b1ba549fdd675c98075f12e9c510f8ef52bd021a9a1f4809d3b4c", |
|
}, { |
|
// It's invalid to parse pubkeys that are not on the curve, however it |
|
// is possible to manually create them and they should serialize |
|
// correctly. |
|
name: "compressed not on curve (ybit = 1)", |
|
pubX: "2689c7c2dab13309fb143e0e8fe396342521887e976690b6b47f5b2a4b7d448d", |
|
pubY: "499dd7852849a38aa23ed9f306f07794063fe7904e0f347bc209fdddaf37691f", |
|
compress: true, |
|
expected: "03" + |
|
"2689c7c2dab13309fb143e0e8fe396342521887e976690b6b47f5b2a4b7d448d", |
|
}, |
|
} |
|
for _, test := range tests { |
|
// Parse the test data. |
|
x, y := hexToFieldVal(test.pubX), hexToFieldVal(test.pubY) |
|
pubKey := NewPublicKey(x, y) |
|
// Serialize with the correct method and ensure the result matches the |
|
// expected value. |
|
var serialized []byte |
|
if test.compress { |
|
serialized = pubKey.SerializeCompressed() |
|
} else { |
|
serialized = pubKey.SerializeUncompressed() |
|
} |
|
expected := hexToBytes(test.expected) |
|
if !utils.FastEqual(serialized, expected) { |
|
t.Errorf( |
|
"%s: mismatched serialized public key -- got %x, want %x", |
|
test.name, serialized, expected, |
|
) |
|
continue |
|
} |
|
} |
|
} |
|
|
|
// TestPublicKeyIsEqual ensures that equality testing between two public keys |
|
// works as expected. |
|
func TestPublicKeyIsEqual(t *testing.T) { |
|
pubKey1 := &PublicKey{ |
|
x: *hexToFieldVal("2689c7c2dab13309fb143e0e8fe396342521887e976690b6b47f5b2a4b7d448e"), |
|
y: *hexToFieldVal("499dd7852849a38aa23ed9f306f07794063fe7904e0f347bc209fdddaf37691f"), |
|
} |
|
pubKey1Copy := &PublicKey{ |
|
x: *hexToFieldVal("2689c7c2dab13309fb143e0e8fe396342521887e976690b6b47f5b2a4b7d448e"), |
|
y: *hexToFieldVal("499dd7852849a38aa23ed9f306f07794063fe7904e0f347bc209fdddaf37691f"), |
|
} |
|
pubKey2 := &PublicKey{ |
|
x: *hexToFieldVal("ce0b14fb842b1ba549fdd675c98075f12e9c510f8ef52bd021a9a1f4809d3b4d"), |
|
y: *hexToFieldVal("0890ff84d7999d878a57bee170e19ef4b4803b4bdede64503a6ac352b03c8032"), |
|
} |
|
|
|
if !pubKey1.IsEqual(pubKey1) { |
|
t.Fatalf( |
|
"bad self public key equality check: (%v, %v)", pubKey1.x, |
|
pubKey1.y, |
|
) |
|
} |
|
if !pubKey1.IsEqual(pubKey1Copy) { |
|
t.Fatalf( |
|
"bad public key equality check: (%v, %v) == (%v, %v)", |
|
pubKey1.x, pubKey1.y, pubKey1Copy.x, pubKey1Copy.y, |
|
) |
|
} |
|
|
|
if pubKey1.IsEqual(pubKey2) { |
|
t.Fatalf( |
|
"bad public key equality check: (%v, %v) != (%v, %v)", |
|
pubKey1.x, pubKey1.y, pubKey2.x, pubKey2.y, |
|
) |
|
} |
|
} |
|
|
|
// TestPublicKeyAsJacobian ensures converting a public key to a jacobian point |
|
// with a Z coordinate of 1 works as expected. |
|
func TestPublicKeyAsJacobian(t *testing.T) { |
|
tests := []struct { |
|
name string // test description |
|
pubKey string // hex encoded serialized compressed pubkey |
|
wantX string // hex encoded expected X coordinate |
|
wantY string // hex encoded expected Y coordinate |
|
}{ |
|
{ |
|
name: "public key for secret key 0x01", |
|
pubKey: "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", |
|
wantX: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", |
|
wantY: "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", |
|
}, { |
|
name: "public for secret key 0x03", |
|
pubKey: "02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9", |
|
wantX: "f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9", |
|
wantY: "388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672", |
|
}, { |
|
name: "public for secret key 0x06", |
|
pubKey: "03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556", |
|
wantX: "fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556", |
|
wantY: "ae12777aacfbb620f3be96017f45c560de80f0f6518fe4a03c870c36b075f297", |
|
}, |
|
} |
|
for _, test := range tests { |
|
// Parse the test data. |
|
pubKeyBytes := hexToBytes(test.pubKey) |
|
wantX := hexToFieldVal(test.wantX) |
|
wantY := hexToFieldVal(test.wantY) |
|
pubKey, err := ParsePubKey(pubKeyBytes) |
|
if err != nil { |
|
t.Errorf("%s: failed to parse public key: %v", test.name, err) |
|
continue |
|
} |
|
// Convert the public key to a jacobian point and ensure the coordinates |
|
// match the expected values. |
|
var point JacobianPoint |
|
pubKey.AsJacobian(&point) |
|
if !point.Z.IsOne() { |
|
t.Errorf( |
|
"%s: invalid Z coordinate -- got %v, want 1", test.name, |
|
point.Z, |
|
) |
|
continue |
|
} |
|
if !point.X.Equals(wantX) { |
|
t.Errorf( |
|
"%s: invalid X coordinate - got %v, want %v", test.name, |
|
point.X, wantX, |
|
) |
|
continue |
|
} |
|
if !point.Y.Equals(wantY) { |
|
t.Errorf( |
|
"%s: invalid Y coordinate - got %v, want %v", test.name, |
|
point.Y, wantY, |
|
) |
|
continue |
|
} |
|
} |
|
} |
|
|
|
// TestPublicKeyIsOnCurve ensures testing if a public key is on the curve works |
|
// as expected. |
|
func TestPublicKeyIsOnCurve(t *testing.T) { |
|
tests := []struct { |
|
name string // test description |
|
pubX string // hex encoded x coordinate for pubkey to serialize |
|
pubY string // hex encoded y coordinate for pubkey to serialize |
|
want bool // expected result |
|
}{ |
|
{ |
|
name: "valid with even y", |
|
pubX: "11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c", |
|
pubY: "4d1f1522047b33068bbb9b07d1e9f40564749b062b3fc0666479bc08a94be98c", |
|
want: true, |
|
}, { |
|
name: "valid with odd y", |
|
pubX: "11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c", |
|
pubY: "b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
want: true, |
|
}, { |
|
name: "invalid due to x coord", |
|
pubX: "15db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c", |
|
pubY: "b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", |
|
want: false, |
|
}, { |
|
name: "invalid due to y coord", |
|
pubX: "15db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c", |
|
pubY: "b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a4", |
|
want: false, |
|
}, |
|
} |
|
for _, test := range tests { |
|
// Parse the test data. |
|
x, y := hexToFieldVal(test.pubX), hexToFieldVal(test.pubY) |
|
pubKey := NewPublicKey(x, y) |
|
|
|
result := pubKey.IsOnCurve() |
|
if result != test.want { |
|
t.Errorf( |
|
"%s: mismatched is on curve result -- got %v, want %v", |
|
test.name, result, test.want, |
|
) |
|
continue |
|
} |
|
} |
|
}
|
|
|