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); }
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); }
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); }
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); }
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); }
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); }
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; } }