Closed brianddk closed 11 years ago
Thanks for the report! The version prefix to the exported private key is incorrect so the import to other clients doesn't work currently. This is the first bug I plan to fix once I get time. Feel free to look through the code and give me hints or a patch and I will get it done quicker.
Apologies for not learning github markup, but I just wanted to get this out there first.
OK... you were right. Looks like the feathercoinj and FeatherCoin repositories have conflicting versions bytes for PrivateKeys. I think the one you were shooting for was 0x8E (128 + 14). That is what is used by FeatherCoin. feathercoinj on the other hand is using 0x80 (128) which I believe is the bitcoin private key header.
Here's a walk through for anyone reading along at home. (3) clearly expects the version to be 0x8E (128 + 14). The IsValid function is ultimately what causes the "Invalid private key" message. (4) through (7) clearly pass the version 128 straight down to the ToString function which ultimately write the key to the SD card.
I would suppose the most isolated change would be to change (5) to: super(params.dumpedPrivateKeyHeader + params.addressHeader, encode(keyBytes, compressed));
Although a broader change may be in order. The scope of my review was VERY narrow.
.. References: .. (1) FeatherCoin: src/base58.h ln:281
PUBKEY_ADDRESS = 14,
(2) FeatherCoin: src/base58.h ln:409
PRIVKEY_ADDRESS = CBitcoinAddress::PUBKEY_ADDRESS + 128,
(3) FeatherCoin: src/base58.h ln:430
bool IsValid() const
{
bool fExpectTestNet = false;
switch(nVersion)
{
case PRIVKEY_ADDRESS
break
case PRIVKEY_ADDRESS_TEST
fExpectTestNet = true
break
default
return false
}
return fExpectTestNet == fTestNet && (vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1));
}
(4) feathercoinj: src/main/java/com/google/feathercoin/core/NetworkParameters.java ln:146
dumpedPrivateKeyHeader = 128;
addressHeader = 14;
(5) feathercoinj: src/main/java/com/google/feathercoin/corecore/DumpedPrivateKey.java ln:35
super(params.dumpedPrivateKeyHeader, encode(keyBytes, compressed));
(6) feathercoinj: src/main/java/com/google/feathercoin/core/VersionedChecksummedBytes.java ln:42
protected VersionedChecksummedBytes(int version, byte[] bytes) {
checkArgument(version < 256 && version >= 0);
this.version = version;
this.bytes = bytes;
}
(7) feathercoinj: src/main/java/com/google/feathercoin/core/VersionedChecksummedBytes.java ln:53
addressBytes[0] = (byte) version;
Wow - fantastic job tracking that down! This will allow me to fix key exports in both feathercoinj and litecoinj and their associated android wallets. I really appreciate this - I did indeed change NetworkParameters to what I thought should work (the +14 on the address header) and I was confused on why this didn't work. As you found, the code kind of goes all over the place, and can be hard to grok without some time dedication. Again, I can't thank you enough for this analysis. I'll get to work on this very soon.
While the patch is in, I wrote a little powershell script to thunk the header field to whatever you what. I listed "known" header fields as: [ftc-qt] FeatherCoin-Qt: 142 [ltc-qt] LiteCoin-Qt: 176 [ftc-and] feathercoin-wallet: 128 [ltc-and] litecoin-wallet: 128
## Powershell Privatekey header modification script.
## Known headers: { ftc-qt:142, ftc-and:128, ltc-qt:176, ltc-and:128 }
## By d4n13 < https://github.com/d4n13 >. Feel free to tip!
## Feathercoin TipJar: 6mx5WVXsTEdsh9UCainpdAHDrDwH4mZQTD
${codeString} = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
${hasher} = [System.Security.Cryptography.HashAlgorithm]::create("sha256")
${base} = New-Object System.Numerics.BigInteger -ArgumentList @(,58)
${bigInt} = New-Object System.Numerics.BigInteger -ArgumentList @(,0)
${strKey} = Read-Host -Prompt "Enter the key to modify"
${oldArray} = ${strKey}.ToCharArray()
foreach( ${char} in ${oldArray} ) {
${bigInt} = ${bigInt} * ${base}
${bigInt} = ${bigInt} + ${codeString}.IndexOf(${char})
}
${intArray} = ${bigInt}.ToByteArray()
${intArray} = ${intArray}[0..(${intArray}.Length-2)]
[System.Array]::Reverse(${intArray})
${intArray} = ${intArray}[0..(${intArray}.Length-5)]
Write-Host "The given key has a header byte of: $(${intArray}[0])"
${intArray}[0] = [Byte]::Parse((Read-Host -Prompt "Input 'desired' header byte"))
${chksum} = ${hasher}.ComputeHash(${hasher}.ComputeHash(${intArray}))
${intArray} = @(,0) + ${intArray} + ${chksum}[0..3]
[System.Array]::Reverse(${intArray})
${bigInt} = New-Object System.Numerics.BigInteger -ArgumentList @(,${intArray})
do {
${newArray} += @(,${codeString}[(${bigInt} % ${base})])
${bigInt} = (${bigInt} / ${base})
}
until (${bigInt}.IsZero)
[System.Array]::Reverse(${newArray})
${strKey} = New-Object System.String -ArgumentList @(,${newArray})
Write-Host "The modified key is: ${strKey}"
@("strKey", "intArray", "oldArray", "newArray") | % { Remove-Variable -Name $_ }
Thanks!
Just tried exporting in the new Litecoin wallet version I uploaded to Play just now (it hasn't appeared yet). I exported the keys and imported into the official client. It works. This is based on exactly the same code you have above, so I'm going to call this closed. If you can validate it, I'd appreciate it (Litecoin-wallet v1.091, Feathercoin-wallet v1.094).
Confirmed... I exported from litecoin-qt and litecoin-wallet and they private keys matched.
Thanks.
No problem! I'm not sure what feathercoin private keys are supposed to look like and didn't have an official client handy. If you could try with feathercoin wallet too, that would help. I can probably try on my end tonight.
On Tue, Jul 23, 2013 at 1:38 AM, d4n13 notifications@github.com wrote:
Confirmed... I exported from litecoin-qt and litecoin-wallet and they private keys matched.
Thanks.
— Reply to this email directly or view it on GitHubhttps://github.com/hank/feathercoin-wallet/issues/3#issuecomment-21394205 .
Confirmed... Feathercoin-Wallet now exports keys correctly too.
I did have some weirdness updating feathercoin-wallet from google-play. In the search results feathercoin-wallet had a "update" by it, but when I opened the listing from search, there wasn't an update button. If I went back to search I could long click on the left of the item in the search results and pick "update". At that point it complained that the app was already installed.
Did the exact same steps this morning and this time the update took. Don't know if it was just wierdness on my phone or wierdness in the listing.
Strange I'll try that tonight on another device. Thanks for the report and the test!
On Tue, Jul 23, 2013 at 9:42 AM, d4n13 notifications@github.com wrote:
Confirmed... Feathercoin-Wallet now exports keys correctly too.
I did have some weirdness updating feathercoin-wallet from google-play. In the search results feathercoin-wallet had a "update" by it, but when I opened the listing from search, there wasn't an update button. If I went back to search I could long click on the left of the item in the search results and pick "update". At that point it complained that the app was already installed.
Did the exact same steps this morning and this time the update took. Don't know if it was just wierdness on my phone or wierdness in the listing.
— Reply to this email directly or view it on GitHubhttps://github.com/hank/feathercoin-wallet/issues/3#issuecomment-21414491 .
Finally coded this up in python:
https://github.com/hank/life/blob/master/code/python/cryptcoin_addr_convert/convert.py
I got this working, please find the pull request for the fixed code here: https://github.com/hank/life/pull/1
I'm one of the idiots that lost coins with the old wallet... i have about 31 ltc sitting in it and I can't access it. I did use openssl to decrypt a backup I had from 6-5-2013 and then converted the private key with the python script and it still tells me it's an invalid private key when I try to import it into litecoin-qt... any thoughts?
I'm a software developer so this is additionally embarrassing for me... :)
@bmilne81 I'd be happy to try and help if you want. Email me at ralree@gmail.com if you like and we can work something out.
Version: (Android) de.schildbach.wallet.feathercoin v1.092 (Windows) feathercoin-qt / feathercoind v0.6.4.2 (Cygwin) OpenSSL v1.0.1e
Procedure to reproduce error 1) From feathercoin-wallet choose {Backup keys -> Export private keys} 2) Choose a password {example "password"} and select export 3) Copy feathercoin-wallet file to Windows box. 4) Decrypt feathercoin-wallet keys to console using openssl: 4a) openssl enc -d -aes-256-cbc -a -in feathercoin-wallet 5) Open debug console in feathercoin-qt gui 6) Unlock wallet with cmd: { walletpassphrase passphrase timeout } 7) Import android key with cmd: { importprivkey feathercoinprivkey label } 8) Note error: {"code":-5,"message":"Invalid private key"}
Verification: Did same procedure with bitcoin-wallet and bitcoin-qt: PASS Did same procedure with litecoin-wallet and litecoin-qt: FAIL
BTW... many thanks for the app, I really like your crypto-currency apps!
PS: This issue seems to have been imported from the litecoin-wallet fork. Currently tracked in litecoin-wallet as issue #15
https://github.com/hank/litecoin-wallet/issues/15