Ejemplo n.º 1
0
        /**
         * Checks, if the point multiplication algorithm of the given point yields
         * the same result as point multiplication done by the reference
         * implementation given in <code>multiply()</code>. This method chooses a
         * random number by which the given point <code>p</code> is multiplied.
         *
         * @param p
         *            The point to be multiplied.
         * @param numBits
         *            The bitlength of the random number by which <code>p</code>
         *            is multiplied.
         */
        private void ImplTestMultiply(ECPoint p, int numBits)
        {
            BigInteger k    = new BigInteger(numBits, secRand);
            ECPoint    reff = ECAlgorithms.ReferenceMultiply(p, k);
            ECPoint    q    = p.Multiply(k);

            AssertPointsEqual("ECPoint.Multiply is incorrect", reff, q);
        }
Ejemplo n.º 2
0
 public static ECKey RecoverFromSignature(int recId, ECDSASignature sig, byte[] message, bool compressed)
 {
   if (recId \        throw new ArgumentException("recId should be positive");
   if (sig.R.SignValue \        throw new ArgumentException("r should be positive");
   if (sig.S.SignValue \        throw new ArgumentException("s should be positive");
   if (message == null)
     throw new ArgumentNullException("message");
   var curve = Secp256k1;
   // 1.0 For j from 0 to h   (h == recId here and the loop is outside this function)
   //   1.1 Let x = r + jn
   var n = curve.N;
   var i = BigInteger.ValueOf((long)recId / 2);
   var x = sig.R.Add(i.Multiply(n));
   //   1.2. Convert the integer x to an octet string X of length mlen using the conversion routine
   //        specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or mlen = ⌈m/8⌉.
   //   1.3. Convert the octet string (16 set binary digits)||X to an elliptic curve point R using the
   //        conversion routine specified in Section 2.3.4. If this conversion routine outputs “invalid”, then
   //        do another iteration of Step 1.
   //
   // More concisely, what these points mean is to use X as a compressed public key.
   //using bouncy and Q value of Point
   var prime = new BigInteger(1,
       Org.BouncyCastle.Utilities.Encoders.Hex.Decode(
           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"));
   if (x.CompareTo(prime) \>\= 0)
     return null;
   // Compressed keys require you to know an extra bit of data about the y-coord as there are two possibilities.
   // So it's encoded in the recId.
   var R = DecompressKey(x, (recId & 1) == 1);
   //   1.4. If nR != point at infinity, then do another iteration of Step 1 (callers responsibility).
   if (!R.Multiply(n).IsInfinity)
     return null;
   //   1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification.
   var e = new BigInteger(1, message);
   //   1.6. For k from 1 to 2 do the following.   (loop is outside this function via iterating recId)
   //   1.6.1. Compute a candidate public key as:
   //               Q = mi(r) * (sR - eG)
   //
   // Where mi(x) is the modular multiplicative inverse. We transform this into the following:
   //               Q = (mi(r) * s ** R) + (mi(r) * -e ** G)
   // Where -e is the modular additive inverse of e, that is z such that z + e = 0 (mod n). In the above equation
   // ** is point multiplication and + is point addition (the EC group operator).
   //
   // We can find the additive inverse by subtracting e from zero then taking the mod. For example the additive
   // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod 11 = 8.
   var eInv = BigInteger.Zero.Subtract(e).Mod(n);
   var rInv = sig.R.ModInverse(n);
   var srInv = rInv.Multiply(sig.S).Mod(n);
   var eInvrInv = rInv.Multiply(eInv).Mod(n);
   var q = ECAlgorithms.SumOfTwoMultiplies(curve.G, eInvrInv, R, srInv);
   q = q.Normalize();
   if (compressed)
   {
     q = Secp256k1.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger());
     return new ECKey(q.GetEncoded(true), false);
   }
   return new ECKey(q.GetEncoded(), false);
 }
Ejemplo n.º 3
0
    protected internal bool SatisfiesCofactor()
    {
        BigInteger cofactor = Curve.Cofactor;

        if (cofactor != null && !cofactor.Equals(BigInteger.One))
        {
            return(!ECAlgorithms.ReferenceMultiply(this, cofactor).IsInfinity);
        }
        return(true);
    }
Ejemplo n.º 4
0
        public static byte GetRecoveryId(byte[] sigR, byte[] sigS, byte[] message, byte[] publicKey)
        {
            //ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1");
            X9ECParameters spec = ECNamedCurveTable.GetByName("secp256k1");

            BigInteger pointN = spec.N;

            for (int recoveryId = 0; recoveryId < 2; recoveryId++)
            {
                try
                {
                    BigInteger pointX = new BigInteger(1, sigR);

                    byte[] compEnc =
                        X9IntegerConverter.IntegerToBytes(pointX, 1 + X9IntegerConverter.GetByteLength(spec.Curve));
                    compEnc[0] = (byte)((recoveryId & 1) == 1 ? 0x03 : 0x02);
                    ECPoint pointR = spec.Curve.DecodePoint(compEnc);
                    if (!pointR.Multiply(pointN).IsInfinity)
                    {
                        continue;
                    }

                    BigInteger pointE        = new BigInteger(1, message);
                    BigInteger pointEInv     = BigInteger.Zero.Subtract(pointE).Mod(pointN);
                    BigInteger pointRInv     = new BigInteger(1, sigR).ModInverse(pointN);
                    BigInteger srInv         = pointRInv.Multiply(new BigInteger(1, sigS)).Mod(pointN);
                    BigInteger pointEInvRInv = pointRInv.Multiply(pointEInv).Mod(pointN);
                    ECPoint    pointQ        = ECAlgorithms.SumOfTwoMultiplies(spec.G, pointEInvRInv, pointR, srInv);
                    byte[]     pointQBytes   = pointQ.GetEncoded(false);
                    bool       matchedKeys   = true;
                    for (int j = 0; j < publicKey.Length; j++)
                    {
                        if (pointQBytes[j] != publicKey[j])
                        {
                            matchedKeys = false;
                            break;
                        }
                    }

                    if (!matchedKeys)
                    {
                        continue;
                    }

                    return((byte)(0xFF & recoveryId));
                }
                catch (Exception e)
                {
                    continue;
                    Console.WriteLine(" Failed: GET recoveryID");
                }
            }

            return((byte)0xFF);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        // Section 7.2.6 ECVP-NR, pg 35

        /**
         * return true if the value r and s represent a signature for the
         * message passed in. Generally, the order of the curve should be at
         * least as long as the hash of the message of interest, and with
         * ECNR, it *must* be at least as long.  But just in case the signer
         * applied mod(n) to the longer digest, this implementation will
         * apply mod(n) during verification.
         *
         * @param digest  the digest to be verified.
         * @param r       the r value of the signature.
         * @param s       the s value of the signature.
         * @exception DataLengthException if the digest is longer than the key allows
         */
        public bool VerifySignature(
            byte[]          message,
            BigInteger r,
            BigInteger s)
        {
            if (this.forSigning)
            {
                // not properly initilaized... deal with it
                throw new InvalidOperationException("not initialised for verifying");
            }

            ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key;
            BigInteger            n      = pubKey.Parameters.N;
            int nBitLength = n.BitLength;

            BigInteger e          = new BigInteger(1, message);
            int        eBitLength = e.BitLength;

            if (eBitLength > nBitLength)
            {
                throw new DataLengthException("input too large for ECNR key.");
            }

            // r in the range [1,n-1]
            if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
            {
                return(false);
            }

            // TODO So why is this different from the spec?
            // s in the range [0,n-1]           NB: ECNR spec says 0
            if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0)
            {
                return(false);
            }

            // compute P = sG + rW

            ECPoint G = pubKey.Parameters.G;
            ECPoint W = pubKey.Q;
            // calculate P using Bouncy math
            ECPoint P = ECAlgorithms.SumOfTwoMultiplies(G, s, W, r);

            if (P.IsInfinity)
            {
                return(false);
            }

            BigInteger x = P.X.ToBigInteger();
            BigInteger t = r.Subtract(x).Mod(n);

            return(t.Equals(e));
        }
Ejemplo n.º 7
0
        public virtual ECPoint Multiply(ECPoint p, BigInteger k)
        {
            int signValue = k.SignValue;

            if (signValue == 0 || p.IsInfinity)
            {
                return(p.Curve.Infinity);
            }
            ECPoint eCPoint = MultiplyPositive(p, k.Abs());
            ECPoint p2      = (signValue <= 0) ? eCPoint.Negate() : eCPoint;

            return(ECAlgorithms.ValidatePoint(p2));
        }
Ejemplo n.º 8
0
        protected virtual ECPoint CalculateU(SM2KeyExchangePublicParameters otherPub)
        {
            ECPoint p1 = otherPub.StaticPublicKey.Q;
            ECPoint p2 = otherPub.EphemeralPublicKey.Q;

            BigInteger x1 = Reduce(mEphemeralPubPoint.AffineXCoord.ToBigInteger());
            BigInteger x2 = Reduce(p2.AffineXCoord.ToBigInteger());
            BigInteger tA = mStaticKey.D.Add(x1.Multiply(mEphemeralKey.D));
            BigInteger k1 = mECParams.H.Multiply(tA).Mod(mECParams.N);
            BigInteger k2 = k1.Multiply(x2).Mod(mECParams.N);

            return(ECAlgorithms.SumOfTwoMultiplies(p1, k1, p2, k2).Normalize());
        }
Ejemplo n.º 9
0
        /**
         * Checks, if the point multiplication algorithm of the given point yields
         * the same result as point multiplication done by the reference
         * implementation given in <code>multiply()</code>. This method tests
         * multiplication of <code>p</code> by every number of bitlength
         * <code>numBits</code> or less.
         *
         * @param p
         *            The point to be multiplied.
         * @param numBits
         *            Try every multiplier up to this bitlength
         */
        private void ImplTestMultiplyAll(ECPoint p, int numBits)
        {
            BigInteger bound = BigInteger.One.ShiftLeft(numBits);
            BigInteger k     = BigInteger.Zero;

            do
            {
                ECPoint reff = ECAlgorithms.ReferenceMultiply(p, k);
                ECPoint q    = p.Multiply(k);
                AssertPointsEqual("ECPoint.Multiply is incorrect", reff, q);
                k = k.Add(BigInteger.One);
            }while (k.CompareTo(bound) < 0);
        }
Ejemplo n.º 10
0
        public static ECPoint DeserializeECPoint(byte[] ecPointFormats, ECCurve curve, byte[] encoding)
        {
            if (encoding == null || encoding.Length < 1)
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }

            byte actualFormat;

            switch (encoding[0])
            {
            case 0x02: // compressed
            case 0x03: // compressed
            {
                if (ECAlgorithms.IsF2mCurve(curve))
                {
                    actualFormat = ECPointFormat.ansiX962_compressed_char2;
                }
                else if (ECAlgorithms.IsFpCurve(curve))
                {
                    actualFormat = ECPointFormat.ansiX962_compressed_prime;
                }
                else
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }
                break;
            }

            case 0x04: // uncompressed
            {
                actualFormat = ECPointFormat.uncompressed;
                break;
            }

            case 0x00: // infinity
            case 0x06: // hybrid
            case 0x07: // hybrid
            default:
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }

            if (actualFormat != ECPointFormat.uncompressed &&
                (ecPointFormats == null || !Arrays.Contains(ecPointFormats, actualFormat)))
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }

            return(curve.DecodePoint(encoding));
        }
Ejemplo n.º 11
0
        /**
         * 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)
        {
            if (forSigning)
            {
                throw new InvalidOperationException("not initialized for verification");
            }

            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));
        }
Ejemplo n.º 12
0
        public static void WriteExplicitECParameters(byte[] ecPointFormats, ECDomainParameters ecParameters,
                                                     Stream output)
        {
            ECCurve curve = ecParameters.Curve;

            if (ECAlgorithms.IsFpCurve(curve))
            {
                TlsUtilities.WriteUint8(ECCurveType.explicit_prime, output);

                WriteECParameter(curve.Field.Characteristic, output);
            }
            else if (ECAlgorithms.IsF2mCurve(curve))
            {
                IPolynomialExtensionField field = (IPolynomialExtensionField)curve.Field;
                int[] exponents = field.MinimalPolynomial.GetExponentsPresent();

                TlsUtilities.WriteUint8(ECCurveType.explicit_char2, output);

                int m = exponents[exponents.Length - 1];
                TlsUtilities.CheckUint16(m);
                TlsUtilities.WriteUint16(m, output);

                if (exponents.Length == 3)
                {
                    TlsUtilities.WriteUint8(ECBasisType.ec_basis_trinomial, output);
                    WriteECExponent(exponents[1], output);
                }
                else if (exponents.Length == 5)
                {
                    TlsUtilities.WriteUint8(ECBasisType.ec_basis_pentanomial, output);
                    WriteECExponent(exponents[1], output);
                    WriteECExponent(exponents[2], output);
                    WriteECExponent(exponents[3], output);
                }
                else
                {
                    throw new ArgumentException("Only trinomial and pentomial curves are supported");
                }
            }
            else
            {
                throw new ArgumentException("'ecParameters' not a known curve type");
            }

            WriteECFieldElement(curve.A, output);
            WriteECFieldElement(curve.B, output);
            TlsUtilities.WriteOpaque8(SerializeECPoint(ecPointFormats, ecParameters.G), output);
            WriteECParameter(ecParameters.N, output);
            WriteECParameter(ecParameters.H, output);
        }
Ejemplo n.º 13
0
        public static byte[] SerializeECPoint(byte[] ecPointFormats, ECPoint point)
        {
            ECCurve curve      = point.Curve;
            bool    compressed = false;

            if (ECAlgorithms.IsFpCurve(curve))
            {
                compressed = IsCompressionPreferred(ecPointFormats, 1);
            }
            else if (ECAlgorithms.IsF2mCurve(curve))
            {
                compressed = IsCompressionPreferred(ecPointFormats, 2);
            }
            return(point.GetEncoded(compressed));
        }
Ejemplo n.º 14
0
        public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
        {
            BigInteger n = key.Parameters.N;

            if (r.SignValue < 1 || s.SignValue < 1 || r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0)
            {
                return(false);
            }
            BigInteger bigInteger = CalculateE(n, message);
            BigInteger val        = s.ModInverse(n);
            BigInteger a          = bigInteger.Multiply(val).Mod(n);
            BigInteger b          = r.Multiply(val).Mod(n);
            ECPoint    g          = key.Parameters.G;
            ECPoint    q          = ((ECPublicKeyParameters)key).Q;
            ECPoint    eCPoint    = ECAlgorithms.SumOfTwoMultiplies(g, a, q, b);

            if (eCPoint.IsInfinity)
            {
                return(false);
            }
            ECCurve curve = eCPoint.Curve;

            if (curve != null)
            {
                BigInteger cofactor = curve.Cofactor;
                if (cofactor != null && cofactor.CompareTo(Eight) <= 0)
                {
                    ECFieldElement denominator = GetDenominator(curve.CoordinateSystem, eCPoint);
                    if (denominator != null && !denominator.IsZero)
                    {
                        ECFieldElement xCoord = eCPoint.XCoord;
                        while (curve.IsValidFieldElement(r))
                        {
                            ECFieldElement eCFieldElement = curve.FromBigInteger(r).Multiply(denominator);
                            if (eCFieldElement.Equals(xCoord))
                            {
                                return(true);
                            }
                            r = r.Add(n);
                        }
                        return(false);
                    }
                }
            }
            BigInteger bigInteger2 = eCPoint.Normalize().AffineXCoord.ToBigInteger().Mod(n);

            return(bigInteger2.Equals(r));
        }
Ejemplo n.º 15
0
        private void ImplValidityTest(ECCurve c, ECPoint g)
        {
            Assert.IsTrue(g.IsValid());

            BigInteger h = c.Cofactor;

            if (h != null && h.CompareTo(BigInteger.One) > 0)
            {
                if (ECAlgorithms.IsF2mCurve(c))
                {
                    ECPoint order2 = c.CreatePoint(BigInteger.Zero, c.B.Sqrt().ToBigInteger());
                    ECPoint bad    = g.Add(order2);
                    Assert.IsFalse(bad.IsValid());
                }
            }
        }
        // The ECMQV Primitive as described in SEC-1, 3.4
        private static ECPoint calculateMqvAgreement(
            ECDomainParameters parameters,
            ECPrivateKeyParameters d1U,
            ECPrivateKeyParameters d2U,
            ECPublicKeyParameters Q2U,
            ECPublicKeyParameters Q1V,
            ECPublicKeyParameters Q2V)
        {
            BigInteger n    = parameters.N;
            int        e    = (n.BitLength + 1) / 2;
            BigInteger powE = BigInteger.One.ShiftLeft(e);

            // The Q2U public key is optional
            ECPoint q;

            if (Q2U == null)
            {
                q = parameters.G.Multiply(d2U.D);
            }
            else
            {
                q = Q2U.Q;
            }

            BigInteger x      = q.X.ToBigInteger();
            BigInteger xBar   = x.Mod(powE);
            BigInteger Q2UBar = xBar.SetBit(e);
            BigInteger s      = d1U.D.Multiply(Q2UBar).Mod(n).Add(d2U.D).Mod(n);

            BigInteger xPrime    = Q2V.Q.X.ToBigInteger();
            BigInteger xPrimeBar = xPrime.Mod(powE);
            BigInteger Q2VBar    = xPrimeBar.SetBit(e);

            BigInteger hs = parameters.H.Multiply(s).Mod(n);

            //ECPoint p = Q1V.Q.Multiply(Q2VBar).Add(Q2V.Q).Multiply(hs);
            ECPoint p = ECAlgorithms.SumOfTwoMultiplies(
                Q1V.Q, Q2VBar.Multiply(hs).Mod(n), Q2V.Q, hs);

            if (p.IsInfinity)
            {
                throw new InvalidOperationException("Infinity is not a valid agreement value for MQV");
            }

            return(p);
        }
Ejemplo n.º 17
0
        public static void WriteExplicitECParameters(byte[] ecPointFormats, ECDomainParameters ecParameters, Stream output)
        {
            //IL_00b2: Unknown result type (might be due to invalid IL or missing references)
            //IL_00bd: Unknown result type (might be due to invalid IL or missing references)
            ECCurve curve = ecParameters.Curve;

            if (ECAlgorithms.IsFpCurve(curve))
            {
                TlsUtilities.WriteUint8(1, output);
                WriteECParameter(curve.Field.Characteristic, output);
            }
            else
            {
                if (!ECAlgorithms.IsF2mCurve(curve))
                {
                    throw new ArgumentException("'ecParameters' not a known curve type");
                }
                IPolynomialExtensionField polynomialExtensionField = (IPolynomialExtensionField)curve.Field;
                int[] exponentsPresent = polynomialExtensionField.MinimalPolynomial.GetExponentsPresent();
                TlsUtilities.WriteUint8(2, output);
                int i = exponentsPresent[exponentsPresent.Length - 1];
                TlsUtilities.CheckUint16(i);
                TlsUtilities.WriteUint16(i, output);
                if (exponentsPresent.Length == 3)
                {
                    TlsUtilities.WriteUint8(1, output);
                    WriteECExponent(exponentsPresent[1], output);
                }
                else
                {
                    if (exponentsPresent.Length != 5)
                    {
                        throw new ArgumentException("Only trinomial and pentomial curves are supported");
                    }
                    TlsUtilities.WriteUint8(2, output);
                    WriteECExponent(exponentsPresent[1], output);
                    WriteECExponent(exponentsPresent[2], output);
                    WriteECExponent(exponentsPresent[3], output);
                }
            }
            WriteECFieldElement(curve.A, output);
            WriteECFieldElement(curve.B, output);
            TlsUtilities.WriteOpaque8(SerializeECPoint(ecPointFormats, ecParameters.G), output);
            WriteECParameter(ecParameters.N, output);
            WriteECParameter(ecParameters.H, output);
        }
Ejemplo n.º 18
0
        public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
        {
            BigInteger n = this.key.Parameters.N;

            if (((r.SignValue < 1) || (s.SignValue < 1)) || ((r.CompareTo(n) >= 0) || (s.CompareTo(n) >= 0)))
            {
                return(false);
            }
            BigInteger integer2 = this.CalculateE(n, message);
            BigInteger val      = s.ModInverse(n);
            BigInteger a        = integer2.Multiply(val).Mod(n);
            BigInteger b        = r.Multiply(val).Mod(n);
            ECPoint    g        = this.key.Parameters.G;
            ECPoint    q        = ((ECPublicKeyParameters)this.key).Q;
            ECPoint    p        = ECAlgorithms.SumOfTwoMultiplies(g, a, q, b);

            if (p.IsInfinity)
            {
                return(false);
            }
            ECCurve curve = p.Curve;

            if (curve != null)
            {
                BigInteger cofactor = curve.Cofactor;
                if ((cofactor != null) && (cofactor.CompareTo(Eight) <= 0))
                {
                    ECFieldElement denominator = this.GetDenominator(curve.CoordinateSystem, p);
                    if ((denominator != null) && !denominator.IsZero)
                    {
                        ECFieldElement xCoord = p.XCoord;
                        while (curve.IsValidFieldElement(r))
                        {
                            if (curve.FromBigInteger(r).Multiply(denominator).Equals(xCoord))
                            {
                                return(true);
                            }
                            r = r.Add(n);
                        }
                        return(false);
                    }
                }
            }
            return(p.Normalize().AffineXCoord.ToBigInteger().Mod(n).Equals(r));
        }
Ejemplo n.º 19
0
        public virtual ECPoint Multiply(ECPoint p, BigInteger k)
        {
            int sign = k.SignValue;

            if (sign == 0 || p.IsInfinity)
            {
                return(p.Curve.Infinity);
            }

            ECPoint positive = MultiplyPositive(p, k.Abs());
            ECPoint result   = sign > 0 ? positive : positive.Negate();

            /*
             * Although the various multipliers ought not to produce invalid output under normal
             * circumstances, a final check here is advised to guard against fault attacks.
             */
            return(ECAlgorithms.ValidatePoint(result));
        }
