core/src/main/java/org/bouncycastle/pqc/crypto/qtesla/QTESLA.java
/******************************************************************************************************************************************************
     * Description:	Generates A Signature for A Given Message According to the Ring-TESLA Signature Scheme for Heuristic qTESLA Security Category-1 and
     * 				Category-3 (Option for Size or Speed)
     *
     * @param        message                                Message to be Signed
     * @param        messageOffset                        Starting Point of the Message to be Signed
     * @param        messageLength                        Length of the Message to be Signed
     * @param        signature                            Output Package Containing Signature
     * @param        privateKey                            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        b                                    Determines the Interval the Randomness is Chosen in During Signing
     * @param        bBit                                b = (2 ^ bBit) - 1
     * @param        d                                    Number of Rounded Bits
     * @param        u                                    Bound in Checking Secret Polynomial
     * @param        rejection                            Bound in Checking Error Polynomial
     * @param        generatorA
     * @param        inverseNumberTheoreticTransform
     * @param        privateKeySize                        Size of the Private Key
     * @param        barrettMultiplication
     * @param        barrettDivision
     * @param        zeta
     *
     * @return 0                                    Successful Execution
     ******************************************************************************************************************************************************/
Generates A Signature for A Given Message According to the Ring-TESLA Signature Scheme for Heuristic qTESLA Security Category-1 and
Category-3 (Option for Size or Speed)



@return 0                                    Successful Execution
Generates A Signature for A Given Message According to the Ring - TESLA Signature Scheme for Heuristic qTESLA Security Category - 1 and Category - 3 ( Option for Size or Speed ) @return 0 Successful Execution
private static int signing(
        byte[] signature,
        final byte[] message, int messageOffset, int messageLength,
        final byte[] privateKey, SecureRandom secureRandom,
        int n, int w, int q, long qInverse, int qLogarithm, int b, int bBit, int d, int u, int rejection,
        int generatorA, int inverseNumberTheoreticTransform, int privateKeySize,
        int barrettMultiplication, int barrettDivision,
        long[] zeta)
    {
        byte[] C = new byte[Polynomial.HASH];
        byte[] randomness = new byte[Polynomial.SEED];
        byte[] randomnessInput = new byte[messageLength + Polynomial.RANDOM + Polynomial.SEED];
        byte[] temporaryRandomnessInput = new byte[Polynomial.RANDOM];
        int[] positionList = new int[w];
        short[] signList = new short[w];
        long[] A = new long[n];
        long[] V = new long[n];
        long[] Y = new long[n];
        long[] Z = new long[n];
        long[] SC = new long[n];
        long[] EC = new long[n];
        /* Domain Separator for Sampling Y */
        int nonce = 0;
        secureRandom.nextBytes(temporaryRandomnessInput);
        System.arraycopy(temporaryRandomnessInput, 0, randomnessInput, Polynomial.RANDOM, Polynomial.RANDOM);
        System.arraycopy(privateKey, privateKeySize - Polynomial.SEED, randomnessInput, 0, Polynomial.SEED);
        System.arraycopy(message, messageOffset, randomnessInput, Polynomial.RANDOM + Polynomial.SEED, messageLength);
        if (q == Parameter.Q_I)
        {
            HashUtils.secureHashAlgorithmKECCAK128(
                randomness, 0, Polynomial.SEED, randomnessInput, 0, messageLength + Polynomial.RANDOM + Polynomial.SEED
            );
        }
        else
        {
            HashUtils.secureHashAlgorithmKECCAK256(
                randomness, 0, Polynomial.SEED, randomnessInput, 0, messageLength + Polynomial.RANDOM + Polynomial.SEED
            );
        }
        Polynomial.polynomialUniform(
            A, privateKey, privateKeySize - 2 * Polynomial.SEED, n, 1, q, qInverse, qLogarithm, generatorA, inverseNumberTheoreticTransform
        );
        /* Loop Due to Possible Rejection */
        while (true)
        {
            /* Sample Y Uniformly Random from -B to B */
            Sample.sampleY(Y, randomness, 0, ++nonce, n, q, b, bBit);
            /* V = A * Y Modulo Q */
            Polynomial.polynomialMultiplication(V, 0, A, 0, Y, 0, n, q, qInverse, zeta);
            hashFunction(C, 0, V, message, messageOffset, messageLength, n, d, q);
            /* Generate C = EncodeC (C') Where C' is the Hashing of V Together with Message */
            Sample.encodeC(positionList, signList, C, 0, n, w);
            sparsePolynomialMultiplication16(SC, privateKey, 0, positionList, signList, n, w);
            /* Z = Y + EC Modulo Q */
            Polynomial.polynomialAddition(Z, 0, Y, 0, SC, 0, n);
            /* Rejection Sampling */
            if (testRejection(Z, n, b, u) == true)
            {
                continue;
            }
            sparsePolynomialMultiplication16(EC, privateKey, n * Short.SIZE / Byte.SIZE, positionList, signList, n, w);
            /* V = V - EC modulo Q */
            Polynomial.polynomialSubtraction(V, 0, V, 0, EC, 0, n, q, barrettMultiplication, barrettDivision);
            if (testV(V, 0, n, d, q, rejection) == true)
            {
                continue;
            }
            switch (q)
            {
            case Parameter.Q_I:
                encodeSignature(signature, 0, C, 0, Z, n, d);
                break;
            case Parameter.Q_III_SIZE:
                encodeSignature(signature, 0, C, 0, Z, n, d);
                break;
            case Parameter.Q_III_SPEED:
                encodeSignatureIIISpeedIP(signature, 0, C, 0, Z, n, d);
                break;
            default:
                throw new IllegalStateException("unknown q: " + q);
            }
            return 0;
        }
    }
