mod hash_channel;
mod sync_channel;
mod track_channel;
#[cfg(unix)]
mod unix_channel;
pub use hash_channel::HashChannel;
pub use sync_channel::SyncChannel;
pub use track_channel::TrackChannel;
#[cfg(unix)]
pub use unix_channel::{track_unix_channel_pair, unix_channel_pair, TrackUnixChannel, UnixChannel};
use crate::{serialization::CanonicalSerialize, Block, Block512};
#[cfg(feature = "curve25519-dalek")]
use curve25519_dalek::ristretto::{CompressedRistretto, RistrettoPoint};
use generic_array::GenericArray;
use std::{
cell::RefCell,
io::{Read, Result, Write},
rc::Rc,
};
pub trait AbstractChannel {
fn read_bytes(&mut self, bytes: &mut [u8]) -> Result<()>;
fn write_bytes(&mut self, bytes: &[u8]) -> Result<()>;
fn flush(&mut self) -> Result<()>;
fn clone(&self) -> Self
where
Self: Sized;
fn read_vec(&mut self, nbytes: usize) -> Result<Vec<u8>> {
let mut data = vec![0; nbytes];
self.read_bytes(&mut data)?;
Ok(data)
}
#[inline(always)]
fn write_bool(&mut self, b: bool) -> Result<()> {
self.write_bytes(&[b as u8])?;
Ok(())
}
#[inline(always)]
fn read_bool(&mut self) -> Result<bool> {
let mut data = [0u8; 1];
self.read_bytes(&mut data)?;
Ok(data[0] != 0)
}
#[inline(always)]
fn write_u8(&mut self, s: u8) -> Result<()> {
let data = [s];
self.write_bytes(&data)?;
Ok(())
}
#[inline(always)]
fn read_u8(&mut self) -> Result<u8> {
let mut data = [0];
self.read_bytes(&mut data)?;
Ok(data[0])
}
#[inline(always)]
fn write_u16(&mut self, s: u16) -> Result<()> {
let data: [u8; 2] = s.to_le_bytes();
self.write_bytes(&data)?;
Ok(())
}
#[inline(always)]
fn read_u16(&mut self) -> Result<u16> {
let mut data = [0u8; 2];
self.read_bytes(&mut data)?;
let s = u16::from_le_bytes(data);
Ok(s)
}
#[inline(always)]
fn write_u32(&mut self, s: u32) -> Result<()> {
let data: [u8; 4] = s.to_le_bytes();
self.write_bytes(&data)?;
Ok(())
}
#[inline(always)]
fn read_u32(&mut self) -> Result<u32> {
let mut data = [0u8; 4];
self.read_bytes(&mut data)?;
let s = u32::from_le_bytes(data);
Ok(s)
}
#[inline(always)]
fn write_u64(&mut self, s: u64) -> Result<()> {
let data: [u8; 8] = s.to_le_bytes();
self.write_bytes(&data)?;
Ok(())
}
#[inline(always)]
fn read_u64(&mut self) -> Result<u64> {
let mut data = [0u8; 8];
self.read_bytes(&mut data)?;
let s = u64::from_le_bytes(data);
Ok(s)
}
#[inline(always)]
fn write_usize(&mut self, s: usize) -> Result<()> {
self.write_u64(s as u64)
}
#[inline(always)]
fn read_usize(&mut self) -> Result<usize> {
let x = self.read_u64()?;
usize::try_from(x).map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
}
#[inline(always)]
fn write_block(&mut self, b: &Block) -> Result<()> {
self.write_bytes(b.as_ref())?;
Ok(())
}
#[inline(always)]
fn read_block(&mut self) -> Result<Block> {
let mut v = Block::default();
self.read_bytes(v.as_mut())?;
Ok(v)
}
#[inline(always)]
fn read_blocks(&mut self, n: usize) -> Result<Vec<Block>> {
(0..n).map(|_| self.read_block()).collect()
}
#[inline(always)]
fn write_block512(&mut self, b: &Block512) -> Result<()> {
self.write_bytes(b.as_ref())
}
#[inline(always)]
fn read_block512(&mut self) -> Result<Block512> {
let mut out = Block512::default();
self.read_bytes(out.as_mut())?;
Ok(out)
}
#[cfg(feature = "curve25519-dalek")]
#[inline(always)]
fn write_pt(&mut self, pt: &RistrettoPoint) -> Result<()> {
self.write_bytes(pt.compress().as_bytes())?;
Ok(())
}
#[cfg(feature = "curve25519-dalek")]
#[inline(always)]
fn read_pt(&mut self) -> Result<RistrettoPoint> {
let mut data = [0u8; 32];
self.read_bytes(&mut data)?;
let pt = match CompressedRistretto::from_slice(&data).decompress() {
Some(pt) => pt,
None => {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"unable to decompress ristretto point",
));
}
};
Ok(pt)
}
fn read_serializable<E: CanonicalSerialize>(&mut self) -> Result<E> {
let mut buf = GenericArray::<u8, E::ByteReprLen>::default();
self.read_bytes(&mut buf[..])?;
let fe = match E::from_bytes(&buf) {
Ok(fe) => fe,
Err(e) => return Err(std::io::Error::new(std::io::ErrorKind::Other, e)),
};
Ok(fe)
}
fn write_serializable<E: CanonicalSerialize>(&mut self, x: &E) -> Result<()> {
self.write_bytes(&x.to_bytes())?;
Ok(())
}
}
pub struct Channel<R, W> {
reader: Rc<RefCell<R>>,
writer: Rc<RefCell<W>>,
}
impl<R: Read, W: Write> Channel<R, W> {
pub fn new(reader: R, writer: W) -> Self {
let reader = Rc::new(RefCell::new(reader));
let writer = Rc::new(RefCell::new(writer));
Self { reader, writer }
}
pub fn reader(self) -> Rc<RefCell<R>> {
self.reader
}
pub fn writer(self) -> Rc<RefCell<W>> {
self.writer
}
}
impl<R: Read, W: Write> AbstractChannel for Channel<R, W> {
#[inline(always)]
fn write_bytes(&mut self, bytes: &[u8]) -> Result<()> {
self.writer.borrow_mut().write_all(bytes)?;
Ok(())
}
#[inline(always)]
fn read_bytes(&mut self, mut bytes: &mut [u8]) -> Result<()> {
self.reader.borrow_mut().read_exact(&mut bytes)
}
#[inline(always)]
fn flush(&mut self) -> Result<()> {
self.writer.borrow_mut().flush()
}
#[inline(always)]
fn clone(&self) -> Self {
Self {
reader: self.reader.clone(),
writer: self.writer.clone(),
}
}
}
pub struct SymChannel<S> {
stream: Rc<RefCell<S>>,
}
impl<S: Read + Write> SymChannel<S> {
pub fn new(stream: S) -> Self {
let stream = Rc::new(RefCell::new(stream));
Self { stream }
}
}
impl<S: Read + Write> AbstractChannel for SymChannel<S> {
#[inline(always)]
fn write_bytes(&mut self, bytes: &[u8]) -> Result<()> {
self.stream.borrow_mut().write_all(bytes)?;
Ok(())
}
#[inline(always)]
fn read_bytes(&mut self, mut bytes: &mut [u8]) -> Result<()> {
self.stream.borrow_mut().read_exact(&mut bytes)
}
#[inline(always)]
fn flush(&mut self) -> Result<()> {
self.stream.borrow_mut().flush()
}
#[inline(always)]
fn clone(&self) -> Self {
Self {
stream: self.stream.clone(),
}
}
}