mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 07:58:00 +00:00
210290f8ca
* Remove unused key types sr25 and ed25. * Restore in specific files to fix build. * Fix runtime tests * Fix keystore test * Revert typo * Move keytypes to primitives/src/testing.rs * More missed items. * Getting close now. * Fix example in documentation. * Update core/application-crypto/src/ed25519.rs * Update core/application-crypto/src/sr25519.rs * Bump impl version.
176 lines
5.1 KiB
Rust
176 lines
5.1 KiB
Rust
// Copyright 2019 Parity Technologies (UK) Ltd.
|
|
// This file is part of Substrate.
|
|
|
|
// Substrate is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// Substrate is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
//! Types that should only be used for testing!
|
|
|
|
#[cfg(feature = "std")]
|
|
use crate::{ed25519, sr25519, crypto::{Public, Pair}};
|
|
use crate::crypto::KeyTypeId; // No idea why this import had to move from
|
|
// the previous line, but now the compiler is happy
|
|
|
|
/// Key type for generic Ed25519 key.
|
|
pub const ED25519: KeyTypeId = KeyTypeId(*b"ed25");
|
|
/// Key type for generic Sr 25519 key.
|
|
pub const SR25519: KeyTypeId = KeyTypeId(*b"sr25");
|
|
|
|
/// A keystore implementation usable in tests.
|
|
#[cfg(feature = "std")]
|
|
#[derive(Default)]
|
|
pub struct KeyStore {
|
|
/// `KeyTypeId` maps to public keys and public keys map to private keys.
|
|
keys: std::collections::HashMap<KeyTypeId, std::collections::HashMap<Vec<u8>, String>>,
|
|
}
|
|
|
|
#[cfg(feature = "std")]
|
|
impl KeyStore {
|
|
/// Creates a new instance of `Self`.
|
|
pub fn new() -> std::sync::Arc<parking_lot::RwLock<Self>> {
|
|
std::sync::Arc::new(parking_lot::RwLock::new(Self::default()))
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "std")]
|
|
impl crate::traits::BareCryptoStore for KeyStore {
|
|
fn sr25519_public_keys(&self, id: KeyTypeId) -> Vec<sr25519::Public> {
|
|
self.keys.get(&id)
|
|
.map(|keys|
|
|
keys.values()
|
|
.map(|s| sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid"))
|
|
.map(|p| p.public())
|
|
.collect()
|
|
)
|
|
.unwrap_or_default()
|
|
}
|
|
|
|
fn sr25519_generate_new(
|
|
&mut self,
|
|
id: KeyTypeId,
|
|
seed: Option<&str>,
|
|
) -> Result<sr25519::Public, String> {
|
|
match seed {
|
|
Some(seed) => {
|
|
let pair = sr25519::Pair::from_string(seed, None).expect("Generates an `sr25519` pair.");
|
|
self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into());
|
|
Ok(pair.public())
|
|
},
|
|
None => {
|
|
let (pair, phrase, _) = sr25519::Pair::generate_with_phrase(None);
|
|
self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), phrase);
|
|
Ok(pair.public())
|
|
}
|
|
}
|
|
}
|
|
|
|
fn sr25519_key_pair(&self, id: KeyTypeId, pub_key: &sr25519::Public) -> Option<sr25519::Pair> {
|
|
self.keys.get(&id)
|
|
.and_then(|inner|
|
|
inner.get(pub_key.as_slice())
|
|
.map(|s| sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid"))
|
|
)
|
|
}
|
|
|
|
fn ed25519_public_keys(&self, id: KeyTypeId) -> Vec<ed25519::Public> {
|
|
self.keys.get(&id)
|
|
.map(|keys|
|
|
keys.values()
|
|
.map(|s| ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid"))
|
|
.map(|p| p.public())
|
|
.collect()
|
|
)
|
|
.unwrap_or_default()
|
|
}
|
|
|
|
fn ed25519_generate_new(
|
|
&mut self,
|
|
id: KeyTypeId,
|
|
seed: Option<&str>,
|
|
) -> Result<ed25519::Public, String> {
|
|
match seed {
|
|
Some(seed) => {
|
|
let pair = ed25519::Pair::from_string(seed, None).expect("Generates an `ed25519` pair.");
|
|
self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into());
|
|
Ok(pair.public())
|
|
},
|
|
None => {
|
|
let (pair, phrase, _) = ed25519::Pair::generate_with_phrase(None);
|
|
self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), phrase);
|
|
Ok(pair.public())
|
|
}
|
|
}
|
|
}
|
|
|
|
fn ed25519_key_pair(&self, id: KeyTypeId, pub_key: &ed25519::Public) -> Option<ed25519::Pair> {
|
|
self.keys.get(&id)
|
|
.and_then(|inner|
|
|
inner.get(pub_key.as_slice())
|
|
.map(|s| ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid"))
|
|
)
|
|
}
|
|
|
|
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(())
|
|
}
|
|
|
|
fn password(&self) -> Option<&str> {
|
|
None
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::{sr25519, traits::BareCryptoStore};
|
|
use crate::testing::{ED25519, SR25519};
|
|
|
|
|
|
#[test]
|
|
fn store_key_and_extract() {
|
|
let store = KeyStore::new();
|
|
|
|
let public = store.write()
|
|
.ed25519_generate_new(ED25519, None)
|
|
.expect("Genrates key");
|
|
|
|
let store_key_pair = store.read()
|
|
.ed25519_key_pair(ED25519, &public)
|
|
.expect("Key should exists in store");
|
|
|
|
assert_eq!(public, store_key_pair.public());
|
|
}
|
|
|
|
#[test]
|
|
fn store_unknown_and_extract_it() {
|
|
let store = KeyStore::new();
|
|
|
|
let secret_uri = "//Alice";
|
|
let key_pair = sr25519::Pair::from_string(secret_uri, None).expect("Generates key pair");
|
|
|
|
store.write().insert_unknown(
|
|
SR25519,
|
|
secret_uri,
|
|
key_pair.public().as_ref(),
|
|
).expect("Inserts unknown key");
|
|
|
|
let store_key_pair = store.read().sr25519_key_pair(
|
|
SR25519,
|
|
&key_pair.public(),
|
|
).expect("Gets key pair from keystore");
|
|
|
|
assert_eq!(key_pair.public(), store_key_pair.public());
|
|
}
|
|
}
|