package org.bouncycastle.crypto.util;

import java.util.HashSet;
import java.util.Set;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.internal.asn1.kisa.KISAObjectIdentifiers;
import org.bouncycastle.internal.asn1.nsri.NSRIObjectIdentifiers;
import org.bouncycastle.internal.asn1.ntt.NTTObjectIdentifiers;

/**
 * Catalogue of content-encryption algorithm OIDs used where code only needs to
 * identify the parameter form or block size family for an algorithm.
 * <p>
 * The methods in this class are membership tests only. They do not provide key
 * sizes, JCA names, or provider registration aliases.
 */
final class OidCatalogue
{
    private static final Set<ASN1ObjectIdentifier> ccmAlgs = new HashSet<ASN1ObjectIdentifier>();
    private static final Set<ASN1ObjectIdentifier> gcmAlgs = new HashSet<ASN1ObjectIdentifier>();
    private static final Set<ASN1ObjectIdentifier> cbc128Algs = new HashSet<ASN1ObjectIdentifier>();

    static
    {
        ccmAlgs.add(NISTObjectIdentifiers.id_aes128_CCM);
        ccmAlgs.add(NISTObjectIdentifiers.id_aes192_CCM);
        ccmAlgs.add(NISTObjectIdentifiers.id_aes256_CCM);
        ccmAlgs.add(NSRIObjectIdentifiers.id_aria128_ccm);
        ccmAlgs.add(NSRIObjectIdentifiers.id_aria192_ccm);
        ccmAlgs.add(NSRIObjectIdentifiers.id_aria256_ccm);
        ccmAlgs.add(GMObjectIdentifiers.sms4_ccm);

        gcmAlgs.add(NISTObjectIdentifiers.id_aes128_GCM);
        gcmAlgs.add(NISTObjectIdentifiers.id_aes192_GCM);
        gcmAlgs.add(NISTObjectIdentifiers.id_aes256_GCM);
        gcmAlgs.add(NSRIObjectIdentifiers.id_aria128_gcm);
        gcmAlgs.add(NSRIObjectIdentifiers.id_aria192_gcm);
        gcmAlgs.add(NSRIObjectIdentifiers.id_aria256_gcm);
        gcmAlgs.add(GMObjectIdentifiers.sms4_gcm);

        cbc128Algs.add(NISTObjectIdentifiers.id_aes128_CBC);
        cbc128Algs.add(NISTObjectIdentifiers.id_aes192_CBC);
        cbc128Algs.add(NISTObjectIdentifiers.id_aes256_CBC);
        cbc128Algs.add(NTTObjectIdentifiers.id_camellia128_cbc);
        cbc128Algs.add(NTTObjectIdentifiers.id_camellia192_cbc);
        cbc128Algs.add(NTTObjectIdentifiers.id_camellia256_cbc);
        cbc128Algs.add(KISAObjectIdentifiers.id_seedCBC);
        cbc128Algs.add(GMObjectIdentifiers.sms4_cbc);
    }

    private OidCatalogue()
    {

    }

    /**
     * Return whether the OID identifies a CCM content-encryption algorithm
     * whose parameters are encoded as CCMParameters.
     *
     * @param algorithm candidate algorithm OID.
     * @return true if the OID is a known CCM content-encryption algorithm.
     */
    public static boolean isCCM(ASN1ObjectIdentifier algorithm)
    {
        return ccmAlgs.contains(algorithm);
    }

    /**
     * Return whether the OID identifies a GCM content-encryption algorithm
     * whose parameters are encoded as GCMParameters.
     *
     * @param algorithm candidate algorithm OID.
     * @return true if the OID is a known GCM content-encryption algorithm.
     */
    public static boolean isGCM(ASN1ObjectIdentifier algorithm)
    {
        return gcmAlgs.contains(algorithm);
    }

    /**
     * Return whether the OID identifies a CBC content-encryption algorithm
     * with a 128-bit block size and an IV encoded as an octet string.
     *
     * @param algorithm candidate algorithm OID.
     * @return true if the OID is a known 128-bit block CBC content-encryption algorithm.
     */
    public static boolean isCBC128(ASN1ObjectIdentifier algorithm)
    {
        return cbc128Algs.contains(algorithm);
    }
}
