『CTF』AMM 算法详解与应用

admin 2023年4月24日08:41:53评论196 views字数 4833阅读16分6秒阅读模式



点击蓝字 关注我们


日期:2023-04-19
作者:jgk01
介绍:之前在RSA题目中遇到过的e和phi不互素的问题,可以采用AMM开根算法来解决这个问题,本篇来了解有限域上的AMM开根算法。

0x00 前言

去年年末的比赛中遇到过多次AMM开根的题目,这类题目特征还是比较明显,所以学习整理记录一下相应的算法与原理。

『CTF』AMM 算法详解与应用

0x01 AMM算法详解

1.1 开2次方

以开2次方为例我们来看一下AMM开根方法思路。

首先对于2次方式子我们有:

『CTF』AMM 算法详解与应用

『CTF』AMM 算法详解与应用

把上面的p-1的变式代入可得到:

『CTF』AMM 算法详解与应用

对于一个非二次剩余Y

『CTF』AMM 算法详解与应用

此时如果t=1,那么上式为:

『CTF』AMM 算法详解与应用

此时我们两边同乘x在开根得到:

『CTF』AMM 算法详解与应用

此时代入密文c就可以求出明文:

『CTF』AMM 算法详解与应用

所以明文m就等于:

『CTF』AMM 算法详解与应用

举一个简单的例子:

『CTF』AMM 算法详解与应用

这里的2就是明文,4就是密文。

我们继续看⬇️

『CTF』AMM 算法详解与应用

对上式开根,可以得到两种结果:

『CTF』AMM 算法详解与应用

这里的k是为了控制是否引入非二次剩余项,我们开出正根k=0,开出负根k=1,之后不断对x开根,一直到2的指数为0,一共t-1k

『CTF』AMM 算法详解与应用

此时,乘二次剩余x然后两边取平方:

『CTF』AMM 算法详解与应用

和上面一样把c带入就可以求出明文了:

『CTF』AMM 算法详解与应用

『CTF』AMM 算法详解与应用

0x02 例题介绍

2.1 题目

题目是一个组合题,前面的解密步骤就让我们得到了如下信息:

e = 1531793p = 152103631606164757991388657189704366976433537820099034648874538500153362765519668135545276650144504533686483692163171569868971464706026329525740394016509191077550351496973264159350455849525747355370985161471258126994336297660442739951587911017897809328177973473427538782352524239389465259173507406981248869793q = 152103631606164757991388657189704366976433537820099034648874538500153362765519668135545276650144504533686483692163171569868971464706026329525740394016509185464641520736454955410019736330026303289754303711165526821866422766844554206047678337249535003432035470125187072461808523973483360158652600992259609986591n = p * qc = 23129683905221590810931073733257240695491909600600821626110967741991475952367362466435001712032183901737453265086024660692796844392297498997208235843621067335947024294793917437465567235097523891328309930140339168673282959013006525102332444767839426566939309039615858490944730603509080574471734733118066791730903874584695936232044353090855494398794086718463881637739165577843547326511641921822024263267673375341299485422153934060527418515955523844699687688348603999820720218160844840953001023840468960215702467203343095303314120059019184362079713388502293450806476408625709403546751299379519145557188933345613844133126

得到这些信息后,首先我们发现e比较小,按常理有了这些数据应该用常规的rsa解密解出flag了,但是这里你就会发现求d的时候会报错,我们可以发现,e(p-1)是不互素的,(p-1)正好是e的倍数,此时,就符合了我们AMM算法的第二种情况,可以利用AMM算法求解。

2.2 解题思路

解题脚本:

from Crypto.Util.number import *import gmpy2import timeimport randomfrom tqdm import tqdme = 1531793p = 152103631606164757991388657189704366976433537820099034648874538500153362765519668135545276650144504533686483692163171569868971464706026329525740394016509191077550351496973264159350455849525747355370985161471258126994336297660442739951587911017897809328177973473427538782352524239389465259173507406981248869793q = 152103631606164757991388657189704366976433537820099034648874538500153362765519668135545276650144504533686483692163171569868971464706026329525740394016509185464641520736454955410019736330026303289754303711165526821866422766844554206047678337249535003432035470125187072461808523973483360158652600992259609986591n = p * qc = 23129683905221590810931073733257240695491909600600821626110967741991475952367362466435001712032183901737453265086024660692796844392297498997208235843621067335947024294793917437465567235097523891328309930140339168673282959013006525102332444767839426566939309039615858490944730603509080574471734733118066791730903874584695936232044353090855494398794086718463881637739165577843547326511641921822024263267673375341299485422153934060527418515955523844699687688348603999820720218160844840953001023840468960215702467203343095303314120059019184362079713388502293450806476408625709403546751299379519145557188933345613844133126
def AMM(o, r, q): start = time.time()
g = GF(q) o = g(o) p = g(random.randint(1, q)) while p ^ ((q-1) // r) == 1: p = g(random.randint(1, q)) print('[+] Find p:{}'.format(p)) t = 0 s = q - 1 while s % r == 0: t += 1 s = s // r print('[+] Find s:{}, t:{}'.format(s, t)) k = 1 while (k * s + 1) % r != 0: k += 1 alp = (k * s + 1) // r print('[+] Find alp:{}'.format(alp)) a = p ^ (r**(t-1) * s) b = o ^ (r*alp - 1) c = p ^ s h = 1 for i in range(1, t): d = b ^ (r^(t-1-i)) if d == 1: j = 0 else: print('[+] Calculating DLP...') j = - discrete_log(d, a) print('[+] Finish DLP...') b = b * (c^r)^j h = h * c^j c = c^r result = o^alp * h end = time.time() print("Finished in {} seconds.".format(end - start)) print('Find one solution: {}'.format(result)) return result
def onemod(p,r): t=p-2 while pow(t,(p-1) // r,p)==1: t -= 1 return pow(t,(p-1) // r,p)
def solution(p,root,e): g = onemod(p,e) may = set() for i in range(e): may.add(root * pow(g,i,p)%p) return maydef union(x1, x2): a1, m1 = x1 a2, m2 = x2 d = gmpy2.gcd(m1, m2) assert (a2 - a1) % d == 0 p1,p2 = m1 // d,m2 // d _,l1,l2 = gmpy2.gcdext(p1,p2) k = -((a1 - a2) // d) * l1 lcm = gmpy2.lcm(m1,m2) ans = (a1 + k * m1) % lcm return ans,lcm

def excrt(ai,mi): tmp = zip(ai,mi) return reduce(union, tmp)
cp = c % pmp = AMM(cp,e,p)
mps = solution(p,mp,e)for mpp in tqdm(mps): ai = [int(mpp)]] mi =

m = CRT_list(ai,mi) flag = long_to_bytes(m) if b'flag' in flag: print(flag) exit(0)

0x03 后记

AMM开根算法在密码学中还算最近是比较常见的题型,大家有兴趣可以看一些这方面的文章进一步学习一下。

Reference

https://arxiv.org/pdf/1111.4877.pdf
https://clingm.github.io/2022/10/02/AMM-Algorithm/
https://www.anquanke.com/post/id/262634
『CTF』AMM 算法详解与应用

免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负。


点此亲启

ABOUT US

宸极实验室隶属山东九州信泰信息科技股份有限公司,致力于网络安全对抗技术研究,是山东省发改委认定的“网络安全对抗关键技术山东省工程实验室”。团队成员专注于 Web 安全、移动安全、红蓝对抗等领域,善于利用黑客视角发现和解决网络安全问题。

团队自成立以来,圆满完成了多次国家级、省部级重要网络安全保障和攻防演习活动,并积极参加各类网络安全竞赛,屡获殊荣。

对信息安全感兴趣的小伙伴欢迎加入宸极实验室,关注公众号,回复『招聘』,获取联系方式。

原文始发于微信公众号(宸极实验室):『CTF』AMM 算法详解与应用

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年4月24日08:41:53
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   『CTF』AMM 算法详解与应用https://cn-sec.com/archives/1679968.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息