class RsaKemHybridEncrypt implements HybridEncrypt {

  @Override
  public byte[] encrypt(final byte[] plaintext, final byte[] contextInfo)
      throws GeneralSecurityException {
    // KEM: generate a random shared secret whose bit length is equal to the modulus'.
    BigInteger mod = recipientPublicKey.getModulus();
    byte[] sharedSecret = RsaKem.generateSecret(mod);

    // KEM: encrypt the shared secret using the public key.
    Cipher rsaCipher = Cipher.getInstance("RSA/ECB/NoPadding");
    rsaCipher.init(Cipher.ENCRYPT_MODE, recipientPublicKey);
    byte[] token = rsaCipher.doFinal(sharedSecret);

    // KDF: derive a DEM key from the shared secret, salt, and contextInfo.
    byte[] demKey =
        Hkdf.computeHkdf(
            hkdfHmacAlgo, sharedSecret, hkdfSalt, contextInfo, aeadFactory.getKeySizeInBytes());

    Aead aead = aeadFactory.createAead(demKey);
    byte[] ciphertext = aead.encrypt(plaintext, RsaKem.EMPTY_AAD);
    return ByteBuffer.allocate(token.length + ciphertext.length).put(token).put(ciphertext).array();
  }

  public  RsaKemHybridEncrypt(
      final RSAPublicKey recipientPublicKey,
      String hkdfHmacAlgo,
      final byte[] hkdfSalt,
      AeadFactory aeadFactory);

}