decrypt static method

Future<String> decrypt({
  1. required String payload,
  2. required Uint8List recipientKemSecretKey,
  3. required String recipientPrivateKey,
  4. required String senderPubkey,
  5. required String recipientPubkey,
})

Decrypts a base64 envelope produced by encrypt.

Throws a single generic error on any failure. Distinguishing bad padding from a bad tag from a wrong key would hand an attacker an oracle.

Implementation

static Future<String> decrypt({
  required String payload,
  required Uint8List recipientKemSecretKey,
  required String recipientPrivateKey,
  required String senderPubkey,
  required String recipientPubkey,
}) async {
  final conversationKey = _conversationKey(recipientPrivateKey, senderPubkey);

  final skPtr = calloc<Uint8>(recipientKemSecretKey.length);
  final convPtr = calloc<Uint8>(conversationKey.length);
  final out = calloc<rust_lib.QsBuffer>();
  final payloadPtr = payload.toNativeUtf8();
  final sender = senderPubkey.toNativeUtf8();
  final recipient = recipientPubkey.toNativeUtf8();
  try {
    skPtr
        .asTypedList(recipientKemSecretKey.length)
        .setAll(0, recipientKemSecretKey);
    convPtr.asTypedList(conversationKey.length).setAll(0, conversationKey);

    final ok = rust_lib.pqOpen(
      payloadPtr,
      skPtr,
      recipientKemSecretKey.length,
      convPtr,
      conversationKey.length,
      sender,
      recipient,
      out,
    );
    if (ok != 1) throw StateError('Decryption failed');
    return utf8.decode(_copyOut(out));
  } finally {
    skPtr
        .asTypedList(recipientKemSecretKey.length)
        .fillRange(0, recipientKemSecretKey.length, 0);
    convPtr
        .asTypedList(conversationKey.length)
        .fillRange(0, conversationKey.length, 0);
    calloc.free(skPtr);
    calloc.free(convPtr);
    calloc.free(out);
    calloc.free(payloadPtr);
    calloc.free(sender);
    calloc.free(recipient);
  }
}