写点什么

提前 15 年!比利时程序员攻克麻省著名加密难题

  • 2019-05-17
  • 本文字数:4059 字

    阅读完需:约 13 分钟

提前15年!比利时程序员攻克麻省著名加密难题

该加密难题由麻省理工学院实验室的 Ron Rivest 教授,也就是著名的 RSA 公钥加密算法负责人提出,并预计需要 35 年时间才能得到答案,而比利时的一名程序员近日攻克了该难题,比预计时间提前了 15 年。


对于比利时人来说,2019 年 4 月是个好月份。相比于专业的比利时自行车手 Victor Campanaerts 打破一小时世界记录,独自跑出 55 公里(实际是 55,089 米)的好成绩之外,专业的比利时程序员 Bernard Fabrot 攻克了更具挑战性的难关,破解了一道 1999 年设置的计算难题,该题由麻省理工的 Ron Rivest 教授,也就是著名的 RSA 公钥加密算法负责人,并预计需要 35 年的运算时间才能得到答案,没想到 Bernard Fabrot 提前 15 年就破解了该难题,并且仅用了 3.5 年的运算时间,超出 Rivest 预期的速度 10 倍。

原题概述

1994 年 4 月,在麻省理工学院计算机科学实验室成立 35 周年的庆祝活动上,时任实验室主任的 Michael Dertouzos 设计了一个“创新成果时间胶囊“,这其中囊括了一系列计算机领军人物的创新成果,准备在 35 年后再取出作为实验室成立 70 周年的献礼。


为了保证刚好在 35 年之后取出,Ron Rivest 教授为时间胶囊设计了一把“密码锁“,也就是一道密码学难题。考虑到未来计算机算力的提升速度,还特意加大了难度,使得该难题至少需要 35 年时间才能破解。


该难题是著名的“时锁问题”,即一个耗时的计算,只能通过调整算法或构建更快的计算机硬件来实现加速。时锁问题很有趣也很重要,因为其不能简单的把问题分解成小块,让更多的计算机来同时运行。


并且,时锁难题存在固有时序,要求在实现算法的大量循环中,循环的每次迭代输入只能读取前一次迭代的输出来得到。这种想法让每个人处于同一境地:即使是世界上最大、最富有、最有能力的云计算公司,其所有的服务器、CPU 及 CPU 核也无法让你一定走向成功。


业内其他密码学专家清楚麻省理工学院的技术能力,因此也没有在此上浪费太多时间,因此这道难题尘封了足足 20 年之久。

难点一:可平行化

大部分问题可以分成小的部分,至少其中有些部分可以有所重叠。比如,如果要求数清非洲的大象数量,你可以飞到好望角,然后曲折往北直到埃及的亚历山大,沿途注意所有的大象。


但这是一个可以平行的任务,因为可以忽略一些复杂情况,比如已经数过的大象穿越了国界线,比如赞比亚的大象数可能和其邻居安哥拉的大象数同时进行统计。


简单讲,每个国家可以分配一个人员来统计数目,不用担心各自开始的顺序——在最大的国家中,可以把任务再次细分,比如每个省指派一个人,以此类推。

难点二:长而曲折的关键路径

Ron Rivest 在 1999 设置的难题没法像数大象那样把任务进行分解。本质上来说,这个难题最初设计是通过一个需要运行长达 35 年迭代的紧凑循环来实现,它取决于计算能力在这个周期内能怎样改进。


Rivest 甚至做了一个年度更新方案,假定解题者能每年某个时刻可以暂停计算,来把计算机更新到当前市面上最大最快的计算机。


2015 年,Bernard Fabrot 才开始启动运行该项目,从启动到结束共花费 3.5 年时间,从而提前 15 年结束了该项工作。

解题思路

以下是 Rivest 设置的难题:


该问题是针对特定的 t 和 n,计算 2^(2^t) (模 n)。n 是两个大质数的乘积,t 的选择可以用来设置难题希望的难度级别。


