Моё внимание привлекли работы американского художника Энди Боча (Andy Bauch) в виде картин из блоков Lego. В них, по заявлению автора, зашифрованы приватных ключи к кошелькам разных криптовалют, в том числе и биткоина. Стоимость активов и адреса кошельков находятся на странице newmoney.andybauch.com

Вызов принят

Для примера возьмём наиболее наглядную картину Bitcoin Initially Valued at $60.



В ней зашифрован приватный ключ к адресу 1HvEJG5JR84MVpncXcDVBqx65uY5odr6fP на котором находилось ~0.14 биткоина (~$1200).

На blockchain.info мы видим текстовую подсказку «Radix 6», запоминаем её и идём дальше.

Зорким взглядом исследуем и замечаем следующие моменты:

  • Квадраты бывают только 6 цветов, а значит перед нами 6-символьная кодировка (radix 6)
  • Ровные вертикальные линии через каждых 3 квадрата, делящие их на блоки, начиная с первого
  • Паттерн идёт слева направо, состоит из 30 блоков и затем повторяется

6 символов явно недостаточно, чтобы закодировать в 270 символах классический WIF или HEX приватный ключ, однако для приватного ключа существует формат мини, он состоит как раз из 30 символов и работает по принципу brainwallet'а — sha256(«mini_private_key»).

Особенностью данного формата является обязательное начало с буквы S, пример — S6c56bnXQiBjk9mqSYE7ykVQ7NzrRy.



В последний раз посмотрим на картину и выпишем все цвета квадратов в первых 30 блоках, за исключением синих вертикальных разделителей, для удобства обозначив цвета одной буквой: Y = Yellow, G = Gray, R = Red, B = Blue, L = Light Blue, D = Dark Green

Получится:

'YGR', 'LBY', 'LBL', 'YBR', 'LGY', 'YYY', 'LBY', 'YBL', 'YDY', 'LGY', 'GRG', 'GRR', 'GDR', 'LBD', 'LBY', 'YDL', 'LBG', 'YYB', 'LYY', 'GRL', 'YYD', 'YGR', 'YDR', 'LBD', 'GYD', 'YRR', 'GRY', 'GYD', 'GRR', 'LGG'

Мы знаем, что первой буквой идёт S, а кодирование у нас 6-числовое, поэтому необходимо найти какой цвет за какую цифру отвечает.

Для числовых преобразований установим пакет baseconvert

pip install baseconvert

Сконвертируем букву S в шестнадцатеричную кодировку

echo -n "S" | od -A n -t x1

53

Полученный результат с помощью другой утилиты преобразуем в 6-числовую кодировку

python3 -m baseconvert --string true --number 53 --input-base 16 --output-base 6

215

Из этого делаем вывод, что

Y = 2
G = 1
R = 5

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

solve.py
#!/usr/bin/python3
import baseconvert
values = ['YGR', 'LBY', 'LBL', 'YBR', 'LGY', 'YYY', 'LBY', 'YBL', 'YDY', 'LGY', 'GRG', 'GRR', 'GDR', 'LBD', 'LBY', 'YDL', 'LBG', 'YYB', 'LYY', 'GRL', 'YYD', 'YGR', 'YDR', 'LBD', 'GYD', 'YRR', 'GRY', 'GYD', 'GRR', 'LGG']
replace = {'Y':'2', 'G':'1', 'R':'5', 'B':'0', 'L':'3', 'D':'4'} #подставляем значения здесь
key = []
base = 6

for char in values:
    for i, j in replace.items():
        char = char.replace(i, j)
    v = baseconvert.base(char, base, 16, string=True)
    v = bytearray.fromhex(v).decode('ascii')
    key.append(v)

print(''.join(key))


Запускаем…

python3 solve.py

SnoMtVnKbtCGApncmTzEXSep4kD4Gs

По спецификации мини приватного ключа, мы можем проверить его валидность, добавив знак вопроса в конец и захешировав sha256. Если первые два символа являются нулями, то ключ считается валидным.

echo -n SnoMtVnKbtCGApncmTzEXSep4kD4Gs? | sha256sum

00edc14de4c175a2a8ccb213e4d5deee738782a8213c25328a7b035d3c728866

Нам повезло, приватный ключ валиден.

Теперь идём на www.bitaddress.org (так быстрее) и вставляем получившийся приватный ключ во вкладку Wallet Details.

Забираем приватный ключ в формате WIF (5KfNkSeQwNgjHr7cRErzDmq5XdUm8qc94YM3iEN5YaMYoA2UGky) и импортируем его в биткоин-клиент.



Так, что тут у нас?..



Упс… Кто-то оказался шустрее и забрал приз. Однако удовлетворение от решённой задачи всё таки было получено.
UPD: $20 и $30 забрал SopaXT

Комментарии (7)


  1. Anton23
    26.03.2018 12:11

    Сложно, в чем прикол в конце?


    1. Eugeny1987
      26.03.2018 12:16

      похоже перевод на другой кошелек


      1. mammuthus
        26.03.2018 12:36

        Что, в общем, логично, квест был опубликован 23-го.


        1. pumpdump Автор
          26.03.2018 14:48

          На самом деле квест был опубликован ещё раньше, но СМИ подхватили это 23-24 числа. Я начал решать задачу когда ещё не было транзакций ни на одном из кошельков.



  1. Zagrebelion
    26.03.2018 13:00

    Не очень понятно про "Упс.." в конце, если транзакцию-перевод с кошелька видно на blockhain.info, ссылка есть в статье.


    1. pumpdump Автор
      26.03.2018 14:49

      Спасибо за комментарий, я поправил статью. Транзакцию совершил не я, поэтому и «Упс».