Generic keystore internals (#13749)

* Generic testing keystore internals

* Generic local keystore internals

* Restore deleted comment
This commit is contained in:
Davide Galassi
2023-03-30 01:22:34 +02:00
committed by GitHub
parent c91b5b5b21
commit 29e31f2b0a
2 changed files with 95 additions and 190 deletions
+47 -74
View File
@@ -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.
@@ -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(
@@ -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(
@@ -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.
@@ -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(
@@ -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.
@@ -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(
@@ -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(
@@ -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(
+48 -116
View File
@@ -42,65 +42,36 @@ impl MemoryKeystore {
Self::default()
}
fn sr25519_key_pair(
&self,
key_type: KeyTypeId,
public: &sr25519::Public,
) -> Option<sr25519::Pair> {
self.keys.read().get(&key_type).and_then(|inner| {
inner.get(public.as_slice()).map(|s| {
sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid")
})
})
}
fn ed25519_key_pair(
&self,
key_type: KeyTypeId,
public: &ed25519::Public,
) -> Option<ed25519::Pair> {
self.keys.read().get(&key_type).and_then(|inner| {
inner.get(public.as_slice()).map(|s| {
ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid")
})
})
}
fn ecdsa_key_pair(&self, key_type: KeyTypeId, public: &ecdsa::Public) -> Option<ecdsa::Pair> {
fn pair<T: Pair>(&self, key_type: KeyTypeId, public: &T::Public) -> Option<T> {
self.keys.read().get(&key_type).and_then(|inner| {
inner
.get(public.as_slice())
.map(|s| ecdsa::Pair::from_string(s, None).expect("`ecdsa` seed slice is valid"))
.map(|s| T::from_string(s, None).expect("seed slice is valid"))
})
}
}
impl Keystore for MemoryKeystore {
fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec<sr25519::Public> {
fn public_keys<T: Pair>(&self, key_type: KeyTypeId) -> Vec<T::Public> {
self.keys
.read()
.get(&key_type)
.map(|keys| {
keys.values()
.map(|s| {
sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid")
})
.map(|s| T::from_string(s, None).expect("seed slice is valid"))
.map(|p| p.public())
.collect()
})
.unwrap_or_default()
}
fn sr25519_generate_new(
fn generate_new<T: Pair>(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<sr25519::Public, Error> {
) -> Result<T::Public, Error> {
match seed {
Some(seed) => {
let pair = sr25519::Pair::from_string(seed, None).map_err(|_| {
Error::ValidationError("Generates an `sr25519` pair.".to_owned())
})?;
let pair = T::from_string(seed, None)
.map_err(|_| Error::ValidationError("Generates a pair.".to_owned()))?;
self.keys
.write()
.entry(key_type)
@@ -109,7 +80,7 @@ impl Keystore for MemoryKeystore {
Ok(pair.public())
},
None => {
let (pair, phrase, _) = sr25519::Pair::generate_with_phrase(None);
let (pair, phrase, _) = T::generate_with_phrase(None);
self.keys
.write()
.entry(key_type)
@@ -120,13 +91,37 @@ impl Keystore for MemoryKeystore {
}
}
fn sign<T: Pair>(
&self,
key_type: KeyTypeId,
public: &T::Public,
msg: &[u8],
) -> Result<Option<T::Signature>, Error> {
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_keys::<sr25519::Pair>(key_type)
}
fn sr25519_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<sr25519::Public, Error> {
self.generate_new::<sr25519::Pair>(key_type, seed)
}
fn sr25519_sign(
&self,
key_type: KeyTypeId,
public: &sr25519::Public,
msg: &[u8],
) -> Result<Option<sr25519::Signature>, Error> {
Ok(self.sr25519_key_pair(key_type, public).map(|pair| pair.sign(msg)))
self.sign::<sr25519::Pair>(key_type, public, msg)
}
fn sr25519_vrf_sign(
@@ -135,27 +130,16 @@ impl Keystore for MemoryKeystore {
public: &sr25519::Public,
transcript_data: VRFTranscriptData,
) -> Result<Option<VRFSignature>, Error> {
let transcript = make_transcript(transcript_data);
let pair =
if let Some(k) = self.sr25519_key_pair(key_type, public) { k } else { return Ok(None) };
let (inout, proof, _) = pair.as_ref().vrf_sign(transcript);
Ok(Some(VRFSignature { output: inout.to_output(), proof }))
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(sig)
}
fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec<ed25519::Public> {
self.keys
.read()
.get(&key_type)
.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()
self.public_keys::<ed25519::Pair>(key_type)
}
fn ed25519_generate_new(
@@ -163,28 +147,7 @@ impl Keystore for MemoryKeystore {
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<ed25519::Public, Error> {
match seed {
Some(seed) => {
let pair = ed25519::Pair::from_string(seed, None).map_err(|_| {
Error::ValidationError("Generates an `ed25519` pair.".to_owned())
})?;
self.keys
.write()
.entry(key_type)
.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
.write()
.entry(key_type)
.or_default()
.insert(pair.public().to_raw_vec(), phrase);
Ok(pair.public())
},
}
self.generate_new::<ed25519::Pair>(key_type, seed)
}
fn ed25519_sign(
@@ -193,22 +156,11 @@ impl Keystore for MemoryKeystore {
public: &ed25519::Public,
msg: &[u8],
) -> Result<Option<ed25519::Signature>, Error> {
Ok(self.ed25519_key_pair(key_type, public).map(|pair| pair.sign(msg)))
self.sign::<ed25519::Pair>(key_type, public, msg)
}
fn ecdsa_public_keys(&self, key_type: KeyTypeId) -> Vec<ecdsa::Public> {
self.keys
.read()
.get(&key_type)
.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()
self.public_keys::<ecdsa::Pair>(key_type)
}
fn ecdsa_generate_new(
@@ -216,27 +168,7 @@ impl Keystore for MemoryKeystore {
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<ecdsa::Public, Error> {
match seed {
Some(seed) => {
let pair = ecdsa::Pair::from_string(seed, None)
.map_err(|_| Error::ValidationError("Generates an `ecdsa` pair.".to_owned()))?;
self.keys
.write()
.entry(key_type)
.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
.write()
.entry(key_type)
.or_default()
.insert(pair.public().to_raw_vec(), phrase);
Ok(pair.public())
},
}
self.generate_new::<ecdsa::Pair>(key_type, seed)
}
fn ecdsa_sign(
@@ -245,7 +177,7 @@ impl Keystore for MemoryKeystore {
public: &ecdsa::Public,
msg: &[u8],
) -> Result<Option<ecdsa::Signature>, Error> {
Ok(self.ecdsa_key_pair(key_type, public).map(|pair| pair.sign(msg)))
self.sign::<ecdsa::Pair>(key_type, public, msg)
}
fn ecdsa_sign_prehashed(
@@ -254,8 +186,8 @@ impl Keystore for MemoryKeystore {
public: &ecdsa::Public,
msg: &[u8; 32],
) -> Result<Option<ecdsa::Signature>, Error> {
let pair = self.ecdsa_key_pair(key_type, public);
pair.map(|pair| pair.sign_prehashed(msg)).map(Ok).transpose()
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<(), ()> {