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

package com.google.crypto.tink.subtle;

import java.security.spec.EllipticCurve;
import java.util.Arrays;
import com.google.crypto.tink.internal.Util;
import com.google.crypto.tink.AccessesPartialKey;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.internal.BigIntegerEncoding;
import com.google.crypto.tink.InsecureSecretKeyAccess;
import com.google.crypto.tink.hybrid.EciesPrivateKey;
import com.google.crypto.tink.hybrid.internal.EciesDemHelper;
import java.security.interfaces.ECPrivateKey;
import com.google.crypto.tink.HybridDecrypt;

public final class EciesAeadHkdfHybridDecrypt implements HybridDecrypt
{
    private final ECPrivateKey recipientPrivateKey;
    private final EciesHkdfRecipientKem recipientKem;
    private final String hkdfHmacAlgo;
    private final byte[] hkdfSalt;
    private final EllipticCurves.PointFormatType ecPointFormat;
    private final EciesDemHelper.Dem dem;
    private final byte[] outputPrefix;
    
    private EciesAeadHkdfHybridDecrypt(final ECPrivateKey recipientPrivateKey, final byte[] hkdfSalt, final String hkdfHmacAlgo, final EllipticCurves.PointFormatType ecPointFormat, final EciesDemHelper.Dem dem, final byte[] outputPrefix) {
        this.recipientPrivateKey = recipientPrivateKey;
        this.recipientKem = new EciesHkdfRecipientKem(recipientPrivateKey);
        this.hkdfSalt = hkdfSalt;
        this.hkdfHmacAlgo = hkdfHmacAlgo;
        this.ecPointFormat = ecPointFormat;
        this.dem = dem;
        this.outputPrefix = outputPrefix;
    }
    
    @AccessesPartialKey
    public static HybridDecrypt create(final EciesPrivateKey key) throws GeneralSecurityException {
        final EllipticCurves.CurveType curveType = EciesAeadHkdfHybridEncrypt.CURVE_TYPE_CONVERTER.toProtoEnum(key.getParameters().getCurveType());
        final ECPrivateKey recipientPrivateKey = EllipticCurves.getEcPrivateKey(curveType, BigIntegerEncoding.toBigEndianBytes(key.getNistPrivateKeyValue().getBigInteger(InsecureSecretKeyAccess.get())));
        byte[] hkdfSalt = new byte[0];
        if (key.getParameters().getSalt() != null) {
            hkdfSalt = key.getParameters().getSalt().toByteArray();
        }
        return new EciesAeadHkdfHybridDecrypt(recipientPrivateKey, hkdfSalt, EciesAeadHkdfHybridEncrypt.toHmacAlgo(key.getParameters().getHashType()), EciesAeadHkdfHybridEncrypt.POINT_FORMAT_TYPE_CONVERTER.toProtoEnum(key.getParameters().getNistCurvePointFormat()), EciesDemHelper.getDem(key.getParameters()), key.getOutputPrefix().toByteArray());
    }
    
    @Override
    public byte[] decrypt(final byte[] ciphertext, final byte[] contextInfo) throws GeneralSecurityException {
        if (!Util.isPrefix(this.outputPrefix, ciphertext)) {
            throw new GeneralSecurityException("Invalid ciphertext (output prefix mismatch)");
        }
        final int prefixSize = this.outputPrefix.length;
        final EllipticCurve curve = this.recipientPrivateKey.getParams().getCurve();
        final int headerSize = EllipticCurves.encodingSizeInBytes(curve, this.ecPointFormat);
        if (ciphertext.length < prefixSize + headerSize) {
            throw new GeneralSecurityException("ciphertext too short");
        }
        final byte[] kemBytes = Arrays.copyOfRange(ciphertext, prefixSize, prefixSize + headerSize);
        final byte[] symmetricKey = this.recipientKem.generateKey(kemBytes, this.hkdfHmacAlgo, this.hkdfSalt, contextInfo, this.dem.getSymmetricKeySizeInBytes(), this.ecPointFormat);
        return this.dem.decrypt(symmetricKey, ciphertext, prefixSize + headerSize);
    }
}
