core/src/main/java/org/bouncycastle/pqc/crypto/qtesla/QTESLA.java
/******************************************************************************************************************************
     * Description:	Extracts the Original Message and Checks Whether the Generated Signature is Valid for A Given Signature Package
     * 				for Provably-Secure qTESLA Security Category-1 and Category-3
     *
     * @param        signature                            Given Signature Package
     * @param        signatureOffset                        Starting Point of the Given Signature Package
     * @param        signatureLength                        Length of the Given Signature Package
     * @param        message                                Original (Signed) Message
     * @param        publicKey                            Public Key
     * @param        n                                    Polynomial Degree
     * @param        k                                    Number of Ring-Learning-With-Errors Samples
     * @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        d                                    Number of Rounded Bits
     * @param        u                                    Bound in Checking Secret Polynomial
     * @param        generatorA
     * @param        inverseNumberTheoreticTransform
     * @param        barrettMultiplication
     * @param        barrettDivision
     * @param        zeta
     *
     * @return 0                                    Valid Signature
     * 				< 0									Invalid Signature
     ********************************************************************************************************************************/
Extracts the Original Message and Checks Whether the Generated Signature is Valid for A Given Signature Package
for Provably-Secure qTESLA Security Category-1 and Category-3



@return 0                                    Valid Signature
< 0                                                                     Invalid Signature
Extracts the Original Message and Checks Whether the Generated Signature is Valid for A Given Signature Package for Provably - Secure qTESLA Security Category - 1 and Category - 3 @return 0 Valid Signature < 0 Invalid Signature
private static int verifying(
        byte[] message,
        final byte[] signature, int signatureOffset, int signatureLength,
        final byte[] publicKey,
        int n, int k, int w, int q, long qInverse, int qLogarithm, int b, int d, int u, int signatureSize,
        int generatorA, int inverseNumberTheoreticTransform,
        int barrettMultiplication, int barrettDivision,
        long[] zeta
    )
    {
        byte[] C = new byte[Polynomial.HASH];
        byte[] cSignature = new byte[Polynomial.HASH];
        byte[] seed = new byte[Polynomial.SEED];
        int[] newPublicKey = new int[n * k];
        int[] positionList = new int[w];
        short[] signList = new short[w];
        long[] W = new long[n * k];
        long[] Z = new long[n];
        long[] numberTheoreticTransformZ = new long[n];
        long[] TC = new long[n * k];
        long[] A = new long[n * k];
        if (signatureLength < signatureSize)
        {
            return -1;
        }
        if (q == Parameter.Q_I_P)
        {
            decodeSignatureIIISpeedIP(C, Z, signature, signatureOffset, n, d);
        }
        if (q == Parameter.Q_III_P)
        {
            decodeSignature(C, Z, signature, signatureOffset);
        }
        /* Check Norm of Z */
        if (testZ(Z, n, b, u) == true)
        {
            return -2;
        }
        if (q == Parameter.Q_I_P)
        {
            decodePublicKeyIP(newPublicKey, seed, 0, publicKey);
        }
        if (q == Parameter.Q_III_P)
        {
            decodePublicKeyIIIP(newPublicKey, seed, 0, publicKey);
        }
        /* Generate A Polynomial */
        Polynomial.polynomialUniform(A, seed, 0, n, k, q, qInverse, qLogarithm, generatorA, inverseNumberTheoreticTransform);
        Sample.encodeC(positionList, signList, C, 0, n, w);
        Polynomial.polynomialNumberTheoreticTransform(numberTheoreticTransformZ, Z, n);
        /* W_i = A_i * Z_i - TC_i for All i */
        for (short i = 0; i < k; i++)
        {
            Polynomial.polynomialMultiplication(W, n * i, A, n * i, numberTheoreticTransformZ, 0, n, q, qInverse);
            sparsePolynomialMultiplication32(
                TC, n * i, newPublicKey, n * i, positionList, signList, n, w, q, barrettMultiplication, barrettDivision);
            Polynomial.polynomialSubtractionP(W, n * i, W, n * i, TC, n * i, n, q, barrettMultiplication, barrettDivision);
        }
        /* Obtain the Hash Symbol */
        hashFunction(cSignature, 0, W, message, 0, message.length, n, k, d, q);
        /* Check if Same with One from Signature */
        if (CommonFunction.memoryEqual(C, 0, cSignature, 0, Polynomial.HASH) == false)
        {
            return -3;
        }
        return 0;
    }
