public AsymmetricCipherKeyPair GenerateKeyPair() { BigInteger p, q, n, d, e, pSub1, qSub1, phi; // // p and q values should have a length of half the strength in bits // int strength = param.Strength; int pbitlength = (strength + 1) / 2; int qbitlength = (strength - pbitlength); int mindiffbits = strength / 3; e = param.PublicExponent; // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes) // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm") // // Generate p, prime and (p-1) relatively prime to e // for (;;) { p = new BigInteger(pbitlength, 1, param.Random); if (p.Mod(e).Equals(BigInteger.One)) continue; if (!p.IsProbablePrime(param.Certainty)) continue; if (e.Gcd(p.Subtract(BigInteger.One)).Equals(BigInteger.One)) break; } // // Generate a modulus of the required length // for (;;) { // Generate q, prime and (q-1) relatively prime to e, // and not equal to p // for (;;) { q = new BigInteger(qbitlength, 1, param.Random); if (q.Subtract(p).Abs().BitLength < mindiffbits) continue; if (q.Mod(e).Equals(BigInteger.One)) continue; if (!q.IsProbablePrime(param.Certainty)) continue; if (e.Gcd(q.Subtract(BigInteger.One)).Equals(BigInteger.One)) break; } // // calculate the modulus // n = p.Multiply(q); if (n.BitLength == param.Strength) break; // // if we Get here our primes aren't big enough, make the largest // of the two p and try again // p = p.Max(q); } if (p.CompareTo(q) < 0) { phi = p; p = q; q = phi; } pSub1 = p.Subtract(BigInteger.One); qSub1 = q.Subtract(BigInteger.One); phi = pSub1.Multiply(qSub1); // // calculate the private exponent // d = e.ModInverse(phi); // // calculate the CRT factors // BigInteger dP, dQ, qInv; dP = d.Remainder(pSub1); dQ = d.Remainder(qSub1); qInv = q.ModInverse(p); return new AsymmetricCipherKeyPair( new RsaKeyParameters(false, n, e), new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv)); }
public RsaSecretBcpgKey( BigInteger d, BigInteger p, BigInteger q) { // PGP requires (p < q) int cmp = p.CompareTo(q); if (cmp >= 0) { if (cmp == 0) throw new ArgumentException("p and q cannot be equal"); BigInteger tmp = p; p = q; q = tmp; } this.d = new MPInteger(d); this.p = new MPInteger(p); this.q = new MPInteger(q); this.u = new MPInteger(p.ModInverse(q)); this.expP = d.Remainder(p.Subtract(BigInteger.One)); this.expQ = d.Remainder(q.Subtract(BigInteger.One)); this.crt = q.ModInverse(p); }
public RSA(int bits) { p = Helper.GenerateBigIntegerPrimes(bits); //p = new Org.BouncyCastle.Math.BigInteger("3557"); q = Helper.GenerateBigIntegerPrimes(bits); //q = new Org.BouncyCastle.Math.BigInteger("2579"); Console.WriteLine("p generated " + p); Console.WriteLine("q generated " + q); n = p.Multiply(q); Console.WriteLine("n = " + n); BigInteger p1 = p.Subtract(new BigInteger("1")); BigInteger q1 = q.Subtract(new BigInteger("1")); fn = p1.Multiply(q1); Console.WriteLine("Функция Эйлера = " + fn); int[] er = new[] { 17, 257, 65537 }; Random rand = new Random((int)System.DateTime.Now.Ticks); e = new BigInteger(er[rand.Next(0, er.Length)].ToString()); Console.WriteLine("e = " + e); d = e.ModInverse(fn); Console.WriteLine("d = " + d); Console.WriteLine("Public Key: " + e + ", " + n); Console.WriteLine("Private Key: " + d + ", " + n); }
/** * Generate a signature for the given message using the key we were * initialised with. For conventional DSA the message should be a SHA-1 * hash of the message of interest. * * @param message the message that will be verified later. */ public IBigInteger[] GenerateSignature(byte[] message) { var parameters = _key.Parameters; var q = parameters.Q; var m = CalculateE(q, message); IBigInteger k; do { k = new BigInteger(q.BitLength, _random); } while (k.CompareTo(q) >= 0); var r = parameters.G.ModPow(k, parameters.P).Mod(q); k = k.ModInverse(q).Multiply(m.Add(((DsaPrivateKeyParameters)_key).X.Multiply(r))); var s = k.Mod(q); return new[] { r, s }; }
public MHKey() { generator gen = new generator(8); Org.BouncyCastle.Math.BigInteger w = gen.w; e = new List <Org.BouncyCastle.Math.BigInteger>(); for (int i = 0; i < gen.a.Count; i++) { e.Add((w.Multiply(gen.a.ElementAt(i))).Mod(gen.n)); // w*a Mod n .. } Org.BouncyCastle.Math.BigInteger w1 = Org.BouncyCastle.Math.BigInteger.ValueOf(1); Org.BouncyCastle.Math.BigInteger one = Org.BouncyCastle.Math.BigInteger.ValueOf(2); while (one.IntValue != 1) { w1 = w1.Add(Org.BouncyCastle.Math.BigInteger.ValueOf(1)).Mod(gen.n); one = w.Multiply(w1).Mod(gen.n); } privateKey = new MHPrivateKey(gen.a, w.ModInverse(gen.n), gen.n); }
public RsaSecretBcpgKey( BigInteger d, BigInteger p, BigInteger q) { // pgp requires (p < q) if (p.CompareTo(q) > 0) { BigInteger tmp = p; p = q; q = tmp; } this.d = new MPInteger(d); this.p = new MPInteger(p); this.q = new MPInteger(q); this.u = new MPInteger(p.ModInverse(q)); this.expP = d.Remainder(p.Subtract(BigInteger.One)); this.expQ = d.Remainder(q.Subtract(BigInteger.One)); this.crt = q.ModInverse(p); }
// 5.3 pg 28 /** * Generate a signature for the given message using the key we were * initialised with. For conventional DSA the message should be a SHA-1 * hash of the message of interest. * * @param message the message that will be verified later. */ public BigInteger[] GenerateSignature( byte[] message) { BigInteger n = key.Parameters.N; BigInteger e = calculateE(n, message); BigInteger r = null; BigInteger s = null; // 5.3.2 do // Generate s { BigInteger k = null; do // Generate r { do { k = new BigInteger(n.BitLength, random); } while (k.SignValue == 0 || k.CompareTo(n) >= 0); ECPoint p = key.Parameters.G.Multiply(k); // 5.3.3 BigInteger x = p.X.ToBigInteger(); r = x.Mod(n); } while (r.SignValue == 0); BigInteger d = ((ECPrivateKeyParameters)key).D; s = k.ModInverse(n).Multiply(e.Add(d.Multiply(r).Mod(n))).Mod(n); } while (s.SignValue == 0); return new BigInteger[]{ r, s }; }
// 5.3 pg 28 /** * Generate a signature for the given message using the key we were * initialised with. For conventional DSA the message should be a SHA-1 * hash of the message of interest. * * @param message the message that will be verified later. */ public IBigInteger[] GenerateSignature(byte[] message) { var n = _key.Parameters.N; var e = CalculateE(n, message); IBigInteger r; IBigInteger s; // 5.3.2 do // Generate s { IBigInteger k; do // Generate r { do { k = new BigInteger(n.BitLength, _random); } while (k.SignValue == 0 || k.CompareTo(n) >= 0); var p = _key.Parameters.G.Multiply(k); // 5.3.3 var x = p.X.ToBigInteger(); r = x.Mod(n); } while (r.SignValue == 0); var d = ((ECPrivateKeyParameters)_key).D; s = k.ModInverse(n).Multiply(e.Add(d.Multiply(r))).Mod(n); } while (s.SignValue == 0); return new[] { r, s }; }
private BigInteger ExtractUsersPrivateKey( ECPoint G, BigInteger N, string message1, string message2, BigInteger r1, BigInteger s1, BigInteger r2, BigInteger s2, BigInteger attackersPrivate, ECPoint attackersPublic, ECPoint usersPublic) { var m1 = new BigInteger(1, Hash(Encoding.UTF8.GetBytes(message1))); // hash of m1 var m2 = new BigInteger(1, Hash(Encoding.UTF8.GetBytes(message2))); // hash of m2 //calculate the result of verifying signature 1 var w = s1.ModInverse(N); var u1 = m1.Multiply(w).Mod(N); var u2 = r1.Multiply(w).Mod(N); var verifyPoint = ECAlgorithms.SumOfTwoMultiplies(G, u1, usersPublic, u2).Normalize(); //reinit K calculator to reproduce a,b,h,e var kCalc = new RandomDsaKCalculator(); kCalc.Init(N, new SecureRandom(new SeededGenerator(Hash(Encoding.UTF8.GetBytes(message2))))); var a = kCalc.NextK(); var b = kCalc.NextK(); var h = kCalc.NextK(); var e = kCalc.NextK(); var Z1 = verifyPoint.Multiply(a).Add(verifyPoint.Multiply(attackersPrivate).Multiply(b)); //cycle through all possible j & u for (int i = 0; i < 2; i++) for (int l = 0; l < 2; l++) { var j = new BigInteger(i.ToString()); var u = new BigInteger(l.ToString()); var Z2 = Z1.Add(G.Multiply(j).Multiply(h)).Add(attackersPublic.Multiply(u).Multiply(e)).Normalize(); var zX = Z2.AffineXCoord.ToBigInteger().ToByteArray(); var hash = Hash(zX); var kCandidate = new BigInteger(1, hash); var verifyPointCandidate = G.Multiply(kCandidate).Normalize(); var rCandidate = verifyPointCandidate.AffineXCoord.ToBigInteger().Mod(N); if (rCandidate.Equals(r2)) // Gotcha! { return s2.Multiply(kCandidate).Subtract(m2).Multiply(r2.ModInverse(N)).Mod(N); } } return null; }
// 5.3 pg 28 /** * Generate a signature for the given message using the key we were * initialised with. For conventional DSA the message should be a SHA-1 * hash of the message of interest. * * @param message the message that will be verified later. */ public BigInteger[] GenerateSignature(byte[] message) { ECDomainParameters ec = key.Parameters; BigInteger n = ec.N; BigInteger e = calculateE(n, message); BigInteger d = ((ECPrivateKeyParameters)key).D; BigInteger r, s; ECMultiplier basePointMultiplier = new FixedPointCombMultiplier(); // 5.3.2 do // Generate s { BigInteger k; do // Generate r { do { k = new BigInteger(n.BitLength, random); } while (k.SignValue == 0 || k.CompareTo(n) >= 0); ECPoint p = basePointMultiplier.Multiply(ec.G, k).Normalize(); // 5.3.3 r = p.AffineXCoord.ToBigInteger().Mod(n); } while (r.SignValue == 0); s = k.ModInverse(n).Multiply(e.Add(d.Multiply(r))).Mod(n); } while (s.SignValue == 0); return new BigInteger[]{ r, s }; }
public System.Numerics.BigInteger[] Merge(Part[][] parts, int threshold) { Org.BouncyCastle.Math.BigInteger p1 = new Org.BouncyCastle.Math.BigInteger(p.ToString()); Console.WriteLine("p1" + p1.ToString()); int secretSize = parts[0].Length; Console.WriteLine("secretsize" + secretSize); System.Numerics.BigInteger[] results = new System.Numerics.BigInteger[secretSize]; string[] secret = new string[secretSize]; byte[] ba; string str; int count = 0; // loop through each secret partition for (int i = 0; i < secretSize; i++) { Sum = System.Numerics.BigInteger.Zero; //doing lagrange interpolation for (int j = 0; j < threshold; j++) { mult = System.Numerics.BigInteger.One; for (int k = 0; k < threshold; k++) { if (j != k) { System.Numerics.BigInteger numerator = parts[k][i].GetX(); System.Numerics.BigInteger denominator = System.Numerics.BigInteger.Subtract(numerator, parts[j][i].GetX()); // take mod of negative number while (System.Numerics.BigInteger.Compare(denominator, System.Numerics.BigInteger.Zero) < 0) { denominator = System.Numerics.BigInteger.Add(denominator, p); } //convert to bouncycastle biginteger to calculate modInverse Org.BouncyCastle.Math.BigInteger denominator1 = new Org.BouncyCastle.Math.BigInteger(denominator.ToString()); Org.BouncyCastle.Math.BigInteger invDenominator1 = denominator1.ModInverse(p1); System.Numerics.BigInteger invDenominator = System.Numerics.BigInteger.Parse(invDenominator1.ToString()); mult = System.Numerics.BigInteger.Multiply(mult, System.Numerics.BigInteger.Multiply(numerator, invDenominator)); mult = System.Numerics.BigInteger.Remainder(mult, p); } } mult = System.Numerics.BigInteger.Multiply(mult, parts[j][i].GetY()); mult = System.Numerics.BigInteger.Remainder(mult, p); Sum = System.Numerics.BigInteger.Add(Sum, mult); Sum = System.Numerics.BigInteger.Remainder(Sum, p); } results[i] = Sum; } foreach (System.Numerics.BigInteger r in results) { //Console.WriteLine(r); //System.Numerics.BigInteger.TryParse ba = r.ToByteArray(); str = Encoding.UTF8.GetString(ba); //Console.WriteLine(str); secret[count++] = str; } str = string.Join("", secret); str.Replace("\n", ""); return(results); }
/** * return true if the value r and s represent a GOST3410 signature for * the passed in message (for standard GOST3410 the message should be * a GOST3411 hash of the real message to be verified). */ public virtual bool VerifySignature( byte[] message, BigInteger r, BigInteger s) { byte[] mRev = new byte[message.Length]; // conversion is little-endian for (int i = 0; i != mRev.Length; i++) { mRev[i] = message[mRev.Length - 1 - i]; } BigInteger e = new BigInteger(1, mRev); BigInteger n = key.Parameters.N; // r in the range [1,n-1] if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) { return false; } // s in the range [1,n-1] if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0) { return false; } BigInteger v = e.ModInverse(n); BigInteger z1 = s.Multiply(v).Mod(n); BigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n); ECPoint G = key.Parameters.G; // P ECPoint Q = ((ECPublicKeyParameters)key).Q; ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2).Normalize(); if (point.IsInfinity) return false; BigInteger R = point.AffineXCoord.ToBigInteger().Mod(n); return R.Equals(r); }
/** * return true if the value r and s represent a GOST3410 signature for * the passed in message (for standard GOST3410 the message should be * a GOST3411 hash of the real message to be verified). */ public bool VerifySignature( byte[] message, BigInteger r, BigInteger s) { byte[] mRev = new byte[message.Length]; // conversion is little-endian for (int i = 0; i != mRev.Length; i++) { mRev[i] = message[mRev.Length - 1 - i]; } BigInteger e = new BigInteger(1, mRev); BigInteger n = key.Parameters.N; // r in the range [1,n-1] if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) { return false; } // s in the range [1,n-1] if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0) { return false; } BigInteger v = e.ModInverse(n); BigInteger z1 = s.Multiply(v).Mod(n); BigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n); ECPoint G = key.Parameters.G; // P ECPoint Q = ((ECPublicKeyParameters)key).Q; ECPoint point = G.Multiply(z1).Add(Q.Multiply(z2)); BigInteger R = point.X.ToBigInteger().Mod(n); return R.Equals(r); }
// --- bs => s public BigInteger UnblindSignature(BigInteger bs, BigInteger r) { BigInteger s = ((r.ModInverse(n)).Multiply(bs)).Mod(n); return s; }
public void TestModInverse() { for (int i = 0; i < 10; ++i) { BigInteger p = BigInteger.ProbablePrime(64, random); BigInteger q = new BigInteger(63, random).Add(one); BigInteger inv = q.ModInverse(p); BigInteger inv2 = inv.ModInverse(p); Assert.AreEqual(q, inv2); Assert.AreEqual(one, q.Multiply(inv).Mod(p)); } }
/** * 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 bool VerifySignature( byte[] message, BigInteger r, BigInteger s) { DsaParameters parameters = key.Parameters; BigInteger q = parameters.Q; BigInteger m = calculateE(q, message); if (r.SignValue <= 0 || q.CompareTo(r) <= 0) { return false; } if (s.SignValue <= 0 || q.CompareTo(s) <= 0) { return false; } BigInteger w = s.ModInverse(q); BigInteger u1 = m.Multiply(w).Mod(q); BigInteger u2 = r.Multiply(w).Mod(q); BigInteger p = parameters.P; u1 = parameters.G.ModPow(u1, p); u2 = ((DsaPublicKeyParameters)key).Y.ModPow(u2, p); BigInteger v = u1.Multiply(u2).Mod(p).Mod(q); return v.Equals(r); }
public BigInteger ModPow( BigInteger exponent, BigInteger m) { if (m.sign < 1) throw new ArithmeticException("Modulus must be positive"); if (m.Equals(One)) return Zero; if (exponent.sign == 0) return One; if (sign == 0) return Zero; int[] zVal = null; int[] yAccum = null; int[] yVal; // Montgomery exponentiation is only possible if the modulus is odd, // but AFAIK, this is always the case for crypto algo's bool useMonty = ((m.magnitude[m.magnitude.Length - 1] & 1) == 1); long mQ = 0; if (useMonty) { mQ = m.GetMQuote(); // tmp = this * R mod m BigInteger tmp = ShiftLeft(32 * m.magnitude.Length).Mod(m); zVal = tmp.magnitude; useMonty = (zVal.Length <= m.magnitude.Length); if (useMonty) { yAccum = new int[m.magnitude.Length + 1]; if (zVal.Length < m.magnitude.Length) { int[] longZ = new int[m.magnitude.Length]; zVal.CopyTo(longZ, longZ.Length - zVal.Length); zVal = longZ; } } } if (!useMonty) { if (magnitude.Length <= m.magnitude.Length) { //zAccum = new int[m.magnitude.Length * 2]; zVal = new int[m.magnitude.Length]; magnitude.CopyTo(zVal, zVal.Length - magnitude.Length); } else { // // in normal practice we'll never see this... // BigInteger tmp = Remainder(m); //zAccum = new int[m.magnitude.Length * 2]; zVal = new int[m.magnitude.Length]; tmp.magnitude.CopyTo(zVal, zVal.Length - tmp.magnitude.Length); } yAccum = new int[m.magnitude.Length * 2]; } yVal = new int[m.magnitude.Length]; // // from LSW to MSW // for (int i = 0; i < exponent.magnitude.Length; i++) { int v = exponent.magnitude[i]; int bits = 0; if (i == 0) { while (v > 0) { v <<= 1; bits++; } // // first time in initialise y // zVal.CopyTo(yVal, 0); v <<= 1; bits++; } while (v != 0) { if (useMonty) { // Montgomery square algo doesn't exist, and a normal // square followed by a Montgomery reduction proved to // be almost as heavy as a Montgomery mulitply. MultiplyMonty(yAccum, yVal, yVal, m.magnitude, mQ); } else { Square(yAccum, yVal); Remainder(yAccum, m.magnitude); Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0, yVal.Length); ZeroOut(yAccum); } bits++; if (v < 0) { if (useMonty) { MultiplyMonty(yAccum, yVal, zVal, m.magnitude, mQ); } else { Multiply(yAccum, yVal, zVal); Remainder(yAccum, m.magnitude); Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0, yVal.Length); ZeroOut(yAccum); } } v <<= 1; } while (bits < 32) { if (useMonty) { MultiplyMonty(yAccum, yVal, yVal, m.magnitude, mQ); } else { Square(yAccum, yVal); Remainder(yAccum, m.magnitude); Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0, yVal.Length); ZeroOut(yAccum); } bits++; } } if (useMonty) { // Return y * R^(-1) mod m by doing y * 1 * R^(-1) mod m ZeroOut(zVal); zVal[zVal.Length - 1] = 1; MultiplyMonty(yAccum, yVal, zVal, m.magnitude, mQ); } BigInteger result = new BigInteger(1, yVal, true); return exponent.sign > 0 ? result : result.ModInverse(m); }
/** * Transforms a Pseudonym from {@code EG(S, y, k)} to {@code EG(S, y^(z^-1), k*z)} * @param z The inverse of the power to exponentiate {@code y} by * @return The transformed Pseudonym */ public Pseudonym KeyPower(BigInteger z) { return new Pseudonym( A.Multiply(z), B, C.Multiply(z.ModInverse(((FpCurve)C.Curve).Q))); }
public AsymmetricCipherKeyPair ComposeKeyPair(BigInteger p, BigInteger q, BigInteger publicExponent) { if (p.Max(q).Equals(q)) { var tmp = p; p = q; q = tmp; } var modulus = p.Multiply(q); var p1 = p.Subtract(BigInteger.One); var q1 = q.Subtract(BigInteger.One); var phi = p1.Multiply(q1); var privateExponent = publicExponent.ModInverse(phi); var dP = privateExponent.Remainder(p1); var dQ = privateExponent.Remainder(q1); var qInv = q.ModInverse(p); var priv = new RsaPrivateCrtKeyParameters(modulus, publicExponent, privateExponent, p, q, dP, dQ, qInv); return new AsymmetricCipherKeyPair(new RsaKeyParameters(false, priv.Modulus, publicExponent), priv); }
public static bool VerifySignature(DsaPublicKeyParameters public_key_param, byte[] data_to_sign_byte_array, byte[] r_byte_array, byte[] s_byte_array) { BigInteger _data_to_sign = new BigInteger(1, data_to_sign_byte_array); BigInteger _r = new BigInteger(1, r_byte_array); BigInteger _s = new BigInteger(1, s_byte_array); DsaParameters _parameters = public_key_param.Parameters; BigInteger zero = BigInteger.ValueOf(0); /* if (IsValidPQLength(_parameters.P.BitLength, _parameters.Q.BitLength) == false) throw new InvalidDataException("VerifySignature: The Length of the DSA key P parameter does not correspond to that of the Q parameter"); */ if (zero.CompareTo(_r) >= 0 || _parameters.Q.CompareTo(_r) <= 0) return false; if (zero.CompareTo(_s) >= 0 || _parameters.Q.CompareTo(_s) <= 0) return false; BigInteger _w = _s.ModInverse(_parameters.Q); BigInteger _u1 = _data_to_sign.Multiply(_w).Mod(_parameters.Q); BigInteger _u2 = _r.Multiply(_w).Mod(_parameters.Q); _u1 = _parameters.G.ModPow(_u1, _parameters.P); _u2 = public_key_param.Y.ModPow(_u2, _parameters.P); BigInteger _v = _u1.Multiply(_u2).Mod(_parameters.P).Mod(_parameters.Q); // Console.WriteLine("Size of Q:{0} \n Size of R:{1} \n Size of S:{2} ", _parameters.Q.BitLength/8, r_byte_array.Length, s_byte_array.Length); return _v.Equals(_r); }
public void GenerateSignature(byte[] data_to_sign_byte_array, ref byte[] r_byte_array, ref byte[] s_byte_array) { if (data_to_sign_byte_array == null || data_to_sign_byte_array.Length < 1) throw new ArgumentException("GenerateSignature: The data byte array to sign cannot be null/empty"); if (_private_key_param == null) throw new ArgumentException("GenerateSignature: The DSA private key cannot be null"); if (_secure_random == null) _secure_random = new SecureRandom(); BigInteger _data_to_sign = null; DsaParameters _parameters = null; BigInteger _k; BigInteger _r; BigInteger _s; int _q_bit_length; bool _do_again = false; int _failure_count = 0; _parameters = _private_key_param.Parameters; _data_to_sign = new BigInteger(1, data_to_sign_byte_array); _q_bit_length = _parameters.Q.BitLength; /* */ // if (IsValidPQLength(_parameters.P.BitLength, _parameters.Q.BitLength) == false) //throw new InvalidDataException("GenerateSignature: The Length of the DSA key P parameter does not correspond to that of the Q parameter"); do { try { do { _k = new BigInteger(1, _secure_random); } while (_k.CompareTo(_parameters.Q) >= 0); _r = _parameters.G.ModPow(_k, _parameters.P).Mod(_parameters.Q); _k = _k.ModInverse(_parameters.Q).Multiply(_data_to_sign.Add((_private_key_param).X.Multiply(_r))); _s = _k.Mod(_parameters.Q); r_byte_array = _r.ToByteArray(); s_byte_array = _s.ToByteArray(); _do_again = false; } catch (Exception) { if (MAX_FAILURE_COUNT == _failure_count) throw new InvalidDataException("GenerateSignature: Failed sign data after " + MAX_FAILURE_COUNT.ToString() + " tries."); _do_again = true; _failure_count++; } } while (_do_again == true); Utility.SetAsMinimalLengthBE(ref r_byte_array); Utility.SetAsMinimalLengthBE(ref s_byte_array); /* Console.WriteLine("Q Length {0} \n", _parameters.Q.BitLength/8); Console.WriteLine("R Length {0} \n", r_byte_array.Length); Console.WriteLine("S Length {0} \n", s_byte_array.Length);//*/ }
// 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 bool VerifySignature( byte[] message, BigInteger r, BigInteger s) { BigInteger n = key.Parameters.N; BigInteger e = calculateE(n, message); // r in the range [1,n-1] if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) { return false; } // s in the range [1,n-1] if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0) { return false; } 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 = G.Multiply(u1).Add(Q.Multiply(u2)); BigInteger v = point.X.ToBigInteger().Mod(n); return v.Equals(r); }
// 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 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; BigInteger v = point.X.ToBigInteger().Mod(n); return v.Equals(r); }
public void Backdoor() { var random = new SecureRandom(); var curve = CustomNamedCurves.GetByName("secp521r1"); var gen = new ECKeyPairGenerator("ECDSA"); var G = curve.G; var N = curve.N; var paramz = new ECDomainParameters(curve.Curve, G, N); gen.Init(new ECKeyGenerationParameters(paramz, random)); var kCalc = new RandomDsaKCalculator(); // kCalc generates random values [1, N-1] kCalc.Init(N, random); var attackersKeyPair = gen.GenerateKeyPair(); var v = ((ECPrivateKeyParameters)attackersKeyPair.Private).D; //attacker's private var V = G.Multiply(v); //attackers public var usersKeyPair = gen.GenerateKeyPair(); //user's keypair var D = ((ECPrivateKeyParameters)usersKeyPair.Private).D; //user's private var Q = ((ECPublicKeyParameters)usersKeyPair.Public).Q;//user's public const string message1 = "First message to sign"; var m1 = new BigInteger(1, Hash(Encoding.UTF8.GetBytes(message1))); // hash of m1 //Generate signature 1 var k1 = kCalc.NextK(); // k1 is true random var signaturePoint1 = G.Multiply(k1).Normalize(); //(r1, s1) - signature 1 var r1 = signaturePoint1.AffineXCoord.ToBigInteger().Mod(N); var s1 = k1.ModInverse(N).Multiply(m1.Add(D.Multiply(r1))); //verify signature 1 var w = s1.ModInverse(N); var u1 = m1.Multiply(w).Mod(N); var u2 = r1.Multiply(w).Mod(N); var verifyPoint1 = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2).Normalize(); var valid1 = verifyPoint1.AffineXCoord.ToBigInteger().Mod(N).Equals(r1); //Generate signature 2 const string message2 = "Second message to sign"; var m2 = new BigInteger(1, Hash(Encoding.UTF8.GetBytes(message2))); // hash of m2 //here we generate a,b,h,e < N using seed = hash(m2) kCalc.Init(N, new SecureRandom(new SeededGenerator(Hash(Encoding.UTF8.GetBytes(message2))))); var a = kCalc.NextK(); var b = kCalc.NextK(); var h = kCalc.NextK(); var e = kCalc.NextK(); //u,j - true random var u = (random.Next() % 2) == 1 ? BigInteger.One : BigInteger.Zero; var j = (random.Next() % 2) == 1 ? BigInteger.One : BigInteger.Zero; //compute hidden field element var Z = G.Multiply(k1).Multiply(a) .Add(V.Multiply(k1).Multiply(b)) .Add(G.Multiply(h).Multiply(j)) .Add(V.Multiply(e).Multiply(u)) .Normalize(); var zX = Z.AffineXCoord.ToBigInteger().ToByteArray(); var hash = Hash(zX); var k2 = new BigInteger(1, hash); var signaturePoint2 = G.Multiply(k2).Normalize(); //(r2, s2) = signature 2 var r2 = signaturePoint2.AffineXCoord.ToBigInteger().Mod(N); var s2 = k2.ModInverse(N).Multiply(m2.Add(D.Multiply(r2))); //verify signature 2 w = s2.ModInverse(N); u1 = m2.Multiply(w).Mod(N); u2 = r2.Multiply(w).Mod(N); var verifyPoint2 = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2).Normalize(); var valid2 = verifyPoint2.AffineXCoord.ToBigInteger().Mod(N).Equals(r2); if (valid1 && valid2) { //compute user's private key var d = ExtractUsersPrivateKey(G, N, message1, message2, r1, s1, r2, s2, v, V, Q); Console.WriteLine("Ecdsa private key restored: {0}", d.Equals(D)); } else { Console.WriteLine("Something's wrong"); } }
// 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); }
public void TestModInverse() { for (int i = 0; i < 10; ++i) { BigInteger p = BigInteger.ProbablePrime(64, random); BigInteger q = new BigInteger(63, random).Add(one); BigInteger inv = q.ModInverse(p); BigInteger inv2 = inv.ModInverse(p); Assert.AreEqual(q, inv2); Assert.AreEqual(one, q.Multiply(inv).Mod(p)); } // ModInverse a power of 2 for a range of powers for (int i = 1; i <= 128; ++i) { BigInteger m = one.ShiftLeft(i); BigInteger d = new BigInteger(i, random).SetBit(0); BigInteger x = d.ModInverse(m); BigInteger check = x.Multiply(d).Mod(m); Assert.AreEqual(one, check); } }