Author

Topic: deleted (Read 148 times)

jr. member
Activity: 40
Merit: 8
December 15, 2024, 04:01:50 AM
#5

I read what mcdouglasx said and took it as a challenge for myself. Take a good look at what I did: The ipad_key and opad_key arrays with 128 bytes each to perform HMAC operations. When the mnemonic_length exceeds 128 bytes (24 words), the remainder of the key is not being processed correctly. Therefore, it would be necessary to implement a key normalization process that complies with HMAC. If the key is larger than the block size (128 bytes for SHA-512), it must first be hashed to reduce its size. Then, it should be padded with zeros to reach 128 bytes if needed.

The changes I made to the file int_to_address.cl look like this:
Code:
__kernel void int_to_address(ulong mnemonic_start_hi, ulong mnemonic_start_lo, __global uchar * target_mnemonic, __global uchar * found_mnemonic) { 
    ulong idx = get_global_id(0);

    ulong mnemonic_lo = mnemonic_start_lo + idx;
    ulong mnemonic_hi = mnemonic_start_hi;

    // ... [existing code to construct 'bytes' and 'mnemonic']

    // Constructing the mnemonic
    uchar mnemonic[180] = {0};
    uchar mnemonic_length = 11;
    for(int i = 0; i < 12; i++) {
        int word_index = indices[i];
        int word_length = word_lengths[word_index];
        mnemonic_length += word_lengths[word_index];
    }

    int mnemonic_index = 0;
    for (int i = 0; i < 12; i++) {
        int word_index = indices[i];
        int word_length = word_lengths[word_index];
       
        for(int j = 0; j < word_length; j++) {
            mnemonic[mnemonic_index] = words[word_index][j];
            mnemonic_index++;
        }
        mnemonic[mnemonic_index] = 32; // Space
        mnemonic_index++;
    }
    mnemonic[mnemonic_index - 1] = 0; // Null termination

    // Key Normalization
    uchar normalized_key[128] = {0};
    if (mnemonic_length > 128) {
        // If the mnemonic is larger than 128 bytes, hash it with SHA-512
        sha512(&mnemonic, mnemonic_length, &normalized_key);
        // Remaining bytes are already zero-padded (done at initialization)
    } else {
        // If the mnemonic is less than or equal to 128 bytes, copy it directly
        for(int i = 0; i < mnemonic_length; i++) {
            normalized_key[i] = mnemonic[i];
        }
        // Remaining bytes are already zero-padded
    }

    // Initialization of ipad_key and opad_key
    uchar ipad_key[128];
    uchar opad_key[128];
    for(int x = 0; x < 128; x++) {
        ipad_key[x] = 0x36;
        opad_key[x] = 0x5c;
    }

    // Apply XOR with the normalized key
    for(int x = 0; x < 128; x++) {
        ipad_key[x] ^= normalized_key[x];
        opad_key[x] ^= normalized_key[x];
    }

    // Continue seed derivation process
    uchar seed[64] = {0};
    uchar sha512_result[64] = {0};
    uchar key_previous_concat[256] = {0};
    uchar salt[12] = {109, 110, 101, 109, 111, 110, 105, 99, 0, 0, 0, 1};
    for(int x = 0; x < 128; x++) {
        key_previous_concat[x] = ipad_key[x];
    }
    for(int x = 0; x < 12; x++) {
        key_previous_concat[x + 128] = salt[x];
    }

    sha512(&key_previous_concat, 140, &sha512_result);
    copy_pad_previous(&opad_key, &sha512_result, &key_previous_concat);
    sha512(&key_previous_concat, 192, &sha512_result);
    xor_seed_with_round(&seed, &sha512_result);

    for(int x = 1; x < 2048; x++) {
        copy_pad_previous(&ipad_key, &sha512_result, &key_previous_concat);
        sha512(&key_previous_concat, 192, &sha512_result);
        copy_pad_previous(&opad_key, &sha512_result, &key_previous_concat);
        sha512(&key_previous_concat, 192, &sha512_result);
        xor_seed_with_round(&seed, &sha512_result);
    }

    // ... [existing code for key generation and address verification]

    if(found_target == 1) {
        found_mnemonic[0] = 0x01;
        for(int i = 0; i < mnemonic_index; i++) {
            target_mnemonic[i] = mnemonic[i];
        }
    }
}

