예제 #1
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);
        }
예제 #2
0
        public static bool UnitTest()
        {
            Random random = new Random(101);
            int    n      = 2048 / 64;

            ulong[] a   = new ulong[n];
            ulong[] b   = new ulong[n];
            ulong[] m   = new ulong[n];
            ulong[] am1 = new ulong[n];
            ulong[] am3 = new ulong[n];
            ulong[] c1  = new ulong[n * 2];
            ulong[] c2  = new ulong[n * 2];
            ulong[] c3  = new ulong[n * 2];
            ulong[] s0  = new ulong[n * 2];
            ulong[] s1  = new ulong[n * 2];
            ulong[] s2  = new ulong[n * 2];

            BigInteger a0, b0, m0;

            TimeSpan
                elapsedMontgomeryExpMod = TimeSpan.Zero,
                elapsedExpMod           = TimeSpan.Zero,
                elapsedBigIntegerExpMod = TimeSpan.Zero;
            bool ok = true;

            for (int iteration = 1; --iteration >= 0;)
            {
                getRandom(a, random);
                getRandom(b, random);
                getRandom(m, random); m[0] &= ulong.MaxValue - 1;
                a0 = new BigInteger(a.SelectMany(l => BitConverter.GetBytes(l)).Concat(Enumerable.Repeat((byte)0, 1)).ToArray());
                b0 = new BigInteger(b.SelectMany(l => BitConverter.GetBytes(l)).Concat(Enumerable.Repeat((byte)0, 1)).ToArray());
                m0 = new BigInteger(m.SelectMany(l => BitConverter.GetBytes(l)).Concat(Enumerable.Repeat((byte)0, 1)).ToArray());

                a.CopyTo(am1, 0);
                ExpMod(am1, b, m, n, 5);

                BigInteger am2 = BigInteger.Zero;
                elapsedBigIntegerExpMod += MeasureTime(() =>
                {
                    am2 = BigInteger.ModPow(a0, b0, m0);
                });
                var bytes1 = am1.SelectMany(l => BitConverter.GetBytes(l)).ToArray();
                var bytes2 = am2.ToByteArray();
                ok &= Enumerable.Range(0, Math.Min(bytes1.Length, bytes2.Length)).All(idx => bytes1[idx] == bytes2[idx]);
            }

            for (int iteration = 1; --iteration >= 0;)
            {
                getRandom(a, random);
                getRandom(b, random);
                getRandom(m, random); m[0] |= 1;
                a.CopyTo(am1, 0);
                a.CopyTo(am3, 0);

                elapsedMontgomeryExpMod += MeasureTime(() =>
                {
                    MontgomeryExpMod(am1, b, m, n, 6);
                });
                elapsedExpMod += MeasureTime(() =>
                {
                    ExpMod(am3, b, m, n, 5);
                });

                ok &= Enumerable.Range(0, n).All(idx => am3[idx] == am1[idx]);
            }

            TimeSpan
                elapsedMulDirect = TimeSpan.Zero,
                elapsedKaratsuba = TimeSpan.Zero;

            ulong[] temporaryKaratsubaBuffer = new ulong[GetKaratsubaMultiplicationBufferSize(n)];
            for (int iteration = 128; --iteration >= 0;)
            {
                getRandom(a, random);
                getRandom(b, random);
                AsmX64Operations.Multiply(a, a, s0, n);

                elapsedMulDirect += MeasureTime(() =>
                {
                    AsmX64Operations.Multiply(a, b, c1, n);
                    AsmX64Operations.Square(a, s1, n);
                });
                elapsedKaratsuba += MeasureTime(() =>
                {
                    AsmX64Operations.Karatsuba(a, b, c2, n, temporaryKaratsubaBuffer);
                    AsmX64Operations.KaratsubaSquare(a, s2, n, temporaryKaratsubaBuffer);
                });

                ok &= Enumerable.Range(0, n * 2).All(idx => c1[idx] == c2[idx]);
                ok &= Enumerable.Range(0, n * 2).All(idx => s0[idx] == s1[idx]);
                ok &= Enumerable.Range(0, n * 2).All(idx => s1[idx] == s2[idx]);
            }
            if (!ok)
            {
                //MessageBox.Show("not ok - error");
                return(false);
            }
            //MessageBox.Show(
            //    "elapsedMontgomeryExpMod: " + elapsedMontgomeryExpMod.ToString() + "\r\n" +
            //    "elapsedExpMod: " + elapsedExpMod.ToString() + "\r\n" +
            //    "elapsedBigIntegerExpMod: " + elapsedBigIntegerExpMod.ToString() + "\r\n" +
            //    "normal: " + elapsedMulDirect.ToString() + "  karatsuba: " + elapsedKaratsuba.ToString());
            return(true);
        }
