К основному содержанию
T TON Adoption
Безопасность DEEP DIVE · 2026

TON mnemonic vs BIP-39: почему адреса разные

Почему 24 слова seed-фразы дают разный адрес в Tonkeeper, MyTonWallet и Ledger. Технический разбор TON-mnemonic, BIP-39, BIP-44

Автор
TON Adoption Team · исследовательская группа проекта
Опубликовано
11 мин. чтения

Типичный сценарий: пользователь записал 24 слова Tonkeeper, купил Ledger, импортировал ту же фразу в Ledger Live — и увидел пустой TON-аккаунт по другому адресу. Первая реакция: «меня взломали». На самом деле это фундаментальная особенность TON, которая редко объясняется в документации кошельков. Эта статья — технический разбор того, что именно происходит под капотом, почему стандарты разошлись и что с этим делать на практике.

TL;DR

  • Один seed phrase ≠ один адрес. Криптографически тот же набор из 24 слов может породить разные приватные ключи в зависимости от того, какой стандарт использует кошелёк.
  • Канонический TON-mnemonic (Tonkeeper, MyTonWallet single-account, tonweb-mnemonic) — собственный стандарт TON-фундации поверх BIP-39 wordlist, но с другим PBKDF2 derive и без HD-дерева.
  • BIP-39 + SLIP-0010 (Ledger, Trezor, MyTonWallet multi-account, bip_utils) — используется на аппаратных кошельках, потому что у них один общий seed на все монеты. Derivation path для TON: m/44'/607'/account'.
  • Два пути дают разные адреса на тех же 24 словах. Это не баг, это design choice.
  • Миграция между ними возможна только через перевод средств, не через повторный импорт mnemonic.

Если вам этого достаточно, остальную статью можно не читать. Дальше — детали для тех, кто хочет понять, почему так получилось и как это устроено криптографически.

Откуда вообще взялась seed phrase

Идея mnemonic seed phrase появилась в Bitcoin-сообществе в 2013 году как ответ на проблему: приватные ключи длиной 256 бит невозможно надёжно запомнить, ввести вручную или продиктовать по телефону. Стандарт BIP-39 (Bitcoin Improvement Proposal 39) предложил элегантное решение — закодировать энтропию в последовательность слов из словаря в 2048 терминов.

Стандартный словарь BIP-39 — это 2048 английских слов длиной 3-8 букв, подобранных так, чтобы первые четыре буквы каждого слова были уникальными. Это упрощает ввод и снижает риск ошибок (abandon, ability, able и т.д.). Существуют локализованные wordlist-ы — на японском, испанском, китайском — но TON, как и большинство кошельков, использует только английский.

После того как BIP-39 стал де-факто стандартом для Bitcoin-кошельков, его подхватили практически все блокчейн-проекты — Ethereum, Solana, Polkadot, Cosmos, и да, TON. Но «использовать BIP-39» означает разные вещи в разных проектах, и здесь начинаются расхождения.

BIP-39: entropy → mnemonic → seed

Криптографически BIP-39 описывает три преобразования:

  1. Энтропия → mnemonic. Случайные 128, 160, 192, 224 или 256 бит (для 12, 15, 18, 21 или 24 слов соответственно) разбиваются на группы по 11 бит. К исходной энтропии добавляется контрольная сумма — несколько бит SHA-256 от самой энтропии. Каждые 11 бит — индекс слова в словаре 2048 слов.

  2. Mnemonic → seed. Применяется функция PBKDF2 с параметрами:

PBKDF2-HMAC-SHA512(
    password = mnemonic_words_joined_with_spaces,
    salt     = "mnemonic" + optional_passphrase,
    iterations = 2048,
    dklen    = 64
)

На выходе — 64 байта (512 бит) seed. Это уже не человекочитаемый объект, а сырьё для дальнейшей деривации ключей.

  1. Seed → master key. Это уже область BIP-32, см. следующий раздел.

Обратите внимание на параметры PBKDF2: salt всегда начинается с константной строки "mnemonic", итераций всего 2048. По меркам современной криптографии 2048 итераций — это очень мало (брутфорс PBKDF2 на GPU стоит копейки). Но логика BIP-39 не в защите от подбора (24 слова дают 264 бита энтропии — невозможно перебрать), а в стандартизации.

