/* * Finds a pair of prime BigInteger's {p, q: p = 2q + 1} * * (see: Handbook of Applied Cryptography 4.86) */ internal static BigInteger[] GenerateSafePrimes(int size, int certainty, SecureRandom random) { BigInteger p, q; int qLength = size - 1; int minWeight = size >> 2; if (size <= 32) { for (;;) { q = new BigInteger(qLength, 2, random); p = q.ShiftLeft(1).Add(BigInteger.One); if (!p.IsProbablePrime(certainty)) continue; if (certainty > 2 && !q.IsProbablePrime(certainty - 2)) continue; break; } } else { // Note: Modified from Java version for speed for (;;) { q = new BigInteger(qLength, 0, random); retry: for (int i = 0; i < primeLists.Length; ++i) { int test = q.Remainder(BigPrimeProducts[i]).IntValue; if (i == 0) { int rem3 = test % 3; if (rem3 != 2) { int diff = 2 * rem3 + 2; q = q.Add(BigInteger.ValueOf(diff)); test = (test + diff) % primeProducts[i]; } } int[] primeList = primeLists[i]; for (int j = 0; j < primeList.Length; ++j) { int prime = primeList[j]; int qRem = test % prime; if (qRem == 0 || qRem == (prime >> 1)) { q = q.Add(Six); goto retry; } } } if (q.BitLength != qLength) continue; if (!q.RabinMillerTest(2, random)) continue; p = q.ShiftLeft(1).Add(BigInteger.One); if (!p.RabinMillerTest(certainty, random)) continue; if (certainty > 2 && !q.RabinMillerTest(certainty - 2, random)) continue; /* * Require a minimum weight of the NAF representation, since low-weight primes may be * weak against a version of the number-field-sieve for the discrete-logarithm-problem. * * See "The number field sieve for integers of low weight", Oliver Schirokauer. */ if (WNafUtilities.GetNafWeight(p) < minWeight) continue; break; } } return new BigInteger[] { p, q }; }
public BigInteger And( BigInteger value) { if (this.sign == 0 || value.sign == 0) { return Zero; } int[] aMag = this.sign > 0 ? this.magnitude : Add(One).magnitude; int[] bMag = value.sign > 0 ? value.magnitude : value.Add(One).magnitude; bool resultNeg = sign < 0 && value.sign < 0; int resultLength = System.Math.Max(aMag.Length, bMag.Length); int[] resultMag = new int[resultLength]; int aStart = resultMag.Length - aMag.Length; int bStart = resultMag.Length - bMag.Length; for (int i = 0; i < resultMag.Length; ++i) { int aWord = i >= aStart ? aMag[i - aStart] : 0; int bWord = i >= bStart ? bMag[i - bStart] : 0; if (this.sign < 0) { aWord = ~aWord; } if (value.sign < 0) { bWord = ~bWord; } resultMag[i] = aWord & bWord; if (resultNeg) { resultMag[i] = ~resultMag[i]; } } BigInteger result = new BigInteger(1, resultMag, true); // TODO Optimise this case if (resultNeg) { result = result.Not(); } return result; }
internal static PrivateKey Derivate(this PrivateKey privateKey, byte[] cc, uint nChild, Network network, out byte[] ccChild) { byte[] l = null; if((nChild >> 31) == 0) { var pubKey = privateKey.GetPublicKey().ToBytes(); l = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.Skip(1).ToArray()); } else { l = Hashes.BIP32Hash(cc, nChild, 0, privateKey.ToBytes()); } var ll = l.Take(32).ToArray(); var lr = l.Skip(32).Take(32).ToArray(); ccChild = lr; var parse256LL = new BigInteger(1, ll); var kPar = new BigInteger(1, privateKey.ToBytes()); var N = ECHelper.CURVE.N; if(parse256LL.CompareTo(N) >= 0) throw new InvalidOperationException("You won a prize ! this should happen very rarely. Take a screenshot, and roll the dice again."); var key = parse256LL.Add(kPar).Mod(N); if(key == BigInteger.Zero) throw new InvalidOperationException("You won the big prize ! this would happen only 1 in 2^127. Take a screenshot, and roll the dice again."); var keyBytes = key.ToByteArrayUnsigned(); if(keyBytes.Length < 32) keyBytes = new byte[32 - keyBytes.Length].Concat(keyBytes).ToArray(); return new PrivateKey(keyBytes, network); }
private static BigInteger ReduceBarrett(BigInteger x, BigInteger m, BigInteger mr, BigInteger yu) { int xLen = x.BitLength, mLen = m.BitLength; if (xLen < mLen) return x; if (xLen - mLen > 1) { int k = m.magnitude.Length; BigInteger q1 = x.DivideWords(k - 1); BigInteger q2 = q1.Multiply(yu); // TODO Only need partial multiplication here BigInteger q3 = q2.DivideWords(k + 1); BigInteger r1 = x.RemainderWords(k + 1); BigInteger r2 = q3.Multiply(m); // TODO Only need partial multiplication here BigInteger r3 = r2.RemainderWords(k + 1); x = r1.Subtract(r3); if (x.sign < 0) { x = x.Add(mr); } } while (x.CompareTo(m) >= 0) { x = x.Subtract(m); } return x; }