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

package com.google.crypto.tink.aead;

import com.google.protobuf.MessageLite;
import com.google.protobuf.Parser;
import com.google.crypto.tink.internal.LegacyKeyManagerImpl;
import com.google.crypto.tink.proto.KeyData;
import com.google.crypto.tink.internal.TinkBugException;
import com.google.crypto.tink.KeyTemplate;
import com.google.crypto.tink.internal.KeyManagerRegistry;
import com.google.crypto.tink.internal.MutableKeyCreationRegistry;
import com.google.crypto.tink.internal.MutableParametersRegistry;
import com.google.crypto.tink.internal.MutablePrimitiveRegistry;
import com.google.crypto.tink.aead.internal.XChaCha20Poly1305ProtoSerialization;
import com.google.crypto.tink.config.internal.TinkFipsUtil;
import java.util.Collections;
import java.util.HashMap;
import com.google.crypto.tink.Parameters;
import java.util.Map;
import com.google.crypto.tink.util.SecretBytes;
import com.google.crypto.tink.AccessesPartialKey;
import com.google.crypto.tink.internal.Util;
import com.google.crypto.tink.SecretKeyAccess;
import javax.annotation.Nullable;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.subtle.XChaCha20Poly1305;
import com.google.crypto.tink.aead.internal.XChaCha20Poly1305Jce;
import com.google.crypto.tink.internal.KeyCreator;
import com.google.crypto.tink.internal.MutableKeyDerivationRegistry;
import com.google.crypto.tink.KeyManager;
import com.google.crypto.tink.Aead;
import com.google.crypto.tink.internal.PrimitiveConstructor;

public final class XChaCha20Poly1305KeyManager
{
    private static final PrimitiveConstructor<XChaCha20Poly1305Key, Aead> X_CHA_CHA_20_POLY_1305_PRIMITIVE_CONSTRUCTOR;
    private static final int KEY_SIZE_IN_BYTES = 32;
    private static final KeyManager<Aead> legacyKeyManager;
    private static final MutableKeyDerivationRegistry.InsecureKeyCreator<XChaCha20Poly1305Parameters> KEY_DERIVER;
    private static final KeyCreator<XChaCha20Poly1305Parameters> KEY_CREATOR;
    
    private static Aead createAead(final XChaCha20Poly1305Key key) throws GeneralSecurityException {
        if (XChaCha20Poly1305Jce.isSupported()) {
            return XChaCha20Poly1305Jce.create(key);
        }
        return XChaCha20Poly1305.create(key);
    }
    
    static String getKeyType() {
        return "type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key";
    }
    
    @AccessesPartialKey
    static XChaCha20Poly1305Key createXChaChaKeyFromRandomness(final XChaCha20Poly1305Parameters parameters, final InputStream stream, @Nullable final Integer idRequirement, final SecretKeyAccess access) throws GeneralSecurityException {
        return XChaCha20Poly1305Key.create(parameters.getVariant(), Util.readIntoSecretBytes(stream, 32, access), idRequirement);
    }
    
    @AccessesPartialKey
    static XChaCha20Poly1305Key createXChaChaKey(final XChaCha20Poly1305Parameters parameters, @Nullable final Integer idRequirement) throws GeneralSecurityException {
        return XChaCha20Poly1305Key.create(parameters.getVariant(), SecretBytes.randomBytes(32), idRequirement);
    }
    
    private static Map<String, Parameters> namedParameters() throws GeneralSecurityException {
        final Map<String, Parameters> result = new HashMap<String, Parameters>();
        result.put("XCHACHA20_POLY1305", XChaCha20Poly1305Parameters.create(XChaCha20Poly1305Parameters.Variant.TINK));
        result.put("XCHACHA20_POLY1305_RAW", XChaCha20Poly1305Parameters.create(XChaCha20Poly1305Parameters.Variant.NO_PREFIX));
        return Collections.unmodifiableMap((Map<? extends String, ? extends Parameters>)result);
    }
    
    public static void register(final boolean newKeyAllowed) throws GeneralSecurityException {
        if (!TinkFipsUtil.AlgorithmFipsCompatibility.ALGORITHM_NOT_FIPS.isCompatible()) {
            throw new GeneralSecurityException("Registering XChaCha20Poly1305 is not supported in FIPS mode");
        }
        XChaCha20Poly1305ProtoSerialization.register();
        MutablePrimitiveRegistry.globalInstance().registerPrimitiveConstructor(XChaCha20Poly1305KeyManager.X_CHA_CHA_20_POLY_1305_PRIMITIVE_CONSTRUCTOR);
        MutableParametersRegistry.globalInstance().putAll(namedParameters());
        MutableKeyCreationRegistry.globalInstance().add(XChaCha20Poly1305KeyManager.KEY_CREATOR, XChaCha20Poly1305Parameters.class);
        MutableKeyDerivationRegistry.globalInstance().add(XChaCha20Poly1305KeyManager.KEY_DERIVER, XChaCha20Poly1305Parameters.class);
        KeyManagerRegistry.globalInstance().registerKeyManager(XChaCha20Poly1305KeyManager.legacyKeyManager, newKeyAllowed);
    }
    
    public static final KeyTemplate xChaCha20Poly1305Template() {
        return TinkBugException.exceptionIsBug(() -> KeyTemplate.createFrom(XChaCha20Poly1305Parameters.create(XChaCha20Poly1305Parameters.Variant.TINK)));
    }
    
    public static final KeyTemplate rawXChaCha20Poly1305Template() {
        return TinkBugException.exceptionIsBug(() -> KeyTemplate.createFrom(XChaCha20Poly1305Parameters.create(XChaCha20Poly1305Parameters.Variant.NO_PREFIX)));
    }
    
    private XChaCha20Poly1305KeyManager() {
    }
    
    static {
        X_CHA_CHA_20_POLY_1305_PRIMITIVE_CONSTRUCTOR = PrimitiveConstructor.create(XChaCha20Poly1305KeyManager::createAead, XChaCha20Poly1305Key.class, Aead.class);
        legacyKeyManager = LegacyKeyManagerImpl.create(getKeyType(), Aead.class, KeyData.KeyMaterialType.SYMMETRIC, com.google.crypto.tink.proto.XChaCha20Poly1305Key.parser());
        KEY_DERIVER = XChaCha20Poly1305KeyManager::createXChaChaKeyFromRandomness;
        KEY_CREATOR = XChaCha20Poly1305KeyManager::createXChaChaKey;
    }
}
