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

package com.google.crypto.tink.streamingaead.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.OutputPrefixType;
import com.google.crypto.tink.proto.AesCtrHmacStreamingKeyFormat;
import com.google.crypto.tink.proto.KeyTemplate;
import com.google.crypto.tink.proto.HmacParams;
import com.google.crypto.tink.proto.AesCtrHmacStreamingParams;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.proto.HashType;
import com.google.crypto.tink.internal.KeyParser;
import com.google.crypto.tink.internal.ProtoKeySerialization;
import com.google.crypto.tink.streamingaead.AesCtrHmacStreamingKey;
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.streamingaead.AesCtrHmacStreamingParameters;
import com.google.crypto.tink.internal.ParametersSerializer;
import com.google.crypto.tink.util.Bytes;
import com.google.crypto.tink.AccessesPartialKey;

@AccessesPartialKey
public final class AesCtrHmacStreamingProtoSerialization
{
    private static final String TYPE_URL = "type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey";
    private static final Bytes TYPE_URL_BYTES;
    private static final ParametersSerializer<AesCtrHmacStreamingParameters, ProtoParametersSerialization> PARAMETERS_SERIALIZER;
    private static final ParametersParser<ProtoParametersSerialization> PARAMETERS_PARSER;
    private static final KeySerializer<AesCtrHmacStreamingKey, ProtoKeySerialization> KEY_SERIALIZER;
    private static final KeyParser<ProtoKeySerialization> KEY_PARSER;
    
    private static HashType toProtoHashType(final AesCtrHmacStreamingParameters.HashType hashType) throws GeneralSecurityException {
        if (AesCtrHmacStreamingParameters.HashType.SHA1.equals(hashType)) {
            return HashType.SHA1;
        }
        if (AesCtrHmacStreamingParameters.HashType.SHA256.equals(hashType)) {
            return HashType.SHA256;
        }
        if (AesCtrHmacStreamingParameters.HashType.SHA512.equals(hashType)) {
            return HashType.SHA512;
        }
        throw new GeneralSecurityException("Unable to serialize HashType " + hashType);
    }
    
    private static AesCtrHmacStreamingParameters.HashType toHashType(final HashType hashType) throws GeneralSecurityException {
        switch (hashType) {
            case SHA1: {
                return AesCtrHmacStreamingParameters.HashType.SHA1;
            }
            case SHA256: {
                return AesCtrHmacStreamingParameters.HashType.SHA256;
            }
            case SHA512: {
                return AesCtrHmacStreamingParameters.HashType.SHA512;
            }
            default: {
                throw new GeneralSecurityException("Unable to parse HashType: " + hashType.getNumber());
            }
        }
    }
    
    private static AesCtrHmacStreamingParams toProtoParams(final AesCtrHmacStreamingParameters parameters) throws GeneralSecurityException {
        return AesCtrHmacStreamingParams.newBuilder().setCiphertextSegmentSize(parameters.getCiphertextSegmentSizeBytes()).setDerivedKeySize(parameters.getDerivedKeySizeBytes()).setHkdfHashType(toProtoHashType(parameters.getHkdfHashType())).setHmacParams(HmacParams.newBuilder().setHash(toProtoHashType(parameters.getHmacHashType())).setTagSize(parameters.getHmacTagSizeBytes())).build();
    }
    
    private static ProtoParametersSerialization serializeParameters(final AesCtrHmacStreamingParameters parameters) throws GeneralSecurityException {
        return ProtoParametersSerialization.create(KeyTemplate.newBuilder().setTypeUrl("type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey").setValue(AesCtrHmacStreamingKeyFormat.newBuilder().setKeySize(parameters.getKeySizeBytes()).setParams(toProtoParams(parameters)).build().toByteString()).setOutputPrefixType(OutputPrefixType.RAW).build());
    }
    
    private static ProtoKeySerialization serializeKey(final AesCtrHmacStreamingKey key, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        return ProtoKeySerialization.create("type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey", com.google.crypto.tink.proto.AesCtrHmacStreamingKey.newBuilder().setKeyValue(ByteString.copyFrom(key.getInitialKeyMaterial().toByteArray(SecretKeyAccess.requireAccess(access)))).setParams(toProtoParams(key.getParameters())).build().toByteString(), KeyData.KeyMaterialType.SYMMETRIC, OutputPrefixType.RAW, key.getIdRequirementOrNull());
    }
    
