Skip to content

Commit

Permalink
Refactor crypto-related traits implementations in term of Public/Sign…
Browse files Browse the repository at this point in the history
…ature Bytes (#3806)

Another simple refactory to prune some duplicate code

Follow up of: #3684
  • Loading branch information
davxy authored Mar 25, 2024
1 parent ce7613a commit 9d12240
Show file tree
Hide file tree
Showing 11 changed files with 254 additions and 658 deletions.
14 changes: 13 additions & 1 deletion substrate/primitives/application-crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub use sp_core::crypto::{DeriveError, Pair, SecretStringError};
#[doc(hidden)]
pub use sp_core::{
self,
crypto::{ByteArray, CryptoType, Derive, IsWrappedBy, Public, UncheckedFrom, Wraps},
crypto::{ByteArray, CryptoType, Derive, IsWrappedBy, Public, Signature, UncheckedFrom, Wraps},
RuntimeDebug,
};

Expand Down Expand Up @@ -505,6 +505,12 @@ macro_rules! app_crypto_signature_common {
}
}

impl AsMut<[u8]> for Signature {
fn as_mut(&mut self) -> &mut [u8] {
self.0.as_mut()
}
}

impl $crate::AppSignature for Signature {
type Generic = $sig;
}
Expand All @@ -525,6 +531,12 @@ macro_rules! app_crypto_signature_common {
}
}

impl $crate::Signature for Signature {}

impl $crate::ByteArray for Signature {
const LEN: usize = <$sig>::LEN;
}

impl Signature {
/// Convert into wrapped generic signature type.
pub fn into_inner(self) -> $sig {
Expand Down
55 changes: 2 additions & 53 deletions substrate/primitives/core/src/bandersnatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,12 @@
//!
//! The primitive can operate both as a regular VRF or as an anonymized Ring VRF.
#[cfg(feature = "serde")]
use crate::crypto::Ss58Codec;
#[cfg(feature = "full_crypto")]
use crate::crypto::VrfSecret;
use crate::crypto::{
ByteArray, CryptoType, CryptoTypeId, Derive, DeriveError, DeriveJunction, Pair as TraitPair,
Public as TraitPublic, PublicBytes, SecretStringError, SignatureBytes, UncheckedFrom,
VrfPublic,
ByteArray, CryptoType, CryptoTypeId, DeriveError, DeriveJunction, Pair as TraitPair,
PublicBytes, SecretStringError, SignatureBytes, UncheckedFrom, VrfPublic,
};
#[cfg(feature = "serde")]
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
#[cfg(all(not(feature = "std"), feature = "serde"))]
use sp_std::alloc::{format, string::String};

use bandersnatch_vrfs::{CanonicalSerialize, SecretKey};
use codec::{Decode, Encode, EncodeLike, MaxEncodedLen};
Expand Down Expand Up @@ -64,42 +57,10 @@ pub struct BandersnatchTag;
/// Bandersnatch public key.
pub type Public = PublicBytes<PUBLIC_SERIALIZED_SIZE, BandersnatchTag>;

impl TraitPublic for Public {}

impl CryptoType for Public {
type Pair = Pair;
}

impl Derive for Public {}

impl sp_std::fmt::Debug for Public {
#[cfg(feature = "std")]
fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
let s = self.to_ss58check();
write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.as_ref()), &s[0..8])
}

#[cfg(not(feature = "std"))]
fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
Ok(())
}
}

#[cfg(feature = "serde")]
impl Serialize for Public {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&self.to_ss58check())
}
}

#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for Public {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Public::from_ss58check(&String::deserialize(deserializer)?)
.map_err(|e| de::Error::custom(format!("{:?}", e)))
}
}

/// Bandersnatch signature.
///
/// The signature is created via the [`VrfSecret::vrf_sign`] using [`SIGNING_CTX`] as transcript
Expand All @@ -110,18 +71,6 @@ impl CryptoType for Signature {
type Pair = Pair;
}

impl sp_std::fmt::Debug for Signature {
#[cfg(feature = "std")]
fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0))
}

#[cfg(not(feature = "std"))]
fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
Ok(())
}
}

