Pages:
Author

Topic: The FinderOuter, a bitcoin recovery tool (v0.16.0 2022-09-19) - page 3. (Read 4154 times)

legendary
Activity: 1040
Merit: 2785
Bitcoin and C♯ Enthusiast
Version 0.10.0 is released.
https://github.com/Coding-Enthusiast/FinderOuter/releases/tag/v0.10.0.0
See changelog for details.
BigInteger Be Gone!
This release introduced a new code for Elliptic Curve Cryptography that also solves issue #9. 
Effectively this brings a ton of optimization to almost all options, mainly the mnemonic recovery and
Base16 rcovery. But also any option that required an ICompareService that used ECC. 
By getting rid of the old ECC code and BigInteger this also solves the pressure on garbage collector
and lets FinderOuter utilize the entire CPU power during parallelism. 
Speed gain in this release is usually around 200% compared to previous releases. 
Good news is that this is the initial step for more optimization! For example the current ECC implementation
uses radix 226 and contstant time operations, changing to radix 252 and using variable time operations, etc
will improve the speed more. 

Some additional changes:
  • Path recovery can now accept any extended keys (xprv, ypub, zprv, ?pub, ...)
  • It is now possible to recover a WIF missing up to 11 characters from the end
  • Reports generated by MissingEncoding option are improved
  • Various code improvements and tests
  • From this version we are also releasing binaries for 3 operating systems (Linux, Windows and MacOs all x64)
legendary
Activity: 1040
Merit: 2785
Bitcoin and C♯ Enthusiast
I am getting the following error when loading FinderOuter in VS2019:

Code:
error  : The project file cannot be opened. Unable to locate the .NET SDK. Check that it is installed and that the version specified in global.json (if any) matches the installed version.

I'm clueless, because I already have .NET SDK and tools installed. Any ideas?
This is a Visual Studio related problem. Refer to SO: https://stackoverflow.com/questions/65209536/microsoft-visual-studio-2019-the-project-file-cannot-be-opened-unable-to-locat
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
I am getting the following error when loading FinderOuter in VS2019:

Code:
error  : The project file cannot be opened. Unable to locate the .NET SDK. Check that it is installed and that the version specified in global.json (if any) matches the installed version.

I'm clueless, because I already have .NET SDK and tools installed. Any ideas?
legendary
Activity: 1040
Merit: 2785
Bitcoin and C♯ Enthusiast
Version 0.9.0 is released.
https://github.com/Coding-Enthusiast/FinderOuter/releases/tag/v0.9.0.0
See changelog for details.
  • New recovery option: find encoding of an arbitrary input string

  • Add a new help view that shows up at startup and suggests which recovery option to choose


  • Add knowledge Base window that contains explanation of different parts
There are small question marks on different UI objects that can be clicked to move to the respective KB

The KB will contain some general information about what the input is, how it is used, etc.


  • Some small improvements in address validation and error message

A good news
I've made good progress on solving issue #9 and next release will hopefully solve it for good as we will replace BigInteger entirely with a UInt256 struct that doesn't have the same issues as BigInteger and also it adds a huge speed gain.
legendary
Activity: 1040
Merit: 2785
Bitcoin and C♯ Enthusiast
When searching for Base58 wif code, can you bring up a method of adding several addresses instead of one destination address?
It could be added but I don't see the point in it and here is why, the checksum in a WIF is big enough to have very little collisions when going through permutations. Most of the times with small number of missing characters (that would take reasonable time) only 1 valid key exists and as the number of missing characters grow the number of valid keys that are returned remain too small. For example with 7 missing chars at random positions worst case scenario is that you get 2 or 3 keys. It is easy for user to check all of them. If the number of missing chars is too big then recovery is most probably not possible, accepting more addresses won't change that. In any case the program is already printing any valid key it finds as it goes.

BTW the Missing base58 option is not using the extra input field (ie. address/pubkey) for WIF recovery. It is just used for a special case where the missing chars are all located at the end.
jr. member
Activity: 38
Merit: 13
This fraudster is selling your software : https://youtu.be/zowg-o4Fszk
Thanks for informing me. The corresponding google account is banned now.

