Моё внимание привлекли работы американского художника Энди Боча (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 значения найдём ручным перебором, благо вариантов у нас немного и сразу напишем небольшой скрипт, который будет выдавать приватный мини-ключ.
#!/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
Автор: pumpdump