tr1pd 0.3.1

tamper resistant audit log
Documentation
use std::ops::Deref;

pub use sodiumoxide::crypto::sign::{self, Signature, SecretKey, PublicKey};

pub mod ring;

pub use self::ring::{VerifyRing, SignRing};

mod errors {
    error_chain! {
        errors {
            InvalidSignature
            CorruptedKey
        }
    }
}
pub use self::errors::{Result, Error, ErrorKind};


pub fn gen_keypair() -> (PublicKey, SecretKey) {
    sign::gen_keypair()
}

pub fn sign(m: &[u8], sk: &SecretKey) -> Signature {
    sign::sign_detached(m, sk)
}

pub fn verify(sig: &Signature, m: &[u8], pk: &PublicKey) -> Result<()> {
    if sign::verify_detached(sig, m, pk) {
        Ok(())
    } else {
        Err(ErrorKind::InvalidSignature.into())
    }
}

pub fn to_pubkey(pk: &[u8]) -> Result<PublicKey> {
    match PublicKey::from_slice(pk) {
        Some(pk) => Ok(pk),
        None => Err(ErrorKind::CorruptedKey.into()),
    }
}

pub fn to_privkey(sk: &[u8]) -> Result<SecretKey> {
    match SecretKey::from_slice(sk) {
        Some(sk) => Ok(sk),
        None => Err(ErrorKind::CorruptedKey.into()),
    }
}


pub trait Signable {
    fn encode(&self) -> Vec<u8>;
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Signed<T: Signable>(pub T, pub Signature);

impl<T: Signable> Deref for Signed<T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &T {
        &self.0
    }
}

impl<T: Signable> Signed<T> {
    pub fn new(inner: T, signature: Signature) -> Signed<T> {
        Signed(inner, signature)
    }

    pub fn encode(&self) -> Vec<u8> {
        let mut buf = self.encode_inner();
        buf.extend(self.signature().0.iter());
        buf
    }

    fn encode_inner(&self) -> Vec<u8> {
        self.0.encode()
    }

    pub fn inner(&self) -> &T {
        &self.0
    }

    pub fn signature(&self) -> &Signature {
        &self.1
    }

    pub fn verify_session(&self, pubkey: &PublicKey) -> Result<()> {
        verify(&self.1, &self.0.encode(), pubkey)
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct Verified<T>(pub T);

impl<T> Deref for Verified<T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &T {
        &self.0
    }
}