casascius (OP)
Mike Caldwell
VIP
Legendary
Offline
Activity: 1386
Merit: 1140
The Casascius 1oz 10BTC Silver Round (w/ Gold B)
|
|
July 01, 2011, 06:30:16 PM |
|
This is a utility I made that does all of the following conversions: BTCAddress <---> PubHash <---- PublicKey <---- PrivateKey <---> WalletImportFormatPrivateKey. It can also generate new Bitcoin addresses, as well as Testnet and Namecoin. It will correct single-character typos in Bitcoin addresses and private keys. It requires the BouncyCastle Crypto library at http://www.bouncycastle.org/csharp/ (just the compiled assembly is fine). You will have to compile it yourself. I don't want to look like a trojan scammer. File: Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Diagnostics; using System.Windows.Forms; using System.Security.Cryptography; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; using Org.BouncyCastle.Math.EC;
namespace BtcAddress { public partial class Form1 : Form { public Form1() { InitializeComponent(); }
private byte[] Base58ToByteArray(string base58) {
Org.BouncyCastle.Math.BigInteger bi2 = new Org.BouncyCastle.Math.BigInteger("0"); string b58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
bool IgnoreChecksum=false;
foreach (char c in base58) { if (b58.IndexOf(c) != -1) { bi2 = bi2.Multiply(new Org.BouncyCastle.Math.BigInteger("58")); bi2 = bi2.Add(new Org.BouncyCastle.Math.BigInteger(b58.IndexOf(c).ToString())); } else if (c=='?') { IgnoreChecksum = true; } else { return null; } }
byte[] bb = bi2.ToByteArrayUnsigned();
// interpret leading '1's as leading zero bytes foreach (char c in base58) { if (c != '1') break; byte[] bbb = new byte[bb.Length + 1]; Array.Copy(bb, 0, bbb, 1, bb.Length); bb = bbb; } if (bb.Length < 4) return null;
if (IgnoreChecksum == false) { SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider(); byte[] checksum = sha256.ComputeHash(bb, 0, bb.Length - 4); checksum = sha256.ComputeHash(checksum); for (int i = 0; i < 4; i++) { if (checksum[i] != bb[bb.Length - 4 + i]) return null; } }
byte[] rv = new byte[bb.Length - 4]; Array.Copy(bb, 0, rv, 0, bb.Length - 4); return rv; }
private string ByteArrayToString(byte[] ba) { return ByteArrayToString(ba, 0, ba.Length); }
private string ByteArrayToString(byte[] ba, int offset, int count) { string rv = ""; int usedcount = 0; for (int i=offset; usedcount<count; i++,usedcount++) { rv += String.Format("{0:X2}", ba[i]) + " "; } return rv; }
private string ByteArrayToBase58(byte[] ba) { Org.BouncyCastle.Math.BigInteger addrremain = new Org.BouncyCastle.Math.BigInteger(1,ba);
Org.BouncyCastle.Math.BigInteger big0 = new Org.BouncyCastle.Math.BigInteger("0"); Org.BouncyCastle.Math.BigInteger big58 = new Org.BouncyCastle.Math.BigInteger("58");
string b58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
string rv = "";
while (addrremain.CompareTo(big0) > 0) { int d = Convert.ToInt32(addrremain.Mod(big58).ToString()); addrremain = addrremain.Divide(big58); rv = b58.Substring(d, 1) + rv; }
// handle leading zeroes foreach (byte b in ba) { if (b != 0) break; rv = "1" + rv;
} return rv; }
private string ByteArrayToBase58Check(byte[] ba) {
byte[] bb = new byte[ba.Length + 4]; Array.Copy(ba, bb, ba.Length); SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider(); byte[] thehash = sha256.ComputeHash(ba); thehash = sha256.ComputeHash(thehash); for (int i = 0; i < 4; i++) bb[ba.Length + i] = thehash[i]; return ByteArrayToBase58(bb); }
private void button4_Click(object sender, EventArgs e) {
var ps = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");
}
private byte[] GetHexBytes(string source, int minimum) { byte[] hex = GetHexBytes(source); if (hex == null) return null; // assume leading zeroes if we're short a few bytes if (hex.Length > (minimum-6) && hex.Length < minimum) { byte[] hex2 = new byte[minimum]; Array.Copy(hex, 0, hex2, minimum - hex.Length, hex.Length); hex = hex2; } // clip off one overhanging leading zero if present if (hex.Length == minimum + 1 && hex[0] == 0) { byte[] hex2 = new byte[minimum]; Array.Copy(hex, 1, hex2, 0, minimum); hex = hex2;
}
return hex; }
private byte[] GetHexBytes(string source) {
List<byte> bytes = new List<byte>(); // copy s into ss, adding spaces between each byte string s = source; string ss = ""; int currentbytelength = 0; foreach (char c in s.ToCharArray()) { if (c == ' ') { currentbytelength = 0; } else { currentbytelength++; if (currentbytelength == 3) { currentbytelength = 1; ss += ' '; } } ss += c; }
foreach (string b in ss.Split(' ')) { int v = 0; if (b.Trim() == "") continue; foreach (char c in b.ToCharArray()) { if (c >= '0' && c <= '9') { v *= 16; v += (c - '0');
} else if (c >= 'a' && c <= 'f') { v *= 16; v += (c - 'a' + 10); } else if (c >= 'A' && c <= 'F') { v *= 16; v += (c - 'A' + 10); }
} v &= 0xff; bytes.Add((byte)v); } return bytes.ToArray(); }
private byte[] ValidateAndGetHexPrivateKey(byte leadingbyte) { byte[] hex = GetHexBytes(txtPrivHex.Text, 32);
if (hex == null || hex.Length < 32 || hex.Length > 33) { MessageBox.Show("Hex is not 32 or 33 bytes."); return null; }
// if leading 00, change it to 0x80 if (hex.Length == 33) { if (hex[0] == 0 || hex[0] == 0x80) { hex[0] = 0x80; } else { MessageBox.Show("Not a valid private key"); return null; } }
// add 0x80 byte if not present if (hex.Length == 32) { byte[] hex2 = new byte[33]; Array.Copy(hex, 0, hex2, 1, 32); hex2[0] = 0x80; hex = hex2; }
hex[0] = leadingbyte; return hex;
}
private byte[] ValidateAndGetHexPublicKey() { byte[] hex = GetHexBytes(txtPubHex.Text, 64);
if (hex == null || hex.Length < 64 || hex.Length > 65) { MessageBox.Show("Hex is not 64 or 65 bytes."); return null; }
// if leading 00, change it to 0x80 if (hex.Length == 65) { if (hex[0] == 0 || hex[0] == 4) { hex[0] = 4; } else { MessageBox.Show("Not a valid public key"); return null; } }
// add 0x80 byte if not present if (hex.Length == 64) { byte[] hex2 = new byte[65]; Array.Copy(hex, 0, hex2, 1, 64); hex2[0] = 4; hex = hex2; } return hex; }
private byte[] ValidateAndGetHexPublicHash() { byte[] hex = GetHexBytes(txtPubHash.Text, 20);
if (hex == null || hex.Length != 20 ) { MessageBox.Show("Hex is not 20 bytes."); return null; } return hex; }
private void btnPrivHexToWIF_Click(object sender, EventArgs e) { byte[] hex = ValidateAndGetHexPrivateKey(0x80); if (hex==null) return; txtPrivWIF.Text = ByteArrayToBase58Check(hex); }
private void btnPrivWIFToHex_Click(object sender, EventArgs e) { byte[] hex = Base58ToByteArray(txtPrivWIF.Text); if (hex == null) { int L = txtPrivWIF.Text.Length; if (L >= 50 && L <= 52) { if (MessageBox.Show("Private key is not valid. Attempt to correct?", "Invalid address", MessageBoxButtons.YesNo) == DialogResult.Yes) { CorrectWIF(); return; } } else { MessageBox.Show("WIF private key is not valid."); } return; } if (hex.Length != 33) { MessageBox.Show("WIF private key is not valid (wrong byte count, should be 33, was " + hex.Length + ")"); return; }
txtPrivHex.Text = ByteArrayToString(hex, 1, 32);
}
private void btnPrivToPub_Click(object sender, EventArgs e) { byte[] hex = ValidateAndGetHexPrivateKey(0x00); if (hex==null) return; var ps = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1"); Org.BouncyCastle.Math.BigInteger Db = new Org.BouncyCastle.Math.BigInteger(hex); ECPoint dd = ps.G.Multiply(Db);
byte[] pubaddr = new byte[65]; byte[] Y = dd.Y.ToBigInteger().ToByteArray(); Array.Copy(Y, 0, pubaddr, 64 - Y.Length + 1, Y.Length); byte[] X = dd.X.ToBigInteger().ToByteArray(); Array.Copy(X, 0, pubaddr, 32 - X.Length + 1, X.Length); pubaddr[0] = 4;
txtPubHex.Text = ByteArrayToString(pubaddr);
}
private void btnPubHexToHash_Click(object sender, EventArgs e) { byte[] hex = ValidateAndGetHexPublicKey(); if (hex == null) return;
SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider(); byte[] shaofpubkey = sha256.ComputeHash(hex);
RIPEMD160 rip = System.Security.Cryptography.RIPEMD160.Create(); byte[] ripofpubkey = rip.ComputeHash(shaofpubkey);
txtPubHash.Text = ByteArrayToString(ripofpubkey);
}
private void btnPubHashToAddress_Click(object sender, EventArgs e) { byte[] hex = ValidateAndGetHexPublicHash(); if (hex == null) return;
byte[] hex2 = new byte[21]; Array.Copy(hex, 0, hex2, 1, 20);
int cointype = 0; if (Int32.TryParse(cboCoinType.Text, out cointype) == false) cointype = 0;
if (cboCoinType.Text == "Testnet") cointype = 111; if (cboCoinType.Text == "Namecoin") cointype = 52; hex2[0] = (byte)(cointype & 0xff); txtBtcAddr.Text = ByteArrayToBase58Check(hex2); }
private void btnAddressToPubHash_Click(object sender, EventArgs e) { byte[] hex = Base58ToByteArray(txtBtcAddr.Text); if (hex == null || hex.Length != 21) { int L = txtBtcAddr.Text.Length; if (L >= 33 && L <= 34) { if (MessageBox.Show("Address is not valid. Attempt to correct?", "Invalid address", MessageBoxButtons.YesNo) == DialogResult.Yes) { CorrectBitcoinAddress(); return; } } else { MessageBox.Show("Address is not valid."); } return; } txtPubHash.Text = ByteArrayToString(hex, 1, 20);
}
private void btnGenerate_Click(object sender, EventArgs e) {
ECKeyPairGenerator gen = new ECKeyPairGenerator(); var secureRandom = new SecureRandom(); var ps = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1"); var ecParams = new ECDomainParameters(ps.Curve, ps.G, ps.N, ps.H); var keyGenParam = new ECKeyGenerationParameters(ecParams, secureRandom); gen.Init(keyGenParam);
AsymmetricCipherKeyPair kp = gen.GenerateKeyPair();
ECPrivateKeyParameters priv = (ECPrivateKeyParameters)kp.Private;
byte[] hexpriv = priv.D.ToByteArrayUnsigned(); txtPrivHex.Text = ByteArrayToString(hexpriv);
btnPrivHexToWIF_Click(null, null); btnPrivToPub_Click(null, null); btnPubHexToHash_Click(null, null); btnPubHashToAddress_Click(null, null);
}
private void btnBlockExplorer_Click(object sender, EventArgs e) { try { if (cboCoinType.Text == "Testnet") { Process.Start("http://www.blockexplorer.com/testnet/address/" + txtBtcAddr.Text); } else if (cboCoinType.Text == "Namecoin") { Process.Start("http://explorer.dot-bit.org/a/" + txtBtcAddr.Text); } else { Process.Start("http://www.blockexplorer.com/address/" + txtBtcAddr.Text); } } catch { } }
private void CorrectBitcoinAddress() { txtBtcAddr.Text = Correction(txtBtcAddr.Text); }
private string Correction(string btcaddr) { int btcaddrlen = btcaddr.Length; string b58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
for (int i = 0; i < btcaddrlen; i++) { for (int j = 0; j < 58; j++) { string attempt = btcaddr.Substring(0, i) + b58.Substring(j, 1) + btcaddr.Substring(i + 1); byte[] bytes = Base58ToByteArray(attempt); if (bytes != null) { MessageBox.Show("Correction was successful. Try your request again."); return attempt; } } } return btcaddr; }
private void CorrectWIF() { txtPrivWIF.Text = Correction(txtPrivWIF.Text); } } }
File: Form1.Designer.cs namespace BtcAddress { partial class Form1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null;
/// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); }
#region Windows Form Designer generated code
/// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.txtPrivWIF = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.txtPrivHex = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.txtPubHex = new System.Windows.Forms.TextBox(); this.label4 = new System.Windows.Forms.Label(); this.txtPubHash = new System.Windows.Forms.TextBox(); this.label5 = new System.Windows.Forms.Label(); this.txtBtcAddr = new System.Windows.Forms.TextBox(); this.btnAddressToPubHash = new System.Windows.Forms.Button(); this.btnPubHashToAddress = new System.Windows.Forms.Button(); this.btnPubHexToHash = new System.Windows.Forms.Button(); this.btnPrivToPub = new System.Windows.Forms.Button(); this.btnPrivWIFToHex = new System.Windows.Forms.Button(); this.btnPrivHexToWIF = new System.Windows.Forms.Button(); this.btnGenerate = new System.Windows.Forms.Button(); this.btnBlockExplorer = new System.Windows.Forms.Button(); this.cboCoinType = new System.Windows.Forms.ComboBox(); this.SuspendLayout(); // // txtPrivWIF // this.txtPrivWIF.Location = new System.Drawing.Point(103, 12); this.txtPrivWIF.Name = "txtPrivWIF"; this.txtPrivWIF.Size = new System.Drawing.Size(557, 20); this.txtPrivWIF.TabIndex = 7; // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(7, 15); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(90, 13); this.label1.TabIndex = 8; this.label1.Text = "Private Key (WIF)"; // // txtPrivHex // this.txtPrivHex.Location = new System.Drawing.Point(103, 70); this.txtPrivHex.Name = "txtPrivHex"; this.txtPrivHex.Size = new System.Drawing.Size(557, 20); this.txtPrivHex.TabIndex = 9; // // label2 // this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(7, 73); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(89, 13); this.label2.TabIndex = 10; this.label2.Text = "Private Key (Hex)"; // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(7, 131); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(85, 13); this.label3.TabIndex = 12; this.label3.Text = "Public Key (Hex)"; // // txtPubHex // this.txtPubHex.Location = new System.Drawing.Point(103, 128); this.txtPubHex.Multiline = true; this.txtPubHex.Name = "txtPubHex"; this.txtPubHex.Size = new System.Drawing.Size(557, 43); this.txtPubHex.TabIndex = 11; // // label4 // this.label4.AutoSize = true; this.label4.Location = new System.Drawing.Point(7, 216); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(91, 13); this.label4.TabIndex = 14; this.label4.Text = "Public Key (Hash)"; // // txtPubHash // this.txtPubHash.Location = new System.Drawing.Point(103, 213); this.txtPubHash.Name = "txtPubHash"; this.txtPubHash.Size = new System.Drawing.Size(557, 20); this.txtPubHash.TabIndex = 13; // // label5 // this.label5.AutoSize = true; this.label5.Location = new System.Drawing.Point(7, 274); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(45, 13); this.label5.TabIndex = 16; this.label5.Text = "Address"; // // txtBtcAddr // this.txtBtcAddr.Location = new System.Drawing.Point(103, 271); this.txtBtcAddr.Name = "txtBtcAddr"; this.txtBtcAddr.Size = new System.Drawing.Size(557, 20); this.txtBtcAddr.TabIndex = 15; // // btnAddressToPubHash // this.btnAddressToPubHash.Location = new System.Drawing.Point(286, 235); this.btnAddressToPubHash.Name = "btnAddressToPubHash"; this.btnAddressToPubHash.Size = new System.Drawing.Size(46, 30); this.btnAddressToPubHash.TabIndex = 18; this.btnAddressToPubHash.Text = "▲"; this.btnAddressToPubHash.UseVisualStyleBackColor = true; this.btnAddressToPubHash.Click += new System.EventHandler(this.btnAddressToPubHash_Click); // // btnPubHashToAddress // this.btnPubHashToAddress.Location = new System.Drawing.Point(334, 235); this.btnPubHashToAddress.Name = "btnPubHashToAddress"; this.btnPubHashToAddress.Size = new System.Drawing.Size(46, 30); this.btnPubHashToAddress.TabIndex = 19; this.btnPubHashToAddress.Text = "▼"; this.btnPubHashToAddress.UseVisualStyleBackColor = true; this.btnPubHashToAddress.Click += new System.EventHandler(this.btnPubHashToAddress_Click); // // btnPubHexToHash // this.btnPubHexToHash.Location = new System.Drawing.Point(334, 177); this.btnPubHexToHash.Name = "btnPubHexToHash"; this.btnPubHexToHash.Size = new System.Drawing.Size(46, 30); this.btnPubHexToHash.TabIndex = 21; this.btnPubHexToHash.Text = "▼"; this.btnPubHexToHash.UseVisualStyleBackColor = true; this.btnPubHexToHash.Click += new System.EventHandler(this.btnPubHexToHash_Click); // // btnPrivToPub // this.btnPrivToPub.Location = new System.Drawing.Point(334, 92); this.btnPrivToPub.Name = "btnPrivToPub"; this.btnPrivToPub.Size = new System.Drawing.Size(46, 30); this.btnPrivToPub.TabIndex = 23; this.btnPrivToPub.Text = "▼"; this.btnPrivToPub.UseVisualStyleBackColor = true; this.btnPrivToPub.Click += new System.EventHandler(this.btnPrivToPub_Click); // // btnPrivWIFToHex // this.btnPrivWIFToHex.Location = new System.Drawing.Point(334, 34); this.btnPrivWIFToHex.Name = "btnPrivWIFToHex"; this.btnPrivWIFToHex.Size = new System.Drawing.Size(46, 30); this.btnPrivWIFToHex.TabIndex = 25; this.btnPrivWIFToHex.Text = "▼"; this.btnPrivWIFToHex.UseVisualStyleBackColor = true; this.btnPrivWIFToHex.Click += new System.EventHandler(this.btnPrivWIFToHex_Click); // // btnPrivHexToWIF // this.btnPrivHexToWIF.Location = new System.Drawing.Point(286, 34); this.btnPrivHexToWIF.Name = "btnPrivHexToWIF"; this.btnPrivHexToWIF.Size = new System.Drawing.Size(46, 30); this.btnPrivHexToWIF.TabIndex = 24; this.btnPrivHexToWIF.Text = "▲"; this.btnPrivHexToWIF.UseVisualStyleBackColor = true; this.btnPrivHexToWIF.Click += new System.EventHandler(this.btnPrivHexToWIF_Click); // // btnGenerate // this.btnGenerate.Location = new System.Drawing.Point(492, 34); this.btnGenerate.Name = "btnGenerate"; this.btnGenerate.Size = new System.Drawing.Size(168, 30); this.btnGenerate.TabIndex = 26; this.btnGenerate.Text = "Generate Address"; this.btnGenerate.UseVisualStyleBackColor = true; this.btnGenerate.Click += new System.EventHandler(this.btnGenerate_Click); // // btnBlockExplorer // this.btnBlockExplorer.Location = new System.Drawing.Point(492, 235); this.btnBlockExplorer.Name = "btnBlockExplorer"; this.btnBlockExplorer.Size = new System.Drawing.Size(167, 29); this.btnBlockExplorer.TabIndex = 27; this.btnBlockExplorer.Text = "Block Explorer"; this.btnBlockExplorer.UseVisualStyleBackColor = true; this.btnBlockExplorer.Click += new System.EventHandler(this.btnBlockExplorer_Click); // // cboCoinType // this.cboCoinType.FormattingEnabled = true; this.cboCoinType.Items.AddRange(new object[] { "Bitcoin", "Testnet", "Namecoin"}); this.cboCoinType.Location = new System.Drawing.Point(382, 239); this.cboCoinType.Name = "cboCoinType"; this.cboCoinType.Size = new System.Drawing.Size(101, 21); this.cboCoinType.TabIndex = 29; this.cboCoinType.Text = "Bitcoin"; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(670, 302); this.Controls.Add(this.cboCoinType); this.Controls.Add(this.btnBlockExplorer); this.Controls.Add(this.btnGenerate); this.Controls.Add(this.btnPrivWIFToHex); this.Controls.Add(this.btnPrivHexToWIF); this.Controls.Add(this.btnPrivToPub); this.Controls.Add(this.btnPubHexToHash); this.Controls.Add(this.btnPubHashToAddress); this.Controls.Add(this.btnAddressToPubHash); this.Controls.Add(this.label5); this.Controls.Add(this.txtBtcAddr); this.Controls.Add(this.label4); this.Controls.Add(this.txtPubHash); this.Controls.Add(this.label3); this.Controls.Add(this.txtPubHex); this.Controls.Add(this.label2); this.Controls.Add(this.txtPrivHex); this.Controls.Add(this.label1); this.Controls.Add(this.txtPrivWIF); this.Name = "Form1"; this.Text = "Bitcoin Address Utility by Casascius (Beta, No Warranty)"; this.ResumeLayout(false); this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox txtPrivWIF; private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox txtPrivHex; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label3; private System.Windows.Forms.TextBox txtPubHex; private System.Windows.Forms.Label label4; private System.Windows.Forms.TextBox txtPubHash; private System.Windows.Forms.Label label5; private System.Windows.Forms.TextBox txtBtcAddr; private System.Windows.Forms.Button btnAddressToPubHash; private System.Windows.Forms.Button btnPubHashToAddress; private System.Windows.Forms.Button btnPubHexToHash; private System.Windows.Forms.Button btnPrivToPub; private System.Windows.Forms.Button btnPrivWIFToHex; private System.Windows.Forms.Button btnPrivHexToWIF; private System.Windows.Forms.Button btnGenerate; private System.Windows.Forms.Button btnBlockExplorer; private System.Windows.Forms.ComboBox cboCoinType;
} }
File: Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms;
namespace BtcAddress { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } }
|
Companies claiming they got hacked and lost your coins sounds like fraud so perfect it could be called fashionable. I never believe them. If I ever experience the misfortune of a real intrusion, I declare I have been honest about the way I have managed the keys in Casascius Coins. I maintain no ability to recover or reproduce the keys, not even under limitless duress or total intrusion. Remember that trusting strangers with your coins without any recourse is, as a matter of principle, not a best practice. Don't keep coins online. Use paper or hardware wallets instead.
|
|
|
bitlotto
|
|
July 01, 2011, 06:52:57 PM |
|
Pretty neat! It would be need to have on a windows Live CD! Kind of related but what would an address that has this look like with check sum: sacrifice4othersprosperity
|
*Next Draw Feb 1* BitLotto: monthly raffle (0.25 BTC per ticket) Completely transparent and impossible to manipulate who wins. TOR TOR2WEB Donations to: 1JQdiQsjhV2uJ4Y8HFtdqteJsZhv835a8J are appreciated.
|
|
|
casascius (OP)
Mike Caldwell
VIP
Legendary
Offline
Activity: 1386
Merit: 1140
The Casascius 1oz 10BTC Silver Round (w/ Gold B)
|
|
July 01, 2011, 06:57:30 PM |
|
Pretty neat! It would be need to have on a windows Live CD! Kind of related but what would an address that has this look like with check sum: sacrifice4othersprosperity 5Jsacrifice4othersprosperity7yjoaJR7mF7Sm1kEibnLCp8 --> 15N3i5weYye7UB4G3G3UbJsn2Bym8LWvFm In my utility, you can substitute characters in the private key, and have the utility recalculate the checksum. Of course you can only substitute characters within the base 58 alphabet, so that eliminates O 0 I l. Generate a random address, and then add a question mark to the WIF private key (turns off checksum). Substitute characters. Convert to hex, and then back to WIF (which will replace the checksum with a valid one). Note that if you change the total number of characters away from 51, you'll get back garbage, so make sure that the character count is correct. This is how I made my "vanity private keys". Once you have a working vanity private key that stays the same no matter which way you convert it, then generate the public key and bitcoin address from it.
|
Companies claiming they got hacked and lost your coins sounds like fraud so perfect it could be called fashionable. I never believe them. If I ever experience the misfortune of a real intrusion, I declare I have been honest about the way I have managed the keys in Casascius Coins. I maintain no ability to recover or reproduce the keys, not even under limitless duress or total intrusion. Remember that trusting strangers with your coins without any recourse is, as a matter of principle, not a best practice. Don't keep coins online. Use paper or hardware wallets instead.
|
|
|
SgtSpike
Legendary
Offline
Activity: 1400
Merit: 1005
|
|
July 01, 2011, 07:03:05 PM |
|
Neat project!
What do you plan to use the vanity private keys for? Is there a point to it? Seems like a waste to put the vanity in the only piece of information that isn't revealed to the public.
|
|
|
|
casascius (OP)
Mike Caldwell
VIP
Legendary
Offline
Activity: 1386
Merit: 1140
The Casascius 1oz 10BTC Silver Round (w/ Gold B)
|
|
July 01, 2011, 07:07:48 PM |
|
Neat project!
What do you plan to use the vanity private keys for? Is there a point to it? Seems like a waste to put the vanity in the only piece of information that isn't revealed to the public.
Nothing in particular... however, the application of delivering private keys will likely have plenty of uses, all of which could contain vanity private keys... - Bitbills
- Offline savings wallets (paper wallets)
- Bitcoin giveaways (where appropriate, the giver can take back the BTC if the recipient never redeems them... e.g. geocaching)
- Poker chips with embedded bitcoin value
- Bitcoin retail cards (where a person can buy BTC in a retail setting the same way they buy a gift card... they scratch off private key to get their coins)
- Computerless transfer of coin value between parties who trust one another (like a cheque)
|
Companies claiming they got hacked and lost your coins sounds like fraud so perfect it could be called fashionable. I never believe them. If I ever experience the misfortune of a real intrusion, I declare I have been honest about the way I have managed the keys in Casascius Coins. I maintain no ability to recover or reproduce the keys, not even under limitless duress or total intrusion. Remember that trusting strangers with your coins without any recourse is, as a matter of principle, not a best practice. Don't keep coins online. Use paper or hardware wallets instead.
|
|
|
bitlotto
|
|
July 01, 2011, 07:08:32 PM |
|
Neat project!
What do you plan to use the vanity private keys for? Is there a point to it? Seems like a waste to put the vanity in the only piece of information that isn't revealed to the public.
Perhaps a Bitcoin card manufacturer could put a PIN into the private key. Then when you redeem it the merchant will ask for the missing part?
|
*Next Draw Feb 1* BitLotto: monthly raffle (0.25 BTC per ticket) Completely transparent and impossible to manipulate who wins. TOR TOR2WEB Donations to: 1JQdiQsjhV2uJ4Y8HFtdqteJsZhv835a8J are appreciated.
|
|
|
casascius (OP)
Mike Caldwell
VIP
Legendary
Offline
Activity: 1386
Merit: 1140
The Casascius 1oz 10BTC Silver Round (w/ Gold B)
|
|
July 01, 2011, 07:10:05 PM |
|
Neat project!
What do you plan to use the vanity private keys for? Is there a point to it? Seems like a waste to put the vanity in the only piece of information that isn't revealed to the public.
Perhaps a Bitcoin card manufacturer could put a PIN into the private key. Then when you redeem it the merchant will ask for the missing part? That would not be secure, one knowing "most" of a private key could easily brute-force the remainder.
|
Companies claiming they got hacked and lost your coins sounds like fraud so perfect it could be called fashionable. I never believe them. If I ever experience the misfortune of a real intrusion, I declare I have been honest about the way I have managed the keys in Casascius Coins. I maintain no ability to recover or reproduce the keys, not even under limitless duress or total intrusion. Remember that trusting strangers with your coins without any recourse is, as a matter of principle, not a best practice. Don't keep coins online. Use paper or hardware wallets instead.
|
|
|
bitlotto
|
|
July 01, 2011, 07:12:43 PM |
|
Neat project!
What do you plan to use the vanity private keys for? Is there a point to it? Seems like a waste to put the vanity in the only piece of information that isn't revealed to the public.
Perhaps a Bitcoin card manufacturer could put a PIN into the private key. Then when you redeem it the merchant will ask for the missing part? That would not be secure, one knowing "most" of a private key could easily brute-force the remainder. I know. I was grasping at straws. LOL.
|
*Next Draw Feb 1* BitLotto: monthly raffle (0.25 BTC per ticket) Completely transparent and impossible to manipulate who wins. TOR TOR2WEB Donations to: 1JQdiQsjhV2uJ4Y8HFtdqteJsZhv835a8J are appreciated.
|
|
|
|
loglow
Jr. Member
Offline
Activity: 69
Merit: 3
|
|
July 01, 2011, 10:25:16 PM |
|
Would it be possible to include a command line interface (non GUI mode) for this program?
My apologies if it already includes this, and I just somehow missed it.
Thanks much.
|
|
|
|
pointbiz
Sr. Member
Offline
Activity: 437
Merit: 415
1ninja
|
|
September 14, 2011, 03:22:01 AM |
|
very nice program!
|
|
|
|
nhodges
|
|
September 14, 2011, 04:28:13 AM |
|
Would it be possible to include a command line interface (non GUI mode) for this program?
My apologies if it already includes this, and I just somehow missed it.
Thanks much.
Aren't there already CLI tools for this?
|
|
|
|
casascius (OP)
Mike Caldwell
VIP
Legendary
Offline
Activity: 1386
Merit: 1140
The Casascius 1oz 10BTC Silver Round (w/ Gold B)
|
|
November 07, 2012, 03:19:20 PM |
|
Recent updates posted to https://casascius.com/btcaddress-alpha.zip : * Banknote voucher printer can now print notes with minikeys. * New options on the main screen to copy - to the clipboard as a QR code graphic for pasting into other programs, where
- can be bitcoin address, minikey, private key, or public hash.
Other updates that have been described elsewhere but not in this thread: * Paper Wallet and Banknote Voucher printer allows printing of multiple colors of the winner of the recent Bitcoin Banknote contest. * Base58 Calculator allows arbitrary conversions of base58 values to hexadecimal and vice versa, regardless of length. Add a "?" to the end of any base58 string to suspend verification of the checksum. * Support for compressed public keys and the ability to convert between compressed and uncompressed. * Classes for managing Bitcoin addresses/pubkeys/privkeys/minikeys have been refactored and are ripe for scraping and using in other projects if needed. You can gain programmatic access to the functions of the main "Bitcoin address Swiss army knife" screen in your own program simply by appropriating the classes Address, PublicKey, KeyPair, and MiniKeyPair. As always, this is a program for Windows, and is based on Microsoft .NET and Visual Studio. Source code is included in the zip.
|
Companies claiming they got hacked and lost your coins sounds like fraud so perfect it could be called fashionable. I never believe them. If I ever experience the misfortune of a real intrusion, I declare I have been honest about the way I have managed the keys in Casascius Coins. I maintain no ability to recover or reproduce the keys, not even under limitless duress or total intrusion. Remember that trusting strangers with your coins without any recourse is, as a matter of principle, not a best practice. Don't keep coins online. Use paper or hardware wallets instead.
|
|
|
HostFat
Staff
Legendary
Offline
Activity: 4270
Merit: 1209
I support freedom of choice
|
|
November 07, 2012, 03:22:27 PM |
|
Can you put it on github?
|
|
|
|
molecular
Donator
Legendary
Offline
Activity: 2772
Merit: 1019
|
|
April 11, 2013, 11:22:30 AM |
|
I fail to make sense of this. Can't even tell which language this is.
Didn't look hard, but maybe someone can give me a hint? How to compile / run?
|
PGP key molecular F9B70769 fingerprint 9CDD C0D3 20F8 279F 6BE0 3F39 FC49 2362 F9B7 0769
|
|
|
MashRinx
|
|
April 11, 2013, 07:47:22 PM |
|
It's Microsoft's C#. You can get a free/lite version of Visual Studio 2012 and it may be able to compile it. (I can't think of any reason why it wouldn't be able to, but I haven't tried). This will hopefully get you going in the right direction though.
|
|
|
|
molecular
Donator
Legendary
Offline
Activity: 2772
Merit: 1019
|
|
April 12, 2013, 10:11:23 AM |
|
It's Microsoft's C#. You can get a free/lite version of Visual Studio 2012 and it may be able to compile it. (I can't think of any reason why it wouldn't be able to, but I haven't tried). This will hopefully get you going in the right direction though.
not to downplay this effort, but m$ is just not for me. There's plenty of python / js / java code around, also.
|
PGP key molecular F9B70769 fingerprint 9CDD C0D3 20F8 279F 6BE0 3F39 FC49 2362 F9B7 0769
|
|
|
samadamsbeer
Member
Offline
Activity: 93
Merit: 10
|
|
April 19, 2013, 05:50:08 PM |
|
Thanks for this tool. I was hoping to use this to verify addresses from brainwallet/bitaddress. Can someone explain how to compile this in Linux/Ubuntu step by step? or if you have a compiled version for that OS, awesome! Thx
|
|
|
|
btctousd81
|
|
August 16, 2017, 04:11:31 AM |
|
sorry for bumping old thread.
but icame from google search.
is it possible to run this code in linux command line ?
|
|
|
|
|
|