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

package com.google.crypto.tink.signature;

import com.google.crypto.tink.internal.MutableKeyCreationRegistry;
import com.google.crypto.tink.internal.MutableParametersRegistry;
import com.google.crypto.tink.signature.internal.MlDsaProtoSerialization;
import com.google.crypto.tink.Parameters;
import java.util.Map;
import com.google.crypto.tink.AccessesPartialKey;
import java.security.KeyPair;
import java.security.Provider;
import com.google.crypto.tink.util.SecretBytes;
import com.google.crypto.tink.InsecureSecretKeyAccess;
import com.google.crypto.tink.util.Bytes;
import java.security.Key;
import com.google.crypto.tink.signature.internal.MlDsaVerifyConscrypt;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.internal.ConscryptUtil;
import javax.annotation.Nullable;
import com.google.crypto.tink.config.internal.TinkFipsUtil;
import com.google.crypto.tink.internal.KeyCreator;

final class MlDsaSignKeyManager
{
    static final String ML_DSA_65_ALGORITHM = "ML-DSA-65";
    private static final KeyCreator<MlDsaParameters> KEY_CREATOR;
    private static final TinkFipsUtil.AlgorithmFipsCompatibility FIPS;
    
    static String getPublicKeyType() {
        return "type.googleapis.com/google.crypto.tink.MlDsaPublicKey";
    }
    
    static String getPrivateKeyType() {
        return "type.googleapis.com/google.crypto.tink.MlDsaPrivateKey";
    }
    
    @AccessesPartialKey
    private static MlDsaPrivateKey createKey(final MlDsaParameters parameters, @Nullable final Integer idRequirement) throws GeneralSecurityException {
        final Provider provider = ConscryptUtil.providerOrNull();
        if (provider == null) {
            throw new GeneralSecurityException("Obtaining Conscrypt provider failed");
        }
        final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ML-DSA-65", provider);
        final KeyPair keyPair = keyPairGenerator.generateKeyPair();
        final KeyFactory keyFactory = KeyFactory.getInstance("ML-DSA-65", provider);
        final MlDsaPublicKey publicKey = MlDsaPublicKey.builder().setSerializedPublicKey(Bytes.copyFrom(keyFactory.getKeySpec(keyPair.getPublic(), MlDsaVerifyConscrypt.RawKeySpec.class).getEncoded())).setParameters(parameters).setIdRequirement(idRequirement).build();
        final SecretBytes privateSeed = SecretBytes.copyFrom(keyFactory.getKeySpec(keyPair.getPrivate(), MlDsaVerifyConscrypt.RawKeySpec.class).getEncoded(), InsecureSecretKeyAccess.get());
        return MlDsaPrivateKey.createWithoutVerification(publicKey, privateSeed);
    }
    
    private static Map<String, Parameters> namedParameters() throws GeneralSecurityException {
        return (Map<String, Parameters>)Map.of("ML_DSA_65", MlDsaParameters.create(MlDsaParameters.MlDsaInstance.ML_DSA_65, MlDsaParameters.Variant.TINK), "ML_DSA_65_RAW", MlDsaParameters.create(MlDsaParameters.MlDsaInstance.ML_DSA_65, MlDsaParameters.Variant.NO_PREFIX));
    }
    
    public static void registerPair() throws GeneralSecurityException {
        if (!MlDsaSignKeyManager.FIPS.isCompatible()) {
            throw new GeneralSecurityException("Cannot use ML-DSA in FIPS-mode, as it is not yet certified in Conscrypt.");
        }
        if (ConscryptUtil.providerOrNull() == null) {
            throw new GeneralSecurityException("Cannot use ML-DSA without Conscrypt provider");
        }
        MlDsaProtoSerialization.register();
        MutableParametersRegistry.globalInstance().putAll(namedParameters());
        MutableKeyCreationRegistry.globalInstance().add(MlDsaSignKeyManager.KEY_CREATOR, MlDsaParameters.class);
    }
    
    private MlDsaSignKeyManager() {
    }
    
    static {
        KEY_CREATOR = MlDsaSignKeyManager::createKey;
        FIPS = TinkFipsUtil.AlgorithmFipsCompatibility.ALGORITHM_NOT_FIPS;
    }
}
