You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BIP-0039助记词23词推导第24校验词代码错误排查求助

BIP39助记词第24个校验词推导错误修复

问题描述

给定有效BIP39助记词:

cute door network found clown neither slight common torch tissue project melt bottom marble tunnel aisle kitchen staff only unhappy measure census need miss

使用下方Python代码从前23个词推导第24个校验词时,输出结果为"type",与正确结果不符。

原错误代码

import hashlib

def get_checksum_word(words_path: str):
    with open(words_path, 'r') as f:
        word_list = f.read().splitlines()

    # Get the first 23 words of the mnemonic
    mnemonic = input("Enter 23 words separated by spaces: ")
    words = mnemonic.strip().split()
    if len(words) != 23:
        raise ValueError("Invalid number of words in mnemonic")

    # Generate the binary string from the first 23 words
    binary_str = ''
    for word in words:
        index = word_list.index(word) + 1
        print(index)
        binary_str += bin(index)[2:].zfill(11)
    entropy_length = len(binary_str)

    # Calculate the checksum
    entropy_bytes = b''
    for i in range(0, entropy_length, 8):
        byte = int(binary_str[i:i+8], 2).to_bytes(1, 'big')
        entropy_bytes += byte
    checksum = hashlib.sha256(entropy_bytes).digest()[0]
    binary_str += bin(checksum)[2:].zfill(8)

    # Get the index of the 24th word
    index = int(binary_str[-11:], 2)
    word = word_list[index]

    print("The 24th word is:", word)

错误原因分析

  1. 词表索引错误:BIP39词表索引从0开始(0-2047对应2048个词),每个词对应11位二进制值。原代码中index = word_list.index(word) + 1错误地将索引加1,导致生成的二进制串完全偏离正确值,这是核心错误。
  2. 熵处理逻辑错误:23个词对应253位二进制串,原代码直接按8位一组转换为字节,而253不是8的整数倍,最后一组仅5位,转换时自动补前导0,导致熵值被篡改,后续校验位计算完全错误。
  3. 校验位拼接错误:BIP39中24词助记词的校验位仅8位,原代码直接将完整8位校验位拼接到253位串后,总长度为261位,无法正确拆分出最后11位的校验词索引。

修正后的代码

import hashlib

def get_checksum_word(words_path: str):
    with open(words_path, 'r') as f:
        word_list = f.read().splitlines()

    mnemonic = input("Enter 23 words separated by spaces: ")
    words = mnemonic.strip().split()
    if len(words) != 23:
        raise ValueError("Invalid number of words in mnemonic")

    # 将每个词转换为11位二进制串(使用词表原始索引,从0开始)
    binary_str = ''
    for word in words:
        idx = word_list.index(word)
        binary_str += bin(idx)[2:].zfill(11)
    
    # 遍历熵的最后3位所有可能(0-7,共8种),找到符合校验规则的组合
    for e_suffix in range(8):
        e_suffix_bin = bin(e_suffix)[2:].zfill(3)
        # 拼接得到完整的256位熵二进制串
        full_entropy_bin = binary_str + e_suffix_bin
        # 转换为字节用于SHA256计算
        entropy_bytes = bytes(int(full_entropy_bin[i:i+8], 2) for i in range(0, 256, 8))
        # 计算SHA256哈希,提取前8位作为校验位
        sha256_hash = hashlib.sha256(entropy_bytes).digest()
        checksum_bin = bin(sha256_hash[0])[2:].zfill(8)
        # 拼接熵的最后3位和校验位,得到第24个词的11位二进制索引
        last_word_bin = e_suffix_bin + checksum_bin
        last_word_idx = int(last_word_bin, 2)
        
        # 验证生成的完整助记词是否符合BIP39校验规则
        full_mnemonic_bin = binary_str + last_word_bin
        verify_entropy_bin = full_mnemonic_bin[:256]
        verify_checksum_bin = full_mnemonic_bin[256:]
        verify_entropy_bytes = bytes(int(verify_entropy_bin[i:i+8], 2) for i in range(0, 256, 8))
        calculated_checksum_bin = bin(hashlib.sha256(verify_entropy_bytes).digest()[0])[2:].zfill(8)[:8]
        
        if verify_checksum_bin == calculated_checksum_bin:
            print("The 24th word is:", word_list[last_word_idx])
            return
    raise ValueError("Invalid 23 words, no valid checksum word found")

修正说明

  1. 移除了索引加1的错误,直接使用词表原始索引生成二进制串。
  2. 按照BIP39规范,23个词对应熵的前253位,遍历熵最后3位的所有可能(共8种),计算对应的校验位并验证。
  3. 增加了校验验证步骤,确保生成的第24个词符合BIP39规则。

内容的提问来源于stack exchange,提问作者user713813

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 03:45:05