add abstractions over ed25519: KP, PK, SK, Sig

This commit is contained in:
DieMyst 2021-01-19 18:28:13 +03:00
parent e922f7bf97
commit a4de8f25a9
14 changed files with 1556 additions and 54 deletions

5
Cargo.lock generated
View File

@ -361,13 +361,10 @@ name = "fluence-identity"
version = "0.2.0"
dependencies = [
"bs58 0.3.1",
"derivative",
"ed25519",
"ed25519-dalek",
"failure",
"fluence-fork-libp2p-core",
"log",
"rand 0.7.3",
"ref-cast",
"serde",
"serde_json",
"signature",

5
bin/Cargo.lock generated
View File

@ -371,13 +371,10 @@ name = "fluence-identity"
version = "0.2.0"
dependencies = [
"bs58 0.3.1",
"derivative",
"ed25519",
"ed25519-dalek",
"failure",
"fluence-fork-libp2p-core",
"log",
"rand 0.7.3",
"ref-cast",
"serde",
"serde_json",
"signature",

1421
identity/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -11,10 +11,7 @@ libp2p-core = { package = "fluence-fork-libp2p-core", version = "0.26.0" }
serde = { version = "=1.0.118", features = ["derive"] }
serde_json = "1.0.58"
bs58 = "0.3.1"
failure = "0.1.6"
log = "0.4.11"
ref-cast = "1.0.2"
derivative = "2.1.1"
ed25519-dalek = "1.0.1"
rand = "0.7.0"
signature = "1.3.0"
ed25519 = "1.0.3"

View File

@ -15,19 +15,62 @@
*/
use crate::ed25519::Keypair as Libp2pKeyPair;
use crate::signature::Signature;
use ed25519_dalek::SignatureError;
use ed25519_dalek::{PublicKey, SecretKey, Signer};
use ed25519_dalek::Signer;
use core::fmt::Debug;
use rand::rngs::OsRng;
use std::fmt;
pub type Signature = ed25519_dalek::Signature;
/// An Ed25519 keypair.
#[derive(Debug)]
pub struct KeyPair {
pub key_pair: ed25519_dalek::Keypair,
key_pair: ed25519_dalek::Keypair,
}
#[derive(Copy, Clone, Default, Eq, PartialEq)]
pub struct PublicKey(ed25519_dalek::PublicKey);
pub struct SecretKey(ed25519_dalek::SecretKey);
impl Debug for PublicKey {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
write!(f, "{:?}", self.0)
}
}
impl PublicKey {
pub fn verify_strict(
&self,
message: &[u8],
signature: &Signature,
) -> Result<(), SignatureError> {
self.0.verify_strict(message, &signature.0)
}
pub fn from_bytes(bytes: &[u8]) -> Result<PublicKey, SignatureError> {
let pk = ed25519_dalek::PublicKey::from_bytes(bytes)?;
Ok(PublicKey(pk))
}
pub fn to_bytes(&self) -> [u8; ed25519_dalek::PUBLIC_KEY_LENGTH] {
self.0.to_bytes()
}
}
impl SecretKey {
pub fn from_bytes(bytes: &[u8]) -> Result<SecretKey, SignatureError> {
let pk = ed25519_dalek::SecretKey::from_bytes(bytes)?;
Ok(SecretKey(pk))
}
}
impl AsRef<[u8]> for SecretKey {
fn as_ref(&self) -> &[u8] {
self.0.as_bytes()
}
}
impl KeyPair {
@ -39,6 +82,15 @@ impl KeyPair {
kp.into()
}
pub fn public(&self) -> PublicKey {
PublicKey(self.key_pair.public)
}
pub fn secret(&self) -> SecretKey {
let b = self.key_pair.secret.to_bytes();
SecretKey::from_bytes(&b).expect("SecretKey::from_bytes(to_bytes(k)) != k")
}
pub fn from_bytes(sk_bytes: &[u8]) -> Result<Self, SignatureError> {
let kp = ed25519_dalek::Keypair::from_bytes(sk_bytes)?;
Ok(KeyPair { key_pair: kp })
@ -61,19 +113,19 @@ impl KeyPair {
/// Get the public key of this keypair.
#[allow(dead_code)]
pub fn public_key(&self) -> PublicKey {
self.key_pair.public
PublicKey(self.key_pair.public)
}
/// Sign a message using the private key of this keypair.
pub fn sign(&self, msg: &[u8]) -> Signature {
self.key_pair.sign(msg)
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: Signature) -> Result<(), String> {
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))?;
pk.verify_strict(msg, &signature)
pk.verify_strict(msg, signature)
.map_err(|err| format!("Signature verification failed: {:?}", err))
}
}
@ -136,9 +188,9 @@ impl<'de> serde::Deserialize<'de> for KeyPair {
impl Clone for KeyPair {
fn clone(&self) -> KeyPair {
let mut sk_bytes = self.key_pair.secret.to_bytes();
let secret = SecretKey::from_bytes(&mut sk_bytes)
let secret = ed25519_dalek::SecretKey::from_bytes(&mut sk_bytes)
.expect("ed25519::SecretKey::from_bytes(to_bytes(k)) != k");
let public = PublicKey::from_bytes(&self.key_pair.public.to_bytes())
let public = ed25519_dalek::PublicKey::from_bytes(&self.key_pair.public.to_bytes())
.expect("ed25519::PublicKey::from_bytes(to_bytes(k)) != k");
KeyPair {
key_pair: ed25519_dalek::Keypair { secret, public },

View File

@ -27,7 +27,9 @@
)]
pub mod key_pair;
pub mod signature;
pub use key_pair::KeyPair;
pub use crate::key_pair::KeyPair;
pub use crate::signature::Signature;
pub(crate) use libp2p_core::identity::ed25519;

39
identity/src/signature.rs Normal file
View File

@ -0,0 +1,39 @@
/*
* Copyright 2020 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use signature::Signature as SigSignature;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Signature(pub ed25519_dalek::Signature);
pub const SIGNATURE_LENGTH: usize = 64;
impl Signature {
/// Create a new signature from a byte array
pub fn new(bytes: [u8; SIGNATURE_LENGTH]) -> Self {
Signature(ed25519_dalek::Signature::from(bytes))
}
/// Return the inner byte array
pub fn to_bytes(&self) -> [u8; SIGNATURE_LENGTH] {
self.0.to_bytes()
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, String> {
let sig = ed25519_dalek::Signature::from_bytes(bytes).map_err(|err| err.to_string())?;
Ok(Signature(sig))
}
}

View File

@ -15,8 +15,8 @@
*/
use crate::trust::{Trust, TRUST_LEN};
use ed25519_dalek::PublicKey;
use fluence_identity::key_pair::KeyPair;
use fluence_identity::key_pair::PublicKey;
use std::str::FromStr;
use std::time::Duration;
@ -261,7 +261,7 @@ mod tests {
let new_cert = Certificate::issue(
&second_kp,
third_kp.key_pair.public,
third_kp.public(),
&cert,
cur_time.checked_add(one_second()).unwrap(),
cur_time,
@ -288,7 +288,7 @@ mod tests {
let new_cert = Certificate::issue(
&second_kp,
third_kp.key_pair.public,
third_kp.public(),
&cert,
cur_time.checked_add(one_second()).unwrap(),
cur_time,
@ -348,7 +348,7 @@ mod tests {
let new_cert = Certificate::issue(
&second_kp,
third_kp.key_pair.public,
third_kp.public(),
&cert,
cur_time.checked_add(one_year()).unwrap(),
cur_time,
@ -359,18 +359,18 @@ mod tests {
println!(
"root_kp:\n\tprivate: {}\n\tpublic: {}",
bs58::encode(root_kp.clone().key_pair.secret).into_string(),
bs58::encode(&root_kp.key_pair.public.to_bytes().to_vec()).into_string()
bs58::encode(root_kp.clone().secret()).into_string(),
bs58::encode(&root_kp.public().to_bytes().to_vec()).into_string()
);
println!(
"second_kp:\n\tprivate: {}\n\tpublic: {}",
bs58::encode(second_kp.clone().key_pair.secret).into_string(),
bs58::encode(&second_kp.key_pair.public.to_bytes().to_vec()).into_string()
bs58::encode(second_kp.clone().secret()).into_string(),
bs58::encode(&second_kp.public().to_bytes().to_vec()).into_string()
);
println!(
"third_kp:\n\tprivate: {}\n\tpublic: {}",
bs58::encode(third_kp.clone().key_pair.secret).into_string(),
bs58::encode(&third_kp.key_pair.public.to_bytes().to_vec()).into_string()
bs58::encode(third_kp.clone().secret()).into_string(),
bs58::encode(&third_kp.public().to_bytes().to_vec()).into_string()
);
println!("cert is\n{}", new_cert.to_string());
@ -391,7 +391,7 @@ mod tests {
let new_cert = Certificate::issue(
&second_kp,
third_kp.key_pair.public,
third_kp.public(),
&cert,
cur_time.checked_sub(one_second()).unwrap(),
cur_time.checked_sub(one_minute()).unwrap(),
@ -413,7 +413,7 @@ mod tests {
let new_cert = Certificate::issue(
&second_kp,
third_kp.key_pair.public,
third_kp.public(),
&cert,
cur_time.checked_add(one_second()).unwrap(),
cur_time,
@ -422,7 +422,7 @@ mod tests {
.unwrap();
let new_cert = Certificate::issue(
&third_kp,
fourth_kp.key_pair.public,
fourth_kp.public(),
&new_cert,
cur_time.checked_add(one_second()).unwrap(),
cur_time,
@ -451,7 +451,7 @@ mod tests {
let new_cert = Certificate::issue(
&second_kp,
third_kp.key_pair.public,
third_kp.public(),
&cert,
cur_time.checked_add(one_second()).unwrap(),
cur_time,
@ -460,7 +460,7 @@ mod tests {
.unwrap();
let new_cert = Certificate::issue(
&second_kp,
fourth_kp.key_pair.public,
fourth_kp.public(),
&new_cert,
cur_time.checked_add(one_second()).unwrap(),
cur_time,
@ -485,7 +485,7 @@ mod tests {
let bad_kp = KeyPair::generate();
let new_cert_bad = Certificate::issue(
&bad_kp,
bad_kp.key_pair.public,
bad_kp.public(),
&cert,
cur_time.checked_add(one_second()).unwrap(),
cur_time,

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
use ed25519_dalek::PublicKey;
use fluence_identity::key_pair::PublicKey;
use core::fmt;
use ref_cast::RefCast;

View File

@ -15,9 +15,9 @@
*/
use crate::trust::{EXPIRATION_LEN, PK_LEN};
use ed25519_dalek::PublicKey;
use fluence_identity::key_pair::KeyPair;
use fluence_identity::key_pair::Signature;
use fluence_identity::key_pair::PublicKey;
use fluence_identity::signature::Signature;
use std::time::Duration;
/// "A document" that cancels trust created before.

View File

@ -15,9 +15,9 @@
*/
use derivative::Derivative;
use ed25519_dalek::PublicKey;
use fluence_identity::key_pair::{KeyPair, Signature};
use signature::Signature as SigSignature;
use fluence_identity::key_pair::KeyPair;
use fluence_identity::key_pair::PublicKey;
use fluence_identity::signature::Signature;
use std::convert::TryInto;
use std::time::Duration;
@ -50,10 +50,7 @@ fn show_pubkey(key: &PublicKey, f: &mut std::fmt::Formatter<'_>) -> Result<(), s
write!(f, "{}", bs58::encode(&key.to_bytes()).into_string())
}
fn show_sig(
sig: &ed25519_dalek::Signature,
f: &mut std::fmt::Formatter<'_>,
) -> Result<(), std::fmt::Error> {
fn show_sig(sig: &Signature, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{}", bs58::encode(&sig.to_bytes()).into_string())
}
@ -100,7 +97,7 @@ impl Trust {
let msg: &[u8] =
&Self::metadata_bytes(&trust.issued_for, trust.expires_at, trust.issued_at);
KeyPair::verify(issued_by, msg, trust.signature)?;
KeyPair::verify(issued_by, msg, &trust.signature)?;
Ok(())
}

View File

@ -20,7 +20,7 @@ use crate::revoke::Revoke;
use crate::trust::Trust;
use crate::trust_graph_storage::Storage;
use crate::trust_node::{Auth, TrustNode};
use ed25519_dalek::PublicKey;
use fluence_identity::key_pair::PublicKey;
use std::borrow::Borrow;
use std::collections::{HashSet, VecDeque};
use std::time::Duration;
@ -371,7 +371,7 @@ mod tests {
let st = Box::new(InMemoryStorage::new());
let mut graph = TrustGraph::new(st);
graph.add_root_weight(root.key_pair.public.into(), 0);
graph.add_root_weight(root.public().into(), 0);
let addition = graph.add(cert, current_time());
assert_eq!(addition.is_ok(), true);

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 ed25519_dalek::PublicKey;
use fluence_identity::key_pair::PublicKey;
use std::collections::HashMap;
use std::time::Duration;

View File

@ -17,8 +17,8 @@
use crate::public_key_hashable::PublicKeyHashable;
use crate::revoke::Revoke;
use crate::trust::Trust;
use ed25519_dalek::PublicKey;
use failure::_core::time::Duration;
use fluence_identity::key_pair::PublicKey;
use std::collections::HashMap;
#[derive(Debug, Clone)]