小 CRT 指数非平衡 RSA 的密码分析论文分析

前言

第一次认真看英文论文,也是第一次看论文。 这篇是 NSSCTF 中 Crypto 题的出题论文,题目非常简单,但是零解() 后来在 Destog3 迎新赛的压轴题又看到了几乎一样的题,照着 NSSCTF 的 wp 改了下参数中跑出来了,既然在短时间内能碰见两次,也是缘分,就读读罢。

论文翻译

引言

论文中写到 (这个我没见过),然后 ,再然后由CRT给出 。 为了加速 RSA 的解密,有人想用小解密指数 ,然而 Wiener 先生指出 时可以在多项式时间内爆破出来。 虽然不能使用小解密指数 ,但还有一个方法,就是计算 是比较小的,这样一个 称为小CRT指数。为了对消息 进行签名,可以计算 ,在之前,由于 看起来是比较大的,所以也没法攻击(意思应该就是现在可以了)。 攻破这个系统的最优的算法的时间复杂度在 ,同时有趣的是, 不平衡时往往会降低 RSA 的安全性。 令 ,当满足 时可以在 复杂度内分解 ,显然,这个方法只能在 时有效。 关键部分来了,这里说到,文章中给出了一种构造任意维度的格的方法来将条件提升到 ,这个 是一个小错误的意思(我也不知道干嘛的)。因此只要 ,这个方法就是有效的,当 时是黄金比例的共轭(这一段我又不知道在干嘛了)。

准备工作

记模 环为 ,整数模 乘法群为

真相1(原文就叫Fact 1,随便翻译意思一下) 为一个由 张成的格,那么 -reduction 算法可以在多项式时间内输出一个以 为基的格且这组基满足

用 CRT 生成 Key

一个模 的方法

同余式改写等式过程如下:

下面假设 不整除 ,否则右式是 的倍数然后我们可以获得更强的结果(又是奇怪的翻译),等下再讨论这个。 此时有多项式

且该多项式有一根 构造时我们有 ,又 ,就有

定义两个上界 ,则模二元多项式方程 有一个小根 满足 ,这个模方程可以用 Howgrave_Grahm 定理转变为一个整数上的方程。

真相2 为一个至多 个单项式的和的多项式,假定 ( 为正整数), 。若 ,则 在整数上成立。

用格约化算法可以找到一个小欧里几得范数的多项式 ,第一个方法是构造一个二维的格,这时高斯约化算法可以找到一个最短向量。 我们选择 ,然后我们使用同样含根 的辅助多项式 ,因为 的倍数。 因此, 的每个整数线性组合都有根 。 此时构造一个由多项式 的系数向量张成的格 。这些系数向量是如下 格基矩阵 的行向量

然后找到一个向量 使其欧里几得范数小于 ,这个向量可以被转换成一个满足真相2的多项式

引理3 满足

