This commit is contained in:
DieMyst 2021-01-18 20:08:05 +03:00
parent 9e74777fe5
commit a0261bc331
11 changed files with 110 additions and 54 deletions

1
Cargo.lock generated
View File

@ -1330,6 +1330,7 @@ dependencies = [
"ref-cast", "ref-cast",
"serde", "serde",
"serde_json", "serde_json",
"signature",
] ]
[[package]] [[package]]

View File

@ -16,6 +16,5 @@ log = "0.4.11"
ref-cast = "1.0.2" ref-cast = "1.0.2"
derivative = "2.1.1" derivative = "2.1.1"
ed25519-dalek = "1.0.1" ed25519-dalek = "1.0.1"
rand = "0.7.0"
[dev-dependencies] signature = "1.3.0"
rand = "0.7.3"

2
bin/Cargo.lock generated
View File

@ -1370,9 +1370,11 @@ dependencies = [
"failure", "failure",
"fluence-fork-libp2p-core", "fluence-fork-libp2p-core",
"log", "log",
"rand 0.7.3",
"ref-cast", "ref-cast",
"serde", "serde",
"serde_json", "serde_json",
"signature",
] ]
[[package]] [[package]]

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
use crate::ed25519::PublicKey; use ed25519_dalek::PublicKey;
use crate::key_pair::KeyPair; use crate::key_pair::KeyPair;
use crate::trust::{Trust, TRUST_LEN}; use crate::trust::{Trust, TRUST_LEN};
use std::str::FromStr; use std::str::FromStr;

View File

