예제 #1
0
        /// <summary>	Gets shared secret. </summary>
        ///
        /// def get_shared_secret(priv, pub) :
        ///    pub_point  = pub.point()
        ///    priv_point = int(repr(priv),16)
        ///    res     = pub_point * priv_point
        ///    res_hex = '%032x' % res.x()
        ///    return res_hex
        ///
        /// <remarks>	Paul, 26/10/2015. </remarks>
        ///
        /// <returns>	The shared secret. </returns>
        static public byte[] GetSharedSecret(KeyPair priv, PublicKey pub)
        {
            var ps = SecNamedCurves.GetByName("secp256k1");

            BigInteger ipriv    = new BigInteger(1, priv.PrivateKeyBytes);
            ECPoint    pubPoint = pub.GetECPoint();

            ECPoint shared = pubPoint.Multiply(ipriv);

            BigInteger s = shared.X.ToBigInteger();

            byte[] data = s.ToByteArray();

            int leadingZeros = -1;

            while (data[++leadingZeros] == 0)
            {
                ;
            }

            byte[] result = new byte[data.Length - leadingZeros];
            Buffer.BlockCopy(data, leadingZeros, result, 0, result.Length);

            return(result);
        }
예제 #2
0
        private void btnCombine_Click(object sender, EventArgs e)
        {
            // What is input #1?

            string    input1 = txtInput1.Text;
            string    input2 = txtInput2.Text;
            PublicKey pub1 = null, pub2 = null;
            KeyPair   kp1 = null, kp2 = null;


            if (KeyPair.IsValidPrivateKey(input1))
            {
                pub1 = kp1 = new KeyPair(input1);
            }
            else if (PublicKey.IsValidPublicKey(input1))
            {
                pub1 = new PublicKey(input1);
            }
            else
            {
                MessageBox.Show("Input key #1 is not a valid Public Key or Private Key Hex", "Can't combine", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (KeyPair.IsValidPrivateKey(input2))
            {
                pub2 = kp2 = new KeyPair(input2);
            }
            else if (PublicKey.IsValidPublicKey(input2))
            {
                pub2 = new PublicKey(input2);
            }
            else
            {
                MessageBox.Show("Input key #2 is not a valid Public Key or Private Key Hex", "Can't combine", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (kp1 == null && kp2 == null && rdoAdd.Checked == false)
            {
                MessageBox.Show("Can't multiply two public keys.  At least one of the keys must be a private key.",
                                "Can't combine", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (pub1.IsCompressedPoint != pub2.IsCompressedPoint)
            {
                MessageBox.Show("Can't combine a compressed key with an uncompressed key.", "Can't combine", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (pub1.AddressBase58 == pub2.AddressBase58)
            {
                if (MessageBox.Show("Both of the key inputs have the same public key hash.  You can continue, but " +
                                    "the results are probably going to be wrong.  You might have provided the wrong " +
                                    "information, such as two parts from the same side of the transaction, instead " +
                                    "of one part from each side.  Continue anyway?", "Duplicate Key Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK)
                {
                    return;
                }
            }

            var ps = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");

            // Combining two private keys?
            if (kp1 != null && kp2 != null)
            {
                BigInteger e1        = new BigInteger(1, kp1.PrivateKeyBytes);
                BigInteger e2        = new BigInteger(1, kp2.PrivateKeyBytes);
                BigInteger ecombined = (rdoAdd.Checked ? e1.Add(e2) : e1.Multiply(e2)).Mod(ps.N);


                System.Diagnostics.Debug.WriteLine(kp1.PublicKeyHex);
                System.Diagnostics.Debug.WriteLine(kp2.PublicKeyHex);
                KeyPair kpcombined = new KeyPair(Util.Force32Bytes(ecombined.ToByteArrayUnsigned()), compressed: kp1.IsCompressedPoint);

                txtOutputAddress.Text = kpcombined.AddressBase58;
                txtOutputPubkey.Text  = kpcombined.PublicKeyHex.Replace(" ", "");
                txtOutputPriv.Text    = kpcombined.PrivateKeyBase58;
            }
            else if (kp1 != null || kp2 != null)
            {
                // Combining one public and one private

                KeyPair   priv = (kp1 == null) ? kp2 : kp1;
                PublicKey pub  = (kp1 == null) ? pub1 : pub2;

                ECPoint point = pub.GetECPoint();

                ECPoint   combined   = rdoAdd.Checked ? point.Add(priv.GetECPoint()) : point.Multiply(new BigInteger(1, priv.PrivateKeyBytes));
                ECPoint   combinedc  = ps.Curve.CreatePoint(combined.X.ToBigInteger(), combined.Y.ToBigInteger(), priv.IsCompressedPoint);
                PublicKey pkcombined = new PublicKey(combinedc.GetEncoded());
                txtOutputAddress.Text = pkcombined.AddressBase58;
                txtOutputPubkey.Text  = pkcombined.PublicKeyHex.Replace(" ", "");
                txtOutputPriv.Text    = "Only available when combining two private keys";
            }
            else
            {
                // Adding two public keys
                ECPoint   combined   = pub1.GetECPoint().Add(pub2.GetECPoint());
                ECPoint   combinedc  = ps.Curve.CreatePoint(combined.X.ToBigInteger(), combined.Y.ToBigInteger(), pub1.IsCompressedPoint);
                PublicKey pkcombined = new PublicKey(combinedc.GetEncoded());
                txtOutputAddress.Text = pkcombined.AddressBase58;
                txtOutputPubkey.Text  = pkcombined.PublicKeyHex.Replace(" ", "");
                txtOutputPriv.Text    = "Only available when combining two private keys";
            }
        }