mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 13:31:10 +00:00
Added RuntimePublic for ecdsa public key. (#6029)
* add generate ecdsa, etc to keystore * impl ecdsa needed traits * add ecdsa to sr_io * add ecdsa to application-crypto * add ecdsa to test-utils * add ecdsa debug derive * fix ecdsa public
This commit is contained in:
@@ -38,6 +38,7 @@ use crate::crypto::Ss58Codec;
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{de, Serializer, Serialize, Deserializer, Deserialize};
|
||||
use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId};
|
||||
use sp_runtime_interface::pass_by::PassByInner;
|
||||
#[cfg(feature = "full_crypto")]
|
||||
use secp256k1::{PublicKey, SecretKey};
|
||||
|
||||
@@ -51,7 +52,7 @@ pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"ecds");
|
||||
type Seed = [u8; 32];
|
||||
|
||||
/// The ECDSA compressed public key.
|
||||
#[derive(Clone, Encode, Decode)]
|
||||
#[derive(Clone, Encode, Decode, PassByInner)]
|
||||
pub struct Public([u8; 33]);
|
||||
|
||||
impl PartialOrd for Public {
|
||||
@@ -125,6 +126,18 @@ impl TraitPublic for Public {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Public> for CryptoTypePublicPair {
|
||||
fn from(key: Public) -> Self {
|
||||
(&key).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Public> for CryptoTypePublicPair {
|
||||
fn from(key: &Public) -> Self {
|
||||
CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec())
|
||||
}
|
||||
}
|
||||
|
||||
impl Derive for Public {}
|
||||
|
||||
impl Default for Public {
|
||||
@@ -178,12 +191,17 @@ impl std::fmt::Display for Public {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl std::fmt::Debug for Public {
|
||||
impl sp_std::fmt::Debug for Public {
|
||||
#[cfg(feature = "std")]
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> 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 = "std")]
|
||||
@@ -209,7 +227,7 @@ impl sp_std::hash::Hash for Public {
|
||||
}
|
||||
|
||||
/// A signature (a 512-bit value, plus 8 bits for recovery ID).
|
||||
#[derive(Encode, Decode)]
|
||||
#[derive(Encode, Decode, PassByInner)]
|
||||
pub struct Signature([u8; 65]);
|
||||
|
||||
impl sp_std::convert::TryFrom<&[u8]> for Signature {
|
||||
@@ -289,11 +307,16 @@ impl AsMut<[u8]> for Signature {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl std::fmt::Debug for Signature {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "full_crypto")]
|
||||
|
||||
@@ -21,7 +21,7 @@ use crate::crypto::KeyTypeId;
|
||||
#[cfg(feature = "std")]
|
||||
use crate::{
|
||||
crypto::{Pair, Public, CryptoTypePublicPair},
|
||||
ed25519, sr25519,
|
||||
ed25519, sr25519, ecdsa,
|
||||
traits::BareCryptoStoreError
|
||||
};
|
||||
#[cfg(feature = "std")]
|
||||
@@ -30,6 +30,8 @@ use std::collections::HashSet;
|
||||
pub const ED25519: KeyTypeId = KeyTypeId(*b"ed25");
|
||||
/// Key type for generic Sr 25519 key.
|
||||
pub const SR25519: KeyTypeId = KeyTypeId(*b"sr25");
|
||||
/// Key type for generic Sr 25519 key.
|
||||
pub const ECDSA: KeyTypeId = KeyTypeId(*b"ecds");
|
||||
|
||||
/// A keystore implementation usable in tests.
|
||||
#[cfg(feature = "std")]
|
||||
@@ -62,6 +64,14 @@ impl KeyStore {
|
||||
)
|
||||
}
|
||||
|
||||
fn ecdsa_key_pair(&self, id: KeyTypeId, pub_key: &ecdsa::Public) -> Option<ecdsa::Pair> {
|
||||
self.keys.get(&id)
|
||||
.and_then(|inner|
|
||||
inner.get(pub_key.as_slice())
|
||||
.map(|s| ecdsa::Pair::from_string(s, None).expect("`ecdsa` seed slice is valid"))
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@@ -74,6 +84,7 @@ impl crate::traits::BareCryptoStore for KeyStore {
|
||||
.fold(Vec::new(), |mut v, k| {
|
||||
v.push(CryptoTypePublicPair(sr25519::CRYPTO_ID, k.clone()));
|
||||
v.push(CryptoTypePublicPair(ed25519::CRYPTO_ID, k.clone()));
|
||||
v.push(CryptoTypePublicPair(ecdsa::CRYPTO_ID, k.clone()));
|
||||
v
|
||||
}))
|
||||
})
|
||||
@@ -142,6 +153,37 @@ impl crate::traits::BareCryptoStore for KeyStore {
|
||||
}
|
||||
}
|
||||
|
||||
fn ecdsa_public_keys(&self, id: KeyTypeId) -> Vec<ecdsa::Public> {
|
||||
self.keys.get(&id)
|
||||
.map(|keys|
|
||||
keys.values()
|
||||
.map(|s| ecdsa::Pair::from_string(s, None).expect("`ecdsa` seed slice is valid"))
|
||||
.map(|p| p.public())
|
||||
.collect()
|
||||
)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn ecdsa_generate_new(
|
||||
&mut self,
|
||||
id: KeyTypeId,
|
||||
seed: Option<&str>,
|
||||
) -> Result<ecdsa::Public, BareCryptoStoreError> {
|
||||
match seed {
|
||||
Some(seed) => {
|
||||
let pair = ecdsa::Pair::from_string(seed, None)
|
||||
.map_err(|_| BareCryptoStoreError::ValidationError("Generates an `ecdsa` pair.".to_owned()))?;
|
||||
self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into());
|
||||
Ok(pair.public())
|
||||
},
|
||||
None => {
|
||||
let (pair, phrase, _) = ecdsa::Pair::generate_with_phrase(None);
|
||||
self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), phrase);
|
||||
Ok(pair.public())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn insert_unknown(&mut self, id: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> {
|
||||
self.keys.entry(id).or_default().insert(public.to_owned(), suri.to_string());
|
||||
Ok(())
|
||||
@@ -187,6 +229,12 @@ impl crate::traits::BareCryptoStore for KeyStore {
|
||||
.ok_or(BareCryptoStoreError::PairNotFound("sr25519".to_owned()))?;
|
||||
return Ok(key_pair.sign(msg).encode());
|
||||
}
|
||||
ecdsa::CRYPTO_ID => {
|
||||
let key_pair: ecdsa::Pair = self
|
||||
.ecdsa_key_pair(id, &ecdsa::Public::from_slice(key.1.as_slice()))
|
||||
.ok_or(BareCryptoStoreError::PairNotFound("ecdsa".to_owned()))?;
|
||||
return Ok(key_pair.sign(msg).encode());
|
||||
}
|
||||
_ => Err(BareCryptoStoreError::KeyNotSupported(id))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
use crate::{
|
||||
crypto::{KeyTypeId, CryptoTypePublicPair},
|
||||
ed25519, sr25519,
|
||||
ed25519, sr25519, ecdsa,
|
||||
};
|
||||
|
||||
use std::{
|
||||
@@ -77,6 +77,18 @@ pub trait BareCryptoStore: Send + Sync {
|
||||
id: KeyTypeId,
|
||||
seed: Option<&str>,
|
||||
) -> Result<ed25519::Public, BareCryptoStoreError>;
|
||||
/// Returns all ecdsa public keys for the given key type.
|
||||
fn ecdsa_public_keys(&self, id: KeyTypeId) -> Vec<ecdsa::Public>;
|
||||
/// Generate a new ecdsa key pair for the given key type and an optional seed.
|
||||
///
|
||||
/// If the given seed is `Some(_)`, the key pair will only be stored in memory.
|
||||
///
|
||||
/// Returns the public key of the generated key pair.
|
||||
fn ecdsa_generate_new(
|
||||
&mut self,
|
||||
id: KeyTypeId,
|
||||
seed: Option<&str>,
|
||||
) -> Result<ecdsa::Public, BareCryptoStoreError>;
|
||||
|
||||
/// Insert a new key. This doesn't require any known of the crypto; but a public key must be
|
||||
/// manually provided.
|
||||
|
||||
Reference in New Issue
Block a user