/**
   * * generate password scheme either a) during initialization or b) after successful login
   *
   * @param hpwd
   * @param positions
   * @param password
   */
  private static void generateScheme(BigInteger hpwd, Position[] positions, String password) {
    /* generate new random polynomial */
    Polynomial newPoly = Polynomial.getRandomPolynomial(Constants.M - 1, hpwd);

    /* generate new R value and persist */
    Generator.R = Generator.getRandomInteger(Generator.BIT_LENGTH);
    LoginHandler.getPreferences().put(Constants.PREF_R, Generator.R.toString());

    /* reinitialize P and G functions with new R value */
    initFunctions(password);

    /* generate new Instruction Table and write to file */
    InstructionTable iTable = InstructionTable.generateInstructionTable(positions, newPoly);
    iTable.writeToFile(Constants.INSTRUCTION_TABLE_FILE_PATH);
  }
  /**
   * * extracts hardened password from features and password
   *
   * @param features
   * @param password
   * @return hardened password
   */
  private static BigInteger extractHardenedPwd(long[] features, String password) {
    List<Point> points = new LinkedList<Point>();
    InstructionTable iTable = InstructionTable.loadTable(Constants.INSTRUCTION_TABLE_FILE_PATH);

    for (int i = 0; i < features.length; i++) {
      int index = iTable.get(i).getIndex();
      BigInteger x = null, y = null;

      switch (InstructionTable.getPosition(features[i], i)) {
        case ALPHA:
        case BOTH:
          x = p_function.execute(2 * index);
          y = iTable.get(i).getAlpha().subtract(g_function.execute(2 * index)).mod(Constants.Q);
          break;
        case BETA:
          x = p_function.execute(2 * index + 1);
          y = iTable.get(i).getBeta().subtract(g_function.execute(2 * index + 1)).mod(Constants.Q);
          break;
      }
      points.add(new Point(x, y));
    }

    BigInteger hpwd = Polynomial.generateZerothCoefficientFromPoints(points);
    return hpwd;
  }