private static int signing ( byte [ ] signature , final byte [ ] message , int messageOffset , int messageLength , final byte [ ] privateKey , SecureRandom secureRandom , int n , int w , int q , long qInverse , int qLogarithm , int b , int bBit , int d , int u , int rejection , int generatorA , int inverseNumberTheoreticTransform , int privateKeySize , int barrettMultiplication , int barrettDivision , long [ ] zeta ) { byte [ ] C = new byte [ Polynomial . HASH ] ; byte [ ] randomness = new byte [ Polynomial . SEED ] ; byte [ ] randomnessInput = new byte [ messageLength + Polynomial . RANDOM + Polynomial . SEED ] ; byte [ ] temporaryRandomnessInput = new byte [ Polynomial . RANDOM ] ; int [ ] positionList = new int [ w ] ; short [ ] signList = new short [ w ] ; long [ ] A = new long [ n ] ; long [ ] V = new long [ n ] ; long [ ] Y = new long [ n ] ; long [ ] Z = new long [ n ] ; long [ ] SC = new long [ n ] ; long [ ] EC = new long [ n ] ; /* Domain Separator for Sampling Y */ int nonce = 0 ; secureRandom . nextBytes ( temporaryRandomnessInput ) ; System . arraycopy ( temporaryRandomnessInput , 0 , randomnessInput , Polynomial . RANDOM , Polynomial . RANDOM ) ; System . arraycopy ( privateKey , privateKeySize - Polynomial . SEED , randomnessInput , 0 , Polynomial . SEED ) ; System . arraycopy ( message , messageOffset , randomnessInput , Polynomial . RANDOM + Polynomial . SEED , messageLength ) ; if ( q == Parameter . Q_I ) { HashUtils . secureHashAlgorithmKECCAK128 ( randomness , 0 , Polynomial . SEED , randomnessInput , 0 , messageLength + Polynomial . RANDOM + Polynomial . SEED ) ; } else { HashUtils . secureHashAlgorithmKECCAK256 ( randomness , 0 , Polynomial . SEED , randomnessInput , 0 , messageLength + Polynomial . RANDOM + Polynomial . SEED ) ; } Polynomial . polynomialUniform ( A , privateKey , privateKeySize - 2 * Polynomial . SEED , n , 1 , q , qInverse , qLogarithm , generatorA , inverseNumberTheoreticTransform ) ; /* Loop Due to Possible Rejection */ while ( true ) { /* Sample Y Uniformly Random from -B to B */ Sample . sampleY ( Y , randomness , 0 , ++ nonce , n , q , b , bBit ) ; /* V = A * Y Modulo Q */ Polynomial . polynomialMultiplication ( V , 0 , A , 0 , Y , 0 , n , q , qInverse , zeta ) ; hashFunction ( C , 0 , V , message , messageOffset , messageLength , n , d , q ) ; /* Generate C = EncodeC (C') Where C' is the Hashing of V Together with Message */ Sample . encodeC ( positionList , signList , C , 0 , n , w ) ; sparsePolynomialMultiplication16 ( SC , privateKey , 0 , positionList , signList , n , w ) ; /* Z = Y + EC Modulo Q */ Polynomial . polynomialAddition ( Z , 0 , Y , 0 , SC , 0 , n ) ; /* Rejection Sampling */ if ( testRejection ( Z , n , b , u ) == true ) { continue ; } sparsePolynomialMultiplication16 ( EC , privateKey , n * Short . SIZE / Byte . SIZE , positionList , signList , n , w ) ; /* V = V - EC modulo Q */ Polynomial . polynomialSubtraction ( V , 0 , V , 0 , EC , 0 , n , q , barrettMultiplication , barrettDivision ) ; if ( testV ( V , 0 , n , d , q , rejection ) == true ) { continue ; } switch ( q ) { case Parameter . Q_I : encodeSignature ( signature , 0 , C , 0 , Z , n , d ) ; break ; case Parameter . Q_III_SIZE : encodeSignature ( signature , 0 , C , 0 , Z , n , d ) ; break ; case Parameter . Q_III_SPEED : encodeSignatureIIISpeedIP ( signature , 0 , C , 0 , Z , n , d ) ; break ; default : throw new IllegalStateException ( "unknown q: " + q ) ; } return 0 ; } }
Description:     Generates A Signature for A Given Message According to the Ring-TESLA Signature Scheme for Heuristic qTESLA Security Category-1 and
                          Category-3 (Option for Size or Speed)
Description : Generates A Signature for A Given Message According to the Ring - TESLA Signature Scheme for Heuristic qTESLA Security Category - 1 and Category - 3 ( Option for Size or Speed )