ciph 0.1.0

Symmetric cipher layer for async read/write connections.
Documentation
use std::{
    fs::File,
    io::{Read, Cursor},
    str::FromStr,
    net::SocketAddr,
};

use tokio::{    
    io::{AsyncWriteExt, AsyncReadExt},
    net::TcpStream,
};

use ciph::salsa::{Psk, Connector, Randomness};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    const PSK_B64: &str = include_str!("example.psk");
    let psk = Psk::from_str(PSK_B64)?;
    let connector = Connector::new(psk, Randomness::Entropy);
    let args: Vec<String> = std::env::args()
        .collect();

    assert!(args.len() >= 3);

    let connect_addr = args[1].to_owned();
    let addr = SocketAddr::from_str(connect_addr.as_str())?;
    let tcp_stream = TcpStream::connect(addr).await?;
    let connect = connector.connect(tcp_stream);
    let mut stream = connect.await?;

    // Slurp our file.
    let filename = args[2].to_owned();
    let mut file =File::open(filename.as_str())?;
    let mut file_b = Vec::new();
    file.read_to_end(&mut file_b)?;

    let length = file_b.len();
    println!("File {} is {} bytes.", &filename, length);

    let mut cursor = Cursor::new(file_b);
    let mut received = Vec::new();
    let mut buffer: [u8; 1024 * 64] = [0; 1024 * 64];
   
    loop {
        stream.write_buf(&mut cursor).await?;
        stream.flush().await?;
        let read = stream.read(&mut buffer).await?;

        let (live, _) = buffer.split_at(read);
        received.extend_from_slice(live);
        
        print!(".");

        if received.len() >= length {
            break;
        }
    }
    
    println!("\nEchoed...");
    assert_eq!(received.as_slice(), cursor.get_ref().as_slice());
    println!("Echo equivalent!");

    Ok(())
}