コード例 #1
0
        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);
        }
コード例 #2
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);
            }
コード例 #3
0
        public static MutableInteger SetGreatestCommonDivisor(this MutableInteger c, MutableInteger a, MutableInteger b, MutableIntegerStore store)
        {
            var reg1 = store.Allocate();

            if (a.IsZero)
            {
                c.Set(b);
            }
            else if (b.IsZero)
            {
                c.Set(a);
            }
            else
            {
                reg1.Set(a);
                c.Set(b);
                while (true)
                {
                    reg1.Modulo(c);
                    if (reg1.IsZero)
                    {
                        break;
                    }
                    c.Modulo(reg1);
                    if (c.IsZero)
                    {
                        c.Set(reg1);
                        break;
                    }
                }
            }
            store.Release(reg1);
            return(c);
        }
コード例 #4
0
 public Reducer(MutableIntegerReduction reduction, BigInteger n)
     : base(reduction, n)
 {
     length = (n.GetBitLength() + 31) / 32 * 2 + 1;
     store  = new MutableIntegerStore(length);
     nRep   = store.Allocate();
     nRep.Set(n);
 }
コード例 #5
0
        public static MutableInteger SetModularInverse(this MutableInteger c, MutableInteger a, MutableInteger b, MutableIntegerStore store)
        {
            var p         = store.Allocate().Set(a);
            var q         = store.Allocate().Set(b);
            var x0        = store.Allocate().Set(1);
            var x1        = store.Allocate().Set(0);
            var quotient  = store.Allocate();
            var remainder = store.Allocate();
            var product   = store.Allocate();

            while (!q.IsZero)
            {
                remainder.Set(p).ModuloWithQuotient(q, quotient);
                var tmpp = p;
                p = q;
                q = tmpp.Set(remainder);
                var tmpx = x1;
                x1 = x0.Subtract(product.SetProduct(quotient, x1));
                x0 = tmpx;
            }
            c.Set(x0);
            if (c.Sign == -1)
            {
                c.Add(b);
            }

            store.Release(p);
            store.Release(q);
            store.Release(x0);
            store.Release(x1);
            store.Release(quotient);
            store.Release(remainder);
            return(c);
        }
コード例 #6
0
            public Reducer(IReductionAlgorithm <BigInteger> reduction, BigInteger p)
            {
                this.reduction = reduction;
                this.p         = p;
                bLength        = 32;
                b = BigInteger.One << bLength;
                var pLength = p.GetBitLength();

                k  = (pLength - 1) / bLength + 1;
                mu = BigInteger.Pow(b, 2 * k) / p;

                var muLength = mu.GetBitLength();

                length = (pLength + 31) / 32 * 2 + (muLength + 31) / 32;
                store  = new MutableIntegerStore(length);
                muRep  = store.Allocate();
                pRep   = store.Allocate();
                muRep.Set(mu);
                pRep.Set(p);
                bToTheKMinusOneLength = bLength * (k - 1);
                bToTheKPlusOneLength  = bLength * (k + 1);
            }
コード例 #7
0
            public Reducer(BigIntegerMontgomeryReduction reduction, BigInteger modulus)
                : base(reduction, modulus)
            {
                if (modulus.IsEven)
                {
                    throw new InvalidOperationException("not relatively prime");
                }
                var rLength = (modulus.GetBitLength() + 31) / 32 * 32;

                length = (int)(2 * rLength / 32 + 1);
                store  = new MutableIntegerStore(length);
                nRep   = store.Allocate().Set(modulus);
                var rRep = store.Allocate().Set(1).LeftShift((int)rLength);
                var nInv = store.Allocate().SetModularInversePowerOfTwoModulus(nRep, (int)rLength, store);
                var kRep = store.Allocate().Set(rRep).Subtract(nInv);

                k0 = kRep.LeastSignificantWord;
                rSquaredModNRep = store.Allocate().SetSquare(rRep).Modulo(nRep);
                oneRep          = store.Allocate().Set(1).Multiply(rSquaredModNRep, store);
                store.Release(rRep);
                store.Release(nInv);
                store.Release(kRep);
                Reduce(oneRep);
            }