public void CanGeneratePubKeysAndAddress() { //Took from http://brainwallet.org/ and http://procbits.com/2013/08/27/generating-a-bitcoin-address-with-javascript var tests = new[] { new { PrivateKeyWIF = "5Hx15HFGyep2CfPxsJKe2fXJsCVn5DEiyoeGGF6JZjGbTRnqfiD", CompressedPrivateKeyWIF = "KwomKti1X3tYJUUMb1TGSM2mrZk1wb1aHisUNHCQXTZq5auC2qc3", PubKey = "04d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6fbdd594388756a7beaf73b4822bc22d36e9bda7db82df2b8b623673eefc0b7495", CompressedPubKey = "03d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6f", Address = "16UjcYNBG9GTK4uq2f7yYEbuifqCzoLMGS", CompressedAddress = "1FkKMsKNJqWSDvTvETqcCeHcUQQ64kSC6s", Hash160 = "3c176e659bea0f29a3e9bf7880c112b1b31b4dc8", CompressedHash160 = "a1c2f92a9dacbd2991c3897724a93f338e44bdc1" }, new { PrivateKeyWIF = "5J7WTMRn1vjZ9udUxNCLq7F9DYEJiqRCjstiBrY6mDjnaomd6kZ", CompressedPrivateKeyWIF = "KxXj1KAMh6ApvKJ2PNZ4XLZRGLqjDehppFdEnueGSBDrC2Hfe7vt", PubKey = "0493e5d305cad2588d5fb254065fe48ce446028ba380e6ee663baea9cd105500897eb030c033cdab160f31c36df0ea38330fdd69677df49cd14826902022d17f3f", CompressedPubKey = "0393e5d305cad2588d5fb254065fe48ce446028ba380e6ee663baea9cd10550089", Address = "1MZmwgyMyjM11uA6ZSpgn1uK3LBWCzvV6e", CompressedAddress = "1AECNr2TDye8dpC1TeDH3eJpGoZ7dNPy4g", Hash160 = "e19557c8f8fb53a964c5dc7bfde86d806709f7c5", CompressedHash160 = "6538094af65453ea279f14d1a04b408e3adfebd7" } }; foreach (var test in tests) { BitcoinSecret secret = Network.Main.CreateBitcoinSecret(test.PrivateKeyWIF); Assert.Equal(test.PubKey, secret.PrivateKey.PubKey.ToHex()); var address = (BitcoinPubKeyAddress)Network.Main.CreateBitcoinAddress(test.Address); Assert.Equal(new KeyId(test.Hash160), address.Hash); Assert.Equal(new KeyId(test.Hash160), secret.PrivateKey.PubKey.Hash); Assert.Equal(new KeyId(test.Hash160).ToString(), test.Hash160); Assert.Equal(address, secret.PrivateKey.PubKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main)); Assert.Equal(new WitKeyId(test.Hash160).ToString(), address.Hash.ToString()); Assert.Equal(new WitKeyId(test.Hash160).ToString(), secret.PrivateKey.PubKey.Hash.ToString()); Assert.Equal(new WitKeyId(test.Hash160).ToString(), test.Hash160.ToString()); var compressedSec = secret.Copy(true); var a = secret.PrivateKey.PubKey; var b = compressedSec.PrivateKey.PubKey; Assert.Equal(test.CompressedPrivateKeyWIF, compressedSec.ToWif()); Assert.Equal(test.CompressedPubKey, compressedSec.PrivateKey.PubKey.ToHex()); Assert.True(compressedSec.PrivateKey.PubKey.IsCompressed); var compressedAddr = (BitcoinPubKeyAddress)Network.Main.CreateBitcoinAddress(test.CompressedAddress); Assert.Equal(new KeyId(test.CompressedHash160), compressedAddr.Hash); Assert.Equal(new KeyId(test.CompressedHash160), compressedSec.PrivateKey.PubKey.Hash); } }
public void Fork_stx_P2SH_P2WPKH_BTCP() { Assert.Inconclusive(); string coin = "BTCP"; string utx = "0100000002f080b83ab42f738cedf4ae611810982fc47c1076492e3b96c7d16903df894ea10000000000ffffffff681e3f81d1c4726f658f33223d1d43d4827809ab51eafc24a24982bbf9180edc0000000000ffffffff010eeb9d7c000000001976a914b3b255028648e151b3e419ab6c5b2e9656ba363988ac00000000"; string privK = ConfigurationManager.AppSettings["BTCP_STX_P2SH_P2WPKH_PK"]; //Ensure privK is compressed format var clientprivkey = new BitcoinSecret(privK, Network.BTCP); var clientprivcompressed = clientprivkey.Copy(compressed: true); string WIFKey = clientprivcompressed.ToWif(); string ustr = "[\r\n {\r\n \"transactionId\": \"dc0e18f9bb8249a224fcea51ab097882d4431d3d22338f656f72c4d1813f1e68\",\r\n \"index\": 0,\r\n \"value\": 2089853221,\r\n \"scriptPubKey\": \"a914040e95a6492afc5a7c572bec3e094728ec27ac9387\",\r\n \"redeemScript\": null\r\n },\r\n {\r\n \"transactionId\": \"a14e89df0369d1c7963b2e4976107cc42f98101861aef4ed8c732fb43ab880f0\",\r\n \"index\": 0,\r\n \"value\": 880889,\r\n \"scriptPubKey\": \"a914040e95a6492afc5a7c572bec3e094728ec27ac9387\",\r\n \"redeemScript\": null\r\n }\r\n]"; string expected = "0100000002f080b83ab42f738cedf4ae611810982fc47c1076492e3b96c7d16903df894ea1000000008147304402205be0a7f20c3d966cb6fedc8f943f5c3b696bfa862261e3b84104823a4173fc9802206bc1a1e7ef7e2485a6c4e651a81df234a3ca8dd94fa5504d9e424bf16d5cf24c4121027977c92d6ce6d6e19a992bb8589515951cb32b977f0513870c6a93f4e75f129d160014c2d6eb6b04819813312c0563706c5cc2008abbc8ffffffff681e3f81d1c4726f658f33223d1d43d4827809ab51eafc24a24982bbf9180edc0000000082483045022100e32214ccc2ab841173283c966c50f514b4b8a9d073fd5b712ab0553ee4cfa6ad0220217bcfb899edf13da2ea083cf8a62feb696478ece2e730337869df67263104ba4121027977c92d6ce6d6e19a992bb8589515951cb32b977f0513870c6a93f4e75f129d160014c2d6eb6b04819813312c0563706c5cc2008abbc8ffffffff010eeb9d7c000000001976a914b3b255028648e151b3e419ab6c5b2e9656ba363988ac00000000"; string stxStr = SignTransaction(coin, utx, ustr, WIFKey); Console.WriteLine(stxStr); Assert.AreEqual(expected, stxStr); }
public void Privk_PrivKeyUncompToComp() { var n = BitcoinForks.ForkByShortName["BTV"].Network; //can use any network which supports segwit //This is a Segwit P2SH-P2WPKH address string addr = "39atb9VMmV9UULHyjtYjakTf1wQ7RZiM2b"; //string addr = "14Z1kt7uUCB8rKwhauXmh5qFdv8cKK9fVj"; var ba = BitcoinAddress.Create(addr, n); Assert.IsTrue(ba is BitcoinScriptAddress); //This is the "wrong" private key - it is uncompressed string privK = "5JRjnSw2q6yKF2MJy9R4h3hLiVvSU8AK6oqRXV3YpeorY2SSP3m"; //string privK = "5J48ML87SFb8hGWJPLbCZYDfkMk3WZ8cgMbTMLCztiNXdWb9sPn"; string privKWIF = "KyvBqbTV5KMZWtxeJp9DHku42AesQic6tdijFYnFTKsodWYvWb6Q"; var clientprivkey = new BitcoinSecret(privK, n); var clientprivcompressed = clientprivkey.Copy(compressed: true); string WIFKey = clientprivcompressed.ToWif(); Assert.AreEqual(privKWIF, WIFKey); }
public void key_test1() { BitcoinSecret bsecret1 = this.networkMain.CreateBitcoinSecret(strSecret1); BitcoinSecret bsecret2 = this.networkMain.CreateBitcoinSecret(strSecret2); BitcoinSecret bsecret1C = this.networkMain.CreateBitcoinSecret(strSecret1C); BitcoinSecret bsecret2C = this.networkMain.CreateBitcoinSecret(strSecret2C); Assert.Throws <FormatException>(() => this.networkMain.CreateBitcoinSecret(strAddressBad)); Key key1 = bsecret1.PrivateKey; Assert.True(key1.IsCompressed == false); Assert.True(bsecret1.Copy(true).PrivateKey.IsCompressed == true); Assert.True(bsecret1.Copy(true).Copy(false).IsCompressed == false); Assert.True(bsecret1.Copy(true).Copy(false).ToString() == bsecret1.ToString()); Key key2 = bsecret2.PrivateKey; Assert.True(key2.IsCompressed == false); Key key1C = bsecret1C.PrivateKey; Assert.True(key1C.IsCompressed == true); Key key2C = bsecret2C.PrivateKey; Assert.True(key1C.IsCompressed == true); PubKey pubkey1 = key1.PubKey; PubKey pubkey2 = key2.PubKey; PubKey pubkey1C = key1C.PubKey; PubKey pubkey2C = key2C.PubKey; Assert.True(this.addr1.Hash == pubkey1.Hash); Assert.True(this.addr2.Hash == pubkey2.Hash); Assert.True(this.addr1C.Hash == pubkey1C.Hash); Assert.True(this.addr2C.Hash == pubkey2C.Hash); for (int n = 0; n < 16; n++) { string strMsg = String.Format("Very secret message {0}: 11", n); if (n == 10) { //Test one long message strMsg = String.Join(",", Enumerable.Range(0, 2000).Select(i => i.ToString()).ToArray()); } uint256 hashMsg = Hashes.Hash256(TestUtils.ToBytes(strMsg)); // normal signatures ECDSASignature sign1 = null, sign2 = null, sign1C = null, sign2C = null; var tasks = new List <Task>(); tasks.Add(Task.Run(() => sign1 = key1.Sign(hashMsg))); tasks.Add(Task.Run(() => sign2 = key2.Sign(hashMsg))); tasks.Add(Task.Run(() => sign1C = key1C.Sign(hashMsg))); tasks.Add(Task.Run(() => sign2C = key2C.Sign(hashMsg))); Task.WaitAll(tasks.ToArray()); tasks.Clear(); tasks.Add(Task.Run(() => Assert.True(pubkey1.Verify(hashMsg, sign1)))); tasks.Add(Task.Run(() => Assert.True(pubkey2.Verify(hashMsg, sign2)))); tasks.Add(Task.Run(() => Assert.True(pubkey1C.Verify(hashMsg, sign1C)))); tasks.Add(Task.Run(() => Assert.True(pubkey2C.Verify(hashMsg, sign2C)))); Task.WaitAll(tasks.ToArray()); tasks.Clear(); tasks.Add(Task.Run(() => Assert.True(pubkey1.Verify(hashMsg, sign1)))); tasks.Add(Task.Run(() => Assert.True(!pubkey1.Verify(hashMsg, sign2)))); tasks.Add(Task.Run(() => Assert.True(pubkey1.Verify(hashMsg, sign1C)))); tasks.Add(Task.Run(() => Assert.True(!pubkey1.Verify(hashMsg, sign2C)))); tasks.Add(Task.Run(() => Assert.True(!pubkey2.Verify(hashMsg, sign1)))); tasks.Add(Task.Run(() => Assert.True(pubkey2.Verify(hashMsg, sign2)))); tasks.Add(Task.Run(() => Assert.True(!pubkey2.Verify(hashMsg, sign1C)))); tasks.Add(Task.Run(() => Assert.True(pubkey2.Verify(hashMsg, sign2C)))); tasks.Add(Task.Run(() => Assert.True(pubkey1C.Verify(hashMsg, sign1)))); tasks.Add(Task.Run(() => Assert.True(!pubkey1C.Verify(hashMsg, sign2)))); tasks.Add(Task.Run(() => Assert.True(pubkey1C.Verify(hashMsg, sign1C)))); tasks.Add(Task.Run(() => Assert.True(!pubkey1C.Verify(hashMsg, sign2C)))); tasks.Add(Task.Run(() => Assert.True(!pubkey2C.Verify(hashMsg, sign1)))); tasks.Add(Task.Run(() => Assert.True(pubkey2C.Verify(hashMsg, sign2)))); tasks.Add(Task.Run(() => Assert.True(!pubkey2C.Verify(hashMsg, sign1C)))); tasks.Add(Task.Run(() => Assert.True(pubkey2C.Verify(hashMsg, sign2C)))); Task.WaitAll(tasks.ToArray()); tasks.Clear(); // compact signatures (with key recovery) byte[] csign1 = null, csign2 = null, csign1C = null, csign2C = null; tasks.Add(Task.Run(() => csign1 = key1.SignCompact(hashMsg))); tasks.Add(Task.Run(() => csign2 = key2.SignCompact(hashMsg))); tasks.Add(Task.Run(() => csign1C = key1C.SignCompact(hashMsg))); tasks.Add(Task.Run(() => csign2C = key2C.SignCompact(hashMsg))); Task.WaitAll(tasks.ToArray()); tasks.Clear(); PubKey rkey1 = null, rkey2 = null, rkey1C = null, rkey2C = null; tasks.Add(Task.Run(() => rkey1 = PubKey.RecoverCompact(hashMsg, csign1))); tasks.Add(Task.Run(() => rkey2 = PubKey.RecoverCompact(hashMsg, csign2))); tasks.Add(Task.Run(() => rkey1C = PubKey.RecoverCompact(hashMsg, csign1C))); tasks.Add(Task.Run(() => rkey2C = PubKey.RecoverCompact(hashMsg, csign2C))); Task.WaitAll(tasks.ToArray()); tasks.Clear(); Assert.True(rkey1.ToHex() == pubkey1.ToHex()); Assert.True(rkey2.ToHex() == pubkey2.ToHex()); Assert.True(rkey1C.ToHex() == pubkey1C.ToHex()); Assert.True(rkey2C.ToHex() == pubkey2C.ToHex()); } }
public void CanGeneratePubKeysAndAddress() { //Took from http://brainwallet.org/ and http://procbits.com/2013/08/27/generating-a-bitcoin-address-with-javascript var tests = new[] { new { PrivateKeyWIF = "5Hx15HFGyep2CfPxsJKe2fXJsCVn5DEiyoeGGF6JZjGbTRnqfiD", CompressedPrivateKeyWIF = "KwomKti1X3tYJUUMb1TGSM2mrZk1wb1aHisUNHCQXTZq5auC2qc3", PubKey = "04d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6fbdd594388756a7beaf73b4822bc22d36e9bda7db82df2b8b623673eefc0b7495", CompressedPubKey = "03d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6f", Address = "16UjcYNBG9GTK4uq2f7yYEbuifqCzoLMGS", CompressedAddress = "1FkKMsKNJqWSDvTvETqcCeHcUQQ64kSC6s", Hash160 = "3c176e659bea0f29a3e9bf7880c112b1b31b4dc8", CompressedHash160 = "a1c2f92a9dacbd2991c3897724a93f338e44bdc1", DER = "3082011302010104201184cd2cdd640ca42cfc3a091c51d549b2f016d454b2774019c2b2d2e08529fda081a53081a2020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a14403420004d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6fbdd594388756a7beaf73b4822bc22d36e9bda7db82df2b8b623673eefc0b7495", CompressedDER = "3081d302010104201184cd2cdd640ca42cfc3a091c51d549b2f016d454b2774019c2b2d2e08529fda08185308182020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a12403220003d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6f" }, new { PrivateKeyWIF = "5J7WTMRn1vjZ9udUxNCLq7F9DYEJiqRCjstiBrY6mDjnaomd6kZ", CompressedPrivateKeyWIF = "KxXj1KAMh6ApvKJ2PNZ4XLZRGLqjDehppFdEnueGSBDrC2Hfe7vt", PubKey = "0493e5d305cad2588d5fb254065fe48ce446028ba380e6ee663baea9cd105500897eb030c033cdab160f31c36df0ea38330fdd69677df49cd14826902022d17f3f", CompressedPubKey = "0393e5d305cad2588d5fb254065fe48ce446028ba380e6ee663baea9cd10550089", Address = "1MZmwgyMyjM11uA6ZSpgn1uK3LBWCzvV6e", CompressedAddress = "1AECNr2TDye8dpC1TeDH3eJpGoZ7dNPy4g", Hash160 = "e19557c8f8fb53a964c5dc7bfde86d806709f7c5", CompressedHash160 = "6538094af65453ea279f14d1a04b408e3adfebd7", DER = "308201130201010420271ac4d7056937c156abd828850d05df0697dd662d3c1b0107f53a387b4c176ca081a53081a2020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a1440342000493e5d305cad2588d5fb254065fe48ce446028ba380e6ee663baea9cd105500897eb030c033cdab160f31c36df0ea38330fdd69677df49cd14826902022d17f3f", CompressedDER = "3081d30201010420271ac4d7056937c156abd828850d05df0697dd662d3c1b0107f53a387b4c176ca08185308182020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a1240322000393e5d305cad2588d5fb254065fe48ce446028ba380e6ee663baea9cd10550089" } }; foreach (var test in tests) { BitcoinSecret secret = Network.Main.CreateBitcoinSecret(test.PrivateKeyWIF); Assert.Equal(test.PubKey, secret.Key.PubKey.ToHex()); TestDERCoherence(secret); TestDEREqual(test.DER, secret); var address = Network.Main.CreateBitcoinAddress(test.Address); Assert.Equal(new KeyId(test.Hash160), address.Hash); Assert.Equal(new KeyId(test.Hash160), secret.Key.PubKey.Hash); Assert.Equal(address.Hash, secret.Key.PubKey.GetAddress(Network.Main).Hash); var compressedSec = secret.Copy(true); TestDERCoherence(compressedSec); TestDEREqual(test.CompressedDER, compressedSec); var a = secret.Key.PubKey; var b = compressedSec.Key.PubKey; Assert.Equal(test.CompressedPrivateKeyWIF, compressedSec.ToWif()); Assert.Equal(test.CompressedPubKey, compressedSec.Key.PubKey.ToHex()); Assert.True(compressedSec.Key.PubKey.IsCompressed); var compressedAddr = Network.Main.CreateBitcoinAddress(test.CompressedAddress); Assert.Equal(new KeyId(test.CompressedHash160), compressedAddr.Hash); Assert.Equal(new KeyId(test.CompressedHash160), compressedSec.Key.PubKey.Hash); } }
static void Main(string[] args) { // Bitcoin var privateKeyBitcoin = "L4Y1cGSsNv1Nf9dZpTkEyQjLU24zRyRQeRyE5i4MoVvrjrr15Koy"; // Example https://komodoplatform.com/en/academy/bitcoin-private-key/ var privateKeyBillText = new BitcoinSecret(privateKeyBitcoin, Network.Main); var uncompressed = privateKeyBillText.Copy(false); var privateKeyBill = uncompressed.ToBytes(); var publicKeyBillText = privateKeyBillText.PubKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main).ToString(); var publicKeyBillTextUncompressed = uncompressed.PubKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main).ToString(); // TODO Remove var publicKeyBillHex = Convert.ToHexString(uncompressed.PubKey.ToBytes().Skip(1).ToArray()); // Data var data = new byte[] { 1, 2, 3 }; // var hash = SHA256.Create().ComputeHash(data); // Calculate hash of data. See also ECDsa.SignHash(); // PrivateKey var privateKey = privateKeyBill; // new byte[32] { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // RNGCryptoServiceProvider.Create().GetBytes(privateKey); // Fill random // PublicKey calculate var ecdsaCurve = ECCurve.CreateFromFriendlyName("secp256k1"); var ecdsa = ECDsa.Create(new ECParameters { Curve = ecdsaCurve, D = privateKey }); var publicAndPrivateKey = ecdsa.ExportParameters(true); // Sign var ecdsaSign = ECDsa.Create(new ECParameters { Curve = ecdsaCurve, D = publicAndPrivateKey.D, Q = publicAndPrivateKey.Q }); var signature = ecdsaSign.SignData(data, HashAlgorithmName.SHA256); // Needs private and public key // Verify var ecdsaVerify = ECDsa.Create(new ECParameters { Curve = ecdsaCurve, Q = publicAndPrivateKey.Q }); bool isValid = ecdsaVerify.VerifyData(data, signature, HashAlgorithmName.SHA256); // No private key needed! // Output var publicKey = Enumerable.Concat(publicAndPrivateKey.Q.X, publicAndPrivateKey.Q.Y).ToArray(); Console.WriteLine("PrivateKey=" + Convert.ToHexString(publicAndPrivateKey.D)); Console.WriteLine("PublicKey=" + Convert.ToHexString(publicKey)); Console.WriteLine("Data=" + Convert.ToHexString(data)); Console.WriteLine("IsValid=" + isValid); Debug.Assert(publicKeyBillHex == Convert.ToHexString(publicKey)); // P2PKH Address var x = new byte[65]; x[0] = 0x04; publicAndPrivateKey.Q.X.CopyTo(x, 1); publicAndPrivateKey.Q.Y.CopyTo(x, 33); var sha256 = System.Security.Cryptography.SHA256.Create().ComputeHash(x); var ripemd160 = RIPEMD160Managed.Create().ComputeHash(sha256); Debug.Assert(ripemd160.Length == 20); var publicKeyText = Base58CheckEncoding.Encode(Enumerable.Concat(new byte[] { 0 }, ripemd160).ToArray()); // Debug.Assert(publicKeyBillText == publicKeyText); // TODO Debug.Assert(publicKeyBillTextUncompressed == publicKeyText); // TODO Remove. Use compressed Console.WriteLine("Hello World!"); }
public void key_test1() { BitcoinSecret bsecret1 = Network.Main.CreateBitcoinSecret(strSecret1); BitcoinSecret bsecret2 = Network.Main.CreateBitcoinSecret(strSecret2); BitcoinSecret bsecret1C = Network.Main.CreateBitcoinSecret(strSecret1C); BitcoinSecret bsecret2C = Network.Main.CreateBitcoinSecret(strSecret2C); Assert.Throws <FormatException>(() => Network.Main.CreateBitcoinSecret(strAddressBad)); Key key1 = bsecret1.PrivateKey; Assert.True(key1.IsCompressed == false); Assert.True(bsecret1.Copy(true).PrivateKey.IsCompressed == true); Assert.True(bsecret1.Copy(true).Copy(false).IsCompressed == false); Assert.True(bsecret1.Copy(true).Copy(false).ToString() == bsecret1.ToString()); Key key2 = bsecret2.PrivateKey; Assert.True(key2.IsCompressed == false); Key key1C = bsecret1C.PrivateKey; Assert.True(key1C.IsCompressed == true); Key key2C = bsecret2C.PrivateKey; Assert.True(key1C.IsCompressed == true); PubKey pubkey1 = key1.PubKey; PubKey pubkey2 = key2.PubKey; PubKey pubkey1C = key1C.PubKey; PubKey pubkey2C = key2C.PubKey; Assert.True(addr1.Hash == pubkey1.Hash); Assert.True(addr2.Hash == pubkey2.Hash); Assert.True(addr1C.Hash == pubkey1C.Hash); Assert.True(addr2C.Hash == pubkey2C.Hash); for (int n = 0; n < 16; n++) { string strMsg = String.Format("Very secret message {0}: 11", n); if (n == 10) { //Test one long message strMsg = String.Join(",", Enumerable.Range(0, 2000).Select(i => i.ToString()).ToArray()); } uint256 hashMsg = Hashes.DoubleSHA256(TestUtils.ToBytes(strMsg)); // normal signatures ECDSASignature sign1 = null, sign2 = null, sign1C = null, sign2C = null; List <Task> tasks = new List <Task>(); sign1 = key1.Sign(hashMsg); sign2 = key2.Sign(hashMsg); sign1C = key1C.Sign(hashMsg); sign2C = key2C.Sign(hashMsg); for (int i = 0; i < 30; i++) { Assert.True(pubkey1.Verify(hashMsg, sign1)); Assert.True(pubkey2.Verify(hashMsg, sign2)); Assert.True(pubkey1C.Verify(hashMsg, sign1C)); Assert.True(pubkey2C.Verify(hashMsg, sign2C)); Assert.True(pubkey1.Verify(hashMsg, sign1)); Assert.True(!pubkey1.Verify(hashMsg, sign2)); Assert.True(pubkey1.Verify(hashMsg, sign1C)); Assert.True(!pubkey1.Verify(hashMsg, sign2C)); Assert.True(!pubkey2.Verify(hashMsg, sign1)); Assert.True(pubkey2.Verify(hashMsg, sign2)); Assert.True(!pubkey2.Verify(hashMsg, sign1C)); Assert.True(pubkey2.Verify(hashMsg, sign2C)); Assert.True(pubkey1C.Verify(hashMsg, sign1)); Assert.True(!pubkey1C.Verify(hashMsg, sign2)); Assert.True(pubkey1C.Verify(hashMsg, sign1C)); Assert.True(!pubkey1C.Verify(hashMsg, sign2C)); Assert.True(!pubkey2C.Verify(hashMsg, sign1)); Assert.True(pubkey2C.Verify(hashMsg, sign2)); Assert.True(!pubkey2C.Verify(hashMsg, sign1C)); Assert.True(pubkey2C.Verify(hashMsg, sign2C)); } // compact signatures (with key recovery) byte[] csign1 = null, csign2 = null, csign1C = null, csign2C = null; csign1 = key1.SignCompact(hashMsg); csign2 = key2.SignCompact(hashMsg); csign1C = key1C.SignCompact(hashMsg); csign2C = key2C.SignCompact(hashMsg); PubKey rkey1 = null, rkey2 = null, rkey1C = null, rkey2C = null; rkey1 = PubKey.RecoverCompact(hashMsg, csign1); rkey2 = PubKey.RecoverCompact(hashMsg, csign2); rkey1C = PubKey.RecoverCompact(hashMsg, csign1C); rkey2C = PubKey.RecoverCompact(hashMsg, csign2C); Assert.True(rkey1.ToHex() == pubkey1.ToHex()); Assert.True(rkey2.ToHex() == pubkey2.ToHex()); Assert.True(rkey1C.ToHex() == pubkey1C.ToHex()); Assert.True(rkey2C.ToHex() == pubkey2C.ToHex()); Assert.True(sign1.IsLowR && sign1.ToDER().Length <= 70); Assert.True(sign2.IsLowR && sign2.ToDER().Length <= 70); Assert.True(sign1C.IsLowR && sign1C.ToDER().Length <= 70); Assert.True(sign2C.IsLowR && sign2C.ToDER().Length <= 70); } }