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

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

import com.google.crypto.tink.internal.Util;
import com.google.crypto.tink.internal.MutableSerializationRegistry;
import com.google.crypto.tink.util.SecretBytes;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.crypto.tink.proto.KeyData;
import com.google.crypto.tink.proto.HmacKey;
import com.google.protobuf.ByteString;
import com.google.crypto.tink.proto.AesCtrKey;
import javax.annotation.Nullable;
import com.google.crypto.tink.SecretKeyAccess;
import com.google.crypto.tink.proto.HmacKeyFormat;
import com.google.crypto.tink.proto.AesCtrParams;
import com.google.crypto.tink.proto.AesCtrKeyFormat;
import com.google.crypto.tink.proto.AesCtrHmacAeadKeyFormat;
import com.google.crypto.tink.proto.KeyTemplate;
import com.google.crypto.tink.proto.HmacParams;
import com.google.crypto.tink.proto.HashType;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.proto.OutputPrefixType;
import com.google.crypto.tink.internal.KeyParser;
import com.google.crypto.tink.internal.ProtoKeySerialization;
import com.google.crypto.tink.aead.AesCtrHmacAeadKey;
import com.google.crypto.tink.internal.KeySerializer;
import com.google.crypto.tink.internal.ParametersParser;
import com.google.crypto.tink.internal.ProtoParametersSerialization;
import com.google.crypto.tink.aead.AesCtrHmacAeadParameters;
import com.google.crypto.tink.internal.ParametersSerializer;
import com.google.crypto.tink.util.Bytes;
import com.google.crypto.tink.AccessesPartialKey;

@AccessesPartialKey
public final class AesCtrHmacAeadProtoSerialization
{
    private static final String TYPE_URL = "type.googleapis.com/google.crypto.tink.AesCtrHmacAeadKey";
    private static final Bytes TYPE_URL_BYTES;
    private static final ParametersSerializer<AesCtrHmacAeadParameters, ProtoParametersSerialization> PARAMETERS_SERIALIZER;
    private static final ParametersParser<ProtoParametersSerialization> PARAMETERS_PARSER;
    private static final KeySerializer<AesCtrHmacAeadKey, ProtoKeySerialization> KEY_SERIALIZER;
    private static final KeyParser<ProtoKeySerialization> KEY_PARSER;
    
    private static OutputPrefixType toProtoOutputPrefixType(final AesCtrHmacAeadParameters.Variant variant) throws GeneralSecurityException {
        if (AesCtrHmacAeadParameters.Variant.TINK.equals(variant)) {
            return OutputPrefixType.TINK;
        }
        if (AesCtrHmacAeadParameters.Variant.CRUNCHY.equals(variant)) {
            return OutputPrefixType.CRUNCHY;
        }
        if (AesCtrHmacAeadParameters.Variant.NO_PREFIX.equals(variant)) {
            return OutputPrefixType.RAW;
        }
        throw new GeneralSecurityException("Unable to serialize variant: " + variant);
    }
    
    private static AesCtrHmacAeadParameters.Variant toVariant(final OutputPrefixType outputPrefixType) throws GeneralSecurityException {
        switch (outputPrefixType) {
            case TINK: {
                return AesCtrHmacAeadParameters.Variant.TINK;
            }
            case CRUNCHY:
            case LEGACY: {
                return AesCtrHmacAeadParameters.Variant.CRUNCHY;
            }
            case RAW: {
                return AesCtrHmacAeadParameters.Variant.NO_PREFIX;
            }
            default: {
                throw new GeneralSecurityException("Unable to parse OutputPrefixType: " + outputPrefixType.getNumber());
            }
        }
    }
    
    private static HashType toProtoHashType(final AesCtrHmacAeadParameters.HashType hashType) throws GeneralSecurityException {
        if (AesCtrHmacAeadParameters.HashType.SHA1.equals(hashType)) {
            return HashType.SHA1;
        }
        if (AesCtrHmacAeadParameters.HashType.SHA224.equals(hashType)) {
            return HashType.SHA224;
        }
        if (AesCtrHmacAeadParameters.HashType.SHA256.equals(hashType)) {
            return HashType.SHA256;
        }
        if (AesCtrHmacAeadParameters.HashType.SHA384.equals(hashType)) {
            return HashType.SHA384;
        }
        if (AesCtrHmacAeadParameters.HashType.SHA512.equals(hashType)) {
            return HashType.SHA512;
        }
        throw new GeneralSecurityException("Unable to serialize HashType " + hashType);
    }
    
