encrypt static method

Future<String> encrypt({
  1. required String plaintext,
  2. required Uint8List recipientKemKey,
  3. required String senderPrivateKey,
  4. required String senderPubkey,
  5. required String recipientPubkey,
})

Encrypts plaintext to recipientKemKey, returning a base64 envelope.

recipientKemKey comes from the recipient's published attestation. senderPubkey and recipientPubkey must be 64-character lowercase hex x-only pubkeys; they are bound into the AEAD so the ciphertext cannot be replayed into a different conversation or have its direction swapped.

Implementation

static Future<String> encrypt({
  required String plaintext,
  required Uint8List recipientKemKey,
  required String senderPrivateKey,
  required String senderPubkey,
  required String recipientPubkey,
}) async {
  final conversationKey = _conversationKey(senderPrivateKey, recipientPubkey);
  final msg = Uint8List.fromList(utf8.encode(plaintext));

  final kemPtr = calloc<Uint8>(recipientKemKey.length);
  final convPtr = calloc<Uint8>(conversationKey.length);
  final msgPtr = calloc<Uint8>(msg.length);
  final out = calloc<rust_lib.QsBuffer>();
  final sender = senderPubkey.toNativeUtf8();
  final recipient = recipientPubkey.toNativeUtf8();
  try {
    kemPtr.asTypedList(recipientKemKey.length).setAll(0, recipientKemKey);
    convPtr.asTypedList(conversationKey.length).setAll(0, conversationKey);
    msgPtr.asTypedList(msg.length).setAll(0, msg);

    final ok = rust_lib.pqSeal(
      kemPtr,
      recipientKemKey.length,
      convPtr,
      conversationKey.length,
      sender,
      recipient,
      msgPtr,
      msg.length,
      out,
    );
    if (ok != 1) throw StateError('Post-quantum encryption failed');
    return utf8.decode(_copyOut(out));
  } finally {
    convPtr
        .asTypedList(conversationKey.length)
        .fillRange(0, conversationKey.length, 0);
    msgPtr.asTypedList(msg.length).fillRange(0, msg.length, 0);
    calloc.free(kemPtr);
    calloc.free(convPtr);
    calloc.free(msgPtr);
    calloc.free(out);
    calloc.free(sender);
    calloc.free(recipient);
  }
}