And in the file just_seed.cl, it turned out like this:
Code:
__kernel void just_seed(ulong mnemonic_start_hi, ulong mnemonic_start_lo, __global uchar * target_mnemonic, __global uchar * found_mnemonic) {
    ulong idx = get_global_id(0);

    ulong seed_start = idx * 64;
    ulong mnemonic_lo = mnemonic_start_lo + idx;
    ulong mnemonic_hi = mnemonic_start_hi;

    // ... [existing code to build 'bytes' and 'mnemonic']

    // Mnemonic construction
    uchar mnemonic[180];
    int mnemonic_index = 0;
    for (int i = 0; i < 12; i++) {
        int word_index = indices[i];
        int word_length = word_lengths[word_index];
       
        for(int j = 0; j < word_length; j++) {
            mnemonic[mnemonic_index] = words[word_index][j];
            mnemonic_index++;
        }
        mnemonic[mnemonic_index] = 32; // Space
        mnemonic_index++;
    }
    mnemonic[mnemonic_index - 1] = 0; // Null termination

    uchar mnemonic_length = 11 + word_lengths[indices[0]] + word_lengths[indices[1]] + word_lengths[indices[2]] + word_lengths[indices[3]] + word_lengths[indices[4]] + word_lengths[indices[5]] + word_lengths[indices[6]] + word_lengths[indices[7]] + word_lengths[indices[8]] + word_lengths[indices[9]] + word_lengths[indices[10]] + word_lengths[indices[11]];

    // Key normalization
    uchar normalized_key[128] = {0};
    if (mnemonic_length > 128) {
        // If the mnemonic is larger than 128 bytes, hash with SHA-512
        sha512(&mnemonic, mnemonic_length, &normalized_key);
        // Fill remaining bytes with zeros (already done during initialization)
    } else {
        // If the mnemonic is 128 bytes or less, copy directly
        for(int i = 0; i < mnemonic_length; i++) {
            normalized_key[i] = mnemonic[i];
        }
        // Remaining bytes are already filled with zeros
    }

    // Initialization of ipad_key and opad_key
    uchar ipad_key[128];
    uchar opad_key[128];
    for(int x = 0; x < 128; x++) {
        ipad_key[x] = 0x36;
        opad_key[x] = 0x5c;
    }

    // Apply XOR with normalized key
    for(int x = 0; x < 128; x++) {
        ipad_key[x] ^= normalized_key[x];
        opad_key[x] ^= normalized_key[x];
    }

    // Continue the seed derivation process
    uchar seed[64] = { 0 };
    uchar sha512_result[64] = { 0 };
    uchar key_previous_concat[256] = { 0 };
    uchar salt[12] = { 109, 110, 101, 109, 111, 110, 105, 99, 0, 0, 0, 1 };
    for(int x = 0; x < 128; x++) {
        key_previous_concat[x] = ipad_key[x];
    }
    for(int x = 0; x < 12; x++) {
        key_previous_concat[x + 128] = salt[x];
    }

    sha512(&key_previous_concat, 140, &sha512_result);
    copy_pad_previous(&opad_key, &sha512_result, &key_previous_concat);
    sha512(&key_previous_concat, 192, &sha512_result);
    xor_seed_with_round(&seed, &sha512_result);

    for(int x = 1; x < 2048; x++) {
        copy_pad_previous(&ipad_key, &sha512_result, &key_previous_concat);
        sha512(&key_previous_concat, 192, &sha512_result);
        copy_pad_previous(&opad_key, &sha512_result, &key_previous_concat);
        sha512(&key_previous_concat, 192, &sha512_result);
        xor_seed_with_round(&seed, &sha512_result);
    }
}

This was my work, test it to see if everything is running fine and let me know




I've made a lot of changes to some of the kernel files and the host file, but the problem I’m facing is the incorrect derivation of addresses from the 24 words mnemonics. As you can see, after running the program, you will get two text files: one for the mnemonics and the other for the addresses. The mnemonics are correct, but the addresses are not. I want to correctly derive the BIP49 addresses from the mnemonics and save them into a text file.

https://github.com/johnnstewart/mt-gpu/tree/main
?
Activity: -
Merit: -
December 12, 2024, 02:39:08 PM
#4

I read what mcdouglasx said and took it as a challenge for myself. Take a good look at what I did: The ipad_key and opad_key arrays with 128 bytes each to perform HMAC operations. When the mnemonic_length exceeds 128 bytes (24 words), the remainder of the key is not being processed correctly. Therefore, it would be necessary to implement a key normalization process that complies with HMAC. If the key is larger than the block size (128 bytes for SHA-512), it must first be hashed to reduce its size. Then, it should be padded with zeros to reach 128 bytes if needed.

