Example #1
0
        public static IntegerNumber operator -(IntegerNumber number1, IntegerNumber number2)
        {
            if (number1.IsNegative != number2.IsNegative)
            {
                return(number2.IsZero ? number1 : number1 + (-number2));
            }   //when subtracting numbers with the same sign, the absolute value of the result is less than the absoulute value of each input. (number size decreases).
            IntegerNumber source1 = number1.ExtendTo(number2.Digits);
            IntegerNumber source2 = number2.ExtendTo(number1.Digits);

            ulong[] result = new ulong[source1.Digits];
            AsmX64Operations.Subtract(source1.bits, source2.bits, result, 0, result.Length);
            return(new IntegerNumber(result, false));
        }
Example #2
0
        public static bool UnitTest()
        {
            //    SPECIAL prime: 2^64 - 2^32 + 1
            //prime: 2^64 - 2^34 + 1
            //prime: 2^64 - 2^40 + 1
            //    SPECIAL prime: 2 ^ 128 - 2 ^ 54 + 1
            //prime: 2 ^ 128 - 2 ^ 108 + 1
            //prime: 2 ^ 256 - 2 ^ 168 + 1
            //prime: 2 ^ 256 - 2 ^ 174 + 1
            //prime: 2 ^ 512 - 2 ^ 32 + 1
            //prime: 2 ^ 512 - 2 ^ 288 + 1
            //    SPECIAL prime: 2 ^ 1024 - 2 ^ 142 + 1
            //    SPECIAL prime: 2 ^ 1024 - 2 ^ 226 + 1
            //prime: 2 ^ 1024 - 2 ^ 562 + 1
            //prime: 2 ^ 1024 - 2 ^ 718 + 1
            //prime: 2 ^ 1024 - 2 ^ 856 + 1
            //prime: 2 ^ 1024 - 2 ^ 880 + 1
            //prime: 2 ^ 4096 - 2 ^ 3510 + 1
            //prime: 2 ^ 4096 - 2 ^ 3708 + 1
            if ("not exec".Trim() == "exec")
            {
                StringBuilder primes = new StringBuilder();
                for (int exp = 6; exp <= 12; exp++)
                {
                    int shift = 1 << exp;
                    Parallel.For(32, shift, i =>
                    {
                        ulong[] baseValue   = new ulong[shift / 64];
                        ulong[] expValue    = new ulong[shift / 64];
                        ulong[] modulo      = new ulong[shift / 64];
                        ulong[] subtractor  = new ulong[shift / 64];
                        ulong[] one         = new ulong[shift / 64];
                        ulong[] pPlusOne    = new ulong[shift / 64];
                        subtractor[i / 64] |= 1UL << (i & 63);
                        modulo[0]           = 1UL;
                        one[0]              = 1UL;
                        AsmX64Operations.Subtract(modulo, subtractor, modulo, 0, modulo.Length);
                        modulo.CopyTo(expValue, 0);
                        modulo.CopyTo(pPlusOne, 0);
                        expValue[0]--;
                        pPlusOne[0]++;

                        int isPrime = 1;
                        for (int a = 2; a <= 128; a++)
                        {
                            one.CopyTo(baseValue, 0);
                            baseValue[0] = (ulong)a;
                            AsmX64Operations.ModularExponentiation(baseValue, expValue, modulo, modulo.Length, 5);
                            if (Enumerable.Range(0, modulo.Length).All(idx => baseValue[idx] == one[idx]) ||
                                Enumerable.Range(0, modulo.Length).All(idx => baseValue[idx] == pPlusOne[idx]))
                            {
                                continue;
                            }
                            isPrime = 0;
                            break;
                        }

                        if (isPrime != 0)
                        {
                            lock (primes)
                            {
                                primes.AppendLine("prime: 2^" + shift.ToString() + " - 2^" + i.ToString() + " + 1");
                            }
                        }
                    });
                }
                Clipboard.SetText(primes.ToString());
                System.Windows.Forms.MessageBox.Show(primes.ToString(), "message");
            }

            Random     random = new Random(1002);
            BigInteger maxx   = 0;
            BigInteger minn   = 0;
            bool       ok     = true;

            for (int i = 2; --i >= 0;)
            {
                byte[] bytes1 = new byte[112 * 8 + random.Next(32 * 8)];
                byte[] bytes2 = new byte[112 * 8 + random.Next(32 * 8)];
                random.NextBytes(bytes1);
                random.NextBytes(bytes2);

                BigInteger    n1 = new BigInteger(bytes1);
                BigInteger    n2 = new BigInteger(bytes2);
                IntegerNumber f1 = new IntegerNumber(bytes1);
                IntegerNumber f2 = new IntegerNumber(bytes2);
                if (n1.ToString() != f1.ToString())
                {
                    ok = false;
                }
                if (n2.ToString() != f2.ToString())
                {
                    ok = false;
                }

                BigInteger    a1 = n1 + n2;
                IntegerNumber a2 = f1 + f2;
                if (a1.ToString() != a2.ToString())
                {
                    ok = false;
                }

                BigInteger    s1 = n1 - n2;
                IntegerNumber s2 = f1 - f2;
                if (s1.ToString() != s2.ToString())
                {
                    ok = false;
                }

                BigInteger    m1 = n1 * n2;
                IntegerNumber m2 = f1 * f2;
                if (m1.ToString() != m2.ToString())
                {
                    ok = false;
                }

                int           shrvalue = random.Next(256) + 1;
                BigInteger    sh1      = n1 >> shrvalue;
                IntegerNumber sh2      = f1 >> shrvalue;
                if (sh1.ToString() != sh2.ToString())
                {
                    ok = false;
                }
                if ((-f1).ToString() != (-n1).ToString() || (-f2).ToString() != (-n2).ToString())
                {
                    ok = false;
                }

                int           shlvalue = random.Next(256) + 1;
                BigInteger    shl1     = n1 << shlvalue;
                IntegerNumber shl2     = f1 << shlvalue;
                if (shl1.ToString() != shl2.ToString())
                {
                    ok = false;
                }

                byte[] bytesINV = new byte[(192 + 32) * 8 + random.Next(64 * 8)];
                random.NextBytes(bytesINV);
                BigInteger    num1 = new BigInteger(bytesINV);
                IntegerNumber num2 = new IntegerNumber(bytesINV);
                if (num1.ToString() != num2.ToString())
                {
                    ok = false;
                }
                BigInteger    inv0 = (BigInteger.One << (num2.Digits * 64 * 2)) / num1;
                IntegerNumber inv1 = num2.Inverse();
                if (inv0.ToString() != inv1.ToString())
                {
                    ok = false;
                }

                byte[] bytes4 = new byte[bytes1.Length * 4];
                random.NextBytes(bytes4);
                BigInteger    n4  = new BigInteger(bytes4);
                IntegerNumber f4  = new IntegerNumber(bytes4);
                BigInteger    qb4 = n4 / n1;
                IntegerNumber qn4 = f4 / f1;
                if (qb4.ToString() != qn4.ToString())
                {
                    ok = false;
                }
                byte[] bytes3 = new byte[(bytes1.Length + bytes2.Length) & -8];
                random.NextBytes(bytes3);
                BigInteger    square1 = BigInteger.Abs(new BigInteger(bytes3));
                IntegerNumber square2 = IntegerNumber.Abs(new IntegerNumber(bytes3));
                BigInteger    root1   = square1.Sqrt();
                IntegerNumber root2   = square2.Sqrt();
                if (root1.ToString() != root2.ToString())
                {
                    ok = false;
                }
                if (!ok)
                {
                    break;
                }
            }
            return(ok);
        }