    private static AesCtrHmacAeadParameters.HashType toHashType(final HashType hashType) throws GeneralSecurityException {
        switch (hashType) {
            case SHA1: {
                return AesCtrHmacAeadParameters.HashType.SHA1;
            }
            case SHA224: {
                return AesCtrHmacAeadParameters.HashType.SHA224;
            }
            case SHA256: {
                return AesCtrHmacAeadParameters.HashType.SHA256;
            }
            case SHA384: {
                return AesCtrHmacAeadParameters.HashType.SHA384;
            }
            case SHA512: {
                return AesCtrHmacAeadParameters.HashType.SHA512;
            }
            default: {
                throw new GeneralSecurityException("Unable to parse HashType: " + hashType.getNumber());
            }
        }
    }
    
    private static HmacParams getHmacProtoParams(final AesCtrHmacAeadParameters parameters) throws GeneralSecurityException {
        return HmacParams.newBuilder().setTagSize(parameters.getTagSizeBytes()).setHash(toProtoHashType(parameters.getHashType())).build();
    }
    
    private static ProtoParametersSerialization serializeParameters(final AesCtrHmacAeadParameters parameters) throws GeneralSecurityException {
        return ProtoParametersSerialization.create(KeyTemplate.newBuilder().setTypeUrl("type.googleapis.com/google.crypto.tink.AesCtrHmacAeadKey").setValue(AesCtrHmacAeadKeyFormat.newBuilder().setAesCtrKeyFormat(AesCtrKeyFormat.newBuilder().setParams(AesCtrParams.newBuilder().setIvSize(parameters.getIvSizeBytes()).build()).setKeySize(parameters.getAesKeySizeBytes()).build()).setHmacKeyFormat(HmacKeyFormat.newBuilder().setParams(getHmacProtoParams(parameters)).setKeySize(parameters.getHmacKeySizeBytes()).build()).build().toByteString()).setOutputPrefixType(toProtoOutputPrefixType(parameters.getVariant())).build());
    }
    
    private static ProtoKeySerialization serializeKey(final AesCtrHmacAeadKey key, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        return ProtoKeySerialization.create("type.googleapis.com/google.crypto.tink.AesCtrHmacAeadKey", com.google.crypto.tink.proto.AesCtrHmacAeadKey.newBuilder().setAesCtrKey(AesCtrKey.newBuilder().setParams(AesCtrParams.newBuilder().setIvSize(key.getParameters().getIvSizeBytes()).build()).setKeyValue(ByteString.copyFrom(key.getAesKeyBytes().toByteArray(SecretKeyAccess.requireAccess(access)))).build()).setHmacKey(HmacKey.newBuilder().setParams(getHmacProtoParams(key.getParameters())).setKeyValue(ByteString.copyFrom(key.getHmacKeyBytes().toByteArray(SecretKeyAccess.requireAccess(access)))).build()).build().toByteString(), KeyData.KeyMaterialType.SYMMETRIC, toProtoOutputPrefixType(key.getParameters().getVariant()), key.getIdRequirementOrNull());
    }
    
    private static AesCtrHmacAeadParameters parseParameters(final ProtoParametersSerialization serialization) throws GeneralSecurityException {
        if (!serialization.getKeyTemplate().getTypeUrl().equals("type.googleapis.com/google.crypto.tink.AesCtrHmacAeadKey")) {
            throw new IllegalArgumentException("Wrong type URL in call to AesCtrHmacAeadProtoSerialization.parseParameters: " + serialization.getKeyTemplate().getTypeUrl());
        }
        AesCtrHmacAeadKeyFormat format;
        try {
            format = AesCtrHmacAeadKeyFormat.parseFrom(serialization.getKeyTemplate().getValue(), ExtensionRegistryLite.getEmptyRegistry());
        }
        catch (final InvalidProtocolBufferException e) {
            throw new GeneralSecurityException("Parsing AesCtrHmacAeadParameters failed: ", e);
        }
        if (format.getHmacKeyFormat().getVersion() != 0) {
            throw new GeneralSecurityException("Only version 0 keys are accepted");
        }
        return AesCtrHmacAeadParameters.builder().setAesKeySizeBytes(format.getAesCtrKeyFormat().getKeySize()).setHmacKeySizeBytes(format.getHmacKeyFormat().getKeySize()).setIvSizeBytes(format.getAesCtrKeyFormat().getParams().getIvSize()).setTagSizeBytes(format.getHmacKeyFormat().getParams().getTagSize()).setHashType(toHashType(format.getHmacKeyFormat().getParams().getHash())).setVariant(toVariant(serialization.getKeyTemplate().getOutputPrefixType())).build();
    }
    
