mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-21 14:25:41 +00:00
Implement crypto byte array newtypes in term of a shared type (#3684)
Introduces `CryptoBytes` type defined as: ```rust pub struct CryptoBytes<const N: usize, Tag = ()>(pub [u8; N], PhantomData<fn() -> Tag>); ``` The type implements a bunch of methods and traits which are typically expected from a byte array newtype (NOTE: some of the methods and trait implementations IMO are a bit redundant, but I decided to maintain them all to not change too much stuff in this PR) It also introduces two (generic) typical consumers of `CryptoBytes`: `PublicBytes` and `SignatureBytes`. ```rust pub struct PublicTag; pub PublicBytes<const N: usize, CryptoTag> = CryptoBytes<N, (PublicTag, CryptoTag)>; pub struct SignatureTag; pub SignatureBytes<const N: usize, CryptoTag> = CryptoBytes<N, (SignatureTag, CryptoTag)>; ``` Both of them use a tag to differentiate the two types at a higher level. Downstream specializations will further specialize using a dedicated crypto tag. For example in ECDSA: ```rust pub struct EcdsaTag; pub type Public = PublicBytes<PUBLIC_KEY_SERIALIZED_SIZE, EcdsaTag>; pub type Signature = PublicBytes<PUBLIC_KEY_SERIALIZED_SIZE, EcdsaTag>; ``` Overall we have a cleaner and most importantly **consistent** code for all the types involved All these details are opaque to the end user which can use `Public` and `Signature` for the cryptos as before
This commit is contained in:
@@ -17,25 +17,22 @@
|
||||
|
||||
//! API for using a pair of crypto schemes together.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use crate::crypto::Ss58Codec;
|
||||
use crate::crypto::{
|
||||
ByteArray, CryptoType, Derive, DeriveError, DeriveJunction, Pair as PairT, Public as PublicT,
|
||||
SecretStringError, UncheckedFrom,
|
||||
PublicBytes, SecretStringError, SignatureBytes, UncheckedFrom,
|
||||
};
|
||||
|
||||
use sp_std::vec::Vec;
|
||||
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
use scale_info::TypeInfo;
|
||||
#[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_runtime_interface::pass_by::{self, PassBy, PassByInner};
|
||||
use sp_std::convert::TryFrom;
|
||||
|
||||
/// ECDSA and BLS12-377 paired crypto scheme
|
||||
#[cfg(feature = "bls-experimental")]
|
||||
pub mod ecdsa_bls377 {
|
||||
@@ -54,12 +51,20 @@ pub mod ecdsa_bls377 {
|
||||
const SIGNATURE_LEN: usize =
|
||||
ecdsa::SIGNATURE_SERIALIZED_SIZE + bls377::SIGNATURE_SERIALIZED_SIZE;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct EcdsaBls377Tag(ecdsa::EcdsaTag, bls377::Bls377Tag);
|
||||
|
||||
impl super::PairedCryptoSubTagBound for EcdsaBls377Tag {}
|
||||
|
||||
/// (ECDSA,BLS12-377) key-pair pair.
|
||||
pub type Pair = super::Pair<ecdsa::Pair, bls377::Pair, PUBLIC_KEY_LEN, SIGNATURE_LEN>;
|
||||
pub type Pair =
|
||||
super::Pair<ecdsa::Pair, bls377::Pair, PUBLIC_KEY_LEN, SIGNATURE_LEN, EcdsaBls377Tag>;
|
||||
|
||||
/// (ECDSA,BLS12-377) public key pair.
|
||||
pub type Public = super::Public<PUBLIC_KEY_LEN>;
|
||||
pub type Public = super::Public<PUBLIC_KEY_LEN, EcdsaBls377Tag>;
|
||||
|
||||
/// (ECDSA,BLS12-377) signature pair.
|
||||
pub type Signature = super::Signature<SIGNATURE_LEN>;
|
||||
pub type Signature = super::Signature<SIGNATURE_LEN, EcdsaBls377Tag>;
|
||||
|
||||
impl super::CryptoType for Public {
|
||||
type Pair = Pair;
|
||||
@@ -110,7 +115,7 @@ pub mod ecdsa_bls377 {
|
||||
let Ok(left_pub) = public.0[..ecdsa::PUBLIC_KEY_SERIALIZED_SIZE].try_into() else {
|
||||
return false
|
||||
};
|
||||
let Ok(left_sig) = sig.0[0..ecdsa::SIGNATURE_SERIALIZED_SIZE].try_into() else {
|
||||
let Ok(left_sig) = sig.0[..ecdsa::SIGNATURE_SERIALIZED_SIZE].try_into() else {
|
||||
return false
|
||||
};
|
||||
if !ecdsa::Pair::verify_prehashed(&left_sig, &msg_hash, &left_pub) {
|
||||
@@ -140,110 +145,49 @@ const SECURE_SEED_LEN: usize = 32;
|
||||
/// will need it later (such as for HDKD).
|
||||
type Seed = [u8; SECURE_SEED_LEN];
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait PairedCryptoSubTagBound {}
|
||||
#[doc(hidden)]
|
||||
pub struct PairedCryptoTag;
|
||||
|
||||
/// A public key.
|
||||
#[derive(Clone, Encode, Decode, MaxEncodedLen, TypeInfo, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Public<const LEFT_PLUS_RIGHT_LEN: usize>([u8; LEFT_PLUS_RIGHT_LEN]);
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> sp_std::hash::Hash for Public<LEFT_PLUS_RIGHT_LEN> {
|
||||
fn hash<H: sp_std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.0.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> ByteArray for Public<LEFT_PLUS_RIGHT_LEN> {
|
||||
const LEN: usize = LEFT_PLUS_RIGHT_LEN;
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> TryFrom<&[u8]> for Public<LEFT_PLUS_RIGHT_LEN> {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
|
||||
if data.len() != LEFT_PLUS_RIGHT_LEN {
|
||||
return Err(())
|
||||
}
|
||||
let mut inner = [0u8; LEFT_PLUS_RIGHT_LEN];
|
||||
inner.copy_from_slice(data);
|
||||
Ok(Public(inner))
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> AsRef<[u8; LEFT_PLUS_RIGHT_LEN]>
|
||||
for Public<LEFT_PLUS_RIGHT_LEN>
|
||||
{
|
||||
fn as_ref(&self) -> &[u8; LEFT_PLUS_RIGHT_LEN] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> AsRef<[u8]> for Public<LEFT_PLUS_RIGHT_LEN> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.0[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> AsMut<[u8]> for Public<LEFT_PLUS_RIGHT_LEN> {
|
||||
fn as_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.0[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> PassByInner for Public<LEFT_PLUS_RIGHT_LEN> {
|
||||
type Inner = [u8; LEFT_PLUS_RIGHT_LEN];
|
||||
|
||||
fn into_inner(self) -> Self::Inner {
|
||||
self.0
|
||||
}
|
||||
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
&self.0
|
||||
}
|
||||
|
||||
fn from_inner(inner: Self::Inner) -> Self {
|
||||
Self(inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> PassBy for Public<LEFT_PLUS_RIGHT_LEN> {
|
||||
type PassBy = pass_by::Inner<Self, [u8; LEFT_PLUS_RIGHT_LEN]>;
|
||||
}
|
||||
pub type Public<const LEFT_PLUS_RIGHT_LEN: usize, SubTag> =
|
||||
PublicBytes<LEFT_PLUS_RIGHT_LEN, (PairedCryptoTag, SubTag)>;
|
||||
|
||||
impl<
|
||||
LeftPair: PairT,
|
||||
RightPair: PairT,
|
||||
const LEFT_PLUS_RIGHT_PUBLIC_LEN: usize,
|
||||
const SIGNATURE_LEN: usize,
|
||||
> From<Pair<LeftPair, RightPair, LEFT_PLUS_RIGHT_PUBLIC_LEN, SIGNATURE_LEN>>
|
||||
for Public<LEFT_PLUS_RIGHT_PUBLIC_LEN>
|
||||
SubTag: PairedCryptoSubTagBound,
|
||||
> From<Pair<LeftPair, RightPair, LEFT_PLUS_RIGHT_PUBLIC_LEN, SIGNATURE_LEN, SubTag>>
|
||||
for Public<LEFT_PLUS_RIGHT_PUBLIC_LEN, SubTag>
|
||||
where
|
||||
Pair<LeftPair, RightPair, LEFT_PLUS_RIGHT_PUBLIC_LEN, SIGNATURE_LEN>:
|
||||
PairT<Public = Public<LEFT_PLUS_RIGHT_PUBLIC_LEN>>,
|
||||
Pair<LeftPair, RightPair, LEFT_PLUS_RIGHT_PUBLIC_LEN, SIGNATURE_LEN, SubTag>:
|
||||
PairT<Public = Public<LEFT_PLUS_RIGHT_PUBLIC_LEN, SubTag>>,
|
||||
{
|
||||
fn from(x: Pair<LeftPair, RightPair, LEFT_PLUS_RIGHT_PUBLIC_LEN, SIGNATURE_LEN>) -> Self {
|
||||
fn from(
|
||||
x: Pair<LeftPair, RightPair, LEFT_PLUS_RIGHT_PUBLIC_LEN, SIGNATURE_LEN, SubTag>,
|
||||
) -> Self {
|
||||
x.public()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> UncheckedFrom<[u8; LEFT_PLUS_RIGHT_LEN]>
|
||||
for Public<LEFT_PLUS_RIGHT_LEN>
|
||||
{
|
||||
fn unchecked_from(data: [u8; LEFT_PLUS_RIGHT_LEN]) -> Self {
|
||||
Public(data)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> std::fmt::Display for Public<LEFT_PLUS_RIGHT_LEN>
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize, SubTag: PairedCryptoSubTagBound> std::fmt::Display
|
||||
for Public<LEFT_PLUS_RIGHT_LEN, SubTag>
|
||||
where
|
||||
Public<LEFT_PLUS_RIGHT_LEN>: CryptoType,
|
||||
Public<LEFT_PLUS_RIGHT_LEN, SubTag>: CryptoType,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{}", self.to_ss58check())
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> sp_std::fmt::Debug for Public<LEFT_PLUS_RIGHT_LEN>
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize, SubTag: PairedCryptoSubTagBound> sp_std::fmt::Debug
|
||||
for Public<LEFT_PLUS_RIGHT_LEN, SubTag>
|
||||
where
|
||||
Public<LEFT_PLUS_RIGHT_LEN>: CryptoType,
|
||||
Public<LEFT_PLUS_RIGHT_LEN, SubTag>: CryptoType,
|
||||
[u8; LEFT_PLUS_RIGHT_LEN]: crate::hexdisplay::AsBytesRef,
|
||||
{
|
||||
#[cfg(feature = "std")]
|
||||
@@ -259,9 +203,10 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> Serialize for Public<LEFT_PLUS_RIGHT_LEN>
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize, SubTag: PairedCryptoSubTagBound> Serialize
|
||||
for Public<LEFT_PLUS_RIGHT_LEN, SubTag>
|
||||
where
|
||||
Public<LEFT_PLUS_RIGHT_LEN>: CryptoType,
|
||||
Public<LEFT_PLUS_RIGHT_LEN, SubTag>: CryptoType,
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@@ -272,9 +217,10 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de, const LEFT_PLUS_RIGHT_LEN: usize> Deserialize<'de> for Public<LEFT_PLUS_RIGHT_LEN>
|
||||
impl<'de, const LEFT_PLUS_RIGHT_LEN: usize, SubTag: PairedCryptoSubTagBound> Deserialize<'de>
|
||||
for Public<LEFT_PLUS_RIGHT_LEN, SubTag>
|
||||
where
|
||||
Public<LEFT_PLUS_RIGHT_LEN>: CryptoType,
|
||||
Public<LEFT_PLUS_RIGHT_LEN, SubTag>: CryptoType,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
@@ -285,12 +231,17 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> PublicT for Public<LEFT_PLUS_RIGHT_LEN> where
|
||||
Public<LEFT_PLUS_RIGHT_LEN>: CryptoType
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize, SubTag: PairedCryptoSubTagBound> PublicT
|
||||
for Public<LEFT_PLUS_RIGHT_LEN, SubTag>
|
||||
where
|
||||
Public<LEFT_PLUS_RIGHT_LEN, SubTag>: CryptoType,
|
||||
{
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> Derive for Public<LEFT_PLUS_RIGHT_LEN> {}
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize, SubTag: PairedCryptoSubTagBound> Derive
|
||||
for Public<LEFT_PLUS_RIGHT_LEN, SubTag>
|
||||
{
|
||||
}
|
||||
|
||||
/// Trait characterizing a signature which could be used as individual component of an
|
||||
/// `paired_crypto:Signature` pair.
|
||||
@@ -299,54 +250,13 @@ pub trait SignatureBound: ByteArray {}
|
||||
impl<T: ByteArray> SignatureBound for T {}
|
||||
|
||||
/// A pair of signatures of different types
|
||||
#[derive(Clone, Encode, Decode, MaxEncodedLen, TypeInfo, PartialEq, Eq)]
|
||||
pub struct Signature<const LEFT_PLUS_RIGHT_LEN: usize>([u8; LEFT_PLUS_RIGHT_LEN]);
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> sp_std::hash::Hash for Signature<LEFT_PLUS_RIGHT_LEN> {
|
||||
fn hash<H: sp_std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.0.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> ByteArray for Signature<LEFT_PLUS_RIGHT_LEN> {
|
||||
const LEN: usize = LEFT_PLUS_RIGHT_LEN;
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> TryFrom<&[u8]> for Signature<LEFT_PLUS_RIGHT_LEN> {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
|
||||
if data.len() != LEFT_PLUS_RIGHT_LEN {
|
||||
return Err(())
|
||||
}
|
||||
let mut inner = [0u8; LEFT_PLUS_RIGHT_LEN];
|
||||
inner.copy_from_slice(data);
|
||||
Ok(Signature(inner))
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> AsMut<[u8]> for Signature<LEFT_PLUS_RIGHT_LEN> {
|
||||
fn as_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.0[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> AsRef<[u8; LEFT_PLUS_RIGHT_LEN]>
|
||||
for Signature<LEFT_PLUS_RIGHT_LEN>
|
||||
{
|
||||
fn as_ref(&self) -> &[u8; LEFT_PLUS_RIGHT_LEN] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> AsRef<[u8]> for Signature<LEFT_PLUS_RIGHT_LEN> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.0[..]
|
||||
}
|
||||
}
|
||||
pub type Signature<const LEFT_PLUS_RIGHT_LEN: usize, SubTag> =
|
||||
SignatureBytes<LEFT_PLUS_RIGHT_LEN, (PairedCryptoTag, SubTag)>;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> Serialize for Signature<LEFT_PLUS_RIGHT_LEN> {
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize, SubTag> Serialize
|
||||
for Signature<LEFT_PLUS_RIGHT_LEN, SubTag>
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
@@ -356,28 +266,23 @@ impl<const LEFT_PLUS_RIGHT_LEN: usize> Serialize for Signature<LEFT_PLUS_RIGHT_L
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de, const LEFT_PLUS_RIGHT_LEN: usize> Deserialize<'de> for Signature<LEFT_PLUS_RIGHT_LEN> {
|
||||
impl<'de, const LEFT_PLUS_RIGHT_LEN: usize, SubTag> Deserialize<'de>
|
||||
for Signature<LEFT_PLUS_RIGHT_LEN, SubTag>
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let bytes = array_bytes::hex2bytes(&String::deserialize(deserializer)?)
|
||||
.map_err(|e| de::Error::custom(format!("{:?}", e)))?;
|
||||
Signature::<LEFT_PLUS_RIGHT_LEN>::try_from(bytes.as_ref()).map_err(|e| {
|
||||
Signature::<LEFT_PLUS_RIGHT_LEN, SubTag>::try_from(bytes.as_ref()).map_err(|e| {
|
||||
de::Error::custom(format!("Error converting deserialized data into signature: {:?}", e))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> From<Signature<LEFT_PLUS_RIGHT_LEN>>
|
||||
for [u8; LEFT_PLUS_RIGHT_LEN]
|
||||
{
|
||||
fn from(signature: Signature<LEFT_PLUS_RIGHT_LEN>) -> [u8; LEFT_PLUS_RIGHT_LEN] {
|
||||
signature.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> sp_std::fmt::Debug for Signature<LEFT_PLUS_RIGHT_LEN>
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize, SubTag> sp_std::fmt::Debug
|
||||
for Signature<LEFT_PLUS_RIGHT_LEN, SubTag>
|
||||
where
|
||||
[u8; LEFT_PLUS_RIGHT_LEN]: crate::hexdisplay::AsBytesRef,
|
||||
{
|
||||
@@ -392,24 +297,30 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEFT_PLUS_RIGHT_LEN: usize> UncheckedFrom<[u8; LEFT_PLUS_RIGHT_LEN]>
|
||||
for Signature<LEFT_PLUS_RIGHT_LEN>
|
||||
{
|
||||
fn unchecked_from(data: [u8; LEFT_PLUS_RIGHT_LEN]) -> Self {
|
||||
Signature(data)
|
||||
}
|
||||
}
|
||||
|
||||
/// A key pair.
|
||||
#[derive(Clone)]
|
||||
pub struct Pair<
|
||||
LeftPair: PairT,
|
||||
RightPair: PairT,
|
||||
const PUBLIC_KEY_LEN: usize,
|
||||
const SIGNATURE_LEN: usize,
|
||||
SubTag,
|
||||
> {
|
||||
left: LeftPair,
|
||||
right: RightPair,
|
||||
_phantom: PhantomData<fn() -> SubTag>,
|
||||
}
|
||||
|
||||
impl<
|
||||
LeftPair: PairT + Clone,
|
||||
RightPair: PairT + Clone,
|
||||
const PUBLIC_KEY_LEN: usize,
|
||||
const SIGNATURE_LEN: usize,
|
||||
SubTag,
|
||||
> Clone for Pair<LeftPair, RightPair, PUBLIC_KEY_LEN, SIGNATURE_LEN, SubTag>
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self { left: self.left.clone(), right: self.right.clone(), _phantom: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
@@ -417,18 +328,19 @@ impl<
|
||||
RightPair: PairT,
|
||||
const PUBLIC_KEY_LEN: usize,
|
||||
const SIGNATURE_LEN: usize,
|
||||
> PairT for Pair<LeftPair, RightPair, PUBLIC_KEY_LEN, SIGNATURE_LEN>
|
||||
SubTag: PairedCryptoSubTagBound,
|
||||
> PairT for Pair<LeftPair, RightPair, PUBLIC_KEY_LEN, SIGNATURE_LEN, SubTag>
|
||||
where
|
||||
Pair<LeftPair, RightPair, PUBLIC_KEY_LEN, SIGNATURE_LEN>: CryptoType,
|
||||
Pair<LeftPair, RightPair, PUBLIC_KEY_LEN, SIGNATURE_LEN, SubTag>: CryptoType,
|
||||
LeftPair::Signature: SignatureBound,
|
||||
RightPair::Signature: SignatureBound,
|
||||
Public<PUBLIC_KEY_LEN>: CryptoType,
|
||||
Public<PUBLIC_KEY_LEN, SubTag>: CryptoType,
|
||||
LeftPair::Seed: From<Seed> + Into<Seed>,
|
||||
RightPair::Seed: From<Seed> + Into<Seed>,
|
||||
{
|
||||
type Seed = Seed;
|
||||
type Public = Public<PUBLIC_KEY_LEN>;
|
||||
type Signature = Signature<SIGNATURE_LEN>;
|
||||
type Public = Public<PUBLIC_KEY_LEN, SubTag>;
|
||||
type Signature = Signature<SIGNATURE_LEN, SubTag>;
|
||||
|
||||
fn from_seed_slice(seed_slice: &[u8]) -> Result<Self, SecretStringError> {
|
||||
if seed_slice.len() != SECURE_SEED_LEN {
|
||||
@@ -436,7 +348,7 @@ where
|
||||
}
|
||||
let left = LeftPair::from_seed_slice(&seed_slice)?;
|
||||
let right = RightPair::from_seed_slice(&seed_slice)?;
|
||||
Ok(Pair { left, right })
|
||||
Ok(Pair { left, right, _phantom: PhantomData })
|
||||
}
|
||||
|
||||
/// Derive a child key from a series of given junctions.
|
||||
@@ -459,7 +371,7 @@ where
|
||||
_ => None,
|
||||
};
|
||||
|
||||
Ok((Self { left: left.0, right: right.0 }, seed))
|
||||
Ok((Self { left: left.0, right: right.0, _phantom: PhantomData }, seed))
|
||||
}
|
||||
|
||||
fn public(&self) -> Self::Public {
|
||||
@@ -479,16 +391,18 @@ where
|
||||
Self::Signature::unchecked_from(raw)
|
||||
}
|
||||
|
||||
fn verify<M: AsRef<[u8]>>(sig: &Self::Signature, message: M, public: &Self::Public) -> bool {
|
||||
fn verify<Msg: AsRef<[u8]>>(
|
||||
sig: &Self::Signature,
|
||||
message: Msg,
|
||||
public: &Self::Public,
|
||||
) -> bool {
|
||||
let Ok(left_pub) = public.0[..LeftPair::Public::LEN].try_into() else { return false };
|
||||
let Ok(left_sig) = sig.0[0..LeftPair::Signature::LEN].try_into() else { return false };
|
||||
if !LeftPair::verify(&left_sig, message.as_ref(), &left_pub) {
|
||||
return false
|
||||
}
|
||||
|
||||
let Ok(right_pub) = public.0[LeftPair::Public::LEN..PUBLIC_KEY_LEN].try_into() else {
|
||||
return false
|
||||
};
|
||||
let Ok(right_pub) = public.0[LeftPair::Public::LEN..].try_into() else { return false };
|
||||
let Ok(right_sig) = sig.0[LeftPair::Signature::LEN..].try_into() else { return false };
|
||||
RightPair::verify(&right_sig, message.as_ref(), &right_pub)
|
||||
}
|
||||
@@ -506,6 +420,7 @@ where
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::{crypto::DEV_PHRASE, KeccakHasher};
|
||||
use codec::{Decode, Encode};
|
||||
use ecdsa_bls377::{Pair, Signature};
|
||||
|
||||
use crate::{bls377, ecdsa};
|
||||
|
||||
Reference in New Issue
Block a user