其他
Beosin硬核研究 | 3种针对ZK基础算法Groth16的攻击手法分享
1. 什么是延展性攻击?
2. Groth16算法
2.1 Groth16算法概述
封闭性:若有限域中的任意两个元素 ,那么 和 也属于该有限域
结合律:若任意 ,则有:
交换律:若任意 ,则有:
2.2 可信设置
2.3 Prover生成证明
2.4 Verifier验证证明
3. Groth16 算法延展性攻击
3.1 乘法逆元构造法
3.2 加法构造法
3.3 合并构造法
/// Given a Groth16 proof, returns a fresh proof of the same statement. For a proof π of a
/// statement S, the output of the non-deterministic procedure `rerandomize_proof(π)` is
/// statistically indistinguishable from a fresh honest proof of S. For more info, see theorem 3 of
/// [\[BKSV20\]](https://eprint.iacr.org/2020/811)
pub fn rerandomize_proof(
vk: &VerifyingKey<E>,
proof: &Proof<E>,
rng: &mut impl Rng,
) -> Proof<E> {
// These are our rerandomization factors. They must be nonzero and uniformly sampled.
let (mut r1, mut r2) = (E::ScalarField::zero(), E::ScalarField::zero());
while r1.is_zero() || r2.is_zero() {
r1 = E::ScalarField::rand(rng);
r2 = E::ScalarField::rand(rng);
}
// See figure 1 in the paper referenced above:
// A' = (1/r₁)A
// B' = r₁B + r₁r₂δ
// C' = C + r₂A
// We can unwrap() this because r₁ is guaranteed to be nonzero
let new_a = proof.a.mul(r1.inverse().unwrap());
let new_b = proof.b.mul(r1) + &vk.delta_g2.mul(r1 * &r2);
let new_c = proof.c + proof.a.mul(r2).into_affine();
Proof {
a: new_a.into_affine(),
b: new_b.into_affine(),
c: new_c.into_affine(),
}
}