Ejemplo n.º 20
0
        private bool VerifySignature(BigInteger r, BigInteger s)
        {
            BigInteger n = ecParams.N;

            // 5.3.1 Draft RFC:  SM2 Public Key Algorithms
            // B1
            if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
            {
                return(false);
            }

            // B2
            if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0)
            {
                return(false);
            }

            // B3
            byte[] eHash = DigestUtilities.DoFinal(digest);

            // B4
            BigInteger e = CalculateE(n, eHash);

            // B5
            BigInteger t = r.Add(s).Mod(n);

            if (t.SignValue == 0)
            {
                return(false);
            }

            // B6
            ECPoint q    = ((ECPublicKeyParameters)ecKey).Q;
            ECPoint x1y1 = ECAlgorithms.SumOfTwoMultiplies(ecParams.G, s, q, t).Normalize();

            if (x1y1.IsInfinity)
            {
                return(false);
            }

            // B7
            return(r.Equals(e.Add(x1y1.AffineXCoord.ToBigInteger()).Mod(n)));
        }
Ejemplo n.º 21
0
        private void ImplValidityTest(ECCurve c, ECPoint g)
        {
            Assert.IsTrue(g.IsValid());

            if (ECAlgorithms.IsF2mCurve(c))
            {
                BigInteger h = c.Cofactor;
                if (null != h)
                {
                    if (!h.TestBit(0))
                    {
                        ECFieldElement sqrtB  = c.B.Sqrt();
                        ECPoint        order2 = c.CreatePoint(BigInteger.Zero, sqrtB.ToBigInteger());
                        Assert.IsTrue(order2.Twice().IsInfinity);
                        Assert.IsFalse(order2.IsValid());
                        ECPoint bad2 = g.Add(order2);
                        Assert.IsFalse(bad2.IsValid());
                        ECPoint good2 = bad2.Add(order2);
                        Assert.IsTrue(good2.IsValid());

                        if (!h.TestBit(1))
                        {
                            ECFieldElement L = SolveQuadraticEquation(c, c.A);
                            Assert.IsNotNull(L);
                            ECFieldElement T      = sqrtB;
                            ECFieldElement x      = T.Sqrt();
                            ECFieldElement y      = T.Add(x.Multiply(L));
                            ECPoint        order4 = c.CreatePoint(x.ToBigInteger(), y.ToBigInteger());
                            Assert.IsTrue(order4.Twice().Equals(order2));
                            Assert.IsFalse(order4.IsValid());
                            ECPoint bad4_1 = g.Add(order4);
                            Assert.IsFalse(bad4_1.IsValid());
                            ECPoint bad4_2 = bad4_1.Add(order4);
                            Assert.IsFalse(bad4_2.IsValid());
                            ECPoint bad4_3 = bad4_2.Add(order4);
                            Assert.IsFalse(bad4_3.IsValid());
                            ECPoint good4 = bad4_3.Add(order4);
                            Assert.IsTrue(good4.IsValid());
                        }
                    }
                }
            }
        }
