core/src/main/java/org/bouncycastle/pqc/crypto/qtesla/QTESLA.java
/************************************************************************************************************************************************************
     * Description:	Generates A Pair of Public Key and Private Key for qTESLA Signature Scheme for Heuristic qTESLA Security Category-1
     *				and Category-3 (Option for Size or Speed)
     *
     * @param        publicKey                            Contains Public Key
     * @param        privateKey                            Contains Private Key
     * @param        secureRandom                        Source of Randomness
     * @param        n                                    Polynomial Degree
     * @param        w                                    Number of Non-Zero Entries of Output Elements of Encryption
     * @param        q                                    Modulus
     * @param        qInverse
     * @param        qLogarithm                            q <= 2 ^ qLogarithm
     * @param        generatorA
     * @param        inverseNumberTheoreticTransform
     * @param        xi
     * @param        zeta
     * @param        errorBound                            Bound in Checking Error Polynomial
     * @param        secretBound                            Bound in Checking Secret Polynomial
     *
     * @return 0                                    Successful Execution
     *
     ************************************************************************************************************************************************************/
Generates A Pair of Public Key and Private Key for qTESLA Signature Scheme for Heuristic qTESLA Security Category-1
and Category-3 (Option for Size or Speed)



@return 0                                    Successful Execution
Generates A Pair of Public Key and Private Key for qTESLA Signature Scheme for Heuristic qTESLA Security Category - 1 and Category - 3 ( Option for Size or Speed ) @return 0 Successful Execution
private static int generateKeyPair(
        byte[] publicKey, byte[] privateKey, SecureRandom secureRandom,
        int n, int w, int q, long qInverse, int qLogarithm, int generatorA, int inverseNumberTheoreticTransform, double xi,
        long[] zeta,
        int errorBound, int secretBound)
    {
        /* Initialize Domain Separator for Error Polynomial and Secret Polynomial */
        int nonce = 0;
        byte[] randomness = new byte[Polynomial.RANDOM];
        /* Extend Random Bytes to Seed Generation of Error Polynomial and Secret Polynomial */
        byte[] randomnessExtended = new byte[Polynomial.SEED * 4];
        long[] secretPolynomial = new long[n];
        long[] errorPolynomial = new long[n];
        long[] A = new long[n];
        long[] T = new long[n];
        /* Get randomnessExtended <- seedErrorPolynomial, seedSecretPolynomial, seedA, seedY */
        secureRandom.nextBytes(randomness);
        if (q == Parameter.Q_I)
        {
            HashUtils.secureHashAlgorithmKECCAK128(randomnessExtended, 0, Polynomial.SEED * 4, randomness, 0, Polynomial.RANDOM);
        }
        if (q == Parameter.Q_III_SIZE || q == Parameter.Q_III_SPEED)
        {
            HashUtils.secureHashAlgorithmKECCAK256(randomnessExtended, 0, Polynomial.SEED * 4, randomness, 0, Polynomial.RANDOM);
        }
        /*
         * Sample the Error Polynomial Fulfilling the Criteria
         * Choose All Error Polynomial in R with Entries from D_SIGMA
         * Repeat Step at Iteration if the h Largest Entries of Error Polynomial Summation to L_E
         */
        do
        {
            if (q == Parameter.Q_I)
            {
                Sample.polynomialGaussSamplerI(errorPolynomial, 0, randomnessExtended, 0, ++nonce, n, xi, Sample.EXPONENTIAL_DISTRIBUTION_I);
            }
            if (q == Parameter.Q_III_SIZE)
            {
                Sample.polynomialGaussSamplerIII(errorPolynomial, 0, randomnessExtended, 0, ++nonce, n, xi, Sample.EXPONENTIAL_DISTRIBUTION_III_SIZE);
            }
            if (q == Parameter.Q_III_SPEED)
            {
                Sample.polynomialGaussSamplerIII(errorPolynomial, 0, randomnessExtended, 0, ++nonce, n, xi, Sample.EXPONENTIAL_DISTRIBUTION_III_SPEED);
            }
        }
        while (checkPolynomial(errorPolynomial, 0, errorBound, n, w) == true);
        /*
         * Sample the Secret Polynomial Fulfilling the Criteria
         * Choose Secret Polynomial in R with Entries from D_SIGMA
         * Repeat Step if the h Largest Entries of Secret Polynomial Summation to L_S
         */
        do
        {
            if (q == Parameter.Q_I)
            {
                Sample.polynomialGaussSamplerI(secretPolynomial, 0, randomnessExtended, 0, ++nonce, n, xi, Sample.EXPONENTIAL_DISTRIBUTION_I);
            }
            if (q == Parameter.Q_III_SIZE)
            {
                Sample.polynomialGaussSamplerIII(secretPolynomial, 0, randomnessExtended, 0, ++nonce, n, xi, Sample.EXPONENTIAL_DISTRIBUTION_III_SIZE);
            }
            if (q == Parameter.Q_III_SPEED)
            {
                Sample.polynomialGaussSamplerIII(secretPolynomial, 0, randomnessExtended, 0, ++nonce, n, xi, Sample.EXPONENTIAL_DISTRIBUTION_III_SPEED);
            }
        }
        while (checkPolynomial(secretPolynomial, 0, secretBound, n, w) == true);
        /* Generate Uniform Polynomial A */
        Polynomial.polynomialUniform(
            A, randomnessExtended, Polynomial.SEED * 2, n, 1, q, qInverse, qLogarithm, generatorA, inverseNumberTheoreticTransform
        );
        /* Compute the Public Key T = A * secretPolynomial + errorPolynomial */
        Polynomial.polynomialMultiplication(T, 0, A, 0, secretPolynomial, 0, n, q, qInverse, zeta);
        Polynomial.polynomialAddition(T, 0, T, 0, errorPolynomial, 0, n);
        /* Pack Public and Private Keys */
        packPrivateKey(privateKey, secretPolynomial, errorPolynomial, randomnessExtended, Polynomial.SEED * 2, n);
        if (q == Parameter.Q_I)
        {
            encodePublicKey(publicKey, T, randomnessExtended, Polynomial.SEED * 2, n, Parameter.Q_LOGARITHM_I);
        }
        if (q == Parameter.Q_III_SIZE)
        {
            encodePublicKey(publicKey, T, randomnessExtended, Polynomial.SEED * 2, n, Parameter.Q_LOGARITHM_III_SIZE);
        }
        if (q == Parameter.Q_III_SPEED)
        {
            encodePublicKeyIIISpeed(publicKey, T, randomnessExtended, Polynomial.SEED * 2);
        }
        return 0;
    }