You're welcome. When searching for Base58 wif code, can you bring up a method of adding several addresses instead of one destination address?
legendary
Activity: 1040
Merit: 2785
Bitcoin and C♯ Enthusiast
This fraudster is selling your software : https://youtu.be/zowg-o4Fszk
Thanks for informing me. The corresponding google account is banned now.
jr. member
Activity: 38
Merit: 13
This fraudster is selling your software : https://youtu.be/zowg-o4Fszk
legendary
Activity: 1040
Merit: 2785
Bitcoin and C♯ Enthusiast
Version 0.8.0 is released.
https://github.com/Coding-Enthusiast/FinderOuter/releases/tag/v0.8.0.0
See changelog for details.
  • Some user interface improvements
  • New recovery option: find BIP-32 derivation path
    Note: this is a simple option with only a handful of standard paths, I'll try finding more paths used by different wallets and optimize it but for now it is very basic.
  • New recovery option: recover Armory backup phrases missing some characters
    Note: this option's speed is wildly variable because it depends a lot on the existence of the checksum. It can be from dozens of keys per second to hundred billion key per second. For example if the recovery phrase has its checksum and is missing 10 characters you can check 1 trillion variations and recover it in 1 second.
  • Main window size has a limit so it can no longer be shrinked to nearly nothing

A small RoadMap
  • For next release I'd like to work more on the user experience by adding a Help window where user can interact with at the start of the application and can figure out which option to use.
  • I would also like to add some more "tips" to the UI explaining different terminology. For example explaining what WIF, Base58, derivation path, ... are.
  • Let me know if there is any interest in changing UI theme like having light or dark theme instead of the default light one or a colored one.
Version 0.9.0 will probably be released with these. But I also have 2 more options in mind:
  • BIP-39 passphrase (the extension words) recovery (hopefully for 0.10.0)
  • BIP-38 password (for encryption) recovery

I've also started working on optimizing ECC to hopefully solve issue #9 but it's still very challenging.
legendary
Activity: 1040
Merit: 2785
Bitcoin and C♯ Enthusiast
Maybe, I do something wrong on building.
Probably. This has nothing to do with the UI (Avalonia).
Inside your Visual Studio place a break on the Find method line and then go to Debug > Start debugging (F5).
After that enter your data in text boxes and click find, the execution should stop at that line where you placed the break.


Then continue pressing F11 to step into each method or F10 to step over until you figure out where the evaluation is failing. You can move your mouse over to any variable and see their value when in debug mode.



