package org.bouncycastle.pqc.crypto.snova;

public class SnovaParameters
{

    public static final SnovaParameters SNOVA_24_5_4_SSK =
        new SnovaParameters("SNOVA_24_5_4_SSK", 24, 5, 4, true, false);
    public static final SnovaParameters SNOVA_24_5_4_ESK =
        new SnovaParameters("SNOVA_24_5_4_ESK", 24, 5, 4, false, false);
    public static final SnovaParameters SNOVA_24_5_4_SHAKE_SSK =
        new SnovaParameters("SNOVA_24_5_4_SHAKE_SSK", 24, 5, 4, true, true);
    public static final SnovaParameters SNOVA_24_5_4_SHAKE_ESK =
        new SnovaParameters("SNOVA_24_5_4_SHAKE_ESK", 24, 5, 4, false, true);

    public static final SnovaParameters SNOVA_24_5_5_SSK =
        new SnovaParameters("SNOVA_24_5_5_SSK", 24, 5, 5, true, false);
    public static final SnovaParameters SNOVA_24_5_5_ESK =
        new SnovaParameters("SNOVA_24_5_5_ESK", 24, 5, 5, false, false);
    public static final SnovaParameters SNOVA_24_5_5_SHAKE_SSK =
        new SnovaParameters("SNOVA_24_5_5_SHAKE_SSK", 24, 5, 5, true, true);
    public static final SnovaParameters SNOVA_24_5_5_SHAKE_ESK =
        new SnovaParameters("SNOVA_24_5_5_SHAKE_ESK", 24, 5, 5, false, true);

    public static final SnovaParameters SNOVA_25_8_3_SSK =
        new SnovaParameters("SNOVA_25_8_3_SSK", 25, 8, 3, true, false);
    public static final SnovaParameters SNOVA_25_8_3_ESK =
        new SnovaParameters("SNOVA_25_8_3_ESK", 25, 8, 3, false, false);
    public static final SnovaParameters SNOVA_25_8_3_SHAKE_SSK =
        new SnovaParameters("SNOVA_25_8_3_SHAKE_SSK", 25, 8, 3, true, true);
    public static final SnovaParameters SNOVA_25_8_3_SHAKE_ESK =
        new SnovaParameters("SNOVA_25_8_3_SHAKE_ESK", 25, 8, 3, false, true);

    public static final SnovaParameters SNOVA_29_6_5_SSK =
        new SnovaParameters("SNOVA_29_6_5_SSK", 29, 6, 5, true, false);
    public static final SnovaParameters SNOVA_29_6_5_ESK =
        new SnovaParameters("SNOVA_29_6_5_ESK", 29, 6, 5, false, false);
    public static final SnovaParameters SNOVA_29_6_5_SHAKE_SSK =
        new SnovaParameters("SNOVA_29_6_5_SHAKE_SSK", 29, 6, 5, true, true);
    public static final SnovaParameters SNOVA_29_6_5_SHAKE_ESK =
        new SnovaParameters("SNOVA_29_6_5_SHAKE_ESK", 29, 6, 5, false, true);

    public static final SnovaParameters SNOVA_37_8_4_SSK =
        new SnovaParameters("SNOVA_37_8_4_SSK", 37, 8, 4, true, false);
    public static final SnovaParameters SNOVA_37_8_4_ESK =
        new SnovaParameters("SNOVA_37_8_4_ESK", 37, 8, 4, false, false);
    public static final SnovaParameters SNOVA_37_8_4_SHAKE_SSK =
        new SnovaParameters("SNOVA_37_8_4_SHAKE_SSK", 37, 8, 4, true, true);
    public static final SnovaParameters SNOVA_37_8_4_SHAKE_ESK =
        new SnovaParameters("SNOVA_37_8_4_SHAKE_ESK", 37, 8, 4, false, true);

    // SNOVA_37_17_2 variants
    public static final SnovaParameters SNOVA_37_17_2_SSK =
        new SnovaParameters("SNOVA_37_17_2_SSK", 37, 17, 2, true, false);
    public static final SnovaParameters SNOVA_37_17_2_ESK =
        new SnovaParameters("SNOVA_37_17_2_ESK", 37, 17, 2, false, false);
    public static final SnovaParameters SNOVA_37_17_2_SHAKE_SSK =
        new SnovaParameters("SNOVA_37_17_2_SHAKE_SSK", 37, 17, 2, true, true);
    public static final SnovaParameters SNOVA_37_17_2_SHAKE_ESK =
        new SnovaParameters("SNOVA_37_17_2_SHAKE_ESK", 37, 17, 2, false, true);

    // SNOVA_49_11_3 variants
    public static final SnovaParameters SNOVA_49_11_3_SSK =
        new SnovaParameters("SNOVA_49_11_3_SSK", 49, 11, 3, true, false);
    public static final SnovaParameters SNOVA_49_11_3_ESK =
        new SnovaParameters("SNOVA_49_11_3_ESK", 49, 11, 3, false, false);
    public static final SnovaParameters SNOVA_49_11_3_SHAKE_SSK =
        new SnovaParameters("SNOVA_49_11_3_SHAKE_SSK", 49, 11, 3, true, true);
    public static final SnovaParameters SNOVA_49_11_3_SHAKE_ESK =
        new SnovaParameters("SNOVA_49_11_3_SHAKE_ESK", 49, 11, 3, false, true);

