{"record":{"id":"df8a6f6378c77d3c","repo":"denoland/deno","slug":"invalid-key-pair","errorCode":null,"errorMessage":"Invalid key pair","messagePattern":"Invalid key pair","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/diffiehellman.ts","lineNumber":1473,"sourceCode":"    } else {\n      const parts = getViewParts(otherPublicKey);\n      otherBuf = Buffer.from(parts.ab, parts.off, parts.len);\n    }\n\n    const secretBuf = Buffer.alloc(this.#curve.sharedSecretSize);\n\n    try {\n      op_node_ecdh_compute_secret(\n        this.#curve.name,\n        this.#privbuf,\n        this.#pubbuf,\n        otherBuf,\n        secretBuf,\n      );\n    } catch (e) {\n      const err = e as any;\n      if (err && err.message === \"Invalid key pair\") {\n        throw new Error(\"Invalid key pair\");\n      }\n      throw new ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY();\n    }\n\n    return ecdhEncode(secretBuf, outputEncoding ?? \"buffer\");\n  }\n\n  generateKeys(\n    encoding?: any,\n    format: any = \"uncompressed\",\n  ): Buffer | string {\n    validateEcdhFormat(format);\n    const pubbuf = Buffer.alloc(\n      format == \"compressed\"\n        ? this.#curve.publicKeySizeCompressed\n        : this.#curve.publicKeySize,\n    );\n    const privbuf = Buffer.alloc(this.#curve.privateKeySize);","sourceCodeStart":1455,"sourceCodeEnd":1491,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/diffiehellman.ts#L1455-L1491","documentation":"computeSecret() rethrows 'Invalid key pair' as a plain Error when the native op_node_ecdh_compute_secret op fails with exactly that message. The peer public key passed structural validation, but the actual scalar-multiply/DH derivation failed for the (private, peerPublic) combination — OpenSSL's way of saying the pair cannot produce a shared secret.","triggerScenarios":"A peer public key that is well-formed for the curve but mathematically unusable with your private key (e.g. yields the point at infinity), or key bytes that happen to have a valid length/prefix but do not decode to a valid point during derivation.","commonSituations":"Interop bugs where a peer transmits truncated or corrupted key material of the right size; test suites feeding random buffers as 'public keys'; hand-rolled key serialization that mangles one byte.","solutions":["Re-verify the peer public key on the wire: recompute length and prefix, and re-send/re-fetch the key from the peer","Confirm both sides really use the same curve — a same-length key from a different curve can reach the op and fail here","Wrap computeSecret in try/catch and treat this message as 'bad peer key': abort the handshake and request re-keying rather than crashing"],"exampleFix":"// before\nconst secret = ecdh.computeSecret(peerPub);\n\n// after\ntry {\n  const secret = ecdh.computeSecret(peerPub);\n} catch (e) {\n  if (e.message === 'Invalid key pair') throw new Error('peer sent unusable public key');\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const secret = ecdh.computeSecret(peerPub);\n} catch (e) {\n  if (e.message === 'Invalid key pair') {\n    throw new Error('peer public key unusable; request re-key');\n  }\n  throw e;\n}","preventionTips":["Treat any computeSecret failure as 'bad peer key' and re-run the key exchange, do not crash","Verify peer key length/prefix before the op (see the ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY guards)","Add integrity (checksum/signature) to key transport so corruption is caught earlier"],"tags":["crypto","ecdh","key-exchange","node-compat"],"backgroundTag":"ecdh-invalid-key-pair","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}