{"record":{"id":"a8771b9b815fbec6","repo":"TheAlgorithms/Python","slug":"invalid-public-key","errorCode":null,"errorMessage":"Invalid public key","messagePattern":"Invalid public key","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"ciphers/diffie_hellman.py","lineNumber":239,"sourceCode":"\n    def get_private_key(self) -> str:\n        return hex(self.__private_key)[2:]\n\n    def generate_public_key(self) -> str:\n        public_key = pow(self.generator, self.__private_key, self.prime)\n        return hex(public_key)[2:]\n\n    def is_valid_public_key(self, key: int) -> bool:\n        # check if the other public key is valid based on NIST SP800-56\n        return (\n            2 <= key <= self.prime - 2\n            and pow(key, (self.prime - 1) // 2, self.prime) == 1\n        )\n\n    def generate_shared_key(self, other_key_str: str) -> str:\n        other_key = int(other_key_str, base=16)\n        if not self.is_valid_public_key(other_key):\n            raise ValueError(\"Invalid public key\")\n        shared_key = pow(other_key, self.__private_key, self.prime)\n        return sha256(str(shared_key).encode()).hexdigest()\n\n    @staticmethod\n    def is_valid_public_key_static(remote_public_key_str: int, prime: int) -> bool:\n        # check if the other public key is valid based on NIST SP800-56\n        return (\n            2 <= remote_public_key_str <= prime - 2\n            and pow(remote_public_key_str, (prime - 1) // 2, prime) == 1\n        )\n\n    @staticmethod\n    def generate_shared_key_static(\n        local_private_key_str: str, remote_public_key_str: str, group: int = 14\n    ) -> str:\n        local_private_key = int(local_private_key_str, base=16)\n        remote_public_key = int(remote_public_key_str, base=16)\n        prime = primes[group][\"prime\"]","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/ciphers/diffie_hellman.py#L221-L257","documentation":"Raised by DiffieHellman.generate_shared_key when the peer's public key fails the NIST SP800-56 validity check in is_valid_public_key: it must lie in [2, p-2] and be a quadratic residue (key^((p-1)/2) mod p == 1). This blocks small-subgroup and invalid-key attacks.","triggerScenarios":"Passing a hex string that decodes to 0, 1, or p-1; passing a value not generated by pow(g, private, p) in the same group; truncated or corrupted hex from the peer; wrong group on one side.","commonSituations":"Hand-rolled transports that mangle leading zeros in hex keys; peers using different group numbers; test code with arbitrary hex strings instead of real public keys; MITM/tampered payloads.","solutions":["Verify both parties constructed DiffieHellman with the same group","Regenerate the peer key from a real generate_public_key() output (full hex, no 0x prefix)","Call is_valid_public_key(int(peer_hex, 16)) yourself and drop the connection/abort on failure"],"exampleFix":"# before\nshared = dh.generate_shared_key(peer_hex)  # raises if peer_hex is invalid\n\n# after\npeer_int = int(peer_hex, 16)\nif not dh.is_valid_public_key(peer_int):\n    raise SystemExit(\"peer sent an invalid public key\")\nshared = dh.generate_shared_key(peer_hex)","handlingStrategy":"validation","validationCode":"peer_int = int(peer_hex, 16)\nif not dh.is_valid_public_key(peer_int):\n    raise ValueError(\"rejecting invalid peer public key\")","typeGuard":null,"tryCatchPattern":"try:\n    shared = dh.generate_shared_key(peer_hex)\nexcept ValueError:\n    abort_handshake(\"peer public key failed NIST SP800-56 validation\")","preventionTips":["Pre-validate with is_valid_public_key before computing the shared key","Ensure both peers use the same group number","Treat invalid keys as a possible attack, not a retryable error — abort the handshake"],"tags":["diffie-hellman","key-exchange","security","validation"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}