1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
//! ECC implementation for curve ED25519.

use sodiumoxide::crypto::sign::ed25519::{
    gen_keypair, keypair_from_seed, sign_detached as ed25519_sign,
    verify_detached as ed25519_verify, PublicKey, SecretKey, Seed, Signature,
};
use std::option::NoneError;

use crate::algo as base;
use base::hash::asymmetric as asymm;

pub struct KeyPair {
    private: Option<SecretKey>,
    public: PublicKey,
}
impl KeyPair {
    fn create_from(sk: Option<SecretKey>, pk: PublicKey) -> Self {
        Self {
            private: sk,
            public: pk,
        }
    }
}
impl Clone for KeyPair {
    fn clone(&self) -> Self {
        // source should be valid if KeyPair had been successfully created, especially since it
        // worked last time.
        Self::create_from(self.private.clone(), self.public.clone())
    }
}
impl base::SafeGenerateKey for KeyPair {
    type Settings = Option<Seed>;
    fn safe_generate(seed: &Self::Settings) -> Self {
        // rust openssl as of 0.10.24 automatically uses required 65537 for exponent
        let (public, private) = if let Some(seed) = seed.as_ref() {
            keypair_from_seed(seed) // TODO probably a bad idea
        } else {
            gen_keypair()
        };
        Self::create_from(Some(private), public)
    }
}
impl asymm::KeyPair for KeyPair {
    type Private = SecretKey;
    type Public = PublicKey;
    fn public_key(&self) -> &Self::Public {
        &self.public
    }
    fn private_key<'a>(&'a self) -> Option<&'a Self::Private> {
        self.private.as_ref()
    }
}

#[derive(Debug)]
pub enum AlgoError {
    DoesNotHavePrivateKey,
    MismatchedSignatureLength,
}
impl From<NoneError> for AlgoError {
    fn from(_: NoneError) -> Self {
        Self::DoesNotHavePrivateKey
    }
}

pub struct Algo;
impl base::Algo for Algo {
    type Key = KeyPair;
    fn key_settings<'a>(&'a self) -> &'a <<Self as base::Algo>::Key as base::Key>::Settings {
        &None
    }
    fn new(_: Self::ConstructionData) -> Self {
        Self
    }
}
impl asymm::Algo for Algo {
    type SigningError = AlgoError;
    type VerifyError = AlgoError;

    /// unimplemented
    fn sign_public(
        _msg: &[u8],
        _key: &<Self::Key as asymm::KeyPair>::Public,
    ) -> Result<Vec<u8>, Self::SigningError> {
        unimplemented!("Unimplemented by ring");
    }
    fn verify_public(
        msg: &[u8],
        signature: &[u8],
        key: &<Self::Key as asymm::KeyPair>::Public,
    ) -> Result<bool, Self::VerifyError> {
        let signature =
            Signature::from_slice(signature).ok_or(Self::VerifyError::MismatchedSignatureLength)?;
        Ok(ed25519_verify(&signature, msg, key))
    }
    fn sign_private(
        msg: &[u8],
        key: Option<&<Self::Key as asymm::KeyPair>::Private>,
    ) -> Result<Vec<u8>, Self::SigningError> {
        Ok(ed25519_sign(msg, key.as_ref()?).as_ref().to_vec())
    }
    /// unimplemented
    fn verify_private(
        _msg: &[u8],
        _signature: &[u8],
        _key: Option<&<Self::Key as asymm::KeyPair>::Private>,
    ) -> Result<bool, Self::VerifyError> {
        unimplemented!("Unimplemented by ring");
    }
}