test_class.declarator: PLAINTEXT = "V2hlbiBJIGdyb3cgdXAsIEkgd2FudCB0byBiZSBhIHdhdGVybWVsb24"
test_class.modifier: private static final
test_class.original_string: private static final String PLAINTEXT = "V2hlbiBJIGdyb3cgdXAsIEkgd2FudCB0byBiZSBhIHdhdGVybWVsb24";
test_class.type: String
test_class.var_name: PLAINTEXT
test_class.declarator: RECEIVER_PRIVATE_KEY = "q1dXpw3UpT5VOmu_cf_v6ih07Aems3njxI-JWgLcM94"
test_class.modifier: private static final
test_class.original_string: private static final String RECEIVER_PRIVATE_KEY = "q1dXpw3UpT5VOmu_cf_v6ih07Aems3njxI-JWgLcM94";
test_class.type: String
test_class.var_name: RECEIVER_PRIVATE_KEY
test_class.declarator: RECEIVER_PUBLIC_KEY =
        "BCVxsr7N_eNgVRqvHtD0zTZsEc6-VV-JvLexhqUzORcxaOzi6-AYWXvTBHm4bjyPjs7Vd8pZGH6SRpkNtoIAiw4"
test_class.modifier: private static final
test_class.original_string: private static final String RECEIVER_PUBLIC_KEY =
        "BCVxsr7N_eNgVRqvHtD0zTZsEc6-VV-JvLexhqUzORcxaOzi6-AYWXvTBHm4bjyPjs7Vd8pZGH6SRpkNtoIAiw4";
test_class.type: String
test_class.var_name: RECEIVER_PUBLIC_KEY
test_class.declarator: AUTH_SECRET = "BTBZMqHH6r4Tts7J_aSIgg"
test_class.modifier: private static final
test_class.original_string: private static final String AUTH_SECRET = "BTBZMqHH6r4Tts7J_aSIgg";
test_class.type: String
test_class.var_name: AUTH_SECRET
test_class.declarator: CIPHERTEXT =
        "DGv6ra1nlYgDCS1FRnbzlwAAEABBBP4z9KsN6nGRTbVYI_c7VJSPQTBtkgcy27ml"
            + "mlMoZIIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A_yl95bQpu6cVPT"
            + "pK4Mqgkf1CXztLVBSt2Ks3oZwbuwXPXLWyouBWLVWGNWQexSgSxsj_Qulcy4a-fN"
test_class.modifier: private static final
test_class.original_string: private static final String CIPHERTEXT =
        "DGv6ra1nlYgDCS1FRnbzlwAAEABBBP4z9KsN6nGRTbVYI_c7VJSPQTBtkgcy27ml"
            + "mlMoZIIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A_yl95bQpu6cVPT"
            + "pK4Mqgkf1CXztLVBSt2Ks3oZwbuwXPXLWyouBWLVWGNWQexSgSxsj_Qulcy4a-fN";
test_class.type: String
test_class.var_name: CIPHERTEXT
test_class.declarator: RECORD_SIZE = 4096
test_class.modifier: private static final
test_class.original_string: private static final int RECORD_SIZE = 4096;
test_class.type: int
test_class.var_name: RECORD_SIZE
test_class.file: apps/webpush/src/test/java/com/google/crypto/tink/apps/webpush/WebPushHybridDecryptTest.java
test_class.identifier: WebPushHybridDecryptTest
test_case.body: @Test
    public void testWithRfc8291TestVector() throws Exception {
      byte[] plaintext = Base64.urlSafeDecode(PLAINTEXT);
      byte[] recipientPrivateKey = Base64.urlSafeDecode(RECEIVER_PRIVATE_KEY);
      byte[] recipientPublicKey = Base64.urlSafeDecode(RECEIVER_PUBLIC_KEY);
      byte[] authSecret = Base64.urlSafeDecode(AUTH_SECRET);
      byte[] ciphertext = Base64.urlSafeDecode(CIPHERTEXT);
  
      HybridDecrypt hybridDecrypt =
          new WebPushHybridDecrypt.Builder()
              .withRecordSize(RECORD_SIZE)
              .withAuthSecret(authSecret)
              .withRecipientPublicKey(recipientPublicKey)
              .withRecipientPrivateKey(recipientPrivateKey)
              .build();
      assertArrayEquals(plaintext, hybridDecrypt.decrypt(ciphertext, null /* contextInfo */));
    }
