//формирование цифровой подписи. public string GenDs(byte[] h, BigInteger d) { var a = new BigInteger(h); BigInteger e = a % _n; if (e == 0) { e = 1; } var k = new BigInteger(); BigInteger r; BigInteger s; do { do { k.genRandomBits(_n.bitCount(), new Random()); }while (k < 0 || k > _n); var c = EcPoint.Multiply(_g, k); r = c.X % _n; s = (r * d + k * e) % _n; }while (r == 0 || s == 0); string rvector = Padding(r.ToHexString(), _n.bitCount() / 4); string svector = Padding(s.ToHexString(), _n.bitCount() / 4); return(rvector + svector); }
/** * Determine if this value can be represented as a long without truncation. * * @return true if this value fits in a long, false otherwise. */ public bool isLong() { // To just chech this.bigVal is a wee bit to simple, since // there just might have be a mean bignum that arrived on // a stream, and was a long disguised as more than 8 byte integer. if (!BigIntegerIsNull(bigVal)) { return(bigVal.bitCount() < 64); } return(true); }
/// <summary> /// Probabilistic prime test based on Rabin-Miller's test /// </summary> /// <param name="bi" type="BigInteger.BigInteger"> /// <para> /// The number to test. /// </para> /// </param> /// <param name="confidence" type="int"> /// <para> /// The number of chosen bases. The test has at least a /// 1/4^confidence chance of falsely returning True. /// </para> /// </param> /// <returns> /// <para> /// True if "this" is a strong pseudoprime to randomly chosen bases. /// </para> /// <para> /// False if "this" is definitely NOT prime. /// </para> /// </returns> public static bool RabinMillerTest(BigInteger bi, ConfidenceFactor confidence) { int Rounds = GetSPPRounds(bi, confidence); // calculate values of s and t BigInteger p_sub1 = bi - 1; int s = p_sub1.LowestSetBit(); BigInteger t = p_sub1 >> s; int bits = bi.bitCount(); BigInteger a = null; RandomNumberGenerator rng = RandomNumberGenerator.Create(); var mr = new BigInteger.ModulusRing(bi); for (int round = 0; round < Rounds; round++) { while (true) { // generate a < n a = BigInteger.genRandom(bits, rng); // make sure "a" is not 0 if (a > 1 && a < bi) { break; } } if (a.gcd(bi) != 1) { return(false); } BigInteger b = mr.Pow(a, t); if (b == 1) { continue; // a^t mod p = 1 } bool result = false; for (int j = 0; j < s; j++) { if (b == p_sub1) { // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 result = true; break; } b = (b * b) % bi; } if (result == false) { return(false); } } return(true); }
private void Initialize(BigInteger p, BigInteger g, BigInteger x, int secretLen, bool checkInput) { if (!p.isProbablePrime() || g <= 0 || g >= p || (x != null && (x <= 0 || x > p - 2))) { throw new CryptographicException(); } if (secretLen == 0) { secretLen = p.bitCount(); } this.m_P = p; this.m_G = g; if (x == null) { BigInteger bi = this.m_P - 1; this.m_X = BigInteger.genRandom(secretLen); while (this.m_X >= bi || this.m_X == 0u) { this.m_X = BigInteger.genRandom(secretLen); } } else { this.m_X = x; } }
// initializes the private variables (throws CryptographicException) private void Initialize(BigInteger p, BigInteger g, BigInteger x, int secretLen, bool checkInput) { if (!p.isProbablePrime() || g <= 0 || g >= p || (x != null && (x <= 0 || x > p - 2))) { throw new CryptographicException(); } // default is to generate a number as large as the prime this // is usually overkill, but it's the most secure thing we can // do if the user doesn't specify a desired secret length ... if (secretLen == 0) { secretLen = p.bitCount(); } m_P = p; m_G = g; if (x == null) { BigInteger pm1 = m_P - 1; for (m_X = BigInteger.genRandom(secretLen); m_X >= pm1 || m_X == 0; m_X = BigInteger.genRandom(secretLen)) { } } else { m_X = x; } }
private static BigInteger findRandomGenerator(BigInteger order, BigInteger modulo, Rng random) { BigInteger one = new BigInteger(1); BigInteger aux = modulo - new BigInteger(1); BigInteger t = aux % order; BigInteger generator; if (t.LongValue() != 0) { return(null); } t = aux / order; while (true) { generator = new BigInteger(); generator.genRandomBits(modulo.bitCount(), random); generator = generator % modulo; generator = generator.modPow(t, modulo); if (generator != one) { break; } } aux = generator.modPow(order, modulo); if (aux != one) { return(null); } return(generator); }
public static BigInteger PKCS1PadType2(BigInteger input, int pad_len, Random rand) { int input_byte_length = (input.bitCount() + 7) / 8; //System.out.println(String.valueOf(pad_len) + ":" + input_byte_length); byte[] pad = new byte[pad_len - input_byte_length - 3]; for (int i = 0; i < pad.Length; i++) { byte[] b = new byte[1]; rand.NextBytes(b); while (b[0] == 0) { rand.NextBytes(b); //0ではだめだ } pad[i] = b[0]; } BigInteger pad_int = new BigInteger(pad); pad_int = pad_int << ((input_byte_length + 1) * 8); BigInteger result = new BigInteger(2); result = result << ((pad_len - 2) * 8); result = result | pad_int; result = result | input; return(result); }
public void TestBitCount() { { // Randomized tests var r = new Random(); for (int j = 0; j < 512; j++) { var length = r.Next(70 * sizeof(uint) * 8 - 2); // TODO: 70 - current maxLength, remove hardcoded value var sb = new StringBuilder("1"); for (var i = 0; i < length; i++) { sb.Append(r.Next() % 2 == 0 ? "1" : "0"); } var bits = sb.Length; var bi = new BigInteger(sb.ToString(), 2); var bitsCounted = bi.bitCount(); Assert.AreEqual(bits, bitsCounted); } } { // Special cases - zero, one var z = new BigInteger(0); var bitsCounted = z.bitCount(); Assert.AreEqual(bitsCounted, 1); var o = new BigInteger(1); bitsCounted = o.bitCount(); Assert.AreEqual(bitsCounted, 1); } }
private BigInteger GenerateY(BigInteger p, BigInteger q) { do { x = BigInteger.genPseudoPrime(q.bitCount(), confidence, rand); } while (x <= 0 && x >= q); return(g.modPow(x, p)); }
public string RSAEncrypt(string a) { BigInteger tmp = pkcs1pad2(a, (n.bitCount() + 7) >> 3); tmp = RSADoPublic(tmp); string result = tmp.ToHexString(); return(0 == (result.Length & 1) ? result : "0" + result); }
public string Encrypt(string a) { BigInteger tmp = AE(a, (Modulus.bitCount() + 7) >> 3); tmp = RSADoPublic(tmp); string result = tmp.ToHexString(); return((result.Length & 1) == 0 ? result : "0" + result); }
static SRP() { // initialize N { NHex = //512bit //"D4C7F8A2B32C11B8FBA9581EC4BA4F1B04215642EF7355E37C0FC0443EF756EA2C6B8EEB755A1C723027663CAA265EF785B8FF6A9B35227A52D86633DBDFCA43"; //256bit "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3".ToLowerInvariant(); N = new BigInteger(NHex, 16); _nbits = N.bitCount(); Nminus1 = N - 1; // if (!N.isProbablePrime(80)) // { // throw new Exception("Warning: N is not prime"); // } // // if (!(Nminus1 / 2).isProbablePrime(80)) // { // throw new Exception("Warning: (N-1)/2 is not prime"); // } } // initialize g { gHex = "2"; g = new BigInteger(gHex, 16); } // initialize k = H(N || g) { BigInteger ktmp = new BigInteger(HHex( (((NHex.Length & 1) == 0) ? "" : "0") + NHex + new string('0', NHex.Length - gHex.Length) + gHex ), 16); k = (ktmp < N) ? ktmp : (ktmp % N); kHex = k.ToString(16).ToLowerInvariant().TrimStart('0'); } // initialize a, A { a = new BigInteger(); a.genRandomBits(36); A = g.modPow(a, N); while (A.modInverse(N) == 0) { a = new BigInteger(); a.genRandomBits(36); A = g.modPow(a, N); } Ahex = A.ToString(16).ToLowerInvariant().TrimStart('0'); } }
private BigInteger GenerateK(BigInteger q) { BigInteger tempK; do { tempK = BigInteger.genPseudoPrime(q.bitCount(), confidence, rand); } while (tempK >= q && tempK <= 0); return(tempK); }
//подписываем сообщение public string SignGen(byte[] h, BigInteger d) { BigInteger alpha = new BigInteger(h); BigInteger e = alpha % n; if (e == 0) { e = 1; } BigInteger k = new BigInteger(); ECPoint C = new ECPoint(); BigInteger r = new BigInteger(); BigInteger s = new BigInteger(); do { do { k.genRandomBits(n.bitCount(), new Random()); } while ((k < 0) || (k > n)); C = ECPoint.multiply(k, G); r = C.x % n; s = ((r * d) + (k * e)) % n; } while ((r == 0) || (s == 0)); string Rvector = padding(r.ToHexString(), n.bitCount() / 4); string Svector = padding(s.ToHexString(), n.bitCount() / 4); return(Rvector + Svector); }
/// <summary> /// Encrypt the content. /// </summary> /// <param name="content"></param> /// <returns></returns> public string Encrypt(string content) { if (Rsa == null) { BigInteger tmp = AE(content, (Modulus.bitCount() + 7) >> 3); tmp = RSADoPublic(tmp); string result = tmp.ToHexString(); return((result.Length & 1) == 0 ? result : "0" + result); } else { return(Convert.ToBase64String(Rsa.Encrypt(Encoding.UTF8.GetBytes(content), false))); } }
/// <summary> /// Probabilistic prime test based on Rabin-Miller's test /// </summary> /// <param name="bi" type="BigInteger.BigInteger"> /// <para> /// The number to test. /// </para> /// </param> /// <param name="confidence" type="int"> /// <para> /// The number of chosen bases. The test has at least a /// 1/4^confidence chance of falsely returning True. /// </para> /// </param> /// <returns> /// <para> /// True if "this" is a strong pseudoprime to randomly chosen bases. /// </para> /// <para> /// False if "this" is definitely NOT prime. /// </para> /// </returns> public static bool RabinMillerTest(BigInteger bi, ConfidenceFactor confidence) { int Rounds = GetSPPRounds(bi, confidence); // calculate values of s and t BigInteger p_sub1 = bi - 1; int s = p_sub1.LowestSetBit(); BigInteger t = p_sub1 >> s; int bits = bi.bitCount(); BigInteger a = null; RandomNumberGenerator rng = RandomNumberGenerator.Create(); BigInteger.ModulusRing mr = new BigInteger.ModulusRing(bi); for (int round = 0; round < Rounds; round++) { while (true) { // generate a < n a = BigInteger.genRandom(bits, rng); // make sure "a" is not 0 if (a > 1 && a < bi) break; } if (a.gcd(bi) != 1) return false; BigInteger b = mr.Pow(a, t); if (b == 1) continue; // a^t mod p = 1 bool result = false; for (int j = 0; j < s; j++) { if (b == p_sub1) { // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 result = true; break; } b = (b * b) % bi; } if (result == false) return false; } return true; }
/** * Create an Erlang integer from the given value. * * @param val * the long value to use. */ public OtpErlangLong(BigInteger v) { if (v == null) { throw new NullReferenceException(); } if (v.bitCount() < 64) { val = v.LongValue(); } else { bigVal = v; } }
public static bool RabinMillerTest(BigInteger bi, ConfidenceFactor confidence) { int sPPRounds = GetSPPRounds(bi, confidence); BigInteger bigInteger = bi - 1; int num = bigInteger.LowestSetBit(); BigInteger exp = bigInteger >> num; int bits = bi.bitCount(); BigInteger bigInteger2 = null; RandomNumberGenerator rng = RandomNumberGenerator.Create(); BigInteger.ModulusRing modulusRing = new BigInteger.ModulusRing(bi); for (int i = 0; i < sPPRounds; i++) { do { bigInteger2 = BigInteger.genRandom(bits, rng); }while (!(bigInteger2 > 1) || !(bigInteger2 < bi)); if (bigInteger2.gcd(bi) != 1u) { return(false); } BigInteger bigInteger3 = modulusRing.Pow(bigInteger2, exp); if (bigInteger3 == 1u) { continue; } bool flag = false; for (int j = 0; j < num; j++) { if (bigInteger3 == bigInteger) { flag = true; break; } bigInteger3 = bigInteger3 * bigInteger3 % bi; } if (!flag) { return(false); } } return(true); }
public static DSAKeyPair GenerateNew(int bits, Rng random) { BigInteger one = new BigInteger(1); BigInteger[] pq = findRandomStrongPrime((uint)bits, 160, random); BigInteger p = pq[0], q = pq[1]; BigInteger g = findRandomGenerator(q, p, random); BigInteger x; do { x = new BigInteger(); x.genRandomBits(q.bitCount(), random); } while ((x < one) || (x > q)); BigInteger y = g.modPow(x, p); return(new DSAKeyPair(p, g, q, y, x)); }
static SRP() { // initialize N { NHex = //512bit "D4C7F8A2B32C11B8FBA9581EC4BA4F1B04215642EF7355E37C0FC0443EF756EA2C6B8EEB755A1C723027663CAA265EF785B8FF6A9B35227A52D86633DBDFCA43"; N = new BigInteger(NHex, 16); _nbits = N.bitCount(); Nminus1 = N - 1; if (!N.isProbablePrime(80)) { throw new Exception("Warning: N is not prime"); } if (!(Nminus1 / 2).isProbablePrime(80)) { throw new Exception("Warning: (N-1)/2 is not prime"); } } // initialize g { gHex = "2"; g = new BigInteger(gHex, 16); } // initialize k = H(N || g) { BigInteger ktmp = new BigInteger(HHex( (((NHex.Length & 1) == 0) ? "" : "0") + NHex + new string('0', NHex.Length - gHex.Length) + gHex ), 16); k = (ktmp < N) ? ktmp : (ktmp % N); kHex = k.ToHexString(); } }
private static int GetSPPRounds(BigInteger bi, ConfidenceFactor confidence) { int num = bi.bitCount(); int num2 = (num <= 100) ? 27 : ((num <= 150) ? 18 : ((num <= 200) ? 15 : ((num <= 250) ? 12 : ((num <= 300) ? 9 : ((num <= 350) ? 8 : ((num <= 400) ? 7 : ((num <= 500) ? 6 : ((num <= 600) ? 5 : ((num <= 800) ? 4 : ((num > 1250) ? 2 : 3)))))))))); switch (confidence) { case ConfidenceFactor.ExtraLow: num2 >>= 2; if (num2 == 0) { return(1); } return(num2); case ConfidenceFactor.Low: num2 >>= 1; if (num2 == 0) { return(1); } return(num2); case ConfidenceFactor.Medium: return(num2); case ConfidenceFactor.High: return(num2 <<= 1); case ConfidenceFactor.ExtraHigh: return(num2 <<= 2); case ConfidenceFactor.Provable: throw new Exception("The Rabin-Miller test can not be executed in a way such that its results are provable"); default: throw new ArgumentOutOfRangeException("confidence"); } }
private static int GetSPPRounds (BigInteger bi, ConfidenceFactor confidence) { int bc = bi.bitCount(); int Rounds; // Data from HAC, 4.49 if (bc <= 100 ) Rounds = 27; else if (bc <= 150 ) Rounds = 18; else if (bc <= 200 ) Rounds = 15; else if (bc <= 250 ) Rounds = 12; else if (bc <= 300 ) Rounds = 9; else if (bc <= 350 ) Rounds = 8; else if (bc <= 400 ) Rounds = 7; else if (bc <= 500 ) Rounds = 6; else if (bc <= 600 ) Rounds = 5; else if (bc <= 800 ) Rounds = 4; else if (bc <= 1250) Rounds = 3; else Rounds = 2; switch (confidence) { case ConfidenceFactor.ExtraLow: Rounds >>= 2; return Rounds != 0 ? Rounds : 1; case ConfidenceFactor.Low: Rounds >>= 1; return Rounds != 0 ? Rounds : 1; case ConfidenceFactor.Medium: return Rounds; case ConfidenceFactor.High: return Rounds <<= 1; case ConfidenceFactor.ExtraHigh: return Rounds <<= 2; case ConfidenceFactor.Provable: throw new Exception ("The Rabin-Miller test can not be executed in a way such that its results are provable"); default: throw new ArgumentOutOfRangeException ("confidence"); } }
public void WriteBigInteger(BigInteger v) { if (v.bitCount() < 64) { WriteLong(v.LongValue(), true); return; } int signum = (v > 0) ? 1 : (v < 0) ? -1 : 0; if (signum < 0) { v = -v; } byte[] magnitude = v.getBytes(); int n = magnitude.Length; // Reverse the array to make it little endian. for (int i = 0, j = n; i < j--; i++) { (magnitude[i], magnitude[j]) = (magnitude[j], magnitude[i]); } if ((n & 0xFF) == n) { Write1(OtpExternal.smallBigTag); Write1(n); // length } else { Write1(OtpExternal.largeBigTag); Write4BE(n); // length } Write1(signum < 0 ? 1 : 0); // sign // Write the array WriteN(magnitude); }
public void write_big_integer(BigInteger v) { if (v.bitCount() < 64) { this.write_long(v.LongValue(), true); return; } int signum = (v > (BigInteger)0) ? 1 : (v < (BigInteger)0) ? -1 : 0; if (signum < 0) { v = -v; } byte[] magnitude = v.getBytes(); int n = magnitude.Length; // Reverse the array to make it little endian. for (int i = 0, j = n; i < j--; i++) { // Swap [i] with [j] byte b = magnitude[i]; magnitude[i] = magnitude[j]; magnitude[j] = b; } if ((n & 0xFF) == n) { write1(OtpExternal.smallBigTag); write1(n); // length } else { write1(OtpExternal.largeBigTag); write4BE(n); // length } write1(signum < 0 ? 1 : 0); // sign // Write the array writeN(magnitude); }
public static BigInteger PKCS1PadType1(BigInteger input, int pad_len) { int input_byte_length = (input.bitCount() + 7) / 8; //System.out.println(String.valueOf(pad_len) + ":" + input_byte_length); byte[] pad = new byte[pad_len - input_byte_length - 3]; for (int i = 0; i < pad.Length; i++) { pad[i] = (byte)0xff; } BigInteger pad_int = new BigInteger(pad); pad_int = pad_int << ((input_byte_length + 1) * 8); BigInteger result = new BigInteger(1); result = result << ((pad_len - 2) * 8); result = result | pad_int; result = result | input; return(result); }
private void Initialize(BigInteger p, BigInteger g, BigInteger x) { if (!p.isProbablePrime() || g <= 0 || g >= p) { throw new CryptographicException("Inputs p or g are not as expected. P probably isn't a prime or G is less than zero or more than P."); } if (x != null) { _x = x; } else { var pMinus1 = p - 1; var secretLen = p.bitCount(); for (_x = BigInteger.genRandom(secretLen); _x >= pMinus1 || _x == 0; _x = BigInteger.genRandom(secretLen)) { } } _p = p; _g = g; }
//подписываем сообщение // msg - сообщение // d - ключ подписи public string SingMsg(byte[] msg, BigInteger d) { // Шаг 2: вычислить e BigInteger e = new BigInteger(msg) % q; if (e == 0) { e = 1; } BigInteger k = new BigInteger(); // точка эллиптической кривой ECPoint C = new ECPoint(); BigInteger r = new BigInteger(); BigInteger s = new BigInteger(); do { // Шаг 3: сгенерировать случайное k (0< k <q) do { k.genRandomBits(q.bitCount(), new Random()); } while ((k < 0) || (k > q)); // найти точку элл. C = kP C = ECPoint.multiply(k, Q); // и определить r = Xc(mod q) r = C.x % q; // определим s = (rd + ke)(mod q), s == 0 -> Шаг 3 s = ((r * d) + (k * e)) % q; } while ((r == 0) || (s == 0)); // перевод значений в двоичный вид string Rvector = padding(r.ToHexString(), q.bitCount() / 4); string Svector = padding(s.ToHexString(), q.bitCount() / 4); // конкатенацию двух двоичных векторов (цифровая подпись) return(Rvector + Svector); }
// TODO redesign keep strategy to allow keeping both highest and lowest private static BigInteger roll(BigInteger dieType, long dieCount, long keepCount, KeepStrategy keepStrategy) { if (dieType <= 1) { throw new InvalidExpressionException ("invalid die"); } // if the diecount is negative we will roll with the positive diecount, but negate the end result. // basically, "-5d6" is treated as "-(5d6)" bool negative = false; if (dieCount < 0) { negative = true; dieCount = -dieCount; } keepCount = Math.Min(keepCount, dieCount); // roll the dice and keep them in an array BigInteger[] results = new BigInteger[dieCount]; for (int i = 0; i < dieCount; i++) { BigInteger num = new BigInteger (); num.genRandomBits (dieType.bitCount (), RAND); results [i] = num; } // add up the results based on the strategy used BigInteger result = 0; if (keepStrategy == KeepStrategy.ALL) { for (int i = 0; i < dieCount; i++) { result += results [i]; } } else { // we are only keeping some, so sort the list Array.Sort (results); if (keepStrategy == KeepStrategy.HIGHEST) { for (long i = dieCount - 1; i >= dieCount - keepCount; i--) { result += results [i]; } } else if (keepStrategy == KeepStrategy.LOWEST) { for (int i = 0; i < keepCount; i++) { result += results [i]; } } } if (negative) { result = -result; } return result; }
private static int GetSPPRounds(BigInteger bi, ConfidenceFactor confidence) { int bc = bi.bitCount(); int Rounds; // Data from HAC, 4.49 if (bc <= 100) { Rounds = 27; } else if (bc <= 150) { Rounds = 18; } else if (bc <= 200) { Rounds = 15; } else if (bc <= 250) { Rounds = 12; } else if (bc <= 300) { Rounds = 9; } else if (bc <= 350) { Rounds = 8; } else if (bc <= 400) { Rounds = 7; } else if (bc <= 500) { Rounds = 6; } else if (bc <= 600) { Rounds = 5; } else if (bc <= 800) { Rounds = 4; } else if (bc <= 1250) { Rounds = 3; } else { Rounds = 2; } switch (confidence) { case ConfidenceFactor.ExtraLow: Rounds >>= 2; return(Rounds != 0 ? Rounds : 1); case ConfidenceFactor.Low: Rounds >>= 1; return(Rounds != 0 ? Rounds : 1); case ConfidenceFactor.Medium: return(Rounds); case ConfidenceFactor.High: return(Rounds <<= 1); case ConfidenceFactor.ExtraHigh: return(Rounds <<= 2); case ConfidenceFactor.Provable: throw new Exception("The Rabin-Miller test can not be executed in a way such that its results are provable"); default: throw new ArgumentOutOfRangeException("confidence"); } }
private static BigInteger[] findRandomStrongPrime(uint primeBits, int orderBits, Random random) { BigInteger one = new BigInteger(1); BigInteger u, aux, aux2; long[] table_q, table_u, prime_table; PrimeSieve sieve = new PrimeSieve(16000); uint table_count = sieve.AvailablePrimes() - 1; int i, j; bool flag; BigInteger prime = null, order = null; order = BigInteger.genPseudoPrime(orderBits, 20, random); prime_table = new long[table_count]; table_q = new long[table_count]; table_u = new long[table_count]; i = 0; for(int pN = 2; pN != 0; pN = sieve.getNextPrime(pN), i++) { prime_table[i] = (long)pN; } for(i = 0; i < table_count; i++) { table_q[i] = (((order % new BigInteger(prime_table[i])).LongValue()) * (long)2) % prime_table[i]; } while(true) { u = new BigInteger(); u.genRandomBits((int)primeBits, random); u.setBit(primeBits - 1); aux = order << 1; aux2 = u % aux; u = u - aux2; u = u + one; if(u.bitCount() <= (primeBits - 1)) continue; for(j = 0; j < table_count; j++) { table_u[j] = (u % new BigInteger(prime_table[j])).LongValue(); } aux2 = order << 1; for(i = 0; i < (1 << 24); i++) { long cur_p; long value; flag = true; for(j = 1; j < table_count; j++) { cur_p = prime_table[j]; value = table_u[j]; if(value >= cur_p) value -= cur_p; if(value == 0) flag = false; table_u[j] = value + table_q[j]; } if(!flag) continue; aux = aux2 * new BigInteger(i); prime = u + aux; if(prime.bitCount() > primeBits) continue; if(prime.isProbablePrime(20)) break; } if(i < (1 << 24)) break; } return new BigInteger[] { prime, order }; }
private static BigInteger findRandomGenerator(BigInteger order, BigInteger modulo, Random random) { BigInteger one = new BigInteger(1); BigInteger aux = modulo - new BigInteger(1); BigInteger t = aux % order; BigInteger generator; if(t.LongValue() != 0) { return null; } t = aux / order; while(true) { generator = new BigInteger(); generator.genRandomBits(modulo.bitCount(), random); generator = generator % modulo; generator = generator.modPow(t, modulo); if(generator!=one) break; } aux = generator.modPow(order, modulo); if(aux!=one) { return null; } return generator; }
//*********************************************************************** // Performs the calculation of the kth term in the Lucas Sequence. // For details of the algorithm, see reference [9]. // // k must be odd. i.e LSB == 1 //*********************************************************************** private static BigInteger[] LucasSequenceHelper(BigInteger P, BigInteger Q, BigInteger k, BigInteger n, BigInteger constant, int s) { BigInteger[] result = new BigInteger[3]; if((k.data[0] & 0x00000001) == 0) throw (new ArgumentException("Argument k must be odd.")); int numbits = k.bitCount(); uint mask = (uint)0x1 << ((numbits & 0x1F) - 1); // v = v0, v1 = v1, u1 = u1, Q_k = Q^0 BigInteger v = 2 % n, Q_k = 1 % n, v1 = P % n, u1 = Q_k; bool flag = true; for(int i = k.dataLength - 1; i >= 0 ; i--) // iterate on the binary expansion of k { //Console.WriteLine("round"); while(mask != 0) { if(i == 0 && mask == 0x00000001) // last bit break; if((k.data[i] & mask) != 0) // bit is set { // index doubling with addition u1 = (u1 * v1) % n; v = ((v * v1) - (P * Q_k)) % n; v1 = n.BarrettReduction(v1 * v1, n, constant); v1 = (v1 - ((Q_k * Q) << 1)) % n; if(flag) flag = false; else Q_k = n.BarrettReduction(Q_k * Q_k, n, constant); Q_k = (Q_k * Q) % n; } else { // index doubling u1 = ((u1 * v) - Q_k) % n; v1 = ((v * v1) - (P * Q_k)) % n; v = n.BarrettReduction(v * v, n, constant); v = (v - (Q_k << 1)) % n; if(flag) { Q_k = Q % n; flag = false; } else Q_k = n.BarrettReduction(Q_k * Q_k, n, constant); } mask >>= 1; } mask = 0x80000000; } // at this point u1 = u(n+1) and v = v(n) // since the last bit always 1, we need to transform u1 to u(2n+1) and v to v(2n+1) u1 = ((u1 * v) - Q_k) % n; v = ((v * v1) - (P * Q_k)) % n; if(flag) flag = false; else Q_k = n.BarrettReduction(Q_k * Q_k, n, constant); Q_k = (Q_k * Q) % n; for(int i = 0; i < s; i++) { // index doubling u1 = (u1 * v) % n; v = ((v * v) - (Q_k << 1)) % n; if(flag) { Q_k = Q % n; flag = false; } else Q_k = n.BarrettReduction(Q_k * Q_k, n, constant); } result[0] = u1; result[1] = v; result[2] = Q_k; return result; }
public static BigInteger PKCS1PadType2(BigInteger input, int pad_len, Rng rng) { int input_byte_length = (input.bitCount() + 7) / 8; //System.out.println(String.valueOf(pad_len) + ":" + input_byte_length); byte[] pad = new byte[pad_len - input_byte_length - 3]; for (int i = 0; i < pad.Length; i++) { byte[] b = new byte[1]; rng.GetBytes(b); while (b[0] == 0) rng.GetBytes(b); //0ではだめだ pad[i] = b[0]; } BigInteger pad_int = new BigInteger(pad); pad_int = pad_int << ((input_byte_length + 1) * 8); BigInteger result = new BigInteger(2); result = result << ((pad_len - 2) * 8); result = result | pad_int; result = result | input; return result; }
//*********************************************************************** // Modulo Exponentiation //*********************************************************************** public BigInteger modPow(BigInteger exp, BigInteger n) { if((exp.data[maxLength-1] & 0x80000000) != 0) throw (new ArithmeticException("Positive exponents only.")); BigInteger resultNum = 1; BigInteger tempNum; bool thisNegative = false; if((this.data[maxLength-1] & 0x80000000) != 0) // negative this { tempNum = -this % n; thisNegative = true; } else tempNum = this % n; // ensures (tempNum * tempNum) < b^(2k) if((n.data[maxLength-1] & 0x80000000) != 0) // negative n n = -n; // calculate constant = b^(2k) / m BigInteger constant = new BigInteger(); int i = n.dataLength << 1; constant.data[i] = 0x00000001; constant.dataLength = i + 1; constant = constant / n; int totalBits = exp.bitCount(); int count = 0; // perform squaring and multiply exponentiation for(int pos = 0; pos < exp.dataLength; pos++) { uint mask = 0x01; //Console.WriteLine("pos = " + pos); for(int index = 0; index < 32; index++) { if((exp.data[pos] & mask) != 0) resultNum = BarrettReduction(resultNum * tempNum, n, constant); mask <<= 1; tempNum = BarrettReduction(tempNum * tempNum, n, constant); if(tempNum.dataLength == 1 && tempNum.data[0] == 1) { if(thisNegative && (exp.data[0] & 0x1) != 0) //odd exp return -resultNum; return resultNum; } count++; if(count == totalBits) break; } } if(thisNegative && (exp.data[0] & 0x1) != 0) //odd exp return -resultNum; return resultNum; }
public static BigInteger PKCS1PadType1(BigInteger input, int pad_len) { int input_byte_length = (input.bitCount() + 7) / 8; //System.out.println(String.valueOf(pad_len) + ":" + input_byte_length); byte[] pad = new byte[pad_len - input_byte_length - 3]; for (int i = 0; i < pad.Length; i++) { pad[i] = (byte)0xff; } BigInteger pad_int = new BigInteger(pad); pad_int = pad_int << ((input_byte_length + 1) * 8); BigInteger result = new BigInteger(1); result = result << ((pad_len - 2) * 8); result = result | pad_int; result = result | input; return result; }
public void TestSecuredGenRandomBits() { { // Test < 32 bits var bi = new BigInteger(); var rng = new RNGCryptoServiceProvider(); var rand = new Random(); bi.genRandomBits(rand.Next(1, 33), rng); var bytes = bi.getBytes(); Array.Reverse(bytes); var new_bytes = new byte[4]; Array.Copy(bytes, new_bytes, bytes.Length); Assert.IsTrue(BitConverter.ToUInt32(new_bytes, 0) < (Math.Pow(2, 32) - 1)); } // Test on random number of bits for (int i = 0; i < 99; i++) { var bi = new BigInteger(); var rng = new RNGCryptoServiceProvider(); var rand = new Random(); var bits = rand.Next(1, 70 * 32 + 1); bi.genRandomBits(bits, rng); Assert.AreEqual(bits, bi.bitCount()); } { // Test upper boundary values var bi = new BigInteger(); var rng = new RNGCryptoServiceProvider(); Exception exception = null; try { bi.genRandomBits(2241, rng); } catch (Exception ex) { exception = ex; } Assert.IsNotNull(exception); bi.genRandomBits(2240, rng); Assert.AreEqual(70, bi.dataLength); bi.genRandomBits(2239, rng); Assert.AreEqual(70, bi.dataLength); Assert.AreEqual(2239, bi.bitCount()); } { // Test lower boudary value var bi = new BigInteger(); var rng = new RNGCryptoServiceProvider(); bi.genRandomBits(1, rng); Assert.IsTrue(bi.getBytes()[0] == 1 || bi.getBytes()[0] == 0); } }
public void WriteBigIntWithBits(BigInteger bi) { WriteInt32(bi.bitCount()); Write(bi.getBytes()); }
private static BigInteger[] findRandomStrongPrime(uint primeBits, int orderBits, Rng random) { BigInteger one = new BigInteger(1); BigInteger u, aux, aux2; long[] table_q, table_u, prime_table; PrimeSieve sieve = new PrimeSieve(16000); uint table_count = sieve.AvailablePrimes() - 1; int i, j; bool flag; BigInteger prime = null, order = null; order = BigInteger.genPseudoPrime(orderBits, 20, random); prime_table = new long[table_count]; table_q = new long[table_count]; table_u = new long[table_count]; i = 0; for (int pN = 2; pN != 0; pN = sieve.getNextPrime(pN), i++) { prime_table[i] = (long)pN; } for (i = 0; i < table_count; i++) { table_q[i] = (((order % new BigInteger(prime_table[i])).LongValue()) * (long)2) % prime_table[i]; } while (true) { u = new BigInteger(); u.genRandomBits((int)primeBits, random); u.setBit(primeBits - 1); aux = order << 1; aux2 = u % aux; u = u - aux2; u = u + one; if (u.bitCount() <= (primeBits - 1)) { continue; } for (j = 0; j < table_count; j++) { table_u[j] = (u % new BigInteger(prime_table[j])).LongValue(); } aux2 = order << 1; for (i = 0; i < (1 << 24); i++) { long cur_p; long value; flag = true; for (j = 1; j < table_count; j++) { cur_p = prime_table[j]; value = table_u[j]; if (value >= cur_p) { value -= cur_p; } if (value == 0) { flag = false; } table_u[j] = value + table_q[j]; } if (!flag) { continue; } aux = aux2 * new BigInteger(i); prime = u + aux; if (prime.bitCount() > primeBits) { continue; } if (prime.isProbablePrime(20)) { break; } } if (i < (1 << 24)) { break; } } return(new BigInteger[] { prime, order }); }
public PaillierPaddingMode Padding; // this parameter should be considered part of the public key public int getPlaintextBlocksize() { return((N.bitCount() - 1) / 8); }