Skip to content

Commit

Permalink
Update Readme. Add code level documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
AlvinHon committed Nov 12, 2024
1 parent db3c1f4 commit 62630f2
Show file tree
Hide file tree
Showing 11 changed files with 98 additions and 5 deletions.
39 changes: 38 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,41 @@

Rust implementation of commuting signatures, a primitive introduced in the paper [Commuting Signatures and Verifiable Encryption and an Application to Non-Interactively Delegatable Credentials](https://eprint.iacr.org/2010/233.pdf).

> a signer can encrypt both signature and message and prove validity; more importantly, given a ciphertext, a signer can create a verifiably encrypted signature on the encrypted message; thus signing and encrypting commute.
> a signer can encrypt both signature and message and prove validity; more importantly, given a ciphertext, a signer can create a verifiably encrypted signature on the encrypted message; thus signing and encrypting commute.
## Verifiable Encryption

The scheme uses commitment scheme as an encryption, and a zero knowledge proof to verify the committed (or encrypted) values are actually the message being signed or the signature on that message.

```rust ignore
// public parameters
let params = Params::<E>::rand(rng);
let signer = Signer::rand(rng);
let verifier = signer.verifier(&params);

// the value being signed
let value = Fr::rand(rng);

// ciphertexts are the commitments and the ZK proofs.
let (message, signature, ciphertexts) = signer.sign(rng, &params, value);

// verify signature
assert!(verifier.verify(&params, &message, &signature));

// verify ciphertexts
assert!(verifier.verify_ciphertexts(&params, &ciphertexts));
```

## Signature on the encrypted message

```rust ignore
// Here is another signer. You can also use the same signer.
let signer2 = Signer::rand(rng);
let verifier2 = signer2.verifier(&params);

// sign on the encrypted message, output another ciphertexts that contains commitment to the signature
let ciphertexts2 = signer2.sign_on_ciphertexts(rng, &params, &ciphertexts);

// verify different ciphertexts
assert!(verifier2.verify_ciphertexts(&params, &ciphertexts2));
```
1 change: 1 addition & 0 deletions src/automorphic_signature/params.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use ark_ec::pairing::Pairing;
use ark_std::{rand::Rng, UniformRand};

#[derive(Clone, Debug)]
pub struct Params<E: Pairing> {
pub g: <E as Pairing>::G1Affine,
pub h: <E as Pairing>::G2Affine,
Expand Down
6 changes: 5 additions & 1 deletion src/ciphertexts.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
//! Defines the [Ciphertexts] struct representing verifiable encrypted message and signature.
use ark_ec::pairing::Pairing;

use crate::{commit::Commitment, proofs::Proofs, sigcom::SigCommitment};

/// Contains the commitments to the message and signature, with proofs for the validity of the committed
/// Verifiable encrypted message and signature, represented by the commitments
/// to the message and signature, with proofs for the validity of the committed
/// message and signature.
#[derive(Clone, Debug)]
pub struct Ciphertexts<E: Pairing> {
pub(crate) commitment: Commitment<E>,
pub(crate) sig_commitment: SigCommitment<E>,
Expand Down
9 changes: 9 additions & 0 deletions src/commit.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
//! Defines the `Commitment` struct, which implements message commitment and its randomization.
use ark_ec::pairing::Pairing;
use ark_std::{rand::Rng, UniformRand};
use gs_ppe::{Com, Proof, Variable};
use std::ops::Mul;

use crate::{equations, randomness::CommitRandomness, Message, Params};

/// Contains the commitments to the message, with proofs for the validity of the committed.
/// Provides functions `Com_M` and `RdCom_M`, for committing to a message and randomizing the
/// commitment respectively.
#[derive(Clone, Debug)]
pub struct Commitment<E: Pairing> {
pub(crate) c_m: Com<<E as Pairing>::G1>,
Expand All @@ -20,6 +25,8 @@ pub struct Commitment<E: Pairing> {
}

impl<E: Pairing> Commitment<E> {
/// The function `Com_M` defined in section 8.1 of the paper.
/// Commit to a message and output commitments (verifiable encrypted) with proofs.
pub fn new<R: Rng>(
rng: &mut R,
pp: &Params<E>,
Expand Down Expand Up @@ -69,6 +76,8 @@ impl<E: Pairing> Commitment<E> {
}
}

/// The function `RdCom_M` defined in section 8.1 of the paper.
/// Randomize the commitments and proofs of this commitment.
pub fn randomize<R: Rng>(&mut self, rng: &mut R, pp: &Params<E>) -> CommitRandomness<E> {
let scalar_t_prime = E::ScalarField::rand(rng);
// it is still c_p_cup now in this line, but will be mutated later: c_p_cup -> c_p'
Expand Down
22 changes: 22 additions & 0 deletions src/equations.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Defines equations for the proof system.
use ark_ec::{
pairing::{Pairing, PairingOutput},
AffineRepr,
Expand All @@ -10,6 +12,9 @@ use crate::Params;

/// E_DH: e(G^-1, Y) e(X, H) = 1
/// It is equivalent to E_r.
///
/// Formula (10) in section 8.1 of the paper.
/// Same as the formula (12) `E_r` in section 8.2 of the paper.
pub(crate) fn equation_dh<E: Pairing>(pp: &Params<E>) -> Equation<E> {
Equation::<E>::new(
vec![pp.pps.g.mul(E::ScalarField::one().neg()).into()],
Expand All @@ -18,7 +23,10 @@ pub(crate) fn equation_dh<E: Pairing>(pp: &Params<E>) -> Equation<E> {
PairingOutput::zero(),
)
}

/// E_u: e(T^-1, Y) e(X, H^-1) = e(U, H)^-1
///
/// Formula (11) in section 8.1 of the paper.
pub(crate) fn equation_u<E: Pairing>(pp: &Params<E>, u: &<E as Pairing>::G1Affine) -> Equation<E> {
Equation::<E>::new(
vec![pp.pps.t.mul(E::ScalarField::one().neg()).into()],
Expand All @@ -29,6 +37,8 @@ pub(crate) fn equation_u<E: Pairing>(pp: &Params<E>, u: &<E as Pairing>::G1Affin
}

/// Define E_at(A; D) : e(A, Y) e(A, D) = 1, where A and D are variables X1 and Y1.
///
/// Formula (14) in section 8.2 of the paper.
pub(crate) fn equation_at<E: Pairing>(y: <E as Pairing>::G2Affine) -> Equation<E> {
// From GS Proof notation:
// e(A1, Y1) e(X1, B1) e(X1, Y1)^1
Expand All @@ -46,6 +56,8 @@ pub(crate) fn equation_at<E: Pairing>(y: <E as Pairing>::G2Affine) -> Equation<E

/// Define E_a(A, M; S, D) : e(T^-1, S) e(A, Y) e(M, H^-1) e(A, D) = e(K, H),
/// where A, M, S, and D are variables X1, X2, Y1, and Y2.
///
/// Formula (12) in section 8.2 of the paper.
pub(crate) fn equation_a<E: Pairing>(pp: &Params<E>, y: <E as Pairing>::G2Affine) -> Equation<E> {
// From GS Proof notation:
// e(A1, Y1) e(A2, Y2) e(X1, B1) e(X2, B2) e(X1, Y2)^1
Expand All @@ -70,6 +82,8 @@ pub(crate) fn equation_a<E: Pairing>(pp: &Params<E>, y: <E as Pairing>::G2Affine
}

/// E_b: e(F^-1, Y) e(X, H) = 1
///
/// Formula (12) in section 8.2 of the paper.
pub(crate) fn equation_b<E: Pairing>(pp: &Params<E>) -> Equation<E> {
Equation::<E>::new(
vec![pp.pps.f.mul(E::ScalarField::one().neg()).into()],
Expand All @@ -83,6 +97,8 @@ pub(crate) fn equation_b<E: Pairing>(pp: &Params<E>) -> Equation<E> {
/// where A, S, and D are variables X1, Y1, and Y2.
///
/// This should be used in function `AdPrC` but we dont know `m`. So we compute the target from LHS of the equation.
///
/// Formula in section 8.3 of the paper.
pub(crate) fn equation_a_tide_from_lhs<E: Pairing>(
pp: &Params<E>,
s: <E as Pairing>::G2Affine,
Expand All @@ -109,6 +125,8 @@ pub(crate) fn equation_a_tide_from_lhs<E: Pairing>(
/// where A, S, and D are variables X1, Y1, and Y2.
///
/// This should be used in function `AdPrC_M`. As `m` is known, we can compute the target from RHS of the equation.
///
/// Formula in section 8.3 of the paper.
pub(crate) fn equation_a_tide_from_rhs<E: Pairing>(
pp: &Params<E>,
y: <E as Pairing>::G2Affine,
Expand All @@ -131,6 +149,8 @@ pub(crate) fn equation_a_tide_from_rhs<E: Pairing>(

/// Define E_a_bar(M) : e(M, H^-1) = e(A, Y + D)^-1 e(K, H) e(T, S),
/// where M is variable X1.
///
/// Formula in section 8.3 of the paper.
pub(crate) fn equation_a_bar_from_lhs<E: Pairing>(
pp: &Params<E>,
m: <E as Pairing>::G1Affine,
Expand All @@ -145,6 +165,8 @@ pub(crate) fn equation_a_bar_from_lhs<E: Pairing>(

/// Define E_a_bar(M) : e(M, H^-1) = e(A, Y + D)^-1 e(K, H) e(T, S),
/// where M is variable X1.
///
/// Formula in section 8.3 of the paper.
pub(crate) fn equation_a_bar_from_rhs<E: Pairing>(
pp: &Params<E>,
y: <E as Pairing>::G2Affine,
Expand Down
5 changes: 5 additions & 0 deletions src/params.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
//! Defines the [Params] struct representing the public parameters for the commuting signature scheme.
use ark_ec::pairing::Pairing;
use ark_std::rand::Rng;
use gs_ppe::CommitmentKeys;

use crate::automorphic_signature;

/// The parameters for the commuting signature scheme. It consists of the parameters for the automorphic
/// signature scheme and the commitment keys from the GS Proof System.
#[derive(Clone, Debug)]
pub struct Params<E: Pairing> {
pub(crate) pps: automorphic_signature::Params<E>,
pub(crate) cks: CommitmentKeys<E>,
Expand Down
5 changes: 4 additions & 1 deletion src/proofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ use crate::{
Message, Params,
};

/// (pi_*, pi_b, pi_r)
/// (pi_*, pi_b, pi_r), the proofs commonly used in the proof adaptation alogrithms.
#[derive(Clone, Debug)]
pub struct Proofs<E: Pairing>(pub Proof<E>, pub Proof<E>, pub Proof<E>);

/// The proofs (pi_a, pi_b, pi_r), used in the proof adaptation algorithms for the
/// equations `E_a`, `E_b`, and `E_r`.
#[derive(Clone, Debug)]
pub struct AdaptProof<E: Pairing> {
pi_a: Proof<E>,
Expand Down
6 changes: 4 additions & 2 deletions src/randomness.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
//! Defines the [CommitRandomness] and [SigRandomness] structs, which represent the randomness used in the message and signature commitments.
use std::ops::Add;

use ark_ec::pairing::Pairing;
use ark_std::{rand::Rng, UniformRand};
use gs_ppe::Randomness;

/// (tau, mu, nu, rho, sigma)
/// (tau, mu, nu, rho, sigma), the randomness used in the message commitment.
#[derive(Copy, Clone, Debug)]
pub struct CommitRandomness<E: Pairing>(
pub E::ScalarField,
Expand Down Expand Up @@ -39,7 +41,7 @@ impl<E: Pairing> Add for CommitRandomness<E> {
}
}

/// (alpha, beta, delta, rho, sigma)
/// (alpha, beta, delta, rho, sigma), the randomness used in the signature commitment.
#[derive(Copy, Clone, Debug)]
pub struct SigRandomness<E: Pairing>(
pub Randomness<<E as Pairing>::G1>,
Expand Down
6 changes: 6 additions & 0 deletions src/sigcom.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Defines the `SigCom` algorithm to commit on a signature, and the related structures.
use ark_ec::pairing::Pairing;
use ark_std::rand::Rng;
use gs_ppe::{Com, Proof, Randomness, Variable};
Expand Down Expand Up @@ -94,6 +96,7 @@ pub fn sig_com<E: Pairing, R: Rng>(
}

/// Commitment on a signature = (A, B, D, R, S).
#[derive(Clone, Debug)]
pub struct SigCommitment<E: Pairing> {
// (c_a, c_b, c_d, c_r, c_s) are commitments on the actual signature = (A, B, D, R, S).
pub(crate) c_a: Com<<E as Pairing>::G1>,
Expand Down Expand Up @@ -174,12 +177,15 @@ impl<E: Pairing> PreSignature<E> {
}
}

/// Represents a state that the signature will/is expected to be committed with a randomness.
pub struct PrecommitSignature<E: Pairing> {
pub signature: Signature<E>,
pub randomness: SigRandomness<E>,
}

impl<E: Pairing> PrecommitSignature<E> {
/// Straightforwardly commit on the signature by the given randomness, by using the commitment scheme
/// in GS proof system.
pub fn commit(&self, pp: &Params<E>) -> SigCommitment<E> {
let Signature { a, b, d, r, s } = self.signature;
let SigRandomness(alpha, beta, delta, rho, sigma) = self.randomness;
Expand Down
2 changes: 2 additions & 0 deletions src/signer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Defines the `Signer` struct and its methods.
use ark_ec::pairing::Pairing;
use ark_std::rand::Rng;

Expand Down
2 changes: 2 additions & 0 deletions src/verifier.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Defines the `Verifier` struct and its methods.
//!
use ark_ec::pairing::Pairing;

use crate::{
Expand Down

0 comments on commit 62630f2

Please sign in to comment.