function encrypt({ message, publicKey, privateKey, ivbuf, opts = {} }) {
  $.checkArgument(message, 'message is required');
  $.checkArgument(publicKey, 'publicKey is required');
  $.checkArgument(privateKey, 'privateKey is required');
  $.checkArgument(!ivbuf || ivbuf.length === 16, 'ivbuf must be 16 bytes');

  if (!Buffer.isBuffer(message)) {
    message = Buffer.from(message);
  }
  if (!ivbuf) {
    ivbuf = Hash.sha256hmac(message, privateKey.toBuffer()).subarray(0, 16);
  }
  if (!(publicKey instanceof PublicKey)) {
    publicKey = new PublicKey(publicKey);
  }
  if (!(privateKey instanceof PrivateKey)) {
    privateKey = new PrivateKey(privateKey);
  }

  const [kE, kM] = KDF(privateKey, publicKey);

  const cipher = crypto.createCipheriv('aes-256-cbc', kE, ivbuf);
  const cipherText = Buffer.concat([cipher.update(message), cipher.final()]);
  
  let tag = Hash.sha256hmac(cipherText, kM);
  if (opts.shortTag) {
    tag = tag.subarray(0, 4);
  }

  let encbuf;
  if (opts.noKey) {
    encbuf = Buffer.concat([ivbuf, cipherText, tag]);
  } else {
    const Rbuf = privateKey.publicKey.toDER(true);
    encbuf = Buffer.concat([Rbuf, ivbuf, cipherText, tag]);
  }
  return encbuf;
}
Encrypts the message (String or Buffer) using EC keys.
@param {Object} params
@param {Buffer|string} params.message - Message to be encrypted.
@param {PublicKey} params.publicKey - Receipient's public key is used to encrypt the message.
@param {PrivateKey} params.privateKey - Your private key is used to sign the payload.
@param {Buffer} params.ivbuf (optional) 16-byte initialization vector (IV) Buffer to be used in AES-CBC.
                   By default, `ivbuf` is computed deterministically from message and private key using HMAC-SHA256.
                   Deterministic IV enables end-to-end test vectors for alternative implementations.
                   Note that identical messages have identical ciphertexts. If it is important to not allow an attacker
                   to learn that a message is repeated, then you should use a custom IV *or* use some sequence identifier
                   or "salt" inside the message.
@param {Object} params.opts (optional) Options object. Every field is optional.
@param {boolean} params.opts.noKey - Do not include pubkey in the output.
@param {boolean} params.opts.shortTag - Use 4-byte tag instead of 32-byte. This must be communicated to the payload recipient.
@returns {Buffer} Payload buffer with `pubkey|iv|ciphertext|tag` (pubkey is excluded if `noKey` is given).