目录
n是p的r次方
n分解三个素数
e与phi不互素
n是p的r次方
此类RSA会给出 n=p^r ,其中p是素数,r为正整数。虽然没有给出q,但是我们也可以算出phi。根据欧拉函数(即phi的值)的定义:
正整数n的欧拉函数ϕ(n),是小于n的正整数中与n互质的数的数目
我们只要找到(0,p^r)中与其互质数的数目即可 。
那么我们开始分析:p为素数,因此小于p^r的数字,只有不含p才可以构成互质,而包含p的数字则有p^(r-1)个,因此:
ϕ(n)=p^r-p^(r-1)
有了phi就转换成了常规题,编写脚本:
import gmpy2 import libnum #n=p^r phi = p^r - P(r-1) d=gmpy2.invert(e,phi) m=pow(c,d,n) print(libnum.n2s(int(m)))
实例解决
我们看一个示例:
n= 908598667358728789272490430197327716041862027366091103106475006016277103250700584060961743801137950558993522830114303932065167092027087502088239246389230331674939950699268035367740231404100177455217445111313678297492589797237575989 e= 65537 c= 133858303290043451919904822232558226590822126778644113869750054931761083653517706859731718319007451221357657841394675101713280351304329823446875738686930287854842700779685930501494130077034480715432429452658619670604139842537381751 #n=p**3
给到n,我们可以使用工具分解(可以使用工具yafu,也可以使用在线网站) ,分解后得到p,直接带入脚本
import gmpy2 import libnum n= 908598667358728789272490430197327716041862027366091103106475006016277103250700584060961743801137950558993522830114303932065167092027087502088239246389230331674939950699268035367740231404100177455217445111313678297492589797237575989 e= 65537 c= 133858303290043451919904822232558226590822126778644113869750054931761083653517706859731718319007451221357657841394675101713280351304329823446875738686930287854842700779685930501494130077034480715432429452658619670604139842537381751 #n=p**3 p=96855442995421883542552954630576294307113521874294933438111345007173429429229 phi = p**3 - p**2 d=gmpy2.invert(e,phi) m=pow(c,d,n) print(libnum.n2s(int(m)))
N分解三个素数
此类题目并没有什么特别的,只是phi=(p-1)*(q-1)*(r-1) ,按正常算法即可。若有多个也是相同的解法。
e和phi不互素
在RSA加密算法中,e与phi是要求互素的,现在不互素,意味着他们的最大公约数不为1。我们可以找到先它们的最大公约数:
t = gcd(e,phi)
有了最大公约数,我们让 e1 = e//t ,现在,e1就与phi互素了,此时,新的d1则为
dt1 = gmpy2.invert(e1,phi)
所以
c = m^e % n
= (m^t)^e1 % n
这时就相当于新的参数的加密,m^t 相当于现在的m,所以
m^t = c ^dt %n
之后开t次方根就可以得到m,编写脚本:
import gmpy2 import libnum n=p*q phi = (p-1)*(q-1) t = gmpy2.gcd(e,phi) dt = gmpy2.invert(e//t,phi) m1 = pow(c,dt,n) s = gmpy2.iroot(m1, t) print(libnum.n2s(int(s[0])))
这里需要注意,gmpy2.iroot用于计算一个数的平方根或其他方根,因为他的返回结果是元组,所以我们需要输出s[0],输出他的第一个元素,即m。
实例解决
如下实例
import gmpy2 import libnum p= 99121189582501008712013968992352803768625246914465855184015436447703186815449262295805380204323710295921854340997828769823231464427130821876580400691211345486729675853150761685349462986166877814175984579563567306549572588319266994795866284845802507095884883153396348382938449540972127499904296247559029225383 q= 150268317336339960126647903449109988255866504007392913394846120571848960249105047280936043706386647123147508124760271106985842327324754758926316201153985618599913716062022820836021510537460439547919271691120014699040128108877277220772435327172560430486687910764022875239978670811789865485555656852692138607963 e= 690 c= 6505780503733715403443854024453332458683344468949367917381899997843566653970592463657488800022481361267796145008565281833144485114003013344972509872537410456069455025354665233053506124595498250925678243187368612466705455369711026029611771580251154647502708121658702303970719096614939559919889007767123101713086072603399574246751930445410516569891126911814849240689260100662046196730328811528659567266274519504438208521127231263846779566225581017589093267179605699105789054236905554565086285947939799397891614189613209207952711175468812692611455797965871838759265528337102845259493469631071499285855955433641064781079 n=p*q phi = (p-1)*(q-1) t = gmpy2.gcd(e,phi) dt = gmpy2.invert(e//t,phi) m1 = pow(c,dt,n) s = gmpy2.iroot(m1, t) print(libnum.n2s(int(s[0])))