예제 #3
0
    private string SHA2_Core(byte[] payload_bytes, ulong[] init, ulong[] constants, int[] sums, int[] sigmas, ulong size_mask, int word_size, int chunk_modulo, int appended_length, int round_count, string output_format, int output_segments)
    {
        int word_bytes = word_size / 8;

        // Working variables h0->h7
        ulong[] working_variables = new ulong[8];
        init.CopyTo(working_variables, 0);

        byte[]  input            = new byte[chunk_modulo];
        ulong[] message_schedule = new ulong[round_count];

        // Each 64-byte/512-bit chunk
        // 64 bits/8 bytes are required at the end for the bit size
        for (int chunk_index = 0; chunk_index < payload_bytes.Length + appended_length + 1; chunk_index += chunk_modulo)
        {
            int chunk_size     = Mathf.Min(chunk_modulo, payload_bytes.Length - chunk_index);
            int schedule_index = 0;

            // Buffer message
            for (; schedule_index < chunk_size; ++schedule_index)
            {
                input[schedule_index] = payload_bytes[chunk_index + schedule_index];
            }
            // Append a 1-bit if not an even chunk
            if (schedule_index < chunk_modulo && chunk_size >= 0)
            {
                input[schedule_index++] = 0b10000000;
            }
            // Pad with zeros until the end
            for (; schedule_index < chunk_modulo; ++schedule_index)
            {
                input[schedule_index] = 0x00;
            }
            // If the chunk is less than 56 bytes, this will be the final chunk containing the data size in bits
            if (chunk_size < chunk_modulo - appended_length)
            {
                ulong bit_size = (ulong)payload_bytes.Length * 8ul;
                input[chunk_modulo - 1] = Convert.ToByte((bit_size >> 0x00) & 0xFFul);
                input[chunk_modulo - 2] = Convert.ToByte((bit_size >> 0x08) & 0xFFul);
                input[chunk_modulo - 3] = Convert.ToByte((bit_size >> 0x10) & 0xFFul);
                input[chunk_modulo - 4] = Convert.ToByte((bit_size >> 0x18) & 0xFFul);
                input[chunk_modulo - 5] = Convert.ToByte((bit_size >> 0x20) & 0xFFul);
                input[chunk_modulo - 6] = Convert.ToByte((bit_size >> 0x28) & 0xFFul);
                input[chunk_modulo - 7] = Convert.ToByte((bit_size >> 0x30) & 0xFFul);
                input[chunk_modulo - 8] = Convert.ToByte((bit_size >> 0x38) & 0xFFul);
            }

            // Copy into w[0..15]
            int copy_index = 0;
            for (; copy_index < 16; copy_index++)
            {
                message_schedule[copy_index] = 0ul;
                for (int i = 0; i < word_bytes; i++)
                {
                    message_schedule[copy_index] = (message_schedule[copy_index] << 8) | input[(copy_index * word_bytes) + i];
                }

                message_schedule[copy_index] = message_schedule[copy_index] & size_mask;
            }
            // Extend
            for (; copy_index < round_count; copy_index++)
            {
                ulong s0_read = message_schedule[copy_index - 15];
                ulong s1_read = message_schedule[copy_index - 2];

                message_schedule[copy_index] = (
                    message_schedule[copy_index - 16] +
                    (((s0_read >> sums[0]) | (s0_read << word_size - sums[0])) ^ ((s0_read >> sums[1]) | (s0_read << word_size - sums[1])) ^ (s0_read >> sums[2])) + // s0
                    message_schedule[copy_index - 7] +
                    (((s1_read >> sums[3]) | (s1_read << word_size - sums[3])) ^ ((s1_read >> sums[4]) | (s1_read << word_size - sums[4])) ^ (s1_read >> sums[5]))   // s1
                    ) & size_mask;
            }

            // temp vars
            ulong temp1, temp2;
            // work is equivalent to a, b, c, d, e, f, g, h
            // This copies work from h0, h1, h2, h3, h4, h5, h6, h7
            ulong[] work = new ulong[8];
            working_variables.CopyTo(work, 0);

            // Compression function main loop
            for (copy_index = 0; copy_index < round_count; copy_index++)
            {
                ulong ep1 = ((work[4] >> sigmas[3]) | (work[4] << word_size - sigmas[3])) ^ ((work[4] >> sigmas[4]) | (work[4] << word_size - sigmas[4])) ^ ((work[4] >> sigmas[5]) | (work[4] << word_size - sigmas[5]));
                ulong ch  = (work[4] & work[5]) ^ ((size_mask ^ work[4]) & work[6]);
                ulong ep0 = ((work[0] >> sigmas[0]) | (work[0] << word_size - sigmas[0])) ^ ((work[0] >> sigmas[1]) | (work[0] << word_size - sigmas[1])) ^ ((work[0] >> sigmas[2]) | (work[0] << word_size - sigmas[2]));
                ulong maj = (work[0] & work[1]) ^ (work[0] & work[2]) ^ (work[1] & work[2]);
                temp1   = work[7] + ep1 + ch + constants[copy_index] + message_schedule[copy_index];
                temp2   = ep0 + maj;
                work[7] = work[6];
                work[6] = work[5];
                work[5] = work[4];
                work[4] = (work[3] + temp1) & size_mask;
                work[3] = work[2];
                work[2] = work[1];
                work[1] = work[0];
                work[0] = (temp1 + temp2) & size_mask;
            }

            for (copy_index = 0; copy_index < 8; copy_index++)
            {
                working_variables[copy_index] = (working_variables[copy_index] + work[copy_index]) & size_mask;
            }
        }

        // Finalization
        string output = "";

        for (int character_index = 0; character_index < output_segments; character_index++)
        {
            output += string.Format(output_format, working_variables[character_index]);
        }

        return(output);
    }