Ejemplo n.º 22
0
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            if (!this.curve.Equals(p.Curve))
            {
                throw new InvalidOperationException();
            }
            BigInteger order = p.Curve.Order;

            BigInteger[] array    = this.glvEndomorphism.DecomposeScalar(k.Mod(order));
            BigInteger   k2       = array[0];
            BigInteger   l        = array[1];
            ECPointMap   pointMap = this.glvEndomorphism.PointMap;

            if (this.glvEndomorphism.HasEfficientPointMap)
            {
                return(ECAlgorithms.ImplShamirsTrickWNaf(p, k2, pointMap, l));
            }
            return(ECAlgorithms.ImplShamirsTrickWNaf(p, k2, pointMap.Map(p), l));
        }
Ejemplo n.º 23
0
        public static ECKey RecoverFromSignature(int rec_id, ECDSASignature signautre, byte[] message, bool compressed)
        {
            if (rec_id < 0)
                throw new ArgumentException("rec_id must be positive");
            if (signautre.R.SignValue < 0)
                throw new ArgumentException("ECDSASignature R must be positive");
            if (signautre.S.SignValue < 0)
                throw new ArgumentException("ECDSASignature S must be positive");
            if (message == null)
                throw new ArgumentNullException("Recovery signature message is null");

            var curve = Secp256k1;
            var n = curve.N;
            var i = BigInteger.ValueOf((long)rec_id / 2);
            var x = signautre.R.Add(i.Multiply(n));
            var prime = new BigInteger(1,
                Org.BouncyCastle.Utilities.Encoders.Hex.Decode(
                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"));
            if (x.CompareTo(prime) >= 0)
                return null;

            var R = DecompressKey(x, (rec_id & 1) == 1);

            if (!R.Multiply(n).IsInfinity)
                return null;

            var e = new BigInteger(1, message);
            var e_inv = BigInteger.Zero.Subtract(e).Mod(n);
            var r_inv = signautre.R.ModInverse(n);
            var sr_inv = r_inv.Multiply(signautre.S).Mod(n);
            var e_invr_inv = r_inv.Multiply(e_inv).Mod(n);
            var q = ECAlgorithms.SumOfTwoMultiplies(curve.G, e_invr_inv, R, sr_inv);
            q = q.Normalize();

            if (compressed)
            {
                q = Secp256k1.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger());
                return new ECKey(q.GetEncoded(true), false);
            }

            return new ECKey(q.GetEncoded(), false);
        }
Ejemplo n.º 24
0
        /**
         * Recover the public key from signature and message.
         * @param recId recovery id which 0 or 1.
         * @param sig {@link ECDSASignature} a signature object
         * @param message message bytes array.
         * @return public key represented by {@link BigInteger}
         */
        public static BigInteger RecoverFromSignature(int recId, ECDSASignature sig, byte[] message)
        {
            if (!(recId == 0 || recId == 1))
            {
                throw new ArgumentOutOfRangeException(nameof(recId), "recId must be 0 or 1");
            }
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message), "message cannot be null");
            }


            BigInteger n = ECKeyPair.Curve.N; // Curve order.
            BigInteger i = BigInteger.ValueOf((long)recId / 2);
            BigInteger x = sig.R.Add(i.Multiply(n));

            // TODO SecP256K1Curve
            //BigInteger prime = SecP256K1Curve.q;
            //if (x.CompareTo(prime) >= 0)
            //{
            //    return null;
            //}

            ECPoint R = DecompressKey(x, (recId & 1) == 1);

            if (!R.Multiply(n).IsInfinity)
            {
                return(null);
            }

            BigInteger e = new BigInteger(1, message);

            BigInteger eInv     = BigInteger.Zero.Subtract(e).Mod(n);
            BigInteger rInv     = sig.R.ModInverse(n);
            BigInteger srInv    = rInv.Multiply(sig.S).Mod(n);
            BigInteger eInvrInv = rInv.Multiply(eInv).Mod(n);
            ECPoint    q        = ECAlgorithms.SumOfTwoMultiplies(ECKeyPair.Curve.G, eInvrInv, R, srInv);

            byte[] qBytes = q.GetEncoded(false);
            // We remove the prefix
            return(new BigInteger(1, Arrays.CopyOfRange(qBytes, 1, qBytes.Length)));
        }
