Ejemplo n.º 1
0
        /// <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));
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
 private static BigInteger CalculateD(BigInteger e, BigInteger phi)
 {
     return(e.ModInverse(phi));
 }