The changes I made to the file int_to_address.cl look like this:
Code:
__kernel void int_to_address(ulong mnemonic_start_hi, ulong mnemonic_start_lo, __global uchar * target_mnemonic, __global uchar * found_mnemonic) {
    ulong idx = get_global_id(0);

    ulong mnemonic_lo = mnemonic_start_lo + idx;
    ulong mnemonic_hi = mnemonic_start_hi;

    // ... [existing code to construct 'bytes' and 'mnemonic']

    // Constructing the mnemonic
    uchar mnemonic[180] = {0};
    uchar mnemonic_length = 11;
    for(int i = 0; i < 12; i++) {
        int word_index = indices[i];
        int word_length = word_lengths[word_index];
        mnemonic_length += word_lengths[word_index];
    }

    int mnemonic_index = 0;
    for (int i = 0; i < 12; i++) {
        int word_index = indices[i];
        int word_length = word_lengths[word_index];
       
        for(int j = 0; j < word_length; j++) {
            mnemonic[mnemonic_index] = words[word_index][j];
            mnemonic_index++;
        }
        mnemonic[mnemonic_index] = 32; // Space
        mnemonic_index++;
    }
    mnemonic[mnemonic_index - 1] = 0; // Null termination

    // Key Normalization
    uchar normalized_key[128] = {0};
    if (mnemonic_length > 128) {
        // If the mnemonic is larger than 128 bytes, hash it with SHA-512
        sha512(&mnemonic, mnemonic_length, &normalized_key);
        // Remaining bytes are already zero-padded (done at initialization)
    } else {
        // If the mnemonic is less than or equal to 128 bytes, copy it directly
        for(int i = 0; i < mnemonic_length; i++) {
            normalized_key[i] = mnemonic[i];
        }
        // Remaining bytes are already zero-padded
    }

    // Initialization of ipad_key and opad_key
    uchar ipad_key[128];
    uchar opad_key[128];
    for(int x = 0; x < 128; x++) {
        ipad_key[x] = 0x36;
        opad_key[x] = 0x5c;
    }

    // Apply XOR with the normalized key
    for(int x = 0; x < 128; x++) {
        ipad_key[x] ^= normalized_key[x];
        opad_key[x] ^= normalized_key[x];
    }

    // Continue seed derivation process
    uchar seed[64] = {0};
    uchar sha512_result[64] = {0};
    uchar key_previous_concat[256] = {0};
    uchar salt[12] = {109, 110, 101, 109, 111, 110, 105, 99, 0, 0, 0, 1};
    for(int x = 0; x < 128; x++) {
        key_previous_concat[x] = ipad_key[x];
    }
    for(int x = 0; x < 12; x++) {
        key_previous_concat[x + 128] = salt[x];
    }

    sha512(&key_previous_concat, 140, &sha512_result);
    copy_pad_previous(&opad_key, &sha512_result, &key_previous_concat);
    sha512(&key_previous_concat, 192, &sha512_result);
    xor_seed_with_round(&seed, &sha512_result);

    for(int x = 1; x < 2048; x++) {
        copy_pad_previous(&ipad_key, &sha512_result, &key_previous_concat);
        sha512(&key_previous_concat, 192, &sha512_result);
        copy_pad_previous(&opad_key, &sha512_result, &key_previous_concat);
        sha512(&key_previous_concat, 192, &sha512_result);
        xor_seed_with_round(&seed, &sha512_result);
    }

    // ... [existing code for key generation and address verification]

    if(found_target == 1) {
        found_mnemonic[0] = 0x01;
        for(int i = 0; i < mnemonic_index; i++) {
            target_mnemonic[i] = mnemonic[i];
        }
    }
}

