/*
 This file is part of GNUnet.
 (C) 2014 Christian Grothoff (and other contributing authors)

 GNUnet is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published
 by the Free Software Foundation; either version 3, or (at your
 option) any later version.

 GNUnet is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with GNUnet; see the file COPYING.  If not, write to the
 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.
 */

package org.gnunet.secretsharing;

import org.gnunet.voting.VotingParameters;

import java.math.BigInteger;
import java.security.SecureRandom;

/**
 * Constants used by the crypto of the secretsharing API.
 */
public abstract class Parameters {
    /**
     * Size of the key.
     */
    public static final int elgamalBits = 1024;

    /**
     * Order of the group.
     */
    public static final BigInteger elgamalQ = new BigInteger(
            "0451a3e9eb4f4596ebe8d895046fde65f5fa65" +
            "37a134d040a70ac51a1894b26ca359f79144118b" +
            "95e7987e047bb93ba65a027cde001537b3584d3c" +
            "ec086b3e27c659df6e303071e477c3a58db26fb8" +
            "b63e958016d4407134a1c6ad3bb735af929e46fa" +
            "b50b58e3e72c6f783e01eda411c556fe2951aa51" +
            "3f6942d860b3ae569f9", 16);

    /**
     * Modulus of the group.
     */
    public static final BigInteger elgamalP = new BigInteger(
            "08a347d3d69e8b2dd7d1b12a08dfbccbebf4ca" +
                    "6f4269a0814e158a34312964d946b3ef22882317" +
                    "2bcf30fc08f772774cb404f9bc002a6f66b09a79" +
                    "d810d67c4f8cb3bedc6060e3c8ef874b1b64df71" +
                    "6c7d2b002da880e269438d5a776e6b5f253c8df5" +
                    "6a16b1c7ce58def07c03db48238aadfc52a354a2" +
                    "7ed285b0c1675cad3f3", 16);

    /**
     * Generator of the group.
     */
    public static final BigInteger elgamalG = new BigInteger(
            "05c00c36d2e822950087ef09d8252994adc4e4" +
            "8fe3ec70269f035b46063aff0c99b633fd64df43" +
            "02442e1914c829a41505a275438871f365e91c12" +
            "3d5303ef9e90f4b8cb89bf86cc9b513e74a72634" +
            "9cfd9f953674fab5d511e1c078fc72d72b34086f" +
            "c82b4b951989eb85325cb203ff98df76bc366bba" +
            "1d7024c3650f60d0da", 16);

    public static BigInteger randomQ() {
        SecureRandom r = new SecureRandom();
        BigInteger y;
        do {
            y = new BigInteger(Parameters.elgamalBits - 1, r);
        } while (y.compareTo(BigInteger.ONE) == 0 || y.compareTo(Parameters.elgamalQ) >= 0);
        return y;
    }

    public static BigInteger modPowG(BigInteger exp) {
        return elgamalG.modPow(exp, elgamalP);
    }

    public static BigInteger[] generateGenerators(int i) {
        BigInteger[] generators = new BigInteger[i];
        for (int j = 0; j < i; j++) {
            // FIXME: this violates proper layering of the modules
            generators[j] = VotingParameters.selectSubgroupGenerator(elgamalP, elgamalQ);
        }
        return generators;
    }
}
