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

package com.google.crypto.tink.daead.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.protobuf.ByteString;
import javax.annotation.Nullable;
import com.google.crypto.tink.SecretKeyAccess;
import com.google.crypto.tink.proto.AesSivKeyFormat;
import com.google.crypto.tink.proto.KeyTemplate;
import java.security.GeneralSecurityException;
import java.util.EnumMap;
import java.util.Collections;
import java.util.HashMap;
import com.google.crypto.tink.proto.OutputPrefixType;
import java.util.Map;
import com.google.crypto.tink.internal.KeyParser;
import com.google.crypto.tink.internal.ProtoKeySerialization;
import com.google.crypto.tink.daead.AesSivKey;
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.daead.AesSivParameters;
import com.google.crypto.tink.internal.ParametersSerializer;
import com.google.crypto.tink.util.Bytes;
import com.google.crypto.tink.AccessesPartialKey;

@AccessesPartialKey
public final class AesSivProtoSerialization
{
    private static final String TYPE_URL = "type.googleapis.com/google.crypto.tink.AesSivKey";
    private static final Bytes TYPE_URL_BYTES;
    private static final ParametersSerializer<AesSivParameters, ProtoParametersSerialization> PARAMETERS_SERIALIZER;
    private static final ParametersParser<ProtoParametersSerialization> PARAMETERS_PARSER;
    private static final KeySerializer<AesSivKey, ProtoKeySerialization> KEY_SERIALIZER;
    private static final KeyParser<ProtoKeySerialization> KEY_PARSER;
    private static final Map<AesSivParameters.Variant, OutputPrefixType> variantsToOutputPrefixMap;
    private static final Map<OutputPrefixType, AesSivParameters.Variant> outputPrefixToVariantMap;
    
    private static Map<AesSivParameters.Variant, OutputPrefixType> createVariantToOutputPrefixMap() {
        final Map<AesSivParameters.Variant, OutputPrefixType> result = new HashMap<AesSivParameters.Variant, OutputPrefixType>();
        result.put(AesSivParameters.Variant.NO_PREFIX, OutputPrefixType.RAW);
        result.put(AesSivParameters.Variant.TINK, OutputPrefixType.TINK);
        result.put(AesSivParameters.Variant.CRUNCHY, OutputPrefixType.CRUNCHY);
        return Collections.unmodifiableMap((Map<? extends AesSivParameters.Variant, ? extends OutputPrefixType>)result);
    }
    
    private static Map<OutputPrefixType, AesSivParameters.Variant> createOutputPrefixToVariantMap() {
        final Map<OutputPrefixType, AesSivParameters.Variant> result = new EnumMap<OutputPrefixType, AesSivParameters.Variant>(OutputPrefixType.class);
        result.put(OutputPrefixType.RAW, AesSivParameters.Variant.NO_PREFIX);
        result.put(OutputPrefixType.TINK, AesSivParameters.Variant.TINK);
        result.put(OutputPrefixType.CRUNCHY, AesSivParameters.Variant.CRUNCHY);
        result.put(OutputPrefixType.LEGACY, AesSivParameters.Variant.CRUNCHY);
        return Collections.unmodifiableMap((Map<? extends OutputPrefixType, ? extends AesSivParameters.Variant>)result);
    }
    
    private static OutputPrefixType toProtoOutputPrefixType(final AesSivParameters.Variant variant) throws GeneralSecurityException {
        if (AesSivProtoSerialization.variantsToOutputPrefixMap.containsKey(variant)) {
            return AesSivProtoSerialization.variantsToOutputPrefixMap.get(variant);
        }
        throw new GeneralSecurityException("Unable to serialize variant: " + variant);
    }
    
    private static AesSivParameters.Variant toVariant(final OutputPrefixType outputPrefixType) throws GeneralSecurityException {
        if (AesSivProtoSerialization.outputPrefixToVariantMap.containsKey(outputPrefixType)) {
            return AesSivProtoSerialization.outputPrefixToVariantMap.get(outputPrefixType);
        }
        throw new GeneralSecurityException("Unable to parse OutputPrefixType: " + outputPrefixType.getNumber());
    }
    
    private static ProtoParametersSerialization serializeParameters(final AesSivParameters parameters) throws GeneralSecurityException {
        return ProtoParametersSerialization.create(KeyTemplate.newBuilder().setTypeUrl("type.googleapis.com/google.crypto.tink.AesSivKey").setValue(AesSivKeyFormat.newBuilder().setKeySize(parameters.getKeySizeBytes()).build().toByteString()).setOutputPrefixType(toProtoOutputPrefixType(parameters.getVariant())).build());
    }
    
