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
pub mod server;
pub mod client;

use std::fmt::{Debug, Display, Formatter, Pointer};
use argon2::Argon2;
use curve25519_dalek;
use curve25519_dalek::ristretto::RistrettoPoint;
use opaque_ke::ciphersuite::CipherSuite;
use sha2;
use base64::DecodeError;
use digest::Digest;
use digest::generic_array::GenericArray;
use digest::generic_array::typenum::Unsigned;
use opaque_ke::errors::{InternalPakeError};
pub use opaque_ke::errors::{PakeError, ProtocolError};
use opaque_ke::hash::Hash;
use opaque_ke::keypair::KeyPair;
use opaque_ke::slow_hash::SlowHash;
use rand::rngs::OsRng;

pub struct Cipher;
impl CipherSuite for Cipher {
    type Group = curve25519_dalek::ristretto::RistrettoPoint;
    type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
    type Hash = sha2::Sha512;
    type SlowHash = ArgonWrapper;
}

pub struct ArgonWrapper(Argon2<'static>);

impl<D: Hash> SlowHash<D> for ArgonWrapper {
    fn hash(
        input: GenericArray<u8, <D as Digest>::OutputSize>,
    ) -> Result<Vec<u8>, InternalPakeError> {
        let params = Argon2::default();
        let mut output = vec![0u8; <D as Digest>::OutputSize::to_usize()];
        params
            .hash_password_into(
                &input,
                &[0; argon2::MIN_SALT_LEN],
                &mut output,
            )
            .map_err(|_| InternalPakeError::SlowHashError)?;
        Ok(output)
    }
}

#[derive(Debug)]
pub enum Error {
    ProtocolError(ProtocolError),
    PakeError(PakeError),
    DecodeError(DecodeError)
}

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

impl std::error::Error for Error {}

impl From<ProtocolError> for Error {
    fn from(e: ProtocolError) -> Self {
        Error::ProtocolError(e)
    }
}

impl From<PakeError> for Error {
    fn from(e: PakeError) -> Self {
        Error::PakeError(e)
    }
}

impl From<DecodeError> for Error {
    fn from(e: DecodeError) -> Self {
        Error::DecodeError(e)
    }
}

pub fn generate_keys() -> (String, String) {
    let keypair = generate_keys_compute();
    let private_key = keypair.private().to_vec();
    let public_key = keypair.public().to_vec();

    let private_encoded = base64::encode_config(private_key, base64::URL_SAFE_NO_PAD);
    let public_encoded = base64::encode_config(public_key, base64::URL_SAFE_NO_PAD);

    (private_encoded, public_encoded)
}

fn generate_keys_compute() -> KeyPair<RistrettoPoint> {
    let mut rng = OsRng;
    Cipher::generate_random_keypair(&mut rng)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn gen_test() {
        let (privt, publ) = generate_keys();
        println!("{}", privt);
        println!("{}", publ);
    }
}