Коротко

  • Помилка у прошивці призвела до того, що гаманці Coldcard генерували сиди з програмного псевдовипадкового генератора замість апаратного чіпа, призначеного для цього.
  • Ця помилка фактично зменшила простір пошуку з 128 біт до приблизно 40 на старіших моделях.
  • Ось що це означає і як це призвело до крадіжки понад 130 мільйонів доларів у біткоїнах.

Хтось спорожняє біткоїн-гаманці, які ніколи не мали бути доступними.

Монети лежали на пристроях Coldcard — апаратних гаманцях від канадського виробника Coinkite, які ніколи не підключаються до інтернету. Жодного фішингового посилання. Жодного шкідливого програмного забезпечення. Жодного вкраденого ноутбука. Зловмисники просто обчислили закриті ключі.

Galaxy Research відстежила понад 1 596 BTC, вкрадених у трьох підтверджених хвилях, з підозрюваною четвертою хвилею, яка підняла б загальну суму до приблизно 2 055 BTC — близько 130 мільйонів доларів за поточними цінами. Одна операція перемістила 70 мільйонів доларів за 41 хвилину. Coinkite повідомляє, що принаймні 15 окремих зловмисників долучилися.

Компанія опублікувала технічний довідник 1 серпня, пояснюючи, що пішло не так. Це надзвичайно відвертий документ, і коротка версія полягає в тому, що гаманець вісім років кидав завантажені кісті, і ніхто цього не помітив.

Нуль — це теж щось

У 2021 році Coinkite перевела криптографію Coldcard на libsecp256k1, ту саму бібліотеку, яку використовує Bitcoin Core. Звучить розумно. Інтеграція — це те, де все розвалилося.

Міграція тихо перенаправила генерацію сидів з власного апаратного генератора випадкових чисел Coldcard на програмний резервний варіант MicroPython — невеликий алгоритм під назвою Yasmarang, який існує для пристроїв без чіпа випадковості взагалі.

Coldcard має чіп випадковості. Просто його перестали питати.

Причина майже занадто мала, щоб у неї повірити. Охоронець збірки використав #ifndef, який перевіряє, чи існує налаштування, а не чи воно увімкнене. Coinkite визначив це налаштування як нуль, що означає "вимкнено". Оскільки нуль все одно вважається визначеним, перевірка безпеки пройшла, і збірка завершилася. Обидві версії функції мали однакові сигнатури, тому ніщо не виглядало підозріло.

"Основна частина випадковості в COLDCARD надходила з PRNG, про який я не знав, що він насправді є у вихідному коді", — написав Coinkite, маючи на увазі генератор псевдовипадкових чисел — програмне забезпечення, яке створює числа, що виглядають випадковими, але слідують фіксованому алгоритму від початкового значення.

Подайте алгоритму те саме початкове значення — і отримаєте той самий результат. Щоразу.

На пристроях Mk2 і Mk3 з прошивкою від 4.0.1 до 4.1.9 це початкове значення походило з серійного номера чіпа та його годинника. Coinkite оцінює результуючий простір пошуку приблизно в 40 біт. Новіші моделі додавали трохи ентропії від захищеного елемента, піднімаючи її приблизно до 72 біт.

Жоден з них не досягає 128 — цільового значення.

Різниця важливіша, ніж здається. Біти — це показники степеня. Простір пошуку в 128 біт містить більше комбінацій, ніж атомів у спостережуваному Всесвіті, і ніхто його не шукає. Сорок біт — це приблизно трильйон — число, яке пристойний ноутбук може перебрати. Кожен втрачений біт удвічі зменшує роботу.

Інженерна команда Block, яка опублікувала власний аналіз, оцінює ефективний простір пошуку захищеного елемента новіших пристроїв у 2^32 кандидатів, у середньому близько 2^31 спроб. Їхня оцінка для старіших плат є більш прямою: для відомого ідентифікатора пристрою, стану таймера та історії викликів генерація гаманця є детермінованою.

А детермінованість — це протилежність випадковості, яка є важливою для криптографії.

Не "слабкий". Передбачуваний.

Coinkite підозрює, що це було знайдено машиною. "Ми повинні припустити, що хтось використав ШІ для перегляду попередніх версій нашої прошивки і натрапив на цю проблему", — написала компанія, додавши, що нещодавно вона прогнала одну з найкращих доступних моделей ШІ по тому ж коду і нічого не знайшла. "І атакуючі, і захисники мають однакові інструменти ШІ, але сьогодні це не допомогло нам, а лише допомогло поганим хлопцям".

Виправлена прошивка вийшла для всіх уражених моделей. Вона не відновлює існуючі сід-фрази; ці гаманці потрібно перегенерувати та переказати кошти. Decrypt висвітлював, як повітряний ізольований зберігання змінюється після такого експлойту, і відстежував збитки, що зростають понад $114 мільйонів.

Що таке ентропія насправді

Ентропія — це міра того, скільки атакуючий не знає.

Іншими словами, це, по суті, невизначеність, яка вимірюється в бітах. Один біт — це один підкинутий монет: два результати, і вгадуючий вгадує правильно в половині випадків. Десять бітів — це 1024 результати. Кожен біт подвоює роботу вгадуючого.