    private static AesCtrHmacStreamingParameters toParametersObject(final AesCtrHmacStreamingParams params, final int keySize) throws GeneralSecurityException {
        return AesCtrHmacStreamingParameters.builder().setKeySizeBytes(keySize).setDerivedKeySizeBytes(params.getDerivedKeySize()).setCiphertextSegmentSizeBytes(params.getCiphertextSegmentSize()).setHkdfHashType(toHashType(params.getHkdfHashType())).setHmacHashType(toHashType(params.getHmacParams().getHash())).setHmacTagSizeBytes(params.getHmacParams().getTagSize()).build();
    }
    
    private static AesCtrHmacStreamingParameters parseParameters(final ProtoParametersSerialization serialization) throws GeneralSecurityException {
        if (!serialization.getKeyTemplate().getTypeUrl().equals("type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey")) {
            throw new IllegalArgumentException("Wrong type URL in call to AesCtrHmacStreamingParameters.parseParameters: " + serialization.getKeyTemplate().getTypeUrl());
        }
        AesCtrHmacStreamingKeyFormat format;
        try {
            format = AesCtrHmacStreamingKeyFormat.parseFrom(serialization.getKeyTemplate().getValue(), ExtensionRegistryLite.getEmptyRegistry());
        }
        catch (final InvalidProtocolBufferException e) {
            throw new GeneralSecurityException("Parsing AesCtrHmacStreamingParameters failed: ", e);
        }
        return toParametersObject(format.getParams(), format.getKeySize());
    }
    
    private static AesCtrHmacStreamingKey parseKey(final ProtoKeySerialization serialization, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        if (!serialization.getTypeUrl().equals("type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey")) {
            throw new IllegalArgumentException("Wrong type URL in call to AesCtrHmacStreamingParameters.parseParameters");
        }
        try {
            final com.google.crypto.tink.proto.AesCtrHmacStreamingKey protoKey = com.google.crypto.tink.proto.AesCtrHmacStreamingKey.parseFrom(serialization.getValue(), ExtensionRegistryLite.getEmptyRegistry());
            if (protoKey.getVersion() != 0) {
                throw new GeneralSecurityException("Only version 0 keys are accepted");
            }
            final AesCtrHmacStreamingParameters parameters = toParametersObject(protoKey.getParams(), protoKey.getKeyValue().size());
            return AesCtrHmacStreamingKey.create(parameters, SecretBytes.copyFrom(protoKey.getKeyValue().toByteArray(), SecretKeyAccess.requireAccess(access)));
        }
        catch (final InvalidProtocolBufferException e) {
            throw new GeneralSecurityException("Parsing AesCtrHmacStreamingKey failed");
        }
    }
    
    public static void register() throws GeneralSecurityException {
        register(MutableSerializationRegistry.globalInstance());
    }
    
    public static void register(final MutableSerializationRegistry registry) throws GeneralSecurityException {
        registry.registerParametersSerializer(AesCtrHmacStreamingProtoSerialization.PARAMETERS_SERIALIZER);
        registry.registerParametersParser(AesCtrHmacStreamingProtoSerialization.PARAMETERS_PARSER);
        registry.registerKeySerializer(AesCtrHmacStreamingProtoSerialization.KEY_SERIALIZER);
        registry.registerKeyParser(AesCtrHmacStreamingProtoSerialization.KEY_PARSER);
    }
    
    private AesCtrHmacStreamingProtoSerialization() {
    }
    
    static {
        TYPE_URL_BYTES = Util.toBytesFromPrintableAscii("type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey");
        PARAMETERS_SERIALIZER = ParametersSerializer.create(AesCtrHmacStreamingProtoSerialization::serializeParameters, AesCtrHmacStreamingParameters.class, ProtoParametersSerialization.class);
        PARAMETERS_PARSER = ParametersParser.create(AesCtrHmacStreamingProtoSerialization::parseParameters, AesCtrHmacStreamingProtoSerialization.TYPE_URL_BYTES, ProtoParametersSerialization.class);
        KEY_SERIALIZER = KeySerializer.create(AesCtrHmacStreamingProtoSerialization::serializeKey, AesCtrHmacStreamingKey.class, ProtoKeySerialization.class);
        KEY_PARSER = KeyParser.create(AesCtrHmacStreamingProtoSerialization::parseKey, AesCtrHmacStreamingProtoSerialization.TYPE_URL_BYTES, ProtoKeySerialization.class);
    }
}