private static int verifying ( byte [ ] message , final byte [ ] signature , int signatureOffset , int signatureLength , final byte [ ] publicKey , int n , int k , int w , int q , long qInverse , int qLogarithm , int b , int d , int u , int signatureSize , int generatorA , int inverseNumberTheoreticTransform , int barrettMultiplication , int barrettDivision , long [ ] zeta ) { byte [ ] C = new byte [ Polynomial . HASH ] ; byte [ ] cSignature = new byte [ Polynomial . HASH ] ; byte [ ] seed = new byte [ Polynomial . SEED ] ; int [ ] newPublicKey = new int [ n * k ] ; int [ ] positionList = new int [ w ] ; short [ ] signList = new short [ w ] ; long [ ] W = new long [ n * k ] ; long [ ] Z = new long [ n ] ; long [ ] numberTheoreticTransformZ = new long [ n ] ; long [ ] TC = new long [ n * k ] ; long [ ] A = new long [ n * k ] ; if ( signatureLength < signatureSize ) { return - 1 ; } if ( q == Parameter . Q_I_P ) { decodeSignatureIIISpeedIP ( C , Z , signature , signatureOffset , n , d ) ; } if ( q == Parameter . Q_III_P ) { decodeSignature ( C , Z , signature , signatureOffset ) ; } /* Check Norm of Z */ if ( testZ ( Z , n , b , u ) == true ) { return - 2 ; } if ( q == Parameter . Q_I_P ) { decodePublicKeyIP ( newPublicKey , seed , 0 , publicKey ) ; } if ( q == Parameter . Q_III_P ) { decodePublicKeyIIIP ( newPublicKey , seed , 0 , publicKey ) ; } /* Generate A Polynomial */ Polynomial . polynomialUniform ( A , seed , 0 , n , k , q , qInverse , qLogarithm , generatorA , inverseNumberTheoreticTransform ) ; Sample . encodeC ( positionList , signList , C , 0 , n , w ) ; Polynomial . polynomialNumberTheoreticTransform ( numberTheoreticTransformZ , Z , n ) ; /* W_i = A_i * Z_i - TC_i for All i */ for ( short i = 0 ; i < k ; i ++ ) { Polynomial . polynomialMultiplication ( W , n * i , A , n * i , numberTheoreticTransformZ , 0 , n , q , qInverse ) ; sparsePolynomialMultiplication32 ( TC , n * i , newPublicKey , n * i , positionList , signList , n , w , q , barrettMultiplication , barrettDivision ) ; Polynomial . polynomialSubtractionP ( W , n * i , W , n * i , TC , n * i , n , q , barrettMultiplication , barrettDivision ) ; } /* Obtain the Hash Symbol */ hashFunction ( cSignature , 0 , W , message , 0 , message . length , n , k , d , q ) ; /* Check if Same with One from Signature */ if ( CommonFunction . memoryEqual ( C , 0 , cSignature , 0 , Polynomial . HASH ) == false ) { return - 3 ; } return 0 ; }
Description:     Extracts the Original Message and Checks Whether the Generated Signature is Valid for A Given Signature Package
                          for Provably-Secure qTESLA Security Category-1 and Category-3
Description : Extracts the Original Message and Checks Whether the Generated Signature is Valid for A Given Signature Package for Provably - Secure qTESLA Security Category - 1 and Category - 3