class PointEd25519 extends Point {

    @Override
    public final Point scalarMultiply(BigInteger integer) {
        if (integer.equals(BigInteger.ZERO)) {
            return PointEd25519.O;
        }

        Point[] qs = new Point[]{O, O};
        Point[] rs = new Point[]{this, this, negateY()};

        int[] signedBin = ArrayUtils.toMutualOppositeForm(integer);

        for (int aSignedBin : signedBin) {
            qs[0] = qs[0].doubling();
            qs[1] = qs[0].add(rs[1 - aSignedBin]).negate();
            qs[0] = qs[(aSignedBin ^ (aSignedBin >> 31)) - (aSignedBin >> 31)];
        }
        return qs[0];
    }

}

class PointEd25519Test {

    private Curve curve;

    @Test
    public void success_ScalarMultiply_2() {

        Point point = curve.getBasePoint();
        BigInteger integer = new BigInteger("20266806181347897178517736945403300566236311925948585575972021784256181966831");

        Point result = point.scalarMultiply(integer);

        assertThat(result.getAffineX().getInteger(), is(new BigInteger("36568395279531091001405240627702774400329345357946000277861114291457062189012")));
        assertThat(result.getAffineY().getInteger(), is(new BigInteger("6892543919216139430465404745243127488161491607535545431263766463424432810420")));
    }

}