[API Proposal]: ECAlgorithm SEC1 public key import and export
- 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
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