    private static AesCtrHmacAeadKey parseKey(final ProtoKeySerialization serialization, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        if (!serialization.getTypeUrl().equals("type.googleapis.com/google.crypto.tink.AesCtrHmacAeadKey")) {
            throw new IllegalArgumentException("Wrong type URL in call to AesCtrHmacAeadProtoSerialization.parseKey");
        }
        try {
            final com.google.crypto.tink.proto.AesCtrHmacAeadKey protoKey = com.google.crypto.tink.proto.AesCtrHmacAeadKey.parseFrom(serialization.getValue(), ExtensionRegistryLite.getEmptyRegistry());
            if (protoKey.getVersion() != 0) {
                throw new GeneralSecurityException("Only version 0 keys are accepted");
            }
            if (protoKey.getAesCtrKey().getVersion() != 0) {
                throw new GeneralSecurityException("Only version 0 keys inner AES CTR keys are accepted");
            }
            if (protoKey.getHmacKey().getVersion() != 0) {
                throw new GeneralSecurityException("Only version 0 keys inner HMAC keys are accepted");
            }
            final AesCtrHmacAeadParameters parameters = AesCtrHmacAeadParameters.builder().setAesKeySizeBytes(protoKey.getAesCtrKey().getKeyValue().size()).setHmacKeySizeBytes(protoKey.getHmacKey().getKeyValue().size()).setIvSizeBytes(protoKey.getAesCtrKey().getParams().getIvSize()).setTagSizeBytes(protoKey.getHmacKey().getParams().getTagSize()).setHashType(toHashType(protoKey.getHmacKey().getParams().getHash())).setVariant(toVariant(serialization.getOutputPrefixType())).build();
            return AesCtrHmacAeadKey.builder().setParameters(parameters).setAesKeyBytes(SecretBytes.copyFrom(protoKey.getAesCtrKey().getKeyValue().toByteArray(), SecretKeyAccess.requireAccess(access))).setHmacKeyBytes(SecretBytes.copyFrom(protoKey.getHmacKey().getKeyValue().toByteArray(), SecretKeyAccess.requireAccess(access))).setIdRequirement(serialization.getIdRequirementOrNull()).build();
        }
        catch (final InvalidProtocolBufferException e) {
            throw new GeneralSecurityException("Parsing AesCtrHmacAeadKey failed");
        }
    }
    
    public static void register() throws GeneralSecurityException {
        register(MutableSerializationRegistry.globalInstance());
    }
    
    public static void register(final MutableSerializationRegistry registry) throws GeneralSecurityException {
        registry.registerParametersSerializer(AesCtrHmacAeadProtoSerialization.PARAMETERS_SERIALIZER);
        registry.registerParametersParser(AesCtrHmacAeadProtoSerialization.PARAMETERS_PARSER);
        registry.registerKeySerializer(AesCtrHmacAeadProtoSerialization.KEY_SERIALIZER);
        registry.registerKeyParser(AesCtrHmacAeadProtoSerialization.KEY_PARSER);
    }
    
    private AesCtrHmacAeadProtoSerialization() {
    }
    
    static {
        TYPE_URL_BYTES = Util.toBytesFromPrintableAscii("type.googleapis.com/google.crypto.tink.AesCtrHmacAeadKey");
        PARAMETERS_SERIALIZER = ParametersSerializer.create(AesCtrHmacAeadProtoSerialization::serializeParameters, AesCtrHmacAeadParameters.class, ProtoParametersSerialization.class);
        PARAMETERS_PARSER = ParametersParser.create(AesCtrHmacAeadProtoSerialization::parseParameters, AesCtrHmacAeadProtoSerialization.TYPE_URL_BYTES, ProtoParametersSerialization.class);
        KEY_SERIALIZER = KeySerializer.create(AesCtrHmacAeadProtoSerialization::serializeKey, AesCtrHmacAeadKey.class, ProtoKeySerialization.class);
        KEY_PARSER = KeyParser.create(AesCtrHmacAeadProtoSerialization::parseKey, AesCtrHmacAeadProtoSerialization.TYPE_URL_BYTES, ProtoKeySerialization.class);
    }
}