BIP-32 и BIP-44: иерархические кошельки

BIP-32 описывает, как из одного master seed детерминированно создать дерево произвольной глубины из приватных и публичных ключей. Идея: один backup восстанавливает миллиарды адресов, и публичные ключи можно выводить независимо от приватных (для watch-only кошельков).

Каждый узел дерева адресуется путём в формате m/index/index/index/.... Индекс с апострофом (44') означает hardened derivation — особый режим, в котором для вывода ребёнка обязательно нужен родительский приватный ключ. Без апострофа — normal derivation, где из публичного ключа родителя можно вывести публичные ключи детей.

BIP-44 поверх BIP-32 стандартизирует структуру пути:

m / purpose' / coin_type' / account' / change / address_index
m / 44'      / coin_type' / 0'       / 0      / 0

coin_type — стандартизированный номер монеты по списку SLIP-0044. Для Bitcoin это 0, для Ethereum — 60, для Solana — 501, для TON — 607. То есть канонический BIP-44 путь для первого TON-адреса должен был бы выглядеть так:

m / 44' / 607' / 0' / 0 / 0

Но это не то, что используют ни Tonkeeper, ни MyTonWallet. Почему — разберём ниже.

SLIP-0010: HD-кошельки для Ed25519

BIP-32 изначально был написан под secp256k1 — кривую, на которой работают Bitcoin и Ethereum. Solana, TON и Cardano используют другую кривую — Ed25519. Простая адаптация BIP-32 на Ed25519 невозможна из-за свойств алгебры этой кривой.

SLIP-0010 (от SatoshiLabs) описывает обобщение BIP-32 на не-secp256k1 кривые, включая Ed25519. Ключевые отличия:

  • Master key выводится через HMAC-SHA512(key="ed25519 seed", msg=seed) (вместо "Bitcoin seed" для secp256k1).
  • Только hardened derivation. Для Ed25519 normal (non-hardened) деривация криптографически невозможна — все индексы в пути неявно становятся hardened.
  • Нет публичного ключа отдельно от приватного. Свойство «вывести child public key из parent public key» не работает на Ed25519, поэтому SLIP-0010 для Ed25519 не поддерживает watch-only режим.

Solana использует SLIP-0010 с путём m/44'/501'/account'/0'. Ledger для TON использует SLIP-0010 с путём m/44'/607'/account' (без change и address_index, потому что для Ed25519 они в любом случае hardened).

Почему TON отказался от BIP-44 в пользу собственного стандарта

Здесь начинается интересное. TON Foundation, разрабатывая wallet protocol, сделала несколько design choices, которые расходятся с устоявшейся практикой:

1. Свой PBKDF2 salt и больше итераций

Канонический TON использует не BIP-39 derive из mnemonic в seed. Вместо salt "mnemonic" и 2048 итераций используется:

PBKDF2-HMAC-SHA512(
    password = mnemonic_bytes,
    salt     = "TON default seed",
    iterations = 100000,
    dklen    = 64
)

100 000 итераций против 2048 у BIP-39 — это на два порядка дороже для brute force атак. Если у вас украли частичный список слов (скажем, 22 из 24), подбор оставшихся двух на TON-стандарте занимает существенно больше времени, чем на BIP-39.

2. Двухэтапная валидация mnemonic

Перед основным derive TON-mnemonic дополнительно валидируется через быстрый PBKDF2 с salt "TON seed version" и числом итераций 390 (или 256 для passphrase-режима с salt "TON fast seed version"). Первый байт результата должен равняться 0 — иначе фраза считается невалидным TON-mnemonic. Это позволяет кошельку понять, является ли введённая фраза «TON-фразой» или «обычной BIP-39-фразой».

На практике это значит: только 1 из 256 случайных BIP-39 фраз оказывается одновременно валидной TON-фразой. Поэтому генерация TON-mnemonic — итеративный процесс: сгенерировать 24 слова, проверить первый байт PBKDF2-валидации, повторить пока не получится 0.

3. Один mnemonic = один keypair

Каноничный TON не строит HD-дерево. После derive первые 32 байта результата PBKDF2 используются напрямую как Ed25519 seed, из которого получается единственный keypair. Никаких m/44'/607'/0'/0/0 — есть только один ключ на один mnemonic.

Это означает, что для нескольких TON-аккаунтов нужно либо несколько разных mnemonic (что Tonkeeper и делает в режиме нескольких кошельков), либо переход на нестандартный SLIP-0010 derive (что делает MyTonWallet в Multi-Account режиме).

4. Опциональная passphrase

TON поддерживает passphrase (по аналогии с BIP-39 25-словом) через ту же mnemonic-валидацию, но с другим salt — "TON fast seed version". Это даёт кошельку понять, является ли фраза «обычной» или «с passphrase».

Что делают разные кошельки на практике

Tonkeeper

Канонический TON-стандарт. 24 слова → PBKDF2 с salt "TON default seed" → 32 байта Ed25519 seed → один keypair → один адрес. Никаких derivation path-ов. Поддерживает passphrase через salt "TON fast seed version".

Для нескольких аккаунтов Tonkeeper хранит несколько отдельных mnemonic, не выводит их из общего seed. Импорт в Tonkeeper «обычной» BIP-39 фразы, которая не проходит TON-валидацию (первый байт PBKDF2 ≠ 0), приведёт к ошибке.

MyTonWallet

В режиме single-account полностью совместим с Tonkeeper — тот же канонический derive, те же 24 слова дают те же адреса.

В Multi-Account режиме MyTonWallet поддерживает импорт BIP-39 seed (12 или 24 слова), для которого использует SLIP-0010 derive по пути m/44'/607'/account'. Это даёт совместимость с Ledger, но не совместимо с Tonkeeper на тех же словах.

При импорте 24 слов в MyTonWallet вам предложат выбрать режим — это критический момент. «TON-mnemonic» = канонический derive (совместим с Tonkeeper); «BIP-39 / Ledger» = SLIP-0010 (другие адреса).

Tonhub

Канонический TON-стандарт, совместим с Tonkeeper и MyTonWallet single-account.

Ledger Live + TON app

Ledger использует общий BIP-39 24-слово seed для всех монет (Bitcoin, Ethereum, Solana, TON и т.д.) — это аппаратное ограничение. Внутри Secure Element нет места для отдельного TON-derive. Поэтому Ledger делает:

  1. Mnemonic (24 слова BIP-39) → seed (BIP-39 derive с salt "mnemonic", 2048 итераций).
  2. Seed → SLIP-0010 ed25519 master key.
  3. Master key → derive по пути m/44'/607'/account'.
  4. Полученный приватный ключ → Ed25519 keypair → TON-адрес.

Это совершенно другой путь относительно Tonkeeper. На входе те же 24 слова, на выходе — разные адреса. Разница не в одном звене цепочки, а во всей цепочке целиком.

Когда вы подключаете Ledger к Tonkeeper через USB, Tonkeeper не просит ввести mnemonic Ledger-а. Вместо этого он запрашивает у устройства публичный ключ по нужному пути, и сам Ledger подписывает транзакции на устройстве. Mnemonic с Ledger никогда не покидает Secure Element. Подробнее — в гайде по подключению Ledger к TON-кошельку.

Keystone, GridPlus и прочие hardware-кошельки

Те же ограничения, что у Ledger — общий BIP-39 seed на все монеты, derive через SLIP-0010 по m/44'/607'/account'. Адреса не совпадают с Tonkeeper-mnemonic.

Конкретный пример: разные адреса из одних слов

Допустим, у вас 24 слова от Tonkeeper:

abandon abandon abandon ... abandon about

(Это не реальная TON-фраза — она бы не прошла валидацию первого байта, но для иллюстрации цепочек подходит.)

Через Tonkeeper-derive:

words → PBKDF2(salt="TON default seed", iter=100000) → seed32
seed32 → Ed25519 keypair → UQA... (адрес 1)

Через Ledger-derive (SLIP-0010):

words → PBKDF2(salt="mnemonic", iter=2048) → seed64
seed64 → HMAC-SHA512("ed25519 seed", seed64) → master_key
master_key → derive_hardened(44') → derive_hardened(607') → derive_hardened(0') → keypair
keypair → UQB... (адрес 2)

UQA... и UQB... — два разных TON-адреса, выведенных из одних и тех же 24 слов. Оба валидны, оба контролируются владельцем фразы — но это разные кошельки с разными балансами.

Практика миграции: как перенести средства между кошельками

Если вы создали кошелёк в Ledger и хотите перенести его в Tonkeeper (не Ledger-аккаунт в Tonkeeper, а именно «нативный» Tonkeeper-кошелёк) — повторный импорт mnemonic не сработает. Адреса разные, баланс на новом адресе будет нулевой.

Правильная процедура:

  1. Создайте новый Tonkeeper-кошелёк с новым mnemonic (или используйте существующий).
  2. Запишите новый Tonkeeper-адрес.
  3. В Ledger Live (или в Tonkeeper в Ledger-режиме) подпишите транзакцию перевода с Ledger-аккаунта на новый Tonkeeper-адрес.
  4. Дождитесь подтверждения, проверьте баланс на новом адресе.
  5. Старый Ledger-аккаунт можно оставить пустым — он по-прежнему контролируется через Ledger, просто без средств.

Обратный сценарий (миграция Tonkeeper → Ledger) делается тем же способом: подключите Ledger как новый аккаунт в Tonkeeper, переведите средства с Tonkeeper-mnemonic на Ledger-аккаунт через обычный transfer.

Полный гайд по восстановлению TON-кошелька включает диагностику кейсов, когда mnemonic «не работает» из-за несовпадения стандартов.

Passphrase в TON: дополнительный риск

TON-кошельки (Tonkeeper, MyTonWallet) поддерживают опциональную passphrase — дополнительный пароль поверх 24 слов. Технически это меняет salt PBKDF2-derive: вместо просто "TON default seed" salt становится "TON default seed" + passphrase.

Это означает:

  • Кошелёк с пустой passphrase и кошелёк с passphrase «hello123» — это два совершенно разных адреса на тех же 24 словах.
  • Невозможно восстановить кошелёк, если passphrase утеряна. В отличие от BIP-39 (где можно перебрать короткие passphrase через скрипт), TON-derive с 100 000 итераций PBKDF2 делает brute force даже короткой passphrase непрактичным.
  • Passphrase нужно записывать отдельно от mnemonic и хранить так же надёжно, как и саму фразу.

Если у вас крупные суммы (>$10K), passphrase даёт реальную защиту от компрометации физического носителя с mnemonic. Если у вас сумма «на покрутить» — passphrase скорее создаст риск потери, чем защитит. См. обзор стратегий холодного хранения.

Безопасность: TON-mnemonic vs BIP-39

С точки зрения энтропии — равны. 24 слова из BIP-39 wordlist дают log2(2048^24) ≈ 264 бита энтропии минус 8 бит контрольной суммы = 256 бит реальной энтропии. Это столько же, сколько у Bitcoin-кошелька на 24 словах.

С точки зрения brute force — TON-mnemonic существенно стойче. 100 000 итераций PBKDF2 vs 2048 у BIP-39 — это 50× больше работы на каждую попытку подбора. Если из 24 слов украдены 22 и нужно подобрать 2 пропущенных, на BIP-39 это занимает часы на современной GPU; на TON-mnemonic — недели.

С точки зрения blast radius — хуже у TON. В BIP-39 + BIP-44 один mnemonic даёт дерево из миллиардов адресов, и компрометация одного приватного ключа (например, через RPC-утечку) затрагивает только один адрес. В каноничном TON один mnemonic = один keypair, поэтому компрометация ключа = компрометация ВСЕХ ваших TON-средств под этим mnemonic.

Это объясняет, почему практики безопасного хранения seed-фразы для TON ещё критичнее, чем для Bitcoin — у вас нет «запасных» адресов в HD-дереве.

Чек-лист: что проверить, прежде чем записать seed

  • Какой именно кошелёк создал mnemonic? Tonkeeper / MyTonWallet single-account → каноничный TON-стандарт. Ledger / MyTonWallet multi → SLIP-0010.
  • Сколько слов — 12 или 24? TON-стандарт всегда 24. 12 слов = BIP-39 / SLIP-0010 path.
  • Включена ли passphrase? Если да — записана отдельно от mnemonic и проверена на восстановление?
  • Какой адрес соответствует фразе в кошельке? Запишите первые 6-8 символов адреса вместе с фразой — это backup-проверка против «не той фразы».
  • Если вы планируете использовать тот же mnemonic в Ledger, проверьте, что оба кошелька показывают одинаковый адрес. Если разные — это нормально, но фиксируйте, какой адрес из какого кошелька.
  • Сделайте тест восстановления на новом устройстве (не на том же телефоне). Импорт mnemonic в чистом приложении и сравнение адресов — единственная проверка, что вы записали правильно.

Что почитать дальше

Если эта статья прояснила картину, дальнейшие темы:

Главное, что нужно запомнить: 24 слова — это не «адрес», это входной материал для derive-функции. Какая именно функция применена, решает кошелёк. Понимая это, вы перестанете паниковать, когда Ledger Live показывает «не тот» баланс на ваших словах, и сможете осознанно выбирать инструменты под свой security model.

Частые вопросы

Tonkeeper использует каноничный TON-стандарт — один mnemonic превращается в один Ed25519 keypair через PBKDF2 c salt 'TON default seed' и 100 000 итераций. Ledger же поверх Ed25519 seed строит SLIP-0010 дерево по пути m/44'/607'/account'. На вход подаётся одна и та же фраза, но криптографические преобразования разные — на выходе разные приватные ключи и разные адреса.
Так задумано, но это плохо документированный design choice TON-фундации. Каноничный TON отказался от BIP-32/BIP-44 дерева и сделал свой derive. Аппаратные кошельки (Ledger, Keystone) физически не могут реализовать TON-derive внутри Secure Element для всех монет сразу — у них общий мастер-seed на BIP-39, поверх которого они строят SLIP-0010. Конфликт инженерных компромиссов.
Нет. Если вы импортируете 24 слова Ledger в Tonkeeper, вы получите другой адрес — пустой. Чтобы перенести именно конкретный аккаунт, нужно экспортировать приватный ключ Ed25519 из Ledger (что Ledger Live не даёт делать напрямую) либо подписать миграционную транзакцию: создать новый адрес в Tonkeeper и перевести на него средства с Ledger.
Да, в режиме одиночного аккаунта MyTonWallet использует тот же каноничный TON-стандарт, что и Tonkeeper — 24 слова дадут один и тот же адрес. Но MyTonWallet поддерживает Multi-Account режим (включая импорт BIP-39 24-слова и Ledger-аккаунтов), где адреса будут отличаться. Проверяйте, какой именно режим включён при импорте.
Каноничный TON-mnemonic — всегда 24 слова из стандартного BIP-39 wordlist. BIP-39 допускает 12, 15, 18, 21 и 24 слова, но TON-спецификация фиксирует длину 24. Если кошелёк предлагает создать TON-аккаунт из 12 слов, это означает работу через BIP-44 / SLIP-0010, а не каноничный TON-стандарт.
Passphrase — необязательный дополнительный пароль, который смешивается с mnemonic при derive ключа. С пустой passphrase TON-кошелёк создаёт один адрес, с непустой — совершенно другой. Tonkeeper поддерживает passphrase через salt 'TON fast seed version'. Главная опасность: если passphrase не записана где-то отдельно, восстановить кошелёк по одним только 24 словам невозможно — каждый пропавший символ даёт другой адрес.
Технически — да, через библиотеки типа bip_utils. Получите адреса по m/44'/60'/0'/0/0 (ETH), m/44'/501'/0'/0' (SOL) и m/44'/607'/0' (TON через SLIP-0010). Но: TON-адрес из такого мульти-сетевого seed НЕ совпадёт с адресом каноничного TON-кошелька на тех же 24 словах. И поверхность атаки увеличивается — компрометация одной сети рискует всеми.
На уровне энтропии — то же самое: 24 слова × ~11 бит = 264 бита (минус контрольная сумма). Но TON-mnemonic использует 100 000 итераций PBKDF2 против 2048 у BIP-39, что делает brute force seed по украденному частичному списку слов на порядки дороже. С другой стороны, отсутствие HD-дерева означает, что компрометация ключа = компрометация ВСЕХ ваших TON-средств под этим mnemonic.

Похожие материалы