dotnet / dotnet/runtime

[API Proposal]: ECAlgorithm SEC1 public key import and export

Open
#133,362 1 comment 0 reactions 0 assignees View on GitHub
api-suggestion area-System.Security
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

### Background and motivation

With `CompositeMLDsa`, `CompositeMLKem`, `Hpke`, etc we are building more on top of EC algorithms. These algorithms are working with EC keys in SEC 1 / ANSI X9.63 keys.

Working with these keys from `ECParameters` results in continuous redundant implementations of "Okay, let's smash X and Y together" for export and "Let's slice in the middle with a bunch of validation" for import.

We should consider just making this a public API. The `Core` virtual method will do this through ECParameters but derived types are free to override it to provide more efficient implementations.

### API Proposal

```csharp
namespace System.Security.Cryptography;

public abstract partial class ECAlgorithm
{
// Exports are always uncompressed. Compressed will be a new API, if we ever add them.
public byte[] ExportUncompressedSec1PublicKey();
public int ExportUncompressedSec1PublicKey(Span destination);
public bool TryExportUncompressedSec1PublicKey(Span destination, out int bytesWritten);
protected virtual bool TryExportUncompressedSec1PublicKeyCore(Span destination, out int bytesWritten);

// Import does not require uncompressed. Derived types are free to support compressed, if they want.
// Inbox implementations will only support uncompressed.
public void ImportSec1PublicKey(ECCurve curve, byte[] publicKey);
public void ImportSec1PublicKey(ECCurve curve, ReadOnlySpan publicKey);
protected virtual void ImportSec1PublicKeyCore(ECCurve curve, ReadOnlySpan publicKey);
}

```

### API Usage

```csharp
ECDiffieHellman ecdh = ECDiffieHellman.Create();
byte[] publicKey = ecdh.ExportUncompressedSec1PublicKey(); // 0x04 || X || Y
```

### Alternative Designs

* Not sure about the `Sec1` as the key format name. It could also be ANSI X9.63.
* The `Try` shape is there for existing API shape matching. We could get rid of it and assume callers are supported to know their buffer size exactly. We could also provide a "GetSec1KeySize" method / property.

### Risks

_No response_

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the proposed ECAlgorithm entry points and the existing ECParameters-based handling described in the issue, then compare the ECDiffieHellman usage example with established API shapes. Done means resolving the naming, compressed-key, buffer, and virtual-core design questions and agreeing on the public API surface.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
cryptography, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.