예제 #4
0
    private string SHA1_Core(byte[] payload_bytes, ulong[] init, ulong size_mask, int word_size, int chunk_modulo, int appended_length, int left_rotations, int round_count, string output_format, int output_segments)
    {
        int word_bytes = word_size / 8;

        // Working variables h0->h4
        ulong[] working_variables = new ulong[5];
        init.CopyTo(working_variables, 0);

        byte[]  input            = new byte[chunk_modulo];
        ulong[] message_schedule = new ulong[round_count];

        // Each 64-byte/512-bit chunk
        // 64 bits/8 bytes are required at the end for the bit size
        for (int chunk_index = 0; chunk_index < payload_bytes.Length + appended_length + 1; chunk_index += chunk_modulo)
        {
            int chunk_size     = Mathf.Min(chunk_modulo, payload_bytes.Length - chunk_index);
            int schedule_index = 0;

            // Buffer message
            for (; schedule_index < chunk_size; ++schedule_index)
            {
                input[schedule_index] = payload_bytes[chunk_index + schedule_index];
            }
            // Append a 1-bit if not an even chunk
            if (schedule_index < chunk_modulo && chunk_size >= 0)
            {
                input[schedule_index++] = 0b10000000;
            }
            // Pad with zeros until the end
            for (; schedule_index < chunk_modulo; ++schedule_index)
            {
                input[schedule_index] = 0x00;
            }
            // If the chunk is less than 56 bytes, this will be the final chunk containing the data size in bits
            if (chunk_size < chunk_modulo - appended_length)
            {
                ulong bit_size = (ulong)payload_bytes.Length * 8ul;
                input[chunk_modulo - 1] = Convert.ToByte((bit_size >> 0x00) & 0xFFul);
                input[chunk_modulo - 2] = Convert.ToByte((bit_size >> 0x08) & 0xFFul);
                input[chunk_modulo - 3] = Convert.ToByte((bit_size >> 0x10) & 0xFFul);
                input[chunk_modulo - 4] = Convert.ToByte((bit_size >> 0x18) & 0xFFul);
                input[chunk_modulo - 5] = Convert.ToByte((bit_size >> 0x20) & 0xFFul);
                input[chunk_modulo - 6] = Convert.ToByte((bit_size >> 0x28) & 0xFFul);
                input[chunk_modulo - 7] = Convert.ToByte((bit_size >> 0x30) & 0xFFul);
                input[chunk_modulo - 8] = Convert.ToByte((bit_size >> 0x38) & 0xFFul);
            }

            // Copy into w[0..15]
            int copy_index = 0;
            for (; copy_index < 16; copy_index++)
            {
                message_schedule[copy_index] = 0ul;
                for (int i = 0; i < word_bytes; i++)
                {
                    message_schedule[copy_index] = (message_schedule[copy_index] << 8) | input[(copy_index * word_bytes) + i];
                }

                message_schedule[copy_index] = message_schedule[copy_index] & size_mask;
            }
            // Extend
            for (; copy_index < round_count; copy_index++)
            {
                ulong w = message_schedule[copy_index - 3] ^ message_schedule[copy_index - 8] ^ message_schedule[copy_index - 14] ^ message_schedule[copy_index - 16];
                message_schedule[copy_index] = (
                    (w << left_rotations) | (w >> word_size - left_rotations)
                    ) & size_mask;
            }

            // temp vars
            ulong temp, k, f;
            // work is equivalent to a, b, c, d, e
            // This copies work from h0, h1, h2, h3, h4
            ulong[] work = new ulong[5];
            working_variables.CopyTo(work, 0);

            // Compression function main loop
            for (copy_index = 0; copy_index < round_count; copy_index++)
            {
                if (copy_index < 20)
                {
                    f = ((work[1] & work[2]) | ((size_mask ^ work[1]) & work[3])) & size_mask;
                    k = 0x5A827999;
                }
                else if (copy_index < 40)
                {
                    f = work[1] ^ work[2] ^ work[3];
                    k = 0x6ED9EBA1;
                }
                else if (copy_index < 60)
                {
                    f = (work[1] & work[2]) ^ (work[1] & work[3]) ^ (work[2] & work[3]);
                    k = 0x8F1BBCDC;
                }
                else
                {
                    f = work[1] ^ work[2] ^ work[3];
                    k = 0xCA62C1D6;
                }

                temp    = (((work[0] << 5) | (work[0] >> word_size - 5)) + f + work[4] + k + message_schedule[copy_index]) & size_mask;
                work[4] = work[3];
                work[3] = work[2];
                work[2] = ((work[1] << 30) | (work[1] >> word_size - 30)) & size_mask;
                work[1] = work[0];
                work[0] = temp;
            }

            for (copy_index = 0; copy_index < 5; copy_index++)
            {
                working_variables[copy_index] = (working_variables[copy_index] + work[copy_index]) & size_mask;
            }
        }

        // Finalization
        string output = "";

        for (int character_index = 0; character_index < output_segments; character_index++)
        {
            output += string.Format(output_format, working_variables[character_index]);
        }

        return(output);
    }