I can write something that is considered invalid inside a file, but it'll be normally built. It makes me curious. Do I change the program or not?
Did you open the solution file or the csproj file or did you just open the .cs file from your explorer? Because the only thing that I can think of is that when you open a .cs file you can't build it, it has to be inside a .csproj file.
This file: https://github.com/Coding-Enthusiast/FinderOuter/blob/v0.6.0.0/Src/FinderOuter.sln or this https://github.com/Coding-Enthusiast/FinderOuter/blob/v0.6.0.0/Src/FinderOuter/FinderOuter.csproj
legendary
Activity: 1512
Merit: 7340
Farewell, Leo
All I can think of is that you should debug the code line by line and see where it calls report.Fail("") (remember to change to debug mode if you haven't already).

It doesn't make sense. I comment the specific part of the code, but I still get the same error. Maybe, I do something wrong on building. Yes, I use Debug, but I've never used Avalonia in the past. Is there something that I have to prepair before building? I've also noticed that there is no syntax error detector shown in VS. For example, I can write something that is considered invalid inside a file, but it'll be normally built. It makes me curious. Do I change the program or not?

Code:
/*words = mnemonic.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (!allowedWordLengths.Contains(words.Length))
{
    return report.Fail("Invalid mnemonic length. Mnemonic is: " + mnemonic);
}*/

legendary
Activity: 1040
Merit: 2785
Bitcoin and C♯ Enthusiast
I wanted to see, what mnemonic it reads. Is there any other part of the source code that prints the same error?
No. https://github.com/Coding-Enthusiast/FinderOuter/search?q=Invalid+mnemonic+length
All I can think of is that you should debug the code line by line and see where it calls report.Fail("") (remember to change to debug mode if you haven't already).
legendary
Activity: 1512
Merit: 7340
Farewell, Leo
Here is the error message. See what the value of mnemonic is.
I don't believe that's the error message. Once I change it to the following I still get "Invalid mnemonic length.", that I shouldn't.

Code:
words = mnemonic.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (!allowedWordLengths.Contains(words.Length))
{
    return report.Fail("Invalid mnemonic length. Mnemonic is: " + mnemonic);
}

I wanted to see, what mnemonic it reads. Is there any other part of the source code that prints the same error?

That's a typo.
Okay, changed.
legendary
Activity: 1040
Merit: 2785
Bitcoin and C♯ Enthusiast
but still I ge tthe same error
Try placing a break point where the error is being created and see what input is being checked. That should give you a good idea where the problem is. Here is the error message. See what the value of mnemonic is.
My guess is that the input is not split into separate lines correctly.

Why is it nvironment? Why not Environment? Based on your code, it doesn't seem you've used it as a variable.
That's a typo.
legendary
Activity: 1512
Merit: 7340
Farewell, Leo
The FindMissing(..) in Service expects a single mnemonic, changing that is a lot of work so you should just change the ViewModel code to call it more than one time with each mnemonic instead of once

I did had changed that. I wasn't taking the entire string with all the lines and starting the brute force. I just used for loop instead foreach as you did. But, I still face the same issue. I replaced everything you said, the Find() and the Message on Report.cs, but still I ge tthe same error:


As for this one:
Quote
nvironment.NewLine
Why is it nvironment? Why not Environment? Based on your code, it doesn't seem you've used it as a variable.
legendary
Activity: 1040
Merit: 2785
Bitcoin and C♯ Enthusiast
I'll have to admit that your code is literally beautiful. Everything is organized and I can understand the functionalities of each file. Somehow, FinderOuter on Visual Studio 2019 goes really fast in contrast with my WinForms programs. Does it have to do with Avalonia? How did they manage to make it that light?
Thanks. I believe XAML is generally cleaner and faster for UI development but I'm not sure since I haven't really used WinForms myself.

Anyway, I got off topic. What I wanted to say is that by changing line 149 on ViewModels/MissingMnemonicViewModel.cs and line 1483 on Services/MnemonicSevice.cs it's not possible. For example line 1425 on Services/MnemonicSevice.cs returns me "Invalid mnemonic length." when I try to add more than one mnemonics:
The FindMissing(..) in Service expects a single mnemonic, changing that is a lot of work so you should just change the ViewModel code to call it more than one time with each mnemonic instead of once
VM code turns into:
Code:
public async override void Find()
{
   string[] mns = Mnemonic.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);
   foreach (var item in mns)
   {
      await MnService.FindMissing(item, MissingChar, PassPhrase, AdditionalInfo, SelectedInputType.Value,
                                  KeyPath,
                                  SelectedMnemonicType, SelectedWordListType,
                                  SelectedElectrumMnType);
   }
}
The FindMissing(..) method has to return a task to be awaitable:
Code:
public async Task FindMissing(string mnemonic, char missChar, string pass, ....
And since IReport.Init() on each call clears the message you have to change that so that on each call to FindMissing() the new messages are added at the end.
https://github.com/Coding-Enthusiast/FinderOuter/blob/681225416796a926479c8d246fb7afbf1e34484c/Src/FinderOuter/Models/Report.cs#L60
Code:
Message += $"{Environment.NewLine}Finished checking first input. Moving on to next.{Environment.NewLine}";

Now you can enter multiple mnemonics in mnemonic textbox in mnemonic recovery option separating them with a new line and each will be checked one after the other.
legendary
Activity: 1512
Merit: 7340
Farewell, Leo
Change this line into a loop where it breaks each line into a single mnemonic and makes the call. And modify the Init() on report so that it doesn't clear the report on each call.

I'll have to admit that your code is literally beautiful. Everything is organized and I can understand the functionalities of each file. Somehow, FinderOuter on Visual Studio 2019 goes really fast in contrast with my WinForms programs. Does it have to do with Avalonia? How did they manage to make it that light?



Anyway, I got off topic. What I wanted to say is that by changing line 149 on ViewModels/MissingMnemonicViewModel.cs and line 1483 on Services/MnemonicSevice.cs it's not possible. For example line 1425 on Services/MnemonicSevice.cs returns me "Invalid mnemonic length." when I try to add more than one mnemonics:

Code:
words = mnemonic.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (!allowedWordLengths.Contains(words.Length))
{
     return report.Fail("Invalid mnemonic length.");
}

I guess that everything goes dominos if I change it to:

Code:
words = mnemonic.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (!allowedWordLengths.Contains(words.Length) && Mnemonic.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries))
{
     return report.Fail("Invalid mnemonic length.");
}

Thanks in advance!
legendary
Activity: 1040
Merit: 2785
Bitcoin and C♯ Enthusiast
I'd also like to ask something else. Is it possible to brute force multiple mnemonics one after the other? One per line? If not, do you plan on doing something similar in the future? (Like adding some extra features on FinderOuter, not necessarily multiple mnemonics at once)
Normally people have one mnemonic that is damaged and want to recover it and if they have more they can just enter the second one after the first finished. I don't think there is any point in accepting more than one at a time.
You can make minimal modification to the code to run it for yourself though.
Change this line into a loop where it breaks each line into a single mnemonic and makes the call. And modify the Init() on report so that it doesn't clear the report on each call.
legendary
Activity: 1512
Merit: 7340
Farewell, Leo
Additionally when the path is something like m/0/0 the final round
And for me that I want to brute force a lot of derivation paths, makes the entire process even slower. This is what I enter on these fields:


(Where "x" is the number I change every time)



I'd also like to ask something else. Is it possible to brute force multiple mnemonics one after the other? One per line? If not, do you plan on doing something similar in the future? (Like adding some extra features on FinderOuter, not necessarily multiple mnemonics at once)
legendary
Activity: 1040
Merit: 2785
Bitcoin and C♯ Enthusiast
4-bit checksum means 1 in 16. That's why you've written 261,774 (~ 20482 / 16) on the SetBip32() call count?
Essentially yes. I modified the code to add a simple counter that incremented on each call.

I still don't understand why you wrote 00:02:44. There is no machine that can do so many operations in such little time. On my pc, brute forcing a 12-words mnemonic with 2 words missing takes me around 12 hours. (Given only the address)
It's not really that many operations.
Each SetBip32() method consists of 2048 HMACSHA512 + (path depth * 1 HMACSHA512). That is 2050 HMACSHA512 for brute forcing m/0'/0'. The 2:44 min is to compute 536,636,700 HMACs in total (it's actually a lot less due to using "specialized" code).
The specialized part is that FinderOuter isn't using the general HMAC functions, everything is specialized to compute only what it's supposed to. For example each HMAC consists of computing at least 2 SHA512 and each SHA512 has at least 2 blocks to compress. PBKDF2 (the 2048 round) repeats this in a loop where roughly 50% of it (4094 block compressions) is skipped on each call which greatly improves the speed.

The only reason why it takes a much longer time (hours) to recover using an address is because of issue #9. ECC on its own is very slow and my implementation of it turns out to be terribly slow.
Additionally when the path is something like m/0/0 the final round (after the PBKDF2) is to compute public keys (so there is an ECMultiply) which is a slow process itself. As a result the recovery process becomes a lot slower and the slowness of FinderOuter on top of it makes it take that long.
Pages:
Jump to: