mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-08-01 12:51:30 +00:00
57 lines
1.7 KiB
Rust
57 lines
1.7 KiB
Rust
use ff::PrimeField;
|
|
use group::{CurveAffine, CurveProjective};
|
|
use pairing::{Engine, PairingCurveAffine};
|
|
|
|
use super::{PreparedVerifyingKey, Proof, VerifyingKey};
|
|
|
|
use SynthesisError;
|
|
|
|
pub fn prepare_verifying_key<E: Engine>(vk: &VerifyingKey<E>) -> PreparedVerifyingKey<E> {
|
|
let mut gamma = vk.gamma_g2;
|
|
gamma.negate();
|
|
let mut delta = vk.delta_g2;
|
|
delta.negate();
|
|
|
|
PreparedVerifyingKey {
|
|
alpha_g1_beta_g2: E::pairing(vk.alpha_g1, vk.beta_g2),
|
|
neg_gamma_g2: gamma.prepare(),
|
|
neg_delta_g2: delta.prepare(),
|
|
ic: vk.ic.clone(),
|
|
}
|
|
}
|
|
|
|
pub fn verify_proof<'a, E: Engine>(
|
|
pvk: &'a PreparedVerifyingKey<E>,
|
|
proof: &Proof<E>,
|
|
public_inputs: &[E::Fr],
|
|
) -> Result<bool, SynthesisError> {
|
|
if (public_inputs.len() + 1) != pvk.ic.len() {
|
|
return Err(SynthesisError::MalformedVerifyingKey);
|
|
}
|
|
|
|
let mut acc = pvk.ic[0].into_projective();
|
|
|
|
for (i, b) in public_inputs.iter().zip(pvk.ic.iter().skip(1)) {
|
|
acc.add_assign(&b.mul(i.into_repr()));
|
|
}
|
|
|
|
// The original verification equation is:
|
|
// A * B = alpha * beta + inputs * gamma + C * delta
|
|
// ... however, we rearrange it so that it is:
|
|
// A * B - inputs * gamma - C * delta = alpha * beta
|
|
// or equivalently:
|
|
// A * B + inputs * (-gamma) + C * (-delta) = alpha * beta
|
|
// which allows us to do a single final exponentiation.
|
|
|
|
Ok(E::final_exponentiation(&E::miller_loop(
|
|
[
|
|
(&proof.a.prepare(), &proof.b.prepare()),
|
|
(&acc.into_affine().prepare(), &pvk.neg_gamma_g2),
|
|
(&proof.c.prepare(), &pvk.neg_delta_g2),
|
|
]
|
|
.into_iter(),
|
|
))
|
|
.unwrap()
|
|
== pvk.alpha_g1_beta_g2)
|
|
}
|