plugins { kotlin("jvm") jacoco } repositories { mavenCentral() } dependencies { // The whole reason this port is small. The Swift implementation had // to hand-write SipHash-2-4, XSalsa20 and Poly1305 because CryptoKit // exposes none of them, and its own field arithmetic because Apple gives // nothing below X25519. BouncyCastle has all four, vetted and // constant-time where it matters: `X25519Field` (including `sqrtRatioVar`, // exactly the primitive Elligator2 needs), `XSalsa20Engine`, `Poly1305`. // // That means the two clients do NOT share an implementation. They share // the vectors and the live interop harness, which is what actually keeps // them honest, see `Obfs4VectorTest`. // // Already a dependency of `:engine`, for the same class of reason: taking a // vetted constant-time implementation over hand-rolling arithmetic on a // secret scalar. implementation("org.bouncycastle:bcprov-jdk18on:1.79") // compileOnly: the transport must not drag OkHttp into anything that // does not already have it. `:client` supplies the real one. compileOnly("com.squareup.okhttp3:okhttp:4.12.0") testImplementation("com.squareup.okhttp3:okhttp:4.12.0") testImplementation(kotlin("test")) testImplementation("org.json:json:20240303") } kotlin { compilerOptions { jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17) } } java { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } tasks.test { useJUnitPlatform() testLogging { events("passed", "failed", "skipped"); showStandardStreams = true } } tasks.withType().configureEach { finalizedBy(tasks.named("jacocoTestReport")) } tasks.named("jacocoTestReport") { dependsOn(tasks.named("test")) reports { xml.required.set(true); html.required.set(true) } }