Skip to content

Use CryptoKit for recovering public key from private EC keys on macOS - #134868

Merged
vcsjones merged 1 commit into
dotnet:mainfrom
vcsjones:unify-apple-ecc-pub-recovery
Sep 29, 2026
Merged

vcsjones merged 1 commit into
dotnet:mainfrom
vcsjones:unify-apple-ecc-pub-recovery

Conversation

@vcsjones

@vcsjones vcsjones commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

In #134682 we added support for iOS and tvOS to import private-key only values (ECParameters that contain only D).

This worked on macOS previously by round-tripping through PKCS#8. This is significantly more expensive, both in CPU and memory. Let's use the CryptoKit approach so that we have a single implementation and use the better one on macOS.

This is around a 100x improvement in time.

Method Toolchain Mean Error StdDev Ratio Allocated Alloc Ratio
ImportP256 After 127.2 μs 0.32 μs 0.30 μs 0.002 256 B 0.06
ImportP256 Before 75,153.2 μs 1,433.16 μs 2,862.18 μs 1.000 4320 B 1.00
ImportP384 After 341.7 μs 3.57 μs 3.34 μs 0.003 288 B 0.06
ImportP384 Before 114,843.9 μs 2,236.42 μs 3,547.20 μs 1.000 4469 B 1.00
ImportP521 After 987.9 μs 9.93 μs 9.29 μs 0.006 337 B 0.07
ImportP521 Before 158,300.2 μs 3,068.62 μs 3,151.25 μs 1.000 4664 B 1.00

Benchmark code:

[MemoryDiagnoser]
public class EccDImportBenchmark
{
    private static readonly ECParameters s_p256 = CreateParameters(ECCurve.NamedCurves.nistP256);
    private static readonly ECParameters s_p384 = CreateParameters(ECCurve.NamedCurves.nistP384);
    private static readonly ECParameters s_p521 = CreateParameters(ECCurve.NamedCurves.nistP521);

    private ECDiffieHellman _p256 = null!;
    private ECDiffieHellman _p384 = null!;
    private ECDiffieHellman _p521 = null!;

    [GlobalSetup]
    public void Setup()
    {
        _p256 = ECDiffieHellman.Create();
        _p384 = ECDiffieHellman.Create();
        _p521 = ECDiffieHellman.Create();
    }

    [GlobalCleanup]
    public void Cleanup()
    {
        _p256.Dispose();
        _p384.Dispose();
        _p521.Dispose();
    }

    [Benchmark]
    public void ImportP256()
    {
        _p256.ImportParameters(s_p256);
    }

    [Benchmark]
    public void ImportP384()
    {
        _p384.ImportParameters(s_p384);
    }

    [Benchmark]
    public void ImportP521()
    {
        _p521.ImportParameters(s_p521);
    }

    private static ECParameters CreateParameters(ECCurve curve)
    {
        using (ECDiffieHellman ecdh = ECDiffieHellman.Create(curve))
        {
            ECParameters privateParameters = ecdh.ExportParameters(includePrivateParameters: true);

            return new ECParameters
            {
                Curve = curve,
                D = privateParameters.D,
            };
        }
    }
}

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b3784a91-b7e4-4d75-8e18-4146850fd5bd
@vcsjones vcsjones self-assigned this Sep 29, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @bartonjs, @vcsjones, @dotnet/area-system-security
See info in area-owners.md if you want to be subscribed.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

No unresolved issues were identified that would block approval.

Review effort: Lite
Findings: None

What changed in this PR

This PR centralizes Apple EC public-key derivation from private scalar-only parameters using CryptoKit, enabling the faster path on macOS as well as mobile Apple platforms.

Changes:

  • Moves the CryptoKit-based derivation helper to shared Apple code.
  • Removes the macOS PKCS#8 round-trip implementation.
  • Removes obsolete platform-specific usings and duplicate code.

Validation: No build or tests were run in this review.

File Description
src/​libraries/​Common/​src/​System/​Security/​Cryptography/​EccAppleCrypto.macOS.cs Updated as part of this pull request.
src/​libraries/​Common/​src/​System/​Security/​Cryptography/​EccAppleCrypto.iOS.cs Updated as part of this pull request.
src/​libraries/​Common/​src/​System/​Security/​Cryptography/​EccAppleCrypto.cs Updated as part of this pull request.

@vcsjones vcsjones added this to the 12.0.0 milestone Sep 29, 2026
@vcsjones vcsjones added the os-mac-os-x macOS aka OSX label Sep 29, 2026
@vcsjones
vcsjones enabled auto-merge (squash) September 29, 2026 21:51
@vcsjones
vcsjones merged commit d0113f2 into dotnet:main Sep 29, 2026
109 of 112 checks passed
@vcsjones
vcsjones deleted the unify-apple-ecc-pub-recovery branch September 29, 2026 21:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-System.Security os-mac-os-x macOS aka OSX tenet-performance Performance related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants