/// <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); }
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"; } }