简单解释下, 2^t  是 Ron Rivest 用以表达 2 的 t 次方的文本标识,即 2t,  mod n 表示取余, 即模运算,也就是除以 n 剩余的部分。


比如,6 是 3 的 2 倍, 因此 6 / 3 = 2 余 0 ;但是如果用 7 除以 3,则得 2 余 1,因此 7 / 3 = 2 余 1。


Rivest 设置 t 为正好小于 80 万亿的一个数,n 为一个 2048 位的二进制数(512 位的 16 进制数或 256 字节),如:


t = 79,685,186,856,218n = 0x32052C40E056ED2C9141FC76C060FA685F60C45095EB69930CBE4B2C81B19C33      55FA9149150D7082284CC3903C12B98DACC7E2FC7C16907F8E946AEFB5FD1240      77E05D944B6738334E71A9BD37E1C08F2DF3D119EB95182B0F3E87B341A217BB      433F2114FEAE1555CFB974DA3D56D4AD7C1D83FD789F34143CDD3D502C104639      EE68DDC8D56D5BC6EAAC7ED16C1F5FF02159B5D52AF94979A18A60EFCABE109E      E2E90C14B6FC1225B754644D989FC1B9F87552B255997CEE22429CF49E3599DA      4B3F6D5535B83072A1D4357AE1ABFF8455B80C438EC33A5C7C6CB1ACE22C62FE      67B3040029B3C37E5EC682363A77D42FB223E194878E146D06739EC4E598A9A1
复制代码


其思路就是这里没有计算最终结果的捷径,除非能知道两个大质数,根据其乘积得到 n 。


Ron Rivest 和现在的 Bernard Fabrot,知道 n 的两个质数,我们称其为 p 和 q 具体是多少 ,但其他人都不知道。


注:Rivest 设计了一个方法,这样可以提前计算出答案,用以确定挑战者是否真正解决了该难题。


因此在不知道 p 和 q 的情况下,要解决这道难题,需要一直不停的进行乘积,直到最后得到计算结果。


每个循环里的乘积都需要用到上次的输出作为本次的输入,所以无法在多台电脑,多 CPU 或 CPU 核间进行计算工作的划分。

代码实现

Bernard Fabrot 尝试使用 Python 来处理该问题。在 Python 中, 操作符 ** 是使数字自乘为指数的幂,即幂运算,% 是找到倍除后的余数,即取模,并假设函数 seq(n) 从数字 1,2,3,一直循环到 n。


   exp = 2 ** 79685186856218   val = 2 ** exp   val = val % 0x32052...98A9A1
复制代码


除了第一行的 exp 是个接近 20 万亿位的 10 进制数字,其余都比较简单可控。因此需要 10 兆字节来存储这个值,然后在代码第二行,我们要得到 2 的幂次方,而指数就是这个已经大的惊人的数。


如果要用重复乘积来实现幂运算  ,2n 需要 n 次循环,做连续乘以 2 的操作 n 次。从下面可以看出这种计算方法的麻烦之处:


   exp = 1   for i in seq(796851868562180): exp = exp * 2   val = 1   for i in seq(exp): val = val * 2   val = val % 0x32052...98A9A1
复制代码


第一个 for 循环中,循环次数为 80 万亿。这还只是为了得到这个超级大的指数,用以在第二个 for 循环中进行真正的计算!

平方后求幂

幸好,有个巧办法来做这个计算。


在循环表达式 val = val * 2 中 , 循环变量的步进是 1,从而每次循环依次得到 2^1, 2^2, 2^3, 2^4, 2^5 等。


但如果不做倍乘而做平方计算,如下所示:


   val = val * val
复制代码


这种方式可以让指数每次翻倍,而不只是加 1,则依次循环得到 2^1, 2^2, 2^4, 2^8, 2^16 等。


