期末周看了看题 把签到的分辨器和ntt给梭出来 本文主要基于rec师傅的博客 来进行对zkpuzzle的一个复现
zkpuzzle1
1 | from sage.all import EllipticCurve, Zmod, is_prime, randint, inverse_mod |
分为两个部分 首先需要选择两个256bits的素数
1 | def myrand(self, E1, E2): |
当然我们也可以令
寻找一个素数
使得曲线 满足
rec师傅使用了一个 Complex Multiplication的方法
随机选取一个大奇数
1 | def find_prime_for_anomalous_curve(target_b): |
在找到这个
此时我们的验证
1 | proofsystem.verify(proofsystem.E1, r, k, w) and proofsystem.verify(proofsystem.E2, r, k, w) |
本质等于一个对
在此之上 我们有
- 我们人为再令
,问题进一步简化成 ,也就是 ; 视为某个奇数 - 故而 我们对
去用 试除 肯定能除掉 那么能除掉的部分我们给 我们的期望是 ; 一旦能进入这个范围的分解 我们就直接得到 完成分解 发送通过此轮
- 故而 我们对
- 我们人为再令
然后就是分解的思路了 还是从rec师傅的分解手法这里学到很多 特别是factor的一种高效好用的写法
1 | def _factor_worker(n, q): |
思路就很简单 每次都找我们的target 直接分解 取光滑的情况 然后找到一组合适的解就行
1 | from Crypto.Util.number import * |
zkpuzzle2
1 | from sage.all import EllipticCurve, Zmod, is_prime, randint, inverse_mod |
等式没变 但是做出了如下限制
ROUND = ROUND - bin(p1).count("1") - bin(p2).count("1")
同时要考虑p和order之间的限制关系 依旧需要构造类似的2-cycle的椭圆曲线
对于
1 | p = 0b1100000000110000000000110000000000000000000000000000000000000000000000000000000000000000000000000000000000011000000000110000000000010000100000010000000000000000000000100000100000000000000000001000001000010000000000001100000000001000000000000000000000000001 |
接下来我们要求解zkp
取
因为我们的检查是分别在
1 | from Crypto.Util.number import * |
zkpuzzle3
1 | from sage.all import EllipticCurve, Zmod, is_prime, randint, inverse_mod |
限制和zkpuzzle2一样 关键在于
- 90s限时 基本0.1s不到就需跑完一轮
- 我们的zkp改为
,因为明显 而且 是不变量
我们借用zkp2的思路
往完全平方转化 BinaryQF(u, 0, v).solve_integer(t)
方法