public static UInt128 PowModP_r(UInt128 a, UInt128 b) { UInt128 half_b = new UInt128(b); if (b._high == 0 && b._low == 1) { return(new UInt128(a)); } half_b.Rshift(); UInt128 t = PowModP_r(a, half_b); t = MulModP(t, t); if (b.IsOdd()) { t = MulModP(t, a); } return(t); }
public static UInt128 MulModP(UInt128 _a, UInt128 _b) { UInt128 r = new UInt128(0, 0); UInt128 a = new UInt128(_a); UInt128 b = new UInt128(_b); while (!b.IsEmpty()) { if (b.IsOdd()) { UInt128 t = sub(P, a); if (Compare(r, t) >= 0) { r = sub(r, t); } else { r = Add(r, a); } } UInt128 double_a = new UInt128(a); double_a.lshift(); UInt128 P_a = sub(P, a); if (Compare(a, P_a) >= 0) { a = Add(double_a, INVERT_P); } else { a = double_a; } b.Rshift(); } return(r); }