// 
// Decompiled by Procyon v0.6.0
// 

package com.google.crypto.tink.hybrid.subtle;

import com.google.crypto.tink.Aead;
import com.google.crypto.tink.subtle.Hkdf;
import java.nio.ByteBuffer;
import java.security.InvalidKeyException;
import java.security.interfaces.RSAPrivateKey;
import java.security.GeneralSecurityException;
import java.math.BigInteger;
import java.security.interfaces.RSAKey;
import com.google.crypto.tink.aead.subtle.AeadFactory;
import java.security.PrivateKey;
import com.google.crypto.tink.HybridDecrypt;

public final class RsaKemHybridDecrypt implements HybridDecrypt
{
    private final PrivateKey recipientPrivateKey;
    private final String hkdfHmacAlgo;
    private final byte[] hkdfSalt;
    private final AeadFactory aeadFactory;
    private final int modSizeInBytes;
    
    private RsaKemHybridDecrypt(final PrivateKey recipientPrivateKey, final String hkdfHmacAlgo, final byte[] hkdfSalt, final AeadFactory aeadFactory) throws GeneralSecurityException {
        final BigInteger mod = ((RSAKey)recipientPrivateKey).getModulus();
        RsaKem.validateRsaModulus(mod);
        this.recipientPrivateKey = recipientPrivateKey;
        this.hkdfSalt = hkdfSalt;
        this.hkdfHmacAlgo = hkdfHmacAlgo;
        this.aeadFactory = aeadFactory;
        this.modSizeInBytes = RsaKem.bigIntSizeInBytes(mod);
    }
    
    public RsaKemHybridDecrypt(final RSAPrivateKey recipientPrivateKey, final String hkdfHmacAlgo, final byte[] hkdfSalt, final AeadFactory aeadFactory) throws GeneralSecurityException {
        this((PrivateKey)recipientPrivateKey, hkdfHmacAlgo, hkdfSalt, aeadFactory);
    }
    
    public static RsaKemHybridDecrypt create(final PrivateKey recipientPrivateKey, final String hkdfHmacAlgo, final byte[] hkdfSalt, final AeadFactory aeadFactory) throws GeneralSecurityException {
        if (!(recipientPrivateKey instanceof RSAKey)) {
            throw new InvalidKeyException("Must be an RSA private key");
        }
        return new RsaKemHybridDecrypt(recipientPrivateKey, hkdfHmacAlgo, hkdfSalt, aeadFactory);
    }
    
    @Override
    public byte[] decrypt(final byte[] ciphertext, final byte[] contextInfo) throws GeneralSecurityException {
        if (ciphertext.length < this.modSizeInBytes) {
            throw new GeneralSecurityException(String.format("Ciphertext must be of at least size %d bytes, but got %d", this.modSizeInBytes, ciphertext.length));
        }
        final ByteBuffer cipherBuffer = ByteBuffer.wrap(ciphertext);
        final byte[] token = new byte[this.modSizeInBytes];
        cipherBuffer.get(token);
        final byte[] sharedSecret = RsaKem.rsaDecrypt(this.recipientPrivateKey, token);
        final byte[] demKey = Hkdf.computeHkdf(this.hkdfHmacAlgo, sharedSecret, this.hkdfSalt, contextInfo, this.aeadFactory.getKeySizeInBytes());
        final Aead aead = this.aeadFactory.createAead(demKey);
        final byte[] demPayload = new byte[cipherBuffer.remaining()];
        cipherBuffer.get(demPayload);
        return aead.decrypt(demPayload, RsaKem.EMPTY_AAD);
    }
}
