Kiloparsec

The new generation of PARanoid SECurity protocol, advanced, faster, more secure. It also allows connecting any "block device" transport to the same local interface. Out if the box it provides the following transports:

name JVM JS native
TCP/IP server *
TCP/IP client *
Websock server *
Websock client * * *

At the moment we're working on supporting TCP/IP on most native targets. This feature is planned to rach public beta in August and production in early september 2024.

TCP/IP transport

It is the fastest. JVM implementation uses nio2 async sockets and optimizes TCP socket to play well with blocks (smart NO_DELAY mode). It is multiplatform, nut lacks of async TCP/IP support on natvic targetm this is where I need help having little time. I'd prefer to use something asyn like UV on native targets.

I know no existing way to implement it in KotlinJS for the modern browsers.

Websock server

While it is much slower than pure TCP, it is still faster than any http-based transport. It uses binary frames based on the Ktor server framework to easily integrate with web services. We recommend using it instead of a classic HTTP API as it beats it in terms of speed and server load even with HTTP/2.

We recommend to create the KiloInterface<S> instance and connect it to the websock and tcp servers in real applications to get easy access from anywhere.

Usage

Th elibrary should be used as maven dependency, not as source.

Adding dependency

Declare maven repository:

Add the private repository to your build.gradle.kts, like:

repositories {
    maven("https://gitea.sergeych.net/api/packages/SergeychWorks/maven")
}

Add dependency block

It could be, depending on your project structure, something like:

val commonMain by getting {
    dependencies {
        api("net.sergeych:kiloparsec:0.2.4")
    }
}

Create shared interface for your server and the client

It could be a multiplatform library that exports it or just a shared or copied source file declaring structures and functions available, like:

// Api.kt

@Serializable
class FooArgs(val text: String,val number: Int = 42)

// Server-side interface
val cmdSetFoo by command<FooArgs,Unit>()
val cmdGetFoo by command<Unit,FooArgs>()
val cmdPing by command<String,String>()
val cmdCheckConnected by command<Unit,Boolean>()

// client-side interface (called from the server)
val cmdPushClient by command<String,Unit>()

Call it from the client:

Remember, we need to implement client interface cmdPushClient in our example, so we need to provide local interace too:

// Unit: no session on the client:
val client = websocketClient<Unit>("wss://your.host.com/kp") {
    // This is server-callable function we export:
    on(cmdPushClient) {
        "server push: $it"
    }
}

// If we want to collect connected state changes (this is optional)
launch {
    client.connectedStateFlow.collect {
        if( it )
            println("I am connected")
        else
            println("trying to connect...")
    }
}

// now we can call server's functions
client.call(cmdSetFoo, FooArgs("bar", 117))
assertEquals(FooArgs("bar", 117), client.call(cmdGetFoo))

Create ktor-based server

Normally server side needs some session. It is convenient and avoid sending repeating data on each request speeding up the protocol. With KILOPARSEC it is rather basic operation:\

// Our session just keeps Foo for cmd{Get|Set}Foo:
data class Session(var fooState: FooArgs?=null)

// Let's now provide interface we export, it will be used on each connection automatically:

// Note server interface uses Session:
val serverInterface = KiloInterface<Session>().apply {
    onConnected { 
        // Do some initialization
        session.fooState = null
    }
    // Exceptions are passed through the network and re-created (re-thrown) on other side:
    on(cmdGetFoo) { session.fooState ?: throw IllegalStateException("foo is not yet set") }
    on(cmdSetFoo) { session.fooState = it }
}

// now create server using ktor (see ktor project for more):

val ns: NettyApplicationEngine = embeddedServer(Netty, port = 8080, host = "0.0.0.0", module = {
    setupWebsocketServer(serverInterface) { Session() }
}).start(wait = false)


Details

It is not compatible with parsec family and no more based on an Universa crypto library. To better fit the modern state of threats and rate of cyber crimes, KiloParsec uses more encryption and random key exchange on each and every connection (while parsec caches session keys to avoid time-consuming keys exchange). For the same reason, keys cryptography for session is shifted to use ed25519 curves which are supposed to provide agreeable strength with enough speed to protect every connection with a unique new keys. Also, we completely get rid of SHA2.

Kiloparsec also uses a denser binary format bipack, no more key-values, which reveals much less on the inner data structure, providing advanced typed RPC interfaces with kotlinx.serialization. There is also Rust implementation bipack_ru. The architecture allows connecting same functional interfaces to several various type channels at once.

Also, the difference from parsecs is that there are no more unencrypted layer commands available to users. All RPC is performed over the encrypted connection.

Technical description

Kiloparsec is a dull-duplex fully async (coroutine based) Remote Procedure Call protocol with typed parameters and support for serializing exceptions (e.g. exception thrown while executing remote command will be caught and rethrown at the caller context).

Kiloparsec is not REST, it has advanced session mechanisms and built-in authentication based on the same curve keys. Integrated tools to prevent MITM attacks include also non-transferred independently generated token that is calculated independently on the ends and is never transferred with the network. Comparing it somehow (visually, with QR code, etc) could add a very robust guarantee of the connection safety and ingenuity.

Kiloparsec has built-in completely asynchronous (coroutine based top-down) transport layer based on TCP (JVM only as for now) and the same async Websocket-based transport based on KTOR. Websocket client is multiplatform, though the server is JVM only insofar.

Licensing

Currently, you need to obtain a license from https://8-rays.dev or Sergey Chernov.

Description
No description provided
Readme 770 KiB
Languages
Kotlin 99.7%
Shell 0.3%