Skip to content

Commit

Permalink
Init with implementation of automorphic signature
Browse files Browse the repository at this point in the history
  • Loading branch information
AlvinHon committed Nov 2, 2024
0 parents commit a85f53d
Show file tree
Hide file tree
Showing 9 changed files with 495 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
24 changes: 24 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "commuting-signature"
version = "0.1.0"
description = ""
authors = ["[email protected]"]
license = "MIT/Apache-2.0"
repository = "https://github.com/AlvinHon/commuting-signature"
categories = ["cryptography"]
keywords = ["cryptography"]
edition = "2021"

[lib]
name = "commuting_signature"
path = "src/lib.rs"

[dependencies]
ark-ec = "0.4"
ark-ff = "0.4"
ark-serialize = "0.4"
ark-std = "0.4"
gs-ppe = { path = "../gs-ppe" }

[dev-dependencies]
ark-bls12-381 = "0.4"
52 changes: 52 additions & 0 deletions src/automorphic_signature/message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use super::{DHGenerators, VerifyingKey};
use ark_ec::pairing::Pairing;
use std::ops::{Add, Mul};

pub struct Message<E: Pairing>(
pub(crate) <E as Pairing>::G1Affine,
pub(crate) <E as Pairing>::G2Affine,
);

impl<E: Pairing> Message<E> {
pub fn new<G: DHGenerators<E>>(grs: &G, m: E::ScalarField) -> Self {
Self(grs.g().mul(m).into(), grs.h().mul(m).into())
}
}

impl<E: Pairing> From<&VerifyingKey<E>> for Message<E> {
fn from(vk: &VerifyingKey<E>) -> Self {
Self(vk.0, vk.1)
}
}

impl<E: Pairing> Add for Message<E> {
type Output = Self;

fn add(self, other: Self) -> Self::Output {
Message((self.0 + other.0).into(), (self.1 + other.1).into())
}
}

impl<E: Pairing> Add for &Message<E> {
type Output = Message<E>;

fn add(self, other: Self) -> Self::Output {
Message((self.0 + other.0).into(), (self.1 + other.1).into())
}
}

impl<E: Pairing> Mul<E::ScalarField> for Message<E> {
type Output = Self;

fn mul(self, scalar: E::ScalarField) -> Self {
Self(self.0.mul(scalar).into(), self.1.mul(scalar).into())
}
}

impl<E: Pairing> Mul<E::ScalarField> for &Message<E> {
type Output = Message<E>;

fn mul(self, scalar: E::ScalarField) -> Self::Output {
Message(self.0.mul(scalar).into(), self.1.mul(scalar).into())
}
}
29 changes: 29 additions & 0 deletions src/automorphic_signature/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
pub mod message;
pub use message::Message;

pub mod params;
pub use params::{DHGenerators, Params, ParamsEx};

pub mod sign;
pub use sign::SigningKey;

pub mod verify;
pub use verify::VerifyingKey;

pub mod signature;
pub use signature::{Signature, SignatureEx, Signatures};

use ark_ec::pairing::Pairing;
use ark_std::{rand::Rng, UniformRand};
use std::ops::Mul;

pub fn key_gen<E: Pairing, R: Rng, G: DHGenerators<E>>(
rng: &mut R,
grs: &G,
) -> (VerifyingKey<E>, SigningKey<E>) {
let x = E::ScalarField::rand(rng);
(
VerifyingKey(grs.g().mul(x).into(), grs.h().mul(x).into()),
SigningKey { x },
)
}
73 changes: 73 additions & 0 deletions src/automorphic_signature/params.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use ark_ec::pairing::Pairing;
use ark_std::{rand::Rng, UniformRand};

pub struct Params<E: Pairing> {
pub g: <E as Pairing>::G1Affine,
pub h: <E as Pairing>::G2Affine,

// additional generators
pub f: <E as Pairing>::G1Affine,
pub k: <E as Pairing>::G1Affine,
pub t: <E as Pairing>::G1Affine,
}

impl<E: Pairing> Params<E> {
pub fn rand<R: Rng>(rng: &mut R) -> Self {
Self {
g: <E as Pairing>::G1Affine::rand(rng),
h: <E as Pairing>::G2Affine::rand(rng),
f: <E as Pairing>::G1Affine::rand(rng),
k: <E as Pairing>::G1Affine::rand(rng),
t: <E as Pairing>::G1Affine::rand(rng),
}
}
}

