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",
"serde",
"serde_json",
"signature",
]
[[package]]

View File

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

2
bin/Cargo.lock generated
View File

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

View File

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

View File

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

View File

@ -14,24 +14,24 @@
* limitations under the License.
*/
use crate::ed25519::PublicKey;
use ed25519_dalek::PublicKey;
use ref_cast::RefCast;
use serde::Deserialize;
use std::{
fmt::{Display, Formatter},
hash::{Hash, Hasher},
};
use core::fmt;
/// Wrapper to use PublicKey in HashMap
#[derive(PartialEq, Eq, Debug, Clone, RefCast, Deserialize)]
#[derive(PartialEq, Eq, Debug, Clone, RefCast)]
#[repr(transparent)]
pub struct PublicKeyHashable(PublicKey);
#[allow(clippy::derive_hash_xor_eq)]
impl Hash for PublicKeyHashable {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write(&self.0.encode());
state.write(&self.0.to_bytes());
state.finish();
}
@ -42,7 +42,7 @@ impl Hash for PublicKeyHashable {
// TODO check for overflow
let mut bytes: Vec<u8> = Vec::with_capacity(data.len() * 32);
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.finish();
@ -75,6 +75,46 @@ impl AsRef<PublicKeyHashable> for PublicKey {
impl Display for PublicKeyHashable {
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.
*/
use crate::ed25519::PublicKey;
use ed25519_dalek::PublicKey;
use crate::key_pair::KeyPair;
use crate::key_pair::Signature;
use crate::trust::{EXPIRATION_LEN, PK_LEN};
@ -61,7 +61,7 @@ impl Revoke {
fn signature_bytes(pk: &PublicKey, revoked_at: Duration) -> Vec<u8> {
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
@ -71,14 +71,10 @@ impl Revoke {
pub fn verify(revoke: &Revoke) -> Result<(), String> {
let msg = Revoke::signature_bytes(&revoke.pk, revoke.revoked_at);
if !revoke
revoke
.revoked_by
.verify(msg.as_slice(), revoke.signature.as_slice())
{
return Err("Revoke has incorrect signature.".to_string());
}
Ok(())
.verify_strict(msg.as_slice(), &revoke.signature)
.map_err(|err| format!("Revoke has incorrect signature: {:?}", err))
}
}

View File

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

View File

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

View File

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

View File

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