这样就可以用 t 次循环得到 2^(2^t) ,而不像之前需要 2^t 次循环,如下所示:


   val =  2   for i in seq(796851868562180-1): val = val * val   # Now find the remainder   val = val % 0x32052...98A9A1
复制代码

数值太大

即使现在总共有 80 万亿次循环,而不是更大的 2^80,000,000,这段代码仍不够好,因为该处理过程中数值 val 太大了。


即使在第二行做一部分循环,也可以看到每次的迭代中的每一步所耗费的时间几乎会成倍增加,因为每次循环要乘的数都比前一次多一倍:


   millisecs | value computed           0 | 2^(2^ 1)           0 | 2^(2^ 2)           0 | 2^(2^ 3)           . . . . . . .           0 | 2^(2^16)           1 | 2^(2^17)           2 | 2^(2^18)           5 | 2^(2^19)          11 | 2^(2^20)          25 | 2^(2^21)          49 | 2^(2^22)          97 | 2^(2^23)         195 | 2^(2^24)         406 | 2^(2^25)         833 | 2^(2^26)        1690 | 2^(2^27)        3513 | 2^(2^28)        7182 | 2^(2^29)       14832 | 2^(2^30)
复制代码


庆幸的是,在模块计算中可以如上最后取余或每步重复取余,因为只有每次循环最后返回的余数需要在下一次乘积中使用到。


因此,可以把计算符 % 放在 for 循环里(在 Python 中,缩进显示了当前循环所在的层级数):


   val =  2   for i in seq(796851868562180-1):      val = val * val      # Calculate the remainder each time round      # inside the loop, not once at the end      val = val % 0x32052...98A9A1
复制代码


余数是固定长度的,在这里,余数不能大于 n-1,假设 n 为 2048 比特,就意味着每次步骤里,都需要 2048 比特的数乘以 2048 比特的数,并对乘积做取余处理,该余数也是 2048 比特。


每次迭代后的累计结果 val 是一个 2048 比特的数字,因此下一个迭代输入也是 2048 比特的数字。循环里的每个操作都要增加相同的时间:


   millisecs | value computed           0 | 2^(2^ 1)           0 | 2^(2^ 2)           0 | 2^(2^ 3)           0 | 2^(2^ 4)           0 | 2^(2^ 5)           0 | 2^(2^ 6)           . . . . . . .           0 | 2^(2^27)           0 | 2^(2^28)           0 | 2^(2^29)           0 | 2^(2^30)
复制代码


在我的 Mac 上,做 1,000,000 次迭代只需要 16 秒,也就是每秒可以做 62,500 次迭代。


按这种速度,需要花费 80,000,000,000,000 / 62,500 秒,也就是 15,000 天或 40 年来完成这个难题。


即便是顶级的 Mac,也许能让 CPU 速度翻倍,计算效率有 4 倍的整体提升,但仍需要 10 年来完成这项工作。


Fabrot 只用了 3.5 年的时间,而且他开始运行时的硬件环境并不如现在,他使用的只是一般商用硬件,这真的是一个了不起的胜利。


根据 Fabrot 的申明,有个做加密货币的新兴公司公开宣称已经用两个月时间使用特殊的现场可编程门阵列(FPGA)解决了该难题。



但尽管其网站上得意地宣称该组织“两个月内解决了该问题”,但这个链接是空的,没有指向任何地方,其可能关联代码的 Github 账号上仍显示“即将提供代码”。


相较而言,Fabrot 默默完成了所有工作。加密专家们表示,攻击只会越来越快,这就是一个重要提醒。


回顾整个过程,算法本身很容易实现。在完成过程中,困难的是需要随时跟踪了解当前进度。与一般程序不一样,该算法没有任何“窍门”,没有精确的计算状态备份供计算机崩溃或开始出现错误时进行恢复,也没有管理良好的备份机制,任何小的故障或断电都会使整个计算过程归于原点。


当然,这里也有挑战,那就是一直不失去信心,继续前行。


