GeDoubleScalarMultVartime function

void GeDoubleScalarMultVartime(
  1. ProjectiveGroupElement r,
  2. Uint8List a,
  3. ExtendedGroupElement A,
  4. Uint8List b,
)

GeDoubleScalarMultVartime sets r = aA + bB where a = a0+256a1+...+256^31 a31. and b = b0+256b1+...+256^31 b31. B is the Ed25519 base point (x,4/5) with x positive.

Implementation

void GeDoubleScalarMultVartime(ProjectiveGroupElement r, Uint8List a,
    ExtendedGroupElement A, Uint8List b) {
  var aSlide = Int8List(256);
  var bSlide = Int8List(256);
  var Ai = List.generate(
      8, (index) => CachedGroupElement()); // A,3A,5A,7A,9A,11A,13A,15A
  var t = CompletedGroupElement();
  var u = ExtendedGroupElement();
  var A2 = ExtendedGroupElement();
  int i;

  slide(aSlide, a);
  slide(bSlide, b);

  A.ToCached(Ai[0]);
  A.Double(t);
  t.ToExtended(A2);

  for (i = 0; i < 7; i++) {
    geAdd(t, A2, Ai[i]);
    t.ToExtended(u);
    u.ToCached(Ai[i + 1]);
  }

  r.Zero();

  for (i = 255; i >= 0; i--) {
    if (aSlide[i] != 0 || bSlide[i] != 0) {
      break;
    }
  }

  for (; i >= 0; i--) {
    r.Double(t);

    if (aSlide[i] > 0) {
      t.ToExtended(u);
      geAdd(t, u, Ai[aSlide[i] ~/ 2]);
    } else if (aSlide[i] < 0) {
      t.ToExtended(u);
      geSub(t, u, Ai[(-aSlide[i]) ~/ 2]);
    }

    if (bSlide[i] > 0) {
      t.ToExtended(u);
      geMixedAdd(t, u, bi[bSlide[i] ~/ 2]);
    } else if (bSlide[i] < 0) {
      t.ToExtended(u);
      geMixedSub(t, u, bi[(-bSlide[i]) ~/ 2]);
    }

    t.ToProjective(r);
  }
}