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

package com.google.crypto.tink;

import com.google.crypto.tink.mac.internal.ChunkedAesCmacImpl;
import com.google.crypto.tink.subtle.PrfAesCmac;
import com.google.crypto.tink.subtle.prf.PrfImpl;
import com.google.crypto.tink.subtle.prf.HkdfStreamingPrf;
import com.google.crypto.tink.prf.HkdfPrfParameters;
import com.google.crypto.tink.subtle.AesSiv;
import com.google.crypto.tink.subtle.XChaCha20Poly1305;
import com.google.crypto.tink.aead.internal.XChaCha20Poly1305Jce;
import com.google.crypto.tink.subtle.ChaCha20Poly1305;
import com.google.crypto.tink.aead.internal.ChaCha20Poly1305Jce;
import com.google.crypto.tink.internal.InternalConfiguration;
import com.google.crypto.tink.signature.RsaSsaPssPublicKey;
import com.google.crypto.tink.subtle.RsaSsaPssVerifyJce;
import com.google.crypto.tink.signature.RsaSsaPssPrivateKey;
import com.google.crypto.tink.subtle.RsaSsaPssSignJce;
import com.google.crypto.tink.signature.RsaSsaPkcs1PublicKey;
import com.google.crypto.tink.subtle.RsaSsaPkcs1VerifyJce;
import com.google.crypto.tink.signature.RsaSsaPkcs1PrivateKey;
import com.google.crypto.tink.subtle.RsaSsaPkcs1SignJce;
import com.google.crypto.tink.signature.Ed25519PublicKey;
import com.google.crypto.tink.subtle.Ed25519Verify;
import com.google.crypto.tink.signature.Ed25519PrivateKey;
import com.google.crypto.tink.subtle.Ed25519Sign;
import com.google.crypto.tink.signature.EcdsaPublicKey;
import com.google.crypto.tink.subtle.EcdsaVerifyJce;
import com.google.crypto.tink.signature.EcdsaPrivateKey;
import com.google.crypto.tink.subtle.EcdsaSignJce;
import com.google.crypto.tink.signature.PublicKeyVerifyWrapper;
import com.google.crypto.tink.signature.PublicKeySignWrapper;
import com.google.crypto.tink.prf.HmacPrfKey;
import com.google.crypto.tink.subtle.PrfHmacJce;
import com.google.crypto.tink.prf.HkdfPrfKey;
import com.google.crypto.tink.prf.Prf;
import com.google.crypto.tink.prf.AesCmacPrfKey;
import com.google.crypto.tink.prf.PrfSetWrapper;
import com.google.crypto.tink.hybrid.HpkePrivateKey;
import com.google.crypto.tink.hybrid.internal.HpkeDecrypt;
import com.google.crypto.tink.hybrid.HpkePublicKey;
import com.google.crypto.tink.hybrid.internal.HpkeEncrypt;
import com.google.crypto.tink.hybrid.EciesPrivateKey;
import com.google.crypto.tink.subtle.EciesAeadHkdfHybridDecrypt;
import com.google.crypto.tink.hybrid.EciesPublicKey;
import com.google.crypto.tink.subtle.EciesAeadHkdfHybridEncrypt;
import com.google.crypto.tink.hybrid.HybridDecryptWrapper;
import com.google.crypto.tink.hybrid.HybridEncryptWrapper;
import com.google.crypto.tink.streamingaead.AesGcmHkdfStreamingKey;
import com.google.crypto.tink.subtle.AesGcmHkdfStreaming;
import com.google.crypto.tink.streamingaead.AesCtrHmacStreamingKey;
import com.google.crypto.tink.subtle.AesCtrHmacStreaming;
import com.google.crypto.tink.streamingaead.StreamingAeadWrapper;
import com.google.crypto.tink.daead.AesSivKey;
import com.google.crypto.tink.daead.DeterministicAeadWrapper;
import com.google.crypto.tink.aead.XChaCha20Poly1305Key;
import com.google.crypto.tink.aead.ChaCha20Poly1305Key;
import com.google.crypto.tink.aead.AesGcmSivKey;
import com.google.crypto.tink.aead.subtle.AesGcmSiv;
import com.google.crypto.tink.aead.AesGcmKey;
import com.google.crypto.tink.subtle.AesGcmJce;
import com.google.crypto.tink.aead.AesEaxKey;
import com.google.crypto.tink.subtle.AesEaxJce;
import com.google.crypto.tink.aead.AesCtrHmacAeadKey;
import com.google.crypto.tink.subtle.EncryptThenAuthenticate;
import com.google.crypto.tink.aead.AeadWrapper;
import com.google.crypto.tink.mac.internal.ChunkedHmacImpl;
import com.google.crypto.tink.mac.ChunkedMac;
import com.google.crypto.tink.mac.HmacKey;
import com.google.crypto.tink.subtle.PrfMac;
import com.google.crypto.tink.internal.PrimitiveConstructor;
import com.google.crypto.tink.mac.AesCmacKey;
import com.google.crypto.tink.mac.ChunkedMacWrapper;
import com.google.crypto.tink.mac.MacWrapper;
import com.google.crypto.tink.internal.PrimitiveRegistry;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.config.internal.TinkFipsUtil;