@ -14,37 +14,43 @@
* limitations under the License. * limitations under the License.
*/ */
use crate::ed25519::{Keypair as Libp2pKeyPair, PublicKey, SecretKey}; extern crate rand;
use ed25519_dalek::SignatureError;
use libp2p_core::identity::error::DecodingError;
use std::fmt;
pub type Signature = Vec<u8>; use crate::ed25519::{Keypair as Libp2pKeyPair};
use ed25519_dalek::SignatureError;
use ed25519_dalek::{PublicKey, Signer};
use signature::{Signature as SigSignature};
use core::fmt::{Debug};
use std::fmt;
use rand::rngs::OsRng;
pub type Signature = ed25519_dalek::Signature;
/// An Ed25519 keypair. /// An Ed25519 keypair.
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct KeyPair { pub struct KeyPair {
pub key_pair: Libp2pKeyPair, pub key_pair: ed25519_dalek::Keypair,
} }
impl KeyPair { impl KeyPair {
/// Generate a new Ed25519 keypair. /// Generate a new Ed25519 keypair.
#[allow(dead_code)] #[allow(dead_code)]
pub fn generate() -> Self { pub fn generate() -> Self {
let kp = Libp2pKeyPair::generate(); let mut csprng = OsRng { };
let kp = ed25519_dalek::Keypair::generate(&mut csprng);
kp.into() kp.into()
} }
pub fn from_bytes(sk_bytes: impl AsMut<[u8]>) -> Result<Self, DecodingError> { pub fn from_bytes(sk_bytes: &[u8]) -> Result<Self, SignatureError> {
let sk = SecretKey::from_bytes(sk_bytes)?; let kp = ed25519_dalek::Keypair::from_bytes(sk_bytes)?;
Ok(Libp2pKeyPair::from(sk).into()) Ok(KeyPair {key_pair: kp})
} }
/// Encode the keypair into a byte array by concatenating the bytes /// Encode the keypair into a byte array by concatenating the bytes
/// of the secret scalar and the compressed public point/ /// of the secret scalar and the compressed public point/
#[allow(dead_code)] #[allow(dead_code)]
pub fn encode(&self) -> [u8; 64] { pub fn encode(&self) -> [u8; 64] {
self.key_pair.encode() self.key_pair.to_bytes()
} }
/// Decode a keypair from the format produced by `encode`. /// Decode a keypair from the format produced by `encode`.
@ -52,26 +58,27 @@ impl KeyPair {
pub fn decode(kp: &[u8]) -> Result<KeyPair, SignatureError> { pub fn decode(kp: &[u8]) -> Result<KeyPair, SignatureError> {
let kp = ed25519_dalek::Keypair::from_bytes(kp)?; let kp = ed25519_dalek::Keypair::from_bytes(kp)?;
Ok(Self { Ok(Self {
key_pair: kp.into(), key_pair: kp,
}) })
} }
/// Get the public key of this keypair. /// Get the public key of this keypair.
#[allow(dead_code)] #[allow(dead_code)]
pub fn public_key(&self) -> PublicKey { pub fn public_key(&self) -> PublicKey {
self.key_pair.public() self.key_pair.public
} }
/// Sign a message using the private key of this keypair. /// Sign a message using the private key of this keypair.
pub fn sign(&self, msg: &[u8]) -> Vec<u8> { pub fn sign(&self, msg: &[u8]) -> Signature {
self.key_pair.sign(msg) self.key_pair.sign(msg)
} }
/// Verify the Ed25519 signature on a message using the public key. /// Verify the Ed25519 signature on a message using the public key.
pub fn verify(pk: &PublicKey, msg: &[u8], signature: &[u8]) -> Result<(), String> { pub fn verify(pk: &PublicKey, msg: &[u8], signature: Signature) -> Result<(), String> {
if pk.verify(msg, signature) { // let signature = ed25519_dalek::Signature::from_bytes(signature)
return Ok(()); // .map_err(|err| format!("Cannot convert bytes to a signature: {:?}", err))?;
} let result = pk.verify_strict(msg, &signature)
.map_err(|err| format!("Signature verification failed: {:?}", err))?;
Err("Signature is not valid.".to_string()) Err("Signature is not valid.".to_string())
} }
@ -79,6 +86,13 @@ impl KeyPair {
impl From<Libp2pKeyPair> for KeyPair { impl From<Libp2pKeyPair> for KeyPair {
fn from(kp: Libp2pKeyPair) -> Self { fn from(kp: Libp2pKeyPair) -> Self {
let kp = ed25519_dalek::Keypair::from_bytes(&kp.encode()).unwrap();
Self { key_pair: kp }
}
}
impl From<ed25519_dalek::Keypair> for KeyPair {
fn from(kp: ed25519_dalek::Keypair) -> Self {
Self { key_pair: kp } Self { key_pair: kp }
} }
} }

View File

@ -14,24 +14,24 @@
* limitations under the License. * limitations under the License.
*/ */
use crate::ed25519::PublicKey; use ed25519_dalek::PublicKey;
use ref_cast::RefCast; use ref_cast::RefCast;
use serde::Deserialize;
use std::{ use std::{
fmt::{Display, Formatter}, fmt::{Display, Formatter},
hash::{Hash, Hasher}, hash::{Hash, Hasher},
}; };
use core::fmt;
/// Wrapper to use PublicKey in HashMap /// Wrapper to use PublicKey in HashMap
#[derive(PartialEq, Eq, Debug, Clone, RefCast, Deserialize)] #[derive(PartialEq, Eq, Debug, Clone, RefCast)]
#[repr(transparent)] #[repr(transparent)]
pub struct PublicKeyHashable(PublicKey); pub struct PublicKeyHashable(PublicKey);
#[allow(clippy::derive_hash_xor_eq)] #[allow(clippy::derive_hash_xor_eq)]
impl Hash for PublicKeyHashable { impl Hash for PublicKeyHashable {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
state.write(&self.0.encode()); state.write(&self.0.to_bytes());
state.finish(); state.finish();
} }
@ -42,7 +42,7 @@ impl Hash for PublicKeyHashable {
// TODO check for overflow // TODO check for overflow
let mut bytes: Vec<u8> = Vec::with_capacity(data.len() * 32); let mut bytes: Vec<u8> = Vec::with_capacity(data.len() * 32);
for d in data { for d in data {
bytes.extend_from_slice(&d.0.encode()) bytes.extend_from_slice(&d.0.to_bytes())
} }
state.write(bytes.as_slice()); state.write(bytes.as_slice());
state.finish(); state.finish();
@ -75,6 +75,46 @@ impl AsRef<PublicKeyHashable> for PublicKey {
impl Display for PublicKeyHashable { impl Display for PublicKeyHashable {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", bs58::encode(self.0.encode()).into_string()) write!(f, "{}", bs58::encode(self.0.to_bytes()).into_string())
}
}
impl <'de>serde::Deserialize<'de> for PublicKeyHashable {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de> {
use serde::de::{Error, Visitor};
struct PKVisitor;
impl<'de> Visitor<'de> for PKVisitor {
type Value = PublicKeyHashable;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("byte array or base58 string")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: Error,
{
bs58::decode(s)
.into_vec()
.map_err(|err| Error::custom(format!("Invalid string '{}': {}", s, err)))
.and_then(|v| self.visit_bytes(v.as_slice()))
.map_err(|err: E| Error::custom(format!("Parsed string '{}' as base58, but {}", s, err)))
}
fn visit_bytes<E>(self, b: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
let pk = PublicKey::from_bytes(b)
.map_err(|err| Error::custom(format!("Invalid bytes {:?}: {}", b, err)))?;
Ok(PublicKeyHashable::from(pk))
}
}
deserializer.deserialize_str(PKVisitor)
} }
} }

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
use crate::ed25519::PublicKey; use ed25519_dalek::PublicKey;
use crate::key_pair::KeyPair; use crate::key_pair::KeyPair;
use crate::key_pair::Signature; use crate::key_pair::Signature;
use crate::trust::{EXPIRATION_LEN, PK_LEN}; use crate::trust::{EXPIRATION_LEN, PK_LEN};
@ -61,7 +61,7 @@ impl Revoke {
fn signature_bytes(pk: &PublicKey, revoked_at: Duration) -> Vec<u8> { fn signature_bytes(pk: &PublicKey, revoked_at: Duration) -> Vec<u8> {
let mut msg = Vec::with_capacity(PK_LEN + EXPIRATION_LEN); let mut msg = Vec::with_capacity(PK_LEN + EXPIRATION_LEN);
msg.extend_from_slice(&pk.encode()); msg.extend_from_slice(&pk.to_bytes());
msg.extend_from_slice(&(revoked_at.as_secs() as u64).to_le_bytes()); msg.extend_from_slice(&(revoked_at.as_secs() as u64).to_le_bytes());
msg msg
@ -71,14 +71,10 @@ impl Revoke {
pub fn verify(revoke: &Revoke) -> Result<(), String> { pub fn verify(revoke: &Revoke) -> Result<(), String> {
let msg = Revoke::signature_bytes(&revoke.pk, revoke.revoked_at); let msg = Revoke::signature_bytes(&revoke.pk, revoke.revoked_at);
if !revoke revoke
.revoked_by .revoked_by
.verify(msg.as_slice(), revoke.signature.as_slice()) .verify_strict(msg.as_slice(), &revoke.signature)
{ .map_err(|err| format!("Revoke has incorrect signature: {:?}", err))
return Err("Revoke has incorrect signature.".to_string());
}
Ok(())
} }
} }

View File

@ -14,11 +14,12 @@
* limitations under the License. * limitations under the License.
*/ */
use crate::ed25519::PublicKey; use ed25519_dalek::{PublicKey};
use crate::key_pair::{KeyPair, Signature}; use crate::key_pair::{KeyPair, Signature};
use derivative::Derivative; use derivative::Derivative;
use std::convert::TryInto; use std::convert::TryInto;
use std::time::Duration; use std::time::Duration;
use signature::{Signature as SigSignature};
pub const SIG_LEN: usize = 64; pub const SIG_LEN: usize = 64;
pub const PK_LEN: usize = 32; pub const PK_LEN: usize = 32;
@ -46,11 +47,11 @@ pub struct Trust {
} }
fn show_pubkey(key: &PublicKey, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { fn show_pubkey(key: &PublicKey, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{}", bs58::encode(key.encode()).into_string()) write!(f, "{}", bs58::encode(&key.to_bytes()).into_string())
} }
fn show_sig(sig: &[u8], f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { fn show_sig(sig: &ed25519_dalek::Signature, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{}", bs58::encode(sig).into_string()) write!(f, "{}", bs58::encode(&sig.to_bytes()).into_string())
} }
impl Trust { impl Trust {
@ -96,13 +97,13 @@ impl Trust {
let msg: &[u8] = let msg: &[u8] =
&Self::metadata_bytes(&trust.issued_for, trust.expires_at, trust.issued_at); &Self::metadata_bytes(&trust.issued_for, trust.expires_at, trust.issued_at);
KeyPair::verify(issued_by, msg, trust.signature.as_slice())?; KeyPair::verify(issued_by, msg, trust.signature)?;
Ok(()) Ok(())
} }
fn metadata_bytes(pk: &PublicKey, expires_at: Duration, issued_at: Duration) -> [u8; 48] { fn metadata_bytes(pk: &PublicKey, expires_at: Duration, issued_at: Duration) -> [u8; 48] {
let pk_encoded = pk.encode(); let pk_encoded = pk.to_bytes();
let expires_at_encoded: [u8; EXPIRATION_LEN] = (expires_at.as_secs() as u64).to_le_bytes(); let expires_at_encoded: [u8; EXPIRATION_LEN] = (expires_at.as_secs() as u64).to_le_bytes();
let issued_at_encoded: [u8; ISSUED_LEN] = (issued_at.as_secs() as u64).to_le_bytes(); let issued_at_encoded: [u8; ISSUED_LEN] = (issued_at.as_secs() as u64).to_le_bytes();
let mut metadata = [0; METADATA_LEN]; let mut metadata = [0; METADATA_LEN];
@ -120,8 +121,8 @@ impl Trust {
#[allow(dead_code)] #[allow(dead_code)]
pub fn encode(&self) -> Vec<u8> { pub fn encode(&self) -> Vec<u8> {
let mut vec = Vec::with_capacity(TRUST_LEN); let mut vec = Vec::with_capacity(TRUST_LEN);
vec.extend_from_slice(&self.issued_for.encode()); vec.extend_from_slice(&self.issued_for.to_bytes());
vec.extend_from_slice(&self.signature.as_slice()); vec.extend_from_slice(&self.signature.to_bytes());
vec.extend_from_slice(&(self.expires_at.as_secs() as u64).to_le_bytes()); vec.extend_from_slice(&(self.expires_at.as_secs() as u64).to_le_bytes());
vec.extend_from_slice(&(self.issued_at.as_secs() as u64).to_le_bytes()); vec.extend_from_slice(&(self.issued_at.as_secs() as u64).to_le_bytes());
@ -137,8 +138,10 @@ impl Trust {
); );
} }
let pk = PublicKey::decode(&arr[0..PK_LEN]).map_err(|err| err.to_string())?; let pk = PublicKey::from_bytes(&arr[0..PK_LEN]).map_err(|err| err.to_string())?;
let signature = &arr[PK_LEN..PK_LEN + SIG_LEN]; let signature = &arr[PK_LEN..PK_LEN + SIG_LEN];
let signature = Signature::from_bytes(signature).map_err(|err| err.to_string())?;
let expiration_bytes = &arr[PK_LEN + SIG_LEN..PK_LEN + SIG_LEN + EXPIRATION_LEN]; let expiration_bytes = &arr[PK_LEN + SIG_LEN..PK_LEN + SIG_LEN + EXPIRATION_LEN];
let expiration_date = u64::from_le_bytes(expiration_bytes.try_into().unwrap()); let expiration_date = u64::from_le_bytes(expiration_bytes.try_into().unwrap());
@ -150,7 +153,7 @@ impl Trust {
Ok(Self { Ok(Self {
issued_for: pk, issued_for: pk,
signature: signature.to_vec(), signature: signature,
expires_at: expiration_date, expires_at: expiration_date,
issued_at: issued_date, issued_at: issued_date,
}) })
@ -183,7 +186,7 @@ impl Trust {
) -> Result<Self, String> { ) -> Result<Self, String> {
// PublicKey // PublicKey
let issued_for_bytes = Self::bs58_str_to_vec(issued_for, "issued_for")?; let issued_for_bytes = Self::bs58_str_to_vec(issued_for, "issued_for")?;
let issued_for = PublicKey::decode(issued_for_bytes.as_slice()).map_err(|e| { let issued_for = PublicKey::from_bytes(issued_for_bytes.as_slice()).map_err(|e| {
format!( format!(
"Cannot decode the public key: {} in the trust '{}'", "Cannot decode the public key: {} in the trust '{}'",
issued_for, e issued_for, e
@ -192,6 +195,7 @@ impl Trust {
// 64 bytes signature // 64 bytes signature
let signature = Self::bs58_str_to_vec(signature, "signature")?; let signature = Self::bs58_str_to_vec(signature, "signature")?;
let signature = Signature::from_bytes(&signature).map_err(|err| err.to_string())?;
// Duration // Duration
let expires_at = Self::str_to_duration(expires_at, "expires_at")?; let expires_at = Self::str_to_duration(expires_at, "expires_at")?;
@ -205,8 +209,8 @@ impl Trust {
impl ToString for Trust { impl ToString for Trust {
fn to_string(&self) -> String { fn to_string(&self) -> String {
let issued_for = bs58::encode(self.issued_for.encode()).into_string(); let issued_for = bs58::encode(self.issued_for.to_bytes()).into_string();
let signature = bs58::encode(self.signature.as_slice()).into_string(); let signature = bs58::encode(self.signature.to_bytes()).into_string();
let expires_at = (self.expires_at.as_secs() as u64).to_string(); let expires_at = (self.expires_at.as_secs() as u64).to_string();
let issued_at = (self.issued_at.as_secs() as u64).to_string(); let issued_at = (self.issued_at.as_secs() as u64).to_string();

View File

@ -15,7 +15,7 @@
*/ */
use crate::certificate::Certificate; use crate::certificate::Certificate;
use crate::ed25519::PublicKey; use ed25519_dalek::PublicKey;
use crate::public_key_hashable::PublicKeyHashable; use crate::public_key_hashable::PublicKeyHashable;
use crate::revoke::Revoke; use crate::revoke::Revoke;
use crate::trust::Trust; use crate::trust::Trust;

View File

@ -2,7 +2,7 @@ use crate::public_key_hashable::PublicKeyHashable;
use crate::revoke::Revoke; use crate::revoke::Revoke;
use crate::trust_graph::Weight; use crate::trust_graph::Weight;
use crate::trust_node::{Auth, TrustNode}; use crate::trust_node::{Auth, TrustNode};
use libp2p_core::identity::ed25519::PublicKey; use ed25519_dalek::PublicKey;
use std::collections::HashMap; use std::collections::HashMap;
use std::time::Duration; use std::time::Duration;

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
use crate::ed25519::PublicKey; use ed25519_dalek::PublicKey;
use crate::public_key_hashable::PublicKeyHashable; use crate::public_key_hashable::PublicKeyHashable;
use crate::revoke::Revoke; use crate::revoke::Revoke;
use crate::trust::Trust; use crate::trust::Trust;