## Validity of public keys is not checked

### Description

The `Verify`

function does not check the validity of the public key `passKey`

. To be valid, a public key needs to

not be the point at infinity,

have coordinates $(x,y)$ satisfying $0≤x,y<p$, and

satisfy the equation $y_{2}=x_{3}+ax+b$ modulo

`p`

.

The public key is only used after conversion to Jacobian coordinates in `_preComputeJacobianPoints`

with `JPoint(passKey.pubKeyX, passKey.pubKeyY, 1)`

, which is never the point at infinity. The `_affineFromJacobian`

function uses the convention that `(0,0)`

in affine coordinates represents the point at infinity. So for this special case, conversion as `JPoint(passKey.pubKeyX, passKey.pubKeyY, 1)`

would be incorrect. But given that the point at infinity is not a valid public key anyway, this is not an issue if instead the public key `(0,0)`

is rejected by recognizing that `(0,0)`

does not lie on the curve.

As x and y coordinates of `passKey`

always get reduced modulo `p`

in calculations, the missing check for property 2 means that `Verify`

will in effect check the signature for the public key with coordinates `(x % p, y % p)`

. This means that for some public keys `(x,y)`

, where $x<2_{256}−p$ or $y<2_{256}−p$, there exists another pair `(x', y')`

--- for example, `(x+p, y)`

--- that can be used as a public key and for which signatures made for `(x,y)`

would also verify.

Finally, if the public key passed to `Verify`

does not lie on the curve, then results returned by `Verify`

do not have a meaningful interpretation.

### Impact

Whether the possibility an attacker could generate two different keys for which the same signature is valid is a problem depends on how the caller uses public keys and signature verification.

This bug allows an attacker to generate public keys together with signatures that will be rejected by verification algorithms that validate the public key but will be accepted by `Verify`

. The impact on the security of projects making use of the Secp256r1 library for signature verification is highly dependent on how signatures are otherwise used. See section ref↗ for a discussion of this as well as the reason for our severity rating.

### Recommendations

Ensure that `(passKey.pubKeyX, passKey.pubKeyY)`

is a valid public key for the secp256r1 curve. One option is to check this in the `Verify`

function. If this is instead ensured by callers to `Verify`

, then one could alternatively document that `Verify`

assumes validity of the public key and that the caller must ensure this.

### Remediation

This issue has been acknowledged by Biconomy Labs, and fixes were implemented in the following commits: