mirror of
https://github.com/fluencelabs/trust-graph
synced 2024-12-04 15:20:19 +00:00
WIP
This commit is contained in:
parent
9e74777fe5
commit
a0261bc331
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1330,6 +1330,7 @@ dependencies = [
|
||||
"ref-cast",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"signature",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -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
2
bin/Cargo.lock
generated
@ -1370,9 +1370,11 @@ dependencies = [
|
||||
"failure",
|
||||
"fluence-fork-libp2p-core",
|
||||
"log",
|
||||
"rand 0.7.3",
|
||||
"ref-cast",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"signature",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -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;
|
||||
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
30
src/trust.rs
30
src/trust.rs
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user