pub struct ParamsEx<E: Pairing> {
pub g: <E as Pairing>::G1Affine,
pub h: <E as Pairing>::G2Affine,

// additional generators
pub f: <E as Pairing>::G1Affine,
pub k: <E as Pairing>::G1Affine,
pub l: <E as Pairing>::G1Affine,
pub t: <E as Pairing>::G1Affine,
}

impl<E: Pairing> ParamsEx<E> {
pub fn rand<R: Rng>(rng: &mut R) -> Self {
Self {
g: <E as Pairing>::G1Affine::rand(rng),
h: <E as Pairing>::G2Affine::rand(rng),
f: <E as Pairing>::G1Affine::rand(rng),
k: <E as Pairing>::G1Affine::rand(rng),
l: <E as Pairing>::G1Affine::rand(rng),
t: <E as Pairing>::G1Affine::rand(rng),
}
}
}

pub trait DHGenerators<E: Pairing> {
fn g(&self) -> <E as Pairing>::G1Affine;
fn h(&self) -> <E as Pairing>::G2Affine;
}

impl<E: Pairing> DHGenerators<E> for Params<E> {
fn g(&self) -> <E as Pairing>::G1Affine {
self.g
}

fn h(&self) -> <E as Pairing>::G2Affine {
self.h
}
}

impl<E: Pairing> DHGenerators<E> for ParamsEx<E> {
fn g(&self) -> <E as Pairing>::G1Affine {
self.g
}

fn h(&self) -> <E as Pairing>::G2Affine {
self.h
}
}
154 changes: 154 additions & 0 deletions src/automorphic_signature/sign.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
use ark_ec::pairing::Pairing;
use ark_ff::One;
use ark_std::{rand::Rng, UniformRand};
use std::ops::Mul;

use super::{key_gen, message::Message, Params, ParamsEx, Signature, SignatureEx, Signatures};

pub struct SigningKey<E: Pairing> {
pub(crate) x: E::ScalarField,
}

