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

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

import com.google.crypto.tink.internal.Util;
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 javax.annotation.Nullable;
import com.google.crypto.tink.SecretKeyAccess;
import com.google.crypto.tink.proto.SlhDsaKeyFormat;
import com.google.crypto.tink.proto.KeyTemplate;
import com.google.protobuf.ByteString;
import com.google.crypto.tink.proto.SlhDsaParams;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.internal.MutableSerializationRegistry;
import com.google.crypto.tink.proto.SlhDsaSignatureType;
import com.google.crypto.tink.proto.SlhDsaHashType;
import com.google.crypto.tink.proto.OutputPrefixType;
import com.google.crypto.tink.internal.EnumTypeProtoConverter;
import com.google.crypto.tink.signature.SlhDsaPrivateKey;
import com.google.crypto.tink.internal.KeyParser;
import com.google.crypto.tink.internal.ProtoKeySerialization;
import com.google.crypto.tink.signature.SlhDsaPublicKey;
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.signature.SlhDsaParameters;
import com.google.crypto.tink.internal.ParametersSerializer;
import com.google.crypto.tink.util.Bytes;
import com.google.crypto.tink.AccessesPartialKey;

@AccessesPartialKey
public final class SlhDsaProtoSerialization
{
    private static final String PRIVATE_TYPE_URL = "type.googleapis.com/google.crypto.tink.SlhDsaPrivateKey";
    private static final Bytes PRIVATE_TYPE_URL_BYTES;
    private static final String PUBLIC_TYPE_URL = "type.googleapis.com/google.crypto.tink.SlhDsaPublicKey";
    private static final Bytes PUBLIC_TYPE_URL_BYTES;
    private static final ParametersSerializer<SlhDsaParameters, ProtoParametersSerialization> PARAMETERS_SERIALIZER;
    private static final ParametersParser<ProtoParametersSerialization> PARAMETERS_PARSER;
    private static final KeySerializer<SlhDsaPublicKey, ProtoKeySerialization> PUBLIC_KEY_SERIALIZER;
    private static final KeyParser<ProtoKeySerialization> PUBLIC_KEY_PARSER;
    private static final KeySerializer<SlhDsaPrivateKey, ProtoKeySerialization> PRIVATE_KEY_SERIALIZER;
    private static final KeyParser<ProtoKeySerialization> PRIVATE_KEY_PARSER;
    private static final EnumTypeProtoConverter<OutputPrefixType, SlhDsaParameters.Variant> VARIANT_CONVERTER;
    private static final EnumTypeProtoConverter<SlhDsaHashType, SlhDsaParameters.HashType> HASH_TYPE_CONVERTER;
    private static final EnumTypeProtoConverter<SlhDsaSignatureType, SlhDsaParameters.SignatureType> SIGNATURE_TYPE_CONVERTER;
    
    public static void register() throws GeneralSecurityException {
        register(MutableSerializationRegistry.globalInstance());
    }
    
    public static void register(final MutableSerializationRegistry registry) throws GeneralSecurityException {
        registry.registerParametersSerializer(SlhDsaProtoSerialization.PARAMETERS_SERIALIZER);
        registry.registerParametersParser(SlhDsaProtoSerialization.PARAMETERS_PARSER);
        registry.registerKeySerializer(SlhDsaProtoSerialization.PUBLIC_KEY_SERIALIZER);
        registry.registerKeyParser(SlhDsaProtoSerialization.PUBLIC_KEY_PARSER);
        registry.registerKeySerializer(SlhDsaProtoSerialization.PRIVATE_KEY_SERIALIZER);
        registry.registerKeyParser(SlhDsaProtoSerialization.PRIVATE_KEY_PARSER);
    }
    
    private static SlhDsaParams getProtoParams(final SlhDsaParameters parameters) throws GeneralSecurityException {
        return SlhDsaParams.newBuilder().setKeySize(parameters.getPrivateKeySize()).setHashType(SlhDsaProtoSerialization.HASH_TYPE_CONVERTER.toProtoEnum(parameters.getHashType())).setSigType(SlhDsaProtoSerialization.SIGNATURE_TYPE_CONVERTER.toProtoEnum(parameters.getSignatureType())).build();
    }
    
    private static com.google.crypto.tink.proto.SlhDsaPublicKey getProtoPublicKey(final SlhDsaPublicKey key) throws GeneralSecurityException {
        return com.google.crypto.tink.proto.SlhDsaPublicKey.newBuilder().setVersion(0).setParams(getProtoParams(key.getParameters())).setKeyValue(ByteString.copyFrom(key.getSerializedPublicKey().toByteArray())).build();
    }
    
