Build Status codecov

kuska handshake

kuska means together in Runasimi

kuska is an implementation of decentralized social network Secure Scuttlebut written in rust, it does not aim to provide a user interface and the functionality implemented in some clients like Patchwork, Patchbay, but the full set of libraries to be able to develop applications for the secure scuttlebut network.

kuska-handshake is the implementation of the handhake and box stream used in SSB, detailed information about the protocol can be found in https://ssbc.github.io/scuttlebutt-protocol-guide/.

the current implementation contains:

sync client/server

server

Create the server key pair let (pk, sk) = ed25519::gen_keypair(); let pk_b64 = base64::encode_config(&pk, base64::STANDARD);

Define the network to connect let net_id_hex = "d4a1cb88a66f02f8db635ce26441cc5dac1b08420ceaac230839b755845a9ffb"; let net_id = auth::Key::from_slice(&hex::decode(net_id_hex).unwrap()).unwrap();

Listen, accept the socket, and perform the handshake let listener = TcpListener::bind(...).unwrap(); let (socket, addr) = listener.accept().unwrap(); let handshake = handshake_server(&socket, net_id, pk, sk)?;

Once the handshake is performed, create both box streams, one to send and another to recieve data, those box streams implements std::io::Read and std::io::Write to perform usual i/o operations on them. ``` let (keynoncesend, keynoncerecv) = KeyNonce::fromhandshake(handshake); let (mut boxstreamread, mut boxstreamwrite) = BoxStream::new(&socket, &socket, keynoncesend, keynoncerecv).splitread_write();

boxstreamread.readexact(...) boxstreamwrite.writeall(...) ```

client

Create the client key pair let (pk, sk) = ed25519::gen_keypair(); let pk_b64 = base64::encode_config(&pk, base64::STANDARD);

Connect to the server, perform the handshake (you need the server public key), and create the box streams to communicate ``` let socket = TcpStream::connect(...).unwrap(); let handshake = handshakeclient(&socket, netid, pk, sk, server_pk)?;

let (keynoncesend, keynoncerecv) = KeyNonce::fromhandshake(handshake); let (mut boxstreamread, mut boxstreamwrite) = BoxStream::new(&socket, &socket, keynoncesend, keynoncerecv).splitread_write();

boxstreamread.readexact(...) boxstreamwrite.writeall(...) ```

async_std client

The async_std client is analogous to the sync version, just all functions are async and uses async_std::io::Read and async_std::io::Write for box streams

``` use asyncstd::io::{Read,Write}; use asyncstd::net::TcpStream; use kuskahandshake::asyncstd::{handshake_client,BoxStream};

[async_std::main]

async fn main() -> Result> { ... let mut socket = TcpStream::connect("127.0.0.1:8008").await?; let (,handshake) = handshakeclient(&mut socket, ssbnetid(), pk, sk, server_pk).await?;

let (boxstreamread, boxstreamwrite) = BoxStream::fromhandhake(&socket, &socket, handshake, 0x8000) .splitread_write(); ```

tokio client

To use the tokio you need the wrappers used in kuska_handshake::async_std::tokio_compat:

``` use tokio::net::TcpStream; use kuskahandshake::asyncstd::{BoxStream,handshake_client,TokioCompatExt,TokioCompatExtRead,TokioCompatExtWrite};

let tokiosocket : TcpStream = TcpStream::connect("127.0.0.1:8008").await?; let asyncstdsocket = TokioCompatExt::wrap(tokio_socket);

let (asyncstdsocket,handshake) = handshakeclient(asyncstdsocket, ssbnetid(), pk, sk.clone(), pk).await?; let mut tokiosocket = asyncstdsocket.intoinner(); let (read,write) = tokio_socket.split();

let read = TokioCompatExtRead::wrap(read); let write = TokioCompatExtWrite::wrap(write);

let (boxstreamread, boxstreamwrite) = BoxStream::fromhandhake(read, write, handshake, 0x8000) .splitread_write(); ```