From 28081bd72c06f645683cec2bf20f93f7bedd2de3 Mon Sep 17 00:00:00 2001 From: aniampio Date: Mon, 28 Mar 2022 17:45:39 +0100 Subject: [PATCH] Move signature related structs and functions to utils --- .../src/scheme/aggregation.rs | 4 +- common/nym-compact-ecash/src/scheme/mod.rs | 106 +-------------- common/nym-compact-ecash/src/scheme/spend.rs | 0 .../src/scheme/withdrawal.rs | 3 +- common/nym-compact-ecash/src/tests/e2e.rs | 3 +- common/nym-compact-ecash/src/utils.rs | 122 ++++++++++++++++-- 6 files changed, 121 insertions(+), 117 deletions(-) delete mode 100644 common/nym-compact-ecash/src/scheme/spend.rs diff --git a/common/nym-compact-ecash/src/scheme/aggregation.rs b/common/nym-compact-ecash/src/scheme/aggregation.rs index e8be02d918..0697795b1e 100644 --- a/common/nym-compact-ecash/src/scheme/aggregation.rs +++ b/common/nym-compact-ecash/src/scheme/aggregation.rs @@ -8,11 +8,11 @@ use itertools::Itertools; use crate::Attribute; use crate::error::{CompactEcashError, Result}; -use crate::scheme::{PartialSignature, PartialWallet, Signature, SignatureShare, SignerIndex, Wallet}; +use crate::scheme::{PartialWallet, Wallet}; use crate::scheme::keygen::{SecretKeyUser, VerificationKeyAuth}; use crate::scheme::setup::Parameters; use crate::scheme::withdrawal::RequestInfo; -use crate::utils::{check_bilinear_pairing, perform_lagrangian_interpolation_at_origin}; +use crate::utils::{check_bilinear_pairing, PartialSignature, perform_lagrangian_interpolation_at_origin, Signature, SignatureShare, SignerIndex}; pub(crate) trait Aggregatable: Sized { fn aggregate(aggregatable: &[Self], indices: Option<&[SignerIndex]>) -> Result; diff --git a/common/nym-compact-ecash/src/scheme/mod.rs b/common/nym-compact-ecash/src/scheme/mod.rs index eca086e67e..f75f78b253 100644 --- a/common/nym-compact-ecash/src/scheme/mod.rs +++ b/common/nym-compact-ecash/src/scheme/mod.rs @@ -10,118 +10,14 @@ use crate::error::{CompactEcashError, Result}; use crate::proofs::proof_spend::{SpendInstance, SpendProof, SpendWitness}; use crate::scheme::keygen::{SecretKeyUser, VerificationKeyAuth}; use crate::scheme::setup::Parameters; -use crate::traits::Bytable; -use crate::utils::{check_bilinear_pairing, hash_to_scalar, try_deserialize_g1_projective}; +use crate::utils::{check_bilinear_pairing, hash_to_scalar, Signature, SignerIndex, try_deserialize_g1_projective}; pub mod aggregation; pub mod keygen; pub mod setup; -pub mod spend; pub mod withdrawal; pub mod identify; -pub type SignerIndex = u64; - -#[derive(Debug, Clone, Copy)] -#[cfg_attr(test, derive(PartialEq))] -pub struct Signature(pub(crate) G1Projective, pub(crate) G1Projective); - -pub type PartialSignature = Signature; - -impl TryFrom<&[u8]> for Signature { - type Error = CompactEcashError; - - fn try_from(bytes: &[u8]) -> Result { - if bytes.len() != 96 { - return Err(CompactEcashError::Deserialization(format!( - "Signature must be exactly 96 bytes, got {}", - bytes.len() - ))); - } - - let sig1_bytes: &[u8; 48] = &bytes[..48].try_into().expect("Slice size != 48"); - let sig2_bytes: &[u8; 48] = &bytes[48..].try_into().expect("Slice size != 48"); - - let sig1 = try_deserialize_g1_projective( - sig1_bytes, - CompactEcashError::Deserialization("Failed to deserialize compressed sig1".to_string()), - )?; - - let sig2 = try_deserialize_g1_projective( - sig2_bytes, - CompactEcashError::Deserialization("Failed to deserialize compressed sig2".to_string()), - )?; - - Ok(Signature(sig1, sig2)) - } -} - -impl Signature { - pub(crate) fn sig1(&self) -> &G1Projective { - &self.0 - } - - pub(crate) fn sig2(&self) -> &G1Projective { - &self.1 - } - - pub fn randomise(&self, params: &Parameters) -> (Signature, Scalar) { - let r = params.random_scalar(); - let r_prime = params.random_scalar(); - let h_prime = self.0 * r_prime; - let s_prime = (self.1 * r_prime) + (h_prime * r); - (Signature(h_prime, s_prime), r) - } - - pub fn to_bytes(self) -> [u8; 96] { - let mut bytes = [0u8; 96]; - bytes[..48].copy_from_slice(&self.0.to_affine().to_compressed()); - bytes[48..].copy_from_slice(&self.1.to_affine().to_compressed()); - bytes - } - - pub fn from_bytes(bytes: &[u8]) -> Result { - Signature::try_from(bytes) - } -} - -impl Bytable for Signature { - fn to_byte_vec(&self) -> Vec { - self.to_bytes().to_vec() - } - - fn try_from_byte_slice(slice: &[u8]) -> Result { - Signature::from_bytes(slice) - } -} - - -#[derive(Debug)] -#[cfg_attr(test, derive(PartialEq))] -pub struct BlindedSignature(G1Projective, G1Projective); - -pub struct SignatureShare { - signature: Signature, - index: SignerIndex, -} - -impl SignatureShare { - pub fn new(signature: Signature, index: SignerIndex) -> Self { - SignatureShare { signature, index } - } - - pub fn signature(&self) -> &Signature { - &self.signature - } - - pub fn index(&self) -> SignerIndex { - self.index - } - - // pub fn aggregate(shares: &[Self]) -> Result { - // aggregate_signature_shares(shares) - // } -} pub struct PartialWallet { sig: Signature, diff --git a/common/nym-compact-ecash/src/scheme/spend.rs b/common/nym-compact-ecash/src/scheme/spend.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/common/nym-compact-ecash/src/scheme/withdrawal.rs b/common/nym-compact-ecash/src/scheme/withdrawal.rs index 0d9821aaae..52bfa7a685 100644 --- a/common/nym-compact-ecash/src/scheme/withdrawal.rs +++ b/common/nym-compact-ecash/src/scheme/withdrawal.rs @@ -3,10 +3,11 @@ use group::{Curve, GroupEncoding}; use crate::error::{CompactEcashError, Result}; use crate::proofs::proof_withdrawal::{WithdrawalReqInstance, WithdrawalReqProof, WithdrawalReqWitness}; -use crate::scheme::{BlindedSignature, PartialWallet, Signature}; use crate::scheme::keygen::{PublicKeyUser, SecretKeyAuth, SecretKeyUser, VerificationKeyAuth}; use crate::scheme::keygen::ttp_keygen; +use crate::scheme::PartialWallet; use crate::scheme::setup::Parameters; +use crate::utils::{BlindedSignature, Signature}; use crate::utils::{check_bilinear_pairing, hash_g1}; pub struct WithdrawalRequest { diff --git a/common/nym-compact-ecash/src/tests/e2e.rs b/common/nym-compact-ecash/src/tests/e2e.rs index e8d22ca078..cdf5c655b5 100644 --- a/common/nym-compact-ecash/src/tests/e2e.rs +++ b/common/nym-compact-ecash/src/tests/e2e.rs @@ -1,14 +1,15 @@ use itertools::izip; use crate::error::CompactEcashError; -use crate::scheme::{PartialWallet, SignatureShare}; use crate::scheme::aggregation::{aggregate_signature_shares, aggregate_verification_keys, aggregate_wallets}; use crate::scheme::keygen::{ generate_keypair_user, PublicKeyUser, SecretKeyUser, ttp_keygen, VerificationKeyAuth, }; +use crate::scheme::PartialWallet; use crate::scheme::PayInfo; use crate::scheme::setup::Parameters; use crate::scheme::withdrawal::{issue_verify, issue_wallet, withdrawal_request}; +use crate::utils::SignatureShare; #[test] fn main() -> Result<(), CompactEcashError> { diff --git a/common/nym-compact-ecash/src/utils.rs b/common/nym-compact-ecash/src/utils.rs index e9b9cb35ce..f9d7478ab2 100644 --- a/common/nym-compact-ecash/src/utils.rs +++ b/common/nym-compact-ecash/src/utils.rs @@ -3,19 +3,19 @@ use core::iter::Sum; use core::ops::Mul; -use std::convert::TryInto; +use std::convert::{TryFrom, TryInto}; use std::ops::Neg; -use bls12_381::hash_to_curve::{ExpandMsgXmd, HashToCurve, HashToField}; use bls12_381::{ - multi_miller_loop, G1Affine, G1Projective, G2Affine, G2Prepared, G2Projective, Scalar, + G1Affine, G1Projective, G2Affine, G2Prepared, G2Projective, multi_miller_loop, Scalar, }; +use bls12_381::hash_to_curve::{ExpandMsgXmd, HashToCurve, HashToField}; use ff::Field; -use group::Group; +use group::{Curve, Group}; use crate::error::{CompactEcashError, Result}; use crate::scheme::setup::Parameters; -use crate::scheme::SignerIndex; +use crate::traits::Bytable; pub struct Polynomial { coefficients: Vec, @@ -85,9 +85,9 @@ pub(crate) fn perform_lagrangian_interpolation_at_origin( points: &[SignerIndex], values: &[T], ) -> Result -where - T: Sum, - for<'a> &'a T: Mul, + where + T: Sum, + for<'a> &'a T: Mul, { if points.is_empty() || values.is_empty() { return Err(CompactEcashError::Interpolation( @@ -197,6 +197,112 @@ pub fn check_bilinear_pairing(p: &G1Affine, q: &G2Prepared, r: &G1Affine, s: &G2 multi_miller.final_exponentiation().is_identity().into() } + +pub type SignerIndex = u64; + +#[derive(Debug, Clone, Copy)] +#[cfg_attr(test, derive(PartialEq))] +pub struct Signature(pub(crate) G1Projective, pub(crate) G1Projective); + +pub type PartialSignature = Signature; + +impl TryFrom<&[u8]> for Signature { + type Error = CompactEcashError; + + fn try_from(bytes: &[u8]) -> Result { + if bytes.len() != 96 { + return Err(CompactEcashError::Deserialization(format!( + "Signature must be exactly 96 bytes, got {}", + bytes.len() + ))); + } + + let sig1_bytes: &[u8; 48] = &bytes[..48].try_into().expect("Slice size != 48"); + let sig2_bytes: &[u8; 48] = &bytes[48..].try_into().expect("Slice size != 48"); + + let sig1 = try_deserialize_g1_projective( + sig1_bytes, + CompactEcashError::Deserialization("Failed to deserialize compressed sig1".to_string()), + )?; + + let sig2 = try_deserialize_g1_projective( + sig2_bytes, + CompactEcashError::Deserialization("Failed to deserialize compressed sig2".to_string()), + )?; + + Ok(Signature(sig1, sig2)) + } +} + +impl Signature { + pub(crate) fn sig1(&self) -> &G1Projective { + &self.0 + } + + pub(crate) fn sig2(&self) -> &G1Projective { + &self.1 + } + + pub fn randomise(&self, params: &Parameters) -> (Signature, Scalar) { + let r = params.random_scalar(); + let r_prime = params.random_scalar(); + let h_prime = self.0 * r_prime; + let s_prime = (self.1 * r_prime) + (h_prime * r); + (Signature(h_prime, s_prime), r) + } + + pub fn to_bytes(self) -> [u8; 96] { + let mut bytes = [0u8; 96]; + bytes[..48].copy_from_slice(&self.0.to_affine().to_compressed()); + bytes[48..].copy_from_slice(&self.1.to_affine().to_compressed()); + bytes + } + + pub fn from_bytes(bytes: &[u8]) -> Result { + Signature::try_from(bytes) + } +} + +impl Bytable for Signature { + fn to_byte_vec(&self) -> Vec { + self.to_bytes().to_vec() + } + + fn try_from_byte_slice(slice: &[u8]) -> Result { + Signature::from_bytes(slice) + } +} + + +#[derive(Debug)] +#[cfg_attr(test, derive(PartialEq))] +pub struct BlindedSignature(pub(crate) G1Projective, pub(crate) G1Projective); + + +pub struct SignatureShare { + signature: Signature, + index: SignerIndex, +} + +impl SignatureShare { + pub fn new(signature: Signature, index: SignerIndex) -> Self { + SignatureShare { signature, index } + } + + pub fn signature(&self) -> &Signature { + &self.signature + } + + pub fn index(&self) -> SignerIndex { + self.index + } + + // pub fn aggregate(shares: &[Self]) -> Result { + // aggregate_signature_shares(shares) + // } +} + + #[cfg(test)] mod tests { use rand::RngCore;