Jane Street 定期发布挑战,这次彻底吸引了作者,使其花了一个月时间解决。这篇概述介绍如何用固执和睡眠不足来破解,内容偏技术。挑战要求分析一个 ASIC(Application-Specific Integrated-Circuit,专用集成电路),即通常所说的计算机芯片。
正文
Jane Street 定期发布挑战,这次彻底把我拖进了一个长达一个月的兔子洞。这篇文章概述了我如何用固执和睡眠不足解决了它。
挑战要求解析一个 ASIC(专用集成电路)的 GDS 文件,逆向工程出它的功能,里面可能藏着一个密码。挑战分两部分:热身题给了更多信息(包括芯片的实际设计),真正的谜题则只有文件和一个“祝你好运”。
文件里有什么?
我直接开始翻文件。里面看到了“clk”(时钟)、“rst”(复位)、“VGND”(地电压)和“VPWR”(电源电压)等熟悉词汇,还有一堆以 sky130_fd_sc_hd__ 开头、后面跟着像“or”、“not”之类逻辑元件名称的东西。
我用 Python 的 gdstk 库读取文件,发现热身题有 27 个元件。主谜题还有一个 VCD 文件,看起来是仿真输入或输出。我在里面看到一些可疑条目,像 ASCII 字符。写了个小程序运行后,输出是“TRY AGAIN”。原来电路里藏着信息!
分心与浪费时间
我花了好几天自己建电路仿真器、写硬件描述语言解析器、测试工具,甚至写了个 GDS 查看器,最后都放弃了。这部分可以跳过。
专注
Jane Street 博客指向了一个方便的 GDS 查看器。我仔细查看文件,大致标注了哪些是输入,后来通过文件中导线的位置确认了。因为这是热身题,我可以对比已知信息和看到的内容。
这些文件有不同“层”,像 3D 打印机的指令。我尝试提取右上角的 Jane Street 标志,结果提取了除它之外的所有东西。
后来我发现库能把元件导出为 SVG,里面包含描述元件部分的文本。这很关键,因为我可以利用这些信息找出哪些是输入输出。
真正阅读元件文档
我找到了 sky130 的官方文档。它包含了元件的功能描述,比如“and”是“与门”,而“o21bai”则复杂得多。利用文档信息和 SVG 标签,我可以把特定几何形状映射到电路元件的输入输出。我运气很好,库能检查两个元件在 2D 空间是否重叠,而且标签正好以中心点对齐,效果比预期好得多。
构建电路图
现在我可以从 GDS 文件提取电路了。这东西有 1000 条路径和近 17000 个多边形。我需要找到相邻层上重叠的“接触”元件。算法很烂但能用。我还把相连的导线段合并成一根导线。
花了好几天调试,我终于能把网络转换成 Verilog 硬件描述语言,运行基本仿真。我手动画出了连接图,最终理解了热身题的主要组件:两个移位寄存器、一个加法器和一个比较器。比较器名为 comparitor496,所以输入需要总和为 496。经过努力,仿真成功了。
真正的谜题
真正的谜题有更多元件类型(81 种对 20 种)和更多数量(近 10000 对 1000)。我快速调整了热身题的脚本,但提取电路需要近一分钟。我优化了导线段收集步骤,速度提升了 100 倍(从 3.4 秒降到 0.03 秒),但找连接组件仍需近一分钟。
我手动从文档复制了约 40 种新元件的实现。之后我构建并运行了仿真,但没成功。
有 Bug 吗?
我重新启用验证,发现仿真中有一根未驱动的导线。视觉检查确认代码正确识别了一根只连接两个输入引脚的导线。更奇怪的是,电路相邻引脚上有一个既不是输入也不是输出的连接。我向 Jane Street 报告了这个问题。第二天收到邮件确认我是对的,但这个 bug 不影响挑战结果。
鸟瞰视角
我花了很多时间映射子电路和连接导线。我发现通向“成功”信号的导线有 6 根,其中两根在特定时钟周期后变高,所以实际上只需处理 4 根。最左边的子电路像信号发生器,馈入其他部分。密码可能藏在元件结构里?结合来看,输出在 120 或 121 个时钟周期后变高,与提供的波形匹配。
我让每个子电路单独仿真成功,但连接成整体电路后,花了两三天才让整体仿真工作。原来我忘了设置“复位”引脚。修复后,我看到了“TRY AGAIN”。我还发现不同输入会输出不同信息:错误答案是“TRY AGAIN”,全 0 是“EMPTY SKY”,全 1 是“BIG BANG”。
停滞期
我找到了输入是 120 位,但不知道如何继续。穷举所有输入是不可能的。
逐线分析
我直接回溯输出导线,但输入太复杂。我想到“反向运行仿真”:我知道第 120 步想要的输出,也知道电路从全零开始。这像递推关系,理论上可解。我聚焦于移位寄存器,它依赖于之前的值,可能需要约束求解器。
用电子表格写 Verilog
我用电子表格写 Verilog,然后输入仿真电路。电子表格实际上是复杂的约束求解器。这个方法对两根导线有效,但整体上不够强大,因为它依赖我肉眼观察和手动调整。
约束求解器
我用了 z3 工具。它很神奇:告诉它“这根导线不能为低”或“这根导线在第 120 步必须为高”,它就能找到解决方案或告诉你不可行。我手动把电路翻译成 z3 约束,逐个处理需要的导线。大约有 24 根导线需要同时为高,我通过求解器和猜测,相对容易地解决了 22 根。
答案
我把所有约束合并成一个脚本,调试后得到了解决方案。加载到仿真器中运行,答案是 (* TWO STARS *)。我发邮件给 Jane Street,第二天早上得到了确认。
评论
讨论气氛以祝贺和好奇为主,分歧集中在挑战的实际价值与工具选择上:多数人赞赏作者的逆向工程能力,少数人质疑 Jane Street 的动机或调侃其商业意图,同时有技术爱好者深入探讨了自动化方案。
祝贺作者完成挑战,欣赏其执着精神
- 评论者普遍对作者独立完成逆向工程表示敬佩,认为这是对技术热情和耐心的证明,甚至有人直接表达“喜欢这个人”。(高赞) > 太酷了,能看到有人如此热爱挑战。(@motoxpro)
猜测 Jane Street 设置挑战的动机
- 多数人认为这与高频交易相关,通过逆向工程芯片来发现延迟优化或硬件缺陷,但也有评论者好奇是否存在更隐蔽的应用场景,比如交易策略的硬件级实现。(较多人) > 好奇 Jane Street 设置这种挑战的实际用途……最明显的答案是交易更贴近硬件,但也许还有不那么明显的应用。(@gyanchawdhary)
讨论自动化工具与 LLM 的潜力
- 部分评论者认为未来可以用 LLM 或开源工具(如 Degate)自动完成芯片逆向,甚至直接生成仿真器,但作者本人表示用 AI 解决后“没学到太多”。(少数人) > 我好奇 LLM 能在这类任务上走多远。未来如果能直接给芯片拍照,让 LLM 生成仿真器,那就太酷了。(@charcircuit)
有价值的补充
- 有评论者分享了用 KLayout Python API 解析 GDS 文件提取网表的方法,并提到 yosys 的断言检查功能可用于验证。
- 另一评论者提供了将电路转换为 Z3 约束方程的详细笔记,并附上 GitHub Gist 链接。
- 有人指出 GDS 格式全称是 Graphic Data System II,源自 1970 年代的 Calma 公司,为技术背景的读者补充了历史知识。