Yes. In order for the public key to be valid (i.e. not just 32 random bytes), the point must be on the curve. You can test if the point is on the curve by plugging the x and y values into the equation of the curve, and solving the equation 'over the field', to see if the equation checks.
For example, the equation for the secp256k1 curve is:
y^2 = x^3 + 7
and the field characteristic (p) is:
p=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
So, to check if a point is on the curve, you would plug the x and y values of the point into the following equation, and test if it checks:
(y^2 - x^3 - 7) % p == 0
The following point is on the secp256k1 curve:
(0x5633454c810b6e3c881e35f904a6215f1825e46429a54061d1b7448be1b4285e, 0xd1016a4e4b8c6d3a2220e76c8cd66d0ad8e42c1ea84109fef12fa601b5dd09b8)
But, the following point is not:
(0x2d09f894eff47eba35ae4eda6ecfe71fb8263b84c092249e820ba5e6e73c0da3, 0x19ece9e391ce286cbb1907c38359dd4c086e5540fc82593731a2f893ef1bedef)
Here is a short Python script that can be used to test whether a point is on the curve.
def isoncurve(x, y):
# For secp256k1
p=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
return (y * y - x * x * x - 7) % p == 0
#returns True
x=0x5633454c810b6e3c881e35f904a6215f1825e46429a54061d1b7448be1b4285e
y=0xd1016a4e4b8c6d3a2220e76c8cd66d0ad8e42c1ea84109fef12fa601b5dd09b8
print (hex(x) + ',' + hex(y) + ' is on secp256k1 curve: ' + str(isoncurve(x, y)))
# Returns False
x=0x2d09f894eff47eba35ae4eda6ecfe71fb8263b84c092249e820ba5e6e73c0da3
y=0x19ece9e391ce286cbb1907c38359dd4c086e5540fc82593731a2f893ef1bedef
print (hex(x) + ',' + hex(y) + ' is on secp256k1 curve: ' + str(isoncurve(x, y)))