private void selectModuli(int totalBitLength) throws InternalErrorException {
        // SUPER SOS EVERY MODULO > MaxA
        do {
            int optimalModuloSize = 200;
            optimalModuloSize = (optimalModuloSize < this.maxA.bitLength()) ? (this.maxA.bitLength() + 1) : optimalModuloSize;
            int size = (totalBitLength - M.bitLength() >= optimalModuloSize) ? optimalModuloSize : totalBitLength - M.bitLength();
            //int size = (moduli.size() < nThreads) ? (totalBitLength - M.bitLength()) / (nThreads - moduli.size()) : (totalBitLength - M.bitLength());

            size = (size < this.maxA.bitLength()) ? (this.maxA.bitLength() + 1) : size;
            size = (size < 2) ? 2 : size;
            //size = (moduli.size() % 2 == 1) ? size + 1 : size;
            boolean repetitionNecessary;
            BigInteger nextModulo;
            do {
                repetitionNecessary = false;
                nextModulo = getPrimeLessThan(size, moduli);

                //check if we must increase the current prime bitlength to produce exactly as many moduli as the number of threads.
                /*if ((totalBitLength - M.bitLength() <= optimalModuloSize) && (M.multiply(nextModulo).bitLength() < totalBitLength)) {
                size++;
                repetitionNecessary = true;
                }*/
            } while (repetitionNecessary);
            M = M.multiply(nextModulo);
            moduli.add(nextModulo);
            if (minModulo == null) {
                minModulo = nextModulo;
            } else {
                minModulo = (minModulo.compareTo(nextModulo) < 0) ? minModulo : nextModulo;
            }
            //System.out.println("Modulo #" + moduli.size() + ": "/* + nextModulo*/ + " bitSize = " + nextModulo.bitLength());
        } while (M.bitLength() < totalBitLength);
    }