And in the file just_seed.cl, it turned out like this:
Code:
__kernel void just_seed(ulong mnemonic_start_hi, ulong mnemonic_start_lo, __global uchar * target_mnemonic, __global uchar * found_mnemonic) {
    ulong idx = get_global_id(0);

    ulong seed_start = idx * 64;
    ulong mnemonic_lo = mnemonic_start_lo + idx;
    ulong mnemonic_hi = mnemonic_start_hi;

    // ... [existing code to build 'bytes' and 'mnemonic']

    // Mnemonic construction
    uchar mnemonic[180];
    int mnemonic_index = 0;
    for (int i = 0; i < 12; i++) {
        int word_index = indices[i];
        int word_length = word_lengths[word_index];
       
        for(int j = 0; j < word_length; j++) {
            mnemonic[mnemonic_index] = words[word_index][j];
            mnemonic_index++;
        }
        mnemonic[mnemonic_index] = 32; // Space
        mnemonic_index++;
    }
    mnemonic[mnemonic_index - 1] = 0; // Null termination

    uchar mnemonic_length = 11 + word_lengths[indices[0]] + word_lengths[indices[1]] + word_lengths[indices[2]] + word_lengths[indices[3]] + word_lengths[indices[4]] + word_lengths[indices[5]] + word_lengths[indices[6]] + word_lengths[indices[7]] + word_lengths[indices[8]] + word_lengths[indices[9]] + word_lengths[indices[10]] + word_lengths[indices[11]];

    // Key normalization
    uchar normalized_key[128] = {0};
    if (mnemonic_length > 128) {
        // If the mnemonic is larger than 128 bytes, hash with SHA-512
        sha512(&mnemonic, mnemonic_length, &normalized_key);
        // Fill remaining bytes with zeros (already done during initialization)
    } else {
        // If the mnemonic is 128 bytes or less, copy directly
        for(int i = 0; i < mnemonic_length; i++) {
            normalized_key[i] = mnemonic[i];
        }
        // Remaining bytes are already filled with zeros
    }

    // Initialization of ipad_key and opad_key
    uchar ipad_key[128];
    uchar opad_key[128];
    for(int x = 0; x < 128; x++) {
        ipad_key[x] = 0x36;
        opad_key[x] = 0x5c;
    }

    // Apply XOR with normalized key
    for(int x = 0; x < 128; x++) {
        ipad_key[x] ^= normalized_key[x];
        opad_key[x] ^= normalized_key[x];
    }

    // Continue the seed derivation process
    uchar seed[64] = { 0 };
    uchar sha512_result[64] = { 0 };
    uchar key_previous_concat[256] = { 0 };
    uchar salt[12] = { 109, 110, 101, 109, 111, 110, 105, 99, 0, 0, 0, 1 };
    for(int x = 0; x < 128; x++) {
        key_previous_concat[x] = ipad_key[x];
    }
    for(int x = 0; x < 12; x++) {
        key_previous_concat[x + 128] = salt[x];
    }

    sha512(&key_previous_concat, 140, &sha512_result);
    copy_pad_previous(&opad_key, &sha512_result, &key_previous_concat);
    sha512(&key_previous_concat, 192, &sha512_result);
    xor_seed_with_round(&seed, &sha512_result);

    for(int x = 1; x < 2048; x++) {
        copy_pad_previous(&ipad_key, &sha512_result, &key_previous_concat);
        sha512(&key_previous_concat, 192, &sha512_result);
        copy_pad_previous(&opad_key, &sha512_result, &key_previous_concat);
        sha512(&key_previous_concat, 192, &sha512_result);
        xor_seed_with_round(&seed, &sha512_result);
    }
}

This was my work, test it to see if everything is running fine and let me know


member
Activity: 239
Merit: 53
New ideas will be criticized and then admired.
December 12, 2024, 11:39:58 AM
#3
when trying the code of this repo
https://github.com/johncantrell97/bip39-solver-gpu
when i try with any mnemonic longer than 128 chars (24 words for example), the resulting seed is wrong. I see the work done with the ipad/opad which is 128 byte long, can anyone give me a pointer on how to adapt the code to support longer mnemonics 24 words specifically?

To process longer mnemonics, you need to increase the size of the blocks used in the HMAC operations from 128 bits to 256 bits. This is because the length of a 24-word mnemonic exceeds 128 bytes and requires greater capacity to handle it correctly.

Since the code is not designed for that, you would have to modify a large part of the code, especially the files int_to_address.cl and just_seed.cl, which are truncated to 12 words.
legendary
Activity: 2870
Merit: 7490
Crypto Swap Exchange
December 12, 2024, 03:45:51 AM
#2
I don't really know how about programming, so i can't give pointer about modify the code. But if your goal is to brute-force 24 BIP39 words, consider using BTCRecover which is actively developed with GPU support.
jr. member
Activity: 40
Merit: 8
December 12, 2024, 12:11:13 AM
#1
deleted
Jump to: