Skip to content

Commit

Permalink
Litecoin minikey address generation added.
Browse files Browse the repository at this point in the history
Key details form now works with selected address type for all buttons (some buttons would always assume Bitcoin address type).
  • Loading branch information
BitKoot committed Jun 29, 2013
1 parent 3498483 commit fb0fe2d
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 81 deletions.
2 changes: 1 addition & 1 deletion BtcAddress.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
<ItemGroup>
<Compile Include="Barcode\Barcode128b.cs" />
<Compile Include="Barcode\QR.cs" />
<Compile Include="Model\AddressType.cs" />
<Compile Include="Model\Base58.cs" />
<Compile Include="Model\Base58CheckString.cs" />
<Compile Include="Model\Bip38Base.cs" />
Expand Down Expand Up @@ -250,7 +251,6 @@
</ItemGroup>
<ItemGroup>
<Content Include="bitcoinlogo.ico" />
<Compile Include="Model\AddressVersion.cs" />
<Content Include="note-blue.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Expand Down
2 changes: 0 additions & 2 deletions Forms/AddressGen.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 7 additions & 22 deletions Forms/AddressGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
using System.Threading;
using System.Diagnostics;
using Casascius.Bitcoin;
using BtcAddress.Model;

namespace BtcAddress.Forms {
public partial class AddressGen : Form {
Expand All @@ -40,7 +39,7 @@ private enum GenChoices {

private GenChoices GenChoice;

private byte ChosenAddressVersion = 0;
private byte ChosenAddressType = 0;

private bool Generating = false;
private bool GeneratingEnded = false;
Expand All @@ -67,8 +66,8 @@ private enum GenChoices {
txtTextInput.Text = "";
txtTextInput.Visible = (rdoDeterministicWallet.Checked || rdoEncrypted.Checked);
lblTextInput.Visible = (rdoDeterministicWallet.Checked || rdoEncrypted.Checked || rdoTwoFactor.Checked);
cboCoinType.Visible = rdoRandomWallet.Checked;
lblCoinType.Visible = rdoRandomWallet.Checked;
cboCoinType.Visible = rdoMiniKeys.Checked || rdoRandomWallet.Checked;
lblCoinType.Visible = rdoMiniKeys.Checked || rdoRandomWallet.Checked;

if (rdoDeterministicWallet.Checked) {
lblTextInput.Text = "Seed for deterministic generation";
Expand Down Expand Up @@ -158,22 +157,8 @@ private enum GenChoices {
GenChoice = GenChoices.TwoFactor;
}

switch (cboCoinType.SelectedItem.ToString())
{
case "Namecoin":
ChosenAddressVersion = AddressVersion.Namecoin;
break;
case "Testnet":
ChosenAddressVersion = AddressVersion.Testnet;
break;
case "Litecoin":
ChosenAddressVersion = AddressVersion.Litecoin;
break;
default:
ChosenAddressVersion = AddressVersion.Bitcoin;
break;
}

ChosenAddressType = AddressType.ToAddressType(cboCoinType.SelectedItem.ToString());

timer1.Interval = 250;
timer1.Enabled = true;
Generating = true;
Expand Down Expand Up @@ -218,12 +203,12 @@ private enum GenChoices {
KeyCollectionItem newitem = null;
switch (GenChoice) {
case GenChoices.Minikey:
MiniKeyPair mkp = MiniKeyPair.CreateRandom(ExtraEntropy.GetEntropy());
MiniKeyPair mkp = MiniKeyPair.CreateRandom(ExtraEntropy.GetEntropy(), ChosenAddressType);
string s = mkp.AddressBase58; // read the property to entice it to compute everything
newitem = new KeyCollectionItem(mkp);
break;
case GenChoices.WIF:
KeyPair kp = KeyPair.Create(ExtraEntropy.GetEntropy(), false, ChosenAddressVersion);
KeyPair kp = KeyPair.Create(ExtraEntropy.GetEntropy(), false, ChosenAddressType);
s = kp.AddressBase58;
newitem = new KeyCollectionItem(kp);
break;
Expand Down
27 changes: 15 additions & 12 deletions Forms/Form1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
using System.Drawing.Printing;

using Casascius.Bitcoin;
using BtcAddress.Model;

namespace BtcAddress {
public partial class Form1 : Form {
Expand All @@ -53,12 +52,16 @@ public partial class Form1 : Form {
/// Item may represent an AddressBase, PublicKey, KeyPair, MiniKey, or an EncryptedKeyPair
/// </summary>
public void DisplayKeyCollectionItem(KeyCollectionItem item) {
if (item != null && item.Address != null) {
cboCoinType.Text = AddressType.FromAddressType(item.Address.AddressType);
}

try {
ChangeFlag++;
if (item.EncryptedKeyPair != null) {
SetText(txtPrivWIF, item.EncryptedKeyPair.EncryptedPrivateKey);
// blank out any validation info of the minikey
UpdateMinikeyDescription();
UpdateMinikeyDescription(item.Address.AddressType);
SetText(txtPassphrase, "");
if (item.EncryptedKeyPair.IsUnencryptedPrivateKeyAvailable()) {
SetText(txtPrivHex, item.EncryptedKeyPair.GetUnencryptedPrivateKey().PublicKeyHex);
Expand Down Expand Up @@ -90,7 +93,7 @@ public partial class Form1 : Form {
}

// update the label to indicate whether this is a valid minikey (or blank it out if n/a)
UpdateMinikeyDescription();
UpdateMinikeyDescription(item.Address.AddressType);

if (item.Address != null) {

Expand Down Expand Up @@ -123,8 +126,8 @@ public partial class Form1 : Form {

}

private void UpdateMinikeyDescription() {
int isminikey = MiniKeyPair.IsValidMiniKey(txtMinikey.Text);
private void UpdateMinikeyDescription(byte addressType) {
int isminikey = MiniKeyPair.IsValidMiniKey(txtMinikey.Text, addressType);
if (isminikey == 1) {
lblWhyNot.Visible = false;
lblNotSafe.Visible = true;
Expand Down Expand Up @@ -152,7 +155,7 @@ public partial class Form1 : Form {
ChangeFlag++;
try {
SetText(txtPrivHex, RemoveSpacesIf(Util.PassphraseToPrivHex(txtMinikey.Text)));
UpdateMinikeyDescription();
UpdateMinikeyDescription(0);

btnPrivHexToWIF_Click(null, null);
btnPrivToPub_Click(null, null);
Expand Down Expand Up @@ -304,7 +307,7 @@ public partial class Form1 : Form {
lblWhyNot.Visible = false;
SetText(txtMinikey, "");

KeyPair kp = KeyPair.Create(ExtraEntropy.GetEntropy(), compressToolStripMenuItem.Checked);
KeyPair kp = KeyPair.Create(ExtraEntropy.GetEntropy(), compressToolStripMenuItem.Checked, AddressType.ToAddressType(cboCoinType.Text));

if (txtPassphrase.Text != "") {
SetText(txtPrivWIF, new Bip38KeyPair(kp, txtPassphrase.Text).EncryptedPrivateKey);
Expand Down Expand Up @@ -396,12 +399,12 @@ public partial class Form1 : Form {

private byte AddressTypeByte {
get {
string cointype = cboCoinType.SelectedText.ToLowerInvariant();
string cointype = cboCoinType.Text.ToLowerInvariant();
switch (cointype) {
case "bitcoin": return AddressVersion.Bitcoin;
case "namecoin": return AddressVersion.Namecoin;
case "testnet": return AddressVersion.Testnet;
case "litecoin": return AddressVersion.Litecoin;
case "bitcoin": return AddressType.Bitcoin;
case "namecoin": return AddressType.Namecoin;
case "testnet": return AddressType.Testnet;
case "litecoin": return AddressType.Litecoin;
}
byte b = 0;
if (Byte.TryParse(cointype, out b)) return b;
Expand Down
13 changes: 6 additions & 7 deletions Forms/KeyCollectionView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
using System.Xml.Serialization;
using System.Drawing.Printing;
using Casascius.Bitcoin;
using BtcAddress.Model;


namespace BtcAddress.Forms {
Expand All @@ -41,23 +40,23 @@ public partial class KeyCollectionView : Form {
}

private void newBtcAddressToolStripMenuItem_Click(object sender, EventArgs e) {
AddKey(AddressVersion.Bitcoin);
AddKey(AddressType.Bitcoin);
}

private void newTestnetAddressToolStripMenuItem_Click(object sender, EventArgs e) {
AddKey(AddressVersion.Testnet);
AddKey(AddressType.Testnet);
}

private void newNmcAddressToolStripMenuItem_Click(object sender, EventArgs e) {
AddKey(AddressVersion.Namecoin);
AddKey(AddressType.Namecoin);
}

private void newLtcAddressToolStripMenuItem_Click(object sender, EventArgs e) {
AddKey(AddressVersion.Litecoin);
AddKey(AddressType.Litecoin);
}

private void AddKey(byte addressVersion) {
KeyPair kp = KeyPair.Create(ExtraEntropy.GetEntropy(), false, addressVersion);
private void AddKey(byte addressType) {
KeyPair kp = KeyPair.Create(ExtraEntropy.GetEntropy(), false, addressType);
KeyCollectionItem item = new KeyCollectionItem(kp);
KeyCollection.AddItem(item);
}
Expand Down
33 changes: 31 additions & 2 deletions Model/AddressVersion.cs → Model/AddressType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,44 @@
using System.Linq;
using System.Text;

namespace BtcAddress.Model
namespace Casascius.Bitcoin
{
/// <summary>
/// Class containing constant version numbers of different address types.
/// </summary>
public class AddressVersion {
public static class AddressType {
public const byte Bitcoin = 0;
public const byte Litecoin = 48;
public const byte Namecoin = 52;
public const byte Testnet = 111;

public static byte ToAddressType(string type) {
switch (type)
{
case "Namecoin":
return AddressType.Namecoin;
case "Testnet":
return AddressType.Testnet;
case "Litecoin":
return AddressType.Litecoin;
default:
return AddressType.Bitcoin;
}
}

public static string FromAddressType(byte addressType)
{
switch (addressType)
{
case AddressType.Namecoin:
return "Namecoin";
case AddressType.Testnet:
return "Testnet";
case AddressType.Litecoin:
return "Litecoin";
default:
return "Bitcoin";
}
}
}
}
19 changes: 7 additions & 12 deletions Model/Bitcoin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Math.EC;
using BtcAddress.Model;

namespace Casascius.Bitcoin {
public class Util {
Expand Down Expand Up @@ -321,27 +320,24 @@ public class Util {

}

public static string PubHashToAddress(string PubHash, string AddressType) {
public static string PubHashToAddress(string PubHash, string addressType) {
byte[] hex = ValidateAndGetHexPublicHash(PubHash);
if (hex == null) throw new ApplicationException("Invalid public hex key");

byte[] hex2 = new byte[21];
Array.Copy(hex, 0, hex2, 1, 20);

int cointype = AddressVersion.Bitcoin;
if (Int32.TryParse(AddressType, out cointype) == false) cointype = AddressVersion.Bitcoin;
byte cointype = AddressType.Bitcoin;
if (byte.TryParse(addressType, out cointype) == false) cointype = AddressType.Bitcoin;

if (AddressType == "Testnet") cointype = AddressVersion.Testnet;
if (AddressType == "Namecoin") cointype = AddressVersion.Namecoin;
if (AddressType == "Litecoin") cointype = AddressVersion.Litecoin;
if (addressType == "Testnet") cointype = AddressType.Testnet;
if (addressType == "Namecoin") cointype = AddressType.Namecoin;
if (addressType == "Litecoin") cointype = AddressType.Litecoin;
hex2[0] = (byte)(cointype & 0xff);
return ByteArrayToBase58Check(hex2);


}

public static bool PassphraseTooSimple(string passphrase) {

int Lowercase = 0, Uppercase = 0, Numbers = 0, Symbols = 0, Spaces = 0;
foreach (char c in passphrase.ToCharArray()) {
if (c >= 'a' && c <= 'z') {
Expand All @@ -358,14 +354,13 @@ public class Util {
}

// let mini private keys through - they won't contain words, they are nonsense characters, so their entropy is a bit better per character
if (MiniKeyPair.IsValidMiniKey(passphrase) != 1) return false;
if (MiniKeyPair.IsValidMiniKey(passphrase, 0) != 1) return false;

if (passphrase.Length < 30 && (Lowercase < 10 || Uppercase < 3 || Numbers < 2 || Symbols < 2)) {
return true;
}

return false;

}

public static byte[] ComputeSha256(string ofwhat) {
Expand Down
7 changes: 3 additions & 4 deletions Model/KeyPair.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Bitcoin Address Utility. If not, see http://www.gnu.org/licenses/.


using System;
using System.Collections.Generic;
using System.Linq;
Expand Down Expand Up @@ -112,7 +111,7 @@ public class KeyPair : PublicKey {
/// Create a Bitcoin address from a key represented in a string.
/// </summary>
public KeyPair(string key, bool compressed=false, byte addressType=0) {
this._addressType = addressType;
_addressType = addressType;
string result = constructWithKey(key, compressed);
if (result != null) throw new ArgumentException(result);

Expand All @@ -127,8 +126,8 @@ public class KeyPair : PublicKey {
hex = Util.HexStringToBytes(key, true);
if (hex == null) {
// tolerate a minikey
if (MiniKeyPair.IsValidMiniKey(key) > 0) {
PrivateKeyBytes = new MiniKeyPair(key).PrivateKeyBytes;
if (MiniKeyPair.IsValidMiniKey(key, _addressType) > 0) {
PrivateKeyBytes = new MiniKeyPair(key, _addressType).PrivateKeyBytes;
return null;
} else {
return "Invalid private key";
Expand Down
Loading

0 comments on commit fb0fe2d

Please sign in to comment.