Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
crypto: Cleanup `hash` module
Alexis Sellier committed 3 years ago
commit 7e1b2b6222ab5b3c98d97ca20b47996d7d961022
parent ef0628c48e85d55feea03632831b3e418d67a9ec
9 files changed +16 -123
modified Cargo.lock
@@ -1929,7 +1929,6 @@ dependencies = [
 "qcheck-macros",
 "radicle-ssh",
 "serde",
-
 "sha2 0.10.6",
 "sqlite",
 "ssh-key",
 "tempfile",
modified radicle-cli/examples/rad-auth.md
@@ -21,7 +21,7 @@ $ rad self
ID             did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
Node ID        z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
Key (hash)     SHA256:UIedaL6Cxm6OUErh9GQUzzglSk7VpQlVTI1TAFB/HWA
-
Key (full)     AAAAC3NzaC1lZDI1NTE5AAAAIHahWSBEpuT1ESZbynOmBNkLBSnR32Ar4woZqSV2YNH1
+
Key (full)     ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHahWSBEpuT1ESZbynOmBNkLBSnR32Ar4woZqSV2YNH1
Storage (git)  [..]/storage
Storage (keys) [..]/keys
Node (socket)  [..]/node/radicle.sock
modified radicle-crypto/Cargo.toml
@@ -18,7 +18,6 @@ cyphernet = { version = "0.2.0", optional = true }
multibase = { version = "0.9.1" }
ec25519 = { version = "0.1.0", features = [] }
serde = { version = "1", features = ["derive"] }
-
sha2 = { version = "0.10.2" }
sqlite = { version = "0.30.3", optional = true }
thiserror = { version = "1" }
zeroize = { version = "1.5.7" }
deleted radicle-crypto/src/hash.rs
@@ -1,69 +0,0 @@
-
use std::{convert::TryInto, fmt};
-

-
use serde::{Deserialize, Serialize};
-
use sha2::{
-
    digest::{generic_array::GenericArray, OutputSizeUser},
-
    Digest as _, Sha256,
-
};
-
use thiserror::Error;
-

-
#[derive(Debug, Clone, PartialEq, Eq, Error)]
-
pub enum DecodeError {
-
    #[error("invalid digest length {0}")]
-
    InvalidLength(usize),
-
}
-

-
/// A SHA-256 hash.
-
#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-
pub struct Digest([u8; 32]);
-

-
impl Digest {
-
    pub fn new(bytes: impl AsRef<[u8]>) -> Self {
-
        Self::from(Sha256::digest(bytes))
-
    }
-
}
-

-
impl AsRef<[u8; 32]> for Digest {
-
    fn as_ref(&self) -> &[u8; 32] {
-
        &self.0
-
    }
-
}
-

-
impl fmt::Debug for Digest {
-
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-
        write!(f, "Hash({self})")
-
    }
-
}
-

-
impl fmt::Display for Digest {
-
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-
        for byte in &self.0 {
-
            write!(f, "{byte:02x}")?;
-
        }
-
        Ok(())
-
    }
-
}
-

-
impl From<[u8; 32]> for Digest {
-
    fn from(bytes: [u8; 32]) -> Self {
-
        Self(bytes)
-
    }
-
}
-

-
impl TryFrom<&[u8]> for Digest {
-
    type Error = DecodeError;
-

-
    fn try_from(bytes: &[u8]) -> Result<Self, DecodeError> {
-
        let bytes: [u8; 32] = bytes
-
            .try_into()
-
            .map_err(|_| DecodeError::InvalidLength(bytes.len()))?;
-

-
        Ok(bytes.into())
-
    }
-
}
-

-
impl From<GenericArray<u8, <Sha256 as OutputSizeUser>::OutputSize>> for Digest {
-
    fn from(array: GenericArray<u8, <Sha256 as OutputSizeUser>::OutputSize>) -> Self {
-
        Self(array.into())
-
    }
-
}
modified radicle-crypto/src/lib.rs
@@ -8,7 +8,6 @@ use thiserror::Error;

pub use ed25519::{edwards25519, Error, KeyPair, Seed};

-
pub mod hash;
#[cfg(feature = "ssh")]
pub mod ssh;
#[cfg(any(test, feature = "test"))]
@@ -166,6 +165,13 @@ impl cyphernet::display::MultiDisplay<cyphernet::display::Encoding> for PublicKe
    }
}

+
#[cfg(feature = "ssh")]
+
impl From<PublicKey> for ssh_key::PublicKey {
+
    fn from(key: PublicKey) -> Self {
+
        ssh_key::PublicKey::from(ssh_key::public::Ed25519PublicKey(**key))
+
    }
+
}
+

#[cfg(feature = "cyphernet")]
impl cyphernet::EcPk for PublicKey {
    const COMPRESSED_LEN: usize = 32;
modified radicle-crypto/src/ssh.rs
@@ -16,35 +16,20 @@ use crate::PublicKey;
pub use keystore::{Keystore, Passphrase};

pub mod fmt {
-
    use radicle_ssh::encoding::Encoding as _;
-

