networky 0.1.1

networking library for indigo with NaCl (Curve25519) encrypted connections and an async progress monitor.
Documentation
pub mod progress;
pub use crate::progress::*;

pub mod nacl;
pub use crate::nacl::*;

#[cfg(feature = "totp")]
mod totp {
    use hmac::{Hmac, Mac};
    use sha1::Sha1;

    type HmacSha1 = Hmac<Sha1>;

    const DIGITS_POWER: [u32; 9]
    // 0 1  2   3    4     5      6       7        8
    = [1,10,100,1000,10000,100000,1000000,10000000,100000000];

    fn generate_otp<const HASH_LENGTH: usize>(hash: [u8; HASH_LENGTH], code_digits: u8) -> String {
        let code_digits = if code_digits > 8 { 8 } else { code_digits };

        let offset = (hash[HASH_LENGTH-1] & 0xf) as usize;

        let binary : u32 = (((hash[offset] & 0x7f) as u32) << 24) |
            ((hash[offset + 1] as u32) << 16) |
            ((hash[offset + 2] as u32) << 8) |
            (hash[offset + 3] as u32);

        let otp = binary % DIGITS_POWER[code_digits as usize];

        format!("{:0code_digits$}", otp, code_digits = code_digits as usize)
    }

    fn calculate_otp_time(mut time: u64, d: i8) -> u64 {
      const T0: u64 = 0;
      time = (time - T0) / 30;
      time = ((time as i64) + d as i64) as u64;
      time
    }

    pub fn generate_otp_sha1(time: u64, d: i8, secret: &[u8], code_digits: u8) -> String {
        let time = calculate_otp_time(time, d);

        let mut mac = HmacSha1::new_from_slice(secret).unwrap();
        mac.update(&time.to_be_bytes());
        let hash = mac.finalize().into_bytes();

        generate_otp(hash.into(), code_digits)
    }
}

#[cfg(feature = "totp")]
pub use totp::*;

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

    #[cfg(feature = "totp")]
    #[test]
    fn totp() {
        let seed : [u8; 20] = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30];
        assert_eq!("94287082", generate_otp_sha1(59, 0, &seed, 8));
        assert_eq!("07081804", generate_otp_sha1(1111111109, 0, &seed, 8));
        assert_eq!("14050471", generate_otp_sha1(1111111111, 0, &seed, 8));
        assert_eq!("89005924", generate_otp_sha1(1234567890, 0, &seed, 8));
        assert_eq!("69279037", generate_otp_sha1(2000000000, 0, &seed, 8));
        assert_eq!("65353130", generate_otp_sha1(20000000000, 0, &seed, 8));
    }
}