Skip to content

Expose P-256 ECDSA crypto builtins#6222

Open
MauScheff wants to merge 6 commits intounisonweb:trunkfrom
MauScheff:maurice/p256-ecdsa-builtins
Open

Expose P-256 ECDSA crypto builtins#6222
MauScheff wants to merge 6 commits intounisonweb:trunkfrom
MauScheff:maurice/p256-ecdsa-builtins

Conversation

@MauScheff
Copy link
Copy Markdown
Contributor

Overview

  • What does this change accomplish and why?

    • This exposes three P-256 ECDSA builtins to Unison code:
      • crypto.P256.publicKey.impl
      • crypto.P256.signSha256.impl
      • crypto.P256.verifySha256.impl
    • Before this change, Unison exposed Ed25519 and RSA crypto builtins, but not P-256 ECDSA.
    • After this change, Unison code can derive a P-256 public key from a private scalar, sign message bytes with
      SHA-256, and verify signatures against message bytes.
  • Include "before and after" examples if appropriate. (You can copy/paste screenshots directly into this
    editor.)

  • List any Github issues that this PR closes, in [closing-issues-using-keywords](https://help.github.com/
    en/enterprise/2.16/user/github/managing-your-work-on-github/closing-issues-using-keywords) format.

Implementation approach and notes

This adds a small P-256 helper module in unison-runtime backed by the existing Haskell crypto dependencies.

The change:

  • adds P-256 builtin types in parser-typechecker
  • adds new foreign-function constructors and builtin-name mappings
  • registers the builtins in unison-runtime
  • binds them to Haskell implementations in Foreign/Function.hs
  • adds runtime tests with fixed vectors for public-key derivation, signing, and verification

The builtin surface uses raw byte-oriented formats:

  • private key: 32-byte scalar
  • public key: 65-byte uncompressed SEC1 form
  • signature: 64-byte raw r || s

Interesting/controversial decisions

The main API choice here is the shape of the builtin surface.

I kept it narrow and curve-specific:

  • P256 rather than a broader generic ECDSA surface
  • raw byte formats rather than higher-level key or signature types

That keeps the initial surface small, but there may be follow-up discussion about whether this should stay
curve-specific or grow into a more general ECC API later.

Test coverage

  • Have you included tests (which could be a transcript) for this change, or is it somehow covered by
    existing tests?

    • Added runtime tests for:
      • public-key derivation
      • deterministic signing
      • verification
      • tampered-message rejection
  • Would you recommend improving the test coverage (either as part of this PR or as a separate issue) or do
    you think it’s adequate?

    • Additional malformed-input cases would improve coverage, but the current runtime tests cover the main
      behavior.
  • If you only tested by hand, because that's all that's practical to do for this change, mention that.
    Include screenshots.

Loose ends

  • This PR only adds the builtin surface and runtime implementation.
  • Follow-up documentation or higher-level wrappers could be added separately if this surface is accepted.

Final checklist

  • Choose your PR title well: Your pull request title is what's used to create release notes, so please
    make it descriptive of the change itself, which may be different from the initial motivation to make the
    change.
  • Update your PR description if the specifics of the PR have changed over time.
  • Include transcripts or screenshots that demonstrate the changed behavior.
  • If you changed .cabal files, make sure the package.yaml files are up-to-date instead.

@MauScheff MauScheff force-pushed the maurice/p256-ecdsa-builtins branch from a01ec38 to 41e6332 Compare April 15, 2026 08:15
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.

1 participant