Skip to content

[bug] Recovery of BIP-39 mnemonic from SLIP-39 is cryptographically incorrect #90

@alvroble

Description

@alvroble

Description

I’d like to highlight a potentially misleading feature in the SLIP-39 implementation in embit. This issue was found while developing a SLIP-39 to BIP-39 recovery feature in SeedSigner (SeedSigner/seedsigner#636). Specifically, the potential problem is in the method that allows recovery of a BIP-39 mnemonic from SLIP-39 shares:

embit/src/embit/slip39.py

Lines 353 to 359 in 9d59774

@classmethod
def recover_mnemonic(cls, share_mnemonics, passphrase=b""):
"""Recovers the BIP39 mnemonic from a bunch of SLIP39 mnemonics"""
shares = [Share.parse(m) for m in share_mnemonics]
share_set = ShareSet(shares)
secret = share_set.recover(passphrase)
return mnemonic_from_bytes(secret)

According to @iancoleman/slip39#1, this process is not practically meaningful and may cause user confusion:

  • SLIP-39 and BIP-39 are separate schemes. They use different algorithms to generate the master secret/seed from a mnemonic and passphrase.
  • Combining SLIP-39 shares and using the result as entropy for a BIP-39 mnemonic will create a different wallet, not the original one. This could result in users thinking they have restored their original wallet, while in reality, they have generated a new, unrelated seed.
  • The process from SLIP-39 shares to BIP-39 mnemonic is not cryptographically feasible. PBKDF2-SHA-512 is a one-way function.
  • Allowing this feature may give users a false sense of security and could lead to accidental loss of funds.

Also see https://trezor.io/guides/backups-recovery/general-standards/slip39-faqs:

No. Converting SLIP39 wallets back to BIP39 is not possible due to fundamental differences in how both standards handle backups and security.

Request

It may be prudent to either:

  • Remove this method,
  • add explicit warnings in documentation and code to prevent misuse and explain the risks, or
  • modify the code to recover just a BIP32 HD Key from the master secret as entropy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions