From e72aaadac2f64693d8fedfbf6a45cb2f392ac789 Mon Sep 17 00:00:00 2001 From: Harshita Yadav Date: Sat, 7 Feb 2026 15:45:15 +0530 Subject: [PATCH 1/2] Document and test maximum deriveBits length for ECDH curves --- lib/src/webcrypto/webcrypto.ecdh.dart | 4 ++ test/crypto_subtle_test.dart | 67 +++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/lib/src/webcrypto/webcrypto.ecdh.dart b/lib/src/webcrypto/webcrypto.ecdh.dart index 6a7770c2..bf55f3d5 100644 --- a/lib/src/webcrypto/webcrypto.ecdh.dart +++ b/lib/src/webcrypto/webcrypto.ecdh.dart @@ -206,6 +206,10 @@ final class EcdhPrivateKey { /// two parties. /// /// [length] specifies the length of the derived secret in bits. + /// The maximum length that can be derived depends on the elliptic curve: + /// * [EllipticCurve.p256] can derive up to 256 bits. + /// * [EllipticCurve.p384] can derive up to 384 bits. + /// * [EllipticCurve.p521] can derive up to 528 bits. /// [publicKey] is [EcdhPublicKey] from the other party's ECDH key pair. /// /// Returns a [Uint8List] containing the derived shared secret. diff --git a/test/crypto_subtle_test.dart b/test/crypto_subtle_test.dart index 3c114a08..f02dcee5 100644 --- a/test/crypto_subtle_test.dart +++ b/test/crypto_subtle_test.dart @@ -310,6 +310,73 @@ void main() { ); }); }); + group('ECDH deriveBits', () { + test('P-256 allows maximum deriveBits length', () async { + final aliceKeyPair = await EcdhPrivateKey.generateKey(EllipticCurve.p256); + final bobKeyPair = await EcdhPrivateKey.generateKey(EllipticCurve.p256); + + final secret = await aliceKeyPair.privateKey.deriveBits( + 256, + bobKeyPair.publicKey, + ); + + expect(secret.length, equals(32)); + }); + + test('P-256 rejects deriveBits larger than maximum', () async { + final aliceKeyPair = await EcdhPrivateKey.generateKey(EllipticCurve.p256); + final bobKeyPair = await EcdhPrivateKey.generateKey(EllipticCurve.p256); + + expect( + aliceKeyPair.privateKey.deriveBits(257, bobKeyPair.publicKey), + throwsA(anyOf(isA(), isA())), + ); + }); + + test('P-384 allows maximum deriveBits length', () async { + final aliceKeyPair = await EcdhPrivateKey.generateKey(EllipticCurve.p384); + final bobKeyPair = await EcdhPrivateKey.generateKey(EllipticCurve.p384); + + final secret = await aliceKeyPair.privateKey.deriveBits( + 384, + bobKeyPair.publicKey, + ); + + expect(secret.length, equals(48)); + }); + + test('P-384 rejects deriveBits larger than maximum', () async { + final aliceKeyPair = await EcdhPrivateKey.generateKey(EllipticCurve.p384); + final bobKeyPair = await EcdhPrivateKey.generateKey(EllipticCurve.p384); + + expect( + aliceKeyPair.privateKey.deriveBits(385, bobKeyPair.publicKey), + throwsA(anyOf(isA(), isA())), + ); + }); + + test('P-521 allows maximum deriveBits length', () async { + final aliceKeyPair = await EcdhPrivateKey.generateKey(EllipticCurve.p521); + final bobKeyPair = await EcdhPrivateKey.generateKey(EllipticCurve.p521); + + final secret = await aliceKeyPair.privateKey.deriveBits( + 528, + bobKeyPair.publicKey, + ); + + expect(secret.length, equals(66)); + }); + + test('P-521 rejects deriveBits larger than maximum', () async { + final aliceKeyPair = await EcdhPrivateKey.generateKey(EllipticCurve.p521); + final bobKeyPair = await EcdhPrivateKey.generateKey(EllipticCurve.p521); + + expect( + aliceKeyPair.privateKey.deriveBits(529, bobKeyPair.publicKey), + throwsA(anyOf(isA(), isA())), + ); + }); + }); } extension on JSArray { From c3f82313b3b77f2a109fc2f3c911d492f7df202c Mon Sep 17 00:00:00 2001 From: Harshita Yadav Date: Wed, 4 Mar 2026 23:20:56 +0530 Subject: [PATCH 2/2] Update lib/src/webcrypto/webcrypto.ecdh.dart Co-authored-by: HamdaanAliQuatil <96776914+HamdaanAliQuatil@users.noreply.github.com> --- lib/src/webcrypto/webcrypto.ecdh.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/webcrypto/webcrypto.ecdh.dart b/lib/src/webcrypto/webcrypto.ecdh.dart index bf55f3d5..7aba31e0 100644 --- a/lib/src/webcrypto/webcrypto.ecdh.dart +++ b/lib/src/webcrypto/webcrypto.ecdh.dart @@ -206,7 +206,7 @@ final class EcdhPrivateKey { /// two parties. /// /// [length] specifies the length of the derived secret in bits. - /// The maximum length that can be derived depends on the elliptic curve: + /// The maximum allowed [length] is determined by the elliptic curve: /// * [EllipticCurve.p256] can derive up to 256 bits. /// * [EllipticCurve.p384] can derive up to 384 bits. /// * [EllipticCurve.p521] can derive up to 528 bits.