【Wilson威尔逊定理】三道题目(附链接 入门Wilson!!

威尔逊定理入门

题目:

import libnum
import uuid
import gmpy2
flag="flag{"+str(uuid.uuid4())+"}"

m=libnum.s2n(flag)
p=libnum.generate_prime(512)
q=gmpy2.next_prime(p)
n=p*q
e=65537
for i in range(1,p):
    m=(m*i)%p

c=pow(m,e,n)
print("c=",c)
print("n=",n)

c= 110529037403457010976226680228015853681747082298049971277864723725003290263121993249901746108064910538219056566054434964752554464076788576969420195833066780032521421693370829430794829520809208371861674386624296250550029664837604012247019944404589941948639334516981017574704294281416080581914051559281376725552
n= 118816369182219711551736875622148948376274930097622029542291351942110204065005093752267272235864774888160522170555189015695148555668006209122716634896476014952586332120668094812890443697140874554631953248467119041951362983074748376348829077644413780641030688747863975973112631445365138922148115802917498155841

解题:

首先根据p和q的生成规则:

p=libnum.generate_prime(512)
q=gmpy2.next_prime(p)

这是两个相近的素数

所以直接对n开平方 然后取平方数的下一个素数

exp:

n = gmpy2.iroot(n,2)[0]

然后根据普通的rsa进行解密 可以获得经过加密之后的m

二次加密的m:

for i in range(1,p):
    m=(m*i)%p

相当于c_m = m*(p-1)! (mod p)

联想到wilson定理:

image-20230803125901141

现在c_m经过rsa算法已知所以m=c_m * (p-1)!的逆 (mod p)

l类比rsa算法:ed = 1 mod phi d = invert(e,phi)

所以(p-1)!*(-1)=1(mod p)

所以(p-1)! = invert(-1,p)

故m = c_m*invert(-1,p) %p (在模p的空间内 一定不要忘记!!!)

完整exp:

import gmpy2
import libnum

c= 110529037403457010976226680228015853681747082298049971277864723725003290263121993249901746108064910538219056566054434964752554464076788576969420195833066780032521421693370829430794829520809208371861674386624296250550029664837604012247019944404589941948639334516981017574704294281416080581914051559281376725552
n= 118816369182219711551736875622148948376274930097622029542291351942110204065005093752267272235864774888160522170555189015695148555668006209122716634896476014952586332120668094812890443697140874554631953248467119041951362983074748376348829077644413780641030688747863975973112631445365138922148115802917498155841
e= 65537

p1 = gmpy2.iroot(n,2)[0]
q = gmpy2.next_prime(p1)
p = n // q
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
c_m = pow(c,d,n)
m = int(c_m*gmpy2.invert(-1,p)%p)
print(libnum.n2s(m))

#b'flag{504fb4bf-9fdc-4cb3-9d84-4c437876ddc3}'

[RoarCTF 2019]babyRSA

考点:威尔逊定理

解题:

题目源码:

import sympy
import random

def myGetPrime():
    A= getPrime(513)
    print(A)
    B=A-random.randint(1e3,1e5)  #10的3次方到10的5次方之间
    print(B)
    return sympy.nextPrime((B!)%A)
p=myGetPrime()
#A1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467234407
#B1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467140596

q=myGetPrime()
#A2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858418927
#B2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858351026

r=myGetPrime()

n=p*q*r
#n=85492663786275292159831603391083876175149354309327673008716627650718160585639723100793347534649628330416631255660901307533909900431413447524262332232659153047067908693481947121069070451562822417357656432171870951184673132554213690123308042697361969986360375060954702920656364144154145812838558365334172935931441424096270206140691814662318562696925767991937369782627908408239087358033165410020690152067715711112732252038588432896758405898709010342467882264362733
c=pow(flag,e,n)
#e=0x1001
#c=75700883021669577739329316795450706204502635802310731477156998834710820770245219468703245302009998932067080383977560299708060476222089630209972629755965140317526034680452483360917378812244365884527186056341888615564335560765053550155758362271622330017433403027261127561225585912484777829588501213961110690451987625502701331485141639684356427316905122995759825241133872734362716041819819948645662803292418802204430874521342108413623635150475963121220095236776428
#so,what is the flag?

题目思路很明确呀:首先根据A和B获得p和q的值 然后进行3个因子的n对应的rsa解密即可

下面来看怎么获得p和q

加密生成代码:sympy.nextPrime((B!)%A)

关键就是解得B! % A 的值 其中AB已知且A是素数

联想到Wilson定理

image-20230803125901141

令p = A

有 (A-1)! = -1 (mod A)

又因为B = A - randomint

所以(A-1)! = (A-1)(A-2)…(B+2)(B+1)B(B-1)…1 = (A-1)…(B+1)B! = -1 (mod A)

又因为我们相求逆元 右边的-1为1比较方便

所以我们探索-1 mod A等于什么

关于负数取模运算:

image-20230804062634970

所以 根据公式 -1 = ()+ (-1)*A 故() = A-1

所以两边消去(A-1)有 (A-2)(A-3)…(B+1)B! = 1 (mod A)

从B到A相距有限 可以求值 所以用invert 可以解出B!

exp:

import gmpy2
import sympy
import libnum

A1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467234407
B1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467140596
A2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858418927
B2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858351026
n=85492663786275292159831603391083876175149354309327673008716627650718160585639723100793347534649628330416631255660901307533909900431413447524262332232659153047067908693481947121069070451562822417357656432171870951184673132554213690123308042697361969986360375060954702920656364144154145812838558365334172935931441424096270206140691814662318562696925767991937369782627908408239087358033165410020690152067715711112732252038588432896758405898709010342467882264362733
e=0x1001
c=75700883021669577739329316795450706204502635802310731477156998834710820770245219468703245302009998932067080383977560299708060476222089630209972629755965140317526034680452483360917378812244365884527186056341888615564335560765053550155758362271622330017433403027261127561225585912484777829588501213961110690451987625502701331485141639684356427316905122995759825241133872734362716041819819948645662803292418802204430874521342108413623635150475963121220095236776428

def getpq(A,B):
   tmp = 1
   for i in range(B+1,A-1):
       tmp *= i
       tmp %= A
   B_all = gmpy2.invert(tmp,A)
   return sympy.nextprime(B_all%A)

p = getpq(A1,B1)
q = getpq(A2,B2)
r = n // (p*q)
phi = (p-1)*(q-1)*(r-1)
d = gmpy2.invert(e,phi)
print(libnum.n2s(int(pow(c,d,n))))

#b'RoarCTF{wm-CongrAtu1ation4-1t4-ju4t-A-bAby-R4A}'

[2022赣育杯]Wilson

考点:Wilson 中国剩余定理crt

解题:

题目:

from os import urandom
from gmpy2 import next_prime
from Crypto.Util.number import getPrime, bytes_to_long

p = getPrime(512)
q = next_prime(p)
f = open('flag.txt', 'rb')
flag = bytes_to_long(f.read() + urandom(80))
f.close()

N = 1
a = p * q
for i in range(1, p):
    N = (N * i) % a
e = 65537
m = N * flag % a
c = pow(m, e, a)
f = open('Encode.txt', 'w')
f.write(f'a = {a}\n')
f.write(f'c = {c}\n')
f.close()


a = 156853895847604116708242664263151514811095704969640303272039451331791888050995073274981545693518063639560286348739938318495685137088495867703518198511200409009953879436648706837731243061114851474801565873584183542649886358523850682697732574913523360866915083642887238043256280849100274825940626065115676325169
c = 3459715117165130065996389169943285249501133832272446001239391765859259811270526185228996906338576254353123756173289118671028939933226544773197852424767051933844004667155191851195814295922794480300237399956789038592856532530692732011427288405114650955620859282144504446058845961744702163836107847961388150810

因为p和q的生成关系 直接对a开平方取下一个素数皆可以获得p和q

破题点:

for i in range(1, p):
    N = (N * i) % a
m = N * flag % a

循环表示的意思:N = (p-1)! %a

m = (p-1)! * flag % a

m = (p-1)! * flag + ka

因为根据威尔逊定理

(p−1)! ≡−1 mod p

我们的p-1的阶乘是要模p的 所以两边同时模p

m%p = flag*(p-1)!%p + ka%p(a=pq 所以为0)

m = flag *(p-1)! (mod p)

上面的式子是在模p的空间中进行 但是p的长度是512bit flag中存在urandom(80)这是填充随机字符长度为80字节 所以这会导致上式求出来的flag会有丢失 只存在低位的flag内容

所以我们想再构建一个mod q的flag 然后用中国剩余定理求出flag的全部值

因为p是小于q的 所以同样可以借助威尔逊定理构造(q-1)! mod q

根据 m = (p-1)! * flag % a

两边同时乘(q-1)(q-2)...(p+1)p 得到 (q-1)(q-2)…(p+1)pm = flag * (q-1)! (mod a)

m1 = flag*(q-1)! (mod a)

化简:

m1 = flag*(q-1)! + ka

两边同时模q

m1 = flag*(q-1)! mod q

整合一下我们推导的式子:

m1=(q-1)(q-2)…(p+1)pm

m = flag *(p-1)! (mod p)

m1 = flag * (q-1)! (mod q)

式子中的阶乘需要处理掉

根据威尔逊定理

(p−1)! ≡−1 mod p

两边乘-1

有-1 (p-1)! = 1 mod p

类比rsa e d = 1 mod phi =》d = invert(e,phi)

故-1 (p-1)! = 1 mod p -》(p-1)! = invert(-1,p)

综上

m1=(q-1)(q-2)…(p+1)pm

m = flag * invert(-1,p) % p

m1 = flag * invert(-1,q) % q

利用中国剩余定理:

image-20230804105012819

现在flag就是我们的未知数x 关于x的解法直接使用sage中的内置函数crt即可

flag = m // int(gmpy2.invert(-1,p)) % p

a1 = m // int(gmpy2.invert(-1,p))

flag = m1 // int(gmpy2.invert(-1,q)) % q

a2 = m1 // int(gmpy2.invert(-1,q))

然后直接用内置函数 crt(a1, a2, p, q)

完整exp:

import libnum
import sympy
import gmpy2
a = 156853895847604116708242664263151514811095704969640303272039451331791888050995073274981545693518063639560286348739938318495685137088495867703518198511200409009953879436648706837731243061114851474801565873584183542649886358523850682697732574913523360866915083642887238043256280849100274825940626065115676325169
c = 3459715117165130065996389169943285249501133832272446001239391765859259811270526185228996906338576254353123756173289118671028939933226544773197852424767051933844004667155191851195814295922794480300237399956789038592856532530692732011427288405114650955620859282144504446058845961744702163836107847961388150810
e = 65537

p1 = gmpy2.iroot(a,2)[0]
q = sympy.nextprime(p1)
p = a // q
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,a)
a1 = m // int(gmpy2.invert(-1,p))

m1 = 1
for i in range(p,q):
    m1 = m*i%q
a2 = m1 // int(gmpy2.invert(-1,q))
flag = int(crt(int(a1),int(a2),p,q))
print(libnum.n2s(flag))

#b'Sangfor{51083a96-13b4-00c4-36c0-2025c1b46a63}\xb5\\\xc4.}5\xe9\x1f\xab\xfbf\xbe0\xf1\xed \x94\xe6\xe5`\xe7\xf2\xc5\xa3a7\xfb\xd6\xcf\x88\x8a\xbd\x10\x90\x92\xcc\xaa\xe0m\x9d\xc7\x81\xafX[\x06#\xb7\x91\x8aW\x9c\xfbCV\x8a\xb1\x80K\xfaw\xb2HSZ\x95\x18\xdd\xc3\x1d\x9cg\xc9\xdc\x0f,\xb4\xe5\xa5\xab'

注意:

  1. 后面是随意生成的80字节的内容
  2. 在整除 crt等计算的时候注意int类型的转换!!!

我是哈皮,祝您每天嗨皮!我们下期再见~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值