有一个最小向量 满足 证明 由 Minkowski 定理,…呃先不说这个,能用就行(逃

通过引理3,我们知道,对每个固定的 ,条件 有适当的模量 (这里我感觉不应该是这么翻译,后面再改)。 假定我们通过格约化找到了一个 中的向量 ,其范数小于 ,令 为多项式 的系数向量,应用真相2,我们知道 在整数上有一根 ,下一个定理将表明这个根可以很容易被找到。

引理4 的最短向量且满足

证明

总结如下结论就有如下定理:

定理5 给定一个 RSA 公钥对 ,令

可以在时间 内被分解。 证明 还是略(

在之前的分析中,我们假设 不整除 ,特殊情况下若 ( ),我们得到了类似于以下更强结果之前的推理(百度翻译的)

定理6 给定一个RSA公钥对,令

可以在时间 内被分解。 证明 又双叒叕是略(

有趣的是,在定理 6 中选择 会有一个界 ,这与 Wiener 的界差不多。

将界提升到

这里将界提升到 。 上面我们使用真相2的时候选择 ,现在一般化方法到任意 。 定义 移位多项式(这个也是百度翻译)

注意到,每个多项式 的线性组合都有零点 。 确定一个格维数 ,然后用 的系数向量来构造一个 维格 ,其中 。参数 的函数且须进行优化。 比如选取 ,格 由如下行向量张成

注意到,之前的 和这里的 是一样的。 为了满足真相2,我们一个满足范数小于 系数向量 ,如下引理给出了一个找这样一个向量的条件

引理7 对每个确定的 ,令 满足

然后用 LLL 算法可以在 中找到一个向量 满足范数小于 证明 略(

现在我们可以用上面的引理7真相2结合来构造一个次数为的双变量多项式 ,该多项式最多由 个单项式组成,有一根 ,现在问题来到如何提取根 。 与引理4类似,等下写这

引理8 ,多项式 有一根 满足 ,令 中范数小于 的向量( 为项式 的系数向量),然后多项式 一定整除 ,我们就可以通过在 上分解 找到

证明 略(

总结这些结论,就有如下定理:

定理9 给定一个 RSA 公钥对 ,令

其中对于适当大的 (啥叫适当大), 任意小,则我们可以在 确定的时间多项式内分解 证明 略(

一个模 的方法

好像没啥用???不写了

方法间的比较

懒得写了(逃

实现

Section3

#!sage
def attack(N, e, beta, delta):
    N = int(N)
    e = int(e)
    if 3*beta+2*delta > 1-log(4, N):
        print('[-] Attack failed')
        return None
    else:
        X = int(pow(N, delta))
        Y = int(pow(N, (beta+delta)))
        Bp = matrix(ZZ, [[N*X, 0], [e*X, -Y]])

        print('[+] LLL reduction...')
        sv = Bp.LLL()[0]

        c = sv*Bp ^ -1
        c1 = -abs(c[0])     # k
        c2 = abs(c[1])      # q*dp
        q = abs((e*c2+c1*N)//(c1+1))
        p = N//q
        print('[+] Attack successed')
        print('[+] p = {}'.format(p))
        print('[+] q = {}'.format(q))
        return p, q


if __name__ == '__main__':
    # from random import *

    # qbits = 900
    # pbits = 3138
    # dpbits = 66

    # print('[+] Generating parameters...')
    # p = random_prime(2 ^ pbits)
    # q = random_prime(2 ^ qbits)
    # dp = random_prime(2 ^ dpbits)

    # while True:
    #     d = (p - 1) * (randint(1 << 895, 1 << 905)) + dp

    #     if GCD(d, (p - 1) * (q - 1)) == 1:
    #         break

    # e = pow(d, -1, (p - 1) * (q - 1))
    # N = p * q
    # Nbits = int(N).bit_length()
    # beta = qbits/Nbits
    # delta = dpbits/Nbits

    # print('[+] N = {}'.format(N))
    # print('[+] e = {}'.format(e))
    # print('[+] beta = {}'.format(beta))
    # print('[+] delta = {}'.format(delta))
    N = 634629908805216799355967956917035397016752766546070169887547308032924761760891699780399214796824214567267154390070522978483366198289411019582748412313710079216359358255867558259121819712947017660972562997658767364245468900343296627500215831311492976020519937654664907394551244233281196085084301881491720946011495516095312100438461444736650645875530160635314476776379821792685906378511085849924665878291761636238890281686290340422138558891124650561389417569572198766305774737557276999432569512459279457704718190818264594575715474945778743504600307881900481338218715405869829242732728780155929040869667117191128487515003629576385308251284254186650906711925117856043812344169291478611645877809590138625462171489233257786403238243625811812424843820945935661305236547254826569192218598933115538295435575896652227458056744204696170806637821332028265957534034435423213071725773547809761130059315592010070432661283749890121832768362711638162670468266766356808625866527581349441814512302739394082651200775637526523353517769267014266507198162521714133402947845712189448974860772495360651769766890958881349140536387282266034095164827944286428551415655867359896643466364963634800962833486281066681776967479689689507887525855059
    e = 222449729494346666756992460607761795081627331408633195158207067801306565329147681510898658030387508242070227143765893175513890166451777866451978064721778354202341750518999213529606354327894502393449664534948211789294499720405305147950904692085956769722064799513485397504251091294784655828560748848569365844048162038115977508383792426755701835564072424447439243657439872604411430842404037279822672689499520052597008624952368711035998877339177834448061486065262519442303882787242038252503252910254536179033495248788991658972894666551977962064604651051056420818328840034050064445699641044377207422145434076180424757570241966515333860523020888095363402812210233331161015473008660090443148983742164413532587125663777942637230471840611787651285227528953723973668762432241634488008559578459289516131455221246160389933755148774233018937472092674461794244671504900737970090655485320247064558891268178725955788668940079001559604584196657982775865643371046971752485475409807795707098733502124948500727883742572495725371711913411783312068234668792482799143907403909681456144274826087394298716593721198894233809352032011315411881752188433540351647062223660868815946885574427181940281003433351179379410815810916817304563532735699
    beta = 225/1009
    delta = 33/2018
    attack(N, e, beta, delta)
文章作者weyung
文章链接https://weyung.cc/posts/08a53d43/
许可协议CC BY-NC-SA 4.0
上一篇

NTRUEncrypt

下一篇

Linux 学习笔记