sharedSecretKey method

  1. @override
Future<SecretKey> sharedSecretKey({
  1. required KeyPair keyPair,
  2. required PublicKey remotePublicKey,
})

Calculates a shared SecretKey.

Example

In this example, we use X25519:

import 'package:cryptography/cryptography.dart';

Future<void> main() async {
  final algorithm = X25519();

  // We need the private key pair of Alice.
  final aliceKeyPair = await algorithm.newKeyPair();

  // We need only public key of Bob.
  final bobKeyPair = await algorithm.newKeyPair();
  final bobPublicKey = await bobKeyPair.extractPublicKey();

  // We can now calculate a 32-byte shared secret key.
  final sharedSecretKey = await algorithm.sharedSecretKey(
    keyPair: aliceKeyPair,
    remotePublicKey: bobPublicKey,
  );
}

Implementation

@override
Future<SecretKey> sharedSecretKey({
  required KeyPair keyPair,
  required PublicKey remotePublicKey,
}) async {
  if (isSupportedPlatform) {
    final keyPairData = await keyPair.extract();
    if (keyPairData is! EcKeyPairData) {
      throw ArgumentError.value(
        keyPair,
        'keyPair',
        'Expected EcKeyPair',
      );
    }
    if (remotePublicKey is! EcPublicKey) {
      throw ArgumentError.value(
        remotePublicKey,
        'remotePublicKey',
        'Expected EcPublicKey',
      );
    }
    Map result;
    if (isCupertino) {
      result = await invokeMethod(
        'Ecdh.sharedSecretKey',
        {
          if (isAndroid) 'androidProvider': androidCryptoProvider,
          'curve': _curveName,
          'localDer': keyPairData.toDer(),
          'remoteDer': remotePublicKey.toDer(),
        },
      );
    } else {
      result = await invokeMethod(
        'Ecdh.sharedSecretKey',
        {
          if (isAndroid) 'androidProvider': androidCryptoProvider,
          'curve': _curveName,
          'localD': asUint8List(keyPairData.d),
          'localX': asUint8List(keyPairData.x),
          'localY': asUint8List(keyPairData.y),
          'remoteX': asUint8List(remotePublicKey.x),
          'remoteY': asUint8List(remotePublicKey.y),
        },
      );
    }
    final error = result['error'];
    if (error != null) {
      throw StateError(
        '"package:cryptography_flutter": invalid output from plugin: $error',
      );
    }
    var bytes = result['bytes'] as Uint8List;
    if (bytes.length >= length) {
      if (bytes.length > length) {
        bytes = bytes.sublist(0, length);
      }
      return SecretKey(bytes);
    }
  }
  final fallback = this.fallback;
  if (fallback == null) {
    throw UnsupportedError('Unsupported and no fallback implementation');
  }
  return await fallback.sharedSecretKey(
    keyPair: keyPair,
    remotePublicKey: remotePublicKey,
  );
}