    private static ProtoParametersSerialization serializeParameters(final SlhDsaParameters parameters) throws GeneralSecurityException {
        return ProtoParametersSerialization.create(KeyTemplate.newBuilder().setTypeUrl("type.googleapis.com/google.crypto.tink.SlhDsaPrivateKey").setValue(SlhDsaKeyFormat.newBuilder().setParams(getProtoParams(parameters)).setVersion(0).build().toByteString()).setOutputPrefixType(SlhDsaProtoSerialization.VARIANT_CONVERTER.toProtoEnum(parameters.getVariant())).build());
    }
    
    private static ProtoKeySerialization serializePublicKey(final SlhDsaPublicKey key, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        return ProtoKeySerialization.create("type.googleapis.com/google.crypto.tink.SlhDsaPublicKey", getProtoPublicKey(key).toByteString(), KeyData.KeyMaterialType.ASYMMETRIC_PUBLIC, SlhDsaProtoSerialization.VARIANT_CONVERTER.toProtoEnum(key.getParameters().getVariant()), key.getIdRequirementOrNull());
    }
    
    private static ProtoKeySerialization serializePrivateKey(final SlhDsaPrivateKey key, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        return ProtoKeySerialization.create("type.googleapis.com/google.crypto.tink.SlhDsaPrivateKey", com.google.crypto.tink.proto.SlhDsaPrivateKey.newBuilder().setVersion(0).setPublicKey(getProtoPublicKey(key.getPublicKey())).setKeyValue(ByteString.copyFrom(key.getPrivateKeyBytes().toByteArray(SecretKeyAccess.requireAccess(access)))).build().toByteString(), KeyData.KeyMaterialType.ASYMMETRIC_PRIVATE, SlhDsaProtoSerialization.VARIANT_CONVERTER.toProtoEnum(key.getParameters().getVariant()), key.getIdRequirementOrNull());
    }
    
    private static SlhDsaParameters parseParameters(final ProtoParametersSerialization serialization) throws GeneralSecurityException {
        if (!serialization.getKeyTemplate().getTypeUrl().equals("type.googleapis.com/google.crypto.tink.SlhDsaPrivateKey")) {
            throw new IllegalArgumentException("Wrong type URL in call to SlhDsaProtoSerialization.parseParameters: " + serialization.getKeyTemplate().getTypeUrl());
        }
        SlhDsaKeyFormat format;
        try {
            format = SlhDsaKeyFormat.parseFrom(serialization.getKeyTemplate().getValue(), ExtensionRegistryLite.getEmptyRegistry());
        }
        catch (final InvalidProtocolBufferException e) {
            throw new GeneralSecurityException("Parsing SlhDsaParameters failed: ", e);
        }
        if (format.getVersion() != 0) {
            throw new GeneralSecurityException("Only version 0 keys are accepted for SLH-DSA.");
        }
        return validateAndConvertToSlhDsaParameters(format.getParams(), SlhDsaProtoSerialization.VARIANT_CONVERTER.fromProtoEnum(serialization.getKeyTemplate().getOutputPrefixType()));
    }
    
    private static SlhDsaParameters validateAndConvertToSlhDsaParameters(final SlhDsaParams params, final SlhDsaParameters.Variant variant) throws GeneralSecurityException {
        if (params.getKeySize() != 64 || params.getHashType() != SlhDsaHashType.SHA2 || params.getSigType() != SlhDsaSignatureType.SMALL_SIGNATURE) {
            throw new GeneralSecurityException("Unsupported SLH-DSA parameters");
        }
        return SlhDsaParameters.createSlhDsaWithSha2And128S(variant);
    }
    
    private static SlhDsaPublicKey parsePublicKey(final ProtoKeySerialization serialization, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        if (!serialization.getTypeUrl().equals("type.googleapis.com/google.crypto.tink.SlhDsaPublicKey")) {
            throw new IllegalArgumentException("Wrong type URL in call to SlhDsaProtoSerialization.parsePublicKey: " + serialization.getTypeUrl());
        }
        if (serialization.getKeyMaterialType() != KeyData.KeyMaterialType.ASYMMETRIC_PUBLIC) {
            throw new GeneralSecurityException("Wrong KeyMaterialType for SlhDsaPublicKey: " + serialization.getKeyMaterialType().name());
        }
        try {
            return convertToSlhDsaPublicKey(serialization, com.google.crypto.tink.proto.SlhDsaPublicKey.parseFrom(serialization.getValue(), ExtensionRegistryLite.getEmptyRegistry()));
        }
        catch (final InvalidProtocolBufferException e) {
            throw new GeneralSecurityException("Parsing SlhDsaPublicKey failed");
        }
    }
    
