Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
node: Create crypto module
Alexis Sellier committed 3 years ago
commit 66d580019b36141927684949682639af06f79e4f
parent b78bbc4ecc0d867a1e800b95ff17d1af9bd71cb3
4 files changed +76 -66
added node/src/crypto.rs
@@ -0,0 +1,65 @@
+
use std::{fmt, ops::Deref, str::FromStr};
+

+
use ed25519_consensus as ed25519;
+
use serde::{Deserialize, Serialize};
+
use thiserror::Error;
+

+
#[derive(Serialize, Deserialize, Eq, Debug, Clone)]
+
#[serde(transparent)]
+
pub struct PublicKey(pub ed25519::VerificationKey);
+

+
#[derive(Error, Debug)]
+
pub enum PublicKeyError {
+
    #[error("invalid length {0}")]
+
    InvalidLength(usize),
+
    #[error("invalid multibase string: {0}")]
+
    Multibase(#[from] multibase::Error),
+
    #[error("invalid key: {0}")]
+
    InvalidKey(#[from] ed25519_consensus::Error),
+
}
+

+
impl std::hash::Hash for PublicKey {
+
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+
        self.0.as_bytes().hash(state)
+
    }
+
}
+

+
impl fmt::Display for PublicKey {
+
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+
        write!(f, "{}", self.encode())
+
    }
+
}
+

+
impl PartialEq for PublicKey {
+
    fn eq(&self, other: &Self) -> bool {
+
        self.0 == other.0
+
    }
+
}
+

+
impl PublicKey {
+
    pub fn encode(&self) -> String {
+
        multibase::encode(multibase::Base::Base58Btc, &self.0)
+
    }
+
}
+

+
impl FromStr for PublicKey {
+
    type Err = PublicKeyError;
+

+
    fn from_str(s: &str) -> Result<Self, Self::Err> {
+
        let (_, bytes) = multibase::decode(s)?;
+
        let array: [u8; 32] = bytes
+
            .try_into()
+
            .map_err(|v: Vec<u8>| PublicKeyError::InvalidLength(v.len()))?;
+
        let key = ed25519::VerificationKey::try_from(ed25519::VerificationKeyBytes::from(array))?;
+

+
        Ok(Self(key))
+
    }
+
}
+

+
impl Deref for PublicKey {
+
    type Target = ed25519::VerificationKey;
+

+
    fn deref(&self) -> &Self::Target {
+
        &self.0
+
    }
+
}
modified node/src/identity.rs
@@ -1,13 +1,16 @@
-
use std::{ffi::OsString, fmt, io, ops::Deref, str::FromStr};
+
use std::{ffi::OsString, fmt, io, str::FromStr};

-
use ed25519_consensus::{VerificationKey, VerificationKeyBytes};
use nonempty::NonEmpty;
use radicle_git_ext::Oid;
use serde::{Deserialize, Serialize};
use thiserror::Error;

+
use crate::crypto;
use crate::hash;

+
/// A user's identifier is simply their public key.
+
pub type UserId = crypto::PublicKey;
+

#[derive(Error, Debug)]
pub enum ProjIdError {
    #[error("invalid digest: {0}")]
@@ -59,10 +62,10 @@ impl From<hash::Digest> for ProjId {
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Hash, Debug, Clone)]
-
pub struct Did(UserId);
+
pub struct Did(crypto::PublicKey);

impl Did {
-
    fn encode(&self) -> String {
+
    pub fn encode(&self) -> String {
        format!("did:key:{}", self.0.encode())
    }
}
@@ -73,66 +76,6 @@ impl fmt::Display for Did {
    }
}

-
#[derive(Serialize, Deserialize, Eq, Debug, Clone)]
-
#[serde(transparent)]
-
pub struct UserId(pub VerificationKey);
-

-
impl std::hash::Hash for UserId {
-
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-
        self.0.as_bytes().hash(state)
-
    }
-
}
-

-
impl fmt::Display for UserId {
-
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-
        write!(f, "{}", self.encode())
-
    }
-
}
-

-
impl PartialEq for UserId {
-
    fn eq(&self, other: &Self) -> bool {
-
        self.0 == other.0
-
    }
-
}
-

-
impl UserId {
-
    fn encode(&self) -> String {
-
        multibase::encode(multibase::Base::Base58Btc, &self.0)
-
    }
-
}
-

-
impl FromStr for UserId {
-
    type Err = UserIdError;
-

-
    fn from_str(s: &str) -> Result<Self, Self::Err> {
-
        let (_, bytes) = multibase::decode(s)?;
-
        let array: [u8; 32] = bytes
-
            .try_into()
-
            .map_err(|v: Vec<u8>| UserIdError::InvalidLength(v.len()))?;
-
        let key = VerificationKey::try_from(VerificationKeyBytes::from(array))?;
-

-
        Ok(Self(key))
-
    }
-
}
-

-
impl Deref for UserId {
-
    type Target = VerificationKey;
-

-
    fn deref(&self) -> &Self::Target {
-
        &self.0
-
    }
-
}
-

-
#[derive(Error, Debug)]
-
pub enum UserIdError {
-
    #[error("invalid length {0}")]
-
    InvalidLength(usize),
-
    #[error("invalid multibase string: {0}")]
-
    Multibase(#[from] multibase::Error),
-
    #[error("invalid key: {0}")]
-
    InvalidKey(#[from] ed25519_consensus::Error),
-
}
-

#[derive(Error, Debug)]
pub enum DocError {
    #[error("toml: {0}")]
modified node/src/lib.rs
@@ -5,6 +5,7 @@ mod address_book;
mod address_manager;
mod clock;
mod collections;
+
mod crypto;
mod decoder;
mod git;
mod hash;
modified node/src/test/arbitrary.rs
@@ -3,6 +3,7 @@ use std::hash::Hash;
use std::ops::RangeBounds;

use crate::collections::HashMap;
+
use crate::crypto::PublicKey;
use crate::hash;
use crate::identity::{ProjId, UserId};
use crate::storage;
@@ -76,7 +77,7 @@ impl quickcheck::Arbitrary for hash::Digest {
    }
}

-
impl quickcheck::Arbitrary for UserId {
+
impl quickcheck::Arbitrary for PublicKey {
    fn arbitrary(g: &mut quickcheck::Gen) -> Self {
        use ed25519_consensus::SigningKey;

@@ -88,6 +89,6 @@ impl quickcheck::Arbitrary for UserId {
        let sk = SigningKey::from(bytes);
        let vk = sk.verification_key();

-
        UserId(vk)
+
        PublicKey(vk)
    }
}