Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Generic keystore internals #13749

Merged
merged 3 commits into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 47 additions & 74 deletions client/keystore/src/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,50 @@ impl LocalKeystore {
) -> Result<Option<Pair>> {
self.0.read().key_pair::<Pair>(public)
}
}

impl Keystore for LocalKeystore {
fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec<sr25519::Public> {
fn public_keys<T: CorePair>(&self, key_type: KeyTypeId) -> Vec<T::Public> {
self.0
.read()
.raw_public_keys(key_type)
.map(|v| {
v.into_iter()
.filter_map(|k| sr25519::Public::from_slice(k.as_slice()).ok())
.collect()
v.into_iter().filter_map(|k| T::Public::from_slice(k.as_slice()).ok()).collect()
})
.unwrap_or_default()
}

fn generate_new<T: CorePair>(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> std::result::Result<T::Public, TraitError> {
let pair = match seed {
Some(seed) => self.0.write().insert_ephemeral_from_seed_by_type::<T>(seed, key_type),
None => self.0.write().generate_by_type::<T>(key_type),
}
.map_err(|e| -> TraitError { e.into() })?;
Ok(pair.public())
}

fn sign<T: CorePair>(
&self,
key_type: KeyTypeId,
public: &T::Public,
msg: &[u8],
) -> std::result::Result<Option<T::Signature>, TraitError> {
let signature = self
.0
.read()
.key_pair_by_type::<T>(public, key_type)?
.map(|pair| pair.sign(msg));
Ok(signature)
}
}

impl Keystore for LocalKeystore {
fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec<sr25519::Public> {
self.public_keys::<sr25519::Pair>(key_type)
}

/// Generate a new pair compatible with the 'ed25519' signature scheme.
///
/// If the `[seed]` is `Some` then the key will be ephemeral and stored in memory.
Expand All @@ -86,16 +115,7 @@ impl Keystore for LocalKeystore {
key_type: KeyTypeId,
seed: Option<&str>,
) -> std::result::Result<sr25519::Public, TraitError> {
let pair = match seed {
Some(seed) => self
.0
.write()
.insert_ephemeral_from_seed_by_type::<sr25519::Pair>(seed, key_type),
None => self.0.write().generate_by_type::<sr25519::Pair>(key_type),
}
.map_err(|e| -> TraitError { e.into() })?;

Ok(pair.public())
self.generate_new::<sr25519::Pair>(key_type, seed)
}

fn sr25519_sign(
Expand All @@ -104,12 +124,7 @@ impl Keystore for LocalKeystore {
public: &sr25519::Public,
msg: &[u8],
) -> std::result::Result<Option<sr25519::Signature>, TraitError> {
let res = self
.0
.read()
.key_pair_by_type::<sr25519::Pair>(public, key_type)?
.map(|pair| pair.sign(msg));
Ok(res)
self.sign::<sr25519::Pair>(key_type, public, msg)
}

fn sr25519_vrf_sign(
Expand All @@ -118,24 +133,16 @@ impl Keystore for LocalKeystore {
public: &sr25519::Public,
transcript_data: VRFTranscriptData,
) -> std::result::Result<Option<VRFSignature>, TraitError> {
let res = self.0.read().key_pair_by_type::<sr25519::Pair>(public, key_type)?.map(|pair| {
let sig = self.0.read().key_pair_by_type::<sr25519::Pair>(public, key_type)?.map(|pair| {
let transcript = make_transcript(transcript_data);
let (inout, proof, _) = pair.as_ref().vrf_sign(transcript);
VRFSignature { output: inout.to_output(), proof }
});
Ok(res)
Ok(sig)
}

fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec<ed25519::Public> {
self.0
.read()
.raw_public_keys(key_type)
.map(|v| {
v.into_iter()
.filter_map(|k| ed25519::Public::from_slice(k.as_slice()).ok())
.collect()
})
.unwrap_or_default()
self.public_keys::<ed25519::Pair>(key_type)
}

/// Generate a new pair compatible with the 'sr25519' signature scheme.
Expand All @@ -146,16 +153,7 @@ impl Keystore for LocalKeystore {
key_type: KeyTypeId,
seed: Option<&str>,
) -> std::result::Result<ed25519::Public, TraitError> {
let pair = match seed {
Some(seed) => self
.0
.write()
.insert_ephemeral_from_seed_by_type::<ed25519::Pair>(seed, key_type),
None => self.0.write().generate_by_type::<ed25519::Pair>(key_type),
}
.map_err(|e| -> TraitError { e.into() })?;

Ok(pair.public())
self.generate_new::<ed25519::Pair>(key_type, seed)
}

fn ed25519_sign(
Expand All @@ -164,24 +162,11 @@ impl Keystore for LocalKeystore {
public: &ed25519::Public,
msg: &[u8],
) -> std::result::Result<Option<ed25519::Signature>, TraitError> {
let res = self
.0
.read()
.key_pair_by_type::<ed25519::Pair>(public, key_type)?
.map(|pair| pair.sign(msg));
Ok(res)
self.sign::<ed25519::Pair>(key_type, public, msg)
}

fn ecdsa_public_keys(&self, key_type: KeyTypeId) -> Vec<ecdsa::Public> {
self.0
.read()
.raw_public_keys(key_type)
.map(|v| {
v.into_iter()
.filter_map(|k| ecdsa::Public::from_slice(k.as_slice()).ok())
.collect()
})
.unwrap_or_default()
self.public_keys::<ecdsa::Pair>(key_type)
}

/// Generate a new pair compatible with the 'ecdsa' signature scheme.
Expand All @@ -192,14 +177,7 @@ impl Keystore for LocalKeystore {
key_type: KeyTypeId,
seed: Option<&str>,
) -> std::result::Result<ecdsa::Public, TraitError> {
let pair = match seed {
Some(seed) =>
self.0.write().insert_ephemeral_from_seed_by_type::<ecdsa::Pair>(seed, key_type),
None => self.0.write().generate_by_type::<ecdsa::Pair>(key_type),
}
.map_err(|e| -> TraitError { e.into() })?;

Ok(pair.public())
self.generate_new::<ecdsa::Pair>(key_type, seed)
}

fn ecdsa_sign(
Expand All @@ -208,12 +186,7 @@ impl Keystore for LocalKeystore {
public: &ecdsa::Public,
msg: &[u8],
) -> std::result::Result<Option<ecdsa::Signature>, TraitError> {
let res = self
.0
.read()
.key_pair_by_type::<ecdsa::Pair>(public, key_type)?
.map(|pair| pair.sign(msg));
Ok(res)
self.sign::<ecdsa::Pair>(key_type, public, msg)
}

fn ecdsa_sign_prehashed(
Expand All @@ -222,12 +195,12 @@ impl Keystore for LocalKeystore {
public: &ecdsa::Public,
msg: &[u8; 32],
) -> std::result::Result<Option<ecdsa::Signature>, TraitError> {
let res = self
let sig = self
.0
.read()
.key_pair_by_type::<ecdsa::Pair>(public, key_type)?
.map(|pair| pair.sign_prehashed(msg));
Ok(res)
Ok(sig)
}

fn insert(
Expand Down
Loading