    use crate::PublicKey;

    /// Get the SSH long key from a public key.
    /// This is the output of `ssh-add -L`.
    pub fn key(key: &PublicKey) -> String {
-
        let mut buf = Vec::new();
-

-
        buf.extend_ssh_string(b"ssh-ed25519");
-
        buf.extend_ssh_string(key.as_ref());
-

-
        base64::encode_config(buf, base64::STANDARD_NO_PAD)
+
        ssh_key::PublicKey::from(*key).to_string()
    }

    /// Get the SSH key fingerprint from a public key.
    /// This is the output of `ssh-add -l`.
    pub fn fingerprint(key: &PublicKey) -> String {
-
        use sha2::Digest;
-

-
        let mut buf = Vec::new();
-

-
        buf.extend_ssh_string(b"ssh-ed25519");
-
        buf.extend_ssh_string(key.as_ref());
-

-
        let sha = sha2::Sha256::digest(&buf).to_vec();
-
        let encoded = base64::encode_config(sha, base64::STANDARD_NO_PAD);
-

-
        format!("SHA256:{encoded}")
+
        ssh_key::PublicKey::from(*key)
+
            .fingerprint(Default::default())
+
            .to_string()
    }

    #[cfg(test)]
@@ -61,7 +46,7 @@ pub mod fmt {

            assert_eq!(
                key(&pk),
-
                "AAAAC3NzaC1lZDI1NTE5AAAAINDoXIrhcnRjnLGUXUFdxhkuy08lkTOwrj2IoGsEX6+Q"
+
                "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINDoXIrhcnRjnLGUXUFdxhkuy08lkTOwrj2IoGsEX6+Q"
            );
        }

@@ -431,7 +416,8 @@ AAAAQI84aPZsXxlQigpy1/Y/iJSmHSS//CIgvqvUMQIb/TM2vhCKruduH0cK02k9G8wOI+
EUMf2bSDyxbJyZThOEiAs=
-----END SSH SIGNATURE-----";

-
        let public_key = "AAAAC3NzaC1lZDI1NTE5AAAAIL460KIEccS4881p7PPpiiQBsxF+H5tgC6De6crw9rbU";
+
        let public_key =
+
            "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL460KIEccS4881p7PPpiiQBsxF+H5tgC6De6crw9rbU";
        let signature = ExtendedSignature::from_armored(armored).unwrap();

        assert_eq!(signature.version, 1);
modified radicle-crypto/src/test/arbitrary.rs
@@ -1,6 +1,6 @@
use qcheck::Arbitrary;

-
use crate::{hash, test::signer::MockSigner, KeyPair, PublicKey, SecretKey, Seed};
+
use crate::{test::signer::MockSigner, KeyPair, PublicKey, SecretKey, Seed};

impl Arbitrary for MockSigner {
    fn arbitrary(g: &mut qcheck::Gen) -> Self {
@@ -21,10 +21,3 @@ impl Arbitrary for PublicKey {
        PublicKey(keypair.pk)
    }
}
-

-
impl Arbitrary for hash::Digest {
-
    fn arbitrary(g: &mut qcheck::Gen) -> Self {
-
        let bytes: Vec<u8> = Arbitrary::arbitrary(g);
-
        hash::Digest::new(bytes)
-
    }
-
}
modified radicle-node/src/lib.rs
@@ -23,7 +23,6 @@ pub use runtime::Runtime;
pub mod prelude {
    pub use crate::bounded::BoundedVec;
    pub use crate::clock::Timestamp;
-
    pub use crate::crypto::hash::Digest;
    pub use crate::crypto::{PublicKey, Signature, Signer};
    pub use crate::deserializer::Deserializer;
    pub use crate::identity::{Did, Id};
modified radicle-node/src/wire.rs
@@ -12,7 +12,6 @@ use std::{io, mem};

use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};

-
use crate::crypto::hash::Digest;
use crate::crypto::{PublicKey, Signature, Unverified};
use crate::git;
use crate::git::fmt;
@@ -189,12 +188,6 @@ impl Encode for git::Url {
    }
}

-
impl Encode for Digest {
-
    fn encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
-
        self.as_ref().encode(writer)
-
    }
-
}
-

impl Encode for Id {
    fn encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
        self.deref().encode(writer)
@@ -396,14 +389,6 @@ impl Decode for Id {
    }
}

-
impl Decode for Digest {
-
    fn decode<R: io::Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
-
        let bytes: [u8; 32] = Decode::decode(reader)?;
-

-
        Ok(Self::from(bytes))
-
    }
-
}
-

impl Encode for filter::Filter {
    fn encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
        let mut n = 0;
@@ -532,11 +517,6 @@ mod tests {
    }

    #[quickcheck]
-
    fn prop_digest(input: Digest) {
-
        assert_eq!(deserialize::<Digest>(&serialize(&input)).unwrap(), input);
-
    }
-

-
    #[quickcheck]
    fn prop_refs(input: Refs) {
        assert_eq!(deserialize::<Refs>(&serialize(&input)).unwrap(), input);
    }