    private static SlhDsaPublicKey convertToSlhDsaPublicKey(final ProtoKeySerialization serialization, final com.google.crypto.tink.proto.SlhDsaPublicKey protoKey) throws GeneralSecurityException {
        if (protoKey.getVersion() != 0) {
            throw new GeneralSecurityException("Only version 0 keys are accepted");
        }
        final SlhDsaParameters parameters = validateAndConvertToSlhDsaParameters(protoKey.getParams(), SlhDsaProtoSerialization.VARIANT_CONVERTER.fromProtoEnum(serialization.getOutputPrefixType()));
        final SlhDsaPublicKey.Builder builder = SlhDsaPublicKey.builder().setParameters(parameters).setSerializedPublicKey(Bytes.copyFrom(protoKey.getKeyValue().toByteArray()));
        if (serialization.getIdRequirementOrNull() != null) {
            builder.setIdRequirement(serialization.getIdRequirementOrNull());
        }
        return builder.build();
    }
    
    private static SlhDsaPrivateKey parsePrivateKey(final ProtoKeySerialization serialization, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        if (!serialization.getTypeUrl().equals("type.googleapis.com/google.crypto.tink.SlhDsaPrivateKey")) {
            throw new IllegalArgumentException("Wrong type URL in call to SlhDsaProtoSerialization.parsePrivateKey: " + serialization.getTypeUrl());
        }
        if (serialization.getKeyMaterialType() != KeyData.KeyMaterialType.ASYMMETRIC_PRIVATE) {
            throw new GeneralSecurityException("Wrong KeyMaterialType for SlhDsaPrivateKey: " + serialization.getKeyMaterialType().name());
        }
        try {
            final com.google.crypto.tink.proto.SlhDsaPrivateKey protoKey = com.google.crypto.tink.proto.SlhDsaPrivateKey.parseFrom(serialization.getValue(), ExtensionRegistryLite.getEmptyRegistry());
            if (protoKey.getVersion() != 0) {
                throw new GeneralSecurityException("Only version 0 keys are accepted");
            }
            final SlhDsaPublicKey publicKey = convertToSlhDsaPublicKey(serialization, protoKey.getPublicKey());
            return SlhDsaPrivateKey.createWithoutVerification(publicKey, SecretBytes.copyFrom(protoKey.getKeyValue().toByteArray(), SecretKeyAccess.requireAccess(access)));
        }
        catch (final InvalidProtocolBufferException e) {
            throw new GeneralSecurityException("Parsing SlhDsaPrivateKey failed");
        }
    }
    
    private SlhDsaProtoSerialization() {
    }
    
    static {
        PRIVATE_TYPE_URL_BYTES = Util.toBytesFromPrintableAscii("type.googleapis.com/google.crypto.tink.SlhDsaPrivateKey");
        PUBLIC_TYPE_URL_BYTES = Util.toBytesFromPrintableAscii("type.googleapis.com/google.crypto.tink.SlhDsaPublicKey");
        PARAMETERS_SERIALIZER = ParametersSerializer.create(SlhDsaProtoSerialization::serializeParameters, SlhDsaParameters.class, ProtoParametersSerialization.class);
        PARAMETERS_PARSER = ParametersParser.create(SlhDsaProtoSerialization::parseParameters, SlhDsaProtoSerialization.PRIVATE_TYPE_URL_BYTES, ProtoParametersSerialization.class);
        PUBLIC_KEY_SERIALIZER = KeySerializer.create(SlhDsaProtoSerialization::serializePublicKey, SlhDsaPublicKey.class, ProtoKeySerialization.class);
        PUBLIC_KEY_PARSER = KeyParser.create(SlhDsaProtoSerialization::parsePublicKey, SlhDsaProtoSerialization.PUBLIC_TYPE_URL_BYTES, ProtoKeySerialization.class);
        PRIVATE_KEY_SERIALIZER = KeySerializer.create(SlhDsaProtoSerialization::serializePrivateKey, SlhDsaPrivateKey.class, ProtoKeySerialization.class);
        PRIVATE_KEY_PARSER = KeyParser.create(SlhDsaProtoSerialization::parsePrivateKey, SlhDsaProtoSerialization.PRIVATE_TYPE_URL_BYTES, ProtoKeySerialization.class);
        VARIANT_CONVERTER = EnumTypeProtoConverter.builder().add(OutputPrefixType.RAW, SlhDsaParameters.Variant.NO_PREFIX).add(OutputPrefixType.TINK, SlhDsaParameters.Variant.TINK).build();
        HASH_TYPE_CONVERTER = EnumTypeProtoConverter.builder().add(SlhDsaHashType.SHA2, SlhDsaParameters.HashType.SHA2).add(SlhDsaHashType.SHAKE, SlhDsaParameters.HashType.SHAKE).build();
        SIGNATURE_TYPE_CONVERTER = EnumTypeProtoConverter.builder().add(SlhDsaSignatureType.FAST_SIGNING, SlhDsaParameters.SignatureType.FAST_SIGNING).add(SlhDsaSignatureType.SMALL_SIGNATURE, SlhDsaParameters.SignatureType.SMALL_SIGNATURE).build();
    }
}
