public static void ScalarMultBase(byte[] k, int kOff, byte[] r, int rOff) { Precompute(); uint[] n = new uint[14]; DecodeScalar(k, kOff, n); uint[] x0 = X448Field.Create(); uint[] x1 = X448Field.Create(); X448Field.Copy(S_x, 0, x1, 0); uint[] z1 = X448Field.Create(); z1[0] = 1; uint[] x2 = X448Field.Create(); X448Field.Copy(PsubS_x, 0, x2, 0); uint[] z2 = X448Field.Create(); z2[0] = 1; uint[] A = X448Field.Create(); uint[] B = z1; uint[] C = x0; uint[] D = x1; uint[] E = B; Debug.Assert(n[13] >> 31 == 1U); int off = 0, bit = 2, swap = 1; do { X448Field.Copy(precompBase, off, x0, 0); off += X448Field.Size; int word = bit >> 5, shift = bit & 0x1F; int kt = (int)(n[word] >> shift) & 1; swap ^= kt; X448Field.CSwap(swap, x1, x2); X448Field.CSwap(swap, z1, z2); swap = kt; //X448Field.Apm(x1, z1, A, B); X448Field.Add(x1, z1, A); X448Field.Sub(x1, z1, B); X448Field.Mul(x0, B, C); X448Field.Carry(A); //X448Field.Apm(A, C, D, E); X448Field.Add(A, C, D); X448Field.Sub(A, C, E); X448Field.Sqr(D, D); X448Field.Sqr(E, E); X448Field.Mul(z2, D, x1); X448Field.Mul(x2, E, z1); }while (++bit < 448); Debug.Assert(swap == 1); for (int i = 0; i < 2; ++i) { PointDouble(x1, z1); } X448Field.Inv(z1, z1); X448Field.Mul(x1, z1, x1); X448Field.Normalize(x1); X448Field.Encode(x1, r, rOff); }