mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-05-14 11:51:19 +00:00
core/src/identity: Implement Keypair::from_protobuf_encoding for ed25519 (#2090)
Implement `Keypair` decoding from Protobuf according to [peer id specification]. For now support ed25519 keys only. Future commits might add RSA secp256k1 and ecdsa. [peer id specification]: https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#keys
This commit is contained in:
parent
3b0f5a4f96
commit
a24e4221bd
@ -40,6 +40,7 @@ ring = { version = "0.16.9", features = ["alloc", "std"], default-features = fal
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
async-std = { version = "1.6.2", features = ["attributes"] }
|
async-std = { version = "1.6.2", features = ["attributes"] }
|
||||||
|
base64 = "0.13.0"
|
||||||
criterion = "0.3"
|
criterion = "0.3"
|
||||||
libp2p-mplex = { path = "../muxers/mplex" }
|
libp2p-mplex = { path = "../muxers/mplex" }
|
||||||
libp2p-noise = { path = "../transports/noise" }
|
libp2p-noise = { path = "../transports/noise" }
|
||||||
|
@ -115,6 +115,37 @@ impl Keypair {
|
|||||||
Secp256k1(pair) => PublicKey::Secp256k1(pair.public().clone()),
|
Secp256k1(pair) => PublicKey::Secp256k1(pair.public().clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Decode a private key from a protobuf structure and parse it as a [`Keypair`].
|
||||||
|
pub fn from_protobuf_encoding(bytes: &[u8]) -> Result<Keypair, DecodingError> {
|
||||||
|
use prost::Message;
|
||||||
|
|
||||||
|
let mut private_key = keys_proto::PrivateKey::decode(bytes)
|
||||||
|
.map_err(|e| DecodingError::new("Protobuf").source(e))
|
||||||
|
.map(zeroize::Zeroizing::new)?;
|
||||||
|
|
||||||
|
let key_type = keys_proto::KeyType::from_i32(private_key.r#type)
|
||||||
|
.ok_or_else(|| DecodingError::new(format!("unknown key type: {}", private_key.r#type)))?;
|
||||||
|
|
||||||
|
match key_type {
|
||||||
|
keys_proto::KeyType::Ed25519 => {
|
||||||
|
ed25519::Keypair::decode(&mut private_key.data).map(Keypair::Ed25519)
|
||||||
|
},
|
||||||
|
keys_proto::KeyType::Rsa => {
|
||||||
|
Err(DecodingError::new("Decoding RSA key from Protobuf is unsupported."))
|
||||||
|
},
|
||||||
|
keys_proto::KeyType::Secp256k1 => {
|
||||||
|
Err(DecodingError::new("Decoding Secp256k1 key from Protobuf is unsupported."))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl zeroize::Zeroize for keys_proto::PrivateKey {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
self.r#type.zeroize();
|
||||||
|
self.data.zeroize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The public key of a node's identity keypair.
|
/// The public key of a node's identity keypair.
|
||||||
@ -219,3 +250,22 @@ impl PublicKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn keypair_from_protobuf_encoding() {
|
||||||
|
// E.g. retrieved from an IPFS config file.
|
||||||
|
let base_64_encoded = "CAESQL6vdKQuznQosTrW7FWI9At+XX7EBf0BnZLhb6w+N+XSQSdfInl6c7U4NuxXJlhKcRBlBw9d0tj2dfBIVf6mcPA=";
|
||||||
|
let expected_peer_id = PeerId::from_str("12D3KooWEChVMMMzV8acJ53mJHrw1pQ27UAGkCxWXLJutbeUMvVu").unwrap();
|
||||||
|
|
||||||
|
let encoded = base64::decode(base_64_encoded).unwrap();
|
||||||
|
|
||||||
|
let keypair = Keypair::from_protobuf_encoding(&encoded).unwrap();
|
||||||
|
let peer_id = keypair.public().into_peer_id();
|
||||||
|
|
||||||
|
assert_eq!(expected_peer_id, peer_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user