public static void Half(uint[] x, uint[] z) { if ((x[0] & 1) == 0) { Nat.ShiftDownBit(7, x, 0, z); } else { uint c = Nat224.Add(x, P, z); Nat.ShiftDownBit(7, z, c); } }
public static void Half(uint[] x, uint[] z) { if ((x[0] & 1) == 0) { Nat.ShiftDownBit(8, x, 0, z); } else { Nat256.Add(x, P, z); Nat.ShiftDownBit(8, z, 0); } }
private static void ScalarMultBase(byte[] k, PointAccum r) { Precompute(); PointSetNeutral(r); uint[] n = new uint[ScalarUints]; DecodeScalar(k, 0, n); // Recode the scalar into signed-digit form, then group comb bits in each block { uint c1 = Nat.CAdd(ScalarUints, ~(int)n[0] & 1, n, L, n); Debug.Assert(c1 == 0); uint c2 = Nat.ShiftDownBit(ScalarUints, n, 1U); Debug.Assert(c2 == (1U << 31)); for (int i = 0; i < ScalarUints; ++i) { n[i] = Interleave.Shuffle2(n[i]); } } PointPrecomp p = new PointPrecomp(); int cOff = (PrecompSpacing - 1) * PrecompTeeth; for (; ;) { for (int b = 0; b < PrecompBlocks; ++b) { uint w = n[b] >> cOff; int sign = (int)(w >> (PrecompTeeth - 1)) & 1; int abs = ((int)w ^ -sign) & PrecompMask; Debug.Assert(sign == 0 || sign == 1); Debug.Assert(0 <= abs && abs < PrecompPoints); PointLookup(b, abs, p); X25519Field.CSwap(sign, p.ypx_h, p.ymx_h); X25519Field.CNegate(sign, p.xyd); PointAddPrecomp(p, r); } if ((cOff -= PrecompTeeth) < 0) { break; } PointDouble(r); } }
private static void ScalarMult(byte[] k, PointAffine p, PointAccum r) { uint[] n = new uint[ScalarUints]; DecodeScalar(k, 0, n); Debug.Assert(0U == (n[0] & 7)); Debug.Assert(1U == n[ScalarUints - 1] >> 30); Nat.ShiftDownBits(ScalarUints, n, 3, 1U); // Recode the scalar into signed-digit form { uint c1 = Nat.CAdd(ScalarUints, ~(int)n[0] & 1, n, L, n); Debug.Assert(c1 == 0U); uint c2 = Nat.ShiftDownBit(ScalarUints, n, 0U); Debug.Assert(c2 == (1U << 31)); } Debug.Assert(1U == n[ScalarUints - 1] >> 28); int[] table = PointPrecompute(p, 8); PointExt q = new PointExt(); // Replace first 4 doublings (2^4 * P) with 1 addition (P + 15 * P) PointCopy(p, r); PointLookup(table, 7, q); PointAdd(q, r); int w = 62; for (;;) { PointLookup(n, w, table, q); PointAdd(q, r); PointDouble(r); PointDouble(r); PointDouble(r); if (--w < 0) { break; } PointDouble(r); } }
private static void ScalarMult(byte[] k, PointExt p, PointExt r) { uint[] n = new uint[ScalarUints]; DecodeScalar(k, 0, n); Debug.Assert(0U == (n[0] & 3)); Debug.Assert(1U == n[ScalarUints - 1] >> 31); Nat.ShiftDownBits(ScalarUints, n, 2, 0U); // Recode the scalar into signed-digit form { uint c1 = Nat.CAdd(ScalarUints, ~(int)n[0] & 1, n, L, n); Debug.Assert(c1 == 0U); uint c2 = Nat.ShiftDownBit(ScalarUints, n, 1U); Debug.Assert(c2 == (1U << 31)); } uint[] table = PointPrecompute(p, 8); PointExt q = new PointExt(); PointLookup(n, 111, table, r); for (int w = 110; w >= 0; --w) { for (int i = 0; i < 4; ++i) { PointDouble(r); } PointLookup(n, w, table, q); PointAdd(q, r); } for (int i = 0; i < 2; ++i) { PointDouble(r); } }