Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/src/webcrypto/webcrypto.ecdh.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
67 changes: 67 additions & 0 deletions test/crypto_subtle_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<subtle.JSDomException>(), isA<Error>())),
);
});

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<subtle.JSDomException>(), isA<Error>())),
);
});

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<subtle.JSDomException>(), isA<Error>())),
);
});
});
}

extension on JSArray<JSString> {
Expand Down