Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Generic local keystore internals
  • Loading branch information
davxy committed Mar 29, 2023
commit e1aa3ccbf67ae505326eee1b81c1c88a2dc40185
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
29 changes: 14 additions & 15 deletions primitives/keystore/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl MemoryKeystore {
})
}

fn public<T: Pair>(&self, key_type: KeyTypeId) -> Vec<T::Public> {
fn public_keys<T: Pair>(&self, key_type: KeyTypeId) -> Vec<T::Public> {
self.keys
.read()
.get(&key_type)
Expand All @@ -62,7 +62,7 @@ impl MemoryKeystore {
.unwrap_or_default()
}

fn generate<T: Pair>(
fn generate_new<T: Pair>(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
Expand Down Expand Up @@ -96,22 +96,22 @@ impl MemoryKeystore {
public: &T::Public,
msg: &[u8],
) -> Result<Option<T::Signature>, Error> {
let signature = self.pair::<T>(key_type, public).map(|pair| pair.sign(msg));
Ok(signature)
let sig = self.pair::<T>(key_type, public).map(|pair| pair.sign(msg));
Ok(sig)
}
}

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

fn sr25519_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<sr25519::Public, Error> {
self.generate::<sr25519::Pair>(key_type, seed)
self.generate_new::<sr25519::Pair>(key_type, seed)
}

fn sr25519_sign(
Expand All @@ -129,24 +129,24 @@ impl Keystore for MemoryKeystore {
public: &sr25519::Public,
transcript_data: VRFTranscriptData,
) -> Result<Option<VRFSignature>, Error> {
let signature = self.pair::<sr25519::Pair>(key_type, public).map(|pair| {
let sig = self.pair::<sr25519::Pair>(key_type, public).map(|pair| {
let transcript = make_transcript(transcript_data);
let (inout, proof, _) = pair.as_ref().vrf_sign(transcript);
VRFSignature { output: inout.to_output(), proof }
});
Ok(signature)
Ok(sig)
}

fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec<ed25519::Public> {
self.public::<ed25519::Pair>(key_type)
self.public_keys::<ed25519::Pair>(key_type)
}

fn ed25519_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<ed25519::Public, Error> {
self.generate::<ed25519::Pair>(key_type, seed)
self.generate_new::<ed25519::Pair>(key_type, seed)
}

fn ed25519_sign(
Expand All @@ -159,15 +159,15 @@ impl Keystore for MemoryKeystore {
}

fn ecdsa_public_keys(&self, key_type: KeyTypeId) -> Vec<ecdsa::Public> {
self.public::<ecdsa::Pair>(key_type)
self.public_keys::<ecdsa::Pair>(key_type)
}

fn ecdsa_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<ecdsa::Public, Error> {
self.generate::<ecdsa::Pair>(key_type, seed)
self.generate_new::<ecdsa::Pair>(key_type, seed)
}

fn ecdsa_sign(
Expand All @@ -185,9 +185,8 @@ impl Keystore for MemoryKeystore {
public: &ecdsa::Public,
msg: &[u8; 32],
) -> Result<Option<ecdsa::Signature>, Error> {
let signature =
self.pair::<ecdsa::Pair>(key_type, public).map(|pair| pair.sign_prehashed(msg));
Ok(signature)
let sig = self.pair::<ecdsa::Pair>(key_type, public).map(|pair| pair.sign_prehashed(msg));
Ok(sig)
}

fn insert(&self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> {
Expand Down