public class ConfigurationV0
{
    private static final int AES_CMAC_KEY_SIZE_BYTES = 32;
    
    private ConfigurationV0() {
    }
    
    public static Configuration get() throws GeneralSecurityException {
        if (TinkFipsUtil.useOnlyFips()) {
            throw new GeneralSecurityException("Cannot use non-FIPS-compliant ConfigurationV0 in FIPS mode");
        }
        final PrimitiveRegistry.Builder builder = PrimitiveRegistry.builder();
        MacWrapper.registerToInternalPrimitiveRegistry(builder);
        ChunkedMacWrapper.registerToInternalPrimitiveRegistry(builder);
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)ConfigurationV0::createAesCmac, (Class<KeyT>)AesCmacKey.class, (Class<PrimitiveT>)Mac.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)PrfMac::create, (Class<KeyT>)HmacKey.class, (Class<PrimitiveT>)Mac.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)ConfigurationV0::createChunkedAesCmac, (Class<KeyT>)AesCmacKey.class, (Class<PrimitiveT>)ChunkedMac.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)ChunkedHmacImpl::new, (Class<KeyT>)HmacKey.class, (Class<PrimitiveT>)ChunkedMac.class));
        AeadWrapper.registerToInternalPrimitiveRegistry(builder);
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)EncryptThenAuthenticate::create, (Class<KeyT>)AesCtrHmacAeadKey.class, (Class<PrimitiveT>)Aead.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)AesEaxJce::create, (Class<KeyT>)AesEaxKey.class, (Class<PrimitiveT>)Aead.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)AesGcmJce::create, (Class<KeyT>)AesGcmKey.class, (Class<PrimitiveT>)Aead.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)AesGcmSiv::create, (Class<KeyT>)AesGcmSivKey.class, (Class<PrimitiveT>)Aead.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)ConfigurationV0::createChaCha20Poly1305, (Class<KeyT>)ChaCha20Poly1305Key.class, (Class<PrimitiveT>)Aead.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)ConfigurationV0::createXChaCha20Poly1305, (Class<KeyT>)XChaCha20Poly1305Key.class, (Class<PrimitiveT>)Aead.class));
        DeterministicAeadWrapper.registerToInternalPrimitiveRegistry(builder);
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)ConfigurationV0::createAesSiv, (Class<KeyT>)AesSivKey.class, (Class<PrimitiveT>)DeterministicAead.class));
        StreamingAeadWrapper.registerToInternalPrimitiveRegistry(builder);
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)AesCtrHmacStreaming::create, (Class<KeyT>)AesCtrHmacStreamingKey.class, (Class<PrimitiveT>)StreamingAead.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)AesGcmHkdfStreaming::create, (Class<KeyT>)AesGcmHkdfStreamingKey.class, (Class<PrimitiveT>)StreamingAead.class));
        HybridEncryptWrapper.registerToInternalPrimitiveRegistry(builder);
        HybridDecryptWrapper.registerToInternalPrimitiveRegistry(builder);
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)EciesAeadHkdfHybridEncrypt::create, (Class<KeyT>)EciesPublicKey.class, (Class<PrimitiveT>)HybridEncrypt.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)EciesAeadHkdfHybridDecrypt::create, (Class<KeyT>)EciesPrivateKey.class, (Class<PrimitiveT>)HybridDecrypt.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)HpkeEncrypt::create, (Class<KeyT>)HpkePublicKey.class, (Class<PrimitiveT>)HybridEncrypt.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)HpkeDecrypt::create, (Class<KeyT>)HpkePrivateKey.class, (Class<PrimitiveT>)HybridDecrypt.class));
        PrfSetWrapper.registerToInternalPrimitiveRegistry(builder);
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)ConfigurationV0::createAesCmacPrf, (Class<KeyT>)AesCmacPrfKey.class, (Class<PrimitiveT>)Prf.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)ConfigurationV0::createHkdfPrf, (Class<KeyT>)HkdfPrfKey.class, (Class<PrimitiveT>)Prf.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)PrfHmacJce::create, (Class<KeyT>)HmacPrfKey.class, (Class<PrimitiveT>)Prf.class));
        PublicKeySignWrapper.registerToInternalPrimitiveRegistry(builder);
        PublicKeyVerifyWrapper.registerToInternalPrimitiveRegistry(builder);
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)EcdsaSignJce::create, (Class<KeyT>)EcdsaPrivateKey.class, (Class<PrimitiveT>)PublicKeySign.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)EcdsaVerifyJce::create, (Class<KeyT>)EcdsaPublicKey.class, (Class<PrimitiveT>)PublicKeyVerify.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)Ed25519Sign::create, (Class<KeyT>)Ed25519PrivateKey.class, (Class<PrimitiveT>)PublicKeySign.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)Ed25519Verify::create, (Class<KeyT>)Ed25519PublicKey.class, (Class<PrimitiveT>)PublicKeyVerify.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)RsaSsaPkcs1SignJce::create, (Class<KeyT>)RsaSsaPkcs1PrivateKey.class, (Class<PrimitiveT>)PublicKeySign.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)RsaSsaPkcs1VerifyJce::create, (Class<KeyT>)RsaSsaPkcs1PublicKey.class, (Class<PrimitiveT>)PublicKeyVerify.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)RsaSsaPssSignJce::create, (Class<KeyT>)RsaSsaPssPrivateKey.class, (Class<PrimitiveT>)PublicKeySign.class));
        builder.registerPrimitiveConstructor((PrimitiveConstructor<Key, Object>)PrimitiveConstructor.create((PrimitiveConstructor.PrimitiveConstructionFunction<KeyT, PrimitiveT>)RsaSsaPssVerifyJce::create, (Class<KeyT>)RsaSsaPssPublicKey.class, (Class<PrimitiveT>)PublicKeyVerify.class));
        return InternalConfiguration.createFromPrimitiveRegistry(builder.allowReparsingLegacyKeys().build());
    }
    
    private static Aead createChaCha20Poly1305(final ChaCha20Poly1305Key key) throws GeneralSecurityException {
        if (ChaCha20Poly1305Jce.isSupported()) {
            return ChaCha20Poly1305Jce.create(key);
        }
        return ChaCha20Poly1305.create(key);
    }
    
    private static Aead createXChaCha20Poly1305(final XChaCha20Poly1305Key key) throws GeneralSecurityException {
        if (XChaCha20Poly1305Jce.isSupported()) {
            return XChaCha20Poly1305Jce.create(key);
        }
        return XChaCha20Poly1305.create(key);
    }
    
    private static DeterministicAead createAesSiv(final AesSivKey key) throws GeneralSecurityException {
        final int aesSivKeySizeInBytes = 64;
        if (key.getParameters().getKeySizeBytes() != aesSivKeySizeInBytes) {
            throw new GeneralSecurityException("invalid key size: " + key.getParameters().getKeySizeBytes() + ". Valid keys must have " + aesSivKeySizeInBytes + " bytes.");
        }
        return AesSiv.create(key);
    }
    
    private static Prf createHkdfPrf(final HkdfPrfKey key) throws GeneralSecurityException {
        final int minHkdfPrfKeySize = 32;
        if (key.getParameters().getKeySizeBytes() < minHkdfPrfKeySize) {
            throw new GeneralSecurityException("Key size must be at least " + minHkdfPrfKeySize);
        }
        if (key.getParameters().getHashType() != HkdfPrfParameters.HashType.SHA256 && key.getParameters().getHashType() != HkdfPrfParameters.HashType.SHA512) {
            throw new GeneralSecurityException("Hash type must be SHA256 or SHA512");
        }
        return PrfImpl.wrap(HkdfStreamingPrf.create(key));
    }
    
    private static Prf createAesCmacPrf(final AesCmacPrfKey key) throws GeneralSecurityException {
        if (key.getParameters().getKeySizeBytes() != 32) {
            throw new GeneralSecurityException("Key size must be 32 bytes");
        }
        return PrfAesCmac.create(key);
    }
    
    private static ChunkedMac createChunkedAesCmac(final AesCmacKey key) throws GeneralSecurityException {
        if (key.getParameters().getKeySizeBytes() != 32) {
            throw new GeneralSecurityException("AesCmac key size is not 32 bytes");
        }
        return ChunkedAesCmacImpl.create(key);
    }
    
    private static Mac createAesCmac(final AesCmacKey key) throws GeneralSecurityException {
        if (key.getParameters().getKeySizeBytes() != 32) {
            throw new GeneralSecurityException("AesCmac key size is not 32 bytes");
        }
        return PrfMac.create(key);
    }
}