Ejemplo n.º 25
0
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            if (!this.curve.Equals(p.Curve))
            {
                throw new InvalidOperationException();
            }

            var        n = p.Curve.Order;
            var        ab = this.glvEndomorphism.DecomposeScalar(k.Mod(n));
            BigInteger a = ab[0], b = ab[1];

            var pointMap = this.glvEndomorphism.PointMap;

            if (this.glvEndomorphism.HasEfficientPointMap)
            {
                return(ECAlgorithms.ImplShamirsTrickWNaf(p, a, pointMap, b));
            }

            return(ECAlgorithms.ImplShamirsTrickWNaf(p, a, pointMap.Map(p), b));
        }
Ejemplo n.º 26
0
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            //IL_0013: Unknown result type (might be due to invalid IL or missing references)
            if (!curve.Equals(p.Curve))
            {
                throw new InvalidOperationException();
            }
            BigInteger order = p.Curve.Order;

            BigInteger[] array    = glvEndomorphism.DecomposeScalar(k.Mod(order));
            BigInteger   k2       = array[0];
            BigInteger   l        = array[1];
            ECPointMap   pointMap = glvEndomorphism.PointMap;

            if (glvEndomorphism.HasEfficientPointMap)
            {
                return(ECAlgorithms.ImplShamirsTrickWNaf(p, k2, pointMap, l));
            }
            return(ECAlgorithms.ImplShamirsTrickWNaf(p, k2, pointMap.Map(p), l));
        }
