test_class.declarator: UTF_8 = Charset.forName("UTF-8")
test_class.modifier: private static final
test_class.original_string: private static final Charset UTF_8 = Charset.forName("UTF-8");
test_class.type: Charset
test_class.var_name: UTF_8
test_class.file: java_src/src/test/java/com/google/crypto/tink/hybrid/subtle/RsaKemHybridEncryptTest.java
test_class.identifier: RsaKemHybridEncryptTest
test_case.body: @Test
    public void encrypt_decrypt_success() throws GeneralSecurityException {
      if (TestUtil.isTsan()) {
        // RsaKem.generateRsaKeyPair is too slow in Tsan.
        return;
      }
      KeyPair keyPair = RsaKem.generateRsaKeyPair(2048);
      String hmacAlgo = "HMACSHA256";
      byte[] salt = Random.randBytes(20);
  
      RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
      HybridEncrypt hybridEncrypt =
          new RsaKemHybridEncrypt(rsaPublicKey, hmacAlgo, salt, new AesGcmFactory(16));
  
      RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
      HybridDecrypt hybridDecrypt =
          new RsaKemHybridDecrypt(rsaPrivateKey, hmacAlgo, salt, new AesGcmFactory(16));
  
      byte[] plaintext = Random.randBytes(20);
      byte[] context = Random.randBytes(20);
  
      // Makes sure that the encryption is randomized.
      Set<String> ciphertexts = new TreeSet<>();
      for (int j = 0; j < 8; j++) {
        byte[] ciphertext = hybridEncrypt.encrypt(plaintext, context);
        if (ciphertexts.contains(new String(ciphertext, UTF_8))) {
          throw new GeneralSecurityException("Encryption is not randomized");
        }
        ciphertexts.add(new String(ciphertext, UTF_8));
        byte[] decrypted = hybridDecrypt.decrypt(ciphertext, context);
        assertArrayEquals(plaintext, decrypted);
      }
      assertThat(ciphertexts).hasSize(8);
    }
test_case.class_method_signature: RsaKemHybridEncryptTest.encrypt_decrypt_success()
test_case.full_signature: @Test public void encrypt_decrypt_success()
test_case.identifier: encrypt_decrypt_success
test_case.invocations: isTsan generateRsaKeyPair randBytes getPublic getPrivate randBytes randBytes encrypt contains add decrypt assertArrayEquals hasSize assertThat
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void encrypt_decrypt_success()
focal_class.declarator: recipientPublicKey
focal_class.modifier: private final
focal_class.original_string: private final RSAPublicKey recipientPublicKey;
focal_class.type: RSAPublicKey
focal_class.var_name: recipientPublicKey
focal_class.declarator: hkdfHmacAlgo
focal_class.modifier: private final
focal_class.original_string: private final String hkdfHmacAlgo;
focal_class.type: String
focal_class.var_name: hkdfHmacAlgo
focal_class.declarator: hkdfSalt
focal_class.modifier: private final
focal_class.original_string: private final byte[] hkdfSalt;
focal_class.type: byte[]
focal_class.var_name: hkdfSalt
focal_class.declarator: aeadFactory
focal_class.modifier: private final
focal_class.original_string: private final AeadFactory aeadFactory;
focal_class.type: AeadFactory
focal_class.var_name: aeadFactory
focal_class.file: java_src/src/main/java/com/google/crypto/tink/hybrid/subtle/RsaKemHybridEncrypt.java
focal_class.identifier: RsaKemHybridEncrypt
focal_class.interfaces: implements HybridEncrypt
focal_class.class_method_signature: RsaKemHybridEncrypt.RsaKemHybridEncrypt(
        final RSAPublicKey recipientPublicKey,
        String hkdfHmacAlgo,
        final byte[] hkdfSalt,
        AeadFactory aeadFactory)
focal_class.full_signature: public  RsaKemHybridEncrypt(
        final RSAPublicKey recipientPublicKey,
        String hkdfHmacAlgo,
        final byte[] hkdfSalt,
        AeadFactory aeadFactory)
focal_class.identifier: RsaKemHybridEncrypt
focal_class.modifiers: public
focal_class.parameters: (
        final RSAPublicKey recipientPublicKey,
        String hkdfHmacAlgo,
        final byte[] hkdfSalt,
        AeadFactory aeadFactory)
focal_class.signature:  RsaKemHybridEncrypt(
        final RSAPublicKey recipientPublicKey,
        String hkdfHmacAlgo,
        final byte[] hkdfSalt,
        AeadFactory aeadFactory)
focal_class.class_method_signature: RsaKemHybridEncrypt.encrypt(final byte[] plaintext, final byte[] contextInfo)
focal_class.full_signature: @Override public byte[] encrypt(final byte[] plaintext, final byte[] contextInfo)
focal_class.identifier: encrypt
focal_class.modifiers: @Override public
focal_class.parameters: (final byte[] plaintext, final byte[] contextInfo)
focal_class.return: byte[]
focal_class.signature: byte[] encrypt(final byte[] plaintext, final byte[] contextInfo)
focal_method.body: @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();
    }
focal_method.class_method_signature: RsaKemHybridEncrypt.encrypt(final byte[] plaintext, final byte[] contextInfo)
focal_method.full_signature: @Override public byte[] encrypt(final byte[] plaintext, final byte[] contextInfo)
focal_method.identifier: encrypt
focal_method.invocations: getModulus generateSecret getInstance init doFinal computeHkdf getKeySizeInBytes createAead encrypt array put put allocate
focal_method.modifiers: @Override public
focal_method.parameters: (final byte[] plaintext, final byte[] contextInfo)
focal_method.return: byte[]
focal_method.signature: byte[] encrypt(final byte[] plaintext, final byte[] contextInfo)