{"record":{"id":"5654be91d5e4b660","repo":"denoland/deno","slug":"invalid-curve","errorCode":null,"errorMessage":"invalid curve","messagePattern":"invalid curve","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/diffiehellman.ts","lineNumber":1381,"sourceCode":"): Buffer | string {\n  if (encoding === undefined || encoding === \"buffer\") {\n    return buffer;\n  }\n  // deno-lint-ignore deno-internal/prefer-primordials -- Buffer.prototype.toString(encoding) has no primordial\n  return buffer.toString(encoding);\n}\n\nclass ECDHImpl {\n  #curve: any; // the selected curve\n  #privbuf: Buffer | null = null; // the private key\n  #pubbuf: Buffer | null = null; // the public key\n\n  constructor(curve: string) {\n    validateString(curve, \"curve\");\n\n    const c = ArrayPrototypeFind(ellipticCurves, (x) => x.name == curve);\n    if (c == undefined) {\n      throw new Error(\"invalid curve\");\n    }\n\n    this.#curve = c;\n  }\n\n  static convertKey(\n    key: any,\n    curve: string,\n    inputEncoding?: any,\n    outputEncoding?: any,\n    format?: any,\n  ): Buffer | string {\n    validateString(curve, \"curve\");\n    const buf = getArrayBufferOrView(key, \"key\", inputEncoding);\n\n    let compress: boolean;\n    if (format) {\n      if (format === \"compressed\") {","sourceCodeStart":1363,"sourceCodeEnd":1399,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/diffiehellman.ts#L1363-L1399","documentation":"The ECDH constructor (diffiehellman.ts:1381) looks the curve up by exact name in the built-in elliptic curve list — the same names crypto.getCurves() returns (OpenSSL-style). A miss throws the plain Error 'invalid curve'. WebCrypto-style names like 'P-256' do not match; the OpenSSL name for that curve is 'prime256v1'.","triggerScenarios":"new ECDH('P-256') or createECDH('P-384') — WebCrypto/JWS names; typos like 'secp233k1'; 'curve25519'/'x25519' which are not ECDH curves here (X25519 goes through crypto.diffieHellman with KeyObjects); names from other stacks like 'NIST P-256'.","commonSituations":"Porting WebCrypto/JWT (ES256) code that uses 'P-256'; curve names pulled from RFC/JOSE registries; stale docs or renamed curves in newer OpenSSL versions.","solutions":["Use OpenSSL-style names: 'prime256v1' (P-256), 'secp384r1' (P-384), 'secp521r1' (P-521), 'secp256k1'","Check membership with crypto.getCurves().includes(curve) before constructing","Translate WebCrypto names once at the edge: P-256 -> prime256v1, P-384 -> secp384r1, P-521 -> secp521r1","For X25519/X448, use crypto.diffieHellman({ privateKey, publicKey }) with KeyObjects instead of ECDH"],"exampleFix":"// before\nconst ecdh = createECDH('P-256'); // invalid curve\n\n// after\nconst ecdh = createECDH('prime256v1'); // same curve, OpenSSL name","handlingStrategy":"validation","validationCode":"import { getCurves } from 'node:crypto';\nconst WEBCRYPTO_TO_OPENSSL = { 'P-256': 'prime256v1', 'P-384': 'secp384r1', 'P-521': 'secp521r1' };\nfunction normalizeCurveName(c) {\n  const n = WEBCRYPTO_TO_OPENSSL[c] ?? c;\n  if (!getCurves().includes(n)) throw new RangeError(`unsupported curve: ${c}`);\n  return n;\n}","typeGuard":"import { getCurves } from 'node:crypto';\nfunction isSupportedCurve(c) { return getCurves().includes(c); }","tryCatchPattern":"try { ecdh = createECDH(curve); } catch (e) { if (e.message === 'invalid curve') { throw new Error(`curve '${curve}' not supported; see crypto.getCurves()`); } else throw e; }","preventionTips":["Translate WebCrypto/JOSE curve names to OpenSSL names at the system boundary","Offer users a curated list from crypto.getCurves() instead of free-text curve input","Use crypto.diffieHellman with X25519/X448 KeyObjects instead of ECDH for those curves"],"tags":["crypto","ecdh","elliptic-curves","portability"],"backgroundTag":"unsupported-elliptic-curve","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}