Author

Topic: In C#, is there a way to use seed phrases the way Electrum would do it? (Read 81 times)

legendary
Activity: 3472
Merit: 10611
Electrum uses a custom wordlist
Electrum uses the same word-list as BIP-39 but the algorithm is flexible and allows you to enter any list of words containing any number of words and use that as your custom word-list.

Quote
Split the seed phrase into words, map each word to its index, and convert to byte array.
There is no need to perform the middle part if you want to derive the BIP32 seed. Just verify if the words are correct and then do a UTF8 decode on the string to get the bytes.

Quote
Electrum uses a HMAC-SHA512 to the seed bytes with a specific key / seed version so the result is used as the master private key,
HMAC is used for the seed version not to derive BIP32 seed from the mnemonic. To do that Electrum is similar to BIP39 and it uses PBKDF2

Quote
Here's the example I used:
I think you forgot to fill in the methods so what you posted more like pseudocode not example to be used considering it throws exceptions.
The only code it has is also wrong, the DeriveMasterPrivateKey() method as I said should be used to verify the version and determine what type of addresses to derive not to derive the master key.

The link OP posted above has a working implementation in C#
https://github.com/Autarkysoft/Denovo/blob/master/Src/Autarkysoft.Bitcoin/ImprovementProposals/ElectrumMnemonic.cs
Vod
legendary
Activity: 3668
Merit: 3010
Licking my boob since 1970
I just starting learning this in C#, not C++ last week since I now use Electrum (thanks icopress!).  Smiley

Electrum uses a custom wordlist and a proprietary algorithm different from BIP39, as you said.

You'll need to implement Electrum's seed phrase decoding logic. Split the seed phrase into words, map each word to its index, and convert to byte array.  Electrum uses a HMAC-SHA512 to the seed bytes with a specific key / seed version so the result is used as the master private key, and the addresses are encoded using Base58Check or Bech32.

Here's the example I used:

Code:
using System;
using System.Security.Cryptography;
using System.Text;

class ElectrumAddressGenerator
{
    public static void Main(string[] args)
    {
        string seedPhrase = "your_seed_phrase_here";
        byte[] seedBytes = GetSeedBytesFromPhrase(seedPhrase);
        byte[] masterPrivateKey = DeriveMasterPrivateKey(seedBytes);
        string address = DeriveAddress(masterPrivateKey);
        Console.WriteLine("Generated Address: " + address);
    }

    static byte[] GetSeedBytesFromPhrase(string seedPhrase)
    {
        // Implement Electrum's seed phrase decoding logic
        // This involves mapping words to indices and converting to bytes
        throw new NotImplementedException();
    }

    static byte[] DeriveMasterPrivateKey(byte[] seedBytes)
    {
        using (HMACSHA512 hmac = new HMACSHA512(Encoding.UTF8.GetBytes("Seed version")))
        {
            return hmac.ComputeHash(seedBytes);
        }
    }

    static string DeriveAddress(byte[] masterPrivateKey)
    {
        // Implement key derivation and address generation logic
        // This involves SHA256, RIPEMD160, and Base58 encoding
        throw new NotImplementedException();
    }
}

newbie
Activity: 7
Merit: 0
Regarding the seed phrase's validity, I've made a related reply July last year, here: https://bitcointalksearch.org/topic/m.64305668
It covers the algorithm to compute if the combination of words has a matching reserved "version number".
If it does, the seed is valid, if not, find another combination and repeat.

That's great, thx! I found that implemented here, and it's nice to have your explanation of the logic so I can follow why it's doing what it's doing...

https://github.com/Autarkysoft/Denovo/blob/419207ecb635ccabb94feaf2fd480d7e73ec86f9/Src/Autarkysoft.Bitcoin/ImprovementProposals/ElectrumMnemonic.cs#L302
legendary
Activity: 2646
Merit: 6681
Self-proclaimed Genius
Regarding the seed phrase's validity, I've made a related reply July last year, here: https://bitcointalksearch.org/topic/m.64305668
It covers the algorithm to compute if the combination of words has a matching reserved "version number".
If it does, the seed is valid, if not, find another combination and repeat.

Anyways, I can't find a C++ implementation of what you're looking for;
And as you know it Electrum is in Python: github.com/spesmilo/electrum/blob/master/electrum/mnemonic.py#L243
newbie
Activity: 7
Merit: 0
Hello.

I'm working on a script in C# to (possibly, hopefully, maybe) solve a BTC puzzle...

I have a list of seed words that I can use to generate seed phrases (yes, it's a lot of permutations, I know), and an address with the prize funds in it...

I'm using NBitcoin to check the seed phrases I generate (to see if they're valid) and then to generate an address I can check against the given funded address...

The issue is that if the puzzle creator used Electrum to generate the seed phrase and address, then I'll never get a match using NBitcoin...

I've looked and searched and I can't seem to find a solution for validating seed phrases and generating addresses the way Electrum does it using C# ... All I know for sure is that Electrum does it different than the standard way, so the NBitcoin lib isn't enough...

Anyone know of a good C# Electrum client/library I can use for this...?

And/Or is there a way I could use a local install of Electrum (on Windows, obviously) to do this via command-line or something...? I've seen the command line docs, but all of the "restore wallet" commands seem to take an Electrum seed file as an input, not a plain seed phrase...

And/Or is there a way to, like, roll my own solution using the crypto/hashing functionality that's built into C# (eg using the various tools available under the `System.Security.Cryptography` namespace, to duplicate what Electrum does under-the-hood)? I'd almost certainly never be able to figure it out on my own, but if someone already knows the steps that need to be taken (like: first MD5 this, and then SHA256 that, and then check the result against X, etc) then I might be able to cobble something together... Crazier things have happened  Cheesy

Thanks in advance for any help/insight anyone can provide
Jump to: