Example #1
0
            private void Reduce(MutableInteger z)
            {
                // var qhat = (z >> (bLength * (k - 1))) * mu >> (bLength * (k + 1));
                var reg1 = store.Allocate().Set(z);

                reg1.RightShift(bToTheKMinusOneLength);
#if false
                var reg2.store.Allocate().SetProductShifted(reg1, muRep, bToTheKPlusOneLength);
#else
                var reg2 = store.Allocate().SetProduct(reg1, muRep);
                reg2.RightShift(bToTheKPlusOneLength);
#endif
                // var r = z % bToTheKPlusOne - qhat * p % bToTheKPlusOne;
                z.Mask(bToTheKPlusOneLength);
#if true
                reg1.SetProductMasked(reg2, pRep, bToTheKPlusOneLength);
#else
                reg1.SetProduct(reg2, pRep);
                reg1.Mask(bToTheKPlusOneLength);
#endif
                // if (r.Sign == -1) r += bToTheKPlusOne;
                if (z < reg1)
                {
                    z.SetBit(bToTheKPlusOneLength, true);
                }
                z.Subtract(reg1);
                // while (r >= p) r -= p;
                while (z >= pRep)
                {
                    z.Subtract(pRep);
                }
                store.Release(reg1);
                store.Release(reg2);
            }
        public static MutableInteger SetModularInversePowerOfTwoModulus(this MutableInteger c, MutableInteger d, int n, MutableIntegerStore store)
        {
            // See 9.2 in: http://gmplib.org/~tege/divcnst-pldi94.pdf
            c.Set(d);
            var two  = store.Allocate().Set(2);
            var reg1 = store.Allocate();
            var reg2 = store.Allocate();

            for (int m = 3; m < n; m *= 2)
            {
                reg1.Set(c);
                reg2.SetProduct(reg1, d);
                reg2.Mask(n);
                reg2.SetDifference(two, reg2);
                c.SetProduct(reg1, reg2);
                c.Mask(n);
            }
            if (c.Sign == -1)
            {
                c.Add(reg1.Set(1).LeftShift(n));
            }
            store.Release(two);
            store.Release(reg1);
            store.Release(reg2);
            return(c);
        }