Jane Streetが出した「ASICを逆向きに解析できるか」というチャレンジに、ある開発者がほぼ1か月つき合わされた、という話だ。元記事は、その人がどうやってGDSファイルやVCDファイルを読み解き、回路図に起こし、最終的に解答へ近づいていったかを、かなり率直に振り返っている。面白いのは、単なる攻略記ではなく、寄り道と遠回りそのものが記事の主題になっていることだと思う。技術的にはかなり濃いが、読み方次第では「人は難題に出会うと、どこまで自作したくなるのか」を見る記事でもある。
元記事の筆者は、Jane Streetが定期的に出すチャレンジのひとつに引っかかり、1か月ほど没頭したという。課題は、ASIC、つまり用途特化の集積回路を逆解析して、その動作を理解することだった。最初に渡されるのはGDSファイルで、回路の物理配置を表す設計データらしい。筆者はまずファイルを覗き込み、clk、rst、VGND、VPWRのような見慣れた文字列を探し、sky130_fd_sc_hd__で始まるセル名から、論理ゲートの断片を拾い始める。Pythonのgdstkで読み込むと、少なくともウォームアップ用のパズルには27個の要素があることが分かった。
本番側ではVCDファイルも扱う。これはシミュレーションの波形情報のようなテキストファイルで、筆者はそこからASCIIっぽい断片を見つけ、Cプログラムで試したところTRY AGAINという出力を得た。回路の中にメッセージが埋め込まれていると気づいた瞬間だ。その後、筆者は勢いで自作の回路シミュレータや独自の解析環境まで作り始めるが、これはかなり遠回りだったと自分でも認めている。結局その大半は捨て、Jane Streetが案内していたGDS viewerを使って目視確認に戻った。
ここから先は、まずGDSのレイヤー構造を理解し、SVG出力のラベルを頼りに入出力を特定し、回路要素同士が2次元で重なっているかを見て配線をグラフ化していく流れになる。ウォームアップ問題では、2つのシフトレジスタ、加算器、そしてcomparitor496という名前の比較器を見つけ、入力の合計が496になるようなビット列を探した。最終的にはシミュレーションを動かせるところまで持っていき、ウォームアップを解いたことで、本題にも手が届く見込みが立ったという。
本番のパズルはさらに大規模だった。部品タイプは約81種類、部品数はほぼ1万個。筆者はウォームアップで作った処理を流用しつつ、足りない40種類ほどのコンポーネントをドキュメントサイトから手で移植した。配線の収集部分を100倍速くし、ワイヤに別名を付けられるようにし、ようやく本番回路のシミュレーションを回したが、最初はうまく動かない。検証を切ったまま進めていたため、再びバグ取りに戻る必要があった、というところで元記事の抜粋は終わっている。
この記事でいちばん印象に残るのは、筆者が自分で道具を作るたびに、少しずつ本筋から外れていることだ。しかも本人はそれをかなり楽しんでいる。sqlite3を使った回路シミュレータ、独自言語のパーサ、ハーネス、波形ビューア、GDSビューアまで作ってしまう。これは技術的な腕前の証明でもあるが、同時に「難しい問題に出会うと、まず環境から作りたくなる人」の姿でもあると思う。実務では往々にして逆で、既存ツールを使って早く仮説検証したほうが勝つ。だが、この種の逆解析チャレンジでは、道具を理解すること自体が目的に近づく行為でもある。どこまで自作し、どこで踏みとどまるか。その境界が、この文章のいちばん人間らしいところだった。
ASICの逆解析というと、回路図がそのまま与えられると思いがちだが、実際にはそうではない。渡されるGDSは、レイヤーやセルの配置を含む物理設計のデータで、そこから論理的なつながりを復元しなければならない。元記事では、ラベルの中心点が配線と重なっていることを利用してI/Oを推定したり、レイヤー同士が重なっている部分をつなぎ合わせてワイヤをまとめたりしている。ここが面白いのは、単に「ファイルを解析した」ではなく、物理設計の癖を手がかりにして、回路の意味へ橋をかけている点だと思う。ソフトウェアの世界に慣れた人ほど、こういう「実体のあるデータ構造」を読む感覚は新鮮ではないか。
ウォームアップ問題を先に解けたのは大きい。シフトレジスタ、加算器、比較器という構成を見つけ、comparitor496という名前から「合計が496になる入力を作ればいい」と見抜く流れは、かなり素直だが、そこで終わらせずに本番の道具立てに再利用している。ここがチャレンジ設計としてうまいところで、簡単な方で解析の勘所を学ばせ、同じ手順を拡張して本番に持ち込ませる。筆者も、ウォームアップで得た理解がなければ本番は無理だったと示唆している。難問は往々にして、答えそのものより「何を観測し、どこまで抽象化するか」を試してくる。この記事は、その練習問題が本当に効いた例として読める。
Jane Streetのチャレンジは、単純なコーディング問題とは違う。回路、ファイル形式、標準セル、シミュレーション、グラフ化といった複数の層をまたいで、最後は人間の目で整合性を確認する。元記事の筆者は、その面倒さをほとんど隠さずに書いていて、むしろ「難しいことを難しいまま進める」執念が前面に出ている。これは好みが分かれるが、私はかなり意味があると思う。というのも、こうしたチャレンジは単に解けるかどうかではなく、未知の形式をどれだけ自分の手で可視化できるかを測っているからだ。会社の採用広報としても、趣味の技術記事としても、かなり強い題材だろう。
元記事は、結果だけを誇る記事ではない。むしろ「もっと楽なやり方があったのに、ひたすら回り道した」と自分で書くことで、解いた事実よりも、解くまでの思考の癖を見せている。これが読後感を軽くしている。失敗や寄り道が多いのに、文章が嫌味にならない。そこには、難問に対して必要以上に肩肘を張らず、でも最後まで手を動かす粘りがある。私は、こういう人が本当に強いのだと思う。速く解くことより、壊れたときに立て直せることのほうが、未知の問題ではずっと大事だからだ。
参考: On solving the Jane Street Reverse Engineering Challenge