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

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

import java.util.Arrays;
import com.google.crypto.tink.internal.Util;
import com.google.crypto.tink.proto.OutputPrefixType;
import com.google.crypto.tink.KeyManager;
import com.google.crypto.tink.internal.ProtoKeySerialization;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.internal.OutputPrefixUtil;
import com.google.crypto.tink.internal.KeyManagerRegistry;
import com.google.crypto.tink.InsecureSecretKeyAccess;
import com.google.crypto.tink.internal.LegacyProtoKey;
import com.google.errorprone.annotations.Immutable;
import com.google.crypto.tink.HybridDecrypt;

@Immutable
public final class LegacyFullHybridDecrypt implements HybridDecrypt
{
    private final HybridDecrypt rawHybridDecrypt;
    private final byte[] outputPrefix;
    
    public static HybridDecrypt create(final LegacyProtoKey key) throws GeneralSecurityException {
        final ProtoKeySerialization protoKeySerialization = key.getSerialization(InsecureSecretKeyAccess.get());
        final KeyManager<HybridDecrypt> manager = KeyManagerRegistry.globalInstance().getKeyManager(protoKeySerialization.getTypeUrl(), HybridDecrypt.class);
        final HybridDecrypt rawPrimitive = manager.getPrimitive(protoKeySerialization.getValue());
        final OutputPrefixType outputPrefixType = protoKeySerialization.getOutputPrefixType();
        byte[] outputPrefix = null;
        switch (outputPrefixType) {
            case RAW: {
                outputPrefix = OutputPrefixUtil.EMPTY_PREFIX.toByteArray();
                break;
            }
            case LEGACY:
            case CRUNCHY: {
                outputPrefix = OutputPrefixUtil.getLegacyOutputPrefix(key.getIdRequirementOrNull()).toByteArray();
                break;
            }
            case TINK: {
                outputPrefix = OutputPrefixUtil.getTinkOutputPrefix(key.getIdRequirementOrNull()).toByteArray();
                break;
            }
            default: {
                throw new GeneralSecurityException("unknown output prefix type " + outputPrefixType);
            }
        }
        return new LegacyFullHybridDecrypt(rawPrimitive, outputPrefix);
    }
    
    private LegacyFullHybridDecrypt(final HybridDecrypt rawHybridDecrypt, final byte[] outputPrefix) {
        this.rawHybridDecrypt = rawHybridDecrypt;
        this.outputPrefix = outputPrefix;
    }
    
    @Override
    public byte[] decrypt(final byte[] ciphertext, final byte[] contextInfo) throws GeneralSecurityException {
        if (this.outputPrefix.length == 0) {
            return this.rawHybridDecrypt.decrypt(ciphertext, contextInfo);
        }
        if (!Util.isPrefix(this.outputPrefix, ciphertext)) {
            throw new GeneralSecurityException("Invalid ciphertext (output prefix mismatch)");
        }
        final byte[] ciphertextNoPrefix = Arrays.copyOfRange(ciphertext, this.outputPrefix.length, ciphertext.length);
        return this.rawHybridDecrypt.decrypt(ciphertextNoPrefix, contextInfo);
    }
}
