diff --git a/bumble/crypto/builtin.py b/bumble/crypto/builtin.py index 03d391e85..12cdd7752 100644 --- a/bumble/crypto/builtin.py +++ b/bumble/crypto/builtin.py @@ -572,6 +572,9 @@ def generate_public_key(self, private_key: int) -> _Point: def ecdh_shared_secret(self, private_key: int, other_public_key: _Point) -> bytes: """Computes the shared secret using ECDH.""" + x, y = other_public_key.x, other_public_key.y + if (y * y - (x * x * x + self.a * x + self.b)) % self.p != 0: + raise core.InvalidPacketError("Public key is not a point on the curve") other_public_key_jacobian = _JacobianPoint.from_affine(other_public_key) shared_point_jacobian = other_public_key_jacobian * private_key shared_point_affine = shared_point_jacobian.to_affine() diff --git a/tests/crypto/crypto_test.py b/tests/crypto/crypto_test.py index 1287ddb64..f6769b917 100644 --- a/tests/crypto/crypto_test.py +++ b/tests/crypto/crypto_test.py @@ -83,6 +83,14 @@ def test_ecc(crypto_backend): assert shared_key == bytes.fromhex(dhkey) +# ----------------------------------------------------------------------------- +@pytest.mark.parametrize("x, y", [(0, 0), (1, 1)]) +def test_ecc_dh_point_not_on_curve(crypto_backend, x, y): + key = EccKey.generate() + with pytest.raises(ValueError): + key.dh(x.to_bytes(32, 'big'), y.to_bytes(32, 'big')) + + # ----------------------------------------------------------------------------- def test_c1(crypto_backend): k = bytes(16)