private static XYZ doubleScalarMultVarTime(byte[] a, XYZT pointA, byte[] b) {
    // pointA, 3*pointA, 5*pointA, 7*pointA, 9*pointA, 11*pointA, 13*pointA, 15*pointA
    CachedXYZT[] pointAArray = new CachedXYZT[8];
    pointAArray[0] = new CachedXYZT(pointA);
    PartialXYZT t = new PartialXYZT();
    doubleXYZT(t, pointA);
    XYZT doubleA = new XYZT(t);
    for (int i = 1; i < pointAArray.length; i++) {
      add(t, doubleA, pointAArray[i - 1]);
      pointAArray[i] = new CachedXYZT(new XYZT(t));
    }

    byte[] aSlide = slide(a);
    byte[] bSlide = slide(b);
    t = new PartialXYZT(NEUTRAL);
    XYZT u = new XYZT();
    int i = 255;
    for (; i >= 0; i--) {
      if (aSlide[i] != 0 || bSlide[i] != 0) {
        break;
      }
    }
    for (; i >= 0; i--) {
      doubleXYZ(t, new XYZ(t));
      if (aSlide[i] > 0) {
        add(t, XYZT.fromPartialXYZT(u, t), pointAArray[aSlide[i] / 2]);
      } else if (aSlide[i] < 0) {
        sub(t, XYZT.fromPartialXYZT(u, t), pointAArray[-aSlide[i] / 2]);
      }
      if (bSlide[i] > 0) {
        add(t, XYZT.fromPartialXYZT(u, t), Ed25519Constants.B2[bSlide[i] / 2]);
      } else if (bSlide[i] < 0) {
        sub(t, XYZT.fromPartialXYZT(u, t), Ed25519Constants.B2[-bSlide[i] / 2]);
      }
    }

    return new XYZ(t);
  }
Computes {@code a}*{@code pointA}+{@code b}*B
where a = a[0]+256*a[1]+...+256^31*a[31].
and b = b[0]+256*b[1]+...+256^31*b[31].
B is the Ed25519 base point (x,4/5) with x positive.

Note that execution time varies based on the input since this will only be used in verification
of signatures.
java_src/src/main/java/com/google/crypto/tink/internal/Ed25519.java