Crypto题目-Others
密码题杂记
Shamir门限
跟着tcxjk师傅的博客学习了一下
题目:
公司使用Shamir门限密钥设计了一个秘密保存方案,将fag保存了起来,最终的设计效果如下密钥总共有9份,拿到任意5个密钥即可解出保存的flag.现在我们知道公共的密钥:
p=0x3b9f64aeadae9545d899102c8c1874e3d4f12caf6ded3eb8454c27fd7058ff31a5742aee60b2b7
以及如下5个密钥:
0x13570e530aaa3639e622d02ca8a0f89089ad0ee3ba51edd95490653b684aaeedd3a762938d08b3
0xb583b75e84190f9d081234088b23e6b634110bda167a21bdfb4b5608a65e7283e8531547623d8
0x8d3bbbb28592b1a00885c11633369568fcb8bbfdec3cbf4d8cd5546728ca99f24cbe0ac214a39
0x13816f03e972210516c17b13a008ee8fd9b888839d6e1ce203fd7723f5e8e0443c2c6279c8dab9
0x1553e323763e4c3ba53f6f93e0feb01d6b168fdda30fd87e949664eb4c8f2fd8414e2c14df8f5e
请恢复flag
什么是Shamir门限密钥?
(借图
题目告诉我们最小恢复人数为5 也就是t=5 还告诉我们这9个 (xi,f(xi))点中的5个 我们需要恢复secret
通过函数上的点来恢复函数系数 一般采用拉格朗日插值法
拉格朗日插值函数:
对于n阶多项式 还原系数需要n+1个点
对于本题Shamir 阶=t-1=4 t=5 足以还原
注意到上式 我们令x=0 得到的值就是系数a0 亦即secret
注意Shamir生成的点为9个 而我们得到的是其中5个 所以要枚举一下这5个点的对应情况(1~9中的5个) 这里可以利用itertools中的permutation简化编程
p=
c = []
from itertools import permutations
from libnum import *
from primefac import modinv
for per in permutations(range(9),5):
x0,x1,x2,x3,x4 = per[0],per[1],per[2],per[3],per[4]
try:
secret = (
c[0]*(-x1)*(-x2)*(-x3)*(-x4)*modinv(x0-x1,p)*modinv(x0-x2,p)*modinv(x0-x3,p)*modinv(x0-x4,p)+
c[1]*(-x0)*(-x2)*(-x3)*(-x4)*modinv(x1-x0,p)*modinv(x1-x2,p)*modinv(x1-x3,p)*modinv(x1-x4,p)+
c[2]*(-x0)*(-x1)*(-x3)*(-x4)*modinv(x2-x0,p)*modinv(x2-x1,p)*modinv(x2-x3,p)*modinv(x2-x4,p)+
c[3]*(-x0)*(-x1)*(-x2)*(-x4)*modinv(x3-x0,p)*modinv(x3-x1,p)*modinv(x3-x2,p)*modinv(x3-x4,p)+
c[4]*(-x0)*(-x1)*(-x2)*(-x3)*modinv(x4-x0,p)*modinv(x4-x1,p)*modinv(x4-x2,p)*modinv(x4-x3,p)
)%p
flag = n2s(int(secret))
if b'flag' in flag:
print(flag)
break
except:
pass
# b'flag{b14f4963671a457cf22ec271356e0f78}'