Skip to content

Consistently label cofactor-absent ECDH test cases#218

Merged
cpu merged 1 commit intoC2SP:mainfrom
sgmenda:add-nocofactor-v2
Mar 11, 2026
Merged

Consistently label cofactor-absent ECDH test cases#218
cpu merged 1 commit intoC2SP:mainfrom
sgmenda:add-nocofactor-v2

Conversation

@sgmenda
Copy link
Contributor

@sgmenda sgmenda commented Feb 18, 2026

The cofactor of an elliptic curve is the ratio of the total number of points on the curve to the order of the base point. For the NIST P curves (P-224, P-256, P-384, P-521), the cofactor is 1 — every point on the curve is generated by the base point. For Curve25519, the cofactor is 8, meaning only 1/8 of the points on the curve are generated by the base point. The cofactor-8 structure of Curve25519 has been a recurring source of bugs, like signature malleability in Ed25519 (see ristretto.group). In practice, a missing cofactor field is unlikely to cause issues for the P curves since implementations can safely hardcode cofactor = 1, but for curves with larger cofactors the value must be parsed correctly from the parameters.

When elliptic curve parameters are encoded explicitly in ASN.1 (the ECParameters SEQUENCE in X9.62 / SEC 1), the cofactor is an optional INTEGER field at the end of the structure. However, RFC 3279 §2.3.5 says it MUST be present in ECDH public keys.

28 ECDH test cases across 14 files (10 non-PEM + 4 PEM) covering 10 cofactor-1 curves (secp224r1, secp256r1, secp256k1, secp384r1, secp521r1, brainpoolP224r1, brainpoolP256r1, brainpoolP320r1, brainpoolP384r1, brainpoolP512r1) have the cofactor INTEGER entirely absent from the ECParameters, but were tagged with NegativeCofactor (the "cofactor = 0" cases) or ModifiedCofactor (the "cofactor = None" cases).

ASN.1 parsing confirms these keys have 5 top-level fields in the ECParameters SEQUENCE (cofactor missing), while the adjacent cofactor = -1 and cofactor = 2 test cases have 6 fields (cofactor present). See this gist for a verification script.

These test cases are correctly marked result: "invalid", but the flag should reflect the actual reason. This PR:

  • Adds a NoCofactor note with bugType: "MISSING_PARAMETER" and the RFC reference.
  • Changes the flag from NegativeCofactor/ModifiedCofactor to NoCofactor.
  • Updates comments from "cofactor = 0" / "cofactor = None" to "no cofactor".

Testing:

  • go run ./tools/vectorlint passes with 0 invalid files.
  • tools/reformat_json.py produces no additional changes (formatting is canonical).
  • ASN.1 field counts verified for all 40 non-PEM test cases (20 absent + 20 present) across 10 curves using openssl asn1parse -strparse.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.

@sgmenda sgmenda self-assigned this Feb 18, 2026
Copy link

@dkostic dkostic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Copy link
Member

@cpu cpu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the detailed PR description/methodology 🙇

This looks correct to me. Would you mind addressing the conflicts?

@cpu
Copy link
Member

cpu commented Mar 4, 2026

@sgmenda Gentle bump. No immediate rush, but I think this could be merged if you were able to rebase away the conflicts.

@sgmenda
Copy link
Contributor Author

sgmenda commented Mar 4, 2026

@cpu oops, lost track, sorry about that. :/ will resolve later today.

@cpu
Copy link
Member

cpu commented Mar 5, 2026

Hmm, something's gone wonky and I can't seem to merge:

Merging is blocked due to failing merge requirements

and

This branch cannot be rebased due to conflicts

Could you try again, or open a second PR if that's easier?

@sgmenda
Copy link
Contributor Author

sgmenda commented Mar 10, 2026

@cpu I pushed an empty commit to refresh CI, could you try again? if that doesn't work, I'll open a new PR.

@cpu
Copy link
Member

cpu commented Mar 10, 2026

cpu I pushed an empty commit to refresh CI, could you try again?

Confusingly, CI is happy now, and it was before as well. It's specifically the GitHub UI for merging that's ghosted out and unavailable due to "failing merge requirements". The only other hint in the UI is the continued presence of "This branch cannot be rebased due to conflicts":

hmm

I'm not sure why this is the case, since typically it would list which files are conflicted and that information is absent. 😕

@botovq
Copy link
Contributor

botovq commented Mar 10, 2026

I don't think any merges to main had merge commits. Is "Allow merge commits" disabled in the repo settings?

@cpu
Copy link
Member

cpu commented Mar 10, 2026

Is "Allow merge commits" disabled in the repo settings?

@FiloSottile Are you able to check this? My permissions level on this repo doesn't allow viewing the branch protection rules or other related settings.

@sgmenda
Copy link
Contributor Author

sgmenda commented Mar 10, 2026

image

odd. on my end, it shows no conflicts.

@cpu cpu force-pushed the add-nocofactor-v2 branch from f28474f to d0194f7 Compare March 11, 2026 15:39
@cpu
Copy link
Member

cpu commented Mar 11, 2026

Since I think Filippo is travelling this week for RWC I figured we should try to find a solution that doesn't require changing the repo settings.

I took the one commit with the changes from this branch and rebased it onto main instead of having commits merging main in here. That seems to have done the trick 👍

@cpu cpu merged commit 7889810 into C2SP:main Mar 11, 2026
4 checks passed
@sgmenda sgmenda deleted the add-nocofactor-v2 branch March 11, 2026 16:13
@sgmenda
Copy link
Contributor Author

sgmenda commented Mar 11, 2026

@cpu tyty <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants