@Test
  public void toP2ReturnsExpectedResultIfGroupElementHasP3Representation() {
    for (int i = 0; i < 10; i++) {
      // Arrange:
      final GroupElement g = MathUtils.getRandomGroupElement();

      // Act:
      final GroupElement h1 = g.toP2();
      final GroupElement h2 = MathUtils.toRepresentation(g, GroupElement.Representation.P2);

      // Assert:
      Assert.assertThat(h1, IsEqual.equalTo(h2));
      Assert.assertThat(h1.getRepresentation(), IsEqual.equalTo(GroupElement.Representation.P2));
      Assert.assertThat(h1.getX(), IsEqual.equalTo(g.getX()));
      Assert.assertThat(h1.getY(), IsEqual.equalTo(g.getY()));
      Assert.assertThat(h1.getZ(), IsEqual.equalTo(g.getZ()));
      Assert.assertThat(h1.getT(), IsEqual.equalTo(null));
    }
  }
  @Test
  public void toP3ReturnsExpectedResultIfGroupElementHasP3Representation() {
    for (int i = 0; i < 10; i++) {
      // Arrange:
      final GroupElement g = MathUtils.getRandomGroupElement();

      // Act:
      final GroupElement h = g.toP3();

      // Assert:
      Assert.assertThat(h, IsEqual.equalTo(g));
      Assert.assertThat(h.getRepresentation(), IsEqual.equalTo(GroupElement.Representation.P3));
      Assert.assertThat(h, IsEqual.equalTo(g));
      Assert.assertThat(h.getX(), IsEqual.equalTo(g.getX()));
      Assert.assertThat(h.getY(), IsEqual.equalTo(g.getY()));
      Assert.assertThat(h.getZ(), IsEqual.equalTo(g.getZ()));
      Assert.assertThat(h.getT(), IsEqual.equalTo(g.getT()));
    }
  }
  @Test
  public void isOnCurveReturnsFalseForPointsNotOnTheCurve() {
    for (int i = 0; i < 100; i++) {
      // Arrange:
      final GroupElement g = MathUtils.getRandomGroupElement();
      final GroupElement h =
          GroupElement.p2(curve, g.getX(), g.getY(), g.getZ().multiply(curve.getField().TWO));

      // Assert (can only fail for 5*Z^2=1):
      Assert.assertThat(h.isOnCurve(), IsEqual.equalTo(false));
    }
  }
  @Test
  public void toCachedReturnsExpectedResultIfGroupElementHasP3Representation() {
    for (int i = 0; i < 10; i++) {
      // Arrange:
      final GroupElement g = MathUtils.getRandomGroupElement();

      // Act:
      final GroupElement h1 = g.toCached();
      final GroupElement h2 = MathUtils.toRepresentation(g, GroupElement.Representation.CACHED);

      // Assert:
      Assert.assertThat(h1, IsEqual.equalTo(h2));
      Assert.assertThat(
          h1.getRepresentation(), IsEqual.equalTo(GroupElement.Representation.CACHED));
      Assert.assertThat(h1, IsEqual.equalTo(g));
      Assert.assertThat(h1.getX(), IsEqual.equalTo(g.getY().add(g.getX())));
      Assert.assertThat(h1.getY(), IsEqual.equalTo(g.getY().subtract(g.getX())));
      Assert.assertThat(h1.getZ(), IsEqual.equalTo(g.getZ()));
      Assert.assertThat(h1.getT(), IsEqual.equalTo(g.getT().multiply(curve.get2D())));
    }
  }
  @Test
  public void toByteArrayReturnsExpectedResult() {
    for (int i = 0; i < 100; i++) {
      // Arrange:
      final GroupElement g = MathUtils.getRandomGroupElement();

      // Act:
      final byte[] gBytes = g.toByteArray();
      final byte[] bytes = MathUtils.toByteArray(MathUtils.toBigInteger(g.getY()));
      if (MathUtils.toBigInteger(g.getX()).mod(new BigInteger("2")).equals(BigInteger.ONE)) {
        bytes[31] |= 0x80;
      }

      // Assert:
      Assert.assertThat(Arrays.equals(gBytes, bytes), IsEqual.equalTo(true));
    }
  }