예제 #5
0
    private string MD5_Core(byte[] payload_bytes, ulong[] init, ulong[] constants, int[] shifts, ulong size_mask, int word_size, int chunk_modulo, int appended_length, int round_count, string output_format, int output_segments)
    {
        int word_bytes = word_size / 8;

        // Working variables a0->d0
        ulong[] working_variables = new ulong[4];
        init.CopyTo(working_variables, 0);

        byte[]  input            = new byte[chunk_modulo];
        ulong[] message_schedule = new ulong[16];

        // Each 64-byte/512-bit chunk
        // 64 bits/8 bytes are required at the end for the bit size
        for (int chunk_index = 0; chunk_index < payload_bytes.Length + appended_length + 1; chunk_index += chunk_modulo)
        {
            int chunk_size     = Mathf.Min(chunk_modulo, payload_bytes.Length - chunk_index);
            int schedule_index = 0;

            // Buffer message
            for (; schedule_index < chunk_size; ++schedule_index)
            {
                input[schedule_index] = payload_bytes[chunk_index + schedule_index];
            }
            // Append a 1-bit if not an even chunk
            if (schedule_index < chunk_modulo && chunk_size >= 0)
            {
                input[schedule_index++] = 0b10000000;
            }
            // Pad with zeros until the end
            for (; schedule_index < chunk_modulo; ++schedule_index)
            {
                input[schedule_index] = 0x00;
            }
            // If the chunk is less than 56 bytes, this will be the final chunk containing the data size in bits
            if (chunk_size < chunk_modulo - appended_length)
            {
                ulong bit_size = (ulong)payload_bytes.Length * 8ul;
                input[chunk_modulo - 8] = Convert.ToByte((bit_size >> 0x00) & 0xFFul);
                input[chunk_modulo - 7] = Convert.ToByte((bit_size >> 0x08) & 0xFFul);
                input[chunk_modulo - 6] = Convert.ToByte((bit_size >> 0x10) & 0xFFul);
                input[chunk_modulo - 5] = Convert.ToByte((bit_size >> 0x18) & 0xFFul);
                input[chunk_modulo - 4] = Convert.ToByte((bit_size >> 0x20) & 0xFFul);
                input[chunk_modulo - 3] = Convert.ToByte((bit_size >> 0x28) & 0xFFul);
                input[chunk_modulo - 2] = Convert.ToByte((bit_size >> 0x30) & 0xFFul);
                input[chunk_modulo - 1] = Convert.ToByte((bit_size >> 0x38) & 0xFFul);
            }

            // Copy into w[0..15]
            int copy_index = 0;
            for (; copy_index < 16; copy_index++)
            {
                message_schedule[copy_index] = 0ul;
                for (int i = 0; i < word_bytes; i++)
                {
                    message_schedule[copy_index] = message_schedule[copy_index] | ((ulong)input[(copy_index * word_bytes) + i] << (i * 8));
                }

                message_schedule[copy_index] = message_schedule[copy_index] & size_mask;
            }

            // temp vars
            ulong f, g;
            // work is equivalent to A, B, C, D
            // This copies work from a0, b0, c0, d0
            ulong[] work = new ulong[4];
            working_variables.CopyTo(work, 0);

            // Compression function main loop
            for (copy_index = 0; copy_index < round_count; copy_index++)
            {
                if (copy_index < 16)
                {
                    f = ((work[1] & work[2]) | ((size_mask ^ work[1]) & work[3])) & size_mask;
                    g = (ulong)copy_index;
                }
                else if (copy_index < 32)
                {
                    f = ((work[3] & work[1]) | ((size_mask ^ work[3]) & work[2])) & size_mask;
                    g = (ulong)(((5 * copy_index) + 1) % 16);
                }
                else if (copy_index < 48)
                {
                    f = work[1] ^ work[2] ^ work[3];
                    g = (ulong)(((3 * copy_index) + 5) % 16);
                }
                else
                {
                    f = (work[2] ^ (work[1] | (size_mask ^ work[3]))) & size_mask;
                    g = (ulong)(7 * copy_index % 16);
                }

                f       = (f + work[0] + constants[copy_index] + message_schedule[g]) & size_mask;
                work[0] = work[3];
                work[3] = work[2];
                work[2] = work[1];
                work[1] = (work[1] + ((f << shifts[copy_index]) | (f >> word_size - shifts[copy_index]))) & size_mask;
            }

            for (copy_index = 0; copy_index < 4; copy_index++)
            {
                working_variables[copy_index] = (working_variables[copy_index] + work[copy_index]) & size_mask;
            }
        }

        // Finalization
        string output = "";

        for (int character_index = 0; character_index < output_segments; character_index++)
        {
            ulong value = working_variables[character_index];
            output += string.Format(output_format,
                                    ((value & 0x000000FFul) << 0x18) |
                                    ((value & 0x0000FF00ul) << 0x08) |
                                    ((value & 0x00FF0000ul) >> 0x08) |
                                    ((value & 0xFF000000ul) >> 0x18)
                                    );
        }

        return(output);
    }