test_case.class_method_signature: WebPushHybridDecryptTest.testWithRfc8291TestVector()
test_case.full_signature: @Test public void testWithRfc8291TestVector()
test_case.identifier: testWithRfc8291TestVector
test_case.invocations: urlSafeDecode urlSafeDecode urlSafeDecode urlSafeDecode urlSafeDecode build withRecipientPrivateKey withRecipientPublicKey withAuthSecret withRecordSize assertArrayEquals decrypt
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testWithRfc8291TestVector()
focal_class.declarator: recipientPrivateKey
focal_class.modifier: private final
focal_class.original_string: private final ECPrivateKey recipientPrivateKey;
focal_class.type: ECPrivateKey
focal_class.var_name: recipientPrivateKey
focal_class.declarator: recipientPublicKey
focal_class.modifier: private final
focal_class.original_string: private final byte[] recipientPublicKey;
focal_class.type: byte[]
focal_class.var_name: recipientPublicKey
focal_class.declarator: authSecret
focal_class.modifier: private final
focal_class.original_string: private final byte[] authSecret;
focal_class.type: byte[]
focal_class.var_name: authSecret
focal_class.declarator: recordSize
focal_class.modifier: private final
focal_class.original_string: private final int recordSize;
focal_class.type: int
focal_class.var_name: recordSize
focal_class.file: apps/webpush/src/main/java/com/google/crypto/tink/apps/webpush/WebPushHybridDecrypt.java
focal_class.identifier: WebPushHybridDecrypt
focal_class.interfaces: implements HybridDecrypt
focal_class.class_method_signature: WebPushHybridDecrypt.WebPushHybridDecrypt(Builder builder)
focal_class.full_signature: private  WebPushHybridDecrypt(Builder builder)
focal_class.identifier: WebPushHybridDecrypt
focal_class.modifiers: private
focal_class.parameters: (Builder builder)
focal_class.signature:  WebPushHybridDecrypt(Builder builder)
focal_class.class_method_signature: WebPushHybridDecrypt.decrypt(final byte[] ciphertext, final byte[] contextInfo /* unused */)
focal_class.full_signature: @Override public byte[] decrypt(final byte[] ciphertext, final byte[] contextInfo /* unused */)
focal_class.identifier: decrypt
focal_class.modifiers: @Override public
focal_class.parameters: (final byte[] ciphertext, final byte[] contextInfo /* unused */)
focal_class.return: byte[]
focal_class.signature: byte[] decrypt(final byte[] ciphertext, final byte[] contextInfo /* unused */)
focal_class.class_method_signature: WebPushHybridDecrypt.decrypt(final byte[] key, final byte[] nonce, final byte[] ciphertext)
focal_class.full_signature: private byte[] decrypt(final byte[] key, final byte[] nonce, final byte[] ciphertext)
focal_class.identifier: decrypt
focal_class.modifiers: private
focal_class.parameters: (final byte[] key, final byte[] nonce, final byte[] ciphertext)
focal_class.return: byte[]
focal_class.signature: byte[] decrypt(final byte[] key, final byte[] nonce, final byte[] ciphertext)
focal_method.body: @Override
    public byte[] decrypt(final byte[] ciphertext, final byte[] contextInfo /* unused */)
        throws GeneralSecurityException {
      if (contextInfo != null) {
        throw new GeneralSecurityException("contextInfo must be null because it is unused");
      }
  
      if (ciphertext.length < WebPushConstants.CIPHERTEXT_OVERHEAD) {
        throw new GeneralSecurityException("ciphertext too short");
      }
  
      // A push service is not required to support more than 4096 octets of
      // payload body. See https://tools.ietf.org/html/rfc8291#section-4.0.
      if (ciphertext.length > WebPushConstants.MAX_CIPHERTEXT_SIZE) {
        throw new GeneralSecurityException("ciphertext too long");
      }
  
      // Unpacking.
      ByteBuffer record = ByteBuffer.wrap(ciphertext);
      byte[] salt = new byte[WebPushConstants.SALT_SIZE];
      record.get(salt);
  
      int recordSize = record.getInt();
      if (recordSize != this.recordSize
          || recordSize < ciphertext.length
          || recordSize > WebPushConstants.MAX_CIPHERTEXT_SIZE) {
        throw new GeneralSecurityException("invalid record size: " + recordSize);
      }
  
      int publicKeySize = (int) record.get();
      if (publicKeySize != WebPushConstants.PUBLIC_KEY_SIZE) {
        throw new GeneralSecurityException("invalid ephemeral public key size: " + publicKeySize);
      }
  
      byte[] asPublicKey = new byte[WebPushConstants.PUBLIC_KEY_SIZE];
      record.get(asPublicKey);
      ECPoint asPublicPoint =
          EllipticCurves.pointDecode(
              WebPushConstants.NIST_P256_CURVE_TYPE,
              WebPushConstants.UNCOMPRESSED_POINT_FORMAT,
              asPublicKey);
  
      byte[] payload = new byte[ciphertext.length - WebPushConstants.CONTENT_CODING_HEADER_SIZE];
      record.get(payload);
  
      // See https://tools.ietf.org/html/rfc8291#section-3.4.
      byte[] ecdhSecret = EllipticCurves.computeSharedSecret(recipientPrivateKey, asPublicPoint);
      byte[] ikm = WebPushUtil.computeIkm(ecdhSecret, authSecret, recipientPublicKey, asPublicKey);
      byte[] cek = WebPushUtil.computeCek(ikm, salt);
      byte[] nonce = WebPushUtil.computeNonce(ikm, salt);
  
      return decrypt(cek, nonce, payload);
    }
focal_method.class_method_signature: WebPushHybridDecrypt.decrypt(final byte[] ciphertext, final byte[] contextInfo /* unused */)
focal_method.full_signature: @Override public byte[] decrypt(final byte[] ciphertext, final byte[] contextInfo /* unused */)
focal_method.identifier: decrypt
focal_method.invocations: wrap get getInt get get pointDecode get computeSharedSecret computeIkm computeCek computeNonce decrypt
focal_method.modifiers: @Override public
focal_method.parameters: (final byte[] ciphertext, final byte[] contextInfo /* unused */)
focal_method.return: byte[]
focal_method.signature: byte[] decrypt(final byte[] ciphertext, final byte[] contextInfo /* unused */)