From 1a8979fa5330dd354e75d992a14caf8308f4294a Mon Sep 17 00:00:00 2001 From: HamdaanAliQuatil Date: Fri, 30 May 2025 03:21:01 +0530 Subject: [PATCH] perf: move ec key gen off the main thread --- lib/src/impl_ffi/impl_ffi.dart | 1 + lib/src/impl_ffi/impl_ffi.ec_common.dart | 22 ++++++++++++++++++---- lib/src/impl_ffi/impl_ffi.ecdh.dart | 2 +- lib/src/impl_ffi/impl_ffi.ecdsa.dart | 2 +- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/src/impl_ffi/impl_ffi.dart b/lib/src/impl_ffi/impl_ffi.dart index 1603dd0f..7f985909 100644 --- a/lib/src/impl_ffi/impl_ffi.dart +++ b/lib/src/impl_ffi/impl_ffi.dart @@ -20,6 +20,7 @@ import 'dart:async'; import 'dart:ffi' show Allocator; import 'dart:typed_data'; import 'dart:convert' show utf8, base64Url; +import 'dart:isolate'; import 'dart:ffi' as ffi; import 'dart:math' as math; import 'package:meta/meta.dart'; diff --git a/lib/src/impl_ffi/impl_ffi.ec_common.dart b/lib/src/impl_ffi/impl_ffi.ec_common.dart index 9c097127..28334a3c 100644 --- a/lib/src/impl_ffi/impl_ffi.ec_common.dart +++ b/lib/src/impl_ffi/impl_ffi.ec_common.dart @@ -327,15 +327,15 @@ Map _exportJwkEcPrivateOrPublicKey( }); } -KeyPair<_EvpPKey, _EvpPKey> _generateEcKeyPair( +Future> _generateEcKeyPair( EllipticCurve curve, -) { - return _Scope.sync((scope) { +) async { + return _Scope.async((scope) async { final ecPriv = ssl.EC_KEY_new_by_curve_name(_ecCurveToNID(curve)); _checkOp(ecPriv.address != 0, fallback: 'internal failure to use curve'); scope.defer(() => ssl.EC_KEY_free(ecPriv)); - _checkOpIsOne(ssl.EC_KEY_generate_key(ecPriv)); + _checkOpIsOne(await _EC_generate_key(ecPriv)); final privKey = _EvpPKey(); _checkOpIsOne(ssl.EVP_PKEY_set1_EC_KEY.invoke(privKey, ecPriv)); @@ -357,3 +357,17 @@ KeyPair<_EvpPKey, _EvpPKey> _generateEcKeyPair( ); }); } + +/// Helper function to run `ssl.EC_KEY_generate_key` in an [Isolate] +/// using [Isolate.run]. +/// +/// Using this auxiliary function to wrap the call should reduce the risk that +/// unnecessary variables are copied into the closure passed to [Isolate.run]. +// ignore: non_constant_identifier_names +Future _EC_generate_key( + ffi.Pointer key, +) async => + await Isolate.run( + () => ssl.EC_KEY_generate_key(key), + debugName: 'EC_KEY_generate_key', + ); diff --git a/lib/src/impl_ffi/impl_ffi.ecdh.dart b/lib/src/impl_ffi/impl_ffi.ecdh.dart index fb8e42d6..5d66051a 100644 --- a/lib/src/impl_ffi/impl_ffi.ecdh.dart +++ b/lib/src/impl_ffi/impl_ffi.ecdh.dart @@ -38,7 +38,7 @@ Future> ecdhPrivateKey_generateKey( EllipticCurve curve, ) async { - final p = _generateEcKeyPair(curve); + final p = await _generateEcKeyPair(curve); return ( privateKey: _EcdhPrivateKeyImpl(p.privateKey), publicKey: _EcdhPublicKeyImpl(p.publicKey), diff --git a/lib/src/impl_ffi/impl_ffi.ecdsa.dart b/lib/src/impl_ffi/impl_ffi.ecdsa.dart index 9f9db6fa..6c05b691 100644 --- a/lib/src/impl_ffi/impl_ffi.ecdsa.dart +++ b/lib/src/impl_ffi/impl_ffi.ecdsa.dart @@ -54,7 +54,7 @@ Future> ecdsaPrivateKey_generateKey( EllipticCurve curve, ) async { - final p = _generateEcKeyPair(curve); + final p = await _generateEcKeyPair(curve); return ( privateKey: _EcdsaPrivateKeyImpl(p.privateKey), publicKey: _EcdsaPublicKeyImpl(p.publicKey),