예제 #6
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);
        }
예제 #7
0
파일: Utils.cs 프로젝트: richardhallett/Fe
        public static void RadixSort64 <T>(ulong[] keys, T[] values, int length)
        {
            // Base 10 Radix Sort
            const int radix = 10;

            // Find the largest number in all the keys
            ulong maxValue = 0;

            for (int i = 0; i < keys.Length; i++)
            {
                var num = keys[i];
                if (num > maxValue)
                {
                    maxValue = num;
                }
            }

            // Buckets to hold the indexes back to the keys array
            int[][] buckets = new int[radix][];
            for (int i = 0; i < radix; i++)
            {
                buckets[i] = new int[length];
            }

            int[] counts = new int[radix]; // The number of key indices stored in each bucket

            // Temporary arrays used to copy after we've sorted
            ulong[] tmpKeys   = new ulong[length];
            T[]     tmpValues = new T[length];

            int    exp   = 1;
            double place = 1;

            // Repeat until we hit max places of the max value.
            while (place <= maxValue)
            {
                // For every key, put the index next to it's LSD
                var  prevKey = keys[0];
                bool sorted  = true;

                for (int i = 0; i < length; i++)
                {
                    var key = keys[i];
                    sorted &= (prevKey <= key);
                    int digit = (int)(keys[i] / place % radix);

                    // Store the key index
                    buckets[digit][counts[digit]] = i;

                    // Increase bucket count
                    counts[digit]++;

                    prevKey = key;
                }

                if (sorted)
                {
                    break;
                }

                // For each bucket take the keys and fill keys/values
                int keyIndex = 0;
                for (int i = 0; i < buckets.Length; i++)
                {
                    var bucket = buckets[i];
                    for (int j = 0; j < counts[i]; j++)
                    {
                        int bucketKey = bucket[j];
                        tmpKeys[keyIndex]   = keys[bucketKey];
                        tmpValues[keyIndex] = values[bucketKey];
                        keyIndex++;
                    }

                    // Reset counter for the bucket
                    counts[i] = 0;
                }

                tmpKeys.CopyTo(keys, 0);
                tmpValues.CopyTo(values, 0);

                // Calculate the places
                place = Math.Pow(radix, exp);
                exp  += 1;
            }
        }