-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Init with implementation of automorphic signature
- Loading branch information
0 parents
commit a85f53d
Showing
9 changed files
with
495 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }, | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
} |
Oops, something went wrong.