/// The raw secret seed, which can be used to reconstruct the secret [`Pair`].
type Seed = [u8; SEED_SERIALIZED_SIZE];

Expand Down
111 changes: 5 additions & 106 deletions substrate/primitives/core/src/bls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,11 @@
//! Chaum-Pedersen proof uses the same hash-to-field specified in RFC 9380 for the field of the BLS
//! curve.
#[cfg(feature = "serde")]
use crate::crypto::Ss58Codec;
use crate::crypto::{
CryptoType, Derive, DeriveError, DeriveJunction, Pair as TraitPair, Public as TraitPublic,
PublicBytes, SecretStringError, SignatureBytes, UncheckedFrom,
CryptoType, DeriveError, DeriveJunction, Pair as TraitPair, PublicBytes, SecretStringError,
SignatureBytes, UncheckedFrom,
};

#[cfg(feature = "serde")]
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
#[cfg(all(not(feature = "std"), feature = "serde"))]
use sp_std::alloc::{format, string::String};
use sp_std::vec::Vec;

use w3f_bls::{
Expand Down Expand Up @@ -115,110 +109,13 @@ pub struct BlsTag;
/// A public key.
pub type Public<SubTag> = PublicBytes<PUBLIC_KEY_SERIALIZED_SIZE, (BlsTag, SubTag)>;

impl<T: BlsBound> From<Pair<T>> for Public<T> {
fn from(x: Pair<T>) -> Self {
x.public()
}
}

#[cfg(feature = "std")]
impl<T: BlsBound> std::str::FromStr for Public<T> {
type Err = crate::crypto::PublicError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::from_ss58check(s)
}
}

#[cfg(feature = "std")]
impl<T: BlsBound> std::fmt::Display for Public<T> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.to_ss58check())
}
}

#[cfg(feature = "std")]
impl<T: BlsBound> sp_std::fmt::Debug for Public<T> {
fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
let s = self.to_ss58check();
write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8])
}
}

#[cfg(not(feature = "std"))]
impl<T> sp_std::fmt::Debug for Public<T> {
fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
Ok(())
}
}

#[cfg(feature = "serde")]
impl<T: BlsBound> Serialize for Public<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.to_ss58check())
}
}

#[cfg(feature = "serde")]
impl<'de, T: BlsBound> Deserialize<'de> for Public<T> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Public::from_ss58check(&String::deserialize(deserializer)?)
.map_err(|e| de::Error::custom(format!("{:?}", e)))
}
}

impl<T: BlsBound> TraitPublic for Public<T> {}

impl<T> Derive for Public<T> {}

impl<T: BlsBound> CryptoType for Public<T> {
type Pair = Pair<T>;
}

/// A generic BLS signature.
pub type Signature<SubTag> = SignatureBytes<SIGNATURE_SERIALIZED_SIZE, (BlsTag, SubTag)>;

#[cfg(feature = "serde")]
impl<T> Serialize for Signature<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&array_bytes::bytes2hex("", self))
}
}

#[cfg(feature = "serde")]
impl<'de, T> Deserialize<'de> for Signature<T> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let signature_hex = array_bytes::hex2bytes(&String::deserialize(deserializer)?)
.map_err(|e| de::Error::custom(format!("{:?}", e)))?;
Signature::try_from(signature_hex.as_ref())
.map_err(|e| de::Error::custom(format!("{:?}", e)))
}
}

impl<T> sp_std::fmt::Debug for Signature<T> {
#[cfg(feature = "std")]
fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0))
}

#[cfg(not(feature = "std"))]
fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
Ok(())
}
}

impl<T: BlsBound> CryptoType for Signature<T> {
type Pair = Pair<T>;
}
Expand Down Expand Up @@ -333,8 +230,10 @@ impl<T: BlsBound> CryptoType for Pair<T> {

// Test set exercising the BLS12-377 implementation
#[cfg(test)]
mod test {
mod tests {
use super::*;
#[cfg(feature = "serde")]
use crate::crypto::Ss58Codec;
use crate::crypto::DEV_PHRASE;
use bls377::{Pair, Signature};

Expand Down
Loading

0 comments on commit 9d12240

Please sign in to comment.