denoland/deno · error · Error
Invalid key pair
Error message
Invalid key pair
What it means
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.
Source
Thrown at ext/node/polyfills/internal/crypto/diffiehellman.ts:1473
} else {
const parts = getViewParts(otherPublicKey);
otherBuf = Buffer.from(parts.ab, parts.off, parts.len);
}
const secretBuf = Buffer.alloc(this.#curve.sharedSecretSize);
try {
op_node_ecdh_compute_secret(
this.#curve.name,
this.#privbuf,
this.#pubbuf,
otherBuf,
secretBuf,
);
} catch (e) {
const err = e as any;
if (err && err.message === "Invalid key pair") {
throw new Error("Invalid key pair");
}
throw new ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY();
}
return ecdhEncode(secretBuf, outputEncoding ?? "buffer");
}
generateKeys(
encoding?: any,
format: any = "uncompressed",
): Buffer | string {
validateEcdhFormat(format);
const pubbuf = Buffer.alloc(
format == "compressed"
? this.#curve.publicKeySizeCompressed
: this.#curve.publicKeySize,
);
const privbuf = Buffer.alloc(this.#curve.privateKeySize);View on GitHub (pinned to 9ad36f7a2c)
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
Example fix
// before
const secret = ecdh.computeSecret(peerPub);
// after
try {
const secret = ecdh.computeSecret(peerPub);
} catch (e) {
if (e.message === 'Invalid key pair') throw new Error('peer sent unusable public key');
throw e;
} Defensive patterns
Strategy: try-catch
Try / catch
try {
const secret = ecdh.computeSecret(peerPub);
} catch (e) {
if (e.message === 'Invalid key pair') {
throw new Error('peer public key unusable; request re-key');
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ERR_CRYPTO_ECDH_INVALID_FORMAT
- Invalid EC curve name
- ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY
- Failed to get ECDH private key
- Failed to get ECDH public key
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/df8a6f6378c77d3c.
Report an issue: GitHub.