Біткоїн-гаманець — це дуже велике число, яке тримається в секреті. Адреса, на яку люди надсилають монети, математично виводиться з нього, і це виведення працює лише в один бік — ви можете перейти від ключа до адреси, але ніколи назад.

Тому безпека кожного гаманця залежить від одного питання: скільки чисел атакуючий повинен спробувати?

Якщо число було вибрано з 128 бітами ентропії, відповідь: «більше, ніж дозволяє фізика». Якщо воно було вибрано з 40, відповідь: «дайте мені трохи часу».

Це та сама властивість, яка робить загрозу квантових обчислень вартою обговорення — квантова машина атакувала б математику, яка пов'язує ключ з адресою. Багу Coldcard це ніколи не було потрібно. Він зробив ключі вгадуваними до того, як ця математика вступала в гру.

Ось де словниковий запас стає слизьким. Псевдовипадковий генератор створює вихідні дані, які проходять статистичні тести на випадковість, тож практично нічого, що електронна таблиця позначила б. Ці вихідні дані все одно повністю визначаються своїм початковим значенням. Вони виглядають випадковими, але не є такими.

Статистична випадковість і криптографічна непередбачуваність — це різні властивості, і вихідні дані Coldcard пройшли б перший тест, повністю проваливши другий.

Справжня випадковість має походити з фізичного шуму: електричного джиттера в схемі, теплових флуктуацій, радіоактивного розпаду. Саме для цього був апаратний чіп на Coldcard. Саме цей чіп відключив прапорець збірки.

Тоді Люк Дашджр згадав про гральні кістки

Коли користувачі поспішали перегенерувати сид-фрази, багато хто звернувся до очевидного низькотехнологічного рішення. Coldcard дозволяють кидати фізичні кістки та вводити результати як ентропію. Власні інструкції Coinkite вважають сид-фрази, створені з щонайменше 50 незалежними, приватними кидками кісток, не схильними до ризику від цього бага.

Це може звучати безглуздо, але компанія насправді продає мішечок зі «100 милими крихітними гральними кісточками», щоб полегшити вам весь процес.

31 липня розробник Bitcoin Core Люк Дашджр опублікував попередження: «Досить багато людей пропонують/використовують гральні кістки для пом'якшення вразливості Coldcard. Зауважте, що звичайні гральні кістки не призначені для криптографічної безпеки. Якщо ви збираєтеся це робити, вам, ймовірно, варто купити точні казино-кістки. І навіть тоді майте інше джерело ентропії».

Bitcoin Twitter не сприйняв це спокійно.

«Лол, тепер навіть не можна кидати кістки», — написав один користувач. «Самозберігання закінчилося...» Інший запитав, чи варто йому найняти когось із хворобою Паркінсона, щоб кидати їх. (Негарно.)

Ймовірно, най<а class="sc-adb616fe-0 bJsyml" href="https://x.com/sharpone74/status/2083079857932816507?s=20" rel="nofollow external noopener" target="_blank">корисніша відповідь надійшла з арифметикою. Розробник Джастін Шарп порахував, скільки саме коштує вам погана кістка:

«Надмірно. Ідеальний d6 дає 2,585 біта за кидок. Помітно зміщена кістка, наприклад, з однією гранню, що випадає у 20% випадків замість 16,7%, все одно дає близько 2,55 біта. За 99 кидків це різниця між ~256 бітами та ~252 бітами ентропії».

Чотири біти з 256. Це вся ціна за явно несправедливу кістку.

Дашджр не помиляється, що дешеві кістки мають помітне зміщення — литі піпси видаляють трохи різну кількість пластику з кожної грані, саме тому казино використовують точні кістки із заповненими піпсами. Він правий щодо фізики, але помиляється щодо ставок. Втрата чотирьох бітів із 256 залишає вам 252. Баг Coldcard залишив користувачам 40.

Однак у його пораді прихований гостріший аргумент, і він не про виробничі допуски. Він про те, щоб не довіряти жодному єдиному джерелу. Провал Coldcard полягав не в тому, що його ентропія була трохи зміщена, а в тому, що один компонент мовчки перестав сприяти, і ніхто цього не помітив.

Що з цим робити

Якщо ви згенерували сід на ураженому Coldcard без кидків кісток (справді) або без надійної BIP-39 парольної фрази, цей сід скомпрометований.

Оновіть прошивку, згенеруйте новий сід, перевірте відбиток, надішліть тестову транзакцію, а потім перемістіть усе. У рекомендаціях Coinkite це розглядається модель за моделлю. Експортовані сіди несуть ваду з собою — перенесення поганого сіда в інший гаманець нічого не вирішує.

Для всіх інших висновок не в тому, що апаратні гаманці зламані або що гральні кістки є пасткою.

Справа в тому, що «випадковість» — це твердження, і твердження потребують перевірки. Вихідний код Coldcard був публічним весь цей час. Апаратний генератор випадкових чисел був прямо там, у бінарному файлі. Рев'юери підтвердили, що він існує, але ніколи не підтвердили, що генератор сидів і фактично викликав його.

Вісім років аудитів дивилися на правильний код. Ніхто не перевірив, чи він виконується.