public MqvPublicParameters(
     ECPublicKeyParameters	staticPublicKey,
     ECPublicKeyParameters	ephemeralPublicKey)
 {
     this.staticPublicKey = staticPublicKey;
     this.ephemeralPublicKey = ephemeralPublicKey;
 }
        // 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);

            ECCurve curve = parameters.Curve;

            ECPoint[] points = new ECPoint[]{
                // The Q2U public key is optional
                ECAlgorithms.ImportPoint(curve, Q2U == null ? parameters.G.Multiply(d2U.D) : Q2U.Q),
                ECAlgorithms.ImportPoint(curve, Q1V.Q),
                ECAlgorithms.ImportPoint(curve, Q2V.Q)
            };

            curve.NormalizeAll(points);

            ECPoint q2u = points[0], q1v = points[1], q2v = points[2];

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

            BigInteger xPrime = q2v.AffineXCoord.ToBigInteger();
            BigInteger xPrimeBar = xPrime.Mod(powE);
            BigInteger Q2VBar = xPrimeBar.SetBit(e);

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

            return ECAlgorithms.SumOfTwoMultiplies(
                q1v, Q2VBar.Multiply(hs).Mod(n), q2v, hs);
        }
        internal static PublicKey Derivate(this PublicKey publicKey, byte[] cc, uint nChild, Network network, out byte[] ccChild)
        {
            byte[] lr = null;
            byte[] l = new byte[32];
            byte[] r = new byte[32];
            if ((nChild >> 31) == 0)
            {
                var pubKey = publicKey.ToBytes();
                lr = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.Skip(1).ToArray());
            }
            else
            {
                throw new InvalidOperationException("A public key can't derivate an hardened child");
            }
            Array.Copy(lr, l, 32);
            Array.Copy(lr, 32, r, 0, 32);
            ccChild = r;

            BigInteger N = ECHelper.CURVE.N;
            BigInteger parse256LL = new BigInteger(1, l);

            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 eq = ECHelper.Secp256k1.Curve.DecodePoint(publicKey.ToBytes());
            var publicKeyParameters = new ECPublicKeyParameters("EC", eq, ECHelper.DomainParameter);

            var q = ECHelper.CURVE.G.Multiply(parse256LL).Add(publicKeyParameters.Q);
            if (q.IsInfinity)
                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 p = new BitcoinKit.BouncyCastle.Math.EC.FpPoint(ECHelper.CURVE.Curve, q.X, q.Y, true);
            return new PublicKey(p.GetEncoded(), network);
        }
 protected bool Equals(
     ECPublicKeyParameters other)
 {
     return q.Equals(other.q) && base.Equals(other);
 }