    private static ProtoKeySerialization serializeKey(final AesSivKey key, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        return ProtoKeySerialization.create("type.googleapis.com/google.crypto.tink.AesSivKey", com.google.crypto.tink.proto.AesSivKey.newBuilder().setKeyValue(ByteString.copyFrom(key.getKeyBytes().toByteArray(SecretKeyAccess.requireAccess(access)))).build().toByteString(), KeyData.KeyMaterialType.SYMMETRIC, toProtoOutputPrefixType(key.getParameters().getVariant()), key.getIdRequirementOrNull());
    }
    
    private static AesSivParameters parseParameters(final ProtoParametersSerialization serialization) throws GeneralSecurityException {
        if (!serialization.getKeyTemplate().getTypeUrl().equals("type.googleapis.com/google.crypto.tink.AesSivKey")) {
            throw new IllegalArgumentException("Wrong type URL in call to AesSivParameters.parseParameters: " + serialization.getKeyTemplate().getTypeUrl());
        }
        AesSivKeyFormat format;
        try {
            format = AesSivKeyFormat.parseFrom(serialization.getKeyTemplate().getValue(), ExtensionRegistryLite.getEmptyRegistry());
            if (format.getVersion() != 0) {
                throw new GeneralSecurityException("Only version 0 keys are accepted");
            }
        }
        catch (final InvalidProtocolBufferException e) {
            throw new GeneralSecurityException("Parsing AesSivParameters failed: ", e);
        }
        return AesSivParameters.builder().setKeySizeBytes(format.getKeySize()).setVariant(toVariant(serialization.getKeyTemplate().getOutputPrefixType())).build();
    }
    
    private static AesSivKey parseKey(final ProtoKeySerialization serialization, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        if (!serialization.getTypeUrl().equals("type.googleapis.com/google.crypto.tink.AesSivKey")) {
            throw new IllegalArgumentException("Wrong type URL in call to AesSivParameters.parseParameters");
        }
        try {
            final com.google.crypto.tink.proto.AesSivKey protoKey = com.google.crypto.tink.proto.AesSivKey.parseFrom(serialization.getValue(), ExtensionRegistryLite.getEmptyRegistry());
            if (protoKey.getVersion() != 0) {
                throw new GeneralSecurityException("Only version 0 keys are accepted");
            }
            final AesSivParameters parameters = AesSivParameters.builder().setKeySizeBytes(protoKey.getKeyValue().size()).setVariant(toVariant(serialization.getOutputPrefixType())).build();
            return AesSivKey.builder().setParameters(parameters).setKeyBytes(SecretBytes.copyFrom(protoKey.getKeyValue().toByteArray(), SecretKeyAccess.requireAccess(access))).setIdRequirement(serialization.getIdRequirementOrNull()).build();
        }
        catch (final InvalidProtocolBufferException e) {
            throw new GeneralSecurityException("Parsing AesSivKey failed");
        }
    }
    
    public static void register() throws GeneralSecurityException {
        register(MutableSerializationRegistry.globalInstance());
    }
    
    public static void register(final MutableSerializationRegistry registry) throws GeneralSecurityException {
        registry.registerParametersSerializer(AesSivProtoSerialization.PARAMETERS_SERIALIZER);
        registry.registerParametersParser(AesSivProtoSerialization.PARAMETERS_PARSER);
        registry.registerKeySerializer(AesSivProtoSerialization.KEY_SERIALIZER);
        registry.registerKeyParser(AesSivProtoSerialization.KEY_PARSER);
    }
    
    private AesSivProtoSerialization() {
    }
    
    static {
        TYPE_URL_BYTES = Util.toBytesFromPrintableAscii("type.googleapis.com/google.crypto.tink.AesSivKey");
        PARAMETERS_SERIALIZER = ParametersSerializer.create(AesSivProtoSerialization::serializeParameters, AesSivParameters.class, ProtoParametersSerialization.class);
        PARAMETERS_PARSER = ParametersParser.create(AesSivProtoSerialization::parseParameters, AesSivProtoSerialization.TYPE_URL_BYTES, ProtoParametersSerialization.class);
        KEY_SERIALIZER = KeySerializer.create(AesSivProtoSerialization::serializeKey, AesSivKey.class, ProtoKeySerialization.class);
        KEY_PARSER = KeyParser.create(AesSivProtoSerialization::parseKey, AesSivProtoSerialization.TYPE_URL_BYTES, ProtoKeySerialization.class);
        variantsToOutputPrefixMap = createVariantToOutputPrefixMap();
        outputPrefixToVariantMap = createOutputPrefixToVariantMap();
    }
}
