/// <summary> /// Creates an ECDSA instance by recovering a public key given a hash, recovery ID, and r and s components of the resulting signature of the hash. Throws an exception if recovery is not possible. /// </summary> /// <param name="hash">The hash of the data which was signed.</param> /// <param name="recoveryId">The recovery ID of ECDSA during signing.</param> /// <param name="ecdsa_r">The r component of the ECDSA signature for the provided hash.</param> /// <param name="ecdsa_s">The s component of the ECDSA signature for the provided hash.</param> /// <returns>Returns the quotient/public key which was used to sign this hash.</returns> public static new EthereumEcdsaBouncyCastle Recover(Span <byte> hash, byte recoveryId, BigInteger ecdsa_r, BigInteger ecdsa_s) { // Source: http://www.secg.org/sec1-v2.pdf (Section 4.1.6 - Public Key Recovery Operation) // Recovery ID must be between 0 and 4 (0 and 1 is all that should be used, but we support multiple cases in case) if (recoveryId < 0 || recoveryId > 3) { throw new ArgumentException($"ECDSA public key recovery must have a v parameter between [0, 3]. Value provided is {recoveryId.ToString(CultureInfo.InvariantCulture)}"); } // NOTES: // First bit of recoveryID being set means y is odd, otherwise it is even. // The second bit indicates which item of the two to choose. // If the hash is null, we'll assume it's a zero length byte array if (hash == null) { hash = Array.Empty <byte>(); } // Obtain our elliptic curve parameters Org.BouncyCastle.Math.BigInteger r = ecdsa_r.ToBouncyCastleBigInteger(); Org.BouncyCastle.Math.BigInteger s = ecdsa_s.ToBouncyCastleBigInteger(); Org.BouncyCastle.Math.BigInteger j = Org.BouncyCastle.Math.BigInteger.ValueOf((long)recoveryId >> 1); Org.BouncyCastle.Math.BigInteger x = j.Multiply(Secp256k1Curve.Parameters.N).Add(r); // To obtain our curve point R, we decode it with an extra byte for Y descriptor which mentions if Y is even or odd. int curveLength = X9IntegerConverter.GetByteLength(Secp256k1Curve.Parameters.Curve); byte[] xdata = X9IntegerConverter.IntegerToBytes(x, curveLength + 1); xdata[0] = (byte)(0x2 | (recoveryId & 1)); ECPoint r1 = Secp256k1Curve.Parameters.Curve.DecodePoint(xdata); // nR should be infinity. if (!r1.Multiply(Secp256k1Curve.Parameters.N).IsInfinity) { throw new ArgumentException("ECDSA's nR should be the point at infinity."); } // We obtain an integer representation of our hash. Org.BouncyCastle.Math.BigInteger e = new Org.BouncyCastle.Math.BigInteger(1, hash.ToArray()); // Next we'll want the multiplicative inverse of r (~r) Org.BouncyCastle.Math.BigInteger rInverse = r.ModInverse(Secp256k1Curve.Parameters.N); // Next we get the additive inverse of our hash, subtracting it from zero, and bounding it accordingly. Org.BouncyCastle.Math.BigInteger eAddInverse = Org.BouncyCastle.Math.BigInteger.Zero.Subtract(e).Mod(Secp256k1Curve.Parameters.N); // Using the inverse of r we have, we can multiply it by s to get our ~r * s. Org.BouncyCastle.Math.BigInteger rsInverse = rInverse.Multiply(s).Mod(Secp256k1Curve.Parameters.N); // Using the inverse of r we have, and the inverse of e, we can have ~r * -e Org.BouncyCastle.Math.BigInteger reInverse = rInverse.Multiply(eAddInverse).Mod(Secp256k1Curve.Parameters.N); // Q = ((~r * s) * R) + ((~r * -e) * G) => (~r * sR) + (~r * -eG) => ~r (sR - eG) ECPoint q = ECAlgorithms.SumOfTwoMultiplies(Secp256k1Curve.Parameters.G, reInverse, r1, rsInverse).Normalize(); // Obtain our public key from this return(new EthereumEcdsaBouncyCastle(Secp256k1Curve.Parameters.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()).GetEncoded(false), EthereumEcdsaKeyType.Public)); }
public RSA(int bits) { p = Helper.GenerateBigIntegerPrimes(bits); q = Helper.GenerateBigIntegerPrimes(bits); 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); }
public System.Numerics.BigInteger[] Merge(Part[][] parts, int threshold) { Org.BouncyCastle.Math.BigInteger p1 = new Org.BouncyCastle.Math.BigInteger(p.ToString()); int secretSize = parts[0].Length; System.Numerics.BigInteger[] results = new System.Numerics.BigInteger[secretSize]; string[] secret = new string[secretSize]; byte[] byteArray; 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) { byteArray = r.ToByteArray(); str = Encoding.UTF8.GetString(byteArray); secret[count++] = str; } return(results); }
private static BigInteger CalculateD(BigInteger e, BigInteger phi) { return(e.ModInverse(phi)); }