Skip to content

Commit

Permalink
Implement for chapter 12 (#14)
Browse files Browse the repository at this point in the history
* Implement for sigma-protocol
* Implement for toy perdersen-commit
  • Loading branch information
SuccinctPaul authored Sep 2, 2023
1 parent b1968fd commit aade593
Show file tree
Hide file tree
Showing 14 changed files with 257 additions and 0 deletions.
15 changes: 15 additions & 0 deletions 12_pedersen_commitment/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "pedersen_commitment"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ff = "0.13.0"
group = "0.13.0"
pairing = "0.23.0"
bls12_381 = "0.8.0"
rand = "0.8.5"
rand_core = { version = "0.6.4", default-features = false, features = ["std"] }

3 changes: 3 additions & 0 deletions 12_pedersen_commitment/src/cs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod commit;
mod keygen;
mod verifier;
Empty file.
Empty file.
Empty file.
30 changes: 30 additions & 0 deletions 12_pedersen_commitment/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use bls12_381::{Bls12, Scalar};
use ff::Field;
use group::Group;
use pairing::Engine;
use rand_core::OsRng;
use std::ops::Mul;

// cm = Com_{G,H}(m, z)= G*m + H*z
fn commit<E: Engine>(m: &E::Fr, r: &E::Fr, h: &E::G1) -> E::G1 {
E::G1::generator().mul(m) + h.mul(r)
}

#[test]
fn test_perseden_commit() {
// 1. mock setup
let mut rng = OsRng;
let H = <Bls12 as Engine>::G1::random(rng);

let m = Scalar::random(rng);
let r = Scalar::random(rng);

// 2.prover commit
let cm = commit::<Bls12>(&m, &r, &H);

// 3. mock-open. Send v,r to verifier.

// 4. verify verify by recompute cm
let cm_1 = commit::<Bls12>(&m, &r, &H);
assert_eq!(cm, cm_1);
}
16 changes: 16 additions & 0 deletions 12_sigma_protocol/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "sigma_protocol"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ff = "0.13.0"
group = "0.13.0"
pairing = "0.23.0"
bls12_381 = "0.8.0"
rand = "0.8.5"
rand_core = { version = "0.6.4", default-features = false, features = ["std"] }
rayon = "1.7.0"
sha3 = "0.10.6"
2 changes: 2 additions & 0 deletions 12_sigma_protocol/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod sigma;
mod transcript;
33 changes: 33 additions & 0 deletions 12_sigma_protocol/src/sigma.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//! Math theory is the ecc Discrete Logarithm problem.
//!
//! The protocol prove :
//! P holds (h, w) such that h = g*w in G, while V knows h and g.
//!
//! The the curves in Bls12 is additive group. So it's little different with the protocl in book(#184).
use pairing::Engine;

mod prover;
mod verifier;

pub struct Proof<E: Engine> {
a: E::G1, // commitment
e: E::Fr, // random scalar, a challenger from verifier
z: E::Fr, // proof: z = we + r
}

#[cfg(test)]
mod test {
use crate::sigma::prover::Prover;
use crate::sigma::verifier::Verifier;
use bls12_381::Bls12;

#[test]
fn test_sigma_protocol() {
let (prover, h) = Prover::<Bls12>::init();
let verifier = Verifier::init(h);

let proof = prover.prove();
verifier.verify(&proof);
}
}
52 changes: 52 additions & 0 deletions 12_sigma_protocol/src/sigma/prover.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::sigma::Proof;
use crate::transcript::default::Keccak256Transcript;
use crate::transcript::Transcript;
use ff::Field;
use group::{Curve, Group};
use pairing::Engine;
use rand_core::OsRng;

#[derive(Default)]
pub struct Prover<E: Engine> {
w: E::Fr,
h: E::G1,
}

impl<E: Engine> Prover<E> {
// init with the statement:
// prover know the w satisfies: h = g*w
pub fn init() -> (Self, E::G1) {
let w = E::Fr::random(OsRng);
let h = Self::statement(Some(w.clone()));
(Self { w, h }, h.clone())
}

fn statement(witness: Option<E::Fr>) -> E::G1 {
let w = match witness {
Some(w) => w,
None => E::Fr::random(OsRng),
};
let g = E::G1::generator();
// h = g*w
let h = g * w;
h
}

pub fn prove(&self) -> Proof<E> {
let g = E::G1::generator();

// commit phase
let mut transcript_1 = Keccak256Transcript::<E::Fr>::default();
let r = transcript_1.challenge();

// a = g*r, aka commit
let a = g * r;

// open phase
let e = transcript_1.challenge();
// z = we + r
let z = r + self.w * e;

Proof { a, e, z }
}
}
35 changes: 35 additions & 0 deletions 12_sigma_protocol/src/sigma/verifier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use crate::sigma::Proof;
use crate::transcript::default::Keccak256Transcript;
use crate::transcript::Transcript;
use ff::Field;
use group::{Curve, Group};
use pairing::Engine;
use std::ops::Mul;

#[derive(Default)]
pub struct Verifier<E: Engine> {
h: E::G1,
}

impl<E: Engine> Verifier<E> {
pub fn init(h: E::G1) -> Self {
Self { h }
}

// check the proof:
// a+h*e = g*z ==>
// g*r + (g*w)*e = g*(we+r) ==>
// g*r * g*(we) = g*(we+r) ==>
// g*(we+r) = g*(we+r)
//
// NOTE:
// a = g*r
// z = we+r
// h = g*w
pub fn verify(&self, proof: &Proof<E>) {
// todo meet bug.
let lhs = proof.a + (self.h * proof.e);
let rhs = E::G1::generator() * proof.z;
assert_eq!(lhs, rhs, "Verifier: verify failed.")
}
}
31 changes: 31 additions & 0 deletions 12_sigma_protocol/src/transcript.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#![allow(clippy::map_flatten)]
#![allow(clippy::ptr_arg)]
use bls12_381::Scalar;
use ff::{Field, PrimeField};

pub mod default;

pub trait Transcript<F: PrimeField> {
fn append(&mut self, new_data: &[u8]);

fn challenge(&mut self) -> F;
}

#[cfg(test)]
mod test {
use super::*;
use crate::transcript::default::Keccak256Transcript;
use bls12_381::Scalar;
use ff::Field;

#[test]
fn test_challenge() {
let mut transcript_1 = Keccak256Transcript::<Scalar>::default();
let challenge_1 = transcript_1.challenge();

let mut transcript_2 = Keccak256Transcript::<Scalar>::default();
let challenge_2 = transcript_2.challenge();

assert_eq!(challenge_2, challenge_1);
}
}
38 changes: 38 additions & 0 deletions 12_sigma_protocol/src/transcript/default.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use crate::transcript::Transcript;
use bls12_381::Scalar;
use ff::{Field, PrimeField};
use sha3::{Digest, Keccak256};
use std::marker::PhantomData;
use std::net::UdpSocket;

pub struct Keccak256Transcript<F: PrimeField> {
hasher: Keccak256,
_marker: PhantomData<F>,
}

impl<F: PrimeField> Transcript<F> for Keccak256Transcript<F> {
fn append(&mut self, new_data: &[u8]) {
self.hasher.update(&mut new_data.to_owned());
}

// auto append and gen challenge
fn challenge(&mut self) -> F {
self.append(&[1]);

let mut result_hash = [0_u8; 32];
result_hash.copy_from_slice(&self.hasher.finalize_reset());
result_hash.reverse();
self.hasher.update(result_hash);
let sum = result_hash.to_vec().iter().map(|&b| b as u128).sum();
F::from_u128(sum)
}
}

impl<F: PrimeField> Default for Keccak256Transcript<F> {
fn default() -> Self {
Self {
hasher: Keccak256::new(),
_marker: Default::default(),
}
}
}
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ members = [
"5_ni_sumcheck",
"7_low_degree_test",
"7_Merkle_tree_commtment",
"12_sigma_protocol",
"12_pedersen_commitment",
"15_kzg",
]

Expand Down

0 comments on commit aade593

Please sign in to comment.