Ejemplo n.º 27
0
 public X9Curve(ECCurve curve, byte[] seed)
 {
     if (curve == null)
     {
         throw new ArgumentNullException("curve");
     }
     this.curve = curve;
     this.seed  = Arrays.Clone(seed);
     if (ECAlgorithms.IsFpCurve(curve))
     {
         this.fieldIdentifier = X9ObjectIdentifiers.PrimeField;
         return;
     }
     if (ECAlgorithms.IsF2mCurve(curve))
     {
         this.fieldIdentifier = X9ObjectIdentifiers.CharacteristicTwoField;
         return;
     }
     throw new ArgumentException("This type of ECCurve is not implemented");
 }
Ejemplo n.º 28
0
        private ECPoint CalculatePoint(ECPublicKeyParameters pubKeyParams)
        {
            ECDomainParameters dp = keyParam.Parameters;

            if (!dp.Equals(pubKeyParams.Parameters))
            {
                throw new InvalidOperationException(
                          "ECDH public key has wrong domain parameters"
                          );
            }

            BigInteger d = keyParam.D;

            ECPoint q = dp.Curve.DecodePoint(pubKeyParams.Q.GetEncoded(true));

            if (q.IsInfinity)
            {
                throw new InvalidOperationException(
                          "Infinity is not a valid public key for ECDH"
                          );
            }

            BigInteger h = dp.H;

            if (!h.Equals(BigInteger.One))
            {
                d = dp.H.ModInverse(dp.N).Multiply(d).Mod(dp.N);
                q = ECAlgorithms.ReferenceMultiply(q, h);
            }

            ECPoint p = q.Multiply(d).Normalize();

            if (p.IsInfinity)
            {
                throw new InvalidOperationException(
                          "Infinity is not a valid agreement value for ECDH"
                          );
            }

            return(p);
        }
Ejemplo n.º 29
0
        internal static ECPoint Validate(ECCurve c, ECPoint q)
        {
            if (q == null)
            {
                throw new ArgumentException("Point has null value", "q");
            }

            q = ECAlgorithms.ImportPoint(c, q).Normalize();

            if (q.IsInfinity)
            {
                throw new ArgumentException("Point at infinity", "q");
            }

            if (!q.IsValid())
            {
                throw new ArgumentException("Point not on curve", "q");
            }

            return(q);
        }
Ejemplo n.º 30
0
        internal static ECPoint ValidatePublicPoint(ECCurve c, ECPoint q)
        {
            if (null == q)
            {
                throw new ArgumentNullException("q", "Point cannot be null");
            }

            q = ECAlgorithms.ImportPoint(c, q).Normalize();

            if (q.IsInfinity)
            {
                throw new ArgumentException("Point at infinity", "q");
            }

            if (!q.IsValid())
            {
                throw new ArgumentException("Point not on curve", "q");
            }

            return(q);
        }