public virtual Number Pow (Number x, Number y) { if (y.IsZero ()) return ToElement (Number.One); if (y.IsOne ()) return x; Number a = x; Number b = ToElement (Number.One); if (y.GetBit (0) == 1) b = a; for (int i = 1; i < y.BitCount (); i ++) { a = Multiply (a, a); if (y.GetBit (i) == 1) b = Multiply (a, b); } return b; }
public override unsafe Number Multiply (Number x, Number y) { if (x.IsZero () || y.IsZero ()) return Number.Zero; if (x.length < y.length) { Number swap = x; x = y; y = swap; } uint[] z = new uint[mod.length + 1]; fixed (uint* px = x.data, py = y.data, pz = z, pp = mod.data) { uint y0 = py[0]; int i = 0; for (; i < x.length; i++) { uint u = (uint)((pz[0] + px[i] * y0) * invMod); uint xi = px[i]; ulong carry1 = ((ulong)xi) * ((ulong)py[0]); ulong carry2 = ((ulong)u) * ((ulong)pp[0]); ulong carry = (((ulong)(uint)carry1) + ((ulong)(uint)carry2) + ((ulong)pz[0])) >> 32; carry1 >>= 32; carry2 >>= 32; int k = 1; for (; k < y.length; k++) { carry1 += ((ulong)xi) * ((ulong)py[k]); carry2 += ((ulong)u) * ((ulong)pp[k]); carry += ((ulong)(uint)carry1) + ((ulong)(uint)carry2) + ((ulong)pz[k]); pz[k - 1] = (uint)carry; carry >>= 32; carry1 >>= 32; carry2 >>= 32; } for (; carry1 != 0 && k < mod.length; k++) { carry2 += ((ulong)u) * ((ulong)pp[k]); carry += ((ulong)(uint)carry1) + ((ulong)(uint)carry2) + ((ulong)pz[k]); pz[k - 1] = (uint)carry; carry >>= 32; carry1 >>= 32; carry2 >>= 32; } for (; k < mod.length; k++) { carry2 += ((ulong)u) * ((ulong)pp[k]); carry += ((ulong)(uint)carry2) + ((ulong)pz[k]); pz[k - 1] = (uint)carry; carry >>= 32; carry2 >>= 32; } carry += carry1 + carry2 + ((ulong)pz[k]); pz[k - 1] = (uint)carry; pz[k] = (uint)(carry >> 32); } for (; i < mod.length; i++) { uint u = (uint)(pz[0] * invMod); ulong carry = (((ulong)u) * ((ulong)pp[0]) + ((ulong)pz[0])) >> 32; int k = 1; for (; k < mod.length; k++) { carry += ((ulong)u) * ((ulong)pp[k]) + ((ulong)pz[k]); pz[k - 1] = (uint)carry; carry >>= 32; } carry += ((ulong)pz[k]); pz[k - 1] = (uint)carry; pz[k] = (uint)(carry >> 32); } if (pz[mod.length] != 0 || Number.Compare (z, mod.length, mod.data, mod.length) >= 0) return new Number (z, Number.Subtract (pz, z.Length, pp, mod.length, pz)); return new Number (z); } }