Files
caulk/src/pedersen.rs
2022-06-02 21:06:09 -04:00

76 lines
2.4 KiB
Rust

// This file includes a prover and verifier for demonstrating knowledge of an
// opening of a Pedersen commitment. The protocol is informally described in
// Appendix A.2, Proof of Opening of a Pedersen Commitment
use crate::CaulkTranscript;
use ark_ec::{AffineCurve, ProjectiveCurve};
use ark_ff::PrimeField;
use ark_std::{end_timer, rand::RngCore, start_timer, UniformRand};
use std::marker::PhantomData;
// Parameters for pedersen commitment
pub struct PedersenParam<C: AffineCurve> {
pub g: C,
pub h: C,
}
// Structure of proof output by prove_pedersen
pub struct PedersenProof<C: AffineCurve> {
pub g1_r: C,
pub t1: C::ScalarField,
pub t2: C::ScalarField,
}
pub struct PedersenCommit<C: AffineCurve> {
phantom: PhantomData<C>,
}
impl<C: AffineCurve> PedersenCommit<C> {
// prove knowledge of a and b such that cm = g^a h^b
pub fn prove<R: RngCore>(
param: &PedersenParam<C>,
transcript: &mut CaulkTranscript<C::ScalarField>,
cm: &C,
a: &C::ScalarField,
b: &C::ScalarField,
rng: &mut R,
) -> PedersenProof<C> {
let timer = start_timer!(|| "prove pedersen commit");
// R = g^s1 h^s2
let s1 = C::ScalarField::rand(rng);
let s2 = C::ScalarField::rand(rng);
let g1_r = (param.g.mul(s1) + param.h.mul(s2.into_repr())).into_affine();
// c = Hash(cm, R)
transcript.append_element(b"commitment", cm);
transcript.append_element(b"g1_r", &g1_r);
let c = transcript.get_and_append_challenge(b"get c");
let t1 = s1 + c * a;
let t2 = s2 + c * b;
end_timer!(timer);
PedersenProof { g1_r, t1, t2 }
}
// Verify that prover knows a and b such that cm = g^a h^b
pub fn verify(
param: &PedersenParam<C>,
transcript: &mut CaulkTranscript<C::ScalarField>,
cm: &C,
proof: &PedersenProof<C>,
) -> bool {
let timer = start_timer!(|| "verify pedersen commit");
// compute c = Hash(cm, R)
transcript.append_element(b"commitment", cm);
transcript.append_element(b"g1_r", &proof.g1_r);
let c = transcript.get_and_append_challenge(b"get c");
// check that R g^(-t1) h^(-t2) cm^(c) = 1
let res = proof.g1_r.into_projective() + cm.mul(c)
== param.g.mul(proof.t1) + param.h.mul(proof.t2);
end_timer!(timer);
res
}
}