Esempio n. 1
0
		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;
		}
Esempio n. 2
0
		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);
			}
		}