public Key Derivate(byte[] cc, uint nChild, out byte[] ccChild) { byte[] l = null; if((nChild >> 31) == 0) { var pubKey = PubKey.ToBytes(); l = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.SafeSubarray(1)); } else { l = Hashes.BIP32Hash(cc, nChild, 0, this.ToBytes()); } var ll = l.SafeSubarray(0, 32); var lr = l.SafeSubarray(32, 32); ccChild = lr; var parse256LL = new BigInteger(1, ll); var kPar = new BigInteger(1, vch); var N = ECKey.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 Key(keyBytes); }
public ExtKey GetParentExtKey(ExtPubKey parent) { if(parent == null) throw new ArgumentNullException("parent"); if(Depth == 0) throw new InvalidOperationException("This ExtKey is the root key of the HD tree"); if(IsHardened) throw new InvalidOperationException("This private key is hardened, so you can't get its parent"); var expectedFingerPrint = parent.CalculateChildFingerprint(); if(parent.Depth != this.Depth - 1 || !expectedFingerPrint.SequenceEqual(vchFingerprint)) throw new ArgumentException("The parent ExtPubKey is not the immediate parent of this ExtKey", "parent"); byte[] l = null; byte[] ll = new byte[32]; byte[] lr = new byte[32]; var pubKey = parent.PubKey.ToBytes(); l = Hashes.BIP32Hash(parent.vchChainCode, nChild, pubKey[0], pubKey.SafeSubarray(1)); Array.Copy(l, ll, 32); Array.Copy(l, 32, lr, 0, 32); var ccChild = lr; BigInteger parse256LL = new BigInteger(1, ll); BigInteger N = ECKey.CURVE.N; if(!ccChild.SequenceEqual(vchChainCode)) throw new InvalidOperationException("The derived chain code of the parent is not equal to this child chain code"); var keyBytes = PrivateKey.ToBytes(); var key = new BigInteger(1, keyBytes); BigInteger kPar = key.Add(parse256LL.Negate()).Mod(N); var keyParentBytes = kPar.ToByteArrayUnsigned(); if(keyParentBytes.Length < 32) keyParentBytes = new byte[32 - keyParentBytes.Length].Concat(keyParentBytes).ToArray(); var parentExtKey = new ExtKey { vchChainCode = parent.vchChainCode, nDepth = parent.Depth, vchFingerprint = parent.Fingerprint, nChild = parent.nChild, key = new Key(keyParentBytes) }; return parentExtKey; }
// 5.4 pg 29 /** * return true if the value r and s represent a DSA signature for * the passed in message (for standard DSA the message should be * a SHA-1 hash of the real message to be verified). */ public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s) { BigInteger n = key.Parameters.N; // r and s should both in the range [1,n-1] if(r.SignValue < 1 || s.SignValue < 1 || r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0) { return false; } BigInteger e = CalculateE(n, message); BigInteger c = s.ModInverse(n); BigInteger u1 = e.Multiply(c).Mod(n); BigInteger u2 = r.Multiply(c).Mod(n); ECPoint G = key.Parameters.G; ECPoint Q = ((ECPublicKeyParameters)key).Q; ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2); if(point.IsInfinity) return false; /* * If possible, avoid normalizing the point (to save a modular inversion in the curve field). * * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'. * If the cofactor is known and small, we generate those possible field values and project each * of them to the same "denominator" (depending on the particular projective coordinates in use) * as the calculated point.X. If any of the projected values matches point.X, then we have: * (point.X / Denominator mod p) mod n == r * as required, and verification succeeds. * * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in * the libsecp256k1 project (https://github.com/bitcoin/secp256k1). */ ECCurve curve = point.Curve; if(curve != null) { BigInteger cofactor = curve.Cofactor; if(cofactor != null && cofactor.CompareTo(Eight) <= 0) { ECFieldElement D = GetDenominator(curve.CoordinateSystem, point); if(D != null && !D.IsZero) { ECFieldElement X = point.XCoord; while(curve.IsValidFieldElement(r)) { ECFieldElement R = curve.FromBigInteger(r).Multiply(D); if(R.Equals(X)) { return true; } r = r.Add(n); } return false; } } } BigInteger v = point.Normalize().AffineXCoord.ToBigInteger().Mod(n); return v.Equals(r); }
/* * 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; }
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; }