private static int generateKeyPair ( byte [ ] publicKey , byte [ ] privateKey , SecureRandom secureRandom , int n , int w , int q , long qInverse , int qLogarithm , int generatorA , int inverseNumberTheoreticTransform , double xi , long [ ] zeta , int errorBound , int secretBound ) { /* Initialize Domain Separator for Error Polynomial and Secret Polynomial */ int nonce = 0 ; byte [ ] randomness = new byte [ Polynomial . RANDOM ] ; /* Extend Random Bytes to Seed Generation of Error Polynomial and Secret Polynomial */ byte [ ] randomnessExtended = new byte [ Polynomial . SEED * 4 ] ; long [ ] secretPolynomial = new long [ n ] ; long [ ] errorPolynomial = new long [ n ] ; long [ ] A = new long [ n ] ; long [ ] T = new long [ n ] ; /* Get randomnessExtended <- seedErrorPolynomial, seedSecretPolynomial, seedA, seedY */ secureRandom . nextBytes ( randomness ) ; if ( q == Parameter . Q_I ) { HashUtils . secureHashAlgorithmKECCAK128 ( randomnessExtended , 0 , Polynomial . SEED * 4 , randomness , 0 , Polynomial . RANDOM ) ; } if ( q == Parameter . Q_III_SIZE || q == Parameter . Q_III_SPEED ) { HashUtils . secureHashAlgorithmKECCAK256 ( randomnessExtended , 0 , Polynomial . SEED * 4 , randomness , 0 , Polynomial . RANDOM ) ; } /*
         * Sample the Error Polynomial Fulfilling the Criteria
         * Choose All Error Polynomial in R with Entries from D_SIGMA
         * Repeat Step at Iteration if the h Largest Entries of Error Polynomial Summation to L_E
         */ do { if ( q == Parameter . Q_I ) { Sample . polynomialGaussSamplerI ( errorPolynomial , 0 , randomnessExtended , 0 , ++ nonce , n , xi , Sample . EXPONENTIAL_DISTRIBUTION_I ) ; } if ( q == Parameter . Q_III_SIZE ) { Sample . polynomialGaussSamplerIII ( errorPolynomial , 0 , randomnessExtended , 0 , ++ nonce , n , xi , Sample . EXPONENTIAL_DISTRIBUTION_III_SIZE ) ; } if ( q == Parameter . Q_III_SPEED ) { Sample . polynomialGaussSamplerIII ( errorPolynomial , 0 , randomnessExtended , 0 , ++ nonce , n , xi , Sample . EXPONENTIAL_DISTRIBUTION_III_SPEED ) ; } } while ( checkPolynomial ( errorPolynomial , 0 , errorBound , n , w ) == true ) ; /*
         * Sample the Secret Polynomial Fulfilling the Criteria
         * Choose Secret Polynomial in R with Entries from D_SIGMA
         * Repeat Step if the h Largest Entries of Secret Polynomial Summation to L_S
         */ do { if ( q == Parameter . Q_I ) { Sample . polynomialGaussSamplerI ( secretPolynomial , 0 , randomnessExtended , 0 , ++ nonce , n , xi , Sample . EXPONENTIAL_DISTRIBUTION_I ) ; } if ( q == Parameter . Q_III_SIZE ) { Sample . polynomialGaussSamplerIII ( secretPolynomial , 0 , randomnessExtended , 0 , ++ nonce , n , xi , Sample . EXPONENTIAL_DISTRIBUTION_III_SIZE ) ; } if ( q == Parameter . Q_III_SPEED ) { Sample . polynomialGaussSamplerIII ( secretPolynomial , 0 , randomnessExtended , 0 , ++ nonce , n , xi , Sample . EXPONENTIAL_DISTRIBUTION_III_SPEED ) ; } } while ( checkPolynomial ( secretPolynomial , 0 , secretBound , n , w ) == true ) ; /* Generate Uniform Polynomial A */ Polynomial . polynomialUniform ( A , randomnessExtended , Polynomial . SEED * 2 , n , 1 , q , qInverse , qLogarithm , generatorA , inverseNumberTheoreticTransform ) ; /* Compute the Public Key T = A * secretPolynomial + errorPolynomial */ Polynomial . polynomialMultiplication ( T , 0 , A , 0 , secretPolynomial , 0 , n , q , qInverse , zeta ) ; Polynomial . polynomialAddition ( T , 0 , T , 0 , errorPolynomial , 0 , n ) ; /* Pack Public and Private Keys */ packPrivateKey ( privateKey , secretPolynomial , errorPolynomial , randomnessExtended , Polynomial . SEED * 2 , n ) ; if ( q == Parameter . Q_I ) { encodePublicKey ( publicKey , T , randomnessExtended , Polynomial . SEED * 2 , n , Parameter . Q_LOGARITHM_I ) ; } if ( q == Parameter . Q_III_SIZE ) { encodePublicKey ( publicKey , T , randomnessExtended , Polynomial . SEED * 2 , n , Parameter . Q_LOGARITHM_III_SIZE ) ; } if ( q == Parameter . Q_III_SPEED ) { encodePublicKeyIIISpeed ( publicKey , T , randomnessExtended , Polynomial . SEED * 2 ) ; } return 0 ; }
Description:     Generates A Pair of Public Key and Private Key for qTESLA Signature Scheme for Heuristic qTESLA Security Category-1
                          and Category-3 (Option for Size or Speed)
Description : Generates A Pair of Public Key and Private Key for qTESLA Signature Scheme for Heuristic qTESLA Security Category - 1 and Category - 3 ( Option for Size or Speed )
// this.rng.randomByte (randomness, (short) 0, Polynomial.RANDOM);