Example #3
0
        public static bool UnitTest()
        {
            //    SPECIAL prime: 2^64 - 2^32 + 1
            //prime: 2^64 - 2^34 + 1
            //prime: 2^64 - 2^40 + 1
            //    SPECIAL prime: 2 ^ 128 - 2 ^ 54 + 1
            //prime: 2 ^ 128 - 2 ^ 108 + 1
            //prime: 2 ^ 256 - 2 ^ 168 + 1
            //prime: 2 ^ 256 - 2 ^ 174 + 1
            //prime: 2 ^ 512 - 2 ^ 32 + 1
            //prime: 2 ^ 512 - 2 ^ 288 + 1
            //    SPECIAL prime: 2 ^ 1024 - 2 ^ 142 + 1
            //    SPECIAL prime: 2 ^ 1024 - 2 ^ 226 + 1
            //prime: 2 ^ 1024 - 2 ^ 562 + 1
            //prime: 2 ^ 1024 - 2 ^ 718 + 1
            //prime: 2 ^ 1024 - 2 ^ 856 + 1
            //prime: 2 ^ 1024 - 2 ^ 880 + 1
            //prime: 2 ^ 4096 - 2 ^ 3510 + 1
            //prime: 2 ^ 4096 - 2 ^ 3708 + 1
            if ("not exec".Trim() == "exec")
            {
                StringBuilder primes = new StringBuilder();
                for (int exp = 6; exp <= 12; exp++)
                {
                    int shift = 1 << exp;
                    Parallel.For(32, shift, i =>
                    {
                        ulong[] baseValue   = new ulong[shift / 64];
                        ulong[] expValue    = new ulong[shift / 64];
                        ulong[] modulo      = new ulong[shift / 64];
                        ulong[] subtractor  = new ulong[shift / 64];
                        ulong[] one         = new ulong[shift / 64];
                        ulong[] pPlusOne    = new ulong[shift / 64];
                        subtractor[i / 64] |= 1UL << (i & 63);
                        modulo[0]           = 1UL;
                        one[0]              = 1UL;
                        AsmX64Operations.Subtract(modulo, subtractor, modulo, 0, modulo.Length);
                        modulo.CopyTo(expValue, 0);
                        modulo.CopyTo(pPlusOne, 0);
                        expValue[0]--;
                        pPlusOne[0]++;

                        int isPrime = 1;
                        for (int a = 2; a <= 128; a++)
                        {
                            one.CopyTo(baseValue, 0);
                            baseValue[0] = (ulong)a;
                            AsmX64Operations.ModularExponentiation(baseValue, expValue, modulo, modulo.Length, 5);
                            if (Enumerable.Range(0, modulo.Length).All(idx => baseValue[idx] == one[idx]) ||
                                Enumerable.Range(0, modulo.Length).All(idx => baseValue[idx] == pPlusOne[idx]))
                            {
                                continue;
                            }
                            isPrime = 0;
                            break;
                        }

                        if (isPrime != 0)
                        {
                            lock (primes)
                            {
                                primes.AppendLine("prime: 2^" + shift.ToString() + " - 2^" + i.ToString() + " + 1");
                            }
                        }
                    });
                }
                Clipboard.SetText(primes.ToString());
                System.Windows.Forms.MessageBox.Show(primes.ToString(), "message");
            }

            Random random = new Random(1001);
            bool   ok     = true;

            for (int i = 400; --i >= 0;)
            {
                byte[] bytes1 = new byte[31 + random.Next(2)];
                byte[] bytes2 = new byte[31 + random.Next(2)];
                random.NextBytes(bytes1);
                random.NextBytes(bytes2);

                BigInteger  n1 = new BigInteger(bytes1);
                BigInteger  n2 = new BigInteger(bytes2);
                FastInteger f1 = new FastInteger(bytes1);
                FastInteger f2 = new FastInteger(bytes2);
                if (n1.ToString() != f1.ToString())
                {
                    ok = false;
                }
                if (n2.ToString() != f2.ToString())
                {
                    ok = false;
                }
                BigInteger  a1 = n1 + n2;
                FastInteger a2 = f1 + f2;
                if (a1.ToString() != a2.ToString())
                {
                    ok = false;
                }
                BigInteger  s1 = n1 - n2;
                FastInteger s2 = f1 - f2;
                if (s1.ToString() != s2.ToString())
                {
                    ok = false;
                }
                BigInteger  m1 = n1 * n2;
                FastInteger m2 = f1 * f2;
                if (m1.ToString() != m2.ToString())
                {
                    ok = false;
                }
                int         shrvalue = random.Next(256) + 1;
                BigInteger  sh1      = n1 >> shrvalue;
                FastInteger sh2      = f1 >> shrvalue;
                if (sh1.ToString() != sh2.ToString())
                {
                    ok = false;
                }
                if ((-f1).ToString() != (-n1).ToString() || (-f2).ToString() != (-n2).ToString())
                {
                    ok = false;
                }
                int         shlvalue = random.Next(256) + 1;
                BigInteger  shl1     = n1 << shlvalue;
                FastInteger shl2     = f1 << shlvalue;
                if (shl1.ToString() != shl2.ToString())
                {
                    ok = false;
                }
                BigInteger  and1 = n1 & n2;
                FastInteger and2 = f1 & f2;
                if (and1.ToString() != and2.ToString())
                {
                    ok = false;
                }
                BigInteger  xor1 = n1 ^ n2;
                FastInteger xor2 = f1 ^ f2;
                if (xor1.ToString() != xor2.ToString())
                {
                    ok = false;
                }

                if (!ok)
                {
                    break;
                }
            }
            return(ok);
        }