impl<E: Pairing> SigningKey<E> {
/// Signing function `Sign` defined in Scheme 1. Signs on a message (M, N) = (G^m, H^m) in DH.
///
/// ## Example
///
/// ```
/// use ark_bls12_381::Bls12_381 as E;
/// use ark_ec::pairing::Pairing;
/// use ark_std::{test_rng, UniformRand};
///
/// use commuting_signature::automorphic_signature::{Message, Params, key_gen};
///
/// type G1Affine = <E as Pairing>::G1Affine;
/// type Fr = <E as Pairing>::ScalarField;
///
/// let rng = &mut test_rng();
///
/// let pp = Params::<E>::rand(rng);
/// let (vk, sk) = key_gen(rng, &pp);
///
/// let mn = Message::new(&pp, Fr::rand(rng));
/// let sig = sk.sign(rng, &pp, &mn);
///
/// assert!(vk.verify(&pp, &mn, &sig));
/// ```
pub fn sign<R: Rng>(&self, rng: &mut R, pp: &Params<E>, mn: &Message<E>) -> Signature<E> {
let m = &mn.0;

let rand_c = E::ScalarField::rand(rng);
let rand_r = E::ScalarField::rand(rng);

let a = {
let exp = E::ScalarField::one() / (self.x + rand_c);
(pp.k + pp.t.mul(rand_r) + m).mul(exp)
}
.into();
let b = pp.f.mul(rand_c).into();
let d = pp.h.mul(rand_c).into();
let r = pp.g.mul(rand_r).into();
let s = pp.h.mul(rand_r).into();

Signature { a, b, d, r, s }
}

/// Signing function `Sign` defined in Scheme 1. Signs on two messages (M, N) and
/// (V, W) at once.
///
/// ## Example
///
/// ```
/// use ark_bls12_381::Bls12_381 as E;
/// use ark_ec::pairing::Pairing;
/// use ark_std::{test_rng, UniformRand};
///
/// use commuting_signature::automorphic_signature::{Message, Params, key_gen};
///
/// type G1Affine = <E as Pairing>::G1Affine;
/// type Fr = <E as Pairing>::ScalarField;
///
/// let rng = &mut test_rng();
///
/// let pp = Params::<E>::rand(rng);
/// let (vk, sk) = key_gen(rng, &pp);
///
/// let mn = Message::new(&pp, Fr::rand(rng));
/// let vw = Message::new(&pp, Fr::rand(rng));
/// let sigs = sk.sign_two_messages(rng, &pp, &mn, &vw);
///
/// assert!(vk.verify_two_messages(&pp, &mn, &vw, &sigs));
/// ```
pub fn sign_two_messages<R: Rng>(
&self,
rng: &mut R,
pp: &Params<E>,
mn: &Message<E>,
vw: &Message<E>,
) -> Signatures<E> {
let (vk2, sk2) = key_gen(rng, pp);
let sig0 = self.sign(rng, pp, &Message::<E>::from(&vk2));
let sig1 = sk2.sign(rng, pp, mn);
let sig2 = sk2.sign(rng, pp, &(mn + vw));
let sig3 = sk2.sign(rng, pp, &(mn + &vw.mul(E::ScalarField::from(3u64))));

Signatures {
vk2,
sig0,
sig1,
sig2,
sig3,
}
}

/// Signing function `Sign"` defined in Scheme 2. Signs on a message (M, N) = (G^m, H^m) in DH,
/// together with a scalar `v`.
///
/// ## Example
///
/// ```
/// use ark_bls12_381::Bls12_381 as E;
/// use ark_ec::pairing::Pairing;
/// use ark_std::{test_rng, UniformRand};
///
/// use commuting_signature::automorphic_signature::{Message, ParamsEx, key_gen};
///
/// type G1Affine = <E as Pairing>::G1Affine;
/// type Fr = <E as Pairing>::ScalarField;
///
/// let rng = &mut test_rng();
///
/// let pp = ParamsEx::<E>::rand(rng);
/// let (vk, sk) = key_gen(rng, &pp);
///
/// let v = Fr::rand(rng);
/// let mn = Message::new(&pp, Fr::rand(rng));
/// let sig_ex = sk.sign_ex(rng, &pp, &v, &mn);
///
/// assert!(vk.verify_ex(&pp, &v, &mn, &sig_ex));
/// ```
pub fn sign_ex<R: Rng>(
&self,
rng: &mut R,
pp: &ParamsEx<E>,
v: &E::ScalarField,
mn: &Message<E>,
) -> SignatureEx<E> {
let m = &mn.0;

let rand_c = E::ScalarField::rand(rng);
let rand_r = E::ScalarField::rand(rng);

let a = {
let exp = E::ScalarField::one() / (self.x + rand_c);
(pp.k + pp.l.mul(v) + pp.t.mul(rand_r) + m).mul(exp)
}
.into();
let b = pp.f.mul(rand_c).into();
let d = pp.h.mul(rand_c).into();
let r = pp.g.mul(rand_r).into();
let s = pp.h.mul(rand_r).into();

SignatureEx { a, b, d, r, s }
}
}
27 changes: 27 additions & 0 deletions src/automorphic_signature/signature.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use ark_ec::pairing::Pairing;

use super::VerifyingKey;

pub struct Signature<E: Pairing> {
pub(crate) a: <E as Pairing>::G1Affine,
pub(crate) b: <E as Pairing>::G1Affine,
pub(crate) d: <E as Pairing>::G2Affine,
pub(crate) r: <E as Pairing>::G1Affine,
pub(crate) s: <E as Pairing>::G2Affine,
}

pub struct Signatures<E: Pairing> {
pub(crate) vk2: VerifyingKey<E>,
pub(crate) sig0: Signature<E>,
pub(crate) sig1: Signature<E>,
pub(crate) sig2: Signature<E>,
pub(crate) sig3: Signature<E>,
}

pub struct SignatureEx<E: Pairing> {
pub(crate) a: <E as Pairing>::G1Affine,
pub(crate) b: <E as Pairing>::G1Affine,
pub(crate) d: <E as Pairing>::G2Affine,
pub(crate) r: <E as Pairing>::G1Affine,
pub(crate) s: <E as Pairing>::G2Affine,
}
Loading

0 comments on commit a85f53d

Please sign in to comment.