密码学知识点-Lcg入门

lcg入门

先看原题代码

from libnum import *

flag = 'flag{******************}'
flag = s2n(flag)

length = flag.bit_length()

a = generate_prime(length)
b = generate_prime(length)
n = generate_prime(length)

for i in range(10):
    flag = (a * flag + b) % n

print("a =", a)
print("b =", b)
print("n =", n)
print("flag =", flag)

# a = 10580362976768902535288290537881894669438793788144555901400894449594743420700735933898091469
# b = 12282491670012215371979074133375864865383435870031708675997502402287216522639028762493710827
# n = 15544810823190562032492196545115274631091651502678197172285073194125696949924554440256408651
# flag = 14208190311706700229018574851578988188134550363358366844269050987652736462089394391688795530

通过分析代码可知这个程序是将flag进行转换后通过循环取模的方式对flag加密

循环中的公式是标准的lcg(线性同余方法)的形式
X n + 1 = ( a X n + b )   m o d   m X_{n+1} = (aX_n + b)\ mod\ m Xn+1=(aXn+b) mod m
逆推公式的推导过程为
X n + 1 = ( a X n + b )   m o d   m ⟹ a X n = ( X n + 1 − b )   m o d   m ⟹ X n = ( a − 1 X n + 1 − b )   m o d   m X_{n+1} = (aX_n + b)\ mod\ m \\ \Longrightarrow aX_n=(X_{n+1}-b)\ mod\ m \quad \quad \\ \Longrightarrow X_n=(a^{-1}X_{n+1}-b)\ mod\ m \quad Xn+1=(aXn+b) mod maXn=(Xn+1b) mod mXn=(a1Xn+1b) mod m
故该公式的逆推公式为
X n = ( a − 1 ( X n + 1 − b ) )   m o d   m X_n=(a^{-1}(X_{n+1}-b)) \ mod \ m Xn=(a1(Xn+1b)) mod m
其中$ a^{-1} $表示的是a相对于模数m的乘法逆元,即为题中的a相对于n的乘法逆元,这里使用gmpy2模块中的invert函数进行计算。

解题脚本

import libnum
import gmpy2

a = 10580362976768902535288290537881894669438793788144555901400894449594743420700735933898091469
b = 12282491670012215371979074133375864865383435870031708675997502402287216522639028762493710827
n = 15544810823190562032492196545115274631091651502678197172285073194125696949924554440256408651
flag = 14208190311706700229018574851578988188134550363358366844269050987652736462089394391688795530

an = gmpy2.invert(a, n)
for i in range(10):
    flag = (an * (flag - b)) % n
print(libnum.n2s(int(flag)))

最后得到flag为flag{90c353c0d77a8d0abfcebffec5c02302}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeMessage学院

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值