1.5
RSA·dp、dq泄漏
什么是dp、dq
dp = d mod (p-1)
dq = d mod (q-1)
重要结论
当m < p 或 q时
m<p:
$$ m = c^d \mod p$$
$$ m = c ^ {dp} \mod p $$
m<q:
$$ m = c^d \mod q$$
$$ m = c ^ {dp} \mod p $$
证明
代码实现
1 | m = pow(c, dp, p) |
更一般的
已知条件
c = m^e mod n
m = c^d mod n
ϕ(n)= (p−1)(q−1)
de≡ 1 mod ϕ(n)
dp= d mod (p−1)
dq= d mod (q−1)m=c^d mod n
m=c^d+k*n因为 n=pq
m=c^d+pq*k同时取余q和p
式1 m1=c^d mod q
式1 c^d=kp+m1式2 m2=c^d mod p
式1带入式2
m2=(kp+m1) mod q等式两边同时减去m1
(m2−m1)≡kp mod q因为gcd(p,q)=1
所以可以求p的逆元,得到
(m2−m1)*p−1≡k mod q得到如下两个式子
k≡(m2−m1)*p−1 mod qc^d=kp+m1
m≡c^d mod n上下两个式子合并
c^d = ((m2−m1)*p−1 mod q)p+m1
m ≡ c^d mod n最后可以有
m≡(((m2−m1)*p−1 mod q)p+m1) mod n
只剩最后一步了
m1≡cd mod q
m2≡cd mod pm1和m2怎么求
d≡dp mod (p−1)
d≡dq mod (q−1)那么分别带入
m1≡cdq mod (q−1) mod q
m2≡cdp mod (p−1) mod p费马小定理即假如p是质数,且gcd(a,p)=1
a^(p−1)≡1 mod p所以如果我们有等式
d=dp+k*(p−1)
直接带入
m2≡c^dp+k*(p−1) mod p这里的指数,我们拆开,为
m2≡c^dpck(p−1) mod pck*(p−1)≡1 mod p
因为p是大素数,显然和c互素所以可以直接得到
m2≡cd^p mod p那么m1根据对称性也可以同理得到
m1≡cd^q mod q
故此,我们现在拥有了所有条件,下面归纳一下为
m1≡cd^q mod q
m2≡cd^p mod p
m≡(((m2−m1)*p−1 mod q)p+m1) mod n
代码实现
1 | # coding=utf-8 |
RSA·n是p的r次方
当$ n = p^{r} $时
$$ phi = p^r - p^{r-1} $$
比较简单,在rsa原理学习就已经提及,略。
1 | import libnum |
当$ n = p^{r}·q^{s} $时
RSA原理学习篇中,已知:
如果n可以分解成两个*互质的整数之积*,n = p1 × p2*,则*:
φ(n) = φ(p1p2) = φ(p1)φ(p2)
所以φ(n) =φ($p^{r} $) · φ($q^{s} $)
$$ φ(n) = (p^{r} - p^{r-1})*(q^{s} - q^{s-1}) $$
通常为了计算方便,公因式提出来。
例子
$$ n = p^{3}*q $$
易知:$ φ(n) = (p^{3} - p^{2})*(q-1) $
提公因式 $ p^2 $,得:
$$ φ(n) = (p-1)p^{2}(q-1) $$
之后就是常规的求解,略。
RSA·n分解为多个素数
结论
例: n = p* q * r
则φ(n) = φ(pqr) = φ(p)φ(q)φ(r)=(p-1)(q-1)(r-1)
原理
如果n可以分解成两个*互质的整数之积*,n = p1 × p2,则:
**φ(n) = φ(p1p2) = φ(p1)φ(p2)
代码
1 | import libnum |
RSA·e和phi不互素
e和phi不互素,这是一个严重的问题。
在rsa原理学习篇中,也有说到:e得与phi互素
否则,求不出e的逆元d
没有私钥d,求解rsa便是无稽之谈了
对策
总体而言,两字:构造
先找到e与phi的公约数
t1 = gcd(e, phi)
得到与phi互素的t2
t2 = e // t1
t1、t2代入
$ c = m^{e}modn = (m^{t1})^{t2}modn$
$ m^{t1} $当作新的明文M;t2当作新的加密指数E,则有:
$ c = M^{E}modn $
t2(E)与phi互素,通过构造,问题已经变得常规了。
最后,对解出的M开t1次方,即得m.
代码实现
1 | import gmpy2 |
RSA·NC不互素
题型
1 | # 2021绿城杯·RSA-1 |
结论
当加密方式为:
$$ c = (m*p)^{e}modn $$
有:p = gcd(n, c)
即:当n,c不互素时,它们的最大公约数必然是p
证明
由$ c = (m*p)^{e}modn $,得:
c = $ (m*p)^{e} - kn $
两边同时模p,则:
$$ c \mod p = (m•p)^{e} \mod p = ((m•p)\mod p)^{e} \mod p =[(m \mod p)•(p\mod p)]\mod p)^{e}\mod p $$
由$ p \mod p = 0 $,得:
$$ c \mod p = 0$$
即: c = kp
因为n = pq,所以有:
gcd(n, c) = p
代码求解
1 | import gmpy2 |
RSA·rabin算法
特征
e = 2
代码
直接给了参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21from gmpy2 import *
import libnum
import hashlib
p=275127860351348928173285174381581152299
q=319576316814478949870590164193048041239
n=87924348264132406875276140514499937145050893665602592992418171647042491658461
e=2
c=45617141162985597041928941111553655146539175146765096976546144304138540198644
inv_p = invert(p, q)
inv_q = invert(q, p)
mp = pow(c, (p + 1) // 4, p)
mq = pow(c, (q + 1) // 4, q)
a = (inv_p * p * mq + inv_q * q * mp) % n
b = n - int(a)
c = (inv_p * p * mq - inv_q * q * mp) % n
d = n - int(c)
#因为rabin 加密有四种结果,全部列出。
aa=[a,b,c,d]
for i in aa:
print(i)
print(libnum.n2s(int(i)))
文件形式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30from Crypto.PublicKey import RSA
import libnum
import gmpy2
#导入公钥
with open("pubkey.pem","rb") as f:
key = RSA.import_key(f.read())
n =key.n
e =key.e
#导入密文
with open("flag","rb") as f:
c=libnum.s2n(f.read())
print(n)
print(e)
#n 在线分解
p=275127860351348928173285174381581152299
q=319576316814478949870590164193048041239
inv_p = gmpy2.invert(p, q)
inv_q = gmpy2.invert(q, p)
mp = pow(c, (p + 1) // 4, p)
mq = pow(c, (q + 1) // 4, q)
a = (inv_p * p * mq + inv_q * q * mp) % n
b = n - int(a)
c = (inv_p * p * mq - inv_q * q * mp) % n
d = n - int(c)
#因为rabin 加密有四种结果,全部列出。
aa=[a,b,c,d]
for i in aa:
# print(i)
print(libnum.n2s(int(i)))
1.6/1.7
一月六日,找到并尝试改了了第二届BMZCTF赛的题解的格式
Sage
M1 macOS·Sage安装
参考资料
Install conda
官网上没有直接给出M1 Mac版本的SageMath二进制安装文件,不过给出了使用conda安装Sage的方法,参考Install from conda-forge。
所以如果自己的Mac上还没有安装conda的话,可以先安装一下,然后使用conda安装SageMath。
首先下载Miniforge3-MacOSX-arm64.sh,cd进入Miniforge3-MacOSX-arm64.sh
所在的目录。
Mentioned files | - | - |
---|---|---|
Miniforge3-MacOSX-arm64.sh | 本地下载 | 腾讯微云 |
1 | bash Miniforge3-MacOSX-arm64.sh |
接着一路回车,直到确认条款:
1 | Do you accept the license terms? [yes|no] |
然后编辑配置文件vim ~/.zshrc
,在最下面加入如下内容:
1 | path=('/Users/「这里替换成Mac用户名」/miniforge3/bin' $path) |
先按esc
键,后输入 wq
保存并退出,然后source ~/.zshrc
,conda info
应该就可以看到了,到这里conda安装完成。
在终端输入下面这些,给conda换到清华源,这样在使用国内网络不走代理的情况下安装一些东西就更快了:
1 | conda config --add channels https://mirrors.ustc.edu.cn/anaconda/pkgs/main/ |
然后输入conda config --show | grep https
可以看到已经更新成功的上面的链接。
如果是直接新开的终端,直接输入conda是没有反应的,需要先
source ~/.zshrc
一下。
Install SageMath
1 | conda config --append channels conda-forge |
M1 macOS·Sage运行
这时输入conda activate sage
,然后输入sage
就可以看到sage启动了,也可以使用sage xxx.sage
来执行一个sage脚本,这样就是安装完成了。
注意每次启动都需要先
conda activate sage
进入sage。
Sage·交互模式
conda activate sage
后输入sage
Sage·网页模式(推荐
conda activate sage
后输入sage -n
1.8
m高位
代码
1 | import libnum |
p高位攻击
1 | n = 22127806011633861727954101002390179580447625543207045612671617864341845851658260004006826435219665722338399712799144283442305160095371386129132285556214330279867129279885732638085139970894386809975772641941102438472230541606849251235636928502018782288977994793382547376630461074356449893196487276906629063423071245785206275636191377977712166746567658967286739276282635616277590864547265366547379387583014365390660407286148179073747800137068237371705680826025177248889969809158386539617738762070772471531610084135064141878988874470291949704156926711239213996266350299670204058121040684469621186909795304289942430452869 |
至今
键盘之争 · 84
题目
你听说过键盘之争吗?提交你找到的字符串md5值。
ypau_kjg;”g;”ypau+
好的,👀看了半天,啥也没看出来
题解
键盘布局有qwerty、dvorak、colemak
此题考察的是将qwerty布局转为dvorak
代码实现
1 | import hashlib |
easy_CRC · 92
题目
1:C4E68E3A
2:08FF301C
3:F6FBA587
4:B85C2F9A
5:F1B73D20
6:C6F1D9D7flag=1+2+3+4+5+6
Each serial number consists of 4 characters
题解
已知明文长度的CRC爆破,具体学习可见:Python·CRC爆破学习
代码
1 | import binascii |
rsa · 97
题目
4153372421328787064168548641845708183921443446990158572506114559735441950501706984118235944441928889749083563790293558028143373121367441549974248211570336802004821051820943229232421937298269855190652251294220483768084460779714162849925877879859830009443131489814222929347727735616113359695228615432020363240247474622132986939108457393618346100033147945959684443762976681454755482192433993286205527003029269574787026484389622816932835184754540312561890719407986296481186847292967270288752616
[AFCTF2018]MagicNum
1 | #72065910510177138000000000000000.000000 |
[AFCTF2018]你听过一次一密么?
题目
1 | 25030206463d3d393131555f7f1d061d4052111a19544e2e5d |
题解
一次一密:异或加密。
将明文分组,与密钥按位异或即可。
攻击原理
题目是用同一个密钥去加密多条明文,当密文条数较多时就很容易被攻击,例如Many Time Pad。
Many Time Pad攻击
原理:c1⊕c2 = m1⊕m2.
通过m1⊕m2可以分析出m1和m2,因此m1与m2不再安全。
注:⊕为异或符号
代码
搬运自Github
1 | #!/usr/bin/python |
Buuctf · Crypto
RSA1
题目
1 | p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229 |
题解
明显可见,dp、dq泄漏。
上代码
代码
1 | import gmpy2 |
old-fashion
题目
1 | Os drnuzearyuwn, y jtkjzoztzoes douwlr oj y ilzwex eq lsdexosa kn pwodw tsozj eq ufyoszlbz yrl rlufydlx pozw douwlrzlbz, ydderxosa ze y rlatfyr jnjzli; mjy gfbmw vla xy wbfnsy symmyew (mjy vrwm qrvvrf), hlbew rd symmyew, mebhsymw rd symmyew, vbomgeyw rd mjy lxrzy, lfk wr dremj. Mjy eyqybzye kyqbhjyew mjy myom xa hyedrevbfn lf bfzyewy wgxwmbmgmbrf. Wr mjy dsln bw f1_2jyf-k3_jg1-vb-vl_l |
题解
quipqiup爆破,得到结果
flag{n1_2hen-d3_hu1-mi-ma_a}
RSA3
题目
1 | c1=22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361 |
题解
共模攻击
上代码
代码
1 | import gmpy2 |
RSA2
题目
1 | e = 65537 |
题解
dp泄漏
代码
1 | import gmpy2 as gp |
RSAROLL
题目
1 |
|
题解
不知道题目的考点在哪,无从下手。
学习他人题解后,得知:
{920139713,19}
n = 920139713,
e = 19
分解 n得到:
q = 18443
p = 49891
常规求phi、d后,对每一行密文(c)进行解密
代码
1 | import gmpy2 |
rsa2
题目
1 | import hashlib |
题解
看出来求d再md5转换后即可。
这里考察本意是e过大的情况下,利用维纳攻击
但此题的p、q发现可拆,则有以下
代码
1 | import hashlib |
交了好几次flag都错了,对比他人题解,得知:
d没错,此方法可行
因为Py2与Py3的差异,导致相同值的md5值不同
其后在cmd5网站加密后的结果与另一部分题解相同,但仍不正确
必须在Py2环境下md5加密
总结
Python2.X的环境还得留着,以备不时之需
RSA5
题目
1 | m = xxxxxxxx |
题解
相同m、e, 不同n
很像是广播攻击,但加密指数不低🤔
还是试了下,没成功
1 | import binascii, gmpy2 |
思维窃取ing
奥,拆不出来的p、q
且那么正常的e 不该是低加密指数广播攻击 但n真的很多,就该考虑n不互素,找到p
获得思路后,再写代码!
代码
1 | import gmpy2 |
总结
不做题就没有记忆点
不互素在无思路时应该多试试。
[NCTF2019]childRSA
题目
1 | from random import choice |
题解
直接拆n得到p、q
1 | import gmpy2, libnum |
[HDCTF2019]bbbbbbrsa
题目
1 | # enc |
题解
q: 题目交代了p、n, 所以 q = n \ q
1
2
3
4p = 177077389675257695042507998165006460849
n = 37421829509887796274897162249367329400988647145613325367337968063341372726061
q = n // p
phi = (p-1)*(q-1)
c: 题目所示,先将flag转为16进制,再转10进制;最后在RSA加密后,base32编码再倒序打印
对此,只需要将c倒序在解码后RSA解密,即可
1
2
3import base64
c = base64.b32decode(c[::-1])但,这么写,执行起来会报错,binascii.Error: Non-base32 digit found
很让人郁闷,以为写法有问题,改了多次,未果
最后上CyberChef👨🍳,看到用的是base64解码😅,所以是题目写错了吧🤔
(现在看到了from base64 import b64encode as b32encode,啊这
e: RSA解密中唯一的问题在于,不知道e
因为知道e的范围是五万到七万,手动爆破即可(使用每一个与phi互素的e,看最后解出来是不是乱码)
需要手动搜索关键词
1
2
3
4
5
6
7
8
9
10
11
12# 爆破e
e = 50000
while e < 70000:
if gcd(e, phi) == 1:
print(e)
d = int(gmpy2.invert(e, phi))
m = pow(c, d, n)
print(libnum.n2s(m), "\n\n")
e += 1
continue
else:
e += 1
😅恍然发现,题目最后一行注释里突兀的数字是十进制的c
最后,经过一点点完善
代码
1 | import gmpy2, base64, libnum |
[BJDCTF2020]RSA
题目
1 | from Crypto.Util.number import getPrime,bytes_to_long |
题解
常规题目
n1、n2不互素
1
2
3
4
5n1 = 13508774104460209743306714034546704137247627344981133461801953479736017021401725818808462898375994767375627749494839671944543822403059978073813122441407612530658168942987820256786583006947001711749230193542370570950705530167921702835627122401475251039000775017381633900222474727396823708695063136246115652622259769634591309421761269548260984426148824641285010730983215377509255011298737827621611158032976420011662547854515610597955628898073569684158225678333474543920326532893446849808112837476684390030976472053905069855522297850688026960701186543428139843783907624317274796926248829543413464754127208843070331063037
n2 = 12806210903061368369054309575159360374022344774547459345216907128193957592938071815865954073287532545947370671838372144806539753829484356064919357285623305209600680570975224639214396805124350862772159272362778768036844634760917612708721787320159318432456050806227784435091161119982613987303255995543165395426658059462110056431392517548717447898084915167661172362984251201688639469652283452307712821398857016487590794996544468826705600332208535201443322267298747117528882985955375246424812616478327182399461709978893464093245135530135430007842223389360212803439850867615121148050034887767584693608776323252233254261047
q = gcd(n1, n2)
p1 = n1 // q
p2 = n2 // q
爆破e:因为m2已知,且与m1共用e
这里注意用加密方式爆破($c = m^{e} \mod n$)
1
2
3
4for e in range(100000):
if pow(m2, e, n2) == c2:
print(e)
break
代码
1 | from Crypto.Util.number import bytes_to_long |
总结
BUUCTF平台前缀统一为flag,记得改格式。
[BJDCTF2020]rsa_output
题目
1 | {21058339337354287847534107544613605305015441090508924094198816691219103399526800112802416383088995253908857460266726925615826895303377801614829364034624475195859997943146305588315939130777450485196290766249612340054354622516207681542973756257677388091926549655162490873849955783768663029138647079874278240867932127196686258800146911620730706734103611833179733264096475286491988063990431085380499075005629807702406676707841324660971173253100956362528346684752959937473852630145893796056675793646430793578265418255919376323796044588559726703858429311784705245069845938316802681575653653770883615525735690306674635167111,2767} |
题解
翻译一下题目
1
2
3
4
5n = 21058339337354287847534107544613605305015441090508924094198816691219103399526800112802416383088995253908857460266726925615826895303377801614829364034624475195859997943146305588315939130777450485196290766249612340054354622516207681542973756257677388091926549655162490873849955783768663029138647079874278240867932127196686258800146911620730706734103611833179733264096475286491988063990431085380499075005629807702406676707841324660971173253100956362528346684752959937473852630145893796056675793646430793578265418255919376323796044588559726703858429311784705245069845938316802681575653653770883615525735690306674635167111
e1 = 2767
e2 = 3659
c1 = 20152490165522401747723193966902181151098731763998057421967155300933719378216342043730801302534978403741086887969040721959533190058342762057359432663717825826365444996915469039056428416166173920958243044831404924113442512617599426876141184212121677500371236937127571802891321706587610393639446868836987170301813018218408886968263882123084155607494076330256934285171370758586535415136162861138898728910585138378884530819857478609791126971308624318454905992919405355751492789110009313138417265126117273710813843923143381276204802515910527468883224274829962479636527422350190210717694762908096944600267033351813929448599
c2 = 11298697323140988812057735324285908480504721454145796535014418738959035245600679947297874517818928181509081545027056523790022598233918011261011973196386395689371526774785582326121959186195586069851592467637819366624044133661016373360885158956955263645614345881350494012328275215821306955212788282617812686548883151066866149060363482958708364726982908798340182288702101023393839781427386537230459436512613047311585875068008210818996941460156589314135010438362447522428206884944952639826677247819066812706835773107059567082822312300721049827013660418610265189288840247186598145741724084351633508492707755206886202876227不难发现,考查共模攻击
代码
1 | import gmpy2 |
RSA4
题目
1 | N = 331310324212000030020214312244232222400142410423413104441140203003243002104333214202031202212403400220031202142322434104143104244241214204444443323000244130122022422310201104411044030113302323014101331214303223312402430402404413033243132101010422240133122211400434023222214231402403403200012221023341333340042343122302113410210110221233241303024431330001303404020104442443120130000334110042432010203401440404010003442001223042211442001413004 |
题解
校内CTF平台同款的密码题
当时折磨了我一两周 : )
五进制:N、c数字很有特点,各位数都不超过5
低加密指数广播攻击:
- 判断在于许多N、c;
- 未给e(尝试e=3
代码
1 | import gmpy2 |
总结
- 学会对现有题型的利用,识别新题目中的老考点
- 猜测中,e往往不是65537就很可能是3
[WUSTCTF2020]babyrsa
题目
1 | c = 28767758880940662779934612526152562406674613203406706867456395986985664083182 |
题解
没什么特殊的常规题。
代码
1 | import gmpy2, libnum |
[GWCTF 2019]BabyRSA
题目
1 | secret |
题解
乍一看,有些头大,仔细琢磨,没有绝对难度
首先,理一下题目操作
把flag平分为F1、F2
$ c1 = F1 + F2$
$c2 = F1^{3} + F2^{3}$
其后,一个让人疑惑的操作
$ m1 = c1^{e} \mod N$
$ m2 = c2^{e} \mod N$
因为通常,RSA算法算法中,加解密方程为:
$c = m^{e} \mod n$
$m = c^{d} \mod n$
故,这里的操作具有迷惑性。
但,我们的目标是明确的,就是想办法求出c1、c2,再通c1、c2想办法求出F1、F2
- 求解c1、c2
这里,我的想法💡是:
把 m1 记作 C1, c1 记作 M1;
把 m2 记作 C2, c2 记作 M2.
则,有:
$ C1 = M1^{e} \mod N$
$ C2 = M2^{e} \mod N$
这样,就顺眼了,只是常规的求明文m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import gmpy2
n = 636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163
p = 797862863902421984951231350430312260517773269684958456342860983236184129602390919026048496119757187702076499551310794177917920137646835888862706126924088411570997141257159563952725882214181185531209186972351469946269508511312863779123205322378452194261217016552527754513215520329499967108196968833163329724620251096080377747699
q = n // p
phi = (p-1)*(q-1)
e = 65537
C1=90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239
C2=487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546
d = int(gmpy2.invert(e, phi))
c1 = M1 = pow(C1, d, n)
c2 = M2 = pow(C2, d, n)
# print(M1)
# c1 = M1 = F1+F2 = 2732509502629189160482346120094198557857912754
# print(M2)
# c2 = M2 = (F1**3 + F2**3) = 5514544075236012543362261483183657422998274674127032311399076783844902086865451355210243586349132992563718009577051164928513093068525554- 求解F1、F2
这里,我们看到,已求出:
$c1 = F1+F2$ ———-1
$c2 = F1^{3} + F2^{3}$
其后通过将c1三次方后减去c2,得到:
${c1^{3} - c2\over 3c1} = F1F2$ ———-2
由式1、2可得F1、F2,所以下面就该解方程
![image-20220114095336077](https://s2.loli.net/2022/01/14/Dby7tNfOvmYhJF4.png)
求解二元一次方程
这里一开始想使用Sage,可惜,没用明白。
最后学习并使用了sympy
1
2
3
4
5
6
7
8
9
10
11
12
13# 一点数学运算
A = F1F2 = (pow(c1, 3) - c2) // (3*c1)
# 二元一次方程组
"""
F1 · F2 = A
F1 + F2 = c1
"""
x = Symbol('x')
y = Symbol('y')
solved_value = solve([x * y - A, x + y - c1], [x, y])
# print(solved_value)
# [(1141553212031156130619789508463772513350070909, 1590956290598033029862556611630426044507841845), (1590956290598033029862556611630426044507841845, 1141553212031156130619789508463772513350070909)]
可见,求出了F1、F2,这里再调试一下先后顺序,即可。
最终,代码如下
代码
1 | import gmpy2, libnum |