感谢 Sophos 研究室的 Alex Bakewell of SophosLabs 对本文撰写提供了帮助


2019-05-17 09:525950

评论

发布
暂无评论
发现更多内容

柏睿数据:以自主可控的智能算力引擎服务数据产业创新发展

新消费日报

新华网专访 | 用友网络:中国企业“出海”要有全球视野 需构建数智化全球人才供应链

用友BIP

人力资源 中企出海

HiveSQL 迁移 FlinkSQL 在快手的实践

Apache Flink

大数据 flink 实时计算

以开放安全底座赋能全球开发者,华为云构筑云原生安全防护体系

华为云开发者联盟

云计算 华为云 华为云开发者联盟 企业号 7 月 PK 榜

华为云云原生数据库,让企业离应用更进一步

新消费日报

超高速稳定!香港虚拟主机助你网站飞一般的速度!

一只扑棱蛾子

香港虚拟主机

如何评价MyBatis-Flex框架

酱紫的小白兔

点云标注的算法优化与性能提升

来自四九城儿

用友iuap:最懂企业级技术,更懂企业级业务

用友BIP

国产替代

24款好用的电脑画图软件推荐,总有一款适合你!

彭宏豪95

效率工具 软件 流程图 画图软件 绘图工具

秒验丨 REST API:手机号码置换接口

MobTech袤博科技

大数据 前端 后端

首个!AI开发者创作激励计划开启,有成长、有收入

飞桨PaddlePaddle

人工智能 百度 paddle 飞桨 百度飞桨

一文详解新一代高效前端构建工具VITE-达观数据

NLP资深玩家

vite 前端构建 es modules

C++ 测试框架 GoogleTest 初学者入门篇

不在线第一只蜗牛

编程 测试框架 C++

IPQ5018 +QCN9074/QCN6122/QCN6102 high-performance IIOT -2.4G/5G/6G-most comprehensive wifi6

wifi6-yiyi

5G wifi6 QCN9074 6G

从大数据到AI,华为云存储加速企业大模型快速应用

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 企业号 7 月 PK 榜

成就数智企业,用友助力中国企业迈向高质量发展

用友BIP

国产替代

华为云MetaStudio全新升级,盘古数字人大模型助力数字人自由

华为云开发者联盟

人工智能 华为云 数字人 华为云开发者联盟 企业号 7 月 PK 榜

问答对话文本数据:解锁智能问答的未来

来自四九城儿

Python源码剖析:深度探索Cpython对象-达观数据

NLP资深玩家

Python CPython 达观数据

基于知识图谱的电影知识问答系统:训练TF-IDF 向量算法和朴素贝叶斯分类器、在 Neo4j 中查询

汀丶人工智能

人工智能 自然语言处理 深度学习 知识图谱 智能问答

ScaleBit 与 NFTScan 达成安全生态合作伙伴关系

NFT Research

安全 NFT\

ChatGPT搭建AI网站实战

快乐非自愿限量之名

网站开发 ChatGPT

语音标注平台:推动语音技术发展的关键支撑

来自四九城儿

ZipZapAI大模型与勇者斗恶龙:探索AVG游戏的无限可能

Ricky

AI Chat ChatGPT

点云标注的标准化与数据共享

来自四九城儿

统一技术底座助力医疗机构数智化转型

用友BIP

数智底座 技术底座

消费品行业全面预算管理领先实践

用友BIP

全面预算

衡阳等保测评中心地址在哪里?电话多少?

行云管家

等保 等级保护 等保测评 衡阳

数据孤岛、系统林立,这些顽疾瓴羊想要全搞定

ToB行业头条

DPO 直接偏好优化:跳过复杂的对抗学习,语言模型本来就会奖励算法

Zilliz

AIGC LLM RLHF

提前15年!比利时程序员攻克麻省著名加密难题_语言 & 开发_Paul Ducklin_InfoQ精选文章