    // SNOVA_56_25_2 variants
    public static final SnovaParameters SNOVA_56_25_2_SSK =
        new SnovaParameters("SNOVA_56_25_2_SSK", 56, 25, 2, true, false);
    public static final SnovaParameters SNOVA_56_25_2_ESK =
        new SnovaParameters("SNOVA_56_25_2_ESK", 56, 25, 2, false, false);
    public static final SnovaParameters SNOVA_56_25_2_SHAKE_SSK =
        new SnovaParameters("SNOVA_56_25_2_SHAKE_SSK", 56, 25, 2, true, true);
    public static final SnovaParameters SNOVA_56_25_2_SHAKE_ESK =
        new SnovaParameters("SNOVA_56_25_2_SHAKE_ESK", 56, 25, 2, false, true);

    // SNOVA_60_10_4 variants
    public static final SnovaParameters SNOVA_60_10_4_SSK =
        new SnovaParameters("SNOVA_60_10_4_SSK", 60, 10, 4, true, false);
    public static final SnovaParameters SNOVA_60_10_4_ESK =
        new SnovaParameters("SNOVA_60_10_4_ESK", 60, 10, 4, false, false);
    public static final SnovaParameters SNOVA_60_10_4_SHAKE_SSK =
        new SnovaParameters("SNOVA_60_10_4_SHAKE_SSK", 60, 10, 4, true, true);
    public static final SnovaParameters SNOVA_60_10_4_SHAKE_ESK =
        new SnovaParameters("SNOVA_60_10_4_SHAKE_ESK", 60, 10, 4, false, true);

    // SNOVA_66_15_4 variants
    public static final SnovaParameters SNOVA_66_15_3_SSK =
        new SnovaParameters("SNOVA_66_15_3_SSK", 66, 15, 3, true, false);
    public static final SnovaParameters SNOVA_66_15_3_ESK =
        new SnovaParameters("SNOVA_66_15_3_ESK", 66, 15, 3, false, false);
    public static final SnovaParameters SNOVA_66_15_3_SHAKE_SSK =
        new SnovaParameters("SNOVA_66_15_3_SHAKE_SSK", 66, 15, 3, true, true);
    public static final SnovaParameters SNOVA_66_15_3_SHAKE_ESK =
        new SnovaParameters("SNOVA_66_15_3_SHAKE_ESK", 66, 15, 3, false, true);

    // SNOVA_75_33_2 variants
    public static final SnovaParameters SNOVA_75_33_2_SSK =
        new SnovaParameters("SNOVA_75_33_2_SSK", 75, 33, 2, true, false);
    public static final SnovaParameters SNOVA_75_33_2_ESK =
        new SnovaParameters("SNOVA_75_33_2_ESK", 75, 33, 2, false, false);
    public static final SnovaParameters SNOVA_75_33_2_SHAKE_SSK =
        new SnovaParameters("SNOVA_75_33_2_SHAKE_SSK", 75, 33, 2, true, true);
    public static final SnovaParameters SNOVA_75_33_2_SHAKE_ESK =
        new SnovaParameters("SNOVA_75_33_2_SHAKE_ESK", 75, 33, 2, false, true);

    private final String name;
    private final int v;
    private final int o;
    private final int l;
    private final int lsq;
    private final int alpha;
    private final boolean skIsSeed;
    private final boolean pkExpandShake;

    private SnovaParameters(String name, int v, int o, int l, boolean skIsSeed, boolean pkExpandShake)
    {
        this.name = name;
        this.v = v;
        this.o = o;
        this.l = l;
        this.lsq = l * l;
        this.alpha = lsq + l;
        this.skIsSeed = skIsSeed;
        this.pkExpandShake = pkExpandShake;
    }

    // Getter methods
    public String getName()
    {
        return name;
    }

    public int getV()
    {
        return v;
    }

    public int getO()
    {
        return o;
    }

    public int getL()
    {
        return l;
    }

    public boolean isSkIsSeed()
    {
        return skIsSeed;
    }

    public boolean isPkExpandShake()
    {
        return pkExpandShake;
    }

    public int getM()
    {
        return o;
    }

    public int getAlpha()
    {
        return alpha;
    }

    public int getPublicKeyLength()
    {
        return SnovaKeyPairGenerator.publicSeedLength + ((o * o * o * lsq + 1) >>> 1);
    }

    public int getPrivateKeyLength()
    {
        return ((lsq * (4 * o * alpha + o * (v * v + v * o + o * v) + v * o) + 1) >> 1)
            + SnovaKeyPairGenerator.privateSeedLength + SnovaKeyPairGenerator.publicSeedLength;
    }

    public int getN()
    {
        return v + o;
    }

    public int getLsq()
    {
        return lsq;
    }

    public int getSaltLength()
    {
        return 16;
    }
}
